יחידה:ארגז חול/ויקיג'אנקי

מתוך ויקיפדיה, האנציקלופדיה החופשית

ניתן ליצור תיעוד על היחידה הזאת בדף יחידה:ארגז חול/ויקיג'אנקי/תיעוד

-- 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 = {}

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


-- 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 = '[[קובץ:' .. image .. '|280px|link=]]'		
--		image = '"[[קובץ:' .. 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 = '[[קובץ:' .. image .. '|280px|link=]]'				
			end
		end
	end
	if image == "" then
		image = '[[קובץ:Wikivoyage-Logo-v3-small-en.png|Wikivoyage|80px|link=]]<br>' -- [[קובץ: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','png','PNG','svg','SVG','tif'}
		
		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', '[[קובץ:', 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*(.*)%}%}.*',"[[קובץ: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 [[קובץ: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 ^[[קובץ:.*%.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

-- 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 = '[[קובץ:' .. image .. '|280px|link=]]' -- should not be necessary
image = '[[קובץ:' .. 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 = "[[קובץ: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 data = frame.args[1]
	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 = '[[קובץ:' .. 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,'%[%[File.*$','')          -- some have an image in content which won't work
			content = string.gsub(content,'%"','\"')
--			if image == "" then 
--				image = "[[קובץ: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(arg1,"^[Qq]%d+$") ~= nil then				
					if latitude == "" then
						latitude = latitude(wikidata)
					end
					if longitude == "" then
						longitude  = longitude(wikidata)
					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="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>'
			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
		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
    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
	
return p