-- This test module has been cleaned up - most functions removed due to lack of interest -- or collaboration to create viable modules for wikivoyage use. -- Left a few functions as they are used on another article page. Module will remain and -- probably will be used for testing other functions... Matroc -- Note: may wish to change some code to do "if not " (boolean) ???? testing for nil  local p = {}    local function loadwikinames()     local wikinames = {}	 	wikinames[1] = "wikisource" 	wikinames[2] = "wikibooks" 	wikinames[3] = "wikinews" 	wikinames[4] = "wikiquote" 	wikinames[5] = "wikivoyage" 	wikinames[6] = "wiki" 	return wikinames end    function p.date(frame) 	 return os.date("%m%d%Y -- %I:%M:%S")  end  -- Load a page and scan it for listing templates and find duplicate parameters   -- The next five functions though not used may be useful for someone else to use in the future -- in building circles for OpenStreetMaps -- see p.circle function below  local function isINF(value)         return value == math.huge or value == -math.huge end  local function degrees2meterslat(lat)         x = math.log(math.tan((90 + lat) * math.pi / 360)) / (math.pi / 180)         x = x * 20037508.34 / 180         return x end  local function degrees2meterslong(long)         y = long * 20037508.34 / 180    --- longitude to meters         return y end  local function meters2degreeslat(y)         lat = math.atan(math.exp(y * math.pi / 20037508.34)) * 90 / math.pi - 90         return lat end  local function meters2degreeslong(y)         long = y *  180 / 20037508.34         return long end  -- Rough calculation of distance between 2 coordinates in miles and kilometres  local function distance(lat1,long1,lat2,long2) -- in Progress     lat1 = math.rad(lat1)     lat2 = math.rad(lat2) 	long1 = math.rad(long1) 	long2 = math.rad(long2)     local longd = long2 - long1     local latd = lat2 - lat1     local x = (math.sin(latd/2))^2 + math.cos(lat1) * math.cos(lat2) * (math.sin(longd/2))^2     local y = 2 * math.atan2( math.sqrt(x), math.sqrt(1-x) )     local distance1 = 3861 * y  -- miles     local distance2 = 6373 * y  -- kilometers     return "Approximate distance in '''miles''': " .. distance1 .. " Approximate distance in '''kilometers''': " .. distance2 end function p.distance(frame,lat1,long1,lat2,long2) -- in Progress 	local lat1 = frame.args['lat1']	     lat1 = math.rad(lat1) local lat2 = frame.args['lat2']	         lat2 = math.rad(lat2) local long1 = frame.args['long1']	       	long1 = math.rad(long1) local long2 = frame.args['long2']	 	long2 = math.rad(long2)     local longd = long2 - long1     local latd = lat2 - lat1     local x = (math.sin(latd/2))^2 + math.cos(lat1) * math.cos(lat2) * (math.sin(longd/2))^2     local y = 2 * math.atan2( math.sqrt(x), math.sqrt(1-x) )     local distance1 = 3861 * y  -- miles     local distance2 = 6373 * y  -- kilometers distance1 = string.format("%.6f",distance1) distance2 = string.format("%.6f",distance2)     return "Approximate distance in '''miles''': " .. distance1 .. " Approximate distance in '''kilometers''': " .. distance2 end   -- load a table for tblukup local function load_t1(t1,table2load) 	if pcall(function()t1 = mw.loadData(table2load) end) then 		return t1 	else 		error ("Unable to load table!") 	end end   -- FROM WIKIBASE  -- Returns the most updated info from a series of statements - called by some of the other functions  local function updated(item,prop,frame)     if item~=nil then         local claims = item.claims         if claims~=nil and claims[prop]~=nil then             for index,claim in pairs(claims[prop]) do                 local qual = claim.qualifiers                 if qual==nil or qual.P582==nil then                     -- p582 è la data di fine, significa che non è il valore attuale                     local val = claim.mainsnak.datavalue.value                     if val['numeric-id']~=nil then                         local id = 'Q'..val['numeric-id']                         local sl = mw.wikibase.sitelink(id)                         local lb = mw.wikibase.label(id)                         if sl~=nil and sl~='' then                             return frame:preprocess('[['..sl..'|'..lb..']]')                         end                         return lb                     end                     return val                 end             end         end     end     return '' end   function p.libya(frame) 	local linkTarget = mw.wikibase.sitelink("Q1016") 	local linkName = mw.wikibase.label("Q1016") 	 	return "LinkTarget: " .. linkTarget .. " LinkName: " .. linkName 	 end   -- GET LATITUDE -- P625  function p.latitude(frame) --    if frame.args[1]~=nil and frame.args[1]~='' then --        return frame.args[1] --    end 	local latitude = "" 	local arg1 = frame.args[1]     local entity = mw.wikibase.getEntityObject(arg1)	 --	local entity = mw.wikibase.getEntityObject() 	if entity == nil then return latitude end    		 	local claims = entity.claims 	if claims == nil then 		return latitude 	end	 	if claims.P625 ~= nil then 		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 		return latitude 	end 	return latitude end  --  GET LONGITUDE -- P625  function p.longitude(frame) --    if frame.args[1]~=nil and frame.args[1]~='' then --        return frame.args[1] --    end 	local longitude = "" 	local arg1 = frame.args[1]     local entity = mw.wikibase.getEntityObject(arg1)	 --	local entity = mw.wikibase.getEntityObject() 	if entity == nil then return longitude end    		 	local claims = entity.claims 	if claims == nil then 		return longitude 	end	 	if claims.P625 ~= nil then 		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 		return longitude 	end 	return longitude end  -- GET URL -- P856 function p.url(frame) --    if frame.args[1]~=nil and frame.args[1]~='' then --        return frame.args[1] --    end 	local url = "" 	local arg1 = frame.args[1] 	local entity = mw.wikibase.getEntityObject(arg1) 	if entity == nil then return url end	 	local claims = entity.claims 	if claims == nil then 		return 		end 	if claims.P856 ~= nil then 		url = entity.claims.P856[1].mainsnak.datavalue.value 		url = string.gsub(url,"%,.*","") -- KEEP ONLY ONE 		return url 	end return url end  -- make a completed mapframe template from data from Wikidata with zoom of 13 {{mapframe|||}}  function p.makemapframe(frame) 	local output = "" 	local latitude = "" 	local longitude = "" 	local arg1 = frame.args[1] 	local entity = mw.wikibase.getEntityObject(arg1) 	if entity == nil then return end 	local claims = entity.claims 	if claims == nil then return end 	if claims.P625 == nil then return end -- pcall is actually used as a test mechanism - bit more complicated in use than regular tests 	if pcall(function () t = claims.P625 end) then  		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		 			latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 			end 		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			 			longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 			end	  		if latitude ~= "" and latitude ~= nil and longitude ~= "" and longitude ~= nil then 			latitude = string.format("%.6f",latitude) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000 			longitude = string.format("%.6f",longitude) -- format number to 6 decimal places see above 			latitude = string.gsub(latitude,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1. 			longitude = string.gsub(longitude,"0+$","") -- string any number of ending zeroes - see above 			latitude = string.gsub(latitude,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1 			longitude = string.gsub(longitude,"%.$","") -- strip an ending period 			output = output .. "{{mapframe|" .. latitude .. "|" .. longitude  .. "|zoom=8}}\n" 			end 	end 	if output ~=nil and output ~= "" then 		return output 	end 	 end  -- make a completed geo template from data from Wikidata {{geo||}}  function p.makegeo(frame) 	local output = "" 	local latitude = "" 	local longitude = "" 	local arg1 = frame.args[1] 	local entity = mw.wikibase.getEntityObject(arg1) 	if entity == nil then return end 	local claims = entity.claims 	if claims == nil then return end 	if claims.P625 == nil then return end -- pcall is actually used as a test mechanism - bit more complicated in use than regular tests 	if pcall(function () t = claims.P625 end) then  		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		 			latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 			end 		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			 			longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 			end	  		if latitude ~= "" and latitude ~= nil and longitude ~= "" and longitude ~= nil then --			latitude = string.format("%.4f",latitude) -- format number to 4 decimal places	-- keeping now as 4 decimal places		 --			longitude = string.format("%.4f",longitude) -- format number to 4 decimal places			 			latitude = string.format("%.6f",latitude) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000 			longitude = string.format("%.6f",longitude) -- format number to 6 decimal places see above 			latitude = string.gsub(latitude,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1. 			longitude = string.gsub(longitude,"0+$","") -- string any number of ending zeroes - see above 			latitude = string.gsub(latitude,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1 			longitude = string.gsub(longitude,"%.$","") -- strip an ending period -- if zoom parameter is desired this can be done fairly easily --			output = output .. "{{geo|" .. latitude .. "|" .. longitude  .. "| zoom=13}}\n" 			output = output .. "{{geo|" .. latitude .. "|" .. longitude  .. "}}\n" 			end 	end 	if output ~=nil and output ~= "" then 		output = string.gsub(output,'}}','|zoom=13}}') 		return output 	end 	 end  -- TBLUKUP - loads a table and does a lookup for table -- Table to load is required to be on a Module: page by itself  function p.tblukup(frame) 	local table2load = frame.args[1] or "" 	local lookup = frame.args[2] or "" 	local bywhat = "key" --- lookup to be performed on the key - can add args[3] as key or str in future 	if table2load == "" or table2load == nil then return end 	table2load = "Module:" .. table2load -- table is to be found on a Module: page 	if lookup == "" or lookup == nil then return end 	local t1 = {} 	t1 = load_t1(t1,table2load) 	if bywhat == "key" then -- Shorter version possible rather than cycling through all  	if t1[lookup] then return t1[lookup] end		 --		for key,value in pairs(t1) do --			if key == lookup then --				return value --				end --		end  	end --	if bywhat == "str" then --		for key,value in pairs(t1) do --			if value == lookup then --				return key --				end --		end --	end 	return lookup end  -- Purpose: Create a basic simple map template in an article based on Qnn for future editorial purposes -- What is produced is actual code for extension Kartographer - this is very verbose and probably not -- for the faint at heart -- programming is being done to translate listings directly in maps  -- One general argument is this function is at cross purposes to normal see, buy listings etc. and probably not -- desired however it appears that just a little bit more can be accomplished in the image field -- than the image field in a listing. -- Whereas there is no place for other pieces of information as found in a see listing. -- arg1 would be the overall location of the Qnn passed to get the latitude and longitude for the overall marker -- arg2 would be multiple Qnnn,Qnnn - separated by a comma -- and build each feature from data garnered from Wikidata - (latitude, longitude, image etc.) -- error could possibly arise if the Qnnn in not in Wikidata -- arguments that can be passed as well have been added for this function are: -- zoom -- group -- show -- color -- symbol -- Possible issue to check - the name in Wikidata may not be name in wikivoyage -- may have to do a check there as well -- safesubst to be used so you can see what you get and once saved can be edited manually -- Is there room for both forms - I do not know. There should be at least some discussion about this....  function p.amapframe(frame) 	local arg1 = frame.args[1] or "" 	if string.match(arg1,"^[Qq]%d+$") == nil then return "" end  -- arg1 should be in a specific format 'Qnnnn' testing  	local arg2 = frame.args['list'] or "" 	if arg2 ~= nil and arg2 ~= "" then 		arg2 = string.gsub(arg2,"%s","") 	end 	local group = frame.args['group'] or "city" 	local show = frame.args['show'] or "city" 	local zoom = frame.args['zoom'] or "4" 	local markercolor = frame.args['color'] or "#33a2ff"  -- prep for color argument -- change the concatenation of text 	if markercolor == nil or markercolor == "" then markercolor = "#33a2ff" end 	local markersymbol = frame.args['symbol'] or "city"   -- prep for symbol argument 	if markersymbol == nil or markersymbol == "" then markersymbol = "city" end     local markercolor = '"marker-color": "' .. markercolor .. '"'     local markersymbol = '"marker-symbol": "' .. markersymbol .. '",' -- use these items for concatenation below 	local latitude = "" 	local longitude = "" 	local separator = "," 	local output = "" 	local feature = "" 	local entity = mw.wikibase.getEntityObject(arg1) 	if entity == nil then return end 	local claims = entity.claims 	if claims == nil then return end 	if claims.P625 == nil then return end -- pcall is actually used as a test mechanism - bit more complicated in use than regular tests 	if pcall(function () t = claims.P625 end) then 		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		 			latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 			end 		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			 			longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 		end	 end 	if latitude ~= "" and latitude ~= nil and longitude ~= "" and longitude ~= nil then 			latitude = string.format("%.6f",latitude) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000 			longitude = string.format("%.6f",longitude) -- format number to 6 decimal places see above 			latitude = string.gsub(latitude,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1. 			longitude = string.gsub(longitude,"0+$","") -- string any number of ending zeroes - see above 			latitude = string.gsub(latitude,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1 			longitude = string.gsub(longitude,"%.$","") -- strip an ending period 			local part1 = '\n'   -- not going to output div box --   	local part1 = '\n<div style="border-style:solid; border-width:2px; width:412px; \ --    	height:412px; padding:12px 12px 2px 2px; float:right;">\n'     	local part2 = '\n<mapframe latitude=' .. latitude .. ' longitude=' .. longitude .. ' zoom=' .. zoom .. ' width="400" height="400" group="' .. group .. '" show="' .. show .. '">\n' 		local part3 = '\n' .. '{' .. '\n\t' .. '"type": "FeatureCollection",' .. '\n\t' ..  '"features": [' .. '\n'  -- count up others to put on map - using Qnnnn and add basic type feature -- module to get each name, latitude and longitude using split arg2 would be Qnnn,Qnnn,Qnnn -- can get label --  get latitude longitude and basic description and image if possible -- Need to eliminate duplicates - perhaps put Qnns in an array and scan each and eliminate duplicates  ---- TEST OF REMOVING DUPLICATES FROM LIST OF Qnn  local index = 1  local items = {}  local flags = {}   for str in string.gmatch(arg2,"([^"..separator.."]+)") do 	items[index] = str 	index = index + 1 	end  for i=1,#items do 	if not flags[items[i]] then 		flags[items[i]] = true  feature = feature .. p.feature(items[i],markercolor,markersymbol) -- extra arguments ?? 		end 	end ---- END TEST OF REMOVING DUPLICATES FROM LIST OF Qnnn  ---- OLD CODE KEEP -- ---- for str in string.gmatch(arg2,"([^"..separator.."]+)") do -- ---- feature = feature .. p.feature(str,markercolor,markersymbol) -- ---- feature = feature .. p.feature(str) --	 --	end -- ----OLD CODE KEEP --  		feature = string.gsub(feature,",$","") 	    local part4 = '\n\t' .. ']' .. '\n' .. '}</mapframe>' .. '\n' -- not outputting div  --	    local part4 = '\n\t' .. ']' .. '\n' .. '}</mapframe>' .. '\n' .. '</div>' .. '\n' 		output = part1 .. part2 .. part3 .. feature .. part4 	end 	return output end -----------function p.feature(str) function p.feature(str,markercolor,markersymbol) 	local text = "" 	local lat = "" 	local long = "" 	local name = "" 	local image = "" 	local voysitename = "" 	local voysitename2 = "" 	local wiki = "" 	local xtraname = "" 	local part1 = "" 	local part2 = "" 	local part3 = "" 	local part4 = "" 	local part5 = "" 	local part6 = "" 	local part7 = "" 	local part8 = "" 	 -- Do check on str to insure its correct format and check to see if we get object or maybe do a test 	 -- using pcall 	 if string.match(str,"^[Qq]%d+$") == nil then return "" end -- str should be in a specific format 'Qnnn'  --	 if pcall(function () t = mw.wikibase.getEntityObject(str) end ) then --	 local entity = mw.wikibase.getEntityObject(str) --	 else return end     	local entity = mw.wikibase.getEntityObject(str)  	if entity == nil then return "" end    		 	local claims = entity.claims 	if claims == nil then 		return "" 	end	 	if pcall(function () t = claims.P625 end) then 		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		 			lat = entity.claims.P625[1].mainsnak.datavalue.value.latitude 			end 		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			 			long = entity.claims.P625[1].mainsnak.datavalue.value.longitude 			end	 		end 	if pcall(function () t = claims.P18 end) then 		if pcall(function () t = entity.claims.P18[1].mainsnak.datavalue.value end ) then		 			image = entity.claims.P18[1].mainsnak.datavalue.value 			end 	end 	if lat == "" or long == "" then return "" end 			lat = string.format("%.6f",lat) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000 			long = string.format("%.6f",long) -- format number to 6 decimal places see above 			lat = string.gsub(lat,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1. 			long = string.gsub(long,"0+$","") -- string any number of ending zeroes - see above 			lat = string.gsub(lat,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1 			long = string.gsub(long,"%.$","") -- strip an ending period 	if image ~= "" then	 		image = str.gsub(image,'%"','\\"') -- Believe it or not there are image names with quotes 		                                -- this can be picked up as a redlinked image 		image = '[[File:' .. image .. '|280px|link=]]'		 --		image = '"[[File:' .. image .. '|280px|link=]]"' 	else 		if pcall(function () t = claims.P948 end) then 			if pcall(function () t = entity.claims.P948[1].mainsnak.datavalue.value end ) then		 				image = entity.claims.P948[1].mainsnak.datavalue.value 				image = '[[File:' .. image .. '|280px|link=]]'				 			end 		end 	end 	if image == "" then 		image = '[[File:Wikivoyage-Logo-v3-small-en.png|Wikivoyage|80px|link=]]<br>' -- [[File:WV-logo-artmap.jpg|120px]] 	end 	name = mw.wikibase.sitelink(str) 	if name == "" or name == nil then 		name = mw.wikibase.label(str) or "" 	end  	voysitename = "" 	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then 		voysitename = entity:getSitelink("enwikivoyage") or "" 		if voysitename ~= nil and voysitename ~= "" then 			name = "[[" .. voysitename  .."]]" 		end 	end  -- testing an idea can be removed if not wanted 	wiki = "enwiki" 	xtraname = "" 	xtraname = entity:getSitelink(wiki) or ""			-- If blank as is in many cases skip adding link to description  	description = mw.wikibase.description(entity.id) 	if description == "" or description == nil then 		description = "" 	end  if str.len(xtraname .. description) <= 15 then   -- arbitrary bending of the rules to make images in box nicer 	description = description .. ' &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' end  	part1 = '\n\t' .. '{' .. '\n\t' .. '"type": "Feature",' .. '\n\t\t' .. '"properties": {' if xtraname ~= "" then     part2 = '\n\t\t\t' .. '"description": "'.. image .. ' ' .. name .. ' &mdash; (w:[[:w:' .. xtraname .. '|' .. xtraname .. ']])' .. ' ' .. description .. '",' else     part2 = '\n\t\t\t' .. '"description": "'.. image .. ' ' .. name .. ' &mdash;' .. ' ' .. description .. '",' end      part3 = '\n\t\t\t' .. '"title": "' .. name .. '",' 	part4 = '\n\t\t\t' .. markersymbol     part5 = '\n\t\t\t' .. '"marker-size": "medium",'     part6 = '\n\t\t\t' .. markercolor     part7 = '\n\t\t' .. '},' .. '\n\t\t' .. '"geometry": {' .. '\n\t\t\t' .. '"type": "Point",' .. '\n\t\t\t' .. '"coordinates": ['     part8 = '\n\t\t\t' .. long .. ',' .. '\n\t\t\t' .. lat .. '\n\t\t\t' .. ']' .. '\n\t\t'.. '}' .. '\n\t' .. '},'     text = part1 .. part2 .. part3 .. part4 .. part5 .. part6 .. part7 .. part8 	return text end -- END Function  -- Make a marker --  function p.initmarker(frame) --    if frame.args[1]~=nil and frame.args[1]~='' then --        return frame.args[1] --    end 	local arg1 = frame.args[1] or '' 	local arg2 = frame.args[2] or 'red'     local entity = mw.wikibase.getEntityObject(arg1)     if entity == nil then return end 	local claims = entity.claims 	if claims == nil then 		return 		end 	local listing = "" 	local type = arg2 	local name = "" 	local url = "" 	local latitude = "" 	local longitude = "" 	local image = "" 	local description = "" 	-- name 	name = mw.wikibase.sitelink(arg1) 	if name == "" or name == nil then 		name = mw.wikibase.label(arg1) 	end 	-- url 	if claims.P856 ~= nil then 		url = entity.claims.P856[1].mainsnak.datavalue.value 		url = string.gsub(url,"%,.*","") -- KEEP ONLY ONE 		if url == nil or url == "" then 			url = "" 		end 	end 	-- coordinates 	if claims.P625 ~= nil then 		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 		if latitude == nil or latitude == "" then 			latitude = "" 			end 		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 		if longitude == nil or longitude == "" then 			longitude = "" 			end 	end 	-- image 	if claims.P18 ~= nil then 		image = entity.claims.P18[1].mainsnak.datavalue.value 		if image == nil then 			image = "" 			end 	end 	-- description 	description = mw.wikibase.description(entity.id) 	if description == "" or description == nil then 		description = "" 	end	  	marker = "{{marker\n| type=" .. type .. "\n| zoom=13\n| wikidata=" .. arg1 .. "\n| name=" .. name .. "\n| url=" .. url .. "\n| lat=" .. latitude .. "\n| long=" .. longitude.. "\n| image=" .. image .. "}} &mdash; " .. description	 	 	return marker  end  function p.initlisting(frame) --    if frame.args[1]~=nil and frame.args[1]~='' then --        return frame.args[1] --    end 	local arg1 = frame.args[1] or '' 	local arg2 = frame.args[2] or 'see'     local entity = mw.wikibase.getEntityObject(arg1)     if entity == nil then return end 	local claims = entity.claims 	if claims == nil then 		return 		end 	local listing = "" 	local type = arg2 	local name = "" 	local alt = "" 	local url = "" 	local email =  "" 	local wiki = "" 	local name = "" 	local wikidata = arg1 	local wikiname = "" 	local address = "" 	local directions = "" 	local phone = "" 	local tollfree = "" 	local fax = "" 	local hours = "" 	local price = "" 	local checkin = "" 	local checkout = "" 	local latitude = "" 	local longitude = "" 	local image = "" 	local description = "" 	local lastedit = "" 	 	 	-- get wikipedia name 	lang = mw.language.getContentLanguage(arg1).code	 	wiki = lang .. "wiki" 	wikiname = entity:getSitelink(wiki) or "" 	-- name 	name = mw.wikibase.sitelink(arg1) 	if name == "" or name == nil then 		name = mw.wikibase.label(arg1) 	end 	-- url 	if claims.P856 ~= nil then 		url = entity.claims.P856[1].mainsnak.datavalue.value 		url = string.gsub(url,"%,.*","") -- KEEP ONLY ONE 		if url == nil or url == "" then 			url = "" 		end 	end 	-- coordinates 	if claims.P625 ~= nil then 		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 		if latitude == nil or latitude == "" then 			latitude = "" 			end 		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 		if longitude == nil or longitude == "" then 			longitude = "" 			end 	end 	-- image 	if claims.P18 ~= nil then 		image = entity.claims.P18[1].mainsnak.datavalue.value 		if image == nil then 			image = "" 			end 	end 	-- description 	description = mw.wikibase.description(entity.id) 	if description == "" or description == nil then 		description = "" 	end	  	local part1 = "{{" .. type .. "\n| name=" .. name .. " | alt= " .. alt .. "| wikidata=" .. wikidata .. "| wikipedia=" .. wikiname 	local part2 = "\n| email=" .. email .. " | address=" .. address .. " | directions=" .. directions 	local part3 = "\n| phone=" .. phone .. " | tollfree=" .. tollfree .. " | fax=" .. fax 	local part4 = "\n| hours=" .. hours .. " | price=" .. price .. " | checkin=" .. checkin .. " | checkout=" .. checkout 	local part5 ="\n| url=" .. url .. "\n| lat=" .. latitude .. "\n| long=" .. longitude 	local part6 ="\n| image=" .. image .. "| content=" .. description .. "}}\n" 	 	listing = part1 .. part2 .. part3 .. part4 .. part5 .. part6  	return listing  end  function p.getwiki(frame) 	local wikip = "" 	local asitelink = "" 	local lang = "" 	local commons = "" 	local quotelink = "" 	local output = "" 	local arg1 = frame.args[1] or "" 	if arg1 == nil or arg1 == "" then return end 	local item = mw.wikibase.getEntityObject(arg1) 	if item == nil or item == "" then return end 	lang = mw.language.getContentLanguage(arg1).code 	if lang ~= nil and lang ~= "" then 		asitelink = lang .. "wiki" 		asitelink = item:getSitelink(asitelink) 		if asitelink ~= nil and asitelink ~= "" then 			asitelink = "[[w:" .. lang .. ":" .. asitelink .. "|W]] " 		end 		quotelink = lang .. "wikiquote" 		quotelink = item:getSitelink(quotelink) 		if quotelink ~= nil and quotelink ~= "" then 			quotelink = "[[q:" .. lang .. ":" .. quotelink .. "|Q]] " 		end 	end 	local claims = item.claims 	if claims ~= nil and claims ~= "" then 		commons = item.claims.P373[1].mainsnak.datavalue.value 		if commons ~= nil and commons ~= "" then 			commons = "[[c:" .. commons .. "|C]] " 			end 		end 	output = asitelink .. commons .. quotelink 	output = string.gsub(output,"%s+","")		-- just for cleaning up since outputting 3 variables as one 	output = string.gsub(output," $","")		-- getting rid of ending space 	return output end   function p.tocheaders3(frame) 	 		local page = frame.args[1]          local title = mw.title.new(page)         if title == nil then return end          if title.id == 0 then             return "Page does not exist!"         end          local data = title:getContent() if data == nil or data == "" then 	return end   data = string.gsub(data,"\n","@@@@@") data = string.gsub(data,"@@@@@@@@@@","@@@@@") 	local tt = {} 	local count = 0 	local output = "\n: [[" .. page .. "]]\n"  	local separator = "@@@@@" 	for str in string.gmatch(data,"([^"..separator.."]+)") do 		if str ~= nil and str ~= "" then 			 if string.find(str, '^%=') == 1 then			-- not just an ='s sign but one at beginning of line 				count = count + 1 				tt[count] = str 			end 		end 	end  	local part1 = "" 	local part2 = "" 	local part2a = ""  	for key,value in pairs(tt) do 		value = mw.text.unstrip(value) 		value = string.gsub(value,"%[","") 		value = string.gsub(value,"%]","") 		value = string.gsub(value,"^%s+","")   -- remove lead spaces 		value = string.gsub(value,"%=%s","%=") 		value = string.gsub(value,"%s+$"," ")  -- change multiple spaces to " " 		value = string.gsub(value,"%=+$","")   -- remove trailing = 		value = string.gsub(value,"%+$","")   -- remove trailing spaces 		value = string.gsub(value,"^%=%=%=%=%=%=","::::::")  -- change leading = to : 		value = string.gsub(value,"^%=%=%=%=%=",":::::")  -- change leading = to : 		value = string.gsub(value,"^%=%=%=%=","::::")  -- change leading = to : 		value = string.gsub(value,"^%=%=%=",":::")  -- change leading = to : 		value = string.gsub(value,"^%=%=","::")  -- change leading = to : 		value = string.gsub(value,"^%=",":")  -- change leading = to : 		part1 = string.gsub(value,"^(%:+)(.*)","%1") 		part2 = string.gsub(value,"^(%:+)(.*)","%2") 		if value ~= nil and value ~= "" then 			part2a = string.gsub(part2," ","_") --			output = output .. part1 .. "[http://localhost/wiki/index.php/" .. page .. "#" .. part2a .. " " .. part2 .. "]\n" 			output = output .. part1 .. "[[" .. page .. "#" .. part2 .. "|" .. part2 .. "]]" .. "\n" 		end 	end 	return output end  -- Load a page and scan it for images and produce a gallery  function p.getsomeimages(frame) 		local page = frame.args[1] or "Main Page" 		local flags = frame.args['flags'] or "n" 		if flags ~= "y" then flags = "n" end       -- Images from {{flag|name}} as in embassies -- y or n         local title = mw.title.new(page)         if title == nil then return end          if title.id == 0 then             return "Page does not exist!"         end          local data = title:getContent() 		 		if data == nil or data == "" then 			return 		end  		local tt = {} 		local count = 0 		local output = "" 		local separator = "@@@@@" 		local newstr = ""		 		 		local imagechecklist = {'jpg','JPG','jpeg','JPEG','jpe','JPE','png','PNG','apng','APNG','svg','SVG','TIF','tif','TIFF','tiff'} 		 		data = string.gsub(data,'%{%{%s*pagebanner%s*%}%}','') 				--get ride of {{pagebanner}} 		data = string.gsub(data,"@","BULLET")								--because I use @@@@@ as a separator changing @ to BULLET 		data = string.gsub(data,"%s+"," ")									--change multiple spaces to a space 		data = string.gsub(data,"\n","@@@@@")								--change \n to separator @@@@@ 		data = string.gsub(data,'%s*%=%s*','=')								--get rid of spaces around = signs --      special case regionmap image		 		data = string.gsub(data,'regionmap%s*%=%s*@@@@@',"") 		data = string.gsub(data,'regionmap%s*%=%s*','@@@@@[[File:')			--if regionmap then put separator @@@@@ plus [[File:  		-- to consider getting images from quickbar (flag,location) 		-- | flag = Flag of India.svg 		-- | location = LocationIndia.png {{quickbar| location= 		data = string.gsub(data,"flag%s*%=%s*@@@@@","") 		data = string.gsub(data,"flag%s%=%s*%|","") 		data = string.gsub(data,"flag%s*%=%s*","@@@@@[[File:") 		data = string.gsub(data,"location%s*%=%s*@@@@@","") 		data = string.gsub(data,"location%s*%=%s*%|","") 		data = string.gsub(data,"location%s*%=%s*","@@@@@[[File:")  		-- ie. {{pagebanner}} or {{pagebanner|TajMahal Banner.jpg|caption=Taj Mahal}} 		-- ie. {{pagebanner|pgname=aaaaaa|named banner.jpg}} etc will not work in this case figure out when going through for loop?? 		data = string.gsub(data,'%{%{%s*pagebanner%s*','@@@@@PAGEBANNERFIX')  -- Issue with SPARQL code - test to see if can eliminate in checking -- may need to refine further -- sample:(concat(?stateLabel, '\\n', '[[File:', substr(str(?img), 52, 100), '|200px]]') as ?description) data = string.gsub(data,"%'%[%[File%:%'%,","SPARQL") data = string.gsub(data,"%]%]%'%)","XSPARQL") 		--     area for flags as found in embassies? {{flag|Afghanistan}} -- make template break up with separator @@@@@ 		data = string.gsub(data,'%{%{%s*flag%s*%|','@@@@@{{flag|') 		data = string.gsub(data,'%{%{%s*listing','@@@@@{{listing') 		 		-- try and get images from routebox - special set 		data = string.gsub(data,'%{%{%s*routebox','@@@@@{{routebox') 		data = string.gsub(data,'image...%s*%=%s*','image=')					--picks up image1= or image10= or image10a 		data = string.gsub(data,'image..%s%=%s*','image=') 		data = string.gsub(data,'image.%s*%=%s*','image=')  		-- also consider see,buy,drink,marker etc. as in listing above      -- drop empties data = string.gsub(data,'image%=%}%}','') 		data = string.gsub(data,'image%=@@@@@','@@@@@') 		data = string.gsub(data,'%s*image%=%s*%|','') 		data = string.gsub(data,'image%s*%=%s*image%s*%=%s*','image=')		-- change image=image= to image= 		data = string.gsub(data,'image%s*%=%s*File%:%s*','image=WHAMMO')			-- change image=File: to image= (Sometimes File may be in another language 		data = string.gsub(data,'%s*image%=%s*@@@@@%|','')					-- more cleanup -- also other languages to consider 		data = string.gsub(data,'%s*image%=%s*@@@@@%}','') --		data = string.gsub(data,'%s*image%=','@@@@@[[File:')				-- duplicate see below 		data = string.gsub(data,"%[%[%s*File:%s*","@@@@@[[File:") 		data = string.gsub(data,"%[%[%s*file:%s*","@@@@@[[File:") 		data = string.gsub(data,"%[%[%s*image:%s*","@@@@@[[File:") 		data = string.gsub(data,"%[%[%s*Image:%s*","@@@@@[[File:") 		data = string.gsub(data,'%s*image%=','@@@@@[[File:')		 -- simply setting up the breakup of data using separator 																	 -- Issue with names like Budapest districts WV map.svg 2.0.png 																	  -- Single exception found to -- if many more then need to figure a way around this rather unique situation 		data = string.gsub(data,'Budapest districts WV map%.svg 2%.0.png',"Budapest districts WV map.DUMBFIX 2.0.png")  		data = string.gsub(data,'%.jpg','.jpg|border|250px]]@@@@@')  -- original prep for images remove |border|250px 		data = string.gsub(data,'%.JPG','.JPG|border|250px]]@@@@@') 		data = string.gsub(data,'%.PNG','.PNG|border|250px]]@@@@@') 		data = string.gsub(data,'%.png','.png|border|250px]]@@@@@') 		data = string.gsub(data,'%.SVG','.SVG|border|250px]]@@@@@') 		data = string.gsub(data,'%.svg','.svg|border|250px]]@@@@@') 		data = string.gsub(data,'%.jpeg','.jpeg|border|250px]]@@@@@') 		data = string.gsub(data,'%.JPEG','.JPEG|border|250px]]@@@@@') 		data = string.gsub(data,'%.tif','.tif|border|250px]]@@@@@')		-- add .tif image  -- return exception back to original 		data = string.gsub(data,'Budapest districts WV map%.DUMBFIX 2%.0.png',"Budapest districts WV map.svg 2.0.png") 		 		data = string.gsub(data,"@@@@@@@@@@","@@@@@")					-- getting rid of blank breakup 		data = string.gsub(data,"@@@@@@@@@@","@@@@@")  		for str in string.gmatch(data,"([^"..separator.."]+)") do  			if str ~= nil and str ~= "" then 				if string.find(str,'PAGEBANNERFIX') ~= nil then			--  caption=sometext pgname=sometext diasambig=yes star=yes dotm=yes otb=yes ftt=yes unesco=yes 																		--  toc=black or white notoc=true index=yes fop=yes -- remove to gettheimage???? 					str = string.gsub(str,'%|%a*%=','DELETEME=') 					newstr = "" 					if string.find(str,'DELETEME') ~= nil then 						for str2 in string.gmatch(str,"([^".."|".."]+)") do 							str2 = string.gsub(str2,'DELETEME.*',"") 							if str2 ~= nil then 								newstr = newstr .. "|" .. str2 								end 						end 					str = string.gsub(newstr,'%|PAGEBANNERFIX%|','[[File:') 						end	 					str = string.gsub(str,'PAGEBANNERFIX%|','[[File:')   				end				 				 				str = string.gsub(str,'%s*$','')       					-- drop ending space 				str = string.gsub(str,'File:%s*%}%}','') 				-- JUNKY FIX NEED SOLUTION TO A DISTINCT UNIQ ISSUE 				if string.find(str,'^%{%{flag%|.*%}%}') == 1 then 					str = string.gsub(str,'%{%{flag%s*%|%s*(.*)%}%}.*',"[[File:Flag of %1.svg]]") -- template puts in "the"     				if flags=="n" then str = "" end 					end 					if string.find(str, '^%[%[File:') == 1 then			-- Key is to have [[File:image...]] 					    str = string.gsub(str,'%_'," ") 						str = string.gsub(str,'%%2C',",") 					    count = count + 1 						tt[count] = str 						end 				end 		end  		table.sort(tt)  					-- BUILD A GALLERY OF PICTURES 		local check = "" 		local previous = "" 		local galleryfile = "" 		for key,value in pairs(tt) do 			if value ~= previous then 				-- Check if ^[[File:.*%.jpg or JPG or jpg or jpeg or JPEG or PNG or png or SVG or svg or tif]]$ 				for i,checker in ipairs(imagechecklist) do 					check = "^%[%[File:.*" .. checker .. "%]%]$" 					if string.gmatch(value,check) then 						galleryfile=value 						galleryfile=string.gsub(galleryfile,'%[%[File:%s*','File:') 						galleryfile=string.gsub(galleryfile,'%|.*$','') 						galleryfile=string.gsub(galleryfile,'%]%]','') -- Special case image=WHAMMO as image=File:somename is an error - in order to pick it up easier using this as test in gallery output -- instead of outputting File:somename which will work - just output name galleryfile=string.gsub(galleryfile,'WHAMMO','image=File:') -- Special case as well image name surrounded by \" -- have to change to "somename" - \" needed for maplink/mapframe - kartographer -- only dealing with one such known case - if more develop then will just replace \\" with" galleryfile=string.gsub(galleryfile,'\\"kirti mandir\\".jpg','"kirti mandir".jpg')  						output = output .. galleryfile .. "\n" 						break 						end 					end 					previous = value 			end 		end		 		output = string.gsub(output,"\n$","") 		output = string.gsub(output,"BULLET","@")		 --  return '<gallery mode="packed">\n' .. output .. "\n</gallery>" 	return '<gallery  widths=150px heights=150px perrow=6>\n' .. output .. "\n</gallery>" end    local function latitude(wikidata) 	local latitude = ""     local entity = mw.wikibase.getEntityObject(wikidata)	 	if entity == nil then return latitude end    		 	local claims = entity.claims 	if claims == nil then 		return latitude 	end	 	if claims.P625 ~= nil then 		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 		return latitude 	end 	return latitude end  --  GET LONGITUDE -- P625  local function longitude(wikidata) 	local longitude = ""     local entity = mw.wikibase.getEntityObject(wikidata)	 	if entity == nil then return longitude end    		 	local claims = entity.claims 	if claims == nil then 		return longitude 	end	 	if claims.P625 ~= nil then 		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 		return longitude 	end 	return longitude end   function p.games(frame) local data = frame.args[1] local wikidata = "" local lat = "" local long = "" local lang = "" local wiki = "" local wikipedia = ""  data = string.gsub(data,'\n','@@@@@NEWLINE') data = string.gsub(data,'%s*%|%s*','@@@@@') data = string.gsub(data,'%s*%=%s*','=') data = string.gsub(data,'%}%}','@@@@@}}')  if string.find(data,'.*wikidata%=Q%d+.*') == 1 then 		wikidata = string.gsub(data,'.*@@@@@wikidata%=(Q%d+).*',"%1")    		local entity = mw.wikibase.getEntityObject(wikidata)    		if entity ~= nil then     			lang = mw.language.getContentLanguage(wikidata).code	     		wiki = lang .. "wiki"     		wikipedia = entity:getSitelink(wiki) or ""		 			lat = latitude(wikidata) or "" 			long = longitude(wikidata) or "" 		end  if string.find(data,'wikipedia%=') == nil and wikipedia ~= " " then data = string.gsub(data,'}}','@@@@@wikipedia%='..wikipedia..'}}') else data = string.gsub(data,'wikipedia%=@@@@@','wikipedia%='..wikipedia..'@@@@@') end   		if string.find(data,'lat%s*%=%s*%d') == nil and lat ~= "" then -- check for lat=n and long=n 			data = string.gsub(data,'lat%=','lat='..lat) 		end 		if string.find(data,'lat%=') == nil and lat ~= "" then			-- no lat= something then add parameter 			data = string.gsub(data,'}}','@@@@@lat='..lat..'}}') 		end 		if string.find(data,'long%s*%=%s*%d') == nil and long ~= "" then		 			data = string.gsub(data,'long%=','long='..long) 		end 		if string.find(data,'long%=') == nil and long ~= "" then		-- no long then add parameter 			data = string.gsub(data,'}}','@@@@@long='..long..'}}') 		end end 		data = string.gsub(data,'@@@@@@@@@@','@@@@@') 		data = string.gsub(data,'@@@@@}}','}}') 		data = string.gsub(data,'NEWLINE@@@@@','\n| ') 		data = string.gsub(data,'@@@@@NEWLINE','\n') 		data = string.gsub(data,'@@@@@',' | ') 		data = string.gsub(data,'NEWLINE','\n') return data  end  function p.games2(frame) 	local list = frame.args['list'] or "" 	local data = "" 	local separator = "," 	local name = "" 	if list ~= nil and list ~= "" then 		list = string.gsub(list,"%s","") 	else 		return "" 	end 	 	local index = 1 	local items = {} 	local flags = {}  	for str in string.gmatch(list,"([^"..separator.."]+)") do 		items[index] = str 		index = index + 1 		end 		 	for i=1,#items do 		if not flags[items[i]] then 			flags[items[i]] = true 			name = "" 			name = mw.wikibase.sitelink(items[i]) 	       if name == "" or name == nil then 	        	name = mw.wikibase.label(items[i]) or "" 			end 			data = data .. items[i] .. " - " .. name .. "XNEWLINEX" 		end 	end data = string.gsub(data,'XNEWLINEX','</br>') return data  end  --* {{see --| name=Akhaura Checkpost | alt= | url= | email= --| address= | lat=23.838611 | long=91.254444 | directions= --| phone= | tollfree= | fax= --| hours= | price= --| content=It handles the largest number of visitors to and from neighbouring Bangladesh. --}} -- dont forget to include a mapframe for the maplinks to work on -- <mapframe latitude="24.3" longitude="74.4" zoom="5" width="400" height="400" group="locations" show="see,do,buy,eat,drink,sleep,go,site,other"/>  -- local function loadchecklist() 	local checklist = {'see','do','buy','eat','drink','sleep','city','vicinity','go','site','around','other','gold','lime','magenta','mediumaquamarine','orange','plum','red','silver','unknown'}	       return checklist end   local function loadcolors() 	local colors = {}		-- table of colors much of which can be used in marker or listings - based on type 	colors['see'] = "#4682B4" 	colors['do'] = "#808080"	 	colors['buy'] = "#008080"	 	colors['eat'] = "#D2691E" 	colors['drink'] = "#000000"	 	colors['sleep'] = "#000080" -- made extras as people tend to mix marker stuff with listing stuff 	colors['city'] = "#0000FF" 	colors['vicinity'] = "#800000" 	colors['go'] = "#A52A2A" 	colors['view'] = "#4169E1" 	colors['site'] = "#CD2626" 	colors['around'] = "800080" 	colors['other'] = "#228B22" -- by color 	colors['gold'] = "#FFD700" 	colors['lime'] = "#00FF00" 	colors['magenta'] = "#FF00FF" 	colors['mediumaquamarine'] = "#66CDAA" 	colors['orange'] = "#FFA500" 	colors['plum'] = "#DDA0DD" 	colors['red'] = "#FF0000" 	colors['silver'] = "#C0C0C0" 	colors['unknown'] = "#FF00FF"     return colors	 	end 	 -- can also create symbols if we dont want to number them which I like better -- right now limited symbols - use of numbers greater -- Maki symbols not available local function loadsymbols() 	local symbols = {} 	symbols['see'] = "star" 	symbols['do'] = "marker"	 	symbols['buy'] = "shop"	 	symbols['eat'] = "restaurant" 	symbols['drink'] = "bar"	 	symbols['sleep'] = "lodging" -- made extras as people tend to mix marker stuff with listing stuff 	symbols['city'] = "city" 	symbols['vicinity'] = "town" 	symbols['go'] = "suitcase" 	symbols['site'] = "monument"	 	symbols['other'] = "triangle" 	return symbols end local function imagex(id) 	local id = id 	local image = ""     local entity = mw.wikibase.getEntityObject(id)	 	if entity == nil then return "" end  	local claims = entity.claims 	if claims == nil then 		return image 	end		 	if pcall(function () t = claims.P18 end) then 		if pcall(function () t = entity.claims.P18[1].mainsnak.datavalue.value end ) then		 			image = entity.claims.P18[1].mainsnak.datavalue.value 			return image 			end 	end 	return image end	  -- getting lat long via passing an ID local function latitudex(id) 	local latitude = "" 	local arg1 = id     local entity = mw.wikibase.getEntityObject(arg1)	 	if entity == nil then return latitude end    		 	local claims = entity.claims 	if claims == nil then 		return latitude 	end	 	if claims.P625 ~= nil then 		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 		return latitude 	end 	return latitude end  --  GET LONGITUDE -- P625  local function longitudex(id)  	local longitude = "" 	local arg1 = id     local entity = mw.wikibase.getEntityObject(arg1)	 	if entity == nil then return longitude end    		 	local claims = entity.claims 	if claims == nil then 		return longitude 	end	 	if claims.P625 ~= nil then 		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 		return longitude 	end 	return longitude end  function p.list2maplink(frame)      -- checklist has args for main listings but also those found in marker and sometimes used in listing templates 	local data = frame.args[1] or "" 	if data == "" then return data end  	local msymbol = frame.args['symbol'] or "n"     -- symbol=y then use from symbols table else use '-number' 	local separator = "@@@@@" 	local newdata = "" 	local color = "" 	local symbol = "" 	local group = "" 	local wikidata = "" 	local image = "" 	local latitude = "" 	local longitude = "" 	local content = "" 	local name = "" 	local lang = "" 	local wikipedia = "" 	local url = "" 	local counter = "" 	local checklist = loadchecklist()	 	local colors = loadcolors() 	local symbols = loadsymbols()  	data = string.gsub(data,"%@","BULLET") 	data = string.gsub(data,"%s*%|\n","|") 	data = string.gsub(data,"\n%s*%}%}","}}") 	data = string.gsub(data,"%s*%|%s*","|") 	data = string.gsub(data,"\n","@@@@@") 	for i,checker in ipairs(checklist) do 		data = string.gsub(data,"%{%{%s*"..checker,"{{listing|type="..checker) 	end     data = string.gsub(data,"%{%{%s*listing%|name%=",'{{listing|type=other|name=')     data = string.gsub(data,"%{%{%s*listing%|image%=",'{{listing|type=other|image=')    --if data ~= "" then return data end data = string.gsub(data,'%{%{listing','@@@@@{{listing') 	for str in string.gmatch(data,"([^"..separator.."]+)") do 		if string.find(str,'%{%{listing') == 1 then 			str = string.gsub(str,'%}%}$','|}}') 			str = string.gsub(str,'image%=%|','') 			str = string.gsub(str,'name%=%|','') 			str = string.gsub(str,'content%=%|','') 			str = string.gsub(str,'lat%=%|','') 			str = string.gsub(str,'long%=%|','') 			str = string.gsub(str,'url%=%|','')  			str = string.gsub(str,'wikipedia%=%|','')  -- I parameter counter= is empty then its a simple -number if counter=aaaa then its a -number-aaaa if string.find(str,'counter%=%|') then 	counter = "-number" else 	if string.find(str,'counter%=%|') then 		counter = string.gsub(str,'^.*counter%=','') 		counter = string.gsub(counter,'%|.*','') 	    counter = "-number-" .. counter -- alpha letters if counter=letter -- special case only - made up --- what about alpha groups (type) 	    if string.find(counter,'%-number%-letter') then 	    	counter = "-letter" 	    end 	 else 	 	counter = "" 	 end end 			if string.find(str,'name%=')  then 				name = string.gsub(str,'^.*name%=','') 				name = string.gsub(name,'%|.*','') 			else 				name = "" 			end 			if string.find(str,'wikipedia%=') then 				wikipedia = string.gsub(str,'^.*wikipedia%=','') 				wikipedia = string.gsub(wikipedia,'%|.*','') 				wikipedia = " [[w:enwiki:" .. wikipedia .."|" .. wikipedia .. "]]" 			end 			if string.find(str,'image%=')  then --	xxx			image = string.gsub(str,'^.*image%=','') image = string.gsub(str,'^.*%|image%=','') 				image = string.gsub(image,'%|.*','') --	xxx			image = '[[File:' .. image .. '|280px|link=]]' -- should not be necessary image = '[[File:' .. image .. '|280px|link=]]' -- should not be necessary 			else 				image = "" 			end	 			if string.find(str,'lat%=') then 				latitude = string.gsub(str,'^.*lat%=','') 				latitude = string.gsub(latitude,'%|.*','') 			else 				latitude = "" 				end						 			if string.find(str,'long%=') then 				longitude = string.gsub(str,'^.*long%=','') 				longitude = string.gsub(longitude,'%|.*','') 			else 				longitude = "" 			end 			if string.find(str,'wikidata%=') then	-- If wikidata and lat long ='s "" then get lat long from wikidata		 				wikidata = string.gsub(str,'^.*wikidata%=','') 				wikidata = string.gsub(wikidata,'%|.*','') if string.match(wikidata,"^[Qq]%d+$") ~= nil then -- if string.match(arg1,"^[Qq]%d+$") ~= nil then 					if latitude == "" then 						latitude = latitudex(wikidata) 					end 					if longitude == "" then 						longitude  = longitudex(wikidata) 					end 				end 			else 				wikidata = "" 			end  			if string.find(str,'content%=') then 				content = string.gsub(str,'^.*content%=','') 				content = string.gsub(content,'%|.*','') -- issue with double quotes as they will cause a JSON error - below should fix it list of others may be incorporated -- xxx				content = string.gsub(content,'%"','\"') 				content = string.gsub(content,'%"','\\"')  -- a blank image not needed as code has been fixed to handle how text comes out when -- one clicks on the marker -- this was precautionary -- --				if image == "" then  --					image = "[[File:3by2white.svg|280px 1px|link=]]" --					content = string.gsub(content,'^%s*','') --				end 			else 				content = "" 			end 			 			if string.find(str,'url%=') then 				url = string.gsub(str,'^.*url%=','') 				url = string.gsub(url,'%|.*','') 				url = "[" .. url .. " &nbsp;]" 			else 				url = "" 				end -- NOT MAKING A DEFAULT OF lat 0 and long 0 as this would bunch up a load of maplinks somewhere in Africa -- Have to have latitude and longitude to create a maplink -- or dropping creation of maplink from a listing 			if latitude ~= "" and longitude ~= "" then 				group = string.gsub(str,".*type%=(%a+)(%|.*)","%1") 				if colors[group] == nil then     -- solves two issues - if bad group then it becomes other and we get a color for it 					group = "other" 				end 				color = colors[group] 				if msymbol == "y" then			-- use a symbol from table for certain group (small list) for on a map 					symbol = symbols[group]		-- no numbers alpha or symbols appear on article page - dealing with maplinks not listing output 				else 					if counter ~= "" then		-- if counter= numbered on page then numbered on map instead - symbols are out???? 						symbol = counter 						if counter == "-letter" then 							symbol = "-letter" .. "-" .. group 							end 						else 						symbol = "-number" .. "-" .. group                 	end 				end  			newdata = newdata .. '\n<maplink class="no-icon" zoom="5" text="" latitude="' .. latitude .. '" longitude="' .. longitude .. '" group="' .. group .. '">' 			newdata = newdata .. '\n{\n\t"type": "Feature",\n\t"geometry": { "type":"Point", "coordinates":[' .. longitude .. ',' .. latitude ..  '] },' 			newdata = newdata .. '\n\t"properties": {\n\t "title": "' .. name .. '",\n' --	newdata = newdata .. '\t"description": "' .. image .. content .. url .. '",\n' 			newdata = newdata .. '\t"description": "' .. image .. name .. url .. "&mdash; " .. wikipedia .. " " .. content .. '",\n'			 			newdata = newdata .. '\t"marker-size": "medium",\n' 			newdata = newdata .. '\t"marker-color": "' .. color .. '",\n' 			newdata = newdata .. '\t"marker-symbol": "' .. symbol  .. '"\n' 			newdata = newdata .. '}\n}\n</maplink>' 			end 		end 	end 		 		newdata = string.gsub(newdata,"BULLET","@") -- return orignal input plus maplink(s) 		return frame.args[1] .. "\n" .. newdata  end  --* {{marker|type=vicinity|zoom=13 --| name=Mollem National Park --| lat=15.33390 | long=74.28835 --| image= --}} (Bhagwan Mahaveer Sanctuary and Mollem National Park), [[Goa]] &mdash; a pristine area diverse in flowering plant life and vegetation is habitat for many mammals, birds, butterflies and reptiles. The largest protected area in [[Goa]]. One can also find the ''Tambdi Surla Temple'', ''Tambdi Falls'' and other attractions here -- In progress  function p.marker2maplink(frame) 	local checklist = loadchecklist() 	local colors = loadcolors() 	local symbols = loadsymbols() 	local data = frame.args[1] or "" 	if data == "" then return data end 	local msymbol = frame.args['symbol'] or "n"     -- symbol=y then use from symbols table else use '-number' 	local separator = "@@@@@" 	local newdata = "" 	local color = "" 	local symbol = "" 	local group = ""     local type = "" 	local name = "" 	local latitude = "" 	local longitude = "" 	local zoom = "" 	local url = "" 	local image = ""     local wikidata = ""     local content = ""     local url = ""     local counter = ""        	data = string.gsub(data,"%@","BULLET") 	data = string.gsub(data,"%s*%|\n","|") 	data = string.gsub(data,"\n%s*%}%}","}}") 	data = string.gsub(data,"%s*%|%s*","|") 	data = string.gsub(data,"\n","@@@@@")  -- not to mess with &mdash; and text for now 	 	data = string.gsub(data,'%{%{marker','@@@@@{{marker') 	for str in string.gmatch(data,"([^"..separator.."]+)") do 		if string.find(str,'%{%{marker') == 1 then            if string.find(str,'%{%{%|type=') == nil then            	str = string.gsub(str,'%{%{marker','{{marker|type=other') -- make default type            end            str = string.gsub(str,'%}%}',"|}}")						  -- get end of marker add | to be able to pick out the pieces            str = string.gsub(str,'%s*%=%s*',"=") 			str = string.gsub(str,'image%=%|','') 			str = string.gsub(str,'name%=%|','') 			str = string.gsub(str,'lat%=%|','') 			str = string.gsub(str,'long%=%|','')             str = string.gsub(str,'url%=%|','')  			if string.find(str,'name%=') then 				name = string.gsub(str,'^.*name%=','') 				name = string.gsub(name,'%|.*','') 			else 				name = "" 			end	 			if string.find(str,'image%=')  then 				image = string.gsub(str,'^.*image%=','') 				image = string.gsub(image,'%|.*','') 				image = '[[File:' .. image .. '|280px|link=]]' 			else 				image = "" 			end  			if string.find(str,'lat%=') then 				latitude = string.gsub(str,'^.*lat%=','') 				latitude = string.gsub(latitude,'%|.*','') 			else 				latitude = "" 				end						 			if string.find(str,'long%=') then 				longitude = string.gsub(str,'^.*long%=','') 				longitude = string.gsub(longitude,'%|.*','') 			else 				longitude = "" 			end 			content = string.gsub(str,'^.*%}%}','')  -- last ditch attempt at content field for a marker - can be tricky - depends what text entered             content = string.gsub(content," &mdash; ","") content = string.gsub(content,'%[%[File.*$','')          -- some have an image in content which won't work 			content = string.gsub(content,'%"','\"') --			if image == "" then  --				image = "[[File:3by2white.svg|280px 1px|link=]]" --				content = string.gsub(content,'^%s*','') --			end 			if string.find(str,'wikidata%=') then	-- If wikidata and lat long ='s "" then get lat long from wikidata		 				wikidata = string.gsub(str,'^.*wikidata%=','') 				wikidata = string.gsub(wikidata,'%|.*','') 				if string.match(wikidata,"^[Qq]%d+$") ~= nil then				 					if latitude == "" then 						latitude = latitudex(wikidata) 					end 					if longitude == "" then 						longitude  = longitudex(wikidata) 					end 					if image == nil or image == "" then 				        image = imagex(wikidata) 				        if image ~= "" then 				            image = '[[File:' .. image .. '|280px|link=]]' 				          else 					        image = "" 			              end 			        end 				end 			else 				wikidata = "" 			end 			if string.find(str,'url%=') then 				url = string.gsub(str,'^.*url%=','') 				url = string.gsub(url,'%|.*','') 				url = "[" .. url .. " &nbsp;]" 			else 				url = "" 			end if string.find(str,'counter%=%|') then 	counter = "-number" else 	if string.find(str,'counter%=%') then 		counter = string.gsub(str,'^.*counter%=','') 		counter = string.gsub(counter,'%|.*','') 	    counter = "-number-" .. counter					-- in case counter has a name -- alpha letters if counter=letter -- special case only - made up --- what about alpha groups (type) 	    if string.find(counter,'%-number%-letter') then 	    	counter = "-letter" 	    end 	 else 	 	counter = "" 	 end end   			if latitude ~= "" and longitude ~= "" then 				group = string.gsub(str,".*type%=(%a+)(%|.*)","%1") 				if colors[group] == nil then     -- solves two issues - if bad group then it becomes other and we get a color for it 					group = "other" 				end 				color = colors[group] 				if msymbol == "y" then 					symbol = symbols[group] 				else if counter == "-letter" then 	symbol = "-letter" .. "-" .. group end 					symbol = "-number" .. "-" .. group 				end -- If counter parameter then it is all numbered either with -number or -number-xxxx -- Color is retained for the type or group  if counter ~= "" and counter ~= nil then symbol = counter end 			newdata = newdata .. '\n<maplink class="icon" zoom="5" text="' .. name .. '" latitude="' .. latitude .. '" longitude="' .. longitude .. '" group="' .. group .. '">' --			newdata = newdata .. '\n<maplink class="no-icon" zoom="5" text="" latitude="' .. latitude .. '" longitude="' .. longitude .. '" group="' .. group .. '">' 			newdata = newdata .. '\n{\n\t"type": "Feature",\n\t"geometry": { "type":"Point", "coordinates":[' .. longitude .. ',' .. latitude ..  '] },' 			newdata = newdata .. '\n\t"properties": {\n\t "title": "' .. name .. '",\n' 			newdata = newdata .. '\t"description": "' .. image .. content .. url .. '",\n' 			newdata = newdata .. '\t"marker-size": "medium",\n' 			newdata = newdata .. '\t"marker-color": "' .. color .. '",\n' 			newdata = newdata .. '\t"marker-symbol": "' .. symbol  .. '"\n' 			newdata = newdata .. '}\n}\n</maplink> ' .. content 			end          			 			 		end 	end    	return frame.args[1] .. "\n" .. newdata 	 end  function p.pagesincategory(frame) 	local arg1 = frame.args[1]     local entity = mw.wikibase.getEntityObject(arg1)     if entity == nil then return end     	local name=mw.wikibase.sitelink(entity.id) 		return '{{#categorytree:' .. name .. '|hideroot|namespaces="-"}}' end  function p.wikidataids(frame)  	local separator = "," 	local wikidatax = "" 	local list = frame.args['list'] or "" 	if list ~= nil and list ~= "" then 		list = string.gsub(list,"%s","") 	end 	local index = 1 	local items = {} 	local flags = {}  	for str in string.gmatch(list,"([^"..separator.."]+)") do 		items[index] = str 		index = index + 1 		end 		 	for i=1,#items do 		if not flags[items[i]] then 			flags[items[i]] = true 		wikidatax = wikidatax .. p.getwikidatax(items[i]) 		end 	end 	 	return "{|border=1\n" .. "! ID !! name !! countryID !! admin || lat !! long !! image !! wikipedia || wikivoyage !! Description \n|-\n" ..  wikidatax .. "|}"  end 	 function p.getwikidatax(str) 	local id = "" 	local name = "" 	local country = "" 	local lat = "" 	local long = "" 	local image = "" 	local wikiname = "" 	local voysitename = "" 	local description = "" 	local lang = "" 	local admin = "" 	 	if string.match(str,"^[Qq]%d+$") == nil then return "" end    	local entity = mw.wikibase.getEntityObject(str)  	if entity == nil then return "" end    		 	local claims = entity.claims 	if claims == nil then 		return "" 	end	  	id = str 	 	name = mw.wikibase.sitelink(str) 	if name == "" or name == nil then 		name = mw.wikibase.label(str) or "" 	end	  if pcall(function () t = entity.claims.P17[1].mainsnak.datavalue.value end) then 	for k, v in pairs( entity.claims.P17[1].mainsnak.datavalue.value ) do 		if k == "numeric-id" then 			country = country .. "Q" .. v 		end 	end      if country ~= "" then country = "[[D:" .. country .. "|" .. country .. "]] - " .. mw.wikibase.label(country) end end  	if pcall(function () t = claims.P625 end) then 		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		 			lat = entity.claims.P625[1].mainsnak.datavalue.value.latitude 			end 		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			 			long = entity.claims.P625[1].mainsnak.datavalue.value.longitude 			end	 	end 	 		if lat ~= "" and lat ~= nil and long ~= "" and long ~= nil then 			lat = string.format("%.6f",lat) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000 			long = string.format("%.6f",long) -- format number to 6 decimal places see above 			lat = string.gsub(lat,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1. 			long = string.gsub(long,"0+$","") -- string any number of ending zeroes - see above 			late = string.gsub(lat,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1 			long = string.gsub(long,"%.$","") -- strip an ending period 		end 		 	if pcall(function () t = claims.P18 end) then 		if pcall(function () t = entity.claims.P18[1].mainsnak.datavalue.value end ) then		 			image = entity.claims.P18[1].mainsnak.datavalue.value 			end 	end  -- Keeping only 1st value for administrative entity  	if pcall(function () t = claims.P131 end) then 		local t = {} 		if pcall(function () t = entity.claims.P131[1].mainsnak.datavalue.value end ) then		 			t = entity.claims.P131[1].mainsnak.datavalue.value 			for k, v in pairs( t ) do 				admin = v 				if not mw.wikibase.label(admin) then admin = "" break end 				if admin ~= "" and admin ~= nil then 					admin = "[[D:" .. admin .. "|" .. admin  .. "]] - " .. mw.wikibase.label(admin) 					break end 			end 			end 	end 	 	lang = mw.language.getContentLanguage(str).code	or "en" 	local wiki = lang .. "wiki" 	local wikiname = entity:getSitelink(wiki) or "" 	if wikiname ~= "" and wikiname ~= nil then 		wikiname = "[[w:" .. lang .. ":" .. wikiname .. "|" .. wikiname .. "]]" 		end  	description = mw.wikibase.description(entity.id) 	 	if description == "" or description == nil then 		description = "" 	end	 	 	voysitename = "" 	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then 		voysitename = entity:getSitelink("enwikivoyage") or "" 		if voysitename ~= nil and voysitename ~= "" then 			voysitename = "[[" .. voysitename  .."]]" 		end 	end	  if id ~= "" and id ~= nil then 	id = "[[D:" .. id .. "|" .. id .. "]]" end  	return "\n| " .. id .. " || " .. name .. " || " .. country .. " || " .. admin .. " || " .. lat .. " || " .. long .. " || " .. image .. " || " .. wikiname .. " || " .. voysitename .. " || " .. description .. "\n|-\n" 	 end  -- Create basic initial listings to work on in editor - can add more later -- Not all parameters are filled just the basic ones  function p.wikidatalistings(frame)  	local separator = "," 	local wikidatax = "" 	local counter = 0 	local interim = "" 	local list = frame.args['list'] or "" 	local listingtype = frame.args['type'] or "see" 	if list ~= nil and list ~= "" then 		list = string.gsub(list,"%s","") 	end 	local index = 1 	local items = {} 	local flags = {}  	for str in string.gmatch(list,"([^"..separator.."]+)") do 		items[index] = str 		index = index + 1 		end 		 	for i=1,#items do 		if not flags[items[i]] then 			flags[items[i]] = true interim = p.getwikidataxlistings(items[i],listingtype) if interim ~= "" then wikidatax = wikidatax .. interim end --- For future use as numbers only go to 99  counter = counter + 1									   --- May want to change listing type or color --		wikidatax = wikidatax .. p.getwikidataxlistings(items[i],listingtype) 		end 	end 	 	return wikidatax  end 	  function p.getwikidataxlistings(str,listingtype) --	local alt = "" --	local email =  "" --	local address = "" --	local directions = "" --	local phone = "" --	local tollfree = ""		-- THESE PARAMETERS ARE NOT INCLUDED IN MAKING INITIAL BASIC LISTING --	local fax = "" --	local hours = "" --	local price = "" --	local checkin = "" --	local lastedit = "" 							-- THESE PARAMETERS ARE INCLUDED	 	local id = "" 	local name = "" 	local url = "" 	local country = "" 	local lat = "" 	local long = "" 	local image = "" 	local wikiname = "" 	local voysitename = "" 	local description = "" 	local wiki = "" 	local lang = "" 	 -- This is to allow this one function to be called separately from a list 	if type(str) == "table" then str = str.args[1] end 	local listingtype = listingtype or "see" 	if string.match(str,"^[Qq]%d+$") == nil then return "" end    	local entity = mw.wikibase.getEntityObject(str)  	if entity == nil then return "" end    		 	local claims = entity.claims 	if claims == nil then 		return "" 	end	  	id = str 	 	name = mw.wikibase.sitelink(str) 	if name == "" or name == nil then 		name = mw.wikibase.label(str) or "" 	end	 	if claims.P856 ~= nil then 		url = entity.claims.P856[1].mainsnak.datavalue.value 		url = string.gsub(url,"%,.*","") -- KEEP ONLY ONE 	end 		 	if pcall(function () t = claims.P625 end) then 		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		 			lat = entity.claims.P625[1].mainsnak.datavalue.value.latitude 			end 		if pcall(function () t = entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then			 			long = entity.claims.P625[1].mainsnak.datavalue.value.longitude 			end	 	end -- format lat and long	 			if lat ~= "" and lat ~= nil and long ~= "" and long ~= nil then 			lat = string.format("%.6f",lat) -- format number to 6 decimal places ie. 10.00 becomes 10.000000 ie. 12.345 becomes 12.345000 ie. 1 becomes 1.000000 			long = string.format("%.6f",long) -- format number to 6 decimal places see above 			lat = string.gsub(lat,"0+$","") -- strip any number of ending zeroes - 10.000000 becomes 10. 12.345000 becomes 12.345 1.000000 becomes 1. 			long = string.gsub(long,"0+$","") -- string any number of ending zeroes - see above 			late = string.gsub(lat,"%.$","") -- strip and ending period - 10. becomes 10, 12.345 remains and 1. becomes 1 			long = string.gsub(long,"%.$","") -- strip an ending period 		end 		 	if pcall(function () t = claims.P18 end) then 		if pcall(function () t = entity.claims.P18[1].mainsnak.datavalue.value end ) then		 			image = entity.claims.P18[1].mainsnak.datavalue.value 			end 	end      lang = mw.language.getContentLanguage(arg1).code	 	wiki = lang .. "wiki" 	wikiname = entity:getSitelink(wiki) or ""  	description = mw.wikibase.description(entity.id) 	 	if description == "" or description == nil then 		description = "" 	end	 	 	voysitename = "" 	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then 		voysitename = entity:getSitelink("enwikivoyage") or "" 		end  if voysitename ~= "" and voysitename ~= nil then 	name = "[[" .. voysitename .. "|" .. name .. ']]' end  	return '\n* {{listing|type=' .. listingtype .. '|name=' .. name .. '|url=' .. url .. '|wikidata=' .. id .. '|wikipedia=' .. wikiname .. '|image=' .. image .. '|lat=' .. lat .. '|long=' .. long .. '|content=' .. description .. '}}'	 	 end    -- gpxmaplink function -- {{safesubst:#invoke:Gpx|gpxmaplink|Test100|maplink=no|lat=65|long=102}} -- This module produces <maplinks> - considering argument to produce a <mapframe> will all contained as one <mapframe> -- Will create a maplink for each segment from a GPX file - will do up to 10 segments only. --      Most GPX template files contain at most 1-4 - a few have more. --      Single set of coordinates will produce a marker "Point" multiple coordinates will produce "LineString" -- colors are random -- all Points are the same color #ff33f3 whereas Lines are random --      can edit results as you see fit -- Arguments: -- "maplink=no" produces group segment of GPX coordinates only - default is "yes" is arg is missing --     and this will create Maplinks -- "lat=nnnn" - latitude otherwise a default is used (middle of Atlantic Ocean) -- "long=nnnn" - longitude otherwise default is used (middle of Atlantic Ocean) -- "set=n" or "set=all" = which group you want out of the track segments - 1 - 10 or all - all is default -- "info=" 'before or after' - some input files have <name> and <desc> after <trkseg> others after --      look at GPX file 1st then go ahead and add this arg. -- default is "before"   function one(xdata,part1,part2,part1a,part2a,name,description,color) 	name = string.gsub(name,'^.*<name>','') 	name = string.gsub(name,'</name>.*$','') 	description = string.gsub(description,'^.*<desc>','') 	description = string.gsub(description,'</desc>.*$','') 	if xdata ~= "" then 		local _, commacount = string.gsub(xdata, '%,', '') 		if commacount > 2 then 			xdata = '[' .. xdata 			xdata = string.gsub(xdata,'^$s+','') 			xdata = string.gsub(xdata,'],$',']],') 			xdata = part1 .. xdata .. part2 			xdata = string.gsub(xdata,'#00e500',color)  		else 			xdata = string.gsub(xdata,',$','') 			xdata = string.gsub(xdata,'^$s+','') 			xdata = part1a .. xdata .. part2a 		end 			xdata = string.gsub(xdata,'"title": ""','"title": "' .. name .. '"') 			xdata = string.gsub(xdata,'"description": ""','"description": "' .. description .. '"') 	end  return xdata  end  function two(vdata) 	vdata = string.gsub(vdata,'.*%<trkpt.*lat%=%"',"") 	vdata = string.gsub(vdata,'%".*lon=%"','ALTERNATE') 	vdata = string.gsub(vdata,'%".*','') 	vdata = string.gsub(vdata,'(.*ALTERNATE)(.*)','%2%,%1') 	vdata = string.gsub(vdata,'ALTERNATE','') 	vdata = '[' .. vdata .. '],' 	return vdata  end  function p.gpxmaplink(frame) 		local page = frame.args[1]                 if page == nil then return end                 local title = mw.title.new(page) 		local lat = frame.args['lat'] or "38.5" 		local long = frame.args['long'] or "38.5"                 local maplink = frame.args['maplink'] or "yes"                 local set = frame.args['set'] or "all"                 local info = frame.args['info'] or "before" 		local tt1 = {} 		local count = 0 		local separator = "@@@@@" 		local newdata = {} --local ele = "" --local elevation = {} --local checker = 0 		local finalnewdata = "" 		local names = {} 		local descriptions = {} 		local colors = {"#662200", "#dc90a9", "#989f4d", "#acedc1", "#b43a32", "#cbffd3", "#bdd52b", "#fbbfb4", "#5c5c5c", "#ffffff"} 		local name = ""                 local description = ""                 local part1 = ""                 local part2 = ""                 local part1a = ""                 local part2a = ""                 local datagroup = 0                 local goahead = 0           	if title == nil then return end          	if title.id == 0 then            	 return "Page does not exist!"        		end          	local data = title:getContent()  		if data == nil or data == "" then 			return 		end  		for i=0, 12 do       			names[i] = ""        			descriptions[i] = ""       			newdata[i] = ""     		end  		if maplink == "yes" then 			part1 = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" zoom="5" group="GPX">\n' 			part1 = part1 .. '{"type":\n\t"Feature","geometry":\n' 			part1 = part1 .. '\t{"coordinates":\n'  			part2 = '\n\t\t"type":"LineString"},' 			part2 = part2 .. '\n\t\t"properties":{' 			part2 = part2 .. '\n\t\t"title": "",' 			part2 = part2 .. '\n\t\t"description": "",' 			part2 = part2 .. '\n\t\t"stroke":"#00e500",' 			part2 = part2 .. '\n\t\t"stroke-width":3\n}}\n</maplink>\n'   			part1a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" zoom="5" group="Point">\n' 			part1a = part1a .. '{"type":\n"Feature","geometry":{ "type":"Point", "coordinates":'  			part2a = " },\n" 			part2a = part2a .. '\t"properties": {' 			part2a = part2a .. '\n\t\t"title": "",' 			part2a = part2a .. '\n\t\t"description": "",' 			part2a = part2a .. '\n\t\t"marker-size": "medium",' 			part2a = part2a .. '\n\t\t"marker-color": "#ff33f3",' 			part2a = part2a .. '\n\t\t"marker-symbol": "marker"\n}}</maplink>\n'  		end --data = string.gsub(data,'%s+%<%s+ele%s+%>','@@@@@<ele') --data = string.gsub(data,'%s+%<%s+/%s+ele%s+%>','</ele>@@@@@') -- prep for elevation - output maplink and pointers with elevation? future 		data = string.gsub(data,'%s+%<%s+name%s+%>','@@@@@<name') 		data = string.gsub(data,'%s+%<%s+/%s+name%s+%>','</name>@@@@@') 		data = string.gsub(data,'%s+%<%s+desc%s+%>','@@@@@<desc') 		data = string.gsub(data,'%s+%<%s+/%s+desc%s+%>','</desc>@@@@@') 		data = string.gsub(data,'%s+%<%s+trkseg%s+%>','@@@@@<trkseg') 		data = string.gsub(data,'%s+%<%s+/%s+trkseg%s+%>','</trkseg>@@@@@') 		data = string.gsub(data,'%s+%<%s+trkpt%s+%>','@@@@@<trkpt') 		data = string.gsub(data,'%s+%<%s+%/%s+trkpt%s+%>','</trkpt>@@@@@')  		data = string.gsub(data,'%/%>','/>@@@@@') 		data = data .. '@@@@@<trksegENDIT>@@@@@' 		data = string.gsub(data,"\n","@@@@@") 		data = string.gsub(data,"@@@@@@@@@@","@@@@@")   		local _, datagroup = string.gsub(data, "<trkseg>", "")  		if datagroup == 0 then return "no trkseg" end 			for i = 1,datagroup, 1 do 			data = string.gsub(data,"<trkseg>", "<trkseg" .. tostring(i) .. ">",1) 			end  		for line in string.gmatch(data,"([^"..separator.."]+)") do 	                tt1[count] = line                     count = count + 1 			end 		 		for k,v in pairs(tt1) do    		    if string.find(v,'<name>',1) ~= nil then          		name = v 		    end  --if string.find(v,'<trkpt>',1) ~= nil then --elevation[checker] = v --checker = checker + 1 --end --if string.find(v,'<ele>',1) ~= nil then -- prep for creating elevation maplink --	elevation[checker] = v --end      		    if string.find(v,'<desc>',1) ~= nil then          		description = v      		    end  		for i=1, 10 do 			if string.find(v,'<trkseg' .. tostring(i) .. '>',1) ~= nil then 				goahead = i 				names[1] = name 				name = "" 				descriptions[i] = description 				description = "" 				break 				end 		end       		   if string.find(v,'<trksegENDIT>',1) ~= nil then          		names['END'] = name          		name = "" 			descriptions['END'] = description 			description = ""      		   end       		   for i=1, 10 do          		   if goahead == i then                  		   if set == "1" or set == "all" then 		     		       if string.find(v,'<trkpt',1) ~= nil then                          		  v = two(v) 		        		  newdata[i] = newdata[i] .. v 		     		       end                 		   end           		   end      		   end  	end  -- END OF CYCLING THROUGH LINE BY LINE  	if info == "after" then 		for i=1, goahead do  			names[i] = names[i + 1] 			descriptions[i] = descriptions[i + 1] 		end 			names[goahead] = names['END'] 			descriptions[goahead] = descriptions['END'] 	end  	for i=1, goahead do         	newdata[i] = one(newdata[i],part1,part2,part1a,part2a,names[i],descriptions[i],colors[i])         end      	for i=1, goahead do 		finalnewdata = finalnewdata .. newdata[i] .. "\n"         end  	finalnewdata = string.gsub(finalnewdata,'\n+$','\n') 	finalnewdata = string.gsub(finalnewdata,'%]%]%,',']],\n')          return finalnewdata  end  -- STAGING a CIRCLE start -- Extra functions while looking at how to build a circle - may be useful for others in building circles etc. --  using some other method. Little or no useful help was found while searching the internet for -- the not so mathematically (trigonometry, algebra etc.) inclined such as myself - hardly anything -- This function is the result of an exhausting trial and error process of what is called Iterative Programming -- The function newlat below is used by p.circle  function newlat(a) -- newlat = math.log(math.tan((90 + a) * math.pi / 360)) / (math.pi / 180) -- worked this code elsewhere in function can remove    newlatitude = 180/math.pi * (2 * math.atan(math.exp( a * math.pi/180)) - math.pi/2 )   if newlatitude > 89.5 then point = 89.5 end -- END if       -- straight line at top of map   if newlatitude < -89.5 then point = -89.5 end -- END if     -- straight line at bottom of map   return newlatitude end  -- CIRCLE FUNCTION -- Get coordinates for a circle to use for drawing a line (LineString) - not filled in -- or get coordinates to build a geoshape (Polygon) -- Note: Polygon can be edited to do just an outline or a solid filled in circle -- Colors etc. can also be changed for fill or outline (stroke) - thickness for stroke as well  -- Latitude and Longitude formatted to %6f or 6 numbers after decimal point - can increase -- Arguments or parameters: --         Required: --                 lat - latitude - ie. 27.0 - error msg will show if missing --                 long - longitude - ie. 28.0 - error msg will show if missing --         Optional --                 type - "line" or "poly" default is "line"  --                 group - group name to be used as "show" argument in <mapframe> - default is "circle" --                 title - title to be used in <maplink> -- default is "A circle" --                 desc - description default is "" --                 radius - radius of circle to be implemented - default is .5 --                         MAX set at 10 -- and can not be less than or equal to 0 --                 fill - default set to #ccef64 if missing --                 stroke - default set to #0000ff --                 marker - y or yes - create a marker - at input lat long -- Code example: --     {{safesubst:#invoke:Sandbox/Matroc|circle|lat=22.35|long=70.07|type=poly|radius=10|fill=#000000|stroke=#0000cc}} --     This creates a <maplink> --  Uses - function newlat -- Note: Yes this is OLD STYLE  function p.circle(frame)         if frame.args['lat'] == nil then error("Missing argument lat!") end -- END if         if frame.args['long'] == nil then error("Missing argument long!") end -- EMD if         local x = string.format("%.6f",frame.args['lat'])         local y = string.format("%.6f",frame.args['long'])         local lat = frame.args['lat']         local long = frame.args['long']         local marker = frame.args['marker'] or "no"               if marker == nil or marker == "" then marker = "no" end         if tonumber(frame.args['lat']) > 85.35 or tonumber(frame.args['lat']) < -85.35 then error("Latitude must be between 85.35 and -85.35!") end -- END if -- I set this as a default - function will not handle the polar circles yet will still handle areas within the majority of a map         if tonumber(frame.args['long']) > 180 or tonumber(frame.args['long']) < -180 then error("Longitude must be between 180 and -180!") end -- END if -- this will draw a full circle at 0 lat and 180 long         local group = frame.args['group'] or 'circle'         local title = frame.args['title'] or 'A circle'         local description = frame.args['desc'] or ''         local r = frame.args['radius'] or ".5"   -- default         -- radius of 10 is approx. 500 km - futz with sizes - below 3 would probably be adequate - .1 is about 20km - .0001 is about 30 m                 r = tonumber(r)                 if r > 10 then error("10 for radius is MAX") end   -- END if - my default                 if r <= 0 then error("radius has to be greater than 0") end -- END if         local fill = frame.args['fill'] or "#ccef64"                 if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end -- END if                 if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then                    error("Incorrect hexidecimal format for argument fill!") end -- END if         local stroke = frame.args['stroke'] or "#0000ff"                 if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end -- END if                 if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then                    error("Incorrect hexidecimal format for argument stroke!") end -- END if         local data = {}         local coordinates = ""         local ptx = 0         local pty = 0         local angle = 0         local type = frame.args['type'] or "line" -- default line for LineString         if type ~= "line" then                 type = "poly"         end -- END if  -- Text for building a maplink - added together with circle coordinates in final output -- This can be modified to output in different order or format if so desired -- my default          local part1a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2a = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2a = part2a .. '\t\t"description": "' .. description .. '",\n'         local part2a = part2a .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'          local part1b = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1b = part1b .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2b = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'         local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'  -- fix latitude to position on mercator openstreetmap - -10.5 to + 10.5 is my default as -- circles in these latitudes are fine for circle drawing          if tonumber(x) >= 10.5 then             x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180)         elseif tonumber(x) <= -10.5 then             x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180)         end -- END if ELSEIF  -- get the latitude & longitudinal places for building or drawing a circle -- this is a common method to build a 360 degree circle           for i = 1, 360 do            angle = i * math.pi / 180            ptx = x + r * math.cos( angle )            pty = y + r * math.sin( angle ) --         ptx, pty = x + r * math.cos( angle ), y + r * math.sin( angle ) -- original code split for readability above  -- fix latitude so that the circle is output and not an eliptical polygon at higher or lower latitudes - this would be due -- to something called isotropy within a mercator projection          if tonumber(x) >= 10.5 then          ptx = newlat(ptx) -- makes correction to make circle show up on map - upper latitudes         end -- END if          if tonumber(x) <= -10.5 then           ptx = newlat(ptx) -- makes correction to make circle show up on map - lower latitudes         end -- END if            data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']'         end -- END for  -- cycle through array and put in a separator symbol (every fifth) so we can put groups of -- 5 coordinates on a single line - in the maplink format          for i = 5,359, 5 do                 data[i] = data[i] .. "@@@@@"         end -- END for  -- cycle through array and build single string of all coordinates to be output          for i = 1,360, 1 do                coordinates = coordinates .. data[i]         end -- END for  -- fix the string to arrange the coordinates with brackets "[]"s separated by ","          coordinates = coordinates.gsub(coordinates,'%]%[','],[')         coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[')         coordinates = "[" .. coordinates .. ',' .. data[1] .. "],"          -- close the circle extra precautionary measure  -- format string coordinates or linestring if a polygon or linestring          if type == "poly" then                 coordinates  = string.gsub(coordinates,'%]%,$',']],')                 coordinates = part1b .. string.gsub(coordinates,'^%[','[[') .. part2b         else                 coordinates = part1a .. coordinates .. part2a         end -- END if         if marker == "yes" or marker == "y" then               coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Center Circle|lat=' .. lat .. "|long=" .. long .. '}}\n'         end         return coordinates  end  -- BOX or RECTANGLE -- Build a box -- Args: --    upper -- latitude and longitude for upper left hand corner -- upper=latitude,longitude --    lower -- latitude and longitude for lower right hand corner -- lower=latitude,longitude --    type -- line or poly --    marker -- y or yes to build an extra marker to place in center of box --    group -- group name --    title -- title --    description -- brief description --    fill -- fill color --    stroke -- color of outline --  Code to build small box for Kronstadt (Russia): --  {{#invoke:Sandbox/Matroc|box|upper=60.03732,29.62099|lower=,59.96866,29.82149|type=poly|title=Kronstadt|marker=y}}  function p.box(frame)         if frame.args['upper'] == nil or frame.args['upper'] == "" then error("Missing argument upper!") end         if frame.args['lower'] == nil or frame.args['lower'] == "" then error("Missing argument lower!") end 	local separator = "@@@@@"         local x = string.gsub(frame.args['upper'],'%,','@@@@@')         local y = string.gsub(frame.args['lower'],'%,','@@@@@')                 x = string.gsub(x,'%s+','')                 y = string.gsub(y,'%s+','')         local tt = {}         local data = {}         local latitudes = {}         local longitudes = {}         local count = 1         local marker = frame.args['marker'] or "no"         if marker == nil or marker == "" then marker = "no" end  	for str in string.gmatch(x,"([^"..separator.."]+)") do 		if str ~= nil and str ~= "" then                     tt[count] = str 		    count = count + 1 		end 	end  	for str in string.gmatch(y,"([^"..separator.."]+)") do 		if str ~= nil and str ~= "" then                     tt[count] = str 		    count = count + 1 		end 	end          if count >=6 then error("Check the upper and lower arguments for format!") end         for i=1,4 do            if tt[i] == nil or tt[i] == "" then error("Check for missing latitude or longitude separated by a comma!") end         end  longitudes[1] = tonumber(tt[2]) if longitudes[1] > 180 or longitudes[1] <- 180 then error("longitude should be between 180 and -180") end         data[1] = "[" .. tt[2]  latitudes[1] = tonumber(tt[1]) if latitudes[1] > 90 or latitudes[1] <- 90 then error("latitude should be between 90 and -90") end         data[2] = "," .. tt[1] .. "]"  longitudes[2] = tonumber(tt[2]) if longitudes[2] > 180 or longitudes[2] <- 180 then error("longitude should be between 180 and -180") end         data[3] = "[" .. tt[2]   latitudes[2] = tonumber(tt[3]) if latitudes[2] > 90 or latitudes[2] <- 90 then error("latitude should be between 90 and -90") end         data[4] = "," .. tt[3] .. "]"  longitudes[3] = tonumber(tt[4]) if longitudes[3] > 180 or longitudes[3] <- 180 then error("longitude should be between 180 and -180") end         data[5] = "[" .. tt[4]  latitudes[3] = tonumber(tt[3]) if latitudes[3] > 90 or latitudes[3] <- 90 then error("latitude should be between 90 and -90") end         data[6] = "," .. tt[3] .. "]"  longitudes[4] = tonumber(tt[4]) if longitudes[4] > 180 or longitudes[4] <- 180 then error("longitude should be between 180 and -180") end         data[7] = "[" .. tonumber(tt[4])  latitudes[4] = tonumber(tt[1]) if latitudes[4] > 90 or latitudes[4] <- 90 then error("latitude should be between 90 and -90") end         data[8] = "," .. tt[1] .. "]"  -- if one wants to output a marker or center of box -- as well as assign the lat/long arguments to maplink (not for geometry coordinates) table.sort(latitudes) table.sort(longitudes) local lat = latitudes[1] + ((latitudes[4] - latitudes[1]) / 2 ) local long = longitudes[1] + ((longitudes[4] - longitudes[1]) / 2)           local group = frame.args['group'] or 'box'         local title = frame.args['title'] or 'A box'         local description = frame.args['desc'] or ''         local fill = frame.args['fill'] or "#ccef64"                 if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end                 if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then                    error("Incorrect hexidecimal format for argument fill!") end         local stroke = frame.args['stroke'] or "#0000ff"                 if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end                 if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then                    error("Incorrect hexidecimal format for argument stroke!") end         local coordinates = ""         local type = frame.args['type'] or "line" -- default line for LineString         if type ~= "line" then                 type = "poly"         end  -- Text for building a maplink - added together with box coordinates in final output -- This can be modified to output in different order if so desired - my default          local part1a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2a = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2a = part2a .. '\t\t"description": "' .. description .. '",\n'         local part2a = part2a .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'          local part1b = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1b = part1b .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2b = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'         local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'  -- cycle through array and build single string of all coordinates to be output          for i = 1,8, 1 do         coordinates = coordinates .. data[i]         end         coordinates = coordinates .. data[1] .. data[2] -- close the box/rectangle polygon  -- fix the string to arrange the coordinates with brackets "[]"s separated by ","          coordinates = coordinates.gsub(coordinates,'%]%[','],[')         coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[')         coordinates = "[" .. coordinates .. "],"  -- format string coordinates or linestring if a polygon or linestring          if type == "poly" then                 coordinates  = string.gsub(coordinates,'%]%,$',']],')                 coordinates = part1b .. string.gsub(coordinates,'^%[','[[') .. part2b         else                 coordinates = part1a .. coordinates .. part2a         end         if marker == "yes" or marker == "y" then                coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Center Box|lat=' .. lat .. "|long=" .. long .. '}}\n'         end         return coordinates  end  -- TRIANGLE  -- Build a triangle -- Args: --    coord1 -- latitude and longitude for point1 of triangle -- coord1=latitude,longitude --    coord2 -- latitude and longitude for point2 of triangle -- coord2=latitude,longitude --    coord3 -- latitude and longitude for point3 of triangle -- coord2=latitude,longitude --    type -- line or poly --    marker -- y or yes to build an extra vicinity marker to place in center of box --          with the name "Center Triangle" --    group -- group name --    title -- title --    description -- brief description --    fill -- fill color --    stroke -- color of outline --    Code for Bermuda Triangle: --   {{safesubst:#invoke:Sandbox/Matroc|triangle|coord1=25.72909,-80.23744|coord2=32.313,-64.765|coord3=18.46633,-66.104736|type=poly|fill=#000000|marker=y}}  function p.triangle(frame)         if frame.args['coord1'] == nil or frame.args['coord1'] == "" then error("Missing argument coord1!") end         if frame.args['coord2'] == nil or frame.args['coord2'] == "" then error("Missing argument coord2!") end         if frame.args['coord3'] == nil or frame.args['coord3'] == "" then error("Missing argument coord3!") end 	local separator = "@@@@@"         local x = string.gsub(frame.args['coord1'],'%,','@@@@@')         local y = string.gsub(frame.args['coord2'],'%,','@@@@@')         local z = string.gsub(frame.args['coord3'],'%,','@@@@@')                 x = string.gsub(x,'%s+','')                 y = string.gsub(y,'%s+','')                 z = string.gsub(z,'%s+','')         local tt = {}         local data = {}         local latitudes = {}         local longitudes = {}         local count = 1         local marker = frame.args['marker'] or "no"                 if marker == nil or marker == "" then marker = "no" end  	for str in string.gmatch(x,"([^"..separator.."]+)") do 		if str ~= nil and str ~= "" then                     tt[count] = str 		    count = count + 1 		end 	end  	for str in string.gmatch(y,"([^"..separator.."]+)") do 		if str ~= nil and str ~= "" then                     tt[count] = str 		    count = count + 1 		end 	end  	for str in string.gmatch(z,"([^"..separator.."]+)") do 		if str ~= nil and str ~= "" then                     tt[count] = str 		    count = count + 1 		end 	end          if count >=8 then error("Check the upper and lower arguments for format!") end         for i=1,6 do            if tt[i] == nil or tt[i] == "" then error("Check for missing latitude or longitude separated by a comma!") end         end          longitudes[1] = tonumber(tt[2])         if longitudes[1] > 180 or longitudes[1] <- 180 then error("longitude should be between 180 and -180") end         data[1] = "[" .. tt[2]          latitudes[1] = tonumber(tt[1])         if latitudes[1] > 90 or latitudes[1] <- 90 then error("latitude should be between 90 and -90") end         data[2] = "," .. tt[1] .. "]"          longitudes[2] = tonumber(tt[4])         if longitudes[2] > 180 or longitudes[2] <- 180 then error("longitude should be between 180 and -180") end         data[3] = "[" .. tt[4]          latitudes[2] = tonumber(tt[3])         if latitudes[2] > 90 or latitudes[2] <- 90 then error("latitude should be between 90 and -90") end         data[4] = "," .. tt[3] .. "]"          longitudes[3] = tonumber(tt[6])         if longitudes[3] > 180 or longitudes[3] <- 180 then error("longitude should be between 180 and -180") end         data[5] = "[" .. tt[6]          latitudes[3] = tonumber(tt[5])         if latitudes[3] > 90 or latitudes[3] <- 90 then error("latitude should be between 90 and -90") end         data[6] = "," .. tt[5] .. "]"   -- if one wants to output a marker or find center of box -- as well as assign the lat/long arguments to maplink (not for geometry coordinates)          local lat = (latitudes[1] + latitudes[2] + latitudes[3]) / 3          local long = (longitudes[1] + longitudes[2] + longitudes[3]) / 3 lat = string.format("%.6f",lat) long = string.format("%.6f",long)         local group = frame.args['group'] or 'triangle'         local title = frame.args['title'] or 'A triangle'         local description = frame.args['desc'] or ''         local fill = frame.args['fill'] or "#ccef64"                 if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end                 if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then                    error("Incorrect hexidecimal format for argument fill!") end         local stroke = frame.args['stroke'] or "#0000ff"                 if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end                 if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then                    error("Incorrect hexidecimal format for argument stroke!") end         local coordinates = ""         local type = frame.args['type'] or "line" -- default line for LineString         if type ~= "line" then                 type = "poly"         end  -- Text for building a maplink - added together with box coordinates in final output -- This can be modified to output in different order if so desired - my default          local part1a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2a = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2a = part2a .. '\t\t"description": "' .. description .. '",\n'         local part2a = part2a .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'          local part1b = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1b = part1b .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2b = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'         local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'  -- cycle through array and build single string of all coordinates to be output          for i = 1,6, 1 do                 coordinates = coordinates .. data[i]                 end         coordinates = coordinates .. data[1] .. data[2] -- close the triangle  -- fix the string to arrange the coordinates with brackets "[]"s separated by ","          coordinates = coordinates.gsub(coordinates,'%]%[','],[')         coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[')         coordinates = "[" .. coordinates .. "],"  -- format string coordinates or linestring if a polygon or linestring          if type == "poly" then                 coordinates  = string.gsub(coordinates,'%]%,$',']],')                 coordinates = part1b .. string.gsub(coordinates,'^%[','[[') .. part2b         else                 coordinates = part1a .. coordinates .. part2a         end          if marker == "yes" or marker == "y" then                 coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Center Triangle|lat=' .. lat .. "|long=" .. long .. '}}\n'         end          return coordinates  end  -- ELIPSE -- Essentially the same code for a circle - this elipise if set to a certain shape -- Get coordinates for an elipse to use for drawing a line (LineString) - not filled in -- or get coordinates to build a geoshape (Polygon) -- Note: Polygon can be edited to do just an outline or a solid filled in elipse -- Colors etc. can also be changed for fill or outline (stroke) - thickness for stroke as well  -- Latitude and Longitude formatted to %6f or 6 numbers after decimal point - can increase -- If its a polygon and you want it to appear with no fill edit output by adding "fill-opacity":, also can change this to a 0 or 1 I think to make -- the fill solid with no opacity -- Arguments or parameters: --         Required: --                 lat - latitude - ie. 27.0 - error msg will show if missing --                 long - longitude - ie. 28.0 - error msg will show if missing --         Optional --                 type - "line" or "poly" default is "line"  --                 group - group name to be used as "show" argument in <mapframe> - default is "circle" --                 title - title to be used in <maplink> -- default is "A circle" --                 desc - description default is "" --                 radius - radius of circle before it is changed to be implemented - default is .5 --                         MAX set at 10 -- and can not be less than or equal to 0 --                 fill - default set to #ccef64 if missing --                 stroke - default set to #0000ff --                 marker - y or yes - create a marker - at input lat long --                 style - h or v -- horizontal or vertical - horizontal or h is default -- Code example: --     {{safesubst:#invoke:Sandbox/Matroc|elipse|lat=22.35|long=70.07|type=poly|radius=10|marker=y|style=h}} --     This creates a <maplink> with coordinates and a marker  function p.elipse(frame)         if frame.args['lat'] == nil then error("Missing argument lat!") end         if frame.args['long'] == nil then error("Missing argument long!") end         local x = string.format("%.6f",frame.args['lat'])         local y = string.format("%.6f",frame.args['long'])         local lat = frame.args['lat']         local long = frame.args['long']         if tonumber(frame.args['lat']) > 90 or tonumber(frame.args['lat']) < -90 then error("Latitude must be between 90 and -90!") end         if tonumber(frame.args['long']) > 180 or tonumber(frame.args['long']) < -180 then error("Longitude must be between 180 and -180!") end         local group = frame.args['group'] or 'elipse'         local title = frame.args['title'] or 'An elipse'         local description = frame.args['desc'] or ''         local r = frame.args['radius'] or ".5"   -- default                 r = tonumber(r)                 if r > 10 then error("10 for radius is MAX") end   -- my default                 if r <= 0 then error("radius has to be greater than 0") end         local fill = frame.args['fill'] or "#ccef64"                 if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end                 if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then                    error("Incorrect hexidecimal format for argument fill!") end         local stroke = frame.args['stroke'] or "#0000ff"                 if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end                 if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then                    error("Incorrect hexidecimal format for argument stroke!") end         local marker = frame.args['marker'] or "no"               if marker == nil or marker == "" then marker = "no" end         local style = frame.args['style'] or "h"               if style == nil or style == "" then style = "h" end               if style ~= "v" then style = "h" end -- if not v (ie. other garbage then force style to be h)         local data = {}         local coordinates = ""         local ptx = 0         local pty = 0         local angle = 0         local type = frame.args['type'] or "line" -- default line for LineString         if type ~= "line" then                 type = "poly"         end  -- Text for building a maplink - added together with elipse coordinates in final output -- This can be modified to output in different order if so desired - my default          local part1a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2a = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2a = part2a .. '\t\t"description": "' .. description .. '",\n'         local part2a = part2a .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'          local part1b = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1b = part1b .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2b = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'         local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'  -- fix latitude to position on mercator openstreetmap - -10.5 to + 10.5 is my default as -- circles in these latitudes are fine for circle drawing          if tonumber(x) >= 10.5 then             x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180)         elseif tonumber(x) <= -10.5 then             x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180)         end  -- get the latitude & longitudinal places for an elipse          for i = 1, 360 do            angle = i * math.pi / 180            ptx = x + r * math.cos( angle )            if style == "v" then                 pty = y - 0.5 * r * math.sin( angle ) -- for elipse vertical              elseif style == "h" then                 pty = y + 2.0 * r * math.sin(angle) -- for elipse horizontal            end --         ptx, pty = x + r * math.cos( angle ), y + r * math.sin( angle )  -- fix latitude so that the elipse is output even at higher or lower latitudes          if tonumber(x) >= 10.5 then          ptx = newlat(ptx) -- makes correction to make circle show up on map         end          if tonumber(x) <= -10.5 then           ptx = newlat(ptx) -- makes correction to make circle show up on map         end            data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']'         end  -- cycle through array and put in a separator symbol (every fifth) so we can put groups of -- 5 coordinates on a single line - in the maplink format          for i = 5,359, 5 do                 data[i] = data[i] .. "@@@@@"         end  -- cycle through array and build single string of all coordinates to be output          for i = 1,360, 1 do         coordinates = coordinates .. data[i]         end  -- fix the string to arrange the coordinates with brackets "[]"s separated by ","          coordinates = coordinates.gsub(coordinates,'%]%[','],[')         coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[')         coordinates = "[" .. coordinates .. ',' .. data[1] .. "],"          -- close the circle extra precautionary measure  -- format string coordinates or linestring if a polygon or linestring          if type == "poly" then                 coordinates  = string.gsub(coordinates,'%]%,$',']],')                 coordinates = part1b .. string.gsub(coordinates,'^%[','[[') .. part2b         else                 coordinates = part1a .. coordinates .. part2a         end         if marker == "yes" or marker == "y" then                 coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Center Elipse|lat=' .. lat .. "|long=" .. long .. '}}\n'         end         return coordinates  end   -- STAR -- Get coordinates for a star to use for drawing a line (LineString) - not filled in -- or get coordinates to build a filled in geoshape (Polygon) -- Note: Polygon can be edited to do just an outline or a solid filled in elipse -- Colors etc. can also be changed for fill or outline (stroke) - thickness for stroke as well  -- Latitude and Longitude formatted to %6f or 6 numbers after decimal point - can increase -- Arguments or parameters: --         Required: --                 lat - latitude - ie. 27.0 - error msg will show if missing --                 long - longitude - ie. 28.0 - error msg will show if missing --         Optional --                 type - "line" or "poly" default is "line"  --                 group - group name to be used as "show" argument in <mapframe> - default is "star" --                 title - title to be used in <maplink> -- default is "A star" --                 desc - description default is "" --                 radius - radius of circle upon which a star is built - default is .5 --                         MAX set at 10 -- and can not be less than or equal to 0 --                 fill - default set to #ccef64 if missing --                 stroke - default set to #0000ff --                 marker - y or yes - create a marker - at input lat long  -- Code example: --     {{safesubst:#invoke:Circle4|star|lat=22.35|long=70.07|type=poly|radius=10}} --     This creates a <maplink>  function p.star(frame)         if frame.args['lat'] == nil then error("Missing argument lat!") end         if frame.args['long'] == nil then error("Missing argument long!") end         local latitude = string.format("%.6f",frame.args['lat'])         local longitude = string.format("%.6f",frame.args['long'])         local lat = frame.args['lat']         local long = frame.args['long']         if tonumber(frame.args['lat']) > 90 or tonumber(frame.args['lat']) < -90 then error("Latitude must be between 90 and -90!") end         if tonumber(frame.args['long']) > 180 or tonumber(frame.args['long']) < -180 then error("Longitude must be between 180 and -180!") end         local group = frame.args['group'] or 'star'         local title = frame.args['title'] or 'A star'         local description = frame.args['desc'] or ''         local radius = frame.args['radius'] or ".5"   -- default                 radius = tonumber(radius)                 if radius > 10 then error("10 for radius is MAX") end   -- my default                 if radius <= 0 then error("radius has to be greater than 0") end         local radius2 = radius * 3;         local fill = frame.args['fill'] or "#ccef64"                 if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end                 if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then                    error("Incorrect hexidecimal format for argument fill!") end         local stroke = frame.args['stroke'] or "#0000ff"                 if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end                 if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then                    error("Incorrect hexidecimal format for argument stroke!") end         local marker = frame.args['marker'] or "no"               if marker == nil or marker == "" then marker = "no" end         latitude = math.log(math.tan((90 + latitude) * math.pi/360)) / (math.pi/180)         local ra = 0         local angle = 0         local points = {}         local coordinates = ""         local type = frame.args['type'] or "line" -- default line for LineString         if type ~= "line" then                 type = "poly"         end          local part1a = '<maplink text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2a = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2a = part2a .. '\t\t"description": "' .. description .. '",\n'         local part2a = part2a .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'          local part1b = '<maplink text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1b = part1b .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2b = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'         local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'         for i = 1,10, 1 do          mod = math.mod(i,2)          if mod == 1 then ra = radius else ra = radius2 end          angle =  ((2 * math.pi / 10)) * i          points[i] =  '[' ..  string.format("%.6f",longitude + (ra * math.cos(angle))) .. ","          points[i] = points[i] .. string.format("%.6f",newlat(latitude + (ra * math.sin(angle)))) .. "],"       end        for i = 1,10, 1 do          coordinates = coordinates .. points[i] .. "\n"       end        coordinates = coordinates .. points[1]          if type == "poly" then                 coordinates  = string.gsub(coordinates,'%]%,$',']]],')                 coordinates = part1b .. string.gsub(coordinates,'^%[','[[[') .. part2b         else                 coordinates  = string.gsub(coordinates,'%]%,$',']],')                 coordinates = part1a .. string.gsub(coordinates,'^%[','[[') .. part2a         end          if marker == "yes" or marker == "y" then                 coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Center Star|lat=' .. lat .. "|long=" .. long .. '}}\n'         end         return coordinates   end  -- Load a page and scan it for listing templates and find duplicate parameters    function p.checkparameters(frame) 		local page = frame.args[1] or "Main Page" 		local flags = frame.args['flags'] or "n" 		if flags ~= "y" then flags = "n" end       -- Images from {{flag|name}} as in embassies -- y or n         local title = mw.title.new(page)         if title == nil then return end          if title.id == 0 then             return "Page does not exist!"         end          local data = title:getContent() 		 		if data == nil or data == "" then 			return "" 		end  -- Isolate listings,eliminate extra spaces etc. and and pull them out of data  local separator = "@@@@@"   data = string.gsub(data,'\n',' ') data = string.gsub(data,'%s+',' ') data = string.gsub(data,"http://www","HTTPWWW") data = string.gsub(data,"https://www","HTTPSWWW") data = string.gsub(data,"http://","HTTP") data = string.gsub(data,"https://",'HTTPS') data = string.gsub(data,'%s+=%s+','=') data = string.gsub(data,'%s+|%s+','|') data = string.gsub(data,'%s+}','}') data = string.gsub(data,'{%s+','{') -- eliminate some templates to minimize later processing data = string.gsub(data,'{{deadlink','DEADLINK') data = string.gsub(data,'{{dead link','DEADLINK') data = string.gsub(data,'{{ISBN','ISBN') data = string.gsub(data,'{{seealso','SEEALSO') data = string.gsub(data,'{{see also','SEEALSO') data = string.gsub(data,'{{seeDistricts}}','')   -- other hatnotes could be added here as well data = string.gsub(data,'{{SeeDistricts}}','') data = string.gsub(data,'{{pagebanner','PAGEBANNER') data = string.gsub(data,'{{quickbar','QUICKBAR') data = string.gsub(data,'{{regionlist','REGIONLIST') data = string.gsub(data,'{{Regionlist','REGIONLIST') data = string.gsub(data,'{{translate','TRANSLATE') data = string.gsub(data,'{{IATA','IATA') data = string.gsub(data,'{{related','RELATED') data = string.gsub(data,'{{geo','GEO') data = string.gsub(data,'{{infobox','INFOBOX') data = string.gsub(data,'{{','@@@@@') data = string.gsub(data,'%s+@@@@@%s+','@@@@@')   local index = 0  local items = {}  local flags = {}  local number = 0 for str in string.gmatch(data,"([^"..separator.."]+)") do  	str = string.gsub(str,'DEADLINK.*%d%d%d%d}}','') -- template inside a template removestring 	str = string.gsub(str,'}}.*','')          local check = {	'Listing', 'Marker', 'See', 'Do', 'Buy', 'Eat', 'Drink', 'Sleep', 'listing', 'marker', 'see', 'do', 'buy', 'eat', 'drink', 'sleep'} -- pick out listings by type Listing,See, Do, Buy, Eat, Drink and Sleep    for k,v in ipairs(check) do         if string.match(str,"^" .. v) then     	   index = index + 1     	   items[index] = str     	   break         end     end end  local dummy = "" local dump1 = "" local newitems = {} local count2 = 0         check = {'Listing', 'Marker', 'See', 'Do', 'Buy', 'Eat', 'Drink', 'Sleep', 'listing', 'marker', 'see', 'do', 'buy', 'eat', 'drink', 'sleep'}   if index >= 1 then 	for i=1,index do         str = items[i]         str = string.gsub(str,'%|',"@@@@@")                    for k,v in ipairs(check) do    	             str = string.gsub(str,"^"..v.."@@@@@","")    	             end         for matchdupes in string.gmatch(str,"([^"..separator.."]+)") do  --       	matchdupes = string.gsub(matchdupes,"%=.*$","=")   -- split off parameters by name       	matchdupes = string.gsub(matchdupes,"%=.*","=")   -- split off parameters by name         	dummy,count = string.gsub(items[i],matchdupes,"")         	if count >= 2 then         		items[i] = string.gsub(items[i],matchdupes,"<duplicate>"..matchdupes.."</duplicate>")         	   end             end     end  end  local testdata = "" if index >= 1 then     for i=1,index do        if string.find(items[i],".*<duplicate>.*") then        	  items[i] = string.gsub(items[i],"duplicate>","b>") 	      testdata = testdata .. "\n* ---- " .. items[i] .. "\n" 	   end 	end end    return "\n----" .. testdata .. "No. of templates reviewed = " .. index .. "\n----"  end    function p.betadellistparams(frame)  		local page = frame.args[1]          local title = mw.title.new(page)         if title == nil then return end          if title.id == 0 then             return "Page does not exist!"         end          local data = title:getContent()         local newdata = ""         if data == nil or data == "" then          	return         end          local tt = {} local count = 0 local continue = 0 local separator = "@@@@@" --data = string.gsub(data,'\n','@@@@@') --data = string.gsub(data,'\n','@@@@@') data = string.gsub(data,'%| *[Hh]ours\= *','|hours=') data = string.gsub(data,'%| *[Pp]rice\= *','|price=') data = string.gsub(data,'%| *[Cc]ontent\= *','|content=') data = string.gsub(data,'%| *[Dd]irections\= *','|directions=') data = string.gsub(data,'%| *[Cc]heckin\= *','|checkin=') data = string.gsub(data,'%| *[Cc]heckout\= *','|checkout=') data = string.gsub(data,'|','@@@@@+++++|') data = string.gsub(data,'\}\}','@@@@@}}') data = string.gsub(data,'@@@@@@@@@@','@@@@@') data = string.gsub(data,'@@@@@@@@@@','@@@@@')   for str in string.gmatch(data,"([^"..separator.."]+)") do 	 -- if string.find(str,'content') ~= nil then return str end if string.find(str,'^\+\+\+\+\+.*') ~= nil then 	str = string.gsub(str,'^\+\+\+\+\+','') 	str = string.gsub(str,'|hours\=.*','|hours=')	 	str = string.gsub(str,'|price\=.*','|price=')	 	str = string.gsub(str,'|checkin\=.*','|checkin=')	 	str = string.gsub(str,'|checkout\=.*','|checkout=')	 	str = string.gsub(str,'|directions\=.*','|directions=')	 	str = string.gsub(str,'|content\=.*','|content=')  -- if string.find(str,'content') ~= nil then return str end  else --    str = str" .. "\n" end  if str ~= nil and str ~= "" then      count = count + 1	      tt[count] = str end  end  for key,value in pairs(tt) do 	newdata = newdata .. value end   	return newdata  end    -- GET LATITUDE -- P625  local function combo(id) 	local latitude = "" 	local longitude = "" 	local name = "" 	local osm = "none" 	local linkosm = ""     local entity = mw.wikibase.getEntityObject(id)	 	if entity == nil then return latitude,longitude,name end    		 	local claims = entity.claims 	if claims == nil then 		return latitude,longitude,name 	end	 	if claims.P625 ~= nil then 		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 		latitude = string.format("%.6f",latitude) 		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 		longitude = string.format("%.6f",longitude)		 	end 	if claims.P402 ~= nil then 		osm = entity.claims.P402[1].mainsnak.datavalue.value or "none" 		if osm == nil then osm = "none" end 		if osm ~= "none" then linkosm = "[https://www.openstreetmap.org/relation/" .. osm .. " " .. osm .. "]" 			osm = linkosm 			end 	end	 	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then 		name = entity:getSitelink("enwikivoyage") or "" 		if name ~= nil and name ~= "" then 			name = "wv: [[" .. name  .."]]" 			else name = "wv: ----" 		end 	end 	return latitude,longitude,name,osm end  -- Combine following into 1 function to avoid multiple repeating actions -- Doing lookup for OSM relation ID move to combo  local function yikes(v)      local entity = mw.wikibase.getEntityObject(string.gsub(v,' ',''))      local claims = entity.claims      if claims == nil then return "---" end      if claims.P402 == nil then return "---" end     local xxx = entity.claims.P402[1].mainsnak.datavalue.value     return xxx end  -- GET LATITUDE -- P625  local function latitude2(id) 	local latitude = ""     local entity = mw.wikibase.getEntityObject(id)	 --	local entity = mw.wikibase.getEntityObject() 	if entity == nil then return latitude end    		 	local claims = entity.claims 	if claims == nil then 		return latitude 	end	 	if claims.P625 ~= nil then 		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 		return string.format("%.6f",latitude) 	end 	return latitude end  local function longitude2(id) 	local longitude = ""     local entity = mw.wikibase.getEntityObject(id)	 	if entity == nil then return longitude end    		 	local claims = entity.claims 	if claims == nil then 		return longitude 	end	 	if claims.P625 ~= nil then 		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 		return string.format("%.6f",longitude) 	end 	return longitude end  local function sitename2(id) 	local name = ""     local entity = mw.wikibase.getEntityObject(id)	 	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then 		name = entity:getSitelink("enwikivoyage") or "" 		if name ~= nil and name ~= "" then 			name = "wv: [[" .. name  .."]]" 		else name = "wv: ----" 		end 	end           	 	return name end  -- look for admin units and related OSM ID function p.looksee(frame) 	local newdata = ""     local previous = ""     local voysitename = ""     local name2 = ""     local lat = ""     local long = ""     local wv = ""     local osm = "" 	local arg1 = frame.args[1]     local entity = mw.wikibase.getEntityObject(arg1)     local str = ""     local strx = ""     local xxx = "" 	if entity == nil then return newdata end	 	local claims = entity.claims 	if claims == nil then 		return newdata 	end	 	local data = "" 	local t = {} 	local tt = {} 	local separator = "%s"	 	local count = 0  --	P47 for bordering entities      if claims.P150 ~= nil then         for k,v in pairs(claims.P150) do     		count = count + 1     		t = {} 			if pcall(function () t = entity.claims.P150[count].mainsnak.datavalue.value end) then 					t = entity.claims.P150[count].mainsnak.datavalue.value    	 				else 					return newdata 			end			 			t = entity.claims.P150[count].mainsnak.datavalue.value  			for k, v in pairs( t ) do 				v = string.gsub(v,"item","") 				v = " Q" .. v 				v = string.gsub(v,"^ Q$","")                 v = string.gsub(v,'Q+','Q')                 if v ~= previous then 				    if v ~= nil and v ~= "" then                         xxx = yikes(v)					 --				        data = data .. v .. "@@@" .. xxx                         data = data .. " " .. v             	    end                     previous = v               end 		  end 		end 		count = 1 		for str in string.gmatch(data,"([^"..separator.."]+)") do --            strx = string.gsub(str,'^.*@@@','') -- OSM ID --            str = string.gsub(str,"@@@.*$",'')  -- Wikidata ID lat,long,name2,osm=combo(str) 	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then 		voysitename = entity:getSitelink("enwikivoyage") or "" 		if voysitename ~= nil and voysitename ~= "" then 			voysitename = "wv: [[" .. voysitename  .."]]" 		else voysitename = "wv: ----" 		end 	end   --			if mw.wikibase.sitelink( str ) ~= nil then --tt[count] = "'''[[" .. mw.wikibase.sitelink( str ) .. "]]''': " .. "'''[[d:" .. str .. " | " .. str .. "]]''' ('''" .. strx .. "''')" --tt[count]= tt[count] ..  " '''lat''': " .. lat .. " '''long''': " .. long .. " - " .. voysitename .. "---" .. name2 -- --else --       if mw.wikibase.label(str) == nil or mw.wikibase.label(str) == "" then --             tt[count] = "'''No Label''': " .. "'''[[d:" .. str .. " | " .. str .. "]]''' ('''No Label ''')" --             tt[count]= tt[count] ..  " '''lat''': " .. lat .. " '''long''': " .. long .. " - " .. voysitename .. "---" .. name2 --             count = count + 1 --             break end --   	      --tt[count] = "'''[[" .. mw.wikibase.label(str) .. "]]''': " .. "'''[[d:" .. str .. " | " .. str .. "]]''' ('''" .. strx .. "''')" --tt[count]= tt[count] ..  " '''lat''': " .. lat .. " '''long''': " .. long .. " - " .. voysitename .. "---" .. name2 --	  end   if mw.wikibase.label(str) == nil or mw.wikibase.label(str) == "" then              tt[count] = "'''No Label''': " .. "'''[[d:" .. str .. " | " .. str .. "]]''' ('''" .. osm .. "''')"              tt[count]= tt[count] ..  " '''lat''': " .. lat .. " '''long''': " .. long .. " - " .. voysitename .. "---" .. name2	 else tt[count] = "'''[[" .. mw.wikibase.label(str) .. "]]''': " .. "'''[[d:" .. str .. " | " .. str .. "]]''' ('''" .. osm .. "''')" tt[count]= tt[count] ..  " '''lat''': " .. lat .. " '''long''': " .. long .. " - " .. voysitename .. "---" .. name2 	 end   			count = count + 1 end 		table.sort(tt) 		count = 1 		for k, v in pairs (tt) do 			if count == 1 then 					newdata = tt[count] 				else --					newdata = newdata .. ", " .. tt[count] 					newdata = newdata .. "</br>" .. tt[count]					 				end 				count = count + 1 			end 			if newdata ~= "" then 	    		newdata = "<div style=\"background-color:WhiteSmoke; border-style:solid; border-width:thin; padding-right: 10px; padding-left: 10px;\">" .. newdata .. "</div>" 			end 			return newdata 		end 	return newdata end	-- END MODULE  function p.convchar(frame)     local xxx = frame.args[1] xxx = string.gsub(xxx,"&#39;","\'") xxx = string.gsub(xxx,"&#34;",'\"') -- xxx = string.gsub(xxx,"&nbsp;",' ') 	return xxx end  function p.getname(frame) 	local name=mw.wikibase.getEntityIdForTitle(frame.args[1]) 	if name == "" or name == nil then return "" end 	return name 	end   function p.getname2(frame) 	local names=frame.args[1] 	local name = "" 	local image = "" 	local items = {} 	local index = 1     local id = "" 	local latitude = '' 	local longitude = '' 	local marker = ''     local entity = ''     local data = ""     local separator = '\n'     local lang = ''     local wiki = ''     local wikiname = ''       for str in string.gmatch(names,"([^"..separator.."]+)") do  	if str ~= nil and str ~= "" then  		str = string.gsub(str,"^%s+","")      	str = string.gsub(str,"%s+$","")      	if str ~= "" then 	       items[index] = str 	       index = index + 1 	       end 	    end 	end       for i=1,#items do  	name = items[i]  	id = ""     wikiname = '' 	 	id=mw.wikibase.getEntityIdForTitle(items[i])     if id == nil then id = '' end      if id ~= nil and id ~= '' then     entity = mw.wikibase.getEntityObject(id)	      if entity == nil then 		latitude = "" 	    longitude = "" 	    end 	     	local claims = entity.claims 	if claims == nil then 		latitude = "" 		longitude = "" 	    end	 --	if claims.P625 ~= nil then if pcall(function () t =claims.P625 end ) then  		if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		 		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 		else latitude = "" end  		if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then		 		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 		else longitude = "" end end  --	if claims.P18 ~= nil then --		image = entity.claims.P18[1].mainsnak.datavalue.value --		if image == nil then --			image = "" -- -- Replace above due to error of getting a nil value -- Lua error in line 3210: attempt to index field 'datavalue' (a nil value). image="" if pcall(function () t =claims.P625 end ) then  		if pcall(function () t =entity.claims.P18[1].mainsnak.datavalue.value end ) then		 		      image = entity.claims.P18[1].mainsnak.datavalue.value 		    else 		    	image = "" 			end		     end  		 	end      wikiname = ""	 	lang = mw.language.getContentLanguage(id).code 	wiki = lang .. "wiki" 	if pcall(function()t1 = entity:getSitelink("wiki") end) then	         wikiname = entity:getSitelink(wiki) or ""     else     	wikiname = ""     end  if id == "" then wikiname = "" end if id ~= nil and id ~= "" then 			name = "[[" .. name .. "]]" end     marker = '* {{see | name=' .. name .. " | lat=" .. latitude .. " | long=" .. longitude .. " | image=" .. image .. " | wikipedia=" .. wikiname .. " | wikidata=" .. id .. "}}"     data = data .. marker .. "\n"     marker = ''     name = ''     latitude = ''     longitude = ''     image= ''     id = ''     wikiname = '' 	 end          return data     end function p.getname3(frame) 	local names=frame.args[1] 	local type = "" 	local name = "" 	local image = "" 	local items = {} 	local index = 1     local id = "" 	local latitude = '' 	local longitude = '' 	local listing = ''     local entity = ''     local data = ""     local separator = '\n'     local lang = ''     local wiki = ''     local wikiname = ''     local counter = 0       for str in string.gmatch(names,"([^"..separator.."]+)") do  	if str ~= nil and str ~= "" then  		str = string.gsub(str,"^%s+","")      	str = string.gsub(str,"%s+$","")      	if str ~= "" then 	       items[index] = str 	       index = index + 1 	       end 	    end 	end       for i=1,#items do  	name = items[i]  	id = ""     wikiname = '' 	 	id=mw.wikibase.getEntityIdForTitle(items[i])     if id == nil then id = '' end      if id ~= nil and id ~= '' then     entity = mw.wikibase.getEntityObject(id)	      if entity == nil then 		latitude = "" 	    longitude = "" 	    end 	     	local claims = entity.claims 	if claims == nil then 		latitude = "" 		longitude = "" 	    end	 	if claims.P625 ~= nil then 		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 	    end 	if claims.P18 ~= nil then 		image = entity.claims.P18[1].mainsnak.datavalue.value 		if image == nil then 			image = "" 			end 		end 	end      wikiname = ""	 	lang = mw.language.getContentLanguage(id).code 	wiki = lang .. "wiki" 	if pcall(function()t1 = entity:getSitelink("wiki") end) then	         wikiname = entity:getSitelink(wiki) or ""     else     	wikiname = ""     end  if id == "" then wikiname = "" end if id ~= nil and id ~= "" then 			name = "[[" .. name .. "]]" end if latitude ~= "" then counter = counter + 1 end -- make different type for listings after groups of 99      listing = '* {{ listing | type=' .. type .. ' | name=' .. name .. " | lat=" .. latitude .. " | long=" .. longitude .. " | image=" .. image .. " | wikipedia=" .. wikiname .. " | wikidata=" .. id .. "}}"     data = data .. listing .. "\n"     listing = ''     name = ''     latitude = ''     longitude = ''     image= ''     id = ''     wikiname = '' 	 end          return data       end  function p.dumbidea(frame) 	local data = "" data = '* {{User:Matroc/Mapdraw2 | map=link ' data = data .. '| group=shape | show=shape | type=poly ' data = data .. '| shape=external | geotype=geoshape | class=no-icon  | title=HELP  | stroke=#4B0082' data = data .. '| strokewidth=3 | fill=\#ff00ff | id=Q25396 | zoom=9  | text=TEST GEOSHAPE }}' 	return data end  -- WIKISTIES INFORMATION   function p.wikisites(frame) --    if frame.args[1]~=nil and frame.args[1]~='' then --        return frame.args[1] --    end  	local arg1 = frame.args[1] or "" local xarg1 = arg1 	local arg2 = frame.args[2] or "wikivoyage" -- wikiname for program - wikivoyage alternative  -- if not Qnnn then get local Qnnn id  if string.find(arg1,"^w") ~= nil then 	arg2 = arg1 end  if string.find(arg1,"^Q") == nil then 	local item = mw.wikibase.getEntityObject() 	if item == nil then return end 	if item.id ~= nil then 		arg1 = item.id 	else 		return 	end end  	local wikinames = loadwikinames() -- table of wikinames 	local lukup = "" 	for k,v in pairs(wikinames) do 		if v == arg2 then 			lukup = v .. "$" 		end 	end 	if lukup == "" then 		return 	end 	local entity = mw.wikibase.getEntityObject(arg1)	 --	local entity = mw.wikibase.getEntityObject()     if entity == nil then return end 	local sites = entity.sitelinks   	if sites ~= nil and sites ~= '' then     	local list = ""     	local newlist = ""     	local separator = "%s"     	local tt = {}     	local asitelink = ""		 		for k,v in pairs(sites) do 			if string.match(k,lukup) == arg2 then 				asitelink = entity:getSitelink(k) 				asitelink = string.gsub(asitelink," ","@@@")      			list = list .. "'''" .. string.gsub(k,lukup,"") .. "''':''" ..  asitelink .. "'' "      		end     	end 		list = string.gsub(list," $","") 		if list == "" then return "" end 		count = 1 		for str in string.gmatch(list,"([^"..separator.."]+)") do 			tt[count] = str 			count = count + 1 		end 		table.sort(tt) 		for k,v in pairs(tt) do 			newlist = newlist .. v .. ", " 		end 		newlist = string.gsub(newlist,", $","") 		newlist = string.gsub(newlist,"@@@"," ") 		newlist = "<span style=\"color:blue; font-family:Times New Roman; font-weight:bold\">" .. arg2 .. "</span>: " .. newlist 		return newlist 	end     return "" end  -- Load a page and scan it for images and produce a list of internal links  function p.getinternallinks(frame) 		local page = frame.args[1] or "Main Page"         local title = mw.title.new(page)         local displayactual = frame.args['option'] or "yes"         if title == nil then return end          if title.id == 0 then             return "Page does not exist!"         end          local data = title:getContent() 		 		if data == nil or data == "" then 			return 		end  		local tt = {} 		local count = 0 		local output = "" 		local separator = "@@@@@" 		local newstr = ""		 			  		data = string.gsub(data,"\n","@@@@@")								--change \n to separator @@@@@ 		data = string.gsub(data,"@","BULLET")								--because I use @@@@@ as a separator changing @ to BULLET 		data = string.gsub(data,"%s+"," ")									--change multiple spaces to a space 		data = string.gsub(data,"%[%[","@@@@@[[")							--change [[ to separator @@@@@[[ 		data = string.gsub(data,"%]%]","]]@@@@@")							--change ]] to separator ]]@@@@@ 		data = string.gsub(data,"@@@@@@@@@@","@@@@@")						--change ]] to separator ]]@@@@@  		for str in string.gmatch(data,"([^"..separator.."]+)") do  			if str ~= nil and str ~= "" then  -- Get rid of File,file,Image,image  str = string.gsub(str,"%[%[[fF]ile.*",'')  str = string.gsub(str,"%[%[[iI]mage.*",'')  				str = string.gsub(str,'%s*$','')       					-- drop ending space 				str = string.gsub(str,'^%s+','') 					if string.find(str, '^%[%[') == 1 then			    -- Key is to have [[ at beginning 					    str = string.gsub(str,'%_'," ")                 -- Change _ to space 						str = string.gsub(str,'%%2C',",") 						str = string.gsub(str,'%s+%|%s+','|') 						str = string.gsub(str,'%[%[%#','[[' .. page .. '#') 						 -- If plain [[something]] then change it into [[something|something]] 	if string.find(str, '^%[%[.*%|.*%]%]') == 0 then        str = string.gsub(str,"(%[%[)(.*)(%]%])","%1%2|%2%3")   -- Change [[something]] to  [[something|something]]    end  -- Display only actual link make it an option if displayactual == "yes" then 	str = string.gsub(str,"%|.*%]%]","]]") end 					    count = count + 1 --					    localstr = str.gsub(str,'^.*|','')                         localstr = str.gsub(str,'|.*','')                         localstr = string.upper (localstr)  						tt[count] = localstr .. "@-@" .. str 						end 				end 		end  		table.sort(tt) 		local previous = ""  		for key,value in pairs(tt) do value = string.gsub(value,'^.*@-@','') 			if value ~= previous then                 output = output .. value .. " -- " 			end 			    previous = value 		end		  		output = string.gsub(output,"BULLET","@") 		output = string.gsub(output," -- $","") 	return output end  --  function p.grabmarkertype(frame) local sectionorig = frame.args['section'] or "" local section = "" local sectionx = "" local level = frame.args['level'] or "0"    if sectionorig == nil or sectionorig == "" then    	level = "0"     end     if tonumber(level) <= 1 or tonumber(level) > 5 then     	level = "0"     	sectionorig = ""     end local a,b,c,d = "" local part1 = "" local part2 = "" 		local page = frame.args['page'] or "" 		local type = frame.args['type'] or ""         local title = mw.title.new(page)         local sort = frame.args['sort'] or "no"         local sortbytype = frame.args['sortbytype'] or "no"         local sortby = ""         local sortname = ""         local data = ""         local newdata = ""         if title == nil then return end         if title.id == 0 then             return "Page does not exist!"         end         newdata = title:getContent() 		if newdata == nil or newdata == "" then 			return 		end -- IMPORTANT TO INCORPORATE IN SOME OF THE TEST MODULES ABOVE GOING BY LINE TO INITIATE         for line in string.gmatch(newdata,'[^\r\n]+') do      -- change any @ to BULLET             line = string.gsub(line,"@","BULLET")             -- add a @@@@@ to each line to act as a separator             line = string.gsub(line,"%s+|%s+","|")             line = string.gsub(line,"^%*%s+|","")             line = string.gsub(line,"^%*+%s+","")             line = string.gsub(line,"%[%[File:.*%]%]","")             line = string.gsub(line,"%[%[Image:.*%]%]","")                         if line ~= "^$" then                 if string.find(line, "^[%||%}|%{]") ~= nil then                    line = string.gsub(line,"^%}%}","}}@@@@@")                    data = data .. line                  else 	               data = data .. line .. "@@@@@" 	              end 	         end         end 		local tt = {}                                         -- create an arrary for markers 		local count = 0                                       -- local counter for arrary tt 		local output = ""                                     -- output - destination of all markers 		local separator = "@@@@@"                            -- indicator for line separation 		local newstr = ""                                     -- to be used for sorting of markers by name if desired		 if sectionorig ~= nil and sectionorig ~= "" then 	sectionorig = string.gsub(sectionorig,"@","|")     if level == "5" then 	    section = "section5" .. sectionorig .. "section5"         sectionx = "section5 " .. sectionorig .. " section5"         end	      if level == "4" then 	    section = "section4" .. sectionorig .. "section4"          sectionx = "section4 " .. sectionorig .. " section4"	                   end	       if level == "3" then          section = "section3" .. sectionorig .. "section3"          sectionx = "section3 " .. sectionorig .. " section3"         end       if level == "2" then          section = "section2" .. sectionorig .. "section2"          sectionx = "section2 " .. sectionorig .. " section2"          end       data = string.gsub(data,"%(","openparens")       data = string.gsub(data,"%)","closeparens")       data = string.gsub(data,"%|","PIPE")       data = string.gsub(data,"%.","PERIOD")       data = string.gsub(data,"%,","COMMA")       data = string.gsub(data,"(==+)(%[+%s*)","%1")       data = string.gsub(data,"(%s*%]+)(==+)","%2")       data = string.gsub(data,"openparens","(")       data = string.gsub(data,"closeparens",")")       data = string.gsub(data,"PIPE","|")       data = string.gsub(data,"PERIOD",".")       data = string.gsub(data,"COMMA",",")       data = string.gsub(data,"=====","section5")       data = string.gsub(data,"====","section4") 	  data = string.gsub(data,"===","section3") 	  data = string.gsub(data,"==","section2")       if string.find(data,sectionx .. ".*") ~= nil          then section = sectionx           end       if string.find(data,section .. ".*") == nil then return "section not found"       	else         a,b = string.find(data,section .. ".*")             data = string.sub(data,a)             part1 = data       	end       if string.find(data,section .. ".*",10) ~= nil then           c,d=string.find(data,section .. ".*",10)           part1 = string.sub(data,1,c)           part2 = string.sub(data,c)        end        part1 = string.gsub(part1,section,"BEGINSECTION")        part2 = string.gsub(part2,section,"BEGINSECTION")       if level == "2" then          part1 = string.gsub(part1,"section2.*","")          part2 = string.gsub(part2,"section2.*","")        		         end        if level == "3" then         	part1 = string.gsub(part1,"section[23].*","")         	part2 = string.gsub(part2,"section[23].*","")         end         if level == "4" then         	part1 = string.gsub(part1,"section[234].*","")		         	part2 = string.gsub(part2,"section[234].*","")		          end         if level == 5 then             part1 = string.gsub(part1,"section[2345].*","")         	part2 = string.gsub(part2,"section[2345].*","")		        		           end           data = part1 .. part2            part1 = ""            part2 = ""         data = string.gsub(data,"BEGINSECTION",section)         data = data    end           data = string.gsub(data,"\n%s+%|","|") 		data = string.gsub(data,"%s+"," ")					  --change multiple spaces to a space 		data = string.gsub(data,"%}%}%}","rightcurliesrightcurliesrightcurlies") 		data = string.gsub(data,"%{%{%{","leftcurliesleftcurliesleftcurlies")		 		data = string.gsub(data,"({{)(IATA|)(...)(}}","leftcurliesleftcurlies%2%3rightcurliesrightcurlies") -- Special case -- SPACE FOR MORE SPECIAL CASES		 		data = string.gsub(data,"%*%s+%{","{") 		data = string.gsub(data,"%*%{","{") 		data = string.gsub(data,"%{ ","{") 		data = string.gsub(data,"%{%{","@@@@@{{")							--change {{ to separator @@@@@{{ 		data = string.gsub(data,"%}%}","}}@@@@@")							--change }} to separator ]]@@@@@ 		data = string.gsub(data,"==+","@@@@@") --change to separator@@@@@ 		data = string.gsub(data,"@@@@@@@@@@","@@@@@") 		data = string.gsub(data,"%}%}@@@@@ %&mdash;","}} &mdash;") 		data = string.gsub(data,"%}%}@@@@@, ","}}, ") 		data = string.gsub(data,"%}%}@@@@@%s%[","}} [") 		data = string.gsub(data,"%}%}@@@@@%-","}} -") 		data = string.gsub(data,"%}%}@@@@@ –","}}  –") 		data = string.gsub(data,"%}%}@@@@@%s%-","}} -")							-- take care of text at end of line if any 1/2 way         data = string.gsub(data,"%}%}@@@@@ %(","}} (")                            -- oddballs add here data = string.gsub(data,"%}%}@@@@@ ","}} ")          data = "@@@@@" .. data .. "@@@@@"  		for str in string.gmatch(data,"([^"..separator.."]+)") do 			if str ~= nil and str ~= "" then 				str = string.gsub(str,'%s+$','')       					-- drop ending space 				str = string.gsub(str,'^%s+','') 				if string.find(str, '^%{%{marker') ~= nil then		-- Key is to have {{marker at beginning 					str = string.gsub(str,'%_'," ")                 -- Change _ to space 					str = string.gsub(str,'%%2C',",") 					str = string.gsub(str,'%s+%|%s+','|') 					str = string.gsub(str,"BULLET","@") 					if string.find(str,"type=") == nil then           -- no type then add type listing to marker as default 						  str = string.gsub(str,"%{%{marker","{{marker|type=listing") 					    end					 				    if sort == "yes" then                        sortname = str                        sortname = str.gsub(sortname,"%s+%|%s+","|")                -- space|space to |                        sortname = str.gsub(sortname,"^.*%|name=","")               -- chop up to name=                        sortname = str.gsub(sortname,"%|.*","")                     -- delete | and after - CHANGE                        sortname = str.gsub(sortname,"%]+.*","")                    -- delete ]] and after                        sortname = str.gsub(sortname,"%[+","")                        sortname = str.gsub(sortname,"}+.*","")                        sortname = sortname .. string.rep(".", 20 - #sortname)       -- pad sortname to 40 chars                        sortname = sortname:upper()                        sortname = sortname .. "SORTIT"                        if sortbytype == "yes" then                            sortby = str                            sortby = str.gsub(sortby,"%s+%|%s+","|")                 -- space|space to |                            sortby = str.gsub(sortby,"^.*type=","")                 -- chop up to type=                            sortby = str.gsub(sortby,"%|.*","")                             sortby = str.gsub(sortby,"}+.*","")                            sortby = sortby:upper()                            sortby = sortby .. string.rep(".", 10 - #sortby)                            sortname = sortby .. sortname                         end                     end                      if type ~= nil and type ~= "" then                           if string.find(str,"type=" .. type) ~= nil then          	 					         count = count + 1                              if sort == "yes" then					                                           tt[count] = sortname .. str                                  else                                 	tt[count] = str                                  end                              end                           else                        	       count = count + 1                                if sort == "yes" then                        	             tt[count] = sortname .. str                                    else 	                                 tt[count] = str                                  end                            end 					end 				end 		end          if sort == "yes" then 		     table.sort(tt)         end 		local previous = "" 		for key,value in pairs(tt) do 			if value ~= previous then                 if sort == "yes" then                       output = output .. "* " .. string.gsub(value,".*SORTIT","") .. "\n"                    else                      output = output .. "* " .. value .. "\n"                    end 			end 			    previous = value 		end		         output = string.gsub(output,"rightcurlies","}")         output = string.gsub(output,"leftcurlies","{") 		output = string.gsub(output,"BULLET","@") 	return output end   --  grab a mapmask if possible and convert to different formats --  for smaller mapmasks only -- otherwise run out of processing time! function p.grabmapmask(frame) 	    local page = frame.args['name'] or "" 	    local out = frame.args['out'] or "inapoly" 	    local data = "" 	    local mapmask = "" 	    local inapoly = "" 	    local coordinates = ""         local title = mw.title.new(page)         if title == nil then return "Need name argument!" end         if title.id == 0 then             return "Page does not exist!"         end         data = title:getContent()          if string.match(data,"{{[M|m]apmask") == nil and string.match(data,"{{ [M|m]apmask") == nil  then  	return "There is no mapmask in " .. page 	end                  data = string.gsub(data,".*{{[M|m]apmask","")         data = string.gsub(data,".*{{ [M|m]apmask","")         data = string.gsub(data,"}}.*","")         data = string.gsub(data,"%s+","") data = string.gsub(data,"\n","")         data = string.gsub(data,"%w%=%w%|","")                  mapmask = data         mapmask = string.gsub(mapmask,"^|","")         mapmask = string.gsub(mapmask,"|"," | ")                  inapoly = string.gsub(data,",",":")         inapoly = string.gsub(inapoly,"^|","")         inapoly = string.gsub(inapoly,"|",", ")                   coordinates = string.gsub(data,"^|","")         coordinates = string.gsub(coordinates,"(%d+%.%d+)(,)(%d+%.%d+)","%3%2%1")          coordinates = string.gsub(coordinates,"%|","],[")         coordinates = "[[[" .. coordinates .. "]]]" if out == "inapoly" then  	return inapoly elseif out == "mapmask" then  	return mapmask elseif out == "json" then 	return coordinates end  	return "'''mapmask''' - " .. mapmask .. "\n\n'''inapoly''' - " .. inapoly .. "\n\n'''coordinates''' - " .. coordinates end  function p.grabmarkerinpoly(frame) 		local page = frame.args['page'] or "" 		local type = frame.args['type'] or ""         local title = mw.title.new(page)         local data = ""         local newdata = ""         if title == nil then return end         if title.id == 0 then             return error "Page does not exist!"         end         newdata = title:getContent() 		if newdata == nil or newdata == "" or not newdata then 			return 		end 		local separator = "@@" 		local tt = {}                                         -- create an arrary for markers 		local count = 1                                       -- local counter for arrary tt 		local output = ""                                     -- output - destination of all markers  		    newdata = string.gsub(newdata,"@","BULLET")  		    newdata = string.gsub(newdata,"\n+"," ")   		    newdata = string.gsub(newdata,"%s+"," ") 			newdata = string.gsub(newdata,"%{%{ Marker","@@{{marker") 			newdata = string.gsub(newdata,"%{%{ marker","@@{{marker") 			newdata = string.gsub(newdata,"%{%{Marker","@@{{marker")			 			newdata = string.gsub(newdata,"%{%{marker","@@{{marker") 			newdata = string.gsub(newdata,"@@@@","@@") -- if newdata ~= nil then return newdata end 		for str in string.gmatch(newdata,"([^"..separator.."]+)") do             if string.find(str,"^%{%{marker") ~= nil then 			   str = str.gsub(str,"}}.*","") 			   str = "@" .. str .. "@" 			   str = str.gsub(str,"= ","=") 			   str = str.gsub(str," =","=")			    			   str = str.gsub(str,"name=","@n") 			   str = str.gsub(str,"lat=","@a") 			   str = str.gsub(str,"long=","@b") 			   str = str.gsub(str,"wikidata=","@w") 			   str = str.gsub(str,"zoom=","@z") 			   str = str.gsub(str,"type=","@t") 			   str = str.gsub(str,"url=","@u") 			   str = str.gsub(str,"image=","@i") 			   str = str.gsub(str,"^@{{marker","@xmarker") 			   str = str.gsub(str,"%s&s+"," ") 			   str = str.gsub(str,"%s@","@") 			    			   str = string.gsub(str,"%s*|%s*@","@") 			   str = string.gsub(str,"@$","")                output = output .. str .. ":"			                   tt[count] = str 		       count = count + 1              end				    		end 			 output,_ = string.gsub(output,":$","") return output  end  function p.combo(frame)     local id = frame.args['id'] or "" 	local latitude = "" 	local longitude = "" 	local name = frame.args['name'] or "" 	local osm = "none" 	local linkosm = ""     local entity = ""     if id == "" or id == nil then     	id=mw.wikibase.getEntityIdForTitle(name)     end     entity = mw.wikibase.getEntityObject(id)	 	if entity == nil then 		 return  "id=" .. id .. " name=" .. name .. " latitude=" .. latitude .. " longitude=" .. longitude .. " osm=" .. osm 		end    		 	local claims = entity.claims 	if claims == nil then 		return "id=" .. id .. " name=" .. name .. " latitude=" .. latitude .. " longitude=" .. longitude .. " osm=" .. osm  	end	 	if claims.P625 ~= nil then  		if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		 		    latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 			latitude = string.format("%.6f",latitude)		      		else 			latitude = "" 		end  		if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then		 		    longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 		    longitude = string.format("%.6f",longitude)			 		else 			longitude = "" 		end 	end 	if claims.P402 ~= nil then 		osm = entity.claims.P402[1].mainsnak.datavalue.value or "none" 		if osm == nil then osm = "none" end 		if osm ~= "none" then linkosm = "[https://www.openstreetmap.org/relation/" .. osm .. " " .. osm .. "]" 			osm = linkosm 			end 	end	 	if pcall(function()t1 = entity:getSitelink("enwikivoyage") end) then 		name = entity:getSitelink("enwikivoyage") or "" 		if name ~= nil and name ~= "" then 			name = "wv: [[" .. name  .."]]" 			else name = "wv: ----" 		end 	end 	return "* id='''" .. id .. "''' name=" .. name .. " latitude=" .. latitude .. " longitude=" .. longitude .. " osm=" .. osm end  function p.checkuni(frame)  		local page = frame.args['page']	 		local separator = frame.args['separator'] or " " -- added so can put in a different separator default is space 		if separator == nil or separator == "" then separator = " " end         local newdata = ""         local title = mw.title.new(page)         if title == nil then return "Non-existant or empty page! " .. page end         if title.id == 0 then             return "Page: " .. page .. " does not exist!"         end          newdata = title:getContent()         if newdata == nil or newdata == "" or not newdata == true then       	   return "No page data to work with! " .. page         end         local output = ""         local counter = 1          for txt in string.gmatch(newdata,"([^"..separator.."]+)") do                      if mw.ustring.match(txt,"‎") ~= nil then                 output = output .. counter .. " " .. txt .. " "                 counter = counter + 1              end          end return output end   function p.checkevent(frame) 		local page = frame.args['page']	         local newdata = ""         local title = mw.title.new(page)         if title == nil then return "Non-existant or empty page! " .. page end          if title.id == 0 then             return "Page: " .. page .. " does not exist!"         end          newdata = title:getContent()         if newdata == nil or newdata == "" or not newdata == true then       	   return "No page data to work with! " .. page         end         local name = ""         local year = ""         local month = ""         local date = ""         local endyear = ""         local endmonth = ""         local enddate = ""         local yymmdd = ""         local endyymmdd = ""         local frequency = ""         local separator = "@@@@"         local counter = 1        	    local formatcheck = "" 	    local checkdate = ""               checkdate = os.date("%Y%m%d")         local eventenddate = ""         local output = ""         local message = ""         local strcopy = ""                          local list = {}         list[1] = {month="[Jj]an%a*",value="01"}         list[2] = {month="[Ff]eb%a*",value="02"}         list[3] = {month="[Mm]ar%a*",value="03"}         list[4] = {month="[Aa]pr%a*",value="04"}         list[5] = {month="[Ma]ay%a*",value="05"}         list[6] = {month="[Jj]un%a*",value="06"}         list[7] = {month="[Jj]ul%a*",value="07"}         list[8] = {month="[Aa]ug%a*",value="08"}         list[9] = {month="[Ss]ep%a*",value="09"}         list[10] = {month="[Oo]ct%a*",value="10"}         list[11] = {month="[Nn]ov%a*",value="11"}         list[12] = {month="[Dd]ec%a*",value="12"}           if string.find(newdata,"{{%s*[Ee]vent") == nil then 			return "No events found in page: " .. page .. "\n" 			end 			          newdata = string.gsub(newdata,"@","BULLETX")			 	     newdata = string.gsub(newdata,"{{%s*[Ee]vent","@@@@{{Event") 		          for str in string.gmatch(newdata,"([^"..separator.."]+)") do           if string.find(str,"^%{%{[Ee]vent") ~= nil then            	 str = string.gsub(str,"{{%s*[Ee]vent","")              str = string.gsub(str,"=%{%{","=opencurlyopencurly")              str = string.gsub(str,"}}%s*|","closecurlyclosecurly|")              str = string.gsub(str,"}}%s*}}","closecurlyclosecurly}}")               str = string.gsub(str,"}}.*","")              str = string.gsub(str,"%s*|%s*","@")              str = "@" .. str .. "@"                           str = string.gsub(str,"@%s*@","@")              str = string.gsub(str,"%s*=%s*","=")              str = string.gsub(str,"@yymmdd=@","@")              str = string.gsub(str,"@endyymmdd=@","@")              str = string.gsub(str,"@endyear=@","@")              str = string.gsub(str,"@endmonth=@","@")              str = string.gsub(str,"@enddate=@","@")                           str = string.gsub(str,"%s@","@")                                           name = string.gsub(string.gsub(str,"^.*@name=",""),"@.*","")                 if string.find(str,"yymmdd") ~= nil then                  yymmdd = string.gsub(string.gsub(str,"^.*@yymmdd=",""),"@.*","")                  yymmdd = string.gsub(yymmdd,"%s*-%s*","")                  year = string.sub(yymmdd,1,4)                  month = string.sub(yymmdd,5,6)                  date = string.sub(yymmdd,7,8)                end                  if string.find(str,"endyymmdd") ~= nil then                    endyymmdd = string.gsub(string.gsub(str,"^.*@yymmdd=",""),"@.*","")                    endyymmdd = string.gsub(yymmdd,"%s*-%s*","")                    endyear = string.sub(yymmdd,1,4)                    endmonth = string.sub(yymmdd,5,6)                    enddate = string.sub(yymmdd,7,8)                end                if year == nil or year == "" then                   year,_  = string.gsub(string.gsub(str,"^.*@year=",""),"@.*","")               end                if month == nil or month == "" then                   month,_ = string.gsub(string.gsub(str,"^.*@month=",""),"@.*","")               end                if date == nil or date == ""then                  date,_ = string.gsub(string.gsub(str,"^.*@date=",""),"@.*","")               end                if endyear == nil or endyear == "" then                    endyear,_  = string.gsub(string.gsub(str,"^.*@endyear=",""),"@.*","")               end                if endyear == nil or endyear == "" then               	endyear = year               end                if endmonth == nil or endmonth == "" then                   endmonth,_  = string.gsub(string.gsub(str,"^.*@endmonth=",""),"@.*","")               end                if endmonth == nil or endmonth == "" then               	endmonth = month               end                if endmonth == nil or endmonth == "" == nil then               	endmonth = "00"               	formatcheck = formatcheck .. " endmonth - notfound!"               end                if enddate == nil or enddate == "" then               enddate,_ = string.gsub(string.gsub(str,"^.*@enddate=",""),"@.*","")               end                if enddate == nil or enddate == "" then               	enddate = date               end                if enddate == nil or enddate == "" then               	enddate = "00"               	formatcheck = formatcheck .. " enddate - not found - set check enddate to 00!"               end                frequency,_ = string.gsub(string.gsub(str,"^.*@frequency=",""),"@.*","")                 for i=1,#list do                    endmonth = string.gsub(endmonth,list[i].month,list[i].value)	                end                if string.match(endmonth,"^%d$") ~= nil then                  	endmonth = string.format("%02d",tonumber(endmonth))                end                if string.match(endmonth,"^%d%d$") == nil then                	    formatcheck = formatcheck .. " format for endmonth is invalid - set check endmonth to 00!"                	endmonth = "00"                end                 if string.match(enddate,"^%d$") ~= nil then                  	enddate = string.format("%02d",tonumber(enddate))                end                if string.match(enddate,"^%d%d$") == nil then                	formatcheck = formatcheck .. " format for enddate is invalid! - set check enddate to 00"                	enddate = "00"                end               if string.match(endyear,"^%d%d%d%d$") == nil then               	if string.match(endyear,"[Aa]nnual") ~= nil or frequency ~= nil or frequency ~= ""               	   then               	   	  formatcheck = formatcheck .. " Annual or Frequency set check endyear to 3000 "               	      endyear = "3000"               	   else                	      formatcheck = formatcheck .. " format for endyear/year invalid set check endyear to 1000 "                       	endyear = "1000"                     end                end               eventenddate = endyear .. endmonth .. string.format("%02d",enddate)                if frequency ~= nil and frequency ~= "" then                     message = message .. " '''<span style= \"color:limegreen;\">Event entry of Frequency type! </span>''' "                	end                  if year == "annual" or year == "Annual" then                    message = message .. " '''<span style= \"color:limegreen;\">Event appears to be an Annual event! Event appears to be still a go!</span>''' "                    elseif tonumber(checkdate) > tonumber(eventenddate) then                 	      message = message .. " '''<span style= \"color:red;\">Event appears to be over!</span>''' "                  else                         message = message .. " '''<span style= \"color:limegreen;\">Event appears to be still a go! </span>''' "                 end                               str = string.gsub(str,"^@","")               str = string.gsub(str,"@$","")               str = string.gsub(str,"@"," | ")               str = string.gsub(str,"BULLETX","@")               str = string.gsub(str,"opencurly","{")               str = string.gsub(str,"closecurly","}") str = string.gsub(str,"&#123;","{") str = string.gsub(str,"&#x7b;","{") str = string.gsub(str,"&#125;","}") str = string.gsub(str,"&#x7d;","}") str = string.gsub(str,"&#124;","|") str = string.gsub(str,"&#x7c;","|")               strcopy = "<div style=\"color:black; background:papayawhip; border:1px solid black;\">" .. str .. "</div>"               str = "{{event|" .. str .. "}}"               formatcheck = string.gsub(formatcheck,"^%s*","")               output = output .. "<div class=\"rectangle\" style=\"width:100px; height:10px; background-color:black\"></div>" .. "\n"               output = output .. "----\n* '''Page''': " .. page .. "''' Event''': " .. name .. " '''Results''': " .. message .. " '''Event end date''': "               output = output .. eventenddate ..  "  '''Check date''': " .. checkdate ..  " '''date''': " .. date .. " '''month''': " .. month .. " '''year''' " .. year ..  " '''enddate''': " .. enddate .. " '''endmonth''': " .. endmonth .. " '''endyear''': " .. endyear .. "\n"               if formatcheck ~= nil and formatcheck ~= "" then               	output = output .. "\n* " .. str .. "\n\n* " .. strcopy  .. "\n\n*" .. "'''Verify all parameter format & useage requirements!''' " .. formatcheck               	else                   output = output .. "\n* " .. str .. "\n\n* " .. strcopy .. "\n\n* '''Verify all parameter formats & useage requirements!'''\n----\n"                end   -- clear - start anew               title = ""               name = ""               year = ""               month = ""               date = ""               endyear = ""               endmonth = ""               enddate = ""               yymmdd = ""               endyymmdd = ""               eventenddate = ""               frequency = ""               message = ""               formatcheck = ""               strcopy=""           end       end     return output	  end  function p.events(frame)     local output = ""     checkdate = os.date("%Y%m%d")     local sortby = frame.args['sortby'] or "begindate"     beginevent = ""     endevent = ""     order = {}     order2 = {}     order3 = {}     counter = 1     local name = ""     local image = ""     local list = {}         list[1] = {month="[Jj]an%a*",value="01"}         list[2] = {month="[Ff]eb%a*",value="02"}         list[3] = {month="[Mm]ar%a*",value="03"}         list[4] = {month="[Aa]pr%a*",value="04"}         list[5] = {month="[Ma]ay%a*",value="05"}         list[6] = {month="[Jj]un%a*",value="06"}         list[7] = {month="[Jj]ul%a*",value="07"}         list[8] = {month="[Aa]ug%a*",value="08"}         list[9] = {month="[Ss]ep%a*",value="09"}         list[10] = {month="[Oo]ct%a*",value="10"}         list[11] = {month="[Nn]ov%a*",value="11"}         list[12] = {month="[Dd]ec%a*",value="12"}     local events = {}         events[1] = {name="World Youth Day in Panama City", text="World Youth Day in Panama, [[Panama]], 22-27 January",     				year="2019", month="January", day="22", endyear="2019", endmonth="January", endday="27"}     events[2] = {name="Winter Universiade 2019", text="Winter Universiade 2019, in [[Krasnoyarsk]], [[Russia]], March 2-12",     				year="2019", month="March", day="2", endyear="2019", endmonth="March", endday="12"}     events[3] = {name="European Capital of Culture", text="European Capital of Culture, [[Matera]] [[Italy]] and [[Plovdiv]] [[Bulgaria]]",     			year="2019", month="January", day="1", endyear="2020", endmonth="December", endday="31"}     events[4] = {name="2019 South Asian Games", text="2019 South Asian Games, in [[Kathmandu]] and [[Pokhara]], [[Nepal]], 9–18 March",     			year="2019", month="March", day="9", endyear="2019", endmonth="March", endday="18"}     events[5] = {name="Special Olympics World Summer Games", text="Special Olympics World Summer Games, [[Abu Dhabi]], [[United Arab Emirates]], 14–21 March",     			year="2019", month="March", day="14", endyear="2019", endmonth="March", endday="21"}     events[6] = {name="Eurovision song contest", text="Eurovision song contest, [[Tel Aviv]], [[Israel]], Tuesday 14, Thursday 16 and Saturday 18 May 2019",     			year="2019", month="May", day="14", endyear="2019", endmonth="May", endday="18"}     events[7] = {name="Travelling during Ramadan", text="[[Travelling during Ramadan]], 6 May–3 June",     			year="2019", month="May", day="6", endyear="2019", endmonth="June", endday="3"}     events[8] = {name="WorldPride New York",text="2019 WorldPride [[New York City | NYC]], 1-30 June",     			year="2019", month="June", day="1", endyear="2019", endmonth="June", endday="1"}     events[9] = {name="2019 Summer Universiade", text="2019 Summer Universiade, [[Naples]], [[Italy]], in July",     			year="2019", month="July", day="3", endyear="2019", endmonth="July", endday="14"}     events[10] = {name="2019 Pacific Games", text="2019 Pacific Games, [[Apia]], [[Samoa]], 8-20 July",     			year="2019", month="July", day="8", endyear="2019", endmonth="July", endday="20"}     events[11] = {name="Wikimania", text="Wikimania, [[Stockholm]]], [[Sweden]] 14-18 August",     			year="2019", month="August", day="14", endyear="2019", endmonth="August", endday="18"}     events[12] = {name="Pan American/Parapan American Games", text="Pan American/Parapan American Games, in [[Lima]], [[Peru]], 26 July 26-1 September",     			year="2019", month="September", day="26", endyear="2019", endmonth="September", endday="26"}     events[13] = {name="Toronto International Film Festival", text="Toronto International Film Festival, in [[Toronto]], [[Canada]], 5–15 September",     			year="2019", month="September", day="5", endyear="2019", endmonth="September", endday="15"}     events[14] = {name="12th African Games", text="12 African Games, in [[Casablanca]], [[Morocco]], 14-31 October",     			year="2019", month="October", day="14", endyear="2019", endmonth="October", endday="14"}     events[15] = {name="Southeast Asian Games", text="Southeast Asian Games, the [[Philippines]], 29 November-10 December",     	year="2019", month="November", day="29", endyear="2019", endmonth="December", endday="29"}     events[16] = { name="Invictus Games", image="Invictus games logo cropped.png", text="From Oct 20-27, 2018, [[Sydney]], [[Australia]], will host the '''Invictus Games''', an international multi-sport event in which wounded, injured or sick armed services personnel and veterans take part in sports.",     			year="2018", month="October", day="20", endyear="2018", endmonth="October", endday="27" }      for i=1,#events do          if events[i].endyear == nil then events[i].endyear = events[i].year end          if events[i].endmonth == nil then events[i].endmonth = events[i].month end          if events[i].endday == nil then events[i].endday = events[i].day end     	    for x=1,#list do                events[i].month = string.gsub(events[i].month,list[x].month,list[x].value)                events[i].endmonth = string.gsub(events[i].endmonth,list[x].month,list[x].value)                          end           if events[i].image == nil then events[i].image = "" end           events[i].day = string.format("%02d",tonumber(events[i].day))           events[i].endday = string.format("%02d",tonumber(events[i].endday))           beginevent = events[i].year .. events[i].month .. events[i].day           endevent = events[i].endyear .. events[i].endmonth .. events[i].endday                      order[counter] = "@a" .. beginevent .. "@b" .. endevent .. "@n" .. events[i].name .. "@i" .. events[i].image .. "@t" .. events[i].text           order2[counter] = "@b" .. endevent .. "@a" .. beginevent .. "@n" .. events[i].name .. "@i" .. events[i].image .. "@t" .. events[i].text                  counter = counter + 1     end          table.sort(order)      counter = 1         for i=1,#order do         beginevent = string.gsub(order[i],"^.*@a","")         beginevent = string.gsub(beginevent,"@.*$","")         endevent =string.gsub(order[i],"^.*@b","")         endevent = string.gsub(endevent,"@.*$","")                 name = string.gsub(order[i],"^.*@n","")         name = string.gsub(name,"@.*$","")                  image = string.gsub(order[i],"^.*@i","")         image = string.gsub(image,"@.*$","")                  text = string.gsub(order[i],"^.*@t","")         text = string.gsub(text,"@.*$","")                   if tonumber(checkdate) > tonumber(endevent) then            output = output .. "* Event " .. name .. " has expired!"  .. checkdate .. " " .. beginevent .. " " .. endevent .. "\n"         elseif tonumber(checkdate) >= tonumber(beginevent) and tonumber(checkdate) <= tonumber(endevent) then            output = output .. "* Event " .. name .. " is happening"  .. checkdate .. " " .. beginevent .. " " .. endevent .. "\n"          elseif tonumber(checkdate) > tonumber(beginevent) - 30 and tonumber(checkdate) < tonumber(endevent) then                 output = output .. "* Event " ..name .. " attempt at 30 day notice! !"  .. checkdate .. " " .. beginevent .. " " .. endevent .. "\n"           elseif tonumber(checkdate) < tonumber(beginevent) and tonumber(checkdate) < tonumber(endevent) then          	    output = output .. "*Event " .. name .. " is a future event! " .. checkdate .. " " .. beginevent .. " " .. endevent .. "\n"          else          	output = output .. checkdate .. "CHECK " .. beginevent .. " " .. endevent .. "\n"          end     end --    output = "|title2=" .. events[1].name .. "|content2=" .. events[1].text return output  end   -- below replaced with quickgrab2 below -- TO BE REMOVED  function p.quickgrab(frame) 	    local page = frame.args['page'] or "Ethiopia" 	    local type = frame.args['type'] or "marker" 	    local subtype = frame.args['subtype'] or "" 	    local pattern = "" 	    local counter = 0 	    local copypattern = "" --	    type = string.gsub(type,"(%a)(.*)","[" .. string.upper(%1) .. string.lower(%1) .. "]%2")         local title = mw.title.new(page)         if title == nil then return "Non-existant or empty page! " .. page end                  if title.id == 0 then             return "Page: " .. page .. " does not exist!"         end          local newdata = title:getContent()                  if newdata == nil or newdata == "" or not newdata == true then       	   return "No data to work with on page: " .. page         end          -- Special spot for addition-- UTF-8 characters if need be for gsub as they can kill processing in places          newdata = string.gsub(newdata,"ö","UMLAUT")         newdata = string.gsub(newdata,"ß","SSSSS")         -- General can get away with         	newdata = string.gsub(newdata,"%s*|%s*","|") -- yes - no spaces around        	newdata = string.gsub(newdata,"%s+"," ") -- down to single spacing -- see also -- anchor        	if type ~= "IATA" then              newdata = string.gsub(newdata,"{{IATA(%|*%w*)}}","opencurlyopencurlyIATA%1closecurlyclosecurly")      	         end                  if type ~= "rint" then             newdata = string.gsub(newdata,"{{rint(%|*%w*%|*%w*)}}","opencurlyopencurlyrint%1closecurlyclosecurly")             newdata = string.gsub(newdata,"{{rint(%/*%w*%|*%w*)}}","opencurlyopencurlyrint%1closecurlyclosecurly")             newdata = string.gsub(newdata,"{{rint(%/*%w*%|*%w*%|*%w*)}}","opencurlyopencurlyrint%1closecurlyclosecurly")        	         end         if type == "flag+" then         	type = "flag"         	newdata = string.gsub(newdata,"{{flag|(%w*%s*%w*%s*%w*%s*%w*%s*%w*%s*%w*%s*)}}%s*{{","{{flag|%1closecurlyclosecurly opencurlyopencurly")         end         if type ~= "station" then              pattern="|%w*%/*%s*%w*"              counter = 0              copypattern=pattern              for i=1,15 do                 newdata,counter = string.gsub(newdata,"{{station(" .. copypattern .. ")}}","opencurlyopencurlystation%1closecurlyclosecurly")                copypattern = copypattern .. pattern              end          end         if type ~= "station" and type ~= "rint" and type ~= "marker" and type ~= "anchor" then --        newdata = string.gsub(newdata,"%*%s*%{%{","*{{")         newdata = string.gsub(newdata,"%{%{%{%{","{{opencurlyopencurly") -- Question - internal template?         newdata = string.gsub(newdata,"}}}}","closecurlyclosecurly}}")         newdata = string.gsub(newdata,"%{%{%{","opencurlyopencurlyopencurly")         newdata = string.gsub(newdata,"}}}","closecurlyclosecurlyclosecurly")         newdata = string.gsub(newdata,"=%{%{","=opencurlyopencurly")          newdata = string.gsub(newdata,"}}%s*|","closecurlyclosecurly|") --        newdata = string.gsub(newdata,"}} ","closecurlyclosecurly ") --        newdata = string.gsub(newdata,"}}%,","closecurlyclosecurly,") --        newdata = string.gsub(newdata,"}}%;","closecurlyclosecurly;")         newdata = string.gsub(newdata,"}}%s*}}","closecurlyclosecurly}}")         newdata = string.gsub(newdata,"@","BULLET")                  else          	         end                  local output = ""  -- local xyz = string.match (mw.title.new ('United States National Parks'):getContent(), '{{ *marker *| *([^}]+) *}}')         local zip = type --        zip = "[" .. string.upper(string.sub(type,1,1)) .. string.lower(string.sub(type,1,1)) .. "]"  .. string.sub(zip,2,20)         if subtype == nil or subtype == "" then              for i in string.gmatch (newdata, '{{%s*' .. zip .. '%s*|%s*([^}]+)%s*}}') do                 output = output .. "\n* {{" .. type .. "|" .. i .. "}}"              end         else              for i in string.gmatch (newdata, '{{%s*' .. zip .. '%s*|%s*type=' .. subtype .. '%s*|%s*([^}]+)%s*}}') do                 output = output .. "\n* {{" .. type .. "| type=" .. subtype .. "|" .. i .. "}}"              end	         end         output = string.gsub(output,"opencurly","{")         output = string.gsub(output,"closecurly","}")         output = string.gsub(output,"BULLET","@")         output = string.gsub(output,"UMLAUT","ö")         output = string.gsub(output,"SSSSS","ß")         return output     end  -- Generally speaking - listing templates such as see can contain marker, station and rint templates and hopefully not another see template -- markers, station and rint templates can be extracted on their own - or can grab station & other templates within the confines of -- an overall template - this insures the complete template one is looking for... -- Matroc -- getname  local function for quickgrab2  local function getname(page) 	local name=mw.wikibase.getEntityIdForTitle(page) 	if name == "" or name == nil then return "" end 	return name 	end  function p.quickgrab2(frame) 	    local sort = frame.args['sort'] or "no" 	    local sortname = "" 	    local sectionorig = frame.args['section'] or "" 	    local section = "" 	    local sectionx = "" 	    local level = frame.args['level'] or "0" 	    if sectionorig == nil or sectionorig == "" then 	    	level = "0" 	    end 	    if tonumber(level) <= 1 or tonumber(level) > 5 then 	    	level = "0" 	    	sectionorig = "" 	    end 	    local name = frame.args['name'] or ""          -- look for particular name=aaaaa aaa         local counter = 1                              -- counter for array content         local content = {}                             -- array for matching template entries         local x = ""                                   -- beginning position for template str to be output         local y = ""                                   -- end position of template str to be output         local output = ""                              -- concatenated output of found template strings         local separator = "@@@@@"                      -- separator to split page up by	 	    local page = frame.args['page'] or ""          -- page to lookup and work from 	    local type = frame.args['type'] or ""          -- type of listing to search for (ie listing) 		local typeul = ""                              -- type for replacement 1st character becomes {Aa]	     	    local subtype = frame.args['subtype'] or ""    -- specific type to select from  	    local subtypeul = ""                           -- 1st character for replacement 1st character becomes [Aa] 	    local zip = ""                                 -- used to copy typeul and/or subtypeul 	    local replacement = ""                         -- replacement string to make templates in common form	             local title = mw.title.new(page)               -- create an empty new page workspace -- later get Content of existing page to work with                   if type == nil or type == "" then         	return "Selection type is missing for page: " .. page end                  if title == nil then return "Non-existant or empty page! " .. page end                  if title.id == 0 then             return "Page: " .. page .. " does not exist!"         end         local id = getname(page)                 -- certain mapshapes don't have anything but would need id         local newdata = title:getContent()         local part1 = ""         local part2 = ""                           -- split up newdata if need be to 2 parts then recombine         local a,b,c,d = 0                  if newdata == nil or newdata == "" or not newdata == true then       	   return "No data to work with on page: " .. page         end         if sectionorig ~= nil and sectionorig ~= "" then 	         sectionorig = string.gsub(sectionorig,"@","|")              if level == "5" then 	            section = "section5" .. sectionorig .. "section5"         	    sectionx = "section5 " .. sectionorig .. " section5"              end	              if level == "4" then 	              section = "section4" .. sectionorig .. "section4"         	      sectionx = "section4 " .. sectionorig .. " section4"	                       end	              if level == "3" then         	      section = "section3" .. sectionorig .. "section3"         	      sectionx = "section3 " .. sectionorig .. " section3"               end              if level == "2" then         	    section = "section2" .. sectionorig .. "section2"         	    sectionx = "section2 " .. sectionorig .. " section2"              end             newdata = string.gsub(newdata,"%(","openparens")             newdata = string.gsub(newdata,"%)","closeparens")             newdata = string.gsub(newdata,"%|","PIPE")             newdata = string.gsub(newdata,"%.","PERIOD")             newdata = string.gsub(newdata,"%,","COMMA")             newdata = string.gsub(newdata,"(==+)(%[+%s*)","%1")             newdata = string.gsub(newdata,"(%s*%]+)(==+)","%2")             newdata = string.gsub(newdata,"openparens","(")             newdata = string.gsub(newdata,"closeparens",")")             newdata = string.gsub(newdata,"PIPE","|")             newdata = string.gsub(newdata,"PERIOD",".")             newdata = string.gsub(newdata,"COMMA",",")             newdata = string.gsub(newdata,"=====","section5")             newdata = string.gsub(newdata,"====","section4") 	        newdata = string.gsub(newdata,"===","section3") 	        newdata = string.gsub(newdata,"==","section2")             if string.find(newdata,sectionx .. ".*") ~= nil                then section = sectionx             end         	if string.find(newdata,section .. ".*") == nil then return "section not found"         		else                    a,b = string.find(newdata,section .. ".*")                    newdata = string.sub(newdata,a)                    part1 = newdata                 	end         	if string.find(newdata,section .. ".*",10) ~= nil then                 c,d=string.find(newdata,section .. ".*",10)                 part1 = string.sub(newdata,1,c)                 part2 = string.sub(newdata,c)             end             part1 = string.gsub(part1,section,"BEGINSECTION")             part2 = string.gsub(part2,section,"BEGINSECTION")         	if level == "2" then         		part1 = string.gsub(part1,"section2.*","")         		part2 = string.gsub(part2,"section2.*","")        		         		end         	if level == "3" then         		part1 = string.gsub(part1,"section[23].*","")         		part2 = string.gsub(part2,"section[23].*","")         		end         	if level == "4" then         		part1 = string.gsub(part1,"section[234].*","")		         		part2 = string.gsub(part2,"section[234].*","")		                 end             if level == 5 then         		part1 = string.gsub(part1,"section[2345].*","")         		part2 = string.gsub(part2,"section[2345].*","")		        		                 end             newdata = part1 .. part2             part1 = ""             part2 = ""         	newdata = string.gsub(newdata,"BEGINSECTION",section)         	newdata = newdata         end          newdata = string.gsub(newdata,"\n", " ")                 newdata = string.gsub(newdata,"%s+"," ")         newdata = string.gsub(newdata,"@","BULLET")                           -- avoiding @ clash with @@@@@ separator         newdata = string.gsub(newdata,"{{%s*","{{")         newdata = string.gsub(newdata,"%s*}}","}}")                 newdata = string.gsub(newdata,"%s*|%s*","|")         newdata = string.gsub(newdata,'%{%{seealso','{{SEEALSO')         newdata = string.gsub(newdata,'%{%{see also','{{SEEALSO')         newdata = string.gsub(newdata,'%{%{[Ss]eeDistricts}}','SEEDISTRICTS')   -- other hatnotes could be added here as well                                                                                 -- to avoid issues with listing templates  -- should always have a type - marker,listing,see,mapframe,station,rint etc.          if type == "flag+" then     -- common form substitution to get {{flag}} {{listing combinations         	type = "flag"             newdata = string.gsub(newdata,"-","HYPHEN")   -- special to be able to make match/substitutions             newdata = string.gsub(newdata,"ã","AACCENTA")             newdata = string.gsub(newdata,"é","EACCENTE")             newdata = string.gsub(newdata,"í","IACCENTI")             newdata = string.gsub(newdata,"'","ACCENT")         	newdata = string.gsub(newdata,"{{[Ff]lag|(%w*%s*%w*%s*%w*%s*%w*%s*%w*%s*%w*)}}%s*{{","{{flag|%1closecurlyclosecurly opencurlyopencurly")             newdata = string.gsub(newdata,"HYPHEN","-")             newdata = string.gsub(newdata,"AACCENTA","ã")             newdata = string.gsub(newdata,"EACCENTE","é")             newdata = string.gsub(newdata,"IACCENTI","í")             newdata = string.gsub(newdata,"ACCENT","'")         end         -- Some put in lowercase first character others uppercase - this should match up ok               zip = type                 typeul = "[" .. string.upper(string.sub(zip,1,1)) .. string.lower(string.sub(zip,1,1)) .. "]"  .. string.sub(zip,2,20)         replacement = typeul                  if subtype ~= nil and subtype ~= "" then         	 zip = subtype              subtypeul = "[" .. string.upper(string.sub(zip,1,1)) .. string.lower(string.sub(zip,1,1)) .. "]"  .. string.sub(zip,2,20)              replacement = replacement .. "|type=" .. subtypeul              newdata = string.gsub(newdata,"{{" .. replacement,"@@@@@{{" .. type .. "|type=" .. subtype)            else              newdata = string.gsub(newdata,"{{" .. replacement,"@@@@@{{" .. type)         end          for str in string.gmatch(newdata,"([^"..separator.."]+)") do             if string.find(str,"^%{%{" .. replacement) ~= nil then                 if str ~= nil then                    x,y = string.find(str,"%b{}")                    if x ~= nil and y ~= nil then                        str = string.sub(str,x,y)                        str = string.gsub(str,"BULLET","@")                        if name == nil or name == "" then --                             str = string.gsub(str,"^","\n%* ")                                if sort == "yes" then                                   sortname = string.gsub(str,"^.*name=","")                          --       sortname = string.gsub(sortname,"|.*","") -- sort by internal link                                   sortname = string.gsub(sortname,"|%s*%w*=.*","")    -- sort by name                                   sortname = string.gsub(sortname,"^.*|","")          -- sort by name                                                                     sortname = string.gsub(sortname,"}}.*","")                                   sortname = str.gsub(sortname,"%[+","")                                   sortname = sortname .. string.rep(".", 20 - #sortname)                                   sortname = string.upper(sortname)                                   str = sortname .. "SORTIT" .. str                                   end                              content[counter],_ = str                              counter = counter + 1 elseif string.find(str,"|name=" .. name) ~= nil or string.find(str,"|name=%[%[" .. name) ~= nil or string.find(str,"name=%[%[%s*.*%s*|%s*" .. name) ~= nil then --                             str = string.gsub(str,"^","\n%* ")                                if sort == "yes" then                                   sortname = string.gsub(str,"^.*name=","")                          --       sortname = string.gsub(sortname,"|.*","") -- sort by internal link                                   sortname = string.gsub(sortname,"|%s*%w*=.*","")    -- sort by name                                   sortname = string.gsub(sortname,"^.*|","")           -- sort by name                                   sortname = string.gsub(sortname,"}}.*","")                                   sortname = str.gsub(sortname,"%[+","")                                     sortname = sortname .. string.rep(".", 20 - #sortname)                                   sortname = string.upper(sortname)                                   str = sortname .. "SORTIT" .. str                                   end                              content[counter],_ = str                              counter = counter + 1		                         end                    end                 end             end        end        if sort == "yes" then table.sort(content) end        -- want some output to not be preceded by an *        -- some templates like geo can't stand apaces befor and after |        for i=1,#content do        	   if string.match(type,"^[Mm]ap.*") ~= nil or string.match(type,"^[Gg]eo.*") ~= nil then        	   	  if string.match(type,"[Mm]apshape") ~= nil and string.match(content[i],"{{[Mm]apshape}}") ~= nil then                 if id ~= nil then                 	content[i] = string.gsub(content[i],"}}","|wikidata=" .. id .. "}}")    	   	  	        end    	   	  	    end        	   	  if string.match(type,"[Mm]apframe") ~= nil and string.match(content[i],"{{[Mm]apframe.*}}") ~= nil then                 if string.match(content[i],"name=") == nil then                 	content[i] = string.gsub(content[i],"}}","|name=" .. page .. "}}")    	   	  	        end    	   	  	    end   	   	  	        	   	  	            	   	  if string.match(type,"^[Gg]eo.*") ~= nil then        	   	  	  content[i] = string.gsub(content[i],"|","PIPE")        	   	  	  end  	          output = output .. "\n" .. string.gsub(content[i],".*SORTIT","")  	          else  	          output = output .. "\n* " .. string.gsub(content[i],".*SORTIT","") 	          	  	          end          end       output = string.gsub(output,"opencurly","{")       output = string.gsub(output,"closecurly","}")       output = string.gsub(output,"%{%{SEEALSO","{{see also")       output = string.gsub(output,"%{%{SEEDISTRICTS","SeeDistricts")       output = string.gsub(output,"|"," | ")       output = string.gsub(output,"PIPE","|")       return output	        end        -- getting lat long image via passing an ID local function returnitems(wikidata) 	local latitude = "" 	local longitude = "" 	local image = "" 	local id = wikidata     local entity = mw.wikibase.getEntityObject(id)	 	if entity == nil then return latitude,longitude,image end    		 	local claims = entity.claims 	if claims == nil then 		return latitude,longitude,image 	end	 	if claims.P625 ~= nil then 		latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 	end 	if claims.P625 ~= nil then 		longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 	end 	if claims.P18 ~= nil then 	   image = entity.claims.P18[1].mainsnak.datavalue.value 	end 	return latitude,longitude,image end  -- MOST OUTPUT FIXED  function p.returnit(frame) 	local data = frame.args[1] or "" 	local group = frame.args['group'] or "luksee" 	local show = frame.args['show'] or group 	local records = {} 	for i=1,100 do 		records[i] = {} 		records[i]['name'] = "" 		records[i]['wikidata'] = "" 		records[i]['lat'] = "" 		records[i]['long'] = "" 		records[i]['image'] = "" 		records[i]['description'] = "" 	end 	local separator = "ENDREC" 	local counter = 1 	local nolistings = 0 	local name= "" 	local wikidata = "" 	local lat = "" 	local long = "" 	local latitude = ""      -- from wikidata 	local longitude = ""     -- from wikidata 	local image = "" 	local latitudexx = "" 	local longitudexx = "" 	local imagexx = ""        -- from wikidata 	local description = "" 	local beginit = "" 	local endit = ""     local output = ""     local symbol = frame.args['symbol'] or "star"     local color = frame.args['color'] or "#ffaabb"  	for line in string.gmatch(data,"([^"..separator.."]+)") do 		if line ~= "" and line ~= nil then             line = "@@@@@" .. line line = string.gsub(line,"XPIPEX","|") --line = string.gsub(line,"EQUALS","=")             line = string.gsub(line,"%}%}","@@@@@")             line = string.gsub(line,'%}%}','')             line = string.gsub(line,"%|","@@@@@")             name = string.gsub(string.gsub(line,'^.*name%=',''),'@@@@@.*','')             wikidata = string.gsub(string.gsub(line,'^.*wikidata%=',''),'@@@@@.*','')             lat = string.gsub(string.gsub(line,'^.*lat%=',''),'@@@@@.*','')             long = string.gsub(string.gsub(line,'^.*long%=',''),'@@@@@.*','')             image = string.gsub(string.gsub(line,'^.*image%=',''),'@@@@@.*','')             description = string.gsub(string.gsub(line,'^.*content%=',''),'@@@@@.*','')  --            if wikidata ~= nil and wikidata ~= "" then --                latitudexx,longitudexx,imagexx = returnitems(wikidata) --                if lat == nil or lat == "" then lat = latitudexx end --                if long == nil or long == "" then long = longitudexx end --                if image == nil or image == "" then image = imagexx end    --               end -- end if wikidata              if image ~= nil and image ~= "" then                image = "[[File:" .. image .. "|260px]] "                description = image .. description               end 	 --            records[counter] = {}             records[counter]['name'] = name or ""      -- assume there             records[counter]['wikidata'] = wikidata or ""          -- may or may not be there             records[counter]['lat'] = lat         -- may or may not be there             records[counter]['long'] = long      -- may or may not be there             records[counter]['image'] = image     -- may or ay not be there             records[counter]['description'] = description  -- may or may not be there             counter = counter + 1  if records[2]['description'] ~= nil and records[2]['description'] ~= "" then  	return records[2]['description'] end   -- if line ~= nil then return line end -- if counter == 2 then return line end            end     end -- checkpoint if counter >= 1 then return counter end     beginit = "<maplink class=\"no-icon\" text=\"\" zoom=\"11\" group=\"seeSwansea\">{\""     beginit = beginit .. "\"type\": \"FeatureCollection\", \"features\":  ["        endit = "] }</maplink> \n\n"  -- testcheck - if beginit ~= nil then return beginit .. endit end      for i = 1,counter -1 ,1 do      output = output .. '\<maplink class=\"icon\" text=\"\" zoom=\"11\" group=\"' .. group .. '\"\>\n'      output = output .. '{\"type\": \"Feature\",\"geometry\": { \"type\":\"Point\", \"coordinates\":\n'      output = output ..  '[' ..  records[i]['long'] .. "," .. records[i]['lat'] .. ']},\n'      output = output .. '\"properties\":{\n'      output = output ..  '\"title\": \"' .. records[i]['name'] .. '\",\n'      if records[i]['description'] ~= nil and records[i]['description'] ~= "" then          output = output .. '\"description\": \"' .. records[i]['description'] .. '\",\n'          end      output = output .. '\"marker-symbol\": \"' .. symbol .. '",\n'      output = output .. '\"marker-color\": \"' .. color .. '\"\n}},' -- testcheck2 - if output ~= nil then return output end         end       if output ~= nil and output ~= "" then      	output = string.gsub(output,"%,$",'') -- get rid of ending comma         output = beginit .. output .. endit         else         	output = ""         end      return output end  function p.linkref(frame) 	    local name = frame.args['name'] or "" 	    local output = ""         local maplink = frame.args['maplink'] or "0"         local id = frame.args['id'] or ""         local lat = frame.args['lat'] or ""         local latitude = ""         local longitude = ""         local long = frame.args['long'] or ""         local zoom = frame.args['zoom'] or "11"         local entity = ""         local claims = ""    if lat == nil or lat == '' and long == nil or long == '' then         if id ~= nil and id ~= '' then            entity = mw.wikibase.getEntityObject(id)            claims = entity.claims            if pcall(function () t =claims.P625 end ) then  	          if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.latitude end ) then		 		        latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude 		         else latitude = "" end  		     if pcall(function () t =entity.claims.P625[1].mainsnak.datavalue.value.longitude end ) then		 		        longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude 	     	    else longitude = "" end            end        end     end     if lat ~= nil and lat ~= "" then latitude = lat end     if long ~= nil and long ~= "" then longitude = long end     latitude = string.format("%.4f",latitude)     longitude = string.format("%.4f",longitude)         output = "[[{{FULLPAGENAME}}#map/" .. maplink .. "/" .. zoom .. "/" .. latitude .. '/' .. longitude .. "|" .. name .. "]]" return output end  function p.newcenter(frame)         local x = string.format("%.6f",frame.args['lat'])         local y = string.format("%.6f",frame.args['long'])         local radius = frame.args['radius']         local angle = 0 		local ptx = 0 		local pty = 0 		local type = frame.args['type'] or "c" 		local direction = frame.args['direction'] or "e" 		     if direction ~= "e" and direction ~= "w" and direction ~= "n" and direction ~= "s" then 		     	direction = "e" 		     	end 		radius = tonumber(radius)         if radius > 10 then error("10 for radius is MAX") end   -- my default         if radius <= 0 then error("radius has to be greater than 0") end         if type == "c" then         	    radius = radius * 2         	else         		radius = radius * 1.5         	end         if direction == "e" then            angle = 90 * math.pi / 180            ptx = x + radius * math.cos( angle )            pty = y + radius * math.sin( angle )          end         if direction == "w" then            angle = 270 * math.pi / 180            ptx = x + radius * math.cos( angle )            pty = y + radius * math.sin( angle )          end          if direction == "n" then            angle = 360 * math.pi / 180            ptx = x + radius * math.cos( angle )            pty = y + radius * math.sin( angle )          end                    if direction == "s" then            angle = 180 * math.pi / 180            ptx = x + radius * math.cos( angle )            pty = y + radius * math.sin( angle )          end          if tonumber(x) >= 10.5 then          ptx = newlat(ptx) -- makes correction to make circle show up on map         end         if tonumber(x) <= -10.5 then           ptx = newlat(ptx) -- makes correction to make circle show up on map         end          ptx = string.format("%.4f",ptx)         pty = string.format("%.4f",pty)          return "latitude: " .. ptx .. " - longitude: " .. pty end             function p.connect(frame) local id=frame.args['id'] local count = 0 local latlong = {} local latitude = "" local longitude = "" local cumlat = 0 local cumlong = 0 local line = "" local output="" local entity = mw.wikibase.getEntityObject(id)	 	if entity == nil then return "No lat long" end    		 	local claims = entity.claims 	if claims == nil then 		return "No lat long" 	end	 	if claims.P625 ~= nil then   for _ in pairs(entity.claims.P625) do count = count + 1  longitude = entity.claims.P625[count].mainsnak.datavalue.value.longitude   latitude = entity.claims.P625[count].mainsnak.datavalue.value.latitude  latlong[count] = longitude .. "," .. latitude  cumlong = cumlong + longitude  cumlat = cumlat + latitude  	end 	end     for i=1, count do     	line = line .. "[" .. latlong[i] .. "]" .. ","     end line = string.gsub(line,"%,$","") output = output .. '\n<mapframe text="Test Map" frame="yes" zoom="6" latitude="' .. cumlat/count .. '" longitude="' .. cumlong/count .. '" width="600" height="400" frame="yes">' output = output .. '\n{"type": "FeatureCollection", "features":  ['	    	     for i=1, count do  output = output .. '\n\n{' .. '"type": "Feature",' .. '"properties": {' .. '"marker-color": "#bbccff",'  output = output .. ' "marker-symbol": "-number",' .. '},' .. '\n\n"geometry": {' .. ' "type": "Point",'  	     output = output .. ' "coordinates": [' .. latlong[i] .. "]}},"    	end    	output = output .. '\n\n{"type":"Feature", "properties": { "stroke":"#D3D3D3", "stroke-opacity":0.7, "stroke-width":50,},'    	output = output .. '\n\n"geometry": {"type":"LineString", "coordinates": [' .. line .. ']}},'    	output = output .. ']}<br></mapframe>\n'  end   return p