<?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%3AStore_locations_list</id>
	<title>Module:Store locations list - 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%3AStore_locations_list"/>
	<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Store_locations_list&amp;action=history"/>
	<updated>2026-04-30T12:36:41Z</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:Store_locations_list&amp;diff=34281&amp;oldid=prev</id>
		<title>Alex: Created page with &quot;-- &lt;pre&gt; local p = {}  local commas = require(&quot;Module:Addcommas&quot;)._add local params = require(&#039;Module:Paramtest&#039;) local yesNo = require(&quot;Module:Yesno&quot;) local currencyImage = require(&quot;Module:Currency Image&quot;) local purge = require(&quot;Module:Purge&quot;)._purge  local p2pIcon = &#039;alt=Members&#039; local f2pIcon = &#039;alt=Free-to-play&#039;  function p.main(frame)     return p._main(frame:getParent().args) end...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Store_locations_list&amp;diff=34281&amp;oldid=prev"/>
		<updated>2024-10-16T00:15:05Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;-- &amp;lt;pre&amp;gt; local p = {}  local commas = require(&amp;quot;Module:Addcommas&amp;quot;)._add local params = require(&amp;#039;Module:Paramtest&amp;#039;) local yesNo = require(&amp;quot;Module:Yesno&amp;quot;) local currencyImage = require(&amp;quot;Module:Currency Image&amp;quot;) local purge = require(&amp;quot;Module:Purge&amp;quot;)._purge  local p2pIcon = &amp;#039;&lt;a href=&quot;/w/File:Member_icon.png&quot; title=&quot;File:Member icon.png&quot;&gt;link=Members|alt=Members&lt;/a&gt;&amp;#039; local f2pIcon = &amp;#039;&lt;a href=&quot;/w/File:Free-to-play_icon.png&quot; title=&quot;File:Free-to-play icon.png&quot;&gt;link=Free-to-play|alt=Free-to-play&lt;/a&gt;&amp;#039;  function p.main(frame)     return p._main(frame:getParent().args) end...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- &amp;lt;pre&amp;gt;&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local commas = require(&amp;quot;Module:Addcommas&amp;quot;)._add&lt;br /&gt;
local params = require(&amp;#039;Module:Paramtest&amp;#039;)&lt;br /&gt;
local yesNo = require(&amp;quot;Module:Yesno&amp;quot;)&lt;br /&gt;
local currencyImage = require(&amp;quot;Module:Currency Image&amp;quot;)&lt;br /&gt;
local purge = require(&amp;quot;Module:Purge&amp;quot;)._purge&lt;br /&gt;
&lt;br /&gt;
local p2pIcon = &amp;#039;[[File:Member icon.png|link=Members|alt=Members]]&amp;#039;&lt;br /&gt;
local f2pIcon = &amp;#039;[[File:Free-to-play icon.png|link=Free-to-play|alt=Free-to-play]]&amp;#039;&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
    return p._main(frame:getParent().args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
    local item, limit = params.defaults{&lt;br /&gt;
                            {args[1], mw.title.getCurrentTitle().text},&lt;br /&gt;
                            {args.Limit, 500}&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
    -- Create the header of the output&lt;br /&gt;
    local restbl = mw.html.create(&amp;#039;table&amp;#039;)&lt;br /&gt;
    restbl:addClass(&amp;#039;wikitable sortable autosort=1,a align-center-3 align-center-4 align-center-5 align-center-6 align-center-7 align-center-8 store-locations-list&amp;#039;)&lt;br /&gt;
        :tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
            :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Seller&amp;#039;):done()&lt;br /&gt;
            :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Location&amp;#039;):done()&lt;br /&gt;
            :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Number&amp;lt;br/&amp;gt;in stock&amp;#039;):attr(&amp;#039;data-sort-type&amp;#039;, &amp;#039;number&amp;#039;):done()&lt;br /&gt;
            :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Restock&amp;lt;br/&amp;gt;time&amp;#039;):attr(&amp;#039;data-sort-type&amp;#039;, &amp;#039;number&amp;#039;):done()&lt;br /&gt;
            :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Price&amp;lt;br/&amp;gt;sold at&amp;#039;):attr(&amp;#039;data-sort-type&amp;#039;, &amp;#039;number&amp;#039;):done()&lt;br /&gt;
            :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Price&amp;lt;br/&amp;gt;bought at&amp;#039;):attr(&amp;#039;data-sort-type&amp;#039;, &amp;#039;number&amp;#039;):done()&lt;br /&gt;
            :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Change&amp;lt;br/&amp;gt;Per&amp;#039;):attr(&amp;#039;data-sort-type&amp;#039;, &amp;#039;number&amp;#039;):done()&lt;br /&gt;
            :tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Members&amp;#039;):done()&lt;br /&gt;
        :done()&lt;br /&gt;
&lt;br /&gt;
    -- Get parsed smw data&lt;br /&gt;
    mw.log(string.format(&amp;#039;Searching for shops that sell: %s&amp;#039;, item))&lt;br /&gt;
    local data = p.getData(item, limit)&lt;br /&gt;
    -- Create the rows for the output table&lt;br /&gt;
    for _, shop in ipairs(data) do&lt;br /&gt;
&lt;br /&gt;
        local shopVersionValues = shop.shopVersion or { &amp;#039;&amp;#039; }&lt;br /&gt;
        if type(shopVersionValues) == &amp;#039;string&amp;#039; then&lt;br /&gt;
            shopVersionValues = { shopVersionValues }&lt;br /&gt;
        end&lt;br /&gt;
        for i, shopVersion in ipairs(shopVersionValues) do&lt;br /&gt;
            local curVersionSeller = shop.seller&lt;br /&gt;
&lt;br /&gt;
            local notetext = shopVersion&lt;br /&gt;
            if shop.namenotes ~= &amp;#039;&amp;#039; then&lt;br /&gt;
                notetext = shop.namenotes&lt;br /&gt;
            end&lt;br /&gt;
            if notetext ~= &amp;#039;&amp;#039; then&lt;br /&gt;
                curVersionSeller = curVersionSeller..&amp;#039; &amp;lt;span class=&amp;quot;shop-version&amp;quot;&amp;gt;&amp;#039;..notetext..&amp;#039;&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            local membersValues = shop.members or {}&lt;br /&gt;
            local curMembers = membersValues&lt;br /&gt;
            if type(membersValues) == &amp;#039;table&amp;#039; then&lt;br /&gt;
                curMembers = membersValues[i] or membersValues[1] or &amp;#039;&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
            if curMembers == &amp;#039;&amp;#039; then&lt;br /&gt;
            	curMembers = &amp;#039;[[Category:Store locations list with empty members]]&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
            local locationValues = shop.location or {}&lt;br /&gt;
            local curLocation = locationValues&lt;br /&gt;
            if type(locationValues) == &amp;#039;table&amp;#039; then&lt;br /&gt;
                curLocation = locationValues[i] or locationValues[1] or &amp;#039;&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
            if curLocation == &amp;#039;&amp;#039; then&lt;br /&gt;
            	curLocation = &amp;#039;[[Category:Store locations list with empty location]]&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            restbl:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
                :tag(&amp;#039;td&amp;#039;):wikitext(curVersionSeller):done()&lt;br /&gt;
                :tag(&amp;#039;td&amp;#039;):wikitext(curLocation):done()&lt;br /&gt;
                :tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
                    :attr({[&amp;#039;data-sort-value&amp;#039;]=shop.stockSortValue})&lt;br /&gt;
                    :wikitext(shop.stock)&lt;br /&gt;
                :done()&lt;br /&gt;
                :tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
                    :attr({[&amp;#039;data-sort-value&amp;#039;]=shop.restockSortValue})&lt;br /&gt;
                    :wikitext(shop.restock)&lt;br /&gt;
                :done()&lt;br /&gt;
                :tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
                    :attr({[&amp;#039;data-sort-value&amp;#039;]=shop.sellSortValue})&lt;br /&gt;
                    :wikitext(shop.sellvalue)&lt;br /&gt;
                :done()&lt;br /&gt;
                :tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
                    :attr({[&amp;#039;data-sort-value&amp;#039;]=shop.buySortValue})&lt;br /&gt;
                    :wikitext(shop.buyvalue)&lt;br /&gt;
                :done()&lt;br /&gt;
                :tag(&amp;#039;td&amp;#039;):wikitext(shop.delta):done()&lt;br /&gt;
                :tag(&amp;#039;td&amp;#039;):wikitext(membersTextToIcon(curMembers)):done()&lt;br /&gt;
            :done()&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return tostring(restbl)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getData(itemName, limit)&lt;br /&gt;
    -- Query smw&lt;br /&gt;
    local q = {&lt;br /&gt;
        &amp;#039;[[Sold item text::&amp;#039;..itemName..&amp;#039;]]&amp;#039;,&lt;br /&gt;
        &amp;#039;?Sold item JSON&amp;#039;,&lt;br /&gt;
        limit = limit,&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    local t1 = os.clock()&lt;br /&gt;
    local smwdata = mw.smw.ask(q)&lt;br /&gt;
    local t2 = os.clock()&lt;br /&gt;
&lt;br /&gt;
    if smwdata == nil then&lt;br /&gt;
        error(&amp;#039;The item &amp;quot;&amp;#039; .. itemName .. &amp;#039;&amp;quot; is not sold in any shop, please check for typos[[Category:Empty store lists]]&amp;#039;, 0)&lt;br /&gt;
    end&lt;br /&gt;
    mw.log(string.format(&amp;#039;SMW (store locations list): entries: %d, time elapsed: %.3f ms.&amp;#039;, #smwdata, (t2 - t1) * 1000))&lt;br /&gt;
&lt;br /&gt;
    -- Iterate through each shop instance of item&lt;br /&gt;
    local data = {}&lt;br /&gt;
    for _, item in ipairs(smwdata) do&lt;br /&gt;
        local soldItemJSON = mw.text.jsonDecode(item[&amp;#039;Sold item JSON&amp;#039;] or &amp;#039;{}&amp;#039;)&lt;br /&gt;
        local dataline = p.processData(soldItemJSON)&lt;br /&gt;
        table.insert(data, dataline)&lt;br /&gt;
    end&lt;br /&gt;
    return data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.processData(item)&lt;br /&gt;
    local seller = item[&amp;#039;Sold by&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
    if not seller:match(&amp;#039;^%[%[&amp;#039;) then&lt;br /&gt;
        seller = &amp;#039;[[&amp;#039;..seller..&amp;#039;]]&amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local delta = string.format(&amp;#039;[[Store price delta::%.1f]]%%&amp;#039;,(item[&amp;#039;Store delta&amp;#039;] or 10)/10)&lt;br /&gt;
&lt;br /&gt;
    local region = item[&amp;#039;Region&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
    local stock = item[&amp;#039;Store stock&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
    local stockSortValue = 0&lt;br /&gt;
    if stock == &amp;#039;∞&amp;#039; then&lt;br /&gt;
        stock = &amp;#039;&amp;lt;span style=&amp;quot;font-size:120%;&amp;quot;&amp;gt;∞&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
        stockSortValue = &amp;#039;10e50&amp;#039;&lt;br /&gt;
    elseif stock == &amp;#039;N/A&amp;#039; then&lt;br /&gt;
        stockSortValue = &amp;#039;10e99&amp;#039;&lt;br /&gt;
    else&lt;br /&gt;
        stock = tonumber(stock)&lt;br /&gt;
        if stock then&lt;br /&gt;
            stockSortValue = stock&lt;br /&gt;
            stock = commas(stock)&lt;br /&gt;
        else&lt;br /&gt;
            stock = &amp;#039;&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local restock = item[&amp;#039;Restock time&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
    local restockSortValue = 0&lt;br /&gt;
    if restock == &amp;#039;N/A&amp;#039; then&lt;br /&gt;
        restockSortValue = &amp;#039;10e99&amp;#039;&lt;br /&gt;
    else&lt;br /&gt;
        restock = tonumber(restock)&lt;br /&gt;
        if restock then&lt;br /&gt;
            restockSortValue = restock&lt;br /&gt;
            restock = ticktime(restock)&lt;br /&gt;
        else&lt;br /&gt;
            restock = &amp;#039;&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local currency = item[&amp;#039;Store currency&amp;#039;]&lt;br /&gt;
&lt;br /&gt;
    local sellvalue = item[&amp;#039;Store sell price&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
    local sellSortValue = 0&lt;br /&gt;
    if not (sellvalue == 1e10) then&lt;br /&gt;
        sellvalue = tonumber(sellvalue)&lt;br /&gt;
        if sellvalue then&lt;br /&gt;
            sellSortValue = sellvalue&lt;br /&gt;
            sellvalue = commas(sellvalue)&lt;br /&gt;
            local currencyImg = currencyImage(currency, sellSortValue) or &amp;#039;&amp;#039;&lt;br /&gt;
            if params.has_content(currencyImg) then&lt;br /&gt;
                currencyImg = string.format(&amp;#039;[[File:%s|link=%s]] &amp;#039;, currencyImg, currency)&lt;br /&gt;
                sellvalue = currencyImg .. sellvalue&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            sellvalue = &amp;#039;&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        sellSortValue = sellvalue&lt;br /&gt;
        sellvalue = &amp;#039;N/A&amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local buyvalue = item[&amp;#039;Store buy price&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
    local buySortValue = 0&lt;br /&gt;
    if not (buyvalue == &amp;#039;N/A&amp;#039;) then&lt;br /&gt;
        buyvalue = tonumber(buyvalue)&lt;br /&gt;
        if buyvalue then&lt;br /&gt;
            buySortValue = buyvalue&lt;br /&gt;
            buyvalue = commas(buyvalue)&lt;br /&gt;
            local currencyImg = currencyImage(currency, buySortValue) or &amp;#039;&amp;#039;&lt;br /&gt;
            if params.has_content(currencyImg) then&lt;br /&gt;
                currencyImg = string.format(&amp;#039;[[File:%s|link=%s]] &amp;#039;, currencyImg, currency)&lt;br /&gt;
                buyvalue = currencyImg .. buyvalue&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            buyvalue = &amp;#039;&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return {&lt;br /&gt;
        seller = seller,&lt;br /&gt;
        region = region,&lt;br /&gt;
        stock = stock,&lt;br /&gt;
        stockSortValue = stockSortValue,&lt;br /&gt;
        restock = restock,&lt;br /&gt;
        restockSortValue = restockSortValue,&lt;br /&gt;
        sellvalue = sellvalue,&lt;br /&gt;
        sellSortValue = sellSortValue,&lt;br /&gt;
        buyvalue = buyvalue,&lt;br /&gt;
        buySortValue = buySortValue,&lt;br /&gt;
        delta = delta,&lt;br /&gt;
        namenotes = item[&amp;#039;Store notes&amp;#039;] or &amp;#039;&amp;#039;,&lt;br /&gt;
        location = item[&amp;#039;Location&amp;#039;],&lt;br /&gt;
        members = item[&amp;#039;Members&amp;#039;],&lt;br /&gt;
        shopVersion = item[&amp;#039;Shop version&amp;#039;],&lt;br /&gt;
    }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ticktime(ticks)&lt;br /&gt;
    if ticks==-1 then&lt;br /&gt;
        return &amp;#039;unknown&amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
    local ret = &amp;#039;&amp;#039;&lt;br /&gt;
    local days = math.floor(ticks/144000)&lt;br /&gt;
    local hours = math.floor(ticks%144000/6000)&lt;br /&gt;
    local minutes = math.floor(ticks%6000/100)&lt;br /&gt;
    local seconds = ticks%100*0.6&lt;br /&gt;
    if days &amp;gt; 0 then&lt;br /&gt;
        ret = ret .. days .. &amp;#039;d &amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
    if hours &amp;gt; 0 then&lt;br /&gt;
        ret = ret .. hours .. &amp;#039;h &amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
    if minutes &amp;gt; 0 then&lt;br /&gt;
        ret = ret .. minutes .. &amp;#039;m &amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
    if seconds &amp;gt; 0 then&lt;br /&gt;
        ret = ret .. seconds .. &amp;#039;s&amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
    return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function membersTextToIcon(text)&lt;br /&gt;
    local lower = string.lower(text or &amp;#039;&amp;#039;)&lt;br /&gt;
    local hasYes = string.match(lower, &amp;#039;yes&amp;#039;)&lt;br /&gt;
    local hasNo = string.match(lower, &amp;#039;no&amp;#039;)&lt;br /&gt;
    if hasYes and hasNo then&lt;br /&gt;
        return f2pIcon..&amp;#039;/&amp;#039;..p2pIcon&lt;br /&gt;
    elseif hasYes then&lt;br /&gt;
        return p2pIcon&lt;br /&gt;
    elseif hasNo then&lt;br /&gt;
        return f2pIcon&lt;br /&gt;
    end&lt;br /&gt;
    return &amp;#039;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Alex</name></author>
	</entry>
</feed>