<?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%3AUI</id>
	<title>Module:UI - 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%3AUI"/>
	<link rel="alternate" type="text/html" href="https://wiki.earthmc.net/index.php?title=Module:UI&amp;action=history"/>
	<updated>2026-10-27T19:06:43Z</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:UI&amp;diff=234620&amp;oldid=prev</id>
		<title>515797455988850689: Created page with &quot;--&lt;pre&gt; -- Taken from: https://minecraft.gamepedia.com/Module:UI local getArgs = require(&#039;Module:Arguments&#039;).getArgs local mergeArgsSyntax = require(&#039;Module:Arguments&#039;).mergeArgsSyntax local loader = require(&#039;Module:Loader&#039;)  local string, table, yesno, uiText, inventorySlot, crafting, Interface, random, mctxt = 	loader.lazy.require(&#039;String&#039;, &#039;Table&#039;, &#039;Yesno&#039;, &#039;UIText&#039;, &#039;Inventory slot&#039;, &#039;Crafting&#039;, &#039;UI/Core&#039;, &#039;Random&#039;, &#039;Mctxt&#039;)  local slot = function(...) 	return invent...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.earthmc.net/index.php?title=Module:UI&amp;diff=234620&amp;oldid=prev"/>
		<updated>2023-11-25T08:18:10Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;--&amp;lt;pre&amp;gt; -- Taken from: https://minecraft.gamepedia.com/Module:UI local getArgs = require(&amp;#039;Module:Arguments&amp;#039;).getArgs local mergeArgsSyntax = require(&amp;#039;Module:Arguments&amp;#039;).mergeArgsSyntax local loader = require(&amp;#039;Module:Loader&amp;#039;)  local string, table, yesno, uiText, inventorySlot, crafting, Interface, random, mctxt = 	loader.lazy.require(&amp;#039;String&amp;#039;, &amp;#039;Table&amp;#039;, &amp;#039;Yesno&amp;#039;, &amp;#039;UIText&amp;#039;, &amp;#039;Inventory slot&amp;#039;, &amp;#039;Crafting&amp;#039;, &amp;#039;UI/Core&amp;#039;, &amp;#039;Random&amp;#039;, &amp;#039;Mctxt&amp;#039;)  local slot = function(...) 	return invent...&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;
-- Taken from: https://minecraft.gamepedia.com/Module:UI&lt;br /&gt;
local getArgs = require(&amp;#039;Module:Arguments&amp;#039;).getArgs&lt;br /&gt;
local mergeArgsSyntax = require(&amp;#039;Module:Arguments&amp;#039;).mergeArgsSyntax&lt;br /&gt;
local loader = require(&amp;#039;Module:Loader&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local string, table, yesno, uiText, inventorySlot, crafting, Interface, random, mctxt =&lt;br /&gt;
	loader.lazy.require(&amp;#039;String&amp;#039;, &amp;#039;Table&amp;#039;, &amp;#039;Yesno&amp;#039;, &amp;#039;UIText&amp;#039;, &amp;#039;Inventory slot&amp;#039;, &amp;#039;Crafting&amp;#039;, &amp;#039;UI/Core&amp;#039;, &amp;#039;Random&amp;#039;, &amp;#039;Mctxt&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local slot = function(...)&lt;br /&gt;
	return inventorySlot.slot(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local function getrandomid()&lt;br /&gt;
	return &amp;#039;ui-&amp;#039; .. random.number{100000000, 999999999}&lt;br /&gt;
end&lt;br /&gt;
local function wrapdiv(s, wr)&lt;br /&gt;
	return yesno(wr, false) and (&amp;#039;&amp;lt;div class=&amp;quot;sbw-ui-tabber&amp;quot;&amp;gt;%s&amp;lt;/div&amp;gt;&amp;#039;):format(s) or s&lt;br /&gt;
end&lt;br /&gt;
local function slotNotation(m, n)&lt;br /&gt;
	if tonumber(m) and tonumber(n) then&lt;br /&gt;
		return (&amp;#039;%s, %s&amp;#039;):format(m, n)&lt;br /&gt;
	elseif m and not n then&lt;br /&gt;
		local m, n = tostring(m):match(&amp;#039;^(%d+)%s*,%s*(%d+)$&amp;#039;)&lt;br /&gt;
		if m and n then&lt;br /&gt;
			return (&amp;#039;%s, %s&amp;#039;):format(m, n)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
local function rc(r, c, nospace)&lt;br /&gt;
	return (&amp;#039;%s,%s%s&amp;#039;):format(r, nospace and &amp;#039;&amp;#039; or &amp;#039; &amp;#039;, c)&lt;br /&gt;
end&lt;br /&gt;
local function pagerid(base, i)&lt;br /&gt;
	if i &amp;gt; 1 then&lt;br /&gt;
		base = (&amp;#039;%s-%s&amp;#039;):format(base, i)&lt;br /&gt;
	end&lt;br /&gt;
	return base&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Furnace&lt;br /&gt;
function p.furnace( frame )&lt;br /&gt;
	local args = getArgs(frame)&lt;br /&gt;
	&lt;br /&gt;
	local body = mw.html.create(&amp;#039;span&amp;#039;):addClass(&amp;#039;mcui mcui-Furnace&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	local input = body:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;mcui-input&amp;#039;)&lt;br /&gt;
	input:wikitext(crafting.addSlot(args, &amp;#039;Input&amp;#039;, &amp;#039;I&amp;#039;))&lt;br /&gt;
	local fuel = input:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;mcui-fuel&amp;#039;):done()&lt;br /&gt;
	local burning = (( args.Input or &amp;#039;&amp;#039; ) ~= &amp;#039;&amp;#039;) or (( args.Fuel or &amp;#039;&amp;#039; ) ~= &amp;#039;&amp;#039;)&lt;br /&gt;
	if not burning then&lt;br /&gt;
		fuel:addClass(&amp;#039;mcui-inactive&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	input:wikitext(crafting.addSlot(args, &amp;#039;Fuel&amp;#039;, &amp;#039;F&amp;#039;))&lt;br /&gt;
	&lt;br /&gt;
	local arrow = body:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;mcui-arrow&amp;#039;):done()&lt;br /&gt;
	if not burning or (args.Output or &amp;#039;&amp;#039;) == &amp;#039;&amp;#039; then&lt;br /&gt;
		arrow:addClass(&amp;#039;mcui-inactive&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	body:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;mcui-output&amp;#039;)&lt;br /&gt;
		:wikitext(crafting.addSlot(args, &amp;#039;Output&amp;#039;, &amp;#039;O&amp;#039;, &amp;#039;invslot-large&amp;#039;))&lt;br /&gt;
	&lt;br /&gt;
	return tostring(mw.html.create(&amp;#039;div&amp;#039;):node(body))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Brewing Stand&lt;br /&gt;
function p.brewingStand( frame )&lt;br /&gt;
	local args = getArgs(frame)&lt;br /&gt;
	&lt;br /&gt;
	local body = mw.html.create(&amp;#039;span&amp;#039;):addClass(&amp;#039;mcui mcui-Brewing_Stand&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	local input = body:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;mcui-input&amp;#039;)&lt;br /&gt;
	input:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;mcui-bubbling&amp;#039;)&lt;br /&gt;
	input:wikitext(crafting.addSlot(args, &amp;#039;Input&amp;#039;, &amp;#039;I&amp;#039;))&lt;br /&gt;
	input:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;mcui-arrow&amp;#039;)&lt;br /&gt;
	if (args.Input or &amp;#039;&amp;#039;) == &amp;#039;&amp;#039; or&lt;br /&gt;
		((args.Output1 or &amp;#039;&amp;#039;) == &amp;#039;&amp;#039; and (args.Output2 or &amp;#039;&amp;#039;) == &amp;#039;&amp;#039; and (args.Output3 or &amp;#039;&amp;#039;) == &amp;#039;&amp;#039;)&lt;br /&gt;
	then&lt;br /&gt;
		input:addClass(&amp;#039;mcui-inactive&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	body:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;mcui-paths&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	local output = body:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;mcui-output&amp;#039;)&lt;br /&gt;
	for i = 1, 3 do&lt;br /&gt;
		output:wikitext(crafting.addSlot(args, &amp;#039;Output&amp;#039; .. i, &amp;#039;O&amp;#039; .. i, &amp;#039;mcui-output&amp;#039; .. i))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return tostring(mw.html.create(&amp;#039;div&amp;#039;):node(body))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Anvil&lt;br /&gt;
function p.anvil( frame )&lt;br /&gt;
	local args = getArgs(frame)&lt;br /&gt;
	local in1 = crafting.addSlot(args, &amp;#039;Input1&amp;#039;, &amp;#039;I1&amp;#039;)&lt;br /&gt;
	local in2 = crafting.addSlot(args, &amp;#039;Input2&amp;#039;, &amp;#039;I2&amp;#039;)&lt;br /&gt;
	local out1 = crafting.addSlot(args, &amp;#039;Output&amp;#039;, &amp;#039;O&amp;#039;)&lt;br /&gt;
	local header = args.header or &amp;#039;Repair &amp;amp;amp; Name&amp;#039;&lt;br /&gt;
	local title = args.title or &amp;#039;&amp;#039;&lt;br /&gt;
	&lt;br /&gt;
	local isCrossed = yesno(args.crossed, false)&lt;br /&gt;
	local isExpensive = yesno(args.expensive, false) or args.cost == &amp;#039;expensive&amp;#039;&lt;br /&gt;
	local displayCost = args.costtext or&lt;br /&gt;
		(args.cost == &amp;#039;expensive&amp;#039; and &amp;#039;Too expensive!&amp;#039;) or&lt;br /&gt;
		(args.cost and &amp;#039;Enchantment Cost: &amp;#039; .. args.cost) or nil&lt;br /&gt;
	&lt;br /&gt;
	local body = mw.html.create(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui mcui-Anvil&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	local top = body:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-top&amp;#039;)&lt;br /&gt;
	top:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-hammer&amp;#039;)&lt;br /&gt;
	local topleft = top:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-topleft&amp;#039;)&lt;br /&gt;
	topleft:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-header&amp;#039;):wikitext(header)&lt;br /&gt;
	local guibar = topleft:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-guibar&amp;#039;)&lt;br /&gt;
	guibar:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-header mcui-guitext format-f&amp;#039;):wikitext(title)&lt;br /&gt;
	&lt;br /&gt;
	local bottom = body:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-bottom&amp;#039;)&lt;br /&gt;
	bottom:node(in1)&lt;br /&gt;
	bottom:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-plus&amp;#039;)&lt;br /&gt;
	bottom:node(in2)&lt;br /&gt;
	bottom:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-arrow&amp;#039; .. (isCrossed and &amp;#039; mcui-disabled&amp;#039; or &amp;#039;&amp;#039;))&lt;br /&gt;
	bottom:node(out1)&lt;br /&gt;
	&lt;br /&gt;
	if displayCost then&lt;br /&gt;
		body:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;mcui-header mcui-cost&amp;#039; .. (isExpensive and &amp;#039; mcui-expensive&amp;#039; or &amp;#039;&amp;#039;)):wikitext(displayCost)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return tostring(mw.html.create(&amp;#039;div&amp;#039;):node(body))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- AnvilSB&lt;br /&gt;
function p.anvilSB( frame )&lt;br /&gt;
	function handleSkyBlockItemSpecialCases(itemName)&lt;br /&gt;
		if not itemName then return nil end&lt;br /&gt;
	    itemName = itemName:gsub(&amp;quot;Enchanted Book %((.+)%)&amp;quot;, &amp;quot;%1&amp;quot;)&lt;br /&gt;
	    return itemName&lt;br /&gt;
	end&lt;br /&gt;
	-- Removes strings inside square brackets, inside round brackets, before a colon, after a comma, or after a semicolon&lt;br /&gt;
	function determineTitle(itemName)&lt;br /&gt;
		if not itemName then return nil end&lt;br /&gt;
	    itemName = itemName:gsub(&amp;quot;%b[]&amp;quot;, &amp;quot;&amp;quot;):gsub(&amp;quot;%b()&amp;quot;, &amp;quot;&amp;quot;):gsub(&amp;quot;[^:]+:&amp;quot;, &amp;quot;&amp;quot;):gsub(&amp;quot;,[^,]*&amp;quot;, &amp;quot;&amp;quot;):gsub(&amp;quot;;[^;]*&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
	    return string.trim(itemName)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local args = getArgs(frame)&lt;br /&gt;
	args.header = args.header or &amp;#039;Combine Items&amp;#039;&lt;br /&gt;
	args.costtext = &amp;#039;Exp Levels Cost: &amp;#039; .. (string._formatNum(args.cost) or 0)&lt;br /&gt;
	&lt;br /&gt;
	args.title = args.title or&lt;br /&gt;
		handleSkyBlockItemSpecialCases(determineTitle(args.Output)) or&lt;br /&gt;
		handleSkyBlockItemSpecialCases(determineTitle(args.Input1)) or &amp;#039;&amp;#039;&lt;br /&gt;
	&lt;br /&gt;
	return p.anvil(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Melody (this is unrelated to Template:Note Sequence)&lt;br /&gt;
function p.noteSequence(f)&lt;br /&gt;
	local args = getArgs(f)&lt;br /&gt;
	local sequence = args[1]&lt;br /&gt;
	return p._noteSequence(sequence)&lt;br /&gt;
end&lt;br /&gt;
function p._noteSequence(sequence)&lt;br /&gt;
	local function simpleSlot(frames)&lt;br /&gt;
		frames = inventorySlot.parseFrameText(frames, nil, false, {aliases = &amp;#039;&amp;#039;, default = nil})&lt;br /&gt;
		local function simpleMakeItem(name)&lt;br /&gt;
			return mw.html.create(&amp;#039;span&amp;#039;):addClass(&amp;#039;invslot-item invslot-item-image&amp;#039;):wikitext(&amp;#039;[[File:&amp;#039;,name,&amp;#039;.png|32px|link=]]&amp;#039;):done()&lt;br /&gt;
		end&lt;br /&gt;
		local body = mw.html.create(&amp;#039;span&amp;#039;):addClass(&amp;#039;invslot animated&amp;#039;)&lt;br /&gt;
		local activeFrame = 1&lt;br /&gt;
		for i, frame in ipairs(frames) do&lt;br /&gt;
			local item&lt;br /&gt;
			if frame[1] then&lt;br /&gt;
				item = body:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;animated-subframe&amp;#039;)&lt;br /&gt;
				local subActiveFrame = 1 --FC-frame.randomise and random(#frame) or 1&lt;br /&gt;
				for sI, sFrame in ipairs(frame) do&lt;br /&gt;
					local sItem = simpleMakeItem(sFrame.name)&lt;br /&gt;
					item:node(sItem)&lt;br /&gt;
					&lt;br /&gt;
					if sI == subActiveFrame then&lt;br /&gt;
						sItem:addClass(&amp;#039;animated-active&amp;#039;)&lt;br /&gt;
					else&lt;br /&gt;
						sItem:addClass(&amp;#039;hidden&amp;#039;)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				item = simpleMakeItem(frame.name)&lt;br /&gt;
				body:node(item)&lt;br /&gt;
			end&lt;br /&gt;
			if i == activeFrame and animated then&lt;br /&gt;
				item:addClass(&amp;#039;animated-active&amp;#039;)&lt;br /&gt;
			elseif animated then&lt;br /&gt;
				item:addClass(&amp;#039;hidden&amp;#039;)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return mw.getCurrentFrame():preprocess(tostring(body))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local colors = {&lt;br /&gt;
		&amp;#039;Red&amp;#039;,&lt;br /&gt;
		&amp;#039;Yellow&amp;#039;,&lt;br /&gt;
		&amp;#039;Lime&amp;#039;,&lt;br /&gt;
		&amp;#039;Green&amp;#039;,&lt;br /&gt;
		&amp;#039;Purple&amp;#039;,&lt;br /&gt;
		&amp;#039;Blue&amp;#039;,&lt;br /&gt;
		&amp;#039;Light_Blue&amp;#039;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	local slots = {}&lt;br /&gt;
	for x = 1, 7, 1 do&lt;br /&gt;
		slots[x] = {}&lt;br /&gt;
		for y = 1, 6, 1 do&lt;br /&gt;
			if y == 5&lt;br /&gt;
				then slots[x][y] = sequence:gsub(&amp;#039;[&amp;#039; .. x .. &amp;#039;]&amp;#039;, &amp;#039;Block_of_Quartz;&amp;#039;)&lt;br /&gt;
				else slots[x][y] = sequence:gsub(&amp;#039;[&amp;#039; .. x .. &amp;#039;]&amp;#039;, colors[x] .. &amp;#039;_Wool;&amp;#039;)&lt;br /&gt;
			end&lt;br /&gt;
			if y == 5&lt;br /&gt;
				then slots[x][y] = slots[x][y]:gsub(&amp;#039;[%d%s]&amp;#039;, colors[x] .. &amp;#039;_Stained_Clay;&amp;#039;)&lt;br /&gt;
				else slots[x][y] = slots[x][y]:gsub(&amp;#039;[%d%s]&amp;#039;, colors[x] .. &amp;#039;_Stained_Glass_Pane;&amp;#039;)&lt;br /&gt;
			end&lt;br /&gt;
			if y == 5&lt;br /&gt;
				then&lt;br /&gt;
					for z = 1, y, 1 do&lt;br /&gt;
						slots[x][y] = colors[x] .. &amp;#039;_Stained_Clay;&amp;#039; .. slots[x][y]&lt;br /&gt;
					end&lt;br /&gt;
					for z = 1, 12-y, 1 do&lt;br /&gt;
						slots[x][y] = slots[x][y] .. colors[x] .. &amp;#039;_Stained_Clay;&amp;#039;&lt;br /&gt;
					end&lt;br /&gt;
				else&lt;br /&gt;
					for z = 1, y, 1 do&lt;br /&gt;
						slots[x][y] = colors[x] .. &amp;#039;_Stained_Glass_Pane;&amp;#039; .. slots[x][y]&lt;br /&gt;
					end&lt;br /&gt;
					for z = 1, 12-y, 1 do&lt;br /&gt;
						slots[x][y] = slots[x][y] .. colors[x] .. &amp;#039;_Stained_Glass_Pane;&amp;#039;&lt;br /&gt;
					end&lt;br /&gt;
			end&lt;br /&gt;
			slots[x][y] = slots[x][y]:gsub(&amp;#039;[_]&amp;#039;, &amp;#039; &amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local table = mw.html.create(&amp;#039;table&amp;#039;):addClass(&amp;#039;mcui mcui-Crafting_Table&amp;#039;):css({margin = &amp;#039;0 auto&amp;#039;, display = &amp;#039;table&amp;#039;, cursor = &amp;#039;not-allowed&amp;#039;})&lt;br /&gt;
	&lt;br /&gt;
	for y = 1, 6, 1 do&lt;br /&gt;
		local row = table:tag(&amp;#039;tr&amp;#039;):addClass(&amp;#039;mcui-row&amp;#039;)&lt;br /&gt;
		row:tag(&amp;#039;td&amp;#039;):wikitext(simpleSlot(&amp;#039;Gray Stained Glass Pane&amp;#039;)):done()&lt;br /&gt;
		for x = 1, 7, 1 do&lt;br /&gt;
			row:tag(&amp;#039;td&amp;#039;):wikitext(simpleSlot(slots[x][y])):done()&lt;br /&gt;
		end&lt;br /&gt;
		row:tag(&amp;#039;td&amp;#039;):wikitext(simpleSlot(&amp;#039;Gray Stained Glass Pane&amp;#039;)):done()&lt;br /&gt;
		row:done()&lt;br /&gt;
	end&lt;br /&gt;
	table:done()&lt;br /&gt;
	return tostring(table)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
-- Template: UIPage&lt;br /&gt;
-- &lt;br /&gt;
-- Imports (transclude) another UI page with custom options on its first UI.&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
function p.uipage(frame)&lt;br /&gt;
	local args = getArgs(frame)&lt;br /&gt;
	local page = args.page or args[1]&lt;br /&gt;
	&lt;br /&gt;
	return frame:preprocess(p._uipage(page, args))&lt;br /&gt;
end&lt;br /&gt;
function p._uipage(page, args)&lt;br /&gt;
	local function injectParamsBoolean(callStr, args)&lt;br /&gt;
		for param, value in pairs(args) do&lt;br /&gt;
			if value then&lt;br /&gt;
				value = tostring(yesno(value))&lt;br /&gt;
				callStr, n = callStr:gsub(&amp;#039;|%s*&amp;#039; .. param .. &amp;#039;%s*=.-%f[|}]&amp;#039;,&amp;#039;|&amp;#039; .. param .. &amp;#039;=&amp;#039; .. value .. &amp;#039;\n&amp;#039;)&lt;br /&gt;
				if n == 0 then callStr = callStr:sub(0,callStr:len()-2) .. &amp;#039;|&amp;#039; .. param .. &amp;#039;=&amp;#039; .. value .. &amp;#039;}}&amp;#039; end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return callStr&lt;br /&gt;
	end&lt;br /&gt;
	local function injectParamsString(callStr, args)&lt;br /&gt;
		for param, value in pairs(args) do&lt;br /&gt;
			if value then&lt;br /&gt;
				callStr, n = callStr:gsub(&amp;#039;|%s*&amp;#039; .. param .. &amp;#039;%s*=.-%f[|}]&amp;#039;,&amp;#039;|&amp;#039; .. param .. &amp;#039;=&amp;#039; .. value .. &amp;#039;\n&amp;#039;)&lt;br /&gt;
				if n == 0 then callStr = callStr:sub(0,callStr:len()-2) .. &amp;#039;|&amp;#039; .. param .. &amp;#039;=&amp;#039; .. value .. &amp;#039;}}&amp;#039; end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return callStr&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local return_id = args.return_id&lt;br /&gt;
	local extPageTitle = mw.title.new(page, 0)&lt;br /&gt;
	&lt;br /&gt;
	if not extPageTitle.exists then error(&amp;#039;Specified page does not exist, page: &amp;#039; .. page) end&lt;br /&gt;
	local extPageContent = extPageTitle:getContent()&lt;br /&gt;
	&lt;br /&gt;
	local ls = string.matchAll(extPageContent,&amp;#039;%b{}&amp;#039;)&lt;br /&gt;
	local finalStr = &amp;#039;&amp;#039;&lt;br /&gt;
	local firstUI = true&lt;br /&gt;
	&lt;br /&gt;
	if ls.n &amp;lt; 1 then return &amp;#039;&amp;#039; end&lt;br /&gt;
	&lt;br /&gt;
	for i = 1, ls.n, 1 do&lt;br /&gt;
		local callStr = ls[i][1]&lt;br /&gt;
		local x, y = callStr:find(&amp;#039;{{UI|&amp;#039;)&lt;br /&gt;
		local x1, y1, subpage, subparams = callStr:find(&amp;#039;{{UIPage|(.-)%f[|}](.-)}}&amp;#039;)&lt;br /&gt;
		if x == 1 then&lt;br /&gt;
			if firstUI then -- first UI on page, apply all the custom settings to this UI&lt;br /&gt;
				callStr = injectParamsBoolean(callStr, {&lt;br /&gt;
					hide = yesno(args.hide,true),&lt;br /&gt;
					fill = args.fill, &lt;br /&gt;
					rows = args.rows,&lt;br /&gt;
					cols = args.cols,&lt;br /&gt;
					noarrow = args.noarrow,&lt;br /&gt;
					noclose = args.noclose,&lt;br /&gt;
				})&lt;br /&gt;
				callStr = injectParamsString(callStr, {&lt;br /&gt;
					id = args.id,&lt;br /&gt;
					goback = (args.return_text or args.goback),&lt;br /&gt;
					goback_link = args.goback_link,&lt;br /&gt;
					return_id = args.return_id,&lt;br /&gt;
					arrow = (args.arrow or args.arrow_),&lt;br /&gt;
					close_ = (args.close or args.close_),&lt;br /&gt;
				})&lt;br /&gt;
				firstUI = false&lt;br /&gt;
			end&lt;br /&gt;
			finalStr = finalStr .. callStr&lt;br /&gt;
		elseif x1 == 1 then&lt;br /&gt;
			subparams = subparams and subparams:gsub(&amp;#039;^[|%s]*(.-)[|%s]*$&amp;#039;,&amp;#039;%1&amp;#039;) or &amp;#039;&amp;#039;&lt;br /&gt;
			local subargs = {}&lt;br /&gt;
			for _, param in ipairs(string.split(subparams,&amp;#039;|&amp;#039;)) do&lt;br /&gt;
				if param:match(&amp;#039;=&amp;#039;) then&lt;br /&gt;
					param = string.split(param, &amp;#039;=&amp;#039;)&lt;br /&gt;
					subargs[param[1]] = param[2]&lt;br /&gt;
				else&lt;br /&gt;
					-- no positional arguments for UIPage at the moment&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			finalStr = finalStr .. p._uipage(subpage, subargs)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return finalStr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
-- Template: UI&lt;br /&gt;
-- &lt;br /&gt;
-- Creates a UI.&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
function p.ui(frame)&lt;br /&gt;
	local args = getArgs(frame, { removeBlanks = false })&lt;br /&gt;
	&lt;br /&gt;
	local ui = Interface(args)&lt;br /&gt;
	&lt;br /&gt;
	local x, y, rowCount = 1, 1, 1&lt;br /&gt;
	local maxRows, maxCols = tonumber(args.rows) or 6, tonumber(args.cols) or 9&lt;br /&gt;
	local fill = yesno(args.fill, true)&lt;br /&gt;
	local defaultnolink = yesno((args[&amp;#039;defaultnolink&amp;#039;] or args[&amp;#039;dnl&amp;#039;]), false)&lt;br /&gt;
	&lt;br /&gt;
	local function decodeCommas(...)&lt;br /&gt;
		local t = { ... }&lt;br /&gt;
		for i, v in ipairs(t) do&lt;br /&gt;
			t[i] = t[i]:gsub(&amp;#039;\255&amp;#039;, &amp;#039;,&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		return unpack(t)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function setSlot(v, x, y)&lt;br /&gt;
		local isCustom = v:match(&amp;#039;&amp;lt;%a-(.-)&amp;gt;(.-)&amp;lt;/%a-&amp;gt;&amp;#039;)&lt;br /&gt;
		&lt;br /&gt;
		v = v:gsub(&amp;#039;\\,&amp;#039;, &amp;#039;\255&amp;#039;)&lt;br /&gt;
		local val, id, title, text = decodeCommas(string.unpackedSplit(v, &amp;#039;%s*,%s*&amp;#039;))&lt;br /&gt;
		&lt;br /&gt;
		local _val = val&lt;br /&gt;
		local val, num = val:match(&amp;#039;^%s*(.+)%s*[;]%s*(%d+)%s*$&amp;#039;)&lt;br /&gt;
		val = val or _val&lt;br /&gt;
		&lt;br /&gt;
		local link_specify&lt;br /&gt;
		if not id or id == &amp;#039;&amp;#039; then id = nil&lt;br /&gt;
		else&lt;br /&gt;
			local _id = id&lt;br /&gt;
			id, link_specify = id:match(&amp;#039;^%s*(.+)%s*[;]%s*(.+)%s*$&amp;#039;)&lt;br /&gt;
			id = id or _id&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- [IMPORTANT] Transform newlines into `/`&lt;br /&gt;
		if text and text:match(&amp;#039;\n&amp;#039;) then&lt;br /&gt;
			text = text:gsub(&amp;#039;\n&amp;#039;, &amp;#039;/&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		ui:setSlot(x, y, isCustom and v or {&lt;br /&gt;
			val .. (num and &amp;#039;, &amp;#039; .. num or &amp;#039;&amp;#039;),&lt;br /&gt;
			class = (id and id ~= &amp;#039;none&amp;#039;) and &amp;#039;goto-&amp;#039; .. id:gsub(&amp;#039;^goto%-&amp;#039;, &amp;#039;&amp;#039;),&lt;br /&gt;
			link = (id and id ~= &amp;#039;none&amp;#039;) and &amp;#039;none&amp;#039; or (link_specify or (defaultnolink and &amp;#039;none&amp;#039; or&amp;#039;&amp;#039;)),&lt;br /&gt;
			title = title,&lt;br /&gt;
			text = text,&lt;br /&gt;
		}, isCustom)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for i, v in ipairs(args) do&lt;br /&gt;
		if i &amp;gt; 1 then&lt;br /&gt;
			if x &amp;gt; 6 then break; end&lt;br /&gt;
			&lt;br /&gt;
			if v:match(&amp;#039;^%-$&amp;#039;) then&lt;br /&gt;
				for y2 = y, maxCols do&lt;br /&gt;
					if fill then&lt;br /&gt;
						ui:setBlankSlot(x, y2)&lt;br /&gt;
					else&lt;br /&gt;
						ui:setSlot(x, y2, &amp;#039;&amp;#039;)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				x = x+1&lt;br /&gt;
				y = 1&lt;br /&gt;
			elseif y &amp;gt; maxCols then&lt;br /&gt;
				y = 1&lt;br /&gt;
				x = x+1&lt;br /&gt;
			else&lt;br /&gt;
				setSlot(v, x, y)&lt;br /&gt;
				y = y+1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		local k = tostring(k)&lt;br /&gt;
		&lt;br /&gt;
		if k:match(&amp;#039;^%d+%s*,%s*%d+$&amp;#039;) then&lt;br /&gt;
			local x, y = k:match(&amp;#039;^(%d+)%s*,%s*(%d+)$&amp;#039;)&lt;br /&gt;
			&lt;br /&gt;
			setSlot(v, tonumber(x), tonumber(y))&lt;br /&gt;
		elseif k:match(&amp;#039;^row%s*([1-6])%s*$&amp;#039;) then&lt;br /&gt;
			local x = k:match(&amp;#039;^row%s*([1-6])$&amp;#039;)&lt;br /&gt;
			local endParams = v:match(&amp;#039;%s*;%s*([%d%s,]-)%s*$&amp;#039;)&lt;br /&gt;
			v = v:gsub(&amp;#039;%s*;%s*([%d%s,]-)%s*$&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
			&lt;br /&gt;
			endParams = endParams and string.split(endParams, &amp;#039;%s*,%s*&amp;#039;) or {1, maxCols}&lt;br /&gt;
			&lt;br /&gt;
			if #endParams &amp;gt; 2 then&lt;br /&gt;
				for dummy, y in pairs(endParams) do&lt;br /&gt;
					setSlot(v:gsub(&amp;#039;%$n&amp;#039;, y):gsub(&amp;#039;\\%$n&amp;#039;, &amp;#039;$n&amp;#039;), tonumber(x), tonumber(y))	&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				for y = tonumber(endParams[1] or 1), tonumber(endParams[2] or maxCols), 1 do&lt;br /&gt;
					setSlot(v:gsub(&amp;#039;%$n&amp;#039;, y):gsub(&amp;#039;\\%$n&amp;#039;, &amp;#039;$n&amp;#039;), tonumber(x), tonumber(y))	&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
		elseif k:match(&amp;#039;^colu?m?n?%s*([1-9])%s*$&amp;#039;) then&lt;br /&gt;
			local y = k:match(&amp;#039;^colu?m?n?%s*([1-9])%s*$&amp;#039;)&lt;br /&gt;
			local endParams = v:match(&amp;#039;%s*;%s*([%d%s,]-)%s*$&amp;#039;)&lt;br /&gt;
			v = v:gsub(&amp;#039;%s*;%s*([%d%s,]-)%s*$&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
			&lt;br /&gt;
			endParams = endParams and string.split(endParams, &amp;#039;%s*,%s*&amp;#039;) or {1, maxRows}&lt;br /&gt;
			&lt;br /&gt;
			if #endParams &amp;gt; 2 then&lt;br /&gt;
				for dummy, x in pairs(endParams) do&lt;br /&gt;
					setSlot(v:gsub(&amp;#039;%$n&amp;#039;, x):gsub(&amp;#039;\\%$n&amp;#039;, &amp;#039;$n&amp;#039;), tonumber(x), tonumber(y))&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				for x = tonumber(endParams[1] or 1), tonumber(endParams[2] or maxRows), 1 do&lt;br /&gt;
					setSlot(v:gsub(&amp;#039;%$n&amp;#039;, x):gsub(&amp;#039;\\%$n&amp;#039;, &amp;#039;$n&amp;#039;), tonumber(x), tonumber(y))&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return tostring(ui)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
-- Template: UI Pager&lt;br /&gt;
-- &lt;br /&gt;
-- An automatic pager for UIs.&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
function p.uiPager(frame)&lt;br /&gt;
	local args = getArgs(frame, { removeBlanks = false })&lt;br /&gt;
	local id = args.id or getrandomid()&lt;br /&gt;
	&lt;br /&gt;
	if yesno(args.title_index, false) and not yesno(args.index_last, false) then&lt;br /&gt;
		args[1] = &amp;#039;({0}/{1}) &amp;#039; .. args[1]&lt;br /&gt;
	else&lt;br /&gt;
	if yesno(args.title_index, false) and yesno(args.index_last, false) then&lt;br /&gt;
		args[1] = args[1] .. &amp;#039; ({0}/{1})&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local ui = table.merge({&lt;br /&gt;
		[1] = args[1],&lt;br /&gt;
		fill = &amp;#039;border&amp;#039;,&lt;br /&gt;
	}, table.mapNamed(args, function (k, v)&lt;br /&gt;
		if type(k) ~= &amp;#039;number&amp;#039; then return v else return nil end&lt;br /&gt;
	end))&lt;br /&gt;
	&lt;br /&gt;
	-- allocate items onto UI pages&lt;br /&gt;
	local pages = {}&lt;br /&gt;
	local rows, cols = args.rows or 6, args.cols or 9&lt;br /&gt;
	local i = 2&lt;br /&gt;
	while args[i] do&lt;br /&gt;
		local ui2 = table.deepCopy(ui)&lt;br /&gt;
		for r = 2, rows - 1 do&lt;br /&gt;
			for c = 2, cols - 1 do&lt;br /&gt;
				if args[i] then&lt;br /&gt;
					ui2[rc(r, c)] = args[i]&lt;br /&gt;
					i = i + 1&lt;br /&gt;
				else&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		table.push(pages, ui2)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return wrapdiv(table.concat(table.map(pages, function (v, i, t)&lt;br /&gt;
		if t[i - 1] and not (v[rc(rows, 1)] or v[rc(rows, 1, true)]) then&lt;br /&gt;
			v[rc(rows, 1)] = (&amp;#039;Arrow, %s, &amp;amp;aPrevious Page, &amp;amp;ePage %s&amp;#039;):format(pagerid(id, i - 1), i - 1)&lt;br /&gt;
		end&lt;br /&gt;
		if t[i + 1] and not (v[rc(rows, cols)] or v[rc(rows, cols, true)]) then&lt;br /&gt;
			v[rc(rows, cols)] = (&amp;#039;Arrow, %s, &amp;amp;aNext Page, &amp;amp;ePage %s&amp;#039;):format(pagerid(id, i + 1), i + 1)&lt;br /&gt;
		end&lt;br /&gt;
		v.id = pagerid(id, i)&lt;br /&gt;
		if i &amp;gt; 1 then&lt;br /&gt;
			v.hide = true&lt;br /&gt;
		end&lt;br /&gt;
		v[1] = v[1]:gsub(&amp;#039;{0}&amp;#039;, i):gsub(&amp;#039;{1}&amp;#039;, #t)&lt;br /&gt;
		return tostring(p.ui(v))&lt;br /&gt;
	end)), #pages &amp;gt; 1 and args.clickable)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
-- Template: ShopUI&lt;br /&gt;
-- &lt;br /&gt;
-- Creates a Shop UI using UIpager.&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
function p.shopUI(frame)&lt;br /&gt;
	local args = getArgs(frame, { removeBlanks = false })&lt;br /&gt;
	local confslot = slotNotation(args.confirmation)&lt;br /&gt;
	local opts = {}&lt;br /&gt;
	if yesno(args.confirmation) or confslot then&lt;br /&gt;
		opts[confslot or &amp;#039;6, 4&amp;#039;] = &amp;#039;Lime Dye, none; none, &amp;amp;aShop Confirmations, &amp;amp;7Confirm when purchasing items/&amp;amp;7worth at least a million coins.//&amp;amp;eClick to disable!&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if not (yesno(args.close) or slotNotation(args.close)) then&lt;br /&gt;
		opts[&amp;#039;6, 5&amp;#039;] = &amp;#039;Hopper, none; none, &amp;amp;aSell Item, &amp;amp;7Click items in your inventory to/&amp;amp;7sell them to this Shop!&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	return p.uiPager(table.merge(opts, table.deepCopy(args, true)))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
-- Template: Rewards UI&lt;br /&gt;
-- &lt;br /&gt;
-- Creates a Rewards UI.&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
function p.rewardsUI(frame)&lt;br /&gt;
	local function getTot(first, second, step)&lt;br /&gt;
		return first * (math.floor(step / 2) + (step % 2)) + second * math.floor(step / 2)&lt;br /&gt;
	end&lt;br /&gt;
	local function getMinMax(i_min, first, second, all_n, step, cols)&lt;br /&gt;
		local tot_n = getTot(first, second, cols)&lt;br /&gt;
		local incr = getTot(first, second, step)&lt;br /&gt;
		return i_min, i_min + tot_n - 1, i_min + incr, (step % 2 == 0 and first or second)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local args = getArgs(frame, { removeBlanks = false })&lt;br /&gt;
	local id = args.id or getrandomid()&lt;br /&gt;
	if yesno(args.title_index, false) then&lt;br /&gt;
		args[1] = &amp;#039;({0}/{1}) &amp;#039; .. args[1]&lt;br /&gt;
	end&lt;br /&gt;
	local ui = table.merge({&lt;br /&gt;
		[1] = args[1],&lt;br /&gt;
	}, table.mapNamed(args, function (k, v)&lt;br /&gt;
		if type(k) ~= &amp;#039;number&amp;#039; then return v else return nil end&lt;br /&gt;
	end))&lt;br /&gt;
	 -- force row, col&lt;br /&gt;
	local rows, cols = 6, 9&lt;br /&gt;
	ui.rows, ui.cols = 6, 9&lt;br /&gt;
	-- fixed maps for snake height of 4, snake gap of 1&lt;br /&gt;
	local rowmap = { 4, 3, 2, 1, 1, 1, 2, 3, 4 }; rowmap[0] = 4&lt;br /&gt;
	local advancemap = { 0, 0, 0, 1, 1, 0, 0, 0, 1 }; advancemap[0] = 1&lt;br /&gt;
	-- slot allocation&lt;br /&gt;
	local step = args.step or 8&lt;br /&gt;
	local pages = {}&lt;br /&gt;
	local all_n, next_colsize, next_min, cont = table.xlength(args, false, true) - 1, 4, 2, true&lt;br /&gt;
	local min, max&lt;br /&gt;
	while cont do&lt;br /&gt;
		min, max, next_min, next_colsize = getMinMax(next_min, next_colsize, 4 + 1 - next_colsize, all_n + 1, step, cols)&lt;br /&gt;
		local ui2, index, c = table.deepCopy(ui), 0, 1&lt;br /&gt;
		for i = min, max do&lt;br /&gt;
			if args[i] then&lt;br /&gt;
				index = index + 1&lt;br /&gt;
				ui2[rc(rowmap[index % 10], c)] = args[i]&lt;br /&gt;
				c = c + advancemap[index % 10]&lt;br /&gt;
			else&lt;br /&gt;
				cont = false&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		table.push(pages, ui2)&lt;br /&gt;
	end&lt;br /&gt;
	local page_n = #pages&lt;br /&gt;
	return wrapdiv(table.concat(table.map(pages, function (v, i, t)&lt;br /&gt;
		if page_n &amp;gt; 1 and t[i - 1] and not (v[rc(rows, 1)] or v[rc(rows, 1, true)]) then&lt;br /&gt;
			v[rc(rows, 1)] = (&amp;#039;Arrow, %s, &amp;amp;aScroll Left, &amp;amp;eLeft-click to scroll!/&amp;amp;eRight-click to scroll fast!&amp;#039;):format(pagerid(id, i - 1))&lt;br /&gt;
		end&lt;br /&gt;
		if page_n &amp;gt; 1 and t[i + 1] and not (v[rc(rows, cols)] or v[rc(rows, cols, true)]) then&lt;br /&gt;
			v[rc(rows, cols)] = (&amp;#039;Arrow, %s, &amp;amp;aScroll Right, &amp;amp;eLeft-click to scroll!/&amp;amp;eRight-click to scroll fast!&amp;#039;):format(pagerid(id, i + 1))&lt;br /&gt;
		end&lt;br /&gt;
		v.id = pagerid(id, i)&lt;br /&gt;
		if i &amp;gt; 1 then&lt;br /&gt;
			v.hide = true&lt;br /&gt;
		end&lt;br /&gt;
		v[1] = v[1]:gsub(&amp;#039;{0}&amp;#039;, i):gsub(&amp;#039;{1}&amp;#039;, #t)&lt;br /&gt;
		return tostring(p.ui(v))&lt;br /&gt;
	end)), #pages &amp;gt; 1 and args.clickable)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
-- Template: Skill UI&lt;br /&gt;
-- &lt;br /&gt;
-- Creates a Skill UI.&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
local skillUISlotMap = {&lt;br /&gt;
	&amp;#039;2, 1&amp;#039;, &amp;#039;3, 1&amp;#039;, &amp;#039;4, 1&amp;#039;, &amp;#039;4, 2&amp;#039;, &amp;#039;4, 3&amp;#039;,&lt;br /&gt;
	&amp;#039;3, 3&amp;#039;, &amp;#039;2, 3&amp;#039;, &amp;#039;1, 3&amp;#039;, &amp;#039;1, 4&amp;#039;, &amp;#039;1, 5&amp;#039;,&lt;br /&gt;
	&amp;#039;2, 5&amp;#039;, &amp;#039;3, 5&amp;#039;, &amp;#039;4, 5&amp;#039;, &amp;#039;4, 6&amp;#039;, &amp;#039;4, 7&amp;#039;,&lt;br /&gt;
	&amp;#039;3, 7&amp;#039;, &amp;#039;2, 7&amp;#039;, &amp;#039;1, 7&amp;#039;, &amp;#039;1, 8&amp;#039;, &amp;#039;1, 9&amp;#039;,&lt;br /&gt;
	&amp;#039;2, 9&amp;#039;, &amp;#039;3, 9&amp;#039;, &amp;#039;4, 9&amp;#039;, &amp;#039;5, 9&amp;#039;, &amp;#039;6, 9&amp;#039;&lt;br /&gt;
}&lt;br /&gt;
function p.skillUI(frame)&lt;br /&gt;
	local args = getArgs(frame, { removeBlanks = false })&lt;br /&gt;
	local id = args.id or getrandomid()&lt;br /&gt;
	if yesno(args.title_index, false) then&lt;br /&gt;
		args[1] = &amp;#039;({0}/{1}) &amp;#039; .. args[1]&lt;br /&gt;
	end&lt;br /&gt;
	local pageSize = #skillUISlotMap&lt;br /&gt;
	local ui = table.merge({&lt;br /&gt;
		[1] = args[1],&lt;br /&gt;
	}, table.mapNamed(args, function (k, v)&lt;br /&gt;
		if type(k) ~= &amp;#039;number&amp;#039; then return v else return nil end&lt;br /&gt;
	end))&lt;br /&gt;
	-- slot allocation&lt;br /&gt;
	local pages = {}&lt;br /&gt;
	local item_n, index, ui2 = table.xlength(args, false, true) - 1, 0, table.deepCopy(ui)&lt;br /&gt;
	while args[index + 2] do&lt;br /&gt;
		ui2[skillUISlotMap[index % pageSize + 1]] = args[index + 2]&lt;br /&gt;
		if index % pageSize == (pageSize - 1) then&lt;br /&gt;
			table.push(pages, ui2)&lt;br /&gt;
			ui2 = table.deepCopy(ui)&lt;br /&gt;
		end&lt;br /&gt;
		index = index + 1&lt;br /&gt;
	end&lt;br /&gt;
	if #pages &amp;lt; 1 or index % pageSize &amp;gt; 0 --[[ ensure there are new things in the ui2 ]] then&lt;br /&gt;
		table.push(pages, ui2)&lt;br /&gt;
	end&lt;br /&gt;
	local page_n = #pages&lt;br /&gt;
	return wrapdiv(table.concat(table.map(pages, function (v, i, t)&lt;br /&gt;
		if page_n &amp;gt; 1 then&lt;br /&gt;
			local targetPage = i + 1 &amp;gt; page_n and 1 or i + 1 -- cyclic&lt;br /&gt;
			v[&amp;#039;6, 6&amp;#039;] = (&amp;#039;Arrow, %s, &amp;amp;aLevels %s - %s, &amp;amp;eClick to view!&amp;#039;):format(pagerid(id, targetPage), (targetPage - 1) * pageSize + 1, math.min(targetPage * pageSize, item_n))&lt;br /&gt;
		end&lt;br /&gt;
		v.id = pagerid(id, i)&lt;br /&gt;
		if i &amp;gt; 1 then&lt;br /&gt;
			v.hide = true&lt;br /&gt;
		end&lt;br /&gt;
		v[1] = v[1]:gsub(&amp;#039;{0}&amp;#039;, i):gsub(&amp;#039;{1}&amp;#039;, #t)&lt;br /&gt;
		return tostring(p.ui(v))&lt;br /&gt;
	end)), #pages &amp;gt; 1 and args.clickable)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
-- Template: Book&lt;br /&gt;
-- &lt;br /&gt;
-- Creates a book UI.&lt;br /&gt;
---------------------------------------------------------------------------------&lt;br /&gt;
function p.bookUI(frame)&lt;br /&gt;
	local args = getArgs(frame)&lt;br /&gt;
	&lt;br /&gt;
	-- We need to know how many pages there are before we can start main loop for next/prev buttons&lt;br /&gt;
	local pages, i = {}, 1&lt;br /&gt;
    while args[i] do&lt;br /&gt;
        pages[#pages+1] = args[i]&lt;br /&gt;
        i = i + 1&lt;br /&gt;
    end&lt;br /&gt;
	&lt;br /&gt;
	local t = {}&lt;br /&gt;
	for i, pageContent in ipairs(pages) do&lt;br /&gt;
		local pageTag = mw.html.create(&amp;#039;div&amp;#039;):attr(&amp;#039;id&amp;#039;, &amp;#039;ui-page&amp;#039;..i)&lt;br /&gt;
			:addClass(&amp;#039;hsw-book-page sbw-ui-tab-content&amp;#039;)&lt;br /&gt;
			:addClass(i==1 and &amp;#039;&amp;#039; or &amp;#039;hidden&amp;#039;)&lt;br /&gt;
		&lt;br /&gt;
		pageTag:tag(&amp;#039;div&amp;#039;):addClass(&amp;quot;hsw-book-page-count&amp;quot;)&lt;br /&gt;
			:wikitext(mctxt.raw{ table.concat{ &amp;quot;Page &amp;quot;,  i,&amp;quot; of &amp;quot;, #pages } }):done()&lt;br /&gt;
		&lt;br /&gt;
		pageTag:wikitext(mctxt.raw{ pageContent })&lt;br /&gt;
		-- Next/Prev buttons&lt;br /&gt;
		if #pages &amp;gt; 1 then&lt;br /&gt;
			local nav = pageTag:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;hsw-book-page-nav&amp;#039;)&lt;br /&gt;
			--prev&lt;br /&gt;
			if i &amp;gt; 1 then&lt;br /&gt;
				nav:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;invslot goto-page&amp;#039;..(i-1)):wikitext(&amp;quot;[[File:Book Arrowleft.png|link=#]]&amp;quot;):done()&lt;br /&gt;
			else&lt;br /&gt;
				nav:tag(&amp;#039;div&amp;#039;):done() -- empty need for formatting&lt;br /&gt;
			end&lt;br /&gt;
			-- next&lt;br /&gt;
			if i &amp;lt; #pages then&lt;br /&gt;
				nav:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;invslot goto-page&amp;#039;..(i+1)):tag(&amp;#039;div&amp;#039;):css{ transform= &amp;quot;scaleX(-1)&amp;quot; }:wikitext(&amp;quot;[[File:Book Arrowleft.png|link=#]]&amp;quot;)&lt;br /&gt;
			else&lt;br /&gt;
				nav:tag(&amp;#039;div&amp;#039;):done() -- empty need for formatting&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		t[#t+1] = tostring(pageTag)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return wrapdiv(table.concat(t), #pages &amp;gt; 1)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.createBlankUI = Interface&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>515797455988850689</name></author>
	</entry>
</feed>