<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="rue">
	<id>https://wiki.kocky.cc/w/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3AVehicle</id>
	<title>Модуль:Vehicle - Історія едітовань</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.kocky.cc/w/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3AVehicle"/>
	<link rel="alternate" type="text/html" href="https://wiki.kocky.cc/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:Vehicle&amp;action=history"/>
	<updated>2026-04-04T21:13:27Z</updated>
	<subtitle>Історія едітовань той сторінкы на вікі</subtitle>
	<generator>MediaWiki 1.40.1</generator>
	<entry>
		<id>https://wiki.kocky.cc/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:Vehicle&amp;diff=82&amp;oldid=prev</id>
		<title>Бетярь: 1 ревізія: InfoboxNeue from StarCitizenTools</title>
		<link rel="alternate" type="text/html" href="https://wiki.kocky.cc/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:Vehicle&amp;diff=82&amp;oldid=prev"/>
		<updated>2023-10-17T23:55:16Z</updated>

		<summary type="html">&lt;p&gt;1 ревізія: InfoboxNeue from StarCitizenTools&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;rue&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Старша верзія&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Ревізія 01:55, 18 октовбра 2023&lt;/td&gt;
				&lt;/tr&gt;
&lt;!-- diff cache key wiki:diff::1.12:old-81:rev-82 --&gt;
&lt;/table&gt;</summary>
		<author><name>Бетярь</name></author>
	</entry>
	<entry>
		<id>https://wiki.kocky.cc/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:Vehicle&amp;diff=81&amp;oldid=prev</id>
		<title>starcitizen&gt;Alistair3149 в 20:35, 25 юлія 2023</title>
		<link rel="alternate" type="text/html" href="https://wiki.kocky.cc/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:Vehicle&amp;diff=81&amp;oldid=prev"/>
		<updated>2023-07-25T20:35:45Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Нова сторінка&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require( &amp;#039;strict&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
local Vehicle = {}&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:Vehicle/data.json&amp;#039; )&lt;br /&gt;
local config = mw.loadJsonData( &amp;#039;Module:Vehicle/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;
&lt;br /&gt;
--- Calls TNT with the given key&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:Vehicle/i18n.json&amp;#039;, config, key, addSuffix, {...} ) or key&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Check if the current vehicle is a ground vehicle&lt;br /&gt;
---&lt;br /&gt;
--- @param smwData table&lt;br /&gt;
--- @return boolean&lt;br /&gt;
local function isGroundVehicle( smwData )&lt;br /&gt;
	local size = smwData[ translate( &amp;#039;SMW_ShipMatrixSize&amp;#039; ) ]&lt;br /&gt;
&lt;br /&gt;
	return ( size ~= nil and size == translate( &amp;#039;Vehicle&amp;#039; ) ) or smwData[ translate( &amp;#039;SMW_ReverseSpeed&amp;#039; ) ] ~= nil&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 vehicle page containing data&lt;br /&gt;
--- @return table&lt;br /&gt;
local function makeSmwQueryObject( page )&lt;br /&gt;
    local langSuffix = &amp;#039;&amp;#039;&lt;br /&gt;
    if config.smw_multilingual_text == true then&lt;br /&gt;
        langSuffix = &amp;#039;+lang=&amp;#039; .. ( config.module_lang or mw.getContentLanguage():getCode() )&lt;br /&gt;
    end&lt;br /&gt;
&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;
	for _, queryPart in pairs( data.smw_data ) do&lt;br /&gt;
		local smwKey&lt;br /&gt;
		for key, _ in pairs( queryPart ) do&lt;br /&gt;
			if string.sub( key, 1, 3 ) == &amp;#039;SMW&amp;#039; then&lt;br /&gt;
				smwKey = key&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local formatString = &amp;#039;?%s&amp;#039;&lt;br /&gt;
&lt;br /&gt;
		if queryPart.smw_format then&lt;br /&gt;
			formatString = formatString .. queryPart.smw_format&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- safeguard&lt;br /&gt;
		if smwKey ~= nil then&lt;br /&gt;
			table.insert( query, string.format( formatString, translate( smwKey ) ) )&lt;br /&gt;
&lt;br /&gt;
			if queryPart.type == &amp;#039;multilingual_text&amp;#039; then&lt;br /&gt;
				table.insert( query, langSuffix )&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&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;
--- FIXME: This should go to somewhere else, like Module:Common&lt;br /&gt;
local function makeTimeReadable( t )&lt;br /&gt;
	if t == nil then return end&lt;br /&gt;
&lt;br /&gt;
	-- Fix for german number format&lt;br /&gt;
	if string.find( t, &amp;#039;,&amp;#039;, 1, true ) then&lt;br /&gt;
		t = string.gsub( t, &amp;#039;,&amp;#039;, &amp;#039;.&amp;#039; )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if type( t ) == &amp;#039;string&amp;#039; then&lt;br /&gt;
		t = tonumber( t, 10 )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	t = lang:formatDuration( t * 60 )&lt;br /&gt;
&lt;br /&gt;
	local regex&lt;br /&gt;
	if lang:getCode() == &amp;#039;de&amp;#039; then&lt;br /&gt;
		regex = {&lt;br /&gt;
			[ &amp;#039;%s?[Tt]agen?&amp;#039; ] = &amp;#039;d&amp;#039;,&lt;br /&gt;
			[ &amp;#039;%s?[Ss]tunden?&amp;#039; ] = &amp;#039;h&amp;#039;,&lt;br /&gt;
			[ &amp;#039;%s?[Mm]inuten?&amp;#039; ] = &amp;#039;m&amp;#039;,&lt;br /&gt;
			[ &amp;#039;%s?[Ss]ekunden?&amp;#039; ] = &amp;#039;s&amp;#039;,&lt;br /&gt;
			[ &amp;#039;,&amp;#039;] = &amp;#039;&amp;#039;,&lt;br /&gt;
			[ &amp;#039;und%s&amp;#039;] = &amp;#039;&amp;#039;&lt;br /&gt;
		}&lt;br /&gt;
	else&lt;br /&gt;
		regex = {&lt;br /&gt;
			[ &amp;#039;%sdays*&amp;#039; ] = &amp;#039;d&amp;#039;,&lt;br /&gt;
			[ &amp;#039;%shours*&amp;#039; ] = &amp;#039;h&amp;#039;,&lt;br /&gt;
			[ &amp;#039;%sminutes*&amp;#039; ] = &amp;#039;m&amp;#039;,&lt;br /&gt;
			[ &amp;#039;%sseconds*&amp;#039; ] = &amp;#039;s&amp;#039;,&lt;br /&gt;
			[ &amp;#039;,&amp;#039;] = &amp;#039;&amp;#039;,&lt;br /&gt;
			[ &amp;#039;and%s&amp;#039;] = &amp;#039;&amp;#039;&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for pattern, replace in pairs( regex ) do&lt;br /&gt;
		t = string.gsub( t, pattern, replace )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- FIXME: This should go to somewhere else, like Module:Common&lt;br /&gt;
--- TODO: Should we color code this for buff and debuff?&lt;br /&gt;
local function formatModifier( x )&lt;br /&gt;
	if x == nil then return end&lt;br /&gt;
	-- Fix for german number format&lt;br /&gt;
	if string.find( x, &amp;#039;,&amp;#039;, 1, true ) then&lt;br /&gt;
		x = string.gsub( x, &amp;#039;,&amp;#039;, &amp;#039;.&amp;#039; )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if type( x ) == &amp;#039;string&amp;#039; then x = tonumber( x, 10 ) end&lt;br /&gt;
&lt;br /&gt;
	local diff = x - 1&lt;br /&gt;
	local sign = &amp;#039;&amp;#039;&lt;br /&gt;
	if diff == 0 then&lt;br /&gt;
		--- Display &amp;#039;None&amp;#039; instead of 0 % for better readability&lt;br /&gt;
		return translate( &amp;#039;none&amp;#039; )&lt;br /&gt;
	elseif diff &amp;gt; 0 then&lt;br /&gt;
		--- Extra space for formatting&lt;br /&gt;
		sign = &amp;#039;+ &amp;#039;&lt;br /&gt;
	elseif diff &amp;lt; 0 then&lt;br /&gt;
		sign = &amp;#039;- &amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	return sign .. tostring( math.abs( diff ) * 100 ) .. &amp;#039; %&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Request Api Data&lt;br /&gt;
--- Using current subpage name without vehicle 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/vehicles/&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 Vehicles&lt;br /&gt;
--- @return table SMW Result&lt;br /&gt;
function methodtable.setSemanticProperties( self )&lt;br /&gt;
	local setData = {}&lt;br /&gt;
	local loanerKey = translate( &amp;#039;SMW_LoanerVehicle&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
	--- Retrieve value(s) from the frame&lt;br /&gt;
	---&lt;br /&gt;
	--- @param datum table An entry from data.smw_data&lt;br /&gt;
	--- @param argKey string The key to use as an accessor to frameArgs&lt;br /&gt;
	--- @return string|number|table|nil&lt;br /&gt;
	local function getFromArgs( datum, argKey )&lt;br /&gt;
		local value&lt;br /&gt;
		-- Numbered parameters, e.g. URL1, URL2, URL3, etc.&lt;br /&gt;
		if datum.type == &amp;#039;range&amp;#039; and type( datum.max ) == &amp;#039;number&amp;#039; then&lt;br /&gt;
			value = {}&lt;br /&gt;
&lt;br /&gt;
			for i = 1, datum.max do&lt;br /&gt;
				local argValue = self.frameArgs[ argKey .. i ]&lt;br /&gt;
				if argValue then table.insert( value, argValue ) end&lt;br /&gt;
			end&lt;br /&gt;
		-- A &amp;quot;simple&amp;quot; arg&lt;br /&gt;
		else&lt;br /&gt;
			value = self.frameArgs[ argKey ]&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return value&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Iterate through the list of SMW attributes that shall be filled&lt;br /&gt;
	for _, datum in ipairs( data.smw_data ) do&lt;br /&gt;
		-- Retrieve the SMW key and from where the data should be pulled&lt;br /&gt;
		local smwKey, from&lt;br /&gt;
		for key, get_from in pairs( datum ) do&lt;br /&gt;
			if string.sub( key, 1, 3 ) == &amp;#039;SMW&amp;#039; then&lt;br /&gt;
				smwKey = key&lt;br /&gt;
				from = get_from&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		smwKey = translate( smwKey )&lt;br /&gt;
&lt;br /&gt;
		if type( from ) ~= &amp;#039;table&amp;#039; then&lt;br /&gt;
			from = { from }&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Iterate the list of data sources in order, later sources override previous ones&lt;br /&gt;
		-- I.e. if the list is Frame Args, API; The api will override possible values set from the frame&lt;br /&gt;
		for _, key in ipairs( from ) do&lt;br /&gt;
			local parts = mw.text.split( key, &amp;#039;_&amp;#039;, true )&lt;br /&gt;
			local value&lt;br /&gt;
&lt;br /&gt;
			-- Re-assemble keys with multiple &amp;#039;_&amp;#039;&lt;br /&gt;
			if #parts &amp;gt; 2 then&lt;br /&gt;
				local tmp = parts[ 1 ]&lt;br /&gt;
				table.remove( parts, 1 )&lt;br /&gt;
				parts = {&lt;br /&gt;
					tmp,&lt;br /&gt;
					table.concat( parts, &amp;#039;_&amp;#039; )&lt;br /&gt;
				}&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			mw.logObject( parts, &amp;#039;Key Parts&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
			-- safeguard check if we have two parts&lt;br /&gt;
			if #parts == 2 then&lt;br /&gt;
				-- Retrieve data from frameArgs&lt;br /&gt;
				if parts[ 1 ] == &amp;#039;ARG&amp;#039; then&lt;br /&gt;
					value = getFromArgs( datum, translate( key ) )&lt;br /&gt;
&lt;br /&gt;
					-- Use EN lang as fallback for arg names that are empty&lt;br /&gt;
					if value == nil then&lt;br /&gt;
						local success, translation = pcall( TNT.formatInLanguage, &amp;#039;en&amp;#039;, &amp;#039;Module:Vehicle/i18n.json&amp;#039;, key )&lt;br /&gt;
						if success then&lt;br /&gt;
							value = getFromArgs( datum, translation )&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				-- Retrieve data from API&lt;br /&gt;
				elseif parts[ 1 ] == &amp;#039;API&amp;#039; and self.apiData ~= nil then&lt;br /&gt;
					mw.logObject({&lt;br /&gt;
						key_access = parts[2],&lt;br /&gt;
						value = self.apiData:get( parts[ 2 ] )&lt;br /&gt;
					})&lt;br /&gt;
&lt;br /&gt;
					value = self.apiData:get( parts[ 2 ] )&lt;br /&gt;
&lt;br /&gt;
					if smwKey == loanerKey and type( value ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
						local tmp = {}&lt;br /&gt;
						for _, loaner in ipairs( value ) do&lt;br /&gt;
							table.insert( tmp, loaner.name )&lt;br /&gt;
						end&lt;br /&gt;
						value = tmp&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- Transform value based on &amp;#039;format&amp;#039; key&lt;br /&gt;
			if value ~= nil then&lt;br /&gt;
				if type( value ) ~= &amp;#039;table&amp;#039; then&lt;br /&gt;
					value = { value }&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				for index, val in ipairs( value ) do&lt;br /&gt;
					-- This should not happen&lt;br /&gt;
					if type( val ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
						val = string.format( &amp;#039;!ERROR! Key %s is a table value; please fix&amp;#039;, key )&lt;br /&gt;
					end&lt;br /&gt;
&lt;br /&gt;
					-- Format number for SMW&lt;br /&gt;
					if datum.type == &amp;#039;number&amp;#039; then&lt;br /&gt;
						val = common.formatNum( val )&lt;br /&gt;
					-- Multilingual Text, add a suffix&lt;br /&gt;
					elseif datum.type == &amp;#039;multilingual_text&amp;#039; and config.smw_multilingual_text == true then&lt;br /&gt;
						val = string.format( &amp;#039;%s@%s&amp;#039;, val, config.module_lang or mw.getContentLanguage():getCode() )&lt;br /&gt;
					-- Num format&lt;br /&gt;
					elseif datum.type == &amp;#039;number&amp;#039; then&lt;br /&gt;
						val = common.formatNum( val )&lt;br /&gt;
					-- String format&lt;br /&gt;
					elseif type( datum.format ) == &amp;#039;string&amp;#039; then&lt;br /&gt;
						if string.find( datum.format, &amp;#039;%&amp;#039;, 1, true  ) then&lt;br /&gt;
							val = string.format( datum.format, val )&lt;br /&gt;
						elseif datum.format == &amp;#039;ucfirst&amp;#039; then&lt;br /&gt;
							val = lang:ucfirst( val )&lt;br /&gt;
						elseif datum.format == &amp;#039;replace-dash&amp;#039; then&lt;br /&gt;
							val = string.gsub( val, &amp;#039;%-&amp;#039;, &amp;#039; &amp;#039; )&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
&lt;br /&gt;
					table.remove( value, index )&lt;br /&gt;
					table.insert( value, index, val )&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				if type( value ) == &amp;#039;table&amp;#039; and #value == 1 then&lt;br /&gt;
					value = value[ 1 ]&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				setData[ smwKey ] = value&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&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 then&lt;br /&gt;
		-- Flight ready vehicles&lt;br /&gt;
		--- Override template parameter with in-game data&lt;br /&gt;
		if self.apiData.uuid ~= nil then&lt;br /&gt;
			--- Components&lt;br /&gt;
			if self.apiData.hardpoints ~= nil and type( self.apiData.hardpoints ) == &amp;#039;table&amp;#039; and #self.apiData.hardpoints &amp;gt; 0 then&lt;br /&gt;
				local hardpoint = require( &amp;#039;Module:VehicleHardpoint&amp;#039; ):new( self.frameArgs[ translate( &amp;#039;ARG_name&amp;#039; ) ] or mw.title.getCurrentTitle().fullText )&lt;br /&gt;
				hardpoint:setHardPointObjects( self.apiData.hardpoints )&lt;br /&gt;
				hardpoint:setParts( self.apiData.parts )&lt;br /&gt;
&lt;br /&gt;
				if not self.apiData.hardpoints and type( self.apiData.components ) == &amp;#039;table&amp;#039; and #self.apiData.components &amp;gt; 0 then&lt;br /&gt;
					hardpoint:setComponents( self.apiData.components )&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&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;
		end&lt;br /&gt;
	end&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;
					  self.frameArgs[ translate( &amp;#039;ARG_Name&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 getIndicatorClass()&lt;br /&gt;
		local state = smwData[ translate( &amp;#039;SMW_ProductionState&amp;#039; ) ]&lt;br /&gt;
		if state == nil then return end&lt;br /&gt;
&lt;br /&gt;
		local classMap = config.productionstate_map&lt;br /&gt;
&lt;br /&gt;
		for _, map in pairs( classMap ) do&lt;br /&gt;
			if string.match( state, translate( map.name ) ) ~= nil then&lt;br /&gt;
				return &amp;#039;infobox__indicator--&amp;#039; .. map.color&lt;br /&gt;
			end&lt;br /&gt;
		end&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 smwData[ translate( &amp;#039;SMW_Manufacturer&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 getSize()&lt;br /&gt;
		if smwData[ translate( &amp;#039;SMW_Size&amp;#039; ) ] == nil then return smwData[ translate( &amp;#039;SMW_ShipMatrixSize&amp;#039; ) ] end&lt;br /&gt;
&lt;br /&gt;
		local codes = { &amp;#039;XXS&amp;#039;, &amp;#039;XS&amp;#039;, &amp;#039;S&amp;#039;, &amp;#039;M&amp;#039;, &amp;#039;L&amp;#039;, &amp;#039;XL&amp;#039; }&lt;br /&gt;
		local size = smwData[ translate( &amp;#039;SMW_Size&amp;#039; ) ]&lt;br /&gt;
&lt;br /&gt;
		-- For uninitialized SMW properties&lt;br /&gt;
		if type( size ) == &amp;#039;string&amp;#039; then&lt;br /&gt;
			size = tonumber( size, 10 )&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return infobox.showDescIfDiff(&lt;br /&gt;
			smwData[ translate( &amp;#039;SMW_ShipMatrixSize&amp;#039; ) ],&lt;br /&gt;
			table.concat( { &amp;#039;S&amp;#039;, size, &amp;#039;/&amp;#039;, codes[ size ] } )&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function getSeries()&lt;br /&gt;
		local series = smwData[ translate( &amp;#039;SMW_Series&amp;#039; ) ]&lt;br /&gt;
		if series == nil then return end&lt;br /&gt;
		return string.format(&lt;br /&gt;
			&amp;#039;[[:Category:%s|%s]]&amp;#039;,&lt;br /&gt;
			translate( &amp;#039;category_series&amp;#039;, false, series ),&lt;br /&gt;
			series&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--- Cost section&lt;br /&gt;
	local function getCostSection()&lt;br /&gt;
		local tabberData = {}&lt;br /&gt;
		local section&lt;br /&gt;
&lt;br /&gt;
		tabberData[ &amp;#039;label1&amp;#039; ] = translate( &amp;#039;LBL_Pledge&amp;#039; )&lt;br /&gt;
		section = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Standalone&amp;#039; ),&lt;br /&gt;
				data = infobox.showDescIfDiff( smwData[ translate( &amp;#039;SMW_PledgePrice&amp;#039; ) ], smwData[ translate( &amp;#039;SMW_OriginalPledgePrice&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Warbond&amp;#039; ),&lt;br /&gt;
				data = infobox.showDescIfDiff( smwData[ translate( &amp;#039;SMW_WarbondPledgePrice&amp;#039; ) ], smwData[ translate( &amp;#039;SMW_OriginalWarbondPledgePrice&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Availability&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_PledgeAvailability&amp;#039; ) ],&lt;br /&gt;
			} ),&lt;br /&gt;
		}&lt;br /&gt;
		tabberData[ &amp;#039;content1&amp;#039; ] = infobox:renderSection( { content = section, col = 2 }, true )&lt;br /&gt;
&lt;br /&gt;
		tabberData[ &amp;#039;label2&amp;#039; ] = translate( &amp;#039;LBL_Insurance&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
		section = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Claim&amp;#039; ),&lt;br /&gt;
				data = makeTimeReadable( smwData[ translate(&amp;#039;SMW_InsuranceClaimTime&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Expedite&amp;#039; ),&lt;br /&gt;
				data = makeTimeReadable( smwData[ translate(&amp;#039;SMW_InsuranceExpediteTime&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_ExpediteFee&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate(&amp;#039;SMW_InsuranceExpediteCost&amp;#039; ) ],&lt;br /&gt;
				colspan = 2&lt;br /&gt;
			} ),&lt;br /&gt;
		}&lt;br /&gt;
		tabberData[ &amp;#039;content2&amp;#039; ] = infobox:renderSection( { content = section, col = 4 }, true )&lt;br /&gt;
&lt;br /&gt;
		--- TODO: Move this back up to the first tab when we fix universe cost&lt;br /&gt;
		section = {}&lt;br /&gt;
&lt;br /&gt;
		--- Show message on where the game price data are&lt;br /&gt;
		if smwData[ &amp;#039;UUID&amp;#039; ] ~= nil then&lt;br /&gt;
			tabberData[ &amp;#039;label3&amp;#039; ] = translate( &amp;#039;LBL_Universe&amp;#039; )&lt;br /&gt;
			tabberData[ &amp;#039;content3&amp;#039; ] = infobox:renderMessage( {&lt;br /&gt;
				title = translate( &amp;#039;msg_ingame_prices_title&amp;#039; ),&lt;br /&gt;
				desc = translate( &amp;#039;msg_ingame_prices_content&amp;#039; )&lt;br /&gt;
			}, true )&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return tabber( tabberData )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--- Specifications section&lt;br /&gt;
	local function getSpecificationsSection()&lt;br /&gt;
		local tabberData = {}&lt;br /&gt;
		local section&lt;br /&gt;
&lt;br /&gt;
		tabberData[ &amp;#039;label1&amp;#039; ] = translate( &amp;#039;LBL_Dimensions&amp;#039; )&lt;br /&gt;
		section = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Length&amp;#039; ),&lt;br /&gt;
				data = infobox.showDescIfDiff( smwData[ translate( &amp;#039;SMW_EntityLength&amp;#039; ) ], smwData[ translate( &amp;#039;SMW_RetractedLength&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 = infobox.showDescIfDiff( smwData[ translate( &amp;#039;SMW_EntityWidth&amp;#039; ) ], smwData[ translate( &amp;#039;SMW_RetractedWidth&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 = infobox.showDescIfDiff( smwData[ translate( &amp;#039;SMW_EntityHeight&amp;#039; ) ], smwData[ translate( &amp;#039;SMW_RetractedHeight&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;
&lt;br /&gt;
		tabberData[ &amp;#039;content1&amp;#039; ] = infobox:renderSection( { content =section, col = 3 }, true )&lt;br /&gt;
&lt;br /&gt;
		tabberData[ &amp;#039;label2&amp;#039; ] = translate( &amp;#039;LBL_Speed&amp;#039; )&lt;br /&gt;
		section = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_ScmSpeed&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_ScmSpeed&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_0ToScm&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_ZeroToScmSpeedTime&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_ScmTo0&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_ScmSpeedToZeroTime&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_MaxSpeed&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_MaximumSpeed&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_0ToMax&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_ZeroToMaximumSpeedTime&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_MaxTo0&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_MaximumSpeedToZeroTime&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_ReverseSpeed&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_ReverseSpeed&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_RollRate&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_RollRate&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_PitchRate&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_PitchRate&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_YawRate&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_YawRate&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
		}&lt;br /&gt;
		tabberData[ &amp;#039;content2&amp;#039; ] = infobox:renderSection( { content = section, col = 3 }, true )&lt;br /&gt;
&lt;br /&gt;
		tabberData[ &amp;#039;label3&amp;#039; ] = translate( &amp;#039;LBL_Fuel&amp;#039; )&lt;br /&gt;
		section = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_HydrogenCapacity&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_HydrogenFuelCapacity&amp;#039; ) ],&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_HydrogenIntake&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_HydrogenFuelIntakeRate&amp;#039; ) ],&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_QuantumCapacity&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_QuantumFuelCapacity&amp;#039; ) ],&lt;br /&gt;
			} ),&lt;br /&gt;
		}&lt;br /&gt;
		tabberData[ &amp;#039;content3&amp;#039; ] = infobox:renderSection( { content = section, col = 2 }, true )&lt;br /&gt;
&lt;br /&gt;
		tabberData[ &amp;#039;label4&amp;#039; ] = translate( &amp;#039;LBL_Hull&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
		section = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_CrossSection&amp;#039; ),&lt;br /&gt;
				data = formatModifier( smwData[ translate( &amp;#039;SMW_CrossSectionSignatureModifier&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Electromagnetic&amp;#039; ),&lt;br /&gt;
				data = formatModifier( smwData[ translate( &amp;#039;SMW_ElectromagneticSignatureModifier&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Infrared&amp;#039; ),&lt;br /&gt;
				data = formatModifier( smwData[ translate( &amp;#039;SMW_InfraredSignatureModifier&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Physical&amp;#039; ),&lt;br /&gt;
				data = formatModifier( smwData[ translate( &amp;#039;SMW_PhysicalDamageModifier&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Energy&amp;#039; ),&lt;br /&gt;
				data = formatModifier( smwData[ translate( &amp;#039;SMW_EnergyDamageModifier&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Distortion&amp;#039; ),&lt;br /&gt;
				data = formatModifier( smwData[ translate( &amp;#039;SMW_DistortionDamageModifier&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Thermal&amp;#039; ),&lt;br /&gt;
				data = formatModifier( smwData[ translate( &amp;#039;SMW_ThermalDamageModifier&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Biochemical&amp;#039; ),&lt;br /&gt;
				data = formatModifier( smwData[ translate( &amp;#039;SMW_BiochemicalDamageModifier&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Stun&amp;#039; ),&lt;br /&gt;
				data = formatModifier( smwData[ translate( &amp;#039;SMW_StunDamageModifier&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Health&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_HealthPoint&amp;#039; ) ],&lt;br /&gt;
			} ),&lt;br /&gt;
		}&lt;br /&gt;
		tabberData[ &amp;#039;content4&amp;#039; ] = infobox:renderSection( { content = section, col = 3 }, true )&lt;br /&gt;
&lt;br /&gt;
		return tabber( tabberData )&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:renderIndicator( {&lt;br /&gt;
		data = smwData[ translate( &amp;#039;SMW_ProductionState&amp;#039; ) ],&lt;br /&gt;
		desc = smwData[ translate( &amp;#039;SMW_ProductionStateDesc&amp;#039; ) ],&lt;br /&gt;
		class = getIndicatorClass()&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;
	} )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--- Role, Size, Series and Loaners&lt;br /&gt;
	infobox:renderSection( {&lt;br /&gt;
		content = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Role&amp;#039; ),&lt;br /&gt;
				data = infobox.tableToCommaList( smwData[ translate( &amp;#039;SMW_Role&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Size&amp;#039; ),&lt;br /&gt;
				data = getSize(),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Series&amp;#039; ),&lt;br /&gt;
				data = getSeries(),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Loaner&amp;#039; ),&lt;br /&gt;
				data = infobox.tableToCommaList( smwData[ translate( &amp;#039;SMW_LoanerVehicle&amp;#039; ) ] ),&lt;br /&gt;
			} ),&lt;br /&gt;
		},&lt;br /&gt;
		col = 2&lt;br /&gt;
	} )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--- Capacity&lt;br /&gt;
	infobox:renderSection( {&lt;br /&gt;
		title = translate( &amp;#039;LBL_Capacity&amp;#039; ),&lt;br /&gt;
		col = 3,&lt;br /&gt;
		content = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Crew&amp;#039; ),&lt;br /&gt;
				data = infobox.formatRange( smwData[ translate( &amp;#039;SMW_MinimumCrew&amp;#039; ) ], smwData[ translate( &amp;#039;SMW_MaximumCrew&amp;#039; ) ], true ),&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Cargo&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_CargoCapacity&amp;#039; ) ],&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Stowage&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_VehicleInventory&amp;#039; ) ],&lt;br /&gt;
			} ),&lt;br /&gt;
		},&lt;br /&gt;
	} )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--- Cost&lt;br /&gt;
	infobox:renderSection( {&lt;br /&gt;
		title = translate( &amp;#039;LBL_Cost&amp;#039; ),&lt;br /&gt;
		class = &amp;#039;infobox__section--tabber&amp;#039;,&lt;br /&gt;
		content = getCostSection(),&lt;br /&gt;
	} )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--- Specifications&lt;br /&gt;
	infobox:renderSection( {&lt;br /&gt;
		title = translate( &amp;#039;LBL_Specifications&amp;#039; ),&lt;br /&gt;
	 	class = &amp;#039;infobox__section--tabber&amp;#039;,&lt;br /&gt;
		content = getSpecificationsSection(),&lt;br /&gt;
	} )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--- Lore section&lt;br /&gt;
	infobox:renderSection( {&lt;br /&gt;
		title = translate( &amp;#039;LBL_Lore&amp;#039; ),&lt;br /&gt;
		col = 2,&lt;br /&gt;
		content = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Released&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_LoreReleaseDate&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Retired&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_LoreRetirementDate&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
		},&lt;br /&gt;
	} )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--- Development section&lt;br /&gt;
	infobox:renderSection( {&lt;br /&gt;
		title = translate( &amp;#039;LBL_Development&amp;#039; ),&lt;br /&gt;
		col = 2,&lt;br /&gt;
		content = {&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_Announced&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_ConceptAnnouncementDate&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
			infobox:renderItem( {&lt;br /&gt;
				label = translate( &amp;#039;LBL_ConceptSale&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_ConceptSaleDate&amp;#039; ) ]&lt;br /&gt;
			} ),&lt;br /&gt;
		},&lt;br /&gt;
	} )&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_ClassName&amp;#039; ),&lt;br /&gt;
				data = smwData[ translate( &amp;#039;SMW_ClassName&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;
	local size = self.smwData[ translate( &amp;#039;SMW_ShipMatrixSize&amp;#039; ) ]&lt;br /&gt;
	local size_cat, pledge_cat&lt;br /&gt;
	local isGroundVehicle = isGroundVehicle( self.smwData )&lt;br /&gt;
&lt;br /&gt;
	if isGroundVehicle then&lt;br /&gt;
		--Ground vehicle has no ship matrix size currently&lt;br /&gt;
		--size_cat = &amp;#039;category_ground_vehicle_size&amp;#039;&lt;br /&gt;
		pledge_cat = &amp;#039;category_ground_vehicle_pledge&amp;#039;&lt;br /&gt;
		table.insert(&lt;br /&gt;
			self.categories,&lt;br /&gt;
			string.format( &amp;#039;[[Category:%s]]&amp;#039;, translate( &amp;#039;category_ground_vehicle&amp;#039; ) )&lt;br /&gt;
		)&lt;br /&gt;
	else&lt;br /&gt;
		size_cat = &amp;#039;category_ship_size&amp;#039;&lt;br /&gt;
		pledge_cat = &amp;#039;category_ship_pledge&amp;#039;&lt;br /&gt;
		table.insert(&lt;br /&gt;
			self.categories,&lt;br /&gt;
			string.format( &amp;#039;[[Category:%s]]&amp;#039;, translate( &amp;#039;category_ship&amp;#039; ) )&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if size ~= nil and size_cat then&lt;br /&gt;
		table.insert(&lt;br /&gt;
			self.categories,&lt;br /&gt;
			string.format( &amp;#039;[[Category:%s]]&amp;#039;, translate( size_cat, false, size ) )&lt;br /&gt;
		)&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(&lt;br /&gt;
			self.categories,&lt;br /&gt;
			string.format( &amp;#039;[[Category:%s]]&amp;#039;, manufacturer )&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if self.smwData[ translate( &amp;#039;SMW_ProductionState&amp;#039; ) ] ~= nil then&lt;br /&gt;
		table.insert(&lt;br /&gt;
			self.categories,&lt;br /&gt;
			string.format( &amp;#039;[[Category:%s]]&amp;#039;, self.smwData[ translate( &amp;#039;SMW_ProductionState&amp;#039; ) ] )&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if self.smwData[ translate( &amp;#039;SMW_Series&amp;#039; ) ] ~= nil then&lt;br /&gt;
		table.insert(&lt;br /&gt;
			self.categories,&lt;br /&gt;
			string.format( &amp;#039;[[Category:%s]]&amp;#039;, translate( &amp;#039;category_series&amp;#039;, false, self.smwData[ translate( &amp;#039;SMW_Series&amp;#039; ) ] ) )&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if pledge_cat and self.smwData[ translate( &amp;#039;SMW_PledgePrice&amp;#039; ) ] ~= nil then&lt;br /&gt;
		table.insert(&lt;br /&gt;
			self.categories,&lt;br /&gt;
			string.format( &amp;#039;[[Category:%s]]&amp;#039;, translate( pledge_cat ) )&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
end&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&lt;br /&gt;
	local vehicleType&lt;br /&gt;
	local isGroundVehicle = isGroundVehicle( self.smwData )&lt;br /&gt;
&lt;br /&gt;
	if isGroundVehicle then&lt;br /&gt;
		vehicleType = translate( &amp;#039;shortdesc_ground_vehicle&amp;#039; )&lt;br /&gt;
	else&lt;br /&gt;
		vehicleType = translate( &amp;#039;shortdesc_ship&amp;#039; )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if self.smwData[ translate( &amp;#039;SMW_Role&amp;#039; ) ] ~= nil then&lt;br /&gt;
		local vehicleRole = self.smwData[ translate( &amp;#039;SMW_Role&amp;#039; ) ]&lt;br /&gt;
		if type( vehicleRole ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
			vehicleRole = table.concat( vehicleRole, &amp;#039; &amp;#039; )&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		vehicleRole = string.lower( vehicleRole )&lt;br /&gt;
		&lt;br /&gt;
		for _, noun in pairs( config.role_suffixes ) do&lt;br /&gt;
			local match = string.find( vehicleRole, &amp;#039;%f[%a]&amp;#039; .. noun .. &amp;#039;%f[%A]&amp;#039; )&lt;br /&gt;
			--- Remove suffix from role&lt;br /&gt;
			if match then&lt;br /&gt;
				vehicleRole = mw.text.trim( string.gsub( vehicleRole, noun, &amp;#039;&amp;#039; ) )&lt;br /&gt;
				vehicleType = noun&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		shortdesc = string.format( &amp;#039;%s %s&amp;#039;, vehicleRole, vehicleType )&lt;br /&gt;
	else&lt;br /&gt;
		shortdesc = vehicleType&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not isGroundVehicle and self.smwData[ translate( &amp;#039;SMW_ShipMatrixSize&amp;#039; ) ] ~= nil then&lt;br /&gt;
		local vehicleSize = self.smwData[ translate( &amp;#039;SMW_ShipMatrixSize&amp;#039; ) ]&lt;br /&gt;
		--- Special handling for single-seat ship&lt;br /&gt;
		if self.smwData[ translate( &amp;#039;SMW_MaximumCrew&amp;#039; ) ] ~= nil and self.smwData[ translate( &amp;#039;SMW_MaximumCrew&amp;#039; ) ] == 1 then&lt;br /&gt;
			vehicleSize = translate( &amp;#039;shortdesc_single_seat&amp;#039; )&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		shortdesc = string.format( &amp;#039;%s %s&amp;#039;, vehicleSize, shortdesc )&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 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;
	shortdesc = lang:ucfirst( shortdesc )&lt;br /&gt;
&lt;br /&gt;
	self.currentFrame:callParserFunction( &amp;#039;SHORTDESC&amp;#039;, shortdesc )&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;
--- New Instance&lt;br /&gt;
function Vehicle.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 Vehicle.loadApiData( frame )&lt;br /&gt;
	local instance = Vehicle: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 Vehicle.infobox( frame )&lt;br /&gt;
	local instance = Vehicle: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 Vehicle.main( frame )&lt;br /&gt;
	local instance = Vehicle: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;
	-- Only set categories and short desc if this is the page that also holds the smw attributes&lt;br /&gt;
	-- Allows outputting vehicle infoboxes on other pages without setting categories&lt;br /&gt;
	if instance.smwData ~= nil then&lt;br /&gt;
		instance:setCategories()&lt;br /&gt;
		instance:setShortDescription()&lt;br /&gt;
		-- FIXME: Is there a cleaner way?&lt;br /&gt;
		infobox = infobox .. common.generateInterWikiLinks( mw.title.getCurrentTitle().rootText )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return infobox .. debugOutput .. table.concat( instance.categories )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
function Vehicle.test( page )&lt;br /&gt;
	page = page or &amp;#039;300i&amp;#039;&lt;br /&gt;
&lt;br /&gt;
	local instance = Vehicle: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 Vehicle&lt;/div&gt;</summary>
		<author><name>starcitizen&gt;Alistair3149</name></author>
	</entry>
</feed>