since = false
if type( item ) == "number" and item > 0 then
local suited = string.format( "Q%d", item )
if link then
r = suited
else
local entity = mw.wikibase.getEntity( suited )
if type( entity ) == "table" then
local seek = Failsafe.serialProperty or "P348"
local vsn = entity:formatPropertyValues( seek )
if type( vsn ) == "table" and
type( vsn.value ) == "string" and
vsn.value ~= "" then
if last and vsn.value == Failsafe.serial then
r = false
elseif linked then
if mw.title.getCurrentTitle.prefixedText
== mw.wikibase.getSitelink( suited ) then
r = false
else
r = suited
end
else
r = vsn.value
end
end
end
end
end
end
if type( r ) == "nil" then
if not since or since <= Failsafe.serial then
r = Failsafe.serial
else
r = false
end
end
return r
end -- Failsafe.failsafe  
-- Provide external access
local p = {}  
function p.assert
-- Perform parameter analysis on some single string
-- Precondition:
-- -- object; #invoke environment
-- Postcondition:
-- Return string with error message or ""
-- Uses:
-- furnish
return furnish( , "assert" )
end -- p.assert  
function p.check
-- Check validity of template parameters
-- Precondition:
-- -- object; #invoke environment
-- Postcondition:
-- Return string with error message or ""
-- Uses:
-- form
-- fill
local options = { optional = { "all",
"opt",
"cat",
"errNS",
"low",
"format",
"preview",
"template" },
template = "&#35;invoke:TemplatePar|check|"
}
local r = form( false, options, )
if not r then
options = { mandatory = fill( .args.all ),
optional = fill( .args.opt ),
cat = .args.cat,
errNS = .args.errNS,
low = .args.low,
format = .args.format,
preview = .args.preview,
template = .args.template
}
r = form( true, options, )
end
return r or ""
end -- p.check  
function p.count
-- Count number of template parameters
-- Postcondition:
-- Return string with digits including "0"
-- Uses:
-- TemplatePar.count
return tostring( TemplatePar.count )
end -- p.count  
function p.countNotEmpty
-- Count number of template parameters which are not empty
-- Postcondition:
-- Return string with digits including "0"
-- Uses:
-- TemplatePar.countNotEmpty
return tostring( TemplatePar.countNotEmpty )
end -- p.countNotEmpty  
function p.match
-- Combined analysis of parameters and their values
-- Precondition:
-- -- object; #invoke environment
-- Postcondition:
-- Return string with error message or ""
-- Uses:
-- TemplatePar.framing
-- mw.text.trim
-- mw.ustring.lower
-- failure
-- form
-- TemplatePar.downcase
-- figure
-- feasible
-- fault
-- finalize
local r = false
local options = { cat = .args.cat,
errNS = .args.errNS,
low = .args.low,
format = .args.format,
preview = .args.preview,
template = .args.template
}
local k, v, s
local params = { }
TemplatePar.framing
for k, v in pairs( .args ) do
if type( k ) == "number" then
s, v = v:match( "^ *([^=]+) *= *(%S.*%S*) *$" )
if s then
s = mw.text.trim( s )
if s == "" then
s = false
end
end
if s then
if options.low then
s = mw.ustring.lower( s )
end
if params[ s ] then
s = params[ s ]
s[ #s + 1 ] = v
else
params[ s ] = { v }
end
else
r = failure( "invalidPar", tostring( k ), options )
break -- for k, v
end
end
end -- for k, v
if not r then
s = { }
for k, v in pairs( params ) do
s[ #s + 1 ] = k
end -- for k, v
options.optional = s
r = form( true, options, )
end
if not r then
local errMiss, errValues, lack, rule
local targs = :getParent.args
options.optional = nil
if options.low then
targs = TemplatePar.downcase
else
targs = :getParent.args
end
errMiss = false
errValues = false
for k, v in pairs( params ) do
options.say = k
s = targs[ k ]
if s then
if s == "" then
lack = true
else
lack = false
end
else
s = ""
lack = true
end
for r, rule in pairs( v ) do
options = figure( rule, options )
r = feasible( s, options, true )
if r then
if lack then
if errMiss then
s = "%s, &quot;%s&quot;"
errMiss = string.format( s, errMiss, k )
else
errMiss = string.format( "&quot;%s&quot;",
k )
end
elseif not errMiss then
errValues = fault( errValues, r )
end
break -- for r, rule
end
end -- for s, rule
end -- for k, v
r = ( errMiss or errValues )
if r then
if errMiss then
r = failure( "undefined", errMiss, options )
else
r = failure( "invalid", errValues, options )
end
r = finalize( r, options )
end
end
return r or ""
end -- p.match  
function p.valid
-- Check validity of one particular template parameter
-- Precondition:
-- -- object; #invoke environment
-- Postcondition:
-- Return string with error message or ""
-- Uses:
-- furnish
return furnish( , "valid" )
end -- p.valid  
p.failsafe = function
-- Versioning interface
local s = type
local since
if s == "table" then
since = .args[ 1 ]
elseif s == "string" then
since =
end
if since then
since = mw.text.trim( since )
if since == "" then
since = false
end
end
return Failsafe.failsafe( since ) or ""
end -- p.failsafe  
function p.TemplatePar
-- Retrieve function access for modules
-- Postcondition:
-- Return table with functions
return TemplatePar
end -- p.TemplatePar  
setmetatable( p, { __call = function ( func, ... )
setmetatable( p, nil )
return Failsafe
end } )  
return p