end  
strFormat = "%." .. numDigits .. "f"  
if precision >= 1 then
latDegrees = strFormat:format(latitude)
lonDegrees = strFormat:format(longitude)  
if not raw then
latDegSym = replaceDecimalMark(latDegrees) .. degSymbol
lonDegSym = replaceDecimalMark(lonDegrees) .. degSymbol
else
latDegSym = latDegrees .. degSymbol
lonDegSym = lonDegrees .. degSymbol
end
else
latConv = math.floor(latitude * unitsPerDegree * 10^numDigits + 0.5) / 10^numDigits
lonConv = math.floor(longitude * unitsPerDegree * 10^numDigits + 0.5) / 10^numDigits  
if precision >= (1 / 60) then
latMinutes = latConv
lonMinutes = lonConv
else
latSeconds = latConv
lonSeconds = lonConv  
latMinutes = math.floor(latSeconds / 60)
lonMinutes = math.floor(lonSeconds / 60)  
latSeconds = strFormat:format(latSeconds - (latMinutes * 60))
lonSeconds = strFormat:format(lonSeconds - (lonMinutes * 60))  
if not raw then
latSecSym = replaceDecimalMark(latSeconds) .. secSymbol
lonSecSym = replaceDecimalMark(lonSeconds) .. secSymbol
else
latSecSym = latSeconds .. secSymbol
lonSecSym = lonSeconds .. secSymbol
end
end  
latDegrees = math.floor(latMinutes / 60)
lonDegrees = math.floor(lonMinutes / 60)  
latDegSym = latDegrees .. degSymbol
lonDegSym = lonDegrees .. degSymbol  
latMinutes = latMinutes - (latDegrees * 60)
lonMinutes = lonMinutes - (lonDegrees * 60)  
if precision >= (1 / 60) then
latMinutes = strFormat:format(latMinutes)
lonMinutes = strFormat:format(lonMinutes)  
if not raw then
latMinSym = replaceDecimalMark(latMinutes) .. minSymbol
lonMinSym = replaceDecimalMark(lonMinutes) .. minSymbol
else
latMinSym = latMinutes .. minSymbol
lonMinSym = lonMinutes .. minSymbol
end
else
latMinSym = latMinutes .. minSymbol
lonMinSym = lonMinutes .. minSymbol
end
end  
latValue = latDegSym .. latMinSym .. latSecSym .. latDirection
lonValue = lonDegSym .. lonMinSym .. lonSecSym .. lonDirection  
value = latValue .. separator .. lonValue  
if link then
globe = parseWikidataURL(datavalue['globe'])  
if globe then
globe = mw.wikibase.getLabelByLang(globe, "en"):lower
else
globe = "earth"
end  
latLink = table.concat({latDegrees, latMinutes, latSeconds}, "_")
lonLink = table.concat({lonDegrees, lonMinutes, lonSeconds}, "_")  
value = ""..value..""
end  
return value
elseif datatype == 'wikibase-entityid' then
local label
local itemID = datavalue['numeric-id']  
if subtype == 'wikibase-item' then
itemID = "Q" .. itemID
elseif subtype == 'wikibase-property' then
itemID = "P" .. itemID
else
return '<strong>' .. errorText('unknown-data-type', subtype) .. '</strong>'
end  
label = self:getLabel(itemID, raw, link, short)  
if label == "" then
label = nil
end  
return label
else
return '<strong>' .. errorText('unknown-data-type', datatype) .. '</strong>'
end
elseif snak.snaktype == 'somevalue' and not noSpecial then
if raw then
return " " -- single space represents 'somevalue'
else
return i18n['values']['unknown']
end
elseif snak.snaktype == 'novalue' and not noSpecial then
if raw then
return "" -- empty string represents 'novalue'
else
return i18n['values']['']
end
else
return nil
end
end  
function Config:getSingleRawQualifier(claim, qualifierID)
local qualifiers  
if claim.qualifiers then qualifiers = claim.qualifiers[qualifierID] end  
if qualifiers and qualifiers[1] then
return self:getValue(qualifiers[1], true) -- raw = true
else
return nil
end
end  
function Config:snakEqualsValue(snak, value)
local snakValue = self:getValue(snak, true) -- raw = true  
if snakValue and snak.snaktype == 'value' and snak.datavalue.type == 'wikibase-entityid' then value = value:upper end  
return snakValue == value
end  
function Config:setRank(rank)
local rankPos  
if rank == p.flags.best then
self.bestRank = true
self.flagBest = true -- mark that 'best' flag was given
return
end  
if rank:sub(1,9) == p.flags.preferred then
rankPos = 1
elseif rank:sub(1,6) == p.flags.normal then
rankPos = 2
elseif rank:sub(1,10) == p.flags.deprecated then
rankPos = 3
else
return
end  
-- one of the rank flags was given, check if another one was given before
if not self.flagRank then
self.ranks = {false, false, false} -- no other rank flag given before, so unset ranks
self.bestRank = self.flagBest -- unsets bestRank only if 'best' flag was not given before
self.flagRank = true -- mark that a rank flag was given
end  
if rank:sub(-1) == "+" then
for i = rankPos, 1, -1 do
self.ranks[i] = true
end
elseif rank:sub(-1) == "-" then
for i = rankPos, #self.ranks do
self.ranks[i] = true
end
else
self.ranks[rankPos] = true
end
end  
function Config:setPeriod(period)
local periodPos  
if period == p.flags.future then
periodPos = 1
elseif period == p.flags.current then
periodPos = 2
elseif period == p.flags.former then
periodPos = 3
else
return
end  
-- one of the period flags was given, check if another one was given before
if not self.flagPeriod then
self.periods = {false, false, false} -- no other period flag given before, so unset periods
self.flagPeriod = true -- mark that a period flag was given
end  
self.periods[periodPos] = true
end  
function Config:qualifierMatches(claim, id, value)
local qualifiers  
if claim.qualifiers then qualifiers = claim.qualifiers[id] end
if qualifiers then
for _, v in pairs(qualifiers) do
if self:snakEqualsValue(v, value) then
return true
end
end
elseif value == "" then
-- if the qualifier is not present then treat it the same as the special value 'novalue'
return true
end  
return false
end  
function Config:rankMatches(rankPos)
if self.bestRank then
return (self.ranks[rankPos] and self.foundRank >= rankPos)
else
return self.ranks[rankPos]
end
end  
function Config:timeMatches(claim)
local startTime = nil
local startTimeY = nil
local startTimeM = nil
local startTimeD = nil
local endTime = nil
local endTimeY = nil
local endTimeM = nil
local endTimeD = nil  
if self.periods[1] and self.periods[2] and self.periods[3] then
-- any time
return true
end  
startTime = self:getSingleRawQualifier(claim, aliasesP.startTime)
if startTime and startTime ~= "" and startTime ~= " " then
startTimeY, startTimeM, startTimeD = parseDate(startTime)
end  
endTime = self:getSingleRawQualifier(claim, aliasesP.endTime)
if endTime and endTime ~= "" and endTime ~= " " then
endTimeY, endTimeM, endTimeD = parseDate(endTime)
end  
if startTimeY ~= nil and endTimeY ~= nil and datePrecedesDate(endTimeY, endTimeM, endTimeD, startTimeY, startTimeM, startTimeD) then
-- invalidate end time if it precedes start time
endTimeY = nil
endTimeM = nil
endTimeD = nil
end  
if self.periods[1] then
-- future
if startTimeY and datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], startTimeY, startTimeM, startTimeD) then
return true
end
end  
if self.periods[2] then
-- current
if (startTimeY == nil or not datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], startTimeY, startTimeM, startTimeD)) and
(endTimeY == nil or datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], endTimeY, endTimeM, endTimeD)) then
return true
end
end  
if self.periods[3] then
-- former
if endTimeY and not datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], endTimeY, endTimeM, endTimeD) then
return true
end
end  
return false
end  
function Config:processFlag(flag)
if not flag then
return false
end  
if flag == p.flags.linked then
self.curState.linked = true
return true
elseif flag == p.flags.raw then
self.curState.rawValue = true  
if self.curState == self.states[parameters.reference] then
-- raw reference values end with periods and require a separator (other than )
self.separators["sep%r"][1] = {" "}
end  
return true
elseif flag == p.flags.short then
self.curState.shortName = true
return true
elseif flag == p.flags.multilanguage then
self.curState.anyLanguage = true
return true
elseif flag == p.flags.unit then
self.curState.unitOnly = true
return true
elseif flag == p.flags.mdy then
self.mdyDate = true
return true
elseif flag == p.flags.single then
self.singleClaim = true
return true
elseif flag == p.flags.sourced then
self.sourcedOnly = true