לדלג לתוכן

יחידה:בקרת זהויות: הבדלים בין גרסאות בדף

מתוך צפונות ויקי
יצירת דף עם התוכן "require('Module:No globals') local function getCatForId( id ) local title = mw.title.getCurrentTitle() local namespace = title.namespace if namespac..."
 
מ 3 גרסאות של הדף wikipedia:he:יחידה:בקרת_זהויות יובאו
 
(90 גרסאות ביניים של 14 משתמשים אינן מוצגות)
שורה 1: שורה 1:
require('Module:No globals')
require('Module:No globals')


local function getCatForId( id )
local p = {}
    local title = mw.title.getCurrentTitle()
local title = mw.title.getCurrentTitle()
    local namespace = title.namespace
local namespace = title.namespace
    if namespace == 0 then
local testcases = (string.sub(title.subpageText,1,9) == 'testcases')
 
--[[==========================================================================]]
--[[                            Category functions                            ]]
--[[==========================================================================]]
 
function p.getCatForId( id )
if namespace == 0 then
         return '[[קטגוריה:ויקיפדיה: ערכים עם מזהה  ' .. id .. ']]'
         return '[[קטגוריה:ויקיפדיה: ערכים עם מזהה  ' .. id .. ']]'
    elseif namespace == 2 and not title.isSubpage then
    elseif namespace == 2 and not title.isSubpage then
        return ''
return ''
    else
    else
        return  
return ''
    end
    end
end
 
function p.redCatLink( catName ) --catName == 'Blah' (not 'Category:Blah', not '[[Category:Blah]]')
if catName and catName ~= '' and
  testcases == false and
  mw.title.new(catName, 14).exists == false
then
return '[[קטגוריה:דפים עם קטגוריות בקרת זהויות אדומות]]'
end
return ''
end
 
function p.createRow( id, label, rawValue, link, withUid, specialCat )
if link then
if withUid then
return '*<span class="nowrap">'..label..' <span class="uid">'..link..'</span></span>\n'
end
return '*<span class="nowrap">'..label..' '..link..'</span>\n'
end
 
local catName = 'ויקיפדיה: ערכים עם מזהה '..(specialCat or id)..' שגוי'
return '* <span class="error">The '..id..' id '..rawValue..' is not valid.</span>[[Category:'..catName..']]'..'\n'
end
 
--[[==========================================================================]]
--[[                      Property formatting functions                      ]]
--[[==========================================================================]]
 
function p.iciaLink( id )
--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/he/?artist='..id..' '..id..']'..p.getCatForId( 'ICIA' )
end
 
function p.aagLink( id )
--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..'/ '..id..']'..p.getCatForId( 'AAG' )
end
 
function p.acmLink( id )
--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..' '..id..']'..p.getCatForId( 'ACM-DL' )
end
 
function p.adbLink( id )
--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..' '..id..']'..p.getCatForId( 'ADB' )
end
 
function p.agsaLink( id )
--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..'/ '..id..']'..p.getCatForId( 'AGSA' )
end
 
function p.autoresuyLink( id )
--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..' '..id..']'..p.getCatForId( 'autores.uy' )
end
 
function p.awrLink( id )
--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 '..id..']'..p.getCatForId( 'AWR' )
end
 
function p.balatLink( id )
--P3293's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[http://balat.kikirpa.be/object/104257'..id..' '..id..']'..p.getCatForId( 'BALaT' ) --no https as of 9/2019
end
 
function p.bibsysLink( id )
--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..' '..id..']'..p.getCatForId( 'BIBSYS' )
end
 
function p.bildLink( id )
--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..' '..id..']'..p.getCatForId( 'Bildindex' )
end
 
function p.bncLink( id )
--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..' '..id..']'..p.getCatForId( 'BNC' )
end
 
function p.bneLink( id )
--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..' '..id..']'..p.getCatForId( 'BNE' ) --no https as of 9/2019
end
 
function p.bnfLink( id )
--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..' '..id..'] [https://data.bnf.fr/ark:/12148/'..id..' (data)]'..p.getCatForId( 'BNF' )
end
 
function p.botanistLink( id )
--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
local id2 = id:gsub(' +', '%%20')
return '[https://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation='..id2..' '..id..']'..p.getCatForId( 'Botanist' )
end
 
function p.bpnLink( id )
--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..' '..id..']'..p.getCatForId( 'BPN' ) --no https as of 9/2019
end
 
function p.canticLink( id )
--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..' '..id..']'..p.getCatForId( 'CANTIC' ) --no https as of 10/2019
end
end


local function viafLink( id )
function p.ciniiLink( id )
    if not string.match( id, '^%d+$' ) then
--P271's format regex: DA\d{7}[\dX] (e.g. DA12345678)
        return false
if not id:match( '^DA%d%d%d%d%d%d%d[%dX]$' ) then
    end
return false
    return '[https://viaf.org/viaf/' .. id .. ' ' .. id .. ']' .. getCatForId( 'VIAF' )
end
return '[https://ci.nii.ac.jp/author/'..id..'?l=en '..id..']'..p.getCatForId( 'CINII' )
end
end


local function kulturnavLink( id )
function p.cwgcLink( id )
    return '[http://kulturnav.org/language/en/' .. id .. ' id]'  
--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..'/ '..id..']'..p.getCatForId( 'CWGC' )
end
end


local function sikartLink( id )
function p.daaoLink( id )
    return '[http://www.sikart.ch/KuenstlerInnen.aspx?id=' .. id .. '&lng=en ' .. id .. ']'  
--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..' '..id..']'..p.getCatForId( 'DAAO' )
end
end


local function tlsLink( id )
function p.dblpLink( id )
local id2 = mw.ustring.gsub(id, '%s', function(s) return mw.uri.encode(s, 'WIKI') end)
--P2456's format regex: \d{2,3} /\d+(-\d+)?|[a-z] /[a-zA-Z][0-9A-Za-z]*(-\d+)? (e.g. 123/123)
    return '[http://tls.theaterwissenschaft.ch/wiki/' .. id2 .. ' ' .. id .. ']'  
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..' '..id..']'..p.getCatForId( 'DBLP' )
end
end


function p.dsiLink( id )
--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..' '..id..']'..p.getCatForId( 'DSI' )
end


local function ciniiLink( id )
function p.fnzaLink( id )
    return '[http://ci.nii.ac.jp/author/' .. id .. '?l=en ' .. id .. ']'  
--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..'/ '..id..']'..p.getCatForId( 'FNZA' )
end
end


local function bneLink( id )
function p.gndLink( id )
    return '[http://catalogo.bne.es/uhtbin/authoritybrowse.cgi?action=display&authority_id=' .. id .. ' ' .. id .. ']'  
--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..' '..id..']'..p.getCatForId( 'GND' )
end
end


local function nliLink( id )
function p.hdsLink( id )
    return '[http://aleph.nli.org.il/F/?func=find-b&local_base=NNL10&find_code=SYS&request=' .. id .. ' ' .. id .. ']'  
--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..' '..id..']'..p.getCatForId( 'HDS' )
end
end


local function uscongressLink( id )
function p.iaafLink( id )
    return '[http://bioguide.congress.gov/scripts/biodisplay.pl?index=' .. id .. ' ' .. id .. ']'  
--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..' '..id..']'..p.getCatForId( 'IAAF' )
end
end


local function narapersonLink( id )
 
    return '[https://research.archives.gov/person/' .. id .. ' ' .. id .. ']'  
function p.isniLink( id )
id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145
if not id then
return false
end
return '[https://isni.org/isni/'..id..' '..id:sub( 1, 4 )..' '..id:sub( 5, 8 )..' '..id:sub( 9, 12 )..' '..id:sub( 13, 16 )..']'..p.getCatForId( 'ISNI' ) --no https as of 9/2019
end
end


local function naraorganizationLink( id )
function p.jocondeLink( id )
    return '[https://research.archives.gov/organization/' .. id .. ' ' .. id .. ']'  
--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..' '..id..']'..p.getCatForId( 'Joconde' )
end
end


local function botanistLink( id )
function p.kulturnavLink( id )
local id2 = mw.ustring.gsub(id, '%s', function(s) return mw.uri.encode(s, 'PATH') end)
--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)
    return '[http://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation=' .. id2 .. ' ' .. id .. ']'  
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..' '..id..']'..p.getCatForId( 'KULTURNAV' ) --no https as of 9/2019
end
end


local function mgpLink( id )
function p.lccnLink( id )
    -- TODO Implement some sanity checking regex
local parts = p.splitLccn( id ) --e.g. n78039510
    return '[http://www.genealogy.ams.org/id.php?id=' .. id .. ' ' .. id .. ']'  
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..' '..id..']'..p.getCatForId( 'LCCN' )
end
end


local function rslLink( id )
function p.lirLink( id )
    -- TODO Implement some sanity checking regex
--P886's format regex: \d+ (e.g. 1)
    return '[http://aleph.rsl.ru/F?func=find-b&find_code=SYS&adjacent=Y&local_base=RSL11&request=' .. id .. '&CON_LNG=ENG ' .. id .. ']'
if not id:match( '^%d+$' ) then
return false
end
return '[http://www.e-lir.ch/e-LIR___Lexicon.'..id..'.450.0.html '..id..']'..p.getCatForId( 'LIR' ) --no https as of 9/2019
end
end


local function leonoreLink( id )
function p.lnbLink( id )
-- Identifiants allant de LH/1/1 à LH/2794/54 (légionnaires)
--P1368's format regex: \d{9} (e.g. 123456789)
-- Identifiants allant de C/0/1 à C/0/84 (84 légionnaires célèbres)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
-- Identifiants allant de 19800035/1/1 à 19800035/385/51670 (légionnaires décédés entre 1954 et 1977, et quelques dossiers de légionnaires décédés avant 1954)
return false
    if not string.match( id, '^LH/%d%d?%d?%d?/%d%d?%d?$' ) and
end
      not string.match( id, '^C/0/%d%d?$' ) and
return '[https://kopkatalogs.lv/F?func=direct&local_base=lnc10&doc_number='..id..'&P_CON_LNG=ENG '..id..']'..p.getCatForId( 'LNB' )
  not string.match( id, '^19800035/%d%d?%d?%d?/%d%d?%d?%d?%d?$' ) then
        return false
    end
    return '[http://www.culture.gouv.fr/public/mistral/leonore_fr?ACTION=CHERCHER&FIELD_1=COTE&VALUE_1=' .. id .. ' ' .. id .. ']'  
end
end


local function sbnLink( id )
function p.leonoreLink( id )
    if not string.match( id, '^IT\\ICCU\\%d%d%d%d%d%d%d%d%d%d$' ) and not string.match( id, '^IT\\ICCU\\%u%u[%d%u]%u\\%d%d%d%d%d%d$' ) then
--P640's format regex: LH/\d{1,4}/\d{1,3}|19800035/\d{1,4}/\d{1,5}(Bis)?|C/0/\d{1,2} (e.g. LH/2064/18)
        return false
if not id:match( '^LH/%d%d?%d?%d?/%d%d?%d?$' ) and             --IDs from      LH/1/1 to        LH/2794/54 (legionaries)
    end
  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)
    return '[http://opac.sbn.it/opacsbn/opac/iccu/scheda_authority.jsp?bid=' .. id .. ' ' .. id .. ']' .. getCatForId( 'SBN' )
  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..' '..id..']'..p.getCatForId( 'Léonore' ) --no https as of 9/2019
end
end


local function nkcLink( id )
function p.mbaLink( id )
return '[http://aleph.nkp.cz/F/?func=find-c&local_base=aut&ccl_term=ica=' .. id .. '&CON_LNG=ENG ' .. id .. ']'  
--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
return '[https://musicbrainz.org/artist/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz' ) --special category name
end
end


local function nclLink( id )
function p.mbareaLink( id )
    if not string.match( id, '^%d+$' ) then
--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)
        return false
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
    end
return false
    return '[http://aleweb.ncl.edu.tw/F/?func=accref&acc_sequence=' .. id .. '&CON_LNG=ENG ' .. id .. ']'  
end
return '[https://musicbrainz.org/area/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz לאזור' ) --special category name
end
end


local function ndlLink( id )
function p.mbiLink( id )
return '[http://id.ndl.go.jp/auth/ndlna/' .. id .. ' ' .. id .. ']'  
--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
return '[https://musicbrainz.org/instrument/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz לכלי נגינה' ) --special category name
end
end


local function sudocLink( id )
function p.mblLink( id )
    if not string.match( id, '^%d%d%d%d%d%d%d%d[%dxX]$' ) then
--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)
        return false
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
    end
return false
    return '[https://www.idref.fr/' .. id .. ' ' .. id .. ']'  
end
return '[https://musicbrainz.org/label/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz label' ) --special category name
end
end


local function hlsLink( id )
function p.mbpLink( id )
    if not string.match( id, '^%d+$' ) then
--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)
        return false
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
    end
return false
    return '[http://www.hls-dhs-dss.ch/textes/f/F' .. id .. '.php ' .. id .. ']'
end
return '[https://musicbrainz.org/place/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz למקום' ) --special category name
end
end


local function lirLink( id )
function p.mbrgLink( id )
    if not string.match( id, '^%d+$' ) then
--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)
        return false
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
    end
return false
    return '[http://www.e-lir.ch/e-LIR___Lexicon.' .. id .. '.450.0.html ' .. id .. ']'
end
return '[https://musicbrainz.org/release-group/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz release group' ) --special category name
end
end


local function splitLccn( id )
function p.mbsLink( id )
    if id:match( '^%l%l?%l?%d%d%d%d%d%d%d%d%d?%d?$' ) then
--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)
        id = id:gsub( '^(%l+)(%d+)(%d%d%d%d%d%d)$', '%1/%2/%3' )
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
    end
return false
    if id:match( '^%l%l?%l?/%d%d%d?%d?/%d+$' ) then
end
        return mw.text.split( id, '/' )
return '[https://musicbrainz.org/series/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz series' ) --special category name
    end
    return false
end
end


local function append(str, c, length)
function p.mbwLink( id )
    while str:len() < length do
--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)
        str = c .. str
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
    end
return false
    return str
end
return '[https://musicbrainz.org/work/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz ליצירה' ) --special category name
end
end


local function lccnLink( id )
function p.mgpLink( id )
    local parts = splitLccn( id )
--P549's format regex: \d{1,6} (e.g. 123456)
    if not parts then
if not id:match( '^%d%d?%d?%d?%d?%d?$' ) then
        return false
return false
    end
end
    local lccnType = parts[1] ~= 'sh' and 'names' or 'subjects'
return '[https://genealogy.math.ndsu.nodak.edu/id.php?id='..id..' '..id..']'..p.getCatForId( 'MGP' )
    id = parts[1] .. parts[2] .. append( parts[3], '0', 6 )
    return '[http://id.loc.gov/authorities/' .. lccnType .. '/' .. id .. ' ' .. id .. ']' .. getCatForId( 'LCCN' )
end
end


local function mbLink( id )
function p.naraLink( id )
    -- TODO Implement some sanity checking regex
--P1225's format regex: ^([1-9]\d{0,8})$ (e.g. 123456789)
    return '[//musicbrainz.org/artist/' .. id .. ' ' .. id .. ']' .. getCatForId( 'MusicBrainz' )
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..' '..id..']'..p.getCatForId( 'NARA' )
end
end


--Returns the ISNI check digit isni must be a string where the 15 first elements are digits
function p.nclLink( id )
local function getIsniCheckDigit( isni )
--P1048's format regex: \d+ (e.g. 1081436)
    local total = 0
if not id:match( '^%d+$' ) then
    for i = 1, 15 do
return false
        local digit = isni:byte( i ) - 48 --Get integer value
end
        total = (total + digit) * 2
return '[http://aleweb.ncl.edu.tw/F/?func=accref&acc_sequence='..id..'&CON_LNG=ENG '..id..']'..p.getCatForId( 'NCL' ) --no https as of 9/2019
    end
end
    local remainder = total % 11
 
    local result = (12 - remainder) % 11
function p.ndlLink( id )
    if result == 10 then
--P349's format regex: 0?\d{8} (e.g. 012345678)
        return "X"
if not id:match( '^0?%d%d%d%d%d%d%d%d$' ) then
    end
return false
    return tostring( result )
end
return '[https://id.ndl.go.jp/auth/ndlna/'..id..' '..id..']'..p.getCatForId( 'NDL' )
end
 
function p.ngvLink( id )
--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..'/ '..id..']'..p.getCatForId( 'NGV' )
end
end


--Validate ISNI (and ORCID) and retuns it as a 16 characters string or returns false if it's invalid
function p.nkcLink( id )
--See http://support.orcid.org/knowledgebase/articles/116780-structure-of-the-orcid-identifier
--P691's format regex: [a-z]{2,4}[0-9]{2,14} (e.g. abcd12345678901234)
local function validateIsni( id )
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
    id = id:gsub( '[ %-]', '' ):upper()
return false
    if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d[%dX]$' ) then
end
        return false
return '[https://aleph.nkp.cz/F/?func=find-c&local_base=aut&ccl_term=ica='..id..'&CON_LNG=ENG '..id..']'..p.getCatForId( 'NKC' )
    end
end
    if getIsniCheckDigit( id ) ~= string.char( id:byte( 16 ) ) then
 
        return false
function p.nlaLink( id )
    end
--P409's format regex: [1-9][0-9]{0,11} (e.g. 123456789012)
    return id
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..' '..id..']'..p.getCatForId( 'NLA' )
end
 
function p.nlgLink( id )
--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..' '..id..']'..p.getCatForId( 'NLG' )
end
 
function p.nliLink( id )
--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'..' '..id..']'..p.getCatForId( 'NLI' )
end
function p.nliLinkNew( id )
--P8189's format
if not id:match( '^9870[01]%d%d%d%d%d%d%d%d05171$' ) then
return false
end
return '[http://uli.nli.org.il/F/?func=find-b&local_base=NLX10&find_code=UID&request='..id..' '..id ..']'..p.getCatForId( 'J9U' )
end
 
 
function p.nlkLink( id )
--P5034's format regex: (KAB|KAC|KSH)([0-9]{4}|[0-9]{4}[a-zA-Z])[0-9]{4,6} (e.g. KAC199616693, KAC2018L4645 or KSH1998000151)
if not id:match( '^KA[BC]%d%d%d%d[a-zA-Z]?%d%d%d%d%d?%d?$' ) and
  not id:match( '^KSH%d%d%d%d[a-zA-Z]?%d%d%d%d%d?%d?$' ) then
return false
end
return '[https://lod.nl.go.kr/resource/'..id..' '..id..']'..p.getCatForId( 'NLK' )
end
 
function p.nlpLink( id )
--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..' '..id..']'..p.getCatForId( 'NLP' )
end
 
function p.nlrLink( id )
--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..']'..p.getCatForId( 'NLR' )
end
 
function p.nskLink( id )
--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 '..id..']'..p.getCatForId( 'NSK' ) --no https as of 9/2019
end
 
function p.ntaLink( id )
--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..' '..id..']'..p.getCatForId( 'NTA' )
end
 
function p.orcidLink( id )
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..' '..id..']'..p.getCatForId( 'ORCID' )
end
 
function p.picLink( id )
--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..' '..id..']'..p.getCatForId( 'PIC' )
end
 
function p.ridLink( id )
--P1053's format regex: [A-Z]{1,3}-\d{4}-20[0-2]\d  (e.g. AAS-5150-2020)
if not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-20[0-2]%d$' ) then
return false
end
return '[https://www.researcherid.com/rid/'..id..' '..id..']'..p.getCatForId( 'RID' )
end
 
function p.reroLink( id )
--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..' '..id..']'..p.getCatForId( 'RERO' )
end
 
function p.rkdartistsLink( id )
--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..' '..id..']'..p.getCatForId( 'RKDartists' )
end
 
function p.rkdidLink( id )
--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..' '..id..']'..p.getCatForId( 'RKDID' )
end
 
function p.rslLink( id )
--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 '..id..']'..p.getCatForId( 'RSL' ) --no https as of 9/2019
end
 
function p.iccuLink( id )
--P396's format regex: \D{2}[A-Z0-3]V\d{6} (e.g. CUBV039952)
if not id:match( '^%u%u[A-Z0-3]V%d%d%d%d%d%d' ) then
return false
end
return '[https://opac.sbn.it/nome/'..id..' '..id..']'..p.getCatForId( 'ICCU' ) end
 
function p.selibrLink( id )
--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..' '..id..']'..p.getCatForId( 'SELIBR' )
end
end


local function isniLink( id )
function p.sikartLink( id )
    id = validateIsni( id )
--P781's format regex: \d{7,9} (e.g. 123456789)
    if not id then
if not id:match( '^%d%d%d%d%d%d%d%d?%d?$' ) then
        return false
return false
    end
end
    return '[http://isni.org/isni/' .. id .. ' ' .. id:sub( 1, 4 ) .. ' ' .. id:sub( 5, 8 ) .. ' ' .. id:sub( 9, 12 ) .. ' ' .. id:sub( 13, 16 ) .. ']' .. getCatForId( 'ISNI' )
return '[http://www.sikart.ch/KuenstlerInnen.aspx?id='..id..'&lng=en '..id..']'..p.getCatForId( 'SIKART' ) --no https as of 9/2019
end
end


local function orcidLink( id )
function p.snacLink( id )
    id = validateIsni( id )
--P3430's format regex: \d*[A-Za-z][0-9A-Za-z]* (e.g. A)
    if not id then
if not id:match( '^%d*[A-Za-z][0-9A-Za-z]*$' ) then
        return false
return false
    end
end
    id = id:sub( 1, 4 ) .. '-' .. id:sub( 5, 8 ) .. '-'  .. id:sub( 9, 12 ) .. '-' .. id:sub( 13, 16 )
return '[https://snaccooperative.org/ark:/99166/'..id..' '..id..']'..p.getCatForId( 'SNAC-ID' )
    return '[https://orcid.org/' .. id .. ' ' .. id .. ']' .. getCatForId( 'ORCID' )
end
end


local function gndLink( id )
function p.sudocLink( id )
    return '[http://d-nb.info/gnd/' .. id .. ' ' .. id .. ']' .. getCatForId( 'GND' )
--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..' '..id..']'..p.getCatForId( 'SUDOC' )
end
end


local function selibrLink( id )
function p.s2authoridLink( id )
if not string.match( id, '^%d+$' ) then
--P4012's format regex: [1-9]\d* (e.g. 1796130)
        return false
if not id:match( '^[1-9]%d*$' ) then
    end
return false
    return '[//libris.kb.se/auth/' .. id .. ' ' .. id .. ']' .. getCatForId( 'SELIBR' )
end
return '[https://www.semanticscholar.org/author/'..id..' '..id..']'..p.getCatForId( 'Semantic Scholar author' ) --special category name
end
end


local function bnfLink( id )
function p.ta98Link( id )
    --Add cb prefix if it has been removed
--P1323's format regex: A\d{2}\.\d\.\d{2}\.\d{3}[FM]? (e.g. A12.3.45.678)
    if not string.match( id, '^cb.+$' ) then
if not id:match( '^A%d%d%.%d%.%d%d%.%d%d%d[FM]?$' ) then
        id = 'cb' .. id
return false
    end
end
return '[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='..id..' '..id..']'..p.getCatForId( 'TA98' )
end


    return '[http://catalogue.bnf.fr/ark:/12148/' .. id .. ' ' .. id .. '] [http://data.bnf.fr/ark:/12148/' .. id .. ' (data)]' .. getCatForId( 'BNF' )
function p.tdviaLink( id )
--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..' '..id..']'..p.getCatForId( 'TDVİA' )
end
end


local function bpnLink( id )
function p.teLink( id )
    if not string.match( id, '^%d+$' ) then
--P1693's format regex: E[1-8]\.\d{1,2}\.\d{1,2}\.\d{1,2}\.\d{1}\.\d{1}\.\d{1,3} (e.g. E1.23.45.67.8.9.0)
        return false
local e1, e2 = id:match( '^E([1-8])%.(%d%d?)%.%d%d?%.%d%d?%.%d%.%d%.%d%d?%d?$' )
    end
if not e1 then
    return '[http://www.biografischportaal.nl/en/persoon/' .. id .. ' ' .. id .. ']' .. getCatForId( 'BPN' )
return false
end
local TEnum = 'TEe0'..e1 --no formatter URL in WD, probably due to this complexity
if e1 == '5' or e1 == '7' then
if #e2 == 1 then e2 = '0'..e2 end
TEnum = TEnum..e2
end
return '[http://www.unifr.ch/ifaa/Public/EntryPage/ViewTE/'..TEnum..'.html '..id..']'..p.getCatForId( 'TE' )
end
end


local function ridLink( id )
function p.tepapaLink( id )
    return '[http://www.researcherid.com/rid/' .. id .. ' ' .. id .. ']' .. getCatForId( 'RID' )
--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..' '..id..']'..p.getCatForId( 'TePapa' )
end
end


local function bibsysLink( id )
function p.thLink( id )
    return '[http://ask.bibsys.no/ask/action/result?cmd=&kilde=biblio&cql=bs.autid+%3D+' .. id .. '&feltselect=bs.autid ' .. id .. ']' .. getCatForId( 'BIBSYS' )
--P1694's format regex: H\d\.\d{2}\.\d{2}\.\d\.\d{5} (e.g. H1.23.45.6.78901)
local h1, h2 = id:match( '^H(%d)%.(%d%d)%.%d%d%.%d%.%d%d%d%d%d$' )
if not h1 then
return false
end
local THnum = 'THh'..h1..h2 --no formatter URL in WD, probably due to this complexity
return '[http://www.unifr.ch/ifaa/Public/EntryPage/ViewTH/'..THnum..'.html '..id..']'..p.getCatForId( 'TH' )
end
end


local function ulanLink( id )
function p.tlsLink( id )
    return '[//www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid=' .. id .. ' ' .. id .. ']' .. getCatForId( 'ULAN' )
local id2 = id:gsub(' +', '_')
--P1362's format regex: \p{Lu}[\p{L}\d_',\.\-\(\)\*/–]{3,59} (e.g. Abcd)
local class = "[%a%d_',%.%-%(%)%*/–]"
local regex = "^%u"..string.rep(class, 3)..string.rep(class.."?", 56).."$"
if not mw.ustring.match( id2, regex ) then
return false
end
return '[http://tls.theaterwissenschaft.ch/wiki/'..id2..' '..id..']'..p.getCatForId( 'TLS' ) --no https as of 9/2019
end
 
function p.troveLink( id )
--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..' '..id..']'..p.getCatForId( 'Trove' )
end
 
function p.ukparlLink( id )
--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..' '..id..']'..p.getCatForId( 'UKPARL' )
end
end


local function nlaLink( id )
function p.ulanLink( id )
return '[//nla.gov.au/anbd.aut-an' .. id .. ' ' .. id .. ']' .. getCatForId( 'NLA' )
--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..' '..id..']'..p.getCatForId( 'ULAN' )
end
end


local function rkdartistsLink( id )
function p.uscongressLink( id )
return '[https://rkd.nl/en/explore/artists/' .. id .. ' ' .. id .. ']' .. getCatForId( 'RKDartists' )
--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..' '..id..']'..p.getCatForId( 'USCongress' ) --no https as of 9/2019
end
end


local function getIdsFromWikidata( item, property )
function p.vcbaLink( id )
    local ids = {}
--P8034's format regex: \d{3}\/[1-9]\d{0,5} (e.g. 494/9793)
    if not item.claims[property] then
if not id:match( '^%d%d%d\/[1-9]%d?%d?%d?%d?%d?$' ) then
        return ids
return false
    end
end
    for _, statement in pairs( item:getBestStatements( property )) do
local id2 = id:gsub('\/', '_')
if statement.mainsnak.datavalue then
return '[https://opac.vatlib.it/auth/detail/'..id2..' '..id..']'..p.getCatForId( 'VcBA' )
table.insert( ids, statement.mainsnak.datavalue.value )
end
 
function p.viafLink( id )
--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
return '[https://viaf.org/viaf/'..id..' '..id..']'..p.getCatForId( 'VIAF' )
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
    end
end
    return ids
return ids
end
end


local function matchesWikidataRequirements( item, reqs )
function p.matchesWikidataRequirements( itemId, reqs )
    for _, group in pairs( reqs ) do
for _, group in ipairs( reqs ) do
        local property = 'p' .. group[1]
local property = 'P'..group[1]
        local qid = group[2]
local qid = group[2]
        if item.claims[property] ~= nil then
local statements = mw.wikibase.getBestStatements( itemId, property )
            for _, statement in pairs ( item.claims[property] ) do
if statements then
            if statement.mainsnak.datavalue ~= nil then
for _, statement in ipairs( statements ) do
                if statement.mainsnak.datavalue.value['numeric-id'] == qid then
if statement.mainsnak.datavalue then
                    return true
if statement.mainsnak.datavalue.value['numeric-id'] == qid then
                end
return true
            end
end end end end end
            end
return false
        end
    end
    return false
end
end


local function createRow( id, label, rawValue, link, withUid )
-- Creates a human-readable standalone wikitable version of p.conf, and tracking categories with page counts, for use in the documentation
    if link then
function p.docConfTable( frame )
        if withUid then
local wikiTable = '{| class="wikitable sortable"\n'..
            return '*<span style="white-space:nowrap;">' .. label .. ' <span class="uid">' .. link .. '</span></span>\n'
  '! rowspan=2 | Parameter\n'..
        else
  '! rowspan=2 | Label\n'..
            return '*<span style="white-space:nowrap;">' .. label .. ' ' .. link .. '</span>\n'
  '! rowspan=2; data-sort-type=number | Wikidata property\n'..
        end
  '! colspan=4 | Tracking categories and page counts\n'..
    else
  '|-\n'..
        return '* <span class="error">The ' .. id .. ' id ' .. rawValue .. ' is not valid.</span>[[Category:Wikipedia articles with faulty authority control identifiers (' .. id .. ')]]\n'
  '! [[:קטגוריה:ערכים עם מידע בקרת זהויות|'..      'ערכים]]\n'..
    end
  '! [[:קטגוריה:דפי משתמש עם מידע בקרת זהויות|'..              'דפי משתמש]]\n'..
  '! [[:קטגוריה:דפים שונים עם מידע בקרת זהויות|'..      'דפים]]\n'..
  '! [[:קטגוריה:ערכים עם מידע בקרת זהויות שגוי|'..'מזהים שגויים]]\n'..
  '|-\n'
local lang = mw.getContentLanguage()
for _, conf in pairs( p.conf ) do
local param, link, pid = conf[1], conf[2], conf[3]
local category = conf.category or param
local args = { id = 'f', pid }
local wpl = frame:expandTemplate{ title = 'Wikidata property link', args = args }
--cats
local articleCat = 'Wikipedia articles with '..category..' identifiers'
local userCat =    'User pages with '..category..' identifiers'
local miscCat =    'Miscellaneous pages with '..category..' identifiers'
local faultyCat =  'Wikipedia articles with faulty '..category..' identifiers'
--counts
local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )
local userCount =    lang:formatNum( mw.site.stats.pagesInCategory(userCat, 'pages') )
local miscCount =    lang:formatNum( mw.site.stats.pagesInCategory(miscCat, 'pages') )
local faultyCount =  lang:formatNum( mw.site.stats.pagesInCategory(faultyCat, 'pages') )
--concat
wikiTable = wikiTable..'\n'..
'|-\n'..
'||'..param..
'||'..link..
'||data-sort-value='..pid..'|'..wpl..
'||style="text-align: right;"|[[:Category:'..articleCat..'|'..articleCount..']]'..
'||style="text-align: right;"|[[:Category:'..   userCat..'|'..   userCount..']]'..
'||style="text-align: right;"|[[:Category:'..   miscCat..'|'..   miscCount..']]'..
'||style="text-align: right;"|[[:Category:'.. faultyCat..'|'.. faultyCount..']]'
end
return wikiTable..'\n|}'
end
end


--In this order: name of the parameter, label, propertyId in Wikidata, formatting function
--[[==========================================================================]]
local conf = {
--[[                             Configuration                              ]]
    { 'VIAF', '[[Virtual International Authority File|VIAF]]', 214, viafLink },
--[[==========================================================================]]
    { 'LCCN', '[[Library of Congress Control Number|LCCN]]', 244, lccnLink },
 
    { 'ISNI', '[[International Standard Name Identifier|ISNI]]', 213, isniLink },
-- If a specific "(identifier) redirect" exists for an identifier, please route through this particular redirect rather than linking directly to the target page. This reduces clutter in "What links here" and improves reverse lookup of articles where a manifestation of this particular identifier is used.
    { 'ORCID', '[[ORCID]]', 496, orcidLink },
    { 'GND', '[[Integrated Authority File|GND]]', 227, gndLink },
    { 'SELIBR', '[[LIBRIS|SELIBR]]', 906, selibrLink },
    { 'SUDOC', '[[Système universitaire de documentation|SUDOC]]', 269, sudocLink },
    { 'BNF', '[[הספרייה הלאומית של צרפת|BNF]]', 268, bnfLink },
    { 'BPN', '[[Biografisch Portaal|BPN]]', 651, bpnLink },
    { 'RID', '[[ResearcherID]]', 1053, ridLink },
    { 'BIBSYS', '[[BIBSYS]]', 1015, bibsysLink },
    { 'ULAN', '[[Union List of Artist Names|ULAN]]', 245, ulanLink },
    { 'HDS', '[[מילון היסטורי של שווייץ|HDS]]', 902, hlsLink },
    { 'LIR', '[[מילון היסטורי של שווייץ#Lexicon_Istoric_Retic|LIR]]', 886, lirLink },
    { 'MBA', '[[MusicBrainz]]', 434, mbLink },
    { 'MGP', '[[פרויקט הגנאלוגיה במתמטיקה|MGP]]', 549, mgpLink },
    { 'NLA', '[[הספרייה הלאומית של אוסטרליה|NLA]]', 409, nlaLink },
    { 'NDL', '[[ספריית הדיאט הלאומית|NDL]]', 349, ndlLink },
    { 'NCL', '[[National Central Library|NCL]]', 1048, nclLink },
    { 'NKC', '[[הספרייה הלאומית של צ&#39;כיה|NKC]]', 691, nkcLink },
    { 'Léonore', '[[Base Léonore|Léonore]]', 640, leonoreLink },
    { 'SBN', '[[Istituto Centrale per il Catalogo Unico|ICCU]]', 396, sbnLink },
    { 'RLS', '[[הספרייה הממלכתית של רוסיה|RLS]]', 947, rslLink },
    { 'Botanist', '[[Author citation (botany)|Botanist]]', 428, botanistLink },
    { 'NARA-person', '[[הארכיון הלאומי של ארצות הברית|NARA]]', 1222, narapersonLink },
    { 'NARA-organization', '[[הארכיון הלאומי של ארצות הברית|NARA]]', 1223, naraorganizationLink },
    { 'USCongress', '[[Biographical Directory of the United States Congress|US Congress]]', 1157, uscongressLink },
    { 'BNE', '[[הספרייה הלאומית של ספרד|BNE]]', 950, bneLink },
    { 'NLI', '[[הספרייה הלאומית של ספרד|NLI]]', 949, nlilink },
    { 'CINII', '[[CiNii]]', 271, ciniiLink },
    { 'TLS', '[[Theaterlexikon der Schweiz|TLS]]', 1362, tlsLink },
    { 'SIKART', '[[SIKART]]', 781, sikartLink },
    { 'KULTURNAV', '[[KulturNav]]', 1248, kulturnavLink },
    { 'RKDartists', '[[Netherlands Institute for Art History#Online artist pages|RKD]]', 650, rkdartistsLink },
}


-- Check that the Wikidata item has this property-->value before adding it
-- Check that the Wikidata item has this property-->value before adding it
local reqs = {}
local reqs = {}


local p = {}
-- Parameter format: { 'parameter name', 'label', propertyId # in Wikidata, formatting/validation function }
p.conf = {
{ 'ICIA', '[[מרכז המידע לאמנות ישראלית|ICIA]]', 1736, p.iciaLink },
{ 'NLIj9u', '[[הספרייה הלאומית|NLI]]', 8189, p.nliLinkNew },
{ 'NLI', '[[הספרייה הלאומית|NLI]]', 949, p.nliLink },
{ 'AAG', '[[גלריית האומנות טואי או טאמאקי באוקלנד|AAG]]', 3372, p.aagLink },
{ 'ACM-DL', '[[Association for Computing Machinery#Portal and Digital Library|ACM DL]]', 864, p.acmLink },
{ 'ADB', '[[Australian Dictionary of Biography|ADB]]', 1907, p.adbLink },
{ 'AGSA', '[[Art Gallery of South Australia|AGSA]]', 6804, p.agsaLink },
{ 'autores.uy', '[[autores.uy]]', 2558, p.autoresuyLink },
{ 'AWR', '[[Australian Women\'s Register|AWR]]', 4186, p.awrLink },
{ 'BALaT', '[[Royal Institute for Cultural Heritage#Online artworks pages|BALaT]]', 3293, p.balatLink },
{ 'BIBSYS', '[[BIBSYS]]', 1015, p.bibsysLink },
{ 'Bildindex', '[[Marburg Picture Index|Bildindex]]', 2092, p.bildLink },
{ 'BNC', '[[הספרייה הלאומית של צ&#39;ילה|BNC]]', 1890, p.bncLink },
{ 'BNE', '[[הספרייה הלאומית של ספרד|BNE]]', 950, p.bneLink },
{ 'BNF', '[[הספרייה הלאומית של צרפת|BnF]]', 268, p.bnfLink },
{ 'Botanist', '[[Author citation (botany)|Botanist]]', 428, p.botanistLink },
{ 'BPN', '[[Biografisch Portaal|BPN]]', 651, p.bpnLink },
{ 'CANTIC', '[[מיון השמות והתארים של קטלוניה|CANTIC]]', 1273, p.canticLink },
{ 'CINII', '[[CiNii]]', 271, p.ciniiLink },
{ 'CWGC', '[[CWGC (identifier)|CWGC]]', 1908, p.cwgcLink },
{ 'DAAO', '[[Dictionary of Australian Artists|DAAO]]', 1707, p.daaoLink },
{ 'DBLP', '[[DBLP]]', 2456, p.dblpLink },
{ 'DSI', '[[מאגר המאיירים המדעיים של שטוטגרט 1450–1950|DSI]]', 2349, p.dsiLink },
{ 'FNZA', '[[:d:Property:P6792|FNZA]]', 6792, p.fnzaLink },
{ 'GND', '[[קובץ בקרה משולב|GND]]', 227, p.gndLink },
{ 'HDS', '[[מילון היסטורי של שווייץ|HDS]]', 902, p.hdsLink },
{ 'IAAF', '[[התאחדות האתלטיקה הבין-לאומית|World Athletics]]', 1146, p.iaafLink },
{ 'ICCU', '[[המכון המרכזי לקטלוג אחיד|ICCU]]', 396, p.iccuLink }, --formerly SBN
{ 'ISNI', '[[תקן בין-לאומי למזהי שמות|ISNI]]', 213, p.isniLink },
{ 'Joconde', '[[Joconde]]' , 347, p.jocondeLink },
{ 'KULTURNAV', '[[KulturNav]]', 1248, p.kulturnavLink },
{ 'LCCN', '[[שיטת ספריית הקונגרס|LCCN]]', 244, p.lccnLink },
{ 'LIR', '[[מילון היסטורי של שווייץ|LIR]]', 886, p.lirLink },
{ 'LNB', '[[הספרייה הלאומית של לטביה|LNB]]', 1368, p.lnbLink },
{ 'Léonore', '[[Base Léonore|Léonore]]', 640, p.leonoreLink },
{ 'MBA', '[[MusicBrainz]]', 434, p.mbaLink, category = 'MusicBrainz' }, --special category name
{ 'MBAREA', '[[MusicBrainz]]', 982, p.mbareaLink, category = 'MusicBrainz area' }, --special category name
{ 'MBI', '[[MusicBrainz]]', 1330, p.mbiLink, category = 'MusicBrainz instrument' }, --special category name
{ 'MBL', '[[MusicBrainz]]', 966, p.mblLink, category = 'MusicBrainz label' }, --special category name
{ 'MBP', '[[MusicBrainz]]', 1004, p.mbpLink, category = 'MusicBrainz place' }, --special category name
{ 'MBRG', '[[MusicBrainz]] release group', 436, p.mbrgLink, category = 'MusicBrainz release group' }, --special category name
{ 'MBS', '[[MusicBrainz]]', 1407, p.mbsLink, category = 'MusicBrainz series' }, --special category name
{ 'MBW', '[[MusicBrainz]] work', 435, p.mbwLink, category = 'MusicBrainz work' }, --special category name
{ 'MGP', '[[פרויקט הגנאלוגיה במתמטיקה|MGP]]', 549, p.mgpLink },
{ 'NARA', '[[הארכיון הלאומי של ארצות הברית|NARA]]', 1225, p.naraLink },
{ 'NCL', '[[National Central Library|NCL]]', 1048, p.nclLink },
{ 'NDL', '[[ספריית הדיאט הלאומית|NDL]]', 349, p.ndlLink },
{ 'NGV', '[[הגלריה הלאומית של ויקטוריה|NGV]]', 2041, p.ngvLink },
{ 'NKC', '[[הספרייה הלאומית של צ&#39;כיה|NKC]]', 691, p.nkcLink },
{ 'NLA', '[[הספרייה הלאומית של אוסטרליה|NLA]]', 409, p.nlaLink },
{ 'NLG', '[[הספרייה הלאומית של יוון|NLG]]', 3348, p.nlgLink },
{ 'NLK', '[[הספרייה הלאומית של קוריאה|NLK]]', 5034, p.nlkLink },
{ 'NLP', '[[הספרייה הלאומית של פולין|NLP]]', 1695, p.nlpLink },
{ 'NLR', '[[הספרייה הלאומית של רומניה|NLR]]', 1003, p.nlrLink },
{ 'NSK', '[[הספרייה הלאומית והאוניברסיטאית בזאגרב|NSK]]', 1375, p.nskLink },
{ 'NTA', '[[הספרייה הלאומית של הולנד|NTA]]', 1006, p.ntaLink },
{ 'ORCID', '[[זיהוי ORCID|ORCID]]', 496, p.orcidLink },
{ 'PIC', '[[:d:Q23892012|PIC]]', 2750, p.picLink },
{ 'RID', '[[ResearcherID]]', 1053, p.ridLink },
{ 'RERO', '[[רשת הספריות של מערב שווייץ|RERO]]', 3065, p.reroLink },
{ 'RKDartists', '[[המכון ההולנדי להיסטוריה של האמנות|RKD]]', 650, p.rkdartistsLink },
{ 'RKDID', '[[המכון ההולנדי להיסטוריה של האמנות|RKDimages ID]]', 350, p.rkdidLink },
{ 'RSL', '[[הספרייה הממלכתית של רוסיה|RSL]]', 947, p.rslLink },
{ 'SELIBR', '[[הספרייה הלאומית של שוודיה|SELIBR]]', 906, p.selibrLink },
{ 'SIKART', '[[SIKART]]', 781, p.sikartLink },
{ 'SNAC-ID', '[[SNAC]]', 3430, p.snacLink },
{ 'SUDOC', '[[מערכת התיעוד האוניברסיטאית (צרפת)|SUDOC]]', 269, p.sudocLink },
{ 'S2AuthorId', '[[Semantic Scholar|S2AuthorId]]', 4012, p.s2authoridLink, category = 'Semantic Scholar author' }, --special category name
{ 'TA98', '[[Terminologia Anatomica|TA98]]', 1323, p.ta98Link },
{ 'TDVİA', '[[האנציקלופדיה של האסלאם|TDVİA]]', 7314, p.tdviaLink },
{ 'TE', '[[Terminologia Embryologica|TE]]', 1693, p.teLink },
{ 'TePapa', '[[המוזיאון של ניו זילנד טה פאפה טונגרווה|TePapa]]', 3544, p.tepapaLink },
{ 'TH', '[[Terminologia Histologica|TH]]', 1694, p.thLink },
{ 'TLS', '[[Theaterlexikon der Schweiz|TLS]]', 1362, p.tlsLink },
{ 'Trove', '[[Trove]]', 1315, p.troveLink }, --formerly NLA-person
{ 'UKPARL', '[[UKPARL]]', 6213, p.ukparlLink },
{ 'ULAN', '[[Union List of Artist Names|ULAN]]', 245, p.ulanLink },
{ 'USCongress', '[[המדריך הביוגרפי של הקונגרס של ארצות הברית|US Congress]]', 1157, p.uscongressLink },
{ 'VcBA', '[[ספריית הוותיקן|VcBA]]', 8034, p.vcbaLink },
{ 'VIAF', '[[VIAF]]', 214, p.viafLink },
{ 'WORLDCATID', '[[WorldCat]]', 7859, nil },
}
 
-- Legitimate aliases to p.conf, for convenience
-- Format: { 'alias', 'parameter name in p.conf' }
p.aliases = {
{ '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:Wikipedia 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 )
function p.authorityControl( frame )
    local parentArgs = frame:getParent().args
--local resolveEntity = require( "Module:ResolveEntityId" )
    --Create rows
local parentArgs = frame:getParent().args
    local elements = {}
local elements = {} --create/insert rows later
local worldcatCat = ''
local suppressedIdCat = ''
local deprecatedIdCat = ''
--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 = '[[קטגוריה:ערכים עם מזהה בקרת זהויות שכבר לא בשימוש|'..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


    --redirect PND to GND
--experiment as requested in מזנון
    if (parentArgs.GND == nil or parentArgs.GND == '') and parentArgs.PND ~= nil and parentArgs.PND ~= '' then
if (parentArgs['purple'] == 'yes') then
        parentArgs.GND = parentArgs.PND
itemId = parentArgs['qid']
    end
end
--Wikidata fallback if requested
if itemId then
for _, params in ipairs( p.conf ) do
if params[3] > 0 then
local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
if val == nil or val == '' then
local canUseWikidata = nil
if reqs[params[1]] then
canUseWikidata = p.matchesWikidataRequirements( itemId, reqs[params[1]] )
else
canUseWikidata = true
end
if canUseWikidata then
local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[3] )
if wikidataIds[1] then
if val == '' and (namespace == 0 or testcases) then
suppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|'..params[1]..']]'
else
parentArgs[params[1]] = wikidataIds[1]
end end end end end end end


    --Wikidata fallback if requested
    local item = mw.wikibase.getEntityObject()
-- dont show both NLI and NLIj9u
    if item ~= nil and item.claims ~= nil then
if parentArgs.NLI and parentArgs.NLIj9u then
        for _, params in pairs( conf ) do
parentArgs.NLI = ''
            if params[3] ~= 0 then
end
                local val = parentArgs[params[1]]
                if not val or val == '' then
--Configured rows
                local canUseWikidata = nil
local rct = 0
                    if reqs[params[1]] ~= nil then
for _, params in ipairs( p.conf ) do
                        canUseWikidata = matchesWikidataRequirements( item, reqs[params[1]] )
local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
                    else
if val and val ~= '' and type(params[4]) == 'function' then
                        canUseWikidata = true
table.insert( elements, p.createRow( params[1], params[2]..':', val, params[4]( val ), true, params.category ) )
                    end
rct = rct + 1
                    if canUseWikidata then
end
                        local wikidataIds = getIdsFromWikidata( item, 'P' .. params[3] )
end
                        if wikidataIds[1] then
                            parentArgs[params[1]] = wikidataIds[1]
                        end
                    end
                end
            end
        end
    end


    --Worldcat
--WorldCat
    if parentArgs['WORLDCATID'] and parentArgs['WORLDCATID'] ~= '' then
local worldcatId = parentArgs['worldcatid'] or parentArgs['WORLDCATID']
        table.insert( elements, createRow( 'WORLDCATID', '', parentArgs['WORLDCATID'], '[//www.worldcat.org/identities/' .. parentArgs['WORLDCATID'] .. ' WorldCat Identities]', false ) ) --Validation?
if worldcatId and worldcatId ~= '' then --if WORLDCATID present & unsuppressed
    elseif parentArgs['VIAF'] and string.match( parentArgs['VIAF'], '^%d+$' ) then -- Hackishly copy the validation code; this should go away when we move to using P1793 and P1630
table.insert( elements, p.createRow( 'WORLDCATID', '', worldcatId, '[[WorldCat]]: [https://www.worldcat.org/identities/'..mw.uri.encode(worldcatId, 'PATH')..' '..worldcatId..']', false ) ) --Validation?
        table.insert( elements, createRow( 'VIAF', '', parentArgs['VIAF'], '[//www.worldcat.org/identities/containsVIAFID/' .. parentArgs['VIAF'] .. ' WorldCat Identities]', false ) )
worldcatCat = p.getCatForId( 'WORLDCATID' )
    elseif parentArgs['LCCN'] and parentArgs['LCCN'] ~= '' then
elseif worldcatId == nil then --if WORLDCATID absent but unsuppressed
        local lccnParts = splitLccn( parentArgs['LCCN'] )
local viafId = parentArgs['viaf'] or parentArgs['VIAF']
        if lccnParts and lccnParts[1] ~= 'sh' then
local lccnId = parentArgs['lccn'] or parentArgs['LCCN']
            table.insert( elements, createRow( 'LCCN', '', parentArgs['LCCN'], '[//www.worldcat.org/identities/lccn-' .. lccnParts[1] .. lccnParts[2] .. '-' .. lccnParts[3] .. ' WorldCat Identities]', false ) )
if viafId and viafId ~= '' and p.viafLink( viafId ) then --VIAF must be present, unsuppressed, & validated
        end
table.insert( elements, p.createRow( 'VIAF', '', viafId, '[[WorldCat]] (עם VIAF): [https://www.worldcat.org/identities/containsVIAFID/'..viafId..' '..viafId..']', false ) )
    end
if namespace == 0 then
 
worldcatCat = '[[קטגוריה:ויקיפדיה: ערכים עם מזהה WorldCat-VIAF]]'
    --Configured rows
end
    local rct = 0
elseif lccnId and lccnId ~= '' and p.lccnLink( lccnId ) then --LCCN must be present, unsuppressed, & validated
    for k, params in pairs( conf ) do
local lccnParts = p.splitLccn( lccnId )
        local val = parentArgs[params[1]]
if lccnParts and lccnParts[1] ~= 'sh' then
        if val and val ~= '' then
local lccnIdFmtd = lccnParts[1]..lccnParts[2]..'-'..lccnParts[3]
            table.insert( elements, createRow( params[1], params[2] .. ':', val, params[4]( val ), true ) )
table.insert( elements, p.createRow( 'LCCN', '', lccnId, '[[WorldCat]] (עם LCCN): [https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' '..lccnIdFmtd..']', false ) )
            rct = rct + 1
if namespace == 0 then
        end
worldcatCat = '[[קטגוריה:ויקיפדיה: ערכים עם מזהה WorldCat-LCCN]]'
    end
end
    local Navbox = require('Module:Navbox')
end
    local elementscats = ''
end
    if rct > 13 then
elseif worldcatId == '' then --if WORLDCATID suppressed
    elementscats = '[[Category:AC with ' .. rct .. ' elements]]'
suppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|WORLDCATID]]'
end
local Navbox = require('Module:Navbox')
local elementsCat = ''
if (rct == 0 or rct >= 25) and (namespace == 0) then
local eCat = 'בקרת זהויות עם '..rct..' פריטים'
elementsCat = '[[Category:'..eCat..']]'..p.redCatLink(eCat)
end
end
if #elements ~= 0 then
local outString = ''
return Navbox._navbox( {
if #elements > 0 then
name  = 'Authority control',
local args = { pid = 'identifiers' } -- #target the list of identifiers
if testcases and itemId then args = { pid = 'identifiers', qid = itemId } end --expensive
local pencil = ''
if itemId then
local pencilLink = mw.title.makeTitle( 0, itemId, '', 'wikidata' ):fullUrl('uselang=he')
pencil = mw.ustring.format(' [[File:Blue pencil RTL.svg|15px|link=%s|עריכת הנתון בוויקינתונים]]', pencilLink)
end
outString = Navbox._navbox( {
name  = 'בקרת זהויות',
navboxclass = 'authority-control',
bodyclass = 'hlist',
bodyclass = 'hlist',
group1 = '[[Help:Authority control|Authority control]]' .. elementscats,
group1 = '[[עזרה:בקרת זהויות|בקרת זהויות]]'..pencil,
list1 = table.concat( elements )
list1 = '<div dir="ltr">\n' .. table.concat( elements ) .. '</div>'
} )
} )
else
return ""
end
end
local auxCats = worldcatCat .. elementsCat .. suppressedIdCat .. deprecatedIdCat
if testcases then
auxCats = mw.ustring.gsub(auxCats, '(%[%[)(Category)', '%1:%2') --for easier checking
end
outString = outString .. auxCats
if namespace ~= 0 then
outString = mw.ustring.gsub(outString, '(%[%[)(Category:Wikipedia articles)', '%1:%2') --by definition
end
return outString
end
end


return p
return p

גרסה אחרונה מ־20:15, 18 ביוני 2023

ניתן ליצור תיעוד על היחידה הזאת בדף יחידה:בקרת זהויות/תיעוד

require('Module:No globals')

local p = {}
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
local testcases = (string.sub(title.subpageText,1,9) == 'testcases')

--[[==========================================================================]]
--[[                            Category functions                            ]]
--[[==========================================================================]]

function p.getCatForId( id )
	if namespace == 0 then
        return '[[קטגוריה:ויקיפדיה: ערכים עם מזהה  ' .. id .. ']]'
    	elseif namespace == 2 and not title.isSubpage then
		return ''
	    else
		return ''
	    end
end

function p.redCatLink( catName ) --catName == 'Blah' (not 'Category:Blah', not '[[Category:Blah]]')
	if catName and catName ~= '' and
	   testcases == false and
	   mw.title.new(catName, 14).exists == false
	then
		return '[[קטגוריה:דפים עם קטגוריות בקרת זהויות אדומות]]'
	end
	return ''
end

function p.createRow( id, label, rawValue, link, withUid, specialCat )
	if link then
		if withUid then
			return '*<span class="nowrap">'..label..' <span class="uid">'..link..'</span></span>\n'
		end
		return '*<span class="nowrap">'..label..' '..link..'</span>\n'
	end

	local catName = 'ויקיפדיה: ערכים עם מזהה '..(specialCat or id)..' שגוי'
	return '* <span class="error">The '..id..' id '..rawValue..' is not valid.</span>[[Category:'..catName..']]'..'\n'
end

--[[==========================================================================]]
--[[                      Property formatting functions                       ]]
--[[==========================================================================]]

function p.iciaLink( id )
	--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/he/?artist='..id..' '..id..']'..p.getCatForId( 'ICIA' )
end

function p.aagLink( id )
	--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..'/ '..id..']'..p.getCatForId( 'AAG' )
end

function p.acmLink( id )
	--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..' '..id..']'..p.getCatForId( 'ACM-DL' )
end

function p.adbLink( id )
	--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..' '..id..']'..p.getCatForId( 'ADB' )
end

function p.agsaLink( id )
	--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..'/ '..id..']'..p.getCatForId( 'AGSA' )
end

function p.autoresuyLink( id )
	--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..' '..id..']'..p.getCatForId( 'autores.uy' )
end

function p.awrLink( id )
	--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 '..id..']'..p.getCatForId( 'AWR' )
end

function p.balatLink( id )
	--P3293's format regex: \d+ (e.g. 1)
	if not id:match( '^%d+$' ) then
		return false
	end
	return '[http://balat.kikirpa.be/object/104257'..id..' '..id..']'..p.getCatForId( 'BALaT' ) --no https as of 9/2019
end

function p.bibsysLink( id )
	--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..' '..id..']'..p.getCatForId( 'BIBSYS' )
end

function p.bildLink( id )
	--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..' '..id..']'..p.getCatForId( 'Bildindex' )
end

function p.bncLink( id )
	--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..' '..id..']'..p.getCatForId( 'BNC' )
end

function p.bneLink( id )
	--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..' '..id..']'..p.getCatForId( 'BNE' ) --no https as of 9/2019
end

function p.bnfLink( id )
	--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..' '..id..'] [https://data.bnf.fr/ark:/12148/'..id..' (data)]'..p.getCatForId( 'BNF' )
end

function p.botanistLink( id )
	--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
	local id2 = id:gsub(' +', '%%20')
	return '[https://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation='..id2..' '..id..']'..p.getCatForId( 'Botanist' )
end

function p.bpnLink( id )
	--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..' '..id..']'..p.getCatForId( 'BPN' ) --no https as of 9/2019
end

function p.canticLink( id )
	--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..' '..id..']'..p.getCatForId( 'CANTIC' ) --no https as of 10/2019
end

function p.ciniiLink( id )
	--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 '..id..']'..p.getCatForId( 'CINII' )
end

function p.cwgcLink( id )
	--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..'/ '..id..']'..p.getCatForId( 'CWGC' )
end

function p.daaoLink( id )
	--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..' '..id..']'..p.getCatForId( 'DAAO' )
end

function p.dblpLink( id )
	--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..' '..id..']'..p.getCatForId( 'DBLP' )
end

function p.dsiLink( id )
	--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..' '..id..']'..p.getCatForId( 'DSI' )
end

function p.fnzaLink( id )
	--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..'/ '..id..']'..p.getCatForId( 'FNZA' )
end

function p.gndLink( id )
	--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..' '..id..']'..p.getCatForId( 'GND' )
end

function p.hdsLink( id )
	--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..' '..id..']'..p.getCatForId( 'HDS' )
end

function p.iaafLink( id )
	--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..' '..id..']'..p.getCatForId( 'IAAF' )
end


function p.isniLink( id )
	id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145
	if not id then
		return false
	end
	return '[https://isni.org/isni/'..id..' '..id:sub( 1, 4 )..' '..id:sub( 5, 8 )..' '..id:sub( 9, 12 )..' '..id:sub( 13, 16 )..']'..p.getCatForId( 'ISNI' ) --no https as of 9/2019
end

function p.jocondeLink( id )
	--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..' '..id..']'..p.getCatForId( 'Joconde' )
end

function p.kulturnavLink( id )
	--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..' '..id..']'..p.getCatForId( 'KULTURNAV' ) --no https as of 9/2019
end

function p.lccnLink( id )
	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..' '..id..']'..p.getCatForId( 'LCCN' )
end

function p.lirLink( id )
	--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 '..id..']'..p.getCatForId( 'LIR' ) --no https as of 9/2019
end

function p.lnbLink( id )
	--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 '..id..']'..p.getCatForId( 'LNB' )
end

function p.leonoreLink( id )
	--P640's format regex: LH/\d{1,4}/\d{1,3}|19800035/\d{1,4}/\d{1,5}(Bis)?|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( '^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..' '..id..']'..p.getCatForId( 'Léonore' ) --no https as of 9/2019
end

function p.mbaLink( id )
	--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
	return '[https://musicbrainz.org/artist/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz' ) --special category name
end

function p.mbareaLink( id )
	--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
	return '[https://musicbrainz.org/area/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz לאזור' ) --special category name
end

function p.mbiLink( id )
	--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
	return '[https://musicbrainz.org/instrument/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz לכלי נגינה' ) --special category name
end

function p.mblLink( id )
	--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
	return '[https://musicbrainz.org/label/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz label' ) --special category name
end

function p.mbpLink( id )
	--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
	return '[https://musicbrainz.org/place/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz למקום' ) --special category name
end

function p.mbrgLink( id )
	--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
	return '[https://musicbrainz.org/release-group/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz release group' ) --special category name
end

function p.mbsLink( id )
	--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
	return '[https://musicbrainz.org/series/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz series' ) --special category name
end

function p.mbwLink( id )
	--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
	return '[https://musicbrainz.org/work/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz ליצירה' ) --special category name
end

function p.mgpLink( id )
	--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..' '..id..']'..p.getCatForId( 'MGP' )
end

function p.naraLink( id )
	--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..' '..id..']'..p.getCatForId( 'NARA' )
end

function p.nclLink( id )
	--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 '..id..']'..p.getCatForId( 'NCL' ) --no https as of 9/2019
end

function p.ndlLink( id )
	--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..' '..id..']'..p.getCatForId( 'NDL' )
end

function p.ngvLink( id )
	--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..'/ '..id..']'..p.getCatForId( 'NGV' )
end

function p.nkcLink( id )
	--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 '..id..']'..p.getCatForId( 'NKC' )
end

function p.nlaLink( id )
	--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..' '..id..']'..p.getCatForId( 'NLA' )
end

function p.nlgLink( id )
	--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..' '..id..']'..p.getCatForId( 'NLG' )
end

function p.nliLink( id )
	--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'..' '..id..']'..p.getCatForId( 'NLI' )
end
function p.nliLinkNew( id )
	--P8189's format
	if not id:match( '^9870[01]%d%d%d%d%d%d%d%d05171$' ) then
		return false
	end
	return '[http://uli.nli.org.il/F/?func=find-b&local_base=NLX10&find_code=UID&request='..id..' '..id ..']'..p.getCatForId( 'J9U' )
end


function p.nlkLink( id )
	--P5034's format regex: (KAB|KAC|KSH)([0-9]{4}|[0-9]{4}[a-zA-Z])[0-9]{4,6} (e.g. KAC199616693, KAC2018L4645 or KSH1998000151)
	if not id:match( '^KA[BC]%d%d%d%d[a-zA-Z]?%d%d%d%d%d?%d?$' ) and
	   not id:match( '^KSH%d%d%d%d[a-zA-Z]?%d%d%d%d%d?%d?$' ) then
		return false
	end
	return '[https://lod.nl.go.kr/resource/'..id..' '..id..']'..p.getCatForId( 'NLK' )
end

function p.nlpLink( id )
	--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..' '..id..']'..p.getCatForId( 'NLP' )
end

function p.nlrLink( id )
	--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..']'..p.getCatForId( 'NLR' )
end

function p.nskLink( id )
	--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 '..id..']'..p.getCatForId( 'NSK' ) --no https as of 9/2019
end

function p.ntaLink( id )
	--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..' '..id..']'..p.getCatForId( 'NTA' )
end

function p.orcidLink( id )
	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..' '..id..']'..p.getCatForId( 'ORCID' )
end

function p.picLink( id )
	--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..' '..id..']'..p.getCatForId( 'PIC' )
end

function p.ridLink( id )
	--P1053's format regex: [A-Z]{1,3}-\d{4}-20[0-2]\d   (e.g. AAS-5150-2020)
	if not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-20[0-2]%d$' ) then
		return false
	end
	return '[https://www.researcherid.com/rid/'..id..' '..id..']'..p.getCatForId( 'RID' )
end

function p.reroLink( id )
	--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..' '..id..']'..p.getCatForId( 'RERO' )
end

function p.rkdartistsLink( id )
	--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..' '..id..']'..p.getCatForId( 'RKDartists' )
end

function p.rkdidLink( id )
	--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..' '..id..']'..p.getCatForId( 'RKDID' )
end

function p.rslLink( id )
	--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 '..id..']'..p.getCatForId( 'RSL' ) --no https as of 9/2019
end

function p.iccuLink( id )
	--P396's format regex: \D{2}[A-Z0-3]V\d{6} (e.g. CUBV039952)
	if not id:match( '^%u%u[A-Z0-3]V%d%d%d%d%d%d' ) then
		return false
	end
	return '[https://opac.sbn.it/nome/'..id..' '..id..']'..p.getCatForId( 'ICCU' ) end

function p.selibrLink( id )
	--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..' '..id..']'..p.getCatForId( 'SELIBR' )
end

function p.sikartLink( id )
	--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 '..id..']'..p.getCatForId( 'SIKART' ) --no https as of 9/2019
end

function p.snacLink( id )
	--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..' '..id..']'..p.getCatForId( 'SNAC-ID' )
end

function p.sudocLink( id )
	--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..' '..id..']'..p.getCatForId( 'SUDOC' )
end

function p.s2authoridLink( id )
	--P4012's format regex: [1-9]\d* (e.g. 1796130)
	if not id:match( '^[1-9]%d*$' ) then
		return false
	end
	return '[https://www.semanticscholar.org/author/'..id..' '..id..']'..p.getCatForId( 'Semantic Scholar author' ) --special category name
end

function p.ta98Link( id )
	--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
	return '[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='..id..' '..id..']'..p.getCatForId( 'TA98' )
end

function p.tdviaLink( id )
	--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..' '..id..']'..p.getCatForId( 'TDVİA' )
end

function p.teLink( id )
	--P1693's format regex: E[1-8]\.\d{1,2}\.\d{1,2}\.\d{1,2}\.\d{1}\.\d{1}\.\d{1,3} (e.g. E1.23.45.67.8.9.0)
	local e1, e2 = id:match( '^E([1-8])%.(%d%d?)%.%d%d?%.%d%d?%.%d%.%d%.%d%d?%d?$' )
	if not e1 then
		return false
	end
	local TEnum = 'TEe0'..e1 --no formatter URL in WD, probably due to this complexity
	if e1 == '5' or e1 == '7' then
		if #e2 == 1 then e2 = '0'..e2 end
		TEnum = TEnum..e2
	end
	return '[http://www.unifr.ch/ifaa/Public/EntryPage/ViewTE/'..TEnum..'.html '..id..']'..p.getCatForId( 'TE' )
end

function p.tepapaLink( id )
	--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..' '..id..']'..p.getCatForId( 'TePapa' )
end

function p.thLink( id )
	--P1694's format regex: H\d\.\d{2}\.\d{2}\.\d\.\d{5} (e.g. H1.23.45.6.78901)
	local h1, h2 = id:match( '^H(%d)%.(%d%d)%.%d%d%.%d%.%d%d%d%d%d$' )
	if not h1 then
		return false
	end
	local THnum = 'THh'..h1..h2 --no formatter URL in WD, probably due to this complexity
	return '[http://www.unifr.ch/ifaa/Public/EntryPage/ViewTH/'..THnum..'.html '..id..']'..p.getCatForId( 'TH' )
end

function p.tlsLink( id )
	local id2 = id:gsub(' +', '_')
	--P1362's format regex: \p{Lu}[\p{L}\d_',\.\-\(\)\*/–]{3,59} (e.g. Abcd)
	local class = "[%a%d_',%.%-%(%)%*/–]"
	local regex = "^%u"..string.rep(class, 3)..string.rep(class.."?", 56).."$"
	if not mw.ustring.match( id2, regex ) then
		return false
	end
	return '[http://tls.theaterwissenschaft.ch/wiki/'..id2..' '..id..']'..p.getCatForId( 'TLS' ) --no https as of 9/2019
end

function p.troveLink( id )
	--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..' '..id..']'..p.getCatForId( 'Trove' )
end

function p.ukparlLink( id )
	--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..' '..id..']'..p.getCatForId( 'UKPARL' )
end

function p.ulanLink( id )
	--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..' '..id..']'..p.getCatForId( 'ULAN' )
end

function p.uscongressLink( id )
	--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..' '..id..']'..p.getCatForId( 'USCongress' ) --no https as of 9/2019
end

function p.vcbaLink( id )
	--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
	local id2 = id:gsub('\/', '_')
	return '[https://opac.vatlib.it/auth/detail/'..id2..' '..id..']'..p.getCatForId( 'VcBA' )
end

function p.viafLink( id )
	--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
	return '[https://viaf.org/viaf/'..id..' '..id..']'..p.getCatForId( 'VIAF' )
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

function p.matchesWikidataRequirements( itemId, reqs )
	for _, group in ipairs( reqs ) do
		local property = 'P'..group[1]
		local qid = group[2]
		local statements = mw.wikibase.getBestStatements( itemId, property )
		if statements then
			for _, statement in ipairs( statements ) do
				if statement.mainsnak.datavalue then
					if statement.mainsnak.datavalue.value['numeric-id'] == qid then
						return true
	end	end	end	end	end
	return false
end

-- Creates a human-readable standalone wikitable version of p.conf, and tracking categories with page counts, for use in the documentation
function p.docConfTable( frame )
	local wikiTable = '{| class="wikitable sortable"\n'..
					  '! rowspan=2 | Parameter\n'..
					  '! rowspan=2 | Label\n'..
					  '! rowspan=2; data-sort-type=number | Wikidata property\n'..
					  '! colspan=4 | Tracking categories and page counts\n'..
					  '|-\n'..
					  '! [[:קטגוריה:ערכים עם מידע בקרת זהויות|'..       'ערכים]]\n'..
					  '! [[:קטגוריה:דפי משתמש עם מידע בקרת זהויות|'..               'דפי משתמש]]\n'..
					  '! [[:קטגוריה:דפים שונים עם מידע בקרת זהויות|'..      'דפים]]\n'..
					  '! [[:קטגוריה:ערכים עם מידע בקרת זהויות שגוי|'..'מזהים שגויים]]\n'..
					  '|-\n'
	
	local lang = mw.getContentLanguage()
	for _, conf in pairs( p.conf ) do
		local param, link, pid = conf[1], conf[2], conf[3]
		local category = conf.category or param
		local args = { id = 'f', pid }
		local wpl = frame:expandTemplate{ title = 'Wikidata property link', args = args }
		--cats
		local articleCat = 'Wikipedia articles with '..category..' identifiers'
		local userCat =    'User pages with '..category..' identifiers'
		local miscCat =    'Miscellaneous pages with '..category..' identifiers'
		local faultyCat =  'Wikipedia articles with faulty '..category..' identifiers'
		--counts
		local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )
		local userCount =    lang:formatNum( mw.site.stats.pagesInCategory(userCat, 'pages') )
		local miscCount =    lang:formatNum( mw.site.stats.pagesInCategory(miscCat, 'pages') )
		local faultyCount =  lang:formatNum( mw.site.stats.pagesInCategory(faultyCat, 'pages') )
		--concat
		wikiTable = wikiTable..'\n'..
					'|-\n'..
					'||'..param..
					'||'..link..
					'||data-sort-value='..pid..'|'..wpl..
					'||style="text-align: right;"|[[:Category:'..articleCat..'|'..articleCount..']]'..
					'||style="text-align: right;"|[[:Category:'..   userCat..'|'..   userCount..']]'..
					'||style="text-align: right;"|[[:Category:'..   miscCat..'|'..   miscCount..']]'..
					'||style="text-align: right;"|[[:Category:'.. faultyCat..'|'.. faultyCount..']]'
	end
	return wikiTable..'\n|}'
end

--[[==========================================================================]]
--[[                              Configuration                               ]]
--[[==========================================================================]]

-- If a specific "(identifier) redirect" exists for an identifier, please route through this particular redirect rather than linking directly to the target page. This reduces clutter in "What links here" and improves reverse lookup of articles where a manifestation of this particular identifier is used.

-- Check that the Wikidata item has this property-->value before adding it
local reqs = {}

-- Parameter format: { 'parameter name', 'label', propertyId # in Wikidata, formatting/validation function }
p.conf = {
	{ 'ICIA', '[[מרכז המידע לאמנות ישראלית|ICIA]]', 1736, p.iciaLink },
	{ 'NLIj9u', '[[הספרייה הלאומית|NLI]]', 8189, p.nliLinkNew },
	{ 'NLI', '[[הספרייה הלאומית|NLI]]', 949, p.nliLink },
	{ 'AAG', '[[גלריית האומנות טואי או טאמאקי באוקלנד|AAG]]', 3372, p.aagLink },
	{ 'ACM-DL', '[[Association for Computing Machinery#Portal and Digital Library|ACM DL]]', 864, p.acmLink },
	{ 'ADB', '[[Australian Dictionary of Biography|ADB]]', 1907, p.adbLink },
	{ 'AGSA', '[[Art Gallery of South Australia|AGSA]]', 6804, p.agsaLink },
	{ 'autores.uy', '[[autores.uy]]', 2558, p.autoresuyLink },
	{ 'AWR', '[[Australian Women\'s Register|AWR]]', 4186, p.awrLink },
	{ 'BALaT', '[[Royal Institute for Cultural Heritage#Online artworks pages|BALaT]]', 3293, p.balatLink },
	{ 'BIBSYS', '[[BIBSYS]]', 1015, p.bibsysLink },
	{ 'Bildindex', '[[Marburg Picture Index|Bildindex]]', 2092, p.bildLink },
	{ 'BNC', '[[הספרייה הלאומית של צ&#39;ילה|BNC]]', 1890, p.bncLink },
	{ 'BNE', '[[הספרייה הלאומית של ספרד|BNE]]', 950, p.bneLink },
	{ 'BNF', '[[הספרייה הלאומית של צרפת|BnF]]', 268, p.bnfLink },
	{ 'Botanist', '[[Author citation (botany)|Botanist]]', 428, p.botanistLink },
	{ 'BPN', '[[Biografisch Portaal|BPN]]', 651, p.bpnLink },
	{ 'CANTIC', '[[מיון השמות והתארים של קטלוניה|CANTIC]]', 1273, p.canticLink },
	{ 'CINII', '[[CiNii]]', 271, p.ciniiLink },
	{ 'CWGC', '[[CWGC (identifier)|CWGC]]', 1908, p.cwgcLink },
	{ 'DAAO', '[[Dictionary of Australian Artists|DAAO]]', 1707, p.daaoLink },
	{ 'DBLP', '[[DBLP]]', 2456, p.dblpLink },
	{ 'DSI', '[[מאגר המאיירים המדעיים של שטוטגרט 1450–1950|DSI]]', 2349, p.dsiLink },
	{ 'FNZA', '[[:d:Property:P6792|FNZA]]', 6792, p.fnzaLink },
	{ 'GND', '[[קובץ בקרה משולב|GND]]', 227, p.gndLink },
	{ 'HDS', '[[מילון היסטורי של שווייץ|HDS]]', 902, p.hdsLink },
	{ 'IAAF', '[[התאחדות האתלטיקה הבין-לאומית|World Athletics]]', 1146, p.iaafLink },
	{ 'ICCU', '[[המכון המרכזי לקטלוג אחיד|ICCU]]', 396, p.iccuLink }, --formerly SBN
	{ 'ISNI', '[[תקן בין-לאומי למזהי שמות|ISNI]]', 213, p.isniLink },
	{ 'Joconde', '[[Joconde]]' , 347, p.jocondeLink },
	{ 'KULTURNAV', '[[KulturNav]]', 1248, p.kulturnavLink },
	{ 'LCCN', '[[שיטת ספריית הקונגרס|LCCN]]', 244, p.lccnLink },
	{ 'LIR', '[[מילון היסטורי של שווייץ|LIR]]', 886, p.lirLink },
	{ 'LNB', '[[הספרייה הלאומית של לטביה|LNB]]', 1368, p.lnbLink },
	{ 'Léonore', '[[Base Léonore|Léonore]]', 640, p.leonoreLink },
	{ 'MBA', '[[MusicBrainz]]', 434, p.mbaLink, category = 'MusicBrainz' }, --special category name
	{ 'MBAREA', '[[MusicBrainz]]', 982, p.mbareaLink, category = 'MusicBrainz area' }, --special category name
	{ 'MBI', '[[MusicBrainz]]', 1330, p.mbiLink, category = 'MusicBrainz instrument' }, --special category name
	{ 'MBL', '[[MusicBrainz]]', 966, p.mblLink, category = 'MusicBrainz label' }, --special category name
	{ 'MBP', '[[MusicBrainz]]', 1004, p.mbpLink, category = 'MusicBrainz place' }, --special category name
	{ 'MBRG', '[[MusicBrainz]] release group', 436, p.mbrgLink, category = 'MusicBrainz release group' }, --special category name
	{ 'MBS', '[[MusicBrainz]]', 1407, p.mbsLink, category = 'MusicBrainz series' }, --special category name
	{ 'MBW', '[[MusicBrainz]] work', 435, p.mbwLink, category = 'MusicBrainz work' }, --special category name
	{ 'MGP', '[[פרויקט הגנאלוגיה במתמטיקה|MGP]]', 549, p.mgpLink },
	{ 'NARA', '[[הארכיון הלאומי של ארצות הברית|NARA]]', 1225, p.naraLink },
	{ 'NCL', '[[National Central Library|NCL]]', 1048, p.nclLink },
	{ 'NDL', '[[ספריית הדיאט הלאומית|NDL]]', 349, p.ndlLink },
	{ 'NGV', '[[הגלריה הלאומית של ויקטוריה|NGV]]', 2041, p.ngvLink },
	{ 'NKC', '[[הספרייה הלאומית של צ&#39;כיה|NKC]]', 691, p.nkcLink },
	{ 'NLA', '[[הספרייה הלאומית של אוסטרליה|NLA]]', 409, p.nlaLink },
	{ 'NLG', '[[הספרייה הלאומית של יוון|NLG]]', 3348, p.nlgLink },
	{ 'NLK', '[[הספרייה הלאומית של קוריאה|NLK]]', 5034, p.nlkLink },
	{ 'NLP', '[[הספרייה הלאומית של פולין|NLP]]', 1695, p.nlpLink },
	{ 'NLR', '[[הספרייה הלאומית של רומניה|NLR]]', 1003, p.nlrLink },
	{ 'NSK', '[[הספרייה הלאומית והאוניברסיטאית בזאגרב|NSK]]', 1375, p.nskLink },
	{ 'NTA', '[[הספרייה הלאומית של הולנד|NTA]]', 1006, p.ntaLink },
	{ 'ORCID', '[[זיהוי ORCID|ORCID]]', 496, p.orcidLink },
	{ 'PIC', '[[:d:Q23892012|PIC]]', 2750, p.picLink },
	{ 'RID', '[[ResearcherID]]', 1053, p.ridLink },
	{ 'RERO', '[[רשת הספריות של מערב שווייץ|RERO]]', 3065, p.reroLink },
	{ 'RKDartists', '[[המכון ההולנדי להיסטוריה של האמנות|RKD]]', 650, p.rkdartistsLink },
	{ 'RKDID', '[[המכון ההולנדי להיסטוריה של האמנות|RKDimages ID]]', 350, p.rkdidLink },
	{ 'RSL', '[[הספרייה הממלכתית של רוסיה|RSL]]', 947, p.rslLink },
	{ 'SELIBR', '[[הספרייה הלאומית של שוודיה|SELIBR]]', 906, p.selibrLink },
	{ 'SIKART', '[[SIKART]]', 781, p.sikartLink },
	{ 'SNAC-ID', '[[SNAC]]', 3430, p.snacLink },
	{ 'SUDOC', '[[מערכת התיעוד האוניברסיטאית (צרפת)|SUDOC]]', 269, p.sudocLink },
	{ 'S2AuthorId', '[[Semantic Scholar|S2AuthorId]]', 4012, p.s2authoridLink, category = 'Semantic Scholar author' }, --special category name
	{ 'TA98', '[[Terminologia Anatomica|TA98]]', 1323, p.ta98Link },
	{ 'TDVİA', '[[האנציקלופדיה של האסלאם|TDVİA]]', 7314, p.tdviaLink },
	{ 'TE', '[[Terminologia Embryologica|TE]]', 1693, p.teLink },
	{ 'TePapa', '[[המוזיאון של ניו זילנד טה פאפה טונגרווה|TePapa]]', 3544, p.tepapaLink },
	{ 'TH', '[[Terminologia Histologica|TH]]', 1694, p.thLink },
	{ 'TLS', '[[Theaterlexikon der Schweiz|TLS]]', 1362, p.tlsLink },
	{ 'Trove', '[[Trove]]', 1315, p.troveLink }, --formerly NLA-person
	{ 'UKPARL', '[[UKPARL]]', 6213, p.ukparlLink },
	{ 'ULAN', '[[Union List of Artist Names|ULAN]]', 245, p.ulanLink },
	{ 'USCongress', '[[המדריך הביוגרפי של הקונגרס של ארצות הברית|US Congress]]', 1157, p.uscongressLink },
	{ 'VcBA', '[[ספריית הוותיקן|VcBA]]', 8034, p.vcbaLink },
	{ 'VIAF', '[[VIAF]]', 214, p.viafLink },
	{ 'WORLDCATID', '[[WorldCat]]', 7859, nil },
}

-- Legitimate aliases to p.conf, for convenience
-- Format: { 'alias', 'parameter name in p.conf' }
p.aliases = {
	{ '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:Wikipedia 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
	local elements = {} --create/insert rows later
	local worldcatCat = ''
	local suppressedIdCat = ''
	local deprecatedIdCat = ''
	
	--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 = '[[קטגוריה:ערכים עם מזהה בקרת זהויות שכבר לא בשימוש|'..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

	--experiment as requested in מזנון	
	if (parentArgs['purple'] == 'yes') then
		itemId = parentArgs['qid']
	end
	
	--Wikidata fallback if requested
	if itemId then
		for _, params in ipairs( p.conf ) do
			if params[3] > 0 then
				local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
				if val == nil or val == '' then
					local canUseWikidata = nil
					if reqs[params[1]] then
						canUseWikidata = p.matchesWikidataRequirements( itemId, reqs[params[1]] )
					else
						canUseWikidata = true
					end
					if canUseWikidata then
						local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[3] )
						if wikidataIds[1] then
							if val == '' and (namespace == 0 or testcases) then
								suppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|'..params[1]..']]'
							else
								parentArgs[params[1]] = wikidataIds[1]
	end	end	end	end	end	end	end

	
	-- dont show both NLI and NLIj9u
	if parentArgs.NLI and parentArgs.NLIj9u then
		parentArgs.NLI = ''
	end
	
	--Configured rows
	local rct = 0
	for _, params in ipairs( p.conf ) do
		local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
		if val and val ~= '' and type(params[4]) == 'function' then
			table.insert( elements, p.createRow( params[1], params[2]..':', val, params[4]( val ), true, params.category ) )
			rct = rct + 1
		end
	end

	--WorldCat
	local worldcatId = parentArgs['worldcatid'] or parentArgs['WORLDCATID']
	if worldcatId and worldcatId ~= '' then --if WORLDCATID present & unsuppressed
		table.insert( elements, p.createRow( 'WORLDCATID', '', worldcatId, '[[WorldCat]]: [https://www.worldcat.org/identities/'..mw.uri.encode(worldcatId, 'PATH')..' '..worldcatId..']', false ) ) --Validation?
		worldcatCat = p.getCatForId( 'WORLDCATID' )
	elseif 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( elements, p.createRow( 'VIAF', '', viafId, '[[WorldCat]] (עם VIAF): [https://www.worldcat.org/identities/containsVIAFID/'..viafId..' '..viafId..']', false ) )
			if namespace == 0 then 
				worldcatCat = '[[קטגוריה:ויקיפדיה: ערכים עם מזהה WorldCat-VIAF]]'
			end
		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( elements, p.createRow( 'LCCN', '', lccnId, '[[WorldCat]] (עם LCCN): [https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' '..lccnIdFmtd..']', false ) )
				if namespace == 0 then
					worldcatCat = '[[קטגוריה:ויקיפדיה: ערכים עם מזהה WorldCat-LCCN]]'
				end
			end
		end
	elseif worldcatId == '' then --if WORLDCATID suppressed
		suppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|WORLDCATID]]'
	end
	
	local Navbox = require('Module:Navbox')
	local elementsCat = ''
	if (rct == 0 or rct >= 25) and (namespace == 0) then
		local eCat = 'בקרת זהויות עם '..rct..' פריטים'
		elementsCat  = '[[Category:'..eCat..']]'..p.redCatLink(eCat)
	end
	
	local outString = ''
	if #elements > 0 then
		local args = { pid = 'identifiers' } -- #target the list of identifiers
		if testcases and itemId then args = { pid = 'identifiers', qid = itemId } end --expensive
		local pencil = ''
		if itemId then
			local pencilLink = mw.title.makeTitle( 0, itemId, '', 'wikidata' ):fullUrl('uselang=he')
			pencil = mw.ustring.format(' [[File:Blue pencil RTL.svg|15px|link=%s|עריכת הנתון בוויקינתונים]]', pencilLink)
		end		
		outString = Navbox._navbox( {
			name  = 'בקרת זהויות',
			navboxclass = 'authority-control',
			bodyclass = 'hlist',
			group1 = '[[עזרה:בקרת זהויות|בקרת זהויות]]'..pencil,
			list1 = '<div dir="ltr">\n' .. table.concat( elements ) .. '</div>'
			} )
	end

	local auxCats = worldcatCat .. elementsCat .. suppressedIdCat .. deprecatedIdCat
	if testcases then
		auxCats = mw.ustring.gsub(auxCats, '(%[%[)(Category)', '%1:%2') --for easier checking
	end
	outString = outString .. auxCats
	if namespace ~= 0 then
		outString = mw.ustring.gsub(outString, '(%[%[)(Category:Wikipedia articles)', '%1:%2') --by definition
	end
	
	return outString
end

return p