diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 26ae87d..deecb9e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,7 +29,7 @@ jobs: run: poetry install - name: Check code - run: poetry run pylint shaperglot + run: poetry run pylint --rcfile pyproject.toml shaperglot - name: Test code run: poetry run pytest diff --git a/AUTHORS.txt b/AUTHORS.txt new file mode 100644 index 0000000..127aee7 --- /dev/null +++ b/AUTHORS.txt @@ -0,0 +1,9 @@ +# This is the official list of authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. +# +# Names should be added to this file as: +# Name or Organization +# The email address is not required for organizations. + +Google LLC diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt new file mode 100644 index 0000000..9dafdb0 --- /dev/null +++ b/CONTRIBUTORS.txt @@ -0,0 +1,27 @@ +# This is the official list of people who can contribute +# (and typically have contributed) code to this repository. +# The AUTHORS file lists the copyright holders; this file +# lists people. For example, Google employees are listed here +# but not in AUTHORS, because Google holds the copyright. +# +# Names should be added to this file only after verifying that +# the individual or the individual's organization has agreed to +# the appropriate Contributor License Agreement, found here: +# +# http://code.google.com/legal/individual-cla-v1.0.html +# http://code.google.com/legal/corporate-cla-v1.0.html +# +# The agreement for individuals can be filled out on the web. +# +# When adding J Random Contributor's name to this file, +# either J's name or J's organization's name should be +# added to the AUTHORS file, depending on whether the +# individual or corporate CLA was used. +# +# Names should be added to this file like so: +# Name +# +# Please keep the list sorted. +# (first name; alphabetical order) + +Simon Cozens diff --git a/language_tag_data/iso639-3-afr-all.txt b/language_tag_data/iso639-3-afr-all.txt new file mode 100644 index 0000000..df0a00b --- /dev/null +++ b/language_tag_data/iso639-3-afr-all.txt @@ -0,0 +1,2130 @@ +afr +aug +sep +dec +amj +thu +aaa +aab +aal +aao +aar +aas +aba +abb +abi +abm +abn +abo +abr +abu +acb +acd +ach +acp +acq +acw +acx +acz +ada +add +ade +adh +adj +adq +adu +aeb +aec +ael +afb +afe +afn +afo +aft +afu +agb +agc +agh +agj +agq +ags +aha +ahg +ahi +ahl +ahm +ahn +ahp +ahs +aik +aiw +aiy +aja +ajg +aju +ajw +aka +akd +akf +akp +aks +aku +akw +ala +ald +alf +alw +alz +amb +amf +amh +amo +anc +anf +ank +ann +anu +anv +anw +any +apd +aqd +aqg +arb +arq +arv +ary +arz +asa +asg +asj +ass +asv +atg +ati +ato +atu +auh +auj +aum +avi +avn +avu +awc +awn +awo +axk +ayb +aye +ayg +ayi +ayk +ayl +ayu +azo +bab +baf +bag +bam +bas +bau +bav +baw +bax +bba +bbe +bbg +bbi +bbj +bbk +bbm +bbo +bbp +bbq +bbs +bbt +bbu +bbw +bbx +bby +bcb +bce +bcg +bci +bcn +bcp +bcq +bcs +bct +bcv +bcw +bcy +bcz +bda +bde +bdh +bdi +bdj +bdm +bdn +bdo +bdp +bds +bdt +bdu +beb +bec +beh +bej +bem +beq +bes +bet +bev +bex +bez +bfa +bfd +bff +bfj +bfl +bfm +bfo +bfp +bga +bgf +bgj +bgo +bgu +bhs +bhy +bib +bid +bif +bij +bil +bim +bin +bip +biv +biw +biz +bja +bjg +bji +bjo +bjt +bju +bjv +bjw +bka +bkc +bkf +bkg +bkh +bkj +bkm +bko +bkp +bkt +bkv +bkw +bky +ble +blh +bli +blm +blo +blv +bly +bma +bmb +bmd +bme +bmf +bmg +bmi +bml +bmo +bmq +bms +bmv +bmw +bng +bni +bnl +bnm +bnx +bnz +bob +boe +bof +boh +bok +bol +bom +boo +bot +bou +bov +box +boy +boz +bpd +bpj +bqa +bqc +bqd +bqf +bqg +bqj +bqk +bqm +bqo +bqp +bqt +bqu +bqv +bqw +bqx +bqz +brf +bri +brk +brl +brm +brt +bsc +bse +bsf +bsi +bsj +bsl +bso +bsp +bsq +bsr +bss +bst +bsv +bsw +bsx +bta +btc +bte +btf +btg +btt +btu +bub +bud +buf +bui +buj +bum +bun +bus +buu +buw +bux +buy +buz +bva +bvb +bvf +bvg +bvh +bvi +bvj +bvm +bvo +bvq +bvw +bvx +bwc +bwg +bwh +bwj +bwl +bwo +bwq +bwr +bws +bwt +bwu +bww +bwy +bwz +bxb +bxc +bxe +bxg +bxk +bxl +bxp +bxq +bxs +bxv +bxw +byb +byc +byf +byg +byi +byj +byn +byp +bys +byt +byv +bza +bze +bzm +bzo +bzv +bzw +bzx +bzy +bzz +cae +cbj +cbo +cbq +cce +ccg +cch +ccj +cdr +cen +cet +cfa +cfd +cfg +cgg +chw +cib +cie +cjk +ckl +cko +ckq +ckx +cky +cla +cli +cll +cme +cmt +cnu +coh +cop +cou +cpn +cpo +cra +cry +csk +cug +cuh +cuv +cwa +cwb +cwe +cwt +daa +dae +dag +dai +daj +dal +dam +das +dau +dav +dba +dbb +dbd +dbg +dbi +dbm +dbo +dbp +dbq +dbr +dbt +dbu +dbv +dbw +ddd +dde +ddn +dds +dee +deg +dek +deq +dez +dga +dgb +dgd +dgh +dgi +dgk +dgl +dgs +dhm +dhs +dib +dic +did +dig +dii +dik +dil +dim +dio +dip +dir +diu +diw +diz +djc +dje +djm +dks +dkx +dlk +dma +dmb +dme +dmm +dmo +dmx +dne +dnj +dnn +dno +doe +doh +doo +dop +dos +dot +dov +dow +dox +doy +doz +drb +dri +drs +dsh +dsi +dsq +dti +dtk +dtm +dtn +dto +dts +dtt +dtu +dua +dug +dur +dux +duz +dwa +dwr +dya +dyi +dym +dyo +dyu +dza +dzg +dzn +ebg +ebo +ebr +ebu +efa +efe +efi +ega +ego +ehu +eja +eka +eke +eki +ekm +eko +ekp +ekr +elh +eli +elm +elo +ema +emk +emn +enb +enn +env +enw +eot +epi +erh +etb +eto +ets +etu +etx +evh +ewe +ewo +eyo +eza +eze +fah +fak +fal +fam +fan +fap +fer +ffm +fgr +fia +fie +fip +fir +fkk +fli +fll +flr +fmp +fni +fod +fom +fon +fub +fuc +fue +fuf +fuh +fui +fuj +fum +fuq +fuu +fuv +fvr +fwe +gaa +gab +gax +gaz +gbg +gbh +gbn +gbo +gbp +gbq +gbr +gbs +gbv +gbx +gby +gde +gdf +gdi +gdk +gdl +gdm +gdu +gea +gec +ged +geg +gej +gek +gel +geq +gev +gew +gex +gey +gez +ggb +ggu +gha +ghl +gho +gic +gid +gie +gis +gix +giz +gji +gjn +gke +gkn +gkp +gku +glc +glj +glo +glr +glu +glw +gly +gmd +gmm +gmn +gmv +gmx +gmz +gna +gnd +gne +gng +gnh +gnj +gnk +gnz +goa +god +gof +gog +gol +gou +gow +gox +goy +gpa +gqa +gqr +grd +grh +grj +grr +gru +grv +gry +gsl +gso +gua +gud +guk +gur +guw +gux +guz +gvl +gvm +gwa +gwb +gwd +gwe +gwg +gwj +gwn +gwr +gwx +gxx +gya +gye +gyg +gyi +gyl +gza +hae +hag +han +haq +har +hau +hav +hay +hba +hbb +hbn +hdy +hed +heh +hem +her +hgm +hhr +hia +hig +hij +hio +hka +hke +hmb +hna +hnh +hod +hoe +hol +hom +hoo +hor +hoz +hts +huc +hum +hwa +hwo +hya +ibb +ibe +ibm +ibn +ibo +ibr +iby +ica +ich +ida +idc +idd +ide +idr +ids +idu +ife +ifm +igb +ige +igl +igw +ihi +ijc +ije +ijj +ijn +ijs +iki +ikk +ikl +iko +ikp +ikv +ikw +ikx +ikz +ilb +ilv +ior +iqw +iri +irk +ish +isi +isn +iso +isu +itm +its +itw +iya +iyo +iyx +izr +izz +jab +jad +jaf +jbe +jbn +jbu +jek +jen +jer +jeu +jgb +jgk +jgo +jia +jib +jid +jie +jii +jim +jit +jjr +jku +jle +jmb +jmc +jmi +jmr +jms +jni +jnj +job +jod +jow +jrr +jrt +jub +jud +juh +juk +jum +juo +juu +juw +jwi +jyy +kab +kad +kah +kai +kaj +kam +kao +kbj +kbl +kbn +kbo +kbp +kbr +kbs +kby +kbz +kcc +kce +kcf +kcg +kch +kci +kcj +kck +kcm +kcp +kcq +kcr +kcs +kcu +kcv +kcw +kcx +kcy +kcz +kdc +kde +kdg +kdh +kdi +kdj +kdl +kdm +kdn +kdp +kdu +kdx +kdz +keb +kec +ked +kef +keg +kel +ken +keo +ker +kes +keu +kez +kfl +kfn +kfo +kfz +kga +kgo +kgt +khj +khq +khu +khx +khy +kia +kib +kid +kie +kik +kil +kin +kiv +kiz +kka +kkd +kke +kki +kkj +kkm +kko +kkq +kkr +kks +kku +kkw +klc +klf +klk +klo +klu +kma +kmb +kme +kmi +kmp +kmq +kmw +kmy +kna +knc +knf +kng +kni +knk +kno +knp +knu +knw +kny +knz +koc +koe +kof +koh +koo +kon +koq +kot +kou +kov +kow +kpa +kph +kpk +kpl +kpo +kpz +kqg +kqh +kqk +kqm +kqn +kqo +kqp +kqs +kqu +kqx +kqy +kqz +krh +krn +krp +krs +krt +krw +krx +ksa +ksb +ksf +ksm +kso +ksp +ksq +kss +kst +ksv +ktb +ktc +ktf +kth +ktj +kty +ktz +kua +kub +kug +kuh +kuj +kul +kun +kus +kuw +kvf +kvi +kvj +kvm +kwb +kwc +kwg +kwl +kwm +kwn +kwp +kws +kwu +kwv +kwy +kwz +kxb +kxc +kxh +kxj +kxx +kya +kye +kyf +kym +kyq +kza +kzc +kzn +kzo +kzr +kzy +laf +lag +lai +laj +lak +lal +lam +lan +lap +lar +las +lbi +lch +lda +ldb +ldd +ldg +ldh +ldi +ldj +ldk +ldl +ldm +ldo +ldp +ldq +lea +leb +led +lee +lef +leh +lej +lel +lem +leo +les +lfa +lgg +lgm +lgn +lgq +lgz +lia +lie +lig +lik +lin +lip +liq +liu +liy +liz +lkb +lke +lko +lkr +lks +lky +lla +llb +llc +lli +lln +lma +lmd +lme +lmi +lmp +lmx +lna +lnb +lnl +lno +lns +lnu +lnz +lob +lof +log +loh +loi +lok +lol +lom +lon +loo +lop +loq +lor +lot +loz +lpx +lri +lrm +lro +lse +lsm +lth +lto +lts +lua +lub +luc +lue +lug +luj +lul +lum +lun +luo +lup +luq +luw +lwa +lwg +lwo +lyn +mae +maf +mas +maw +mbm +mbo +mbu +mbv +mcj +mck +mcn +mcp +mcs +mct +mcu +mcw +mcx +mda +mdd +mde +mdg +mdi +mdj +mdk +mdm +mdn +mdp +mdq +mdt +mdu +mdw +mdx +mdy +mea +mei +men +meq +mer +mes +mev +mew +mey +mfc +mfd +mff +mfg +mfh +mfi +mfj +mfk +mfl +mfm +mfn +mfo +mfq +mfu +mfv +mfx +mfz +mgb +mgc +mgd +mge +mgg +mgh +mgi +mgj +mgn +mgo +mgq +mgr +mgs +mgv +mgw +mgy +mgz +mhb +mhd +mhi +mhk +mhm +mho +mhw +mif +mij +mje +mjh +mjs +mlg +mka +mkf +mkk +mkl +mko +mku +mlb +mlj +mlk +mlo +mlq +mlr +mls +mlt +mlw +mma +mmf +mmu +mmy +mmz +mne +mnf +mnh +mnk +mny +moa +moi +moj +mor +mos +mou +mow +moy +moz +mpa +mpe +mpg +mpi +mpk +mqb +mql +mqu +mrt +mru +msc +mse +msj +msv +msw +mtb +mtk +mtl +mua +mub +muc +mug +muh +muj +muo +mur +muu +muy +muz +mvh +mvu +mvw +mvz +mwe +mwk +mwm +mwn +mws +mwu +mwz +mxc +mxf +mxg +mxh +mxl +mxo +mxu +mxx +myb +myc +mye +myf +myg +myj +myk +mym +myo +mys +myx +mzb +mzd +mzj +mzk +mzm +mzv +mzw +naj +naq +nar +nat +naw +nba +nbb +nbd +nbh +nbl +nbm +nbo +nbp +nbr +nbv +nbw +ncr +ncu +nda +ndb +ndc +ndd +nde +ndg +ndh +ndi +ndj +ndk +ndl +ndm +ndn +ndo +ndp +ndq +ndr +ndt +ndu +ndv +ndw +ndy +ndz +neb +ned +ney +nfd +nfr +nfu +nga +ngb +ngc +ngd +nge +ngg +ngh +ngi +ngj +ngl +ngn +ngo +ngp +ngq +ngs +ngv +ngw +ngx +ngy +ngz +nhb +nhr +nhu +nie +nih +nim +nin +niq +nix +niy +nja +njd +njj +njl +njr +njx +njy +nka +nkc +nkn +nko +nkq +nkt +nku +nkv +nkw +nkx +nkz +nla +nle +nlj +nlo +nlu +nmc +nmd +nmg +nmi +nmj +nml +nmn +nmq +nmr +nmz +nnb +nnc +nne +nnh +nnj +nnn +nnq +nnu +nnw +nnz +noq +now +noy +noz +nqg +nqk +nql +nqo +nra +nrb +nsc +nse +nsg +nsh +nso +nsx +nte +nti +ntk +ntm +nto +ntr +nue +nuh +nui +nuj +nup +nus +nuu +nuv +nvo +nwb +nwe +nwm +nxd +nxi +nxo +nya +nyb +nyc +nyd +nye +nyf +nyg +nyi +nyj +nyk +nym +nyn +nyo +nyp +nyr +nyu +nyy +nza +nzb +nzd +nzi +nzk +nzu +nzy +nzz +obl +obu +oda +odu +ofu +ogb +ogc +ogg +ogo +ogu +okb +okd +oke +oki +okr +oks +oku +okx +old +olm +olu +omi +oml +omt +opa +orc +org +orm +orr +orx +oso +ost +otr +oua +oub +oyd +ozm +pae +pai +pbi +pbl +pbn +pbo +pbp +pbr +pcn +pcw +pem +pfe +pgs +phm +pic +pil +pip +piw +piy +pkb +pko +plj +plr +pmb +pmm +pmn +pnd +png +pnl +pnq +pny +pnz +pof +poy +ppp +pqa +pug +puu +pwb +pye +pym +rag +ras +rax +reg +rel +rer +res +rif +rim +rin +rkm +rnd +rng +rnw +rod +rof +rou +rub +ruc +ruf +rui +ruk +run +ruy +ruz +rwk +rwm +rzh +saa +sad +saf +sag +sak +saq +sav +say +sba +sbd +sbf +sbj +sbk +sbm +sbp +sbs +sbw +sby +sbz +scv +scw +sde +sdj +sds +seb +sef +seg +seh +sen +seq +ses +sev +sfw +sgc +sgi +sgm +sgw +sha +shc +she +shg +shi +shj +shk +sho +shq +shr +shu +shw +shy +shz +sid +sie +sif +sig +sil +sir +siz +sjg +sjs +skq +skt +sld +slx +smd +smx +sna +snf +sng +snk +snm +snq +snw +soc +sod +soe +soh +sok +som +soo +sop +sor +sos +sot +sox +soy +soz +spp +spy +sqa +sqh +sqm +srr +ssc +ssl +ssn +ssw +ssy +stj +stv +sub +suj +suk +suq +sur +sus +suw +swa +swb +swc +swf +swh +swj +swk +swn +swq +swy +sxb +sxe +sxs +sxw +syc +syi +syk +sym +sys +syx +sze +szg +szv +tag +tak +tal +tan +tap +taq +tax +taz +tbi +tbm +tbr +tbt +tbz +tcc +tcd +tck +tda +tde +tdk +tdl +tdo +tdq +tdv +tec +ted +teg +tek +tem +teo +teq +teu +tex +tey +tez +tfi +tga +tgd +tgw +tgy +thk +thv +thy +thz +tia +tic +tig +tii +tik +tiq +tir +tiv +tja +tjn +tjo +tke +tkq +tlj +tll +tlo +tma +tmc +tms +tmv +tng +tnr +tny +tod +tog +toh +toi +toq +tor +toz +tpm +tqq +tqr +trj +tsa +tsb +tsc +tsh +tsn +tso +tsp +tst +tsv +tsw +ttb +ttf +ttj +ttl +ttq +ttr +tug +tui +tul +tum +tuq +tuv +tuy +tuz +tvd +tvs +tvu +twi +twl +twn +two +twq +twx +txj +tye +tyi +tyu +tyx +tzm +uba +ubi +uda +udl +udu +uha +uiv +uji +ukh +ukp +ukq +uku +ukw +ula +ulb +umb +umm +une +urh +usk +uss +uta +uth +utr +uya +vae +vag +vai +vaj +vau +vem +ven +ver +vid +vif +vig +vin +vit +vki +vkj +vmk +vmr +vmw +vor +vum +vun +vut +wal +wan +wav +wbf +wbh +wbi +wbj +wci +wdd +wec +weh +wem +wib +wja +wji +wka +wlc +wle +wll +wlx +wma +wmw +wni +wob +wof +wok +wol +wom +won +woy +wrn +wss +wti +wud +wum +wun +wwa +www +xab +xam +xan +xdo +xed +xeg +xel +xho +xii +xkb +xkg +xkt +xku +xkv +xma +xmb +xmc +xmd +xmg +xmj +xnz +xoc +xog +xom +xon +xpe +xrb +xsh +xsj +xsm +xsn +xsq +xtc +xuo +xuu +xwe +xwg +xwl +yaf +yaj +yal +yam +yao +yas +yat +yav +yax +yay +yaz +yba +ybb +ybj +ybl +yei +yel +yer +yes +yey +yko +yky +ymg +ymk +ymm +yng +ynq +yns +yom +yor +yot +yre +yul +yun +zag +zah +zaj +zak +zay +zaz +zdj +zen +zga +zgh +zhi +zhw +zil +zim +zin +zir +ziw +ziz +zmb +zmf +zmn +zmo +zmp +zmq +zms +zmw +zmx +zmz +zna +zne +zns +zrn +zua +zul +zuy +zwa \ No newline at end of file diff --git a/language_tag_data/ot-lang-tags.yaml b/language_tag_data/ot-lang-tags.yaml new file mode 100644 index 0000000..5234a87 --- /dev/null +++ b/language_tag_data/ot-lang-tags.yaml @@ -0,0 +1,1823 @@ +# OpenType language tags +# +# This list is based on OpenType Specification (version from 23 August 2018): +# http://www.microsoft.com/typography/otspec/languagetags.htm +# Compiled manually. +# +# Notes: +# - inconsistent formatting present at the website have been fixed manually here +# - the OpenType language tags are always 4-letter codes, sometimes padded with spaces +# - the codes are either codes from ISO 639-3, ISO 639-2 language collections, +# or retired ISO 639-3 codes. Not all OpenType language tags refer to ISO codes. + +- name: Abaza + tag: "ABA " + codes: [abq] +- name: Abkhazian + tag: "ABK " + codes: [abk] +- name: Acholi + tag: "ACH " + codes: [ach] +- name: Achi + tag: "ACR " + codes: [acr] +- name: Adyghe + tag: "ADY " + codes: [ady] +- name: Afrikaans + tag: "AFK " + codes: [afr] +- name: Afar + tag: "AFR " + codes: [aar] +- name: Agaw + tag: "AGW " + codes: [ahg] +- name: Aiton + tag: "AIO " + codes: [aio] +- name: Akan + tag: "AKA " + codes: [aka] +- name: Alsatian + tag: "ALS " + codes: [gsw] +- name: Altai + tag: "ALT " + codes: [atv, alt] +- name: Amharic + tag: "AMH " + codes: [amh] +- name: Anglo-Saxon + tag: "ANG " + codes: [ang] +- name: Phonetic transcription—Americanist conventions + tag: APPH + codes: [] +- name: Arabic + tag: "ARA " + codes: [ara] +- name: Aragonese + tag: "ARG " + codes: [arg] +- name: Aari + tag: "ARI " + codes: [aiw] +- name: Rakhine + tag: "ARK " + codes: [mhv, rmz, rki] +- name: Assamese + tag: "ASM " + codes: [asm] +- name: Asturian + tag: "AST " + codes: [ast] +- name: Athapaskan + tag: "ATH " + codes: [apk, apj, apl, apm, apw, nav, bea, sek, bcr, caf, crx, clc, gwi, haa, chp, dgr, scs, xsl, srs, ing, hoi, koy, hup, ktw, mvb, wlk, coq, ctc, gce, tol, tuu, kkz, tgx, tht, aht, tfn, taa, tau, tcb, kuu, tce, ttm, txc] +- name: Avar + tag: "AVR " + codes: [ava] +- name: Awadhi + tag: "AWA " + codes: [awa] +- name: Aymara + tag: "AYM " + codes: [aym] +- name: Torki + tag: "AZB " + codes: [azb] +- name: Azerbaijani + tag: "AZE " + codes: [aze] +- name: Badaga + tag: "BAD " + codes: [bfq] +- name: Banda + tag: BAD0 + codes: [bad] +- name: Baghelkhandi + tag: "BAG " + codes: [bfy] +- name: Balkar + tag: "BAL " + codes: [krc] +- name: Balinese + tag: "BAN " + codes: [ban] +- name: Bavarian + tag: "BAR " + codes: [bar] +- name: Baulé + tag: "BAU " + codes: [bci] +- name: Batak Toba + tag: "BBC " + codes: [bbc] +- name: Berber + tag: "BBR " + codes: [] +- name: Bench + tag: "BCH " + codes: [bcq] +- name: Bible Cree + tag: "BCR " + codes: [] +- name: Bandjalang + tag: "BDY " + codes: [bdy] +- name: Belarussian + tag: "BEL " + codes: [bel] +- name: Bemba + tag: "BEM " + codes: [bem] +- name: Bengali + tag: "BEN " + codes: [ben] +- name: Haryanvi + tag: "BGC " + codes: [bgc] +- name: Bagri + tag: "BGQ " + codes: [bgq] +- name: Bulgarian + tag: "BGR " + codes: [bul] +- name: Bhili + tag: "BHI " + codes: [bhi, bhb] +- name: Bhojpuri + tag: "BHO " + codes: [bho] +- name: Bikol + tag: "BIK " + codes: [bik, bhk, bcl, bto, cts, bln, fbl, lbl, rbl, ubl] +- name: Bilen + tag: "BIL " + codes: [byn] +- name: Bislama + tag: "BIS " + codes: [bis] +- name: Kanauji + tag: "BJJ " + codes: [bjj] +- name: Blackfoot + tag: "BKF " + codes: [bla] +- name: Baluchi + tag: "BLI " + codes: [bal] +- name: Pa’o Karen + tag: "BLK " + codes: [blk] +- name: Balante + tag: "BLN " + codes: [bjt, ble] +- name: Balti + tag: "BLT " + codes: [bft] +- name: Bambara (Bamanankan) + tag: "BMB " + codes: [bam] +- name: Bamileke + tag: "BML " + codes: [] +- name: Bosnian + tag: "BOS " + codes: [bos] +- name: Bishnupriya Manipuri + tag: "BPY " + codes: [bpy] +- name: Breton + tag: "BRE " + codes: [bre] +- name: Brahui + tag: "BRH " + codes: [brh] +- name: Braj Bhasha + tag: "BRI " + codes: [bra] +- name: Burmese + tag: "BRM " + codes: [mya] +- name: Bodo + tag: "BRX " + codes: [brx] +- name: Bashkir + tag: "BSH " + codes: [bak] +- name: Burushaski + tag: "BSK " + codes: [bsk] +- name: Beti + tag: "BTI " + codes: [btb, beb, bum, bxp, eto, ewo, mct] +- name: Batak Simalungun + tag: "BTS " + codes: [bts] +- name: Bugis + tag: "BUG " + codes: [bug] +- name: Medumba + tag: "BYV " + codes: [byv] +- name: Kaqchikel + tag: "CAK " + codes: [cak] +- name: Catalan + tag: "CAT " + codes: [cat] +- name: Zamboanga Chavacano + tag: "CBK " + codes: [cbk] +- name: Chinantec + tag: CCHN + codes: [cco, chj, chq, chz, cle, cnl, cnt, cpa, csa, cso, cte, ctl, cuc, cvn] +- name: Cebuano + tag: "CEB " + codes: [ceb] +- name: Chechen + tag: "CHE " + codes: [che] +- name: Chaha Gurage + tag: "CHG " + codes: [sgw] +- name: Chattisgarhi + tag: "CHH " + codes: [hne] +- name: Chichewa (Chewa, Nyanja) + tag: "CHI " + codes: [nya] +- name: Chukchi + tag: "CHK " + codes: [ckt] +- name: Chuukese + tag: CHK0 + codes: [chk] +- name: Choctaw + tag: "CHO " + codes: [cho] +- name: Chipewyan + tag: "CHP " + codes: [chp] +- name: Cherokee + tag: "CHR " + codes: [chr] +- name: Chamorro + tag: "CHA " + codes: [cha] +- name: Chuvash + tag: "CHU " + codes: [chv] +- name: Cheyenne + tag: "CHY " + codes: [chy] +- name: Chiga + tag: "CGG " + codes: [cgg] +- name: Western Cham + tag: "CJA " + codes: [cja] +- name: Eastern Cham + tag: "CJM " + codes: [cjm] +- name: Comorian + tag: "CMR " + codes: [swb, wlc, wni, zdj] +- name: Coptic + tag: "COP " + codes: [cop] +- name: Cornish + tag: "COR " + codes: [cor] +- name: Corsican + tag: "COS " + codes: [cos] +- name: Creoles + tag: "CPP " + codes: [crp, cpe, cpf, cpp] +- name: Cree + tag: "CRE " + codes: [cre] +- name: Carrier + tag: "CRR " + codes: [crx, caf] +- name: Crimean Tatar + tag: "CRT " + codes: [crh] +- name: Kashubian + tag: "CSB " + codes: [csb] +- name: Church Slavonic + tag: "CSL " + codes: [chu] +- name: Czech + tag: "CSY " + codes: [ces] +- name: Chittagonian + tag: "CTG " + codes: [ctg] +- name: San Blas Kuna + tag: "CUK " + codes: [cuk] +- name: Danish + tag: "DAN " + codes: [dan] +- name: Dargwa + tag: "DAR " + codes: [dar] +- name: Dayi + tag: "DAX " + codes: [dax] +- name: Woods Cree + tag: "DCR " + codes: [cwd] +- name: German + tag: "DEU " + codes: [deu] +- name: Dogri + tag: "DGO " + codes: [dgo] +- name: Dogri + tag: "DGR " + codes: [doi] +- name: Dhangu + tag: "DHG " + codes: [dhg] +- name: Divehi (Dhivehi, Maldivian) + tag: "DHV " + codes: [div] + ignore: true + note: deprecated +- name: Dimli + tag: "DIQ " + codes: [diq] +- name: Divehi (Dhivehi, Maldivian) + tag: "DIV " + codes: [div] +- name: Zarma + tag: "DJR " + codes: [dje] +- name: Djambarrpuyngu + tag: DJR0 + codes: [djr] +- name: Dangme + tag: "DNG " + codes: [ada] +- name: Dan + tag: "DNJ " + codes: [dnj] +- name: Dinka + tag: "DNK " + codes: [din] +- name: Dari + tag: "DRI " + codes: [prs] +- name: Dhuwal + tag: "DUJ " + codes: [duj, dwu, dwy] +- name: Dungan + tag: "DUN " + codes: [dng] +- name: Dzongkha + tag: "DZN " + codes: [dzo] +- name: Ebira + tag: "EBI " + codes: [igb] +- name: Eastern Cree + tag: "ECR " + codes: [crj, crl] +- name: Edo + tag: "EDO " + codes: [bin] +- name: Efik + tag: "EFI " + codes: [efi] +- name: Greek + tag: "ELL " + codes: [ell] +- name: Eastern Maninkakan + tag: "EMK " + codes: [emk] +- name: English + tag: "ENG " + codes: [eng] +- name: Erzya + tag: "ERZ " + codes: [myv] +- name: Spanish + tag: "ESP " + codes: [spa] +- name: Central Yupik + tag: "ESU " + codes: [esu] +- name: Estonian + tag: "ETI " + codes: [est] +- name: Basque + tag: "EUQ " + codes: [eus] +- name: Evenki + tag: "EVK " + codes: [evn] +- name: Even + tag: "EVN " + codes: [eve] +- name: Ewe + tag: "EWE " + codes: [ewe] +- name: French Antillean + tag: "FAN " + codes: [acf] +- name: Fang + tag: FAN0 + codes: [fan] +- name: Persian + tag: "FAR " + codes: [fas] +- name: Fanti + tag: "FAT " + codes: [fat] +- name: Finnish + tag: "FIN " + codes: [fin] +- name: Fijian + tag: "FJI " + codes: [fij] +- name: Dutch (Flemish) + tag: "FLE " + codes: [vls] +- name: Fe’fe’ + tag: "FMP " + codes: [fmp] +- name: Forest Nenets + tag: "FNE " + codes: [enf, yrk] +- name: Fon + tag: "FON " + codes: [fon] +- name: Faroese + tag: "FOS " + codes: [fao] +- name: French + tag: "FRA " + codes: [fra] +- name: Cajun French + tag: "FRC " + codes: [frc] +- name: Frisian + tag: "FRI " + codes: [fry] +- name: Friulian + tag: "FRL " + codes: [fur] +- name: Arpitan + tag: "FRP " + codes: [frp] +- name: Futa + tag: "FTA " + codes: [fuf] +- name: Fulah + tag: "FUL " + codes: [ful] +- name: Nigerian Fulfulde + tag: "FUV " + codes: [fuv] +- name: Ga + tag: "GAD " + codes: [gaa] +- name: Scottish Gaelic (Gaelic) + tag: "GAE " + codes: [gla] +- name: Gagauz + tag: "GAG " + codes: [gag] +- name: Galician + tag: "GAL " + codes: [glg] +- name: Garshuni + tag: "GAR " + codes: [] +- name: Garhwali + tag: "GAW " + codes: [gbm] +- name: Geez + tag: "GEZ " + codes: [gez] +- name: Githabul + tag: "GIH " + codes: [gih] +- name: Gilyak + tag: "GIL " + codes: [niv] +- name: Kiribati (Gilbertese) + tag: GIL0 + codes: [gil] +- name: Kpelle (Guinea) + tag: "GKP " + codes: [gkp] +- name: Gilaki + tag: "GLK " + codes: [glk] +- name: Gumuz + tag: "GMZ " + codes: [guk] +- name: Gumatj + tag: "GNN " + codes: [gnn] +- name: Gogo + tag: "GOG " + codes: [gog] +- name: Gondi + tag: "GON " + codes: [gon] +- name: Greenlandic + tag: "GRN " + codes: [kal] +- name: Garo + tag: "GRO " + codes: [grt] +- name: Guarani + tag: "GUA " + codes: [grn] +- name: Wayuu + tag: "GUC " + codes: [guc] +- name: Gupapuyngu + tag: "GUF " + codes: [guf] +- name: Gujarati + tag: "GUJ " + codes: [guj] +- name: Gusii + tag: "GUZ " + codes: [guz] +- name: Haitian (Haitian Creole) + tag: "HAI " + codes: [hat] +- name: Halam (Falam Chin) + tag: "HAL " + codes: [flm, cfm, rnl] +- name: Harauti + tag: "HAR " + codes: [hoj] +- name: Hausa + tag: "HAU " + codes: [hau] +- name: Hawaiian + tag: "HAW " + codes: [haw] +- name: Haya + tag: "HAY " + codes: [hay] +- name: Hazaragi + tag: "HAZ " + codes: [haz] +- name: Hammer-Banna + tag: "HBN " + codes: [amf] +- name: Herero + tag: "HER " + codes: [her] +- name: Hiligaynon + tag: "HIL " + codes: [hil] +- name: Hindi + tag: "HIN " + codes: [hin] +- name: High Mari + tag: "HMA " + codes: [mrj] +- name: Hmong + tag: "HMN " + codes: [hmn] +- name: Hiri Motu + tag: "HMO " + codes: [hmo] +- name: Hindko + tag: "HND " + codes: [hno, hnd] +- name: Ho + tag: "HO " + codes: [hoc] +- name: Harari + tag: "HRI " + codes: [har] +- name: Croatian + tag: "HRV " + codes: [hrv] +- name: Hungarian + tag: "HUN " + codes: [hun] +- name: Armenian + tag: "HYE " + codes: [hye, hyw] +- name: Armenian East + tag: HYE0 + codes: [hye] +- name: Iban + tag: "IBA " + codes: [iba] +- name: Ibibio + tag: "IBB " + codes: [ibb] +- name: Igbo + tag: "IBO " + codes: [ibo] +- name: Ijo languages + tag: "IJO " + codes: [ijc, ijo] +- name: Ido + tag: "IDO " + codes: [ido] +- name: Interlingue + tag: "ILE " + codes: [ile] +- name: Ilokano + tag: "ILO " + codes: [ilo] +- name: Interlingua + tag: "INA " + codes: [ina] +- name: Indonesian + tag: "IND " + codes: [ind] +- name: Ingush + tag: "ING " + codes: [inh] +- name: Inuktitut + tag: "INU " + codes: [iku] +- name: Inupiat + tag: "IPK " + codes: [ipk] +- name: Phonetic transcription—IPA conventions + tag: IPPH + codes: [""] +- name: Irish + tag: "IRI " + codes: [gle] +- name: Irish Traditional + tag: "IRT " + codes: [gle] +- name: Icelandic + tag: "ISL " + codes: [isl] +- name: Inari Sami + tag: "ISM " + codes: [smn] +- name: Italian + tag: "ITA " + codes: [ita] +- name: Hebrew + tag: "IWR " + codes: [heb] +- name: Jamaican Creole + tag: "JAM " + codes: [jam] +- name: Japanese + tag: "JAN " + codes: [jpn] +- name: Javanese + tag: "JAV " + codes: [jav] +- name: Lojban + tag: "JBO " + codes: [jbo] +- name: Krymchak + tag: "JCT " + codes: [jct] +- name: Yiddish + tag: "JII " + codes: [yid] +- name: Ladino + tag: "JUD " + codes: [lad] +- name: Jula + tag: "JUL " + codes: [dyu] +- name: Kabardian + tag: "KAB " + codes: [kbd] +- name: Kabyle + tag: KAB0 + codes: [kab] +- name: Kachchi + tag: "KAC " + codes: [kfr] +- name: Kalenjin + tag: "KAL " + codes: [kln] +- name: Kannada + tag: "KAN " + codes: [kan] +- name: Karachay + tag: "KAR " + codes: [krc] +- name: Georgian + tag: "KAT " + codes: [kat] +- name: Kazakh + tag: "KAZ " + codes: [kaz] +- name: Makonde + tag: "KDE " + codes: [kde] +- name: Kabuverdianu (Crioulo) + tag: "KEA " + codes: [kea] +- name: Kebena + tag: "KEB " + codes: [ktb] +- name: Kekchi + tag: "KEK " + codes: [kek] +- name: Khutsuri Georgian + tag: "KGE " + codes: [kat] +- name: Khakass + tag: "KHA " + codes: [kjh] +- name: Khanty-Kazim + tag: "KHK " + codes: [kca] +- name: Khmer + tag: "KHM " + codes: [khm] +- name: Khanty-Shurishkar + tag: "KHS " + codes: [kca] +- name: Khamti Shan + tag: "KHT " + codes: [kht] +- name: Khanty-Vakhi + tag: "KHV " + codes: [kca] +- name: Khowar + tag: "KHW " + codes: [khw] +- name: Kikuyu (Gikuyu) + tag: "KIK " + codes: [kik] +- name: Kirghiz (Kyrgyz) + tag: "KIR " + codes: [kir] +- name: Kisii + tag: "KIS " + codes: [kqs, kss] +- name: Kirmanjki + tag: "KIU " + codes: [kiu] +- name: Southern Kiwai + tag: "KJD " + codes: [kjd] +- name: Eastern Pwo Karen + tag: "KJP " + codes: [kjp] +- name: Bumthangkha + tag: "KJZ " + codes: [kjz] +- name: Kokni + tag: "KKN " + codes: [kex] +- name: Kalmyk + tag: "KLM " + codes: [xal] +- name: Kamba + tag: "KMB " + codes: [kam] +- name: Kumaoni + tag: "KMN " + codes: [kfy] +- name: Komo + tag: "KMO " + codes: [kmw] +- name: Komso + tag: "KMS " + codes: [kxc] +- name: Khorasani Turkic + tag: "KMZ " + codes: [kmz] +- name: Kanuri + tag: "KNR " + codes: [kau] +- name: Kodagu + tag: "KOD " + codes: [kfa] +- name: Korean Old Hangul + tag: "KOH " + codes: [okm] +- name: Konkani + tag: "KOK " + codes: [kok] +- name: Kikongo + tag: "KON " + codes: [ktu] +- name: Komi + tag: "KOM " + codes: [kom] +- name: Kongo + tag: KON0 + codes: [kon] +- name: Komi-Permyak + tag: "KOP " + codes: [koi] +- name: Korean + tag: "KOR " + codes: [kor] +- name: Kosraean + tag: "KOS " + codes: [kos] +- name: Komi-Zyrian + tag: "KOZ " + codes: [kpv] +- name: Kpelle + tag: "KPL " + codes: [kpe] +- name: Krio + tag: "KRI " + codes: [kri] +- name: Karakalpak + tag: "KRK " + codes: [kaa] +- name: Karelian + tag: "KRL " + codes: [krl] +- name: Karaim + tag: "KRM " + codes: [kdr] +- name: Karen + tag: "KRN " + codes: [kar] +- name: Koorete + tag: "KRT " + codes: [kqy] +- name: Kashmiri + tag: "KSH " + codes: [kas] +- name: Ripuarian + tag: KSH0 + codes: [ksh] +- name: Khasi + tag: "KSI " + codes: [kha] +- name: Kildin Sami + tag: "KSM " + codes: [sjd] +- name: S’gaw Karen + tag: "KSW " + codes: [ksw] +- name: Kuanyama + tag: "KUA " + codes: [kua] +- name: Kui + tag: "KUI " + codes: [kxu] +- name: Kulvi + tag: "KUL " + codes: [kfx] +- name: Kumyk + tag: "KUM " + codes: [kum] +- name: Kurdish + tag: "KUR " + codes: [kur] +- name: Kurukh + tag: "KUU " + codes: [kru] +- name: Kuy + tag: "KUY " + codes: [kdt] +- name: Koryak + tag: "KYK " + codes: [kpy] +- name: Western Kayah + tag: "KYU " + codes: [kyu] +- name: Ladin + tag: "LAD " + codes: [lld] +- name: Lahuli + tag: "LAH " + codes: [bfu] +- name: Lak + tag: "LAK " + codes: [lbe] +- name: Lambani + tag: "LAM " + codes: [lmn] +- name: Lao + tag: "LAO " + codes: [lao] +- name: Latin + tag: "LAT " + codes: [lat] +- name: Laz + tag: "LAZ " + codes: [lzz] +- name: L-Cree + tag: "LCR " + codes: [crm] +- name: Ladakhi + tag: "LDK " + codes: [lbj] +- name: Lezgi + tag: "LEZ " + codes: [lez] +- name: Ligurian + tag: "LIJ " + codes: [lij] +- name: Limburgish + tag: "LIM " + codes: [lim] +- name: Lingala + tag: "LIN " + codes: [lin] +- name: Lisu + tag: "LIS " + codes: [lis] +- name: Lampung + tag: "LJP " + codes: [ljp] +- name: Laki + tag: "LKI " + codes: [lki] +- name: Low Mari + tag: "LMA " + codes: [mhr] +- name: Limbu + tag: "LMB " + codes: [lif] +- name: Lombard + tag: "LMO " + codes: [lmo] +- name: Lomwe + tag: "LMW " + codes: [ngl] +- name: Loma + tag: "LOM " + codes: [lom] +- name: Luri + tag: "LRC " + codes: [lrc, luz, bqi, zum] +- name: Lower Sorbian + tag: "LSB " + codes: [dsb] +- name: Lule Sami + tag: "LSM " + codes: [smj] +- name: Lithuanian + tag: "LTH " + codes: [lit] +- name: Luxembourgish + tag: "LTZ " + codes: [ltz] +- name: Luba-Lulua + tag: "LUA " + codes: [lua] +- name: Luba-Katanga + tag: "LUB " + codes: [lub] +- name: Ganda + tag: "LUG " + codes: [lug] +- name: Luyia + tag: "LUH " + codes: [luy] +- name: Luo + tag: "LUO " + codes: [luo] +- name: Latvian + tag: "LVI " + codes: [lav] +- name: Madura + tag: "MAD " + codes: [mad] +- name: Magahi + tag: "MAG " + codes: [mag] +- name: Marshallese + tag: "MAH " + codes: [mah] +- name: Majang + tag: "MAJ " + codes: [mpe] +- name: Makhuwa + tag: "MAK " + codes: [vmw] +- name: Malayalam + tag: "MAL " + codes: [mal] +- name: Mam + tag: "MAM " + codes: [mam] +- name: Mansi + tag: "MAN " + codes: [mns] +- name: Mapudungun + tag: "MAP " + codes: [arn] +- name: Marathi + tag: "MAR " + codes: [mar] +- name: Marwari + tag: "MAW " + codes: [mwr, dhd, rwr, mve, wry, mtr, swv] +- name: Mbundu + tag: "MBN " + codes: [kmb] +- name: Mbo + tag: "MBO " + codes: [mbo] +- name: Manchu + tag: "MCH " + codes: [mnc] +- name: Moose Cree + tag: "MCR " + codes: [crm] +- name: Mende + tag: "MDE " + codes: [men] +- name: Mandar + tag: "MDR " + codes: [mdr] +- name: Me’en + tag: "MEN " + codes: [mym] +- name: Meru + tag: "MER " + codes: [mer] +- name: Pattani Malay + tag: "MFA " + codes: [mfa] +- name: Morisyen + tag: "MFE " + codes: [mfe] +- name: Minangkabau + tag: "MIN " + codes: [min] +- name: Mizo + tag: "MIZ " + codes: [lus] +- name: Macedonian + tag: "MKD " + codes: [mkd] +- name: Makasar + tag: "MKR " + codes: [mak] +- name: Kituba + tag: "MKW " + codes: [mkw] +- name: Male + tag: "MLE " + codes: [mdy] +- name: Malagasy + tag: "MLG " + codes: [mlg] +- name: Malinke + tag: "MLN " + codes: [mlq] +- name: Malayalam Reformed + tag: "MLR " + codes: [mal] +- name: Malay + tag: "MLY " + codes: [msa] +- name: Mandinka + tag: "MND " + codes: [mnk] +- name: Mongolian + tag: "MNG " + codes: [mon] +- name: Manipuri + tag: "MNI " + codes: [mni] +- name: Maninka + tag: "MNK " + codes: [man, mnk, myq, mku, msc, emk, mwk, mlq] +- name: Manx + tag: "MNX " + codes: [glv] +- name: Mohawk + tag: "MOH " + codes: [moh] +- name: Moksha + tag: "MOK " + codes: [mdf] +- name: Moldavian + tag: "MOL " + codes: [mol] +- name: Mon + tag: "MON " + codes: [mnw] +- name: Moroccan + tag: "MOR " + codes: [] +- name: Mossi + tag: "MOS " + codes: [mos] +- name: Maori + tag: "MRI " + codes: [mri] +- name: Maithili + tag: "MTH " + codes: [mai] +- name: Maltese + tag: "MTS " + codes: [mlt] +- name: Mundari + tag: "MUN " + codes: [unr] +- name: Muscogee + tag: "MUS " + codes: [mus] +- name: Mirandese + tag: "MWL " + codes: [mwl] +- name: Hmong Daw + tag: "MWW " + codes: [mww] +- name: Mayan + tag: "MYN " + codes: [myn] +- name: Mazanderani + tag: "MZN " + codes: [mzn] +- name: Naga-Assamese + tag: "NAG " + codes: [nag] +- name: Nahuatl + tag: "NAH " + codes: [nah] +- name: Nanai + tag: "NAN " + codes: [gld] +- name: Neapolitan + tag: "NAP " + codes: [nap] +- name: Naskapi + tag: "NAS " + codes: [nsk] +- name: Nauruan + tag: "NAU " + codes: [nau] +- name: Navajo + tag: "NAV " + codes: [nav] +- name: N-Cree + tag: "NCR " + codes: [csw] +- name: Ndebele + tag: "NDB " + codes: [nbl, nde] +- name: Ndau + tag: "NDC " + codes: [ndc] +- name: Ndonga + tag: "NDG " + codes: [ndo] +- name: Low Saxon + tag: "NDS " + codes: [nds] +- name: Nepali + tag: "NEP " + codes: [nep] +- name: Newari + tag: "NEW " + codes: [new] +- name: Ngbaka + tag: "NGA " + codes: [nga] +- name: Nagari + tag: "NGR " + codes: [] +- name: Norway House Cree + tag: "NHC " + codes: [csw] +- name: Nisi + tag: "NIS " + codes: [dap, njz, tgj] +- name: Niuean + tag: "NIU " + codes: [niu] +- name: Nyankole + tag: "NKL " + codes: [nyn] +- name: N’Ko + tag: "NKO " + codes: [nqo] +- name: Dutch + tag: "NLD " + codes: [nld] +- name: Nimadi + tag: "NOE " + codes: [noe] +- name: Nogai + tag: "NOG " + codes: [nog] +- name: Norwegian + tag: "NOR " + codes: [nob] +- name: Novial + tag: "NOV " + codes: [nov] +- name: Northern Sami + tag: "NSM " + codes: [sme] +- name: Sotho, Northern + tag: "NSO " + codes: [nso] +- name: Northern Tai + tag: "NTA " + codes: [nod] +- name: Esperanto + tag: "NTO " + codes: [epo] +- name: Nyamwezi + tag: "NYM " + codes: [nym] +- name: Norwegian Nynorsk (Nynorsk, Norwegian) + tag: "NYN " + codes: [nno] +- name: Mbembe Tigon + tag: "NZA " + codes: [nza] +- name: Occitan + tag: "OCI " + codes: [oci] +- name: Oji-Cree + tag: "OCR " + codes: [ojs] +- name: Ojibway + tag: "OJB " + codes: [oji] +- name: Odia (formerly Oriya) + tag: "ORI " + codes: [ori] +- name: Oromo + tag: "ORO " + codes: [orm] +- name: Ossetian + tag: "OSS " + codes: [oss] +- name: Palestinian Aramaic + tag: "PAA " + codes: [sam] +- name: Pangasinan + tag: "PAG " + codes: [pag] +- name: Pali + tag: "PAL " + codes: [pli] +- name: Pampangan + tag: "PAM " + codes: [pam] +- name: Punjabi + tag: "PAN " + codes: [pan] +- name: Palpa + tag: "PAP " + codes: [plp] +- name: Papiamentu + tag: PAP0 + codes: [pap] +- name: Pashto + tag: "PAS " + codes: [pus] +- name: Palauan + tag: "PAU " + codes: [pau] +- name: Bouyei + tag: "PCC " + codes: [pcc] +- name: Picard + tag: "PCD " + codes: [pcd] +- name: Pennsylvania German + tag: "PDC " + codes: [pdc] +- name: Polytonic Greek + tag: "PGR " + codes: [ell] +- name: Phake + tag: "PHK " + codes: [phk] +- name: Norfolk + tag: "PIH " + codes: [pih] +- name: Filipino + tag: "PIL " + codes: [fil] +- name: Palaung + tag: "PLG " + codes: [pce, rbb, pll] +- name: Polish + tag: "PLK " + codes: [pol] +- name: Piemontese + tag: "PMS " + codes: [pms] +- name: Western Panjabi + tag: "PNB " + codes: [pnb] +- name: Pocomchi + tag: "POH " + codes: [poh] +- name: Pohnpeian + tag: "PON " + codes: [pon] +- name: Provençal / Old Provençal + tag: "PRO " + codes: [pro] +- name: Portuguese + tag: "PTG " + codes: [por] +- name: Western Pwo Karen + tag: "PWO " + codes: [pwo] +- name: Chin + tag: "QIN " + codes: [bgr, cnh, cnw, czt, sez, tcp, csy, ctd, flm, pck, tcz, zom, cmr, dao, hlt, cka, cnk, mrh, cbl, cnb, csh] +- name: K’iche’ + tag: "QUC " + codes: [quc] +- name: Quechua (Bolivia) + tag: "QUH " + codes: [quh] +- name: Quechua + tag: "QUZ " + codes: [quz] +- name: Quechua (Ecuador) + tag: "QVI " + codes: [qvi] +- name: Quechua (Peru) + tag: "QWH " + codes: [qwh] +- name: Rajasthani + tag: "RAJ " + codes: [raj] +- name: Rarotongan + tag: "RAR " + codes: [rar] +- name: Russian Buriat + tag: "RBU " + codes: [bxr] +- name: R-Cree + tag: "RCR " + codes: [atj] +- name: Rejang + tag: "REJ " + codes: [rej] +- name: Riang + tag: "RIA " + codes: [ria] +- name: Tarifit + tag: "RIF " + codes: [rif] +- name: Ritarungo + tag: "RIT " + codes: [rit] +- name: Arakwal + tag: "RKW " + codes: [rkw] +- name: Romansh + tag: "RMS " + codes: [roh] +- name: Vlax Romani + tag: "RMY " + codes: [rmy] +- name: Romanian + tag: "ROM " + codes: [ron] +- name: Romany + tag: "ROY " + codes: [rom] +- name: Rusyn + tag: "RSY " + codes: [rue] +- name: Rotuman + tag: "RTM " + codes: [rtm] +- name: Kinyarwanda + tag: "RUA " + codes: [kin] +- name: Rundi + tag: "RUN " + codes: [run] +- name: Aromanian + tag: "RUP " + codes: [rup] +- name: Russian + tag: "RUS " + codes: [rus] +- name: Sadri + tag: "SAD " + codes: [sck] +- name: Sanskrit + tag: "SAN " + codes: [san] +- name: Sasak + tag: "SAS " + codes: [sas] +- name: Santali + tag: "SAT " + codes: [sat] +- name: Sayisi + tag: "SAY " + codes: [chp] +- name: Sicilian + tag: "SCN " + codes: [scn] +- name: Scots + tag: "SCO " + codes: [sco] +- name: Sekota + tag: "SEK " + codes: [xan] +- name: Selkup + tag: "SEL " + codes: [sel] +- name: Old Irish + tag: "SGA " + codes: [sga] +- name: Sango + tag: "SGO " + codes: [sag] +- name: Samogitian + tag: "SGS " + codes: [sgs] +- name: Tachelhit + tag: "SHI " + codes: [shi] +- name: Shan + tag: "SHN " + codes: [shn] +- name: Sibe + tag: "SIB " + codes: [sjo] +- name: Sidamo + tag: "SID " + codes: [sid] +- name: Silte Gurage + tag: "SIG " + codes: [xst, stv, wle] +- name: Skolt Sami + tag: "SKS " + codes: [sms] +- name: Slovak + tag: "SKY " + codes: [slk] +- name: North Slavey + tag: "SCS " + codes: [scs] +- name: Slavey + tag: "SLA " + codes: [scs, xsl] +- name: Slovenian + tag: "SLV " + codes: [slv] +- name: Somali + tag: "SML " + codes: [som] +- name: Samoan + tag: "SMO " + codes: [smo] +- name: Sena + tag: "SNA " + codes: [seh] +- name: Shona + tag: SNA0 + codes: [sna] +- name: Sindhi + tag: "SND " + codes: [snd] +- name: Sinhala (Sinhalese) + tag: "SNH " + codes: [sin] +- name: Soninke + tag: "SNK " + codes: [snk] +- name: Sodo Gurage + tag: "SOG " + codes: [gru] +- name: Songe + tag: "SOP " + codes: [sop] +- name: Sotho, Southern + tag: "SOT " + codes: [sot] +- name: Albanian + tag: "SQI " + codes: [sqi] +- name: Serbian + tag: "SRB " + codes: [srp] +- name: Sardinian + tag: "SRD " + codes: [srd] +- name: Saraiki + tag: "SRK " + codes: [skr] +- name: Serer + tag: "SRR " + codes: [srr] +- name: South Slavey + tag: "SSL " + codes: [xsl] +- name: Southern Sami + tag: "SSM " + codes: [sma] +- name: Saterland Frisian + tag: "STQ " + codes: [stq] +- name: Sukuma + tag: "SUK " + codes: [suk] +- name: Sundanese + tag: "SUN " + codes: [sun] +- name: Suri + tag: "SUR " + codes: [suq] +- name: Svan + tag: "SVA " + codes: [sva] +- name: Swedish + tag: "SVE " + codes: [swe] +- name: Swadaya Aramaic + tag: "SWA " + codes: [aii] +- name: Swahili + tag: "SWK " + codes: [swa] +- name: Swati + tag: "SWZ " + codes: [ssw] +- name: Sutu + tag: "SXT " + codes: [ngo] +- name: Upper Saxon + tag: "SXU " + codes: [sxu] +- name: Sylheti + tag: "SYL " + codes: [syl] +- name: Syriac + tag: "SYR " + codes: [aii, amw, cld, syc, syr, tru] +- name: Syriac, Estrangela script-variant (equivalent to ISO 15924 "Syre") + tag: SYRE + codes: [syc, syr] +- name: Syriac, Western script-variant (equivalent to ISO 15924 "Syrj") + tag: SYRJ + codes: [syc, syr] +- name: Syriac, Eastern script-variant (equivalent to ISO 15924 "Syrn") + tag: SYRN + codes: [syc, syr] +- name: Silesian + tag: "SZL " + codes: [szl] +- name: Tabasaran + tag: "TAB " + codes: [tab] +- name: Tajiki + tag: "TAJ " + codes: [tgk] +- name: Tamil + tag: "TAM " + codes: [tam] +- name: Tatar + tag: "TAT " + codes: [tat] +- name: TH-Cree + tag: "TCR " + codes: [cwd] +- name: Dehong Dai + tag: "TDD " + codes: [tdd] +- name: Telugu + tag: "TEL " + codes: [tel] +- name: Tetum + tag: "TET " + codes: [tet] +- name: Tagalog + tag: "TGL " + codes: [tgl] +- name: Tongan + tag: "TGN " + codes: [ton] +- name: Tigre + tag: "TGR " + codes: [tig] +- name: Tigrinya + tag: "TGY " + codes: [tir] +- name: Thai + tag: "THA " + codes: [tha] +- name: Tahitian + tag: "THT " + codes: [tah] +- name: Tibetan + tag: "TIB " + codes: [bod] +- name: Tiv + tag: "TIV " + codes: [tiv] +- name: Turkmen + tag: "TKM " + codes: [tuk] +- name: Tamashek + tag: "TMH " + codes: [tmh] +- name: Temne + tag: "TMN " + codes: [tem] +- name: Tswana + tag: "TNA " + codes: [tsn] +- name: Tundra Nenets + tag: "TNE " + codes: [enh, yrk] +- name: Tonga + tag: "TNG " + codes: [toi] +- name: Todo + tag: "TOD " + codes: [xal] +- name: Toma + tag: TOD0 + codes: [tod] +- name: Tok Pisin + tag: "TPI " + codes: [tpi] +- name: Turkish + tag: "TRK " + codes: [tur] +- name: Tsonga + tag: "TSG " + codes: [tso] +- name: Tshangla + tag: "TSJ " + codes: [tsj] +- name: Turoyo Aramaic + tag: "TUA " + codes: [tru] +- name: Tulu + tag: "TUM " + codes: [tum] +- name: Tumbuka + tag: "TUL " + codes: [tcy] +- name: Tuvin + tag: "TUV " + codes: [tyv] +- name: Tuvalu + tag: "TVL " + codes: [tvl] +- name: Twi + tag: "TWI " + codes: [aka] +- name: Tày + tag: "TYZ " + codes: [tyz] +- name: Tamazight + tag: "TZM " + codes: [tzm] +- name: Tzotzil + tag: "TZO " + codes: [tzo] +- name: Udmurt + tag: "UDM " + codes: [udm] +- name: Ukrainian + tag: "UKR " + codes: [ukr] +- name: Umbundu + tag: "UMB " + codes: [umb] +- name: Urdu + tag: "URD " + codes: [urd] +- name: Upper Sorbian + tag: "USB " + codes: [hsb] +- name: Uyghur + tag: "UYG " + codes: [uig] +- name: Uzbek + tag: "UZB " + codes: [uzb] +- name: Venetian + tag: "VEC " + codes: [vec] +- name: Venda + tag: "VEN " + codes: [ven] +- name: Vietnamese + tag: "VIT " + codes: [vie] +- name: Volapük + tag: "VOL " + codes: [vol] +- name: Võro + tag: "VRO " + codes: [vro] +- name: Wa + tag: "WA " + codes: [wbm] +- name: Wagdi + tag: "WAG " + codes: [wbr] +- name: Waray-Waray + tag: "WAR " + codes: [war] +- name: West-Cree + tag: "WCR " + codes: [crk] +- name: Welsh + tag: "WEL " + codes: [cym] +- name: Walloon + tag: "WLN " + codes: [wln] +- name: Wolof + tag: "WLF " + codes: [wol] +- name: Mewati + tag: "WTM " + codes: [wtm] +- name: Lü + tag: "XBD " + codes: [khb] +- name: Khengkha + tag: "XKF " + codes: [xkf] +- name: Xhosa + tag: "XHS " + codes: [xho] +- name: Minjangbal + tag: "XJB " + codes: [xjb] +- name: Soga + tag: "XOG " + codes: [xog] +- name: Kpelle (Liberia) + tag: "XPE " + codes: [xpe] +- name: Sakha + tag: "YAK " + codes: [sah] +- name: Yao + tag: "YAO " + codes: [yao] +- name: Yapese + tag: "YAP " + codes: [yap] +- name: Yoruba + tag: "YBA " + codes: [yor] +- name: Y-Cree + tag: "YCR " + codes: [cre] +- name: Yi Classic + tag: "YIC " + codes: [] +- name: Yi Modern + tag: "YIM " + codes: [iii] +- name: Zealandic + tag: "ZEA " + codes: [zea] +- name: Standard Moroccan Tamazight + tag: "ZGH " + codes: [zgh] +- name: Zhuang + tag: "ZHA " + codes: [zha] +- name: Chinese, Hong Kong SAR + tag: "ZHH " + codes: [zho] +- name: Chinese Phonetic + tag: "ZHP " + codes: [zho] +- name: Chinese Simplified + tag: "ZHS " + codes: [zho] +- name: Chinese Traditional + tag: "ZHT " + codes: [zho] +- name: Zande + tag: "ZND " + codes: [zne] +- name: Zulu + tag: "ZUL " + codes: [zul] +- name: Zazaki + tag: "ZZA " + codes: [zza] \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 142906a..f5f170b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -42,28 +42,6 @@ docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] -[[package]] -name = "black" -version = "20.8b1" -description = "The uncompromising code formatter." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -appdirs = "*" -click = ">=7.1.2" -mypy-extensions = ">=0.4.3" -pathspec = ">=0.6,<1" -regex = ">=2020.1.8" -toml = ">=0.10.1" -typed-ast = ">=1.4.0" -typing-extensions = ">=3.7.4" - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] - [[package]] name = "booleanOperations" version = "0.9.0" @@ -76,6 +54,14 @@ python-versions = ">=3.6" fonttools = ">=4.0.2" pyclipper = ">=1.1.0.post1" +[[package]] +name = "certifi" +version = "2022.9.24" +description = "Python package for providing Mozilla's CA Bundle." +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "cffsubr" version = "0.2.9.post1" @@ -91,24 +77,23 @@ fontTools = ">=4.10.2" testing = ["pytest"] [[package]] -name = "click" -version = "8.1.3" -description = "Composable command line interface toolkit" -category = "dev" +name = "charset-normalizer" +version = "2.0.12" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.5.0" -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +[package.extras] +unicode_backport = ["unicodedata2"] [[package]] name = "colorama" -version = "0.4.5" +version = "0.4.6" description = "Cross-platform colored terminal text." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" [[package]] name = "cu2qu" @@ -134,7 +119,7 @@ python-versions = "*" [[package]] name = "fonttools" -version = "4.37.4" +version = "4.38.0" description = "Tools to manipulate font files" category = "main" optional = false @@ -175,7 +160,7 @@ scandir = ["scandir (>=1.5,<2.0)"] [[package]] name = "gflanguages" -version = "0.4.1.dev51+g26623df" +version = "0.4.2.dev1+gd200bc1" description = "A python API for evaluating language support in the Google Fonts collection." category = "main" optional = false @@ -183,13 +168,21 @@ python-versions = ">=3.7" develop = false [package.dependencies] -protobuf = "3.19.4" +protobuf = ">=3.19.4" [package.source] type = "git" url = "https://github.com/googlefonts/lang" reference = "HEAD" -resolved_reference = "26623dfe29bd1d4f97930b8043e15dc2ac48fea2" +resolved_reference = "d200bc1f7d693e3ea2e8c5b4a73abece9898b335" + +[[package]] +name = "idna" +version = "3.4" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" +optional = false +python-versions = ">=3.5" [[package]] name = "importlib-metadata" @@ -246,14 +239,6 @@ category = "dev" optional = false python-versions = ">=3.7" -[[package]] -name = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "num2words" version = "0.5.12" @@ -276,14 +261,6 @@ python-versions = ">=3.6" [package.dependencies] pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" -[[package]] -name = "pathspec" -version = "0.10.1" -description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" -optional = false -python-versions = ">=3.7" - [[package]] name = "pluggy" version = "0.13.1" @@ -383,12 +360,22 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" six = ">=1.5" [[package]] -name = "regex" -version = "2022.9.13" -description = "Alternative regular expression module, to replace re." -category = "dev" +name = "requests" +version = "2.27.1" +description = "Python HTTP for Humans." +category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} +idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] [[package]] name = "setuptools" @@ -456,7 +443,7 @@ python-versions = ">=3.7" [[package]] name = "ufo2ft" -version = "2.28.0" +version = "2.29.0" description = "A bridge between UFOs and FontTools." category = "main" optional = false @@ -466,7 +453,7 @@ python-versions = ">=3.7" booleanOperations = ">=0.9.0" cffsubr = ">=0.2.8" cu2qu = ">=1.6.7" -fonttools = {version = ">=4.34.0", extras = ["ufo"]} +fonttools = {version = ">=4.38.0", extras = ["ufo"]} [package.extras] compreffor = ["compreffor (>=0.4.6)"] @@ -474,12 +461,24 @@ pathops = ["skia-pathops (>=0.5.1)"] [[package]] name = "uharfbuzz" -version = "0.31.0" +version = "0.32.0" description = "Streamlined Cython bindings for the harfbuzz shaping engine" category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "urllib3" +version = "1.22" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" +optional = false +python-versions = "*" + +[package.extras] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + [[package]] name = "vharfbuzz" version = "0.1.4" @@ -508,9 +507,20 @@ category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +[[package]] +name = "youseedee" +version = "0.3.0" +description = "Interface to the Unicode Character Database" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +requests = "*" + [[package]] name = "zipp" -version = "3.9.0" +version = "3.10.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false @@ -523,7 +533,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = ">= 3.7" -content-hash = "0ad1308dfa47d649d30ba7be6dccb5e1ea3320f94d2d00b667de69f181c861ca" +content-hash = "8bc7390978df0dd5ab45e3ce632e6908f47f7506b79ec4ad470d028805391f2f" [metadata.files] appdirs = [ @@ -541,13 +551,14 @@ attrs = [ {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, ] -black = [ - {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, -] booleanOperations = [ {file = "booleanOperations-0.9.0-py3-none-any.whl", hash = "sha256:86c291c2fba9faedff6f007c932d7f242dd9b4304e9c6ca8149f864d07877a59"}, {file = "booleanOperations-0.9.0.zip", hash = "sha256:8cfa821c32ad374fa120d6b2e0b444ebeac57c91e6631528645fa19ac2a281b8"}, ] +certifi = [ + {file = "certifi-2022.9.24-py3-none-any.whl", hash = "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"}, + {file = "certifi-2022.9.24.tar.gz", hash = "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14"}, +] cffsubr = [ {file = "cffsubr-0.2.9.post1-py3-none-macosx_10_9_universal2.whl", hash = "sha256:768386249183e961c0e5e57e86c6c855f8ce71a13b9a43e0d2f936877bdb1135"}, {file = "cffsubr-0.2.9.post1-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:3b0ac2782af3b072179a2c0f43137e77dd6e1290749d7a45b23c008c05695639"}, @@ -556,13 +567,13 @@ cffsubr = [ {file = "cffsubr-0.2.9.post1-py3-none-win_amd64.whl", hash = "sha256:df01a53b71028b92db4c9680b8dab0710e97d9b7772fdb05a49ba6358a4118c3"}, {file = "cffsubr-0.2.9.post1.tar.gz", hash = "sha256:6b31412dcf49c8fa84664bda867e2eddc55b6fe6fa696ff253c4f13a9ff2fc5c"}, ] -click = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +charset-normalizer = [ + {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, + {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, ] colorama = [ - {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, - {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] cu2qu = [ {file = "cu2qu-1.6.7.post1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:885988713beee1a17c2b5586d19029422112fcdb3d38b6190b76fefb8ca8bb6d"}, @@ -588,14 +599,18 @@ docopt = [ {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, ] fonttools = [ - {file = "fonttools-4.37.4-py3-none-any.whl", hash = "sha256:afae1b39555f9c3f0ad1f0f1daf678e5ad157e38c8842ecb567951bf1a9b9fd7"}, - {file = "fonttools-4.37.4.zip", hash = "sha256:86918c150c6412798e15a0de6c3e0d061ddefddd00f97b4f7b43dfa867ad315e"}, + {file = "fonttools-4.38.0-py3-none-any.whl", hash = "sha256:820466f43c8be8c3009aef8b87e785014133508f0de64ec469e4efb643ae54fb"}, + {file = "fonttools-4.38.0.zip", hash = "sha256:2bb244009f9bf3fa100fc3ead6aeb99febe5985fa20afbfbaa2f8946c2fbdaf1"}, ] fs = [ {file = "fs-2.4.16-py2.py3-none-any.whl", hash = "sha256:660064febbccda264ae0b6bace80a8d1be9e089e0a5eb2427b7d517f9a91545c"}, {file = "fs-2.4.16.tar.gz", hash = "sha256:ae97c7d51213f4b70b6a958292530289090de3a7e15841e108fbe144f069d313"}, ] gflanguages = [] +idna = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] importlib-metadata = [ {file = "importlib_metadata-5.0.0-py3-none-any.whl", hash = "sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43"}, {file = "importlib_metadata-5.0.0.tar.gz", hash = "sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab"}, @@ -635,10 +650,6 @@ more-itertools = [ {file = "more-itertools-9.0.0.tar.gz", hash = "sha256:5a6257e40878ef0520b1803990e3e22303a41b5714006c32a3fd8304b26ea1ab"}, {file = "more_itertools-9.0.0-py3-none-any.whl", hash = "sha256:250e83d7e81d0c87ca6bd942e6aeab8cc9daa6096d12c5308f3f92fa5e5c1f41"}, ] -mypy-extensions = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, -] num2words = [ {file = "num2words-0.5.12-py3-none-any.whl", hash = "sha256:9eeef488658226ab36818c06d7aeb956d19b530fb62030596b6802fb4659f30e"}, {file = "num2words-0.5.12.tar.gz", hash = "sha256:7e7c0b0f080405aa3a1dd9d32b1ca90b3bf03bab17b8e54db05e1b78301a0988"}, @@ -647,10 +658,6 @@ packaging = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] -pathspec = [ - {file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"}, - {file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"}, -] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, @@ -737,95 +744,9 @@ python-dateutil = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] -regex = [ - {file = "regex-2022.9.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0394265391a86e2bbaa7606e59ac71bd9f1edf8665a59e42771a9c9adbf6fd4f"}, - {file = "regex-2022.9.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86df2049b18745f3cd4b0f4c4ef672bfac4b80ca488e6ecfd2bbfe68d2423a2c"}, - {file = "regex-2022.9.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce331b076b2b013e7d7f07157f957974ef0b0881a808e8a4a4b3b5105aee5d04"}, - {file = "regex-2022.9.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:360ffbc9357794ae41336b681dff1c0463193199dfb91fcad3ec385ea4972f46"}, - {file = "regex-2022.9.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18e503b1e515a10282b3f14f1b3d856194ecece4250e850fad230842ed31227f"}, - {file = "regex-2022.9.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e167d1ccd41d27b7b6655bb7a2dcb1b1eb1e0d2d662043470bd3b4315d8b2b"}, - {file = "regex-2022.9.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4146cb7ae6029fc83b5c905ec6d806b7e5568dc14297c423e66b86294bad6c39"}, - {file = "regex-2022.9.13-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a1aec4ae549fd7b3f52ceaf67e133010e2fba1538bf4d5fc5cd162a5e058d5df"}, - {file = "regex-2022.9.13-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cab548d6d972e1de584161487b2ac1aa82edd8430d1bde69587ba61698ad1cfb"}, - {file = "regex-2022.9.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3d64e1a7e6d98a4cdc8b29cb8d8ed38f73f49e55fbaa737bdb5933db99b9de22"}, - {file = "regex-2022.9.13-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:67a4c625361db04ae40ef7c49d3cbe2c1f5ff10b5a4491327ab20f19f2fb5d40"}, - {file = "regex-2022.9.13-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:5d0dd8b06896423211ce18fba0c75dacc49182a1d6514c004b535be7163dca0f"}, - {file = "regex-2022.9.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4318f69b79f9f7d84a7420e97d4bfe872dc767c72f891d4fea5fa721c74685f7"}, - {file = "regex-2022.9.13-cp310-cp310-win32.whl", hash = "sha256:26df88c9636a0c3f3bd9189dd435850a0c49d0b7d6e932500db3f99a6dd604d1"}, - {file = "regex-2022.9.13-cp310-cp310-win_amd64.whl", hash = "sha256:6fe1dd1021e0f8f3f454ce2811f1b0b148f2d25bb38c712fec00316551e93650"}, - {file = "regex-2022.9.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:83cc32a1a2fa5bac00f4abc0e6ce142e3c05d3a6d57e23bd0f187c59b4e1e43b"}, - {file = "regex-2022.9.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2effeaf50a6838f3dd4d3c5d265f06eabc748f476e8441892645ae3a697e273"}, - {file = "regex-2022.9.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59a786a55d00439d8fae4caaf71581f2aaef7297d04ee60345c3594efef5648a"}, - {file = "regex-2022.9.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b701dbc124558fd2b1b08005eeca6c9160e209108fbcbd00091fcfac641ac7"}, - {file = "regex-2022.9.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dab81cc4d58026861445230cfba27f9825e9223557926e7ec22156a1a140d55c"}, - {file = "regex-2022.9.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0c5cc3d1744a67c3b433dce91e5ef7c527d612354c1f1e8576d9e86bc5c5e2"}, - {file = "regex-2022.9.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:518272f25da93e02af4f1e94985f5042cec21557ef3591027d0716f2adda5d0a"}, - {file = "regex-2022.9.13-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8418ee2cb857b83881b8f981e4c636bc50a0587b12d98cb9b947408a3c484fe7"}, - {file = "regex-2022.9.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cfa4c956ff0a977c4823cb3b930b0a4e82543b060733628fec7ab3eb9b1abe37"}, - {file = "regex-2022.9.13-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:a1c4d17879dd4c4432c08a1ca1ab379f12ab54af569e945b6fc1c4cf6a74ca45"}, - {file = "regex-2022.9.13-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:77c2879d3ba51e5ca6c2b47f2dcf3d04a976a623a8fc8236010a16c9e0b0a3c7"}, - {file = "regex-2022.9.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2885ec6eea629c648ecc9bde0837ec6b92208b7f36381689937fe5d64a517e8"}, - {file = "regex-2022.9.13-cp311-cp311-win32.whl", hash = "sha256:2dda4b096a6f630d6531728a45bd12c67ec3badf44342046dc77d4897277d4f2"}, - {file = "regex-2022.9.13-cp311-cp311-win_amd64.whl", hash = "sha256:592b9e2e1862168e71d9e612bfdc22c451261967dbd46681f14e76dfba7105fd"}, - {file = "regex-2022.9.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:df8fe00b60e4717662c7f80c810ba66dcc77309183c76b7754c0dff6f1d42054"}, - {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:995e70bb8c91d1b99ed2aaf8ec44863e06ad1dfbb45d7df95f76ef583ec323a9"}, - {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad75173349ad79f9d21e0d0896b27dcb37bfd233b09047bc0b4d226699cf5c87"}, - {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7681c49da1a2d4b905b4f53d86c9ba4506e79fba50c4a664d9516056e0f7dfcc"}, - {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9bc8edc5f8ef0ebb46f3fa0d02bd825bbe9cc63d59e428ffb6981ff9672f6de1"}, - {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bee775ff05c9d519195bd9e8aaaccfe3971db60f89f89751ee0f234e8aeac5"}, - {file = "regex-2022.9.13-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1a901ce5cd42658ab8f8eade51b71a6d26ad4b68c7cfc86b87efc577dfa95602"}, - {file = "regex-2022.9.13-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:14a7ab070fa3aec288076eed6ed828587b805ef83d37c9bfccc1a4a7cfbd8111"}, - {file = "regex-2022.9.13-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d23ac6b4bf9e32fcde5fcdb2e1fd5e7370d6693fcac51ee1d340f0e886f50d1f"}, - {file = "regex-2022.9.13-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:4cdbfa6d2befeaee0c899f19222e9b20fc5abbafe5e9c43a46ef819aeb7b75e5"}, - {file = "regex-2022.9.13-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ab07934725e6f25c6f87465976cc69aef1141e86987af49d8c839c3ffd367c72"}, - {file = "regex-2022.9.13-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d2a1371dc73e921f3c2e087c05359050f3525a9a34b476ebc8130e71bec55e97"}, - {file = "regex-2022.9.13-cp36-cp36m-win32.whl", hash = "sha256:fcbd1edff1473d90dc5cf4b52d355cf1f47b74eb7c85ba6e45f45d0116b8edbd"}, - {file = "regex-2022.9.13-cp36-cp36m-win_amd64.whl", hash = "sha256:fe428822b7a8c486bcd90b334e9ab541ce6cc0d6106993d59f201853e5e14121"}, - {file = "regex-2022.9.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d7430f041755801b712ec804aaf3b094b9b5facbaa93a6339812a8e00d7bd53a"}, - {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:079c182f99c89524069b9cd96f5410d6af437e9dca576a7d59599a574972707e"}, - {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59bac44b5a07b08a261537f652c26993af9b1bbe2a29624473968dd42fc29d56"}, - {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a59d0377e58d96a6f11636e97992f5b51b7e1e89eb66332d1c01b35adbabfe8a"}, - {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9d68eb704b24bc4d441b24e4a12653acd07d2c39940548761e0985a08bc1fff"}, - {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0385d66e73cdd4462f3cc42c76a6576ddcc12472c30e02a2ae82061bff132c32"}, - {file = "regex-2022.9.13-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:db45016364eec9ddbb5af93c8740c5c92eb7f5fc8848d1ae04205a40a1a2efc6"}, - {file = "regex-2022.9.13-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:03ff695518482b946a6d3d4ce9cbbd99a21320e20d94913080aa3841f880abcd"}, - {file = "regex-2022.9.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6b32b45433df1fad7fed738fe15200b6516da888e0bd1fdd6aa5e50cc16b76bc"}, - {file = "regex-2022.9.13-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:003a2e1449d425afc817b5f0b3d4c4aa9072dd5f3dfbf6c7631b8dc7b13233de"}, - {file = "regex-2022.9.13-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:a9eb9558e1d0f78e07082d8a70d5c4d631c8dd75575fae92105df9e19c736730"}, - {file = "regex-2022.9.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f6e0321921d2fdc082ef90c1fd0870f129c2e691bfdc4937dcb5cd308aba95c4"}, - {file = "regex-2022.9.13-cp37-cp37m-win32.whl", hash = "sha256:3f3b4594d564ed0b2f54463a9f328cf6a5b2a32610a90cdff778d6e3e561d08b"}, - {file = "regex-2022.9.13-cp37-cp37m-win_amd64.whl", hash = "sha256:8aba0d01e3dfd335f2cb107079b07fdddb4cd7fb2d8c8a1986f9cb8ce9246c24"}, - {file = "regex-2022.9.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:944567bb08f52268d8600ee5bdf1798b2b62ea002cc692a39cec113244cbdd0d"}, - {file = "regex-2022.9.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0b664a4d33ffc6be10996606dfc25fd3248c24cc589c0b139feb4c158053565e"}, - {file = "regex-2022.9.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f06cc1190f3db3192ab8949e28f2c627e1809487e2cfc435b6524c1ce6a2f391"}, - {file = "regex-2022.9.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c57d50d4d5eb0c862569ca3c840eba2a73412f31d9ecc46ef0d6b2e621a592b"}, - {file = "regex-2022.9.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19a4da6f513045f5ba00e491215bd00122e5bd131847586522463e5a6b2bd65f"}, - {file = "regex-2022.9.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a926339356fe29595f8e37af71db37cd87ff764e15da8ad5129bbaff35bcc5a6"}, - {file = "regex-2022.9.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:091efcfdd4178a7e19a23776dc2b1fafb4f57f4d94daf340f98335817056f874"}, - {file = "regex-2022.9.13-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:880dbeb6bdde7d926b4d8e41410b16ffcd4cb3b4c6d926280fea46e2615c7a01"}, - {file = "regex-2022.9.13-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:73b985c9fc09a7896846e26d7b6f4d1fd5a20437055f4ef985d44729f9f928d0"}, - {file = "regex-2022.9.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c0b7cb9598795b01f9a3dd3f770ab540889259def28a3bf9b2fa24d52edecba3"}, - {file = "regex-2022.9.13-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:37e5a26e76c46f54b3baf56a6fdd56df9db89758694516413757b7d127d4c57b"}, - {file = "regex-2022.9.13-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:99945ddb4f379bb9831c05e9f80f02f079ba361a0fb1fba1fc3b267639b6bb2e"}, - {file = "regex-2022.9.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dcbcc9e72a791f622a32d17ff5011326a18996647509cac0609a7fc43adc229"}, - {file = "regex-2022.9.13-cp38-cp38-win32.whl", hash = "sha256:d3102ab9bf16bf541ca228012d45d88d2a567c9682a805ae2c145a79d3141fdd"}, - {file = "regex-2022.9.13-cp38-cp38-win_amd64.whl", hash = "sha256:14216ea15efc13f28d0ef1c463d86d93ca7158a79cd4aec0f9273f6d4c6bb047"}, - {file = "regex-2022.9.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9a165a05979e212b2c2d56a9f40b69c811c98a788964e669eb322de0a3e420b4"}, - {file = "regex-2022.9.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:14c71437ffb89479c89cc7022a5ea2075a842b728f37205e47c824cc17b30a42"}, - {file = "regex-2022.9.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee7045623a5ace70f3765e452528b4c1f2ce669ed31959c63f54de64fe2f6ff7"}, - {file = "regex-2022.9.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6e521d9db006c5e4a0f8acfef738399f72b704913d4e083516774eb51645ad7c"}, - {file = "regex-2022.9.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b86548b8234b2be3985dbc0b385e35f5038f0f3e6251464b827b83ebf4ed90e5"}, - {file = "regex-2022.9.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b39ee3b280e15824298b97cec3f7cbbe6539d8282cc8a6047a455b9a72c598"}, - {file = "regex-2022.9.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6e6e61e9a38b6cc60ca3e19caabc90261f070f23352e66307b3d21a24a34aaf"}, - {file = "regex-2022.9.13-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d837ccf3bd2474feabee96cd71144e991472e400ed26582edc8ca88ce259899c"}, - {file = "regex-2022.9.13-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6adfe300848d61a470ec7547adc97b0ccf86de86a99e6830f1d8c8d19ecaf6b3"}, - {file = "regex-2022.9.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d5b003d248e6f292475cd24b04e5f72c48412231961a675edcb653c70730e79e"}, - {file = "regex-2022.9.13-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:d5edd3eb877c9fc2e385173d4a4e1d792bf692d79e25c1ca391802d36ecfaa01"}, - {file = "regex-2022.9.13-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:50e764ffbd08b06aa8c4e86b8b568b6722c75d301b33b259099f237c46b2134e"}, - {file = "regex-2022.9.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6d43bd402b27e0e7eae85c612725ba1ce7798f20f6fab4e8bc3de4f263294f03"}, - {file = "regex-2022.9.13-cp39-cp39-win32.whl", hash = "sha256:7fcf7f94ccad19186820ac67e2ec7e09e0ac2dac39689f11cf71eac580503296"}, - {file = "regex-2022.9.13-cp39-cp39-win_amd64.whl", hash = "sha256:322bd5572bed36a5b39952d88e072738926759422498a96df138d93384934ff8"}, - {file = "regex-2022.9.13.tar.gz", hash = "sha256:f07373b6e56a6f3a0df3d75b651a278ca7bd357a796078a26a958ea1ce0588fd"}, +requests = [ + {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, + {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, ] setuptools = [ {file = "setuptools-65.5.0-py3-none-any.whl", hash = "sha256:f62ea9da9ed6289bfe868cd6845968a2c854d1427f8548d52cae02a42b4f0356"}, @@ -882,52 +803,56 @@ typing-extensions = [ {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, ] ufo2ft = [ - {file = "ufo2ft-2.28.0-py2.py3-none-any.whl", hash = "sha256:abd5a35b45232daad208f346ca1f0027883d9f6c7d7bcf84192eaebc1d35ffbc"}, - {file = "ufo2ft-2.28.0.tar.gz", hash = "sha256:a561ef8c0bc735696626243be49466172ae3627cdb246eccf3f0c6a085a91019"}, + {file = "ufo2ft-2.29.0-py2.py3-none-any.whl", hash = "sha256:0f77eba1184829f851be0906bac89047b8f22d7d66015564852c981dc43df72d"}, + {file = "ufo2ft-2.29.0.tar.gz", hash = "sha256:b8af42a957f2cc7fdd70df5457cc05bb89be88f6d5e8d54a038e3aa82f5a024d"}, ] uharfbuzz = [ - {file = "uharfbuzz-0.31.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f1243031eb84c28f99771fd47f994a2d57111663aba7e6b7543e09123fe1350e"}, - {file = "uharfbuzz-0.31.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:592db372e21c4993ae827f045d64da782a2a06a2617150921369ab10f5713992"}, - {file = "uharfbuzz-0.31.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12a207f0cc827babef95e9ba16b5a78da6145af988dfe0145f275f5c9d373241"}, - {file = "uharfbuzz-0.31.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78eb16db2bb589859d2a8e1df1699bd3c44828ddaaef208115e507b2b9fca93b"}, - {file = "uharfbuzz-0.31.0-cp310-cp310-win32.whl", hash = "sha256:1141530e0902e087a8f76d664cce7cca86aaba149e48425851f315ccfc25210f"}, - {file = "uharfbuzz-0.31.0-cp310-cp310-win_amd64.whl", hash = "sha256:153813fd2f49f7e6f9ef3661491d656ff2f14ab01b6237752862f741f38cf374"}, - {file = "uharfbuzz-0.31.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2c5e2061cb32c03063189f94bc1b88b6f83c341cd9585f97a30699f1ca556db2"}, - {file = "uharfbuzz-0.31.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:98bfcba56973a2b6b54a474867d12e0f4806e4c05ab33080b7e51f4db00a46bf"}, - {file = "uharfbuzz-0.31.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a28cde98d3a362be5a2dd505ae1006d9b1f7e6e39af8dae7f5453b75cfd4b56e"}, - {file = "uharfbuzz-0.31.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12a8079ed43533f771010cd356e3bc8a30c5162ff20174a34044ad97dbbb6947"}, - {file = "uharfbuzz-0.31.0-cp311-cp311-win32.whl", hash = "sha256:ce1ad9f94fb03e9dc28a983939e79e0aab5622bced8549e0cff2881c38cea080"}, - {file = "uharfbuzz-0.31.0-cp311-cp311-win_amd64.whl", hash = "sha256:b1eb559d9d76d132c533e3a340409d7baad6c47539eef3c4d4f10906dde613e0"}, - {file = "uharfbuzz-0.31.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:29daf822fe146f93a006c0a07400a708213a313b97b59f935854aa095777e9b5"}, - {file = "uharfbuzz-0.31.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76507b963cf7e40277b83a92220426f29dad10c1610a3ae157a4a7efca6da180"}, - {file = "uharfbuzz-0.31.0-cp36-cp36m-win32.whl", hash = "sha256:811e8ba8b4dc63dadc9317c2cd0cc80aa0d6d196e08e0f048ec88983e51ef3c5"}, - {file = "uharfbuzz-0.31.0-cp36-cp36m-win_amd64.whl", hash = "sha256:08ddd3799ee0c903531ea6d9532199b59f9782c40e74b1c212007ce783b093a5"}, - {file = "uharfbuzz-0.31.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:1cbf7b6cdb0e32c20beff436c3390a8ee8c7f628b79ef56fa5034df011f577d0"}, - {file = "uharfbuzz-0.31.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74b87ec6dc89c70fa36bbd71decca53d4318d42a8e83b8d862d1f4bb1eb80581"}, - {file = "uharfbuzz-0.31.0-cp37-cp37m-win32.whl", hash = "sha256:0dedc3e1690c16da33f6e16579b5fc9a3d960ce89c40f0f0fc0c0ff85656a62d"}, - {file = "uharfbuzz-0.31.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4f50fb85a590d1b66c32f4d66e7a5d4e2b88fb1a1b9fa68f4c2cc7113d1bab02"}, - {file = "uharfbuzz-0.31.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8d5847174ddcfece2439a198a761e8f64a31246e4aa4b41fa4be01538f8edbc2"}, - {file = "uharfbuzz-0.31.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f76049adab2ef5b9ad58249a6d1ba2569c2749830add6d7e7380dd1780be8650"}, - {file = "uharfbuzz-0.31.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d5540d7137e4c430d0e164a49002656513d8b9296ca5b22c3e54d08b77993175"}, - {file = "uharfbuzz-0.31.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cd9a9b6f0fbbe108e6aab3f3414fdf134dfae5882f83557ae23d67a5b33b37"}, - {file = "uharfbuzz-0.31.0-cp38-cp38-win32.whl", hash = "sha256:1db15e50cde2519abbf9f6ff5f74a9ea1aa47c25393a4024d7c3bf3bd36d61dc"}, - {file = "uharfbuzz-0.31.0-cp38-cp38-win_amd64.whl", hash = "sha256:a5d761ec37564bced80d2e03f57a6b8395334e046b67e0bcf9ee3581d3416472"}, - {file = "uharfbuzz-0.31.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bab979867799d2a98d8e8ce290762b3d0a3cbaf6daf764136c75b0c337c0a12b"}, - {file = "uharfbuzz-0.31.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:44e8b8a7507af0317709a486874df6cf095b80324128548a03da69d743cc2d30"}, - {file = "uharfbuzz-0.31.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d6ed5b31200232b0df94cb28000988cffad293e149c1f2e657b95bfb92db887e"}, - {file = "uharfbuzz-0.31.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d08da708690a9e5b67f7ca6f649e76d469b56b038eb67e479e1dab95652d346a"}, - {file = "uharfbuzz-0.31.0-cp39-cp39-win32.whl", hash = "sha256:7f174176e5437ec58d5ad03af1c7926adec6d340bd94603726134b51d595091f"}, - {file = "uharfbuzz-0.31.0-cp39-cp39-win_amd64.whl", hash = "sha256:ee080496c2c7995f42989c5c2930bdd9554564d34974b248e70d87f30723105c"}, - {file = "uharfbuzz-0.31.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:15a1d1aa07ae49fa9d89b67a8996bd7118cb7bf4a4f2619015d1b3c4dad5254b"}, - {file = "uharfbuzz-0.31.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad466747b9034472d2eccb8bbb8caf330552359e48933e1c66209eb2114dd083"}, - {file = "uharfbuzz-0.31.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:b4e7f899c19883f367fa7b6dad0fc40606881f287af8f6aa0ad71a8fc7a826f9"}, - {file = "uharfbuzz-0.31.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:14e3ea8bafd26725a9f0a7534de394f9936e6cb3072aad22b82cb906d73efd9e"}, - {file = "uharfbuzz-0.31.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:987f0518a8f4ca7d3e8a1335595d4eaa7682a88e725fcbb716a92dd6953affa0"}, - {file = "uharfbuzz-0.31.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cc0d705dfcadaeb60d6035b2ebb06ce2dfd7dcbf0bbd8d861ecbb5df7c8540f5"}, - {file = "uharfbuzz-0.31.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4f4e470393e4f145b766c951f09e0a67f3b35039cbaade4176ad5f3bde83dd92"}, - {file = "uharfbuzz-0.31.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:944ead7acf27713881214996a40d6e80a481640cd205066ff6ddd80908b50bfc"}, - {file = "uharfbuzz-0.31.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6f282945e85550fd26c6f1fe032b8734569cbc3bd05d612a6a2ab0cee29cacc7"}, - {file = "uharfbuzz-0.31.0.zip", hash = "sha256:fc5da07133053e5eb2073b04c13dcb2ef992a816f2e04f80036f7e97e275f5da"}, + {file = "uharfbuzz-0.32.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:151603a44e1d6441777ccef28698d9285919882c0daf9d942868fdb7a9682a65"}, + {file = "uharfbuzz-0.32.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3ff0376cc775276777ce9e788f5ca7c78a3ef46041613e184a88629d4c15bae6"}, + {file = "uharfbuzz-0.32.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86cc96e4186fa3e80b91e7ef76094605e8b5c2bcfecaf4fff94453c6eb0ef82e"}, + {file = "uharfbuzz-0.32.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9648daf8717bd150affc338f6937b167b94bec1264175ea62199d8a710e7b4a"}, + {file = "uharfbuzz-0.32.0-cp310-cp310-win32.whl", hash = "sha256:24efef8f6b039d7834d6b8d0828b4ce89bc9be57abd2d5ea2027997cbbb93eff"}, + {file = "uharfbuzz-0.32.0-cp310-cp310-win_amd64.whl", hash = "sha256:52de9122f3961dc65f6fc9374b07b8ea3ea9c79b618d8c8b006f8f1f9fdf1e02"}, + {file = "uharfbuzz-0.32.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:242051369f8cf61df385e7b3b497e653bdf7698cea7ae39f75f4465cd7dc8ac2"}, + {file = "uharfbuzz-0.32.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:95f1b9e78b0b51f02b75d3dde3bd0bec5cffac96b60f27eb30505c92f7b54c91"}, + {file = "uharfbuzz-0.32.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:facfb1cad8779b9fbf16a19f1675d175b6936570009fc16909634a3d83870bca"}, + {file = "uharfbuzz-0.32.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5bac3198b5c543650dccb9b3d92db8f3e124683b966c095b16f6fac93564341f"}, + {file = "uharfbuzz-0.32.0-cp311-cp311-win32.whl", hash = "sha256:790827fe825b69e5b89e17323f25a3f5223b428168099ca6203caf9fafaf8bcb"}, + {file = "uharfbuzz-0.32.0-cp311-cp311-win_amd64.whl", hash = "sha256:b81ead7fa91b66b43a7caa57e70943539028ca781ee3d267665b592fc68851a9"}, + {file = "uharfbuzz-0.32.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:258ef5ffc57de465c2433648923afaf5589ca39cf0df2c6c65c52f353bc35f07"}, + {file = "uharfbuzz-0.32.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:726faa21f51b18f3fb9d9f6b488d8d49a6016b4cbb7733c01dff6da437181e40"}, + {file = "uharfbuzz-0.32.0-cp36-cp36m-win32.whl", hash = "sha256:5694e2aed81fc5f541a2ebc3aa53b967cc48898520556bcad7fbcd352d21d5da"}, + {file = "uharfbuzz-0.32.0-cp36-cp36m-win_amd64.whl", hash = "sha256:fbaba7b4834573f689012e7bf002948cf71da03ef4adff0f638bde7f6397c775"}, + {file = "uharfbuzz-0.32.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:17373daf08faf0044770f74dc06cd1f589e7306f6b737b15dacf1a5f997cb730"}, + {file = "uharfbuzz-0.32.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f61e4cf32e3e5c75086a67638053053036a2e7172fc61ddff0f66ec9ca242b2"}, + {file = "uharfbuzz-0.32.0-cp37-cp37m-win32.whl", hash = "sha256:772c8b48b82a7eeb93e722badf9dd09921e1d65ff52f8224d51130fcb86aa1d6"}, + {file = "uharfbuzz-0.32.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c14360e3347b1b34efa98a0dba5fed0863b71f222b2b14e221c76503f78a6ce1"}, + {file = "uharfbuzz-0.32.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:66836f87e47ba2ca34b7691016c7bf8fa3c44448382da90e2684412d53daf4d5"}, + {file = "uharfbuzz-0.32.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b794bdc63ef805f26246a9694d4936162101d4be89ed156f1c08060c42a88006"}, + {file = "uharfbuzz-0.32.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:372d3cdda722875b8c97b42e6987160c3328fddf8d439b94742d5e5555207df7"}, + {file = "uharfbuzz-0.32.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04cdc453977759569c8adf1a6d2fde02e95caaf7a8ce9c41054aabf5a88446b9"}, + {file = "uharfbuzz-0.32.0-cp38-cp38-win32.whl", hash = "sha256:18357ca239614d771d59978eb36612a2b1e33e514511c11eee0acf763afeb2b0"}, + {file = "uharfbuzz-0.32.0-cp38-cp38-win_amd64.whl", hash = "sha256:659076f5fe844857b69699484c25499fb640d11f8ca635d1dfd7774f1c4e5fa5"}, + {file = "uharfbuzz-0.32.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:32139f2d5df48230a3a39c6ffc3e0654ddd7b78dd6175e48b3bddef38a6001d1"}, + {file = "uharfbuzz-0.32.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bab7313490fb1cee2e60d2388e7bf60aae750aaa4a443e242937da3b2fd8066b"}, + {file = "uharfbuzz-0.32.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2c7f140b9e7cf30081a5b617c752790b6ff0c4b016bac7784a51ff574a7166ee"}, + {file = "uharfbuzz-0.32.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55baec4f951dae377099f4a91e10a18f65fd80012cf723e7cbd85c088ef94d35"}, + {file = "uharfbuzz-0.32.0-cp39-cp39-win32.whl", hash = "sha256:143e3f9050cb2d16926a10d161fc0beb276a00b7acb570ab165f6e9ead5806d3"}, + {file = "uharfbuzz-0.32.0-cp39-cp39-win_amd64.whl", hash = "sha256:59ac2f51354e604963f26dbe22e337544562b90ea78a9850361b124b04337ef0"}, + {file = "uharfbuzz-0.32.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6a4e01d8df0f3b1a5f0dacd6fdaacd5ab7957c3637fc1b40ceb369093161c92e"}, + {file = "uharfbuzz-0.32.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8a3499e766b925b79d26adab17a5e9ead11ace1eaa9830df11cf68061b42b60"}, + {file = "uharfbuzz-0.32.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:fbecf72e22b3f6f8c498f87356c90a7de5eea9670f297caa5565be1d84945bb2"}, + {file = "uharfbuzz-0.32.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:faf80398c8aff75a95a24f2e2633f0bc1bf29b49a2056017ee1dee443fd5caa0"}, + {file = "uharfbuzz-0.32.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a17ee362791ad3d8cf18509845b2501d5cb766279c54798704f5eedf7c3f19b3"}, + {file = "uharfbuzz-0.32.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:32c5decfd36225c1726b9a32ff126b75616134d29d900addeb3de6a53605870b"}, + {file = "uharfbuzz-0.32.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f12f451fc46b993e5313698296607923f08b6f198ce4a493293b3d6be7dd22e6"}, + {file = "uharfbuzz-0.32.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e83068ac19d321d08fb5780929d00d5310eb0bacc980ed3fed8ef6dfcc75199b"}, + {file = "uharfbuzz-0.32.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2652a046d31c842434d9155f621353fd604b89ca5a98a8189ac678f7351cbc76"}, + {file = "uharfbuzz-0.32.0.zip", hash = "sha256:209ac2abe706b6129e160dd4a18aeae813c09e10e43c116e67a76fb025cb8cbc"}, +] +urllib3 = [ + {file = "urllib3-1.22-py2.py3-none-any.whl", hash = "sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b"}, + {file = "urllib3-1.22.tar.gz", hash = "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f"}, ] vharfbuzz = [ {file = "vharfbuzz-0.1.4-py3-none-any.whl", hash = "sha256:7cf3299669661c5aa62bfec277846006f20b74b26839d02bce66a9636f7e1b6a"}, @@ -1003,7 +928,11 @@ wrapt = [ {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] +youseedee = [ + {file = "youseedee-0.3.0-py3-none-any.whl", hash = "sha256:4fd21aa6da264694113831546cfee008954e44df650e7909ac02f4404bf5de4f"}, + {file = "youseedee-0.3.0.tar.gz", hash = "sha256:596c1112230bdd154b6d6c962872933e16748ae8efd7cb2389b922cc9aabcab0"}, +] zipp = [ - {file = "zipp-3.9.0-py3-none-any.whl", hash = "sha256:972cfa31bc2fedd3fa838a51e9bc7e64b7fb725a8c00e7431554311f180e9980"}, - {file = "zipp-3.9.0.tar.gz", hash = "sha256:3a7af91c3db40ec72dd9d154ae18e008c69efe8ca88dde4f9a731bb82fe2f9eb"}, + {file = "zipp-3.10.0-py3-none-any.whl", hash = "sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1"}, + {file = "zipp-3.10.0.tar.gz", hash = "sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8"}, ] diff --git a/pyproject.toml b/pyproject.toml index 461c974..8e7acfb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,11 +35,12 @@ vharfbuzz = "^0" strictyaml = "*" num2words = "^0.5" ufo2ft = "*" +youseedee = "*" +protobuf = "3.19.4" [tool.poetry.dev-dependencies] # Formatters -black = "=20.8b1" pylint = "~2.6.0" pytest = "^5.3.2" @@ -56,3 +57,12 @@ skip-string-normalization = true requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" + +[tool.pylint."messages control"] +good-names = [ + "fh", + "e", + "ix", +] +disable=["broad-except", "missing-module-docstring", "no-self-use", "too-many-instance-attributes", "missing-function-docstring", "missing-class-docstring", "duplicate-code","too-many-branches"] +max-line-length=120 diff --git a/scripts/bulk-sg-run.py b/scripts/bulk-sg-run.py new file mode 100644 index 0000000..c2eea2d --- /dev/null +++ b/scripts/bulk-sg-run.py @@ -0,0 +1,132 @@ +import argparse +import os +import subprocess +import glob +import yaml +from multiprocessing import Pool +from pathlib import Path +from itertools import repeat + +from shaperglot.languages import Languages +from shaperglot.checker import Checker +from shaperglot.reporter import Result + +gflangs = Languages() + + +with open("./language_tag_data/iso639-3-afr-all.txt", "r") as f2: + afr_tags = f2.read().splitlines() + +output = open("results.txt", "w", encoding="utf8") +results = open("results.yaml", "w", encoding="utf8") +summary = open("summary.csv", "w", encoding="utf8") + +isoconv = { + "aar": "aa", + "afr": "af", + "aka": "ak", + "amh": "am", + "bam": "bm", + "ewe": "ee", + "ful": "ff", + "hau": "ha", + "her": "hz", + "ibo": "ig", + "kik": "ki", + "kin": "rw", + "kon": "kg", + "kua": "kj", + "lin": "ln", + "lub": "lu", + "lug": "lg", + "mlg": "mg", + "nbl": "nr", + "nde": "nd", + "ndo": "ng", + "nya": "ny", + "orm": "om", + "run": "rn", + "sag": "sg", + "sna": "sn", + "som": "so", + "sot": "st", + "ssw": "ss", + "swa": "sw", + "tir": "ti", + "tsn": "tn", + "tso": "ts", + "twi": "tw", + "ven": "ve", + "wol": "wo", + "xho": "xh", + "yor": "yo", +} + + +# afr_tags = ["dje", "agq", "ro", "bjp", "bas"] + + +def summarize(tag, fontname, results): + for message in results: + if message.result == Result.PASS: + continue + elif message.result_code == "bases-missing": + errcount = str(len(message.context["glyphs"])) + summary.write(fontname + "," + tag + ",missing base," + errcount + "\n") + elif message.result_code == "marks-missing": + errcount = str(len(message.context["glyphs"])) + summary.write(fontname + "," + tag + ",missing mark," + errcount + "\n") + elif message.check_name == "no-orphaned-marks": + summary.write(fontname + "," + tag + ",orphaned marks,1\n") + + +def check_one(font, available_tags): + checker = Checker(font) + print(f"analyzing {font}") + results_for_font = {} + for tag, item in available_tags.items(): + results_for_font[tag] = checker.check(gflangs[item]) + return results_for_font + + +def main(args=None): + parser = argparse.ArgumentParser(description="Check a library for African language support") + parser.add_argument('directory', + help='directory to check') + + args = parser.parse_args() + fonts = [str(f) for f in Path(args.directory).glob("**/*.ttf")] + + tag_results = {} + missing_tags = [] + available_tags = {} + + for tag in afr_tags: + if isoconv.get(tag) is not None: + item = isoconv.get(tag) + "_Latn" + else: + item = tag + "_Latn" + if item not in gflangs: + missing_tags.append(item) + continue + available_tags[tag] = item + + args = zip(fonts, repeat(available_tags)) + with Pool() as p: + all_font_results = p.starmap(check_one, args) + for font, font_results in zip(fonts, all_font_results): + fontname = Path(font).stem + for tag, this_tag_results in font_results.items(): + summarize(tag, fontname, this_tag_results) + fails = [ + message.message for message in this_tag_results if message.result != Result.PASS + ] + if fails: + tag_results.setdefault(tag, {})[fontname] = fails + + tag_results["Missing GFLang Data"] = missing_tags + yaml.safe_dump(tag_results, results, allow_unicode=True, sort_keys=False) + + +if __name__ == "__main__": + main() diff --git a/scripts/sg-bulk-builder.py b/scripts/sg-bulk-builder.py new file mode 100644 index 0000000..b17da62 --- /dev/null +++ b/scripts/sg-bulk-builder.py @@ -0,0 +1,146 @@ +from itertools import permutations +import os +from xxlimited import new +import yaml +import sys +import unicodedata +import itertools +from gflanguages import LoadLanguages, LoadScripts +from google.protobuf.json_format import MessageToDict + +gflangs = LoadLanguages() +gfscripts = LoadScripts() + +isoconv = {"aar": "aa", "afr": "af", "aka": "ak", "amh": "am", "bam": "bm", "ewe": "ee", "ful": "ff", "hau": "ha", "her": "hz", "ibo": "ig", "kik": "ki", "kin": "rw", "kon": "kg", "kua": "kj", "lin": "ln", "lub": "lu", "lug": "lg", "mlg": "mg", "nbl": "nr", "nde": "nd", "ndo": "ng", "nya": "ny", "orm": "om", "run": "rn", "sag": "sg", "sna": "sn", "som": "so", "sot": "st", "ssw": "ss", "swa": "sw", "tir": "ti", "tsn": "tn", "tso": "ts", "twi": "tw", "ven": "ve", "wol": "wo", "xho": "xh", "yor": "yo"} + +with open('./language_tag_data/ot-lang-tags.yaml', 'r') as f: + ot_tags = yaml.safe_load(f) + #debug pprint(dataMap) + +with open('./language_tag_data/iso639-3-afr-all.txt', 'r') as f2: + afr_tags = f2.read().splitlines() + +def create_file(profile_name): + path = "./shaperglot/languages/" + os.makedirs(os.path.dirname(path), exist_ok=True) + profile = open(path + profile_name, "w") + return profile + +def collect(lang): + exemplar_chars = lang.get("exemplarChars", {}) + marks = exemplar_chars.get("marks", "").replace("◌", "").split() or [] + bases = exemplar_chars.get("base", "").split() or [] + auxiliary = exemplar_chars.get("auxiliary", "").split() or [] + return(bases, auxiliary, marks) + +def check_ot_tags (tag): #to be used for unencoded glyph variant check + for ot_tag in ot_tags: + if tag in ot_tag['codes']: + return(True) + else: + return(False) + +def build_unencoded_gv(record, bases, auxiliary): #to be used for unencoded glyph variant check + if record.get("exemplarChars"): + if "\u014A" in bases or '\u014A' in auxiliary: + return(True) + +def build_no_orphaned_marks(bases, auxiliary): + basemarks = [] + nom_test = [] + nom_smcp_test = [] + new_basemarks = [] + + for base in bases: + if len(base) > 1 : + unpack = base.replace("{", "").replace("}", "") + for char in unpack: + if unicodedata.combining(char): + basemarks.append(unpack) + for aux in auxiliary: + if len(aux) > 1: + unpack = aux.replace("{", "").replace("}", "") + for char in unpack: + if unicodedata.combining(char): + basemarks.append(unpack) + + for basemark in basemarks: + if len(basemark) > 2: + base_only = basemark[0] + marks_only = "basemark"[1:len(basemark)] + for i in itertools.permutations(marks_only, len(marks_only)): #generate mark permutations + new_basemark = base_only.join(i) + new_basemarks.append(new_basemark) + + if new_basemarks: + basemark_string = "".join(basemarks).join(new_basemarks) + else: + basemark_string = "".join(basemarks) + + if basemark_string: + nom_test = {"check": "no_orphaned_marks", "input": {"text": basemark_string}} + nom_smcp_test = {"check": "no_orphaned_marks", "input": {"text": basemark_string, "features": {"smcp": True}}} + return(nom_test, nom_smcp_test) + +def build_results(item, new_profile): + profile = "" + if(profile == ''): + current_script = item + profile_name = '%s.yaml' % item + profile = create_file(profile_name) + profile.write("#auto-generated using sg-bulk-builder.py\n") + yaml.safe_dump(new_profile, profile, allow_unicode=True, sort_keys=False) + print("Building " + item + ".yaml") + elif(item != current_script): + profile.close + current_script = item + profile_name = '%s.yaml' % item + profile = create_file(profile_name) + profile.write("#auto-generated using sg-bulk-builder.py\n") + yaml.safe_dump(new_profile, profile, allow_unicode=True, sort_keys=False) + print("Building " + item + ".yaml") + + + +def main(): + new_profile = [] + record = {} + all_tags = 0 + with_record = 0 + with_ot_tags = 0 + with_exemplars = 0 + needs_variant = 0 + + + for tag in afr_tags: + new_profile = [] + + all_tags = all_tags + 1 + item = "" + if isoconv.get(tag) is not None: + item = isoconv.get(tag)+"_Latn" + else: + item = tag+"_Latn" + if item in gflangs: + record = MessageToDict(gflangs[item]) + bases, auxiliary, marks = collect(record) + with_record = with_record + 1 + if bases: + with_exemplars = with_exemplars + 1 + + nom_test, nom_smcp_test = build_no_orphaned_marks(bases, auxiliary) + if nom_test: + new_profile.append(nom_test) + new_profile.append(nom_smcp_test) + + build_results(item, new_profile) + + + #profile.close + f.close + f2.close + + print("African ISO-639 tags:\t" + str(all_tags) + "\nAvailable GF Lang Record:\t" + str(with_record) + "\nGF Lang Contains Exemplar Characters:\t" + str(with_exemplars) + "\nCorresponding OT Lang Tag Exists:\t" + str(with_ot_tags) + "\nNeeds Glyphs Variant:\t" + str(needs_variant)) + +if __name__ == '__main__': + main() diff --git a/shaperglot/checker.py b/shaperglot/checker.py index a8b1eaa..8034bcb 100644 --- a/shaperglot/checker.py +++ b/shaperglot/checker.py @@ -1,3 +1,4 @@ +from ufo2ft.util import closeGlyphsOverGSUB from vharfbuzz import Vharfbuzz from shaperglot.reporter import Reporter @@ -16,18 +17,47 @@ def _get_cluster(buffers, index): return cluster -class Checker: +class Checker: # pylint: disable=too-few-public-methods def __init__(self, fontfile): self.vharfbuzz = Vharfbuzz(fontfile) self.ttfont = self.vharfbuzz.ttfont self.glyphorder = self.ttfont.getGlyphOrder() self.cmap = self.ttfont["cmap"].getBestCmap() + self.reversed_cmap = self.ttfont["cmap"].buildReversed() + self.full_reversed_cmap = None self.results = None self.lang = None + self.cache = {"can_shape": {}} + + def _build_full_reversed_cmap(self): + gsub = self.ttfont.get("GSUB") + self.full_reversed_cmap = {k: list(v)[0] for k,v in self.reversed_cmap.items()} + if not gsub: + return + if len(self.full_reversed_cmap) > 5_000: + # Some kind of CJK monstrosity, give up + return + for codepoint, glyph in self.cmap.items(): + glyphs = set([glyph]) + if gsub: + closeGlyphsOverGSUB(gsub, glyphs) + for new_glyph in glyphs: + self.full_reversed_cmap[new_glyph] = codepoint + + def codepoint_for(self, glyphname): + if glyphname in self.reversed_cmap: + return list(self.reversed_cmap[glyphname])[0] + if not self.full_reversed_cmap: + self._build_full_reversed_cmap() + return self.full_reversed_cmap.get(glyphname, 0) def check(self, lang): self.results = Reporter() self.lang = lang for check_object in self.lang.get("shaperglot_checks", []): + skip_reason = check_object.should_skip(self) + if skip_reason: + self.results.skip(check_name=check_object.name, message=skip_reason) + continue check_object.execute(self) return self.results diff --git a/shaperglot/checks/__init__.py b/shaperglot/checks/__init__.py index 0cb98da..55149ce 100644 --- a/shaperglot/checks/__init__.py +++ b/shaperglot/checks/__init__.py @@ -3,7 +3,8 @@ from .orthographies import OrthographiesCheck from .shaping_differs import ShapingDiffersCheck from .no_orphaned_marks import NoOrphanedMarksCheck +from .unencoded_variants import UnencodedVariantsCheck -checks = [OrthographiesCheck, ShapingDiffersCheck, NoOrphanedMarksCheck] +checks = [OrthographiesCheck, ShapingDiffersCheck, NoOrphanedMarksCheck, UnencodedVariantsCheck] checks_map = {cls.name: cls for cls in checks} schemas = {cls.name: cls.schema for cls in checks} diff --git a/shaperglot/checks/common.py b/shaperglot/checks/common.py index 74667d7..2564ef7 100644 --- a/shaperglot/checks/common.py +++ b/shaperglot/checks/common.py @@ -1,4 +1,4 @@ -from strictyaml import Str, Map, Optional, MapPattern, Bool +from strictyaml import Str, Map, Optional, MapPattern, Bool, Seq shaping_input_schema = Map( { @@ -8,6 +8,19 @@ } ) +conditions_schema = Map({Optional("features"): Seq(Str())}) + + +def check_schema(schema): + base_schema = { + "check": Str(), + Optional("rationale"): Str(), + Optional("conditions"): conditions_schema, + } + schema.update(base_schema) + return Map(schema) + + def and_join(lst): lst = list(lst) if len(lst) == 0: @@ -16,6 +29,7 @@ def and_join(lst): return ', '.join(lst[:-1]) + ' and ' + lst[-1] return lst[0] + class ShapeInput: def __init__(self, check_yaml): self.text = str(check_yaml["text"]) @@ -24,6 +38,7 @@ def __init__(self, check_yaml): self.features = check_yaml["features"].data else: self.features = {} + self.check_yaml = check_yaml def describe(self): result = f"shaping the text '{self.text}' " @@ -34,10 +49,12 @@ def describe(self): if self.features: result += "and " if self.features: - result += "turning " + and_join([ - f"the '{feat}' feature " + (state and "on" or "off") - for feat, state in self.features.items() - ]) + result += "turning " + and_join( + [ + f"the '{feat}' feature " + (state and "on" or "off") + for feat, state in self.features.items() + ] + ) return result.strip() def shape(self, checker): @@ -48,6 +65,7 @@ def shape(self, checker): parameters["features"] = self.features return checker.vharfbuzz.shape(self.text, parameters) + # pylint: disable=R0903 class ShaperglotCheck: def __init__(self, check_yaml): @@ -56,3 +74,23 @@ def __init__(self, check_yaml): self.inputs = [ShapeInput(x) for x in check_yaml["inputs"]] if "input" in check_yaml: self.input = ShapeInput(check_yaml["input"]) + + def should_skip(self, checker): + conditions = self.definition.get("conditions") + if conditions is None: + return False + if "features" in conditions: + font_features = set() + for table in ["GSUB", "GPOS"]: + if ( + checker.ttfont.get(table) + and checker.ttfont[table].table.FeatureList + ): + for feature_record in checker.ttfont[ + table + ].table.FeatureList.FeatureRecord: + font_features.add(feature_record.FeatureTag) + required = set(str(f) for f in conditions["features"]) + if required - font_features: + return f"Missing features: {', '.join(required-font_features)}" + return False diff --git a/shaperglot/checks/no_orphaned_marks.py b/shaperglot/checks/no_orphaned_marks.py index 34e6fd4..a0f1e62 100644 --- a/shaperglot/checks/no_orphaned_marks.py +++ b/shaperglot/checks/no_orphaned_marks.py @@ -1,21 +1,20 @@ -from strictyaml import Str, Map, Optional -from ufo2ft.util import classifyGlyphs +from functools import cache + from youseedee import ucd_data -from .common import shaping_input_schema, ShaperglotCheck +from .common import shaping_input_schema, ShaperglotCheck, check_schema +@cache def _simple_mark_check(codepoint): return ucd_data(codepoint).get("General_Category") == "Mn" class NoOrphanedMarksCheck(ShaperglotCheck): name = "no_orphaned_marks" - schema = Map( + schema = check_schema( { - "check": Str(), "input": shaping_input_schema, - Optional("rationale"): Str(), } ) @@ -27,13 +26,6 @@ def execute(self, checker): dotted_circle_glyph = checker.cmap.get(0x25CC) # GDEF may be wrong, don't trust it. - is_mark = {} - for yes_no, glyphs in classifyGlyphs( - _simple_mark_check, checker.cmap, checker.ttfont.get("GSUB") - ).items(): - for glyphname in glyphs: - is_mark[glyphname] = yes_no - passed = True previous = None # pylint: disable=C0103 @@ -44,20 +36,49 @@ def execute(self, checker): # Is this a mark glyph? if info.codepoint == 0: passed = False - checker.results.fail("Shaper produced a .notdef") + message = "Shaper produced a .notdef" + # Generally this message happens because we're missing + # base/mark glyphs, so we will heard about this already, + # *except* if no exemplars are defined, when it would be + # good to hear specifically what glyphs we tried to test here. + if not checker.lang.get("exemplarChars"): + message += " when shaping " + self.input.describe() + + checker.results.fail( + check_name="no-orphaned-marks", + result_code="notdef-produced", + message=message, + context={"text": self.input.check_yaml}, + ) break - if is_mark[glyphname]: + if _simple_mark_check(checker.codepoint_for(glyphname)): # Was the previous glyph dotted circle? if previous and previous == dotted_circle_glyph: passed = False - checker.results.fail("Shaper produced a dotted circle") + checker.results.fail( + check_name="no-orphaned-marks", + result_code="dotted-circle-produced", + message="Shaper produced a dotted circle when shaping " + + self.input.describe(), + context={"text": self.input.check_yaml}, + ) elif pos.x_offset == 0 and pos.y_offset == 0: # Suspicious passed = False checker.results.fail( - f"Shaper didn't attached {glyphname} to {previous}" + check_name="no-orphaned-marks", + result_code="orphaned-mark", + message=f"Shaper didn't attach {glyphname} to {previous}", + context={ + "text": self.input.check_yaml, + "mark": glyphname, + "base": previous, + }, ) previous = glyphname if passed: checker.results.okay( - "No unattached mark glyphs were produced " + self.input.describe() + check_name="no-orphaned-marks", + message="No unattached mark glyphs were produced " + + self.input.describe(), + context={"text": self.input.check_yaml}, ) diff --git a/shaperglot/checks/orthographies.py b/shaperglot/checks/orthographies.py index 8242307..72b5898 100644 --- a/shaperglot/checks/orthographies.py +++ b/shaperglot/checks/orthographies.py @@ -1,8 +1,23 @@ +import re + from strictyaml import Map from .common import ShaperglotCheck, and_join +def parse_bases(bases): + return [x[0] or x[1] for x in re.findall(r"\{([^}]+)\}|(\S+)", bases)] + + +def can_shape(text, checker): + if text not in checker.cache["can_shape"]: + buf = checker.vharfbuzz.shape(text) + checker.cache["can_shape"][text] = all( + gi.codepoint != 0 for gi in buf.glyph_infos + ) + return checker.cache["can_shape"][text] + + class OrthographiesCheck(ShaperglotCheck): name = "orthographies" schema = Map({}) @@ -11,11 +26,16 @@ class OrthographiesCheck(ShaperglotCheck): def __init__(self, lang): exemplar_chars = lang.get("exemplarChars", {}) marks = exemplar_chars.get("marks", "").replace("◌", "").split() or [] - bases = exemplar_chars.get("base", "").split() or [] + bases = parse_bases(exemplar_chars.get("base", "")) + aux = parse_bases(exemplar_chars.get("auxiliary", "")) + bases = bases + aux self.all_glyphs = marks + bases self.marks = set(marks) self.bases = set(bases) - self.marks + def should_skip(self, checker): + return False + def describe(self): return "that the following glyphs are in the font: " + and_join( f"'{g}'" for g in self.all_glyphs @@ -24,19 +44,39 @@ def describe(self): def execute(self, checker): if not self.all_glyphs: checker.results.warn( - f"No glyphs were defined for language {checker.lang['name']}" + check_name="orthographies", + result_code="no-exemplars", + message=f"No exemplar glyphs were defined for language {checker.lang['name']}", + ) + return + missing = sorted([x for x in self.bases if not can_shape(x, checker)]) + if missing: + checker.results.fail( + check_name="orthographies", + result_code="bases-missing", + message=f"Some base glyphs were missing: {', '.join(missing)}", + context={"glyphs": missing}, + ) + else: + checker.results.okay( + check_name="orthographies", + message="All base glyphs were present in the font", ) + + if not self.marks: return - missing = [x for x in self.bases if ord(x) not in checker.cmap] + + missing = sorted([x for x in self.marks if not can_shape(x, checker)]) if missing: - missing = ", ".join(missing) - checker.results.fail(f"Some base glyphs were missing: {missing}") + missing_str = ", ".join([chr(0x25CC) + x for x in missing]) + checker.results.fail( + check_name="orthographies", + result_code="marks-missing", + message=f"Some mark glyphs were missing: {missing_str}", + context={"glyphs": missing}, + ) else: - checker.results.okay("All base glyphs were present in the font") - if self.marks: - missing = [x for x in self.marks if ord(x) not in checker.cmap] - if missing: - missing = ", ".join(missing) - checker.results.fail(f"Some mark glyphs were missing: {missing}") - else: - checker.results.okay("All mark glyphs were present in the font") + checker.results.okay( + check_name="orthographies", + message="All mark glyphs were present in the font", + ) diff --git a/shaperglot/checks/shaping_differs.py b/shaperglot/checks/shaping_differs.py index 47edc33..4877a8f 100644 --- a/shaperglot/checks/shaping_differs.py +++ b/shaperglot/checks/shaping_differs.py @@ -1,19 +1,17 @@ -from strictyaml import FixedSeq, Str, Map, Int, Optional +from strictyaml import FixedSeq, Map, Int, Optional from num2words import num2words -from .common import shaping_input_schema, ShaperglotCheck +from .common import shaping_input_schema, ShaperglotCheck, check_schema cluster_schema = Map({Optional("cluster"): Int(), "glyph": Int()}) class ShapingDiffersCheck(ShaperglotCheck): name = "shaping_differs" - schema = Map( + schema = check_schema( { - "check": Str(), "inputs": FixedSeq([shaping_input_schema, shaping_input_schema]), Optional("differs"): FixedSeq([cluster_schema, cluster_schema]), - Optional("rationale"): Str(), } ) @@ -45,12 +43,21 @@ def execute(self, checker): serialized_buf1 = checker.vharfbuzz.serialize_buf(buffers[0]) serialized_buf2 = checker.vharfbuzz.serialize_buf(buffers[1]) if serialized_buf1 != serialized_buf2: - checker.results.okay(self.definition["rationale"]) + checker.results.okay( + check_name="shaping-differs", + message=f"{self.definition['rationale']}", + ) else: checker.results.fail( - self.definition["rationale"] + check_name="shaping-differs", + result_code="shaping-did-not-differ", + message=f"{self.definition['rationale']}" + "; both buffers returned " - + serialized_buf1 + + serialized_buf1, + context={ + "input1": self.inputs[0].check_yaml, + "input2": self.inputs[0].check_yaml, + }, ) return # We are looking for a specific difference @@ -62,15 +69,31 @@ def execute(self, checker): glyph_ix = int(differs["glyph"]) if len(buffer) - 1 < glyph_ix: checker.results.fail( - f"Test asked for glyph {glyph_ix} but shaper only returned {len(buffer)} glyphs" + check_name="shaping-differs", + result_code="too-few-glyphs", + message=f"Test asked for glyph {glyph_ix} but shaper only returned {len(buffer)} glyphs", + context={ + "input1": self.inputs[0].check_yaml, + "input2": self.inputs[0].check_yaml, + }, ) return glyphs.append((buffer[glyph_ix][0].codepoint, buffer[glyph_ix][1])) if glyphs[0] != glyphs[1]: - checker.results.okay(self.definition["rationale"]) + checker.results.okay( + check_name="shaping-differs", + result_code="shaping-did-not-differ", + message=f"{self.definition['rationale']}", + ) else: checker.results.fail( - self.definition["rationale"] + check_name="shaping-differs", + result_code="shaping-did-not-differ", + message=f"{self.definition['rationale']}" + "; both buffers returned " - + checker.vharfbuzz.serialize_buf(buffers[0]) + + serialized_buf1, + context={ + "input1": self.inputs[0].check_yaml, + "input2": self.inputs[0].check_yaml, + }, ) diff --git a/shaperglot/checks/unencoded_variants.py b/shaperglot/checks/unencoded_variants.py new file mode 100644 index 0000000..137fdf3 --- /dev/null +++ b/shaperglot/checks/unencoded_variants.py @@ -0,0 +1,54 @@ +from .common import shaping_input_schema, ShaperglotCheck, check_schema + + +class UnencodedVariantsCheck(ShaperglotCheck): + name = "unencoded_variants" + schema = check_schema( + { + "input": shaping_input_schema, + } + ) + + def describe(self): + return f"that, when {self.input.describe()}, an unencoded variant glyph is substituted used the `locl` feature" + + def execute(self, checker): + if len(self.input.text) > 1: + raise ValueError( + f"Please only pass one codepoint at a time to the unencoded variants check (not '{self.input.text}')" + ) + self.input.features["locl"] = False + buffer = self.input.shape(checker) + glyphname = checker.glyphorder[buffer.glyph_infos[0].codepoint] + # Are there variant versions of this glyph? + variants = [ + glyph for glyph in checker.glyphorder if glyph.startswith(glyphname + ".") + ] + if not variants: + checker.results.warn( + check_name="unencoded-variants", + result_code="no-variant", + message="No variant glyphs were found for " + glyphname, + context={"text": self.input.check_yaml, "glyph": glyphname}, + ) + return + # Try it again with locl on, set the language to the one we're + # looking for see if something happens. + if not self.input.language: + self.input.language = checker.lang["language"] + self.input.features["locl"] = True + buffer2 = self.input.shape(checker) + glyphname2 = checker.glyphorder[buffer2.glyph_infos[0].codepoint] + if glyphname2 == glyphname: + checker.results.fail( + check_name="unencoded-variants", + result_code="unchanged-after-locl", + message=f"The locl feature did not affect {glyphname}", + context={"text": self.input.check_yaml, "glyph": glyphname}, + ) + else: + checker.results.okay( + check_name="unencoded-variants", + message=f"The locl feature changed {glyphname} to {glyphname2}", + context={"text": self.input.check_yaml, "glyph": glyphname}, + ) diff --git a/shaperglot/cli.py b/shaperglot/cli.py index a19bbbb..69f1e0b 100644 --- a/shaperglot/cli.py +++ b/shaperglot/cli.py @@ -2,6 +2,7 @@ import sys from textwrap import fill import os +import re from shaperglot.checker import Checker from shaperglot.languages import Languages @@ -46,19 +47,105 @@ def check(options): results = checker.check(langs[lang]) - if results.is_success: + if results.is_unknown: + print(f"Cannot determine whether font supports language '{lang}'") + elif results.is_success: print(f"Font supports language '{lang}'") else: print(f"Font does not fully support language '{lang}'") if options.verbose and options.verbose > 1: - for status, message in results: - print(f" * {status.value}: {message}") + for message in results: + print(f" * {message}") elif options.verbose or not results.is_success: for message in results.fails: print(f" * {message}") +def report(options): + checker = Checker(options.font) + langs = Languages() + messages = [] + supported = [] + unsupported = [] + + for lang in sorted(langs.keys()): + if options.filter and not re.search(options.filter, lang): + continue + results = checker.check(langs[lang]) + + if results.is_unknown: + continue + + if results.is_success: + supported.append(langs[lang]['name']) + print(f"Font supports language '{lang}' ({langs[lang]['name']})") + else: + unsupported.append(langs[lang]['name']) + print( + f"Font does not fully support language '{lang}' ({langs[lang]['name']})" + ) + messages.extend(results) + if options.verbose and options.verbose > 1: + for status, message in results: + print(f" * {status.value}: {message}") + + # Collate a useful fixing guide + print("\n== Summary ==\n") + print(f"* {len(supported)+len(unsupported)} languages checked") + if supported: + print(f"* {len(supported)} languages supported") + if not options.verbose: + return + if unsupported: + print( + fill( + "* Unsupported languages: " + ", ".join(unsupported), + subsequent_indent=" " * 25, + width=os.get_terminal_size()[0] - 2, + ) + ) + print("\nTo add support:") + missing_bases = set() + missing_marks = set() + missing_anchors = set() + for msg in messages: + if msg.result_code == "bases-missing": + missing_bases |= set(msg.context["glyphs"]) + if msg.result_code == "marks-missing": + missing_marks |= set(msg.context["glyphs"]) + if msg.result_code == "orphaned-mark": + missing_anchors.add((msg.context["base"], msg.context["mark"])) + if missing_marks: + print( + fill( + " * Add mark glyphs: " + + ", ".join(["\u25cc" + x for x in sorted(missing_marks)]), + subsequent_indent=" ", + width=os.get_terminal_size()[0] - 2, + ) + ) + if missing_bases: + print( + fill( + " * Support characters: " + ", ".join(sorted(missing_bases)), + subsequent_indent=" ", + width=os.get_terminal_size()[0] - 2, + ) + ) + if missing_anchors: + print( + fill( + " * Add anchor attachments: " + + ", ".join( + [base + '/' + mark for base, mark in sorted(missing_anchors)] + ), + subsequent_indent=" ", + width=os.get_terminal_size()[0] - 2, + ) + ) + + def main(args=None): if args is None: args = sys.argv[1:] @@ -89,6 +176,11 @@ def main(args=None): 'report', help='report which languages are supported' ) parser_report.add_argument('font', metavar='FONT', help='the font file') + parser_report.add_argument('--verbose', '-v', action='count') + parser_report.add_argument( + '--filter', type=str, help="Regular expression to filter languages" + ) + parser_report.set_defaults(func=report) options = parser.parse_args(args) if not hasattr(options, "func"): diff --git a/shaperglot/languages.py b/shaperglot/languages.py index 32c0e44..41ca88f 100644 --- a/shaperglot/languages.py +++ b/shaperglot/languages.py @@ -18,20 +18,23 @@ def load_shaperglot_definition(language, validate=False): definition_file = definitions_directory / (language + ".yaml") if not definition_file.is_file(): return [] - with open(definition_file) as fh: + with open(definition_file, encoding="utf-8") as fh: data = load(fh.read()) check_objects = [] for ix, check in enumerate(data): if validate: if check["check"] not in schemas: raise ValueError( - f"Language definition file for {language} invalid; unknown check type {check['check']} in check {ix} - choose from { ', '.join(schemas.keys()) }" + f"Language definition file for {language} invalid; " + f"unknown check type {check['check']} in check {ix} " + f"- choose from { ', '.join(schemas.keys()) }" ) try: check.revalidate(schemas[check["check"]]) except YAMLValidationError as e: raise ValueError( - f"Language definition file for {language} invalid; parser error in check {ix}: {e}" + f"Language definition file for {language} invalid; " + f"parser error in check {ix}: {e}" ) from e # This turns a { "check": "foobar" } into a FoobarCheck({"check": "foobar"}) check_objects.append(checks_map[check["check"]](check)) @@ -60,7 +63,7 @@ def __getitem__(self, item): if item in self.loaded: return self.loaded[item] if item not in gflangs: - return + return None orig = MessageToDict(gflangs[item]) orig["full_name"] = ( orig["name"] + " in the " + gfscripts[orig["script"]].name + " script" diff --git a/shaperglot/languages/agq_Latn.yaml b/shaperglot/languages/agq_Latn.yaml new file mode 100644 index 0000000..1bf579c --- /dev/null +++ b/shaperglot/languages/agq_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ɛ̀ɛ̂ɛ̌ɛ̄ɨ̀ɨ̂ɨ̌ɨ̄ɔ̀ɔ̂ɔ̌ɔ̄ʉ̀ʉ̂ʉ̌ʉ̄ +- check: no_orphaned_marks + input: + text: ɛ̀ɛ̂ɛ̌ɛ̄ɨ̀ɨ̂ɨ̌ɨ̄ɔ̀ɔ̂ɔ̌ɔ̄ʉ̀ʉ̂ʉ̌ʉ̄ + features: + smcp: true diff --git a/shaperglot/languages/bas_Latn.yaml b/shaperglot/languages/bas_Latn.yaml new file mode 100644 index 0000000..4a2f98e --- /dev/null +++ b/shaperglot/languages/bas_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: aasaea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aaeasa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇saaaea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇saeaaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eaaasa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇easaaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aasaea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aaeasa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇saaaea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇saeaaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eaaasa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇easaaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aeseea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aeeesa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇seaeea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇seeeaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eeaesa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eeseaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aeseea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aeeesa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇seaeea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇seeeaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eeaesa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eeseaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɛsɛea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɛeɛsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɛaɛea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɛeɛaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɛaɛsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɛsɛaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɛsɛea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɛeɛsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɛaɛea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɛeɛaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɛaɛsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɛsɛaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aisiea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aieisa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇siaiea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sieiaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eiaisa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eisiaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aisiea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aieisa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇siaiea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sieiaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eiaisa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eisiaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aosoea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aoeosa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇soaoea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇soeoaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eoaosa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eosoaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aosoea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aoeosa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇soaoea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇soeoaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eoaosa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eosoaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɔsɔea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɔeɔsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɔaɔea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɔeɔaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɔaɔsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɔsɔaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɔsɔea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɔeɔsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɔaɔea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɔeɔaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɔaɔsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɔsɔaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇ausuea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aueusa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇suauea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sueuaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇euausa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eusuaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇ausuea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aueusa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇suauea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sueuaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇euausa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eusua +- check: no_orphaned_marks + input: + text: aasaea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aaeasa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇saaaea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇saeaaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eaaasa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇easaaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aasaea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aaeasa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇saaaea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇saeaaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eaaasa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇easaaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aeseea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aeeesa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇seaeea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇seeeaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eeaesa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eeseaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aeseea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aeeesa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇seaeea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇seeeaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eeaesa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eeseaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɛsɛea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɛeɛsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɛaɛea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɛeɛaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɛaɛsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɛsɛaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɛsɛea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɛeɛsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɛaɛea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɛeɛaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɛaɛsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɛsɛaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aisiea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aieisa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇siaiea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sieiaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eiaisa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eisiaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aisiea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aieisa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇siaiea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sieiaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eiaisa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eisiaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aosoea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aoeosa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇soaoea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇soeoaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eoaosa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eosoaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aosoea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aoeosa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇soaoea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇soeoaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eoaosa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eosoaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɔsɔea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɔeɔsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɔaɔea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɔeɔaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɔaɔsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɔsɔaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɔsɔea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aɔeɔsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɔaɔea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sɔeɔaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɔaɔsa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eɔsɔaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇ausuea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aueusa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇suauea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sueuaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇euausa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eusuaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇ausuea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇aueusa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇suauea᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇sueuaa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇euausa᷆a᷇a᷆a᷇e᷆e᷇e᷆e᷇ɛ́ɛ̀ɛ̂ɛ̌ɛ̄ɛ᷆ɛ᷇ɛ᷆ɛ᷇i᷆i᷇i᷆i᷇o᷆o᷇o᷆o᷇ɔ́ɔ̀ɔ̂ɔ̌ɔ̄ɔ᷆ɔ᷇ɔ᷆ɔ᷇u᷆u᷇u᷆u᷇a᷆a᷇e᷆e᷇ɛ᷆ɛ᷇i᷆i᷇o᷆o᷇ɔ᷆ɔ᷇u᷆u᷇eusua + features: + smcp: true diff --git a/shaperglot/languages/dua_Latn.yaml b/shaperglot/languages/dua_Latn.yaml new file mode 100644 index 0000000..6829988 --- /dev/null +++ b/shaperglot/languages/dua_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ɛ́ɔ́ +- check: no_orphaned_marks + input: + text: ɛ́ɔ́ + features: + smcp: true diff --git a/shaperglot/languages/ee_Latn.yaml b/shaperglot/languages/ee_Latn.yaml new file mode 100644 index 0000000..60362e6 --- /dev/null +++ b/shaperglot/languages/ee_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ɛ́ɛ̀ɛ̃ɔ́ɔ̀ɔ̃ +- check: no_orphaned_marks + input: + text: ɛ́ɛ̀ɛ̃ɔ́ɔ̀ɔ̃ + features: + smcp: true diff --git a/shaperglot/languages/ewo_Latn.yaml b/shaperglot/languages/ewo_Latn.yaml new file mode 100644 index 0000000..919aaa9 --- /dev/null +++ b/shaperglot/languages/ewo_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ə́ə̀ə̂ə̌ɛ́ɛ̀ɛ̂ɛ̌ɔ́ɔ̀ɔ̂ɔ̌ +- check: no_orphaned_marks + input: + text: ə́ə̀ə̂ə̌ɛ́ɛ̀ɛ̂ɛ̌ɔ́ɔ̀ɔ̂ɔ̌ + features: + smcp: true diff --git a/shaperglot/languages/ha_Latn.yaml b/shaperglot/languages/ha_Latn.yaml new file mode 100644 index 0000000..b9dbaa4 --- /dev/null +++ b/shaperglot/languages/ha_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: r̃ +- check: no_orphaned_marks + input: + text: r̃ + features: + smcp: true diff --git a/shaperglot/languages/ig_Latn.yaml b/shaperglot/languages/ig_Latn.yaml new file mode 100644 index 0000000..34f0ddc --- /dev/null +++ b/shaperglot/languages/ig_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ị́ị̀m̀ọ́ọ̀ụ́ụ̀ +- check: no_orphaned_marks + input: + text: ị́ị̀m̀ọ́ọ̀ụ́ụ̀ + features: + smcp: true diff --git a/shaperglot/languages/jgo_Latn.yaml b/shaperglot/languages/jgo_Latn.yaml new file mode 100644 index 0000000..ab5315b --- /dev/null +++ b/shaperglot/languages/jgo_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ɛ́ɛ̀ɛ̂ɛ̌ɛ̄m̀m̄n̄ŋ́ŋ̀ŋ̄ɔ́ɔ̂ɔ̌ʉ́ʉ̂ʉ̌ʉ̈ +- check: no_orphaned_marks + input: + text: ɛ́ɛ̀ɛ̂ɛ̌ɛ̄m̀m̄n̄ŋ́ŋ̀ŋ̄ɔ́ɔ̂ɔ̌ʉ́ʉ̂ʉ̌ʉ̈ + features: + smcp: true diff --git a/shaperglot/languages/kkj_Latn.yaml b/shaperglot/languages/kkj_Latn.yaml new file mode 100644 index 0000000..8e7a205 --- /dev/null +++ b/shaperglot/languages/kkj_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: a̧ɛ́ɛ̀ɛ̂ɛ̧i̧ɔ́ɔ̀ɔ̂ɔ̧u̧ +- check: no_orphaned_marks + input: + text: a̧ɛ́ɛ̀ɛ̂ɛ̧i̧ɔ́ɔ̀ɔ̂ɔ̧u̧ + features: + smcp: true diff --git a/shaperglot/languages/ksf_Latn.yaml b/shaperglot/languages/ksf_Latn.yaml new file mode 100644 index 0000000..2ff3d9d --- /dev/null +++ b/shaperglot/languages/ksf_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ǝ́ɛ́ɔ́ +- check: no_orphaned_marks + input: + text: ǝ́ɛ́ɔ́ + features: + smcp: true diff --git a/shaperglot/languages/ln_Latn.yaml b/shaperglot/languages/ln_Latn.yaml new file mode 100644 index 0000000..6436482 --- /dev/null +++ b/shaperglot/languages/ln_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ɛ́ɛ̂ɛ̌ɔ́ɔ̂ɔ̌ +- check: no_orphaned_marks + input: + text: ɛ́ɛ̂ɛ̌ɔ́ɔ̂ɔ̌ + features: + smcp: true diff --git a/shaperglot/languages/lu_Latn.yaml b/shaperglot/languages/lu_Latn.yaml new file mode 100644 index 0000000..3a315a5 --- /dev/null +++ b/shaperglot/languages/lu_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ɛ́ɛ̀ɔ́ɔ̀ +- check: no_orphaned_marks + input: + text: ɛ́ɛ̀ɔ́ɔ̀ + features: + smcp: true diff --git a/shaperglot/languages/mas_Latn.yaml b/shaperglot/languages/mas_Latn.yaml new file mode 100644 index 0000000..a96f496 --- /dev/null +++ b/shaperglot/languages/mas_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ʉ́ +- check: no_orphaned_marks + input: + text: ʉ́ + features: + smcp: true diff --git a/shaperglot/languages/mgo_Latn.yaml b/shaperglot/languages/mgo_Latn.yaml new file mode 100644 index 0000000..2f2f330 --- /dev/null +++ b/shaperglot/languages/mgo_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ə̀ɔ̀ +- check: no_orphaned_marks + input: + text: ə̀ɔ̀ + features: + smcp: true diff --git a/shaperglot/languages/nmg_Latn.yaml b/shaperglot/languages/nmg_Latn.yaml new file mode 100644 index 0000000..f7ba125 --- /dev/null +++ b/shaperglot/languages/nmg_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ǝ́ǝ̂ǝ̌ǝ̄ɛ́ɛ̂ɛ̌ɛ̄ɔ́ɔ̂ɔ̌ɔ̄ +- check: no_orphaned_marks + input: + text: ǝ́ǝ̂ǝ̌ǝ̄ɛ́ɛ̂ɛ̌ɛ̄ɔ́ɔ̂ɔ̌ɔ̄ + features: + smcp: true diff --git a/shaperglot/languages/nnh_Latn.yaml b/shaperglot/languages/nnh_Latn.yaml new file mode 100644 index 0000000..98bc52c --- /dev/null +++ b/shaperglot/languages/nnh_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ɛ́ɛ̀ɛ̂ɛ̌ɔ́ɔ̀ɔ̂ɔ̌ʉ́ʉ̀ʉ̂ʉ̌ +- check: no_orphaned_marks + input: + text: ɛ́ɛ̀ɛ̂ɛ̌ɔ́ɔ̀ɔ̂ɔ̌ʉ́ʉ̀ʉ̂ʉ̌ + features: + smcp: true diff --git a/shaperglot/languages/nus_Latn.yaml b/shaperglot/languages/nus_Latn.yaml new file mode 100644 index 0000000..8e8da39 --- /dev/null +++ b/shaperglot/languages/nus_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: aɛsa̱e̱ɛ̈ɛ̱ɛ̱̈ɛ̱̈i̱o̱ɔ̈ɔ̱sɛaa̱e̱ɛ̈ɛ̱ɛ̱̈ɛ̱̈i̱o̱ɔ̈ɔ̱aɛsa̱e̱ɛ̈ɛ̱ɛ̱̈ɛ̱̈i̱o̱ɔ̈ɔ̱sɛa +- check: no_orphaned_marks + input: + text: aɛsa̱e̱ɛ̈ɛ̱ɛ̱̈ɛ̱̈i̱o̱ɔ̈ɔ̱sɛaa̱e̱ɛ̈ɛ̱ɛ̱̈ɛ̱̈i̱o̱ɔ̈ɔ̱aɛsa̱e̱ɛ̈ɛ̱ɛ̱̈ɛ̱̈i̱o̱ɔ̈ɔ̱sɛa + features: + smcp: true diff --git a/shaperglot/languages/st_Latn.yaml b/shaperglot/languages/st_Latn.yaml new file mode 100644 index 0000000..6000157 --- /dev/null +++ b/shaperglot/languages/st_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ÈĒŌÒèēōò +- check: no_orphaned_marks + input: + text: ÈĒŌÒèēōò + features: + smcp: true diff --git a/shaperglot/languages/vai_Latn.yaml b/shaperglot/languages/vai_Latn.yaml new file mode 100644 index 0000000..096368a --- /dev/null +++ b/shaperglot/languages/vai_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ɛ́ɛ̃ɔ́ɔ̃ +- check: no_orphaned_marks + input: + text: ɛ́ɛ̃ɔ́ɔ̃ + features: + smcp: true diff --git a/shaperglot/languages/yav_Latn.yaml b/shaperglot/languages/yav_Latn.yaml new file mode 100644 index 0000000..3a315a5 --- /dev/null +++ b/shaperglot/languages/yav_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ɛ́ɛ̀ɔ́ɔ̀ +- check: no_orphaned_marks + input: + text: ɛ́ɛ̀ɔ́ɔ̀ + features: + smcp: true diff --git a/shaperglot/languages/yo_Latn.yaml b/shaperglot/languages/yo_Latn.yaml new file mode 100644 index 0000000..86d7f48 --- /dev/null +++ b/shaperglot/languages/yo_Latn.yaml @@ -0,0 +1,9 @@ +#auto-generated using sg-bulk-builder.py +- check: no_orphaned_marks + input: + text: ẹ́ẹ̀m̀ọ́ọ̀ +- check: no_orphaned_marks + input: + text: ẹ́ẹ̀m̀ọ́ọ̀ + features: + smcp: true diff --git a/shaperglot/reporter.py b/shaperglot/reporter.py index 10c6624..233c460 100644 --- a/shaperglot/reporter.py +++ b/shaperglot/reporter.py @@ -1,7 +1,8 @@ from enum import Enum from collections.abc import Sequence -from termcolor import colored +from dataclasses import dataclass, field +from termcolor import colored class Result(Enum): PASS = colored("PASS", "green") @@ -10,6 +11,18 @@ class Result(Enum): SKIP = colored("SKIP", "blue") +@dataclass(repr=False) +class Message(): + result: Result + check_name: str + message: str + result_code: str = "ok" + context: dict = field(default_factory=dict) + + def __repr__(self): + return self.result.value + ": " + self.message + + class Reporter(Sequence): def __init__(self): self.results = [] @@ -20,26 +33,34 @@ def __getitem__(self, index): def __len__(self): return len(self.results) - def okay(self, message): - self.results.append((Result.PASS, message)) + def okay(self, **kwargs): + self.results.append(Message(result=Result.PASS, **kwargs)) - def warn(self, message): - self.results.append((Result.WARN, message)) + def warn(self, **kwargs): + self.results.append(Message(result=Result.WARN, **kwargs)) - def fail(self, message): - self.results.append((Result.FAIL, message)) + def fail(self, **kwargs): + self.results.append(Message(result=Result.FAIL, **kwargs)) - def skip(self, message): - self.results.append((Result.SKIP, message)) + def skip(self, **kwargs): + self.results.append(Message(result=Result.SKIP, **kwargs)) + + @property + def is_unknown(self): + return not self.passes and not self.fails @property def is_success(self): - return not self.fails + return len(self.passes) > 0 and not self.fails + + @property + def passes(self): + return [x for x in self.results if x.result == Result.PASS] @property def fails(self): - return [x[1] for x in self.results if x[0] == Result.FAIL] + return [x for x in self.results if x.result == Result.FAIL] @property def warns(self): - return [x[1] for x in self.results if x[0] == Result.WARN] + return [x for x in self.results if x.result == Result.WARN]