<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://dev.dsp-wiki.com/Module:Item/history?feed=atom</id>
	<title>Module:Item - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://dev.dsp-wiki.com/Module:Item/history?feed=atom"/>
	<link rel="alternate" type="text/html" href="https://dev.dsp-wiki.com/Module:Item/history"/>
	<updated>2026-05-08T21:16:49Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://dev.dsp-wiki.com/index.php?title=Module:Item&amp;diff=14394&amp;oldid=prev</id>
		<title>Antt1995: 1 revision imported: New Files</title>
		<link rel="alternate" type="text/html" href="https://dev.dsp-wiki.com/index.php?title=Module:Item&amp;diff=14394&amp;oldid=prev"/>
		<updated>2024-03-24T11:54:36Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported: New Files&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 11:54, 24 March 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Antt1995</name></author>
	</entry>
	<entry>
		<id>https://dev.dsp-wiki.com/index.php?title=Module:Item&amp;diff=14390&amp;oldid=prev</id>
		<title>Antt1995 at 05:26, 22 November 2023</title>
		<link rel="alternate" type="text/html" href="https://dev.dsp-wiki.com/index.php?title=Module:Item&amp;diff=14390&amp;oldid=prev"/>
		<updated>2023-11-22T05:26:11Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require( &amp;#039;strict&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
local Item = {}&lt;br /&gt;
&lt;br /&gt;
local metatable = {}&lt;br /&gt;
local methodtable = {}&lt;br /&gt;
&lt;br /&gt;
metatable.__index = methodtable&lt;br /&gt;
&lt;br /&gt;
local TNT = require( &amp;#039;Module:Translate&amp;#039; ):new()&lt;br /&gt;
local common = require( &amp;#039;Module:Common&amp;#039; )&lt;br /&gt;
local manufacturer = require( &amp;#039;Module:Manufacturer&amp;#039; )._manufacturer&lt;br /&gt;
local hatnote = require( &amp;#039;Module:Hatnote&amp;#039; )._hatnote&lt;br /&gt;
local data = mw.loadJsonData( &amp;#039;Module:Item/data.json&amp;#039; )&lt;br /&gt;
local config = mw.loadJsonData( &amp;#039;Module:Item/config.json&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
local lang&lt;br /&gt;
if config.module_lang then&lt;br /&gt;
	lang = mw.getLanguage( config.module_lang )&lt;br /&gt;
else&lt;br /&gt;
	lang = mw.getContentLanguage()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local moduleCache = {}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Wrapper function for Module:Translate.translate&lt;br /&gt;
---&lt;br /&gt;
--- @param key string The translation key&lt;br /&gt;
--- @param addSuffix boolean Adds a language suffix if config.smw_multilingual_text is true&lt;br /&gt;
--- @return string If the key was not found in the .tab page, the key is returned&lt;br /&gt;
local function translate( key, addSuffix, ... )&lt;br /&gt;
	return TNT:translate( &amp;#039;Module:Item/i18n.json&amp;#039;, config, key, addSuffix, {...} ) or key&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Invokes a method on the required module, if the modules type matches targetType&lt;br /&gt;
--- Utilizes the moduleCache to only load modules once&lt;br /&gt;
---&lt;br /&gt;
--- @param targetType string|boolean The type to check against extension_modules.type or &amp;#039;true&amp;#039; to run against all modules&lt;br /&gt;
--- @param methodName string The method to invoke&lt;br /&gt;
--- @param args table Arguments passed to the method&lt;br /&gt;
local function runModuleFN( targetType, methodName, args, returnsData )&lt;br /&gt;
	returnsData = returnsData or false&lt;br /&gt;
	for _, module in ipairs( data.extension_modules ) do&lt;br /&gt;
		if targetType == true or ( module.type ~= nil and type( module.type ) == &amp;#039;table&amp;#039; ) then&lt;br /&gt;
			for _, type in ipairs( module.type ) do&lt;br /&gt;
				if module ~= nil and ( targetType == true or targetType == type ) then&lt;br /&gt;
					if moduleCache[ module.name ] == nil then&lt;br /&gt;
						local success, mod = pcall( require, module.name )&lt;br /&gt;
						if success then&lt;br /&gt;
							moduleCache[ module.name ] = mod&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					module = moduleCache[ module.name ]&lt;br /&gt;
&lt;br /&gt;
					if module ~= nil then&lt;br /&gt;
						local result = module[ methodName ]( unpack( args ) )&lt;br /&gt;
						if returnsData then&lt;br /&gt;
							return result&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Creates the object that is used to query the SMW store&lt;br /&gt;
---&lt;br /&gt;
--- @param page string the item page containing data&lt;br /&gt;
--- @return table&lt;br /&gt;
local function makeSmwQueryObject( page )&lt;br /&gt;
	local query = {&lt;br /&gt;
		string.format( &amp;#039;[[%s]]&amp;#039;, page ),&lt;br /&gt;
		&amp;#039;?Page image#-=image&amp;#039;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	require( &amp;#039;Module:Common/SMW&amp;#039; ).addSmwAskProperties(&lt;br /&gt;
		query,&lt;br /&gt;
		translate,&lt;br /&gt;
		config,&lt;br /&gt;
		data&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	runModuleFN( true, &amp;#039;addSmwAskProperties&amp;#039;, { query } )&lt;br /&gt;
&lt;br /&gt;
	table.insert( query, &amp;#039;limit=1&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	return query&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Request Api Data&lt;br /&gt;
--- Using current subpage name without item type suffix&lt;br /&gt;
--- @return table or nil&lt;br /&gt;
function methodtable.getApiDataForCurrentPage( self )&lt;br /&gt;
	local api = require( &amp;#039;Module:Common/Api&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	local query = self.frameArgs[ translate( &amp;#039;ARG_UUID&amp;#039; ) ] or self.frameArgs[ translate( &amp;#039;ARG_Name&amp;#039; ) ] or common.removeTypeSuffix(&lt;br /&gt;
        mw.title.getCurrentTitle().rootText,&lt;br /&gt;
		config.name_suffixes&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
	local success, json = pcall( mw.text.jsonDecode, mw.ext.Apiunto.get_raw( &amp;#039;v2/items/&amp;#039; .. query, {&lt;br /&gt;
		include = data.includes,&lt;br /&gt;
		locale = config.api_locale&lt;br /&gt;
	} ) )&lt;br /&gt;
&lt;br /&gt;
	if not success or api.checkResponseStructure( json, true, false ) == false then return end&lt;br /&gt;
&lt;br /&gt;
    self.apiData = json[ &amp;#039;data&amp;#039; ]&lt;br /&gt;
    self.apiData = api.makeAccessSafe( self.apiData )&lt;br /&gt;
&lt;br /&gt;
    return self.apiData&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Base Properties that are shared across all items&lt;br /&gt;
--- @return table SMW Result&lt;br /&gt;
function methodtable.setSemanticProperties( self )&lt;br /&gt;
	local setData = {}&lt;br /&gt;
&lt;br /&gt;
	local smwCommon = require( &amp;#039;Module:Common/SMW&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	smwCommon.addSmwProperties(&lt;br /&gt;
		self.apiData,&lt;br /&gt;
		self.frameArgs,&lt;br /&gt;
		setData,&lt;br /&gt;
		translate,&lt;br /&gt;
		config,&lt;br /&gt;
		data,&lt;br /&gt;
		&amp;#039;Item&amp;#039;&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	setData[ translate( &amp;#039;SMW_Name&amp;#039; ) ] = self.frameArgs[ translate( &amp;#039;ARG_Name&amp;#039; ) ] or common.removeTypeSuffix(&lt;br /&gt;
		mw.title.getCurrentTitle().rootText,&lt;br /&gt;
		config.name_suffixes&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	if type( setData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ] ) == &amp;#039;string&amp;#039; then&lt;br /&gt;
		local man = manufacturer( setData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ] )&lt;br /&gt;
		if man ~= nil then man = man.name end&lt;br /&gt;
&lt;br /&gt;
		setData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ] = man or setData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ]&lt;br /&gt;
		setData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ] = string.format( &amp;#039;[[%s]]&amp;#039;, setData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ] )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Set properties with API data&lt;br /&gt;
    if self.apiData ~= nil and self.apiData.uuid ~= nil then&lt;br /&gt;
		--- Commodity&lt;br /&gt;
		local commodity = require( &amp;#039;Module:Commodity&amp;#039; ):new()&lt;br /&gt;
		commodity:addShopData( self.apiData )&lt;br /&gt;
&lt;br /&gt;
		--- Merge subtype into type, like how the game handles it&lt;br /&gt;
		if self.apiData.type ~= nil and self.apiData.sub_type ~= nil and self.apiData.sub_type ~= &amp;#039;UNDEFINED&amp;#039; then&lt;br /&gt;
			--- SMW_Type is already set prior if self.apiData.type exists&lt;br /&gt;
			setData[ translate( &amp;#039;SMW_Type&amp;#039; ) ] = string.format( &amp;#039;%s.%s&amp;#039;, setData[ translate( &amp;#039;SMW_Type&amp;#039; ) ], self.apiData.sub_type )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	runModuleFN( setData[ translate( &amp;#039;SMW_Type&amp;#039; ) ], &amp;#039;addSmwProperties&amp;#039;, { self.apiData, self.frameArgs, setData } )&lt;br /&gt;
&lt;br /&gt;
	mw.logObject( setData, &amp;#039;SET&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	self.setData = setData&lt;br /&gt;
&lt;br /&gt;
	return mw.smw.set( setData )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Queries the SMW Store&lt;br /&gt;
--- @return table&lt;br /&gt;
function methodtable.getSmwData( self )&lt;br /&gt;
	-- Cache multiple calls&lt;br /&gt;
    if self.smwData ~= nil and self.smwData[ translate( &amp;#039;SMW_Name&amp;#039; ) ] ~= nil then&lt;br /&gt;
        return self.smwData&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
	local queryName = self.frameArgs[ translate( &amp;#039;ARG_SmwQueryName&amp;#039; ) ] or&lt;br /&gt;
					  mw.title.getCurrentTitle().fullText&lt;br /&gt;
&lt;br /&gt;
    local smwData = mw.smw.ask( makeSmwQueryObject( queryName ) )&lt;br /&gt;
&lt;br /&gt;
    if smwData == nil or smwData[ 1 ] == nil then&lt;br /&gt;
		return hatnote( string.format(&lt;br /&gt;
				&amp;#039;%s[[%s]]&amp;#039;,&lt;br /&gt;
				translate( &amp;#039;error_no_data_text&amp;#039; ),&lt;br /&gt;
				translate( &amp;#039;error_script_error_cat&amp;#039; )&lt;br /&gt;
			),&lt;br /&gt;
			{ icon = &amp;#039;WikimediaUI-Error.svg&amp;#039; }&lt;br /&gt;
		)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    self.smwData = smwData[ 1 ]&lt;br /&gt;
&lt;br /&gt;
    return self.smwData&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Creates the infobox&lt;br /&gt;
function methodtable.getInfobox( self )&lt;br /&gt;
	local smwData = self:getSmwData()&lt;br /&gt;
&lt;br /&gt;
	local infobox = require( &amp;#039;Module:InfoboxNeue&amp;#039; ):new( {&lt;br /&gt;
		placeholderImage = config.placeholder_image&lt;br /&gt;
	} )&lt;br /&gt;
	local tabber = require( &amp;#039;Module:Tabber&amp;#039; ).renderTabber&lt;br /&gt;
&lt;br /&gt;
	--- SMW Data load error&lt;br /&gt;
	--- Infobox data should always have Name property&lt;br /&gt;
	if type( smwData ) ~= &amp;#039;table&amp;#039; then&lt;br /&gt;
		return infobox:renderInfobox( infobox:renderMessage( {&lt;br /&gt;
			title = translate( &amp;#039;error_no_data_title&amp;#039; ),&lt;br /&gt;
			desc = translate( &amp;#039;error_no_data_text&amp;#039; ),&lt;br /&gt;
		} ) )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function getManufacturer()&lt;br /&gt;
		if smwData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ] == nil then return end&lt;br /&gt;
&lt;br /&gt;
		local mfu = manufacturer( smwData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ] )&lt;br /&gt;
		if mfu == nil then return &amp;#039;[[&amp;#039; .. smwData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ] .. &amp;#039;]]&amp;#039; end&lt;br /&gt;
&lt;br /&gt;
		return infobox.showDescIfDiff(&lt;br /&gt;
			table.concat( { &amp;#039;[[&amp;#039;, smwData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ], &amp;#039;|&amp;#039;, mfu.name , &amp;#039;]]&amp;#039; } ),&lt;br /&gt;
			mfu.code&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function getType()&lt;br /&gt;
		if smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ] == nil then return end&lt;br /&gt;
&lt;br /&gt;
		local itemType = translate( string.format( &amp;#039;type_%s&amp;#039;, string.lower( smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ] ) ) )&lt;br /&gt;
&lt;br /&gt;
		if string.find( itemType, &amp;#039;type_&amp;#039; ) then&lt;br /&gt;
			itemType = smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ]&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return string.format( &amp;#039;[[%s]]&amp;#039;, itemType )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function getSize()&lt;br /&gt;
		if smwData[ translate( &amp;#039;SMW_Size&amp;#039; ) ] == nil then return end&lt;br /&gt;
		return &amp;#039;S&amp;#039; .. smwData[ translate( &amp;#039;SMW_Size&amp;#039; ) ]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function getClass()&lt;br /&gt;
		if smwData[ translate( &amp;#039;SMW_Class&amp;#039; ) ] == nil then return end&lt;br /&gt;
&lt;br /&gt;
		local classKey = string.lower( smwData[ translate( &amp;#039;SMW_Class&amp;#039; ) ] )&lt;br /&gt;
		local class = translate( string.format( &amp;#039;class_%s&amp;#039;, classKey ) )&lt;br /&gt;
&lt;br /&gt;
		if smwData[ translate( &amp;#039;SMW_Grade&amp;#039; ) ] ~= nil then&lt;br /&gt;
			class = class .. &amp;#039; (&amp;#039; .. smwData[ translate( &amp;#039;SMW_Grade&amp;#039; ) ] .. &amp;#039;)&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return class&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--- Other sites&lt;br /&gt;
	local function getOfficialSites()&lt;br /&gt;
		local links = {}&lt;br /&gt;
&lt;br /&gt;
		for _, site in ipairs( data.official_sites ) do&lt;br /&gt;
			local query = smwData[ translate( site.attribute ) ]&lt;br /&gt;
&lt;br /&gt;
			if query ~= nil then&lt;br /&gt;
				table.insert( links, infobox:renderLinkButton( {&lt;br /&gt;
					label = translate( site.label ),&lt;br /&gt;
					link = query&lt;br /&gt;
				} ) )&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return links&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function getCommunitySites()&lt;br /&gt;
		local links = {}&lt;br /&gt;
&lt;br /&gt;
		for _, site in ipairs( data.community_sites ) do&lt;br /&gt;
			local query = smwData[ translate( site.data ) ]&lt;br /&gt;
&lt;br /&gt;
			if query ~= nil then&lt;br /&gt;
				if site.data == &amp;#039;SMW_ClassName&amp;#039; or site.data == &amp;#039;SMW_UUID&amp;#039; then&lt;br /&gt;
					query = string.lower( query )&lt;br /&gt;
				elseif site.data == &amp;#039;SMW_ShipMatrixName&amp;#039; then&lt;br /&gt;
					query = mw.uri.encode( query, &amp;#039;PATH&amp;#039; )&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				if site.label == &amp;#039;FleetYards&amp;#039; then&lt;br /&gt;
					query = string.lower( string.gsub( query, &amp;#039;%%20&amp;#039;, &amp;#039;-&amp;#039; ) )&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				table.insert( links, infobox:renderLinkButton( {&lt;br /&gt;
					label = site.label,&lt;br /&gt;
					link = string.format( site.format, query )&lt;br /&gt;
				} ) )&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return links&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	local image = self.frameArgs[ translate( &amp;#039;ARG_Image&amp;#039; ) ] or self.frameArgs[ &amp;#039;image&amp;#039; ] or smwData[ &amp;#039;image&amp;#039; ]&lt;br /&gt;
	infobox:renderImage( image )&lt;br /&gt;
&lt;br /&gt;
	infobox:renderHeader( {&lt;br /&gt;
		title = smwData[ translate( &amp;#039;SMW_Name&amp;#039; ) ],&lt;br /&gt;
		--- e.g. Aegis Dynamics (AEGS)&lt;br /&gt;
		subtitle = getManufacturer(),&lt;br /&gt;
		badge = getSize()&lt;br /&gt;
	} )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--- Type, Size, Class&lt;br /&gt;
	infobox:renderSection( {&lt;br /&gt;
		content = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Type&amp;#039; ),&lt;br /&gt;
				data = getType(),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Class&amp;#039; ),&lt;br /&gt;
				data = getClass(),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Occupancy&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_Occupancy&amp;#039; ) ],&lt;br /&gt;
			} )&lt;br /&gt;
		},&lt;br /&gt;
		col = 2&lt;br /&gt;
	} )&lt;br /&gt;
&lt;br /&gt;
	local pageIdentifier = self.frameArgs[ translate( &amp;#039;ARG_SmwQueryName&amp;#039; ) ] or mw.title.getCurrentTitle().fullText&lt;br /&gt;
	runModuleFN( smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ], &amp;#039;addInfoboxData&amp;#039;, { infobox, smwData, pageIdentifier } )&lt;br /&gt;
&lt;br /&gt;
	--- Dimensions&lt;br /&gt;
	infobox:renderSection( {&lt;br /&gt;
		title = translate( &amp;#039;LBL_Dimensions&amp;#039; ),&lt;br /&gt;
		content = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Length&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_EntityLength&amp;#039; ) ],&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Width&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_EntityWidth&amp;#039; ) ],&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Height&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_EntityHeight&amp;#039; ) ],&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Mass&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_Mass&amp;#039; ) ],&lt;br /&gt;
			} )&lt;br /&gt;
		},&lt;br /&gt;
		col = 3&lt;br /&gt;
	} )&lt;br /&gt;
&lt;br /&gt;
	--- Footer&lt;br /&gt;
	infobox:renderFooter( {&lt;br /&gt;
		content = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;SMW_UUID&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_UUID&amp;#039; ) ],&lt;br /&gt;
				row = true,&lt;br /&gt;
				spacebetween = true&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;SMW_GameBuild&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_GameBuild&amp;#039; ) ],&lt;br /&gt;
				row = true,&lt;br /&gt;
				spacebetween = true&lt;br /&gt;
			} ),&lt;br /&gt;
		},&lt;br /&gt;
		button = {&lt;br /&gt;
			icon = &amp;#039;WikimediaUI-Globe.svg&amp;#039;,&lt;br /&gt;
			label = translate( &amp;#039;LBL_OtherSites&amp;#039; ),&lt;br /&gt;
			type = &amp;#039;popup&amp;#039;,&lt;br /&gt;
			content = infobox:renderSection( {&lt;br /&gt;
				content = {&lt;br /&gt;
					infobox:renderItem( {&lt;br /&gt;
						label = translate( &amp;#039;LBL_OfficialSites&amp;#039; ),&lt;br /&gt;
						data = table.concat( getOfficialSites(), &amp;#039;&amp;#039; )&lt;br /&gt;
					} ),&lt;br /&gt;
					infobox:renderItem( {&lt;br /&gt;
						label = translate( &amp;#039;LBL_CommunitySites&amp;#039; ),&lt;br /&gt;
						data = table.concat( getCommunitySites(), &amp;#039;&amp;#039; )&lt;br /&gt;
					} ),&lt;br /&gt;
				},&lt;br /&gt;
				class = &amp;#039;infobox__section--linkButtons&amp;#039;,&lt;br /&gt;
			}, true )&lt;br /&gt;
		}&lt;br /&gt;
	} )&lt;br /&gt;
&lt;br /&gt;
	return infobox:renderInfobox( nil, smwData[ translate( &amp;#039;SMW_Name&amp;#039; ) ] )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Set the frame and load args&lt;br /&gt;
--- @param frame table&lt;br /&gt;
function methodtable.setFrame( self, frame )&lt;br /&gt;
	self.currentFrame = frame&lt;br /&gt;
	self.frameArgs = require( &amp;#039;Module:Arguments&amp;#039; ).getArgs( frame )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Sets the main categories for this object&lt;br /&gt;
function methodtable.setCategories( self )&lt;br /&gt;
	if config.set_categories == false then&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--- Lowers all words unless the word is fully capitalized (e.g.: EMP Generators -&amp;gt; EMP generators)&lt;br /&gt;
	local function lowercaseWords( input )&lt;br /&gt;
	    local result = input:gsub( &amp;#039;(%S+)&amp;#039; , function( word )&lt;br /&gt;
    	    if string.upper( word ) == word then&lt;br /&gt;
        	    return word&lt;br /&gt;
    	    end&lt;br /&gt;
&lt;br /&gt;
			return string.lower( word )&lt;br /&gt;
	    end)&lt;br /&gt;
	    return result&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function startsWith( str, start )&lt;br /&gt;
		return str:sub( 1, #start ) == start&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--- Only set category if category_type value exists&lt;br /&gt;
	if self.smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ] ~= nil then&lt;br /&gt;
		local typeCategory = translate( &amp;#039;category_&amp;#039; .. string.lower( self.smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ] ) )&lt;br /&gt;
&lt;br /&gt;
		if typeCategory ~= nil and typeCategory ~= &amp;#039;category_&amp;#039; .. string.lower( self.smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ] ) then&lt;br /&gt;
			table.insert( self.categories, typeCategory ) &lt;br /&gt;
			&lt;br /&gt;
			local categoryTypeSuffix = translate( &amp;#039;category_&amp;#039; .. string.lower( self.smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ] ) )&lt;br /&gt;
			if startsWith( lang:getCode(), &amp;#039;en&amp;#039; ) then categoryTypeSuffix = lowercaseWords( categoryTypeSuffix ) end&lt;br /&gt;
&lt;br /&gt;
			if self.smwData[ translate( &amp;#039;SMW_Size&amp;#039; ) ] ~= nil then&lt;br /&gt;
				local sizeCategory = translate( &amp;#039;SMW_Size&amp;#039; ) .. &amp;#039; &amp;#039; .. self.smwData[ translate( &amp;#039;SMW_Size&amp;#039; ) ] .. &amp;#039; &amp;#039; .. categoryTypeSuffix&lt;br /&gt;
				table.insert( self.categories, sizeCategory )&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if self.smwData[ translate( &amp;#039;SMW_Grade&amp;#039; ) ] ~= nil then&lt;br /&gt;
				local gradeCategory = translate( &amp;#039;SMW_Grade&amp;#039; ) .. &amp;#039; &amp;#039; .. self.smwData[ translate( &amp;#039;SMW_Grade&amp;#039; ) ] .. &amp;#039; &amp;#039; .. categoryTypeSuffix&lt;br /&gt;
				table.insert( self.categories, gradeCategory )&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if self.smwData[ translate( &amp;#039;SMW_Class&amp;#039; ) ] ~= nil then&lt;br /&gt;
				local classCategory = self.smwData[ translate( &amp;#039;SMW_Class&amp;#039; ) ] .. &amp;#039; &amp;#039; .. categoryTypeSuffix&lt;br /&gt;
				table.insert( self.categories, classCategory )&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if self.smwData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ] ~= nil then&lt;br /&gt;
		local manufacturer = string.gsub( self.smwData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ], &amp;#039;%[+&amp;#039;, &amp;#039;&amp;#039; )&lt;br /&gt;
		manufacturer = string.gsub( manufacturer, &amp;#039;%]+&amp;#039;, &amp;#039;&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
		table.insert( self.categories, manufacturer )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	runModuleFN( self.smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ], &amp;#039;addCategories&amp;#039;, { self.categories, self.frameArgs, self.smwData } )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Sets the short description for this object&lt;br /&gt;
function methodtable.setShortDescription( self )&lt;br /&gt;
	local shortdesc = &amp;#039;&amp;#039;&lt;br /&gt;
	local itemType = translate( &amp;#039;type_item&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	if self.smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ] ~= nil then&lt;br /&gt;
		local itemTypeKey = &amp;#039;type_&amp;#039; .. string.lower( self.smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ] )&lt;br /&gt;
		if translate( itemTypeKey ) ~= nil and translate( itemTypeKey ) ~= itemTypeKey then&lt;br /&gt;
			itemType = string.lower( translate( itemTypeKey ) )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	shortdesc = itemType&lt;br /&gt;
&lt;br /&gt;
	if self.smwData[ translate( &amp;#039;SMW_Class&amp;#039; ) ] ~= nil then&lt;br /&gt;
		shortdesc = string.format( &amp;#039;%s %s&amp;#039;,&lt;br /&gt;
			string.lower( self.smwData[ translate( &amp;#039;SMW_Class&amp;#039; ) ] ),&lt;br /&gt;
			shortdesc&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if self.smwData[ translate( &amp;#039;SMW_Grade&amp;#039; ) ] ~= nil then&lt;br /&gt;
		shortdesc = translate( &amp;#039;shortdesc_grade&amp;#039;, false, self.smwData[ translate( &amp;#039;SMW_Grade&amp;#039; ) ], shortdesc )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if self.smwData[ translate( &amp;#039;SMW_Size&amp;#039; ) ] ~= nil then&lt;br /&gt;
		shortdesc = string.format( &amp;#039;S%d %s&amp;#039;,&lt;br /&gt;
			self.smwData[ translate( &amp;#039;SMW_Size&amp;#039; ) ],&lt;br /&gt;
			shortdesc&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--- Manufacturer&lt;br /&gt;
	if self.smwData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ] ~= nil then&lt;br /&gt;
		local mfuname = self.smwData[ translate( &amp;#039;SMW_Manufacturer&amp;#039; ) ]&lt;br /&gt;
		local man = manufacturer( mfuname )&lt;br /&gt;
		--- Use short name if possible&lt;br /&gt;
		if man ~= nil and man.shortname ~= nil then mfuname = man.shortname end&lt;br /&gt;
&lt;br /&gt;
		shortdesc = translate( &amp;#039;shortdesc_manufactured_by&amp;#039;, false, shortdesc, mfuname )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--- Submodule override&lt;br /&gt;
	shortdesc = runModuleFN(&lt;br /&gt;
		self.smwData[ translate( &amp;#039;SMW_Type&amp;#039; ) ],&lt;br /&gt;
		&amp;#039;getShortDescription&amp;#039;,&lt;br /&gt;
		{ self.frameArgs, self.smwData },&lt;br /&gt;
		true&lt;br /&gt;
	) or shortdesc&lt;br /&gt;
&lt;br /&gt;
	if type( shortdesc ) == &amp;#039;string&amp;#039; and shortdesc ~= &amp;#039;&amp;#039; then&lt;br /&gt;
		shortdesc = lang:ucfirst( shortdesc )&lt;br /&gt;
		self.currentFrame:callParserFunction( &amp;#039;SHORTDESC&amp;#039;, shortdesc )&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Save Api Data to SMW store&lt;br /&gt;
function methodtable.saveApiData( self )&lt;br /&gt;
    self:getApiDataForCurrentPage()&lt;br /&gt;
    self:setSemanticProperties()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Generates debug output&lt;br /&gt;
function methodtable.makeDebugOutput( self )&lt;br /&gt;
	local debug = require( &amp;#039;Module:Common/Debug&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	self.smwData = nil&lt;br /&gt;
	local smwData = self:getSmwData()&lt;br /&gt;
&lt;br /&gt;
	local queryName = self.frameArgs[ translate( &amp;#039;ARG_SmwQueryName&amp;#039; ) ] or&lt;br /&gt;
					  self.frameArgs[ translate( &amp;#039;ARG_Name&amp;#039; ) ] or&lt;br /&gt;
					  mw.title.getCurrentTitle().fullText&lt;br /&gt;
&lt;br /&gt;
	return debug.collapsedDebugSections({&lt;br /&gt;
		{&lt;br /&gt;
			title = &amp;#039;SMW Query&amp;#039;,&lt;br /&gt;
			content = debug.convertSmwQueryObject( makeSmwQueryObject( queryName ) ),&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			title = &amp;#039;SMW Data&amp;#039;,&lt;br /&gt;
			content = smwData,&lt;br /&gt;
			tag = &amp;#039;pre&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			title = &amp;#039;Frame Args&amp;#039;,&lt;br /&gt;
			content = self.frameArgs,&lt;br /&gt;
			tag = &amp;#039;pre&amp;#039;,&lt;br /&gt;
		},&lt;br /&gt;
	})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Get the wikitext valid categories for this item&lt;br /&gt;
function methodtable.getCategories( self )&lt;br /&gt;
	local mapped = {}&lt;br /&gt;
&lt;br /&gt;
	for _, category in pairs( self.categories ) do&lt;br /&gt;
		if string.sub( category, 1, 2 ) ~= &amp;#039;[[&amp;#039; then&lt;br /&gt;
			category = string.format( &amp;#039;[[Category:%s]]&amp;#039;, category )&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		table.insert( mapped, category )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat( mapped )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- New Instance&lt;br /&gt;
function Item.new( self )&lt;br /&gt;
    local instance = {&lt;br /&gt;
        categories = {}&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    setmetatable( instance, metatable )&lt;br /&gt;
&lt;br /&gt;
    return instance&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Load data from api.star-citizen.wiki and save it to SMW&lt;br /&gt;
---&lt;br /&gt;
--- @param frame table Invocation frame&lt;br /&gt;
--- @return string|nil&lt;br /&gt;
function Item.loadApiData( frame )&lt;br /&gt;
	local instance = Item:new()&lt;br /&gt;
	instance:setFrame( frame )&lt;br /&gt;
	instance:saveApiData()&lt;br /&gt;
&lt;br /&gt;
	local debugOutput&lt;br /&gt;
	if instance.frameArgs[ &amp;#039;debug&amp;#039; ] ~= nil then&lt;br /&gt;
		local debug = require( &amp;#039;Module:Common/Debug&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
		debugOutput = debug.collapsedDebugSections({&lt;br /&gt;
			{&lt;br /&gt;
				title = &amp;#039;SMW Set Data&amp;#039;,&lt;br /&gt;
				content = mw.getCurrentFrame():callParserFunction( &amp;#039;#tag&amp;#039;, { &amp;#039;nowiki&amp;#039;, mw.dumpObject( instance.setData or {} ) } ),&lt;br /&gt;
			},&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return debugOutput&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Generates an infobox based on passed frame args and SMW data&lt;br /&gt;
---&lt;br /&gt;
--- @param frame table Invocation frame&lt;br /&gt;
--- @return string&lt;br /&gt;
function Item.infobox( frame )&lt;br /&gt;
	local instance = Item:new()&lt;br /&gt;
	instance:setFrame( frame )&lt;br /&gt;
&lt;br /&gt;
	local debugOutput = &amp;#039;&amp;#039;&lt;br /&gt;
	if instance.frameArgs[ &amp;#039;debug&amp;#039; ] ~= nil then&lt;br /&gt;
		debugOutput = instance:makeDebugOutput()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return tostring( instance:getInfobox() ) .. debugOutput&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- &amp;quot;Main&amp;quot; entry point for templates that saves the API Data and outputs the infobox&lt;br /&gt;
---&lt;br /&gt;
--- @param frame table Invocation frame&lt;br /&gt;
--- @return string&lt;br /&gt;
function Item.main( frame )&lt;br /&gt;
	local instance = Item:new()&lt;br /&gt;
	instance:setFrame( frame )&lt;br /&gt;
	instance:saveApiData()&lt;br /&gt;
&lt;br /&gt;
	local debugOutput = &amp;#039;&amp;#039;&lt;br /&gt;
	if instance.frameArgs[ &amp;#039;debug&amp;#039; ] ~= nil then&lt;br /&gt;
		debugOutput = instance:makeDebugOutput()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local infobox = tostring( instance:getInfobox() )&lt;br /&gt;
&lt;br /&gt;
	if instance.smwData ~= nil then&lt;br /&gt;
		instance:setCategories()&lt;br /&gt;
		instance:setShortDescription()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return infobox .. debugOutput .. instance:getCategories()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
function Item.test( page )&lt;br /&gt;
	page = page or &amp;#039;Cirrus&amp;#039;&lt;br /&gt;
&lt;br /&gt;
	local instance = Item:new()&lt;br /&gt;
	instance.frameArgs = {}&lt;br /&gt;
	instance.frameArgs[ translate( &amp;#039;ARG_Name&amp;#039; ) ] = page&lt;br /&gt;
&lt;br /&gt;
	instance:saveApiData()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return Item&lt;/div&gt;</summary>
		<author><name>Antt1995</name></author>
	</entry>
</feed>