Documentation[voir] [modifier] [historique] [purger]

Utilisation

Le module Cycling race est un programme codé en Lua. Il n'accepte que les données de Wikidata. Il est une simple copie de sa version sur Wikidata Module:Cycling race. Toute amélioration du module doit donc se faire sur Wikidata et le code doit être recopié sur toutes les versions linguistiques de Wikipédia qui l'utilisent.

Fonctions

Toutes les fonctions peuvent être appelée par les modèles en anglais, "{{Cycling race/" +Fonction dans le code+"}}". Pour rendre l'utilisation plus facile d'accès, les noms des modèles ont été traduits en français.

Nom completFonction dans le codeModèle (FR)DescriptionExemple
Fonctions pour une course cycliste
Infoboxraceinfobox{{Course cycliste/courseinfobox}}Affiche l'infobox de la course{{Cycling race/raceinfobox|Q1578389}}
ou
{{Course cycliste/courseinfobox|Q1578389}}
Liste des vainqueurslistofwinners{{Course cycliste/listedesvainqueurs}}Affiche le palmarès d'une course{{Cycling race/listofwinners|Q15043657}}
ou
{{Course cycliste/listedesvainqueurs|Q15043657}}
Liste des vainqueurs (pour les championnats)listofwinnersChamp{{Course cycliste/listedesvainqueurschamp}}Affiche le palmarès d'un championnat (sans les drapeaux){{Course cycliste/listedesvainqueurschamp|Q15043657}}
Liste des vainqueurs à partir d'une année donnée (pour les championnats)listofwinnersChampsecondpart{{Course cycliste/listedesvainqueurschampdeuxiemepartie}}Affiche le palmarès d'un championnat à partir d'une année donnée (sans les drapeaux), évite de surcharger le serveur{{Course cycliste/listedesvainqueurschampdeuxiemepartie|Q30577837|2018}}
Liste des vainqueurs du classement par pointslistofpointswinners{{Course cycliste/listedesvainqueurspoints}}Affiche le palmarès d'une course{{Course cycliste/listedesvainqueurspoints|Q15043657}}
Liste des vainqueurs du classement de la montagnelistofmountainwinners{{Course cycliste/listedesvainqueursmontagne}}Affiche le palmarès d'une course{{Course cycliste/listedesvainqueursmontagne|Q15043657}}
Liste des vainqueurs du classement du meilleur jeunelistofyoungwinners{{Course cycliste/listedesvainqueursjeune}}Affiche le palmarès d'une course{{Course cycliste/listedesvainqueursjeune|Q15043657}}
Fonctions pour une équipe cycliste
Infoboxteaminfobox{{Course cycliste/equipeinfobox}}Affiche l'infobox d'une équipe{{Course cycliste/equipeinfobox|Q1757136}}
Infoboxteamseasoninfobox{{Course cycliste/saisonequipeinfobox}}Affiche l'infobox d'une saison d'une équipe{{Course cycliste/saisonequipeinfobox|Q104525546}}
Effectifteamroster{{Course cycliste/effectif}}Affiche l'effectif d'une équipe pour une saison donnéee{{Course cycliste/effectif|Q21968189}}
Effectif actuellastteamroster{{Course cycliste/derniereffectif}}Affiche l'effectif d'une équipe pour la saison actuelle{{Course cycliste/effectifactuel|Q2651858}}
Victoiresvictories{{Course cycliste/victoires}}Affiche les victoires d'une équipe{{Course cycliste/victoires|Q27891882}}
Classement UCIUCIclassification{{Course cycliste/classementUCI}}Affiche le classement UCI des différents coureurs de l'équipe{{Course cycliste/classementUCI|Q27891882}}
Classement des coureurs dans une compétitionteamriderCompetitionranking{{Course cycliste/classementcoureurscompetition}}Affiche le classement des coureurs dans une compétition donnée{{Course cycliste/classementcoureurscompetition|Q104525546|WWT}}
Classement équipeteamranking{{Course cycliste/classementequipe}}Affiche un tableau avec les classements d'une équipe dans une compétition{{Course cycliste/classementequipe|Q2651858|women}}
Fonctions pour les éditions d'une course cycliste
Infoboxinfobox{{Course cycliste/infobox}}Affiche l'infobox pour une course cycliste (une édition){{Course cycliste/infobox|Q28859163}}
Liste des étapeslistofstages{{Course cycliste/listedesetapes}}Affiche un tableau listant les étapes{{Course cycliste/listedesetapes|Q18589873}}
Evolution des classementslistofstagesclassification{{Course cycliste/evolutiondesclassements}}Affiche un tableau listant les leaders des classements{{Course cycliste/evolutiondesclassements|Q18589873}}
Liste des équipeslistofteams{{Course cycliste/listedesequipes}}Liste les équipes participant à une course{{Course cycliste/listedesequipes|Q20872500}}
Liste des partantsstartlist{{Course cycliste/listedespartants}}Liste des partants à une course{{Course cycliste/listedespartants|Q20872500}}
Liste des partants tableaustartlisttable{{Course cycliste/listedespartantstableau}}Liste des partants à une course sous forme de liste{{Course cycliste/listedespartantstableau|Q20872500}}
Classement généralgeneralclassification{{Course cycliste/classementgeneral}}Affiche le classement général de la course ou étape{{Course cycliste/classementgeneral|Q21934629}}
Classement général par pointsgeneralclassificationpoint{{Course cycliste/classementgeneralpoint}}Affiche le classement général par points de la course ou étape{{Course cycliste/classementgeneralpoint|Q21934629}}
Classement étapestageclassification{{Course cycliste/classementetape}}Affiche le classement de l'étape{{Course cycliste/classementetape|Q21934629}}
Classement clm par équipesteamtimetrialclassification{{Course cycliste/classementclmparequipes}}Affiche le classement d'une étape en clm par équipes (attention, il existe aussi la fonction pour l'affichage du classement général d'un clm par équipes){{Course cycliste/classementclmparequipes|Q26209129}}
Classement par pointspointsclassification{{Course cycliste/classementparpoints}}Affiche le classement par points, de la course ou de l'étape{{Course cycliste/classementparpoints|Q20882755}}
Classement par équipes au tempsteamsclassificationbytime{{Course cycliste/classementparequipesautemps}}Affiche le classement par équipes au temps{{Course cycliste/classementparequipesautemps|Q20882755}}
Classement par équipes aux pointsteamsclassificationbypoints{{Course cycliste/classementparequipesauxpoints}}Affiche le classement par équipes aux points{{Course cycliste/classementparequipesauxpoints|Q20882755}}
Classement de la montagnemountainsclassification{{Course cycliste/classementdelamontagne}}Affiche le classement de la montagne{{Course cycliste/classementdelamontagne|Q20882755}}
Classement des sprintssprintsclassification{{Course cycliste/classementdessprints}}Affiche le classement des sprints{{Course cycliste/classementdessprints|Q20882755}}
Classement du meilleur jeunebestyoungclassification{{Course cycliste/classementdumeilleurjeune}}Affiche le classement du meilleur jeune (au temps){{Course cycliste/classementdumeilleurjeune|Q20882755}}
Classement du meilleur jeune par pointsbestyoungclassificationbypoints{{Course cycliste/classementdumeilleurjeuneparpoints}}Affiche le classement du meilleur jeune par points{{Course cycliste/classementdumeilleurjeuneparpoints|Q20882755}}
Classement du combinécombinationclassification{{Course cycliste/classementducombine}}Affiche le classement du combiné{{Course cycliste/classementducombine|Q20882755}}
Classement de la combativitécombativeclassification{{Course cycliste/classementdelacombativite}}Affiche le classement de la combativité{{Course cycliste/classementdelacombativite|Q20882755}}
Classement par points personnalisécustompointsclassification{{Course cycliste/classementparpointsperso}}Affiche un classement par points, de la course ou de l'étape{{Course cycliste/classementparpointsperso|Q42158490|propriété=P3494|titre=Classement cyclamen}}
Classement au temps personnalisécustomtimeclassification{{Course cycliste/classementautempsperso}}Affiche un classement au temps, de la course ou de l'étape{{Course cycliste/classementparpointsperso|Q42158490|propriété=P4323|titre=Classement du meilleur amateur}}
Fonctions pour les calendriers
Calendriercalendar{{Course cycliste/calendrier}}Affiche le calendrier et les vainqueurs d'une compétition{{Course cycliste/calendrier|women|2018}}
Calendrier personalisécalendarcustom{{Course cycliste/calendrierperso}}Affiche le calendrier et les vainqueurs d'une compétition, affichage personnalisé{{Course cycliste/calendrierperso|Q47034891|podium=1|classe=1}}
Championnats nationauxnationalchampionships{{Course cycliste/championnatsnationaux}}Affiche la liste des championnats nationaux (féminins) pour une année donnée{{Course cycliste/championnatsnationaux|2018}}
Infobox pour les championnatschampinfobox{{Course cycliste/championnatinfobox}}Affiche l'infobox d'un championnats{{Course cycliste/championnatinfobox|Q60967591}}
Infobox pour les compétitions, calendriers ou les challengesseasoninfobox{{Course cycliste/competitioninfobox}}Affiche l'infobox d'une compétition{{Course cycliste/competitioninfobox|Q2395083}}
Fonctions pour les étapes d'une course cycliste
Infobox étapestageinfobox{{Course cycliste/infoboxetape}}Affiche l'infobox d'étape cycliste{{Course cycliste/infoboxetape|Q265672}}
Fonctions pour les coureurs
Infoboxriderinfobox{{Course cycliste/coureurinfobox}}Affiche l'infobox d'un coureur{{Course cycliste/coureurinfobox}|Q40853827}}
Classement coureurriderranking{{Course cycliste/classementcoureur}}Affiche un tableau avec les classements UCI du coureur{{Course cycliste/classementcoureur}|Q40853827}}
local p = {}local wiki = string.match(mw.site.server, "%a+")if wiki == "www" thenwiki = "fr"end--import translationlocal l10n = mw.loadData("Module:Cycling race/l10n")--import datalocal 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" thentextalign = "right"floattable = "right"floatinfobox = "left"endlocal Wikidatalogosize = "12px"if wiki == "ar" then Wikidatalogosize = "15px" endlocal standardtablecss=data.standardtablecss_part1..textalign..data.standardtablecss_part2local lang_priority --for lang priority and fallbackif l10n["lang_priority"] thenlang_priority=l10n["lang_priority"]else --defaultlang_priority={}table.insert(lang_priority,wikilang)for _, lang in ipairs({'mul','en', 'fr', 'de','es','nl','it'}) doif lang~=wikilang thentable.insert(lang_priority,lang)endendend--"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 namelocal 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 hereif not l10n["country_name_list"] thentable.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 truelocal 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 wikiif value == wiki then backgroundColor="#EAECF0" backgroundColorLight="#EFEFEF"endendlocal function istrue(x)    if x and (x == 1 or x == "1" or x == "true") then return true end    return nilend--== II) Translation ==local function translate(func_name_short, index, w_race, title)if index==1000 then --code for some custom functionreturn titleelseif func_name_short thenlocal func_nameif w_race thenfunc_name=func_name_short.."_women_translate"if l10n[func_name] and l10n[func_name][index] then return l10n[func_name][index]endendfunc_name=func_name_short.."_translate"if l10n[func_name][index] then return l10n[func_name][index]endreturn "translation for "..func_name.." index ".. tostring(index).." not found"else error('func_name found')endendendlocal function plural(num)local plural=false --latin languagelocal gen_singular=false --for slavic languagelocal gen_plural=false --for slavic languageif num thenif num > 1 thenplural=trueif num < 5 then -- 2, 3 and 4gen_singular = trueelseif num > 20 thenlocal modulo = math.fmod( num, 10)--modulo==1 --> nothing, it is singularif modulo>1 and modulo<5 thengen_singular = trueelseif modulo>4 thengen_plural=trueendelsegen_plural=trueendendendreturn plural, gen_singular, gen_pluralendlocal 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 printedas 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]endlocal function country_name_from_list(countryID)if l10n["country_name_list"] and l10n["country_name_list"][countryID] thenreturn l10n["country_name_list"][countryID]endreturn nilendlocal function stageLink(x, a, b) -- x= 10a: a = 10, b = a. x = 5: a = 5, b = ""local word1 local word2=translate("func_prologue",2) --stagelocal word=word2if wiki=="ar" then return word2 .. " " .. ( a or "" ) , "#" .. word2 .. " " .. ( a or "" ) end-- fr: {{1re}} étape, {{2e}} étapeif wiki=="fr" thenif b == "" then -- series_ordinal without characterif 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 étapereturn word1, word2endif 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 étapereturn word1, word2endendif wiki=="hu" thenif b == "" then return a..". "..word, "#"..a..". "..wordelse return a..b.." "..word, "#"..a..b.." "..word endendif wiki=="de" or wiki=="da" or wiki=="fo" or wiki=="lb" or wiki=="no" then return a..". "..b.." "..word, "#"..a..". "..b.." "..word endif wiki=="ca" then return a.."a "..b.." "..word, "#"..a..". "..b.." "..word endif wiki=="es" then return a..".ª "..word.." "..b, "#"..a..".ª "..word.." "..b endif wiki=="ast" thenif b == "" then -- series_ordinal without characterif 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ᵉʳ etapareturn word1, word2endif 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ª etapareturn word1, word2endend-- defaultword1 = x                  -- table text = 1, 2a, 3word2 = "#"..word.." ".. x -- text of section header = #Etappe 2a, #Stage 4return word1, word2endlocal 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 borderif 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] thenreturn stages[x]endif x=='time trial stage' thenif noborder then border="" else border="|right" endlocal 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] thenreturn stages2[typ]endendendlocal function typeofstagelogo(stageID, noborder)local sTypep = 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) doif t.mainsnak.snaktype == 'value' thenlocal iOf = t.mainsnak.datavalue.value.idif stages[iOf] thensType = typeofstage(stages[iOf][1], stages[iOf][2], noborder)breakendendendreturn sType or ''end--== III) basic functions--[[ Get any value for a property which is not deprecated ]]local function firstValue(QID, PID, field)if QID thenlocal ss = wikibase.getAllStatements(QID, PID)for _, s in pairs(ss) doif s.rank ~= 'deprecated' and s.mainsnak.snaktype == 'value' thenreturn field and s.mainsnak.datavalue.value[field] or s.mainsnak.datavalue.valueendendelsereturn nilendend--[[ 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 labelif fallback==nil then --defaultfallback=lang_priorityendfor _, lang in ipairs(fallback) dolabel = mw.wikibase.getLabelByLang(itemID, lang)if label then break endendreturn labelend--[[ 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 endfor _, lang in ipairs(fallback) dolink = mw.wikibase.getSitelink(itemID, lang .. 'wiki')if link then return link endendreturn nilendlocal arwiki_totemplate = mw.getCurrentFrame():getParent().args["totemplate"] or mw.getCurrentFrame().args["totemplate"]arwiki_totemplate = (wiki == "ar" and arwiki_totemplate and arwiki_totemplate ~= "") or falselocal function get_lf(frame)local lf = frameif string.match(frame:getParent():getTitle(), '%P+') == mw.site.namespaces.Template.name thenlf = frame:getParent()endreturn lfendlocal function get_and_checkID(frame)local lf = get_lf(frame)local entityID = mw.text.trim(lf.args[1])entityID= string.gsub(entityID, "%c", "") --probably redundantif type(entityID) ~= 'string' then error('parameter must be a string') endif not entityID:match('Q%d+') then error('parameter must be a valid Wikidata item (ex: Q42)') endreturn entityID, lfendlocal function make_IllWD2_link(q, arlabel, enlabel, text)local argse = { ["المعرف"] = q, target='en' }if arlabel and arlabel ~= '' then argse.label = arlabelelseif enlabel and enlabel ~= '' thenargse.enlabel = enlabelendif text and text ~= "" thenargse.text = text endlocal final = mw.getCurrentFrame():expandTemplate{ title = 'Ill-WD2', args = argse }if arwiki_totemplate thenfinal = "{{Ill-WD2"for k,v in pairs(argse) do            final = final .. "|" .. k .. "=" .. v        end        final = final .. "}}"    endreturn finalendlocal function change_listofstages(tab, raceID, header, Id)-- code used in arwiki onlyreturn tabend--[[ Iterator to get all statements for an entity and property which are not deprecated and have a value]]local function nextStatement(state, i)repeati = i + 1local s = state[i]if s and s.rank ~= 'deprecated' and s.mainsnak.snaktype == 'value' thenreturn i, senduntil s == nilendlocal function statements(QID, PID)return nextStatement, wikibase.getAllStatements(QID, PID), 0end--[[ Iterator to get all qualifier values for a property for a statement]]local function nextQualifier(state, i)repeati = i + 1local q = state[i]if q and q.snaktype == 'value' thenreturn i, q.datavalueenduntil q == nilendlocal function qualifiers(statement, PID)return nextQualifier, statement.qualifiers and statement.qualifiers[PID] or {}, 0endlocal function qualifieramount(element, property)local resultfor _, q in qualifiers(element, property) doresult = tonumber(q.value.amount)breakendreturn resultendlocal function dispmoney(amount, unit)if amount and unit thenlocal cost = contentLanguage:formatNum(tonumber(amount))if wiki == 'fo' then cost = string.gsub(cost, "%.", ",") endif unit == "http://www.wikidata.org/entity/Q4916" then cost = cost .. ' €'elseif unit == "http://www.wikidata.org/entity/Q4917" then cost = cost .. ' $'endreturn costendreturn nilend--== 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, timePrecisionif not q or not time thenreturn sendlocal _, _, _, m, _ = string.find(time, "(%d+)%p(%d+)%p(%d+)")if m=="00" thentimePrecision=9endif q.P580 and q.P580[1] and q.P580[1].snaktype == 'value' then -- P580 is start timestart = q.P580[1].datavalue.value.timestartPrecision = q.P580[1].datavalue.value.precisionif startPrecision == 9 or timePrecision==9 then -- precision is yearsstart = string.sub(start, 1, 5) -- Cut of everything after yearelseif startPrecision == 10 then -- precision is monthsstart = string.sub(start, 1, 8) -- Cut of everything after monthendendif q.P582 and q.P582[1] and q.P582[1].snaktype == 'value' then -- P582 is end timeEND = q.P582[1].datavalue.value.timeendPrecision = q.P582[1].datavalue.value.precisionendif not start or start <= time thenif not END thenreturn sendif endPrecision == 9 or timePrecision==9 then -- precision 9 is 'years'END = string.sub(END, 1, 6) .. '13' -- Set month to 13elseif endPrecision == 10 then -- precision 10 is 'months'END = string.sub(END, 1, 9) .. '32' -- Set day to 32endif END >= time thenreturn sendendreturn nilendlocal function getStatementForTime(ID, property, time)local tempfor _, s in statements(ID, property) dotemp =checktime(s, s.qualifiers, time)if temp then return temp endendreturn nilend--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 sufficientlocal function getStartEndTime(sTime, eTime, mode)-- Note: Add the 4formats to "formats" and use funcDatelocal lang = contentLanguagelocal 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 issueif  mode=='long' or mode=="verylong" thenstarttime =lang:formatDate( "Y", sTime )elsestarttime ='-'endelseif y ~= y2 thenif mode=='long' or mode=="verylong" thenstarttime = lang:formatDate( "j F Y", sTime )elsestarttime = lang:formatDate( "j M Y", sTime )endelseif m ~= m2 thenif mode=='long' or mode=="verylong" thenstarttime = lang:formatDate( "j F", sTime )elsestarttime = lang:formatDate( "j M", sTime )endelsestarttime = lang:formatDate( "j", sTime )endif wiki == "ar" thenif 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 ) endelseif wiki == "br" thenif 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 ) .." "endelseif wiki == "ca" or wiki == "es" or wiki == "ast" thenif y ~= y2 thenstarttime = lang:formatDate( "j", sTime ) .." de ".. lang:formatDate( "F", sTime ) .." de ".. lang:formatDate( "Y", sTime )elseif m ~= m2 thenstarttime = lang:formatDate( "j", sTime ) .." de ".. lang:formatDate( "F", sTime )else starttime = lang:formatDate( "j", sTime ) .." "endelseif wiki == "cs" thenif 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 )endelseif wiki == "de" or wiki == "da" or wiki == "fo" or wiki == "lb" or wiki == "no" thenif 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 )endelseif wiki == "fi" thenif 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 )endelseif wiki == "eo" thenif 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 "endelseif wiki == "eu" thenif 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 )endelseif wiki == "hu" thenstarttime = lang:formatDate( "Y. F j.", sTime)elseif wiki == "ja" thenif 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 )endelseif wiki == "lv" thenif 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 )endelseif wiki == "pl" thenif 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 )endendendif m2=='00' then --manage the 30 November issueif  mode=='long' or mode=="verylong" thenendtime= lang:formatDate( "Y", eTime )elseendtime= '-'endelseif (mode=='long' and y ~= y2) or mode=="verylong" thenendtime = lang:formatDate("j F Y", eTime)elseif y ~= y2 then --smallendtime = lang:formatDate("j M Y", eTime)elseif mode=='long' thenendtime = lang:formatDate("j F", eTime)elseendtime = lang:formatDate("j M", eTime)endif wiki == "ar" thenif 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 )endelseif wiki == "br" then endtime = lang:formatDate( "j", eTime ) .." a viz ".. lang:formatDate( "F Y", eTime )elseif wiki == "ca" or wiki == "es" or wiki == "ast" thenif mode=='long' or mode=="verylong" or y ~= y2 thenendtime = lang:formatDate( "j", eTime ) .." de "..lang:formatDate( "F", eTime ) .." de ".. lang:formatDate( "Y", eTime )elseendtime = lang:formatDate( "j", eTime ) .." de "..lang:formatDate( "F", eTime )endelseif 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" thenif mode=='long' or mode=="verylong" or y ~= y2 thenendtime = lang:formatDate( "j. F Y", eTime )elseendtime = lang:formatDate( "j. M", eTime )endelseif 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" thenif 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" thenif 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 )endelseif wiki == "lv" thenif y ~= y2 then endtime = lang:formatDate( "Y. \\g\\a\\d\\a j. F", eTime )else endtime = lang:formatDate( "j. F", eTime )endelseif wiki == "pl" then endtime = lang:formatDate( "j xg Y", eTime )endendreturn starttime, endtimeendlocal formats = data.formats -- Display the date, the mode changes the formatlocal 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 precisionlocal dispDate = dateif string.sub(date,7,8)=='00' then-- lack of monthdispDate= string.sub(date,1,6).."01-01"..string.sub(date,12)if mode == 'long' or mode == 'onlyyear' or mode == 'monthly' thenmode = 'onlyyear'elsemode = 'nodate'endelseif string.sub(date,10,11)=='00' then -- lack of daydispDate= string.sub(date,1,9).."01"..string.sub(date,12)if mode == 'long' thenmode = 'monthly'elseif mode == 'small' thenmode = 'onlymonth'elseif mode == 'onlyday' thenmode = 'nodate'endendif format[mode] == nil then mode = 'nodate' endreturn 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 thenreturn string.sub(year, 2, 5)endreturn ''endlocal function isdisqualified(p,q) --disqualification can use deprecated or P1534local cancelled=""local disqualified=falseif p and p.rank=='deprecated' thencancelled='text-decoration:line-through;'disqualified=trueelseif q and q.P1534 and q.P1534[1].snaktype == 'value' thenlocal tempdsq=q.P1534[1].datavalue.value.idif tempdsq=='Q1229261' then cancelled='text-decoration:line-through;'disqualified=trueend --disqualifiedendendreturn cancelled, disqualifiedend--=== B) Link functions ===local function getOfficialName(teamID, timeOfRace,season,strict) -- for team--return officialName, isLocallocal 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) dowantedLanguages[lang] = iend    --case one, one official name / period overloaded with other languages as qualifier    --for instance https://www.wikidata.org/wiki/Q195833    best = 999for _, p1448 in statements(teamID, 'P1448') docorrecttime=trueif timeOfRace and timeOfRace ~='' thencorrecttime =checktime(p1448, p1448.qualifiers, timeOfRace)endif correcttime then if p1448.qualifiers and p1448.qualifiers.P1448 thenlocal q = p1448.qualifiers.P1448    best = 999for _, l in pairs(q) doif l.snaktype == 'value' thenlocal lang = l.datavalue.value.languageif wantedLanguages[lang] and wantedLanguages[lang] < best thenbest = wantedLanguages[lang]name = l.datavalue.value.textendendendif name then return name, true endend--p1448 and correct time, look in the not qualifier partlang=p1448.mainsnak.datavalue.value.languageif strictLangBool thenif wiki==lang thenname = p1448.mainsnak.datavalue.value.textendelseif wantedLanguages[lang] and wantedLanguages[lang] < best thenbest = wantedLanguages[lang]name = p1448.mainsnak.datavalue.value.textelseif cyrillic[lang]==nil then --don't display cyrillic for latin wikinametemp = p1448.mainsnak.datavalue.value.textendendendend    if name then     return name, true    elseif not strictLangBool and nametemp then    return nametemp, false    end    --no official name, get labellocal label=wikibase.getLabel(teamID)if season and season==true thenif label then return string.sub(label,1,label:len()-5),true end -- elsereturn label, true -- No official name, try labelendendlocal function revertfirstlast(name)local nametable = mw.text.split(name, ",")if nametable[2] then --there is a comareturn nametable[2].." "..nametable[1]elsereturn nametable[1]endendlocal function checksitelink(sitelink, label)if sitelink==label thenreturn "[[" .. sitelink .."]]"elsereturn "[[" .. sitelink .. "|" .. label.. "]]"endend-- RiderID --> RiderLinklocal 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 languagelocal strictLang = {mk = true, ru = true}local strictLangBool= strictLang[wiki]local sitelink = wikibase.getSitelink(riderID)local officialname,officialnametemp, language, namelocal correctlanguage=falselocal listOfProperty={'P1813','P1448'}for _, prop in ipairs(listOfProperty) dofor _, p1813 in statements(riderID, prop) doif not officialname or not correctlanguage thenlanguage = p1813.mainsnak.datavalue.value.languageofficialnametemp = p1813.mainsnak.datavalue.value.textif strictLangBool thenif wiki==language thenname=officialnametemp --only exact languagecorrectlanguage=trueendelseif wiki==language then --exact language --> okname=officialnametempcorrectlanguage=trueelseif strictLang[language]==nil and not officialname then--normally all "latin" languages use the same name, except for cyrillic translationlocal russianLabel= wikibase.getLabelByLang(riderID, "ru")if russianLabel thenlocal russianEnd=string.sub(russianLabel, -3)if russianEnd~="вна" and russianEnd~="вич" then --otherwise rejectedname=officialnametemp correctlanguage=falseendelse -- no russian label, it is most probably not a cyrillic translationname=officialnametemp --any language latincorrectlanguage=falseendendendif startOfSeason~= nil thenlocal q = p1813.qualifiersif q thenlocal temp = checktime(name,q,startOfSeason)if temp then officialname = name end--if the time is correct than it is finishedelseofficialname = nameendelseofficialname = nameendendendendif sitelink and officialname then --if there is an official name, then use itreturn checksitelink(sitelink, officialname), correctlanguageelseif officialname then return officialname endif sitelink thenif wiki == "de" thenlocal label = wikibase.getLabelByLang(riderID, wiki)if label thenlocal p27 = wikibase.getBestStatements(riderID, 'P27') -- P27 is country of citizenshipif p27[1] and p27[1].mainsnak.snaktype == 'value' thenlocal c = p27[1].mainsnak.datavalue.value.idif c=="Q159" or c=="Q184" or c=="Q212" or c=="Q232" then -- Q159, Q184, Q212, Q232 is Russia, Belarus, Ukraine, Kazakhstanreturn checksitelink(sitelink, label), correctlanguageendendendendif wiki == 'ru' thenlocal label = revertfirstlast(mw.text.trim(string.gsub(sitelink, "%b()", ""), " "))return checksitelink(sitelink, label), correctlanguageelsereturn checksitelink(sitelink, mw.text.trim(string.gsub(sitelink, "%b()",""), " ")), correctlanguageendend-- No WP article. Display label, and make it a red link if no other article uses the titlelocal linklocal label = wikibase.getLabelByLang(riderID, wiki)if label thenif wiki == 'ar' thenlink = make_IllWD2_link(riderID, label)elseif wiki=='ru' thenlabel=revertfirstlast(label)endif black_list( label) thenlink = labelelselocal title = mw.title.new(label)if title and title.exists thenlink = labelelselink = "[[" .. label.. "]]"endendendreturn link, correctlanguageend-- No label in the local language. Try other languages, but don't link.correctlanguage=falseif wiki == 'ar' thenlink = make_IllWD2_link(riderID)elselink = getLabelFallback(riderID)if link thenlink = string.gsub(link, "%b()", "")elselink = "(label missing)"endendreturn link, correctlanguageendend-- Get the countryID, return a single one, not a listlocal function getCountryID(entityID, timeOfRace)local countryIDif entityID thenlocal stm = getStatementForTime(entityID, 'P1532', timeOfRace) -- P1532 is country for sportif stm == nil thenstm = getStatementForTime(entityID, 'P17', timeOfRace) -- P17 is countryendif stm then countryID = stm.mainsnak.datavalue.value.id endendreturn countryIDend--[[ Get the name of a country ]]local function getCountryName(countryID)local name = country_name_from_list(countryID)if name == nil thenlocal label, lang = wikibase.getLabelWithLang(countryID)--[[ Uses standard language fallback. Should not return nil, nil, as all countries have English labels. ]]if lang == wikilang thenname = labelelseif lang thenname = label .. ' (' .. lang .. ')'endendreturn name or ''end--[[ Get sitelink with no wiki no formating ]]local function getRawTeamLink(teamID)local sitelinklocal parentID = getParentID(teamID)if parentID then -- try parent team firstsitelink = mw.wikibase.getSitelink(parentID)endif not sitelink thensitelink = mw.wikibase.getSitelink(teamID)endreturn sitelinkend--[[ 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, p31local parentID = getParentID(teamID)local season=false-- Find team category--Hypothesis, it is a season, look in P2094for _, p2094 in statements(teamID, 'P2094') doif checktime(p2094, p2094.qualifiers, timeOfRace) thenif data.teamCats[p2094.mainsnak.datavalue.value.id] thencatID = p2094.mainsnak.datavalue.value.idseason=truebreakendendend--check if seasonif season==false then --otherwise already clearfor _, p in statements(teamID, 'P31') dolocal natureID = p.mainsnak.datavalue.value.idif natureID=="Q53534649" thenseason=truebreakendendend--look by the parent, then P31 is used for the categoryif (not catID and parentID and season) thenp31 = getStatementForTime(parentID, 'P31', timeOfRace)elseif not season then --it is the team look in the team directlyp31 = getStatementForTime(teamID, 'P31', timeOfRace)endif p31 and data.teamCats[p31.mainsnak.datavalue.value.id] then catID = p31.mainsnak.datavalue.value.id end-- Find country if neededif country or data.natTeamCats[catID] thencountryID = getCountryID(teamID, timeOfRace)endif countryID and data.natTeamCats[catID] thenif countryID=='Q145' thenname = getCountryName('Q23666')else --to solve the United-Kingdom/Great Britain problem by national teamname = getCountryName(countryID)endlocal 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])endsitelink = getRawTeamLink(teamID)else-- It is not a national cycling teamlocal isLocalif season and not forceParentlink thensitelink = 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 thensitelink = wikibase.getSitelink(parentID)endelseif parentID then -- try parent team firstsitelink = wikibase.getSitelink(parentID)name, isLocal = getOfficialName(parentID, timeOfRace)endif not sitelink thensitelink = wikibase.getSitelink(teamID)endend        if not name or (not isLocal and l10n["lang_priority"]) thenlocal partName, partIsLocal = getOfficialName(teamID, timeOfRace)if partName and (not name or partIsLocal) thenname = partNameendendendif sitelink thenif name thensitelink = '[[' .. sitelink .. '|' .. name .. ']]'elsesitelink = '[[' .. sitelink .. ']]'endelse        if wiki == "ar" thenlocal 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        endendreturn sitelink, catID, countryIDendlocal function getTeamCodeCat(teamID, timeOfRace)-- Find team categorylocal codeUCIlocal p1998 =getStatementForTime(teamID, 'P1998', timeOfRace)if p1998 thencodeUCI = p1998.mainsnak.datavalue.valueelselocal parentID = getParentID(teamID)if parentID thenp1998 =getStatementForTime(parentID, 'P1998', timeOfRace)if p1998 thencodeUCI = p1998.mainsnak.datavalue.valueendendendreturn codeUCIendlocal function getReference(lf,statement, outputLocal)local function formatRefDate(date, precision)if precision == 9 then -- Precision is yearreturn string.sub(date, 2, 5)elseif precision == 10 then -- Precision is monthreturn contentLanguage:formatDate("F Y", string.sub(date, 2, 8))elseif precision >= 11 then -- Precision is day (or less)return funcDate(date, 'long')endendlocal ref = statement.referencesif not ref or not ref[1] thenreturn nilendref = ref[1].snaksif ref.P854 and ref.P854[1] and ref.P854[1].snaktype == 'value' then -- P854 is 'reference URL'local refURL = ref.P854[1].datavalue.valuelocal 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.textlocal lang = ref.P1476[1].datavalue.value.languageif lang ~= wikilang thenrefLang = '(' .. lang .. ')'                if wiki == 'ar' then refLang = lang end            endendif ref.P577 and ref.P577[1] and ref.P577[1].snaktype == 'value' then -- P577 is 'publication date'local value = ref.P577[1].datavalue.valuerefDate = formatRefDate(value.time, value.precision)if (wiki == 'ar') then refDate = refDateelse refDate = ', ' .. refDateendendif ref.P813 and ref.P813[1] and ref.P813[1].snaktype == 'value' then -- P813 is 'retrieved'local value = ref.P813[1].datavalue.valuerefRetrieved = formatRefDate(value.time, value.precision)if wiki == "de" thenrefRetrieved = ", (abgerufen am " .. refRetrieved .. ')'elseif wiki == "ar" thenrefRetrieved = refRetrievedelseif wiki == "fr" thenrefRetrieved = " (consulté le " .. refRetrieved .. ')'elseif wiki == "da" thenrefRetrieved = " Hentet " .. refRetrieved .. '.'elserefRetrieved = " Retrieved " .. refRetrieved .. '.'endendlocal domain = string.match(refURL, '//([^/]+)')if string.sub(domain, 1, 4) == 'www.' thendomain = string.sub(domain, 5)endlocal refTextif 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" thenlocal In = ' In: <span style="font-style:italic;">' .. domain .. '</span>'refText = '<span style="font-style:italic;">['.. refURL.. ' '.. refTitle.. '.]</span> ' ..In .. refDate .. refRetrieved ..'.'elselocal at = ', <span style="font-style:italic;"> ' .. domain .. '</span>'refText = refLang .. ' [' .. refURL .. ' ' .. refTitle .. ']' .. at .. refDate .. '.' .. refRetrievedendif outputLocal==1 thenreturn refTextelse            local refargs = {}            if wiki ~= "ar" then                 refargs.name = refText            endreturn lf:extensionTag('ref', refText, refargs)endendend--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-objectlocal function get_arg(index, lf, number)if lf.args[index] thenif number thenreturn tonumber(lf.args[index])elsereturn string.gsub(lf.args[index], "%c", "")endendreturn nilendlocal function getImageOrMap(QID, PID)local p18 = wikibase.getBestStatements(QID, PID) -- P18 is 'image'local firstfor _, image in pairs(p18) doif image.mainsnak.snaktype == 'value' thenif not first thenfirst = image.mainsnak.datavalue.valueendlocal q = image.qualifiersif q and q.P2096 thenfor _, caption in pairs(q.P2096) do -- P2096 is 'caption'if caption.snaktype == 'value' and caption.datavalue.value.language == wikilang thenreturn image.mainsnak.datavalue.value, caption.datavalue.value.textendendendendendreturn firstendlocal function getLogo(QID)return getImageOrMap(QID, 'P154')endlocal function getImage(QID)return getImageOrMap(QID, 'P18')endlocal function getMap(QID)return getImageOrMap(QID, 'P242')endlocal 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 theninstanceOf = firstValue(QID, 'P31', 'id') -- P31 is 'instance of'endif instanceOf == 'Q1137352' then -- Q1137352 is 'French Road Cycling Cup'local label2 = wikibase.getLabel(instanceOf)if sitelink thenif label2 then return '[[' .. sitelink .. '|' .. label2 .. ']]' endreturn '[[' .. sitelink .. ']]'endlocal sitelink2 = wikibase.getSitelink(instanceOf)if sitelink2 then return '[[' .. sitelink2 ..'|' .. string.gsub(sitelink2, " %b()", "") .. ']]' endif label2 then return label2 endendif sitelink then return "[[".. sitelink.. "]]" endreturn wikibase.getLabel(QID) or ''endlocal function getPlaceLink(placeID,timeOfRace)local sitelink = wikibase.getSitelink(placeID)local name = country_name_from_list(placeID)if name==nil thenname=getOfficialName(placeID, timeOfRace,nil,true) --name should be in the right languageendif sitelink then-- Delete " (...)" form e.g. "Unley (South Australia)"if name ~=nil thenreturn '[[' .. sitelink .. '|' .. name .. ']]'elsereturn '[[' .. sitelink .. '|' .. string.gsub(sitelink, ' %b()', '') .. ']]'endendlocal label = wikibase.getLabel(placeID) or ''if wiki == 'ar' thenarlabel = wikibase.getLabelByLang(placeID, "ar")return make_IllWD2_link(placeID, arlabel)endreturn contentLanguage:ucfirst(label)end-- ClassID --> ClassLink-- some WPs use a unique article for this caselocal function classLinkFn(classID, circuitID)local link, labelif wiki~="fr" then --not usedlink= wikibase.getSitelink('Q22348500') -- Q22348500 is 'cycling race class'elseif circuitID thenlink =wikibase.getSitelink(circuitID) --optional parameter to obtain [circuitlink|class label] endif classID=="Q18536594" then if wiki=="fr" thenlabel="JO"elselabel="OG"endelse label = getLabelFallback(classID)endif label and link thenlink = '[[' .. link .. '|' .. label .. ']]'elseif link thenlink = '[[' .. link .. ']]'elseif label thenlink = labelelselink=''endif wiki == "ar" then-- right now Q22348500 has no link in "ar"link = make_IllWD2_link(classID , "", label)endreturn linkend--[[ Get local content to a infoboxe from template args ]]local function getLocalContent(contents, args)for _, content in pairs(contents) dolocal name = content.nameif not name then error('translation missing in Module:Cycling race/l10n of your wikipedia') endlocal nameNoShy = string.gsub(name, '&#173;', '')  -- filter soft hyphen outlocal nameNoShyLow, name_pluralNoShyLowif nameNoShy thennameNoShyLow = mw.ustring.lower(nameNoShy)endlocal name_plural = content.name_plurallocal name_pluralNoShy = name_plural and string.gsub(name_plural, '&#173;', '')  -- filter soft hyphen outif name_pluralNoShy thenname_pluralNoShyLow = mw.ustring.lower(name_pluralNoShy)endif args[nameNoShy] and args[nameNoShy] ~= '' thenif content.special thenlocal newname, value = string.match(args[nameNoShy], '([^:]+):(.*)')if value and mw.text.trim(value) ~= '' thencontent.name = mw.text.trim(newname)content.content = mw.text.trim(value)endelsecontent.content = mw.text.trim(args[nameNoShy])endelseif nameNoShyLow and args[nameNoShyLow] and args[nameNoShyLow] ~= '' thenif content.special thenlocal newname, value = string.match(args[nameNoShyLow], '([^:]+):(.*)')if value and mw.text.trim(value) ~= '' thencontent.name = mw.text.trim(newname)content.content = mw.text.trim(value)endelsecontent.content = mw.text.trim(args[nameNoShyLow])endelseif args[name_pluralNoShy] and args[name_pluralNoShy] ~= '' thencontent.name = content.name_pluralcontent.content = mw.text.trim(args[name_pluralNoShy])elseif name_pluralNoShyLow and args[name_pluralNoShyLow] and args[name_pluralNoShyLow] ~= '' thencontent.name = content.name_pluralcontent.content = mw.text.trim(args[name_pluralNoShyLow])endendendlocal function checkDis(q)dis="road"if q and q.P642 and q.P642[1] and q.P642[1].snaktype == 'value' thenif q.P642[1].datavalue.value.id == 'Q520611' or q.P642[1].datavalue.value.id =='Q1031445' thenonlyRoad=falsedis="mountainBike"elseif  q.P642[1].datavalue.value.id == 'Q335638' thenonlyRoad=falsedis="cycloCross"elseif q.P642[1].datavalue.value.id == 'Q221635' thenonlyRoad=falsedis="track"endendreturn disend-- Rider --> Team linklocal function getTeam(riderID, timeOfRace, q)-- q: qualifiers of statement in race entity where the rider is the valuelocal teamID, link, catID, countryIDif q and q.P54 and q.P54[1].snaktype == 'value' then -- P54 is member of sports teamteamID = q.P54[1].datavalue.value.idlink, catID, countryID = getTeamLinkCat(teamID, timeOfRace)elsefor _, s in statements(riderID, 'P54') doif not link then --like a breakp54 =checktime(s, s.qualifiers, timeOfRace) if p54 thendis=checkDis(p54.qualifiers)    if dis=='road' then --by defaultteamID = p54.mainsnak.datavalue.value.idlink, catID, countryID = getTeamLinkCat(teamID, timeOfRace)endendendendendreturn link, teamID, catID, countryIDend--RiderID --> UCI codelocal function getTeamCode(riderID, timeOfRace, q)-- q: qualifiers of statement in race entity where the rider is the valuelocal teamID, codeif q and q.P54 and q.P54[1].snaktype == 'value' then -- P54 is member of sports teamteamID = q.P54[1].datavalue.value.idcode = getTeamCodeCat(teamID, timeOfRace)elselocal p54 = getStatementForTime(riderID, 'P54', timeOfRace)if p54 thenteamID = p54.mainsnak.datavalue.value.idcode= getTeamCodeCat(teamID, timeOfRace)endendreturn codeendlocal function seasonToTeamID(teamID)if teamID thenlocal parentID=getParentID(teamID)if parentID then--season was usedreturn parentIDelsereturn teamIDendelsereturn nilendendlocal 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 textendlocal function WPlinkpure(Qnumber)local link=''local Sitelink = wikibase.getSitelink(Qnumber) -- link to WParticlelocal Label = getLabelFallback(Qnumber) or ''if Sitelink ~= nil then link = "[[" .. Sitelink .. "|" .. mw.text.trim(string.gsub(Sitelink, "%b()", "")..' ') .. "]]"elseif wiki == 'ar' thenarlabel = 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)endreturn linkend--=== C) Function for the output ===local function getCountryBool(no_country_list)local country = trueif no_country_list thenfor _, value in pairs(no_country_list) do -- get data if country should be printed in this wikiif value == wiki then country = false endendendreturn countryendlocal function handle_error_message(s)local error_message=''if s.error_message and s.error_message ~= 0 thenerror_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 .. ']]'endreturn error_message endlocal 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 endlocal 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) endlocal 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) doif i == s.country_column thenif country == true thenheader:tag('th'):cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate(s.header_function,k,s.w_race))endendif i ~= s.country_column thenlocal 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' thencolumn:addClass('unsortable')endendendreturn tendlocal function tableB(s) --for startlistlocal error_message=handle_error_message(s)local roll = truefor _, value in pairs(s.no_roll_startlist) do -- get data if country should be printed in this wikiif value == wiki then roll = false endendlocal 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) endif roll == true thenlocal 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, insideTableelse--otherwise problem of clearlocal 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, tRowendend--=== D) Jersey, flag functions ===--used from 2 functionslocal 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', '+1937-12-29'}},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'}},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'}},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', '+1946-06-19'},{'Flag of Italy (1861–1946).svg', '+1861', '+1946-06-19'}},Q39 = {'SUI', {'Flag of Switzerland.svg', '+1889-12-12'},{'Flag of Switzerland.svg', '+1879-01-01'}},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', '+1806'}},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', '+1794-05-20', '+2020–07-14'}},Q145 = {'GBR', {'Flag of the United Kingdom (3-5).svg'}},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'}},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-14'}},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'}},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'}},Q916 = {'ANG', {'Flag of Angola.svg', '+1975-11-11'}},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 RepublicQ8646 = {'HKG', {'Flag of Hong Kong.svg'}},Q25228 = {'AIA', {'Flag of Anguilla.svg'}},Q29999 = {'NED', {'Flag of the Netherlands.svg', '+1690'}}, --Kingdom of the NetherlandsQ33946 = {'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 RepublicQ47588 = {'EU', {'Flag_of_the_Basque_Country.svg'}},Q83286 = {'YUG', {'Flag of Yugoslavia (1943–1992).svg'}}, --Socialist Federal Republic of YugoslaviaQ172579 = {'ITA', {'Flag of Italy (1861–1946).svg'}}, --Kingdom of Italy (1861-1946)Q216923 = {'TPE', {'Flag of Chinese Taipei for Olympic games.svg'}}, -- Chinese TaipeiQ268970 = {'AUT', {'Flag of Austria.svg', '+1918-11-12', '+1919-09-10'}}, -- German-Austria (1918-1919)Q713750 = {'FRG', {'Flag of Germany.svg'}}, --West GermanyQ853348 = {'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 GermanyQ13474305 = {'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 inthe flag table will be placed in a tracking category. You can use this to find more flagsto add to the table. ]]-- trackingCategory = '[[Category:Missing flag in Module:Cycling race]]'local entry = flags[countryID]local IOClocal filelocal result = ""if entry thenfor i, v in ipairs(entry) doif i == 1 thenIOC = velseif not date thenfile = v[1]breakelselocal from = v[2]local to = v[3]if (not from or from <= date) and (not to or to > date) thenfile = v[1]breakendendendendendlocal flagpxSize = '20px'if countryID == 'Q39' then flagpxSize = '16px'end -- Small size for an square flag as Switzerlandif file thenresult = '[[File:' .. file .. '|border|' .. flagpxSize ..'|' .. IOC .. ']]'if arwiki_totemplate thenresult = '{{flagicon|' .. IOC .. '}}'endelseif not date thenlocal p41 = firstValue(countryID, "P41") -- P41 is flag imageif p41 thenresult = '[[File:' .. p41 .. '|border|' .. flagpxSize ..'|(Wikidata:' .. countryID .. ')]]'if arwiki_totemplate thenresult = '{{flagicon image|' .. p41 .. '}}'endendelse-- Search flag for specific datelocal p41 = getStatementForTime(countryID, "P41", date) -- P41 is flag imageif p41 thenresult = '[[File:' .. p41.mainsnak.datavalue.value .. '|border|' .. flagpxSize ..'|(Wikidata:' .. countryID .. ')]]'if arwiki_totemplate thenresult = '{{flagicon image|' .. p41.mainsnak.datavalue.value .. '}}'endendendreturn result .. trackingCategoryend-- countryID --> shape ([[France|FRA]])local function uciCodeCountry(countryID)    local uciCode, countryName     local blacklist={Q736=true}if countryID then--get UCI codeif flags[countryID] thenuciCode=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 sitelinkscountryName=country_name_from_list(countryID)if countryName == nil or blacklist[countryID] thencountryName = mw.wikibase.getSitelink(countryID)endif uciCode and countryName thenreturn ' <small>([['..countryName..'|'..uciCode..']])</small> 'endendreturn '' --elseendlocal 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) dofor _, value in pairs(data.stageinfobox_jersey) doif v == value[1] thenif winner_classification == value[2] thenif (timeOfRace >= value[3]) and (timeOfRace <= value[4]) thenjersey = value[5]jerseyWPID = value[6]endendendendend-- local starttime, endtime = '', '+2500'if jersey ~= '' then --and (timeOfRace > starttime) and (timeOfRace < endtime) thenlocal entity_jersey = mw.wikibase.getEntity(jersey)jersey = entity_jersey.claims['P18'][1].mainsnak.datavalue.valuejersey_name = entity_jersey:getLabel(wikilang) or ''if jerseyWPID ~= '' thenlocal entity = mw.wikibase.getEntity( jerseyWPID )local Sitelink = entity:getSitelink(wiki..'wiki') -- link to WParticleif Sitelink ~= nil then jerseyWPID = wiki..':'..Sitelink else jerseyWPID = '' endendreturn jersey, jersey_name, jerseyWPIDelse return '', '', ''endendlocal 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] thenfor _, v in ipairs(h) dolocal jersey_nameif jerseys[v] thenjersey_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 thenjersey_string = jersey_string .. '|' .. jersey_nameendjersey_string = jersey_string .. ']]'elselocal p18 = mw.wikibase.getBestStatements(v, 'P18')if p18[1] and p18[1].mainsnak.snaktype == 'value' thenjersey_string = jersey_string .. '[[File:' .. p18[1].mainsnak.datavalue.value .. '|20px'jersey_name = getLabelFallback(v)if jersey_name thenjersey_string = jersey_string .. '|' .. jersey_nameendjersey_string = jersey_string .. ']]'endendendendreturn jersey_stringend -- function end--=== E) Other (winner) ===local function isHuman(riderId)local isHuman = falseif riderId thenlocal p31 = wikibase.getBestStatements(riderId, 'P31')for _, iOf in pairs (p31) doif iOf.mainsnak.snaktype == 'value' and iOf.mainsnak.datavalue.value.id == "Q5" thenisHuman = truebreakendendendreturn isHumanendlocal function isCountry(inputID)local isCountry = falseif inputID thenlocal p31 = wikibase.getBestStatements(inputID, 'P31')for _, iOf in pairs (p31) do-- exception Hong-Kong and Taiwanif 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") thenisCountry = truebreakendendendreturn isCountryendlocal function isWomenrace(raceID) --for translationfor _, p2094 in statements(raceID, 'P2094') do if p2094.mainsnak.datavalue.value.id == "Q1451845" thenreturn trueendendreturn falseendlocal function isWomenteam(teamID, timeOfRace)if isWomenrace(teamID) then --simplest wayreturn trueend--else we can identify with teamCatlocal _, catID= getTeamLinkCat(teamID, timeOfRace, false)if data.womenCats[catID] thenreturn trueendreturn falseendlocal function getNationality(wID, timeOfRace,q) --for a riderlocal p27, countryID--allow overload of the property, for cases like Russian/BLR ban, or Commonwealth games, only for P1532if q and q.P1532 and q.P1532[1].snaktype == 'value' thencountryID = q.P1532[1].datavalue.value.idelselocal listOfProperty={'P1532','P27'}if wID thenfor _, prop in ipairs(listOfProperty) doif countryID==nil thenp27 = getStatementForTime(wID, prop, timeOfRace) --P27 is country of citizenshiif p27 thencountryID = p27.mainsnak.datavalue.value.idendendendendif wiki=='eu' and (countryID=="Q142" or countryID=="Q29") then --look for people or location in the Basque Country, quite expensive functionlocal birth_place = firstValue(wID, 'P19','id') --birth placeif data.BasqueTown[birth_place] thenreturn "Q47588"endendendreturn countryIDendlocal function subwinner(riderId, timeOfRace, q)local outTable={}local riderTeam, riderLink, countryIDif riderId thenif isHuman(riderId) thenriderLink = getRiderLink(riderId, timeOfRace)countryID = getNationality(riderId, timeOfRace,q)if countryID thenriderLink = flag(countryID, timeOfRace) .. ' ' .. riderLinkendriderTeam = getTeam(riderId, timeOfRace, q) or ''elselocal _riderLink, _, countryID = getTeamLinkCat(riderId, timeOfRace, true)if countryID thenriderLink = flag(countryID, timeOfRace) .. ' ' .. riderLinkendendendreturn riderLink, riderTeamendlocal 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) dolocal wID = winner.mainsnak.snaktype == 'value' and winner.mainsnak.datavalue.value.idlocal wOf, wCause, wCriterion, riderLinklocal q = winner.qualifiersif q thenlocal _, disqualified =isdisqualified(winner,q)if q.P642 and q.P642[1].snaktype == 'value' thenfor _, q642 in pairs(q.P642) dowOf = q642.datavalue.value.id -- P642 is 'of'if not wOf then-- Try P1346 (winner) instead-- Assume Q20882667 ('overall winner general classification') if neither are foundwOf = q.P1346 and q.P1346[1].snaktype == 'value' and q.P1346[1].datavalue.value.id or 'Q20882667'endwCause = 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] thenif wID thenlocal reference = ref and getReference(lf,winner)local _, countryIDif isHuman(wID) thenriderLink = getRiderLink(wID, timeOfRace)if reference thenriderLink = riderLink .. referenceendif team thenlocal riderTeam = getTeam(wID, timeOfRace, q)if riderTeam thenriderLink = riderLink .. ' (' .. riderTeam .. ')'endendelseif isCountry(wID) thenriderLink = flag(wID, timeOfRace).." "..getCountryName(wID) if reference thenriderLink = riderLink .. referenceendcountry=trueelse --teamlocal _riderLink, _, countryID = getTeamLinkCat(wID, timeOfRace, country)if reference thenriderLink = riderLink .. referenceendendif not country thenif not countryID thenif isHuman(wID) thencountryID = getNationality(wID, timeOfRace,q)elsecountryID = getCountryID(wID, timeOfRace)endendif countryID thenriderLink = flag(countryID, timeOfRace) .. ' ' .. riderLinkendendif WDlink_on thenriderLink = riderLink .. ' ' .. wdLink(wID)endelseriderLink = wCriterion and contentLanguage:ucfirst(wikibase.getLabel(wCriterion) or '') or ''if wCause thenlocal cause = wikibase.getLabel(wCause)if cause thenriderLink = riderLink .. ' (' .. cause .. ')'endendendif disqualified==true thenriderLink='<s>'..riderLink..'</s>'endif winnersId and winnersId[wOf] thenif disqualified or ((not wID) and wCriterion) then winnersId[wOf]= 'Q666' --to identify disqualificationelsewinnersId[wOf]= wID --identify cancelledendendif winners[wOf] == '' thenwinners[wOf] = riderLinkelsewinners[wOf] = winners[wOf] .. '<br/>' .. riderLinkendendendendendendendlocal 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']) endreturn resultTableend--------- Definition sub-functions for calendar and victory ------local function getTimeOfRace(raceID, mandatory, p582_prio)local timeOfRace, propertiesif p582_prio then --for case like  UCI Europe Tour 2006 (Q1455600) where most of the competition is in the next yearproperties={'P582','P585','P580'}elseproperties={'P580','P585','P582'}endfor _, prop in ipairs(properties) dotimeOfRace= firstValue(raceID, prop, 'time')if timeOfRace ~= nil then return timeOfRace endendlocal link = getSitelinkFallback(raceID, {'en', 'fr', 'de','es'}) --language is not important here, it is just to get the yearif link thenlocal year = string.match(link, '%d%d%d%d')if year thenreturn year .. '-01-01T00:00:00Z'endendif wiki == "ar" thenreturn '+1970-01-01T00:00:00Z'endif mandatory thenerror('> Wikidata is missing data about start time (P580) or point in time (P582)')endreturn nilendlocal 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" thenstyle1='verylong' --force to display the yearstyle2='long'elsestyle1='small'style2='small'endif sTime and eTime thenlocal 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, trueendelselocal pTime = firstValue(entityID, 'P585', 'time') -- P585 is 'point in time'if pTime thenreturn funcDate(pTime, style2), pTime, falseendendreturn nilendlocal function fn_date(entityID, functionName)  --to move as a general functionlocal 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' endlocal 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), sortkeyendlocal function fn_country(entityID, timeOfRace,country, raceCell, parentID)-- This function gives countries where the race take place-- parentID taken from fn_race, optionallocal country_str, country_name, country_flaglocal 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) endif countryID thencountry_flag=flag(countryID, timeOfRace)country_str=country_flagcountry_name = getCountryName(countryID)if country_name~='' thentCell:attr('data-sort-value',country_name)if country~= false then country_str=country_str.." "..country_nameendendelsecountry_flag="no flag"endif country==false thentCell:wikitext(country_flag.." "..(raceCell or ''))country_name=''elseif country_str then tCell:wikitext(country_str) endendreturn country_flag, country_name, tCellendlocal function commaStage(stageID,raceLabel) --how to write "stage, "local outTable={}local stageNumber=''local subStage = ''local stageNumberonly, stageLetterlocal temp=firstValue(stageID, 'P1545')if temp then stageNumber = temp endif stageNumber=='0' then --prologuestageNumber= translate("victories",9)elseif stageNumber==nil thenstageNumber= translate("victories",8)else--look for subStagelocal i,j = string.find(stageNumber, "%a+") --if letter in the stage numberif i ~= nil then --we have to do somethinglocal k,l = string.find(stageNumber, "%d+") --select the number in the stage numberstageNumberonly = string.sub(stageNumber, k, l)--cut the string in 2stageLetter = string.sub(stageNumber, i, j)stageNumber=stageNumberonlyif stageLetter ~= nil then subStage=stageLetter endendif wiki == 'ar' thenstageNumber= translate("victories",8)..' '..number('f', tonumber(stageNumber), wiki)elsestageNumber= number('f', tonumber(stageNumber), wiki)..subStage..' '..translate("victories",8)endendendlocal comma = ", "if wiki == 'ar' then comma = " ، " endif wiki == 'fr' thenlocal 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) doif string.find(raceLabel, v.name) thencomma = v.articlebreakendendendif wiki == 'fr' or wiki=="ca" or wiki=="es" or wiki=="ast" thenoutTable["prefix"]=stageNumber..commaoutTable["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" thenoutTable["prefix"]=''outTable["postfix"]=comma..stageNumberendreturn outTableendlocal function getMainRaceLink(entityID,entity_type,stageID, functionName,timeOfRace) --the link to the edition but with a general namelocal instanceOf, instanceOfTemp, label, Sitelink, isclass, prefix, postfixlocal arlabellocal stage_link=falseif stageID thenSitelink=wikibase.getSitelink(stageID)if Sitelink then stage_link=true endendif Sitelink==nil thenSitelink=wikibase.getSitelink(entityID)endprefix=''; postfix='' --general classificationlistOfProperty={'P2561','P1448'}        --main race link is in the parent--can be improvedfor _, p31 in statements(entityID, 'P31') doinstanceOfTemp = p31.mainsnak.datavalue.value.idif instanceOfTemp ~= "Q27020041" and instanceOfTemp ~= 'Q88903067' and data.class_dic[instanceOfTemp]==nil then--but the main raceinstanceOf=instanceOfTempendend    --get information from the parentif instanceOf then--look forfor _, prop in ipairs(listOfProperty) dofor _, p2561 in statements(instanceOf, prop) do --name for championshipif label==nil thenlocal lang_WD = p2561.mainsnak.datavalue.value.languageif wiki == lang_WD thenlocal nametemp = p2561.mainsnak.datavalue.value.textif timeOfRace~= nil thenlocal q = p2561.qualifiersif q thenlocal temp = checktime(nametemp,q,timeOfRace)if temp then label = nametemp end--if the time is correct than it is finishedelselabel = nametemparlabel = labelendendendendendendif label==nil thenlabel=getLabelFallback(instanceOf,lang_priority) --the case of 'ar' should be handled in lang_priorityif not label thenlabel=getLabelFallback(entityID,lang_priority) or ''endendif Sitelink==nil and entity_type~=0 then --only if no link to the race directSitelink=wikibase.getSitelink(instanceOf)endif Sitelink==nil and entity_type==0 then --only for champlocal temp=firstValue(entityID, 'P361','id') --temp is NC France 2019 for instanceif temp then Sitelink= wikibase.getSitelink(temp) endif Sitelink == nil thenlocal temp2=firstValue(entityID, 'P31','id') -- French NC Men ITTif temp2 thenSitelink= wikibase.getSitelink(temp2)  if Sitelink == nil thenlocal temp3=firstValue(temp2, 'P361','id') -- French NC ITTif not temp3 then temp3=firstValue(temp2, 'P31','id') endif temp3 thenSitelink= wikibase.getSitelink(temp3)  if Sitelink == nil thenlocal temp4=firstValue(temp3, 'P361','id') -- French NC if not temp4 then temp4=firstValue(temp3, 'P31','id') endif temp4 thenSitelink= wikibase.getSitelink(temp4)  endendendendendendendend--affect the labelif label==nil thenlabel=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 createdif entity_type==2 thenif functionName~=nil then --calendar=nilif wiki == 'fr' then prefix= translate("victories",1)..', ' --general classificationelseif wiki == 'ar' then postfix ='، '..translate("victories",1)else postfix = ', '..translate("victories",1)endendelseif entity_type=='stage' then--how to write "stage, " is concentrated in one functionlocal commaTable=commaStage(stageID, label)prefix= commaTable["prefix"]postfix=commaTable["postfix"]endif Sitelink == nil thenif wiki == 'ar' then label = make_IllWD2_link(entityID,arlabel,label)endreturn prefix..label..postfixelseif stage_link thenreturn '[['..Sitelink..'|'..prefix..label..postfix..']]'elsereturn prefix..'[['..Sitelink..'|'..label..']]'..postfixendend--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 infolocal function classToCircuit(classID, entityID, child, q) local displayedCircuitID, circuitIDif classID thenif classID=='Q23005601' or classID=='Q23005603' then --1WWT 2WWT cleardisplayedCircuitID = 'Q21075974'elseif classID=='Q22231106' or classID=='Q22231107' then --1UWT 2UWT cleardisplayedCircuitID = 'Q635366'else --we have to look in the itemif child then --for instance Flèche wallonne 2020for _, p361 in statements(entityID, 'P361') docircuitID = p361.mainsnak.datavalue.value.idfor _, p31 in statements(circuitID, 'P31') do --is it a UCI circuit?parentCircuitID = p31.mainsnak.datavalue.value.idif data.UCI_Circuits[parentCircuitID] thendisplayedCircuitID=circuitIDendendendelse --for instance Flèche wallonneif q thenif q.P642 and q.P642[1].snaktype == 'value' and q.P642[1].datavalue.value.id thendisplayedCircuitID = q.P642[1].datavalue.value.idendendendendendreturn displayedCircuitIDendlocal function getStartEndfromQuali(q) --return sTime and eTime as datelocal sTime, eTimeif q thenif q.P580 and q.P580[1] and q.P580[1].snaktype == 'value' then -- P580 is start timesTime = q.P580[1].datavalue.value.timeendif q.P582 and q.P582[1] and q.P582[1].snaktype == 'value' then -- P582 is end timeeTime = q.P582[1].datavalue.value.timeendendreturn sTime, eTimeendlocal function funcDateFigure(date,mode)local y, m = string.match(date, "(%d+)-(%d+)-%d+")if mode=='Y' or m=='00' or not m thenreturn yelseif y thenreturn string.gsub(m,'0','').."."..yelsereturn nilendendlocal function getPeriodSubSub(sTime, eTime, startTime,endTime,brackets)local periodif sTime and eTime thenif startTime==endTime thenperiod=startTime --only (1990)elseperiod=startTime .. '-'..endTimeendelseif sTime thenperiod=startTime .. '-'elseif eTime thenperiod='-'..endTimeelseperiod=""endif brackets and period~="" thenperiod="("..period..")"endreturn periodendlocal function getPeriodSub(sTime, eTime, brackets) local startTime, endTime, y, m, y2, m2if sTime theny, m = string.match(sTime, "(%d+)-(%d+)-%d+")if m=='00' or m=='01' then startTime= funcDateFigure(sTime, 'Y')elsestartTime= funcDateFigure(sTime,'m') endendif eTime theny2, m2 = string.match(eTime, "(%d+)-(%d+)-%d+")if m2=='00' or m2=='12' thenendTime=funcDateFigure(eTime, 'Y')elseendTime=funcDateFigure(eTime, 'm')endendreturn getPeriodSubSub(sTime, eTime, startTime,endTime,brackets)endlocal function getPeriodSub_season(sTime, eTime, brackets) local startTime, endTimeif sTime and eTime thenstartTime, endTime = getStartEndTime(sTime, eTime, 'small')elseif sTime thenstartTime=funcDate(sTime, 'small')elseif eTime thenendTime=funcDate(eTime, 'small')endreturn 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 thenreturn getPeriodSub_season(sTime, eTime, brackets), sTimeelsereturn getPeriodSub(sTime, eTime, brackets), sTimeendend-- For infoboxlocal function getClass(entityID)local classLink, circuitID, circuitLinklocal classTable={}for ii, p279 in statements(entityID, 'P279') doif p279 and p279.mainsnak.snaktype == 'value' thenlocal classID = p279.mainsnak.datavalue.value.idif 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})endendendendif #classTable~=0 thentable.sort(classTable, function(a, b) return a[1] < b[1] end)endfor _, class in pairs(classTable) doif not str then str='' else str=str..'<br>' endstr=str..class[2]if class[3] thencircuitLink=WPlinkpure(class[3])endend    return str, circuitLink, #classTableendlocal function fn_race(entityID,displayed_class,display_class,timeOfRace, functionName,country)--return link to the race and class--first function read from victory mainlocal Sitelink, entity_type, classID, stageID, race_tCell, class_tCell, parentIDfor _, p31 in statements(entityID, 'P31') doif data.stages[p31.mainsnak.datavalue.value.id] thenentity_type = 'stage'  --then the class is one stage above!parentID = getParentID(entityID)classID=firstValue(parentID, 'P279', 'id') stageID= entityID --everything slide from one rankentityID = parentIDendend--Now we have the class and know the type of race it isif entity_type == 'stage' thenSitelink=getMainRaceLink(entityID,entity_type,stageID, functionName,timeOfRace)elseclassID=firstValue(entityID, 'P279', 'id')Sitelink=getMainRaceLink(entityID,data.class_dic[classID],nil, functionName,timeOfRace)endif country~=false thenlocal tCell=mw.html.create('td'):cssText("text-align:".. textalign ..";padding:0 2.3em"):wikitext(Sitelink)race_tCell=tostring(tCell)elserace_tCell=Sitelink --already openedendif display_class == true and classID~=nil and (displayed_class==nil or displayed_class[classID]~=nil) thenlocal circuitID=classToCircuit(classID, entityID, true,nil) local classLink=classLinkFn(classID,circuitID) --return '' worst caseclass_tCell=mw.html.create('td'):attr('data-sort-value',data.class_sort[classID]) --sortkey:cssText("text-align:center;padding:0 0.5em"):wikitext(classLink)endreturn parentID, race_tCell, class_tCellendlocal function fn_rider(lf,entityID,timeOfRace,display_team,only_winner,country)local winners, countrytemp, resultlocal WDlink_on = (wiki == "mk" or wiki == "ja")local thereisawinner=falseif only_winner == 1 thenwinners = {Q20882667 = '', Q20882747=''} -- first, general or stageelseif only_winner == 0 thenwinners = { Q20882667 = '', Q20882668 = '',Q20882669 = ''} -- Q20882668 is 'second overall'else --3winners = { Q47640757='' } -- World Tour -- name not used hereendif country==nil then countrytemp=false else countrytemp=country endwinner(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 thentCell: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)elselocal tempwinnerif only_winner == 1 thenif winners.Q20882667~=nil and winners.Q20882667~='' thentempwinner=winners.Q20882667elsetempwinner=winners.Q20882747endelsetempwinner=winners.Q47640757endif tempwinner~='' and tempwinner~=nil then thereisawinner=true endreturn tCell:wikitext(tempwinner), thereisawinnerendendlocal function compareDate(tdate) --test futureif tdate thenlocal 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'] thenreturn trueelseif tYear<today['year'] thenreturn false  --the last race is the futureelseif tMonth>today['month'] thenreturn trueelseif  tMonth<today['month'] thenreturn falseelseif tDay>today['day'] thenreturn trueelseif  tDay<today['day'] thenreturn falseelsereturn false --arbitraryendendendelsereturn false --arbitraryendendlocal function calculateAge(birthDate, endDate) --test futurelocal eYear, eMonth, eDaylocal longestcontractyears=10if birthDate thenif not endDate thenlocal today=os.date("*t")     eYear=today['year']    eMonth=today['month']    eDay=today['day']elselocal _, _, y, m, d = string.find(endDate, "(%d+)%p(%d+)%p(%d+)")eYear=tonumber(y)eMonth=tonumber(m)eDay=tonumber(d)endlocal _, _, y, m, d = string.find(birthDate, "(%d+)%p(%d+)%p(%d+)")local tYear=tonumber(y)local tMonth=tonumber(m)local tDay=tonumber(d)local alreadyThisYearif eMonth>tMonth thenalreadyThisYear=trueelseif  eMonth<tMonth thenalreadyThisYear=falseelseif eDay>tDay thenalreadyThisYear=trueelseif  eDay<tDay thenalreadyThisYear=falseelsealreadyThisYear=trueendendif alreadyThisYear thenreturn eYear-tYear, tYear, eYear+longestcontractyearselsereturn eYear-tYear-1, tYear, eYear+longestcontractyearsendelsereturn 0, tYear, eYear+longestcontractyearsendendlocal function evaluateWinnerMax(t)local winners = t.vainqueurlocal resultlocal most_wins = 0local most_wins_ID = {}for winnerID, winner in pairs(winners) doif winner.count > most_wins thenmost_wins = winner.countmost_wins_ID = { winnerID }elseif winner.count == most_wins thenmost_wins_ID[#most_wins_ID + 1] = winnerIDendendif most_wins > 1 thenfor _, id in pairs(most_wins_ID) doif not result thenresult=winners[id].linkelseresult=result.."<br>"..winners[id].linkendendlocal _, gen_singular, gen_plural=plural(most_wins)if gen_singular then --slavic plural, 1 victory is not displayedword_victory=translate("raceinfobox",29)elseif gen_plural thenword_victory=translate("raceinfobox",30)elseword_victory=translate("raceinfobox",32) --singularendresult=result.."<br>("..tostring(most_wins).." "..word_victory..")"endt.maxWinner=resultendlocal function listOfWinners(itemID,t, team,lf, mandatory_prop)local winners = {Q20882667 = '',}-- Q20882667 is 'overall winner general classification'local winnersId={Q20882667 = '',}--to detect disqualificationlocal WDlink_on, sitelinkif wiki == "mk" or wiki == "ja" or wiki == "ru" then WDlink_on = true else WDlink_on = false end    -- Get the date to sort the editionsfor _, p527 in statements(itemID, 'P527') do  --_, p527local raceDate, year, raceID, entity_race, a, b raceId = p527.mainsnak.datavalue.value.id -- Qnumbers of the parts of a tourraceDate=getTimeOfRace(raceId)table.insert(t.race, { raceId=raceId, raceDate=raceDate, future=compareDate(raceDate)} ) --check if futuretable.sort(t.race, function(a,b) return a['raceDate'] < b['raceDate'] end) -- t.race is sorted after yearend --look for the next racelocal lastRunEdition, lastEditionDate, nextEditionfor num, race in ipairs(t.race) doif race['future'] thennextEdition=numbreakendend--Get the winnerslocal numberOfEditions=0local lastWinner, winnerIdif not team then --for race, a test shall be performedfor num=1,#t.race dowinners.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 pastif winnersId.Q20882667~="Q30108381" then --cancellednumberOfEditions=numberOfEditions+1lastRunEdition=numlastEditionDate=t.race[num]['raceDate']lastWinner=winners.Q20882667endendwinnerId=winnersId.Q20882667if winnerId~=nil and winnerId~='' and winnerId~='Q666' and winnerId~='Q30108381' then --code for disqualificationif not t.vainqueur[winnerId] thent.vainqueur[winnerId]={}t.vainqueur[winnerId].link=winners.Q20882667t.vainqueur[winnerId].count=0endt.vainqueur[winnerId].count=t.vainqueur[winnerId].count+1endendelse --for team the check is lighterfor num=1,#t.race doif t.race[num]['future']==false then --in the pastif mandatory_prop==nil thennumberOfEditions=numlastRunEdition=numlastEditionDate=t.race[num]['raceDate']elselocal ss = wikibase.getAllStatements(t.race[num]['raceId'], mandatory_prop)if #ss >0 thennumberOfEditions=numlastRunEdition=numlastEditionDate=t.race[num]['raceDate']endendendendendlocal monthId=firstValue(itemID, 'P2922','id') if monthId then t.lastEditionMonth=getLabelFallback(monthId) or ''elset.lastEditionMonth=contentLanguage:formatDate("M", lastEditionDate)endif lastEditionDate thent.lastEditionYear=funcDate(lastEditionDate,"onlyyear")   endt.numberOfEditions=numberOfEditionsif not team then evaluateWinnerMax(t) endif lastRunEdition thent.lastWinner=lastWinner or '' --t.vainqueur[lastRunEdition]['link']t.lastID=t.race[lastRunEdition]['raceId']sitelink = wikibase.getSitelink(t.lastID)if sitelink ~= nil thent.lastLink = "[[" .. sitelink .. "]]"elset.lastLink = nilendendif nextEdition then t.nextID=t.race[nextEdition]['raceId']sitelink = wikibase.getSitelink(t.nextID)if sitelink ~= nil thent.nextLink = "[[" .. sitelink .. "]]"elset.nextLink = nilendendendlocal function getPeriodicity(itemID, t)local p = wikibase.getBestStatements(itemID, 'P2257')if p[1] and p[1].mainsnak.snaktype == 'value' thenlocal period=p[1].mainsnak.datavalue.value.amountlocal periodunit=p[1].mainsnak.datavalue.value.unitif tonumber(period)==1 and periodunit == 'http://www.wikidata.org/entity/Q577' thenreturn translate("raceinfobox",1).." ("..t.lastEditionMonth ..")"elseif tonumber(period)==1 and periodunit == 'http://www.wikidata.org/entity/Q5151' thenreturn translate("raceinfobox",2)elsereturn nilendelsereturn nilendendlocal function getType(itemID)local result, typeIDtypeID =firstValue(itemID, 'P31', 'id')if typeID ~= nil thenif typeID=="Q2912397" and wiki=="fr" thenresult="[[Cyclisme_sur_route#Épreuve_d'un_jour|Course d'un jour]]"elseresult=WPlinkpure(typeID)endend --else result=nil   return result  endlocal function getFormerNames(itemID, PID, season)local listOfNames={}local officialname,languagelocal kk=1while #listOfNames == 0 and kk<=#lang_priority dolang=lang_priority[kk]kk=kk+1for _, prop in ipairs({PID}) dofor _, p1813 in statements(itemID, prop) dolanguage = p1813.mainsnak.datavalue.value.languageofficialname = p1813.mainsnak.datavalue.value.textif lang==language then --only exact languagelocal period, sTime=getPeriod(p1813.qualifiers, nil, season)if not sTime then sTime="+1900-01-01T00:00:00Z" end --firsttable.insert(listOfNames,{sTime, period, officialname, language})endendendendtable.sort(listOfNames, function(a, b) return a[1] < b[1] end)return listOfNamesendlocal function officialSite(itemID)local url=firstValue(itemID, 'P856')if url then return '['..url.." "..translate("raceinfobox",3)..']'endreturn nilendlocal function checkkm(p)local km, unitif p[1] and p[1].mainsnak.snaktype == 'value' thenkm = tonumber(p[1].mainsnak.datavalue.value.amount)unit = p[1].mainsnak.datavalue.value.unitif unit == 'http://www.wikidata.org/entity/Q828224' thenreturn kmendendreturn nilendlocal function checkm(p, in_cm)local m, unit, resif p[1] and p[1].mainsnak.snaktype == 'value' thenm = tonumber(p[1].mainsnak.datavalue.value.amount)unit = p[1].mainsnak.datavalue.value.unitif unit == 'http://www.wikidata.org/entity/Q11573' thenres=melseif unit=='http://www.wikidata.org/entity/Q174728' then --cmres=m*0.01endif res thenif in_cm thenres=res*100endreturn resendendreturn nilendlocal function checkkmh(p)if p[1] and p[1].mainsnak.snaktype == 'value' thenkmh = tonumber(p[1].mainsnak.datavalue.value.amount)unit = p[1].mainsnak.datavalue.value.unitif unit == 'http://www.wikidata.org/entity/Q180154' then -- Q180154 is 'kilometre per hour'return kmhendendreturn nilendlocal function checkkg(p)local kg, unitif p[1] and p[1].mainsnak.snaktype == 'value' thenkg = tonumber(p[1].mainsnak.datavalue.value.amount)unit = p[1].mainsnak.datavalue.value.unitif unit == 'http://www.wikidata.org/entity/Q11570' thenreturn kgendendreturn nilendlocal function formatNumber(e, addUnit, trans)local textif e thentext = contentLanguage:formatNum(e)if wiki == 'fo' thentext = string.gsub(text, "%.", ",")endif addUnit thenlocal t=translate("unit",trans)if string.find( t," ")==1 thentext = text ..telsetext = text .. ' ' ..tendendendreturn textendlocal function getHeight(entityID, in_cm)local p = mw.wikibase.getBestStatements(entityID, 'P2048')if in_cm thenreturn formatNumber(checkm(p, in_cm), true, 11)elsereturn formatNumber(checkm(p, in_cm), true, 9)endendlocal function getWeight(entityID)local p = mw.wikibase.getBestStatements(entityID, 'P2067')return formatNumber(checkkg(p), true, 10)endlocal 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 stagelocal stagep, tempkmfor _, p527 in statements(raceID,'P527') dostagep=mw.wikibase.getBestStatements(p527.mainsnak.datavalue.value.id, 'P3157')tempkm=checkkm(stagep)if tempkm thenif not km then km=0 endkm=km+tempkmendendendreturn formatNumber(km, addUnit, 8), kmendlocal function getElevation(raceID)local p =mw.wikibase.getBestStatements(raceID, 'P7297')return formatNumber(checkm(p), true, 9)endlocal function getSpeed(raceID, addUnit,kmdistance, property)local timeOfRacelocal p = mw.wikibase.getBestStatements(raceID, 'P2052') -- P2052 is 'speed'local kmh=checkkmh(p)if not kmh and kmdistance then --calculate speedlocal p2321= wikibase.getBestStatements(raceID, property) --winner supposed to be first of overall classificationif p2321 and p2321[1] and p2321[1].mainsnak.snaktype == 'value' thenlocal q = p2321[1].qualifiersif q and q.P1352 and q.P1352[1].snaktype == 'value' then --rankfor _, q1352 in pairs(q.P1352) dorank = tonumber(q1352.datavalue.value.amount)endif rank == 1 thentimeOfRace=qualifieramount(p2321[1], 'P2781') --get timeendendif timeOfRace thenkmh=math.modf(1000*kmdistance/(timeOfRace/3600))/1000endendendreturn formatNumber(kmh, addUnit, 5)endlocal function getGenderCode(riderID, default)local gender=default -- default is for teams, n or flocal g = firstValue(riderID, 'P21', 'id')if g == 'Q6581097' then gender = 'm' -- Maleelseif g == 'Q6581072' then gender = 'f' -- Femaleelseif g == 'Q1052281' then gender = 't' -- Transgenreendreturn gender endfunction number(gender, b, wiki)local strif b==nil or b=="" then return "" endif wiki=="ar" thenstr = belseif wiki == "ca" thenif 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.."è"endelseif wiki=="es" thenif gender == 'm' or gender == 'n' then str = b..".º"elseif gender == 'f' then str = b..".ª"else str = b.."."endelseif wiki=="fr" thenif b==1 thenif 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>"endelse str=b.."<sup>e</sup>"endelseif wiki=="nl" then str=b.."e"elseif wiki=="ru" then str=b.."-й"elseif wiki=="eo" then str=b.."-a"elseif wiki=="ast" thenif gender == 'm' or gender == 'n' then str = b.."ᵘ"elseif gender == 'f' then str = b.."ª"else str = b.."."endelse str = b .. ". "endreturn strendlocal function calculateTime(t)local time = tonumber(t)local h, m, s = 0, 0, 0local str = ''if time == nil then return '' endif time < 60 then s = timeelseif time < 3600 then m = math.modf(time/60) s = time - m*60else h = math.modf(time/3600) m = math.modf((time - h*3600)/60) s = time - h*3600 - m*60endif h>0 then str = str..mw.ustring.format ('%i'..translate("unit",2), h) endif m>=0 and h>0 then str = str.. mw.ustring.format('%02i'..translate("unit",3), m) endif m>0 and h==0 then str = str.. mw.ustring.format('%i'..translate("unit",3), m) endif s>=0 and (h>0 or m>0) then str = str.. mw.ustring.format('%02i'..translate("unit",4), s) endif s>=0 and h==0 and m==0 then str = str.. mw.ustring.format('%i'..translate("unit",4), s) endreturn str --time..': '..h..' '..m..' '..sendlocal 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  -- defaultreturn l10n[x]endlocal 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 thenl10n = ''endreturn l10nendlocal function getStageLabel(inp)local alocal b='' local this_label=''if inp thena, _ = string.gsub(inp, "%a", "") -- 20, not 20aif string.find(inp, "%a") then b = string.sub(inp, string.find(inp, "%a"))endif inp == "0" then this_label = translate("func_prologue",1)else    this_label = stageLink(inp, a, b)endendreturn this_labelend--[[ 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 thenfor _, s in statements(raceID, 'P3450') do-- for items using P3450local q = s.qualifiersif q thenif not previousID and q.P155 and q.P155[1] andq.P155[1].snaktype == 'value' thenpreviousID = q.P155[1].datavalue.value.idendif not nextID and q.P156 and q.P156[1] andq.P156[1].snaktype == 'value' thennextID = q.P156[1].datavalue.value.idendendendendif not previousID and not nextID thenreturn ''endlocal 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_labelif previousID thenif stage  then local series_ordinal= firstValue(previousID, 'P1545', 'value') this_label=getStageLabel(series_ordinal)elsethis_label = getYear(previousID)endlocal link = wikibase.getSitelink(previousID)if link thenpreviousText = '<span style="color:#3366CC">[[' .. link .. '| ' .. previous_sign .. this_label .. ']]</span>'elsepreviousText = '<span style="color:#3366CC">' .. previous_sign .. '</span> ' .. this_labelendendif nextID thenif stage thenlocal series_ordinal= firstValue(nextID, 'P1545', 'value')this_label=getStageLabel(series_ordinal)elsethis_label = getYear(nextID)endlocal link = wikibase.getSitelink(nextID)if link thennextText = '<span style="color:#3366CC">[[' .. link .. '|' .. this_label .. next_sign .. ']]</span>'elsenextText = this_label .. ' <span style="color:#3366CC">' .. next_sign .. '</span>'endendlocal 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%')endreturn outTableend--== 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}endlocal function infoGetOthers(others, entityID)if not others[1].content then --pictureothers[1].content, others[2].content = getLogo(entityID)if not others[1].content thenothers[1].content, others[2].content = getImage(entityID) -- picture, captionendendif not others[3].content then  -- mapothers[3].content, others[5].content = getMap(entityID)  -- P242 is 'locator map image'endif not others[4].content then  -- mapothers[4].content, others[6].content = getSectionalView(entityID) -- sectional_viewendendlocal function infoGetPlaceOrCountry(details,index, entityID, timeOfRace, PID) --generalized infoGetCountryif not details[index].content then -- country-- This function gives countries where the race take placelocal place = {}    if not place[1] then for _, p17 in statements(entityID, PID) do -- P17 is 'country'local countryID = p17.mainsnak.datavalue.value.idif PID=='P17' thenplace[#place + 1] = flag(countryID, timeOfRace) .. ' ' .. getCountryName(countryID) elseplace[#place + 1] =  wikibase.getLabel(countryID)endendendif place[1] thenif #place > 1 thendetails[index].name = details[index].name_pluralenddetails[index].content = table.concat(place, '<br/>')endendendlocal function infoGetPlace(details,index, entityID, timeOfRace)infoGetPlaceOrCountry(details,index, entityID, timeOfRace, "P276")endlocal function infoGetCountry(details,index, entityID, timeOfRace)infoGetPlaceOrCountry(details,index, entityID, timeOfRace, "P17")endlocal function infoGetStartEnd(details,index, entityID, timeOfRace)if not details[index].content then -- start placelocal place = firstValue(entityID, 'P1427', 'id') -- P1427 is 'start point'details[index].content = place and getPlaceLink(place, timeOfRace)endif not details[index+1].content then -- end placelocal place = firstValue(entityID, 'P1444', 'id') -- P1444 is 'destination point'details[index+1].content = place and getPlaceLink(place, timeOfRace)endendlocal function infoGetParticipants(details,index, entityID)-- Function that give the number of cyclists at the beginning and at the finishing of a racefor _, 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.idif location == "Q529711" then -- Q529711 is 'beginning'if not details[index].content then details[index].content = amount end -- participants at startelseif location == "Q12769393" then -- Q12769393 is 'end'if not details[index+1].content then details[index+1].content = amount end -- participants at endendendendendlocal function infoInitTab(width, name, icon, cellpadding)if width==nil then width= '320px' endlocal tab = mw.html.create('table'):addClass('infobox')if wiki == "eo" thentab:cssText(standardtablecss):css('width','23em')elsecellpadding=tostring(cellpadding or 4)tab:attr('cellpadding',cellpadding):attr('cellspacing','0'):cssText(standardtablecss):cssText("float:"..floatinfobox.."; max-width:"..width)endlocal 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 tabendlocal function addARow(name, content)local tRowif content thentRow= 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)endreturn tRowendlocal function addATitle(title)local tRowif title thentRow= mw.html.create('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('background-color',backgroundColor):css('font-weight','bold'):wikitext(title)endreturn tRowendlocal function infoFillOthersDetails(tab, others, details,title, pxmax)if not pxmax thenpxmax="300px"endif others and others[1].content then -- picturetab: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 -- captiontab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%'):wikitext(others[2].content)endendif details thentab:node(addATitle(title))for _, row in ipairs(details) do    tab:node(addARow(row.name, row.content)) --node check itself if nilendendendlocal function infoFillOthersMap(tab, others)if others[3].content then -- maptab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):wikitext("[[File:".. others[3].content .. "|center|300px]]")if others[5].content then -- captiontab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%'):wikitext(others[5].content)endendif others[4].content then -- maptab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):wikitext("[[File:".. others[4].content .. "|center|300px]]")if others[6].content then -- captiontab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%'):wikitext(others[6].content)endendendlocal function wdDoc(tab, s, translation, ID)local tCell=tab:tag('tr'):tag('td')local tC, linklocal commons_cat=firstValue(ID, 'P373', 'id')if commons_cat thencommons_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:75%'):wikitext(icon):tag('td')elsetC=tCell:attr('colspan','2')endif wiki == "ar" thenlink = wdLink(ID) .." [[" .. s .. "|" .. translation .. "]]"elselink = "[[" .. s .. "|" .. translation .. "]] "..wdLink(ID)endtC:cssText('text-align:right; border-top:3px solid '..backgroundColor..'; font-size:75%'):wikitext(link)endlocal function listWPlink(details, index, entityID, PID, bool_link)local org={}for _, p in statements(entityID, PID) do if p and p.mainsnak.snaktype == 'value' thenif bool_link thentable.insert(org,WPlinkpure(p.mainsnak.datavalue.value.id))elselocal label=wikibase.getLabelByLang(p.mainsnak.datavalue.value.id, wiki)table.insert(org,label)endendendif org[1] thenif #org > 1 thendetails[index].name = details[index].name_pluralenddetails[index].content = table.concat(org, '<br/>')endend--Display in a chronological order fields in a tablelocal function listWPlinkChrono(details, index, entityID, listOfProperty, option, initialYear, display_flag, comma,season)local period, sTime, value, ID, templocal list={}if not initialYear then initialYear="1900" endif not details[index].content thenfor _, prop in ipairs(listOfProperty) doif #list==0 then --if P1532 is used P17 is not usedfor _, p in statements(entityID, prop) doif p and p.mainsnak.snaktype == 'value' thenID=p.mainsnak.datavalue.value.idif p.qualifiers thenperiod, sTime=getPeriod( p.qualifiers, true,season)endif not sTime then sTime="+"..initialYear.."-01-01T00:00:00Z" end --firstif option =='label' thenvalue=wikibase.getLabelByLang(ID, wiki)elseif option == 'country' thenvalue=getCountryName(ID)if display_flag thenvalue= flag(ID, sTime).." "..valueendelseif option=='officialname' thenvalue=getOfficialName(ID, sTime,false) --official name is necessary because of continental team change in ProTeamelseif option =='place' thenvalue=getPlaceLink(ID, sTime)elseif option=='UCIcode' thenvalue=getTeamCodeCat(entityID, sTime) --! getTeamCodeCat uses teamIDelseif option=='money' thenlocal amount=p.mainsnak.datavalue.value.amountlocal unit=p.mainsnak.datavalue.value.unitvalue=dispmoney(amount, unit) or ''else --ridervalue=getRiderLink(ID, sTime)endif value thentable.insert(list,{sTime,period,value})endendendendendif #list ~=0 thentable.sort(list, function(a, b) return a[1] < b[1] end)endlocal separator='<br/>'if comma then separator=', ' endif list and #list==1 thendetails[index].content=list[1][3] or ''elseif list and #list~=0 thendetails[index].name = details[index].name_pluraldetails[index].content=''for _, v in pairs(list) dotemp=v[3] or ''if v[2] thentemp=temp..' <small>'..v[2]..'</small>'..separatorelsetemp=temp..separatorenddetails[index].content=details[index].content..tempendendendend-- == Functions for team rosterlocal function getReason(riderReason, riderRef, p527,timeOfRace,riderEnd,lf) --reason for endlocal listofproperty={'P1642','P1643','P1534'}local outTable={}local seasonYear, endYearif timeOfRace thenseasonYear=tonumber(string.sub(timeOfRace, 2, 5))endif riderEnd thenendYear=tonumber(string.sub(riderEnd, 2, 5))end--if not the last season, do not display the reason for endif (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 itfor _,v in ipairs(listofproperty) dofor _, q in qualifiers(p527, v) doriderReason = q.value.idendendif riderReason thenlocal label =string.gsub(getLabelFallback(riderReason,lang_priority), "%b()", "")riderRef = getReference(lf,p527, 1)riderReason = ', ' .. labelendendreturn riderReason, riderRefendlocal function getPosition(riderPosition,v)local stagiaireif riderPosition == nil then -- find the 'position' (P39) of a riderfor _, q in qualifiers(v, 'P39') dostagiaire = q.value.idlocal label = string.gsub(getLabelFallback(stagiaire,lang_priority), "%b()", "")Sitelink = wikibase.getSitelink('Q2328847')if Sitelink then riderPosition=', ' .. "[["..Sitelink .."|"..label.."]]" elseriderPosition =', ' .. labelendendendreturn riderPositionendlocal function trans(date, month, day)if date ~= '' and date~=nil thenlocal _, _, y, m, d = string.find(date, "(%d+)-(%d+)-(%d+)")if m == '00' then m = month endif d == '00' then d = day enddate = '+'..y..'-'..m..'-'..d..'T00:00:00Z'return dateendreturn nilendlocal function parseDate(date, defaultYear, defaultMonth, defaultDay, errortext, etext)local y, m, dlocal date=trans(date, defaultMonth, defaultDay)if not date then date = '+'..defaultYear..'-'..defaultMonth..'-'..defaultDay..'T00:00:00Z'y=defaultYearm=defaultMonthd=defaultDayerrortext=errortext..etextelse_, _, y, m, d = string.find(date, "(%d+)-(%d+)-(%d+)")if not y or y=="0000" then y=defaultYear errortext=errortext..etextenddate = '+'..y..'-'..m..'-'..d..'T00:00:00Z'endreturn date, y, m, d, errortextendlocal function findLastName(label,wiki)if not label then label = '' endlocal _, count = string.gsub(label, " ", " ")local nameslocal a,b,c,d = '', '', '', ''local done = falseif count ~= nil then count = count + 1 else count = 1 endif count > 1 thenif count == 2 thenif label ~= '' thena, b = string.match(label, "(%S+)%s+(%S+)")names = b..' '..aendelselocal name_parts_mk = {'да', 'ди', 'де', 'Де', 'ла', 'Ле', 'тен', 'ван', 'Ван'}local name_parts_ru = {'да', 'ди', 'де', 'Де', 'ла', 'Ле', 'тен', 'ван', 'Ван'}local name_parts    = {'da', 'de', 'di', 'De', 'la', 'Le', 'ten', 'van', 'Van'}if count == 3 and label ~= '' thena, b, c = string.match(label, "(%S+)%s+(%S+)%s+(%S+)")if wiki == 'mk' thenfor _,v in ipairs(name_parts_mk) do if b == v then names = b..' '..c..' '..a done = true break end endelseif wiki == 'ru' thenfor _,v in ipairs(name_parts_ru) do if b == v then names = b..' '..c..' '..a done = true break end endelsefor _,v in ipairs(name_parts) do if b == v then names = b..' '..c..' '..a done = true break end endendif not done thennames = tostring(c)..' '..tostring(a)..' '..tostring(b)done = trueendendif count > 3 and label ~= '' thena, b, c, d = string.match(label, "(%S+)%s+(%S+)%s+(%S+)%s+(%S+)")if wiki == 'mk' thenfor _,v in ipairs(name_parts_mk) do if c == v then names = c..' '..d..' '..a..' '..b done = true break end endfor _,v in ipairs(name_parts_mk) do if b == v then names = b..' '..c..' '..d..' '..a done = true break end endelseif wiki == 'ru' thenfor _,v in ipairs(name_parts_ru) do if c == v then names = c..' '..d..' '..a..' '..b done = true break end endfor _,v in ipairs(name_parts_ru) do if b == v then names = b..' '..c..' '..d..' '..a done = true break end endelsefor _,v in ipairs(name_parts) do if c == v then names = c..' '..d..' '..a..' '..b done = true break end endfor _,v in ipairs(name_parts) do if b == v then names = b..' '..c..' '..d..' '..a done = true break end end endif not done then names = label.."%"..b end --b..' '..c..' '..d..' '..a endendendendreturn names or ''endlocal function findSortKey(riderID, correctlanguage, wikiIsSlavic)--find the last name to sortif wikiIsSlavic and correctlanguage thenlocal label = wikibase.getLabelByLang(riderID, wiki)if label thenlocal nametable = mw.text.split(label, ",")if nametable[2] then --there is a coma so the lastname is firstreturn nametable[1]..nametable[2]else --no comareturn findLastName(label,wiki) endendend--all other caseslabel = 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 reffor _, base in pairs(bases) dolocal 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 resultsref=getReference(lf,p[1], 1)if ref thentable.insert(links, ref) endelsetable.insert(links, ' [' .. base[3] .. p[1].mainsnak.datavalue.value .. " " .. base[1] ..']')endendendif #links == 1 thenreturn translate("race_reference", 1) .. table.concat(links)elseif #links > 1 thenreturn translate("race_reference", 2) .. table.concat(links)elsereturn ''endend--=== B) Calendar ===function p.calendarcustom(frame)local headers={2} --datelocal calendarID, lf =get_and_checkID(frame)local display_numbering=false --defaultlocal country_column=2if istrue(get_arg('display_numbering',frame)) thendisplay_numbering=truetable.insert(headers, 3)country_column=3end    --no_country modify the way the country is displayed    local no_country={}    if istrue(get_arg('no_country',frame)) or wiki == "ar" thenno_country={wiki}end-- country --table.insert(headers, 5)--race--table.insert(headers, 4)local display_class=falseif istrue(get_arg('display_class',frame)) or wiki == "ar" thendisplay_class=truetable.insert(headers, 6)end    table.insert(headers, 7) --winnerlocal only_winner=1if istrue(get_arg('podium',frame)) or wiki == "ar" thenonly_winner =0table.insert(headers, 8) --secondtable.insert(headers, 9)--thirdendlocal display_leader=falseif istrue(get_arg('display_leader',frame)) then display_leader=true table.insert(headers, 10)endlocal display_team =falseif istrue(get_arg('display_team',frame)) thendisplay_team =trueendlocal data_type={}for ii=1,#headers dotable.insert(data_type,'')end    local w_race=isWomenrace(calendarID)local s = {header_function = "calendar", -- translations are in function Calendarheader_1 = 1000, -- translation 1 in function Calendar is printed in the upper part of the table headerheader_2 = headers,-- translations 2, 3, 4, 5, 6 in function Calendar are printed in this ordertitle=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:Sortingitem = 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))endfunction p.calendar(frame)----- function to display UCI calendar of one year --------- based on WWTcalendar function ---------- author: Mr. Ibrahem -----local calendarID --determined laterlocal lf = get_lf(frame)local UCI = data.UCIYearToQlocal 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 = 12local tempdic, year, keyk, yearylocal 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) doyear = get_arg(key,frame) --with lf does not workif not calendarID  and year thenif v[year] thencalendarID = v[year]header_1_number = header_1_tab[key]display_code = display_code_tab[key]keyk=keyyeary=yearendendendif wiki == "ar" thenif not (frame.args["code"] and frame.args["code"] == "2") thendisplay_code = 1endif calendarID == "" and frame.args.test thencalendarID = frame.args.testendendif not calendarID or calendarID == "" then return "" endif display_code == 1 thentempdic=tempdic1if keyk=="UWT" and tonumber(yeary) > 2018 thentempdic.display_leader=false --no more leader after 2018tempdic.header_2 ={2, 3,5, 4, 7, 8, 9}endelsetempdic=tempdic2endif istrue(get_arg('display_numbering',lf)) thentempdic.display_numbering=trueelseif get_arg('display_numbering',lf) and istrue(get_arg('display_numbering',lf)) == nil thentempdic.display_numbering=falseendlocal w_race=isWomenrace(calendarID)local s = {header_function = "calendar", -- translations are in function Calendarheader_1 = header_1_number, -- theader_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:Sortingitem = calendarID,property = 'P527',no_country = no_country_calendar,only_winner = tempdic.only_winner,display_numbering = tempdic.display_numbering,displayed_class = nil, --alldisplay_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))endfunction calendar_main(s, resultTable)--Display the UCI women calendar of one yearlocal lf = s.lflocal calendarID=s.itemlocal 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 "" endendlocal country=getCountryBool(s.no_country)----- Begin of the main part of the codefor kk, p527 in statements(calendarID, 'P527') dolocal 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 displaylocal country_flag, country_name, country_tCell=fn_country(RaceID, timeOfRace, country, race_tCell, parentID) --create the tablelocal tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 5px;")tRow:node(date_tCell)if s.display_numbering == true thentRow:tag('td'):cssText("text-align:center;padding:0 0.5em"):wikitext(tostring(kk))endtRow:node(country_tCell)if country thentRow:node(race_tCell) endif class_tCell then tRow:node(class_tCell) endlocal rider_tCell =fn_rider(lf,RaceID,timeOfRace,s.display_team,s.only_winner)tRow:node(rider_tCell)if s.display_leader==true thenlocal leader_tCell=fn_rider(lf,RaceID,timeOfRace,s.display_team,3)tRow:node(leader_tCell)end---- Add the row to the tabletable.insert(t_Body, {sortkey=date_sortkey, body=tRow})end endreturn sortAndConcat(t_Body, resultTable)endfunction p.nationalchampionships(frame)local calendarroadID, calendarITTID, yearlocal lf=get_lf(frame)local listOfCalendar={data.NationalRoadCyclingChampionships,data.NationalITTCyclingChampionships}for ii, thisCalendar in pairs(listOfCalendar) do --road/ITTfor key, v in pairs(thisCalendar) do --look for the key of the dictionnary, here women/menyear = get_arg(key,frame) --with lf does not workif ((ii==1 and calendarroadID==nil) or (ii==2 and calendarITTID ==nil)) and year thenif v[year] thenif ii==1 thencalendarroadID = v[year]elsecalendarITTID = v[year]endendendendendlocal w_race=isWomenrace(calendarroadID)local s = {header_function = "calendar", -- translations are in function Calendarheader_1 = 19, --header_2 = {5, 20, 21},country_column = 1,data_sort_type = {'', '', ''},   -- -- see https://meta.wikimedia.org/wiki/Help:Sortingitem= calendarroadID,calendarroadID = calendarroadID,calendarITTID = calendarITTID,property = 'P527',year = year,no_country = {}, --no sense here to hide the countrydisplay_team = true,display_countrylink = false, --too expensivew_race=w_race,lf=lf}return nationalchampionships_main(s,tableA(s))endfunction nationalchampionships_main(s, resultTable)--Display the list of national champions for one yearlocal lf = s.lflocal tableChamp, t_Body = {}, {}, {}local timeOfRace ='+'..tostring(s.year).."-01-01T00:00:00Z"local rider_tCell, thereisawinner, parentID, parentParentID, sitelinklocal country_flag, country_name, country_tCelllocal temp=firstValue(s.calendarroadID, s.property)if not temp or temp=="" then s.error_message = 2 if wiki == "ar" then return "" endendlocal listOfCalendarID={s.calendarroadID, s.calendarITTID}--create the table with the informationfor ii, thisCalendarID in ipairs(listOfCalendarID) doif thisCalendarID ~= nil thenfor _, p527 in statements(thisCalendarID, 'P527') dothisID = p527.mainsnak.datavalue.value.idcountry_flag, country_name, country_tCell=fn_country(thisID,timeOfRace,s.country)if country_name == nil thencountry_name="country not found" endsortkey=string.gsub(country_name, 'É', 'E') --case États Unis--create the tableif tableChamp[sortkey]==nil then tableChamp[sortkey]={}tableChamp[sortkey]['countryname']=country_nametableChamp[sortkey]['roadwinner']='<td></td>'tableChamp[sortkey]['ITTwinner']='<td></td>'--look for sitelink to championshipsitelink=nil --reinitif s.display_countrylink then --expensiveparentID = firstValue(thisID, 'P361', 'id') --part ofif parentID then parentParentID = firstValue(parentID, 'P31', 'id') if parentParentID then sitelink = wikibase.getSitelink(parentParentID) endendendtableChamp[sortkey]['sitelink']=sitelinktableChamp[sortkey]['flag']=country_flagend--fill the tablerider_tCell, thereisawinner=fn_rider(lf,thisID,timeOfRace,s.display_team,1,true)if tableChamp[sortkey]['thereisawinner']~=true then --all other casestableChamp[sortkey]['thereisawinner']=thereisawinner endif ii==1 thentableChamp[sortkey]['roadwinner']=rider_tCellelsetableChamp[sortkey]['ITTwinner']=rider_tCellendendendend-- structure the displayfor key, thisRow in pairs(tableChamp) doif thisRow['thereisawinner'] then --there is a winnerlocal tRow = mw.html.create('tr'):cssText( "line-height: 1.8em; padding: 5px;")if thisRow['sitelink']~=nil thentRow:tag('td'):wikitext(thisRow['flag']..' [['..thisRow['sitelink']..'|'..thisRow['countryname']..']]')elsetRow:tag('td'):wikitext(thisRow['flag']..' '..thisRow['countryname'])endtRow:node(thisRow['roadwinner'])tRow:node(thisRow['ITTwinner'])table.insert(t_Body, {sortkey=key, body=tRow})end --no winnerend --end list of keyreturn 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 victoriesheader_1 = 2, -- translation 1 in function victories is printed in the upper part of the table headerheader_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:Sortingitem = tempID,property = 'P2522',no_country = no_country_victories,lf=lf,w_race=w_race}return victory_main(s ,tableA(s))endfunction victory_main(s, resultTable)local lf = s.lflocal __, _, 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 "" endendlocal country=getCountryBool(s.no_country)local t_Body = {}for _, p2522 in statements(s.item, 'P2522') dolocal RaceID = p2522.mainsnak.datavalue.value.idlocal 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=nilif race_tCell~= nil then --otherwise class not to be displayedcountry_flag, country_name, country_tCell=fn_country(RaceID, timeOfRace, country, race_tCell, parentID)--Build the tabletRow:node(date_tCell)if country==true thentRow:node(race_tCell)  --race site link is in fn_countrytableendtRow:node(country_tCell) tRow:node(class_tCell) --classlocal rider_tCell =fn_rider(lf,RaceID,timeOfRace,false,1)tRow:node(rider_tCell)table.insert(t_Body, {sortkey=date_sortkey, body=tRow})end --no winnerend --end list of keyreturn sortAndConcat(t_Body, resultTable)end--== D) Stage infoboxfunction 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 functionlocal 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 timeOfRacelocal temp = firstValue(stageID, 'P31','id')icon = ''if temp and temp ~= 'Q18131152' thenif temp=='Q2266066' or temp=='Q2348250' or temp=='Q485321' then icon = " [[File:Cycling (track) pictogram.svg|35px]]"else icon = " [[File:Cycling (road) pictogram.svg|35px]]" enddetails[3].content = typeofstagelogo(stageID, true).." "..WPlinkpure(temp)endlocal 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)--namelocal race={}if course==nil thentemp = firstValue(stageID, 'P1545')if temp thendetails[2].content =getStageLabel(temp)raceId = getParentID(stageID) --for instance Tour de France 2020if raceId thendetails[2].content = (details[2].content or '') .. '، '.. WPlinkpure(raceId)for k, p31 in statements(raceId, 'P31') do --get Tour de Francerace[k] = p31.mainsnak.datavalue.value.id --for the jerseyendendendend-- This function give a format to dates when P585 (date) is used in a single day racelocal pTime = firstValue(stageID, 'P585', 'time') -- P585 is 'point in time'if pTime thendetails[4].content = funcDate(pTime, 'long')timeOfRace = pTimeendlocal kmdistanceif not details[5].content then details[5].content, kmdistance = getDistance(stageID, true) end -- distanceinfoGetCountry(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 --speedif not details[12].content then local elevation=getElevation(stageID) if  elevation ~= nil then details[12].content =elevation else details[12].content = nil endend --Elevationlocal jerseyWPID, jersey_namelocal 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 possiblecima_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}}}--Winnerfor _, p1346 in statements(stageID, 'P1346') dolocal id_speed, id_time, id_time_gap, id_points_a, id_points_b, type_ofclas, name_ofclaslocal q = p1346.qualifierslocal riderId = p1346.mainsnak.datavalue.value.idid_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 thenlocal 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' thenfor _, vv in pairs(q.P642) dolocal qual = vv.datavalue.value.idif qual~=nil and deprecated~='deprecated' and t_P642[qual] thenif qual=="Q21686770" and t_s['results']['winner_fighting'][1] ~= "" then t_P642[qual][2] = 'winner_fighting2' endtype_ofclas=t_P642[qual][1] --annex or genname_ofclas=t_P642[qual][2] --name of rankinglocal 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 endv['speed']=id_speed if qual=="Q27104271" and t_s.annex.equipe_points['link']==nil thent_s.annex.equipe_points['link']=riderId endif qual=="Q20882922" and t_s.annex.equipe['link']==nil then t_s.annex.equipe['link']=riderId endv['genre'] = getGenderCode(riderId,'f')endendendendendlocal rank, deprecated, prop, order, thisorder-- look into P2417, stage classification, then p2321 gen classificationfor ii, thistable in ipairs({'results','gen'}) doif ii==1 thenprop='P2417'order = {'first', 'second', 'third'}elseprop='P2321'order = {'leader', 'deuxieme', 'troisieme'}endfor _, p2417 in statements(stageID, prop) dolocal q = p2417.qualifiersif q.P1352 and q.P1352[1].snaktype == 'value' thenfor _, q1352 in pairs(q.P1352) dorank = tonumber(q1352.datavalue.value.amount)endif rank == 1 or rank == 2 or rank == 3 thenthisorder=order[rank]local v=t_s[thistable][thisorder]v['rank'] = isdisqualified(p2417, q)local thisid= p2417.mainsnak.datavalue.value.idv['link'],_  = subwinner(thisid, timeOfRace, q) if v['gap'] == nil and v['time'] == nil thenv['gap'] = qualifieramount(p2417, 'P2911') endif v['gap'] == nil and v['time'] == nil thenv['time'] = qualifieramount(p2417, 'P2781') endv['speed'] = qualifieramount(p2417, 'P2052') v['genre'] = getGenderCode(thisid, 'f')endendendendfor _, thistable in ipairs({t_s.results,t_s.gen,t_s.annex}) dofor _, v in ipairs(thistable.order) do --order is the list of all classification namesif thistable[v]['link'] thenthistable.show = true endendend---General tablelocal templocal width= '320px' -- size standard 320px, special 340pxif t_s.annex.show == true and (wiki == 'no' or wiki == '..') then width= '340px' endtab= infoInitTab(width, name, icon)infoFillOthersDetails(tab, others, details,translate("stageinfobox",1,w_race))-- ranking table, general and stagefor _, value_order in ipairs(t_s.order) dolocal thistable =t_s[value_order] --results or gen or annexif thistable.show then -- if a section of the stageinfobox should be showntCell=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 classlocal v=thistable[value]if v['link'] thenlocal a1a1, jersey_name, jerseyWPID = jersey_infobox( value, race, timeOfRace)if a1~='' then v['jersey'] = a1 endif v['speed']  thenif wiki == 'fo' thenv['speed'] = string.gsub(v['speed'], "%.", ",") elselocal lang = mw.language.getContentLanguage()v['speed'] = '('.. lang:formatNum(v['speed'])..translate("unit",5,w_race)..')'endendif v['points'] thenif v['points'] > 1 then temp=translate("unit",7,w_race)else     temp=translate("unit",6,w_race) end v['points'] = v['points']..tempendlocal 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 lefttRow=tTab:tag('tr'):css('vertical-align','top')tCell=tRow:tag('td'):css('font-weight','bold')if v['team']~=nil or v['speed'] ~=nil thentCell:attr('rowspan','2')endtCell: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 breakif v['jersey'] == nil thenif (value_order=='results') and (value=='winner_fighting' or value=='winner_fighting2' or value=='cima_coppi' or value=='cima_pantanii') thentCell:wikitext(translate("stageinfobox",v['translation'],w_race))elsetCell:wikitext(number(v['genre'], key, wiki))endelsetemp=''if jerseyWPID~='' thentemp="|link="..jerseyWPIDendtCell:wikitext("[[File:"..v['jersey'].."|20px|"..title..temp.."]]")endelseif v['jersey'] == nil then tCell:wikitext(title)elseif jerseyWPID=='' thenif jersey_name ~= '' then temp = "|"..jersey_nameelsetemp=''endelse temp= "|link="..jerseyWPIDendtCell:wikitext("[[File:"..v['jersey'].."|20px"..temp.."]]" .. title)endendtRow: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']))endif v['gap'] then tCell:wikitext('+ '.. calculateTime(v['gap']))endtCell:wikitext(v['points'])endtCell=tTab:tag('tr'):tag('td'):attr('colspan','2')if v['team']~=nil and v['speed'] ~=nil then -- team rowtTab2=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 teamtRow:tag('td'):cssText('font-size:85%;vertical-align:top;white-space:nowrap'):wikitext(v['speed'])elseif v['team']~=nil or v['speed'] ~=nil thentCell:cssText("text-align:" .. textalign .. ";padding-left:2px")if v['team'] ~= nil thentCell:wikitext("("..v['team']..")") --add the teamendtCell:tag('span'):cssText("float:right;font-size:85%;"):wikitext(v['speed'])endendendendendinfoFillOthersMap(tab, others)tab:node(getPreviousNextLine(stageID,true))wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/stageinfobox", translate("stageinfobox",39,w_race), stageID)return tabend--== E) List of teamsfunction 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"]  = {4,5,11},   -- UCI Women’s WorldTeam["Q119942457"] = {32,33,12}, -- UCI Women's Continental Team (2020-)["Q2466826"]   = {28,29,13}, -- UCI Women’s Team (-2019)["Q119948768"] = {55,56,14}, -- 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 teamslocal no = 0 -- Index used for stable sortingfor _, v in pairs(p1923) doif v.mainsnak.snaktype == 'value' thenno = no + 1local 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}endendtable.sort(teams, function(a,b)if a[3] < b[3] then return true end -- First sort key: Order from table teamCats_lotif a[3] > b[3] then return false endreturn a[4] < b[4] -- Second key is the index to ensure stable sortingend)local function getHeader(CatID, count)local header, sitelinkif teamCats_lot[CatID] thenlocal done=falseif CatID=="Q2466826" then --name changed after 2020local year = timeOfRace and tonumber(string.sub(timeOfRace, 2, 5))if year and year>2019 thenif count == 1 thenheader_label = translate("headoftableIII",32, w_race) -- singular nameelseheader_label = translate("headoftableIII",33, w_race) -- plural nameenddone=trueendendif done==false thenif count == 1 thenheader_label = translate("headoftableIII",teamCats_lot[CatID][1], w_race) -- singular nameelseheader_label = translate("headoftableIII",teamCats_lot[CatID][2], w_race) -- plural nameendendif CatID=='Q78464255' thensitelink=wikibase.getSitelink('Q382927') --continentalelsesitelink=wikibase.getSitelink(CatID)endif sitelink ~= nil then header = '[['..sitelink..'|'..header_label..']]'elseheader= header_labelendendlocal 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 possibleheader = (CatID and getLabelFallback(CatID)) or 'Unknown team category'tHeader:css('text-transform','capitalize')endtHeader:wikitext(header)-- Set parameter to show team count in front of each categorylocal tTag=''local showcounter = 2if count >= showcounter thentTag=mw.html.create('small'):wikitext(' (' .. count ..')')endreturn tostring(tHeader)..tostring(tTag)endlocal oldOrder = 0local oldCatIDlocal count = 0local list = ''local headerlocal 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) dolocal order = team[3]if order ~= oldOrder then --new catif oldOrder > 0 thenheader = getHeader(oldCatID, count)tCell:wikitext(header)tCell:node(tOl)endcount = 1oldOrder = ordertOl = mw.html.create('ul') --reinitelsecount = count + 1endoldCatID = team[2]        tOl:tag('li'):cssText("width:20em;display:inline-block;vertical-align:text-top"):wikitext(team[1])end--add last rowheader = 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') endlocal 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 resultTableend--== F) Classificationsfunction p.UCIclassification(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 19, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_2 = {1, 2, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table headeritem =tempID,property = 'P3494', -- property to use for this tableteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowdisplay_team=false,max_rank_displayed=100000, --unlimited the whole team must be displayedlf=lf}return new_classification(s, frame)endfunction p.pointsclassification(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 10, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem = tempID,property = 'P3494', -- property to use for this tableteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.teamsclassificationbytime(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 14, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_2 = {3, 2, 4}, -- translations 3, 2, 4 in function headoftableII are printed in this order in the lower part of the table headeritem = tempID,property = 'P3497', -- property to use for this tableteam_classification = true, -- it is a team classification table, its not a rider classification tablebackground = 'strong', -- there is no background color for the first row, but the first row is formated strongmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.teamsclassificationbypoints(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 15, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_2 = {3, 2, 7}, -- translations 3, 2, 7 in function headoftableII are printed in this order in the lower part of the table headeritem = tempID,property = 'P3496', -- property to use for this tableteam_classification = true, -- it is a team classification table, its not a rider classification tablebackground = 'strong', -- there is no background color for the first row, but the first row is formated strongmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.stageclassification(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 8, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem = tempID,property = 'P2417', -- property to use for this tableteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = false, -- there is no background color for the first rowdisplay_ref = get_arg(2, frame,true) == 0 and 0 or 1,max_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.generalclassification(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 9, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem = tempID,property = 'P2321', -- property to use for this tableteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowdisplay_ref = get_arg(2, frame,true) == 0 and 0 or 1,max_rank_displayed=25,lf=lf}return new_classification(s, frame)endfunction p.generalclassificationpoint(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 9, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem = tempID,property = 'P2321', -- property to use for this tableteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowdisplay_ref = get_arg(2, frame,true) == 0 and 0 or 1,max_rank_displayed=25,lf=lf}return new_classification(s, frame)endfunction p.generalclassificationforttt(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 9, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem = tempID,property = 'P2321', -- property to use for this tableteam_classification = true, -- it is a team classification table, its not a rider classification tablebackground = false, -- there is no background color for the first rowdisplay_ref =get_arg(2, frame,true) == 0 and 0 or 1,max_rank_displayed=25,lf=lf}return new_classification(s, frame)endfunction p.teamtimetrialclassification(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 8, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem = tempID,property = 'P2417', -- property to use for this tableteam_classification = true, -- it is a team classification table, its not a rider classification tablebackground = false, -- there is no background color for the first rowdisplay_ref = get_arg(2, frame,true) == 0 and 0 or 1,max_rank_displayed=25,lf=lf}return new_classification(s, frame)endfunction p.mountainsclassification(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 11, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem =  tempID,property = 'P4320', -- property to use for this tableteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.sprintsclassification(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 12, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem =  tempID,property = 'P4322', -- property to use for this tableteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.bestyoungclassificationbypoints(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 13, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem =  tempID,property = 'P4323', -- property to use for this tableteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.bestyoungclassification(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 13, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem =  tempID,property = 'P4323', -- property to use for this tableteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.u23classification(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 18, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem =  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 tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.combinationclassification(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 16, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem = tempID,property = 'P4324', -- property to use for this tableteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.combativeclassification(frame)local tempID, lf=get_and_checkID(frame)local s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_1 = 17, -- translation 10 in function headoftableII is printed in the upper part of the table headerheader_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 headeritem =  tempID,property = 'P4321', -- property to use for this tableteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.custompointsclassification(frame)local tempID, lf=get_and_checkID(frame)local team_titlelocal temp=get_arg(4,frame)if temp and string.find(temp,"{{{")==nil then team_title=tempendlocal s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_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 headerheader_1_text=get_arg(3,frame) or '', --with lf does not workitem =  tempID,property = get_arg(2,frame), -- property to use for this tableteam_title=team_title, --for old races where there was no team, only bike brandsteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.customtimeclassification(frame)local tempID, lf=get_and_checkID(frame)local team_titlelocal temp=get_arg(4,frame)if temp and string.find(temp,"{{{")==nil then team_title=tempendlocal s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_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 headerheader_1_text=get_arg(3,frame) or '',item = tempID,property = get_arg(2,frame), -- property to use for this tableteam_title=team_title, --for old races where there was no team, only bike brandsteam_classification = false, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.customteamclassificationbypoints(frame)local tempID, lf=get_and_checkID(frame)local team_titlelocal temp=get_arg(4,frame)if temp and string.find(temp,"{{{")==nil then team_title=tempendlocal s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_2 = {3, 2, 7}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table headerheader_1_text=get_arg(3,frame) or '', --with lf does not workitem =  tempID,property = get_arg(2,frame), -- property to use for this tableteam_title=team_title, --for old races where there was no team, only bike brandsteam_classification = true, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction p.customteamclassificationbytime(frame)local tempID, lf=get_and_checkID(frame)local team_titlelocal temp=get_arg(4,frame)if temp and string.find(temp,"{{{")==nil then team_title=tempendlocal s = {header_function = "headoftableII", -- translations are in function headoftableIIheader_2 = {3, 2, 4}, -- translations 1, 2, 3, 7 in function headoftableII are printed in this order in the lower part of the table headerheader_1_text=get_arg(3,frame) or '', --with lf does not workitem =  tempID,property = get_arg(2,frame), -- property to use for this tableteam_title=team_title, --for old races where there was no team, only bike brandsteam_classification = true, -- it is not a team classification table, its a rider classification tablebackground = 'color', -- there is a background color for the first rowmax_rank_displayed=10,lf=lf}return new_classification(s, frame)endfunction new_classification(s, frame)local country = getCountryBool(no_country_classification)local lf = s.lflocal raceID = s.itemlocal 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 isno 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 wikihere 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 articleif get_arg('country',frame) == 'true' and l10n["country_name_list"] then country = true endif get_arg('country',frame) == 'false' then country = false endendlocal tableHeader2_size = #s.header_2local max_rank_displayed=s.max_rank_displayedfor _, p31 in statements(raceID, 'P31') doif data.stages[p31.mainsnak.datavalue.value.id] thenmax_rank_displayed=10 --limit general ranking to 10 except for not stageendendlocal temp=get_arg('max_rank_displayed',frame)if temp and temp~='' and string.find(temp,"{{{")==nil thenmax_rank_displayed=tonumber(temp)endif s.header_1_text ==nil then s.header_1_text=translate(s.header_function,s.header_1,w_race) end --for custom titlelocal team_translation_index=3if 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" thenif arwiki_totemplate then wd_span = wd_linkelse wd_span = mw.html.create('span'):css('float','right'):wikitext(wd_link)end endtableBody: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) doif i ~= 2 or country thenlocal header_textif k == team_translation_index then --for team    header_text=s.team_titleelse    header_text=translate(s.header_function,k,w_race)endlocal head =header:tag('th'):wikitext(header_text)if i == 1 thenhead:attr('colspan','2')endendendlocal t_Body = {} --contains all rowslocal tCell, bg_color, tStyle, temp, temp2local claims = mw.wikibase.getAllStatements(raceID, s.property)for l, m in pairs(claims) do -- look into all statementsif m.mainsnak.snaktype == 'value' thenlocal riderID = m.mainsnak.datavalue.value.idlocal q = m.qualifiers or {}local rank, riderLink, gender, countryID, teamLinklocal flagLink, countryName = '', ''local h = {jersey = {}, -- lots of jerseyIDvalue = {'', '', '', ''} -- points, time, time_gap, speed}if q.P1352 and q.P1352[1].snaktype == 'value' then -- P1352 is rankingrank = tonumber(q.P1352[1].datavalue.value.amount)elserank = ''endif q.P1534 and q.P1534[1].snaktype == 'value' thenlocal dnf=q.P1534[1].datavalue.value.idif 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=''endelse riderDNF=''endlocal 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')endh.value[1] = qualifieramount(m, 'P1358')h.value[2] = qualifieramount(m, 'P2781')if q.P2911 and q.P2911[1].snaktype == 'value' then -- P2911 is time gaph.value[3] = tonumber(q.P2911[1].datavalue.value.amount)plus = '+ 'endh.value[4] = qualifieramount(m, 'P2052')if q.P2912 then -- P2912 is distinctive jerseyfor _, v in pairs(q.P2912) doif v.snaktype == 'value' thentable.insert(h.jersey, v.datavalue.value.id)endendendif s.team_classification thenlocal _teamLink, _, countryID = getTeamLinkCat(riderID, timeOfRace, true)elseriderLink = getRiderLink(riderID,timeOfRace)..(getReference(lf,m) or '')teamLink = getTeam(riderID, timeOfRace, q)countryID = getNationality(riderID, timeOfRace,q)endif countryID thenflagLink = flag(countryID, timeOfRace)if country thencountryName = getCountryName(countryID)endend-- find the right background color if a rider has more then one jersey-- see Wikidata:WikiProject Cycling/Kit to translate/Jerseysbg_color=nilif h.jersey[1] thenfor _, jersey in pairs(h.jersey) doif data.bg_color_table[jersey] thenbg_color = data.bg_color_table[jersey]breakendendendtStyle=''if rank == 1 thenif s.background then -- values are 'strong' or 'color'tStyle = tStyle ..'font-weight:bold;' -- winner is formated boldif s.background == 'color' thenif h.jersey[1] and bg_color then -- background color of winner depending on jerseytStyle = tStyle .. 'background-color:' ..bg_colorendendendendlocal tBody = mw.html.create('tr'):cssText(tStyle) -- a rowtBody: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 thenif country thentCell:wikitext(riderLink .. jersey(h.jersey) )tBody:tag('td'):wikitext( flagLink ..' '.. countryName)elsetCell:wikitext(flagLink .. ' ' .. riderLink .. jersey(h.jersey))endif s.display_team~=false thentBody:tag('td'):cssText("text-align:".. textalign ..";padding:0 0.2em 0 0.2em"):wikitext(teamLink or '')endelse --teamif country thentCell:wikitext(teamLink .. jersey(h.jersey))tBody:tag('td'):wikitext(flagLink .. ' ' .. countryName)elsetCell:wikitext(flagLink .. ' ' .. teamLink .. jersey(h.jersey))endendif s.header_2[4] == 4 then -- for table stageclassification, generalclassification, adds time and time gapif riderDNF=='' thenif rank == 1 and h.value[2] thentemp=calculateTime(h.value[2])elseif rank == 1 and h.value[3]==nil then --avoid a plus with nothingtemp=''elsetemp=plus .. calculateTime(h.value[3])endelsetemp=riderDNFendtBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(temp)endif 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 classificationif riderDNF=='' thenif h.value[1] then temp=h.value[1] else temp='' endtCell=tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(temp)if type(h.value[1]) == "number" thenif h.value[1] > 1 thentemp2=translate("unit",7,w_race)elsetemp2=translate("unit",6,w_race)endtCell:tag('span'):cssText("font-size:80%"):wikitext(temp2)endelsetBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(riderDNF)endendif s.header_2[3] == 4 thenif s.property == 'P2417' or s.property == 'P2321' then-- for tables teamtimetrialclassification or generaltttclassification, adds timetBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(calculateTime(h.value[2]))endendif s.property == 'P3497' then -- for table teambytimeclassification, adds time and time gapif rank == 1 then temp=calculateTime(h.value[2])elsetemp=plus .. calculateTime(h.value[3])endtBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(temp)endif s.property == 'P3496' then -- for table teambypointsclassification, adds pointstCell=tBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em")    :wikitext(h.value[1])if type(h.value[1]) == "number" thenif h.value[1] > 1 thentemp2=translate("unit",7,w_race)elsetemp2=translate("unit",6,w_race)endtCell:tag('span'):cssText("font-size:80%"):wikitext(temp2)endendif s.header_2[4] == 5 then -- for table teamtimetrialclassification, adds time gapif l > 1 then temp= plus else temp='' endtBody:tag('td'):cssText("text-align:right;padding:0 0.2em 0 0.2em"):wikitext(temp..calculateTime(h.value[3]))endif s.header_2[5] == 6 then -- for table teamtimetrialclassification, adds speedtCell=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))endendif rank~='' and rank<=max_rank_displayed then --else no displayif riderDNF=='' thentable.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 revidedtable.insert(t_Body, {sortkey=(type(rank) == 'number') and rank-0.1 or 999, body=tostring(tBody)})endendendend    tableBody=sortAndConcat(t_Body, tableBody)local tableFooter1,tableFooter2if s.display_ref == 1 or wiki == "ar" thentableFooter1=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 linelocal tableStyle, tableNewlineif 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 = ''endif 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;">'endif get_arg('newline',frame) == nil then -- no second parameter, compatible to the old codeif s.property == 'P2417' then --stageclassificationtableStyle = "float:"..floattable.."; margin-right:0.5em; border:1px solid rgb(200,200,200)"tableNewline = ''elsetableStyle = "border:1px solid rgb(200,200,200)"tableNewline = '<br style="clear:left;">' -- everything elseendendlocal finalTable= mw.html.create('table'):cssText(tableStyle)finalTable:tag('tr'):tag('td'):node(tableBody)if tableFooter1 thenfinalTable:node(tableFooter1)finalTable:node(tableFooter2)endreturn tostring(finalTable)..tableNewlineend--=== G) Infobox ===function p.infobox(frame) -- normal infoboxreturn infobox_main(frame,0)endfunction p.seasoninfobox(frame) -- season infoboxreturn infobox_main(frame,1)endfunction p.champinfobox(frame) -- champ infoboxreturn infobox_main(frame,2)endfunction infobox_main(frame, selector)local WDlink_on = (wiki == "mk" or wiki == "ja")-- If true, winners will the team of the cyclistlocal team = truelocal details, others, winners, plurallocal entityID, lf = get_and_checkID(frame)local w_race=isWomenrace(entityID)if selector==0 then -- normal infoboxdetails = {{ 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 infoboxdetails = {{ 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}endothers = 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 thengetLocalContent(winners, lf.args)endlocal timeOfRace, classlocal 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 P393local nr = firstValue(entityID, 'P393') -- P393 is 'edition number'if nr thenif 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 .. ". "endendlocal is_alocal classID = firstValue(entityID, 'P279', 'id')--fallbackif classID then class = classLinkFn(classID)elsefor _, p31 in statements(entityID, 'P31') do -- P31 is 'instance of'local instanceOf = p31.mainsnak.datavalue.value.idif instanceOf ~= "Q27020041" and data.class_dic[instanceOf] thenclass = classLinkFn(instanceOf)breakendendendlocal season = firstValue(entityID, 'P3450', 'id') -- P3450 is 'sports season of league or competition'if season thenis_a = raceLink(season)else--normally there should be only a p31for _, p31 in statements(entityID, 'P31') do -- P31 is 'instance of'local instanceOf = p31.mainsnak.datavalue.value.idif instanceOf ~= 'Q27968055' and instanceOf ~= 'Q27020041' then -- Q27020041 is 'sports season'is_a = raceLink(instanceOf)breakendendendif nr and is_a thendetails[1].content = nr .. ' ' .. is_aendendif selector==0 or selector==1 thenif 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)endif tours[1] thenif #tours > 1 thendetails[2].name = details[2].name_pluralendif class thentours[1] = tours[1] .. ' ' .. classenddetails[2].content = table.concat(tours, '<br/>')endendendif selector==0 thenif not details[3].content then -- stageslocal stages = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part'if stages > 0 thendetails[3].content = stagesendendendlocal index_date, index_official_siteif selector==0 thenindex_date=4index_official_site=17elseif selector==1 thenindex_date=3index_official_site=10else index_date=2index_official_site=11end--if selector==0 or selector==1 thenif not details[index_date].content then -- datedetails[index_date].content, timeOfRace, plural = get_formatted_date(entityID, 'infobox')if plural thendetails[index_date].name = details[index_date].name_pluralendend--end--from this point the functions differ fundamentallyif selector==0 thenlocal kmdistanceif not details[5].content then details[5].content, kmdistance = getDistance(entityID, true) end -- distanceinfoGetCountry(details,6, entityID, timeOfRace)infoGetStartEnd(details,7, entityID, timeOfRace)if not details[9].content then -- teamslocal teams = #wikibase.getBestStatements(entityID, 'P1923') -- P1923 is 'participating teams'if teams > 0 thendetails[9].content = teamsendendinfoGetParticipants(details,10, entityID)if not details[10].content or not details[11].content thenlocal Allp710= wikibase.getAllStatements(entityID, 'P710')if Allp710 and #Allp710~=0 thenif not details[10].content then details[10].content=#Allp710 endif not details[11].content thenlocal maxrank=1for _, p710 in pairs(Allp710) do -- look into all statementslocal q = p710.qualifiersif q and q.P1352 and q.P1352[1].snaktype == 'value' then -- P1352 is rankinglocal riderRank = tonumber(q.P1352[1].datavalue.value.amount)if riderRank > maxrank then maxrank = riderRank endendendif maxrank~=1 then details[11].content=maxrank endendendendif not details[12].content then details[12].content = getSpeed(entityID, true, kmdistance, 'P2321') end --speedif not details[13].content then local elevation=getElevation(entityID) if  elevation then details[13].content =elevation else details[13].content = nil endend --Elevationif not details[14].content then -- costlocal cost = firstValue(entityID, 'P2130') -- P2130 is costif cost thendetails[14].content = dispmoney(cost.amount, cost.unit)endendelseif selector==1 thenif not details[4].content then -- racinglocal stages = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part'if stages > 0 thendetails[4].content = stagesif stages > 1 thendetails[4].name = details[4].name_pluralendendendif not details[5].content then -- locationinfoGetPlace(details,5, entityID, timeOfRace) --in GAN version, the separator is , not <br />endif not details[6].content then -- organizer sitelinklistWPlink(details, 6, entityID,'P664',true) --orgendif not details[7].content then -- organizer sitelinklistWPlink(details, 7, entityID,'P2670',true) --team ????endelse --champinfoGetCountry(details,3, entityID, timeOfRace)if not details[4].content then -- locationinfoGetPlace(details,4, entityID, timeOfRace) --in GAN version, the separator is , not <br />endif not details[5].content then -- arena / stadionlistWPlink(details, 5, entityID,'P115',true) endif not details[6].content then -- racinglocal stages = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part'if stages > 0 thendetails[6].content = stagesendendif not details[7].content then -- teamslocal teams = #wikibase.getBestStatements(entityID, 'P1923') -- P1923 is 'participating teams'if teams > 0 thendetails[7].content = teamsendendif not details[8].content then -- organizer sitelinklistWPlink(details, 8, entityID,'P664',true) --orgendendif not details[index_official_site].content thendetails[index_official_site].content = officialSite(entityID)endtab = infoInitTab("300px", name, icon)if selector==0 then      -- normal infoboxinfoFillOthersDetails(tab, others, details,translate("infobox",1,w_race))elseif selector==1 then  -- season infoboxinfoFillOthersDetails(tab, others, details,translate("infobox",69,w_race))else                     -- champ infoboxinfoFillOthersDetails(tab, others, details,translate("infobox",70,w_race))endif selector==0 or selector==1 then --no winners for champlocal winRows=''local win = {}for _, v in pairs(winners) doif not v.content thenwin[v.QID] = ''endendwinner(lf,entityID, win, timeOfRace, false, WDlink_on, team, true)for _, v in pairs(winners) doif not v.content thenif win[v.QID] ~= '' thenv.content = win[v.QID]endendif v.content thentRow= 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 elegantendendif winRows~= '' thentab: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)endendif others[3].content then -- maptab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):wikitext("[[File:".. others[3].content .. "|center|300px]]")if others[5].content then -- captiontab:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','center'):css('font-size','80%'):wikitext(others[5].content)endendtab:node(getPreviousNextLine(entityID))wdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/infobox", translate("infobox",34,w_race), entityID)return tabend--=== H) race infoboxfunction p.raceinfobox(frame)local lang = contentLanguagelocal 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 sportif not details[1].content and sport_id thendetails[1].content = WPlinkpure(sport_id)end--creationlocal creation=firstValue(entityID, 'P571', 'time')if not details[2].content and creation thendetails[2].content = funcDate(creation, "onlyyear" )end--disparitionlocal disparition=firstValue(entityID, 'P576', 'time')if not details[3].content and disparition thendetails[3].content =  funcDate(disparition,"onlyyear")end--populate tRacelistOfWinners(entityID, tRace,nil,lf)--number of editionsif not details[4].content and tRace.numberOfEditions and tRace.lastEditionYear thendetails[4].content = tostring(tRace.numberOfEditions).." (" .. translate("raceinfobox",31,w_race) .. " "..tostring(tRace.lastEditionYear)..")"end--periodicityif not details[5].content thendetails[5].content = getPeriodicity(entityID, tRace)end--typeif not details[6].content thendetails[6].content = getType(entityID)endtimeOfRace=nil --could be from last editionif not details[7].content theninfoGetCountry(details,7, entityID, timeOfRace)endif not details[8].content theninfoGetPlace(details,8, entityID, timeOfRace)endif not details[9].content thenlistWPlinkChrono(details, 9, entityID, {'P664'}, true, initialYear) --organiserendif not details[10].content thenlistWPlinkChrono(details, 10, entityID, {'P488'}, 'rider', initialYear) --race dirend--Class and circuitlocal classContent, circuitLink, numberClass= getClass(entityID)if not details[11].content thendetails[11].content = classContentif numberClass >1 then details[11].name = details[11].name_pluralend end  if not details[12].content thendetails[12].content = circuitLink end --Official web siteif not details[13].content thendetails[13].content = officialSite(entityID)end--Build the tabletab = infoInitTab("300px", name, icon)--former nameswiki_listOfNamesAtBottom={'ru'}local listOfNamesAtBottom = falsefor _, value in pairs(wiki_listOfNamesAtBottom) do -- if value == wiki then listOfNamesAtBottom = true endend--picture at the topinfoFillOthersDetails(tab, others, nil,translate("raceinfobox",19,w_race),"260px")if not listOfNamesAtBottom thenif listOfNames and #listOfNames>1 thentab:node(addATitle(translate("raceinfobox",18,w_race)))  for _, v in pairs(listOfNames) dotab:node(addARow(v[2],v[3])) --period, nameendendend    infoFillOthersDetails(tab, nil, details,translate("raceinfobox",19,w_race),"260px")if listOfNamesAtBottom thenif 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) dotab:node(addARow(v[2],v[3])) --period, nameendendendif (tRace.lastWinner and tRace.lastWinner~='') or (tRace.maxWinner and tRace.maxWinner~='') thentab:node(addATitle(translate("raceinfobox",20,w_race)))if (tRace.lastWinner and tRace.lastWinner~='') thentab:node(addARow(translate("raceinfobox",21,w_race),tRace.lastWinner))endif (tRace.maxWinner and tRace.maxWinner~='') thentab:node(addARow(translate("raceinfobox",22,w_race),tRace.maxWinner))endendif tRace.nextLink or tRace.lastLink thentab: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)endif tRace.nextLink thenoutTable = 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)endendwdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/raceinfobox", translate("raceinfobox",26,w_race), entityID)return tabend--=== I) Team rosterfunction 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 thenif 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 endendlocal s = {sort=sort,seasonID=tRace.lastID,lf=lf,year=tRace.lastEditionYear}if tRace.lastID thenreturn teamroster_main(s)endendfunction 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 thenif 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 endendlocal s = {sort=sort,seasonID=seasonID,lf=lf}return teamroster_main(s)endfunction teamroster_main(s)local flags, pays = {}, {}local riderName, riderBirthday,riderTeam, timeTeam, correctlanguage,riderStart, riderEndlocal riderPosition, riderReason, riderRef, errortextlocal riderReasonTable, riderTablecorrect, riderTablenotcorrect, riderTable = {}, {}, {}, {}local labelMissing = falselocal teamID, stagiairelocal 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 endlocal startOfSeason = getTimeOfRace(s.seasonID, true)if not s.year thenlabel=getLabelFallback(s.seasonID)local second_occurrencelocal first_occurrence=string.find(label, "%d%d%d%d")if first_occurrence~=nil thensecond_occurrence=string.find(label, "%d%d%d%d",first_occurrence+1)if second_occurrence~=nil thens.year=string.match(label, "%d%d%d%d",first_occurrence+1) --case Tartu2024elses.year=string.match(label, "%d%d%d%d")endendendfor _, p527 in statements(s.seasonID, 'P527') do--re-initriderName, riderBirthday, correctlanguage=nil, nil, nilriderTeam, timeTeam, riderReason, riderRef=nil, nil, nil, nilriderStart, riderEnd=nil, nillocal riderID = p527.mainsnak.datavalue.value.idriderName, correctlanguage =getRiderLink(riderID, startOfSeason) --labelif WDlink_on==true then riderName=riderName..wdLink(riderID) endlocal 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 foundlocal sortkey = findSortKey(riderID, correctlanguage,  wikiIsSlavic)for _, q in qualifiers(p527, 'P580') dolocal startdate = q.value['time']timeOfRace = startdateriderStart = funcDate(trans(startdate,'01', '01') or '', 'small')endfor _, q in qualifiers(p527, 'P582') dolocal enddate=q.value['time']riderEnd = funcDate(trans(enddate,'12', '31') or '', 'small')endriderPosition=getPosition(riderPosition,p527)riderReason, riderRef=getReason(riderReason,riderRef,p527, timeOfRace,enddate,s.lf)local beginYear, beginMonth, beginDay, endYear, endMonth, endDay, beginDate, endDate, endDatefound, endDatetemplocal changedTime = '+0000-00-00'if teamID == nil thenlocal p54 = getStatementForTime(riderID, 'P54', timeOfRace)if p54 then teamID = p54.mainsnak.datavalue.value.id endelsefor _, v in statements(riderID, 'P54') do -- look into all P54 teamsstagiaire=nil errortext=''local thisteamID = v.mainsnak.datavalue.value.idif thisteamID == teamID thenendDatefound=truebeginDate, 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 endendDate, 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 seasonriderStart = funcDate(beginDate, 'small')if endDatefound then riderEnd = funcDate(endDate, 'small')elseriderEnd = funcDate('+'..beginYear..'-12-31T00:00:00Z', 'small')endriderPosition=getPosition(riderPosition,v)endelsefor _, q in qualifiers(v, 'P39') dostagiaire =q.value.idendif not stagiaire thenendDatefound=truebeginDate, endDatetemp=getStartEndfromQuali(v.qualifiers)if not endDatetemp then endDatefound=false endbeginDate, 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 timeif endDatefound thenif (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 startOfSeasonif endYear > startOfSeasonYear then changedTime = '+'..startOfSeasonYear..'-12-31T00:00:00Z' else changedTime = endDate or ''endendendendif changedTime ~= '+0000-00-00' thenriderTeam = getTeam(riderID, changedTime, nil)local _, _, endYear, _, _ = string.find(changedTime, "(%d+)-(%d+)-(%d+)")timeTeam = ' ('..endYear..')'if wiki == "ar" then timeTeam = endYear endendendendendend--get the countrylocal countryID = getNationality(riderID, timeOfRace,q)if countryID thenpays = getCountryName(countryID)flags = flag(countryID, timeOfRace)end--savelocal 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 thentable.insert(riderTablecorrect,tRider )elsetable.insert(riderTablenotcorrect, tRider)endend-- sorting namesif sort == true thenif #riderTablecorrect~=0 thentable.sort(riderTablecorrect, function(a,b) return a["sortkey"]<b["sortkey"] end)endif #riderTablenotcorrect~=0 thentable.sort(riderTablenotcorrect, function(a,b) return a["sortkey"]<b["sortkey"] end)endend--mergefor _, v in pairs (riderTablecorrect) dotable.insert(riderTable, v)endfor _, v in pairs (riderTablenotcorrect) dotable.insert(riderTable, v)endlocal wd_link = mw.html.create('span'):css('float','left'):wikitext(wdLink(s.seasonID..'#P527'))if arwiki_totemplate then wd_link = wdLink(s.seasonID .. '#P527') endlocal 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 = 4if wiki == "ar" then th_colspan = 5 endlocal 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)elsetRow:wikitext(translate("getSquadTableColumn",7,w_race))endlocal 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' endheader: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))endif wiki == "ar" thenheader:tag('th'):attr('colspan', 2):cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",3,w_race))elseheader:tag('th'):cssText('text-align:center;padding:2px 20px 2px 2px;white-space:nowrap'):wikitext(translate("getSquadTableColumn",3,w_race))endlocal templocal iii = 1for i, v in pairs (riderTable) dolocal 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='' endtCell:wikitext(temp..v['riderName']):attr('data-sort-value',v['sortkey'])if v['riderStart']~=nil or v['riderEnd']~=nil thentCell:tag('span'):cssText("font-size:80%; color:#686868")local note=''if v['riderReason'] ~= nil thennote = ', [[#tr_'..i..s.seasonID..'|'..translate("getSquadTableColumn",4,w_race)..']]'if wiki == "ar" then note = '، [[#tr_'..i..s.seasonID..'|'..translate("getSquadTableColumn",4,w_race)..']]' endendtCell:wikitext(' ('..(v['riderStart'] or '')..'–'..(v['riderEnd'] or '').. (v['riderPosition'] or '')..note..')')elseif v['riderReason'] thentCell:tag('span'):cssText("font-size:80%; color:#686868"):wikitext('([[#tr_'..i..s.seasonID..'|'..translate("getSquadTableColumn",4,w_race)..']]'.. ')')endtCell=tRow:tag('td'):cssText("text-align:right;white-space:nowrap")if wiki == 'lv' thenlocal _, _, 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 } })elsetCell:wikitext(funcDate(v['riderBirthday'] or '', 'long'))if l10n["country_name_list"] and wiki ~= 'ar' and wiki ~= 'ru' and wiki ~= 'da' thentRow:tag('td'):wikitext(v['flags'].. ' '..v['pays'])endendif wiki =='he' thenlocal isRtl = (mw.ustring.find(v['riderTeam'], '|.*[א-ת]') or (not mw.ustring.find(v['riderTeam'], '|') and mw.ustring.find(riderTeam, '[א-ת]')))if isRtl thentCell=tRow:tag('td'):cssText("padding:0 0.5em; text-align:right")elselabelMissing = true -- FIXME: labelMissing is not functional in most languages. once we have infra support for it, move it theretCell=tRow:tag('td'):cssText("padding:0 0.5em; text-align:left")endelseif 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")endif v['riderTeam'] then if wiki == "ar" thentCell:wikitext( v['riderTeam'] )tCell=tRow:tag('td'):cssText("padding:0 0.5em")tCell:wikitext( v['timeTeam']..v['errortext'] )elsetCell:wikitext(v['riderTeam'].. v['timeTeam']..v['errortext'])endend--tableEndText is not a tableif v['riderReason'] ~= nil or v['errortext'] ~= '' thenlocal temp=(v['riderReason'] or '')..(v['errortext'] or '')if iii == 1 thentableEndText = tableEndText.. translate("getSquadTableColumn",5,w_race)..': '.. v['riderName'].. tempelsetableEndText = tableEndText.. '<span style="color:white">'.. translate("getSquadTableColumn",5,w_race)..': </span>'.. riderName.. tempendiii = iiiif riderRef ~= nil then tableEndText = tableEndText..s.lf:extensionTag{name='ref', content=v['riderRef'], args = {name='tr_'..iii..s.seasonID}} endtableEndText = tableEndText.. '<br>'endendif labelMissing then outTable:wikitext(getMissingLabelTrackingCategory()) endlocal ref=race_reference(s.seasonID,s.lf)if ref=='' then --fallbacklocal UCIlinkif wiki=="fr" thenUCIlink="https://www.uci.org/fr/route/%C3%A9quipe"elseUCIlink="https://www.uci.org/road/teams"endref=translate("race_reference", 1,w_race).."["..UCIlink..' UCI]'endoutTable: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)..tableEndTextend--== 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 teamwinnersProperty=winnersProperty,custom=false,lf=lf}return listofwinners_main(s)endfunction 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 teamwinnersProperty=winnersProperty,custom=false,lf=lf}return listofwinners_main(s)endfunction 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.listofwinnersfunction 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 teamwinnersProperty=winnersProperty,custom=false,lf=lf}return frame:extensionTag{ name = 'nowiki', content = listofwinners_main(s)}endfunction 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 teamwinnersProperty=winnersProperty,custom=false,lf=lf}return listofwinners_main(s)endfunction 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 teamwinnersProperty=winnersProperty,custom=false,lf=lf}return listofwinners_main(s)endfunction 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 teamwinnersProperty=winnersProperty,custom=false,lf=lf}return listofwinners_main(s)endfunction 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 teamwinnersProperty=winnersProperty,custom=false,lf=lf}return listofwinners_main(s)endfunction 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 teamwinnersProperty=winnersProperty,custom=false,lf=lf}return listofwinners_main(s)endfunction 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 teamwinnersProperty=winnersProperty,custom=false,lf=lf}return listofwinners_main(s)endfunction p.listofwinnerscustom(frame)local raceID, lf =get_and_checkID(frame)local winnersProperty ={}if istrue(get_arg('general',frame)) then table.insert( winnersProperty,'Q20882667') endif istrue(get_arg('podium',frame)) then table.insert( winnersProperty,'Q20882668') table.insert( winnersProperty,'Q20882669') endif istrue(get_arg('points',frame)) then table.insert( winnersProperty, 'Q20883007' ) endif istrue(get_arg('mountain',frame)) then table.insert( winnersProperty, 'Q20883212' ) endif istrue(get_arg('sprints',frame)) then table.insert( winnersProperty, 'Q20883328' ) endif istrue(get_arg('youth',frame)) then table.insert( winnersProperty, 'Q20883139' ) endif istrue(get_arg('combativity',frame)) then table.insert( winnersProperty, 'Q101246973' ) table.insert( winnersProperty, 'Q20893983' ) endif istrue(get_arg('volante',frame)) then table.insert( winnersProperty, 'Q27067359' ) endif istrue(get_arg('regularity',frame)) then table.insert( winnersProperty, 'Q27067170' ) endif istrue(get_arg('combination',frame)) then table.insert( winnersProperty, 'Q20893979' ) endif istrue(get_arg('breakaway',frame)) then table.insert( winnersProperty, 'Q27907715' ) endif istrue(get_arg('azzurri',frame)) then table.insert( winnersProperty, 'Q27907747' ) endif istrue(get_arg('rookie',frame)) then table.insert( winnersProperty, 'Q28092831' )end if istrue(get_arg('teams',frame)) then table.insert( winnersProperty, 'Q20882921' )endif istrue(get_arg('teamspoints',frame)) then table.insert( winnersProperty, 'Q27104269' ) endif istrue(get_arg('amateur',frame)) then table.insert( winnersProperty, 'Q61976850' ) endif istrue(get_arg('nationality',frame)) then table.insert( winnersProperty, 'Q61976872' ) endif istrue(get_arg('country',frame)) then table.insert( winnersProperty, 'Q72068715' ) endif istrue(get_arg('countryU23',frame)) then table.insert( winnersProperty, 'Q72068724' ) endlocal 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)endfunction listofwinners_main(s)local lf=s.lflocal raceID=s.raceIDlocal rows = {}local WDlink_on = (wiki == "mk") or (wiki == "ja") or (wiki == "ru")local WPcontent = {row ={},code = {}}local beginyear=s.beginyear or 0local endyear=s.endyear or 0local shapka=s.shapka or 0local titletablelocal w_race=isWomenrace(raceID)if s.custom thentitletable={[ '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) thenfor num, _ in pairs(lf.args) doif num > 1 and mw.ustring.find(mw.ustring.lower(get_arg(num,lf)), 'row') thenlocal _, _, 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 aboveif kebeginYear1 == 'belowrow' then WPcontent.row[kebeginYear2] = val WPcontent.code[kebeginYear2] = 1  end --0 is aboveendendendlocal firstyeartodisplay=2100local parts = mw.wikibase.getAllStatements(raceID, 'P527') -- P527 is 'has part'for _, part in ipairs(parts) doif part.rank ~= 'deprecated' and part.mainsnak.snaktype == 'value' thenlocal partID = part.mainsnak.datavalue.value.idlocal timeOfRace=getTimeOfRace(partID,true,true) --original P585 and P580 inverted herelocal 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 ) endif endyear==0 or (tonumber(year) or 0)<=endyear thenif (tonumber(year) or 0) >= beginyear thenlocal thereisawinner=falselocal sitelink = mw.wikibase.getSitelink(partID)if sitelink thensitelink = '[[' .. sitelink .. '|' .. year .. ']]'elsesitelink = yearendif WDlink_on thensitelink = sitelink .. ' ' .. wdLink(partID)endlocal winners = {}for _, property in ipairs(s.winnersProperty) do winners[property]='' endlocal tCelllocal tCellstr='' local temp=firstValue(partID, 'P1346','id')if temp and temp=='Q30108381' then --race cancelledlocal cancelledlabel = getLabelFallback('Q30108381')tCell=mw.html.create('td'):attr('colspan','4'):cssText('text-align:center; font-style: italic'):wikitext(cancelledlabel)tCellstr=tostring(tCell)elsewinner(lf,partID, winners, timeOfRace, not s.countryflag, WDlink_on,s.display_team,true)for _, property in ipairs(s.winnersProperty) dotCell=mw.html.create('td'):wikitext(winners[property])if winners[property]~='' then thereisawinner=true if tonumber(year)<firstyeartodisplay then firstyeartodisplay=tonumber(year) endendtCellstr= tCellstr..tostring(tCell)endendif firstyeartodisplay<=tonumber(year) then    rows[#rows+1]={year..month, sitelink, tCellstr}endendendendendtable.sort(rows, function(a, b) return a[1] < b[1] end) -- Sort by yearlocal clear = "left"if wiki == "ar" then clear = "right" end--do not use hw.html here otherwise the begin and end year won't worklocal 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") endif WDlink_on == false thentCell:wikitext(tostring(wd_link))endtCell:wikitext(translate("listofwinners",1,w_race)) --yearfor _, pp in ipairs(s.winnersProperty) dotTitleRow:tag('th'):wikitext(titletable[pp])endlocal table_center=''local nb_year_inrow=1local lastyearfor i, row in ipairs(rows) dositelink=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 thennb_year_inrow=nb_year_inrow+1tCell:wikitext(sitelink..' ('..tostring(nb_year_inrow)..')') elsetCell:wikitext(sitelink)nb_year_inrow=1endlastyear=mw.ustring.sub(row[1],1,4)tRowWD:node(row[3]) --add the end of the rowif WPcontent.row[i] thentRow=mw.html.create('tr'):tag('td'):attr('colspan','4'):css('text-align','center')tRow:wikitext(WPcontent.row[i])if WPcontent.code[i]==0 then --abovetable_center=table_center..tostring(tRow)table_center=table_center..tostring(tRowWD)else --belowtable_center=table_center..tostring(tRowWD)table_center=table_center..tostring(tRow)endelsetable_center=table_center..tostring(tRowWD)endend--firstpart with header no footif shapka == 1 then -- standard headerreturn table_center .. "</table>"elseif shapka == 2 then-- you need to add a title and you can add text at the beginningreturn table_center else -- you need to add a title and you can add anything and anywherereturn table_first .. tostring(tTitleRow) .. table_center .. "</table>"endend--== K) List of stagesfunction check_basque_place(sPoint, sPointID)local eu=false--check if it is a townlocal town=falsefor _, p31 in statements(sPointID, 'P31') doif p31.mainsnak.datavalue.value.id == "Q2074737" or p31.mainsnak.datavalue.value.id == "Q484170" then --Spanish and French townstown=trueendendif not town then --if it not a town look for parentfor _, p131 in statements(sPointID, 'P131') doif data.BasqueTown[p131.mainsnak.datavalue.value.id] theneu=trueendendelseif data.BasqueTown[sPointID] theneu=trueendendif eu thensPoint = flag("Q47588", timeOfRace).." "..sPointendreturn sPoint, euendfunction p.listofstages(frame)local WDlink_on = wiki == "mk" or wiki == "ja"local WPcontent = {}local raceID, lf = get_and_checkID(frame)local thereiselevation=falselocal result, tableBodylocal 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 andend 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) thenlocal WProw, WPnew_row, WPcourse, WPtext, WPdate, WPwinner, WPicon, WPdistance= 'row', 'afterrow', 'location', 'text', 'date', 'winner', 'icon', 'distance'local _, kebeginYear, key2, vallocal key01, kebeginYear1, kebeginYear2local key21, key22for num, var in pairs(lf.args) doif 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] = {} endif kebeginYear1 == WProw and key21 == WPcourse then WPcontent[kebeginYear2][key22] = val endif kebeginYear1 == WPnew_row and key2 == WPdate thenWPcontent[kebeginYear2]['date'] = valWPcontent[kebeginYear2]['text'] = WPcontent[kebeginYear2]['text'] or ''WPcontent[kebeginYear2]['icon (new row)'] = WPcontent[kebeginYear2]['icon (new row)'] or ''endif kebeginYear1 == WPnew_row and key2 == WPtext thenWPcontent[kebeginYear2]['text'] = valWPcontent[kebeginYear2]['date'] = WPcontent[kebeginYear2]['date'] or ''WPcontent[kebeginYear2]['icon (new row)'] = WPcontent[kebeginYear2]['icon (new row)'] or ''endif kebeginYear1 == WPnew_row and key2 == WPicon thenval = string.gsub(val, "|", "|border|right|20px|", 1)WPcontent[kebeginYear2]['icon (new row)'] = valWPcontent[kebeginYear2]['date'] = WPcontent[kebeginYear2]['date'] or ''WPcontent[kebeginYear2]['text'] = WPcontent[kebeginYear2]['text'] or ''endif kebeginYear1 == WProw and key21 == WPwinner and key22 == 'a' then WPcontent[kebeginYear2]['stage winner'] = val endif kebeginYear1 == WProw and key21 == WPwinner and key22 == 'b' then WPcontent[kebeginYear2]['general winner'] = val endif kebeginYear1 == WProw and key21 == WPicon thenval = string.gsub(val, "|", "|border|right|20px|", 1)WPcontent[kebeginYear2]['icon'] = val endif kebeginYear1 == WProw and key21 == WPdistance then WPcontent[kebeginYear2]['distance'] = val endendendendlocal countries = wikibase.getAllStatements(raceID, 'P17')local onecountry, firstcountryIDif countries and #countries>1 thenonecountry=falseif countries[1] thenfirstcountryID=countries[1].mainsnak.datavalue.value.idendelseonecountry=trueendlocal rows = {}local stages = mw.wikibase.getBestStatements(raceID, 'P527') -- P527 is 'has part'for _, v in pairs(stages) doif v.mainsnak.snaktype == 'value' thenlocal stageID = v.mainsnak.datavalue.value.idlocal 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.valueor ''local _, _, sNumber, sLetter = string.find(sOrdinal, '(%d+)(.*)')if not sNumber then sNumber = '' endif not sLetter then sLetter = '' endlocal 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=falseif wiki=="eu" and sPointID thensPoint, eu=check_basque_place(sPoint, sPointID)endif sPointID and not onecountry and not eu thenlocal startcountryID=getCountryID(sPointID, timeOfRace)if startcountryID and firstcountryID ~= startcountryID thensPoint = flag(startcountryID, timeOfRace).." "..sPointendendlocal dPointID = firstValue(stageID, 'P1444', 'id')local dPoint = (dPointID and getPlaceLink(dPointID, timeOfRace)) or ''eu=falseif wiki=="eu" and dPointID thendPoint, eu=check_basque_place(dPoint, dPointID)endif dPointID and not onecountry and not eu thenlocal dcountryID=getCountryID(dPointID, timeOfRace)if dcountryID and firstcountryID ~= dcountryID thendPoint = flag(dcountryID, timeOfRace).." "..dPointendendlocal sDistance = getDistance(stageID, false) or ''local sElevation = getElevation(stageID) if sElevation then thereiselevation=true endlocal 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 stagelocal sType = typeofstagelogo(stageID)local label, section_titleif sOrdinal == "0" thenlabel, section_title = translate("func_prologue",1), "#" .. translate("func_prologue",1)elselabel, section_title = stageLink(sOrdinal, sNumber, sLetter)end-- if there is a Wikipedia article of that stage show it or show the sectionlocal sLink = sitelink and ("[[" .. sitelink .. "|" .. label .. "]]") or("[[" .. section_title .. "|" .. label .. "]]")local sDate = funcDate(timeOfRace, 'small')local tempoverallif  winners['Q20882763']~='' then tempoverall=winners['Q20882763'] elsetempoverall=winners['Q20882667'] endrows[#rows + 1] = {rank=tonumber(sNumber) or 0, sortkey=sLetter,  -- Sort keyssLink=sLink,sDate=sDate, WDLink=WDLink, sPoint=sPoint, dPoint=dPoint, sType=sType, sDistance=sDistance, sElevation=sElevation, sSWin=winners['Q20882747'], sGWin=tempoverall -- Content}endendtable.sort(rows, function(a, b)if a["rank"] ~= b["rank"] then return a["rank"] < b["rank"] endreturn 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))endtRow: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) dolocal sPoint=row["sPoint"]local dPoint=row["dPoint"]local sType=row["sType"]local sDistance=row["sDistance"]local WPc = WPcontent[num]if WPc thenif WPc['a'] then sPoint = WPc['a'] endif WPc['b'] then dPoint = WPc['b'] endif WPc['ab'] then sPoint, dPoint = WPc['ab'], '' endif WPc['icon'] then sType = WPc['icon'] endif WPc['distance'] then sDistance = WPc['distance'] endendlocal 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 ~= '' thentCell:wikitext(" – " .. dPoint)endtRow:tag('td'):cssText("padding-right:0px"):wikitext(sType)tRow:tag('td'):css('text-align','center'):wikitext( sDistance)if thereiselevation thentRow:tag('td'):css('text-align','center'):wikitext(row["sElevation"])endif WPc and WPc['stage winner'] thentRow:tag('td'):css('text-align',textalign):wikitext( WPc['stage winner'])elsetRow:tag('td'):wikitext(row["sSWin"])endif WPc and WPc['general winner'] thentRow:tag('td'):css('text-align',textalign):wikitext( WPc['general winner'])elsetRow:tag('td'):wikitext(row["sGWin"])endif WPc and (WPc['date'] or WPc['text'] or WPc['icon (new row)']) thentRow = tab:tag('tr')tRow:tag('td') --emptyif WPc['icon (new row)'] == '' thentRow: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'])elsetRow:tag('td'):cssText('text-align:right; padding-right:0px'):wikitext(WPc['date'])tRow:tag('td'):cssText("text-align:" .. textalign):wikitext(WPc['text'])endtRow:tag('td'):css('padding-top','10px'):wikitext(WPc['icon (new row)'])tRow:tag('td'):attr('colspan','3')endendif arwiki_totemplate thentab = change_listofstages(tab, raceID, header, Id)endreturn tabendfunction 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 stagetab=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 tabendlocal function champtitle(h) --!h is h.jerseylocal road, ITT, resultlocal 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 championshipsif type(h) == 'table' and h[1] thenfor _, v in ipairs(h) doroadtemp=falseITTtemp=falseif data.womenNcRoadtable[v] or data.menNcRoadtable[v] then road = true roadtemp=trueelseif data.womenNcITTtable[v] or data.menNcITTtable[v] then ITT = true ITTtemp=true    else    local raceLabel = mw.wikibase.getLabelByLang(v,"fr")if raceLabel thenlocal testMenRoadrace, testMenITT, testWomenRoadrace, testWomenITTlocal 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 endif testWomenITT or testMenITT then ITT = true ITTtemp=true endendendif roadtemp or ITTtemp thentable.insert(hcountry,v)elsetable.insert(hnotcountry,v)endendendif road and ITT thenlocal image = {}for ii, v in ipairs(hcountry) dolocal p18 = mw.wikibase.getBestStatements(v, 'P18')if p18[1] and p18[1].mainsnak.snaktype == 'value' thenlocal temp = p18[1].mainsnak.datavalue.valuelocal alreadythere = 0for _, vv in ipairs(image) doif vv==temp then alreadythere = 1 endendif alreadythere==0 thentable.insert(image,temp)else hcountry[ii] = nilendendend--avoid double display of jerseyresult = "<small>("..translate("startlist",10,w_race).." "..translate("startlist",12,w_race).." "..translate("startlist",11,w_race)..")</small>"elseif road thenresult = "<small>("..translate("startlist",10,w_race)..")</small>"elseif ITT thenresult = "<small>("..translate("startlist",11,w_race)..")</small>"elseresult = ""endreturn jersey(hcountry)..result..jersey(hnotcountry)end-- L) List of stages classificationlocal function winnerjersey(raceID, winners)local jerseytable, bgcolortable={}, {}local p1346 = wikibase.getAllStatements(raceID, 'P1346') -- P1346 is 'winner'for _, winner in pairs(p1346) dolocal wOf, thisjersey, bg_colorlocal q = winner.qualifiersif q thenif q.P642 and q.P642[1].snaktype == 'value' thenwOf = q.P642[1].datavalue.value.id -- P642 is 'of'endif q.P2912 and q.P2912[1].snaktype == 'value' thenthisjersey=q.P2912[1].datavalue.value.idif data.bg_color_table[thisjersey] thenbg_color = data.bg_color_table[thisjersey]endendendif winners[wOf] and thisjersey thenjerseytable={}table.insert(jerseytable,thisjersey)winners[wOf] = jersey(jerseytable)bgcolortable[wOf] = bg_colorendendreturn winners, bgcolortableendfunction p.listofstagesclassification(frame)-- WDlink_on is used to decide if a Wikidata logo will be shownlocal WDlink_on = wiki == "mk" or wiki == "ja"local displaytypeofstage = truelocal stageinfotable = {}local raceID, lf = get_and_checkID(frame)local w_race=isWomenrace(raceID)local sType--link for Grand Tourlocal GTid={['Q33881']=true,['Q33861']=true,['Q33937']=true}local thisGTfor _, p31 in statements(raceID, 'P31') doif GTid[p31.mainsnak.datavalue.value.id]==true then thisGT=p31.mainsnak.datavalue.value.id break endendlocal Sitelink,overallname, pointsname, mountainname, youngname, teamname, combativityname, supercombativityname, combinednameif thisGT thenif thisGT=='Q33881' thenSitelink = wikibase.getSitelink('Q2267539')if Sitelink then overallname="[["..Sitelink .."|"..translate("headoftableII",9,w_race).."]]" endSitelink = wikibase.getSitelink('Q175399')if Sitelink then pointsname="[["..Sitelink .."|"..translate("infobox",22,w_race).."]]" endSitelink = wikibase.getSitelink('Q927157')if Sitelink then mountainname="[["..Sitelink .."|"..translate("infobox",23,w_race).."]]" endSitelink = wikibase.getSitelink('Q641662')if Sitelink then youngname="[["..Sitelink .."|"..translate("infobox",25,w_race).."]]" endSitelink = wikibase.getSitelink('Q1436680')if Sitelink then teamname="[["..Sitelink .."|"..translate("infobox",28,w_race).."]]" endSitelink = wikibase.getSitelink('Q2094179')if Sitelink then combativityname="[["..Sitelink .."|"..translate("infobox",26,w_race).."]]" endSitelink = wikibase.getSitelink('Q2094179')if Sitelink then supercombativityname="[["..Sitelink .."|"..translate("infobox",26,w_race).."]]" endSitelink = wikibase.getSitelink('Q1835362')if Sitelink then combinedname="[["..Sitelink .."|"..translate("infobox",27,w_race).."]]" endelseif thisGT=='Q33861' thenSitelink = wikibase.getSitelink('Q1164275')if Sitelink then overallname="[["..Sitelink .."|"..translate("headoftableII",9,w_race).."]]" endSitelink = wikibase.getSitelink('Q641083')if Sitelink then pointsname="[["..Sitelink .."|"..translate("infobox",22,w_race).."]]" endSitelink = wikibase.getSitelink('Q641060')if Sitelink then mountainname="[["..Sitelink .."|"..translate("infobox",23,w_race).."]]" endSitelink = wikibase.getSitelink('Q641662')if Sitelink then youngname="[["..Sitelink .."|"..translate("infobox",25,w_race).."]]" endelseSitelink = wikibase.getSitelink('Q2532554')if Sitelink then overallname="[["..Sitelink .."|"..translate("headoftableII",9,w_race).."]]" endSitelink = wikibase.getSitelink('Q2241695')if Sitelink then pointsname="[["..Sitelink .."|"..translate("infobox",22,w_race).."]]" endSitelink = wikibase.getSitelink('Q1118296')if Sitelink then mountainname="[["..Sitelink .."|"..translate("infobox",23,w_race).."]]" endSitelink = wikibase.getSitelink('Q2330008')if Sitelink then combinedname="[["..Sitelink .."|"..translate("infobox",27,w_race).."]]" endendendlocal 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 stageslocal stages = mw.wikibase.getBestStatements(raceID, 'P527') -- P527 is 'has part'local columntable, jerseytable, bgcolortable={}, {}, {}for ii, v in ipairs(winners) doif v.QID thenlocal t = {key=ii, name=v.name, jersey='', bg_color='', used=false}for jj = 1, #stages+1 dot[jj] = { {}, {}, {} }  -- leader, first stage, number of stages consecutive (for rowspan)endcolumntable[v.QID] = tendend--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, 2local function itercolumns(columntable)local keys = {}for k, v in pairs(columntable) dokeys[v.key] = k --v.key is just the order of the columnsendlocal upto = 1return function ()while keys[upto] doupto = upto + 1return columntable[keys[upto-1]]endendendlocal timeOfRacefor ii, v in pairs(stages) doif v.mainsnak.snaktype == 'value' thenlocal somewinner = false --show the stagelocal stageID = v.mainsnak.datavalue.value.idlocal sitelink = mw.wikibase.getSitelink(stageID)if displaytypeofstage==true thensType = typeofstagelogo(stageID)endlocal 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.valueor ''local _, _, sNumber, sLetter = string.find(sOrdinal, '(%d+)(.*)')sNumber=sNumber or ''sLetter=sLetter or ''local label, section_titleif sOrdinal == "0" thenlabel, section_title = translate("func_prologue",1), "#" .. translate("func_prologue",1)elselabel, 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) dowin[v.QID] = ''if ii==1 then jerseytable[v.QID]='' endendwinner(lf,stageID, win, timeOfRace, false, WDlink_on, false, false) --fill win tableif ii<=2 then --only two first stagesjerseytable, bgcolortable=winnerjersey(stageID, jerseytable)endfor _, v in pairs(winners) doif v.QID and win[v.QID] ~= '' then--column infosomewinner=truecolumntable[v.QID][ii]["leader"]=win[v.QID]if ii==1 then --first stagecolumntable[v.QID][ii]["start"]=1  --start at row 1columntable[v.QID][ii]["rowspan"]=1  --1 consecutive stageelseif columntable[v.QID][ii-1]["leader"]==win[v.QID] then --same winner as past stage ,make previous longer and delete this onelocal initialstage=columntable[v.QID][ii-1]["start"]columntable[v.QID][ii]["start"]=initialstage --need because of the row abovecolumntable[v.QID][initialstage]["rowspan"]=columntable[v.QID][initialstage]["rowspan"]+1 --one more consecutive stagecolumntable[v.QID][ii]["rowspan"]=0else --new winnercolumntable[v.QID][ii]["start"]=ii --start at this row/stagecolumntable[v.QID][ii]["rowspan"]=1  --1 consecutive stageendcolumntable[v.QID].used=trueif ii<=2 then --read the jersey in the two first stages of a raceif columntable[v.QID].jersey == '' or columntable[v.QID].jersey==nil thencolumntable[v.QID].jersey=jerseytable[v.QID]columntable[v.QID].bg_color=bgcolortable[v.QID]endendendendtable.insert(stageinfotable,{sLink=sLink, sType=sType, somewinner=somewinner})endend--read parentlocal win= {}for _, v in pairs(winnersgen) doif v.QID thenwin[v.QID] = ''jerseytable[v.QID]=''endendlocal thiskeysomewinner = falsejerseytable, bgcolortable=winnerjersey(raceID, jerseytable)winner(lf,raceID, win, timeOfRace, false, WDlink_on, false, false)for _, v in pairs(winnersgen) doif win[v.QID] and win[v.QID] ~= '' thensomewinner=truethiskey=generaltoleader[v.QID]--fill the final classificationcolumntable[thiskey][#stages+1]["leader"]=win[v.QID]columntable[thiskey][#stages+1]["start"]=#stages+1columntable[thiskey][#stages+1]["rowspan"]=1--#stages is the last stageif (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 winnerif (type(columntable[thiskey][#stages-1]["leader"])=="string" and     win[v.QID]==columntable[thiskey][#stages-1]["leader"]) then --if there is a leader at forelast stagelocal initialstage=columntable[thiskey][#stages-1]["start"]columntable[thiskey][#stages]["start"]=initialstage --needed because of row abovecolumntable[thiskey][initialstage]["rowspan"]=columntable[thiskey][initialstage]["rowspan"]+1columntable[thiskey][#stages]["rowspan"]=0elsecolumntable[thiskey][#stages]["start"]=#stagescolumntable[thiskey][#stages]["rowspan"]=1endendif jerseytable[v.QID] and jerseytable[v.QID]~='' thencolumntable[thiskey].jersey=jerseytable[v.QID]columntable[thiskey].bg_color=bgcolortable[v.QID]endendendtable.insert(stageinfotable,{sLink=translate("listofstagesclassification",2,w_race), sType=nil, somewinner=somewinner}) --build the tablelocaltab=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') endfor v in itercolumns(columntable) doif v.used == true thenif v.jersey == '' then v.jersey = "_" endtRow:tag('th'):wikitext(v.name.."<br />"..v.jersey)endendlocal style--then fill the tablefor ii, v in pairs(stageinfotable) do --one stage=one row--stages linktRow=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;')endtCell:wikitext(v.sLink)if displaytypeofstage == true thentCell=tRow:tag('td')if ii==#stageinfotable then --general rowtCell:cssText('font-weight:bold; border-top: 2px black solid;')endif v.sType thentCell:wikitext(v.sType) --picture type of stageendend--add winnersfor y in itercolumns(columntable) doif y.used==true and not (ii==#stageinfotable and columntable['Q20882747']==y) then --only display used QIDif type(y[ii]["leader"])=="string" and type(y[ii]["rowspan"])=="number" then --actually check nil but it is a tablestyle=""if y[ii]["rowspan"]~=0 and (columntable['Q20882747']==y)==false thenif ii~=1 and ii~=#stageinfotable then style=style.." border-top:1px gray solid;" endif y.bg_color then style=style.." background-color:"..y.bg_color..";" endif ii==#stageinfotable then style=style.."font-weight:bold; border-top: 2px black solid;" endtRow:tag('td'):attr('rowspan',tostring(y[ii]["rowspan"])):cssText(style):wikitext(y[ii]["leader"])elseif (columntable['Q20882747']==y) then --no rowspan for stagestRow:tag('td'):wikitext(y[ii]["leader"])endelsetCell=tRow:tag('td')if ii~=#stageinfotable and v.somewinner==true thentCell:wikitext(translate("listofstagesclassification",1,w_race)) --not attributed elseif ii~=#stageinfotable then --emptyelseif v.somewinner==true then  --general rowtCell:cssText('border-top: 2px black solid'):wikitext(translate("listofstagesclassification",1,w_race)) --not attributed elsetCell:cssText('border-top: 2px black solid') --emptyendendendendendreturn tabend--M) Start listfunction 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 headerheader_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)  endfunction 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 headerheader_2 = {2, 3,4,5},-- translations 2, 3, 4, 5, 6 in function victories are printed in this orderitem=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))endlocal 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, etclocal h = {}local tBody = '' --row in our caselocal riderID, riderTeamLink, riderTeamID, riderDossard, riderLink, riderRanklocal q, gender, riderTeamCode, riderDNF, DSQ, catID, countryID, national_team_booleanriderID = p710.mainsnak.datavalue.value.idq= p710.qualifiersriderLink= getRiderLink(riderID, timeOfRace)if WDlink_on then riderLink=riderLink..wdLink(riderID) endif q and q.P1618 and q.P1618[1].snaktype == 'value' thenriderDossard = q.P1618[1].datavalue.value or ''elseriderDossard = ''endriderDNF='' riderRank = '' DSQ=''if q and q.P1352 and q.P1352[1].snaktype == 'value' then -- P1352 is rankingriderRank = 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' thenlocal dnf=q.P1534[1].datavalue.value.idif 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=''endif q.P1545 and q.P1545[1].snaktype == 'value' thenlocal stageofdnf=q.P1545[1].datavalue.valueif stageofdnf and string.len(stageofdnf)>1 thenriderDNF='<small>'..riderDNF.."-"..stageofdnf..'</small>'elseriderDNF=riderDNF.."-"..stageofdnfendendendendh = {jersey = {}, -- lots of jerseyIDvalue = {'', '', '', ''} -- points, time, time_gap, speed}if q and q.P2912 then -- P2912 is distinctive jerseyfor _, v in pairs(q.P2912) doif v.snaktype == 'value' thentable.insert(h.jersey, v.datavalue.value.id)endendendif 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')endlocal countryID = getNationality(riderID, timeOfRace,q)local uciCode=''local jerseytemp=''if countryID thenif wiki ~= "ar" then uciCode=uciCodeCountry(countryID)endriderLink = flag(countryID, timeOfRace) ..' '.. riderLink endif h.jersey[1] thenjerseytemp=champtitle(h.jersey) -- champtitle manages also the jerseyendriderTeamLink, riderTeamID, catID, countryID = getTeam(riderID, timeOfRace, q)riderTeamID=seasonToTeamID(riderTeamID)riderTeamCode= getTeamCode(riderID, timeOfRace, q)--Custom display for national selectionif data.natTeamCats[catID] and countryID thenif riderTeamCode and wikibase.getSitelink(countryID) then --for the refugee caseriderTeamCode='[['..wikibase.getSitelink(countryID)..'|'..riderTeamCode..']]'endriderTeamLink=flag(countryID, timeOfRace)..' '..riderTeamLinkelse --for non national selection display "ridername (FRA)""riderLink =riderLink..uciCodeendriderLink =riderLink..jerseytemplocal 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" endif istable thentBody:tag('td'):cssText(td_css):wikitext(riderTeamLink or "")endtBody: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}endfunction startlist_main(s, resultTable, tag)local ridertable, DStable, subtable = {}, {}, {}local DSID, DSLink, DSteamID, DSteamlocal 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 DSDSID = p286.mainsnak.datavalue.value.idDSLink= getRiderLink(DSID, timeOfRace)q= p286.qualifiersif q.P642 and q.P642[1].snaktype == 'value' thenDSteamID=q.P642[1].datavalue.value.idDSteamID=seasonToTeamID(DSteamID)endtable.insert(DStable, {DSLink=DSLink, DSteamID=DSteamID})endfor _, p710 in statements(s.item, 'P710') do -- P710 is participantstable.insert(ridertable, startlist_sub(p710, timeOfRace, WDlink_on, false,w_race))endtable.sort(ridertable, function(a, b)  --sort by team and then by bib and then by teamif 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, testlocal tSubtitle, tTitleif wiki == "ar" thentSubtitle=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))elsetSubtitle=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 teamslocal numberofteam=0local tDSif #ridertable==0 then--empty tablereturn nilelsefor ii=1,#ridertable  do--new teamif not (ii~=1 and ridertable[ii].riderTeamID==ridertable[ii-1].riderTeamID) or ii==1 then --ridertable[ii].riderTeamID and if thisDS and ii~=1 thentDS=insideTable:tag('tr')tDS:tag('td'):attr('colspan','3'):attr('align','center'):wikitext(translate("startlist",5,w_race).." "..thisDS)thisDS=nilendnumberofteam=numberofteam+1if math.fmod(numberofteam, 3 )==1 thenif ii~=1 thentag:node(thisTableRow) --a row with 3 tables inside, save and re-initendthisTableRow=mw.html.create('tr') endthisTeamTable= 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 teamfor _,v in pairs(DStable) doif v.DSteamID==ridertable[ii].riderTeamID thenif not thisDS thenthisDS=v.DSLinkelsethisDS=thisDS..", "..v.DSLinkendendendend--add the rider, also for old teaminsideTable:node(ridertable[ii].body)end--last DSif thisDS thentDS=insideTable:tag('tr')tDS:tag('td'):attr('colspan','3'):attr('align','center'):wikitext(translate("startlist",5,w_race).." "..thisDS)endtag:node(thisTableRow)return resultTableendendlocal 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 participantstable.insert(t_Body, startlist_sub(p710, timeOfRace, WDlink_on, true))endreturn sortAndConcat(t_Body, resultTable)end-- N) Rider rankinglocal function checkminmaxyear(minmaxyear,thisyear)if minmaxyear.minimum ==0 or thisyear<minmaxyear.minimum thenminmaxyear.minimum=thisyearendif minmaxyear.maximum==0 or thisyear>minmaxyear.maximum thenminmaxyear.maximum=thisyearend   return minmaxyearendfunction p.riderranking(frame)local tempID, lf=get_and_checkID(frame)local s = {item = tempID,lf=lf}return riderranking_main(s)endlocal function checkWorldTourTeam(itemID,year)local thisdate='+'..tostring(year).."-07-01T00:00:00Z"local catIDfor _, s in statements(itemID, 'P54') dop54 =checktime(s, s.qualifiers, thisdate) --present Teamif p54 thenteamId= p54.mainsnak.datavalue.value.id_, catID=getTeamLinkCat(teamId, thisdate)if catID=="Q6154783" or catID=="Q20638319" thenreturn trueendendendreturn falseendlocal function ranking_legend()local UCIlink, legendif wiki=="fr" thenUCIlink="https://www.uci.org/fr/route/classements" --see also https://dataride.uci.org/iframe/Rankings/10/legend= "  Légende : nc = non classé"elseUCIlink="https://www.uci.org/road/rankings" legend=""endreturn UCIlink, legendendlocal function riderranking_sub(w_race)local listofcalendar=data.listofmencalendarif w_race thenlistofcalendar=data.listofwomencalendarendlocal UCIQtoYear={}for k,v in pairs(data.UCIYearToQ) doUCIQtoYear[k]={}for kk, vv in pairs(v) doUCIQtoYear[k][vv]=kk  --calendar/Q = yearendendreturn listofcalendar, UCIQtoYearendfunction riderranking_main(s)local lf=s.lflocal thisCompetition, rank, thisyear, sitelink, q, gender, DSQ    local calendarlistpresent={}local gender=getGenderCode(s.item, 'm')local w_race=falseif gender=="f" then w_race=true endlocal minmaxyear= {minimum = 0, maximum = 0 }local listofcalendar, UCIQtoYear=riderranking_sub(w_race)local resultTable={}for ii=1900,2100,1 doresultTable[tostring(ii)]={}for _, calendar  in pairs(listofcalendar) doresultTable[tostring(ii)][calendar]={}endend--build the tablefor _, p1344 in statements(s.item, 'P1344') dothisCompetition = p1344.mainsnak.datavalue.value.idfor _, calendar  in pairs(listofcalendar) doif UCIQtoYear[calendar][thisCompetition] thenthisyear=UCIQtoYear[calendar][thisCompetition]minmaxyear=checkminmaxyear(minmaxyear,thisyear)q = p1344.qualifiersif q and q.P1352 and q.P1352[1].snaktype == 'value' then --rankresultTable[thisyear][calendar]["rank"] = tostring(tonumber(q.P1352[1].datavalue.value.amount)) --without the tonumber, there can be +1 instead of 1resultTable[thisyear][calendar]["DSQ"] = isdisqualified(p1344, q) or ""calendarlistpresent[calendar]=truesitelink=mw.wikibase.getSitelink(thisCompetition)resultTable[thisyear][calendar]["sitelink"]=sitelinkendendendend--display resultif minmaxyear.minimum~=0 thenlocal 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)) --yearfor ii=minmaxyear.minimum,minmaxyear.maximum,1 dotRow:tag('th'):attr("width","50px"):css('background-color',backgroundColor):css("text-align","center"):css("padding","1px 1px"):wikitext(tostring(ii))endfor _, calendar  in pairs(listofcalendar) doif calendarlistpresent[calendar] thensitelink=mw.wikibase.getSitelink(data.UCImaster[calendar])local tRow=finalTable:tag('tr')local tCell = tRow:tag('th'):cssText("text-align:" .. textalign .. ";") -- leftlocal calendar_name=translate("riderranking",data.KeytoRiderRankingCode[calendar],w_race)if sitelink thentCell:wikitext('[['..sitelink..'|'..calendar_name..']]')elsetCell:wikitext(calendar_name)endfor yy=minmaxyear.minimum,minmaxyear.maximum,1 dothisyear=tostring(yy)color="white"local impossible=false--we need to check the impossibility here, as it is impossible even if nothing is in P1344if 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 thenif checkWorldTourTeam(s.item,thisyear) thenimpossible=trueend--between 2016 and 2018 no contradiction--after 2019, it depends on the nationalityelseif tonumber(thisyear)>=2019 thenlocal countryID=getNationality(s.item,'+'..tostring(year).."-07-01T00:00:00Z")if data.continental_calendar[calendar] and not data.continental_calendar[calendar][countryID] thenimpossible=trueendendelseif calendar=="UWT" then--non member of World Tour team cannot point in the WTif tonumber(thisyear)>=2005 and tonumber(thisyear)<=2015 thenif not checkWorldTourTeam(s.item,thisyear) thenimpossible=trueendendendif resultTable[thisyear][calendar]["rank"] or impossible thenif impossible thentRow:tag('td'):css('background-color',backgroundColorLight)elseif resultTable[thisyear][calendar]["rank"]=="1" thencolor="gold"elseif (2<=tonumber(resultTable[thisyear][calendar]["rank"])) and (tonumber(resultTable[thisyear][calendar]["rank"])<=3) thencolor="YellowGreen"elseif (4<=tonumber(resultTable[thisyear][calendar]["rank"])) and (tonumber(resultTable[thisyear][calendar]["rank"])<=10) thencolor="silver"endtCell=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"] thentCell:wikitext('[['..resultTable[thisyear][calendar]["sitelink"]..'|'..rank..']]')elsetCell:wikitext(rank)endend--this ranking exist for this year, but the rider is not rankedelseif yy>=data.UCIcalendarstartend[calendar].b and(data.UCIcalendarstartend[calendar].e==0 or yy<=data.UCIcalendarstartend[calendar].e) then if wiki=="fr" thentRow:tag('td'):wikitext(' nc ')elsetRow:tag('td'):wikitext(' - ')end--this ranking does not exist for this yearelse tRow:tag('td'):css('background-color',backgroundColorLight)endendendendlocal tableyearsize=minmaxyear.maximum-minmaxyear.minimum+2local 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  finalTableendendfunction 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 "" endlocal w_race=falseif calendar_key=="women" or calendar_key=="WWT" or calendar_key=="WWC" thenw_race=trueendlocal 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))endlocal function get_teamranking(seasonID, w_race, UCIQtoYear,listofcalendar, tTable,gender)--fill resultTablelocal done, thisyear, q, done, rider, riderLink, countryID, rank, thisdate, teamrankfor _, p1344 in statements(seasonID, 'P1344') dothisCompetition = p1344.mainsnak.datavalue.value.idfor _, calendar  in pairs(listofcalendar) doif UCIQtoYear[calendar][thisCompetition] thenthisyear=UCIQtoYear[calendar][thisCompetition]thisdate='+'..tostring(thisyear).."-07-01T00:00:00Z"rank=nilif tTable[calendar] thentTable[calendar][thisyear]={}elseerror("tTable badly initialized")endq = p1344.qualifiersdone=false--get team ranklocal 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' thenif q.P642[1].datavalue.value.id=="Q20653564" thensuffix=" (GSII)"elseif q.P642[1].datavalue.value.id=="Q20653566" thensuffix=" (GSIII)"endendendif q and q.P1352 and q.P1352[1].snaktype == 'value' then --rankteamrank= tonumber(q.P1352[1].datavalue.value.amount) tTable[calendar][thisyear]["teamrank"]=number(gender,teamrank,wiki)..suffixdone=trueend--get best rider rankif q and q.P1545 and q.P1545[1].snaktype == 'value' then --participantrank = tostring(tonumber(q.P1545[1].datavalue.value))done=trueend--get best riderif q and q.P710 and q.P710[1].snaktype == 'value' then --participantrider = q.P710[1].datavalue.value.idriderLink = getRiderLink(rider, thisdate)countryID = getNationality(rider, thisdate)if countryID thenriderLink = flag(countryID, thisdate) .. ' ' .. riderLinkendif rank thenrank=number(gender,tonumber(rank),wiki)riderLink=riderLink.." ("..rank..")"endtTable[calendar][thisyear]["rider"]=riderLinkdone=trueendsitelink=mw.wikibase.getSitelink(thisCompetition)tTable[calendar][thisyear]["sitelink"]=sitelinkendendendreturn tTableendfunction teamranking_main(s, resultTable)local lf=s.lflocal t_Body = {}local gender="m"if s.w_race then gender="f" end--init, reverse UCIQtoYearlocal UCIQtoYear={}UCIQtoYear[s.calendar_key]={}if data.UCIYearToQ[s.calendar_key] thenlocal v=data.UCIYearToQ[s.calendar_key]for kk, vv in pairs(v) doUCIQtoYear[s.calendar_key][vv]=kkendendlocal tTable={}tTable[s.calendar_key]={}for ii, p527 in statements(s.item, "P527") dotTable=get_teamranking(p527.mainsnak.datavalue.value.id, w_race,                         UCIQtoYear,{s.calendar_key}, tTable,gender)endlocal t=tTable[s.calendar_key]if t thenfor thisyear, v in pairs(t) dolocal 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"] thentCell:wikitext('[['..v["sitelink"]..'|'..thisyear..']]')elsetCell:wikitext(thisyear)endif v["teamrank"] thentRow:tag('td'):wikitext(v["teamrank"]):css("text-align","center")elsetRow:tag('td'):wikitext(" - "):css("text-align","center")endif v["rider"] thentRow:tag('td'):wikitext(v["rider"])elsetRow:tag('td'):wikitext(" - ")endtable.insert(t_Body, {sortkey=thisyear, body=tRow})endendresultTable=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 resultTableendlocal function toboolean(str)if str=="true" thenreturn trueelseif str=="false" thenreturn falseelsereturn strendend--=== O) Rider infoboxlocal function convertDate(date1, beginOrEnd, initialYear, finalYear)if not date1 thenif beginOrEnd==0 then --beginy1=tostring(initialYear)m1="01"d1="01"elsey1=tostring(finalYear)m1="12"d1="31"endelse_, _, y1,m1,d1 = string.find(date1, "(%d+)-(%d+)-(%d+)")if m1 ==nil or m1=="00" thenif beginOrEnd==0 then --beginm1="01"d1="01"else--endm1="12"d1="31"endendendreturn '+'..y1.."-"..m1.."-"..d1.."T00:00:00Z"endlocal function listofTeam(itemID, initialYear, finalYear, PID) --first we have to read P54 of the rider--alternative P6087 for managed teamlocal 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=t1local t_finalYear=t2for ii, p54 in statements(itemID, PID) do --itemID loaded in presentTeamlocal q = p54.qualifiersif q thenlocal sTime, eTime=getStartEndfromQuali(q)--min/max if sTime theny=tonumber(string.sub(sTime, 2, 5))if y < t_initialYear thent_initialYear=yendif y>t_finalYear thent_finalYear=yendendif eTime theny=tonumber(string.sub(eTime, 2, 5))if y < t_initialYear thent_initialYear=yendif y>t_finalYear thent_finalYear=yendendendendif t_initialYear~=t1 then initialYear=t_initialYear endif t_finalYear~=t2 then finalYear=t_finalYear endfor ii, p54 in statements(itemID, PID) do --itemID loaded in presentTeamif p54 thenteamId=p54.mainsnak.datavalue.value.idelseteamId=nilendlocal q = p54.qualifiersif q thenlocal sTime, eTime=getStartEndfromQuali(q)sTime=convertDate(sTime, 0, initialYear, finalYear)eTime=convertDate(eTime, 1, initialYear, finalYear)if q.P39 and q.P39[1] andq.P39[1].snaktype == 'value' thenstagiaire = q.P39[1].datavalue.valueelsestagiaire = nilenddis=checkDis(q)table.insert(riderteam,{teamId=teamId, startTime=sTime, endTime=eTime, stagiaire=stagiaire, dis=dis})endendreturn riderteam, initialYear, finalYearend--format the date for display of the teamlocal function riderFormatDate(thisDate) if thisDate=='' thenreturn ''elselocal month=math.ceil(thisDate['month']/2)if month==12 or month==1 thenreturn thisDate['year']elselocal date1='+'..thisDate['year'].."-"..month.."-".."01".."T00:00:00Z"--local newobj = Complexedate.splitDate(date1)  if month == 0 or month==nil thenreturn thisDate['year']elsereturn month..'.'..thisDate['year']endendendendlocal function getTeamInfo(teamId,mm,yy,dd,managedTeam)--get the nature and name of the team for the date mm,yymm=tostring(mm)yy=tostring(yy)dd=tostring(dd)if mw.ustring.len(mm)==1 then mm='0'..mm endif mw.ustring.len(dd)==1 then dd='0'..dd endthistime='+'..yy.."-"..mm.."-"..dd.."T00:00:00Z"local sitelink, teamNature=getTeamLinkCat(teamId, thistime, false) local cat, booleanif managedTeam then   cat=data.nationalcatelse   cat=data.amateurcatendif cat[teamNature] then --clubboolean=true--amateur / national selection elseboolean=false--pro  / not national selectionendreturn boolean, sitelinkend--for managed team, the table should be splat, as we can be national trainer and team trainer at the same timelocal function analyzeManagedTeam(teamRider, initialYear,finalYear)local natTeamOut, managedTeamOut={},{}local dis="road"local managedTeam=truefor i=1,24 do --init tablenatTeamOut[i]={}managedTeamOut[i]={}for j=initialYear,finalYear donatTeamOut[i][j]={ amateurTeam, link, stagiaire=nil}managedTeamOut[i][j]={amateurTeam,link, stagiaire=nil}endendlocal teamId, natTeam, sitelinklocal sYear, sMonth,eYear, eMonth, sDay, eDayif teamRider==nil then return nil endfor _, v in pairs(teamRider) do --for each team where was the riderif 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 congruencefor yy=sYear,eYear do for mm=1,12 dolocal mmindex=(mm-1)*2+1--avoid reading info where the team is not the one of the ridergetinfo=trueif (yy==sYear and mm<sMonth) or (yy==eYear and mm>eMonth) thengetinfo=falseendif getinfo thenif (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 thennatTeamOut[mmindex+1][yy]['amateurTeam']=truenatTeamOut[mmindex+1][yy]['link']=sitelinkelsemanagedTeamOut[mmindex+1][yy]['amateurTeam']=falsemanagedTeamOut[mmindex+1][yy]['link']=sitelinkendelsenatTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'01', managedTeam)if natTeam thennatTeamOut[mmindex][yy]['amateurTeam']=truenatTeamOut[mmindex][yy]['link']=sitelinkif natTeamOut[mmindex+1][yy]['amateurTeam']==nil or v['stagiaire'] then --to avoid problem with team name change during the monthnatTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'28',managedTeam)natTeamOut[mmindex+1][yy]['amateurTeam']=true --a nat team stays a nat teamnatTeamOut[mmindex+1][yy]['link']=sitelinkendelsemanagedTeamOut[mmindex][yy]['amateurTeam']=falsemanagedTeamOut[mmindex][yy]['link']=sitelinkif managedTeamOut[mmindex+1][yy]['amateurTeam']==nil or v['stagiaire'] then --to avoid problem with team name change during the monthnatTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'28',managedTeam)managedTeamOut[mmindex+1][yy]['amateurTeam']=false --a nat team stays a nat teammanagedTeamOut[mmindex+1][yy]['link']=sitelinkendendendendendendendendendreturn natTeamOut, managedTeamOut --a filled matrix with the link and nature of the teamsendlocal function analyzeTeam(teamRider, initialYear,finalYear, dis)local teamOut={}local managedTeam=falsefor i=1,24 do --init tableteamOut[i]={}for j=initialYear,finalYear doteamOut[i][j]={ amateurTeam, link, stagiaire}endendlocal teamId, amateurTeam, sitelinklocal sYear, sMonth,eYear, eMonth, sDay, eDayif teamRider==nil then return nil endfor _, v in pairs(teamRider) do --for each team where was the riderif 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 congruencefor yy=sYear,eYear do for mm=1,12 dolocal mmindex=(mm-1)*2+1--avoid reading info where the team is not the one of the ridergetinfo=trueif (yy==sYear and mm<sMonth) or (yy==eYear and mm>eMonth) thengetinfo=falseendif getinfo thenif (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']=amateurTeamteamOut[mmindex+1][yy]['link']=sitelinkteamOut[mmindex+1][yy]['stagiaire']=v['stagiaire']elseamateurTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'01', managedTeam)teamOut[mmindex][yy]['amateurTeam']=amateurTeamteamOut[mmindex][yy]['link']=sitelinkteamOut[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 monthamateurTeam, sitelink=getTeamInfo(v['teamId'],mm,yy,'28',managedTeam)teamOut[mmindex+1][yy]['amateurTeam']=amateurTeamteamOut[mmindex+1][yy]['link']=sitelinkteamOut[mmindex+1][yy]['stagiaire']=v['stagiaire']endendendendendendendendreturn teamOut --a filled matrix with the link and nature of the teamsendlocal 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'] thentable.insert(teamAmateur,ins)elsetable.insert(teamPro,ins)endreturn teamAmateur,teamProendlocal function synthetizeTable(analyzedTeam, initialYear,finalYear)local teamPro, teamAmateur, tempTeam, tempsDate, tempeDate={}, {},{},{},{}local empty=truelocal active=false    --bring together successive month with identical contentfor yy=initialYear,finalYear dofor mm=1,24 dolocal v=analyzedTeam[mm][yy]if v['amateurTeam']~=nil thenif empty then --first lineactive=trueempty=falsetempTeam=vtempsDate['month']=mmtempsDate['year']=yyelseif tempTeam['amateurTeam']==v['amateurTeam'] and tempTeam['link']==v['link']and tempTeam['stagiaire']==v['stagiaire'] then --no changeif yy==finalYear and mm==24 then--present teamteamAmateur,teamPro=insertTeam(teamAmateur,teamPro,tempsDate,'',tempTeam)endelse--change--save the oldif active then --if active false then it was already savedif mm==1 thentempeDate['year']=yy-1tempeDate['month']=24elsetempeDate['year']=yytempeDate['month']=mm-1endteamAmateur,teamPro=insertTeam(teamAmateur,teamPro,tempsDate,tempeDate,tempTeam)end--save the newactive=truetempTeam=vtempsDate['month']=mmtempsDate['year']=yyend --changeend--first lineelseif active then --there was a team and now there is an empty periodactive=false--save the oldif mm==1 thentempeDate['year']=yy-1tempeDate['month']=24elsetempeDate['year']=yytempeDate['month']=mm-1endteamAmateur,teamPro=insertTeam(teamAmateur,teamPro,tempsDate,tempeDate,tempTeam)tempTeam['link']=nil --avoid problem if the rider comes back in the same teamend  end-- for mmend--for yyreturn teamAmateur,teamProendlocal function listOfManagedTeamTable(itemID, initialYear,finalYear)local managedTeamRider, initialYear, finalYear = listofTeam(itemID, initialYear,finalYear,'P6087')--raw list of teamif not managedTeamRider thenreturn nil, nilendlocal natTeamOut, managedTeamOut=analyzeManagedTeam(managedTeamRider, initialYear,finalYear) --table with links and nature of teamslocal nationalTeam,_=synthetizeTable(natTeamOut, initialYear,finalYear)local _,managedTeam=synthetizeTable(managedTeamOut, initialYear,finalYear)return nationalTeam,managedTeamendlocal function listOfTeamTable(itemID, initialYear,finalYear)local teamRider, initialYear, finalYear = listofTeam(itemID, initialYear,finalYear,'P54')--raw list of teamif not teamRider thenreturn nil, nilendlocal analyzedTeam1=analyzeTeam(teamRider, initialYear,finalYear, "road") --table with links and nature of teamslocal teamAmateur,teamPro=synthetizeTable(analyzedTeam1, initialYear,finalYear) --table formated, globallocal 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, teamTrackendlocal function getBirthDeathDate(entityID, display_age)local birthDate=firstValue(entityID, 'P569', 'time')local deathDate=firstValue(entityID, 'P570', 'time')local temp2, temp3, birth, death, initialYear, finalYear, agelocal gender=getGenderCode(entityID, 'm')local w_race=falseif gender=="f" then w_race=true endif birthDate thenlocal 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)    endif not deathDate and display_age~=false thentemp2=' ('..tostring(age)..' '..ans..')<br/>'elsetemp2='<br/>'end    birth=birthDateFormatted..temp2..birthPlaceLinkelse    birth=nilendif deathDate thenlocal deathDateFormatted= funcDate(deathDate, 'long')local deathPlace= firstValue(entityID, 'P20', 'id')local deathPlaceLink=''if deathPlace then deathPlaceLink=getPlaceLink(deathPlace, deathDate) endif 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/>'    elsetemp2=' ('..tostring(age)..' '..ans..')<br/>'endelsetemp2='<br/>'enddeath=deathDateFormatted..temp2..deathPlaceLinkelse    death=nilendreturn birth, death, initialYear, finalYearendlocal function presentTeam(itemID)local tToday=os.date("*t")  if mw.ustring.len(tToday["month"])==1 then tToday["month"]='0'..tToday["month"] endif mw.ustring.len(tToday["day"])==1 then tToday["day"]='0'..tToday["day"] endlocal today='+'..tToday["year"].."-"..tToday["month"].."-"..tToday["day"].."T00:00:00Z"local plural=false    local teamId, result, teamLink, teamLinkRoad, rowfor _, s in statements(itemID, 'P54') dop54 =checktime(s, s.qualifiers, today) --present Teamif p54 thenteamId= p54.mainsnak.datavalue.value.idteamLink=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    endendendif teamLinkRoad and result then --put road firstresult = teamLinkRoad..' (route)<br/>'..resultplural= trueelseif teamLinkRoad thenresult = teamLinkRoadendreturn result, pluralendlocal function getSomeNames(details,entityID, PID, index, display_language)local rows={}if not details[index].content thenlocal listOfNames=getFormerNames(entityID, PID)if listOfNames thenfor _, v in pairs(listOfNames) dorows[#rows + 1]=v[3]if v[2] and v[2]~='' thenrows[#rows]=rows[#rows]..' <small>('..v[2]..')</small>'endif display_language thenrows[#rows]=rows[#rows]..' <b><small>('..v[4]..')</small></b>'endendif #rows>0 thendetails[index].content = table.concat(rows, '<br/>') endendendend--for wikidata inputlocal function teamTable(tab, teamAmateur, title_singular, title_plural)if teamAmateur and #teamAmateur>0 thenif #teamAmateur==1 thentab:node(addATitle(title_singular)) elsetab:node(addATitle(title_plural)) endfor _, v in pairs(teamAmateur) do local nametemp=v['link']if v['sDate']==v['eDate'] thenperiodtemp=v['sDate']elseperiodtemp=v['sDate']..'-'..v['eDate']endif v['stagiaire'] thenlocal stagiaire = string.gsub(getLabelFallback('Q2328847',lang_priority), "%b()", "")nametemp=nametemp..' ('..stagiaire..')'endtab:node(addARow(periodtemp or '',nametemp)) --period, nameendendend--for local datalocal function localTeamTable(tab, names, periods, title_singular, title_plural)if names thennames =  mw.text.split(names, '<br />')periods = mw.text.split(periods or '', '<br />')if #names==1 thentab:node(addATitle(title_singular)) elsetab:node(addATitle(title_plural)) endfor i, name in pairs(names) dotab:node(addARow(periods[i] or '', name))endendendfunction 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=falseif gender=="f" then w_race=true endlocal 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 titlelocal subtitle = {{ name = translate("riderinfobox",51,w_race)}, -- insertion of a sub-title}    --separated to have a titlelocal victories = {{ name = translate("riderinfobox",38,w_race)}, -- main victories}--separated to have a titlelocal medals = {{ name = translate("riderinfobox",47,w_race)}, -- main victories}local others = get_others_dic()local name =  getLabelFallback(entityID) or ''local display_birthnameastitle=falsefor _, value in pairs(display_birthnameastitle_in_riderinfobox) do -- get data if country should be printed in this wikiif value == wiki then display_birthnameastitle=true endendgetLocalContent(subtitle, lf.args)if not subtitle[1].content and display_birthnameastitle thenlocal p1477 = mw.wikibase.getBestStatements(entityID, "P1477") if p1477[1] and p1477[1].mainsnak.snaktype == 'value' thensubtitle[1].content = p1477[1].mainsnak.datavalue.value.text..' <b><small>('..p1477[1].mainsnak.datavalue.value.language..')</small></b>'endif not subtitle[1].content then    local p1559 = mw.wikibase.getBestStatements(entityID, "P1559") -- P580 is start timeif p1559[1] and p1559[1].mainsnak.snaktype == 'value' thensubtitle[1].content = p1559[1].mainsnak.datavalue.value.text..' <b><small>('..    p1559[1].mainsnak.datavalue.value.language..')</small></b>'endendendinfoGetOthers(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, listOfShortNameslocal icon = ' [[File:Cycling (road) pictogram.svg|35px]]'local display_language=falsefor _, value in pairs(display_language_in_riderinfobox) do -- get data if country should be printed in this wikiif value == wiki then display_language=true endendlocal display_age=truefor _, value in pairs(display_noage_in_riderinfobox) do -- get data if country should be printed in this wikiif value == wiki then display_age=false endendlocal display_nickname=truefor _, value in pairs(display_nonickname_in_riderinfobox) do -- get data if country should be printed in this wikiif value == wiki then display_nickname=false endendlocal display_cm=falsefor _, value in pairs(display_cm_in_riderinfobox) do -- get data if country should be printed in this wikiif value == wiki then display_cm=true endend--getSomeNames(details, entityID, 'P1477', 1, display_language) --birthname--less prio than P1477if display_nickname thengetSomeNames(details, entityID, 'P1559', 1, display_language) --birthname, bisgetSomeNames(details, entityID, 'P1449', 2, display_language) --nick nameendgetSomeNames(details, entityID, 'P1448', 3, display_language) --official nameif display_nickname thengetSomeNames(details, entityID, 'P1813', 4, display_language) --short nameendlocal birth, death, initialYear, finalYear=getBirthDeathDate(entityID, display_age)if not details[5].content thendetails[5].content=birthendif not details[6].content thendetails[6].content= deathendlocal display_flag=falsefor _, value in pairs(display_flag_in_riderinfobox) do -- get data if country should be printed in this wikiif value == wiki then display_flag=true endendlistWPlinkChrono(details, 7, entityID, {'P1532','P27'}, 'country', initialYear, display_flag)if not details[8].content thenlocal pluraldetails[8].content, plural=presentTeam(entityID)if plural thendetails[8].name = details[8].name_pluralendend--specialitylistWPlink(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)--heightif not details[12].content thendetails[12].content=getHeight(entityID, display_cm) endlocal display_weight=truefor _, value in pairs(display_noweight_in_riderinfobox) do -- get data if country should be printed in this wikiif value == wiki then display_weight=false endend--weightif not details[13].content and  display_weight thendetails[13].content=getWeight(entityID)end--award, should be table--awards look weird--if not details[14].content then--listWPlink(details, 14, entityID, 'P166',false)--endlocal amateurTeam, nonUCITeam, proTeam, UCITeam --local datalocal amateurWD=truelocal proWD=truelocal managedWD=truelocal teamAmateur,teamPro, teamMountainBike, teamCycloCross, teamTrack=listOfTeamTable(entityID, initialYear, finalYear)local nationalTeam, managedTeam=listOfManagedTeamTable(entityID, initialYear, finalYear)local managedTeam_names, managedTeam_periods, amateurTeam_names, amateurTeam_periodslocal nonUCITeam_names, nonUCITeam_periods, proTeam_names, proTeam_periodslocal nationalTeam_names, nationalTeam_periodslocal UCITeam_names, UCITeam_periodsif teams[1].content thenmanagedTeam_names=teams[1].contentmanagedTeam_periods=teams[2].contentmanagedWD=falseendif teams[3].content thenamateurWD=falseamateurTeam_names=teams[3].contentamateurTeam_periods=teams[4].contentendif teams[5].content then amateurWD=falsenonUCITeam_names=teams[5].contentnonUCITeam_periods=teams[6].contentendif teams[7].content thenproWD=falseproTeam_names=teams[7].contentproTeam_periods=teams[8].contentendif teams[9].content thenproWD=falseUCITeam_names=teams[9].contentUCITeam_periods=teams[10].contentendif teams[11].content thennationalTeam_names=teams[11].contentnationalTeam_periods=teams[12].contentmanagedWD=falseend--plate and grabtab = 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)endinfoFillOthersDetails(tab, others, details,translate("riderinfobox",55,w_race),"260px")if amateurWD thenteamTable(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))endif proWD thenteamTable(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))elselocalTeamTable(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 teamsif managedWD thenteamTable(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))elselocalTeamTable(tab,managedTeam_names, managedTeam_periods,translate("riderinfobox",23,w_race), translate("riderinfobox",24,w_race))endif victories[1].content thentab:node(addATitle(translate("riderinfobox",38,w_race))) tab:tag('tr'):tag('td'):css('vertical-align','top'):attr('colspan','2'):wikitext(victories[1].content)endif medals[1].content thentab:node(addATitle(translate("riderinfobox",47,w_race))) tab:tag('tr'):tag('td'):css('vertical-align','top'):attr('colspan','2'):wikitext(medals[1].content)endwdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/riderinfobox", translate("raceinfobox",26,w_race), entityID)return tabend--=== P) Team infoboxlocal function get_rider_number(entityID, details, index)if not details[index].content thenlocal riders = #wikibase.getAllStatements(entityID, 'P527') -- P527 is 'has part'if riders > 0 thenlocal stagiaire = string.gsub(getLabelFallback('Q2328847'), "%b()", "")local nb_stagiaires=0for ii, p527 in statements(entityID, 'P527') dolocal q = p527.qualifiersif q and q.P39 and q.P39[1] andq.P39[1].snaktype == 'value' and   q.P39[1].datavalue.value=='Q2328847'then   nb_stagiaires=nb_stagiaires+1endend    if nb_stagiaires>0 thendetails[index].content = riders ..' ('.. tostring(nb_stagiaires).." "..stagiaire..')'elsedetails[index].content = ridersendendendendfunction 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" endlocal 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 sportif not details[1].content and sport_id thendetails[1].content = WPlinkpure(sport_id)endlocal timeOfRace=getTimeOfRace(seasonID)local initialYearif timeOfRace theninitialYear=string.sub(timeOfRace,2,5)elseerror("no timeOfRace found for "..seasonID)end    local sitelink, catID, _=getTeamLinkCat(seasonID, timeOfRace, nil, true)    --teamif not details[2].content then details[2].content=sitelinkend--typelistWPlinkChrono(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    endendlistWPlinkChrono(details, 4, seasonID, {'P1998'}, 'UCIcode', initialYear, nil, true,true)local display_flag=truelistWPlinkChrono(details, 5, seasonID, {'P1532','P17'}, 'country', initialYear, display_flag,nil,true)-- number of ridersget_rider_number(seasonID, details, 6)-- official siteif not details[7].content thendetails[7].content = officialSite(seasonID)end--SponsorlistWPlinkChrono(details, 8, seasonID, {'P859'}, 'rider', initialYear, nil, nil, true)--bikelistWPlinkChrono(details, 9, seasonID, {'P1876'}, 'rider', initialYear, nil, nil, true)--budgetif not details[10].content thenp=firstValue(seasonID,'P2769')if p and p.mainsnak.snaktype == 'value' thenlocal amount=p.mainsnak.datavalue.value.amountlocal unit=p.mainsnak.datavalue.value.unitdetails[10].content=dispmoney(amount, unit)endendlocal listofcalendar, UCIQtoYear=riderranking_sub(w_race)local tTable={} --no need for year, it is clearfor _, calendar  in pairs(listofcalendar) dotTable[calendar]={}end--not over-writable presentlytTable=get_teamranking(seasonID, w_race, UCIQtoYear,listofcalendar, tTable,gender)--Staff, there can be several-- managerlistWPlinkChrono(managers, 1, seasonID, {'P505'}, 'rider', initialYear, nil, nil, true)-- sports directorlistWPlinkChrono(managers, 2, seasonID, {'P286'}, 'rider', initialYear, nil, nil, true)--Build the tabletab = infoInitTab("300px", name, icon, 2)infoFillOthersDetails(tab, others, details, translate("teaminfobox",1,w_race))--in case there are several namesif listOfNames and #listOfNames>1 then --Always display a list of namestab:node(addATitle(translate("teaminfobox",19,w_race))) for _, v in pairs(listOfNames) dotab:node(addARow(v[2],v[3])) --period, nameendendif managers[1].content or managers[2].content thentab:node(addATitle(translate("teaminfobox",18,w_race)))for _, row in ipairs(managers) do    tab:node(addARow(row.name, row.content)) --node check itself if nilendend--Palmarestab:node(addATitle(translate("raceinfobox",20,w_race)))local wins = #wikibase.getAllStatements(seasonID, 'P2522') if wins thentab:node(addARow(translate("victories",2,w_race),tostring(wins)))endfor calendar, v_calendar in pairs(tTable) doif v_calendar[initialYear] thenlocal v=v_calendar[initialYear]local calendar_name=translate("riderranking",KeytoRiderRankingCode[calendar],w_race)if v["sitelink"] thentab:node(addATitle('[['..v["sitelink"]..'|'..calendar_name..']]'))elsetab:node(addATitle(calendar_name))endif v["teamrank"] thentab:node(addARow(translate("riderranking",20,w_race),v["teamrank"]))endif v["rider"] thentab:node(addARow(translate("riderranking",21,w_race),v["rider"]))endendend-- an empty line with a title under the form in the form of an image or third-party templateif 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 tabendfunction p.teaminfobox(frame)-- If true, winners will have Wikidata logos with link to Wikidatalocal 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 sportif not details[1].content and sport_id thendetails[1].content = WPlinkpure(sport_id)endlocal 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 codelistWPlinkChrono(details, 3, entityID, {'P1998'}, 'UCIcode', initialYear, nil, true)-- сountrylocal display_flag=truelistWPlinkChrono(details, 4, entityID, {'P1532','P17'}, 'country', initialYear, display_flag)--creation dateif not details[5].content and creation thendetails[5].content = funcDate(creation, "onlyyear" )end-- disparition datelocal disparition=firstValue(entityID, 'P576', 'time')if not details[6].content and disparition thendetails[6].content =  funcDate(disparition,"onlyyear")end--populate tRacelistOfWinners(entityID, tRace,true,lf)-- number of seasonif not details[7].content and tRace.numberOfEditions and tRace.lastEditionYear thendetails[7].content = tostring(tRace.numberOfEditions).." (" .. translate("teaminfobox",12,w_race) .. " "..tostring(tRace.lastEditionYear)..")"end-- official siteif not details[8].content thendetails[8].content = officialSite(entityID)end--9 is sponsorlistWPlinkChrono(details, 9, entityID, {'P859'}, 'rider', initialYear)--10 is bike listWPlinkChrono(details, 10, entityID, {'P1876'}, 'rider', initialYear)--11 budgetlistWPlinkChrono(details, 11, entityID, {'P2769'}, 'money', initialYear)-- managerlistWPlinkChrono(managers, 1, entityID, {'P505'}, 'rider', initialYear)-- sports directorlistWPlinkChrono(managers, 2, entityID, {'P286'}, 'rider', initialYear)--Build the tabletab = infoInitTab("300px", name, icon, 2)--former nameswiki_listOfNamesAtBottom={'ru'}local listOfNamesAtBottom = falsefor _, value in pairs(wiki_listOfNamesAtBottom) do -- if value == wiki then listOfNamesAtBottom = true endend--picture at the topinfoFillOthersDetails(tab, others, details, translate("teaminfobox",1,w_race),"260px")if managers[1].content or managers[2].content thentab:node(addATitle(translate("teaminfobox",18,w_race)))for _, row in ipairs(managers) do    tab:node(addARow(row.name, row.content)) --node check itself if nilendendif listOfNames and #listOfNames>0 then --Always display a list of namestab:node(addATitle(translate("teaminfobox",19,w_race))) for _, v in pairs(listOfNames) dotab:node(addARow(v[2],v[3])) --period, nameendend-- an empty line with a title under the form in the form of an image or third-party templateif 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-- managerlistWPlinkChrono(managers_season, 1, tRace.lastID, {'P505'}, 'rider', tRace.lastEditionYear, nil, nil, true)-- sports directorlistWPlinkChrono(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 yeardetails_season[2].content=tostring(wins)endinfoFillOthersDetails(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)endif tRace.nextLink thenoutTable = 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)endendwdDoc(tab, "d:Wikidata:WikiProject Cycling/Documentation/raceinfobox", translate("raceinfobox",26,w_race), entityID)return tabend--== teamriderCompetitionrankingfunction p.teamriderCompetitionranking(frame)local tempID, lf=get_and_checkID(frame)local calendarIDlocal timeOfRace=getTimeOfRace(tempID)local initialYearif timeOfRace thenyear=string.sub(timeOfRace,2,5)endlocal 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 = 12local key=get_arg(2,frame)if key and year thencalendarID=data.UCIYearToQ[key][year]header_1_number = header_1_tab[key]endlocal w_race=isWomenteam(calendarID)if not calendarID or calendarID == "" then return "" endlocal 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 tableAlf=lf,w_race=w_race}return teamriderCompetitionranking_main(s,tableA(s))endlocal function get_competition_bestrider(RaceID, seasonID, gender)local riderLink, rank, disqualified, cancelled, q local bold=falsefor _, p1344 in statements(seasonID, 'P1344') do thisCompetition = p1344.mainsnak.datavalue.value.idif thisCompetition and thisCompetition==RaceID thenq = p1344.qualifiersif q thenif q and q.P1352 and q.P1352[1].snaktype == 'value' then --rankrank= tonumber(q.P1352[1].datavalue.value.amount) if rank==1 thenbold=trueendrank=number(gender,rank,wiki)end--get best riderif q and q.P710 and q.P710[1].snaktype == 'value' then --participantrider = q.P710[1].datavalue.value.idriderLink = getRiderLink(rider, thisdate)countryID = getNationality(rider, thisdate)if countryID thenriderLink = flag(countryID, thisdate) .. ' ' .. riderLinkendend_,disqualified=isdisqualified(p1344, q)if riderLink and disqualified==true thenriderLink='<s>'..riderLink..'</s>'endendendendreturn riderLink, rank, boldendfunction teamriderCompetitionranking_main(s, resultTable)--Display the UCI women calendar of one yearlocal best_rider, ranklocal lf = s.lflocal calendarID=s.calendarIDlocal seasonID= s.itemlocal t_Body ={}local w_race=s.w_racelocal gender="m"if w_race then gender="f" endlocal temp=firstValue(calendarID, s.property)if not temp or temp=="" then s.error_message = 2 if wiki == "ar" then return "" endendlocal country=getCountryBool(s.no_country)----- Begin of the main part of the codelocal ind=0for _, p527 in statements(calendarID, 'P527') dolocal RaceID = p527.mainsnak.datavalue.value.idlocal temp=firstValue(RaceID, 'P1346','id')local cancelled=falseif temp and temp=='Q30108381' then --race cancelledcancelled=trueelseind=ind+1endif 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 displaylocal country_flag, country_name, country_tCell=fn_country(RaceID, timeOfRace, country, race_tCell, parentID) --create the tablelocal 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 wikidatatRow:node(country_tCell)if country thentRow:node(race_tCell) end--logic to get the best rider||rankingriderLink, rank, bold=get_competition_bestrider(RaceID, seasonID, gender)local tCell=tRow:tag('td'):cssText("text-align:".. textalign ..";padding:0 0.5em")if riderLink thentCell:wikitext(riderLink)elseif future thentCell:wikitext("")elsetCell:wikitext(" - ")endtCell=tRow:tag('td'):cssText("text-align:".. textalign ..";padding:0 0.5em")if bold thentCell:cssText("font-weight:bold;")endif rank thentCell:wikitext(rank)elseif future thentCell:wikitext("")elsetCell:wikitext(" - ")end---- Add the row to the tabletable.insert(t_Body, {sortkey=date_sortkey, body=tRow})endend endreturn 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 endif name == 'getStatementForTime' then return getStatementForTime endendfunction p.testlocal(frame) --function to test local functionslocal function_name=frame.args[1]local argu=frame.argslocal temp, temp2if function_name=='firstValue' thenreturn firstValue(argu[2],argu[3],argu[4])elseif function_name=='getOfficialName' thentemp, temp2 =getOfficialName(argu[2],argu[3],argu[4])return tempelseif function_name=='getRiderLink' thenif argu[3]=="nil" then arg3=nil else arg3=argu[3] endtemp=getRiderLink(argu[2],arg3) --only first arg returnedreturn tempelseif function_name=='funcDate' thenreturn funcDate(argu[2],argu[3])elseif function_name=='funcDateFigure' thenreturn funcDateFigure(argu[2],argu[3])elseif function_name=='getStartEndTime1' thentemp, temp2=getStartEndTime(argu[2],argu[3],argu[4])return tempelseif function_name=='getStartEndTime2' thentemp, temp2=getStartEndTime(argu[2],argu[3],argu[4])return temp2elseif function_name=='getPeriodSub' thentemp, temp2=getPeriodSub(argu[2],argu[3],toboolean(argu[4]))return tempelseif function_name=='getTeam' thentemp=getTeam(argu[2],argu[3],argu[4])if temp then return temp else return 'nil' endelseif function_name=='getStatementForTime' thentemp=getStatementForTime(argu[2],argu[3],argu[4])if temp thenreturn temp.mainsnak.datavalue.value.idelsereturn 'nil'endelseif function_name=='getTeamLinkCat' thentemp=getTeamLinkCat(argu[2],argu[3],toboolean(argu[4]))if temp then return temp else return 'nil' endelseif function_name=='getTeamLinkCat2' thentemp, temp2=getTeamLinkCat(argu[2],argu[3],toboolean(argu[4]))if temp2 then return temp2 else return 'nil' endelseif function_name=='getPlaceLink' then if argu[3]=="nil" then arg3=nil else arg3=argu[3] endreturn getPlaceLink(argu[2],arg3)elseif function_name=='getPlaceLink2' then return getPlaceLink(argu[2],argu[3],nil,true)elseif function_name=='seasonToTeamID' thenif argu[2]=="nil" then arg2=nil else arg2=argu[2] endreturn tostring(seasonToTeamID(arg2))elseif function_name=='translate' thenreturn translate(argu[2],tonumber(argu[3]),toboolean(argu[4]))elseif function_name=="classLinkFn" thenreturn classLinkFn(argu[2])elseif function_name=='raceLink' thenreturn tostring(raceLink(argu[2]))elseif function_name=='getMainRaceLink' thenif argu[5]=="nil" then arg5=nil else arg5=argu[5] endif argu[3]=='stage' then arg3='stage' else arg3=tonumber(argu[3]) endreturn tostring(getMainRaceLink(argu[2],arg3,argu[4], arg5,argu[6]))elseif  function_name=='getYear' thenreturn getYear(argu[2])elseif function_name=='getCountryName' thenreturn tostring(getCountryName(argu[2]))elseif function_name=='getTeamCodeCat' thenreturn tostring(getTeamCodeCat(argu[2],argu[3]))elseif function_name=='getTeamCode' thenreturn tostring(getTeamCode(argu[2],argu[3],argu[4]))elseif function_name=='getCountryBool' thenreturn tostring(getCountryBool({argu[2],argu[3]}))elseif function_name=='WPlinkpure' thenreturn WPlinkpure(argu[2])elseif function_name=='uciCodeCountry' thenreturn uciCodeCountry(argu[2])elseif function_name=='isHuman' thenreturn tostring(isHuman(argu[2]))elseif function_name=='isCountry' thenreturn tostring(isCountry(argu[2]))elseif function_name=='isWomenrace' thenreturn tostring(isWomenrace(argu[2]))elseif function_name=='isWomenteam' thenreturn tostring(isWomenteam(argu[2]))elseif function_name=='commaStage' thentemp =commaStage(argu[2],argu[3])return temp["prefix"]elseif function_name=='number' thenreturn 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' thenreturn calculateTime(argu[2])elseif function_name=='getClass1' thentemp, temp2 = getClass(argu[2])return temp elseif function_name=='getClass2' thentemp, temp2 = getClass(argu[2])return temp2 elseif function_name=='infoGetPlace' thenlocal details = {{ name = "test", name_plural="tests"}} -- course / not usedinfoGetPlace(details,1, argu[2], argu[3], argu[4])return details[1].contentelseif function_name=='getFormerNames1' thentemp=getFormerNames(argu[2],'P1448')if temp[1] thenreturn temp[1][2]  --periodelsereturn ""endelseif function_name=='getFormerNames2' thentemp=getFormerNames(argu[2],'P1448')if temp[1] thenreturn temp[1][3]  --nameelsereturn ""endelseif function_name=='getType' thenreturn getType(argu[2])elseif function_name=='compareDate' thenreturn tostring(compareDate(argu[2]))elseif function_name=='officialSite' thenreturn officialSite(argu[2])elseif function_name=='trans' thenreturn tostring(trans(argu[2], argu[3], argu[4]))elseif function_name=='parseDate1' thentemp1, temp2, temp3, temp4, temp5= parseDate(argu[2], argu[3], argu[4], argu[5], "", "error text")return temp1elseif function_name=='parseDate2' thentemp1, temp2, temp3, temp4, temp5= parseDate(argu[2], argu[3], argu[4], argu[5], "", "error text")return temp2elseif function_name=='parseDate5' thentemp1, temp2, temp3, temp4, temp5= parseDate(argu[2], argu[3], argu[4], argu[5], "", "error text")return temp5elseif function_name=='findLastName' thenreturn findLastName(argu[2],wiki)elseif function_name=='findSortKey' thenif wiki=="ru" or wiki=="mk" thenreturn findSortKey(argu[2],false, true)elsereturn findSortKey(argu[2],true, false)endelseif function_name=='calculateAge' thentemp1, _, _ =calculateAge(argu[2])return temp1elseif function_name=='getBirthDeathDate1' then    temp1, temp2 =getBirthDeathDate(argu[2])return temp1elseif function_name=='getBirthDeathDate2' thentemp1, temp2 =getBirthDeathDate(argu[2])return temp2elseif function_name=='getLocalContent' thenlocal details = {            { name = argu[2], name_plural= argu[3]}            }local arguments = {}arguments[argu[4]]="test"getLocalContent(details, arguments)return details[1].contentelseif function_name=='plural1' then_, temp1, temp2=plural(tonumber(argu[2]))return temp1elseif function_name=='plural2' then_, temp1, temp2=plural(tonumber(argu[2]))return temp2elseif function_name=='getNationality' thenreturn getNationality(argu[2], argu[3])elseif function_name=='getCountryID' thenreturn getCountryID(argu[2], argu[3])elseif function_name=='get_formatted_date1' thenif argu[3]=="nil" then arg3=nil else arg3=argu[3] endtemp, temp2= get_formatted_date(argu[2], arg3)if temp then return temp endelseif function_name=='get_formatted_date2' thenif argu[3]=="nil" then arg3=nil else arg3=argu[3] endtemp, temp2= get_formatted_date(argu[2], arg3)if temp2 then return temp2 endelseif function_name=="getSpeed" thenif argu[4]=="nil" then arg4=nil else arg4=tonumber(argu[4]) endreturn tostring(getSpeed(argu[2], toboolean(argu[3]),arg4, argu[5]))elseif function_name=="formatNumber" thenreturn formatNumber(tonumber(argu[2]), toboolean(argu[3]),tonumber(argu[4]))endendfunction p.test_import(frame)local function_name=frame.args[1]local argu=frame.argsif function_name=='class_dic' thenreturn tostring(data.class_dic[argu[2]])elseif function_name=="class_sort" thenreturn tostring(data.class_sort[argu[2]])elseif function_name=='bg_color_table' thenlocal temp = data.bg_color_table[argu[2]]temp=string.gsub(temp,'#',"")return tempendendreturn p