From Wikipedia, the free encyclopedia

local p = {}

local entries = {}

local pathCell = {}

local crossCell = {}

local skipPath = {}

local shift = {}

local hascross = {}

local teams_per_match = {}

local rlegs = {}

local maxlegs = {}

local autolegs

local byes = {}

local hide = {}

local matchgroup = {}

local nowrap

local autocol

local seeds

local forceseeds

local boldwinner

local aggregate

local paramstyle

local masterindex



local function isempty(s)

	return s==nil or s==''

end



local function notempty(s)

	return s~=nil and s~=''

end



local function bargs(s)

	return pargss or fargss

end



local function toChar(num)

	return string.char(string.byte("a")+num-1)

end



local function unboldParenthetical(text)

    -- Replace wikilinks with unique placeholders

    local counter = 0

    local placeholders = {}

    text = text:gsub('%[%[(.-)%]%]', function(link)

        counter = counter + 1

        local placeholder = '__WIKILINK__' .. counter .. '__'

        placeholdersplaceholder = link

        return placeholder

    end)



    -- Apply <span style="font-weight:normal"></span> to parenthetical and bracketed text

    text = text:gsub('(%b())', '<span style="font-weight:normal">%1</span>')

               :gsub('(%b[])', '<span style="font-weight:normal">%1</span>')



    -- Restore the original wikilinks

    for placeholder, link in pairs(placeholders) do

        text = text:gsub(placeholder, '[[' .. link .. ']]')

    end



    return text

end



local function split(str,delim,tonum)

	result = {};

	local a = "[^"..table.concat(delim).."]+"

		for w in str:gmatch(a) do

			if tonum==true then

				table.insert(result, tonumber(w));

			else

				table.insert(result, w);

			end

		end

	return result;

end



local function getWidth(ctype, default)

	local result = bargs(ctype..'-width')

	if isempty(result) then return default end

	if tonumber(result)~=nil then return result..'px' end

	return result

end



local function matchGroups()

	for j=minc,c do

		matchgroupj={}

		for i=1,r do

			if entriesj][i~= nil and entriesj][i]['ctype'=='team' then

				matchgroupj][i=math.ceil(entriesj][i]['index'/teams_per_matchj])

				entriesj][i]['group' = math.ceil(entriesj][i]['index'/teams_per_matchj])

			end

		end

	end

end



local function teamLegs(j,i)

	local legs = rlegsj

	if notempty(entriesj][i]['legs']) then

		legs = tonumber(entriesj][i]['legs'])

	end

	if autolegs then

		local l=1

		repeat l=l+1

		until isempty(entriesj][i]['score'][l])

		legs = l-1

	end

	return legs

end



local function boldWinner()

	local function boldScore(j,i,l)

		if entriesj][i~= nil and entriesj][i]['ctype'=='team' then

			local myscore = entriesj][i]['score'][l]:gsub('%W','')

			if myscore == "" or myscore:find("%D") then return 'normal'

				else myscore=tonumber(myscore) end

			local compscore = {}

			for k,v in pairs(matchgroupj]) do

				if matchgroupj][i==v and k~=i then

					local theirscore = entriesj][k]['score'][l or ''

					theirscore = theirscore:gsub('%W','')

					if theirscore== "" or theirscore:find("%D") then return 'normal'

						else table.insert(compscore,tonumber(theirscore)) end

				end

			end

			for k,v in pairs(compscore) do

				if myscore<=v then return 'normal' end

			end

			if l~='agg' then

				entriesj][i]['wins' = entriesj][i]['wins'+1

			else

				entriesj][i]['aggwins' = 1

			end

			return 'bold'

		end

	end

	local function boldTeam(j,i,agg)

		local wins

		local legs = teamLegs(j,i)

		if agg~=true then

			wins = 'wins'

			if entriesj][i][wins>legs/2 then 

				return 'bold' 

			end

			if autolegs then

				for l=1,legs do

					if notempty(entriesj][i]['score'][l]) and string.find(entriesj][i]['score'][l],"nbsp") then 

						return 'normal' 

					end

				end

			else

				for l=1,legs do

					if isempty(entriesj][i]['score'][l]) or string.find(entriesj][i]['score'][l],"nbsp") then 

						return 'normal' 

					end

				end

			end

		else 

			wins = 'aggwins'

		end

		

		local compteam = {}

		for k,v in pairs(matchgroupj]) do

			if matchgroupj][i==v and k~=i then

				table.insert(compteam,tonumber(entriesj][k][wins]))

			end

		end

		for k,v in pairs(compteam) do

			if entriesj][i][wins<=v then 

				return 'normal' 

			end

		end

		return 'bold'

	end

	for j=minc,c do

		for i=1,r do

			if entriesj][i~= nil and entriesj][i]['ctype'=='team' then

				entriesj][i]['wins' = 0

				entriesj][i]['aggwins' = 0

			end

		end

		for i=1,r do

			if entriesj][i~= nil and entriesj][i]['ctype'=='team' then

				local legs = teamLegs(j,i)

				for l=1,legs do

					entriesj][i]['score']['weight'][l = boldScore(j,i,l)

				end

				if aggregate and legs>1 then

					entriesj][i]['score']['weight']['agg' = boldScore(j,i,'agg')

				end

			end

		end

		for i=1,r do

			if entriesj][i~= nil and entriesj][i]['ctype'=='team' then

				local agg

				local legs = teamLegs(j,i)

				if aggregate and legs>1 then agg=true end

				entriesj][i]['weight' = boldTeam(j,i,agg)

			end

		end

	end

end



local function isBlankEntry(col,row,ctype)

	if isempty(entriescol][row]) then return true end

	if isempty(entriescol][row]['team']) and isempty(entriescol][row]['text']) then return true end

	return false

end



local function showSeeds(j,i)

	local showseed=false

	if forceseeds or notempty(entriesj][i]['seed']) then

		showseed=true

	else

		for k=1,teams_per_matchj-1 do

			if notempty(entriesj][i+2*k]) and entriesj][i]['group'==entriesj][i+2*k]['group' and notempty(entriesj][i+2*k]['seed']) then

				showseed=true

			end

			if notempty(entriesj][i-2*k]) and entriesj][i]['group'==entriesj][i-2*k]['group' and notempty(entriesj][i-2*k]['seed']) then

				showseed=true

			end

		end

	end

	return showseed

end



local function cellBorder(b)

	return b1..'px '..b2..'px '..b3..'px '..b4..'px'

end



local function Cell(tbl,j,i,rowspan,colspan,text,align,border,border_width,bg,padding,weight,nwrap)

	local cell = tbl:tag('td')

	if colspan~=1 then

		cell:attr('colspan',colspan)

	end

	if rowspan~=1 then

		cell:attr('rowspan',rowspan)

	end

	if notempty(border) then

		cell:css('border',border)

	end

	if notempty(border_width) then

		cell:css('border-width',cellBorder(border_width))

	end

	if notempty(bg) then

		cell:css('background-color',bg)

	end

	if notempty(align) then

		cell:css('text-align',align)

	end

	cell:css('padding','0em 0.3em')

	if weight=='bold' then

		cell:css('font-weight',weight)

	end

	if notempty(text) then

		cell:wikitext(text)

	end

	return cell

end



local function teamCell(tbl,k,j,i,l,colspan)

	local bg = '#F2F2F2'

	local align

	local padding

	local weight

	local text

	local nwrap

	local b={0,0,1,1}

	if k=='seed' or k=='score' then

		align='center'

	end

	if k~='seed' then

		bg='#F9F9F9'

	end

	if k=='team' then 

		padding='0.3em'

		if teamLegs(j,i)==0 then

			b2=1

		end

	end

	if entriesj][i]['position'=='top' then

		b1=1

	end

	if l==teamLegs(j,i) or l=='agg' or k=='seed' then

		b2=1

	end

	if (l==nil and entriesj][i]['weight'=='bold') or entriesj][i]['score']['weight'][l=='bold' then

		weight='bold'

	end

	if l==nil then

		text=unboldParenthetical(entriesj][i][k])

	else

		text=tostring(entriesj][i][k][l])

	end

	return Cell(tbl,j,i,2,colspan,text,align,'solid #aaa',b,bg,padding,weight,nwrap)

end



local function insertEntry(tbl,j,i)

	local entry_colspan=maxlegsj+2

	if not seeds then entry_colspan=entry_colspan-1	end

	if (aggregate and maxlegsj>1) or maxlegsj==0 then

		entry_colspan=entry_colspan+1

	end

	

	if entriesj][i~=nil and entriesj][i]['ctype'=='blank' then

		return

	end

	

	if entriesj][i==nil then

		if entriesj][i-1~=nil or i==1 then

			local rowspan = 0

			local row = i

			repeat

				rowspan=rowspan+1

				row=row+1

			until entriesj][row~=nil or row>r

			return Cell(tbl,j,i,rowspan,entry_colspan)

		else

			return

		end

	end



	if entriesj][i]['ctype'=='header' then

		if byesj][entriesj][i]['headerindex']] then

			local emptyround = true

			local row = i+1

			repeat

				if not isBlankEntry(j,row) then

					emptyround = false

				end

				row = row+1

			until (entriesj][row~=nil and entriesj][row]['ctype'=='header') or row>r

			if emptyround == true then

				return Cell(tbl,j,i,2,entry_colspan)

			end

		end

		

		if hidej][entriesj][i]['headerindex']] then

			return Cell(tbl,j,i,2,entry_colspan)

		end

		

		if isempty(entriesj][i]['header']) then

			if entriesj][i]['headerindex'==1 then

				if     j==c   then entriesj][i]['header' = 'Final'

				elseif j==c-1 then entriesj][i]['header' = 'Semifinals'

				elseif j==c-2 then entriesj][i]['header' = 'Quarterfinals'

				else			   entriesj][i]['header' = 'Round '..j

				end

			else

				entriesj][i]['header' = 'Lower round '..j

			end

		end

		

		return Cell(tbl,j,i,2,entry_colspan,entriesj][i]['header'],'center','1px solid #aaa',nil,entriesj][i]['shade'])

	end

	

	if entriesj][i]['ctype'=='team' then

		if (byesj][entriesj][i]['headerindex']] and isBlankEntry(j,i)) or hidej][entriesj][i]['headerindex']] then

			return Cell(tbl,j,i,2,entry_colspan)

		end

		

		local legs = teamLegs(j,i)

		local team_colspan = maxlegsj-legs+1

		if aggregate and legs==1 and maxlegsj>1 then

			team_colspan=team_colspan+1

		end

		if maxlegsj==0 then 

			team_colspan=team_colspan+1

		end

		

		if seeds then

			if showSeeds(j,i)==true then

				teamCell(tbl,'seed',j,i)

			else

				team_colspan=team_colspan+1

			end

		end

		teamCell(tbl,'team',j,i,nil,team_colspan)

		for l=1,legs do

			teamCell(tbl,'score',j,i,l)

		end

		if aggregate and legs>1 then

			teamCell(tbl,'score',j,i,'agg')

		end

	end



	if entriesj][i]['ctype'=='text' then

		Cell(tbl,j,i,2,entry_colspan,entriesj][i]['text'],nil,nil,nil,nil,'0.3em')

	end

	

	if entriesj][i]['ctype'=='group' then

		local colspan=0

		for m=j,entriesj][i]['colspan'+j-1 do

			colspan=colspan+maxlegsm+2

			if not seeds then colspan=colspan-1 end

			if (aggregate and maxlegsm>1) or maxlegsm==0 then

				colspan=colspan+1

			end

		end

		colspan = colspan+2*(entriesj][i]['colspan'-1)

		return Cell(tbl,j,i,2,colspan,entriesj][i]['group'],'center')

	end

	

	if entriesj][i]['ctype'=='line' then

		local b={0,0,0,0}

		b3=2*pathCellj-1][i+1][3][1][3

		return Cell(tbl,j,i,2,entry_colspan,entriesj][i]['text'],nil,'solid black',b)

	end

	

	if entriesj][i]['ctype'=='line2' then

		local b={0,0,0,0}

		b1=2*pathCellj-1][i][3][1][1

		return Cell(tbl,j,i,2,entry_colspan,entriesj][i]['text'],nil,'solid black',b)

	end

end



local function isRoundHidden(j,i,headerindex)

	if notempty(entriesj][i]['pheader']) then

		hidej][entriesj][i]['headerindex']] = false

	end

	local row = i+1

	repeat

		if not isBlankEntry(j,row) then

			hidej][entriesj][i]['headerindex']] = false

		end

		row = row+1

	until (entriesj][row~=nil and entriesj][row]['ctype'=='header') or row>r

end



local function paramNames(cname,j,i,l)

	local rname = {

			{'RD'..j, bargs('RD'..j..'-altname') or 'RD'..j},

			{'RD'..j..toChar(entriesj][i]['headerindex']),bargs('RD'..j..toChar(entriesj][i]['headerindex'])..'-altname') or 'RD'..j..toChar(entriesj][i]['headerindex'])}

			}

	local name = {cname, bargs(cname..'-altname') or cname}

	local index = {entriesj][i]['index'], entriesj][i]['altindex']}

	local result = {}

	if cname=='header' then

		if entriesj][i]['headerindex'==1 then 

			for k=1,2 do

				table.insert(result,bargs(rname1][3-k]) or '')

				table.insert(result,bargs(rname2][3-k]) or '')

			end

		else 

			for k=1,2 do

				table.insert(result,bargs(rname2][3-k]) or '')

			end

		end

	elseif cname=='pheader' then

		if entriesj][i]['headerindex'==1 then 

			for k=1,2 do

				table.insert(result,pargsrname1][3-k]] or '')

				table.insert(result,pargsrname2][3-k]] or '')

			end

		else 

			for k=1,2 do

				table.insert(result,pargsrname2][3-k]] or '')

			end

		end

	elseif cname=='score' then

		for m=1,2 do for k=1,2 do

			if l==1 then

				table.insert(result,bargs(rname3-m][3-k..'-'..name1..index3-m]) or bargs(rname3-m][3-k..'-'..name1..'0'..index3-m]) or '')

			end

			table.insert(result,bargs(rname3-m][3-k..'-'..name1..index3-m..'-'..l) or bargs(rname3-m][3-k..'-'..name1..'0'..index3-m..'-'..l) or '')

		end	end

	elseif cname=='shade' then

		for k=1,2 do

			if entriesj][i]['headerindex'==1 then

				table.insert(result,bargs(rname1][3-k..'-'..name1]) or '')

			else

				table.insert(result,bargs(rname2][3-k..'-'..name1]) or '')

			end

		end

		table.insert(result,bargs('RD-shade'))

		table.insert(result,'#F2F2F2')

	elseif cname=='text' then

		for n=1,2 do for m=1,2 do for k=1,2 do

			table.insert(result,bargs(rname3-m][3-k..'-'..name3-n..index3-m]) or bargs(rname3-m][3-k..'-'..name3-n..'0'..index3-m]) or '')

		end end	end

	else

		for m=1,2 do for k=1,2 do

			table.insert(result,bargs(rname3-m][3-k..'-'..name1..index3-m]) or bargs(rname3-m][3-k..'-'..name1..'0'..index3-m]) or '')

		end	end

	end

	for k=1,#result do

		if notempty(resultk]) then

			return resultk

		end

	end

	return ''

end



local function indexedParams(j)

	for i=1,r do

		if entriesj][i~=nil then

			if entriesj][i]['ctype'=='team' then

				local legs = rlegsj

				if forceseeds then

					entriesj][i]['seed' = bargs(masterindex) or ''

					masterindex = masterindex+1

				end

				entriesj][i]['team' = bargs(tostring(masterindex)) or ''

				masterindex = masterindex+1

				entriesj][i]['legs' = paramNames('legs',j,i)

				entriesj][i]['score' = {}

				entriesj][i]['weight' = 'normal'

				entriesj][i]['score']['weight' = {}

				if notempty(entriesj][i]['legs']) then

					legs = tonumber(entriesj][i]['legs'])

				end

				for l=1,legs do

					entriesj][i]['score'][l = bargs(tostring(masterindex)) or ''

					masterindex = masterindex+1

					entriesj][i]['score']['weight'][l = 'normal'

				end

				if aggregate and legs>1 then

					entriesj][i]['score']['agg' = bargs(masterindex) or ''

					masterindex = masterindex+1

					entriesj][i]['score']['weight']['agg' = 'normal'

				end

			end

			if entriesj][i]['ctype'=='header' then

				entriesj][i]['header' = paramNames('header',j,i)

				entriesj][i]['pheader' = paramNames('pheader',j,i)

				entriesj][i]['shade' = paramNames('shade',j,i)

			end

			if entriesj][i]['ctype'=='text' then

				entriesj][i]['text' = bargs(tostring(masterindex)) or ''

				masterindex = masterindex+1

			end

			if entriesj][i]['ctype'=='group' then

				entriesj][i]['group' = bargs(tostring(masterindex)) or ''

				masterindex = masterindex+1

			end

			if entriesj][i]['ctype' == 'line' and entriesj][i]['hastext'==true then

				entriesj][i]['text' = bargs(masterindex) or ''

				masterindex = masterindex+1

			end

		end

	end

end



local function assignParams()

	masterindex = 1

	local maxcol = 1

	local byerows = 1

	local hiderows = 1

	for j=minc,c do

		rlegsj = tonumber(bargs('RD'..j..'-legs')) or tonumber(bargs('legs')) or 1

		if notempty(bargs('RD'..j..'-legs')) or bargs('legs') then autolegs = false end

		if paramstyle == 'numbered' then

			indexedParams(j)

		else

			for i=1,r do

				if entriesj][i~=nil then

					if entriesj][i]['ctype'=='team' then

						local legs = rlegsj

						entriesj][i]['seed' = paramNames('seed',j,i)

						entriesj][i]['team' = paramNames('team',j,i)

						entriesj][i]['legs' = paramNames('legs',j,i)

						entriesj][i]['score' = {}

						entriesj][i]['weight' = 'normal'

						entriesj][i]['score']['weight' = {}

						if notempty(entriesj][i]['legs']) then

							legs = tonumber(entriesj][i]['legs'])

						end

						if autolegs then

							local l=1

							repeat

								entriesj][i]['score'][l = paramNames('score',j,i,l)

								entriesj][i]['score']['weight'][l = 'normal'

								l=l+1

							until isempty(paramNames('score',j,i,l))

							legs = l-1

						else

							for l=1,legs do

								entriesj][i]['score'][l = paramNames('score',j,i,l)

								entriesj][i]['score']['weight'][l = 'normal'

							end

						end

						if aggregate and legs>1 then

							entriesj][i]['score']['agg' = paramNames('score',j,i,'agg')

							entriesj][i]['score']['weight']['agg' = 'normal'

						end

					end

					if entriesj][i]['ctype'=='header' then

						entriesj][i]['header' = paramNames('header',j,i)

						entriesj][i]['pheader' = paramNames('pheader',j,i)

						entriesj][i]['shade' = paramNames('shade',j,i)

					end

					if entriesj][i]['ctype'=='text' then

						entriesj][i]['text' = paramNames('text',j,i)

					end

					if entriesj][i]['ctype'=='group' then

						entriesj][i]['group' = paramNames('group',j,i)

					end

					if entriesj][i]['ctype' == 'line' and entriesj][i]['hastext'==true then

						entriesj][i]['text' = paramNames('text',j,i)

					end

				end

				if autocol and not isBlankEntry(j,i) then

					maxcol = math.max(maxcol,j)

				end

			end

		end

		for i=1,r do

			if entriesj][i~=nil and entriesj][i]['ctype'=='header' then 

				isRoundHidden(j,i) 

			end

			if entriesj][i~=nil and not hidej][entriesj][i]['headerindex']] then

				if not byesj][entriesj][i]['headerindex']] or (byesj][entriesj][i]['headerindex']] and not isBlankEntry(j,i)) then

					byerows = math.max(byerows,i)

				end

			end

		end

	end

	for j=minc,c do

		for k=1,headerindexj do

			if byesj][k or hidej][k then

				r=byerows+1

			end

		end

	end

	if autocol then

		c = maxcol

	end

end



local function getHide(j,headerindex)

	hidej = {}

	for k=1,headerindexj do

		if bargs('RD'..j..toChar(k)..'-hide')=='yes' or bargs('RD'..j..toChar(k)..'-hide')=='y' then

			hidej][k=true

		end

	end

end



local function getByes(j,headerindex)

	byesj = {}

	for k=1,headerindexj do

		if bargs('byes')=='yes' or bargs('byes')=='y' then

			byesj][k=true 

		elseif tonumber(bargs('byes')) then

			if j<=tonumber(bargs('byes')) then

				byesj][k=true

			end

		else 

			byesj][k=false

		end

		if bargs('RD'..j..'-byes')=='yes' or bargs('RD'..j..'-byes')=='y' then

			byesj][k=true

		elseif bargs('RD'..j..'-byes')=='no' or bargs('RD'..j..'-byes')=='n' then

			byesj][k=false

		end

		if bargs('RD'..j..toChar(k)..'-byes')=='yes' or bargs('RD'..j..toChar(k)..'-byes')=='y' then

			byesj][k=true

		elseif bargs('RD'..j..'-byes')=='no' or bargs('RD'..j..'-byes')=='n' then

			byesj][k=false

		end

	end

end



local function getAltIndices()

	local teamindex=1

	local textindex=1

	local groupindex=1

	for j=minc,c do

		headerindexj=0

		for i=1,r do

			if entriesj][i==nil and i==1 then

				headerindexj=headerindexj+1

			end

			if entriesj][i~=nil then

				if entriesj][i]['ctype' == 'header' then

					entriesj][i]['altindex' = headerindexj

					teamindex=1

					textindex=1

					headerindexj=headerindexj+1

				elseif entriesj][i]['ctype' == 'team' then

					entriesj][i]['altindex' = teamindex

					teamindex=teamindex+1

				elseif entriesj][i]['ctype' == 'text' then

					entriesj][i]['altindex' = textindex

					textindex=textindex+1

				elseif entriesj][i]['ctype' == 'group' then

					entriesj][i]['altindex' = groupindex

					groupindex=groupindex+1

				elseif entriesj][i]['ctype' == 'line' and entriesj][i]['hastext'==true then

					entriesj][i]['altindex' = textindex

					textindex=textindex+1

				end

				entriesj][i]['headerindex' = headerindexj

			end

		end

		getByes(j,headerindex)

		getHide(j,headerindex)

	end

end



local function noPaths(j,i)

	local result = true

	local cols = 2

	if hascrossj==true then

		cols = 3

	end

	for k=1,cols do

		for n=1,4 do

			if pathCellj][i][k][1][n~=0 then

				result = false

				return result

			end

		end

	end

	if hascrossj==true and (crossCellj][i]['left'][1==1 or crossCellj][i]['right'][1==1) then

		result = false

		return result

	end

	return result

end



local function generatePathCell(tbl,j,i,k,bg,rowspan)

	local color = pathCellj][i][k]['color'

	if not hascrossj and k==2 then 

		return 

	end

	local cell=tbl:tag('td')

	local a=pathCellj][i

	if rowspan~=1 then

		cell:attr('rowspan',rowspan)

	end

	if notempty(bg) and k==2 then

		cell:css('background',bg)

			:css('transform','translate(-1px)')

	end

	if ak][1][1~=0 or ak][1][2~=0 or ak][1][3~=0 or ak][1][4~=0 then

		cell:css('border','solid '..color)

			:css('border-width',2*ak][1][1..'px '..2*ak][1][2..'px '..2*ak][1][3..'px '..2*ak][1][4..'px')

	end

	return cell

end



local function insertPath(tbl,j,i)

	if skipPathj][i then

		return

	end



	local colspan = 2

	local rowspan = 1

	local angle = 58.2

	local pathcolor

	local bg = ''

	local cross = {'',''}

	

	if i<r then

		local function repeatedPath(a)

			if a>r-1 or skipPathj][a then

				return false

			end

			for k=1,3 do

				for n=1,4 do

					if pathCellj][i][k][1][n~=pathCellj][a][k][1][n then

						return false

					end

				end

			end

			return true

		end

		if repeatedPath(i) then

			local row=i

			repeat

				if row~=i and repeatedPath(row) then

					skipPathj][row=true

				end

				rowspan=rowspan+1

				row=row+1

			until row>r or not repeatedPath(row)

			rowspan=rowspan-1

		end

	end

	

	if i>1 and (crossCellj][i-1]['left'][1==1 or crossCellj][i-1]['right'][1==1) then

		return

	end

	if hascrossj then

		colspan = 3

		if crossCellj][i]['left'][1==1 or crossCellj][i]['right'][1==1 then

			rowspan = 2

			if crossCellj][i]['left'][1==1 then

				cross1 = 'linear-gradient(to top right, transparent calc(50% - 1px),'..crossCellj][i]['left'][2..' calc(50% - 1px),'..crossCellj][i]['left'][2..' calc(50% + 1px), transparent calc(50% + 1px))'

			end

			if crossCellj][i]['right'][1==1 then

				cross2 = 'linear-gradient(to bottom right, transparent calc(50% - 1px),'..crossCellj][i]['right'][2..' calc(50% - 1px),'..crossCellj][i]['right'][2..' calc(50% + 1px), transparent calc(50% + 1px))'

			end

		end

		if notempty(cross1]) and notempty(cross2]) then

			cross1 = cross1..','

		end

		bg = cross1..cross2

	end

	for k=1,3 do

		generatePathCell(tbl,j,i,k,bg,rowspan)

	end

end



local function parsePaths(j)

	local result={}

	local str = fargs'col'..j..'-col'..(j+1)..'-paths' or ''

		for val in str:gsub("%s+","")

					:gsub(",",", ")

					:gsub("%S+","\0%0\0")

					:gsub("%b()", function(s) return s:gsub("%z","") end)

					:gmatch("%z(.-)%z") do

			local array = split(val:gsub("%s+",""):gsub("%)",""):gsub("%(",""),{"-"})

			for k,_ in pairs(array) do

				arrayk = split(arrayk],{","})

			end

			if notempty(array2]) then

				for m=1,#array2 do

					array3 = {}

					array2][m = split(array2][m],{":"})

					array3][m = array2][m][2

					array2][m = array2][m][1

				end

				for n=1,#array1 do

					for m=1,#array2 do

						table.insert(result,{tonumber(array1][n]),tonumber(array2][m]),['color'=array3][m]})

					end

				end

			end

		end

	return result

end



local function isPathHidden(j,i,start,stop)

	local result=false

	if notempty(entriesj][start-1]) and (byesj][entriesj][start-1]['headerindex']] and isBlankEntry(j,start-1) and isBlankEntry(j,start+1) or hidej][entriesj][start-1]['headerindex']]) then

		if bargs('show-bye-paths')~='y' and bargs('show-bye-paths')~='yes' then

			result=true

		end

	end

	if notempty(entriesj+1][stop-1]) and (byesj+1][entriesj+1][stop-1]['headerindex']] and isBlankEntry(j+1,stop-1) and isBlankEntry(j+1,stop+1) or hidej+1][entriesj+1][stop-1]['headerindex']])then

		if bargs('show-bye-paths')~='y' and bargs('show-bye-paths')~='yes' then

			result=true

		end

	end

	if bargs('RD'..j..'-RD'..(j+1)..'-path')=='n' or bargs('RD'..j..'-RD'..(j+1)..'-path')=='no' or bargs('RD'..j..'-RD'..(j+1)..'-path')=='0' then

		if notempty(entriesj][start-1]) and entriesj][start-1]['headerindex'==1 then

			result=true

		end

	end

	return result

end



local function getPaths()

	local paths = {}

	for j=minc,c-1 do

		hascrossj = false

		if notempty(fargs'col'..j..'-col'..(j+1)..'-cross']) then

			hascrossj = true

		end

	end

	for j=minc,c-1 do

		local straightpaths = {}

		local outpaths = {}

		local inpaths = {}

		pathsj=parsePaths(j)

		pathCellj = {}

		crossCellj = {}

		skipPathj = {}

		for i=1,r do

			pathCellj][i = {}

			crossCellj][i = {['left'={0,'black'},['right'={0,'black'}}

			for k=1,3 do

				pathCellj][i][k = {{0,0,0,0},['color'='black'}

			end

			skipPathj][i = false

			end

		local crossloc = split((fargs'col'..j..'-col'..(j+1)..'-cross' or ''):gsub("%s+", ""),{","},true)

		if shiftj~=0 and notempty(crossloc1]) then

			for n=1,#crossloc do

				crosslocn = crosslocn+shiftj

			end

		end

		for k,v in ipairs(pathsj]) do

			local start = 2*(pathsj][k][1+shiftj])+(teams_per_matchj-2)

			local stop = 2*(pathsj][k][2+shiftj+1])+(teams_per_matchj+1-2)

			local mid = {}

			local cross = 0

			

			if notempty(crossloc1]) then

				for n=1,#crossloc do

					midn = 2*crosslocn+(teams_per_matchj-2)

				end

			else

				mid1=0

			end

			for n=1,#mid do

				if (start<stop and midn<stop and midn>start) or (start>stop and midn>stop and midn<start) then

					cross = midn

				end

			end

			pathsj][k]['color' = pathsj][k]['color' or 'black'

			table.insert(outpaths,{start,pathsj][k]['color']})

			table.insert(inpaths,{stop,pathsj][k]['color']})

			if not isPathHidden(j,i,start,stop) then

				if start==stop then

					table.insert(straightpaths,{start,pathsj][k]['color']})

				elseif start<stop then

					if stop>r then break end

					pathCellj][start+1][1][1][1 = 1

					pathCellj][start+1][1]['color' = pathsj][k]['color'

					if cross==0 then

						if hascrossj then

							pathCellj][start+1][2][1][1 = 1

							pathCellj][start+1][2]['color' = pathsj][k]['color'

							for i=start+1,stop do

								pathCellj][i][2][1][2 = 1

								pathCellj][i][2]['color' = pathsj][k]['color'

							end

						else

							for i=start+1,stop do

								pathCellj][i][1][1][2 = 1

								pathCellj][i][1]['color' = pathsj][k]['color'

							end

						end

					else

						crossCellj][cross]['left' = {1,pathsj][k]['color']}

						for i=start+1,cross-1 do 

							pathCellj][i][1][1][2 = 1

							pathCellj][i][1]['color' = pathsj][k]['color'

							end

						for i=cross+2,stop do 

							pathCellj][i][2][1][2 = 1 

							pathCellj][i][2]['color' = pathsj][k]['color'

							end	

					end

					pathCellj][stop][3][1][3 = 1

					pathCellj][stop][3]['color' = pathsj][k]['color'

				elseif start>stop then

					if start>r then break end

					pathCellj][stop+1][3][1][1 = 1

					pathCellj][stop+1][3]['color' = pathsj][k]['color'

					if cross==0 then

						if hascrossj then

							for i=stop+1,start do

								pathCellj][i][2][1][2 = 1

								pathCellj][i][2]['color' = pathsj][k]['color'

							end

							pathCellj][start][2][1][3 = 1

							pathCellj][start][2]['color' = pathsj][k]['color'

						else

							for i=stop+1,start do

								pathCellj][i][1][1][2 = 1

								pathCellj][i][1]['color' = pathsj][k]['color'

							end

						end

					else

						crossCellj][cross]['right' = {1,pathsj][k]['color']}

						for i=stop+1,cross-1 do 

							pathCellj][i][2][1][2 = 1 

							pathCellj][i][2]['color' = pathsj][k]['color'

							end

						for i=cross+2,start do 

							pathCellj][i][1][1][2 = 1 

							pathCellj][i][1]['color' = pathsj][k]['color'

							end	

					end

					pathCellj][start][1][1][3 = 1

					pathCellj][start][1]['color' = pathsj][k]['color'

				end

			end

		end

		-- Thicken start==stop paths

		for n=1,#straightpaths do

			local i = straightpathsn][1

			local color = straightpathsn][2

			if i>r then break end

			if pathCellj][i][1][1][3==0 then

				pathCellj][i][1][1][3 = 1

				pathCellj][i][2][1][3 = 1

				pathCellj][i][3][1][3 = 1

				pathCellj][i][1]['color' = color

				pathCellj][i][2]['color' = color

				pathCellj][i][3]['color' = color

				if pathCellj][i+1][1][1][1==0 then

					pathCellj][i+1][1][1][1 = 0.5

					pathCellj][i+1][2][1][1 = 0.5

					pathCellj][i+1][3][1][1 = 0.5

					pathCellj][i+1][1]['color' = color

					pathCellj][i+1][2]['color' = color

					pathCellj][i+1][3]['color' = color

				end

			elseif pathCellj][i+1][1][1][1==0 then

				pathCellj][i+1][1][1][1 = 1

				pathCellj][i+1][1]['color' = color

				if hascrossj then

					pathCellj][i+1][2][1][1 = 1

					pathCellj][i+1][2]['color' = color

				end

				pathCellj][i+1][3][1][1 = 1

				pathCellj][i+1][3]['color' = color

			end

		end

		-- Thicken/Thin out paths

		for n=1,#outpaths do

			local i = outpathsn][1

			local color = outpathsn][2

			if i<r and pathCellj][i][1][1][3==1 and pathCellj][i+1][1][1][1==0 then

				pathCellj][i+1][1][1][1 = 0.5*pathCellj][i][1][1][3

				pathCellj][i+1][2][1][1 = 0.5*pathCellj][i][2][1][3

				pathCellj][i+1][1]['color' = pathCellj][i][1]['color'

				pathCellj][i+1][2]['color' = pathCellj][i][2]['color'

			elseif i<r and pathCellj][i][1][1][3==0 and pathCellj][i+1][1][1][1==1 then

				pathCellj][i][1][1][3 = pathCellj][i+1][1][1][1

				pathCellj][i][2][1][3 = pathCellj][i+1][2][1][1

				pathCellj][i+1][1][1][1 = 0.5*pathCellj][i][1][1][3

				pathCellj][i+1][2][1][1 = 0.5*pathCellj][i][2][1][3

				pathCellj][i][1]['color' = pathCellj][i+1][1]['color'

				pathCellj][i][2]['color' = pathCellj][i+1][2]['color'

			end

		end

		-- Thin double-in paths

		for n=1,#inpaths do

			local i = inpathsn][1

			local color = inpathsn][2

			if i<r and pathCellj][i][3][1][3==1 and pathCellj][i+1][3][1][1==1 and pathCellj][i][3]['color'==pathCellj][i+1][3]['color' then

				pathCellj][i+1][3][1][1 = 0.5*pathCellj][i][3][1][3

			end

		end

	end

	for j=minc,c-1 do

		for i=1,r-1 do

			local straightpath=false

			if (entriesj+1][i-1==nil or (byesj+1][entriesj+1][i-1]['headerindex']]) and isBlankEntry(j+1,i-1)) then

				if (pathCellj][i][3][1][3~=0 and pathCellj+1][i][1][1][3~=0) or (pathCellj][i+1][3][1][1~=0 and pathCellj+1][i+1][1][1][1~=0) then

					if pathCellj+1][i][1][1][3==pathCellj+1][i][3][1][3 and pathCellj+1][i+1][1][1][1==pathCellj+1][i+1][3][1][1 then

						straightpath=true

					end

					pathCellj+1][i][1][1][3=pathCellj][i][3][1][3

					pathCellj+1][i+1][1][1][1=pathCellj][i+1][3][1][1

					pathCellj+1][i][2][1][3=pathCellj][i][3][1][3

					pathCellj+1][i+1][2][1][1=pathCellj][i+1][3][1][1

					entriesj+1][i-1={['ctype'='line'}

					entriesj+1][i={['ctype'='blank'}

					if notempty(entriesj+1][i+1]) then

						entriesj+1][i+1]['ctype' = 'line2'

					else

						entriesj+1][i+1={['ctype'='line2'}

					end

					entriesj+1][i+2={['ctype'='blank'}

					if straightpath then

						pathCellj+1][i][3][1][3=pathCellj+1][i][1][1][3

						pathCellj+1][i+1][3][1][1=pathCellj+1][i+1][1][1][1

					end

				end

			end

		end

	end

end



local function getGroups()

	local function check(j,i)

		local result=false

		if entriesj][i == nil then

			if entriesj][i+1 == nil then 

				result=true 

			elseif entriesj][i+1]['ctype'=='text' and isBlankEntry(j,i+1) then

				result=true

			end

		elseif entriesj][i]['ctype'=='text' and isBlankEntry(j,i) then

			result=true

		end

		return result

	end

	for j=minc,c-1 do

		if teams_per_matchj==2 then

			local n=0

			for i=1,r-1 do

				if pathCellj][i][3][1][3==1 or pathCellj][i+1][3][1][1==1 then

					n=n+1

					if check(j,i) then

						local k=minc-1

						repeat

							if entriesj-k][i+1~=nil and entriesj-k][i+1]['ctype'=='text' and isBlankEntry(j-k,i+1) then

								entriesj-k][i+2=nil

							end

							entriesj-k][i={['ctype'='blank'}

							entriesj-k][i+1={['ctype'='blank'}

							if k>0 and noPaths(j-k,i) then

								skipPathj-k][i = true

								skipPathj-k][i+1 = true

							end

							k=k+1

						until k>j-1 or not check(j-k,i) or not noPaths(j-k,i)

						k=k-1

						entriesj-k][i={['ctype'='group',['index'=n,['colspan'=k+1}

						entriesj-k][i+1={['ctype'='blank'}

						entriesj-k][i]['group' = bargs('RD'..j..'-group'..n)

					end

				end

			end

		end

	end

end



local function getCells()

	local maxrow = 1

	local colentry = {}

	local bool = true

	for j=minc,c do

		if notempty(fargs'col'..j..'-headers']) then bool=false end

		teams_per_matchj = tonumber(fargs'RD'..j..'-teams-per-match']) or tonumber(fargs'col'..j..'-teams-per-match']) or tonumber(fargs'teams-per-match']) or 2

		maxtpm = math.max(maxtpm,teams_per_matchj])

	end

	for j=minc,c do

		entriesj = {}

		shiftj = tonumber(bargs('RD'..j..'-shift')) or tonumber(bargs('shift')) or 0

		colentryj = {

			split((fargs'col'..j..'-headers' or ''):gsub("%s+", ""),{","},true),

			split((fargs'col'..j..'-matches' or ''):gsub("%s+", ""),{","},true),

			split((fargs'col'..j..'-lines' or ''):gsub("%s+", ""),{","},true),

			split((fargs'col'..j..'-text' or ''):gsub("%s+", ""),{","},true),

		}

		if bool==true and fargs'noheaders'~='y' and fargs'noheaders'~='yes' then

			table.insert(colentryj][1],1)

		end

	end



	for j=minc,c do

		local textindex=0

		for k,v in ipairs(colentryj]) do

			table.sort(colentryj][k])

			local ctype

			if k==1 then ctype='header'

			elseif k==2 then ctype='team'

			elseif k==3 then ctype='line'

			elseif k==4 then ctype='text'

			elseif k==5 then ctype='group'

			end

			for n=1,#colentryj][k do

				if shiftj~=0 and colentryj][k][n>1 then

					colentryj][k][n = colentryj][k][n+shiftj

				end

				local i=2*colentryj][k][n-1

				maxrow = math.max(i+2*teams_per_matchj-1,maxrow)

				if ctype=='team' then

					if entriesj][i-1==nil and entriesj][i-2==nil then

						entriesj][i-2={['ctype'='text',['index'=n}

						entriesj][i-1={['ctype'='blank'}

						textindex=n

					end

					entriesj][i={['ctype'=ctype,['index'=teams_per_matchj*n-(teams_per_matchj-1),['position'='top'}

					entriesj][i+1={['ctype'='blank'}

					for m=2,teams_per_matchj do

						entriesj][i+2*(m-1)]={['ctype'=ctype,['index'=teams_per_matchj*n-(teams_per_matchj-m)}

						entriesj][i+2*(m-1)+1={['ctype'='blank'}

					end

				elseif ctype=='text' then

					entriesj][i={['ctype'=ctype,['index'=textindex+n}

					entriesj][i+1={['ctype'='blank'}

				elseif ctype=='line' then

					entriesj][i={['ctype'=ctype}

					entriesj][i+1={['ctype'='blank'}

					entriesj][i+2={['ctype'='line2'}

					entriesj][i+3={['ctype'='blank'}

				elseif ctype=='group' then

					entriesj][i={['ctype'=ctype,['index'=n}

					entriesj][i+1={['ctype'='blank'}

				else

					entriesj][i={['ctype'=ctype,['index'=n,['position'='top'}

					entriesj][i+1={['ctype'='blank'}

				end

			end

		end

	end

	if isempty(r) then

		r = maxrow

	end

end



function p.main(frame)

	fargs = frame.args

	pargs = frame:getParent().args;

	

	

	r = tonumber(fargs.rows) or ''

	c = tonumber(fargs.rounds) or 1

	maxc = tonumber(pargs.maxrounds) or tonumber(pargs.maxround) or ''

	minc = tonumber(pargs.minround) or 1

	headerindex = {}

	if notempty(maxc) then c=maxc end

	if fargs.autocol=='yes' or fargs.autocol=='y' then autocol=true end

	local colspacing = tonumber(fargs'col-spacing']) or 5

	local height = bargs('height') or 0 

	

	maxtpm = 1

	seeds = true

	nowrap = true

	forceseeds = false

	boldwinner = bargs('boldwinner') or ''

	if bargs('seeds')=='y' or bargs('seeds')=='yes' then forceseeds=true end

	if bargs('seeds')=='n' or bargs('seeds')=='no' then seeds=false end

	if bargs('aggregate')=='y' or bargs('aggregate')=='yes' then aggregate=true end

	if bargs('autolegs')=='y' or bargs('autolegs')=='yes' then autolegs=true end

	if bargs('paramstyle')=='numbered' then 

		paramstyle = 'numbered'

	else

		paramstyle = 'indexed'

	end

	if pargs.nowrap=='n' or pargs.nowrap=='no' then nowrap=false end

	

	getCells()

	getAltIndices()

	assignParams()

	matchGroups()

	if (boldwinner=='yes' or boldwinner=='y' or boldwinner=='high') then boldWinner() end

	getPaths()

	if minc==1 then

	getGroups()

	end

	

	for j=minc,c do

		maxlegsj = rlegsj

		for i=1,r do

			if notempty(entriesj][i]) then

				if notempty(entriesj][i]['legs']) then

					maxlegsj = math.max(rlegsj],entriesj][i]['legs'])

				end

				if autolegs then

					local l=1

					repeat l=l+1

					until isempty(entriesj][i]['score']) or isempty(entriesj][i]['score'][l])

					maxlegsj = math.max(maxlegsj],l-1)

				end

			end

		end

	end

	

	local div = mw.html.create('div')

    		:css('overflow','auto')

    		

	if height~=0 then

		div:css('height',height)

	end

	

	local tbl = mw.html.create('table')

			:attr('cellpadding','0')

			:attr('cellspacing','0')

			:css('font-size','90%')

			:css('border-collapse','separate')

			:css('margin','1em 2em 0em 1em')

			

	if nowrap then 

		tbl:css('white-space','nowrap') 

	end

	

	tbl:tag('tr'):css('visibility','collapse')

	tbl:tag('td'):css('width','1px')

	for j=minc,c do

		if seeds then

			tbl:tag('td'):css('width',getWidth('seed','25px'))

		end

		tbl:tag('td'):css('width',getWidth('team','150px'))

		if maxlegsj==0 then

			tbl:tag('td'):css('width',getWidth('score','25px'))

			else

			for l=1,maxlegsj do

				tbl:tag('td'):css('width',getWidth('score','25px'))

			end

		end

		if aggregate and maxlegsj>1 then

			tbl:tag('td'):css('width',getWidth('agg',getWidth('score','25px')))

		end

		if j~=c then

			if hascrossj then

				tbl:tag('td'):css('width',colspacing+1-4 ..'px')

							:css('padding-left','4px')

				tbl:tag('td'):css('padding-left','5px')

							:css('width','5px')

				tbl:tag('td'):css('width',colspacing-1-2 ..'px')

							:css('padding-right','2px')

			else

				tbl:tag('td'):css('width',colspacing+1-4 ..'px')

							:css('padding-left','4px')

				tbl:tag('td'):css('width',colspacing-1-2 ..'px')

							:css('padding-right','2px')

			end

		end

	end

	

	for i=1,r do

		local row = tbl:tag('tr')

		row:tag('td'):css('height','11px')

		for j=minc,c do

			insertEntry(row,j,i)

			if j~=c then

				insertPath(row,j,i)

			end

		end

	end

	

	div:wikitext(tostring(tbl))

			

	return tostring(div)

end



return p
From Wikipedia, the free encyclopedia

local p = {}

local entries = {}

local pathCell = {}

local crossCell = {}

local skipPath = {}

local shift = {}

local hascross = {}

local teams_per_match = {}

local rlegs = {}

local maxlegs = {}

local autolegs

local byes = {}

local hide = {}

local matchgroup = {}

local nowrap

local autocol

local seeds

local forceseeds

local boldwinner

local aggregate

local paramstyle

local masterindex



local function isempty(s)

	return s==nil or s==''

end



local function notempty(s)

	return s~=nil and s~=''

end



local function bargs(s)

	return pargss or fargss

end



local function toChar(num)

	return string.char(string.byte("a")+num-1)

end



local function unboldParenthetical(text)

    -- Replace wikilinks with unique placeholders

    local counter = 0

    local placeholders = {}

    text = text:gsub('%[%[(.-)%]%]', function(link)

        counter = counter + 1

        local placeholder = '__WIKILINK__' .. counter .. '__'

        placeholdersplaceholder = link

        return placeholder

    end)



    -- Apply <span style="font-weight:normal"></span> to parenthetical and bracketed text

    text = text:gsub('(%b())', '<span style="font-weight:normal">%1</span>')

               :gsub('(%b[])', '<span style="font-weight:normal">%1</span>')



    -- Restore the original wikilinks

    for placeholder, link in pairs(placeholders) do

        text = text:gsub(placeholder, '[[' .. link .. ']]')

    end



    return text

end



local function split(str,delim,tonum)

	result = {};

	local a = "[^"..table.concat(delim).."]+"

		for w in str:gmatch(a) do

			if tonum==true then

				table.insert(result, tonumber(w));

			else

				table.insert(result, w);

			end

		end

	return result;

end



local function getWidth(ctype, default)

	local result = bargs(ctype..'-width')

	if isempty(result) then return default end

	if tonumber(result)~=nil then return result..'px' end

	return result

end



local function matchGroups()

	for j=minc,c do

		matchgroupj={}

		for i=1,r do

			if entriesj][i~= nil and entriesj][i]['ctype'=='team' then

				matchgroupj][i=math.ceil(entriesj][i]['index'/teams_per_matchj])

				entriesj][i]['group' = math.ceil(entriesj][i]['index'/teams_per_matchj])

			end

		end

	end

end



local function teamLegs(j,i)

	local legs = rlegsj

	if notempty(entriesj][i]['legs']) then

		legs = tonumber(entriesj][i]['legs'])

	end

	if autolegs then

		local l=1

		repeat l=l+1

		until isempty(entriesj][i]['score'][l])

		legs = l-1

	end

	return legs

end



local function boldWinner()

	local function boldScore(j,i,l)

		if entriesj][i~= nil and entriesj][i]['ctype'=='team' then

			local myscore = entriesj][i]['score'][l]:gsub('%W','')

			if myscore == "" or myscore:find("%D") then return 'normal'

				else myscore=tonumber(myscore) end

			local compscore = {}

			for k,v in pairs(matchgroupj]) do

				if matchgroupj][i==v and k~=i then

					local theirscore = entriesj][k]['score'][l or ''

					theirscore = theirscore:gsub('%W','')

					if theirscore== "" or theirscore:find("%D") then return 'normal'

						else table.insert(compscore,tonumber(theirscore)) end

				end

			end

			for k,v in pairs(compscore) do

				if myscore<=v then return 'normal' end

			end

			if l~='agg' then

				entriesj][i]['wins' = entriesj][i]['wins'+1

			else

				entriesj][i]['aggwins' = 1

			end

			return 'bold'

		end

	end

	local function boldTeam(j,i,agg)

		local wins

		local legs = teamLegs(j,i)

		if agg~=true then

			wins = 'wins'

			if entriesj][i][wins>legs/2 then 

				return 'bold' 

			end

			if autolegs then

				for l=1,legs do

					if notempty(entriesj][i]['score'][l]) and string.find(entriesj][i]['score'][l],"nbsp") then 

						return 'normal' 

					end

				end

			else

				for l=1,legs do

					if isempty(entriesj][i]['score'][l]) or string.find(entriesj][i]['score'][l],"nbsp") then 

						return 'normal' 

					end

				end

			end

		else 

			wins = 'aggwins'

		end

		

		local compteam = {}

		for k,v in pairs(matchgroupj]) do

			if matchgroupj][i==v and k~=i then

				table.insert(compteam,tonumber(entriesj][k][wins]))

			end

		end

		for k,v in pairs(compteam) do

			if entriesj][i][wins<=v then 

				return 'normal' 

			end

		end

		return 'bold'

	end

	for j=minc,c do

		for i=1,r do

			if entriesj][i~= nil and entriesj][i]['ctype'=='team' then

				entriesj][i]['wins' = 0

				entriesj][i]['aggwins' = 0

			end

		end

		for i=1,r do

			if entriesj][i~= nil and entriesj][i]['ctype'=='team' then

				local legs = teamLegs(j,i)

				for l=1,legs do

					entriesj][i]['score']['weight'][l = boldScore(j,i,l)

				end

				if aggregate and legs>1 then

					entriesj][i]['score']['weight']['agg' = boldScore(j,i,'agg')

				end

			end

		end

		for i=1,r do

			if entriesj][i~= nil and entriesj][i]['ctype'=='team' then

				local agg

				local legs = teamLegs(j,i)

				if aggregate and legs>1 then agg=true end

				entriesj][i]['weight' = boldTeam(j,i,agg)

			end

		end

	end

end



local function isBlankEntry(col,row,ctype)

	if isempty(entriescol][row]) then return true end

	if isempty(entriescol][row]['team']) and isempty(entriescol][row]['text']) then return true end

	return false

end



local function showSeeds(j,i)

	local showseed=false

	if forceseeds or notempty(entriesj][i]['seed']) then

		showseed=true

	else

		for k=1,teams_per_matchj-1 do

			if notempty(entriesj][i+2*k]) and entriesj][i]['group'==entriesj][i+2*k]['group' and notempty(entriesj][i+2*k]['seed']) then

				showseed=true

			end

			if notempty(entriesj][i-2*k]) and entriesj][i]['group'==entriesj][i-2*k]['group' and notempty(entriesj][i-2*k]['seed']) then

				showseed=true

			end

		end

	end

	return showseed

end



local function cellBorder(b)

	return b1..'px '..b2..'px '..b3..'px '..b4..'px'

end



local function Cell(tbl,j,i,rowspan,colspan,text,align,border,border_width,bg,padding,weight,nwrap)

	local cell = tbl:tag('td')

	if colspan~=1 then

		cell:attr('colspan',colspan)

	end

	if rowspan~=1 then

		cell:attr('rowspan',rowspan)

	end

	if notempty(border) then

		cell:css('border',border)

	end

	if notempty(border_width) then

		cell:css('border-width',cellBorder(border_width))

	end

	if notempty(bg) then

		cell:css('background-color',bg)

	end

	if notempty(align) then

		cell:css('text-align',align)

	end

	cell:css('padding','0em 0.3em')

	if weight=='bold' then

		cell:css('font-weight',weight)

	end

	if notempty(text) then

		cell:wikitext(text)

	end

	return cell

end



local function teamCell(tbl,k,j,i,l,colspan)

	local bg = '#F2F2F2'

	local align

	local padding

	local weight

	local text

	local nwrap

	local b={0,0,1,1}

	if k=='seed' or k=='score' then

		align='center'

	end

	if k~='seed' then

		bg='#F9F9F9'

	end

	if k=='team' then 

		padding='0.3em'

		if teamLegs(j,i)==0 then

			b2=1

		end

	end

	if entriesj][i]['position'=='top' then

		b1=1

	end

	if l==teamLegs(j,i) or l=='agg' or k=='seed' then

		b2=1

	end

	if (l==nil and entriesj][i]['weight'=='bold') or entriesj][i]['score']['weight'][l=='bold' then

		weight='bold'

	end

	if l==nil then

		text=unboldParenthetical(entriesj][i][k])

	else

		text=tostring(entriesj][i][k][l])

	end

	return Cell(tbl,j,i,2,colspan,text,align,'solid #aaa',b,bg,padding,weight,nwrap)

end



local function insertEntry(tbl,j,i)

	local entry_colspan=maxlegsj+2

	if not seeds then entry_colspan=entry_colspan-1	end

	if (aggregate and maxlegsj>1) or maxlegsj==0 then

		entry_colspan=entry_colspan+1

	end

	

	if entriesj][i~=nil and entriesj][i]['ctype'=='blank' then

		return

	end

	

	if entriesj][i==nil then

		if entriesj][i-1~=nil or i==1 then

			local rowspan = 0

			local row = i

			repeat

				rowspan=rowspan+1

				row=row+1

			until entriesj][row~=nil or row>r

			return Cell(tbl,j,i,rowspan,entry_colspan)

		else

			return

		end

	end



	if entriesj][i]['ctype'=='header' then

		if byesj][entriesj][i]['headerindex']] then

			local emptyround = true

			local row = i+1

			repeat

				if not isBlankEntry(j,row) then

					emptyround = false

				end

				row = row+1

			until (entriesj][row~=nil and entriesj][row]['ctype'=='header') or row>r

			if emptyround == true then

				return Cell(tbl,j,i,2,entry_colspan)

			end

		end

		

		if hidej][entriesj][i]['headerindex']] then

			return Cell(tbl,j,i,2,entry_colspan)

		end

		

		if isempty(entriesj][i]['header']) then

			if entriesj][i]['headerindex'==1 then

				if     j==c   then entriesj][i]['header' = 'Final'

				elseif j==c-1 then entriesj][i]['header' = 'Semifinals'

				elseif j==c-2 then entriesj][i]['header' = 'Quarterfinals'

				else			   entriesj][i]['header' = 'Round '..j

				end

			else

				entriesj][i]['header' = 'Lower round '..j

			end

		end

		

		return Cell(tbl,j,i,2,entry_colspan,entriesj][i]['header'],'center','1px solid #aaa',nil,entriesj][i]['shade'])

	end

	

	if entriesj][i]['ctype'=='team' then

		if (byesj][entriesj][i]['headerindex']] and isBlankEntry(j,i)) or hidej][entriesj][i]['headerindex']] then

			return Cell(tbl,j,i,2,entry_colspan)

		end

		

		local legs = teamLegs(j,i)

		local team_colspan = maxlegsj-legs+1

		if aggregate and legs==1 and maxlegsj>1 then

			team_colspan=team_colspan+1

		end

		if maxlegsj==0 then 

			team_colspan=team_colspan+1

		end

		

		if seeds then

			if showSeeds(j,i)==true then

				teamCell(tbl,'seed',j,i)

			else

				team_colspan=team_colspan+1

			end

		end

		teamCell(tbl,'team',j,i,nil,team_colspan)

		for l=1,legs do

			teamCell(tbl,'score',j,i,l)

		end

		if aggregate and legs>1 then

			teamCell(tbl,'score',j,i,'agg')

		end

	end



	if entriesj][i]['ctype'=='text' then

		Cell(tbl,j,i,2,entry_colspan,entriesj][i]['text'],nil,nil,nil,nil,'0.3em')

	end

	

	if entriesj][i]['ctype'=='group' then

		local colspan=0

		for m=j,entriesj][i]['colspan'+j-1 do

			colspan=colspan+maxlegsm+2

			if not seeds then colspan=colspan-1 end

			if (aggregate and maxlegsm>1) or maxlegsm==0 then

				colspan=colspan+1

			end

		end

		colspan = colspan+2*(entriesj][i]['colspan'-1)

		return Cell(tbl,j,i,2,colspan,entriesj][i]['group'],'center')

	end

	

	if entriesj][i]['ctype'=='line' then

		local b={0,0,0,0}

		b3=2*pathCellj-1][i+1][3][1][3

		return Cell(tbl,j,i,2,entry_colspan,entriesj][i]['text'],nil,'solid black',b)

	end

	

	if entriesj][i]['ctype'=='line2' then

		local b={0,0,0,0}

		b1=2*pathCellj-1][i][3][1][1

		return Cell(tbl,j,i,2,entry_colspan,entriesj][i]['text'],nil,'solid black',b)

	end

end



local function isRoundHidden(j,i,headerindex)

	if notempty(entriesj][i]['pheader']) then

		hidej][entriesj][i]['headerindex']] = false

	end

	local row = i+1

	repeat

		if not isBlankEntry(j,row) then

			hidej][entriesj][i]['headerindex']] = false

		end

		row = row+1

	until (entriesj][row~=nil and entriesj][row]['ctype'=='header') or row>r

end



local function paramNames(cname,j,i,l)

	local rname = {

			{'RD'..j, bargs('RD'..j..'-altname') or 'RD'..j},

			{'RD'..j..toChar(entriesj][i]['headerindex']),bargs('RD'..j..toChar(entriesj][i]['headerindex'])..'-altname') or 'RD'..j..toChar(entriesj][i]['headerindex'])}

			}

	local name = {cname, bargs(cname..'-altname') or cname}

	local index = {entriesj][i]['index'], entriesj][i]['altindex']}

	local result = {}

	if cname=='header' then

		if entriesj][i]['headerindex'==1 then 

			for k=1,2 do

				table.insert(result,bargs(rname1][3-k]) or '')

				table.insert(result,bargs(rname2][3-k]) or '')

			end

		else 

			for k=1,2 do

				table.insert(result,bargs(rname2][3-k]) or '')

			end

		end

	elseif cname=='pheader' then

		if entriesj][i]['headerindex'==1 then 

			for k=1,2 do

				table.insert(result,pargsrname1][3-k]] or '')

				table.insert(result,pargsrname2][3-k]] or '')

			end

		else 

			for k=1,2 do

				table.insert(result,pargsrname2][3-k]] or '')

			end

		end

	elseif cname=='score' then

		for m=1,2 do for k=1,2 do

			if l==1 then

				table.insert(result,bargs(rname3-m][3-k..'-'..name1..index3-m]) or bargs(rname3-m][3-k..'-'..name1..'0'..index3-m]) or '')

			end

			table.insert(result,bargs(rname3-m][3-k..'-'..name1..index3-m..'-'..l) or bargs(rname3-m][3-k..'-'..name1..'0'..index3-m..'-'..l) or '')

		end	end

	elseif cname=='shade' then

		for k=1,2 do

			if entriesj][i]['headerindex'==1 then

				table.insert(result,bargs(rname1][3-k..'-'..name1]) or '')

			else

				table.insert(result,bargs(rname2][3-k..'-'..name1]) or '')

			end

		end

		table.insert(result,bargs('RD-shade'))

		table.insert(result,'#F2F2F2')

	elseif cname=='text' then

		for n=1,2 do for m=1,2 do for k=1,2 do

			table.insert(result,bargs(rname3-m][3-k..'-'..name3-n..index3-m]) or bargs(rname3-m][3-k..'-'..name3-n..'0'..index3-m]) or '')

		end end	end

	else

		for m=1,2 do for k=1,2 do

			table.insert(result,bargs(rname3-m][3-k..'-'..name1..index3-m]) or bargs(rname3-m][3-k..'-'..name1..'0'..index3-m]) or '')

		end	end

	end

	for k=1,#result do

		if notempty(resultk]) then

			return resultk

		end

	end

	return ''

end



local function indexedParams(j)

	for i=1,r do

		if entriesj][i~=nil then

			if entriesj][i]['ctype'=='team' then

				local legs = rlegsj

				if forceseeds then

					entriesj][i]['seed' = bargs(masterindex) or ''

					masterindex = masterindex+1

				end

				entriesj][i]['team' = bargs(tostring(masterindex)) or ''

				masterindex = masterindex+1

				entriesj][i]['legs' = paramNames('legs',j,i)

				entriesj][i]['score' = {}

				entriesj][i]['weight' = 'normal'

				entriesj][i]['score']['weight' = {}

				if notempty(entriesj][i]['legs']) then

					legs = tonumber(entriesj][i]['legs'])

				end

				for l=1,legs do

					entriesj][i]['score'][l = bargs(tostring(masterindex)) or ''

					masterindex = masterindex+1

					entriesj][i]['score']['weight'][l = 'normal'

				end

				if aggregate and legs>1 then

					entriesj][i]['score']['agg' = bargs(masterindex) or ''

					masterindex = masterindex+1

					entriesj][i]['score']['weight']['agg' = 'normal'

				end

			end

			if entriesj][i]['ctype'=='header' then

				entriesj][i]['header' = paramNames('header',j,i)

				entriesj][i]['pheader' = paramNames('pheader',j,i)

				entriesj][i]['shade' = paramNames('shade',j,i)

			end

			if entriesj][i]['ctype'=='text' then

				entriesj][i]['text' = bargs(tostring(masterindex)) or ''

				masterindex = masterindex+1

			end

			if entriesj][i]['ctype'=='group' then

				entriesj][i]['group' = bargs(tostring(masterindex)) or ''

				masterindex = masterindex+1

			end

			if entriesj][i]['ctype' == 'line' and entriesj][i]['hastext'==true then

				entriesj][i]['text' = bargs(masterindex) or ''

				masterindex = masterindex+1

			end

		end

	end

end



local function assignParams()

	masterindex = 1

	local maxcol = 1

	local byerows = 1

	local hiderows = 1

	for j=minc,c do

		rlegsj = tonumber(bargs('RD'..j..'-legs')) or tonumber(bargs('legs')) or 1

		if notempty(bargs('RD'..j..'-legs')) or bargs('legs') then autolegs = false end

		if paramstyle == 'numbered' then

			indexedParams(j)

		else

			for i=1,r do

				if entriesj][i~=nil then

					if entriesj][i]['ctype'=='team' then

						local legs = rlegsj

						entriesj][i]['seed' = paramNames('seed',j,i)

						entriesj][i]['team' = paramNames('team',j,i)

						entriesj][i]['legs' = paramNames('legs',j,i)

						entriesj][i]['score' = {}

						entriesj][i]['weight' = 'normal'

						entriesj][i]['score']['weight' = {}

						if notempty(entriesj][i]['legs']) then

							legs = tonumber(entriesj][i]['legs'])

						end

						if autolegs then

							local l=1

							repeat

								entriesj][i]['score'][l = paramNames('score',j,i,l)

								entriesj][i]['score']['weight'][l = 'normal'

								l=l+1

							until isempty(paramNames('score',j,i,l))

							legs = l-1

						else

							for l=1,legs do

								entriesj][i]['score'][l = paramNames('score',j,i,l)

								entriesj][i]['score']['weight'][l = 'normal'

							end

						end

						if aggregate and legs>1 then

							entriesj][i]['score']['agg' = paramNames('score',j,i,'agg')

							entriesj][i]['score']['weight']['agg' = 'normal'

						end

					end

					if entriesj][i]['ctype'=='header' then

						entriesj][i]['header' = paramNames('header',j,i)

						entriesj][i]['pheader' = paramNames('pheader',j,i)

						entriesj][i]['shade' = paramNames('shade',j,i)

					end

					if entriesj][i]['ctype'=='text' then

						entriesj][i]['text' = paramNames('text',j,i)

					end

					if entriesj][i]['ctype'=='group' then

						entriesj][i]['group' = paramNames('group',j,i)

					end

					if entriesj][i]['ctype' == 'line' and entriesj][i]['hastext'==true then

						entriesj][i]['text' = paramNames('text',j,i)

					end

				end

				if autocol and not isBlankEntry(j,i) then

					maxcol = math.max(maxcol,j)

				end

			end

		end

		for i=1,r do

			if entriesj][i~=nil and entriesj][i]['ctype'=='header' then 

				isRoundHidden(j,i) 

			end

			if entriesj][i~=nil and not hidej][entriesj][i]['headerindex']] then

				if not byesj][entriesj][i]['headerindex']] or (byesj][entriesj][i]['headerindex']] and not isBlankEntry(j,i)) then

					byerows = math.max(byerows,i)

				end

			end

		end

	end

	for j=minc,c do

		for k=1,headerindexj do

			if byesj][k or hidej][k then

				r=byerows+1

			end

		end

	end

	if autocol then

		c = maxcol

	end

end



local function getHide(j,headerindex)

	hidej = {}

	for k=1,headerindexj do

		if bargs('RD'..j..toChar(k)..'-hide')=='yes' or bargs('RD'..j..toChar(k)..'-hide')=='y' then

			hidej][k=true

		end

	end

end



local function getByes(j,headerindex)

	byesj = {}

	for k=1,headerindexj do

		if bargs('byes')=='yes' or bargs('byes')=='y' then

			byesj][k=true 

		elseif tonumber(bargs('byes')) then

			if j<=tonumber(bargs('byes')) then

				byesj][k=true

			end

		else 

			byesj][k=false

		end

		if bargs('RD'..j..'-byes')=='yes' or bargs('RD'..j..'-byes')=='y' then

			byesj][k=true

		elseif bargs('RD'..j..'-byes')=='no' or bargs('RD'..j..'-byes')=='n' then

			byesj][k=false

		end

		if bargs('RD'..j..toChar(k)..'-byes')=='yes' or bargs('RD'..j..toChar(k)..'-byes')=='y' then

			byesj][k=true

		elseif bargs('RD'..j..'-byes')=='no' or bargs('RD'..j..'-byes')=='n' then

			byesj][k=false

		end

	end

end



local function getAltIndices()

	local teamindex=1

	local textindex=1

	local groupindex=1

	for j=minc,c do

		headerindexj=0

		for i=1,r do

			if entriesj][i==nil and i==1 then

				headerindexj=headerindexj+1

			end

			if entriesj][i~=nil then

				if entriesj][i]['ctype' == 'header' then

					entriesj][i]['altindex' = headerindexj

					teamindex=1

					textindex=1

					headerindexj=headerindexj+1

				elseif entriesj][i]['ctype' == 'team' then

					entriesj][i]['altindex' = teamindex

					teamindex=teamindex+1

				elseif entriesj][i]['ctype' == 'text' then

					entriesj][i]['altindex' = textindex

					textindex=textindex+1

				elseif entriesj][i]['ctype' == 'group' then

					entriesj][i]['altindex' = groupindex

					groupindex=groupindex+1

				elseif entriesj][i]['ctype' == 'line' and entriesj][i]['hastext'==true then

					entriesj][i]['altindex' = textindex

					textindex=textindex+1

				end

				entriesj][i]['headerindex' = headerindexj

			end

		end

		getByes(j,headerindex)

		getHide(j,headerindex)

	end

end



local function noPaths(j,i)

	local result = true

	local cols = 2

	if hascrossj==true then

		cols = 3

	end

	for k=1,cols do

		for n=1,4 do

			if pathCellj][i][k][1][n~=0 then

				result = false

				return result

			end

		end

	end

	if hascrossj==true and (crossCellj][i]['left'][1==1 or crossCellj][i]['right'][1==1) then

		result = false

		return result

	end

	return result

end



local function generatePathCell(tbl,j,i,k,bg,rowspan)

	local color = pathCellj][i][k]['color'

	if not hascrossj and k==2 then 

		return 

	end

	local cell=tbl:tag('td')

	local a=pathCellj][i

	if rowspan~=1 then

		cell:attr('rowspan',rowspan)

	end

	if notempty(bg) and k==2 then

		cell:css('background',bg)

			:css('transform','translate(-1px)')

	end

	if ak][1][1~=0 or ak][1][2~=0 or ak][1][3~=0 or ak][1][4~=0 then

		cell:css('border','solid '..color)

			:css('border-width',2*ak][1][1..'px '..2*ak][1][2..'px '..2*ak][1][3..'px '..2*ak][1][4..'px')

	end

	return cell

end



local function insertPath(tbl,j,i)

	if skipPathj][i then

		return

	end



	local colspan = 2

	local rowspan = 1

	local angle = 58.2

	local pathcolor

	local bg = ''

	local cross = {'',''}

	

	if i<r then

		local function repeatedPath(a)

			if a>r-1 or skipPathj][a then

				return false

			end

			for k=1,3 do

				for n=1,4 do

					if pathCellj][i][k][1][n~=pathCellj][a][k][1][n then

						return false

					end

				end

			end

			return true

		end

		if repeatedPath(i) then

			local row=i

			repeat

				if row~=i and repeatedPath(row) then

					skipPathj][row=true

				end

				rowspan=rowspan+1

				row=row+1

			until row>r or not repeatedPath(row)

			rowspan=rowspan-1

		end

	end

	

	if i>1 and (crossCellj][i-1]['left'][1==1 or crossCellj][i-1]['right'][1==1) then

		return

	end

	if hascrossj then

		colspan = 3

		if crossCellj][i]['left'][1==1 or crossCellj][i]['right'][1==1 then

			rowspan = 2

			if crossCellj][i]['left'][1==1 then

				cross1 = 'linear-gradient(to top right, transparent calc(50% - 1px),'..crossCellj][i]['left'][2..' calc(50% - 1px),'..crossCellj][i]['left'][2..' calc(50% + 1px), transparent calc(50% + 1px))'

			end

			if crossCellj][i]['right'][1==1 then

				cross2 = 'linear-gradient(to bottom right, transparent calc(50% - 1px),'..crossCellj][i]['right'][2..' calc(50% - 1px),'..crossCellj][i]['right'][2..' calc(50% + 1px), transparent calc(50% + 1px))'

			end

		end

		if notempty(cross1]) and notempty(cross2]) then

			cross1 = cross1..','

		end

		bg = cross1..cross2

	end

	for k=1,3 do

		generatePathCell(tbl,j,i,k,bg,rowspan)

	end

end



local function parsePaths(j)

	local result={}

	local str = fargs'col'..j..'-col'..(j+1)..'-paths' or ''

		for val in str:gsub("%s+","")

					:gsub(",",", ")

					:gsub("%S+","\0%0\0")

					:gsub("%b()", function(s) return s:gsub("%z","") end)

					:gmatch("%z(.-)%z") do

			local array = split(val:gsub("%s+",""):gsub("%)",""):gsub("%(",""),{"-"})

			for k,_ in pairs(array) do

				arrayk = split(arrayk],{","})

			end

			if notempty(array2]) then

				for m=1,#array2 do

					array3 = {}

					array2][m = split(array2][m],{":"})

					array3][m = array2][m][2

					array2][m = array2][m][1

				end

				for n=1,#array1 do

					for m=1,#array2 do

						table.insert(result,{tonumber(array1][n]),tonumber(array2][m]),['color'=array3][m]})

					end

				end

			end

		end

	return result

end



local function isPathHidden(j,i,start,stop)

	local result=false

	if notempty(entriesj][start-1]) and (byesj][entriesj][start-1]['headerindex']] and isBlankEntry(j,start-1) and isBlankEntry(j,start+1) or hidej][entriesj][start-1]['headerindex']]) then

		if bargs('show-bye-paths')~='y' and bargs('show-bye-paths')~='yes' then

			result=true

		end

	end

	if notempty(entriesj+1][stop-1]) and (byesj+1][entriesj+1][stop-1]['headerindex']] and isBlankEntry(j+1,stop-1) and isBlankEntry(j+1,stop+1) or hidej+1][entriesj+1][stop-1]['headerindex']])then

		if bargs('show-bye-paths')~='y' and bargs('show-bye-paths')~='yes' then

			result=true

		end

	end

	if bargs('RD'..j..'-RD'..(j+1)..'-path')=='n' or bargs('RD'..j..'-RD'..(j+1)..'-path')=='no' or bargs('RD'..j..'-RD'..(j+1)..'-path')=='0' then

		if notempty(entriesj][start-1]) and entriesj][start-1]['headerindex'==1 then

			result=true

		end

	end

	return result

end



local function getPaths()

	local paths = {}

	for j=minc,c-1 do

		hascrossj = false

		if notempty(fargs'col'..j..'-col'..(j+1)..'-cross']) then

			hascrossj = true

		end

	end

	for j=minc,c-1 do

		local straightpaths = {}

		local outpaths = {}

		local inpaths = {}

		pathsj=parsePaths(j)

		pathCellj = {}

		crossCellj = {}

		skipPathj = {}

		for i=1,r do

			pathCellj][i = {}

			crossCellj][i = {['left'={0,'black'},['right'={0,'black'}}

			for k=1,3 do

				pathCellj][i][k = {{0,0,0,0},['color'='black'}

			end

			skipPathj][i = false

			end

		local crossloc = split((fargs'col'..j..'-col'..(j+1)..'-cross' or ''):gsub("%s+", ""),{","},true)

		if shiftj~=0 and notempty(crossloc1]) then

			for n=1,#crossloc do

				crosslocn = crosslocn+shiftj

			end

		end

		for k,v in ipairs(pathsj]) do

			local start = 2*(pathsj][k][1+shiftj])+(teams_per_matchj-2)

			local stop = 2*(pathsj][k][2+shiftj+1])+(teams_per_matchj+1-2)

			local mid = {}

			local cross = 0

			

			if notempty(crossloc1]) then

				for n=1,#crossloc do

					midn = 2*crosslocn+(teams_per_matchj-2)

				end

			else

				mid1=0

			end

			for n=1,#mid do

				if (start<stop and midn<stop and midn>start) or (start>stop and midn>stop and midn<start) then

					cross = midn

				end

			end

			pathsj][k]['color' = pathsj][k]['color' or 'black'

			table.insert(outpaths,{start,pathsj][k]['color']})

			table.insert(inpaths,{stop,pathsj][k]['color']})

			if not isPathHidden(j,i,start,stop) then

				if start==stop then

					table.insert(straightpaths,{start,pathsj][k]['color']})

				elseif start<stop then

					if stop>r then break end

					pathCellj][start+1][1][1][1 = 1

					pathCellj][start+1][1]['color' = pathsj][k]['color'

					if cross==0 then

						if hascrossj then

							pathCellj][start+1][2][1][1 = 1

							pathCellj][start+1][2]['color' = pathsj][k]['color'

							for i=start+1,stop do

								pathCellj][i][2][1][2 = 1

								pathCellj][i][2]['color' = pathsj][k]['color'

							end

						else

							for i=start+1,stop do

								pathCellj][i][1][1][2 = 1

								pathCellj][i][1]['color' = pathsj][k]['color'

							end

						end

					else

						crossCellj][cross]['left' = {1,pathsj][k]['color']}

						for i=start+1,cross-1 do 

							pathCellj][i][1][1][2 = 1

							pathCellj][i][1]['color' = pathsj][k]['color'

							end

						for i=cross+2,stop do 

							pathCellj][i][2][1][2 = 1 

							pathCellj][i][2]['color' = pathsj][k]['color'

							end	

					end

					pathCellj][stop][3][1][3 = 1

					pathCellj][stop][3]['color' = pathsj][k]['color'

				elseif start>stop then

					if start>r then break end

					pathCellj][stop+1][3][1][1 = 1

					pathCellj][stop+1][3]['color' = pathsj][k]['color'

					if cross==0 then

						if hascrossj then

							for i=stop+1,start do

								pathCellj][i][2][1][2 = 1

								pathCellj][i][2]['color' = pathsj][k]['color'

							end

							pathCellj][start][2][1][3 = 1

							pathCellj][start][2]['color' = pathsj][k]['color'

						else

							for i=stop+1,start do

								pathCellj][i][1][1][2 = 1

								pathCellj][i][1]['color' = pathsj][k]['color'

							end

						end

					else

						crossCellj][cross]['right' = {1,pathsj][k]['color']}

						for i=stop+1,cross-1 do 

							pathCellj][i][2][1][2 = 1 

							pathCellj][i][2]['color' = pathsj][k]['color'

							end

						for i=cross+2,start do 

							pathCellj][i][1][1][2 = 1 

							pathCellj][i][1]['color' = pathsj][k]['color'

							end	

					end

					pathCellj][start][1][1][3 = 1

					pathCellj][start][1]['color' = pathsj][k]['color'

				end

			end

		end

		-- Thicken start==stop paths

		for n=1,#straightpaths do

			local i = straightpathsn][1

			local color = straightpathsn][2

			if i>r then break end

			if pathCellj][i][1][1][3==0 then

				pathCellj][i][1][1][3 = 1

				pathCellj][i][2][1][3 = 1

				pathCellj][i][3][1][3 = 1

				pathCellj][i][1]['color' = color

				pathCellj][i][2]['color' = color

				pathCellj][i][3]['color' = color

				if pathCellj][i+1][1][1][1==0 then

					pathCellj][i+1][1][1][1 = 0.5

					pathCellj][i+1][2][1][1 = 0.5

					pathCellj][i+1][3][1][1 = 0.5

					pathCellj][i+1][1]['color' = color

					pathCellj][i+1][2]['color' = color

					pathCellj][i+1][3]['color' = color

				end

			elseif pathCellj][i+1][1][1][1==0 then

				pathCellj][i+1][1][1][1 = 1

				pathCellj][i+1][1]['color' = color

				if hascrossj then

					pathCellj][i+1][2][1][1 = 1

					pathCellj][i+1][2]['color' = color

				end

				pathCellj][i+1][3][1][1 = 1

				pathCellj][i+1][3]['color' = color

			end

		end

		-- Thicken/Thin out paths

		for n=1,#outpaths do

			local i = outpathsn][1

			local color = outpathsn][2

			if i<r and pathCellj][i][1][1][3==1 and pathCellj][i+1][1][1][1==0 then

				pathCellj][i+1][1][1][1 = 0.5*pathCellj][i][1][1][3

				pathCellj][i+1][2][1][1 = 0.5*pathCellj][i][2][1][3

				pathCellj][i+1][1]['color' = pathCellj][i][1]['color'

				pathCellj][i+1][2]['color' = pathCellj][i][2]['color'

			elseif i<r and pathCellj][i][1][1][3==0 and pathCellj][i+1][1][1][1==1 then

				pathCellj][i][1][1][3 = pathCellj][i+1][1][1][1

				pathCellj][i][2][1][3 = pathCellj][i+1][2][1][1

				pathCellj][i+1][1][1][1 = 0.5*pathCellj][i][1][1][3

				pathCellj][i+1][2][1][1 = 0.5*pathCellj][i][2][1][3

				pathCellj][i][1]['color' = pathCellj][i+1][1]['color'

				pathCellj][i][2]['color' = pathCellj][i+1][2]['color'

			end

		end

		-- Thin double-in paths

		for n=1,#inpaths do

			local i = inpathsn][1

			local color = inpathsn][2

			if i<r and pathCellj][i][3][1][3==1 and pathCellj][i+1][3][1][1==1 and pathCellj][i][3]['color'==pathCellj][i+1][3]['color' then

				pathCellj][i+1][3][1][1 = 0.5*pathCellj][i][3][1][3

			end

		end

	end

	for j=minc,c-1 do

		for i=1,r-1 do

			local straightpath=false

			if (entriesj+1][i-1==nil or (byesj+1][entriesj+1][i-1]['headerindex']]) and isBlankEntry(j+1,i-1)) then

				if (pathCellj][i][3][1][3~=0 and pathCellj+1][i][1][1][3~=0) or (pathCellj][i+1][3][1][1~=0 and pathCellj+1][i+1][1][1][1~=0) then

					if pathCellj+1][i][1][1][3==pathCellj+1][i][3][1][3 and pathCellj+1][i+1][1][1][1==pathCellj+1][i+1][3][1][1 then

						straightpath=true

					end

					pathCellj+1][i][1][1][3=pathCellj][i][3][1][3

					pathCellj+1][i+1][1][1][1=pathCellj][i+1][3][1][1

					pathCellj+1][i][2][1][3=pathCellj][i][3][1][3

					pathCellj+1][i+1][2][1][1=pathCellj][i+1][3][1][1

					entriesj+1][i-1={['ctype'='line'}

					entriesj+1][i={['ctype'='blank'}

					if notempty(entriesj+1][i+1]) then

						entriesj+1][i+1]['ctype' = 'line2'

					else

						entriesj+1][i+1={['ctype'='line2'}

					end

					entriesj+1][i+2={['ctype'='blank'}

					if straightpath then

						pathCellj+1][i][3][1][3=pathCellj+1][i][1][1][3

						pathCellj+1][i+1][3][1][1=pathCellj+1][i+1][1][1][1

					end

				end

			end

		end

	end

end



local function getGroups()

	local function check(j,i)

		local result=false

		if entriesj][i == nil then

			if entriesj][i+1 == nil then 

				result=true 

			elseif entriesj][i+1]['ctype'=='text' and isBlankEntry(j,i+1) then

				result=true

			end

		elseif entriesj][i]['ctype'=='text' and isBlankEntry(j,i) then

			result=true

		end

		return result

	end

	for j=minc,c-1 do

		if teams_per_matchj==2 then

			local n=0

			for i=1,r-1 do

				if pathCellj][i][3][1][3==1 or pathCellj][i+1][3][1][1==1 then

					n=n+1

					if check(j,i) then

						local k=minc-1

						repeat

							if entriesj-k][i+1~=nil and entriesj-k][i+1]['ctype'=='text' and isBlankEntry(j-k,i+1) then

								entriesj-k][i+2=nil

							end

							entriesj-k][i={['ctype'='blank'}

							entriesj-k][i+1={['ctype'='blank'}

							if k>0 and noPaths(j-k,i) then

								skipPathj-k][i = true

								skipPathj-k][i+1 = true

							end

							k=k+1

						until k>j-1 or not check(j-k,i) or not noPaths(j-k,i)

						k=k-1

						entriesj-k][i={['ctype'='group',['index'=n,['colspan'=k+1}

						entriesj-k][i+1={['ctype'='blank'}

						entriesj-k][i]['group' = bargs('RD'..j..'-group'..n)

					end

				end

			end

		end

	end

end



local function getCells()

	local maxrow = 1

	local colentry = {}

	local bool = true

	for j=minc,c do

		if notempty(fargs'col'..j..'-headers']) then bool=false end

		teams_per_matchj = tonumber(fargs'RD'..j..'-teams-per-match']) or tonumber(fargs'col'..j..'-teams-per-match']) or tonumber(fargs'teams-per-match']) or 2

		maxtpm = math.max(maxtpm,teams_per_matchj])

	end

	for j=minc,c do

		entriesj = {}

		shiftj = tonumber(bargs('RD'..j..'-shift')) or tonumber(bargs('shift')) or 0

		colentryj = {

			split((fargs'col'..j..'-headers' or ''):gsub("%s+", ""),{","},true),

			split((fargs'col'..j..'-matches' or ''):gsub("%s+", ""),{","},true),

			split((fargs'col'..j..'-lines' or ''):gsub("%s+", ""),{","},true),

			split((fargs'col'..j..'-text' or ''):gsub("%s+", ""),{","},true),

		}

		if bool==true and fargs'noheaders'~='y' and fargs'noheaders'~='yes' then

			table.insert(colentryj][1],1)

		end

	end



	for j=minc,c do

		local textindex=0

		for k,v in ipairs(colentryj]) do

			table.sort(colentryj][k])

			local ctype

			if k==1 then ctype='header'

			elseif k==2 then ctype='team'

			elseif k==3 then ctype='line'

			elseif k==4 then ctype='text'

			elseif k==5 then ctype='group'

			end

			for n=1,#colentryj][k do

				if shiftj~=0 and colentryj][k][n>1 then

					colentryj][k][n = colentryj][k][n+shiftj

				end

				local i=2*colentryj][k][n-1

				maxrow = math.max(i+2*teams_per_matchj-1,maxrow)

				if ctype=='team' then

					if entriesj][i-1==nil and entriesj][i-2==nil then

						entriesj][i-2={['ctype'='text',['index'=n}

						entriesj][i-1={['ctype'='blank'}

						textindex=n

					end

					entriesj][i={['ctype'=ctype,['index'=teams_per_matchj*n-(teams_per_matchj-1),['position'='top'}

					entriesj][i+1={['ctype'='blank'}

					for m=2,teams_per_matchj do

						entriesj][i+2*(m-1)]={['ctype'=ctype,['index'=teams_per_matchj*n-(teams_per_matchj-m)}

						entriesj][i+2*(m-1)+1={['ctype'='blank'}

					end

				elseif ctype=='text' then

					entriesj][i={['ctype'=ctype,['index'=textindex+n}

					entriesj][i+1={['ctype'='blank'}

				elseif ctype=='line' then

					entriesj][i={['ctype'=ctype}

					entriesj][i+1={['ctype'='blank'}

					entriesj][i+2={['ctype'='line2'}

					entriesj][i+3={['ctype'='blank'}

				elseif ctype=='group' then

					entriesj][i={['ctype'=ctype,['index'=n}

					entriesj][i+1={['ctype'='blank'}

				else

					entriesj][i={['ctype'=ctype,['index'=n,['position'='top'}

					entriesj][i+1={['ctype'='blank'}

				end

			end

		end

	end

	if isempty(r) then

		r = maxrow

	end

end



function p.main(frame)

	fargs = frame.args

	pargs = frame:getParent().args;

	

	

	r = tonumber(fargs.rows) or ''

	c = tonumber(fargs.rounds) or 1

	maxc = tonumber(pargs.maxrounds) or tonumber(pargs.maxround) or ''

	minc = tonumber(pargs.minround) or 1

	headerindex = {}

	if notempty(maxc) then c=maxc end

	if fargs.autocol=='yes' or fargs.autocol=='y' then autocol=true end

	local colspacing = tonumber(fargs'col-spacing']) or 5

	local height = bargs('height') or 0 

	

	maxtpm = 1

	seeds = true

	nowrap = true

	forceseeds = false

	boldwinner = bargs('boldwinner') or ''

	if bargs('seeds')=='y' or bargs('seeds')=='yes' then forceseeds=true end

	if bargs('seeds')=='n' or bargs('seeds')=='no' then seeds=false end

	if bargs('aggregate')=='y' or bargs('aggregate')=='yes' then aggregate=true end

	if bargs('autolegs')=='y' or bargs('autolegs')=='yes' then autolegs=true end

	if bargs('paramstyle')=='numbered' then 

		paramstyle = 'numbered'

	else

		paramstyle = 'indexed'

	end

	if pargs.nowrap=='n' or pargs.nowrap=='no' then nowrap=false end

	

	getCells()

	getAltIndices()

	assignParams()

	matchGroups()

	if (boldwinner=='yes' or boldwinner=='y' or boldwinner=='high') then boldWinner() end

	getPaths()

	if minc==1 then

	getGroups()

	end

	

	for j=minc,c do

		maxlegsj = rlegsj

		for i=1,r do

			if notempty(entriesj][i]) then

				if notempty(entriesj][i]['legs']) then

					maxlegsj = math.max(rlegsj],entriesj][i]['legs'])

				end

				if autolegs then

					local l=1

					repeat l=l+1

					until isempty(entriesj][i]['score']) or isempty(entriesj][i]['score'][l])

					maxlegsj = math.max(maxlegsj],l-1)

				end

			end

		end

	end

	

	local div = mw.html.create('div')

    		:css('overflow','auto')

    		

	if height~=0 then

		div:css('height',height)

	end

	

	local tbl = mw.html.create('table')

			:attr('cellpadding','0')

			:attr('cellspacing','0')

			:css('font-size','90%')

			:css('border-collapse','separate')

			:css('margin','1em 2em 0em 1em')

			

	if nowrap then 

		tbl:css('white-space','nowrap') 

	end

	

	tbl:tag('tr'):css('visibility','collapse')

	tbl:tag('td'):css('width','1px')

	for j=minc,c do

		if seeds then

			tbl:tag('td'):css('width',getWidth('seed','25px'))

		end

		tbl:tag('td'):css('width',getWidth('team','150px'))

		if maxlegsj==0 then

			tbl:tag('td'):css('width',getWidth('score','25px'))

			else

			for l=1,maxlegsj do

				tbl:tag('td'):css('width',getWidth('score','25px'))

			end

		end

		if aggregate and maxlegsj>1 then

			tbl:tag('td'):css('width',getWidth('agg',getWidth('score','25px')))

		end

		if j~=c then

			if hascrossj then

				tbl:tag('td'):css('width',colspacing+1-4 ..'px')

							:css('padding-left','4px')

				tbl:tag('td'):css('padding-left','5px')

							:css('width','5px')

				tbl:tag('td'):css('width',colspacing-1-2 ..'px')

							:css('padding-right','2px')

			else

				tbl:tag('td'):css('width',colspacing+1-4 ..'px')

							:css('padding-left','4px')

				tbl:tag('td'):css('width',colspacing-1-2 ..'px')

							:css('padding-right','2px')

			end

		end

	end

	

	for i=1,r do

		local row = tbl:tag('tr')

		row:tag('td'):css('height','11px')

		for j=minc,c do

			insertEntry(row,j,i)

			if j~=c then

				insertPath(row,j,i)

			end

		end

	end

	

	div:wikitext(tostring(tbl))

			

	return tostring(div)

end



return p

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook