team = i/(step/2)
w = isHidden(round, 2*team-1) and isHidden(round, 2*team) and '0' or wdef
end
if (round < maxround) then
addBlank(i, {
['-color'] = 'black',
['-style'] = 'solid',
['-width'] = '0 ' .. w .. ' 0 0'})
else
addBlank(i)
end
if (round <= byes) then
team = team + 1
w = isHidden(round, 2*team-1) and isHidden(round, 2*team) and '0' or wdef
end
if (round < maxround) then
addBlank(i+1, {
['-color'] = 'black',
['-style'] = 'solid',
['-width'] = '0 ' .. w .. ' 0 0'})
else
addBlank(i+1)
end
group = group + 1
end
end  
local function getThirdOffset
local offset = (compact and 1 or 3) * (math.pow(2, rounds) - math.pow(2, rounds-3)) - (compact and 2 or 4)
if rounds < 4 then
offset = compact and 8 or 17
if rounds < 3 then
offset = compact and 6 or 10
if rounds < 2 then
offset = compact and 4 or 7
end
end
end
return offset
end  
local function renderThird(count)
local k = offsetThird
local row = rows[k]
local blank
if rounds < 2 then
blank = addBlank(k-1, {['height'] = ''})
end
blank = addBlank(k, rounds < 2 and {['height'] = ''} or nil)
addHeading(row, rounds + 1, args['3rd'] or 'Third place')
if rounds < 2 then
for i = 1,(compact and 1 or 2) do
blank = addBlank(k+i, {['height'] = ''})
end
end
k = k + (compact and 2 or 3)
for i = 1,2 do
row = rows[k]
blank = addBlank(k, rounds < 2 and {['height'] = ''} or nil)
if row then
renderTeam(row, rounds + 1, i, i == 1, false)
end
if rounds < 2 and not compact then
blank = addBlank(k+1, {['height'] = ''})
end
k = k + (compact and 1 or 2)
end
end  
local function maskRows(tbl, count, offsetcount)
local rmin = 1
local rmax = count
for i = rmin, rmax do
mask[i] = false
end
if showThird then
for i = offsetThird,(offsetThird+ (compact and 3 or 5)) do
rmax = (i > rmax) and i or rmax
mask[i] = true
end
end
for r = 1, maxround do
local teams = math.pow(2, rounds - r + 1)
local step = count / teams
local topTeam = true -- is top row in match-up
local team = 1  
for i = 1, count, step do
local offset, height, blank
local hideteam = false
if r <= byes then
hideteam = isHidden(r, team)
end
if (r == 1) and (RD1seedmap[team] <= 0) then
hideteam = true
end
if not hideteam then
local j = topTeam and i + step - (compact and 1 or 2) or i
mask[j] = true
end
team = team + 1
topTeam = not topTeam
end
end  
for r = 1, maxround do
local roundFromLast = rounds - r + 1
local groups = math.pow(2, roundFromLast - 2)
local step = count / groups
local group = 1
for i = step / 2, count, step do
if args['RD' .. r .. '-group' .. group] then
mask[i] = true
mask[i+1] = true
end
group = group + 1
end
end
local mmin, mmax = rmax, rmin
for i = rmin, rmax do
if mask[i] == true then
mmin = (i < mmin) and i or mmin
mmax = (i > mmax) and i or mmax
end
end
for i = mmin, mmax do
rows[i] = addTableRow(tbl)
end
end  
local function renderTree(tbl)
-- create 3 or 1 rows for every team
local count = math.pow(2, rounds) * (compact and 1 or 3)
local offsetcount = 2 * (compact and 1 or 3) + (compact and 2 or 3)
offsetThird = getThirdOffset
maskRows(tbl, count, offsetcount)
if showThird then
for i = (count+1), (offsetcount + offsetThird) do
if (rounds > 1) then
local blank = addBlank(i, nil, 1, tonumber(hideSeeds and '3' or '4') + legs[1])
if compact and (rounds > 2) then
blank = addBlank(i, nil, 1, tonumber(hideSeeds and '3' or '4') + legs[2])
end
end
end
end
if not compact then
-- fill rows with groups
for r = 1, rounds - 1 do
renderGroups(count, r)
end
end
-- fill rows with bracket
for r = 1, maxround do
renderRound(count, r)
end
if showThird then
renderThird(count, compact)
end
end  
local function renderHeadings(tbl)
local titleRow = addTableRow((not hideHeadings) and tbl or mw.html.create('table'))
local widthRow = addTableRow(tbl)
for r = 1, (compactFinal and (maxround-1) or maxround) do
titleRow:tag('td')
widthRow:tag('td'):css('width', r > 1 and * or *)
if compactFinal and r == (maxround-1) then
addHeading(titleRow, r, getRoundName(r), legs[r+1] - legs[r])
else
addHeading(titleRow, r, getRoundName(r) )
end
local seedCell
if (not hideSeeds) then
seedCell = widthRow:tag('td'):css('width', getWidth('seed', ''))
end
local teamCell = widthRow:tag('td'):css('width', getWidth('team', ''))
local scoreCells = {}
local legsr = legs[r]
if compactFinal and r == (maxround-1) then
legsr = legs[r+1] > legs[r] and legs[r+1] or legs[r]
end
for s = 1, legsr do
local score_
if aggregate and aggregate ~= '' and s > 1 and s == legsr then
score_width = getWidth('agg', getWidth('score', score_width))
else
score_width = getWidth('score', score_width)
end
scoreCells[s] = widthRow:tag('td'):css('width', score_width)
end
titleRow:tag('td')
widthRow:tag('td'):css('width', r < rounds and * or *)  
if compact then
teamCell:css('height', '')
else
if seedCell then
seedCell:wikitext('&nbsp;')
end
teamCell:wikitext('&nbsp;')
for s = 1, legs[r] do
scoreCells[s]:wikitext('&nbsp;')
end
end
end
end  
function p.main
parseArgs
rounds = tonumber(args.rounds) or 2
maxround = tonumber(args.maxround) or rounds
local teams = math.pow(2, rounds)
compact = (args['compact'] and (args['compact'] == 'yes' or args['compact'] == 'y'))
compactFinal = ((rounds > 4) and compact and args['compact-final'] and (args['compact-final'] == 'yes' or args['compact-final'] == 'y'))
sepwidth = tonumber(args['sepwidth'] or ((args.sets or args.legs) and 1) or (compact and 1) or 2) or 1
aggregate = (args['aggregate'] or ''):lower
aggsep = args['aggsep'] or args['aggregate'] or nil
boldwinner = args['boldwinner'] or args['bold_winner'] or ''
local autoSeeds = (args['autoseeds'] and (args['autoseeds'] == 'yes' or args['autoseeds'] == 'y'))
hideSeeds = (args['seeds'] and (args['seeds'] == 'no' or args['seeds'] == 'n'))
showSeeds = (args['seeds'] and (args['seeds'] == 'yes' or args['seeds'] == 'y'))
byes = (args['byes'] and (args['byes'] == 'yes' or args['byes'] == 'y') and 1) or (tonumber(args['byes'] or '0') or 0)
hideomittedscores = (args['hideomittedscores'] and (args['hideomittedscores'] == 'yes' or args['hideomittedscores'] == 'y') and 1) or (tonumber(args['hideomittedscores'] or '0') or 0)
hideHeadings = (args['headings'] and (args['headings'] == 'no' or args['headings'] == 'n'))
showThird = isnotblank(args['3rd']) or isnotblank(args['3rd-team1']) or isnotblank(args['3rd-team2'])
local align = (args['float'] or args['align'] or ''):lower
local clear = args['clear'] or ''
parseSeedmap(args['RD1-omit'])
parseLegs(args.sets or args.legs)  
if autoSeeds then
-- set default seeds for round 1
local seeds = getSeeds
for i = 1, table.getn(seeds) do
local argname = getTeamArgName(1, 'seed', i)
if not args[argname] then
args[argname] = seeds[i]
end
end
end  
-- create the table
local tbl = mw.html.create('table')
:css('-style', '')
:css('font-size', '90%')
:css('-collapse', 'separate')
:css('-spacing', '0')
:attr('cellpadding', '0')  
if (args['nowrap'] and (args['nowrap'] == 'yes' or args['nowrap'] == 'y')) then
tbl:css('white-space', 'nowrap')
end  
if align == '' then
tbl:css('float', '')
if clear ~= '' and clear ~= 'no' and clear ~= 'n' then
tbl:css('clear', '')
end
tbl:css('margin', '1em 0 1em 2em')
elseif align == '' then
tbl:css('float', '')
if clear ~= '' and clear ~= 'no' and clear ~= 'n' then
tbl:css('clear', '')
end
tbl:css('margin', '1em 2em 1em 0')
elseif align == '' or align == 'centre' then
tbl:css('margin', '1em auto')
else
tbl:css('margin', '1em 2em 1em 1em')
end  
renderHeadings(tbl)
renderTree(tbl)
if (args['wide'] and (args['wide'] == 'y' or args['wide'] == 'yes')) then
return '<div>' .. tostring(tbl) .. '</div>' .. tcats
end
return tostring(tbl) .. tcats
end  
function p.teamBracket
return p.main
end  
return p