Módulo:Testes

A documentação para este módulo pode ser criada na página Módulo:Testes/doc

require('Module:No globals')
local p = {}
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
local testcases = (string.sub(title.subpageText,1,9) == 'Exemplos para testes')
--[[==========================================================================]]
--[[                            Category functions                            ]]
--[[==========================================================================]]
local function addCat( cat )
				if cat then return '[[Categoria:'..cat..']]'..p.redCatLink(cat) end
				return ''
end
function p.getCatForId( id )
				local cat = ''
				if namespace == 0 then
								cat = '!Artigos enciclopédicos com identificadores '..id
				elseif namespace == 2 and not title.isSubpage then
								cat = '!Páginas de usuário com identificadores '..id
				else
								cat = '!Páginas de teor misto com identificadores '..id
				end
				return addCat(cat)
end
function p.redCatLink( cat ) --cat == 'Blah' (not 'Category:Blah', not '[[Categoria:Blah]]')
				if cat and cat ~= '' and
							testcases == false and
							mw.title.new(cat, 14).exists == false
				then
								return '' --'[[Categoria:Pages with red-linked authority control categories]]'
				end
				return ''
end
function p.createRow( id, rawValues, link, links, withUid, specialCat, prefix)
				local faultyCat = '!Artigos com identificadores com erro '..(specialCat or id)
				if links then -- all links[] use withUid = false; no check needed
								local row = ''
								if prefix then
												row = row..'*'..prefix
								end
								for i, l in ipairs( links ) do
												if i == 1 and not prefix then row = row..'*'
												else           row = row..'\n**' end
												if l then
																row = row..'<span class="uid">'..l..'</span>'
												else
																row = row..'<span class="error">O '..id..' id '..rawValues[i]..' não é válido.</span>'..addCat(faultyCat)
												end
								end
								return row..'\n'
				elseif link then -- All IDs that have a prefix support multiple identifiers, so prefix is not needed
								if withUid then
												return '*<span class="nowrap"><span class="uid">'..link..'</span></span>\n'
								end
								return '*<span class="nowrap">'..link..'</span>\n'
				end
				
				return '* <span class="error">O '..id..' id '..rawValues..' não é válido.</span>' ..addCat(faultyCat)..'\n'
end
--[[==========================================================================]]
--[[                      Property formatting functions                       ]]
--[[==========================================================================]]
-- If a link has a suitable entry in the global inter-wiki prefix table at [[:m:Interwiki_map]],
-- please consider routing through this prefix rather than as external link URL.
-- This will ease future maintenance as necessary updates to the link can be centrally carried out there rather than by updating this module.
-- The "external link" icon would disappear for such entries.
function p.aagLink( id, label)
				--P3372's format regex: \d+ (e.g. 1)
				if not id:match( '^%d+$' ) then
								return false
				end
				return '[https://www.aucklandartgallery.com/explore-art-and-ideas/artist/'..id..'/ '..(label or 'Auckland')..']'
end
function p.acmLink( id, label )
				--P864's format regex: \d{11} (e.g. 12345678901)
				if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d$' ) then
								return false
				end
				return '[https://dl.acm.org/profile/'..id..' '..(label or 'Association for Computing Machinery')..']'
end
function p.adbLink( id, label )
				--P1907's format regex: [a-z][-a-z]+-([1-3]\d|[1-9])\d{0,3} (e.g. barton-sir-edmund-toby-71)
				if not id:match( '^[a-z][-a-z]+-[1-3]%d%d?%d?%d?$' ) and
							not id:match( '^[a-z][-a-z]+-[1-9]%d?%d?%d?$' ) then
								return false
				end
				return '[http://adb.anu.edu.au/biography/'..id..' '..(label or 'Austrália')..']'
end
function p.admiraltyLink(id,label)
				--P3562's format regex: [A-Q]\d{4}(\.\d+)? (e.g. D1204.1)
				if not id:match('^[A-Q]%d%d%d%d$') and
							not id:match('^[A-Q]%d%d%d%d%.%d+$') then
								return false
				end
				return id
end
function p.agsaLink( id, label )
				--P6804's format regex: [1-9]\d* (e.g. 3625)
				if not id:match( '^[1-9]%d*$' ) then
								return false
				end
				return '[https://www.agsa.sa.gov.au/collection-publications/collection/creators/_/'..id..'/ '..(label or 'Sul da Austrália')..']'
end
function p.ARLHSLink(id,label)
				--P2980's format regex: [A-Z]{3}\d{3,4}[A-Z]?| e.g. LAT023
				if not id:match('^[A-Z][A-Z][A-Z]%d%d%d%d?[A-Z]?$') then
								return false
				end
				return '[http://wlol.arlhs.com/lighthouse/'..id..'.html '..(label or 'ARLHS')..']'
end
function p.autoresuyLink( id, label )
				--P2558's format regex: [1-9]\d{0,4} (e.g. 12345)
				if not id:match( '^[1-9]%d?%d?%d?%d?$' ) then
								return false
				end
				return '[https://autores.uy/autor/'..id..' '..(label or 'Uruguai')..']'
end
function p.awrLink( id, label )
				--P4186's format regex: (([A-Z]{3}\d{4})|([A-Z]{2}\d{5}))[a-z] (e.g. PR00768b)
				if not id:match( '^[A-Z][A-Z][A-Z]%d%d%d%d[a-z]$' ) and
							not id:match( '^[A-Z][A-Z]%d%d%d%d%d[a-z]$' ) then
								return false
				end
				return '[http://www.womenaustralia.info/biogs/'..id..'.htm '..(label or 'Australian Women\'s Register')..']'
end
function p.bibsysLink( id, label )
				--P1015's format regex: [1-9]\d* or [1-9](\d{0,8}|\d{12}) (e.g. 1234567890123)
				--TODO: follow up @ [[d:Property talk:P1015#Discrepancy between the 2 regex constraints]] or escalate/investigate
				if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) and
							not id:match( '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d$' ) then
								return false
				end
				return '[https://authority.bibsys.no/authority/rest/authorities/html/'..id..' '..(label or 'Noruega')..']'
end
function p.bildLink( id, label )
				--P2092's format regex: \d+ (e.g. 1)
				if not id:match( '^%d+$' ) then
								return false
				end
				return '[https://www.bildindex.de/document/obj'..id..' '..(label or 'Bildindex (Alemanha)')..']'
end
function p.blbnbLink( id, label )
				--P4619's format regex: \d{9}* (e.g. 001027092)
				if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
								return false
				end
				return '[http://acervo.bn.br/sophia_web/autoridade/detalhe/'..id..' '..(label or 'BLBNB (Brasil)')..']'
end
function p.bncLink( id, label )
				--P1890's format regex: \d{9} (e.g. 123456789)
				if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
								return false
				end
				return '[http://www.bncatalogo.cl/F?func=direct&local_base=red10&doc_number='..id..' '..(label or 'Chile')..']'
end
function p.bneLink( id, label )
				--P950's format regex: (XX|FF|a)\d{4,7}|(bima|bimo|bica|bis[eo]|bivi|Mise|Mimo|Mima)\d{10} (e.g. XX1234567)
				if not id:match( '^[XF][XF]%d%d%d%d%d?%d?%d?$' ) and
							not id:match( '^a%d%d%d%d%d?%d?%d?$' ) and
							not id:match( '^bi[mcsv][aoei]%d%d%d%d%d%d%d%d%d%d$' ) and
							not id:match( '^Mi[sm][eoa]%d%d%d%d%d%d%d%d%d%d$' ) then
								return false
				end
				return '[http://catalogo.bne.es/uhtbin/authoritybrowse.cgi?action=display&authority_id='..id..' '..(label or 'Espanha')..']' --no https as of 9/2019
end
function p.bnfLink( id, label )
				--P268's format regex: \d{8}[0-9bcdfghjkmnpqrstvwxz] (e.g. 123456789)
				if not id:match( '^c?b?%d%d%d%d%d%d%d%d[0-9bcdfghjkmnpqrstvwxz]$' ) then
								return false
				end
				--Add cb prefix if it has been removed
				if not id:match( '^cb.+$' ) then
								id = 'cb'..id
				end
				return '[https://catalogue.bnf.fr/ark:/12148/'..id..' '..(label or 'França')..'] [https://data.bnf.fr/ark:/12148/'..id..' (dados)]'
end
function p.botanistLink( id, label )
				--P428's format regex: ('t )?(d')?(de )?(la )?(van (der )?)?(Ma?c)?(De)?(Di)?\p{Lu}?C?['\p{Ll}]*([-'. ]*(van )?(y )?(d[ae][nr]?[- ])?(Ma?c)?[\p{Lu}bht]?C?['\p{Ll}]*)*\.? ?f?\.? (e.g. L.)
				--not easily/meaningfully implementable in Lua's regex since "(this)?" is not allowed...
				if not mw.ustring.match( id, "^[%u%l%d%. '-]+$" ) then --better than nothing
								return false
				end
				id = id:gsub(' +', '%%20')
				return '[https://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation='..id..' '..(label or 'Índice Internacional de Nomes de Plantas')..']'
end
function p.bndLink( id, label )
				--P5691's format regex: \d{5} (e.g. 22954)
				if not id:match( '^%d%d%d%d%d$' ) then
								return false
				end
				return '[http://purl.pt/'..id..(label or 'BND (Portugal)')..']'
end
function p.bpnLink( id, label )
				--P651's format regex: \d{6,8} (e.g. 00123456)
				if not id:match( '^%d%d%d%d%d%d%d%d$' ) and --original format regex, changed 8/2019 to
							not id:match( '^0?%d%d%d%d%d%d%d$' ) and --allow 1-2 leading 0s, allowed by the website
							not id:match( '^0?0?%d%d%d%d%d%d$' ) then
								return false
				end
				return '[http://www.biografischportaal.nl/en/persoon/'..id..' '..(label or 'Países Baixos')..']' --no https as of 9/2019
end
function p.canticLink( id, label )
				--P1273's format regex: a\d{7}[0-9x] (e.g. a10640745)
				if not id:match( '^a%d%d%d%d%d%d%d[%dx]$' ) then
								return false
				end
				return '[http://cantic.bnc.cat/registres/CUCId/'..id..' '..(label or 'Catalunha')..']' --no https as of 10/2019
end
function p.ccgLink( id, label )
				--P3920's format regex: ([NAIP])?[1-9]\d*(\.\d+)? (e.g. A1761)
				if not id:match( '^[NAIP]?[1-9]%d*$' ) and
							not id:match( '^[NAIP]?[1-9]%d*%.%d+$' ) then
								return false
				end
				return id
end
function p.ciniiLink( id, label )
				--P271's format regex: DA\d{7}[\dX] (e.g. DA12345678)
				if not id:match( '^DA%d%d%d%d%d%d%d[%dX]$' ) then
								return false
				end
				return '[https://ci.nii.ac.jp/author/'..id..'?l=en '..(label or 'CiNii (Japão)')..']'
end
function p.cwgcLink( id, label )
				--P1908's format regex: [1-9]\d* (e.g. 75228351)
				if not id:match( '^[1-9]%d*$' ) then
								return false
				end
				return '[https://www.cwgc.org/find-war-dead/casualty/'..id..'/ '..(label or 'Commonwealth War Graves Commission')..']'
end
function p.emuLink( id, label )
				--P4613's format regex: \d{1,6} (e.g. 15409 (or 015409))
				if not id:match( '^%d%d?%d?%d?%d?%d?$' ) then
								return false
				end
				return '[http://esu.com.ua/search_articles.php?id='..id..' '..(label or 'Ucrânia')..']'
end
function p.daaoLink( id, label )
				--P1707's format regex: [a-z\-]+\d* (e.g. rolf-harris)
				if not id:match( '^[a-z%-]+%d*$' ) then
								return false
				end
				return '[https://www.daao.org.au/bio/'..id..' '..(label or 'Australian Artists')..']'
end
function p.dblpLink( id, label )
				--P2456's format regex: \d{2,3} /\d+(-\d+)?|[a-z] /[a-zA-Z][0-9A-Za-z]*(-\d+)? (e.g. 123/123)
				if not id:match( '^%d%d%d?/%d+$' ) and
							not id:match( '^%d%d%d?/%d+%-%d+$' ) and
							not id:match( '^[a-z]/[a-zA-Z][0-9A-Za-z]*$' ) and
							not id:match( '^[a-z]/[a-zA-Z][0-9A-Za-z]*%-%d+$' ) then
								return false
				end
				return '[https://dblp.org/pid/'..id..' '..(label or 'DBLP (ciência da computação)')..']'
end
function p.dibLink( id, label )
				--P6829's format regex: a\d{4}\d?(-[A-D])? (e.g. a1953)
				if not id:match( '^a%d%d%d%d%d?%-?[A-D]?$' ) then
								return false
				end
				return '[https://dib.cambridge.org/viewReadPage.do?articleId='..id..' '..(label or 'Irlanda')..']'
end
function p.dsiLink( id, label )
				--P2349's format regex: [1-9]\d* (e.g. 1538)
				if not id:match( '^[1-9]%d*$' ) then
								return false
				end
				return '[http://www.uni-stuttgart.de/hi/gnt/dsi2/index.php?table_name=dsi&function=details&where_field=id&where_value='..id..' '..(label or 'Ilustração técnica')..']'
end
function p.fastLink( id, label )
				--P2163's format regex: [1-9]\d{0,7} (e.g. 1916996)
				if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?$' ) then
								return false
				end
				return '[http://id.worldcat.org/fast/'..id..'/ '..(label or 'Faceted Application of Subject Terminology')..']'
end
function p.fnzaLink( id, label )
				--P6792's format regex: [1-9]\d* (e.g. 9785)
				if not id:match( '^[1-9]%d*$' ) then
								return false
				end
				return '[https://findnzartists.org.nz/artist/'..id..'/ '..(label or 'New Zealand Artists')..']'
end
function p.gndLink( id, label )
				--P227's format regex: 1[012]?\d{7}[0-9X]|[47]\d{6}-\d|[1-9]\d{0,7}-[0-9X]|3\d{7}[0-9X] (e.g. 4079154-3)
				if not id:match( '^1[012]?%d%d%d%d%d%d%d[0-9X]$' ) and
							not id:match( '^[47]%d%d%d%d%d%d%-%d$' ) and
							not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%-[0-9X]$' ) and
							not id:match( '^3%d%d%d%d%d%d%d[0-9X]$' ) then
								return false
				end
				return '[https://d-nb.info/gnd/'..id..' '..(label or 'Gemeinsame Normdatei (Alemanha)')..']'
end
function p.googleLink( id, label )
				--P1960's format regex: [-_0-9A-Za-z]{12} (e.g. CUO0vDcAAAAJ)
				if not id:match( '^[%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u][%-_%d%l%u]$' ) then
								return false
				end
				return '[https://scholar.google.com/citations?user='..id..' '..(label or 'Google Scholar')..']'
end
function p.hdsLink( id, label )
				--P902's format regex: \d{6} (e.g. 050123)
				if not id:match( '^%d%d%d%d%d%d$' ) then
								return false
				end
				return '[https://hls-dhs-dss.ch/fr/articles/'..id..' '..(label or 'Dicionário Histórico da Suíça')..']'
end
function p.iaafLink( id, label )
				--P1146's format regex: [0-9][0-9]* (e.g. 012)
				if not id:match( '^%d+$' ) then
								return false
				end
				return '[https://www.iaaf.org/athletes/_/'..id..' '..(label or 'World Athletics')..']'
end
function p.iccuLink( id, label )
				--P396's format regex: IT\\ICCU\\(\d{10}|\D\D[\D\d]\D\\\d{6}) (e.g. IT\ICCU\CFIV\000163)
				if not id:match( '^IT\\ICCU\\%d%d%d%d%d%d%d%d%d%d$' ) and
							not id:match( '^IT\\ICCU\\%u%u[%u%d]%u\\%d%d%d%d%d%d$' ) then --legacy: %u used here instead of %D (but the faulty ID cat is empty, out of ~12k uses)
								return false
				end
				return '[https://opac.sbn.it/opacsbn/opac/iccu/scheda_authority.jsp?bid='..id..' '..(label or 'Itália')..']'
end
function p.iciaLink( id, label )
				--P1736's format regex: \d+ (e.g. 1)
				if not id:match( '^%d+$' ) then
								return false
				end
				return '[https://www.imj.org.il/artcenter/newsite/en/?artist='..id..' '..(label or 'ICIA (Israel)')..']'
end
function p.ieuLink( id, label )
				--P9070's format regex: [A-Z]\\[A-Z]\\[A-Za-z0-9]+ (e.g. K\Y\Kyiv)
				if not id:match( '^[A-Z]\\[A-Z]\\%w+$' ) then
								return false
				end
				return '[http://www.encyclopediaofukraine.com/display.asp?linkpath=pages\\'..id..' '..(label or 'Internet Encyclopedia of Ukraine')..']'
end
function p.itauLink( id, label )
				--P4399's format regex: (pessoa|grupo|obra|evento|instituicao|termo)\d+\/[a-z][\-a-z]* (e.g. 1743787)
				if not id:match( '^(pessoa|grupo|obra|evento|instituicao|termo)\d+\/[a-z][\-a-z]*$' ) then
								return false
				end
				return '[https://enciclopedia.itaucultural.org.br/'..id..' '..(label or 'Itáu cultural')..']'
end
function p.isniLink( id, label )
				id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145
				if not id then
								return false
				end
				return '[https://isni.org/isni/'..id..' '..(label or 'ISNI')..']'
end
function p.jocondeLink( id, label )
				--P347's format regex: [\-0-9A-Za-z]{11} (e.g. 12345678901)
				local regex = '^'..string.rep('[%-0-9A-Za-z]', 11)..'$'
				if not id:match( regex ) then
								return false
				end
				return '[https://www.pop.culture.gouv.fr/notice/joconde/'..id..' '..(label or 'Joconde (França)')..']'
end
function p.kulturnavLink( id, label )
				--P1248's format regex: [0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
				if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
								return false
				end
				return '[http://kulturnav.org/'..id..' '..(label or 'KulturNav (Noruega)')..']' --no https as of 9/2019
end
function p.lccnLink( id, label )
				local parts = p.splitLccn( id ) --e.g. n78039510
				if not parts then
								return false
				end
				local lccnType = parts[1] ~= 'sh' and 'names' or 'subjects'
				id = parts[1] .. parts[2] .. p.append( parts[3], '0', 6 )
				return '[https://id.loc.gov/authorities/'..lccnType..'/'..id..' '..(label or 'Estados Unidos')..']'
end
function p.lirLink( id, label )
				--P886's format regex: \d+ (e.g. 1)
				if not id:match( '^%d+$' ) then
								return false
				end
				return '[http://www.e-lir.ch/e-LIR___Lexicon.'..id..'.450.0.html '..(label or 'Lexicon Istoric Retic (Suíça)')..']' --no https as of 9/2019
end
function p.lnbLink( id, label )
				--P1368's format regex: \d{9} (e.g. 123456789)
				if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
								return false
				end
				return '[https://kopkatalogs.lv/F?func=direct&local_base=lnc10&doc_number='..id..'&P_CON_LNG=ENG '..(label or 'Letónia')..']'
end
function p.leonoreLink( id, label )
				--P640's format regex: LH//\d{1,4}/\d{1,3}|19800035/\d{1,4}/\d{1,5}(Bis|Ter)?|C/0/\d{1,2} (e.g. LH//2064/18)
				if not id:match( '^LH//%d%d?%d?%d?/%d%d?%d?$' ) and               --IDs from      LH//1/1 to        LH//2794/54 (legionaries)
							not id:match( '^19800035/%d%d?%d?%d?/%d%d?%d?%d?%d?$' ) and    --IDs from 19800035/1/1 to 19800035/385/51670 (legionnaires who died 1954-1977 & some who died < 1954)
							not id:match( '^19800035/%d%d?%d?%d?/%d%d?%d?%d?%d?Bis$' ) and --IDs from ?
							not id:match( '^19800035/%d%d?%d?%d?/%d%d?%d?%d?%d?Ter$' ) and --IDs from ?
							not id:match( '^C/0/%d%d?$' ) then                             --IDs from        C/0/1 to             C/0/84 (84 famous legionaries)
								return false
				end
				return '[http://www.culture.gouv.fr/public/mistral/leonore_fr?ACTION=CHERCHER&FIELD_1=COTE&VALUE_1='..id..' '..(label or 'Léonore (França)')..']' --no https as of 9/2019
end
function p.mbaLink( id, label )
				--P434's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
				if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
								return false
				end
				local url = 'https://musicbrainz.org/artist/'..id
				if label then
								return '['..url..' '..label..']'--..cat   
				else
								return '[[MBA (identificador)|MusicBrainz]] ['..url..' artist]'
				end
end
function p.mbareaLink( id, label )
				--P982's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
				if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
								return false
				end
				local url = 'https://musicbrainz.org/area/'..id
				if label then
								return '['..url..' '..label..']'   
				else
								return '[[MBAREA (identificador)|MusicBrainz]] ['..url..' area]'-- ..cat
				end
end
function p.mbiLink( id, label )
				--P1330's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
				if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
								return false
				end
				local url = 'https://musicbrainz.org/instrument/'..id
				if label then
								return '['..url..' '..label..']'--..cat   
				else
								return '[[MBI (identificador)|MusicBrainz]] ['..url..' instrument]'
				end
end
function p.mblLink( id, label )
				--P966's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
				if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
								return false
				end
				local url = 'https://musicbrainz.org/label/'..id
				if label then
								return '['..url..' '..label..']'
				else
								return '[[MBL (identificador)|MusicBrainz]] ['..url..' label]'--..cat
				end
end
function p.mbpLink( id, label )
				--P1004's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
				if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
								return false
				end
				local url = 'https://musicbrainz.org/place/'..id
				if label then
								return '['..url..' '..label..']'
				else
								return '[[MBP (identificador)|MusicBrainz]] ['..url..' place]'--..cat
				end
end
function p.mbrgLink( id, label )
				--P436's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
				if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
								return false
				end
				local url = 'https://musicbrainz.org/release-group/'..id
				if label then
								return '['..url..' '..label..']'   
				else
								return '[[MBRG (identificador)|MusicBrainz]] ['..url..' release group]'--..cat
				end
end
function p.mbsLink( id, label )
				--P1407's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
				if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
								return false
				end
				local url = 'https://musicbrainz.org/series/'..id
				if label then
								return '['..url..' '..label..']'   
				else
								return '[[MBS (identificador)|MusicBrainz]] ['..url..' series]'--..cat
				end
end
function p.mbwLink( id, label )
				--P435's format regex: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
				if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
								return false
				end
				
				local url = 'https://musicbrainz.org/work/'..id
				if label then
								return '['..url..' '..label..']'
				else
								return '[[MBW (identificador)|MusicBrainz]] ['..url..' work]'--..cat
				end
end
function p.mgpLink( id, label )
				--P549's format regex: \d{1,6} (e.g. 123456)
				if not id:match( '^%d%d?%d?%d?%d?%d?$' ) then
								return false
				end
				return '[https://genealogy.math.ndsu.nodak.edu/id.php?id='..id..' '..(label or 'Mathematics Genealogy Project')..']'
end
function p.naraLink( id, label )
				--P1225's format regex: ^([1-9]\d{0,8})$ (e.g. 123456789)
				if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
								return false
				end
				return '[https://catalog.archives.gov/id/'..id..' '..(label or 'National Archives (EUA)')..']'
end
function p.nclLink( id, label )
				--P1048's format regex: \d+ (e.g. 1081436)
				if not id:match( '^%d+$' ) then
								return false
				end
				return '[http://aleweb.ncl.edu.tw/F/?func=accref&acc_sequence='..id..'&CON_LNG=ENG '..(label or 'Taiwan')..']' --no https as of 9/2019
end
function p.ndlLink( id, label )
				--P349's format regex: 0?\d{8} (e.g. 012345678)
				if not id:match( '^0?%d%d%d%d%d%d%d%d$' ) then
								return false
				end
				return '[https://id.ndl.go.jp/auth/ndlna/'..id..' '..(label or 'Japão')..']'
end
function p.ngaLink(id,label)
				--P3563's format rgex: 11[0-6]-\d+(\.\d+)? (e.g. 114-7721.2)
				if not id:match('^11[0-6]%-%d+%.?%d*$') then
								return false
				end
				return '[https://wikidata-externalid-url.toolforge.org/?url=https%3A%2F%2Fmsi.nga.mil%2FqueryResults%3Fpublications%2Fngalol%2Flights-buoys%3Fvolume%3D%251%26featureNumber%3D%252%26includeRemovals%3Dfalse%26output%3Dhtml&exp=(%5Cd%7B3%7D)-(.*)&id='..id..' '..(label or 'NGA')..']'
end
function p.ngvLink( id, label )
				--P2041's format regex: \d+ (e.g. 12354)
				if not id:match( '^%d+$' ) then
								return false
				end
				return '[https://www.ngv.vic.gov.au/explore/collection/artist/'..id..'/ '..(label or 'Victoria')..']'
end
function p.nkcLink( id, label )
				--P691's format regex: [a-z]{2,4}[0-9]{2,14} (e.g. abcd12345678901234)
				if not id:match( '^[a-z][a-z][a-z]?[a-z]?%d%d%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
								return false
				end
				return '[https://aleph.nkp.cz/F/?func=find-c&local_base=aut&ccl_term=ica='..id..'&CON_LNG=ENG '..(label or 'Chéquia')..']'
end
function p.nlaLink( id, label )
				--P409's format regex: [1-9][0-9]{0,11} (e.g. 123456789012)
				if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
								return false
				end
				return '[https://nla.gov.au/anbd.aut-an'..id..' '..(label or 'Austrália')..']'
end
function p.nlgLink( id, label )
				--P3348's format regex: [1-9]\d* (e.g. 1)
				if not id:match( '^[1-9]%d*$' ) then
								return false
				end
				return '[https://data.nlg.gr/resource/authority/record'..id..' '..(label or 'Grécia')..']'
end
function p.nliLink( id, label )
				--P949's format regex: \d{9} (e.g. 123456789)
				if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
								return false
				end
				return '[http://uli.nli.org.il/F/?func=direct&doc_number='..id..'&local_base=nlx10'..' '..(label or 'Israel')..']'
end
function p.nlkLink( id, label )
				--P5034's format regex: KA.(19|20).{7} (e.g. KAC201501465)
				if not id:match( '^KA.19.......$' ) and
							not id:match( '^KA.20.......$' ) then
								return false
				end
				return '[https://librarian.nl.go.kr/LI/contents/L20101000000.do?id='..id..' '..(label or 'Coreia')..']'
end
function p.nlpLink( id, label )
				--P1695's format regex: 9810[0-9]\d* or A[0-9]{7}[0-9X] (e.g. 9810123456789012345 or A10414836)
				if not id:match( '^9810%d+$' ) and
							not id:match( '^A%d%d%d%d%d%d%d[%dX]$' ) then
								return false
				end
				return '[https://tools.wmflabs.org/wikidata-externalid-url?p=1695&id='..id..' '..(label or 'Polónia')..']'
end
function p.nlrLink( id, label )
				--P1003's format regex: \d{9} (e.g. 123456789)
				if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
								return false
				end
				return '[http://aleph.bibnat.ro:8991/F/?func=direct&local_base=NLR10&doc_number='..id..' '..(label or 'Romênia')..']'
end
function p.nskLink( id, label )
				--P1375's format regex: \d{9} (e.g. 123456789)
				if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
								return false
				end
				return '[http://katalog.nsk.hr/F/?func=direct&doc_number='..id..'&local_base=nsk10 '..(label or 'Croácia')..']' --no https as of 9/2019
end
function p.ntaLink( id, label )
				--P1006's format regex: \d{8}[\dX] (e.g. 12345678X)
				if not id:match( '^%d%d%d%d%d%d%d%d[%dX]$' ) then
								return false
				end
				return '[http://data.bibliotheken.nl/id/thes/p'..id..' '..(label or 'Países Baixos')..']'
end
function p.orcidLink( id, label )
				id = p.validateIsni( id ) --e.g. 0000-0002-7398-5483
				if not id then
								return false
				end
				id = id:sub( 1, 4 )..'-'..id:sub( 5, 8 )..'-'..id:sub( 9, 12 )..'-'..id:sub( 13, 16 )
				return '[https://orcid.org/'..id..' '..(label or 'ORCID')..']'
end
function p.picLink( id, label )
				--P2750's format regex: [1-9]\d* (e.g. 1)
				if not id:match( '^[1-9]%d*$' ) then
								return false
				end
				return '[https://pic.nypl.org/constituents/'..id..' '..(label or 'Photographers\' Identities')..']'
end
function p.plwabnLink( id, label )
				--P7293's format regex: 981[0-9]{8}05606 (e.g. 9810696457305606)
				if not id:match( '^981%d%d%d%d%d%d%d%d05606*$' ) then
								return false
				end
				return '[http://mak.bn.org.pl/cgi-bin/KHW/makwww.exe?BM=1&NU=1&IM=4&WI='..id..' '..(label or 'Polónia')..']'
end
function p.publonsLink( id, label )
				--P3829's format regex: \d+ (e.g. 654601)
				if not id:match( '^%d+$' ) then
								return false
				end
				return '[https://publons.com/author/'..id..'/ '..(label or 'Publons (investigadores)')..']'
end
function p.PWNLink( id, label )
				--P7305's format regex: [1-9]\d+ (e.g. 3886065)
				if not id:match( '^[1-9]%d+$' ) then
								return false
				end
				return '[https://encyklopedia.pwn.pl/haslo/;'..id..'.html '..(label or 'Online PWN')..']'
end
function p.ridLink( id, label )
				--P1053's format regex: [A-Z]{1,3}-\d{4}-(19|20)\d\d (e.g. AAS-5150-2020)
				if not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-19%d%d$' ) and
							not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-20%d%d$' ) then
								return false
				end
				return '[https://www.researcherid.com/rid/'..id..' '..(label or 'ResearcherID')..']'
end
function p.rismLink( id, label )
				--P5504's format regex: (pe|ks)?\[1-9]d* (e.g. pe30006410)
				if not id:match( '^pe[1-9]%d*$' ) and --99% start with 'pe'
							not id:match( '^ks[1-9]%d*$' ) and
							not id:match( '^[1-9]%d*$' ) then
								return false
				end
				return '[https://opac.rism.info/search?id='..id..' '..(label or 'RISM (França)')..']'
end
function p.reroLink( id, label )
				--P3065's format regex: 0[1-2]-[A-Z0-9]{1,10} (e.g. 02-A012345678)
				if not id:match( '^0[1-2]%-[A-Z%d][A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?$' ) then
								return false
				end
				return '[http://data.rero.ch/'..id..' '..(label or 'RERO (Suíça')..']'
end
function p.rkdartistsLink( id, label )
				--P650's format regex: [1-9]\d{0,5} (e.g. 123456)
				if not id:match( '^[1-9]%d?%d?%d?%d?%d?$' ) then
								return false
				end
				return '[https://rkd.nl/en/explore/artists/'..id..' '..(label or 'RKD Artists (Países Baixos)')..']'
end
function p.rkdidLink( id, label )
				--P350's format regex: [1-9]\d{0,5} (e.g. 123456)
				if not id:match( '^[1-9]%d?%d?%d?%d?%d?$' ) then
								return false
				end
				return '[https://rkd.nl/nl/explore/images/'..id..' '..(label or 'RKD ID (Países Baixos)')..']'
end
function p.rslLink( id, label )
				--P947's format regex: \d{1,9} (e.g. 123456789)
				if not id:match( '^%d%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
								return false
				end
				return '[http://aleph.rsl.ru/F?func=find-b&find_code=SYS&adjacent=Y&local_base=RSL11&request='..id..'&CON_LNG=ENG '..(label or 'Rússia')..']' --no https as of 9/2019
end
function p.scopusLink( id, label )
				--P1153's format regex: [1-9]\d{9,10} (e.g. 35247902700)
				if not id:match( '^[1-9]%d%d%d%d%d%d%d%d%d%d?$' ) then
								return false
				end
				return '[https://www.scopus.com/authid/detail.uri?authorId='..id..' '..(label or 'autor Scopus')..']'
end
function p.selibrLink( id, label )
				--P906's format regex: [1-9]\d{4,5} (e.g. 123456)
				if not id:match( '^[1-9]%d%d%d%d%d?$' ) then
								return false
				end
				return '[https://libris.kb.se/auth/'..id..' '..(label or 'Suécia')..']'
end
function p.sikartLink( id, label )
				--P781's format regex: \d{7,9} (e.g. 123456789)
				if not id:match( '^%d%d%d%d%d%d%d%d?%d?$' ) then
								return false
				end
				return '[http://www.sikart.ch/KuenstlerInnen.aspx?id='..id..'&lng=en '..(label or 'SIKART (Suíça)')..']' --no https as of 9/2019
end
function p.snacLink( id, label )
				--P3430's format regex: \d*[A-Za-z][0-9A-Za-z]* (e.g. A)
				if not id:match( '^%d*[A-Za-z][0-9A-Za-z]*$' ) then
								return false
				end
				return '[https://snaccooperative.org/ark:/99166/'..id..' '..(label or 'Social Networks and Archival Context')..']'
end
function p.sudocLink( id, label )
				--P269's format regex: (\d{8}[\dX]|) (e.g. 026927608)
				if not id:match( '^%d%d%d%d%d%d%d%d[%dxX]$' ) then --legacy: allow lowercase 'x'
								return false
				end
				return '[https://www.idref.fr/'..id..' '..(label or 'SUDOC (França)')..']'
end
function p.ta98Link( id, label )
				--P1323's format regex: A\d{2}\.\d\.\d{2}\.\d{3}[FM]? (e.g. A12.3.45.678)
				if not id:match( '^A%d%d%.%d%.%d%d%.%d%d%d[FM]?$' ) then
								return false
				end
				local longurl = '[http://tools.wmflabs.org/wikidata-externalid-url/?p=1323&url_prefix=https:%2F%2Fwww.unifr.ch%2Fifaa%2FPublic%2FEntryPage%2FTA98%20Tree%2FEntity%20TA98%20EN%2F&url_suffix=%20Entity%20TA98%20EN.htm&id='
				return longurl..id..' '..(label or 'Terminologia Anatomica')..']'
end
function p.tdviaLink( id, label )
				--P7314's format regex: [a-z/-]+] (e.g. barkan-omer-lutfi)
				if not id:match( '^[a-z/-]+$' ) then
								return false
				end
				return '[https://islamansiklopedisi.org.tr/'..id..' '..(label or 'Enciclopédia do Islão')..']'
end
function p.tepapaLink( id, label )
				--P3544's format regex: \d+ (e.g. 1)
				if not id:match( '^%d+$' ) then
								return false
				end
				return '[https://collections.tepapa.govt.nz/agent/'..id..' '..(label or 'Te Papa (Nova Zelândia)')..']'
end
function p.tlsLink( id, label )
				id = id:gsub(' +', '_')
				--P1362's format regex: \p{Lu}[\p{L}\d_',\.\-\(\)\*/–]{3,69} (e.g. Abcd)
				local class = "[%a%d_',%.%-%(%)%*/–]"
				local idlen = #id
				if idlen < 4 or idlen > 70 then
								return false
				end
				local regex = '^%u'..string.rep(class, idlen - 1)..'$'
				if not mw.ustring.match( id, regex ) then
								return false
				end
				return '[http://tls.theaterwissenschaft.ch/wiki/'..id..' '..(label or 'Theaterlexikon (Suíça)')..']' --no https as of 9/2019
end
function p.troveLink( id, label )
				--P1315's format regex: [1-9]\d{5,7} (e.g. 12345678)
				if not id:match( '^[1-9]%d%d%d%d%d%d?%d?$' ) then
								return false
				end
				return '[https://trove.nla.gov.au/people/'..id..' '..(label or 'Trove (Austrália)')..']'
end
function p.ukparlLink( id, label )
				--P6213's format regex: [a-zA-Z\d]{8} (e.g. AQUupyiR)
				if not id:match( '^[a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d]$' ) then
								return false
				end
				return '[https://id.parliament.uk/'..id..' '..(label or 'Parlamento do RU')..']'
end
function p.ulanLink( id, label )
				--P245's format regex: 500\d{6} (e.g. 500123456)
				if not id:match( '^500%d%d%d%d%d%d$' ) then
								return false
				end
				return '[https://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid='..id..' '..(label or 'Nomes de Artistas (Getty)')..']'
end
function p.uscgLink( id, label )
				--P3723's format regex: [1-7]-\d{1,5}(.[1-9])? (e.g. 6-0695)
				if not id:match( '^[1-7]%-%d%d?%d?%d?%d?$' ) and
							not id:match( '^[1-7]%-%d%d?%d?%d?%d?%.%d*[1-9]$' ) then
								return false
				end
				return id
end
function p.uscongressLink( id, label )
				--P1157's format regex: [A-Z]00[01]\d{3} (e.g. A000123)
				if not id:match( '^[A-Z]00[01]%d%d%d$' ) then
								return false
				end
				return '[http://bioguide.congress.gov/scripts/biodisplay.pl?index='..id..' '..(label or 'Congresso dos EUA')..']' --no https as of 9/2019
end
function p.vcbaLink( id, label )
				--P8034's format regex: \d{3}\/[1-9]\d{0,5} (e.g. 494/9793)
				if not id:match( '^%d%d%d\/[1-9]%d?%d?%d?%d?%d?$' ) then
								return false
				end
				id = id:gsub('\/', '_')
				return '[https://opac.vatlib.it/auth/detail/'..id..' '..(label or 'Vaticano')..']'
end
function p.viafLink( id, label )
				--P214's format regex: [1-9]\d(\d{0,7}|\d{17,20}) (e.g. 123456789, 1234567890123456789012)
				if not id:match( '^[1-9]%d%d?%d?%d?%d?%d?%d?%d?$' ) and
							not id:match( '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d?%d?%d?$' ) then
								return false
				end
				-- If the "VIAF" entry at [[:m:Interwiki map]] would resolve to "https://viaf.org/viaf/$1" (rather than "http://viaf.org/viaf/$1", as it currently still does),
				-- then the code below could change from '[https://viaf.org/viaf/'..id..' '..id..']' to '[[:VIAF:'..id..'|'..id..']]'.
				return '[https://viaf.org/viaf/'..id..' '..(label or 'VIAF')..']'
end
function p.worldcatidLink( id, label )
				--P7859's format regex: viaf-\d+|lccn-n[a-z]?[0-9\-]+|n[pc]-.+ (e.g. viaf-100181709, lccn-n78-95332, np-verbeck,%20william$1861)
				if not id:match( '^viaf%-%d+$' ) and
							not id:match( '^lccn%-n[a-z]?[0-9%-]+$' ) and
							not id:match( '^n[pc]%-.+$' ) then
								return false
				end
				return '[https://www.worldcat.org/identities/'..mw.uri.encode(id, 'PATH')..'/ '..(label or 'WorldCat')..']'
end
--[[=========================== Helper functions =============================]]
function p.append(str, c, length)
				while str:len() < length do
								str = c..str
				end
				return str
end
--Returns the ISNI check digit isni must be a string where the 15 first elements are digits, e.g. 0000000066534145
function p.getIsniCheckDigit( isni )
				local total = 0
				for i = 1, 15 do
								local digit = isni:byte( i ) - 48 --Get integer value
								total = (total + digit) * 2
				end
				local remainder = total % 11
				local result = (12 - remainder) % 11
				if result == 10 then
								return 'X'
				end
				return tostring( result )
end
--Validate ISNI (and ORCID) and retuns it as a 16 characters string or returns false if it's invalid
--See http://support.orcid.org/knowledgebase/articles/116780-structure-of-the-orcid-identifier
function p.validateIsni( id )
				--P213 (ISNI) format regex: [0-9]{4} [0-9]{4} [0-9]{4} [0-9]{3}[0-9X] (e.g. 0000-0000-6653-4145)
				--P496 (ORCID) format regex: 0000-000(1-[5-9]|2-[0-9]|3-[0-4])\d{3}-\d{3}[\dX] (e.g. 0000-0002-7398-5483)
				id = id:gsub( '[ %-]', '' ):upper()
				if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d[%dX]$' ) then
								return false
				end
				if p.getIsniCheckDigit( id ) ~= string.char( id:byte( 16 ) ) then
								return false
				end
				return id
end
function p.splitLccn( id )
				--P244's format regex: (n|nb|nr|no|ns|sh)([4-9][0-9]|00|20[0-1][0-9])[0-9]{6} (e.g. n78039510)
				if id:match( '^%l%l?%l?%d%d%d%d%d%d%d%d%d?%d?$' ) then
								id = id:gsub( '^(%l+)(%d+)(%d%d%d%d%d%d)$', '%1/%2/%3' )
				end
				if id:match( '^%l%l?%l?/%d%d%d?%d?/%d+$' ) then
								return mw.text.split( id, '/' )
				end
				return false
end
--[[==========================================================================]]
--[[                    Wikidata & documentation functions                    ]]
--[[==========================================================================]]
function p.getIdsFromWikidata( itemId, property )
				local ids = {}
				local statements = mw.wikibase.getBestStatements( itemId, property )
				if statements then
								for _, statement in ipairs( statements ) do
												if statement.mainsnak.datavalue then
																table.insert( ids, statement.mainsnak.datavalue.value )
												end
								end
				end
				return ids
end
--[[==========================================================================]]
--[[                              Configuration                               ]]
--[[==========================================================================]]
-- Please use "<parameter> (identificador)" redirects rather than linking directly to the target page.
-- This reduces clutter in "What links here" on both the redirect and the target,
-- and improves reverse lookup of articles where a manifestation of each identifier is used.
-- p.conf table basic format: { 'parameter name', propertyId # in Wikidata, formatting/validation function, section, example ID for documentation }
-- p.conf table optional named parameters:
--  link: to override the link in the documentation (defaults to "<parameter> (identifier)")
--  category: to override the ID in category names (defaults to "... with <parameter> identifiers")
--  prefix: to include a prefix (usually a wikilink explaining what the identifier is) before the external link itself
p.conf = {
				{ 'GeoNames', 1566, 'p.getIdsFromWikidata' ,'Lugares' },
				{ 'Booking.com', 3607, 'p.getIdsFromWikidata', 'Lugares' },
				{ 'GeoNames', 1566, 'p.getIdsFromWikidata' ,'Lugares' },
				{ 'MusicBrainzArea', 982, 'p.getIdsFromWikidata','Lugares' },
				{ 'AAG', 3372, p.aagLink, 'Galerias de arte e museus', '1' },
				{ 'ACM-DL', 864, p.acmLink, 'Bases de dados científicas', '12345678901', link = 'ACM DL (identificador)' },
				{ 'ADB', 1907, p.adbLink,'Dicionários bibliográficos', 'barton-sir-edmund-toby-71' },
				{ 'admiralty', 3562, p.admiraltyLink, 'Identificadores de faróis', 'D1204.1', prefix='[[Instituto Hidrográfico do Reino Unido|Admiralty]]'},
				{ 'AGSA', 6804, p.agsaLink, 'Galerias de arte e museus', '3625' },
				{ 'ARLHS', 2980, p.ARLHSLink, 'Identificadores de faróis', 'LAT023'},
				{ 'autores.uy', 2558, p.autoresuyLink, 'Dicionários bibliográficos', '12345' },
				{ 'AWR', 4186, p.awrLink, 'Dicionários bibliográficos', 'PR00768b' },
				{ 'BIBSYS', 1015, p.bibsysLink, 'Bibliotecas nacionais', '1234567890123' },
				{ 'Bildindex', 2092, p.bildLink, 'Institutos de pesquisa de arte', '1' },
				{ 'BLBNB', 4619, p.blbnbLink, 'Bibliotecas nacionais', '001027092'},
				{ 'BNC', 1890, p.bncLink, 'Bibliotecas nacionais', '123456789' },
				{ 'BND', 5691, p.bndLink, 'Bibliotecas nacionais', '22954' },
				{ 'BNE', 950, p.bneLink, 'Bibliotecas nacionais', 'XX1234567' },
				{ 'BNF', 268, p.bnfLink, 'Bibliotecas nacionais', '123456789' },
				{ 'Botanist', 428, p.botanistLink , 'Bases de dados científicas', 'L.' },
				{ 'BPN', 651, p.bpnLink , 'Dicionários bibliográficos', '12345678' },
				{ 'CANTIC', 1273, p.canticLink, 'Bibliotecas nacionais', 'a12345678' },
				{ 'CCG', 3920, p.ccgLink, 'Identificadores de faróis', 'A1761', prefix='[[CCG (identificador)|CCG]]' },
				{ 'CINII', 271, p.ciniiLink, 'Bases de dados científicas', 'DA12345678', link = 'CiNii (identificador)' },
				{ 'CWGC', 1908, p.cwgcLink, 'Outro', '1234567' },
				{ 'DAAO', 1707, p.daaoLink, 'Institutos de pesquisa de arte', 'rolf-harris' },
				{ 'DBLP', 2456, p.dblpLink, 'Bases de dados científicas', '123/123' },
				{ 'DIB',  6829, p.dibLink, 'Dicionários bibliográficos', 'a1234' },
				{ 'DSI', 2349, p.dsiLink, 'Institutos de pesquisa de arte', '1538' },
				{ 'EMU', 4613, p.emuLink, 'Bibliotecas nacionais', '15409' },
				{ 'FAST', 2163, p.fastLink, 'Outro', '1' },
				{ 'FNZA', 6792, p.fnzaLink, 'Institutos de pesquisa de arte', '12' },
				{ 'GND', 227, p.gndLink, 'Geral', '4079154-3' },
				{ 'Google Scholar', 1960, p.googleLink, 'Bases de dados científicas', 'QPdLuj8AAAAJ' },
				{ 'HDS', 902, p.hdsLink, 'Outro', '050123' },
				{ 'IAAF', 1146, p.iaafLink, 'Outro', '123' },
				{ 'ICCU', 396, p.iccuLink, 'Bibliotecas nacionais', 'IT\\ICCU\\CFIV\\000163' }, --formerly SBN
				{ 'ICIA', 1736, p.iciaLink, 'Institutos de pesquisa de arte', '1' },
				{ 'IEU', 9070, p.ieuLink, 'Outro', 'N\\A\\NationalAcademyofArtandArchitecture' },
				{ 'ISNI', 213, p.isniLink, 'Geral', '0000-0000-6653-4145', prefix = '[[ISNI (identificador)|ISNI]]' },
				{ 'ITAU', 4399, p.itauLink, 'Outro', 'pessoa1461/burle-marx'},
				{ 'Joconde', 347, p.jocondeLink, 'Institutos de pesquisa de arte', '12345678901' },
				{ 'KULTURNAV', 1248, p.kulturnavLink, 'Institutos de pesquisa de arte', '12345678-1234-1234-1234-1234567890AB', link = 'KulturNav (identificador)' },
				{ 'LCCN', 244, p.lccnLink, 'Bibliotecas nacionais', 'n78039510' },
				{ 'LIR', 886, p.lirLink, 'Outro', '1' },
				{ 'LNB', 1368, p.lnbLink, 'Bibliotecas nacionais', '123456789' },
				{ 'Léonore', 640, p.leonoreLink, 'Outro', 'LH//1/1', prefix = '[[Léonore (identificador)|Léonore (França)]]' },
				{ 'MBA', 434, p.mbaLink, 'Outro', '12345678-1234-1234-1234-1234567890AB' }, --special cat name
				{ 'MBAREA', 982, p.mbareaLink, 'Outro', '12345678-1234-1234-1234-1234567890AB' }, --special cat name
				{ 'MBI', 1330, p.mbiLink, 'Outro', '12345678-1234-1234-1234-1234567890AB' }, --special cat name
				{ 'MBL', 966, p.mblLink, 'Outro', '12345678-1234-1234-1234-1234567890AB' }, --special cat name
				{ 'MBP', 1004, p.mbpLink, 'Outro', '12345678-1234-1234-1234-1234567890AB' }, --special cat name
				{ 'MBRG', 436, p.mbrgLink, 'Outro', '12345678-1234-1234-1234-1234567890AB' }, --special cat name
				{ 'MBS', 1407, p.mbsLink, 'Outro', '12345678-1234-1234-1234-1234567890AB' }, --special cat name
				{ 'MBW',  435, p.mbwLink, 'Outro', '12345678-1234-1234-1234-1234567890AB' }, --special cat name
				{ 'MGP', 549, p.mgpLink, 'Bases de dados científicas', '123456' },
				{ 'NARA', 1225, p.naraLink, 'Outro', '12345678' },
				{ 'NCL', 1048, p.nclLink, 'Bibliotecas nacionais', '1081436' },
				{ 'NDL', 349, p.ndlLink, 'Bibliotecas nacionais', '012345678' },
				{ 'NGA', 3563, p.ngaLink, 'Identificadores de faróis', '114-5592'},
				{ 'NGV', 2041, p.ngvLink, 'Galerias de arte e museus', '12354' },
				{ 'NKC', 691, p.nkcLink, 'Bibliotecas nacionais', 'abcd12345678901234' },
				{ 'NLA', 409, p.nlaLink, 'Bibliotecas nacionais', '123456789012' },
				{ 'NLG', 3348, p.nlgLink, 'Bibliotecas nacionais', '12345678' },
				{ 'NLI', 949, p.nliLink, 'Bibliotecas nacionais', '123456789' },
				{ 'NLK', 5034, p.nlkLink, 'Bibliotecas nacionais', 'KAB197000000' },
				{ 'NLP', 1695, p.nlpLink, 'Bibliotecas nacionais', '9810123456789012345' },
				{ 'NLR', 1003, p.nlrLink, 'Bibliotecas nacionais', '123456789' },
				{ 'NSK', 1375, p.nskLink, 'Bibliotecas nacionais', '123456789' },
				{ 'NTA', 1006, p.ntaLink, 'Bibliotecas nacionais', '12345678X' },
				{ 'ORCID', 496, p.orcidLink, 'Geral', '0000-0002-7398-5483', prefix = '[[ORCID (identificador)|ORCID]]' },
				{ 'PIC', 2750, p.picLink, 'Institutos de pesquisa de arte', '1' },
				{ 'PLWABN',  7293, p.plwabnLink, 'Bibliotecas nacionais', '9812345678905606' },
				{ 'Publons', 3829, p.publonsLink, 'Bases de dados científicas', '2776255' },
				{ 'PWN', 7305, p.PWNLink, 'Geral', '3878797' },
				{ 'RID', 1053, p.ridLink, 'Bases de dados científicas', 'A-1234-1934' },
				{ 'RISM', 5504, p.rismLink, 'Outro', 'pe1',  prefix = '[[RISM (identificador)|RISM (França)]]' },
				{ 'RERO', 3065, p.reroLink, 'Outro', '02-A012345678', prefix = '[[RERO (identificador)|RERO (Suíça)]]' },
				{ 'RKDartists', 650, p.rkdartistsLink, 'Institutos de pesquisa de arte', '123456' },
				{ 'RKDID', 350, p.rkdidLink, 'Institutos de pesquisa de arte', '123456' },
				{ 'RSL', 947, p.rslLink, 'Bibliotecas nacionais', '123456789' },
				{ 'Scopus', 1153, p.scopusLink, 'Bases de dados científicas', '7005487412' },
				{ 'SELIBR', 906, p.selibrLink, 'Bibliotecas nacionais', '123456' },
				{ 'SIKART', 781, p.sikartLink, 'Institutos de pesquisa de arte', '123456789' },
				{ 'SNAC-ID', 3430, p.snacLink, 'Outro', 'A' },
				{ 'SUDOC', 269, p.sudocLink, 'Outro', '026927608', prefix = '[[SUDOC (identificador)|SUDOC (França)]]' },
				{ 'TA98', 1323, p.ta98Link, 'Bases de dados científicas', 'A12.3.45.678' },
				{ 'TDVİA', 7314, p.tdviaLink, 'Outro', 'asim-b-behdele' },
				{ 'TePapa', 3544, p.tepapaLink, 'Galerias de arte e museus', '1' },
				{ 'TLS',  1362, p.tlsLink, 'Outro', 'Abcd' },
				{ 'Trove', 1315, p.troveLink, 'Outro', '12345678', prefix = '[[Trove (identificador)|Trove (Austrália)]]' }, --formerly NLA-person
				{ 'UKPARL', 6213, p.ukparlLink, 'Outro', 'AQUupyiR' },
				{ 'ULAN', 245, p.ulanLink, 'Institutos de pesquisa de arte', '500123456' },
				{ 'USCG', 3723, p.uscgLink, 'Identificadores de faróis', '6-0695', prefix='[[USCG (identificador)|USCG]]'},
				{ 'USCongress', 1157, p.uscongressLink, 'Outro', 'A000123', link = 'US Congress (identificador)' },
				{ 'VcBA', 8034, p.vcbaLink, 'Bibliotecas nacionais', '494/9793' },
				{ 'VIAF', 214, p.viafLink, 'Geral', '123456789', prefix = '[[VIAF (identificador)|VIAF]]' },
				{ 'WORLDCATID', 7859, p.worldcatidLink, 'Geral', 'lccn-n78-95332', link = 'WorldCat Identities (identificador)' },
}
-- Legitimate aliases to p.conf, for convenience
-- Format: { 'alias', 'parameter name in p.conf' }
p.aliases = {
				{ 'DNB', 'GND' }, --Deutsche Nationalbibliothek -> Gemeinsame Normdatei
				{ 'Leonore', 'Léonore' }, --alias name without diacritics
				{ 'leonore', 'Léonore' }, --lowercase variant without diacritics
				{ 'MusicBrainz', 'MBA' },
				{ 'MusicBrainz artist', 'MBA' },
				{ 'MusicBrainz label', 'MBL' },
				{ 'MusicBrainz release group', 'MBRG' },
				{ 'MusicBrainz work', 'MBW' },
				{ 'SBN', 'ICCU' }, --SBN alias to be deprecated at a later stage
				{ 'TDVIA', 'TDVİA' }, --alias name without diacritics
				{ 'tdvia', 'TDVİA' }, --lowercase variant without diacritics
}
-- Deprecated aliases to p.conf; tracked in [[Category:Articles with deprecated authority control identifiers]]
-- Format: { 'deprecated parameter name', 'replacement parameter name in p.conf' }
p.deprecated = {
				{ 'GKD', 'GND' },
				{ 'PND', 'GND' },
				{ 'RLS', 'RSL' },
				{ 'SWD', 'GND' },
				{ 'NARA-organization', 'NARA' },
				{ 'NARA-person', 'NARA' },
}
--[[==========================================================================]]
--[[                                   Main                                   ]]
--[[==========================================================================]]
function p.authorityControl( frame )
				local resolveEntity = require( 'Module:ResolveEntityId' )
				local parentArgs = frame:getParent().args --WD IDs added here later
				local iParentArgs = 0 --count original/manual parent args only later
				local worldcatCat = ''
				local elementsCat = ''
				local multipleIdCat = ''
				local suppressedIdCat = ''
				local suppressedIdCatArts = ''
				local deprecatedIdCat = ''
				local differentOnWDCat = ''
				local sameOnWDCat = ''
				local stateCat = ''
				
				--redirect aliases to proper parameter names
				for _, a in pairs( p.aliases ) do
								local alias, param = a[1], a[2]
								if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[alias] then
												parentArgs[param] = parentArgs[alias]
								end
				end
				
				--redirect deprecated parameters to proper parameter names, and assign tracking cat
				for _, d in pairs( p.deprecated ) do
								local dep, param = d[1], d[2]
								if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[dep] then
												parentArgs[param] = parentArgs[dep]
												if namespace == 0 then
																deprecatedIdCat = '[[Categoria:!Artigos com identificadores de controle de autoridade obsoletos|'..dep..']]'
												end
								end
				end
				
				--use QID= parameter for testing/example purposes only
				local itemId = nil
				if namespace ~= 0 then
								local qid = parentArgs['qid'] or parentArgs['QID']
								if qid then
												itemId = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '')
												itemId = resolveEntity._id(itemId) --nil if unresolvable
								end
				else
								itemId = mw.wikibase.getEntityIdForCurrentPage()
				end
				
				--Wikidata fallback if available
				if itemId then
								local suppressedIdCount = 0
								local iMatches = 0
								for _, params in ipairs( p.conf ) do
												if params[2] > 0 then
																local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
																if val == nil or val == '' then
																				local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
																				if wikidataIds[1] then
																								if val == '' and (namespace == 0 or testcases) then
																												suppressedIdCount = suppressedIdCount + 1
																												suppressedIdCat = '[[Categoria:!Artigos com identificadores de controle de autoridade suprimidos|'..params[1]..']]'
																								else
																												parentArgs[params[1]] = wikidataIds[1] --add ID from WD
																								end
																				end
																else
																				iParentArgs = iParentArgs + 1
																				local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
																				if wikidataIds[1] and differentOnWDCat == '' then
																								local bMatch = false
																								for _, wd in pairs( wikidataIds ) do
																												if val == wd then
																																iMatches = iMatches + 1
																																bMatch = true
																												end
																								end
																								if bMatch == false then
--                            differentOnWDCat = '[[Category:Pages using authority control with parameters different on Wikidata|'..params[1]..']]'
								end    end    end    end    end
								if iMatches > 0 and iMatches == iParentArgs then
												sameOnWDCat = '[[Categoria:!Artigos com identificadores de controle de autoridade com todos os parâmetros iguais a Wikidata]]'
								end
								if parentArgs['arts'] == 'arts' and suppressedIdCount > 0 then
												if namespace == 0 or testcases then
																local s = 's'
																if suppressedIdCount == 1 then s = '' end
--                local sCat = 'ACArt with '..suppressedIdCount..' suppressed element'..s
--                suppressedIdCatArts = addCat(sCat)
												end
								end
				end
				
				--configure rows
				local rct = 0
				local sectionOrder = {
								'Geral',
								'Bibliotecas nacionais',
								'Galerias de arte e museus',
								'Institutos de pesquisa de arte',
								'Dicionários bibliográficos',
								'Bases de dados científicas',
								'Identificadores de faróis',
								'Outro',
				'identificadores taxonómicos',
				'Cinema',
				'informática',
				'Bases de datos taxonómicas',
				'Identificadores médicos',
				'Identificadores químicos',
				'Identificadores biológicos',
				'Identificadores astronómicos',
				'Lugares',
				'Arquitetura'
				}
				local sections = {
								['Geral'] = {},
								['Bibliotecas nacionais'] = {},
								['Galerias de arte e museus'] = {},
								['Institutos de pesquisa de arte'] = {},
								['Dicionários bibliográficos'] = {},
								['Bases de dados científicas'] = {},
								['Identificadores de faróis'] = {},
								['Outro'] = {},
				['identificadores taxonómicos'] = {},
				['Cinema'] = {},
				['informática'] = {},
				['Bases de datos taxonómicas'] = {},
				['Identificadores médicos'] = {},
				['Identificadores químicos'] = {},
				['Identificadores biológicos'] = {},
				['Identificadores astronómicos'] = {},
				['Lugares'] = {},
				['Arquitetura'] = {},
				}
				--don't show NLP if PLWABN is present, since they both go to the National Library of Poland
				--and the library has deprecated NLP IDs in favor of PLWABN IDs
				if parentArgs.PLWABN or parentArgs.plwabn then
								parentArgs.NLP = ''
								parentArgs.nlp = ''
				end
				for _, params in ipairs( p.conf ) do
								local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
								local tval, tlinks = {}, {} --init tables
								if val and val ~= '' and type(params[3]) == 'function' then
												table.insert( tval, val )
												if params.prefix then
																table.insert( tlinks, params[3]( val, '1' ) )
												else
																table.insert( tlinks, params[3]( val ) )
												end
								end
								--collect other unique vals (IDs) from WD, if present
								if itemId and tval[1] then
												local nextIdVal = 2
												local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )
												for _, v in pairs( wikidataIds ) do
																local bnew = true
																for _, w in pairs( tval ) do
																				if v == w then bnew = false end
																end
																if bnew then
																				table.insert( tval, v )
																				table.insert( tlinks, params[3]( v, tostring(nextIdVal) ) )
																				nextIdVal = nextIdVal + 1
																end
												end
								end
								--assemble
								if tval[1] then
												table.insert( sections[params[4]], p.createRow( params[1], tval, nil, tlinks, true, params.category, params.prefix) )
												rct = rct + 1
--            if tval[2] then
--                multipleIdCat = p.getCatForId( 'multiple' )
--            end
								end
				
				end
				
				--WorldCat-VIAF & WorldCat-LCCN
				local worldcatId = parentArgs['worldcatid'] or parentArgs['WORLDCATID']
				if worldcatId == nil then --if WORLDCATID absent but unsuppressed
								local viafId = parentArgs['viaf'] or parentArgs['VIAF']
								local lccnId = parentArgs['lccn'] or parentArgs['LCCN']
								if viafId and viafId ~= '' and p.viafLink( viafId ) then --VIAF must be present, unsuppressed, & validated
												table.insert( sections['Geral'], p.createRow( 'VIAF', viafId, '[https://www.worldcat.org/identities/containsVIAFID/'..viafId..' WorldCat (via VIAF)]', nil, false ) )
												if namespace == 0 then
																worldcatCat = '[[Categoria:!Artigos com identificadores WorldCat-VIAF]]'
												end
												rct = rct + 1
								elseif lccnId and lccnId ~= '' and p.lccnLink( lccnId ) then --LCCN must be present, unsuppressed, & validated
												local lccnParts = p.splitLccn( lccnId )
												if lccnParts and lccnParts[1] ~= 'sh' then
																local lccnIdFmtd = lccnParts[1]..lccnParts[2]..'-'..lccnParts[3]
																table.insert( sections['Geral'], p.createRow( 'LCCN', lccnId, '[https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' WorldCat (via Library of Congress)]', nil, false ) )
																if namespace == 0 then
																				worldcatCat = '[[Categoria:!Artigos com identificadores WorldCat-LCCN]]'
																end
												end
												rct = rct + 1
								end
				end
				
				--configure Navbox
				local outString = ''
				local extrap = true
				local extra = parentArgs.extralist
				if extra == nil or extra == '' then
								extrap = false
				end
				if rct > 0 or extrap then
								local Navbox = require('Module:Navbox')
								local sectionID = 1
								local args = { pid = 'identifiers' } -- #target the list of identifiers
								if testcases and itemId then args = { pid = 'identifiers', qid = itemId } end --expensive
								local pencil = frame:expandTemplate{ title = 'EditAtWikidata', args = args}
								local navboxArgs = {
												name  = 'Controle de autoridade',
												navboxclass = 'authority-control',
												bodyclass = 'hlist',
												state = parentArgs.state or parentArgs.estado or 'autocollapse',
												navbar = 'off'
								}
								for _, sectName in ipairs(sectionOrder) do
												if #sections[sectName] ~= 0 then
																navboxArgs['group'..sectionID] = sectName
																navboxArgs['list'..sectionID] = table.concat(sections[sectName])
																sectionID = sectionID + 1
												end
								end
								if extrap then
												if parentArgs.extragroup then
																navboxArgs['group'..sectionID] = parentArgs.extragroup
												else
																navboxArgs['group'..sectionID] = 'Adicional'
												end
												navboxArgs['list'..sectionID] = extra
												sectionID = sectionID + 1
								end
								if navboxArgs.list2 then
												navboxArgs.title = '[[Ajuda:Controle de autoridade|Controle de autoridade]]'..pencil
								else
												local sect = navboxArgs.group1
												if sect == 'Geral' or sect == 'Outro' or sect == 'Adicional' then
																-- Just say "Authority control" with no label if only general or only other IDs are present
																-- since "general" is redundant and "other" is silly when there's nothing to contrast it with
																navboxArgs.group1 = '[[Ajuda:Controle de autoridade|Controle de autoridade]]'..pencil
												else
																navboxArgs.group1 = '[[Ajuda:Controle de autoridade|Controle de autoridade: '..sect..']] '..pencil
												end
								end
								outString = Navbox._navbox(navboxArgs)
				end
				
				--auxCats
				if rct == 0 or rct >= 25 then
								if namespace == 0 or testcases then
												local eCat = '!CA com '..rct..' elementos'
												elementsCat = addCat(eCat)
								end
				end
				if parentArgs.state or parentArgs.estado then
								if namespace == 0 or testcases then
												local sCat
												if parentArgs.state or parentArgs.estado== 'collapsed' or 'colapsar' then sCat = '!Artigos que utilizam colapsar em "Controle de autoridade"'
												elseif parentArgs.state == 'expanded' or 'expandir' then sCat = '!Artigos que utilizam expandir em "Controle de autoridade"'
												elseif parentArgs.state == 'autocollapse' or 'autocolapsar' then sCat = '!Artigos que utilizam autocolapsar em "Controle de autoridade"'
												else sCat = '' --'AC using state parameter: other'
												end
												stateCat = addCat(sCat)
								end
				end
				local auxCats = stateCat --worldcatCat..elementsCat..multipleIdCat..suppressedIdCat..suppressedIdCatArts..
--                    deprecatedIdCat..differentOnWDCat..sameOnWDCat..stateCat
				if testcases then
								auxCats = mw.ustring.gsub(auxCats, '(%[%[)(Categoria)', '%1:%2') --for easier checking
				end
				
				--out
				outString = outString --..auxCats
				if namespace ~= 0 then
								outString = mw.ustring.gsub(outString, '(%[%[)(Categoria:!Artigos)', '%1:%2') --by definition
				end
				
				return outString
end
return p