require('strict')
local delink=require('Module:Delink').delink
local getArgs = require('Module:Arguments').getArgs
local p = {}
local maplist={}
local sgNames={}
local highlightOption=false
local highlightNum
local visibleLinks  
-- This module creates framed maps of anywhere in the world, at the required scale, and enables annotations,
-- dots, shapes, lines and other ways to customise the area of the map being shown. It also provides a link
-- to an interactive fullscreen version, which has locator dots instead of annotations and shapes.  
-- This is the 2025 successor module to a wiki-markup template version of 2024, which itself was a successor
-- to the 'Graph'/VEGA driven template that was begun in 2016, until the Vega version was switched off in 2023.  
-- This module is called from template , which uses the same parameter formats as before.  
-- In addition it will be possible to use a more concise parameter format using the template
-- In general the css output from the two formats will be identical, but the the concise version will allow bits of
-- greater control over some of the settings.  
-- see the documentation on the two template pages for details of how to use the mapping features.  
-- If language customisation is needed, there are text items below that can be translated. Also see the color table
-- below with details of how to add additional color names to allow localised alternatives.
-- (Translating other language shape-types could be possible, but has not currently been contemplated.
-- Parameter name translation would be harder but likely to be possible, ideally still retaining compatibility
-- with template calls already written using English).  
local negativeAnswer={no=1,'0'-1,off=1}
local fullscreenlinktext='Click for interactive fullscreen map with links to nearby articles'
local toggletext='[Hide/show caption list]'
local termsOfUse='Maps: terms of use'
local aboutOSM='About OpenStreetMaps'  
local shapeList={} --This sets up the 'factoryDefault' shape group 0
shapeList["0"]={shapeType="0",
Name="initialSettings",
Parent="0",
--sga items for the shape
shape="circle",
shapeSize="",
shapeColor="blue",
shapeAngle="0deg",
--sgb items for of the shape
outline,
outlineColor="darkblue",
outline,
--sgc items text settings for labels
textSZ="",
textCL="darkgrey",
textNG="0deg",
--sgf further text settings
textSP="",
textLH="120%",
textOL="",
textBG="transparent",
--sgd items for dotTag text settings
tagSize="",
tagColor="white",
tagSpacer="",
tagAngle="0deg",
--sge items for extension line to connect label to dot
textEW="",
textEC="darkgrey",
textES="solid"
}  
local colorList={} -- used by colorLookup to catch unsupported colors (eg 'LimeGreen'), to convert to generic version
colorList['green']='hardgreen' -- it could also be added to to include alternative language equivelants, for a quick solution.
colorList['red']='hardred' -- colorList ['source'] = target
colorList['white']='white' -- converts any color that includes 'source' into its equivelent target
colorList['blue']='hardblue' -- note, for translation you can add to this list, rather than replace it,
colorList['brown']='brown' -- which would mean existing map definitions in english would also still work, alongside translated ones
colorList['grey']='hardgrey'
colorList['gray']='hardgrey'
colorList['purple']='hardpurple'
colorList['orange']='hardorange'
colorList['leaf']='hardleaf'  
--for a more thorough translation, you can add all the variants of the colors as further CTB elements and hex values or redirects
local CTB={} -- set up a table of color names (the CTB Color table index) and html hash colorhex values.
CTB["paleblue"],CTB["softblue"],CTB["hardblue"],CTB["darkblue"]="#D6E1EC","#77A1CB","#4B77D6","#1c559e"
CTB["palered"],CTB["softred"],CTB["hardred"],CTB["darkred"] = "#FCC6C0","#EC644B","#DB3123","#AA1205"
CTB["palegreen"],CTB["softgreen"],CTB["hardgreen"],CTB["darkgreen"]= "#D2F0E5","#81AF81","#269F46","#0b7527"
CTB["paleleaf"],CTB["softleaf"],CTB["hardleaf"],CTB["darkleaf"]= "#dff5c1","#b5e376","#8cc244","#679c21"
CTB["palegrey"],CTB["softgrey"],CTB["hardgrey"],CTB["darkgrey"]= "#E8E8D6","#AAAA88","#777755","#444433"
CTB["palegray"],CTB["softgray"],CTB["hardgray"],CTB["darkgray"]=CTB["palegrey"],CTB["softgrey"],CTB["hardgrey"],CTB["darkgrey"]
CTB["palebrown"],CTB["softbrown"],CTB["hardbrown"],CTB["darkbrown"]="#FAF6ED","#CCB56C","#AD7F14","#754910"
CTB["palepurple"],CTB["softpurple"],CTB["hardpurple"],CTB["darkpurple"]="#e0d1e6","#c784e0","#a029cf","#7a05a8"
CTB["paleorange"],CTB["softorange"],CTB["hardorange"],CTB["darkorange"]="#ffedc2","#ffcf61","#EEB533","#e39f05"
CTB["black"],CTB["white"],CTB["yellow"]="#000000","#FFFFFF","#FAF039"
CTB["background"],CTB["paleground"],CTB["beigeground"]="#f9f6f2","#FEFEFA","#F5F5DC"
CTB["beige"]=CTB["beigeground"]
CTB["aqua"],CTB["teal"],CTB["fuchsia"] = "#00FFFF","#008080","#FF00FF"
CTB["maroon"],CTB["olive"],CTB["navy"] = "#800000","#808000","#000080"
CTB["lime"],CTB["limegreen"],CTB["aquamarine"] = "#00FF00","#32CD32","#7FFFD4"
CTB["silver"],CTB["yellow"],CTB["orchid"] = "#800000","#FFFF00","#DA70D6"  
-- set up a table of predefined clip-paths
local pathshape={}
pathshape.squaredd = "M 19,1.25 l 0,18 -18,0 0,-18 18,0m-1,1 -16,0 0,16 16,0 0,-16m-1,1 0,14 -14,0 0,-14 14,0zm-1,1 -12,0 0,12 12,0 0,-12zm-1,1 0,10 -10,0 0,-10 10,0z"
pathshape.squared = "M 18,2.5 l 0,15 -15,0 0,-15 15,0m-1,1 -13,0 0,13 13,0 0,-13zm-1,1 0,11 -11,0 0,-11 11,0z"
pathshape.triangledd="M 0 20,20 20,10 0,0 20ZM1.5 19,10 1.7,18.5 19,1.5 19ZM3 18,17 18,10 3.8,3 18ZM4.5 17,10 5.4,15.4 17, 4.5,17ZM6 16,13.8 16,10 7.4z"
pathshape.triangled ="M1,18 l 18,0 l -9,-18 l -9,18zm1.7,-1.1 l 7.3,-14.6 l 7.3,14.6 l -14.6, 0zm1.7,-1 l 11.0,0 l -5.5,-11 l -5.5,11z"
pathshape.circledd = "M0,10a10,10 0 1,0 20,0a10,10 0 1,0 -20,0zm0.8,0a9.2,9.2 0 1,1 18.4,0a9.2,9.2 0 1,1 -18.4,0m1,0a8.2,8.2 0 1,0 16.4,0a8.2,8.2 0 1,0 -16.4,0zm0.8,0a7.2,7.2 0 1,1 14.8,0a7.2,7.2 0 1,1 -14.8,0m1,0 a6.4,6.4 0 1,1 12.8,0a6.4,6.4 0 1,1 -12.8,0z"
pathshape.circled = "M2.5,10a7.5,7.5 0 1,0 15,0a7.5,7.5 0 1,0 -15,0zm1,0a6.5,6.5 0 1,1 13,0a6.5,6.5 0 1,1 -13,0m0.8,0 a5,5 0 1,1 11.4,0a5,5 0 1,1 -11.4,0"
pathshape.diamond = "M3,10 l 7,-10 l 7,10 -7,10 -7,-10z"
pathshape.diamondd = "M3,10 l 7,-10 l 7,10 -7,10 -7,-10zm1,0 l 6,8.5 l 6,-8.5 -6,-8.5 -6,8.5zm1,0 l 5,-7 5,7 -5,7 -5,-7z"
pathshape.diamonddd = "M3,10 l 7,-10 l 7,10 -7,10 -7,-10zm0.75,0 l 6.25,9 l 6.25,-9 -6.25,-9 -6.25,9zm0.75,0 l 5.5,-8 5.5,8 -5.5,8 -5.5,-8zm0.75,0 l 4.75,7 l 4.75,-7 -4.75,-7 -4.75,7zm0.75,0 l 4,-6 4,6 -4,6 -4,-6z"
pathshape.crossd = "M3.1,12.5 l4.2,0 l0,4.2 l5,0 l0,-4 l4.2,0 l0,-5 l-4.2,0 l0,-4.2 l-5,0 l0,4.2 l-4.2,0zM2.3,10a7.5,7.5 0 1,0 15,0a7.5,7.5 0 1,0 -15,0zm1,0a6.5,6.5 0 1,1 13,0a6.5,6.5 0 1,1 -13,0z"
pathshape.cross = "M3.1,12.5 l4.2,0 l0,4.2 l5,0 l0,-4 l4.2,0 l0,-5 l-4.2,0 l0,-4.2 l-5,0 l0,4.2 l-4.2,0z"
pathshape.thincross = "M2,12 l6,0 l0,6 l4,0 l0,-6 l6,0 l0,-4 l-6,0 l0,-6 l-4,0 l0,6 l-6,0z"
pathshape.fivepointstar = "M10 0 L12.245 6.91 19.511 6.91 13.633 11.18 15.878 18.09 10 13.82 4.122 18.09 6.367 11.18 0.489 6.91 7.755 6.91Z"
pathshape.fivepointstard = "M10 1.5 L 11.90825 7.3735 18.08435 7.3735 13.08805 11.003 14.9963 16.8765 10 13.247 5.0037 16.8765 6.91195 11.003 1.91565 7.3735 8.09175 7.3735 ZM0,10a10,10 0 1,0 20,0a10,10 0 1,0 -20,0zm1.5,0a8.5,8.5 0 1,1 17,0a8.5,8.5 0 1,1 -17,0z"
pathshape.sixpointstar = "M10 0 L12.323 5.977 18.66 5 14.645 10 18.66 15 12.323 14.023 10 20 7.677 14.023 1.34 15 5.355 10 1.34 5 7.677 5.977Z"
pathshape.sixpointstard = "M10 1.5 L 11.97455 6.58045 17.361 5.75 13.94825 10 17.361 14.25 11.97455 13.41955 10 18.5 8.02545 13.41955 2.639 14.25 6.05175 10 2.639 5.75 8.02545 6.58045 ZM0,10a10,10 0 1,0 20,0a10,10 0 1,0 -20,0zm1.5,0a8.5,8.5 0 1,1 17,0a8.5,8.5 0 1,1 -17,0z"
pathshape.sevenpointstar = "M10 0 L12.048 5.747 17.818 3.765 14.602 8.95 19.749 12.225 13.69 12.943 14.339 19.01 10 14.72 5.661 19.01 6.31 12.943 0.251 12.225 5.398 8.95 2.182 3.765 7.952 5.747Z"