Jump to content

Module:Wiki99

From Meta, a Wikimedia project coordination wiki
Module documentation

Module:Wiki99 takes user input of Wikidata items and outputs a table which shows whether a Wikipedia article exists for that item in a list of selected languages. The intended use of this table is community organization for improving and developing lists of about 99 topics in the Wiki99 outreach model.

Internationalization

[edit]

This module generates a table supporting internationalization. Its labels can be translated on Template:Wiki99/i18n.

Usage

[edit]

Setup the table according to this template (by default, this tests and shows an extensive set of languages). "Q" numbers are Wikidata identifiers. Search for any topic in Wikidata to get its identifier.

{{#invoke:Wiki99|table
|Q2|Q405|Q525|Q283|Q309|Q5|Q3196|Q1|Q3|Q4|Q527|Q450|Q8
}}

Wikipedia articles
enaaababsaceadyaebafakalnaltamamiananganpararnarqaryarzasaseastatjavavkawaayazazbbabanbarbbcbccbcibclbebe-
tar
ask
bgbgnbhobibjnblkbmbnbobpybqibrbrhbrxbsbtmbtobugbxrcacbk-x-zamcdocecebchchochrchyckbcocpscrcrhcscsbcucvcydadagdedindiqdsbdtpdtydvdzeeegleleoeseteuextfafatfffifitfjfofonfrfrcfrpfrrfurfygagaagaggangcfgcrgdgilglgldglkgngomgorgotgpegrcgswgugucgurguwgvhahakhawhehihifhilhohrhrxhsbhsnhthuhyhywhziaidieigiiikiloinhioisitiujajamjbojutjvjv-x-bmskakaakabkbdkbpkcgkeakgkhwkikiukjkjpkkklkmknkokoikrkrckrikrjkrlkskshkswkukumkvkwkylaladlblbelezlfnlglilijlivlkilldlmolnlolozlrcltltglusluzlvlzhlzzmadmaimdfmgmhmhrmiminmkmlmnmnimnwmosmrmrhmrjmsmtmusmwlmymyvmznnanahnannapnap
-x-
tar
a
nbndndsnds-nlnenewngnianiunlnmznnnodnovnqonrfnsonvnynynnysocojboloomorospapagpampappcdpcmpdcpdtpflpipihplpmspnbpntprgpsptpwnququgrcfrgnrifrmrmcrmyrnrorskruruerupruqrwryusasahsatscscnscosdsdcsdhseseisessgsgsshshishnshysisim
ple
sjdsjeskskrslslismsmasmnsmssnsosqsrsrnsrossststqstysusvswsycszlszytataotaytcytddtetettgthtitktltlytntotpitrtrutrvtstttumtwtytyvtzmudmugukuruzvaivevecvepvivlsvmfvmwvovotvrowawalwarwlswowuuxacxalxhxmfxsyyiyoyoiyrkyrlyuayuezazeazghzhzuΣ
Wikidata item
st.
c:
1Earth307Q28310
2MoonView on maps278Q405599
3Sun298Q525396
4water264Q283577
5history238Q309172
6human222Q5365
7fire204Q3196154
8Universe191Q1274
9life169Q3193
10death174Q4263
11sky146Q52783
12mind143Q450102
13happiness118Q8121
Σautolist map13425122124118613111112135838813121171031213121312465513111312871113411101018413861346121213513410438532712131313131013241387513410711131012101351354110845510114131311135111213713138713111011131381311812612611388431381313451051151111135938115119713101013513965812369131310751241361212699137412118121041313557262136866138105556213111341313313561132131096710115121011521213741113135134312121313312612131381071366213212135912535513591348357131313171213588111361329111381312461392,752avg.:  6 \ 212
(50 %)
40859

Selection of languages to test and display

[edit]

You can pass langs=simple to get a reduced list with the most common languages:

{{#invoke:Wiki99|table
|Q2|Q405|Q525|Q283|Q309|Q5|Q3196|Q1|Q3|Q4|Q527|Q450|Q8
|langs = simple
}}

Wikipedia articles
ensim
ple
afamanarasastavayazbabebgbmbnbobrbscacechckbcocscvcydadedvdzeeeleoeseteuextfafffifjfofrfygagdglgngswgugvhahakhehihrhthuhyiaidieigioisitiujajvkakgkkklkmknkokskukwkylalblglilnloltlvmgmkmlmnmrmsmtmynannbnenlnnnyocomorospapiplpnbpsptqurmrnrorurwsascsdseshsiskslsnsosqsrstsusvswtatetgthtitktltrtstttwugukuruzvivowawarwowuuxhyiyoyuezazhzuΣ
Wikidata item
st.
c:
1Earth159Q28310
2MoonView on maps152Q405599
3Sun155Q525396
4water153Q283577
5history148Q309172
6human143Q5365
7fire129Q3196154
8Universe128Q1274
9life125Q3193
10death123Q4263
11sky112Q52783
12mind104Q450102
13happiness100Q8121
Σautolist map131312121113121388131113135131113121310113813121213135321213131313101341387131113101313108510111313131112131313871113138131212413813131011111113951110101313121313101213612131212131321386613213131313135113136751151311131312121313212131313131213591213913871313131381113613913813121391,731avg.:  11 \ 133
(82 %)
40859

You can also specify which languages are to be presented in the table by inputting their codes in the langs parameter (its value is actually a set of valid BCP 47 language tags). Language tags are encoded from Basic Latin/ASCII only, have non-significant lettercase, and must start by at 2 or 3 letters, normally from ISO 639-1, or ISO 639-2/T, or ISO 639-3 otherwise (a few legacy language tags for variants may start by a few more letters); language tags are made of subtags, each comprising 1 to 8 characters, separated by a single hyphen or underscore; subtags can only contain letters, or possibly digits (only in trailing subtags for a few variants): any other character (including controls, whitespaces, symbols, or punctuation signs) is treated as a separator between language codes.

Language are then listed as columns in the table in the specified order (but after the user language and its fallbacks that are always listed first, even if they are not requested), and should occur only once in the list:

{{#invoke:Wiki99|table
|Q2|Q405|Q525|Q283|Q309|Q5|Q3196|Q1|Q3|Q4|Q527|Q450|Q8
|langs = am,ar,be,bn,cs,da,de,el,en,es,et,fa,fi,fr,he,hi,hr,hu,hy,id,is,it,ja,ka,kk,km,ko,lo,lt,lv,mn,nb,ne,nl,pl,pt,ru,si,sk,sq,sr,sv,th,tk,tr,uk,uz,vi,zh
}}

Wikipedia articles
enamarbebncsdadeelesetfafifrhehihrhuhyidisitjakakkkmkololtlvmnnbnenlplptrusisksqsrsvthtktrukuzvizhΣ
Wikidata item
st.
c:
1Earth49Q28310
2MoonView on maps49Q405599
3Sun49Q525396
4water49Q283577
5history49Q309172
6human49Q5365
7fire48Q3196154
8Universe47Q1274
9life48Q3193
10death47Q4263
11sky43Q52783
12mind42Q450102
13happiness45Q8121
Σautolist map131213131313131312131313131313131312131313131312138131013131012121313131311131313131391313131313614avg.:  13 \ 47
(96 %)
40859

Optional parameters for showing additional result columns

[edit]

You can also set the following options to add columns that will be shown on each row before the list of tested languages:

  • image = y (or any non-empty value) for showing an examplar image for the topic, found in some properties of the Wikidata item.
{{#invoke:Wiki99|table
|Q2|Q405|Q525|Q283|Q309|Q5|Q3196|Q1|Q3|Q4|Q527|Q450|Q8
|image = y
|langs = am,ar,be,bn,cs,da,de,el,en,es,et,fa,fi,fr,he,hi,hr,hu,hy,id,is,it,ja,ka,kk,km,ko,lo,lt,lv,mn,nb,ne,nl,pl,pt,ru,si,sk,sq,sr,sv,th,tk,tr,uk,uz,vi,zh
}}
Image
Wikipedia articles
enamarbebncsdadeelesetfafifrhehihrhuhyidisitjakakkkmkololtlvmnnbnenlplptrusisksqsrsvthtktrukvizhΣ
Wikidata item
st.
c:
1Earth48Q28310
2MoonView on maps48Q405599
3Sun48Q525396
4water48Q283577
5history48Q309172
6human48Q5365
7fire47Q3196154
8Universe46Q1274
9life47Q3193
10death46Q4263
11sky42Q52783
12mind41Q450102
13happiness44Q8121
Σautolist map/gallery1312131313131313121313131313131313121313131313121381310131310121213131313111313131313913131313601avg.:  13 \ 46
(96 %)
40859
  • description = y (or any non-empty value) for showing the description label of the item in Wikidata after the name of the item, also allowing to disambiguate its default label.
{{#invoke:Wiki99|table
|Q2|Q405|Q525|Q283|Q309|Q5|Q3196|Q1|Q3|Q4|Q527|Q8|Q450
|description = y
|langs = am,ar,be,bn,cs,da,de,el,en,es,et,fa,fi,fr,he,hi,hr,hu,hy,id,is,it,ja,ka,kk,km,ko,lo,lt,lv,mn,nb,ne,nl,pl,pt,ru,si,sk,sq,sr,sv,th,tk,tr,uk,uz,vi,zh
}}

Wikipedia articles
Description on WikidataenamarbebncsdadeelesetfafifrhehihrhuhyidisitjakakkkmkololtlvmnnbnenlplptrusisksqsrsvthtktrukuzvizhΣ
Wikidata item
st.
c:
1Earththird planet from the Sun in the Solar System49Q28310
2MoonView on mapsEarth's only natural satellite49Q405599
3Sunstar at the centre of the Solar System49Q525396
4waterchemical compound whose molecules are formed by two hydrogen atoms and one oxygen atom49Q283577
5historypast events and their tracks or records49Q309172
6humanany single member of Homo sapiens, unique extant species of the genus Homo49Q5365
7firerapid oxidation of a material; phenomenon that emits light and heat48Q3196154
8Universetotality consisting of space, time, matter and energy47Q1274
9lifematter capable of extracting energy from the environment for replication48Q3193
10deathpermanent cessation of vital functions47Q4263
11skyregion of the atmosphere and outer space visible from the surface of the Earth43Q52783
12mindcombination of cognitive faculties that provides consciousness, thinking, reasoning, perception, and judgement in humans and potentially other life forms42Q450102
13happinesspositive emotional state45Q8121
Σautolist map131213131313131312131313131313131312131313131312138131013131012121313131311131313131391313131313614avg.:  13 \ 47
(96 %)
40859

Credit

[edit]

As of January 2022 the original or at least the oldest version I found is Module:WikimediaCEETable, made in 2016 by User:Voll for Wikimedia Central and Eastern Europe and which Special:WhatLinksHere/Module:WikimediaCEETable reports is used on 304 pages. It is hard for me to tell how many of those 304 pages have repeated tables, but I think about 50 of those 300 pages have original content based on checking a few. Other projects using derivative versions of this table tool are Module:WikiDonneLang from WikiDonne, which Special:WhatLinksHere/Module:WikiDonneLang reports is being used for about 10 projects. The other is Module:WikimediaCH2020 from Wikimedia CH, which Special:WhatLinksHere/Module:WikimediaCH2020 reports is being used in 6 projects.

Bluerasberry (talk) 20:01, 12 June 2022 (UTC)

-- Wiki99: builds a table of articles translated in many languages, based on sitelinks and properties from a list of Wikidata elements.
-- Can be used to list 400+ articles on 1.
-- Derived from WikimediaCEETable by User:Voll, with additions by Halibutt, Braveheart, Jura1, Strainu, Yupik, Verdy_p
-- Original at https://meta.wikimedia.org/wiki/Module:wiki99. Please contribute amendments there and keep copies in sync with that version.

-- This must constain ONLY standard BCP 47 codes used to query Wikidata elements by language
-- (see the next table for legacy Wikimedia codes used for interwiki links).
-- SHOULD be lowercase only, and separators MUST be hyphens (-) and not underscores (_).
-- Note that sitelinks can only be queried on Wikidata by replacing hyphens (-), used in actual interwiki prefixes and domain names, by underscores (_).
local langTable = {
    'aa', 'ab', 'abs', 'ace', 'ady', 'aeb', 'af', 'ak', 'aln', 'alt', 'am', 'ami', 'an', 'ang', 'anp', 'ar', 'arn', 'arq', 'ary', 'arz', 'as', 'ase', 'ast', 'atj', 'av', 'avk', 'awa', 'ay', 'az', 'azb',
    'ba', 'ban', 'bar', 'bbc', 'bcc', 'bci', 'bcl', 'be', 'be-tarask', 'bg', 'bgn', 'bho', 'bi', 'bjn', 'blk', 'bm', 'bn', 'bo', 'bpy', 'bqi', 'br', 'brh', 'brx', 'bs', 'btm', 'bto', 'bug', 'bxr',
    'ca', 'cbk-x-zam', 'cdo', 'ce', 'ceb', 'ch', 'cho', 'chr', 'chy', 'ckb', 'co', 'cps', 'cr', 'crh', 'cs', 'csb', 'cu', 'cv', 'cy',
    'da', 'dag', 'de', 'din', 'diq', 'dsb', 'dtp', 'dty', 'dv', 'dz',
    'ee', 'egl', 'el', 'en', 'eml', 'eo', 'es', 'et', 'eu', 'ext',
    'fa', 'fat', 'ff', 'fi', 'fit', 'fj', 'fo', 'fon', 'fr', 'frc', 'frp', 'frr', 'fur', 'fy',
    'ga', 'gaa', 'gag', 'gan', 'gcf', 'gcr', 'gd', 'gil', 'gl', 'gld', 'glk', 'gn', 'gom', 'gor', 'got', 'gpe', 'grc', 'gsw', 'gu', 'guc', 'gur', 'guw', 'gv',
    'ha', 'hak', 'haw', 'he', 'hi', 'hif', 'hil', 'ho', 'hr', 'hrx', 'hsb', 'hsn', 'ht', 'hu', 'hy', 'hyw', 'hz',
    'ia', 'id', 'ie', 'ig', 'ii', 'ik', 'ilo', 'inh', 'io', 'is', 'it', 'iu',
    'ja', 'jam', 'jbo', 'jut', 'jv', 'jv-x-bms',
    'ka', 'kaa', 'kab', 'kbd', 'kbp', 'kcg', 'kea', 'kg', 'khw', 'ki', 'kiu', 'kj', 'kjp', 'kk', 'kl', 'km', 'kn', 'ko', 'koi', 'kr', 'krc', 'kri', 'krj', 'krl', 'ks', 'ksh', 'ksw', 'ku', 'kum', 'kv', 'kw', 'ky',
    'la', 'lad', 'lb', 'lbe', 'lez', 'lfn', 'lg', 'li', 'lij', 'liv', 'lki', 'lld', 'lmo', 'ln', 'lo', 'loz', 'lrc', 'lt', 'ltg', 'lus', 'luz', 'lv', 'lzh', 'lzz',
    'mad', 'mai', 'mdf', 'mg', 'mh', 'mhr', 'mi', 'min', 'mk', 'ml', 'mn', 'mni', 'mnw', 'mos', 'mr', 'mrh', 'mrj', 'ms', 'mt', 'mus', 'mwl', 'my', 'myv', 'mzn',
    'na', 'nah', 'nan', 'nap', 'nap-x-tara', 'nb', 'nd', 'nds', 'nds-nl', 'ne', 'new', 'ng', 'nia', 'niu', 'nl', 'nmz', 'nn', --[['no' removed, see below]] 'nod', 'nov', 'nqo', 'nrf', 'nso', 'nv', 'ny', 'nyn', 'nys', 
    'oc', 'ojb', 'olo', 'om', 'or', 'os',
    'pa', 'pag', 'pam', 'pap', 'pcd', 'pcm', 'pdc', 'pdt', 'pfl', 'pi', 'pih', 'pl', 'pms', 'pnb', 'pnt', 'prg', 'ps', 'pt', 'pwn',
    'qu', 'qug',
    'rcf', 'rgn', 'rif', 'rm', 'rmc', 'rmy', 'rn', 'ro', 'rsk', 'ru', 'rue', 'rup', 'ruq', 'rw', 'ryu',
    'sa', 'sah', 'sat', 'sc', 'scn', 'sco', 'sd', 'sdc', 'sdh', 'se', 'sei', 'ses', 'sg', 'sgs', 'sh', 'shi', 'shn', 'shy', 'si', 'simple', 'sjd', 'sje', 'sk', 'skr', 'sl', 'sli', 'sm', 'sma', 'smn', 'sms', 'sn', 'so', 'sq', 'sr', 'srn', 'sro', 'ss', 'st', 'stq', 'sty', 'su', 'sv', 'sw', 'syc', 'szl', 'szy',
    'ta', 'tao', 'tay', 'tcy', 'tdd', 'te', 'tet', 'tg', 'th', 'ti', 'tk', 'tl', 'tly', 'tn', 'to', 'tpi', 'tr', 'tru', 'trv', 'ts', 'tt', 'tum', 'tw', 'ty', 'tyv', 'tzm',
    'udm', 'ug', 'uk', 'ur', 'uz',
    'vai', 've', 'vec', 'vep', 'vi', 'vls', 'vmf', 'vmw', 'vo', 'vot', 'vro',
    'wa', 'wal', 'war', 'wls', 'wo', 'wuu',
    'xac', 'xal', 'xh', 'xmf', 'xsy',
    'yi', 'yo', 'yoi', 'yrk', 'yrl', 'yua', 'yue',
    'za', 'zea', 'zgh', 'zh', 'zu',
}

-- Remap standard BCP 47 codes to legacy or merged codes used by interwiki links to Wikimedia wikis and in their canonical domain names.
-- Note that sitelinks can only be queried on Wikidata by replacing hyphens (-), used in actual interwiki prefixes and domain names, by underscores (_).
-- Note also that if these remapped codes match a standard BC P47 code, they cannot be used in the table above according to their BCP 47 definition.
local iwLegacyTable = {
    ['be-tarask'] = 'be-x-old', -- non-standard extension of Wikimedia wikis (only the wiki domain names use the standard BCP 47 code, but still not sitelinks in Wikidata)
    bho = 'bh', -- conflicts with BCP 47 (where 'bh' normally matches multiple Bihari languages), Wikimedia wikis assume only the Bhojpuri language
    ['bs-cyrl'] = 'bs', -- merged on Wikipedia
    ['bs-latn'] = 'bs', -- merged on Wikipedia
    ['cbk-x-zam'] = 'cbk-zam', -- non-standard extension of Wikimedia wikis
    ['de-x-formal'] = 'de', -- non-standard extension of Wikimedia wikis
    egl = 'eml', -- conflicts with BCP 47 (where 'eml' normally matches Emilian and Romagnol languages), Wikimedia wikis assume only the Emilian language
    ['es-x-informal'] = 'es-informal', -- non-standard extension of Wikimedia wikis
    gsw = 'als', -- conflicts with BCP 47 (where 'als' normally matches the unrelated Albanian Tosk language), Wikimedia wikis assume only the Alemannic language
    ['jv-x-bms'] = 'map-bms', -- non-standard extension of Wikimedia wikis
    lzh = 'zh-classical', -- deprecated in BCP 47, still used by Wikimedia wikis
    nan = 'zh-min-nan', -- deprecated in BCP 47, still used by Wikimedia wikis
    ['nap-x-tara'] = 'roa-tara', -- non-standard extension of Wikimedia wikis
    nb = 'no', -- conflicts with BCP 47 (where 'no' normally matches multiple Norwegian languages), Wikimedia wikis assume only the Bokmal Norwegian language
    ['nl-x-informal'] = 'nl', -- non-standard extension of Wikimedia wikis
    nrf = 'nrm', -- conflicts with BCP 47 (where 'als' normally matches the unrelated Narom language), Wikimedia wikis assume only the Norman language
    rup = 'roa-rup', -- non-standard extension of Wikimedia wikis
    sgs = 'bat-smg', -- non-standard extension of Wikimedia wikis
    ['sr-cyrl'] = 'sr', -- merged on Wikipedia
    ['sr-latn'] = 'sr', -- merged on Wikipedia
    syc = 'arc', -- conflicts with BCP 47 (where 'arc' normally matches multiple Aramaic languages), Wikimedia wikis assume only the Classical Neo-Syriac/Eastern Aramaic language
    ['tg-arab'] = 'tg', -- merged on Wikipedia
    ['tg-cyrl'] = 'tg', -- merged on Wikipedia
    vro = 'fiu-vro', -- non-standard extension of Wikimedia wikis
    yue = 'zh-yue', -- deprecated in BCP 47, still used by Wikimedia wikis
    ['zh-hans'] = 'zh', -- merged on Wikipedia
    ['zh-hant'] = 'zh', -- merged on Wikipedia
    ['zh-wuu'] = 'wuu', -- deprecated in BCP 47, still used in some old Wikimedia templates and in interwikis
}

-- Remap Wikimedia interwiki codes or deprecated IANA codes to standard BCP 47
local wmBCP47Table = {
    als = 'gsw', -- conflicts with BCP 47 (where 'als' normally matches the unrelated Albanian Tosk language), Wikimedia wikis assume only the Alemannic language
    arc = 'syc', -- conflicts with BCP 47 (where 'arc' normally matches multiple Aramaic languages), Wikimedia wikis assume only the Classical Neo-Syriac/Eastern Aramaic language
    ['art-lojban'] = 'jbo', -- still used in some old Wikimedia templates
    ['bat-smg'] = 'sgs', -- non-standard extension of Wikimedia wikis
    ['be-x-old'] = 'be-tarask', -- non-standard extension of Wikimedia wikis (only the wiki domain names use the standard BCP 47 code, but still not sitelinks in Wikidata)
    bh = 'bho', -- conflicts with BCP 47 (where 'bh' normally matches multiple Bihari languages), Wikimedia wikis assume only the Bhojpuri language
    ['bs-ec'] = 'bs-cyrl',
    ['bs-el'] = 'bs-latn',
    ['cbk-zam'] = 'cbk-x-zam', -- non-standard extension of Wikimedia wikis
    ['cel-gaulish'] = 'xtg', -- ambiguous, most often "xtg" for Transalpine Gaulish in today's France, may also be "xcg" for Cisalpine Gaulish in today's Northern Italy
    ['de-formal'] = 'de', -- non-standard extension of Wikimedia wikis
    eml = 'egl', -- conflicts with BCP 47 (where 'eml' normally matches Emilian and Romagnol languages), Wikimedia wikis assume only the Emilian language
    ['en-gb-oed'] = 'en-gb', -- no preferred replacement, could be "en-gb-x-oed" but actually a subset within standard "en-gb"
    ['es-informal'] = 'es', -- non-standard extension of Wikimedia wikis
    ['fiu-vro'] = 'vro', -- non-standard extension of Wikimedia wikis
    ['i-ami'] = 'ami',
    ['i-bnn'] = 'bnn',
    ['i-enochian'] = 'x-enochian', -- no clear replacement
    ['i-hak'] = 'hak',
    ['i-klingon'] = 'tlh',
    ['i-lux'] = 'lb',
    ['i-mingo'] = 'x-mingo', -- no clear replacement
    ['i-navajo'] = 'nv',
    ['i-pwn'] = 'pwn',
    ['i-tao'] = 'tao',
    ['i-tay'] = 'tay',
    ['i-tsu'] = 'tstu',
    ['map-bms'] = 'jv-x-bms', -- non-standard extension of Wikimedia wikis
    ['mo'] = 'ro-cyrl',
    ['nl-informal'] = 'nl', -- non-standard extension of Wikimedia wikis
    no = 'nb', -- conflicts with BCP 47 (where 'no' normally matches multiple Norwegian languages), Wikimedia wikis assume only the Bokmal Norwegian language
    ['no-bok'] = 'nb', -- still used in some old Wikimedia templates
    ['no-nyn'] = 'nn', -- still used in some old Wikimedia templates
    nrm = 'nrf', -- conflicts with BCP 47 (where 'als' normally matches the unrelated Narom language), Wikimedia wikis assume only the Norman language
    ['roa-rup'] = 'rup', -- non-standard extension of Wikimedia wikis
    ['roa-tara'] = 'nap-x-tara', -- non-standard extension of Wikimedia wikis
    ['sgn-be-fr='] = 'fb',
    ['sgn-be-nl'] = 'vgt',
    ['sgn-br'] = 'bzs',
    ['sgn-ch-de'] = 'sgg',
    ['sgn-co'] = 'csn',
    ['sgn-de'] = 'gsg',
    ['sgn-dk'] = 'dsl',
    ['sgn-es'] = 'ssp',
    ['sgn-fr'] = 'fsl', -- still used in some old Wikimedia templates
    ['sgn-gb'] = 'bfi',
    ['sgn-gr'] = 'gss',
    ['sgn-ie'] = 'isg',
    ['sgn-it'] = 'ise',
    ['sgn-jp'] = 'jsl',
    ['sgn-mx'] = 'mfs',
    ['sgn-ni'] = 'ncs',
    ['sgn-nl'] = 'dse',
    ['sgn-no'] = 'nsl',
    ['sgn-pt'] = 'psr',
    ['sgn-se'] = 'swl',
    ['sgn-us'] = 'ase', -- still used in some old Wikimedia templates
    ['sgn-za'] = 'sfs',
    ['sr-ec'] = 'sr-cyrl',
    ['sr-el'] = 'sr-latn',
    ['tgl'] = 'tl-tglg',
    ['zh-classical'] = 'lzh', -- deprecated in BCP 47, still used by Wikimedia wikis
    ['zh-cmn'] = 'zh', -- still used in some old Wikimedia templates, this could be an alias of "zh" on Wikimedia sites, which do not use "cmn" but assume "zh" is Mandarin
    ['zh-cmn-Hans'] = 'zh-hans', -- still used in some old Wikimedia templates, this could be an alias of "zh-hans" on Wikimedia sites, which do not use "cmn" but assume "zh" is Mandarin
    ['zh-cmn-Hant'] = 'zh-hant', -- still used in some old Wikimedia templates, this could be an alias of "zh-hant" on Wikimedia sites, which do not use "cmn" but assume "zh" is Mandarin
    ['zh-gan'] = 'gan', -- still used in some old Wikimedia templates
    ['zh-guoyu'] = 'zh', -- this could be an alias of "zh" on Wikimedia sites, which do not use "cmn" but assume "zh" is Mandarin
    ['zh-hakka'] = 'hak',
    ['zh-cn'] = 'zh-hans',
    ['zh-hk'] = 'zh-hant',
    ['zh-min'] = 'zh-tw', -- no preferred replacement, could be "zh-x-min", but actually a subset within standard "zh-tw"; not necessarily "nan"
    ['zh-min-nan'] = 'nan', -- deprecated in BCP 47, still used by Wikimedia wikis
    ['zh-mo'] = 'zh-hant',
    ['zh-ms'] = 'zh-hans',
    ['zh-sg'] = 'zh-hans',
    ['zh-tw'] = 'zh-hant',
    ['zh-wuu'] = 'wuu', -- deprecated in BCP 47, still used in some old Wikimedia templates and in interwikis
    ['zh-xiang'] = 'hsn',
    ['zh-yue'] = 'yue', -- deprecated in BCP 47, still used in some old Wikimedia templates and in interwikis
}

-- Alternate display for overlong BCP 47 language codes (inserting some breaks for narrowing table column headers)
local langCodeDisplay = {
    ['be-tarask'] = 'be-<br>tar<br>ask',
    ['nap-x-tara'] = 'nap<br>-x-<br>tar<br>a',
    simple = 'sim<br>ple',
}

local sub = string.sub
local gfind = string.gfind
local insert = table.insert
local remove = table.remove
local clone = mw.clone
local encode = mw.uri.encode

local myFrame = mw.getCurrentFrame()
local myLang = myFrame:callParserFunction('Int', 'Lang'):lower():gsub('_', '-')
local myLangBCP47 = wmBCP47Table[myLang] or myLang
myLang = iwLegacyTable[myLangBCP47] or myLangBCP47
local myLangObj = mw.language.new(myLang)
local myLangIsRTL = myLangObj:isRTL()

local function formatNum(number)
    return myLangObj:formatNum(number)
end

local myFallbacks = myLangObj:getFallbackLanguages()
for i, lang in ipairs(myFallbacks) do
    lang = lang:lower():gsub('_', '-')
    if lang == myLang then
        remove(myFallbacks, i)
        break
    end
end
insert(myFallbacks, 1, myLang)

local function getLangTable(langs)
    if langs == 'simple' then
        -- Most common modern languages with ISO 639-1 codes and a few very common languages with ISO 639-3 codes:
        langs = 'en,simple,' -- English and Simple English are always listed first (after user's language and its fallbacks)
        .. 'af,am,an,ar,as,ast,av,ay,az,ba,be,bg,bm,bn,bo,br,bs,ca,ce,ch,ckb,co,cs,cv,cy,'
        .. 'da,de,dv,dz,ee,el,eo,es,et,eu,ext,fa,ff,fi,fj,fo,fr,fy,ga,gd,gl,gn,gsw,gu,gv,'
        .. 'ha,hak,he,hi,hr,ht,hu,hy,ia,id,ie,ig,io,is,it,iu,ja,jv,ka,kg,kk,kl,km,kn,ko,ks,ku,kw,ky,'
        .. 'la,lb,lg,li,ln,lo,lt,lv,mg,mk,ml,mn,mr,ms,mt,my,nan,nb,ne,nl,nn,ny,oc,om,or,os,'
        .. 'pa,pi,pl,pnb,ps,pt,qu,rm,rn,ro,ru,rw,sa,sc,sd,se,sh,si,sk,sl,sn,so,sq,sr,st,su,sv,sw,'
        .. 'ta,te,tg,th,ti,tk,tl,tr,ts,tt,tw,ug,uk,ur,uz,vi,vo,wa,war,wo,wuu,xh,yi,yo,yue,za,zh,zu'
    end
    local t = {}
    local u = {} -- Used to detect duplicates.
    -- First insert my language and its fallbacks.
    for i, lang in ipairs(myFallbacks) do
        lang = lang:lower():gsub('_', '-')
        lang = wmBCP47Table[lang] or lang
        lang = iwLegacyTable[lang] or lang
        if not u[lang] then
            insert(t, lang)
            u[lang] = true
        end
    end
   -- Then insert the specified languages (also avoiding duplicates).
    if langs then -- Use the language list specified by a string
        for lang in gfind(langs:lower():gsub('_', '-'), '[-0-9a-z]+') do
            lang = wmBCP47Table[lang] or lang
            lang = iwLegacyTable[lang] or lang
            if not u[lang] then
                insert(t, lang)
                u[lang] = true
            end
        end
    else -- use the extensive language list by default
        for i, lang in ipairs(langTable) do
            lang = lang:lower():gsub('_', '-')
            lang = wmBCP47Table[lang] or lang
            lang = iwLegacyTable[lang] or lang
            if not u[lang] then
                insert(t, lang)
                u[lang] = true
             end
        end
    end
    return t
end

local i18nPage = 'Template:Wiki99/i18n'
local i18nSubpage = i18nPage .. '/en'
for i, lang in ipairs(myFallbacks) do
    if mw.title.new(i18nPage .. '/' .. myLang).exists then
        i18nSubpage =  i18nPage .. '/' .. myLang
        break
    end
end

local function i18n(args)
    return (myFrame:expandTemplate{title = i18nSubpage, args = args})
end

local function formatNumCell(number, class)
    if number == 0 then
        return '<td class=n>' -- Empty cell (red)
    end
    return '<td' .. (class and (' class=' .. class) or '') .. '>' .. formatNum(number)
end

local fetchLanguageName = mw.language.fetchLanguageName

local function setOf(keys, set)
    set = set or {}
    for _, k in ipairs(keys) do
        set[k] = true
    end
    return set
end

-- List of properties to ignore in the count of "main" properties for the topic: exclude internal or external identifiers, 
-- wikilinks and URLs to pages or sites covering the topic, as well as presentational and sandbox properties.
local internalProperties = setOf{
    'P213', -- ISNI
    'P227', -- GND ID
    'P244', -- 	Library of Congress authority ID
    'P345', -- IMDb ID
    'P373', -- Commons category
    'P460', -- said to be the same as, identical to
    'P856', -- official website
    'P910', -- topic's main category
    'P948', -- page banner (image at top of an article about the topic, mainly used by Wikivoyage and Women in Red)
    'P973', -- described at URL
    'P1325', -- external data available at
    'P1343', -- described by source
    'P4045', -- Sandbox-Tabular data
    'P4047', -- Sandbox-Geographic shape
    'P4656', -- Wikimedia import URL
    'P7782', -- category for ship name
    'P7861', -- category for files created with program (most often on Commons)
    'P7867', -- category for maps (most often on Commons)
    'P8464', -- content partnership category (on Commons)
    'P7561', -- category for the interior of the item
    'P8596', -- category for the exterior of the item
    'P8933', -- category for the view from the item
    'P8989', -- category for the view of the item
    'P9126', -- Commons media contributed by (contributing organization)
    'P10032', -- Museu da Pessoa History
}

-- Properties for image files (in order of preference)
local fileProperties = {
    'P154', -- logo image
    'P41', -- flag image
    'P94', -- coat of arms image
    'P158', -- seal image
    'P4004', -- escutcheon image, shield
    'P2425', -- service ribbon image
    'P8766', -- rank insignia (e.g. military)

    'P18', -- image
    'P10093', -- image with color chart

    'P242', -- locator map image
    'P15', -- route map
    'P1621', -- detail map
    'P1943', -- location map
    'P1944', -- relief location map
    'P207', -- bathymetry image

    'P14', -- traffic sign
    'P3383', -- film poster (movie)
    'P3311', -- image of design plans
    'P996', -- document file, scan image, book image, PDF
    'P3030', -- sheet music, musical score
    'P2343', -- playing range image (music)

    'P109', -- signature (image), autograph
    'P7457', -- creator's signature
    'P1543', -- monogram
    'P8195', -- ex-libris, bookplate (for a person)
    'P1801', -- commemorative plaque image
    'P1442', -- image of grave
    'P9906', -- inscription image

    'P692', -- Gene Atlas Image
    'P4640', -- photosphere image

    'P491', -- orbit diagram (astronomical)
    'P367', -- astronomic symbol image
    'P5962', -- sail emblem
    'P9664', -- named place on map
    'P4896', -- 3D model
    'P117', -- chemical structure
    'P5555', -- schematic diagram
    'P6655', -- stroke order (for Han ideographs)
    'P2910', -- icon

    'P5252', -- winter view
    'P3451', -- nighttime view
    'P8592', -- aerial view of the subject, orthophoto, satellite image
    'P2713', -- sectional view

    'P1766', -- place name sign
    'P8667', -- twin town sign
    'P9721', -- image of entrance
    'P5775', -- image of interior (indoor)
    'P8517', -- view (from the from the given site)
    'P4291', -- panoramic view
    'P2716', -- collage image

    'P1846', -- distribution map
    'P181', -- taxon range map image
    'P6802', -- related image (alternate, secondary, decorative, placeholder...)

    'P10', -- video

    'P990', -- audio recording of the subject's spoken voice
    'P443', -- pronunciation audio
    'P989', -- spoken text audio
    'P51', -- audio
}

-- List of properties to count as additional informative properties on Commons 
local commonsProperties = setOf{
    'P935', -- Commons gallery
    'P1472', -- Commons Creator page
    'P1612', -- Commons Institution page
    'P2033', -- category for pictures taken with camera
    'P3896', -- geoshape (for vector maps)
    'P4150', -- weather history (tabular data)
    'P4179', -- tabular population
    'P4669', -- tabular software version
    'P8204', -- tabular case data (confirmed cases, recoveries, deaths, etc. due to a medical event)
    'P8265', -- based on tabular data
    'P10358', -- original catalog description (from institutional catalog metadata)
}
setOf(fileProperties, commonsProperties)

local wikibase = mw.wikibase
local getLabelWithLang = wikibase.getLabelWithLang
local getEntityObject = wikibase.getEntityObject
local renderSnak = wikibase.renderSnak

local function getmainsnakid(entity, property)
    local stmt = entity:getBestStatements(property)[1]
    return stmt
        and stmt.mainsnak.snaktype == 'value'
        and stmt.mainsnak.datavalue.type == 'wikibase-entityid'
        and stmt.mainsnak.datavalue.value['id']
        or nil
end

local function renderDate(entity, property)
    local stmt = entity:getBestStatements(property)[1]
    if stmt then
        local snak = stmt.mainsnak
        if snak.snaktype == 'value' and snak.datavalue.type == 'time' then
            if snak.datavalue.value.precision > 9 then
                -- More precise than year, make it year-precise.
                -- Make a deep copy to make sure we don’t change anything outside of this.
                snak = clone(snak)
                snak.datavalue.value.precision = 9 -- year:9, month:10, day:11, hour:12, minute:13, second:14, fraction:15
            end
            -- Don't render dates with a precision less than the year
            if snak.datavalue.value.precision >= 9 then
                return renderSnak(snak)
            end
        end
    end
    return nil
end

---------------------------------------------------------------------------------------------------
local p = {}

--[[
Wiki99.count: counts articles from the list in certain wiki.
Sample use:
    {{#invoke:Wiki99|table|Q1|Q2|Q3|Q4|Q5}}
    {{#invoke:Wiki99|table|Q1|Q2|Q3|Q4|Q5|lang=en,simple}}
]]
function p.table(frame)
    local result = {
        frame:extensionTag{name = 'templatestyles', args = {src = 'Template:Wiki99/styles.css'}},
        '<div class="wiki99 mw-content-', myLangIsRTL and 'rtl' or 'ltr',
        '" lang="', myLangBCP47,
        '"><table class=sortable><tr>',
    }

    -- Rank column (R)
    insert(result, '<th class=R>')

    -- Optional Image column (F)
    local image = frame.args['image']
    if image then
        insert(result, '<th class="F unsortable">')
        insert(result, i18n{'F'})
    end

    -- Wikipedia articles column (A)
    insert(result, '<th class=A>')
    insert(result, '[[File:Wikipedia-logo.svg|x20px|link=|alt=]]<br>')
    insert(result, (i18n{'A'}))

    -- Optional occupation column (O)
    local occupation = frame.args['occupation']
    if occupation then
        insert(result, '<th class=O>')
        insert(result, i18n{'O'})
    end

    -- Optional description column (D)
    local description = frame.args['description']
    if description then
        insert(result, '<th class="D unsortable">')
        insert(result, i18n{'D'})
    end

    -- Languages columns (L)
    local langTable = getLangTable(frame.args['langs'])
    for i, iw in ipairs(langTable) do
        local langBCP47 = wmBCP47Table[iw] or iw
        local langName = fetchLanguageName(langBCP47, myLangBCP47)
        insert(result, '<th class="L unsortable" title="')
        insert(result, (fetchLanguageName(langBCP47, myLangBCP47):gsub('"', '&#34;')))
        insert(result, '">')
        insert(result, langCodeDisplay[langBCP47] or langBCP47)
    end

    -- Counted languages column (N)
    insert(result, '<th class=N>Σ')

    -- Wikidata column (Q)
    insert(result, '<th class=Q>[[File:Wikidata-logo.svg|x20px|link=|alt=]]<br>')
    insert(result, i18n{'Q'})

    -- Main statements column (S)
    insert(result, '<th class=S><abbr title="')
    insert(result, (i18n{'S2'}:gsub('"', '&#34;')))
    insert(result, '">')
    insert(result, i18n{'S'})
    insert(result, '</abbr>')

    -- Wikimedia Commons column (C)
    insert(result, '<th class="C unsortable">[[File:Commons-logo.svg|x20px|link=|alt=]]<br><abbr title="')
    insert(result, (i18n{'C'}:gsub('"', '&#34;')))
    insert(result, '">c:</abbr>')

    -- Enumerate QIDs in parameters and generate one table row for each
    local statementst = 0
    local coords = 0
    local images = 0
    local timeline = 0
    local wqsitems = ''
    local ids = {}
    local ctt = {}
    local commonst = 0
    for i = 1, #langTable do
        ctt[i] = 0
    end
    local anum = 0
    while true do
        local qid = frame.args[anum + 1]
        if not qid then
            break
        end
        qid = qid:gsub('^%s+', ''):gsub('%s+$', '') -- strip leading/trailing whitespace
        wqsitems = wqsitems .. ' wd:' .. qid
        local id = sub(qid, 2)
        insert(ids, id)
        local entity = getEntityObject(qid)
        if not entity then
            return '<strong class=error>Entity ' .. qid .. ' not found</strong>'
        end

        -- Count main statements on Wikidata and detect extra properties to Wikimedia Commons)
        local commons = 0
        local statements = 0
        if entity.claims then
            for property, statement in pairs(entity.claims) do
                local snak = statement[1].mainsnak
                if snak then
                    if not internalProperties[property] then
                        if snak.datatype ~= 'external-id' then
                            statements = statements + 1
                        end
                    end
                    if commonsProperties[property] then
                        commons = commons + 1
                    end
                end
            end
        end

        --- New data row
        insert(result, '<tr>')

        -- Rank column (R)
        anum = anum + 1
        insert(result, '<th class=R>')
        insert(result, formatNum(anum))

        -- Optional image column (F)
        if image then
            local file
            for i, prop in ipairs(fileProperties) do
                local stmt = entity:getBestStatements(prop)[1]
                filename = stmt
                    and stmt.mainsnak.snaktype == 'value'
                    and stmt.mainsnak.datavalue.type == 'string' --'commonsMedia'
                    and stmt.mainsnak.datavalue.value
                if filename and filename ~= '' then
                    break
                end
            end
            if not filename or filename == '' then
                insert(result, '<td class=n>') -- Empty cell (red)
            else
                insert(result, '<td class=F>[[File:')
                insert(result, filename)
                insert(result, '|80x120px|alt=]]')
                images = images + 1
            end
        end

        -- Wikipedia articles column (A)
        -- (show the best Wikidata label, linked to the first article found in a Wikipedia from the fallbacks list)
        local label, labelLang = entity:getLabelWithLang()
        if not label then
            insert(result, '<td class=An>') -- Empty cell (red)
        else
            local hrefLang, sitelinkLang, sitelink
            local usingFallback = false
            for i, lang in ipairs(myFallbacks) do
               hrefLang = lang
               sitelinkLang = iwLegacyTable[lang] and iwLegacyTable[lang] or lang
               sitelink = entity:getSitelink(sitelinkLang:gsub('-', '_') .. 'wiki')
               if sitelink then
                   break
               end
                usingFallback = true
            end
            insert(result, '<td class=A')
            insert(result, sitelink and not usingFallback and '' or 'n')
            labelLang = wmBCP47Table[labelLang] or labelLang
            if labelLang ~= myLangBCP47 then
                insert(result, ' lang="')
                insert(result, labelLang)
                insert(result, '" dir=auto')
            end
            insert(result, '>')
            if not sitelink then
                insert(result, label)
            else
                insert(result, '[[:')
                insert(result, sitelinkLang)
                insert(result, ':')
                insert(result, sitelink)
                insert(result, '|')
                if hrefLang == labelLang then
                    insert(result, label)
                else
                    insert(result, '<span lang="')
                    insert(result, labelLang)
                    insert(result, '">')
                    insert(result, label)
                    insert(result, '</span>')
                end
                insert(result, ']]')
            end
        end
        local date1, date2
        if getmainsnakid(entity, 'P31') == 'Q5' then -- instance of: human
            -- Gender icon
            local genderid = getmainsnakid(entity, 'P21')
            if genderid == 'Q6581097' or genderid == 'Q2449503' or genderid == 'Q27679766' then
                --  males (Q6581097), transgender males (Q2449503) transmasculines (Q27679766),
                insert(result, ' [[File:Male Icon.svg|15px|link=|alt=♂]]')
            elseif genderid == 'Q6581072' or genderid == 'Q1052281' or genderid == 'Q27679684' then
                -- females (Q6581072), transgender females (Q1052281), and transfeminines (Q27679684),
                insert(result, ' [[File:Female Icon.svg|15px|link=|alt=♀]]')
            elseif genderid == 'Q660882' then
              -- hijras (Q660882), neither male or female
                insert(result, ' [[File:MOREmoji transgender symbol 2.svg|15px|link=|alt=⚧️]]')
            end
            -- Lifespan years for humans (Q5)
            date1 = renderDate(entity, 'P569') -- date of birth
            date2 = renderDate(entity, 'P570') -- date of death
        else
            -- Years for other types
           date1 = renderDate(entity, 'P571') -- date of inception, creation, foundation
           date2 = renderDate(entity, 'P576') -- dissolved, abolished or demolished date
           if not date1 and date2 then
               date1 = ''
           elseif not date2 and date1 then
               date2 = ''
           end
           local date = renderDate(entity, 'P580') -- start time
           if date and (not date1 or date < date1) then
               date1 = date
               if not date2 then
                   date2 = ''
               end
           end
           date = renderDate(entity, 'P582') -- end time
           if date and (not date2 or date > date2) then
               date2 = date
               if not date1 then
                   date1 = ''
               end
           end
           date = renderDate(entity, 'P577') -- publication date
           if date and date1 and date < date1 then
               if not date2 then
                   date2 = date1
               end
               date1 = date
           end
        end
        -- Show dates, add to the timeline
        if date1 or date2 then
            insert(result, ' <bdi class=s>(')
            insert(result, date1 or '')
            if date1 ~= date2 then
                insert(result, '–')
                insert(result, date2 or '')
            end
            insert(result, ')</bdi>')
            timeline = timeline + 1
        end
        -- Geolocation coordinates
        local coord = entity:getBestStatements('P625')[1] -- coordinate location
        if coord then
            local label = i18n{'view on maps'}
            insert(result, ' [[File:Geographylogo.svg|18px|link=')
            insert(result, 'https://geohack.toolforge.org/geohack.php?language=en&pagename=')
            insert(result, encode(label, 'QUERY'))
            insert(result, '&params=')
            insert(result, coord.mainsnak.datavalue.value.latitude)
            insert(result, '_N_')
            insert(result, coord.mainsnak.datavalue.value.longitude)
            insert(result, '_E')
            insert(result, '|alt=')
            insert(result, label)
            insert(result, '|')
            insert(result, label)
            insert(result, ']]')
            coords = coords + 1
        end

        -- Optional occupation column (O)
        if occupation then
            local desc, descLang
            local qid = getmainsnakid(entity, 'P106') -- occupation
            if qid then
                desc, descLang = getLabelWithLang(qid)
            end
            if desc then
                insert(result, '<td class=O')
                descLang = wmBCP47Table[descLang] or descLang
                if descLang ~= myLangBCP47 then
                    insert(result, 'n lang=')
                    insert(result, descLang)
                    insert(result, ' dir=auto')
                end
                insert(result, '>')
                insert(result, desc)
            else
                insert(result, '<td class=n>') -- Empty cell (red)
            end
        end

        -- Optional description column (D)
        if description then
            local desc, descLang = entity:getDescriptionWithLang()
            if desc then
                insert(result, '<td class=D')
                descLang = wmBCP47Table[descLang] or descLang
                if descLang ~= myLangBCP47 then
                    insert(result, 'n lang=')
                    insert(result, descLang)
                    insert(result, ' dir=auto')
                end
                insert(result, '>')
                insert(result, desc)
            else
                insert(result, '<td class=n>') -- Empty cell (red)
            end
        end

        -- Language columns (L)
        local ct = 0
        for i, lang in ipairs(langTable) do
            -- Remap BCP 47 or legacy Wikimedia Interwiki codes to the interwiki codes that are currently working (this may change over time!).
            local iw = iwLegacyTable[lang] or lang
            local sitelink = entity:getSitelink(lang:gsub('-', '_') .. 'wiki')
                or iw ~= lang and entity:getSitelink(iw:gsub('-', '_') .. 'wiki')
            insert(result, '<td class=')
            if sitelink then
                insert(result, 'L>[[:')
                insert(result, iw)
                insert(result, ':')
                insert(result, sitelink)
                insert(result, '|✔]]')
                ct = ct + 1
                ctt[i] = ctt[i] + 1
            else
                insert(result, 'n>') -- ✗
            end

        end -- of loop on languages

        -- Counted languages column (N)
        insert(result, formatNumCell(ct, 'N'))

        -- Wikidata column (Q)
        insert(result, '<td class=Q data-sort-value="')
        insert(result, id)
        insert(result, '">[[d:')
        insert(result, qid)
        insert(result, '|')
        insert(result, qid)
        insert(result, ']]')

        -- Main statements column (S)
        insert(result, formatNumCell(statements, 'S'))
        statementst = statementst + statements

        -- Wikimedia Commons column (C)
        if commons > 0 then
            insert(result, '<td class=C title="')
            insert(result, (i18n{'commons-resources'}:gsub('"', '&#34;')))
            insert(result, '">')
            insert(result, commons)
            commonst = commonst + commons
        else
            insert(result, '<td class=n>') -- Empty cell (red)
        end
    end -- of loop for rows on each item

    -- Footer row
    insert(result, '<tr class="sortbottom">')

    -- Rank column (R)
    insert(result, '<th class=R>Σ')

    -- Image column (F)
    if image then
        insert(result, '<td class=e>') -- Empty cell (gray)
    end

    -- Wikipedia articles column (A)
    -- (show links to autolist, maps, gallery, timeline)
    insert(result, '<td class=A>[https://autolist.toolforge.org/?run=Run&chunk_size=10000&mode_manual=or&mode_cat=or&mode_wdq=not&mode_wdqs=or&mode_find=or&project=wikipedia&language=')
    insert(result, myLang)
    insert(result, '&wdq=items')
    insert(result, encode('[' .. table.concat(ids, ',') .. ']', 'QUERY'))
    insert(result, ' <bdi>')
    insert(result, (i18n{'autolist'}))
    insert(result, '</bdi>]')
    if coords > 0 or images > 0 then
        insert(result, ' [https://query.wikidata.org/#')
        insert(result, encode(
                '# Click the "Execute" icon on the left side to run the query,\n' ..
                '# then below select the type of view: "Map" or "Image Grid".\n' ..
                'SELECT\n' ..
                    '\t?item \n' ..
                    '\t?itemLabel \n' ..
                    '\t(GROUP_CONCAT(DISTINCT(?instanceLabel);separator=", ")AS ?instanceOf)\n' ..
                    '\t(SAMPLE(?coord)AS ?coordinates)\n' ..
                    '\t(SAMPLE(?img)AS ?image)\n' ..
                'WHERE{\n' ..
                    '\tVALUES ?item{' .. wqsitems .. ' }\n' ..
                    '\tOPTIONAL{?item wdt:P31 ?instance}.\n' .. -- instance of
                    '\tOPTIONAL{?item wdt:P625 ?coord1}.\n' .. -- coordinate location
                    '\tOPTIONAL{?item wdt:P131/wdt:P625 ?coord2}.\n' .. -- located in the administrative territorial entity/coordinate location
                    '\tOPTIONAL{?item wdt:P276/wdt:P625 ?coord3}.\n' .. -- location/coordinate location
                    '\tBIND(IF(BOUND(?coord1),?coord1,IF(BOUND(?coord2),?coord2,?coord3))AS ?coord).\n' ..
                    '\tOPTIONAL{?item wdt:P18 ?img}.\n' .. -- image
                    '\tSERVICE wikibase:label{\n' ..
                        '\t\tbd:serviceParam wikibase:language "' .. myLangBCP47 .. ',en".\n' ..
                        '\t\t?item rdfs:label ?itemLabel.\n' ..
                        '\t\t?instance rdfs:label ?instanceLabel\n' ..
                    '\t}\n' ..
                '}\n' ..
                'GROUP BY ?item ?itemLabel',
            'PATH'))
        insert(result, ' <bdi>')
        insert(result, (i18n{(coords > 0 and 'map' or '') .. (images > 0 and 'gallery' or '')}))
        insert(result, '</bdi>]')
    end
    if timeline > 2 then
        insert(result, ' [https://wikidata-timeline.toolforge.org/#/timeline?query=')
        insert(result, encode('items[' .. table.concat(ids, ',') .. ']', 'QUERY'))
        insert(result, ' <bdi>')
        insert(result, (i18n{'timeline'}))
        insert(result, '</bdi>]')
    end

    -- Optional occupation column (O)
    if occupation then
        insert(result, '<td class=e>') -- Empty cell (gray)
    end

    -- Optional description column (D)
    if description then
        insert(result, '<td class=e>') -- Empty cell (gray)
    end

    -- Language columns (L)
    ct = 0
    for i, lang in ipairs(langTable) do
        local c = ctt[i]
        insert(result, formatNumCell(c, 'L'))
        ct = ct + c
    end

    -- Counted languages column (N)
    insert(result, formatNumCell(ct, 'N'))

    -- Wikidata column (Q)
    insert(result, '<td class=Q>')
    insert(result, (i18n{'avg',
        numlang = formatNum(#langTable),
        avglang = formatNum(math.floor(ct / anum + .5)),
        numarticle = formatNum(#ids),
        avgarticle = formatNum(math.floor(ct / (#langTable) + .5)),
        numtotal = formatNum(#langTable * anum),
        avgtotal = formatNum(math.floor(100 * ct / (anum * #langTable) + .5))
        }))

    -- Statements column (S)
    insert(result, formatNumCell(statementst, 'S'))

    -- Wikimedia Commons column (C)
    insert(result, formatNumCell(commonst, 'C'))

    -- End of footer and table
    insert(result, '</table></div>')
    return table.concat(result)
end

--[[
Wiki99.count: counts articles from the list in certain wiki, based on previous "table" function stripped from all the table formatting.
Sample use:
    {{#invoke:wiki99|count|en|Q1|Q2|Q3|Q4|Q5}}
    {{#invoke:wiki99|count|en|Q1|Q2|Q3|Q4|Q5|lang=en,simple}}
]]
function p.count(frame)
    local myLang = frame.args[1]
    local myLangBCP47 = iwLegacyTable[lang] or myLang
    local myIw = wmBCP47Table[myLangBCP47]
    local langTable = getLangTable(frame.args['langs'])

    local ctt = {}
    for i = 1, #langTable do
        ctt[i] = 0
    end

    local anum = 0
    while true do
        local qid = frame.args[anum + 2]
        if not qid then
            break
        end
        anum  = anum + 1

        local entity = getEntityObject(qid)
        if not entity then
            return '<strong class=error>Entity ' .. qid .. ' not found</strong>'
        end
        for i = 1, #langTable do
            local iw = langTable[i]
            local sitelink = entity:getSitelink(iw:gsub('-', '_') .. 'wiki') or
                iw ~= myIw and entity:getSitelink(myIw:gsub('-', '_') .. 'wiki')
            if sitelink then
                ctt[i] = ctt[i] + 1
            end
        end
    end -- of loop counting rows

    -- Number of articles in certain wiki. Straight...
    local ct = 0
    for i = 1, #langTable do
        if langTable[i] == lang then
            ct = ctt[i]
        end
    end
    return wikianum .. '/' .. anum -- Result is two numbers with '/' separator
end

return p