# Module:COVID-19 data

local p = {}  

local data_title = mw.title.new(  
'Template:COVID-19 data/data'  
local data_content = data_title:getContent  
local data = mw.text.jsonDecode(data_content)  

local function format_num(number)  
if not number then  
return ''  
end  
local _, _, minus, int, _ = tostring(number):find('([-]?)(%d+)([.]?%d*)')  
int = int:reverse:gsub("(%d%d%d)", "%1,")  
int = int:reverse:gsub("^,", "")  
int = minus .. int  
return int  
end  

function p.main  
local out = ''  
local data_s = {}  
local has_notelist = false  
local count_row = 0  
local count_col = 0  
-- Build new table  
local locations = {}  
if mw.getCurrentFrame.args['locations'] then  
for location in string.gmatch(  
mw.getCurrentFrame.args['locations'],  
'([^,]+)'  
) do  
locations[location] = true  
end  
else  
locations = nil  
end  
for key, value in pairs(data) do  
local index  
if mw.getCurrentFrame.args['sort'] then  
if value[mw.getCurrentFrame.args['sort']] then  
index = value[mw.getCurrentFrame.args['sort']]  
else  
index = 0  
end  
else  
if value.cases then  
index = value.cases  
elseif value.deaths then  
index = value.deaths  
elseif value.vaccine_doses then  
index = value.vaccine_doses  
elseif value.total_vaccinated then  
index = value.total_vaccinated  
elseif value.fully_vaccinated then  
index = value.fully_vaccinated  
else index = 0  
end  
end  
if (not locations) or locations[key] then  
data_s[#data_s+1] = value  
data_s[#data_s]['_index'] = index  
data_s[#data_s]['_code'] = key  
end  
end  
-- Sort the new table  
table.sort(  
data_s,  
function(x, y)  
if x._code == 'XW' then  
return true  
elseif y._code == 'XW' then  
return false  
else  
return (x._index > y._index)  
end  
end  
-- Get columns  
local columns = {  
cases = false,  
deaths = false,  
total_vaccinated = false,  
vaccine_doses = false,  
fully_vaccinated = false,  
percent_vaccinated = false,  
percent_fully_vaccinated = false,  
deaths_per_million = false,  
population = false  
}  
local columns_index = {}  
if mw.getCurrentFrame.args['columns'] then  
for column in string.gmatch(  
mw.getCurrentFrame.args['columns'],  
'([^,]+)'  
) do  
columns[column] = true  
columns_index[#columns_index+1] = column  
end  
else  
columns = {  
cases = true,  
deaths = true,  
total_vaccinated = true,  
vaccine_doses = true,  
fully_vaccinated = true,  
percent_vaccinated = false,  
percent_fully_vaccinated = false,  
deaths_per_million = false,  
population = false  
}  
columns_index = {  
'cases',  
'deaths',  
'total_vaccinated',  
'vaccine_doses',  
'fully_vaccinated',  
'percent_vaccinated',  
'percent_fully_vaccinated',  
'deaths_per_million',  
'population'  
}  
end  
-- Check if should show note_vaccination  
local show_note_vaccination = false  
if columns['total_vaccinated'] or columns['vaccine_doses'] or columns['fully_vaccinated'] or columns['percent_vaccinated'] or columns['percent_fully_vaccinated'] then  
show_note_vaccination = true  
end  
-- Generate wikitext content  
for _, row in ipairs(data_s) do  
-- Test for empty rows  
local has_data = false  
for _, column in pairs(columns_index) do  
if columns[column] and row[column] then  
has_data = true  
end  
end  
if has_data then -- Only add row if it has data  
count_row = count_row + 1  
out = out .. '\n|-'  
if row._code == 'XW' then  
out = out .. ''  
end  
-- Add the flag  
if not mw.getCurrentFrame.args['noflag'] then  
if count_row == 1 then  
count_col = count_col + 1  
end  
out = out .. '\n| data-sort-value="' .. row.name .. '" | '  
if row._code == 'XW' then  
out = out ..  
''  
else  
flag_params = {row.name}  
-- So that it's not too large  
if row.name == 'New Caledonia' then  
flag_params[2] = 'merged'  
end  
out = out ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Flagicon',  
args = flag_params  
}  
end  
end  
-- Add country name  
if count_row == 1 then  
count_col = count_col + 1  
end  
if mw.getCurrentFrame.args['noflag'] then  
out = out .. '\n! scope="row" data-sort-value="' .. row.name .. '" | '  
else  
out = out .. '\n! scope="row" |'  
end  
if row._code == 'XW' then  
out = out .. * .. row.name .. *  
elseif row._code == 'GE' then  
out = out ..  
* .. row.name .. *  
elseif row._code == 'IM' then  
out = out ..  
* .. row.name .. *  
else  
out = out ..  
* .. row.name .. *  
end  
-- Add notes  
if row.note then  
has_notelist = true  
out = out ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Efn',  
args = {row.note}  
}  
end  
if row.note_vaccination and show_note_vaccination then  
has_notelist = true  
out = out ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Efn',  
args = {'Vaccination note: ' .. row.note_vaccination}  
}  
end  
-- Fill out columns  
for _, column in ipairs(columns_index) do  
if columns[column] then  
if count_row == 1 then  
count_col = count_col + 1  
end  
if row[column] then  
out = out .. '\n| data-sort-value=' ..  
tostring(row[column]) ..  
'|'  
if column:find('^percent') then  
out = out .. string.format('%.2f', row[column]) .. '%'  
else  
out = out .. format_num(row[column])  
end  
else  
out = out .. '\n| data-sort-value=0 | —'  
end  
end  
end  
end  
end  
if has_notelist then  
out = out .. '\n|-' ..  
'\n| |' ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Notelist'  
}  
end  
return out  
end  

function p.vac  
local out = ''  
local data_s = {}  
local has_country_num_doses = false  
local has_country_num_fully = false  
local count_row = 0  
local count_col = 0  
-- Build new table  
for key, value in pairs(data) do  
if value.total_vaccinated then  
data_s[#data_s+1] = value  
data_s[#data_s]['index'] = value.total_vaccinated  
elseif value.vaccine_doses then  
data_s[#data_s+1] = value  
data_s[#data_s]['index'] = value.vaccine_doses  
elseif value.fully_vaccinated then  
data_s[#data_s+1] = value  
data_s[#data_s]['index'] = value.fully_vaccinated  
end  
end  
-- Sort the new table  
table.sort(  
data_s,  
function(x, y)  
return (x.index > y.index)  
end  
-- Generate wikitext content  
for _, row in pairs(data_s) do  
count_row = count_row + 1  
out = out .. '\n|-'  
-- Add the flag  
if count_row == 1 then  
count_col = count_col + 2  
end  
if row.name == 'World' then  
out = out ..  
'' ..  
'\n| data-sort-value="' .. row.name .. '" | ' ..  
'' ..  
'\n! scope="row" data-sort-value="' .. row.name .. '" | ' ..  
'World'  
else  
flag_params = {row.name}  
-- So that it's not too large  
if row.name == 'New Caledonia' then  
flag_params[2] = 'merged'  
end  
out = out ..  
'\n| data-sort-value="' .. row.name .. '" | ' ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Flagicon',  
args = flag_params  
} ..  
'\n! scope="row" data-sort-value="' .. row.name .. '" | ' ..  
* .. row.name .. *  
end  
-- Add note  
if row.note_vaccination then  
out = out ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Efn',  
args = {row.note_vaccination}  
}  
end  
-- Add the number  
if count_row == 1 then  
count_col = count_col + 1  
end  
if row.total_vaccinated then  
out = out .. '\n| data-sort-value=' ..  
tostring(row.total_vaccinated) ..  
'|' .. format_num(row.total_vaccinated)  
elseif row.vaccine_doses then  
has_country_num_doses = true  
out = out .. '\n| data-sort-value=' ..  
tostring(row.vaccine_doses) ..  
'|' ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Font color',  
args = {'darkred', format_num(row.vaccine_doses)}  
} ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Efn',  
args = {name = 'country_num_doses'}  
}  
elseif row.fully_vaccinated then  
has_country_num_fully = true  
out = out .. '\n| data-sort-value=' ..  
tostring(row.fully_vaccinated) ..  
'|' ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Font color',  
args = {'darkorange', format_num(row.fully_vaccinated)}  
} ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Efn',  
args = {name = 'country_num_fully'}  
}  
end  
-- Add the percentage  
if count_row == 1 then  
count_col = count_col + 1  
end  
if row.percent_vaccinated then  
out = out .. '\n| data-sort-value=' ..  
tostring(row.percent_vaccinated) ..  
'|' .. string.format("%.1f", row.percent_vaccinated) .. '%'  
else  
out = out .. '\n| data-sort-value=0 | —'  
end  
end  
if has_country_num_doses or has_country_num_fully then  
notelist_refs = ''  
if has_country_num_doses then  
notelist_refs = notelist_refs ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Efn',  
args = {  
name = 'country_num_doses',  
'This country\'s data are the ' ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Font color',  
args = {  
'darkred',  
'number of vaccine doses administered'  
}  
} ..  
', not the first dose only.'  
}  
}  
end  
if has_country_num_fully then  
notelist_refs = notelist_refs ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Efn',  
args = {  
name = 'country_num_fully',  
'This country\'s data are the ' ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Font color',  
args = {  
'darkorange',  
'number of people fully vaccinated'  
}  
} ..  
', not the number of people ' ..  
'who have received at least one dose.'  
}  
}  
end  
out = out .. '\n|-' ..  
'\n| |' ..  
mw.getCurrentFrame:expandTemplate{  
title = 'Notelist',  
args = {refs = notelist_refs}  
}  
end  
return out  
end  

function p.text  
local location = mw.getCurrentFrame.args['location']  
local column = mw.getCurrentFrame.args['column']  
return data[location][column]  
end  

return p