<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://wiki.2006scape.org/index.php?action=history&amp;feed=atom&amp;title=Module%3AMap</id>
	<title>Module:Map - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.2006scape.org/index.php?action=history&amp;feed=atom&amp;title=Module%3AMap"/>
	<link rel="alternate" type="text/html" href="https://wiki.2006scape.org/index.php?title=Module:Map&amp;action=history"/>
	<updated>2026-04-22T13:32:46Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>https://wiki.2006scape.org/index.php?title=Module:Map&amp;diff=983&amp;oldid=prev</id>
		<title>Dark98: Created page with &quot;-- &lt;nowiki&gt; local hc = require(&#039;Module:Paramtest&#039;).has_content  local p = {}  local zoomSizes = { 	{ 3, 8 }, 	{ 2, 4 }, 	{ 1, 2 }, 	{ 0, 1 }, 	{ -1, 1/2 }, 	{ -2, 1/4 }, 	{ -3, 1/8 } } -- Default size of maps (to calc zoom) local default_size = 800 -- 800px for full screen -- Map feature (overlay) types local featureMap = { 	none = {}, 	square = { square=true }, 	rectangle = { square=true }, 	polygon = { polygon=true }, 	line = { line=true }, 	lines = { line=true }, 	cir...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.2006scape.org/index.php?title=Module:Map&amp;diff=983&amp;oldid=prev"/>
		<updated>2023-02-10T00:57:25Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;-- &amp;lt;nowiki&amp;gt; local hc = require(&amp;#039;Module:Paramtest&amp;#039;).has_content  local p = {}  local zoomSizes = { 	{ 3, 8 }, 	{ 2, 4 }, 	{ 1, 2 }, 	{ 0, 1 }, 	{ -1, 1/2 }, 	{ -2, 1/4 }, 	{ -3, 1/8 } } -- Default size of maps (to calc zoom) local default_size = 800 -- 800px for full screen -- Map feature (overlay) types local featureMap = { 	none = {}, 	square = { square=true }, 	rectangle = { square=true }, 	polygon = { polygon=true }, 	line = { line=true }, 	lines = { line=true }, 	cir...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- &amp;lt;nowiki&amp;gt;&lt;br /&gt;
local hc = require(&amp;#039;Module:Paramtest&amp;#039;).has_content&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local zoomSizes = {&lt;br /&gt;
	{ 3, 8 },&lt;br /&gt;
	{ 2, 4 },&lt;br /&gt;
	{ 1, 2 },&lt;br /&gt;
	{ 0, 1 },&lt;br /&gt;
	{ -1, 1/2 },&lt;br /&gt;
	{ -2, 1/4 },&lt;br /&gt;
	{ -3, 1/8 }&lt;br /&gt;
}&lt;br /&gt;
-- Default size of maps (to calc zoom)&lt;br /&gt;
local default_size = 800 -- 800px for full screen&lt;br /&gt;
-- Map feature (overlay) types&lt;br /&gt;
local featureMap = {&lt;br /&gt;
	none = {},&lt;br /&gt;
	square = { square=true },&lt;br /&gt;
	rectangle = { square=true },&lt;br /&gt;
	polygon = { polygon=true },&lt;br /&gt;
	line = { line=true },&lt;br /&gt;
	lines = { line=true },&lt;br /&gt;
	circle = { circle=true },&lt;br /&gt;
	pin = { pins=true },&lt;br /&gt;
	pins = { pins=true },&lt;br /&gt;
	[&amp;#039;pin-polygon&amp;#039;] = { polygon=true, pins=true },&lt;br /&gt;
	[&amp;#039;pins-polygon&amp;#039;] = { polygon=true, pins=true },&lt;br /&gt;
	[&amp;#039;pin-line&amp;#039;] = { line=true, pins=true },&lt;br /&gt;
	[&amp;#039;pins-line&amp;#039;] = { line=true, pins=true },&lt;br /&gt;
	[&amp;#039;pin-circle&amp;#039;] = { circle=true, pins=true },&lt;br /&gt;
	[&amp;#039;pins-circle&amp;#039;] = { circle=true, pins=true }&lt;br /&gt;
}&lt;br /&gt;
-- Possible properties&lt;br /&gt;
local simplestyle = {&amp;#039;title&amp;#039;, &amp;#039;description&amp;#039;, &amp;#039;marker-size&amp;#039;, &amp;#039;marker-symbol&amp;#039;, &amp;#039;marker-color&amp;#039;,&lt;br /&gt;
	&amp;#039;stroke&amp;#039;, &amp;#039;stroke-opacity&amp;#039;, &amp;#039;stroke-width&amp;#039;, &amp;#039;fill&amp;#039;, &amp;#039;fill-opacity&amp;#039;}&lt;br /&gt;
local properties = {&lt;br /&gt;
	polygon = { title=true, description=true, stroke=true, [&amp;#039;stroke-opacity&amp;#039;]=true, [&amp;#039;stroke-width&amp;#039;]=true, fill=true, [&amp;#039;fill-opacity&amp;#039;]=true },&lt;br /&gt;
	line = { title=true, description=true, stroke=true, [&amp;#039;stroke-opacity&amp;#039;]=true, [&amp;#039;stroke-width&amp;#039;]=true },&lt;br /&gt;
	circle = { title=true, description=true, stroke=true, [&amp;#039;stroke-opacity&amp;#039;]=true, [&amp;#039;stroke-width&amp;#039;]=true, fill=true, [&amp;#039;fill-opacity&amp;#039;]=true },&lt;br /&gt;
	pin = { title=true, description=true, icon=true, iconWikiLink=true, iconSize=true, iconAnchor=true, popupAnchor=true}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Create JSON&lt;br /&gt;
function toJSON(j)&lt;br /&gt;
	local json_good, json = pcall(mw.text.jsonEncode, j)--, mw.text.JSON_PRETTY)&lt;br /&gt;
	if json_good then&lt;br /&gt;
		return json&lt;br /&gt;
	end&lt;br /&gt;
	return error(&amp;#039;Error converting to JSON&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
-- Create SMW string&lt;br /&gt;
function setSMW(obj, prop)&lt;br /&gt;
	mw.smw.set({[prop] = toJSON(obj)})&lt;br /&gt;
end&lt;br /&gt;
-- Create map html element&lt;br /&gt;
function createMapElement(elem, args, json)&lt;br /&gt;
	local mapelem = mw.html.create(elem)&lt;br /&gt;
	mapelem:attr(args):newline():wikitext(toJSON(json)):newline()&lt;br /&gt;
	return mapelem&lt;br /&gt;
end&lt;br /&gt;
-- Create pin description&lt;br /&gt;
function parseDesc(args, pin, pgname, ptype)&lt;br /&gt;
	local desc = {}&lt;br /&gt;
	if ptype == &amp;#039;item&amp;#039; then&lt;br /&gt;
		desc = {&lt;br /&gt;
			&amp;quot;&amp;#039;&amp;#039;&amp;#039;Item&amp;#039;&amp;#039;&amp;#039;: &amp;quot;.. (args.name or pgname),&lt;br /&gt;
			&amp;quot;&amp;#039;&amp;#039;&amp;#039;Quantity&amp;#039;&amp;#039;&amp;#039;: &amp;quot;.. (pin.qty or 1)&lt;br /&gt;
		}&lt;br /&gt;
		if pin.respawn then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Respawn time&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.respawn)&lt;br /&gt;
		elseif args.respawn then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Respawn time&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.respawn)&lt;br /&gt;
		end&lt;br /&gt;
		if pin.notes then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Notes&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.notes)&lt;br /&gt;
		elseif args.notes then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Notes&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.notes)&lt;br /&gt;
		end&lt;br /&gt;
	elseif ptype == &amp;#039;monster&amp;#039; then&lt;br /&gt;
		table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Monster&amp;#039;&amp;#039;&amp;#039;: &amp;quot; .. (args.name or pgname))&lt;br /&gt;
		if pin.levels then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Level(s)&amp;#039;&amp;#039;&amp;#039;: &amp;quot; .. pin.levels)&lt;br /&gt;
		elseif args.levels then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Level(s)&amp;#039;&amp;#039;&amp;#039;: &amp;quot; .. args.levels)&lt;br /&gt;
		end&lt;br /&gt;
	elseif ptype == &amp;#039;npc&amp;#039; then&lt;br /&gt;
		table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;NPC&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..(args.name or pgname))&lt;br /&gt;
		if pin.version then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Version&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.version)&lt;br /&gt;
		elseif args.version then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Version&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.version)&lt;br /&gt;
		end&lt;br /&gt;
		if pin.npcid then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;NPC ID&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.npcid)&lt;br /&gt;
		elseif args.npcid then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;NPC ID&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.npcid)&lt;br /&gt;
		end&lt;br /&gt;
		if pin.objectid then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Object ID&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.objectid)&lt;br /&gt;
		elseif args.objectid then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Object ID&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.objectid)&lt;br /&gt;
		end&lt;br /&gt;
		if pin.respawn then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Respawn time&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.respawn)&lt;br /&gt;
		elseif args.respawn then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Respawn time&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.respawn)&lt;br /&gt;
		end&lt;br /&gt;
		if pin.notes then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Notes&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.notes)&lt;br /&gt;
		elseif args.notes then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Notes&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.notes)&lt;br /&gt;
		end&lt;br /&gt;
	elseif ptype == &amp;#039;object&amp;#039; then&lt;br /&gt;
		table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Object&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..(args.name or pgname))&lt;br /&gt;
		if pin.version then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Version&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.version)&lt;br /&gt;
		elseif args.version then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Version&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.version)&lt;br /&gt;
		end&lt;br /&gt;
		if pin.objectid then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Object ID&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.objectid)&lt;br /&gt;
		elseif args.objectid then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Object ID&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.objectid)&lt;br /&gt;
		end&lt;br /&gt;
		if pin.npcid then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;NPC ID&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.npcid)&lt;br /&gt;
		elseif args.npcid then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;NPC ID&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.npcid)&lt;br /&gt;
		end&lt;br /&gt;
		if pin.respawn then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Respawn time&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.respawn)&lt;br /&gt;
		elseif args.respawn then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Respawn time&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.respawn)&lt;br /&gt;
		end&lt;br /&gt;
		if pin.notes then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Notes&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..pin.notes)&lt;br /&gt;
		elseif args.notes then&lt;br /&gt;
			table.insert(desc, &amp;quot;&amp;#039;&amp;#039;&amp;#039;Notes&amp;#039;&amp;#039;&amp;#039;: &amp;quot;..args.notes)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		if args.desc then&lt;br /&gt;
			table.insert(desc, args.desc)&lt;br /&gt;
		end&lt;br /&gt;
		if pin.desc then&lt;br /&gt;
			table.insert(desc, pin.desc)&lt;br /&gt;
		elseif pin.x and pin.y then&lt;br /&gt;
			table.insert(desc, &amp;#039;X,Y: &amp;#039;..pin.x..&amp;#039;,&amp;#039;..pin.y)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat(desc, &amp;#039;&amp;lt;br&amp;gt;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
-- Parse unnamed arguments (arg = pin)&lt;br /&gt;
function p.parseArgs(args, ptype)&lt;br /&gt;
	args.pins = {}&lt;br /&gt;
	local sep = args.sep or &amp;#039;%s*,%s*&amp;#039;&lt;br /&gt;
	local pgname = mw.title.getCurrentTitle().text&lt;br /&gt;
	local rng = {&lt;br /&gt;
		xmin = 10000000,&lt;br /&gt;
		xmax = -10000000,&lt;br /&gt;
		ymin = 10000000,&lt;br /&gt;
		ymax = -10000000&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local i,cnt = 1,0&lt;br /&gt;
	while (args[i]) do&lt;br /&gt;
		local v = mw.text.trim(args[i])&lt;br /&gt;
		if hc(v) then&lt;br /&gt;
			local pin = {}&lt;br /&gt;
			for u in mw.text.gsplit(v, sep) do&lt;br /&gt;
				local _u = mw.text.split(u, &amp;#039;%s*:%s*&amp;#039;)&lt;br /&gt;
				if _u[2] then&lt;br /&gt;
					local k = mw.text.trim(_u[1])&lt;br /&gt;
					if k == &amp;#039;x&amp;#039; or k == &amp;#039;y&amp;#039; then&lt;br /&gt;
						pin[k] = tonumber(mw.text.trim(_u[2]))&lt;br /&gt;
					else&lt;br /&gt;
						pin[k] = mw.text.trim(_u[2])&lt;br /&gt;
					end&lt;br /&gt;
				else&lt;br /&gt;
					if pin.x then&lt;br /&gt;
						pin.y = tonumber(_u[1])&lt;br /&gt;
					else&lt;br /&gt;
						pin.x = tonumber(_u[1])&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if pin.x &amp;gt; rng.xmax then&lt;br /&gt;
				rng.xmax = pin.x&lt;br /&gt;
			end&lt;br /&gt;
			if pin.x &amp;lt; rng.xmin then&lt;br /&gt;
				rng.xmin = pin.x&lt;br /&gt;
			end&lt;br /&gt;
			if pin.y &amp;gt; rng.ymax then&lt;br /&gt;
				rng.ymax = pin.y&lt;br /&gt;
			end&lt;br /&gt;
			if pin.y &amp;lt;  rng.ymin then&lt;br /&gt;
				rng.ymin = pin.y&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- Pin size/location args&lt;br /&gt;
			if pin.iconSizeX and pin.iconSizeY then&lt;br /&gt;
				pin.iconSize = {tonumber(pin.iconSizeX), tonumber(pin.iconSizeY) }&lt;br /&gt;
			elseif pin.iconSize then&lt;br /&gt;
				pin.iconSize = { tonumber(pin.iconSize), tonumber(pin.iconSize)}&lt;br /&gt;
			end&lt;br /&gt;
			if pin.iconAnchorX and pin.iconAnchorY then&lt;br /&gt;
				pin.iconAnchor = {tonumber(pin.iconAnchorX), tonumber(pin.iconAnchorY) }&lt;br /&gt;
			elseif pin.iconAnchor then&lt;br /&gt;
				pin.iconAnchor = {tonumber(pin.iconAnchor), tonumber(pin.iconAnchor)}&lt;br /&gt;
			end&lt;br /&gt;
			if pin.popupAnchorX and pin.popupAnchorY then&lt;br /&gt;
				pin.popupAnchor = {tonumber(pin.popupAnchorX), tonumber(pin.popupAnchorY) }&lt;br /&gt;
			elseif pin.popupAnchor then&lt;br /&gt;
				pin.popupAnchor = {tonumber(pin.popupAnchor), tonumber(pin.popupAnchor)}&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			pin.desc = parseDesc(args, pin, pgname, ptype)&lt;br /&gt;
			&lt;br /&gt;
			table.insert( args.pins, pin)&lt;br /&gt;
			cnt =  cnt + 1&lt;br /&gt;
		end&lt;br /&gt;
		i =  i + 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- In no anonymous args then x,y are pin&lt;br /&gt;
	if cnt == 0 then&lt;br /&gt;
		local x = tonumber(args.x) or 3233 -- Default is Lumbridge loadstone&lt;br /&gt;
		local y = tonumber(args.y) or 3222&lt;br /&gt;
		rng.xmax = x&lt;br /&gt;
		rng.xmin = x&lt;br /&gt;
		rng.ymax = y&lt;br /&gt;
		rng.ymin = y&lt;br /&gt;
		local desc = parseDesc(args, {}, pgname, ptype)&lt;br /&gt;
		table.insert( args.pins, {x = x, y = y, desc = desc} )&lt;br /&gt;
		cnt = cnt + 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local xrange = rng.xmax - rng.xmin&lt;br /&gt;
	local yrange = rng.ymax - rng.ymin&lt;br /&gt;
&lt;br /&gt;
	if not tonumber(args.x) then&lt;br /&gt;
		args.x = math.floor(rng.xmin + xrange/2)&lt;br /&gt;
	end&lt;br /&gt;
	if not tonumber(args.y) then&lt;br /&gt;
		args.y = math.floor(rng.ymin + yrange/2)&lt;br /&gt;
	end&lt;br /&gt;
	-- Default range (1 pin) is 40&lt;br /&gt;
	if not tonumber(args.x_range) then&lt;br /&gt;
		if xrange &amp;gt; 0 then&lt;br /&gt;
			args.x_range = xrange&lt;br /&gt;
		else&lt;br /&gt;
			args.x_range = 40&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if not tonumber(args.y_range) then&lt;br /&gt;
		if yrange &amp;gt; 0 then&lt;br /&gt;
			args.y_range = yrange&lt;br /&gt;
		else&lt;br /&gt;
			args.y_range = 40&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- Default square (1 pin) is 20&lt;br /&gt;
	if not tonumber(args.squareX) then&lt;br /&gt;
		if xrange &amp;gt; 0 then&lt;br /&gt;
			args.squareX = xrange&lt;br /&gt;
		else&lt;br /&gt;
			args.squareX = 20&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if not tonumber(args.squareY) then&lt;br /&gt;
		if yrange &amp;gt; 0 then&lt;br /&gt;
			args.squareY = yrange&lt;br /&gt;
		else&lt;br /&gt;
			args.squareY = 20&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	args.pin_count = cnt&lt;br /&gt;
	&lt;br /&gt;
	if args.smw == &amp;#039;yes&amp;#039; or args.smw == &amp;#039;y&amp;#039; or tonumber(args.smw) == 1 then&lt;br /&gt;
		args.smw = &amp;quot;Location JSON&amp;quot;&lt;br /&gt;
	elseif args.smw == &amp;#039;hist&amp;#039; then&lt;br /&gt;
		args.smw = &amp;quot;Historic Location JSON&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		args.smw = nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return args&lt;br /&gt;
end&lt;br /&gt;
-- Add styles&lt;br /&gt;
function styles(ftjson, args, this, ptype)&lt;br /&gt;
	local props = properties[ptype]&lt;br /&gt;
	for i,v in pairs(args) do&lt;br /&gt;
		if props[i] then&lt;br /&gt;
			ftjson.properties[i] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for i,v in pairs(this) do&lt;br /&gt;
		if props[i] then&lt;br /&gt;
			ftjson.properties[i] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return ftjson&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.map(frame)&lt;br /&gt;
	return p.buildMap(frame:getParent().args)	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Functions for templates --&lt;br /&gt;
function p.buildMap(arguments)&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for i,v in pairs(arguments) do&lt;br /&gt;
		args[i] = v&lt;br /&gt;
	end&lt;br /&gt;
	-- Allow map/element type per template easily&lt;br /&gt;
	local inv_args = {}&lt;br /&gt;
	for i,v in pairs(arguments) do&lt;br /&gt;
		inv_args[i] = v&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--[[ Each unnamed arg is 1 pin in format:&lt;br /&gt;
		x,y&lt;br /&gt;
		or&lt;br /&gt;
		x:#,y:#,desc:#&lt;br /&gt;
	]]&lt;br /&gt;
	args = p.parseArgs(args, args.ptype)&lt;br /&gt;
&lt;br /&gt;
	if hc(args.iconSize) then&lt;br /&gt;
		if string.find(args.iconSize, &amp;#039;,&amp;#039;) then&lt;br /&gt;
			local isize = mw.text.split(args.iconSize, &amp;#039;%s*,%s*&amp;#039;)&lt;br /&gt;
			args.iconSize = { tonumber(isize[1]) or 25, tonumber(isize[2]) or 25}&lt;br /&gt;
		else&lt;br /&gt;
			args.iconSize = { tonumber(args.iconSize) or 25, tonumber(args.iconSize) or 25}&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if hc(args.iconAnchor) then&lt;br /&gt;
		if string.find(args.iconAnchor, &amp;#039;,&amp;#039;) then&lt;br /&gt;
			local ianch = mw.text.split(args.iconAnchor, &amp;#039;%s*,%s*&amp;#039;)&lt;br /&gt;
			args.iconAnchor = { tonumber(ianch[1]) or 0, tonumber(ianch[2]) or 0}&lt;br /&gt;
		else&lt;br /&gt;
			args.iconAnchor = { tonumber(args.iconAnchor) or 0, tonumber(args.iconAnchor) or 0}&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if hc(args.popupAnchor) then&lt;br /&gt;
		if string.find(args.popupAnchor, &amp;#039;,&amp;#039;) then&lt;br /&gt;
			local panch = mw.text.split(args.popupAnchor, &amp;#039;%s*,%s*&amp;#039;)&lt;br /&gt;
			args.popupAnchor = { tonumber(panch[1]) or 0, tonumber(panch[2]) or 0}&lt;br /&gt;
		else&lt;br /&gt;
			args.popupAnchor = { tonumber(args.popupAnchor) or 0, tonumber(args.popupAnchor) or 0}&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if args.showPins then&lt;br /&gt;
		if args.pin_count &amp;gt; 1 then&lt;br /&gt;
			if not hc(args.text) then&lt;br /&gt;
				args.text = &amp;#039;Show exact locations&amp;#039;&lt;br /&gt;
			end&lt;br /&gt;
			local capt = string.format(&amp;#039;%s locations&amp;#039;, args.pin_count)&lt;br /&gt;
			if hc(args.caption) then&lt;br /&gt;
				capt = args.caption&lt;br /&gt;
			end&lt;br /&gt;
	&lt;br /&gt;
			args.etype = &amp;#039;maplink&amp;#039;&lt;br /&gt;
			args.features = &amp;#039;pins&amp;#039;&lt;br /&gt;
			local link = tostring(p.createMap(args))&lt;br /&gt;
			capt = capt .. link&lt;br /&gt;
	&lt;br /&gt;
			args.etype = &amp;#039;mapframe&amp;#039;&lt;br /&gt;
			args.caption = &amp;#039;&amp;#039;&lt;br /&gt;
			args.features = &amp;#039;square&amp;#039;&lt;br /&gt;
			local map = tostring(p.createMap(args))&lt;br /&gt;
	&lt;br /&gt;
			local classes = &amp;#039;mw-kartographer-container thumb&amp;#039;&lt;br /&gt;
			if hc(args.align) then&lt;br /&gt;
				local align = string.lower(args.align)&lt;br /&gt;
				if align == &amp;#039;left&amp;#039; then&lt;br /&gt;
					classes = classes..&amp;#039; tleft&amp;#039;&lt;br /&gt;
				elseif align == &amp;#039;right&amp;#039; then&lt;br /&gt;
					classes = classes..&amp;#039; tright&amp;#039;&lt;br /&gt;
				else&lt;br /&gt;
					classes = classes..&amp;#039; center&amp;#039;&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				classes = classes..&amp;#039; center&amp;#039;&lt;br /&gt;
			end&lt;br /&gt;
	&lt;br /&gt;
			local width = args.width or 300&lt;br /&gt;
			local ret = mw.html.create(&amp;#039;div&amp;#039;)&lt;br /&gt;
			ret:addClass(classes)&lt;br /&gt;
				:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
					:addClass(&amp;#039;thumbinner&amp;#039;)&lt;br /&gt;
					:css(&amp;#039;width&amp;#039;, width .. &amp;#039;px&amp;#039;)&lt;br /&gt;
					:node(map)&lt;br /&gt;
					:tag(&amp;#039;div&amp;#039;)&lt;br /&gt;
						:addClass(&amp;#039;thumbcaption&amp;#039;)&lt;br /&gt;
						:css(&amp;#039;text-align&amp;#039;, &amp;#039;center&amp;#039;)&lt;br /&gt;
						:node(capt)&lt;br /&gt;
	&lt;br /&gt;
			return ret&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if hc(inv_args.mtype) then&lt;br /&gt;
		args.features = string.lower(inv_args.mtype)&lt;br /&gt;
	end&lt;br /&gt;
	if hc(args.mtype) then&lt;br /&gt;
		args.features = string.lower(args.mtype)&lt;br /&gt;
	end&lt;br /&gt;
	if not args.features then&lt;br /&gt;
		args.features = &amp;#039;none&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	args.etype = &amp;#039;mapframe&amp;#039;&lt;br /&gt;
	&lt;br /&gt;
	if hc(inv_args.type) then&lt;br /&gt;
		args.etype = string.lower(inv_args.type)&lt;br /&gt;
	end&lt;br /&gt;
	if hc(args.type) then&lt;br /&gt;
		args.etype = string.lower(args.type)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return p.createMap(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Function for creating map or link&lt;br /&gt;
function p.createMap(args)&lt;br /&gt;
	local x, y = args.x, args.y&lt;br /&gt;
	local opts = {&lt;br /&gt;
		x = x,&lt;br /&gt;
		y = y,&lt;br /&gt;
		width = args.width or 300,&lt;br /&gt;
		height = args.height or 300,&lt;br /&gt;
		mapID = args.mapID or 0, -- RuneScape Surface&lt;br /&gt;
		plane = tonumber(args.plane) or 0,&lt;br /&gt;
		zoom = args.zoom or 2,&lt;br /&gt;
		align = args.align or &amp;#039;center&amp;#039;,&lt;br /&gt;
		icon = args.icon or &amp;#039;greenPin&amp;#039;&lt;br /&gt;
	}&lt;br /&gt;
	if hc(args.group) then&lt;br /&gt;
		opts.group = args.group&lt;br /&gt;
	end&lt;br /&gt;
	if hc(args.show) then&lt;br /&gt;
		opts.show = args.show&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- plain map tiles&lt;br /&gt;
	if hc(args.plaintiles) then&lt;br /&gt;
		opts.plainTiles = &amp;#039;true&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	if hc(args.plainTiles) then&lt;br /&gt;
		opts.plainTiles = &amp;#039;true&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- other map tile version&lt;br /&gt;
	if hc(args.mapversion) then&lt;br /&gt;
		opts.mapVersion = args.mapversion&lt;br /&gt;
	end&lt;br /&gt;
	if hc(args.mapVersion) then&lt;br /&gt;
		opts.mapVersion = args.mapVersion&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- mapframe, maplink&lt;br /&gt;
	local etype = &amp;#039;mapframe&amp;#039;&lt;br /&gt;
	if hc(args.etype) then&lt;br /&gt;
		etype = args.etype&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- translate &amp;quot;centre&amp;quot; spelling for align&lt;br /&gt;
	if opts.align == &amp;#039;centre&amp;#039; then&lt;br /&gt;
		opts.align = &amp;#039;center&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Caption or link text&lt;br /&gt;
	if etype == &amp;#039;maplink&amp;#039; then&lt;br /&gt;
		opts.text = args.text or &amp;#039;Maplink&amp;#039;&lt;br /&gt;
		if string.find(opts.text,&amp;#039;[%[%]]&amp;#039;) then &lt;br /&gt;
			return error(&amp;#039;Text cannot contain links&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	elseif hc(args.caption) then&lt;br /&gt;
		opts.text = args.caption&lt;br /&gt;
	else&lt;br /&gt;
		opts.frameless = &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local featColl, features = {}, {}&lt;br /&gt;
	local smwstr = &amp;quot;&amp;quot;&lt;br /&gt;
	if hc(args.features) then&lt;br /&gt;
		local _features = string.lower(args.features)&lt;br /&gt;
		features = featureMap[_features] or {}&lt;br /&gt;
	end&lt;br /&gt;
	if features.square then&lt;br /&gt;
		local feat = p.featSquare(args, opts)&lt;br /&gt;
		table.insert(featColl, feat)&lt;br /&gt;
		if args.smw then&lt;br /&gt;
			setSMW(feat, args.smw)&lt;br /&gt;
		end&lt;br /&gt;
	elseif features.circle then&lt;br /&gt;
		local feat = p.featCircle(args, opts)&lt;br /&gt;
		table.insert(featColl, feat)&lt;br /&gt;
		if args.smw then&lt;br /&gt;
			setSMW(feat, args.smw)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if features.polygon then&lt;br /&gt;
		local feat = p.featPolygon(args, opts)&lt;br /&gt;
		table.insert(featColl, feat)&lt;br /&gt;
		if args.smw then&lt;br /&gt;
			setSMW(feat, args.smw)&lt;br /&gt;
		end&lt;br /&gt;
	elseif features.line then&lt;br /&gt;
		local feat = p.featLine(args, opts)&lt;br /&gt;
		table.insert(featColl, feat)&lt;br /&gt;
		if args.smw then&lt;br /&gt;
			setSMW(feat, args.smw)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if features.pins then&lt;br /&gt;
		if not opts.group then&lt;br /&gt;
			opts.group = &amp;#039;pins&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		-- opts.icon = args.icon or &amp;#039;greenPin&amp;#039;&lt;br /&gt;
		for _,pin in ipairs(args.pins) do&lt;br /&gt;
			local feat = p.featPin(args, opts, pin)&lt;br /&gt;
			table.insert(featColl, feat)&lt;br /&gt;
			if args.smw then&lt;br /&gt;
				setSMW(feat, args.smw)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local json = {}&lt;br /&gt;
	if #featColl &amp;gt; 0 then&lt;br /&gt;
		json = {&lt;br /&gt;
			type = &amp;#039;FeatureCollection&amp;#039;,&lt;br /&gt;
			features = featColl&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		-- Zoom&lt;br /&gt;
		local width,height = opts.width, opts.height&lt;br /&gt;
		if etype == &amp;#039;maplink&amp;#039; then&lt;br /&gt;
			width,height = default_size, default_size&lt;br /&gt;
		end&lt;br /&gt;
		local x_range = tonumber(args.squareX) or 40&lt;br /&gt;
		local y_range = tonumber(args.squareY) or 40&lt;br /&gt;
		if tonumber(args.r) then&lt;br /&gt;
			x_range = tonumber(args.r)&lt;br /&gt;
			y_range = tonumber(args.r)&lt;br /&gt;
		end&lt;br /&gt;
		if tonumber(args.x_range) then&lt;br /&gt;
			x_range = tonumber(args.x_range)&lt;br /&gt;
		end&lt;br /&gt;
		if tonumber(args.y_range) then&lt;br /&gt;
			y_range = tonumber(args.y_range)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local zoom = -3&lt;br /&gt;
		for i,v in ipairs(zoomSizes) do&lt;br /&gt;
			local sqsx, sqsy = width/v[2], height/v[2]&lt;br /&gt;
			if sqsx &amp;gt; x_range and sqsy &amp;gt; y_range then&lt;br /&gt;
				zoom = v[1]&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if zoom &amp;gt; 2 then&lt;br /&gt;
			zoom = 2&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if tonumber(args.zoom) then&lt;br /&gt;
			opts.zoom = args.zoom&lt;br /&gt;
		else&lt;br /&gt;
			opts.zoom = zoom&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local map = createMapElement(etype, opts, json)&lt;br /&gt;
	if args.nopreprocess then&lt;br /&gt;
		return tostring(map) .. smwstr&lt;br /&gt;
	end&lt;br /&gt;
	return mw.getCurrentFrame():preprocess(tostring(map) .. smwstr)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Create a square feature&lt;br /&gt;
function p.featSquare(args, opts)&lt;br /&gt;
	local x, y = args.x, args.y&lt;br /&gt;
	local squareX = tonumber(args.squareX) or 20&lt;br /&gt;
	local squareY = tonumber(args.squareY) or 20&lt;br /&gt;
	squareX = math.max(1, args.r or math.floor(squareX / 2))&lt;br /&gt;
	squareY = math.max(1, args.r or math.floor(squareY / 2))&lt;br /&gt;
&lt;br /&gt;
	local ftjson = {&lt;br /&gt;
		type = &amp;#039;Feature&amp;#039;,&lt;br /&gt;
		properties = {[&amp;#039;_&amp;#039;]=&amp;#039;_&amp;#039;, mapID=opts.mapID, plane=opts.plane},&lt;br /&gt;
		geometry = {&lt;br /&gt;
			type = &amp;#039;Polygon&amp;#039;,&lt;br /&gt;
			coordinates = {&lt;br /&gt;
				{&lt;br /&gt;
					{ x-squareX, y-squareY },&lt;br /&gt;
					{ x-squareX, y+squareY },&lt;br /&gt;
					{ x+squareX, y+squareY },&lt;br /&gt;
					{ x+squareX, y-squareY }&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ftjson = styles(ftjson, args, {}, &amp;#039;polygon&amp;#039;)&lt;br /&gt;
	return ftjson&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Create a polygon feature&lt;br /&gt;
function p.featPolygon(args, opts)&lt;br /&gt;
	local points, lastpoint = {}, {}&lt;br /&gt;
	for _,v in ipairs(args.pins) do&lt;br /&gt;
		table.insert(points, {v.x, v.y,})&lt;br /&gt;
		lastpoint = {v.x, v.y,}&lt;br /&gt;
	end&lt;br /&gt;
	-- Close polygon&lt;br /&gt;
	if not (points[1][1] == lastpoint[1] and points[1][2] == lastpoint[2]) then&lt;br /&gt;
		table.insert(points, {points[1][1], points[1][2]})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ftjson = {&lt;br /&gt;
		type = &amp;#039;Feature&amp;#039;,&lt;br /&gt;
		properties = {[&amp;#039;_&amp;#039;]=&amp;#039;_&amp;#039;, mapID=opts.mapID, plane=opts.plane},&lt;br /&gt;
		geometry = {&lt;br /&gt;
			type = &amp;#039;Polygon&amp;#039;,&lt;br /&gt;
			coordinates = { points }&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ftjson = styles(ftjson, args, {}, &amp;#039;polygon&amp;#039;)&lt;br /&gt;
	return ftjson&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Create a line feature&lt;br /&gt;
function p.featLine(args, opts)&lt;br /&gt;
	local points, lastpoint = {}, {}&lt;br /&gt;
	for _,v in ipairs(args.pins) do&lt;br /&gt;
		table.insert(points, {v.x, v.y,})&lt;br /&gt;
		lastpoint = {v.x, v.y,}&lt;br /&gt;
	end&lt;br /&gt;
	if hc(args.close) then&lt;br /&gt;
		-- Close line&lt;br /&gt;
		if not (points[1][1] == lastpoint[1] and points[1][2] == lastpoint[2]) then&lt;br /&gt;
			table.insert(points, {points[1][1], points[1][2]})&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ftjson = {&lt;br /&gt;
		type = &amp;#039;Feature&amp;#039;,&lt;br /&gt;
		properties = {&lt;br /&gt;
			[&amp;#039;_&amp;#039;] = &amp;#039;_&amp;#039;,&lt;br /&gt;
			shape = &amp;#039;Line&amp;#039;,&lt;br /&gt;
			mapID = opts.mapID,&lt;br /&gt;
			plane = opts.plane&lt;br /&gt;
		},&lt;br /&gt;
		geometry = {&lt;br /&gt;
			type = &amp;#039;LineString&amp;#039;,&lt;br /&gt;
			coordinates = points&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ftjson = styles(ftjson, args, {}, &amp;#039;line&amp;#039;)&lt;br /&gt;
	return ftjson&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Create a circle feature&lt;br /&gt;
function p.featCircle(args, opts)&lt;br /&gt;
	local rad = tonumber(args.r) or 10&lt;br /&gt;
	local ftjson = {&lt;br /&gt;
		type = &amp;#039;Feature&amp;#039;,&lt;br /&gt;
		properties = {&lt;br /&gt;
			[&amp;#039;_&amp;#039;]=&amp;#039;_&amp;#039;,&lt;br /&gt;
			shape = &amp;#039;Circle&amp;#039;,&lt;br /&gt;
			radius = rad,&lt;br /&gt;
			mapID = opts.mapID,&lt;br /&gt;
			plane = opts.plane&lt;br /&gt;
		},&lt;br /&gt;
		geometry = {&lt;br /&gt;
			type = &amp;#039;Point&amp;#039;,&lt;br /&gt;
			coordinates = {&lt;br /&gt;
				args.x, args.y, opts.plane&lt;br /&gt;
			}	&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ftjson = styles(ftjson, args, {}, &amp;#039;circle&amp;#039;)&lt;br /&gt;
	return ftjson&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Create a pin feature&lt;br /&gt;
-- Pin types: greyPin, greenPin, redPin&lt;br /&gt;
function p.featPin(args, opts, pin)&lt;br /&gt;
	local desc = pin.desc or pin.x..&amp;#039;, &amp;#039;..pin.y&lt;br /&gt;
	local ftjson = {&lt;br /&gt;
		type = &amp;#039;Feature&amp;#039;,&lt;br /&gt;
		properties = {&lt;br /&gt;
			providerID = 0,&lt;br /&gt;
			description = desc,&lt;br /&gt;
			mapID = opts.mapID,&lt;br /&gt;
			plane = opts.plane&lt;br /&gt;
		},&lt;br /&gt;
		geometry = {&lt;br /&gt;
			type = &amp;#039;Point&amp;#039;,&lt;br /&gt;
			coordinates = {&lt;br /&gt;
				pin.x, pin.y, opts.plane&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	if pin.iconWikiLink then&lt;br /&gt;
		pin.iconWikiLink = mw.ext.GloopTweaks.filepath(pin.iconWikiLink)&lt;br /&gt;
	end&lt;br /&gt;
	ftjson = styles(ftjson, args, pin, &amp;#039;pin&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	if not (ftjson.properties.icon or ftjson.properties.iconWikiLink) then&lt;br /&gt;
		ftjson.properties.icon = &amp;#039;greenPin&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return ftjson&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;br /&gt;
-- &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dark98</name></author>
	</entry>
</feed>