Jump to content

Module:Sandbox

Shortcuts: WD:SB, WD:SANDBOX
From Wikidata
Lua
CodeDiscussionLinksLink count SubpagesDocumentationTestsResultsSandboxLive code All modules



Code

 local p = {} local wiki = string.match(mw.site.server, "%a+") if wiki == "www" then	wiki = "fr" end --import translation local l10n = mw.loadData("Module:Cycling race/l10n") --import data local data = mw.loadData("Module:Cycling race/data") local contentLanguage = mw.getContentLanguage() local wikilang = contentLanguage:getCode() local wikibase = mw.wikibase -- == Structure of the code == -- I) Constant -- II) Translation -- III) Basic functions -- IV) Functions less basic called from other functions -----A) Time functions -----B) Link functions -----C) Functions for the output, like table -----D) Jersey, flag functions -----E) Other (winner) -- V) Main functions ----- A) Function race reference ----- B) Calendar ----- C) Victory ----- Cbis) Function for infobox ----- D) Stage infobox ----- E) List of teams ----- F) Classifications ----- G) Infobox ----- H) Race infobox ----- I) Team roster ----- J) Function list of winners (palmarès) ----- K) List of stages ----- L) List of stages classification ----- M) Start list ----- N) Rider ranking ----- O) Rider infobox ----- P) Team infobox -- .................. ----- Z) Miscellaneous / Other / Tests --Tip: search "--==" to navigate between the sections --== I) Classes declared as global == local textalign = "left" local floattable = "left" local floatinfobox = "right" if wiki == "ar" or wiki == "fa" or wiki == "ur" or wiki == "he" then	textalign = "right"	floattable = "right"	floatinfobox = "left" end local Wikidatalogosize = "12px" if wiki == "ar" then Wikidatalogosize = "15px" end local standardtablecss=data.standardtablecss_part1..textalign..data.standardtablecss_part2 local lang_priority --for lang priority and fallback if l10n["lang_priority"] then	lang_priority=l10n["lang_priority"] else --default	lang_priority={}	table.insert(lang_priority,wikilang)	for _, lang in ipairs({'mul','en', 'fr', 'de','es','nl','it','da'}) do	if lang~=wikilang then	table.insert(lang_priority,lang)	end	end end --"country" means here, that there will be a separated column containing the country name --otherwise a flag is typically added in another column, for instance before the rider name local no_country_calendar={'ru','ar'} local no_country_victories={'ru','ar','da'} local no_country_classification={'es','da','no','ru','ar'} --to avoid wrong display, or country names becoming very long, --available_list==false --> country=false in the old code, --should be implemented here if not l10n["country_name_list"] then	table.insert(no_country_calendar, wiki)	table.insert(no_country_victories, wiki)	table.insert(no_country_classification, wiki) end --Note about WDlink_on --On some wikipedia small wikidata flag are displayed after all data coming from wikidata --to enable that set WDlink_on on true local no_roll_startlist={'fr','da','no','ar','ru','de'} local display_language_in_riderinfobox={'ru'} local display_flag_in_riderinfobox={'ru'} local display_birthnameastitle_in_riderinfobox={'ru'} local display_noweight_in_riderinfobox={'fr','pl'} local display_noage_in_riderinfobox={'pl'} local display_nonickname_in_riderinfobox={'pl'} local display_cm_in_riderinfobox={'pl'} local silver_theme_countries={'da', 'pl'} local backgroundColor="#FFDF80" local backgroundColorLight="#FFF7DF" for _, value in pairs(silver_theme_countries) do -- get data if country should be printed in this wiki	if value == wiki then	backgroundColor="#EAECF0"	backgroundColorLight="#EFEFEF"	end end local function istrue(x) if x and (x == 1 or x == "1" or x == "true") then return true end return nil end --== II) Translation == local function translate(func_name_short, index, w_race, title)	if index==1000 then --code for some custom function	return title	else	if func_name_short then	local func_name	if w_race then	func_name=func_name_short.."_women_translate"	if l10n[func_name] and l10n[func_name][index] then	return l10n[func_name][index]	end	end	func_name=func_name_short.."_translate"	if l10n[func_name][index] then	return l10n[func_name][index]	end	return "translation for "..func_name.." index ".. tostring(index).." not found"	else	error('func_name found')	end	end end local function plural(num)	local plural=false --latin language	local gen_singular=false --for slavic language	local gen_plural=false --for slavic language	if num then	if num > 1 then	plural=true	if num < 5 then -- 2, 3 and 4	gen_singular = true	elseif num > 20 then	local modulo = math.fmod( num, 10)	--modulo==1 --> nothing, it is singular	if modulo>1 and modulo<5 then	gen_singular = true	elseif modulo>4 then	gen_plural=true	end	else	gen_plural=true	end	end	end	return plural, gen_singular, gen_plural end local function black_list( Label)	local black_list=l10n.black_list	--[[ List of Wikipedia articles with the same lemma as the non existing rider article. Those lemmas are printed	as text "black" in the tables, not "blue" or "red". This way there will be no false wikilinks at the WhatLinksHere entry.	List should be updated maybe once a year. ]]	return black_list[Label] end local function country_name_from_list(countryID)	if l10n["country_name_list"] and l10n["country_name_list"][countryID] then	return l10n["country_name_list"][countryID]	end	return nil end local function stageLink(x, a, b) -- x= 10a: a = 10, b = a. x = 5: a = 5, b = ""	local word1	local word2=translate("func_prologue",2) --stage	local word=word2	if wiki=="ar" then return word2 .. " " .. ( a or "" ) , "#" .. word2 .. " " .. ( a or "" ) end -- fr: {{1re}} étape, {{2e}} étape	if wiki=="fr" then	if b == "" then -- series_ordinal without character	if a == "1" then word1 = "1<sup>re</sup> "..word else word1 = a.."<sup>e</sup> "..word end -- table text = {{1re}} étape, {{2ae}} étape,	if a == "1" then word2 = "#1re "..word else word2 = "#"..a.."e "..word end --text of section header = #1re étape, #2e étape	return word1, word2	end	if b ~= "" then -- series_ordinal with character: instead of eg "1a re" it is "1re a"	if a == "1" then word1 = "1<sup>re</sup> "..b.." "..word else word1 = a.."<sup>e</sup> "..b.." "..word end -- table text = {{1re}} étape, {{2ae}} étape,	if a == "1" then word2 = "#1re "..b.." "..word else word2 = "#"..a.."e"..b.." "..word end --text of section header = #1re étape, #2e étape	return word1, word2	end	end	if wiki=="hu" then	if b == "" then return a..". "..word, "#"..a..". "..word	else return a..b.." "..word, "#"..a..b.." "..word end	end	if wiki=="de" or wiki=="da" or wiki=="fo" or wiki=="lb" or wiki=="no" then return a..". "..b.." "..word, "#"..a..". "..b.." "..word end	if wiki=="ca" then return a.."a "..b.." "..word, "#"..a..". "..b.." "..word end	if wiki=="es" then return a..".ª "..word.." "..b, "#"..a..".ª "..word.." "..b end	if wiki=="ast" then	if b == "" then -- series_ordinal without character	if a == "1" or a == "3" then word1 = a.."ᵉʳ "..word else word1 = a.."ª "..word end -- table text = 1ᵉʳ etapa, 2ª etapa, 3ᵉʳ etapa,	if a == "1" or a == "3" then word2 = "#"..a.."ᵉʳ "..word else word2 = "#"..a.."ª "..word end --text of section header = #1ᵉʳ etapa, #2ª etapa, #3ᵉʳ etapa	return word1, word2	end	if b ~= "" then -- series_ordinal with character: instead of eg "1a re" it is "1re a"	if a == "1" or a == "3" then word1 = a.."ᵉʳ "..b.." "..word else word1 = a.."ª "..b.." "..word end -- table text = {{1ᵉʳ}} etapa, {{2ª}} etapa,	if a == "1" or a == "3" then word2 = "#"..a.."ᵉʳ "..b.." "..word else word2 = "#"..a.."ª"..b.." "..word end --text of section header = #1ᵉʳ etapa, #2ª etapa	return word1, word2	end	end	-- default	word1 = x -- table text = 1, 2a, 3	word2 = "#"..word.." ".. x -- text of section header = #Etappe 2a, #Stage 4	return word1, word2 end local function typeofstage(x, typ, noborder)	-- plain, hilly, inter, ... must be "" or "any text"	-- l10nDef[""] = {plain = "", hilly="", inter='', mount='', time_prologue='', time_team='', time_indiv='', uphill='', rest=''}	local l10n=l10n["type_of_stage_translate"]	local border	if noborder then border="" else border="|border|right" end local stages = { ["plain stage"] = "[[File:Plainstage.svg"..border.."|20px|"..l10n.plain.."]]", ["hilly stage"] = "[[File:Hillystage.svg"..border.."|20px|"..l10n.hilly.."]]", ["intermediate stage"] = "[[File:Mediummountainstage.svg"..border.."|20px|"..l10n.inter.."]]", ["mountain stage"] = "[[File:Mountainstage.svg"..border.."|20px|"..l10n.mount.."]]", ["uphill time trial stage"] = "[[File:Mountain Time Trial Stage.svg"..border.."|20px|"..l10n.uphill.."]]", ["rest day"] = "[[File:Stage rest day.svg"..border.."|20px|"..l10n.rest.."]]" }	if stages[x] then	return stages[x]	end	if x=='time trial stage' then	if noborder then border="" else border="|right" end	local stages2 = {	["Q2348250"] = "[[File:Team Time Trial Stage.svg"..border.."|20px|"..l10n.time_team.."]]",	["Q2266066"] = "[[File:Time Trial.svg"..border.."|20px|"..l10n.time_indiv.."]]",	["Q485321"] = "[[File:Time Trial.svg"..border.."|20px|"..l10n.time_prologue.."]]"	}	if stages2[typ] then	return stages2[typ]	end	end end local function typeofstagelogo(stageID, noborder)	local sType	p = mw.wikibase.getBestStatements(stageID, 'P31') -- P31 is 'instance of'	local stages = {	["Q20646667"] = {"plain stage", nil},	["Q20646670"] = {"hilly stage", nil},	["Q20680270"] = {"intermediate stage", nil},	["Q20646668"] = {"mountain stage", nil},	["Q485321"] = {"time trial stage", "Q485321"}, -- prologue	["Q2266066"] = {"time trial stage", "Q2266066"}, -- individual time trial	["Q2348250"] = {"time trial stage", "Q2348250"}, -- team time trial	["Q20679712"] = {"uphill time trial stage", nil}	}	for _, t in pairs(p) do	if t.mainsnak.snaktype == 'value' then	local iOf = t.mainsnak.datavalue.value.id	if stages[iOf] then	sType = typeofstage(stages[iOf][1], stages[iOf][2], noborder)	break	end	end	end	return sType or '' end --== III) basic functions --[[ Get any value for a property which is not deprecated ]] local function firstValue(QID, PID, field)	if QID then	local ss = wikibase.getAllStatements(QID, PID)	for _, s in pairs(ss) do	if s.rank ~= 'deprecated' and s.mainsnak.snaktype == 'value' then	return field and s.mainsnak.datavalue.value[field] or s.mainsnak.datavalue.value	end	end	else	return nil	end end --[[ Go from season of a team to the team ]] local function getParentID(teamID)	return firstValue(teamID, 'P5138', 'id') -- P361 is 'part of'	or firstValue(teamID, 'P361', 'id') -- P5138 is 'season of club or team' end --[[ Get a label in any of the languages in the fallback list of language codes ]] local function getLabelFallback(itemID, fallback)	local label	if fallback==nil then --default	fallback=lang_priority	end	for _, lang in ipairs(fallback) do	label = mw.wikibase.getLabelByLang(itemID, lang)	if label then break end	end	return label end --[[ Get a sitelink from the local wiki or from the fallback list of language codes ]] local function getSitelinkFallback(itemID, fallback)	local link = mw.wikibase.getSitelink(itemID)	if link then return link end	for _, lang in ipairs(fallback) do	link = mw.wikibase.getSitelink(itemID, lang .. 'wiki')	if link then return link end	end	return nil end local arwiki_totemplate = mw.getCurrentFrame():getParent().args["totemplate"] or mw.getCurrentFrame().args["totemplate"] arwiki_totemplate = (wiki == "ar" and arwiki_totemplate and arwiki_totemplate ~= "") or false local function get_lf(frame)	local lf = frame	if string.match(frame:getParent():getTitle(), '%P+') == mw.site.namespaces.Template.name then	lf = frame:getParent()	end	return lf end local function get_and_checkID(frame)	local lf = get_lf(frame)	local entityID = mw.text.trim(lf.args[1])	entityID= string.gsub(entityID, "%c", "") --probably redundant	if type(entityID) ~= 'string' then error('parameter must be a string') end	if not entityID:match('Q%d+') then error('parameter must be a valid Wikidata item (ex: Q42)') end	return entityID, lf end local function make_IllWD2_link(q, arlabel, enlabel, text)	local argse = { ["المعرف"] = q, target='en' }	if arlabel and arlabel ~= '' then	argse.label = arlabel	elseif enlabel and enlabel ~= '' then	argse.enlabel = enlabel	end	if text and text ~= "" then	argse.text = text	end	local final = mw.getCurrentFrame():expandTemplate{ title = 'Ill-WD2', args = argse }	if arwiki_totemplate then	final = "{{Ill-WD2"	for k,v in pairs(argse) do final = final .. "|" .. k .. "=" .. v end final = final .. "}}" end	return final end local function change_listofstages(tab, raceID, header, Id)	-- code used in arwiki only	return tab end --[[ Iterator to get all statements for an entity and property which are not deprecated and have a value]] local function nextStatement(state, i)	repeat	i = i + 1	local s = state[i]	if s and s.rank ~= 'deprecated' and s.mainsnak.snaktype == 'value' then	return i, s	end	until s == nil end local function statements(QID, PID)	return nextStatement, wikibase.getAllStatements(QID, PID), 0 end --[[ Iterator to get all qualifier values for a property for a statement]] local function nextQualifier(state, i)	repeat	i = i + 1	local q = state[i]	if q and q.snaktype == 'value' then	return i, q.datavalue	end	until q == nil end local function qualifiers(statement, PID)	return nextQualifier, statement.qualifiers and statement.qualifiers[PID] or {}, 0 end local function qualifieramount(element, property)	local result	for _, q in qualifiers(element, property) do	result = tonumber(q.value.amount)	break	end	return result end local function dispmoney(amount, unit)	if amount and unit then	local cost = contentLanguage:formatNum(tonumber(amount))	if wiki == 'fo' then cost = string.gsub(cost, "%.", ",") end	if unit == "http://www.wikidata.org/entity/Q4916" then	cost = cost .. ' €'	elseif unit == "http://www.wikidata.org/entity/Q4917" then	cost = cost .. ' $'	end	return cost	end	return nil end --== IV) Functions less basic called from other functions == --=== A) Time functions === --[[ Get a Wikidata statement for an entity and property valid at the given timevalue ]] local function checktime(s,q, time)	local start, startPrecision, END, endPrecision, timePrecision	if not q or not time then	return s	end	local _, _, _, m, _ = string.find(time, "(%d+)%p(%d+)%p(%d+)")	if m=="00" then	timePrecision=9	end	if q.P580 and q.P580[1] and q.P580[1].snaktype == 'value' then -- P580 is start time	start = q.P580[1].datavalue.value.time	startPrecision = q.P580[1].datavalue.value.precision	if startPrecision == 9 or timePrecision==9 then -- precision is years	start = string.sub(start, 1, 5) -- Cut of everything after year	elseif startPrecision == 10 then -- precision is months	start = string.sub(start, 1, 8) -- Cut of everything after month	end	end	if q.P582 and q.P582[1] and q.P582[1].snaktype == 'value' then -- P582 is end time	END = q.P582[1].datavalue.value.time	endPrecision = q.P582[1].datavalue.value.precision	end	if not start or start <= time then	if not END then	return s	end	if endPrecision == 9 or timePrecision==9 then -- precision 9 is 'years'	END = string.sub(END, 1, 6) .. '13' -- Set month to 13	elseif endPrecision == 10 then -- precision 10 is 'months'	END = string.sub(END, 1, 9) .. '32' -- Set day to 32	end	if END >= time then	return s	end	end	return nil end local function getStatementForTime(ID, property, time)	local temp	for _, s in statements(ID, property) do	temp =checktime(s, s.qualifiers, time)	if temp then return temp end	end	return nil end --Display date interval in a natural way: --long: --4-5 January 2020 --4 January - 2 February 2020 --4 January 2020 - 2 February 2021 --small is the same with short month names --Does not work properly if the precision is not sufficient local function getStartEndTime(sTime, eTime, mode)	-- Note: Add the 4formats to "formats" and use funcDate	local lang = contentLanguage	local starttime, endtime	--local format = formats[wiki] or formats['']	if mode==nil then mode='long' end	-- Timevalues is like "+2015-07-04T00:00:00Z"	local y, m = string.match(sTime, "(%d+)-(%d+)-%d+")	local y2, m2 = string.match(eTime, "(%d+)-(%d+)-%d+")	if m=='00' then --manage the 30 November issue	if mode=='long' or mode=="verylong" then	starttime =lang:formatDate( "Y", sTime )	else	starttime ='-'	end	else	if y ~= y2 then	if mode=='long' or mode=="verylong" then	starttime = lang:formatDate( "j F Y", sTime )	else	starttime = lang:formatDate( "j M Y", sTime )	end	elseif m ~= m2 then	if mode=='long' or mode=="verylong" then	starttime = lang:formatDate( "j F", sTime )	else	starttime = lang:formatDate( "j M", sTime )	end	else	starttime = lang:formatDate( "j", sTime )	end	if wiki == "ar" then	if y ~= y2 then starttime = lang:formatDate( "d F Y", sTime )	elseif m ~= m2 then starttime = lang:formatDate( "d F", sTime )	else starttime = lang:formatDate( "d ", sTime ) end	elseif wiki == "br" then	if y ~= y2 then starttime = lang:formatDate( "j", sTime ) .." a viz ".. lang:formatDate( "F Y", sTime )	elseif m ~= m2 then starttime = lang:formatDate( "j", sTime ) .." a viz ".. lang:formatDate( "F", sTime )	else starttime = lang:formatDate( "j", sTime ) .." "	end	elseif wiki == "ca" or wiki == "es" or wiki == "ast" then	if y ~= y2 then	starttime = lang:formatDate( "j", sTime ) .." de ".. lang:formatDate( "F", sTime ) .." de ".. lang:formatDate( "Y", sTime )	elseif m ~= m2 then	starttime = lang:formatDate( "j", sTime ) .." de ".. lang:formatDate( "F", sTime )	else starttime = lang:formatDate( "j", sTime ) .." "	end	elseif wiki == "cs" then	if y ~= y2 then starttime = lang:formatDate( "j. xg Y", sTime )	elseif m ~= m2 then starttime = lang:formatDate( "j. xg", sTime )	else starttime = lang:formatDate( "j", sTime )	end	elseif wiki == "de" or wiki == "da" or wiki == "fo" or wiki == "lb" or wiki == "no" then	if y ~= y2 then starttime = lang:formatDate( "j. F Y", sTime )	elseif m ~= m2 then starttime = lang:formatDate( "j. F", sTime )	else starttime = lang:formatDate( "j.", sTime )	end	elseif wiki == "fi" then	if y ~= y2 then starttime = lang:formatDate( 'j. F"ta" Y', sTime )	elseif m ~= m2 then starttime = lang:formatDate( 'j. F"ta"', sTime )	else starttime = lang:formatDate( "j.", sTime )	end	elseif wiki == "eo" then	if y ~= y2 then starttime = lang:formatDate( "j", sTime ) .."-a de ".. lang:formatDate( "F Y", sTime )	elseif m ~= m2 then starttime = lang:formatDate( "j", sTime ) .."-a de ".. lang:formatDate( "F", sTime )	else starttime = lang:formatDate( "j", sTime ) .."-a "	end	elseif wiki == "eu" then	if y ~= y2 then starttime = lang:formatDate( "Y", sTime ) ..".eko ".. lang:formatDate( "F", sTime ) .."k ".. lang:formatDate( "j", sTime )	elseif m ~= m2 then starttime = lang:formatDate( "F", sTime ) .."k ".. lang:formatDate( "j", sTime )	else starttime = lang:formatDate( "F", sTime ) .."k ".. lang:formatDate( "j", sTime )	end	elseif wiki == "hu" then	starttime = lang:formatDate( "Y. F j.", sTime)	elseif wiki == "ja" then	if y ~= y2 then starttime = lang:formatDate( "Y年m月d日", sTime )	elseif m ~= m2 then starttime = lang:formatDate( "Y年m月d日", sTime )	else starttime = lang:formatDate( "Y年m月d日", sTime )	end	elseif wiki == "lv" then	if m ~= m2 then starttime = lang:formatDate( "Y. \\g\\a\\d\\a j. F", sTime )	else starttime = lang:formatDate( "Y. \\g\\a\\d\\a j.", sTime )	end	elseif wiki == "pl" then	if y ~= y2 then starttime = lang:formatDate( "j xg Y", sTime )	elseif m ~= m2 then starttime = lang:formatDate( "j xg", sTime )	else starttime = lang:formatDate( "j", sTime )	end	end	end	if m2=='00' then --manage the 30 November issue	if mode=='long' or mode=="verylong" then	endtime= lang:formatDate( "Y", eTime )	else	endtime= '-'	end	else	if (mode=='long' and y ~= y2) or mode=="verylong" then	endtime = lang:formatDate("j F Y", eTime)	elseif y ~= y2 then --small	endtime = lang:formatDate("j M Y", eTime)	elseif mode=='long' then	endtime = lang:formatDate("j F", eTime)	else	endtime = lang:formatDate("j M", eTime)	end	if wiki == "ar" then	if mode=='long' or mode=="verylong" or y ~= y2 then endtime = lang:formatDate( "d F Y", eTime )	elseif m ~= m2 then endtime = lang:formatDate( "d F Y", eTime )	else endtime = lang:formatDate( "d F Y", eTime )	end	elseif wiki == "br" then endtime = lang:formatDate( "j", eTime ) .." a viz ".. lang:formatDate( "F Y", eTime )	elseif wiki == "ca" or wiki == "es" or wiki == "ast" then	if mode=='long' or mode=="verylong" or y ~= y2 then	endtime = lang:formatDate( "j", eTime ) .." de "..	lang:formatDate( "F", eTime ) .." de ".. lang:formatDate( "Y", eTime )	else	endtime = lang:formatDate( "j", eTime ) .." de "..	lang:formatDate( "F", eTime )	end	elseif wiki == "cs" then endtime = lang:formatDate( "j. xg Y", eTime )	elseif wiki == "de" or wiki == "da" or wiki == "fi" or wiki == "fo" or wiki == "lb" or wiki == "no" then	if mode=='long' or mode=="verylong" or y ~= y2 then	endtime = lang:formatDate( "j. F Y", eTime )	else	endtime = lang:formatDate( "j. M", eTime )	end	elseif wiki == "eo" then endtime = lang:formatDate( "j", eTime ) .."-a de ".. lang:formatDate( "F Y", eTime )	elseif wiki == "eu" then endtime = lang:formatDate( "Y", eTime ) ..".eko ".. lang:formatDate( "F", eTime ) .."k "..	lang:formatDate( "j", eTime )	elseif wiki == "fi" then endtime = lang:formatDate('j F"ta" Y', eTime)	elseif wiki == "hu" then	if y ~= y2 then endtime = lang:formatDate( "Y. F j.", eTime )	elseif m ~= m2 then endtime = lang:formatDate( "F j.", eTime )	else endtime = lang:formatDate( "j.", eTime )	end	--endtime = lang:formatDate( "Y", eTime ) ..". ".. lang:formatDate( "F j", eTime ) .."."	elseif wiki == "ja" then	if y ~= y2 then endtime = lang:formatDate( "Y年m月d日", eTime )	elseif m ~= m2 then endtime = lang:formatDate( "m月d日", eTime )	else endtime = lang:formatDate( "d日", eTime )	end	elseif wiki == "lv" then	if y ~= y2 then endtime = lang:formatDate( "Y. \\g\\a\\d\\a j. F", eTime )	else endtime = lang:formatDate( "j. F", eTime )	end	elseif wiki == "pl" then endtime = lang:formatDate( "j xg Y", eTime )	end	end	return starttime, endtime end local formats = data.formats -- Display the date, the mode changes the format local function funcDate(date, mode)	-- local date = '+2016-05-20'	-- local mode = 'small'	local format = formats[wiki] or formats[''] local lang = contentLanguage	--handle problems with lack of precision	local dispDate = date	if string.sub(date,7,8)=='00' then	-- lack of month	dispDate= string.sub(date,1,6).."01-01"..string.sub(date,12)	if mode == 'long' or mode == 'onlyyear' or mode == 'monthly' then	mode = 'onlyyear'	else	mode = 'nodate'	end	elseif string.sub(date,10,11)=='00' then -- lack of day	dispDate= string.sub(date,1,9).."01"..string.sub(date,12)	if mode == 'long' then	mode = 'monthly'	elseif mode == 'small' then	mode = 'onlymonth'	elseif mode == 'onlyday' then	mode = 'nodate'	end	end	if format[mode] == nil then mode = 'nodate' end	return contentLanguage:formatDate(format[mode], dispDate) end --[[ get the year for a race as a string, or an empty string]] local function getYear(raceID)	local year = firstValue(raceID, 'P580', 'time') or -- P580 is 'start time'	firstValue(raceID, 'P585', 'time') -- P585 is 'point in time'	if year then	return string.sub(year, 2, 5)	end	return '' end local function isdisqualified(p,q) --disqualification can use deprecated or P1534	local cancelled=""	local disqualified=false	if p and p.rank=='deprecated' then	cancelled='text-decoration:line-through;'	disqualified=true	else	if q and q.P1534 and q.P1534[1].snaktype == 'value' then	local tempdsq=q.P1534[1].datavalue.value.id	if tempdsq=='Q1229261' then	cancelled='text-decoration:line-through;'	disqualified=true	end --disqualified	end	end	return cancelled, disqualified end --=== B) Link functions === local function getOfficialName(teamID, timeOfRace,season,strict) -- for team	--return officialName, isLocal	local strictLang = {mk = true}	local cyrillic = {mk = true, ru = true}	local strictLangBool= strictLang[wiki] or strict local correcttime, best, name, nametemp local wantedLanguages = {}	for i, lang in ipairs(lang_priority) do	wantedLanguages[lang] = i	end --case one, one official name / period overloaded with other languages as qualifier --for instance https://www.wikidata.org/wiki/Q195833 best = 999	for _, p1448 in statements(teamID, 'P1448') do	correcttime=true	if timeOfRace and timeOfRace ~='' then	correcttime =checktime(p1448, p1448.qualifiers, timeOfRace)	end	if correcttime then	if p1448.qualifiers and p1448.qualifiers.P1448 then	local q = p1448.qualifiers.P1448 best = 999	for _, l in pairs(q) do	if l.snaktype == 'value' then	local lang = l.datavalue.value.language	if wantedLanguages[lang] and wantedLanguages[lang] < best then	best = wantedLanguages[lang]	name = l.datavalue.value.text	end	end	end	if name then return name, true end	end	--p1448 and correct time, look in the not qualifier part	lang=p1448.mainsnak.datavalue.value.language	if strictLangBool then	if wiki==lang then	name = p1448.mainsnak.datavalue.value.text	end	elseif wantedLanguages[lang] and wantedLanguages[lang] < best then	best = wantedLanguages[lang]	name = p1448.mainsnak.datavalue.value.text	else	if cyrillic[lang]==nil then --don't display cyrillic for latin wiki	nametemp = p1448.mainsnak.datavalue.value.text	end	end	end	end if name then	return name, true elseif not strictLangBool and nametemp then	return nametemp, false end --no official name, get label	local label=wikibase.getLabel(teamID)	if season and season==true then	if label then return string.sub(label,1,label:len()-5),true end --	else	return label, true -- No official name, try label	end end local function revertfirstlast(name)	local nametable = mw.text.split(name, ",")	if nametable[2] then --there is a coma	return nametable[2].." "..nametable[1]	else	return nametable[1]	end end local function checksitelink(sitelink, label)	if sitelink==label then	return "[[" .. sitelink .."]]"	else	return "[[" .. sitelink .. "|" .. label.. "]]"	end end -- RiderID --> RiderLink local function getRiderLink(riderID, startOfSeason) --startOfSeason optional	--Priority order	--#1 P1813, short name, in correct alphabet, correct time	--#2 P1448, official name, in correct alphabet, correct time	--#3 sitelink (so label from wikipedia) in correct language	--#4 label from wikidata in correct language	--#5 label from wikidata in another language	local strictLang = {mk = true, ru = true}	local strictLangBool= strictLang[wiki]	local sitelink = wikibase.getSitelink(riderID)	local officialname,officialnametemp, language, name	local correctlanguage=false	local listOfProperty={'P1813','P1448'}	for _, prop in ipairs(listOfProperty) do	for _, p1813 in statements(riderID, prop) do	if not officialname or not correctlanguage then	language = p1813.mainsnak.datavalue.value.language	officialnametemp = p1813.mainsnak.datavalue.value.text	if strictLangBool then	if wiki==language then	name=officialnametemp --only exact language	correctlanguage=true	end	else	if wiki==language then --exact language --> ok	name=officialnametemp	correctlanguage=true	elseif strictLang[language]==nil and not officialname then	--normally all "latin" languages use the same name, except for cyrillic translation	local russianLabel= wikibase.getLabelByLang(riderID, "ru")	if russianLabel then	local russianEnd=string.sub(russianLabel, -3)	if russianEnd~="вна" and russianEnd~="вич" then --otherwise rejected	name=officialnametemp	correctlanguage=false	end	else -- no russian label, it is most probably not a cyrillic translation	name=officialnametemp --any language latin	correctlanguage=false	end	end	end	if startOfSeason~= nil then	local q = p1813.qualifiers	if q then	local temp = checktime(name,q,startOfSeason)	if temp then officialname = name end--if the time is correct than it is finished	else	officialname = name	end	else	officialname = name	end	end	end	end	if sitelink and officialname then --if there is an official name, then use it	return checksitelink(sitelink, officialname), correctlanguage	else	if officialname then return officialname end	if sitelink then	if wiki == "de" then	local label = wikibase.getLabelByLang(riderID, wiki)	if label then	local p27 = wikibase.getBestStatements(riderID, 'P27') -- P27 is country of citizenship	if p27[1] and p27[1].mainsnak.snaktype == 'value' then	local c = p27[1].mainsnak.datavalue.value.id	if c=="Q159" or c=="Q184" or c=="Q212" or c=="Q232" then -- Q159, Q184, Q212, Q232 is Russia, Belarus, Ukraine, Kazakhstan	return checksitelink(sitelink, label), correctlanguage	end	end	end	end	if wiki == 'ru' then	local label = revertfirstlast(mw.text.trim(string.gsub(sitelink, "%b()", ""), " "))	return checksitelink(sitelink, label), correctlanguage	else	return checksitelink(sitelink, mw.text.trim(string.gsub(sitelink, "%b()",""), " ")), correctlanguage	end	end	-- No WP article. Display label, and make it a red link if no other article uses the title	local link	local label = wikibase.getLabelByLang(riderID, wiki)	if label then	if wiki == 'ar' then	link = make_IllWD2_link(riderID, label)	else	if wiki=='ru' then	label=revertfirstlast(label)	end	if black_list( label) then	link = label	else	local title = mw.title.new(label)	if title and title.exists then	link = label	else	link = "[[" .. label.. "]]"	end	end	end	return link, correctlanguage	end	-- No label in the local language. Try other languages, but don't link.	correctlanguage=false	if wiki == 'ar' then	link = make_IllWD2_link(riderID)	else	link = getLabelFallback(riderID)	if link then	link = string.gsub(link, "%b()", "")	else	link = "(label missing)"	end	end	return link, correctlanguage	end end -- Get the countryID, return a single one, not a list local function getCountryID(entityID, timeOfRace)	local countryID	if entityID then	local stm = getStatementForTime(entityID, 'P1532', timeOfRace) -- P1532 is country for sport	if stm == nil then	stm = getStatementForTime(entityID, 'P17', timeOfRace) -- P17 is country	end	if stm then countryID = stm.mainsnak.datavalue.value.id end	end	return countryID end --[[ Get the name of a country ]] local function getCountryName(countryID)	local name = country_name_from_list(countryID)	if name == nil then	local label, lang = wikibase.getLabelWithLang(countryID)	--[[ Uses standard language fallback. Should not return nil, nil, as all countries have English labels. ]]	if lang == wikilang then	name = label	elseif lang then	name = label .. ' (' .. lang .. ')'	end	end	return name or '' end --[[ Get sitelink with no wiki no formating ]] local function getRawTeamLink(teamID)	local sitelink	local parentID = getParentID(teamID)	if parentID then -- try parent team first	sitelink = mw.wikibase.getSitelink(parentID)	end	if not sitelink then	sitelink = mw.wikibase.getSitelink(teamID)	end	return sitelink end --[[ Get sitelink, categoryID and maybe country for a team.	Returns sitelink, team category ID, countryID (only countryID if country arg is true ]] local function getTeamLinkCat(teamID, timeOfRace, country, forceParentlink)	local name, sitelink, catID, countryID, p31	local parentID = getParentID(teamID)	local season=false	-- Find team category	--Hypothesis, it is a season, look in P2094	for _, p2094 in statements(teamID, 'P2094') do	if checktime(p2094, p2094.qualifiers, timeOfRace) then	if data.teamCats[p2094.mainsnak.datavalue.value.id] then	catID = p2094.mainsnak.datavalue.value.id	season=true	break	end	end	end	--check if season	if season==false then --otherwise already clear	for _, p in statements(teamID, 'P31') do	local natureID = p.mainsnak.datavalue.value.id	if natureID=="Q53534649" then	season=true	break	end	end	end	--look by the parent, then P31 is used for the category	if (not catID and parentID and season) then	p31 = getStatementForTime(parentID, 'P31', timeOfRace)	elseif not season then --it is the team look in the team directly	p31 = getStatementForTime(teamID, 'P31', timeOfRace)	end	if p31 and data.teamCats[p31.mainsnak.datavalue.value.id] then	catID = p31.mainsnak.datavalue.value.id	end	-- Find country if needed	if country or data.natTeamCats[catID] then	countryID = getCountryID(teamID, timeOfRace)	end	if countryID and data.natTeamCats[catID] then	if countryID=='Q145' then	name = getCountryName('Q23666')	else --to solve the United-Kingdom/Great Britain problem by national team	name = getCountryName(countryID)	end	local t={Q20738667=34, Q54555994=35, Q99658502=36}	if t[catID] then --add U23, U19, B, (note: why "B" and not B)	name = name ..' '..translate("headoftableIII",t[catID])	end	sitelink = getRawTeamLink(teamID)	else	-- It is not a national cycling team	local isLocal	if season and not forceParentlink then	sitelink = wikibase.getSitelink(teamID)	name, isLocal = getOfficialName(teamID, timeOfRace,true) --problem here is that the label will be used if no official name, official name of the parent would actually be better...	if not sitelink and parentID then	sitelink = wikibase.getSitelink(parentID)	end	else	if parentID then -- try parent team first	sitelink = wikibase.getSitelink(parentID)	name, isLocal = getOfficialName(parentID, timeOfRace)	end	if not sitelink then	sitelink = wikibase.getSitelink(teamID)	end	end	if not name or (not isLocal and l10n["lang_priority"]) then	local partName, partIsLocal = getOfficialName(teamID, timeOfRace)	if partName and (not name or partIsLocal) then	name = partName	end	end	end	if sitelink then	if name then	sitelink = '[[' .. sitelink .. '|' .. name .. ']]'	else	sitelink = '[[' .. sitelink .. ']]'	end	else if wiki == "ar" then	local arlabel = mw.wikibase.getLabelByLang((parentID or ''), 'ar') or "" local texte = mw.wikibase.getLabelByLang(teamID, 'ar') or "" sitelink = make_IllWD2_link((parentID or teamID), arlabel, name, texte) else if name then sitelink = name else sitelink = (parentID and wikibase.getLabel(parentID)) or wikibase.getLabel(teamID) or 'No name' end end	end	return sitelink, catID, countryID end local function getTeamCodeCat(teamID, timeOfRace)	-- Find team category	local codeUCI	local p1998 =getStatementForTime(teamID, 'P1998', timeOfRace)	if p1998 then	codeUCI = p1998.mainsnak.datavalue.value	else	local parentID = getParentID(teamID)	if parentID then	p1998 =getStatementForTime(parentID, 'P1998', timeOfRace)	if p1998 then	codeUCI = p1998.mainsnak.datavalue.value	end	end	end	return codeUCI end local function getReference(lf,statement, outputLocal)	local function formatRefDate(date, precision)	if precision == 9 then -- Precision is year	return string.sub(date, 2, 5)	elseif precision == 10 then -- Precision is month	return contentLanguage:formatDate("F Y", string.sub(date, 2, 8))	elseif precision >= 11 then -- Precision is day (or less)	return funcDate(date, 'long')	end	end	local ref = statement.references	if not ref or not ref[1] then	return nil	end	ref = ref[1].snaks	if ref.P854 and ref.P854[1] and ref.P854[1].snaktype == 'value' then -- P854 is 'reference URL'	local refURL = ref.P854[1].datavalue.value	local refTitle = ''	local refDate = ''	local refRetrieved = ''	local refLang = ''	if ref.P1476 and ref.P1476[1] and ref.P1476[1].snaktype == 'value' then -- P1476 is 'title URL'	refTitle = ref.P1476[1].datavalue.value.text	local lang = ref.P1476[1].datavalue.value.language	if lang ~= wikilang then	refLang = '(' .. lang .. ')' if wiki == 'ar' then refLang = lang end end	end	if ref.P577 and ref.P577[1] and ref.P577[1].snaktype == 'value' then -- P577 is 'publication date'	local value = ref.P577[1].datavalue.value	refDate = formatRefDate(value.time, value.precision)	if (wiki == 'ar') then refDate = refDate	else refDate = ', ' .. refDate	end	end	if ref.P813 and ref.P813[1] and ref.P813[1].snaktype == 'value' then -- P813 is 'retrieved'	local value = ref.P813[1].datavalue.value	refRetrieved = formatRefDate(value.time, value.precision)	if wiki == "de" then	refRetrieved = ", (abgerufen am " .. refRetrieved .. ')'	elseif wiki == "ar" then	refRetrieved = refRetrieved	elseif wiki == "fr" then	refRetrieved = " (consulté le " .. refRetrieved .. ')'	elseif wiki == "da" then	refRetrieved = " Hentet " .. refRetrieved .. '.'	else	refRetrieved = " Retrieved " .. refRetrieved .. '.'	end	end	local domain = string.match(refURL, '//([^/]+)')	if string.sub(domain, 1, 4) == 'www.' then	domain = string.sub(domain, 5)	end	local refText	if wiki == "ar" then refText = '{{web cite' ..	'|url = ' .. refURL ..	'|title= ' .. refTitle ..	'|lang = ' .. refLang ..	'|website=' .. domain ..	'|date=' .. refDate ..	'|accessdate=' .. refRetrieved ..	'}}' elseif wiki == "fr" then -- fr: "(en) « Lloyd Mondory ... EPO », sur velonews.competitor.com (consulté le 30 april 2016), 30 octobre 2015."	local sur = ', sur <span style="font-style:italic;"> ' .. domain .. '</span>'	refText = refLang .. ' « ['.. refURL .. ' '.. refTitle .. '] »' .. sur .. refRetrieved .. refDate .. '.'	elseif wiki == "de" then	local In = ' In: <span style="font-style:italic;">' .. domain .. '</span>'	refText = '<span style="font-style:italic;">['.. refURL.. ' '.. refTitle.. '.]</span> ' ..	In .. refDate .. refRetrieved ..'.'	else	local at = ', <span style="font-style:italic;"> ' .. domain .. '</span>'	refText = refLang .. ' [' .. refURL .. ' ' .. refTitle .. ']' .. at .. refDate .. '.' .. refRetrieved	end	if outputLocal==1 then	return refText	else local refargs = {} if wiki ~= "ar" then refargs.name = refText end	return lf:extensionTag('ref', refText, refargs)	end	end end --Some wikipedia, like WP:ar, don't use model like --{{#invoke:Cycling race/infobox|Q123}} --But have the module included in another module --{{#invoke:wikidata|Cycling race/infobox|... --in this case frame does not refer to the arguments of /infobox but to the wanted ones --read https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#frame-object local function get_arg(index, lf, number)	if lf.args[index] then	if number then	return tonumber(lf.args[index])	else	return string.gsub(lf.args[index], "%c", "")	end	end	return nil end local function getImageOrMap(QID, PID)	local p18 = wikibase.getBestStatements(QID, PID) -- P18 is 'image'	local first	for _, image in pairs(p18) do	if image.mainsnak.snaktype == 'value' then	if not first then	first = image.mainsnak.datavalue.value	end	local q = image.qualifiers	if q and q.P2096 then	for _, caption in pairs(q.P2096) do -- P2096 is 'caption'	if caption.snaktype == 'value' and caption.datavalue.value.language == wikilang then	return image.mainsnak.datavalue.value, caption.datavalue.value.text	end	end	end	end	end	return first end local function getLogo(QID)	return getImageOrMap(QID, 'P154') end local function getImage(QID)	return getImageOrMap(QID, 'P18') end local function getMap(QID)	return getImageOrMap(QID, 'P242') end local function getSectionalView(QID)	return getImageOrMap(QID, 'P2713') end --[[ Get link for race or competition]] local function raceLink(QID)	local sitelink = wikibase.getSitelink(QID)	local instanceOf = firstValue(QID, 'P3450', 'id')	if instanceOf == nil then	instanceOf = firstValue(QID, 'P31', 'id') -- P31 is 'instance of'	end	if instanceOf == 'Q1137352' then -- Q1137352 is 'French Road Cycling Cup'	local label2 = wikibase.getLabel(instanceOf)	if sitelink then	if label2 then return '[[' .. sitelink .. '|' .. label2 .. ']]' end	return '[[' .. sitelink .. ']]'	end	local sitelink2 = wikibase.getSitelink(instanceOf)	if sitelink2 then return '[[' .. sitelink2 ..'|' .. string.gsub(sitelink2, " %b()", "") .. ']]' end	if label2 then return label2 end	end	if sitelink then return "[[".. sitelink.. "]]" end	return wikibase.getLabel(QID) or '' end local function getPlaceLink(placeID,timeOfRace)	local sitelink = wikibase.getSitelink(placeID)	local name = country_name_from_list(placeID)	if name==nil then	name=getOfficialName(placeID, timeOfRace,nil,true) --name should be in the right language	end	if sitelink then	-- Delete " (...)" form e.g. "Unley (South Australia)"	if name ~=nil then	return '[[' .. sitelink .. '|' .. name .. ']]'	else	return '[[' .. sitelink .. '|' .. string.gsub(sitelink, ' %b()', '') .. ']]'	end	end	local label = wikibase.getLabel(placeID) or ''	if wiki == 'ar' then	arlabel = wikibase.getLabelByLang(placeID, "ar")	return make_IllWD2_link(placeID, arlabel)	end	return contentLanguage:ucfirst(label) end -- ClassID --> ClassLink -- some WPs use a unique article for this case local function classLinkFn(classID, circuitID)	local link, label	if wiki~="fr" then --not used	link= wikibase.getSitelink('Q22348500') -- Q22348500 is 'cycling race class'	elseif circuitID then	link =wikibase.getSitelink(circuitID) --optional parameter to obtain [circuitlink|class label]	end	if classID=="Q18536594" then	if wiki=="fr" then	label="JO"	else	label="OG"	end	else label = getLabelFallback(classID)	end	if label and link then	link = '[[' .. link .. '|' .. label .. ']]'	elseif link then	link = '[[' .. link .. ']]'	elseif label then	link = label	else	link=''	end	if wiki == "ar" then-- right now Q22348500 has no link in "ar"	link = make_IllWD2_link(classID , "", label)	end	return link end --[[ Get local content to a infoboxe from template args ]] local function getLocalContent(contents, args)	for _, content in pairs(contents) do	local name = content.name	if not name then error('translation missing in Module:Cycling race/l10n of your wikipedia') end	local nameNoShy = string.gsub(name, '&#173;', '') -- filter soft hyphen out	local nameNoShyLow, name_pluralNoShyLow	if nameNoShy then	nameNoShyLow = mw.ustring.lower(nameNoShy)	end	local name_plural = content.name_plural	local name_pluralNoShy = name_plural and string.gsub(name_plural, '&#173;', '') -- filter soft hyphen out	if name_pluralNoShy then	name_pluralNoShyLow = mw.ustring.lower(name_pluralNoShy)	end	if args[nameNoShy] and args[nameNoShy] ~= '' then	if content.special then	local newname, value = string.match(args[nameNoShy], '([^:]+):(.*)')	if value and mw.text.trim(value) ~= '' then	content.name = mw.text.trim(newname)	content.content = mw.text.trim(value)	end	else	content.content = mw.text.trim(args[nameNoShy])	end	elseif nameNoShyLow and args[nameNoShyLow] and args[nameNoShyLow] ~= '' then	if content.special then	local newname, value = string.match(args[nameNoShyLow], '([^:]+):(.*)')	if value and mw.text.trim(value) ~= '' then	content.name = mw.text.trim(newname)	content.content = mw.text.trim(value)	end	else	content.content = mw.text.trim(args[nameNoShyLow])	end	elseif args[name_pluralNoShy] and args[name_pluralNoShy] ~= '' then	content.name = content.name_plural	content.content = mw.text.trim(args[name_pluralNoShy])	elseif name_pluralNoShyLow and args[name_pluralNoShyLow] and args[name_pluralNoShyLow] ~= '' then	content.name = content.name_plural	content.content = mw.text.trim(args[name_pluralNoShyLow])	end	end end local function checkDis(q)	dis="road"	if q and q.P642 and q.P642[1] and q.P642[1].snaktype == 'value' then	if q.P642[1].datavalue.value.id == 'Q520611' or q.P642[1].datavalue.value.id =='Q1031445' then	onlyRoad=false	dis="mountainBike"	elseif q.P642[1].datavalue.value.id == 'Q335638' then	onlyRoad=false	dis="cycloCross"	elseif q.P642[1].datavalue.value.id == 'Q221635' then	onlyRoad=false	dis="track"	end	end	return dis end -- Rider --> Team link local function getTeam(riderID, timeOfRace, q)	-- q: qualifiers of statement in race entity where the rider is the value	local teamID, link, catID, countryID	if q and q.P54 and q.P54[1].snaktype == 'value' then -- P54 is member of sports team	teamID = q.P54[1].datavalue.value.id	link, catID, countryID = getTeamLinkCat(teamID, timeOfRace)	else	for _, s in statements(riderID, 'P54') do	if not link then --like a break	p54 =checktime(s, s.qualifiers, timeOfRace)	if p54 then	dis=checkDis(p54.qualifiers)	if dis=='road' then --by default	teamID = p54.mainsnak.datavalue.value.id	link, catID, countryID = getTeamLinkCat(teamID, timeOfRace)	end	end	end	end	end	return link, teamID, catID, countryID end --RiderID --> UCI code local function getTeamCode(riderID, timeOfRace, q)	-- q: qualifiers of statement in race entity where the rider is the value	local teamID, code	if q and q.P54 and q.P54[1].snaktype == 'value' then -- P54 is member of sports team	teamID = q.P54[1].datavalue.value.id	code = getTeamCodeCat(teamID, timeOfRace)	else	local p54 = getStatementForTime(riderID, 'P54', timeOfRace)	if p54 then	teamID = p54.mainsnak.datavalue.value.id	code= getTeamCodeCat(teamID, timeOfRace)	end	end	return code end local function seasonToTeamID(teamID)	if teamID then	local parentID=getParentID(teamID)	if parentID then--season was used	return parentID	else	return teamID	end	else	return nil	end end local function wdLink(id)	local text = "[[File:Wikidata-logo S.svg| " .. Wikidatalogosize .. "|link=d:" .. id .. "]]"	if arwiki_totemplate then text = '{{عدل في ويكي بيانات|type1=1|id=' .. id .. '}}' end return text end local function WPlinkpure(Qnumber)	local link=''	local Sitelink = wikibase.getSitelink(Qnumber) -- link to WParticle	local Label = getLabelFallback(Qnumber) or ''	if Sitelink ~= nil then link = "[[" .. Sitelink .. "|" .. mw.text.trim(string.gsub(Sitelink, "%b()", "")..' ') .. "]]"	elseif wiki == 'ar' then	arlabel = mw.wikibase.getLabelByLang(Qnumber, 'ar') or ""	link = make_IllWD2_link(Qnumber , arlabel , Label)	else link = mw.ustring.gsub(Label, "^(%a)", function (x) return mw.ustring.upper(x) end)	end	return link end --=== C) Function for the output === local function getCountryBool(no_country_list)	local country = true	if no_country_list then	for _, value in pairs(no_country_list) do -- get data if country should be printed in this wiki	if value == wiki then country = false end	end	end	return country end local function handle_error_message(s)	local error_message=''	if s.error_message and s.error_message ~= 0 then	error_message = func_error_message( 1)	error_message = mw.ustring.gsub(error_message, "<1>", s.property)	error_message = mw.ustring.gsub(error_message, "<2>", mw.wikibase.label( s.item ))	error_message = mw.ustring.gsub(error_message, "<3>", s.item)	error_message = ' [[File:Exclam icon.svg|12px|'.. error_message .. ']]'	end	return error_message end local function tableA(s)	local error_message=handle_error_message(s)	local t = mw.html.create('table')	:addClass('sortable')	:attr('cellpadding', '0')	:attr('cellspacing', '0')	:css('border' , '1px solid rgb(200,200,200)')	:css('padding', '3px')	local title =translate(s.header_function,s.header_1, s.w_race, s.title)	if s.header_1 == 19 and wiki == "ar" then title = title .. " " .. s.year end	local wd_link = mw.html.create('span'):cssText('float:left; margin: 0 5px'):wikitext(wdLink(s.item..'#'..s.property))	if arwiki_totemplate then wd_link = wdLink(s.item..'#'..s.property) end	local caption = t:tag('tr'):tag('th'):attr('colspan', tostring(#s.header_2 + 1))	:cssText('padding:2px; text-align:center; line-height: 1.8em;')	:css('background-color',backgroundColor)	caption:wikitext(tostring(wd_link)..' '..error_message ..' '..title)	local country=getCountryBool(s.no_country)	local header = t:tag('tr')	for i,k in ipairs(s.header_2) do	if i == s.country_column then	if country == true then	header:tag('th')	:cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap')	:wikitext(translate(s.header_function,k,s.w_race))	end	end	if i ~= s.country_column then	local column = header:tag('th')	:cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap')	:wikitext(translate(s.header_function,k,s.w_race))	if s.data_sort_type[i] == 'unsortable' then	column:addClass('unsortable')	end	end	end	return t end local function tableB(s) --for startlist	local error_message=handle_error_message(s)	local roll = true	for _, value in pairs(s.no_roll_startlist) do -- get data if country should be printed in this wiki	if value == wiki then roll = false end	end	local cssTable= "border: 1px solid rgb(200,200,200); margin: 0 0 0 0;"..	"background-color: rgb(255, 255, 255); padding: 0px; float: left;"..	"clear: left; ; text-align: left; vertical-align: top; font-size: 85%; line-height: 1.8em;"	local wdlink_span = mw.html.create('span'):css('float',floattable):wikitext(wdLink(s.item.. '#'.. s.property)..' '..error_message)	if arwiki_totemplate then wdlink_span = wdLink(s.item..'#'..s.property) end	if roll == true then	local rollTable1 = mw.html.create('div'):addClass("NavFrame")	:cssText('center = margin: 0 0.5em 0;clear:both; border: 1px solid rgb(200,200,200);' ..	'cellpadding="4" cellspacing="0" style="width:100%; background-color: rgb(255, 255, 255);padding: 5px;'..	'margin-bottom:1em; background-color:'..backgroundColor..';')	:attr('title','['..translate("startlist",14)..']/['..translate("startlist",15)..']')	local tDiv= rollTable1:tag('div'):addClass("NavHead")	:cssText('text-align:'.. textalign .." =;height:1.8em; color:black;font-weight:bold;")	:css('background-color',backgroundColor)	tDiv:tag('span')	local tSpan=tDiv:wikitext(tostring(wdlink_span))	tDiv:wikitext(translate("startlist",1,s.w_race or false))	tDiv = rollTable1:tag('div'):addClass("NavContent"):cssText("margin:0; background:white; display:block; text-align:left;")	local tTable= tDiv:tag('table'):cssText("border:1px solid rgb(200,200,200)")	local tCell = tTable:tag('tr'):tag('td')	local insideTable =tCell:tag('table'):attr('cellpadding','4') -- cellspacing="0" style="width:100%;" color: black;	:cssText(cssTable)	return rollTable1, insideTable	else	--otherwise problem of clear	local tab = mw.html.create('table')	tCell=tab:tag('td')	local tTable =tCell:tag('table')	:attr('cellpadding','0')	:cssText(cssTable)	tCell = tTable:tag('tr'):tag('th')	:css("background-color",backgroundColor)	:attr('colspan','3'):attr('align','center')	tCell:node(wdlink_span)	tCell:wikitext(translate("startlist",1,s.w_race or false)) local tRow=tCell:tag('tr')	return tab, tRow	end end --=== D) Jersey, flag functions === --used from 2 functions local flags = {	Q16 = {'CAN', {'Flag of Canada.svg', '+1965-02-15'}},	Q17 = {'JPN', {'Flag of Japan.svg', '+1999-08-13'},	{'Flag of Japan (1870–1999).svg', '+1870-02-27', '+1999-08-12'}},	Q20 = {'NOR', {'Flag of Norway.svg', '+1821-07-13'}},	Q27 = {'IRL', {'Flag of Ireland.svg', '+1980-07-29'},	{'Olympic flag.svg', '+1980-07-19', '+1980-07-29'}, -- OG-1980	{'Flag of Ireland.svg', '+1937-12-29', '+1980-07-19'}},	Q28 = {'HUN', {'Flag of Hungary.svg', '+1957-05-23'}},	Q29 = {'ESP', {'Flag of Spain.svg', '+1981-12-06'},	{'Flag of Spain (1977–1981).svg', '+1977-01-21', '+1981-12-06'},	{'Flag of Spain (1945–1977).svg', '+1945-10-11', '+1977-01-21'},	{'Flag of Spain (1938–1945).svg', '+1939', '+1945-10-11'},	{'Flag of the Second Spanish Republic.svg', '+1931-04-14', '+1939'},	{'Flag of Spain (1785–1873, 1875–1931).svg', '+1874', '+1931-04-13'}},	Q30 = {'USA', {'Flag of the United States.svg', '+1960-07-04'}},	Q31 = {'BEL', {'Flag of Belgium (civil).svg', '+1980-07-29'},	{'Olympic flag.svg', '+1980-07-19', '+1980-07-29'}, -- OG-1980	{'Flag of Belgium (civil).svg', '+1800', '+1980-07-19'}},	Q32 = {'LUX', {'Flag of Luxembourg.svg'}},	Q33 = {'FIN', {'Flag of Finland.svg', '+1918-05-29'}},	Q34 = {'SWE', {'Flag of Sweden.svg'}},	Q35 = {'DEN', {'Flag of Denmark.svg', '+1980-07-29'},	{'Olympic flag.svg', '+1980-07-19', '+1980-07-29'}, -- OG-1980	{'Flag of Denmark.svg', '+1800', '+1980-07-19'}},	Q36 = {'POL', {'Flag of Poland.svg'}},	Q37 = {'LTU', {'Flag of Lithuania.svg', '+2004-09-01'},	{'Flag of Lithuania (1988-2004).svg', '+1990-03-11', '+2004-09-01'}},	Q38 = {'ITA', {'Flag of Italy.svg', '+1980-07-29'},	{'Olympic flag.svg', '+1980-07-19', '+1980-07-29'}, -- OG-1980	{'Flag of Italy.svg', '+1946-06-19', '+1980-07-19'},	{'Flag of Italy (1861–1946).svg', '+1861', '+1946-06-19'}},	Q39 = {'SUI', {'Flag of Switzerland.svg', '+1980-08-29'},	{'Olympic flag.svg', '+1980-07-19', '+1980-07-29'}, -- OG-1980	{'Flag of Switzerland.svg', '+1879-01-01', '+1980-07-19'}},	Q40 = {'AUT', {'Flag of Austria.svg', '+1945-05-01'},	{'Flag of Austria.svg', '+1919-10-21', '+1938-03-13'}},	Q41 = {'GRE', {'Flag of Greece.svg', '+1978'}},	Q43 = {'TUR', {'Flag of Turkey.svg'}},	Q45 = {'POR', {'Flag of Portugal.svg', '+1911-06-30'}},	Q55 = {'NED', {'Flag of the Netherlands.svg', '+1980-07-29'},	{'Olympic flag.svg', '+1980-07-19', '+1980-07-29'}, -- OG-1980	{'Flag of the Netherlands.svg', '+1806', '+1980-07-19'}},	Q77 = {'URU', {'Flag of Uruguay.svg'}},	Q96 = {'MEX', {'Flag of Mexico.svg', '+1968-09-16'},	{'Flag of Mexico (1934-1968).svg', '+1934', '+1968-09-16'}},	Q114 = {'KEN', {'Flag of Kenya.svg'}},	Q115 = {'ETH', {'Flag of Ethiopia.svg', '+1996-10-31'}},	Q117 = {'GHA', {'Flag of Ghana.svg', '+1966-02-28'}}, Q142 = {'FRA', {'Flag of France (1794–1815, 1830–1974, 2020–present).svg', '+2020-07-14'}, {'Flag of France.svg', '+1980-07-29', '+2020–07-14'},	{'Olympic flag.svg', '+1980-07-19', '+1980-07-29'}, -- OG-1980 {'Flag of France.svg', '+1794-05-20', '+1980-07-19'}},	Q145 = {'GBR', {'Flag of the United Kingdom (3-5).svg', '+1980-07-29'},	{'Olympic flag.svg', '+1980-07-19', '+1980-07-29'}, -- OG-1980	{'Flag of the United Kingdom (3-5).svg', '+1980-07-19'}},	Q148 = {'CHN', {"Flag of the People's Republic of China.svg", '+1985'}},	Q155 = {'BRA', {'Flag of Brazil.svg', '+1992-05-11'},	{'Flag of Brazil (1968–1992).svg', '+1968-05-28', '+1992-05-11'}},	Q159 = {'RUS', {'Flag of Russia.svg', '+1993-12-11'},	{'Flag of Russia (1991–1993).svg', '+1991-08-22', '+1993-12-11'},	{'Flag of the Russian Soviet Federative Socialist Republic.svg', '+1954', '+1991-08-22'},	{'Flag of the Russian Soviet Federative Socialist Republic (1937–1954).svg', '+1937', '+1954'}},	Q183 = {'GER', {'Flag of Germany.svg', '+1949-05-23'},	{'Flag of the German Reich (1935–1945).svg', '+1935-09-15', '+1945-05-23'},	{'Flag of the German Reich (1933–1935).svg', '+1933-03-12', '+1935-09-15'},	{'Flag of Germany (3-2 aspect ratio).svg', '+1919-04-11', '+1933-03-12'},	{'Flag of the German Empire.svg', '+1871-04-16', '+1919-04-11'}},	Q184 = {'BLR', {'Flag of Belarus.svg', '+2012-05-11'},	{'Flag of Belarus (1995–2012).svg', '+1995-06-07', '+2012-05-11'},	{'Flag of Belarus (1918, 1991–1995).svg', '+1991-09-19', '1995-06-07'}},	Q189 = {'ISL', {'Flag of Iceland.svg', '+1944-06-17'}},	Q191 = {'EST', {'Flag of Estonia.svg'}},	Q211 = {'LAT', {'Flag of Latvia.svg'}},	Q212 = {'UKR', {'Flag of Ukraine.svg', '+1992-01-28'}},	Q213 = {'CZE', {'Flag of the Czech Republic.svg', '+1920-03-30'}},	Q214 = {'SVK', {'Flag of Slovakia.svg'}},	Q215 = {'SLO', {'Flag of Slovenia.svg'}},	Q217 = {'MDA', {'Flag of Moldova.svg'}},	Q218 = {'ROU', {'Flag of Romania.svg', '+1989-12-27'},	{'Flag of Romania (1965-1989).svg', '+1989-12-27', '+1965'},	{'Flag of Romania (1952-1965).svg', '+1952', '+1965'},	{'Flag of Romania (1948-1952).svg', '+1948-01-08', '+1952'},	{'Flag of Romania.svg', '12. april 1867-04-12', '+1948-01-08'}},	Q219 = {'BUL', {'Flag of Bulgaria.svg', '+1990-11-22'},	{'Flag of Bulgaria (1971 – 1990).svg', '+1971-05-18', '+1990-11-22'}},	Q222 = {'ALB', {'Flag of Albania.svg', '+1992'}},	Q224 = {'CRO', {'Flag of Croatia.svg', '+1990-12-21'},	{'Flag of Croatia (white chequy).svg', '+1990-06-27', '+1990-12-21'}},	Q227 = {'AZE', {'Flag of Azerbaijan.svg'}},	Q228 = {'AND', {'Flag of Andorra.svg'}},	Q229 = {'CYP', {'Flag of Cyprus.svg', '+2006-08-20'},	{'Flag of Cyprus (1960-2006).svg', '+1960-08-16', '+2006-08-20'}},	Q232 = {'KAZ', {'Flag of Kazakhstan.svg'}},	Q235 = {'MON', {'Flag of Monaco.svg'}},	Q238 = {'SMR', {'Flag of San Marino.svg', '+1980-07-29'},	{'Olympic flag.svg', '+1980-07-19', '+1980-07-29'}, -- OG-1980	{'Flag of San Marino.svg', '+1980-07-19'}},	Q241 = {'CUB', {'Flag of Cuba.svg'}},	Q244 = {'BAR', {'Flag of Barbados.svg'}},	Q252 = {'INA', {'Flag of Indonesia.svg'}},	Q258 = {'RSA', {'Flag of South Africa.svg', '+1994-04-27'},	{'Flag of South Africa (1928–1994).svg', '+1928-05-31', '+1994-04-27'}},	Q262 = {'ALG', {'Flag of Algeria.svg'}},	Q265 = {'UZB', {'Flag of Uzbekistan.svg'}},	Q298 = {'CHI', {'Flag of Chile.svg'}},	Q334 = {'SGP', {'Flag of Singapore.svg'}},	Q347 = {'LIE', {'Flag of Liechtenstein.svg'}},	Q398 = {'BRN ', {'Flag of Bahrain.svg','+2002-02-17'},	{'Flag of Bahrain (1972–2002).svg', '+1972-08-19', '+2002-02-16'}},	Q403 = {'SRB', {'Flag of Serbia.svg', '+2004-08-18'},	{'Flag of Serbia (1992–2004).svg', '+1992-04-27', '+2004-08-17'}},	Q408 = {'AUS', {'Flag of Australia.svg', '+1980-07-29'},	{'Olympic flag.svg', '+1980-07-19', '+1980-07-29'}, -- OG-1980	{'Flag of Australia.svg', '+1980-07-19'}},	Q414 = {'ARG', {'Flag of Argentina.svg'}},	Q419 = {'PER', {'Flag of Peru.svg', '+1950'},	{'Flag of Peru (1825-1950).svg', '+1825-02-25', '+1950'}},	Q424 = {'CAM', {'Flag of Cambodia.svg', '+1993-06-30'},	{'Flag of Cambodia.svg', '+1948-10-20', '+1970-10-09'}},	Q664 = {'NZL', {'Flag of New Zealand.svg'}},	Q711 = {'MGL', {'Flag of Mongolia.svg'}},	Q717 = {'VEN', {'Flag of Venezuela.svg', '+2006-03-12'},	{'Flag of Venezuela (1930–2006).svg', '+1930','+2006-03-12'}},	Q733 = {'PAR', {'Flag of Paraguay.svg', '+2013-07-15'},	{'Flag of Paraguay (1990–2013).svg', '+1990', '+2013-07-14'}},	Q736 = {'ECU', {'Flag of Ecuador.svg'}},	Q739 = {'COL', {'Flag of Colombia.svg'}},	Q750 = {'BOL', {'Flag of Bolivia.svg', '+1851-10-31'}},	Q754 = {'TTO', {'Flag of Trinidad and Tobago.svg'}},	Q769 = {'GRN', {'Flag of Grenada.svg'}},	Q774 = {'GUA', {'Flag of Guatemala.svg'}},	Q778 = {'BAH', {'Flag of the Bahamas.svg'}, '+1973-07-10'},	Q783 = {'HON', {'Flag of Honduras.svg'}, '+1949'},	Q786 = {'DOM', {'Flag of the Dominican Republic.svg'}},	Q794 = {'IRI', {'Flag of Iran.svg', '+1980-07-29'},	{'Flag of Iran (1964–1980).svg', '+1964', '+1980-07-29'}},	Q800 = {'CRC', {'Flag of Costa Rica (state).svg', '+1906-11-27'}},	Q801 = {'ISR', {'Flag of Israel.svg'}},	Q804 = {'PAN', {'Flag of Panama.svg'}},	Q813 = {'KGZ', {'Flag of Kyrgyzstan.svg', '+1992-03-03'}},	Q817 = {'KUW', {'Flag of Kuwait.svg', '+1961-09-07'}},	Q833 = {'MAS', {'Flag of Malaysia.svg', '+1963-09-16'}},	Q842 = {'OMA', {'Flag of Oman.svg', '+1995'}},	Q846 = {'QAT', {'Flag of Qatar.svg'}},	Q858 = {'SYR', {'Flag of Syria.svg', '+1980-03-29'}},	Q865 = {'TPE', {'Flag of the Republic of China.svg', '+1928-12-17'}},	Q869 = {'THA', {'Flag of Thailand.svg'}},	Q878 = {'UAE', {'Flag of the United Arab Emirates.svg'}},	Q881 = {'VIE', {'Flag of Vietnam.svg', '+1976-02-07'}},	Q884 = {'KOR', {'Flag of South Korea.svg', '+1997-10'}},	Q889 = {'AFG', {'Flag of Afghanistan (2013–2021).svg','+2013-08-19'},	{'Flag of Afghanistan (2004-2021, Variant).svg', '+2004-10-09', '+2013-08-18'},	{'Flag of Afghanistan (2002–2004, variant with golden arms).svg', '+2002-06-27', '+2004-10-08'},	{'Flag of Afghanistan (2002–2004).svg', '+2002-01-28', '+2002-06-26'},	{'Flag of Afghanistan (2001–2002).svg', '+2001-11-13', '+2002-01-27'},	{'Flag of Afghanistan (1992–2001).svg', '+1992-12-07', '+2002-01-26'},	{'Flag of Afghanistan (1992).svg', '+1992-04-27', '+1992-12-06'},	{'Flag of Afghanistan (1987–1992).svg', '+1987-11-30', '+1992-04-26'},	{'Flag of Afghanistan (1980–1987).svg', '+1980-04-22', '+1987-11-29'},	{'Flag of Afghanistan (1978–1980).svg', '+1978-10-19', '+1980-04-21'},	{'Flag of Afghanistan (1978).svg', '+1978-04-27', '+1978-10-18'},	{'Flag of Afghanistan (1974–1978).svg', '+1974-05-9', '+19780-4-26'},	{'Flag of Afghanistan (1973–1974).svg', '+1973-03-17', '+1974-05-8'},	{'Flag of Afghanistan (1931–1973).svg', '+1930-03-27', '+1973-03-16'},	{'Flag of Afghanistan (1929–1931).svg', '+1929-01-1', '+1930-03-26'}},	Q902 = {'BAN ', {'Flag of Bangladesh.svg','+1972-01-17'},	{'Flag of Bangladesh (1971).svg', '+1971-03-06', '+1972-01-16'}},	Q916 = {'ANG', {'Flag of Angola.svg', '+1975-11-11'}},	Q917 = {'BHU ', {'Flag of Bhutan.svg','+1972-06-08'},	{'Flag of Bhutan (1956–1969).svg', '+1956-07-01', '+1972-06-07'},	{'Flag of Bhutan (1949–1956).svg', '+1949-01-01', '+1956-06-30'}},	Q921 = {'BRU', {'Flag of Brunei.svg', '+1959-09-29'}},	Q928 = {'PHI', {'Flag of the Philippines.svg', '+1998'}},	Q948 = {'TUN', {'Flag of Tunisia.svg', '+1999-07-03'}},	Q954 = {'ZIM', {'Flag of Zimbabwe.svg', '+1980-04-18'}},	Q965 = {'BUR', {'Flag of Burkina Faso.svg'}},	Q983 = {'GEQ', {'Flag of Equatorial Guinea.svg', '+1979-08-21'},	{'Flag of Equatorial Guinea (1973–1979).svg', '+1973', '+1979-08-21'},	{'Flag of Equatorial Guinea (without coat of arms).svg', '+1968-10-12', '+1973'}},	Q986 = {'ERI', {'Flag of Eritrea.svg'}},	Q1000 = {'GAB', {'Flag of Gabon.svg', '+1960-08-09'}},	Q1007 = {'GBS', {'Flag of Guinea-Bissau.svg', '+1973-09-24'}},	Q1008 = {'CIV', {"Flag of Côte d'Ivoire.svg"}},	Q1009 = {'CMR', {'Flag of Cameroon.svg'}},	Q1027 = {'MRI', {'Flag of Mauritius.svg', '+1968-03-13'}},	Q1028 = {'MAR', {'Flag of Morocco.svg'}},	Q1030 = {'NAM', {'Flag of Namibia.svg', '+1990-03-21'}},	Q1036 = {'UGA', {'Flag of Uganda.svg', '+1962-10-09'}},	Q1037 = {'RWA', {'Flag of Rwanda.svg', '+2001-10-25'},	{'Flag of Rwanda (1962–2001).svg', '+1962', '+2001-10-25'}},	Q1183 = {'PUR', {'Flag of Puerto Rico.svg'}},	Q9676 = {'IMN', {'Flag of the Isle of Man.svg'}},	Q15180 = {'URS', {'Flag of the Soviet Union.svg', '+1980-08-15', '+1991-12-25'},	{'Flag of the Soviet Union (1955–1980).svg', '+1955-08-19', '+1980-08-14'},	{'Flag of the Soviet Union (1924–1955).svg', '+1923-11-13', '+1955-08-18'}},	Q16957 = {'GDR', {'Flag of East Germany.svg', '+1959-10-01'},	{'Flag of Germany.svg', '+1949-10-07', '+1959-10-01'}}, --German Democratic Republic	Q8646 = {'HKG', {'Flag of Hong Kong.svg'}},	Q25228 = {'AIA', {'Flag of Anguilla.svg'}},	Q29999 = {'NED', {'Flag of the Netherlands.svg', '+1980-07-29'}, --Kingdom of the Netherlands	{'Olympic flag.svg', '+1980-07-19', '+1980-07-29'}, -- OG-1980	{'Flag of the Netherlands.svg', '+1690', '+1980-07-19'}},	Q33946 = {'TCH', {'Flag of the Czech Republic.svg', '+1920'}}, -- Czechoslovakia (1918–1992)	Q36704 = {'YUG', {'Flag of Yugoslavia (1992–2003).svg', '+1992-04-27', '+2003-02-04'}, --Yugoslavia	{'Flag of Yugoslavia (1943–1992).svg', '+1946', '+1992-04-27'}},	Q41304 = {'GER', {'Flag of Germany (3-2 aspect ratio).svg', '+1918-11-09'}}, -- Weimar Republic	Q47588 = {'EU', {'Flag_of_the_Basque_Country.svg'}},	Q83286 = {'YUG', {'Flag of Yugoslavia (1943–1992).svg'}}, --Socialist Federal Republic of Yugoslavia	Q172579 = {'ITA', {'Flag of Italy (1861–1946).svg'}}, --Kingdom of Italy (1861-1946)	Q216923 = {'TPE', {'Flag of Chinese Taipei for Olympic games.svg'}}, -- Chinese Taipei	Q268970 = {'AUT', {'Flag of Austria.svg', '+1918-11-12', '+1919-09-10'}}, -- German-Austria (1918-1919)	Q713750 = {'FRG', {'Flag of Germany.svg'}}, --West Germany	Q853348 = {'TCH', {'Flag of the Czech Republic.svg'}, '+1960-07-11', '+1990-03-29'}, -- Czechoslovak Socialist Republic (1960-1990)	Q2415901 = {'GER', {'Merchant flag of Germany (1946–1949).svg', '+1945-05-09', '+1949-05-23'}}, -- Allied-occupied Germany	Q13474305 = {'ESP', {'Flag of Spain (1945–1977).svg', '+1945-10-11', '+1977-01-21'}, -- Francoist Spain (1935-1976)	{'Flag of Spain (1938–1945).svg', '+1939', '+1945-10-11'},	{'Flag of the Second Spanish Republic.svg', '+1931-04-14', '+1939'}},	Q113486069={'NEUTRAL', {'Flag white.svg'}} --Russia and Belarus during the ban, cannot replace the flags above, because there are cases where it does not apply	} local function flag(countryID, date)	local trackingCategory = ''	--[[ If you uncomment the line under this comment, all pages with look-up misses in	the flag table will be placed in a tracking category. You can use this to find more flags	to add to the table. ]]	-- trackingCategory = '[[Category:Missing flag in Module:Cycling race]]'	local entry = flags[countryID]	local IOC	local file	local result = ""	if entry then	for i, v in ipairs(entry) do	if i == 1 then	IOC = v	else	if not date then	file = v[1]	break	else	local from = v[2]	local to = v[3]	if (not from or from <= date) and (not to or to > date) then	file = v[1]	break	end	end	end	end	end	local flagpxSize = '20px'	if countryID == 'Q39' then flagpxSize = '16px'end -- Small size for an square flag as Switzerland	if file then	result = '[[File:' .. file .. '|border|' .. flagpxSize ..'|' .. IOC .. ']]'	if arwiki_totemplate then	result = '{{flagicon|' .. IOC .. '}}'	end	elseif not date then	local p41 = firstValue(countryID, "P41") -- P41 is flag image	if p41 then	result = '[[File:' .. p41 .. '|border|' .. flagpxSize ..'|(Wikidata:' .. countryID .. ')]]'	if arwiki_totemplate then	result = '{{flagicon image|' .. p41 .. '}}'	end	end	else	-- Search flag for specific date	local p41 = getStatementForTime(countryID, "P41", date) -- P41 is flag image	if p41 then	result = '[[File:' .. p41.mainsnak.datavalue.value .. '|border|' .. flagpxSize ..'|(Wikidata:' .. countryID .. ')]]'	if arwiki_totemplate then	result = '{{flagicon image|' .. p41.mainsnak.datavalue.value .. '}}'	end	end	end	return result .. trackingCategory end -- countryID --> shape ([[France|FRA]]) local function uciCodeCountry(countryID) local uciCode, countryName local blacklist={Q736=true}	if countryID then	--get UCI code	if flags[countryID] then	uciCode=flags[countryID][1]	end	--get link, assumed for a country the label is equal to the link, where not correct in the blacklist	--if the black list becomes too long, we could create a second list for the sitelinks	countryName=country_name_from_list(countryID)	if countryName == nil or blacklist[countryID] then	countryName = mw.wikibase.getSitelink(countryID)	end	if uciCode and countryName then	return ' <small>([['..countryName..'|'..uciCode..']])</small> '	end	end	return '' --else end local function jersey_infobox( winner_classification, item, timeOfRace)	local jersey, jersey_name = '', ''	local jerseyWPID = ''	-- 1. Item of race, e.g. Tour de France = 'Q33881'	-- 2. type of winner, names are the ones in variable t_s	-- 3. and 4. start and end time. '+2500' means year 2500. Always beginning with a '+'	-- 5. item of the jersey	-- 6. item of the Wikipedia article of that jersey	--timeOfRace = '+1968-07-01T00:00:00Z'	timeOfRace = string.match(timeOfRace, "+%d%d%d%d") or ''	for _, v in pairs(item) do	for _, value in pairs(data.stageinfobox_jersey) do	if v == value[1] then	if winner_classification == value[2] then	if (timeOfRace >= value[3]) and (timeOfRace <= value[4]) then	jersey = value[5]	jerseyWPID = value[6]	end	end	end	end	end	-- local starttime, endtime = '', '+2500'	if jersey ~= '' then --and (timeOfRace > starttime) and (timeOfRace < endtime) then	local entity_jersey = mw.wikibase.getEntity(jersey)	jersey = entity_jersey.claims['P18'][1].mainsnak.datavalue.value	jersey_name = entity_jersey:getLabel(wikilang) or ''	if jerseyWPID ~= '' then	local entity = mw.wikibase.getEntity( jerseyWPID )	local Sitelink = entity:getSitelink(wiki..'wiki') -- link to WParticle	if Sitelink ~= nil then jerseyWPID = wiki..':'..Sitelink else jerseyWPID = '' end	end	return jersey, jersey_name, jerseyWPID	else return '', '', ''	end end local function jersey(h)	local jersey_string = ' '	local jerseys = {	['Q24257871'] = {file = 'Jersey yellow.svg',	name_ar = 'قميص أصفر لمتصدر الترتيب العام',	name_fr = 'maillot jaune de leader du classement général',	name_es = 'maillot amarillo de líder de la clasificación general',	name_ru = 'жёлтая майка лидера генеральной классификации'	},	['Q24645209'] = {file = 'Jersey green.svg',	name_ar = 'قميص أخضر لمتصدر ترتيب النقاط',	name_fr = 'maillot vert de leader du classement par points',	name_es = 'maillot verde de líder de la clasificación por puntos',	name_ca = 'mallot verd del líder de la classificació per punts',	name_ru = 'зелёная майка лидера очковой классификации'	},	['Q640430'] = {file = 'Jersey white.svg',	name_ar = 'قميص أبيض لمتصدر ترتيب الشباب',	name_fr = 'maillot blanc de leader du classement du meilleur jeune',	name_es = 'maillot blanco de líder de la clasificación de los jóvenes',	name_ru = 'белая майка лидера молодёжной классификации',	name_de = 'weißes Trikot des Führenden der Nachwuchswertung'	},	}	if type(h) == 'table' and h[1] then	for _, v in ipairs(h) do	local jersey_name	if jerseys[v] then	jersey_string = jersey_string .. '[[File:' .. jerseys[v].file .. '|20px'	jersey_name = jerseys[v]['name_' .. wiki] or mw.wikibase.getLabel(v) or jerseys[v]['name_fr']	if jersey_name then	jersey_string = jersey_string .. '|' .. jersey_name	end	jersey_string = jersey_string .. ']]'	else	local p18 = mw.wikibase.getBestStatements(v, 'P18')	if p18[1] and p18[1].mainsnak.snaktype == 'value' then	jersey_string = jersey_string .. '[[File:' .. p18[1].mainsnak.datavalue.value .. '|20px'	jersey_name = getLabelFallback(v)	if jersey_name then	jersey_string = jersey_string .. '|' .. jersey_name	end	jersey_string = jersey_string .. ']]'	end	end	end	end	return jersey_string end -- function end --=== E) Other (winner) === local function isHuman(riderId)	local isHuman = false	if riderId then	local p31 = wikibase.getBestStatements(riderId, 'P31')	for _, iOf in pairs (p31) do	if iOf.mainsnak.snaktype == 'value' and iOf.mainsnak.datavalue.value.id == "Q5" then	isHuman = true	break	end	end	end	return isHuman end local function isCountry(inputID)	local isCountry = false	if inputID then	local p31 = wikibase.getBestStatements(inputID, 'P31')	for _, iOf in pairs (p31) do	-- exception Hong-Kong and Taiwan	if iOf.mainsnak.snaktype == 'value' and (iOf.mainsnak.datavalue.value.id == "Q6256" or iOf.mainsnak.datavalue.value.id =="Q15634554" or iOf.mainsnak.datavalue.value.id =="Q779415") then	isCountry = true	break	end	end	end	return isCountry end local function isWomenrace(raceID) --for translation	for _, p2094 in statements(raceID, 'P2094') do	if p2094.mainsnak.datavalue.value.id == "Q1451845" then	return true	end	end	return false end local function isWomenteam(teamID, timeOfRace)	if isWomenrace(teamID) then --simplest way	return true	end	--else we can identify with teamCat	local _, catID= getTeamLinkCat(teamID, timeOfRace, false)	if data.womenCats[catID] then	return true	end	return false end local function getNationality(wID, timeOfRace,q) --for a rider	local p27, countryID	--allow overload of the property, for cases like Russian/BLR ban, or Commonwealth games, only for P1532	if q and q.P1532 and q.P1532[1].snaktype == 'value' then	countryID = q.P1532[1].datavalue.value.id	else	local listOfProperty={'P1532','P27'}	if wID then	for _, prop in ipairs(listOfProperty) do	if countryID==nil then	p27 = getStatementForTime(wID, prop, timeOfRace) --P27 is country of citizenshi	if p27 then	countryID = p27.mainsnak.datavalue.value.id	end	end	end	end	if wiki=='eu' and (countryID=="Q142" or countryID=="Q29") then --look for people or location in the Basque Country, quite expensive function	local birth_place = firstValue(wID, 'P19','id') --birth place	if data.BasqueTown[birth_place] then	return "Q47588"	end	end	end	return countryID end local function subwinner(riderId, timeOfRace, q)	local outTable={}	local riderTeam, riderLink, countryID	if riderId then	if isHuman(riderId) then	riderLink = getRiderLink(riderId, timeOfRace)	countryID = getNationality(riderId, timeOfRace,q)	if countryID then	riderLink = flag(countryID, timeOfRace) .. ' ' .. riderLink	end	riderTeam = getTeam(riderId, timeOfRace, q) or ''	else	local _	riderLink, _, countryID = getTeamLinkCat(riderId, timeOfRace, true)	if countryID then	riderLink = flag(countryID, timeOfRace) .. ' ' .. riderLink	end	end	end	return riderLink, riderTeam end local function winner(lf,raceID, winners, timeOfRace, country, WDlink_on, team, ref, winnersId)	local p1346 = wikibase.getAllStatements(raceID, 'P1346') -- P1346 is 'winner'	for _, winner in pairs(p1346) do	local wID = winner.mainsnak.snaktype == 'value' and winner.mainsnak.datavalue.value.id	local wOf, wCause, wCriterion, riderLink	local q = winner.qualifiers	if q then	local _, disqualified =isdisqualified(winner,q)	if q.P642 and q.P642[1].snaktype == 'value' then	for _, q642 in pairs(q.P642) do	wOf = q642.datavalue.value.id -- P642 is 'of'	if not wOf then	-- Try P1346 (winner) instead	-- Assume Q20882667 ('overall winner general classification') if neither are found	wOf = q.P1346 and q.P1346[1].snaktype == 'value' and q.P1346[1].datavalue.value.id or 'Q20882667'	end	wCause = q.P828 and q.P828[1].snaktype == 'value' and q.P828[1].datavalue.value.id	-- P828 is 'has cause'	wCriterion = q.P1013 and q.P1013[1].snaktype == 'value' and q.P1013[1].datavalue.value.id	-- P1013 is 'criterion used'	if winners[wOf] then	if wID then	local reference = ref and getReference(lf,winner)	local _, countryID	if isHuman(wID) then	riderLink = getRiderLink(wID, timeOfRace)	if reference then	riderLink = riderLink .. reference	end	if team then	local riderTeam = getTeam(wID, timeOfRace, q)	if riderTeam then	riderLink = riderLink .. ' (' .. riderTeam .. ')'	end	end	elseif isCountry(wID) then	riderLink = flag(wID, timeOfRace).." "..getCountryName(wID)	if reference then	riderLink = riderLink .. reference	end	country=true	else --team	local _	riderLink, _, countryID = getTeamLinkCat(wID, timeOfRace, country)	if reference then	riderLink = riderLink .. reference	end	end	if not country then	if not countryID then	if isHuman(wID) then	countryID = getNationality(wID, timeOfRace,q)	else	countryID = getCountryID(wID, timeOfRace)	end	end	if countryID then	riderLink = flag(countryID, timeOfRace) .. ' ' .. riderLink	end	end	if WDlink_on then	riderLink = riderLink .. ' ' .. wdLink(wID)	end	else	riderLink = wCriterion and contentLanguage:ucfirst(wikibase.getLabel(wCriterion) or '') or ''	if wCause then	local cause = wikibase.getLabel(wCause)	if cause then	riderLink = riderLink .. ' (' .. cause .. ')'	end	end	end	if disqualified==true then	riderLink='<s>'..riderLink..'</s>'	end	if winnersId and winnersId[wOf] then	if disqualified or ((not wID) and wCriterion) then	winnersId[wOf]= 'Q666' --to identify disqualification	else	winnersId[wOf]= wID --identify cancelled	end	end	if winners[wOf] == '' then	winners[wOf] = riderLink	else	winners[wOf] = winners[wOf] .. '<br/>' .. riderLink	end	end	end	end	end	end end local function sortAndConcat(t_Body, resultTable)	table.sort(t_Body, function(a, b) return a['sortkey'] < b['sortkey'] end)	for _, m in ipairs(t_Body) do resultTable:node(m['body']) end	return resultTable end --------- Definition sub-functions for calendar and victory ------ local function getTimeOfRace(raceID, mandatory, p582_prio)	local timeOfRace, properties	if p582_prio then --for case like UCI Europe Tour 2006 (Q1455600) where most of the competition is in the next year	properties={'P582','P585','P580'}	else	properties={'P580','P585','P582'}	end	for _, prop in ipairs(properties) do	timeOfRace= firstValue(raceID, prop, 'time')	if timeOfRace ~= nil then return timeOfRace end	end	local link = getSitelinkFallback(raceID, {'en', 'fr', 'de','es'}) --language is not important here, it is just to get the year	if link then	local year = string.match(link, '%d%d%d%d')	if year then	return year .. '-01-01T00:00:00Z'	end	end	if wiki == "ar" then	return '+1970-01-01T00:00:00Z'	end	if mandatory then	error('> Wikidata is missing data about start time (P580) or point in time (P582)')	end	return nil end local function get_formatted_date(entityID, functionName)	local sTime = firstValue(entityID, 'P580', 'time') -- P580 is 'start time'	local eTime = firstValue(entityID, 'P582', 'time') -- P582 is 'end time'	local style1, style2	if functionName=="infobox" then	style1='verylong' --force to display the year	style2='long'	else	style1='small'	style2='small'	end	if sTime and eTime then	local startTime, endTime = getStartEndTime(sTime, eTime, style1)	if functionName==nil or functionName=='infobox' then --calendar, infobox	return startTime .. ' – ' .. endTime, sTime, true else --victory, general classification	return endTime, eTime, true	end	else	local pTime = firstValue(entityID, 'P585', 'time') -- P585 is 'point in time'	if pTime then	return funcDate(pTime, style2), pTime, false	end	end	return nil end local function fn_date(entityID, functionName) --to move as a general function	local tempdate, timeOfRace, _ = get_formatted_date(entityID, functionName) --is there a reason why timeofrace cannot be sTime??	local _, _, y, m, d = string.find(timeOfRace or "", "(%d+)-(%d+)-(%d+)")	local sortkey=(y or '')..(m or '')..(d or '')	if sortkey =='' then sortkey = '0000' end	local tCell = mw.html.create('td'):attr('data-sort-value',sortkey)	:cssText("style=text-align:right;padding:0 0.5em")	:wikitext(tempdate)	return timeOfRace, tostring(tCell), sortkey end local function fn_country(entityID, timeOfRace,country, raceCell, parentID)	-- This function gives countries where the race take place	-- parentID taken from fn_race, optional	local country_str, country_name, country_flag	local cssCell="text-align:" .. textalign .. ";padding:0 0.5em"	local tCell= mw.html.create('td'):cssText(cssCell)	local countryID = getCountryID(entityID, timeOfRace)	if countryID==nil then countryID = getCountryID(parentID, timeOfRace) end	if countryID then	country_flag=flag(countryID, timeOfRace)	country_str=country_flag	country_name = getCountryName(countryID)	if country_name~='' then	tCell:attr('data-sort-value',country_name)	if country~= false then	country_str=country_str.." "..country_name	end	end	else	country_flag="no flag"	end	if country==false then	tCell:wikitext(country_flag.." "..(raceCell or ''))	country_name=''	else	if country_str then	tCell:wikitext(country_str)	end	end	return country_flag, country_name, tCell end local function commaStage(stageID,raceLabel) --how to write "stage, "	local outTable={}	local stageNumber=''	local subStage = ''	local stageNumberonly, stageLetter	local temp=firstValue(stageID, 'P1545')	if temp then stageNumber = temp end	if stageNumber=='0' then --prologue	stageNumber= translate("victories",9)	else	if stageNumber==nil then	stageNumber= translate("victories",8)	else	--look for subStage	local i,j = string.find(stageNumber, "%a+") --if letter in the stage number	if i ~= nil then --we have to do something	local k,l = string.find(stageNumber, "%d+") --select the number in the stage number	stageNumberonly = string.sub(stageNumber, k, l)--cut the string in 2	stageLetter = string.sub(stageNumber, i, j)	stageNumber=stageNumberonly	if stageLetter ~= nil then subStage=stageLetter end	end	if wiki == 'ar' then	stageNumber= translate("victories",8)..' '..number('f', tonumber(stageNumber), wiki)	else	stageNumber= number('f', tonumber(stageNumber), wiki)..subStage..' '..translate("victories",8)	end	end	end	local comma = ", "	if wiki == 'ar' then comma = " ، " end	if wiki == 'fr' then	local correpondance={	{name="^Trois", article= " des "},	{name="^Quatre", article= " des "},	{name="^Boucles", article= " des "},	{name="^Triptyque", article= " du "},	{name="^Tour", article= " du "},	{name="^Grand Prix", article= " du "},	{name="^Circuit", article= " du "},	{name="^Mémorial", article= " du "},	{name="^Trophée", article= " du "},	{name="^Ronde", article= " de la "},	{name="^Semaine", article= " de la "},	{name="^Classica", article= " de la "},	{name="^Flèche", article= " de la "},	{name="^Course", article= " de la "},	{name="^Classique", article= " de la "},	{name="Race", article= " de la "},	{name="^Étoile", article= " de l'"},	{name="^La", article= " de "}	}	for _, v in ipairs(correpondance) do	if string.find(raceLabel, v.name) then	comma = v.article	break	end	end	end	if wiki == 'fr' or wiki=="ca" or wiki=="es" or wiki=="ast" then	outTable["prefix"]=stageNumber..comma	outTable["postfix"]=''	else	--if wiki=="de" or wiki=="da" or wiki=="fo" or wiki == "lb" or wiki=="no" or wiki=="ru" or wiki=="ar" or wiki=="lv" or wiki=="pl" then	outTable["prefix"]=''	outTable["postfix"]=comma..stageNumber	end	return outTable end local function getMainRaceLink(entityID,entity_type,stageID, functionName,timeOfRace) --the link to the edition but with a general name	local instanceOf, instanceOfTemp, label, Sitelink, isclass, prefix, postfix	local arlabel	local stage_link=false	if stageID then	Sitelink=wikibase.getSitelink(stageID)	if Sitelink then stage_link=true end	end	if Sitelink==nil then	Sitelink=wikibase.getSitelink(entityID)	end	prefix=''; postfix='' --general classification	listOfProperty={'P2561','P1448'} --main race link is in the parent	--can be improved	for _, p31 in statements(entityID, 'P31') do	instanceOfTemp = p31.mainsnak.datavalue.value.id	if instanceOfTemp ~= "Q27020041" and instanceOfTemp ~= 'Q88903067' and data.class_dic[instanceOfTemp]==nil then	--but the main race	instanceOf=instanceOfTemp	end	end --get information from the parent	if instanceOf then	--look for	for _, prop in ipairs(listOfProperty) do	for _, p2561 in statements(instanceOf, prop) do --name for championship	if label==nil then	local lang_WD = p2561.mainsnak.datavalue.value.language	if wiki == lang_WD then	local nametemp = p2561.mainsnak.datavalue.value.text	if timeOfRace~= nil then	local q = p2561.qualifiers	if q then	local temp = checktime(nametemp,q,timeOfRace)	if temp then label = nametemp end--if the time is correct than it is finished	else	label = nametemp	arlabel = label	end	end	end	end	end	end	if label==nil then	label=getLabelFallback(instanceOf,lang_priority) --the case of 'ar' should be handled in lang_priority	if not label then	label=getLabelFallback(entityID,lang_priority) or ''	end	end	if Sitelink==nil and entity_type~=0 then --only if no link to the race direct	Sitelink=wikibase.getSitelink(instanceOf)	end	if Sitelink==nil and entity_type==0 then --only for champ	local temp=firstValue(entityID, 'P361','id') --temp is NC France 2019 for instance	if temp then	Sitelink= wikibase.getSitelink(temp)	end	if Sitelink == nil then	local temp2=firstValue(entityID, 'P31','id') -- French NC Men ITT	if temp2 then	Sitelink= wikibase.getSitelink(temp2)	if Sitelink == nil then	local temp3=firstValue(temp2, 'P361','id') -- French NC ITT	if not temp3 then temp3=firstValue(temp2, 'P31','id') end	if temp3 then	Sitelink= wikibase.getSitelink(temp3)	if Sitelink == nil then	local temp4=firstValue(temp3, 'P361','id') -- French NC	if not temp4 then temp4=firstValue(temp3, 'P31','id') end	if temp4 then	Sitelink= wikibase.getSitelink(temp4)	end	end	end	end	end	end	end	end	--affect the label	if label==nil then	label=getLabelFallback(entityID,lang_priority) or ''	end	--look for link to the race if nothing	--if different languages have to be added, a language table can be created	if entity_type==2 then	if functionName~=nil then --calendar=nil	if wiki == 'fr' then prefix= translate("victories",1)..', ' --general classification	elseif wiki == 'ar' then postfix ='، '..translate("victories",1)	else postfix = ', '..translate("victories",1)	end	end	elseif entity_type=='stage' then	--how to write "stage, " is concentrated in one function	local commaTable=commaStage(stageID, label)	prefix= commaTable["prefix"]	postfix=commaTable["postfix"]	end	if Sitelink == nil then	if wiki == 'ar' then	label = make_IllWD2_link(entityID,arlabel,label)	end	return prefix..label..postfix	elseif stage_link then	return '[['..Sitelink..'|'..prefix..label..postfix..']]'	else	return prefix..'[['..Sitelink..'|'..label..']]'..postfix	end end --look for the circuitID to create a link as [[World Tour|1.UWT]] --a bit redundant with classLink which needs less computation --for infobox classLink gives enough info local function classToCircuit(classID, entityID, child, q)	local displayedCircuitID, circuitID	if classID then	if classID=='Q23005601' or classID=='Q23005603' then --1WWT 2WWT clear	displayedCircuitID = 'Q21075974'	elseif classID=='Q22231106' or classID=='Q22231107' then --1UWT 2UWT clear	displayedCircuitID = 'Q635366'	else --we have to look in the item	if child then --for instance Flèche wallonne 2020	for _, p361 in statements(entityID, 'P361') do	circuitID = p361.mainsnak.datavalue.value.id	for _, p31 in statements(circuitID, 'P31') do --is it a UCI circuit?	parentCircuitID = p31.mainsnak.datavalue.value.id	if data.UCI_Circuits[parentCircuitID] then	displayedCircuitID=circuitID	end	end	end	else --for instance Flèche wallonne	if q then	if q.P642 and q.P642[1].snaktype == 'value' and q.P642[1].datavalue.value.id then	displayedCircuitID = q.P642[1].datavalue.value.id	end	end	end	end	end	return displayedCircuitID end local function getStartEndfromQuali(q) --return sTime and eTime as date	local sTime, eTime	if q then	if q.P580 and q.P580[1] and q.P580[1].snaktype == 'value' then -- P580 is start time	sTime = q.P580[1].datavalue.value.time	end	if q.P582 and q.P582[1] and q.P582[1].snaktype == 'value' then -- P582 is end time	eTime = q.P582[1].datavalue.value.time	end	end	return sTime, eTime end local function funcDateFigure(date,mode)	local y, m = string.match(date, "(%d+)-(%d+)-%d+")	if mode=='Y' or m=='00' or not m then	return y	elseif y then	return string.gsub(m,'0','').."."..y	else	return nil	end end local function getPeriodSubSub(sTime, eTime, startTime,endTime,brackets)	local period	if sTime and eTime then	if startTime==endTime then	period=startTime --only (1990)	else	period=startTime .. '-'..endTime	end	elseif sTime then	period=startTime .. '-'	elseif eTime then	period='-'..endTime	else	period=""	end	if brackets and period~="" then	period="("..period..")"	end	return period end local function getPeriodSub(sTime, eTime, brackets)	local startTime, endTime, y, m, y2, m2	if sTime then	y, m = string.match(sTime, "(%d+)-(%d+)-%d+")	if m=='00' or m=='01' then	startTime= funcDateFigure(sTime, 'Y')	else	startTime= funcDateFigure(sTime,'m')	end	end	if eTime then	y2, m2 = string.match(eTime, "(%d+)-(%d+)-%d+")	if m2=='00' or m2=='12' then	endTime=funcDateFigure(eTime, 'Y')	else	endTime=funcDateFigure(eTime, 'm')	end	end	return getPeriodSubSub(sTime, eTime, startTime,endTime,brackets) end local function getPeriodSub_season(sTime, eTime, brackets)	local startTime, endTime	if sTime and eTime then	startTime, endTime = getStartEndTime(sTime, eTime, 'small')	elseif sTime then	startTime=funcDate(sTime, 'small')	elseif eTime then	endTime=funcDate(eTime, 'small')	end	return getPeriodSubSub(sTime, eTime, startTime,endTime,brackets) end -- for display period with only year, for instance (2020-2021) local function getPeriod(q, brackets,season)	local sTime, eTime = getStartEndfromQuali(q)	if season then	return getPeriodSub_season(sTime, eTime, brackets), sTime	else	return getPeriodSub(sTime, eTime, brackets), sTime	end end -- For infobox local function getClass(entityID)	local classLink, circuitID, circuitLink	local classTable={}	for ii, p279 in statements(entityID, 'P279') do	if p279 and p279.mainsnak.snaktype == 'value' then	local classID = p279.mainsnak.datavalue.value.id	if data.class_dic[classID]~=nil then circuitID=classToCircuit(classID, entityID, false, p279.qualifiers) classLink=classLinkFn(classID,circuitID) if classLink then	local period, sTime=getPeriod(p279.qualifiers, true)	local classStr = classLink .. " <small>"..period.."</small>"	table.insert(classTable, {sTime, classStr, circuitID})	end	end	end	end	if #classTable~=0 then	table.sort(classTable, function(a, b) return a[1] < b[1] end)	end	for _, class in pairs(classTable) do	if not str then str='' else str=str..'<br>' end	str=str..class[2]	if class[3] then	circuitLink=WPlinkpure(class[3])	end	end return str, circuitLink, #classTable end local function fn_race(entityID,displayed_class,display_class,timeOfRace, functionName,country)--return link to the race and class	--first function read from victory main	local Sitelink, entity_type, classID, stageID, race_tCell, class_tCell, parentID	for _, p31 in statements(entityID, 'P31') do	if data.stages[p31.mainsnak.datavalue.value.id] then	entity_type = 'stage' --then the class is one stage above!	parentID = getParentID(entityID)	classID=firstValue(parentID, 'P279', 'id')	stageID= entityID --everything slide from one rank	entityID = parentID	end	end	--Now we have the class and know the type of race it is	if entity_type == 'stage' then	Sitelink=getMainRaceLink(entityID,entity_type,stageID, functionName,timeOfRace)	else	classID=firstValue(entityID, 'P279', 'id')	Sitelink=getMainRaceLink(entityID,data.class_dic[classID],nil, functionName,timeOfRace)	end	if country~=false then	local tCell=mw.html.create('td'):cssText("text-align:".. textalign ..";padding:0 2.3em"):wikitext(Sitelink)	race_tCell=tostring(tCell)	else	race_tCell=Sitelink --already opened	end	if display_class == true and classID~=nil and (displayed_class==nil or displayed_class[classID]~=nil) then	local circuitID=classToCircuit(classID, entityID, true,nil)	local classLink=classLinkFn(classID,circuitID) --return '' worst case	class_tCell=mw.html.create('td')	:attr('data-sort-value',data.class_sort[classID]) --sortkey	:cssText("text-align:center;padding:0 0.5em")	:wikitext(classLink)	end	return parentID, race_tCell, class_tCell end local function fn_rider(lf,entityID,timeOfRace,display_team,only_winner,country)	local winners, countrytemp, result	local WDlink_on = (wiki == "mk" or wiki == "ja")	local thereisawinner=false	if only_winner == 1 then	winners = {Q20882667 = '', Q20882747=''} -- first, general or stage	elseif only_winner == 0 then	winners = { Q20882667 = '', Q20882668 = '',Q20882669 = ''} -- Q20882668 is 'second overall'	else --3	winners = { Q47640757='' } -- World Tour -- name not used here	end	if country==nil then countrytemp=false else countrytemp=country end	winner(lf,entityID, winners, timeOfRace, countrytemp, WDlink_on, display_team, true)	local tCell=mw.html.create('td'):css("text-align:".. textalign ..";padding:0 0.5em")	if only_winner == 0 then	tCell:wikitext(winners.Q20882667)	result=tostring(tCell)	tCell=mw.html.create('td'):css("text-align:".. textalign ..";padding:0 0.5em"):wikitext(winners.Q20882668)	result=result..tostring(tCell)	tCell=mw.html.create('td'):css("text-align:".. textalign ..";padding:0 0.5em"):wikitext(winners.Q20882669)	return result..tostring(tCell)	else	local tempwinner	if only_winner == 1 then	if winners.Q20882667~=nil and winners.Q20882667~='' then	tempwinner=winners.Q20882667	else	tempwinner=winners.Q20882747	end	else	tempwinner=winners.Q47640757	end	if tempwinner~='' and tempwinner~=nil then thereisawinner=true end	return tCell:wikitext(tempwinner), thereisawinner	end end local function compareDate(tdate) --test future	if tdate then	local today=os.date("*t")	local _, _, y, m, d = string.find(tdate, "(%d+)%p(%d+)%p(%d+)")	local tYear=tonumber(y)	local tMonth=tonumber(m)	local tDay=tonumber(d)	if tYear>today['year'] then	return true	elseif tYear<today['year'] then	return false --the last race is the future	else	if tMonth>today['month'] then	return true	elseif tMonth<today['month'] then	return false	else	if tDay>today['day'] then	return true	elseif tDay<today['day'] then	return false	else	return false --arbitrary	end	end	end	else	return false --arbitrary	end end local function calculateAge(birthDate, endDate) --test future	local eYear, eMonth, eDay	local longestcontractyears=10	if birthDate then	if not endDate then	local today=os.date("*t") eYear=today['year'] eMonth=today['month'] eDay=today['day']	else	local _, _, y, m, d = string.find(endDate, "(%d+)%p(%d+)%p(%d+)")	eYear=tonumber(y)	eMonth=tonumber(m)	eDay=tonumber(d)	end	local _, _, y, m, d = string.find(birthDate, "(%d+)%p(%d+)%p(%d+)")	local tYear=tonumber(y)	local tMonth=tonumber(m)	local tDay=tonumber(d)	local alreadyThisYear	if eMonth>tMonth then	alreadyThisYear=true	elseif eMonth<tMonth then	alreadyThisYear=false	else	if eDay>tDay then	alreadyThisYear=true	elseif eDay<tDay then	alreadyThisYear=false	else	alreadyThisYear=true	end	end	if alreadyThisYear then	return eYear-tYear, tYear, eYear+longestcontractyears	else	return eYear-tYear-1, tYear, eYear+longestcontractyears	end	else	return 0, tYear, eYear+longestcontractyears	end end local function evaluateWinnerMax(t)	local winners = t.vainqueur	local result	local most_wins = 0	local most_wins_ID = {}	for winnerID, winner in pairs(winners) do	if winner.count > most_wins then	most_wins = winner.count	most_wins_ID = { winnerID }	elseif winner.count == most_wins then	most_wins_ID[#most_wins_ID + 1] = winnerID	end	end	if most_wins > 1 then	for _, id in pairs(most_wins_ID) do	if not result then	result=winners[id].link	else	result=result.."<br>"..winners[id].link	end	end	local _, gen_singular, gen_plural=plural(most_wins)	if gen_singular then --slavic plural, 1 victory is not displayed	word_victory=translate("raceinfobox",29)	elseif gen_plural then	word_victory=translate("raceinfobox",30)	else	word_victory=translate("raceinfobox",32) --singular	end	result=result.."<br>("..tostring(most_wins).." "..word_victory..")"	end	t.maxWinner=result end local function listOfWinners(itemID,t, team,lf, mandatory_prop)	local winners = {	Q20882667 = '',}-- Q20882667 is 'overall winner general classification'	local winnersId={	Q20882667 = '',}--to detect disqualification	local WDlink_on, sitelink	if wiki == "mk" or wiki == "ja" or wiki == "ru" then WDlink_on = true else WDlink_on = false end -- Get the date to sort the editions	for _, p527 in statements(itemID, 'P527') do --_, p527	local raceDate, year, raceID, entity_race, a, b	raceId = p527.mainsnak.datavalue.value.id -- Qnumbers of the parts of a tour	raceDate=getTimeOfRace(raceId)	table.insert(t.race, { raceId=raceId, raceDate=raceDate, future=compareDate(raceDate)} ) --check if future	table.sort(t.race, function(a,b) return a['raceDate'] < b['raceDate'] end) -- t.race is sorted after year	end	--look for the next race	local lastRunEdition, lastEditionDate, nextEdition	for num, race in ipairs(t.race) do	if race['future'] then	nextEdition=num	break	end	end	--Get the winners	local numberOfEditions=0	local lastWinner, winnerId	if not team then --for race, a test shall be performed	for num=1,#t.race do	winners.Q20882667=''	winnersId.Q20882667=''	winner(lf,t.race[num]['raceId'], winners, t.race[num]['raceDate'], false, WDlink_on, nil, nil, winnersId )	if t.race[num]['future']==false then --in the past	if winnersId.Q20882667~="Q30108381" then --cancelled	numberOfEditions=numberOfEditions+1	lastRunEdition=num	lastEditionDate=t.race[num]['raceDate']	lastWinner=winners.Q20882667	end	end	winnerId=winnersId.Q20882667	if winnerId~=nil and winnerId~='' and winnerId~='Q666' and winnerId~='Q30108381' then --code for disqualification	if not t.vainqueur[winnerId] then	t.vainqueur[winnerId]={}	t.vainqueur[winnerId].link=winners.Q20882667	t.vainqueur[winnerId].count=0	end	t.vainqueur[winnerId].count=t.vainqueur[winnerId].count+1	end	end	else --for team the check is lighter	for num=1,#t.race do	if t.race[num]['future']==false then --in the past	if mandatory_prop==nil then	numberOfEditions=num	lastRunEdition=num	lastEditionDate=t.race[num]['raceDate']	else	local ss = wikibase.getAllStatements(t.race[num]['raceId'], mandatory_prop)	if #ss >0 then	numberOfEditions=num	lastRunEdition=num	lastEditionDate=t.race[num]['raceDate']	end	end	end	end	end	local monthId=firstValue(itemID, 'P2922','id')	if monthId then	t.lastEditionMonth=getLabelFallback(monthId) or ''	else	t.lastEditionMonth=contentLanguage:formatDate("M", lastEditionDate)	end	if lastEditionDate then	t.lastEditionYear=funcDate(lastEditionDate,"onlyyear")	end	t.numberOfEditions=numberOfEditions	if not team then evaluateWinnerMax(t) end	if lastRunEdition then	t.lastWinner=lastWinner or '' --t.vainqueur[lastRunEdition]['link']	t.lastID=t.race[lastRunEdition]['raceId']	sitelink = wikibase.getSitelink(t.lastID)	if sitelink ~= nil then	t.lastLink = "[[" .. sitelink .. "]]"	else	t.lastLink = nil	end	end	if nextEdition then	t.nextID=t.race[nextEdition]['raceId']	sitelink = wikibase.getSitelink(t.nextID)	if sitelink ~= nil then	t.nextLink = "[[" .. sitelink .. "]]"	else	t.nextLink = nil	end	end end local function getPeriodicity(itemID, t)	local p = wikibase.getBestStatements(itemID, 'P2257')	if p[1] and p[1].mainsnak.snaktype == 'value' then	local period=p[1].mainsnak.datavalue.value.amount	local periodunit=p[1].mainsnak.datavalue.value.unit	if tonumber(period)==1 and periodunit == 'http://www.wikidata.org/entity/Q577' then	return translate("raceinfobox",1).." ("..t.lastEditionMonth ..")"	elseif tonumber(period)==1 and periodunit == 'http://www.wikidata.org/entity/Q5151' then	return translate("raceinfobox",2)	else	return nil	end	else	return nil	end end local function getType(itemID)	local result, typeID	typeID =firstValue(itemID, 'P31', 'id')	if typeID ~= nil then	if typeID=="Q2912397" and wiki=="fr" then	result="[[Cyclisme_sur_route#Épreuve_d'un_jour|Course d'un jour]]"	else	result=WPlinkpure(typeID)	end	end --else result=nil	return result end local function getFormerNames(itemID, PID, season)	local listOfNames={}	local officialname,language	local kk=1	while #listOfNames == 0 and kk<=#lang_priority do	lang=lang_priority[kk]	kk=kk+1	for _, prop in ipairs({PID}) do	for _, p1813 in statements(itemID, prop) do	language = p1813.mainsnak.datavalue.value.language	officialname = p1813.mainsnak.datavalue.value.text	if lang==language then --only exact language	local period, sTime=getPeriod(p1813.qualifiers, nil, season)	if not sTime then sTime="+1900-01-01T00:00:00Z" end --first	table.insert(listOfNames,{sTime, period, officialname, language})	end	end	end	end	table.sort(listOfNames, function(a, b) return a[1] < b[1] end)	return listOfNames end local function officialSite(itemID)	local url=firstValue(itemID, 'P856')	if url then	return '['..url.." "..translate("raceinfobox",3)..']'	end	return nil end local function checkkm(p)	local km, unit	if p[1] and p[1].mainsnak.snaktype == 'value' then	km = tonumber(p[1].mainsnak.datavalue.value.amount)	unit = p[1].mainsnak.datavalue.value.unit	if unit == 'http://www.wikidata.org/entity/Q828224' then	return km	end	end	return nil end local function checkm(p, in_cm)	local m, unit, res	if p[1] and p[1].mainsnak.snaktype == 'value' then	m = tonumber(p[1].mainsnak.datavalue.value.amount)	unit = p[1].mainsnak.datavalue.value.unit	if unit == 'http://www.wikidata.org/entity/Q11573' then	res=m	elseif unit=='http://www.wikidata.org/entity/Q174728' then --cm	res=m*0.01	end	if res then	if in_cm then	res=res*100	end	return res	end	end	return nil end local function checkkmh(p)	if p[1] and p[1].mainsnak.snaktype == 'value' then	kmh = tonumber(p[1].mainsnak.datavalue.value.amount)	unit = p[1].mainsnak.datavalue.value.unit	if unit == 'http://www.wikidata.org/entity/Q180154' then -- Q180154 is 'kilometre per hour'	return kmh	end	end	return nil end local function checkkg(p)	local kg, unit	if p[1] and p[1].mainsnak.snaktype == 'value' then	kg = tonumber(p[1].mainsnak.datavalue.value.amount)	unit = p[1].mainsnak.datavalue.value.unit	if unit == 'http://www.wikidata.org/entity/Q11570' then	return kg	end	end	return nil end local function formatNumber(e, addUnit, trans)	local text	if e then	text = contentLanguage:formatNum(e)	if wiki == 'fo' then	text = string.gsub(text, "%.", ",")	end	if addUnit then	local t=translate("unit",trans)	if string.find( t," ")==1 then	text = text ..t	else	text = text .. ' ' ..t	end	end	end	return text end local function getHeight(entityID, in_cm)	local p = mw.wikibase.getBestStatements(entityID, 'P2048')	if in_cm then	return formatNumber(checkm(p, in_cm), true, 11)	else	return formatNumber(checkm(p, in_cm), true, 9)	end end local function getWeight(entityID)	local p = mw.wikibase.getBestStatements(entityID, 'P2067')	return formatNumber(checkkg(p), true, 10) end local function getDistance(raceID, addUnit)	local p = mw.wikibase.getBestStatements(raceID, 'P3157') -- P3157 is 'event distance'	local km =checkkm(p)	if not km then --for stage race we can sum the distances from each stage	local stagep, tempkm	for _, p527 in statements(raceID,'P527') do	stagep=mw.wikibase.getBestStatements(p527.mainsnak.datavalue.value.id, 'P3157')	tempkm=checkkm(stagep)	if tempkm then	if not km then km=0 end	km=km+tempkm	end	end	end	return formatNumber(km, addUnit, 8), km end local function getElevation(raceID)	local p =mw.wikibase.getBestStatements(raceID, 'P7297')	return formatNumber(checkm(p), true, 9) end local function getSpeed(raceID, addUnit,kmdistance, property)	local timeOfRace	local p = mw.wikibase.getBestStatements(raceID, 'P2052') -- P2052 is 'speed'	local kmh=checkkmh(p)	if not kmh and kmdistance then --calculate speed	local p2321= wikibase.getBestStatements(raceID, property) --winner supposed to be first of overall classification	if p2321 and p2321[1] and p2321[1].mainsnak.snaktype == 'value' then	local q = p2321[1].qualifiers	if q and q.P1352 and q.P1352[1].snaktype == 'value' then --rank	for _, q1352 in pairs(q.P1352) do	rank = tonumber(q1352.datavalue.value.amount)	end	if rank == 1 then	timeOfRace=qualifieramount(p2321[1], 'P2781') --get time	end	end	if timeOfRace then	kmh=math.modf(1000*kmdistance/(timeOfRace/3600))/1000	end	end	end	return formatNumber(kmh, addUnit, 5) end local function getGenderCode(riderID, default)	local gender=default -- default is for teams, n or f	local g = firstValue(riderID, 'P21', 'id')	if g == 'Q6581097' then gender = 'm' -- Male	elseif g == 'Q6581072' then gender = 'f' -- Female	elseif g == 'Q1052281' then gender = 't' -- Transgenre	end	return gender end function number(gender, b, wiki)	local str	if b==nil or b=="" then return "" end	if wiki=="ar" then	str = b	elseif wiki == "ca" then	if b==1 then str = b.."r"	elseif b==2 then str = b.."n"	elseif b==3 then str = b.."r"	elseif b==4 then str = b.."t"	else str = b.."è"	end	elseif wiki=="es" then	if gender == 'm' or gender == 'n' then str = b..".º"	elseif gender == 'f' then str = b..".ª"	else str = b.."."	end	elseif wiki=="fr" then	if b==1 then	if gender == 'm' then str="1<sup>er</sup>"	elseif gender == 'f' or gender == 'n' then str="1<sup>re</sup>"	else str="1<sup>e</sup>"	end	else str=b.."<sup>e</sup>"	end	elseif wiki=="nl" then str=b.."e"	elseif wiki=="ru" then str=b.."-й"	elseif wiki=="eo" then str=b.."-a"	elseif wiki=="ast" then	if gender == 'm' or gender == 'n' then str = b.."ᵘ"	elseif gender == 'f' then str = b.."ª"	else str = b.."."	end	else str = b .. ". "	end	return str end local function calculateTime(t)	local time = tonumber(t)	local h, m, s = 0, 0, 0	local str = ''	if time == nil then return '' end	if time < 60 then s = time	elseif time < 3600 then m = math.modf(time/60) s = time - m*60	else h = math.modf(time/3600) m = math.modf((time - h*3600)/60) s = time - h*3600 - m*60	end	if h>0 then str = str..mw.ustring.format ('%i'..translate("unit",2), h) end	if m>=0 and h>0 then str = str.. mw.ustring.format('%02i'..translate("unit",3), m) end	if m>0 and h==0 then str = str.. mw.ustring.format('%i'..translate("unit",3), m) end	if s>=0 and (h>0 or m>0) then str = str.. mw.ustring.format('%02i'..translate("unit",4), s) end	if s>=0 and h==0 and m==0 then str = str.. mw.ustring.format('%i'..translate("unit",4), s) end	return str --time..': '..h..' '..m..' '..s end local function func_error_message(x)	local l10nDef = {	["fr"] = {"La propriété <1> est manquante dans l'item <2> (<3>)"},	["en"] = {'Property <1> is missing in item "<2>" (<3>)'},	["ar"] = {'الخاصية <1> غير موجودة في العنصر "<2>" (<3>)'},	}	local l10n = l10nDef[wiki]	if not l10n then l10n = l10nDef["en"] end -- default	return l10n[x] end local function getMissingLabelTrackingCategory()	local l10nDef = {	["cs"] = '[[Kategorie:Údržba:Doplnit štítek na Wikidatech]]',	["lv"] = '[[Category:Vikidatos trūkst nosaukuma latviešu valodā]]',	["he"] = '[[קטגוריה:ויקינתונים:ערכים חסרי תווית בעברית: קבוצת אופניים]]',	}	local l10n = l10nDef[wiki]	if not l10n then	l10n = ''	end	return l10n end local function getStageLabel(inp)	local a	local b=''	local this_label=''	if inp then	a, _ = string.gsub(inp, "%a", "") -- 20, not 20a	if string.find(inp, "%a") then	b = string.sub(inp, string.find(inp, "%a"))	end	if inp == "0" then	this_label = translate("func_prologue",1)	else this_label = stageLink(inp, a, b)	end	end	return this_label end --[[ Make a table row for infoboxes with links to previous and next ]] local function getPreviousNextLine(raceID, stage)	local previousID = firstValue(raceID, 'P155', 'id') -- P155 is 'follows'	local nextID = firstValue(raceID, 'P156', 'id') -- P156 is 'followed by'	if not nextID or not previousID then	for _, s in statements(raceID, 'P3450') do	-- for items using P3450	local q = s.qualifiers	if q then	if not previousID and q.P155 and q.P155[1] and	q.P155[1].snaktype == 'value' then	previousID = q.P155[1].datavalue.value.id	end	if not nextID and q.P156 and q.P156[1] and	q.P156[1].snaktype == 'value' then	nextID = q.P156[1].datavalue.value.id	end	end	end	end	if not previousID and not nextID then	return ''	end	local previousText, nextText = '', ''	local direction = contentLanguage:getDir()	local previous_sign = (direction == 'ltr') and '&#x25C0;' or '&#x25B6;'	local next_sign = (direction == 'ltr') and '&#x25B6;' or '&#x25C0;'	local this_label	if previousID then	if stage then local series_ordinal= firstValue(previousID, 'P1545', 'value') this_label=getStageLabel(series_ordinal)	else	this_label = getYear(previousID)	end	local link = wikibase.getSitelink(previousID)	if link then	previousText = '<span style="color:#3366CC">[[' .. link .. '| ' .. previous_sign .. this_label .. ']]</span>'	else	previousText = '<span style="color:#3366CC">' .. previous_sign .. '</span> ' .. this_label	end	end	if nextID then	if stage then	local series_ordinal= firstValue(nextID, 'P1545', 'value')	this_label=getStageLabel(series_ordinal)	else	this_label = getYear(nextID)	end	local link = wikibase.getSitelink(nextID)	if link then	nextText = '<span style="color:#3366CC">[[' .. link .. '|' .. this_label .. next_sign .. ']]</span>'	else	nextText = this_label .. ' <span style="color:#3366CC">' .. next_sign .. '</span>'	end	end	local direction = contentLanguage:getDir()	local outTable = mw.html.create('tr')	local tCell=outTable:tag('td')	tCell:cssText("text-align:" .. ((direction == 'ltr') and 'left' or 'right')):wikitext(previousText)	if stage ~= nil and wiki=="ar" then	tCell:css('width','50%')	end tCell=outTable:tag('td') :cssText("text-align:" .. ((direction == 'ltr') and 'right' or 'left')):wikitext( nextText) if stage ~= nil and wiki=="ar" then	tCell:css('width','50%')	end	return outTable end --== Functions for infobox -- functions for infoboxs local function get_others_dic()	return {	{ name = translate("infobox",29,w_race)}, -- picture	{ name = translate("infobox",30,w_race)}, -- caption	{ name = translate("infobox",31,w_race)}, -- map	{ name = 'sectional'}, -- sectional	{ name = translate("infobox",30,w_race)}, -- caption map	{ name = translate("infobox",30,w_race)}, -- caption sectional	} end local function infoGetOthers(others, entityID)	if not others[1].content then --picture	others[1].content, others[2].content = getLogo(entityID)	if not others[1].content then	others[1].content, others[2].content = getImage(entityID) -- picture, caption	end	end	if not others[3].content then -- map	others[3].content, others[5].content = getMap(entityID) -- P242 is 'locator map image'	end	if not others[4].content then -- map	others[4].content, others[6].content = getSectionalView(entityID) -- sectional_view	end end local function infoGetPlaceOrCountry(details,index, entityID, timeOfRace, PID) --generalized infoGetCountry	if not details[index].content then -- country	-- This function gives countries where the race take place	local place = {} if not place[1] then	for _, p17 in statements(entityID, PID) do -- P17 is 'country'	local countryID = p17.mainsnak.datavalue.value.id	if PID=='P17' then	place[#place + 1] = flag(countryID, timeOfRace) .. ' ' .. getCountryName(countryID)	else	place[#place + 1] = wikibase.getLabel(countryID)	end	end	end	if place[1] then	if #place > 1 then	details[index].name = details[index].name_plural	end	details[index].content = table.concat(place, '<br/>')	end	end end local function infoGetPlace(details,index, entityID, timeOfRace)	infoGetPlaceOrCountry(details,index, entityID, timeOfRace, "P276") end local function infoGetCountry(details,index, entityID, timeOfRace)	infoGetPlaceOrCountry(details,index, entityID, timeOfRace, "P17") end local function infoGetStartEnd(details,index, entityID, timeOfRace)	if not details[index].content then -- start place	local place = firstValue(entityID, 'P1427', 'id') -- P1427 is 'start point'	details[index].content = place and getPlaceLink(place, timeOfRace)	end	if not details[index+1].content then -- end place	local place = firstValue(entityID, 'P1444', 'id') -- P1444 is 'destination point'	details[index+1].content = place and getPlaceLink(place, timeOfRace)	end end local function infoGetParticipants(details,index, entityID)	-- Function that give the number of cyclists at the beginning and at the finishing of a race	for _, p1132 in statements(entityID, 'P1132') do -- P1132 is 'number of participants'	local amount = tonumber(p1132.mainsnak.datavalue.value.amount) -- tonumber to remove starting '+'	for _, q in qualifiers(p1132, 'P276') do -- P276 is 'location'	local location = q.value.id	if location == "Q529711" then -- Q529711 is 'beginning'	if not details[index].content then details[index].content = amount end -- participants at start	elseif location == "Q12769393" then -- Q12769393 is 'end'	if not details[index+1].content then details[index+1].content = amount end -- participants at end	end	end	end end local function infoInitTab(width, name, icon, cellpadding)	if width==nil then width= '320px' end	local tab = mw.html.create('table'):addClass('infobox')	if wiki == "eo" then	tab:cssText(standardtablecss):css('width','23em')	else	cellpadding=tostring(cellpadding or 4)	tab:attr('cellpadding',cellpadding)	:attr('cellspacing','0')	:cssText(standardtablecss)	:cssText("float:"..floatinfobox.."; max-width:"..width)	end	local tCell=tab:tag('tr'):tag('td'):attr('colspan','2')	:cssText('border-bottom:5px solid white; font-size:175%; text-align:center')	:css('background-color',backgroundColor)	local topTable = tCell:tag('table')	:cssText('width:100%')	local tRow=topTable:tag('tr')	tRow:tag('td'):wikitext(name or '')	tRow:tag('td'):wikitext(icon or '')	return tab end local function addARow(name, content)	local tRow	if content then	tRow= mw.html.create('tr'):css('vertical-align','top')	tRow:tag('td'):css('width','40%'):css('font-weight','bold')	:wikitext(name)	tRow:tag('td'):wikitext(content)	end	return tRow end local function addATitle(title)	local tRow	if title then	tRow= mw.html.create('tr'):tag('td'):attr('colspan','2')	:css('text-align','center')	:css('background-color',backgroundColor)	:css('font-weight','bold')	:wikitext(title)	end	return tRow end local function infoFillOthersDetails(tab, others, details,title, pxmax)	if not pxmax then	pxmax="300px"	end	if others and others[1].content then -- picture	tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center')	:wikitext("[[File:" .. others[1].content .."|center|"..pxmax.."]]")	if others and others[2].content then -- caption	tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%')	:wikitext(others[2].content)	end	end	if details then	tab:node(addATitle(title))	for _, row in ipairs(details) do	tab:node(addARow(row.name, row.content)) --node check itself if nil	end	end end local function infoFillOthersMap(tab, others)	if others[3].content then -- map	tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center')	:wikitext("[[File:".. others[3].content .. "|center|300px]]")	if others[5].content then -- caption	tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%')	:wikitext(others[5].content)	end	end	if others[4].content then -- map	tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center')	:wikitext("[[File:".. others[4].content .. "|center|300px]]")	if others[6].content then -- caption	tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%')	:wikitext(others[6].content)	end	end end local function wdDoc(tab, s, translation, ID)	local tCell=tab:tag('tr'):tag('td')	local tC, link	local commons_cat=firstValue(ID, 'P373', 'id')	if commons_cat then	commons_cat=string.gsub(commons_cat, '%s', '_')	local icon="[[File:Commons-logo.svg|12px|link=https://commons.wikimedia.org/wiki/Category:"..commons_cat.."]]"	tC=tCell:cssText('text-align:left; border-top:3px solid '..backgroundColor..'; font-size:93%')	:wikitext(icon):tag('td')	else	tC=tCell:attr('colspan','2')	end	if wiki == "ar" then	link = wdLink(ID) .." [[" .. s .. "|" .. translation .. "]]"	else	link = "[[" .. s .. "|" .. translation .. "]] "..wdLink(ID)	end	tC:cssText('text-align:right; border-top:3px solid '..backgroundColor..'; font-size:93%')	:wikitext(link) end local function listWPlink(details, index, entityID, PID, bool_link)	local org={}	for _, p in statements(entityID, PID) do	if p and p.mainsnak.snaktype == 'value' then	if bool_link then	table.insert(org,WPlinkpure(p.mainsnak.datavalue.value.id))	else	local label=wikibase.getLabelByLang(p.mainsnak.datavalue.value.id, wiki)	table.insert(org,label)	end	end	end	if org[1] then	if #org > 1 then	details[index].name = details[index].name_plural	end	details[index].content = table.concat(org, '<br/>')	end end --Display in a chronological order fields in a table local function listWPlinkChrono(details, index, entityID, listOfProperty, option, initialYear, display_flag, comma,season)	local period, sTime, value, ID, temp	local list={}	if not initialYear then initialYear="1900" end	if not details[index].content then	for _, prop in ipairs(listOfProperty) do	if #list==0 then --if P1532 is used P17 is not used	for _, p in statements(entityID, prop) do	if p and p.mainsnak.snaktype == 'value' then	ID=p.mainsnak.datavalue.value.id	if p.qualifiers then	period, sTime=getPeriod( p.qualifiers, true,season)	end	if not sTime then sTime="+"..initialYear.."-01-01T00:00:00Z" end --first	if option =='label' then	value=wikibase.getLabelByLang(ID, wiki)	elseif option == 'country' then	value=getCountryName(ID)	if display_flag then	value= flag(ID, sTime).." "..value	end	elseif option=='officialname' then	value=getOfficialName(ID, sTime,false) --official name is necessary because of continental team change in ProTeam	elseif option =='place' then	value=getPlaceLink(ID, sTime)	elseif option=='UCIcode' then	value=getTeamCodeCat(entityID, sTime) --! getTeamCodeCat uses teamID	elseif option=='money' then	local amount=p.mainsnak.datavalue.value.amount	local unit=p.mainsnak.datavalue.value.unit	value=dispmoney(amount, unit) or ''	else --rider	value=getRiderLink(ID, sTime)	end	if value then	table.insert(list,{sTime,period,value})	end	end	end	end	end	if #list ~=0 then	table.sort(list, function(a, b) return a[1] < b[1] end)	end	local separator='<br/>'	if comma then separator=', ' end	if list and #list==1 then	details[index].content=list[1][3] or ''	elseif list and #list~=0 then	details[index].name = details[index].name_plural	details[index].content=''	for _, v in pairs(list) do	temp=v[3] or ''	if v[2] then	temp=temp..' <small>'..v[2]..'</small>'..separator	else	temp=temp..separator	end	details[index].content=details[index].content..temp	end	end	end end -- == Functions for team roster local function getReason(riderReason, riderRef, p527,timeOfRace,riderEnd,lf) --reason for end	local listofproperty={'P1642','P1643','P1534'}	local outTable={}	local seasonYear, endYear	if timeOfRace then	seasonYear=tonumber(string.sub(timeOfRace, 2, 5))	end	if riderEnd then	endYear=tonumber(string.sub(riderEnd, 2, 5))	end	--if not the last season, do not display the reason for end	if (riderReason == nil and (not endYear or	(seasonYear and endYear and (seasonYear== endYear)))) then --if no riderReason before then look for it, otherwise don't touch it	for _,v in ipairs(listofproperty) do	for _, q in qualifiers(p527, v) do	riderReason = q.value.id	end	end	if riderReason then	local label =string.gsub(getLabelFallback(riderReason,lang_priority), "%b()", "")	riderRef = getReference(lf,p527, 1)	riderReason = ', ' .. label	end	end	return riderReason, riderRef end local function getPosition(riderPosition,v)	local stagiaire	if riderPosition == nil then -- find the 'position' (P39) of a rider	for _, q in qualifiers(v, 'P39') do	stagiaire = q.value.id	local label = string.gsub(getLabelFallback(stagiaire,lang_priority), "%b()", "")	Sitelink = wikibase.getSitelink('Q2328847')	if Sitelink then	riderPosition=', ' .. "[["..Sitelink .."|"..label.."]]"	else	riderPosition =', ' .. label	end	end	end	return riderPosition end local function trans(date, month, day)	if date ~= '' and date~=nil then	local _, _, y, m, d = string.find(date, "(%d+)-(%d+)-(%d+)")	if m == '00' then m = month end	if d == '00' then d = day end	date = '+'..y..'-'..m..'-'..d..'T00:00:00Z'	return date	end	return nil end local function parseDate(date, defaultYear, defaultMonth, defaultDay, errortext, etext)	local y, m, d	local date=trans(date, defaultMonth, defaultDay)	if not date then	date = '+'..defaultYear..'-'..defaultMonth..'-'..defaultDay..'T00:00:00Z'	y=defaultYear	m=defaultMonth	d=defaultDay	errortext=errortext..etext	else	_, _, y, m, d = string.find(date, "(%d+)-(%d+)-(%d+)")	if not y or y=="0000" then	y=defaultYear	errortext=errortext..etext	end	date = '+'..y..'-'..m..'-'..d..'T00:00:00Z'	end	return date, y, m, d, errortext end local function findLastName(label,wiki)	if not label then label = '' end	local _, count = string.gsub(label, " ", " ")	local names	local a,b,c,d = '', '', '', ''	local done = false	if count ~= nil then count = count + 1 else count = 1 end	if count > 1 then	if count == 2 then	if label ~= '' then	a, b = string.match(label, "(%S+)%s+(%S+)")	names = b..' '..a	end	else	local name_parts_mk = {'да', 'ди', 'де', 'Де', 'ла', 'Ле', 'тен', 'ван', 'Ван'}	local name_parts_ru = {'да', 'ди', 'де', 'Де', 'ла', 'Ле', 'тен', 'ван', 'Ван'}	local name_parts = {'da', 'de', 'di', 'De', 'la', 'Le', 'ten', 'van', 'Van'}	if count == 3 and label ~= '' then	a, b, c = string.match(label, "(%S+)%s+(%S+)%s+(%S+)")	if wiki == 'mk' then	for _,v in ipairs(name_parts_mk) do if b == v then names = b..' '..c..' '..a done = true break end end	elseif wiki == 'ru' then	for _,v in ipairs(name_parts_ru) do if b == v then names = b..' '..c..' '..a done = true break end end	else	for _,v in ipairs(name_parts) do if b == v then names = b..' '..c..' '..a done = true break end end	end	if not done then	names = tostring(c)..' '..tostring(a)..' '..tostring(b)	done = true	end	end	if count > 3 and label ~= '' then	a, b, c, d = string.match(label, "(%S+)%s+(%S+)%s+(%S+)%s+(%S+)")	if wiki == 'mk' then	for _,v in ipairs(name_parts_mk) do if c == v then names = c..' '..d..' '..a..' '..b done = true break end end	for _,v in ipairs(name_parts_mk) do if b == v then names = b..' '..c..' '..d..' '..a done = true break end end	elseif wiki == 'ru' then	for _,v in ipairs(name_parts_ru) do if c == v then names = c..' '..d..' '..a..' '..b done = true break end end	for _,v in ipairs(name_parts_ru) do if b == v then names = b..' '..c..' '..d..' '..a done = true break end end	else	for _,v in ipairs(name_parts) do if c == v then names = c..' '..d..' '..a..' '..b done = true break end end	for _,v in ipairs(name_parts) do if b == v then names = b..' '..c..' '..d..' '..a done = true break end end	end	if not done then names = label.."%"..b end --b..' '..c..' '..d..' '..a end	end	end	end	return names or '' end local function findSortKey(riderID, correctlanguage, wikiIsSlavic)	--find the last name to sort	if wikiIsSlavic and correctlanguage then	local label = wikibase.getLabelByLang(riderID, wiki)	if label then	local nametable = mw.text.split(label, ",")	if nametable[2] then --there is a coma so the lastname is first	return nametable[1]..nametable[2]	else --no coma	return findLastName(label,wiki)	end	end	end	--all other cases	label = getLabelFallback(riderID)	return findLastName(label,wiki) end --== V) Main functions == --=== A) Function race reference === local function race_reference(raceID,lf)	-- Allow to display the reference below the classifications --	local bases={	{"ProCyclingStats", "P2327", "http://www.procyclingstats.com/race.php?id="},	{"Cycling Quotient", "P2648", "http://www.cqranking.com/men/asp/gen/race.asp?raceid="},	{"Cycling Archives", "P2330", "http://www.cyclingarchives.com/ritfiche.php?ritid="},	{"Cycling Quotient", "P2708", "http://www.cqranking.com/women/asp/gen/race.asp?raceid="},	-- cycling team	{"ProCyclingStats", "P2328", "http://www.procyclingstats.com/team/"},	{"Cycling Quotient", "P2649", ""}, --The entire link is indicated in full	{"Cycling Archives", "P2331", "http://www.cyclingarchives.com/ploegfiche.php?id="}	}	local links = {}	local ref	for _, base in pairs(bases) do	local p = mw.wikibase.getBestStatements(raceID, base[2])	if p[1] and p[1].mainsnak.snaktype == 'value' then if base[2]=="P2648" and p[1].mainsnak.datavalue.value=="1" then --code for general reference of results	ref=getReference(lf,p[1], 1)	if ref then	table.insert(links, ref) end	else	table.insert(links, ' [' .. base[3] .. p[1].mainsnak.datavalue.value .. " " .. base[1] ..']')	end	end	end	if #links == 1 then	return translate("race_reference", 1) .. table.concat(links)	elseif #links > 1 then	return translate("race_reference", 2) .. table.concat(links)	else	return ''	end end --=== B) Calendar === function p.calendarcustom(frame)	local headers={2} --date	local calendarID, lf =get_and_checkID(frame)	local display_numbering=false --default	local country_column=2	if istrue(get_arg('display_numbering',frame)) then	display_numbering=true	table.insert(headers, 3)	country_column=3	end --no_country modify the way the country is displayed local no_country={} if istrue(get_arg('no_country',frame)) or wiki == "ar" then	no_country={wiki}	end	-- country --	table.insert(headers, 5)	--race--	table.insert(headers, 4)	local display_class=false	if istrue(get_arg('display_class',frame)) or wiki == "ar" then	display_class=true	table.insert(headers, 6)	end table.insert(headers, 7) --winner	local only_winner=1	if istrue(get_arg('podium',frame)) or wiki == "ar" then	only_winner =0	table.insert(headers, 8) --second	table.insert(headers, 9)	--third	end	local display_leader=false	if istrue(get_arg('display_leader',frame)) then display_leader=true table.insert(headers, 10)	end	local display_team =false	if istrue(get_arg('display_team',frame)) then	display_team =true	end	local data_type={}	for ii=1,#headers do	table.insert(data_type,'')	end local w_race=isWomenrace(calendarID)	local s = {	header_function = "calendar", -- translations are in function Calendar	header_1 = 1000, -- translation 1 in function Calendar is printed in the upper part of the table header	header_2 = headers,-- translations 2, 3, 4, 5, 6 in function Calendar are printed in this order	title=wikibase.getLabel(calendarID), -- in the lower part of the table header. The second value 3 in {4, 3} tells where the icon will go.	country_column = country_column,	data_sort_type = data_type, -- see https://meta.wikimedia.org/wiki/Help:Sorting	item = calendarID,	property = 'P527',	no_country = no_country,	only_winner = only_winner,	display_numbering = display_numbering,	displayed_class =nil,	display_team=display_team,	display_class=display_class,	display_leader= display_leader,	w_race=w_race,	lf=lf	}	return calendar_main(s, tableA(s)) end function p.calendar(frame)	----- function to display UCI calendar of one year ----	----- based on WWTcalendar function -----	----- author: Mr. Ibrahem -----	local calendarID --determined later	local lf = get_lf(frame)	local UCI = data.UCIYearToQ	local header_1_tab = {["UWT"]=13 ,["europe"]=14 ,["asia"]=15,["america"]=16 ,["africa"]=17 ,["oceania"]=18, ["WWT"]=11, ["women"]=1, ["Pro"]=22}	local display_code_tab= {["UWT"]=1 ,["europe"]=2 ,["asia"]=2,["america"]=2 ,["africa"]=2 ,["oceania"]=2, ["WWT"]=1, ["women"]=2, ["Pro"]=2}	local header_1_number = 12	local tempdic, year, keyk, yeary	local tempdic1 = {	header_2 = {2, 3,5, 4, 7, 8, 9, 10},	only_winner =0,	display_numbering=true,	display_team=false,	display_class=false,	display_leader=true	}	local tempdic2 = {	header_2 = {2, 5, 4, 6, 7},	only_winner =1,	display_numbering=false,	display_team=true,	display_class=true,	display_leader=false	}	for key, v in pairs(UCI) do	year = get_arg(key,frame) --with lf does not work	if not calendarID and year then	if v[year] then	calendarID = v[year]	header_1_number = header_1_tab[key]	display_code = display_code_tab[key]	keyk=key	yeary=year	end	end	end	if wiki == "ar" then	if not (frame.args["code"] and frame.args["code"] == "2") then	display_code = 1	end	if calendarID == "" and frame.args.test then	calendarID = frame.args.test	end	end	if not calendarID or calendarID == "" then return "" end	if display_code == 1 then	tempdic=tempdic1	if keyk=="UWT" and tonumber(yeary) > 2018 then	tempdic.display_leader=false --no more leader after 2018	tempdic.header_2 ={2, 3,5, 4, 7, 8, 9}	end	else	tempdic=tempdic2	end	if istrue(get_arg('display_numbering',lf)) then	tempdic.display_numbering=true	elseif get_arg('display_numbering',lf) and istrue(get_arg('display_numbering',lf)) == nil then	tempdic.display_numbering=false	end	local w_race=isWomenrace(calendarID)	local s = {	header_function = "calendar", -- translations are in function Calendar	header_1 = header_1_number, -- t	header_2 = tempdic.header_2,	-- in the lower part of the table header. The second value 3 in {4, 3} tells where the icon will go.	country_column = 3,	data_sort_type ={'', 'unsortable', '', '', '','',''}, -- -- see https://meta.wikimedia.org/wiki/Help:Sorting	item = calendarID,	property = 'P527',	no_country = no_country_calendar,	only_winner = tempdic.only_winner,	display_numbering = tempdic.display_numbering,	displayed_class = nil, --all	display_team=tempdic.display_team,	display_class=tempdic.display_class,	display_leader=tempdic.display_leader,	w_race=w_race,	lf=lf	}	return calendar_main(s, tableA(s)) end function calendar_main(s, resultTable)--Display the UCI women calendar of one year	local lf = s.lf	local calendarID=s.item	local t_Body ={}	local w_race=isWomenrace(calendarID)	local temp=firstValue(calendarID, s.property)	if not temp or temp=="" then	s.error_message = 2	if wiki == "ar" then return "" end	end	local country=getCountryBool(s.no_country)	----- Begin of the main part of the code	for kk, p527 in statements(calendarID, 'P527') do	local RaceID = p527.mainsnak.datavalue.value.id	---- Create a row ----	local timeOfRace, date_tCell, date_sortkey = fn_date(RaceID)	local parentID, race_tCell, class_tCell= fn_race(RaceID,s.displayed_class,s.display_class,timeOfRace,nil,country)	if race_tCell~=nil then --otherwise the class is not display	local country_flag, country_name, country_tCell=fn_country(RaceID, timeOfRace, country, race_tCell, parentID)	--create the table	local tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 5px;")	tRow:node(date_tCell)	if s.display_numbering == true then	tRow:tag('td'):cssText("text-align:center;padding:0 0.5em"):wikitext(tostring(kk))	end	tRow:node(country_tCell)	if country then	tRow:node(race_tCell) end	if class_tCell then tRow:node(class_tCell) end	local rider_tCell =fn_rider(lf,RaceID,timeOfRace,s.display_team,s.only_winner)	tRow:node(rider_tCell)	if s.display_leader==true then	local leader_tCell=fn_rider(lf,RaceID,timeOfRace,s.display_team,3)	tRow:node(leader_tCell)	end	---- Add the row to the table	table.insert(t_Body, {sortkey=date_sortkey, body=tRow})	end	end	return sortAndConcat(t_Body, resultTable) end function p.nationalchampionships(frame)	local calendarroadID, calendarITTID, year	local lf=get_lf(frame)	local listOfCalendar={data.NationalRoadCyclingChampionships,data.NationalITTCyclingChampionships}	for ii, thisCalendar in pairs(listOfCalendar) do --road/ITT	for key, v in pairs(thisCalendar) do --look for the key of the dictionnary, here women/men	year = get_arg(key,frame) --with lf does not work	if ((ii==1 and calendarroadID==nil) or (ii==2 and calendarITTID ==nil)) and year then	if v[year] then	if ii==1 then	calendarroadID = v[year]	else	calendarITTID = v[year]	end	end	end	end	end	local w_race=isWomenrace(calendarroadID)	local s = {	header_function = "calendar", -- translations are in function Calendar	header_1 = 19, --	header_2 = {5, 20, 21},	country_column = 1,	data_sort_type = {'', '', ''}, -- -- see https://meta.wikimedia.org/wiki/Help:Sorting	item= calendarroadID,	calendarroadID = calendarroadID,	calendarITTID = calendarITTID,	property = 'P527',	year = year,	no_country = {}, --no sense here to hide the country	display_team = true,	display_countrylink = false, --too expensive	w_race=w_race,	lf=lf	}	return nationalchampionships_main(s,tableA(s)) end function nationalchampionships_main(s, resultTable)--Display the list of national champions for one year	local lf = s.lf	local tableChamp, t_Body = {}, {}, {}	local timeOfRace ='+'..tostring(s.year).."-01-01T00:00:00Z"	local rider_tCell, thereisawinner, parentID, parentParentID, sitelink	local country_flag, country_name, country_tCell	local temp=firstValue(s.calendarroadID, s.property)	if not temp or temp=="" then	s.error_message = 2	if wiki == "ar" then return "" end	end	local listOfCalendarID={s.calendarroadID, s.calendarITTID}	--create the table with the information	for ii, thisCalendarID in ipairs(listOfCalendarID) do	if thisCalendarID ~= nil then	for _, p527 in statements(thisCalendarID, 'P527') do	thisID = p527.mainsnak.datavalue.value.id	country_flag, country_name, country_tCell=fn_country(thisID,timeOfRace,s.country)	if country_name == nil then	country_name="country not found" end	sortkey=string.gsub(country_name, 'É', 'E') --case États Unis	--create the table	if tableChamp[sortkey]==nil then	tableChamp[sortkey]={}	tableChamp[sortkey]['countryname']=country_name	tableChamp[sortkey]['roadwinner']='<td></td>'	tableChamp[sortkey]['ITTwinner']='<td></td>'	--look for sitelink to championship	sitelink=nil --reinit	if s.display_countrylink then --expensive	parentID = firstValue(thisID, 'P361', 'id') --part of	if parentID then	parentParentID = firstValue(parentID, 'P31', 'id')	if parentParentID then sitelink = wikibase.getSitelink(parentParentID) end	end	end	tableChamp[sortkey]['sitelink']=sitelink	tableChamp[sortkey]['flag']=country_flag	end	--fill the table	rider_tCell, thereisawinner=fn_rider(lf,thisID,timeOfRace,s.display_team,1,true)	if tableChamp[sortkey]['thereisawinner']~=true then --all other cases	tableChamp[sortkey]['thereisawinner']=thereisawinner	end	if ii==1 then	tableChamp[sortkey]['roadwinner']=rider_tCell	else	tableChamp[sortkey]['ITTwinner']=rider_tCell	end	end	end	end	-- structure the display	for key, thisRow in pairs(tableChamp) do	if thisRow['thereisawinner'] then --there is a winner	local tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 5px;")	if thisRow['sitelink']~=nil then	tRow:tag('td'):wikitext(thisRow['flag']..' [['..thisRow['sitelink']..'|'..thisRow['countryname']..']]')	else	tRow:tag('td'):wikitext(thisRow['flag']..' '..thisRow['countryname'])	end	tRow:node(thisRow['roadwinner'])	tRow:node(thisRow['ITTwinner'])	table.insert(t_Body, {sortkey=key, body=tRow})	end --no winner	end --end list of key	return sortAndConcat(t_Body, resultTable) end --=== C) Victory === function p.victories(frame)	local tempID, lf=get_and_checkID(frame)	local w_race=isWomenrace(tempID)	local s = {	header_function = "victories", -- translations are in function victories	header_1 = 2, -- translation 1 in function victories is printed in the upper part of the table header	header_2 = {3, 4, 5, 6, 7},-- translations 2, 3, 4, 5, 6 in function victories are printed in this order	-- in the lower part of the table header. The second value 3 in {4, 3} tells where the icon will go.	data_type = {'date', 'race', 'country', 'class', 'rider'},	country_column = 3,	data_sort_type = {'', 'unsortable', '', '', ''}, -- see https://meta.wikimedia.org/wiki/Help:Sorting	item = tempID,	property = 'P2522',	no_country = no_country_victories,	lf=lf,	w_race=w_race	}	return victory_main(s ,tableA(s)) end function victory_main(s, resultTable)	local lf = s.lf	local _	_, _, s.item = string.find(s.item, "(%w+)")	local temp=firstValue(s.item, s.property,'id')	if not temp or temp=="" then	s.error_message = 2	if wiki == "ar" then return "" end	end	local country=getCountryBool(s.no_country)	local t_Body = {}	for _, p2522 in statements(s.item, 'P2522') do	local RaceID = p2522.mainsnak.datavalue.value.id	local tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 5px;")	local timeOfRace, date_tCell, date_sortkey = fn_date(RaceID, 'victory')	local parentID, race_tCell, class_tCell=fn_race(RaceID,nil ,true,timeOfRace, 'victory',country)--displayed_class=nil	if race_tCell~= nil then --otherwise class not to be displayed	country_flag, country_name, country_tCell=fn_country(RaceID, timeOfRace, country, race_tCell, parentID)	--Build the table	tRow:node(date_tCell)	if country==true then	tRow:node(race_tCell) --race site link is in fn_countrytable	end	tRow:node(country_tCell)	tRow:node(class_tCell) --class	local rider_tCell =fn_rider(lf,RaceID,timeOfRace,false,1)	tRow:node(rider_tCell)	table.insert(t_Body, {sortkey=date_sortkey, body=tRow})	end --no winner	end --end list of key	return sortAndConcat(t_Body, resultTable) end --== D) Stage infobox function p.stageinfobox(frame)	local stageID, lf = get_and_checkID(frame)	local w_race=isWomenrace(stageID)	local details = {	{ name = translate("stageinfobox",2,w_race)}, -- course / not used	{ name = translate("stageinfobox",2,w_race)}, -- competition	{ name = translate("stageinfobox",3,w_race), name_plural = translate("infobox",4,w_race)}, -- stage type	{ name = translate("stageinfobox",4,w_race), name_plural = translate("infobox",7,w_race)}, -- date	{ name = translate("stageinfobox",6,w_race)}, -- distance	{ name = translate("stageinfobox",7,w_race), name_plural = translate("infobox",10,w_race)}, -- country	{ name = translate("stageinfobox",9,w_race)}, -- start place	{ name = translate("stageinfobox",10,w_race)}, -- endplace	{ name = translate("stageinfobox",11,w_race)}, -- participants at start	{ name = translate("stageinfobox",12,w_race)}, -- participants at end	{ name = translate("stageinfobox",13,w_race)}, -- speed	{ name = translate("stageinfobox",44,w_race)}, -- elevation	{ name = translate("infobox",32,w_race), special = true}, -- special 1	{ name = translate("infobox",33,w_race), special = true}, -- special 2	}	local others = get_others_dic()	--begin of the function	local t_P642 = {	Q20882747={'results', 'first'},	Q20882748={'results', 'second'},	Q20882749={'results', 'third'},	Q21686770={'results', 'winner_fighting'},	Q2250962={'results', 'cima_coppi'},	Q10452933={'results', 'cima_pantani'},	Q20882763={'gen', 'leader'},	Q20882764={'gen', 'deuxieme'},	Q20882765={'gen', 'troisieme'},	Q20883213={'annex', 'montagne'},	Q20883140={'annex', 'jeune'},	Q20883008={'annex', 'points'},	Q20883329={'annex', 'sprints'},	Q20893984={'annex', 'super_combatif'},	Q20965880={'annex', 'combine'},	Q27104688={'annex', 'stage_volantes'},	Q27104684={'annex', 'regularite'},	Q20882922={'annex', 'equipe'},	Q27104271={'annex', 'equipe_points'},	Q20882667={'gen', 'leader'},	Q20882668={'gen', 'deuxieme'},	Q20882669={'gen', 'troisieme'},	Q20883212={'annex', 'montagne'},	Q20883139={'annex', 'jeune'},	Q20883007={'annex', 'points'},	Q20883328={'annex', 'sprints'},	Q20893983={'annex', 'super_combatif'},	Q20893979={'annex', 'combine'},	Q27067359={'annex', 'stage_volantes'},	Q27067170={'annex', 'regularite'},	Q27907747={'annex', 'azzurri_ditalia'},	Q27907748={'annex', 'azzurri_ditalia'},	Q27907714={'annex', 'breakaway'},	Q27907715={'annex', 'breakaway'},	Q20882921={'annex', 'equipe'},	Q27104269={'annex', 'equipe_points'}	}	getLocalContent(details, lf.args)	getLocalContent(others, lf.args)	local timeOfRace	local temp = firstValue(stageID, 'P31','id')	icon = ''	if temp and temp ~= 'Q18131152' then	if temp=='Q2266066' or temp=='Q2348250' or temp=='Q485321' then	icon = " [[File:Cycling (track) pictogram.svg|35px]]"	else	icon = " [[File:Cycling (road) pictogram.svg|35px]]"	end	details[3].content = typeofstagelogo(stageID, true).." "..WPlinkpure(temp)	end	local name = getLabelFallback(stageID) or ''	if wiki == 'fr' and name ~= nil then	name= mw.ustring.gsub(name, "^(%d+)([re]+)", "%1<sup>%2</sup> ")	end name= mw.ustring.gsub(name, "^(%a)",function (x) return mw.ustring.upper(x) end)	infoGetOthers(others, stageID)	--name	local race={}	if course==nil then	temp = firstValue(stageID, 'P1545')	if temp then	details[2].content =getStageLabel(temp)	raceId = getParentID(stageID) --for instance Tour de France 2020	if raceId then	details[2].content = (details[2].content or '') .. '، '.. WPlinkpure(raceId)	for k, p31 in statements(raceId, 'P31') do --get Tour de France	race[k] = p31.mainsnak.datavalue.value.id --for the jersey	end	end	end	end	-- This function give a format to dates when P585 (date) is used in a single day race	local pTime = firstValue(stageID, 'P585', 'time') -- P585 is 'point in time'	if pTime then	details[4].content = funcDate(pTime, 'long')	timeOfRace = pTime	end	local kmdistance	if not details[5].content then details[5].content, kmdistance = getDistance(stageID, true) end -- distance	infoGetCountry(details,6, stageID, timeOfRace)	infoGetStartEnd(details,7, stageID, timeOfRace)	infoGetParticipants(details,9, stageID)	if not details[11].content then details[11].content = getSpeed(stageID, true, kmdistance, 'P2417') end --speed	if not details[12].content then	local elevation=getElevation(stageID)	if elevation ~= nil then details[12].content =elevation else details[12].content = nil end	end --Elevation	local jerseyWPID, jersey_name	local t_s = {	order={'results', 'gen', 'annex'},	results={show=false,	header=15,	order = {'first','second','third','winner_fighting','winner_fighting2','cima_coppi','cima_pantani'},	first={translation=16},	second={translation=17},	third={translation=18},	winner_fighting={translation=19},	winner_fighting2={translation=19}, -- two winner_fighting possible	cima_coppi={translation=40},	cima_pantani={translation=41}	},	gen={show=false,	header=20,	order = {"leader", "deuxieme", "troisieme"},	leader={translation=21},	deuxieme={translation=22},	troisieme={translation=23}	},	annex={show=false,	header=24,	order={"points","montagne","sprints","jeune","super_combatif","combine",	"stage_volantes","regularite","azzurri_ditalia","breakaway","equipe","equipe_points"},	points={translation=25},	montagne={translation=26},	sprints={translation=27},	jeune={translation=28},	super_combatif={translation=29},	combine={translation=30},	stage_volantes={translation=31},	regularite={translation=32},	azzurri_ditalia={translation=42},	breakaway={translation=43},	equipe={translation=33},	equipe_points={translation=34}	}	}	--Winner	for _, p1346 in statements(stageID, 'P1346') do	local id_speed, id_time, id_time_gap, id_points_a, id_points_b, type_ofclas, name_ofclas	local q = p1346.qualifiers	local riderId = p1346.mainsnak.datavalue.value.id	id_time = qualifieramount(p1346, 'P2781')	id_time_gap =qualifieramount(p1346, 'P2911')	id_speed =qualifieramount(p1346, 'P2052')	id_points_a = qualifieramount(p1346, 'P1358')	id_points_b =qualifieramount(p1346, 'P1351')	if riderId ~= nil then	local riderLink,riderTeam = subwinner(riderId, timeOfRace, q) --sub function to avoid code in double	-- looks into race item if the winner has a P642 statement for showing the type of winner(points, mountain, ..)	if q.P642 and q.P642[1].snaktype == 'value' then	for _, vv in pairs(q.P642) do	local qual = vv.datavalue.value.id	if qual~=nil and deprecated~='deprecated' and t_P642[qual] then	if qual=="Q21686770" and t_s['results']['winner_fighting'][1] ~= "" then	t_P642[qual][2] = 'winner_fighting2'	end	type_ofclas=t_P642[qual][1] --annex or gen	name_ofclas=t_P642[qual][2] --name of ranking	local v=t_s[type_ofclas][name_ofclas]	v['link']=riderLink	v['team']=riderTeam	v['rank']=isdisqualified(p1346,q)	v['time']=id_time	v['gap']=id_time_gap	if id_points_a then v['points']=id_points_a end	if id_points_b then v['points']=id_points_b end	v['speed']=id_speed	if qual=="Q27104271" and t_s.annex.equipe_points['link']==nil then	t_s.annex.equipe_points['link']=riderId	end	if qual=="Q20882922" and t_s.annex.equipe['link']==nil then	t_s.annex.equipe['link']=riderId	end	v['genre'] = getGenderCode(riderId,'f')	end	end	end	end	end	local rank, deprecated, prop, order, thisorder	-- look into P2417, stage classification, then p2321 gen classification	for ii, thistable in ipairs({'results','gen'}) do	if ii==1 then	prop='P2417'	order = {'first', 'second', 'third'}	else	prop='P2321'	order = {'leader', 'deuxieme', 'troisieme'}	end	for _, p2417 in statements(stageID, prop) do	local q = p2417.qualifiers	if q.P1352 and q.P1352[1].snaktype == 'value' then	for _, q1352 in pairs(q.P1352) do	rank = tonumber(q1352.datavalue.value.amount)	end	if rank == 1 or rank == 2 or rank == 3 then	thisorder=order[rank]	local v=t_s[thistable][thisorder]	v['rank'] = isdisqualified(p2417, q)	local thisid= p2417.mainsnak.datavalue.value.id	v['link'],_ = subwinner(thisid, timeOfRace, q)	if v['gap'] == nil and v['time'] == nil then	v['gap'] = qualifieramount(p2417, 'P2911')	end	if v['gap'] == nil and v['time'] == nil then	v['time'] = qualifieramount(p2417, 'P2781')	end	v['speed'] = qualifieramount(p2417, 'P2052')	v['genre'] = getGenderCode(thisid, 'f')	end	end	end	end	for _, thistable in ipairs({t_s.results,t_s.gen,t_s.annex}) do	for _, v in ipairs(thistable.order) do --order is the list of all classification names	if thistable[v]['link'] then	thistable.show = true	end	end	end	---General table	local temp	local width= '320px' -- size standard 320px, special 340px	if t_s.annex.show == true and (wiki == 'no' or wiki == '..') then width= '340px' end	tab= infoInitTab(width, name, icon)	infoFillOthersDetails(tab, others, details,translate("stageinfobox",1,w_race)) -- ranking table, general and stage	for _, value_order in ipairs(t_s.order) do	local thistable =t_s[value_order] --results or gen or annex	if thistable.show then -- if a section of the stageinfobox should be shown	tCell=tab:tag('tr'):tag('td'):attr('colspan','2')	tTab=tCell:tag('table'):attr('cellpadding','0'):attr('cellspacing','0'):css('width','100%')	tCell=tTab:tag('tr'):tag('td'):attr('colspan','3')	:cssText('border-bottom:5px solid '..backgroundColorLight..'; background-color:'..backgroundColor..'; text-align:center')	:css('font-weight','bold')	:wikitext(translate("stageinfobox",thistable.header,w_race))	for key, value in ipairs(thistable.order) do --value is the name of the class	local v=thistable[value]	if v['link'] then	local a1	a1, jersey_name, jerseyWPID = jersey_infobox( value, race, timeOfRace)	if a1~='' then v['jersey'] = a1 end	if v['speed'] then	if wiki == 'fo' then	v['speed'] = string.gsub(v['speed'], "%.", ",")	else	local lang = mw.language.getContentLanguage()	v['speed'] = '('.. lang:formatNum(v['speed'])..translate("unit",5,w_race)..')'	end	end	if v['points'] then	if v['points'] > 1 then	temp=translate("unit",7,w_race)	else temp=translate("unit",6,w_race)	end	v['points'] = v['points']..temp	end	local title, k = string.gsub(translate("stageinfobox",v['translation'],w_race), " ", "&nbsp;")	if k > 0 then title = string.gsub(title, "&nbsp;", "<br>", 1) end --&#32;	--Create an empty column on the left	tRow=tTab:tag('tr'):css('vertical-align','top')	tCell=tRow:tag('td')	:css('font-weight','bold')	if v['team']~=nil or v['speed'] ~=nil then	tCell:attr('rowspan','2')	end	tCell:cssText("width:1%;background-color:"..backgroundColorLight..";text-align:" ..	textalign .. ";padding:0 2px 0 2px;white-space:nowrap")	if value_order~='annex' and v['translation']~=40 and v['translation']~=41 then -- Cima Coppi, Cima Pantani with a line break	if v['jersey'] == nil then	if (value_order=='results') and (value=='winner_fighting' or value=='winner_fighting2' or value=='cima_coppi' or value=='cima_pantanii') then	tCell:wikitext(translate("stageinfobox",v['translation'],w_race))	else	tCell:wikitext(number(v['genre'], key, wiki))	end	else	temp=''	if jerseyWPID~='' then	temp="|link="..jerseyWPID	end	tCell:wikitext("[[File:"..v['jersey'].."|20px|"..title..temp.."]]")	end	else	if v['jersey'] == nil then	tCell:wikitext(title)	else	if jerseyWPID=='' then	if jersey_name ~= '' then	temp = "|"..jersey_name	else	temp=''	end	else	temp= "|link="..jerseyWPID	end	tCell:wikitext("[[File:"..v['jersey'].."|20px"..temp.."]]" .. title)	end	end	tRow:tag('td'):cssText("padding:0 0.5em 0 0.5em;"..v['rank'])	:wikitext( v['link'])	tCell=tRow:tag('td'):cssText('text-align:right;font-size:85%;white-space:nowrap')	if v['time'] then	tCell:wikitext(calculateTime(v['time']))	end	if v['gap'] then	tCell:wikitext('+ '.. calculateTime(v['gap']))	end	tCell:wikitext(v['points'])	end	tCell=tTab:tag('tr'):tag('td'):attr('colspan','2')	if v['team']~=nil and v['speed'] ~=nil then -- team row	tTab2=tCell:tag('table'):attr('cellpadding','0'):attr('cellspacing','0'):css('width','100%')	tRow = tTab2:tag('tr')	tRow:tag('td'):cssText('width:100%;text-align:" .. textalign .. ";padding-left:2px')	:wikitext("("..v['team']..")") --add the team	tRow:tag('td'):cssText('font-size:85%;vertical-align:top;white-space:nowrap')	:wikitext(v['speed'])	else	if v['team']~=nil or v['speed'] ~=nil then	tCell:cssText("text-align:" .. textalign .. ";padding-left:2px")	if v['team'] ~= nil then	tCell:wikitext("("..v['team']..")") --add the team	end	tCell:tag('span'):cssText("float:right;font-size:85%;"):wikitext(v['speed'])	end	end	end	end	end	infoFillOthersMap(tab, others)	tab:node(getPreviousNextLine(stageID,true))	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/stageinfobox", translate("stageinfobox",39,w_race), stageID)	return tab end --== E) List of teams function p.listofteams(frame)	local raceID, lf = get_and_checkID(frame)	local teams = {} -- values will be {teamLink, teamCat, sortkey, index}	local WDlink_on = (wiki == "mk" or wiki == "ja")	local timeOfRace = getTimeOfRace(raceID, true)	local w_race=isWomenrace(raceID)	local teamCats_lot = { -- {c,d,e} c = singular team type, d = plural team type, e = print order of the team types -- Part of the numbering is omitted for the convenience of possible subsequent editing.	-- UCI professional men's teams	["Q6154783"] = {4,5,1}, -- WorldTeam	["Q20638319"] = {6,7,2}, -- ProTeam (2005-2014)	["Q78464255"] = {6,7,3}, -- ProTeam (2020-)	["Q382927"] = {8,9,4}, -- UCI Professional Continental Team (2005-2019)	["Q1756006"] = {10,11,5}, -- UCI Continental Team	["Q20639847"] = {16,17,6}, -- professional cycling team	["Q20653563"] = {20,21,7}, -- Groupe Sportif I	["Q20653564"] = {22,23,8}, -- Groupe Sportif II	["Q20653566"] = {24,25,9}, -- Groupe Sportif III	-- UCI professional women's teams	["Q80425135"] = {57,58,11}, -- UCI Women’s WorldTeam	["Q130604574"] = {59,60,12}, -- UCI Women’s ProTeam	["Q119942457"] = {32,33,13}, -- UCI Women's Continental Team (2020-)	["Q2466826"] = {28,29,14}, -- UCI Women’s Team (-2019)	["Q119948768"] = {55,56,15}, -- UCI Women's Elite-2 Team	-- other non-road UCI teams	["Q2466819"] = {45,46,21}, -- UCI Track Team	["Q39885628"] = {47,48,22}, -- UCI Cyclocross Team	["Q2466804"] = {49,50,23}, -- UCI MTB Team	["Q39885630"] = {51,52,24}, -- UCI BMX Team	-- national teams (partially merged)	["Q54660600"] = {12,13,31}, -- national cycling team "any", without specifying additional parameters"	["Q23726798"] = {12,13,31}, -- national cycling team Elit	["Q99658502"] = {12,13,31}, -- national cycling team "B"	["Q20738667"] = {12,13,31}, -- national cycling team U23	["Q54555994"] = {12,13,31}, -- national cycling team U19	["Q26213387"] = {12,13,31}, -- olympic team	["Q46135307"] = {12,13,31}, -- nation at sport competition in multisport games	["Q28492441"] = {39,40,32}, -- national cycling team with sponsor name	["Q117280678"] = {37,38,33}, -- mixt cycling team -- Below are two blocks with "non-professional" teams. They differ in the type of output - individually or all together. You can choose any manual setting.	-- amateur, club and region (not merged). Each type of team is output in a separate block	["Q114864716"] = {43,44,41}, -- DCU Elite Team	["Q20652655"] = {18,19,42}, -- amateur cycling team	["Q26849121"] = {30,31,43}, -- Women's amateur cycling team	["Q20639848"] = {14,15,44}, -- club cycling team	["Q20653570"] = {53,54,45}, -- region cycling team	-- amateur, club and region (merged). All types of team are displayed in a common block --	["Q114864716"] = {41,42,41}, -- DCU Elite Team --	["Q26849121"] = {41,42,41}, -- Women's amateur cycling team --	["Q20652655"] = {41,42,41}, -- amateur cycling team --	["Q20639848"] = {41,42,41}, -- club cycling team --	["Q20653570"] = {41,42,41}, -- region cycling team	}	local p1923 = mw.wikibase.getBestStatements(raceID, 'P1923') -- P1923 is participating teams	local no = 0 -- Index used for stable sorting	for _, v in pairs(p1923) do	if v.mainsnak.snaktype == 'value' then	no = no + 1	local teamLink, teamCat, countryID = getTeamLinkCat(v.mainsnak.datavalue.value.id, timeOfRace, true)	local flagImage = countryID and flag(countryID, timeOfRace) or ''	teams[#teams + 1] = {flagImage .. ' ' .. teamLink, teamCat,	teamCats_lot[teamCat] and teamCats_lot[teamCat][3] or 999, no}	end	end	table.sort(teams, function(a,b)	if a[3] < b[3] then return true end -- First sort key: Order from table teamCats_lot	if a[3] > b[3] then return false end	return a[4] < b[4] -- Second key is the index to ensure stable sorting	end)	local function getHeader(CatID, count)	local header, sitelink	if teamCats_lot[CatID] then	local done=false	if CatID=="Q2466826" then --name changed after 2020	local year = timeOfRace and tonumber(string.sub(timeOfRace, 2, 5))	if year and year>2019 then	if count == 1 then	header_label = translate("headoftableIII",32, w_race) -- singular name	else	header_label = translate("headoftableIII",33, w_race) -- plural name	end	done=true	end	end	if done==false then	if count == 1 then	header_label = translate("headoftableIII",teamCats_lot[CatID][1], w_race) -- singular name	else	header_label = translate("headoftableIII",teamCats_lot[CatID][2], w_race) -- plural name	end	end	if CatID=='Q78464255' then	sitelink=wikibase.getSitelink('Q382927') --continental	else	sitelink=wikibase.getSitelink(CatID)	end	if sitelink ~= nil then	header = '[['..sitelink..'|'..header_label..']]'	else	header= header_label	end	end	local tHeader= mw.html.create('span'):css('font-size','1.2em'):css('font-weight','bold')	if not header then	-- Unknown team category. Get the label for the entity to display if possible	header = (CatID and getLabelFallback(CatID)) or 'Unknown team category'	tHeader:css('text-transform','capitalize')	end	tHeader:wikitext(header)	-- Set parameter to show team count in front of each category	local tTag=''	local showcounter = 2	if count >= showcounter then	tTag=mw.html.create('small'):wikitext(' (' .. count ..')')	end	return tostring(tHeader)..tostring(tTag)	end	local oldOrder = 0	local oldCatID	local count = 0	local list = ''	local header	local resultTable = mw.html.create('table')	:cssText("max-width:95%; padding:0.5em; margin-right:1em; border:1px solid rgb(200,200,200)")	local tCell = resultTable:tag('tr'):tag('td')	for _, team in ipairs(teams) do	local order = team[3]	if order ~= oldOrder then --new cat	if oldOrder > 0 then	header = getHeader(oldCatID, count)	tCell:wikitext(header)	tCell:node(tOl)	end	count = 1	oldOrder = order	tOl = mw.html.create('ul') --reinit	else	count = count + 1	end	oldCatID = team[2] tOl:tag('li')	:cssText("width:20em;display:inline-block;vertical-align:text-top")	:wikitext(team[1])	end	--add last row	header = getHeader(oldCatID, count)	tCell:wikitext(header)	tCell:node(tOl)	local wd_link = mw.html.create('span'):css('float',floattable):wikitext(wdLink(raceID .. '#P1923'))	if arwiki_totemplate then wd_link = wdLink(raceID .. '#P1923') end	local tableFooter1=mw.html.create('tr')	tCell=tableFooter1:tag('td')	:addClass('navigation-only')	:cssText('border-top: 2px '..backgroundColor..' solid; font-size: 80%;')	tCell:wikitext(tostring(wd_link))	resultTable:node(tableFooter1)	return resultTable end --== F) Classifications function p.UCIclassification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 19, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	item =tempID,	property = 'P3494', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	display_team=false,	max_rank_displayed=100000, --unlimited the whole team must be displayed	lf=lf	}	return new_classification(s, frame) end function p.pointsclassification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 10, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P3494', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.teamsclassificationbytime(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 14, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {3, 2, 4}, -- translations 3, 2, 4 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P3497', -- property to use for this table	team_classification = true, -- it is a team classification table, its not a rider classification table	background = 'strong', -- there is no background color for the first row, but the first row is formated strong	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.teamsclassificationbypoints(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 15, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {3, 2, 7}, -- translations 3, 2, 7 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P3496', -- property to use for this table	team_classification = true, -- it is a team classification table, its not a rider classification table	background = 'strong', -- there is no background color for the first row, but the first row is formated strong	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.stageclassification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 8, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 4}, -- translations 1, 2, 3, 4 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P2417', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = false, -- there is no background color for the first row	display_ref = get_arg(2, frame,true) == 0 and 0 or 1,	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.generalclassification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 9, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 4}, -- translations 1, 2, 3, 4 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P2321', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	display_ref = get_arg(2, frame,true) == 0 and 0 or 1,	max_rank_displayed=25,	lf=lf	}	return new_classification(s, frame) end function p.generalclassificationpoint(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 9, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P2321', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	display_ref = get_arg(2, frame,true) == 0 and 0 or 1,	max_rank_displayed=25,	lf=lf	}	return new_classification(s, frame) end function p.generalclassificationforttt(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 9, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {3, 2, 4, 5, 6}, -- translations 3, 2, 4, 5, 6 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P2321', -- property to use for this table	team_classification = true, -- it is a team classification table, its not a rider classification table	background = false, -- there is no background color for the first row	display_ref =get_arg(2, frame,true) == 0 and 0 or 1,	max_rank_displayed=25,	lf=lf	}	return new_classification(s, frame) end function p.teamtimetrialclassification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 8, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {3, 2, 4, 5, 6}, -- translations 3, 2, 4, 5, 6 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P2417', -- property to use for this table	team_classification = true, -- it is a team classification table, its not a rider classification table	background = false, -- there is no background color for the first row	display_ref = get_arg(2, frame,true) == 0 and 0 or 1,	max_rank_displayed=25,	lf=lf	}	return new_classification(s, frame) end function p.mountainsclassification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 11, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P4320', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.sprintsclassification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 12, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P4322', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.intermediatesprintclassification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 20, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P4958', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.bestyoungclassificationbypoints(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 13, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P4323', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.bestyoungclassification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 13, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 4}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P4323', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.u23classification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 18, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 4}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P4323', -- property to use for this table (same as best young classification)	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.combinationclassification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 16, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P4324', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.combativeclassification(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_1 = 17, -- translation 10 in function headoftableII is printed in the upper part of the table header	header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	item = tempID,	property = 'P4321', -- property to use for this table	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.custompointsclassification(frame)	local tempID, lf=get_and_checkID(frame)	local team_title	local temp=get_arg(4,frame)	if temp and string.find(temp,"{{{")==nil then	team_title=temp	end	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_2 = {1, 2, 3, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	header_1_text=get_arg(3,frame) or '', --with lf does not work	item = tempID,	property = get_arg(2,frame), -- property to use for this table	team_title=team_title, --for old races where there was no team, only bike brands	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.customtimeclassification(frame)	local tempID, lf=get_and_checkID(frame)	local team_title	local temp=get_arg(4,frame)	if temp and string.find(temp,"{{{")==nil then	team_title=temp	end	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_2 = {1, 2, 3, 4}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	header_1_text=get_arg(3,frame) or '',	item = tempID,	property = get_arg(2,frame), -- property to use for this table	team_title=team_title, --for old races where there was no team, only bike brands	team_classification = false, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.customteamclassificationbypoints(frame)	local tempID, lf=get_and_checkID(frame)	local team_title	local temp=get_arg(4,frame)	if temp and string.find(temp,"{{{")==nil then	team_title=temp	end	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_2 = {3, 2, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	header_1_text=get_arg(3,frame) or '', --with lf does not work	item = tempID,	property = get_arg(2,frame), -- property to use for this table	team_title=team_title, --for old races where there was no team, only bike brands	team_classification = true, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function p.customteamclassificationbytime(frame)	local tempID, lf=get_and_checkID(frame)	local team_title	local temp=get_arg(4,frame)	if temp and string.find(temp,"{{{")==nil then	team_title=temp	end	local s = {	header_function = "headoftableII", -- translations are in function headoftableII	header_2 = {3, 2, 4}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table header	header_1_text=get_arg(3,frame) or '', --with lf does not work	item = tempID,	property = get_arg(2,frame), -- property to use for this table	team_title=team_title, --for old races where there was no team, only bike brands	team_classification = true, -- it is not a team classification table, its a rider classification table	background = 'color', -- there is a background color for the first row	max_rank_displayed=10,	lf=lf	}	return new_classification(s, frame) end function new_classification(s, frame)	local country = getCountryBool(no_country_classification)	local lf = s.lf	local raceID = s.item	local w_race=isWomenrace(raceID)	--[=[ It is possible to give the classification tables in the article commands to change the standard behaviour. They could look like this:	{{Cycling race/teamsclassificationbytime|Q18574623|newline=false|country=true}}	{{Cycling race/teamsclassificationbytime|Q18574623|country= false|newline=false}}	{{Cycling race/teamsclassificationbypoints|Q18574623|newline =true|country=true}}	{{Cycling race/teamsclassificationbypoints|Q18574623|newline= true}}	{{Cycling race/teamsclassificationbypoints|Q18574623|newline = false|country=false}}	{{Cycling race/teamsclassificationbytime|Q18574623|newline=true|country=true}}	One additional parameter is "newline" with the values "true" or "false". "newline" says, if there is a line brake after the table. Standard is	no line break after the tables stageclassification and teamtimetrialclassification.	The second parameter is "country" with the values "true" or "false". "country" tells the module to print the country column or not.	Most wikis have as standard to print the country columns, some wikis prefer as standard not to show the country column. A few lines above,	the command "if wiki == 'da' then country = false end" tells that daWiki do not want to see the country colums as standard. You can add your wiki	here in, if you do not want to see them as standard. With the new parameter editors are able to tell the module in the article what to do.	]=]	local timeOfRace = getTimeOfRace(raceID, true)	local plus = ''	if get_arg('country',frame)~=nil then -- switch country column on or off in the article	if get_arg('country',frame) == 'true' and l10n["country_name_list"] then country = true end	if get_arg('country',frame) == 'false' then country = false end	end	local tableHeader2_size = #s.header_2	local max_rank_displayed=s.max_rank_displayed	for _, p31 in statements(raceID, 'P31') do	if data.stages[p31.mainsnak.datavalue.value.id] then	max_rank_displayed=10 --limit general ranking to 10 except for not stage	end	end	local temp=get_arg('max_rank_displayed',frame)	if temp and temp~='' and string.find(temp,"{{{")==nil then	max_rank_displayed=tonumber(temp)	end	if s.header_1_text ==nil then s.header_1_text=translate(s.header_function,s.header_1,w_race) end --for custom title	local team_translation_index=3	if s.team_title == nil then s.team_title=translate(s.header_function,team_translation_index,w_race) end --translation for team has index "3"	local tableBody = mw.html.create('table')	:addClass('sortable')	:attr('cellpadding', '0')	:attr('cellspacing', '0')	:css('border' , '0')	local wd_link = wdLink( raceID .. '#' .. s.property )	local wd_span = mw.html.create('span'):css('float','left'):wikitext(wd_link)	if wiki == "ar" then	if arwiki_totemplate then wd_span = wd_link	else wd_span = mw.html.create('span'):css('float','right'):wikitext(wd_link)	end end	tableBody:tag('tr'):tag('th') :attr('colspan', tostring(tableHeader2_size + 1)):cssText("padding:2px 2px; text-align:center; background-color:"..backgroundColor)	:wikitext(tostring(wd_span)..s.header_1_text)	header= tableBody:tag('tr'):cssText("text-align:center;padding:2px 2px;white-space:nowrap")	for i, k in ipairs(s.header_2) do	if i ~= 2 or country then	local header_text	if k == team_translation_index then --for team header_text=s.team_title	else header_text=translate(s.header_function,k,w_race)	end	local head =header:tag('th'):wikitext(header_text)	if i == 1 then	head:attr('colspan','2')	end	end	end	local t_Body = {} --contains all rows	local tCell, bg_color, tStyle, temp, temp2	local claims = mw.wikibase.getAllStatements(raceID, s.property)	for l, m in pairs(claims) do -- look into all statements	if m.mainsnak.snaktype == 'value' then	local riderID = m.mainsnak.datavalue.value.id	local q = m.qualifiers or {}	local rank, riderLink, gender, countryID, teamLink	local flagLink, countryName = '', ''	local h = {	jersey = {}, -- lots of jerseyID	value = {'', '', '', ''} -- points, time, time_gap, speed	}	if q.P1352 and q.P1352[1].snaktype == 'value' then -- P1352 is ranking	rank = tonumber(q.P1352[1].datavalue.value.amount)	else	rank = ''	end	if q.P1534 and q.P1534[1].snaktype == 'value' then	local dnf=q.P1534[1].datavalue.value.id	if dnf=='Q1210380' then riderDNF =translate("startlist",6,w_race)--"HD","NP","DQ"	elseif dnf=='Q54881674' or dnf=='Q7113430' then riderDNF =translate("startlist",7,w_race)	elseif dnf=='Q1210382' then riderDNF =translate("startlist",8,w_race)	elseif dnf=='Q1229261' then riderDNF =translate("startlist",9,w_race)	else riderDNF=''	end	else	riderDNF=''	end	local cancelled=isdisqualified(m,q)	if wiki == 'es' or wiki == 'fr' or wiki == 'ast' then	--[[ These wikis need the gender to display the rank correct. Other wikis can skip this. ]]	gender = getGenderCode(riderID, 'n')	end	h.value[1] = qualifieramount(m, 'P1358')	h.value[2] = qualifieramount(m, 'P2781')	if q.P2911 and q.P2911[1].snaktype == 'value' then -- P2911 is time gap	h.value[3] = tonumber(q.P2911[1].datavalue.value.amount)	plus = '+ '	end	h.value[4] = qualifieramount(m, 'P2052')	if q.P2912 then -- P2912 is distinctive jersey	for _, v in pairs(q.P2912) do	if v.snaktype == 'value' then	table.insert(h.jersey, v.datavalue.value.id)	end	end	end	if s.team_classification then	local _	teamLink, _, countryID = getTeamLinkCat(riderID, timeOfRace, true)	else	riderLink = getRiderLink(riderID,timeOfRace)..(getReference(lf,m) or '')	teamLink = getTeam(riderID, timeOfRace, q)	countryID = getNationality(riderID, timeOfRace,q)	end	if countryID then	flagLink = flag(countryID, timeOfRace)	if country then	countryName = getCountryName(countryID)	end	end	-- find the right background color if a rider has more then one jersey	-- see Wikidata:WikiProject Cycling/Kit to translate/Jerseys	bg_color=nil	if h.jersey[1] then	for _, jersey in pairs(h.jersey) do	if data.bg_color_table[jersey] then	bg_color = data.bg_color_table[jersey]	break	end	end	end	tStyle=''	if rank == 1 then	if s.background then -- values are 'strong' or 'color'	tStyle = tStyle ..'font-weight:bold;' -- winner is formated bold	if s.background == 'color' then	if h.jersey[1] and bg_color then -- background color of winner depending on jersey	tStyle = tStyle .. 'background-color:' ..bg_color	end	end	end	end	local tBody = mw.html.create('tr'):cssText(tStyle) -- a row	tBody:tag('td'):cssText("text-align:center;padding:2px 0.5em 2px 0.5em;white-space:nowrap;"..cancelled)	:wikitext(number(gender, rank, wiki))	tCell= tBody:tag('td'):cssText("text-align:" .. textalign .. ";padding:0 0.2em 0 0.2em;"..cancelled)	if not s.team_classification then	if country then	tCell:wikitext(riderLink .. jersey(h.jersey) )	tBody:tag('td'):wikitext( flagLink ..' '.. countryName)	else	tCell:wikitext(flagLink .. ' ' .. riderLink .. jersey(h.jersey))	end	if s.display_team~=false then	tBody:tag('td'):cssText("text-align:".. textalign ..";padding:0 0.2em 0 0.2em")	:wikitext(teamLink or '')	end	else --team	if country then	tCell:wikitext(teamLink .. jersey(h.jersey))	tBody:tag('td'):wikitext(flagLink .. ' ' .. countryName)	else	tCell:wikitext(flagLink .. ' ' .. teamLink .. jersey(h.jersey))	end	end	if s.header_2[4] == 4 then -- for table stageclassification, generalclassification, adds time and time gap	if riderDNF=='' then	if rank == 1 and h.value[2] then	temp=calculateTime(h.value[2])	elseif rank == 1 and h.value[3]==nil then --avoid a plus with nothing	temp=''	else	temp=plus .. calculateTime(h.value[3])	end	else	temp=riderDNF	end	tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(temp)	end	if s.header_2[4] == 7 or (s.header_2[3] == 7 and s.header_2[1] == 1) then -- for table pointsclassification, adds points	--trick for UCI classification	if riderDNF=='' then	if h.value[1] then temp=h.value[1] else temp='' end	tCell=tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em")	:wikitext(temp)	if type(h.value[1]) == "number" then	if h.value[1] > 1 then	temp2=translate("unit",7,w_race)	else	temp2=translate("unit",6,w_race)	end	tCell:tag('span'):cssText("font-size:80%"):wikitext(temp2)	end	else	tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(riderDNF)	end	end	if s.header_2[3] == 4 then	if s.property == 'P2417' or s.property == 'P2321' then	-- for tables teamtimetrialclassification or generaltttclassification, adds time	tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em")	:wikitext(calculateTime(h.value[2]))	end	end	if s.property == 'P3497' then -- for table teambytimeclassification, adds time and time gap	if rank == 1 then	temp=calculateTime(h.value[2])	else	temp=plus .. calculateTime(h.value[3])	end	tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(temp)	end	if s.property == 'P3496' then -- for table teambypointsclassification, adds points	tCell=tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em") :wikitext(h.value[1])	if type(h.value[1]) == "number" then	if h.value[1] > 1 then	temp2=translate("unit",7,w_race)	else	temp2=translate("unit",6,w_race)	end	tCell:tag('span'):cssText("font-size:80%"):wikitext(temp2)	end	end	if s.header_2[4] == 5 then -- for table teamtimetrialclassification, adds time gap	if l > 1 then temp= plus else temp='' end	tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(temp..calculateTime(h.value[3]))	end	if s.header_2[5] == 6 then -- for table teamtimetrialclassification, adds speed	tCell=tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em")	if type(h.value[4]) == "number" then	tCell:wikitext(mw.ustring.format('%.3f', h.value[4]))	:tag('span'):cssText("font-size:80%"):wikitext(translate("unit",5,w_race))	end	end	if rank~='' and rank<=max_rank_displayed then --else no display	if riderDNF=='' then	table.insert(t_Body, {sortkey=(type(rank) == 'number') and rank or 999, body=tostring(tBody)})	else --disqualified should be higher than not disqualified if the ranking was revided	table.insert(t_Body, {sortkey=(type(rank) == 'number') and rank-0.1 or 999, body=tostring(tBody)})	end	end	end	end tableBody=sortAndConcat(t_Body, tableBody)	local tableFooter1,tableFooter2	if s.display_ref == 1 or wiki == "ar" then	tableFooter1=mw.html.create('tr')	tCell=tableFooter1:tag('td')	:addClass('navigation-only')	:cssText('border-top: 2px '..backgroundColor..' solid; font-size: 80%;')	tableFooter2=mw.html.create('tr')	tCell=tableFooter2:tag('td')	:cssText("text-align:right")	tCell:tag('small')	:wikitext(race_reference(raceID,lf))	end	--general table style and last line	local tableStyle, tableNewline	if get_arg('newline',frame) == 'false' then -- parameter newline in WP article is 'false'	tableStyle = "float:" .. floattable .. "; margin-right:0.5em; border:1px solid rgb(200,200,200)"	tableNewline = ''	end	if get_arg('newline',frame) == 'true' then -- parameter newline in WP article is 'true'	tableStyle = "border:1px solid rgb(200,200,200)"	tableNewline = '<br style="clear:left;">'	end	if get_arg('newline',frame) == nil then -- no second parameter, compatible to the old code	if s.property == 'P2417' then --stageclassification	tableStyle = "float:"..floattable.."; margin-right:0.5em; border:1px solid rgb(200,200,200)"	tableNewline = ''	else	tableStyle = "border:1px solid rgb(200,200,200)"	tableNewline = '<br style="clear:left;">' -- everything else	end	end	local finalTable= mw.html.create('table'):cssText(tableStyle)	finalTable:tag('tr'):tag('td')	:node(tableBody)	if tableFooter1 then	finalTable:node(tableFooter1)	finalTable:node(tableFooter2)	end	return tostring(finalTable)..tableNewline end --=== G) Infobox === function p.infobox(frame) -- normal infobox	return infobox_main(frame,0) end function p.seasoninfobox(frame) -- season infobox	return infobox_main(frame,1) end function p.champinfobox(frame) -- champ infobox	return infobox_main(frame,2) end function infobox_main(frame, selector)	local WDlink_on = (wiki == "mk" or wiki == "ja")	-- If true, winners will the team of the cyclist	local team = true	local details, others, winners, plural	local entityID, lf = get_and_checkID(frame)	local w_race=isWomenrace(entityID)	if selector==0 then -- normal infobox	details = {	{ name = translate("infobox",2,w_race)}, -- course	{ name = translate("infobox",3,w_race), name_plural = translate("infobox",4,w_race)}, -- competition	{ name = translate("infobox",5,w_race)}, -- stages	{ name = translate("infobox",6,w_race), name_plural = translate("infobox",7,w_race)}, -- date	{ name = translate("infobox",8,w_race)}, -- distance	{ name = translate("infobox",9,w_race), name_plural = translate("infobox",10,w_race)}, -- country	{ name = translate("infobox",11,w_race)}, -- start place	{ name = translate("infobox",12,w_race)}, -- endplace	{ name = translate("infobox",13,w_race)}, -- teams	{ name = translate("infobox",14,w_race)}, -- participants at start	{ name = translate("infobox",15,w_race)}, -- participants at end	{ name = translate("infobox",16,w_race)}, -- speed	{ name = translate("infobox",43,w_race)}, -- elevation	{ name = translate("infobox",17,w_race)}, -- cost	{ name = translate("infobox",32,w_race), special = true}, -- special 1	{ name = translate("infobox",33,w_race), special = true}, -- special 2	{ name = translate("teaminfobox",13,w_race)}, -- official web site	}	elseif selector==1 then -- season infobox	details = {	{ name = translate("infobox",46,w_race)}, -- edition (1)	{ name = translate("infobox",3,w_race), name_plural = translate("infobox",4,w_race)}, -- competition (2)	{ name = translate("infobox",6,w_race), name_plural = translate("infobox",7,w_race)}, -- date (3)	{ name = translate("infobox",45,w_race), name_plural=translate("infobox",71,w_race)}, -- rasing (4)	{ name = translate("infobox",47,w_race), name_plural = translate("infobox",48,w_race)}, -- location (country) (5)	{ name = translate("infobox",49,w_race), name_plural = translate("infobox",50,w_race)}, -- organizer (6)	{ name = translate("infobox",63,w_race), name_plural = translate("infobox",63,w_race)}, -- team class (7)	{ name = translate("infobox",32,w_race), special = true}, -- special 1	{ name = translate("infobox",33,w_race), special = true}, -- special 2	{ name = translate("teaminfobox",13,w_race)}, -- official web site	}	else -- champ infobox details = {	{ name = translate("infobox",46,w_race)}, -- edition (1)	{ name = translate("infobox",6,w_race), name_plural = translate("infobox",7,w_race)}, -- date (2)	{ name = translate("infobox",9,w_race), name_plural = translate("infobox",10,w_race)}, -- country (3)	{ name = translate("infobox",67,w_race), name_plural = translate("infobox",68,w_race)}, -- location (city) (4)	{ name = translate("infobox",61,w_race), name_plural = translate("infobox",62,w_race)}, -- arena / stadion (5)	{ name = translate("infobox",60,w_race)}, -- medals (6)	{ name = translate("infobox",13,w_race)}, -- team (7)	{ name = translate("infobox",49,w_race), name_plural = translate("infobox",50,w_race)}, -- organizer (8)	{ name = translate("infobox",32,w_race), special = true}, -- special 1	{ name = translate("infobox",33,w_race), special = true}, -- special 2	{ name = translate("teaminfobox",13,w_race)}, -- official web site	}	end	others = get_others_dic()	if selector==0 then -- normal infobox winners = {	{ name = translate("infobox",19,w_race), QID = 'Q20882667' }, -- first	{ name = translate("infobox",20,w_race), QID = 'Q20882668' }, -- second	{ name = translate("infobox",21,w_race), QID = 'Q20882669' }, -- third	{ name = translate("infobox",22,w_race), QID = 'Q20883007' }, -- points	{ name = translate("infobox",23,w_race), QID = 'Q20883212' }, -- mountains	{ name = translate("infobox",24,w_race), QID = 'Q20883328' }, -- sprints	{ name = translate("infobox",25,w_race), QID = 'Q20883139' }, -- youth	{ name = translate("infobox",26,w_race), QID = 'Q101246973' }, -- supercombativity	{ name = translate("infobox",26,w_race), QID = 'Q20893983' }, -- combativity	{ name = translate("infobox",35,w_race), QID = 'Q27067359' }, -- volantes	{ name = translate("infobox",36,w_race), QID = 'Q27067170' }, -- regularity	{ name = translate("infobox",27,w_race), QID = 'Q20893979' }, -- combination	{ name = translate("infobox",38,w_race), QID = 'Q27907715' }, -- breakaway	{ name = translate("infobox",39,w_race), QID = 'Q27907747' }, -- azzurri	{ name = translate("infobox",40,w_race), QID = 'Q28092831' }, -- rookie	{ name = translate("infobox",28,w_race), QID = 'Q20882921' }, -- teams	{ name = translate("infobox",37,w_race), QID = 'Q27104269' }, -- teamspoints	{ name = translate("infobox",41,w_race), QID ='Q61976850' },-- amateur	{ name = translate("infobox",42,w_race), QID ='Q61976872' } --nationality	}	elseif selector==1 then -- season infobox winners = {	{ name = translate("infobox",52,w_race), QID = 'Q20882667' }, -- individual (first)	{ name = translate("infobox",53,w_race), QID = 'Q20883139' }, -- youth	{ name = translate("infobox",54,w_race), QID = 'Q27104269' }, -- team (teamspoints)	{ name = translate("infobox",55,w_race), QID = 'Q98959152' }, -- team GS-I	{ name = translate("infobox",56,w_race), QID = 'Q98959153' }, -- team GS-II	{ name = translate("infobox",57,w_race), QID = 'Q98959155' }, -- team GS-III	{ name = translate("infobox",58,w_race), QID = 'Q72068715' }, -- country	{ name = translate("infobox",59,w_race), QID = 'Q72068724' } -- country U23	}	end -- Champ infobox has no winners	getLocalContent(details, lf.args)	getLocalContent(others, lf.args)	if selector==0 or selector==1 then	getLocalContent(winners, lf.args)	end	local timeOfRace, class	local icon = (firstValue(entityID, 'P641','id') == "Q3609") and -- P641 is 'sport', Q3609 is 'road bicycle racing'	' [[File:Cycling (road) pictogram.svg|35px]]' or ''	local name = getLabelFallback(entityID) or ''	infoGetOthers(others, entityID)	if not details[1].content then -- course	-- For FR Wiki and Wikidata, exception that permit to display 1er, 2e... for the edition number ;	-- for RU -й is written after the value of P393	local nr = firstValue(entityID, 'P393') -- P393 is 'edition number'	if nr then	if wiki == 'fr' then nr = (nr == 1) and "1<sup>re</sup> " or (nr .. "<sup>e</sup> ")	elseif wiki == "nl" then nr = nr .. "e "	elseif wiki == "ru" then nr = nr .. "-й "	elseif wiki == "eo" then nr = nr .. "-a "	elseif wiki == "hu" then nr = nr .. ". "	else nr = nr .. ". "	end	end	local is_a	local classID = firstValue(entityID, 'P279', 'id')	--fallback	if classID then	class = classLinkFn(classID)	else	for _, p31 in statements(entityID, 'P31') do -- P31 is 'instance of'	local instanceOf = p31.mainsnak.datavalue.value.id	if instanceOf ~= "Q27020041" and data.class_dic[instanceOf] then	class = classLinkFn(instanceOf)	break	end	end	end	local season = firstValue(entityID, 'P3450', 'id') -- P3450 is 'sports season of league or competition'	if season then	is_a = raceLink(season)	else	--normally there should be only a p31	for _, p31 in statements(entityID, 'P31') do -- P31 is 'instance of'	local instanceOf = p31.mainsnak.datavalue.value.id	if instanceOf ~= 'Q27968055' and instanceOf ~= 'Q27020041' then -- Q27020041 is 'sports season'	is_a = raceLink(instanceOf)	break	end	end	end	if nr and is_a then	details[1].content = nr .. ' ' .. is_a	end	end	if selector==0 or selector==1 then	if not details[2].content then -- competition	-- Class of a cycling race. Class is: 1.UWT, 2.UWT, 1.HC, ... add new classes, no problem	-- Competition of the cycling race : UCI World Tour 2016, UCI Europe Tour 2016...	local tours = {}	for _, p361 in statements(entityID, 'P361') do -- P361 is 'part of'	tours[#tours + 1] = raceLink(p361.mainsnak.datavalue.value.id)	end	if tours[1] then	if #tours > 1 then	details[2].name = details[2].name_plural	end	if class then	tours[1] = tours[1] .. ' ' .. class	end	details[2].content = table.concat(tours, '<br/>')	end	end	end	if selector==0 then	if not details[3].content then -- stages	local stages = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part'	if stages > 0 then	details[3].content = stages	end	end	end	local index_date, index_official_site	if selector==0 then	index_date=4	index_official_site=17	elseif selector==1 then	index_date=3	index_official_site=10	else	index_date=2	index_official_site=11	end --	if selector==0 or selector==1 then	if not details[index_date].content then -- date	details[index_date].content, timeOfRace, plural = get_formatted_date(entityID, 'infobox')	if plural then	details[index_date].name = details[index_date].name_plural	end	end --	end	--from this point the functions differ fundamentally	if selector==0 then	local kmdistance	if not details[5].content then details[5].content, kmdistance = getDistance(entityID, true) end -- distance	infoGetCountry(details,6, entityID, timeOfRace)	infoGetStartEnd(details,7, entityID, timeOfRace)	if not details[9].content then -- teams	local teams = #wikibase.getBestStatements(entityID, 'P1923') -- P1923 is 'participating teams'	if teams > 0 then	details[9].content = teams	end	end	infoGetParticipants(details,10, entityID)	if not details[10].content or not details[11].content then	local Allp710= wikibase.getAllStatements(entityID, 'P710')	if Allp710 and #Allp710~=0 then	if not details[10].content then details[10].content=#Allp710 end	if not details[11].content then	local maxrank=1	for _, p710 in pairs(Allp710) do -- look into all statements	local q = p710.qualifiers	if q and q.P1352 and q.P1352[1].snaktype == 'value' then -- P1352 is ranking	local riderRank = tonumber(q.P1352[1].datavalue.value.amount)	if riderRank > maxrank then maxrank = riderRank end	end	end	if maxrank~=1 then details[11].content=maxrank end	end	end	end	if not details[12].content then details[12].content = getSpeed(entityID, true, kmdistance, 'P2321') end --speed	if not details[13].content then	local elevation=getElevation(entityID)	if elevation then details[13].content =elevation else details[13].content = nil end	end --Elevation	if not details[14].content then -- cost	local cost = firstValue(entityID, 'P2130') -- P2130 is cost	if cost then	details[14].content = dispmoney(cost.amount, cost.unit)	end	end	elseif selector==1 then	if not details[4].content then -- racing	local stages = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part'	if stages > 0 then	details[4].content = stages	if stages > 1 then	details[4].name = details[4].name_plural	end	end	end	if not details[5].content then -- location	infoGetPlace(details,5, entityID, timeOfRace) --in GAN version, the separator is , not <br />	end	if not details[6].content then -- organizer sitelink	listWPlink(details, 6, entityID,'P664',true) --org	end	if not details[7].content then -- organizer sitelink	listWPlink(details, 7, entityID,'P2670',true) --team ????	end	else --champ	infoGetCountry(details,3, entityID, timeOfRace)	if not details[4].content then -- location	infoGetPlace(details,4, entityID, timeOfRace) --in GAN version, the separator is , not <br />	end	if not details[5].content then -- arena / stadion	listWPlink(details, 5, entityID,'P115',true)	end	if not details[6].content then -- racing	local stages = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part'	if stages > 0 then	details[6].content = stages	end	end	if not details[7].content then -- teams	local teams = #wikibase.getBestStatements(entityID, 'P1923') -- P1923 is 'participating teams'	if teams > 0 then	details[7].content = teams	end	end	if not details[8].content then -- organizer sitelink	listWPlink(details, 8, entityID,'P664',true) --org	end	end	if not details[index_official_site].content then	details[index_official_site].content = officialSite(entityID)	end	tab = infoInitTab("300px", name, icon)	if selector==0 then -- normal infobox	infoFillOthersDetails(tab, others, details,translate("infobox",1,w_race))	elseif selector==1 then -- season infobox	infoFillOthersDetails(tab, others, details,translate("infobox",69,w_race))	else -- champ infobox	infoFillOthersDetails(tab, others, details,translate("infobox",70,w_race))	end	if selector==0 or selector==1 then --no winners for champ	local winRows=''	local win = {}	for _, v in pairs(winners) do	if not v.content then	win[v.QID] = ''	end	end	winner(lf,entityID, win, timeOfRace, false, WDlink_on, team, true)	for _, v in pairs(winners) do	if not v.content then	if win[v.QID] ~= '' then	v.content = win[v.QID]	end	end	if v.content then	tRow= mw.html.create('tr') :css('vertical-align','top')	tRow:tag('td'):css('font-weight','bold'):wikitext(v.name)	tRow:tag('td'):wikitext(v.content)	winRows=winRows..tostring(tRow) --not elegant	end	end	if winRows~= '' then	tab:tag('tr'):tag('td'):attr('colspan','2')	:cssText('border-bottom:5px solid white; background-color:'..backgroundColor..'; text-align:center')	:css('font-weight','bold')	:wikitext(translate("infobox",18,w_race))	tab:wikitext(winRows)	end	end	if others[3].content then -- map	tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center')	:wikitext("[[File:".. others[3].content .. "|center|300px]]")	if others[5].content then -- caption	tab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%')	:wikitext(others[5].content)	end	end	tab:node(getPreviousNextLine(entityID))	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/infobox", translate("infobox",34,w_race), entityID)	return tab end --=== H) race infobox function p.raceinfobox(frame)	local lang = contentLanguage	local WDlink_on = (wiki == "mk" or wiki == "ja")	local tRace = {race={	raceId,	raceDate,	future,	}, vainqueur= {}, }	local entityID, lf = get_and_checkID(frame)	local w_race= isWomenrace(entityID)	local details = {	{ name = translate("raceinfobox",4,w_race)}, -- sport	{ name = translate("raceinfobox",5,w_race)}, -- creation date	{ name = translate("raceinfobox",6,w_race)}, -- disparition date	{ name = translate("raceinfobox",7,w_race)}, -- number of editions	{ name = translate("raceinfobox",8,w_race)}, -- periodicity	{ name = translate("raceinfobox",9,w_race)}, -- type , name_plural = translate("infobox",10)	{ name = translate("raceinfobox",33,w_race), name_plural = translate("raceinfobox",34,w_race)},	--country	{ name = translate("raceinfobox",10,w_race), name_plural = translate("raceinfobox",11,w_race)}, -- place	{ name = translate("raceinfobox",12,w_race), name_plural = translate("raceinfobox",13,w_race)}, --org	{ name = translate("raceinfobox",27,w_race), name_plural = translate("raceinfobox",28,w_race)}, --race director	{ name = translate("raceinfobox",15,w_race), name_plural = translate("raceinfobox",16,w_race)}, -- Cat	{ name = translate("raceinfobox",17,w_race)}, -- circuit	{ name = translate("raceinfobox",14,w_race)}, -- official web site	}	local others = get_others_dic()	local name = getLabelFallback(entityID) or ''	infoGetOthers(others, entityID)	getLocalContent(details, lf.args)	getLocalContent(others, lf.args)	local timeOfRace, class local listOfNames=getFormerNames(entityID, 'P1448')	local sport_id=firstValue(entityID, 'P641', 'id')	local icon = (sport_id == "Q3609") and -- P641 is 'sport', Q3609 is 'road bicycle racing'	' [[File:Cycling (road) pictogram.svg|35px]]' or ''	--1st ist sport	if not details[1].content and sport_id then	details[1].content = WPlinkpure(sport_id)	end	--creation	local creation=firstValue(entityID, 'P571', 'time')	if not details[2].content and creation then	details[2].content = funcDate(creation, "onlyyear" )	end	--disparition	local disparition=firstValue(entityID, 'P576', 'time')	if not details[3].content and disparition then	details[3].content = funcDate(disparition,"onlyyear")	end	--populate tRace	listOfWinners(entityID, tRace,nil,lf)	--number of editions	if not details[4].content and tRace.numberOfEditions and tRace.lastEditionYear then	details[4].content = tostring(tRace.numberOfEditions).." (" .. translate("raceinfobox",31,w_race) .. " "..tostring(tRace.lastEditionYear)..")"	end	--periodicity	if not details[5].content then	details[5].content = getPeriodicity(entityID, tRace)	end	--type	if not details[6].content then	details[6].content = getType(entityID)	end	timeOfRace=nil --could be from last edition	if not details[7].content then	infoGetCountry(details,7, entityID, timeOfRace)	end	if not details[8].content then	infoGetPlace(details,8, entityID, timeOfRace)	end	if not details[9].content then	listWPlinkChrono(details, 9, entityID, {'P664'}, true, initialYear) --organiser	end	if not details[10].content then	listWPlinkChrono(details, 10, entityID, {'P488'}, 'rider', initialYear) --race dir	end	--Class and circuit	local classContent, circuitLink, numberClass= getClass(entityID)	if not details[11].content then	details[11].content = classContent	if numberClass >1 then	details[11].name = details[11].name_plural	end	end	if not details[12].content then	details[12].content = circuitLink	end	--Official web site	if not details[13].content then	details[13].content = officialSite(entityID)	end	--Build the table	tab = infoInitTab("300px", name, icon)	--former names	wiki_listOfNamesAtBottom={'ru'}	local listOfNamesAtBottom = false	for _, value in pairs(wiki_listOfNamesAtBottom) do --	if value == wiki then listOfNamesAtBottom = true end	end	--picture at the top	infoFillOthersDetails(tab, others, nil,translate("raceinfobox",19,w_race),"260px")	if not listOfNamesAtBottom then	if listOfNames and #listOfNames>1 then	tab:node(addATitle(translate("raceinfobox",18,w_race)))	for _, v in pairs(listOfNames) do	tab:node(addARow(v[2],v[3])) --period, name	end	end	end	infoFillOthersDetails(tab, nil, details,translate("raceinfobox",19,w_race),"260px")	if listOfNamesAtBottom then	if listOfNames and #listOfNames>0 then -- except for the ru-wiki, no one uses the display of official names at the bottom anyway	tab:node(addATitle(translate("raceinfobox",18,w_race)))	for _, v in pairs(listOfNames) do	tab:node(addARow(v[2],v[3])) --period, name	end	end	end	if (tRace.lastWinner and tRace.lastWinner~='') or	(tRace.maxWinner and tRace.maxWinner~='') then	tab:node(addATitle(translate("raceinfobox",20,w_race)))	if (tRace.lastWinner and tRace.lastWinner~='') then	tab:node(addARow(translate("raceinfobox",21,w_race),tRace.lastWinner))	end	if (tRace.maxWinner and tRace.maxWinner~='') then	tab:node(addARow(translate("raceinfobox",22,w_race),tRace.maxWinner))	end	end	if tRace.nextLink or tRace.lastLink then	tab:node(addATitle(translate("raceinfobox",23,w_race)))	local outTable	if tRace.lastLink then outTable = mw.html.create('tr')	local tCell=outTable:tag('td'):attr('colspan','2'):css('text-align','center')	local lastText="[[File:Crystal Clear app kworldclock.png|left|37px]]"..	translate("raceinfobox",24,w_race)..	":<br>'''"..	tRace.lastLink.."'''"	tCell:wikitext(lastText)	tab:node(outTable)	end	if tRace.nextLink then	outTable = mw.html.create('tr')	local tCell=outTable:tag('td'):attr('colspan','2'):css('text-align','center') local nextText = "[[File:Crystal Clear app kworldclock.png|left|37px]]".. translate("raceinfobox",25,w_race).. ":<br>'''".. tRace.nextLink.."'''"	tCell:cssText("text-align:center"):wikitext(nextText)	tab:node(outTable)	end	end	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/raceinfobox", translate("raceinfobox",26,w_race), entityID)	return tab end --=== I) Team roster function p.lastteamroster(frame)	local teamID, lf = get_and_checkID(frame)	local tRace = {race={	raceId,	raceDate,	future,	}, vainqueur= {},	}	listOfWinners(teamID, tRace,true,lf,"P527")	if get_arg(2,frame) ~= nil then	if mw.ustring.find(mw.ustring.lower(get_arg(2,frame)), "sort") or wiki == "lv" or wiki == "mk" or wiki == "ru" then	sort = true	else	sort = false	end	end	local s = {	sort=sort,	seasonID=tRace.lastID,	lf=lf,	year=tRace.lastEditionYear	}	if tRace.lastID then	return teamroster_main(s)	end end function p.teamroster(frame)	local seasonID, lf = get_and_checkID(frame)	local sort	--[[	The word 'sort' is used to sort the riders after the surname. It could look like this in the Wikipedia article	{{Cycling race/teamroster|Q21769847	| sort	}}	A rider called 'Laurens De Vreese' is sorted after 'De Vreese Laurens'. If you want to sort after 'Vreese Laurens De'	change that in the code. In lv mkWiki and ruWiki sorting is standard, there is no need to switch sorting on in the article	]]	if get_arg(2,frame) ~= nil then	if mw.ustring.find(mw.ustring.lower(get_arg(2,frame)), "sort") or wiki == "lv" or wiki == "mk" or wiki == "ru" then	sort = true	else	sort = false	end	end	local s = {	sort=sort,	seasonID=seasonID,	lf=lf	}	return teamroster_main(s) end function teamroster_main(s)	local flags, pays = {}, {}	local riderName, riderBirthday,riderTeam, timeTeam, correctlanguage,riderStart, riderEnd	local riderPosition, riderReason, riderRef, errortext	local riderReasonTable, riderTablecorrect, riderTablenotcorrect, riderTable = {}, {}, {}, {}	local labelMissing = false	local teamID, stagiaire	local slavicWikis = {mk = true, ru = true}	local wikiIsSlavic = slavicWikis[wiki]	local WDlink_on = wiki == "mk" or wiki == "ja" or wiki == "ru" or wiki == "he"	local tableEndText = ''	local w_race=isWomenrace(s.seasonID)	local temp = firstValue(s.seasonID, 'P5138', 'id')	if temp then teamID = temp end	local startOfSeason = getTimeOfRace(s.seasonID, true)	if not s.year then	label=getLabelFallback(s.seasonID)	local second_occurrence	local first_occurrence=string.find(label, "%d%d%d%d")	if first_occurrence~=nil then	second_occurrence=string.find(label, "%d%d%d%d",first_occurrence+1)	if second_occurrence~=nil then	s.year=string.match(label, "%d%d%d%d",first_occurrence+1) --case Tartu2024	else	s.year=string.match(label, "%d%d%d%d")	end	end	end	for _, p527 in statements(s.seasonID, 'P527') do	--re-init	riderName, riderBirthday, correctlanguage=nil, nil, nil	riderTeam, timeTeam, riderReason, riderRef=nil, nil, nil, nil	riderStart, riderEnd=nil, nil	local riderID = p527.mainsnak.datavalue.value.id	riderName, correctlanguage =getRiderLink(riderID, startOfSeason) --label	if WDlink_on==true then riderName=riderName..wdLink(riderID) end	local timeOfRace = startOfSeason	_, startOfSeasonYear, startOfSeasonMonth, startOfSeasonDay, _=parseDate(startOfSeason, '2040', '12', '31', '','')	riderBirthday=firstValue(riderID, 'P569','time')	if not wikiIsSlavic then correctlanguage=true end --actually we never take a cyrillic name if no latin is found	local sortkey = findSortKey(riderID, correctlanguage, wikiIsSlavic)	for _, q in qualifiers(p527, 'P580') do	local startdate = q.value['time']	timeOfRace = startdate	riderStart = funcDate(trans(startdate,'01', '01') or '', 'small')	end	for _, q in qualifiers(p527, 'P582') do	local enddate=q.value['time']	riderEnd = funcDate(trans(enddate,'12', '31') or '', 'small')	end	riderPosition=getPosition(riderPosition,p527)	riderReason, riderRef=getReason(riderReason,riderRef,p527, timeOfRace,enddate,s.lf)	local beginYear, beginMonth, beginDay, endYear, endMonth, endDay, beginDate, endDate, endDatefound, endDatetemp	local changedTime = '+0000-00-00'	if teamID == nil then	local p54 = getStatementForTime(riderID, 'P54', timeOfRace)	if p54 then teamID = p54.mainsnak.datavalue.value.id end	else	for _, v in statements(riderID, 'P54') do -- look into all P54 teams	stagiaire=nil	errortext=''	local thisteamID = v.mainsnak.datavalue.value.id	if thisteamID == teamID then	endDatefound=true	beginDate, endDate = getStartEndfromQuali(v.qualifiers)	beginDate, beginYear, beginMonth, beginDay, errortext = parseDate(beginDate, '2040', '01', '01', errortext, ' missing qualifiers by rider')	if not endDate then endDatefound=false end	endDate, endYear, endMonth, endDay, _ = parseDate(endDate, beginYear, '12', '31', errortext,'')	riderReason, riderRef=getReason(riderReason,riderRef,v,timeOfRace,endDate,s.lf)	if (beginYear == startOfSeasonYear or endYear == startOfSeasonYear) and ((beginYear == startOfSeasonYear and (beginMonth ~= '01' or beginDay ~= '01')) or (endYear == startOfSeasonYear and (endMonth ~= '12' or endDay ~= '31'))) then	-- riders who start after 1 January or end earlier then 31 December in the season	riderStart = funcDate(beginDate, 'small')	if endDatefound then	riderEnd = funcDate(endDate, 'small')	else	riderEnd = funcDate('+'..beginYear..'-12-31T00:00:00Z', 'small')	end	riderPosition=getPosition(riderPosition,v)	end	else	for _, q in qualifiers(v, 'P39') do	stagiaire =q.value.id	end	if not stagiaire then	endDatefound=true	beginDate, endDatetemp=getStartEndfromQuali(v.qualifiers)	if not endDatetemp then endDatefound=false end	beginDate, beginYear, beginMonth, beginDay, errortext = parseDate(beginDate, '2040', '01', '01', errortext, ' missing qualifiers by rider') endDate, endYear, endMonth, endDay, _ = parseDate(endDatetemp, beginYear, '12', '31', errortext, '')	if beginYear < startOfSeasonYear or (beginYear == startOfSeasonYear and beginMonth < startOfSeasonMonth) or	(beginYear == startOfSeasonYear and beginMonth == startOfSeasonMonth and beginDay < startOfSeasonDay) then -- start time < season time	if endDatefound then	if (endDate or '') >= changedTime then -- find maximum end time	-- Case Pierre-Roger Latour: Chambéry CF (2012 - 2014), time season at 2013	-- Task: changedTime should be after start time, but before startOfSeason	if endYear > startOfSeasonYear then	changedTime = '+'..startOfSeasonYear..'-12-31T00:00:00Z'	else	changedTime = endDate or ''	end	end	end	end	if changedTime ~= '+0000-00-00' then	riderTeam = getTeam(riderID, changedTime, nil)	local _, _, endYear, _, _ = string.find(changedTime, "(%d+)-(%d+)-(%d+)")	timeTeam = ' ('..endYear..')'	if wiki == "ar" then timeTeam = endYear end	end	end	end	end	end	--get the country	local countryID = getNationality(riderID, timeOfRace,q)	if countryID then	pays = getCountryName(countryID)	flags = flag(countryID, timeOfRace)	end	--save	local tRider={	sortkey=sortkey,	riderName=riderName,	riderBirthday=riderBirthday,	riderTeam=riderTeam,	timeTeam=timeTeam,	riderStart=riderStart,	riderEnd=riderEnd,	riderPosition=riderPosition,	riderReason=riderReason,	riderRef=riderRef,	errortext=errortext,	pays=pays,	flags=flags	}	if correctlanguage == true then	table.insert(riderTablecorrect,tRider )	else	table.insert(riderTablenotcorrect, tRider)	end	end	-- sorting names	if sort == true then	if #riderTablecorrect~=0 then	table.sort(riderTablecorrect, function(a,b) return a["sortkey"]<b["sortkey"] end)	end	if #riderTablenotcorrect~=0 then	table.sort(riderTablenotcorrect, function(a,b) return a["sortkey"]<b["sortkey"] end)	end	end	--merge	for _, v in pairs (riderTablecorrect) do	table.insert(riderTable, v)	end	for _, v in pairs (riderTablenotcorrect) do	table.insert(riderTable, v)	end	local wd_link = mw.html.create('span'):css('float','left'):wikitext(wdLink(s.seasonID..'#P527'))	if arwiki_totemplate then wd_link = wdLink(s.seasonID .. '#P527') end	local outTable = mw.html.create('table') :addClass('sortable') :attr('cellpadding', '2') :attr('cellspacing', '0') :css('border' , '1px solid rgb(200,200,200)') :css('padding', '3px')	local th_colspan = 4	if wiki == "ar" then th_colspan = 5 end	local tRow=outTable:tag('tr'):css('line-height','1.8em') :css('background-color',backgroundColor) :tag('th'):attr('colspan', th_colspan):cssText('text-align:center;white-space:nowrap')	:wikitext(tostring(wd_link))	if s.year then tRow:wikitext(translate("getSquadTableColumn",7,w_race).." "..s.year)	else	tRow:wikitext(translate("getSquadTableColumn",7,w_race))	end	local header = outTable:tag('tr')	header:tag('th'):cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",1,w_race))	local textalign = 'center'	if wiki=='ar' then textalign = 'right' end	header:tag('th'):cssText('text-align:'..textalign..';padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",2,w_race))	if l10n["country_name_list"] and wiki ~= 'lv' and wiki ~= 'ru' and wiki ~= 'da' then header:tag('th'):cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",6,w_race))	end	if wiki == "ar" then	header:tag('th'):attr('colspan', 2):cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",3,w_race))	else	header:tag('th'):cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",3,w_race))	end	local temp	local iii = 1	for i, v in pairs (riderTable) do	local tRow=outTable:tag('tr'):css('line-height','1.8em')	local tCell= tRow:tag('td'):cssText("padding:0 1em 0 0;white-space:nowrap")	if not l10n["country_name_list"] or wiki == 'lv' or wiki == 'ar' or wiki == 'ru' or wiki == 'da' then temp=v['flags']..' ' else temp='' end	tCell:wikitext(temp..v['riderName']):attr('data-sort-value',v['sortkey'])	if v['riderStart']~=nil or v['riderEnd']~=nil then	tCell:tag('span'):cssText("font-size:80%; color:#686868")	local note=''	if v['riderReason'] ~= nil then	note = ', [[#tr_'..i..s.seasonID..'|'..translate("getSquadTableColumn",4,w_race)..']]'	if wiki == "ar" then note = '، [[#tr_'..i..s.seasonID..'|'..translate("getSquadTableColumn",4,w_race)..']]' end	end	tCell:wikitext(' ('..(v['riderStart'] or '')..'–'..(v['riderEnd'] or '')	.. (v['riderPosition'] or '')..note..')')	elseif v['riderReason'] then	tCell:tag('span'):cssText("font-size:80%; color:#686868")	:wikitext('([[#tr_'..i..s.seasonID..'|'..translate("getSquadTableColumn",4,w_race)..']]'.. ')')	end	tCell=tRow:tag('td'):cssText("text-align:right;white-space:nowrap")	if wiki == 'lv' then	local _, _, beginYear, beginMonth, beginDay = string.find(startOfSeason,"(%d+)-(%d+)-0*(%d+)")	local _, _, endYear, endMonth, endDay = string.find(v['riderBirthday'] or '',"(%d+)-(%d+)-0*(%d+)")	tCell:wikitext(s.lf:expandTemplate{ title = 'Template:Birth date and age2', args = { beginYear, beginMonth, beginDay, endYear, endMonth, endDay } })	else	tCell:wikitext(funcDate(v['riderBirthday'] or '', 'long'))	if l10n["country_name_list"] and wiki ~= 'ar' and wiki ~= 'ru' and wiki ~= 'da' then	tRow:tag('td'):wikitext(v['flags'].. ' '..v['pays'])	end	end	if wiki =='he' then	local isRtl = (mw.ustring.find(v['riderTeam'], '|.*[א-ת]') or (not mw.ustring.find(v['riderTeam'], '|') and mw.ustring.find(riderTeam, '[א-ת]')))	if isRtl then	tCell=tRow:tag('td'):cssText("padding:0 0.5em; text-align:right")	else	labelMissing = true -- FIXME: labelMissing is not functional in most languages. once we have infra support for it, move it there	tCell=tRow:tag('td'):cssText("padding:0 0.5em; text-align:left")	end	elseif wiki == "ar" then tCell=tRow:tag('td'):cssText("padding:0 0.5em") else tCell=tRow:tag('td'):cssText("padding:0 0.5em; text-align:left")	end	if v['riderTeam'] then	if wiki == "ar" then	tCell:wikitext( v['riderTeam'] )	tCell=tRow:tag('td'):cssText("padding:0 0.5em")	tCell:wikitext( v['timeTeam']..v['errortext'] )	else	tCell:wikitext(v['riderTeam'].. v['timeTeam']..v['errortext'])	end	end	--tableEndText is not a table	if v['riderReason'] ~= nil or v['errortext'] ~= '' then	local temp=(v['riderReason'] or '')..(v['errortext'] or '')	if iii == 1 then	tableEndText = tableEndText.. translate("getSquadTableColumn",5,w_race)..': '.. v['riderName'].. temp	else	tableEndText = tableEndText.. '<span style="color:white">'.. translate("getSquadTableColumn",5,w_race)..': </span>'.. riderName.. temp	end	iii = iii	if riderRef ~= nil then tableEndText = tableEndText..	s.lf:extensionTag{name='ref', content=v['riderRef'], args = {name='tr_'..iii..s.seasonID}} end	tableEndText = tableEndText.. '<br>'	end	end	if labelMissing then outTable:wikitext(getMissingLabelTrackingCategory()) end	local ref=race_reference(s.seasonID,s.lf)	if ref=='' then --fallback	local UCIlink	if wiki=="fr" then	UCIlink="https://www.uci.org/fr/route/%C3%A9quipe"	else	UCIlink="https://www.uci.org/road/teams"	end	ref=translate("race_reference", 1,w_race).."["..UCIlink..' UCI]'	end	outTable:tag('tr'):tag('td'):addClass("navigation-only")	:attr('data-sort-value','zz')	:attr('colspan',th_colspan)	:cssText("border-top: 2px "..backgroundColor.." solid; font-size: 80%;")	:tag('tr')	:tag('td'):attr('colspan',th_colspan)	:attr('data-sort-value','zzz')	:cssText("text-align:right")	:tag('small'):wikitext(ref)	return tostring(outTable)..tableEndText end --== J) List of winners == function p.listofwinners(frame)	local raceID, lf =get_and_checkID(frame)	local winnersProperty = {'Q20882667','Q20882668','Q20882669'}	local s = {	countryflag=true,	raceID=raceID,	beginyear=get_arg(2,frame,true),	endyear=get_arg(3,frame,true),	shapka=get_arg(4,frame,true),	display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	winnersProperty=winnersProperty,	custom=false,	lf=lf	}	return listofwinners_main(s) end function p.listofwinnersyoung(frame)	local raceID, lf =get_and_checkID(frame)	local winnersProperty = {'Q20883139','Q72099969','Q72099972'}	local s = {	countryflag=true,	raceID=raceID,	beginyear=get_arg(2,frame,true),	endyear=get_arg(3,frame,true),	shapka=get_arg(4,frame,true),	display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	winnersProperty=winnersProperty,	custom=false,	lf=lf	}	return listofwinners_main(s) end function p.listofwinnersChamp(frame)	local raceID, lf =get_and_checkID(frame)	local winnersProperty = {'Q20882667','Q20882668','Q20882669'}	local s = {	countryflag=false,	raceID=raceID,	beginyear=get_arg(2,frame,true),	endyear=get_arg(3,frame,true),	shapka=get_arg(4,frame,true),	winnersProperty=winnersProperty,	display_team = false,	custom=false,	lf=lf	}	return listofwinners_main(s) end --listofwinnerssecondpart and so on can be coded with p.listofwinners function p.listofwinnersnowiki(frame)	local raceID, lf =get_and_checkID(frame)	local winnersProperty = {'Q20882667','Q20882668','Q20882669'}	local s = {	countryflag=true,	raceID=raceID,	beginyear=get_arg(2,frame,true),	endyear=get_arg(3,frame,true),	shapka=get_arg(4,frame,true),	display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	winnersProperty=winnersProperty,	custom=false,	lf=lf	}	return frame:extensionTag{ name = 'nowiki', content = listofwinners_main(s)} end function p.listofwinnersteamofpoint(frame)	local raceID, lf =get_and_checkID(frame)	local winnersProperty = {'Q27104269','Q72065970','Q72065977'}	local s = {	countryflag=true,	raceID=raceID,	beginyear=get_arg(2,frame,true),	endyear=get_arg(3,frame,true),	shapka=get_arg(4,frame,true),	display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	winnersProperty=winnersProperty,	custom=false,	lf=lf	}	return listofwinners_main(s) end function p.listofwinnersGSI(frame)	local raceID, lf =get_and_checkID(frame)	local winnersProperty = {'Q98959152','Q98959192','Q98959196'}	local s = {	countryflag=true,	raceID=raceID,	beginyear=get_arg(2,frame,true),	endyear=get_arg(3,frame,true),	shapka=get_arg(4,frame,true),	display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	winnersProperty=winnersProperty,	custom=false,	lf=lf	}	return listofwinners_main(s) end function p.listofwinnersGSII(frame)	local raceID, lf =get_and_checkID(frame)	local winnersProperty = {'Q98959153','Q98959194','Q98959197'}	local s = {	countryflag=true,	raceID=raceID,	beginyear=get_arg(2,frame,true),	endyear=get_arg(3,frame,true),	shapka=get_arg(4,frame,true),	display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	winnersProperty=winnersProperty,	custom=false,	lf=lf	}	return listofwinners_main(s) end function p.listofwinnersGSIII(frame)	local raceID, lf =get_and_checkID(frame)	local winnersProperty = {'Q98959155','Q98959195','Q98959198'}	local s = {	countryflag=true,	raceID=raceID,	beginyear=get_arg(2,frame,true),	endyear=get_arg(3,frame,true),	shapka=get_arg(4,frame,true),	display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	winnersProperty=winnersProperty,	custom=false,	lf=lf	}	return listofwinners_main(s) end function p.listofwinnerscountry(frame)	local raceID, lf =get_and_checkID(frame)	local winnersProperty = {'Q72068715','Q72068718','Q72068721'}	local s = {	countryflag=true,	raceID=raceID,	beginyear=get_arg(2,frame,true),	endyear=get_arg(3,frame,true),	shapka=get_arg(4,frame,true),	display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	winnersProperty=winnersProperty,	custom=false,	lf=lf	}	return listofwinners_main(s) end function p.listofwinnerscountryU23(frame)	local raceID, lf =get_and_checkID(frame)	local winnersProperty = {'Q72068724','Q72068725','Q72068729'}	local s = {	countryflag=true,	raceID=raceID,	beginyear=get_arg(2,frame,true),	endyear=get_arg(3,frame,true),	shapka=get_arg(4,frame,true),	display_team=istrue(get_arg(5,frame)), -- false= display of a rider without a team	winnersProperty=winnersProperty,	custom=false,	lf=lf	}	return listofwinners_main(s) end function p.listofwinnerscustom(frame)	local raceID, lf =get_and_checkID(frame)	local winnersProperty ={}	if istrue(get_arg('general',frame)) then table.insert( winnersProperty,'Q20882667') end	if istrue(get_arg('podium',frame)) then	table.insert( winnersProperty,'Q20882668')	table.insert( winnersProperty,'Q20882669')	end	if istrue(get_arg('points',frame)) then table.insert( winnersProperty, 'Q20883007' ) end	if istrue(get_arg('mountain',frame)) then table.insert( winnersProperty, 'Q20883212' ) end	if istrue(get_arg('sprints',frame)) then table.insert( winnersProperty, 'Q20883328' ) end	if istrue(get_arg('youth',frame)) then table.insert( winnersProperty, 'Q20883139' ) end	if istrue(get_arg('combativity',frame)) then table.insert( winnersProperty, 'Q101246973' ) table.insert( winnersProperty, 'Q20893983' ) end	if istrue(get_arg('volante',frame)) then table.insert( winnersProperty, 'Q27067359' ) end	if istrue(get_arg('regularity',frame)) then table.insert( winnersProperty, 'Q27067170' ) end	if istrue(get_arg('combination',frame)) then table.insert( winnersProperty, 'Q20893979' ) end	if istrue(get_arg('breakaway',frame)) then table.insert( winnersProperty, 'Q27907715' ) end	if istrue(get_arg('azzurri',frame)) then table.insert( winnersProperty, 'Q27907747' ) end	if istrue(get_arg('rookie',frame)) then table.insert( winnersProperty, 'Q28092831' )	end	if istrue(get_arg('teams',frame)) then table.insert( winnersProperty, 'Q20882921' )	end	if istrue(get_arg('teamspoints',frame)) then table.insert( winnersProperty, 'Q27104269' ) end	if istrue(get_arg('amateur',frame)) then table.insert( winnersProperty, 'Q61976850' ) end	if istrue(get_arg('nationality',frame)) then table.insert( winnersProperty, 'Q61976872' ) end	if istrue(get_arg('country',frame)) then table.insert( winnersProperty, 'Q72068715' ) end	if istrue(get_arg('countryU23',frame)) then table.insert( winnersProperty, 'Q72068724' ) end	local s = {	countryflag=true,	raceID=raceID,	beginyear=get_arg(2,frame,true),	endyear=get_arg(3,frame,true),	shapka=get_arg(4,frame,true),	display_team = false,	winnersProperty=winnersProperty,	custom=true,	lf=lf	}	return listofwinners_main(s) end function listofwinners_main(s)	local lf=s.lf	local raceID=s.raceID	local rows = {}	local WDlink_on = (wiki == "mk") or (wiki == "ja") or (wiki == "ru")	local WPcontent = {	row ={},	code = {}	}	local beginyear=s.beginyear or 0	local endyear=s.endyear or 0	local shapka=s.shapka or 0	local titletable	local w_race=isWomenrace(raceID)	if s.custom then	titletable={	[ 'Q20882667' ]=translate("listofwinners",2, w_race), -- winner	[ 'Q20882668' ]=translate("listofwinners",3, w_race), -- second	[ 'Q20882669' ]=translate("listofwinners",4, w_race), -- third	[ 'Q20883007' ]=translate("listofwinners",5, w_race), -- points	[ 'Q20883212' ]=translate("listofwinners",6, w_race), -- mountains	[ 'Q20883328' ]=translate("listofwinners",7, w_race), -- sprints	[ 'Q20883139' ]=translate("listofwinners",8, w_race), -- youth	[ 'Q101246973' ]=translate("listofwinners",9, w_race), -- supercombativity	[ 'Q20893983' ]=translate("listofwinners",9, w_race), -- combativity	[ 'Q20893979' ]=translate("listofwinners",10, w_race), -- combination	[ 'Q20882921' ]=translate("listofwinners",11, w_race), -- teams	[ 'Q27067359' ]=translate("listofwinners",12, w_race), -- volantes	[ 'Q27067170' ]=translate("listofwinners",13, w_race), -- regularity	[ 'Q27104269' ]=translate("listofwinners",14, w_race), -- teamspoints	[ 'Q27907715' ]=translate("listofwinners",15, w_race), -- breakaway	[ 'Q27907747' ]=translate("listofwinners",16, w_race), -- azzurri	[ 'Q28092831' ]=translate("listofwinners",17, w_race), -- rookie	[ 'Q61976850' ]=translate("listofwinners",18, w_race), -- amateur	[ 'Q61976872' ]=translate("listofwinners",19, w_race), -- nationality	[ 'Q72068715' ]=translate("listofwinners",23, w_race), -- winner country	[ 'Q72068724' ]=translate("listofwinners",24, w_race), -- winner countryU23	}	else --main titletable={ -- winner:	[ 'Q20882667' ]=translate("listofwinners",2, w_race), -- winner	[ 'Q20883007' ]=translate("listofwinners",2, w_race), -- points	[ 'Q20883212' ]=translate("listofwinners",2, w_race), -- mountains	[ 'Q20883328' ]=translate("listofwinners",2, w_race), -- sprints	[ 'Q20883139' ]=translate("listofwinners",2, w_race), -- youth (time or point)	[ 'Q101246973' ]=translate("listofwinners",2, w_race), -- supercombativity	[ 'Q20893983' ]=translate("listofwinners",2, w_race), -- combativity	[ 'Q20893979' ]=translate("listofwinners",2, w_race), -- combination	[ 'Q20882921' ]=translate("listofwinners",2, w_race), -- team (time)	[ 'Q27067359' ]=translate("listofwinners",2, w_race), -- volantes	[ 'Q27067170' ]=translate("listofwinners",2, w_race), -- regularity	[ 'Q27104269' ]=translate("listofwinners",2, w_race), -- teampoints	[ 'Q27907715' ]=translate("listofwinners",2, w_race), -- breakaway	[ 'Q27907747' ]=translate("listofwinners",2, w_race), -- azzurri	[ 'Q28092831' ]=translate("listofwinners",2, w_race), -- rookie	[ 'Q61976850' ]=translate("listofwinners",2, w_race), -- amateur	[ 'Q61976872' ]=translate("listofwinners",2, w_race), -- nationality	[ 'Q72068715' ]=translate("listofwinners",2, w_race), -- winner country	[ 'Q72068724' ]=translate("listofwinners",2, w_race), -- winner countryU23	[ 'Q98959152' ]=translate("listofwinners",2, w_race), -- winner team GS-I	[ 'Q98959153' ]=translate("listofwinners",2, w_race), -- winner team GS-II	[ 'Q98959155' ]=translate("listofwinners",2, w_race), -- winner team GS-III -- 2 place:	[ 'Q20882668' ]=translate("listofwinners",3, w_race), -- second	[ 'Q72065970' ]=translate("listofwinners",3, w_race), -- second teampoints	[ 'Q72099969' ]=translate("listofwinners",3, w_race), -- youth (time or point)	[ 'Q72068718' ]=translate("listofwinners",3, w_race), -- second country	[ 'Q72068725' ]=translate("listofwinners",3, w_race), -- second countryU23	[ 'Q98959192' ]=translate("listofwinners",3, w_race), -- second team GS-I	[ 'Q98959194' ]=translate("listofwinners",3, w_race), -- second team GS-II	[ 'Q98959195' ]=translate("listofwinners",3, w_race), -- second team GS-III -- 3 place:	[ 'Q20882669' ]=translate("listofwinners",4, w_race), -- third	[ 'Q72065977' ]=translate("listofwinners",4, w_race), -- third teampoints	[ 'Q72099972' ]=translate("listofwinners",4, w_race), -- youth (time or point)	[ 'Q72068721' ]=translate("listofwinners",4, w_race), -- third country	[ 'Q72068729' ]=translate("listofwinners",4, w_race), -- third countryU23	[ 'Q98959196' ]=translate("listofwinners",4, w_race), -- third team GS-I	[ 'Q98959197' ]=translate("listofwinners",4, w_race), -- third team GS-II	[ 'Q98959198' ]=translate("listofwinners",4, w_race), -- third team GS-III	}	end --[=[ It is possible to give the table listofwinners in the article commands. It could look like this: {{Cycling race/listofwinners|Q18574623 | above row 1: '''[[aaa bbb ccc]]''' xxx }} "above row x" inserts a new row above row x into the table. Content is what is behind the ":". ]=]	if get_arg(2,lf) then	for num, _ in pairs(lf.args) do	if num > 1 and mw.ustring.find(mw.ustring.lower(get_arg(num,lf)), 'row') then	local _, _, kebeginYear, val = mw.ustring.find(get_arg(num,lf), "([^:]+)%s*:%s*(%C+)")	local _, _, key01, kebeginYear1, kebeginYear2 = mw.ustring.find(kebeginYear, "(%a+)%s*(%a+)%s*(%d+)")	kebeginYear2 = tonumber(kebeginYear2) kebeginYear1 = mw.ustring.lower(key01..kebeginYear1)	if kebeginYear1 == 'aboverow' then WPcontent.row[kebeginYear2] = val WPcontent.code[kebeginYear2] = 0 end --0 is above	if kebeginYear1 == 'belowrow' then WPcontent.row[kebeginYear2] = val WPcontent.code[kebeginYear2] = 1 end --0 is above	end	end	end	local firstyeartodisplay=2100	local parts = mw.wikibase.getAllStatements(raceID, 'P527') -- P527 is 'has part'	for _, part in ipairs(parts) do	if part.rank ~= 'deprecated' and part.mainsnak.snaktype == 'value' then	local partID = part.mainsnak.datavalue.value.id	local timeOfRace=getTimeOfRace(partID,true,true) --original P585 and P580 inverted here	local year = timeOfRace and string.sub(timeOfRace, 2, 5) or '?'	local month = timeOfRace and string.sub(timeOfRace, 7, 8) or '01'	if year == "?" then mw.log("no year at " .. partID ) end	if endyear==0 or (tonumber(year) or 0)<=endyear then	if (tonumber(year) or 0) >= beginyear then	local thereisawinner=false	local sitelink = mw.wikibase.getSitelink(partID)	if sitelink then	sitelink = '[[' .. sitelink .. '|' .. year .. ']]'	else	sitelink = year	end	if WDlink_on then	sitelink = sitelink .. ' ' .. wdLink(partID)	end	local winners = {}	for _, property in ipairs(s.winnersProperty) do winners[property]='' end	local tCell	local tCellstr=''	local temp=firstValue(partID, 'P1346','id')	if temp and temp=='Q30108381' then --race cancelled	local cancelledlabel = getLabelFallback('Q30108381')	tCell=mw.html.create('td'):attr('colspan','4')	:cssText('text-align:center; font-style: italic')	:wikitext(cancelledlabel)	tCellstr=tostring(tCell)	else	winner(lf,partID, winners, timeOfRace, not s.countryflag, WDlink_on,s.display_team,true)	for _, property in ipairs(s.winnersProperty) do	tCell=mw.html.create('td'):wikitext(winners[property])	if winners[property]~='' then	thereisawinner=true	if tonumber(year)<firstyeartodisplay then firstyeartodisplay=tonumber(year) end	end	tCellstr= tCellstr..tostring(tCell)	end	end	if firstyeartodisplay<=tonumber(year) then rows[#rows+1]={year..month, sitelink, tCellstr}	end	end	end	end	end	table.sort(rows, function(a, b) return a[1] < b[1] end) -- Sort by year	local clear = "left"	if wiki == "ar" then clear = "right" end	--do not use hw.html here otherwise the begin and end year won't work	local table_first = "<table cellpadding='4' cellspacing='0' style='"..standardtablecss.."'>"	local tTitleRow=mw.html.create('tr')	:css('text-align','center')	:css('background-color',backgroundColor)	local tCell=tTitleRow:tag('th')	local wd_link = mw.html.create('span'):css('float','left'):wikitext(wdLink(raceID .. "#P527"))	if arwiki_totemplate then wd_link = wdLink(tostring(raceID) .. "#P527") end	if WDlink_on == false then	tCell:wikitext(tostring(wd_link))	end	tCell:wikitext(translate("listofwinners",1,w_race)) --year	for _, pp in ipairs(s.winnersProperty) do	tTitleRow:tag('th'):wikitext(titletable[pp])	end	local table_center=''	local nb_year_inrow=1	local lastyear	for i, row in ipairs(rows) do	sitelink=row[2]	local tRowWD=mw.html.create('tr')	local tCell=tRowWD:tag('td'):css('text-align','left')	if lastyear and mw.ustring.sub(row[1],1,4)==lastyear then	nb_year_inrow=nb_year_inrow+1	tCell:wikitext(sitelink..' ('..tostring(nb_year_inrow)..')')	else	tCell:wikitext(sitelink)	nb_year_inrow=1	end	lastyear=mw.ustring.sub(row[1],1,4)	tRowWD:node(row[3]) --add the end of the row	if WPcontent.row[i] then	tRow=mw.html.create('tr'):tag('td'):attr('colspan','4')	:css('text-align','center')	tRow:wikitext(WPcontent.row[i])	if WPcontent.code[i]==0 then --above	table_center=table_center..tostring(tRow)	table_center=table_center..tostring(tRowWD)	else --below	table_center=table_center..tostring(tRowWD)	table_center=table_center..tostring(tRow)	end	else	table_center=table_center..tostring(tRowWD)	end	end	--firstpart with header no foot	if shapka == 1 then -- standard header	return table_center .. "</table>"	elseif shapka == 2 then	-- you need to add a title and you can add text at the beginning	return table_center	else -- you need to add a title and you can add anything and anywhere	return table_first .. tostring(tTitleRow) .. table_center .. "</table>"	end end --== K) List of stages function check_basque_place(sPoint, sPointID)	local eu=false	--check if it is a town	local town=false	for _, p31 in statements(sPointID, 'P31') do	if p31.mainsnak.datavalue.value.id == "Q2074737" or p31.mainsnak.datavalue.value.id == "Q484170" then --Spanish and French towns	town=true	end	end	if not town then --if it not a town look for parent	for _, p131 in statements(sPointID, 'P131') do	if data.BasqueTown[p131.mainsnak.datavalue.value.id] then	eu=true	end	end	else	if data.BasqueTown[sPointID] then	eu=true	end	end	if eu then	sPoint = flag("Q47588", timeOfRace).." "..sPoint	end	return sPoint, eu end function p.listofstages(frame)	local WDlink_on = wiki == "mk" or wiki == "ja"	local WPcontent = {}	local raceID, lf = get_and_checkID(frame)	local thereiselevation=false	local result, tableBody	local w_race=isWomenrace(raceID) --[=[ It is possible to give the table listofstages in the article commands which overwrites data from Wikidata. It could look like this: {{Cycling race/listofstages|Q18574623 | RoW 1: locaTION Ab : [[1a1b]] | after row 1 : date : 99 août | after row 1 : icon : [[File:Stage rest day.svg|vbght frthzt fdgtr]] | after row 1: text : rest day at [[aaa bbb ccc]] | row 4: location A : [[4a4a]]abc | row 3 : winner a : <sup>tzhgt</sup> | row 4 : winner b : kjuzhgt<br />bbjje | row 4 : icon : [[File:Mediummountainstage.svg|xcvbbgf fgtr]] | row 4 : distance : <s>141.8</s> 122<ref>test</ref> }} The first paramer is "row x" or "after row x". "after row" adds a new row after row x into the table to print e.g. a rest day. The second parameters are "location [a/b/ab]", "date", "icon", "text", "winner [a/b]" and "distance". "a" and "b" means the first and the second location or winner. "ab" could be used if start location and end location are the same. The file data for the icon looks this way: [[File:Stage rest day.svg|any text]] ]=]	if get_arg(2,lf) then	local WProw, WPnew_row, WPcourse, WPtext, WPdate, WPwinner, WPicon, WPdistance	= 'row', 'afterrow', 'location', 'text', 'date', 'winner', 'icon', 'distance'	local _, kebeginYear, key2, val	local key01, kebeginYear1, kebeginYear2	local key21, key22	for num, var in pairs(lf.args) do	if num > 1 and mw.ustring.find(mw.ustring.lower(var), WProw) then	_, _, kebeginYear, key2, val = mw.ustring.find(var, "([^:]+)%s*:?%s*([^:]*)%s*:%s*(%C+)")	_, _, key01, kebeginYear1, kebeginYear2 = mw.ustring.find(kebeginYear, "(%a+)%s*(%a+)%s*(%d+)")	kebeginYear2 = tonumber(kebeginYear2)	kebeginYear1 = mw.ustring.lower(key01 .. kebeginYear1)	key2 = mw.ustring.lower(mw.text.trim(key2))	_, _, key21, key22 = mw.ustring.find(key2, "(%a+)%s*(%a*)")	if not WPcontent[kebeginYear2] then WPcontent[kebeginYear2] = {} end	if kebeginYear1 == WProw and key21 == WPcourse then WPcontent[kebeginYear2][key22] = val end	if kebeginYear1 == WPnew_row and key2 == WPdate then	WPcontent[kebeginYear2]['date'] = val	WPcontent[kebeginYear2]['text'] = WPcontent[kebeginYear2]['text'] or ''	WPcontent[kebeginYear2]['icon (new row)'] = WPcontent[kebeginYear2]['icon (new row)'] or ''	end	if kebeginYear1 == WPnew_row and key2 == WPtext then	WPcontent[kebeginYear2]['text'] = val	WPcontent[kebeginYear2]['date'] = WPcontent[kebeginYear2]['date'] or ''	WPcontent[kebeginYear2]['icon (new row)'] = WPcontent[kebeginYear2]['icon (new row)'] or ''	end	if kebeginYear1 == WPnew_row and key2 == WPicon then	val = string.gsub(val, "|", "|border|right|20px|", 1)	WPcontent[kebeginYear2]['icon (new row)'] = val	WPcontent[kebeginYear2]['date'] = WPcontent[kebeginYear2]['date'] or ''	WPcontent[kebeginYear2]['text'] = WPcontent[kebeginYear2]['text'] or ''	end	if kebeginYear1 == WProw and key21 == WPwinner and key22 == 'a' then WPcontent[kebeginYear2]['stage winner'] = val end	if kebeginYear1 == WProw and key21 == WPwinner and key22 == 'b' then WPcontent[kebeginYear2]['general winner'] = val end	if kebeginYear1 == WProw and key21 == WPicon then	val = string.gsub(val, "|", "|border|right|20px|", 1)	WPcontent[kebeginYear2]['icon'] = val end	if kebeginYear1 == WProw and key21 == WPdistance then WPcontent[kebeginYear2]['distance'] = val end	end	end	end	local countries = wikibase.getAllStatements(raceID, 'P17')	local onecountry, firstcountryID	if countries and #countries>1 then	onecountry=false	if countries[1] then	firstcountryID=countries[1].mainsnak.datavalue.value.id	end	else	onecountry=true	end	local rows = {}	local stages = mw.wikibase.getBestStatements(raceID, 'P527') -- P527 is 'has part'	for _, v in pairs(stages) do	if v.mainsnak.snaktype == 'value' then	local stageID = v.mainsnak.datavalue.value.id	local p = mw.wikibase.getBestStatements(stageID, 'P1545') -- P1545 is 'series ordinal'	local sOrdinal = p[1] and p[1].mainsnak.snaktype == 'value' and p[1].mainsnak.datavalue.value	or ''	local _, _, sNumber, sLetter = string.find(sOrdinal, '(%d+)(.*)')	if not sNumber then sNumber = '' end	if not sLetter then sLetter = '' end	local WDLink = WDlink_on and wdLink(stageID) or ''	local sitelink = mw.wikibase.getSitelink(stageID)	local timeOfRace =getTimeOfRace(stageID)	local sPointID = firstValue(stageID, 'P1427', 'id')	local sPoint = (sPointID and getPlaceLink(sPointID, timeOfRace)) or ''	local eu=false	if wiki=="eu" and sPointID then	sPoint, eu=check_basque_place(sPoint, sPointID)	end	if sPointID and not onecountry and not eu then	local startcountryID=getCountryID(sPointID, timeOfRace)	if startcountryID and firstcountryID ~= startcountryID then	sPoint = flag(startcountryID, timeOfRace).." "..sPoint	end	end	local dPointID = firstValue(stageID, 'P1444', 'id')	local dPoint = (dPointID and getPlaceLink(dPointID, timeOfRace)) or ''	eu=false	if wiki=="eu" and dPointID then	dPoint, eu=check_basque_place(dPoint, dPointID)	end	if dPointID and not onecountry and not eu then	local dcountryID=getCountryID(dPointID, timeOfRace)	if dcountryID and firstcountryID ~= dcountryID then	dPoint = flag(dcountryID, timeOfRace).." "..dPoint	end	end	local sDistance = getDistance(stageID, false) or ''	local sElevation = getElevation(stageID)	if sElevation then thereiselevation=true end	local winners = {	Q20882747 = '', -- Q20882747 is 'stage winner'	Q20882763 = '', -- Q20882763 is 'overall leader at the end of the stage'	Q20882667 = '', -- Q20882667 is 'overall winner' not supposed to be used	}	winner(lf,stageID, winners, timeOfRace, false, WDlink_on)	-- find the type of stage	local sType = typeofstagelogo(stageID)	local label, section_title	if sOrdinal == "0" then	label, section_title = translate("func_prologue",1), "#" .. translate("func_prologue",1)	else	label, section_title = stageLink(sOrdinal, sNumber, sLetter)	end	-- if there is a Wikipedia article of that stage show it or show the section	local sLink = sitelink and ("[[" .. sitelink .. "|" .. label .. "]]") or	("[[" .. section_title .. "|" .. label .. "]]")	local sDate = funcDate(timeOfRace, 'small')	local tempoverall	if winners['Q20882763']~='' then tempoverall=winners['Q20882763'] else	tempoverall=winners['Q20882667'] end	rows[#rows + 1] = {	rank=tonumber(sNumber) or 0,	sortkey=sLetter, -- Sort keys	sLink=sLink,	sDate=sDate,	WDLink=WDLink,	sPoint=sPoint,	dPoint=dPoint,	sType=sType,	sDistance=sDistance,	sElevation=sElevation,	sSWin=winners['Q20882747'],	sGWin=tempoverall -- Content	}	end	end	table.sort(rows, function(a, b)	if a["rank"] ~= b["rank"] then return a["rank"] < b["rank"] end	return a["sortkey"] < b["sortkey"]	end)	local Id = ((not WDlink_on and wdLink(string.gsub(raceID, '%s', '') .. "#P527")) or "")	tab=mw.html.create('table')	:attr('cellpadding','4' )	:attr('cellspacing','0')	:cssText(standardtablecss)	local tRow=tab:tag('tr'):css('background-color',backgroundColor)	:css('text-align','center')	tRow:tag('th'):css('white-space','nowrap')	:wikitext(Id..translate("headoftable",1,w_race))	tRow:tag('th'):wikitext(translate("headoftable",2,w_race))	tRow:tag('th'):wikitext(translate("headoftable",3,w_race))	tRow:tag('th'):css('color',backgroundColor):wikitext("type")	tRow:tag('th'):wikitext(translate("headoftable",4,w_race))	if thereiselevation then	tRow:tag('th'):wikitext(translate("headoftable",7,w_race))	end	tRow:tag('th'):wikitext(translate("headoftable",5,w_race))	tRow:tag('th'):wikitext(translate("headoftable",6,w_race))	local header = tostring(tRow)	for num, row in pairs(rows) do	local sPoint=row["sPoint"]	local dPoint=row["dPoint"]	local sType=row["sType"]	local sDistance=row["sDistance"]	local WPc = WPcontent[num]	if WPc then	if WPc['a'] then sPoint = WPc['a'] end	if WPc['b'] then dPoint = WPc['b'] end	if WPc['ab'] then sPoint, dPoint = WPc['ab'], '' end	if WPc['icon'] then sType = WPc['icon'] end	if WPc['distance'] then sDistance = WPc['distance'] end	end	local tRow = tab:tag('tr')	local tCell= tRow:tag('td'):cssText('text-align:center; white-space:nowrap'):wikitext(row["sLink"])	tCell:tag('span'):css('white-space','nowrap'):wikitext("&nbsp;".. row["WDLink"])	tRow:tag('td'):css('white-space','nowrap'):cssText("text-align:right; padding-right:0px")	:wikitext(row["sDate"])	tCell=tRow:tag('td'):cssText("padding-right:0px"):wikitext( sPoint)	if dPoint ~= '' then	tCell:wikitext(" – " .. dPoint)	end	tRow:tag('td'):cssText("padding-right:0px"):wikitext(sType)	tRow:tag('td'):css('text-align','center'):wikitext( sDistance)	if thereiselevation then	tRow:tag('td'):css('text-align','center'):wikitext(row["sElevation"])	end	if WPc and WPc['stage winner'] then	tRow:tag('td'):css('text-align',textalign):wikitext( WPc['stage winner'])	else	tRow:tag('td'):wikitext(row["sSWin"])	end	if WPc and WPc['general winner'] then	tRow:tag('td'):css('text-align',textalign):wikitext( WPc['general winner'])	else	tRow:tag('td'):wikitext(row["sGWin"])	end	if WPc and (WPc['date'] or WPc['text'] or WPc['icon (new row)']) then	tRow = tab:tag('tr')	tRow:tag('td') --empty	if WPc['icon (new row)'] == '' then	tRow:tag('td'):cssText('text-align:right; padding:3px 0px 10px 0px;white-space:nowrap')	:wikitext(WPc['date'])	tRow:tag('td'):cssText("text-align:" .. textalign .. "; padding:3px 4px 10px")	:wikitext(WPc['text'])	else	tRow:tag('td'):cssText('text-align:right; padding-right:0px')	:wikitext(WPc['date'])	tRow:tag('td'):cssText("text-align:" .. textalign)	:wikitext(WPc['text'])	end	tRow:tag('td'):css('padding-top','10px'):wikitext(WPc['icon (new row)'])	tRow:tag('td'):attr('colspan','3')	end	end	if arwiki_totemplate then	tab = change_listofstages(tab, raceID, header, Id)	end	return tab end function p.stagetitle(frame)	local stageID = get_and_checkID(frame)	-- from to	local sPointID = firstValue(stageID, 'P1427', 'id')	local sPoint = sPointID and getPlaceLink(sPointID) or ''	local dPointID = firstValue(stageID, 'P1444', 'id')	local dPoint = (dPointID and getPlaceLink(dPointID)) or ''	local sDistance = getDistance(stageID, true) or ''	local sType = typeofstagelogo(stageID) -- find the type of stage	tab=mw.html.create('table')	tab:tag('th'):wikitext(sPoint.." - "..dPoint)	tab:tag('td'):wikitext(sType)	tab:tag('td'):css('font-weight','bold'):wikitext("("..sDistance..")")	return tab end local function champtitle(h) --!h is h.jersey	local road, ITT, result	local hcountry, hnotcountry = {},{}	local w_race=nil --to be defined if needed	--the jersey for a stage race and the jersey from national championship should be differentiated	--to avoid to look every time, below is a list of all national championships	if type(h) == 'table' and h[1] then	for _, v in ipairs(h) do	roadtemp=false	ITTtemp=false	if data.womenNcRoadtable[v] or data.menNcRoadtable[v] then road = true roadtemp=true	elseif data.womenNcITTtable[v] or data.menNcITTtable[v] then ITT = true ITTtemp=true	else	local raceLabel = mw.wikibase.getLabelByLang(v,"fr")	if raceLabel then	local testMenRoadrace, testMenITT, testWomenRoadrace, testWomenITT	local raceLabelmod = string.gsub(raceLabel, '-', 'x')	testMenRoadrace = string.find( raceLabel, 'Course en ligne masculine aux' )	testMenITT = string.find( raceLabelmod, 'Contrexlaxmontre masculin aux' )	testWomenRoadrace = string.find( raceLabel, 'Course en ligne féminine aux' )	testWomenITT = string.find( raceLabelmod, 'Contrexlaxmontre féminin aux' )	if testWomenRoadrace or testMenRoadrace then road = true roadtemp=true end	if testWomenITT or testMenITT then ITT = true ITTtemp=true end	end	end	if roadtemp or ITTtemp then	table.insert(hcountry,v)	else	table.insert(hnotcountry,v)	end	end	end	if road and ITT then	local image = {}	for ii, v in ipairs(hcountry) do	local p18 = mw.wikibase.getBestStatements(v, 'P18')	if p18[1] and p18[1].mainsnak.snaktype == 'value' then	local temp = p18[1].mainsnak.datavalue.value	local alreadythere = 0	for _, vv in ipairs(image) do	if vv==temp then alreadythere = 1 end	end	if alreadythere==0 then	table.insert(image,temp)	else hcountry[ii] = nil	end	end	end	--avoid double display of jersey	result = "<small>("..translate("startlist",10,w_race).." "..translate("startlist",12,w_race).." "..translate("startlist",11,w_race)..")</small>"	elseif road then	result = "<small>("..translate("startlist",10,w_race)..")</small>"	elseif ITT then	result = "<small>("..translate("startlist",11,w_race)..")</small>"	else	result = ""	end	return jersey(hcountry)..result..jersey(hnotcountry) end -- L) List of stages classification local function winnerjersey(raceID, winners)	local jerseytable, bgcolortable={}, {}	local p1346 = wikibase.getAllStatements(raceID, 'P1346') -- P1346 is 'winner'	for _, winner in pairs(p1346) do	local wOf, thisjersey, bg_color	local q = winner.qualifiers	if q then	if q.P642 and q.P642[1].snaktype == 'value' then	wOf = q.P642[1].datavalue.value.id -- P642 is 'of'	end	if q.P2912 and q.P2912[1].snaktype == 'value' then	thisjersey=q.P2912[1].datavalue.value.id	if data.bg_color_table[thisjersey] then	bg_color = data.bg_color_table[thisjersey]	end	end	end	if winners[wOf] and thisjersey then	jerseytable={}	table.insert(jerseytable,thisjersey)	winners[wOf] = jersey(jerseytable)	bgcolortable[wOf] = bg_color	end	end	return winners, bgcolortable end function p.listofstagesclassification(frame)	-- WDlink_on is used to decide if a Wikidata logo will be shown	local WDlink_on = wiki == "mk" or wiki == "ja"	local displaytypeofstage = true	local stageinfotable = {}	local raceID, lf = get_and_checkID(frame)	local w_race=isWomenrace(raceID)	local sType	--link for Grand Tour	local GTid={['Q33881']=true,['Q33861']=true,['Q33937']=true,['Q1526999']=true}	local thisGT	for _, p31 in statements(raceID, 'P31') do	if GTid[p31.mainsnak.datavalue.value.id]==true then thisGT=p31.mainsnak.datavalue.value.id break end	end	local Sitelink,overallname, pointsname, mountainname, youngname, teamname, combativityname, supercombativityname, combinedname	if thisGT then	if thisGT=='Q33881' then -- Tour de France	Sitelink = wikibase.getSitelink('Q2267539') -- General	if Sitelink then overallname="[["..Sitelink .."|"..translate("headoftableII",9,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q175399') -- Point	if Sitelink then pointsname="[["..Sitelink .."|"..translate("infobox",22,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q927157') -- Mountains	if Sitelink then mountainname="[["..Sitelink .."|"..translate("infobox",23,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q2254180') -- Young	if Sitelink then youngname="[["..Sitelink .."|"..translate("infobox",25,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q1436680') -- Team by time	if Sitelink then teamname="[["..Sitelink .."|"..translate("infobox",28,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q2094179') -- Combativity award	if Sitelink then combativityname="[["..Sitelink .."|"..translate("infobox",26,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q2094179') -- Combativity award	if Sitelink then supercombativityname="[["..Sitelink .."|"..translate("infobox",26,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q1835362') -- Combination	if Sitelink then combinedname="[["..Sitelink .."|"..translate("infobox",27,w_race).."]]" end	elseif thisGT=='Q33861' then -- Giro d'Italia	Sitelink = wikibase.getSitelink('Q1164275') -- General	if Sitelink then overallname="[["..Sitelink .."|"..translate("headoftableII",9,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q641083') -- Point	if Sitelink then pointsname="[["..Sitelink .."|"..translate("infobox",22,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q641060') -- Mountains	if Sitelink then mountainname="[["..Sitelink .."|"..translate("infobox",23,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q641662') -- Young	if Sitelink then youngname="[["..Sitelink .."|"..translate("infobox",25,w_race).."]]" end	elseif thisGT=='Q33937' then -- Vuelta a España	Sitelink = wikibase.getSitelink('Q2532554') -- General	if Sitelink then overallname="[["..Sitelink .."|"..translate("headoftableII",9,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q2241695') -- Point	if Sitelink then pointsname="[["..Sitelink .."|"..translate("infobox",22,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q1118296') -- Mountains	if Sitelink then mountainname="[["..Sitelink .."|"..translate("infobox",23,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q60233927') -- Young	if Sitelink then youngname="[["..Sitelink .."|"..translate("infobox",25,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q2141595') -- Team by time	if Sitelink then teamname="[["..Sitelink .."|"..translate("infobox",28,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q20882672') -- Combativity award	if Sitelink then combativityname="[["..Sitelink .."|"..translate("infobox",26,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q2330008') -- Combination	if Sitelink then combinedname="[["..Sitelink .."|"..translate("infobox",27,w_race).."]]" end	else -- Giro d'Italia Women	Sitelink = wikibase.getSitelink('Q3679692') -- General	if Sitelink then overallname="[["..Sitelink .."|"..translate("headoftableII",9,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q3679673') -- Point	if Sitelink then pointsname="[["..Sitelink .."|"..translate("infobox",22,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q3679712') -- Mountains	if Sitelink then mountainname="[["..Sitelink .."|"..translate("infobox",23,w_race).."]]" end	Sitelink = wikibase.getSitelink('Q3679695') -- Young	if Sitelink then youngname="[["..Sitelink .."|"..translate("infobox",25,w_race).."]]" end	end	end	local winners = {	{ name = translate("infobox",19,w_race), QID = 'Q20882747'}, -- stage	{ name = overallname or translate("headoftableII",9,w_race), QID = 'Q20882763' }, -- overall	{ name = pointsname or translate("infobox",22,w_race), QID = 'Q20883008' }, -- points	{ name = mountainname or translate("infobox",23,w_race), QID = 'Q20883213' }, -- mountains	{ name = translate("infobox",24,w_race), QID= 'Q20883329' }, -- sprints	{ name = youngname or translate("infobox",25,w_race), QID='Q20883140' }, -- youth	{ name = combativityname or translate("infobox",26,w_race), QID= 'Q21686770' }, -- combativity	{ name = supercombativityname or translate("infobox",26,w_race), QID= 'Q20893984' }, -- combativity	{ name = translate("infobox",35,w_race), QID= 'Q27104688' }, -- volantes	{ name = translate("infobox",36,w_race), QID= 'Q27104684' }, -- regularity	{ name = combinedname or translate("infobox",27,w_race), QID='Q20965880' }, -- combination	{ name = translate("infobox",38,w_race), QID='Q27907714' }, -- breakaway	{ name = translate("infobox",39,w_race), QID='Q27907748' }, -- azzurri	{ name = translate("infobox",40,w_race), QID='Q28096780'}, -- rookie	{ name = teamname or translate("infobox",28,w_race), QID='Q20882922' }, -- teams	{ name = translate("infobox",37,w_race), QID ='Q27104271' }, -- teamspoints	{ name = translate("infobox",41,w_race), QID ='Q61976847' },-- amateur	{ name = translate("infobox",42,w_race), QID ='Q61976871' } --nationality	}	local winnersgen = {	{ QID = 'Q20882667' }, -- overall	{ QID = 'Q20883007' }, -- points	{ QID = 'Q20883212' }, -- mountains	{ QID = 'Q20883328' }, -- sprints	{ QID = 'Q20883139' }, -- youth	{ QID = 'Q101246973' }, -- supercombativity	{ QID = 'Q20893983' }, -- combativity	{ QID = 'Q27067359' }, -- volantes	{ QID = 'Q27067170' }, -- regularity	{ QID = 'Q20893979' }, -- combination	{ QID = 'Q27907715' }, -- breakaway	{ QID = 'Q27907747' }, -- azzurri	{ QID = 'Q28092831' }, -- rookie	{ QID = 'Q20882921' }, -- teams	{ QID = 'Q27104269' }, -- teamspoints	{ QID = 'Q61976850' }, -- amateur	{ QID = 'Q61976872' } --nationality	}	local generaltoleader = {	['Q20882747']= nil,	['Q20882667']= 'Q20882763', -- overall	['Q20883007']= 'Q20883008', -- points	['Q20883212']= 'Q20883213', -- mountains	['Q20883328']= 'Q20883329', -- sprints	['Q20883139']= 'Q20883140', -- youth	['Q20893983']= 'Q20893984', -- combativity	['Q101246973']= 'Q21686770', -- supercombativity	['Q27067359']= 'Q27104688', -- volantes	['Q27067170']= 'Q27104684', -- regularity	['Q20893979']= 'Q20965880', -- combination	['Q27907715']= 'Q27907714', -- breakaway	['Q27907747']= 'Q27907748', -- azzurri	['Q28092831']= 'Q28096780', -- rookie	['Q20882921']= 'Q20882922', -- teams	['Q27104269']= 'Q27104271', -- teamspoints	['Q61976850']= 'Q61976847', -- amateur	['Q61976872']= 'Q61976871' --nationality	}	--read stages	local stages = mw.wikibase.getBestStatements(raceID, 'P527') -- P527 is 'has part'	local columntable, jerseytable, bgcolortable={}, {}, {}	for ii, v in ipairs(winners) do	if v.QID then	local t = {key=ii, name=v.name, jersey='', bg_color='', used=false}	for jj = 1, #stages+1 do	t[jj] = { {}, {}, {} } -- leader, first stage, number of stages consecutive (for rowspan)	end	columntable[v.QID] = t	end	end	--to have the columns in the same order as defined, otherwise they would be sorted according to the order in wikidata	--make "Q123", "Q456" --> 1, 2	local function itercolumns(columntable)	local keys = {}	for k, v in pairs(columntable) do	keys[v.key] = k --v.key is just the order of the columns	end	local upto = 1	return function ()	while keys[upto] do	upto = upto + 1	return columntable[keys[upto-1]]	end	end	end	local timeOfRace	for ii, v in pairs(stages) do	if v.mainsnak.snaktype == 'value' then	local somewinner = false --show the stage	local stageID = v.mainsnak.datavalue.value.id	local sitelink = mw.wikibase.getSitelink(stageID)	if displaytypeofstage==true then	sType = typeofstagelogo(stageID)	end	local p = mw.wikibase.getBestStatements(stageID, 'P1545') -- P1545 is 'series ordinal'	local sOrdinal = p[1] and p[1].mainsnak.snaktype == 'value' and p[1].mainsnak.datavalue.value	or ''	local _, _, sNumber, sLetter = string.find(sOrdinal, '(%d+)(.*)')	sNumber=sNumber or ''	sLetter=sLetter or ''	local label, section_title	if sOrdinal == "0" then	label, section_title = translate("func_prologue",1), "#" .. translate("func_prologue",1)	else	label, section_title = stageLink(sOrdinal, sNumber, sLetter)	end	-- If there is a Wikipedia article of that stage show it or show the section.	local sLink = sitelink and ("[[" .. sitelink .. "|" .. label .. "]]") or	("[[" .. section_title .. "|" .. label .. "]]")	timeOfRace =getTimeOfRace(stageID)	local win= {}	for _, v in pairs(winners) do	win[v.QID] = ''	if ii==1 then jerseytable[v.QID]='' end	end	winner(lf,stageID, win, timeOfRace, false, WDlink_on, false, false) --fill win table	if ii<=2 then --only two first stages	jerseytable, bgcolortable=winnerjersey(stageID, jerseytable)	end	for _, v in pairs(winners) do	if v.QID and win[v.QID] ~= '' then	--column info	somewinner=true	columntable[v.QID][ii]["leader"]=win[v.QID]	if ii==1 then --first stage	columntable[v.QID][ii]["start"]=1 --start at row 1	columntable[v.QID][ii]["rowspan"]=1 --1 consecutive stage	elseif columntable[v.QID][ii-1]["leader"]==win[v.QID] then --same winner as past stage ,make previous longer and delete this one	local initialstage=columntable[v.QID][ii-1]["start"]	columntable[v.QID][ii]["start"]=initialstage --need because of the row above	columntable[v.QID][initialstage]["rowspan"]=columntable[v.QID][initialstage]["rowspan"]+1 --one more consecutive stage	columntable[v.QID][ii]["rowspan"]=0	else --new winner	columntable[v.QID][ii]["start"]=ii --start at this row/stage	columntable[v.QID][ii]["rowspan"]=1 --1 consecutive stage	end	columntable[v.QID].used=true	if ii<=2 then --read the jersey in the two first stages of a race	if columntable[v.QID].jersey == '' or columntable[v.QID].jersey==nil then	columntable[v.QID].jersey=jerseytable[v.QID]	columntable[v.QID].bg_color=bgcolortable[v.QID]	end	end	end	end	table.insert(stageinfotable,{sLink=sLink, sType=sType, somewinner=somewinner})	end	end	--read parent	local win= {}	for _, v in pairs(winnersgen) do	if v.QID then	win[v.QID] = ''	jerseytable[v.QID]=''	end	end	local thiskey	somewinner = false	jerseytable, bgcolortable=winnerjersey(raceID, jerseytable)	winner(lf,raceID, win, timeOfRace, false, WDlink_on, false, false)	for _, v in pairs(winnersgen) do	if win[v.QID] and win[v.QID] ~= '' then	somewinner=true	thiskey=generaltoleader[v.QID]	--fill the final classification	columntable[thiskey][#stages+1]["leader"]=win[v.QID]	columntable[thiskey][#stages+1]["start"]=#stages+1	columntable[thiskey][#stages+1]["rowspan"]=1	--#stages is the last stage	if (type(columntable[thiskey][#stages]["leader"])~="string" --combativity is not extrapolated and thiskey~='Q20893984') then --check nil actually, but it is a table..	columntable[thiskey][#stages]["leader"]= win[v.QID] --extrapolate the winner	if (type(columntable[thiskey][#stages-1]["leader"])=="string" and win[v.QID]==columntable[thiskey][#stages-1]["leader"]) then --if there is a leader at forelast stage	local initialstage=columntable[thiskey][#stages-1]["start"]	columntable[thiskey][#stages]["start"]=initialstage --needed because of row above	columntable[thiskey][initialstage]["rowspan"]=columntable[thiskey][initialstage]["rowspan"]+1	columntable[thiskey][#stages]["rowspan"]=0	else	columntable[thiskey][#stages]["start"]=#stages	columntable[thiskey][#stages]["rowspan"]=1	end	end	if jerseytable[v.QID] and jerseytable[v.QID]~='' then	columntable[thiskey].jersey=jerseytable[v.QID]	columntable[thiskey].bg_color=bgcolortable[v.QID]	end	end	end	table.insert(stageinfotable,{sLink=translate("listofstagesclassification",2,w_race), sType=nil, somewinner=somewinner})	--build the table	local	tab=mw.html.create('table')	:attr('cellpadding','4' )	:attr('cellspacing','0')	:cssText(standardtablecss)	local tRow=tab:tag('tr'):css('background-color',backgroundColor)	:css('text-align','center')	tRow:tag('th'):css('white-space','nowrap')	:wikitext(((not WDlink_on and wdLink(string.gsub(raceID, '%s', '') .. "#P527")) or "")..	translate("headoftable",1,w_race))	if displaytypeofstage==true then tRow:tag('th') end	for v in itercolumns(columntable) do	if v.used == true then	if v.jersey == '' then v.jersey = "_" end	tRow:tag('th'):wikitext(v.name.."<br />"..v.jersey)	end	end	local style	--then fill the table	for ii, v in pairs(stageinfotable) do --one stage=one row	--stages link	tRow=tab:tag('tr')	local tCell=tRow:tag('td')	if ii==#stageinfotable then	tCell:attr('colspan','2'):cssText('font-weight:bold; border-top: 2px black solid;')	end	tCell:wikitext(v.sLink)	if displaytypeofstage == true then	tCell=tRow:tag('td')	if ii==#stageinfotable then --general row	tCell:cssText('font-weight:bold; border-top: 2px black solid;')	end	if v.sType then	tCell:wikitext(v.sType) --picture type of stage	end	end	--add winners	for y in itercolumns(columntable) do	if y.used==true and not (ii==#stageinfotable and columntable['Q20882747']==y) then --only display used QID	if type(y[ii]["leader"])=="string" and type(y[ii]["rowspan"])=="number" then --actually check nil but it is a table	style=""	if y[ii]["rowspan"]~=0 and (columntable['Q20882747']==y)==false then	if ii~=1 and ii~=#stageinfotable then style=style.." border-top:1px gray solid;" end	if y.bg_color then style=style.." background-color:"..y.bg_color..";" end	if ii==#stageinfotable then style=style.."font-weight:bold; border-top: 2px black solid;" end	tRow:tag('td'):attr('rowspan',tostring(y[ii]["rowspan"])):cssText(style):wikitext(y[ii]["leader"])	elseif (columntable['Q20882747']==y) then --no rowspan for stages	tRow:tag('td'):wikitext(y[ii]["leader"])	end	else	tCell=tRow:tag('td')	if ii~=#stageinfotable and v.somewinner==true then	tCell:wikitext(translate("listofstagesclassification",1,w_race)) --not attributed	elseif ii~=#stageinfotable then --empty	elseif v.somewinner==true then --general row	tCell:cssText('border-top: 2px black solid')	:wikitext(translate("listofstagesclassification",1,w_race)) --not attributed	else	tCell:cssText('border-top: 2px black solid') --empty	end	end	end	end	end	return tab end --M) Start list function p.startlist(frame)	local tempID, lf=get_and_checkID(frame)	local w_race=isWomenrace(tempID)	local s = {	header_function = "startlist",	header_1 = 1, -- translation 1 in function victories is printed in the upper part of the table header	header_2 = {2, 3,4,5},	item=tempID,	title="Start list",	data_sort_type={'unsortable', 'unsortable', 'unsortable'},	property ='P710',	no_roll_startlist=no_roll_startlist,	w_race=w_race,	lf=lf	}	local resultTable, tag = tableB(s)	return startlist_main(s, resultTable, tag) end function p.startlisttable(frame)	local tempID, lf=get_and_checkID(frame)	local w_race=isWomenrace(tempID)	local s = {	header_function = "startlisttable",	header_1 = 1, -- translation 1 in function victories is printed in the upper part of the table header	header_2 = {2, 3,4,5},-- translations 2, 3, 4, 5, 6 in function victories are printed in this order	item=tempID,	title="Start list", -- in the lower part of the table header. The second value 3 in {4, 3} tells where the icon will go.	no_country ={'fr'},	data_sort_type={'', '', ''},	property ='P710',	no_roll_startlist=no_roll_startlist,	w_race=w_race,	lf=lf	}	return startlisttable_main(s, tableA(s)) end local function startlist_sub(p710, timeOfRace, WDlink_on, istable,w_race)	--Return a table containing a row for the selected rider and their associated team, link, etc	local h = {}	local tBody = '' --row in our case	local riderID, riderTeamLink, riderTeamID, riderDossard, riderLink, riderRank	local q, gender, riderTeamCode, riderDNF, DSQ, catID, countryID, national_team_boolean	riderID = p710.mainsnak.datavalue.value.id	q= p710.qualifiers	riderLink= getRiderLink(riderID, timeOfRace)	if WDlink_on then riderLink=riderLink..wdLink(riderID) end	if q and q.P1618 and q.P1618[1].snaktype == 'value' then	riderDossard = q.P1618[1].datavalue.value or ''	else	riderDossard = ''	end	riderDNF='' riderRank = '' DSQ=''	if q and q.P1352 and q.P1352[1].snaktype == 'value' then -- P1352 is ranking	riderRank = tonumber(q.P1352[1].datavalue.value.amount)	--look for DSQ--	DSQ=isdisqualified(p710, q)	else	--look for DNF...	if q and q.P1534 and q.P1534[1].snaktype == 'value' then	local dnf=q.P1534[1].datavalue.value.id	if dnf=='Q1210380' then riderDNF =translate("startlist",6,w_race)--"HD","NP","DQ"	elseif dnf=='Q54881674' or dnf=='Q7113430' then riderDNF =translate("startlist",7,w_race)	elseif dnf=='Q1210382' then riderDNF =translate("startlist",8,w_race)	elseif dnf=='Q1229261' then riderDNF =translate("startlist",9,w_race)	else riderDNF=''	end	if q.P1545 and q.P1545[1].snaktype == 'value' then	local stageofdnf=q.P1545[1].datavalue.value	if stageofdnf and string.len(stageofdnf)>1 then	riderDNF='<small>'..riderDNF.."-"..stageofdnf..'</small>'	else	riderDNF=riderDNF.."-"..stageofdnf	end	end	end	end	h = {	jersey = {}, -- lots of jerseyID	value = {'', '', '', ''} -- points, time, time_gap, speed	}	if q and q.P2912 then -- P2912 is distinctive jersey	for _, v in pairs(q.P2912) do	if v.snaktype == 'value' then	table.insert(h.jersey, v.datavalue.value.id)	end	end	end	if wiki == 'es' or wiki == 'fr' or wiki == 'ast' then	--[[ These wikis need the gender to display the rank correct. Other wikis can skip this. ]]	gender = getGenderCode(riderID, 'n')	end	local countryID = getNationality(riderID, timeOfRace,q)	local uciCode=''	local jerseytemp=''	if countryID then	if wiki ~= "ar" then	uciCode=uciCodeCountry(countryID)	end	riderLink = flag(countryID, timeOfRace) ..' '.. riderLink	end	if h.jersey[1] then	jerseytemp=champtitle(h.jersey) -- champtitle manages also the jersey	end	riderTeamLink, riderTeamID, catID, countryID = getTeam(riderID, timeOfRace, q)	riderTeamID=seasonToTeamID(riderTeamID)	riderTeamCode= getTeamCode(riderID, timeOfRace, q)	--Custom display for national selection	if data.natTeamCats[catID] and countryID then	if riderTeamCode and wikibase.getSitelink(countryID) then --for the refugee case	riderTeamCode='[['..wikibase.getSitelink(countryID)..'|'..riderTeamCode..']]'	end	riderTeamLink=flag(countryID, timeOfRace)..' '..riderTeamLink	else --for non national selection display "ridername (FRA)""	riderLink =riderLink..uciCode	end	riderLink =riderLink..jerseytemp	local sortkey = riderDossard == "" and 0 or tonumber(riderDossard)	tBody = mw.html.create('tr'):cssText("line-height: 1.8em; padding: 5px;")	tBody:tag('td'):cssText("text-align:right;padding:0 0.5em"):wikitext(riderDossard)	tBody:tag('td'):cssText('text-align:'..textalign.. ';padding:0 0.5em;'..DSQ):wikitext(riderLink)	local td_css = "text-align:left;padding:0 0.5em"	if wiki == "ar" then td_css = "text-align:right;padding:0 0.5em" end	if istable then	tBody:tag('td'):cssText(td_css):wikitext(riderTeamLink or "")	end	tBody:tag('td'):cssText('text-align:'..textalign.. ';padding:0 0.5em;'..DSQ):wikitext(number(gender,riderRank,wiki)..riderDNF)	--table.insert(resultTable, )	return {sortkey=sortkey, riderTeamLink=riderTeamLink,riderTeamID=riderTeamID,riderTeamCode=riderTeamCode, body=tBody} end function startlist_main(s, resultTable, tag)	local ridertable, DStable, subtable = {}, {}, {}	local DSID, DSLink, DSteamID, DSteam	local WDlink_on = (wiki == "mk" or wiki == "ja" or wiki == "ru")	local timeOfRace=getTimeOfRace(s.item)	local w_race=isWomenrace(s.item)	for _,p286 in statements(s.item, 'P286') do--look for DS	DSID = p286.mainsnak.datavalue.value.id	DSLink= getRiderLink(DSID, timeOfRace)	q= p286.qualifiers	if q.P642 and q.P642[1].snaktype == 'value' then	DSteamID=q.P642[1].datavalue.value.id	DSteamID=seasonToTeamID(DSteamID)	end	table.insert(DStable, {DSLink=DSLink, DSteamID=DSteamID})	end	for _, p710 in statements(s.item, 'P710') do -- P710 is participants	table.insert(ridertable, startlist_sub(p710, timeOfRace, WDlink_on, false,w_race))	end	table.sort(ridertable, function(a, b) --sort by team and then by bib and then by team	if a['sortkey'] ~= b['sortkey'] then --sort by bib return a['sortkey'] < b['sortkey']	else	return (a['riderTeamCode'] or 'a') < (b['riderTeamCode'] or 'a') --order does not matter for nil	end end)	local thisTableRow, thisTeamTable, thisDS, insideTable, test	local tSubtitle, tTitle	if wiki == "ar" then	tSubtitle=mw.html.create('tr')	tSubtitle:tag('td'):attr('width','30px')	:css("align:right;text-align:right")	:wikitext(translate("startlist",2,w_race))	tSubtitle:tag('td'):attr('width','200px')	:css("align:right;text-align:right")	:wikitext(translate("startlist",3,w_race))	tSubtitle:tag('td'):attr('width','85px')	:css("align:right;text-align:right")	:wikitext(translate("startlist",4,w_race))	else	tSubtitle=mw.html.create('tr')	tSubtitle:tag('td'):attr('width','30px'):wikitext(translate("startlist",2,w_race))	tSubtitle:tag('td'):attr('width','250px'):wikitext(translate("startlist",3,w_race))	tSubtitle:tag('td'):attr('width','35px'):wikitext(translate("startlist",4,w_race))	end	--look for transition between teams	local numberofteam=0	local tDS	if #ridertable==0 then--empty table	return nil	else	for ii=1,#ridertable do	--new team	if not (ii~=1 and ridertable[ii].riderTeamID==ridertable[ii-1].riderTeamID) or ii==1 then --ridertable[ii].riderTeamID and	if thisDS and ii~=1 then	tDS=insideTable:tag('tr')	tDS:tag('td'):attr('colspan','3'):attr('align','center')	:wikitext(translate("startlist",5,w_race).." "..thisDS)	thisDS=nil	end	numberofteam=numberofteam+1	if math.fmod(numberofteam, 3 )==1 then	if ii~=1 then	tag:node(thisTableRow) --a row with 3 tables inside, save and re-init	end	thisTableRow=mw.html.create('tr')	end	thisTeamTable= thisTableRow:tag('td'):cssText("width:33%;"):attr('valign','top')	insideTable=thisTeamTable:tag('table') --reinit	:attr('cellpadding','4') --solid rgb(200,200,200)	:attr('background-color','rgb(255, 255, 255)')	:attr('margin', '0 0 0.5em 0')	:attr('padding','5px')	:attr('float','left')	:attr('text-align',textalign)	:attr('line-height','1.8em')	:attr('clear',floattable)	tTitle = mw.html.create('tr')	:css("background-color",backgroundColor)	:attr('align','center')	local tCell=tTitle:tag('th'):attr('colspan','3')	tCell:tag('big'):wikitext((ridertable[ii].riderTeamLink or translate("startlist",13,w_race)).."<br/>"..(ridertable[ii].riderTeamCode or "___"))	insideTable:node(tTitle)	insideTable:node(tSubtitle)	tDS=nil	--look for the DS of this team	for _,v in pairs(DStable) do	if v.DSteamID==ridertable[ii].riderTeamID then	if not thisDS then	thisDS=v.DSLink	else	thisDS=thisDS..", "..v.DSLink	end	end	end	end	--add the rider, also for old team	insideTable:node(ridertable[ii].body)	end	--last DS	if thisDS then	tDS=insideTable:tag('tr')	tDS:tag('td'):attr('colspan','3'):attr('align','center')	:wikitext(translate("startlist",5,w_race).." "..thisDS)	end	tag:node(thisTableRow)	return resultTable	end end local KeytoRiderRankingCode={	["women"]=	2,	['WWT']=	3,	['WWC']=	4,	["UWT"]=	5,	["europe"]=	6,	["asia"]=	7,	["oceania"]=8,	["america"]=9,	["africa"]=	10,	["WR"]= 11,	["WC"]=	12,	["UPT"]=	13, --WC is world calendar here	["UCImen"]=	14,	["WCmen"]=	15, --UCImen = UCI ranking 1984-2004, WC= World cup men	["Pernod"]=	16,	["Desgrange"]=17,	} function startlisttable_main(s, resultTable)	local t_Body = {}	local WDlink_on = (wiki == "mk" or wiki == "ja" or wiki == "ru")	local timeOfRace=getTimeOfRace(s.item)	for _, p710 in statements(s.item, 'P710') do -- P710 is participants	table.insert(t_Body, startlist_sub(p710, timeOfRace, WDlink_on, true))	end	return sortAndConcat(t_Body, resultTable) end -- N) Rider ranking local function checkminmaxyear(minmaxyear,thisyear)	if minmaxyear.minimum ==0 or thisyear<minmaxyear.minimum then	minmaxyear.minimum=thisyear	end	if minmaxyear.maximum==0 or thisyear>minmaxyear.maximum then	minmaxyear.maximum=thisyear	end return minmaxyear end function p.riderranking(frame)	local tempID, lf=get_and_checkID(frame)	local s = {	item = tempID,	lf=lf	}	return riderranking_main(s) end local function checkWorldTourTeam(itemID,year)	local thisdate='+'..tostring(year).."-07-01T00:00:00Z"	local catID	for _, s in statements(itemID, 'P54') do	p54 =checktime(s, s.qualifiers, thisdate) --present Team	if p54 then	teamId= p54.mainsnak.datavalue.value.id	_, catID=getTeamLinkCat(teamId, thisdate)	if catID=="Q6154783" or catID=="Q20638319" then	return true	end	end	end	return false end local function ranking_legend()	local UCIlink, legend	if wiki=="fr" then	UCIlink="https://www.uci.org/fr/route/classements" --see also https://dataride.uci.org/iframe/Rankings/10/	legend= " Légende : nc = non classé"	else	UCIlink="https://www.uci.org/road/rankings"	legend=""	end	return UCIlink, legend end local function riderranking_sub(w_race)	local listofcalendar=data.listofmencalendar	if w_race then	listofcalendar=data.listofwomencalendar	end	local UCIQtoYear={}	for k,v in pairs(data.UCIYearToQ) do	UCIQtoYear[k]={}	for kk, vv in pairs(v) do	UCIQtoYear[k][vv]=kk --calendar/Q = year	end	end	return listofcalendar, UCIQtoYear end function riderranking_main(s)	local lf=s.lf	local thisCompetition, rank, thisyear, sitelink, q, gender, DSQ local calendarlistpresent={}	local gender=getGenderCode(s.item, 'm')	local w_race=false	if gender=="f" then w_race=true end	local minmaxyear= {	minimum = 0, maximum = 0 }	local listofcalendar, UCIQtoYear=riderranking_sub(w_race)	local resultTable={}	for ii=1900,2100,1 do	resultTable[tostring(ii)]={}	for _, calendar in pairs(listofcalendar) do	resultTable[tostring(ii)][calendar]={}	end	end	--build the table	for _, p1344 in statements(s.item, 'P1344') do	thisCompetition = p1344.mainsnak.datavalue.value.id	for _, calendar in pairs(listofcalendar) do	if UCIQtoYear[calendar][thisCompetition] then	thisyear=UCIQtoYear[calendar][thisCompetition]	minmaxyear=checkminmaxyear(minmaxyear,thisyear)	q = p1344.qualifiers	if q and q.P1352 and q.P1352[1].snaktype == 'value' then --rank	resultTable[thisyear][calendar]["rank"] = tostring(tonumber(q.P1352[1].datavalue.value.amount)) --without the tonumber, there can be +1 instead of 1	resultTable[thisyear][calendar]["DSQ"] = isdisqualified(p1344, q) or ""	calendarlistpresent[calendar]=true	sitelink=mw.wikibase.getSitelink(thisCompetition)	resultTable[thisyear][calendar]["sitelink"]=sitelink	end	end	end	end	--display result	if minmaxyear.minimum~=0 then	local finalTable =mw.html.create('table'):attr('cellspacing','0')	:attr("align","center"):cssText("text-align:center; border: 1px solid #999; line-height: 1.8em;")	local wdLin = wdLink(string.gsub(s.item, '%s', '') .. "#P1344")	local tRow= finalTable:tag('tr'):tag('th')	:css("background-color",backgroundColor)	:wikitext(wdLin..' '..translate("riderranking",1,w_race)) --year	for ii=minmaxyear.minimum,minmaxyear.maximum,1 do	tRow:tag('th'):attr("width","50px")	:css('background-color',backgroundColor)	:css("text-align","center")	:css("padding","1px 1px")	:wikitext(tostring(ii))	end	for _, calendar in pairs(listofcalendar) do	if calendarlistpresent[calendar] then	sitelink=mw.wikibase.getSitelink(data.UCImaster[calendar])	local tRow=finalTable:tag('tr')	local tCell = tRow:tag('th'):cssText("text-align:" .. textalign .. ";") -- left	local calendar_name=translate("riderranking",data.KeytoRiderRankingCode[calendar],w_race)	if sitelink then	tCell:wikitext('[['..sitelink..'|'..calendar_name..']]')	else	tCell:wikitext(calendar_name)	end	for yy=minmaxyear.minimum,minmaxyear.maximum,1 do	thisyear=tostring(yy)	color="white"	local impossible=false	--we need to check the impossibility here, as it is impossible even if nothing is in P1344	if data.continental_calendar[calendar] then	--between 2005 and 2015 WorldTour team member cannot score by continental calendars.	if tonumber(thisyear)>=2005 and tonumber(thisyear)<=2015 then	if checkWorldTourTeam(s.item,thisyear) then	impossible=true	end	--between 2016 and 2018 no contradiction	--after 2019, it depends on the nationality	elseif tonumber(thisyear)>=2019 then	local countryID=getNationality(s.item,'+'..tostring(year).."-07-01T00:00:00Z")	if data.continental_calendar[calendar] and not data.continental_calendar[calendar][countryID] then	impossible=true	end	end	elseif calendar=="UWT" then	--non member of World Tour team cannot point in the WT	if tonumber(thisyear)>=2005 and tonumber(thisyear)<=2015 then	if not checkWorldTourTeam(s.item,thisyear) then	impossible=true	end	end	end	if resultTable[	thisyear][calendar]["rank"] or impossible then	if impossible then	tRow:tag('td'):css('background-color',backgroundColorLight)	else	if resultTable[thisyear][calendar]["rank"]=="1" then	color="gold"	elseif (2<=tonumber(resultTable[thisyear][calendar]["rank"])) and (tonumber(resultTable[thisyear][calendar]["rank"])<=3) then	color="YellowGreen"	elseif (4<=tonumber(resultTable[thisyear][calendar]["rank"])) and (tonumber(resultTable[thisyear][calendar]["rank"])<=10) then	color="silver"	end	tCell=tRow:tag('td'):attr("bgcolor",color):cssText(resultTable[thisyear][calendar]["DSQ"])	local rank=tonumber(resultTable[thisyear][calendar]["rank"])	rank=number(gender,rank,wiki)	if resultTable[thisyear][calendar]["sitelink"] then	tCell:wikitext('[['..resultTable[thisyear][calendar]["sitelink"]..'|'..rank..']]')	else	tCell:wikitext(rank)	end	end	--this ranking exist for this year, but the rider is not ranked	elseif yy>=data.UCIcalendarstartend[calendar].b and	(data.UCIcalendarstartend[calendar].e==0 or yy<=data.UCIcalendarstartend[calendar].e) then	if wiki=="fr" then	tRow:tag('td'):wikitext(' nc ')	else	tRow:tag('td'):wikitext(' - ')	end	--this ranking does not exist for this year	else	tRow:tag('td'):css('background-color',backgroundColorLight)	end	end	end	end	local tableyearsize=minmaxyear.maximum-minmaxyear.minimum+2	local UCIlink, legend=ranking_legend()	finalTable:tag('tr'):tag('td'):addClass("navigation-only")	:attr('colspan',tostring(tableyearsize))	:cssText("border-top: 2px "..backgroundColor.." solid; font-size: 80%;")	tCell=finalTable:tag('tr'):tag('td'):attr('colspan',tostring(tableyearsize))	:tag('small')	tCell:tag('span'):css("float","left")	:wikitext(legend)	tCell:tag('span'):css("float","right")	:wikitext(translate("race_reference", 1,w_race).."["..UCIlink..' UCI]')	return finalTable	end end function p.teamranking(frame)	local tempID, lf=get_and_checkID(frame)	local calendar_key=get_arg(2,frame)	if not calendar_key or calendar_key == "" then return "" end	local w_race=false	if calendar_key=="women" or calendar_key=="WWT" or calendar_key=="WWC" then	w_race=true	end	local s = {	header_function = "riderranking", header_1 = data.KeytoRiderRankingCode[calendar_key] or 1,	header_2 = {1, 18, 19},	property="P527",	data_sort_type = {'unsortable', 'unsortable', 'unsortable'},	item = tempID,	calendar_key=calendar_key,	lf=lf,	w_race=w_race	}	return teamranking_main(s,tableA(s)) end local function get_teamranking(seasonID, w_race, UCIQtoYear,listofcalendar, tTable,gender)	--fill resultTable	local done, thisyear, q, done, rider, riderLink, countryID, rank, thisdate, teamrank	for _, p1344 in statements(seasonID, 'P1344') do	thisCompetition = p1344.mainsnak.datavalue.value.id	for _, calendar in pairs(listofcalendar) do	if UCIQtoYear[calendar][thisCompetition] then	thisyear=UCIQtoYear[calendar][thisCompetition]	thisdate='+'..tostring(thisyear).."-07-01T00:00:00Z"	rank=nil	if tTable[calendar] then	tTable[calendar][thisyear]={}	else	error("tTable badly initialized")	end	q = p1344.qualifiers	done=false	--get team rank	local suffix=""	if calendar== "UCImen" then --case of GSI (Q20653563), GSII (Q20653564) and GSIII (Q20653566)	if q and q.P642 and q.P642[1].snaktype == 'value' then	if q.P642[1].datavalue.value.id=="Q20653564" then	suffix=" (GSII)"	elseif q.P642[1].datavalue.value.id=="Q20653566" then	suffix=" (GSIII)"	end	end	end	if q and q.P1352 and q.P1352[1].snaktype == 'value' then --rank	teamrank= tonumber(q.P1352[1].datavalue.value.amount)	tTable[calendar][thisyear]["teamrank"]=number(gender,teamrank,wiki)..suffix	done=true	end	--get best rider rank	if q and q.P1545 and q.P1545[1].snaktype == 'value' then --participant	rank = tostring(tonumber(q.P1545[1].datavalue.value))	done=true	end	--get best rider	if q and q.P710 and q.P710[1].snaktype == 'value' then --participant	rider = q.P710[1].datavalue.value.id	riderLink = getRiderLink(rider, thisdate)	countryID = getNationality(rider, thisdate)	if countryID then	riderLink = flag(countryID, thisdate) .. ' ' .. riderLink	end	if rank then	rank=number(gender,tonumber(rank),wiki)	riderLink=riderLink.." ("..rank..")"	end	tTable[calendar][thisyear]["rider"]=riderLink	done=true	end	sitelink=mw.wikibase.getSitelink(thisCompetition)	tTable[calendar][thisyear]["sitelink"]=sitelink	end	end	end	return tTable end function teamranking_main(s, resultTable)	local lf=s.lf	local t_Body = {}	local gender="m"	if s.w_race then gender="f" end	--init, reverse UCIQtoYear	local UCIQtoYear={}	UCIQtoYear[s.calendar_key]={}	if data.UCIYearToQ[s.calendar_key] then	local v=data.UCIYearToQ[s.calendar_key]	for kk, vv in pairs(v) do	UCIQtoYear[s.calendar_key][vv]=kk	end	end	local tTable={}	tTable[s.calendar_key]={}	for ii, p527 in statements(s.item, "P527") do	tTable=get_teamranking(p527.mainsnak.datavalue.value.id, w_race, UCIQtoYear,{s.calendar_key}, tTable,gender)	end	local t=tTable[s.calendar_key]	if t then	for thisyear, v in pairs(t) do	local tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 0.5em;")	local tCell=tRow:tag('td'):css("text-align",textalign)	if v["sitelink"] then	tCell:wikitext('[['..v["sitelink"]..'|'..thisyear..']]')	else	tCell:wikitext(thisyear)	end	if v["teamrank"] then	tRow:tag('td'):wikitext(v["teamrank"]):css("text-align","center")	else	tRow:tag('td'):wikitext(" - "):css("text-align","center")	end	if v["rider"] then	tRow:tag('td'):wikitext(v["rider"])	else	tRow:tag('td'):wikitext(" - ")	end	table.insert(t_Body, {sortkey=thisyear, body=tRow})	end	end	resultTable=sortAndConcat(t_Body, resultTable)	local UCIlink, _=ranking_legend()	local tRow=resultTable:tag('tr')	tRow:tag('td'):addClass("navigation-only")	:attr('colspan',tostring(3))	:cssText("border-top: 2px "..backgroundColor.." solid; font-size: 80%;")	tRow=resultTable:tag('tr')	local tCell=tRow:tag('td'):attr('colspan',tostring(3)):tag('small')	tCell:tag('span'):css("float","right")	:wikitext(translate("race_reference", 1,w_race).."["..UCIlink..' UCI]')	return resultTable end local function toboolean(str)	if str=="true" then	return true	elseif str=="false" then	return false	else	return str	end end --=== O) Rider infobox local function convertDate(date1, beginOrEnd, initialYear, finalYear)	if not date1 then	if beginOrEnd==0 then --begin	y1=tostring(initialYear)	m1="01"	d1="01"	else	y1=tostring(finalYear)	m1="12"	d1="31"	end	else	_, _, y1,m1,d1 = string.find(date1, "(%d+)-(%d+)-(%d+)")	if m1 ==nil or m1=="00" then	if beginOrEnd==0 then --begin	m1="01"	d1="01"	else--end	m1="12"	d1="31"	end	end	end	return '+'..y1.."-"..m1.."-"..d1.."T00:00:00Z" end local function listofTeam(itemID, initialYear, finalYear, PID)	--first we have to read P54 of the rider	--alternative P6087 for managed team	local riderteam={}	local stagiaire	--initially initialYear is the birthyear of the rider	--end year is now +10 years, or the death date	--let's reduce the range (note: it may be slightly over-engineered, maybe it can be deleted and just assume 10 years in the future is sufficient)	local today=os.date("*t")	local t1=tonumber(today['year'])	local t2=math.min(finalYear, tonumber(today['year']))	local t_initialYear=t1	local t_finalYear=t2	for ii, p54 in statements(itemID, PID) do --itemID loaded in presentTeam	local q = p54.qualifiers	if q then	local sTime, eTime=getStartEndfromQuali(q)	--min/max	if sTime then	y=tonumber(string.sub(sTime, 2, 5))	if y < t_initialYear then	t_initialYear=y	end	if y>t_finalYear then	t_finalYear=y	end	end	if eTime then	y=tonumber(string.sub(eTime, 2, 5))	if y < t_initialYear then	t_initialYear=y	end	if y>t_finalYear then	t_finalYear=y	end	end	end	end	if t_initialYear~=t1 then initialYear=t_initialYear end	if t_finalYear~=t2 then finalYear=t_finalYear end	for ii, p54 in statements(itemID, PID) do --itemID loaded in presentTeam	if p54 then	teamId=p54.mainsnak.datavalue.value.id	else	teamId=nil	end	local q = p54.qualifiers	if q then	local sTime, eTime=getStartEndfromQuali(q)	sTime=convertDate(sTime, 0, initialYear, finalYear)	eTime=convertDate(eTime, 1, initialYear, finalYear)	if q.P39 and q.P39[1] and	q.P39[1].snaktype == 'value' then	stagiaire = q.P39[1].datavalue.value	else	stagiaire = nil	end	dis=checkDis(q)	table.insert(riderteam,{teamId=teamId, startTime=sTime, endTime=eTime, stagiaire=stagiaire, dis=dis})	end	end	return riderteam, initialYear, finalYear end --format the date for display of the team local function riderFormatDate(thisDate)	if thisDate=='' then	return ''	else	local month=math.ceil(thisDate['month']/2)	if month==12 or month==1 then	return thisDate['year']	else	local date1='+'..thisDate['year'].."-"..month.."-".."01".."T00:00:00Z"	--	local newobj = Complexedate.splitDate(date1)	if month == 0 or month==nil then	return thisDate['year']	else	return month..'.'..thisDate['year']	end	end	end end local function getTeamInfo(teamId,mm,yy,dd,managedTeam)	--get the nature and name of the team for the date mm,yy	mm=tostring(mm)	yy=tostring(yy)	dd=tostring(dd)	if mw.ustring.len(mm)==1 then mm='0'..mm end	if mw.ustring.len(dd)==1 then dd='0'..dd end	thistime='+'..yy.."-"..mm.."-"..dd.."T00:00:00Z"	local sitelink, teamNature=getTeamLinkCat(teamId, thistime, false)	local cat, boolean	if managedTeam then cat=data.nationalcat	else cat=data.amateurcat	end	if cat[teamNature] then --club	boolean=true--amateur / national selection	else	boolean=false--pro / not national selection	end	return boolean, sitelink end --for managed team, the table should be splat, as we can be national trainer and team trainer at the same time local function analyzeManagedTeam(teamRider, initialYear,finalYear)	local natTeamOut, managedTeamOut={},{}	local dis="road"	local managedTeam=true	for i=1,24 do --init table	natTeamOut[i]={}	managedTeamOut[i]={}	for j=initialYear,finalYear do	natTeamOut[i][j]={ amateurTeam, link, stagiaire=nil}	managedTeamOut[i][j]={amateurTeam,link, stagiaire=nil}	end	end	local teamId, natTeam, sitelink	local sYear, sMonth,eYear, eMonth, sDay, eDay	if teamRider==nil then return nil end	for _, v in pairs(teamRider) do --for each team where was the rider	if v['dis']==dis then	--exception managed at the reading	_, _, sYear,sMonth,sDay = string.find(v['startTime'], "(%d+)-(%d+)-(%d+)")	_, _, eYear,eMonth,eDay = string.find(v['endTime'], "(%d+)-(%d+)-(%d+)")	sYear=tonumber(sYear)	sMonth=tonumber(sMonth)	eYear=tonumber(eYear)	eMonth=tonumber(eMonth)	if sYear<=eYear then --test of congruence	for yy=sYear,eYear do	for mm=1,12 do	local mmindex=(mm-1)*2+1	--avoid reading info where the team is not the one of the rider	getinfo=true	if (yy==sYear and mm<sMonth) or (yy==eYear and mm>eMonth) then	getinfo=false	end	if getinfo then	if (yy==sYear) and (mm==sMonth) and (sDay~='01' and sDay~='00' and sDay~=nil)then	natTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,sDay, managedTeam)	if natTeam then	natTeamOut[mmindex+1][yy]['amateurTeam']=true	natTeamOut[mmindex+1][yy]['link']=sitelink	else	managedTeamOut[mmindex+1][yy]['amateurTeam']=false	managedTeamOut[mmindex+1][yy]['link']=sitelink	end	else	natTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'01', managedTeam)	if natTeam then	natTeamOut[mmindex][yy]['amateurTeam']=true	natTeamOut[mmindex][yy]['link']=sitelink	if natTeamOut[mmindex+1][yy]['amateurTeam']==nil or v['stagiaire'] then --to avoid problem with team name change during the month	natTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'28',managedTeam)	natTeamOut[mmindex+1][yy]['amateurTeam']=true --a nat team stays a nat team	natTeamOut[mmindex+1][yy]['link']=sitelink	end	else	managedTeamOut[mmindex][yy]['amateurTeam']=false	managedTeamOut[mmindex][yy]['link']=sitelink	if managedTeamOut[mmindex+1][yy]['amateurTeam']==nil or v['stagiaire'] then --to avoid problem with team name change during the month	natTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'28',managedTeam)	managedTeamOut[mmindex+1][yy]['amateurTeam']=false --a nat team stays a nat team	managedTeamOut[mmindex+1][yy]['link']=sitelink	end	end	end	end	end	end	end	end	end	return natTeamOut, managedTeamOut --a filled matrix with the link and nature of the teams end local function analyzeTeam(teamRider, initialYear,finalYear, dis)	local teamOut={}	local managedTeam=false	for i=1,24 do --init table	teamOut[i]={}	for j=initialYear,finalYear do	teamOut[i][j]={ amateurTeam, link, stagiaire}	end	end	local teamId, amateurTeam, sitelink	local sYear, sMonth,eYear, eMonth, sDay, eDay	if teamRider==nil then return nil end	for _, v in pairs(teamRider) do --for each team where was the rider	if v['dis']==dis then	--exception managed at the reading	_, _, sYear,sMonth,sDay = string.find(v['startTime'], "(%d+)-(%d+)-(%d+)")	_, _, eYear,eMonth,eDay = string.find(v['endTime'], "(%d+)-(%d+)-(%d+)")	sYear=tonumber(sYear)	sMonth=tonumber(sMonth)	eYear=tonumber(eYear)	eMonth=tonumber(eMonth)	if sYear<=eYear then --test of congruence	for yy=sYear,eYear do	for mm=1,12 do	local mmindex=(mm-1)*2+1	--avoid reading info where the team is not the one of the rider	getinfo=true	if (yy==sYear and mm<sMonth) or (yy==eYear and mm>eMonth) then	getinfo=false	end	if getinfo then	if (yy==sYear) and (mm==sMonth) and (sDay~='01' and sDay~='00' and sDay~=nil)then	amateurTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,sDay, managedTeam)	teamOut[mmindex+1][yy]['amateurTeam']=amateurTeam	teamOut[mmindex+1][yy]['link']=sitelink	teamOut[mmindex+1][yy]['stagiaire']=v['stagiaire']	else	amateurTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'01', managedTeam)	teamOut[mmindex][yy]['amateurTeam']=amateurTeam	teamOut[mmindex][yy]['link']=sitelink	teamOut[mmindex][yy]['stagiaire']=v['stagiaire']	if teamOut[mmindex+1][yy]['amateurTeam']==nil or v['stagiaire'] then --to avoid problem with team name change during the month	amateurTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'28',managedTeam)	teamOut[mmindex+1][yy]['amateurTeam']=amateurTeam	teamOut[mmindex+1][yy]['link']=sitelink	teamOut[mmindex+1][yy]['stagiaire']=v['stagiaire']	end	end	end	end	end	end	end	end	return teamOut --a filled matrix with the link and nature of the teams end local function insertTeam(teamAmateur,teamPro,sDate,eDate,v)	local sDate2=riderFormatDate(sDate)	local eDate2=riderFormatDate(eDate)	local ins = {link=v['link'], sDate=sDate2,eDate=eDate2,stagiaire=v['stagiaire']}	if v['amateurTeam'] then	table.insert(teamAmateur,ins)	else	table.insert(teamPro,ins)	end	return teamAmateur,teamPro end local function synthetizeTable(analyzedTeam, initialYear,finalYear)	local teamPro, teamAmateur, tempTeam, tempsDate, tempeDate={}, {},{},{},{}	local empty=true	local active=false --bring together successive month with identical content	for yy=initialYear,finalYear do	for mm=1,24 do	local v=analyzedTeam[mm][yy]	if v['amateurTeam']~=nil then	if empty then --first line	active=true	empty=false	tempTeam=v	tempsDate['month']=mm	tempsDate['year']=yy	else	if tempTeam['amateurTeam']==v['amateurTeam'] and tempTeam['link']==v['link']	and tempTeam['stagiaire']==v['stagiaire'] then --no change	if yy==finalYear and mm==24 then--present team	teamAmateur,teamPro=insertTeam(teamAmateur,teamPro,tempsDate,'',tempTeam)	end	else--change	--save the old	if active then --if active false then it was already saved	if mm==1 then	tempeDate['year']=yy-1	tempeDate['month']=24	else	tempeDate['year']=yy	tempeDate['month']=mm-1	end	teamAmateur,teamPro=insertTeam(teamAmateur,teamPro,tempsDate,tempeDate,tempTeam)	end	--save the new	active=true	tempTeam=v	tempsDate['month']=mm	tempsDate['year']=yy	end --change	end--first line	elseif active then --there was a team and now there is an empty period	active=false	--save the old	if mm==1 then	tempeDate['year']=yy-1	tempeDate['month']=24	else	tempeDate['year']=yy	tempeDate['month']=mm-1	end	teamAmateur,teamPro=insertTeam(teamAmateur,teamPro,tempsDate,tempeDate,tempTeam)	tempTeam['link']=nil --avoid problem if the rider comes back in the same team	end	end-- for mm	end--for yy	return teamAmateur,teamPro end local function listOfManagedTeamTable(itemID, initialYear,finalYear)	local managedTeamRider, initialYear, finalYear = listofTeam(itemID, initialYear,finalYear,'P6087')--raw list of team	if not managedTeamRider then	return nil, nil	end	local natTeamOut, managedTeamOut=analyzeManagedTeam(managedTeamRider, initialYear,finalYear) --table with links and nature of teams	local nationalTeam,_=synthetizeTable(natTeamOut, initialYear,finalYear)	local _,managedTeam=synthetizeTable(managedTeamOut, initialYear,finalYear)	return nationalTeam,managedTeam end local function listOfTeamTable(itemID, initialYear,finalYear)	local teamRider, initialYear, finalYear = listofTeam(itemID, initialYear,finalYear,'P54')--raw list of team	if not teamRider then	return nil, nil	end	local analyzedTeam1=analyzeTeam(teamRider, initialYear,finalYear, "road") --table with links and nature of teams	local teamAmateur,teamPro=synthetizeTable(analyzedTeam1, initialYear,finalYear) --table formated, global	local analyzedTeam2=analyzeTeam(teamRider, initialYear,finalYear, "mountainBike") local _, teamMountainBike=synthetizeTable(analyzedTeam2, initialYear,finalYear) local analyzedTeam3=analyzeTeam(teamRider, initialYear,finalYear, "cycloCross")	local _, teamCycloCross=synthetizeTable(analyzedTeam3, initialYear,finalYear)	local analyzedTeam4=analyzeTeam(teamRider, initialYear,finalYear, "track")	local _, teamTrack=synthetizeTable(analyzedTeam4, initialYear,finalYear)	return teamAmateur,teamPro, teamMountainBike, teamCycloCross, teamTrack end local function getBirthDeathDate(entityID, display_age)	local birthDate=firstValue(entityID, 'P569', 'time')	local deathDate=firstValue(entityID, 'P570', 'time')	local temp2, temp3, birth, death, initialYear, finalYear, age	local gender=getGenderCode(entityID, 'm')	local w_race=false	if gender=="f" then w_race=true end	if birthDate then	local birthDateFormatted= funcDate(birthDate, 'long')	age, initialYear, finalYear=calculateAge(birthDate)	local birthPlace = firstValue(entityID, 'P19', 'id')	local birthPlaceLink=''	if birthPlace then birthPlaceLink=getPlaceLink(birthPlace, birthDate) end local plural, gen_singular, gen_plural = plural(age) local ans if gen_singular then	ans=translate("riderinfobox",48,w_race) elseif gen_plural then	ans=translate("riderinfobox",49,w_race) else	ans=translate("riderinfobox",50,w_race) end	if not deathDate and display_age~=false then	temp2=' ('..tostring(age)..' '..ans..')<br/>'	else	temp2='<br/>'	end	birth=birthDateFormatted..temp2..birthPlaceLink	else birth=nil	end	if deathDate then	local deathDateFormatted= funcDate(deathDate, 'long')	local deathPlace= firstValue(entityID, 'P20', 'id')	local deathPlaceLink=''	if deathPlace then deathPlaceLink=getPlaceLink(deathPlace, deathDate) end	if birthDate then local age=calculateAge(birthDate, deathDate) local plural, gen_singular, gen_plural = plural(age) local ans if gen_singular then	ans=translate("riderinfobox",48,w_race) elseif gen_plural then	ans=translate("riderinfobox",49,w_race) else	ans=translate("riderinfobox",50,w_race) end if display_age==false then	temp2='<br/>' else	temp2=' ('..tostring(age)..' '..ans..')<br/>'	end	else	temp2='<br/>'	end	death=deathDateFormatted..temp2..deathPlaceLink	else death=nil	end	return birth, death, initialYear, finalYear end local function presentTeam(itemID)	local tToday=os.date("*t")	if mw.ustring.len(tToday["month"])==1 then tToday["month"]='0'..tToday["month"] end	if mw.ustring.len(tToday["day"])==1 then tToday["day"]='0'..tToday["day"] end	local today='+'..tToday["year"].."-"..tToday["month"].."-"..tToday["day"].."T00:00:00Z"	local plural=false local teamId, result, teamLink, teamLinkRoad, row	for _, s in statements(itemID, 'P54') do	p54 =checktime(s, s.qualifiers, today) --present Team	if p54 then	teamId= p54.mainsnak.datavalue.value.id	teamLink=getTeamLinkCat(teamId, today) dis=checkDis(p54.qualifiers) row=nil if dis=='road' then	teamLinkRoad=teamLink elseif dis=='mountainBike' then	row=teamLink..' ('..translate("riderinfobox",56,w_race)..')' elseif dis=='cycloCross' then	row=teamLink..' ('..translate("riderinfobox",57,w_race)..')' else	row=teamLink..' ('..translate("riderinfobox",58,w_race)..')' end if row then if not result then	result = row else	result= result..'<br/>'..row	plural = true end end	end	end	if teamLinkRoad and result then --put road first	result = teamLinkRoad..' (route)<br/>'..result	plural= true	elseif teamLinkRoad then	result = teamLinkRoad	end	return result, plural end local function getSomeNames(details,entityID, PID, index, display_language)	local rows={}	if not details[index].content then	local listOfNames=getFormerNames(entityID, PID)	if listOfNames then	for _, v in pairs(listOfNames) do	rows[#rows + 1]=v[3]	if v[2] and v[2]~='' then	rows[#rows]=rows[#rows]..' <small>('..v[2]..')</small>'	end	if display_language then	rows[#rows]=rows[#rows]..' <b><small>('..v[4]..')</small></b>'	end	end	if #rows>0 then	details[index].content = table.concat(rows, '<br/>')	end	end	end end --for wikidata input local function teamTable(tab, teamAmateur, title_singular, title_plural)	if teamAmateur and #teamAmateur>0 then	if #teamAmateur==1 then	tab:node(addATitle(title_singular))	else	tab:node(addATitle(title_plural))	end	for _, v in pairs(teamAmateur) do	local nametemp=v['link']	if v['sDate']==v['eDate'] then	periodtemp=v['sDate']	else	periodtemp=v['sDate']..'-'..v['eDate']	end	if v['stagiaire'] then	local stagiaire = string.gsub(getLabelFallback('Q2328847',lang_priority), "%b()", "")	nametemp=nametemp..' ('..stagiaire..')'	end	tab:node(addARow(periodtemp or '',nametemp)) --period, name	end	end end --for local data local function localTeamTable(tab, names, periods, title_singular, title_plural)	if names then	names = mw.text.split(names, '<br />')	periods = mw.text.split(periods or '', '<br />')	if #names==1 then	tab:node(addATitle(title_singular))	else	tab:node(addATitle(title_plural))	end	for i, name in pairs(names) do	tab:node(addARow(periods[i] or '', name))	end	end end function p.riderinfobox(frame)	local WDlink_on = (wiki == "mk" or wiki == "ja")	local entityID, lf = get_and_checkID(frame)	local gender=getGenderCode(entityID, 'm')	local w_race=false	if gender=="f" then w_race=true end	local details = {	{ name = translate("riderinfobox",1,w_race), name_plural =translate("riderinfobox",2,w_race)}, -- birth name	{ name = translate("riderinfobox",3,w_race), name_plural =translate("riderinfobox",4,w_race)}, -- nick name	{ name = translate("riderinfobox",5,w_race), name_plural =translate("riderinfobox",6,w_race)}, -- official name	{ name = translate("riderinfobox",7,w_race), name_plural =translate("riderinfobox",8,w_race)}, -- official name	{ name = translate("riderinfobox",9,w_race) }, -- birth translate("riderinfobox",9)	{ name = translate("riderinfobox",10,w_race)}, -- death	{ name = translate("riderinfobox",11,w_race), name_plural =translate("riderinfobox",12,w_race)}, -- country	{ name = translate("riderinfobox",13,w_race), name_plural =translate("riderinfobox",14,w_race)}, -- present team	{ name = translate("riderinfobox",15,w_race), name_plural =translate("riderinfobox",16,w_race)}, -- speciality	{ name = translate("riderinfobox",17,w_race) }, -- lateralisation	{ name = translate("riderinfobox",18,w_race) }, -- blood group	{ name = translate("riderinfobox",19,w_race) }, -- height	{ name = translate("riderinfobox",20,w_race) }, -- weight	{ name = translate("riderinfobox",21,w_race), name_plural =translate("riderinfobox",22,w_race)}, -- awards	}	local teams = {	{ name = translate("riderinfobox",23,w_race), name_plural =translate("riderinfobox",24,w_race)}, -- directed teams	{ name = translate("riderinfobox",25,w_race)}, -- directed years	{ name = translate("riderinfobox",26,w_race), name_plural =translate("riderinfobox",27,w_race)}, -- amateur names	{ name = translate("riderinfobox",28,w_race)}, -- amateur periods	{ name = translate("riderinfobox",29,w_race), name_plural =translate("riderinfobox",30,w_race)}, -- nonUCI names	{ name = translate("riderinfobox",31,w_race)}, -- nonUCI periods	{ name = translate("riderinfobox",32,w_race), name_plural =translate("riderinfobox",33,w_race)}, -- pro names	{ name = translate("riderinfobox",34,w_race)}, -- pro periods	{ name = translate("riderinfobox",35,w_race), name_plural =translate("riderinfobox",36,w_race)}, -- UCI names	{ name = translate("riderinfobox",37,w_race)}, -- UCI periods	{ name = translate("riderinfobox",52,w_race), name_plural =translate("riderinfobox",53,w_race)}, -- national selections	{ name = translate("riderinfobox",54,w_race)}, -- national selection years	} --separated to have a title	local subtitle = {	{ name = translate("riderinfobox",51,w_race)}, -- insertion of a sub-title	} --separated to have a title	local victories = {	{ name = translate("riderinfobox",38,w_race)}, -- main victories	}	--separated to have a title	local medals = {	{ name = translate("riderinfobox",47,w_race)}, -- main victories	}	local others = get_others_dic()	local name = getLabelFallback(entityID) or ''	local display_birthnameastitle=false	for _, value in pairs(display_birthnameastitle_in_riderinfobox) do -- get data if country should be printed in this wiki	if value == wiki then display_birthnameastitle=true end	end	getLocalContent(subtitle, lf.args)	if not subtitle[1].content and display_birthnameastitle then	local p1477 = mw.wikibase.getBestStatements(entityID, "P1477")	if p1477[1] and p1477[1].mainsnak.snaktype == 'value' then	subtitle[1].content = p1477[1].mainsnak.datavalue.value.text..' <b><small>('..	p1477[1].mainsnak.datavalue.value.language..')</small></b>'	end	if not subtitle[1].content then local p1559 = mw.wikibase.getBestStatements(entityID, "P1559") -- P580 is start time	if p1559[1] and p1559[1].mainsnak.snaktype == 'value' then	subtitle[1].content = p1559[1].mainsnak.datavalue.value.text..' <b><small>('.. p1559[1].mainsnak.datavalue.value.language..')</small></b>'	end	end	end	infoGetOthers(others, entityID)	getLocalContent(details, lf.args)	getLocalContent(teams, lf.args)	getLocalContent(others, lf.args) getLocalContent(victories, lf.args) getLocalContent(medals, lf.args)	local listOfBirthNames, listOfNickNames, listOfOfficialNames, listOfShortNames	local icon = ' [[File:Cycling (road) pictogram.svg|35px]]'	local display_language=false	for _, value in pairs(display_language_in_riderinfobox) do -- get data if country should be printed in this wiki	if value == wiki then display_language=true end	end	local display_age=true	for _, value in pairs(display_noage_in_riderinfobox) do -- get data if country should be printed in this wiki	if value == wiki then display_age=false end	end	local display_nickname=true	for _, value in pairs(display_nonickname_in_riderinfobox) do -- get data if country should be printed in this wiki	if value == wiki then display_nickname=false end	end	local display_cm=false	for _, value in pairs(display_cm_in_riderinfobox) do -- get data if country should be printed in this wiki	if value == wiki then display_cm=true end	end --	getSomeNames(details, entityID, 'P1477', 1, display_language) --birthname	--less prio than P1477	if display_nickname then	getSomeNames(details, entityID, 'P1559', 1, display_language) --birthname, bis	getSomeNames(details, entityID, 'P1449', 2, display_language) --nick name	end	getSomeNames(details, entityID, 'P1448', 3, display_language) --official name	if display_nickname then	getSomeNames(details, entityID, 'P1813', 4, display_language) --short name	end	local birth, death, initialYear, finalYear=getBirthDeathDate(entityID, display_age)	if not details[5].content then	details[5].content=birth	end	if not details[6].content then	details[6].content= death	end	local display_flag=false	for _, value in pairs(display_flag_in_riderinfobox) do -- get data if country should be printed in this wiki	if value == wiki then display_flag=true end	end	listWPlinkChrono(details, 7, entityID, {'P1532','P27'}, 'country', initialYear, display_flag)	if not details[8].content then	local plural	details[8].content, plural=presentTeam(entityID)	if plural then	details[8].name = details[8].name_plural	end	end	--speciality	listWPlink(details, 9, entityID, 'P413',false)	--lateralisation, for cycling not very interesting	--listWPlink(details, 10, entityID, 'P552',false)	--blood group, idem	--listWPlink(details, 11, entityID, 'P1853',false)	--height	if not details[12].content then	details[12].content=getHeight(entityID, display_cm)	end	local display_weight=true	for _, value in pairs(display_noweight_in_riderinfobox) do -- get data if country should be printed in this wiki	if value == wiki then display_weight=false end	end	--weight	if not details[13].content and display_weight then	details[13].content=getWeight(entityID)	end	--award, should be table	--awards look weird	--if not details[14].content then	--	listWPlink(details, 14, entityID, 'P166',false)	--end	local amateurTeam, nonUCITeam, proTeam, UCITeam --local data	local amateurWD=true	local proWD=true	local managedWD=true	local teamAmateur,teamPro, teamMountainBike, teamCycloCross, teamTrack=listOfTeamTable(entityID, initialYear, finalYear)	local nationalTeam, managedTeam=listOfManagedTeamTable(entityID, initialYear, finalYear)	local managedTeam_names, managedTeam_periods, amateurTeam_names, amateurTeam_periods	local nonUCITeam_names, nonUCITeam_periods, proTeam_names, proTeam_periods	local nationalTeam_names, nationalTeam_periods	local UCITeam_names, UCITeam_periods	if teams[1].content then	managedTeam_names=teams[1].content	managedTeam_periods=teams[2].content	managedWD=false	end	if teams[3].content then	amateurWD=false	amateurTeam_names=teams[3].content	amateurTeam_periods=teams[4].content	end	if teams[5].content then	amateurWD=false	nonUCITeam_names=teams[5].content	nonUCITeam_periods=teams[6].content	end	if teams[7].content then	proWD=false	proTeam_names=teams[7].content	proTeam_periods=teams[8].content	end	if teams[9].content then	proWD=false	UCITeam_names=teams[9].content	UCITeam_periods=teams[10].content	end	if teams[11].content then	nationalTeam_names=teams[11].content	nationalTeam_periods=teams[12].content	managedWD=false	end	--plate and grab	tab = infoInitTab("300px", name, icon, 2)	if subtitle[1].content then tCell=tab:tag('tr'):tag('td'):attr('colspan','2')	:cssText('solid white; text-align:center')	:wikitext(subtitle[1].content)	end	infoFillOthersDetails(tab, others, details,translate("riderinfobox",55,w_race),"260px")	if amateurWD then	teamTable(tab, teamAmateur, translate("riderinfobox",26,w_race), translate("riderinfobox",27,w_race))	else	localTeamTable(tab,amateurTeam_names, amateurTeam_periods, translate("riderinfobox",26,w_race), translate("riderinfobox",27,w_race))	localTeamTable(tab,nonUCITeam_names, nonUCITeam_periods, translate("riderinfobox",29,w_race), translate("riderinfobox",30,w_race))	end	if proWD then	teamTable(tab, teamPro, translate("riderinfobox",45,w_race),translate("riderinfobox",46,w_race))	teamTable(tab, teamMountainBike, translate("riderinfobox",39,w_race), translate("riderinfobox",40,w_race))	teamTable(tab, teamCycloCross, translate("riderinfobox",41,w_race), translate("riderinfobox",42,w_race))	teamTable(tab, teamTrack, translate("riderinfobox",43,w_race), translate("riderinfobox",44,w_race))	else	localTeamTable(tab,proTeam_names, proTeam_periods,translate("riderinfobox",45,w_race), translate("riderinfobox",46,w_race))	localTeamTable(tab,UCITeam_names, UCITeam_periods, translate("riderinfobox",35,w_race), translate("riderinfobox",36,w_race))	end	--managed teams	if managedWD then	teamTable(tab, nationalTeam, translate("riderinfobox",52,w_race), translate("riderinfobox",53,w_race))	teamTable(tab, managedTeam, translate("riderinfobox",23,w_race), translate("riderinfobox",24,w_race))	else	localTeamTable(tab,managedTeam_names, managedTeam_periods,translate("riderinfobox",23,w_race), translate("riderinfobox",24,w_race))	end	if victories[1].content then	tab:node(addATitle(translate("riderinfobox",38,w_race)))	tab:tag('tr'):tag('td')	:css('vertical-align','top'):attr('colspan','2')	:wikitext(victories[1].content)	end	if medals[1].content then	tab:node(addATitle(translate("riderinfobox",47,w_race)))	tab:tag('tr'):tag('td')	:css('vertical-align','top'):attr('colspan','2')	:wikitext(medals[1].content)	end	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/riderinfobox", translate("raceinfobox",26,w_race), entityID)	return tab end --=== P) Team infobox local function get_rider_number(entityID, details, index)	if not details[index].content then	local riders = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part'	if riders > 0 then	local stagiaire = string.gsub(getLabelFallback('Q2328847'), "%b()", "")	local nb_stagiaires=0	for ii, p527 in statements(entityID, 'P527') do	local q = p527.qualifiers	if q and q.P39 and q.P39[1] and	q.P39[1].snaktype == 'value' and q.P39[1].datavalue.value=='Q2328847'then nb_stagiaires=nb_stagiaires+1	end	end if nb_stagiaires>0 then	details[index].content = riders ..' ('.. tostring(nb_stagiaires).." "..stagiaire..')'	else	details[index].content = riders	end	end	end end function p.teamseasoninfobox(frame)	local WDlink_on = (wiki == "mk" or wiki == "ja")	local seasonID, lf = get_and_checkID(frame)	local w_race=isWomenteam(seasonID)	local gender="m"	if w_race then gender="f" end	local details = {	{ name = translate("teaminfobox",2,w_race)}, -- sport	{ name = translate("headoftableII",3,w_race)}, -- team	{ name = translate("teaminfobox",3,w_race), name_plural = translate("teaminfobox",4,w_race)}, -- type	{ name = translate("teaminfobox",5,w_race), name_plural = translate("teaminfobox",6,w_race)}, -- UCI-cod	{ name = translate("teaminfobox",7,w_race), name_plural = translate("teaminfobox",8,w_race)}, -- сountry	{ name = translate("getSquadTableColumn",7,w_race)}, --team size	{ name = translate("teaminfobox",13,w_race)}, -- official web site	{ name = translate("teaminfobox",27,w_race), name_plural = translate("teaminfobox",28,w_race)}, --sponsor	{ name = translate("teaminfobox",24,w_race), name_plural = translate("teaminfobox",25,w_race) }, -- bike	{ name = translate("teaminfobox",26,w_race)}, -- budget	}	local managers ={	{ name = translate("teaminfobox",14,w_race), name_plural = translate("teaminfobox",15,w_race)}, -- manager	--country	{ name = translate("teaminfobox",16,w_race), name_plural = translate("teaminfobox",17,w_race)}, -- sports director	}	local others=get_others_dic()	infoGetOthers(others, seasonID)	getLocalContent(details, lf.args)	getLocalContent(others, lf.args)	local sport_id=firstValue(seasonID, 'P641', 'id')	local icon = (sport_id == "Q3609") and -- P641 is 'sport', Q3609 is 'road bicycle racing'	' [[File:Cycling (road) pictogram.svg|35px]]' or ''	local name = getLabelFallback(seasonID) or ''	local listOfNames=getFormerNames(seasonID, 'P1448',true)	--1st ist sport	if not details[1].content and sport_id then	details[1].content = WPlinkpure(sport_id)	end	local timeOfRace=getTimeOfRace(seasonID)	local initialYear	if timeOfRace then	initialYear=string.sub(timeOfRace,2,5)	else	error("no timeOfRace found for "..seasonID)	end local sitelink, catID, _=getTeamLinkCat(seasonID, timeOfRace, nil, true) --team	if not details[2].content then	details[2].content=sitelink	end	--type	listWPlinkChrono(details, 3, seasonID, {'P2094'}, 'rider', initialYear, nil, nil, true)	if not details[3].content then --fallback if catID then	details[3].content=getRiderLink(catID, timeOfRace) --it is not a rider, but it gives the correct result end	end	listWPlinkChrono(details, 4, seasonID, {'P1998'}, 'UCIcode', initialYear, nil, true,true)	local display_flag=true	listWPlinkChrono(details, 5, seasonID, {'P1532','P17'}, 'country', initialYear, display_flag,nil,true)	-- number of riders	get_rider_number(seasonID, details, 6)	-- official site	if not details[7].content then	details[7].content = officialSite(seasonID)	end	--Sponsor	listWPlinkChrono(details, 8, seasonID, {'P859'}, 'rider', initialYear, nil, nil, true)	--bike	listWPlinkChrono(details, 9, seasonID, {'P1876'}, 'rider', initialYear, nil, nil, true)	--budget	if not details[10].content then	p=firstValue(seasonID,'P2769')	if p and p.mainsnak.snaktype == 'value' then	local amount=p.mainsnak.datavalue.value.amount	local unit=p.mainsnak.datavalue.value.unit	details[10].content=dispmoney(amount, unit)	end	end	local listofcalendar, UCIQtoYear=riderranking_sub(w_race)	local tTable={} --no need for year, it is clear	for _, calendar in pairs(listofcalendar) do	tTable[calendar]={}	end	--not over-writable presently	tTable=get_teamranking(seasonID, w_race, UCIQtoYear,listofcalendar, tTable,gender)	--Staff, there can be several	-- manager	listWPlinkChrono(managers, 1, seasonID, {'P505'}, 'rider', initialYear, nil, nil, true)	-- sports director	listWPlinkChrono(managers, 2, seasonID, {'P286'}, 'rider', initialYear, nil, nil, true)	--Build the table	tab = infoInitTab("300px", name, icon, 2)	infoFillOthersDetails(tab, others, details, translate("teaminfobox",1,w_race))	--in case there are several names	if listOfNames and #listOfNames>1 then --Always display a list of names	tab:node(addATitle(translate("teaminfobox",19,w_race)))	for _, v in pairs(listOfNames) do	tab:node(addARow(v[2],v[3])) --period, name	end	end	if managers[1].content or managers[2].content then	tab:node(addATitle(translate("teaminfobox",18,w_race)))	for _, row in ipairs(managers) do	tab:node(addARow(row.name, row.content)) --node check itself if nil	end	end	--Palmares	tab:node(addATitle(translate("raceinfobox",20,w_race)))	local wins = #wikibase.getAllStatements(seasonID, 'P2522')	if wins then	tab:node(addARow(translate("victories",2,w_race),tostring(wins)))	end	for calendar, v_calendar in pairs(tTable) do	if v_calendar[initialYear] then	local v=v_calendar[initialYear]	local calendar_name=translate("riderranking",KeytoRiderRankingCode[calendar],w_race)	if v["sitelink"] then	tab:node(addATitle('[['..v["sitelink"]..'|'..calendar_name..']]'))	else	tab:node(addATitle(calendar_name))	end	if v["teamrank"] then	tab:node(addARow(translate("riderranking",20,w_race),v["teamrank"]))	end	if v["rider"] then	tab:node(addARow(translate("riderranking",21,w_race),v["rider"]))	end	end	end -- an empty line with a title under the form in the form of an image or third-party template	if get_arg('jersey',lf) then -- if the jersey is not specified, then the JERSEY header is not displayed	tab:node(addATitle(translate("teaminfobox",20,w_race))) local outTable = mw.html.create('tr')	local tCell=outTable:tag('td'):attr('colspan','3'):css('text-align','center')	tCell:wikitext(get_arg('jersey',lf)) -- adding a form via "argument 2" by an image or an extraneous template	tab:node(outTable)	end -- adding a link to articles about the last and current seasons (the same as for the race)	tab:node(getPreviousNextLine(seasonID))	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/raceinfobox", translate("raceinfobox",26,w_race), seasonID)	return tab end function p.teaminfobox(frame)	-- If true, winners will have Wikidata logos with link to Wikidata	local WDlink_on = (wiki == "mk" or wiki == "ja")	local entityID, lf = get_and_checkID(frame)	local w_race=isWomenrace(entityID)	local tRace = {race={	raceId,	raceDate,	future,	}, }	local details = {	{ name = translate("teaminfobox",2,w_race)}, -- sport	{ name = translate("teaminfobox",3,w_race), name_plural = translate("teaminfobox",4,w_race)}, -- type	{ name = translate("teaminfobox",5,w_race), name_plural = translate("teaminfobox",6,w_race)}, -- UCI-cod	{ name = translate("teaminfobox",7,w_race), name_plural = translate("teaminfobox",8,w_race)}, -- сountry	{ name = translate("teaminfobox",9,w_race)}, -- creation date	{ name = translate("teaminfobox",10,w_race)}, -- disparition date	{ name = translate("teaminfobox",11,w_race)}, -- number of season	{ name = translate("teaminfobox",13,w_race)}, -- official web site	{ name = translate("teaminfobox",27,w_race), name_plural = translate("teaminfobox",28,w_race)}, --sponsor	{ name = translate("teaminfobox",24,w_race), name_plural = translate("teaminfobox",25,w_race) }, -- bike	{ name = translate("teaminfobox",26,w_race)}, -- budget	}	local others=get_others_dic()	local managers ={	{ name = translate("teaminfobox",14,w_race), name_plural = translate("teaminfobox",15,w_race)}, -- manager	--country	{ name = translate("teaminfobox",16,w_race), name_plural = translate("teaminfobox",17,w_race)}, -- sports director	}	local managers_season ={	{ name = translate("teaminfobox",14,w_race), name_plural = translate("teaminfobox",15,w_race)}, -- manager	--country	{ name = translate("teaminfobox",16,w_race), name_plural = translate("teaminfobox",17,w_race)}, -- sports director	}	local details_season = {	{ name = translate("getSquadTableColumn",7,w_race)}, --team size	{ name = translate("victories",2,w_race)} --number of victories	}	local name = getLabelFallback(entityID, lang_priority) or ''	infoGetOthers(others, entityID)	getLocalContent(details, lf.args)	getLocalContent(others, lf.args)	getLocalContent(managers, lf.args) local listOfNames=getFormerNames(entityID, 'P1448')	local sport_id=firstValue(entityID, 'P641', 'id')	local icon = (sport_id == "Q3609") and -- P641 is 'sport', Q3609 is 'road bicycle racing'	' [[File:Cycling (road) pictogram.svg|35px]]' or ''	--1st ist sport	if not details[1].content and sport_id then	details[1].content = WPlinkpure(sport_id)	end	local creation=firstValue(entityID, 'P571', 'time')	local initialYear=string.sub(creation,2,5)	-- type	listWPlinkChrono(details, 2, entityID, {'P31'}, 'rider', initialYear)--it is not a rider, but we need link + official name	--UCI code	listWPlinkChrono(details, 3, entityID, {'P1998'}, 'UCIcode', initialYear, nil, true)	-- сountry	local display_flag=true	listWPlinkChrono(details, 4, entityID, {'P1532','P17'}, 'country', initialYear, display_flag)	--creation date	if not details[5].content and creation then	details[5].content = funcDate(creation, "onlyyear" )	end	-- disparition date	local disparition=firstValue(entityID, 'P576', 'time')	if not details[6].content and disparition then	details[6].content = funcDate(disparition,"onlyyear")	end	--populate tRace	listOfWinners(entityID, tRace,true,lf)	-- number of season	if not details[7].content and tRace.numberOfEditions and tRace.lastEditionYear then	details[7].content = tostring(tRace.numberOfEditions).." (" .. translate("teaminfobox",12,w_race) .. " "..tostring(tRace.lastEditionYear)..")"	end	-- official site	if not details[8].content then	details[8].content = officialSite(entityID)	end	--9 is sponsor	listWPlinkChrono(details, 9, entityID, {'P859'}, 'rider', initialYear)	--10 is bike	listWPlinkChrono(details, 10, entityID, {'P1876'}, 'rider', initialYear)	--11 budget	listWPlinkChrono(details, 11, entityID, {'P2769'}, 'money', initialYear)	-- manager	listWPlinkChrono(managers, 1, entityID, {'P505'}, 'rider', initialYear)	-- sports director	listWPlinkChrono(managers, 2, entityID, {'P286'}, 'rider', initialYear)	--Build the table	tab = infoInitTab("300px", name, icon, 2)	--former names	wiki_listOfNamesAtBottom={'ru'}	local listOfNamesAtBottom = false	for _, value in pairs(wiki_listOfNamesAtBottom) do --	if value == wiki then listOfNamesAtBottom = true end	end	--picture at the top	infoFillOthersDetails(tab, others, details, translate("teaminfobox",1,w_race),"260px")	if managers[1].content or managers[2].content then	tab:node(addATitle(translate("teaminfobox",18,w_race)))	for _, row in ipairs(managers) do	tab:node(addARow(row.name, row.content)) --node check itself if nil	end	end	if listOfNames and #listOfNames>0 then --Always display a list of names	tab:node(addATitle(translate("teaminfobox",19,w_race)))	for _, v in pairs(listOfNames) do	tab:node(addARow(v[2],v[3])) --period, name	end	end -- an empty line with a title under the form in the form of an image or third-party template	if get_arg(2,lf) then -- if the jersey is not specified, then the JERSEY header is not displayed	tab:node(addATitle(translate("teaminfobox",20,w_race))) local outTable = mw.html.create('tr')	local tCell=outTable:tag('td'):attr('colspan','3'):css('text-align','center')	tCell:wikitext(get_arg(2,lf)) -- adding a form via "argument 2" by an image or an extraneous template	tab:node(outTable)	end -- adding a link to articles about the last and current seasons (the same as for the race)	if tRace.lastID then	-- manager	listWPlinkChrono(managers_season, 1, tRace.lastID, {'P505'}, 'rider', tRace.lastEditionYear, nil, nil, true)	-- sports director	listWPlinkChrono(managers_season, 2, tRace.lastID, {'P286'}, 'rider', tRace.lastEditionYear, nil, nil, true)	get_rider_number(tRace.lastID, details_season, 1)	local wins = #wikibase.getAllStatements(tRace.lastID, 'P2522')	local today=os.date("*t")	if wins and tonumber(tRace.lastEditionYear)==tonumber(today['year']) then --display only if the season if for this year	details_season[2].content=tostring(wins)	end	infoFillOthersDetails(tab, nil, managers_season, translate("teaminfobox",21,w_race),"260px")	infoFillOthersDetails(tab, nil, details_season, nil,"260px")	local outTable	if tRace.lastLink then outTable = mw.html.create('tr')	local tCell=outTable:tag('td'):attr('colspan','2'):css('text-align','center')	local lastText="[[File:Crystal Clear app kworldclock.png|left|37px]]"..	translate("teaminfobox",22,w_race)..	":<br>'''"..	tRace.lastLink.."'''"	tCell:wikitext(lastText)	tab:node(outTable)	end	if tRace.nextLink then	outTable = mw.html.create('tr')	local tCell=outTable:tag('td'):attr('colspan','2'):css('text-align','center') local nextText = "[[File:Crystal Clear app kworldclock.png|left|37px]]".. translate("teaminfobox",23,w_race).. ":<br>'''".. tRace.nextLink.."'''"	tCell:cssText("text-align:center"):wikitext(nextText)	tab:node(outTable)	end	end	wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/raceinfobox", translate("raceinfobox",26,w_race), entityID)	return tab end --== teamriderCompetitionranking function p.teamriderCompetitionranking(frame)	local tempID, lf=get_and_checkID(frame)	local calendarID	local timeOfRace=getTimeOfRace(tempID)	local initialYear	if timeOfRace then	year=string.sub(timeOfRace,2,5)	end	local header_1_tab = {["UWT"]=13 ,["europe"]=14 ,["asia"]=15,["america"]=16 ,["africa"]=17 ,["oceania"]=18, ["WWT"]=11, ["women"]=1, ["Pro"]=22}	local header_1_number = 12	local key=get_arg(2,frame)	if key and year then	calendarID=data.UCIYearToQ[key][year]	header_1_number = header_1_tab[key]	end	local w_race=isWomenteam(calendarID)	if not calendarID or calendarID == "" then return "" end	local s = {	header_function = "calendar",	header_1 =header_1_number,	header_2 = {2, 3, 5, 4, 24, 23},	data_sort_type = {'', '','', 'unsortable', '', ''},	property="P1344",	calendarID=calendarID,	item = tempID, --should be called item for tableA	lf=lf,	w_race=w_race	}	return teamriderCompetitionranking_main(s,tableA(s)) end local function get_competition_bestrider(RaceID, seasonID, gender)	local riderLink, rank, disqualified, cancelled, q	local bold=false	for _, p1344 in statements(seasonID, 'P1344') do	thisCompetition = p1344.mainsnak.datavalue.value.id	if thisCompetition and thisCompetition==RaceID then	q = p1344.qualifiers	if q then	if q and q.P1352 and q.P1352[1].snaktype == 'value' then --rank	rank= tonumber(q.P1352[1].datavalue.value.amount)	if rank==1 then	bold=true	end	rank=number(gender,rank,wiki)	end	--get best rider	if q and q.P710 and q.P710[1].snaktype == 'value' then --participant	rider = q.P710[1].datavalue.value.id	riderLink = getRiderLink(rider, thisdate)	countryID = getNationality(rider, thisdate)	if countryID then	riderLink = flag(countryID, thisdate) .. ' ' .. riderLink	end	end	_,disqualified=isdisqualified(p1344, q)	if riderLink and disqualified==true then	riderLink='<s>'..riderLink..'</s>'	end	end	end	end	return riderLink, rank, bold end function teamriderCompetitionranking_main(s, resultTable)--Display the UCI women calendar of one year	local best_rider, rank	local lf = s.lf	local calendarID=s.calendarID	local seasonID= s.item	local t_Body ={}	local w_race=s.w_race	local gender="m"	if w_race then gender="f" end	local temp=firstValue(calendarID, s.property)	if not temp or temp=="" then	s.error_message = 2	if wiki == "ar" then return "" end	end	local country=getCountryBool(s.no_country)	----- Begin of the main part of the code	local ind=0	for _, p527 in statements(calendarID, 'P527') do	local RaceID = p527.mainsnak.datavalue.value.id	local temp=firstValue(RaceID, 'P1346','id')	local cancelled=false	if temp and temp=='Q30108381' then --race cancelled	cancelled=true	else	ind=ind+1	end	if not cancelled then	---- Create a row ----	local timeOfRace, date_tCell, date_sortkey = fn_date(RaceID)	local future=compareDate(timeOfRace)	local parentID, race_tCell, _= fn_race(RaceID,nil,false,timeOfRace,nil,country)	if race_tCell~=nil then --otherwise the class is not display	local country_flag, country_name, country_tCell=fn_country(RaceID, timeOfRace, country, race_tCell, parentID)	--create the table	local tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 5px;")	tRow:node(date_tCell)	tRow:tag('td'):cssText("text-align:center;padding:0 0.5em"):wikitext(tostring(ind)) --correct only if the races are sorted correctly in wikidata	tRow:node(country_tCell)	if country then	tRow:node(race_tCell) end	--logic to get the best rider||ranking	riderLink, rank, bold=get_competition_bestrider(RaceID, seasonID, gender)	local tCell=tRow:tag('td'):cssText("text-align:".. textalign ..";padding:0 0.5em")	if riderLink then	tCell:wikitext(riderLink)	elseif future then	tCell:wikitext("")	else	tCell:wikitext(" - ")	end	tCell=tRow:tag('td'):cssText("text-align:".. textalign ..";padding:0 0.5em")	if bold then	tCell:cssText("font-weight:bold;")	end	if rank then	tCell:wikitext(rank)	elseif future then	tCell:wikitext("")	else	tCell:wikitext(" - ")	end	---- Add the row to the table	table.insert(t_Body, {sortkey=date_sortkey, body=tRow})	end	end	end	return sortAndConcat(t_Body, resultTable) end --=== Z) Miscellaneous / Other / Tests --[[ Give access to a local variable. Used by other modules. ]] function p.getLocal(name)	if name == 'getTeamLinkCat' then return getTeamLinkCat end	if name == 'getStatementForTime' then return getStatementForTime end end function p.testlocal(frame) --function to test local functions	local function_name=frame.args[1]	local argu=frame.args	local temp, temp2	if function_name=='firstValue' then	return firstValue(argu[2],argu[3],argu[4])	elseif function_name=='getOfficialName' then	temp, temp2 =getOfficialName(argu[2],argu[3],argu[4])	return temp	elseif function_name=='getRiderLink' then	if argu[3]=="nil" then arg3=nil else arg3=argu[3] end	temp=getRiderLink(argu[2],arg3) --only first arg returned	return temp	elseif function_name=='funcDate' then	return funcDate(argu[2],argu[3])	elseif function_name=='funcDateFigure' then	return funcDateFigure(argu[2],argu[3])	elseif function_name=='getStartEndTime1' then	temp, temp2=getStartEndTime(argu[2],argu[3],argu[4])	return temp	elseif function_name=='getStartEndTime2' then	temp, temp2=getStartEndTime(argu[2],argu[3],argu[4])	return temp2	elseif function_name=='getPeriodSub' then	temp, temp2=getPeriodSub(argu[2],argu[3],toboolean(argu[4]))	return temp	elseif function_name=='getTeam' then	temp=getTeam(argu[2],argu[3],argu[4])	if temp then return temp else return 'nil' end	elseif function_name=='getStatementForTime' then	temp=getStatementForTime(argu[2],argu[3],argu[4])	if temp then	return temp.mainsnak.datavalue.value.id	else	return 'nil'	end	elseif function_name=='getTeamLinkCat' then	temp=getTeamLinkCat(argu[2],argu[3],toboolean(argu[4]))	if temp then return temp else return 'nil' end	elseif function_name=='getTeamLinkCat2' then	temp, temp2=getTeamLinkCat(argu[2],argu[3],toboolean(argu[4]))	if temp2 then return temp2 else return 'nil' end	elseif function_name=='getPlaceLink' then	if argu[3]=="nil" then arg3=nil else arg3=argu[3] end	return getPlaceLink(argu[2],arg3)	elseif function_name=='getPlaceLink2' then	return getPlaceLink(argu[2],argu[3],nil,true)	elseif function_name=='seasonToTeamID' then	if argu[2]=="nil" then arg2=nil else arg2=argu[2] end	return tostring(seasonToTeamID(arg2))	elseif function_name=='translate' then	return translate(argu[2],tonumber(argu[3]),toboolean(argu[4]))	elseif function_name=="classLinkFn" then	return classLinkFn(argu[2])	elseif function_name=='raceLink' then	return tostring(raceLink(argu[2]))	elseif function_name=='getMainRaceLink' then	if argu[5]=="nil" then arg5=nil else arg5=argu[5] end	if argu[3]=='stage' then arg3='stage' else arg3=tonumber(argu[3]) end	return tostring(getMainRaceLink(argu[2],arg3,argu[4], arg5,argu[6]))	elseif function_name=='getYear' then	return getYear(argu[2])	elseif function_name=='getCountryName' then	return tostring(getCountryName(argu[2]))	elseif function_name=='getTeamCodeCat' then	return tostring(getTeamCodeCat(argu[2],argu[3]))	elseif function_name=='getTeamCode' then	return tostring(getTeamCode(argu[2],argu[3],argu[4]))	elseif function_name=='getCountryBool' then	return tostring(getCountryBool({argu[2],argu[3]}))	elseif function_name=='WPlinkpure' then	return WPlinkpure(argu[2])	elseif function_name=='uciCodeCountry' then	return uciCodeCountry(argu[2])	elseif function_name=='isHuman' then	return tostring(isHuman(argu[2]))	elseif function_name=='isCountry' then	return tostring(isCountry(argu[2]))	elseif function_name=='isWomenrace' then	return tostring(isWomenrace(argu[2]))	elseif function_name=='isWomenteam' then	return tostring(isWomenteam(argu[2]))	elseif function_name=='commaStage' then	temp =commaStage(argu[2],argu[3])	return temp["prefix"]	elseif function_name=='number' then	return number(argu[2],tonumber(argu[3]), argu[4])	elseif function_name=='classToCircuit' then return classToCircuit(argu[2], argu[3], toboolean(argu[5]), nil)	elseif function_name=='getGenderCode' then return tostring(getGenderCode(argu[2], argu[3]))	elseif function_name=='calculateTime' then	return calculateTime(argu[2])	elseif function_name=='getClass1' then	temp, temp2 = getClass(argu[2])	return temp	elseif function_name=='getClass2' then	temp, temp2 = getClass(argu[2])	return temp2	elseif function_name=='infoGetPlace' then	local details = {{ name = "test", name_plural="tests"}} -- course / not used	infoGetPlace(details,1, argu[2], argu[3], argu[4])	return details[1].content	elseif function_name=='getFormerNames1' then	temp=getFormerNames(argu[2],'P1448')	if temp[1] then	return temp[1][2] --period	else	return ""	end	elseif function_name=='getFormerNames2' then	temp=getFormerNames(argu[2],'P1448')	if temp[1] then	return temp[1][3] --name	else	return ""	end	elseif function_name=='getType' then	return getType(argu[2])	elseif function_name=='compareDate' then	return tostring(compareDate(argu[2]))	elseif function_name=='officialSite' then	return officialSite(argu[2])	elseif function_name=='trans' then	return tostring(trans(argu[2], argu[3], argu[4]))	elseif function_name=='parseDate1' then	temp1, temp2, temp3, temp4, temp5= parseDate(argu[2], argu[3], argu[4], argu[5], "", "error text")	return temp1	elseif function_name=='parseDate2' then	temp1, temp2, temp3, temp4, temp5= parseDate(argu[2], argu[3], argu[4], argu[5], "", "error text")	return temp2	elseif function_name=='parseDate5' then	temp1, temp2, temp3, temp4, temp5= parseDate(argu[2], argu[3], argu[4], argu[5], "", "error text")	return temp5	elseif function_name=='findLastName' then	return findLastName(argu[2],wiki)	elseif function_name=='findSortKey' then	if wiki=="ru" or wiki=="mk" then	return findSortKey(argu[2],false, true)	else	return findSortKey(argu[2],true, false)	end	elseif function_name=='calculateAge' then	temp1, _, _ =calculateAge(argu[2])	return temp1	elseif function_name=='getBirthDeathDate1' then temp1, temp2 =	getBirthDeathDate(argu[2])	return temp1	elseif function_name=='getBirthDeathDate2' then	temp1, temp2 =	getBirthDeathDate(argu[2])	return temp2	elseif function_name=='getLocalContent' then	local details = {	{ name = argu[2], name_plural= argu[3]} }	local arguments = {}	arguments[argu[4]]="test"	getLocalContent(details, arguments)	return details[1].content	elseif function_name=='plural1' then	_, temp1, temp2=plural(tonumber(argu[2]))	return temp1	elseif function_name=='plural2' then	_, temp1, temp2=plural(tonumber(argu[2]))	return temp2	elseif function_name=='getNationality' then	return getNationality(argu[2], argu[3])	elseif function_name=='getCountryID' then	return getCountryID(argu[2], argu[3])	elseif function_name=='get_formatted_date1' then	if argu[3]=="nil" then arg3=nil else arg3=argu[3] end	temp, temp2= get_formatted_date(argu[2], arg3)	if temp then return temp end	elseif function_name=='get_formatted_date2' then	if argu[3]=="nil" then arg3=nil else arg3=argu[3] end	temp, temp2= get_formatted_date(argu[2], arg3)	if temp2 then return temp2 end	elseif function_name=="getSpeed" then	if argu[4]=="nil" then arg4=nil else arg4=tonumber(argu[4]) end	return tostring(getSpeed(argu[2], toboolean(argu[3]),arg4, argu[5]))	elseif function_name=="formatNumber" then	return formatNumber(tonumber(argu[2]), toboolean(argu[3]),tonumber(argu[4]))	end end function p.test_import(frame)	local function_name=frame.args[1]	local argu=frame.args	if function_name=='class_dic' then	return tostring(data.class_dic[argu[2]])	elseif function_name=="class_sort" then	return tostring(data.class_sort[argu[2]])	elseif function_name=='bg_color_table' then	local temp = data.bg_color_table[argu[2]]	temp=string.gsub(temp,'#',"")	return temp	end end return p