<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.runerealm.org/index.php?action=history&amp;feed=atom&amp;title=Module%3ABestiary%2FSandbox</id>
	<title>Module:Bestiary/Sandbox - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.runerealm.org/index.php?action=history&amp;feed=atom&amp;title=Module%3ABestiary%2FSandbox"/>
	<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Bestiary/Sandbox&amp;action=history"/>
	<updated>2026-05-05T14:27:22Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://wiki.runerealm.org/index.php?title=Module:Bestiary/Sandbox&amp;diff=34424&amp;oldid=prev</id>
		<title>Alex: Created page with &quot;local p = {}  local yesno = require(&#039;Module:Yesno&#039;) local pt = require(&#039;Module:Paramtest&#039;) local enum = require(&#039;Module:Enum&#039;) local pagelisttools = require(&#039;Module:PageListTools&#039;) local avg = require(&#039;Module:Average_drop_value/Sandbox&#039;) local curr = require(&#039;Module:Currency&#039;)._amount local pageswithcats = pagelisttools.pageswithcats  local smwstats = {}  -- Formats a table header function p.header(tbl, verbose)     local tr = tbl:tag(&#039;tr&#039;)         :tag(&#039;th&#039;):addClass(&#039;u...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Bestiary/Sandbox&amp;diff=34424&amp;oldid=prev"/>
		<updated>2024-10-16T23:00:38Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local p = {}  local yesno = require(&amp;#039;Module:Yesno&amp;#039;) local pt = require(&amp;#039;Module:Paramtest&amp;#039;) local enum = require(&amp;#039;Module:Enum&amp;#039;) local pagelisttools = require(&amp;#039;Module:PageListTools&amp;#039;) local avg = require(&amp;#039;Module:Average_drop_value/Sandbox&amp;#039;) local curr = require(&amp;#039;Module:Currency&amp;#039;)._amount local pageswithcats = pagelisttools.pageswithcats  local smwstats = {}  -- Formats a table header function p.header(tbl, verbose)     local tr = tbl:tag(&amp;#039;tr&amp;#039;)         :tag(&amp;#039;th&amp;#039;):addClass(&amp;#039;u...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local yesno = require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
local pt = require(&amp;#039;Module:Paramtest&amp;#039;)&lt;br /&gt;
local enum = require(&amp;#039;Module:Enum&amp;#039;)&lt;br /&gt;
local pagelisttools = require(&amp;#039;Module:PageListTools&amp;#039;)&lt;br /&gt;
local avg = require(&amp;#039;Module:Average_drop_value/Sandbox&amp;#039;)&lt;br /&gt;
local curr = require(&amp;#039;Module:Currency&amp;#039;)._amount&lt;br /&gt;
local pageswithcats = pagelisttools.pageswithcats&lt;br /&gt;
&lt;br /&gt;
local smwstats = {}&lt;br /&gt;
&lt;br /&gt;
-- Formats a table header&lt;br /&gt;
function p.header(tbl, verbose)&lt;br /&gt;
    local tr = tbl:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
        :tag(&amp;#039;th&amp;#039;):addClass(&amp;#039;unsortable&amp;#039;):node(&amp;#039;&amp;#039;):done()&lt;br /&gt;
        :tag(&amp;#039;th&amp;#039;):css(&amp;#039;text-align&amp;#039;, &amp;#039;left&amp;#039;):wikitext(&amp;#039;Monster&amp;#039;):done()&lt;br /&gt;
        :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;[[File:Member icon.png|link=|Members]]&amp;#039;):done()&lt;br /&gt;
        :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;[[File:Attack style icon.png|link=|Combat level]]&amp;#039;):done()&lt;br /&gt;
        :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;[[File:Hitpoints icon.png|link=|Hitpoints]]&amp;#039;):done()&lt;br /&gt;
        :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;[[File:Attack icon.png|link=|Attack level]]&amp;#039;):done()&lt;br /&gt;
        :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;[[File:Defence icon.png|link=|Defence level]]&amp;#039;):done()&lt;br /&gt;
        :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;[[File:Magic icon.png|link=|Magic level]]&amp;#039;):done()&lt;br /&gt;
        :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;[[File:Ranged icon.png|link=|Ranged level]]&amp;#039;):done()&lt;br /&gt;
        :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;[[File:Coins 10000.png|link=|Average drop value]]&amp;#039;):done()&lt;br /&gt;
&lt;br /&gt;
    if verbose then&lt;br /&gt;
        tr:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;[[File:Slayer icon.png|link=|Slayer level]]&amp;#039;):done()&lt;br /&gt;
          :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;&amp;lt;span title=&amp;quot;Slayer experience&amp;quot;&amp;gt;XP&amp;lt;/span&amp;gt;&amp;#039;):done()&lt;br /&gt;
          :tag(&amp;#039;th&amp;#039;):css(&amp;#039;text-align&amp;#039;, &amp;#039;left&amp;#039;):wikitext(&amp;#039;Slayer categories&amp;#039;):done()&lt;br /&gt;
          :tag(&amp;#039;th&amp;#039;):css(&amp;#039;text-align&amp;#039;, &amp;#039;left&amp;#039;):wikitext(&amp;#039;Assigned by&amp;#039;):done()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Main entrypoint&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
    local args = frame:getParent().args&lt;br /&gt;
    return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
    local mambo = {&amp;#039;Members&amp;#039;, &amp;#039;F2P&amp;#039;, &amp;#039;All&amp;#039;}&lt;br /&gt;
    local slayer_masters = { &amp;#039;Spria&amp;#039;, &amp;#039;Turael&amp;#039;, &amp;#039;Krystilia&amp;#039;, &amp;#039;Mazchna&amp;#039;, &amp;#039;Vannaka&amp;#039;, &amp;#039;Chaeldar&amp;#039;, &amp;#039;Konar quo Maten&amp;#039;, &amp;#039;Nieve&amp;#039;, &amp;#039;Steve&amp;#039;, &amp;#039;Duradel&amp;#039; }&lt;br /&gt;
    local pattern_alpha = &amp;#039;^%a$&amp;#039;&lt;br /&gt;
&lt;br /&gt;
    -- Fetch and validate all input parameters&lt;br /&gt;
    local fromlevel = tonumber(pt.default_to(args[&amp;#039;fromlevel&amp;#039;], &amp;#039;1&amp;#039;))&lt;br /&gt;
    local tolevel = tonumber(pt.default_to(args[&amp;#039;tolevel&amp;#039;], &amp;#039;1&amp;#039;))&lt;br /&gt;
    local fromletter = string.upper(pt.default_to(args[&amp;#039;fromletter&amp;#039;], &amp;#039;A&amp;#039;))&lt;br /&gt;
    local toletter = string.upper(pt.default_to(args[&amp;#039;toletter&amp;#039;], &amp;#039;A&amp;#039;))&lt;br /&gt;
    local mems = pt.default_to(args[&amp;#039;mems&amp;#039;], &amp;#039;All&amp;#039;)&lt;br /&gt;
    local assignedby = pt.default_to(args[&amp;#039;assignedby&amp;#039;], &amp;#039;&amp;#039;)&lt;br /&gt;
    local onlycat = pt.default_to(args[&amp;#039;onlycat&amp;#039;], &amp;#039;&amp;#039;)&lt;br /&gt;
    local attribute = pt.default_to(args[&amp;#039;attribute&amp;#039;], &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    local ba = {&lt;br /&gt;
        levelselect = true,&lt;br /&gt;
        levelsort   = true,&lt;br /&gt;
        slayeronly  = false,&lt;br /&gt;
        verbose     = false,&lt;br /&gt;
        showstats   = false,&lt;br /&gt;
        disco       = false,&lt;br /&gt;
        quest       = true,&lt;br /&gt;
        dmm         = true,&lt;br /&gt;
        cache       = false&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for k, b in pairs(ba) do&lt;br /&gt;
        if pt.has_content(args[k]) then&lt;br /&gt;
            ba[k] = yesno(args[k])&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if pt.has_content(args[&amp;#039;mems&amp;#039;]) and not enum.contains(mambo, mw.text.trim(args[&amp;#039;mems&amp;#039;])) then&lt;br /&gt;
        error(&amp;#039;mems parameter has invalid value&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if pt.has_content(args[&amp;#039;assignedby&amp;#039;]) and not enum.contains(slayer_masters, mw.text.trim(args[&amp;#039;assignedby&amp;#039;])) then&lt;br /&gt;
        error(&amp;#039;assignedby parameter has invalid value&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if ba[&amp;#039;levelselect&amp;#039;] then&lt;br /&gt;
        if pt.is_empty(args[&amp;#039;fromlevel&amp;#039;]) or not fromlevel then&lt;br /&gt;
            error(&amp;#039;parameter fromlevel is invalid&amp;#039;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        if pt.is_empty(args[&amp;#039;tolevel&amp;#039;]) or not tolevel then&lt;br /&gt;
            error(&amp;#039;parameter tolevel is invalid&amp;#039;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        assert(tolevel &amp;gt;= fromlevel, &amp;#039;parameter tolevel must be greater than or equal to fromlevel&amp;#039;)&lt;br /&gt;
    else&lt;br /&gt;
        if pt.is_empty(args[&amp;#039;fromletter&amp;#039;]) or not fromletter:match(pattern_alpha) then&lt;br /&gt;
            error(&amp;#039;parameter fromletter is invalid&amp;#039;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        if pt.is_empty(args[&amp;#039;toletter&amp;#039;]) or not toletter:match(pattern_alpha) then&lt;br /&gt;
            error(&amp;#039;parameter toletter is invalid&amp;#039;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        assert(toletter &amp;gt;= fromletter, &amp;#039;parameter toletter must be greater than or equal to fromletter&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Gather the data&lt;br /&gt;
    local fulldata = p.loadData(fromlevel, tolevel, fromletter, toletter, ba[&amp;#039;levelselect&amp;#039;], mems, ba[&amp;#039;slayeronly&amp;#039;], onlycat, attribute, assignedby, ba[&amp;#039;verbose&amp;#039;])&lt;br /&gt;
&lt;br /&gt;
    local data = p.filterData(fulldata, ba[&amp;#039;disco&amp;#039;], ba[&amp;#039;quest&amp;#039;], ba[&amp;#039;dmm&amp;#039;], ba[&amp;#039;cache&amp;#039;])&lt;br /&gt;
    local fulldata = nil&lt;br /&gt;
&lt;br /&gt;
    if ba[&amp;#039;levelsort&amp;#039;] then&lt;br /&gt;
        table.sort(data, function(a, b) return a[&amp;#039;level&amp;#039;] &amp;lt; b[&amp;#039;level&amp;#039;] end)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Format the output page&lt;br /&gt;
    local div = mw.html.create(&amp;#039;div&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    if #data == 0 then&lt;br /&gt;
        div:wikitext(&amp;#039;Search yielded no results.&amp;#039;)&lt;br /&gt;
        return div&lt;br /&gt;
    elseif ba[&amp;#039;showstats&amp;#039;] then&lt;br /&gt;
        div:wikitext(string.format(&amp;#039;Search yielded %i results.&amp;#039;, #data))&lt;br /&gt;
        if smwstats[&amp;#039;found&amp;#039;] == smwstats[&amp;#039;limit&amp;#039;] then&lt;br /&gt;
            div:wikitext(string.format(&amp;#039; Your search might have been too large and have been truncated as a result.&amp;#039;))&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local tbl = div:tag(&amp;#039;table&amp;#039;):addClass(&amp;#039;wikitable sortable&amp;#039;)&lt;br /&gt;
        :addClass(&amp;#039;align-center-1 align-left-2 align-left-3 align-center-4 align-center-5&amp;#039;)&lt;br /&gt;
        :addClass(&amp;#039;align-center-6 align-center-7 align-center-8 align-center-9 align-center-10&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    if ba[&amp;#039;verbose&amp;#039;] then&lt;br /&gt;
        tbl:addClass(&amp;#039;align-center-11 align-center-12 align-left-13 align-left-14&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    p.header(tbl, ba[&amp;#039;verbose&amp;#039;])&lt;br /&gt;
&lt;br /&gt;
    -- Render rows&lt;br /&gt;
    local storedavgdata = {}&lt;br /&gt;
    for e, entry in ipairs(data) do&lt;br /&gt;
        local name = mw.text.split(entry[&amp;#039;name&amp;#039;], &amp;#039;#&amp;#039;, true)&lt;br /&gt;
        --we save up smw queries for performance, e.g. all barbarians in generic barbarian drop table get the same results so they are computed once.&lt;br /&gt;
        local avgdata = storedavgdata[name[1]] or avg.getDropData({entry[&amp;#039;name&amp;#039;]})&lt;br /&gt;
        --fallback case for average drop value&lt;br /&gt;
        if (not avgdata) or avgdata == {} or avgdata == &amp;#039;&amp;#039; then&lt;br /&gt;
        	avgdata = avg.getDropData({name[1]}) or {}&lt;br /&gt;
        	storedavgdata[name[1]] = avgdata&lt;br /&gt;
        end&lt;br /&gt;
        if name[2] then&lt;br /&gt;
        	name[2] = name[2]:gsub(&amp;#039;_&amp;#039;, &amp;#039; &amp;#039;)&lt;br /&gt;
        else name[2] = &amp;#039;&amp;amp;nbsp;&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
        local tr = tbl:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
            :tag(&amp;#039;td&amp;#039;):css(&amp;#039;height&amp;#039;, &amp;#039;64px&amp;#039;):wikitext(entry[&amp;#039;image&amp;#039;] and string.format(&amp;#039;[[%s|link=|64x64px|%s]]&amp;#039;, entry[&amp;#039;image&amp;#039;], entry[&amp;#039;name&amp;#039;]) or &amp;#039;&amp;#039;):done()&lt;br /&gt;
            :tag(&amp;#039;td&amp;#039;):wikitext(string.format(&amp;#039;[[%s|%s]]&amp;lt;br/&amp;gt;\&amp;#039;\&amp;#039;%s\&amp;#039;\&amp;#039;&amp;#039;, entry[&amp;#039;name&amp;#039;], name[1], name[2])):done()&lt;br /&gt;
            :tag(&amp;#039;td&amp;#039;):wikitext(entry[&amp;#039;members&amp;#039;] and &amp;#039;[[File:Member icon.png|link=|Members]]&amp;#039; or &amp;#039;[[File:Free-to-play icon.png|link=|Free-to-play]]&amp;#039;):done()&lt;br /&gt;
            :tag(&amp;#039;td&amp;#039;):wikitext(entry[&amp;#039;level&amp;#039;]):done()&lt;br /&gt;
            :tag(&amp;#039;td&amp;#039;):wikitext(entry[&amp;#039;hitpoints&amp;#039;]):done()&lt;br /&gt;
            :tag(&amp;#039;td&amp;#039;):wikitext(entry[&amp;#039;attack&amp;#039;]):done()&lt;br /&gt;
            :tag(&amp;#039;td&amp;#039;):wikitext(entry[&amp;#039;defence&amp;#039;]):done()&lt;br /&gt;
            :tag(&amp;#039;td&amp;#039;):wikitext(entry[&amp;#039;magic&amp;#039;]):done()&lt;br /&gt;
            :tag(&amp;#039;td&amp;#039;):wikitext(entry[&amp;#039;ranged&amp;#039;]):done()&lt;br /&gt;
            :tag(&amp;#039;td&amp;#039;):wikitext(curr(avg.totalvalfromdata(avgdata), &amp;#039;coins&amp;#039;)):done()&lt;br /&gt;
            &lt;br /&gt;
        if ba[&amp;#039;verbose&amp;#039;] then&lt;br /&gt;
            tr:tag(&amp;#039;td&amp;#039;):wikitext(entry[&amp;#039;slaylvl&amp;#039;] or &amp;#039;1&amp;#039;):done()&lt;br /&gt;
              :tag(&amp;#039;td&amp;#039;):wikitext(entry[&amp;#039;slayxp&amp;#039;]):done()&lt;br /&gt;
              :tag(&amp;#039;td&amp;#039;):wikitext(entry[&amp;#039;slaycat&amp;#039;]):done()&lt;br /&gt;
&lt;br /&gt;
            local td = tr:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
            for a, ab in ipairs(entry[&amp;#039;assignedby&amp;#039;]) do&lt;br /&gt;
                if enum.contains(slayer_masters, ab) then&lt;br /&gt;
                    td:wikitext(string.format(&amp;#039;[[File:%s chathead.png|48x64px|link=%s]]&amp;#039;, ab, ab))&lt;br /&gt;
                else&lt;br /&gt;
                    mw.log(string.format(&amp;#039;unknown slayer master: %s&amp;#039;, ab))&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return div&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Estimate the storage size of a serialized table of data&lt;br /&gt;
-- This function assumes somewhat consistent sizes of the elements&lt;br /&gt;
-- like for instance typical SMW data tables&lt;br /&gt;
function p.est_serial_size(tbl, datapoints)&lt;br /&gt;
    assert(type(tbl) == &amp;#039;table&amp;#039;)&lt;br /&gt;
    assert(type(datapoints) == &amp;#039;number&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    local dp = {}&lt;br /&gt;
&lt;br /&gt;
    for p = 1, datapoints do&lt;br /&gt;
        local pos = math.floor(#tbl * p / datapoints)&lt;br /&gt;
        local txt = mw.text.jsonEncode(tbl[pos])&lt;br /&gt;
        table.insert(dp, txt:len())&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local avgsize = math.floor(enum.sum(dp) / datapoints)&lt;br /&gt;
&lt;br /&gt;
    return #tbl * avgsize&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Filter data with exclusion lists&lt;br /&gt;
function p.filterData(indata, disco, quest, dmm, cache)&lt;br /&gt;
    -- Fetch exclusion list&lt;br /&gt;
    local exlist = {}&lt;br /&gt;
&lt;br /&gt;
    if not disco then&lt;br /&gt;
        table.insert(exlist, &amp;#039;[[Category:Monsters]] [[Category:Discontinued content]]&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
    if not quest then&lt;br /&gt;
        table.insert(exlist, &amp;#039;[[Category:Quest monsters]]&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
    if not dmm then&lt;br /&gt;
        table.insert(exlist, &amp;#039;[[Category:Monsters]] [[Category:Deadman Mode]]&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
    if not cache then&lt;br /&gt;
        table.insert(exlist, &amp;#039;[[Category:Monsters]] [[Category:Pages using information from game APIs or cache]]&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local pages_excl = pageswithcats(exlist)&lt;br /&gt;
&lt;br /&gt;
    -- Post-process the data&lt;br /&gt;
    local data = {}&lt;br /&gt;
&lt;br /&gt;
    for _, entry in ipairs(indata) do&lt;br /&gt;
        local process = true&lt;br /&gt;
&lt;br /&gt;
        if enum.contains(pages_excl, entry[&amp;#039;variantof&amp;#039;]) or enum.contains(pages_excl, entry[&amp;#039;name&amp;#039;]) then&lt;br /&gt;
            process = false&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        if process then&lt;br /&gt;
            table.insert(data, entry)&lt;br /&gt;
        else&lt;br /&gt;
            --mw.log(string.format(&amp;#039;Removed: %s&amp;#039;, entry[1]))&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Statistics&lt;br /&gt;
    mw.log(string.format(&amp;#039;Filter: exclusion list size: %i, start size: %i, end size: %i, removed %i.&amp;#039;, &lt;br /&gt;
        #pages_excl, #indata, #data, #indata - #data))&lt;br /&gt;
&lt;br /&gt;
    return data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Sends a query to SMW and returns the data&lt;br /&gt;
function p.loadData(fromlevel, tolevel, fromletter, toletter, levelselect, mems, slayeronly, onlycat, attribute, assignedby, verbose)&lt;br /&gt;
    local props = {&lt;br /&gt;
        [&amp;#039;Image&amp;#039;]             = &amp;#039;image&amp;#039;,&lt;br /&gt;
        [&amp;#039;Is members only&amp;#039;]   = &amp;#039;members&amp;#039;,&lt;br /&gt;
        [&amp;#039;Combat level&amp;#039;]      = &amp;#039;level&amp;#039;,&lt;br /&gt;
        [&amp;#039;Hitpoints&amp;#039;]         = &amp;#039;hitpoints&amp;#039;,&lt;br /&gt;
        [&amp;#039;Attack level&amp;#039;]      = &amp;#039;attack&amp;#039;,&lt;br /&gt;
        [&amp;#039;Defence level&amp;#039;]     = &amp;#039;defence&amp;#039;,&lt;br /&gt;
        [&amp;#039;Magic level&amp;#039;]       = &amp;#039;magic&amp;#039;,&lt;br /&gt;
        [&amp;#039;Ranged level&amp;#039;]      = &amp;#039;ranged&amp;#039;,&lt;br /&gt;
        [&amp;#039;Is variant of&amp;#039;]     = &amp;#039;variantof&amp;#039;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    local extprops = {&lt;br /&gt;
        [&amp;#039;Slayer level&amp;#039;]      = &amp;#039;slaylvl&amp;#039;,&lt;br /&gt;
        [&amp;#039;Slayer experience&amp;#039;] = &amp;#039;slayxp&amp;#039;,&lt;br /&gt;
        [&amp;#039;Slayer category&amp;#039;]   = &amp;#039;slaycat&amp;#039;,&lt;br /&gt;
        [&amp;#039;Assigned by&amp;#039;]       = &amp;#039;assignedby&amp;#039;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    local query = {}&lt;br /&gt;
&lt;br /&gt;
    -- Conditions part of query&lt;br /&gt;
    local condition = { &amp;#039;[[Uses infobox::Monster]]&amp;#039; }&lt;br /&gt;
    if mems == &amp;#039;Members&amp;#039; then&lt;br /&gt;
        table.insert(condition, &amp;#039; [[Is members only::true]]&amp;#039;)&lt;br /&gt;
    elseif mems == &amp;#039;F2P&amp;#039; then&lt;br /&gt;
        table.insert(condition, &amp;#039; [[Is members only::false]]&amp;#039;)&lt;br /&gt;
    end&lt;br /&gt;
    if onlycat:len() &amp;gt; 0 or slayeronly then&lt;br /&gt;
        if onlycat:len() &amp;gt; 0 then&lt;br /&gt;
            table.insert(condition, string.format(&amp;#039; [[Slayer category::%s]]&amp;#039;, onlycat))&lt;br /&gt;
        else&lt;br /&gt;
            table.insert(condition, &amp;#039; [[Slayer category::+]]&amp;#039;)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if attribute:len() &amp;gt; 0 then&lt;br /&gt;
        table.insert(condition, string.format(&amp;#039; [[Monster attribute::%s]]&amp;#039;, attribute))&lt;br /&gt;
    end&lt;br /&gt;
    if assignedby:len() &amp;gt; 0 then&lt;br /&gt;
        table.insert(condition, string.format(&amp;#039; [[Assigned by::%s]]&amp;#039;, assignedby))&lt;br /&gt;
    end&lt;br /&gt;
    if levelselect then&lt;br /&gt;
        table.insert(condition, string.format(&amp;#039; [[Combat level::≥%i]] [[Combat level::≤%i]]&amp;#039;, fromlevel, tolevel))&lt;br /&gt;
    else&lt;br /&gt;
        if (toletter == &amp;#039;Z&amp;#039;) then&lt;br /&gt;
            table.insert(condition, string.format(&amp;#039; [[Name::≥%s]]&amp;#039;, fromletter))&lt;br /&gt;
        else&lt;br /&gt;
            table.insert(condition, string.format(&amp;#039; [[Name::≥%s]] [[Name::&amp;lt;&amp;lt;%s]]&amp;#039;, fromletter, string.char(toletter:byte() + 1)))&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    table.insert(query, table.concat(condition))&lt;br /&gt;
&lt;br /&gt;
    -- Printouts part of query&lt;br /&gt;
    table.insert(query, &amp;#039;?=#-&amp;#039;)&lt;br /&gt;
    for k, pr in pairs(props) do&lt;br /&gt;
        table.insert(query, string.format(&amp;#039;?%s #- = %s&amp;#039;, k, pr))&lt;br /&gt;
    end&lt;br /&gt;
    if verbose then&lt;br /&gt;
        for k, pr in pairs(extprops) do&lt;br /&gt;
            table.insert(query, string.format(&amp;#039;?%s #- = %s&amp;#039;, k, pr))&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Parameters part of query&lt;br /&gt;
    query.offset = 0&lt;br /&gt;
    query.limit = verbose and 500 or 580&lt;br /&gt;
&lt;br /&gt;
    -- Fetch the data&lt;br /&gt;
    -- mw.logObject(query)&lt;br /&gt;
    local t1 = os.clock()&lt;br /&gt;
    local smw = mw.smw.ask(query)&lt;br /&gt;
    local t2 = os.clock()&lt;br /&gt;
    if not smw or #smw == 0 then&lt;br /&gt;
        smw = {}&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Post-process the data&lt;br /&gt;
    local data = {}&lt;br /&gt;
&lt;br /&gt;
    for _, entry in ipairs(smw) do&lt;br /&gt;
        local dataline = entry&lt;br /&gt;
&lt;br /&gt;
        dataline[&amp;#039;name&amp;#039;] = dataline[1]&lt;br /&gt;
        dataline[1] = nil&lt;br /&gt;
        if type(dataline[&amp;#039;image&amp;#039;]) == &amp;#039;table&amp;#039; then&lt;br /&gt;
            dataline[&amp;#039;image&amp;#039;] = dataline[&amp;#039;image&amp;#039;][1]&lt;br /&gt;
        end&lt;br /&gt;
        if type(dataline[&amp;#039;slaycat&amp;#039;]) == &amp;#039;table&amp;#039; then&lt;br /&gt;
            dataline[&amp;#039;slaycat&amp;#039;] = table.concat(entry[&amp;#039;slaycat&amp;#039;], &amp;#039;, &amp;#039;)&lt;br /&gt;
        end&lt;br /&gt;
        if type(dataline[&amp;#039;assignedby&amp;#039;]) == &amp;#039;string&amp;#039; then&lt;br /&gt;
            dataline[&amp;#039;assignedby&amp;#039;] = { entry[&amp;#039;assignedby&amp;#039;] }&lt;br /&gt;
        elseif type(dataline[&amp;#039;assignedby&amp;#039;]) == &amp;#039;nil&amp;#039; then&lt;br /&gt;
            dataline[&amp;#039;assignedby&amp;#039;] = { }&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        table.insert(data, dataline)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Statistics&lt;br /&gt;
    smwstats = {&lt;br /&gt;
        offset  = query.offset,&lt;br /&gt;
        limit   = query.limit,&lt;br /&gt;
        found   = #smw,&lt;br /&gt;
        time    = (t2 - t1) * 1000,&lt;br /&gt;
        size    = p.est_serial_size(smw, 5)&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mw.log(string.format(&amp;#039;SMW: Found %i, offset %i, limit %i, time elapsed %.3f ms, est. serial size: %.0f KiB.&amp;#039;, &lt;br /&gt;
        smwstats.found, smwstats.offset, smwstats.limit, smwstats.time, smwstats.size / 1024))&lt;br /&gt;
&lt;br /&gt;
    return data&lt;br /&gt;
end    &lt;br /&gt;
&lt;br /&gt;
--[[ DEBUG COPYPASTA&lt;br /&gt;
mw.logObject( p.loadData(&amp;#039;1&amp;#039;, &amp;#039;1&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, true, &amp;#039;All&amp;#039;, false, &amp;#039;&amp;#039;, &amp;#039;&amp;#039;, &amp;#039;&amp;#039;, false) )&lt;br /&gt;
mw.logObject( p.loadData(&amp;#039;1&amp;#039;, &amp;#039;1&amp;#039;, &amp;#039;A&amp;#039;, &amp;#039;A&amp;#039;, false, &amp;#039;All&amp;#039;, false, &amp;#039;&amp;#039;, &amp;#039;&amp;#039;, &amp;#039;&amp;#039;, false) )&lt;br /&gt;
= p._main({fromlevel=&amp;#039;1&amp;#039;, tolevel=&amp;#039;1&amp;#039;, verbose=&amp;#039;yes&amp;#039;})&lt;br /&gt;
= p._main({fromletter=&amp;#039;A&amp;#039;, toletter=&amp;#039;A&amp;#039;, levelselect=&amp;#039;no&amp;#039;, levelsort=&amp;#039;no&amp;#039;, verbose=&amp;#039;yes&amp;#039;})&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Alex</name></author>
	</entry>
</feed>