Module:Sandbox: Difference between revisions
		
		
		
		Jump to navigation
		Jump to search
		
| No edit summary | No edit summary | ||
| Line 1: | Line 1: | ||
| local p = {} | local p = {} | ||
| local views = {} | |||
| local getArgs | local getArgs | ||
| local doConcat | |||
| function  | --------------------------------------------------------------------- | ||
| -- Argument processing | |||
| --------------------------------------------------------------------- | |||
| local function makeInvokeFunc(funcName) | |||
| 	return function (frame) | |||
| 		if not getArgs then | |||
| 			getArgs = require('Module:Arguments').getArgs | |||
| 		end | |||
| 		local args = getArgs(frame) | |||
| 		return p[funcName](args) | |||
| 	end | |||
| end | |||
| --------------------------------------------------------------------- | |||
| -- Implements {{item}} | |||
| --------------------------------------------------------------------- | |||
| p.item = makeInvokeFunc('_item') | |||
| function p._item(args) | |||
| 	local cleanArgs = {} | |||
| 	cleanArgs.view = args.view or args.View or 'full' | |||
| 	cleanArgs.format = args.format or args.Format | |||
| 	cleanArgs.name = args.name or args.Name | |||
| 	cleanArgs.sortKey = args.sortKey or args.SortKey or cleanArgs.name | |||
| 	cleanArgs.pageName = args.pageName or args.PageName or cleanArgs.name | |||
| 	cleanArgs.image = args.image or args.Image or cleanArgs.pageName .. '.png' | |||
| 	cleanArgs.size = args.size or args.Size or '2x_' | |||
| 	cleanArgs.rarity = args.rarity or args.Rarity or 'Normal' | |||
| 	cleanArgs.type = args.type or args.Type | |||
| 	cleanArgs.subtype = args.subtype or args.Subtype | |||
| 	cleanArgs.baseItem = args.baseItem or args.BaseItem | |||
| 	cleanArgs.baseItemPage = args.baseItemPage or args.BaseItemPage or cleanArgs.baseItem | |||
| 	cleanArgs.level = args.level or args.RequiredLevel | |||
| 	cleanArgs.strength = args.strength or args.RequiredStrength | |||
| 	cleanArgs.dexterity = args.dexterity or args.RequiredDexterity | |||
| 	cleanArgs.intelligence = args.intelligence or args.RequiredIntelligence | |||
| 	cleanArgs.physical = args.physicalDamage or args.PhysicalDamage | |||
| 	cleanArgs.fire = args.fire or args.FireDamage | |||
| 	cleanArgs.cold = args.cold or args.ColdDamage | |||
| 	cleanArgs.lightning = args.lightning or args.LightningDamage | |||
| 	cleanArgs.chaos = args.chaos or args.ChaosDamage | |||
| 	cleanArgs.averageDamage = args.averageDamage or args.AverageDamage | |||
| 	cleanArgs.critChance = args.critChance or args.CriticalStrikeChance | |||
| 	cleanArgs.attacksPerSecond = args.attacksPerSecond or args.AttacksPerSecond | |||
| 	cleanArgs.blockChance = args.blockChance or args.Block | |||
| 	cleanArgs.armour = args.armour or args.Armour | |||
| 	cleanArgs.evasion = args.evasion or args.Evasion | |||
| 	cleanArgs.energyShield = args.energyShield or args.EnergyShield | |||
| 	cleanArgs.mapLevel = args.mapLevel or args.MapLevel | |||
| 	cleanArgs.itemQuantity = args.itemQuantity or args.itemQuantity | |||
| 	cleanArgs.radius = args.radius or args.Radius | |||
| 	cleanArgs.stackSize = args.stackSize or args.StackSize | |||
| 	cleanArgs.effect = args.effect or args.Effect | |||
| 	cleanArgs.life = args.life or args.FlaskLife | |||
| 	cleanArgs.mana = args.mana or args.FlaskMana | |||
| 	cleanArgs.duration = args.duration or args.FlaskDuration | |||
| 	cleanArgs.chargeCap = args.chargeCap or args.FlaskCharges | |||
| 	cleanArgs.chargeUse = args.chargeUse or args.ChargesUsed | |||
| 	cleanArgs.implicitMods = args.implicitMods or args.ImplicitMods | |||
| 	cleanArgs.randomMods = args.randomMods or args.RandomMods | |||
| 	cleanArgs.cosmeticMods = args.cosmeticMods or args.CosmeticMods | |||
| 	cleanArgs.helpText = args.helpText or args.HelpText | |||
| 	cleanArgs.flavourText = args.flavourText or args.FlavourText | |||
| 	return views[cleanArgs.view](cleanArgs) | |||
| end | |||
| --------------------------------------------------------------------- | |||
| -- Views | |||
| --------------------------------------------------------------------- | |||
| function views.full(args) | |||
| 	args.stats = p.statsBuilder(args) | |||
| 	args.class = 'itembox-full' | |||
| 	local frame = { | |||
| 		['Currency'] = 'currency', | |||
| 		['Microtrans'] = 'currency', | |||
| 		['Gem'] = 'gem', | |||
| 		['Quest'] = 'quest' | |||
| 	} | |||
| 	args.frame = frame[args.type] or args.rarity | |||
| 	args.name = '[[' .. args.pageName .. '|' .. args.name .. ']]' | |||
| 	args.baseItem = args.baseItem and ('[[' .. args.baseItemPage .. '|' .. args.baseItem .. ']]') or nil | |||
| 	args.belowstats = tostring( | |||
| 		mw.html.create('div') | |||
| 			:attr('class', 'itemboximage') | |||
| 			:wikitext( '[[File:' .. args.image .. '|' .. p._itemsize(args.size) .. '|]]' ) | |||
| 	) | |||
| 	local category | |||
| 	local types = { | |||
| 		['Weapon'] = { | |||
| 			['Bow'] = 'Bows', | |||
| 			['Claw'] = 'Claws', | |||
| 			['Dagger'] = 'Daggers', | |||
| 			['Wand'] = 'Wands', | |||
| 			['Fishing Rod'] = 'Fishing rods', | |||
| 			['Staff'] = 'Staves', | |||
| 			['One Handed Axe'] = 'One-handed axes', | |||
| 			['Two Handed Axe'] = 'Two-handed axes', | |||
| 			['One Handed Mace'] = 'One-handed maces', | |||
| 			['Two Handed Mace'] = 'Two-handed maces', | |||
| 			['One Handed Sword'] = 'One-handed swords', | |||
| 			['Two Handed Sword'] = 'Two-handed swords' | |||
| 		}, | |||
| 		['Armour'] = { | |||
| 			['Body Armour'] = 'Body armours', | |||
| 			['Helmet'] = 'Helmets', | |||
| 			['Shield'] = 'Shields', | |||
| 			['Boots'] = 'Boots', | |||
| 			['Gloves'] = 'Gloves' | |||
| 		}, | |||
| 		['Accessory'] = { | |||
| 			['Amulet'] = 'Amulets', | |||
| 			['Belt'] = 'Belts', | |||
| 			['Quiver'] = 'Quivers', | |||
| 			['Ring'] = 'Rings' | |||
| 		}, | |||
| 		['Flask'] = { | |||
| 			['Life'] = 'Life flasks', | |||
| 			['Mana'] = 'Mana flasks', | |||
| 			['Hybrid'] = 'Hybrid flasks', | |||
| 			['Utility'] = 'Utility flasks' | |||
| 		}, | |||
| 		['Map'] = { | |||
| 			['Fragment'] = 'Map fragments', | |||
| 			['_default'] = 'Maps' | |||
| 		}, | |||
| 		['Jewel'] = 'Jewels', | |||
| 		['Currency'] = 'Currency items', | |||
| 		['Quest'] = 'Quest items', | |||
| 		['Microtrans'] = 'Microtransaction features' | |||
| 	} | |||
| 	category = types[args.type] | |||
| 	if type(category) == 'table' then | |||
| 		category = types[args.type][args.subtype or '_default'] | |||
| 	end | 	end | ||
| 	local args  | 	if category then | ||
| 		if args.rarity == 'Unique' then | |||
| 			category = 'Unique ' .. string.lower(category) | |||
| 		end | |||
| 	return  | 	else | ||
| 		category = 'Items with invalid types' | |||
| 	end | |||
| 	return p.itembox(args) .. '[[Category:' .. category .. ']]' | |||
| end | |||
| --------------------------------------------------------------------- | |||
| -- Itembox | |||
| --------------------------------------------------------------------- | |||
| function p.itembox(args) | |||
| 	local container = mw.html.create(args.ishover and 'span' or 'div') | |||
| 		:attr( 'class', 'itembox-' .. ( string.lower(args.frame or 'normal') ) .. (args.class or '') ) | |||
| 		:tag('span') | |||
| 			:attr( 'class', 'itemboxheader-' .. (args.baseItem and 'double' or 'single') ) | |||
| 			:tag('span') | |||
| 				:attr('class', 'itemboxheaderleft') | |||
| 				:done() | |||
| 			:tag('span') | |||
| 				:attr('class', 'itemboxheaderright') | |||
| 				:done() | |||
| 			:tag('span') | |||
| 				:attr('class', 'itemboxheadertext') | |||
| 				:wikitext( args.name .. (args.baseItem and '<br>' .. args.baseItem or '') ) | |||
| 				:done() | |||
| 			:done() | |||
| 		:wikitext(args.abovestats or '') | |||
| 		:tag('span') | |||
| 			:attr('class', 'itemboxstats') | |||
| 			:wikitext(args.stats or '') | |||
| 			:done() | |||
| 		:wikitext(args.belowstats or '') | |||
| 	return tostring(container) | |||
| end | end | ||
| function p. | --------------------------------------------------------------------- | ||
| local container = mw.html.create(' | -- Stats builder | ||
| --------------------------------------------------------------------- | |||
| function p.statsBuilder(args) | |||
| 	local container = mw.html.create('span') | |||
| 	local group | 	local group | ||
| 	local function newGroup( | 	local function newGroup(class) | ||
| 		return mw.html.create('span') | 		return mw.html.create('span') | ||
| 			:attr('class', 'itemboxstatsgroup ' ..  | 			:attr( 'class', 'itemboxstatsgroup ' .. (class or '') ) | ||
| 	end | 	end | ||
| 	local function newLine( | 	local function newLine(class) | ||
| 		return mw.html.create('span') | 		return mw.html.create('span') | ||
| 			:attr('class', 'itemboxstatsgroupline ' ..  | 			:attr( 'class', 'itemboxstatsgroupline ' .. (class or '') ) | ||
| 	end | 	end | ||
| 	local function newColor(label, text) | 	local function newColor(label, text) | ||
| Line 34: | Line 199: | ||
| 			:wikitext(text) | 			:wikitext(text) | ||
| 	end | 	end | ||
| 	if args.type == 'Weapon' then | |||
| 	if args.type == ' | |||
| 		group = newGroup() | 		group = newGroup() | ||
| 			:node( newLine() | 			:node( newLine() | ||
| 				:wikitext(args.subtype) | 				:wikitext(args.subtype or '') | ||
| 			) | 			) | ||
| 		if args.physical then | 		if args.physical then | ||
| Line 80: | Line 244: | ||
| 			) | 			) | ||
| 		container:node(group) | 		container:node(group) | ||
| 	elseif args.type == ' | 	elseif args.type == 'Armour' then | ||
| 		if args.blockChance or args.armour or args.evasion or args.energyShield then | 		if args.blockChance or args.armour or args.evasion or args.energyShield then | ||
| 			group = newGroup() | 			group = newGroup() | ||
| Line 113: | Line 277: | ||
| 			container:node(group) | 			container:node(group) | ||
| 		end | 		end | ||
| 	elseif args.type == ' | 	elseif args.type == 'Map' then | ||
| 		if args.mapLevel then | 		if args.mapLevel then | ||
| 			group = newGroup() | 			group = newGroup() | ||
| Line 129: | Line 293: | ||
| 			container:node(group) | 			container:node(group) | ||
| 		end | 		end | ||
| 	elseif args.type == ' | 	elseif args.type == 'Jewel' then | ||
| 		if args.radius then | 		if args.radius then | ||
| 			group = newGroup() | 			group = newGroup() | ||
| Line 138: | Line 302: | ||
| 			container:node(group) | 			container:node(group) | ||
| 		end | 		end | ||
| 	elseif args.type == ' | 	elseif args.type == 'Currency' then | ||
| 		group = newGroup() | 		group = newGroup() | ||
| 			:node( newLine() | 			:node( newLine() | ||
| Line 148: | Line 312: | ||
| 			group = newGroup('textwrap') | 			group = newGroup('textwrap') | ||
| 				:node( newLine('text-mod') | 				:node( newLine('text-mod') | ||
| 					:wikitext(args.effect) | 					:wikitext(args.effect or '') | ||
| 				) | 				) | ||
| 			container:node(group) | 			container:node(group) | ||
| 		end | 		end | ||
| 	elseif args.type == ' | 	elseif args.type == 'Flask' then | ||
| 		group = newGroup() | 		group = newGroup() | ||
| 		if args.life then | 		if args.life then | ||
| Line 193: | Line 357: | ||
| 			group | 			group | ||
| 				:node( newLine('text-mod') | 				:node( newLine('text-mod') | ||
| 					:wikitext(args.effect) | 					:wikitext(args.effect or '') | ||
| 				) | 				) | ||
| 		end | 		end | ||
| 		container:node(group) | 		container:node(group) | ||
| 	elseif args.type == ' | 	elseif args.type == 'Microtrans' then | ||
| 		group = newGroup() | 		group = newGroup() | ||
| 		if args.subtype or args.stackSize then | 		if args.subtype or args.stackSize then | ||
| 			group | 			group | ||
| 				:node( newLine() | 				:node( newLine() | ||
| 					:wikitext(args.subtype) | 					:wikitext(args.subtype or '') | ||
| 				) | 				) | ||
| 			if args.stackSize then | 			if args.stackSize then | ||
| Line 215: | Line 379: | ||
| 		group = newGroup('textwrap') | 		group = newGroup('textwrap') | ||
| 			:node( newLine('text-mod') | 			:node( newLine('text-mod') | ||
| 				:wikitext(args.effect) | 				:wikitext(args.effect or '') | ||
| 			) | 			) | ||
| 		container:node(group) | 		container:node(group) | ||
| Line 264: | Line 428: | ||
| 		group = newGroup() | 		group = newGroup() | ||
| 			:node( newLine('text-mod') | 			:node( newLine('text-mod') | ||
| 				:wikitext(args.implicitMods) | 				:wikitext(args.implicitMods or '') | ||
| 			) | 			) | ||
| 		container:node(group) | 		container:node(group) | ||
| Line 271: | Line 435: | ||
| 		group = newGroup() | 		group = newGroup() | ||
| 			:node( newLine('text-mod') | 			:node( newLine('text-mod') | ||
| 				:wikitext(args.randomMods) | 				:wikitext(args.randomMods or '') | ||
| 			) | 			) | ||
| 		container:node(group) | 		container:node(group) | ||
| Line 278: | Line 442: | ||
| 		group = newGroup() | 		group = newGroup() | ||
| 			:node( newLine('text-cosmetic') | 			:node( newLine('text-cosmetic') | ||
| 				:wikitext(args.cosmeticMods) | 				:wikitext(args.cosmeticMods or '') | ||
| 			) | 			) | ||
| 		container:node(group) | 		container:node(group) | ||
| Line 285: | Line 449: | ||
| 		group = newGroup() | 		group = newGroup() | ||
| 			:node( newLine('textwrap text-flavour') | 			:node( newLine('textwrap text-flavour') | ||
| 				:wikitext(args.flavourText) | 				:wikitext(args.flavourText or '') | ||
| 			) | 			) | ||
| 		container:node(group) | 		container:node(group) | ||
| Line 292: | Line 456: | ||
| 		group = newGroup() | 		group = newGroup() | ||
| 			:node( newLine('textwrap text-help') | 			:node( newLine('textwrap text-help') | ||
| 				:wikitext(args.helpText) | 				:wikitext(args.helpText or '') | ||
| 			) | 			) | ||
| 		container:node(group) | 		container:node(group) | ||
| 	end | 	end | ||
| 	return tostring(container) | 	return tostring(container) | ||
| end | |||
| --------------------------------------------------------------------- | |||
| -- Implements {{item range average}} | |||
| --------------------------------------------------------------------- | |||
| p.itemRangeAverage = makeInvokeFunc('_itemRangeAverage') | |||
| function p._itemRangeAverage(args) | |||
| 	local prop = args[1] | |||
| 	return prop | |||
| end | |||
| --------------------------------------------------------------------- | |||
| -- Implements {{itemsize}} | |||
| --------------------------------------------------------------------- | |||
| p.itemsize = makeInvokeFunc('_itemsize') | |||
| function p._itemsize(args) | |||
| 	local size = args[1] or '1x_' | |||
| 	local grid = args[2] or 78 | |||
| 	local dim = mw.text.split(size, 'x', true) | |||
| 	if dim[1] == '_' then | |||
| 		if dim[2] == '_' then | |||
| 			dim[1] = grid | |||
| 		else | |||
| 			dim[1] = '' | |||
| 		end | |||
| 	else | |||
| 		dim[1] = dim[1] * grid | |||
| 	end | |||
| 	if dim[2] == '_' then | |||
| 		dim[2] = '' | |||
| 	else | |||
| 		dim[2] = 'x' .. dim[2] * grid | |||
| 	end | |||
| 	return dim[1] .. dim[2] .. 'px' | |||
| end | end | ||
| return p | return p | ||
Revision as of 11:17, 22 April 2015
This page is not an actual Scribunto module. It exists to provide editors a place to create experimental modules.
Naming your modules
To keep things tidy, please use the following format to name your experimental modules:
Module:Sandbox/Your username/Module name
Cleaning up unused modules
Experimental modules may be deleted by admins upon request or after a long period of inactivity.
List of modules in this area
For a list of the experimental modules under Module:Sandbox, see Special:PrefixIndex/Module:Sandbox/.
The above documentation is transcluded from Module:Sandbox/doc. 
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
local p = {}
local views = {}
local getArgs
local doConcat
---------------------------------------------------------------------
-- Argument processing
---------------------------------------------------------------------
local function makeInvokeFunc(funcName)
	return function (frame)
		if not getArgs then
			getArgs = require('Module:Arguments').getArgs
		end
		local args = getArgs(frame)
		return p[funcName](args)
	end
end
---------------------------------------------------------------------
-- Implements {{item}}
---------------------------------------------------------------------
p.item = makeInvokeFunc('_item')
function p._item(args)
	local cleanArgs = {}
	cleanArgs.view = args.view or args.View or 'full'
	cleanArgs.format = args.format or args.Format
	cleanArgs.name = args.name or args.Name
	cleanArgs.sortKey = args.sortKey or args.SortKey or cleanArgs.name
	cleanArgs.pageName = args.pageName or args.PageName or cleanArgs.name
	cleanArgs.image = args.image or args.Image or cleanArgs.pageName .. '.png'
	cleanArgs.size = args.size or args.Size or '2x_'
	cleanArgs.rarity = args.rarity or args.Rarity or 'Normal'
	cleanArgs.type = args.type or args.Type
	cleanArgs.subtype = args.subtype or args.Subtype
	cleanArgs.baseItem = args.baseItem or args.BaseItem
	cleanArgs.baseItemPage = args.baseItemPage or args.BaseItemPage or cleanArgs.baseItem
	cleanArgs.level = args.level or args.RequiredLevel
	cleanArgs.strength = args.strength or args.RequiredStrength
	cleanArgs.dexterity = args.dexterity or args.RequiredDexterity
	cleanArgs.intelligence = args.intelligence or args.RequiredIntelligence
	cleanArgs.physical = args.physicalDamage or args.PhysicalDamage
	cleanArgs.fire = args.fire or args.FireDamage
	cleanArgs.cold = args.cold or args.ColdDamage
	cleanArgs.lightning = args.lightning or args.LightningDamage
	cleanArgs.chaos = args.chaos or args.ChaosDamage
	cleanArgs.averageDamage = args.averageDamage or args.AverageDamage
	cleanArgs.critChance = args.critChance or args.CriticalStrikeChance
	cleanArgs.attacksPerSecond = args.attacksPerSecond or args.AttacksPerSecond
	cleanArgs.blockChance = args.blockChance or args.Block
	cleanArgs.armour = args.armour or args.Armour
	cleanArgs.evasion = args.evasion or args.Evasion
	cleanArgs.energyShield = args.energyShield or args.EnergyShield
	cleanArgs.mapLevel = args.mapLevel or args.MapLevel
	cleanArgs.itemQuantity = args.itemQuantity or args.itemQuantity
	cleanArgs.radius = args.radius or args.Radius
	cleanArgs.stackSize = args.stackSize or args.StackSize
	cleanArgs.effect = args.effect or args.Effect
	cleanArgs.life = args.life or args.FlaskLife
	cleanArgs.mana = args.mana or args.FlaskMana
	cleanArgs.duration = args.duration or args.FlaskDuration
	cleanArgs.chargeCap = args.chargeCap or args.FlaskCharges
	cleanArgs.chargeUse = args.chargeUse or args.ChargesUsed
	cleanArgs.implicitMods = args.implicitMods or args.ImplicitMods
	cleanArgs.randomMods = args.randomMods or args.RandomMods
	cleanArgs.cosmeticMods = args.cosmeticMods or args.CosmeticMods
	cleanArgs.helpText = args.helpText or args.HelpText
	cleanArgs.flavourText = args.flavourText or args.FlavourText
	return views[cleanArgs.view](cleanArgs)
end
---------------------------------------------------------------------
-- Views
---------------------------------------------------------------------
function views.full(args)
	args.stats = p.statsBuilder(args)
	args.class = 'itembox-full'
	local frame = {
		['Currency'] = 'currency',
		['Microtrans'] = 'currency',
		['Gem'] = 'gem',
		['Quest'] = 'quest'
	}
	args.frame = frame[args.type] or args.rarity
	args.name = '[[' .. args.pageName .. '|' .. args.name .. ']]'
	args.baseItem = args.baseItem and ('[[' .. args.baseItemPage .. '|' .. args.baseItem .. ']]') or nil
	args.belowstats = tostring(
		mw.html.create('div')
			:attr('class', 'itemboximage')
			:wikitext( '[[File:' .. args.image .. '|' .. p._itemsize(args.size) .. '|]]' )
	)
	local category
	local types = {
		['Weapon'] = {
			['Bow'] = 'Bows',
			['Claw'] = 'Claws',
			['Dagger'] = 'Daggers',
			['Wand'] = 'Wands',
			['Fishing Rod'] = 'Fishing rods',
			['Staff'] = 'Staves',
			['One Handed Axe'] = 'One-handed axes',
			['Two Handed Axe'] = 'Two-handed axes',
			['One Handed Mace'] = 'One-handed maces',
			['Two Handed Mace'] = 'Two-handed maces',
			['One Handed Sword'] = 'One-handed swords',
			['Two Handed Sword'] = 'Two-handed swords'
		},
		['Armour'] = {
			['Body Armour'] = 'Body armours',
			['Helmet'] = 'Helmets',
			['Shield'] = 'Shields',
			['Boots'] = 'Boots',
			['Gloves'] = 'Gloves'
		},
		['Accessory'] = {
			['Amulet'] = 'Amulets',
			['Belt'] = 'Belts',
			['Quiver'] = 'Quivers',
			['Ring'] = 'Rings'
		},
		['Flask'] = {
			['Life'] = 'Life flasks',
			['Mana'] = 'Mana flasks',
			['Hybrid'] = 'Hybrid flasks',
			['Utility'] = 'Utility flasks'
		},
		['Map'] = {
			['Fragment'] = 'Map fragments',
			['_default'] = 'Maps'
		},
		['Jewel'] = 'Jewels',
		['Currency'] = 'Currency items',
		['Quest'] = 'Quest items',
		['Microtrans'] = 'Microtransaction features'
	}
	category = types[args.type]
	if type(category) == 'table' then
		category = types[args.type][args.subtype or '_default']
	end
	if category then
		if args.rarity == 'Unique' then
			category = 'Unique ' .. string.lower(category)
		end
	else
		category = 'Items with invalid types'
	end
	return p.itembox(args) .. '[[Category:' .. category .. ']]'
end
---------------------------------------------------------------------
-- Itembox
---------------------------------------------------------------------
function p.itembox(args)
	local container = mw.html.create(args.ishover and 'span' or 'div')
		:attr( 'class', 'itembox-' .. ( string.lower(args.frame or 'normal') ) .. (args.class or '') )
		:tag('span')
			:attr( 'class', 'itemboxheader-' .. (args.baseItem and 'double' or 'single') )
			:tag('span')
				:attr('class', 'itemboxheaderleft')
				:done()
			:tag('span')
				:attr('class', 'itemboxheaderright')
				:done()
			:tag('span')
				:attr('class', 'itemboxheadertext')
				:wikitext( args.name .. (args.baseItem and '<br>' .. args.baseItem or '') )
				:done()
			:done()
		:wikitext(args.abovestats or '')
		:tag('span')
			:attr('class', 'itemboxstats')
			:wikitext(args.stats or '')
			:done()
		:wikitext(args.belowstats or '')
	return tostring(container)
end
---------------------------------------------------------------------
-- Stats builder
---------------------------------------------------------------------
function p.statsBuilder(args)
	local container = mw.html.create('span')
	local group
	local function newGroup(class)
		return mw.html.create('span')
			:attr( 'class', 'itemboxstatsgroup ' .. (class or '') )
	end
	local function newLine(class)
		return mw.html.create('span')
			:attr( 'class', 'itemboxstatsgroupline ' .. (class or '') )
	end
	local function newColor(label, text)
		if text == nil or text == '' then
			return nil
		end
		return mw.html.create('span')
			:attr('class', 'text-' .. label)
			:wikitext(text)
	end
	if args.type == 'Weapon' then
		group = newGroup()
			:node( newLine()
				:wikitext(args.subtype or '')
			)
		if args.physical then
			group
				:node( newLine()
					:wikitext('Physical Damage: ')
					:node( newColor('value', args.physical) )
				)
		end
		if args.fire or args.cold or args.lightning then
			if not doConcat then
				doConcat = require('Module:Concat')._main
			end
			group
				:node( newLine()
					:wikitext('Elemental Damage: ')
					:wikitext(
						doConcat({
							tostring( newColor('fire', args.fire) ), 
							tostring( newColor('cold', args.cold) ), 
							tostring( newColor('lightning', args.lightning) )
						})
					)
				)
		end
		if args.chaos then
			group
				:node( newLine()
					:wikitext('Chaos Damage: ')
					:node( newColor('chaos', args.chaos) )
				)
		end
		group
			:node( newLine()
				:wikitext('Critical Strike Chance: ')
				:node( newColor('value', args.critChance) )
			)
			:node( newLine()
				:wikitext('Attacks per Second: ')
				:node( newColor('value', args.attacksPerSecond) )
			)
		container:node(group)
	elseif args.type == 'Armour' then
		if args.blockChance or args.armour or args.evasion or args.energyShield then
			group = newGroup()
			if args.blockChance then
				group
					:node( newLine()
						:wikitext('Chance to Block: ')
						:node( newColor('value', args.blockChance) )
					)
			end
			if args.armour then
				group
					:node( newLine()
						:wikitext('Armour: ')
						:node( newColor('value', args.armour) )
					)
			end
			if args.evasion then
				group
					:node( newLine()
						:wikitext('Evasion: ')
						:node( newColor('value', args.evasion) )
					)
			end
			if args.energyShield then
				group
					:node( newLine()
						:wikitext('Energy Shield: ')
						:node( newColor('value', args.energyShield) )
					)
			end
			container:node(group)
		end
	elseif args.type == 'Map' then
		if args.mapLevel then
			group = newGroup()
				:node( newLine()
					:wikitext('Map Level: ')
					:node( newColor('value', args.mapLevel) )
				)
			if args.itemQuantity then
				group
					:node( newLine()
						:wikitext('Item Quantity: ')
						:node( newColor('value', args.itemQuantity) )
					)
			end
			container:node(group)
		end
	elseif args.type == 'Jewel' then
		if args.radius then
			group = newGroup()
				:node( newLine()
					:wikitext('Radius: ')
					:node( newColor('value', args.radius) )
				)
			container:node(group)
		end
	elseif args.type == 'Currency' then
		group = newGroup()
			:node( newLine()
				:wikitext('Stack Size: ')
				:node( newColor('value', args.stackSize) )
			)
		container:node(group)
		if args.effect then
			group = newGroup('textwrap')
				:node( newLine('text-mod')
					:wikitext(args.effect or '')
				)
			container:node(group)
		end
	elseif args.type == 'Flask' then
		group = newGroup()
		if args.life then
			group
				:node( newLine()
					:wikitext('Recovers ')
					:node( newColor('value', args.life) )
					:wikitext(' Life over ')
					:node( newColor('value', args.duration) )
					:wikitext(' Seconds')
				)
		end
		if args.mana then
			group
				:node( newLine()
					:wikitext('Recovers ')
					:node( newColor('value', args.mana) )
					:wikitext(' Mana over ')
					:node( newColor('value', args.duration) )
					:wikitext(' Seconds')
				)
		end
		if args.effect then
			group
				:node( newLine()
					:wikitext('Lasts ')
					:node( newColor('value', args.duration) )
					:wikitext(' Seconds')
				)
		end
		group
			:node( newLine()
				:wikitext('Consumes ')
				:node( newColor('value', args.chargeUse) )
				:wikitext(' of ')
				:node( newColor('value', args.chargeCap) )
				:wikitext(' Charges on use')
			)
		if args.effect then
			group
				:node( newLine('text-mod')
					:wikitext(args.effect or '')
				)
		end
		container:node(group)
	elseif args.type == 'Microtrans' then
		group = newGroup()
		if args.subtype or args.stackSize then
			group
				:node( newLine()
					:wikitext(args.subtype or '')
				)
			if args.stackSize then
				group
					:node( newLine()
						:wikitext('Stack Size: ')
						:node( newColor('value', args.stackSize) )
					)
			end
			container:node(group)
		end
		group = newGroup('textwrap')
			:node( newLine('text-mod')
				:wikitext(args.effect or '')
			)
		container:node(group)
	end
	if args.level or args.strength or args.dexterity or args.intelligence then
		local lvlReq
		local strReq
		local dexReq
		local intReq
		local reqTxt
		if args.level then
			lvlReq = 'Level ' .. tostring( newColor('value', args.level) )
		end
		if args.strength then
			reqTxt = 'Strength'
			if args.level or args.dexterity or args.intelligence then
				reqTxt = 'Str'
			end
			strReq = tostring( newColor('value', args.strength) ) .. reqTxt
		end
		if args.dexterity then
			reqTxt = 'Dexterity'
			if args.level or args.strength or args.intelligence then
				reqTxt = 'Dex'
			end
			dexReq = tostring( newColor('value', args.dexterity) ) .. reqTxt
		end
		if args.intelligence then
			reqTxt = 'Intelligence'
			if args.level or args.strength or args.dexterity then
				reqTxt = 'Int'
			end
			intReq = tostring( newColor('value', args.intelligence) ) .. reqTxt
		end
		if not doConcat then
			doConcat = require('Module:Concat')._main
		end
		group = newGroup()
			:node( newLine()
				:wikitext('Requires ')
				:wikitext(
					doConcat({lvlReq, strReq, dexReq, intReq})
				)
			)
		container:node(group)
	end
	if args.implicitMods then
		group = newGroup()
			:node( newLine('text-mod')
				:wikitext(args.implicitMods or '')
			)
		container:node(group)
	end
	if args.randomMods then
		group = newGroup()
			:node( newLine('text-mod')
				:wikitext(args.randomMods or '')
			)
		container:node(group)
	end
	if args.cosmeticMods then
		group = newGroup()
			:node( newLine('text-cosmetic')
				:wikitext(args.cosmeticMods or '')
			)
		container:node(group)
	end
	if args.flavourText then
		group = newGroup()
			:node( newLine('textwrap text-flavour')
				:wikitext(args.flavourText or '')
			)
		container:node(group)
	end
	if args.helpText then
		group = newGroup()
			:node( newLine('textwrap text-help')
				:wikitext(args.helpText or '')
			)
		container:node(group)
	end
	return tostring(container)
end
---------------------------------------------------------------------
-- Implements {{item range average}}
---------------------------------------------------------------------
p.itemRangeAverage = makeInvokeFunc('_itemRangeAverage')
function p._itemRangeAverage(args)
	local prop = args[1]
	return prop
end
---------------------------------------------------------------------
-- Implements {{itemsize}}
---------------------------------------------------------------------
p.itemsize = makeInvokeFunc('_itemsize')
function p._itemsize(args)
	local size = args[1] or '1x_'
	local grid = args[2] or 78
	local dim = mw.text.split(size, 'x', true)
	if dim[1] == '_' then
		if dim[2] == '_' then
			dim[1] = grid
		else
			dim[1] = ''
		end
	else
		dim[1] = dim[1] * grid
	end
	if dim[2] == '_' then
		dim[2] = ''
	else
		dim[2] = 'x' .. dim[2] * grid
	end
	return dim[1] .. dim[2] .. 'px'
end
return p
