Module:ECR

--[=[ -- LUA script to get Enchanted Chests Rewards -- --]=]

local p = {}

local availableData = mw.loadData( 'Module:Available/data' ) local cData = mw.loadData( 'Module:ItemCollection/data' ) ---[==[ For testing purposes local chestData = mw.loadData( 'Module:ECR/data' ) --[===[]==] local chestData = { ["Legendary"] = { ["Pinocchio"] = { ["C"] = "60 Real Money (x6)", ["R"] = { ["Common"] = "EC-Magic #50-613 $ Jiminy Cricket $ Figaro $ Geppetto's Workshop", ["Uncommon"] = "EC-Magic #100-1,225 $ Geppetto $ Blue Fairy $ Pinocchio Village Haus $ Jiminy Cricket's Hat Stand", ["Rare"] = "EC-Magic #150-1,838 $ Honest John $ Stromboli's Caravan", ["Epic"] = "Stromboli $ Pinocchio's Daring Journey $ Pinocchio's Hat Stand", ["Legendary"] = "Pinocchio", },		},	}, 	["Radiant"] = {true, ["THOND Event"] = { ["N"] = "", ["D"] = {"2022/12/28", 18}, ["C"] = "20 Real Money (x6)", ["R"] = { ["T"] = {"Phoebus$Djali$Claude Frollo$Esmeralda$Quasimodo"}, ["Common"] = "EC-THOND #200 $ EC-Magic #100-700 $ IP-THOND #5", ["Uncommon"] = "EC-Magic #200-1,400", ["Rare"] = "EC-Magic #500-3,500", },		},	}, } --]===]

local util = require('Module:Utility') local RARITY = require("Module:Rarity").rarity local EC = require("Module:EC").getEC local TOK = require("Module:CharacterToken") local CHEST = require("Module:EnchantedChest").getChest local COLL = require("Module:ItemCollection").getCollection local date = require("Dev:Date")

local bubbles = {}

local function countdown(enddate, text1, text2, nowrap) return "Available" .. text1 .. "" .. enddate .. "  "        	.. (nowrap and "" or "") .. " (Available"       	.. text2        	.. date(enddate):fmt("%A, %B %d")        	.. ") " .. (nowrap and "" or " ") end

local function addItem(data) local dataUnknown = {data["Unknown"] or ""} local dataCommon = {data["Common"] or ""} local dataUncommon = {data["Uncommon"] or ""} local dataRare = {data["Rare"] or ""} local dataEpic = {data["Epic"] or ""} local dataLegendary = {data["Legendary"] or ""}

local raTok = "" local rbTok = ""

if data["T"] and data["T"][1] then for tCh in mw.text.gsplit(data["T"][1], "%s*$%s*") do raTok = TOK.getToken({(tCh .. ",2"), "R"}) rbTok = TOK.getToken({(tCh .. ",3"), "R"})

local tOut = "$" .. tCh

if raTok == "common" then table.insert(dataCommon, (tOut .. ",2 #" .. (data["T"][2] or "1"))) elseif raTok == "uncommon" then table.insert(dataUncommon, (tOut .. ",2 #" .. (data["T"][3] or "1"))) elseif raTok == "rare" then table.insert(dataRare, (tOut .. ",2 #" .. (data["T"][4] or "1"))) elseif raTok == "epic" then table.insert(dataEpic, (tOut .. ",2 #" .. (data["T"][5] or "1"))) elseif raTok == "legendary" then table.insert(dataLegendary, (tOut .. ",2 #" .. (data["T"][6] or "1"))) end

if rbTok == "common" then table.insert(dataCommon, (tOut .. ",3 #" .. (data["T"][2] or "1"))) elseif rbTok == "uncommon" then table.insert(dataUncommon, (tOut .. ",3 #" .. (data["T"][3] or "1"))) elseif rbTok == "rare" then table.insert(dataRare, (tOut .. ",3 #" .. (data["T"][4] or "1"))) elseif rbTok == "epic" then table.insert(dataEpic, (tOut .. ",3 #" .. (data["T"][5] or "1"))) elseif rbTok == "legendary" then table.insert(dataLegendary, (tOut .. ",3 #" .. (data["T"][6] or "1"))) end end end

local tRarity = {} table.insert(tRarity, {"Legendary", table.concat(dataLegendary)}) table.insert(tRarity, {"Epic", table.concat(dataEpic)}) table.insert(tRarity, {"Rare", table.concat(dataRare)}) table.insert(tRarity, {"Uncommon", table.concat(dataUncommon)}) table.insert(tRarity, {"Common", table.concat(dataCommon)}) table.insert(tRarity, {"Unknown", table.concat(dataUnknown)})

return tRarity end

local function chItems(inStr) local tIn = mw.text.split(inStr, "%s*%$%s*") local tOut = {} for idx = 1, #tIn do		local tt = mw.text.split(tIn[idx], "%s*#%s*") if tt[1] ~= "" then if not tt[2] or tt[2] == "" then tt[2] = 1 end table.insert(tOut, tt) end end return tOut end

local function oneItem(item, count, size) nCount = count or 0 if nCount == 0 then return "" end

local conv = { ["ch"] = "cp", ["cos"] = "cp", }

local tItem = {"", (" " .. nCount), " ",			"", "",			" ",	}

local iName = item local iData = cData.Items[iName]

if item:match("Chests") then tItem[1] = CHEST({iName, (size or 35)}) tItem[4] = CHEST({item, "L"}) elseif iData and iData[2] then local isize = size or 45 isize = isize + 5 local iDisp = iName:gsub("^([^%(]-)%/([^%(]-)$", "%2") local fname = mw.ustring.gsub(mw.ustring.lower(iName), "[':\"%,%.]", "")		fname = fname:gsub(" ", "_")		if iData[2] == "pf" then			fname = fname:gsub("_float$", "")		else			fname = fname:gsub("^([^%(]-)%/([^%(]-)$", "%1-%2")			fname = mw.ustring.gsub(fname, "^([^%(]-) *%(([^%(]-)%)$", "%1_%2")		end

local tItemData = {"", "", ""							}		if cData["Items"][item]["C"] and cData["Categories"][cData["Items"][item]["C"]] then local category = cData["Items"][item]["C"] tItemData[1] = '' local csize = 27 if isize == 47 then csize = 24 end tItemData[15] = ' ' tItem[3] = ' ' end tItem[1] = table.concat(tItemData) tItem[2] = "" tItem[4] = table.concat({"", (iDisp or iName), ""}) elseif item:match("^EC") then tItem[1] = EC({item, nil, nil, "E", (size or 35)}) tItem[4] = EC({item, "L", S=(nCount == "1")}) else tItem[1] = TOK.getToken({item, (size or 35)}) tItem[4] = TOK.getToken({item, "L"}) if nCount ~= "1" then tItem[5] = "s" end end

if size then return tItem[1] else return table.concat(tItem) end end

local function colItem(iNumb, tNumb, aNumb, item) local tOut = {}

if iNumb == 1 then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, '\n| colspan="2"|') elseif iNumb == 2 then if aNumb == (tNumb - 1) then table.insert(tOut, '\n|\n| colspan="2"|') table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == tNumb then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) table.insert(tOut, '\n| colspan="2"|\n|') end elseif iNumb == 3 then if aNumb == (tNumb - 2) then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == (tNumb - 1) then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == tNumb then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) table.insert(tOut, '\n| colspan="2"|') end elseif iNumb == 4 then if aNumb == (tNumb - 3) then table.insert(tOut, '\n|\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == (tNumb - 2) then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == (tNumb - 1) then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == tNumb then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) table.insert(tOut, '\n|') end else table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) end

return table.concat(tOut) end

function getBubbles(data, legendary) local tOut = {} local item = "" local k = 1

for rarity, v in pairs(data) do		if k == 1 then item = v[1] or v[2] or v[3] if legendary then table.insert(tOut, (' ')) else table.insert(tOut, (' ')) end elseif k == 2 and not legendary then item = v[3] or v[2] or v[1] table.insert(tOut, (' ')) elseif k == 3 then item = v[1] or v[2] or v[3] table.insert(tOut, (' ')) break end k = k + 1 end

return table.concat(tOut) end

function p.getECR(frame) local tArgs = util.getArgs(frame)

local pagename = tArgs[1] or mw.title.getCurrentTitle.baseText local cName = mw.ustring.gsub(pagename, " Chests", "") local tOut = {} local cSection = {} local today = os.date("%Y/%m/%d %H:%M:%S") local allcoll = "" if chestData[cName] then for k, v in pairs(chestData[cName]) do			if v ~= true then local aData = (v["D"] or {"2016/01/01", 0}) if availableData[cName] and availableData[cName][k] then aData = availableData[cName][k] end local cNumb = date(aData[1]):adddays(aData[2]):fmt("%Y/%m/%d") .. (aData[3] or util.dayStart) local cDur = nil if (aData[1] .. util.dayStart) <= today then cDur = util.strDate(aData[1], aData[2]) end if aData[2] == 0 then cNumb = date(aData[1]):adddays(aData[2]+1):fmt("%Y/%m/%d") .. (aData[3] or util.dayStart) cDur = nil end table.insert(cSection, {cNumb, k, v, cDur, (aData[1] .. util.dayStart), (aData["C"] or v["C"])}) end end

table.sort(cSection, function(a,b) return a[1] > b[1] end)

for _, cItem in pairs(cSection) do		if chestData[cName][1] and (cItem[5] >= today) then table.insert(tOut, "") else local tCard = {} local tTable = {} local tRarity = {} bubbles[cItem[2]] = {} local ecData = cItem[3]

local sName = cItem[2]:gsub(" ", "_")

table.insert(tTable, '{| class="dmk-chests mw-collapsible mw-collapsed" id="mw-customcollapsible-')			table.insert(tTable, sName)			table.insert(tTable, '" style="text-align: center; line-height: 1.0; display: unset;"\n! id="')			table.insert(tTable, cItem[2])			table.insert(tTable, '" colspan="10" style="background: linear-gradient(#14bfe4 5%,#2866ce 100%); border-radius: 20px 20px 0 0; height: 35px; color: white; text-shadow: 1px 2px 3px #030d9d;"| Possible Rewards You can receive the following rewards\n|- style="height: 0px;"|\n||||||||||||||||||||')

if ecData["S"] then table.insert(tTable, '\n|-\n! colspan="10"|⸺⸺⸺ Only at ') table.insert(tTable, (ecData["S"][1] or "?")) table.insert(tTable, '% Special Chance  ⸺⸺⸺ ') tRarity = addItem(ecData["S"])

for _, item in pairs(tRarity) do				   if item[2] ~= "" then table.insert(tTable, '\n|-\n! colspan="10" style="padding: 5px;"|') table.insert(tTable, RARITY({item[1], "ECR"})) table.insert(tTable, '\n|-')

item[2] = chItems(item[2])

local tItems = {} local tNo = "" local rNo = "" for No, rData in ipairs(item[2]) do						table.insert(tItems, oneItem(rData[1], rData[2])) tNo = No						rNo = No

if not bubbles[cItem[2]]["specialchance"] then bubbles[cItem[2]]["specialchance"] = {} end

local bData = bubbles[cItem[2]]["specialchance"]

if cData["Items"][rData[1]] and not bData[1] then bData[1] = rData[1] elseif rData[1]:match("^EC") and not bData[3] then bData[3] = rData[1] elseif not cData["Items"][rData[1]] and not rData[1]:match("^EC") and not bData[2] then bData[2] = rData[1] end end local iNo = 0 if tNo > 5 then repeat rNo = rNo - 5 iNo = iNo + 1 until rNo < 5 end for i, item in ipairs(tItems) do						if i == 6 or i == 11 then table.insert(tTable, '\n|-') end if i <= (iNo * 5) then table.insert(tTable, '\n| colspan="2"|') table.insert(tTable, item) else table.insert(tTable, colItem(rNo, tNo, i, item)) end end end end table.insert(tTable, '\n|-\n! colspan="10"|⸺⸺⸺⸺ ⸺⸺⸺⸺ ') end

tRarity = addItem(ecData["R"])

for i, item in ipairs(tRarity) do			   if item[2] ~= "" then table.insert(tTable, '\n|-\n! colspan="10" style="padding: 5px;"|') table.insert(tTable, RARITY({item[1], "ECR"})) table.insert(tTable, '\n|-')

item[2] = chItems(item[2])

local tItems = {} local tNo = "" local rNo = "" for No, rData in ipairs(item[2]) do					table.insert(tItems, oneItem(rData[1], rData[2])) tNo = No					rNo = No

if not bubbles[cItem[2]][item[1]:lower] then bubbles[cItem[2]][item[1]:lower] = {} end

local bData = bubbles[cItem[2]][item[1]:lower]

if cData["Items"][rData[1]] and not bData[1] then bData[1] = rData[1] elseif rData[1]:match("^EC") and not bData[3] then bData[3] = rData[1] elseif not bData[2] then bData[2] = rData[1] end end local iNo = 0 if tNo > 5 then repeat rNo = rNo - 5 iNo = iNo + 1 until rNo < 5 end local br = 6 for i, iName in ipairs(tItems) do					if i == br then table.insert(tTable, '\n|-') br = br + 5 end if i <= (iNo * 5) then table.insert(tTable, '\n| colspan="2"|') table.insert(tTable, iName) else table.insert(tTable, colItem(rNo, tNo, i, iName)) end end end end if tArgs[cItem[2]] then table.insert(tTable, '\n|-\n|colspan="10" style="line-height: 1.75; text-align: left;"|') table.insert(tTable, tArgs[cItem[2]]) end table.insert(tTable, '\n|}\n')

tCard = {'{| class="chestcard ', "default", '" style="text-align: center; line-height: normal; border-spacing: 0px; color: white; text-shadow: 1px 2px 3px #030d9d; display: inline-table; margin: 0 0px 10px 0;"\n', '| style="text-align: left; width: 115px !important; height: 40px; background-size: 231px; background-position: 0 0; padding: 7px 0 0 7px;"|', "", '\n', '| style="text-align: right; width: 115px !important; background-size: 231px; background-position: -116px 0; padding: 3px 20px 0 0;"|', "", '\n', '|-\n', '| colspan="2" style="height: 160px; background-size: cover; background-position: 0 -40px;"| ', CHEST({cName .. "-" .. cItem[2], 100}), getBubbles(bubbles[cItem[2]]), '  \n', '|-\n', '| colspan="2" style="height: 60px; max-width: 230px !important; background-size: cover; background-repeat: no-repeat; background-position: 0 -200px; padding: 0 10px 0 5px;"| ', (ecData["N"] or cItem[2]), ' \n', '|-\n', '| colspan="2" style="height: 75px; background-size: cover; background-position: 0 -260px; vertical-align: top; padding: 0 10px; max-width: 230px !important;"| \n', '|-\n', '| colspan="2" style="background-size: cover;background-position: 0 -335px;background-repeat: no-repeat; max-width: 230px !important;"|', "", '\n|}\n'}

if cName == "Legendary" then tCard[2] = COLL({cItem[2], "S"}):lower tCard[8] = COLL({cItem[2], 35}) tCard[12] = "" tCard[13] = getBubbles(bubbles[cItem[2]], true) allcoll = allcoll .. "$" .. cItem[2] end

if cName == "Special Request Wishes" then tCard[12] = '' end

if cItem[6] then local iCost = "" for costItem in mw.text.gsplit(cItem[6], "%s*$%s*") do					if costItem:match("^EC-") then local curName, curNumb = mw.ustring.match(costItem, "^([^,]-)%s*#%s*(.-)$") if not curName then curName = costItem end if not curNumb then curNumb = "1" end

local cNumb, sNumb = mw.ustring.match(curNumb, "^([^,]-)%s*-%s*(.-)$") if not cNumb then cNumb = count end

if sNumb then cNumb = tonumber((string.gsub(cNumb or "", "[,]", ""))) sNumb = tonumber((string.gsub(sNumb or "", "[,]", ""))) iCost = iCost .. EC({curName .. " #" .. sNumb}).. '  ' .. cNumb .. ' (-' .. (100-(string.format("%.2f", (sNumb/cNumb))*100)) .. '%) ' tCard[5] = '' else iCost = iCost .. EC({curName .. " #" .. curNumb}) .. " "						end else iCost = iCost .. costItem .. " "					end end tCard[23] = ' .. iCost ..  '			end

if cItem[5] <= today and today <= cItem[1] then cItem[4] = countdown(cItem[1], " for ", " until ", true) elseif cItem[5] >= today then cItem[4] = ": " .. countdown(cItem[1], " in ", " on ") elseif cName == "Legendary" then cItem[4] = " Last Time: " .. cItem[4] end if cItem[4] then tCard[27] = ' ' end

table.insert(tOut, table.concat(tCard)) table.insert(tOut, table.concat(tTable)) end end end

if allcoll ~= "" then table.insert(tOut, 1, (COLL({allcoll, "A"}) .. " \n")) end

return frame:preprocess(table.concat(tOut)) end

function p.getDATA(tItems, cSection) local cName = mw.ustring.gsub(tItems, " Chests", "") or ""

if chestData[cName] and chestData[cName][cSection] then local rarity = chestData[cName][cSection]["R"] local tRarity = addItem(rarity)

for _, item in ipairs(tRarity) do			if item[2] ~= "" then item[2]	= chItems(item[2]) for _, rData in ipairs(item[2]) do tItems = tItems .. "$" .. rData[1] end end end

if chestData[cName][cSection]["S"] then local rarity = chestData[cName][cSection]["S"] local tRarity = addItem(rarity)

for _, item in ipairs(tRarity) do				if item[2] ~= "" then item[2]	= chItems(item[2]) for _, rData in ipairs(item[2]) do tItems = tItems .. "$" .. rData[1] end end end end end

return tItems end

local function getChest(iType, data, cName, pagename, special, old, section) local tRarity = addItem(data)

for _, item in pairs(tRarity) do		if item[2] ~= "" then item[2] = chItems(item[2]) for _, rData in ipairs(item[2]) do				local iName = rData[1]

if iType == "T" then if pagename == "Collection" or pagename == "Common" or pagename == "Uncommon" or pagename == "Rare" or pagename == "Epic" or pagename == "Legendary" or pagename == "Relic Common" or pagename == "Relic Uncommon" or pagename == "Relic Rare" then iName = iName elseif iName:match("^EC") then iName = EC({iName, "T"}) else iName = TOK.getToken({iName, "T"}) end else if iName:match("^EC") then iName = EC({iName, "T"}) end end

if rData[2] then rData[2] = "x" .. rData[2] end

if pagename == iName then return {(cName .. "-" .. (section or "")), rData[2], special, old, CHEST=true} end end end end

return tOut end

function p.getTOK(frame) local tArgs = util.getArgs(frame)

local tOut = {} local tChest = {} if tArgs[1] then local conv = { ["Bronze-Old"]   = {"Bronze", ' data-sort-value="99902"|3h'}, ["Silver-Old"]   = {"Silver", ' data-sort-value="99903"|6h'}, ["Gold-Old"]     = {"Gold", ' data-sort-value="99904"|12h'}, ["Platinum-Old"] = {"Platinum", ' data-sort-value="99905"|24h'}, }		if conv[tArgs[1]] then table.insert(tChest, {conv[tArgs[1]][1], ("x" .. (tArgs[3] or "1")), (tArgs[2] or nil), (conv[tArgs[1]][2] or nil)}) else table.insert(tChest, {tArgs[1], ("x" .. (tArgs[3] or "1")), (tArgs[2] or nil)}) end else local pagename = tArgs["P"] or mw.title.getCurrentTitle.text

for cName, chest in pairs(chestData) do			for n, v in pairs(chest) do				if v ~= true then if v["D"] then local today = os.date("%Y/%m/%d %H:%M:%S") local data = v["D"] local UnlockDate = data[1] .. util.dayStart local LockDate = date(data[1]):adddays(data[2]):fmt("%Y/%m/%d") .. (data[3] or util.dayStart) if UnlockDate < today and (data[2] == 0 or today < LockDate) then if v["R"] then table.insert(tChest, getChest("T", v["R"], cName, pagename, nil, nil, n)) end if v["S"] then table.insert(tChest, getChest("T", v["S"], cName, pagename, "S", nil, n)) end

if not pagename:match("^.+ Blueprint Token$") and not pagename:match("^.+ Elixir Ingot Token$") and not pagename:match("^Time Skip Token$") then local pRarity = TOK.tokenType({pagename, "S"}) pRarity = string.upper(string.sub(pRarity, 1, 1)) .. string.sub(pRarity, 2) if pagename:match("^.+ Relic Token$") then pRarity = TOK.tokenType({pagename, "T"}) pRarity = string.upper(string.sub(pRarity, 1, 1)) .. string.sub(pRarity, 2) pRarity = "Relic " .. mw.ustring.gsub(pRarity, " relic", "") end

if v["R"] then table.insert(tChest, getChest("T", v["R"], cName, pRarity, nil, nil, n)) end if v["S"] then table.insert(tChest, getChest("T", v["S"], cName, pRarity, "S", nil, n)) end end end end end end end end

for k, v in pairs(tChest) do		if v[1] == "Special Request Wishes-Current" then local tRet = {	'|-\n| style="text-align: center;"| \n|Special Request Wishes\n|\n| data-sort-value="0"|Instant\n| colspan="2"|', v[2], '\n' }			table.insert(tOut, table.concat(tRet)) else local tRet = {	'|-\n| style="text-align: center;"| ', CHEST({v[1], "50"}), ' \n|', CHEST({v[1], "L"}), "", "", '\n|\n| style="text-align: center;"', ' data-sort-value="99901"|Instant', '\n| colspan="2"|', v[2], '\n' }

if v[3] then tRet[6] = " * Special Chance Only " end

if v[4] then tRet[8] = v[4] end

table.insert(tOut, table.concat(tRet)) end end

return table.concat(tOut) end

function p.getITEM(frame) local ME = require("Module:MiniEvent").getME local tArgs = util.getArgs(frame) local today = os.date("%Y/%m/%d %H:%M:%S")

local tOut = {} local tChest = {} local space = "" local pagename = tArgs["P"] or mw.title.getCurrentTitle.text

for cName, chest in pairs(chestData) do		for n, v in pairs(chest) do			if v ~= true then if v["D"] then local data = v["D"] local UnlockDate = data[1] .. util.dayStart local LockDate = date(data[1]):adddays(data[2]):fmt("%Y/%m/%d") .. (data[3] or util.dayStart) if UnlockDate < today and (data[2] == 0 or today < LockDate) and cName ~= "Legendary" then if v["R"] then table.insert(tChest, getChest("I", chestData[cName][n]["R"], cName, pagename, nil, nil, n)) end if v["S"] then table.insert(tChest, getChest("I", chestData[cName][n]["S"], cName, pagename, "S", nil, n)) end end else table.insert(tChest, getChest("I", v["R"], "Legendary", pagename, nil, nil, n)) end end end end

for sName, data in pairs(availableData) do		if availableData[sName][1] and type(data) == "table" then for name, v in pairs(data) do				if v ~= true then local UnlockDate = v[1] .. util.dayStart local LockDate = date(v[1]):adddays(v[2]):fmt("%Y/%m/%d") .. (v[3] or util.dayStart) if UnlockDate < today and (v[2] == 0 or today < LockDate) and cName ~= "Legendary" then for cName in mw.text.gsplit(name, "%s*%$%s*") do							if pagename == cName then table.insert(tChest, {(v["L"] or sName), (v["A"] or ""), (v["D"] or v["A"] or v["L"] or sName), v["R"]}) end end end end end end end

pagename = mw.title.getCurrentTitle.subpageText

for k, v in pairs(tChest) do		local tRet = {space, "", "", "", "", ""}

if tArgs[1] == "L" and v["CHEST"] then tRet[2] = CHEST({v[1], "O"}) elseif tArgs[1] == "I" and v["CHEST"] then tRet[2] = CHEST({v[1], "L", "S"}) elseif tArgs[1] == "L" then tRet[2] = "[[File:"			if v[1]:match(" Mini Event$") then				local meData = mw.loadData( 'Module:MiniEvent/data')				tRet[3] = v[1]:match("^(.+) Mini Event$"):lower				tRet[3] = meData[tRet[3]]["NPC"] tRet[3] = "Npc-" .. tRet[3]:gsub(" ", "_"):lower

local mile, pos = string.match(v[4], "^([LM])(.*)") tRet[5] = "''Unlock " .. v[3] .. ": " .. util.ordinal(pos) .. ((mile == "M") and " Milestone" or " Leaderboard") .. " to get " .. pagename .. "!''"			elseif v[1]:match("^Season") then tRet[3] = "season_pass" elseif v[1]:match("Calendar$") then tRet[3] = "home-calendar" elseif v[1] == "Discovery Rewards" then tRet[3] = "discovery" else tRet[3] = "home-promotion" end tRet[4] = ".png|x25px|link=" .. v[1] .. "#" .. v[2].. "|" .. v[3] .. "]] "			if tRet[5] == "" then tRet[5] = "''Unlock [[" .. v[1] .. "#" .. v[2] .. "|" .. v[3] .. ": " .. v[2] .. "]] to get " .. pagename .. "!''" end elseif tArgs[1] == "I" then tRet[2] = "" .. v[3] .. ": " tRet[3] = v[2] if v[1]:match("Mini Event$") and v[4] then local mile, pos = string.match(v[4], "^([LM])(.*)") tRet[3] = util.ordinal(pos) tRet[4] = (mile == "M") and " Milestone" or " Leaderboard" end end space = " "

table.insert(tOut, table.concat(tRet)) end

if table.concat(tOut) ~= "" then table.insert(tOut, " ") end

return table.concat(tOut) end

function p.getLastCost(frame) local tArgs = util.getArgs(frame) local tOut = "" local prevTab = "2016/01/01" local pagename = tArgs["P"] if not pagename then pagename = mw.title.getCurrentTitle.text end pagename = mw.ustring.gsub(pagename, " Chests", "") or "" if not chestData[pagename] then return "" end

for cName, chest in pairs(chestData[pagename]) do		if chest ~= true and chest["D"] and chest["C"] and chest["D"][1] > prevTab then tOut = chest["C"] prevTab = chest["D"][1] end end

return frame:preprocess(tOut) end

function p.availabilityEC(frame) local tArgs = util.getArgs(frame)

local today = os.date("%Y/%m/%d %H:%M:%S") local pagename = tArgs[1] or mw.title.getCurrentTitle.text pagename = mw.ustring.gsub(pagename, " Chests", "") or ""

local tOut = "" local space = "" local tItem = {}

for cName, chest in pairs(chestData) do		if pagename == cName then for n, v in pairs(chest) do				if v ~= true then if availableData[cName] and availableData[cName][n] then table.insert(tItem, {n, availableData[cName][n][1], availableData[cName][n][2], (availableData[cName][n][3] or util.dayStart), (cName .. " Chests"), n}) elseif v["D"] then table.insert(tItem, {n, v["D"][1], v["D"][2], (v["D"][3] or util.dayStart), (cName .. " Chests"), n}) end end end elseif pagename == "All" then for n, v in pairs(chest) do				if v ~= true then if availableData[cName] and availableData[cName][n] then table.insert(tItem, {n, availableData[cName][n][1], availableData[cName][n][2], (availableData[cName][n][3] or util.dayStart), (cName .. " Chests"), (n .. " Chests")}) elseif v["D"] and v["D"][2] ~= 0 then table.insert(tItem, {n, v["D"][1], v["D"][2], (v["D"][3] or util.dayStart), (cName .. " Chests"), (cName .. " Chests")}) end end end end end

table.sort(tItem, function(a,b) return (date(a[2]):adddays(a[3]):fmt("%Y/%m/%d")) < (date(b[2]):adddays(b[3]):fmt("%Y/%m/%d")) end)

for _, v in pairs(tItem) do local Header = "" .. (v[6] or v[5] or v[1]) .. ":  " local UnlockDate = v[2] .. util.dayStart local LockDate = date(v[2]):adddays(v[3]):fmt("%Y/%m/%d") .. v[4]

if today <= UnlockDate then tOut = tOut .. space .. Header .. ": " .. countdown(UnlockDate, " in ", " on ") space = " " elseif v[3] == 0 then tOut = tOut .. space .. Header .. ": Currently Available" space = " " elseif today <= LockDate then tOut = tOut .. space .. Header .. ": " .. countdown(LockDate, " for ", " until ") space = " " end end

if tOut ~= "" then return tOut else return "" .. pagename .. " Chests:  : Not Currently Available" end end

return p