Module:IgenCoa

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules

Deutsch: Im Normalfall muss sich der Benutzer nicht mit diesem Modul auseinandersetzen;

WWWes arbeitet im Hintergrund und erleichtert seine Arbeit, indem es Parameter sinnvoll ergänzt.
WWWNur in Einzelfällen wird es notwendig, diese vor dem Zurückschreiben zu modifizieren.

WWWEs muss jedoch der komplette String eingegeben werden, falls ohne das Modul gearbeitet wird!
English: Normally the user has nothing to do with this module, it works in the background,

WWWwhere it generates a useful parameter_string, which can be modified when necessary.

WWWBut the complete string as here described has to be composed when working without that module!

en-1 The description below was composed by a non-native English speaker.
You are cordially invited to improve the literal quality of any textual expression.

This module enables simplification when Template:COAInformation is used.

It is intended to be invoked from {{COAInformation}} with {{#invoke:IgenCoa|main|parameter_string}} to generate the parameters for | image =0 and to pass the returned code to the Template:Image generation. See the flow chart for more information.[clarification needed]

For test purposes it can be invoked from other templates, and return to another template. It is also possible to be invoked from files with Information-description, via the adapter template Igenc.

The module's argument is a single string containing all the parameters. Therefore neither the pipe character nor the equal sign can be used within this string.

These characters, when needed, have to be replaced: pipes by slashes, equal signs by tildes.

Usage

{{IgenCoa |1= }}

Parameters in the module's argument

Template parameters

ParameterDescriptionDefaultStatus
1The only required parameter specifies

   ■ either a complete {{Igen|.....}} definition, with all the tags, in curly brackets with pipes
   ■ or a tool name (e.g. I, Im, Ic; A, AH, IA)

   ■ or a short code for a user entry (e.g. TK for User:TomKr), case-insensitive
emptyrequired
2possible W3C error count[clarification needed]0 (valid)optional
3topic for the file, e.g. c, ce, eh (or something else)0coptional
4shortcode for a national graphic lab, e.g. gd, ge, gf (or something else)emptyoptional
5validation style, e.g. fl or no (or something else)emptyoptional
gc ~can specify or suppress a subcategory within the graphic lab, e.g. ":TomKr" (with :)[clarification needed]emptyoptional
sd ~can specify or suppress a Graphic Lab subcategory differentiation[clarification needed]emptyoptional
U ~can specify or suppress a user for the text (with link) — oremptyoptional
u ~can specify or suppress a user for the text (without link) (see description)emptyoptional
su ~
sub: ~
can specify or suppress a subcategory within
"Valid SVG created with ..." or "Invalid SVG created with ..."
emptyoptional
ca ~
cat2 ~
can specify or suppress an additional category,
either with [[Category:Xxxx]] or just the name Xxxx
emptyoptional
more parametersneed to be specified in the format name ~ value (instead of name = value)

All Image generation-specified parameters can be passed, using the name~value notation:
replacements are needed: for pipes slashes, for equal signs tildes,
00 for slashes backslashes (or broken pipes), for spaces underscores (or ).

When a parameter value is itself a template transclusion, within its curly brackets all characters, including equal signs, pipes and slashes, are allowed.
emptyoptional

Additional information

The template is intended to be used in the following namespaces: the File namespace

The template is intended to be used by the following user groups: all users

See also

Module usage

{{ #invoke:IgenCoa | main | parameter_string }}


Normally the user has nothing to do with this module, it works in the background.[clarification needed]

The simpleSVGcheck.js script will generate a useful parameter_string for {{COAInformation}}, but it can be modified when necessary.

The format is |image=parameter_string; it can be either a complete {{Igen|....}} clause, or slash-separated parameters.

For example, |image={{Image generation|Im|6|+|gf|s=eh}} stands for :

Equivalent are |image = Im/6/eh/gf and |image = Fe/6/tool~Im, which shows the two main cases:

parameter 1 is the code for either a tool (like Inkscape), or the table key for the table of predefined user options.


Every single parameter can be modified, all parameters can be added, and each value transfer from the table can be excluded with the value -.

  • When e.g. the tool "Adobe" is predefined, it can be substituted with e.g. /tool~I to Inkscape.
  • When e.g. the topic "c" is predefined, it can be substituted with e.g. /s~ce to Coa-element.
  • When e.g. no graphic lab is predefined, it can be added with e.g. /g~es to CoA Lab-es.
  • When e.g. a graphic lab is predefined, it can be suppressed with the minus value e.g. /g~-.
Examples:
To add the tag % for embedded text, add /%
To add the tag ~ for PGF data, add /~;
to specify the user causing that[clarification needed], add /~~username (the first ~ is the tag, the second ~ is for the =)

Any other tag or parameter for {{Image generation}} can be specified this mode, positionals just preceded by a slash, named parameters with slash + name + tilde + value.

Spaces don't matter; /g~it is equal to / g ~ it.

Replacements:
For needed spaces pass the underscore _ (or the character , U+2194 double arrow).
For needed slash use the backslash \ (or the broken bar ¦)
For needed backslash use the inverted exclamation ¡
User name:

For {{Igen}} the uppercase "U" and the lowercase "u" are mutually exclusive, U has precedence when both are specified.
By this module a "u" in the usertable is overwritten by a "U" in the usertable (therefore it has no sense to predefine both);
an input "u~" overwrites all values from the usertable, and an input "U~" overwrites (or suppresses) everything.
Note: A "u~" is just text, it is not necessarily a valid user name. It can be wikicode, as e.g. [[User:name|display]]


Modifying the table:

This is mere technical information for people wanting to change entries, or to add new ones.

  • Entries for new users should be inserted in alphabetical order;
to distinguish, "c" is often used for charges (elements). and "e" for ecclesiasticals.[clarification needed]
  • up to 11 parameters can be defined for each entry, with nil for unused positions
when less than 11 are needed, further nil filling is not necessary after the last value.
  • more user entries can be specified, there is no technical limit.
But some codes are reserved pseudo keys, e.g. for tools like "I", or for labs like "fi" for "fr" individuell.[clarification needed]
g_lab coa element eccles. indiv. catonly
g_d d dc de di dx
g_e e ec ee ei ex
g_f f fc fe fi fx

These national wikipedias have projects which are linked standardwise, while the CoA Lab (parm 4) is linked "individuell":[clarification needed]

Wp Coa Lab Project
de di dw = Wappenwerkstatt
es ei ge = THV
fr fi gf = Projet Blasons
pl [ Pi ] gP = WPGW vector image
  • Simplification: A graphic lab modification is corrrectly written e.g image = Ph///dw
    but it will be understood when written image = Ph//dw or image = Ph/dw

The catonly option avoids the invocation of the Graphic Lab but categorizes to it, without the icon box.

Most predefinitions are for SVG files; raster images are drawn with often unknown tools.

All usernames and their keys must be also defined in the cleanup script.

For raster graphics, user keys of 2 characters become internally appended with an "r"; when userkey e.g. Ab is for SVG files, internal userkey Abr is for raster images. The cleanup script needs only one userkey for a user, for both SVG and non-SVG; it can detect whether it is a raster file, and an element ('charge'), but only the user can see if it's an ecclesiastical CoA.[clarification needed]

It is very irritating that the topics used by Igen differ completely from the keys used in this table.

While for the topics the "c" was expanded to ce for "coa element", and eh for "eccelsiastical heraldry",
the table has to allow that one user may draw as well coa and elements and eccelsiasticals.
The user key "Uu" may get expanded with "c" for charges, or "e" for ecclesisatical, or "r" for raster images.
usage coa element eccles. raster
Igen topic c ce eh
table key Uu Uuc Uue Uur

With modification, the Igen topic is the third parameter, e.g. |image = Uu//eh

Search mode: The search key may consist of two or three characters.

  • three character key: first is searched whether that entry exists; when not and the third key character is c or e or r, another search is performed with this key reduced to two characters.
  • two character key: first is searched whether that entry exists; when not and it is a raster image or an element, the key is expanded with r or c and another search is performed with this key.

A user may have up to four keys: the 2-character key and its expansions with c or e or r.

Treatment for coats of arms, elements and ecclesiasticals

Besides the "normal" CoAs are there also elements used for drawing vector image CoA, and the group of CoAs used by religious leaders of the Roman Catholic Church.

Another differentiation exists for bitmap (raster image) CoAs.

These groups exist

  • SVG CoA: the standard processing.
  • SVG CoA elements: two possibilities
  • either they have an own userkey, the standard key with "c".
  • when the key for |image is this Uuc key, it is used.
  • when the key for |image is just Uu, the Uuc key is searched and used, when found.
  • when the key for |image is just Uu and no Uuc key exists, the Uu key is used;
It should be modified with topic ce, and probaly other parameters (tool);
Otherwise the element is treated as a standard SVG CoA.
  • SVG ecclesiastical CoA
  • cannot be detected automatically; the |image key should be Uue or Uu modified with eh.
  • SVG ecclesiastical elements
  • BMP CoA
  • either they have an own userkey, the standard key with "r".
  • when the key for |image is this Uur key, it is used.
  • when the key for |image is just Uu, the Uur key is searched and used, when found.
  • when the key for |image is just Uu and no Uur key exists, it should be modified.
BMP elements are rare
  • BMP ecclesiastical CoA
  • does not get yet a special treatment, all raster CoAs are the same.

With modifictions, all different groups can be processed with one userkey. But the automatic treatment is only possible when each group has an own key predefined, e.g. Uuc, Uue, Uur.[clarification needed]

Table of the predefinitions

{{#invoke:IgenCoa|distab}} (sorted by key: first all the user keys, then the pseudo keys)[clarification needed]

Table display
#keytoolertoplabgcsdUusubcat
1a6Icgf:Anno16A6Anno16
2adIcgf:Adalric67ADAdalric67
3agIcgi:ANGELUSAGANGELUS
4ahIcnl:AtHoekAHA. ter Hoek
5akIscgH:ARKAKARK
6alIcHi:AlimanALAliman5040
7anIcge:AnenjaANAnenjaContribuciones de Anenja
8aoIIcgi:AshoppioAO
9apIcgf:ApnAPApn
10arIcgf:ArocheARAroche
11asIcASArchmedus
12auIcgf:AupsAUAups
13avIcgp:Aviz2000AVAviz2000
14axIcgf:Axel41AXAxel41
15b1IcB1B1mbo
16b2Icgf:BarsupilamiB2Barsupilami1512
17b4Acgi:BaselunaB4Baseluna014
18baIcgP:BastianowBABastianow
19bbrUncgp:Brian BoruBBBrian Boru
20bcIcgf:ByacCBCByacC
21beIcgf:Bear17BEBear17
22bfIcgf:BrookfordBFBrookford
23bgIcgc:BalmungBGBalmung0731
24biIcgf:BibarBIBibar
25blIcgf:BluebearBLBluebear2
26bnF8cgH:BerninaBNBernina
27boDcBoBrCaLeTo
28brIcbr:BriegBRBrieg
29bvIcgf:Bvs-acaBVbvs-aca
30byIcgf:BizcayenBYBizcayen
31bzIcgf:BenzebuBZBenzebuth198
32c1AcC1COAmaker17
33c2DcsuC2Care
34cbIcgf:CelbusroCBCelbusro
35ccrUnehgp:CatChessCCCatChess
36chIcgf:ChatsamChatsamBlason chatsam
37chxIcgf:ChatsamChatsam
38clIcCLCarlos yo
39cmDrawShieldcgl:Charles MatthewsCharles Matthews
40cnIcgf:CaranornCNCaranorn
41cpIehph:CPhoenixCP
42csIcdnnl:ChrisChris die SeeleCoA by Chris die Seele
43cvIcCVCsavil
44cyIcgf:CyygmaCYCyygma
45czIccs
46d9Im5cgH:Delta-9D9Delta-9
47daIcnl:DArchDAD'ArchCoat of Arms by Arch
48dbIcgf:DarkbobDBDarkbob
49ddIcgi:Dd..monnDDDdurbmonnejg
50dkUncgs:Dan KoehlDKDan KoehlCoats of arms by Dan Koehl
51dkrUncgs:Dan KoehlDKDan KoehlCoats of arms by Dan Koehl
52dlIcdi:D.S.LiuzzoDLDavid Liuzzo
53dtxIcdnDoc TaxonCoA by Doc Taxon
54dxrUncei:DomaleixoDODomaleixo
55ekrUncdi:EkpahEKEkpah
56elIcgf:Elolo15ELElolo15
57emIcgi:EchandoEMEchando una mano
58enImcgB:EnekorgaENEnekorga
59epAcei:BoricuaEP
60erIocgeErlenmeyerContribuciones de Erlenmeyer
61esIzcgH:EspanderoESEspandero
62etIAcgf:EtxekoETEtxeko
63euIcgc:EuryrelEUEuryrel
64eueIehgc:EuryrelEUEuryrel
65f2Icdi:Flow2F2Flow2
66f5Icgf:F5JMHF5F5JMH
67fjIcgf:FlyjackFJFlying jacket
68fmuUcFDFDRMRZUSA
69foIcsu:FennOFOFenn-O-maniC
70fqIcgi:FacquisFQFacquis
71frIcgH:FränsmerFRFränsmer
72fuIcgi:FulvioπFUFulvio314
73g2Icgi:Gb89.2G2Gb89.2
74gbIcgH:GerhardBGBGerhard Bräunlich
75gjIcgi:GJoGJGJo
76gkUcGKGeraldiker
77glIcdisx:GliwiGliwiCoA by Gliwi
78goIcGOGunnar.offel
79grIcgf:GretazGRGretaz
80gtIcgf:GroteddyGTGroteddy
81gyIehph:G_YoshGY
82heIcei:HeralderHEHeralder
83hsIcgf:HSaloméHSℍenry Salomé
84ilIcgc:IlzolendeILIlzolende
85ioIcgf:InfofiltrageIOInfofiltrage
86ipIcgc:IpankoninIPIpankoninImages by Ipankonin
87iwIcgP:Isidor WIWIsidor Welti
88j2IcJ2James2813
89j6Icgf:Jacques63J6Jacques63
90j9Icgf:Jean92J9Jean92 dit le Comte
91jcrUncbr:J.C EVENJCJ.C EVEN
92jkIcJürgen KrauseCoA by Jürgen KrauseCOA by User:Jürgen Krause
93jlIcgf:Jacques LysJLJacques Lys
94jnIcgf:Jimmy44Jimmy44Files by User:Jimmy from fr.wikipedia
95jneIehgf:Jimmy44Jimmy44Files by User:Jimmy from fr.wikipedia
96jpIcgf:JpgibertJpgibertCoA by JPGibert
97jpcIcegf:JpgibertJean-Paul GibertCoA by JPGibertProducts of jpgibert/heraldry/charge
98jpeIehgf:JpgibertJpgibertCoA by JPGibert
99jrIehph:J-RonnJRJ-Ronn
100jwUncgc:JwnabdJwnabdCoats of arms drawn by User:Jwnabd
101jwrUncgc:JwnabdJwnabdCoats of arms drawn by User:Jwnabd
102k2Tcgf:KontributorK2Kontributor 2K
103keIcgi:KetipmaigKEKetipmaig
104kiAcsk:KrumpiKIKrumpiCoats of arms by Krumpi
105kkrUncga:KKundlKKKontrollstellekundl
106l2DcL2Leonid 2
107l5rUncdi:Lothar520L5Lothar520
108laIcgi:LambertoLALamberto99
109lhrUncdi:LoschLHLosch
110lmIcgf:LeMorvandLMLeMorvandiau
111lpIcsx:Lokal_ProfilLPLokal_ProfilImages by Lokal_Profil/CoA
112luIcdi:Ludger1961LULudger1961
113lvDcgr:LobachevLV Lobachev
114lyUncgi:LynxlynxLYLynxlynx
115lyrUncgi:LynxlynxLYLynxlynx
116maIcgf:ManassasMAManassas
117mbIcgh:MadboyMadboy74CoA by Madboy74
118mcIehei:MacucalMCMacucalUser:Macucal
119meIcgi:MostEpicMEMostEpic
120mgUncgP:MagulMGMagul
121mgrUncgP:MagulMGMagul
122miIcMilenioscuroCoats of arms by User:Milenioscuro
123mlIcdwno:MaxxLMaxxLCoA by MaxxL
124mmruncgi:MassimopMMMassimop
125mnIcge:MiguillenMNMiguillen
126moIcgH:ManoillonMOManoillon
127mrIcgf:MaclaurenMRMaclauren
128mxIcdi:MaxwxyzMXMaxwxyz
129n7IcN7Nanin7
130ngIcgc:Ng556NGNg556
131ngeIehgc:Ng556NGNg556
132npIcgp:NPortuguêsNPN.Português
133odBlenderncgf:OdejeaODOdejeaFiles by Odejea/PNG coat of arms
134odeIehgf:OdejeaOdejeaFiles by Odejea/SVG ecclesiastical coat of arms
135odrBlenderncgf:OdejeaODOdejeaFiles by Odejea/PNG coat of arms
136p4Acdi:Puck04P4Puck04
137phIcdi:PerhelionPHPerhelion
138piUnehgP:PiomPIPiomPictures by PioM
139pirUnehgP:PiomPIPiomPictures by PioM
140plIcgP
141pnIcdi:PhilnatePNPhilnate
142poAcgr:PopadiusPOPopadius
143r2IcR2RaFaDa20631
144raIcgP:RagimiriRARagimiri
145rcAcRCRegicollis
146rgrUncdi:RepgowRGRepgow
147rlUncRLRootOfAllLight
148rlrUncRLRootOfAllLight
149rnIcgf:RinaldumRNRinaldum
150rqIcRQRoqz
151rvIcgi:RuthvenRuthvenCoA by Ruthven
152rveIehgi:RuthvenRuthvenCoA by Ruthven
153s0Icgf:Spax89Spax89CoA by Spax89
154s1Icgf:Spax8989Spax89
155s7Icgf:SsireS7Ssire
156saIcSajoRCoA by SajoR
157saeIehSajoREscudos eclesiásticos de SajoR
158seIcdi:Simon.ESimon.ellerCoA by Simon Eller
159sfIcSFSrfortes
160sgImcgf:SanguinezSGSanguinez
161sgeImehgf:SanguinezSGSanguinez
162siAcgH:SidoniusSISidonius
163sjIcSJSsolbergj
164skwIcgdsxSteveKCOA by SteveK
165smIcSMSamhanin
166snIcei:SeñorDLNSNElSeñorDeLaNoche
167soIcgl:SodacanSOSodacan
168spIcgf:SpedonaSPSpedona
169sqIcgeSQSanchoPanzaXXIGraphics by User:SanchoPanzaXXI
170srIcgf:SanglierTSanglierTPictures by SanglierT
171sreIehgf:SanglierTSanglierTPictures by SanglierT
172ssIcgH:Sandro S.SSSa-se
173suIcgs:C.SundinSUC.SundinImages by User:C.Sundin
174syPhotoshopncgf:SyryatsuSYSyryatsuBlason par Syryatsu
175syrPhotoshopncgf:SyryatsuSYSyryatsuBlason par Syryatsu
176taIcgH:TaktaalTATaktaal
177tcIcgf:TwocatsTCTwocats
178tfIccs:TFerenczyTFTFerenczy
179tkIcgf:TomKrTKTomKr
180tlIcgf:LanaudTLThom.Lanaud
181toIcnl:Tom-LTOTom-L
182trUncdi:TRystauTRT. Rystau
183trrUncdi:TRystauTRT. Rystau
184tuUnehTUTomáš Urban
185turUnehTUTomáš Urban
186tvIcgf:TretinvilleTVTretinvilleBlasons Tretinville
187v1AcV1ViniciusBR11
188v9Uncgi:Vale93bVale93bCoA by Vale93bU:Vale93b
189v9hUnehgi:Vale93bVale93bCoA by Vale93bU:Vale93b
190v9rUncgi:Vale93bVale93bCoA by Vale93bU:Vale93b
191vaIcgf:B.ValletteVABruno
192vdIcgf:VddbertVDVddbert
193vdeIehgf:VddbertVDVddbert
194vorUncuk:VityOKMVOVity OKM
195whTcdi:WalderichWHWalderich
196wkAcgc:KaliforniykaWKKaliforniyka
197xvIcge:XavigivaxXVXavigivax
198ylIcgf:Yves LGYLYves LG
199yrImcgf:YricordelYRYricordel
200zaIcgf:Zardoz91ZAZardoz91
201ziIcgf:ZigeunerZIZigeuner
202zoIcgf:ZorlotZOZorlot
==================
1aAc
2dIcgd
3dcIcegd
4deIehgd
5diIcdi
6dxUncei:DomaleixoDODomaleixo
7eIcge
8ecIcege
9eeIehge
10eiIcei
11exIcge
12fIcgf
13fcIcegf
14feIehgf
15fiIcfi
16fxIcgf
17gcIcgc
18hIcgH
19iIc
20iaIAc
21imImc
22itIcgi
23nlIcnl
24pbIcgf
25rieUneh
26rirUnc
27ruIcgr
28skIcflSteveKCoA by SteveKCOA by SteveK
29slAccgH:Spinner2SLSpinnerLaserzthe2nd
30tT0c
31uUcgc:UU
==================
1zzzzUcgc:??substitute:


Code

local libraryUtil = require('libraryUtil') 

local p = {}  --

-- local function "user code table" for COAInformtion users, 
-- by the user short code ('uc') as table key
-- user short code may get an expansion "c" for charges, "e" for ecclesiasticals, "x" for raster images

	utab =
  {	
--- tools:	 1    2    3 
  	a	= { 'A', nil, 'c' }; 		--	standard Adobe
  	i	= { 'I', nil, 'c' }; 		--	standard Inkscape
  	ia	= { 'IA',nil, 'c' }; 		--	Inkscape + Adobe
  	im	= { 'Im',nil, 'c' }; 		--	impotent Inkscape
	t   = { 'T', '0', 'c' };		--	Text editor
-- user:	 1    2    3    4    5			gc	sd	  U,u	su   ca
	a6	= { 'I', nil, 'c', 'gf', nil,		':Anno16', 'A6', 'Anno16' };
	ad	= { 'I', nil, 'c', 'gf', nil,		':Adalric67', 'AD', 'Adalric67' };
	ag	= { 'I', nil, 'c', 'gi', nil,		':ANGELUS', 'AG', 'ANGELUS' };
	ah	= { 'I', nil, 'c', 'nl', nil,		':AtHoek', 'AH', 'A. ter Hoek' };
	ak	= { 'Is',nil, 'c', 'gH', nil,		':ARK', 'AK', 'ARK' };
	al	= { 'I', nil, 'c', 'Hi', nil,		':Aliman', 'AL', 'Aliman5040' };
	an	= { 'I', nil, 'c', 'ge', nil,		':Anenja', 'AN', 'Anenja',nil, nil, 'Contribuciones de Anenja' };
	ao	= { 'II',nil, 'c', 'gi', nil,		':Ashoppio', 'AO' };
	ap	= { 'I', nil, 'c', 'gf', nil,		':Apn', 'AP', 'Apn' };
	ar	= { 'I', nil, 'c', 'gf', nil,		':Aroche', 'AR', 'Aroche' };
	as	= { 'I', nil, 'c',  nil, nil,		nil, 'AS', 'Archmedus' };
--	at	= { 'I', nil, 'c', 'gP', nil,		nil, 'AT', 'Alex Tora' };   images afre too poor
	au  = { 'I', nil, 'c', 'gf', nil,		':Aups', 'AU', 'Aups' };
	av	= { 'I', nil, 'c', 'gp', nil,		':Aviz2000', 'AV', 'Aviz2000' };
	ax	= { 'I', nil, 'c', 'gf', nil,		':Axel41', 'AX', 'Axel41' };
	b1	= { 'I', nil, 'c',  nil, nil,		nil, 'B1', 'B1mbo' };
	b2	= { 'I', nil, 'c', 'gf', nil,		':Barsupilami', 'B2', 'Barsupilami1512' };
	b4	= { 'A', nil, 'c', 'gi', nil,		':Baseluna', 'B4', 'Baseluna014' };
	ba	= { 'I', nil, 'c', 'gP', nil,		':Bastianow', 'BA', 'Bastianow' };
	bbr	= { 'U', 'n', 'c', 'gp', nil,		':Brian Boru', 'BB', 'Brian Boru' };
	bc  = { 'I', nil, 'c', 'gf', nil,		':ByacC', 'BC', nil, '[[User talk:ByacC|ByacC]]' };
	be	= { 'I', nil, 'c', 'gf', nil,		':Bear17', 'BE', 'Bear17' };
	bf	= { 'I', nil, 'c', 'gf', nil,		':Brookford', 'BF', 'Brookford' };
	bg	= { 'I', nil, 'c', 'gc', nil,		':Balmung', 'BG', 'Balmung0731' };		--	Japanese
	bi	= { 'I', nil, 'c', 'gf', nil,		':Bibar', 'BI', 'Bibar' };	--	nil, '-Blasons' };
	bl	= { 'I', nil, 'c', 'gf', nil,		':Bluebear', 'BL', 'Bluebear2' };
	bn	= { 'F', '8', 'c', 'gH', nil,		':Bernina', 'BN', nil,'[[User:Bernina~commonswiki|Bernina]]' };
	bo	= { 'D', nil, 'c',  nil, nil,		nil, 'Bo', 'BrCaLeTo' };
	br	= { 'I', nil, 'c', 'br', nil,		':Brieg', 'BR', 'Brieg' };
	bv	= { 'I', nil, 'c', 'gf', nil,		':Bvs-aca', 'BV', 'bvs-aca' };
	by	= { 'I', nil, 'c', 'gf', nil,		':Bizcayen', 'BY', 'Bizcayen' };
	bz	= { 'I', nil, 'c', 'gf', nil,		':Benzebu', 'BZ', 'Benzebuth198' };
	c1	= { 'A', nil, 'c',  nil, nil,		nil, 'C1', 'COAmaker17' };
	c2	= { 'D', nil, 'c', 'su', nil,		nil, 'C2', 'Care' };
--	c3	= { 'I', nil, 'c',  nil, nil,		nil, 'C3', 'Care  corel' };
	cb  = { 'I', nil, 'c', 'gf', nil,		':Celbusro', 'CB', 'Celbusro' };
	ccr	= { 'U', 'n', 'eh','gp', nil,		':CatChess', 'CC', 'CatChess' };
	ch	= { 'I', nil, 'c', 'gf', nil,		':Chatsam', nil, 'Chatsam', nil, nil, 'Blason chatsam' };
--	chc = { 'I', nil, 'ce','gf', nil,		':Chatsam', nil, 'Chatsam', nil, nil, 'Blason chatsam' };   use chx instead
	chx  = { 'I', nil, 'c', 'gf', nil,		':Chatsam', nil, 'Chatsam' };   -- not in dir. per req.
	cl	= { 'I', nil, 'c',  nil, nil,		nil, 'CL', 'Carlos yo' };
	cm =  { 'DrawShield', nil, 'c', 'gl', nil,		':Charles Matthews', nil, 'Charles Matthews' }; -- DrSh doesn't subcat CM
	cn  = { 'I', nil, 'c', 'gf', nil,		':Caranorn', 'CN', 'Caranorn' };
	cp  = { 'I', nil, 'eh','ph', nil,		':CPhoenix', 'CP' };
	cs	= { 'I', nil, 'c', 'dn','nl',		':Chris', nil, 'Chris die Seele',nil, 'CoA by Chris die Seele' };
	cv	= { 'I', nil, 'c',  nil, nil,		nil, 'CV', nil,'[[User:Christhoforos|Csavil]]' };
	cy	= { 'I', nil, 'c', 'gf', nil,		':Cyygma', 'CY', 'Cyygma' };
	d9	= { 'Im','5', 'c', 'gH', nil,		':Delta-9', 'D9', 'Delta-9' };
	da	= { 'I', nil, 'c', 'nl', nil,		':DArch', 'DA', "D'Arch",nil, nil, 'Coat of Arms by Arch'  };
	db  = { 'I', nil, 'c', 'gf', nil,		':Darkbob', 'DB', 'Darkbob' };
	dd	= { 'I', nil, 'c', 'gi', nil,		':Dd..monn', 'DD', 'Ddurbmonnejg' };
	dk  = { 'T', '0', 'c', 'gs', nil,		':Dan Koehl', 'DK', 'Sarang',nil, nil, 'Coats of arms by Dan Koehl'};
	dkr = { 'U', 'n', 'c', 'gs', nil,		':Dan Koehl', 'DK', 'Dan Koehl',nil, nil, 'Coats of arms by Dan Koehl'};
	dl	= { 'I', nil, 'c', 'di', nil,		':D.S.Liuzzo', 'DL', 'David Liuzzo' };
	dtx	= { 'I', nil, 'c', 'dn', nil,		nil, nil, 'Doc Taxon',nil, 'CoA by Doc Taxon'};
	dxr = { 'U', 'n', 'c', 'ei', nil,		':Domaleixo', 'DO', 'Domaleixo' };
	ekr	= { 'U', 'n', 'c', 'di', nil,		':Ekpah', 'EK', 'Ekpah' };
	el	= { 'I', nil, 'c', 'gf', nil,		':Elolo15', 'EL', 'Elolo15' };
	em	= { 'I', nil, 'c', 'gi', nil,		':Echando', 'EM',  nil,"''Echando una mano''" };
	en	= { 'Im',nil, 'c', 'gB', nil,		':Enekorga', 'EN', 'Enekorga' };
	ep	= { 'A', nil, 'c', 'ei', nil,		':Boricua', 'EP' };	--	 	User:The Eloquent Peasant - also Adobe
	er	= { 'Io',nil, 'c', 'ge', nil,		nil, nil, 'Erlenmeyer',nil, nil, 'Contribuciones de Erlenmeyer' };
	es	= { 'Iz',nil, 'c', 'gH', nil,		':Espandero', 'ES', 'Espandero' };
	et	= { 'IA',nil, 'c', 'gf', nil,		':Etxeko', 'ET', 'Etxeko' };
	eu	= { 'I', nil, 'c', 'gc', nil,		':Euryrel', 'EU', 'Euryrel' };
	eue	= { 'I', nil, 'eh','gc', nil,		':Euryrel', 'EU', 'Euryrel' };
	f2	= { 'I', nil, 'c', 'di', nil,		':Flow2', 'F2', 'Flow2' };
	f5	= { 'I', nil, 'c', 'gf', nil,		':F5JMH', 'F5', 'F5JMH' };
	fj	= { 'I', nil, 'c', 'gf', nil,		':Flyjack', 'FJ', 'Flying jacket' };
	fmu	= { 'U', nil, 'c',  nil, nil,		nil, 'FD', 'FDRMRZUSA' };
	fo	= { 'I', nil, 'c', 'su', nil,		':FennO', 'FO', 'Fenn-O-maniC' };
	fq	= { 'I', nil, 'c', 'gi', nil,		':Facquis', 'FQ', 'Facquis' };
	fr	= { 'I', nil, 'c', 'gH', nil,		':Fränsmer', 'FR', 'Fränsmer' };
	fu	= { 'I', nil, 'c', 'gi', nil,		':Fulvioπ', 'FU', 'Fulvio314' };
-- take care with g  -  some pseudo-keys ae reserved !	
	g2	= { 'I', nil, 'c', 'gi', nil,		':Gb89.2', 'G2', 'Gb89.2' };
	gb	= { 'I', nil, 'c', 'gH', nil,		':GerhardB', 'GB', 'Gerhard Bräunlich' };
	gj	= { 'I', nil, 'c', 'gi', nil,		':GJo', 'GJ', 'GJo' };
	gk	= { 'U', nil, 'c',  nil, nil,		nil, 'GK', 'Geraldiker' };
	gl	= { 'I', nil, 'c', 'di','sx',		':Gliwi', nil, 'Gliwi',nil, 'CoA by Gliwi' };
	go	= { 'I', nil, 'c',  nil, nil,		nil, 'GO', 'Gunnar.offel' };
	gr	= { 'I', nil, 'c', 'gf', nil,		':Gretaz', 'GR', 'Gretaz' };
	gt	= { 'I', nil, 'c', 'gf', nil,		':Groteddy', 'GT', 'Groteddy' };
	gy	= { 'I', nil, 'eh','ph', nil,		':G_Yosh', 'GY' };
	he	= { 'I', nil, 'c', 'ei', nil,		':Heralder', 'HE', 'Heralder' };
	hs	= { 'I', nil, 'c', 'gf', nil,		':HSalomé', 'HS', nil, '[[User:Henrysalome|ℍenry Salomé]]' };
-- take care with i  -  some pseudo-keys ae reserved !	
	il	= { 'I', nil, 'c', 'gc', nil,		':Ilzolende', 'IL', 'Ilzolende' };
	io	= { 'I', nil, 'c', 'gf', nil,		':Infofiltrage', 'IO', 'Infofiltrage' };
	ip  = { 'I', nil, 'c', 'gc', nil,		':Ipankonin', 'IP', 'Ipankonin',nil, nil, 'Images by Ipankonin' };
	iw	= { 'I', nil, 'c', 'gP', nil,		':Isidor W', 'IW', 'Isidor Welti' };
	j2	= { 'I', nil, 'c',  nil, nil,		nil, 'J2', 'James2813' };
	jcr	= { 'U', 'n', 'c', 'br', nil,		':J.C EVEN', 'JC', 'J.C EVEN' };
	j6  = { 'I', nil, 'c', 'gf', nil,		':Jacques63', 'J6', 'Jacques63' };
	j9	= { 'I', nil, 'c', 'gf', nil,		':Jean92', 'J9', nil, '[[User talk:Jean92 dit le Comte|Jean92 dit le Comte]]' };
	jk	= { 'I', nil, 'c',  nil, nil,		nil, nil, 'Jürgen Krause',nil, 'CoA by Jürgen Krause', 'COA by User:Jürgen Krause' };
	jl	= { 'I', nil, 'c', 'gf', nil,		':Jacques Lys', 'JL', nil, '[[User talk:Jacques Lys|Jacques Lys]]' };
	jn	= { 'I', nil, 'c', 'gf', nil,		':Jimmy44', nil, 'Jimmy44',nil, nil, 'Files by User:Jimmy from fr.wikipedia' };
	jne	= { 'I', nil, 'eh','gf', nil,		':Jimmy44', nil, 'Jimmy44',nil, nil, 'Files by User:Jimmy from fr.wikipedia' };
	jp	= { 'I', nil, 'c', 'gf', nil,		':Jpgibert', nil, 'Jpgibert',nil, 'CoA by JPGibert' };
	jpc = { 'I', nil, 'ce','gf', nil,		':Jpgibert', nil, nil,'[[User:Jpgibert|Jean-Paul Gibert]]', 'CoA by JPGibert', 'Products of jpgibert/heraldry/charge' };
	jpe = { 'I', nil, 'eh','gf', nil,		':Jpgibert', nil, 'Jpgibert',nil, 'CoA by JPGibert' };
	jr  = { 'I', nil, 'eh','ph', nil,		':J-Ronn', 'JR', 'J-Ronn' };
	jw	= { 'T', nil, 'c', 'gc', nil,		':Jwnabd', 'JW', 'Jwnabd',nil, nil, 'Coats of arms drawn by User:Jwnabd' };
	jwr	= { 'U', 'n', 'c', 'gc', nil,		':Jwnabd',  nil, 'Jwnabd',nil, nil, 'Coats of arms drawn by User:Jwnabd' };
	k2	= { 'T', nil, 'c', 'gf', nil,		':Kontributor', 'K2', 'Kontributor 2K' };
	ke	= { 'I', nil, 'c', 'gi', nil,		':Ketipmaig', 'KE', 'Ketipmaig' };
	ki	= { 'A', nil, 'c', 'sk', nil,		':Krumpi', 'KI', 'Krumpi', nil, nil, 'Coats of arms by Krumpi' };	
	kkr = { 'U', 'n', 'c', 'ga', nil,		':KKundl', 'KK', 'Kontrollstellekundl' };
	l2	= { 'D', nil, 'c', nil, nil,		nil, 'L2', 'Leonid 2' };
	l5r	= { 'U', 'n', 'c', 'di', nil,		':Lothar520', 'L5', 'Lothar520' };
	la	= { 'I', nil, 'c', 'gi', nil,		':Lamberto', 'LA', 'Lamberto99' };
	lhr	= { 'U', 'n', 'c', 'di', nil,		':Losch', 'LH', 'Losch' };
	lm	= { 'I', nil, 'c', 'gf', nil,		':LeMorvand', 'LM', 'LeMorvandiau' };
	lp	= { 'I', nil, 'c', 'sx', nil,		':Lokal_Profil', 'LP', 'Lokal_Profil',nil ,nil, 'Images by Lokal_Profil/CoA'};
	lu	= { 'I', nil, 'c', 'di', nil,		':Ludger1961', 'LU', 'Ludger1961' };
	lv	= { 'D', nil, 'c', 'gr', nil,		':Lobachev', 'LV ', nil, '[[User:Лобачев Владимир|Lobachev]]' };
	ly 	= { 'I', nil, 'c', 'gi', nil,		':Lynxlynx', 'LY', 'Lynxlynx' };
	lyr	= { 'U', 'n', 'c', 'gi', nil,		':Lynxlynx', 'LY', 'Lynxlynx' };
	ma	= { 'I', nil, 'c', 'gf', nil,		':Manassas', 'MA', nil,'[[User talk:Manassas~commonswiki|Manassas]]' };
	mb	= { 'I', nil, 'c', 'gh', nil,		':Madboy', nil, 'Madboy74',nil, 'CoA by Madboy74' };
	mc	= { 'I', nil, 'eh','ei', nil,		':Macucal', 'MC', 'Macucal',nil, nil, 'User:Macucal' };
	me	= { 'I', nil, 'c', 'gi', nil,		':MostEpic', 'ME', 'MostEpic' };
	mg	= { 'I', nil, 'c', 'gP', nil,		':Magul', nil, 'Magul' };
	mgr	= { 'U', 'n', 'c', 'gP', nil,		':Magul', 'MG', 'Magul' };
	mi	= { 'I', nil, 'c',  nil, nil,		nil, nil, 'Milenioscuro',nil, nil, 'Coats of arms by User:Milenioscuro' };
	ml	= { 'I', nil, 'c', 'dw','no',		':MaxxL', nil, 'MaxxL',nil, 'CoA by MaxxL' };
	mmr	= { 'u', 'n', 'c', 'gi', nil,		':Massimop', 'MM', 'Massimop' };
	mn	= { 'I', nil, 'c', 'ge', nil,		':Miguillen', 'MN', 'Miguillen' };
	mo	= { 'I', nil, 'c', 'gH', nil,		':Manoillon', 'MO', 'Manoillon' };
	mr	= { 'I', nil, 'c', 'gf', nil,		':Maclauren', 'MR', nil, '[[User:Maclauren~commonswiki|Maclauren]]' };
	mx	= { 'I', nil, 'c', 'di', nil,		':Maxwxyz', 'MX', 'Maxwxyz' };
	n7 =  { 'I', nil, 'c',  nil, nil,		nil, 'N7', 'Nanin7' };
	ng =  { 'I', nil, 'c', 'gc', nil,		':Ng556', 'NG', 'Ng556' };
	nge=  { 'I', nil, 'eh','gc', nil,		':Ng556', 'NG', 'Ng556' };
	np	= { 'I', nil, 'c', 'gp', nil,		':NPortuguês', 'NP', 'N.Português' };
	od	= { 'I', nil, 'c', 'gf', nil,		':Odejea', nil, 'Odejea',nil, nil, 'Files by Odejea/SVG coat of arms' };
	ode	= { 'I', nil, 'eh','gf', nil,		':Odejea', nil, 'Odejea',nil, nil, 'Files by Odejea/SVG ecclesiastical coat of arms' };
	odr = { 'Blender', 'n', 'c','gf', nil,	':Odejea','OD', 'Odejea',nil, nil, 'Files by Odejea/PNG coat of arms' };
	p4	= { 'A', nil, 'c', 'di', nil,		':Puck04', 'P4', 'Puck04' };
	ph	= { 'I', nil, 'c', 'di', nil,		':Perhelion', 'PH', 'Perhelion' };
	pi	= { 'I', nil, 'eh','gP', nil,		':Piom', 'PI', 'Piom',nil, nil, 'Pictures by PioM' };
	pir	= { 'U', 'n', 'eh','gP', nil,		':Piom', 'PI', 'Piom',nil, nil, 'Pictures by PioM' };
	pn	= { 'I', nil, 'c', 'di', nil,		':Philnate', 'PN', 'Philnate' };
	po	= { 'A', nil, 'c', 'gr', nil,		':Popadius', 'PO', 'Popadius' };
	r2	= { 'I', nil, 'c',  nil, nil,		nil, 'R2', 'RaFaDa20631' };
	ra	= { 'I', nil, 'c', 'gP', nil,		':Ragimiri', 'RA', 'Ragimiri' };
	rc	= { 'A', nil, 'c',  nil, nil,		nil, 'RC', 'Regicollis' };
	rgr	= { 'U', 'n', 'c', 'di', nil,		':Repgow', 'RG', 'Repgow' };
	rl	= { 'U', nil, 'c', nil, nil,		nil, 'RL', 'RootOfAllLight' }; -- ':R-O-A-L'
	rlr	= { 'U', 'n', 'c', nil, nil,		nil, 'RL', 'RootOfAllLight' }; -- ':R-O-A-L'
	rn	= { 'I', nil, 'c', 'gf', nil,		':Rinaldum', 'RN', 'Rinaldum' };
	rq	= { 'I', nil, 'c',  nil, nil,		nil, 'RQ', nil,'[[User:RoboQwezt0x7CB|Roqz]]' };
	rv	= { 'I', nil, 'c', 'gi', nil,		':Ruthven',nil, 'Ruthven',nil, 'CoA by Ruthven' };
	rve	= { 'I', nil, 'eh','gi', nil,		':Ruthven',nil, 'Ruthven',nil, 'CoA by Ruthven' };
	s0	= { 'I', nil, 'c', 'gf', nil,		':Spax89', nil, 'Spax89',nil, 'CoA by Spax89' };
	s1	= { 'I', nil, 'c', 'gf', nil,		':Spax89', '89', 'Spax89' };		-- noshow invalid, and don't subcat
--	s3	= { 'I', nil, 'c',  nil, nil,		nil, 'S3', 'Skjoldbro' };
	s7	= { 'I', nil, 'c', 'gf', nil,		':Ssire', 'S7', 'Ssire' };			-- + c, + e
	sa	= { 'I', nil, 'c',  nil, nil,		nil, nil, 'SajoR',nil, 'CoA by SajoR' };
	sae	= { 'I', nil, 'eh', nil, nil,		nil, nil, 'SajoR',nil, 'Escudos eclesiásticos de SajoR' };
	se	= { 'I', nil, 'c', 'di', nil,		':Simon.E', nil, 'Simon.eller',nil, 'CoA by Simon Eller' };
	sf	= { 'I', nil, 'c',  nil, nil,		nil, 'SF', 'Srfortes' };
	sg	= { 'Im',nil, 'c', 'gf', nil,		':Sanguinez', 'SG', 'Sanguinez' };
	sge	= { 'Im',nil, 'eh','gf', nil,		':Sanguinez', 'SG', 'Sanguinez' };
	si	= { 'A', nil, 'c', 'gH', nil,		':Sidonius', 'SI', 'Sidonius' };
	sj	= { 'I', nil, 'c',  nil, nil,		nil, 'SJ', 'Ssolbergj' };
	sk	= { 'I', nil, 'c',  nil,'fl',		nil, nil, 'SteveK', nil, 'CoA by SteveK', 'COA by SteveK' };
	skw	= { 'I', nil, 'c', 'gd','sx',		nil, nil, 'SteveK', nil, nil, 'COA by SteveK' };
	sl	= { 'Ac',nil, 'c', 'gH', nil,		':Spinner2', 'SL', 'SpinnerLaserzthe2nd' };
	sm	= { 'I', nil, 'c',  nil, nil,		nil, 'SM', 'Samhanin' };
	sn	= { 'I', nil, 'c', 'ei', nil,		':SeñorDLN', 'SN', 'ElSeñorDeLaNoche' };
	so	= { 'I', nil, 'c', 'gl', nil,		':Sodacan', 'SO', 'Sodacan' };
	sp	= { 'I', nil, 'c', 'gf', nil,		':Spedona', 'SP', 'Spedona' };
	sq	= { 'I', nil, 'c', 'ge', nil,		nil, 'SQ', nil, '[[User:SanchoPanzaXXI~commonswiki|SanchoPanzaXXI]]', nil, 'Graphics by User:SanchoPanzaXXI' };
	sr	= { 'I', nil, 'c', 'gf', nil,		':SanglierT', nil, 'SanglierT',nil, nil, 'Pictures by SanglierT' };
	sre	= { 'I', nil, 'eh','gf', nil,		':SanglierT', nil, 'SanglierT',nil, nil, 'Pictures by SanglierT' };
	ss	= { 'I', nil, 'c', 'gH', nil,		':Sandro S.', 'SS', 'Sa-se' };
	su	= { 'I', nil, 'c', 'gs', nil,		':C.Sundin', 'SU', 'C.Sundin',nil, nil, 'Images by User:C.Sundin' };
	sy	= { 'I', nil, 'c', 'gf', nil,		':Syryatsu', nil, 'Syryatsu',nil, nil, 'Blason par Syryatsu' };
	syr	= { 'Photoshop', 'n', 'c', 'gf', nil,		':Syryatsu', 'SY', 'Syryatsu',nil, nil, 'Blason par Syryatsu' };
	ta	= { 'I', nil, 'c', 'gH', nil,		':Taktaal', 'TA', 'Taktaal' };
	tc  = { 'I', nil, 'c', 'gf', nil,		':Twocats', 'TC', nil, '[[User talk:Twocats|Twocats]]' };
	tf	= { 'I', nil, 'c', 'cs', nil,		':TFerenczy', 'TF', 'TFerenczy' };
	tk	= { 'I', nil, 'c', 'gf', nil,		':TomKr', 'TK', 'TomKr' };
	tl	= { 'I', nil, 'c', 'gf', nil,		':Lanaud', 'TL', nil, '[[User:Thom.lanaud|Thom.Lanaud]]' };
	to	= { 'I', nil, 'c', 'nl', nil,		':Tom-L', 'TO',  'Tom-L' };
	tr	= { 'I', nil, 'c', 'di', nil,		':TRystau', 'TR',  nil, '[[User talk:Ollemarkeagle|T. Rystau]]' };
	trr	= { 'U', 'n', 'c', 'di', nil,		':TRystau', 'TR',  nil, '[[User talk:Ollemarkeagle|T. Rystau]]' };
	tu	= { 'Im',nil, 'c',  nil, nil,		nil, 'TU', nil, '[[User:Tomas.urban|Tomáš Urban]]' };
	tur	= { 'U', 'n', 'eh', nil, nil,		nil, 'TU', nil, '[[User:Tomas.urban|Tomáš Urban]]' };
	tv	= { 'I', nil, 'c', 'gf', nil,		':Tretinville', 'TV', 'Tretinville', nil, nil, 'Blasons Tretinville' };
	v1 =  { 'A', nil, 'c',  nil, nil,		nil, 'V1', 'ViniciusBR11' };
	v9 =  { 'I', nil, 'c', 'gi', nil,		':Vale93b', nil, 'Vale93b',nil, 'CoA by Vale93b', 'U:Vale93b' };
--	v9e=  { 'I', nil, 'eh','gi', nil,		':Vale93b', nil, 'Vale93b',nil, 'Ecclesiastical heraldry by Vale93b', 'U:Vale93b' };
	v9h=  { 'U', 'n', 'eh','gi', nil,		':Vale93b', nil, 'Vale93b',nil, 'CoA by Vale93b', 'U:Vale93b' };
	v9r=  { 'U', 'n', 'c', 'gi', nil,		':Vale93b', nil, 'Vale93b',nil, 'CoA by Vale93b', 'U:Vale93b' };
	va	= { 'I', nil, 'c', 'gf', nil,		':B.Vallette', 'VA', nil, '[[User:Bruno Vallette|Bruno]]' };
	vd	= { 'I', nil, 'c', 'gf', nil,		':Vddbert', 'VD', 'Vddbert' };
	vde	= { 'I', nil, 'eh','gf', nil,		':Vddbert', 'VD', 'Vddbert' };
	vor	= { 'U', 'n', 'c', 'uk', nil,		':VityOKM', 'VO', 'Vity OKM' };
	wh	= { 'T', nil, 'c', 'di', nil,		':Walderich', 'WH', 'Walderich' };
	wk	= { 'A', nil, 'c', 'gc', nil,		':Kaliforniyka', 'WK', 'Kaliforniyka' }; -- fmr. Wikimandia
	xv	= { 'I', nil, 'c', 'ge', nil,		':Xavigivax', 'XV', 'Xavigivax' };
	yl	= { 'I', nil, 'c', 'gf', nil,		':Yves LG', 'YL', 'Yves LG' };
	yr	= { 'Im', nil, 'c', 'gf', nil,		':Yricordel', 'YR', 'Yricordel' };
	za	= { 'I', nil, 'c', 'gf', nil,		':Zardoz91', 'ZA', 'Zardoz91' };
	zi	= { 'I', nil, 'c', 'gf', nil,		':Zigeuner', 'ZI', nil, '[[User:ZigeunerAlt|Zigeuner]]' }; -- Alt
	zo	= { 'I', nil, 'c', 'gf', nil,		':Zorlot', 'ZO', 'Zorlot' };
--- formatting:
	v   = { '=========', '==', '==', '==' };	--	separator
-- labs:											these are all reserved pseudo keys
	h	= { 'I', nil, 'c', 'gH' };	--	ch
	cz	= { 'I', nil, 'c', 'cs' };	--	cs
	d	= { 'I', nil, 'c', 'gd' };	--	de
	dc	= { 'I', nil, 'ce','gd' };	--	de charges
	de	= { 'I', nil, 'eh','gd' };	--	de eccles.
	di	= { 'I', nil, 'c', 'di' };	--	de individ
	dx	= { 'I', nil, 'c', 'gd' };	--	de catonly
	e	= { 'I', nil, 'c', 'ge' };	--	es
	ec	= { 'I', nil, 'ce','ge' };	--	es charges
	ee	= { 'I', nil, 'eh','ge' };	--	es eccles.
	ei	= { 'I', nil, 'c', 'ei' };	--	es individ
	ex	= { 'I', nil, 'c', 'ge' };	--	es catonly
	f	= { 'I', nil, 'c', 'gf' };	--	fr
	fc	= { 'I', nil, 'ce','gf' };	-- 	fr charges
	fe	= { 'I', nil, 'eh','gf' };	-- 	fr eccles. 
	fi	= { 'I', nil, 'c', 'fi' };	--	fr individ
	fx	= { 'I', nil, 'c', 'gf' };	--	fr catonly
	gc	= { 'I', nil, 'c', 'gc' };	--	common
	it	= { 'I', nil, 'c', 'gi' };	--	it
	nl	= { 'I', nil, 'c', 'nl' };	--	nl
	pb	= { 'I', nil, 'c', 'gf' };	--	fr project blason
	pl	= { 'I', nil, 'c', 'gP' };	--	pl
	rie	= { 'U', 'n', 'eh', nil };	--	raster image (+ c)
	rir	= { 'U', 'n', 'c',  nil };	--	raster image
	ru	= { 'I', nil, 'c', 'gr' };	--	ru
--	sx	= { 'I', nil, 'c', 'gs' };	--	sv catonly
  	u	= { 'U', nil, 'c', 'gc', nil,	':UU' }; 		--	Unknown tool
  	zzzz= { 'U', nil, 'c', 'gc', nil,	':??' ,nil, nil,"''substitute:''" };	--	return value for invalid key
  };

--------------------------------------------------------------------------------
 -- get extension flag ('s' when svg, otherwise another letter ) 
local function extflag ( )
	local page = mw.title.getCurrentTitle().text;
	local ptab = mw.text.split(page , '.', true)
	local extn = mw.ustring.lower( table.concat(ptab, '', #ptab  ) )
	return		 mw.ustring.sub ( extn, 1, 1 )
end -- local function extflag
--------------------------------------------------------------------------------
local function uctab ( uc )
	local	p1	=	mw.ustring.lower( uc ) or 'nihl';
	local	p2	=	p1;
	if	#p1 == 2 then
		if	extflag() ~= 's'  then
			p2 = p1..'r';						--	raster
		elseif gratop == 'eh' then
			p2 = p1..'e';						--	ecclesiastical
		elseif gratop == 'ce' then
			p2 = p1..'c';						--	charges
		end
	end
	if	#p1 == 3 then
		if mw.ustring.sub(p1,3) == 'c' 			--	charges
		or mw.ustring.sub(p1,3) == 'e' 			--	ecclesial
		or mw.ustring.sub(p1,3) == 'r' then		--	rasters
			p1 = mw.ustring.sub(p1,1,2);		--	shorten
		end
	end
	if 		utab[mw.ustring.lower(p2)] ~= nil then 
		return utab[mw.ustring.lower(p2)];		--	expanded key
	elseif	utab[mw.ustring.lower(p1)] ~= nil then 
		return utab[mw.ustring.lower(p1)];		--	original key
	else
		return utab[mw.ustring.lower('zzzz')];	--	neither exist
	end	
end	-- local function utab
--------------------------------------------------------------------------------
------------------------🔶🔶🔶🔶🔶🔶🔶🔶 ---------------------------------------
--------------------------------------------------------------------------------
-- global function - with the user code table
function p.main ( frame )			--	invoked from template:COAInformation
	local lpar   = frame.args
	local parstr = mw.text.trim(lpar[1] or ' ');	--	slash-separated 
	local tmplte = mw.text.trim(lpar[2] or 'Igen');	--	or c/f/m	?
	local gratop = mw.text.trim(lpar[3] or 'c');	--	graphic lab topic
	local inptab = {};
	local outtab = {};
	local argtab = mw.text.split( parstr, "/" );	--	becomes "|"
 	local labtb	=									-- corresponds with {{Igen/glc}}
	{--	parm 4 = g_lab		coa		 charge		eccles		indiv.		catonly	 Wappenwerkst		 
			g7 = 'g7';	g8 = 'g8';	g9 = 'g9';		-- + Baltic
			ga = 'ga';  gB = 'gB'; 
			gc = 'gc';	br = 'br';					-- Breton												cx = 'gc';
			gd = 'gd';	d = 'gd';	dc = 'gd';	de = 'gd';	di = 'gd';	dx = 'gd'; dw = 'gd';
			ge = 'ge';	e = 'ge';	ec = 'ge';	ee = 'ge';	ei = 'ge';	ex = 'ge';
			gl = 'en';	
			gf = 'gf';	f = 'gf';	fc = 'gf';	fe = 'gf';	fi = 'gf';	fx = 'gf'; 
			gH = 'gH';										Hi = 'gH';
			gi = 'gi';				gl = 'gl';  gh = 'gh';
			gp = 'gp';	gP = 'gP';	gr = 'gr';	nl = 'nl';	ph = 'ph';	ru = 'ru'; uk = 'uk';
			gs = 'gs';				sk = 'sk';	sl = 'sl';	si = 'gs';	sx = 'gs'; su = 'fi';
			xx = 'xx';  cx = 'cx';	cs = 'cs';  dn = '  ';  nn = '  '; 
	};

 	local nattb	= { g7='et'; g8='lt'; g9='lv'; ga='at'; gB='eu'; gc='cm'; gd='de'; ge='es'; 
 					gf='fr'; gH='ch'; gh='hu'; gi='it'; gp='pt'; gP='pl'; gr='ru'; br='br';
 					gl='en'; gs='sv'; sk='sk'; sl='sl'; nl='nl'; ph='ph'; uk='uk'; fi='fi'; cs='cs';};
	local natio = '';
 	local toptb	= { 'm', 'lm', 'wm', 'ggg', 'f', 'ffi', 'c', 'ce', 'eh', 'ee' };
	local modtb	= { 'dc', 'de', 'di', 'dx', 'dw', 'dn', 'nn' };		--	Lab modification
 	local coatb = { c = 'c'; ce = 'c'; eh = 'c'; ee = 'c'; }
 	local v_stb = { lf = ''; fl = ''; nl = ''; no = ''; none = ''; sx = ''; }
	local othtb = {};
		othtb [1] = '+';		--	re_insert the "+"


	if	gratop == ''		then gratop = 'c';  end 	-- test
	if	lpar["el"] == 'y'	then gratop = 'ce'; end 	-- test 'ce' for element (charge)
	if	lpar["eh"] == 'y'	then gratop = 'eh'; end 	-- test 'eh' for ecclesial coa
	if	lpar["el"] == 'y'
	and	lpar["eh"] == 'y'	then gratop = 'ee'; end 	-- test 'ee' for ecclesial element
	if	tmplte == 'c'			--	coa
	or	tmplte == 'f'			--	flag
	or	tmplte == 'm' then		--	map
		if	gratop ~= "ce" 
		and	gratop ~= "ee" 
		and	gratop ~= "eh" then	--	graphic lab topic comes with second parameter 
			gratop  = tmplte	--	c, f, m
		end
		tmplte  = 'Igen'
	end

--1:  get values from input parameter, to inptab
	for i, v in ipairs(argtab) do
		v	= mw.ustring.gsub( v, "  " , "↔" ),_;		-- double spaces
		v	= mw.ustring.gsub( v, " " , "" ),_;			-- remove spaces
		v	= mw.ustring.gsub( v, "[↔_]" , " " ),_;		-- but make spaces from _ and ↔ U+2194 (8596)
		local fpos = nil;
		if	v ~= '' then
			v	= mw.ustring.gsub( v, "[¦\\]" , "/" ),_;--	repl brokenbar (or "\") by slash;
			v	= mw.ustring.gsub( v, "¡" , "\\" ),_;	--	repl inv. "!" by "\"
			if	v == '~' then 
				fpos = nil; 
			else
				fpos = mw.ustring.find( mw.ustring.sub(v,2), '~' );	--	"~" becomes "="
			end
			if	fpos == nil then		--	pos, par
				if	v == '×'	then	simpl = '×';	end	
				if	v ~= '+' then
					if	i < 6	then  
						inptab [i] = v;	--	positional trimmed 
					else
						outtab [i] = v;
					end
				end
			else
				local parmn = mw.text.trim(mw.ustring.sub ( v, 1, fpos ));
				if '+' ~=  mw.ustring.sub ( v, fpos+2 ) then
					if	parmn == 'ca' 	or	parmn == 'cat2'
					or	parmn == 'gc'
					or	parmn == 'sd'
					or	parmn == 'su'	or	parmn == 'sub:'
					or	parmn == 'U'	or	parmn == 'u' 
 --					or	parmn == 'k'
					or	parmn == 'tool'	then		-- is a known parmname
						inptab [ parmn ] = mw.ustring.sub ( v, fpos+2 );
					else
						outtab [ parmn ] = mw.ustring.sub ( v, fpos+2 );
					end
				end
			end
		end
	end	

--2: All parameters are processed; check now the inptab
	for i = 1, #modtb do				--	(if	inptab[4]	== nil then) 
		if	inptab[2] == modtb[i] then	--	was Uu/ll
			inptab[4]  = inptab[2];		--	gralab modification
			inptab[2]  = nil;
		end 
	 end
	for i = 1, #modtb do
		if	inptab[3] == modtb[i] then	--	was Uu//ll 
			inptab[4]  = inptab[3];
			inptab[3]  = gratop;
		end 
	end
	local iparm1 = inptab[1];		--	tool or user_short_code	key
	local iparm2 = inptab[2];		--	error count   or missing=nil	
	local iparm3 = inptab[3];		--	topic c/ce/eh or missing=gratop
--	special case: gratop = ce, and inptab[3] = eh: ee = ecclesiastical element
--								or gratop;
	local iparm4 = inptab[4];		--	graphic lab   or missing
	local iparm5 = inptab[5];		--	vstyle        or  missing	
--	Named parameters  (maybe nil)
	local ipargc = inptab['gc'];	--	parameter gc=	
	local iparsd = inptab['sd'];	--	parameter sd=	
	local iparuu = inptab['U'];		--	parameter U=	
	local iparul = inptab['u'];		--	parameter u=	
 --	local iparky = inptab['k'];		--	parameter k=	
	local iparsu = inptab['sub:'] or inptab['su'];	--	sub:=	
	local iparca = inptab['cat2'] or inptab['ca'];	--	cat2=

--	test parm2 to parm5 for their values
	coatb ["-"] = '';	labtb ["-"] = '';	v_stb ["-"] = '';
	if iparm2 ~= nil then
		if	tonumber(iparm2)== nil	then	othtb[2] = iparm2;	iparm2 = nil;
		end
	end
	if iparm3 ~= nil then
		if	coatb [iparm3]	== nil	then	othtb[3] = iparm3;	iparm3 = nil;
		end
	end
	if iparm4 ~= nil then
		if	labtb [iparm4]	== nil	then	othtb[4] = iparm4;	iparm4 = nil;
		end
	end
	if iparm5 ~= nil then
		if	v_stb [iparm5]	== nil	then	othtb[5] = iparm5;	iparm5 = nil;		
		end
	end
-- solve the special case of numeric parm1
	if	iparm2 == nil 
	and tonumber(iparm1) ~= nil then
		iparm2  = iparm1; 			--  numeric error count
		iparm1  = 'I';				--	default tool
	end

--3: get values from the uctab	with key: iparm1
	local etab  = {};
	etab  = uctab ( iparm1 );		--	call the local function	💜💜💜💜💜💜💜💜
	if	etab [6] == ':??' then
--		etab [6]  = ':'..mw.ustring.upper(iparm1);			--	subst 'gc'
		etab [9]  = etab [9]..' '..mw.ustring.upper(iparm1);--	subst 'ul'
	end
	
--4: replace values ( set 'nil' when "-", or may be kept 'nil' )
	if	iparsd ~= nil	then	etab [10]	= nil;	end  
	if	iparsu ~= nil	then	etab [7]	= nil;	end  
	outtab [1]	=	inptab ['tool'] or etab [1];	--	converted value - NOT iparm1 key !
	if	iparm2 == '-'	then	outtab [ 2 ]	=	nil;
						else	outtab [ 2 ]	=   iparm2 or etab [2];	end
	if	etab[3] == 'eh' and gratop == 'c'	then	gratop  = etab [3];	end
	if	iparm3 == '-'	then	outtab [ 3 ]	=	nil;
						else	outtab [ 3 ]	=   iparm3 or gratop or etab [3];  end
	if	iparm4 == '-'	then	outtab [ 4 ]	=	nil;
						else	outtab [ 4 ]	=   iparm4 or etab [4];	end
	if	iparm5 == '-'	then	outtab [ 5 ]	=	nil;
						else	outtab [ 5 ]	=   iparm5 or etab [5];	end
	if	ipargc  == '-'	then	outtab ['gc']	=	nil;
						else	outtab ['gc']	=   ipargc or etab [6];	end
	if	iparsd == '-'	then	outtab ['sd']	=	nil;
						else	outtab ['sd']	=   iparsd or etab [7];	end
	if	iparuu == '-'	then	outtab ['U']	=	nil;
						else	outtab ['U']	=   iparuu or etab [8];	end
	if	iparul == '-'	then	outtab ['u']	=	nil;
						else	outtab ['u']	=   iparul or etab [9];	end
	if	iparsu == '-'	then	outtab ['sub:']	=	nil;
						else	outtab ['sub:']	=   iparsu or etab [10];end
 --	if	iparky == '-'	then	outtab ['k']	=	'~';
 --						else	outtab ['k']	=   iparky; end
	if	iparca == '-'	then	outtab ['cat2']	=	nil;
						else	outtab ['cat2']	=   iparca or etab [11];end
--		check whether parm 3,4,5 are topic, labcode, vs - or something else

    if gratop == 'ce' and inptab[3] == 'eh'	then	--	ecclesiastical element 'ee'
    	outtab [3] = 'ee';
    end
	iparm3 = outtab [3];		--	topic  - or something else
	iparm4 = outtab [4];		--	gralab - or something else
	iparm5 = outtab [5];		--	vstyle - or something else 

	local glc = 'g';
	local cnt = 0;
	for i = 1, #toptb do
		if iparm3 == toptb [i] then cnt = i; end 
	end
	if	cnt > 0 then				--	valid topic ?
		outtab ['s'] = iparm3;
		outtab [ 3 ] = nil;
		if	cnt > 6 then			--	valid coa topic
			glc = 'glc';
			if cnt == 9	then			--	'eh' = ecclesiastical heraldry 
				outtab ['s']  = 'eh';
     			outtab ['sub:'] = 'Ecclesiastical heraldry';
--	   			outtab ['w']  = 
			elseif cnt == 10	then	--	'ee' = ecclesiastical element 
				outtab ['s']  = 'eh';	--	or 'ce'    ???
     			outtab ['s:'] = 'ecclesiastical element';
--	   			outtab ['w']  = 'eccl. CoA element';
	   			outtab ['w']  = 'eccl. [[:en:Coat of arms|CoA]] element';
--	   			if	
--  -- --		outtab ['sd'] = nil;	--	no further subc ?
			 end
		end
	else
		outtab ['s'] = etab[3];		--	unknown topic
	end
	local save4 = iparm4;			--	etab or itab
	natio = labtb [iparm4] or '';
	if	natio == '' then			--	if invalid,
		iparm4  = etab [4];			--	forget it
		natio = labtb [iparm4] or '';
	end
	if	natio ~= '' then			--	valid gralab code
		outtab [ glc ]  = iparm4;			--	treat with Igen/glc
		outtab ['nat']  = natio;			--	national lab cod
		outtab ['lang'] = nattb [natio];	--	national lang code
		if	save4 == iparm4	then
			outtab [ 4 ] = nil; 			--	when from itab
		end
	else
		outtab ['g'] = save4;
	end
	--				for Doc Taxon (+ others?)
	if	iparm4	==	'dw'	then
		outtab ['gc']	=   ':'..outtab ['U'];
		outtab ['lc']	=   'n'; 				--	no lab cat
	else
		outtab ['lc']	=   's'; 				--	std lab cat
	end

	
	if	iparm5 == 'nl' 	or	iparm5 == 'lf' 	
	or	iparm5 == 'sx' 	or	iparm5 == 'no' then
		outtab ['vs'] = iparm5;		-- valid vstyle
		outtab [ 5 ] = nil;
	else
		outtab ['vs'] = etab[5];
	end

	if 	outtab ['sd'] ~= nil then	--	complete 
		outtab ['sd'] = '-'..outtab['sd'];	
	end	
	
	if	iparul ~= nil then			-- 	mutually exclusive:
		outtab['U']= nil;			--	when ul-input, U is not possible
	end	
	if	iparuu ~= nil then			-- 	but when uu-input 
		outtab['U']= iparuu;		--	it gets independently precedence 
	end
	if	extflag() ~= 's'  then
		if	outtab [2] ~= nil then
				table.insert( outtab, outtab [2]  )	
		end
		outtab [2]	= 'n'
		if	outtab [1] == 'A' 
		or	mw.ustring.sub(outtab [1], 1, 1 ) == 'I' then
			outtab [1] = 'U';
		end
	end
	if	outtab [1]	== 'U'  
	and	extflag()	~= 's'  then
		outtab['cat']= 'Raster images created with Other tools' -- ..':CoA<'..iparm1..'>';
	end
--	if	outtab [3]	== nil
--	or	outtab [3]	== 'c'
--	if	lpar["eh"]	== 'y'	then 
		outtab ['s']	= gratop;		--	'eh' or 'ee'
--	end

	for i = 1, 5 do
		if  othtb [i] ~= nil	then
			table.insert(outtab, othtb [i]);
		end
	end
	if outtab['tst'] == 'yes'	then
		tmplte = 'Showname';		-- final test
	end
	outtab ['k']	=	'~';		--	with DEFAULTSORT
	return mw.getCurrentFrame(): expandTemplate { title = tmplte, args = outtab };
end -- function main

------------------------🔷🔷🔷🔷🔷🔷🔷🔷 ---------------------------------------

function p.distab(frame)
	local lpar  = frame.args
	local sortp = lpar[1] or ' ';	--	"sort" ?
	if	sortp == 'sort' then
		sortp  = ' class="sortable" ';
	end
	local ixtab = {};			--	user entries
	local fitab = {};			--	pseudo keys
	local rowrw = {};
	local ixcnt = 0;
	local disct = 0;
	local disst = '';
	local valid = 'Valid';
	local lbtab	= 
		{	
--		parm 1 = tool pseudo keys
			a = ''; i = ''; ia = '';  im = ''; is = ''; t = '';  u = ''; rie= ''; rir= '';
			v  = '==';	zzzz = '';
--		parm 4 = g_lab		coa		 charge		eccles		indiv.		catonly	 Wappenwerkst		 
			g7 = 'et';	g8 = 'lt';	g9 = 'lv';			-- Baltic
			ga = 'at';  gB = 'eu'; 	br = 'br';			-- Breton
			gc = 'cm';
			gd = 'de';	d = 'de';	dc = 'de';	de = 'de';	di = 'de';	dx = 'de';	dw = 'de';
			ge = 'es';	e = 'es';	ec = 'es';	ee = 'es';	ei = 'es';	ex = 'es';
			gl = 'en';		--	← "gl" is used as the key for Gimli
			gf = 'fr';	f = 'fr';	fc = 'fr';	fe = 'fr';	fi = 'fr';	fx = 'fr';	pb = 'fr';
			gH = 'ch';	h = 'ch';									Hi = 'ch';
			gi = 'it';  gl = 'en';  gh = 'hu';  it = 'it';       
			gp = 'pt';  gP = 'pl';	gr = 'ru';	nl = 'nl';  ph = 'ph';	ru = 'ru';	uk = 'uk';
			gs = 'gs';				sk = 'sk';	sl = 'sl';	si = 'gs';	sx = 'gs';  su = 'fi';	
--			gs = 'sv';										si = 'sv';	sx = 'sv';	su = 'fi';
			xx = 'xx'; cx = 'cx'; cs = 'cs';
		 };
	local extab = { br=''; cs=''; gb=''; gl=''; gr=''; ph=''; si=''; su='' };		--	exceptions: these are (also) user keys
--	local rmtab = {  d; dc; de; di; dx; dw;  e; ec; ee; ei; ex;   f; fc; fe; fi; fx;  gH; h; a; i; ia; im; sx; t; u; v };	-- pseudo		  
	local outtb = '\n<table'..sortp..' border="" style="border:1px solid #999;text-align:center;border-collapse:collapse"}">';
	outtb =	outtb .. '\n<tr><th>#</th><th>key</th><th>tool</th><th>er</th><th>top</th><th>lab</th><th> — </th>'
	outtb =	outtb .. '<th>gc</th><th>sd</th><th>U</th><th>u</th><th>sub</th><th>cat</th></tr>'

	local checkType = libraryUtil.checkType
	checkType('keysToList', 1, utab, 'table')

	for key, value in pairs(utab) do		--  generate table of sorted kys 
		if	extab [key] ~= nil				--	exception:these are user keys
		or	lbtab [key] == nil then			--	no pseudokeys (tools, g_lab)
			ixcnt = ixcnt + 1; 
			ixtab[ixcnt] = key;				--	user key
		else
			table.insert (fitab, key);		--	really defined pseudokeys
		end
	end	

	table.sort(ixtab)
	table.sort(fitab)

 	table.insert (ixtab, 'v');			--	+ separator
 	for i = 1, #fitab do
 		table.insert (ixtab, fitab[i]);	--	re-insert at the end
 	end
	local fvkey = false;				--	first v-key
	local outky ='';
	for rw = 1, ixcnt + #fitab + 1  do	--	"v" was first insertion
		local tbkey = ixtab [rw];
		disct = disct + 1; 
		if tbkey == nil then 
			break;						--	iterate
		end
		if	lbtab [tbkey] ~= nil	then		-- user key also lab key
			outky  = "<kbd>''"..tbkey.."''</kbd>";
		else
			outky  = '<kbd>'..tbkey..'</kbd>';
		end
		disst = tostring(disct);
		if tbkey == 'v' then 
--			if fvkey  then 
--				break;					--	iterate
--			end
			fvkey = true;
			outky = '===';		-- separator
			disct = 0; 
			disst = ''; 
		end	
		if	lbtab [tbkey] ~= nil			-- 	lab		
		and lbtab [tbkey] ~= '=='			--	sep.
		and extab [tbkey] == nil  then		--	[gb, gl, gr, ]
--			disst = ' ';			-- pseudo lab
--			disct = disct - 0; 
		end

		rowrw = uctab ( tbkey );
		outtb =	outtb .. '\n<tr><td>'..disst..'</td><td>'..outky..'</td>'
		local bmp = false;
		if	mw.ustring.sub(tbkey,3,3) == 'r' then					--	raster
			bmp = true;
		end
		for cl = 1, 11 do
			if cl == 7 and rowrw [7] ~= nil and rowrw [10] ~= nil then
				outtb =	outtb ..'<td style="background:#FC6">'		-- hilite error 
			else	
				outtb =	outtb ..'<td>'
			end	
			if	rowrw [cl] ~= nil then 
				if cl == 8 then
 					outtb = outtb .. '[[User:'..rowrw [8]..'|'..rowrw [8]..']]';
				elseif cl == 11 then 
 					outtb = outtb .. '[[:Category:'..rowrw [11]..'|'..rowrw [11]..']]';
				elseif cl == 6 then
					if	rowrw [4] == 'dw' then 
 						outtb = outtb .. '[[:Category:Wappenwerkstatt' ..rowrw [6]..'|'..rowrw [6]..']]';
					else
						local labix = rowrw [4] or 'xx';
 						outtb = outtb .. '[[:Category:CoA Lab-'..(lbtab[labix] or '') ..rowrw [6]..'|'..rowrw [6]..']]';
					end
				elseif cl == 7 then
						  valid = 'Valid';
					local toolx = 'Inkscape';			-- also IA, Im, Io, Is ...	
						if rowrw [1] == 'T' then toolx = 'Text Editor'; 
					elseif rowrw [1] == 'U' then toolx = 'Other tools';	
					elseif rowrw [1] == 'A' then toolx = 'Adobe Illustrator';
					elseif rowrw [1] == 'D' then toolx = 'CorelDRAW';
					elseif rowrw [1] == 'F' then toolx = 'Fig2SVG';
					elseif rowrw [1] == 'Ac' then toolx = 'Vectornator'; 
												  valid = 'Invalid';
					elseif mw.ustring.sub(rowrw[1],1,1) ~= 'I' then 
						toolx =  rowrw [1]
					end
					toolx = toolx .. ':CoA';
					if bmp then 
						outtb = outtb .. '[[:Category:Raster images created with '..toolx..'-'..rowrw [7]..'|'..rowrw [7]..']]';
					else
						outtb = outtb .. '[[:Category:'..valid..' SVG created with '..toolx..'-'..rowrw [7]..'|'..rowrw [7]..']]';
					end
				elseif cl == 10 then	
					if bmp then 
						outtb = outtb .. '[[:Category:Raster images created with Other tools:'..rowrw [10]..'|'..rowrw [10]..']]';
					else
						outtb = outtb .. '[[:Category:Valid SVG created with Inkscape:'.. rowrw [10]..'|'..rowrw [10]..']]';
					end
				else	
					outtb = outtb .. rowrw [cl];
				end 
 			end
			outtb =	outtb .. '</td>'
		end
		outtb =	outtb .. '</tr>'
	end
	outtb =	outtb .. '\n</table>';
	return  outtb;
end -- function distab

------------------------🔸🔸🔸🔸🔸🔸🔸🔸 ---------------------------------------

 function p.catg(frame)			--	definitions for user category
	local lparm = frame.args	--	global param
	local uname = lparm[1];  	--	or ???
	local csrpl = lparm['r+']; 	--	catseealso raster 
	local csrmn = lparm['r-']; 	--
	local unam2 = mw.text.trim(lparm[2]  or uname);  
	local natlb = lparm[4];
	local outtb = {};
	local tooln = '???';
	local rtval = '';
	local cname = '';
	local cnamu = nil;
	local cnamu = nil;
	local cnamr = '';
	local cattx = '';
	local txttb = {};
	local sl    = 24;
	local ul    = 4;
	local cttxt = ' drawers';

	cname = mw.title.getCurrentTitle().text
	if	unam2 == nil  or unam2 == ''  or unam2 == ' ' then
		unam2 = uname;					-- didn't work ?
	end 	
	if	mw.ustring.sub(cname,1,1) == 'V' then
		cnamv = 'In' ..mw.ustring.lower(mw.ustring.sub(cname,1,1))..(mw.ustring.sub(cname,2));
		cnamr = mw.ustring.sub(cname,10,23);
	elseif mw.ustring.sub(cname,1,1) == 'I' then
		cnamv = mw.ustring.upper(mw.ustring.sub(cname,3,3))..(mw.ustring.sub(cname,4));
		cnamr = mw.ustring.sub(cname,12,25);
		sl	= 26;
	else
		cnamv = nil;
	end
	if	mw.ustring.sub(cname,-#uname-4,-#uname-1) == ' by ' then
		ul	= #uname+4;				--	_by_username
		cttxt = ' by user';
	end

	if	cname ~= nil then
		if 		mw.ustring.sub(cname,sl,sl+7) == 'Inkscape'		then tooln = 'Inkscape';			
		elseif	mw.ustring.sub(cname,sl,sl+10)== 'Other tools'	then tooln = 'Other tools';			
		elseif	mw.ustring.sub(cname,sl,sl+10)== 'Text Editor'	then tooln = 'Text Editor';			
		elseif	mw.ustring.sub(cname,sl,sl+10)== 'Adobe Illus'	then tooln = 'Illustrator';			
		elseif	mw.ustring.sub(cname,sl,sl+6) == 'Fig2SVG'		then tooln = 'Fig2SVG';	
		elseif	mw.ustring.sub(cname,sl,sl+8) == 'CorelDRAW'	then tooln = 'CorelDRAW';	
		elseif	mw.ustring.sub(cname,sl,sl+9) == 'DrawShield'	then tooln = 'DrawShield';			
		else	tooln = 'Unknown tool';
		end
	end 

	if	uname ~= nil 
	and cname ~= nil then
		if	mw.ustring.sub(uname,1,1) ~= '['
		and	mw.ustring.sub(uname,1,1) ~= '}' then 
			cnamu ='[[Special:ListFiles/'..uname..'|📤]] &nbsp;'
			uname = '[[User:'..uname..'|'..unam2..']]';
		end
		tooln = '[[Template:Created with '..tooln..'|'..tooln..']]';
		txttb['br']='Ardamezioù krouet gant '..uname..' gant '..tooln..'.';
		txttb['cs']='Erb vytvořený uživatelem '..uname..' pomocí nástroje '..tooln..'.';
		txttb['de']='Wappen die der Benutzer '..uname..' mittels '..tooln..' erstellt hat.';
		txttb['en']='Coat of arms created by the user '..uname..' using '..tooln..'.';
		txttb['es']='Escudos creados por el usuario '..uname..' utilizando '..tooln..'.';
		txttb['et']='Kasutaja '..uname..' poolt '..tooln.."'i abil loodud vapp."; 
		txttb['eu']=uname..' lankideak '..tooln..' erabiliz sortutako armarriak.'; 
		txttb['fi']= uname..'-käyttäjän '..tooln..'-ohjelmalla luoma vaakuna.';
		txttb['fr']="Blasons créés par l'utilisateur "..uname.." à l'aide de "..tooln..".";
		txttb['hu']= uname..' felhasználó által '..tooln..' segítségével készített címer.';
		txttb['it']='Stemmi creati dall utente '..uname..' usando '..tooln..'.';
		txttb['lt']='Herbas, sukurtas naudotojo '..uname..' naudojant '..tooln..'.';
		txttb['lv']='Ģerbonis, ko izveidojis lietotājs '..uname..', izmantojot '..tooln..'.';
		txttb['nl']='Wapen gemaakt door de gebruiker '..uname..' met '..tooln..'.';
		txttb['pl']='Herb stworzony przez użytkownika '..uname..' przy użyciu '..tooln..'.';
		txttb['pt']='Escudo de armas criado pelo utilizador '..uname..' com '..tooln..'.';
		txttb['ru']='Герб, созданный пользователем '..uname..' с помощью '..tooln..'.';
		txttb['sk']="Erb vytvorený používateľom "..uname.." pomocou "..tooln..".";
		txttb['sl']='Grb, ki ga je uporabnik '..uname..' ustvaril z orodjem '..tooln..'.';
		txttb['sv']='Vapensköld skapad av användaren '..uname..' med '..tooln..'.';
		txttb['tr']=uname..' kullanıcısı tarafından '..tooln..' ile oluşturulan arma.';
		txttb['uk']='Герб, створений користувачем '..uname..' за допомогою '..tooln..'.';
	end 
 	if	cnamu ~= nil then
		cattx = cnamu;			-- appears only when cnamv 
	end
	if	cnamv ~= nil then
		cattx = cattx.."See also category: [[:Category:"..cnamv.."]] __HIDDENCAT__"; 	
		if	lparm[3] == nil then
			cattx = cattx..'[[Category:'..mw.ustring.sub(cname,1,-ul)..cttxt..'| ]]';
		else 
			cattx = cattx..'[[Category:'..mw.ustring.sub(cname,1,sl-1)..lparm[3]..'| ]]';
		end
		if  mw.ustring.sub(cnamv,1,1) == 'I' then
			cattx = cattx..' &nbsp; &nbsp; with&nbsp;';
			table.insert(outtb, frame:expandTemplate{ title = "Catcont", args = { cnamv, coa='files', pref=cattx } } );
		else
			table.insert(outtb, frame:expandTemplate{ title = "=", args = { cattx..'<br />' } } );
		end
 		if	csrpl == 'y' then
			cattx = "<br /> &nbsp; &nbsp; ''and'' [[:Category:Raster images"..cnamr.."]]"; 	
  			table.insert(outtb, frame:expandTemplate{ title = "=", args = { cattx..'<br />' } } );
		end
	else
		if	mw.ustring.sub(cname,1,13) == 'Raster images' then
			cattx = 'All uploads by '..uname..': '..cattx;	-- Special:ListFiles
			cattx = cattx..' [[Category:CoA drawers raster images| ]]__HIDDENCAT__';	-- test
--			if	csrmn == 'y' then
			table.insert(outtb, frame:expandTemplate{ title = "=", args = { cattx..'<br />' } } );
		end
	end
	if	txttb['de'] ~= nil	then
	if natlb == 'br'  or  natlb == '+'	then	-- exotic languages only for such users	
  		table.insert(outtb, frame:expandTemplate{ title = "Br", args = { txttb['br'] } } );
	 end	
	if natlb == 'cs'  or  natlb == '+'	then
		table.insert(outtb, frame:expandTemplate{ title = "Cs", args = { txttb['cs'] } } );
	 end	
		table.insert(outtb, frame:expandTemplate{ title = "De", args = { txttb['de'] } } );
	 if natlb == 'et'  or  natlb == 'lt'  or  natlb == 'lv'  or  natlb == '+'	then
 		table.insert(outtb, frame:expandTemplate{ title = "Et", args = { txttb['et'] } } );
	end
		table.insert(outtb, frame:expandTemplate{ title = "En", args = { txttb['en'] } } );
		table.insert(outtb, frame:expandTemplate{ title = "Es", args = { txttb['es'] } } );
	 if natlb == 'eu'  or  natlb == '+'	then	
		table.insert(outtb, frame:expandTemplate{ title = "Eu", args = { txttb['eu'] } } );
	 end	
	 if natlb == 'fi'  or  natlb == '+'	then	
		table.insert(outtb, frame:expandTemplate{ title = "Fi", args = { txttb['fi'] } } );
	 end	
		table.insert(outtb, frame:expandTemplate{ title = "Fr", args = { txttb['fr'] } } );
	 if natlb == 'hu'  or  natlb  ==  '+'	then
		table.insert(outtb, frame:expandTemplate{ title = "Hu", args = { txttb['hu'] } } );
	end
		table.insert(outtb, frame:expandTemplate{ title = "It", args = { txttb['it'] } } );
	 if natlb == 'et'  or  natlb == 'lt'  or  natlb == 'lv'  or  natlb == '+'	then
		table.insert(outtb, frame:expandTemplate{ title = "Lv", args = { txttb['lv'] } } );
  		table.insert(outtb, frame:expandTemplate{ title = "Lt", args = { txttb['lt'] } } );
	end
		table.insert(outtb, frame:expandTemplate{ title = "Nl", args = { txttb['nl'] } } );
		table.insert(outtb, frame:expandTemplate{ title = "Pl", args = { txttb['pl'] } } );
		table.insert(outtb, frame:expandTemplate{ title = "Pt", args = { txttb['pt'] } } );
	 if natlb == 'ru'  or  natlb == '+'	then
		table.insert(outtb, frame:expandTemplate{ title = "Ru", args = { txttb['ru'] } } );
	 end
		table.insert(outtb, frame:expandTemplate{ title = "Sk", args = { txttb['sk'] } } );
		table.insert(outtb, frame:expandTemplate{ title = "Sl", args = { txttb['sl'] } } );
		table.insert(outtb, frame:expandTemplate{ title = "Sv", args = { txttb['sv'] } } );
	 if natlb == 'tr'  or  natlb  ==  '+'	then
		table.insert(outtb, frame:expandTemplate{ title = "Tr", args = { txttb['tr'] } } );
	end
		table.insert(outtb, frame:expandTemplate{ title = "Uk", args = { txttb['uk'] } } );
--		table.insert(outtb, frame:expandTemplate{ title = "  ", args = { txttb['  '] } } );
	end	
	return  table.concat (outtb)
end -- function catg

------------------------🔹🔹🔹🔹🔹🔹🔹🔹 ---------------------------------------

return p;	--