<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.earthmc.net/index.php?action=history&amp;feed=atom&amp;title=Module%3AInventory_slot</id>
	<title>Module:Inventory slot - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.earthmc.net/index.php?action=history&amp;feed=atom&amp;title=Module%3AInventory_slot"/>
	<link rel="alternate" type="text/html" href="https://wiki.earthmc.net/index.php?title=Module:Inventory_slot&amp;action=history"/>
	<updated>2026-10-27T18:21:27Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://wiki.earthmc.net/index.php?title=Module:Inventory_slot&amp;diff=234634&amp;oldid=prev</id>
		<title>515797455988850689: Created page with &quot;------------------------------------------------------------ -- Initially taken from: https://minecraft.gamepedia.com/Module:Inventory_slot ------------------------------------------------------------  local p = {}  local getArgs = require(&#039;Module:Arguments&#039;).getArgs local loader = require(&#039;Module:Loader&#039;)  local string, table, yesno, currency, random, uitext, cache = 	loader.require(&#039;String&#039;, &#039;Table&#039;, &#039;Yesno&#039;, &#039;Currency&#039;, &#039;Random&#039;, &#039;UIText&#039;, &#039;Cache&#039;) local slotAliases =...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.earthmc.net/index.php?title=Module:Inventory_slot&amp;diff=234634&amp;oldid=prev"/>
		<updated>2023-11-25T08:28:29Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;------------------------------------------------------------ -- Initially taken from: https://minecraft.gamepedia.com/Module:Inventory_slot ------------------------------------------------------------  local p = {}  local getArgs = require(&amp;#039;Module:Arguments&amp;#039;).getArgs local loader = require(&amp;#039;Module:Loader&amp;#039;)  local string, table, yesno, currency, random, uitext, cache = 	loader.require(&amp;#039;String&amp;#039;, &amp;#039;Table&amp;#039;, &amp;#039;Yesno&amp;#039;, &amp;#039;Currency&amp;#039;, &amp;#039;Random&amp;#039;, &amp;#039;UIText&amp;#039;, &amp;#039;Cache&amp;#039;) local slotAliases =...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;------------------------------------------------------------&lt;br /&gt;
-- Initially taken from: https://minecraft.gamepedia.com/Module:Inventory_slot&lt;br /&gt;
------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local getArgs = require(&amp;#039;Module:Arguments&amp;#039;).getArgs&lt;br /&gt;
local loader = require(&amp;#039;Module:Loader&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local string, table, yesno, currency, random, uitext, cache =&lt;br /&gt;
	loader.require(&amp;#039;String&amp;#039;, &amp;#039;Table&amp;#039;, &amp;#039;Yesno&amp;#039;, &amp;#039;Currency&amp;#039;, &amp;#039;Random&amp;#039;, &amp;#039;UIText&amp;#039;, &amp;#039;Cache&amp;#039;)&lt;br /&gt;
local slotAliases = loader.loadData(&amp;#039;Inventory slot/Aliases&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local invslotCache = cache.invslotCache&lt;br /&gt;
-- local slotAliasesCache = cache.slotAliasesCache&lt;br /&gt;
local itemVariantsCache = cache.itemVariantsCache&lt;br /&gt;
&lt;br /&gt;
local pageName = mw.title.getCurrentTitle().text&lt;br /&gt;
local availableFrameParameters = { &amp;#039;title&amp;#039;, &amp;#039;text&amp;#039;, &amp;#039;num&amp;#039;, &amp;#039;num2&amp;#039;, &amp;#039;link&amp;#039;, &amp;#039;image&amp;#039;, &amp;#039;image_id&amp;#039; }&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------&lt;br /&gt;
--	Structure for main slot creation:&lt;br /&gt;
--	p.slot()&lt;br /&gt;
--	├── p.parseFrameText()&lt;br /&gt;
--	│	└── p.combineFrames()&lt;br /&gt;
--	│	└── p.makeFrame()&lt;br /&gt;
--	└── p.makeItem()&lt;br /&gt;
--------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
--[[Merges a list, or inserts a string&lt;br /&gt;
	or table into a table&lt;br /&gt;
--]]&lt;br /&gt;
local function mergeList( parentTable, content )&lt;br /&gt;
	if content[1] then&lt;br /&gt;
		-- Merge list into table&lt;br /&gt;
		for _, v in ipairs( content ) do&lt;br /&gt;
			parentTable[#parentTable + 1] = v&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		-- Add strings or tables to table&lt;br /&gt;
		parentTable[#parentTable + 1] = content&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Main entry point&lt;br /&gt;
function p.slot( f )&lt;br /&gt;
	local args = getArgs(f)&lt;br /&gt;
	&lt;br /&gt;
	if not args.parsed then&lt;br /&gt;
		args[1] = string.trim( args[1] and (args[1]:gsub(&amp;quot;(%s)%s+&amp;quot;, &amp;quot;%1&amp;quot;)) or &amp;#039;&amp;#039; )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Prepare List of &amp;quot;Frames&amp;quot;&lt;br /&gt;
	local frames&lt;br /&gt;
	if args.parsed then&lt;br /&gt;
		frames = args[1]&lt;br /&gt;
	elseif args[1] ~= &amp;#039;&amp;#039; then&lt;br /&gt;
		local randomise = args.class == &amp;#039;invslot-large&amp;#039; and &amp;#039;never&amp;#039; or nil&lt;br /&gt;
		frames = p.parseFrameText( args[1], randomise, false )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if not frames then&lt;br /&gt;
		local body = p.makeBody( args, false )&lt;br /&gt;
		return tostring(body:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;invslot-item&amp;#039;):done())&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Create Slot Item for Each &amp;quot;Frame&amp;quot;&lt;br /&gt;
	if args.display == &amp;#039;grid&amp;#039; or args.display == &amp;#039;inline-grid&amp;#039; then -- display: grid&lt;br /&gt;
		local inline = args.display == &amp;#039;inline-grid&amp;#039;&lt;br /&gt;
		local grid = mw.html.create(&amp;#039;div&amp;#039;):addClass(inline and &amp;#039;&amp;#039; or &amp;#039; mcui-centered&amp;#039;)&lt;br /&gt;
		local row&lt;br /&gt;
		local gridcol = tonumber(args.grid_columns) or 6&lt;br /&gt;
		if gridcol &amp;lt; 1 then&lt;br /&gt;
			row = mw.html.create(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-row&amp;#039;)&lt;br /&gt;
			grid:node( row )&lt;br /&gt;
			for index, frame in ipairs( frames ) do&lt;br /&gt;
				local body = p.makeBody( args, animated )&lt;br /&gt;
				local item = p.makeItem( frame, index, args )&lt;br /&gt;
				body:node( item )&lt;br /&gt;
				row:node( body )&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			for index, frame in ipairs( frames ) do&lt;br /&gt;
				if gridcol == 1 or index % gridcol == 1 then&lt;br /&gt;
					-- new row&lt;br /&gt;
					row = mw.html.create(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-row&amp;#039;)&lt;br /&gt;
					grid:node( row )&lt;br /&gt;
				end&lt;br /&gt;
				local body = p.makeBody( args, animated )&lt;br /&gt;
				local item = p.makeItem( frame, index, args )&lt;br /&gt;
				body:node( item )&lt;br /&gt;
				row:node( body )&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return tostring( grid )&lt;br /&gt;
	else -- display: animated&lt;br /&gt;
		local activeFrame = frames.randomise == true and random.number{ #frames } or 1&lt;br /&gt;
		local animated = frames and #frames &amp;gt; 1 and (args.display or &amp;#039;animated&amp;#039;) == &amp;#039;animated&amp;#039;&lt;br /&gt;
		local body = p.makeBody( args, animated )&lt;br /&gt;
		for index, frame in ipairs( frames ) do&lt;br /&gt;
			local item = p.makeItem( frame, index, args )&lt;br /&gt;
			body:node( item )&lt;br /&gt;
			if index == activeFrame and animated then&lt;br /&gt;
				item:addClass( &amp;#039;animated-active&amp;#039; )&lt;br /&gt;
			elseif animated then&lt;br /&gt;
				-- CUSTOM: &amp;quot;nomobile&amp;quot; class is needed to hide it on mobile (since Fandom doesn&amp;#039;t allow JS on mobile)&lt;br /&gt;
				item:addClass( &amp;#039;nomobile&amp;#039; )&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return tostring( body )&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[Creates the HTML for a single Top-level Slot Element&lt;br /&gt;
--]]&lt;br /&gt;
function p.makeBody( args, animated )&lt;br /&gt;
	local body = mw.html.create( &amp;#039;span&amp;#039; ):addClass( &amp;#039;invslot&amp;#039; ):css{ [&amp;#039;vertical-align&amp;#039;] = args.align }&lt;br /&gt;
	if animated then&lt;br /&gt;
		body:addClass( &amp;#039;animated&amp;#039; )&lt;br /&gt;
	end&lt;br /&gt;
	if args.class then&lt;br /&gt;
		body:addClass( args.class )&lt;br /&gt;
	end&lt;br /&gt;
	if args.style then&lt;br /&gt;
		body:cssText( args.style )&lt;br /&gt;
	end&lt;br /&gt;
	return body&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[Creates the HTML for a single Slot Item&lt;br /&gt;
--]]&lt;br /&gt;
function p.makeItem( frame, i, args )&lt;br /&gt;
	-- Initialize Element&lt;br /&gt;
	local item = mw.html.create( &amp;#039;span&amp;#039; ):addClass( &amp;#039;invslot-item&amp;#039; )&lt;br /&gt;
	if args.imgclass then&lt;br /&gt;
		item:addClass( args.imgclass )&lt;br /&gt;
	end&lt;br /&gt;
	if frame.image_id then&lt;br /&gt;
		item:attr(&amp;#039;data-iid&amp;#039;, frame.image_id)&lt;br /&gt;
	end&lt;br /&gt;
	if frame.name == &amp;#039;&amp;#039; then&lt;br /&gt;
		return item&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local category&lt;br /&gt;
	local name = frame.name or &amp;#039;&amp;#039;&lt;br /&gt;
	-- Top-level inheritance handling (args inherits item)&lt;br /&gt;
	local rp_title = (frame.title or &amp;#039;&amp;#039;):gsub(&amp;#039;%%&amp;#039;, &amp;#039;%%%%&amp;#039;)&lt;br /&gt;
	local rp_description = (frame.text or &amp;#039;&amp;#039;):gsub(&amp;#039;%%&amp;#039;, &amp;#039;%%%%&amp;#039;)&lt;br /&gt;
	local title = (args.title or &amp;#039;%inherit%&amp;#039;):gsub(&amp;#039;%%inherit%%&amp;#039;, rp_title)&lt;br /&gt;
	local description = (args.text or &amp;#039;%inherit%&amp;#039;):gsub(&amp;#039;%%inherit%%&amp;#039;, rp_description)&lt;br /&gt;
	local n_1 = tonumber(frame.num) or 1&lt;br /&gt;
	local n_2 = tonumber(frame.num2)&lt;br /&gt;
	local n_str, n_fs, n_r&lt;br /&gt;
	local image = args.image or frame.image or nil&lt;br /&gt;
	local img&lt;br /&gt;
	&lt;br /&gt;
	-- Handle Image&lt;br /&gt;
	if frame.image_id then -- has CSS handled image ID: don&amp;#039;t display image&lt;br /&gt;
		img = nil&lt;br /&gt;
	elseif image and string.anyMatched(image, &amp;#039;%.gif$&amp;#039;, &amp;#039;%.webp$&amp;#039;, &amp;#039;%.png$&amp;#039;, &amp;#039;%.apng$&amp;#039;, &amp;#039;%.jpg$&amp;#039;, &amp;#039;%.jpeg$&amp;#039;) then&lt;br /&gt;
		img = image&lt;br /&gt;
	else&lt;br /&gt;
		img = (image or name) .. &amp;#039;.png&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	-- Handle Link&lt;br /&gt;
	local link = args.link or frame.link or &amp;#039;&amp;#039;&lt;br /&gt;
	if link == &amp;#039;&amp;#039; then&lt;br /&gt;
		link = name&lt;br /&gt;
	end&lt;br /&gt;
	if link:lower() == &amp;#039;none&amp;#039; then&lt;br /&gt;
		link = nil&lt;br /&gt;
	else&lt;br /&gt;
		-- (Handle Link Redirects)&lt;br /&gt;
		local rtName = mw.title.makeTitle(0, link or &amp;#039;&amp;#039;) or false&lt;br /&gt;
		rtName = rtName and rtName.redirectTarget and rtName.redirectTarget.text or false&lt;br /&gt;
		local unfragmentedLink = (link or &amp;#039;&amp;#039;):gsub(&amp;#039;^(.-)#.-$&amp;#039;, &amp;#039;%1&amp;#039;)&lt;br /&gt;
		if unfragmentedLink == pageName or rtName == pageName then&lt;br /&gt;
			link = nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- Handle Numbers&lt;br /&gt;
	if not (n_1 and n_2 and n_1 ~= n_2) then&lt;br /&gt;
		-- No second number&lt;br /&gt;
		n_2 = nil&lt;br /&gt;
	end&lt;br /&gt;
	if (n_1 or 0) &amp;gt;= 10000 then&lt;br /&gt;
		n_1 = string._formatShortNum(n_1):lower()&lt;br /&gt;
	end&lt;br /&gt;
	if (n_2 or 0) &amp;gt;= 10000 then&lt;br /&gt;
		n_2 = string._formatShortNum(n_2):lower()&lt;br /&gt;
	end&lt;br /&gt;
	if yesno(args.forcenum) or ((not n_2) and n_1 and n_1 ~= 1) or (n_1 and n_2) then&lt;br /&gt;
		-- Entering condition for displaying numbers (else, n_str undefined)&lt;br /&gt;
		local function len(n)&lt;br /&gt;
			return n and tostring(n):len() or 0&lt;br /&gt;
		end&lt;br /&gt;
		if n_1 and n_2 then&lt;br /&gt;
			n_1 = tostring(n_1) .. &amp;#039;-&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		local splitLine = n_2 and (len(n_1) + len(n_2) &amp;gt; 4)&lt;br /&gt;
		-- Deciding font-size (n_fs) and right (n_r) values&lt;br /&gt;
		if (len(n_1) &amp;gt; 7) or (len(n_2) &amp;gt; 7) then&lt;br /&gt;
			n_fs = 5.4; n_r = 1.2&lt;br /&gt;
		elseif (len(n_1) &amp;gt; 6) or (len(n_2) &amp;gt; 6) then&lt;br /&gt;
			n_fs = 6.1; n_r = 1.3&lt;br /&gt;
		elseif (len(n_1) &amp;gt; 5) or (len(n_2) &amp;gt; 5) then&lt;br /&gt;
			n_fs = 7.2; n_r = 1.6&lt;br /&gt;
		elseif (len(n_1) &amp;gt; 3) or (len(n_2) &amp;gt; 3) or splitLine then&lt;br /&gt;
			n_fs = 9; n_r = 1&lt;br /&gt;
		elseif n_2 or splitLine then&lt;br /&gt;
			n_fs = 12; n_r = 0&lt;br /&gt;
		else&lt;br /&gt;
			n_fs = 15; n_r = 0&lt;br /&gt;
		end&lt;br /&gt;
		-- Stringify Numbers&lt;br /&gt;
		n_str = n_2 and (n_1 .. (splitLine and &amp;#039;&amp;lt;br&amp;gt;&amp;#039; or &amp;#039;&amp;#039;) .. n_2) or n_1&lt;br /&gt;
	end&lt;br /&gt;
	-- Handle Title&lt;br /&gt;
	local formattedTitle, plainTitle&lt;br /&gt;
	title = uitext.applyReplacements(title)&lt;br /&gt;
	if title == &amp;#039;&amp;#039; then&lt;br /&gt;
		plainTitle = name&lt;br /&gt;
		formattedTitle = name&lt;br /&gt;
	elseif title:lower() ~= &amp;#039;none&amp;#039; then&lt;br /&gt;
		formattedTitle = title&lt;br /&gt;
		plainTitle = title&lt;br /&gt;
		local formatPattern = &amp;#039;&amp;amp;[0-9a-fk-or]&amp;#039;&lt;br /&gt;
		if plainTitle:match( formatPattern ) then&lt;br /&gt;
			plainTitle = plainTitle:gsub( formatPattern, &amp;#039;&amp;#039; )&lt;br /&gt;
		end&lt;br /&gt;
		if plainTitle == &amp;#039;&amp;#039; then&lt;br /&gt;
			plainTitle = name&lt;br /&gt;
		end&lt;br /&gt;
	elseif link then&lt;br /&gt;
		if img then&lt;br /&gt;
			formattedTitle = &amp;#039;&amp;#039;&lt;br /&gt;
		else&lt;br /&gt;
			plainTitle = &amp;#039;&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- Handle Description&lt;br /&gt;
	description = uitext.applyReplacements(description)&lt;br /&gt;
	if description:lower() == &amp;#039;none&amp;#039; then description = &amp;#039;&amp;#039; end&lt;br /&gt;
	-- (Transform newlines into `/`)&lt;br /&gt;
	if description and description:match(&amp;quot;\n&amp;quot;) then&lt;br /&gt;
		description = description:gsub(&amp;quot;\n&amp;quot;, &amp;quot;/&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Now, Prepare Element&lt;br /&gt;
	-- Insert Title/Text&lt;br /&gt;
	item:attr{&lt;br /&gt;
		[&amp;#039;data-minetip-title&amp;#039;] = formattedTitle and formattedTitle:gsub(&amp;#039;&amp;quot;&amp;#039;, &amp;#039;&amp;amp;quot;&amp;#039;) or nil,&lt;br /&gt;
		[&amp;#039;data-minetip-text&amp;#039;] = description and description:gsub(&amp;#039;&amp;quot;&amp;#039;, &amp;#039;&amp;amp;quot;&amp;#039;) or nil,&lt;br /&gt;
	}&lt;br /&gt;
	-- Insert Image&lt;br /&gt;
	if img then&lt;br /&gt;
		-- &amp;amp; is re-escaped because mw.html treats attributes&lt;br /&gt;
		-- as plain text, but MediaWiki doesn&amp;#039;t&lt;br /&gt;
		local escapedTitle = ( plainTitle or &amp;#039;&amp;#039; ):gsub( &amp;#039;&amp;amp;&amp;#039;, &amp;#039;&amp;amp;#38;&amp;#039; )&lt;br /&gt;
		item:addClass( &amp;#039;invslot-item-image&amp;#039; )&lt;br /&gt;
			:wikitext( &amp;#039;[[File:&amp;#039;, img, &amp;#039;|32x32px|link=&amp;#039;, link or &amp;#039;&amp;#039;, &amp;#039;|&amp;#039;, escapedTitle, &amp;#039;]]&amp;#039; )&lt;br /&gt;
	end&lt;br /&gt;
	-- Insert Numbers&lt;br /&gt;
	if n_str then&lt;br /&gt;
		local stacksizeElm = item:tag( &amp;#039;span&amp;#039; )&lt;br /&gt;
			:addClass( &amp;#039;invslot-stacksize&amp;#039; )&lt;br /&gt;
			:attr{ title = plainTitle }&lt;br /&gt;
		stacksizeElm:css(&amp;#039;font-size&amp;#039;, n_fs .. &amp;#039;px&amp;#039;):css(&amp;#039;right&amp;#039;, (n_r - 2) .. &amp;#039;px&amp;#039;)&lt;br /&gt;
		if args.numStyle then&lt;br /&gt;
			stacksizeElm:cssText( args.numStyle )&lt;br /&gt;
		end&lt;br /&gt;
		stacksizeElm:wikitext( n_str )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return item&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[Parses the frame text into a table of frames,&lt;br /&gt;
	expanding aliases, and&lt;br /&gt;
	deciding if the slot can be randomised&lt;br /&gt;
--]]&lt;br /&gt;
function p.parseFrameText( framesText, randomise )&lt;br /&gt;
	local frames = { randomise = randomise }&lt;br /&gt;
	local expandedAliases&lt;br /&gt;
	framesText = framesText:gsub( &amp;#039;\\;&amp;#039;, &amp;#039;%%SEMICOLON%%&amp;#039; );-- gsub here allows us to escape ; character&lt;br /&gt;
	local splitFrames = string.split( string.trim( framesText ), &amp;#039;%s*;%s*&amp;#039; )&lt;br /&gt;
	for _, frameText in ipairs( splitFrames ) do&lt;br /&gt;
		frameText = frameText:gsub(&amp;#039;%%SEMICOLON%%&amp;#039;, &amp;#039;;&amp;#039;) -- undo-escape now that semicolon regex check is done&lt;br /&gt;
		-- Now, Parse Frame Text&lt;br /&gt;
		local frame = p.makeFrame( frameText )&lt;br /&gt;
		local newFrame = frame&lt;br /&gt;
		local id = frame.name&lt;br /&gt;
		local id_trim = frame.name:gsub(&amp;#039;^%?&amp;#039;, &amp;#039;&amp;#039;):gsub(&amp;#039;^%*&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
		-- Find Frame Alias and Combine With Frame&lt;br /&gt;
		local alias, variants&lt;br /&gt;
		if frame.name ~= id_trim then&lt;br /&gt;
			variants = itemVariantsCache:get(id_trim)&lt;br /&gt;
		end&lt;br /&gt;
		if variants then&lt;br /&gt;
			alias = {}&lt;br /&gt;
			for i, v in ipairs(variants) do&lt;br /&gt;
				-- local alt = slotAliasesCache:get(v, 1)&lt;br /&gt;
				local alt = slotAliases[v]&lt;br /&gt;
				alias[i] = alt and invslotCache:get(alt, 1) or invslotCache:get(v, 1) or v&lt;br /&gt;
				-- note: this falls back to the string (v) instead of leaving alias[i] a nil&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- local alt = slotAliasesCache:get(id, 1)&lt;br /&gt;
			local alt = slotAliases[id]&lt;br /&gt;
			alias = alt and invslotCache:get(alt, 1) or invslotCache:get(id, 1)&lt;br /&gt;
		end&lt;br /&gt;
		if alias then&lt;br /&gt;
			newFrame = p.combineFrames( alias, frame )&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Randomise starting frame for &amp;quot;Any *&amp;quot; aliases, as long as the alias is the only frame&lt;br /&gt;
		if frames.randomise == nil and frame.name:match( &amp;#039;^%?&amp;#039; ) then&lt;br /&gt;
			frames.randomise = true&lt;br /&gt;
		elseif frames.randomise ~= &amp;#039;never&amp;#039; then&lt;br /&gt;
			frames.randomise = false&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		mergeList( frames, newFrame )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return frames&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[Returns a new table with the parsed frame values&lt;br /&gt;
	added to alias frames (parsed frame overrides alias frames)&lt;br /&gt;
--]]&lt;br /&gt;
function p.combineFrames( aliasFrames, parsedFrame )&lt;br /&gt;
	-- If alias is just a name, return the parsed frame with the new name&lt;br /&gt;
	if type( aliasFrames ) == &amp;#039;string&amp;#039; then&lt;br /&gt;
		local expandedFrame = mw.clone( parsedFrame )&lt;br /&gt;
		expandedFrame.name = aliasFrames&lt;br /&gt;
		return { expandedFrame }&lt;br /&gt;
	end&lt;br /&gt;
	-- Single frame alias, put in list&lt;br /&gt;
	if aliasFrames.name then&lt;br /&gt;
		aliasFrames = { aliasFrames }&lt;br /&gt;
	end&lt;br /&gt;
	-- Prepare new table, combine frames&lt;br /&gt;
	local expandedFrames = {}&lt;br /&gt;
	for i, aliasFrame in ipairs( aliasFrames ) do&lt;br /&gt;
		local expandedFrame&lt;br /&gt;
		if type( aliasFrame ) == &amp;#039;string&amp;#039; then&lt;br /&gt;
			expandedFrame = { name = aliasFrame }&lt;br /&gt;
		else&lt;br /&gt;
			expandedFrame = table.deepCopy( aliasFrame, true )&lt;br /&gt;
		end&lt;br /&gt;
		for _, param in ipairs(availableFrameParameters) do&lt;br /&gt;
			expandedFrame[param] = parsedFrame[param] or expandedFrame[param]&lt;br /&gt;
		end&lt;br /&gt;
		-- Lower-level inheritance handling (parsed item inherits alias)&lt;br /&gt;
		if aliasFrame.title then&lt;br /&gt;
			local rp = aliasFrame.title:gsub(&amp;#039;%%&amp;#039;, &amp;#039;%%%%&amp;#039;)&lt;br /&gt;
			expandedFrame.title = (expandedFrame.title or &amp;#039;%inherit%&amp;#039;):gsub(&amp;#039;%%inherit%%&amp;#039;, rp)&lt;br /&gt;
		end&lt;br /&gt;
		if aliasFrame.text then&lt;br /&gt;
			local rp = aliasFrame.text:gsub(&amp;#039;%%&amp;#039;, &amp;#039;%%%%&amp;#039;)&lt;br /&gt;
			expandedFrame.text = (expandedFrame.text or &amp;#039;%inherit%&amp;#039;):gsub(&amp;#039;%%inherit%%&amp;#039;, rp)&lt;br /&gt;
		end&lt;br /&gt;
		expandedFrames[i] = expandedFrame&lt;br /&gt;
	end&lt;br /&gt;
	return expandedFrames&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[Parses frame text into a table&lt;br /&gt;
	[&amp;lt;Title&amp;gt;]&amp;lt;image&amp;gt;:&amp;lt;item&amp;gt;,&amp;lt;count&amp;gt;[&amp;lt;description&amp;gt;]&lt;br /&gt;
-]]&lt;br /&gt;
function p.makeFrame( frameText )&lt;br /&gt;
	local function forwardSubstitute(text)&lt;br /&gt;
		return text:gsub( &amp;#039;\\\\&amp;#039;, &amp;#039;%%BACKSLASH%%&amp;#039; ):gsub( &amp;#039;\\%[&amp;#039;, &amp;#039;%%SQBRACL%%&amp;#039; ):gsub( &amp;#039;\\%]&amp;#039;, &amp;#039;%%SQBRACR%%&amp;#039; ):gsub( &amp;#039;\\:&amp;#039;, &amp;#039;%%COLON%%&amp;#039; ):gsub( &amp;#039;\\,&amp;#039;, &amp;#039;%%COMMA%%&amp;#039; )&lt;br /&gt;
	end&lt;br /&gt;
	local function backSubstitute(text)&lt;br /&gt;
		return text:gsub(&amp;#039;%%BACKSLASH%%&amp;#039;,&amp;#039;\\&amp;#039;):gsub(&amp;#039;%%SQBRACL%%&amp;#039;,&amp;#039;[&amp;#039;):gsub(&amp;#039;%%SQBRACR%%&amp;#039;,&amp;#039;]&amp;#039;):gsub(&amp;#039;%%COLON%%&amp;#039;,&amp;#039;:&amp;#039;):gsub(&amp;#039;%%COMMA%%&amp;#039;,&amp;#039;,&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	local c = currency._newCurrencySlot( frameText )&lt;br /&gt;
	if c then return c end&lt;br /&gt;
	-- Simple frame with no parts&lt;br /&gt;
	if type(frameText) ~= &amp;#039;string&amp;#039; then error(type(frameText)) end&lt;br /&gt;
	-- [ESC] allow escaping special characters - we&amp;#039;ll convert normal character after we parse&lt;br /&gt;
	frameText = forwardSubstitute(frameText)&lt;br /&gt;
	&lt;br /&gt;
	if not frameText:match( &amp;#039;[%[:,]&amp;#039; ) then&lt;br /&gt;
		frameText = backSubstitute(frameText)&lt;br /&gt;
		return {&lt;br /&gt;
			name = string.trim(frameText),&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	frameText = frameText:gsub( &amp;#039;%s*([%[%]:,;])%s*&amp;#039;, &amp;#039;%1&amp;#039; )&lt;br /&gt;
	&lt;br /&gt;
	local frame = {}&lt;br /&gt;
	frame.title = frameText:match( &amp;#039;^%[([^%]]+)%]&amp;#039; )&lt;br /&gt;
	frame.image = frameText:match( &amp;#039;([^:%]]+):&amp;#039; )&lt;br /&gt;
	&lt;br /&gt;
	local nameStart = ( frameText:find( &amp;#039;:&amp;#039; ) or frameText:find( &amp;#039;%]&amp;#039; ) or 0 ) + 1&lt;br /&gt;
	if nameStart - 1 == #frameText then&lt;br /&gt;
		nameStart = 1&lt;br /&gt;
	end&lt;br /&gt;
	frame.name = frameText:sub( nameStart, ( frameText:find( &amp;#039;[,%[]&amp;#039;, nameStart ) or 0 ) - 1 )&lt;br /&gt;
	&lt;br /&gt;
	-- Handle m-n syntax&lt;br /&gt;
	frame.num = math.floor( frameText:match( &amp;#039;,%s*(%d+)&amp;#039; ) or 1 )&lt;br /&gt;
	frame.num2 = math.floor( frameText:match( &amp;#039;,%s*%d+%s*[%-%–]%s*(%d+)%s*&amp;#039; ) or frame.num )&lt;br /&gt;
	frame.text = frameText:match( &amp;#039;%[([^%]]+)%]$&amp;#039; )&lt;br /&gt;
	&lt;br /&gt;
	-- [/ESC] un-replace the characters we used for escaped characters earlier&lt;br /&gt;
	if frame.title then frame.title = backSubstitute(frame.title) end&lt;br /&gt;
	if frame.name then frame.name = backSubstitute(frame.name) end&lt;br /&gt;
	if frame.text then frame.text = backSubstitute(frame.text) end&lt;br /&gt;
	&lt;br /&gt;
	-- Transform newlines into `/`&lt;br /&gt;
	if frame.text and frame.text:match(&amp;quot;\n&amp;quot;) then&lt;br /&gt;
		frame.text = frame.text:gsub(&amp;quot;\n&amp;quot;, &amp;quot;/&amp;quot;)	&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return frame&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------&lt;br /&gt;
-- Other Features&lt;br /&gt;
-------------------------------------&lt;br /&gt;
&lt;br /&gt;
p.getAlias = p.combineFrames&lt;br /&gt;
function p.expandAlias( parsedFrame, alias )&lt;br /&gt;
	return p.combineFrames( alias, parsedFrame )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- create [%s]%s,%s[%s] and escape symbols&lt;br /&gt;
function p.stringifyFrame( frame )&lt;br /&gt;
	local function escape(s)&lt;br /&gt;
		return s:gsub( &amp;#039;\\&amp;#039;, &amp;#039;\\\\&amp;#039; ):gsub( &amp;#039;([%[%]:,;])&amp;#039;, &amp;#039;\\%1&amp;#039; )&lt;br /&gt;
	end&lt;br /&gt;
	local s = frame.name or frame[1]&lt;br /&gt;
	if not s then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	s = escape(s)&lt;br /&gt;
	if frame.num then&lt;br /&gt;
		s = (&amp;#039;%s,%s&amp;#039;):format(s, escape(frame.num))&lt;br /&gt;
	end&lt;br /&gt;
	if frame.title then&lt;br /&gt;
		s = (&amp;#039;[%s]%s&amp;#039;):format(escape(frame.title), s)&lt;br /&gt;
	end&lt;br /&gt;
	if frame.text then&lt;br /&gt;
		s = (&amp;#039;%s[%s]&amp;#039;):format(s, escape(frame.text))&lt;br /&gt;
	end&lt;br /&gt;
	return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.stringifyFrames( frames )&lt;br /&gt;
	for i, frame in ipairs( frames ) do&lt;br /&gt;
		frames[i] = p.stringifyFrame( frame )&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat( frames, &amp;#039;;&amp;#039; )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>515797455988850689</name></author>
	</entry>
</feed>