<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.funkystation.org/index.php?action=history&amp;feed=atom&amp;title=Module%3AItem</id>
	<title>Module:Item - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.funkystation.org/index.php?action=history&amp;feed=atom&amp;title=Module%3AItem"/>
	<link rel="alternate" type="text/html" href="https://wiki.funkystation.org/index.php?title=Module:Item&amp;action=history"/>
	<updated>2026-06-05T00:21:00Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.42.3</generator>
	<entry>
		<id>https://wiki.funkystation.org/index.php?title=Module:Item&amp;diff=202&amp;oldid=prev</id>
		<title>imported&gt;Aliser: added a function for ID lookups by name overrides, which will provide proper errors on fails (instead of direct lookups which fail silently, causing a bug somewhere further down the line, requiring an hour and a half of debugging and pulling hair out RAAAAAAA); unified most lookup functions docs</title>
		<link rel="alternate" type="text/html" href="https://wiki.funkystation.org/index.php?title=Module:Item&amp;diff=202&amp;oldid=prev"/>
		<updated>2024-09-15T11:22:08Z</updated>

		<summary type="html">&lt;p&gt;added a function for ID lookups by name overrides, which will provide proper errors on fails (instead of direct lookups which fail silently, causing a bug somewhere further down the line, requiring an hour and a half of debugging and pulling hair out RAAAAAAA); unified most lookup functions docs&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Contains utilities for working with in-game items.&lt;br /&gt;
&lt;br /&gt;
-- todo create external tests for schema tables (under /doc)&lt;br /&gt;
-- todo make `generate_list_of_all_items_with_icons` also display items with nontrivial image files&lt;br /&gt;
&lt;br /&gt;
local p = {} --p stands for package&lt;br /&gt;
local getArgs = require(&amp;#039;Module:Arguments&amp;#039;).getArgs&lt;br /&gt;
local yesNo = require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
-- A table mapping item IDs to their names.&lt;br /&gt;
-- Keys are item IDs; each value is a string.&lt;br /&gt;
--&lt;br /&gt;
-- These names are used for labels.&lt;br /&gt;
-- This table will be updated automatically, DO NOT make manual changes to it - they will be lost.&lt;br /&gt;
local item_names_by_item_ids = mw.loadJsonData(&amp;quot;Module:Item/item names by item ids.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- A table mapping item names to their IDs.&lt;br /&gt;
-- Keys are item names; each value is an item ID.&lt;br /&gt;
-- An item can have multiple names.&lt;br /&gt;
--&lt;br /&gt;
-- These names are used for ID lookups.&lt;br /&gt;
-- This table will be updated automatically, DO NOT make manual changes to it - they will be lost.&lt;br /&gt;
local item_ids_by_item_names = mw.loadJsonData(&amp;quot;Module:Item/item ids by item lowercase names.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- Same as `item_ids_by_item_names`, but has a higher priority&lt;br /&gt;
-- and meant to be filled manually.&lt;br /&gt;
--&lt;br /&gt;
-- These names are used for ID lookups.&lt;br /&gt;
local item_ids_by_item_names_override = mw.loadJsonData(&amp;quot;Module:Item/item ids by item lowercase names overrides.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- A table mapping item IDs to their image files.&lt;br /&gt;
-- Keys are item IDs; each value is a file name or an object (for items with multiple textures).&lt;br /&gt;
--&lt;br /&gt;
-- Meant to be filled manually.&lt;br /&gt;
--&lt;br /&gt;
-- These are used to display item icons.&lt;br /&gt;
local item_images_by_item_ids = mw.loadJsonData(&amp;quot;Module:Item/item image files by item id.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- A table mapping item IDs to specific pages.&lt;br /&gt;
-- Keys are item IDs; each value is a page name.&lt;br /&gt;
--&lt;br /&gt;
-- Meant to be filled manually.&lt;br /&gt;
--&lt;br /&gt;
-- These are used to turn items into links.&lt;br /&gt;
local item_page_links_by_item_ids = mw.loadJsonData(&amp;quot;Module:Item/item page links by item ids.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- Get a reference to the current frame.&lt;br /&gt;
local current_frame = mw:getCurrentFrame()&lt;br /&gt;
&lt;br /&gt;
-- A boolean that becomes `true` once the template styles for {{Item}} has been added to the page.&lt;br /&gt;
-- Used to not add them a million times for all items generations.&lt;br /&gt;
local was_template_styles_tag_el_added = false&lt;br /&gt;
&lt;br /&gt;
-- =======================&lt;br /&gt;
&lt;br /&gt;
local function numeric_table_length(t)&lt;br /&gt;
    local count = 0&lt;br /&gt;
    for _ in ipairs(t) do count = count + 1 end&lt;br /&gt;
    return count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function table_length(t)&lt;br /&gt;
    local count = 0&lt;br /&gt;
    for _ in pairs(t) do count = count + 1 end&lt;br /&gt;
    return count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function table_has_value(tab, val)&lt;br /&gt;
    for _, value in ipairs(tab) do&lt;br /&gt;
        if value == val then&lt;br /&gt;
            return true&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function assert_value_not_nil(value, error_message)&lt;br /&gt;
    if value == nil then&lt;br /&gt;
        if error_message == nil then&lt;br /&gt;
            error(&amp;quot;value is nil&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
            error(error_message)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Makes the first letter uppercase.&lt;br /&gt;
-- Source: https://stackoverflow.com/a/2421746&lt;br /&gt;
local function capitalize(str)&lt;br /&gt;
    return (str:gsub(&amp;quot;^%l&amp;quot;, string.upper))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function passthrough_assert_true(value, valueToReturnIfTrue, errorMessageOnFalse)&lt;br /&gt;
    if value then&lt;br /&gt;
        return valueToReturnIfTrue&lt;br /&gt;
    else&lt;br /&gt;
        error(errorMessageOnFalse)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- =======================&lt;br /&gt;
&lt;br /&gt;
-- A table of item IDs that were validated for `validate_item_images_by_item_ids_table_entry`..&lt;br /&gt;
local validate_item_images_by_item_ids_table_entry__validated_item_ids = {}&lt;br /&gt;
&lt;br /&gt;
-- Validator for item images table entries.&lt;br /&gt;
--&lt;br /&gt;
-- Used internally for lazilly validating schema of entries.&lt;br /&gt;
--&lt;br /&gt;
-- Once a validation is conducted for an entry, subsequent calls for the same item ID will&lt;br /&gt;
-- not trigger revalidation, thus the lazy part.&lt;br /&gt;
local function validate_item_images_by_item_ids_table_entry(entry, item_id)&lt;br /&gt;
    -- skip validation for already validated entries&lt;br /&gt;
    if validate_item_images_by_item_ids_table_entry__validated_item_ids[item_id] ~= nil then&lt;br /&gt;
        return&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    assert_value_not_nil(entry, &amp;quot;item images json file validation failed: no entry was found with item ID: &amp;quot; .. item_id)&lt;br /&gt;
&lt;br /&gt;
    if type(entry) == &amp;#039;table&amp;#039; then&lt;br /&gt;
        assert_value_not_nil(entry.default,&lt;br /&gt;
            &amp;quot;item images json file validation failed: expected &amp;#039;default&amp;#039; to be defined for item: &amp;quot; .. item_id)&lt;br /&gt;
        assert(type(entry.default) == &amp;quot;string&amp;quot;,&lt;br /&gt;
            &amp;quot;item images json file validation failed: expected &amp;#039;default&amp;#039; to be a string, found &amp;#039;&amp;quot; ..&lt;br /&gt;
            type(entry.default) .. &amp;quot;&amp;#039; for item: &amp;quot; .. item_id)&lt;br /&gt;
&lt;br /&gt;
        local byCondition = entry.byCondition&lt;br /&gt;
        assert_value_not_nil(entry.byCondition,&lt;br /&gt;
            &amp;quot;item images json file validation failed: expected &amp;#039;byCondition&amp;#039; to be defined since &amp;#039;amount&amp;#039; was given; item: &amp;quot; ..&lt;br /&gt;
            item_id)&lt;br /&gt;
        assert(type(entry.byCondition) == &amp;quot;table&amp;quot;,&lt;br /&gt;
            &amp;quot;item images json file validation failed: expected &amp;#039;byCondition&amp;#039; to be a table, found &amp;#039;&amp;quot; ..&lt;br /&gt;
            type(entry.byCondition) .. &amp;quot;&amp;#039; for item: &amp;quot; .. item_id)&lt;br /&gt;
&lt;br /&gt;
        for _, byConditionEntry in ipairs(byCondition) do&lt;br /&gt;
            local entry_type = byConditionEntry.type&lt;br /&gt;
            assert_value_not_nil(entry_type,&lt;br /&gt;
                &amp;quot;item images json file validation failed: expected &amp;#039;type&amp;#039; to be defined on one of &amp;#039;byCondition&amp;#039; entries; item: &amp;quot; ..&lt;br /&gt;
                item_id)&lt;br /&gt;
            assert(type(entry_type) == &amp;quot;string&amp;quot;,&lt;br /&gt;
                &amp;quot;item images json file validation failed: expected &amp;#039;type&amp;#039; to be a string on one of &amp;#039;byCondition&amp;#039; entries, found &amp;#039;&amp;quot; ..&lt;br /&gt;
                type(entry_type) .. &amp;quot;&amp;#039; for item: &amp;quot; .. item_id)&lt;br /&gt;
&lt;br /&gt;
            if entry_type == &amp;#039;amount&amp;#039; then&lt;br /&gt;
                local conditions = byConditionEntry.conditions&lt;br /&gt;
                assert_value_not_nil(conditions,&lt;br /&gt;
                    &amp;quot;item images json file validation failed: expected &amp;#039;conditions&amp;#039; to be defined on one of &amp;#039;byCondition&amp;#039; entries; item: &amp;quot; ..&lt;br /&gt;
                    item_id)&lt;br /&gt;
                assert(type(conditions) == &amp;quot;table&amp;quot;,&lt;br /&gt;
                    &amp;quot;item images json file validation failed: expected &amp;#039;conditions&amp;#039; to be a table on one of &amp;#039;byCondition&amp;#039; entries, found &amp;#039;&amp;quot; ..&lt;br /&gt;
                    type(conditions) .. &amp;quot;&amp;#039; for item: &amp;quot; .. item_id)&lt;br /&gt;
&lt;br /&gt;
                for _, condition in ipairs(conditions) do&lt;br /&gt;
                    local file = condition.file&lt;br /&gt;
                    assert_value_not_nil(file,&lt;br /&gt;
                        &amp;quot;item images json file validation failed: expected &amp;#039;file&amp;#039; in one of &amp;#039;conditions&amp;#039; entries in on one of &amp;#039;byCondition&amp;#039; entries to be defined for item: &amp;quot; ..&lt;br /&gt;
                        item_id)&lt;br /&gt;
&lt;br /&gt;
                    local conditionMin = condition.min&lt;br /&gt;
                    if conditionMin ~= nil then&lt;br /&gt;
                        assert(type(conditionMin) == &amp;quot;number&amp;quot;,&lt;br /&gt;
                            &amp;quot;item images json file validation failed: expected &amp;#039;min&amp;#039; in one of &amp;#039;conditions&amp;#039; entries in on one of &amp;#039;byCondition&amp;#039; entries to be a number, found &amp;#039;&amp;quot; ..&lt;br /&gt;
                            type(condition.min) .. &amp;quot;&amp;#039; for item: &amp;quot; .. item_id)&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            else&lt;br /&gt;
                error(&lt;br /&gt;
                    &amp;quot;item images json file validation failed: expected &amp;#039;type&amp;#039; to be one of known values on one of &amp;#039;byCondition&amp;#039; entries, but found &amp;#039;&amp;quot; ..&lt;br /&gt;
                    entry_type .. &amp;quot;&amp;#039; entries; item: &amp;quot; .. item_id)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    validate_item_images_by_item_ids_table_entry__validated_item_ids[item_id] = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- =======================&lt;br /&gt;
&lt;br /&gt;
-- Lookups item ID by item name override (any casing).&lt;br /&gt;
--&lt;br /&gt;
-- Raises an error if no item name override was found.&lt;br /&gt;
-- Set `no_error` to `true` to return `nil` instead.&lt;br /&gt;
function p.lookup_item_id_by_name_override(item_name_override, no_error)&lt;br /&gt;
    assert_value_not_nil(item_name_override,&lt;br /&gt;
        &amp;quot;item ID lookup by item name override failed: item name override was not provided&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    local item_name_override_lower = string.lower(item_name_override)&lt;br /&gt;
&lt;br /&gt;
    local item_id = item_ids_by_item_names_override[item_name_override_lower]&lt;br /&gt;
    if item_id == nil then&lt;br /&gt;
        if no_error then&lt;br /&gt;
            return nil&lt;br /&gt;
        else&lt;br /&gt;
            error(&amp;quot;item ID lookup by item name override failed: no item name override &amp;#039;&amp;quot; ..&lt;br /&gt;
                item_name_override_lower ..&lt;br /&gt;
                &amp;quot;&amp;#039; was found. Make sure that an override is defined in the item name overrides table of Module:Item&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if not p.item_exists_with_id(item_id) then&lt;br /&gt;
        error(&amp;quot;item ID lookup by item name override failed: item with looked up item ID &amp;#039;&amp;quot; ..&lt;br /&gt;
            item_id .. &amp;quot;&amp;#039; does not exist (item name override: &amp;#039;&amp;quot; ..&lt;br /&gt;
            item_name_override_lower ..&lt;br /&gt;
            &amp;quot;&amp;#039;). Make sure that the name override for this item is defined correctly in Module:Item and the item exist&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return item_id&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Lookups item ID by item name `item_name` (any casing).&lt;br /&gt;
--&lt;br /&gt;
-- Raises an error if no item was found.&lt;br /&gt;
-- Set `no_error` to `true` to return `nil` instead.&lt;br /&gt;
function p.lookup_item_id_by_item_name(item_name, no_error)&lt;br /&gt;
    assert_value_not_nil(item_name, &amp;quot;item ID lookup by item name failed: item name was not provided&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    -- first, try to lookup item name in name overrides&lt;br /&gt;
    return p.lookup_item_id_by_name_override(item_name, true)&lt;br /&gt;
        -- then, look in regular item names&lt;br /&gt;
        or item_ids_by_item_names[string.lower(item_name)]&lt;br /&gt;
        or passthrough_assert_true(&lt;br /&gt;
            no_error,&lt;br /&gt;
            nil,&lt;br /&gt;
            &amp;quot;item ID lookup by item name failed: no item name was found by item ID &amp;#039;&amp;quot; ..&lt;br /&gt;
            item_name .. &amp;quot;&amp;#039;. Make sure that an item exist with this ID or a name override is defined&amp;quot;&lt;br /&gt;
        )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Lookups item ID by query.&lt;br /&gt;
-- Query can either be an item ID (strict casing) or item name (any casing).&lt;br /&gt;
--&lt;br /&gt;
-- Raises an error if no item was found.&lt;br /&gt;
-- Set `no_error` to `true` to return `nil` instead.&lt;br /&gt;
function p.lookup_item_id(query, no_error)&lt;br /&gt;
    assert_value_not_nil(query, &amp;quot;item ID lookup failed: item ID/name (query) was not provided&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if item_names_by_item_ids[query] ~= nil then&lt;br /&gt;
        return query&lt;br /&gt;
    else&lt;br /&gt;
        return p.lookup_item_id_by_item_name(query, true)&lt;br /&gt;
            or passthrough_assert_true(&lt;br /&gt;
                no_error,&lt;br /&gt;
                nil,&lt;br /&gt;
                &amp;quot;item ID lookup failed: no item was found by ID/name &amp;#039;&amp;quot; ..&lt;br /&gt;
                query .. &amp;quot;&amp;#039;. Make sure that an item exist with this ID or a name override is defined&amp;quot;&lt;br /&gt;
            )&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Lookups item name by item ID `item_id` (strict casing).&lt;br /&gt;
--&lt;br /&gt;
-- Raises an error if if no item was found.&lt;br /&gt;
-- Set `no_error` to `true` to return `nil` instead.&lt;br /&gt;
function p.lookup_item_name_by_item_id(item_id, no_error)&lt;br /&gt;
    assert_value_not_nil(item_id, &amp;quot;item name lookup by item ID failed: item ID was not provided&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    return item_names_by_item_ids[item_id]&lt;br /&gt;
        or&lt;br /&gt;
        passthrough_assert_true(&lt;br /&gt;
            no_error,&lt;br /&gt;
            nil,&lt;br /&gt;
            &amp;quot;item name lookup by item ID failed: no item name was found by item ID &amp;#039;&amp;quot; ..&lt;br /&gt;
            item_id .. &amp;quot;&amp;#039;. Make sure that an item exist with this ID or a name override is defined&amp;quot;&lt;br /&gt;
        )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Lookups item name by query.&lt;br /&gt;
-- Query can either be an item ID (strict casing) or item name (any casing).&lt;br /&gt;
--&lt;br /&gt;
-- Raises an error if if no item was found.&lt;br /&gt;
-- Set `no_error` to `true` to return `nil` instead.&lt;br /&gt;
function p.lookup_item_name(query, no_error)&lt;br /&gt;
    assert_value_not_nil(query, &amp;quot;item name lookup failed: item ID/name (query) was not provided&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    local query_lower = string.lower(query)&lt;br /&gt;
&lt;br /&gt;
    if p.lookup_item_id_by_name_override(query, true) ~= nil or item_ids_by_item_names[query_lower] ~= nil then&lt;br /&gt;
        return query&lt;br /&gt;
    else&lt;br /&gt;
        return p.lookup_item_name_by_item_id(query, true)&lt;br /&gt;
            or passthrough_assert_true(&lt;br /&gt;
                no_error,&lt;br /&gt;
                nil,&lt;br /&gt;
                &amp;quot;item name lookup failed: no item was found by ID/name &amp;#039;&amp;quot; ..&lt;br /&gt;
                query .. &amp;quot;&amp;#039;. Make sure that an item exist with this ID or a name override is defined&amp;quot;&lt;br /&gt;
            )&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Checks whether an item exists with name `item_name` (any casing).&lt;br /&gt;
function p.item_exists_with_name(item_name)&lt;br /&gt;
    -- query non-nil assertion is done in the subsequent function call&lt;br /&gt;
&lt;br /&gt;
    return p.lookup_item_id_by_item_name(item_name, true) ~= nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Checks whether an item exists with ID `item_id` (strict casing).&lt;br /&gt;
function p.item_exists_with_id(item_id)&lt;br /&gt;
    -- query non-nil assertion is done in the subsequent function call&lt;br /&gt;
&lt;br /&gt;
    return p.lookup_item_name_by_item_id(item_id, true) ~= nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Checks whether an item exists by query.&lt;br /&gt;
-- Query can either be an item ID (strict casing) or item name (any casing).&lt;br /&gt;
function p.item_exists(query)&lt;br /&gt;
    -- query non-nil assertion is done in the subsequent function calls&lt;br /&gt;
&lt;br /&gt;
    return p.item_exists_with_id(query)&lt;br /&gt;
        or p.item_exists_with_name(query)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Lookups item image by query.&lt;br /&gt;
-- Query can either be an item ID (strict casing) or item name (any casing).&lt;br /&gt;
--&lt;br /&gt;
-- An `amount` can be specified to correctly pick an image for items&lt;br /&gt;
-- with multiple images (depending on the amount). By default, it has no value.&lt;br /&gt;
--&lt;br /&gt;
-- Raises an error if no item was found by `query`.&lt;br /&gt;
--&lt;br /&gt;
-- Returns `nil` if no image is defined for an item.&lt;br /&gt;
function p.try_lookup_item_image(query, amount)&lt;br /&gt;
    local item_id = p.lookup_item_id(query, true)&lt;br /&gt;
    assert_value_not_nil(item_id, &amp;quot;item image lookup failed: no item was found by ID/name &amp;#039;&amp;quot; .. query .. &amp;quot;&amp;#039;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    local item_image = item_images_by_item_ids[item_id]&lt;br /&gt;
    if item_image == nil then&lt;br /&gt;
        return nil&lt;br /&gt;
    elseif type(item_image) == &amp;#039;string&amp;#039; then&lt;br /&gt;
        return item_image&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- if item image &amp;quot;entry&amp;quot; was found and it&amp;#039;s not a string,&lt;br /&gt;
    -- then it must be a config for multiple images.&lt;br /&gt;
    --&lt;br /&gt;
    -- send the &amp;quot;entry&amp;quot; to validation.&lt;br /&gt;
    validate_item_images_by_item_ids_table_entry(item_image, item_id)&lt;br /&gt;
&lt;br /&gt;
    -- if validation was successful with no errors,&lt;br /&gt;
    -- now we can utilize the config schema without doing any checks.&lt;br /&gt;
&lt;br /&gt;
    -- if no amount is specified,&lt;br /&gt;
    -- then there&amp;#039;s no reason to resolve further.&lt;br /&gt;
    -- use the default image file for that config.&lt;br /&gt;
    if amount == nil then&lt;br /&gt;
        return item_image.default&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- if amount is specified, then resolve further&lt;br /&gt;
    for _, byConditionEntry in ipairs(item_image.byCondition) do&lt;br /&gt;
        local entry_type = byConditionEntry.type&lt;br /&gt;
&lt;br /&gt;
        if entry_type == &amp;#039;amount&amp;#039; then&lt;br /&gt;
            local conditions = byConditionEntry.conditions&lt;br /&gt;
&lt;br /&gt;
            for _, condition in ipairs(conditions) do&lt;br /&gt;
                -- currently, there&amp;#039;s a single condition - &amp;quot;min&amp;quot;.&lt;br /&gt;
                -- it might be unset, meaning no other conditions,&lt;br /&gt;
                local conditionMin = condition.min&lt;br /&gt;
                if conditionMin == nil then&lt;br /&gt;
                    -- if this condition is not set, then there&amp;#039;s no other conditions to check.&lt;br /&gt;
                    -- use the file from this condition&lt;br /&gt;
                    return condition.file&lt;br /&gt;
                elseif amount &amp;gt;= conditionMin then&lt;br /&gt;
                    -- if condition is set - validate it.&lt;br /&gt;
                    -- if it satisfies - return the file.&lt;br /&gt;
                    return condition.file&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            error(&lt;br /&gt;
                &amp;quot;item image lookup failed: unknown entry type &amp;#039;&amp;quot; .. entry_type .. &amp;quot;&amp;#039; for item &amp;#039;&amp;quot; .. item_id .. &amp;quot;&amp;#039;&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- if not a single condition satisfied - raise an error&lt;br /&gt;
    error(&amp;quot;item image lookup failed: no condition satisfied for item &amp;#039;&amp;quot; .. item_id .. &amp;quot;&amp;#039;&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Lookups item page name by query.&lt;br /&gt;
-- Query can either be an item ID (strict casing) or item name (any casing).&lt;br /&gt;
--&lt;br /&gt;
-- Returns `nil` if no page is defined for an item.&lt;br /&gt;
function p.try_lookup_item_page(query)&lt;br /&gt;
    local item_id = p.lookup_item_id(query, true)&lt;br /&gt;
    assert_value_not_nil(item_id, &amp;quot;item page lookup failed: no item was found by ID/name &amp;#039;&amp;quot; .. query .. &amp;quot;&amp;#039;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    return item_page_links_by_item_ids[item_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ==============================&lt;br /&gt;
&lt;br /&gt;
-- Generates an item element.&lt;br /&gt;
-- This is the main function of this module.&lt;br /&gt;
function p.generate_item(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local argsWithWhitespace = getArgs(frame, { trim = false, removeBlanks = false })&lt;br /&gt;
&lt;br /&gt;
    -- [REQUIRED]&lt;br /&gt;
&lt;br /&gt;
    -- input item name or ID.&lt;br /&gt;
    -- any casing is allowed for name, but ID must follow strict casing.&lt;br /&gt;
    local input_item = args[1]&lt;br /&gt;
    assert_value_not_nil(input_item, &amp;quot;failed to generate an item: item was not provided&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    -- [OPTIONAL]&lt;br /&gt;
&lt;br /&gt;
    -- amount of item.&lt;br /&gt;
    -- input is a string number or nil&lt;br /&gt;
    local input_amount = tonumber(args[2])&lt;br /&gt;
&lt;br /&gt;
    -- item icon size. uses CSS units.&lt;br /&gt;
    local input_icon_size = args.size or &amp;quot;32px&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    -- text label. can be set, otherwise inferred from the item later (so &amp;quot;nil&amp;quot; for now).&lt;br /&gt;
    local input_label = argsWithWhitespace.label or argsWithWhitespace.l&lt;br /&gt;
&lt;br /&gt;
    -- whether to capitalize the label. false by default.&lt;br /&gt;
    local input_capitalize_label = yesNo(args.capitalize or args.cap or false)&lt;br /&gt;
&lt;br /&gt;
    -- a link to a page.&lt;br /&gt;
    -- if set, turns item into a link.&lt;br /&gt;
    -- if unset, and item has a link defined for it in the config - uses it.&lt;br /&gt;
    local input_link = args.link&lt;br /&gt;
&lt;br /&gt;
    -- ============&lt;br /&gt;
&lt;br /&gt;
    local item_id = p.lookup_item_id(input_item, true)&lt;br /&gt;
    assert_value_not_nil(item_id, &amp;quot;item generation failed: no item was found by ID/name &amp;#039;&amp;quot; .. input_item .. &amp;quot;&amp;#039;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    local item_image_filename = p.try_lookup_item_image(item_id, input_amount)&lt;br /&gt;
&lt;br /&gt;
    local item_page_link = input_link&lt;br /&gt;
        or p.try_lookup_item_page(item_id)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    local label&lt;br /&gt;
    if input_label == nil then&lt;br /&gt;
        -- if a custom label is not provided, lookup the item&amp;#039;s label&lt;br /&gt;
        label = p.lookup_item_name_by_item_id(item_id)&lt;br /&gt;
    else&lt;br /&gt;
        -- if a label is provided - use it&lt;br /&gt;
        label = input_label&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if input_capitalize_label then&lt;br /&gt;
        label = capitalize(label)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if input_amount ~= nil then&lt;br /&gt;
        label = input_amount .. &amp;quot; &amp;quot; .. label&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if item_page_link ~= nil then&lt;br /&gt;
        label = &amp;quot;[[&amp;quot; .. item_page_link .. &amp;quot;|&amp;quot; .. label .. &amp;quot;]]&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- ============&lt;br /&gt;
&lt;br /&gt;
    local item_el = mw.html.create(&amp;quot;span&amp;quot;)&lt;br /&gt;
        :addClass(&amp;quot;item&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    -- add icon element inside the label if icon is provided&lt;br /&gt;
    if item_image_filename ~= nil then&lt;br /&gt;
        local link_param = &amp;#039;&amp;#039;&lt;br /&gt;
        if item_page_link ~= nil then&lt;br /&gt;
            link_param = &amp;#039;|link=&amp;#039; .. item_page_link&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        item_el:node(&amp;quot;[[File:&amp;quot; ..&lt;br /&gt;
            item_image_filename .. &amp;quot;|&amp;quot; .. input_icon_size .. &amp;quot;|class=item-icon&amp;quot; .. link_param .. &amp;quot;]]&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    item_el:node(label)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if not was_template_styles_tag_el_added then&lt;br /&gt;
        item_el:node(current_frame:extensionTag(&amp;quot;templatestyles&amp;quot;, &amp;quot;&amp;quot;, { src = &amp;#039;Template:Item/styles.css&amp;#039; }))&lt;br /&gt;
&lt;br /&gt;
        was_template_styles_tag_el_added = true&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    return item_el&lt;br /&gt;
        :allDone()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.generate_list_of_all_items_with_icons(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local columns_count = args[1]&lt;br /&gt;
    assert_value_not_nil(columns_count, &amp;quot;columns count was not provided&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    local container = mw.html.create(&amp;quot;div&amp;quot;)&lt;br /&gt;
        :css(&amp;quot;column-count&amp;quot;, columns_count)&lt;br /&gt;
&lt;br /&gt;
    -- an array of item ids that have images&lt;br /&gt;
    local item_ids_with_images = {}&lt;br /&gt;
    for item_id, _ in pairs(item_images_by_item_ids) do&lt;br /&gt;
        table.insert(item_ids_with_images, item_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local function assert_looked_up_item_name_is_not_nil(item_id, item_name)&lt;br /&gt;
        assert_value_not_nil(item_name,&lt;br /&gt;
            &amp;quot;failed to generate a list of items with icons: no item was found by ID &amp;#039;&amp;quot; ..&lt;br /&gt;
            item_id ..&lt;br /&gt;
            &amp;quot;&amp;#039;. This likely indicates that the item with this ID was removed or the ID was misspelled in the item image files table&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- sort alphabetically&lt;br /&gt;
    table.sort(item_ids_with_images, function(first, second)&lt;br /&gt;
        local first_item_name = p.lookup_item_name_by_item_id(first, true)&lt;br /&gt;
        local second_item_name = p.lookup_item_name_by_item_id(second, true)&lt;br /&gt;
&lt;br /&gt;
        assert_looked_up_item_name_is_not_nil(first, first_item_name)&lt;br /&gt;
        assert_looked_up_item_name_is_not_nil(second, second_item_name)&lt;br /&gt;
&lt;br /&gt;
        return first_item_name &amp;lt; second_item_name&lt;br /&gt;
    end)&lt;br /&gt;
&lt;br /&gt;
    -- generate child elements from the template&lt;br /&gt;
    for _, item_id in ipairs(item_ids_with_images) do&lt;br /&gt;
        local item_el = p.generate_item { item_id }&lt;br /&gt;
            :css(&amp;quot;display&amp;quot;, &amp;quot;block&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        container:node(item_el)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return container&lt;br /&gt;
        :allDone()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- -- Generates a list of ALL items.&lt;br /&gt;
-- -- Will likely break :clueless:&lt;br /&gt;
function p.generate_list_of_all_items(frame)&lt;br /&gt;
    local args = getArgs(frame)&lt;br /&gt;
    local columns_count = args[1]&lt;br /&gt;
    assert_value_not_nil(columns_count, &amp;quot;columns count was not provided&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    local container = mw.html.create(&amp;quot;div&amp;quot;)&lt;br /&gt;
        :css(&amp;quot;column-count&amp;quot;, columns_count)&lt;br /&gt;
&lt;br /&gt;
    local item_ids = {}&lt;br /&gt;
    for item_id, _ in pairs(item_names_by_item_ids) do&lt;br /&gt;
        table.insert(item_ids, item_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- sort alphabetically&lt;br /&gt;
    table.sort(item_ids, function(first, second)&lt;br /&gt;
        return p.lookup_item_name_by_item_id(first) &amp;lt; p.lookup_item_name_by_item_id(second)&lt;br /&gt;
    end)&lt;br /&gt;
&lt;br /&gt;
    -- generate child elements from the template&lt;br /&gt;
    for _, item_id in ipairs(item_ids) do&lt;br /&gt;
        local item_el = p.generate_item { item_id }&lt;br /&gt;
            :css(&amp;quot;display&amp;quot;, &amp;quot;block&amp;quot;)&lt;br /&gt;
            :node(&amp;quot; &amp;lt;span style=&amp;#039;color: gray;&amp;#039;&amp;gt;ID &amp;quot; .. item_id .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        container:node(item_el)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return container&lt;br /&gt;
        :allDone()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>imported&gt;Aliser</name></author>
	</entry>
</feed>