Bước tới nội dung

Mô đun:Cite taxon

Bách khoa toàn thư mở Wikipedia
require('strict')local p = {}local data = {}         local templateArgs = {}  -- contains arguments passed to cite weblocal target = {}        -- short cut to target table, e.g. fishbase, cof, etclocal function firstToUpper(str)    return (str:gsub("^%l", string.upper))end-- define citation template and custom parameters for various sources--####################### Default functions ##########################data.default = {}-- currently being tested on Avibase, but Fossilworks, Tropicos, FNA and a few others are candidatesdata.default.id = function (id, source)	local title = id	local url = source.customArgs['baseURL'] .. (source.customArgs['searchStr'] or "") .. id	return title, urlenddata.default.error = function()	return "Minimal requirement is two of id, url and title parameters"enddata.default.search = function (search, source)	local title = "Search for " .. search	local url = source.customArgs['baseURL'] .. source.customArgs['searchString'] .. search .. source.customArgs['searchSuffix'] 	return title, urlend--[[ handling for ID only (unused, original concept) p.genericIdCitation = function(frame, title, url)    if not templateArgs['id'] then return "no id parameter detected" end     templateArgs['url']= target.CustomArgs['baseURL'] .. target.CustomArgs['searchStr'] .. templateArgs['id']        return p.citeWeb(frame, title, url)end]]--####################### FISH #####################################--======================== Fishbase =================================data.fishbase = {	citationArgs = {	['editor1-last']="Froese",  ['editor1-first']="Rainer", ['editor1-link']="Rainer Froese",	['editor2-last']="Pauly",  ['editor2-first']="Daniel",   	--['last-author-amp'] ="yes",    ['website'] = "[[Fishbase]]",	--['publisher'] = ""	},	customArgs = { exclude= "order, family,genus, species, subspecies, 1, 2, 3, 4",	               baseURL = "http://www.fishbase.org/",	               defaultTitle = "Search FishBase"	},}data.fishbase.species = function(genus, species, subspecies)		local title = genus .. " " .. species		local url = data.fishbase.customArgs['baseURL'] 		            .. "summary/SpeciesSummary.php?genusname=" .. genus .. "&speciesname=" .. species		if subspecies then 			url = url .. "+" .. subspecies			title = title .. " " .. subspecies		end               		title =  "''" .. title  .. "''"		return title, urlenddata.fishbase.genus = function(genus)		local title = "Species in genus ''" .. firstToUpper(genus) .. "''"		local url = data.fishbase.customArgs['baseURL'] ..  "identification/SpeciesList.php?genus=" .. genus   		return title, urlenddata.fishbase.order = function(order) 		local title =  "Order " .. firstToUpper(order)		local url = data.fishbase.customArgs['baseURL'] ..  "Summary/OrdersSummary.php?order=" .. order		return title, urlenddata.fishbase.family = function(family) 		local title = "Family " .. firstToUpper(family)		local url = data.fishbase.customArgs['baseURL'] ..  "Summary/FamilySummary.php?family=" .. family		return title, urlenddata.fishbase.error = function()   	return "No recognised taxon options: order, family, genus, species, subspecies."enddata.fishbase.custom = function()        --TODO decide what to do with default date    local version = "April 2006 version"  -- Should we have a default (probably not)    if templateArgs['month'] then version = templateArgs['month'] end    if templateArgs['year'] then version = templateArgs['year'] .. " version" end    if templateArgs['month'] then version = templateArgs['month'] .. " " .. version end    templateArgs['version'] = versionend--================================ Catalog of Fishes ================================================data.cof = {	citationArgs = {		--baseURL = "http://researcharchive.calacademy.org/research/ichthyology/catalog/fishcatget.asp?",		['editor1-last']="Eschmeyer",  ['editor1-first']="William N.", ['editor1-link']="William N. Eschmeyer",		['editor2-last']="Fricke",  ['editor2-first']="Ron",   		['editor3-last']="van der Laan",  ['editor3-first']="Richard", 		['name-list-style'] ="amp",	    ['website'] = "[[Catalog of Fishes]]",		['publisher'] = "[[California Academy of Sciences]]"	},	customArgs = { exclude= "family,genus,species,genid,spid,id,list,1,2,3",	               baseURL = "http://researcharchive.calacademy.org/research/ichthyology/catalog/fishcatget.asp?",	               defaultTitle = "CAS - Eschmeyer's Catalog of Fishes"	}}data.cof.species = function(genus, species, subspecies)		local taxon = genus .. " " .. species	    local url = data.cof.customArgs['baseURL'] ..  'tbl=species&genus=' .. genus .. '&species=' .. species	    local title = "Species related to " .. "''" .. firstToUpper(taxon) .. "''"        -- .. "" species synonyms"	    return title, urlenddata.cof.genus  = function(genus)	    local url = data.cof.customArgs['baseURL'] .. 'tbl=species&genus=' .. genus	    local title = "Species in the genus ''" .. firstToUpper(genus) .. "''" 	    return title, urlend       -- note the family works with subfamilies using &family=SUBFAMILYdata.cof.family  = function(family)	    local list = templateArgs['list'] or "genus"	    local url = data.cof.customArgs['baseURL'] .. 'tbl=' .. list .. '&family=' .. family        local title = "Species"        if list == "genus" then  title = "Genera" end         title = title .. ' in the family ' .. firstToUpper(family)          return title, urlenddata.cof.genid = function(genid)   	    local searchStr =  "genid" .. '=' .. genid        local title =  searchStr        local url = data.cof.customArgs['baseURL'] .. searchStr        return title, urlenddata.cof.spid = function(spid)   	    local searchStr =  "spid" .. '=' .. spid        local title =  searchStr        local url = data.cof.customArgs['baseURL'] .. searchStr        return title, urlenddata.cof.error = function()    	return "Error. No recognised option set by template (need one of family, genus, species (also requires genus), spid, or genid"end--======================Fishes of the World 5===============================	data.fotw5 = {	citeTemplate = "Cite book",	citationArgs = {	    --['website'] = "[[]]",		first1 = "Joseph S.", last1 = "Nelson",		first2="Terry C.", last2="Grande",		first3="Mark V. H.", last3="Wilson", 		--work = "Fishes of the World (work)",		title = "Fishes of the World", edition="5th", year = 2016,		publisher ="John Wiley and Sons", location="Hoboken",		isbn = "978-1-118-34233-6", doi="10.1002/9781119174844" ,	},	customArgs = {exclude="gb-page,q,dq,1",	              baseURL = "https://onlinelibrary.wiley.com/doi/book/10.1002/9781119174844", -- online library	              defaultTitle = "Fishes of the World",	              altTitle = "[[Fishes of the World]]",               -- wikilinked for when using chapter/section title	              altURL = "https://sites.google.com/site/fotw5th/",  -- classification	},	GoogleBooks = { baseURL = "https://books.google.co.uk/books?id=",		            id = "E-MLDAAAQBAJ",		            defaultPage = "&pg=PP1"	}}data.fotw5.default2 = function(targs)     local title = data.fotw5.citationArgs['work']     local url = data.fotw5.customArgs['baseURL']     local chapterParams =  { title      = title,     	                    ['chapter-url']= data.fotw5.customArgs['googleBooks']     }     --return title, url, chapterParamsenddata.BentonVP4 = {	citeTemplate = "Cite book",	citationArgs = {		first1 = "Michael J.", last1 = "Benton",		title = "Vertebrate Palaeontology", edition="4th", year = 2014,		publisher ="John Wiley & Sons", 		isbn = "978-1-118-40764-6", 	},	customArgs = {exclude="gb-page,q,dq,1",	              --baseURL = "",	              defaultTitle = "Vertebrate Palaeontology",	              altTitle = "[[Vertebrate Palaeontology]]"  -- wikilinked for when using chapter/section title	},	GoogleBooks = { baseURL = "https://books.google.co.uk/books?id=",		            id = "qak-BAAAQBAJ",		            defaultPage = "&pg=PP1",	}}--====================TODO FishWisePro==================================================	data.fishwisepro = {	citationArgs = {	    ['website'] = "[[FishWisePro]]",	},	customArgs = {exclude="family,genus,species,1",	              baseURL = ""	}}-- #################### AMPHIBIA and REPTILES ###############################-- ================= Amphibian Species of the World (ASW6)--[[Recommended citation: Frost, Darrel R. 2019. Amphibian Species of the World: an Online Reference. Version 6.0 (Date of access). Electronic Database accessible at http://research.amnh.org/herpetology/amphibia/index.html. American Museum of Natural History, New York, USA.    URL for family page: http://research.amnh.org/vz/herpetology/amphibia/Amphibia/Anura/Allophrynidae           baseURL      = http://research.amnh.org/vz/herpetology/amphibia/           suffix       = Amphibia/Anura/Allophrynidae           note: needs the whole hierarchy (except the superfamily which is optional)    Template for main taxonomic listing: {{BioRef|ASW6 |title=Amphibia |year=2019 |url=http://research.amnh.org/herpetology/amphibia/index.html |access-date=27 September 2019}}    SEARCH http://research.amnh.org/vz/herpetology/amphibia/amphib/basic_search?basic_query=Atelopus&stree=&stree_id=           searchSuffix = amphib/basic_search?basic_query=Atelopus&stree=&stree_id=    SEARCH http://research.amnh.org/vz/herpetology/amphibia/content/search?taxon=Allophryn*&subtree=&subtree_id=&english_name=&author=&year=&country=           searchSuffix = /content/search?taxon=Allophryn*&subtree=&subtree_id=&english_name=&author=&year=&country=           minimul      = /content/search?taxon=Allophryn*&subtree    ]]data.ASW6 ={	citationArgs = {		website  ="Amphibian Species of the World, an Online Reference.",		version  = "Version 6.0",		publisher = "American Museum of Natural History, New York",		['last1']="Frost",  ['first1']="Darrel R.", ['author1-link']="Darrel R. Frost",	},	customArgs = { exclude = "taxon,species,genus,family, superfamily,1,2,3",	               baseURL = "http://research.amnh.org/herpetology/amphibia/",	               defaultSuffix = "index.html",	               defaultTitle = "ASW Home"  	}}data.ASW6.species = function(genus, species, subspecies)		-- search for genus+species  ()	    local title = "Search for taxon: " .. "''" .. genus .. " " .. species .. "''"			 	--local search = ""?action=names&taxon="" -- old version (pre ASW6)		 	--local search =  "amphib/basic_search?basic_query="  -- basic search	 	local search = "content/search?taxon="              -- guided search for taxon name		 			local url = data.ASW6.customArgs['baseURL'] .. search  -- .. genus .. '+AND+' .. species		 	            .. '&quot;' .. genus .. '+' .. species .. '&quot;'		return title, urlenddata.ASW6.genus = function(genus)	return data.ASW6.taxon(genus)  -- use genus as alias of taxonenddata.ASW6.taxon = function(taxon)			    local title = "Search for Taxon: " .. taxon	    local url= data.ASW6.customArgs['baseURL'] .. "content/search?taxon=" .. taxon	    return title, urlenddata.ASW6.family = function(family) 		local order = data.ASW6.checkOrder(family)		local url= data.ASW6.customArgs['baseURL'] .. "Amphibia/" .. order .. "/" .. firstToUpper(family)		local title = firstToUpper(family) 		return title, urlenddata.ASW6.checkOrder = function(family)	local gymnophiona={ "Caeciliidae", "Chikilidae", "Dermophiidae", "Herpelidae", "Ichthyophiidae", "Grandisoniidae", "Indotyphlidae", "Rhinatrematidae", "Scolecomorphidae", "Siphonopidae", "Typhlonectidae" }    local caudata = { "Ambystomatidae", "Amphiumidae", "Cryptobranchidae", "Hynobiidae", "Plethodontidae", "Proteidae", "Rhyacotritonidae", "Salamandridae", "Sirenidae" }       for k,v in pairs(caudata) do    	if v == family then return "Caudata" end    end    for k,v in pairs(gymnophiona) do    	if v == family then return "Gymnophiona" end    end        return "Anura"end   --============================= AmphibiaWeb ===================================--[[   Citation: AmphibiaWeb. 2019. <https://amphibiaweb.org> University of California, Berkeley, CA, USA. Accessed 27 Sep 2019.       Code:     {{BioRef|amphibiaweb |title=Amphibia |year=2019 |url=https://amphibiaweb.org/taxonomy/AW_FamilyPhylogeny.html |access-date=27 September 2019}}--]]data.amphibiaweb = {	citationArgs = {		website  = "AmphibiaWeb",		publisher = "University of California, Berkeley",		--['editor1-last']="",  ['editor1-first']="", ['editor1-link']="",	},    customArgs = { exclude = "taxon,species,genus,family,1,2,3",	               baseURL = "https://amphibiaweb.org/",	               defaultSuffix = "taxonomy/AW_FamilyPhylogeny.html",	               defaultTitle = "AmphibiaWeb Family Taxonomy"	}}data.amphibiaweb.species = function (genus, species, subspecies)		local title = "''" .. genus .. " " .. species .. "''"		 	--https://amphibiaweb.org/cgi/amphib_query?where-genus=Altiphrynoides&where-species=malcolmi		local url = data.amphibiaweb.customArgs['baseURL'] .. "cgi/amphib_query?rel-genus=equals&where-genus="		 	                   .. genus .. "&rel-species=equals&where-species=" .. species		return title, urlenddata.amphibiaweb.genus = function (genus)		local title = "''" .. genus ..  "''"		 	--https://amphibiaweb.org/cgi/amphib_query?where-genus=Altiphrynoides&where-species=malcolmi		local url = data.amphibiaweb.customArgs['baseURL'] .. "cgi/amphib_query?rel-genus=equals&where-genus=" 		 	                .. genus .. "&include_synonymies=Yes&show_photos=Yes"		return title, urlend	data.amphibiaweb.family = function (family)		-- if family use standardised url		 local url = data.amphibiaweb.customArgs['baseURL'] .. "lists/" .. firstToUpper(templateArgs['family']) .. ".shtml"		 local title = templateArgs['family']		 return title, urlend	--=========================== The Reptile Databasedata.reptileDB = {	-- http://reptile-database.reptarium.cz/species?genus=Epacrophis&species=boulengeri	-- recommended citation: Uetz, P., Freed, P. & Hošek, J. (eds.) (2019) The Reptile Database, http://www.reptile-database.org, accessed [insert date here]	citationArgs = {		--website="reptile-database.org",		website="[[The Reptile Database]]",		['editor1-last']="Uetz",  ['editor1-first']="P.", --['editor1-link']="Peter Uetz",		['editor2-last']="Freed",  ['editor2-first']="P.", 		['editor3-last']="Hošek",  ['editor3-first']="J.", 		--year=2019			},	customArgs = { exclude = "taxon,species,genus,family,1,2,3",	               baseURL = "http://reptile-database.reptarium.cz/"	}}data.reptileDB.species = function(genus, species)	    local title = "''" .. genus .. " " .. species .. "''"	    --http://reptile-database.reptarium.cz/species?genus=Loxocemus&species=bicolor		local url = data.reptileDB.customArgs['baseURL'] .. "species?genus=" .. genus .. "&species=" .. species		return  title, urlenddata.reptileDB.genus = function(genus)	    local title = "''" .. genus .. "''" 	    --http://reptile-database.reptarium.cz/advanced_search?genus=Malayopython&submit=Search	    local url = data.reptileDB.customArgs['baseURL'] .. "advanced_search?genus=" .. genus .. "&exact%5B0%5D=taxon&submit=search"		return  title, urlenddata.reptileDB.family = function(family)       return data.reptileDB.taxon(family)enddata.reptileDB.order = function(order)       return data.reptileDB.taxon(order)enddata.reptileDB.taxon = function(taxon)	    local title = taxon		--http://reptile-database.reptarium.cz/advanced_search?taxon=Viperidae&exact%5B0%5D=taxon&submit=Search		local url = data.reptileDB.customArgs['baseURL'] .. "advanced_search?taxon=" .. taxon .. "&exact%5B0%5D=taxon&submit=search"		return  title, urlend	   --################################### BIRDS ########################################--====================Handbook of the Birds of the World Alive (HBW Alive)==============data.HBWalive = {         	citationArgs = {		website="[[Handbook of the Birds of the World|Handbook of the Birds of the World Alive]]", 		publisher="Lynx Edicions"	},	customArgs = { exclude="order,family,genus,species,taxon,id,1",	               baseURL = "https://www.hbw.com/",	               defaultSuffix = "family/home",	               defaultTitle = "Family | HBW Alive"	               	}}--############################## HBW ALIVE #########################################   -- family and species entries have mix of common name and taxon name so cannot be prempted;    -- must use title + url (which uses default functions in this module)data.HBWalive.order = function(order)    	local title = "Order " .. firstToUpper(order)    	--https://www.hbw.com/order/struthioniformes    	local url = target.customArgs['baseURL'] .. "order/" .. order    	return title, urlend --[[======================IOC World Bird List==========================	        Gill, F & D Donsker (Eds). 2019. IOC World Bird List (v9.2). doi :  10.14344/IOC.ML.9.2.	        Gill F, D Donsker & P Rasmussen  (Eds). 2020. IOC World Bird List (v10.2). doi :  10.14344/IOC.ML.10.1.]]data.IOC = {         	citationArgs = {		website="[[IOC World Bird List]]", 	--	version="Version 9.2",                               -- shouldn't default; should be hardcode so it doesn't change		['editor1-last']="Gill",  ['editor1-first']="F.",  ['editor1-link']="Frank Gill (ornithologist)",		['editor2-last']="Donsker",  ['editor2-first']="D.",		['editor3-last']="Rasmussen",  ['editor3-first']="P.",  -- TODO only show from version 10.1 onwards	--	doi = "10.14344/IOC.ML.9.2",                          -- this changes by version number and is not a useful part of the cictation		publisher="International Ornithological Congress"	},	customArgs = { exclude="order,family,genus,species,taxon,id,1",	               baseURL = "https://www.worldbirdnames.org/",	               defaultSuffix = "",	               defaultTitle = "IOC World Bird List: Welcome"	               	},}data.IOC.version = function()	local version =  templateArgs['version'] 	local old = false	if version then		version = string.gsub( version, "[Vv]ersion ", "")     	local versionNumber = tonumber(version)    	if versionNumber < 10.1 then	    	old = true		end	else		local Date = require('Module:Date')._Date		if Date(templateArgs['access-date']) < Date('1 January 2020') then			old = true		end	end		if old then	    	data.IOC.citationArgs['editor3-last'] = nil		    data.IOC.citationArgs['editor3-first'] = nil	endenddata.IOC.order = function(order) 	    data.IOC.version()        local IOCorders = {Struthioniformes='ratites',Rheiformes='ratites',Apterygiformes='ratites',Casuariiformes='ratites',Tinamiformes='ratites',Galliformes='megapodes',Anseriformes='waterfowl',Caprimulgiformes='nightjars',Apodiformes='swifts',Musophagiformes='turacos',Otidiformes='turacos',Cuculiformes='turacos',Mesitornithiformes='turacos',Pterocliformes='turacos',Columbiformes='pigeons',Gruiformes='flufftails',Podicipediformes='grebes',Phoenicopteriformes='grebes',Charadriiformes='sandpipers',Eurypygiformes='loons',Phaethontiformes='loons',Gaviiformes='loons',Sphenisciformes='loons',Procellariiformes='loons',Ciconiiformes='storks',Suliformes='storks',Pelecaniformes='pelicans',Opisthocomiformes='raptors',Accipitriformes='raptors',Strigiformes='owls',Coliiformes='mousebirds',Leptosomiformes='mousebirds',Trogoniformes='mousebirds',Bucerotiformes='mousebirds',Coraciiformes='rollers',Piciformes='woodpeckers',Cariamiformes='falcons',Falconiformes='falcons',Psittaciformes='parrots',	               Passeriformes='nz_wrens'} -- passeriformes link not very useful    	local title = "Order " .. firstToUpper(order)    	local url = data.IOC.customArgs['baseURL'] .. "/bow/" .. IOCorders[order]    	return title, url    	enddata.IOC.family = function(family)	    data.IOC.version()	    local IOCfamilies = { Struthionidae = {"ratites", 4}, Alcippeidae = {"babblers", 24989 } }      -- temporary partial list for testing    	    	local title = "Family " .. firstToUpper(family)    	--https://www.worldbirdnames.org/Family/Struthionidae    	local url = data.IOC.customArgs['baseURL'] .. "Family/" .. family   -- old version (might be resurrected by IOC)    	    	-- https://www.worldbirdnames.org/new/bow/babblers/#1338626516R24989    	if IOCfamilies[family] then                                             -- test version local partial list    		url = data.IOC.customArgs['baseURL'] .. "new/bow/" ..  IOCfamilies[family][1] .. "/#1338626516R" .. IOCfamilies[family][2]    	end    	return title, urlend    data.IOC.default = function( title, url) 	    data.IOC.version()	    return title, urlenddata.BOW = {         	citationArgs = {		website="Birds of the World Online", 	--	doi = "",                          	--	['last1']="Winkler",  ['first1']="David W.",              -- are these always the authors in version 1? no, perhaps for family page	--	['last2']="Billerman",  ['first2']="Shawn M.",	--	['last3']="Lovette",  ['first3']="Irby J.",  	--	['editor1-last']="Billerman",  ['editor1-first']="S. M.",  --['editor1-link']="",	--	['editor2-last']="Keeney",  ['editor2-first']="B. K.",	--	['editor3-last']="Rodewald",  ['editor3-first']="P. G.",  	--    ['editor4-last']="Schulenberg",  ['editor4-first']="T. S.",	--    ['version'] = 1,   ['year'] = 2020,                                             -- may not want to default		publisher="[[Cornell Lab of Ornithology]], Ithaca, NY."	},	customArgs = { exclude="citation,make,order,family,genus,species,taxon,id,1",	               baseURL = "https://birdsoftheworld.org/bow/species/",	               defaultSuffix = "",	               defaultTitle = "Explore Taxonomy"	               	},}-- function not needed of not adding anything elsedata.BOW.default2 =  function( title, url)  	 --data.BOW.citationArgs['version'] = "Version 1"	 mw.addWarning("testing BOW.default function")	 return title, urlend-- id works with the default function data.default.id  (id, source)data.BOW.id2 = function( id)    local url = data.IOC.customArgs['baseURL'] ..id   local title = "BOW id="  .. id end--[[ make BOW to parse standard citation, {{BioRef|BOW|citation=CITATION}}    vesrion 1 (family): Winkler, D. W., S. M. Billerman, and I.J. Lovette (2020). Bulbuls (Pycnonotidae), version 1.0. In Birds of the World                         (S. M. Billerman, B. K. Keeney, P. G. Rodewald, and T. S. Schulenberg, Editors). Cornell Lab of Ornithology, Ithaca, NY, USA.                         https://doi.org/10.2173/bow.pycnon4.01    version 2 (species): Limparungpatthanakij , W. L., L. Fishpool, and J. Tobias (2020). Buff-vented Bulbul (Iole crypta), version 2.0. In Birds of the World                         (S. M. Billerman and B. K. Keeney, Editors). Cornell Lab of Ornithology, Ithaca, NY, USA.                         https://doi.org/10.2173/bow.buvbul1.02]]data.BOW.citation =  function( value)  	local citation  = templateArgs['citation']     data.BOW.citationArgs['year']  = citation:match ('^%D+(%d%d%d%d)')    data.BOW.citationArgs['doi']  = citation:match ('10%.2173/bow%..+')                           -- https://doi.org/10.2173/bow.pycnon4.01    --data.BOW.citationArgs['version']  = citation:match ('version %d%.%d')                       -- version applies to page, not whole BOW    local title = citation:match ('%d%d%d%d%)%.(.*, version %d%.%d)');                            -- include version number in title    local suffix = citation:match ('10%.2173/bow%.(.+%d)%.');                                     -- https://doi.org/10.2173/bow.pycnon4.01    local version = "/cur/"                                                                       -- for the current version    version = citation:match ('version (%d%.%d)')                                                 -- for the cited version    local url = data.BOW.customArgs['baseURL']  .. suffix .. '/'  .. version .. '/'         title = title:gsub( '%((%D+) (%D+)%)' , "(''%1 %2'')")        local authors = citation:match ('^(%D+) %(%d%d%d%d%)')    if authors then           -- split authors with modified code from make cite iucn    	local list = {}    	--mw.addWarning ("author string: " .. authors)    	authors = authors:gsub(", and ", ", ")   -- for 3 or more authors    	authors = authors:gsub(" and ", ", ")     -- for 2 editors      	list = mw.text.split (authors, ',');									    -- split the string on the commas into entries in list		if #list == 0 then			mw.addWarning ("Zero length author list. Please report example of BOW citation at Cite BOW template talk page.");			data.BOW.citationArgs['author'] = authors 					        	-- no 'names' of the proper form; return the original as a single |author= parameter		else			for i, name in ipairs (list) do											-- for each author in list 			    if i==1 then                                --note the first name has last name followed by initials after comma, so takes fill first two parts of the split			    	data.BOW.citationArgs['last1'] = name			    elseif i==2 then			    	data.BOW.citationArgs['first1'] = name			    elseif i > 2 then			    	data.BOW.citationArgs['last'..i-1] =  name:match ('%s(%a-)$')			    	data.BOW.citationArgs['first'..i-1] =  name:match ('(.+)%s%a-$')			    	--data.BOW.citationArgs['author'..i-1] = nil			    else -- something has gone wrong (use author)			    	data.BOW.citationArgs['author'..i-1] = name 			    end			    if i>1 and 1==2 then					mw.addWarning ("last" .. tostring(i-1)  .. "=" .. data.BOW.citationArgs['last'..i-1])			    	mw.addWarning ("first".. tostring(i-1)  .. "=" .. data.BOW.citationArgs['first'..i-1])			    end			end		end       end    -- now parse editors    local editors = citation:match ('In Birds of the World %((.-), Editors?%)' ) -- omit editors as cite web psoitioning is weird    if editors then           -- split editors with modified code from make cite iucn    	local list = {}    	--mw.addWarning ("editor string: " .. editors)    	editors = editors:gsub(", and ", ", ")    -- for 3 or more authors    	editors = editors:gsub(" and ", ", ")     -- for 2 editors      	list = mw.text.split (editors, ',');									    -- split the string on the commas into entries in list		if #list == 0 then		    mw.addWarning ("problem with editor splitting")			data.BOW.citationArgs['editor'] = editors 					        	-- no 'names' of the proper form; return the original as a single |author= parameter		else			for i, name in ipairs (list) do											-- for each author in list 			    if i>0 then                                --note the editor names are all same format (unlike authors)			    	data.BOW.citationArgs['editor-last'..i] =  name:match ('%s(%a-)$')			    	data.BOW.citationArgs['editor-first'..i] =  name:match ('(.+)%s%a-$')			    	--data.BOW.citationArgs['editor'..i-1] = nil			    else -- something has gone wrong (use editor)--			    	data.BOW.citationArgs['editor'..i] = name 			    end			    if i>0 and 1==2 then					mw.addWarning ("editor-last" .. tostring(i)  .. "=" .. data.BOW.citationArgs['editor-last'..i])			    	mw.addWarning ("editor-first".. tostring(i)  .. "=" .. data.BOW.citationArgs['editor-first'..i])			    end			end		end       end	 --if not url then url = data.BOW.customArgs['baseURL']  end	 --if not title then title = "Title parameter required" end	 	 return title, urlend-- basic handling for Taxonomy in Flux websitedata.tif = {         	citationArgs = {		website="Taxonomy in Flux", 		['editor1-last']="Boyd III",  ['editor1-first']="John H.",    --['editor1-link']="",	},	customArgs = { exclude="order,family,genus,species,taxon,id,1",	               baseURL = "http://jboyd.net/Taxo/",	               defaultSuffix = "List.html",	               defaultTitle = "Taxonomy in Flux"	               	},}--[[ ------------- Avibase                   e.g. https://avibase.bsc-eoc.org/species.jsp?avibaseid=9144EF4017F2D8B1]]data.avibase = {		citationArgs = {		website="Avibase", 		['editor1-last']="Lepage",  ['editor1-first']="Denis",    --['editor1-link']="",	},	customArgs = { exclude="order,family,genus,species,taxon,id,1",	               baseURL = "https://avibase.bsc-eoc.org/",	               searchStr = "species.jsp?avibaseid=",	               defaultTitle = "Avibase - The World Bird Database"	}}--[[ use default functiondata.avibase.id = function (id)        local title = "Avibase id: " .. id	local url = data.avibase.customArgs['baseURL'] .. data.avibase.customArgs['searchStr'] .. id	return title, urlend--]]-- ============================= IUCN =================================================-- for species in taxon; for species assessments, us {{cite iucn}}-- https://www.iucnredlist.org/search?query=Murexia&searchType=species -- https://www.iucnredlist.org/search?query=aonyx&searchType=speciesdata.iucn = {	citationArgs = {		website="[[IUCN Red List of Threatened Species]]", 		--publisher="[[IUCN]]"	},	customArgs = { exclude="family,genus,species,taxon,id,1",	               baseURL = "https://www.iucnredlist.org",	               searchString = "/search?query=",	               searchSuffix = "&searchType=species",	               defaultSuffix = "",	               defaultTitle="IUCN Red List of Threatened Species"	}	}data.iucn.genus  = function(genus)  return data.iucn.taxon(genus, "TITLE_ITALICS") enddata.iucn.family = function(family) return data.iucn.taxon(family) enddata.iucn.order  = function(order)  return data.iucn.taxon(order) enddata.iucn.taxon  = function(taxon, titleItalics)    local title = firstToUpper(taxon)    if titleItalics then title = "''" .. title .. "''" end    local url = data.iucn.customArgs['baseURL'] .. data.iucn.customArgs['searchString'] .. taxon .. data.iucn.customArgs['searchSuffix']    return title, urlend   -- ============================= ASM Mammal Diversity Database ========================data.asm = {	citationArgs = {		website="ASM Mammal Diversity Database", 		publisher="[[American Society of Mammalogists]]"	},	customArgs = { exclude="family,genus,species,taxon,id,1,2,3",	               baseURL = "https://www.mammaldiversity.org/",	               defaultTitle="ASM Mammal Diversity Database"	               	}}data.asm.species2 = function(genus, species) -- use species function below    -- old url = https://mammaldiversity.org/species-account.php?genus=ursus&species=arctos	-- new url = https://www.mammaldiversity.org/explore.html#genus=Dipodomys&species=deserti&id=1001892 (only id required)    local title = "''" .. genus .. " " .. species .. "''"	local url = data.asm.customArgs['baseURL'] .. "explore.html#genus=" .. genus .. "&species=" .. species	if templateArgs['id'] then url = url .. "&id=" .. templateArgs['id'] end	return title, urlend	    data.asm.id = function(id)    	--local url = data.asm.customArgs['baseURL'] .. "species-account/species-id=" .. templateArgs['id']    	-- new format https://www.mammaldiversity.org/explore.html#species-id=1006310    	--local url = data.asm.customArgs['baseURL'] .. "explore.html#species-id=" .. id -- templateArgs['id']    	-- newer format https://www.mammaldiversity.org/explore.html#genus=Leopardus&species=colocola&id=1005993 (genus and species can be blank)    	-- newer (Mar 2024) https://www.mammaldiversity.org/taxon/1006020    	    	local title = "Species-id=" .. id    	local hashString = "genus=&species=&id=" .. id                   -- if id only, requires blank genus and species (superceded by /taxon/link)    	if templateArgs['genus'] and templateArgs['species'] then    		title = "''" .. templateArgs['genus'] .. " " .. templateArgs['species'] .. "'' (id=" .. id ..")"    		hashString = "genus=" .. templateArgs['genus'] .. "&species=" .. templateArgs['species'] .. "&id=" .. id    	end    	--local url = data.asm.customArgs['baseURL'] .. "explore.html#genus=&species=&id=" .. id -- templateArgs['id']    	-- url = data.asm.customArgs['baseURL'] .. "explore.html#" .. hashString    	local url = data.asm.customArgs['baseURL'] .. "taxon/" .. id    	return title, urlenddata.asm.species = function(genus, species)	if templateArgs['id'] then 		return data.asm.id(templateArgs['id'])  -- use the ASM explore page if ID given (as permalink)    end	if genus and species then -- otherwisee use the treeview page with the species info		local title = "''" .. firstToUpper(genus) .. " " .. species .. "''" 		local url = data.asm.customArgs['baseURL'] .. "tree.html#genus=" .. genus ..  "&species="  .. species 	    return title, url	end	enddata.asm.genus  = function(genus)  return data.asm.taxon(genus, "genus", "TITLE_ITALICS") enddata.asm.family = function(family) return data.asm.taxon(family, "family") enddata.asm.order  = function(order)  return data.asm.taxon(order, "order") enddata.asm.taxon  = function(taxon, rank, titleItalics)    	--https://mammaldiversity.org/#ZmVsaWRhZSZnbG9iYWxfc2VhcmNoPXRydWUmbG9vc2U9dHJ1ZQ    	--                             Base64.encode(felidae&global_search=true&loose=true)    local title = firstToUpper(taxon)    if titleItalics then title = "''" .. title .. "''" end    local url = data.asm.customArgs['baseURL'] .. "tree.html" 	if rank then                                               -- no rank if taxon called directly		url = url .. "#" .. rank .. "=" .. taxon  	end    return title, urlend   --############################## Base64 encode and decode (used for ASM#####################local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'-- encodingdata.asm.Base64 = {}data.asm.Base64.encode = function(data)    return ((data:gsub('.', function(x)         local r,b='',x:byte()        for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end        return r;    end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)        if (#x < 6) then return '' end        local c=0        for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end        return b:sub(c+1,c+1)    end)..({ '', '==', '=' })[#data%3+1])end-- decodingdata.asm.Base64.decode=function(data)    data = string.gsub(data, '[^'..b..'=]', '')    return (data:gsub('.', function(x)        if (x == '=') then return '' end        local r,f='',(b:find(x)-1)        for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end        return r;    end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)        if (#x ~= 8) then return '' end        local c=0        for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end        return string.char(c)    end))end--######################## Misc ##################################--[[ 3 approaches to handling DB:         1) use DB as website and use author for editors (if known)            (a) use via to append WoRMS            (b) use postscript to append WoRMs            (c) use publisher for WoRMS        2) use WoRMS as website and designate DB as author (recommended by WoRMS) CURRENT            (option) add editors [TODO see cite WoRMS for list]            issue: what to do about editors changing (need to use access-date)]]data.WoRMS = {	citationArgs = {	    author = "WoRMS",	    website = "[[World Register of Marine Species]]",	    --['via'] = "[[World Register of Marine Species]]",	    --postscript = '&#32;from the [[World Register of Marine Species]].'	},	customArgs = {exclude="id,db,1",	              baseURL = "http://www.marinespecies.org/aphia.php?",	              searchStr = "p=taxdetails&id=",	              defaultTitle="World Register of Marine Species"	}}data.WoRMS.id = function(id)    --[[ Two styles         1. http://www.marinespecies.org/aphia.php?p=taxdetails&id=14712            >  WoRMS (2018). Heterobranchia. Accessed at: http://marinespecies.org/aphia.php?p=taxdetails&id=14712 on 2018-11-28          2. http://www.marinespecies.org/aphia.php?p=taxdetails&id=1057249            > MolluscaBase (2018). Ringipleura. Accessed through: World Register of Marine Species at: http://www.marinespecies.org/aphia.php?p=taxdetails&id=1057249 on 2018-11-28     ]]    if not templateArgs['id'] then return "no id parameter detected" end    local searchStr = "p=taxdetails&id=" .. templateArgs['id']        if templateArgs['db'] then    	data.WoRMS.db (templateArgs['db'])    --[[else -- WoRMS is primary source (note cite WoRMs uses WoRMS as publisher and the db as the work)    	 templateArgs['via'] = nil    	 templateArgs['postscript'] = nil]]    end        --templateArgs['website'] = templateArgs['db']  -- alternative (and use |postscript)    	--templateArgs['publisher'] = templateArgs['via']    	    --page <title>WoRMS - World Register of Marine Species - Heterobranchia</title>    local title = "WoRMS taxon details: AphiaID " .. id    local url = data.WoRMS.customArgs['baseURL'] .. data.WoRMS.customArgs['searchStr'] .. id    return title, url    enddata.WoRMS.default = function()	 if templateArgs['db'] then    	data.WoRMS.db (templateArgs['db'])     endenddata.WoRMS.db = function(db)	-- if database hosted by WoRMS    db = string.lower( db )	if db == "world of copepods database" or db == "copepoda" or db == "copepods" or db == "copepod" then		templateArgs['author'] = "World of Copepods Database"		templateArgs['editor-last1']="Walter"; templateArgs['editor-first1']="T.C."		templateArgs['editor-last2']="Boxshall"; templateArgs['editor-first2']="G."		-- year ? (2022). 	elseif db == "world amphipoda database" or db == "amphipoda" or db == "amphipod"then		templateArgs['author'] = "World Amphipoda Database"		templateArgs['editor-last1']="Horton"; templateArgs['editor-first1']="T."		templateArgs['editor-last2']="Lowry"; templateArgs['editor-first2']="J."		templateArgs['editor-last3']="De Broyer"; templateArgs['editor-first3']="C."		templateArgs['display-editors']="etal";  -- full list is about 20 names	elseif db == "world isopoda database" or db == "isopoda" or db == "isopod"then		templateArgs['author'] = "World Marine, Freshwater and Terrestrial Isopod Crustaceans database"		templateArgs['editor-last1']="Boyko"; templateArgs['editor-first1']="C.B."		templateArgs['editor-last2']="Bruce"; templateArgs['editor-first2']="N.L."		templateArgs['editor-last3']="Hadfield"; templateArgs['editor-first3']="K.A."		templateArgs['editor-last4']="Merrin"; templateArgs['editor-first4']="K.L."		templateArgs['editor-last5']="Ota."; templateArgs['editor-first5']="Y."		templateArgs['editor-last6']="Poore"; templateArgs['editor-first6']="G.C.B."		templateArgs['editor-last7']="Taiti"; templateArgs['editor-first7']="S."	elseif db == "millibase" or db == "diplopoda" or db == "diplopod"then		templateArgs['author'] = "MilliBase"		templateArgs['editor-last1']="Sierwald"; templateArgs['editor-first1']="P."		templateArgs['editor-last2']="Spelda"; templateArgs['editor-first2']="J."	elseif db == "molluscabase" or db == "mollusca" or db == "mollusc" then		templateArgs['author'] = "MolluscaBase"	else		templateArgs['author'] = templateArgs['db']  -- this is recommended by WoRMS	endend--[[ Species files       -- takes db parameter       --https://db.speciesfile.org/otus/$ID/overview       --https://plecoptera.speciesfile.org/otus/890815/overview]]data.speciesfile = {	citationArgs = {	    website   = " Species File",	    --publisher = "",	},	customArgs = {exclude="id,1,2,3,4,5,db",	              --baseURL = "https://" .. firstToUpper(templateArgs['db'] ) .. ".speciesfile.org/",	              --searchStr = "otus/",	             -- defaultSuffix = "/overview",	              --defaultTitle=  " Species File"	}}data.speciesfile.id = function(id)                               -- e.g. https://plecoptera.speciesfile.org/otus/890815/overview	local db = data.speciesfile.db()  -- customise for speciesfile    local title = firstToUpper(db) .. " Species File id=" .. id    --local url = data.speciesfile.customArgs['baseURL'] .. data.speciesfile.customArgs['searchStr'] .. id .. data.speciesfile.customArgs['defaultSuffix ']    local url = "https://" ..db .. ".speciesfile.org/otus/" .. id .. "/overview"               	return title, url    enddata.speciesfile.default = function()    local db = data.speciesfile.db ()    local title = firstToUpper(db) .. " Species File"     local url = "https://" ..db .. ".speciesfile.org/"    return title, url enddata.speciesfile.db = function()    local db = string.lower( templateArgs['db']  )		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."	if db == "zoraptera" then    -- ed: Hopkins, H.		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."	elseif db == "dermaptera" then  -- eds: Hopkins, H., Haas, F. & Deem, L.S.		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."		templateArgs['editor-last2']="Johnson"; templateArgs['editor-first2']="K.P."		templateArgs['editor-last3']="Smith"; templateArgs['editor-first3']="V.S."	elseif db == "plecoptera" then                    -- (eds) DeWalt RE, Hopkins H, Neu-Becker U, and Stueber G		templateArgs['editor-last1']="DeWalt"; templateArgs['editor-first1']="R.E."		templateArgs['editor-last2']="Hopkins"; templateArgs['editor-first2']="H."		templateArgs['editor-last3']="Neu-Becker"; templateArgs['editor-first3']="U."		templateArgs['editor-last4']="Stueber"; templateArgs['editor-first4']="G."	elseif db == "orthoptera " then  --eds: Cigliano, M.M., H. Braun, D.C. Eades & D. Otte.		templateArgs['editor-last1']="Cigliano"; templateArgs['editor-first1']="M.M."		templateArgs['editor-last2']="Braun"; templateArgs['editor-first2']="H."		templateArgs['editor-last3']="Eades"; templateArgs['editor-first3']="D.C."		templateArgs['editor-last4']="Otte"; templateArgs['editor-first4']="D."	elseif db == "grylloblattodea" then      -- ed: Hopkins, H.		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."	elseif db == "mantophasmatodea" then      -- ed: Hopkins, H.		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."	elseif db == "embioptera" then      -- ed: Hopkins, H.		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."	elseif db == "phasmida" then        -- eds: Brock PD, Büscher TH, Baker E. 		templateArgs['editor-last1']="Brock"; templateArgs['editor-first1']="P.D."		templateArgs['editor-last2']="Büscher"; templateArgs['editor-first2']="T.H."		templateArgs['editor-last3']="Baker"; templateArgs['editor-first3']="E."	elseif db == "mantodea" then		-- not updated yet	elseif db == "cockroach" then       -- ed: Beccaloni, G.W.		templateArgs['editor-last1']="Beccaloni"; templateArgs['editor-first1']="G.W."	elseif db == "isoptera" then        -- ed: Hopkins, H.		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."	elseif db == "psocodea" then      --eds: Hopkins, H., Johnson, K.P., & Smith, V.S. 		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."		templateArgs['editor-last2']="Johnson"; templateArgs['editor-first2']="K.P."		templateArgs['editor-last3']="Smith"; templateArgs['editor-first3']="V.S."	elseif db == "aphid" then         -- ed: Colin FAVRET		templateArgs['editor-last1']="Favret"; templateArgs['editor-first1']="Colin"	elseif db == "coleorrhyncha" then -- ed: Hopkins, H.		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."	elseif db == "coreoidea" then -- not updated yet	elseif db == "lygaeoidea" then -- eds: Dellapé, Pablo M. & Thomas J. Henry		templateArgs['editor-last1']="Dellapé"; templateArgs['editor-first1']="Pablo M."		templateArgs['editor-last2']="Henry"; templateArgs['editor-first2']="Thomas J."	elseif db == "hoppers" then  -- eds: Dmitriev, D.A., Anufriev, G.A., Bartlett, C.R., Blanco-Rodríguez, E., Borodin, Oleg I., Cao, Y.-H., Deitz, L.L., Dietrich, C.H., Dmitrieva, M.O., El-Sonbati, S.A., Evangelista de Souza, O., Gjonov, I.V., Gonçalves, A.C., Hendrix, S., McKamey, S., Kohler, M., Kunz, G., Malenovský, I., Morris, B.O., Novoselova, M., Pinedo-Escatel, J.A., Rakitov, R.A., Rothschild, M.J., Sanborn, A.F., Takiya, D.M., Wallace, M.S., Zahniser, J.N.		templateArgs['editor-last1']="Dmitriev"; templateArgs['editor-first1']="D.A."		templateArgs['editor-last2']="Anufriev"; templateArgs['editor-first2']="G.A."		templateArgs['editor-last3']="Bartlett"; templateArgs['editor-first3']="C.R."		templateArgs['display-editors']="etal";  -- full list is about 28 names		else		--return "Species File database not recognised"	end	if db == "hoppers" then		data.speciesfile.citationArgs['website'] = "World Auchenorrhyncha Database"	else	    data.speciesfile.citationArgs['website'] =  firstToUpper(db) .. data.speciesfile.citationArgs['website']	end    return dbend--[[ ITIS - Integrated Taxonomic Information System          https://www.itis.gov/servlet/SingleRpt/SingleRpt?search_topic=TSN&search_value=95601#null]]data.itis = {	citationArgs = {	    website   = "[[Integrated Taxonomic Information System]]",	    --publisher = "",	},	customArgs = {exclude="id,1,2,3,4,5",	              baseURL = "https://www.itis.gov/",	              searchStr = "servlet/SingleRpt/SingleRpt?search_topic=TSN&search_value=",	              defaultTitle="Integrated Taxonomic Information System"	}}data.itis.id = function(id)       local title = "ITIS id=" .. id    local url = data.itis.customArgs['baseURL'] .. data.itis.customArgs['searchStr'] .. id  	return title, url    	end--[[ Catalogue of Life:		Roskov Y., Ower G., Orrell T., Nicolson D., Bailly N., Kirk P.M., Bourgoin T., DeWalt R.E., Decock W., van Nieukerken E.J., Penev L. (eds.) (2020). 		Species 2000 & ITIS Catalogue of Life, 2020-12-01. 		Digital resource at www.catalogueoflife.org. Species 2000: Naturalis, Leiden, the Netherlands. ISSN 2405-8858.		Species 2000 & ITIS Catalogue of Life, 2020-12-01. Digital resource at www.catalogueoflife.org. 		Species 2000: Naturalis, Leiden, the Netherlands. ISSN 2405-8858.]]data.col = {	db       = "col",  -- need rethink this	citationArgs = {	    --author = "Catalogue of Life",	    --['editor-last1'] = "Roskov",   ['editor-first1'] = "Y.", ['editor-last2'] = "Ower",     ['editor-first2'] = "G.", 	    ['editor-last3'] = "Orrell",   ['editor-first3'] = "T.", ['editor-last4'] = "Nicolson", ['editor-first4'] = "D.", 	    ['editor-last5'] = "Bailly",   ['editor-first5'] = "N.", ['editor-last6'] = "Kirk",     ['editor-first6'] = "P.M.", 	    ['editor-last7'] = "Bourgoin", ['editor-first7'] = "T.", ['editor-last8'] = "DeWalt",   ['editor-first8'] = "R.E.", 	    ['editor-last9'] = "Decock",   ['editor-first9'] = "W.", ['editor-last10'] = "van Nieukerken", ['editor-first10'] = "E.J.", 	    ['editor-last11'] = "Penev", ['editor-first11'] = "L.", 	    --website   = "[[Catalogue of Life]]",	    --website   = "[[Catalogue of Life|Species 2000 & ITIS Catalogue of Life]]",	    -- website   = "[[Species 2000]] & [[ITIS]] [[Catalogue of Life]]",	    website   = "[[Catalogue of Life]]",	    publisher = "[[Species 2000]]: Leiden, the Netherlands",	    --others    = "Species 2000 & ITIS"	},	customArgs = {exclude="id,db,1,2,3,4,5,legacy,option",	              baseURL = "https://www.catalogueoflife.org/data/",	              searchStr = "browse?taxonKey=",	              defaultTitle="Catalogue of Life"	}}data.col.id = function(id)        --[[ Catalogue of Life        browse option:	https://www.catalogueoflife.org/data/browse?taxonKey=4JQ8            use id for taxoKey                    taxon option    https://www.catalogueoflife.org/data/taxon/6HR5M    ]]    local title = "Catalogue of Life taxonKey " .. id    local url = data.col.customArgs['baseURL']        -- some new CoL are numbers e.g. 64553 in https://www.catalogueoflife.org/data/taxon/64553	if not tonumber(id)  and string.find( id,  "^[0-9abcdef]+$" ) then                                            -- if old-style id		local year = "2019"        -- last old-style version available    	if templateArgs['version'] and string.find( templateArgs['version'], "^%d%d%d%d$"  ) then --if version specied        	year = templateArgs['version']        end    	if templateArgs['option'] == "browse" then 		    url = "http://www.catalogueoflife.org/annual-checklist/" .. year .. "/browse/tree/id/" .. id		else -- default to option=taxon		    url = "http://www.catalogueoflife.org/annual-checklist/" .. year .. "/details/species/id/" .. id		end    else                                                                                  -- else use current version    	if templateArgs['option'] == "browse" then 		    url = url .. "browse?taxonKey=" .. id		else -- default to option=taxon		    url = url .. "taxon/" .. id		end    end	return title, url    	end--[[ current links				 https://www.catalogueoflife.org/data/search?q=" Chinchilla+chinchilla&type=EXACT	legacy links with redirect	    Species pages:    http://www.catalogueoflife.org/col/details/species/id/12dca9c49741815f82400bb7bff50553	    Species searches: http://www.catalogueoflife.org/col/search/all/key/Dracula+antonii/    old-style links                		  http://www.catalogueoflife.org/col/details/species/id/7539827da517bd6273a4a3836578cb24            		      http://www.catalogueoflife.org/col/search/scientific/genus/Chinchilla/species/chinchilla/match/1/                		  http://www.catalogueoflife.org/col/browse/tree/id/003e480e646d0e7647ab67efc1218197	year specific links        2019              http://www.catalogueoflife.org/annual-checklist/2019/details/species/id/7539827da517bd6273a4a3836578cb24                          http://www.catalogueoflife.org/annual-checklist/2019/search/all/key/Chinchilla+chinchilla/fossil/1/match/1                           http://www.catalogueoflife.org/annual-checklist/2019/search/scientific/genus/Chinchilla/species/chinchilla/match/1/                     ?    http://www.catalogueoflife.org/annual-checklist/2016/browse/tree?6d600f4985f19b1207d41d847424edd0                      ?    http://www.catalogueoflife.org/col/browse/tree/id/003e480e646d0e7647ab67efc1218197        browse            http://www.catalogueoflife.org/annual-checklist/2019/browse/tree/id/003e480e646d0e7647ab67efc1218197 ]]data.col.default = function(mode)  -- this handles the old style template with positional parameters (mode unused?)   	local para1 = templateArgs[2] 	local para2 = templateArgs[3] 	local para3 = templateArgs[4]  	local para4 = templateArgs[5]  	if para1 then para1 = mw.text.trim(para1) end	if para2 then para2 = mw.text.trim(para2) end	if para3 then para3 = mw.text.trim(para3) end	if para4 then para4 = mw.text.trim(para4) end		local title, url		if para1 then        --local match = "7539827da517bd6273a4a3836578cb24" 		local match = "^[0-9abcdef]+$" 		if string.find( para1, match ) then			url = "http://www.catalogueoflife.org/col/details/species/id/" .. para1  -- ""Old style id"			--url ="https://www.catalogueoflife.org/data/search?q=" .. para1			if para2 then				title = para2			else				title = "Oldstyle id: " .. para1			end					else			--https://www.catalogueoflife.org/data/search?q=" Chinchilla+chinchilla&type=EXACT						if para1 ~= "" then				url = "https://www.catalogueoflife.org/data/search?q=" .. para1 				title = "''" .. para1 				if para2  then					url = url .. "+" .. para2 					title = title .. " " .. para2				end				url = url .. "&type=EXACT"				title = title .. "''"			end					end			if para3 then title = title .. " " .. para3 end   -- add authority		if para4 == "nv" then templateArgs['trans-title'] = "synonym" end   -- if nv add [synonym]. Note that this parameter is not used to add COinS metadata 	else		-- no parameter 1	end		return title, url    end--======================  Fossilworks =======================================data.fossilworks = {	citationArgs = {		website="[[Fossilworks]]",		agency="Gateway to the [[Paleobiology Database]]",		--publisher="Paleobiology Database",		--postscript = 'none',		-- postscript = "&#32;from the [[Paleobiology Database]].",  -- gives maintenance warning		--via="''fossilworks.org''"   -- an alternative format to using |website=	},	customArgs = { exclude = "id,collection,date,1",	               baseURL = "http://www.fossilworks.org/cgi-bin/",	               searchStr ="bridge.pl?a=taxonInfo&taxon_no=",	               defaultTitle = "Fossilworks: Gateway to the Paleobiology Database"	}	--id = function(id) return p.genericIdCitation (frame, title, url)}data.fossilworks.id = function(id)--[[ http://fossilworks.org/cgi-bin/bridge.pl?a=taxonInfo&taxon_no=83087	    if not templateArgs['id'] then return "no id parameter detected" end    local searchStr = "bridge.pl?a=taxonInfo&taxon_no=" .. templateArgs['id']    templateArgs['url']= target.CustomArgs['baseURL'] .. searchStr    ]]    local title = "PaleoDB taxon number: " .. id    local url = data.fossilworks.customArgs['baseURL'] .. data.fossilworks.customArgs['searchStr'] .. id    return title, url  enddata.fossilworks.collection = function(collection)	-- http://fossilworks.org/bridge.pl?a=collectionSearch&collection_no=20072	local title = "PaleoDB collection number: " .. collection	local url = data.fossilworks.customArgs['baseURL'] .. "bridge.pl?a=collectionSearch&collection_no=" .. collection	return title, url enddata.fossilworks.error = function()	return "Requires id and title parameters"end--======================  Paleobiology Database: paleobiodb.org =======================================data.paleobiodb = {	citationArgs = {		website="[[Paleobiology Database]]"	},	customArgs = { exclude = "id,collection,date,1",	               baseURL = "https://paleobiodb.org/classic/",	               searchStr ="basicTaxonInfo?taxon_no=",	               defaultTitle = "Paleobiology Database"	}	--id = function(id) return p.genericIdCitation (frame, title, url)}data.paleobiodb.id = function(id)--[[ https://paleobiodb.org/classic/basicTaxonInfo?taxon_no=22786	    if not templateArgs['id'] then return "no id parameter detected" end    ]]    local title = "PaleoDB taxon number: " .. id    local url = data.paleobiodb.customArgs['baseURL'] .. data.paleobiodb.customArgs['searchStr'] .. id    return title, url  enddata.paleobiodb.collection = function(collection)	-- https://paleobiodb.org/classic/basicCollectionSearch?collection_no=24193	local title = "PaleoDB collection number: " .. collection	local url = data.paleobiodb.customArgs['baseURL'] .. "basicCollectionSearch?collection_no=" .. collection	return title, url enddata.paleobiodb.error = function()	return "Requires id and title parameters"end--======================================= PLANTS =========================--[[ Plant authorities can end in a period. This is stripped by the citation templates.      This function encloses titles ending in such authorities in double parentheses, i.e. ((title))     ]]local addAuthority = function(formattedTaxonName)    if templateArgs['authority'] then    	local title = formattedTaxonName .. " " .. templateArgs['authority']     	return string.gsub( title, "(.*%.)$", "((%1))")  -- if authority ends in "." enclose ((title)) to prevent removal    end    return formattedTaxonNameend--[[ Hassler, Michael (2004 - 2020): World Plants. Synonymic Checklist and Distribution of the World Flora.        Version x.xx; last update xx.xx.xxxx. - www.worldplants.de. Last accessed dd/mm/yyyy.       https://www.worldplants.de/world-plants-complete-list/complete-plant-list#1599996425     Hassler, Michael (2004 - 2020): World Ferns. Synonymic Checklist and Distribution of Ferns and Lycophytes of the World.        Version x.xx; last update xx.xx.xxxx. - www.worldplants.de/ferns/. Last accessed dd/mm/yyyy.       https://www.worldplants.de/world-ferns/ferns-and-lycophytes-list#1599997555    deeplinks:		Genus:  [https://www.worldplants.de?deeplink=Helosciadium-Koch ''Helosciadium'']		Species: [https://www.worldplants.de?deeplink=Helosciadium-longipedunculatum ''Helosciadium longipedunculatum'']				Genus:  [https://www.worldplants.de?deeplink=Lycopodium-L. ''Lycopodium'']		Species: [https://www.worldplants.de?deeplink=Lycopodium-clavatum ''Lycopodium clavatum'']--]]data.worldplants = {	citationArgs = {		last1 = "Hassler", first1 = "Michael",		website="World Plants. Synonymic Checklist and Distribution of the World Flora.",		--publisher=""	},	customArgs = { exclude = "id,authority,family,genus,species,1",	               baseURL = "https://www.worldplants.de",	               searchStr ="/world-plants-complete-list/complete-plant-list#",	               defaultSuffix = "",	               defaultTitle = "World Plants"	}}data.worldplants.genus = function(genus)	local title = addAuthority("''" .. genus .. "''")	local genusString = genus 	if templateArgs['authority'] then genusString = genus .. "-" .. templateArgs['authority'] end	local url = data.worldplants.customArgs['baseURL'] .. "?deeplink=" .. genusString	return title, url  enddata.worldplants.species = function(genus, species)	local title = addAuthority("''" .. genus .. " " .. species .. "''")	local url = data.worldplants.customArgs['baseURL'] .. "?deeplink=" .. genus .. "-" .. species .. " " .. (templateArgs['authority'] or "")	return title, url  end--[[ experimental, don't leave live data.worldplants.taxon = function(taxon)	local title =  taxon .. " " .. (templateArgs['authority'] or "")	local url = data.worldplants.customArgs['baseURL'] .. "?deeplink=" .. taxon	return title, url  enddata.worldplants.family = function(family)	local title = family .. " " .. (templateArgs['authority'] or "")	local url = data.worldplants.customArgs['baseURL'] .. "?deeplink=" .. family	return title, url  end--]]data.worldferns = {	citationArgs = {		last1 = "Hassler", first1 = "Michael",		website="World Ferns. Synonymic Checklist and Distribution of the World Flora.",		--publisher=""	},	customArgs = { exclude = "id,authority,family,genus,species,1",	               baseURL = "https://www.worldplants.de/",	               searchStr ="world-ferns/ferns-and-lycophytes-list?name=",	               defaultSuffix = "",	               defaultTitle = "World Ferns"	}}data.worldferns.genus = function(genus)	local title = addAuthority("''" .. genus .. "''")	local genusString = genus 	if templateArgs['authority'] then genusString = genus .. "-" .. templateArgs['authority'] end	local url = data.worldferns.customArgs['baseURL'] .. data.worldferns.customArgs['searchStr'] ..  genusString	return title, url  enddata.worldferns.species = function(genus, species)	local title = addAuthority("''" .. genus .. " " .. species .. "''")	local url = data.worldferns.customArgs['baseURL'] .. data.worldferns.customArgs['searchStr'] .. genus .. "-" .. species .. " " .. (templateArgs['authority'] or "")	return title, url  end--[[Plants of the World online	   http://powo.science.kew.org/taxon/urn:lsid:ipni.org:names:30003057-2  -- use id	   http://powo.science.kew.org/?q=Selaginellaceae                        -- use search	   http://powo.science.kew.org/?family=Selaginellaceae                   -- can also use family= [gets same result as q=]	   http://powo.science.kew.org/?genus=Selago                             -- or genus	   http://powo.science.kew.org/?genus=Selago&species=abietina            -- or genus + species	   http://powo.science.kew.org/?genus=Selago&f=accepted_names            -- filter for accepted names	   http://powo.science.kew.org/?genus=Selago&f=genus_f                   -- filter for genus (no species selected)	   http://powo.science.kew.org/?genus=Selago&f=genus_f%2Caccepted_names  -- filter for genus and accepted names	   http://powo.science.kew.org/?page.size=480&f=family_f%2Caccepted_names -- list of accepted families	   -- all these searches get the search result (no apparent way to target the article when unique)]]data.POWO = {	citationArgs = {		website="[[Plants of the World Online]]",		publisher="Royal Botanic Gardens, Kew",		--postscript = 'none',	},	customArgs = { exclude = "id,authority,family,genus,species,1",	               baseURL = "http://powo.science.kew.org/taxon/",	               searchStr ="urn:lsid:ipni.org:names:",	               defaultSuffix = "",	               defaultTitle = "Plants of the World Online"	}	--id = function(id) return p.genericIdCitation (frame, title, url)}--[[ http://powo.science.kew.org/taxon/urn:lsid:ipni.org:names:30003057-2	]]data.POWO.id = function(id)	local id = data.POWO.getValidID()	if not id then return data.POWO.error() end    local title = id                                                                          -- as default value	local url = data.POWO.customArgs['baseURL'] .. data.POWO.customArgs['searchStr'] .. id    return title, url  enddata.POWO.family = function(family)	local title = addAuthority(family)	local id = templateArgs['id']	if not id then return data.POWO.error() end	local url = data.POWO.customArgs['baseURL'] .. data.POWO.customArgs['searchStr'] .. id    return title, url  enddata.POWO.genus = function(genus)	local title = addAuthority("''" .. genus .. "''")	local id = data.POWO.getValidID()	if not id then return data.POWO.error() end	local url = data.POWO.customArgs['baseURL'] .. data.POWO.customArgs['searchStr'] .. id    return title, url  enddata.POWO.species = function(genus,species)	local title = addAuthority("''" .. genus .. " " .. species .. "''")	local id = data.POWO.getValidID()	if not id then return data.POWO.error() end	local url = data.POWO.customArgs['baseURL'] .. data.POWO.customArgs['searchStr'] ..id    return title, url  enddata.POWO.getValidID = function()	local id = templateArgs['id']	if id then 		return string.gsub( id, "urn:lsid:ipni.org:names:", "") -- don't want this twice	end	return nilenddata.POWO.error = function()	return '<span style="color:red">Requires id and one of title, family, genus or species parameters</span>'end--[[Gouda, E.J., Butcher, D. & Gouda, C.S. (cont.updated) Encyclopaedia of Bromeliads, Version 4. http://bromeliad.nl/encyclopedia/ Utrecht University Botanic Gardens]]data.bromeliad = {	citationArgs = {		last1="Gouda", first1="E.J.",		last2="Butcher", first2="D.",		last3="Gouda", first3="C.S",		website="[[Encyclopaedia of Bromeliads]]",		version="Version 4",		publisher="Utrecht University Botanic Gardens",		--postscript = 'none',	},	customArgs = { exclude = "id,authority,family,genus,species,list,1",	               baseURL = "https://bromeliad.nl/",	               searchStr ="encyclopedia/index.php?find=",	               defaultSuffix = "",	               defaultTitle = "Encyclopaedia of Bromeliads, Version 4"	}	--id = function(id) return p.genericIdCitation (frame, title, url)}--[[ https://bromeliad.nl/encyclopedia/index.php?find=Hylaeaicum	]]data.bromeliad.search = function(search)    local title = search                                                                          -- as default value	local url = data.bromeliad.customArgs['baseURL'] .. data.bromeliad.customArgs['searchStr'] .. search    return title, url  end--[[ http://bromeliad.nl/species/Bromeliaceae	]]data.bromeliad.taxon = function(taxon)    local title = addAuthority(taxon)                                                                          -- as default value	local url = data.bromeliad.customArgs['baseURL'] .. "species/" .. taxon    return title, url  end--[[ genus	]]data.bromeliad.genus = function(genus)    local title = addAuthority("''" .. genus .. "''")                                                                          -- as default value	local url = data.bromeliad.customArgs['baseURL'] .. "species/" .. genus	if templateArgs['list'] == "species" then        url = data.bromeliad.customArgs['baseURL'] .. "encyclopedia/brome.php?action=showSpeciesIndex&name=" .. genus .. "&flags="    end    return title, url  end--[[ 	]]data.bromeliad.species = function(genus, species)    local title = addAuthority("''" .. genus .. " " .. species .. "''")                                                                          -- as default value	local url = data.bromeliad.customArgs['baseURL'] .. "species/" .. genus .. "/" .. species     return title, url  end--[[ https://bromeliad.nl/encyclopedia/brome.php?action=showTaxon&id=10093 ]]data.bromeliad.id = function(id)    local title = id                                                                          -- as default value	local url = data.bromeliad.customArgs['baseURL'] .. "encyclopedia/brome.php?action=showTaxon&id=" .. id    return title, url  end--[[GRIN 	Cite as: USDA, Agricultural Research Service, National Plant Germplasm System. 2021. Germplasm Resources Information Network (GRIN Taxonomy). National Germplasm Resources Laboratory, Beltsville, Maryland.	URL: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=tribe&id=1571. Accessed 27 October 2021. 	Family record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?id=440	   Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=440&type=family	Subfamily record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=subfamily&id=1507	   Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=3265&type=subfamily	Tribe record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=tribe&id=1551 (Millettieae)	   Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=1551&type=tribe	Subtribe record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=subtribe&id=1507	   Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=1507&type=subtribe	Genus record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenus?id=191 (Genus Adenodolichos Harms)	  Species list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyspecieslist?id=191&type=genus	Species record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomydetail?id=489203 ( Adenodolichos paniculatus)	]]data.GRIN = {     	citationArgs = {		website="[[Germplasm Resources Information Network]] (GRIN)",		publisher="[[Agricultural Research Service]] (ARS), [[United States Department of Agriculture]] (USDA)",		--postscript = 'none',	},	customArgs = { exclude = "id,authority,family,genus,species,1",	               baseURL = "https://npgsweb.ars-grin.gov/gringlobal",	               searchStr ="/taxon/taxonomydetail?",                             -- for species record	               defaultSuffix = "",	               defaultTitle = "GRIN-Global"	}	--id = function(id) return p.genericIdCitation (frame, title, url)}data.GRIN.id = function(id)    local title = data.GRIN.customArgs['defaultTitle'] .. ' ' .. id    local url = data.GRIN.customArgs['baseURL'] .. data.GRIN.customArgs['searchStr'] .. id    return title, url  end-- IPNI--→ "Meconopsis Vig." International Plant Names Index (IPNI). Royal Botanic Gardens, Kew.--- 	https://www.ipni.org/n/30149252-2--- as {{IPNI |id=30149252-2 |taxon=((Meconopsis |authority=Vig.))}} data.IPNI = {     	citationArgs = {		website="[[International Plant Names Index]] (IPNI)",		publisher="Royal Botanic Gardens, Kew",		--postscript = 'none',	},	customArgs = { exclude = "id,authority,family,genus,species,1",	               baseURL = "https://www.ipni.org",	               searchStr ="/n/",	               defaultSuffix = "",	               defaultTitle = "IPNI"	}	--id = function(id) return p.genericIdCitation (frame, title, url)}data.IPNI.id = function(id)    local title = id    local url = data.IPNI.customArgs['baseURL'] .. data.IPNI.customArgs['searchStr'] .. id    return title, url  enddata.IPNI.species  = function(genus, species)  return data.IPNI.taxon(genus .. " " .. species, "TITLE_ITALICS") enddata.IPNI.genus  = function(genus)  return data.IPNI.taxon(genus, "TITLE_ITALICS") enddata.IPNI.taxon = function(taxon, italics)	local title = taxon 	if italics then title = "''" .. title .. "''"  end	title = addAuthority(title)--[[	if templateArgs['authority'] then		title = title .. " " .. templateArgs['authority']		title = string.gsub( title, "(.*%.)$", "((%1))")  -- if authority ends in "." enclose ((title)) to prevent removal	end ]]	local url = data.IPNI.customArgs['baseURL'] .. data.IPNI.customArgs['searchStr'] .. templateArgs['id']    return title, url  end--[[World Flora Online     	http://www.worldfloraonline.org/taxon/wfo-4000012284  -- id]]data.WFO = {	citationArgs = {		website="[[World Flora Online]]",		--publisher="Missouri Botanical Gardens",		--postscript = 'none',	},	customArgs = { exclude = "id,family,genus,species,authority,1",	               baseURL = "http://www.worldfloraonline.org",	               searchStr ="/taxon/wfo-",                                       -- not strictly search string	               defaultSuffix = "",	               --defaultTitle = "World Flora Online"	               defaultTitle = "An Online Flora of All Known Plants"	}}data.WFO.id = function(id)--[[ http://www.worldfloraonline.org/taxon/wfo-4000012284	    ]]    local title = id    local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. id    return title, url  enddata.WFO.family = function(family)	local title = addAuthority(family) 	local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. templateArgs['id']    return title, url  enddata.WFO.genus = function(genus)	local title = addAuthority("''" .. genus .. "''") 	local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. templateArgs['id']    return title, url  enddata.WFO.species = function(genus,species)	local title = addAuthority("''" .. genus .. " " .. species .. "''") 	local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. templateArgs['id']    return title, url  enddata.WFO.error = function()	return "Requires id and title parameters"enddata.Tropicos = {	citationArgs = {		website="[[Tropicos]]",		--publisher="Missouri Botanical Gardens",		--postscript = 'none',	},	customArgs = { exclude = "id,1",	               baseURL = "http://legacy.tropicos.org/Name/",	               searchStr ="",	               defaultSuffix = "",	               defaultTitle = "Tropicos"	}}data.Tropicos.id = function(id)--[[ hhttp://legacy.tropicos.org/Name/100444532	    ]]    local title = id    local url = data.Tropicos.customArgs['baseURL'] .. data.Tropicos.customArgs['searchStr'] .. id    return title, url  enddata.Tropicos.error = function()	return "Requires id and title parameters"enddata.FNA = {	citationArgs = {		            website="[[Flora of North America]]",		            --publisher="http://www.efloras.org",		            --postscript = 'none',	},	customArgs = { exclude = "id,1",	               baseURL = "http://www.efloras.org/florataxon.aspx",	               searchStr ="?flora_id=1&taxon_id=",	               defaultSuffix = "",	               defaultTitle = "Flora of North America"	}	--id = function(id) return p.genericIdCitation (frame, title, url)}data.FNA.id = function(id)--[[ http://www.efloras.org/florataxon.aspx?flora_id=1&taxon_id=125683    ]]    local title = id    local url = data.FNA.customArgs['baseURL'] .. data.FNA.customArgs['searchStr'] .. id    return title, url  enddata.FNA.error = function()	return "Requires id and title parameters"end-- ATRP: Australian Tropical Rainforest Plants data.ATRP = {	citationArgs = {		            website="[[Australian Tropical Rainforest Plants]]",		            publisher="[[Commonwealth Scientific and Industrial Research Organisation]] (CSIRO)",		            version = "Edition 8",				    year = 2020,		            --postscript = 'none',		            last1= "Zich", first1="F. A.", 		            last2= "Hyland",  first2= "B. P. M.", ['author2-link']="Bernard Hyland",		            last3= "Whiffin", first3= "T.", 		            last4= "Kerrigan",  first4= "R.A.",		            --['display-authors']=3,	},	customArgs = { exclude = "genus, species,authority, id,1",	               baseURL = "https://apps.lucidcentral.org/rainforest",	               searchStr ="/text/entities/",	               defaultSuffix = ".htm",	               defaultTitle = "[[Australian Tropical Rainforest Plants]]"	}	--id = function(id) return p.genericIdCitation (frame, title, url)}data.ATRP.species = function(genus,species)--[[ https://apps.lucidcentral.org/rainforest/text/entities/buckinghamia_celsissima.htm    ]]    local title = addAuthority("''" .. genus .. " " .. species .. "''") --"''" .. genus .. " " .. species .. "''"    local url = data.ATRP.customArgs['baseURL'] .. data.ATRP.customArgs['searchStr'] .. genus .. "_" .. species .. data.ATRP.customArgs['defaultSuffix']    return title, url  enddata.ATRP.error = function()	return "Requires genus and species parameters"end-- ============================= Mosses (Goffinet's site) =================================================-- for species in taxon; for species assessments, us {{cite iucn}}-- https://bryology.uconn.edu/classification/#Hypnanae-- https://bryology.uconn.edu/classification/#Bryalesdata.goffinet = {	citationArgs = {		first1="B.", last1="Goffinet", 		first2="W.R.", last2="Buck",		website="Classification of extant moss genera"		--publisher="[[xxx]]"	},	customArgs = { exclude="family,genus,species,taxon,id,1",	               baseURL = "https://bryology.uconn.edu/classification/",	               searchString = "#",	               searchSuffix = "",	               defaultSuffix = "",	               defaultTitle="Classification of the Bryophyta"	}	}data.goffinet.genus  = function(genus)  return data.goffinet.taxon(genus, "GENUS") enddata.goffinet.family = function(family) return data.goffinet.taxon(family, "FAMILY") enddata.goffinet.order  = function(order)  return data.goffinet.taxon(order, "ORDER") enddata.goffinet.taxon  = function(taxon, rank)    local title = firstToUpper(taxon)    if rank == "GENUS" then title = "''" .. title .. "''" end    if not (rank == "GENUS" or rank == "FAMILY") then  -- upper case anchors for orders and above    	if taxon ~= "Bryanae" and taxon ~= "Hypnanae" and taxon ~= "Bryales" and taxon ~= "Bryidae" then -- check for exceptions (inconsistencies at website)    		taxon = taxon:upper()    	end    end    local url = data.goffinet.customArgs['baseURL'] .. data.goffinet.customArgs['searchString'] .. taxon .. data.goffinet.customArgs['searchSuffix']    return title, urlend --[[ AlgaeBase    (old) taxonomy browser url (Volvox) = https://www.algaebase.org/browse/taxonomy/?id=6898    taxonomy browser url (Volvox) = https://www.algaebase.org/browse/taxonomy/?#6898    genus article url (Volvox) =  https://www.algaebase.org/search/genus/detail/?genus_id=43497 (different id)    genus article url (Torodinium)= https://www.algaebase.org/search/genus/detail/?genus_id=44698    Please cite this record as:   M.D. Guiry in Guiry, M.D. & Guiry, G.M. 2020. AlgaeBase.                                   World-wide electronic publication, National University of Ireland, Galway.                                   http://www.algaebase.org; searched on 10 May 2020.              ]]data.AlgaeBase = {	citationArgs = {		           website="[[AlgaeBase]]",	               ['editor1-last']="Guiry", ['editor1-first']="M.D.",	               ['editor2-last']="Guiry", ['editor2-first']="G.M.",		           publisher="National University of Ireland, Galway",	},	customArgs = { exclude = "id,1,genus_id,species_id,spid,genid",	               baseURL = "https://www.algaebase.org/",	               --searchStr ="browse/taxonomy/?id=", (old)	               searchStr ="browse/taxonomy/?#",	               defaultSuffix = "",	               defaultTitle = "AlgaeBase"	}}data.AlgaeBase.id = function(id)--[[ https://www.algaebase.org/browse/taxonomy/?id=6898 (id for taxonomy page)    ]]    local title = id    local url = data.AlgaeBase.customArgs['baseURL'] .. data.AlgaeBase.customArgs['searchStr'] .. id    return title, url  enddata.AlgaeBase.genid = function(genid)--[[ https://www.algaebase.org/search/genus/detail/?genus_id=43497 (different id for genus page)    ]]    local title = genid    local url = data.AlgaeBase.customArgs['baseURL'] .. "search/genus/detail/?genus_id=" .. genid    return title, url  enddata.AlgaeBase.spid = function(spid)--[[ https://www.algaebase.org/search/species/detail/?species_id=52713 (id for species page)    ]]    local title = spid    local url = data.AlgaeBase.customArgs['baseURL'] .. "search/species/detail/?species_id=" .. spid    return title, url  enddata.AlgaeBase.error = function()	return "Requires id and title parameters"end--================= Viruses =========data.ictv = {	citationArgs = {		           website="ictv.global",	               --['editor1-last']="xx", ['editor1-first']="xx",	               --['editor2-last']="xx", ['editor2-first']="xx",		           author="International Committee on Taxonomy of Viruses (ICTV)",	},	customArgs = { exclude = "id,1",	               baseURL = "https://ictv.global/taxonomy/",	               searchStr ="taxondetails?taxnode_id=",	               defaultSuffix = "",	               defaultTitle = "Taxonomy Browser"	}}data.ictv.id = function(id)--[[ https://ictv.global/taxonomy/taxondetails?taxnode_id=202308917&taxon_name=Campanilevirus%20YC          (for species Campanilevirus YC)     https://ictv.global/taxonomy/taxondetails?taxnode_id=202308917 (also works with just the id)    ]]    local title = id    local url = data.ictv.customArgs['baseURL'] .. data.ictv.customArgs['searchStr'] .. id    return title, url  enddata.ictv.error = function()	return "Requires id and title parameters"end--############################## General Functions ########################################local function getArgs (frame, args)	local parents = mw.getCurrentFrame():getParent()			for k,v in pairs(parents.args) do		--check content		if v and v ~= "" then			args[k]=v --parents.args[k]		end	end	for k,v in pairs(frame.args) do		--check content		if v and v ~= "" then			args[k]=v 		end	endendlocal function initialise(frame, sourceDB)		target=sourceDB	templateArgs = sourceDB.citationArgs -- get custom arguments for target (fishbase, cof etc    	getArgs(frame, templateArgs) -- get template arguments from parent frame and frane			local url = (target.customArgs['baseURL'] or "") .. (target.customArgs['defaultSuffix'] or "")	local title = target.customArgs['defaultTitle'] or ""	return title, urlend -- moved up top for scopelocal function firstToUpper2(str)    return (str:gsub("^%l", string.upper))end-- clear template arguments that won't be recognised by {{cite web}}local function clearCustomArgs()		local excludeTable = { 'genus', 'species', 'subspecies', 'family', 'order', 'taxon', 		                   'id', 'search' , 'citation', 1, 2, 3, 4 }                          -- add defaults ?		if target.customArgs['exclude'] then		local customTable = mw.text.split (target.customArgs['exclude'] , "%s*,%s*");			for k,v in pairs(customTable) do	    	table.insert (excludeTable, v )		end	end			for k,v in pairs(excludeTable) do	    	if tonumber (v) then	    		v = tonumber (v)  --convert positional parameters (numbers as string) to a number			end			templateArgs[v]=nil --clear content		endend-- function handling the cite web templatep.citeWeb = function(frame, title, url)        -- set url and title if not provided (template parameters override above)    if not templateArgs['url'] and url then    		templateArgs['url']= url    end    if not templateArgs['title'] and title then	    	templateArgs['title'] = title	end    clearCustomArgs()--blank template parameters not for cite web		local citeTemplate = 'cite web'          -- use Template:Cite web unless specified	--if target.citeTemplate then citeTemplate = target.citeTemplate end	return frame:expandTemplate{ title = citeTemplate, args = templateArgs  }end-- p.CiteBook-- for reasons of consisitency within BioRef/FishRef the title parameter is the section-title of {{cite book}}p.citeBook = function(frame, title, url, chapterParams) -- very much a msw3 function            --if (1==1) then return templateArgs['title']  end        -- set url and title if not provided (template parameters override above)    if not templateArgs['url'] and url then    		templateArgs['url']= url    		if target.GoogleBooks then    			templateArgs['url'] = target.GoogleBooks['baseURL'] .. target.GoogleBooks['id']		                   	.. (target.GoogleBooks['defaultPage'] or "&pg=PP1")    			    		end    end    if not templateArgs['title'] and title then	--    	templateArgs['title'] = title 	end	if templateArgs['title'] ~= title or templateArgs['taxon-title'] then -- do we have a section title provided		templateArgs['section'] = templateArgs['title']  -- chapter/section title passed as title parameter		templateArgs['title']   = title -- the work is the book title given in the source data		if target.GoogleBooks then						templateArgs['section-url'] = target.GoogleBooks['baseURL'] .. target.GoogleBooks['id']			local pageSuffix = target.GoogleBooks['defaultPage'] or ""			if templateArgs['page'] or templateArgs['gb-page'] then				pageSuffix = "&pg=PT" .. (templateArgs['gb-page'] or templateArgs['page'] )			end			local searchStr = ""		    -- quoted search {{#if:{{{text|{{{dq|}}}}}}|&dq={{urlencode:{{{text|{{{dq|}}}}}}}}}}		    if templateArgs['q'] then searchStr = "&q=" .. mw.text.encode( templateArgs['q'] ) end		    -- search #if:{{{keywords|{{{q|}}}}}}|&q={{urlencode:{{{keywords|{{{q|}}}}}}}}}}		    if templateArgs['dq'] then searchStr = "&dq=" .. mw.text.encode( templateArgs['dq'] ) end		    		    		    templateArgs['section-url'] = templateArgs['section-url'] .. pageSuffix ..  searchStr            templateArgs['url'] = nil   -- no need for second link to google books		end	    -- if the chapter/section is linked, we can link the main book chapter differently 	    if target.customArgs['altTitle'] then -- if we are using a chapter/section, we can wikilink the book title 	    	templateArgs['title'] = target.customArgs['altTitle']  -- alternative to allow wikilink	    elseif target.customArgs['altURL'] then	    	templateArgs['url'] = target.customArgs['altURL']	    end	end -- end if using supplied title for chapter/section    clearCustomArgs()--blank template parameters not for cite web		local citeTemplate = 'cite book'          -- use Template:Cite web unless specified	--if target.citeTemplate then citeTemplate = target.citeTemplate end	return frame:expandTemplate{ title = citeTemplate, args = templateArgs  }end-- common function for genus and specieslocal function getGenusSpecies()	--TODO standardise genus species handling	local genus, species, subspecies	if (templateArgs['genus']  or templateArgs[2] ) then 	    genus = templateArgs['genus'] or templateArgs[2]        genus = firstToUpper(mw.text.trim(genus))	end	if (templateArgs['species']  or templateArgs[3] ) then 	    species = templateArgs['species'] or templateArgs[3]	    species = 	mw.text.trim(species)	end	if (templateArgs['subspecies']  or templateArgs[4] ) then 	    subspecies = templateArgs['subspecies'] or templateArgs[4]	    subspecies = 	mw.text.trim(subspecies)	end		return genus, species, subspeciesend--#################### MSW3   -- uses cite bookp.MSW3 = function(frame) 	local msw = require('Module:FishRef/MSW')	initialise(frame, msw.MSW3)	return msw.MSW3.main(frame,templateArgs)endp.MSW3merged = function(frame) 	local data = require('Module:FishRef/MSW')	return p._main(frame, data.MSW3)endp.MSW3_standalone = function(frame) 		local data = require('Module:FishRef/MSW')	initialise(frame, data.MSW3)    local url = target.CustomArgs['baseURL']             if templateArgs['title'] and templateArgs['id'] then    	templateArgs['chapter-url']= url .. target.CustomArgs['searchStr']  ..  templateArgs['id']    	templateArgs['chapter'] = templateArgs['title']          	templateArgs['title'] = target.CustomArgs['bookTitle']    	if templateArgs['page'] then    		templateArgs['url'] = target.CustomArgs['googleBooksURL'] .. templateArgs['page'] 		else   	        --return "Page number for google books required"    	end    elseif templateArgs['order'] then    	templateArgs['chapter'] =  "Order " .. templateArgs['order']    	local chapter = target.chapters[templateArgs['order']]    	for k,v in pairs(chapter) do   -- add chapter specific parameters    		templateArgs[k] = v     	end    	templateArgs['chapter-url']= url .. target.CustomArgs['searchStr']  ..  templateArgs['id']    	templateArgs['url']= target.CustomArgs['googleBooksURL']  ..  templateArgs['page']    	if templateArgs['pages'] and templateArgs['page'] then templateArgs['page'] = nil end    else -- default output    	templateArgs['url']= target.CustomArgs['googleBooksURL']  .. "1" -- default to book    	templateArgs['url']= url     end    -- using cite book	clearCustomArgs()--blank template parameters not for cite web	return frame:expandTemplate{ title = 'cite book', args = templateArgs  }end--########################### Functions for access (using invoke) ##############################################--================ Fishbase, Catalog of Fishes (cof) ================p.fishbase    = function(frame) return p._main(frame, data.fishbase) endp.cof         = function(frame) return p._main(frame, data.cof) end p.fotw5       = function(frame) return p._main(frame, data.fotw5) end --=================== ASW6, AmphibiaWeb, ReptileDBp.reptileDB   = function(frame) return p._main(frame, data.reptileDB) endp.ASW6        = function(frame) return p._main(frame, data.ASW6) endp.amphibiaweb = function(frame) return p._main(frame, data.amphibiaweb) end--=========== Birdsp.HBWa        = function(frame) return p._main(frame, data.HBWalive) endp.HBWalive    = function(frame) return p._main(frame, data.HBWalive)  endp.IOC         = function(frame) return p._main(frame, data.IOC) endp.BOW         = function(frame) return p._main(frame, data.BOW) end--======= Mammalsp.asm         = function(frame) return p._main(frame, data.asm) end--======= Plantsp.WFO         = function(frame) return p._main(frame, data.WFO) endp.POWO        = function(frame) return p._main(frame, data.POWO) end-- MSW3 has custom handling (see above)--=========== Otherp.fossilworks = function(frame) return p._main(frame, data.fossilworks) endp.worms       = function(frame) return p._main(frame, data.WoRMS) endp.WoRMS       = function(frame) return p._main(frame, data.WoRMS) endp.col         = function(frame) return p._main(frame, data.col) end --fallback = function() return "hello" end--#########################################################p.main = function(frame) 	local source = mw.text.trim(frame.args[1])	--TODO force to lower case and use lower case for all functions above		if source == "MSW3" then return p.MSW3(frame) end		if source == "ref" or source == "reference" then source = "Reference" end   -- aliases	if source == "Reference" then return p.Reference(frame) end        if source == "HBWa" then source = "HBWalive" end   -- aliases    if source == "powo" then source = "POWO" end   -- aliases    if source == "wfo" then source = "WFO" end   -- aliases    if source == "mdd" then source = "asm" end   -- aliases	--return p[source]['test']	if source == "fishbase"              -- unnecessary?		or source == "cof" 		or source == "fotw5" or source == "Fotw5" 		or source == "reptileDB" 		or source == "amphibiaweb" 		or source == "BOW"		or source == "ASW6" 		or source == "asm" 		or source == "HBWalive" or source == "HBWa" 		or source == "fossilworks" 		or source == "WoRMS" or source == "worms" 		or source == "POWO" or source == "powo" 		or source == "WFO" or source == "wfo" 		or source == "AlgaeBase"		-- and so on	    then return p._main(frame,data[source])	else		-- 		-- is there a point in the default if it needs the named object/table?		return p._main(frame,data[source])	endendp._main = function(frame, source)     --TODO in modular version source will be provided in frame arguments     --local source = mw.getCurrentFrame():getParent().args[1]    local chapterParams = {} -- used for cite book (only MSW3 at moment)        if not source then return "Error: unrecognised source." end        local title, url = initialise(frame, source)        --taxon related parameters    local genus, species, subspecies        if source.db ~= "col" then                             -- col legacy uses positional parameters differently    	genus, species, subspecies = getGenusSpecies()                 end        local family = templateArgs['family']    local order = templateArgs['order']    local taxon = templateArgs['taxon']		local id = templateArgs['id']                                       --id related parameters	local spid = templateArgs['spid'] or templateArgs['species_id']	local genid = templateArgs['genid'] or templateArgs['genus_id']	local citation = templateArgs['citation']     local collection = templateArgs['collection'] or templateArgs['collection_no'] 	local search = templateArgs['search']    local mode, value        -- the functions    if genus and species and source.species then    	title, url = source.species(genus,species,subspecies)    else -- functions with just their own name as parameter    	    	if id then mode = "id"; value = id    	elseif taxon then mode = "taxon"; value = taxon    	elseif order then mode = "order"; value = order    	elseif family then mode = "family"; value = family    	elseif genus then mode = "genus"; value = genus     	elseif spid then mode = "spid"; value = spid    	elseif genid then mode = "genid"; value = genid	        elseif search then mode = "search"; value = search	        elseif citation then mode = "citation"; value = citation	        elseif collection then mode = "collection"; value = collection	    	else    		-- no suitable parameter (use default page)    		if source.default then    			title, url, chapterParams = source.default(title, url)    		end    	end    end    if mode then    	if source[mode] then    		title, url, chapterParams = source[mode](value)      	elseif data.default[mode] then    		title, url, chapterParams = data.default[mode](value, source)    	else    		if source.error then return source.error() end             -- custom error message    	    return "Error: parameter not supported for this source" .. " (" .. mode .. ")"    	end    else     	-- if no mode then use the default title and url set by initialize()    end    if source.citeTemplate == "Cite book" then    	return p.citeBook(frame, title, url, chapterParams)    end	return p.citeWeb(frame, title, url)	end  -- End the function.p.Reference = function(frame)		local refs = require('Module:FishRef/refs')	getArgs(frame, templateArgs)		if templateArgs[2] then		local reference = mw.text.trim(templateArgs[2])		if reference ~= "" and refs[reference] then 			if templateArgs['pages'] then 				refs[reference] = refs[reference]:gsub("}}", "|pages="..templateArgs['pages'].."}}")				refs[reference] = refs[reference]:gsub("|pages=[^|{}%[%]]*(|[^|{}}%[%]]*|pages=)", "%1")			end			if templateArgs['reftags'] == "yes" then				refs[reference] = '<ref name=' .. templateArgs[2] ..'>' .. refs[reference] .. '</ref>'			end   			if templateArgs['expand'] and templateArgs['expand']=='no' or templateArgs['raw']  then   				return refs[reference]   			else   				return frame:preprocess(refs[reference])   			end   		else   			return 'Reference not found: "'	.. templateArgs[2] .. '"'		end	end	return "Reference parameter missing."end -- End the function.-- All modules end by returning the variable containing its functions to Wikipedia.return p