Module:Infobox Recipe: Difference between revisions

From Brighter Shores Wiki
Jump to navigation Jump to search
Content added Content deleted
No edit summary
m (Spaces to tabs)
Line 2: Line 2:


function p._main(frame)
function p._main(frame)
local args = frame:getParent().args
local args = frame:getParent().args
local mw = require('mw')
local mw = require('mw')
local currency = require('Module:Currency').parse
local currency = require('Module:Currency').parse
local parse = require('Module:Param Parse')
local parse = require('Module:Param Parse')
local yn = require('Module:Yesno')
local yn = require('Module:Yesno')

--If set to true, will check if any of the items passed as a rawmaterialparam are actually intermediate materials. Will then change the display order of the infobox.
--If set to true, will check if any of the items passed as a rawmaterialparam are actually intermediate materials. Will then change the display order of the infobox.
local showFullRecipe = yn(args.showFull or 'no', false)
local showFullRecipe = yn(args.showFull or 'no', false)

--Get each of the rawmatX parameters from params and store their values in a new table
--Get each of the rawmatX parameters from params and store their values in a new table
local argsMaterials = p._extractRawMaterials(args)
local argsMaterials = p._extractRawMaterials(args)
--empty tables to hold materials
--empty tables to hold materials
local rawMaterials = {}
local rawMaterials = {}
local intermediateMaterials = {}
local intermediateMaterials = {}

--counter for total price of raw materials
--counter for total price of raw materials
local rawMaterialCost = 0
local rawMaterialCost = 0

--get the value for the output product
--get the value for the output product
local output1Value = args.output1 and mw.smw.ask('[[:+]][[' .. args.output1 .. ']]|?Value|limit=1')
local output1Value = args.output1 and mw.smw.ask('[[:+]][[' .. args.output1 .. ']]|?Value|limit=1')
Line 29: Line 29:
output1TotalValue = 0
output1TotalValue = 0
end
end

--Check if any of the raw mats provided are intermediate products, if they are, return their own raw materials
--Check if any of the raw mats provided are intermediate products, if they are, return their own raw materials
if showFullRecipe then
if showFullRecipe then
Line 45: Line 45:
local queryResult = mw.smw.ask('[[:+]][[Sold item::' .. material['name'] .. ']]|?Shop buy price|sort=Shop buy price|order=asc|limit=1') or 0
local queryResult = mw.smw.ask('[[:+]][[Sold item::' .. material['name'] .. ']]|?Shop buy price|sort=Shop buy price|order=asc|limit=1') or 0
if type(queryResult) == "table" and queryResult[1]['Shop buy price'] then
if type(queryResult) == "table" and queryResult[1]['Shop buy price'] then
return tonumber(queryResult[1]['Shop buy price']) or 0
return tonumber(queryResult[1]['Shop buy price']) or 0
end
end
return 0
return 0
end
end


Line 55: Line 55:
local pageName = ''
local pageName = ''
if result and result[1] and result[1]["Uses facility"] then
if result and result[1] and result[1]["Uses facility"] then
local usesFac = result[1]["Uses facility"]
local usesFac = result[1]["Uses facility"]
pageName = usesFac:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
pageName = usesFac:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
end
end
return pageName
return pageName
end
end


--Set SMW properties
--Set SMW properties
if args.rawmat1 then
if args.rawmat1 then
mw.smw.set({
mw.smw.set({
["Uses item"] = args.rawmat1,
["Uses item"] = args.rawmat1,
})
})
end
end
if args.rawmat2 then
if args.rawmat2 then
mw.smw.set({
mw.smw.set({
["Uses item"] = args.rawmat2,
["Uses item"] = args.rawmat2,
})
})
end
end
if args.rawmat3 then
if args.rawmat3 then
mw.smw.set({
mw.smw.set({
["Uses item"] = args.rawmat3,
["Uses item"] = args.rawmat3,
})
})
end
end
if args.facility then
if args.facility then
mw.smw.set({
mw.smw.set({
["Uses facility"] = args.facility
["Uses facility"] = args.facility
Line 89: Line 89:
local row = {}
local row = {}
table.insert(row, '| [[File:' .. item['name'] .. '.png|30px]]')
table.insert(row, '| [[File:' .. item['name'] .. '.png|30px]]')
table.insert(row, '| [[' .. item['name'] .. ']]')
table.insert(row, '| [[' .. item['name'] .. ']]')
table.insert(row, '| style="text-align: right;" | ' .. (quantity or 1))
table.insert(row, '| style="text-align: right;" | ' .. (quantity or 1))
table.insert(row, '| style="text-align: right;" | ' .. currency(materialBuyPrice))
table.insert(row, '| style="text-align: right;" | ' .. currency(materialBuyPrice))
table.insert(row, '|-')
table.insert(row, '|-')
return row
return row
end
end

--Creates a row suitable for the intermediate materials section of the infobox. Quantity is optional, if no value is provided it will default to 1
--Creates a row suitable for the intermediate materials section of the infobox. Quantity is optional, if no value is provided it will default to 1
local function createIntermediateMaterialRow(item, quantity)
local function createIntermediateMaterialRow(item, quantity)
Line 101: Line 101:
local facility = getFacility(item)
local facility = getFacility(item)
table.insert(row, '| [[File:' .. item .. '.png|30px]]')
table.insert(row, '| [[File:' .. item .. '.png|30px]]')
table.insert(row, '| [[' .. item .. ']]')
table.insert(row, '| [[' .. item .. ']]')
table.insert(row, '| style="text-align: right;" | ' .. (quantity or 1))
table.insert(row, '| style="text-align: right;" | ' .. (quantity or 1))
table.insert(row, '| style="text-align: right;" | [[File:' .. facility .. '.png|30px]] [[' .. facility .. ']]')
table.insert(row, '| style="text-align: right;" | [[File:' .. facility .. '.png|30px]] [[' .. facility .. ']]')
table.insert(row, '|-')
table.insert(row, '|-')
return row
return row
end
end

-- Recipe Table Head
-- Recipe Table Head
local out = {}
local out = {}
table.insert(out, '{| class="wikitable"')
table.insert(out, '{| class="wikitable"')
table.insert(out, '! colspan="4" | Requirements')
table.insert(out, '! colspan="4" | Requirements')
table.insert(out, '|-')
table.insert(out, '|-')
table.insert(out, '! colspan="2" | Facility')
table.insert(out, '! colspan="2" | Facility')
table.insert(out, '| colspan="2" | ' .. (args.facility and '[[' .. args.facility .. ']]' or 'Unknown'))
table.insert(out, '| colspan="2" | ' .. (args.facility and '[[' .. args.facility .. ']]' or 'Unknown'))
table.insert(out, '|-')
table.insert(out, '|-')
table.insert(out, '! colspan="2" | Profession')
table.insert(out, '! colspan="2" | Profession')
table.insert(out, '! Level')
table.insert(out, '! Level')
table.insert(out, '! XP')
table.insert(out, '! XP')
table.insert(out, '|-')
table.insert(out, '|-')
table.insert(out, '| colspan="2" style="text-align:center;" | ' .. (args.profession and '[[' .. args.profession .. ']]' or 'Unknown'))
table.insert(out, '| colspan="2" style="text-align:center;" | ' .. (args.profession and '[[' .. args.profession .. ']]' or 'Unknown'))
table.insert(out, '| style="text-align: center;" | ' .. (args.level or 'Unknown'))
table.insert(out, '| style="text-align: center;" | ' .. (args.level or 'Unknown'))
table.insert(out, '| style="text-align: center;" | ' .. (args.exp or 'Unknown'))
table.insert(out, '| style="text-align: center;" | ' .. (args.exp or 'Unknown'))
table.insert(out, '|-')
table.insert(out, '|-')

-- Add raw materials
-- Add raw materials
-- Headers
-- Headers
table.insert(out, '! colspan="2" | Raw Ingredient')
table.insert(out, '! colspan="2" | Raw Ingredient')
table.insert(out, '! Quantity')
table.insert(out, '! Quantity')
table.insert(out, '! Cost')
table.insert(out, '! Cost')
table.insert(out, '|-')
table.insert(out, '|-')


-- Values
-- Values
for _, material in ipairs(rawMaterials) do
for _, material in ipairs(rawMaterials) do
local row = createRawMaterialRow(material)
local row = createRawMaterialRow(material)
for _, value in ipairs(row) do
for _, value in ipairs(row) do
table.insert(out, value)
table.insert(out, value)
end
end
end
end


-- Add total raw cost
-- Add total raw cost
table.insert(out, '! colspan="3" | Total Raw cost')
table.insert(out, '! colspan="3" | Total Raw cost')
table.insert(out, '| style="text-align: right;" | ' .. currency(rawMaterialCost))
table.insert(out, '| style="text-align: right;" | ' .. currency(rawMaterialCost))
table.insert(out, '|-')
table.insert(out, '|-')

-- Add Intermediate steps if required
-- Add Intermediate steps if required
-- Headers
-- Headers
if next(intermediateMaterials) ~= nil then
if next(intermediateMaterials) ~= nil then
-- Headers
-- Headers
table.insert(out, '! colspan="2" | Intermediate Ingredient')
table.insert(out, '! colspan="2" | Intermediate Ingredient')
table.insert(out, '! Quantity')
table.insert(out, '! Quantity')
table.insert(out, '! Facility')
table.insert(out, '! Facility')
table.insert(out, '|-')
table.insert(out, '|-')

-- Values
-- Values
for _, material in ipairs(intermediateMaterials) do
for _, material in ipairs(intermediateMaterials) do
local row = createIntermediateMaterialRow(material['name'])
local row = createIntermediateMaterialRow(material['name'])
for _, value in ipairs(row) do
for _, value in ipairs(row) do
table.insert(out, value)
table.insert(out, value)
end
end
end
end
end
end


-- Add output data
-- Add output data
-- Headers
-- Headers
table.insert(out, '! colspan="2" | Output')
table.insert(out, '! colspan="2" | Output')
table.insert(out, '! Quantity')
table.insert(out, '! Quantity')
table.insert(out, '! Value')
table.insert(out, '! Value')
table.insert(out, '|-')
table.insert(out, '|-')
-- Values
table.insert(out, '| [[File:' .. args.output1 .. '.png|30px]]')
table.insert(out, '| ' .. (args.output1 and '[[' .. args.output1 .. ']]' or 'Unknown'))
table.insert(out, '| style="text-align: right;" | ' .. (args.output1qty or 1))
table.insert(out, '| style="text-align: right;" | ' .. currency(output1TotalValue))
table.insert(out, '|-')
-- Add profit data
table.insert(out, '! colspan="3" | Profit')
table.insert(out, '| style="text-align: right;" | ' .. currency(output1TotalValue - rawMaterialCost))
table.insert(out, '|}')


-- Values
return table.concat(out, '\n')
table.insert(out, '| [[File:' .. args.output1 .. '.png|30px]]')
table.insert(out, '| ' .. (args.output1 and '[[' .. args.output1 .. ']]' or 'Unknown'))
table.insert(out, '| style="text-align: right;" | ' .. (args.output1qty or 1))
table.insert(out, '| style="text-align: right;" | ' .. currency(output1TotalValue))
table.insert(out, '|-')

-- Add profit data
table.insert(out, '! colspan="3" | Profit')
table.insert(out, '| style="text-align: right;" | ' .. currency(output1TotalValue - rawMaterialCost))
table.insert(out, '|}')

return table.concat(out, '\n')
end
end


function p._extractRawMaterials(args)
function p._extractRawMaterials(args)
local rawMaterials = {}
local rawMaterials = {}


for i = 1, 9 do
for i = 1, 9 do
local materialKey = "rawmat" .. i
local materialKey = "rawmat" .. i
local quantityKey = "rawmat" .. i .. "qty"
local quantityKey = "rawmat" .. i .. "qty"


local materialValue = args[materialKey]
local materialValue = args[materialKey]
if materialValue and materialValue ~= "" then
if materialValue and materialValue ~= "" then
local quantityValue = tonumber(args[quantityKey]) or 1
local quantityValue = tonumber(args[quantityKey]) or 1
table.insert(rawMaterials, { name = materialValue, quantity = quantityValue })
table.insert(rawMaterials, { name = materialValue, quantity = quantityValue })
end
end
end
end
return rawMaterials
return rawMaterials
end
end


function p._getTrueRawMaterials(argsMaterials)
function p._getTrueRawMaterials(argsMaterials)
local queryResult = {}
local queryResult = {}
for _, item in pairs(argsMaterials) do
for _, item in pairs(argsMaterials) do
if item["name"] then
if item["name"] then
local result = mw.smw.ask('[[:+]][[' .. item["name"] .. ']]|?Uses item')
local result = mw.smw.ask('[[:+]][[' .. item["name"] .. ']]|?Uses item')
if result and result[1] and result[1]["Uses item"] then
local usesItems = result[1]["Uses item"]


if result and result[1] and result[1]["Uses item"] then
-- If usesItems is a table (multiple items), iterate and add each to queryResult
if type(usesItems) == "table" then
local usesItems = result[1]["Uses item"]

for _, usedItem in ipairs(usesItems) do
-- If usesItems is a table (multiple items), iterate and add each to queryResult
local pageName = usedItem:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
if type(usesItems) == "table" then
table.insert(queryResult, { ["name"] = pageName, ["quantity"] = 1 })
for _, usedItem in ipairs(usesItems) do
end
local pageName = usedItem:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
else
table.insert(queryResult, { ["name"] = pageName, ["quantity"] = 1 })
-- If usesItems is a single item, add it directly
end
local pageName = usesItems:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
else
table.insert(queryResult, { ["name"] = pageName, ["quantity"] = 1 })
-- If usesItems is a single item, add it directly
end
local pageName = usesItems:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
end
table.insert(queryResult, { ["name"] = pageName, ["quantity"] = 1 })
end
end
end
end
return queryResult
end
end
return queryResult
end
end



Revision as of 19:35, 20 November 2024

Module documentation
This documentation is transcluded from Module:Infobox Recipe/doc. [edit] [history] [purge]
Module:Infobox Recipe's function _main is invoked by Template:Infobox Recipe.
Module:Infobox Recipe requires Module:Currency.
Module:Infobox Recipe requires Module:Mw.
Module:Infobox Recipe requires Module:Param Parse.
Module:Infobox Recipe requires Module:Yesno.

The Infobox Recipe template is used to show the details of a recipe step in item articles, such as a potion mixture or adding a cooking ingredient. It can also be used to display the experience gained for item creation.

Parameters

Parameter Format Usage Mandatory?
facility Link to facility The name of the facility that is required to create the item; e.g. facility = Standard Potion Station will display

Standard Potion Station

Yes
profession profession name The profession in which experience is gained, or which has a level requirement, for creating the item Yes
level Integer The level required in the profession to create the item. Yes
exp number The amount of experience gained for performing the action. Yes
rawmat1 Exact name of the item The primary item used for performing the craft. e.g. Brown Kelp for Brown Kelp Yes
rawmat1qty Integer The amount of the material used in the process.

This parameter can be removed if it would be 1

No
rawmat2 Exact name of the item The secondary item used for performing the craft. e.g. Brown Kelp for Brown Kelp No
rawmat2qty Integer The amount of the material used in the process.

This parameter can be removed if it would be 1

No
rawmat3 Exact name of the item The tertiary item used for performing the craft. e.g. Brown Kelp for Brown Kelp No
rawmat3qty Integer The amount of the material used in the process.

This parameter can be removed if it would be 1

No
rawmat4 Exact name of the item The fourth item used for performing the craft. e.g. Brown Kelp for Brown Kelp No
rawmat4qty Integer The amount of the material used in the process.

This parameter can be removed if it would be 1

No
output1 Exact name of the item The item created by performing the craft. e.g. Brown Kelp for Brown Kelp Yes
output1qty Integer The amount of the output created in the process.

This parameter can be removed if it would be 1

No
showFull boolean Flag to display all steps of a recipe or only the step specified in the params No

Examples

Show Single Step Recipe

This is an example that uses values from the 10% Potion Healing recipe. Notice that this only shows information of the steps for which the information has been provided. The showFull parameter can be omitted entirely if this is the desired outcome as the default value is false

{{Infobox Recipe
|facility = Standard Potion Station
|profession = Alchemist
|level = 0
|exp = 63
|rawmat1 = 10% Preparation Healing
|rawmat2 = Bottle
|output1 = 10% Potion Healing
|output1qty = 1
}}
Requirements
Facility Standard Potion Station
Profession Level XP
Alchemist 0 63
Raw Ingredient Quantity Cost
10% Preparation Healing 1 Copper
Bottle 1 20 Copper
Total Raw cost 20 Copper
Output Quantity Value
10% Potion Healing 1 450 Copper
Profit 430 Copper

Show Full Recipe

This is an example that uses values from the 10% Potion Healing recipe. Notice that the parameters that have been passed to this example do not include 'Brown Kelp' This is displayed because the showFull parameter has been set to true. This causes the Infobox Module to query smw data for each of the provided raw materials to check if they have raw materials of their own. If they do, they are brought in to the recipe.

{{Infobox Recipe
|facility = Standard Potion Station
|profession = Alchemist
|level = 0
|exp = 63
|rawmat1 = 10% Preparation Healing
|rawmat2 = Bottle
|output1 = 10% Potion Healing
|output1qty = 1
|showFull = true
}}
Requirements
Facility Standard Potion Station
Profession Level XP
Alchemist 0 63
Raw Ingredient Quantity Cost
Brown Kelp 1 500 Copper
Total Raw cost 500 Copper
Intermediate Ingredient Quantity Facility
10% Preparation Healing 1 Reagent Preparation Station
Bottle 1 File:.png [[]]
Output Quantity Value
10% Potion Healing 1 450 Copper
Profit -50 Copper

Blank infobox

{{Infobox Recipe
|facility = 
|profession = 
|level = 
|exp = 
|rawmat1 = 
|rawmat1qty = 
|rawmat2 = 
|rawmat2qty = 
|rawmat3 = 
|rawmat3qty = 
|output1 = 
|output1qty = 

local p = {}

function p._main(frame)
	local args = frame:getParent().args
	local mw = require('mw')
	local currency = require('Module:Currency').parse
	local parse = require('Module:Param Parse')
	local yn = require('Module:Yesno')

	--If set to true, will check if any of the items passed as a rawmaterialparam are actually intermediate materials. Will then change the display order of the infobox.
	local showFullRecipe = yn(args.showFull or 'no', false)

	--Get each of the rawmatX parameters from params and store their values in a new table
	local argsMaterials = p._extractRawMaterials(args)
	--empty tables to hold materials
	local rawMaterials = {}
	local intermediateMaterials = {}

	--counter for total price of raw materials
	local rawMaterialCost = 0

	--get the value for the output product
	local output1Value = args.output1 and mw.smw.ask('[[:+]][[' .. args.output1 .. ']]|?Value|limit=1')
	local output1TotalValue = 0
	mw.logObject(output1Value)
	if output1Value ~= nil then
		output1TotalValue = output1Value[1]['Value'] * (tonumber(args.output1qty) or 1)
	else
		output1TotalValue = 0
	end

	--Check if any of the raw mats provided are intermediate products, if they are, return their own raw materials
	if showFullRecipe then
		local trueRawMaterials = p._getTrueRawMaterials(argsMaterials)
		if next(trueRawMaterials) ~= nil then
			rawMaterials = trueRawMaterials
			intermediateMaterials = argsMaterials
		end
	else
			rawMaterials = argsMaterials
	end

	--Simple query to get the shop buy price for the provided material, if no buy price is available returns 0
	local function getBuyPrice(material)
		local queryResult = mw.smw.ask('[[:+]][[Sold item::' .. material['name'] .. ']]|?Shop buy price|sort=Shop buy price|order=asc|limit=1') or 0
		if type(queryResult) == "table" and queryResult[1]['Shop buy price'] then
			return tonumber(queryResult[1]['Shop buy price']) or 0
		end
		return 0
	end

	--If one of the raw materials provided as a param has been identified as an intermediate material then get the facility it is created at to display in the intermediate Ingredient row
	local function getFacility(material)
		local result = mw.smw.ask('[[:+]][[' .. material .. ']]|?Uses facility|limit=1') or 'unknown'
		local pageName = ''
		if result and result[1] and result[1]["Uses facility"] then
			local usesFac = result[1]["Uses facility"]
			pageName = usesFac:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
		end
		return pageName
	end

	--Set SMW properties
	if args.rawmat1 then
		mw.smw.set({
			["Uses item"] = args.rawmat1,
		})
	end
	if args.rawmat2 then
		mw.smw.set({
			["Uses item"] = args.rawmat2,
		})
	end
	if args.rawmat3 then
		mw.smw.set({
			["Uses item"] = args.rawmat3,
		})
	end
	if args.facility then
		mw.smw.set({
			["Uses facility"] = args.facility
		})
	end

	--Creates a row suitable for the raw materials section of the infobox. Quantity is optional, if no value is provided it will default to 1
	local function createRawMaterialRow(item, quantity)
		local materialBuyPrice = getBuyPrice(item)
		rawMaterialCost = rawMaterialCost + materialBuyPrice
		local row = {}
		table.insert(row, '| [[File:' .. item['name'] .. '.png|30px]]')
		table.insert(row, '| [[' .. item['name'] .. ']]')
		table.insert(row, '| style="text-align: right;" | ' .. (quantity or 1))
		table.insert(row, '| style="text-align: right;" | ' .. currency(materialBuyPrice))
		table.insert(row, '|-')
		return row
	end

	--Creates a row suitable for the intermediate materials section of the infobox. Quantity is optional, if no value is provided it will default to 1
	local function createIntermediateMaterialRow(item, quantity)
		local row = {}
		local facility = getFacility(item)
		table.insert(row, '| [[File:' .. item .. '.png|30px]]')
		table.insert(row, '| [[' .. item .. ']]')
		table.insert(row, '| style="text-align: right;" | ' .. (quantity or 1))
		table.insert(row, '| style="text-align: right;" | [[File:' .. facility .. '.png|30px]] [[' .. facility .. ']]')
		table.insert(row, '|-')
		return row
	end

-- Recipe Table Head 
	local out = {}
	table.insert(out, '{| class="wikitable"')
	table.insert(out, '! colspan="4" | Requirements')
	table.insert(out, '|-')
	table.insert(out, '! colspan="2" | Facility')
	table.insert(out, '| colspan="2" | ' .. (args.facility and '[[' .. args.facility .. ']]' or 'Unknown'))
	table.insert(out, '|-')
	table.insert(out, '! colspan="2" | Profession')
	table.insert(out, '! Level')
	table.insert(out, '! XP')
	table.insert(out, '|-')
	table.insert(out, '| colspan="2" style="text-align:center;" | ' .. (args.profession and '[[' .. args.profession .. ']]' or 'Unknown'))
	table.insert(out, '| style="text-align: center;" | ' .. (args.level or 'Unknown'))
	table.insert(out, '| style="text-align: center;" | ' .. (args.exp or 'Unknown'))
	table.insert(out, '|-')

-- Add raw materials
	-- Headers
	table.insert(out, '! colspan="2" | Raw Ingredient')
	table.insert(out, '! Quantity')
	table.insert(out, '! Cost')
	table.insert(out, '|-')

	-- Values
	for _, material in ipairs(rawMaterials) do
		local row = createRawMaterialRow(material)
		for _, value in ipairs(row) do
			table.insert(out, value)
		end
	end

-- Add total raw cost
	table.insert(out, '! colspan="3" | Total Raw cost')
	table.insert(out, '| style="text-align: right;" | ' .. currency(rawMaterialCost))
	table.insert(out, '|-')

-- Add Intermediate steps if required
	-- Headers
	if next(intermediateMaterials) ~= nil then
		-- Headers
		table.insert(out, '! colspan="2" | Intermediate Ingredient')
		table.insert(out, '! Quantity')
		table.insert(out, '! Facility')
		table.insert(out, '|-')

	-- Values
		for _, material in ipairs(intermediateMaterials) do
			local row = createIntermediateMaterialRow(material['name'])
			for _, value in ipairs(row) do
				table.insert(out, value)
			end
		end
	end

-- Add output data
	-- Headers
	table.insert(out, '! colspan="2" | Output')
	table.insert(out, '! Quantity')
	table.insert(out, '! Value')
	table.insert(out, '|-')

	-- Values
	table.insert(out, '| [[File:' .. args.output1 .. '.png|30px]]')
	table.insert(out, '| ' .. (args.output1 and '[[' .. args.output1 .. ']]' or 'Unknown'))
	table.insert(out, '| style="text-align: right;" | ' .. (args.output1qty or 1))
	table.insert(out, '| style="text-align: right;" | ' .. currency(output1TotalValue))
	table.insert(out, '|-')

	-- Add profit data
	table.insert(out, '! colspan="3" | Profit')
	table.insert(out, '| style="text-align: right;" | ' .. currency(output1TotalValue - rawMaterialCost))
	table.insert(out, '|}')

	return table.concat(out, '\n')
end

function p._extractRawMaterials(args)
	local rawMaterials = {}

	for i = 1, 9 do
		local materialKey = "rawmat" .. i
		local quantityKey = "rawmat" .. i .. "qty"

		local materialValue = args[materialKey]
		if materialValue and materialValue ~= "" then
			local quantityValue = tonumber(args[quantityKey]) or 1
			table.insert(rawMaterials, { name = materialValue, quantity = quantityValue })
		end
	end
	return rawMaterials
end

function p._getTrueRawMaterials(argsMaterials)
	local queryResult = {}
	for _, item in pairs(argsMaterials) do
		if item["name"] then
			local result = mw.smw.ask('[[:+]][[' .. item["name"] .. ']]|?Uses item')

			if result and result[1] and result[1]["Uses item"] then
				local usesItems = result[1]["Uses item"]

				-- If usesItems is a table (multiple items), iterate and add each to queryResult
				if type(usesItems) == "table" then
					for _, usedItem in ipairs(usesItems) do
						local pageName = usedItem:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
						table.insert(queryResult, { ["name"] = pageName, ["quantity"] = 1 })
					end
				else
					-- If usesItems is a single item, add it directly
					local pageName = usesItems:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
					table.insert(queryResult, { ["name"] = pageName, ["quantity"] = 1 })
				end
			end
		end
	end
	return queryResult
end

return p