Module:Election results#L-525

require('strict')

local p = {}

local political_party = require('Module:Political party')

function p.main(frame)

local args = require('Module:Arguments').getArgs(frame)

local index, headings, showtotal = {}, {}, {}

local cols, rounds = 0, 1

local winner, winner_votes = {0, 0, 0}, {0, 0, 0}

local valid = {0, 0, 0}

local invalid = {tonumber(args.invalid) or 0, tonumber(args.invalid2) or 0, tonumber(args.invalid3) or 0}

local blank = {tonumber(args.blank) or 0, tonumber(args.blank2) or 0, tonumber(args.blank3) or 0}

local majority = {tonumber(args.majority)}

local majority2 = {tonumber(args.majority2)}

local majoritypct = {tonumber(args.majoritypct)}

local majoritypct2 = {tonumber(args.majoritypct2)}

local totalvotes = {tonumber(args.totalvotes), tonumber(args.totalvotes2), tonumber(args.totalvotes3)}

local electorate = {tonumber(args.electorate), tonumber(args.electorate2), tonumber(args.electorate3)}

local turnout = {tonumber(args.turnout), tonumber(args.turnout2), tonumber(args.turnout3)}

local seats = 0

local seats_2 = 0

local seats_3 = 0

local st1t = 0

local st2t = 0

local st3t = 0

local st4t = 0

local st5t = 0

local totseats = 0

local row, secondrow

local tracking = ''

local max_rows = 0

-- helper functions

local lang = mw.getContentLanguage()

local function fmt(n)

return n and tonumber(n) and lang:formatNum(tonumber(n)) or nil

end

local function pct(n, d)

n, d = tonumber(n), tonumber(d)

if n and d and d > 0 then

return string.format('%.2f', n / d * 100)

end

return '–'

end

local function tonumdash(s)

if s then

s = mw.ustring.gsub(s, '&[MmNn][Dd][Aa][Ss][Hh];', '-')

s = mw.ustring.gsub(s, '&[Mm][Ii][Nn][Uu][Ss];', '-')

s = mw.ustring.gsub(s, '[—–−]', '-')

return tonumber(s) or 0

end

end

local function unlink(s)

if s then

s = s:match("^[^%[]-%[%[([^%]]-)|[^%]]-%]%].*$") or s

s = s:match("^[^%[]-%[%[([^%]]-)%]%].*$") or s

end

return s

end

local function get_color(color, party)

if color == nil then

local party = unlink(party) or ''

if party ~= '' then

color = political_party._fetch({party, 'color'})

end

end

if color ~= nil then

color = mw.ustring.gsub(color, '&(#)35;', '%1')

end

return color

end

-- preprocess the input

local stop_flag = false

local i = 0

local has_votes = args['invalid'] or args['totalvotes'] or args['electorate'] or args['turnout']

local has_votes2 = args['invalid2'] or args['totalvotes2'] or args['electorate2'] or args['turnout2']

local has_votes3 = args['votes' .. i .. '_3'] or args['ivotes' .. i .. '_3']

local has_seats2 = args['seats' .. i .. '_2'] or args['iseats' .. i .. '_2']

local has_seats3 = args['seats' .. i .. '_3']

local has_sw2 = args['sw' .. i .. '_2']

local seats_only = has_seats2 and not has_votes

local has_cand = args['cand' .. i]

local has_alliance = args['alliance' .. i]

local has_party = args['party' .. i]

local has_rspan = args['vspan' .. i] or args['v2span' .. i]

local has_sspan = args['sspan' .. i] or args['tsspan' .. i]

while stop_flag == false do

stop_flag = true

for kk = 1, 20 do

i = i + 1

for k, key in ipairs({'alliance', 'atotal', 'cand', 'vp', 'party', 'ivotes', 'ipct', 'iseats', 'sc', 'st1t', 'st2t', 'st3t', 'st4t', 'st5t', 'sw', 'seats', 'totalvotes', 'totseats', 'acolor', 'rcolor'}) do

if args[key .. i] then

headings[key] = true

stop_flag = false

max_rows = i > max_rows and i or max_rows

end

end

if args['row' .. i] then

stop_flag = false

max_rows = i > max_rows and i or max_rows

end

if args['row' .. i] or args['cand' .. i] or args['party' .. i] or args['alliance' .. i] or args['atotal' .. i] or args['atotalnv' .. i] or args['header' .. i] then

table.insert(index, i)

if args['votes' .. i] then

has_votes = true

if tonumber(args['votes' .. i]) then showtotal.votes = 1 end

local votesi = tonumber(args['votes' .. i]) or 0

args['votes' .. i] = votesi

if votesi > winner_votes[1] then

winner[1] = i

winner_votes[1] = votesi

end

valid[1] = valid[1] + votesi

end

if args['votes' .. i .. '_2'] or args['ivotes' .. i .. '_2'] or args['avotes' .. i .. '_2'] or args['ipct' .. i .. '_2'] or args['apct' .. i .. '_2'] then

has_votes2 = true

end

if args['votes' .. i .. '_3'] or args['ivotes' .. i .. '_3'] or args['ipct' .. i .. '_3'] then

has_votes3 = true

end

if args['alliance' .. i] then

has_alliance = true

end

if args['party' .. i] then

has_party = true

end

if args['cand' .. i] then

has_cand = true

end

if args['ivotes' .. i] then

has_votes = true

end

if args['ipct' .. i] then

has_votes = true

end

if args['sw' .. i .. '_2'] then

has_sw2 = true

rounds = (rounds < 2) and 2 or rounds

end

if args['valid2'] or args['invalid2'] or args['totalvotes2'] or args['electorate2'] or args['turnout2'] then

rounds = (rounds < 2) and 2 or rounds

end

if args['vspan' .. i] or args['v2span' .. i] then

has_rspan = true

end

if args['sspan' .. i] or args['tsspan' .. i] then

has_sspan = true

end

if args['ipct' .. i .. '_2'] then

rounds = (rounds < 2) and 2 or rounds

end

if args['votes' .. i .. '_2'] then

has_votes = true

rounds = (rounds < 2) and 2 or rounds

if tonumber(args['votes' .. i .. '_2']) then showtotal.votes_2 = 1 end

local votesi = tonumber(args['votes' .. i .. '_2']) or 0

args['votes' .. i .. '_2'] = votesi

if votesi > winner_votes[2] then

winner[2] = i

winner_votes[2] = votesi

end

valid[2] = valid[2] + votesi

end

if args['votes' .. i .. '_3'] then

has_votes = true

rounds = (rounds < 3) and 3 or rounds

if tonumber(args['votes' .. i .. '_3']) then showtotal.votes_3 = 1 end

local votesi = tonumber(args['votes' .. i .. '_3']) or 0

args['votes' .. i .. '_3'] = votesi

if votesi > winner_votes[3] then

winner[3] = i

winner_votes[3] = votesi

end

valid[3] = valid[3] + votesi

end

if args['seats' .. i] then

if tonumber(args['seats' .. i]) then showtotal.seats = 1 end

seats = seats + (tonumber(args['seats' .. i]) or 0)

end

if args['seats' .. i .. '_2'] or args['iseats' .. i .. '_2'] then

has_seats2 = true

rounds = (rounds < 2) and 2 or rounds

if tonumber(args['seats' .. i ..'_2']) then showtotal.seats_2 = 1 end

seats_2 = seats_2 + (tonumber(args['seats' .. i .. '_2']) or 0)

end

if args['seats' .. i .. '_3'] then

has_seats3 = true

rounds = (rounds < 3) and 3 or rounds

if tonumber(args['seats' .. i ..'_3']) then showtotal.seats_3 = 1 end

seats_3 = seats_3 + (tonumber(args['seats' .. i .. '_3']) or 0)

end

if args['st1t' .. i] then

if tonumber(args['st1t' .. i]) then showtotal.st1t = 1 end

st1t = st1t + (tonumber(args['st1t' .. i]) or 0)

end

if args['st2t' .. i] then

if tonumber(args['st2t' .. i]) then showtotal.st2t = 1 end

st2t = st2t + (tonumber(args['st2t' .. i]) or 0)

end

if args['st3t' .. i] then

if tonumber(args['st3t' .. i]) then showtotal.st3t = 1 end

st3t = st3t + (tonumber(args['st3t' .. i]) or 0)

end

if args['st4t' .. i] then

if tonumber(args['st4t' .. i]) then showtotal.st4t = 1 end

st4t = st4t + (tonumber(args['st4t' .. i]) or 0)

end

if args['st5t' .. i] then

if tonumber(args['st5t' .. i]) then showtotal.st5t = 1 end

st5t = st5t + (tonumber(args['st5t' .. i]) or 0)

end

if args['totseats' .. i] then

if tonumber(args['totseats' .. i]) then showtotal.totseats = 1 end

totseats = totseats + (tonumber(args['totseats' .. i]) or 0)

end

if has_seats2 and not has_votes or has_seats3 and not has_votes then

seats_only = true

end

end

end

end

local ovalid = {valid[1], valid[2], valid[3]}

seats = ((args['total_seats'] or '') == 'TOTAL' and seats) or args['total_seats'] or seats

totseats = ((args['total_totseats'] or '') == 'TOTAL' and totseats) or args['total_totseats'] or totseats

st1t = ((args['total_st1t'] or '') == 'TOTAL' and st1t) or args['total_st1t'] or st1t

st2t = ((args['total_st2t'] or '') == 'TOTAL' and st2t) or args['total_st2t'] or st2t

st3t = ((args['total_st3t'] or '') == 'TOTAL' and st3t) or args['total_st3t'] or st3t

st4t = ((args['total_st4t'] or '') == 'TOTAL' and st4t) or args['total_st4t'] or st4t

st5t = ((args['total_st5t'] or '') == 'TOTAL' and st5t) or args['total_st5t'] or st5t

if seats or totseats or st1t or st2t or st3t or st4t or st5t or args['total_sc'] or args['total_st1t'] or args['total_st2t'] or args['total_st3t'] or args['total_st4t'] or args['total_st5t'] or args['valid'] or ((rounds > 1) and args['valid2']) or ((rounds > 1) and args['valid3']) then

max_rows = max_rows + 1

local i = max_rows

table.insert(index, i)

args['votes' .. i] = showtotal.votes and valid[1] or nil

args['votes' .. i .. '_2'] = showtotal.votes_2 and valid[2] or nil

args['votes' .. i .. '_3'] = showtotal.votes_3 and valid[3] or nil

args['colour' .. i] = 'inherit'

args['color' .. i] = 'inherit'

args['row' .. i] = 'Total'

args['sw' .. i] = '–'

args['sw' .. i .. '_2'] = '–'

args['seats' .. i] = showtotal.seats and seats or nil

args['seats' .. i .. '_2'] = showtotal.seats_2 and seats_2 or nil

args['seats' .. i .. '_3'] = showtotal.seats_3 and seats_3 or nil

args['st1t' .. i] = showtotal.st1t and st1t or args.total_st1t

args['st2t' .. i] = showtotal.st2t and st2t or args.total_st2t

args['st3t' .. i] = showtotal.st3t and st3t or args.total_st3t

args['st4t' .. i] = showtotal.st4t and st4t or args.total_st4t

args['st5t' .. i] = showtotal.st5t and st5t or args.total_st5t

args['sc' .. i] = args['total_sc']

args['totseats' .. i] = showtotal.totseats and totseats or nil

args['font-weight' .. i] = 'bold'

args['class' .. i] = 'sortbottom'

ovalid[1] = tonumber(args['valid']) or valid[1]

ovalid[2] = tonumber(args['valid2']) or valid[2]

ovalid[3] = tonumber(args['valid3']) or valid[3]

end

-- build the table

local root = mw.html.create(args['embed'] and '' or 'table')

if args['embed'] == nil and args['floatright'] then

root

:addClass('wikitable sortable floatright')

:tag('caption')

:wikitext(args.caption)

:done()

elseif args['embed'] == nil then

root

:addClass('wikitable sortable')

:tag('caption')

:wikitext(args.caption)

:done()

end

local topcell = nil

if args['image'] then

topcell = root

:tag('th')

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

:css('color', 'var( --color-base, #202122 )')

:css('background', 'var( --background-color-neutral, #F8F9FA )')

:wikitext(args['image'])

end

if args['reporting'] then

if (topcell == nil) then

topcell = root

:tag('td')

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

:css('color', 'var( --color-base, #202122 )')

:css('background', 'var( --background-color-neutral, #F8F9FA )')

end

topcell:tag('div')

:addClass('center')

:wikitext(frame:expandTemplate{

title = 'percentage bar',

args = {args.reporting,

args.reporting .. '% reporting',

['width'] = '200px',

['hex'] = '1BCE0E'

}})

end

local rowspan = (rounds > 1) and 2 or headings['st1t'] and 2 or nil

row = args['embed'] and mw.html.create('') or root:tag('tr')

if args['dsv'] and has_alliance and has_party then

row

:tag('th')

:wikitext(args.partytitle or 'Party or alliance')

:attr('scope', 'col')

:attr('colspan', 4)

:attr('rowspan', rowspan)

:done()

cols = cols + 4

row

:tag('th')

:wikitext(args.candtitle or 'Candidate')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 1

elseif args['dsv'] then

row

:tag('th')

:wikitext(args.partytitle or 'Party')

:attr('scope', 'col')

:attr('colspan', 2)

:attr('rowspan', rowspan)

:done()

cols = cols + 2

row

:tag('th')

:wikitext(args.candtitle or 'Candidate')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 1

elseif has_cand then

if has_cand and has_party and has_alliance then

row

:tag('th')

:wikitext('Candidate')

:attr('rowspan', rowspan)

:attr('colspan', 2)

if headings['vp'] then

row

:tag('th')

:wikitext('Running mate')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 1

end

row

:tag('th')

:wikitext(args.partytitle or 'Party or alliance')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:attr('colspan', 3)

:done()

cols = cols + 5

elseif has_cand and has_party then

row

:tag('th')

:wikitext('Candidate')

:attr('scope', 'col')

:attr('colspan', 2)

:attr('rowspan', rowspan)

:done()

cols = cols + 2

end

if has_cand and not has_party then

row

:tag('th')

:wikitext('Candidate')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 1

end

if headings['vp'] and not has_alliance then

row

:tag('th')

:wikitext('Running mate')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 1

end

if has_party and not has_alliance then

row

:tag('th')

:wikitext(args.partytitle or 'Party')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 1

end

elseif has_party and has_alliance then

row

:tag('th')

:wikitext(args.partytitle or 'Party or alliance')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:attr('colspan', 4)

:done()

cols = cols + 4

else

row

:tag('th')

:wikitext(args.partytitle or 'Party')

:attr('scope', 'col')

:attr('colspan', 2)

:attr('rowspan', rowspan)

:done()

cols = cols + 2

end

if rounds > 1 then

if has_seats2 and headings['sw'] and not has_seats3 then

row

:tag('th')

:wikitext(args.firstround or 'First round')

:attr('scope', 'col')

:attr('colspan', 4)

:done()

:tag('th')

:wikitext(args.secondround or 'Second round')

:attr('scope', 'col')

:attr('colspan', 4)

:done()

elseif has_seats2 and not has_seats3 then

row

:tag('th')

:wikitext(args.firstround or 'First round')

:attr('scope', 'col')

:attr('colspan', 3)

:done()

:tag('th')

:wikitext(args.secondround or 'Second round')

:attr('scope', 'col')

:attr('colspan', 3)

:done()

elseif has_seats3 then

row

:tag('th')

:wikitext(args.firstround or 'First round')

:attr('scope', 'col')

:attr('colspan', 3)

:done()

:tag('th')

:wikitext(args.secondround or 'Second round')

:attr('scope', 'col')

:attr('colspan', 3)

:done()

:tag('th')

:wikitext(args.thirdround or 'Third round')

:attr('scope', 'col')

:attr('colspan', 3)

:done()

elseif has_votes3 then

row

:tag('th')

:wikitext(args.firstround or 'First round')

:attr('scope', 'col')

:attr('colspan', 2)

:done()

:tag('th')

:wikitext(args.secondround or 'Second round')

:attr('scope', 'col')

:attr('colspan', 2)

:done()

:tag('th')

:wikitext(args.thirdround or 'Third round')

:attr('scope', 'col')

:attr('colspan', 2)

:done()

elseif has_votes then

row

:tag('th')

:wikitext(args.firstround or 'First round')

:attr('scope', 'col')

:attr('colspan', 2)

:done()

:tag('th')

:wikitext(args.secondround or 'Second round')

:attr('scope', 'col')

:attr('colspan', 2)

:done()

end

secondrow = args['embed'] and mw.html.create('') or root:tag('tr')

else

secondrow = row

end

rowspan = (rounds > 1) and 1 or (rounds < 2 and headings['st1t']) and 2 or nil

if has_seats2 and not has_seats3 and headings['sw'] then

for k=1, rounds do

secondrow

:tag('th')

:wikitext(args.votestitle or 'Votes')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

:tag('th')

:wikitext('%')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

:tag('th')

:wikitext('+/–')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

:tag('th')

:wikitext(args.seatstitle or 'Seats')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 4

end

end

if has_seats2 and not headings['sw'] or has_seats3 and not headings['sw'] then

for k=1, rounds do

secondrow

:tag('th')

:wikitext(args.votestitle or 'Votes')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

:tag('th')

:wikitext('%')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

:tag('th')

:wikitext(args.seatstitle or 'Seats')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 3

end

end

if has_votes and not has_seats2 then

for k=1, rounds do

secondrow

:tag('th')

:wikitext(args.votestitle or 'Votes')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

:tag('th')

:wikitext('%')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 2

end

end

if headings['sw'] and not has_seats2 then

row

:tag('th')

:wikitext('+/–')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 1

end

rowspan = (rounds > 1) and 2 or headings['sc'] and headings['st1t'] and 2 or headings['seats'] and headings['st1t'] and 2 or nil

if headings['seats'] and not has_seats2 then

row

:tag('th')

:wikitext(args.seatstitle or 'Seats')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 1

end

if headings['st1t'] then

row

:tag('th')

:wikitext('Seats')

:attr('colspan', 5)

:attr('scope', 'col')

:done()

if rounds < 2 then secondrow = root:tag('tr')

end

secondrow

:tag('th')

:wikitext(args.seattype1)

:attr('scope', 'col')

:done()

cols = cols + 1

if headings['st2t'] then

secondrow

:tag('th')

:wikitext(args.seattype2)

:attr('scope', 'col')

:done()

cols = cols + 1

end

if headings['st3t'] then

secondrow

:tag('th')

:wikitext(args.seattype3)

:attr('scope', 'col')

:done()

cols = cols + 1

end

if headings['st4t'] then

secondrow

:tag('th')

:wikitext(args.seattype4)

:attr('scope', 'col')

:done()

cols = cols + 1

end

if headings['st5t'] then

secondrow

:tag('th')

:wikitext(args.seattype5)

:attr('scope', 'col')

:done()

cols = cols + 1

end

end

if headings['totseats'] then

row

:tag('th')

:wikitext(headings['totseats'] and 'Total
seats' or 'Totseats±')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 1

end

if headings['sc'] then

row

:tag('th')

:wikitext(args.sctitle or '+/–')

:attr('scope', 'col')

:attr('rowspan', rowspan)

:done()

cols = cols + 1

end

if topcell then

topcell:attr('colspan', cols)

end

local cs = cols - 2*rounds

- (headings['sw'] and 1 or 0)

- (headings['totseats'] and 1 or 0)

- (headings['seats'] and 1 or 0)

- (headings['sc'] and 1 or 0)

- (headings['st1t'] and 1 or 0)

- (headings['st2t'] and 1 or 0)

- (headings['st3t'] and 1 or 0)

- (headings['st4t'] and 1 or 0)

- (headings['st5t'] and 1 or 0)

- (has_seats2 and 1 or 0)

- (has_seats3 and 1 or 0)

- (has_sw2 and 1 or 0)

+ (has_votes and 0 or 2)

- (seats_only and 2 or 0)

local rsuff = (rounds > 1) and {, '_2'} or (rounds > 2) and {, '_3'} or {''}

for i, v in ipairs(index) do

local has_votesrow = args['votes' .. v] or args['ivotes' .. v] or args['avotes' .. v] or args['ipct' .. v] or args['apct' .. v] or args['atotal' .. v]

local has_seatsrow = args['seats' .. v] or args['iseats' .. v] or args['aseats' .. v]

local has_votesrow2 = args['votes' .. v .. '_2'] or args['ivotes' .. v .. '_2'] or args['avotes' .. v .. '_2'] or args['ipct' .. v .. '_2'] or args['apct' .. v .. '_2'] or args['atotal' .. v .. '_2']

local has_seatsrow2 = args['seats' .. v .. '_2'] or args['iseats' .. v .. '_2'] or args['aseats' .. v .. '_2']

local has_votesrow3 = args['votes' .. v .. '_3'] or args['ivotes' .. v .. '_3'] or args['avotes' .. v .. '_3'] or args['ipct' .. v .. '_3'] or args['apct' .. v .. '_3'] or args['atotal' .. v .. '_3']

local has_seatsrow3 = args['seats' .. v .. '_3'] or args['iseats' .. v .. '_3'] or args['aseats' .. v .. '_3']

row = root:tag('tr')

:addClass(args['class' .. v])

:css('font-weight', args['font-weight' .. v])

-- determine the colors

local color = get_color(args['colour' .. v] or args['color' .. v] or nil, args['party' .. v])

local acolor = get_color(args['acolour' .. v] or args['acolor' .. v] or nil, args['alliance' .. v])

local rcolor = get_color(args['rcolour' .. v] or args['rcolor' .. v] or nil)

-- headers

if args['header' .. v] then

row

:tag('th')

:wikitext(args['header' .. v])

:attr('colspan', cols)

else

if args['alliance' .. v] then

row

:tag('td')

:attr('rowspan', args['aspan' .. v])

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

:css('background-color', acolor)

elseif args['party' .. v] and not has_alliance or args['cand' .. v] and has_party and not has_alliance then

row

:tag('td')

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

:css('background-color', color)

end

if args['cand' .. v] and not args.dsv then

row

:css('background-color', rcolor)

:tag('td')

:attr('rowspan', args['candspan' .. v] or args['aspan' .. v])

:wikitext(args['cand' .. v])

end

if args['vp' .. v] then

row

:tag('td')

:attr('rowspan', args['candspan' .. v] or args['aspan' .. v])

:wikitext(args['vp' .. v])

end

if args['alliance' .. v] and not has_party and args.dsv then

row

:tag('td')

:attr('rowspan', args['aspan' .. v])

:wikitext(args['alliance' .. v])

end

if args['alliance' .. v] and not args['party' .. v] and not args.dsv then

row

:tag('td')

:attr('rowspan', args['aspan' .. v])

:attr('colspan', 3)

:wikitext(args['alliance' .. v])

end

if args['alliance' .. v] and not args['party' .. v] and has_party and args.dsv then

row

:tag('td')

:attr('rowspan', args['aspan' .. v])

:attr('colspan', 3)

:wikitext(args['alliance' .. v])

end

if args['alliance' .. v] and args['party' .. v] then

row

:tag('td')

:attr('rowspan', args['aspan' .. v])

:wikitext(args['alliance' .. v])

end

if args['party' .. v] and not has_alliance or args['cand' .. v] and has_party and not has_alliance then

row

:tag('td')

:wikitext(args['party' .. v])

end

if args['row' .. v] then

row

:css('background-color', rcolor)

:tag('td')

:attr('colspan', cs)

:wikitext(args['row' .. v])

end

if has_alliance and args['party' .. v] then

row

:tag('td')

:css('background-color', color)

:tag('td')

:wikitext(args['party' .. v])

end

if args['cand' .. v] and args.dsv then

row

:tag('td')

:attr('rowspan', args['candspan' .. v])

:wikitext(args['cand' .. v])

end

if args['atotal' .. v] and has_party and not args.dsv or args['atotalnv' .. v] and has_party and not args.dsv then

row

:css('font-style', 'italic')

:tag('td')

:attr('colspan', 2)

:wikitext('Total')

end

if args['atotal' .. v] and not has_party or args['atotalnv' .. v] and not has_party then

row

:css('font-style', 'italic')

:tag('td')

:wikitext('Total')

end

if args['atotal' .. v] and has_cand and has_party and args.dsv or args['atotalnv' .. v] and has_party and args.dsv then

row

:css('font-style', 'italic')

:tag('td')

:attr('colspan', 3)

:wikitext('Total')

end

if args['votes' .. v] and args['divisor'] then

row:tag('td')

:attr('rowspan', args['vspan' .. v])

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

:wikitext(fmt(args['votes' .. v]))

row:tag('td')

:attr('rowspan', args['vspan' .. v])

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

:wikitext(pct(args['votes' .. v], (args['row' .. v] == 'Total') and args['votes' .. v] or args['divisor']))

elseif args['votes' .. v] then

row:tag('td')

:attr('rowspan', args['vspan' .. v])

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

:wikitext(fmt(args['votes' .. v]))

row:tag('td')

:attr('rowspan', args['vspan' .. v])

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

:wikitext(pct(args['votes' .. v], valid[1]))

elseif args['avotes' .. v] then

row:tag('td')

:attr('rowspan', args['vspan' .. v])

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

:css('font-style', 'italic')

:wikitext(fmt(args['avotes' .. v]))

row:tag('td')

:attr('rowspan', args['vspan' .. v])

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

:css('font-style', 'italic')

:wikitext(pct(args['avotes' .. v], valid[1]))

elseif args['ivotes' .. v] or args ['ipct' .. v] or args['atotal' .. v] then

row:tag('td')

:attr('rowspan', args['vspan' .. v])

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

:css('font-style', 'italic')

:wikitext(fmt(args['ivotes' .. v]) or fmt(args['atotal' .. v]))

if args['ipct' .. v] or args['apct' .. v] or args['atotal' .. v] then

row:tag('td')

:attr('rowspan', args['vspan' .. v])

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

:css('font-style', 'italic')

:wikitext(args['ipct' .. v] or args['apct' .. v] or pct(args['atotal' .. v], valid[1]))

else

row:tag('td')

:attr('rowspan', args['vspan' .. v])

:wikitext()

end

elseif has_votes and headings['seats'] and headings['sw'] and not has_votesrow and not has_seatsrow and not args['sw' .. v] and not has_rspan then

row:tag('td')

:attr('colspan', 4)

elseif has_votes and headings['seats'] and not has_votesrow and not has_seatsrow and not has_rspan or has_votes and headings['sw'] and not has_votesrow and not args['sw' .. v] and not has_rspan or has_seats2 and not has_votesrow and not has_seatsrow and not has_rspan then

row:tag('td')

:attr('colspan', 3)

elseif has_votes and not has_votesrow and not has_rspan or has_votes and args['row' .. v] and has_seatsrow and not has_votesrow or has_seats2 and not has_votesrow and not has_rspan then

row:tag('td')

:attr('colspan', 2)

elseif args['r1blockc' .. v] then

row:tag('td')

:attr('rowspan', args['r1blockr' .. v])

:attr('colspan', args['r1blockc' .. v])

:wikitext()

end

if headings['sw'] and has_votesrow then

row

:tag('td')

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

:wikitext(args['sw' .. v])

end

if headings['seats'] and not args['dsv'] and not has_seats2 and rounds < 2 or has_seats2 and args['seats' .. v] or has_seats2 and args['votes' .. v] or has_seats2 and args['iseats' .. v] or has_seats2 and args['aseats' .. v] then

if args['iseats' .. v] or args['aseats' .. v] then

row

:tag('td')

:css('font-style', 'italic')

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

:wikitext(args['iseats' .. v] or args['aseats' .. v])

elseif args['seats' .. v] or headings['seats'] and not has_sspan then

row

:tag('td')

:attr('rowspan', args['sspan' .. v])

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

:wikitext(fmt(args['seats' .. v]) or '–')

end

end

if args['votes' .. v .. '_2'] and args['divisor2'] then

row:tag('td')

:attr('rowspan', args['v2span' .. v])

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

:wikitext(fmt(args['votes' .. v .. '_2']))

row:tag('td')

:attr('rowspan', args['v2span' .. v])

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

:wikitext(pct(args['votes' .. v .. '_2'], (args['row' .. v] == 'Total') and args['votes' .. v .. '_2'] or args['divisor2']))

elseif args['votes' .. v .. '_2'] then

row:tag('td')

:attr('rowspan', args['v2span' .. v])

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

:wikitext(fmt(args['votes' .. v .. '_2']))

row:tag('td')

:attr('rowspan', args['v2span' .. v])

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

:wikitext(pct(args['votes' .. v .. '_2'], valid[2]))

elseif args['ivotes' .. v .. '_2'] or args ['ipct' .. v.. '_2'] or args['avotes' .. v .. '_2'] then

row:tag('td')

:attr('rowspan', args['v2span' .. v])

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

:css('font-style', 'italic')

:wikitext(fmt(args['ivotes' .. v .. '_2']) or fmt(args['avotes' .. v .. '_2']))

row:tag('td')

:attr('rowspan', args['v2span' .. v])

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

:css('font-style', 'italic')

:wikitext(args['ipct' .. v .. '_2'] or args['apct' .. v .. '_2'] or pct(args['avotes' .. v .. '_2'], valid[2]))

elseif has_votes2 and has_seats2 and has_sw2 and not has_votesrow2 and not has_seatsrow2 and not args['sw' .. v .. '_2'] and not has_rspan then

row:tag('td')

:attr('colspan', 4)

elseif has_votes2 and has_seats2 and not has_votesrow2 and not has_seatsrow2 and not has_rspan or has_votes2 and has_sw2 and not has_votesrow2 and not args['sw' .. v .. '_2'] and not has_rspan or has_seats2 and not has_votesrow2 and not has_seatsrow2 and not has_rspan then

row:tag('td')

:attr('colspan', 3)

elseif has_votes2 and not has_votesrow2 and not has_rspan or has_votes2 and args['row' .. v] and has_seatsrow2 and not has_votesrow2 or has_seats2 and not has_votesrow2 and not has_rspan then

row:tag('td')

:attr('colspan', 2)

elseif args['r2blockc' .. v] then

row:tag('td')

:attr('rowspan', args['r2blockr' .. v])

:attr('colspan', args['r2blockc' .. v])

:wikitext()

end

if headings['seats'] and args['dsv'] and not has_sspan or headings['seats'] and rounds > 1 and not has_seats2 and not has_sspan or args['seats' .. v] and has_sspan and rounds > 1 and not has_seats2 then

row

:tag('td')

:attr('rowspan', args['sspan' .. v])

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

:wikitext(fmt(args['seats' .. v]) or fmt(args['aseats' .. v]) or '–')

end

if has_sw2 and args['votes' .. v .. '_2'] then

row

:tag('td')

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

:wikitext(args['sw' .. v .. '_2'])

end

if args['seats' .. v .. '_2'] or has_seats2 and args['votes' .. v .. '_2'] then

row

:tag('td')

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

:wikitext(fmt(args['seats' .. v .. '_2']) or '–')

end

if args['iseats' .. v .. '_2'] or has_seats2 and args['ivotes' .. v .. '_2'] and not args['seats' .. v .. '_2'] or args['aseats' .. v .. '_2'] then

row

:tag('td')

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

:wikitext(fmt(args['iseats' .. v .. '_2']) or fmt(args['aseats' .. v .. '_2']))

end

if has_seats3 or has_votes3 then

if args['votes' .. v .. '_3'] then

row:tag('td')

:attr('rowspan', args['v3span' .. v])

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

:wikitext(fmt(args['votes' .. v .. '_3']))

row:tag('td')

:attr('rowspan', args['v3span' .. v])

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

:wikitext(pct(args['votes' .. v .. '_3'], valid[3]))

elseif args['ivotes' .. v .. '_3'] or args ['ipct' .. v.. '_3'] or args['avotes' .. v .. '_3'] then

row:tag('td')

:attr('rowspan', args['v3span' .. v])

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

:css('font-style', 'italic')

:wikitext(fmt(args['ivotes' .. v .. '_3']) or fmt(args['avotes' .. v .. '_3']))

row:tag('td')

:attr('rowspan', args['v3span' .. v])

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

:css('font-style', 'italic')

:wikitext(args['ipct' .. v .. '_3'] or args['apct' .. v .. '_3'] or pct(args['avotes' .. v .. '_3'], valid[3]))

elseif has_seats3 and not has_votesrow3 and not has_seatsrow3 and not has_rspan then

row:tag('td')

:attr('colspan', 3)

elseif has_seats3 and not has_votesrow3 and not has_rspan or has_seats3 and args['row' .. v] and has_seatsrow3 and not has_votesrow3 or has_votes3 and not has_votesrow3 and not has_rspan then

row:tag('td')

:attr('colspan', 2)

elseif args['r3blockc' .. v] then

row:tag('td')

:attr('rowspan', args['r3blockr' .. v])

:attr('colspan', args['r3blockc' .. v])

:wikitext()

end

if has_sw2 and args['votes' .. v .. '_3'] then

row

:tag('td')

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

:wikitext(args['sw' .. v .. '_3'])

end

if args['seats' .. v .. '_3'] or has_seats3 and args['votes' .. v .. '_3'] then

row

:tag('td')

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

:wikitext(fmt(args['seats' .. v .. '_3']) or '–')

end

if args['iseats' .. v .. '_3'] or has_seats3 and args['ivotes' .. v .. '_3'] and not args['seats' .. v .. '_3'] or args['aseats' .. v .. '_3'] then

row

:tag('td')

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

:wikitext(fmt(args['iseats' .. v .. '_3']) or fmt(args['aseats' .. v .. '_3']))

end

end

if args['st1t' .. v] and has_sspan or headings['st1t'] and not has_sspan then

row

:tag('td')

:attr('rowspan', args['sspan' .. v])

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

:wikitext(args['st1t' .. v] or '–')

end

if args['st2t' .. v] and has_sspan or headings['st2t'] and not has_sspan then

row

:tag('td')

:attr('rowspan', args['sspan' .. v])

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

:wikitext(args['st2t' .. v] or '–')

end

if args['st3t' .. v] and has_sspan or headings['st3t'] and not has_sspan then

row

:tag('td')

:attr('rowspan', args['sspan' .. v])

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

:wikitext(args['st3t' .. v] or '–')

end

if args['st4t' .. v] and has_sspan or headings['st4t'] and not has_sspan then

row

:tag('td')

:attr('rowspan', args['sspan' .. v])

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

:wikitext(args['st4t' .. v] or '–')

end

if args['st5t' .. v] and has_sspan or headings['st5t'] and not has_sspan then

row

:tag('td')

:attr('rowspan', args['sspan' .. v])

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

:wikitext(args['st5t' .. v] or '–')

end

if args['totseats' .. v] and has_sspan or args['atotseats' .. v] and has_sspan then

row

:tag('td')

:attr('rowspan', args['tsspan' .. v])

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

:wikitext(args['totseats' .. v] or args['atotseats' .. v] or '–')

end

if headings['totseats'] and not args['itotseats' .. v] and not args['atotseats' .. v] and not has_sspan then

row

:tag('td')

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

:wikitext(fmt(args['totseats' .. v]) or '–')

elseif headings['totseats'] and not has_sspan then

row

:tag('td')

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

:css('font-style', 'italic')

:wikitext(args['itotseats' .. v] or args['atotseats' .. v])

end

if headings['sc'] and args.sctitle then

row

:tag('td')

:wikitext(args['sc' .. v])

elseif headings['sc'] then

row

:tag('td')

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

:wikitext(args['sc' .. v] or '–')

end

end

end

-- separating line

if args['valid'] or args['valid2'] or args['valid3'] or args['invalid'] or args['invalid2'] or args['invalid3'] or args['totalvotes'] or args['totalvotes2'] or args['totalvotes3'] or args['electorate'] or args['electorate2'] or args['electorate3'] or args['turnout'] or args['turnout2'] or args['turnout3'] or args['source'] then

row = root

:tag('tr')

:addClass('sortbottom')

row

:tag('td')

:css('color', 'var( --color-base, #202122 )')

:css('background', 'var( --background-color-neutral, #eaecf0 )')

:attr('colspan', cols)

end

-- valid votes

if args['invalid'] or args['invalid2'] or args['invalid3'] then

row = root

:tag('tr')

:addClass('sortbottom')

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

row

:tag('th')

:wikitext('Valid votes')

:attr('scope', 'row')

:attr('colspan', cs)

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

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

:css('color', 'inherit')

:css('background', 'inherit')

if args['invalid'] then

row

:tag('td')

:wikitext(fmt(ovalid[1]))

:tag('td')

:wikitext(pct(ovalid[1], ovalid[1] + invalid[1] + blank[1]))

elseif not args['invalid'] then

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if has_seats2 and not headings['sw'] then

row

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and args['validsw'] then

row

:tag('td')

:wikitext(args['validsw'])

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and not args['validsw'] then

row

:tag('td')

:attr('colspan', 2)

:wikitext()

end

if rounds > 1 and args['invalid2'] then

row

:tag('td')

:wikitext(fmt(ovalid[2]))

:tag('td')

:wikitext(pct(ovalid[2], ovalid[2] + invalid[2] + blank[2]))

elseif rounds > 1 and not args['invalid2'] then

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if has_seats2 and not headings['sw'] then

row

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and args['validsw2'] then

row

:tag('td')

:wikitext(args['validsw2'])

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and not args['validsw2'] then

row

:tag('td')

:attr('colspan', 2)

:wikitext()

end

if args['invalid3'] then

row

:tag('td')

:wikitext(fmt(ovalid[3]))

:tag('td')

:wikitext(pct(ovalid[3], ovalid[3] + invalid[3] + blank[3]))

elseif has_seats3 and not args['invalid3'] then

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if args['invalidsw'] and not has_sw2 then

row:tag('td')

:wikitext(args['validsw'])

local cspan = (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) + (has_seats3 and 1 or 0)

if headings['seats'] or headings['sc'] then

local cspan = (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) + (has_seats3 and 1 or 0)

row

:tag('td')

:attr('colspan', cspan > 1 and cspan or nil)

end

elseif headings['sw'] or headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then

local cspan = (headings['sw'] and 1 or 0) + (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) + (has_seats3 and 1 or 0)

row

:tag('td')

:attr('colspan', cspan > 1 and cspan or nil)

end

-- invalid votes

row = root:tag('tr')

:addClass('sortbottom')

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

if args['invalidonly'] or args['blank'] then

row

:tag('th')

:wikitext('Invalid votes')

:attr('scope', 'row')

:attr('colspan', cs)

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

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

:css('color', 'inherit')

:css('background', 'inherit')

else

row

:tag('th')

:wikitext('Invalid/blank votes')

:wikitext(args.invalidnote)

:attr('scope', 'row')

:attr('colspan', cs)

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

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

:css('color', 'inherit')

:css('background', 'inherit')

end

if args['invalid'] then

row

:tag('td')

:wikitext(fmt(invalid[1]))

:tag('td')

:wikitext(pct(invalid[1], ovalid[1] + invalid[1] + blank[1]))

elseif not args['invalid'] then

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if has_seats2 and not headings['sw'] then

row

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and args['invalidsw'] then

row

:tag('td')

:wikitext(args['invalidsw'])

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and not args['invalidsw'] then

row

:tag('td')

:attr('colspan', 2)

:wikitext()

end

if rounds > 1 and args['invalid2'] then

row

:tag('td')

:wikitext(fmt(invalid[2]))

:tag('td')

:wikitext(pct(invalid[2], ovalid[2] + invalid[2] + blank[2]))

elseif rounds > 1 and not args['invalid2'] then

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if has_seats2 and not headings['sw'] then

row

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and args['invalidsw2'] then

row

:tag('td')

:wikitext(args['invalidsw2'])

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and not args['invalidsw2'] then

row

:tag('td')

:attr('colspan', 2)

:wikitext()

end

if has_seats3 and args['invalid3'] or has_votes3 and args['invalid3'] then

row

:tag('td')

:wikitext(fmt(invalid[3]))

:tag('td')

:wikitext(pct(invalid[3], ovalid[3] + invalid[3] + blank[3]))

elseif has_seats3 and not args['invalid3'] then

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if args['invalidsw'] and not has_sw2 then

row:tag('td')

:wikitext(args['invalidsw'])

if headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then

local cspan = (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (has_seats3 and 1 or 0)

row

:tag('td')

:attr('colspan', cspan > 1 and cspan or nil)

end

elseif headings['sw'] or headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then

local cspan = (headings['sw'] and 1 or 0) + (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) + (has_seats3 and 1 or 0)

row

:tag('td')

:attr('colspan', cspan > 1 and cspan or nil)

end

end

-- blank votes

if args['blank'] or args['blank2'] or args['blank3'] then

row = root:tag('tr')

:addClass('sortbottom')

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

row

:tag('th')

:wikitext('Blank votes')

:attr('scope', 'row')

:attr('colspan', cs)

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

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

:css('color', 'inherit')

:css('background', 'inherit')

if args['blank'] then

row

:tag('td')

:wikitext(fmt(blank[1]))

:tag('td')

:wikitext(pct(blank[1], ovalid[1] + invalid[1] + blank[1]))

else

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if has_seats2 and not headings['sw'] then

row

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and args['blanksw'] then

row

:tag('td')

:wikitext(args['blanksw'])

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and not args['blanksw'] then

row

:tag('td')

:attr('colspan', 2)

:wikitext()

end

if rounds > 1 and args['blank2'] then

row

:tag('td')

:wikitext(fmt(blank[2]))

:tag('td')

:wikitext(pct(blank[2], ovalid[2] + invalid[2] + blank[2]))

elseif rounds > 1 and not args['blank2'] then

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if has_seats2 and not headings['sw'] then

row

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and args['blanksw2'] then

row

:tag('td')

:wikitext(args['blanksw2'])

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and not args['blanksw2'] then

row

:tag('td')

:attr('colspan', 2)

:wikitext()

end

if has_seats3 and args['blank3'] or has_votes3 and args['blank3'] then

row

:tag('td')

:wikitext(fmt(blank[3]))

:tag('td')

:wikitext(pct(blank[3], ovalid[3] + invalid[3] + blank[3]))

elseif has_seats3 and args['blank3'] or has_votes3 and args['blank3'] then

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if args['blanksw'] and not has_sw2 then

row:tag('td')

:wikitext(args['blanksw'])

if headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then

local cspan = (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (has_seats3 and 1 or 0)

row

:tag('td')

:attr('colspan', cspan > 1 and cspan or nil)

end

elseif headings['sw'] or headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then

local cspan = (headings['sw'] and 1 or 0) + (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) + (has_seats3 and 1 or 0)

row

:tag('td')

:attr('colspan', cspan > 1 and cspan or nil)

end

end

-- total

if args['invalid'] or args['totalvotes'] or args['invalid2'] or args['totalvotes2'] then

row = root:tag('tr')

:addClass('sortbottom')

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

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

row

:tag('th')

:wikitext(args.tvtitle or 'Total votes')

:attr('scope', 'row')

:attr('colspan', cs)

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

:css('background', 'inherit')

:css('color', 'inherit')

if not args['totalvotes'] and args['invalid'] then

row

:tag('td')

:wikitext(fmt(ovalid[1] + invalid[1] + blank[1]))

:tag('td')

:wikitext(pct(1, 1))

elseif args['totalvotes'] then

row

:tag('td')

:wikitext(fmt(args.totalvotes))

:tag('td')

:wikitext('–')

elseif not args['invalid'] and not args['totalvotes'] then

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if has_seats2 and not headings['sw'] then

row

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and args['invalidsw'] then

row

:tag('td')

:wikitext('–')

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and not args['invalidsw'] then

row

:tag('td')

:attr('colspan', 2)

:wikitext()

end

if rounds > 1 and args['invalid2'] and not args['totalvotes2'] then

row

:tag('td')

:wikitext(fmt(ovalid[2] + invalid[2] + blank[2]))

:tag('td')

:wikitext(pct(1, 1))

elseif rounds > 1 and args['totalvotes2'] then

row

:tag('td')

:wikitext(fmt(args.totalvotes2))

:tag('td')

:wikitext('–')

elseif rounds > 1 and not args['invalid2'] or rounds > 1 and not args['totalvotes2'] then

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if has_seats2 and not headings['sw'] then

row

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and args['invalidsw2'] then

row

:tag('td')

:wikitext('–')

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and not args['invalidsw2'] then

row

:tag('td')

:attr('colspan', 2)

:wikitext()

end

if has_seats3 and not args['totalvotes3'] and args['invalid3'] or has_votes3 and not args['totalvotes3'] and args['invalid3'] then

row

:tag('td')

:wikitext(fmt(ovalid[3] + invalid[3] + blank[3]))

:tag('td')

:wikitext(pct(1, 1))

elseif has_seats3 and args['totalvotes3'] or has_votes3 and args['totalvotes3'] then

row

:tag('td')

:wikitext(fmt(args.totalvotes3))

:tag('td')

:wikitext('–')

elseif has_seats3 and not args['invalid3'] or has_votes3 and not args['invalid3'] then

row

:tag('td')

:wikitext()

:tag('td')

:wikitext()

end

if args['invalidsw'] and not has_sw2 then

row:tag('td')

:wikitext('–')

if headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then

local cspan = (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) + (has_seats3 and 1 or 0)

row

:tag('td')

:attr('colspan', cspan > 1 and cspan or nil)

end

elseif headings['sw'] or headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then

local cspan = (headings['sw'] and 1 or 0) + (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) + (has_seats3 and 1 or 0)

row

:tag('td')

:attr('colspan', cspan > 1 and cspan or nil)

end

end

-- registered

if args['electorate'] or args['electorate2'] or args['turnout'] or args['turnout2'] then

row = root:tag('tr')

:addClass('sortbottom')

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

row

:tag('th')

:wikitext('Registered voters/turnout')

:attr('scope', 'row')

:attr('colspan', cs)

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

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

:css('color', 'inherit')

:css('background', 'inherit')

row

:tag('td')

:wikitext(fmt(electorate[1]))

if args['invalid'] and args['electorate'] and not args['totalvotes'] then

row

:tag('td')

:wikitext(args.turnout or pct(ovalid[1] + invalid[1] + blank[1], electorate[1]))

elseif args['totalvotes'] and args['electorate'] then

row

:tag('td')

:wikitext(args.turnout or pct(totalvotes[1], electorate[1]))

elseif args['electorate'] then

row

:tag('td')

:wikitext(args.turnout or '–')

else

row

:tag('td')

:wikitext(args.turnout)

end

if has_seats2 and not headings['sw'] then

row

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and args['turnoutsw'] then

row

:tag('td')

:wikitext(args['turnoutsw'])

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and not args['turnoutsw'] then

row

:tag('td')

:attr('colspan', 2)

:wikitext()

end

if rounds > 1 then

row

:tag('td')

:wikitext(fmt(electorate[2]))

if args['invalid2'] and args['electorate2'] then

row

:tag('td')

:wikitext(args.turnout2 or pct(ovalid[2] + invalid[2] + blank[2], electorate[2]))

elseif args['totalvotes2'] and args['electorate2'] then

row

:tag('td')

:wikitext(args.turnout2 or pct(totalvotes[2], electorate[2]))

elseif args['electorate2'] then

row

:tag('td')

:wikitext(args.turnout2 or '–')

else

row

:tag('td')

:wikitext(args.turnout2)

end

if has_seats2 and not headings['sw'] then

row

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and args['turnoutsw2'] then

row

:tag('td')

:wikitext(args['turnoutsw2'])

:tag('td')

:wikitext()

end

if has_seats2 and headings['sw'] and not args['turnoutsw2'] then

row

:tag('td')

:attr('colspan', 2)

:wikitext()

end

end

if has_seats3 or has_votes3 then

row

:tag('td')

:wikitext(fmt(electorate[3]))

if args['invalid3'] and args['electorate3'] then

row

:tag('td')

:wikitext(args.turnout3 or pct(ovalid[3] + invalid[3] + blank[3], electorate[3]))

elseif args['totalvotes3'] and args['electorate3'] then

row

:tag('td')

:wikitext(args.turnout3 or pct(totalvotes[3], electorate[3]))

elseif args['electorate3'] then

row

:tag('td')

:wikitext(args.turnout3 or '–')

else

row

:tag('td')

:wikitext(args.turnout3)

end

end

if args['turnoutsw'] and not has_sw2 then

row:tag('td')

:wikitext(args['turnoutsw'])

if headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then

local cspan = (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) + (has_seats3 and 1 or 0)

row

:tag('td')

:attr('colspan', cspan > 1 and cspan or nil)

end

elseif headings['sw'] or headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then

local cspan = (headings['sw'] and 1 or 0) + (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) + (has_seats3 and 1 or 0)

row

:tag('td')

:attr('colspan', cspan > 1 and cspan or nil)

end

end

if args['majority'] then

if args['invalid'] or args['electorate'] then

row = root

:tag('tr')

:addClass('sortbottom')

row

:tag('td')

:css('color', 'var( --color-base, #202122 )')

:css('background', 'var( --background-color-neutral, #eaecf0 )')

:attr('colspan', cols)

end

row = root

:tag('tr')

:addClass('sortbottom')

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

row

:tag('th')

:wikitext('Majority')

:attr('scope', 'row')

:attr('colspan', cs)

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

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

:css('color', 'inherit')

:css('background', 'inherit')

for k=1, rounds do

row

:tag('td')

:wikitext(fmt(majority[k]))

:tag('td')

:wikitext(fmt(majoritypct[k]))

end

if args['majoritysw'] then

row

:tag('td')

:wikitext(args['majoritysw'])

end

end

if args['result'] then

row = root:tag('tr')

:addClass('sortbottom')

-- determine the color

local color = get_color(args['resultcolour'] or nil, args['result'])

if args['resultsw'] then

row

:tag('td')

:css('background-color', color)

row

:tag('td')

:attr('colspan', 2)

:wikitext(args['result'])

row

:tag('td')

:attr('colspan', 2)

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

:wikitext('Swing')

row

:tag('td')

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

:wikitext(args['resultsw'])

else

row

:tag('td')

:css('background-color', color)

row

:tag('td')

:attr('colspan', cols - 1)

:wikitext(args['result'])

end

end

if args['majority2'] then

row = root

:tag('tr')

:addClass('sortbottom')

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

row

:tag('th')

:wikitext('Majority')

:attr('scope', 'row')

:attr('colspan', cs)

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

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

:css('color', 'inherit')

:css('background', 'inherit')

for k=1, rounds do

row

:tag('td')

:wikitext(fmt(majority2[k]))

:tag('td')

:wikitext(fmt(majoritypct2[k]))

end

if args['majoritysw2'] then

row

:tag('td')

:wikitext(args['majoritysw2'])

end

end

if args['result2'] then

row = root:tag('tr')

:addClass('sortbottom')

-- determine the color

local color = get_color(args['resultcolour'] or nil, args['result2'])

if args['resultsw2'] then

row

:tag('td')

:css('background-color', color)

row

:tag('td')

:attr('colspan', 2)

:wikitext(args['result2'])

row

:tag('td')

:attr('colspan', 2)

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

:wikitext('Swing')

row

:tag('td')

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

:wikitext(args['resultsw2'])

else

row

:tag('td')

:css('background-color', color)

row

:tag('td')

:attr('colspan', cols - 1)

:wikitext(args['result2'])

end

end

if args['source'] then

row = root:tag('tr')

:addClass('sortbottom')

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

row:tag('td')

:wikitext('Source: ', args.source)

:attr('colspan', cols)

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

end

if args['embedded'] then

root:wikitext(args['embedded'])

end

return tostring(root) .. tracking

end

return p