local p = {} local convert = require('মডিউল:সংখ্যা রূপান্তরকারী').convert   Background colours for table cells ---------- local colours = {     W = "#99FF99",     ['জ'] = "#99FF99",     L = "#FFDDDD",     ['হা'] = "#FFDDDD",     N = "#DFDFFF",     D = "#F0E68C",     T = "#DDFFDD",     X = "#FFD" } local classes = {     W = "yes table-yes2",     L = "no table-no2",     N = "noresult",     X = "partial table-partial" } local elimColour = "#DCDCDC" -- Eliminated  function trim(s)     if not s then         return nil     else         return (mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1"))     end end  function getArgs(frame)     local parent = frame:getParent();     local args = {}     for k,v in pairs(parent.args) do         args[k] = trim(v)     end     for k,v in pairs(frame.args) do         args[k] = trim(v)     end     return args; end  -- --   Match class -- local cricmatch = {}  cricmatch.__index = function(t, key)     local ret = rawget(t, key)     if ret then         return ret     end     ret = cricmatch[key]     if type(ret) == 'function' then         return function(...)             return ret(t, ...)         end     else         return ret     end end  cricmatch.title = function(m, home)     local opponent = home and m.away or m.home     local venue = home and 'স্বাগতিক' or 'অতিথি'     local title = string.format('বনাম %s (%s)', opponent.fullName, venue)     if m.result ~= 'H' and m.result ~= 'A' then         return title     end      local marginText = (m.result == 'H' and home or         m.result == 'A' and not home) and ' জয়ী' or ' পরাজিত'     if m.margin == 'F' then         marginText = "বাজেয়াপ্তে" .. marginText     elseif m.margin == 'SO' then         marginText = "সুপার ওভারে" .. marginText     else         local n = tonumber(string.sub(m.margin, 1, -2))         local t = string.upper(string.sub(m.margin, -1, -1))         if t == 'R' then             marginText = "%d রানে" .. marginText         elseif t == 'W' then             marginText =  "%d উইকেটে" .. marginText         elseif t == 'I' then             marginText = "একটি ইনিংস ও %d রানে" .. marginText         end         if marginText and n then             marginText = string.format(marginText, n)  --           if n > 1 then marginText = marginText .. "s" end         end         if m.dl then             marginText = marginText                 .. ' (' .. m.dl .. ')'         end     end     return convert('bn', tostring(marginText)) .. ' ' .. title end  cricmatch.render = function(m, row, team, points)     local cell = row:tag('td')     local home = m.home == team     local span = cell:tag('span'):attr('title', m.title(home))      local result = m.result     local gained = 0     if m.result == 'H' then         result = home and 'W' or 'L'         gained = home and 2 or 0     elseif m.result == 'A' then         result = home and 'L' or 'W'         gained = home and 0 or 2     elseif m.result == 'N' or m.result == 'T' then         gained = 1     else         cell             :css('background-color', colours.X)             :attr('class', classes.X)         span:wikitext(string.format('?', m.id))         return points     end      points = points + gained     cell:css('background-color', colours[result])     span:wikitext(string.format('%s', m.id, convert('bn', tostring(points))))     if classes[cell] then cell:attr('class', classes[cell]) end     return points end  function createMatch(id, home, away, result, margin, dl)     if not home or not away then         return nil     end     local match = {}     setmetatable(match, cricmatch)     match.id = id     match.home = home     match.away = away     match.result = result     match.margin = margin     match.dl = dl     return match end  -- --   Helper functions -- function buildLegend(container, types)     local key = container:tag('table')         :addClass('wikitable')         :css('float', 'right')         :css('text-align', 'center')         :css('font-size', '90%')         :css('margin', '0 0 0 10px')         :tag('td')             :css('background-color', colours.W)             :css('padding-left', '10px')             :css('padding-right', '10px')             :wikitext('জয়')         :done()         :tag('td')             :css('background-color', colours.L)             :css('padding', '0 10px')             :wikitext('হার')         :done()         :tag('td')             :css('background-color', colours.N)             :css('padding', '0 10px')             :wikitext('ফলাফল হয়নি')         :done()      local list = container:tag('ul')         :css('font-size', '90%')         :tag('li')             :wikitext("টীকা: প্রতিটি গ্রুপ ম্যাচের খেলা শেষে " ..                 "পয়েন্ট হালনাগাদ করা হয়েছে।")         :done()         :tag('li')             :wikitext("টীকা: খেলার সারাংশ দেখতে (গ্রুপ খেলার) পয়েন্টের উপর " ..                 "অথবা (প্লে-অফের) জ/হা এর উপর ক্লিক করুন।")         :done()     return container end  function getMatchData(args, teams)     local i, m = 0, 1     local match     local matches = {}     local home, away, result, margin, dl     local dlText = args.dls == 'Y' and 'DLS' or 'ডি/এল'     while args[i * 5 + 5] do         home = teams[trim(args[i * 5 + 1])]         away = teams[args[i * 5 + 2]]         result = args[i * 5 + 3]         margin = args[i * 5 + 4]         dl = args[i * 5 + 5] == "Y"         match = createMatch(m, home, away, result, margin, dl and dlText or nil)         if match then             table.insert(matches, match)             m = m + 1         end         i = i + 1     end     return matches end  function renderTeam(tbl, count, team, matches, koStages, total)     local row = tbl:tag('tr')         :tag('th')             :css('text-align', 'left')             :css('padding-right', '10px')             :css('border-right', 'black solid 2px')             :css('min-width', '160px')             :wikitext(string.format('%s', team.pageName, team.fullName))         :done()     local points = 0     for i = 1, count do         if matches[i] then             points = matches[i].render(row, team, points)         else             row:tag('td')         end     end     local cell, koMatches, koMatch, result, colour, matchNo     local eliminated = true     for i = 1, #koStages do         result = nil         cell = row:tag('td')         if i == 1 then cell:css('border-left', 'black solid 2px') end         koMatches = koStages[i].matches         for j = 1, #koMatches do             total = total + 1             koMatch = koMatches[j]             if result then             elseif not koMatch.winner then                 eliminated = false             else                 if koMatch.winner == team.code then                     result = 'জ'                     matchNo = total                 elseif koMatch.loser == team.code then                     result = 'হা'                     matchNo = total                 end             end         end         if result then             cell:css('background-color', colours[result])                 :wikitext(string.format('%s', matchNo, convert('bn', tostring(result))))         elseif eliminated then             cell:css('background-color', elimColour)         end     end end  p.create = function(args, teams, koName, koStages)     local matches = getMatchData(args, teams)     local wrapper = mw.html.create('div')      local codes, results = {}, {}     local count = 0     for _, match in ipairs(matches) do         local home = match.home.code         local away = match.away.code         if not results[home] then             table.insert(codes, home)             results[home] = {}         end         if not results[away] then             table.insert(codes, away)             results[away] = {}         end         table.insert(results[home], match)         table.insert(results[away], match)         count = math.max(count, #results[home], #results[away])     end     local teamsort = function(t1, t2)         return teams[t1].fullName < teams[t2].fullName     end     table.sort(codes, teamsort)      local container = wrapper:tag('div')         :css('float', 'left')         :css('max-width', '100%')     local tbl = container:tag('table')         :attr('class', 'wikitable')         :css('width', '100%')         :css('text-align', 'center')         :css('display', 'block')         :css('overflow', 'auto')         :css('border', 'none')      -- headers     local row = tbl:tag('tr')     row         :tag('th')             :attr('scope', 'col')             :attr('rowspan', '2')             :css('border-right', 'black solid 2px')             :wikitext('দল')         :done()         :tag('th'):attr('colspan', count):wikitext('গ্রুপের খেলা'):done()     if koStages then         row:tag('th')             :attr('colspan', #koStages)             :css('border-left', 'black solid 2px')             :wikitext(koName or 'নকআউট ম্যাচ')     end      row = tbl:tag('tr')     for i = 1, count do         row:tag('th'):attr('scope', 'col'):css('min-width', '18px'):wikitext(convert('bn', tostring(i)))     end     local cell     for i = 1, #koStages do         cell = row:tag('th')             :attr('scope', 'col')             :css('width', '18px')             :tag('abbr')                 :attr('title', koStages[i].name)                 :wikitext(koStages[i].abbr)             :done()         if i == 1 then cell:css('border-left', 'black solid 2px') end     end      -- matches     for _, code in ipairs(codes) do         renderTeam(tbl, count, teams[code], results[code], koStages, #matches)     end      buildLegend(container)     wrapper:tag('div'):css('clear', 'left')     return tostring(wrapper) end  p.IPL = function(frame)     local args = getArgs(frame)     local teams = mw.loadData("Module:IndianPremierLeague/Teams")     local teamsAssoc = {}     local i = 1     while teams[i] do         teamsAssoc[teams[i].code] = teams[i]         i = i + 1     end     local playoffs = {         { name = 'বাছাইপর্ব ১ বা এলিমিনেটর', abbr = 'ব১/এ', matches = {             { winner = args.P1W, loser = args.P1L },             { winner = args.P2W, loser = args.P2L }         }},         { name = 'বাছাইপর্ব ২', abbr = 'বা২', matches = {             { winner = args.P3W, loser = args.P3L }         }},         { name = 'ফাইনাল', abbr = 'ফা', matches = {             { winner = args.P4W, loser = args.P4L }         }}     }     return p.create(args, teamsAssoc, "প্লে-অফ", playoffs) end  p.IPL_SF = function(frame)     local args = getArgs(frame)     local teams = mw.loadData("Module:IndianPremierLeague/Teams")     local teamsAssoc = {}     local i = 1     while teams[i] do         teamsAssoc[teams[i].code] = teams[i]         i = i + 1     end     local knockout = {         { name = 'সেমি-ফাইনাল', abbr = 'সেফা', matches = {             { winner = args.SF1W, loser = args.SF1L },             { winner = args.SF2W, loser = args.SF2L }         }},         { name = 'ফাইনাল', abbr = 'ফা', matches = {             { winner = args.FW, loser = args.FL }         }}     }     return p.create(args, teamsAssoc, "নকআউট", knockout) end  p.WPL = function(frame)     local args = getArgs(frame)     local teams = mw.loadData("Module:Women's Premier League teams")     local teamsAssoc = {}     local i = 1     while teams[i] do         teamsAssoc[teams[i].code] = teams[i]         i = i + 1     end     local playoffs = {         { name = 'এলিমিনেটর', abbr = 'এলিমিনেটর' , matches = {             { winner = args.P1W, loser = args.P1L }         }},         { name = 'ফাইনাল', abbr = 'ফাইনাল', matches = {             { winner = args.P2W, loser = args.P2L }         }}     }     return p.create(args, teamsAssoc, "প্লে–অফ", playoffs) end  p.WPL_SF = function(frame)     local args = getArgs(frame)     local teams = mw.loadData("Module:Women's Premier League teams")     local teamsAssoc = {}     local i = 1     while teams[i] do         teamsAssoc[teams[i].code] = teams[i]         i = i + 1     end     local knockout = {         { name = 'Semi-finals', abbr = 'সেমি', matches = {             { winner = args.SF1W, loser = args.SF1L },             { winner = args.SF2W, loser = args.SF2L }         }},         { name = 'Final', abbr = 'ফাই', matches = {             { winner = args.FW, loser = args.FL }         }}     }     return p.create(args, teamsAssoc, "নকআউট", knockout) end  p.PSL = function(frame)     local args = getArgs(frame)     local teams = mw.loadData("Module:PakistanSuperLeagueTeams")     local teamsAssoc = {}     local i = 1     while teams[i] do         teamsAssoc[teams[i].code] = teams[i]         i = i + 1     end     local playoffs = {         { name = 'Eliminator 1 or Qualifier', abbr = 'E1/Q', matches = {             { winner = args.P1W, loser = args.P1L },             { winner = args.P2W, loser = args.P2L }         }},         { name = 'Eliminator 2', abbr = 'E2', matches = {             { winner = args.P3W, loser = args.P3L }         }},         { name = 'Final', abbr = 'F', matches = {             { winner = args.P4W, loser = args.P4L }         }}     }     return p.create(args, teamsAssoc, "Playoffs", playoffs) end  p.PSL_SF = function(frame)     local args = getArgs(frame)     local teams = mw.loadData("Module:PakistanSuperLeagueTeams")     local teamsAssoc = {}     local i = 1     while teams[i] do         teamsAssoc[teams[i].code] = teams[i]         i = i + 1     end     local knockout = {         { name = 'Semi-finals', abbr = 'SF', matches = {             { winner = args.SF1W, loser = args.SF1L },             { winner = args.SF2W, loser = args.SF2L }         }},         { name = 'Final', abbr = 'F', matches = {             { winner = args.FW, loser = args.FL }         }}     }     return p.create(args, teamsAssoc, "Knockout", knockout) end  return p