Modulo:Coordinates

Dokumentado Dokumentado


Ŝablona programadoDiskutojLuaTestojSubpaĝoj
ModuloEsperantoEnglishDeutsch

Modulo:Dokumentado


Se vi havas demandon pri ĉi tiu Lua-modulo, tiam vi povas demandi en la diskutejo pri Lua-moduloj. La Intervikiaj ligiloj estu metataj al Vikidatumoj. (Vidu Helpopaĝon pri tio.)
--[[ Coordinates 2020-05-04This module is intended to replace the functionality of {{Coord}} and relatedtemplates.  It provides several methods, including{{#Invoke:Coordinates | coord }} : General function formatting and displayingcoordinate values.{{#Invoke:Coordinates | dec2dms }} : Simple function for converting decimaldegree values to DMS format.{{#Invoke:Coordinates | dms2dec }} : Simple function for converting DMS formatto decimal degree format.{{#Invoke:Coordinates | dec2ch1903 }} : Simple function for converting decimaldegree values to CH1903 format.{{#Invoke:Coordinates | dms2ch1903 }} : Simple function for converting DMS formatto CH1903 format.{{#Invoke:Coordinates | dec2utm }} : Simple function for converting decimaldegree values to UTM format.{{#Invoke:Coordinates | dms2utm }} : Simple function for converting DMS formatto UTM format.]]math_mod = require( "Module:Math" );globalFrame = nilcoordinates = {};-- por koordinatojlocal function koordinatoj(latitudo, longitudo, regiono, tipo, nomo, supre, teksto )local t = "dms"if teksto ~= "" and teksto ~= nil thent = tekstoendlocal frame = mw.getCurrentFrame()local n = frame:expandTemplate {title="Koordinato",args ={NS=latitudo,EW=longitudo,region=regiono,type=tipo,name=nomo,text=t,                  -- la koordinatoj aperu en la informkestoarticle=supre     -- ĉu ankaŭ supre? se jes, la parametro havu la valoron /}}return nend-- {{#invoke:map|tag|type=maplink|text=(mapo)|geotype=Point|title={{{name}}}|latitude={{{NS|0}}} |longitude={{{EW|0}}}|zoom=15|image=|marker-symbol={{#switch:{{{type|}}}|country|state|adm1st|adm2nd|city=city|isle=circle|mountain|landmark=triangle|waterbody=water|#default=<!-- fino "switch"-->}}|marker-size=large|marker-color=4682B4}} -- from {{Ŝablono:CoordinateLINK}}local function mapligilo (lat, long, name, ctype)local frame = mw.getCurrentFrame()local s = ''if ctype == 'country' or ctype == 'state' or ctype == 'adm1st' or ctype == 'adm2nd' or ctype == 'city' thens = 'city'elseif ctype == 'isle' thens = 'circle'elseif ctype == 'mountain' or ctype == 'landmark' thens = 'triangle'elseif ctype == 'waterbody' thens = 'water'endlocal koord = koordinatoj(lat, long)local r = frame:expandTemplate {title='Mapligilo',args={text='(mapo)',type='point',title=name,coord=koord,zoom='15',['marker']=s,['marker-size']='large',['marker-color']='4682B4'}}return rend--[[ Helper function, replacement for {{coord/display/title}} ]]function displaytitle (s, notes, globe)    if mw.ustring.lower(mw.ustring.sub(s,1,5)) == "(div)" then        s = mw.ustring.sub(s,6);        tag = "div"    end    if mw.ustring.lower(mw.ustring.sub(s,1,6)) == "(span)" then        s = mw.ustring.sub(s,7);        tag = "span"    end    local l = "[[Geografia koordinata sistemo|Koordinatoj]]: " .. s    -- local l = "" .. s    if tag ~= "" and tag ~= nil then     co = '<' .. tag .. ' id="coordinates">' .. l .. notes .. '</' .. tag .. '>';            else    co = '<span id="coordinates">' .. l .. notes .. '</span>';    end    if tag == "div" then        return co     else         return '<span style="font-size: small;">' .. co .. '</span>'     endend--[[ Helper function, replacement for {{CoordinateNOx}}, but its text is elsewhere ]]function displaytitle2 (s, format)    --local l = "[[Geographic coordinate system|Coordinates]]: " .. s    local l = "" .. s    if format ~= "" and format ~= nil then        co = '<span id="coordinates" style="' .. format .. '">' .. l .. '</span>';    else co = '<span id="coordinates">' .. l .. '</span>';    end    return '<span style="font-size: small;">' .. co .. '</span>'end  --[[ Helper function, Replacement for {{coord/display/inline}} ]]function displayinline (s, notes)    return s .. notes    end--[[ Helper function, used in detecting DMS formatting ]]local dmsTest = function(first, second)    local concatenated = first:upper() .. second:upper();        return concatenated == "NE" or concatenated == "NO" or concatenated == "NW" or concatenated == "NU" or concatenated == "SE" or concatenated == "SO"          or concatenated == "SW" or concatenated == "SU" or concatenated == "EN" or concatenated == "ON" or concatenated == "WN"  or concatenated == "UN"         or concatenated == "ES" or concatenated == "OS" or concatenated == "WS" or concatenated == "US"end--[[parseDecTransforms decimal format latitude and longitude into the astructure to be used in displaying coordinates]]function parseDec( lat, long, format )    local coordinateSpec = {}    local errors = {}        if long == "" or long == nil then        return nil, {{"parseDec", "Mankas longitudo"}}    elseif not tonumber(formatPoint(long),10) then     return nil, {{"parseDec", "Longitudo ne povis esti parsata kiel numero: " .. long}} elseif not tonumber(long) thenreturn nil, {{"parseDec", "Longitudo ne povis esti parsata kiel numero: " .. long}}            end        errors = validate( lat, nil, nil, long, nil, nil, 'parseDec', false );        coordinateSpec["dec-lat"]  = lat;    coordinateSpec["dec-long"] = long;    local mode = coordinates.determineMode( lat, long );    coordinateSpec["dms-lat"]  = convert_dec2dms( lat, "N", "S", mode)  -- {{coord/dec2dms|{{{1}}}|N|S|{{coord/prec dec|{{{1}}}|{{{2}}}}}}}    coordinateSpec["dms-long"] = convert_dec2dms( long, "O", "U", mode)  -- {{coord/dec2dms|{{{2}}}|E|W|{{coord/prec dec|{{{1}}}|{{{2}}}}}}}      coordinateSpec["dmslong-lat"]  = convert_dec2dms( lat, "Nordo", "Sudo", mode)  -- {{coord/dec2dms|{{{1}}}|N|S|{{coord/prec dec|{{{1}}}|{{{2}}}}}}}    coordinateSpec["dmslong-long"] = convert_dec2dms( long, "Oriento", "Okcidento", mode)  -- {{coord/dec2dms|{{{2}}}|E|W|{{coord/prec dec|{{{1}}}|{{{2}}}}}}}          --added formats    coordinateSpec['ch1903-x'], coordinateSpec['ch1903-y'] = convert_dec2ch1903("",lat,long,0) -- for Swiss coordinates    coordinateSpec['zonenumber'], coordinateSpec['zonedir'], coordinateSpec['zone'], coordinateSpec['utm-x'], coordinateSpec['utm-y'] = convert_dec2utm("",lat,long,0) -- for UTM coordinates    coordinateSpec["dm-lat"]  = convert_dec2dms( lat, "N", "S", "dm")      coordinateSpec["dm-long"] = convert_dec2dms( long, "O", "U", "dm")     coordinateSpec["d-lat"]  = convert_dec2dms( lat, "N", "S", "d")      coordinateSpec["d-long"] = convert_dec2dms( long, "O", "U", "d")              if format ~= "" then        coordinateSpec.default = format    else        coordinateSpec.default = "dec"    end    return coordinateSpec, errorsend--[[ Helper function, handle optional args. ]]function optionalArg(arg, suplement)    if arg ~= nil and arg ~= "" then        return arg .. suplement    end    return ""end--[[parseDMSTransforms degrees, minutes, seconds format latitude and longitude into the a structure to be used in displaying coordinates]]function parseDMS( lat_d, lat_m, lat_s, lat_f, long_d, long_m, long_s, long_f, format )    local coordinateSpec = {}    local errors = {}        lat_f = lat_f:upper();    -- long_f = string.gsub(long_f:upper(),'W','U');    long_f = long_f:upper();    local lat_flong = 'Nordo';    if lat_f == 'S' then        lat_flong = 'Sudo';    end    local long_flong = 'Okcidento';    if long_f == 'E' or long_f == 'O' then        long_flong = 'Oriento';    end            -- Check if specified backward    if lat_f == 'E' or lat_f == "O" or lat_f == 'W' or lat_f == 'U' then        local t_d, t_m, t_s, t_f;        t_d = lat_d;        t_m = lat_m;        t_s = lat_s;        t_f = lat_f;        lat_d = long_d;        lat_m = long_m;        lat_s = long_s;        lat_f = long_f;        long_d = t_d;        long_m = t_m;        long_s = t_s;        long_f = t_f;    end            errors = validate( lat_d, lat_m, lat_s, long_d, long_m, long_s, 'parseDMS', true );    if long_d == nil or long_d == "" then        table.insert(errors, {"parseDMS", "Mankas longitudo" })    elseif not tonumber(formatPoint(long_d),10) thenreturn nil, {{"parseDMS", "Longitudo ne povis esti parsata kiel numero:" .. long_d }}            elseif not tonumber(long_d) thenreturn nil, {{"parseDMS", "Longitudo ne povis esti parsata kiel numero:" .. long_d }}    end        if lat_m == nil and lat_s == nil and long_m == nil and long_s == nil and #errors == 0 then         if math_mod._precision( lat_d ) > 0 or math_mod._precision( long_d ) > 0 then            if lat_f:upper() == 'S' then                 lat_d = '-' .. lat_d;            end            if long_f:upper() == 'W' or long_f:upper() == 'U' then                 long_d = '-' .. long_d;            end                             return parseDec( lat_d, long_d, format );        end            end           if long_f == "W" then        long_f = "U"        -- montri direkton, escepte de coordinateSpec["param"]    end    if long_f == "E" then        long_f = "O"        -- montri direkton, escepte de coordinateSpec["param"]    end        coordinateSpec["dms-lat"]  = lat_d.."°&nbsp;"..optionalArg(lat_m,"′&nbsp;") .. optionalArg(lat_s,"″&nbsp;") .. lat_f    coordinateSpec["dmslong-lat"]  = lat_d.."°&nbsp;"..optionalArg(lat_m,"′&nbsp;") .. optionalArg(lat_s,"″&nbsp;") .. lat_flong    coordinateSpec["dms-long"] = long_d.."°&nbsp;"..optionalArg(long_m,"′&nbsp;") .. optionalArg(long_s,"″&nbsp;") .. long_f    coordinateSpec["dmslong-long"] = long_d.."°&nbsp;"..optionalArg(long_m,"′&nbsp;") .. optionalArg(long_s,"″&nbsp;") .. long_flong    coordinateSpec["dec-lat"]  = convert_dms2dec(lat_f, lat_d, lat_m, lat_s) -- {{coord/dms2dec|{{{4}}}|{{{1}}}|0{{{2}}}|0{{{3}}}}}    coordinateSpec["dec-long"] = convert_dms2dec(long_f, long_d, long_m, long_s) -- {{coord/dms2dec|{{{8}}}|{{{5}}}|0{{{6}}}|0{{{7}}}}}    --added formats    coordinateSpec['ch1903-x'], coordinateSpec['ch1903-y'] = convert_dms2ch1903(lat_f, lat_d, lat_m, lat_s ,long_f, long_d, long_m, long_s) -- for Swiss coordinates    coordinateSpec['zonenumber'], coordinateSpec['zonedir'], coordinateSpec['zone'], coordinateSpec['utm-x'], coordinateSpec['utm-y'] = convert_dms2utm(lat_f, lat_d, lat_m, lat_s ,long_f, long_d, long_m, long_s) -- for UTM coordinates    coordinateSpec["dm-lat"]  = lat_d.."°&nbsp;"..optionalArg(lat_m,"′&nbsp;") .. lat_f    coordinateSpec["dm-long"] = long_d.."°&nbsp;"..optionalArg(long_m,"′&nbsp;") .. long_f    coordinateSpec["d-lat"]  = lat_d.."°&nbsp;" .. lat_f    coordinateSpec["d-long"] = long_d.."°&nbsp;" .. long_f                if format ~= "" then        coordinateSpec.default = format    else        coordinateSpec.default = "dms"    end       return coordinateSpec, errorsend--[[specPrinterOutput formatter.  Takes the structure generated by either parseDecor parseDMS and formats it for inclusion on Wikipedia.]]function specPrinter(args, coordinateSpec)    local uriComponents = coordinateSpec["param"]    if uriComponents == "" then        -- RETURN error, should never be empty or nil        return "ERARO param estis malplena"    end    if args["name"] ~= "" and args["name"] ~= nil then        uriComponents = uriComponents .. "&title=" .. mw.uri.encode(coordinateSpec["name"])    end        local lang=mw.language.getContentLanguage():getCode();        local geodmshtml = '<span class="geo-dms" title="Mapoj, elĉielaj bildoj kaj aliaj datumoj por ' .. coordinateSpec["dms-lat"] .. ' ' ..  coordinateSpec["dms-long"] .. '">'             .. '<span class="latitude">' .. coordinateSpec["dms-lat"] .. '</span> '             .. '<span class="longitude">' ..coordinateSpec["dms-long"] .. '</span>'             .. '</span>'    local geodmhtml = '<span title="Mapoj, elĉielaj bildoj kaj aliaj datumoj por ' .. coordinateSpec["dm-lat"] .. ' ' ..  coordinateSpec["dm-long"] .. '">'             .. '<span title="Latitude">' .. coordinateSpec["dm-lat"] .. '</span> '             .. '<span title="Longitude">' ..coordinateSpec["dm-long"] .. '</span>'             .. '</span>'           local geodhtml = '<span title="Mapoj, elĉielaj bildoj kaj aliaj datumoj por ' .. coordinateSpec["d-lat"] .. ' ' ..  coordinateSpec["d-long"] .. '">'             .. '<span title="Latitude">' .. coordinateSpec["d-lat"] .. '</span> '             .. '<span title="Longitude">' ..coordinateSpec["d-long"] .. '</span>'             .. '</span>'                   local geodmslonghtml = '<span class="geo-dms" title="Mapoj, elĉielaj bildoj kaj aliaj datumoj por ' .. coordinateSpec["dmslong-lat"] .. ' ' ..  coordinateSpec["dmslong-long"] .. '">'             .. '<span class="latitude">' .. coordinateSpec["dmslong-lat"] .. '</span> '             .. '<span class="longitude">' ..coordinateSpec["dmslong-long"] .. '</span>'             .. '</span>'    local lat = tonumber( coordinateSpec["dec-lat"] ) or 0    if lat < 0 then        -- FIXME this breaks the pre-existing precision        geodeclat = coordinateSpec["dec-lat"]:sub(2) .. " °S"        catlat    = coordinateSpec["dec-lat"]:sub(2)         catdirlat = "° S"        --geodeclat = "-" .. coordinateSpec["dec-lat"]:sub(2)    else        geodeclat = (coordinateSpec["dec-lat"] or 0) .. " °N"        catlat    = (coordinateSpec["dec-lat"] or 0)         catdirlat = "° N"        --geodeclat = (coordinateSpec["dec-lat"] or 0)    end    local long = tonumber( coordinateSpec["dec-long"] ) or 0    if long < 0 then        -- FIXME does not handle unicode minus        geodeclong = coordinateSpec["dec-long"]:sub(2) .. " °U"        catlong    = coordinateSpec["dec-long"]:sub(2)         catdirlong = "° U"        --geodeclong = '-' .. coordinateSpec["dec-long"]:sub(2)    else        geodeclong = (coordinateSpec["dec-long"] or 0) .. " °O"        catlong    = (coordinateSpec["dec-long"] or 0)         catdirlong = "° E" -- O estus pli taŭga, se por okcidento estas U        --geodeclong = (coordinateSpec["dec-long"] or 0)    end        -- it creates coding for categories, if the paramter "category" is used. after that returns it    if args['category'] =="jes" or args['category'] =="yes" then        -- category scheme from {{Ŝablono:Koord/kategorioj}}        local cat =""        catlong = math.floor (catlong) -- catlong % 10000        catlat = math.floor (catlat) -- catlat % 10000        if catlong == 180 then cat= "[[Kategorio:179° U]][[Kategorio:179° E]]"        else cat ="[[Kategorio:" .. catlong .. catdirlong .. "]]"          end        cat = cat .. "[[Kategorio:" .. catlat .. catdirlat .. "]]"        return cat    elseif args['category'] == "ne" or args['category'] == "no" then        cat = "[[Kategorio:Artikolo kun koordinatoj, sed sen koordinataj ligiloj]]"         return cat    end        local geodechtml = '<span class="geo-dec" title="Mapoj, elĉielaj bildoj kaj aliaj datumoj por ' .. coordinateSpec["dec-lat"] .. ' ' ..  coordinateSpec["dec-long"] .. '">'             .. geodeclat .. ', '             .. geodeclong             .. '</span>'    local geonumhtml = '<span class="geo">'             .. coordinateSpec["dec-lat"] .. '; '             .. coordinateSpec["dec-long"]             .. '</span>'             --cf http://www.mediawiki.org/wiki/Extension:GeoData    local geodata = ''    local r,s,t=string.match (coordinateSpec["param"],'(.*)_(E?W?)_(.*)')    local globe,globend=string.match (coordinateSpec["param"],'_globe:(.*)(_*)')    local ctype,ctypend = string.match(coordinateSpec["param"],'type:(.*)(_*)')    --Désactivé pour les astres à cause de problèmes de longitudes planétocentriques/planétographiques    if globe == nil or globe == 'earth' then    geodata = '{{#coordinates:' .. coordinateSpec["dec-lat"] .. '|' .. coordinateSpec["dec-long"] .. '|primary|' .. t .. '}}'    end    if args['geodata'] ~= nil then        return geodata;    end                 local inner;    if coordinateSpec["default"] == "dms" then        inner = '<span class="' .. displayDefault(coordinateSpec["default"], "dms" ) .. '">' .. geodmshtml .. '</span>'                    .. '<span class="geo-multi-punct">&#xfeff; / &#xfeff;</span>'                    .. '<span class="' .. displayDefault(coordinateSpec["default"], "dec" ) .. '">';    elseif coordinateSpec["default"] == "dm" then        inner = '<span class="' .. displayDefault(coordinateSpec["default"], "dm" ) .. '">' .. geodmhtml .. '</span>'                    .. '<span class="geo-multi-punct">&#xfeff; / &#xfeff;</span>'                    .. '<span class="' .. displayDefault(coordinateSpec["default"], "dec" ) .. '">';    elseif coordinateSpec["default"] == "d" then        inner = '<span class="' .. displayDefault(coordinateSpec["default"], "d" ) .. '">' .. geodhtml .. '</span>'                    .. '<span class="geo-multi-punct">&#xfeff; / &#xfeff;</span>'                    .. '<span class="' .. displayDefault(coordinateSpec["default"], "dec" ) .. '">';                        else        inner = '<span class="' .. displayDefault(coordinateSpec["default"], "dms long" ) .. '">' .. geodmslonghtml .. '</span>'                    .. '<span class="geo-multi-punct">&#xfeff; / &#xfeff;</span>'                    .. '<span class="' .. displayDefault(coordinateSpec["default"], "dec" ) .. '">';            end    if args["name"] == "" or args["name"] == nil then        inner = inner .. geodechtml                 .. '<span style="display:none">&#xfeff; / ' .. geonumhtml .. '</span></span>'    else        inner = inner .. '<span class="vcard">' .. geodechtml                 .. '<span style="display:none">&#xfeff; / ' .. geonumhtml .. '</span>'                .. '<span style="display:none">&#xfeff; (<span class="fn org">'                .. args["name"] .. '</span>)</span></span></span>'    end    if args["link"] == "jes" or args["link"] == "yes" or args["link"] == "" or args["link"] == nil then    return '<span class="plainlinks nourlexpansion">' .. globalFrame:preprocess(        '[http://tools.wmflabs.org/geohack/geohack.php?pagename={{FULLPAGENAMEE}}&language=' .. lang .. '&params=' ..        uriComponents .. ' ' .. inner .. ']') .. '</span> ' .. mapligilo (lat, long, name, ctype)    elseif args["link"] == "ne" or args["link"] == "no" then    return '<span class="plainlinks nourlexpansion">' .. inner .. '</span>'        end    end--[[specPrinter2 - for {{Koordinato}} Output formatter.  Takes the structure generated by either parseDecor parseDMS and formats it for inclusion on Wikipedia.]]function specPrinter2(args, coordinateSpec)    local uriComponents = coordinateSpec["param"]    if uriComponents == "" then        -- RETURN error, should never be empty or nil        return "ERARO param estis malplena"    end    if args["name"] ~= "" and args["name"] ~= nil then        uriComponents = uriComponents .. "&title=" .. mw.uri.encode(coordinateSpec["name"])    end        local lang=mw.language.getContentLanguage():getCode();        local geodmshtml = '<span title="Mapoj, elĉielaj bildoj kaj aliaj datumoj por ' .. coordinateSpec["dms-lat"] .. ' ' ..  coordinateSpec["dms-long"] .. '">'             .. '<span title="Latitude">' .. coordinateSpec["dms-lat"] .. '</span> '             .. '<span title="Longitude">' ..coordinateSpec["dms-long"] .. '</span>'             .. '</span>'    local geodmslonghtml = '<span title="Mapoj, elĉielaj bildoj kaj aliaj datumoj por ' .. coordinateSpec["dmslong-lat"] .. ' ' ..  coordinateSpec["dmslong-long"] .. '">'             .. '<span title="Latitude">' .. coordinateSpec["dmslong-lat"] .. '</span> '             .. '<span title="Longitude">' ..coordinateSpec["dmslong-long"] .. '</span>'             .. '</span>'    local geodmhtml = '<span title="Mapoj, elĉielaj bildoj kaj aliaj datumoj por ' .. coordinateSpec["dm-lat"] .. ' ' ..  coordinateSpec["dm-long"] .. '">'             .. '<span title="Latitude">' .. coordinateSpec["dm-lat"] .. '</span> '             .. '<span title="Longitude">' ..coordinateSpec["dm-long"] .. '</span>'             .. '</span>'        local geodhtml = '<span title="Mapoj, elĉielaj bildoj kaj aliaj datumoj por ' .. coordinateSpec["d-lat"] .. ' ' ..  coordinateSpec["d-long"] .. '">'             .. '<span title="Latitude">' .. coordinateSpec["d-lat"] .. '</span> '             .. '<span title="Longitude">' ..coordinateSpec["d-long"] .. '</span>'             .. '</span>'                                local lat = tonumber( coordinateSpec["dec-lat"] ) or 0    if lat < 0 then        -- FIXME this breaks the pre-existing precision        geodeclat = coordinateSpec["dec-lat"]:sub(2) .. " °S"        catlat    = coordinateSpec["dec-lat"]:sub(2)         catdirlat = "° S"        --geodeclat = "-" .. coordinateSpec["dec-lat"]:sub(2)    else        geodeclat = (coordinateSpec["dec-lat"] or 0) .. " °N"        catlat    = (coordinateSpec["dec-lat"] or 0)         catdirlat = "° N"        --geodeclat = (coordinateSpec["dec-lat"] or 0)    end    local long = tonumber( coordinateSpec["dec-long"] ) or 0    if long < 0 then        -- FIXME does not handle unicode minus        geodeclong = coordinateSpec["dec-long"]:sub(2) .. " °U"        catlong    = coordinateSpec["dec-long"]:sub(2)         catdirlong = "° U"        --geodeclong = '-' .. coordinateSpec["dec-long"]:sub(2)    else        geodeclong = (coordinateSpec["dec-long"] or 0) .. " °O"        catlong    = (coordinateSpec["dec-long"] or 0)         catdirlong = "° E" -- O estus pli taŭga, se por okcidento estas U        --geodeclong = (coordinateSpec["dec-long"] or 0)    end        -- it creates coding for categories, if the paramter "category" is used. after that returns it    if args['category'] =="jes" or args['category'] =="yes" then        -- category scheme from {{Ŝablono:Koord/kategorioj}}        local cat =""        catlong = math.floor (catlong) -- catlong % 10000        catlat = math.floor (catlat) -- catlat % 10000        if catlong == 180 then cat= "[[Kategorio:179° U]][[Kategorio:179° E]]"        else cat ="[[Kategorio:" .. catlong .. catdirlong .. "]]"          end        cat = cat .. "[[Kategorio:" .. catlat .. catdirlat .. "]]"        return cat            elseif args['category'] == "ne" or args['category'] == "no" then        cat = "[[Kategorio:Artikolo kun koordinatoj, sed sen koordinataj ligiloj]]"         return cat    end        local geodechtml = '<span title="Mapoj, elĉielaj bildoj kaj aliaj datumoj por ' .. coordinateSpec["dec-lat"] .. ' ' ..  coordinateSpec["dec-long"] .. '">'             .. '<span title="Latitudo">' .. geodeclat .. '</span>' .. ', '             .. '<span title="Longitudo">' .. geodeclong .. '</span>'             .. '</span>'    local geonumhtml = '<span class="geo">'             .. coordinateSpec["dec-lat"] .. '; '             .. coordinateSpec["dec-long"]             .. '</span>'                 --<span title="Svislandaj landaj koordinatoj">CH1903:&nbsp;</span>    --<span title="y easting">562330</span>&nbsp;/&nbsp;<span title="x northing">124404</span>    if coordinateSpec['ch1903-x'] ~= nil and coordinateSpec['ch1903-y'] ~= nil then    geoch1903html = '<span title="Svislandaj landaj koordinatoj">CH1903:&nbsp;</span>'        .. '<span title="y easting">' .. coordinateSpec['ch1903-y'] .. '</span>&nbsp;/&nbsp;'                .. '<span title="x northing">' .. coordinateSpec ['ch1903-x'] .. '</span>'         ch1903 = "yes"    end            --UTM format    if coordinateSpec['utm-x'] ~= nil and coordinateSpec['utm-y'] ~= nil then    geoutmhtml = '<span title="Universal Transverse Mercator, baziĝanta sur WGS84">UTM:&nbsp;</span>'        .. 'Zono&nbsp;<span title="Zononumero">' .. coordinateSpec['zonenumber'] .. '</span>'        .. '<span title="Zonobendo, ' .. coordinateSpec['zonedir'] .. ' de la ekvatoro">' .. coordinateSpec['zone'] .. '</span>, '        .. '<span title="easting">' .. coordinateSpec['utm-y'] .. '</span>&nbsp;/&nbsp;'                .. '<span title="northing">' .. coordinateSpec['utm-x'] .. '</span>'         utm = "yes"    end          local inner;            if coordinateSpec["default"] == "dms" then        inner = geodmshtml     elseif coordinateSpec["default"] == "dms long" then        inner = geodmslonghtml     elseif coordinateSpec["default"] == "dm" then        inner = geodmhtml        elseif coordinateSpec["default"] == "d" then        inner = geodhtml                elseif coordinateSpec["default"] == "ch1903" and ch1903 == "yes" then        inner = geoch1903html    elseif coordinateSpec["default"] == "utm" and utm == "yes" then        inner = geoutmhtml            else inner = geodechtml     end    local id = " "    local display = args['display'] -- or "inline"    if display == nil then display = "inline"    end            if string.find( display, 'inline' ) ~= nil then    -- creates a text for id, if it used in the text, not in the title               if args["name"] ~= "" and args["name"] ~= nil then        id = ' id="' .. args['name'] .. '" '            else id = ' id="text_coordinates" '        end                        -- for microformats according to {{Koordinato}}        micro = '<span class="geo microformat"><span class="latitude">' .. coordinateSpec["dec-lat"] .. '</span>'        micro = micro .. '<span class="longitude">' .. coordinateSpec["dec-long"] .. '</span><span class="elevation"></span></span>'        --sortkey has to be added only, if display is "inline"        --replacement for {{CoordinateSort}}        if args['sortkey'] ~= "" and args['sortkey'] ~= nil then            local k = args['sortkey']                         local z = 500.0000005            local h            key = '<span style="display:none">!'                 k = mw.ustring.upper(k) -- capitalize                 if k == "EW" or k == "LONG" then                    h = math_mod._round(z + long, 6) .. math_mod._round(z + lat, 6)                   key = key .. h                else                    h = math_mod._round(z + lat, 6) .. math_mod._round(z + long, 6)                   key = key .. h                end                 key = key .. '</span>'        else key = ""            end        if args['format2'] ~= "" and args['format2'] ~= nil then        -- create second format               local format2 = args['format2']:lower()               if format2 == "dms" then                    f2 = geodmshtml                elseif format2 == "dms long" then                    f2 = geodmslonghtml                elseif format2 == "ch1903" and ch1903 == "yes" then                    f2 = geoch1903html               elseif format2 == "utm" and utm == "yes" then                    f2 = geoutmhtml                                   else f2 = geodechtml                end               -- f2 = ' ( ' .. f2 .. ' ) '        else f2 = ""           end            if args['format3'] ~= "" and args['format3'] ~= nil then        -- create third format               local format3 = args['format3']:lower()               if format3 == "dms" then                    f3 = geodmshtml                elseif format3 == "dms long" then                    f3 = geodmslonghtml                elseif format3 == "ch1903" and ch1903 == "yes" then                    f3 = geoch1903html               elseif format3 == "utm" and utm == "yes" then                    f2 = geoutmhtml                                      else f3 = geodechtml                end               -- f3 = ' ( ' .. f3 .. ' ) '        else f3 = ""                        end                if args['format4'] ~= "" and args['format4'] ~= nil then        -- create fourth format               local format4 = args['format4']:lower()               if format4 == "dms" then                    f4 = geodmshtml                elseif format4 == "dms long" then                    f4 = geodmslonghtml                elseif format4 == "ch1903" and ch1903 == "yes" then                    f4 = geoch1903html               elseif format4 == "utm" and utm == "yes" then                    f2 = geoutmhtml                                      else f4 = geodechtml                end               -- f4 = ' ( ' .. f4 .. ' ) '        else f4 = ""            end        else             micro = '<div class="geo microformat"><span class="latitude">' .. coordinateSpec["dec-lat"] .. '</span>'        micro = micro .. '<span class="longitude">' .. coordinateSpec["dec-long"] .. '</span><span class="elevation"></span></div>'        key = ""        f2 = ""        f3 = ""        f4 = ""    end       if string.find( display, 'title' ) ~= nil then        if args['formatitle2'] ~= "" and args['formatitle2'] ~= nil then        -- create second format               local formatitle2 = args['formatitle2']:lower()        --       if formatitle2 == "dms" then        --            ft2 = geodmshtml         --       elseif formatitle2 == "dms long" then        --            ft2 = geodmslonghtml         --       elseif formatitle2 == "ch1903" and ch1903 == "yes" then               if formatitle2 == "ch1903" and ch1903 == "yes" then                    ft2 = geoch1903html               else ft2 = geodechtml                end               -- ft2 = ' ( ' .. ft2 .. ' ) '        else ft2 = ""           end            end            -- add a clip before and after the added formats    if args['second'] == "yes" then        if ft2 ~= "" and ft2 ~= nil then        otherformat = ' (' .. ft2 .. ')'        else otherformat = ''        end    else        if (f2 ~= "" and f2 ~= nil) or (f3 ~= "" and f3 ~= nil) or (f4 ~= "" and f4 ~= nil) then        if f2 ~= "" and f2 ~= nil and f3 ~= "" and f3 ~= nil then             f2f3 = ' ; '        else f2f3 = ""            end        if f3 ~= "" and f3 ~= nil and f4 ~= "" and f4 ~= nil then             f3f4 = ' ; '        else f3f4 = ""            end                otherformat = ' (' .. f2 .. f2f3 .. f3 .. f3f4 .. f4 .. ')'        else otherformat = ''            end    end         -- a little trick for return the microformats only    if args['micro'] == "yes" then       return micro    end        -- analyzes the parameter "word", if it a has a value for certain symbol    if args['word'] ~= "" and args['word'] ~= nil then        local word = args['word']        upperword = string.upper(word)        --ICON0 and ICON1        if upperword == "ICON0" then            word = "⊙"        elseif upperword == "ICON" then            word = "⦁"            elseif upperword == "ICON1" then            word = "<sup>▼</sup>"        elseif upperword == "ICON2" then            word = "[[Dosiero:Erioll world.svg|15px|link=|loko]]"        end        if args['name'] ~= "" and args['name'] ~= nil then            word = '<span title="' .. args['name'] .. '">' .. word .. '</span>'        else            word = '<span>' .. word .. '</span>'        end        return key .. '<span' .. id .. 'class="plainlinks nourlexpansion">' .. globalFrame:preprocess(        '[http://tools.wmflabs.org/geohack/geohack.php?pagename={{FULLPAGENAMEE}}&language=' .. lang .. '&params=' ..        uriComponents .. ' ' .. word .. ']') .. '</span>'    else       return key .. '<span' .. id .. 'class="plainlinks nourlexpansion">' .. globalFrame:preprocess(        '[http://tools.wmflabs.org/geohack/geohack.php?pagename={{FULLPAGENAMEE}}&language=' .. lang .. '&params=' ..        uriComponents .. ' ' .. inner .. otherformat .. ']') .. '</span>'     endend--[[Formats any error messages generated for display]]function errorPrinter(errors)    local result = ""    for i,v in ipairs(errors) do        local errorHTML = '<strong class="error">Koordinatoj: ' .. v[2] .. '</strong>'        result = result .. errorHTML .. "<br />"    end    return resultend--[[Determine the required CSS class to display coordinatesUsually geo-nondefault is hidden by CSS, unless a user has overridden this for himselfdefault is the mode as specificied by the user when calling the {{coord}} templatemode is the display mode (dec or dms) that we will need to determine the css class for ]]function displayDefault(default, mode)    if default == "" then        default = "dec"    end        if default:sub(1,4) == mode:sub(1,4) or default:sub(1,3) == mode:sub(1,3) then        return "geo-default"    else        return "geo-nondefault"    endend--[[ Check the input arguments for coord to determine the kind of data being providedand then make the necessary processing.]]function formatTest(args)    local result, errors;    local primary = false;        if args[1] == "" then        -- no lat logic        return errorPrinter( {{"formatTest", "Mankas latitudo"}} )--elseif not tonumber(formatPoint(args[1]), 10) then-- bad lat logic--return errorPrinter( {{"formatTest", "Ne eblas parsi latitudon kiel numeron:" .. args[1]}} )        --elseif not tonumber(args[1]) then-- bad lat logic--return errorPrinter( {{"formatTest", "Ne eblas parsi latitudon kiel numeron:" .. args[1]}} )            elseif args[4] == "" and args[5] == "" and args[6] == "" then        -- dec logic        result, errors = parseDec( formatPoint(args[1]), formatPoint(args[2]), args['format'] )        if result == nil then            return errorPrinter( errors );        end                      local declat = tonumber( formatPoint(args[1]), 10 ) or 0        if declat < 0 then             dirNS = "_S_"             declat = 0 - declat        else             dirNS = "_N_"               declat = formatPoint(args[1])        end        local declong = tonumber( formatPoint(args[2]), 10 ) or 0        if declong < 0 then             dirEW = "_W_"            declong = 0 - declong        else             dirEW = "_E_"                declong = formatPoint(args[2])        end        result.param    = table.concat( {declat, dirNS, declong, dirEW, args[3] } );        --result.param    = table.concat( {formatPoint(args[1]), "_N_", formatPoint(args[2]), "_E_", args[3] } );    elseif dmsTest(args[4], args[8]) then        -- dms logic        result, errors = parseDMS( args[1], args[2], formatPoint(args[3]), args[4],             args[5], args[6], formatPoint(args[7]), args[8], args['format'] )        result.param = table.concat( { args[1], args[2], formatPoint(args[3]), args[4], args[5],            args[6], formatPoint(args[7]), formatLongEW(args[8]), args[9] } , '_' );        if args[10] ~= '' then        local deko = '<span style="display:none;">' .. args[10] .. '</span>'            table.insert( errors, { 'formatTest', 'Kromaj neatenditaj parametroj/10' .. deko } );        end            elseif dmsTest(args[3], args[6]) then        -- dm logic        result, errors = parseDMS( args[1], formatPoint(args[2]), nil, args[3],             args[4], formatPoint(args[5]), nil, args[6], args['format'] )        result.param = table.concat( { args[1], formatPoint(args[2]), args[3], args[4], formatPoint(args[5]),            formatLongEW(args[6]), args[7] } , '_' );        if args[8] ~= '' then        local oko = '<span style="display:none;">' .. args[8] .. '</span>'            table.insert( errors, { 'formatTest', 'Kromaj neatenditaj parametroj/8' .. oko } );        end            elseif dmsTest(args[2], args[4]) then        -- d logic        result, errors = parseDMS( formatPoint(args[1]), nil, nil, args[2],             formatPoint(args[3]), nil, nil, args[4], args['format'] )        result.param = table.concat( { formatPoint(args[1]), args[2], formatPoint(args[3]), formatLongEW(args[4]), args[5] } , '_' );        if args[6] ~= '' then        local seso = '<span style="display:none;">' .. args[6] .. '</span>'            table.insert( errors, { 'formatTest', 'Kromaj neatenditaj parametroj/6' .. seso } );        end            else        -- Error        return errorPrinter( {{"formatTest", "Nekonata argumenta formato"}} )    end    result.name     = args["name"] or args["nomo"]        local extra_param = {'dim', 'globe', 'scale', 'region', 'source', 'type'}    for _, v in ipairs( extra_param ) do        if (args[v] or '') ~= '' then             table.insert( errors, {'formatTest', 'Parametro: "' .. v .. '=" estu "' .. v .. ':"' } );        end    end        if args['mode'] == "de" then      if #errors == 0 then          return specPrinter2( args, result )          else          return specPrinter2( args, result ) .. " " .. errorPrinter(errors) .. '[[Kategorio:Artikoloj kun problemo de koordinatoj]]';       end          else        if #errors == 0 then          return specPrinter( args, result )          else          return specPrinter( args, result ) .. " " .. errorPrinter(errors) .. '[[Kategorio:Artikoloj kun problemo de koordinatoj]]';       end        endend--[[ Helper function, convert the decimal comma to decimal point ]]function formatPoint(num)    return mw.ustring.gsub(num, ",", ".")end--[[ Helper function, convert longitude U to W or longitude O to E]]function formatLongEW(dir)    if dir:upper() == "U" then        return "W"    end    if dir:upper() == "O" then        return "E"    end        return dirend--[[ Helper function, convert decimal latitude or longitude to degrees, minutes, and seconds format based on the specified precision.  ]]function convert_dec2dms(coordinate, firstPostfix, secondPostfix, precision)    local coord = tonumber(coordinate) or 0    local postfix    if coord >= 0 then        postfix = firstPostfix    else        postfix = secondPostfix    end    precision = precision:lower();    if precision == "dms" then        return convert_dec2dms_dms( math.abs( coord ) ) .. postfix;    elseif precision == "dm" then        return convert_dec2dms_dm( math.abs( coord ) ) .. postfix;    elseif precision == "d" then        return convert_dec2dms_d( math.abs( coord ) ) .. postfix;    endend--[[ Helper function, convert decimal to degrees ]]function convert_dec2dms_d(coordinate)    local d = math_mod._round( coordinate, 0 ) .. "°&nbsp;"    return d .. ""end--[[ Helper function, convert decimal to degrees and minutes ]]function convert_dec2dms_dm(coordinate)        coordinate = math_mod._round( coordinate * 60, 0 );    local m = coordinate % 60;    coordinate = math.floor( (coordinate - m) / 60 );    local d = coordinate % 360 .."°&nbsp;"        return d .. string.format( "%02d′&nbsp;", m )end--[[ Helper function, convert decimal to degrees, minutes, and seconds ]]function convert_dec2dms_dms(coordinate)    coordinate = math_mod._round( coordinate * 60 * 60, 0 );    local s = coordinate % 60    coordinate = math.floor( (coordinate - s) / 60 );    local m = coordinate % 60    coordinate = math.floor( (coordinate - m) / 60 );    local d = coordinate % 360 .."°&nbsp;"    return d .. string.format( "%02d′&nbsp;", m ) .. string.format( "%02d″&nbsp;", s )end--[[Convert DMS format into a N or E decimal coordinate]]function convert_dms2dec(direction, degrees_str, minutes_str, seconds_str)    local degrees = tonumber(degrees_str) or 0    local minutes = tonumber(minutes_str) or 0    local seconds = tonumber(seconds_str) or 0        local factor    direction = mw.ustring.gsub(direction, '^[ ]*(.-)[ ]*$', '%1');    if direction == "N" or direction == "E" or direction == "O" then        factor = 1    else        factor = -1    end        local precision = 0    if seconds_str ~= nil and seconds_str ~= '' then        precision = 5 + math.max( math_mod._precision(seconds_str), 0 );    elseif minutes_str ~= nil and minutes_str ~= '' then        precision = 3 + math.max( math_mod._precision(minutes_str), 0 );    else        precision = math.max( math_mod._precision(degrees_str), 0 );    end        local decimal = factor * (degrees+(minutes+seconds/60)/60)     return string.format( "%." .. precision .. "f", decimal ) -- not tonumber since this whole thing is string based.end--[[ Helper function   Convert decimal into CH1903 - replacement for {{Coordinate/to CH1903}}]] function convert_dec2ch1903(label,lat,lon,prec)              local errors = {}              local b_lbl = (label or "" ) ~= "";              local n     =  math.floor (tonumber(prec) or 0);              local lat = tonumber(lat)              local lon = tonumber(lon)              if( lat < 45.7 or lat > 47.9 or lon < 5.8 or lon > 10.6 ) then                 --ErrMsg(ErrCode='OOR', ErrFun='WGS84toCH1903',ErrData="keine")                 table.insert(errors, {"dec2ch1903", "latitudaj gradoj < 45.7 aŭ > 47.9 aŭ longitudaj gradoj < 5.8 aŭ > 10.6"})              end              -- genaue Berechnung, Lua kann sich das leisten              local phi    = (lat * 3600 - 169028.66 ) /10000;              local lambda = (lon * 3600 - 26782.5) / 10000;              local x = 200147.07 + 308807.95 * phi    +  3745.25 * lambda^2 +    76.63 * phi^2 + 119.79 * phi^3 - 194.56 * lambda^2 * phi;              local y = 600072.37 + 211455.93 * lambda - 10938.51 * lambda * phi - 0.36 * lambda * phi^2 - 44.54 * lambda^3;              x = (math.floor(x* 10^n + 0.5))/10^n;              y = (math.floor(y* 10^n + 0.5))/10^n;              x = math_mod._round( x, 0 )              y = math_mod._round( y, 0 )              return x .. "", y .. "", errors;end--[[ Helper function   Convert dms into CH1903 ]] function convert_dms2ch1903(lat_f, lat_d, lat_m, lat_s ,long_f, long_d, long_m, long_s)            local errors = {}            local label = ""            local prec = 0            local lat = convert_dms2dec(lat_f, lat_d, lat_m, lat_s)            local lon = convert_dms2dec(long_f, long_d, long_m, long_s)            local x, y = convert_dec2ch1903(label, lat, lon, prec)            x = tonumber(x) .. ""            y = tonumber(y) .. ""            return x, y, errorsend    --[[ Helper function - replacement for {{Coordinate/to UTM/Easting}}   ({{{A}}}) + ( 1 - ({{{T}}}) + ({{{C}}}) ) * ({{{A}}})^3 / 6 + ( 5 - 18*({{{T}}}) + ({{{T}}})^2 + 72*({{{C}}}) - 0.39089<!--58e²/(1-e²)-->) * ({{{A}}})^5 / 120]]function easting (A,T,C)    local easting = (A)       + ( 1 - (T) + (C) ) * (A)^3 / 6       + ( 5 - 18*(T) + (T)^2 + 72*(C) - 0.39089) * (A)^5 / 120    return eastingend    --[[ Helper function - replacement for {{Coordinate/to UTM/Northing}}  ({{{A}}})^2 / 2+ ( 5 - ({{{T}}}) + 9*({{{C}}}) + 4*({{{C}}})^2 ) * ({{{A}}})^4 / 24+ ( 61 - 58*({{{T}}}) + ({{{T}}})^2 + 600*({{{C}}}) - 2.22403) * ({{{A}}})^6 / 720]]function northing (A,T,C)    local northing = (A)^2 / 2 + ( 5 - (T) + 9*(C) + 4*(C)^2 ) * (A)^4 / 24 + ( 61 - 58*(T) + (T)^2 + 600*(C) - 2.22403) * (A)^6 / 720    return northing end     --[[ Helper function   Convert decimal into UTM - replacement for {{Coordinate/to UTM}}]] function convert_dec2utm(label,lat,lon,prec)              local errors = {}              local b_lbl = (label or "" ) ~= "";              local n     =  math.floor (tonumber(prec) or 0);              local lat = tonumber(lat)              local lon = tonumber(lon)              local zonenumber = math.ceil(lon/6)+30              if lat < 0 then                  zonedir = "sude"              else                  zonedir = "norde"              end              local z = math.floor(lat/8)              if z == -10 then zone = "C"              elseif z == -9 then zone = "D"              elseif z == -8 then zone = "E"              elseif z == -7 then zone = "F"              elseif z == -6 then zone = "G"              elseif z == -5 then zone = "H"              elseif z == -4 then zone = "J"              elseif z == -3 then zone = "K"              elseif z == -2 then zone = "L"              elseif z == -1 then zone = "M"              elseif z == 0 then zone = "N"              elseif z == 1 then zone = "P"              elseif z == 2 then zone = "Q"              elseif z == 3 then zone = "R"              elseif z == 4 then zone = "S"              elseif z == 5 then zone = "T"              elseif z == 6 then zone = "U"              elseif z == 7 then zone = "V"              elseif z == 8 then zone = "W"              elseif z == 9 then zone = "X"              elseif math.abs(lat-78) <= 6 then zone = "X"                  else table.insert(errors, {"dec2utm", "latitudaj gradoj estas ekster la eblaj valoroj."})                        if lat > 0 then                      if lon > 0 then zone = "B"                      else zone = "A"                        end                  else                       if lon > 0 then zone = "Z"                      else zone = "Y"                      end                  end              end               local k_0 = 0.9996              local a = 6378137              local pi = 3.1415926535898              local A = (lon - math.ceil(lon/6) * 6 + 3)/180*pi * math.cos(lat/180*pi)              local T = math.tan(lat/180*pi)^2              local C = 0.0067394968 * math.cos(lat/180*pi)^2              local y = 500000 + k_0 * a / ( 1 - 0.00669438 * math.sin(lat/180*pi)^2 )^.5 * easting(A,T,C);              if lat < 0 then                   x1 = 1              else                  x1 = 0              end              local x = x1*10000000 + k_0 * a * (0.9983243 * ( lat/180*pi) - 2.51460708e-3 * math.sin(2 * lat/180*pi)                 + 2.63904664e-6 * math.sin(4 * lat/180*pi) - 3.41804618e-9 * math.sin(6 * lat/180*pi)                 + math.tan(lat/180*pi) / ( 1 - 0.00669438 * math.sin(lat/180*pi)^2 )^.5 * (northing(A,T,C) ) );               x = math_mod._round( x, 0 )              y = math_mod._round( y, 0 )              return zonenumber .. "", zonedir .. "", zone .. "", x .. "", y .. "", errors;end--[[ Helper function   Convert dms into UTM ]] function convert_dms2utm(lat_f, lat_d, lat_m, lat_s ,long_f, long_d, long_m, long_s)            local errors = {}            local label = ""            local prec = 0            local lat = convert_dms2dec(lat_f, lat_d, lat_m, lat_s)            local lon = convert_dms2dec(long_f, long_d, long_m, long_s)            local zonenumber, zonedir, zone, x, y = convert_dec2utm(label, lat, lon, prec)            x = tonumber(x) .. ""            y = tonumber(y) .. ""            return zonenumber, zonedir, zone, x, y, errorsend  --[[ Checks input values to for out of range errors.]]function validate( lat_d, lat_m, lat_s, long_d, long_m, long_s, source, strong )    local errors = {};    lat_d = tonumber( lat_d ) or 0;    lat_m = tonumber( lat_m ) or 0;    lat_s = tonumber( lat_s ) or 0;    long_d = tonumber( long_d ) or 0;    long_m = tonumber( long_m ) or 0;    long_s = tonumber( long_s ) or 0;    if strong then        if lat_d < 0 then            table.insert(errors, {source, "latitudaj gradoj < 0 kun hemisfera flago"})        end        if long_d < 0 then            table.insert(errors, {source, "longitudaj gradoj < 0 kun hemisfera flago"})        end        --[[         #coordinates is inconsistent about whether this is an error.  If globe: is        specified, it won't error on this condition, but otherwise it will.                For not simply disable this check.                if long_d > 180 then            table.insert(errors, {source, "longitude degrees > 180 with hemisphere flag"})        end        ]]    end                if lat_d > 90 then        table.insert(errors, {source, "latitudaj gradoj > 90"})    end    if lat_d < -90 then        table.insert(errors, {source, "latitudaj gradoj < -90"})    end    if lat_m >= 60 then        table.insert(errors, {source, "latitudaj minutoj >= 60"})    end    if lat_m < 0 then        table.insert(errors, {source, "latitudaj minutoj < 0"})    end    if lat_s >= 60 then        table.insert(errors, {source, "latitudaj sekundoj >= 60"})    end    if lat_s < 0 then        table.insert(errors, {source, "latitudaj sekundoj < 0"})    end    if long_d >= 360 then        table.insert(errors, {source, "longitudaj gradoj >= 360"})    end    if long_d <= -360 then        table.insert(errors, {source, "longitudaj gradoj <= -360"})    end    if long_m >= 60 then        table.insert(errors, {source, "longitudaj minutoj >= 60"})    end    if long_m < 0 then        table.insert(errors, {source, "longitudaj minutoj < 0"})    end    if long_s >= 60 then        table.insert(errors, {source, "longitudaj sekundoj >= 60"})    end    if long_s < 0 then        table.insert(errors, {source, "longitudaj sekundoj < 0"})    end        return errors;end--[[dec2dmsWrapper to allow templates to call dec2dms directly.Usage:    {{ Invoke:Coordinates | dec2dms | decimal_coordinate | positive_suffix |         negative_suffix | precision }}    decimal_coordinate is converted to DMS format.  If positive, the positive_suffixis appended (typical N or E), if negative, the negative suffix is appended.  Thespecified precision is one of 'D', 'DM', or 'DMS' to specify the level of detailto use.]]function coordinates.dec2dms(frame)    globalFrame = frame    local coordinate = frame.args[1]    local firstPostfix = frame.args[2]    local secondPostfix = frame.args[3]    local precision = frame.args[4]    return convert_dec2dms(coordinate, firstPostfix, secondPostfix, precision)end--[[ Wrapper to allow templates to call dec2ch1903 directly ]]function coordinates.dec2ch1903 (frame)    globaFrame = frame    local label = frame.args[1]    local lat = frame.args[2]    local lon = frame.args[3]    local prec = frame.args[4]    local text = ""    local x, y = convert_dec2ch1903(label,lat,lon, prec)    if label ~= "" and label ~= nil then        text = '<span title="Svislandaj landaj koordinatoj">CH1903:&nbsp;</span>'        .. '<span title="y easting">' .. y .. '</span>&nbsp;/&nbsp;'                .. '<span title="x northing">' .. x .. '</span>'     else        text = "CH1903: " .. y .. " / " .. x    end        return textend    --[[ Wrapper to allow templates to call dec2utm directly ]]function coordinates.dec2utm (frame)    globaFrame = frame    local label = frame.args[1]    local lat = frame.args[2]    local lon = frame.args[3]    local prec = frame.args[4]    local text = ""    local zonenumber, zonedir, zone, x, y = convert_dec2utm(label,lat,lon, prec)    -- if label ~= "" and label ~= nil then        text = '<span title="Universal Transverse Mercator, baziĝanta sur WGS84">UTM:&nbsp;</span>'        .. 'Zono&nbsp;<span title="Zononumero">' .. zonenumber .. '</span>'        .. '<span title="Zonobendo, ' .. zonedir .. ' de la ekvatoro">' .. zone .. '</span>, '        .. '<span title="easting">' .. y .. '</span>&nbsp;/&nbsp;'                .. '<span title="northing">' .. x .. '</span>'     -- else       -- text = "CH1903: " .. y .. " / " .. x    -- end        return textend--[[Helper function to determine whether to use D, DM, or DMSformat depending on the precision of the decimal input.]]function coordinates.determineMode( value1, value2 )    local precision = math.max( math_mod._precision( value1 ), math_mod._precision( value2 ) );    if precision <= 0 then        return 'd'    elseif precision <= 2 then        return 'dm';    else        return 'dms';    endend        --[[dms2decWrapper to allow templates to call dms2dec directly.Usage:    {{ Invoke:Coordinates | dms2dec | direction_flag | degrees |         minutes | seconds }}    Converts DMS values specified as degrees, minutes, seconds too decimal format.direction_flag is one of N, S, E, W, and determines whether the output is positive (i.e. N and E) or negative (i.e. S and W).]]function coordinates.dms2dec(frame)    globalFrame = frame        local direction = frame.args[1]    local degrees = frame.args[2]    local minutes = frame.args[3]    local seconds = frame.args[4]          if frame.args[2] == nil then         local explode=mw.text.split( frame.args[1], '/' )        if (#explode > 1) then            direction = explode[#explode]            degrees = explode[1]        else            local sign, val=string.match (explode[1], '([\-]*)([%d.]*)')            if sign == '-' then direction='S' else direction='N' end            degrees = val        end            if(#explode>2) then             minutes = explode[2]        end        if(#explode>3) then             seconds = explode[3]        end    end         return convert_dms2dec(direction, degrees, minutes, seconds)end--[[dms2ch1903Wrapper to allow templates to call dms2ch1903 directly.Usage:    {{ Invoke:Coordinates | dms2ch1903 | direction_flag1 | degrees |         minutes | seconds | direction_flag2 | degrees | minutes | seconds }}    Converts DMS values specified as degrees, minutes, seconds too format of Swiss coordinates.direction_flag1 is one of N, S and direction_flag2 is one of E, W, and determines whether the output is positive (i.e. N and E) or negative (i.e. S and W).]]function coordinates.dms2ch1903(frame)    globalFrame = frame        local lat_f = frame.args[1]    local lat_d = frame.args[2]    local lat_m = frame.args[3]    local lat_s = frame.args[4]    local long_f = frame.args[5]    local long_d = frame.args[6]    local long_m = frame.args[7]    local long_s = frame.args[8]    local label = frame.args['label']    local text = ""        if frame.args[3] == nil then         local explode1=mw.text.split( frame.args[1]:match( '^%s*(.-)%s*$' ), '/' )        local explode2=mw.text.split( frame.args[2]:match( '^%s*(.-)%s*$' ), '/' )          --latitude        if (#explode1 > 1) then            lat_f = explode1[#explode1]            lat_d = explode1[1]        else            local sign, val=string.match (explode1[1], '([\-]*)([%d.]*)')            if sign == '-' then lat_f='S' else lat_f='N' end            lat_d = val        end            if(#explode1>2) then             lat_m = explode1[2]        end        if(#explode1>3) then             lat_s = explode1[3]        end        --longitude        if (#explode2 > 1) then            long_f = explode2[#explode2]            long_d = explode2[1]        else            local sign, val=string.match (explode2[1], '([\-]*)([%d.]*)')            if sign == '-' then long_f='W' else long_f='E' end            long_d = val        end            if(#explode2>2) then             long_m = explode2[2]        end        if(#explode2>3) then             long_s = explode2[3]        end    end             local x, y = convert_dms2ch1903(lat_f, lat_d, lat_m, lat_s, long_f, long_d, long_m, long_s)    if label ~= "" and label ~= nil then        text = '<span title="Svislandaj landaj koordinatoj">CH1903:&nbsp;</span>'        .. '<span title="y easting">' .. y .. '</span>&nbsp;/&nbsp;'                .. '<span title="x northing">' .. x .. '</span>'     else        text = "CH1903: " .. y .. " / " .. x    end        return textend    --[[dms2utmWrapper to allow templates to call dms2utm directly.Usage:    {{ Invoke:Coordinates | dms2utm | direction_flag1 | degrees |         minutes | seconds | direction_flag2 | degrees | minutes | seconds }}    Converts DMS values specified as degrees, minutes, seconds too format of Swiss coordinates.direction_flag1 is one of N, S and direction_flag2 is one of E, W, and determines whether the output is positive (i.e. N and E) or negative (i.e. S and W).]]function coordinates.dms2utm(frame)    globalFrame = frame        local lat_f = frame.args[1]    local lat_d = frame.args[2]    local lat_m = frame.args[3]    local lat_s = frame.args[4]    local long_f = frame.args[5]    local long_d = frame.args[6]    local long_m = frame.args[7]    local long_s = frame.args[8]    local label = frame.args['label']    local text = ""        if frame.args[3] == nil then         local explode1=mw.text.split( frame.args[1]:match( '^%s*(.-)%s*$' ), '/' )        local explode2=mw.text.split( frame.args[2]:match( '^%s*(.-)%s*$' ), '/' )          --latitude        if (#explode1 > 1) then            lat_f = explode1[#explode1]            lat_d = explode1[1]        else            local sign, val=string.match (explode1[1], '([\-]*)([%d.]*)')            if sign == '-' then lat_f='S' else lat_f='N' end            lat_d = val        end            if(#explode1>2) then             lat_m = explode1[2]        end        if(#explode1>3) then             lat_s = explode1[3]        end        --longitude        if (#explode2 > 1) then            long_f = explode2[#explode2]            long_d = explode2[1]        else            local sign, val=string.match (explode2[1], '([\-]*)([%d.]*)')            if sign == '-' then long_f='W' else long_f='E' end            long_d = val        end            if(#explode2>2) then             long_m = explode2[2]        end        if(#explode2>3) then             long_s = explode2[3]        end    end             local zonenumber, zonedir, zone, x, y = convert_dms2utm(lat_f, lat_d, lat_m, lat_s, long_f, long_d, long_m, long_s)    -- if label ~= "" and label ~= nil then        text = '<span title="Universal Transverse Mercator, baziĝanta sur WGS84">UTM:&nbsp;</span>'        .. 'Zono&nbsp;<span title="Zononumero">' .. zonenumber .. '</span>'        .. '<span title="Zonobendo, ' .. zonedir .. ' de la ekvatoro">' .. zone .. '</span>, '        .. '<span title="easting">' .. y .. '</span>&nbsp;/&nbsp;'                .. '<span title="northing">' .. x .. '</span>'     -- else       -- text = "CH1903: " .. y .. " / " .. x    -- end         return textend --[[ Helper function, returns values for "display", if the parameter "montru" is used insteadif the given text in "montru" is empty, it returns nilif the given text in "montru" isn't empty, it returns an utilizable value]]function coordinates.montru (montru)    local text = ""    -- if montru isn't empty, then it changes the text in "montru" in lower case letters    if montru ~= "" and montru ~= nil then montru = string.lower(montru)       -- it analyzes the text       if string.find(montru, "titolo") ~= nil then text = "title"       end           if string.find(montru, "entekste") ~= nil then            if text == "" then text = "inline"            else text = "inline," .. text           end           end        -- elseif montru == nil then text = montru        end         return textend    --[[ Helper function, returns values for "format", if the paramter "formato" is used insteadif the given text in "formato" is empty, it returns nilif the given text in "formato" isn't empty, it returns an utilizable value]]function coordinates.formato (formato)    local text = ""    if formato ~= nil and formato ~= "" then       -- if formato isn't empty, then it changes the text in "formato" into lower case letters        formato = string.lower(formato)       -- the value of formato is analyzed       if formato == "gms" or formato == "dms" then text = "dms"       elseif formato == "gm" or formato == "dm" then text = "dm"       elseif formato == "g" or formato == "grado" or formato == "d" then text = "d"              elseif formato == "gms-longa" or formato == "gms longa" or formato == "dms long" then text = "dms long"          elseif formato == "dek" or formato == "dec" then text = "dec"          -- if there is a nonsense text in "formato", then it returns "dms"         else text = "dms"           end    else text = formato       end       return textend    --[[ Helper function, for {{Koordinato}}, which returns values for "format", if the paramter "formato" is used insteadif the given text in "formato" is empty, it returns nilif the given text in "formato" isn't empty, it returns an utilizable value]]function coordinates.formattext (formato)    local text = ""    if formato ~= nil and formato ~= "" then       -- if formato isn't empty, then it changes the text in "formato" into lower case letters        formato = string.lower(formato)       -- the value of formato is analyzed       if formato == "gms" or formato == "dms" then text = "dms"       elseif formato == "gm" or formato == "dm" then text = "dm"       elseif formato == "g" or formato == "grado" or formato == "d" then text = "d"              elseif formato == "gms-longa" or formato == "gms longa" or formato == "dms long" then text = "dms long"          -- addition for {{Koordinato}}       elseif formato == "ch1903" then text = formato       elseif formato == "utm" then text = formato       elseif formato == "dek" or formato == "dec" then text = "dec"          -- some icons for {{Koordinato}}       elseif formato == "icon0" or formato == "icon1" or formato == "icon2" then text = formato       -- any image with the name space prefix       elseif mw.ustring.lower(mw.ustring.sub(formato,1,5)) == "file:" or mw.ustring.lower(mw.ustring.sub(formato,1,6)) == "image:"           or mw.ustring.lower(mw.ustring.sub(formato,1,8)) == "dosiero:" then text = formato       -- if there is an other text in "formato", then it returns dms         else text = "dms"        end    else text = formato       end       return textend    --[[ Helper function, chiefly for {{Koordinato}}, which returns values for "formatitle", if the paramter "titolformato" is used insteadif the given text in "formato" is empty, it returns nilif the given text in "formato" isn't empty, it returns an utilizable value]]function coordinates.formatarticle (formato)    local text = ""    if formato ~= nil and formato ~= "" then       -- if formato isn't empty, then it changes the text in "formato" into lower case letters        formato = string.lower(formato)       -- the value of formato is analyzed       if formato == "gms" or formato == "dms" then text = "dms"       elseif formato == "gm" or formato == "dm" then text = "dm"       elseif formato == "g" or formato == "grado" or formato == "d" then text = "d"              elseif formato == "gms-longa" or formato == "gms longa" or formato == "dms long" then text = "dms long"          -- addition for {{Koordinato}}       elseif formato == "ch1903" then text = formato       elseif formato == "dek" or formato == "dec" then text = "dec"          -- if there is an other text in "formato", then it returns dms         else text = "dms"        end    else text = formato       end       return textend    --[[coordMain entry point for Lua function to replace {{coord}}Usage:    {{ Invoke:Coordinates | coord }}    {{ Invoke:Coordinates | coord | lat | long }}    {{ Invoke:Coordinates | coord | lat | lat_flag | long | long_flag }}    ...        Refer to {{coord}} documentation page for many additional parameters and     configuration options.    Note: This function provides the visual display elements of {{coord}}.  Inorder to load coordinates into the database, the {{#coordinates:}} parser function must also be called, this is done automatically in the Luaversion of {{coord}}.]]function coordinates.coord(frame)    globalFrame = frame        local text = ''        local args = frame.args    if args[1] == nil then        local pFrame = frame:getParent();        args = pFrame.args;        for k,v in pairs( frame.args ) do            args[k] = v;        end    end        for i=1,10 do         if args[i] == nil then             args[i] = ""        else            args[i] = args[i]:match( '^%s*(.-)%s*$' );  --remove whitespace        end            end    if args['mode'] == "de" then        args['format'] = coordinates.formattext(args['format']) or coordinates.formattext(args['formato']) or '';    else            args['format'] = coordinates.formato(args['format']) or coordinates.formato(args['formato']) or '';    end    args['name'] = args['name'] or args['nomo']    args['category'] = args['category'] or args['kategorio'];    args['link'] = args['link'] or args['ligu'];    local latdms=mw.text.split( args[1], '/' )    local lngdms=mw.text.split( args[2], '/' )    if #latdms > 1 or #lngdms >1 then         -- je copie        local argsN=mw.clone(args)           local i = 1 -- point de départ        local ia = 1 -- point de départ        while (latdms[i] ~= nil) do          args[ia]=mw.text.trim(latdms[i])          i = i + 1          ia = ia +1        end        local i = 1 -- point de départ        while (lngdms[i] ~= nil) do          args[ia]=mw.text.trim(lngdms[i])          i = i + 1          ia = ia +1        end        local i = 3 -- point de départ        while (argsN[i] ~= nil) do          args[ia]=argsN[i]          i = i + 1          ia = ia +1        end    end               --definition of the planete    local astre    for _, l in ipairs(args) do        for w in string.gmatch(l, "globe:(%a+)") do            astre=w            break        end    end            local contents = formatTest(args)    local Notes = args.notes or ""    local Display = string.lower(args.display or coordinates.montru(args.montru) or "inline")    if Display == '' then        Display = 'inline';    end        local havedisplay = "";     if string.find( Display, 'inline' ) ~= nil or Display == 'i' or             Display == 'it' or Display == 'ti'  or (args['category'] ~= "" and args['category'] ~= nil)             or args['link'] == "ne" or args['link']  == "no" then        text = text .. displayinline(contents, Notes)        havedisplay = havedisplay .. "i";    end    if (args['category'] == "" or args['category'] == nil) and (args['link'] == ""     or args['link'] == nil or args['link'] == "jes" or args['link'] == "yes") then        if string.find( Display, 'title' ) ~= nil or Display == 't' or               Display == 'it' or Display == 'ti' then           if args['formatitle'] ~= nil then              args['format'] = args['formatitle'] or args['format']              contents = formatTest(args)           end              text = text .. displaytitle(contents, Notes, astre)           args['geodata']="primary"           text = text ..  globalFrame:preprocess(formatTest(args) )            havedisplay = havedisplay .. "t";       end    end     if havedisplay == "" then        --rien n'a été affiché!        text = text .. displayinline(contents, Notes) .. errorPrinter( {{"display", "argumento display estas malĝusta"}} )     end     return textendfunction coordinates.Coord(frame)    return coordinates.coord(frame)end--[[ coord2 - variant of coord for use in Modulo:Coordinates2]]function coordinates.coord2(frame)        globalFrame = frame.args.gf         local origArgs = {}              if frame == mw.getCurrentFrame() then                 origArgs = frame:getParent().args             else                         origArgs = frame.args             end          args = {}            for k, v in pairs(origArgs) do                                      args[k] = v                                end    for i=1,10 do         if args[i] == nil then             args[i] = ""        else            args[i] = args[i]:match( '^%s*(.-)%s*$' );  --remove whitespace        end            end    args['format'] = coordinates.formattext(args['format']) or coordinates.formattext(args['formato']) or '';            args['formatitle'] = coordinates.formatarticle(args['formatitle']) or coordinates.formatarticle(args['titolformato']) -- or '';    args['name'] = args['name'] or args['nomo']    args['category'] = args['category'] or args['kategorio'];    args['mode'] = "de"    local latdms=mw.text.split( args[1], '/' )    local lngdms=mw.text.split( args[2], '/' )    if #latdms > 1 or #lngdms >1 then         -- je copie        local argsN=mw.clone(args)           local i = 1 -- point de départ        local ia = 1 -- point de départ        while (latdms[i] ~= nil) do          args[ia]=mw.text.trim(latdms[i])          i = i + 1          ia = ia +1        end        local i = 1 -- point de départ        while (lngdms[i] ~= nil) do          args[ia]=mw.text.trim(lngdms[i])          i = i + 1          ia = ia +1        end        local i = 3 -- point de départ        while (argsN[i] ~= nil) do          args[ia]=argsN[i]          i = i + 1          ia = ia +1        end    end           local contents = formatTest(args)    local Notes = args.notes or ""    -- local Display = string.lower(args.display or coordinates.montru(args.montru) or "inline")    local Display = string.lower(args.display or "inline")        if Display == '' then        Display = 'inline';    end        local text = ''    if string.find( Display, 'inline' ) ~= nil or Display == 'i' or             Display == 'it' or Display == 'ti' or (args['category'] ~= "" and args['category'] ~= nil) then        text = displayinline(contents, Notes)        isInline = "yes"    else isInline = "no"        end    if args['category'] == "" or args['category'] == nil then        -- creates the code for the microformat        args['micro'] = "yes"        content = formatTest(args)        args['micro'] = ""        text = text .. content -- adds it to the return string      if string.find( Display, 'title' ) ~= nil or Display == 't' or             Display == 'it' or Display == 'ti' then        -- a helper parameter for uses, if there are more than one format for the coordinates                      args['second'] = "yes"          if args['formatitle'] ~= nil then            args['format'] = args['formatitle'] -- or args['format']            contents = formatTest(args)        end                   if isInline == "no" then            -- a little bit tricky methode to put in an information about the tags to be used            contents = "(div)" .. contents          else contents = "(span)" .. contents              end        text = text .. displaytitle(contents, Notes)      end        end    if string.find( Display, 'project' ) ~= nil then        -- message from {{CoordinateNOx}}. but its HTML-code is elsewhere        text = displaytitle2('Koordinatoj mankas! [[Projekto:Geografiaj koordinatoj|Bonvolu kunhelpi]]',"background:#FFC")    end            return textendreturn coordinates