Wikipedia sowiki https://so.wikipedia.org/wiki/Bogga_Hore MediaWiki 1.47.0-wmf.20 first-letter Media Special Talk User User talk Wikipedia Wikipedia talk File File talk MediaWiki MediaWiki talk Template Template talk Help Help talk Category Category talk Portal Portal talk TimedText TimedText talk Module Module talk Event Event talk Allaybaday 0 7872 308482 305264 2026-09-17T21:29:03Z ~2026-50488-58 47425 /* */ 308482 wikitext text/x-wiki {{Infobox settlement | name = Allaybaday | native_name = | settlement_type = Magaalo | image_skyline = | image_flag = | image_seal = | subdivision_type = [[Dalalka|Wadanka]] | subdivision_name = {{flag|Somaliland}} | subdivision_type1 = [[Gobolada Somaliland|Gobolka]] | subdivision_name1 = [[Maroodi Jeex]] | subdivision_type2 = [[Qaybaha maamulka Somaliland|Degmo]] | subdivision_name2 = [[Degmada Gabiley]] | established_title = la aasaasay | established_date = | population_total = | area_total_km2 = | population_density_km2 = auto | timezone = [[East Africa Time|EAT]] | utc_offset = +3 | postal_code_type = | postal_code = | area_code = +252 | coordinates = {{coord|9|23|13|N|43|31|03|E|scale:100000_region:SO-WG|display=inline,title}} | pushpin_map = Marodi Jeh | pushpin_label_position = Bottom | elevation_m = 1,125 }} '''Allaybaday''' waa magaalo ka tirsan gobolka [[Maroodi Jeex]] ee [[Somaliland]], oo ku taal xuduudka [[Itoobiya]]. Waxa degan Abdalla Abokor. Degmada Allaybaday waxaa ku nool 120,000 (2022) Sida ku cad qoraal ay dawladda [[Somaliland]] soo saartay sannadkii 2002-dii, Allaybaday waa degmada 9-aad ee ugu muhiimsan gobolka [[Maroodi Jeex]], iyadoo loo kala saaray D. ==Beeraha== Degmada Allaybaday ayaa waxaa laga soo saaraa tamaandho yaanyo iyo basasha ah bil walba xilliyada roobabka ==Taariikhda dhow== Horaantii sannadkii 1979-kii, laba dagaalyahan oo ka tirsan Jabhadda Xoraynta Soomaali Galbeed (WSLF) ayaa gabadh ku kufsaday inta u dhaxaysa Tog Wajaale iyo Allaybaday, ka dibna walaalkeed oo dhawr iyo toban jir ah ayaa toogtay dagaalyahannadaas. Taliyahii WSLF ayaa dabadeed dilay walaalkii iyo qoyskiisa. Tani waxay ahayd mid ka mid ah dagaaladii u dhexeeyay WSLF iyo Dhaqdhaqaaqa Waddaniga Soomaaliyeed. 93  1987kii, Dhaqdhaqaaqa Waddaniga Soomaaliyeed ayaa ka fallaagoobay Madaxweynihii Soomaaliya. Waqtigaan waxaa Waqooyi Galbeed Soomaaliya ku sugnaa 7-askari oo ka tirsan ciidamada Milatariga Soomaaliya oo ay ka mid tahay Allaybaday. Bishii Janaayo 1988dii, ciidamada qalabka sida ee Soomaaliya qeybta 12-aad ayaa Allaybaday ku toogtay illaa 20 qof oo rayid ah. Arintaan ayaa lagu tiriyaa inay ka mid tahay tacadiyada ay ciidamada qalabka sida ee Soomaaliya u gaysteen Isaaqa . ===Kadib Ku Dhawaaqii Madaxbanaanida Somaliland=== Bishii Jannaayo 2004, ka dib wadahadal dhexmaray UNICEF iyo maamulka deegaanka, xarunta hooyada iyo dhallaanka (MCH) ayaa dib uga hawlgashey Allaybaday. Sida lagu sheegay warbixin ay hay’adda Interpeace soo saartay sannadkii 2006-dii , dhul-beereedkii fadhi-ku-dirirka ahaa iyo dhul-daaqsimeedka ee deegaanka Allaybaday ayaa kordhiyey colaadda, taas oo keentay in deegaanka Allaybaday ee dhinaca Itoobiya iskahorimaadku ka dhaco. 8  Bishii February 2006, Wasiirka Deegaanka Somaliland waxa uu sheegay in Ajaanib ay soo kiraysteen Ganacsato reer Gabiley ah ay burburinayaan kaymo ku dhow degmada Allaybaday. 31  ishii Abriil 2007, daadad xooggan oo ka dhacay Allaybaday ayaa burburiyay 87 ka mid ah 105 biyo-xireenno . Bishii Oktoobar 2008, dab ayaa ka kacay kaalin shidaal oo ku taal Allaybaday, waxaana ku dhintay 10 bakhaar. Bishii December 2013, Madaxweynaha Somaliland ayaa booqasho ku tagay degmada Allaybaday, waxaanu dhagax dhigay waddo isku xidhi doonta Allaybaday iyo Hargeysa . Bishii April 2014, Badhasaabkii Degmada Allaybaday Keyse Maxamed Ibraahim (Keyse Meegaar) ayaa booqasho ku tagay Gabiley si uu u sii daayo dadka reer Allaybaday ee la xidhay. May 7, 2015, Wasiirka Arrimaha Gudaha Somaliland ayaa Maxamed Xasan Shiil u magacaabay duqa magaalada Allaybaday. Bishii July 2015, ayaa madax-dhaqameedka Allaybaday shir jaraa’id ku qabteen Hargeysa, waxay beeniyeen inuu jiro hoggaan cusub oo ay beeshu dooratay. Bishii March 2016, dawladda Somaliland waxay gaadhsiisay deegaanka Allaybaday gargaar biyo iyo cunto ah oo ceelkii ciladoobay. Bishii Sebtembar 2017, waxa Allaybaday booqday murashaxa madaxweyne Muuse Biixi Cabdi . Bishii Disembar 2019, laba qof oo rayid ah ayay askar booliisku ku dileen Allaybaday. Bishii Febraayo 2021, waxaa la furay wadadii ugu horeysay ee laami ah oo laga dhiso Allaybaday. ==Sidoo kale eeg== [[Qaybaha maamulka Somaliland]] [[Gobolada Somaliland]] [[Degmooyinka Somaliland]] ==Tixraac== [https://reliefweb.int/report/somalia/somalia-concern-over-deteriorating-food-security-somaliland "SOOMAALIYA: Walaac ku saabsan haqab-beelka cuntada ee Somaliland - Soomaaliya"] [https://wargeyskadawan.com/2015/07/09/madaxdhaqameedka-allaybaday-oo-beeniyey-nin-ugaasnimo-sheegtay-beeshooda/ "Madaxda Allaybaday oo Beeniyey Nin Ugaasnimo Sheegtay Beeshooda"] [https://ijisrt.com/assets/upload/submitted_files/1566803014.pdf "Qiimaynta Qiimaynta Kaabayaasha Kaabayaasha Magaalooyinka iyo Maamulka Maareynta ee Adeegga Biyaha Magaalooyinka: Somaliland"] [https://ijisrt.com/assets/upload/submitted_files/1566803014.pdf "Qiimaynta Qiimaynta Kaabayaasha Kaabayaasha Magaalooyinka iyo Maamulka Maareynta ee Adeegga Biyaha Magaalooyinka: Somaliland"] [https://books.google.com/books?id=RcVFXUwraxsC Maalmo Xun: Soddon Sano Oo Dagaal Iyo Macaluul Ka Dhacay Itoobiya] [https://www.wajaalenews.net/?p=12531 "GUDOOMIYAHA DEGNADA ALLAY BADAY OO EEDAYN USOO JEEDIYEY XEER ILAALINTA GOBOLKA GABILAY IYO KHILAAF HOR LEH OO KA DHASHAY"] {{Wayback|url=https://www.wajaalenews.net/?p=12531 |date=20230527044601 }} [https://www.qurbejoog.com/wasiir-waran-cadde-oo-maanta-guddoomiye-cusub-u-magacaabay-degmada-allaybaday/ "Wasiir Waran-cadde Oo Maanta Guddoomiye Cusub u Magacaabay Degmada Allaybaday"] [https://berberatoday.com/2017/09/08/muuse-biixi-oo-soo-dhaweyn-ballaadhan-kala-kulmay-shacabka-allay-baday-deegaannada-idhanka-iyo-geed-ballaadh/ "MUUSE BIIXI OO SOO DHAWEYN BALLAADHAN KALA KULMAY SHACABKA ALLAY-BADAY, DEEGAANKA IDHANKA IYO GEED-BALLAADH"] [https://berberatoday.com/2019/12/20/daawo-muuqalkaugaas-cabdirasaaq-koosar-oo-ka-hadlay-dad-ciimada-liyuu-boolisku-ku-laayeen-magaalada-allaybaday/ "DAAWO MUUQALKA"UGAAS CABDIRASAAQ KOOSAR OO KA HADLAY DAD CIIMADA LIYUU BOOLISKU KU LAAYEEN MAGAALADA ALLAYBADAY"] [https://www.wajaalenews.net/?p=128143 "DAAWO;-MAAMULKA GOBOLKA GABILEY OO XADHIGA KA JARAY WADO LAAMI AH OO DAWLADA HOOSE EE GABILEY KA HIRGALISAY ALLAYBADAY"] {{Wayback|url=https://www.wajaalenews.net/?p=128143 |date=20230527144343 }} [https://somalilandpost.net/daawomadaxweyne-siilaanyo-oo-dhagax-dhigay-dhismaha-cusub-oo-isku-xidhaysa-magaalada-hargeisa-iyo-degmada-alleybaday/ "DAAWO:Madaxweyne Siilaanyo oo Dhagax-dhigay Dhismaha Cusub oo Isku Xidhay Magaalada Hargeysa iyo Degmada Alleybaday"] aawiwqgltawsqfcmnilc6odfhr073vj User talk:SHB 3 33138 308504 214289 2026-09-18T03:43:33Z Max 35277 Max la wareejiyay bogga [[User talk:SHB2000]] ilaa [[User talk:SHB]]: Bogga si otomaatig ah ayaa loo wareejiyay intii lagu jiray magaca beddelka isticmaalaha "[[Special:CentralAuth/SHB2000|SHB2000]]" loona beddelay "[[Special:CentralAuth/SHB|SHB]]" 214289 wikitext text/x-wiki <div style="border: 1rem #dd0000 ridge; padding: 0.5em;">Hello! Please message me on [[m:User talk:SHB2000|meta.wikimedia.org]] instead. I may not notice messages on this page.</div> ojy2vkqs676esjrcfi79dwyt0tjr5xc Template:Test case nowiki 10 33761 308469 218250 2026-09-17T16:44:18Z Isma4l 41797 308469 wikitext text/x-wiki <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude> tqcbtoi20hh04qz7tcyj9c81ibksvas Module:Goalscorers 828 46913 308437 294112 2026-09-17T16:11:30Z Isma4l 41797 308437 Scribunto text/plain require('strict'); local yesno = require('Module:Yesno') local p = {} local g = {} -- for parameters with global scope in this module g.goalscorers = {} -- table where selected and sorted players will be place g.args = {} g.totalGoals = 0 local data = {} -- module subpage data -- require('Module:Goalscorers/data/UEFA Euro 2016 qualifying'); p.errorString = "" function p.error_msg() if p.errorString ~= "" then return '<span style="font-size:100%" class="error">' -- '<code style="color:inherit;border:inherit;padding:inherit;">&#124;_template=</code>' .. p.errorString .. '</span>'; end end -- data for goals scored held in module subpages, e.g. "Module:Goalscorers/data/UEFA Euro 2016 qualifying" --[[ parameters containing data help in three tables data.rounds = {} -- group, play-off data.goalscorers = {} -- player, country, goals in each round) data.owngoalscorers = {} -- player, country, goals in each round) data.updated = {} -- date of latest update (month, day, year) --]] --[[ ############################ Parameter handing ############################### p.getArgs() - gets arguments from frame (invoke) or parent frame (template) ]] local function getArgs(frame) local parents = mw.getCurrentFrame():getParent() for k,v in pairs(parents.args) do --check content if v and v ~= "" then g.args[k]=mw.text.trim(v) --parents.args[k] end end for k,v in pairs(frame.args) do --check content if v and v ~= "" then g.args[k]= mw.text.trim(v) --parents.args[k] end end -- allow empty caption to blank default --if parents.args['caption'] then templateArgs['caption'] = parents.args['caption'] end end --[[ ############################## Main function and other functions ###################### p.main() - simple output of the data in the module in list form p.addIntroductorySentence() - add sentence on number of goals and matches, with goals per match p.addFooterSentence() - add footnote p.getNumberMatches() p.owngoals() - get own goals (no longer used?) p._owngoals() - core functionality for p.owngoals() ]] function p.main(frame) getArgs(frame) local dataTarget = g.args[1] or g.args['data'] if dataTarget then data = require('Module:Goalscorers/data/'.. dataTarget) --or 'UEFA Euro 2016 qualifying' return p.useModuleData(frame) -- data on goals taken from module subpage else return p.useTemplateData(frame) -- data on goals/assists taken from template end end function p.useModuleData(frame) --p.goalscorers = {} -- table where selected and sorted players will be place g.totalGoals = 0 local ok = p.selectGoalscorers() -- selected goalscorers meeting round and group criteris if not ok then return p.error_msg() end -- CHANGE: append own goals to list (data will now include goals and own goals (negative)) p.selectGoalscorers("OG") p.sortGoalscorers() -- sort selected goalscorers by number of goal, then country local outputString = p.addIntroductorySentence() .. p.outputGoalscorers(frame) .. p.addFooterSentence() -- .. "" --TODO add intermediate heading? -- .. p._owngoals(frame) -- output list of goalscorers return p.error_msg() or outputString end --[[ ##################### standalone value outputs ########################## p.goals(frame) - output ONLY the total number of goals scored p.matches(frame) - output ONLY the number of matches played p.date(frame) - output ONLY the date of the most recent matches played accepts optional |format=yes to comma-format the number (e.g. 1,234). ]] function p.goals(frame) getArgs(frame) local result local dataTarget = g.args[1] or g.args['data'] if dataTarget then data = require('Module:Goalscorers/data/' .. dataTarget) g.goalscorers = {} -- reset state (safe for multiple invokes per page) g.totalGoals = 0 local ok = p.selectGoalscorers() -- count goals for selected round/group if not ok then return p.error_msg() end p.selectGoalscorers("OG") -- include own goals in the total if p.errorString ~= "" then return p.error_msg() end result = g.totalGoals else result = tonumber(g.args['goals']) or 0 -- fall back to template-supplied data end if yesno(g.args['format']) then return mw.getLanguage('en'):formatNum(result) end return tostring(result) end function p.matches(frame) getArgs(frame) local result local dataTarget = g.args[1] or g.args['data'] if dataTarget then data = require('Module:Goalscorers/data/' .. dataTarget) local round = g.args['round'] or "all" if round ~= "all" and not p.validateRound(round) then -- guard against bad round p.errorString = p.errorString .. 'Invalid round "' .. round .. '" specified. ' return p.error_msg() end result = p.getNumberMatches() -- respects round/group args else result = tonumber(g.args['matches']) or 0 end if yesno(g.args['format']) then return mw.getLanguage('en'):formatNum(result) end return tostring(result) end function p.date(frame) getArgs(frame) local dataTarget = g.args[1] or g.args['data'] if not dataTarget then return g.args['updated'] or "" end -- template-data fallback data = require('Module:Goalscorers/data/' .. dataTarget) local round = g.args['round'] or "all" if round ~= "all" and not p.validateRound(round) then p.errorString = p.errorString .. 'Invalid round "' .. round .. '" specified. ' return p.error_msg() end local _, dateUpdated = p.getNumberMatches() if dateUpdated == "complete" or dateUpdated == "" then return "" end -- nothing to show local dateFormat = (data.params and data.params['date_format']) or 'dmy' local mdy = yesno(g.args['mdy']) if mdy == true then dateFormat = "mdy" elseif mdy == false then dateFormat = "dmy" end local r, grp = p.getRoundAndGroup() local finished = p.matchesFinished(r, grp, dateUpdated) if finished ~= "" then finished = " (" .. finished .. ")" end return p.error_msg() or (require('Module:Date')._Date(dateUpdated):text(dateFormat) .. finished) end --[[ ##################### matches-finished helper ############################ p.matchesFinished(round, group, latestDate) Sums the optional "F/T" field (3rd element of a data.updated entry) for every entry dated on latestDate. Older dates are ignored. Returns "" when no entry supplies F/T, or a contributing entry on that date lacks it. ]] function p.matchesFinished(round, group, latestDate) if not latestDate or latestDate == "complete" or latestDate == "" or latestDate == "1700-01-01" then return "" end local entries = {} -- entries applying to round/group if round == "all" then for k, v in pairs(data.updated) do if k ~= "date" and k ~= "group" and p.validateRound(k) then entries[#entries+1] = v end end elseif round ~= "group" then entries[#entries+1] = data.updated[round] end if (round == "all" or round == "group") and data.updated.group then if group and group ~= "all" then entries[#entries+1] = data.updated.group[group] else for _, v in pairs(data.updated.group) do entries[#entries+1] = v end end end local finished, total, found = 0, 0, false -- sum F/T on the most-recent date for _, e in ipairs(entries) do if e[2] == latestDate then local f, t = string.match(tostring(e[3] or ""), "^%s*(%d+)%s*/%s*(%d+)%s*$") if not f then return "" end -- contributing entry without F/T -> skip finished, total, found = finished + f, total + t, true end end if not found then return "" end if finished >= total or finished < 1 or total < 1 then return "" end -- all done / invalid -> date only return finished .. " of " .. total .. " matches finished" end function p.addIntroductorySentence() -- add introductory text local totalGoalString = "A total of " .. g.totalGoals .. " goals were scored." --There were [has been|have been|was|were] #GOALS goal(s) scored in #MATCHES match(s), for an average of #GOALS/#MATCHES per match. local matches, dateUpdated = p.getNumberMatches() local mdyFormat = yesno(g.args['mdy']) local Date = require('Module:Date')._Date local pluralGoals = "s" local text1 = "" if g.totalGoals == 1 then pluralGoals = "" if dateUpdated == 'complete' then text1 = "was" else text1 = "has been" end else if dateUpdated == 'complete' then text1 = "were" else text1 = "have been" end end local text = string.format("There %s %s goal%s scored", text1, mw.getLanguage('en'):formatNum(g.totalGoals), pluralGoals) local pluralMatches = "es" if matches==1 then pluralMatches = "" end if matches then local average = g.totalGoals/tonumber(matches) local precision = 3 -- display d.dd (three significant disgits) if average < 1 then precision = 2 end -- display 0.dd (thwo significant disgits) average = tostring (average) local pluralAverage = "s" if tonumber(string.format("%.2f",average))==1 then pluralAverage = "" end text = text .. string.format(" in %d match%s, for an average of %."..precision.."g goal%s per match", matches, pluralMatches, average, pluralAverage) end if dateUpdated == 'complete' or dateUpdated == "" then text = text .. "." else local dateFormat = 'dmy' -- default if data.params and data.params['date_format'] then dateFormat = data.params['date_format'] end -- from data module if mdyFormat == true then dateFormat = "mdy" else if mdyFormat == false then dateFormat = "dmy" end -- template param overrides end local round, group = p.getRoundAndGroup() local finished = p.matchesFinished(round, group, dateUpdated) if finished ~= "" then finished = ", " .. finished end text = text .. " (as of " .. Date(dateUpdated):text(dateFormat) .. finished .. ")." end text = p.addAdditionHeaderText(text, dateUpdated) -- handles template parameters bold, further, extra return text --totalGoalString end function p.addFooterSentence() -- add notes at bottom local footerSentence = g.args['footer'] or "" --footerSentence = "This is a footer sentence." -- test footer if data.params then local footer = data.params['footer'] or nil if footer then local frame = mw.getCurrentFrame() local processed = frame:preprocess(footer) if g.notes then footerSentence = footerSentence .. processed end end end if footerSentence ~= "" then footerSentence = '<div style = "" >' .. footerSentence .. '</div>' end return footerSentence end function p.getNumberMatches() local matches = g.args['matches'] local dateUpdated = data.updated['date'] or "1700-01-01" --'complete' -- assume completed if missing --local round = g.args['round'] or "all" -- round = all(empty)|group|playoffs --local group = g.args['group'] or "all" -- group = all(empty), A,B,C etc local round, group = p.getRoundAndGroup() local allGroupGames = 0 local latestGroupDate = "1800-01-01" if group and (round == "all" or group == "all") then -- count all the group games for k,v in pairs(data.updated.group) do allGroupGames = allGroupGames + v[1] if v[2] ~= "complete" and v[2] > latestGroupDate then latestGroupDate = v[2] end -- update if later date end if latestGroupDate == "1800-01-01" then latestGroupDate = "complete" end -- no dates so must be complete end if group and (round == "all" and group ~= "all") then -- for totals of all rounds with only one group allGroupGames = data.updated.group[group][1] -- number matches latestGroupDate = data.updated.group[group][2] -- update date or completed end if round == "all" then -- all rounds and goals matches=0 for k,v in pairs(data.updated) do if k == "group" then matches = matches + allGroupGames if latestGroupDate ~= "complete" and latestGroupDate > dateUpdated then dateUpdated = latestGroupDate -- update if later date end elseif p.validateRound(k) then matches = matches + v[1] if v[2] ~= "complete" and v[2] > dateUpdated then dateUpdated = v[2] end -- update if later date end end elseif round == "group" then -- group round only if group == "all" then matches = allGroupGames dateUpdated = latestGroupDate else -- single group only matches = data.updated.group[group][1] -- number matches dateUpdated = data.updated.group[group][2] -- update date or completed end else -- any other round matches = data.updated[round][1] -- number matches dateUpdated = data.updated[round][2] -- update date or completed end if dateUpdated == "1700-01-01" then dateUpdated = "complete" end -- no dates so must be complete return matches, dateUpdated end function p.owngoals(frame) -- need to check parameters if external call getArgs(frame) data = require('Module:Goalscorers/data/'.. g.args[1]) --or 'UEFA Euro 2016 qualifying' local outputString = p._owngoals(frame) return p.error_msg() or outputString end function p._owngoals(frame) -- internal call for own goals --p.goalscorers = {} -- table where selected and sorted players will be place p.selectGoalscorers("OG") -- selected goalscorers meeting round and group criteris p.sortGoalscorers() -- sort selected goalscorers by number of goal, then country return p.outputGoalscorers(frame, "OG") -- output list of goalscorers end function p.validateRound(round) local validateRound = false for k,v in pairs(data.rounds) do if k == round then validateRound = true end -- data for this round exists end return validateRound end --[[ ############################## functions to select goalscorers ###################### p.selectGoalscorers() - select goals scoreers required for list (rounds, groups) p.getRoundAndGroup() p.getGoalsCol(round) - get column containing round data or first data column if round = all (country, possibleGroup) p.getGoals (u, player) p.parseComment(comment) p.getPlayer(u) ]] --[[ p.selectGoalscorers() - select players meeting round and group criteria from goalscoreres list - gets goals and comments ]] function p.selectGoalscorers(og) local round, group = p.getRoundAndGroup() if not round then return false end -- exit if no valid round local goalMinimum = tonumber(g.args['minimum']) or -5 -- assume 5 own goals is maximum local goalsCol = p.getGoalsCol(round) -- first column for goals -- select players who have scored in rounds/groups requested local goalscorerData = data.goalscorers if og == "OG" then goalscorerData = data.owngoalscorers end for k,v in pairs(goalscorerData) do local goals, comment = 0, "" -- goals > 0 is the flag to include the player local playerName, playerAlias = p.getPlayer(v[1]) -- player name local goalsByRound, commentByRound = 0, "" if round == "all" then -- goals in all rounds and all groups for i = goalsCol, #v, 1 do if group and group ~= "all" and i == p.getGoalsCol("group") and group ~= p.getGroup(v[2], v[3]) then goalsByRound = 0 commentByRound = "" else goalsByRound, commentByRound = p.getGoals( v[i] , playerName) end goals = goals + goalsByRound --TODO use getGoals on round options if commentByRound ~= "" then if comment == "" then comment = commentByRound else comment = comment .. "," .. commentByRound --TODO decide on comma or semi-colon end end i = i+1 end elseif round == "all2" and group ~= "all" then -- goals in all rounds but only from one group --TODO code to go through all rounds but only include goals in specified group [TODO merge with above option] --mw.addWarning( g.args[1] .. ":Mix:round=all and group=" .. group .. "/" .. p.getGroup(v[2], v[3] ) ) for i = goalsCol, #v, 1 do if i == p.getGoalsCol("group") and group ~= p.getGroup(v[2], v[3]) then goalsByRound = 0 commentByRound = "" else goalsByRound, commentByRound = p.getGoals( v[i] , playerName) end goals = goals + goalsByRound if commentByRound ~= "" then if comment == "" then comment = commentByRound else comment = comment .. "," .. commentByRound --TODO decide on comma or semi-colon end end i = i+1 end elseif round == "group" then -- group round only if group == p.getGroup(v[2], v[3]) then -- single group only goals, comment = p.getGoals( v[goalsCol] , playerName) elseif group == "all" then -- any group goals, comment = p.getGoals( v[goalsCol] , playerName) else -- do nothing for other groups end --elseif round == "playoffs" then -- playoff round (redunant?) -- goals = v[goalsCol] else -- any other round goals, comment = p.getGoals( v[goalsCol] , playerName) -- should also handle playoffs end if goals >= goalMinimum and goals ~= 0 then if comment ~= "" then if og == "OG" then comment = '<span> (' .. p.sortComment(comment) .. ')</span>' else comment = '<span>' .. comment .. '</span>' -- no parenthesis when using notes end end if og == "OG" then goals = -goals end -- make owngoals negative numbers g.goalscorers[#g.goalscorers+1] = { player=playerName, alias=playerAlias, country=v[2], goals=goals, comment=p.parseComment(comment)} --g.totalGoals = g.totalGoals + math.abs(goals) -- increment total goal counter end g.totalGoals = g.totalGoals + math.abs(goals) -- increment total goal counter end return true -- data collected for selected goalscorers end --[[ p.getRoundAndGroup() ]] function p.getRoundAndGroup() local round = g.args['round'] or "all" -- round = all(empty)|group|playoffs local group = g.args['group'] or "all" -- group = all(empty), A,B,C etc local validateRound = false local validateGroupRound = false for k,v in pairs(data.rounds) do if k == round then validateRound = true end -- data for this round exists if k == "group" then validateGroupRound = true end -- there is a group round end if validateRound == false and round ~= "all" then local message = 'Invalid round "' .. round .. '" specified. No data found for that round. ' mw.addWarning( message ) p.errorString = p.errorString .. message round = nil end if validateGroupRound == false then group = false end -- there is no group round -- TODO add group error checking -- Could merge with getGoalsCol() and also return goalsCol return round, group end --[[ p.getGoalsCol(round) - get column containing round data or first data column if round = "all" - allows group column to be omitted from player table when group table provided ]] function p.getGoalsCol(round) local minimum = 1000 if round == "all" then -- if all need column of first round for k,v in pairs(data.rounds) do if v < minimum then minimum = v end --return v -- return the first one [this seemed to work reliably, but sometimes table order is not as listed] end return minimum end if data.rounds and data.rounds[round] then return data.rounds[round] -- get column containing goals for that round else return 4 -- an old default when no data.round (may not be necessary) end end --[[ p.getGroup(country, possibleGroup) - get group from group table or from player table - possibleGroup is the column containing the Group (when no group table) or the first data column ]] function p.getGroup(country, possibleGroup) -- row contain player name, country code, group if given, goals if data.groups then for k,v in pairs(data.groups) do -- iterate through the groups --local = gotGroup = false for j,u in pairs(v) do -- for each group if u == country then return k end end end return "no group found" else return possibleGroup -- no group table, so assume column three contains the group end end --[[ get number of goals and any associated comment the goals can be a single number (the usual case) or as an option table (e.g. for own goals): { number of own goals, comma-delimited list of opponents } - if the entry is a table, we want the first entry (a number) and the second (comment string) - otherwise, if a number, we just want the number and an empty string ]] function p.getGoals (u, player) if type(u) == 'table' and type(u[1]) == 'number' then return u[1], u[2] -- return number of goals, comment elseif type(u) == 'number' then return u, "" -- return number of goals, empty string else p.errorString = p.errorString .. " Invalid goals entry for player " .. player return 0, "" end end function p.parseComment(comment) local frame = mw.getCurrentFrame() -- we have something like "{{efn-ua|name=goals}}" if string.find(comment, "efn" , 1 , true ) then -- if we have a comment with a note g.notes = true -- set flag end return frame:preprocess(comment) end function p.getPlayer(u) if type(u) == 'table' then if type(u[1]) == 'string' and type(u[2]) == 'string' then --[[if #u[2] >1 then p.errorString = p.errorString .. "\n\nWe have u[1]=" .. u[1] .. " and u[2]=" .. u[2] end]] return u[1], u[2] -- return player name, player sorting alias else p.errorString = p.errorString .. " Invalid name entry for player " .. u[1] .. ", " .. u[2] return "", "" --TODO errroer end elseif type(u) == 'string' then return u, "" -- return player name else p.errorString = p.errorString .. " Invalid name entry for player " .. u or u[1] or "unknown" return "", "" end end --[[ ############################## functions to sort goalscorers ###################### p.preprocessSortName (name) p.getPlayerSortName (playerName, sortName, countryName) p.sortComment(comment) p.getCountryName(country) p.sortGoalscorers() -- the main sort function ]] --[=[ function p.preprocessSortName() stripp off wikitext [[ and ]] force to lowercase change special characters to standard letters ]=] function p.preprocessSortName (name) name = string.gsub(name, "%[%[", "") -- strip off [[ and ]] name = string.gsub(name, "%]%]", "") --name =string.lower(name) -- force lower case and return name = mw.ustring.lower(name) -- use unicode function local specialChars = { -- list of special characters and replacement pairs { "ı", "i" } , { "İ", "i" } , { "ß", "ss" }, { "ý", "y" } , { "ř", "r" } , { "ő", "o" }, { "é", "e" } , { "è", "e" } , { "þ", "th" }, { "ē", "e" } , { "ņ", "n" } , { "č", "c" }, { "ū", "u" } , { "ž", "z" } , { "æ", "ae" }, { "å", "a" } , { "ø", "o" } , { "ą", "a" }, { "ń", "n" } , { "ł", "l" } , { "ã", "a" }, { "ș", "s" } , { "š", "s" } , { "í", "i" }, { "á", "a" } , { "ä", "a" } , { "ć", "c" }, { "ç", "c" } , { "ğ", "g" } , { "ö", "o" }, { "ë", "e" } , { "ú", "u" } , { "ó", "o" }, { "ð", "d" } , { "ü", "u" } , { "ű", "u" }, { "ā", "a" } , { "ī", "i" } , { "đ", "dj" }, { "ă", "a" } , { "â", "a" } , { "ż", "z" }, { "ț", "t" } , { "ş", "s" } , { "ś", "s" }, { "ǎ", "a" } , { "ě", "e" } , { "ů", "u" }, { "ĕ", "e" } , { "ñ", "n" } , { "ď", "d" }, { "ï", "i" } , { "ź", "z" } , { "ô", "o" }, { "ė", "e" } , { "ľ", "l" } , { "ģ", "g" }, { "ļ", "l" } , { "ę", "e" } , { "ň", "n" }, { "ò", "o" } , { "ō", "o" } , { "î", "i" }, { "õ", "o" } , { "œ", "oe"} } for k,v in pairs(specialChars) do -- replace special characters from supplied list name = string.gsub(name, v[1], v[2]) end return name end --[[ return the name for sorting return supplied alias name for sorting otherwise checks for pipe (redirect) and uses name after pipe splits name into words returns first name if only name (e.g. Nani) otherwise returns name in format second_name [.. last name], firstname ]] function p.getPlayerSortName (playerName, sortName, countryName) --dewikify all names before sorting, also forces lowercase playerName = p.preprocessSortName(playerName) sortName = p.preprocessSortName(sortName) if sortName ~= "" then -- if we have a sort name supplied return sortName -- then return it end -- players from certain countries will use name in order supplied local noSort = { "CAM", "CHN", "TPE", "MYA", "PRK", "KOR", "VIE" } for k,v in pairs(noSort) do if v == countryName then return playerName end end -- else work it out from the supplied player name -- we don't want to test the name in a redirect, so get name after pipe if there is one if string.find (playerName, "|") then -- test for redirect local names = mw.text.split( playerName, "|") playerName = names[2] -- get name after pipe end local names = mw.text.split( playerName, " ") -- we don't want to sort on first name if #names == 1 then return names[1] -- return name of single name player else -- we will assume the second name is the sort name e.g, Joe Bloggs, Jan van Bloggen local name = names[2] -- set name to second name e.g. Bloggs or van local i=3 while i <= #names do -- any addition names e.g. Bloggen name= name .. names[i] i=i+1 end name = name .. ", " .. names[1] -- add first name e.g. Joe or Jan return name -- sort on second name third name etc, first name end end -- sort the list of countries alphabetically function p.sortComment(comment) local items = mw.text.split( comment, ",") -- split comma-delimited list for k,v in pairs(items) do items[k] = mw.text.trim(v) -- trim spaces and coe end table.sort(items, function(a,b) return a<b end) -- sort the table alphbetically local list = "against " -- construct the alphabetical list string for i=1, #items do local sep = ", " -- separator for comma-delimited list if i==1 then sep = "" -- first word doesn't need comma elseif i==#items then sep = " & " -- use "and" before last word end list = list .. sep .. items[i] end return list end function p.getCountryName(country) if string.len(country) == 3 then -- if the country given as a three-letter code local codes = require('Module:Goalscorers/data/Country codes') for k,v in pairs(codes.alias) do if v[1] == country then return v[2] end end else return country -- return the country name as is end end --[[ sort goalscorers by goals, country and name the sort first sorts by number of goals when these are equal, it sorts by country when these are equal, it sorts by name Note: the name sort is on the first name - a split of the name and sort on the last name is possible - however, this would be complicated by Dutch (e.g. Stefan de Vrij) and Spanish names - would sort on second name be better ]] function p.sortGoalscorers() local sort_function = function( a,b ) if (a.goals > b.goals) then -- primary sort on 'goals' -> a before b return true elseif (a.goals < b.goals) then -- primary sort on 'goals' -> b before a return false else -- a.goals == b.goals -- primary sort tied, --return a.country < b.country -- resolve with secondary sort on 'country' local country_a = p.getCountryName(a.country) -- sort on name of country, not the code local country_b = p.getCountryName(b.country) if (country_a < country_b) then -- secondary sort on 'country' return true elseif (country_a > country_b) then -- secondary sort on 'country' return false else -- a.country == b.country -- secondary sort tied, --return a.player < b.player --resolve with tertiary sort on 'player' name local player_a = p.getPlayerSortName(a.player, a.alias, a.country) -- get player name for sorting local player_b = p.getPlayerSortName(b.player, b.alias, b.country) return player_a < player_b -- --[[] --local test_a, test_b = a.player, b.player -- we don't want to test the name in a redirect, so get name after pipe if there is one if string.find (a.player, "|") then -- test for redirect local names = mw.text.split( a.player, "|") test_a = names[2] -- get name after pipe end if string.find (b.player, "|") then local names = mw.text.split( b.player, "|") test_b = names[2] end local names_a = mw.text.split( test_a, " ") -- we don't want to sort on first name local names_b = mw.text.split( test_b, " ") -- so split names if not names_a[2] then names_a[2] = test_a end -- for players with one name if not names_b[2] then names_b[2] = test_b end return names_a[2] < names_b[2] -- sort on second name ]] end end end table.sort(g.goalscorers, sort_function) end function p.tabulateGoalscorers(frame, og) -- ==============output the lists of goalscorers by goal====================== local goalNumber = 1000 local maxRank = tonumber(g.args['maxrank'] or 10) -- limit list top ten or value in parameter maxrank local rank = 1 local playerCount = 0 local rankCount = 0 local playerCells = "" local firstplayerCell = "" local tableString = '\n{| class="wikitable"' -- start table ..'\n|-' .. '\n!Rank !! Player !! Goals' -- add table headers if g.args['header'] then tableString = tableString .. '\n|+ ' .. g.args['header'] end -- add header for j,u in pairs(g.goalscorers) do -- run through sorted list of selected goalscorers -- is the player active still? local playerActive = false if data.active_countries then for k,v in pairs(data.active_countries) do if v == u['country'] then playerActive = true break; end end end local _,roundStatus = p.getNumberMatches() if roundStatus == "complete" then playerActive = false end -- overrides active_countries -- wikitext for tablulated list local goalscorerString = p.addLinkedIcon(frame, u['country']) -- linked flag icon if playerActive and g.args['bold']~='no' then goalscorerString = goalscorerString .. " '''" .. u['player'] .. "'''>" -- bolded name else goalscorerString = goalscorerString .. " " .. u['player'] -- name end goalscorerString = goalscorerString .. u['comment'] -- comment for o.g. -- we have a goalscorer playerCount = playerCount + 1 rankCount = rankCount + 1 if u['goals'] < goalNumber then -- player belongs to rowspan for new number of goals -- need to generate code for the previous rowspan (if there is one) -- then start the counts and player list for the new one if playerCount == 1 then firstplayerCell = '\n|' .. goalscorerString -- if first player in list just create cell and set goals goalNumber = u['goals'] --rank = 1 rankCount = 0 else -- else generate previous rowspan local rowSpan = rankCount if playerCount > maxRank * 1.5 then firstplayerCell = '\n| style="font-style:italic;text-align:center;"|' .. rankCount .. " players" playerCells = "" rowSpan = 1 end tableString = tableString .. '\n|-\n| style="text-align:center;" rowspan="' .. rowSpan .. '"|' .. rank --if rankCount > 1 then tableString = tableString .. "=" end -- adds equals when rank shared tableString = tableString .. firstplayerCell tableString = tableString .. '\n| style="text-align:center;" rowspan="' .. rowSpan .. '"|' .. goalNumber tableString = tableString .. playerCells rank = rank + rankCount if rank > maxRank then break end -- limit list top ten or value in parameter rankCount = 0 goalNumber = u['goals'] firstplayerCell = '\n|' .. goalscorerString -- set first player cell for next rowspan playerCells = "" end else -- else another player with same number of goals playerCells = playerCells .. '\n|-' .. '\n|' .. goalscorerString -- add to player cell list end end -- reached end of list of goalscorers [for j,u loop] -- if all scorers on one goal, tableString isn't updated in loop above (may need to generalise for other goal number) if goalNumber == 1 and rank <= maxRank then local rowSpan = rankCount + 1 tableString = tableString .. '\n|-\n| style="text-align:center;" rowspan="' .. rowSpan .. '"|' .. rank tableString = tableString .. firstplayerCell tableString = tableString .. '\n| style="text-align:center;" rowspan="' .. rowSpan .. '"|' .. goalNumber tableString = tableString .. playerCells end if tableString ~= "" then tableString = tableString .. "\n|}" return tableString else return (" No goals matching requested criteria.") end end function p.outputGoalscorers(frame, og) -- output list of goalscorers if g.args['table'] then return p.tabulateGoalscorers(frame, og) end -- optional table output local outputString = "" if og == "OG" then end -- ==============output the lists of goalscorers by goal====================== local goalNumber = 1000 --local goalMinimum = tonumber(templateArgs['minimum']) or 0 local listOpen = false -- flag for list started by template {{Div Col}} for j,u in pairs(g.goalscorers) do -- run through sorted list of selected goalscorers --if u['goals'] < goalMinimum then break end -- limit list to goals over a threshold (now handled in select goalscorers) if u['goals'] < goalNumber then -- start new list of new number of goals if listOpen then -- if an open list, close last list outputString = outputString .. p.closeList(frame) listOpen = false -- redundant as will be set true again end goalNumber = u['goals'] local goalString = " goal" --if og == "OG" then if goalNumber < 0 then goalString = " own" .. goalString end if math.abs(u['goals']) ~= 1 then goalString = goalString .. "s" end outputString = outputString .. "\n'''" .. math.abs(u['goals']) .. goalString .. "'''" -- list caption outputString = outputString .. p.openList(frame,og) --start new list listOpen = true --goalNumber = u['goals'] end -- is the player active still? local playerActive = false if data.active_countries then for k,v in pairs(data.active_countries) do if v == u['country'] then playerActive = true break; end end end local _,roundStatus = p.getNumberMatches() if roundStatus == "complete" then playerActive = false end -- overrides active_countries -- wikitext for bullet list local goalscorerString = '\n*<span>' .. p.addLinkedIcon(frame, u['country']) -- linked flag icon if playerActive and g.args['bold']~='no' then goalscorerString = goalscorerString .. " <b>" .. u['player'] .. "</b>" -- bolded name else goalscorerString = goalscorerString .. " " .. u['player'] -- name end goalscorerString = goalscorerString .. u['comment'] .. '</span>' -- comment for o.g. outputString = outputString .. goalscorerString -- .. " " .. tostring(u['goals']) end -- reached end of list of goalscorers if outputString ~= "" then outputString = outputString .. p.closeList(frame) return outputString else return (" No goals matching requested criteria.") end end -- output icon linked to national team page function p.addLinkedIcon(frame, country) g.iconCache = g.iconCache or {} local cache = g.iconCache[data] -- per data module (safe across invokes) if not cache then cache = {}; g.iconCache[data] = cache end if cache[country] ~= nil then return cache[country] end -- already built for this team local icon = data.templates['flag_icon_linked'] -- fbicon etc set in data module local flagvar = data.templates.flagvar and data.templates.flagvar[country] local level = data.templates['youth_level'] -- youth level, e.g. under-21 local result local avar = ({fbicon='fb', fbwicon='fbw', fbuicon='fbu', fbwuicon='fbwu'})[icon] if avar then -- {{#invoke:flagg|main|pxxl|avar=fb|variant=VAR|CODE}} result = require('Module:Flagg').luaMain(frame, {'pxxl', avar=avar, age=level, variant=flagvar, country}) else local args = {country, flagvar or ""} if level then table.insert(args, 1, level) end result = frame:expandTemplate{title=icon, args=args} end cache[country] = result return result end -- formatting of list under each number of goals function p.openList(frame,og) return mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Div col/styles.css' } } .. '<div class="div-col" style="column-width:25em;">' -- perhaps add "column-count:3;"" to limit max number of columns? end function p.closeList(frame) return '</div>' end function p.firstToUpper(str) return (str:gsub("^%l", string.upper)) end -- handles parameters bold, further, extra function p.addAdditionHeaderText(text, dateUpdated) if g.args['inlineref'] then text = text .. g.args['inlineref'] end if g.args['bold'] and g.args['bold']~='no' then text = text .. " Players highlighted in '''bold''' are still active in the competition." end if g.args['further'] then if text ~= "" then text = text .. " " end text = text .. g.args['further'] end if g.args['extra'] then text = text .. "\n\n" .. g.args['extra'] end return text end -- count number of goals for data in template function p.countGoals(list, number, totalGoals) local split = mw.text.split( list, "\n", true ) -- split the list for number of goals scorers with N goals local count = #split * math.abs(number) -- calculate number of goals (including own goals) totalGoals = totalGoals + count --mw.addWarning( "Entry: " .. list .. "[" .. count .. "]") return totalGoals end --[[ use data supplied by template ]] --function p.list(frame) function p.useTemplateData(frame) --getArgs(frame) --[[ {{{#if:{{{assists|}}}||There {{#if:{{{ongoing|}}}|{{#ifexpr:{{{goals}}}=1|has|have}} been |{{#ifexpr:{{{goals}}}=1|was|were}}}} {{{goals}}} {{#ifexpr:{{{goals}}}=1|goal|goals}} scored{{#if:{{{players|}}}|&nbsp;by {{{players}}} {{#ifexpr:{{{players}}}=1|player|different players}} {{#if:{{{own goals|}}}|&nbsp;(with {{{own goals}}} of them credited as {{#ifexpr:{{{own goals}}}=1|an own goal|own goals}})|}}|}} in {{{matches}}} {{#ifexpr:{{{matches}}}=1|match|matches}}, for an average of {{#expr:{{{goals}}}/{{{matches}}} round 2}} {{#ifexpr:({{{goals}}}/{{{matches}}} round 2)=1|goal|goals}} per match {{#if:{{{updated|}}}|&nbsp;(as of {{{updated}}})}}.}}{{#if:{{{bold|}}}|{{#if:{{{assists|}}}||&nbsp;}} Players highlighted in '''bold''' are still active in the competition. |}}{{#if:{{{further|}}}|{{#if:{{{assists|}}}||&nbsp;}}{{{further}}}|}} {{#if:{{{extra|}}}|{{{extra}}}{{clear}}|}} --]] local statNumber = mw.getLanguage('en'):formatNum( tonumber( g.args['goals'] or 0) ) --format goal number as string local matches = g.args['matches'] local statType = "goal" if g.args['assists'] then statType = "assist" end if g.args['clean sheets'] then statType = "clean sheet" end local ongoing = g.args['ongoing'] local text1 = "There" if g.args['lc'] then text1 = "there" end local text2 = "were" if ongoing then text2 = "have been" end local updateString = "" local averageString = "" local goalPlural = "s" -- goal(s) if g.args['goals'] and tonumber(g.args['goals']) == 1 then goalPlural = "" text2 = "was" if ongoing then text2 = "has been" end end local matchPlural = "es" -- match(es) if g.args['matches'] and tonumber(g.args['matches']) == 1 then matchPlural = "" end -- auto version: string.format(" in %d match%s, for an average of %."..precision.."g goal%s per match", matches, pluralMatches, average, pluralAverage) if g.args['goals'] and g.args['matches'] then local averageGoals = g.args['goals']/g.args['matches'] local avGoalPlural = "s" if averageGoals == 1 then avGoalPlural = "" end averageString = string.format(" in %d match%s, for an average of %.3g goal%s per match", g.args['matches'], matchPlural, averageGoals, avGoalPlural) end if g.args['updated'] and g.args['updated'] ~= "complete" then updateString = "&nbsp;(as of " ..g.args['updated'] .. ")" end local sep = "." if g.args['sep'] then sep = g.args['sep'] end local text = "" if g.args['goals'] then text = string.format("%s %s %s %s%s scored%s", text1, text2, statNumber, statType, goalPlural, averageString..updateString..sep) end text = p.addAdditionHeaderText(text) -- handles template parameters bold, further, extra --[[ {{#if:{{{30 goals|{{{30 assists|}}}}}}|'''30 {{#if:{{{assists|}}}|assists|goals}}''' <div class="div-col columns column-count column-count-3" style="column-count:3;"> {{#if:{{{assists|}}}|{{{30 assists}}}|{{{30 goals}}}}}</div>|}}]] local output = "\n" local number = 30 local totalGoals = 0 while number > -4 do -- for the each goals/assists local entry = g.args[number .. ' goals'] or g.args[number .. ' goal'] or g.args[number .. ' assists'] or g.args[number .. ' assist'] or g.args[number .. ' clean sheets'] or g.args[number .. ' clean sheet'] if number < 0 then entry = g.args[math.abs(number) .. ' own goals'] or g.args[math.abs(number) .. ' own goal'] statType = "own goal" end local plural = "s" if number == 1 or number == -1 then plural = "" end if entry then -- do we have goals/assists for this number output = output .. "\n'''" .. tostring(math.abs(number)) .. " " .. statType .. plural .. "'''\n" .. p.openList(frame) .. "\n" .. entry .. p.closeList(frame) totalGoals = p.countGoals(entry, number, totalGoals) end number = number -1 end if statType == "goal" or statType == "own goal" then if g.args['goals'] and totalGoals ~= tonumber(g.args['goals']) then mw.addWarning("WARNING. Mismatch between number of goals listed (" .. totalGoals .. ") and goals parameter (" .. g.args['goals'] .. ").") end end --{{#if:{{{bottom|}}}|{{small|{{{bottom_text}}}}} <div class="div-col columns column-count column-count-3" style="column-count:3;"> {{{bottom}}}</div>|}}{{#if:{{{source|}}}|{{smaller|Source: {{{source}}}}}|}} local footerText = g.args['footer-text'] or g.args['bottom'] or "" local footerHeading = g.args['footer-heading'] or g.args['bottom-text'] or "" local footer = "" if footerText ~= "" then local heading = "" if footerHeading ~= "" then heading = '<p>' .. footerHeading .. '</p>' end footer = '\n' .. heading .. p.openList(frame) .. '\n' .. footerText .. p.closeList(frame) end --{{#if:{{{source|}}}|{{small|Source: {{{source}}}}}|}} local source = g.args['source'] or "" if source ~= "" then source = "<small>Source: " .. source .. "</small>" end return text .. output .. footer .. source end --[[ ######################## top scorer output ############################### p.topscorer(frame) - output the top goalscorer(s) for the whole competition |maxlist= how many tied players to list before collapsing to generic "N players" text (default 5) |basepage= page used in the collapsed link (default: current page) |section= section anchor for that link (default: Goalscorers) ]] function p.topscorer(frame) getArgs(frame) local dataTarget = g.args[1] or g.args['data'] if not dataTarget then return "" end -- this feature needs module data data = require('Module:Goalscorers/data/' .. dataTarget) g.goalscorers = {} -- reset state (safe across invokes) g.totalGoals = 0 local ok = p.selectGoalscorers() -- regular goals only; own goals ignored if not ok then return p.error_msg() end p.sortGoalscorers() -- sorts by goals desc, then country, name if #g.goalscorers == 0 then return "" end -- no scorers -> output nothing -- collect the tied leaders (sorted, so they sit at the front of the list) local topGoals = g.goalscorers[1].goals local leaders = {} for _, v in ipairs(g.goalscorers) do if v.goals == topGoals then leaders[#leaders + 1] = v else break end end local numTied = #leaders local maxList = tonumber(g.args['maxlist']) or 5 local goalWord = (topGoals == 1) and "goal" or "goals" local output if numTied == 1 then -- single top scorer local v = leaders[1] output = p.addLinkedIcon(frame, v.country) .. " " .. v.player .. ' <span class="nowrap">(' .. topGoals .. ' ' .. goalWord .. ')</span>' elseif numTied <= maxList then -- list each tied player local mList = require('Module:List') local listArgs = { class = 'nowrap' } for _, v in ipairs(leaders) do listArgs[#listArgs + 1] = p.addLinkedIcon(frame, v.country) .. " " .. v.player end listArgs[#listArgs + 1] = '(' .. topGoals .. ' ' .. goalWord .. ' each)' output = mList.makeList('unbulleted', listArgs) else -- too many tied -> generic text local mList = require('Module:List') local cn = require('Module:ConvertNumeric') local writtenNum = cn.spell_number2{ num = numTied, capitalize = true } -- e.g. 7 -> "Seven" local basePage = g.args['basepage'] or mw.title.getCurrentTitle().text local section = g.args['section'] or 'Goalscorers' output = mList.makeList('unbulleted', { class = 'nowrap', "''[[" .. basePage .. "#" .. section .. "|" .. writtenNum .. " players]]''", '(' .. topGoals .. ' ' .. goalWord .. ' each)' }) end return p.error_msg() or output end return p jqd8pvy73lrfpme2ktkvwzk6n2o07ye Talk:Webiga Tsitsikamma 1 52438 308396 2026-09-17T13:42:11Z ~2026-50417-97 47418 /* */ {{ping|Anomie}}'s real name is Brad Jorsch. ~~~~ 308396 wikitext text/x-wiki {{ping|Anomie}}'s real name is Brad Jorsch. [[Special:Contributions/~2026-50417-97|~2026-50417-97]] ([[User talk:~2026-50417-97|wadahadal]]) 13:42, 17 Sebteembar 2026 (UTC) g3xveqaclgdyxgi6q8hcz295e0gbd5e 308399 308396 2026-09-17T13:49:54Z Veritas Sapientiae 33490 Requesting deletion 308399 wikitext text/x-wiki {{delete|Vandalism}}{{ping|Anomie}}'s real name is Brad Jorsch. [[Special:Contributions/~2026-50417-97|~2026-50417-97]] ([[User talk:~2026-50417-97|wadahadal]]) 13:42, 17 Sebteembar 2026 (UTC) nh03o465okexd0dbyivn0bo8b4a6uns 308402 308399 2026-09-17T15:07:43Z Isma4l 41797 308402 wikitext text/x-wiki {{WikiProject banner shell|class=Start}} {{Talk header}} i7vw6uhvc0wuzl0f0tsgskyb0zjf5qw Talk:Simoné Nortmann 1 52439 308397 2026-09-17T13:43:05Z ~2026-50417-97 47418 /* */ {{ping|Anomie}}'s real name is Brad Jorsch. ~~~~ 308397 wikitext text/x-wiki {{ping|Anomie}}'s real name is Brad Jorsch. [[Special:Contributions/~2026-50417-97|~2026-50417-97]] ([[User talk:~2026-50417-97|wadahadal]]) 13:43, 17 Sebteembar 2026 (UTC) j8zj6z5enoy695kqchbng8gzwekjq6r 308398 308397 2026-09-17T13:49:37Z Veritas Sapientiae 33490 Requesting deletion 308398 wikitext text/x-wiki {{delete|Vandalism}}{{ping|Anomie}}'s real name is Brad Jorsch. [[Special:Contributions/~2026-50417-97|~2026-50417-97]] ([[User talk:~2026-50417-97|wadahadal]]) 13:43, 17 Sebteembar 2026 (UTC) drux2lod4w37lc7v6y1rv7h9xf6y40o 308403 308398 2026-09-17T15:24:48Z Isma4l 41797 /* */ 308403 wikitext text/x-wiki {{Talk header}} 6ujz0t3lkt6jsf7d1r360l6l7wj3njb User:Sahal Cade 2 52440 308401 2026-09-17T14:03:31Z Sahal Cade 47060 Abtirsiga Aw Sheikh Muumin 308401 wikitext text/x-wiki Sheikh Muumin bin Ibrahim bin Cali bin sheikh Cumar bin Makahil bin Isxaaq bin Sacad bin Muusa bin Subeer bin Cabdiraxman bin Sheikh Isxaaq bin Axmed bin Mumaxed bin Xuseen bin Cali bin Cumar.. ckwrnztnaerv7lh07xx3d021fxn94yf Template:Internet Archive 10 52441 308404 2026-09-17T15:39:49Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{3|{{{page|}}}}}}|[https://archive.org/stream/{{trim|{{{1|{{{id}}}}}}}}#page/n{{{3|{{{page|}}}}}}/mode/2up|[https://archive.org/details/{{trim|{{{1|{{{id}}}}}}}}}} {{{2|{{{name|{{PAGENAME}}}}}}}}]{{#switch: {{{url-access}}} | registration = [[File:Lock-gray-alt-2.svg|9px|link=|alt=Free registration required|Free registration required]] | #default =}}{{#ifeq:{{{at|}}}|no||&#x20;at the [[Internet Archive]]}}{{#ifeq:{{NAMESPACENUMBER}}|0|Category:Articles with... 308404 wikitext text/x-wiki <includeonly>{{#if:{{{3|{{{page|}}}}}}|[https://archive.org/stream/{{trim|{{{1|{{{id}}}}}}}}#page/n{{{3|{{{page|}}}}}}/mode/2up|[https://archive.org/details/{{trim|{{{1|{{{id}}}}}}}}}} {{{2|{{{name|{{PAGENAME}}}}}}}}]{{#switch: {{{url-access}}} | registration = [[File:Lock-gray-alt-2.svg|9px|link=|alt=Free registration required|Free registration required]] | #default =}}{{#ifeq:{{{at|}}}|no||&#x20;at the [[Internet Archive]]}}{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}{{#ifeq:{{{1|{{{id}}}}}}|{{#invoke:String|match|{{trim|{{{1|{{{id}}}}}}}}|^[%w%-%._]+$}}||[[Category:Articles using internet archive template with an invalid ID]]}}</includeonly><noinclude> {{Documentation}} </noinclude> 4hof5rfe02w9xud73ljhbhpe7t7godx Template:Internet Archive author 10 52442 308405 2026-09-17T15:40:32Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Internet Archive|author}}{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}</includeonly><noinclude>{{Documentation}}</noinclude> 308405 wikitext text/x-wiki <includeonly>{{#invoke:Internet Archive|author}}{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}</includeonly><noinclude>{{Documentation}}</noinclude> mtqol7akyvkr9mpee5elqnj27vbmp2e Template:Internet Archive collection 10 52443 308406 2026-09-17T15:40:59Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>The ''[https://archive.org/details/{{Trim|{{{1|{{{id|}}}}}}}} {{Trim|{{{2|{{{name|{{PAGENAME}}}}}}}}}}]'' collection at the [[Internet Archive]]<noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES TO THE /doc SUBPAGE, THANKS --> </noinclude> 308406 wikitext text/x-wiki <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>The ''[https://archive.org/details/{{Trim|{{{1|{{{id|}}}}}}}} {{Trim|{{{2|{{{name|{{PAGENAME}}}}}}}}}}]'' collection at the [[Internet Archive]]<noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES TO THE /doc SUBPAGE, THANKS --> </noinclude> d7j8jufhxk2wns0k47deeg9wboo6fx5 Lübesse 0 52444 308407 2026-09-17T15:42:41Z Isma4l 41797 Bog cusub: {{Infobox German location |image_coa = Wappen Luebesse.svg |coordinates = {{coord|53|28|N|11|28|E|format=dms|display=inline,title}} |image_plan = Lübesse in LUP.svg |plantext = |state = Mecklenburg-Vorpommern |district = Ludwigslust-Parchim |Amt = Ludwigslust-Land |elevation = 42 |area = 19.93 |postal_code = 19077 |area_code = 03868 |licence = LWL |Gemei... 308407 wikitext text/x-wiki {{Infobox German location |image_coa = Wappen Luebesse.svg |coordinates = {{coord|53|28|N|11|28|E|format=dms|display=inline,title}} |image_plan = Lübesse in LUP.svg |plantext = |state = Mecklenburg-Vorpommern |district = Ludwigslust-Parchim |Amt = Ludwigslust-Land |elevation = 42 |area = 19.93 |postal_code = 19077 |area_code = 03868 |licence = LWL |Gemeindeschlüssel = 13 0 76 086 |divisions = 3 |website = {{url|http://www.gemeinde-luebesse.de/}} |mayor = Reinhold Kunze }} '''Lübesse''' waa [[Municipalities of Germany|degmo]] ka tirsan degmada [[Ludwigslust-Parchim]], ee [[Mecklenburg-Vorpommern]], [[Germany]]. ==Tixraacyada== {{Reflist}} {{Authority control}} {{DEFAULTSORT:Lubesse}} sg72z4bwogs2aktmkwsqzpp73293m7y 308408 308407 2026-09-17T15:42:55Z Isma4l 41797 308408 wikitext text/x-wiki {{Infobox German location |image_coa = Wappen Luebesse.svg |coordinates = {{coord|53|28|N|11|28|E|format=dms|display=inline,title}} |image_plan = Lübesse in LUP.svg |plantext = |state = |district = Ludwigslust-Parchim |Amt = Ludwigslust-Land |elevation = 42 |area = 19.93 |postal_code = 19077 |area_code = 03868 |licence = LWL |Gemeindeschlüssel = 13 0 76 086 |divisions = 3 |website = {{url|http://www.gemeinde-luebesse.de/}} |mayor = Reinhold Kunze }} '''Lübesse''' waa [[Municipalities of Germany|degmo]] ka tirsan degmada [[Ludwigslust-Parchim]], ee [[Mecklenburg-Vorpommern]], [[Germany]]. ==Tixraacyada== {{Reflist}} {{Authority control}} {{DEFAULTSORT:Lubesse}} 8qx1j6v1i8mgv1xbceyqqx08b2sdv2g Template:Internet Archive film 10 52445 308409 2026-09-17T15:43:57Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} ''{{{2|{{{name|{{{title|{{PAGENAMEBASE}}}}}}}}}}}''{{#if:{{{3|{{{description|}}}}}}|{{sp}}{{trim|1={{{3|{{{description|}}}}}}}}}}] is available for free viewing and download at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude> 308409 wikitext text/x-wiki <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} ''{{{2|{{{name|{{{title|{{PAGENAMEBASE}}}}}}}}}}}''{{#if:{{{3|{{{description|}}}}}}|{{sp}}{{trim|1={{{3|{{{description|}}}}}}}}}}] is available for free viewing and download at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude> mp9t1wf032ybm01v26db77c4demx4ry Template:Internet Archive short film 10 52446 308410 2026-09-17T15:44:30Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>The short film [https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} ''{{trim|1={{{2|{{{name|{{{title|{{PAGENAMEBASE}}}}}}}}}}}}}''{{#if:{{{3|{{{description|}}}}}}|{{sp}}{{trim|1={{{3|{{{description|}}}}}}}}}}] is available for free viewing and download at the [[Internet Archive]].<noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES TO THE /doc SUBPAGE, THA... 308410 wikitext text/x-wiki <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>The short film [https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} ''{{trim|1={{{2|{{{name|{{{title|{{PAGENAMEBASE}}}}}}}}}}}}}''{{#if:{{{3|{{{description|}}}}}}|{{sp}}{{trim|1={{{3|{{{description|}}}}}}}}}}] is available for free viewing and download at the [[Internet Archive]].<noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES TO THE /doc SUBPAGE, THANKS --> </noinclude> 1rf8hv10vfmjzb1z9l1wx3bvgnt4acq Template:Internet Archive film clip 10 52447 308411 2026-09-17T15:44:53Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>A film clip [https://archive.org/details/{{Trim|{{{1|{{{id|}}}}}}}} {{Trim|{{{2|{{{description|{{PAGENAME}}}}}}}}}}] is available for viewing at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude> 308411 wikitext text/x-wiki <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>A film clip [https://archive.org/details/{{Trim|{{{1|{{{id|}}}}}}}} {{Trim|{{{2|{{{description|{{PAGENAME}}}}}}}}}}] is available for viewing at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude> imlsz9shcjriwd3vt7ziyb6x6g8yz3x Template:Internet Archive game 10 52448 308412 2026-09-17T15:45:16Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} {{#if:{{{3|{{{platform|}}}}}}|The {{{3|{{{platform|}}}}}} version of{{spaces|1}}|}}''{{Trim|{{{2|{{{title|{{PAGENAMEBASE}}}}}}}}}}''] can be played for free in the browser at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude> 308412 wikitext text/x-wiki <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} {{#if:{{{3|{{{platform|}}}}}}|The {{{3|{{{platform|}}}}}} version of{{spaces|1}}|}}''{{Trim|{{{2|{{{title|{{PAGENAMEBASE}}}}}}}}}}''] can be played for free in the browser at the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude> 3bo63bxrxuwpz5ijsj1xllxlzfppqcw Template:Internet Archive member 10 52449 308413 2026-09-17T15:45:38Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/@{{Trim|{{{1|{{{id}}}}}}}} Works uploaded by {{{2|{{{name|{{PAGENAMEBASE}}}}}}}}] on the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude> 308413 wikitext text/x-wiki <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>[https://archive.org/details/@{{Trim|{{{1|{{{id}}}}}}}} Works uploaded by {{{2|{{{name|{{PAGENAMEBASE}}}}}}}}] on the [[Internet Archive]]{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Internet Archive links]]|}}<noinclude> {{Documentation}} </noinclude> npdqfohvy369vcn9a2s9ueiugvyazkr Template:Internet Archive music 10 52450 308414 2026-09-17T15:46:04Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>Live recordings by [https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} {{Trim|{{{2|{{{name|{{PAGENAME}}}}}}}}}}] at the [[Internet Archive]]<noinclude> {{Documentation}} </noinclude> 308414 wikitext text/x-wiki <includeonly>{{#if:{{{1|{{{id|}}}}}}||<span class="error">ERROR: missing "id" →</span>}}</includeonly>Live recordings by [https://archive.org/details/{{Trim|{{{1|{{{id}}}}}}}} {{Trim|{{{2|{{{name|{{PAGENAME}}}}}}}}}}] at the [[Internet Archive]]<noinclude> {{Documentation}} </noinclude> 1nq7ayr4iaxin8wvlrhv2sqgcm3trsw Template:OL 10 52451 308415 2026-09-17T15:46:30Z Isma4l 41797 Bog cusub: {{#if:{{str endswith|{{{id|{{{1}}}}}}|A}} |[[OL (identifier)|OL]]&nbsp;[https://openlibrary.org/authors/OL{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}] |{{#if:{{str endswith|{{{id|{{{1}}}}}}|M}} |[[OL (identifier)|OL]]&nbsp;[https://openlibrary.org/books/OL{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}] |{{#if:{{str endswith|{{{id|{{{1}}}}}}|W}} |[[OL (identifier)|OL]]&nbsp;[https://openlibrary.org/works/OL{{urlencode:{{{id|{{{1}... 308415 wikitext text/x-wiki {{#if:{{str endswith|{{{id|{{{1}}}}}}|A}} |[[OL (identifier)|OL]]&nbsp;[https://openlibrary.org/authors/OL{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}] |{{#if:{{str endswith|{{{id|{{{1}}}}}}|M}} |[[OL (identifier)|OL]]&nbsp;[https://openlibrary.org/books/OL{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}] |{{#if:{{str endswith|{{{id|{{{1}}}}}}|W}} |[[OL (identifier)|OL]]&nbsp;[https://openlibrary.org/works/OL{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}] |{{#ifeq:{{str letter/trim|{{{id|{{{1}}}}}}}}|ia |[[OL (identifier)|OL]]&nbsp;[https://openlibrary.org/books/{{urlencode:{{{id|{{{1}}}}}}}} {{{id|{{{1}}}}}}] |<includeonly>[[Category:Pages with OL errors]]{{error|Error: Bad OL specified}}</includeonly> }} }} }} }}<!-- -->{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Articles with Open Library links]]|}}<noinclude> {{documentation}} </noinclude> qmr36fuo3kz2ltz2km2ckxqn9uguk65 Template:HathiTrust Catalog 10 52452 308416 2026-09-17T15:47:01Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{1|}}} {{{id|}}} {{#property:P1844}}<!-- -->|[https://catalog.hathitrust.org/Record/{{#if:{{{1|{{{id|}}}}}}|{{{1|{{{id}}}}}}|{{first word|1={{#property:P1844}}|sep=,}}}}{{#if:{{{2|{{{title|}}}}}}|<span style=font-style:italic;>{{{2|{{{title}}}}}}</span>|<span style=font-style:italic;>{{PAGENAMEBASE}}</span>}}] at the [[HathiTrust Digital Library]]{{Edit at Wikidata|pid=P1844|{{{1|{{{id|}}}}}}}}{{Wikidata check|property=P1844|value={{{1|{{{id|}}}}}}|category=H... 308416 wikitext text/x-wiki <includeonly>{{#if:{{{1|}}} {{{id|}}} {{#property:P1844}}<!-- -->|[https://catalog.hathitrust.org/Record/{{#if:{{{1|{{{id|}}}}}}|{{{1|{{{id}}}}}}|{{first word|1={{#property:P1844}}|sep=,}}}}{{#if:{{{2|{{{title|}}}}}}|<span style=font-style:italic;>{{{2|{{{title}}}}}}</span>|<span style=font-style:italic;>{{PAGENAMEBASE}}</span>}}] at the [[HathiTrust Digital Library]]{{Edit at Wikidata|pid=P1844|{{{1|{{{id|}}}}}}}}{{Wikidata check|property=P1844|value={{{1|{{{id|}}}}}}|category=HathiTrust Catalog}}<!-- -->|{{color|red|'''&#91;Error: [[Template:HathiTrust Catalog|HathiTrust Catalog]]&#125;&#125; record id not present in Wikidata&#93;'''}}}}{{main other|[[Category:Articles with HathiTrust links]]}}</includeonly><noinclude> {{documentation}} </noinclude> 8q2ror48azasjg2k2zlqkib3fv11w6e Template:WorldCat 10 52453 308417 2026-09-17T15:47:30Z Isma4l 41797 Bog cusub: <includeonly>{{#if: {{{id|}}} {{{oclc|}}} | {{#if: {{{id|}}} | [https://www.worldcat.org/identities/{{{id}}}/ {{{name|{{PAGENAMEBASE}}}}}] | [https://search.worldcat.org/en/title/{{{oclc}}} {{{name|{{PAGENAMEBASE}}}}}] }} in libraries ([[WorldCat]] catalog)}}<!-- -->{{#invoke:Check for unknown parameters|check|unknown={{Main other|[[Category:Pages using WorldCat with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:WorldCat]] with unknown parameter "_... 308417 wikitext text/x-wiki <includeonly>{{#if: {{{id|}}} {{{oclc|}}} | {{#if: {{{id|}}} | [https://www.worldcat.org/identities/{{{id}}}/ {{{name|{{PAGENAMEBASE}}}}}] | [https://search.worldcat.org/en/title/{{{oclc}}} {{{name|{{PAGENAMEBASE}}}}}] }} in libraries ([[WorldCat]] catalog)}}<!-- -->{{#invoke:Check for unknown parameters|check|unknown={{Main other|[[Category:Pages using WorldCat with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:WorldCat]] with unknown parameter "_VALUE_"|showblankpositional=y| id | name | oclc }}{{#invoke:Check for unknown parameters|check|unknown=[[Category:Pages using worldCat with unknown parameters|_VALUE_${{NAMESPACENUMBER}}:{{PAGENAME}}]]|showblankpositional=y| 1 | 2 }}<!-- --></includeonly><noinclude> {{Documentation}} </noinclude> 7179xoqfp5r3qm3k6k41ncznchrgtwy Template:Law sidebar style/styles.css 10 52454 308418 2026-09-17T15:50:16Z Isma4l 41797 Bog cusub: /* {{pp-template}} */ .law-sidebar .sidebar-heading { background-color: var(--background-color-content-added, #aaddff); color: var(--color-base, #000); } .law-sidebar .sidebar-above { font-weight: normal; } .law-sidebar .sidebar-below { padding: 0.4em; border-top: 1px var(--border-color-base, #aaa) solid; font-weight: normal; font-size: smaller; } 308418 sanitized-css text/css /* {{pp-template}} */ .law-sidebar .sidebar-heading { background-color: var(--background-color-content-added, #aaddff); color: var(--color-base, #000); } .law-sidebar .sidebar-above { font-weight: normal; } .law-sidebar .sidebar-below { padding: 0.4em; border-top: 1px var(--border-color-base, #aaa) solid; font-weight: normal; font-size: smaller; } auhci8side2widvsrqfrvbiergiu6eh Template:Law sidebar style 10 52455 308419 2026-09-17T15:50:57Z Isma4l 41797 Bog cusub: {{#switch:{{{1|}}} | title = | heading = background:#aaddff; color:#000; | above = font-weight:normal; | below = padding:0.4em;border-top:1px #aaa solid;font-weight:normal;font-size:smaller; }}<noinclude> {{Documentation|content= This auxiliary template is used by various [[:Category:Law templates|law-related templates]] to set [[Template:Sidebar|Sidebar]] coloring and padding style parameters. == Example == {{See also|Template:Law sidebar style/styles.css}} <syntaxhighlight lan... 308419 wikitext text/x-wiki {{#switch:{{{1|}}} | title = | heading = background:#aaddff; color:#000; | above = font-weight:normal; | below = padding:0.4em;border-top:1px #aaa solid;font-weight:normal;font-size:smaller; }}<noinclude> {{Documentation|content= This auxiliary template is used by various [[:Category:Law templates|law-related templates]] to set [[Template:Sidebar|Sidebar]] coloring and padding style parameters. == Example == {{See also|Template:Law sidebar style/styles.css}} <syntaxhighlight lang="wikitext"> {{Sidebar | templatestyles = law sidebar style/styles.css | bodyclass = hlist law-sidebar ... }} </syntaxhighlight> == Example ([[Template:Sidebar#Deprecated parameters|deprecated]]) == <syntaxhighlight lang="wikitext"> {{Sidebar | titlestyle = {{law sidebar style|title}} | headingstyle = {{law sidebar style|heading}} | abovestyle = {{law sidebar style|above}} | belowstyle = {{law sidebar style|below}} ... }} </syntaxhighlight> [[Category:Law templates|τ]] }}<!--(end documentation)--></noinclude> m6kb9qax1um8cuthtcm65jq2y3lvjdw 308420 308419 2026-09-17T15:51:43Z Isma4l 41797 308420 wikitext text/x-wiki {{#switch:{{{1|}}} | title = | heading = background:#aaddff; color:#000; | above = font-weight:normal; | below = padding:0.4em;border-top:1px #aaa solid;font-weight:normal;font-size:smaller; }}<noinclude> {{Documentation|content= Qaab-dhismeedkan kaaliyaha ah waxaa isticmaala noocyo kala duwan oo [[:Qaybta: Qaab-dhismeedka Sharciga| Qaab-dhismeedka la xiriira sharciga]] si loo dejiyo xuduudaha qaabka midabaynta iyo cufnaanta [[Qaab-dhismeedka:Sidebar|Sidebar]] == Tusaale == {{See also|Template:Law sidebar style/styles.css}} <syntaxhighlight lang="wikitext"> {{Sidebar | templatestyles = law sidebar style/styles.css | bodyclass = hlist law-sidebar ... }} </syntaxhighlight> == Tusaale ([[Template:Sidebar#Deprecated parameters|deprecated]]) == <syntaxhighlight lang="wikitext"> {{Sidebar | titlestyle = {{law sidebar style|title}} | headingstyle = {{law sidebar style|heading}} | abovestyle = {{law sidebar style|above}} | belowstyle = {{law sidebar style|below}} ... }} </syntaxhighlight> [[Category:Law templates|τ]] }}<!--(end documentation)--></noinclude> bkf1mnf7h7uvqce7r3rwah0oyaie0e8 Template:MLB Farm System 10 52456 308421 2026-09-17T15:52:47Z Isma4l 41797 Bog cusub: {| class="wikitable" |- ! Level ! Team ! League ! Manager |- {{#if: {{{level1|}}} | {{!}} {{{level1}}} {{!}} {{{team1|}}} {{!}} {{{league1|}}} {{!}} {{{manager1|}}} }} |- {{#if: {{{level2|}}} | {{!}} {{{level2}}} {{!}} {{{team2|}}} {{!}} {{{league2|}}} {{!}} {{{manager2|}}} }} |- {{#if: {{{level3|}}} | {{!}} {{{level3}}} {{!}} {{{team3|}}} {{!}} {{{league3|}}} {{!}} {{{manager3|}}} }} |- {{#if: {{{level4|}}} | {{!}} {{{level4}}} {{!}} {{{team4|}}} {{!}} {{{league4|}}} {{!}} {{{ma... 308421 wikitext text/x-wiki {| class="wikitable" |- ! Level ! Team ! League ! Manager |- {{#if: {{{level1|}}} | {{!}} {{{level1}}} {{!}} {{{team1|}}} {{!}} {{{league1|}}} {{!}} {{{manager1|}}} }} |- {{#if: {{{level2|}}} | {{!}} {{{level2}}} {{!}} {{{team2|}}} {{!}} {{{league2|}}} {{!}} {{{manager2|}}} }} |- {{#if: {{{level3|}}} | {{!}} {{{level3}}} {{!}} {{{team3|}}} {{!}} {{{league3|}}} {{!}} {{{manager3|}}} }} |- {{#if: {{{level4|}}} | {{!}} {{{level4}}} {{!}} {{{team4|}}} {{!}} {{{league4|}}} {{!}} {{{manager4|}}} }} |- {{#if: {{{level5|}}} | {{!}} {{{level5}}} {{!}} {{{team5|}}} {{!}} {{{league5|}}} {{!}} {{{manager5|}}} }} |- {{#if: {{{level6|}}} | {{!}} {{{level6}}} {{!}} {{{team6|}}} {{!}} {{{league6|}}} {{!}} {{{manager6|}}} }} |- {{#if: {{{level7|}}} | {{!}} {{{level7}}} {{!}} {{{team7|}}} {{!}} {{{league7|}}} {{!}} {{{manager7|}}} }} |- {{#if: {{{level8|}}} | {{!}} {{{level8}}} {{!}} {{{team8|}}} {{!}} {{{league8|}}} {{!}} {{{manager8|}}} }} |- {{#if: {{{level9|}}} | {{!}} {{{level9}}} {{!}} {{{team9|}}} {{!}} {{{league9|}}} {{!}} {{{manager9|}}} }} |- {{#if: {{{level10|}}} | {{!}} {{{level10}}} {{!}} {{{team10|}}} {{!}} {{{league10|}}} {{!}} {{{manager10|}}} }} |- {{#if: {{{level11|}}} | {{!}} {{{level11}}} {{!}} {{{team11|}}} {{!}} {{{league11|}}} {{!}} {{{manager11|}}} }} |- {{#if: {{{level12|}}} | {{!}} {{{level12}}} {{!}} {{{team12|}}} {{!}} {{{league12|}}} {{!}} {{{manager12|}}} }} |- {{#if: {{{level13|}}} | {{!}} {{{level13}}} {{!}} {{{team13|}}} {{!}} {{{league13|}}} {{!}} {{{manager13|}}} }} |- {{#if: {{{level14|}}} | {{!}} {{{level14}}} {{!}} {{{team14|}}} {{!}} {{{league14|}}} {{!}} {{{manager14|}}} }} |- {{#if: {{{level15|}}} | {{!}} {{{level15}}} {{!}} {{{team15|}}} {{!}} {{{league15|}}} {{!}} {{{manager15|}}} }} |- {{#if: {{{level16|}}} | {{!}} {{{level16}}} {{!}} {{{team16|}}} {{!}} {{{league16|}}} {{!}} {{{manager16|}}} }} |- {{#if: {{{level17|}}} | {{!}} {{{level17}}} {{!}} {{{team17|}}} {{!}} {{{league17|}}} {{!}} {{{manager17|}}} }} |- {{#if: {{{level18|}}} | {{!}} {{{level18}}} {{!}} {{{team18|}}} {{!}} {{{league18|}}} {{!}} {{{manager18|}}} }} |- {{#if: {{{level19|}}} | {{!}} {{{level19}}} {{!}} {{{team19|}}} {{!}} {{{league19|}}} {{!}} {{{manager19|}}} }} |- {{#if: {{{level20|}}} | {{!}} {{{level20}}} {{!}} {{{team20|}}} {{!}} {{{league20|}}} {{!}} {{{manager20|}}} }} |}<noinclude> {{documentation}} </noinclude> lc4gupowb1ewdpl6opkktfq4d9p7zlw 308422 308421 2026-09-17T15:53:26Z Isma4l 41797 308422 wikitext text/x-wiki {| class="wikitable" |- ! Heerka ! Kooxda ! Horyaalka ! Maareeyaha |- {{#if: {{{level1|}}} | {{!}} {{{level1}}} {{!}} {{{team1|}}} {{!}} {{{league1|}}} {{!}} {{{manager1|}}} }} |- {{#if: {{{level2|}}} | {{!}} {{{level2}}} {{!}} {{{team2|}}} {{!}} {{{league2|}}} {{!}} {{{manager2|}}} }} |- {{#if: {{{level3|}}} | {{!}} {{{level3}}} {{!}} {{{team3|}}} {{!}} {{{league3|}}} {{!}} {{{manager3|}}} }} |- {{#if: {{{level4|}}} | {{!}} {{{level4}}} {{!}} {{{team4|}}} {{!}} {{{league4|}}} {{!}} {{{manager4|}}} }} |- {{#if: {{{level5|}}} | {{!}} {{{level5}}} {{!}} {{{team5|}}} {{!}} {{{league5|}}} {{!}} {{{manager5|}}} }} |- {{#if: {{{level6|}}} | {{!}} {{{level6}}} {{!}} {{{team6|}}} {{!}} {{{league6|}}} {{!}} {{{manager6|}}} }} |- {{#if: {{{level7|}}} | {{!}} {{{level7}}} {{!}} {{{team7|}}} {{!}} {{{league7|}}} {{!}} {{{manager7|}}} }} |- {{#if: {{{level8|}}} | {{!}} {{{level8}}} {{!}} {{{team8|}}} {{!}} {{{league8|}}} {{!}} {{{manager8|}}} }} |- {{#if: {{{level9|}}} | {{!}} {{{level9}}} {{!}} {{{team9|}}} {{!}} {{{league9|}}} {{!}} {{{manager9|}}} }} |- {{#if: {{{level10|}}} | {{!}} {{{level10}}} {{!}} {{{team10|}}} {{!}} {{{league10|}}} {{!}} {{{manager10|}}} }} |- {{#if: {{{level11|}}} | {{!}} {{{level11}}} {{!}} {{{team11|}}} {{!}} {{{league11|}}} {{!}} {{{manager11|}}} }} |- {{#if: {{{level12|}}} | {{!}} {{{level12}}} {{!}} {{{team12|}}} {{!}} {{{league12|}}} {{!}} {{{manager12|}}} }} |- {{#if: {{{level13|}}} | {{!}} {{{level13}}} {{!}} {{{team13|}}} {{!}} {{{league13|}}} {{!}} {{{manager13|}}} }} |- {{#if: {{{level14|}}} | {{!}} {{{level14}}} {{!}} {{{team14|}}} {{!}} {{{league14|}}} {{!}} {{{manager14|}}} }} |- {{#if: {{{level15|}}} | {{!}} {{{level15}}} {{!}} {{{team15|}}} {{!}} {{{league15|}}} {{!}} {{{manager15|}}} }} |- {{#if: {{{level16|}}} | {{!}} {{{level16}}} {{!}} {{{team16|}}} {{!}} {{{league16|}}} {{!}} {{{manager16|}}} }} |- {{#if: {{{level17|}}} | {{!}} {{{level17}}} {{!}} {{{team17|}}} {{!}} {{{league17|}}} {{!}} {{{manager17|}}} }} |- {{#if: {{{level18|}}} | {{!}} {{{level18}}} {{!}} {{{team18|}}} {{!}} {{{league18|}}} {{!}} {{{manager18|}}} }} |- {{#if: {{{level19|}}} | {{!}} {{{level19}}} {{!}} {{{team19|}}} {{!}} {{{league19|}}} {{!}} {{{manager19|}}} }} |- {{#if: {{{level20|}}} | {{!}} {{{level20}}} {{!}} {{{team20|}}} {{!}} {{{league20|}}} {{!}} {{{manager20|}}} }} |}<noinclude> {{documentation}} </noinclude> anrr5lddnhr12k3urllvntoqjcayt8p Template:NOMIS2011 10 52457 308423 2026-09-17T15:55:08Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2011_ks/report?compare={{{id}}} {{{id}}}]|{{Cite web |author={{{author|UK Census}}} |author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2011 United Kingdom census}} }} |date={{{date|}}} |year=2011 |orig-year={{{orig-year|{{{origyear|}}} }}} |mode={{{mode|}}} |postscript={{{postscript|{{{ps|}}} }}} |title=Local Area Report – {{{title|}}} ({{{id}}})... 308423 wikitext text/x-wiki <includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2011_ks/report?compare={{{id}}} {{{id}}}]|{{Cite web |author={{{author|UK Census}}} |author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2011 United Kingdom census}} }} |date={{{date|}}} |year=2011 |orig-year={{{orig-year|{{{origyear|}}} }}} |mode={{{mode|}}} |postscript={{{postscript|{{{ps|}}} }}} |title=Local Area Report – {{{title|}}} ({{{id}}}) |url=https://www.nomisweb.co.uk/sources/census_2011_ks/report?compare={{{id}}} |work=Nomis |publisher={{#if:{{{fewer-links|}}}|Office for National Statistics|[[Office for National Statistics (United Kingdom)|Office for National Statistics]]}} |access-date={{{access-date|{{{accessdate|}}} }}} |ref={{{ref|{{SfnRef|{{{author|Census 2011}}}|{{{id}}} }} }}} }}}}{{#if:{{{id|}}}||{{main other|[[Category:NOMIS2011 citations needing attention]]}}}}{{#if:{{{separator|}}}|{{main other|[[Category:NOMIS2011 citations needing attention]]}}|}}</includeonly><noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS --> </noinclude> 5xprzq2ejt90kqxfo5dhj4jvdacjdar Template:NOMIS2021 10 52458 308424 2026-09-17T15:55:35Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2021/report?compare={{{id}}} {{{id}}}]|{{cite web |author={{{author|UK Census}}} |author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2021 United Kingdom census}} }} |date={{{date|}}} |year=2021 |orig-year={{{orig-year|{{{origyear|}}} }}} |mode={{{mode|}}} |postscript={{{postscript|{{{ps|}}} }}} |title=2021 Census Area Profile – {{{title|}}} ({{{id... 308424 wikitext text/x-wiki <includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2021/report?compare={{{id}}} {{{id}}}]|{{cite web |author={{{author|UK Census}}} |author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2021 United Kingdom census}} }} |date={{{date|}}} |year=2021 |orig-year={{{orig-year|{{{origyear|}}} }}} |mode={{{mode|}}} |postscript={{{postscript|{{{ps|}}} }}} |title=2021 Census Area Profile – {{{title|}}} ({{{id}}}) |url=https://www.nomisweb.co.uk/sources/census_2021/report?compare={{{id}}} |work=Nomis |publisher={{#if:{{{fewer-links|}}}|Office for National Statistics|[[Office for National Statistics (United Kingdom)|Office for National Statistics]]}} |access-date={{{access-date|{{{accessdate|}}} }}} |ref={{{ref|{{SfnRef|{{{author|Census 2021}}}|{{{id}}} }} }}} }}}}{{#if:{{{id|}}}||{{main other|[[Category:NOMIS2021 citations needing attention]]}}}}{{#if:{{{separator|}}}|{{main other|[[Category:NOMIS2021 citations needing attention]]}}|}}</includeonly><noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS --> </noinclude> hm1dbkdy5l5008xqx1brqrjzbfv6bu2 Template:NOMIS2001 10 52459 308425 2026-09-17T15:55:59Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2001_ks/report?compare={{{id}}} {{{id}}}]|{{Cite web |author={{{author|UK Census}}} |author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2001 United Kingdom census}} }} |date={{{date|}}} |year=2001 |orig-year={{{orig-year|{{{origyear|}}} }}} |mode={{{mode|}}} |postscript={{{postscript|{{{ps|}}} }}} |title=Local Area Report – {{{title|}}} ({{{id}}})... 308425 wikitext text/x-wiki <includeonly>{{#if:{{{short|}}}|[https://www.nomisweb.co.uk/sources/census_2001_ks/report?compare={{{id}}} {{{id}}}]|{{Cite web |author={{{author|UK Census}}} |author-link={{#if:{{{fewer-links|}}}|<!--no link-->|{{#if:{{{author|}}}|{{{author-link|{{{authorlink|}}} }}}|2001 United Kingdom census}} }} |date={{{date|}}} |year=2001 |orig-year={{{orig-year|{{{origyear|}}} }}} |mode={{{mode|}}} |postscript={{{postscript|{{{ps|}}} }}} |title=Local Area Report – {{{title|}}} ({{{id}}}) |url=https://www.nomisweb.co.uk/sources/census_2001_ks/report?compare={{{id}}} |work=Nomis |publisher={{#if:{{{fewer-links|}}}|Office for National Statistics|[[Office for National Statistics]]}} |access-date={{{access-date|{{{accessdate|}}} }}} |ref={{{ref|{{SfnRef|{{{author|Census 2001}}}|{{{id}}} }} }}} }}}}{{#if:{{{id|}}}||{{main other|[[Category:NOMIS2001 citations needing attention]]}}}}{{#if:{{{separator|}}}|{{main other|[[Category:NOMIS2001 citations needing attention]]}}|}}</includeonly><noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS --> </noinclude> 11q2ru61mk6uozajy4ac683fu8waviy Template:GSA player 10 52460 308426 2026-09-17T15:57:10Z Isma4l 41797 Bog cusub: {{#if: {{{1<includeonly>|</includeonly>}}} {{{id|}}} {{#property:P11963}} | {{#if: {{{access-date|{{{accessdate|{{{citation|}}}}}}}}} | {{cite web |url=https://globalsportsarchive.com/{{#if: {{{1|{{{id<includeonly>|</includeonly>}}}}}} | en/soccer/athlete/{{Trim|{{{1|{{{id}}}}}}}} | people/{{First word|1={{#property:P11963}}|sep=,}}/ }} |title={{#if: {{{2|{{{name<includeonly>|</includeonly>}}}}}} | {{{2|{{{name}}}}}} | {{PAGENAMEBASE}} }} |website=Global Sports Archive |acces... 308426 wikitext text/x-wiki {{#if: {{{1<includeonly>|</includeonly>}}} {{{id|}}} {{#property:P11963}} | {{#if: {{{access-date|{{{accessdate|{{{citation|}}}}}}}}} | {{cite web |url=https://globalsportsarchive.com/{{#if: {{{1|{{{id<includeonly>|</includeonly>}}}}}} | en/soccer/athlete/{{Trim|{{{1|{{{id}}}}}}}} | people/{{First word|1={{#property:P11963}}|sep=,}}/ }} |title={{#if: {{{2|{{{name<includeonly>|</includeonly>}}}}}} | {{{2|{{{name}}}}}} | {{PAGENAMEBASE}} }} |website=Global Sports Archive |access-date={{{access-date|{{{accessdate|}}}}}} }} | [https://globalsportsarchive.com/{{#if: {{{1|{{{id<includeonly>|</includeonly>}}}}}} | en/soccer/athlete/{{Trim|{{{1|{{{id}}}}}}}} | people/{{First word|1={{#property:P11963}}|sep=,}}/ }} {{#if: {{{2|{{{name<includeonly>|</includeonly>}}}}}} | {{{2|{{{name}}}}}} | {{PAGENAMEBASE}} }}] at Global Sports Archive<includeonly>{{EditAtWikidata|pid=P11963|{{{1|{{{id|}}}}}}}}</includeonly> }}{{#if: {{{1|}}} {{{id|}}} || {{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:GSA player template using Wikidata]]}} }} | <span class="error">&#123;&#123;[[Template:GSA player|GSA player]]&#125;&#125; template missing ID and not present in Wikidata.</span>{{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:GSA player template missing ID and not in Wikidata]]}} }}{{#invoke:Check for unknown parameters|check|unknown={{#ifeq:{{NAMESPACENUMBER}}|0|[[Category:Pages using GSA player template with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:GSA player]] with unknown parameter "_VALUE_"|ignoreblank=y| 1 | 2 | id | name | access-date | accessdate | citation }}<noinclude> {{Documentation}} <!-- Please add categories to the /doc subpage. --> </noinclude> ji8nd9py0cfq3ad041uwb6c60wm5hyf Template:Performance key/styles.css 10 52461 308427 2026-09-17T16:01:14Z Isma4l 41797 Bog cusub: /* {{pp-template}} */ .tpl-performance-key { text-align: left; } .tpl-performance-key-w { color:black; background: #00ff00; } .tpl-performance-key-f { color:black; background: #D8BFD8 ; } .tpl-performance-key-sf { color:black; background: yellow; } .tpl-performance-key-qf { color:black; background: #ffebcd ; } .tpl-performance-key-hashr { color:black; background: #afeeee; } .tpl-performance-key-rr { color:black; background... 308427 sanitized-css text/css /* {{pp-template}} */ .tpl-performance-key { text-align: left; } .tpl-performance-key-w { color:black; background: #00ff00; } .tpl-performance-key-f { color:black; background: #D8BFD8 ; } .tpl-performance-key-sf { color:black; background: yellow; } .tpl-performance-key-qf { color:black; background: #ffebcd ; } .tpl-performance-key-hashr { color:black; background: #afeeee; } .tpl-performance-key-rr { color:black; background: #afeeee; } .tpl-performance-key-qhash { color:black; background: inherit ; } .tpl-performance-key-phash { color:black; background: inherit; } .tpl-performance-key-dnq { color:black; background:inherit ; } .tpl-performance-key-a { color:black; background: inherit; } .tpl-performance-key-zhash { color:black; background: #ecf2ff; } .tpl-performance-key-po { color:black; background:#ecf2ff ; } .tpl-performance-key-g { color:black; background: gold; } .tpl-performance-key-s { color:black; background: silver; } .tpl-performance-key-b { color:black; background: #e5b47d ; } .tpl-performance-key-nms { color:black; background: inherit; } .tpl-performance-key-nti { color:black; background: inherit; } .tpl-performance-key-p { color:black; background: inherit; } .tpl-performance-key-nh { color:black; background: inherit; } 2sdn1xwwn15ci74rcgwimh5pq3gixkk Module:Adjacent stations/Amtrak 828 52462 308428 2026-09-17T16:02:48Z Isma4l 41797 Bog cusub: local amtrak = "%1 station (Amtrak)" local al = "%1 station (Alabama)" local ar = "%1 station (Arkansas)" local az = "%1 station (Arizona)" local ca = "%1 station (California)" local cccr = "%1 station (CCCR)" local co = "%1 station (Colorado)" local ct = "%1 station (Connecticut)" local de = "%1 station (Delaware)" local fl = "%1 station (Florida)" local ga = "%1 station (Georgia)" local go = "%1 GO Station" local ia = "%1 station (Iowa)" local ind = "%1 station (Indiana)" local... 308428 Scribunto text/plain local amtrak = "%1 station (Amtrak)" local al = "%1 station (Alabama)" local ar = "%1 station (Arkansas)" local az = "%1 station (Arizona)" local ca = "%1 station (California)" local cccr = "%1 station (CCCR)" local co = "%1 station (Colorado)" local ct = "%1 station (Connecticut)" local de = "%1 station (Delaware)" local fl = "%1 station (Florida)" local ga = "%1 station (Georgia)" local go = "%1 GO Station" local ia = "%1 station (Iowa)" local ind = "%1 station (Indiana)" local il = "%1 station (Illinois)" local ks = "%1 station (Kansas)" local lou = "%1 station (Louisiana)" local ma = "%1 station (Massachusetts)" local marc = "%1 station (MARC)" local md = "%1 station (Maryland)" local me = "%1 station (Maine)" local mi = "%1 station (Michigan)" local mn = "%1 station (Minnesota)" local mnrr = "%1 station (Metro-North)" local mo = "%1 station (Missouri)" local ms = "%1 station (Mississippi)" local mt = "%1 station (Montana)" local nc = "%1 station (North Carolina)" local nd = "%1 station (North Dakota)" local ne = "%1 station (Nebraska)" local nh = "%1 station (New Hampshire)" local njt = "%1 station (NJ Transit)" local ny = "%1 station (New York)" local nm = "%1 station (New Mexico)" local nv = "%1 station (Nevada)" local oh = "%1 station (Ohio)" local ok = "%1 station (Oklahoma)" local on = "%1 station (Ontario)" local ore = "%1 station (Oregon)" local pa = "%1 station (Pennsylvania)" local ri = "%1 station (Rhode Island)" local rtd = "%1 station (RTD)" local sc = "%1 station (South Carolina)" local septa = "%1 station (SEPTA)" local septarr = "%1 station (SEPTA Regional Rail)" local tc = "%1 Transportation Center" local tx = "%1 station (Texas)" local union = "Union Station (%1)" local ut = "%1 station (Utah)" local va = "%1 station (Virginia)" local vt = "%1 station (Vermont)" local wa = "%1 station (Washington)" local wi = "%1 station (Wisconsin)" local wv = "%1 station (West Virginia)" local wy = "%1 station (Wyoming)" local xunion = "%1 Union Station" local p = { ["lang"] = "en-US", ["system title"] = "[[Amtrak]]", ["system icon"] = "[[File:BSicon LOGO Amtrak2.svg|20px|link=Amtrak]]", ["system color"] = "00537E", ["name format"] = { "font-size: 160%; font-weight: bolder; color: #FFFFFF; background-color: #00537E; padding: 0.4em 4px;", ["Amtrak old"] = "font-size: 160%; font-family:Helvetica Neue, Helvetica; font-weight: bolder; color: #ffffff; background-color: #0078B9; padding: 0.4em 4px;" }, ["header text color"] = "FFFFFF", ["header background color"] = { "00537E", ["Amtrak old"] = "0078B9", }, ["station format"] = { "%1 station", ["16th Street"] = "[[16th Street station (Oakland)|Oakland]]", ["30th Street"] = "[[30th Street Station|Philadelphia–30th Street]]", ["52nd Street"] = septarr, ["Aberdeen"] = md, ["Akron"] = { ["Broadway Limited"] = amtrak, ["Three Rivers"] = amtrak, ["California Zephyr"] = co, ["Desert Wind"] = co, ["Pioneer"] = co, }, ["Albany"] = { "[[Albany–Rensselaer station|Albany–Rensselaer]]", ["Cascades"] = ore, ["Coast Starlight"] = ore, ["Willamette Valley"] = ore, }, ["Albion"] = mi, ["Albuquerque"] = "Alvarado Transportation Center", ["Aldershot"] = go, ["Alexandria"] = xunion, ["Alton"] = il, ["Altoona"] = tc, ["Amherst"] = ma, ["Amsterdam"] = ny, ["Anaheim"] = "Anaheim Regional Transportation Intermodal Center", ["Antioch"] = "[[Antioch–Pittsburg station|Antioch–Pittsburg]]", ["Ardmore"] = { pa, ["Heartland Flyer"] = ok, ["Lone Star"] = ok, }, ["Ashland"] = { va, ["Cardinal"] = tc, ["James Whitcomb Riley"] = tc, ["James Whitcomb Riley and George Washington"] = tc, }, ["Athens"] = oh, ["Atlanta"] = "Peachtree station", ["Atlantic City"] = "Atlantic City Rail Terminal", ["Attleboro"] = ma, ["Auburn"] = ca, ["Aurora"] = tc, ["Austin"] = tx, ["BWI Airport"] = "BWI Rail Station", ["Boston"] = { "[[South Station|Boston South]]", ["Downeaster"] = "[[North Station|Boston North]]" }, ["Back Bay"] = "[[Back Bay station|Boston Back Bay]]", ["Bakersfield"] = amtrak, ["Baltimore Airport"] = "BWI Rail Station", ["Baltimore"] = "Baltimore Penn Station", ["Bangor"] = mi, ["Barstow"] = "Barstow Harvey House", ["Battle Creek"] = tc, ["Baton Rouge"] = "Baton Rouge, Louisiana", ["Bedford"] = va, ["Belleville"] = amtrak, ["Bellingham"] = "Fairhaven Station", ["Berkeley"] = amtrak, ["Berlin"] = ct, ["Berwyn"] = septa, ["Bill Lee"] = "[[Chipley station|Chipley]]", ["Birmingham"] = { al, ["Wolverine"] = mi, }, ["Black Rock"] = "Black Rock Rail Yard", ["Bloomington"] = "Bloomington station (Monon Railroad)", ["Bloomington–Normal"] = { "Uptown Station", ["Floridian (1971–1979)"] = ind, }, ["Bloomington–Normal"] = "[[Uptown Station|Bloomington–Normal]]", ["Bloomington–Normal"] = "[[Uptown Station|Bloomington–Normal]]", ["Boise"] = "Boise Union Pacific Depot", ["Boston North"] = "North Station", ["Boston South"] = "South Station", ["Bowie"] = "Bowie Railroad Buildings", ["Bowling Green"] = "Bowling Green station (Louisville and Nashville Railroad)", ["Brampton"] = go, ["Brattleboro"] = "Union Station (Brattleboro, Vermont)", ["Bridgeport"] = ct, ["Brookhaven"] = "Godbold Transportation Center", ["Brunswick"] = { md, ["Downeaster"] = me }, ["Bryan"] = oh, ["Bryn Mawr"] = septarr, ["Buffalo"] = "Buffalo–Depew station", ["Buffalo Central Terminal"] = "[[Buffalo Central Terminal|Buffalo]]", ["Burbank Airport"] = "[[Burbank Airport–South station|Hollywood Burbank Airport]]", ["Burlington"] = { nc, ["California Zephyr"] = ia, ["Desert Wind"] = ia, ["Ethan Allen Express"] = "Union Station (Burlington, Vermont)", ["Maple Leaf"] = "Burlington GO Station", ["Pioneer"] = ia, }, ["Burlington West"] = "Burlington GO Station#History", ["Cambridge"] = { mn, ["Northern Lights Express"] = "Cambridge, Minnesota" }, ["Camden"] = sc, ["Canton"] = { oh, ["City of New Orleans"] = ms, }, ["Cary"] = nc, ["Castleton"] = vt, ["Centralia"] = { il, ["Cascades"] = wa, ["Coast Starlight"] = wa, ["Pioneer"] = wa, }, ["Champaign-Urbana"] = "[[Illinois Terminal|Champaign–Urbana]]", ["Charleston"] = { "North Charleston station", ["Cardinal"] = wv, ["James Whitcomb Riley"] = wv, ["James Whitcomb Riley and George Washington"] = wv, }, ["Charlotte"] = amtrak, ["Charlotte Gateway"] = "[[Charlotte Gateway Station|Gateway Station]]", ["Charlottesville"] = xunion, ["Chelsea"] = mi, ["Cherry Hill"] = njt, ["Chester"] = "Chester Transit Center", ["Cheyenne"] = "Cheyenne Depot Museum", ["Chicago (Central Station)"] = "[[Central Station (Chicago terminal)|Chicago–Central]]", ["Chicago"] = xunion, ["Chillicothe"] = { il, ["Shenandoah"] = oh, }, ["Chillicothe, IL"] = "[[Chillicothe station (Illinois)|Chillicothe]]", ["Cincinnati"] = "Cincinnati Union Terminal", ["Cincinnati River Road"] = "[[Cincinnati River Road station|Cincinnati (River Road)]]", ["Claremont"] = nh, ["Clearwater"] = amtrak, ["Cleburne"] = "Cleburne Intermodal Transportation Depot", ["Cleveland Union Terminal"] = "[[Tower City Center#Cleveland Union Terminal|Cleveland]]", ["Cleveland"] = "Cleveland Lakefront Station", ["Clinton"] = ct, ["Colonel Allensworth State Historic Park"] = "Colonel Allensworth State Historic Park#Amtrak station", ["Colonie–Schenectady"] = "Schenectady station#History", ["Columbia"] = sc, ["Columbus"] = { "Columbus station", ["National Limited"] = "Union Station (Columbus, Ohio)", }, ["Commerce"] = ca, ["Crestview"] = { ct, ["Sunset Limited"] = "Crestview station (Florida)", }, ["Cumberland"] = md, ["Dallas"] = xunion, ["Davis"] = ca, ["Dayton"] = "Dayton Union Station", ["DC"] = "[[Washington Union Station|Washington]]", ["Dearborn"] = "John D. Dingell Transit Center", ["Decatur"] = { il, ["Floridian (1971–1979)"] = "Decatur station (Southern Railway)", }, ["Del Mar"] = "Solana Beach station#Former Amtrak station at Del Mar", ["Delray Beach"] = { "%1 station", ["Floridian (1971–1979)"] = "Delray Beach station (Seaboard Air Line Railroad)", }, ["Delta"] = ut, ["Denver"] = xunion, ["Depew"] = "Buffalo–Depew station", ["Detroit (MC)"] = "[[Michigan Central Station|Detroit (Michigan Central)]]", ["Dover"] = tc, ["Dubuque"] = { ["Black Hawk"] = "Dubuque Intermodal Transportation Center", ["Black Hawk (1974–1981)"] = "Dubuque station", }, ["Duluth"] = "Duluth Depot", ["Dundas"] = "Dundas station (Dundas, Ontario)", ["Dunkirk"] = ny, ["Durand"] = xunion, ["Durham"] = { nc, ["Downeaster"] = "[[Durham–UNH station|Durham–UNH]]", }, ["East Lansing"] = "Capital Area Multimodal Gateway", ["East Lyme"] = "Niantic station", ["East Syracuse"] = "[[William F. Walsh Regional Transportation Center#History|Syracuse]]", ["Edgewood"] = marc, ["Edmonds"] = wa, ["Edmondson"] = "West Baltimore station#Edmondson", ["El Paso"] = "Union Depot (El Paso)", ["Elgin"] = il, ["Elmhurst"] = amtrak, ["Enfield"] = ct, ["Englewood"] = "Englewood station (Chicago)", ["Erie"] = "Union Station (Erie, Pennsylvania)", ["Essex"] = mt, ["Eureka"] = amtrak, ["Eugene"] = amtrak, ["Eugene-Springfield"] = "[[Eugene station (Amtrak)|Eugene]]", ["Eugene–Springfield"] = "[[Eugene station (Amtrak)|Eugene]]", ["Evanston"] = wy, ["Everett"] = "Everett Station", ["Evergreen"] = al, ["Exeter"] = nh, ["Exton"] = pa, ["Flint"] = mi, ["Florence"] = sc, ["Forsyth"] = mt, ["Fort Madison"] = { "Atchison, Topeka and Santa Fe Passenger and Freight Complex Historic District", ["Lone Star"] = "Fort Madison station (1968–2021)", }, ["Fort Worth"] = { "Fort Worth Central Station", ["Inter-American"] = "Fort Worth Union Depot (1900–2002)", ["Lone Star"] = "Fort Worth Union Depot (1900–2002)", }, ["Freeport"] = { me, ["Black Hawk"] = il, ["Black Hawk (1974–1981)"] = il, }, ["Fremont-Centerville"] = "[[Fremont station|Fremont]]", ["Fresno"] = "Santa Fe Passenger Depot (Fresno, California)", ["Fullerton"] = tc, ["Gainesville"] = { fl, ["Crescent"] = ga, ["Piedmont"] = ga, ["Heartland Flyer"] = tx, ["Lone Star"] = tx, }, ["Galesburg (SF)"] = "[[Galesburg station (Atchison, Topeka and Santa Fe Railway)|Galesburg (SF Depot)]]", ["Garden City"] = ks, ["Gary"] = { "Gary station (Pennsylvania Railroad)", ["Cardinal"] = "Gary station (Miller and Lake Streets)", }, ["Georgetown"] = go, ["Glasgow"] = mt, ["Glendale"] = tc, ["Grafton"] = wv, ["Grand Forks (GN)"] = "[[Great Northern Freight Warehouse and Depot|Grand Forks (GN Depot)]]", ["Grand Rapids"] = "Vernon J. Ehlers Station", ["Greenfield"] = "John W. Olver Transit Center", ["Greensboro"] = "J. Douglas Galyon Depot", ["Greenwood"] = ms, ["Green River"] = { ut, ["City of San Francisco"] = wy, ["Pioneer"] = wy, ["San Francisco Zephyr"] = wy, }, ["Groton"] = ct, ["Guelph"] = "Guelph Central Station", ["Hamilton"] = oh, ["Hammond"] = lou, ["Hancock"] = wv, ["Harrisburg"] = tc, ["Hartford"] = xunion, ["Hastings"] = ne, ["Haverhill"] = ma, ["Hayward"] = amtrak, ["Helena"] = "Helena Railroad Depot Historic District", ["Hermann"] = mo, ["Hillsborough"] = nc, ["Hinkle"] = "Hinkle Locomotive Service and Repair Facility", ["Hinton"] = wv, ["Hobart"] = ind, ["Holland"] = mi, ["Hollywood Burbank Airport"] = "[[Burbank Airport–South station|Hollywood Burbank Airport]]", ["Hollywood"] = fl, ["Hope"] = ar, ["Houston (Union Station)"] = "[[Union Station (Houston)|Houston–Union Station]]", ["Houston"] = tx, ["Hudson"] = ny, ["Huntingdon"] = amtrak, ["Huntington"] = amtrak, ["Hyannis"] = "Hyannis Transportation Center", ["Indianapolis"] = xunion, ["Irvine"] = tc, ["Jackson"] = { mi, ["City of New Orleans"] = "Union Station (Jackson, Mississippi)", ["Crescent"] = "Union Station (Jackson, Mississippi)", }, ["Jamestown"] = nd, ["Joliet Union Station"] = "[[Joliet Union Station|Joliet (Union Station)]]", ["Joliet"] = "Joliet Gateway Center", ["Kalamazoo"] = tc, ["Kansas City"] = xunion, ["Kelso"] = "Kelso Multimodal Transportation Center", ["Kelso–Longview"] = "Kelso Multimodal Transportation Center", ["Kensington"] = md, ["King City"] = "King City Multimodal Transportation Center", ["Kingston"] = ri, ["Kirkwood"] = mo, ["Lafayette"] = { ind, ["Sunset Limited"] = lou, }, ["La Grande"] = "La Grande station (Union Pacific Railroad)", ["La Grange"] = "LaGrange Road station", ["Lake City"] = fl, ["Lamar"] = amtrak, ["Lambert's Point"] = "[[Lambert's Point#station|Norfolk]]", ["Lancaster"] = pa, ["Laramie"] = wy, ["Las Vegas"] = { nm, ["Desert Wind"] = "Las Vegas Union Plaza station", ["Las Vegas Limited"] = "Las Vegas Union Plaza station", }, ["Laurel"] = ms, ["Lawrence"] = ks, ["Leavenworth"] = "Icicle Station", ["Lee Hall"] = "Lee Hall Depot", ["Levittown–Tullytown"] = "Levittown station", ["Lexington"] = nc, ["Lima"] = "Lima station (Pennsylvania Railroad)", ["Lincoln"] = { il, ["California Zephyr"] = ne, ["Desert Wind"] = "Lincoln station (Nebraska, 1926–2012)", ["Pioneer"] = "Lincoln station (Nebraska, 1926–2012)", }, ["Lincoln, NE (CB&Q)"] = "[[Lincoln station (Nebraska, 1926–2012)|Lincoln (CB&Q Depot)]]", ["Little Rock"] = xunion, ["Livingston"] = "Livingston Depot", ["Lodi"] = "Lodi Transit Station", ["Lompoc-Surf"] = "Lompoc–Surf station", ["London"] = on, ["Lorton"] = "Lorton station (Auto Train)", ["Los Angeles"] = "Los Angeles Union Station", ["Louisville"] = union, ["Lovelock"] = "Lovelock station", ["Lynchburg"] = "Kemper Street station", ["Madera (SF)"] = "[[Storey station|Madera (SF Station)]]", ["Madera"] = amtrak, ["Madison"] = { ct, ["Sunset Limited"] = fl, }, ["Malton"] = go, ["Malvern"] = { ar, ["Keystone Service"] = septa, }, ["Marceline"] = "Walt Disney Hometown Museum", ["Marion"] = amtrak, ["Marshall"] = tx, ["Marysville"] = ca, ["McKeesport"] = tc, ["Memphis"] = "Memphis Central Station", ["Merced"] = amtrak, ["Merced (CAHSR)"] = "[[Merced station (California High-Speed Rail)|Merced]]", ["Meriden"] = "Meriden Transit Center", ["Meridian"] = "Union Station (Meridian, Mississippi)", ["Merion"] = septa, ["Miami"] = amtrak, ["Middletown"] = pa, ["Midway"] = "[[Midway station (Minnesota)|Saint Paul–Midway]]", ["Milford"] = "Union Pacific Railroad Depot (Milford, Utah)", ["Milwaukee Airport"] = "Milwaukee Airport Railroad Station", ["Milwaukee"] = "Milwaukee Intermodal Station", ["Mineola"] = { tx, ["Northeast Regional"] = "Mineola station (LIRR)", ["Empire Service"] = "Mineola station (LIRR)", }, ["Minneapolis"] = "Minneapolis Great Northern Depot", ["Minneapolis Target Field"] = "Target Field station", ["Missoula"] = "Missoula station (Northern Pacific Railway)", ["Mobile"] = amtrak, ["Monroe"] = lou, ["Montgomery"] = { "Montgomery Union Station", ["Cardinal"] = wv, }, ["Montpelier"] = vt, ["Montreal"] = "Montreal Central Station", ["Montreal old"] = "[[Windsor Station (Montreal)|Montreal]]", ["Montreal West"] = "Montréal-Ouest station", ["Morris"] = mn, ["Mount Joy"] = pa, ["Mount Pleasant"] = ia, ["Mount Vernon"] = "Skagit Station", ["Munice"] = "Cincinnati, Richmond, & Muncie Depot (Muncie, Indiana)", ["Mystic"] = ct, ["Narberth"] = septa, ["Nashville"] = union, ["Natomas/Sacramento Airport"] = "[[Natomas/Sacramento Airport station|Natomas/​Sacramento Airport]]", ["Needles"] = "El Garces Intermodal Transportation Facility", ["New Buffalo (PM)"] = "[[New Buffalo station|New Buffalo (PM Depot)]]", ["New Haven"] = union, ["New London"] = xunion, ["New Orleans"] = "New Orleans Union Passenger Terminal", ["New York (Grand Central)"] = "Grand Central Terminal", ["New York"] = "New York Penn Station", ["New York City"] = "New York Penn Station", ["Newark Airport"] = "Newark Liberty International Airport Station", ["Newark, Delaware"] = "Newark station (Delaware)", ["Newark, New Jersey"] = "[[Newark Penn Station|Newark Penn]]", ["Newark, NJ"] = "[[Newark Penn Station|Newark Penn]]", ["Newark Penn"] = "[[Newark Penn Station|Newark Penn]]", ["Newbern"] = "Newbern Depot", ["Newport"] = ar, ["Newport News"] = { tc, ["Acela Regional"] = "Newport News station", ["Colonial"] = "Newport News station", ["Twilight Shoreliner"] = "Newport News station", ["George Washington"] = "Newport News station", ["James Whitcomb Riley"] = "Newport News station", ["James Whitcomb Riley and George Washington"] = "Newport News station", }, ["Newport News old"] = "[[Newport News station|Newport News]]", ["Newton"] = ks, ["Niagara Falls (former)"] = "[[Niagara Falls station (New York, 1978–2016)|Niagara Falls, New York]]", ["Niagara Falls, New York"] = "Niagara Falls station (New York)", ["Niagara Falls, Ontario"] = "Niagara Falls station (Ontario)", ["Norfolk"] = { amtrak, ["Mountaineer"] = "Lambert's Point#station", }, ["Normal"] = "Uptown Station", ["North Haven"] = ct, ["North Kingston"] = "Wickford Junction station", ["Northampton"] = "Union Station (Northampton, Massachusetts)", ["Oakland"] = { "Oakland–Jack London Square station", ["Shenandoah"] = md, ["West Virginian"] = md, }, ["Oakland – Jack London Square"] = "[[Oakland–Jack London Square station|Oakland–Jack London Square]]", ["Oakland 16th Street"] = "[[16th Street station (Oakland)|Oakland-16th Street]]", ["Oakley"] = ca, ["Oakville"] = go, ["Ocala"] = xunion, ["Oceanside"] = "Oceanside Transit Center", ["Ogden"] = "Union Station (Ogden, Utah)", ["Okeechobee"] = amtrak, ["Oklahoma City"] = "Santa Fe Depot (Oklahoma City)", ["Old Town San Diego"] = "[[Old Town Transit Center|San Diego–Old Town]]", ["San Diego–Old Town"] = "[[Old Town Transit Center|San Diego–Old Town]]", ["Olympia–Lacey"] = "Centennial Station", ["Omaha (CB&Q)"] = "[[Omaha station (Chicago, Burlington and Quincy Railroad)|Omaha (CB&Q Depot)]]", ["Ontario"] = { amtrak, ["Pioneer"] = ore, }, ["Orange"] = ca, ["Orlando"] = "Orlando Health/Amtrak station", ["Oxford"] = oh, ["Oxnard"] = "Oxnard Transit Center", ["Pajaro/Watsonville"] = "[[Pajaro/Watsonville station|Pajaro/​Watsonville]]", ["Pasadena"] = "Del Mar station", ["Pasco"] = "Pasco Intermodal Train Station", ["Pensacola"] = amtrak, ["Perry"] = ok, ["Petersburg (Union Station)"] = "[[Union Station (Petersburg)|Petersburg–Union Station]]", ["Philadelphia"] = "30th Street Station", ["Philadelphia-Suburban"] = "[[Suburban Station|Philadelphia-Suburban]]", ["Philadelphia International Airport"] = "Airport Terminal stations (SEPTA)", ["Phoenix"] = "Union Station (Phoenix, Arizona)", ["Pittsburgh"] = union, ["Pittsfield"] = "Joseph Scelsi Intermodal Transportation Center", ["Plano"] = il, ["Pocatello"] = "Union Pacific Railroad Depot (Pocatello, Idaho)", ["Pomona"] = { "[[Pomona–Downtown station|Pomona]]", ["Desert Wind"] = "Pomona–North station", ["Las Vegas Limited"] = "Pomona–North station", ["Southwest Chief"] = "Pomona–North station", ["Southwest Limited"] = "Pomona–North station", ["Super Chief"] = "Pomona–North station", }, ["Pontiac"] = { il, ["Lake Cities"] = tc, ["Wolverine"] = tc, ["Michigan"] = tc, }, ["Portland"] = { "Portland Union Station", ["Downeaster"] = tc, }, ["Princeton"] = il, ["Providence (Union Station)"] = "[[Union Station (Providence)|Providence–Union Station]]", ["Provo"] = amtrak, ["Pueblo"] = "Union Depot (Pueblo, Colorado)", ["Quincy"] = amtrak, ["Radnor"] = septarr, ["Raleigh"] = xunion, ["Randolph"] = vt, ["Rawlins"] = "Union Pacific Railroad Depot (Rawlins, Wyoming)", ["Redding"] = ca, ["Richmond"] = { ca, ["Cardinal"] = "Richmond station (Chesapeake and Ohio Railway)", ["James Whitcomb Riley"] = "Richmond station (Chesapeake and Ohio Railway)", ["Mountaineer"] = "Richmond station (Chesapeake and Ohio Railway)", ["National Limited"] = "Richmond Railroad Station Historic District", }, ["Richmond Main Street"] = "[[Richmond Main Street Station|Richmond–Main Street]]", ["Richmond-Broad Street"] = "[[Broad Street Station (Richmond)|Richmond–Broad Street]]", ["Riverbank"] = "[[Gold Runner|Riverbank]]", ["Riverside"] = "[[Riverside–Downtown station|Riverside]]", ["Rochester"] = "Louise M. Slaughter Rochester Station", ["Rome"] = ny, ["Rosemont"] = septa, ["Rosenberg"] = tx, ["Roseville"] = ca, ["Royal Oak"] = mi, ["Rugby"] = nd, ["Rye"] = mnrr, ["Saco"] = tc, ["Sacramento"] = "Sacramento Valley Station", ["City College"] = "City College station (Sacramento)", ["Sacramento City College"] = "[[City College station (Sacramento)|City College]]", ["Saint Paul"] = "Saint Paul Union Depot", ["Salem"] = ore, ["Salinas"] = "Salinas Intermodal Transportation Center", ["Salisbury"] = nc, ["Salt Lake City (D&RGW)"] = "[[Denver and Rio Grande Western Depot (Salt Lake City)|Salt Lake City (D&RGW Depot)]]", ["Salt Lake City (UP)"] = "[[Salt Lake City Union Pacific Depot|Salt Lake City (UP Depot)]]", ["Salt Lake City"] = "Salt Lake City Intermodal Hub", ["San Antonio"] = tx, ["San Antonio-Sunset"] = "[[San Antonio station (Texas)#Sunset Station|San Antonio-Sunset]]", ["San Bernardino"] = "San Bernardino Santa Fe Depot", ["San Clemente"] = "[[San Clemente Pier station|San Clemente]]", ["San Diego Old Town"] = "[[Old Town Transit Center|San Diego–Old Town]]", ["San Diego Sorrento Valley"] = "[[Sorrento Valley station|San Diego–Sorrento Valley]]", ["San Diego"] = "Santa Fe Depot (San Diego)", ["San Joaquin Street"] = "[[San Joaquin Street station|Stockton–San Joaquin Street]]", ["San Jose"] = "San Jose Diridon station", ["Sandwich"] = ma, ["Sanford (ACL)"] = "[[Sanford Atlantic Coast Line Station|Sanford (ACL Depot)]]", ["Sanford"] = amtrak, ["Santa Ana"] = "Santa Ana Regional Transportation Center", ["Santa Clara"] = "[[Santa Clara Transit Center|Santa Clara–University]]", ["Santa Clarita"] = "Newhall station", ["Savannah"] = amtrak, ["Seattle"] = "King Street Station", ["Selma"] = "Selma Union Depot", ["Shreveport"] = amtrak, ["Silver Spring"] = "Silver Spring station (Baltimore and Ohio Railroad)", ["Spokane"] = "Spokane Intermodal Center", ["Springfield"] = { "Springfield Union Station (Massachusetts)", ["Abraham Lincoln"] = il, ["Inter-American"] = il, ["Lincoln Service"] = il, ["Loop"] = il, ["Texas Eagle"] = il, }, ["St. Albans"] = vt, ["St. Louis (Union Station)"] = "[[St. Louis Union Station|St. Louis–Union Station]]", ["St. Louis"] = "Gateway Transportation Center", ["St. Marys"] = on, ["St. Paul"] = "Saint Paul Union Depot", ["St. Petersburg"] = amtrak, ["St. Thomas"] = "Canada Southern Railway Station", ["Stamford"] = tc, ["Stanley"] = nd, ["Stockton"] = "[[Robert J. Cabral Station|Stockton–Downtown]]", ["Stockton–Downtown"] = "[[Robert J. Cabral Station|Stockton–Downtown]]", ["Stockton–San Joaquin Street"] = "[[San Joaquin Street station|Stockton–San Joaquin Street]]", ["Stony Creek"] = ct, ["Stratford"] = on, ["Suburban Station"] = "[[Suburban Station|Philadelphia–Suburban]]", ["Suffolk"] = va, ["Summit"] = il, ["Superior"] = { "[[Superior Union Station|Superior]]", ["Northern Lights Express"] = "Superior, Wisconsin", }, ["Surf"] = "[[Lompoc–Surf station|Lompoc–Surf]]", ["Syracuse"] = "William F. Walsh Regional Transportation Center", ["Tacoma (Union Station)"] = "[[Union Station (Tacoma, Washington)|Tacoma–Union Station]]", ["Tacoma Dome"] = "Tacoma Dome Station", ["Tacoma"] = "[[Tacoma station (1984)|Tacoma]]", ["Tampa"] = xunion, ["Taunton"] = amtrak, ["Tempe"] = az, ["Temple"] = tx, ["Texarkana"] = xunion, ["Thomasville"] = "Thomasville Depot (Georgia)", ["Thompson"] = "Green River station (Utah)#History", ["Toledo"] = "Martin Luther King Jr. Plaza (Toledo)", ["Toronto"] = union, ["Trenton"] = "Trenton Transit Center", ["Tri-State"] = "Catlettsburg station", ["Trinidad"] = co, ["Troy"] = "Troy Transit Center", ["Utica"] = "Union Station (Utica, New York)", ["Vancouver, British Columbia"] = "Pacific Central Station", ["Vancouver, Washington"] = "Vancouver station (Washington)", ["Victorville"] = "Victor Valley Transportation Center", ["Wallingford"] = ct, ["Wareham"] = "Wareham Village station", ["Warren"] = il, ["Warsaw"] = ind, ["Washington, DC"] = "[[Washington Union Station|Washington, D.C.]]", ["Washington, D.C."] = "[[Washington Union Station|Washington, D.C.]]", ["Washington, Missouri"] = "[[Washington station (Missouri)|Washington]]", ["Waterbury"] = vt, ["Waterloo"] = ind, ["Wells"] = "Wells Regional Transportation Center", ["Wellesley"] = "Wellesley Square station", ["Wenatchee"] = "Columbia Station (Washington)", ["Westminster"] = "Downtown Westminster station", ["Westport"] = ny, ["Westwood"] = "[[Route 128 station|Westwood Route 128]]", ["Wheeler"] = ind, ["Whiting"] = "Whiting station (Pennsylvania Railroad)", ["Wichita"] = "Union Station (Wichita, Kansas)", ["Williamsburg"] = tc, ["Wilmington"] = de, ["Wilson"] = nc, ["Windsor"] = { ct, ["Niagara Rainbow"] = "Windsor station (Michigan Central Railroad)", ["Vermonter"] = vt, ["Wolverine"] = on, }, ["Winona"] = { "Winona station", ["City of New Orleans"] = ms, }, ["Winslow"] = az, ["Woburn"] = "Anderson Regional Transportation Center", ["Woodbridge"] = va, ["Woodstock"] = on, ["Worcester"] = "Union Station (Worcester, Massachusetts)", ["Youngstown"] = "Youngstown station (Baltimore and Ohio Railroad)", ["Ypsilanti"] = "Michigan Executive", ["Yuma"] = az, }, ["lines"] = { ["_default"] = { ["title"] = "''[[%1]]''", ["color"] = "00537E", }, ["Abraham Lincoln"] = { ["title"] = "''[[Abraham Lincoln (train)|Abraham Lincoln]]''", ["color"] = "0078B9", ["left terminus"] = "St. Louis (Union Station)", ["right terminus"] = "Chicago", }, ["Acela"] = { ["title"] = "''[[Acela]]''", ["color"] = "00B5E2", ["left terminus"] = "Washington, D.C.", ["right terminus"] = "Boston South", }, ["Acela Commuter"] = { ["title"] = "''[[Clocker (train)|Acela Commuter]]''", ["left terminus"] = "Philadelphia", ["right terminus"] = "New York," }, ["Acela Express"] = { ["title"] = "''[[Acela]]''", ["color"] = "00b5e2", ["left terminus"] = "Washington, D.C.", ["right terminus"] = "Boston South", }, ["Acela Regional"] = { ["title"] = "''[[Northeast Regional#History|Acela Regional]]''", ["left terminus"] = "Newport News", ["right terminus"] = "Boston South," }, ["Adirondack"] = { ["title"] = "''[[Adirondack (train)|Adirondack]]''", ["left terminus"] = "Montreal", ["right terminus"] = "New York", }, ["Ann Rutledge"] = { ["title"] = "''[[Ann Rutledge (train)|Ann Rutledge]]''", ["left terminus"] = "Kansas City", ["right terminus"] = "St. Louis", }, ["Arrowhead"] = { ["title"] = "''[[Arrowhead (train)|Arrowhead]]''", ["color"] = "0078B9", ["left terminus"] = "Duluth", ["right terminus"] = "Minneapolis", }, ["Atlantic City Express"] = { ["title"] = "''[[Atlantic City Express (Amtrak train)|Atlantic City Express]]''", ["color"] = "0078B9", ["left terminus"] = {"Richmond Staples Mill Road", "Harrisburg", "Springfield"}, ["right terminus"] = "Atlantic City", }, ["Auto Train"] = { ["left terminus"] = "Sanford", ["right terminus"] = "Lorton", }, ["Badger"] = { ["title"] = "''[[Hiawatha (Amtrak train)|Badger]]''", ["color"] = "0078B9", }, ["Bankers"] = { ["title"] = "''[[Bankers (train)|Bankers]]''", ["color"] = "0078B9", }, ["Bay State"] = { ["title"] = "''[[New Haven–Springfield Line|Bay State]]''", ["color"] = "0078B9", ["left terminus"] = "Philadelphia", ["right terminus"] = "Boston South", }, ["Beacon Hill"] = { ["title"] = "''[[Beacon Hill (train)|Beacon Hill]]''", ["color"] = "0078B9", ["left terminus"] = "New Haven", ["right terminus"] = "Boston South", }, ["Berkshire Flyer"] = { ["title"] = "''[[Berkshire Flyer]]''", ["left terminus"] = "Pittsfield", ["right terminus"] = "New York", }, ["Big Apple"] = { ["title"] = "''[[Keystone Service#Through service|Big Apple]]''", ["color"] = "0078B9", }, ["Black Hawk"] = { ["title"] = "''[[Black Hawk (Amtrak train)|Black Hawk]]''", ["left terminus"] = "Rockford", ["right terminus"] = "Chicago", }, ["Black Hawk (1974–1981)"] = { ["title"] = "''[[Black Hawk (Amtrak train)|Black Hawk]]''", ["color"] = "0078B9", ["left terminus"] = "Dubuque", ["right terminus"] = "Chicago", ["note-mid"] = "1974–1981", }, ["Blue Ridge"] = { ["title"] = "''[[Blue Ridge (train)|Blue Ridge]]''", ["color"] = "0078B9", ["left terminus"] = "Martinsburg", ["right terminus"] = "Washington, D.C.", ["note-mid"] = "1973–1986", }, ["Blue Water"] = { ["title"] = "''[[Blue Water (train)|Blue Water]]''", ["left terminus"] = "Chicago", ["right terminus"] = "Port Huron", }, ["Borealis"] = { ["title"] = "''[[Borealis (train)|Borealis]]''", ["left terminus"] = "St. Paul", ["right terminus"] = "Chicago", }, ["Broadway Limited"] = { ["color"] = "0078B9", ["left terminus"] = "Chicago", ["right terminus"] = "New York", }, ["California Zephyr"] = { ["left terminus"] = "Emeryville", ["right terminus"] = "Chicago", }, ["California Zephyr (1983–1994)"] = { ["title"] = "''[[California Zephyr]]''", ["color"] = "0078B9", ["left terminus"] = "Oakland 16th Street", ["right terminus"] = "Chicago", }, ["Calumet"] = { ["title"] = "''[[Calumet (train)|Calumet]]''", ["color"] = "0078B9", ["left terminus"] = "Chicago", ["right terminus"] = "Valparaiso", }, ["Campus"] = { ["title"] = "''[[Campus (train)|Campus]]''", ["color"] = "0078B9", ["left terminus"] = "Champaign-Urbana", ["right terminus"] = "Chicago (Central Station)", }, ["Cape Codder"] = { ["title"] = "''[[Cape Codder (train)|Cape Codder]]''", ["color"] = "0078B9", ["left terminus"] = "New York", ["right terminus"] = "Hyannis", }, ["Capitol Corridor"] = { ["color"] = "1C1B4D", ["left terminus"] = "San Jose", ["right terminus"] = "Auburn", }, ["Capitol Limited"] = { ["left terminus"] = "Chicago", ["right terminus"] = "Washington, D.C.", }, ["Capitols (1991–1998)"] = { ["title"] = "''[[Capitol Corridor|Capitols]]''", ["color"] = "FFC709", ["left terminus"] = "San Jose", ["right terminus"] = "Roseville", }, ["Cardinal"] = { ["title"] = "''[[Cardinal (train)|Cardinal]]''", ["left terminus"] = "Chicago", ["right terminus"] = "New York", }, ["Carolina Special"] = { ["title"] = "''[[Carolina Special (Amtrak train)|Carolina Special]]''", ["color"] = "0078B9", ["left terminus"] = "Jacksonville", ["right terminus"] = "New York", }, ["Carolinian"] = { ["title"] = "''[[Carolinian (train)|Carolinian]]''", ["left terminus"] = "Charlotte", ["right terminus"] = "New York", }, ["Cascades"] = { ["title"] = "[[Amtrak Cascades|Amtrak ''Cascades'']]", ["color"] = "223832", ["left terminus"] = "Eugene", ["right terminus"] = "Vancouver, British Columbia", }, ["Champion"] = { ["title"] = "''[[Champion (train)|Champion]]''", ["color"] = "0078B9", ["left terminus"] = "St. Petersburg", ["right terminus"] = "New York", }, ["Charter Oak"] = { ["title"] = "''[[Colonial (Amtrak train)|Charter Oak]]''", ["color"] = "0078B9", }, ["Chesapeake"] = { ["title"] = "''[[Chesapeake (train)|Chesapeake]]''", ["color"] = "0078B9", ["left terminus"] = "Washington, D.C.", ["right terminus"] = "Suburban Station", }, ["Chesapeake Virginia"] = { ["title"] = "''[[Colonial (Amtrak train)|Chesapeake]]''", ["color"] = "0078B9", }, ["Chief"] = { ["title"] = "''[[Chief (train)|Chief]]''", ["color"] = "0078B9", ["left terminus"] = "Los Angeles", ["right terminus"] = "Chicago", }, ["City of New Orleans"] = { ["title"] = "''[[City of New Orleans (train)|City of New Orleans]]''", ["left terminus"] = "New Orleans", ["right terminus"] = "Chicago", }, ["City of San Francisco"] = { ["title"] = "''[[City of San Francisco (train)|City of San Francisco]]''", ["color"] = "0078B9", ["left terminus"] = "Oakland 16th Street", ["right terminus"] = "Chicago", }, ["Clamdigger"] = { ["title"] = "''[[Clamdigger (train)|Clamdigger]]''", ["color"] = "0078B9", ["left terminus"] = "New Haven", ["right terminus"] = "New London", }, ["Clocker"] = { ["title"] = "''[[Clocker (train)|Clocker]]''", ["left terminus"] = "Philadelphia", ["right terminus"] = "New York," }, ["Coast Starlight"] = { ["left terminus"] = "Los Angeles", ["right terminus"] = "Seattle", }, ["CoCo"] = { ["title"] = "[[Colorado Connector]]", ["note-mid"] = "Opening 2029", ["color"] = "F26D3D", ["left terminus"] = "Denver Union Station", ["right terminus"] = "Fort Collins", ["types"] = { ["Pueblo"] = { ["title"] = "Phase II", ["note-mid"] = "Opening 2032", ["left terminus"] = "Pueblo", ["right terminus"] = "Fort Collins", }, }, }, ["Colonial"] = { ["title"] = "''[[Colonial (Amtrak train)|Colonial]]''", ["color"] = "0078B9", ["left terminus"] = "Newport News", ["right terminus"] = "Boston South", }, ["Colonial (PRR)"] = { ["title"] = "''[[Colonial (PRR train)|Colonial]]''", ["color"] = "0078B9", }, ["Connecticut Valley Service"] = { ["title"] = "''[[Amtrak Hartford Line|Connecticut Valley Service]]''", ["color"] = "0078B9", ["left terminus"] = "New Haven", ["right terminus"] = "Springfield", }, ["Crescent"] = { ["title"] = "''[[Crescent (train)|Crescent]]''", ["left terminus"] = "New Orleans", ["right terminus"] = "New York", }, ["Desert Wind"] = { ["color"] = "0078B9", ["left terminus"] = "Los Angeles", ["right terminus"] = "Chicago", }, ["Downeaster"] = { ["title"] = "''[[Downeaster (train)|Downeaster]]''", ["left terminus"] = "Boston North", ["right terminus"] = "Brunswick", }, ["Duquesne"] = { ["title"] = "''[[Pennsylvanian (train)|Duquesne]]''", ["color"] = "0078B9", }, ["Eagle"] = { ["title"] = "''[[Texas Eagle|Eagle]]''", ["color"] = "0078B9", }, ["El Capitan"] = { ["title"] = "''[[El Capitan (train)|El Capitan]]''", ["color"] = "0078B9", }, ["Empire Builder"] = { ["left terminus"] = {"Seattle", "Portland"}, ["right terminus"] = "Chicago", }, ["Empire Builder (1971-1981)"] = { ["title"] = "''[[Empire Builder]]''", ["color"] = "0078B9", ["left terminus"] = "Seattle", ["right terminus"] = "Chicago", }, ["Empire Service"] = { ["left terminus"] = "Niagara Falls, New York", ["right terminus"] = "New York", }, ["Encore"] = { ["title"] = "''[[Hiawatha Service|Encore]]''", ["color"] = "0078B9", }, ["Ethan Allen Express"] = { ["left terminus"] = "Burlington", ["right terminus"] = "New York", }, ["Executive Sleeper"] = { ["title"] = "''[[Night Owl (train)|Executive Sleeper]]''", ["color"] = "0078B9", }, ["Expo '74"] = { ["title"] = "''[[Expo '74 (train)|Expo '74]]''", ["color"] = "0078B9", ["left terminus"] = "Seattle", ["right terminus"] = "Spokane", }, ["Fast Mail"] = { ["title"] = "''[[Fast Mail (Amtrak train)|Fast Mail]]''", ["left terminus"] = "Washington, D.C.", ["right terminus"] = "Boston or Springfield", }, ["Federal"] = { ["title"] = "''[[Twilight Shoreliner|Federal]]''", ["color"] = "0078B9", ["left terminus"] = "Washington, D.C.", ["right terminus"] = "Boston South", }, ["Floridian"] = { ["title"] = "''[[Floridian (train)|Floridian]]''", ["left terminus"] = "Miami", ["right terminus"] = "Chicago", }, ["Floridian (1971–1979)"] = { ["title"] = "''[[Floridian (train, 1971–1979)|Floridian]]''", ["color"] = "0078B9", ["left terminus"] = {"St. Petersburg", "Miami"}, ["right terminus"] = "Chicago", ["types"] = { ["Miami"] = { ["title"] = "", ["left terminus"] = "Miami", ["right terminus"] = "Chicago", }, ["St. Petersburg"] = { ["title"] = "", ["left terminus"] = "St. Petersburg", ["right terminus"] = "Chicago", }, }, }, ["Florida Special"] = { ["title"] = "''[[Florida Special (train)|Florida Special]]''", ["color"] = "0078B9", }, ["Fort Pitt"] = { ["title"] = "''[[Fort Pitt (train)|Fort Pitt]]''", ["color"] = "0078B9", ["left terminus"] = "Pittsburgh", ["right terminus"] = "Altoona", }, ["George Washington"] = { ["title"] = "''[[George Washington (train)|George Washington]]''", ["color"] = "0078B9", ["left terminus"] = "Chicago", ["right terminus"] = {"Washington, D.C.", "Newport News"}, }, ["Gold Runner"] = { ["title"] = "''[[Gold Runner]]''", ["color"] = "0096CE", ["left terminus"] = {"Oakland", "Sacramento"}, ["right terminus"] = "Bakersfield", }, ["Gotham Limited"] = { ["title"] = "''[[Colonial (Amtrak train)|Gotham Limited]]''", ["color"] = "0078B9", }, ["Gulf Breeze"] = { ["title"] = "''[[Gulf Breeze (train)|Gulf Breeze]]''", ["color"] = "0078B9", ["left terminus"] = "Mobile", ["right terminus"] = "Birmingham", }, ["Gulf Coast Limited"] = { ["title"] = "''[[Gulf Coast Limited]]''", ["color"] = "0078B9", ["left terminus"] = "New Orleans", ["right terminus"] = "Mobile", }, ["Hartford"] = { ["title"] = "[[Amtrak Hartford Line|''Hartford Line'']]", ["left terminus"] = "New Haven", ["right terminus"] = "Springfield", }, ["Heartland Flyer"] = { ["left terminus"] = "Fort Worth", ["right terminus"] = "Oklahoma City", }, ["Hiawatha (1971-1977)"] = { ["title"] = "''[[Borealis (train)#History|Hiawatha]]''", ["color"] = "0078B9", }, ["Hiawatha"] = { ["title"] = "''[[Hiawatha (Amtrak train)|Hiawatha]]''", ["left terminus"] = "Milwaukee", ["right terminus"] = "Chicago", }, ["Hilltopper"] = { ["title"] = "''[[Hilltopper (train)|Hilltopper]]''", ["color"] = "0078B9", ["left terminus"] = "Tri-State", ["right terminus"] = "Boston South", }, ["Hoosier State"] = { ["title"] = "''[[Hoosier State (train)|Hoosier State]]''", ["left terminus"] = "Chicago", ["right terminus"] = "Indianapolis", }, ["Illini and Saluki"] = { ["title"] = "[[Illini and Saluki|''Illini'' and ''Saluki'']]", ["left terminus"] = "Carbondale", ["right terminus"] = "Chicago", }, ["Illini (Central)"] = { ["title"] = "[[Illini and Saluki|''Illini'']]", ["color"] = "0078B9", ["left terminus"] = "Champaign-Urbana", ["right terminus"] = "Chicago", }, ["Illinois Zephyr and Carl Sandburg"] = { ["title"] = "[[Illinois Zephyr and Carl Sandburg|''Illinois Zephyr'' and ''Carl Sandburg'']]", ["left terminus"] = "Quincy", ["right terminus"] = "Chicago", }, ["Illinois Zephyr old"] = { ["title"] = "[[Illinois Zephyr and Carl Sandburg|''Illinois Zephyr'']]", ["left terminus"] = "Quincy", ["right terminus"] = "Chicago", }, ["Inter-American"] = { ["title"] = "''[[Inter-American (train)|Inter-American]]''", ["color"] = "0078B9", ["left terminus"] = {"Laredo", "Houston"}, ["right terminus"] = "Chicago", }, ["International"] = { ["title"] = "''[[International (Amtrak train)|International]]''", ["left terminus"] = "Chicago", ["right terminus"] = "Toronto", }, ["International (1982–1990)"] = { ["title"] = "''[[International (Amtrak train)|International]]''", ["color"] = "0078B9", ["left terminus"] = "Chicago", ["right terminus"] = "Toronto", }, ["James River"] = { ["title"] = "''[[Colonial (Amtrak train)|James River]]''", ["color"] = "0078B9", }, ["James Whitcomb Riley"] = { ["title"] = "''[[James Whitcomb Riley (train)|James Whitcomb Riley]]''", ["color"] = "0078B9", ["left terminus"] = "Chicago", ["right terminus"] = {"Washington, D.C.", "Newport News"}, }, ["James Whitcomb Riley and George Washington"] = { ["title"] = "''[[James Whitcomb Riley (train)|James Whitcomb Riley]] and [[George Washington (train)|George Washington]]''", ["color"] = "0078B9", ["left terminus"] = "Chicago", ["right terminus"] = {"Washington, D.C.", "Newport News"}, }, ["Kentucky Cardinal"] = { ["left terminus"] = "Chicago", ["right terminus"] = "Louisville", }, ["Keystone"] = { ["title"] = "''[[Pennsylvanian (train)#History|Keystone]]''", ["color"] = "0078B9", ["left terminus"] = "Pittsburgh", ["right terminus"] = "New York", }, ["Keystone (1971-1972)"] = { ["title"] = "''[[Pennsylvanian (train)|Keystone]]''", ["color"] = "0078B9", }, ["Keystone Executive"] = { ["title"] = "''[[Keystone Service#Declining service|Keystone Executive]]''", ["color"] = "0078B9", }, ["Keystone Service"] = { ["left terminus"] = "Harrisburg", ["right terminus"] = "New York", }, ["Keystone State Express"] = { ["title"] = "''[[Keystone Service#Through service|Keystone State Express]]''", ["color"] = "0078B9", }, ["Lake Cities"] = { ["title"] = "''[[Lake Cities (Amtrak train)|Lake Cities]]''", ["left terminus"] = "Chicago", ["right terminus"] = "Pontiac", }, ["Lake Cities (1980–1995)"] = { ["title"] = "''[[Lake Cities (Amtrak train)|Lake Cities]]''", ["color"] = "0078B9", ["left terminus"] = "Chicago", ["right terminus"] = "Toledo", }, ["Lake Country Limited"] = { ["left terminus"] = "Janesville", ["right terminus"] = "Chicago", }, ["Lake Shore"] = { ["title"] = "''[[Lake Shore Limited#Lake Shore|Lake Shore]]''", ["color"] = "0078B9", ["left terminus"] = "Chicago", ["right terminus"] = "New York (Grand Central)", }, ["Lake Shore Limited"] = { ["left terminus"] = "Chicago", ["right terminus"] = {"New York", "Boston South"}, }, ["LaSalle"] = { ["title"] = "''[[Hiawatha (Amtrak train)|LaSalle]]''", ["color"] = "0078B9", }, ["Las Vegas Limited"] = { ["color"] = "0078B9", ["left terminus"] = "Los Angeles", ["right terminus"] = "Las Vegas", }, ["Loop"] = { ["title"] = "''[[Loop (Amtrak train)|Loop]]''", ["color"] = "0078B9", ["left terminus"] = "Springfield", ["right terminus"] = "Chicago", }, ["Limited"] = { ["title"] = "''[[Alton Limited|Limited]]''", ["color"] = "0078B9", }, ["Lincoln Service"] = { ["left terminus"] = "St. Louis", ["right terminus"] = "Chicago", }, ["Lone Star"] = { ["title"] = "''[[Lone Star (Amtrak train)|Lone Star]]''", ["color"] = "0078B9", ["left terminus"] = {"Dallas", "Houston"}, ["right terminus"] = "Chicago", }, ["Manhattan Express"] = { ["title"] = "''[[Colonial (Amtrak train)|Manhattan Express]]''", ["color"] = "0078B9", }, ["Mardi Gras Service"] = { ["title"] = "''[[Mardi Gras Service]]''", ["left terminus"] = "New Orleans", ["right terminus"] = "Mobile", }, ["Maple Leaf"] = { ["title"] = "''[[Maple Leaf (train)|Maple Leaf]]''", ["left terminus"] = "Toronto", ["right terminus"] = "New York", }, ["Marquette"] = { ["title"] = "''[[Hiawatha (Amtrak train)|Marquette]]''", ["color"] = "0078B9", }, ["Merchants"] = { ["title"] = "''[[Merchants Limited|Merchants]]''", ["color"] = "0078B9", }, ["Merchants Limited"] = { ["title"] = "''[[Merchants Limited]]''", ["color"] = "0078B9", }, ["Meteor"] = { ["title"] = "''[[Champion (train)#Amtrak|Meteor]]''", ["color"] = "0078B9", ["left terminus"] = {"St. Petersburg", "Miami"}, ["right terminus"] = "Boston South", }, ["Metroliner"] = { ["title"] = "''[[Metroliner (train)|Metroliner]]''", ["left terminus"] = "Washington, D.C.", ["right terminus"] = "New York", }, ["Miamian"] = { ["title"] = "''[[Vacationer (train)|Miamian]]''", ["color"] = "0078B9", }, ["Michigan Executive"] = { ["color"] = "0078B9", ["left terminus"] = "Jackson", ["right terminus"] = "Detroit (MC)", }, ["Missouri River Runner"] = { ["left terminus"] = "Kansas City", ["right terminus"] = "St. Louis", }, ["Montrealer"] = { ["title"] = "''[[Montrealer (train)|Montrealer]]''", ["color"] = "0078B9", ["left terminus"] = "Washington, D.C.", ["right terminus"] = "Montreal", }, ["Mount Rainier"] = { ["title"] = "''[[Amtrak Cascades#History|Mount Rainier]]''", ["color"] = "0078B9", ["left terminus"] = "Eugene", ["right terminus"] = "Seattle", }, ["Mountaineer"] = { ["title"] = "''[[Mountaineer (Amtrak train)|Mountaineer]]''", ["color"] = "0078B9", ["left terminus"] = "Chicago", ["right terminus"] = "Norfolk", }, ["Mountain Rail"] = { ["title"] = "''[[Winter Park Express#Future plans|Mountain Rail]]''", ["left terminus"] = "Craig", ["right terminus"] = "Denver", }, ["National Limited"] = { ["title"] = "''[[National Limited (Amtrak train)|National Limited]]''", ["color"] = "0078B9", ["left terminus"] = "Kansas City", ["right terminus"] = {"New York", "Washington, D.C."}, }, ["New England Express"] = { ["title"] = "''[[Colonial (Amtrak train)|New England Express]]''", ["color"] = "0078B9", }, ["New Orleans–Baton Rouge passenger rail"] = { ["title"] = "[[New Orleans–Baton Rouge passenger rail|New Orleans–Baton Rouge]]", ["left terminus"] = "Baton Rouge", ["right terminus"] = "New Orleans", }, ["Niagara Rainbow"] = { ["color"] = "0078B9", ["left terminus"] = "Detroit (MC)", ["right terminus"] = "New York (Grand Central)", }, ["Nicollet"] = { ["title"] = "''[[Hiawatha (Amtrak train)|Nicollet]]''", ["color"] = "0078B9", }, ["Night Owl"] = { ["title"] = "''[[Night Owl (train)|Night Owl]]''", ["color"] = "0078B9", ["left terminus"] = "Washington, D.C.", ["right terminus"] = "Boston South", }, ["North Coast Hiawatha"] = { ["color"] = "0078B9", ["left terminus"] = "Seattle", ["right terminus"] = "Chicago", }, ["Northern Lights Express"] = { ["color"] = "78BE21", ["left terminus"] = "Duluth", ["right terminus"] = "Minneapolis Target Field", }, ["North Star"] = { ["title"] = "''[[North Star (Amtrak train)|North Star]]''", ["color"] = "0078B9", ["left terminus"] = "Duluth", ["right terminus"] = {"Chicago", "Midway"}, }, ["Northeast Corridor"] = { ["title"] = "[[Northeast Corridor]]", ["color"] = "0078B9", ["left terminus"] = "Washington, D.C.", ["right terminus"] = "Boston South", }, ["Northeast Regional"] = { ["left terminus"] = {"Norfolk", "Newport News", "Roanoke"}, ["right terminus"] = {"Boston South", "Springfield"}, ["types"] = { ["Newport News or Roanoke"] = { ["title"] = "", ["left terminus"] = {"Newport News", "Roanoke"}, ["right terminus"] = {"Boston South", "Springfield"}, }, ["Norfolk or Newport News"] = { ["title"] = "", ["left terminus"] = {"Norfolk", "Newport News"}, ["right terminus"] = {"Boston South", "Springfield"}, }, ["Norfolk or Roanoke"] = { ["title"] = "", ["left terminus"] = {"Norfolk", "Roanoke"}, ["right terminus"] = {"Boston South", "Springfield"}, }, }, }, ["Old Dominion"] = { ["title"] = "''[[Colonial (Amtrak train)|Old Dominion]]''", ["color"] = "0078B9", }, ["Orange County Commuter"] = { ["title"] = "''[[Orange County Line|Orange County Commuter]]''", ["color"] = "0078B9", ["left terminus"] = "Los Angeles", ["right terminus"] = "San Juan Capistrano", }, ["Pacific International"] = { ["title"] = "''[[Pacific International]]''", ["color"] = "0078B9", ["left terminus"] = "Seattle", ["right terminus"] = "Vancouver, British Columbia", }, ["Pacific Surfliner"] = { ["color"] = "003C5B", ["left terminus"] = "San Luis Obispo", ["right terminus"] = "San Diego", }, ["Palmetto"] = { ["title"] = "''[[Palmetto (train)|Palmetto]]''", ["left terminus"] = "Savannah", ["right terminus"] = "New York", }, ["Panama Limited"] = { ["title"] = "''[[Panama Limited]]''", ["color"] = "0078B9", ["left terminus"] = "New Orleans", ["right terminus"] = "Chicago (Central Station)", }, ["Pennsylvanian"] = { ["title"] = "''[[Pennsylvanian (train)|Pennsylvanian]]''", ["left terminus"] = "Pittsburgh", ["right terminus"] = "New York", }, ["Pere Marquette"] = { ["title"] = "''[[Pere Marquette (Amtrak train)|Pere Marquette]]''", ["left terminus"] = "Chicago", ["right terminus"] = "Grand Rapids", }, ["Piedmont"] = { ["title"] = "''[[Piedmont (train)|Piedmont]]''", ["left terminus"] = "Charlotte", ["right terminus"] = "Raleigh", }, ["Pioneer"] = { ["title"] = "''[[Pioneer (train)|Pioneer]]''", ["color"] = "0078B9", ["left terminus"] = "Seattle", ["right terminus"] = "Chicago", }, ["Potomac"] = { ["title"] = "''[[Colonial (Amtrak train)|Potomac]]''", ["color"] = "0078B9", }, ["Prairie Marksman"] = { ["title"] = "''[[Prairie Marksman]]''", ["left terminus"] = "East Peoria", ["right terminus"] = "Chicago", ["color"] = "0078B9", }, ["Prairie State"] = { ["title"] = "''[[Prairie State (Amtrak)|Prairie State]]''", ["color"] = "0078B9", }, ["Quad Cities"] = { ["title"] = "''[[Quad Cities (train)|Quad Cities]]''", ["left terminus"] = "Moline", ["right terminus"] = "Chicago", ["note-mid"] = "Proposed", }, ["Radisson"] = { ["title"] = "''[[Hiawatha (Amtrak train)|Radisson]]''", ["color"] = "0078B9", }, ["River Cities"] = { ["title"] = "''[[River Cities (train)|River Cities]]''", ["color"] = "0078B9", ["left terminus"] = "New Orleans", ["right terminus"] = "Kansas City", }, ["San Diegan"] = { ["title"] = "''[[San Diegan (train)|San Diegan]]''", ["color"] = "0078B9", ["left terminus"] = "Los Angeles", ["right terminus"] = "San Diego", }, ["San Francisco Zephyr"] = { ["color"] = "0078B9", ["left terminus"] = "Oakland 16th Street", ["right terminus"] = "Chicago", }, ["San Joaquin (1974–1994)"] = { ["title"] = "''[[Gold Runner#History|San Joaquins]]''", ["color"] = "0078B9", ["left terminus"] = "Oakland 16th Street", ["right terminus"] = "Bakersfield", }, ["San Joaquin (1994–1996)"] = { ["title"] = "''[[Gold Runner#History|San Joaquins]]''", ["color"] = "FFC709", ["left terminus"] = "Emeryville", ["right terminus"] = "Bakersfield", }, ["San Joaquin (1996–2002)"] = { ["title"] = "''[[Gold Runner#History|San Joaquins]]''", ["color"] = "FFC709", ["left terminus"] = "Oakland", ["right terminus"] = "Bakersfield", }, ["San Joaquins (1999–2025)"] = { ["title"] = "''[[Gold Runner#History|San Joaquins]]''", ["color"] = "1EB1D2", ["left terminus"] = {"Oakland", "Sacramento"}, ["right terminus"] = "Bakersfield", }, ["Shawnee"] = { ["title"] = "''[[Shawnee (train)|Shawnee]]''", ["color"] = "0078B9", ["left terminus"] = "Carbondale", ["right terminus"] = "Chicago", }, ["Shenandoah"] = { ["title"] = "''[[Shenandoah (Amtrak train)|Shenandoah]]''", ["color"] = "0078B9", ["left terminus"] = "Cincinnati River Road", ["right terminus"] = "Washington, D.C.", }, ["Silver Meteor"] = { ["left terminus"] = "Miami", ["right terminus"] = "New York", }, ["Silver Palm (1982–1985)"] = { ["title"] = "''[[Silver Palm (train)|Silver Palm]]''", ["color"] = "0078B9", ["left terminus"] = "Miami", ["right terminus"] = "Tampa", }, ["Silver Palm (1996–2002)"] = { ["title"] = "''[[Palmetto (train)#History|Silver Palm]]''", ["left terminus"] = "Miami", ["right terminus"] = "New York", }, ["Silver Star"] = { ["title"] = "''[[Silver Star (Amtrak train)|Silver Star]]''", ["left terminus"] = "Miami", ["right terminus"] = "New York", }, ["Silverliner Service"] = { ["color"] = "0078B9", ["left terminus"] = "Harrisburg", ["right terminus"] = "Suburban Station", }, ["Southwest Chief"] = { ["left terminus"] = "Los Angeles", ["right terminus"] = "Chicago", }, ["Southwest Limited"] = { ["title"] = "''[[Southwest Chief|Southwest Limited]]''", ["color"] = "0078B9", ["left terminus"] = "Los Angeles", ["right terminus"] = "Chicago", }, ["South Wind"] = { ["title"] = "''[[South Wind (train)|South Wind]]''", ["color"] = "0078B9", }, ["Spirit of California"] = { ["color"] = "0078B9", ["left terminus"] = "Los Angeles", ["right terminus"] = "Sacramento", }, ["Spirit of St. Louis"] = { ["title"] = "''[[Spirit of St. Louis (train)|Spirit of St. Louis]]''", ["color"] = "0078B9", }, ["State House"] = { ["title"] = "''[[State House (train)|State House]]''", ["left terminus"] = "St. Louis", ["right terminus"] = "Chicago", }, ["St. Clair"] = { ["title"] = "''[[Lake Cities (Amtrak train)|St. Clair]]''", ["color"] = "0078B9", }, ["Sunset Limited"] = { ["left terminus"] = "Los Angeles", ["right terminus"] = "New Orleans", ["types"] = { ["East"] = { ["title"] = "", ["left terminus"] = "Los Angeles", ["right terminus"] = {"Orlando", "Miami"}, }, }, }, ["Super Chief"] = { ["color"] = "0078B9", ["left terminus"] = "Los Angeles", ["right terminus"] = "Chicago", }, ["Super Chief/El Capitan"] = { ["title"] = "''[[Super Chief]]''/​''[[El Capitan (train)|El Capitan]]''", ["color"] = "0078B9", }, ["Susquehanna"] = { ["title"] = "''[[Keystone Service#Through service|Susquehanna]]''", ["color"] = "0078B9", }, ["Texas Eagle"] = { ["left terminus"] = {"Los Angeles", "San Antonio"}, ["right terminus"] = "Chicago", }, ["Three Rivers"] = { ["title"] = "''[[Three Rivers (train)|Three Rivers]]''", ["left terminus"] = "Chicago", ["right terminus"] = "New York", }, ["Tidewater"] = { ["title"] = "''[[Colonial (Amtrak train)|Tidewater]]''", ["color"] = "0078B9", }, ["Tidewater Express"] = { ["title"] = "''[[Colonial (Amtrak train)|Tidewater Express]]''", ["color"] = "0078B9", }, ["Turboliner"] = { ["title"] = "''[[Turboliner#Service|Turboliner]]''", ["color"] = "0078B9", }, ["Twilight Limited"] = { ["left terminus"] = "Chicago", ["right terminus"] = "Pontiac", }, ["Twilight Shoreliner"] = { ["title"] = "''[[Twilight Shoreliner]]''", ["color"] = "0078B9", ["left terminus"] = "Newport News", ["right terminus"] = "Boston South", }, ["Twin Cities Hiawatha"] = { ["title"] = "''[[Borealis (train)#History|Twin Cities Hiawatha]]''", ["color"] = "0078B9", ["left terminus"] = {"Minneapolis", "Midway"}, ["right terminus"] = "Chicago", }, ["Vacationer"] = { ["title"] = "''[[Vacationer (train)|Vacationer]]''", ["color"] = "0078B9", ["left terminus"] = "Miami", ["right terminus"] = "New York", }, ["Valley Forge"] = { ["title"] = "''[[Keystone Service#Through service|Valley Forge]]''", ["color"] = "0078B9", ["left terminus"] = "Harrisburg", ["right terminus"] = "New York", ["types"] = { ["weekends only"] = { ["title"] = "1974-1975, weekends only", ["right terminus"] = "Boston South", }, }, }, ["Valley Flyer"] = { ["title"] = "''[[Valley Flyer]]''", ["left terminus"] = "New Haven", ["right terminus"] = "Greenfield", }, ["Vermonter"] = { ["title"] = "''[[Vermonter (train)|Vermonter]]''", ["left terminus"] = "Washington, D.C.", ["right terminus"] = "St. Albans", }, ["Virginian"] = { ["title"] = "''[[Colonial (Amtrak train)|Virginian]]''", ["color"] = "0078B9", }, ["Washington Executive"] = { ["title"] = "''[[Night Owl (train)|Washington Executive]]''", ["color"] = "0078B9", }, ["Weekender"] = { ["title"] = "''[[Lincoln Service|Weekender]]''", ["color"] = "0078B9", }, ["Weekend Metroliner"] = { ["title"] = "''[[Metroliner (train)|Weekend Metroliner]]''", ["color"] = "0078B9", }, ["West Virginian"] = { ["title"] = "''[[West Virginian (Amtrak train)|West Virginian]]''", ["color"] = "0078B9", ["left terminus"] = "Parkersburg", ["right terminus"] = "Washington, D.C.", ["note-mid"] = "1971–1973", }, ["Willamette Valley"] = { ["title"] = "''[[Willamette Valley (train)|Willamette Valley]]''", ["color"] = "0078B9", ["left terminus"] = "Eugene", ["right terminus"] = "Portland", }, ["Winter Park Express"] = { ["left terminus"] = "Fraser–Winter Park", ["right terminus"] = "Denver", }, ["Wolverine"] = { ["title"] = "''[[Wolverine (train)|Wolverine]]''", ["left terminus"] = "Chicago", ["right terminus"] = "Pontiac", }, -- For generic system display on station layouts using rail color box ["Amtrak"] = { ["title"] = "[[Amtrak]]", }, }, ["aliases"] = { ["amtrak cascades"] = "Cascades", ["amtrak hartford line"] ="Hartford", ["carl sandburg"] = "Illinois Zephyr and Carl Sandburg", ["carl sandburg/illinois zephyr"] = "Illinois Zephyr and Carl Sandburg", ["hartford line"] ="Hartford", ["hiawatha service"] = "Hiawatha", ["hiawatha (1971-1974)"] = "Hiawatha (1971-1977)", ["illini"] = "Illini and Saluki", ["illini/saluki"] = "Illini and Saluki", ["illinois zephyr"] = "Illinois Zephyr and Carl Sandburg", ["illinois zephyr/carl sandburg"] = "Illinois Zephyr and Carl Sandburg", ["international limited"] = "International", ["international (1982-1990)"] = "International (1982–1990)", ["new haven–springfield shuttle"] = "Hartford", ["new haven-springfield shuttle"] = "Hartford", ["regional"] = "Northeast Regional", ["saluki"] = "Illini and Saluki", ["saluki/illini"] = "Illini and Saluki", ["san joaquin"] = "Gold Runner", ["san joaquins"] = "Gold Runner", ["shuttle"] = "Hartford Line", ["black hawk (1974-1981)"] = "Black Hawk (1974–1981)", ["california zephyr (1983-1994)"] = "California Zephyr (1983–1994)", ["capitols (1991-1998)"] = "Capitols (1991–1998)", ["lake cities (1980-1995)"] = "Lake Cities (1980–1995)", ["san joaquin (1974-1994)"] = "San Joaquin (1974–1994)", ["san joaquin (1994-1996)"] = "San Joaquin (1994–1996)", ["san joaquin (1996-2002)"] = "San Joaquin (1996–2002)", ["silver palm (1982-1985)"] = "Silver Palm (1982–1985)", ["silver palm (1996-2002)"] = "Silver Palm (1996–2002)", ["northern lights express"] = "Northern Lights Express", ["baton rouge"] = "New Orleans–Baton Rouge passenger rail", ["great river"] = "Borealis", ["tcmc"] = "Borealis", }, } return p qec8xb0tqhp94u8nj5282zloiklk3sd Module:Adjacent stations 828 52463 308429 2026-09-17T16:03:57Z Isma4l 41797 Bog cusub: require('strict') local p = {} local lang = 'en-GB' -- local default language -- Below these comments: Internationalization table -- How to translate this module (for languages without variants): -- • Characters inside single and double quotation marks are called strings. -- The strings in this i18n table are used as output. -- • Strings within square brackets are keys. -- • Strings are concatenated (joined) with two dots. -- • Set the string after «local lang =» t... 308429 Scribunto text/plain require('strict') local p = {} local lang = 'en-GB' -- local default language -- Below these comments: Internationalization table -- How to translate this module (for languages without variants): -- • Characters inside single and double quotation marks are called strings. -- The strings in this i18n table are used as output. -- • Strings within square brackets are keys. -- • Strings are concatenated (joined) with two dots. -- • Set the string after «local lang =» to your language's code. -- Change the first key after "i18n" (usually "en-GB") to the same thing. -- • For each string which is not inside a function, translate it directly. -- • Strings with keys named "format" are Lua regular expressions. -- «()» is a match; «.+» means all characters; «%s+» means all spaces. -- • For each string which is concatenated to the variable «var», -- translate the phrase assuming that «var» will be a noun. -- • Remove any unnecessary translations. local i18n = require("Module:Adjacent stations/i18n") local function getData(system, verify) if verify then local title = mw.title.new('Module:Adjacent stations/' .. system -- .. '/sandbox' ) if not (title and title.exists) then return nil end end return require('Module:Adjacent stations/' .. system -- .. '/sandbox' ) end local function getLine(data, lineN) if lineN then if data['aliases'] then lineN = data['aliases'][mw.ustring.lower(lineN)] or lineN end local default = data['lines']['_default'] or {} local line = data['lines'][lineN] or {} for k, v in pairs(default) do if v then line[k] = line[k] or v end end line['title'] = line['title'] and mw.ustring.gsub(line['title'], '%%1', lineN) return line, lineN end end local function getColor(data, system, line, Type, frame) if system then if line then return frame:expandTemplate{ title = system .. ' color', args = {line, ['branch'] = Type} } end return frame:expandTemplate{ title = system .. ' color' } else line = (getLine(data, line)) local default = data['lines']['_default'] if line or default then default = default or {} if not line then line = mw.clone(default) end local color = line['color'] or line['background color'] or default['color'] or default['background color'] or data['system color'] local Type_value = Type and line['types'] and (line['types'][Type] and line['types'][Type]['color']) if Type_value then color = Type_value end return color end return (default and (default['color'] or default['background color']) or data['system color'] or '') end end local lineN, typeN local function somethingMissing(name, key, formats) local formatKeys = {} for k in pairs(formats) do table.insert(formatKeys, k) end return name .. ' was "' .. key .. '" but neither an entry for it nor a default was found. Choices were: ' .. table.concat(formatKeys, ', ') end local function getStation(station, _Format) if type(_Format) == 'table' then local lineNformats = _Format _Format = lineNformats[lineN] or lineNformats[1] if not _Format then error(somethingMissing('lineN', lineN, lineNformats)) elseif type(_Format) == 'table' then local typeNformats = _Format _Format = typeNformats[typeN] or typeNformats[1] if not _Format then error(somethingMissing('typeN', typeN, typeNformats)) end end end if typeN then _Format = mw.ustring.gsub(_Format, '%%3', typeN) end if lineN then _Format = mw.ustring.gsub(_Format, '%%2', lineN) end return (mw.ustring.match(_Format, '%[%[.+%]%]')) and (mw.ustring.gsub(_Format, '%%1', station)) or table.concat({'[[', mw.ustring.gsub(_Format, '%%1', station), '|', station, ']]'}) end local function getTerminusText(var, Format) local function subst(var1, var2) -- var1 is the terminus or table of termini; var2 is the key for the table of termini return type(var1) == 'string' and getStation(var1, (Format[var1] or Format[1])) or type(var1) == 'table' and #var1 > 0 and getStation(var1[var2], (Format[var1[var2]] or Format[1])) or '' end if Format then if type(var) == 'string' then return subst(var) elseif type(var) == 'table' and #var > 0 then local t = {subst(var, 1)} for i = 2, #var - 1 do t[i] = i18n[lang]['comma'](subst(var, i)) end if #var > 1 then t[#var] = i18n[lang]['or'](subst(var, #var)) end if var['via'] then if i18n[lang]['via-first'] then table.insert(t, 1, i18n[lang]['via'](subst(var, 'via'))) else table.insert(t, i18n[lang]['via'](subst(var, 'via'))) end end return table.concat(t) else return '' end else return var or '' end end function p._main(_args) -- Arguments are processed here instead of the main function local yesno = require('Module:Yesno') local trimq = require('Module:Trim quotes')._trim local boolean = { ['oneway-left'] = true, ['oneway-right'] = true, ['reverse'] = true, ['reverse-left'] = true, ['reverse-right'] = true } local args = {} -- Processed arguments local index = {} -- A list of addresses corresponding to number suffixes in the arguments for k, v in pairs(_args) do -- Maps each raw argument to processed arguments by string matching _args[k] = v:match('^%s*(.-)%s*$') if _args[k] and _args[k] ~= '' then local a = mw.ustring.match(k, '^(.*%D)%d+$') or k -- The parameter; address 1 can be omitted local b = tonumber(mw.ustring.match(k, '^.*%D(%d+)$')) or 1 -- The address for a given argument; address 1 can be omitted if boolean[a] then v = yesno(v) end if not args[b] then args[b] = {[a] = v} table.insert(index, b) elseif args[b][a] then return error(i18n[lang]['error_duplicate'](a .. b)) else args[b][a] = v end end end table.sort(index) local function small(s, italic) return italic and '<div class="isA">' .. s .. '</div>' or '<div class="smA">' .. s .. '</div>' end local style = { -- Style for each cell type ['header cell'] = 'class="hcA"|', ['header midcell'] = 'colspan="3" class="hmA"|', ['body cell'] = 'class="bcA"|', ['body banner'] = 'class="bbA notheme" style="color:inherit;background-color:#', } local function rgb(var) if var:len() == 3 then return {tonumber(var:sub(1, 1), 16) * 17, tonumber(var:sub(2, 2), 16) * 17, tonumber(var:sub(2, 2), 16) * 17} elseif var:len() == 6 then return {tonumber(var:sub(1, 2), 16), tonumber(var:sub(3, 4), 16), tonumber(var:sub(5, 6), 16)} end return {} end local data = {} -- A table of data modules for each address local noclearclass = (((_args.noclear or '') ~= '') and ' adjacent-stations-noclear' or '') local wikitable = {'{| class="wikitable adjacent-stations' .. noclearclass .. '"'} for i, v in ipairs(index) do -- If an address has a system argument, indexes the data module data[v] = args[v]['system'] and getData(args[v]['system']) -- If an address has no system, the row uses data from the previous address or data[index[i - 1]] or (args[v]['header'] and getData(args[index[i+1]]['system'])) or error(i18n[lang]['error_unknown'](args[v]['system'])) local lang = data[v]['lang'] or lang if args[v]['system'] and not args[v]['hide-system'] then -- Header row local stop_noun = data[v]['header stop noun'] or i18n[lang]['stop_noun'] table.insert(wikitable, table.concat({'\n|-', '\n! scope="col" ', style['header cell'], i18n[lang]['preceding'](stop_noun), '\n! scope="col" ', style['header midcell'], (data[v]['system icon'] and data[v]['system icon'] .. ' ' or ''), (data[v]['system title'] or ('[['.. args[v]['system'] ..']]')), '\n! scope="col" ', style['header cell'], i18n[lang]['following'](stop_noun) })) table.insert(wikitable, '') table.insert(wikitable, '') table.insert(wikitable, '') end if args[v]['header'] then -- Subheader table.insert(wikitable, '\n|-\n!colspan="5" class="hmA"|'.. args[v]['header']) table.insert(wikitable, '') table.insert(wikitable, '') table.insert(wikitable, '') end if args[v]['line'] or args[v]['left'] or args[v]['right'] or args[v]['nonstop'] then if not args[v]['line'] and i > 1 and not args[v]['system'] then args[v]['line'] = args[index[i - 1]]['line'] end lineN = args[v]['line'] or '_default' typeN = args[v]['type'] if data[v]['aliases'] then lineN = data[v]['aliases'][mw.ustring.lower(lineN)] or lineN if typeN then typeN = data[v]['aliases'][mw.ustring.lower(typeN)] or typeN end end -- get the line table local line = data[v]['lines'] and (mw.clone(data[v]['lines'][lineN]) or error(i18n[lang]['error_unknown'](args[v]['line']))) or error(i18n[lang]['error_line']) local default = data[v]['lines']['_default'] or {} line['title'] = line['title'] or default['title'] or '' line['title'] = mw.ustring.gsub(line['title'], '%%1', lineN) -- cell across row for non-stop service if args[v]['nonstop'] then table.insert(wikitable, table.concat({'\n|-\n|colspan="5" ', style['body cell'], ((args[v]['nonstop'] == 'former') and i18n[lang]['nonstop_past'] or i18n[lang]['nonstop_present'])(p._box({data = data[v], line = lineN, Type = typeN, inline = 'yes'})) }) ) table.insert(wikitable, '') table.insert(wikitable, '') table.insert(wikitable, '') else local Format = data[v]['station format'] or i18n[lang]['error_format'] local color, color_2, background_color, circular local Type = line['types'] and line['types'][typeN] -- get the line type table if Type then if Type['color'] then -- line color is used as background if there is no background color in the line type table background_color = Type['background color'] or line['color'] color = Type['color'] color_2 = Type['color2'] or color else background_color = Type['background color'] or line['background color'] color = line['color'] or default['color'] or '' color_2 = line['color2'] or color end if Type['circular'] then -- Type may override the circular status of the line circular = Type['circular'] end else background_color = line['background color'] color = line['color'] or default['color'] or '' color_2 = line['color2'] or color circular = line['circular'] end -- Alternate termini can be specified based on type local sideCell = {true, true} for i, b in ipairs({'left', 'right'}) do if not args[v][b] then -- If no station is given on one side, the station is assumed to be the terminus on that side local _through = args[v]['through-' .. b] or args[v]['through'] local _through_data = getLine(data[v], _through) if _through_data then _through = _through_data['title'] or _through end sideCell[i] = _through and "''" .. i18n[lang]['through'](trimq(_through)) .. "''" or "''" .. trimq((args[v]['reverse-' .. b] or args[v]['reverse']) and i18n[lang]['reverse'] or i18n[lang]['terminus']) .. "''" else local terminusT local terminusN = Type and Type[b .. ' terminus'] or line[b .. ' terminus'] -- If the terminus table has more than one numbered key or has the via key then the table shows only the default termini, since terminusN[2] cannot be used and terminusN[via] is reserved if type(terminusN) == 'string' or (type(terminusN) == 'table' and (terminusN[2] or terminusN['via'])) then if args[v]['to-' .. b] then terminusT = args[v]['to-' .. b] local _or = mw.ustring.match(terminusT, i18n[lang]['or-format']) if _or then terminusT = mw.ustring.gsub(terminusT, i18n[lang]['or-format'], '\127_OR_\127') terminusT = mw.ustring.gsub(terminusT, i18n[lang]['comma-format'], '\127_OR_\127') end local _via = (mw.ustring.match(terminusT, i18n[lang]['via-format'])) if _via then terminusT = mw.ustring.gsub(terminusT, i18n[lang]['via-format'], '') terminusT = mw.text.split(terminusT, '\127_OR_\127') terminusT['via'] = _via elseif _or then terminusT = mw.text.split(terminusT, '\127_OR_\127') end else terminusT = terminusN end elseif type(terminusN) == 'table' then terminusT = terminusN[args[v]['to-' .. b]] or terminusN[args[v]['to']] or terminusN[1] end local mainText = args[v]['note-' .. b] and getTerminusText(args[v][b], Format) .. small(args[v]['note-' .. b]) or getTerminusText(args[v][b], Format) local subText = (args[v]['oneway-' .. b] or line['oneway-' .. b]) and i18n[lang]['oneway'] or args[v][b] == terminusT and i18n[lang]['terminus'] or circular and terminusT or i18n[lang]['towards'](getTerminusText(terminusT, Format)) subText = small(subText, true) sideCell[i] = mainText .. subText end end table.insert(wikitable, '\n|-') table.insert(wikitable, '\n|' .. style['body cell'] .. sideCell[1]) table.insert(wikitable, table.concat({'\n|', style['body banner'], color, '"|', '\n|', (background_color and 'class="bcA" style="background-color:rgba(' .. table.concat(rgb(background_color), ',') .. ',.2)"|' or style['body cell']), line['title'], -- Type; table key 'types' in subpages (datatype table, with strings as keys). If table does not exist then the input is displayed as the text (typeN and '<div>' .. (Type and Type['title'] or typeN) .. '</div>' or ''), -- Note-mid; table key 'note-mid' in subpages. Overridden by user input ((args[v]['note-mid'] and small(args[v]['note-mid'])) or (Type and Type['note-mid'] and small(Type['note-mid'])) or (line['note-mid'] and small(line['note-mid'])) or ''), -- Transfer; uses system's station link table (args[v]['transfer'] and small('transfer at ' .. getTerminusText(args[v]['transfer'], Format), true) or ''), '\n|', style['body banner'], color_2, '"|'})) table.insert(wikitable, '\n|' .. style['body cell'] .. sideCell[2]) end end if args[v]['note-row'] then -- Note if args[v]['note-row']:match('^%s*<tr') or args[v]['note-row']:match('^%s*%|%-') then table.insert(wikitable, '\n' .. args[v]['note-row']) else table.insert(wikitable, '\n|-\n|colspan="5" ' .. style['body cell'] .. args[v]['note-row']) end table.insert(wikitable, '') table.insert(wikitable, '') table.insert(wikitable, '') end end local function combine(t, n) if t[n + 4] ~= '' and t[n + 4] == t[n] then t[n + 4] = '' -- The cell in the next row is deleted local rowspan = 2 while t[n + rowspan * 4] == t[n] do t[n + rowspan * 4] = '' rowspan = rowspan + 1 end t[n] = mw.ustring.gsub(t[n], '\n|class="', '\n|rowspan="' .. rowspan .. '" class="') end end local M = #wikitable for i = 3, M, 4 do combine(wikitable, i) end for i = 4, M, 4 do combine(wikitable, i) end for i = 5, M, 4 do combine(wikitable, i) end table.insert(wikitable, '\n|}') return table.concat(wikitable) end local getArgs = require('Module:Arguments').getArgs local function makeInvokeFunction(funcName) -- makes a function that can be returned from #invoke, using -- [[Module:Arguments]] return function (frame) local args = getArgs(frame, {parentOnly = true}) return p[funcName](args, frame) end end local function makeTemplateFunction(funcName) -- makes a function that can be returned from #invoke, using -- [[Module:Arguments]] return function (frame) local args = getArgs(frame, {frameOnly = true}) return p[funcName](args, frame) end end p.main = makeInvokeFunction('_main') function p._color(args, frame) local data = args.data if args[1] or data then data = data or getData(args[1], true) if not data then return getColor(nil, args[1], args[2], args[3], frame) end return getColor(data, nil, args[2], args[3]) end end p.color = makeInvokeFunction('_color') function p._box(args, frame) local system = args[1] or args.system lineN = args[2] or args.line if not (system or lineN) then return '' end local line, Type, line_data local inline = args[3] or args.inline typeN = args.type local data = args.data if system or data then data = data or getData(system, true) local color if data then local default = data['lines']['_default'] or {} line, lineN = getLine(data, lineN) if typeN then typeN = data['aliases'] and data['aliases'][mw.ustring.lower(typeN)] or typeN Type = line['types'] and line['types'][typeN] and line['types'][typeN]['title'] or typeN end color = getColor(data, nil, lineN, typeN) if inline ~= 'box' then line_data = line or error(i18n[lang]['error_unknown'](lineN)) line = line_data['title'] or default['title'] or error(i18n[lang]['error_missing']('title')) line = mw.ustring.gsub(line, '%%1', lineN) end else color = getColor(nil, system, lineN, typeN, frame) if inline ~= 'box' then line = frame:expandTemplate{ title = system .. ' lines', args = {lineN, ['branch'] = typeN} } if mw.text.trim(line) == '' then return error(i18n[lang]['error_unknown'](lineN)) end end Type = typeN end local result if Type and Type ~= '' and inline ~= 'box' then if line == '' then line = Type else result = ' – ' .. Type end end if args.note then result = (result or '') .. ' ' .. args.note end result = result or '' if not inline then -- [[Template:Legend]] result = '<div class="legend" style="page-break-inside:avoid;break-inside:avoid-column"><span class="legend-color" style="display:inline-block;min-width:1.25em;height:1.25em;line-height:1.25;margin:1px 0;border:1px solid black;color:inherit;background-color:#' .. color .. '"> </span> ' .. line .. result .. '</div>' elseif inline == 'yes' then result = '<span style="color:inherit;background-color:#' .. color .. ';border:1px solid #000">    </span>&nbsp;' .. line .. result elseif inline == 'box' then result = '<span style="color:inherit;background-color:#' .. color .. ';border:1px solid #000">    </span>' .. result elseif inline == 'link' then local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]') if link then result = '[[' .. link .. '|<span style="color:inherit;background-color:#' .. color .. ';border:1px solid #000">    </span>]]' .. result else result = '<span style="color:inherit;background-color:#' .. color .. ';border:1px solid #000">    </span>' .. result end elseif inline == 'square' then result = '<span style="color:#' .. color .. ';line-height:initial">■</span>&nbsp;' .. line .. result elseif inline == 'lsquare' then local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]') if link then result = '[[' .. link .. '|<span style="color:#' .. color .. ';line-height:initial">■</span>]]' else result = '<span style="color:#' .. color .. ';line-height:initial">■</span>' end elseif inline == 'dot' then result = '<span style="color:#' .. color .. ';line-height:initial">●</span> ' .. line .. result elseif inline == 'ldot' then local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]') if link then result = '[[' .. link .. '|<span style="color:#' .. color .. ';line-height:initial">●</span>]]' else result = '<span style="color:#' .. color .. ';line-height:initial">●</span>' end elseif inline == 'small' then result = '<span style="color:inherit;background-color:#' .. color .. '"> </span>' .. ' ' .. line .. result else local yesno = require("Module:Yesno") local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]') local border_color, text_color local color_box = data['color box format'] or data['rail box format'] or {} if line_data then if line_data['types'] and line_data['types'][typeN] then local Type_data = line_data['types'][typeN] border_color = Type_data['border color'] or line_data['border color'] or color text_color = Type_data['text color'] or line_data['text color'] if color_box == 'title' and not args[4] then lineN = Type_data['short name'] or line_data['short name'] or require('Module:Delink')._delink{line} else lineN = Type_data['short name'] or line_data['short name'] or lineN end else border_color = line_data['border color'] or color text_color = line_data['text color'] if color_box == 'title' and not args[4] then lineN = line_data['short name'] or require('Module:Delink')._delink{line} else lineN = line_data['short name'] or lineN end end else border_color = color end text_color = text_color and '#' .. text_color or require('Module:Color contrast')._greatercontrast{color} local bold = ';font-weight:bold' if (yesno(args.bold) == false) then bold = '' end if inline == 'route' then -- [[Template:RouteBox]] if link then result = '<span style="color:inherit;background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';padding:0 .3em">[[' .. link .. '|<span style="color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>' else result = '<span style="background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';padding:0 .3em;color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>' end elseif inline == 'croute' then -- [[Template:Bahnlinie]] if link then result = '<span style="color:inherit;background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em">[[' .. link .. '|<span style="color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>' else result = '<span style="color:inherit;background-color:#' .. color .. ';border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em;color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>' end elseif inline == 'xroute' then -- [[Template:Bahnlinie]] if link then result = '<span style="border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em">[[' .. link .. '|<span style="color:#' .. color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>' else result = '<span style="border:.075em solid #' .. border_color .. ';border-radius:.5em;padding:0 .3em;color:#' .. color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>' end elseif inline == 'broute' then if link then result = '<span style="color:inherit;background-color:#' .. color .. ';border:.075em solid #000;padding:0 .3em">[[' .. link .. '|<span style="color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>]]</span>' else result = '<span style="background-color:#' .. color .. ';border:.075em solid #000;padding:0 .3em;color:' .. text_color .. bold .. ';font-size:inherit;white-space:nowrap">' .. lineN .. '</span>' end else -- [[Template:Legend]] (fallback; duplication to simplify logic) result = '<div class="legend" style="page-break-inside:avoid;break-inside:avoid-column"><span class="legend-color" style="display:inline-block;min-width:1.25em;height:1.25em;line-height:1.25;margin:1px 0;border:1px solid black;color:inherit;background-color:#' .. color .. '"> </span> ' .. line .. result .. '</div>' end end result = mw.ustring.gsub(result, ':%s*#transparent', ':transparent') return result end end p.box = makeInvokeFunction('_box') function p._icon(args, frame) local system = args[1] or args.system local data = args.data if not system and not data then return end data = data or getData(system) local line, line_name = getLine(data, args[2] or args.line) local icon local icon_format if line then local line_type = args[3] or args.type if line_type then line_type = data.aliases and data.aliases[mw.ustring.lower(line_type)] or line_type line_type = line.types and line.types[line_type] -- If there's no type table or entry for this type, then it can't have its own icon icon_format = line_type['icon format'] or data['type icon format'] if line_type.icon then icon = line_type.icon end end if not icon then icon = line.icon end -- Only if there is no icon use the icon_format. if not icon and not icon_format then icon_format = line['icon format'] or data['line icon format'] end local default = data.lines._default or {} if icon and string.find(icon, "%%1") and default and default.icon then icon = mw.ustring.gsub(default.icon, '%%1', line_name) end end if not icon then icon = data['system icon'] end if not icon_format then icon_format = data['system icon format'] end if icon_format then if icon_format ~= 'image' then icon = p._box({data = data, [2] = (args[2] or args.line), [3] = icon_format, type = (args[3] or args.type), bold = args.bold, link = args.link}, frame) if args.name then if line and line.title then return icon .. " " .. line.title end return icon .. " " .. data["system title"] end end end local size = args.size if size then if mw.ustring.match(size, '%d$') then size = '|' .. size .. 'px' else size = '|' .. size end -- Upright values are to be disabled until there is use of upright scaling in subpages; doesn't seem to work anyway as of 2018-08-10 local regex = { '|%s*%d*x?%d+px%s*([%]|])', -- '|%s*upright=%d+%.?%d*%s*([%]|])', '|%s*upright%s*([%]|])' } if mw.ustring.match(icon, regex[1]) then icon = mw.ustring.gsub(icon, regex[1], size .. '%1') -- elseif mw.ustring.match(icon, regex[2]) then -- icon = gsub(icon, regex[2], size .. '%1') -- elseif mw.ustring.match(icon, regex[3]) then -- icon = gsub(icon, regex[3], size .. '%1') else icon = mw.ustring.gsub(icon, '(%[%[[^%]|]+)([%]|])', '%1' .. size .. '%2') end end local link = args.link if link then if mw.ustring.match(icon, '|%s*link=[^%]|]*[%]|]') then icon = mw.ustring.gsub(icon, '|%s*link=[^%]|]*([%]|])', '|link=' .. link .. '%1') else icon = mw.ustring.gsub(icon, '(%[%[[^%]|]+)([%]|])', '%1|link=' .. link .. '%2') end end local alt = args.alt or link if alt then if mw.ustring.match(icon, '|%s*alt=[^%]|]*[%]|]') then icon = mw.ustring.gsub(icon, '|%s*alt=[^%]|]*([%]|])', '|alt=' .. alt .. '%1') else icon = mw.ustring.gsub(icon, '(%[%[[^%]|]+)([%]|])', '%1|alt=' .. alt .. '%2') end end if args.name then if line and line.title then return icon .. " " .. line.title end return icon .. " " .. data["system title"] end return icon end p.icon = makeInvokeFunction('_icon') p['rail icon'] = makeTemplateFunction('_icon') function p._line(args, frame) local system = args[1] or args.system local line = args[2] or args.line if not line then return '' end local Type = args[3] or args.type local data = args.data if system or data then data = data or getData(system, true) if data then line = (getLine(data, line)) or error(i18n[lang]['error_unknown'](line)) if Type then Type = data['aliases'] and data['aliases'][mw.ustring.lower(Type)] or Type Type = line['types'] and line['types'][Type] and line['types'][Type]['title'] or Type end line = line['title'] or error(i18n[lang]['error_missing']('title')) else line = frame:expandTemplate{ title = system .. ' lines', args = {line, ['branch'] = Type} } if mw.text.trim(line) == '' then return error(i18n[lang]['error_unknown'](lineN)) end end if Type and Type ~= '' then if line == '' then line = Type else line = line .. ' – ' .. Type end end return line end end p.line = makeInvokeFunction('_line') function p._shortline(args, frame) local system = args[1] or args.system lineN = args[2] or args.line if not (system or lineN) then return '' end local line, Type, line_data typeN = args.type local data = args.data if system or data then data = data or getData(system, true) if data then local default = data['lines']['_default'] or {} line, lineN = getLine(data, lineN) if typeN then typeN = data['aliases'] and data['aliases'][mw.ustring.lower(typeN)] or typeN Type = line['types'] and line['types'][typeN] and line['types'][typeN]['title'] or typeN end line_data = line or error(i18n[lang]['error_unknown'](lineN)) line = line_data['title'] or default['title'] or error(i18n[lang]['error_missing']('title')) line = mw.ustring.gsub(line, '%%1', lineN) else line = frame:expandTemplate{ title = system .. ' lines', args = {lineN, ['branch'] = typeN} } if mw.text.trim(line) == '' then return error(i18n[lang]['error_unknown'](lineN)) end Type = typeN end local result if Type and Type ~= '' then if line == '' then line = Type else result = ' – ' .. Type end end if args.note then result = (result or '') .. ' ' .. args.note end result = result or '' local link = args.link or mw.ustring.match(line, '%[%[([^%[:|%]]+)[|%]]') if line_data then if line_data['types'] and line_data['types'][typeN] then local Type_data = line_data['types'][typeN] lineN = Type_data['short name'] or line_data['short name'] or lineN else lineN = line_data['short name'] or lineN end end if link then result = '[[' .. link .. '|' .. lineN .. ']]' else result = lineN end result = mw.ustring.gsub(result, ':%s*#transparent', ':transparent') return result end end p.shortline = makeInvokeFunction('_shortline') function p._station(args, frame) local system = args[1] or args.system local station = args[2] or args.station if not station then return '' end lineN = args[3] or args.line typeN = args[4] or args.type local data = args.data if system or data then data = data or getData(system, true) if data then local _Format = data['station format'][station] or data['station format'][1] if _Format then if data['aliases'] then if lineN then lineN = data['aliases'][mw.ustring.lower(lineN)] or lineN end if typeN then typeN = data['aliases'][mw.ustring.lower(typeN)] or typeN end end station = getStation(station, _Format) else station = station or '' end else station = frame:expandTemplate{ title = system .. ' stations', args = {['station'] = station, ['line'] = lineN, ['branch'] = typeN} } end return station end end p.station = makeInvokeFunction('_station') p['station link'] = makeTemplateFunction('_station') function p._terminusTable(args, frame) local system = args[1] or args.system lineN = args[2] or args.line local side = mw.ustring.sub(mw.ustring.lower(args[3] or args.side or ''), 1, 1) typeN = args.type local prefix = (side == 'r') and 'right' or 'left' local data = args.data if system or data then data = data or getData(system, true) end if data then local line = getLine(data, lineN) or error(i18n[lang]['error_unknown'](lineN)) if typeN and data and data['aliases'] then typeN = data['aliases'][mw.ustring.lower(typeN)] or typeN end local Type = line['types'] and line['types'][typeN] local circular if Type then if Type['circular'] then -- Type may override the circular status of the line circular = Type['circular'] end else circular = line['circular'] end return Type and Type[prefix .. ' terminus'] or line[prefix .. ' terminus'], data['station format'] or i18n[lang]['error_format'], circular else local terminus = frame:expandTemplate{ title = 'S-line/' .. system .. ' ' .. prefix .. '/' .. lineN } return mw.ustring.gsub(terminus, '{{{type}}}', typeN) end end function p._terminus(args, frame) local var, Format, circular = p._terminusTable(args, frame) return circular and var or getTerminusText(var, Format) end p.terminus = makeInvokeFunction('_terminus') function p._style(args, frame) local style = args[1] or args.style local system = args[2] or args.system local line = args[3] or args.line local station = args[4] or args.station local result = {} local data = args.data local default = 'color:inherit;background-color:#efefef' -- Default text and background color for {{Infobox station}} if system or data then data = data or getData(system, true) end if data then local function getValue(var) if type(var) == 'table' then var = var[line] or var[1] if type(var) == 'table' then var = var[station] or var[1] end end if var ~= '' then return var end end if style == 'header' then local tmp = data['name format'] and getValue(data['name format']) if tmp then table.insert(result, tmp) end elseif style == 'subheader' then local tmp = data['header background color'] and getValue(data['header background color']) if tmp then table.insert(result, 'background-color:#' .. tmp) local color = data['header text color'] and getValue(data['header text color']) if color then table.insert(result, 'color:#' .. color) else local greatercontrast = require('Module:Color contrast')._greatercontrast if greatercontrast{tmp} == '#FFFFFF' then table.insert(result, 'color:#FFFFFF') end end else table.insert(result, default) local color = data['header text color'] and getValue(data['header text color']) if color then table.insert(result, 'color:#' .. color) end end end result = table.concat(result, ';') elseif system then local title = 'Template:' .. system .. ' style' local titleObj = mw.title.new(title) if titleObj and titleObj.exists then local tmp if style == 'header' then tmp = frame:expandTemplate{ title = title, args = {'name_format', line, station} } if tmp ~= '' then table.insert(result, tmp) end elseif style == 'subheader' then tmp = frame:expandTemplate{ title = title, args = {'thbgcolor', line, station} } if tmp ~= '' then table.insert(result, 'background-color:#' .. tmp) local color = frame:expandTemplate{ title = title, args = {'thcolor', line, station} } if color ~= '' then table.insert(result, 'color:#' .. color) else local ratio = require('Module:Color contrast')._ratio if ratio{tmp, '222222'} < 4.5 then table.insert(result, 'color:#FFFFFF') end -- 222222 is the default text color in Vector end else table.insert(result, default) tmp = frame:expandTemplate{ title = title, args = {'thcolor', line, station} } if tmp ~= '' then table.insert(result, 'color:#' .. tmp) end end end result = table.concat(result, ';') else if style == 'subheader' then result = default else result = '' end end else if style == 'subheader' then result = default else result = '' end end return result end function p.style(frame) local args = getArgs(frame, {frameOnly = true}) return p._style(args, frame) end function p.convert(frame) local args = frame.args local code = mw.text.split(mw.ustring.gsub(args[1], '^%s*{{(.*)}}%s*$', '%1'), '%s*}}%s*{{%s*') local system local group = tonumber(args.offset or 0) or 0 local firstgroup = group + 1 local delete = { ['s-rail'] = true, ['s-rail-next'] = true, ['s-rail-national'] = true, ['s-start'] = true, ['s-rail-start'] = true, ['start'] = true, ['s-end'] = true, ['end'] = true } local order = { 'line', 'left', 'right', 'to-left', 'to-right', 'oneway-left', 'oneway-right', 'through-left', 'through-right', 'reverse', 'reverse-left', 'reverse-right', 'note-left', 'note-mid', 'note-right', 'transfer' -- circular: use module subpage -- state: not implemented } local replace = { ['previous'] = 'left', ['next'] = 'right', ['type'] = 'to-left', ['type2'] = 'to-right', ['branch'] = 'type', ['note'] = 'note-left', ['notemid'] = 'note-mid', ['note2'] = 'note-right', ['oneway1'] = 'oneway-left', ['oneway2'] = 'oneway-right', ['through1'] = 'through-left', ['through2'] = 'through-right' } local remove_rows = {} local data = {} local noclear = false for i, v in ipairs(code) do code[i] = mw.ustring.gsub(code[i], '\n', ' ') local template = mw.ustring.lower(mw.text.trim(mw.ustring.match(code[i], '^[^|]+'))) code[i] = mw.ustring.match(code[i], '(|.+)$') if (mw.ustring.match(code[i] or '', 'noclear%s*=%s*[a-z]')) then noclear = true end if template == 's-line' then data[i] = {} local this_system = mw.text.trim(mw.ustring.match(code[i], '|%s*system%s*=([^|]+)')) code[i] = mw.text.split(code[i], '%s*|%s*') for m, n in ipairs(code[i]) do local tmp = mw.text.split(n, '%s*=%s*') if tmp[3] then tmp[2] = mw.ustring.gsub(n, '^.-%s*=', '') end tmp[1] = replace[tmp[1]] or tmp[1] if tmp[2] then -- checks for matching brackets local curly = select(2, mw.ustring.gsub(tmp[2], "{", ""))-select(2, mw.ustring.gsub(tmp[2], "}", "")) local square = select(2, mw.ustring.gsub(tmp[2], "%[", ""))-select(2, mw.ustring.gsub(tmp[2], "%]", "")) if not (curly == 0 and square == 0) then local count = mw.clone(m)+1 while not (curly == 0 and square == 0) do tmp[2] = tmp[2]..'|'..code[i][count] curly = curly+select(2, mw.ustring.gsub(code[i][count], "{", ""))-select(2, mw.ustring.gsub(code[i][count], "}", "")) square = square+select(2, mw.ustring.gsub(code[i][count], "%[", ""))-select(2, mw.ustring.gsub(code[i][count], "%]", "")) code[i][count] = '' count = count+1 end end data[i][tmp[1]] = tmp[2] end end if (this_system ~= system) or (not system) then system = this_system data[i]['system'] = system else data[i]['system'] = nil end local last = data[i-1] or data[i-2] or data[i-3] if last then for r, s in pairs({ ['hide1'] = {'left', 'to-left', 'note-left', 'oneway-left'}, ['hide2'] = {'right', 'to-right', 'note-right', 'oneway-right'}, ['hidemid'] = {'type', 'note-mid'} }) do if data[i][r] then for m, n in ipairs(s) do if not data[i][n] then data[i][n] = last[n] end end end end end code[i] = {} local X = '|' local Y = (i+group)..'=' if data[i]['system'] then table.insert(code[i], '|system') table.insert(code[i], Y) table.insert(code[i], data[i]['system']) table.insert(code[i], '\n') end for m, n in ipairs(order) do if data[i][n] then table.insert(code[i], X) table.insert(code[i], n) table.insert(code[i], Y) table.insert(code[i], data[i][n]) end end code[i] = table.concat(code[i]) elseif template == 's-note' then code[i] = mw.ustring.gsub(code[i], '|%s*text%s*=', '|header'..i+group..'=') code[i] = mw.ustring.gsub(code[i], '|%s*wide%s*=[^|]*', '') elseif template == 's-text' then code[i] = mw.ustring.gsub(code[i], '|%s*text%s*=', '|note-row'..i+group..'=') elseif delete[template] then code[i] = '' table.insert(remove_rows, 1, i) -- at the start, so that the rows are deleted in reverse order group = group-1 end end for i, v in ipairs(remove_rows) do table.remove(code, v) end code = table.concat(code, '\n') local t = {'{{Adjacent stations' .. (noclear and '|noclear=y\n' or ''), '\n}}'} system = mw.ustring.match(code, '|system(%d*)=') code = mw.ustring.gsub(code, '\n\n+', '\n') if tonumber(system) > firstgroup then -- If s-line isn't the first template then the system will have to be moved to the top system = mw.ustring.match(code, '|system%d*=([^|]*[^|\n])') code = mw.ustring.gsub(code, '|system%d*=[^|]*', '') code = '\n|system'..firstgroup..'='..system..code elseif not mw.ustring.match(code, '^[^{%[]*|[^=|]+2=') then -- If there's only one parameter group then there's no need to have line breaks code = mw.ustring.gsub(code, '\n', '') code = mw.ustring.gsub(code, '(|[^=|]+)1=', '%1=') t[2] = '}}' if not mw.ustring.match(code, '[%[{]') then code = mw.ustring.gsub(code, '|[^=|]*=$', '') code = mw.ustring.gsub(code, '|[^=|]*$', '') end end if not mw.ustring.match(code, '[%[{]') then code = mw.ustring.gsub(code, '|[^=|]*=|', '|') code = mw.ustring.gsub(code, '|[^=|]*|', '|') code = mw.ustring.gsub(code, '|[^=|]*=\n', '\n') code = mw.ustring.gsub(code, '|[^=|]*\n', '\n') end return t[1]..code..t[2] end return p jca1evjg28y2y92hnk1s3eak58flopp Template:Line terminus link 10 52464 308430 2026-09-17T16:04:59Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Adjacent stations|terminus}}</includeonly><noinclude> {{documentation}} </noinclude> 308430 wikitext text/x-wiki <includeonly>{{#invoke:Adjacent stations|terminus}}</includeonly><noinclude> {{documentation}} </noinclude> rond8etukbu6w1wx6cxfe7r1mbwq1jy Template:Station icon link 10 52465 308431 2026-09-17T16:05:25Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{line|{{{3}}}}}}}}{{#if:{{{4|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{4}}}}}|}}{{#if:{{{5|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{5}}}}}|}}{{#if:{{{6|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{6}}}}}|}} {{#ifeq:{{{links}}}|no|{{{station|{{{2}}}}}}|{{#invoke:adjacent stations|station link|{{{system|{{{1}}}}}}|{{{station|{{{2}}}}}}|{... 308431 wikitext text/x-wiki <includeonly>{{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{line|{{{3}}}}}}}}{{#if:{{{4|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{4}}}}}|}}{{#if:{{{5|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{5}}}}}|}}{{#if:{{{6|}}}| {{#invoke:adjacent stations|rail icon|{{{system|{{{1}}}}}}|{{{6}}}}}|}} {{#ifeq:{{{links}}}|no|{{{station|{{{2}}}}}}|{{#invoke:adjacent stations|station link|{{{system|{{{1}}}}}}|{{{station|{{{2}}}}}}|{{{line|{{{3}}}}}}}}}}</includeonly><noinclude>{{documentation}}</noinclude> p5fzuurb284xm6fwd4eqpsp45j9kvcd Template:Line link 10 52466 308432 2026-09-17T16:05:50Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Adjacent stations|line}}</includeonly><noinclude> {{documentation}} </noinclude> 308432 wikitext text/x-wiki <includeonly>{{#invoke:Adjacent stations|line}}</includeonly><noinclude> {{documentation}} </noinclude> kp5kspm90n7yiowkxwn0azq0oypfigm Template:Rail color box 10 52467 308433 2026-09-17T16:06:32Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Adjacent stations|box}}</includeonly><noinclude> {{documentation}} </noinclude> 308433 wikitext text/x-wiki <includeonly>{{#invoke:Adjacent stations|box}}</includeonly><noinclude> {{documentation}} </noinclude> 0z5wsspuhn41s44huksyg8mmcifp924 Template:Adjacent stations 10 52468 308434 2026-09-17T16:06:56Z Isma4l 41797 Bog cusub: <includeonly><templatestyles src="Adjacent stations/styles.css"/>{{safesubst:#invoke:Adjacent stations|main}}</includeonly><noinclude> {{documentation}} </noinclude> 308434 wikitext text/x-wiki <includeonly><templatestyles src="Adjacent stations/styles.css"/>{{safesubst:#invoke:Adjacent stations|main}}</includeonly><noinclude> {{documentation}} </noinclude> q99wx427wztspgaso2z00zfax8t4u3l Template:Adjacent stations/styles.css 10 52469 308435 2026-09-17T16:07:21Z Isma4l 41797 Bog cusub: /* {{pp-template}} */ .adjacent-stations { max-width: 50em; margin: 0.5em auto; font-size: 95%; clear: both; } .infobox .adjacent-stations { font-size: 100%; } .adjacent-stations .isA { font-size: 90%; font-style: italic; } .adjacent-stations .smA { font-size: 90%; } .infobox .adjacent-stations .isA, .infobox .adjacent-stations .smA { font-size: 96.6%; } .adjacent-stations .hcA { width: 30%; vertical-align: middle; } .adjacent-stations .hmA, .adjacent-stations .hm... 308435 sanitized-css text/css /* {{pp-template}} */ .adjacent-stations { max-width: 50em; margin: 0.5em auto; font-size: 95%; clear: both; } .infobox .adjacent-stations { font-size: 100%; } .adjacent-stations .isA { font-size: 90%; font-style: italic; } .adjacent-stations .smA { font-size: 90%; } .infobox .adjacent-stations .isA, .infobox .adjacent-stations .smA { font-size: 96.6%; } .adjacent-stations .hcA { width: 30%; vertical-align: middle; } .adjacent-stations .hmA, .adjacent-stations .hmA > a:last-child { vertical-align: middle; } .adjacent-stations .bcA { text-align: center; vertical-align: middle; } .adjacent-stations .bbA { text-align: center; width: 8px; min-width: 8px; } .adjacent-stations-noclear { clear: none; } risrhgjz6v7pgpul9mqye7kqmrkfy21 Template:Calendar/styles.css 10 52470 308436 2026-09-17T16:09:37Z Isma4l 41797 Bog cusub: /* {{pp-template}} */ .calendar-purple { color: var(--color-base, #202122); background-color: #ccf; } .calendar-lightpurple { color: var(--color-base, #202122); background-color: #d8e0ff; } html.skin-theme-clientpref-night .calendar-purple { background-color: #2a2a5c; } html.skin-theme-clientpref-night .calendar-lightpurple { background-color: #202040; } @media screen and (prefers-color-scheme: dark){ html.skin-theme-clientpref-os .calendar-purple { background-col... 308436 sanitized-css text/css /* {{pp-template}} */ .calendar-purple { color: var(--color-base, #202122); background-color: #ccf; } .calendar-lightpurple { color: var(--color-base, #202122); background-color: #d8e0ff; } html.skin-theme-clientpref-night .calendar-purple { background-color: #2a2a5c; } html.skin-theme-clientpref-night .calendar-lightpurple { background-color: #202040; } @media screen and (prefers-color-scheme: dark){ html.skin-theme-clientpref-os .calendar-purple { background-color: #2a2a5c; } html.skin-theme-clientpref-night .calendar-lightpurple { background-color: #202040; } } jrd7yfzquhnqcn1szvnw2rt01dj5nez Template:Use shortened footnotes 10 52471 308438 2026-09-17T16:12:43Z Isma4l 41797 Bog cusub: {{ {{{|safesubst:}}}#invoke:Unsubst||date=__DATE__|$B= {{DMCA|Use shortened footnotes|from|{{{date|}}}}} }}<noinclude>{{Documentation}}</noinclude> 308438 wikitext text/x-wiki {{ {{{|safesubst:}}}#invoke:Unsubst||date=__DATE__|$B= {{DMCA|Use shortened footnotes|from|{{{date|}}}}} }}<noinclude>{{Documentation}}</noinclude> 20rhb7nv1ahv4iombvadidqs8cr3kz0 Template:GHS exclamation mark 10 52472 308439 2026-09-17T16:14:02Z Isma4l 41797 Bog cusub: [[File:GHS-pictogram-exclam.svg|50px|{{{1|GHS07: Exclamation mark}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> 308439 wikitext text/x-wiki [[File:GHS-pictogram-exclam.svg|50px|{{{1|GHS07: Exclamation mark}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> pj5fpeqpsz924tq1d7ysyq8l2c95voh Template:GHS exploding bomb 10 52473 308440 2026-09-17T16:14:32Z Isma4l 41797 Bog cusub: [[File:GHS-pictogram-explos.svg|50px|{{{1|GHS01: Explosive}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> 308440 wikitext text/x-wiki [[File:GHS-pictogram-explos.svg|50px|{{{1|GHS01: Explosive}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> bqrroy35u4i02y6e0b0wgcosefwv6mq Template:GHS flame 10 52474 308441 2026-09-17T16:15:10Z Isma4l 41797 Bog cusub: [[File:GHS-pictogram-flamme.svg|50px|{{{1|GHS02: Flammable}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> 308441 wikitext text/x-wiki [[File:GHS-pictogram-flamme.svg|50px|{{{1|GHS02: Flammable}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> ab3j7d7nh12ue16srbyg5yjghaa45zt Template:GHS flame over circle 10 52475 308442 2026-09-17T16:15:37Z Isma4l 41797 Bog cusub: [[File:GHS-pictogram-rondflam.svg|50px|{{{1|GHS03: Oxidizing}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> 308442 wikitext text/x-wiki [[File:GHS-pictogram-rondflam.svg|50px|{{{1|GHS03: Oxidizing}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> lkn4ircb92jw5vt06eqlht40en3koa2 Template:GHS gas cylinder 10 52476 308443 2026-09-17T16:16:01Z Isma4l 41797 Bog cusub: [[File:GHS-pictogram-bottle.svg|50px|{{{1|GHS04: Compressed Gas}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> 308443 wikitext text/x-wiki [[File:GHS-pictogram-bottle.svg|50px|{{{1|GHS04: Compressed Gas}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> oedsl2shc4p4dow3fw69uk7pzw02t6k Template:GHS corrosion 10 52477 308444 2026-09-17T16:16:22Z Isma4l 41797 Bog cusub: [[File:GHS-pictogram-acid.svg|50px|{{{1|GHS05: Corrosive}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> 308444 wikitext text/x-wiki [[File:GHS-pictogram-acid.svg|50px|{{{1|GHS05: Corrosive}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> gvjpaf4fg2no8wm8mm50xi0deigmbxw Template:GHS skull and crossbones 10 52478 308445 2026-09-17T16:17:10Z Isma4l 41797 Bog cusub: [[File:GHS-pictogram-skull.svg|50px|{{{1|GHS06: Toxic}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> 308445 wikitext text/x-wiki [[File:GHS-pictogram-skull.svg|50px|{{{1|GHS06: Toxic}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> 2kgrqxrifdzs0u6uu2gglubdt95el2g Template:GHS health hazard 10 52479 308446 2026-09-17T16:17:31Z Isma4l 41797 Bog cusub: [[File:GHS-pictogram-silhouette.svg|50px|{{{1|GHS08: Health hazard}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> 308446 wikitext text/x-wiki [[File:GHS-pictogram-silhouette.svg|50px|{{{1|GHS08: Health hazard}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> eehtp8i5yjzfnlkh1c4onaks3u2b1dj Template:GHS environment 10 52480 308447 2026-09-17T16:17:53Z Isma4l 41797 Bog cusub: [[File:GHS-pictogram-pollu.svg|50px|{{{1|GHS09: Environmental hazard}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> 308447 wikitext text/x-wiki [[File:GHS-pictogram-pollu.svg|50px|{{{1|GHS09: Environmental hazard}}}]]<!-- --><noinclude>{{documentation|1=Template:GHS exploding bomb/doc}}</noinclude> 450mbwngn1hy77go5k38asqrrwbqz0h Template:Editcount 10 52481 308448 2026-09-17T16:19:13Z Isma4l 41797 Bog cusub: <span class="plainlinks">[https://xtools.wmflabs.org/ec/{{CONTENTLANGUAGE}}.wikipedia/{{urlencode:{{{1}}}|PATH}} {{{2|Wax ka beddel tirada {{{1}}}}}}]</span><noinclude> {{documentation}} </noinclude> 308448 wikitext text/x-wiki <span class="plainlinks">[https://xtools.wmflabs.org/ec/{{CONTENTLANGUAGE}}.wikipedia/{{urlencode:{{{1}}}|PATH}} {{{2|Wax ka beddel tirada {{{1}}}}}}]</span><noinclude> {{documentation}} </noinclude> kfca5rxiw6c5mey1flnh0izumn93edp Template:Ed right 10 52482 308449 2026-09-17T16:19:48Z Isma4l 41797 Bog cusub: <div class="editsection noprint editlink plainlinks" align="right" style="float: right; margin-left: 5px;"><small>[{{fullurl:{{transclude|{{#if:{{{namespace|}}}|{{{namespace|}}}:}}{{{1}}}}}|action=edit}} edit{{#if:{{{2|}}}|&#32;{{{2}}}}}]</small></div><noinclude> {{documentation}} </noinclude> 308449 wikitext text/x-wiki <div class="editsection noprint editlink plainlinks" align="right" style="float: right; margin-left: 5px;"><small>[{{fullurl:{{transclude|{{#if:{{{namespace|}}}|{{{namespace|}}}:}}{{{1}}}}}|action=edit}} edit{{#if:{{{2|}}}|&#32;{{{2}}}}}]</small></div><noinclude> {{documentation}} </noinclude> 1fmx0srcskfzhg7uz6c41vu3y60k16j Template:Edit section 10 52483 308450 2026-09-17T16:20:48Z Isma4l 41797 Bog cusub: <{{{type|div}}} class="mw-editsection plainlinks"><span class="mw-editsection-bracket">[</span><span style="color:#002bb8;">[{{fullurl:{{{page|{{FULLPAGENAME}}}}}|action=edit{{#ifeq:{{{1|{{{section}}}}}}|-1||&section={{urlencode:{{{1|{{{section|0}}}}}}}}}}}} edit]</span><span class="mw-editsection-bracket">]</span></{{{type|div}}}><noinclude> <!--Categories and interwikis go on the /doc page.--> {{Documentation}} </noinclude> 308450 wikitext text/x-wiki <{{{type|div}}} class="mw-editsection plainlinks"><span class="mw-editsection-bracket">[</span><span style="color:#002bb8;">[{{fullurl:{{{page|{{FULLPAGENAME}}}}}|action=edit{{#ifeq:{{{1|{{{section}}}}}}|-1||&section={{urlencode:{{{1|{{{section|0}}}}}}}}}}}} edit]</span><span class="mw-editsection-bracket">]</span></{{{type|div}}}><noinclude> <!--Categories and interwikis go on the /doc page.--> {{Documentation}} </noinclude> hxk71ckfgc7ieipadx5rg014o9r790v Template:View 10 52484 308451 2026-09-17T16:21:39Z Isma4l 41797 Bog cusub: {{#invoke:navbar|navbar|plain = 1|template = {{{template|{{{1|}}}}}}}}<noinclude> {{Documentation|Template:Navbar/doc}} </noinclude> 308451 wikitext text/x-wiki {{#invoke:navbar|navbar|plain = 1|template = {{{template|{{{1|}}}}}}}}<noinclude> {{Documentation|Template:Navbar/doc}} </noinclude> 3cdib5yx2npzm141agd4nm089qwwm12 Template:VTE 10 52485 308452 2026-09-17T16:22:06Z Isma4l 41797 Bog cusub: {{#invoke:Navbar|navbar|mini = 1|template = {{{template|{{{1|}}}}}}}}<noinclude> {{Documentation}} </noinclude> 308452 wikitext text/x-wiki {{#invoke:Navbar|navbar|mini = 1|template = {{{template|{{{1|}}}}}}}}<noinclude> {{Documentation}} </noinclude> frbwokefeudcd6b73e189tb5en7psk5 Template:Talk 10 52486 308453 2026-09-17T16:22:40Z Isma4l 41797 Bog cusub: [[{{ {{{|safesubst:}}}TALKPAGENAME:{{{1|{{ {{{|safesubst:}}}FULLPAGENAME}}}}}}}{{ {{{|safesubst:}}}#if:{{{2|}}}|{{ {{{|safesubst:}}}!}}{{{2}}}}}]]<noinclude> {{documentation}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 308453 wikitext text/x-wiki [[{{ {{{|safesubst:}}}TALKPAGENAME:{{{1|{{ {{{|safesubst:}}}FULLPAGENAME}}}}}}}{{ {{{|safesubst:}}}#if:{{{2|}}}|{{ {{{|safesubst:}}}!}}{{{2}}}}}]]<noinclude> {{documentation}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> fo91apztssmkvsddbf3f3uyyl9d8nve Template:Article links 10 52487 308454 2026-09-17T16:23:22Z Isma4l 41797 Bog cusub: {{#ifeq:{{{noanchor|no}}}|yes|<!--nothing-->|<span id="{{anchorencode:{{{1}}}}}"></span>}}<span class="plainlinks nourlexpansion lx">[[:{{encodefirst|{{ucfirst:{{{1|Article}}}}}}}]] ([[Special:EditPage/{{{1}}}|edit]]&nbsp;&#124; [[Talk:{{{1}}}|talk]]&nbsp;&#124; [[Special:PageHistory/{{{1}}}|history]]<span class="sysop-show">&nbsp;&#124; [[Special:ProtectPage/{{{1}}}|protect]]&nbsp;&#124; [[Special:DeletePage/{{{1}}}|delete]]</span>&nbsp;&#124; [{{fullurl:Special:WhatLinksHere/{{... 308454 wikitext text/x-wiki {{#ifeq:{{{noanchor|no}}}|yes|<!--nothing-->|<span id="{{anchorencode:{{{1}}}}}"></span>}}<span class="plainlinks nourlexpansion lx">[[:{{encodefirst|{{ucfirst:{{{1|Article}}}}}}}]] ([[Special:EditPage/{{{1}}}|edit]]&nbsp;&#124; [[Talk:{{{1}}}|talk]]&nbsp;&#124; [[Special:PageHistory/{{{1}}}|history]]<span class="sysop-show">&nbsp;&#124; [[Special:ProtectPage/{{{1}}}|protect]]&nbsp;&#124; [[Special:DeletePage/{{{1}}}|delete]]</span>&nbsp;&#124; [{{fullurl:Special:WhatLinksHere/{{{1}}}|limit=999}} links]&nbsp;&#124; [{{fullurl:{{{1}}}|action=watch}} watch]&nbsp;&#124; [{{fullurl:Special:Log|page={{urlencode:{{{1}}}}}}} logs]&nbsp;&#124; [https://tools.wmflabs.org/pageviews?pages={{urlencode:{{encodefirst|{{{1}}}}}|WIKI}}&project=en.wikipedia.org views])</span><noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude> rd9w26p8xo65u4r3foruloy50jsp8ly Template:Getalias2 10 52488 308455 2026-09-17T16:24:54Z Isma4l 41797 Bog cusub: {{Country data {{{1|}}}|Getalias2/core|name={{{2|}}}|variant={{{variant|}}}}}<noinclude> {{Documentation}} </noinclude> 308455 wikitext text/x-wiki {{Country data {{{1|}}}|Getalias2/core|name={{{2|}}}|variant={{{variant|}}}}}<noinclude> {{Documentation}} </noinclude> 8g87ju7uka8mcb316x6x4kqww76hxqy Template:Getalias2/core 10 52489 308456 2026-09-17T16:25:55Z Isma4l 41797 Bog cusub: {{#if:{{{variant|}}}|{{{{{{name}}}-{{{variant}}}|{{{{{{name}}}}}}}}}|{{{{{{name}}}}}}}}<noinclude> {{Documentation|content=This template is used internally by {{tl|Getalias2}} and should not be used directly.}} [[Category:Flag template system cores]] </noinclude> 308456 wikitext text/x-wiki {{#if:{{{variant|}}}|{{{{{{name}}}-{{{variant}}}|{{{{{{name}}}}}}}}}|{{{{{{name}}}}}}}}<noinclude> {{Documentation|content=This template is used internally by {{tl|Getalias2}} and should not be used directly.}} [[Category:Flag template system cores]] </noinclude> ssnmytqj5xe9ej30r5f2l246byoquzc Template:Cite NatureServe 10 52490 308457 2026-09-17T16:26:52Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:template wrapper|wrap|_template=cite web|_exclude=id | url = https://explorer.natureserve.org/Taxon/ELEMENT_GLOBAL.{{{id|}}}/ | last1 = NatureServe | author-link1 = NatureServe | website = NatureServe Explorer | location = Arlington, Virginia | language = en }}</includeonly><noinclude> {{Documentation}} </noinclude> 308457 wikitext text/x-wiki <includeonly>{{#invoke:template wrapper|wrap|_template=cite web|_exclude=id | url = https://explorer.natureserve.org/Taxon/ELEMENT_GLOBAL.{{{id|}}}/ | last1 = NatureServe | author-link1 = NatureServe | website = NatureServe Explorer | location = Arlington, Virginia | language = en }}</includeonly><noinclude> {{Documentation}} </noinclude> pqiphwa4or9qs5tgxqepk0uphars7cy Module:Professional wrestling profiles 828 52491 308458 2026-09-17T16:27:35Z Isma4l 41797 Bog cusub: local getArgs = require('Module:Arguments').getArgs local p = {} local profiles = { { key = "wwe", name = "WWE", person = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" }, team = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" }, stable = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" } }, { key = "roh", name = "Ring of Honor", person = { url = "https://www.ringofhonor.com/active-roster/%s", wikidata = nil },... 308458 Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local p = {} local profiles = { { key = "wwe", name = "WWE", person = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" }, team = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" }, stable = { url = "https://www.wwe.com/superstars/%s", wikidata = "P2857" } }, { key = "roh", name = "Ring of Honor", person = { url = "https://www.ringofhonor.com/active-roster/%s", wikidata = nil }, team = { url = nil, wikidata = nil }, stable = { url = nil, wikidata = nil } }, { key = "njpw", name = "New Japan Pro-Wrestling", person = { url = "https://www.njpw1972.com/profile/%s", wikidata = nil }, team = { url = nil, wikidata = nil }, stable = { url = nil, wikidata = nil } }, { key = "cagematch", name = "Cagematch", person = { url = "https://www.cagematch.net/?id=2&nr=%s", wikidata = "P2728" }, team = { url = "https://www.cagematch.net/?id=28&nr=%s", wikidata = "P2939" }, stable = { url = "https://www.cagematch.net/?id=29&nr=%s", wikidata = "P3042" } }, { key = "wrestlingdata", name = "Wrestlingdata", person = { url = "https://www.wrestlingdata.com/index.php?befehl=bios&wrestler=%s", wikidata = "P2764" }, team = { url = "https://www.wrestlingdata.com/index.php?befehl=stables&stable=%s", wikidata = nil }, stable = { url = "https://www.wrestlingdata.com/index.php?befehl=stables&stable=%s", wikidata = nil } }, { key = "iwd", name = "Internet Wrestling Database", person = { url = "http://www.profightdb.com/wrestlers/%s.html", wikidata = "P2829" }, team = { url = nil, wikidata = nil }, stable = { url = nil, wikidata = nil } }, { key = "wrestlingtitles", name = "Wrestling-Titles", person = { url = "https://www.wrestling-titles.com/personalities/%s/", wikidata = nil }, team = { url = nil, wikidata = nil }, stable = { url = nil, wikidata = nil } } } local function fetch_wikidata(entity, property) if entity and property then local value = entity:getBestStatements(property)[1] if value then return value["mainsnak"]["datavalue"]["value"] end end return nil end function p.profiles(frame) local args = getArgs(frame) local entity = mw.wikibase.getEntity() local _type = "person" local text = "" -- Determine type if args["type"] and (args["type"] == "person" or args["type"] == "team" or args["type"] == "stable") then _type = args["type"] else local instance = fetch_wikidata(entity, "P31") -- "instance of" on Wikidata local types = { ["Q5"] = "person", -- "human" ["Q1066670"] = "team", -- "tag team" ["Q25178247"] = "stable" -- "professional wrestling stable" } if instance and types[instance.id] then _type = types[instance.id] end end -- Parse profiles for index, data in ipairs(profiles) do local value = args[data["key"]] or fetch_wikidata(entity, data[_type]["wikidata"]) if value and data[_type]["url"] then text = text .. string.format("[" .. data[_type]["url"] .. " " .. data["name"] .. "]", value) .. (args[data["key"]] and "" or frame:expandTemplate{title = 'EditAtWikidata', args = { pid = data[_type]["wikidata"] }}) .. ", " end end if text == "" then return mw.title.getCurrentTitle().namespace == 0 and "[[Category:Professional wrestling profiles template without any identifiers]]" or nil end return (args["name"] or frame:expandTemplate{title = 'PAGENAMEBASE'}) .. "'s profile at " .. string.sub(text, 1, -3) end return p h3rlfmn2355yia23tw7t3btnf50vg8u Template:Professional wrestling profiles 10 52492 308459 2026-09-17T16:29:01Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Professional wrestling profiles|profiles}}</includeonly><noinclude>{{Documentation}}</noinclude> 308459 wikitext text/x-wiki <includeonly>{{#invoke:Professional wrestling profiles|profiles}}</includeonly><noinclude>{{Documentation}}</noinclude> 6mkfk6eftvwjngjes14wll8gt93acps Module:Template test case/config 828 52493 308460 2026-09-17T16:30:26Z Isma4l 41797 Bog cusub: ------------------------------------------------------------------------------- -- Module:Template test case/config -- This module holds configuration data for [[Module:Template test case]]. ------------------------------------------------------------------------------- return { ------------------------------------------------------------------------------- -- Options ------------------------------------------------------------------------------- -- The magi... 308460 Scribunto text/plain ------------------------------------------------------------------------------- -- Module:Template test case/config -- This module holds configuration data for [[Module:Template test case]]. ------------------------------------------------------------------------------- return { ------------------------------------------------------------------------------- -- Options ------------------------------------------------------------------------------- -- The magic word used in place of the template name when making nowiki -- invocations. templateNameMagicWord = '__TEMPLATENAME__', -- The subpage that sandboxes are typically stored on. Used when loading -- wrapper template config and when guessing the sandbox template name. sandboxSubpage = 'sandbox', ------------------------------------------------------------------------------- -- Messages ------------------------------------------------------------------------------- msg = { -- The default header for test cases rendered in columns. ['columns-header'] = 'Side by side comparison', -- The error message to use if a template option is missing. -- $1 - the number of the missing template option. ['missing-template-option-error'] = "one or more options ending in '$1' " .. "were detected, but no 'template$1' option was found", -- The error message to use if a nowiki invocation is used but the template -- name magic word is not found. -- $1 - the value of the template name magic word ['nowiki-magic-word-error'] = "the template invocation must include '$1' in " .. "place of the template name", }, ------------------------------------------------------------------------------- -- Wrapper template config. -- The wrapper template config is a table with wrapper template names as keys, -- and subtables containing two fields: -- func - the function name to be used with that template. This must be a -- function exported by the main module. This is optional: the default -- value is "table". -- args - a table of default arguments to be used with that template. This is -- is optional. ------------------------------------------------------------------------------- wrappers = { ['Template:Test case'] = {}, ['Template:Testcase table'] = { args = {_format = 'columns'} }, ['Template:Testcase rows'] = { args = {_format = 'rows'} }, ['Template:Test case nowiki'] = { func = 'nowiki' }, ['Template:Nowiki template demo'] = { func = 'nowiki', args = {showheader = false, showtemplate2 = false} }, ['Template:Collapsible test case'] = { args = {_collapsible = true} }, ['Template:Collapsible 2 test case'] = { args = {_collapsible = true, _wantdiff = true} }, ['Template:Inline test case'] = { args = {_format = 'inline', _showcode = true} }, }, ------------------------------------------------------------------------------- -- End config ------------------------------------------------------------------------------- } ls9rvym0pi5xrbhs2q9kgqx1nenxr3g Module:Template test case 828 52494 308461 2026-09-17T16:31:16Z Isma4l 41797 Bog cusub: --[[ A module for generating test case templates. This module incorporates code from the English Wikipedia's "Testcase table" module,[1] written by Frietjes [2] with contributions by Mr. Stradivarius [3] and Jackmcbarn,[4] and the English Wikipedia's "Testcase rows" module,[5] written by Mr. Stradivarius. The "Testcase table" and "Testcase rows" modules are released under the CC BY-SA 3.0 License [6] and the GFDL.[7] License: CC BY-SA 3.0 and the GFDL... 308461 Scribunto text/plain --[[ A module for generating test case templates. This module incorporates code from the English Wikipedia's "Testcase table" module,[1] written by Frietjes [2] with contributions by Mr. Stradivarius [3] and Jackmcbarn,[4] and the English Wikipedia's "Testcase rows" module,[5] written by Mr. Stradivarius. The "Testcase table" and "Testcase rows" modules are released under the CC BY-SA 3.0 License [6] and the GFDL.[7] License: CC BY-SA 3.0 and the GFDL Author: Mr. Stradivarius [1] https://en.wikipedia.org/wiki/Module:Testcase_table [2] https://en.wikipedia.org/wiki/User:Frietjes [3] https://en.wikipedia.org/wiki/User:Mr._Stradivarius [4] https://en.wikipedia.org/wiki/User:Jackmcbarn [5] https://en.wikipedia.org/wiki/Module:Testcase_rows [6] https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License [7] https://en.wikipedia.org/wiki/Wikipedia:Text_of_the_GNU_Free_Documentation_License ]] -- Load required modules local yesno = require('Module:Yesno') -- Set constants local DATA_MODULE = 'Module:Template test case/data' local SYNTAXHIGHLIGHT_IS_PRESENT = mw.getCurrentFrame():preprocess( "<syntaxhighlight lang=\"text\"></syntaxhighlight>" ) ~= "<syntaxhighlight lang=\"text\"></syntaxhighlight>" ------------------------------------------------------------------------------- -- Shared methods ------------------------------------------------------------------------------- local function message(self, key, ...) -- This method is added to classes that need to deal with messages from the -- config module. local msg = self.cfg.msg[key] if select(1, ...) then return mw.message.newRawMessage(msg, ...):plain() else return msg end end ------------------------------------------------------------------------------- -- Template class ------------------------------------------------------------------------------- local Template = {} Template.memoizedMethods = { -- Names of methods to be memoized in each object. This table should only -- hold methods with no parameters. getFullPage = true, getName = true, makeHeader = true, getOutput = true } function Template.new(invocationObj, options) local obj = {} -- Set input for k, v in pairs(options or {}) do if not Template[k] then obj[k] = v end end obj._invocation = invocationObj -- Validate input if not obj.template and not obj.title then error('no template or title specified', 2) end -- Memoize expensive method calls local memoFuncs = {} return setmetatable(obj, { __index = function (t, key) if Template.memoizedMethods[key] then local func = memoFuncs[key] if not func then local val = Template[key](t) func = function () return val end memoFuncs[key] = func end return func else return Template[key] end end }) end function Template:getFullPage() if not self.template then return self.title.prefixedText elseif self.template:sub(1, 7) == '#invoke' then return 'Module' .. self.template:sub(8):gsub('|.*', '') else local strippedTemplate, hasColon = self.template:gsub('^:', '', 1) hasColon = hasColon > 0 local ns = strippedTemplate:match('^(.-):') ns = ns and mw.site.namespaces[ns] if ns then return strippedTemplate elseif hasColon then return strippedTemplate -- Main namespace else return mw.site.namespaces[10].name .. ':' .. strippedTemplate end end end function Template:getName() if self.template then return self.template else return require('Module:Template invocation').name(self.title) end end function Template:makeLink(display) if display then return string.format('[[:%s|%s]]', self:getFullPage(), display) else return string.format('[[:%s]]', self:getFullPage()) end end function Template:makeBraceLink(display) display = display or self:getName() local link = self:makeLink(display) return mw.text.nowiki('{{') .. link .. mw.text.nowiki('}}') end function Template:makeHeader() return self.heading or self:makeBraceLink() end function Template:getInvocation(format) format = format or '' local invocation = self._invocation:getInvocation{ template = self:getName(), requireMagicWord = self.requireMagicWord, } if format == 'code' or (not SYNTAXHIGHLIGHT_IS_PRESENT and format == 'inline') then -- if syntaxhighlight not present and inline required use code invocation = '<code>' .. mw.text.nowiki(invocation) .. '</code>' elseif format == 'kbd' then invocation = '<kbd>' .. mw.text.nowiki(invocation) .. '</kbd>' elseif format == 'plain' then invocation = mw.text.nowiki(invocation) elseif format == 'pre' or not SYNTAXHIGHLIGHT_IS_PRESENT then -- if syntaxhighlight not present and block required use pre invocation = mw.text.encode(invocation, '&') invocation = '<pre style="white-space: pre-wrap;">' .. invocation .. '</pre>' invocation = mw.getCurrentFrame():preprocess(invocation) else -- use syntaxhighlight as default if present invocation = mw.text.encode(invocation, '&') invocation = mw.getCurrentFrame():preprocess( '<syntaxhighlight lang="wikitext"' .. ( format == 'inline' and ' inline' or '') .. '>' .. invocation .. '</syntaxhighlight>' ) end return invocation end function Template:getOutput() local protect = require('Module:Protect') -- calling self._invocation:getOutput{...} return protect(self._invocation.getOutput)(self._invocation, { template = self:getName(), requireMagicWord = self.requireMagicWord, }) end ------------------------------------------------------------------------------- -- TestCase class ------------------------------------------------------------------------------- local TestCase = {} TestCase.__index = TestCase TestCase.message = message -- add the message method TestCase.renderMethods = { -- Keys in this table are values of the "format" option, values are the -- method for rendering that format. columns = 'renderColumns', rows = 'renderRows', tablerows = 'renderRows', inline = 'renderInline', cells = 'renderCells', default = 'renderDefault' } function TestCase.new(invocationObj, options, cfg) local obj = setmetatable({}, TestCase) obj.cfg = cfg -- Separate general options from template options. Template options are -- numbered, whereas general options are not. local generalOptions, templateOptions = {}, {} for k, v in pairs(options) do local prefix, num if type(k) == 'string' then prefix, num = k:match('^(.-)([1-9][0-9]*)$') end if prefix then num = tonumber(num) templateOptions[num] = templateOptions[num] or {} templateOptions[num][prefix] = v else generalOptions[k] = v end end -- Set general options generalOptions.showcode = yesno(generalOptions.showcode) generalOptions.showheader = yesno(generalOptions.showheader) ~= false generalOptions.showcaption = yesno(generalOptions.showcaption) ~= false generalOptions.collapsible = yesno(generalOptions.collapsible) generalOptions.notcollapsed = yesno(generalOptions.notcollapsed) generalOptions.wantdiff = yesno(generalOptions.wantdiff) obj.options = generalOptions -- Preprocess template args for num, t in pairs(templateOptions) do if t.showtemplate ~= nil then t.showtemplate = yesno(t.showtemplate) end end -- Set up first two template options tables, so that if only the -- "template3" is specified it isn't made the first template when the -- the table options array is compressed. templateOptions[1] = templateOptions[1] or {} templateOptions[2] = templateOptions[2] or {} -- Allow the "template" option to override the "template1" option for -- backwards compatibility with [[Module:Testcase table]]. if generalOptions.template then templateOptions[1].template = generalOptions.template end -- Add default template options if templateOptions[1].template and not templateOptions[2].template then templateOptions[2].template = templateOptions[1].template .. '/' .. obj.cfg.sandboxSubpage end if not templateOptions[1].template then templateOptions[1].title = mw.title.getCurrentTitle().basePageTitle end if not templateOptions[2].template then templateOptions[2].title = templateOptions[1].title:subPageTitle( obj.cfg.sandboxSubpage ) end -- Remove template options for any templates where the showtemplate -- argument is false. This prevents any output for that template. for num, t in pairs(templateOptions) do if t.showtemplate == false then templateOptions[num] = nil end end -- Check for missing template names. for num, t in pairs(templateOptions) do if not t.template and not t.title then error(obj:message( 'missing-template-option-error', num, num ), 2) end end -- Compress templateOptions table so we can iterate over it with ipairs. templateOptions = (function (t) local nums = {} for num in pairs(t) do nums[#nums + 1] = num end table.sort(nums) local ret = {} for i, num in ipairs(nums) do ret[i] = t[num] end return ret end)(templateOptions) -- Don't require the __TEMPLATENAME__ magic word for nowiki invocations if -- there is only one template being output. if #templateOptions <= 1 then templateOptions[1].requireMagicWord = false end mw.logObject(templateOptions) -- Make the template objects obj.templates = {} for i, options in ipairs(templateOptions) do table.insert(obj.templates, Template.new(invocationObj, options)) end -- Add tracking categories. At the moment we are only tracking templates -- that use any "heading" parameters or an "output" parameter. obj.categories = {} for k, v in pairs(options) do if type(k) == 'string' and k:find('heading') then obj.categories['Test cases using heading parameters'] = true elseif k == 'output' then obj.categories['Test cases using output parameter'] = true end end return obj end function TestCase:getTemplateOutput(templateObj) local output = templateObj:getOutput() if self.options.resetRefs then mw.getCurrentFrame():extensionTag('references') end return output end function TestCase:templateOutputIsEqual() -- Returns a boolean showing whether all of the template outputs are equal. -- The random parts of strip markers (see [[Help:Strip markers]]) are -- removed before comparison. This means a strip marker can contain anything -- and still be treated as equal, but it solves the problem of otherwise -- identical wikitext not returning as exactly equal. local function normaliseOutput(obj) local out = obj:getOutput() -- Remove the random parts from strip markers. out = out:gsub('(\127[^\127]*UNIQ%-%-%l+%-)%x+(%-%-?QINU[^\127]*\127)', '%1%2') return out end local firstOutput = normaliseOutput(self.templates[1]) for i = 2, #self.templates do local output = normaliseOutput(self.templates[i]) if output ~= firstOutput then return false end end return true end function TestCase:makeCollapsible(s) local title = self.options.title or self.templates[1]:makeHeader() if self.options.titlecode then title = self.templates[1]:getInvocation('kbd') end local isEqual = self:templateOutputIsEqual() local root = mw.html.create('div') root :wikitext(mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Module:Template test case/styles.css' }, }) :addClass('mw-collapsible') :addClass('test-case-collapsible') :addClass(self.options.notcollapsed == false and 'mw-collapsed' or nil) if self.options.wantdiff then root :tag('div') :addClass(isEqual and 'test-case-collapsible-b1' or 'test-case-collapsible-b2') :wikitext(title) :done() else if self.options.notcollapsed ~= true or false then root :addClass(isEqual and 'mw-collapsed' or nil) end root :tag('div') :addClass(isEqual and 'test-case-collapsible-b3' or 'test-case-collapsible-b1') :wikitext(title) :done() end root :tag('div') :addClass('mw-collapsible-content') :newline() :wikitext(s) :newline() return tostring(root) end function TestCase:renderColumns() local root = mw.html.create() if self.options.showcode then root :wikitext(self.templates[1]:getInvocation()) :newline() end local tableroot = root:tag('table') if self.options.showheader then -- Caption if self.options.showcaption then tableroot :addClass(self.options.class) :cssText(self.options.style) :tag('caption') :wikitext(self.options.caption or self:message('columns-header')) end -- Headers local headerRow = tableroot:tag('tr') if self.options.rowheader then -- rowheader is correct here. We need to add another th cell if -- rowheader is set further down, even if heading0 is missing. headerRow:tag('th'):wikitext(self.options.heading0) end local width if #self.templates > 0 then width = tostring(math.floor(100 / #self.templates)) .. '%' else width = '100%' end for i, obj in ipairs(self.templates) do headerRow :tag('th') :css('width', width) :wikitext(obj:makeHeader()) end end -- Row header local dataRow = tableroot:tag('tr'):css('vertical-align', 'top') if self.options.rowheader then dataRow:tag('th') :attr('scope', 'row') :wikitext(self.options.rowheader) end -- Template output for i, obj in ipairs(self.templates) do if self.options.output == 'nowiki+' then dataRow:tag('td') :newline() :wikitext(self.options.before) :wikitext(self:getTemplateOutput(obj)) :wikitext(self.options.after) :wikitext('<pre style="white-space: pre-wrap;">') :wikitext(mw.text.nowiki(self.options.before or "")) :wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) :wikitext(mw.text.nowiki(self.options.after or "")) :wikitext('</pre>') elseif self.options.output == 'nowiki' then dataRow:tag('td') :newline() :wikitext(mw.text.nowiki(self.options.before or "")) :wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) :wikitext(mw.text.nowiki(self.options.after or "")) else dataRow:tag('td') :newline() :wikitext(self.options.before) :wikitext(self:getTemplateOutput(obj)) :wikitext(self.options.after) end end return tostring(root) end function TestCase:renderRows() local root = mw.html.create() if self.options.showcode then root :wikitext(self.templates[1]:getInvocation()) :newline() end local tableroot = root:tag('table') tableroot :addClass(self.options.class) :cssText(self.options.style) if self.options.caption then tableroot :tag('caption') :wikitext(self.options.caption) end for _, obj in ipairs(self.templates) do local dataRow = tableroot:tag('tr') -- Header if self.options.showheader then if self.options.format == 'tablerows' then dataRow:tag('th') :attr('scope', 'row') :css('vertical-align', 'top') :css('text-align', 'left') :wikitext(obj:makeHeader()) dataRow:tag('td') :css('vertical-align', 'top') :css('padding', '0 1em') :wikitext('→') else dataRow:tag('td') :css('text-align', 'center') :css('font-weight', 'bold') :wikitext(obj:makeHeader()) dataRow = tableroot:tag('tr') end end -- Template output if self.options.output == 'nowiki+' then dataRow:tag('td') :newline() :wikitext(self.options.before) :wikitext(self:getTemplateOutput(obj)) :wikitext(self.options.after) :wikitext('<pre style="white-space: pre-wrap;">') :wikitext(mw.text.nowiki(self.options.before or "")) :wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) :wikitext(mw.text.nowiki(self.options.after or "")) :wikitext('</pre>') elseif self.options.output == 'nowiki' then dataRow:tag('td') :newline() :wikitext(mw.text.nowiki(self.options.before or "")) :wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) :wikitext(mw.text.nowiki(self.options.after or "")) else dataRow:tag('td') :newline() :wikitext(self.options.before) :wikitext(self:getTemplateOutput(obj)) :wikitext(self.options.after) end end return tostring(root) end function TestCase:renderInline() local arrow = mw.language.getContentLanguage():getArrow('forwards') local ret = {} for i, obj in ipairs(self.templates) do local line = {} line[#line + 1] = self.options.prefix or '* ' if self.options.showcode then line[#line + 1] = obj:getInvocation('inline') line[#line + 1] = ' ' line[#line + 1] = arrow line[#line + 1] = ' ' end if self.options.output == 'nowiki+' then line[#line + 1] = self.options.before or "" line[#line + 1] = self:getTemplateOutput(obj) line[#line + 1] = self.options.after or "" line[#line + 1] = '<pre style="white-space: pre-wrap;">' line[#line + 1] = mw.text.nowiki(self.options.before or "") line[#line + 1] = mw.text.nowiki(self:getTemplateOutput(obj)) line[#line + 1] = mw.text.nowiki(self.options.after or "") line[#line + 1] = '</pre>' elseif self.options.output == 'nowiki' then line[#line + 1] = mw.text.nowiki(self.options.before or "") line[#line + 1] = mw.text.nowiki(self:getTemplateOutput(obj)) line[#line + 1] = mw.text.nowiki(self.options.after or "") else line[#line + 1] = self.options.before or "" line[#line + 1] = self:getTemplateOutput(obj) line[#line + 1] = self.options.after or "" end ret[#ret + 1] = table.concat(line) end if self.options.addline then local line = {} line[#line + 1] = self.options.prefix or '* ' line[#line + 1] = self.options.addline ret[#ret + 1] = table.concat(line) end return table.concat(ret, '\n') end function TestCase:renderCells() local root = mw.html.create() local dataRow = root:tag('tr') dataRow :css('vertical-align', 'top') :addClass(self.options.class) :cssText(self.options.style) -- Row header if self.options.rowheader then dataRow:tag('th') :attr('scope', 'row') :newline() :wikitext(self.options.rowheader or self:message('row-header')) end -- Caption if self.options.showcaption then dataRow:tag('th') :attr('scope', 'row') :newline() :wikitext(self.options.caption or self:message('columns-header')) end -- Show code if self.options.showcode then dataRow:tag('td') :newline() :wikitext(self:getInvocation('inline')) end -- Template output for i, obj in ipairs(self.templates) do if self.options.output == 'nowiki+' then dataRow:tag('td') :newline() :wikitext(self.options.before) :wikitext(self:getTemplateOutput(obj)) :wikitext(self.options.after) :wikitext('<pre style="white-space: pre-wrap;">') :wikitext(mw.text.nowiki(self.options.before or "")) :wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) :wikitext(mw.text.nowiki(self.options.after or "")) :wikitext('</pre>') elseif self.options.output == 'nowiki' then dataRow:tag('td') :newline() :wikitext(mw.text.nowiki(self.options.before or "")) :wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) :wikitext(mw.text.nowiki(self.options.after or "")) else dataRow:tag('td') :newline() :wikitext(self.options.before) :wikitext(self:getTemplateOutput(obj)) :wikitext(self.options.after) end end return tostring(root) end function TestCase:renderDefault() local ret = {} if self.options.showcode then ret[#ret + 1] = self.templates[1]:getInvocation() end for i, obj in ipairs(self.templates) do ret[#ret + 1] = '<div style="clear: both;"></div>' if self.options.showheader then ret[#ret + 1] = obj:makeHeader() end if self.options.output == 'nowiki+' then ret[#ret + 1] = (self.options.before or "") .. self:getTemplateOutput(obj) .. (self.options.after or "") .. '<pre style="white-space: pre-wrap;">' .. mw.text.nowiki(self.options.before or "") .. mw.text.nowiki(self:getTemplateOutput(obj)) .. mw.text.nowiki(self.options.after or "") .. '</pre>' elseif self.options.output == 'nowiki' then ret[#ret + 1] = mw.text.nowiki(self.options.before or "") .. mw.text.nowiki(self:getTemplateOutput(obj)) .. mw.text.nowiki(self.options.after or "") else ret[#ret + 1] = (self.options.before or "") .. self:getTemplateOutput(obj) .. (self.options.after or "") end end return table.concat(ret, '\n\n') end function TestCase:__tostring() local format = self.options.format local method = format and TestCase.renderMethods[format] or 'renderDefault' local ret = self[method](self) if self.options.collapsible then ret = self:makeCollapsible(ret) end for cat in pairs(self.categories) do ret = ret .. string.format('[[Category:%s]]', cat) end return ret end ------------------------------------------------------------------------------- -- Nowiki invocation class ------------------------------------------------------------------------------- local NowikiInvocation = {} NowikiInvocation.__index = NowikiInvocation NowikiInvocation.message = message -- Add the message method function NowikiInvocation.new(invocation, cfg) local obj = setmetatable({}, NowikiInvocation) obj.cfg = cfg invocation = mw.text.unstrip(invocation) -- Decode HTML entities for <, >, and ". This means that HTML entities in -- the original code must be escaped as e.g. &amp;lt;, which is unfortunate, -- but it is the best we can do as the distinction between <, >, " and &lt;, -- &gt;, &quot; is lost during the original nowiki operation. invocation = invocation:gsub('&lt;', '<') invocation = invocation:gsub('&gt;', '>') invocation = invocation:gsub('&quot;', '"') obj.invocation = invocation return obj end function NowikiInvocation:getInvocation(options) local template = options.template:gsub('%%', '%%%%') -- Escape "%" with "%%" local invocation, count = self.invocation:gsub( self.cfg.templateNameMagicWordPattern, template ) if options.requireMagicWord ~= false and count < 1 then error(self:message( 'nowiki-magic-word-error', self.cfg.templateNameMagicWord )) end return invocation end function NowikiInvocation:getOutput(options) local invocation = self:getInvocation(options) return mw.getCurrentFrame():preprocess(invocation) end ------------------------------------------------------------------------------- -- Table invocation class ------------------------------------------------------------------------------- local TableInvocation = {} TableInvocation.__index = TableInvocation TableInvocation.message = message -- Add the message method function TableInvocation.new(invokeArgs, nowikiCode, cfg) local obj = setmetatable({}, TableInvocation) obj.cfg = cfg obj.invokeArgs = invokeArgs obj.code = nowikiCode return obj end function TableInvocation:getInvocation(options) if self.code then local nowikiObj = NowikiInvocation.new(self.code, self.cfg) return nowikiObj:getInvocation(options) else return require('Module:Template invocation').invocation( options.template, self.invokeArgs ) end end function TableInvocation:getOutput(options) if (options.template:sub(1, 7) == '#invoke') then local moduleCall = mw.text.split(options.template, '|', true) local args = mw.clone(self.invokeArgs) table.insert(args, 1, moduleCall[2]) return mw.getCurrentFrame():callParserFunction(moduleCall[1], args) end return mw.getCurrentFrame():expandTemplate{ title = options.template, args = self.invokeArgs } end ------------------------------------------------------------------------------- -- Bridge functions -- -- These functions translate template arguments into forms that can be accepted -- by the different classes, and return the results. ------------------------------------------------------------------------------- local bridge = {} function bridge.table(args, cfg) cfg = cfg or mw.loadData(DATA_MODULE) local options, invokeArgs = {}, {} for k, v in pairs(args) do local optionKey = type(k) == 'string' and k:match('^_(.*)$') if optionKey then if type(v) == 'string' then v = v:match('^%s*(.-)%s*$') -- trim whitespace end if v ~= '' then options[optionKey] = v end else invokeArgs[k] = v end end -- Allow passing a nowiki invocation as an option. While this means users -- have to pass in the code twice, whitespace is preserved and &lt; etc. -- will work as intended. local nowikiCode = options.code options.code = nil local invocationObj = TableInvocation.new(invokeArgs, nowikiCode, cfg) local testCaseObj = TestCase.new(invocationObj, options, cfg) return tostring(testCaseObj) end function bridge.nowiki(args, cfg) cfg = cfg or mw.loadData(DATA_MODULE) -- Convert args beginning with _ for consistency with the normal bridge local newArgs = {} for k, v in pairs(args) do local normalName = type(k) == "string" and string.match(k, "^_(.*)$") if normalName then newArgs[normalName] = v else newArgs[k] = v end end local code = newArgs.code or newArgs[1] local invocationObj = NowikiInvocation.new(code, cfg) newArgs.code = nil newArgs[1] = nil -- Assume we want to see the code as we already passed it in. newArgs.showcode = newArgs.showcode or true local testCaseObj = TestCase.new(invocationObj, newArgs, cfg) return tostring(testCaseObj) end ------------------------------------------------------------------------------- -- Exports ------------------------------------------------------------------------------- local p = {} function p.main(frame, cfg) cfg = cfg or mw.loadData(DATA_MODULE) -- Load the wrapper config, if any. local wrapperConfig if frame.getParent then local title = frame:getParent():getTitle() local template = title:gsub(cfg.sandboxSubpagePattern, '') wrapperConfig = cfg.wrappers[template] end -- Work out the function we will call, use it to generate the config for -- Module:Arguments, and use Module:Arguments to find the arguments passed -- by the user. local func = wrapperConfig and wrapperConfig.func or 'table' local userArgs = require('Module:Arguments').getArgs(frame, { parentOnly = wrapperConfig, frameOnly = not wrapperConfig, trim = func ~= 'table', removeBlanks = func ~= 'table' }) -- Get default args and build the args table. User-specified args overwrite -- default args. local defaultArgs = wrapperConfig and wrapperConfig.args or {} local args = {} for k, v in pairs(defaultArgs) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return bridge[func](args, cfg) end function p._exportClasses() -- For testing return { Template = Template, TestCase = TestCase, NowikiInvocation = NowikiInvocation, TableInvocation = TableInvocation } end return p saiu0jsc1rxo0bujmsl0mtks0pxrp9l Module:Template test case/styles.css 828 52495 308462 2026-09-17T16:31:46Z Isma4l 41797 Bog cusub: /* {{pp-template}} */ .test-case-collapsible { width: 100%; border: 1px solid silver; padding: 0.2em; margin: 1em 0; margin-top: -1px; clear: both; color: inherit; box-sizing: border-box; } .test-case-collapsible .mw-collapsible-content > ul { margin-left: 0; } .mw-collapsible.test-case-collapsible.mw-made-collapsible .mw-collapsible-content { padding: 0.5em 1em; } .mw-collapsible.test-case-collapsible.mw-made-collapsible.mw-collapsed { margin-bottom: 0; marg... 308462 sanitized-css text/css /* {{pp-template}} */ .test-case-collapsible { width: 100%; border: 1px solid silver; padding: 0.2em; margin: 1em 0; margin-top: -1px; clear: both; color: inherit; box-sizing: border-box; } .test-case-collapsible .mw-collapsible-content > ul { margin-left: 0; } .mw-collapsible.test-case-collapsible.mw-made-collapsible .mw-collapsible-content { padding: 0.5em 1em; } .mw-collapsible.test-case-collapsible.mw-made-collapsible.mw-collapsed { margin-bottom: 0; margin-top: -1px; } div.mw-collapsible-content > ul > li { display: block; } .test-case-collapsible-b1 { background-color: var(--background-color-warning-subtle, #fdf2d5); margin: 1px; } .test-case-collapsible-b2 { background-color: var(--background-color-content-added, #a3d3ff); margin: 1px; } .test-case-collapsible-b3 { background-color: var(--background-color-success-subtle, #dff2eb); margin: 1px; } @media screen { html.skin-theme-clientpref-night .test-case-collapsible-b1 { background-color: #453217; } html.skin-theme-clientpref-night .test-case-collapsible-b2 { background-color: #233566; } html.skin-theme-clientpref-night .test-case-collapsible-b3 { background-color: #003500; } } @media screen and ( prefers-color-scheme: dark ) { html.skin-theme-clientpref-os .test-case-collapsible-b1 { background-color: #453217; } html.skin-theme-clientpref-os .test-case-collapsible-b2 { background-color: #233566; } html.skin-theme-clientpref-os .test-case-collapsible-b3 { background-color: #003500; } } r42sby19eiy8mqrh9eyydx3ttjg2v72 Module:Template test case/data 828 52496 308463 2026-09-17T16:32:40Z Isma4l 41797 Bog cusub: -- This module processes configuration data for use in -- [[Module:Template test case]]. It is loaded from the main module with -- mw.loadData. local cfg = require('Module:Template test case/config') local function escapePattern(s) s = s:gsub('%p', '%%%0') return s end -- Escape config items that need to be used as patterns. Doing it here is more -- efficient, as mw.loadData saves them from having to be computed for every -- test case on a page. cfg.templateNameMagicWordPatt... 308463 Scribunto text/plain -- This module processes configuration data for use in -- [[Module:Template test case]]. It is loaded from the main module with -- mw.loadData. local cfg = require('Module:Template test case/config') local function escapePattern(s) s = s:gsub('%p', '%%%0') return s end -- Escape config items that need to be used as patterns. Doing it here is more -- efficient, as mw.loadData saves them from having to be computed for every -- test case on a page. cfg.templateNameMagicWordPattern = escapePattern(cfg.templateNameMagicWord) cfg.sandboxSubpagePattern = '/' .. escapePattern(cfg.sandboxSubpage) .. '$' return cfg dmdplkk88kmnriu7s6pk3hhob51o8xa Template:Test case 10 52497 308464 2026-09-17T16:33:13Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude> 308464 wikitext text/x-wiki <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude> tqcbtoi20hh04qz7tcyj9c81ibksvas Template:Testcase table 10 52498 308465 2026-09-17T16:33:44Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} </noinclude> 308465 wikitext text/x-wiki <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} </noinclude> 0445uyzppdfnu1j4kj9ie42pyliyrbz Template:Testcase rows 10 52499 308466 2026-09-17T16:41:41Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude> 308466 wikitext text/x-wiki <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude> irr9qc03niujceohpr6rvkn46wvotik Template:Collapsible test case 10 52500 308467 2026-09-17T16:42:06Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude> 308467 wikitext text/x-wiki <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude> tqcbtoi20hh04qz7tcyj9c81ibksvas Template:Inline test case 10 52501 308468 2026-09-17T16:42:28Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude> 308468 wikitext text/x-wiki <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude> tqcbtoi20hh04qz7tcyj9c81ibksvas Template:Nowiki template demo 10 52502 308470 2026-09-17T16:44:56Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude> 308470 wikitext text/x-wiki <includeonly>{{#invoke:Template test case|main}}</includeonly><noinclude> {{documentation}} <!-- Categories go on the /doc subpage and interwikis go on Wikidata. --> </noinclude> tqcbtoi20hh04qz7tcyj9c81ibksvas Module:ScribuntoUnit 828 52503 308471 2026-09-17T16:46:11Z Isma4l 41797 Bog cusub: ------------------------------------------------------------------------------- -- Unit tests for Scribunto. ------------------------------------------------------------------------------- require('strict') local DebugHelper = {} local ScribuntoUnit = {} ScribuntoUnit.__meta = {} -- The cfg table contains all localisable strings and configuration, to make it -- easier to port this module to another wiki. local cfg = mw.loadData('Module:ScribuntoUnit/config') ------------------... 308471 Scribunto text/plain ------------------------------------------------------------------------------- -- Unit tests for Scribunto. ------------------------------------------------------------------------------- require('strict') local DebugHelper = {} local ScribuntoUnit = {} ScribuntoUnit.__meta = {} -- The cfg table contains all localisable strings and configuration, to make it -- easier to port this module to another wiki. local cfg = mw.loadData('Module:ScribuntoUnit/config') ------------------------------------------------------------------------------- -- Concatenates keys and values, ideal for displaying a template or parser function argument table. -- @param keySeparator glue between key and value (defaults to " = ") -- @param separator glue between different key-value pairs (defaults to ", ") -- @example concatWithKeys({a = 1, b = 2, c = 3}, ' => ', ', ') => "a => 1, b => 2, c => 3" -- function DebugHelper.concatWithKeys(table, keySeparator, separator) keySeparator = keySeparator or ' = ' separator = separator or ', ' local concatted = '' local i = 1 local first = true local unnamedArguments = true for k, v in pairs(table) do if first then first = false else concatted = concatted .. separator end if k == i and unnamedArguments then i = i + 1 concatted = concatted .. tostring(v) else unnamedArguments = false concatted = concatted .. tostring(k) .. keySeparator .. tostring(v) end end return concatted end ------------------------------------------------------------------------------- -- Compares two tables recursively (non-table values are handled correctly as well). -- @param ignoreMetatable if false, t1.__eq is used for the comparison -- function DebugHelper.deepCompare(t1, t2, ignoreMetatable) local type1 = type(t1) local type2 = type(t2) if type1 ~= type2 then return false end if type1 ~= 'table' then return t1 == t2 end local metatable = getmetatable(t1) if not ignoreMetatable and metatable and metatable.__eq then return t1 == t2 end for k1, v1 in pairs(t1) do local v2 = t2[k1] if v2 == nil or not DebugHelper.deepCompare(v1, v2) then return false end end for k2, v2 in pairs(t2) do if t1[k2] == nil then return false end end return true end ------------------------------------------------------------------------------- -- Raises an error with stack information -- @param details a table with error details -- - should have a 'text' key which is the error message to display -- - a 'trace' key will be added with the stack data -- - and a 'source' key with file/line number -- - a metatable will be added for error handling -- function DebugHelper.raise(details, level) level = (level or 1) + 1 details.trace = debug.traceback('', level) details.source = string.match(details.trace, '^%s*stack traceback:%s*(%S*: )') -- setmetatable(details, { -- __tostring: function() return details.text end -- }) error(details, level) end ------------------------------------------------------------------------------- -- when used in a test, that test gets ignored, and the skipped count increases by one. -- function ScribuntoUnit:markTestSkipped() DebugHelper.raise({ScribuntoUnit = true, skipped = true}, 3) end ------------------------------------------------------------------------------- -- Unconditionally fail a test -- @param message optional description of the test -- function ScribuntoUnit:fail(message) DebugHelper.raise({ScribuntoUnit = true, text = "Test failed", message = message}, 2) end ------------------------------------------------------------------------------- -- Checks that the input is true -- @param message optional description of the test -- @param level optional number to raise error stack level by -- function ScribuntoUnit:assertTrue(actual, message, level) if not actual then DebugHelper.raise({ScribuntoUnit = true, text = string.format("Failed to assert that %s is true", tostring(actual)), message = message}, 2 + (level or 0)) end end ------------------------------------------------------------------------------- -- Checks that the input is false -- @param message optional description of the test -- @param level optional number to raise error stack level by -- function ScribuntoUnit:assertFalse(actual, message, level) if actual then DebugHelper.raise({ScribuntoUnit = true, text = string.format("Failed to assert that %s is false", tostring(actual)), message = message}, 2 + (level or 0)) end end ------------------------------------------------------------------------------- -- Checks an input string contains the expected string -- @param message optional description of the test -- @param plain search is made with a plain string instead of a ustring pattern -- @param level optional number to raise error stack level by -- function ScribuntoUnit:assertStringContains(pattern, s, plain, message, level) if type(pattern) ~= 'string' then DebugHelper.raise({ ScribuntoUnit = true, text = mw.ustring.format("Pattern type error (expected string, got %s)", type(pattern)), message = message }, 2 + (level or 0)) end if type(s) ~= 'string' then DebugHelper.raise({ ScribuntoUnit = true, text = mw.ustring.format("String type error (expected string, got %s)", type(s)), message = message }, 2 + (level or 0)) end if not mw.ustring.find(s, pattern, nil, plain) then DebugHelper.raise({ ScribuntoUnit = true, text = mw.ustring.format('Failed to find %s "%s" in string "%s"', plain and "plain string" or "pattern", pattern, s), message = message }, 2 + (level or 0)) end end ------------------------------------------------------------------------------- -- Checks an input string doesn't contain the expected string -- @param message optional description of the test -- @param plain search is made with a plain string instead of a ustring pattern -- @param level optional number to raise error stack level by -- function ScribuntoUnit:assertNotStringContains(pattern, s, plain, message, level) if type(pattern) ~= 'string' then DebugHelper.raise({ ScribuntoUnit = true, text = mw.ustring.format("Pattern type error (expected string, got %s)", type(pattern)), message = message }, 2 + (level or 0)) end if type(s) ~= 'string' then DebugHelper.raise({ ScribuntoUnit = true, text = mw.ustring.format("String type error (expected string, got %s)", type(s)), message = message }, 2 + (level or 0)) end local i, j = mw.ustring.find(s, pattern, nil, plain) if i then local match = mw.ustring.sub(s, i, j) DebugHelper.raise({ ScribuntoUnit = true, text = mw.ustring.format('Found match "%s" for %s "%s"', match, plain and "plain string" or "pattern", pattern), message = message }, 2 + (level or 0)) end end ------------------------------------------------------------------------------- -- Checks that an input has the expected value. -- @param message optional description of the test -- @example assertEquals(4, add(2,2), "2+2 should be 4") -- @param level optional number to raise error stack level by -- function ScribuntoUnit:assertEquals(expected, actual, message, level) if type(expected) == 'number' and type(actual) == 'number' then self:assertWithinDelta(expected, actual, 1e-8, message, (level or 0) + 1) elseif expected ~= actual then DebugHelper.raise({ ScribuntoUnit = true, text = string.format("Failed to assert that %s equals expected %s", tostring(actual), tostring(expected)), actual = actual, expected = expected, message = message, }, 2 + (level or 0)) end end ------------------------------------------------------------------------------- -- Checks that an input does not have the expected value. -- @param message optional description of the test -- @example assertNotEquals(5, add(2,2), "2+2 should not be 5") -- @param level optional number to raise error stack level by -- function ScribuntoUnit:assertNotEquals(expected, actual, message, level) if type(expected) == 'number' and type(actual) == 'number' then self:assertNotWithinDelta(expected, actual, 1e-8, message, (level or 0) + 1) elseif expected == actual then DebugHelper.raise({ ScribuntoUnit = true, text = string.format("Failed to assert that %s does not equal expected %s", tostring(actual), tostring(expected)), actual = actual, expected = expected, message = message, }, 2 + (level or 0)) end end ------------------------------------------------------------------------------- -- Validates that both the expected and actual values are numbers -- @param message optional description of the test -- @param level number to raise error stack level by -- local function validateNumbers(expected, actual, message, level) if type(expected) ~= "number" then DebugHelper.raise({ ScribuntoUnit = true, text = string.format("Expected value %s is not a number", tostring(expected)), actual = actual, expected = expected, message = message, }, 3 + level) end if type(actual) ~= "number" then DebugHelper.raise({ ScribuntoUnit = true, text = string.format("Actual value %s is not a number", tostring(actual)), actual = actual, expected = expected, message = message, }, 3 + level) end end ------------------------------------------------------------------------------- -- Checks that 'actual' is within 'delta' of 'expected'. -- @param message optional description of the test -- @param level optional number to raise error stack level by -- @example assertWithinDelta(1/3, 3/9, 0.000001, "3/9 should be 1/3") function ScribuntoUnit:assertWithinDelta(expected, actual, delta, message, level) validateNumbers(expected, actual, message, level or 0) local diff = expected - actual if diff < 0 then diff = - diff end -- instead of importing math.abs if diff > delta then DebugHelper.raise({ ScribuntoUnit = true, text = string.format("Failed to assert that %f is within %f of expected %f", actual, delta, expected), actual = actual, expected = expected, message = message, }, 2 + (level or 0)) end end ------------------------------------------------------------------------------- -- Checks that 'actual' is not within 'delta' of 'expected'. -- @param message optional description of the test -- @param level optional number to raise error stack level by -- @example assertNotWithinDelta(1/3, 2/3, 0.000001, "1/3 should not be 2/3") function ScribuntoUnit:assertNotWithinDelta(expected, actual, delta, message, level) validateNumbers(expected, actual, message, level or 0) local diff = expected - actual if diff < 0 then diff = - diff end -- instead of importing math.abs if diff <= delta then DebugHelper.raise({ ScribuntoUnit = true, text = string.format("Failed to assert that %f is not within %f of expected %f", actual, delta, expected), actual = actual, expected = expected, message = message, }, 2 + (level or 0)) end end ------------------------------------------------------------------------------- -- Checks that a table has the expected value (including sub-tables). -- @param message optional description of the test -- @param level optional number to raise error stack level by -- @example assertDeepEquals({{1,3}, {2,4}}, partition(odd, {1,2,3,4})) function ScribuntoUnit:assertDeepEquals(expected, actual, message, level) if not DebugHelper.deepCompare(expected, actual) then if type(expected) == 'table' then expected = mw.dumpObject(expected) end if type(actual) == 'table' then actual = mw.dumpObject(actual) end DebugHelper.raise({ ScribuntoUnit = true, text = string.format("Failed to assert that %s equals expected %s", tostring(actual), tostring(expected)), actual = actual, expected = expected, message = message, }, 2 + (level or 0)) end end ------------------------------------------------------------------------------- -- Checks that a wikitext gives the expected result after processing. -- @param message optional description of the test -- @example assertResultEquals("Hello world", "{{concat|Hello|world}}") function ScribuntoUnit:assertResultEquals(expected, text, message) local frame = self.frame local actual = frame:preprocess(text) if expected ~= actual then DebugHelper.raise({ ScribuntoUnit = true, text = string.format("Failed to assert that %s equals expected %s after preprocessing", text, tostring(expected)), actual = actual, actualRaw = text, expected = expected, message = message, }, 2) end end ------------------------------------------------------------------------------- -- Checks that two wikitexts give the same result after processing. -- @param message optional description of the test -- @example assertSameResult("{{concat|Hello|world}}", "{{deleteLastChar|Hello world!}}") function ScribuntoUnit:assertSameResult(text1, text2, message) local frame = self.frame local processed1 = frame:preprocess(text1) local processed2 = frame:preprocess(text2) if processed1 ~= processed2 then DebugHelper.raise({ ScribuntoUnit = true, text = string.format("Failed to assert that %s equals expected %s after preprocessing", processed1, processed2), actual = processed1, actualRaw = text1, expected = processed2, expectedRaw = text2, message = message, }, 2) end end ------------------------------------------------------------------------------- -- Checks that a parser function gives the expected output. -- @param message optional description of the test -- @example assertParserFunctionEquals("Hello world", "msg:concat", {"Hello", " world"}) function ScribuntoUnit:assertParserFunctionEquals(expected, pfname, args, message) local frame = self.frame local actual = frame:callParserFunction{ name = pfname, args = args} if expected ~= actual then DebugHelper.raise({ ScribuntoUnit = true, text = string.format("Failed to assert that %s with args %s equals expected %s after preprocessing", DebugHelper.concatWithKeys(args), pfname, expected), actual = actual, actualRaw = pfname, expected = expected, message = message, }, 2) end end ------------------------------------------------------------------------------- -- Checks that a template gives the expected output. -- @param message optional description of the test -- @example assertTemplateEquals("Hello world", "concat", {"Hello", " world"}) function ScribuntoUnit:assertTemplateEquals(expected, template, args, message) local frame = self.frame local actual = frame:expandTemplate{ title = template, args = args} if expected ~= actual then DebugHelper.raise({ ScribuntoUnit = true, text = string.format("Failed to assert that %s with args %s equals expected %s after preprocessing", DebugHelper.concatWithKeys(args), template, expected), actual = actual, actualRaw = template, expected = expected, message = message, }, 2) end end ------------------------------------------------------------------------------- -- Checks whether a function throws an error -- @param fn the function to test -- @param expectedMessage optional the expected error message -- @param message optional description of the test -- @param varargs optional arguments to be passed to fn function ScribuntoUnit:assertThrows(fn, expectedMessage, message, ...) local succeeded, actualMessage = pcall(fn, ...) if succeeded then DebugHelper.raise({ ScribuntoUnit = true, text = 'Expected exception but none was thrown', message = message, }, 2) end -- For strings, strip the line number added to the error message actualMessage = type(actualMessage) == 'string' and string.match(actualMessage, 'Module:[^:]*:[0-9]*: (.*)') or actualMessage local messagesMatch = DebugHelper.deepCompare(expectedMessage, actualMessage) if expectedMessage and not messagesMatch then DebugHelper.raise({ ScribuntoUnit = true, expected = expectedMessage, actual = actualMessage, text = string.format('Expected exception with message %s, but got message %s', tostring(expectedMessage), tostring(actualMessage) ), message = message }, 2) end end ------------------------------------------------------------------------------- -- Checks whether a function doesn't throw an error -- @param fn the function to test -- @param message optional description of the test -- @param varargs optional arguments to be passed to fn function ScribuntoUnit:assertDoesNotThrow(fn, message, ...) local succeeded, actualMessage = pcall(fn, ...) if succeeded then return end -- For strings, strip the line number added to the error message actualMessage = type(actualMessage) == 'string' and string.match(actualMessage, 'Module:[^:]*:[0-9]*: (.*)') or actualMessage DebugHelper.raise({ ScribuntoUnit = true, actual = actualMessage, text = string.format('Expected no exception, but got exception with message %s', tostring(actualMessage) ), message = message }, 2) end ------------------------------------------------------------------------------- -- Set up metatable ScribuntoUnit.__meta.__index = ScribuntoUnit function ScribuntoUnit.__meta:__newindex(key, value) if type(key) == "string" and key:find('^test') and type(value) == "function" then -- Store test functions in the order they were defined table.insert(self._tests, {name = key, test = value}) else rawset(self, key, value) end end ------------------------------------------------------------------------------- -- Creates a new test suite. -- function ScribuntoUnit.new() local self = {} self._tests = {} setmetatable(self, ScribuntoUnit.__meta) self.run = function(frame) return ScribuntoUnit.run(self, frame) end return self end ------------------------------------------------------------------------------- -- Resets global counters -- function ScribuntoUnit:init(frame) self.frame = frame or mw.getCurrentFrame() self.successCount = 0 self.failureCount = 0 self.skipCount = 0 self.results = {} end ------------------------------------------------------------------------------- -- Runs a single testcase -- @param name test nume -- @param test function containing assertions -- function ScribuntoUnit:runTest(name, test) local success, details = pcall(test, self) if success then self.successCount = self.successCount + 1 table.insert(self.results, {name = name, success = true}) elseif type(details) ~= 'table' or not details.ScribuntoUnit then -- a real error, not a failed assertion self.failureCount = self.failureCount + 1 table.insert(self.results, {name = name, error = true, message = 'Lua error -- ' .. tostring(details)}) elseif details.skipped then self.skipCount = self.skipCount + 1 table.insert(self.results, {name = name, skipped = true}) else self.failureCount = self.failureCount + 1 local message = details.source or "" if details.message then message = message .. details.message .. "\n" end message = message .. details.text table.insert(self.results, {name = name, error = true, message = message, expected = details.expected, actual = details.actual, testname = details.message}) end end ------------------------------------------------------------------------------- -- Runs all tests and displays the results. -- function ScribuntoUnit:runSuite(frame) self:init(frame) for i, testDetails in ipairs(self._tests) do self:runTest(testDetails.name, testDetails.test) end return { successCount = self.successCount, failureCount = self.failureCount, skipCount = self.skipCount, results = self.results, } end ------------------------------------------------------------------------------- -- #invoke entry point for running the tests. -- Can be called without a frame, in which case it will use mw.log for output -- @param displayMode see displayResults() -- function ScribuntoUnit:run(frame) local testData = self:runSuite(frame) if frame and frame.args then return self:displayResults(testData, frame.args.displayMode or 'table') else return self:displayResults(testData, 'log') end end ------------------------------------------------------------------------------- -- Displays test results -- @param displayMode: 'table', 'log' or 'short' -- function ScribuntoUnit:displayResults(testData, displayMode) if displayMode == 'table' then return self:displayResultsAsTable(testData) elseif displayMode == 'log' then return self:displayResultsAsLog(testData) elseif displayMode == 'short' then return self:displayResultsAsShort(testData) elseif displayMode == 'enum' then return self:displayResultsAsEnum(testData) else error('unknown display mode') end end function ScribuntoUnit:displayResultsAsLog(testData) if testData.failureCount > 0 then mw.log('FAILURES!!!') elseif testData.skipCount > 0 then mw.log('Some tests could not be executed without a frame and have been skipped. Invoke this test suite as a template to run all tests.') end mw.log(string.format('Assertions: success: %d, error: %d, skipped: %d', testData.successCount, testData.failureCount, testData.skipCount)) mw.log('-------------------------------------------------------------------------------') for _, result in ipairs(testData.results) do if result.error then mw.log(string.format('%s: %s', result.name, result.message)) end end end function ScribuntoUnit:displayResultsAsShort(testData) local text = string.format(cfg.shortResultsFormat, testData.successCount, testData.failureCount, testData.skipCount) if testData.failureCount > 0 then text = '<span class="error">' .. text .. '</span>' end return text end function ScribuntoUnit:displayResultsAsEnum(testData) if (testData.failureCount > 0) then return 'fail' elseif (testData.skipCount > 0 and testData.successCount == 0) then return 'skipped' else return 'success' end end function ScribuntoUnit:displayResultsAsTable(testData) local successIcon, failIcon = self.frame:preprocess(cfg.successIndicator), self.frame:preprocess(cfg.failureIndicator) local text = '' if testData.failureCount > 0 then local msg = mw.message.newRawMessage(cfg.failureSummary, testData.failureCount):plain() msg = self.frame:preprocess(msg) if cfg.failureCategory then msg = cfg.failureCategory .. msg end text = text .. failIcon .. ' ' .. msg .. '\n' else text = text .. successIcon .. ' ' .. cfg.successSummary .. '\n' end text = text .. '{| class="wikitable scribunto-test-table"\n' text = text .. '!\n! ' .. cfg.nameString .. '\n! ' .. cfg.expectedString .. '\n! ' .. cfg.actualString .. '\n' for _, result in ipairs(testData.results) do text = text .. '|-\n' if result.error then text = text .. '| ' .. failIcon .. '\n| ' if (result.expected and result.actual) then local name = result.name if result.testname then name = name .. ' / ' .. result.testname end text = text .. mw.text.nowiki(name) .. '\n| ' .. mw.text.nowiki(tostring(result.expected)) .. '\n| ' .. mw.text.nowiki(tostring(result.actual)) .. '\n' else text = text .. mw.text.nowiki(result.name) .. '\n| ' .. ' colspan="2" | ' .. mw.text.nowiki(result.message) .. '\n' end else text = text .. '| ' .. successIcon .. '\n| ' .. mw.text.nowiki(result.name) .. '\n|\n|\n' end end text = text .. '|}\n' return text end return ScribuntoUnit 6ndvyy4oz3v3i8fjoxts3ofs01uwk3h Module:UnitTests 828 52504 308472 2026-09-17T16:47:45Z Isma4l 41797 Bog cusub: -- UnitTester provides unit testing for other Lua scripts. For details see [[Wikipedia:Lua#Unit testing]]. -- For user documentation see above. local UnitTester = {} -- The cfg table contains all localisable strings and configuration, to make it -- easier to port this module to another wiki. local cfg = mw.loadData('Module:UnitTests/config') local frame, tick, cross, should_highlight local result_table = {n = 0} local result_table_mt = { insert = function (self, ...) local... 308472 Scribunto text/plain -- UnitTester provides unit testing for other Lua scripts. For details see [[Wikipedia:Lua#Unit testing]]. -- For user documentation see above. local UnitTester = {} -- The cfg table contains all localisable strings and configuration, to make it -- easier to port this module to another wiki. local cfg = mw.loadData('Module:UnitTests/config') local frame, tick, cross, should_highlight local result_table = {n = 0} local result_table_mt = { insert = function (self, ...) local n = self.n for i = 1, select('#', ...) do local val = select(i, ...) if val ~= nil then n = n + 1 self[n] = val end end self.n = n end, insert_format = function (self, ...) self:insert(string.format(...)) end, concat = table.concat } result_table_mt.__index = result_table_mt setmetatable(result_table, result_table_mt) local num_failures_sandbox = 0 local num_failures = 0 local num_runs = 0 local function first_difference(s1, s2) s1, s2 = tostring(s1), tostring(s2) if s1 == s2 then return '' end local max = math.min(#s1, #s2) for i = 1, max do if s1:sub(i, i) ~= s2:sub(i, i) then return i end end return max + 1 end local function add_diff_highlighting(str) if mw.ustring.find(str, "%s") then return '<span style="background-color: var(--wikt-palette-red-4, pink);">' .. string.gsub(str, " ", "&nbsp;") .. '</span>' else return '<span style="color: var(--wikt-palette-red-9, red);">' .. str .. '</span>' end end local is_combining = require("Module:Unicode data").is_combining local function find_noncombining(str, i, incr) while true do local ch = mw.ustring.sub(str, i, i) if ch == "" or not is_combining(mw.ustring.byte(ch)) then return i end i = i + incr end end -- Highlight character where a difference was found. Start highlight at first -- non-combining character before the position. End it after the first non- -- combining characters after the position. local function highlight_difference(actual, expected, differs_at) if type(differs_at) ~= "number" or not (actual and expected) then return actual end differs_at = find_noncombining(expected, differs_at, -1) local i = find_noncombining(actual, differs_at, -1) local j = find_noncombining(actual, differs_at + 1, 1) j = j - 1 return mw.ustring.sub(actual, 1, i - 1) .. add_diff_highlighting(mw.ustring.sub(actual, i, j)) .. mw.ustring.sub(actual, j + 1, -1) end local function return_varargs(...) return ... end function UnitTester:calculate_output(text, expected, actual, options) -- Set up some variables for throughout for ease num_runs = num_runs + 1 options = options or {} -- Fix any stripmarkers if asked to do so to prevent incorrect fails local compared_expected = expected local compared_actual = actual if options.templatestyles then local pattern = '(\127[^\127]*UNIQ%-%-templatestyles%-)(%x+)(%-QINU[^\127]*\127)' local _, expected_stripmarker_id = compared_expected:match(pattern) -- when module rendering has templatestyles strip markers, use ID from expected to prevent false test fail if expected_stripmarker_id then compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- replace actual id with expected id; ignore second capture in pattern compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- account for other strip markers end end if options.stripmarker then local pattern = '(\127[^\127]*UNIQ%-%-%l+%-)(%x+)(%-%-?QINU[^\127]*\127)' local _, expected_stripmarker_id = compared_expected:match(pattern) if expected_stripmarker_id then compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') end end -- Perform the comparison local success = compared_actual == compared_expected if options.noexpectation and compared_expected == '' then success = true end if not success then num_failures = num_failures + 1 end -- Sort the wikitext for displaying the results if options.combined then -- We need 2 rows available for the expected and actual columns -- Top one is parsed, bottom is unparsed local diff, differs_at = 0, self.differs_at and (' \n| rowspan=2|' .. first_difference(compared_expected, compared_actual)) or '' -- Local copies of tick/cross to allow for highlighting local highlight = (should_highlight and not success and 'style="background: #fc0;" ') or '' local highlight_diff = return_varargs if self.differs_at then diff = first_difference(compared_expected, compared_actual) differs_at = ' \n| rowspan=2|' .. diff if type(diff) == "number" then highlight_diff = highlight_difference end end result_table:insert( -- Start output '| ', highlight, 'rowspan=2|', success and tick or cross, -- Tick/Cross (2 rows) ' \n| rowspan=2|', mw.text.nowiki(text), ' \n| ', -- Text used for the test (2 rows) expected, ' \n| ', highlight_diff(actual, expected, diff), -- The parsed outputs (in the 1st row) differs_at, ' \n|-\n| ', -- Where any relevant difference was (2 rows) mw.text.nowiki(expected), ' \n| ', highlight_diff(mw.text.nowiki(actual), mw.text.nowiki(actual), first_difference(mw.text.nowiki(expected), mw.text.nowiki(actual))), -- The unparsed outputs (in the 2nd row) '\n|-\n' -- End output ) else -- Display normally with whichever option was preferred (nowiki/parsed) local differs_at = '' local formatting = options.nowiki and mw.text.nowiki or return_varargs local highlight = (should_highlight and not success and 'style="background: #fc0;" |') or '' local formated_expected, formated_actual = formatting(expected), formatting(actual) if self.differs_at then local diff = first_difference(compared_expected, compared_actual) differs_at = ' \n| ' .. diff if type(diff) == "number" then formated_actual = highlight_difference(formated_actual, formated_expected, first_difference(formated_actual, formated_expected)) end end result_table:insert( -- Start output '| ', highlight, success and tick or cross, -- Tick/Cross ' \n| ', mw.text.nowiki(text), ' \n| ', -- Text used for the test formated_expected, ' \n| ', formated_actual, -- The formatted outputs differs_at, -- Where any relevant difference was '\n|-\n' -- End output ) end end function UnitTester:preprocess_equals(text, expected, options) local actual = frame:preprocess(text) self:calculate_output(text, expected, actual, options) end function UnitTester:preprocess_equals_many(prefix, suffix, cases, options) for _, case in ipairs(cases) do self:preprocess_equals(prefix .. case[1] .. suffix, case[2], options) end end function UnitTester:preprocess_equals_preprocess(text1, text2, options) local actual = frame:preprocess(text1) local expected = frame:preprocess(text2) self:calculate_output(text1, expected, actual, options) end function UnitTester:preprocess_equals_compare(live, sandbox, expected, options) options = options or {} local live_text = frame:preprocess(live) local sandbox_text = frame:preprocess(sandbox) local highlight_live = false local highlight_sandbox = false num_runs = num_runs + 1 local compared_live = live_text local compared_sandbox = sandbox_text local compared_expected = expected if options.templatestyles then local pattern = '(\127[^\127]*UNIQ%-%-templatestyles%-)(%x+)(%-QINU[^\127]*\127)' local _, expected_stripmarker_id = compared_expected:match(pattern) -- when module rendering has templatestyles strip markers, use ID from expected to prevent false test fail if expected_stripmarker_id then compared_live = compared_live:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- replace actual id with expected id; ignore second capture in pattern compared_sandbox = compared_sandbox:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- replace actual id with expected id; ignore second capture in pattern compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- account for other strip markers end end if options.stripmarker then local pattern = '(\127[^\127]*UNIQ%-%-%l+%-)(%x+)(%-%-?QINU[^\127]*\127)' local _, expected_stripmarker_id = compared_expected:match(pattern) if expected_stripmarker_id then compared_live = compared_live:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') compared_sandbox = compared_sandbox:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') end end local success = compared_live == compared_expected and compared_sandbox == compared_expected if not success then if compared_live ~= compared_expected then num_failures = num_failures + 1 highlight_live = true end if compared_sandbox ~= compared_expected then num_failures_sandbox = num_failures_sandbox + 1 highlight_sandbox = true end end -- Sort the wikitext for displaying the results if options.combined then -- We need 2 rows available for the expected, live, and sandbox columns -- Top one is parsed, bottom is unparsed local differs_at = '' local highlight_diff_live, highlight_diff_sandbox = return_varargs, return_varargs local diff_live, diff_sandbox = 0,0 if self.differs_at then diff_live = first_difference(compared_expected, compared_live) diff_sandbox = first_difference(compared_expected, compared_sandbox) differs_at = ' \n| rowspan=2|' .. (diff_live or diff_sandbox) if type(diff_live) == "number" then highlight_diff_live = highlight_difference end if type(diff_sandbox) == "number" then highlight_diff_sandbox = highlight_difference end end result_table:insert( '| ', 'rowspan=2|', not highlight_live and tick or cross, not highlight_sandbox and tick or cross, ' \n| rowspan=2|', mw.text.nowiki(live), should_highlight and highlight_live and ' \n| style="background: #fc0;" | ' or ' \n| ', highlight_diff_live(live_text, expected, diff_live), should_highlight and highlight_sandbox and ' \n| style="background: #fc0;" | ' or ' \n| ', highlight_diff_sandbox(sandbox_text, expected, diff_sandbox), ' \n| ', expected, differs_at, should_highlight and highlight_sandbox and ' \n|-\n| style="background: #fc0;" | ' or ' \n|-\n| ', highlight_diff_live(mw.text.nowiki(live_text), mw.text.nowiki(expected), first_difference(mw.text.nowiki(expected), mw.text.nowiki(live_text))), should_highlight and highlight_sandbox and ' \n| style="background: #fc0;" | ' or ' \n| ', highlight_diff_sandbox(mw.text.nowiki(sandbox_text), mw.text.nowiki(expected), first_difference(mw.text.nowiki(expected), mw.text.nowiki(sandbox_text))), ' \n| ', mw.text.nowiki(expected), '\n|-\n' ) else -- Display normally with whichever option was preferred (nowiki/parsed) local differs_at = '' local formatting = options.nowiki and mw.text.nowiki or return_varargs local formated_expected, formated_live, formated_sandbox = formatting(expected), formatting(live_text), formatting(sandbox_text) if self.differs_at then local diff = first_difference(compared_expected, live_text) local diff2 = first_difference(compared_expected, sandbox_text) differs_at = ' \n| ' .. (diff or diff2) if type(diff) == "number" then formated_live = highlight_difference(formated_live, formated_expected, first_difference(formated_live, formated_expected)) end if type(diff2) == "number" then formated_sandbox = highlight_difference(formated_sandbox, formated_expected, first_difference(formated_sandbox, formated_expected)) end end result_table:insert( '| ', not highlight_live and tick or cross, not highlight_sandbox and tick or cross, ' \n| ', mw.text.nowiki(live), should_highlight and highlight_live and ' \n| style="background: #fc0;" | ' or ' \n| ', formated_live, should_highlight and highlight_sandbox and ' \n| style="background: #fc0;" | ' or ' \n| ', formated_sandbox, ' \n| ', formated_expected, differs_at, '\n|-\n' ) end end function UnitTester:preprocess_equals_preprocess_many(prefix1, suffix1, prefix2, suffix2, cases, options) for _, case in ipairs(cases) do self:preprocess_equals_preprocess(prefix1 .. case[1] .. suffix1, prefix2 .. (case[2] and case[2] or case[1]) .. suffix2, options) end end function UnitTester:preprocess_equals_sandbox_many(module, function_name, cases, options) for _, case in ipairs(cases) do local live = module .. '|' .. function_name .. '|' .. case[1] .. '}}' local sandbox = module .. '/sandbox|' .. function_name .. '|' .. case[1] .. '}}' self:preprocess_equals_compare(live, sandbox, case[2], options) end end function UnitTester:equals(name, actual, expected, options) num_runs = num_runs + 1 if actual == expected then result_table:insert('| ', tick) else result_table:insert('| ', cross) num_failures = num_failures + 1 end local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs local differs_at = self.differs_at and (' \n| ' .. first_difference(expected, actual)) or '' local display = options and options.display or return_varargs result_table:insert(' \n| ', name, ' \n| ', formatting(tostring(display(expected))), ' \n| ', formatting(tostring(display(actual))), differs_at, '\n|-\n') end local deep_compare; do --//pulled from [[wikt:Module:table/deepEquals]] local function is_eq(a, b, seen, include_mt) -- If `a` and `b` have been compared before, return the memoized result. This will usually be true, since failures normally fail the whole check outright, but match failures are tolerated during the laborious check without this happening, since it compares key/value pairs until it finds a match, so it could be false. local memo_a = seen[a] if memo_a then local result = memo_a[b] if result ~= nil then return result end -- To avoid recursive references causing infinite loops, assume the tables currently being compared are equivalent by memoizing the comparison as true; this will be corrected to false if there's a match failure. memo_a[b] = true else memo_a = {[b] = true} seen[a] = memo_a end -- Don't bother checking `memo_b` for `a`, since if `a` and `b` had been compared before then `b` would be in `memo_a`, but it isn't. local memo_b = seen[b] if memo_b then memo_b[a] = true else memo_b = {[a] = true} seen[b] = memo_b end -- If `include_mt` is set, check the metatables are equivalent. if include_mt then local mt_a, mt_b = getmetatable(a), getmetatable(b) if not (mt_a == mt_b or type(mt_a) == "table" and type(mt_b) == "table" and is_eq(mt_a, mt_b, seen, true)) then memo_a[b], memo_b[a] = false, false return false end end -- Copy all key/values pairs in `b` to `remaining_b`, and count the size: this uses `pairs`, which will also be used to iterate over `a`, ensuring that `a` and `b` are iterated over using the same iterator. This is necessary to ensure that `deepEquals(a, b)` and `deepEquals(b, a)` always give the same result. Simply iterating over `a` while accessing keys in `b` for comparison would ignore any `__pairs` metamethod that `b` has, which could cause asymmetrical outputs if `__pairs` returns more or less than the complete set of key/value pairs accessible via `__index`, so using `pairs` for both `a` and `b` prevents this. -- TODO: handle exotic `__pairs` methods which return the same key multiple times with different values. local remaining_b, size_b = {}, 0 for k_b, v_b in pairs(b) do remaining_b[k_b], size_b = v_b, size_b + 1 end -- Fast check: iterate over the keys in `a`, checking if an equivalent value exists at the same key in `remaining_b`. As matches are found, key/value pairs are removed from `remaining_b`. If any keys in `a` or `remaining_b` are tables, the fast check will only work if the exact same object exists as a key in the other table. Any others from `a` that don't match anything in `remaining_b` are added to `remaining_a`, while those in `remaining_b` that weren't found will still remain once the loop ends. `remaining_a` and `remaining_b` are then compared at the end with the laborious check. local size_a, remaining_a = 0 for k, v_a in pairs(a) do local v_b = remaining_b[k] -- If `k` isn't in `remaining_b`, `a` and `b` can't be equivalent unless it's a table. if v_b == nil then if type(k) ~= "table" then memo_a[b], memo_b[a] = false, false return false -- Otherwise, add the `k`/`v_a` pair to `remaining_a` for the laborious check. elseif not remaining_a then remaining_a = {} end remaining_a[k], size_a = v_a, size_a + 1 -- Otherwise, if `k` exists in `a` and `remaining_b`, `v_a` and `v_b` must be equivalent for there to be a match. elseif v_a == v_b or type(v_a) == "table" and type(v_b) == "table" and is_eq(v_a, v_b, seen, include_mt) then remaining_b[k], size_b = nil, size_b - 1 else memo_a[b], memo_b[a] = false, false return false end end -- Must be the same number of remaining keys in each table. if size_a ~= size_b then memo_a[b], memo_b[a] = false, false return false -- If the size is 0, there's nothing left to check. elseif size_a == 0 then return true end -- Laborious check: since it's not possible to use table lookups to check if two keys are equivalent when they're tables, check each key/value pair in `remaining_a` against every key/value pair in `remaining_b` until a match is found, removing the matching key/value pair from `remaining_b` each time, to ensure one-to-one equivalence. for k_a, v_a in next, remaining_a do local success for k_b, v_b in next, remaining_b do -- Keys/value pairs must be equivalent in order to match. if ( -- More efficient to compare the values first, as they might not be tables. (v_a == v_b or type(v_a) == "table" and type(v_b) == "table" and is_eq(v_a, v_b, seen, include_mt)) and (k_a == k_b or type(k_a) == "table" and type(k_b) == "table" and is_eq(k_a, k_b, seen, include_mt)) ) then -- Remove matched key from `remaining_b`, and break the inner loop. success, remaining_b[k_b] = true, nil break end end -- Fail if `remaining_b` runs out of keys, as the `k_a`/`v_a` pair still hasn't matched. if not success then memo_a[b], memo_b[a] = false, false return false end end -- If every key/value pair in `remaining_a` matched with one in `remaining_b`, `a` and `b` must be equivalent. Note that `remaining_b` will now be empty, since the laborious check only starts if `remaining_a` and `remaining_b` are the same size. return true end deep_compare = function(a, b, ignore_mt) -- Do simple checks before calling is_eq to avoid generating an unnecessary memo. -- Simple equality check and type check; if not a ~= b, a and b can only be equivalent if they're both tables. return a == b or type(a) == "table" and type(b) == "table" and is_eq(a, b, {}, not ignore_mt) end end local function val_to_str(obj) local function table_key_to_str(k) if type(k) == 'string' and mw.ustring.match(k, '^[_%a][_%a%d]*$') then return k else return '[' .. val_to_str(k) .. ']' end end if type(obj) == 'string' then obj = mw.ustring.gsub(obj, '\n', '\\n') if mw.ustring.match(mw.ustring.gsub(obj, '[^\'"]', ''), '^"+$') then return "'" .. obj .. "'" end return '"' .. mw.ustring.gsub(obj, '"', '\\"' ) .. '"' elseif type(obj) == 'table' then local result, checked = {}, {} for k, v in ipairs(obj) do table.insert(result, val_to_str(v)) checked[k] = true end for k, v in pairs(obj) do if not checked[k] then table.insert(result, table_key_to_str(k) .. '=' .. val_to_str(v)) end end return '{' .. table.concat(result, ',') .. '}' else return tostring(obj) end end local function insert_differences(keys, t1, t2) for k, v1 in pairs(t1) do local v2 = t2[k] if v2 == nil or not deep_compare(v1, v2, true) then table.insert(keys, k) end end end local function get_differing_keys(t1, t2) local ty1 = type(t1) if not (ty1 == type(t2) and ty1 == "table") then return nil end local keys = {} insert_differences(keys, t1, t2) insert_differences(keys, t2, t1) return keys end local function extract_keys(t, keys) if not keys then return t end local new_t = {} for _, key in ipairs(keys) do new_t[key] = t[key] end return new_t end function UnitTester:equals_deep(name, actual, expected, options) num_runs = num_runs + 1 local actual_str, expected_str local success = deep_compare(actual, expected, true) if success then result_table:insert('| ', tick) if options and options.show_table_difference then actual_str = '' expected_str = '' end else if options and options.show_table_difference then local keys = get_differing_keys(actual, expected) actual_str = val_to_str(extract_keys(actual, keys)) expected_str = val_to_str(extract_keys(expected, keys)) end end if (not options) or not options.show_table_difference then actual_str = val_to_str(actual) expected_str = val_to_str(expected) end local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs local differs_at = self.differs_at and (' \n| ' .. first_difference(expected_str, actual_str)) or '' result_table:insert(' \n| ', name, ' \n| ', formatting(expected_str), ' \n| ', formatting(actual_str), differs_at, '\n|-\n') end function UnitTester:iterate(examples, func) require 'libraryUtil'.checkType('iterate', 1, examples, 'table') if type(func) == 'string' then func = self[func] elseif type(func) ~= 'function' then error(("bad argument #2 to 'iterate' (expected function or string, got %s)") :format(type(func)), 2) end for i, example in ipairs(examples) do if type(example) == 'table' then func(self, unpack(example)) elseif type(example) == 'string' then self:heading(example) else error(('bad example #%d (expected table, got %s)') :format(i, type(example)), 2) end end end function UnitTester:heading(text) result_table:insert_format(' ! colspan="%u" style="text-align: left;" | %s \n |- \n ', self.columns, text) end function UnitTester:runTest(name, test) local success, details = xpcall(function() test(self) end, function(err) return {error = err, trace = debug.traceback()} end) if not success then num_failures = num_failures + 1 num_runs = num_runs + 1 result_table:insert('| ', 'rowspan=2|', cross, ' \n| ', name, ' \n| ') result_table:insert_format(' colspan="%u"| <strong class="error">Lua error during testing -- %s;traceback:<br>%s</strong>\n', self.columns, details.error, frame:extensionTag("pre", details.trace or "(no traceback)")) result_table:insert('\n|-\n') end end function UnitTester:run(frame_arg) frame = frame_arg or mw.getCurrentFrame() self.frame = frame self.differs_at = frame.args['differs_at'] self.live_sandbox = frame.args['live_sandbox'] tick = frame:preprocess(cfg.successIndicator) cross = frame:preprocess(cfg.failureIndicator) local table_header = '{| class="wikitable unit-tests-result"\n|+ %s\n! !! ' if self.live_sandbox then table_header = table_header .. cfg.testString .. ' !! ' .. cfg.liveString .. ' !! ' .. cfg.sandboxString .. ' !! ' .. cfg.expectedString else table_header = table_header .. cfg.testString .. ' !! ' .. cfg.expectedString .. ' !! ' .. cfg.actualString end if frame.args.highlight then should_highlight = true end self.columns = 4 if self.differs_at then table_header = table_header .. ' !! ' .. cfg.differsString self.columns = self.columns + 1 end if self._tests._last then table.insert(self._tests, self._tests._last) self._tests._last = nil end -- Add results to the results table. for _, testDetails in ipairs(self._tests) do result_table:insert_format('<h2>%s</h2>\n', testDetails.name) result_table:insert_format(table_header .. '\n|-\n', testDetails.name) self:runTest(testDetails.name, testDetails.test) result_table:insert('|}\n') end local refresh_link = tostring(mw.uri.fullUrl(mw.title.getCurrentTitle().fullText, 'action=purge&forcelinkupdate=1')) if self.live_sandbox then local live, sandbox if num_runs == 0 then live = cfg.noTestsRunSummary elseif num_failures ~= 0 then live = mw.message.newRawMessage(cfg.liveFailureSummary, num_runs, num_failures):plain() live = frame:preprocess(live) else live = mw.message.newRawMessage(cfg.liveSuccessSummary, num_runs):plain() live = frame:preprocess(live) end if num_runs == 0 then sandbox = '' elseif num_failures_sandbox ~= 0 then sandbox = mw.message.newRawMessage(cfg.sandboxFailureSummary, num_runs, num_failures_sandbox):plain() sandbox = frame:preprocess(sandbox) else sandbox = mw.message.newRawMessage(cfg.sandboxSuccessSummary, num_runs):plain() sandbox = frame:preprocess(sandbox) end local cat = (num_failures ~= 0 or num_failures_sandbox ~= 0) and (cfg.failureCategory .. " <span class='plainlinks unit-tests-refresh'>[" .. refresh_link .. " (refresh)]</span>") or '' return live .. ' ' .. sandbox .. cat .. '\n\n' .. frame:preprocess(result_table:concat()) else local msg; if num_runs == 0 then msg = cfg.noTestsRunSummary elseif num_failures ~= 0 then msg = mw.message.newRawMessage(cfg.failureSummary, num_runs, num_failures):plain() msg = frame:preprocess(msg) msg = msg .. cfg.failureCategory msg = msg .. " <span class='plainlinks unit-tests-refresh'>[" .. refresh_link .. " (refresh)]</span>" else msg = mw.message.newRawMessage(cfg.successSummary, num_runs):plain() msg = frame:preprocess(msg) end return msg .. '\n\n' .. frame:preprocess(result_table:concat()) end end -- Set up metatable UnitTester.__meta = {} UnitTester.__meta.__index = UnitTester function UnitTester.__meta:__newindex(key, value) if type(key) == 'string' and key:find('^test') and type(value) == 'function' then -- Store test functions in the order they were defined if key == self.runLast or key == rawget(_G, "runLast") then self._tests._last = {name = key, test = value} else table.insert(self._tests, {name = key, test = value}) end else rawset(self, key, value) end end function UnitTester.new() local o = {} o.runLast = '' -- puts a test at the end of the page o._tests = {} setmetatable(o, UnitTester.__meta) function o.run_tests(frame_arg) return o:run(frame_arg) end return o end local p = UnitTester.new() return p 3rqorj108acff8styw7tuar1fzojyeq Module:Fiction-based redirects to list entries category handler/RedirectType 828 52505 308473 2026-09-17T16:49:42Z Isma4l 41797 Bog cusub: require("strict") local libraryUtil = require("libraryUtil") local p = {} local franchiseList = { [1] = "Module:Arrowverse redirect category handler" } --[[ RedirectType class. --]] local function RedirectType(o) local RedirectType = o or {redirectType = "", defaultCategory = "", topLevelCategory = "", template = "", from = "", suffix = "", isFranchise = false} local checkSelf = libraryUtil.makeCheckSelfFunction("Fiction-based redirects to list entries category handler", "... 308473 Scribunto text/plain require("strict") local libraryUtil = require("libraryUtil") local p = {} local franchiseList = { [1] = "Module:Arrowverse redirect category handler" } --[[ RedirectType class. --]] local function RedirectType(o) local RedirectType = o or {redirectType = "", defaultCategory = "", topLevelCategory = "", template = "", from = "", suffix = "", isFranchise = false} local checkSelf = libraryUtil.makeCheckSelfFunction("Fiction-based redirects to list entries category handler", "RedirectType", RedirectType, "Fiction-based redirects to list entries category handler object") --[[ Public function which is used to retrieve the main category for a specific type. --]] function RedirectType:getMainCategory(mainCategory) return RedirectType:getCategory(mainCategory) end --[[ Public function which is used to retrieve the top level category (or categories) for a specific type and media format. If no media format is passed, the function returns the default top level category. --]] function RedirectType:getTopLevelCategory(mediaList) if (mediaList and #mediaList > 0) then local categories = "" for i = 1, #mediaList do local category if ((RedirectType.redirectType == "episode") and (string.lower(mediaList[i]) == "television")) then category = RedirectType:getCategory(RedirectType.defaultCategory) else category = RedirectType:getCategory(RedirectType.topLevelCategory) end categories = categories .. category:gsub("{media}", mediaList[i]) end return categories else return RedirectType.defaultCategory end end --[[ Public function which is used to retrieve a category for a specific type. --]] function RedirectType:getCategory(category) return category:gsub("{type}", RedirectType.redirectType) end --[[ Public function which is used to check if the category belongs to a special franchise, such as the Arrowverse. If the category is part of that franchise, returns the series name, else returns nil. --]] function RedirectType:isCategorySpecialFranchise(series) local seriesParameter if (RedirectType.redirectType == "character" or RedirectType.redirectType == "element" or RedirectType.redirectType == "location") then for i, v in pairs(franchiseList) do local seriesModule = require(v) local seriesList = seriesModule.getSeriesList() for i, v in pairs(seriesList) do local currentTVSeries = seriesList[i] if (series == currentTVSeries.seriesName) then seriesParameter = currentTVSeries.argName break end end local franchise = seriesModule.getFranchiseName() if (series == franchise) then seriesParameter = franchise RedirectType.isFranchise = true end if (seriesParameter) then if (i == 1) then RedirectType:setTemplateAsArrowverse() end break end end end if (seriesParameter) then return seriesParameter else return nil end end --[[ Public function which is used to change the type of template to the Arrowverse specific version. --]] function RedirectType:setTemplateAsArrowverse() RedirectType.template = "Arrowverse " .. RedirectType.redirectType .. " redirect" end return RedirectType end --[[ Public function which is used to retrieve the list of redirect types. --]] function p.getRedirectTypes() return { RedirectType{ redirectType = "character", defaultCategory = "[[Category:Redirects from fictional characters]]", topLevelCategory = "[[Category:{media} character redirects]]", template = "Fictional character redirect", from = "fictional characters", suffix = "redirects" }, RedirectType{ redirectType = "element", defaultCategory = "[[Category:Fictional element redirects]]", topLevelCategory = "[[Category:{media} element redirects to lists]]", template = "Fictional element redirect", from = "fictional elements", suffix = "redirects to lists" }, RedirectType{ redirectType = "episode", defaultCategory = "[[Category:Episode redirects to lists]]", topLevelCategory = "[[Category:{media} episode redirects to lists]]", template = "Television episode redirect handler", from = "episodes", suffix = "redirects to lists" }, RedirectType{ redirectType = "location", defaultCategory = "[[Category:Redirects from fictional locations]]", topLevelCategory = "[[Category:{media} location redirects]]", template = "Fictional location redirect", from = "fictional locations or settings", suffix = "redirects" } } end --[[ Public function which is used to retrieve a default redirect type. --]] function p.getDefaultType(typeList) return typeList[3] end return p 0zkqfk6y8durx9rrrw0twob6eul69el Module:Arrowverse redirect category handler 828 52506 308474 2026-09-17T16:50:29Z Isma4l 41797 Bog cusub: require("strict") local getArgs = require("Module:Arguments").getArgs local p = {} local tvSeriesNameList = { {argName = "arrow", seriesName = "Arrow (TV series)"}, {argName = "flash", seriesName = "The Flash (2014 TV series)"}, {argName = "constantine", seriesName = "Constantine (TV series)"}, {argName = "legends", seriesName = "Legends of Tomorrow"}, {argName = "supergirl", seriesName = "Supergirl (TV series)"}, {argName = "vixen", seriesName = "Vixen (web series)"},... 308474 Scribunto text/plain require("strict") local getArgs = require("Module:Arguments").getArgs local p = {} local tvSeriesNameList = { {argName = "arrow", seriesName = "Arrow (TV series)"}, {argName = "flash", seriesName = "The Flash (2014 TV series)"}, {argName = "constantine", seriesName = "Constantine (TV series)"}, {argName = "legends", seriesName = "Legends of Tomorrow"}, {argName = "supergirl", seriesName = "Supergirl (TV series)"}, {argName = "vixen", seriesName = "Vixen (web series)"}, {argName = "ray", seriesName = "Freedom Fighters: The Ray"}, {argName = "batwoman", seriesName = "Batwoman (TV series)"}, {argName = "black_lightning", seriesName = "Black Lightning (TV series)"}, {argName = "superman", seriesName = "Superman & Lois"}, } local FRANCHISE = "Arrowverse" --[[ Local function which handles the main operation. --]] local function main(args, objectType) local franchiseHandlerModule = require("Module:Fiction redirect category handler/Franchise") return franchiseHandlerModule.main(args, objectType, FRANCHISE, tvSeriesNameList) end --[[ Public function which is used to create a Redirect category shell with relevant redirects for Arrowverse-related character redirects. Parameters: -- |arrow= — optional; Any value will tag the redirect as belonging to Arrow. -- |flash= — optional; Any value will tag the redirect as belonging to The Flash. -- |constantine= — optional; Any value will tag the redirect as belonging to Constantine. -- |legends= — optional; Any value will tag the redirect as belonging to Legends of Tomorrow. -- |supergirl= — optional; Any value will tag the redirect as belonging to Supergirl. -- |vixen= — optional; Any value will tag the redirect as belonging to Vixen. -- |ray= — optional; Any value will tag the redirect as belonging to Freedom Fighters: The Ray. -- |batwoman= — optional; Any value will tag the redirect as belonging to Batwoman. -- |black_lightning= — optional; Any value will tag the redirect as belonging to Black Lightning. Notes: -- A: The redirect will automatically be tagged with "R from fictional character", "R from fictional element" or "R from fictional location", depending on the function used, and be placed in the category "Arrowverse (object) redirects to lists". -- B: Using any of the series parameters will place the redirect in a series-specific category: "(series) (object) redirects to lists". -- F: If the redirect does not use one of the following correct disambiguation — "Arrowverse", "Arrowverse character", "Arrowverse element" or "Arrowverse character" — the redirect will be tagged with "R from incorrect disambiguation" and "R unprintworthy". --]] function p.character(frame) local args = getArgs(frame) return main(args, "character") end --[[ Public function which is used to create a Redirect category shell with relevant redirects for Arrowverse-related element redirects. Parameters: See character() for documentation. --]] function p.element(frame) local args = getArgs(frame) return main(args, "element") end --[[ Public function which is used to create a Redirect category shell with relevant redirects for Arrowverse-related location redirects. Parameters: See character() for documentation. --]] function p.location(frame) local args = getArgs(frame) return main(args, "location") end --[[ Public function which is used to return a list of Arrowverse shows. --]] function p.getSeriesList() return tvSeriesNameList end --[[ Public function which is used to return a franchise name. --]] function p.getFranchiseName() return FRANCHISE end --[[ Public function which is used for the testcases. --]] function p.testSeriesName(frame) local args = getArgs(frame) local franchiseHandlerModule = require("Module:Fiction redirect category handler/Franchise") return franchiseHandlerModule.testSeriesName(args, FRANCHISE, tvSeriesNameList) end return p bbiyp8n4vogplntslfp5qkzdx87zuji Module:Fiction redirect category handler/Franchise 828 52507 308475 2026-09-17T16:51:16Z Isma4l 41797 Bog cusub: require("strict") local p = {} --[[ Local function which adds the names relevant TV series to the args table. Franchise templates, such as the Arrowverse-specific one, have short parameters that editors can use instead of the full TV series name. This functions checks if the user-input parameters match the ones on the list, and if they do, adds them to the list. Franchise templates can also use a "franchise" default parameter so all members will automatically be tagged in the... 308475 Scribunto text/plain require("strict") local p = {} --[[ Local function which adds the names relevant TV series to the args table. Franchise templates, such as the Arrowverse-specific one, have short parameters that editors can use instead of the full TV series name. This functions checks if the user-input parameters match the ones on the list, and if they do, adds them to the list. Franchise templates can also use a "franchise" default parameter so all members will automatically be tagged in the franchise category, as well as the specific TV series category. --]] local function getListOfSeriesTags(templateArgs, franchise, tvSeriesNameList, validArgs) local seriesArgs = {} for i, v in ipairs(tvSeriesNameList) do local tvSeries = tvSeriesNameList[i] -- Check if the user-input parameter matches one on the list; -- If it matches, add the series name to the list. if (templateArgs[tvSeries.argName]) then table.insert(seriesArgs, tvSeries.seriesName) table.insert(validArgs, tvSeries.argName) end end if (#seriesArgs > 0) then table.insert(seriesArgs, franchise) -- This parameter is used by the relevant "R to fictional x" templates -- to enable multi-series categories. seriesArgs["multi"] = "yes" templateArgs["multi_series_name_table"] = seriesArgs else templateArgs["series_name"] = franchise end return templateArgs, validArgs end --[[ Public function which handles the main operation. --]] function p.main(args, objectType, franchise, tvSeriesNameList) local validArgs = {"correct_disambiguation", "multi", "multi_series_name_table"} args, validArgs = getListOfSeriesTags(args, franchise, tvSeriesNameList, validArgs) -- Franchise articles, such as the Arrowverse and the Marvel Cinematic Universe, -- use the franchise name as disambiguation for articles, and not a TV series or film name. args["correct_disambiguation"] = franchise local fictionRedirectCategoryHandler = require("Module:Fiction redirect category handler") return fictionRedirectCategoryHandler["_" .. objectType](args, validArgs) end --[[ Public function which is used for the /testcases to verify correct series name output. --]] function p.testSeriesName(args, franchise, tvSeriesNameList) args = getListOfSeriesTags(args, franchise, tvSeriesNameList, {}) if (args.series_name) then return args.series_name else return args.multi_series_name_table[1] end end return p 2hpj0m1jgjh64l4ukw75beidqayzph4 Module:Fiction-based redirects to list entries category handler 828 52508 308476 2026-09-17T16:51:54Z Isma4l 41797 Bog cusub: require("strict") local p = {} local mainCategory = {name = "Category:{series}", link = "[[Category:{series}|{type}]]"} local secondaryCategoryList = { {name = "Category:{series} {type}s", link = "[[Category:{series} {type}s|*]]"}, {name = "Category:{series} redirects", link = "[[Category:{series} redirects|{type}]]"} } local TRACKING_CATEGORY = "[[Category:Fiction redirect categories with non-existent parent categories]]" local ERROR_MESSAGE = "Valid titles are in the styl... 308476 Scribunto text/plain require("strict") local p = {} local mainCategory = {name = "Category:{series}", link = "[[Category:{series}|{type}]]"} local secondaryCategoryList = { {name = "Category:{series} {type}s", link = "[[Category:{series} {type}s|*]]"}, {name = "Category:{series} redirects", link = "[[Category:{series} redirects|{type}]]"} } local TRACKING_CATEGORY = "[[Category:Fiction redirect categories with non-existent parent categories]]" local ERROR_MESSAGE = "Valid titles are in the style of \"Category:series-name content-type redirects to lists\"" --[[ Local function which checks if the category exists. --]] local function doesCategoryExist(category) return mw.title.new(category).exists end --[[ Local function which "Module:Sort title" to retrieve a sortkey and set it as the default sortkey. --]] local function getDefaultSortKey(frame) local sortkeyModule = require("Module:Sort title") local sortkey = sortkeyModule._getSortKey() return frame:preprocess{text = "{{DEFAULTSORT:" .. sortkey .. "}}"} end --[[ Local helper function which handles the gsub of the series name into the category name. --]] local function gsubSeriesName(category, articleTitle) return category:gsub("{series}", articleTitle) end --[[ Local helper function which sets the top level category. --]] local function getTopLevelCategory(categoryType, args) local mediaList = {} table.insert(mediaList, args.media) for i = 2, 10 do if (args["media" .. i]) then table.insert(mediaList, args["media" .. i]) else break end end return categoryType:getTopLevelCategory(mediaList) end --[[ Local helper function which sets the main category. --]] local function getMainCategory(categoryType, articleTitle) local categoryLink = gsubSeriesName(mainCategory.link, articleTitle) local categoryName = gsubSeriesName(mainCategory.name, articleTitle) if (not doesCategoryExist(categoryName)) then return TRACKING_CATEGORY end return categoryType:getMainCategory(categoryLink) end --[[ Local helper function which sets the secondary categories. --]] local function getSecondaryCategories(categoryType, articleTitle) local categoryList = "" for i = 1, #secondaryCategoryList do local secondaryCategory = secondaryCategoryList[i] local category = gsubSeriesName(secondaryCategory.name, articleTitle) category = categoryType:getCategory(category) if (doesCategoryExist(category)) then category = gsubSeriesName(secondaryCategory.link, articleTitle) category = categoryType:getCategory(category) categoryList = categoryList .. category end end return categoryList end --[[ Local function which handles the categorization of the category. --]] local function getCategories(categoryType, articleTitle, args) if (args.main) then articleTitle = args.main end local categoryList = getSecondaryCategories(categoryType, articleTitle) -- Only if there are no secondary categories, add to main category. if (categoryList == "") then categoryList = getMainCategory(categoryType, articleTitle) end local topLevelCategory = getTopLevelCategory(categoryType, args) return categoryList .. topLevelCategory end --[[ Local function which handles the Redirect category code. --]] local function getRedirectCategoryTemplate(frame, categoryType, articleTitle, seriesNameModified, seriesParameter) local redirectArgs = { from = string.format("[[%s|%s]] %s", articleTitle, seriesNameModified, categoryType.from), template = categoryType.template, no_info = "yes", not_maintenance = "yes", fiction = "yes" } if (categoryType.isFranchise) then redirectArgs.parameters = -1 else redirectArgs.parameters = "series_name=" .. seriesParameter end return frame:expandTemplate{title = "Redirect category", args = redirectArgs} end --[[ Local function which handles the italicization of the category title. --]] local function getItalicTitle(frame, seriesName, noItalic, test) local seriesNameModified = "''" .. seriesName .. "''" if (test) then if (noItalic) then return seriesName, seriesName else return seriesNameModified, seriesNameModified end else if (noItalic) then return "", seriesName else local italicTitleModule = require("Module:Italic title")._main local italicTitleArg = {string = seriesName} local italicText = italicTitleModule(italicTitleArg) return frame:preprocess{text = italicText}, seriesNameModified end end end --[[ Local function which extracts the series article name and the category type from the category name. --]] local function getCategoryTitleParts(currentTitle, typeList) for _, categoryType in ipairs(typeList) do local _, _, articleTitle = string.find(currentTitle, "^(.*) " .. categoryType.redirectType .. " " .. categoryType.suffix) if (articleTitle) then return articleTitle, categoryType end end return nil, -1 end --[[ Local function which is used to handle the actual main process. --]] local function _main(frame, args, title, namespace) local redirectType = require("Module:Fiction-based redirects to list entries category handler/RedirectType") local typeList = redirectType.getRedirectTypes() local articleTitle, categoryType = getCategoryTitleParts(title, typeList) -- A call from a documentation page; Show only the Redirect category header. if ((namespace ~= "Category") and (not args.test)) then categoryType = redirectType.getDefaultType(typeList) local redirectCategoryTemplate = getRedirectCategoryTemplate(frame, categoryType, "Series name", "Series name", "Series name") return redirectCategoryTemplate end if (articleTitle) then local seriesParameter = articleTitle local franchiseSeriesParameter = categoryType:isCategorySpecialFranchise(articleTitle) if (franchiseSeriesParameter) then seriesParameter = franchiseSeriesParameter end local seriesName = mw.ustring.gsub(articleTitle, "%s+%b()$", "") local italicTitle, seriesNameModified = getItalicTitle(frame, seriesName, args.no_italic, args.test) local redirectCategoryTemplate = getRedirectCategoryTemplate(frame, categoryType, articleTitle, seriesNameModified, seriesParameter) local categoryToc = frame:expandTemplate{title = "Automatic category TOC"} local categories = getCategories(categoryType, articleTitle, args) local defaultSortKey = getDefaultSortKey(frame) if (args.test) then return italicTitle, articleTitle, categoryType.template, categories else return italicTitle .. "\n" .. redirectCategoryTemplate .. "\n" .. categoryToc .. "\n\n" .. defaultSortKey .. "\n" .. categories end else return error(ERROR_MESSAGE, 0) end end --[[ Public function which is used to handle the logic for fiction-based redirects to lists categories. Parameters: -- |media= — optional and suggested; The type of media the fiction belongs to. Types include, but not limited to: Film, Television and Video game. If unsure, check the high level category, such as "Category:Fictional character redirects", and see what sub-categories that category has. -- |media2...4= — optional; Additional types of media the fiction belongs to. -- |main= — optional; Use when the main series category is not written or disambiguated the same as the series article. Value will be used for the series category title. -- |no_italic= — optional; Disables the italicizing of the series title. --]] function p.main(frame) local getArgs = require("Module:Arguments").getArgs local args = getArgs(frame) local currentTitle = mw.title.getCurrentTitle() return _main(frame, args, currentTitle.text, currentTitle.nsText) end --[[ Public function which is used for the testcases. Parameters: -- |test= — required; The series article name. --]] function p.test(frame) local getArgs = require("Module:Arguments").getArgs local args = getArgs(frame) local seriesName, articleTitle, template, categories = _main(frame, args, args.test, "Module") local testString = "Series name: %s\n\nArticle title: %s\n\nTemplate: %s\n\nCategories: <nowiki>%s</nowiki>" testString = string.format(testString, seriesName, articleTitle, template, categories) return testString end return p g9b1buxm1c5rs8ytah92nfbu8j1icq4 Template:Fiction-based redirects to list entries category handler 10 52509 308477 2026-09-17T16:52:34Z Isma4l 41797 Bog cusub: <includeonly><!-- -->{{#invoke:Fiction-based redirects to list entries category handler|main}}<!-- --></includeonly><!-- --><noinclude>{{Documentation}}</noinclude> 308477 wikitext text/x-wiki <includeonly><!-- -->{{#invoke:Fiction-based redirects to list entries category handler|main}}<!-- --></includeonly><!-- --><noinclude>{{Documentation}}</noinclude> tpmx31s38f1hb57rg7h6z1i3q0uzpoq Template:Television episode redirect handler 10 52510 308478 2026-09-17T16:53:06Z Isma4l 41797 Bog cusub: <includeonly><!-- -->{{#invoke:Television episode redirect handler|main}}<!-- --></includeonly><!-- --><noinclude>{{Documentation}}</noinclude> 308478 wikitext text/x-wiki <includeonly><!-- -->{{#invoke:Television episode redirect handler|main}}<!-- --></includeonly><!-- --><noinclude>{{Documentation}}</noinclude> 40w5th1w2ex9x9fs1owjt0clxg3t1ey Template:Fictional character redirect 10 52511 308479 2026-09-17T16:53:35Z Isma4l 41797 Bog cusub: <includeonly><!-- -->{{#invoke:Fiction redirect category handler|character}}<!-- --></includeonly><!-- --><noinclude>{{Documentation}}</noinclude> 308479 wikitext text/x-wiki <includeonly><!-- -->{{#invoke:Fiction redirect category handler|character}}<!-- --></includeonly><!-- --><noinclude>{{Documentation}}</noinclude> jyhz9nip93zqvjzgyb63eztga1atjn2 Axmed Gacayte 0 52512 308480 2026-09-17T17:04:51Z Mohamed Abdiwali Yusuf 46970 Samee turjumidda bogga "[[:en:Special:Redirect/revision/1364495395|Ahmed Gacayte]]" 308480 wikitext text/x-wiki {{Infobox musical artist|Name=Ahmed Gacayte|birth_place=[[Hargeisa]], [[British Somaliland]]|image=|image_size=|caption=|Birth_name=Ahmed Mohamed Yusuf|Alias=|birth_date={{birth date text|1948}}|native_name=Axmed Gacayte|native_name_lang=so|death_place=[[Hargeisa]], [[Somali Democratic Republic|Somalia]]|death_date={{death year and age|1988|1948}}|Origin=|instruments=Singing|Genre=[[Music of Somalia|Somali music]]|Occupation=Musician, artist|Years_active=1965–1988|Label=|website=}}'''Axmed Maxamed Yuusuf,''' oo inta badan loo yaqaan Axmed Gacayte, wuxuu ahaa fannaan, hal-abuur, laxamiiste iyo qoraa heeso Soomaaliyeed oo caan ah.<ref name=":1">Woolner, Christina J. (2023-11-24). ''Love Songs in Motion: Voicing Intimacy in Somaliland''. University of Chicago Press. ISBN&nbsp;<bdi>978-0-226-82738-4</bdi>.</ref><ref>Diiriye, Anwar Maxamed (2006). ''Literature of Somali Onomastics & Proverbs with Comparison of Foreign Sayings''. Gobaad Communications & Press. ISBN&nbsp;<bdi>978-0-9726615-1-5</bdi>.</ref><ref>Ahmedyasin, Ismail (2019-10-19). "Taariikhda Axmed Gacayte (WQ: Cumar seerbiya)". ''Bandhige- Wararka Somaliland iyo faallooyinkooda''. Retrieved 2021-01-22.</ref> == Taariikh == '''Axmed Gacayte''' wuxuu ku dhashay sannadkii '''1948''', xaafadda '''Xidigta''', oo ku dhow togga magaalada '''Hargeysa'''. Wuxuu ahaa curadka qoys ka kooban '''10 wiil iyo 3 gabdhood'''. Magaca '''“Gacayte”''' wuxuu ka dhaxlay aabbihii, '''Maxamed Yuusuf “Gacayte”''', oo uu naanaystiisa u qaatay. Sannadkii '''1964''', wariyeyaal ka socday '''Raadiyo Hargeysa''' ayaa yimid dugsigii uu dhiganayay Axmed Gacayte, iyagoo raadinayay arday leh karti iyo hibbo dhanka '''heesaha iyo codka''' ah. Gacayte ayaa lagu arkay hibadiisa, waxaana ugu dambayn loo '''xushay inuu ku biiro Raadiyo Hargeysa''', taasoo noqotay bilow muhiim ah oo uu ka sameeyo mihnaddiisa fanka. Sannadkii '''1965''', Axmed Gacayte wuxuu duubay heestiisii ugu horreysay oo la oran jiray '''“Ahlan wa Sahlan Daahir”''', taas oo laga sii daayay '''Raadiyo Hargeysa'''.<ref>"Taariikhdii Axmed Gacayte Yuusuf | Somalisan.com". Retrieved 2021-01-22.</ref> Heestu waxay noqotay tallaabo muhiim ah oo uu ku bilaabay safarkiisa faneed. Hase yeeshee, aabbihii arrintaas kuma uusan qanacsanayn, waxaana la sheegay inuu '''ka diiday wiilnimadiisa isla markaana guriga ka saaray''', taas oo ku timid doorashadii uu Gacayte ku doortay inuu fanka sii wato. Kadib, '''Axmed Gacayte''' wuxuu sii waday hal-abuurkiisa, isagoo curiyay isla markaana qoray heeso iyo riwaayado dhowr ah, oo ay ka mid yihiin '''“Bood Xirsi”''' iyo '''“Siyar”''', kuwaas oo uu la sameeyay '''Aamina Cabdullaahi'''.<ref>admin (2016-04-25). "Sahra-yartii Miyiga : Waxa Qoray Cumar Seerbiya". ''Sagal News''. Retrieved 2021-01-22.</ref><ref>"Aamina Cabdilaahi Xirsi: Fankii Jabuuti, Hargeysa Iyo Muqdisho U Kala Dabqaaday – Qalinka: Cumar Seerbiya | Somalidiasporanews.com". Retrieved 2021-01-22.</ref> Sidoo kale, wuxuu laxameeyay heeso ay qaadday fanaanadda '''Khadra Daahir Cige'''. Hibadiisa curinta, qoraalka iyo laxanka ayaa si dhakhso ah uga dhigtay fannaan caan ah oo laga wada yaqaan '''dunida Soomaalida''', gaar ahaan dhulka maanta loo yaqaan '''Somaliland'''. == Nolosha shaqsiyeed == Axmed Gacayte '''waligiis ma uusan guursan''', balse wuxuu lahaa '''hal wiil'''. Wiilkiisa ayaa ku geeriyooday '''Hargeysa sannadkii 1988''', isagoo jiray '''40 sano'''. <ref>"Somalilandhorta". Archived from the original on July 1, 2007. Retrieved 2021-01-22.</ref> == Diwaan-gelin == * Inaan Weli Ku Jecelahay <ref name=":1" /> * Ilaahay Baa Deeq Baxshee * Umaley Jacayl * Orod orod * Sabaalo * Dulmiga * Siyar (oo ay la socoto Amina Cabdullaahi) * Bood Xirsi (with Amina Abdullahi) * Ahlan wa sahlaan Daahir == Tixraacyada == <references /> {{Reflist}} [[Category:Articles with hCards]] [[Category:Somalia]] [[Category:Heeso]] [[Category:Fanka iyo Suugaanta Soomaalida]] [[Category:1988]] [[Category:Radio Hargeysa]] 3vcdf850ws8u0zynz3716tarsbzuqep 308481 308480 2026-09-17T17:05:21Z Quinlan83 28506 Fix 308481 wikitext text/x-wiki {{Infobox musical artist|Name=Ahmed Gacayte|birth_place=[[Hargeisa]], [[British Somaliland]]|image=|image_size=|caption=|Birth_name=Ahmed Mohamed Yusuf|Alias=|birth_date={{birth date text|1948}}|native_name=Axmed Gacayte|native_name_lang=so|death_place=[[Hargeisa]], [[Somali Democratic Republic|Somalia]]|death_date={{death year and age|1988|1948}}|Origin=|instruments=Singing|Genre=[[Music of Somalia|Somali music]]|Occupation=Musician, artist|Years_active=1965–1988|Label=|website=}}'''Axmed Maxamed Yuusuf,''' oo inta badan loo yaqaan Axmed Gacayte, wuxuu ahaa fannaan, hal-abuur, laxamiiste iyo qoraa heeso Soomaaliyeed oo caan ah.<ref name=":1">Woolner, Christina J. (2023-11-24). ''Love Songs in Motion: Voicing Intimacy in Somaliland''. University of Chicago Press. ISBN&nbsp;<bdi>978-0-226-82738-4</bdi>.</ref><ref>Diiriye, Anwar Maxamed (2006). ''Literature of Somali Onomastics & Proverbs with Comparison of Foreign Sayings''. Gobaad Communications & Press. ISBN&nbsp;<bdi>978-0-9726615-1-5</bdi>.</ref><ref>Ahmedyasin, Ismail (2019-10-19). "Taariikhda Axmed Gacayte (WQ: Cumar seerbiya)". ''Bandhige- Wararka Somaliland iyo faallooyinkooda''. Retrieved 2021-01-22.</ref> == Taariikh == '''Axmed Gacayte''' wuxuu ku dhashay sannadkii '''1948''', xaafadda '''Xidigta''', oo ku dhow togga magaalada '''Hargeysa'''. Wuxuu ahaa curadka qoys ka kooban '''10 wiil iyo 3 gabdhood'''. Magaca '''“Gacayte”''' wuxuu ka dhaxlay aabbihii, '''Maxamed Yuusuf “Gacayte”''', oo uu naanaystiisa u qaatay. Sannadkii '''1964''', wariyeyaal ka socday '''Raadiyo Hargeysa''' ayaa yimid dugsigii uu dhiganayay Axmed Gacayte, iyagoo raadinayay arday leh karti iyo hibbo dhanka '''heesaha iyo codka''' ah. Gacayte ayaa lagu arkay hibadiisa, waxaana ugu dambayn loo '''xushay inuu ku biiro Raadiyo Hargeysa''', taasoo noqotay bilow muhiim ah oo uu ka sameeyo mihnaddiisa fanka. Sannadkii '''1965''', Axmed Gacayte wuxuu duubay heestiisii ugu horreysay oo la oran jiray '''“Ahlan wa Sahlan Daahir”''', taas oo laga sii daayay '''Raadiyo Hargeysa'''.<ref>"Taariikhdii Axmed Gacayte Yuusuf | Somalisan.com". Retrieved 2021-01-22.</ref> Heestu waxay noqotay tallaabo muhiim ah oo uu ku bilaabay safarkiisa faneed. Hase yeeshee, aabbihii arrintaas kuma uusan qanacsanayn, waxaana la sheegay inuu '''ka diiday wiilnimadiisa isla markaana guriga ka saaray''', taas oo ku timid doorashadii uu Gacayte ku doortay inuu fanka sii wato. Kadib, '''Axmed Gacayte''' wuxuu sii waday hal-abuurkiisa, isagoo curiyay isla markaana qoray heeso iyo riwaayado dhowr ah, oo ay ka mid yihiin '''“Bood Xirsi”''' iyo '''“Siyar”''', kuwaas oo uu la sameeyay '''Aamina Cabdullaahi'''.<ref>admin (2016-04-25). "Sahra-yartii Miyiga : Waxa Qoray Cumar Seerbiya". ''Sagal News''. Retrieved 2021-01-22.</ref><ref>"Aamina Cabdilaahi Xirsi: Fankii Jabuuti, Hargeysa Iyo Muqdisho U Kala Dabqaaday – Qalinka: Cumar Seerbiya | Somalidiasporanews.com". Retrieved 2021-01-22.</ref> Sidoo kale, wuxuu laxameeyay heeso ay qaadday fanaanadda '''Khadra Daahir Cige'''. Hibadiisa curinta, qoraalka iyo laxanka ayaa si dhakhso ah uga dhigtay fannaan caan ah oo laga wada yaqaan '''dunida Soomaalida''', gaar ahaan dhulka maanta loo yaqaan '''Somaliland'''. == Nolosha shaqsiyeed == Axmed Gacayte '''waligiis ma uusan guursan''', balse wuxuu lahaa '''hal wiil'''. Wiilkiisa ayaa ku geeriyooday '''Hargeysa sannadkii 1988''', isagoo jiray '''40 sano'''. <ref>"Somalilandhorta". Archived from the original on July 1, 2007. Retrieved 2021-01-22.</ref> == Diwaan-gelin == * Inaan Weli Ku Jecelahay <ref name=":1" /> * Ilaahay Baa Deeq Baxshee * Umaley Jacayl * Orod orod * Sabaalo * Dulmiga * Siyar (oo ay la socoto Amina Cabdullaahi) * Bood Xirsi (with Amina Abdullahi) * Ahlan wa sahlaan Daahir == Tixraacyada == <references /> {{Reflist}} [[Category:Articles with hCards]] [[Category:Somalia]] [[Category:Heeso]] [[Category:Fanka iyo Suugaanta Soomaalida]] [[Category:1988]] [[Category:Radio Hargeysa]] gevc9qu08cy87yp01hl2ciwn5us9t0v Template:Quote frame 10 52513 308483 2026-09-17T22:06:27Z Isma4l 41797 Bog cusub: <templatestyles src="Quote frame/styles.css"/><blockquote class="quote-frame pullquote {{#switch:{{{align|}}}|left=quote-frame-left|right=quote-frame-right|center=quote-frame-center|#default=}} {{#if:{{{width|}}}|quote-frame-with-width}}" {{#if:{{{width|}}} |style="width:{{{width}}};"}}><div><!-- left this now-unused div in because I don't want to fight the parser right now -->{{{text|{{{content|{{{quotetext|{{{quote|{{{1|<includeonly>{{error|Error: No text given for quotation (o... 308483 wikitext text/x-wiki <templatestyles src="Quote frame/styles.css"/><blockquote class="quote-frame pullquote {{#switch:{{{align|}}}|left=quote-frame-left|right=quote-frame-right|center=quote-frame-center|#default=}} {{#if:{{{width|}}}|quote-frame-with-width}}" {{#if:{{{width|}}} |style="width:{{{width}}};"}}><div><!-- left this now-unused div in because I don't want to fight the parser right now -->{{{text|{{{content|{{{quotetext|{{{quote|{{{1|<includeonly>{{error|Error: No text given for quotation (or equals sign used in the actual argument to an unnamed parameter)}}</includeonly><noinclude>{{lorem ipsum}}</noinclude>}}}}}}}}}}}}}}}<!-- -->{{#if:{{{author|}}}{{{2|}}}{{{title|}}}{{{3|}}}{{{source|}}}{{{4|}}} |<cite class="quote-frame-source"> —&#8202;{{trim|1={{{author|{{{2|}}}}}}{{#if:{{{title|}}}{{{3|}}} |{{#if:{{{author|}}}{{{2|}}}|,&#32;}}''{{{title|{{{3}}}}}}'' }}{{#if:{{{source|}}}{{{4|}}} |{{#if:{{{author|}}}{{{2|}}}{{{title|}}}{{{3|}}}|,&#32;}}{{{source|{{{4}}}}}} }}}}</cite>}}</div></blockquote><noinclude> {{Documentation}} <!-- PLEASE ADD CATEGORIES TO THE /doc SUBPAGE, THANKS --> </noinclude> tg03374i2hyx0vx01azk7g6ppma1hh7 Template:Quote frame/styles.css 10 52514 308484 2026-09-17T22:07:07Z Isma4l 41797 Bog cusub: .quote-frame { font-size: 95%; background-color: var( --background-color-neutral-subtle, #f8f9fa ); border: 1px solid #aaa; box-sizing: border-box; } .quote-frame-source { display: block; text-align: right; } @media (max-width: 639px) { .quote-frame-with-width { width: auto !important; } } @media (min-width: 640px) { .quote-frame { width: fit-content; padding: 1em 3em; } .quote-frame-left { float: left; } .quote-frame-right { float: right; } .qu... 308484 sanitized-css text/css .quote-frame { font-size: 95%; background-color: var( --background-color-neutral-subtle, #f8f9fa ); border: 1px solid #aaa; box-sizing: border-box; } .quote-frame-source { display: block; text-align: right; } @media (max-width: 639px) { .quote-frame-with-width { width: auto !important; } } @media (min-width: 640px) { .quote-frame { width: fit-content; padding: 1em 3em; } .quote-frame-left { float: left; } .quote-frame-right { float: right; } .quote-frame-center { margin-left: auto; margin-right: auto; } } q4bpepimgz7vmchi5khyl60hbp08fk5 Template:Block indent 10 52515 308485 2026-09-17T22:07:31Z Isma4l 41797 Bog cusub: <templatestyles src="Block indent/styles.css"/><div class="block-indent {{{class|}}}" {{#if:{{{left|}}}{{{em|}}}{{{right|}}}{{{style|}}}|style="{{#if:{{{left|{{{em|}}}}}}|padding-left: {{{left|{{{em}}}}}}em;}}{{#if:{{{right|}}}|padding-right: {{{right}}}em;}}{{#if:{{{style|}}}|{{{style}}}}}"}}>{{{1|{{{text|{{{content|{{{quote|<noinclude>{{lorem ipsum}}</noinclude><includeonly>{{error|Error: No content given to indent (or equals sign used in the actual argument to an unnamed param... 308485 wikitext text/x-wiki <templatestyles src="Block indent/styles.css"/><div class="block-indent {{{class|}}}" {{#if:{{{left|}}}{{{em|}}}{{{right|}}}{{{style|}}}|style="{{#if:{{{left|{{{em|}}}}}}|padding-left: {{{left|{{{em}}}}}}em;}}{{#if:{{{right|}}}|padding-right: {{{right}}}em;}}{{#if:{{{style|}}}|{{{style}}}}}"}}>{{{1|{{{text|{{{content|{{{quote|<noinclude>{{lorem ipsum}}</noinclude><includeonly>{{error|Error: No content given to indent (or equals sign used in the actual argument to an unnamed parameter)}}</includeonly>}}}}}}}}}}}}</div><noinclude> {{documentation}} </noinclude> s97n0kekohfw61aczb4rdypuzqrqlog Template:Indent 5 10 52516 308486 2026-09-17T22:07:59Z Isma4l 41797 Bog cusub: <includeonly>{{{{{|safesubst:}}}#invoke:in5|in5|1={{{1|}}}}}</includeonly><noinclude> {{Documentation}} <!--[[Category:Smart formatting templates|In5]]--> </noinclude> 308486 wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#invoke:in5|in5|1={{{1|}}}}}</includeonly><noinclude> {{Documentation}} <!--[[Category:Smart formatting templates|In5]]--> </noinclude> 8vq8wpy1id7garukyg2rx2pi2ojk3nv Module:In5 828 52517 308487 2026-09-17T22:08:25Z Isma4l 41797 Bog cusub: -- This module implements {{in5}}. local p = {} function p.in5(frame) local indent = frame.args[1] -- Trim whitespace and convert to number. Default to 5 if not present, -- as per the template title. indent = tonumber( mw.text.trim(indent) ) or 5 -- Round down to nearest integer. Decimal values produce funky results -- from the original template, but there's no need for us to replicate that. indent = math.floor( indent ) -- Don't output anything... 308487 Scribunto text/plain -- This module implements {{in5}}. local p = {} function p.in5(frame) local indent = frame.args[1] -- Trim whitespace and convert to number. Default to 5 if not present, -- as per the template title. indent = tonumber( mw.text.trim(indent) ) or 5 -- Round down to nearest integer. Decimal values produce funky results -- from the original template, but there's no need for us to replicate that. indent = math.floor( indent ) -- Don't output anything for zero or less. Again, there was some funky output -- here for negatives, but now we're in Lua we should use sane defaults. if indent <= 0 then return end local base = '&nbsp; ' local modulo = '&nbsp;' --[[ Indent values and the corresponding values for base and modulo: indent base modulo 1 0 1 2 0 2 3 1 1 4 1 2 5 2 1 6 2 2 7 3 1 8 3 2 9 4 1 10 4 2 ]] local baseNum = math.floor( (indent - 1) / 2 ) local modNum = math.fmod( indent - 1 , 2 ) + 1 return mw.ustring.rep( base, baseNum) .. mw.ustring.rep( modulo, modNum ) end return p d2jdhmzl1ariwd7uypwfkhex9llkyg6 Template:Numbered verses 10 52518 308488 2026-09-17T22:09:09Z Isma4l 41797 Bog cusub: <includeonly>{{#if:{{{1|}}}|<templatestyles src="Template:Numbered verses/styles.css" /><div class="numbered-verses"{{#if:{{{first|}}}|{{#iferror:{{#expr:{{{first}}}*0}}||<nowiki /> style="counter-reset: versus {{#expr:({{{first}}}) - 1}};"}}|<nowiki /> style="counter-reset: versus 0;"}}>{{#invoke:string|replace|{{#invoke:string|replace|{{#invoke:string|replace|{{#invoke:string|replace|~#!@@/// <div>{{#if:1|{{{1}}}}}</div>| +|</div><div class{{=}}"intervallum-carminis"><br /> |p... 308488 wikitext text/x-wiki <includeonly>{{#if:{{{1|}}}|<templatestyles src="Template:Numbered verses/styles.css" /><div class="numbered-verses"{{#if:{{{first|}}}|{{#iferror:{{#expr:{{{first}}}*0}}||<nowiki /> style="counter-reset: versus {{#expr:({{{first}}}) - 1}};"}}|<nowiki /> style="counter-reset: versus 0;"}}>{{#invoke:string|replace|{{#invoke:string|replace|{{#invoke:string|replace|{{#invoke:string|replace|~#!@@/// <div>{{#if:1|{{{1}}}}}</div>| +|</div><div class{{=}}"intervallum-carminis"><br /> |plain=false}}|([^ ]+ [^ ]+ [^ ]+ [^ ]+ [^ ]+) |%1</div><div class{{=}}"quintina-carminis">|plain=false}}|^~#!@@/// ||count=1|plain=false}}| |</div><div>|plain=true}}{{#if:{{{2|}}}|<div class="auctor-carminis">{{#if:1|{{{2}}}}}</div>}}</div><div style="clear: both;"></div>|{{#invoke:Error|error|Error: No verses were given.}} }}</includeonly><noinclude>{{Documentation}}</noinclude> pmzjlp3985fhdut6fvehpu8yc41h54z Template:Numbered verses/styles.css 10 52519 308489 2026-09-17T22:09:43Z Isma4l 41797 Bog cusub: div.numbered-verses { float: left; margin: 1em auto 1em 3%; } div.numbered-verses > div { margin-left: 3em; text-indent: -3em; counter-increment: versus; margin-right: 5em; } div.numbered-verses > div.titulus-carminis { text-indent: 0; margin: 0 0 1em 0; font-weight: bold; counter-increment: none; } div.numbered-verses > div.intervallum-carminis { margin-left: 0; text-indent: 0; counter-increment: none; } div.numbered-verses > div.quintina-carminis { position: r... 308489 sanitized-css text/css div.numbered-verses { float: left; margin: 1em auto 1em 3%; } div.numbered-verses > div { margin-left: 3em; text-indent: -3em; counter-increment: versus; margin-right: 5em; } div.numbered-verses > div.titulus-carminis { text-indent: 0; margin: 0 0 1em 0; font-weight: bold; counter-increment: none; } div.numbered-verses > div.intervallum-carminis { margin-left: 0; text-indent: 0; counter-increment: none; } div.numbered-verses > div.quintina-carminis { position: relative; } div.numbered-verses > div.quintina-carminis::after { display: block; position: absolute; right: -5em; bottom: 0; content: counter(versus); } div.auctor-carminis { margin: 0 auto .5em 8%; position: relative; top: -.5em; left: 0; } div.auctor-carminis::before { content: "\2015"; margin-right: .25em; } o0eqr5gnl2k4kh495wpriem6xvcwz3r Template:Poem 10 52520 308490 2026-09-17T22:10:20Z Isma4l 41797 Bog cusub: <includeonly><<noinclude></noinclude>poem>{{{1|}}}<<noinclude></noinclude>/poem></includeonly><noinclude>{{documentation}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude> 308490 wikitext text/x-wiki <includeonly><<noinclude></noinclude>poem>{{{1|}}}<<noinclude></noinclude>/poem></includeonly><noinclude>{{documentation}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude> lxh06q36jeurkf3ihs391f1fgg0zold Template:Poetically break lines 10 52521 308491 2026-09-17T22:10:55Z Isma4l 41797 Bog cusub: <includeonly><templatestyles src="Template:Poetically break lines/styles.css" />{{#if:{{{1|}}}|<div class="pbl" style="margin:{{#if:{{{margin|}}}|{{{margin|}}}|1em auto 1em 5%}};"><div>{{#invoke:String|replace|{{#invoke:String|replace|{{trim|{{{1}}}}}| |</div><div>|plain=true}}|<div></div>|<div><br /></div>|plain=true}}</div></div>|{{#invoke:Error|error|Error: Missing argument.}}}}</includeonly><noinclude>{{Documentation}}</noinclude> 308491 wikitext text/x-wiki <includeonly><templatestyles src="Template:Poetically break lines/styles.css" />{{#if:{{{1|}}}|<div class="pbl" style="margin:{{#if:{{{margin|}}}|{{{margin|}}}|1em auto 1em 5%}};"><div>{{#invoke:String|replace|{{#invoke:String|replace|{{trim|{{{1}}}}}| |</div><div>|plain=true}}|<div></div>|<div><br /></div>|plain=true}}</div></div>|{{#invoke:Error|error|Error: Missing argument.}}}}</includeonly><noinclude>{{Documentation}}</noinclude> 6nvbha92kwi9g9jh91k6q0ebtjyueg3 Template:Poetically break lines/styles.css 10 52522 308492 2026-09-17T22:11:16Z Isma4l 41797 Bog cusub: div.pbl > div { margin-left: 3em; text-indent: -3em; } 308492 sanitized-css text/css div.pbl > div { margin-left: 3em; text-indent: -3em; } b7qkcr465hjxfo470uir6el3v6bghc7 Template:Translated blockquote 10 52523 308493 2026-09-17T22:11:50Z Isma4l 41797 Bog cusub: <includeonly>{{#invoke:Template wrapper|{{#if:{{{_debug|}}}|list|wrap}} |_template=blockquote |_exclude=_debug,language,lang,translation,quote,italic,rtl,show-language,link-language,nocat,size,brackets,text-style,text-class |multiline=yes |text={{#if:{{{text-style|}}}{{{text-class|}}}|<div class="{{{text-class|}}}" style="{{{text-style|}}}">}}{{if both|{{yesno|{{{show-language|}}}}}|{{yesno|{{{link-language|}}}|yes=|no=true|def=true}}|{{lang|fn=name_from_tag|{{{language|{{{lang|}... 308493 wikitext text/x-wiki <includeonly>{{#invoke:Template wrapper|{{#if:{{{_debug|}}}|list|wrap}} |_template=blockquote |_exclude=_debug,language,lang,translation,quote,italic,rtl,show-language,link-language,nocat,size,brackets,text-style,text-class |multiline=yes |text={{#if:{{{text-style|}}}{{{text-class|}}}|<div class="{{{text-class|}}}" style="{{{text-style|}}}">}}{{if both|{{yesno|{{{show-language|}}}}}|{{yesno|{{{link-language|}}}|yes=|no=true|def=true}}|{{lang|fn=name_from_tag|{{{language|{{{lang|}}}}}}}}:&#32;}}{{Lang/with italics|italic={{{italic|}}}|nocat={{{nocat|}}}|rtl={{{rtl|}}}|size={{{size|}}}|fn={{if both|{{yesno|{{{show-language|}}}}}|{{yesno|{{{link-language|}}}}}|lang_xx_inherit|lang}}|code={{{language|{{{lang|}}}}}}|text={{{1|{{{quote|}}}}}}}} {{#if:{{{3|}}}{{{4|}}}{{{5|}}}|{{error|Too many unnamed parameters given to {{FULLPAGENAME}}. A maximum of 2 unnamed parameters are allowed.}} |}}{{yesno|{{{brackets|}}}|yes=[|no=|blank=[|def=[}}{{trim|{{{2|{{{translation|}}}}}}}}{{yesno|{{{brackets|yes}}}|yes=]|no=|blank=]|def=]{{error|Unexpected value {{para|brackets|{{{brackets}}}}}}}}}{{if either|1={{{text-style|}}}|2={{{text-class|}}}|3=</div>|4=}} }}</includeonly><noinclude>{{documentation}}</noinclude> big63259rkzxj4ijtmixqbcn43ku1i7 Template:Text and translation 10 52524 308494 2026-09-17T22:12:27Z Isma4l 41797 Bog cusub: <div class="text-and-translation" style="padding:1em 3em 1em 3em"><!-- --><div style="display:flex;flex-flow:row wrap; gap:1em"><!-- --><div style="flex: 1 1 300px;">{{#if:{{{language|}}}|{{lang|{{{language}}}|{{{1}}}|italic=unset}}|{{trim|{{{1}}}}}}}</div><!-- --><div style="flex: 1 1 300px;">{{trim|{{{2}}}}}</div><!-- --></div><!-- -->{{#if:{{{3|<noinclude>TRUE</noinclude>}}}|<p style="clear:left;margin:1em 0 1em 6em;align-self:flex-end">—{{hair space}... 308494 wikitext text/x-wiki <div class="text-and-translation" style="padding:1em 3em 1em 3em"><!-- --><div style="display:flex;flex-flow:row wrap; gap:1em"><!-- --><div style="flex: 1 1 300px;">{{#if:{{{language|}}}|{{lang|{{{language}}}|{{{1}}}|italic=unset}}|{{trim|{{{1}}}}}}}</div><!-- --><div style="flex: 1 1 300px;">{{trim|{{{2}}}}}</div><!-- --></div><!-- -->{{#if:{{{3|<noinclude>TRUE</noinclude>}}}|<p style="clear:left;margin:1em 0 1em 6em;align-self:flex-end">—{{hair space}}{{{3}}}</p>}}<!-- --></div><noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS --> </noinclude> iuzmeijjj02y0bsy8x6x66q4xmmow15 Template:Verse transliteration-translation 10 52525 308495 2026-09-17T22:12:57Z Isma4l 41797 Bog cusub: <templatestyles src="Verse transliteration-translation/styles.css" /> {| class="Verse_transliteration-translation" {{#if:{{{originalHeading|}}}||style="margin-left:2em !important;"}} |- style="vertical-align: top;" | style="padding-right:1em" | {{#if:{{{originalHeading|}}}|<strong>{{{originalHeading}}}</strong>|}}{{#if:{{{originalHeading|{{{transliteration heading|{{{translationHeading|}}}}}}}}}|<br />}}{{#if:{{{lang|}}}|<div style={{#if:{{{rtl|}}}|"direction:rtl;"|""}}>{{lang... 308495 wikitext text/x-wiki <templatestyles src="Verse transliteration-translation/styles.css" /> {| class="Verse_transliteration-translation" {{#if:{{{originalHeading|}}}||style="margin-left:2em !important;"}} |- style="vertical-align: top;" | style="padding-right:1em" | {{#if:{{{originalHeading|}}}|<strong>{{{originalHeading}}}</strong>|}}{{#if:{{{originalHeading|{{{transliteration heading|{{{translationHeading|}}}}}}}}}|<br />}}{{#if:{{{lang|}}}|<div style={{#if:{{{rtl|}}}|"direction:rtl;"|""}}>{{lang|{{{lang}}}|{{#tag:poem|{{{1|{{error|missing input}}}}}}}|rtl={{{rtl|}}}}}</div>|{{#tag:poem|{{{1|{{error|missing input}}}}}|style={{#if:{{{originalHeading|}}}|"margin-left:1em;"}}}}}} | style="padding-right:1em" | {{#if:{{{transliterationHeading|}}}|<strong>{{{transliterationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#if:{{{lang|}}}|{{Transliteration|{{{lang}}}|{{#tag:poem|{{{2|{{error|missing input}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}}|{{#tag:poem|{{{2|{{error|missing input}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}} | {{#if:{{{translationHeading|}}}|<strong>{{{translationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#tag:poem|{{{3|{{error|missing input}}}}} |style={{#if:{{{translationHeading|}}}|"margin-left:1em;"}}}} |}<noinclude> {{documentation}} </noinclude> 79uv36zqsbogfpp0u3qgwm2pwf9uzxc 308497 308495 2026-09-17T22:15:21Z Isma4l 41797 308497 wikitext text/x-wiki <templatestyles src="Verse transliteration-translation/styles.css" /> {| class="Verse_transliteration-translation" {{#if:{{{originalHeading|}}}||style="margin-left:2em !important;"}} |- style="vertical-align: top;" | style="padding-right:1em" | {{#if:{{{originalHeading|}}}|<strong>{{{originalHeading}}}</strong>|}}{{#if:{{{originalHeading|{{{transliteration heading|{{{translationHeading|}}}}}}}}}|<br />}}{{#if:{{{lang|}}}|<div style={{#if:{{{rtl|}}}|"direction:rtl;"|""}}>{{lang|{{{lang}}}|{{#tag:poem|{{{1|{{error|missing input}}}}}}}|rtl={{{rtl|}}}}}</div>|{{#tag:poem|{{{1|{{error|missing input}}}}}|style={{#if:{{{originalHeading|}}}|"margin-left:1em;"}}}}}} | style="padding-right:1em" | {{#if:{{{transliterationHeading|}}}|<strong>{{{transliterationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#if:{{{lang|}}}|{{Transliteration|{{{lang}}}|{{#tag:poem|{{{2|{{error|missing input}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}}|{{#tag:poem|{{{2|{{error|missing input}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}} | {{#if:{{{translationHeading|}}}|<strong>{{{translationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#tag:poem|{{{3|{{error|Wax gelinta maqan}}}}} |style={{#if:{{{translationHeading|}}}|"margin-left:1em;"}}}} |}<noinclude> {{documentation}} </noinclude> hebsnz2yv9b63f4zsv3c6emgtytlw44 308498 308497 2026-09-17T22:16:46Z Isma4l 41797 308498 wikitext text/x-wiki <templatestyles src="Verse transliteration-translation/styles.css" /> {| class="Verse_transliteration-translation" {{#if:{{{originalHeading|}}}||style="margin-left:2em !important;"}} |- style="vertical-align: top;" | style="padding-right:1em" | {{#if:{{{originalHeading|}}}|<strong>{{{originalHeading}}}</strong>|}}{{#if:{{{originalHeading|{{{transliteration heading|{{{translationHeading|}}}}}}}}}|<br />}}{{#if:{{{lang|}}}|<div style={{#if:{{{rtl|}}}|"direction:rtl;"|""}}>{{lang|{{{lang}}}|{{#tag:poem|{{{1|{{error|Wax gelinta maqan}}}}}}}|rtl={{{rtl|}}}}}</div>|{{#tag:poem|{{{1|{{error|Wax gelinta maqan}}}}}|style={{#if:{{{originalHeading|}}}|"margin-left:1em;"}}}}}} | style="padding-right:1em" | {{#if:{{{transliterationHeading|}}}|<strong>{{{transliterationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#if:{{{lang|}}}|{{Transliteration|{{{lang}}}|{{#tag:poem|{{{2|{{error|Wax gelinta maqan}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}}|{{#tag:poem|{{{2|{{error|Wax gelinta maqan}}}}}|style={{#if:{{{transliterationHeading|}}}|"margin-left:1em;"}}}}}} | {{#if:{{{translationHeading|}}}|<strong>{{{translationHeading}}}</strong>}} {{#if:{{{originalHeading|{{{transliterationHeading|{{{translationHeading|}}}}}}}}}|<br />}} {{#tag:poem|{{{3|{{error|Wax gelinta maqan}}}}} |style={{#if:{{{translationHeading|}}}|"margin-left:1em;"}}}} |}<noinclude> {{documentation}} </noinclude> dnkfjqoiqkzxwact3gntema6na339ds Template:Verse transliteration-translation/styles.css 10 52526 308496 2026-09-17T22:13:45Z Isma4l 41797 Bog cusub: .Verse_transliteration-translation tr > td > .poem > p > span > i, .Verse_transliteration-translation tr > td > .poem > p > span > span { line-height: 1em; } .Verse_transliteration-translation td { display: inline-block; } /*wrap if below 900px*/ @media only screen and (max-width: 900px) { .Verse_transliteration-translation td { display: block; } } 308496 sanitized-css text/css .Verse_transliteration-translation tr > td > .poem > p > span > i, .Verse_transliteration-translation tr > td > .poem > p > span > span { line-height: 1em; } .Verse_transliteration-translation td { display: inline-block; } /*wrap if below 900px*/ @media only screen and (max-width: 900px) { .Verse_transliteration-translation td { display: block; } } hmlj25mh8v43ggyqhvvq4crxwp25btl Template:Reduced quote 10 52527 308499 2026-09-17T22:17:41Z Isma4l 41797 Bog cusub: <noinclude>The template appears as follows in article space: {{Blockquote|class=rquote|text={{lorem ipsum}}|style=width:33%}} and as follows in all other namespaces: </noinclude><templatestyles src="Reduced quote/styles.css"/>{{Main other |demospace={{{demospace|}}} |1=<!-- result if in mainspace --><div class="rquote" style="float: {{{1|{{{align}}}}}}; width: {{{width|39%}}}; {{{style|}}}">{{Blockquote | class = | text = {{Trim quotes|{{{text|{{{content|{{{quotetext|{{... 308499 wikitext text/x-wiki <noinclude>The template appears as follows in article space: {{Blockquote|class=rquote|text={{lorem ipsum}}|style=width:33%}} and as follows in all other namespaces: </noinclude><templatestyles src="Reduced quote/styles.css"/>{{Main other |demospace={{{demospace|}}} |1=<!-- result if in mainspace --><div class="rquote" style="float: {{{1|{{{align}}}}}}; width: {{{width|39%}}}; {{{style|}}}">{{Blockquote | class = | text = {{Trim quotes|{{{text|{{{content|{{{quotetext|{{{quote|{{{2|<includeonly>{{Error|Error: No text given for quotation (or equals sign used in the actual argument to an unnamed parameter)}}</includeonly><noinclude>{{lorem ipsum}}</noinclude>}}}}}}}}}}}}}}}}} | author = {{{3|{{{author|<noinclude>person quoted</noinclude>}}}}}} | source = {{#if:{{{4|{{{source|}}}}}}|{{{4|{{{source<noinclude>|cited source</noinclude>}}}}}}}} }}</div> |2=<!-- result if elsewhere --> {{{!}} class="rquote pullquote float{{{1|{{{align}}}}}}" role="presentation" style="display:table; border-collapse:collapse; border-style:none; float:{{{1|{{{align}}}}}}; margin:0.5em 0.75em; width:{{{width|33%}}}; {{{style|}}}" {{!}}- style="text-align:left; vertical-align:top;" {{!}} style="color:#b2b7f2; font-size:3.3em; font-family:'Times New Roman',serif; font-weight:bold; padding:4px 2px 2px; width:0.5em; line-height: 1em;"{{!}} “ {{!}} style="padding:0 10px;"{{!}} {{trim quotes|{{{text|{{{content|{{{quotetext|{{{quote|{{{2|<includeonly>{{Error|Error: No text given for quotation (or equals sign used in the actual argument to an unnamed parameter)}}</includeonly><noinclude>{{Lorem ipsum}}</noinclude>}}}}}}}}}}}}}}}}} {{!}} style="color:#b2b7f2; font-size:3.3em; font-family:'Times New Roman',serif; font-weight:bold; padding:4px 2px 2px; text-align:right; vertical-align:bottom; width:0.5em; line-height: 1em;"{{!}} ” {{!}}- {{!}} class="rquotecite" colspan="3" style="padding-top:10px; font-size:smaller; line-height:normal; text-align:right;"{{!}} {{#if:{{{3|{{{author|{{{4|{{{source|}}}}}}}}}}}}|<cite>—&#8202;<!--hairspace-->{{trim|1={{{3|{{{author|<noinclude>person quoted</noinclude>}}}}}}{{#if:{{{4|{{{source|}}}}}}|{{#if:{{{3|{{{author|}}}}}}|,}}&#32;{{{4|{{{source<noinclude>|cited source</noinclude>}}}}}}}}}}</cite>}} {{!}}} }}<!--Markup inserted from Template:Rquote--><noinclude> {{Documentation}} </noinclude> laqdc7tm4zfshl5bolq7226fctvwc9r Template:Reduced quote/styles.css 10 52528 308500 2026-09-17T22:19:14Z Isma4l 41797 Bog cusub: /* {{pp-template}} */ @media all and (max-width:720px) { .rquote { width:auto !important; float:none !important; } } 308500 sanitized-css text/css /* {{pp-template}} */ @media all and (max-width:720px) { .rquote { width:auto !important; float:none !important; } } oone4wbwswbh8wrhecdprbqwo2932mh Template:Talk quote block minimalist 10 52529 308501 2026-09-17T22:20:59Z Isma4l 41797 Bog cusub: <templatestyles src="Talk quote block minimalist/styles.css" /><blockquote class="tqb talkquote-minimal"><!-- -->{{{text|{{{1|<noinclude>{{lorem ipsum}}</noinclude>}}}}}}<!-- --></blockquote><noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS --> </noinclude> 308501 wikitext text/x-wiki <templatestyles src="Talk quote block minimalist/styles.css" /><blockquote class="tqb talkquote-minimal"><!-- -->{{{text|{{{1|<noinclude>{{lorem ipsum}}</noinclude>}}}}}}<!-- --></blockquote><noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS --> </noinclude> qrp6ffi0hkm8o3831w6wflvfm0u7fo7 Template:Talk quote block minimalist/styles.css 10 52530 308502 2026-09-17T22:21:24Z Isma4l 41797 Bog cusub: /* {{pp-template}} */ .talkquote-minimal { color: var(--color-subtle, #54595d); border-left: .25em solid var(--border-color-muted, #dadde3); padding: 0 1em; margin: 0.3em 0 0 0; } 308502 sanitized-css text/css /* {{pp-template}} */ .talkquote-minimal { color: var(--color-subtle, #54595d); border-left: .25em solid var(--border-color-muted, #dadde3); padding: 0 1em; margin: 0.3em 0 0 0; } t4jbl1ixlvxkpqqz1fedzald35ax4r0 User:Mjcwm 2 52531 308503 2026-09-18T01:34:32Z Mjcwm 47428 /* */ 308503 wikitext text/x-wiki Maxamed xaaji jaamac cabdilaahi Awal olg647vmfhss698iyxk07ca93d15ogu User talk:SHB2000 3 52532 308505 2026-09-18T03:43:33Z Max 35277 Max la wareejiyay bogga [[User talk:SHB2000]] ilaa [[User talk:SHB]]: Bogga si otomaatig ah ayaa loo wareejiyay intii lagu jiray magaca beddelka isticmaalaha "[[Special:CentralAuth/SHB2000|SHB2000]]" loona beddelay "[[Special:CentralAuth/SHB|SHB]]" 308505 wikitext text/x-wiki #REDIRECT [[User talk:SHB]] dgionzejbwpmne0gol3e840676zou8k