local colorRatiocategoryData = require("Module:ColorStorm contrastcategories/categories")._ratio
local TableToolscolors = require("Module:TableToolsStorm categories/colors").colors
local icons = require("Module:Storm categories/icons").icons
local cats = categoryData.cats
local defaultCategory = categoryData.defaultCategory
local p = {}
-- Define categories
-- All sortkeys have been guessed. They may be changed by common sense
-- or consensus at [[Wikipedia talk:WikiProject Tropical cyclones]]
local cats = {
severe = {
color = "ccffff",
name = "Severe tropical storm",
sortkey = 120
},
mtstorm = {
color = "00faf4", -- Old {{storm colour}} did not support. Value guessed.
name = "Moderate tropical storm",
sortkey = 105
},
storm = {
color = "00faf4",
name = "Tropical storm",
sortkey = 100
},
severedep = {
color = "5ebaff", -- Old {{storm colour}} did not support. Value guessed.
name = "Severe tropical depression",
sortkey = 120
},
moddepression = {
color = "5ebaff", -- Old {{storm colour}} did not support. Value guessed.
name = "Moderate tropical depression",
sortkey = 95
},
depression = {
color = "5ebaff",
name = "Tropical depression",
sortkey = 90
},
disturbance = {
color = "80ccff",
name = "Tropical disturbance",
sortkey = 80
},
subtropicalcyclone = {
color = "00faf4",
name = "Subtropical cyclone",
sortkey = 70
},
subtropical = {
color = "00faf4",
name = "Subtropical storm",
sortkey = 65
},
subdepression = {
color = "5ebaff",
name = "Subtropical depression",
sortkey = 60
},
subdisturbance = {
color = "80ccff",
name = "Subtropical disturbance",
sortkey = 55
},
extratropical = {
color = "cccccc",
name = "Extratropical cyclone",
sortkey = 50
},
monsoondepression = {
color = "5ebaff",
name = "Monsoon depression",
sortkey = 30
},
potential = {
color = "80ccff",
name = "Potential tropical cyclone",
sortkey = 25
},
posttropical = {
color = "cccccc",
name = "Post-tropical depression",
sortkey = 70
},
remnant = {
color = "cccccc",
name = "Post-tropical depression",
sortkey = 70
},
unknown = {
color = "c0c0c0",
name = "Unknown strength tropical cyclone",
sortkey = 0
},
cat5 = {
color = "ff6060",
name = {
atl = "Category 5 hurricane",
epac = "Category 5 hurricane",
satl = "Category 5 hurricane",
wpac = "Category 5-equivalent super typhoon",
default = "Category 5-equivalent tropical cyclone"
},
sortkey = 80020
},
cat4 = {
color = "ff8f20",
name = {
atl = "Category 4 hurricane",
epac = "Category 4 hurricane",
satl = "Category 4 hurricane",
wpac = "Category 4-equivalent typhoon",
default = "Category 4-equivalent tropical cyclone"
},
sortkey = 80008
},
cat3 = {
color = "ffc140",
name = {
atl = "Category 3 hurricane",
epac = "Category 3 hurricane",
satl = "Category 3 hurricane",
wpac = "Category 3-equivalent typhoon",
default = "Category 3-equivalent tropical cyclone"
},
sortkey = 80006
},
cat2 = {
color = "ffe775",
name = {
atl = "Category 2 hurricane",
epac = "Category 2 hurricane",
satl = "Category 2 hurricane",
wpac = "Category 2-equivalent typhoon",
default = "Category 2-equivalent tropical cyclone"
},
sortkey = 80004
},
cat1 = {
color = "ffffcc",
name = {
atl = "Category 1 hurricane",
epac = "Category 1 hurricane",
satl = "Category 1 hurricane",
wpac = "Category 1-equivalent typhoon",
default = "Category 1-equivalent tropical cyclone"
},
sortkey = 80002
},
supertyphoon = {
color = "ff6060",
name = "Category 4 super typhoon",
sortkey = 80015
},
typhoon = {
color = "fdaf9a",
name = "Typhoon",
sortkey = 60010
},
vstyphoon = {
color = "fe887d",
name = "Very strong typhoon",
sortkey = 60020
},
vityphoon = {
color = "ff6060",
name = "Violent typhoon",
sortkey = 60030
},
-- PAGASA
styphoon = {
color = "ff6060",
name = "Supertyphoon",
sortkey = 60050
},
sprcyclstorm = {
color = "ff6060",
name = "Super cyclonic storm",
sortkey = 50020
},
esvrcyclstorm = {
color = "ffc140",
name = "Extremely severe cyclonic storm",
sortkey = 50015
},
vsvrcyclstorm = {
color = "ffffcc",
name = "Very severe cyclonic storm",
sortkey = 50010
},
svrcyclstorm = {
color = "ccffff",
name = "Severe cyclonic storm",
sortkey = 50008
},
niocyclone = {
color = "00faf4",
name = "Cyclonic storm",
sortkey = 50006
},
deepdepression = {
color = "5ebaff",
name = "Deep depression",
sortkey = 50002
},
niodepression = {
color = "80ccff",
name = "Depression",
sortkey = 50001
},
nioland = {
color = "80ccff",
name = "Land depression",
sortkey = 50000
},
aus5 = {
color = "ff6060",
name = "Category 5 severe tropical cyclone",
sortkey = 40015
},
aus4 = {
color = "ffc140",
name = "Category 4 severe tropical cyclone",
sortkey = 40013
},
aus3 = {
color = "ffffcc",
name = "Category 3 severe tropical cyclone",
sortkey = 40010
},
aus2 = {
color = "ccffff",
name = "Category 2 tropical cyclone",
sortkey = 40008
},
aus1 = {
color = "00faf4",
name = "Category 1 tropical cyclone",
sortkey = 40006
},
low = {
color = "5ebaff",
name = "Tropical low",
sortkey = 40002
},
sublow = {
color = "5ebaff",
name = "Subtropical low",
sortkey = 40000
},
vintense = {
color = "ff6060",
name = "Very intense tropical cyclone",
sortkey = 30010
},
intense = {
color = "ffc140",
name = "Intense tropical cyclone",
sortkey = 30008
},
tropicalcyclone = {
color = "ffffcc",
name = "Tropical cyclone",
sortkey = 30006
},
mstorm = {
color = "00faf4",
name = "Moderate tropical storm",
sortkey = 30004
},
zodw = {
color = "80ccff",
name = "Zone of disturbed weather",
sortkey = 30000
},
shemsvrtc = {
color = "ffe775",
name = "Severe tropical cyclone",
sortkey = 20020
},
shem5 = {
color = "ff6060",
name = "Severe tropical cyclone",
sortkey = 20010
},
shem4 = {
color = "ffc140",
name = "Tropical cyclone",
sortkey = 20008
},
shem2 = {
color = "ccffff",
name = "Tropical cyclone",
sortkey = 20008
},
shem1 = {
color = "00faf4",
name = "Tropical cyclone",
sortkey = 20008
}
}
-- Default
local defaultCategory = "unknown"
-- Define aliases
-- All non-alphanumeric characters are already stripped, and the string is
-- already set to lowercase, so additional aliases for those are no longer
-- required.
cats["sty"] = cats["supertyphoon"]
cats["nwpsevere"] = cats["severe"]
cats["strong"] = cats["severe"]
cats["swiosts"] = cats["severe"]
cats["sts"] = cats["severe"]
cats["severets"] = cats["severe"]
cats["ty"] = cats["typhoon"]
cats["td"] = cats["depression"]
cats["ts"] = cats["storm"]
cats["nwpstorm"] = cats["storm"]
cats["d"] = cats["depression"]
cats["spdepression"] = cats["depression"]
cats["shdepression"] = cats["depression"]
cats["shemdepression"] = cats["depression"]
cats["swiodepression"] = cats["depression"]
cats["spdepression"] = cats["depression"]
cats["nwpdepression"] = cats["depression"]
cats["swsubdep"] = cats["subdepression"]
cats["sd"] = cats["subdepression"]
cats["ss"] = cats["subtropical"]
cats["et"] = cats["extratropical"]
cats["md"] = cats["monsoondepression"]
cats["pt"] = cats["potential"]
cats["potentialtropicalcyclone"] = cats["potential"]
cats["potentialtropicalcyclone"] = cats["potential"]
cats["post"] = cats["remnant"]
cats["remnantlow"] = cats["remnant"]
cats["rl"] = cats["remnant"]
cats["sucs"] = cats["sprcyclstorm"]
cats["escs"] = cats["esvrcyclstorm"]
cats["vscs"] = cats["vsvrcyclstorm"]
cats["scs"] = cats["svrcyclstorm"]
cats["cs"] = cats["niocyclone"]
cats["dd"] = cats["deepdepression"]
cats["cyclstorm"] = cats["niocyclone"]
cats["landdepression"] = cats["nioland"]
cats["land"] = cats["nioland"]
cats["ld"] = cats["nioland"]
cats["fiji5"] = cats["aus5"]
cats["fiji4"] = cats["aus4"]
cats["fiji3"] = cats["aus3"]
cats["fiji2"] = cats["aus2"]
cats["fiji1"] = cats["aus1"]
cats["tl"] = cats["low"]
cats["di"] = cats["disturbance"]
cats["swiodisturbance"] = cats["disturbance"]
cats["mts"] = cats["mstorm"]
cats["sub"] = cats["mstorm"]
cats["vitc"] = cats["vintense"]
cats["itc"] = cats["intense"]
cats["tc"] = cats["tropicalcyclone"]
cats["swiotc"] = cats["tropicalcyclone"]
cats["shem3"] = cats["tropicalcyclone"]
cats["shemtc"] = cats["tropicalcyclone"]
-- Ambiguous color names. This is because the old {[storm colour}} itself is
-- extremely ambiguous. This is also used to override the output of some codes.
local colors = {
-- Basin colors
["5"] = cats["cat5"].color,
["4"] = cats["cat4"].color,
["3"] = cats["cat3"].color,
["2"] = cats["cat2"].color,
["1"] = cats["cat1"].color,
-- Enhanced Fujita scale
["ef5"] = cats["cat5"].color,
["ef4"] = cats["cat4"].color,
["ef3"] = cats["cat3"].color,
["ef2"] = cats["cat2"].color,
["ef1"] = cats["cat1"].color,
["ef0"] = cats["ts"].color,
-- Depression
["d"] = "80ccff",
-- FMS scale
["a5"] = cats["aus5"].color,
["a4"] = cats["aus4"].color,
["a3"] = cats["aus3"].color,
["a2"] = cats["aus2"].color,
["a1"] = cats["aus1"].color
}
function p.color(frame)
return p._color(frame.args[1] or frame:getParent().args[1], false)
end
return p._name(
frame.args[1] or frame:getParent().args[1],
frame.args[2] or frame:getParent().args[2],
false
)
end
function p.sortkey(frame)
return p._sortkey(frame.args[1] or frame:getParent().args[1], false)
end
function p._coloricon(colorCodeframe)
return p._icon(frame.args[1] or frame:getParent().args[1], false)
end
function p.isEqual(frame)
return p._isEqual(
frame.args[1] or frame:getParent().args[1],
frame.args[2] or frame:getParent().args[2]
) and "yes" or ""
end
function p._normalizeId(category, fallback)
-- Normalize if normalizable, fall back to default if not.
return (category ~= nil and string.len(category) ~= 0) and
string.gsub(string.lower(category), "[^%w]", "") or fallback
end
function p._color(category, nilIfMissing)
-- This looks confusing, but it's actually nested ternaries (for nil checks)
local color = (colorCode ~= nil and stringp.len_normalizeId(colorCode)category, ~= 0defaultCategory) and
string.gsub(string.lower(colorCode), "[^%w]", "")
or defaultCategory
return colors[color] or ((cats[color] or ( nilIfMissing and { color = nil } or cats[defaultCategory] )).color)
end
function p._name(category, basin, nilIfMissing)
local name_def = (cats[
p._normalizeId(category, defaultCategory)
(category ~= nil and string.len(category) ~= 0) and
] or (nilIfMissing and { name = nil } or cats[defaultCategory])).name
string.gsub(string.lower(category), "[^%w]", "")
or defaultCategory
] or cats[defaultCategory]).name
return type(name_def) == "table" and
(
name_def[string.lower(basin or "default")]
or name_def["default"]
or (not nilIfMissing and error("No default name for basin-based category name.") or nil)
)
or name_def
end
function p._sortkey(category, nilIfMissing)
-- This looks confusing, but it's actually nested ternaries (for nil checks)
return (cats[
p._normalizeId(category, defaultCategory)
(category ~= nil and string.len(category) ~= 0) and
] or (nilIfMissing and { sortkey = nil } or cats[defaultCategory])).sortkey
string.gsub(string.lower(category), "[^%w]", "")
or defaultCategory
] or cats[defaultCategory]).sortkey
end
function countp._icon(_tablecategory, nilIfMissing)
-- This looks confusing, but it's actually nested ternaries (for nil checks)
local n = 0
local icon = p._normalizeId(category, defaultCategory)
for _ in pairs(_table) do
n = n + 1
return icons[icon] or (cats[icon] ~= nil and (
end
cats[icon].icon or cats["tropicalcyclone"].icon
return n
) or (not nilIfMissing and cats[defaultCategory].icon) or nil)
end
function inlineWarningp._isEqual(detailscategory1, iconcategory2)
-- Checks if two IDs are equal.
return mw.html.create("span")
-- An {{#ifeq}} check does not consider aliases. This function compares two
:css("color", "darkred")
-- IDs in a way that considers category aliases. This works because alias
:wikitext("(")
-- assignments are references to the actual table containing the category
:node(
-- info found in the main category table.
mw.html.create("span")
--
:attr("title", details)
-- `false` will be returned if at least one of the categories are nil or
:css("text-decoration", "underline")
-- if the category is not defined.
:css("text-decoration-style", "dotted")
local _category1 = p._normalizeId(category1)
:wikitext(icon or "!")
local _category2 = p._normalizeId(category2)
)
return (_category1 == _category2 and _category1 ~= nil) or
:wikitext(")")
cats[ _category1 ] == cats[ _category2 ] and
-- `false` if categories are undefined and not equal.
cats[ _category1 ] ~= nil
end
function p.demo(frame)
return require("Module:Storm categories/demo").demo(frame)
local out = mw.html.create("table")
:addClass("wikitable")
:addClass("sortable")
:attr("style", "width: 100%")
out
:node(
mw.html.create("tr")
:node(mw.html.create("th"):wikitext("ID")
:attr("rowspan", "2"))
:node(mw.html.create("th"):wikitext("Name")
:attr("colspan", "2"))
:node(mw.html.create("th"):wikitext("Color")
:attr("rowspan", "2")
:attr("colspan", "2"))
:node(mw.html.create("th"):wikitext("Sortkey")
:attr("colspan", "2"))
):node(
mw.html.create("tr")
:node(mw.html.create("th"):wikitext("Basin"))
:node(mw.html.create("th"):wikitext("Name"))
:node(mw.html.create("th"):wikitext("Basin"))
:node(mw.html.create("th"):wikitext("Sortkey")
:attr("data-sort-type", "number"))
)
local legends = {}
for name, cat in TableTools.sortedPairs(cats) do
local rows = { mw.html.create("tr") }
local row = rows[1]
local id = mw.html.create("td")
:wikitext(name)
local actualColor = p._color(name)
local colorPreview = mw.html.create("td")
:attr("style", "background-color: #" .. actualColor .. "; padding: 0; width: 1.8em")
local color = mw.html.create("td")
:wikitext("#" .. actualColor)
if actualColor ~= cat["color"] then
color
:node(
mw.html.create("span")
:css("text-decoration", "underline")
:css("text-decoration-style", "dotted")
:attr("title", "Overriden from original color (#" .. cat["color"] .. ")")
:wikitext("*")
)
legends["*"] = "Overriden from original color."
end
local catColorBlackRatio = colorRatio({ "#" .. actualColor, "black" })
local catColorLinkRatio = colorRatio({ "#" .. actualColor, "#0645ad" })
local catColorVisitedLinkRatio = colorRatio({ "#" .. actualColor, "#0b0080" })
if catColorBlackRatio == "?" or catColorLinkRatio == "?" or catColorVisitedLinkRatio == "?" then
color
:wikitext(" ")
:node(inlineWarning("This color must be a hexadecimal color.", "E"))
legends["E"] = "Not a valid hexadecimal color code."
else
if catColorBlackRatio < 4.5 then
color
:wikitext(" ")
:node(inlineWarning("This color has contrast issues with black (not WCAG 2.0 AA-compatible).", "C"))
legends["C"] = "Color has contrast issues with black."
end
if catColorLinkRatio < 4.5 then
color
:wikitext(" ")
:node(inlineWarning("This color has contrast issues with links (not WCAG 2.0 AA-compatible).", "L"))
legends["L"] = "Color has contrast issues with links (#0645ad)."
end
if catColorVisitedLinkRatio < 4.5 then
color
:wikitext(" ")
:node(inlineWarning("This color has contrast issues with visited links (not WCAG 2.0 AA-compatible).", "V"))
legends["V"] = "Color has contrast issues with visited links (#0b0080)."
end
end
local sortkeyCategory = mw.html.create("td")
:attr("data-sort-value", cat["sortkey"])
local sortkey = mw.html.create("td")
:attr("data-sort-value", cat["sortkey"])
:wikitext(cat["sortkey"])
if cat["sortkey"] < 0 then
sortkeyCategory:wikitext("Invalid")
elseif cat["sortkey"] < 20000 then
sortkeyCategory:wikitext("Global")
elseif cat["sortkey"] < 30000 then
sortkeyCategory:wikitext("Historical")
elseif cat["sortkey"] < 40000 then
sortkeyCategory:wikitext("SWIO")
elseif cat["sortkey"] < 50000 then
sortkeyCategory:wikitext("Aus/Fiji")
elseif cat["sortkey"] < 60000 then
sortkeyCategory:wikitext("NIO")
elseif cat["sortkey"] < 80000 then
sortkeyCategory:wikitext("WPAC")
elseif cat["sortkey"] < 90000 then
sortkeyCategory:wikitext("Atl/EPac/SAtl")
elseif cat["sortkey"] < 100000 then
sortkeyCategory:attr("style", "color: gray")
sortkeyCategory:wikitext("''Global''")
else
sortkeyCategory:wikitext("Invalid")
end
if type(cat["name"]) == "string" then
local name = mw.html.create("td")
:attr("colspan", "2")
:wikitext(cat["name"])
row:node(id)
row:node(name)
else
local nameTableLength = count(cat["name"])
id:attr("rowspan", nameTableLength)
colorPreview:attr("rowspan", nameTableLength)
color:attr("rowspan", nameTableLength)
sortkeyCategory:attr("rowspan", nameTableLength)
sortkey:attr("rowspan", nameTableLength)
row:node(id)
local firstDone = false
for key, basinName in TableTools.sortedPairs(cat["name"]) do
if firstDone then
local nameRow = mw.html.create("tr")
nameRow
:node(mw.html.create("td"):wikitext(key))
:node(mw.html.create("td"):wikitext(basinName))
table.insert(rows, nameRow)
else
firstDone = true
row
:node(mw.html.create("td"):wikitext(key))
:node(mw.html.create("td"):wikitext(basinName))
end
end
end
row:node(colorPreview)
row:node(color)
row:node(sortkeyCategory)
row:node(sortkey)
for _, _row in TableTools.sortedPairs(rows) do
out:node(_row)
end
end
for name, color in TableTools.sortedPairs(colors) do
if cats[name] == nil then
local row = mw.html.create("tr")
:node(mw.html.create("td"):wikitext(name))
:node(mw.html.create("td")
:attr("colspan", "2")
:wikitext("''<span style=\"color:gray\">not available</span>''"))
:node(mw.html.create("td")
:attr("style", "background-color: #" .. color .. "; padding: 0; width: 1.8em"))
:node(mw.html.create("td")
:wikitext("#" .. color))
:node(mw.html.create("td")
:attr("colspan", "2")
:wikitext("''<span style=\"color:gray\">not available</span>''"))
out:node(row)
end
end
local legendsCompiled = mw.html.create("ul")
local showLegend = false
legendsCompiled
:css("list-style-image", "none")
:css("list-style-type", "none")
for legend, details in TableTools.sortedPairs(legends) do
showLegend = true
legendsCompiled:node(
mw.html.create("li")
-- en dash
:wikitext("'''" .. legend .. "''' – " .. details)
)
end
return (showLegend and tostring(legendsCompiled) or "") .. tostring(out)
end
p.cats = cats
return p
|