Module:Sandbox/Alexiscoutinho Explained

local p =

function p.test(frame) local lang = mw.getContentLanguage local frame = mw.getCurrentFrame

local frozenset, set = unpack(require('Module:Lua set')) local fs = frozenset local s = set s.add(true) s.add(false) s.add(fs)

--local conc = for k in pairs(t) do conc = conc .. k end

return tostring(fs) .. ' ' .. tostring(s)end

local getArgs = require('Module:Arguments').getArgslocal yesno = require('Module:Yesno')local BarBox

local language = 'en' -- local default language

local i18n = require("Module:Medical cases chart/i18n")[language]

local function is(v) return (v or ) ~= end

function p._barColors(n) local colors =

return colors[n]end

function p._legend0(args) return '

' .. '' .. '    ' .. '' .. ' ' .. (args[2] or ) .. ''end

function p._customBarStacked(args) local barargs = barargs[1] = args[1]

local function _numwidth(nw) if nw

'n' then return 0 elseif nw

't' then return 2.45 elseif nw

'm' then return 3.5 elseif nw

'w' then return 4.55 elseif nw

'x' then return 5.6 elseif nw

'd' then return 3.5 end

return 3.5 end

local width1 = 3.5 local width2 = 3.5 local width3, width4 if is(args.numwidth) then width1 = _numwidth(mw.ustring.sub(args.numwidth,1,1)) width2 = _numwidth(mw.ustring.sub(args.numwidth,2,2)) width3 = _numwidth(mw.ustring.sub(args.numwidth,3,3)) width4 = _numwidth(mw.ustring.sub(args.numwidth,4,4)) end

barargs[2] = '

' .. (args[7] or ) .. '' .. '' .. (args[8] or ) .. ''

if mw.ustring.len(args.numwidth)

4 then local padding = '0.3em' if mw.ustring.sub(args.numwidth,3,3)

'n' then padding = '0' end

barargs.note2 = '

' .. (args[9] or ) .. '' .. '' .. (args[10] or ) .. '' end

for i=1,5 do barargs[2*i + 1] = p._barColors(i) barargs[2*i + 2] = (tonumber(args[i+1]) or 0)/(tonumber(args.divisor) or 1) barargs['title' .. i] = args[i+1] end

barargs.align = 'cdcc' barargs.collapsed = args.collapsed barargs.id = args.id

return BarBox.stacked(barargs)end

function p._row(args) local barargs = local rowDate = args.prevDate or

if is(args[1]) then if pcall(function mw.getContentLanguage:formatDate(, args[1]) end) then barargs[1] = args[1] rowDate = args[1] else barargs[1] = '' .. i18n.invalidTime .. '' end else barargs[1] = '⋮' end barargs[1] = barargs[1] .. (args['note0'] or )

barargs[2] = args[2] or 0 barargs[3] = args[3] or 0

if is(args['alttot1']) then barargs[4] = args['alttot1'] elseif args[4] then barargs[4] = (tonumber(args[4]) or 0) - (tonumber(barargs[2]) or 0) - (tonumber(barargs[3]) or 0) else barargs[4] = 0 end

barargs[5] = args[5] or 0

if is(args['alttot2']) then barargs[6] = args['alttot2'] elseif args[6] then barargs[6] = (tonumber(args[6]) or 0) - (tonumber(barargs[2]) or 0) - (tonumber(barargs[3]) or 0) else barargs[6] = 0 end

barargs[7] = args[7] or

local function changeArg(firstright, valuecol, changecol) local change = if yesno(args['firstright' .. firstright])

true then change = '(' .. i18n.na .. ')' elseif yesno(args['firstright' .. firstright])

false or not is(args['firstright' .. firstright]) then if not is(args[1]) and is(args[valuecol]) then change = '(=)' else change = is(args[changecol]) and '(' .. args[changecol] .. ')' or end end change = change .. (args['note' .. firstright] or )

return change end

barargs[8] = changeArg(1,7,8) barargs[9] = args[9] or barargs[10] = changeArg(2,9,10)

barargs.divisor = args.divisor or 1 barargs.numwidth = args.numwidth

if yesno(args.collapsible)

true then local duration = tonumber(args.duration) or 15 if args.collapsed then barargs.collapsed = args.collapsed elseif args.rowsToEnd >= duration then barargs.collapsed = true else barargs.collapsed = false end

if args.id then barargs.id = args.id elseif args.nooverlap and args.rowsToEnd < duration then barargs.id = 'l' .. duration else barargs.id = mw.ustring.lower(mw.getLanguage('en'):formatDate('M', rowDate)) if args.rowsToEnd < duration then barargs.id = barargs.id .. '-l' .. duration end end else barargs.collapsed = false end

return p._customBarStacked(barargs)end

function p._buildBars(args) local lines = mw.text.split(args.data, '\n') local frame = mw.getCurrentFrame local lang = mw.getContentLanguage

local bars, rows, months, prevRow, maxparam =,,, , 1 for k, line in pairs(lines) do local barargs, i =, 1 for parameter in mw.text.gsplit(line, ';') do parameter = mw.text.trim(parameter) if string.find(parameter, '^%a') then parameter = mw.text.split(parameter, '=') if parameter[1]

'alttot1' or parameter[1]

'alttot2' then parameter[2] = tonumber(frame:callParserFunction('#expr', parameter[2])) if is(parameter[2]) then maxparam = math.max(maxparam, parameter[2]) end end barargs[parameter[1]] = parameter[2] else if is(parameter) then if i >= 2 and i <= 6 then parameter = tonumber(frame:callParserFunction('#expr', frame:callParserFunction('formatnum',parameter,'R'))) maxparam = math.max(maxparam, parameter or 1) end barargs[i] = parameter if i

7 or i

9 then parameter = tonumber(mw.ustring.match(frame:callParserFunction('formatnum',parameter,'R'), '^%d*')) maxparam = math.max(maxparam, parameter or 1) end end i = i + 1 end end

local function fillCols(col, change) local data = args['right' .. col .. 'data'] local changetype = args['changetype' .. col] local value, num, prevnum

if data

'alttot1' then num = tonumber(barargs.alttot1 or barargs[4]) prevnum = tonumber(prevRow.alttot1 or prevRow[4]) elseif data

'alttot2' then num = tonumber(barargs.alttot2 or barargs[6]) prevnum = tonumber(prevRow.alttot2 or prevRow[6]) elseif is(data) then num = tonumber(barargs[tonumber(data) + 1]) prevnum = tonumber(prevRow[tonumber(data) + 1]) end

if is(data) and num then -- nothing in column, source found, and data exists value = changetype

'o' and or lang:formatNum(num) -- set value to num if changetype isn't 'o' if not change and yesno(barargs['firstright' .. col] ~= true) then if prevnum and prevnum ~= 0 then -- data on previous row if num - prevnum ~= 0 then --data has changed since previous row change = num-prevnum if changetype

'a' then -- change type is "absolute" if change > 0 then change = '+' .. lang:formatNum(change) end else -- change type is "percent", "only percent" or undefined local percent = 100 * change / prevnum -- calculate percent local rounding = math.abs(percent) >= 10 and "%.0f" or math.abs(percent) >= 1 and "%.1f" or "%.2f" percent = tonumber(mw.ustring.format(rounding, percent)) -- round to two sigfigs if percent > 0 then change = '+' .. lang:formatNum(percent) .. '%' elseif percent < 0 then change = lang:formatNum(percent) .. '%' else change = i18n['='] end end else -- data has not changed since previous row change = i18n['='] end else -- no data on previous row barargs['firstright' .. col] = true -- set to (n.a.) end end end

return value, change end

if not is(barargs[7]) then barargs[7], barargs[8] = fillCols(1, barargs[8]) end if not is(barargs[9]) then barargs[9], barargs[10] = fillCols(2, barargs[10]) end if is(barargs[1]) then local e,f,g = pcall(function return mw.getLanguage('en'):formatDate('M',barargs[1]), mw.getLanguage('en'):formatDate('j',barargs[1]) end ) if e then months[#months+1] = end end barargs.prevDate = prevRow[1] rows[#rows + 1] = barargs prevRow = barargs end

for i=1,#rows do -- build rows rows[i].divisor = tonumber(args.divisor) and tonumber(args.divisor) or maxparam / (0.95 * args.barwidth) rows[i].numwidth = args.numwidth rows[i].collapsible = args.collapsible rows[i].rowsToEnd = #rows - i rows[i].duration = args.duration if #months>(args.duration or 0) then rows[i].nooverlap = args.nooverlap end bars[i] = p._row(rows[i]) end return table.concat(bars, '\n'), monthsend

function p._monthToggleButton(args) local month = mw.ustring.lower(mw.ustring.sub(args.month[1] or ,1,3)) local outString = local newline = (args.nonewline or false) and or '\n' if is(month) then local collapsed = (args.active

) and or ' mw-collapsed' local uncollapsed = (args.active

) and ' mw-collapsed' or if args.nooverlap then outString = '

%s\n' .. '%s' .. newline if mw.ustring.sub(month,1,1)

'l' and tonumber(mw.ustring.sub(month,2))

args.duration then --"Last ## days" local lastDays = mw.ustring.format(i18n.lastDays, args.duration) outString = mw.ustring.format(outString, collapsed, lastDays, uncollapsed, lastDays) else if i18n.m[month] then if is(args.month[2]) and is(args.month[3]) then if (args.month[2] ~= args.month[3]) then -- "Mmm ##–##" month = mw.ustring.gsub(i18n.toggleRange,'$.',) else -- "Mmm ##"" month = mw.ustring.gsub(i18n.toggleSingleDate,'$.',) end else --"Mmm" month = i18n.m[month] end end outString = mw.ustring.format(outString, uncollapsed, month, collapsed, month) end elseif mw.ustring.sub(month,1,1)

'l' and tonumber(mw.ustring.sub(month,2))

args.duration then local customtoggles = for k in pairs(i18n.m) do --list of months customtoggles[#customtoggles + 1] = ' mw-customtoggle-' .. k .. '-l' .. args.duration end local lastDays = mw.ustring.format(i18n.lastDays, args.duration) outString = '

' .. lastDays .. '\n' .. '' .. lastDays .. '' .. newline else local customtoggles = ' mw-customtoggle-' .. month .. ' mw-customtoggle-' .. month .. '-l' .. args.duration outString = '' .. (i18n.m[month] or month) .. '\n' .. '' .. (i18n.m[month] or month) .. '' .. newline end end return outStringend

function p._chart(args) local navbar = require('Module:Navbar')._navbar

local barargs =

local function _numwidth(p) local nw = mw.ustring.sub(args.numwidth or ,p,p) if nw

'n' then return 0 elseif nw

't' then return 40 elseif nw

'm' then return 55 elseif nw

'w' then return 70 elseif nw

'x' then return 85 elseif nw

'd' then return 55 end

return 0 end

local numwidth = 120 local right1 = numwidth - 8 -- -8 because of padding if args.numwidth then numwidth = _numwidth(1) + 10 + _numwidth(2) if mw.ustring.len(args.numwidth)

4 then numwidth = numwidth + _numwidth(3) + _numwidth(4) if mw.ustring.sub(args.numwidth,3,3)

'n' then numwidth = numwidth + 6 else numwidth = numwidth + 10 end end

right1 = _numwidth(1) + 2 + _numwidth(2) if not args.right2 and mw.ustring.len(args.numwidth)

4 then right1 = right1 + _numwidth(3) + _numwidth(4) if mw.ustring.sub(args.numwidth,3,3)

'n' then numwidth = numwidth + 6 else numwidth = numwidth + 10 end end end

local barwidth = 280

if args.barwidth

'thin' then barwidth = 120 elseif args.barwidth

'medium' then barwidth = 280 elseif args.barwidth

'wide' then barwidth = 400 elseif args.barwidth

'auto' then barwidth = 'auto' end

if tonumber(barwidth) then barargs.width = 85 + barwidth + numwidth .. 'px' barargs.barwidth = barwidth .. 'px' else barargs.width = 'auto' barargs.barwidth = 'auto' end barargs.lineheight = args.rowheight

barargs.float = args.float and args.float or 'right' local location = mw.ustring.gsub(args.location, 'the ', ) location = mw.ustring.upper(mw.ustring.sub(location,1,1)) .. mw.ustring.sub(location,2)

local navbartitle = args.outbreak .. ' data/' .. (args.location3 and args.location3 .. '/' or ) .. (args.location2 and args.location2 .. '/' or ) .. location .. ' medical cases chart' -- get duration for toggles local duration = 15 -- default if manual togglesbar is last 15 days if yesno(args.collapsible)

true and (not is(args.togglesbar)) then duration = tonumber(args.duration) or 15 -- default if auto togglesbar is last 15 days end local months, togglesbar, lastdate =, , nil if args.rows then barargs.bars = args.rows if yesno(args.collapsible)

true then togglesbar = is(args.togglesbar) and args.togglesbar or end elseif is(args.data) or is(args.datapage) then local buildargs = local nooverlap = yesno(args.nooverlap) buildargs.barwidth = tonumber(barwidth) or 280 buildargs.data = is(args.datapage) and require('Module:Medical cases chart/data')._externalData(args) or args.data buildargs.divisor = args.divisor buildargs.numwidth = args.numwidth buildargs.collapsible = args.collapsible buildargs.right1data = args.right1data or -- if no right1data and right1 title is default, use 3rd classification not args.right1 and 3 buildargs.right2data = args.right2data or -- if no right2data and right2 title is deaths, use 1st classification (args.right2

i18n.noOfDeaths or args.right2

i18n.noOfDeaths2) and 1 buildargs.changetype1 = mw.ustring.sub(args.changetype1 or (args.changetype or ),1,1) -- 1st letter buildargs.changetype2 = mw.ustring.sub(args.changetype2 or (args.changetype or ),1,1) -- 1st letter buildargs.duration = duration if is(args.togglesbar) then buildargs.nooverlap = false else buildargs.nooverlap = nooverlap end local monthList barargs.bars, monthList = p._buildBars(buildargs) local lastRow = #monthList if nooverlap

true then if #monthList <= duration then nooverlap = false else lastRow = #monthList - duration end end

for i=1,(lastRow) do -- deduplicate months if monthList[i][1] ~= months[#months][1] then --new month if #months > 1 and i > 1 then months[#months][3] = monthList[i-1][2] --store end of previous month end months[#months+1] = monthList[i] --store start of this month end end months[#months][3] = monthList[lastRow][2] --store end of final month -- automatically generate toggles if yesno(args.collapsible)

true then if is(args.togglesbar) then togglesbar = args.togglesbar else local toggles = for i=1,#months do toggles[#toggles+1] = p._monthToggleButton end toggles[#toggles+1] = p._monthToggleButton togglesbar = '

\n' .. table.concat(toggles) .. '

' end end end local title = title[1] = (args.pretitle and args.pretitle .. ' ' or ) .. args.disease .. ' ' .. i18n.casesIn .. ' ' .. args.location .. (args.location2 and ', ' .. args.location2 or ) .. (args.location3 and ', ' .. args.location3 or ) .. (args.posttitle and ' ' .. args.posttitle or ) .. '

  (' .. navbar .. ')
' title[2] = p._legend0 if yesno(args.recoveries)

false then title[3] = else title[3] = '

   ' .. p._legend0 end title[4] = '   ' .. p._legend0 if args.altlbl2 then title[5] = '   ' .. p._legend0 else title[5] = end if args.altlbl3 then title[6] = '   ' .. p._legend0 ..'\n' else title[6] = '\n' end title[7] = togglesbar

barargs.title = table.concat(title) barargs.left1 = '

' .. -- 85-8 because of padding "" .. i18n.date .. "" .. '

'

barargs.right1 = '

' .. "" .. (args.right1 or i18n.noOfCases) .. "" .. '

'

if args.right2 then local right2 = _numwidth(3) + _numwidth(4) if mw.ustring.sub(args.numwidth,3,3)

'n' then right2 = right2 - 2 else right2 = right2 + 2 end

barargs.right2 = '

' .. "" .. args.right2 .. "" .. '

' end

barargs.footer = args.caption barargs.css = 'Module:Medical_cases_chart/styles.css' local box = BarBox.create(barargs) return tostring(box)end

function p.chart(frame) BarBox = unpack(require('Module:Bar box')) local args = getArgs(frame,) return p._chart(args)end

function p.barColors(frame) return p._barColors(tonumber(frame:getParent.args[1]))end

function p.buildBars(frame) local bars = p._buildBars(frame.args) return barsend

function p.monthToggleButton(frame) local args = args.month = args.active = frame:getParent.args.active or 'true' args.duration = frame:getParent.args.duration or 15 args.nonewline = true return p._monthToggleButton(args)end

return p