Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Records: Difference between revisions

From eSportsAmaze
Created page with "local p = {} local cargo = mw.ext.cargo local html = mw.html local function sqlEscape(s) if not s then return "" end return s:gsub("\\", "\\\\"):gsub("'", "\\'") end local function getNum(s) if not s then return 0 end return tonumber(s:match("%d+")) or 0 end function p.main(frame) local args = frame:getParent().args local tournamentName = args.tournament or mw.title.getCurrentTitle().text local whereClause = string.format("tournament = '%s'..."
 
No edit summary
Line 19: Line 19:
      
      
     -- ==========================================
     -- ==========================================
     -- 1. DAILY RECORDS (Grouped by Day & Team)
     -- 1. DATA FETCHING (Single Pass)
     -- ==========================================
     -- ==========================================
     local dayStats = cargo.query("MatchStats_Team",  
     local teamMatch = cargo.query("MatchStats_Team", "tournament_day, team, map, total_pts, elim_pts", { where = whereClause, limit = 5000 })
        "tournament_day, team, SUM(total_pts)=day_total, SUM(elim_pts)=day_elims",  
    local playerMatch = cargo.query("MatchStats_Player", "tournament_day, player, team, player_elims, damage, mvp, long_elim, rescues", { where = whereClause, limit = 5000 })
        { where = whereClause, groupBy = "tournament_day, team", limit = 5000 }
    )
      
      
     local days = {}
     -- Data Holders
     local dayList = {}
     local d_team = {}     -- Daily Team
      
     local d_player = {}   -- Daily Player
    if dayStats and #dayStats > 0 then
    local o_player = {}   -- Overall Player
        for _, r in ipairs(dayStats) do
     local map_rec = {}     -- Map Records
            local day = r.tournament_day
     local daySet = {}
            if day and day ~= "" then
                if not days[day] then
                    days[day] = { pts = {team="-", val=-1}, elims = {team="-", val=-1} }
                    table.insert(dayList, day)
                end
               
                local pts = tonumber(r.day_total) or 0
                local elims = tonumber(r.day_elims) or 0
               
                if pts > days[day].pts.val then days[day].pts = {team=r.team, val=pts} end
                if elims > days[day].elims.val then days[day].elims = {team=r.team, val=elims} end
            end
        end
    end
   
    -- Sort days intelligently (Day 1, Day 2 ... Day 10)
     table.sort(dayList, function(a, b) return getNum(a) < getNum(b) end)
 
    -- ==========================================
    -- 2. OVERALL MATCH RECORDS
     -- ==========================================
    local teamMatch = cargo.query("MatchStats_Team", "team, total_pts, elim_pts", { where = whereClause, limit = 5000 })
     local playerMatch = cargo.query("MatchStats_Player", "player, team, player_elims, damage", { where = whereClause, limit = 5000 })
      
      
     local rec = {
     local rec = {
         t_pts = {name="-", val=-1},
         t_pts = {n="-", v=-1}, t_elims = {n="-", v=-1},
        t_elims = {name="-", val=-1},
         p_elims = {n="-", t="-", v=-1}, p_dmg = {n="-", t="-", v=-1},
         p_elims = {name="-", team="-", val=-1},
         long = {n="-", t="-", v=-1}, rescues = {n="-", t="-", v=-1}
         p_dmg = {name="-", team="-", val=-1}
     }
     }
      
 
     -- Process Teams
     if teamMatch then
     if teamMatch then
         for _, r in ipairs(teamMatch) do
         for _, r in ipairs(teamMatch) do
             local pts = tonumber(r.total_pts) or 0
             local pts = tonumber(r.total_pts) or 0
             local elims = tonumber(r.elim_pts) or 0
             local elims = tonumber(r.elim_pts) or 0
             if pts > rec.t_pts.val then rec.t_pts = {name=r.team, val=pts} end
            local day = r.tournament_day
             if elims > rec.t_elims.val then rec.t_elims = {name=r.team, val=elims} end
            local map = r.map
           
            -- Single Match Highs
             if pts > rec.t_pts.v then rec.t_pts = {n=r.team, v=pts} end
             if elims > rec.t_elims.v then rec.t_elims = {n=r.team, v=elims} end
           
            -- Map Highs
            if map and map ~= "" then
                if not map_rec[map] or pts > map_rec[map].v then map_rec[map] = {n=r.team, v=pts} end
            end
           
            -- Daily Accumulation
            if day and day ~= "" then
                daySet[day] = true
                if not d_team[day] then d_team[day] = {} end
                if not d_team[day][r.team] then d_team[day][r.team] = {pts=0, elims=0} end
                d_team[day][r.team].pts = d_team[day][r.team].pts + pts
                d_team[day][r.team].elims = d_team[day][r.team].elims + elims
            end
         end
         end
     end
     end
      
      
    -- Process Players
     if playerMatch then
     if playerMatch then
         for _, r in ipairs(playerMatch) do
         for _, r in ipairs(playerMatch) do
             local elims = tonumber(r.player_elims) or 0
             local elims = tonumber(r.player_elims) or 0
             local dmg = tonumber(r.damage) or 0
             local dmg = tonumber(r.damage) or 0
             if elims > rec.p_elims.val then rec.p_elims = {name=r.player, team=r.team, val=elims} end
            local mvp = tonumber(r.mvp) or 0
             if dmg > rec.p_dmg.val then rec.p_dmg = {name=r.player, team=r.team, val=dmg} end
            local long = tonumber(r.long_elim) or 0
            local res = tonumber(r.rescues) or 0
            local day = r.tournament_day
            local p = r.player
           
            -- Single Match Highs
             if elims > rec.p_elims.v then rec.p_elims = {n=p, t=r.team, v=elims} end
             if dmg > rec.p_dmg.v then rec.p_dmg = {n=p, t=r.team, v=dmg} end
            if long > rec.long.v then rec.long = {n=p, t=r.team, v=long} end
            if res > rec.rescues.v then rec.rescues = {n=p, t=r.team, v=res} end
           
            -- Overall Accumulation
            if not o_player[p] then o_player[p] = {t=r.team, elims=0, mvp=0} end
            o_player[p].elims = o_player[p].elims + elims
            o_player[p].mvp = o_player[p].mvp + mvp
           
            -- Daily Accumulation
            if day and day ~= "" then
                daySet[day] = true
                if not d_player[day] then d_player[day] = {} end
                if not d_player[day][p] then d_player[day][p] = {t=r.team, elims=0, dmg=0} end
                d_player[day][p].elims = d_player[day][p].elims + elims
                d_player[day][p].dmg = d_player[day][p].dmg + dmg
            end
        end
    end
 
    -- ==========================================
    -- 2. DETERMINE WINNERS
    -- ==========================================
    -- Overall Leaders
    local top_fragger = {n="-", t="-", v=-1}
    local top_mvp = {n="-", t="-", v=-1}
    for p, d in pairs(o_player) do
        if d.elims > top_fragger.v then top_fragger = {n=p, t=d.t, v=d.elims} end
        if d.mvp > top_mvp.v then top_mvp = {n=p, t=d.t, v=d.mvp} end
    end
 
    -- Daily Leaders
    local dayList = {}
    for day in pairs(daySet) do table.insert(dayList, day) end
    table.sort(dayList, function(a, b) return getNum(a) < getNum(b) end)
   
    local dailyWinners = {}
    for _, day in ipairs(dayList) do
        dailyWinners[day] = { t_pts = {n="-", v=-1}, p_elims = {n="-", t="-", v=-1} }
       
        if d_team[day] then
            for t, d in pairs(d_team[day]) do
                if d.pts > dailyWinners[day].t_pts.v then dailyWinners[day].t_pts = {n=t, v=d.pts} end
            end
        end
        if d_player[day] then
            for p, d in pairs(d_player[day]) do
                if d.elims > dailyWinners[day].p_elims.v then dailyWinners[day].p_elims = {n=p, t=d.t, v=d.elims} end
            end
         end
         end
     end
     end
    -- Map List Sort
    local mapOrder = {}
    for m in pairs(map_rec) do table.insert(mapOrder, m) end
    table.sort(mapOrder)


     -- ==========================================
     -- ==========================================
     -- 3. BUILD UI
     -- 3. BUILD UI
     -- ==========================================
     -- ==========================================
     if #dayList == 0 and rec.t_pts.val == -1 then
     if rec.t_pts.v == -1 then return "" end -- No data
        return "" -- No data yet
    end


     local root = html.create('div'):addClass('rec-wrapper')
     local root = html.create('div'):addClass('rec-wrapper')
     root:tag('div'):addClass('rec-header'):wikitext('🏆 Tournament Records')
     root:tag('div'):addClass('rec-header'):wikitext('🏆 Tournament Records')
      
      
    -- BANNER: Overall Leaders
    local banner = root:tag('div'):addClass('rec-banner')
    if top_fragger.v > 0 then
        local b1 = banner:tag('div'):addClass('rec-ban-item')
        b1:tag('div'):addClass('rec-ban-lbl'):wikitext('Tournament Top Fragger')
        b1:tag('div'):addClass('rec-ban-val'):wikitext('🥇 [[' .. top_fragger.n .. ']] <span class="rec-dim">(' .. top_fragger.t .. ')</span>')
        b1:tag('div'):addClass('rec-ban-stat'):wikitext(top_fragger.v .. ' Elims')
    end
    if top_mvp.v > 0 then
        local b2 = banner:tag('div'):addClass('rec-ban-item')
        b2:tag('div'):addClass('rec-ban-lbl'):wikitext('Tournament MVP Leader')
        b2:tag('div'):addClass('rec-ban-val'):wikitext('⭐ [[' .. top_mvp.n .. ']] <span class="rec-dim">(' .. top_mvp.t .. ')</span>')
        b2:tag('div'):addClass('rec-ban-stat'):wikitext(top_mvp.v .. ' Match MVPs')
    end
     local grid = root:tag('div'):addClass('rec-grid')
     local grid = root:tag('div'):addClass('rec-grid')
   
    -- LEFT COLUMN: Overall Single Match Records
    local colLeft = grid:tag('div'):addClass('rec-col')
    colLeft:tag('div'):addClass('rec-col-title'):wikitext('Single Match Highs')
      
      
     local function addRecord(parent, icon, title, name, subname, val, suffix)
     local function addRecord(parent, icon, title, name, subname, val, suffix)
         if val == -1 then return end
         if val <= 0 then return end
         local box = parent:tag('div'):addClass('rec-box')
         local box = parent:tag('div'):addClass('rec-box')
         box:tag('div'):addClass('rec-icon'):wikitext(icon)
         box:tag('div'):addClass('rec-icon'):wikitext(icon)
         local info = box:tag('div'):addClass('rec-info')
         local info = box:tag('div'):addClass('rec-info')
         info:tag('div'):addClass('rec-title'):wikitext(title)
         info:tag('div'):addClass('rec-title'):wikitext(title)
       
         local nameStr = "'''[[" .. name .. "]]'''"
         local nameStr = "'''[[" .. name .. "]]'''"
         if subname and subname ~= "-" then nameStr = nameStr .. " <span style='font-size:0.75em; color:var(--text-muted);'>(" .. subname .. ")</span>" end
         if subname and subname ~= "-" then nameStr = nameStr .. " <span class='rec-dim'>(" .. subname .. ")</span>" end
         info:tag('div'):addClass('rec-name'):wikitext(nameStr)
         info:tag('div'):addClass('rec-name'):wikitext(nameStr)
       
         box:tag('div'):addClass('rec-val'):wikitext(math.floor(val) .. '<span>' .. suffix .. '</span>')
         box:tag('div'):addClass('rec-val'):wikitext(val .. '<span>' .. suffix .. '</span>')
     end
     end
      
 
     addRecord(colLeft, '🔥', 'Highest Team Points', rec.t_pts.name, nil, rec.t_pts.val, 'pts')
    -- COL 1: Single Match Highs
     addRecord(colLeft, '⚔️', 'Highest Team Elims', rec.t_elims.name, nil, rec.t_elims.val, 'elims')
     local col1 = grid:tag('div'):addClass('rec-col')
     addRecord(colLeft, '💀', 'Highest Player Elims', rec.p_elims.name, rec.p_elims.team, rec.p_elims.val, 'elims')
    col1:tag('div'):addClass('rec-col-title'):wikitext('Single Match Records')
     if rec.p_dmg.val > 0 then
     addRecord(col1, '🔥', 'Highest Team Points', rec.t_pts.n, nil, rec.t_pts.v, 'pts')
        addRecord(colLeft, '💥', 'Highest Player Damage', rec.p_dmg.name, rec.p_dmg.team, math.floor(rec.p_dmg.val), 'dmg')
     addRecord(col1, '⚔️', 'Highest Team Elims', rec.t_elims.n, nil, rec.t_elims.v, 'elims')
     addRecord(col1, '💀', 'Highest Player Elims', rec.p_elims.n, rec.p_elims.t, rec.p_elims.v, 'elims')
     addRecord(col1, '💥', 'Highest Player Dmg', rec.p_dmg.n, rec.p_dmg.t, rec.p_dmg.v, 'dmg')
 
    -- COL 2: Maps & Highlights
    local col2 = grid:tag('div'):addClass('rec-col')
    col2:tag('div'):addClass('rec-col-title'):wikitext('Map Highs & Highlights')
    for _, m in ipairs(mapOrder) do
        addRecord(col2, '🗺️', m .. ' Record', map_rec[m].n, nil, map_rec[m].v, 'pts')
     end
     end
    addRecord(col2, '🔭', 'Longest Elimination', rec.long.n, rec.long.t, rec.long.v, 'm')
    addRecord(col2, '⛑️', 'Most Rescues', rec.rescues.n, rec.rescues.t, rec.rescues.v, 'revives')


     -- RIGHT COLUMN: Daily Leaders
     -- COL 3: Daily Leaders
     local colRight = grid:tag('div'):addClass('rec-col')
     local col3 = grid:tag('div'):addClass('rec-col')
     colRight:tag('div'):addClass('rec-col-title'):wikitext('Daily Leaders')
     col3:tag('div'):addClass('rec-col-title'):wikitext('Daily Top Performers')
   
     local dayListContainer = col3:tag('div'):addClass('rec-day-list')
     local dayListContainer = colRight:tag('div'):addClass('rec-day-list')
      
      
     for _, day in ipairs(dayList) do
     for _, day in ipairs(dayList) do
         local d = days[day]
         local d = dailyWinners[day]
         local dayRow = dayListContainer:tag('div'):addClass('rec-day-row')
         local dayRow = dayListContainer:tag('div'):addClass('rec-day-row')
         dayRow:tag('div'):addClass('rec-day-name'):wikitext(day)
         dayRow:tag('div'):addClass('rec-day-name'):wikitext(day)
          
          
         local dStats = dayRow:tag('div'):addClass('rec-day-stats')
         local dStats = dayRow:tag('div'):addClass('rec-day-stats')
         dStats:tag('div'):wikitext("🏅 '''Pts:''' [[" .. d.pts.team .. "]] <span style='color:var(--text-muted)'>(" .. d.pts.val .. ")</span>")
         if d.t_pts.v > 0 then
         dStats:tag('div'):wikitext("🔫 '''Elims:''' [[" .. d.elims.team .. "]] <span style='color:var(--text-muted)'>(" .. d.elims.val .. ")</span>")
            dStats:tag('div'):wikitext("🛡️ [[" .. d.t_pts.n .. "]] <span class='rec-dim'>(" .. d.t_pts.v .. " pts)</span>")
         end
        if d.p_elims.v > 0 then
            dStats:tag('div'):wikitext("🎯 [[" .. d.p_elims.n .. "]] <span class='rec-dim'>(" .. d.p_elims.v .. " elims)</span>")
        end
     end
     end



Revision as of 06:49, 21 May 2026

Documentation for this module may be created at Module:Records/doc

local p = {}
local cargo = mw.ext.cargo
local html = mw.html

local function sqlEscape(s)
    if not s then return "" end
    return s:gsub("\\", "\\\\"):gsub("'", "\\'")
end

local function getNum(s)
    if not s then return 0 end
    return tonumber(s:match("%d+")) or 0
end

function p.main(frame)
    local args = frame:getParent().args
    local tournamentName = args.tournament or mw.title.getCurrentTitle().text
    local whereClause = string.format("tournament = '%s'", sqlEscape(tournamentName))
    
    -- ==========================================
    -- 1. DATA FETCHING (Single Pass)
    -- ==========================================
    local teamMatch = cargo.query("MatchStats_Team", "tournament_day, team, map, total_pts, elim_pts", { where = whereClause, limit = 5000 })
    local playerMatch = cargo.query("MatchStats_Player", "tournament_day, player, team, player_elims, damage, mvp, long_elim, rescues", { where = whereClause, limit = 5000 })
    
    -- Data Holders
    local d_team = {}      -- Daily Team
    local d_player = {}    -- Daily Player
    local o_player = {}    -- Overall Player
    local map_rec = {}     -- Map Records
    local daySet = {}
    
    local rec = {
        t_pts = {n="-", v=-1}, t_elims = {n="-", v=-1},
        p_elims = {n="-", t="-", v=-1}, p_dmg = {n="-", t="-", v=-1},
        long = {n="-", t="-", v=-1}, rescues = {n="-", t="-", v=-1}
    }

    -- Process Teams
    if teamMatch then
        for _, r in ipairs(teamMatch) do
            local pts = tonumber(r.total_pts) or 0
            local elims = tonumber(r.elim_pts) or 0
            local day = r.tournament_day
            local map = r.map
            
            -- Single Match Highs
            if pts > rec.t_pts.v then rec.t_pts = {n=r.team, v=pts} end
            if elims > rec.t_elims.v then rec.t_elims = {n=r.team, v=elims} end
            
            -- Map Highs
            if map and map ~= "" then
                if not map_rec[map] or pts > map_rec[map].v then map_rec[map] = {n=r.team, v=pts} end
            end
            
            -- Daily Accumulation
            if day and day ~= "" then
                daySet[day] = true
                if not d_team[day] then d_team[day] = {} end
                if not d_team[day][r.team] then d_team[day][r.team] = {pts=0, elims=0} end
                d_team[day][r.team].pts = d_team[day][r.team].pts + pts
                d_team[day][r.team].elims = d_team[day][r.team].elims + elims
            end
        end
    end
    
    -- Process Players
    if playerMatch then
        for _, r in ipairs(playerMatch) do
            local elims = tonumber(r.player_elims) or 0
            local dmg = tonumber(r.damage) or 0
            local mvp = tonumber(r.mvp) or 0
            local long = tonumber(r.long_elim) or 0
            local res = tonumber(r.rescues) or 0
            local day = r.tournament_day
            local p = r.player
            
            -- Single Match Highs
            if elims > rec.p_elims.v then rec.p_elims = {n=p, t=r.team, v=elims} end
            if dmg > rec.p_dmg.v then rec.p_dmg = {n=p, t=r.team, v=dmg} end
            if long > rec.long.v then rec.long = {n=p, t=r.team, v=long} end
            if res > rec.rescues.v then rec.rescues = {n=p, t=r.team, v=res} end
            
            -- Overall Accumulation
            if not o_player[p] then o_player[p] = {t=r.team, elims=0, mvp=0} end
            o_player[p].elims = o_player[p].elims + elims
            o_player[p].mvp = o_player[p].mvp + mvp
            
            -- Daily Accumulation
            if day and day ~= "" then
                daySet[day] = true
                if not d_player[day] then d_player[day] = {} end
                if not d_player[day][p] then d_player[day][p] = {t=r.team, elims=0, dmg=0} end
                d_player[day][p].elims = d_player[day][p].elims + elims
                d_player[day][p].dmg = d_player[day][p].dmg + dmg
            end
        end
    end

    -- ==========================================
    -- 2. DETERMINE WINNERS
    -- ==========================================
    -- Overall Leaders
    local top_fragger = {n="-", t="-", v=-1}
    local top_mvp = {n="-", t="-", v=-1}
    for p, d in pairs(o_player) do
        if d.elims > top_fragger.v then top_fragger = {n=p, t=d.t, v=d.elims} end
        if d.mvp > top_mvp.v then top_mvp = {n=p, t=d.t, v=d.mvp} end
    end

    -- Daily Leaders
    local dayList = {}
    for day in pairs(daySet) do table.insert(dayList, day) end
    table.sort(dayList, function(a, b) return getNum(a) < getNum(b) end)
    
    local dailyWinners = {}
    for _, day in ipairs(dayList) do
        dailyWinners[day] = { t_pts = {n="-", v=-1}, p_elims = {n="-", t="-", v=-1} }
        
        if d_team[day] then
            for t, d in pairs(d_team[day]) do
                if d.pts > dailyWinners[day].t_pts.v then dailyWinners[day].t_pts = {n=t, v=d.pts} end
            end
        end
        if d_player[day] then
            for p, d in pairs(d_player[day]) do
                if d.elims > dailyWinners[day].p_elims.v then dailyWinners[day].p_elims = {n=p, t=d.t, v=d.elims} end
            end
        end
    end

    -- Map List Sort
    local mapOrder = {}
    for m in pairs(map_rec) do table.insert(mapOrder, m) end
    table.sort(mapOrder)

    -- ==========================================
    -- 3. BUILD UI
    -- ==========================================
    if rec.t_pts.v == -1 then return "" end -- No data

    local root = html.create('div'):addClass('rec-wrapper')
    root:tag('div'):addClass('rec-header'):wikitext('🏆 Tournament Records')
    
    -- BANNER: Overall Leaders
    local banner = root:tag('div'):addClass('rec-banner')
    if top_fragger.v > 0 then
        local b1 = banner:tag('div'):addClass('rec-ban-item')
        b1:tag('div'):addClass('rec-ban-lbl'):wikitext('Tournament Top Fragger')
        b1:tag('div'):addClass('rec-ban-val'):wikitext('🥇 [[' .. top_fragger.n .. ']] <span class="rec-dim">(' .. top_fragger.t .. ')</span>')
        b1:tag('div'):addClass('rec-ban-stat'):wikitext(top_fragger.v .. ' Elims')
    end
    if top_mvp.v > 0 then
        local b2 = banner:tag('div'):addClass('rec-ban-item')
        b2:tag('div'):addClass('rec-ban-lbl'):wikitext('Tournament MVP Leader')
        b2:tag('div'):addClass('rec-ban-val'):wikitext('⭐ [[' .. top_mvp.n .. ']] <span class="rec-dim">(' .. top_mvp.t .. ')</span>')
        b2:tag('div'):addClass('rec-ban-stat'):wikitext(top_mvp.v .. ' Match MVPs')
    end

    local grid = root:tag('div'):addClass('rec-grid')
    
    local function addRecord(parent, icon, title, name, subname, val, suffix)
        if val <= 0 then return end
        local box = parent:tag('div'):addClass('rec-box')
        box:tag('div'):addClass('rec-icon'):wikitext(icon)
        local info = box:tag('div'):addClass('rec-info')
        info:tag('div'):addClass('rec-title'):wikitext(title)
        local nameStr = "'''[[" .. name .. "]]'''"
        if subname and subname ~= "-" then nameStr = nameStr .. " <span class='rec-dim'>(" .. subname .. ")</span>" end
        info:tag('div'):addClass('rec-name'):wikitext(nameStr)
        box:tag('div'):addClass('rec-val'):wikitext(math.floor(val) .. '<span>' .. suffix .. '</span>')
    end

    -- COL 1: Single Match Highs
    local col1 = grid:tag('div'):addClass('rec-col')
    col1:tag('div'):addClass('rec-col-title'):wikitext('Single Match Records')
    addRecord(col1, '🔥', 'Highest Team Points', rec.t_pts.n, nil, rec.t_pts.v, 'pts')
    addRecord(col1, '⚔️', 'Highest Team Elims', rec.t_elims.n, nil, rec.t_elims.v, 'elims')
    addRecord(col1, '💀', 'Highest Player Elims', rec.p_elims.n, rec.p_elims.t, rec.p_elims.v, 'elims')
    addRecord(col1, '💥', 'Highest Player Dmg', rec.p_dmg.n, rec.p_dmg.t, rec.p_dmg.v, 'dmg')

    -- COL 2: Maps & Highlights
    local col2 = grid:tag('div'):addClass('rec-col')
    col2:tag('div'):addClass('rec-col-title'):wikitext('Map Highs & Highlights')
    for _, m in ipairs(mapOrder) do
        addRecord(col2, '🗺️', m .. ' Record', map_rec[m].n, nil, map_rec[m].v, 'pts')
    end
    addRecord(col2, '🔭', 'Longest Elimination', rec.long.n, rec.long.t, rec.long.v, 'm')
    addRecord(col2, '⛑️', 'Most Rescues', rec.rescues.n, rec.rescues.t, rec.rescues.v, 'revives')

    -- COL 3: Daily Leaders
    local col3 = grid:tag('div'):addClass('rec-col')
    col3:tag('div'):addClass('rec-col-title'):wikitext('Daily Top Performers')
    local dayListContainer = col3:tag('div'):addClass('rec-day-list')
    
    for _, day in ipairs(dayList) do
        local d = dailyWinners[day]
        local dayRow = dayListContainer:tag('div'):addClass('rec-day-row')
        dayRow:tag('div'):addClass('rec-day-name'):wikitext(day)
        
        local dStats = dayRow:tag('div'):addClass('rec-day-stats')
        if d.t_pts.v > 0 then
            dStats:tag('div'):wikitext("🛡️ [[" .. d.t_pts.n .. "]] <span class='rec-dim'>(" .. d.t_pts.v .. " pts)</span>")
        end
        if d.p_elims.v > 0 then
            dStats:tag('div'):wikitext("🎯 [[" .. d.p_elims.n .. "]] <span class='rec-dim'>(" .. d.p_elims.v .. " elims)</span>")
        end
    end

    return tostring(root)
end

return p