From 687dedfe1b9355ed03f1d4affba3f5d8f805485e Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 10 Jul 2021 20:08:30 +0300 Subject: [PATCH 01/82] state only borders + watercolor style --- index.css | 14 +-- index.html | 58 +++++++---- main.js | 9 +- modules/lakes.js | 7 +- modules/load.js | 10 +- modules/save.js | 5 +- modules/ui/general.js | 2 +- modules/ui/layers.js | 139 ++++++++++++++++++-------- modules/ui/style.js | 226 ++++++++++++++++++++++-------------------- 9 files changed, 279 insertions(+), 191 deletions(-) diff --git a/index.css b/index.css index be4e2143..849d66c0 100644 --- a/index.css +++ b/index.css @@ -171,11 +171,18 @@ a { #statesBody, #provincesBody { - stroke-width: 2; + stroke-width: 3; + stroke-linejoin: round; fill-rule: evenodd; mask: url(#land); } +#statesHalo { + fill: none; + stroke-linecap: round; + stroke-linejoin: round; +} + #relig, #biomes, #cults { @@ -183,11 +190,6 @@ a { mask: url(#land); } -#statesHalo { - fill: none; - filter: url(#blur5); -} - #borders { stroke-linejoin: round; fill: none; diff --git a/index.html b/index.html index ad8f238f..2d651fba 100644 --- a/index.html +++ b/index.html @@ -322,6 +322,7 @@ + @@ -363,16 +364,15 @@ - - + @@ -387,24 +387,6 @@ - - - - - - - - - - - - @@ -757,6 +739,40 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/main.js b/main.js index c53c5f65..93cc919b 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ // https://github.com/Azgaar/Fantasy-Map-Generator "use strict"; -const version = "1.63"; // generator version +const version = "1.64"; // generator version document.title += " v" + version; // Switches to disable/enable logging features @@ -506,13 +506,14 @@ function invokeActiveZooming() { // change states halo width if (!customization) { - const haloSize = rn(statesHalo.attr("data-width") / scale, 1); - statesHalo.attr("stroke-width", haloSize).style("display", haloSize > 3 ? "block" : "none"); + const desired = +statesHalo.attr("data-width"); + const haloSize = rn(desired / scale ** 0.8, 2); + statesHalo.attr("stroke-width", haloSize).style("display", haloSize > 0.1 ? "block" : "none"); } // rescale map markers if (+markers.attr("rescale") && markers.style("display") !== "none") { - markers.selectAll("use").each(function (d) { + markers.selectAll("use").each(function () { const x = +this.dataset.x, y = +this.dataset.y, desired = +this.dataset.size; diff --git a/modules/lakes.js b/modules/lakes.js index d127c2cf..778dcd2f 100644 --- a/modules/lakes.js +++ b/modules/lakes.js @@ -10,8 +10,8 @@ pack.features.forEach(f => { if (f.type !== "lake") return; - // default flux: sum of precipition around lake first cell - f.flux = rn(d3.sum(f.shoreline.map(c => grid.cells.prec[cells.g[c]])) / 2); + // default flux: sum of precipitation around lake + f.flux = f.shoreline.reduce((acc, c) => acc + grid.cells.prec[cells.g[c]], 0); // temperature and evaporation to detect closed lakes f.temp = f.cells < 6 ? grid.cells.temp[cells.g[f.firstCell]] : rn(d3.mean(f.shoreline.map(c => grid.cells.temp[cells.g[c]])), 1); @@ -96,7 +96,6 @@ if (feature.type !== "lake") continue; delete feature.river; delete feature.enteringFlux; - delete feature.shoreline; delete feature.outCell; delete feature.closed; feature.height = rn(feature.height, 3); @@ -140,7 +139,7 @@ if (feature.height > 60 && feature.cells < 10 && feature.firstCell % 10 === 0) return "lava"; if (!feature.inlets && !feature.outlet) { - if (feature.evaporation / 2 > feature.flux) return "dry"; + if (feature.evaporation > feature.flux * 4) return "dry"; if (feature.cells < 3 && feature.firstCell % 10 === 0) return "sinkhole"; } diff --git a/modules/load.js b/modules/load.js index ca5bf23b..619e8350 100644 --- a/modules/load.js +++ b/modules/load.js @@ -681,7 +681,7 @@ function parseLoadedData(data) { } if (version < 1.63) { - // v.1.63 change ocean pattern opacity element + // v.1.63 changed ocean pattern opacity element const oceanPattern = document.getElementById("oceanPattern"); if (oceanPattern) oceanPattern.removeAttribute("opacity"); const oceanicPattern = document.getElementById("oceanicPattern"); @@ -693,6 +693,14 @@ function parseLoadedData(data) { labels.select("#states").style("text-shadow", "white 0 0 4px"); labels.select("#addedLabels").style("text-shadow", "white 0 0 4px"); } + + if (version < 1.64) { + // v.1.64 change states style + const bodyOpacity = regions.attr("opacity"); + statesBody.attr("opacity", bodyOpacity); + statesHalo.attr("opacity", bodyOpacity).attr("filter", "blur(5px)"); + regions.removeAttribute("opacity"); + } })(); void (function checkDataIntegrity() { diff --git a/modules/save.js b/modules/save.js index 7d109e10..9b9d74c6 100644 --- a/modules/save.js +++ b/modules/save.js @@ -600,10 +600,7 @@ function getRiverPoints(node) { } async function quickSave() { - if (customization) { - tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error"); - return; - } + if (customization) return tip("Map cannot be saved when edit mode is active, please exit the mode and retry", false, "error"); const blob = await getMapData(); if (blob) ldb.set("lastMap", blob); // auto-save map tip("Map is saved to browser memory. Please also save as .map file to secure progress", true, "success", 2000); diff --git a/modules/ui/general.js b/modules/ui/general.js index d87afe06..5da081b5 100644 --- a/modules/ui/general.js +++ b/modules/ui/general.js @@ -22,7 +22,7 @@ document.getElementById("exitCustomization").addEventListener("mousemove", showD /** * @param {string} tip Tooltip text * @param {boolean} main Show above other tooltips - * @param {string} type Message type (color): error, warn, success + * @param {string} type Message type (color): error / warn / success * @param {number} time Timeout to auto hide, ms */ function tip(tip = "Tip is undefined", main, type, time) { diff --git a/modules/ui/layers.js b/modules/ui/layers.js index 7dc3953f..ff490119 100644 --- a/modules/ui/layers.js +++ b/modules/ui/layers.js @@ -880,30 +880,83 @@ function drawStates() { TIME && console.time("drawStates"); regions.selectAll("path").remove(); - const cells = pack.cells, - vertices = pack.vertices, - states = pack.states, - n = cells.i.length; + const {cells, vertices, features} = pack; + const states = pack.states; + const n = cells.i.length; + const used = new Uint8Array(cells.i.length); const vArray = new Array(states.length); // store vertices array - const body = new Array(states.length).fill(""); // store path around each state - const gap = new Array(states.length).fill(""); // store path along water for each state to fill the gaps + const body = new Array(states.length).fill(""); // path around each state + const gap = new Array(states.length).fill(""); // path along water for each state to fill the gaps + const halo = new Array(states.length).fill(""); // path around states, but not lakes + + // helper functions + const isLand = i => i[1] === "land"; + const nextIsLand = (ar, i) => ar[i + 1]?.[1] === "land"; + const prevIsLand = (ar, i) => ar[i - 1]?.[1] === "land"; + const getStringPoint = v => vertices.p[v[0]].join(","); + + // define inner-state lakes to omit on border render + const innerLakes = features.map(feature => { + if (feature.type !== "lake") return false; + if (!feature.shoreline) Lakes.getShoreline(feature); + + const states = feature.shoreline.map(i => cells.state[i]); + return new Set(states).size > 1 ? false : true; + }); for (const i of cells.i) { if (!cells.state[i] || used[i]) continue; - const s = cells.state[i]; - const onborder = cells.c[i].some(n => cells.state[n] !== s); + const state = cells.state[i]; + + // if (state !== 5) continue; + + const onborder = cells.c[i].some(n => cells.state[n] !== state); if (!onborder) continue; - const borderWith = cells.c[i].map(c => cells.state[c]).find(n => n !== s); + const borderWith = cells.c[i].map(c => cells.state[c]).find(n => n !== state); const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.state[i] === borderWith)); - const chain = connectVertices(vertex, s, borderWith); + const chain = connectVertices(vertex, state); if (chain.length < 3) continue; - const points = chain.map(v => vertices.p[v[0]]); - if (!vArray[s]) vArray[s] = []; - vArray[s].push(points); - body[s] += "M" + points.join("L"); - gap[s] += "M" + vertices.p[chain[0][0]] + chain.reduce((r, v, i, d) => (!i ? r : !v[2] ? r + "L" + vertices.p[v[0]] : d[i + 1] && !d[i + 1][2] ? r + "M" + vertices.p[v[0]] : r), ""); + + // get path around state + const points = chain.filter(v => v[1] !== "innerLake").map(v => vertices.p[v[0]]); + if (!vArray[state]) vArray[state] = []; + + if (points.length) { + vArray[state].push(points); + body[state] += "M" + points.join("L"); + } + + // connect path for halo + let discontinued = true; + halo[state] += chain + .map((v, i) => { + if (isLand(v) || nextIsLand(chain, i) || prevIsLand(chain, i)) { + const operation = discontinued ? "M" : "L"; + discontinued = false; + return `${operation}${getStringPoint(v)}`; + } + + discontinued = true; + return ""; + }) + .join(""); + + // connect gaps between state and water into a single path + discontinued = true; + gap[state] += chain + .map(v => { + if (isLand(v)) { + discontinued = true; + return ""; + } + + const operation = discontinued ? "M" : "L"; + discontinued = false; + return `${operation}${getStringPoint(v)}`; + }) + .join(""); } // find state visual center @@ -912,54 +965,56 @@ function drawStates() { states[i].pole = polylabel(sorted, 1.0); // pole of inaccessibility }); - const bodyData = body.map((p, i) => [p.length > 10 ? p : null, i, states[i].color]).filter(d => d[0]); - const gapData = gap.map((p, i) => [p.length > 10 ? p : null, i, states[i].color]).filter(d => d[0]); + const bodyData = body.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]); + const gapData = gap.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]); + const haloData = halo.map((p, s) => [p.length > 10 ? p : null, s, states[s].color]).filter(d => d[0]); const bodyString = bodyData.map(d => ``).join(""); const gapString = gapData.map(d => ``).join(""); const clipString = bodyData.map(d => ``).join(""); - const haloString = bodyData.map(d => ``).join(""); + const haloString = haloData.map(d => ``).join(""); statesBody.html(bodyString + gapString); defs.select("#statePaths").html(clipString); statesHalo.html(haloString); // connect vertices to chain - function connectVertices(start, t, state) { + function connectVertices(start, state) { const chain = []; // vertices chain to form a path - let land = vertices.c[start].some(c => cells.h[c] >= 20 && cells.state[c] !== t); - function check(i) { - state = cells.state[i]; - land = cells.h[i] >= 20; - } + const getType = c => { + const waterCell = c.find(i => cells.h[i] < 20); + if (!waterCell) return "land"; + if (innerLakes[cells.f[waterCell]]) return "innerLake"; + return features[cells.f[waterCell]].type; + }; for (let i = 0, current = start; i === 0 || (current !== start && i < 20000); i++) { - const prev = chain[chain.length - 1] ? chain[chain.length - 1][0] : -1; // previous vertex in chain - chain.push([current, state, land]); // add current vertex to sequence + const prev = chain.length ? chain[chain.length - 1][0] : -1; // previous vertex in chain + const c = vertices.c[current]; // cells adjacent to vertex - c.filter(c => cells.state[c] === t).forEach(c => (used[c] = 1)); - const c0 = c[0] >= n || cells.state[c[0]] !== t; - const c1 = c[1] >= n || cells.state[c[1]] !== t; - const c2 = c[2] >= n || cells.state[c[2]] !== t; + chain.push([current, getType(c)]); // add current vertex to sequence + + c.filter(c => cells.state[c] === state).forEach(c => (used[c] = 1)); + const c0 = c[0] >= n || cells.state[c[0]] !== state; + const c1 = c[1] >= n || cells.state[c[1]] !== state; + const c2 = c[2] >= n || cells.state[c[2]] !== state; + const v = vertices.v[current]; // neighboring vertices - if (v[0] !== prev && c0 !== c1) { - current = v[0]; - check(c0 ? c[0] : c[1]); - } else if (v[1] !== prev && c1 !== c2) { - current = v[1]; - check(c1 ? c[1] : c[2]); - } else if (v[2] !== prev && c0 !== c2) { - current = v[2]; - check(c2 ? c[2] : c[0]); - } - if (current === chain[chain.length - 1][0]) { + + if (v[0] !== prev && c0 !== c1) current = v[0]; + else if (v[1] !== prev && c1 !== c2) current = v[1]; + else if (v[2] !== prev && c0 !== c2) current = v[2]; + + if (current === prev) { ERROR && console.error("Next vertex is not found"); break; } } - chain.push([start, state, land]); // add starting vertex to sequence to close the path + + if (chain.length) chain.push(chain[0]); return chain; } + invokeActiveZooming(); TIME && console.timeEnd("drawStates"); } diff --git a/modules/ui/style.js b/modules/ui/style.js index d986bc28..e8db0bf4 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -29,31 +29,26 @@ function selectStyleElement() { let el = d3.select("#" + sel); styleElements.querySelectorAll("tbody").forEach(e => (e.style.display = "none")); // hide all sections - const off = sel !== "ocean" && (el.style("display") === "none" || !el.selectAll("*").size()); // check if layer is off - if (off) { - styleIsOff.style.display = "block"; - setTimeout(() => (styleIsOff.style.display = "none"), 1500); - } + + // show alert line if layer is not visible + const isLayerOff = sel !== "ocean" && (el.style("display") === "none" || !el.selectAll("*").size()); + styleIsOff.style.display = isLayerOff ? "block" : "none"; // active group element const group = styleGroupSelect.value; if (["routes", "labels", "coastline", "lakes", "anchors", "burgIcons", "borders"].includes(sel)) { - el = d3 - .select("#" + sel) - .select("g#" + group) - .size() - ? d3.select("#" + sel).select("g#" + group) - : d3.select("#" + sel).select("g"); + const gEl = el.select("#" + group); + el = gEl.size() ? gEl : el.select("g"); } - if (sel !== "landmass" && sel !== "legend") { - // opacity - if (sel !== "ocean") { - styleOpacity.style.display = "block"; - styleOpacityInput.value = styleOpacityOutput.value = el.attr("opacity") || 1; - } + // opacity + if (!["landmass", "ocean", "regions", "legend"].includes(sel)) { + styleOpacity.style.display = "block"; + styleOpacityInput.value = styleOpacityOutput.value = el.attr("opacity") || 1; + } - // filter + // filter + if (!["landmass", "legend"].includes(sel)) { styleFilter.style.display = "block"; styleFilterInput.value = el.attr("filter") || ""; } @@ -87,7 +82,6 @@ function selectStyleElement() { // show specific sections if (sel === "texture") styleTexture.style.display = "block"; - if ((sel === "routes", "labels" || sel == "anchors" || sel == "burgIcons", "coastline", "lakes", "borders")) styleGroup.style.display = "block"; if (sel === "terrs") { styleHeightmap.style.display = "block"; @@ -137,8 +131,11 @@ function selectStyleElement() { if (sel === "regions") { styleStates.style.display = "block"; - styleStatesHaloWidth.value = styleStatesHaloWidthOutput.value = statesHalo.attr("data-width"); - styleStatesHaloOpacity.value = styleStatesHaloOpacityOutput.value = statesHalo.attr("opacity"); + styleStatesBodyOpacity.value = styleStatesBodyOpacityOutput.value = statesBody.attr("opacity") || 1; + styleStatesHaloWidth.value = styleStatesHaloWidthOutput.value = statesHalo.attr("data-width") || 10; + styleStatesHaloOpacity.value = styleStatesHaloOpacityOutput.value = statesHalo.attr("opacity") || 1; + const blur = parseFloat(statesHalo.attr("filter")?.match(/blur\(([^)]+)\)/)?.[1]) || 0; + styleStatesHaloBlur.value = styleStatesHaloBlurOutput.value = blur; } if (sel === "labels") { @@ -254,17 +251,17 @@ function selectStyleElement() { // update group options styleGroupSelect.options.length = 0; // remove all options if (["routes", "labels", "coastline", "lakes", "anchors", "burgIcons", "borders"].includes(sel)) { - document - .getElementById(sel) - .querySelectorAll("g") - .forEach(el => { - if (el.id === "burgLabels") return; - const count = el.childElementCount; - styleGroupSelect.options.add(new Option(`${el.id} (${count})`, el.id, false, false)); - }); + const groups = document.getElementById(sel).querySelectorAll("g"); + groups.forEach(el => { + if (el.id === "burgLabels") return; + const option = new Option(`${el.id} (${el.childElementCount})`, el.id, false, false); + styleGroupSelect.options.add(option); + }); styleGroupSelect.value = el.attr("id"); + styleGroup.style.display = "block"; } else { styleGroupSelect.options.add(new Option(sel, sel, false, true)); + styleGroup.style.display = "none"; } if (sel === "coastline" && styleGroupSelect.value === "sea_island") { @@ -278,8 +275,8 @@ function selectStyleElement() { styleGroupSelect.addEventListener("change", selectStyleElement); function getEl() { - const el = styleElementSelect.value, - g = styleGroupSelect.value; + const el = styleElementSelect.value; + const g = styleGroupSelect.value; if (g === el) return svg.select("#" + el); else return svg.select("#" + el).select("#" + g); } @@ -317,10 +314,7 @@ styleOpacityInput.addEventListener("input", function () { }); styleFilterInput.addEventListener("change", function () { - if (styleGroupSelect.value === "ocean") { - oceanLayers.attr("filter", this.value); - return; - } + if (styleGroupSelect.value === "ocean") return oceanLayers.attr("filter", this.value); getEl().attr("filter", this.value); }); @@ -648,6 +642,11 @@ function changeIconSize(size, group) { styleIconSizeInput.value = size; } +styleStatesBodyOpacity.addEventListener("input", function () { + styleStatesBodyOpacityOutput.value = this.value; + statesBody.attr("opacity", this.value); +}); + styleStatesHaloWidth.addEventListener("input", function () { styleStatesHaloWidthOutput.value = this.value; statesHalo.attr("data-width", this.value).attr("stroke-width", this.value); @@ -658,6 +657,12 @@ styleStatesHaloOpacity.addEventListener("input", function () { statesHalo.attr("opacity", this.value); }); +styleStatesHaloBlur.addEventListener("input", function () { + styleStatesHaloBlurOutput.value = this.value; + const blur = +this.value > 0 ? `blur(${this.value}px)` : null; + statesHalo.attr("filter", blur); +}); + styleArmiesFillOpacity.addEventListener("input", function () { armies.attr("fill-opacity", this.value); styleArmiesFillOpacityOutput.value = this.value; @@ -722,10 +727,11 @@ function fetchTextureURL(url) { } const defaultStyles = { - styleAncient: `{"#map":{"background-color":"#000000","filter":"url(#filter-sepia)","data-filter":"sepia"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.05,"opacity":0.8,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":null,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eee9d7","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#5d97bb"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.8,"stroke":"#2e1607","stroke-width":1.23,"stroke-dasharray":3,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.8,"stroke":"#331809","stroke-width":0.5,"stroke-dasharray":"1 2","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.8,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#regions":{"opacity":0.4,"filter":""},"#statesHalo":{"opacity":1,"data-width":10,"stroke-width":10},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.8,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#outline)"},"#emblems":{"opacity":0.6,"stroke-width":0.8,"filter":"url(#dropShadow05)"},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#blur5)","layers":"-6,-4,-2"},"#oceanBase":{"fill":"#a7a01f"},"#oceanicPattern":{"href":"./images/pattern1.png", "opacity":0.2},"#terrs":{"opacity":null,"scheme":"light","terracing":0,"skip":0,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":8,"font-size":8,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#fdfab9","fill-opacity":0.7,"size":1,"stroke":"#54251d","stroke-width":0.3,"stroke-dasharray":".3 .4","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#fef4d8","fill-opacity":0.7,"size":0.5,"stroke":"#463124","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`, - styleGloom: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":"url(#land)"},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":""},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.3,"stroke-dasharray":".7 1","stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":14,"font-size":14,"stroke":"#4a4a4a","stroke-width":1,"stroke-dasharray":6,"stroke-linecap":null,"filter":"","mask":""},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(100 100) scale(0.3)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":1,"filter":null},"#cults":{"opacity":0.7,"stroke":"#777777","stroke-width":1.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e0e0e0","filter":null},"#markers":{"opacity":0.8,"rescale":1,"filter":"url(#dropShadow05)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000aa"},"#urban":{"stroke":"#9d0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.9,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":"","fill":"#779582"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":1,"stroke":"#8b4418","stroke-width":0.9,"stroke-dasharray":"2 3","stroke-linecap":"round","filter":"","mask":null},"#trails":{"opacity":1,"stroke":"#844017","stroke-width":0.2,"stroke-dasharray":".5 1","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#5e1865","stroke-width":0.6,"stroke-dasharray":"1.2 2.4","stroke-linecap":"round","filter":null,"mask":null},"#regions":{"opacity":0.4,"filter":"url(#dropShadow)"},"#statesHalo":{"opacity":1,"data-width":10.2,"stroke-width":10.2},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":1,"font-size":"11px","fill":"#62001b","fill-opacity":0.3,"stroke":null,"stroke-width":2,"stroke-dasharray":2,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#emblems": {"opacity":0.6,"stroke-width":0.5,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.5,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":"url(#dropShadow01)","mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#4e6964"},"#oceanicPattern":{"href":"./images/pattern3.png", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"bright","terracing":0,"skip":0,"relax":1,"curve":1,"filter":"url(#filter-grayscale)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":2,"stroke":"#444444","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":0.8,"fill":"#ffffff","size":4,"stroke":"#3e3e4b","stroke-width":1},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":3,"font-size":3,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #towns":{"opacity":0.95,"fill":"#ffffff","fill-opacity":0.7,"size":0.8,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1.6,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#4e4e4e","stroke":"#b5b5b5","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":""},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#1b1423","filter":null}}`, - styleClean: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.5,"filter":"url(#blur7)","mask":"url(#land)"},"#stateBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"butt","filter":""},"#provinceBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.09,"filter":null,"mask":"url(#land)"},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":3,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eeedeb","filter":null},"#markers":{"opacity":null,"rescale":null,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0,"fill":"#0080ff","filter":null},"#population":{"opacity":null,"stroke-width":2.58,"stroke-dasharray":0,"stroke-linecap":"butt","filter":"url(#blur3)"},"#rural":{"stroke":"#ff0000"},"#urban":{"stroke":"#800000"},"#freshwater":{"opacity":0.5,"fill":"#aadaff","stroke":"#5f799d","stroke-width":0,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#595959","stroke-width":0.4,"filter":"","auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#aadaff"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#f6d068","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#ffffff","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#4f82c6","stroke-width":0.45,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":"url(#water)"},"#regions":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0,"data-width":null,"stroke-width":0},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow01)"},"#emblems":{"opacity":1,"stroke-width":1,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.7,"stroke":"#ff6262","stroke-width":0,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"","layers":"none"},"#oceanBase":{"fill":"#aadaff"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":0.5,"scheme":"bright","terracing":0,"skip":5,"relax":0,"curve":0,"filter":"","mask":"url(#land)"},"#legend":{"data-size":12.74,"font-size":12.74,"data-font":"Arial","font-family":"Arial","stroke":"#909090","stroke-width":1.13,"stroke-dasharray":0,"stroke-linecap":"round","data-x":98.39,"data-y":12.67,"data-columns":null},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#414141","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#303030","stroke-width":1.7},"#burgLabels > #towns":{"opacity":1,"fill":"#414141","data-size":3,"font-size":3,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.06},"#labels > #states":{"opacity":1,"fill":"#292929","stroke":"#303030","stroke-width":0,"text-shadow":"white 0 0 2px","data-size":10,"font-size":10,"data-font":"Arial","font-family":"Arial","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#414141","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Arial","font-family":"Arial","filter":null},"#fogging":{"opacity":1,"fill":"#ffffff","filter":null}}`, - styleMonochrome: `{"#map":{"background-color":"#000000","filter":"url(#filter-grayscale)","data-filter":"grayscale"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":null},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.4,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#000000","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#000000","stroke":"#515151","stroke-width":0,"filter":null},"#salt":{"opacity":1,"fill":"#000000","stroke":"#484848","stroke-width":0,"filter":null},"#sinkhole":{"opacity":1,"fill":"#000000","stroke":"#5f5f5f","stroke-width":0.5,"filter":null},"#frozen":{"opacity":1,"fill":"#000000","stroke":"#6f6f6f","stroke-width":0,"filter":null},"#lava":{"opacity":1,"fill":"#000000","stroke":"#5d5d5d","stroke-width":0,"filter":""},"#sea_island":{"opacity":1,"stroke":"#1f3846","stroke-width":0,"filter":"","auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":0.2,"filter":"url(#blur1)","fill":"#000000"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.7,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.25,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#regions":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":1,"data-width":10,"stroke-width":10},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#texture":{"opacity":1,"filter":null,"mask":"url(#land)"},"#emblems": {"opacity": 0.5,"stroke-width": 0.5,"filter": null},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#000000"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"monochrome","terracing":0,"skip":5,"relax":0,"curve":0,"filter":"url(#blur3)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}` + styleAncient: `{"#map":{"background-color":"#000000","filter":"url(#filter-sepia)","data-filter":"sepia"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.05,"opacity":0.8,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":null,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eee9d7","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#5d97bb"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.8,"stroke":"#2e1607","stroke-width":1.23,"stroke-dasharray":3,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.8,"stroke":"#331809","stroke-width":0.5,"stroke-dasharray":"1 2","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.8,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#regions":{"filter":null},"#statesBody":{"opacity":0.4},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(8px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.8,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#outline)"},"#emblems":{"opacity":0.6,"stroke-width":0.8,"filter":"url(#dropShadow05)"},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#blur5)","layers":"-6,-4,-2"},"#oceanBase":{"fill":"#a7a01f"},"#oceanicPattern":{"href":"./images/pattern1.png", "opacity":0.2},"#terrs":{"opacity":null,"scheme":"light","terracing":0,"skip":0,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":8,"font-size":8,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#fdfab9","fill-opacity":0.7,"size":1,"stroke":"#54251d","stroke-width":0.3,"stroke-dasharray":".3 .4","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#fef4d8","fill-opacity":0.7,"size":0.5,"stroke":"#463124","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`, + styleGloom: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":"url(#land)"},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.3,"stroke-dasharray":".7 1","stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":14,"font-size":14,"stroke":"#4a4a4a","stroke-width":1,"stroke-dasharray":6,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(100 100) scale(0.3)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":1,"filter":null},"#cults":{"opacity":0.7,"stroke":"#777777","stroke-width":1.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e0e0e0","filter":null},"#markers":{"opacity":0.8,"rescale":1,"filter":"url(#dropShadow05)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000aa"},"#urban":{"stroke":"#9d0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.9,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#779582"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":1,"stroke":"#8b4418","stroke-width":0.9,"stroke-dasharray":"2 3","stroke-linecap":"round","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#844017","stroke-width":0.2,"stroke-dasharray":".5 1","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#5e1865","stroke-width":0.6,"stroke-dasharray":"1.2 2.4","stroke-linecap":"round","filter":null,"mask":null}, "#regions":{"filter":"url(#dropShadow)"},"#statesBody":{"opacity":0.4},"#statesHalo":{"opacity":0.5,"data-width":12,"stroke-width":12,"filter":"blur(10px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":1,"font-size":"11px","fill":"#62001b","fill-opacity":0.3,"stroke":null,"stroke-width":2,"stroke-dasharray":2,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#emblems": {"opacity":0.6,"stroke-width":0.5,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.5,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":"url(#dropShadow01)","mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#4e6964"},"#oceanicPattern":{"href":"./images/pattern3.png", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"bright","terracing":0,"skip":0,"relax":1,"curve":1,"filter":"url(#filter-grayscale)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":2,"stroke":"#444444","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":0.8,"fill":"#ffffff","size":4,"stroke":"#3e3e4b","stroke-width":1},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":3,"font-size":3,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #towns":{"opacity":0.95,"fill":"#ffffff","fill-opacity":0.7,"size":0.8,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1.6,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#4e4e4e","stroke":"#b5b5b5","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#1b1423","filter":null}}`, + styleClean: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.5,"filter":"url(#blur7)","mask":"url(#land)"},"#stateBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.09,"filter":null,"mask":"url(#land)"},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":3,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eeedeb","filter":null},"#markers":{"opacity":null,"rescale":null,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0,"fill":"#0080ff","filter":null},"#population":{"opacity":null,"stroke-width":2.58,"stroke-dasharray":0,"stroke-linecap":"butt","filter":"url(#blur3)"},"#rural":{"stroke":"#ff0000"},"#urban":{"stroke":"#800000"},"#freshwater":{"opacity":0.5,"fill":"#aadaff","stroke":"#5f799d","stroke-width":0,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#595959","stroke-width":0.4,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#aadaff"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#f6d068","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#ffffff","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#4f82c6","stroke-width":0.45,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":"url(#water)"},"#regions":{"filter":null},"#statesBody":{"opacity":0.3},"#statesHalo":{"opacity":0.5,"data-width":1,"stroke-width":1,"filter":null},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow01)"},"#emblems":{"opacity":1,"stroke-width":1,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.7,"stroke":"#ff6262","stroke-width":0,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#aadaff"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":0.5,"scheme":"bright","terracing":0,"skip":5,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":12.74,"font-size":12.74,"data-font":"Arial","font-family":"Arial","stroke":"#909090","stroke-width":1.13,"stroke-dasharray":0,"stroke-linecap":"round","data-x":98.39,"data-y":12.67,"data-columns":null},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#414141","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#303030","stroke-width":1.7},"#burgLabels > #towns":{"opacity":1,"fill":"#414141","data-size":3,"font-size":3,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.06},"#labels > #states":{"opacity":1,"fill":"#292929","stroke":"#303030","stroke-width":0,"text-shadow":"white 0 0 2px","data-size":10,"font-size":10,"data-font":"Arial","font-family":"Arial","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#414141","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Arial","font-family":"Arial","filter":null},"#fogging":{"opacity":1,"fill":"#ffffff","filter":null}}`, + styleWatercolor: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.2,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.6,"filter":null,"mask":null},"#stateBorders":{"opacity":0.6,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":3,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.5,"stroke":"#56566d","stroke-width":0.5,"stroke-dasharray":"0 2","stroke-linecap":"round","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#777777","stroke-width":0,"filter":"url(#bluredSplotch)"},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":"url(#splotch)"},"#landmass":{"opacity":1,"fill":"#eef6fb","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":1,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":null,"set":"gray","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#2e89c2"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#969696","stroke-width":0.4,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#regions":{"filter":null},"#statesBody":{"opacity":0.05},"#statesHalo":{"opacity":0.4,"data-width":8,"stroke-width":8,"filter":"blur(2px)"},"#provs":{"opacity":0.7,"fill":"#000000","font-size":4,"data-font":"Comfortaa:700","font-family":"Comfortaa","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.7,"fill":"#dfe8ec","stroke":"#000000","stroke-width":0,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.95,"stroke-width":1,"filter":null},"#texture":{"opacity":0.2,"filter":null,"mask":"url(#land)"},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#2d788b"},"#oceanicPattern":{"href":"./images/kiwiroo.png","opacity":0.5},"#terrs":{"opacity":0.5,"scheme":"light","terracing":0,"skip":5,"relax":1,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#043449","text-shadow":"white 0px 0px 2px","data-size":5,"font-size":5,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":3,"font-size":3,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#ffffff","stroke":"#000000","stroke-width":0.15,"text-shadow":"black 1px 1px 2px","data-size":20,"font-size":20,"data-font":"Gloria+Hallelujah","font-family":"Gloria Hallelujah","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":18,"font-size":18,"data-font":"Comfortaa","font-family":"Comfortaa","filter":null},"#fogging":{"opacity":0.97,"fill":"#8398ce","filter":null}}`, + styleMonochrome: `{"#map":{"background-color":"#000000","filter":"url(#filter-grayscale)","data-filter":"grayscale"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":null},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.4,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#000000","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#000000","stroke":"#515151","stroke-width":0,"filter":null},"#salt":{"opacity":1,"fill":"#000000","stroke":"#484848","stroke-width":0,"filter":null},"#sinkhole":{"opacity":1,"fill":"#000000","stroke":"#5f5f5f","stroke-width":0.5,"filter":null},"#frozen":{"opacity":1,"fill":"#000000","stroke":"#6f6f6f","stroke-width":0,"filter":null},"#lava":{"opacity":1,"fill":"#000000","stroke":"#5d5d5d","stroke-width":0,"filter":null},"#sea_island":{"opacity":1,"stroke":"#1f3846","stroke-width":0,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":0.2,"filter":"url(#blur1)","fill":"#000000"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.7,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.25,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#regions":{"filter":null},"#statesBody":{"opacity":0.4},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(5px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#texture":{"opacity":1,"filter":null,"mask":"url(#land)"},"#emblems": {"opacity": 0.5,"stroke-width": 0.5,"filter": null},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#000000"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"monochrome","terracing":0,"skip":5,"relax":0,"curve":0,"filter":"url(#blur3)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}` }; // apply default or custom style settings on load @@ -790,8 +796,10 @@ function applyDefaultStyle() { trails.attr("opacity", 0.9).attr("stroke", "#d06324").attr("stroke-width", 0.25).attr("stroke-dasharray", ".8 1.6").attr("stroke-linecap", "butt").attr("filter", null).attr("mask", null); searoutes.attr("opacity", 0.8).attr("stroke", "#ffffff").attr("stroke-width", 0.45).attr("stroke-dasharray", "1 2").attr("stroke-linecap", "round").attr("filter", null).attr("mask", null); - regions.attr("opacity", 0.4).attr("filter", null); - statesHalo.attr("data-width", 10).attr("stroke-width", 10).attr("opacity", 1); + regions.attr("filter", null); + statesBody.attr("opacity", 0.4); + statesHalo.attr("data-width", 10).attr("stroke-width", 10).attr("opacity", 0.4).attr("filter", "blur(5px)"); + provs.attr("opacity", 0.7).attr("fill", "#000000").attr("font-family", "Georgia").attr("data-font", "Georgia").attr("data-size", 10).attr("font-size", 10).attr("filter", null); temperature.attr("opacity", null).attr("fill", "#000000").attr("stroke-width", 1.8).attr("fill-opacity", 0.3).attr("font-size", "8px").attr("stroke-dasharray", null).attr("filter", null).attr("mask", null); @@ -954,75 +962,77 @@ function addStylePreset() { }); function getStyle() { - const style = {}, - attributes = { - "#map": ["background-color", "filter", "data-filter"], - "#armies": ["font-size", "box-size", "stroke", "stroke-width", "fill-opacity", "filter"], - "#biomes": ["opacity", "filter", "mask"], - "#stateBorders": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"], - "#provinceBorders": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"], - "#cells": ["opacity", "stroke", "stroke-width", "filter", "mask"], - "#gridOverlay": ["opacity", "scale", "dx", "dy", "type", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "transform", "filter", "mask"], - "#coordinates": ["opacity", "data-size", "font-size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], - "#compass": ["opacity", "transform", "filter", "mask", "shape-rendering"], - "#rose": ["transform"], - "#relig": ["opacity", "stroke", "stroke-width", "filter"], - "#cults": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"], - "#landmass": ["opacity", "fill", "filter"], - "#markers": ["opacity", "rescale", "filter"], - "#prec": ["opacity", "stroke", "stroke-width", "fill", "filter"], - "#population": ["opacity", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"], - "#rural": ["stroke"], - "#urban": ["stroke"], - "#freshwater": ["opacity", "fill", "stroke", "stroke-width", "filter"], - "#salt": ["opacity", "fill", "stroke", "stroke-width", "filter"], - "#sinkhole": ["opacity", "fill", "stroke", "stroke-width", "filter"], - "#frozen": ["opacity", "fill", "stroke", "stroke-width", "filter"], - "#lava": ["opacity", "fill", "stroke", "stroke-width", "filter"], - "#dry": ["opacity", "fill", "stroke", "stroke-width", "filter"], - "#sea_island": ["opacity", "stroke", "stroke-width", "filter", "auto-filter"], - "#lake_island": ["opacity", "stroke", "stroke-width", "filter"], - "#terrain": ["opacity", "set", "size", "density", "filter", "mask"], - "#rivers": ["opacity", "filter", "fill"], - "#ruler": ["opacity", "filter"], - "#roads": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], - "#trails": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], - "#searoutes": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], - "#regions": ["opacity", "filter"], - "#statesHalo": ["opacity", "data-width", "stroke-width"], - "#provs": ["opacity", "fill", "font-size", "data-font", "font-family", "filter"], - "#temperature": ["opacity", "font-size", "fill", "fill-opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"], - "#ice": ["opacity", "fill", "stroke", "stroke-width", "filter"], - "#emblems": ["opacity", "stroke-width", "filter"], - "#texture": ["opacity", "filter", "mask"], - "#textureImage": ["x", "y"], - "#zones": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], - "#oceanLayers": ["filter", "layers"], - "#oceanBase": ["fill"], - "#oceanicPattern": ["href", "opacity"], - "#terrs": ["opacity", "scheme", "terracing", "skip", "relax", "curve", "filter", "mask"], - "#legend": ["data-size", "font-size", "data-font", "font-family", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "data-x", "data-y", "data-columns"], - "#legendBox": ["fill", "fill-opacity"], - "#burgLabels > #cities": ["opacity", "fill", "text-shadow", "data-size", "font-size", "data-font", "font-family"], - "#burgIcons > #cities": ["opacity", "fill", "fill-opacity", "size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap"], - "#anchors > #cities": ["opacity", "fill", "size", "stroke", "stroke-width"], - "#burgLabels > #towns": ["opacity", "fill", "text-shadow", "data-size", "font-size", "data-font", "font-family"], - "#burgIcons > #towns": ["opacity", "fill", "fill-opacity", "size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap"], - "#anchors > #towns": ["opacity", "fill", "size", "stroke", "stroke-width"], - "#labels > #states": ["opacity", "fill", "stroke", "stroke-width", "text-shadow", "data-size", "font-size", "data-font", "font-family", "filter"], - "#labels > #addedLabels": ["opacity", "fill", "stroke", "stroke-width", "text-shadow", "data-size", "font-size", "data-font", "font-family", "filter"], - "#fogging": ["opacity", "fill", "filter"] - }; + const style = {}; + const attributes = { + "#map": ["background-color", "filter", "data-filter"], + "#armies": ["font-size", "box-size", "stroke", "stroke-width", "fill-opacity", "filter"], + "#biomes": ["opacity", "filter", "mask"], + "#stateBorders": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"], + "#provinceBorders": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"], + "#cells": ["opacity", "stroke", "stroke-width", "filter", "mask"], + "#gridOverlay": ["opacity", "scale", "dx", "dy", "type", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "transform", "filter", "mask"], + "#coordinates": ["opacity", "data-size", "font-size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], + "#compass": ["opacity", "transform", "filter", "mask", "shape-rendering"], + "#rose": ["transform"], + "#relig": ["opacity", "stroke", "stroke-width", "filter"], + "#cults": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"], + "#landmass": ["opacity", "fill", "filter"], + "#markers": ["opacity", "rescale", "filter"], + "#prec": ["opacity", "stroke", "stroke-width", "fill", "filter"], + "#population": ["opacity", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"], + "#rural": ["stroke"], + "#urban": ["stroke"], + "#freshwater": ["opacity", "fill", "stroke", "stroke-width", "filter"], + "#salt": ["opacity", "fill", "stroke", "stroke-width", "filter"], + "#sinkhole": ["opacity", "fill", "stroke", "stroke-width", "filter"], + "#frozen": ["opacity", "fill", "stroke", "stroke-width", "filter"], + "#lava": ["opacity", "fill", "stroke", "stroke-width", "filter"], + "#dry": ["opacity", "fill", "stroke", "stroke-width", "filter"], + "#sea_island": ["opacity", "stroke", "stroke-width", "filter", "auto-filter"], + "#lake_island": ["opacity", "stroke", "stroke-width", "filter"], + "#terrain": ["opacity", "set", "size", "density", "filter", "mask"], + "#rivers": ["opacity", "filter", "fill"], + "#ruler": ["opacity", "filter"], + "#roads": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], + "#trails": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], + "#searoutes": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], + "#regions": ["filter"], + "#statesBody": ["opacity"], + "#statesHalo": ["opacity", "data-width", "stroke-width", "filter"], + "#provs": ["opacity", "fill", "font-size", "data-font", "font-family", "filter"], + "#temperature": ["opacity", "font-size", "fill", "fill-opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"], + "#ice": ["opacity", "fill", "stroke", "stroke-width", "filter"], + "#emblems": ["opacity", "stroke-width", "filter"], + "#texture": ["opacity", "filter", "mask"], + "#textureImage": ["x", "y"], + "#zones": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], + "#oceanLayers": ["filter", "layers"], + "#oceanBase": ["fill"], + "#oceanicPattern": ["href", "opacity"], + "#terrs": ["opacity", "scheme", "terracing", "skip", "relax", "curve", "filter", "mask"], + "#legend": ["data-size", "font-size", "data-font", "font-family", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "data-x", "data-y", "data-columns"], + "#legendBox": ["fill", "fill-opacity"], + "#burgLabels > #cities": ["opacity", "fill", "text-shadow", "data-size", "font-size", "data-font", "font-family"], + "#burgIcons > #cities": ["opacity", "fill", "fill-opacity", "size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap"], + "#anchors > #cities": ["opacity", "fill", "size", "stroke", "stroke-width"], + "#burgLabels > #towns": ["opacity", "fill", "text-shadow", "data-size", "font-size", "data-font", "font-family"], + "#burgIcons > #towns": ["opacity", "fill", "fill-opacity", "size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap"], + "#anchors > #towns": ["opacity", "fill", "size", "stroke", "stroke-width"], + "#labels > #states": ["opacity", "fill", "stroke", "stroke-width", "text-shadow", "data-size", "font-size", "data-font", "font-family", "filter"], + "#labels > #addedLabels": ["opacity", "fill", "stroke", "stroke-width", "text-shadow", "data-size", "font-size", "data-font", "font-family", "filter"], + "#fogging": ["opacity", "fill", "filter"] + }; for (const selector in attributes) { - const s = (style[selector] = {}); - attributes[selector].forEach(attr => { - const el = document.querySelector(selector); - if (!el) return; - let value = el.getAttribute(attr) || el.style[attr]; + const el = document.querySelector(selector); + if (!el) continue; + + style[selector] = {}; + for (const attr of attributes[selector]) { + let value = el.style[attr] || el.getAttribute(attr); if (attr === "font-size" && el.hasAttribute("data-size")) value = el.getAttribute("data-size"); - s[attr] = parseValue(value); - }); + style[selector][attr] = parseValue(value); + } } function parseValue(value) { @@ -1069,7 +1079,7 @@ function addStylePreset() { localStorage.setItem(preset, styleSaverJSON.value); // save preset $("#styleSaver").dialog("close"); removeStyleButton.style.display = "inline-block"; - tip("Style preset is saved", false, "warn", 4000); + tip("Style preset is saved", false, "success", 4000); } function styleDownload() { From 43ce0424a5b9889f767cc29dc090f9253a80065e Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 10 Jul 2021 20:45:59 +0300 Subject: [PATCH 02/82] move filter from regions to statesBody --- index.html | 69 +++++++++++++++++---------------------------- modules/load.js | 9 +++--- modules/ui/style.js | 38 ++++++++++++++++++------- 3 files changed, 59 insertions(+), 57 deletions(-) diff --git a/index.html b/index.html index 2d651fba..7d851b89 100644 --- a/index.html +++ b/index.html @@ -45,36 +45,36 @@ xmlns:svg="http://www.w3.org/2000/svg"> - + - + - + - + - + - + - + - + - + @@ -82,7 +82,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -98,23 +98,23 @@ - + - + - + - + @@ -124,7 +124,7 @@ - + @@ -134,16 +134,16 @@ - + - + - + - + @@ -748,6 +748,11 @@ + + + + + - + diff --git a/modules/load.js b/modules/load.js index 619e8350..4308eceb 100644 --- a/modules/load.js +++ b/modules/load.js @@ -696,10 +696,11 @@ function parseLoadedData(data) { if (version < 1.64) { // v.1.64 change states style - const bodyOpacity = regions.attr("opacity"); - statesBody.attr("opacity", bodyOpacity); - statesHalo.attr("opacity", bodyOpacity).attr("filter", "blur(5px)"); - regions.removeAttribute("opacity"); + const opacity = regions.attr("opacity"); + const filter = regions.attr("filter"); + statesBody.attr("opacity", opacity).attr("filter", filter); + statesHalo.attr("opacity", opacity).attr("filter", "blur(5px)"); + regions.attr("opacity", null).attr("filter", null); } })(); diff --git a/modules/ui/style.js b/modules/ui/style.js index e8db0bf4..d25a7d4f 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -1,6 +1,21 @@ // UI module to control the style "use strict"; +// add available filters to lists +void (function addFilters() { + const filters = Array.from(document.getElementById("filters").querySelectorAll("filter")); + const emptyOption = ''; + const options = filters.map(filter => { + const id = filter.getAttribute("id"); + const name = filter.getAttribute("name"); + return ``; + }); + const allOptions = emptyOption + options.join(""); + + document.getElementById("styleFilterInput").innerHTML = allOptions; + document.getElementById("styleStatesBodyFilter").innerHTML = allOptions; +})(); + // store some style inputs as options styleElements.addEventListener("change", function (ev) { if (ev.target.dataset.stored) lock(ev.target.dataset.stored); @@ -48,7 +63,7 @@ function selectStyleElement() { } // filter - if (!["landmass", "legend"].includes(sel)) { + if (!["landmass", "legend", "regions"].includes(sel)) { styleFilter.style.display = "block"; styleFilterInput.value = el.attr("filter") || ""; } @@ -132,6 +147,7 @@ function selectStyleElement() { if (sel === "regions") { styleStates.style.display = "block"; styleStatesBodyOpacity.value = styleStatesBodyOpacityOutput.value = statesBody.attr("opacity") || 1; + styleStatesBodyFilter.value = statesBody.attr("filter") || ""; styleStatesHaloWidth.value = styleStatesHaloWidthOutput.value = statesHalo.attr("data-width") || 10; styleStatesHaloOpacity.value = styleStatesHaloOpacityOutput.value = statesHalo.attr("opacity") || 1; const blur = parseFloat(statesHalo.attr("filter")?.match(/blur\(([^)]+)\)/)?.[1]) || 0; @@ -647,6 +663,10 @@ styleStatesBodyOpacity.addEventListener("input", function () { statesBody.attr("opacity", this.value); }); +styleStatesBodyFilter.addEventListener("change", function () { + statesBody.attr("filter", this.value); +}); + styleStatesHaloWidth.addEventListener("input", function () { styleStatesHaloWidthOutput.value = this.value; statesHalo.attr("data-width", this.value).attr("stroke-width", this.value); @@ -727,11 +747,11 @@ function fetchTextureURL(url) { } const defaultStyles = { - styleAncient: `{"#map":{"background-color":"#000000","filter":"url(#filter-sepia)","data-filter":"sepia"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.05,"opacity":0.8,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":null,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eee9d7","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#5d97bb"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.8,"stroke":"#2e1607","stroke-width":1.23,"stroke-dasharray":3,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.8,"stroke":"#331809","stroke-width":0.5,"stroke-dasharray":"1 2","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.8,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#regions":{"filter":null},"#statesBody":{"opacity":0.4},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(8px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.8,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#outline)"},"#emblems":{"opacity":0.6,"stroke-width":0.8,"filter":"url(#dropShadow05)"},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#blur5)","layers":"-6,-4,-2"},"#oceanBase":{"fill":"#a7a01f"},"#oceanicPattern":{"href":"./images/pattern1.png", "opacity":0.2},"#terrs":{"opacity":null,"scheme":"light","terracing":0,"skip":0,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":8,"font-size":8,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#fdfab9","fill-opacity":0.7,"size":1,"stroke":"#54251d","stroke-width":0.3,"stroke-dasharray":".3 .4","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#fef4d8","fill-opacity":0.7,"size":0.5,"stroke":"#463124","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`, - styleGloom: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":"url(#land)"},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.3,"stroke-dasharray":".7 1","stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":14,"font-size":14,"stroke":"#4a4a4a","stroke-width":1,"stroke-dasharray":6,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(100 100) scale(0.3)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":1,"filter":null},"#cults":{"opacity":0.7,"stroke":"#777777","stroke-width":1.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e0e0e0","filter":null},"#markers":{"opacity":0.8,"rescale":1,"filter":"url(#dropShadow05)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000aa"},"#urban":{"stroke":"#9d0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.9,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#779582"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":1,"stroke":"#8b4418","stroke-width":0.9,"stroke-dasharray":"2 3","stroke-linecap":"round","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#844017","stroke-width":0.2,"stroke-dasharray":".5 1","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#5e1865","stroke-width":0.6,"stroke-dasharray":"1.2 2.4","stroke-linecap":"round","filter":null,"mask":null}, "#regions":{"filter":"url(#dropShadow)"},"#statesBody":{"opacity":0.4},"#statesHalo":{"opacity":0.5,"data-width":12,"stroke-width":12,"filter":"blur(10px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":1,"font-size":"11px","fill":"#62001b","fill-opacity":0.3,"stroke":null,"stroke-width":2,"stroke-dasharray":2,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#emblems": {"opacity":0.6,"stroke-width":0.5,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.5,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":"url(#dropShadow01)","mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#4e6964"},"#oceanicPattern":{"href":"./images/pattern3.png", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"bright","terracing":0,"skip":0,"relax":1,"curve":1,"filter":"url(#filter-grayscale)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":2,"stroke":"#444444","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":0.8,"fill":"#ffffff","size":4,"stroke":"#3e3e4b","stroke-width":1},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":3,"font-size":3,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #towns":{"opacity":0.95,"fill":"#ffffff","fill-opacity":0.7,"size":0.8,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1.6,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#4e4e4e","stroke":"#b5b5b5","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#1b1423","filter":null}}`, - styleClean: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.5,"filter":"url(#blur7)","mask":"url(#land)"},"#stateBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.09,"filter":null,"mask":"url(#land)"},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":3,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eeedeb","filter":null},"#markers":{"opacity":null,"rescale":null,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0,"fill":"#0080ff","filter":null},"#population":{"opacity":null,"stroke-width":2.58,"stroke-dasharray":0,"stroke-linecap":"butt","filter":"url(#blur3)"},"#rural":{"stroke":"#ff0000"},"#urban":{"stroke":"#800000"},"#freshwater":{"opacity":0.5,"fill":"#aadaff","stroke":"#5f799d","stroke-width":0,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#595959","stroke-width":0.4,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#aadaff"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#f6d068","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#ffffff","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#4f82c6","stroke-width":0.45,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":"url(#water)"},"#regions":{"filter":null},"#statesBody":{"opacity":0.3},"#statesHalo":{"opacity":0.5,"data-width":1,"stroke-width":1,"filter":null},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow01)"},"#emblems":{"opacity":1,"stroke-width":1,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.7,"stroke":"#ff6262","stroke-width":0,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#aadaff"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":0.5,"scheme":"bright","terracing":0,"skip":5,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":12.74,"font-size":12.74,"data-font":"Arial","font-family":"Arial","stroke":"#909090","stroke-width":1.13,"stroke-dasharray":0,"stroke-linecap":"round","data-x":98.39,"data-y":12.67,"data-columns":null},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#414141","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#303030","stroke-width":1.7},"#burgLabels > #towns":{"opacity":1,"fill":"#414141","data-size":3,"font-size":3,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.06},"#labels > #states":{"opacity":1,"fill":"#292929","stroke":"#303030","stroke-width":0,"text-shadow":"white 0 0 2px","data-size":10,"font-size":10,"data-font":"Arial","font-family":"Arial","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#414141","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Arial","font-family":"Arial","filter":null},"#fogging":{"opacity":1,"fill":"#ffffff","filter":null}}`, - styleWatercolor: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.2,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.6,"filter":null,"mask":null},"#stateBorders":{"opacity":0.6,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":3,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.5,"stroke":"#56566d","stroke-width":0.5,"stroke-dasharray":"0 2","stroke-linecap":"round","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#777777","stroke-width":0,"filter":"url(#bluredSplotch)"},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":"url(#splotch)"},"#landmass":{"opacity":1,"fill":"#eef6fb","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":1,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":null,"set":"gray","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#2e89c2"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#969696","stroke-width":0.4,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#regions":{"filter":null},"#statesBody":{"opacity":0.05},"#statesHalo":{"opacity":0.4,"data-width":8,"stroke-width":8,"filter":"blur(2px)"},"#provs":{"opacity":0.7,"fill":"#000000","font-size":4,"data-font":"Comfortaa:700","font-family":"Comfortaa","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.7,"fill":"#dfe8ec","stroke":"#000000","stroke-width":0,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.95,"stroke-width":1,"filter":null},"#texture":{"opacity":0.2,"filter":null,"mask":"url(#land)"},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#2d788b"},"#oceanicPattern":{"href":"./images/kiwiroo.png","opacity":0.5},"#terrs":{"opacity":0.5,"scheme":"light","terracing":0,"skip":5,"relax":1,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#043449","text-shadow":"white 0px 0px 2px","data-size":5,"font-size":5,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":3,"font-size":3,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#ffffff","stroke":"#000000","stroke-width":0.15,"text-shadow":"black 1px 1px 2px","data-size":20,"font-size":20,"data-font":"Gloria+Hallelujah","font-family":"Gloria Hallelujah","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":18,"font-size":18,"data-font":"Comfortaa","font-family":"Comfortaa","filter":null},"#fogging":{"opacity":0.97,"fill":"#8398ce","filter":null}}`, - styleMonochrome: `{"#map":{"background-color":"#000000","filter":"url(#filter-grayscale)","data-filter":"grayscale"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":null},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.4,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#000000","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#000000","stroke":"#515151","stroke-width":0,"filter":null},"#salt":{"opacity":1,"fill":"#000000","stroke":"#484848","stroke-width":0,"filter":null},"#sinkhole":{"opacity":1,"fill":"#000000","stroke":"#5f5f5f","stroke-width":0.5,"filter":null},"#frozen":{"opacity":1,"fill":"#000000","stroke":"#6f6f6f","stroke-width":0,"filter":null},"#lava":{"opacity":1,"fill":"#000000","stroke":"#5d5d5d","stroke-width":0,"filter":null},"#sea_island":{"opacity":1,"stroke":"#1f3846","stroke-width":0,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":0.2,"filter":"url(#blur1)","fill":"#000000"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.7,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.25,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#regions":{"filter":null},"#statesBody":{"opacity":0.4},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(5px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#texture":{"opacity":1,"filter":null,"mask":"url(#land)"},"#emblems": {"opacity": 0.5,"stroke-width": 0.5,"filter": null},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#000000"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"monochrome","terracing":0,"skip":5,"relax":0,"curve":0,"filter":"url(#blur3)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}` + styleAncient: `{"#map":{"background-color":"#000000","filter":"url(#filter-sepia)","data-filter":"sepia"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.05,"opacity":0.8,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":null,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eee9d7","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#5d97bb"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.8,"stroke":"#2e1607","stroke-width":1.23,"stroke-dasharray":3,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.8,"stroke":"#331809","stroke-width":0.5,"stroke-dasharray":"1 2","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.8,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(8px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.8,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#outline)"},"#emblems":{"opacity":0.6,"stroke-width":0.8,"filter":"url(#dropShadow05)"},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#blur5)","layers":"-6,-4,-2"},"#oceanBase":{"fill":"#a7a01f"},"#oceanicPattern":{"href":"./images/pattern1.png", "opacity":0.2},"#terrs":{"opacity":null,"scheme":"light","terracing":0,"skip":0,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":8,"font-size":8,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#fdfab9","fill-opacity":0.7,"size":1,"stroke":"#54251d","stroke-width":0.3,"stroke-dasharray":".3 .4","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#fef4d8","fill-opacity":0.7,"size":0.5,"stroke":"#463124","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`, + styleGloom: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":"url(#land)"},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.3,"stroke-dasharray":".7 1","stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":14,"font-size":14,"stroke":"#4a4a4a","stroke-width":1,"stroke-dasharray":6,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(100 100) scale(0.3)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":1,"filter":null},"#cults":{"opacity":0.7,"stroke":"#777777","stroke-width":1.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e0e0e0","filter":null},"#markers":{"opacity":0.8,"rescale":1,"filter":"url(#dropShadow05)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000aa"},"#urban":{"stroke":"#9d0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.9,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#779582"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":1,"stroke":"#8b4418","stroke-width":0.9,"stroke-dasharray":"2 3","stroke-linecap":"round","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#844017","stroke-width":0.2,"stroke-dasharray":".5 1","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#5e1865","stroke-width":0.6,"stroke-dasharray":"1.2 2.4","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.5,"data-width":12,"stroke-width":12,"filter":"blur(10px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":1,"font-size":"11px","fill":"#62001b","fill-opacity":0.3,"stroke":null,"stroke-width":2,"stroke-dasharray":2,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#emblems": {"opacity":0.6,"stroke-width":0.5,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.5,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":"url(#dropShadow01)","mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#4e6964"},"#oceanicPattern":{"href":"./images/pattern3.png", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"bright","terracing":0,"skip":0,"relax":1,"curve":1,"filter":"url(#filter-grayscale)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":2,"stroke":"#444444","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":0.8,"fill":"#ffffff","size":4,"stroke":"#3e3e4b","stroke-width":1},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":3,"font-size":3,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #towns":{"opacity":0.95,"fill":"#ffffff","fill-opacity":0.7,"size":0.8,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1.6,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#4e4e4e","stroke":"#b5b5b5","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#1b1423","filter":null}}`, + styleClean: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.5,"filter":"url(#blur7)","mask":"url(#land)"},"#stateBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.09,"filter":null,"mask":"url(#land)"},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":3,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eeedeb","filter":null},"#markers":{"opacity":null,"rescale":null,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0,"fill":"#0080ff","filter":null},"#population":{"opacity":null,"stroke-width":2.58,"stroke-dasharray":0,"stroke-linecap":"butt","filter":"url(#blur3)"},"#rural":{"stroke":"#ff0000"},"#urban":{"stroke":"#800000"},"#freshwater":{"opacity":0.5,"fill":"#aadaff","stroke":"#5f799d","stroke-width":0,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#595959","stroke-width":0.4,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#aadaff"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#f6d068","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#ffffff","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#4f82c6","stroke-width":0.45,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":"url(#water)"},"#statesBody":{"opacity":0.3,"filter":null},"#statesHalo":{"opacity":0.5,"data-width":1,"stroke-width":1,"filter":null},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow01)"},"#emblems":{"opacity":1,"stroke-width":1,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.7,"stroke":"#ff6262","stroke-width":0,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#aadaff"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":0.5,"scheme":"bright","terracing":0,"skip":5,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":12.74,"font-size":12.74,"data-font":"Arial","font-family":"Arial","stroke":"#909090","stroke-width":1.13,"stroke-dasharray":0,"stroke-linecap":"round","data-x":98.39,"data-y":12.67,"data-columns":null},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#414141","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#303030","stroke-width":1.7},"#burgLabels > #towns":{"opacity":1,"fill":"#414141","data-size":3,"font-size":3,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.06},"#labels > #states":{"opacity":1,"fill":"#292929","stroke":"#303030","stroke-width":0,"text-shadow":"white 0 0 2px","data-size":10,"font-size":10,"data-font":"Arial","font-family":"Arial","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#414141","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Arial","font-family":"Arial","filter":null},"#fogging":{"opacity":1,"fill":"#ffffff","filter":null}}`, + styleWatercolor: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.2,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.6,"filter":null,"mask":null},"#stateBorders":{"opacity":0.6,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":3,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.5,"stroke":"#56566d","stroke-width":0.5,"stroke-dasharray":"0 2","stroke-linecap":"round","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#777777","stroke-width":0,"filter":"url(#bluredSplotch)"},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":"url(#splotch)"},"#landmass":{"opacity":1,"fill":"#eef6fb","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":1,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":null,"set":"gray","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#2e89c2"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#969696","stroke-width":0.4,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.05,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":8,"stroke-width":8,"filter":"blur(2px)"},"#provs":{"opacity":0.7,"fill":"#000000","font-size":4,"data-font":"Comfortaa:700","font-family":"Comfortaa","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.7,"fill":"#dfe8ec","stroke":"#000000","stroke-width":0,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.95,"stroke-width":1,"filter":null},"#texture":{"opacity":0.2,"filter":null,"mask":"url(#land)"},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#2d788b"},"#oceanicPattern":{"href":"./images/kiwiroo.png","opacity":0.5},"#terrs":{"opacity":0.5,"scheme":"light","terracing":0,"skip":5,"relax":1,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#043449","text-shadow":"white 0px 0px 2px","data-size":5,"font-size":5,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":3,"font-size":3,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#ffffff","stroke":"#000000","stroke-width":0.15,"text-shadow":"black 1px 1px 2px","data-size":20,"font-size":20,"data-font":"Gloria+Hallelujah","font-family":"Gloria Hallelujah","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":18,"font-size":18,"data-font":"Comfortaa","font-family":"Comfortaa","filter":null},"#fogging":{"opacity":0.97,"fill":"#8398ce","filter":null}}`, + styleMonochrome: `{"#map":{"background-color":"#000000","filter":"url(#filter-grayscale)","data-filter":"grayscale"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":null},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.4,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#000000","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#000000","stroke":"#515151","stroke-width":0,"filter":null},"#salt":{"opacity":1,"fill":"#000000","stroke":"#484848","stroke-width":0,"filter":null},"#sinkhole":{"opacity":1,"fill":"#000000","stroke":"#5f5f5f","stroke-width":0.5,"filter":null},"#frozen":{"opacity":1,"fill":"#000000","stroke":"#6f6f6f","stroke-width":0,"filter":null},"#lava":{"opacity":1,"fill":"#000000","stroke":"#5d5d5d","stroke-width":0,"filter":null},"#sea_island":{"opacity":1,"stroke":"#1f3846","stroke-width":0,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":0.2,"filter":"url(#blur1)","fill":"#000000"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.7,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.25,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(5px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#texture":{"opacity":1,"filter":null,"mask":"url(#land)"},"#emblems": {"opacity": 0.5,"stroke-width": 0.5,"filter": null},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#000000"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"monochrome","terracing":0,"skip":5,"relax":0,"curve":0,"filter":"url(#blur3)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}` }; // apply default or custom style settings on load @@ -796,8 +816,7 @@ function applyDefaultStyle() { trails.attr("opacity", 0.9).attr("stroke", "#d06324").attr("stroke-width", 0.25).attr("stroke-dasharray", ".8 1.6").attr("stroke-linecap", "butt").attr("filter", null).attr("mask", null); searoutes.attr("opacity", 0.8).attr("stroke", "#ffffff").attr("stroke-width", 0.45).attr("stroke-dasharray", "1 2").attr("stroke-linecap", "round").attr("filter", null).attr("mask", null); - regions.attr("filter", null); - statesBody.attr("opacity", 0.4); + statesBody.attr("opacity", 0.4).attr("filter", null); statesHalo.attr("data-width", 10).attr("stroke-width", 10).attr("opacity", 0.4).attr("filter", "blur(5px)"); provs.attr("opacity", 0.7).attr("fill", "#000000").attr("font-family", "Georgia").attr("data-font", "Georgia").attr("data-size", 10).attr("font-size", 10).attr("filter", null); @@ -996,8 +1015,7 @@ function addStylePreset() { "#roads": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], "#trails": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], "#searoutes": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"], - "#regions": ["filter"], - "#statesBody": ["opacity"], + "#statesBody": ["opacity", "filter"], "#statesHalo": ["opacity", "data-width", "stroke-width", "filter"], "#provs": ["opacity", "fill", "font-size", "data-font", "font-family", "filter"], "#temperature": ["opacity", "font-size", "fill", "fill-opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"], From 0e9732e6ced7578ef4f8c2447b8b1f6bf734569a Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 10 Jul 2021 22:41:50 +0300 Subject: [PATCH 03/82] fix the issue with province that cannot be reassigned --- modules/ui/states-editor.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/ui/states-editor.js b/modules/ui/states-editor.js index 441b551e..45c74829 100644 --- a/modules/ui/states-editor.js +++ b/modules/ui/states-editor.js @@ -827,18 +827,15 @@ function editStates() { } function adjustProvinces(affectedProvinces) { - const cells = pack.cells, - provinces = pack.provinces, - states = pack.states; + const {cells, provinces, states} = pack; const form = {Zone: 1, Area: 1, Territory: 2, Province: 1}; affectedProvinces.forEach(p => { - // do nothing if neutral lands are captured - if (!p) return; + if (!p) return; // do nothing if neutral lands are captured + const old = provinces[p].state; // remove province from state provinces list - const old = provinces[p].state; - if (states[old].provinces.includes(p)) states[old].provinces.splice(states[old].provinces.indexOf(p), 1); + if (states[old]?.provinces?.includes(p)) states[old].provinces.splice(states[old].provinces.indexOf(p), 1); // find states owning at least 1 province cell const provCells = cells.i.filter(i => cells.province[i] === p); From 25de9edb13d44afc15f7c2030c44a3037142e3be Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 10 Jul 2021 22:49:35 +0300 Subject: [PATCH 04/82] fix select group issue --- modules/ui/style.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ui/style.js b/modules/ui/style.js index d25a7d4f..3d8e7954 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -52,8 +52,8 @@ function selectStyleElement() { // active group element const group = styleGroupSelect.value; if (["routes", "labels", "coastline", "lakes", "anchors", "burgIcons", "borders"].includes(sel)) { - const gEl = el.select("#" + group); - el = gEl.size() ? gEl : el.select("g"); + const gEl = group && el.select("#" + group); + el = group && gEl.size() ? gEl : el.select("g"); } // opacity From cfb6e1eeeb4d02fd3fe279dbce8aebe0be850cd4 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 00:29:58 +0300 Subject: [PATCH 05/82] load fonts on .map file open --- main.js | 2 +- modules/load.js | 9 +++++++++ modules/save.js | 30 +++++++++++++++++------------- modules/ui/states-editor.js | 2 +- modules/ui/style.js | 2 +- 5 files changed, 29 insertions(+), 16 deletions(-) diff --git a/main.js b/main.js index 93cc919b..f7346147 100644 --- a/main.js +++ b/main.js @@ -122,7 +122,7 @@ let customization = 0; // 0 - no; 1 = heightmap draw; 2 - states draw; 3 - add s let biomesData = applyDefaultBiomesSystem(); let nameBases = Names.getNameBases(); // cultures-related data -const fonts = ["Almendra+SC", "Georgia", "Arial", "Times+New+Roman", "Comic+Sans+MS", "Lucida+Sans+Unicode", "Courier+New"]; // default web-safe fonts +const fonts = ["Almendra+SC", "Georgia", "Arial", "Times+New+Roman", "Comic+Sans+MS", "Lucida+Sans+Unicode", "Courier+New", "Verdana", "Arial", "Impact"]; // default fonts let color = d3.scaleSequential(d3.interpolateSpectral); // default color scheme const lineGen = d3.line().curve(d3.curveBasis); // d3 line generator with default curve interpolation diff --git a/modules/load.js b/modules/load.js index 4308eceb..15c30438 100644 --- a/modules/load.js +++ b/modules/load.js @@ -220,6 +220,15 @@ function parseLoadedData(data) { burgLabels = labels.select("#burgLabels"); })(); + void (function loadUsedFonts() { + const fontsInUse = getFontsList(svg); + const fontsToLoad = fontsInUse.filter(font => !fonts.includes(font)); + if (fontsToLoad) { + const url = "https://fonts.googleapis.com/css?family=" + fontsToLoad.join("|"); + addFonts(url); + } + })(); + void (function parseGridData() { grid = JSON.parse(data[6]); calculateVoronoi(grid, grid.points); diff --git a/modules/save.js b/modules/save.js index 9b9d74c6..a7c5c687 100644 --- a/modules/save.js +++ b/modules/save.js @@ -269,8 +269,16 @@ async function getMapURL(type, subtype) { }); } - const fontStyle = await GFontToDataURI(getFontsToLoad(clone)); // load non-standard fonts - if (fontStyle) clone.select("defs").append("style").text(fontStyle.join("\n")); // add font to style + // load non-standard fonts + const usedFonts = getFontsList(clone); + const webSafe = ["Georgia", "Times+New+Roman", "Comic+Sans+MS", "Lucida+Sans+Unicode", "Courier+New", "Verdana", "Arial", "Impact"]; + const fontsToLoad = usedFonts.filter(font => !webSafe.includes(font)); + if (fontsToLoad.length) { + const url = "https://fonts.googleapis.com/css?family=" + fontsToLoad.join("|"); + const fontStyle = await GFontToDataURI(url); + if (fontStyle) clone.select("defs").append("style").text(fontStyle.join("\n")); + } + clone.remove(); const serialized = `` + new XMLSerializer().serializeToString(cloneEl); @@ -351,21 +359,17 @@ function inlineStyle(clone) { emptyG.remove(); } -// get non-standard fonts used for labels to fetch them from web -function getFontsToLoad(clone) { - const webSafe = ["Georgia", "Times+New+Roman", "Comic+Sans+MS", "Lucida+Sans+Unicode", "Courier+New", "Verdana", "Arial", "Impact"]; // fonts to not fetch +function getFontsList(svg) { + const fontsInUse = []; - const fontsInUse = new Set(); // to store fonts currently in use - clone.selectAll("#labels > g").each(function () { + svg.selectAll("#labels > g").each(function () { if (!this.hasChildNodes()) return; const font = this.dataset.font; - if (!font || webSafe.includes(font)) return; - fontsInUse.add(font); + if (font) fontsInUse.push(font); }); - const legendFont = legend.attr("data-font"); - if (legend.node().hasChildNodes() && !webSafe.includes(legendFont)) fontsInUse.add(legendFont); - const fonts = [...fontsInUse]; - return fonts.length ? "https://fonts.googleapis.com/css?family=" + fonts.join("|") : null; + if (legend.node().hasChildNodes()) fontsInUse.push(legend.attr("data-font")); + + return [...new Set(fontsInUse)]; } // code from Kaiido's answer https://stackoverflow.com/questions/42402584/how-to-use-google-fonts-in-canvas-when-drawing-dom-objects-in-svg diff --git a/modules/ui/states-editor.js b/modules/ui/states-editor.js index 45c74829..b7952453 100644 --- a/modules/ui/states-editor.js +++ b/modules/ui/states-editor.js @@ -846,7 +846,7 @@ function editStates() { if (owner) { const name = provinces[p].name; - // if province is historical part of abouther state province, unite with old province + // if province is a historical part of another state's province, unite with old province const part = states[owner].provinces.find(n => name.includes(provinces[n].name)); if (part) { provinces[p].removed = true; diff --git a/modules/ui/style.js b/modules/ui/style.js index 3d8e7954..59c8e659 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -1233,7 +1233,7 @@ function addFonts(url) { document.head.removeChild(s); return fetched; }) - .catch(function () {}); + .catch(err => ERROR && console.error(err)); } // Update font list for Label and Burg Editors From 805684f79e24f18e70c5c3da7cdaeaa6c04fc3cb Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 00:53:48 +0300 Subject: [PATCH 06/82] draw halo along water, but not map border --- modules/ui/layers.js | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/modules/ui/layers.js b/modules/ui/layers.js index ff490119..a643a22a 100644 --- a/modules/ui/layers.js +++ b/modules/ui/layers.js @@ -890,10 +890,6 @@ function drawStates() { const gap = new Array(states.length).fill(""); // path along water for each state to fill the gaps const halo = new Array(states.length).fill(""); // path around states, but not lakes - // helper functions - const isLand = i => i[1] === "land"; - const nextIsLand = (ar, i) => ar[i + 1]?.[1] === "land"; - const prevIsLand = (ar, i) => ar[i - 1]?.[1] === "land"; const getStringPoint = v => vertices.p[v[0]].join(","); // define inner-state lakes to omit on border render @@ -909,37 +905,34 @@ function drawStates() { if (!cells.state[i] || used[i]) continue; const state = cells.state[i]; - // if (state !== 5) continue; - const onborder = cells.c[i].some(n => cells.state[n] !== state); if (!onborder) continue; const borderWith = cells.c[i].map(c => cells.state[c]).find(n => n !== state); const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.state[i] === borderWith)); const chain = connectVertices(vertex, state); - if (chain.length < 3) continue; - // get path around state - const points = chain.filter(v => v[1] !== "innerLake").map(v => vertices.p[v[0]]); + const noInnerLakes = chain.filter(v => v[1] !== "innerLake"); + if (noInnerLakes.length < 3) continue; + + // get path around the state if (!vArray[state]) vArray[state] = []; - - if (points.length) { - vArray[state].push(points); - body[state] += "M" + points.join("L"); - } + const points = noInnerLakes.map(v => vertices.p[v[0]]); + vArray[state].push(points); + body[state] += "M" + points.join("L"); // connect path for halo let discontinued = true; - halo[state] += chain - .map((v, i) => { - if (isLand(v) || nextIsLand(chain, i) || prevIsLand(chain, i)) { - const operation = discontinued ? "M" : "L"; - discontinued = false; - return `${operation}${getStringPoint(v)}`; + halo[state] += noInnerLakes + .map(v => { + if (v[1] === "border") { + discontinued = true; + return ""; } - discontinued = true; - return ""; + const operation = discontinued ? "M" : "L"; + discontinued = false; + return `${operation}${getStringPoint(v)}`; }) .join(""); @@ -947,7 +940,7 @@ function drawStates() { discontinued = true; gap[state] += chain .map(v => { - if (isLand(v)) { + if (v[1] === "land") { discontinued = true; return ""; } @@ -982,6 +975,9 @@ function drawStates() { function connectVertices(start, state) { const chain = []; // vertices chain to form a path const getType = c => { + const borderCell = c.find(i => cells.b[i]); + if (borderCell) return "border"; + const waterCell = c.find(i => cells.h[i] < 20); if (!waterCell) return "land"; if (innerLakes[cells.f[waterCell]]) return "innerLake"; From c8eccfb0e767f97f4380ac614410a5287d0e2f57 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 01:18:39 +0300 Subject: [PATCH 07/82] more state types --- index.html | 8 + modules/burgs-and-states.js | 676 +++++++++++++++++++++--------------- 2 files changed, 413 insertions(+), 271 deletions(-) diff --git a/index.html b/index.html index 7d851b89..3721ff6b 100644 --- a/index.html +++ b/index.html @@ -2537,6 +2537,7 @@ + @@ -2559,10 +2560,17 @@ + + + + + + + diff --git a/modules/burgs-and-states.js b/modules/burgs-and-states.js index 5524e81d..78054d1c 100644 --- a/modules/burgs-and-states.js +++ b/modules/burgs-and-states.js @@ -1,17 +1,18 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.BurgsAndStates = factory()); -}(this, (function () { 'use strict'; + typeof exports === "object" && typeof module !== "undefined" ? (module.exports = factory()) : typeof define === "function" && define.amd ? define(factory) : (global.BurgsAndStates = factory()); +})(this, function () { + "use strict"; - const generate = function() { - const cells = pack.cells, cultures = pack.cultures, n = cells.i.length; + const generate = function () { + const cells = pack.cells, + cultures = pack.cultures, + n = cells.i.length; cells.burg = new Uint16Array(n); // cell burg cells.road = new Uint16Array(n); // cell road power cells.crossroad = new Uint16Array(n); // cell crossroad power - const burgs = pack.burgs = placeCapitals(); + const burgs = (pack.burgs = placeCapitals()); pack.states = createStates(); const capitalRoutes = Routes.getRoads(); @@ -32,7 +33,7 @@ drawBurgs(); function placeCapitals() { - TIME && console.time('placeCapitals'); + TIME && console.time("placeCapitals"); let count = +regionsInput.value; let burgs = [0]; @@ -41,15 +42,21 @@ if (sorted.length < count * 10) { count = Math.floor(sorted.length / 10); - if (!count) {WARN && console.warn(`There is no populated cells. Cannot generate states`); return burgs;} - else {WARN && console.warn(`Not enough populated cells (${sorted.length}). Will generate only ${count} states`);} + if (!count) { + WARN && console.warn(`There is no populated cells. Cannot generate states`); + return burgs; + } else { + WARN && console.warn(`Not enough populated cells (${sorted.length}). Will generate only ${count} states`); + } } let burgsTree = d3.quadtree(); let spacing = (graphWidth + graphHeight) / 2 / count; // min distance between capitals - for (let i=0; burgs.length <= count; i++) { - const cell = sorted[i], x = cells.p[cell][0], y = cells.p[cell][1]; + for (let i = 0; burgs.length <= count; i++) { + const cell = sorted[i], + x = cells.p[cell][0], + y = cells.p[cell][1]; if (burgsTree.find(x, y, spacing) === undefined) { burgs.push({cell, x, y}); @@ -59,22 +66,22 @@ if (i === sorted.length - 1) { WARN && console.warn("Cannot place capitals with current spacing. Trying again with reduced spacing"); burgsTree = d3.quadtree(); - i = -1, burgs = [0], spacing /= 1.2; + (i = -1), (burgs = [0]), (spacing /= 1.2); } } burgs[0] = burgsTree; - TIME && console.timeEnd('placeCapitals'); + TIME && console.timeEnd("placeCapitals"); return burgs; } // For each capital create a state function createStates() { - TIME && console.time('createStates'); - const states = [{i:0, name: "Neutrals"}]; - const colors = getColors(burgs.length-1); + TIME && console.time("createStates"); + const states = [{i: 0, name: "Neutrals"}]; + const colors = getColors(burgs.length - 1); - burgs.forEach(function(b, i) { + burgs.forEach(function (b, i) { if (!i) return; // skip first element // burgs data @@ -86,63 +93,68 @@ // states data const expansionism = rn(Math.random() * powerInput.value + 1, 1); - const basename = b.name.length < 9 && b.cell%5 === 0 ? b.name : Names.getCultureShort(b.culture); + const basename = b.name.length < 9 && b.cell % 5 === 0 ? b.name : Names.getCultureShort(b.culture); const name = Names.getState(basename, b.culture); const type = cultures[b.culture].type; const coa = COA.generate(null, null, null, type); coa.shield = COA.getShield(b.culture, null); - states.push({i, color: colors[i-1], name, expansionism, capital: i, type, center: b.cell, culture: b.culture, coa}); + states.push({i, color: colors[i - 1], name, expansionism, capital: i, type, center: b.cell, culture: b.culture, coa}); cells.burg[b.cell] = i; }); - TIME && console.timeEnd('createStates'); + TIME && console.timeEnd("createStates"); return states; } // place secondary settlements based on geo and economical evaluation function placeTowns() { - TIME && console.time('placeTowns'); - const score = new Int16Array(cells.s.map(s => s * gauss(1,3,0,20,3))); // a bit randomized cell score for towns placement + TIME && console.time("placeTowns"); + const score = new Int16Array(cells.s.map(s => s * gauss(1, 3, 0, 20, 3))); // a bit randomized cell score for towns placement const sorted = cells.i.filter(i => !cells.burg[i] && score[i] > 0 && cells.culture[i]).sort((a, b) => score[b] - score[a]); // filtered and sorted array of indexes - const desiredNumber = manorsInput.value == 1000 ? rn(sorted.length / 5 / (grid.points.length / 10000) ** .8) : manorsInput.valueAsNumber; + const desiredNumber = manorsInput.value == 1000 ? rn(sorted.length / 5 / (grid.points.length / 10000) ** 0.8) : manorsInput.valueAsNumber; const burgsNumber = Math.min(desiredNumber, sorted.length); // towns to generate let burgsAdded = 0; const burgsTree = burgs[0]; - let spacing = (graphWidth + graphHeight) / 150 / (burgsNumber ** .7 / 66); // min distance between towns + let spacing = (graphWidth + graphHeight) / 150 / (burgsNumber ** 0.7 / 66); // min distance between towns while (burgsAdded < burgsNumber && spacing > 1) { - for (let i=0; burgsAdded < burgsNumber && i < sorted.length; i++) { + for (let i = 0; burgsAdded < burgsNumber && i < sorted.length; i++) { if (cells.burg[sorted[i]]) continue; - const cell = sorted[i], x = cells.p[cell][0], y = cells.p[cell][1]; - const s = spacing * gauss(1, .3, .2, 2, 2); // randomize to make placement not uniform + const cell = sorted[i], + x = cells.p[cell][0], + y = cells.p[cell][1]; + const s = spacing * gauss(1, 0.3, 0.2, 2, 2); // randomize to make placement not uniform if (burgsTree.find(x, y, s) !== undefined) continue; // to close to existing burg const burg = burgs.length; const culture = cells.culture[cell]; const name = Names.getCulture(culture); - burgs.push({cell, x, y, state: 0, i: burg, culture, name, capital: 0, feature:cells.f[cell]}); + burgs.push({cell, x, y, state: 0, i: burg, culture, name, capital: 0, feature: cells.f[cell]}); burgsTree.add([x, y]); cells.burg[cell] = burg; burgsAdded++; } - spacing *= .5; + spacing *= 0.5; } if (manorsInput.value != 1000 && burgsAdded < desiredNumber) { ERROR && console.error(`Cannot place all burgs. Requested ${desiredNumber}, placed ${burgsAdded}`); } - burgs[0] = {name:undefined}; // do not store burgsTree anymore - TIME && console.timeEnd('placeTowns'); + burgs[0] = {name: undefined}; // do not store burgsTree anymore + TIME && console.timeEnd("placeTowns"); } - } + }; // define burg coordinates, coa, port status and define details - const specifyBurgs = function() { + const specifyBurgs = function () { TIME && console.time("specifyBurgs"); - const cells = pack.cells, vertices = pack.vertices, features = pack.features, temp = grid.cells.temp; + const cells = pack.cells, + vertices = pack.vertices, + features = pack.features, + temp = grid.cells.temp; for (const b of pack.burgs) { if (!b.i || b.lock) continue; @@ -158,7 +170,7 @@ } else b.port = 0; // define burg population (keep urbanization at about 10% rate) - b.population = rn(Math.max((cells.s[i] + cells.road[i] / 2) / 8 + b.i / 1000 + i % 100 / 1000, .1), 3); + b.population = rn(Math.max((cells.s[i] + cells.road[i] / 2) / 8 + b.i / 1000 + (i % 100) / 1000, 0.1), 3); if (b.capital) b.population = rn(b.population * 1.3, 3); // increase capital population if (b.port) { @@ -169,24 +181,26 @@ } // add random factor - b.population = rn(b.population * gauss(2,3,.6,20,3), 3); + b.population = rn(b.population * gauss(2, 3, 0.6, 20, 3), 3); // shift burgs on rivers semi-randomly and just a bit if (!b.port && cells.r[i]) { - const shift = Math.min(cells.fl[i]/150, 1); - if (i%2) b.x = rn(b.x + shift, 2); else b.x = rn(b.x - shift, 2); - if (cells.r[i]%2) b.y = rn(b.y + shift, 2); else b.y = rn(b.y - shift, 2); + const shift = Math.min(cells.fl[i] / 150, 1); + if (i % 2) b.x = rn(b.x + shift, 2); + else b.x = rn(b.x - shift, 2); + if (cells.r[i] % 2) b.y = rn(b.y + shift, 2); + else b.y = rn(b.y - shift, 2); } // define emblem const state = pack.states[b.state]; const stateCOA = state.coa; - let kinship = .25; - if (b.capital) kinship += .1; - else if (b.port) kinship -= .1; - if (b.culture !== state.culture) kinship -= .25; + let kinship = 0.25; + if (b.capital) kinship += 0.1; + else if (b.port) kinship -= 0.1; + if (b.culture !== state.culture) kinship -= 0.25; b.type = getType(i, b.port); - const type = b.capital && P(.2) ? "Capital" : b.type === "Generic" ? "City" : b.type; + const type = b.capital && P(0.2) ? "Capital" : b.type === "Generic" ? "City" : b.type; b.coa = COA.generate(stateCOA, kinship, null, type); b.coa.shield = COA.getShield(b.culture, b.state); } @@ -200,9 +214,9 @@ } TIME && console.timeEnd("specifyBurgs"); - } + }; - const getType = function(i, port) { + const getType = function (i, port) { const cells = pack.cells; if (port) return "Naval"; if (cells.haven[i] && pack.features[cells.f[cells.haven[i]]].type === "lake") return "Lake"; @@ -215,23 +229,25 @@ } return "Generic"; - } + }; - const defineBurgFeatures = function(newburg) { + const defineBurgFeatures = function (newburg) { const cells = pack.cells; - pack.burgs.filter(b => newburg ? b.i == newburg.i : (b.i && !b.removed)).forEach(b => { - const pop = b.population; - b.citadel = b.capital || pop > 50 && P(.75) || P(.5) ? 1 : 0; - b.plaza = pop > 50 || pop > 30 && P(.75) || pop > 10 && P(.5) || P(.25) ? 1 : 0; - b.walls = b.capital || pop > 30 || pop > 20 && P(.75) || pop > 10 && P(.5) || P(.2) ? 1 : 0; - b.shanty = pop > 30 || pop > 20 && P(.75) || b.walls && P(.75) ? 1 : 0; - const religion = cells.religion[b.cell]; - const theocracy = pack.states[b.state].form === "Theocracy"; - b.temple = religion && theocracy || pop > 50 || pop > 35 && P(.75) || pop > 20 && P(.5) ? 1 : 0; - }); - } + pack.burgs + .filter(b => (newburg ? b.i == newburg.i : b.i && !b.removed)) + .forEach(b => { + const pop = b.population; + b.citadel = b.capital || (pop > 50 && P(0.75)) || P(0.5) ? 1 : 0; + b.plaza = pop > 50 || (pop > 30 && P(0.75)) || (pop > 10 && P(0.5)) || P(0.25) ? 1 : 0; + b.walls = b.capital || pop > 30 || (pop > 20 && P(0.75)) || (pop > 10 && P(0.5)) || P(0.2) ? 1 : 0; + b.shanty = pop > 30 || (pop > 20 && P(0.75)) || (b.walls && P(0.75)) ? 1 : 0; + const religion = cells.religion[b.cell]; + const theocracy = pack.states[b.state].form === "Theocracy"; + b.temple = (religion && theocracy) || pop > 50 || (pop > 35 && P(0.75)) || (pop > 20 && P(0.5)) ? 1 : 0; + }); + }; - const drawBurgs = function() { + const drawBurgs = function () { TIME && console.time("drawBurgs"); // remove old data @@ -247,18 +263,40 @@ const capitalAnchors = anchors.selectAll("#cities"); const caSize = capitalAnchors.attr("size") || 2; - capitalIcons.selectAll("circle").data(capitals).enter() - .append("circle").attr("id", d => "burg"+d.i).attr("data-id", d => d.i) - .attr("cx", d => d.x).attr("cy", d => d.y).attr("r", capitalSize); + capitalIcons + .selectAll("circle") + .data(capitals) + .enter() + .append("circle") + .attr("id", d => "burg" + d.i) + .attr("data-id", d => d.i) + .attr("cx", d => d.x) + .attr("cy", d => d.y) + .attr("r", capitalSize); - capitalLabels.selectAll("text").data(capitals).enter() - .append("text").attr("id", d => "burgLabel"+d.i).attr("data-id", d => d.i) - .attr("x", d => d.x).attr("y", d => d.y).attr("dy", `${capitalSize * -1.5}px`).text(d => d.name); + capitalLabels + .selectAll("text") + .data(capitals) + .enter() + .append("text") + .attr("id", d => "burgLabel" + d.i) + .attr("data-id", d => d.i) + .attr("x", d => d.x) + .attr("y", d => d.y) + .attr("dy", `${capitalSize * -1.5}px`) + .text(d => d.name); - capitalAnchors.selectAll("use").data(capitals.filter(c => c.port)).enter() - .append("use").attr("xlink:href", "#icon-anchor").attr("data-id", d => d.i) - .attr("x", d => rn(d.x - caSize * .47, 2)).attr("y", d => rn(d.y - caSize * .47, 2)) - .attr("width", caSize).attr("height", caSize); + capitalAnchors + .selectAll("use") + .data(capitals.filter(c => c.port)) + .enter() + .append("use") + .attr("xlink:href", "#icon-anchor") + .attr("data-id", d => d.i) + .attr("x", d => rn(d.x - caSize * 0.47, 2)) + .attr("y", d => rn(d.y - caSize * 0.47, 2)) + .attr("width", caSize) + .attr("height", caSize); // towns const towns = pack.burgs.filter(b => b.i && !b.capital); @@ -268,40 +306,64 @@ const townsAnchors = anchors.selectAll("#towns"); const taSize = townsAnchors.attr("size") || 1; - townIcons.selectAll("circle").data(towns).enter() - .append("circle").attr("id", d => "burg"+d.i).attr("data-id", d => d.i) - .attr("cx", d => d.x).attr("cy", d => d.y).attr("r", townSize); + townIcons + .selectAll("circle") + .data(towns) + .enter() + .append("circle") + .attr("id", d => "burg" + d.i) + .attr("data-id", d => d.i) + .attr("cx", d => d.x) + .attr("cy", d => d.y) + .attr("r", townSize); - townLabels.selectAll("text").data(towns).enter() - .append("text").attr("id", d => "burgLabel"+d.i).attr("data-id", d => d.i) - .attr("x", d => d.x).attr("y", d => d.y).attr("dy", `${townSize * -1.5}px`).text(d => d.name); + townLabels + .selectAll("text") + .data(towns) + .enter() + .append("text") + .attr("id", d => "burgLabel" + d.i) + .attr("data-id", d => d.i) + .attr("x", d => d.x) + .attr("y", d => d.y) + .attr("dy", `${townSize * -1.5}px`) + .text(d => d.name); - townsAnchors.selectAll("use").data(towns.filter(c => c.port)).enter() - .append("use").attr("xlink:href", "#icon-anchor").attr("data-id", d => d.i) - .attr("x", d => rn(d.x - taSize * .47, 2)).attr("y", d => rn(d.y - taSize * .47, 2)) - .attr("width", taSize).attr("height", taSize); + townsAnchors + .selectAll("use") + .data(towns.filter(c => c.port)) + .enter() + .append("use") + .attr("xlink:href", "#icon-anchor") + .attr("data-id", d => d.i) + .attr("x", d => rn(d.x - taSize * 0.47, 2)) + .attr("y", d => rn(d.y - taSize * 0.47, 2)) + .attr("width", taSize) + .attr("height", taSize); TIME && console.timeEnd("drawBurgs"); - } + }; // growth algorithm to assign cells to states like we did for cultures - const expandStates = function() { + const expandStates = function () { TIME && console.time("expandStates"); const {cells, states, cultures, burgs} = pack; cells.state = new Uint16Array(cells.i.length); const queue = new PriorityQueue({comparator: (a, b) => a.p - b.p}); const cost = []; - const neutral = cells.i.length / 5000 * 2500 * neutralInput.value * statesNeutral.value; // limit cost for state growth + const neutral = (cells.i.length / 5000) * 2500 * neutralInput.value * statesNeutral.value; // limit cost for state growth - states.filter(s => s.i && !s.removed).forEach(s => { - const capitalCell = burgs[s.capital].cell; - cells.state[capitalCell] = s.i; - const cultureCenter = cultures[s.culture].center; - const b = cells.biome[cultureCenter]; // state native biome - queue.queue({e:s.center, p:0, s:s.i, b}); - cost[s.center] = 1; - }); + states + .filter(s => s.i && !s.removed) + .forEach(s => { + const capitalCell = burgs[s.capital].cell; + cells.state[capitalCell] = s.i; + const cultureCenter = cultures[s.culture].center; + const b = cells.biome[cultureCenter]; // state native biome + queue.queue({e: s.center, p: 0, s: s.i, b}); + cost[s.center] = 1; + }); while (queue.length) { const next = queue.dequeue(); @@ -325,12 +387,12 @@ if (!cost[e] || totalCost < cost[e]) { if (cells.h[e] >= 20) cells.state[e] = s; // assign state to cell cost[e] = totalCost; - queue.queue({e, p:totalCost, s, b}); + queue.queue({e, p: totalCost, s, b}); } }); } - burgs.filter(b => b.i && !b.removed).forEach(b => b.state = cells.state[b.cell]); // assign state to burgs + burgs.filter(b => b.i && !b.removed).forEach(b => (b.state = cells.state[b.cell])); // assign state to burgs function getBiomeCost(b, biome, type) { if (b === biome) return 10; // tiny penalty for native biome @@ -354,7 +416,7 @@ function getRiverCost(r, i, type) { if (type === "River") return r ? 0 : 100; // penalty for river cultures if (!r) return 0; // no penalty for others if there is no river - return Math.min(Math.max(cells.fl[i] / 10, 20), 100) // river penalty from 20 to 100 based on flux + return Math.min(Math.max(cells.fl[i] / 10, 20), 100); // river penalty from 20 to 100 based on flux } function getTypeCost(t, type) { @@ -365,11 +427,12 @@ } TIME && console.timeEnd("expandStates"); - } + }; - const normalizeStates = function() { + const normalizeStates = function () { TIME && console.time("normalizeStates"); - const cells = pack.cells, burgs = pack.burgs; + const cells = pack.cells, + burgs = pack.burgs; for (const i of cells.i) { if (cells.h[i] < 20 || cells.burg[i]) continue; // do not overwrite burgs @@ -383,38 +446,40 @@ cells.state[i] = cells.state[adversaries[0]]; } TIME && console.timeEnd("normalizeStates"); - } + }; // Resets the cultures of all burgs and states to their // cell or center cell's (respectively) culture. const updateCultures = function () { - TIME && console.time('updateCulturesForBurgsAndStates'); + TIME && console.time("updateCulturesForBurgsAndStates"); // Assign the culture associated with the burgs cell. - pack.burgs = pack.burgs.map( (burg, index) => { + pack.burgs = pack.burgs.map((burg, index) => { // Ignore metadata burg - if(index === 0) { + if (index === 0) { return burg; } return {...burg, culture: pack.cells.culture[burg.cell]}; }); // Assign the culture associated with the states' center cell. - pack.states = pack.states.map( (state, index) => { + pack.states = pack.states.map((state, index) => { // Ignore neutrals state - if(index === 0) { + if (index === 0) { return state; } return {...state, culture: pack.cells.culture[state.center]}; }); - TIME && console.timeEnd('updateCulturesForBurgsAndStates'); - } + TIME && console.timeEnd("updateCulturesForBurgsAndStates"); + }; // calculate and draw curved state labels for a list of states - const drawStateLabels = function(list) { + const drawStateLabels = function (list) { TIME && console.time("drawStateLabels"); - const cells = pack.cells, features = pack.features, states = pack.states; + const cells = pack.cells, + features = pack.features, + states = pack.states; const paths = []; // text paths lineGen.curve(d3.curveBundle.beta(1)); @@ -428,22 +493,29 @@ const delaunay = Delaunator.from(points); const voronoi = new Voronoi(delaunay, points, points.length); const chain = connectCenters(voronoi.vertices, s.pole[1]); - const relaxed = chain.map(i => voronoi.vertices.p[i]).filter((p, i) => i%15 === 0 || i+1 === chain.length); + const relaxed = chain.map(i => voronoi.vertices.p[i]).filter((p, i) => i % 15 === 0 || i + 1 === chain.length); paths.push([s.i, relaxed]); function getHull(start, state, maxLake) { - const queue = [start], hull = new Set(); + const queue = [start], + hull = new Set(); while (queue.length) { const q = queue.pop(); const nQ = cells.c[q].filter(c => cells.state[c] === state); - cells.c[q].forEach(function(c, d) { + cells.c[q].forEach(function (c, d) { const passableLake = features[cells.f[c]].type === "lake" && features[cells.f[c]].cells < maxLake; - if (cells.b[c] || (cells.state[c] !== state && !passableLake)) {hull.add(cells.v[q][d]); return;} + if (cells.b[c] || (cells.state[c] !== state && !passableLake)) { + hull.add(cells.v[q][d]); + return; + } const nC = cells.c[c].filter(n => cells.state[n] === state); - const intersected = common(nQ, nC).length - if (hull.size > 20 && !intersected && !passableLake) {hull.add(cells.v[q][d]); return;} + const intersected = common(nQ, nC).length; + if (hull.size > 20 && !intersected && !passableLake) { + hull.add(cells.v[q][d]); + return; + } if (used[c]) return; used[c] = 1; queue.push(c); @@ -455,24 +527,27 @@ function connectCenters(c, y) { // check if vertex is inside the area - const inside = c.p.map(function(p) { + const inside = c.p.map(function (p) { if (p[0] <= 0 || p[1] <= 0 || p[0] >= graphWidth || p[1] >= graphHeight) return false; // out of the screen return used[findCell(p[0], p[1])]; }); const pointsInside = d3.range(c.p.length).filter(i => inside[i]); if (!pointsInside.length) return [0]; - const h = c.p.length < 200 ? 0 : c.p.length < 600 ? .5 : 1; // power of horyzontality shift - const end = pointsInside[d3.scan(pointsInside, (a, b) => (c.p[a][0] - c.p[b][0]) + (Math.abs(c.p[a][1] - y) - Math.abs(c.p[b][1] - y)) * h)]; // left point - const start = pointsInside[d3.scan(pointsInside, (a, b) => (c.p[b][0] - c.p[a][0]) - (Math.abs(c.p[b][1] - y) - Math.abs(c.p[a][1] - y)) * h)]; // right point + const h = c.p.length < 200 ? 0 : c.p.length < 600 ? 0.5 : 1; // power of horyzontality shift + const end = pointsInside[d3.scan(pointsInside, (a, b) => c.p[a][0] - c.p[b][0] + (Math.abs(c.p[a][1] - y) - Math.abs(c.p[b][1] - y)) * h)]; // left point + const start = pointsInside[d3.scan(pointsInside, (a, b) => c.p[b][0] - c.p[a][0] - (Math.abs(c.p[b][1] - y) - Math.abs(c.p[a][1] - y)) * h)]; // right point // connect leftmost and rightmost points with shortest path const queue = new PriorityQueue({comparator: (a, b) => a.p - b.p}); - const cost = [], from = []; + const cost = [], + from = []; queue.queue({e: start, p: 0}); while (queue.length) { - const next = queue.dequeue(), n = next.e, p = next.p; + const next = queue.dequeue(), + n = next.e, + p = next.p; if (n === end) break; for (const v of c.v[n]) { @@ -494,11 +569,11 @@ } return chain; } - } - void function drawLabels() { - const g = labels.select("#states"), t = defs.select("#textPaths"); + void (function drawLabels() { + const g = labels.select("#states"), + t = defs.select("#textPaths"); const displayed = layerIsOn("toggleLabels"); if (!displayed) toggleLabels(); @@ -516,58 +591,70 @@ const s = states[p[0]]; if (list) { - t.select("#textPath_stateLabel"+id).remove(); - g.select("#stateLabel"+id).remove(); + t.select("#textPath_stateLabel" + id).remove(); + g.select("#stateLabel" + id).remove(); } - const path = p[1].length > 1 ? lineGen(p[1]) : `M${p[1][0][0]-50},${p[1][0][1]}h${100}`; - const textPath = t.append("path").attr("d", path).attr("id", "textPath_stateLabel"+id); + const path = p[1].length > 1 ? lineGen(p[1]) : `M${p[1][0][0] - 50},${p[1][0][1]}h${100}`; + const textPath = t + .append("path") + .attr("d", path) + .attr("id", "textPath_stateLabel" + id); const pathLength = p[1].length > 1 ? textPath.node().getTotalLength() / letterLength : 0; // path length in letters - let lines = [], ratio = 100; + let lines = [], + ratio = 100; if (pathLength < s.name.length) { // only short name will fit lines = splitInTwo(s.name); - ratio = Math.max(Math.min(rn(pathLength / lines[0].length * 60), 150), 50); + ratio = Math.max(Math.min(rn((pathLength / lines[0].length) * 60), 150), 50); } else if (pathLength > s.fullName.length * 2.5) { // full name will fit in one line lines = [s.fullName]; - ratio = Math.max(Math.min(rn(pathLength / lines[0].length * 70), 170), 70); + ratio = Math.max(Math.min(rn((pathLength / lines[0].length) * 70), 170), 70); } else { // try miltilined label lines = splitInTwo(s.fullName); - ratio = Math.max(Math.min(rn(pathLength / lines[0].length * 60), 150), 70); + ratio = Math.max(Math.min(rn((pathLength / lines[0].length) * 60), 150), 70); } // prolongate path if it's too short if (pathLength && pathLength < lines[0].length) { const points = p[1]; - const f = points[0], l = points[points.length-1]; - const dx = l[0] - f[0], dy = l[1] - f[1]; - const mod = Math.abs(letterLength * lines[0].length / dx) / 2; + const f = points[0], + l = points[points.length - 1]; + const dx = l[0] - f[0], + dy = l[1] - f[1]; + const mod = Math.abs((letterLength * lines[0].length) / dx) / 2; points[0] = [rn(f[0] - dx * mod), rn(f[1] - dy * mod)]; - points[points.length-1] = [rn(l[0] + dx * mod), rn(l[1] + dy * mod)]; + points[points.length - 1] = [rn(l[0] + dx * mod), rn(l[1] + dy * mod)]; textPath.attr("d", round(lineGen(points))); } - example.attr("font-size", ratio+"%"); + example.attr("font-size", ratio + "%"); const top = (lines.length - 1) / -2; // y offset const spans = lines.map((l, d) => { example.text(l); const left = example.node().getBBox().width / -2; // x offset - return `${l}`; + return `${l}`; }); - const el = g.append("text").attr("id", "stateLabel"+id) - .append("textPath").attr("xlink:href", "#textPath_stateLabel"+id) - .attr("startOffset", "50%").attr("font-size", ratio+"%").node(); + const el = g + .append("text") + .attr("id", "stateLabel" + id) + .append("textPath") + .attr("xlink:href", "#textPath_stateLabel" + id) + .attr("startOffset", "50%") + .attr("font-size", ratio + "%") + .node(); el.insertAdjacentHTML("afterbegin", spans.join("")); if (lines.length < 2) return; // check whether multilined label is generally inside the state. If no, replace with short name label - const cs = pack.cells.state, b = el.parentNode.getBBox(); + const cs = pack.cells.state, + b = el.parentNode.getBBox(); const c1 = () => +cs[findCell(b.x, b.y)] === id; const c2 = () => +cs[findCell(b.x + b.width / 2, b.y)] === id; const c3 = () => +cs[findCell(b.x + b.width, b.y)] === id; @@ -581,21 +668,22 @@ example.text(name); const left = example.node().getBBox().width / -2; // x offset el.innerHTML = `${name}`; - ratio = Math.max(Math.min(rn(pathLength / name.length * 60), 130), 40); - el.setAttribute("font-size", ratio+"%"); + ratio = Math.max(Math.min(rn((pathLength / name.length) * 60), 130), 40); + el.setAttribute("font-size", ratio + "%"); }); example.remove(); if (!displayed) toggleLabels(); - }() + })(); TIME && console.timeEnd("drawStateLabels"); - } + }; // calculate states data like area, population etc. - const collectStatistics = function() { + const collectStatistics = function () { TIME && console.time("collectStatistics"); - const cells = pack.cells, states = pack.states; + const cells = pack.cells, + states = pack.states; states.forEach(s => { if (s.removed) return; s.cells = s.area = s.burgs = s.rural = s.urban = 0; @@ -626,9 +714,9 @@ }); TIME && console.timeEnd("collectStatistics"); - } + }; - const assignColors = function() { + const assignColors = function () { TIME && console.time("assignColors"); const colors = ["#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854", "#ffd92f"]; // d3.schemeSet2; @@ -651,53 +739,56 @@ }); TIME && console.timeEnd("assignColors"); - } + }; // generate historical conflicts of each state - const generateCampaigns = function() { - const wars = {"War":6, "Conflict":2, "Campaign":4, "Invasion":2, "Rebellion":2, "Conquest":2, "Intervention":1, "Expedition":1, "Crusade":1}; + const generateCampaigns = function () { + const wars = {War: 6, Conflict: 2, Campaign: 4, Invasion: 2, Rebellion: 2, Conquest: 2, Intervention: 1, Expedition: 1, Crusade: 1}; pack.states.forEach(s => { if (!s.i || s.removed) return; const n = s.neighbors.length ? s.neighbors : [0]; - s.campaigns = n.map(i => { - const name = i && P(.8) ? pack.states[i].name : Names.getCultureShort(s.culture); - const start = gauss(options.year-100, 150, 1, options.year-6); - const end = start + gauss(4, 5, 1, options.year - start - 1); - return {name:getAdjective(name) + " " + rw(wars), start, end}; - }).sort((a, b) => a.start - b.start); + s.campaigns = n + .map(i => { + const name = i && P(0.8) ? pack.states[i].name : Names.getCultureShort(s.culture); + const start = gauss(options.year - 100, 150, 1, options.year - 6); + const end = start + gauss(4, 5, 1, options.year - start - 1); + return {name: getAdjective(name) + " " + rw(wars), start, end}; + }) + .sort((a, b) => a.start - b.start); }); - } + }; // generate Diplomatic Relationships - const generateDiplomacy = function() { + const generateDiplomacy = function () { TIME && console.time("generateDiplomacy"); - const cells = pack.cells, states = pack.states; - const chronicle = states[0].diplomacy = []; + const cells = pack.cells, + states = pack.states; + const chronicle = (states[0].diplomacy = []); const valid = states.filter(s => s.i && !states.removed); - const neibs = {"Ally":1, "Friendly":2, "Neutral":1, "Suspicion":10, "Rival":9}; // relations to neighbors - const neibsOfNeibs = {"Ally":10, "Friendly":8, "Neutral":5, "Suspicion":1}; // relations to neighbors of neighbors - const far = {"Friendly":1, "Neutral":12, "Suspicion":2, "Unknown":6}; // relations to other - const navals = {"Neutral":1, "Suspicion":2, "Rival":1, "Unknown":1}; // relations of naval powers + const neibs = {Ally: 1, Friendly: 2, Neutral: 1, Suspicion: 10, Rival: 9}; // relations to neighbors + const neibsOfNeibs = {Ally: 10, Friendly: 8, Neutral: 5, Suspicion: 1}; // relations to neighbors of neighbors + const far = {Friendly: 1, Neutral: 12, Suspicion: 2, Unknown: 6}; // relations to other + const navals = {Neutral: 1, Suspicion: 2, Rival: 1, Unknown: 1}; // relations of naval powers - valid.forEach(s => s.diplomacy = new Array(states.length).fill("x")); // clear all relationships + valid.forEach(s => (s.diplomacy = new Array(states.length).fill("x"))); // clear all relationships if (valid.length < 2) return; // no states to renerate relations with const areaMean = d3.mean(valid.map(s => s.area)); // avarage state area // generic relations - for (let f=1; f < states.length; f++) { + for (let f = 1; f < states.length; f++) { if (states[f].removed) continue; if (states[f].diplomacy.includes("Vassal")) { // Vassals copy relations from their Suzerains const suzerain = states[f].diplomacy.indexOf("Vassal"); - for (let i=1; i < states.length; i++) { + for (let i = 1; i < states.length; i++) { if (i === f || i === suzerain) continue; states[f].diplomacy[i] = states[suzerain].diplomacy[i]; if (states[suzerain].diplomacy[i] === "Suzerain") states[f].diplomacy[i] = "Ally"; - for (let e=1; e < states.length; e++) { + for (let e = 1; e < states.length; e++) { if (e === f || e === suzerain) continue; if (states[e].diplomacy[suzerain] === "Suzerain" || states[e].diplomacy[suzerain] === "Vassal") continue; states[e].diplomacy[f] = states[e].diplomacy[suzerain]; @@ -706,30 +797,36 @@ continue; } - for (let t=f+1; t < states.length; t++) { + for (let t = f + 1; t < states.length; t++) { if (states[t].removed) continue; if (states[t].diplomacy.includes("Vassal")) { const suzerain = states[t].diplomacy.indexOf("Vassal"); states[f].diplomacy[t] = states[f].diplomacy[suzerain]; continue; - }; + } const naval = states[f].type === "Naval" && states[t].type === "Naval" && cells.f[states[f].center] !== cells.f[states[t].center]; const neib = naval ? false : states[f].neighbors.includes(t); - const neibOfNeib = naval || neib ? false : states[f].neighbors.map(n => states[n].neighbors).join("").includes(t); + const neibOfNeib = + naval || neib + ? false + : states[f].neighbors + .map(n => states[n].neighbors) + .join("") + .includes(t); let status = naval ? rw(navals) : neib ? rw(neibs) : neibOfNeib ? rw(neibsOfNeibs) : rw(far); // add Vassal - if (neib && P(.8) && states[f].area > areaMean && states[t].area < areaMean && states[f].area / states[t].area > 2) status = "Vassal"; + if (neib && P(0.8) && states[f].area > areaMean && states[t].area < areaMean && states[f].area / states[t].area > 2) status = "Vassal"; states[f].diplomacy[t] = status === "Vassal" ? "Suzerain" : status; states[t].diplomacy[f] = status; } } // declare wars - for (let attacker=1; attacker < states.length; attacker++) { + for (let attacker = 1; attacker < states.length; attacker++) { const ad = states[attacker].diplomacy; // attacker relations; if (states[attacker].removed) continue; if (!ad.includes("Rival")) continue; // no rivals to attack @@ -737,31 +834,38 @@ if (ad.includes("Enemy")) continue; // already at war // random independent rival - const defender = ra(ad.map((r, d) => r === "Rival" && !states[d].diplomacy.includes("Vassal") ? d : 0).filter(d => d)); - let ap = states[attacker].area * states[attacker].expansionism, dp = states[defender].area * states[defender].expansionism; - if (ap < dp * gauss(1.6, .8, 0, 10, 2)) continue; // defender is too strong - const an = states[attacker].name, dn = states[defender].name; // names - const attackers = [attacker], defenders = [defender]; // attackers and defenders array + const defender = ra(ad.map((r, d) => (r === "Rival" && !states[d].diplomacy.includes("Vassal") ? d : 0)).filter(d => d)); + let ap = states[attacker].area * states[attacker].expansionism, + dp = states[defender].area * states[defender].expansionism; + if (ap < dp * gauss(1.6, 0.8, 0, 10, 2)) continue; // defender is too strong + const an = states[attacker].name, + dn = states[defender].name; // names + const attackers = [attacker], + defenders = [defender]; // attackers and defenders array const dd = states[defender].diplomacy; // defender relations; // start a war - const war = [`${an}-${trimVowels(dn)}ian War`,`${an} declared a war on its rival ${dn}`]; + const war = [`${an}-${trimVowels(dn)}ian War`, `${an} declared a war on its rival ${dn}`]; const end = options.year; const start = end - gauss(2, 2, 0, 5); states[attacker].campaigns.push({name: `${trimVowels(dn)}ian War`, start, end}); states[defender].campaigns.push({name: `${trimVowels(an)}ian War`, start, end}); // attacker vassals join the war - ad.forEach((r, d) => {if (r === "Suzerain") { - attackers.push(d); - war.push(`${an}'s vassal ${states[d].name} joined the war on attackers side`); - }}); + ad.forEach((r, d) => { + if (r === "Suzerain") { + attackers.push(d); + war.push(`${an}'s vassal ${states[d].name} joined the war on attackers side`); + } + }); // defender vassals join the war - dd.forEach((r, d) => {if (r === "Suzerain") { - defenders.push(d); - war.push(`${dn}'s vassal ${states[d].name} joined the war on defenders side`); - }}); + dd.forEach((r, d) => { + if (r === "Suzerain") { + defenders.push(d); + war.push(`${dn}'s vassal ${states[d].name} joined the war on defenders side`); + } + }); ap = d3.sum(attackers.map(a => states[a].area * states[a].expansionism)); // attackers joined power dp = d3.sum(defenders.map(d => states[d].area * states[d].expansionism)); // defender joined power @@ -769,7 +873,7 @@ // defender allies join dd.forEach((r, d) => { if (r !== "Ally" || states[d].diplomacy.includes("Vassal")) return; - if (states[d].diplomacy[attacker] !== "Rival" && ap / dp > (2 * gauss(1.6, .8, 0, 10, 2))) { + if (states[d].diplomacy[attacker] !== "Rival" && ap / dp > 2 * gauss(1.6, 0.8, 0, 10, 2)) { const reason = states[d].diplomacy.includes("Enemy") ? `Being already at war,` : `Frightened by ${an},`; war.push(`${reason} ${states[d].name} severed the defense pact with ${dn}`); dd[d] = states[d].diplomacy[defender] = "Suspicion"; @@ -780,71 +884,84 @@ war.push(`${dn}'s ally ${states[d].name} joined the war on defenders side`); // ally vassals join - states[d].diplomacy.map((r, d) => r === "Suzerain" ? d : 0).filter(d => d).forEach(v => { - defenders.push(v); - dp += states[v].area * states[v].expansionism; - war.push(`${states[d].name}'s vassal ${states[v].name} joined the war on defenders side`); - }); + states[d].diplomacy + .map((r, d) => (r === "Suzerain" ? d : 0)) + .filter(d => d) + .forEach(v => { + defenders.push(v); + dp += states[v].area * states[v].expansionism; + war.push(`${states[d].name}'s vassal ${states[v].name} joined the war on defenders side`); + }); }); // attacker allies join if the defender is their rival or joined power > defenders power and defender is not an ally ad.forEach((r, d) => { if (r !== "Ally" || states[d].diplomacy.includes("Vassal") || defenders.includes(d)) return; const name = states[d].name; - if (states[d].diplomacy[defender] !== "Rival" && (P(.2) || ap <= dp * 1.2)) {war.push(`${an}'s ally ${name} avoided entering the war`); return;} - const allies = states[d].diplomacy.map((r, d) => r === "Ally" ? d : 0).filter(d => d); - if (allies.some(ally => defenders.includes(ally))) {war.push(`${an}'s ally ${name} did not join the war as its allies are in war on both sides`); return;}; + if (states[d].diplomacy[defender] !== "Rival" && (P(0.2) || ap <= dp * 1.2)) { + war.push(`${an}'s ally ${name} avoided entering the war`); + return; + } + const allies = states[d].diplomacy.map((r, d) => (r === "Ally" ? d : 0)).filter(d => d); + if (allies.some(ally => defenders.includes(ally))) { + war.push(`${an}'s ally ${name} did not join the war as its allies are in war on both sides`); + return; + } attackers.push(d); ap += states[d].area * states[d].expansionism; war.push(`${an}'s ally ${name} joined the war on attackers side`); // ally vassals join - states[d].diplomacy.map((r, d) => r === "Suzerain" ? d : 0).filter(d => d).forEach(v => { - attackers.push(v); - dp += states[v].area * states[v].expansionism; - war.push(`${states[d].name}'s vassal ${states[v].name} joined the war on attackers side`); - }); + states[d].diplomacy + .map((r, d) => (r === "Suzerain" ? d : 0)) + .filter(d => d) + .forEach(v => { + attackers.push(v); + dp += states[v].area * states[v].expansionism; + war.push(`${states[d].name}'s vassal ${states[v].name} joined the war on attackers side`); + }); }); // change relations to Enemy for all participants - attackers.forEach(a => defenders.forEach(d => states[a].diplomacy[d] = states[d].diplomacy[a] = "Enemy")); + attackers.forEach(a => defenders.forEach(d => (states[a].diplomacy[d] = states[d].diplomacy[a] = "Enemy"))); chronicle.push(war); // add a record to diplomatical history } TIME && console.timeEnd("generateDiplomacy"); //console.table(states.map(s => s.diplomacy)); - } + }; // select a forms for listed or all valid states - const defineStateForms = function(list) { + const defineStateForms = function (list) { TIME && console.time("defineStateForms"); const states = pack.states.filter(s => s.i && !s.removed); if (states.length < 1) return; - const generic = {Monarchy:25, Republic:2, Union:1}; - const naval = {Monarchy:25, Republic:8, Union:3}; + const generic = {Monarchy: 25, Republic: 2, Union: 1}; + const naval = {Monarchy: 25, Republic: 8, Union: 3}; const median = d3.median(pack.states.map(s => s.area)); - const empireMin = states.map(s => s.area).sort((a, b) => b - a)[Math.max(Math.ceil(states.length ** .4) - 2, 0)]; + const empireMin = states.map(s => s.area).sort((a, b) => b - a)[Math.max(Math.ceil(states.length ** 0.4) - 2, 0)]; const expTiers = pack.states.map(s => { - let tier = Math.min(Math.floor(s.area / median * 2.6), 4); + let tier = Math.min(Math.floor((s.area / median) * 2.6), 4); if (tier === 4 && s.area < empireMin) tier = 3; return tier; }); const monarchy = ["Duchy", "Grand Duchy", "Principality", "Kingdom", "Empire"]; // per expansionism tier - const republic = {Republic:75, Federation:4, Oligarchy:2, Tetrarchy:1, Triumvirate:1, Diarchy:1, "Trade Company":4, Junta:1}; // weighted random - const union = {Union:3, League:4, Confederation:1, "United Kingdom":1, "United Republic":1, "United Provinces":2, Commonwealth:1, Heptarchy:1}; // weighted random - const theocracy = {Theocracy: 20, Brotherhood:1, Thearchy:2, See:1}; - const anarchy = {"Free Territory":2, Council:3, Commune:1, Community:1}; + const republic = {Republic: 75, Federation: 4, Oligarchy: 2, "Most Serene Republic": 2, Tetrarchy: 1, Triumvirate: 1, Diarchy: 1, "Trade Company": 4, Junta: 1}; // weighted random + const union = {Union: 3, League: 4, Confederation: 1, "United Kingdom": 1, "United Republic": 1, "United Provinces": 2, Commonwealth: 1, Heptarchy: 1}; // weighted random + const theocracy = {Theocracy: 20, Brotherhood: 1, Thearchy: 2, See: 1, "Holy State": 1}; + const anarchy = {"Free Territory": 2, Council: 3, Commune: 1, Community: 1}; for (const s of states) { if (list && !list.includes(s.i)) continue; + const tier = expTiers[s.i]; const religion = pack.cells.religion[s.center]; - const isTheocracy = religion && pack.religions[religion].expansion === "state" || (P(.1) && ["Organized", "Cult"].includes(pack.religions[religion].type)); - const isAnarchy = P(.01 - expTiers[s.i]/500); + const isTheocracy = (religion && pack.religions[religion].expansion === "state") || (P(0.1) && ["Organized", "Cult"].includes(pack.religions[religion].type)); + const isAnarchy = P(0.01 - tier / 500); if (isTheocracy) s.form = "Theocracy"; else if (isAnarchy) s.form = "Anarchy"; @@ -857,11 +974,11 @@ const base = pack.cultures[s.culture].base; if (s.form === "Monarchy") { - const form = monarchy[expTiers[s.i]]; + const form = monarchy[tier]; // Default name depends on exponent tier, some culture bases have special names for tiers if (s.diplomacy) { if (form === "Duchy" && s.neighbors.length > 1 && rand(6) < s.neighbors.length && s.diplomacy.includes("Vassal")) return "Marches"; // some vassal dutchies on borderland - if (P(.3) && s.diplomacy.includes("Vassal")) return "Protectorate"; // some vassals + if (P(0.3) && s.diplomacy.includes("Vassal")) return "Protectorate"; // some vassals } if (base === 16 && (form === "Empire" || form === "Kingdom")) return "Sultanate"; // Turkic @@ -879,12 +996,12 @@ if (s.form === "Republic") { // Default name is from weighted array, special case for small states with only 1 burg - if (expTiers[s.i] < 2 && s.burgs === 1) { + if (tier < 2 && s.burgs === 1) { if (trimVowels(s.name) === trimVowels(pack.burgs[s.capital].name)) { s.name = pack.burgs[s.capital].name; return "Free City"; } - if (P(.3)) return "City-state"; + if (P(0.3)) return "City-state"; } return rw(republic); } @@ -893,93 +1010,108 @@ if (s.form === "Anarchy") return rw(anarchy); if (s.form === "Theocracy") { - if (P(.5) && [0, 1, 2, 3, 4, 6, 8, 9, 13, 15, 20].includes(base)) return "Diocese"; // Euporean - if (P(.9) && [7, 5].includes(base)) return "Eparchy"; // Greek, Ruthenian - if (P(.9) && [21, 16].includes(base)) return "Imamah"; // Nigerian, Turkish - if (P(.8) && [18, 17, 28].includes(base)) return "Caliphate"; // Arabic, Berber, Swahili + // European + if ([0, 1, 2, 3, 4, 6, 8, 9, 13, 15, 20].includes(base)) { + if (P(0.1)) return "Divine " + monarchy[tier]; + if (tier < 2 && P(0.5)) return "Diocese"; + if (tier < 2 && P(0.5)) return "Bishopric"; + } + if (tier < 2 && P(0.9) && [7, 5].includes(base)) return "Eparchy"; // Greek, Ruthenian + if (P(0.9) && [21, 16].includes(base)) return "Imamah"; // Nigerian, Turkish + if (tier > 2 && P(0.8) && [18, 17, 28].includes(base)) return "Caliphate"; // Arabic, Berber, Swahili return rw(theocracy); } } TIME && console.timeEnd("defineStateForms"); - } + }; // state forms requiring Adjective + Name, all other forms use scheme Form + Of + Name const adjForms = ["Empire", "Sultanate", "Khaganate", "Shogunate", "Caliphate", "Despotate", "Theocracy", "Oligarchy", "Union", "Confederation", "Trade Company", "League", "Tetrarchy", "Triumvirate", "Diarchy", "Horde", "Marches"]; - const getFullName = function(s) { + const getFullName = function (s) { if (!s.formName) return s.name; if (!s.name && s.formName) return "The " + s.formName; - const adjName = adjForms.includes(s.formName) && !(/-| /).test(s.name); + const adjName = adjForms.includes(s.formName) && !/-| /.test(s.name); return adjName ? `${getAdjective(s.name)} ${s.formName}` : `${s.formName} of ${s.name}`; - } + }; - const generateProvinces = function(regenerate) { + const generateProvinces = function (regenerate) { TIME && console.time("generateProvinces"); const localSeed = regenerate ? Math.floor(Math.random() * 1e9).toString() : seed; Math.random = aleaPRNG(localSeed); - const cells = pack.cells, states = pack.states, burgs = pack.burgs; - const provinces = pack.provinces = [0]; + const cells = pack.cells, + states = pack.states, + burgs = pack.burgs; + const provinces = (pack.provinces = [0]); cells.province = new Uint16Array(cells.i.length); // cell state const percentage = +provincesInput.value; - if (states.length < 2 || !percentage) {states.forEach(s => s.provinces = []); return;} // no provinces - const max = percentage == 100 ? 1000 : gauss(20, 5, 5, 100) * percentage ** .5; // max growth + if (states.length < 2 || !percentage) { + states.forEach(s => (s.provinces = [])); + return; + } // no provinces + const max = percentage == 100 ? 1000 : gauss(20, 5, 5, 100) * percentage ** 0.5; // max growth const forms = { - Monarchy: {County:11, Earldom:3, Shire:1, Landgrave:1, Margrave:1, Barony:1}, - Republic: {Province:6, Department:2, Governorate:2, District:1, Canton:1, Prefecture:1}, - Theocracy: {Parish:3, Deanery:1}, - Union: {Province:1, State:1, Canton:1, Republic:1, County:1, Council:1}, - Anarchy: {Council:1, Commune:1, Community:1, Tribe:1}, - Wild: {Territory:10, Land:5, Region:2, Tribe:1, Clan:1, Dependency:1, Area: 1} - } + Monarchy: {County: 11, Earldom: 3, Shire: 1, Landgrave: 1, Margrave: 1, Barony: 1}, + Republic: {Province: 6, Department: 2, Governorate: 2, District: 1, Canton: 1, Prefecture: 1}, + Theocracy: {Parish: 3, Deanery: 1}, + Union: {Province: 1, State: 1, Canton: 1, Republic: 1, County: 1, Council: 1}, + Anarchy: {Council: 1, Commune: 1, Community: 1, Tribe: 1}, + Wild: {Territory: 10, Land: 5, Region: 2, Tribe: 1, Clan: 1, Dependency: 1, Area: 1} + }; // generate provinces for a selected burgs Math.random = aleaPRNG(localSeed); states.forEach(s => { s.provinces = []; if (!s.i || s.removed) return; - const stateBurgs = burgs.filter(b => b.state === s.i && !b.removed) - .sort((a, b) => b.population * gauss(1, .2, .5, 1.5, 3) - a.population) + const stateBurgs = burgs + .filter(b => b.state === s.i && !b.removed) + .sort((a, b) => b.population * gauss(1, 0.2, 0.5, 1.5, 3) - a.population) .sort((a, b) => b.capital - a.capital); if (stateBurgs.length < 2) return; // at least 2 provinces are required - const provincesNumber = Math.max(Math.ceil(stateBurgs.length * percentage / 100), 2); + const provincesNumber = Math.max(Math.ceil((stateBurgs.length * percentage) / 100), 2); const form = Object.assign({}, forms[s.form]); - for (let i=0; i < provincesNumber; i++) { + for (let i = 0; i < provincesNumber; i++) { const province = provinces.length; s.provinces.push(province); const center = stateBurgs[i].cell; const burg = stateBurgs[i].i; const c = stateBurgs[i].culture; - const nameByBurg = P(.5); + const nameByBurg = P(0.5); const name = nameByBurg ? stateBurgs[i].name : Names.getState(Names.getCultureShort(c), c); const formName = rw(form); form[formName] += 10; const fullName = name + " " + formName; const color = getMixedColor(s.color); - const kinship = nameByBurg ? .8 : .4; + const kinship = nameByBurg ? 0.8 : 0.4; const type = getType(center, burg.port); const coa = COA.generate(stateBurgs[i].coa, kinship, null, type); coa.shield = COA.getShield(c, s.i); - provinces.push({i:province, state:s.i, center, burg, name, formName, fullName, color, coa}); + provinces.push({i: province, state: s.i, center, burg, name, formName, fullName, color, coa}); } }); // expand generated provinces const queue = new PriorityQueue({comparator: (a, b) => a.p - b.p}); const cost = []; - provinces.forEach(function(p) { + provinces.forEach(function (p) { if (!p.i || p.removed) return; cells.province[p.center] = p.i; - queue.queue({e:p.center, p:0, province:p.i, state:p.state}); + queue.queue({e: p.center, p: 0, province: p.i, state: p.state}); cost[p.center] = 1; }); while (queue.length) { - const next = queue.dequeue(), n = next.e, p = next.p, province = next.province, state = next.state; - cells.c[n].forEach(function(e) { + const next = queue.dequeue(), + n = next.e, + p = next.p, + province = next.province, + state = next.state; + cells.c[n].forEach(function (e) { const land = cells.h[e] >= 20; if (!land && !cells.t[e]) return; // cannot pass deep ocean if (land && cells.state[e] !== state) return; @@ -990,7 +1122,7 @@ if (!cost[e] || totalCost < cost[e]) { if (land) cells.province[e] = province; // assign province to a cell cost[e] = totalCost; - queue.queue({e, p:totalCost, province, state}); + queue.queue({e, p: totalCost, province, state}); } }); } @@ -1003,7 +1135,7 @@ if (adversaries.length < 2) continue; const buddies = neibs.filter(c => c === cells.province[i]).length; if (buddies.length > 2) continue; - const competitors = adversaries.map(p => adversaries.reduce((s, v) => v === p ? s+1 : s, 0)); + const competitors = adversaries.map(p => adversaries.reduce((s, v) => (v === p ? s + 1 : s), 0)); const max = d3.max(competitors); if (buddies >= max) continue; cells.province[i] = adversaries[competitors.indexOf(max)]; @@ -1023,51 +1155,56 @@ cells.province[center] = province; // expand province - const cost = []; cost[center] = 1; - queue.queue({e:center, p:0}); + const cost = []; + cost[center] = 1; + queue.queue({e: center, p: 0}); while (queue.length) { - const next = queue.dequeue(), n = next.e, p = next.p; + const next = queue.dequeue(), + n = next.e, + p = next.p; - cells.c[n].forEach(function(e) { + cells.c[n].forEach(function (e) { if (cells.province[e]) return; const land = cells.h[e] >= 20; if (cells.state[e] && cells.state[e] !== s.i) return; - const ter = land ? cells.state[e] === s.i ? 3 : 20 : cells.t[e] ? 10 : 30; + const ter = land ? (cells.state[e] === s.i ? 3 : 20) : cells.t[e] ? 10 : 30; const totalCost = p + ter; if (totalCost > max) return; if (!cost[e] || totalCost < cost[e]) { if (land && cells.state[e] === s.i) cells.province[e] = province; // assign province to a cell cost[e] = totalCost; - queue.queue({e, p:totalCost}); + queue.queue({e, p: totalCost}); } }); } // generate "wild" province name const c = cells.culture[center]; - const nameByBurg = burgCell && P(.5); + const nameByBurg = burgCell && P(0.5); const name = nameByBurg ? burgs[burg].name : Names.getState(Names.getCultureShort(c), c); const f = pack.features[cells.f[center]]; const provCells = stateNoProvince.filter(i => cells.province[i] === province); const singleIsle = provCells.length === f.cells && !provCells.find(i => cells.f[i] !== f.i); const isleGroup = !singleIsle && !provCells.find(i => pack.features[cells.f[i]].group !== "isle"); - const colony = !singleIsle && !isleGroup && P(.5) && !isPassable(s.center, center); + const colony = !singleIsle && !isleGroup && P(0.5) && !isPassable(s.center, center); const formName = singleIsle ? "Island" : isleGroup ? "Islands" : colony ? "Colony" : rw(forms["Wild"]); const fullName = name + " " + formName; const color = getMixedColor(s.color); - const dominion = colony ? P(.95) : singleIsle || isleGroup ? P(.7) : P(.3); - const kinship = dominion ? 0 : .4; + const dominion = colony ? P(0.95) : singleIsle || isleGroup ? P(0.7) : P(0.3); + const kinship = dominion ? 0 : 0.4; const type = getType(center, burgs[burg]?.port); const coa = COA.generate(s.coa, kinship, dominion, type); coa.shield = COA.getShield(c, s.i); - provinces.push({i:province, state:s.i, center, burg, name, formName, fullName, color, coa}); + provinces.push({i: province, state: s.i, center, burg, name, formName, fullName, color, coa}); s.provinces.push(province); // check if there is a land way within the same state between two cells function isPassable(from, to) { if (cells.f[from] !== cells.f[to]) return false; // on different islands - const queue = [from], used = new Uint8Array(cells.i.length), state = cells.state[from]; + const queue = [from], + used = new Uint8Array(cells.i.length), + state = cells.state[from]; while (queue.length) { const current = queue.pop(); if (current === to) return true; // way is found @@ -1086,10 +1223,7 @@ }); TIME && console.timeEnd("generateProvinces"); - } + }; - return {generate, expandStates, normalizeStates, assignColors, - drawBurgs, specifyBurgs, defineBurgFeatures, getType, drawStateLabels, collectStatistics, - generateCampaigns, generateDiplomacy, defineStateForms, getFullName, generateProvinces, updateCultures}; - -}))); + return {generate, expandStates, normalizeStates, assignColors, drawBurgs, specifyBurgs, defineBurgFeatures, getType, drawStateLabels, collectStatistics, generateCampaigns, generateDiplomacy, defineStateForms, getFullName, generateProvinces, updateCultures}; +}); From 25c97df2d09930035da4afd286951f75c6142f6b Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 01:20:25 +0300 Subject: [PATCH 08/82] add tier --- modules/burgs-and-states.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/burgs-and-states.js b/modules/burgs-and-states.js index 78054d1c..d3c426d6 100644 --- a/modules/burgs-and-states.js +++ b/modules/burgs-and-states.js @@ -966,11 +966,11 @@ if (isTheocracy) s.form = "Theocracy"; else if (isAnarchy) s.form = "Anarchy"; else s.form = s.type === "Naval" ? rw(naval) : rw(generic); - s.formName = selectForm(s); + s.formName = selectForm(s, tier); s.fullName = getFullName(s); } - function selectForm(s) { + function selectForm(s, tier) { const base = pack.cultures[s.culture].base; if (s.form === "Monarchy") { From 68f1861603bf2f15ce0db2be64dc51d627e60812 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 13:18:02 +0300 Subject: [PATCH 09/82] default styleSaverName ti take current name --- modules/ui/style.js | 81 ++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 57 deletions(-) diff --git a/modules/ui/style.js b/modules/ui/style.js index 59c8e659..c7645988 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -965,6 +965,8 @@ function addStylePreset() { position: {my: "center", at: "center", of: "svg"} }); + const currentStyle = document.getElementById("stylePreset").selectedOptions[0].text; + document.getElementById("styleSaverName").value = currentStyle; styleSaverJSON.value = JSON.stringify(getStyle(), null, 2); checkName(); @@ -1075,22 +1077,11 @@ function addStylePreset() { } function saveStyle() { - if (!styleSaverJSON.value) { - tip("Please provide a style JSON", false, "error"); - return; - } - if (!JSON.isValid(styleSaverJSON.value)) { - tip("JSON string is not valid, please check the format", false, "error"); - return; - } - if (!styleSaverName.value) { - tip("Please provide a preset name", false, "error"); - return; - } - if (styleSaverTip.innerHTML === "default") { - tip("You cannot overwrite default preset, please change the name", false, "error"); - return; - } + if (!styleSaverJSON.value) return tip("Please provide a style JSON", false, "error"); + if (!JSON.isValid(styleSaverJSON.value)) return tip("JSON string is not valid, please check the format", false, "error"); + if (!styleSaverName.value) return tip("Please provide a preset name", false, "error"); + if (styleSaverTip.innerHTML === "default") return tip("You cannot overwrite default preset, please change the name", false, "error"); + const preset = "style" + styleSaverName.value; applyOption(stylePreset, preset, styleSaverName.value); // add option localStorage.setItem("presetStyle", preset); // mark preset as default @@ -1101,41 +1092,25 @@ function addStylePreset() { } function styleDownload() { - if (!styleSaverJSON.value) { - tip("Please provide a style JSON", false, "error"); - return; - } - if (!JSON.isValid(styleSaverJSON.value)) { - tip("JSON string is not valid, please check the format", false, "error"); - return; - } - if (!styleSaverName.value) { - tip("Please provide a preset name", false, "error"); - return; - } + if (!styleSaverJSON.value) return tip("Please provide a style JSON", false, "error"); + if (!JSON.isValid(styleSaverJSON.value)) return tip("JSON string is not valid, please check the format", false, "error"); + if (!styleSaverName.value) return tip("Please provide a preset name", false, "error"); + const data = styleSaverJSON.value; - if (!data) { - tip("Please provide a style JSON", false, "error"); - return; - } + if (!data) return tip("Please provide a style JSON", false, "error"); downloadFile(data, "style" + styleSaverName.value + ".json", "application/json"); } function styleUpload(dataLoaded) { - if (!dataLoaded) { - tip("Cannot load the file. Please check the data format", false, "error"); - return; - } + if (!dataLoaded) return tip("Cannot load the file. Please check the data format", false, "error"); const data = JSON.stringify(JSON.parse(dataLoaded), null, 2); styleSaverJSON.value = data; } } function removeStylePreset() { - if (stylePreset.selectedOptions[0].dataset.system) { - tip("Cannot remove system preset", false, "error"); - return; - } + if (stylePreset.selectedOptions[0].dataset.system) return tip("Cannot remove system preset", false, "error"); + localStorage.removeItem("presetStyle"); localStorage.removeItem(stylePreset.value); stylePreset.selectedOptions[0].remove(); @@ -1148,10 +1123,8 @@ function applyMapFilter(event) { if (event.target.tagName !== "BUTTON") return; const button = event.target; svg.attr("data-filter", null).attr("filter", null); - if (button.classList.contains("pressed")) { - button.classList.remove("pressed"); - return; - } + if (button.classList.contains("pressed")) return button.classList.remove("pressed"); + mapFilters.querySelectorAll(".pressed").forEach(button => button.classList.remove("pressed")); button.classList.add("pressed"); svg.attr("data-filter", button.id).attr("filter", "url(#filter-" + button.id + ")"); @@ -1179,23 +1152,17 @@ function loadDefaultFonts() { function fetchFonts(url) { return new Promise((resolve, reject) => { - if (url === "") { - tip("Use a direct link to any @font-face declaration or just font name to fetch from Google Fonts"); - return; - } + if (url === "") return tip("Use a direct link to any @font-face declaration or just font name to fetch from Google Fonts"); + if (url.indexOf("http") === -1) { url = url.replace(url.charAt(0), url.charAt(0).toUpperCase()).split(" ").join("+"); url = "https://fonts.googleapis.com/css?family=" + url; } - const fetched = addFonts(url).then(fetched => { - if (fetched === undefined) { - tip("Cannot fetch font for this value!", false, "error"); - return; - } - if (fetched === 0) { - tip("Already in the fonts list!", false, "error"); - return; - } + + addFonts(url).then(fetched => { + if (fetched === undefined) return tip("Cannot fetch font for this value!", false, "error"); + if (fetched === 0) return tip("Already in the fonts list!", false, "error"); + updateFontOptions(); if (fetched === 1) { tip("Font " + fonts[fonts.length - 1] + " is fetched"); From 659a2173682f399488ef5f628cf4ca15e3478b89 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 13:24:36 +0300 Subject: [PATCH 10/82] new style: Light --- index.html | 2 +- modules/ui/style.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 3721ff6b..45d6782d 100644 --- a/index.html +++ b/index.html @@ -323,7 +323,7 @@ - + diff --git a/modules/ui/style.js b/modules/ui/style.js index c7645988..11abf93c 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -750,6 +750,7 @@ const defaultStyles = { styleAncient: `{"#map":{"background-color":"#000000","filter":"url(#filter-sepia)","data-filter":"sepia"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.05,"opacity":0.8,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":null,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eee9d7","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#5d97bb"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.8,"stroke":"#2e1607","stroke-width":1.23,"stroke-dasharray":3,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.8,"stroke":"#331809","stroke-width":0.5,"stroke-dasharray":"1 2","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.8,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(8px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.8,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#outline)"},"#emblems":{"opacity":0.6,"stroke-width":0.8,"filter":"url(#dropShadow05)"},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#blur5)","layers":"-6,-4,-2"},"#oceanBase":{"fill":"#a7a01f"},"#oceanicPattern":{"href":"./images/pattern1.png", "opacity":0.2},"#terrs":{"opacity":null,"scheme":"light","terracing":0,"skip":0,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":8,"font-size":8,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#fdfab9","fill-opacity":0.7,"size":1,"stroke":"#54251d","stroke-width":0.3,"stroke-dasharray":".3 .4","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#fef4d8","fill-opacity":0.7,"size":0.5,"stroke":"#463124","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`, styleGloom: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":"url(#land)"},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.3,"stroke-dasharray":".7 1","stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":14,"font-size":14,"stroke":"#4a4a4a","stroke-width":1,"stroke-dasharray":6,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(100 100) scale(0.3)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":1,"filter":null},"#cults":{"opacity":0.7,"stroke":"#777777","stroke-width":1.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e0e0e0","filter":null},"#markers":{"opacity":0.8,"rescale":1,"filter":"url(#dropShadow05)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000aa"},"#urban":{"stroke":"#9d0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.9,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#779582"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":1,"stroke":"#8b4418","stroke-width":0.9,"stroke-dasharray":"2 3","stroke-linecap":"round","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#844017","stroke-width":0.2,"stroke-dasharray":".5 1","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#5e1865","stroke-width":0.6,"stroke-dasharray":"1.2 2.4","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.5,"data-width":12,"stroke-width":12,"filter":"blur(10px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":1,"font-size":"11px","fill":"#62001b","fill-opacity":0.3,"stroke":null,"stroke-width":2,"stroke-dasharray":2,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#emblems": {"opacity":0.6,"stroke-width":0.5,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.5,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":"url(#dropShadow01)","mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#4e6964"},"#oceanicPattern":{"href":"./images/pattern3.png", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"bright","terracing":0,"skip":0,"relax":1,"curve":1,"filter":"url(#filter-grayscale)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":2,"stroke":"#444444","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":0.8,"fill":"#ffffff","size":4,"stroke":"#3e3e4b","stroke-width":1},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":3,"font-size":3,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #towns":{"opacity":0.95,"fill":"#ffffff","fill-opacity":0.7,"size":0.8,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1.6,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#4e4e4e","stroke":"#b5b5b5","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#1b1423","filter":null}}`, styleClean: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.5,"filter":"url(#blur7)","mask":"url(#land)"},"#stateBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.09,"filter":null,"mask":"url(#land)"},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":3,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eeedeb","filter":null},"#markers":{"opacity":null,"rescale":null,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0,"fill":"#0080ff","filter":null},"#population":{"opacity":null,"stroke-width":2.58,"stroke-dasharray":0,"stroke-linecap":"butt","filter":"url(#blur3)"},"#rural":{"stroke":"#ff0000"},"#urban":{"stroke":"#800000"},"#freshwater":{"opacity":0.5,"fill":"#aadaff","stroke":"#5f799d","stroke-width":0,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#595959","stroke-width":0.4,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#aadaff"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#f6d068","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#ffffff","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#4f82c6","stroke-width":0.45,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":"url(#water)"},"#statesBody":{"opacity":0.3,"filter":null},"#statesHalo":{"opacity":0.5,"data-width":1,"stroke-width":1,"filter":null},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow01)"},"#emblems":{"opacity":1,"stroke-width":1,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.7,"stroke":"#ff6262","stroke-width":0,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#aadaff"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":0.5,"scheme":"bright","terracing":0,"skip":5,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":12.74,"font-size":12.74,"data-font":"Arial","font-family":"Arial","stroke":"#909090","stroke-width":1.13,"stroke-dasharray":0,"stroke-linecap":"round","data-x":98.39,"data-y":12.67,"data-columns":null},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#414141","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#303030","stroke-width":1.7},"#burgLabels > #towns":{"opacity":1,"fill":"#414141","data-size":3,"font-size":3,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.06},"#labels > #states":{"opacity":1,"fill":"#292929","stroke":"#303030","stroke-width":0,"text-shadow":"white 0 0 2px","data-size":10,"font-size":10,"data-font":"Arial","font-family":"Arial","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#414141","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Arial","font-family":"Arial","filter":null},"#fogging":{"opacity":1,"fill":"#ffffff","filter":null}}`, + styleLight: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.02,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":0.5,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#4c483e","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"square","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.5,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#808080","stroke-width":1,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":0.7,"data-size":15,"font-size":15,"stroke":"#734d37","stroke-width":1.5,"stroke-dasharray":5,"stroke-linecap":"square","filter":null,"mask":""},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.5,"stroke":null,"stroke-width":0,"filter":null},"#cults":{"opacity":0.5,"stroke":"#777777","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#f9f2ea","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":null},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#2554ef","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#98cdc4","stroke":"#719892","stroke-width":0.46,"filter":"url(#dropShadow05)"},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":1,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":1,"stroke":"#5e5e5e","stroke-width":0.4,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.62,"set":"colored","size":1.73,"density":0.3,"filter":"url(#filter-sepia)","mask":""},"#rivers":{"opacity":null,"filter":null,"fill":"#6d94ba"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#3c1d0b","stroke-width":1.37,"stroke-dasharray":2,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#95481a","stroke-width":0.88,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.2,"filter":null},"#statesHalo":{"opacity":0.3,"data-width":25,"stroke-width":25,"filter":"blur(5px)"},"#provs":{"opacity":0.4,"fill":"#000000","font-size":5,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.5,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1.5,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.9,"stroke-width":1,"filter":null},"#texture":{"opacity":0.39,"filter":null,"mask":""},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#dropShadow05)","layers":"-6,-3,-1"},"#oceanBase":{"fill":"#8dc1c8"},"#oceanicPattern":{"href":"./images/pattern1.png","opacity":0.2},"#terrs":{"opacity":0.4,"scheme":"light","terracing":10,"skip":5,"relax":0,"curve":0,"filter":"url(#turbulence)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":54.73,"data-y":62.98,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#3a3a3a","text-shadow":"white 0px 0px 4px","data-size":8,"font-size":8,"data-font":"IM+Fell+English","font-family":"IM Fell English"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":3,"stroke":"#3e3e4b","stroke-width":0.4,"stroke-dasharray":"0.5 0.25","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":5.5,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":4,"font-size":4,"data-font":"IM+Fell+English","font-family":"IM Fell English"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1.2,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":2.2,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e3e","stroke":"#000000","stroke-width":0.3,"text-shadow":"white 0px 0px 6px","data-size":14,"font-size":14,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#f24706","stroke":"#701b05","stroke-width":0.1,"text-shadow":"white 0px 0px 4px","data-size":6,"font-size":6,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#fogging":{"opacity":1,"fill":"#30426f","filter":null}}`, styleWatercolor: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.2,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.6,"filter":null,"mask":null},"#stateBorders":{"opacity":0.6,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":3,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.5,"stroke":"#56566d","stroke-width":0.5,"stroke-dasharray":"0 2","stroke-linecap":"round","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#777777","stroke-width":0,"filter":"url(#bluredSplotch)"},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":"url(#splotch)"},"#landmass":{"opacity":1,"fill":"#eef6fb","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":1,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":null,"set":"gray","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#2e89c2"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#969696","stroke-width":0.4,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.05,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":8,"stroke-width":8,"filter":"blur(2px)"},"#provs":{"opacity":0.7,"fill":"#000000","font-size":4,"data-font":"Comfortaa:700","font-family":"Comfortaa","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.7,"fill":"#dfe8ec","stroke":"#000000","stroke-width":0,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.95,"stroke-width":1,"filter":null},"#texture":{"opacity":0.2,"filter":null,"mask":"url(#land)"},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#2d788b"},"#oceanicPattern":{"href":"./images/kiwiroo.png","opacity":0.5},"#terrs":{"opacity":0.5,"scheme":"light","terracing":0,"skip":5,"relax":1,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#043449","text-shadow":"white 0px 0px 2px","data-size":5,"font-size":5,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":3,"font-size":3,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#ffffff","stroke":"#000000","stroke-width":0.15,"text-shadow":"black 1px 1px 2px","data-size":20,"font-size":20,"data-font":"Gloria+Hallelujah","font-family":"Gloria Hallelujah","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":18,"font-size":18,"data-font":"Comfortaa","font-family":"Comfortaa","filter":null},"#fogging":{"opacity":0.97,"fill":"#8398ce","filter":null}}`, styleMonochrome: `{"#map":{"background-color":"#000000","filter":"url(#filter-grayscale)","data-filter":"grayscale"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":null},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.4,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#000000","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#000000","stroke":"#515151","stroke-width":0,"filter":null},"#salt":{"opacity":1,"fill":"#000000","stroke":"#484848","stroke-width":0,"filter":null},"#sinkhole":{"opacity":1,"fill":"#000000","stroke":"#5f5f5f","stroke-width":0.5,"filter":null},"#frozen":{"opacity":1,"fill":"#000000","stroke":"#6f6f6f","stroke-width":0,"filter":null},"#lava":{"opacity":1,"fill":"#000000","stroke":"#5d5d5d","stroke-width":0,"filter":null},"#sea_island":{"opacity":1,"stroke":"#1f3846","stroke-width":0,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":0.2,"filter":"url(#blur1)","fill":"#000000"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.7,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.25,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(5px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#texture":{"opacity":1,"filter":null,"mask":"url(#land)"},"#emblems": {"opacity": 0.5,"stroke-width": 0.5,"filter": null},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#000000"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"monochrome","terracing":0,"skip":5,"relax":0,"curve":0,"filter":"url(#blur3)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}` }; From 966184be36de74cf095a326ee22448935da0928f Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 13:31:32 +0300 Subject: [PATCH 11/82] add Light style to options --- index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/index.html b/index.html index 45d6782d..ae703a71 100644 --- a/index.html +++ b/index.html @@ -321,6 +321,7 @@ + From f69443c5848d6975b20ca5067381470f76f86e2d Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 15:00:35 +0300 Subject: [PATCH 12/82] save stylePreset to .map file --- index.html | 4 ++-- modules/load.js | 1 + modules/save.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index ae703a71..7ebd40a2 100644 --- a/index.html +++ b/index.html @@ -316,13 +316,13 @@
-

Style preset:

+

Style preset:

diff --git a/modules/load.js b/modules/load.js index 15c30438..f1d308a2 100644 --- a/modules/load.js +++ b/modules/load.js @@ -141,6 +141,7 @@ function parseLoadedData(data) { if (settings[19]) options = JSON.parse(settings[19]); if (settings[20]) mapName.value = settings[20]; if (settings[21]) hideLabels.checked = +settings[21]; + if (settings[22]) stylePreset.value = +settings[22]; })(); void (function parseConfiguration() { diff --git a/modules/save.js b/modules/save.js index a7c5c687..c0ac85ea 100644 --- a/modules/save.js +++ b/modules/save.js @@ -421,7 +421,7 @@ function getMapData() { const dateString = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(); const license = "File can be loaded in azgaar.github.io/Fantasy-Map-Generator"; const params = [version, license, dateString, seed, graphWidth, graphHeight, mapId].join("|"); - const settings = [distanceUnitInput.value, distanceScaleInput.value, areaUnit.value, heightUnit.value, heightExponentInput.value, temperatureScale.value, barSizeInput.value, barLabel.value, barBackOpacity.value, barBackColor.value, barPosX.value, barPosY.value, populationRate, urbanization, mapSizeOutput.value, latitudeOutput.value, temperatureEquatorOutput.value, temperaturePoleOutput.value, precOutput.value, JSON.stringify(options), mapName.value, +hideLabels.checked].join("|"); + const settings = [distanceUnitInput.value, distanceScaleInput.value, areaUnit.value, heightUnit.value, heightExponentInput.value, temperatureScale.value, barSizeInput.value, barLabel.value, barBackOpacity.value, barBackColor.value, barPosX.value, barPosY.value, populationRate, urbanization, mapSizeOutput.value, latitudeOutput.value, temperatureEquatorOutput.value, temperaturePoleOutput.value, precOutput.value, JSON.stringify(options), mapName.value, +hideLabels.checked, stylePreset.value].join("|"); const coords = JSON.stringify(mapCoordinates); const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|"); const notesData = JSON.stringify(notes); From 186ed14eee28839f0cb03650e705652e782a9632 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 15:02:08 +0300 Subject: [PATCH 13/82] style is a stirng --- modules/load.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/load.js b/modules/load.js index f1d308a2..cec66434 100644 --- a/modules/load.js +++ b/modules/load.js @@ -141,7 +141,7 @@ function parseLoadedData(data) { if (settings[19]) options = JSON.parse(settings[19]); if (settings[20]) mapName.value = settings[20]; if (settings[21]) hideLabels.checked = +settings[21]; - if (settings[22]) stylePreset.value = +settings[22]; + if (settings[22]) stylePreset.value = settings[22]; })(); void (function parseConfiguration() { From 7d299ff3952c18f806dfcc6a795cc54a6edeedfe Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 16:47:49 +0300 Subject: [PATCH 14/82] redraw relief on size change --- index.html | 16 +++--- modules/relief-icons.js | 109 +++++++++++++++++++++++----------------- modules/ui/layers.js | 6 +-- modules/ui/style.js | 32 ++++-------- 4 files changed, 84 insertions(+), 79 deletions(-) diff --git a/index.html b/index.html index 7ebd40a2..843fdac9 100644 --- a/index.html +++ b/index.html @@ -579,7 +579,7 @@
- + - + - + diff --git a/modules/relief-icons.js b/modules/relief-icons.js index ea677e0f..e7d8b6a0 100644 --- a/modules/relief-icons.js +++ b/modules/relief-icons.js @@ -1,41 +1,43 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.ReliefIcons = factory()); -}(this, (function () {'use strict'; + typeof exports === "object" && typeof module !== "undefined" ? (module.exports = factory()) : typeof define === "function" && define.amd ? define(factory) : (global.ReliefIcons = factory()); +})(this, function () { + "use strict"; - const ReliefIcons = function() { - TIME && console.time('drawRelief'); + const ReliefIcons = function () { + TIME && console.time("drawRelief"); terrain.selectAll("*").remove(); - const density = terrain.attr("density") || .4; - const size = 1.6 * (terrain.attr("size") || 1); - const mod = .2 * size; // size modifier;s - const relief = []; // t: type, c: cell, x: centerX, y: centerY, s: size; + const cells = pack.cells; + const density = terrain.attr("density") || 0.4; + const size = 2 * (terrain.attr("size") || 1); + const mod = 0.2 * size; // size modifier + const relief = []; for (const i of cells.i) { const height = cells.h[i]; if (height < 20) continue; // no icons on water if (cells.r[i]) continue; // no icons on rivers - const b = cells.biome[i]; - if (height < 50 && biomesData.iconsDensity[b] === 0) continue; // no icons for this biome - const polygon = getPackPolygon(i); - const x = d3.extent(polygon, p => p[0]), y = d3.extent(polygon, p => p[1]); - const e = [Math.ceil(x[0]), Math.ceil(y[0]), Math.floor(x[1]), Math.floor(y[1])]; // polygon box + const biome = cells.biome[i]; + if (height < 50 && biomesData.iconsDensity[biome] === 0) continue; // no icons for this biome - if (height < 50) placeBiomeIcons(i, b); else placeReliefIcons(i); + const polygon = getPackPolygon(i); + const [minX, maxX] = d3.extent(polygon, p => p[0]); + const [minY, maxY] = d3.extent(polygon, p => p[1]); + + if (height < 50) placeBiomeIcons(i, biome); + else placeReliefIcons(i); function placeBiomeIcons() { - const iconsDensity = biomesData.iconsDensity[b] / 100; + const iconsDensity = biomesData.iconsDensity[biome] / 100; const radius = 2 / iconsDensity / density; if (Math.random() > iconsDensity * 10) return; - for (const [cx, cy] of poissonDiscSampler(e[0], e[1], e[2], e[3], radius)) { + for (const [cx, cy] of poissonDiscSampler(minX, minY, maxX, maxY, radius)) { if (!d3.polygonContains(polygon, [cx, cy])) continue; - let h = rn((4 + Math.random()) * size, 2); - const icon = getBiomeIcon(i, biomesData.icons[b]); - if (icon === "#relief-grass-1") h *= 1.3; - relief.push({i: icon, x: rn(cx-h, 2), y: rn(cy-h, 2), s: rn(h*2, 2)}); + let h = (4 + Math.random()) * size; + const icon = getBiomeIcon(i, biomesData.icons[biome]); + if (icon === "#relief-grass-1") h *= 1.2; + relief.push({i: icon, x: rn(cx - h, 2), y: rn(cy - h, 2), s: rn(h * 2, 2)}); } } @@ -43,9 +45,9 @@ const radius = 2 / density; const [icon, h] = getReliefIcon(i, height); - for (const [cx, cy] of poissonDiscSampler(e[0], e[1], e[2], e[3], radius)) { + for (const [cx, cy] of poissonDiscSampler(minX, minY, maxX, maxY, radius)) { if (!d3.polygonContains(polygon, [cx, cy])) continue; - relief.push({i: icon, x: rn(cx-h, 2), y: rn(cy-h, 2), s: rn(h*2, 2)}); + relief.push({i: icon, x: rn(cx - h, 2), y: rn(cy - h, 2), s: rn(h * 2, 2)}); } } @@ -58,17 +60,16 @@ } // sort relief icons by y+size - relief.sort((a, b) => (a.y + a.s) - (b.y + b.s)); + relief.sort((a, b) => a.y + a.s - (b.y + b.s)); - // append relief icons at once using pure js let reliefHTML = ""; for (const r of relief) { reliefHTML += ``; } terrain.html(reliefHTML); - TIME && console.timeEnd('drawRelief'); - } + TIME && console.timeEnd("drawRelief"); + }; function getBiomeIcon(i, b) { let type = b[Math.floor(Math.random() * b.length)]; @@ -78,27 +79,42 @@ } function getVariant(type) { - switch(type) { - case "mount": return rand(2,7); - case "mountSnow": return rand(1,6); - case "hill": return rand(2,5); - case "conifer": return 2; - case "coniferSnow": return 1; - case "swamp": return rand(2,3); - case "cactus": return rand(1,3); - case "deadTree": return rand(1,2); - default: return 2; + switch (type) { + case "mount": + return rand(2, 7); + case "mountSnow": + return rand(1, 6); + case "hill": + return rand(2, 5); + case "conifer": + return 2; + case "coniferSnow": + return 1; + case "swamp": + return rand(2, 3); + case "cactus": + return rand(1, 3); + case "deadTree": + return rand(1, 2); + default: + return 2; } } function getOldIcon(type) { - switch(type) { - case "mountSnow": return "mount"; - case "vulcan": return "mount"; - case "coniferSnow": return "conifer"; - case "cactus": return "dune"; - case "deadTree": return "dune"; - default: return type; + switch (type) { + case "mountSnow": + return "mount"; + case "vulcan": + return "mount"; + case "coniferSnow": + return "conifer"; + case "cactus": + return "dune"; + case "deadTree": + return "dune"; + default: + return type; } } @@ -111,5 +127,4 @@ } return ReliefIcons; - -}))); \ No newline at end of file +}); diff --git a/modules/ui/layers.js b/modules/ui/layers.js index a643a22a..b2bad889 100644 --- a/modules/ui/layers.js +++ b/modules/ui/layers.js @@ -1606,21 +1606,21 @@ function drawEmblems() { const getStateEmblemsSize = () => { const startSize = Math.min(Math.max((graphHeight + graphWidth) / 40, 10), 100); const statesMod = 1 + validStates.length / 100 - (15 - validStates.length) / 200; // states number modifier - const sizeMod = +document.getElementById("styleEmblemsStateSizeInput").value || 1; + const sizeMod = +document.getElementById("emblemsStateSizeInput").value || 1; return rn((startSize / statesMod) * sizeMod); // target size ~50px on 1536x754 map with 15 states }; const getProvinceEmblemsSize = () => { const startSize = Math.min(Math.max((graphHeight + graphWidth) / 100, 5), 70); const provincesMod = 1 + validProvinces.length / 1000 - (115 - validProvinces.length) / 1000; // states number modifier - const sizeMod = +document.getElementById("styleEmblemsProvinceSizeInput").value || 1; + const sizeMod = +document.getElementById("emblemsProvinceSizeInput").value || 1; return rn((startSize / provincesMod) * sizeMod); // target size ~20px on 1536x754 map with 115 provinces }; const getBurgEmblemSize = () => { const startSize = Math.min(Math.max((graphHeight + graphWidth) / 185, 2), 50); const burgsMod = 1 + validBurgs.length / 1000 - (450 - validBurgs.length) / 1000; // states number modifier - const sizeMod = +document.getElementById("styleEmblemsBurgSizeInput").value || 1; + const sizeMod = +document.getElementById("emblemsBurgSizeInput").value || 1; return rn((startSize / burgsMod) * sizeMod); // target size ~8.5px on 1536x754 map with 450 burgs }; diff --git a/modules/ui/style.js b/modules/ui/style.js index 11abf93c..764ddda9 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -458,23 +458,13 @@ styleReliefSet.addEventListener("change", function () { }); styleReliefSizeInput.addEventListener("change", function () { + terrain.attr("size", this.value); styleReliefSizeOutput.value = this.value; - const size = +this.value; - terrain.attr("size", size); - - terrain.selectAll("use").each(function (d) { - const newSize = this.getAttribute("data-size") * size; - const shift = (newSize - +this.getAttribute("width")) / 2; - this.setAttribute("width", newSize); - this.setAttribute("height", newSize); - const x = +this.getAttribute("x"); - const y = +this.getAttribute("y"); - this.setAttribute("x", x - shift); - this.setAttribute("y", y - shift); - }); + ReliefIcons(); + if (!layerIsOn("toggleRelief")) toggleRelief(); }); -styleReliefDensityInput.addEventListener("input", function () { +styleReliefDensityInput.addEventListener("change", function () { terrain.attr("density", this.value); styleReliefDensityOutput.value = this.value; ReliefIcons(); @@ -698,9 +688,9 @@ styleArmiesSize.addEventListener("input", function () { }); }); -styleEmblemsStateSizeInput.addEventListener("input", drawEmblems); -styleEmblemsProvinceSizeInput.addEventListener("input", drawEmblems); -styleEmblemsBurgSizeInput.addEventListener("input", drawEmblems); +emblemsStateSizeInput.addEventListener("change", drawEmblems); +emblemsProvinceSizeInput.addEventListener("change", drawEmblems); +emblemsBurgSizeInput.addEventListener("change", drawEmblems); // request a URL to image to be used as a texture function textureProvideURL() { @@ -747,11 +737,11 @@ function fetchTextureURL(url) { } const defaultStyles = { - styleAncient: `{"#map":{"background-color":"#000000","filter":"url(#filter-sepia)","data-filter":"sepia"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.05,"opacity":0.8,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":null,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eee9d7","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#5d97bb"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.8,"stroke":"#2e1607","stroke-width":1.23,"stroke-dasharray":3,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.8,"stroke":"#331809","stroke-width":0.5,"stroke-dasharray":"1 2","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.8,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(8px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.8,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#outline)"},"#emblems":{"opacity":0.6,"stroke-width":0.8,"filter":"url(#dropShadow05)"},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#blur5)","layers":"-6,-4,-2"},"#oceanBase":{"fill":"#a7a01f"},"#oceanicPattern":{"href":"./images/pattern1.png", "opacity":0.2},"#terrs":{"opacity":null,"scheme":"light","terracing":0,"skip":0,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":8,"font-size":8,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#fdfab9","fill-opacity":0.7,"size":1,"stroke":"#54251d","stroke-width":0.3,"stroke-dasharray":".3 .4","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#fef4d8","fill-opacity":0.7,"size":0.5,"stroke":"#463124","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`, + styleAncient: `{"#map":{"background-color":"#000000","filter":"url(#filter-sepia)","data-filter":"sepia"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.05,"opacity":0.8,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":null,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eee9d7","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":1,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#5d97bb"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.8,"stroke":"#2e1607","stroke-width":1.23,"stroke-dasharray":3,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.8,"stroke":"#331809","stroke-width":0.5,"stroke-dasharray":"1 2","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.8,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(8px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.8,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#outline)"},"#emblems":{"opacity":0.6,"stroke-width":0.8,"filter":"url(#dropShadow05)"},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#blur5)","layers":"-6,-4,-2"},"#oceanBase":{"fill":"#a7a01f"},"#oceanicPattern":{"href":"./images/pattern1.png", "opacity":0.2},"#terrs":{"opacity":null,"scheme":"light","terracing":0,"skip":0,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":8,"font-size":8,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#fdfab9","fill-opacity":0.7,"size":1,"stroke":"#54251d","stroke-width":0.3,"stroke-dasharray":".3 .4","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#fef4d8","fill-opacity":0.7,"size":0.5,"stroke":"#463124","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`, styleGloom: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":"url(#land)"},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.3,"stroke-dasharray":".7 1","stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":14,"font-size":14,"stroke":"#4a4a4a","stroke-width":1,"stroke-dasharray":6,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(100 100) scale(0.3)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":1,"filter":null},"#cults":{"opacity":0.7,"stroke":"#777777","stroke-width":1.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e0e0e0","filter":null},"#markers":{"opacity":0.8,"rescale":1,"filter":"url(#dropShadow05)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000aa"},"#urban":{"stroke":"#9d0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.9,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#779582"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":1,"stroke":"#8b4418","stroke-width":0.9,"stroke-dasharray":"2 3","stroke-linecap":"round","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#844017","stroke-width":0.2,"stroke-dasharray":".5 1","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#5e1865","stroke-width":0.6,"stroke-dasharray":"1.2 2.4","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.5,"data-width":12,"stroke-width":12,"filter":"blur(10px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":1,"font-size":"11px","fill":"#62001b","fill-opacity":0.3,"stroke":null,"stroke-width":2,"stroke-dasharray":2,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#emblems": {"opacity":0.6,"stroke-width":0.5,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.5,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":"url(#dropShadow01)","mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#4e6964"},"#oceanicPattern":{"href":"./images/pattern3.png", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"bright","terracing":0,"skip":0,"relax":1,"curve":1,"filter":"url(#filter-grayscale)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":2,"stroke":"#444444","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":0.8,"fill":"#ffffff","size":4,"stroke":"#3e3e4b","stroke-width":1},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":3,"font-size":3,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #towns":{"opacity":0.95,"fill":"#ffffff","fill-opacity":0.7,"size":0.8,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1.6,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#4e4e4e","stroke":"#b5b5b5","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#1b1423","filter":null}}`, - styleClean: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.5,"filter":"url(#blur7)","mask":"url(#land)"},"#stateBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.09,"filter":null,"mask":"url(#land)"},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":3,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eeedeb","filter":null},"#markers":{"opacity":null,"rescale":null,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0,"fill":"#0080ff","filter":null},"#population":{"opacity":null,"stroke-width":2.58,"stroke-dasharray":0,"stroke-linecap":"butt","filter":"url(#blur3)"},"#rural":{"stroke":"#ff0000"},"#urban":{"stroke":"#800000"},"#freshwater":{"opacity":0.5,"fill":"#aadaff","stroke":"#5f799d","stroke-width":0,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#595959","stroke-width":0.4,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#aadaff"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#f6d068","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#ffffff","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#4f82c6","stroke-width":0.45,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":"url(#water)"},"#statesBody":{"opacity":0.3,"filter":null},"#statesHalo":{"opacity":0.5,"data-width":1,"stroke-width":1,"filter":null},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow01)"},"#emblems":{"opacity":1,"stroke-width":1,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.7,"stroke":"#ff6262","stroke-width":0,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#aadaff"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":0.5,"scheme":"bright","terracing":0,"skip":5,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":12.74,"font-size":12.74,"data-font":"Arial","font-family":"Arial","stroke":"#909090","stroke-width":1.13,"stroke-dasharray":0,"stroke-linecap":"round","data-x":98.39,"data-y":12.67,"data-columns":null},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#414141","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#303030","stroke-width":1.7},"#burgLabels > #towns":{"opacity":1,"fill":"#414141","data-size":3,"font-size":3,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.06},"#labels > #states":{"opacity":1,"fill":"#292929","stroke":"#303030","stroke-width":0,"text-shadow":"white 0 0 2px","data-size":10,"font-size":10,"data-font":"Arial","font-family":"Arial","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#414141","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Arial","font-family":"Arial","filter":null},"#fogging":{"opacity":1,"fill":"#ffffff","filter":null}}`, - styleLight: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.02,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":0.5,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#4c483e","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"square","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.5,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#808080","stroke-width":1,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":0.7,"data-size":15,"font-size":15,"stroke":"#734d37","stroke-width":1.5,"stroke-dasharray":5,"stroke-linecap":"square","filter":null,"mask":""},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.5,"stroke":null,"stroke-width":0,"filter":null},"#cults":{"opacity":0.5,"stroke":"#777777","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#f9f2ea","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":null},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#2554ef","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#98cdc4","stroke":"#719892","stroke-width":0.46,"filter":"url(#dropShadow05)"},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":1,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":1,"stroke":"#5e5e5e","stroke-width":0.4,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.62,"set":"colored","size":1.73,"density":0.3,"filter":"url(#filter-sepia)","mask":""},"#rivers":{"opacity":null,"filter":null,"fill":"#6d94ba"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#3c1d0b","stroke-width":1.37,"stroke-dasharray":2,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#95481a","stroke-width":0.88,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.2,"filter":null},"#statesHalo":{"opacity":0.3,"data-width":25,"stroke-width":25,"filter":"blur(5px)"},"#provs":{"opacity":0.4,"fill":"#000000","font-size":5,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.5,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1.5,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.9,"stroke-width":1,"filter":null},"#texture":{"opacity":0.39,"filter":null,"mask":""},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#dropShadow05)","layers":"-6,-3,-1"},"#oceanBase":{"fill":"#8dc1c8"},"#oceanicPattern":{"href":"./images/pattern1.png","opacity":0.2},"#terrs":{"opacity":0.4,"scheme":"light","terracing":10,"skip":5,"relax":0,"curve":0,"filter":"url(#turbulence)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":54.73,"data-y":62.98,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#3a3a3a","text-shadow":"white 0px 0px 4px","data-size":8,"font-size":8,"data-font":"IM+Fell+English","font-family":"IM Fell English"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":3,"stroke":"#3e3e4b","stroke-width":0.4,"stroke-dasharray":"0.5 0.25","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":5.5,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":4,"font-size":4,"data-font":"IM+Fell+English","font-family":"IM Fell English"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1.2,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":2.2,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e3e","stroke":"#000000","stroke-width":0.3,"text-shadow":"white 0px 0px 6px","data-size":14,"font-size":14,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#f24706","stroke":"#701b05","stroke-width":0.1,"text-shadow":"white 0px 0px 4px","data-size":6,"font-size":6,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#fogging":{"opacity":1,"fill":"#30426f","filter":null}}`, - styleWatercolor: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.2,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.6,"filter":null,"mask":null},"#stateBorders":{"opacity":0.6,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":3,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.5,"stroke":"#56566d","stroke-width":0.5,"stroke-dasharray":"0 2","stroke-linecap":"round","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#777777","stroke-width":0,"filter":"url(#bluredSplotch)"},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":"url(#splotch)"},"#landmass":{"opacity":1,"fill":"#eef6fb","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":1,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":null,"set":"gray","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#2e89c2"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#969696","stroke-width":0.4,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.05,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":8,"stroke-width":8,"filter":"blur(2px)"},"#provs":{"opacity":0.7,"fill":"#000000","font-size":4,"data-font":"Comfortaa:700","font-family":"Comfortaa","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.7,"fill":"#dfe8ec","stroke":"#000000","stroke-width":0,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.95,"stroke-width":1,"filter":null},"#texture":{"opacity":0.2,"filter":null,"mask":"url(#land)"},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#2d788b"},"#oceanicPattern":{"href":"./images/kiwiroo.png","opacity":0.5},"#terrs":{"opacity":0.5,"scheme":"light","terracing":0,"skip":5,"relax":1,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#043449","text-shadow":"white 0px 0px 2px","data-size":5,"font-size":5,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":3,"font-size":3,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#ffffff","stroke":"#000000","stroke-width":0.15,"text-shadow":"black 1px 1px 2px","data-size":20,"font-size":20,"data-font":"Gloria+Hallelujah","font-family":"Gloria Hallelujah","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":18,"font-size":18,"data-font":"Comfortaa","font-family":"Comfortaa","filter":null},"#fogging":{"opacity":0.97,"fill":"#8398ce","filter":null}}`, + styleClean: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.5,"filter":"url(#blur7)","mask":"url(#land)"},"#stateBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.09,"filter":null,"mask":"url(#land)"},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":3,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eeedeb","filter":null},"#markers":{"opacity":null,"rescale":null,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0,"fill":"#0080ff","filter":null},"#population":{"opacity":null,"stroke-width":2.58,"stroke-dasharray":0,"stroke-linecap":"butt","filter":"url(#blur3)"},"#rural":{"stroke":"#ff0000"},"#urban":{"stroke":"#800000"},"#freshwater":{"opacity":0.5,"fill":"#aadaff","stroke":"#5f799d","stroke-width":0,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#595959","stroke-width":0.4,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":1,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#aadaff"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#f6d068","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#ffffff","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#4f82c6","stroke-width":0.45,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":"url(#water)"},"#statesBody":{"opacity":0.3,"filter":null},"#statesHalo":{"opacity":0.5,"data-width":1,"stroke-width":1,"filter":null},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow01)"},"#emblems":{"opacity":1,"stroke-width":1,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.7,"stroke":"#ff6262","stroke-width":0,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#aadaff"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":0.5,"scheme":"bright","terracing":0,"skip":5,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":12.74,"font-size":12.74,"data-font":"Arial","font-family":"Arial","stroke":"#909090","stroke-width":1.13,"stroke-dasharray":0,"stroke-linecap":"round","data-x":98.39,"data-y":12.67,"data-columns":null},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#414141","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#303030","stroke-width":1.7},"#burgLabels > #towns":{"opacity":1,"fill":"#414141","data-size":3,"font-size":3,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.06},"#labels > #states":{"opacity":1,"fill":"#292929","stroke":"#303030","stroke-width":0,"text-shadow":"white 0 0 2px","data-size":10,"font-size":10,"data-font":"Arial","font-family":"Arial","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#414141","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Arial","font-family":"Arial","filter":null},"#fogging":{"opacity":1,"fill":"#ffffff","filter":null}}`, + styleLight: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.02,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":0.5,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#4c483e","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"square","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.5,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#808080","stroke-width":1,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":0.7,"data-size":15,"font-size":15,"stroke":"#734d37","stroke-width":1.5,"stroke-dasharray":5,"stroke-linecap":"square","filter":null,"mask":""},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.5,"stroke":null,"stroke-width":0,"filter":null},"#cults":{"opacity":0.5,"stroke":"#777777","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#f9f2ea","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":null},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#2554ef","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#98cdc4","stroke":"#719892","stroke-width":0.46,"filter":"url(#dropShadow05)"},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":1,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":1,"stroke":"#5e5e5e","stroke-width":0.4,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.6,"set":"colored","size":1,"density":0.3,"filter":null,"mask":""},"#rivers":{"opacity":null,"filter":null,"fill":"#6d94ba"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#3c1d0b","stroke-width":1.37,"stroke-dasharray":2,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#95481a","stroke-width":0.88,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.2,"filter":null},"#statesHalo":{"opacity":0.3,"data-width":25,"stroke-width":25,"filter":"blur(5px)"},"#provs":{"opacity":0.4,"fill":"#000000","font-size":5,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.5,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1.5,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.9,"stroke-width":1,"filter":null},"#texture":{"opacity":0.39,"filter":null,"mask":""},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#dropShadow05)","layers":"-6,-3,-1"},"#oceanBase":{"fill":"#8dc1c8"},"#oceanicPattern":{"href":"./images/pattern1.png","opacity":0.2},"#terrs":{"opacity":0.4,"scheme":"light","terracing":10,"skip":5,"relax":0,"curve":0,"filter":"url(#turbulence)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":54.73,"data-y":62.98,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#3a3a3a","text-shadow":"white 0px 0px 4px","data-size":8,"font-size":8,"data-font":"IM+Fell+English","font-family":"IM Fell English"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":3,"stroke":"#3e3e4b","stroke-width":0.4,"stroke-dasharray":"0.5 0.25","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":5.5,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":4,"font-size":4,"data-font":"IM+Fell+English","font-family":"IM Fell English"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1.2,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":2.2,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e3e","stroke":"#000000","stroke-width":0.3,"text-shadow":"white 0px 0px 6px","data-size":14,"font-size":14,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#f24706","stroke":"#701b05","stroke-width":0.1,"text-shadow":"white 0px 0px 4px","data-size":6,"font-size":6,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#fogging":{"opacity":1,"fill":"#30426f","filter":null}}`, + styleWatercolor: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.2,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.6,"filter":null,"mask":null},"#stateBorders":{"opacity":0.6,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":3,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.5,"stroke":"#56566d","stroke-width":0.5,"stroke-dasharray":"0 2","stroke-linecap":"round","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#777777","stroke-width":0,"filter":"url(#bluredSplotch)"},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":"url(#splotch)"},"#landmass":{"opacity":1,"fill":"#eef6fb","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":1,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":1,"set":"gray","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#2e89c2"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#969696","stroke-width":0.4,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.9,"stroke":"#969696","stroke-width":0.7,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.05,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":8,"stroke-width":8,"filter":"blur(2px)"},"#provs":{"opacity":0.7,"fill":"#000000","font-size":4,"data-font":"Comfortaa:700","font-family":"Comfortaa","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.7,"fill":"#dfe8ec","stroke":"#000000","stroke-width":0,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.95,"stroke-width":1,"filter":null},"#texture":{"opacity":0.2,"filter":null,"mask":"url(#land)"},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#2d788b"},"#oceanicPattern":{"href":"./images/kiwiroo.png","opacity":0.5},"#terrs":{"opacity":0.5,"scheme":"light","terracing":0,"skip":5,"relax":1,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#043449","text-shadow":"white 0px 0px 2px","data-size":5,"font-size":5,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":3,"font-size":3,"data-font":"Comfortaa:700","font-family":"Comfortaa"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#ffffff","stroke":"#000000","stroke-width":0.15,"text-shadow":"black 1px 1px 2px","data-size":20,"font-size":20,"data-font":"Gloria+Hallelujah","font-family":"Gloria Hallelujah","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":18,"font-size":18,"data-font":"Comfortaa","font-family":"Comfortaa","filter":null},"#fogging":{"opacity":0.97,"fill":"#8398ce","filter":null}}`, styleMonochrome: `{"#map":{"background-color":"#000000","filter":"url(#filter-grayscale)","data-filter":"grayscale"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":null},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.4,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#000000","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#000000","stroke":"#515151","stroke-width":0,"filter":null},"#salt":{"opacity":1,"fill":"#000000","stroke":"#484848","stroke-width":0,"filter":null},"#sinkhole":{"opacity":1,"fill":"#000000","stroke":"#5f5f5f","stroke-width":0.5,"filter":null},"#frozen":{"opacity":1,"fill":"#000000","stroke":"#6f6f6f","stroke-width":0,"filter":null},"#lava":{"opacity":1,"fill":"#000000","stroke":"#5d5d5d","stroke-width":0,"filter":null},"#sea_island":{"opacity":1,"stroke":"#1f3846","stroke-width":0,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":null,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":0.2,"filter":"url(#blur1)","fill":"#000000"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.7,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#d06324","stroke-width":0.25,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(5px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#texture":{"opacity":1,"filter":null,"mask":"url(#land)"},"#emblems": {"opacity": 0.5,"stroke-width": 0.5,"filter": null},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#000000"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"monochrome","terracing":0,"skip":5,"relax":0,"curve":0,"filter":"url(#blur3)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}` }; From 1f10a8e281c6d9190e2d9a22a2a0d2a9420bc339 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 17:53:22 +0300 Subject: [PATCH 15/82] fix font size settings --- main.js | 6 +++--- modules/ui/style.js | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/main.js b/main.js index f7346147..6e06fb1c 100644 --- a/main.js +++ b/main.js @@ -476,12 +476,12 @@ function invokeActiveZooming() { // rescale lables on zoom if (labels.style("display") !== "none") { - labels.selectAll("g").each(function (d) { + labels.selectAll("g").each(function () { if (this.id === "burgLabels") return; const desired = +this.dataset.size; const relative = Math.max(rn((desired + desired / scale) / 2, 2), 1); - this.getAttribute("font-size", relative); - const hidden = hideLabels.checked && (relative * scale < 6 || relative * scale > 50); + this.setAttribute("font-size", relative); + const hidden = hideLabels.checked && (relative * scale < 6 || relative * scale > 60); if (hidden) this.classList.add("hidden"); else this.classList.remove("hidden"); }); diff --git a/modules/ui/style.js b/modules/ui/style.js index 764ddda9..73a4c459 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -578,13 +578,21 @@ styleFontMinus.addEventListener("click", function () { }); function changeFontSize(size) { - const legend = styleElementSelect.value === "legend"; - const coords = styleElementSelect.value === "coordinates"; - - const desSize = legend ? size : coords ? rn(size / scale ** 0.8, 2) : rn(size + size / scale); - getEl().attr("data-size", size).attr("font-size", desSize); styleFontSize.value = size; - if (legend) redrawLegend(); + + const getSizeOnScale = element => { + // some labels are rescaled on zoom + if (element === "labels") return Math.max(rn((size + size / scale) / 2, 2), 1); + if (element === "coordinates") return rn(size / scale ** 0.8, 2); + + // other has the same size + return size; + }; + + const scaleSize = getSizeOnScale(styleElementSelect.value); + getEl().attr("data-size", size).attr("font-size", scaleSize); + + if (styleElementSelect.value === "legend") redrawLegend(); } styleRadiusInput.addEventListener("change", function () { From 2dd8628f2b35e0eb445cf96fb89ac3f60a8e03a9 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 17:59:31 +0300 Subject: [PATCH 16/82] fix font size change buttons --- index.html | 4 ++-- modules/ui/style.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index 843fdac9..a6bb70b9 100644 --- a/index.html +++ b/index.html @@ -676,8 +676,8 @@ diff --git a/modules/ui/style.js b/modules/ui/style.js index 73a4c459..b1c718fd 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -568,13 +568,13 @@ styleFontSize.addEventListener("change", function () { }); styleFontPlus.addEventListener("click", function () { - const size = Math.max(rn(getEl().attr("data-size") * 1.1, 2), 1); - changeFontSize(size); + const size = +getEl().attr("data-size") + 1; + changeFontSize(Math.min(size, 999)); }); styleFontMinus.addEventListener("click", function () { - const size = Math.max(rn(getEl().attr("data-size") * 0.9, 2), 1); - changeFontSize(size); + const size = +getEl().attr("data-size") - 1; + changeFontSize(Math.max(size, 1)); }); function changeFontSize(size) { From 5e6760ddd365fc4ed1211a9c63600e8e1bf33a13 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 18:36:17 +0300 Subject: [PATCH 17/82] fix old relief icons --- index.css | 4 ---- index.html | 10 +++++----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/index.css b/index.css index 849d66c0..f39b718f 100644 --- a/index.css +++ b/index.css @@ -2013,10 +2013,6 @@ svg.button { width: 16em; } -#reliefEditor input[type="number"] { - width: 3em; -} - #reliefIconsDiv { margin-top: 2px; padding: 2px; diff --git a/index.html b/index.html index a6bb70b9..5d82bab8 100644 --- a/index.html +++ b/index.html @@ -3539,12 +3539,12 @@ - - + + - - + + @@ -3561,7 +3561,7 @@ - + From cf269b775caeb7a32e18083b839b6335348848b4 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 19:23:13 +0300 Subject: [PATCH 18/82] ancient style update --- modules/ui/style.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui/style.js b/modules/ui/style.js index b1c718fd..6b9eb7d6 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -745,7 +745,7 @@ function fetchTextureURL(url) { } const defaultStyles = { - styleAncient: `{"#map":{"background-color":"#000000","filter":"url(#filter-sepia)","data-filter":"sepia"},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.05,"opacity":0.8,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":null,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eee9d7","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":1,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#5d97bb"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.8,"stroke":"#2e1607","stroke-width":1.23,"stroke-dasharray":3,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.8,"stroke":"#331809","stroke-width":0.5,"stroke-dasharray":"1 2","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.8,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(8px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.8,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#outline)"},"#emblems":{"opacity":0.6,"stroke-width":0.8,"filter":"url(#dropShadow05)"},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#blur5)","layers":"-6,-4,-2"},"#oceanBase":{"fill":"#a7a01f"},"#oceanicPattern":{"href":"./images/pattern1.png", "opacity":0.2},"#terrs":{"opacity":null,"scheme":"light","terracing":0,"skip":0,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":8,"font-size":8,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #cities":{"opacity":1,"fill":"#fdfab9","fill-opacity":0.7,"size":1,"stroke":"#54251d","stroke-width":0.3,"stroke-dasharray":".3 .4","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":4,"font-size":4,"data-font":"Almendra+SC","font-family":"Almendra SC"},"#burgIcons > #towns":{"opacity":1,"fill":"#fef4d8","fill-opacity":0.7,"size":0.5,"stroke":"#463124","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`, + styleAncient: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.2,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.5,"transform":null,"filter":"url(#filter-sepia)","mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e3dfce","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":""},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":1,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":"","fill":"#a69b7d"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.7,"stroke":"#8d502a","stroke-width":1,"stroke-dasharray":3,"stroke-linecap":"inherit","filter":"","mask":null},"#trails":{"opacity":0.7,"stroke":"#924217","stroke-width":0.5,"stroke-dasharray":"1 2","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#b16925","stroke-width":0.8,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.2,"filter":"url(#filter-sepia)"},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(6px)"},"#provs":{"opacity":0.7,"fill":"#000000","font-size":10,"data-font":"Georgia","font-family":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.35,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":3,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.8,"stroke-width":0.8,"filter":"url(#dropShadow05)"},"#texture":{"opacity":0.6,"filter":"","mask":""},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"","layers":"-6,-4,-2"},"#oceanBase":{"fill":"#c99f64"},"#oceanicPattern":{"href":"./images/kiwiroo.png","opacity":0.4},"#terrs":{"opacity":null,"scheme":"bright","terracing":0,"skip":2,"relax":1,"curve":0,"filter":"url(#blur3)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":12,"font-size":12,"data-font":"Great+Vibes","font-family":"Great Vibes"},"#burgIcons > #cities":{"opacity":1,"fill":"#fdfab9","fill-opacity":0.7,"size":1,"stroke":"#6f4e1f","stroke-width":0.3,"stroke-dasharray":".3 .4","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":5,"font-size":5,"data-font":"Great+Vibes","font-family":"Great Vibes"},"#burgIcons > #towns":{"opacity":1,"fill":"#fef4d8","fill-opacity":0.7,"size":0.5,"stroke":"#72472c","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":22,"font-size":22,"data-font":"Great+Vibes","font-family":"Great Vibes","filter":"url(#filter-sepia)"},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":18,"font-size":18,"data-font":"Times+New+Roman","font-family":"Times New Roman","filter":"url(#filter-sepia)"},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`, styleGloom: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":"url(#land)"},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.3,"stroke-dasharray":".7 1","stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":14,"font-size":14,"stroke":"#4a4a4a","stroke-width":1,"stroke-dasharray":6,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(100 100) scale(0.3)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":1,"filter":null},"#cults":{"opacity":0.7,"stroke":"#777777","stroke-width":1.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e0e0e0","filter":null},"#markers":{"opacity":0.8,"rescale":1,"filter":"url(#dropShadow05)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000aa"},"#urban":{"stroke":"#9d0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.9,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#779582"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":1,"stroke":"#8b4418","stroke-width":0.9,"stroke-dasharray":"2 3","stroke-linecap":"round","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#844017","stroke-width":0.2,"stroke-dasharray":".5 1","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#5e1865","stroke-width":0.6,"stroke-dasharray":"1.2 2.4","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.5,"data-width":12,"stroke-width":12,"filter":"blur(10px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":1,"font-size":"11px","fill":"#62001b","fill-opacity":0.3,"stroke":null,"stroke-width":2,"stroke-dasharray":2,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#emblems": {"opacity":0.6,"stroke-width":0.5,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.5,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":"url(#dropShadow01)","mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#4e6964"},"#oceanicPattern":{"href":"./images/pattern3.png", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"bright","terracing":0,"skip":0,"relax":1,"curve":1,"filter":"url(#filter-grayscale)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":2,"stroke":"#444444","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":0.8,"fill":"#ffffff","size":4,"stroke":"#3e3e4b","stroke-width":1},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":3,"font-size":3,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #towns":{"opacity":0.95,"fill":"#ffffff","fill-opacity":0.7,"size":0.8,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1.6,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#4e4e4e","stroke":"#b5b5b5","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#1b1423","filter":null}}`, styleClean: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.5,"filter":"url(#blur7)","mask":"url(#land)"},"#stateBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.09,"filter":null,"mask":"url(#land)"},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":3,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eeedeb","filter":null},"#markers":{"opacity":null,"rescale":null,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0,"fill":"#0080ff","filter":null},"#population":{"opacity":null,"stroke-width":2.58,"stroke-dasharray":0,"stroke-linecap":"butt","filter":"url(#blur3)"},"#rural":{"stroke":"#ff0000"},"#urban":{"stroke":"#800000"},"#freshwater":{"opacity":0.5,"fill":"#aadaff","stroke":"#5f799d","stroke-width":0,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#595959","stroke-width":0.4,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":1,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#aadaff"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#f6d068","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#ffffff","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#4f82c6","stroke-width":0.45,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":"url(#water)"},"#statesBody":{"opacity":0.3,"filter":null},"#statesHalo":{"opacity":0.5,"data-width":1,"stroke-width":1,"filter":null},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow01)"},"#emblems":{"opacity":1,"stroke-width":1,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.7,"stroke":"#ff6262","stroke-width":0,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#aadaff"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":0.5,"scheme":"bright","terracing":0,"skip":5,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":12.74,"font-size":12.74,"data-font":"Arial","font-family":"Arial","stroke":"#909090","stroke-width":1.13,"stroke-dasharray":0,"stroke-linecap":"round","data-x":98.39,"data-y":12.67,"data-columns":null},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#414141","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#303030","stroke-width":1.7},"#burgLabels > #towns":{"opacity":1,"fill":"#414141","data-size":3,"font-size":3,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.06},"#labels > #states":{"opacity":1,"fill":"#292929","stroke":"#303030","stroke-width":0,"text-shadow":"white 0 0 2px","data-size":10,"font-size":10,"data-font":"Arial","font-family":"Arial","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#414141","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Arial","font-family":"Arial","filter":null},"#fogging":{"opacity":1,"fill":"#ffffff","filter":null}}`, styleLight: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.02,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":0.5,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#4c483e","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"square","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.5,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#808080","stroke-width":1,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":0.7,"data-size":15,"font-size":15,"stroke":"#734d37","stroke-width":1.5,"stroke-dasharray":5,"stroke-linecap":"square","filter":null,"mask":""},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.5,"stroke":null,"stroke-width":0,"filter":null},"#cults":{"opacity":0.5,"stroke":"#777777","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#f9f2ea","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":null},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#2554ef","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#98cdc4","stroke":"#719892","stroke-width":0.46,"filter":"url(#dropShadow05)"},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":1,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":1,"stroke":"#5e5e5e","stroke-width":0.4,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.6,"set":"colored","size":1,"density":0.3,"filter":null,"mask":""},"#rivers":{"opacity":null,"filter":null,"fill":"#6d94ba"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#3c1d0b","stroke-width":1.37,"stroke-dasharray":2,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#95481a","stroke-width":0.88,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.2,"filter":null},"#statesHalo":{"opacity":0.3,"data-width":25,"stroke-width":25,"filter":"blur(5px)"},"#provs":{"opacity":0.4,"fill":"#000000","font-size":5,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.5,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1.5,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.9,"stroke-width":1,"filter":null},"#texture":{"opacity":0.39,"filter":null,"mask":""},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#dropShadow05)","layers":"-6,-3,-1"},"#oceanBase":{"fill":"#8dc1c8"},"#oceanicPattern":{"href":"./images/pattern1.png","opacity":0.2},"#terrs":{"opacity":0.4,"scheme":"light","terracing":10,"skip":5,"relax":0,"curve":0,"filter":"url(#turbulence)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":54.73,"data-y":62.98,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#3a3a3a","text-shadow":"white 0px 0px 4px","data-size":8,"font-size":8,"data-font":"IM+Fell+English","font-family":"IM Fell English"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":3,"stroke":"#3e3e4b","stroke-width":0.4,"stroke-dasharray":"0.5 0.25","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":5.5,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":4,"font-size":4,"data-font":"IM+Fell+English","font-family":"IM Fell English"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1.2,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":2.2,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e3e","stroke":"#000000","stroke-width":0.3,"text-shadow":"white 0px 0px 6px","data-size":14,"font-size":14,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#f24706","stroke":"#701b05","stroke-width":0.1,"text-shadow":"white 0px 0px 4px","data-size":6,"font-size":6,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#fogging":{"opacity":1,"fill":"#30426f","filter":null}}`, From 99dd005e5cc59167d1f4b1c720089f59ee8b12a3 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 19:35:43 +0300 Subject: [PATCH 19/82] load fonts on style set change --- index.html | 1 + modules/fonts.js | 63 +++++++++++++++++++++++++++++++++++++++++++++ modules/load.js | 9 +------ modules/save.js | 53 -------------------------------------- modules/ui/style.js | 7 +++-- 5 files changed, 68 insertions(+), 65 deletions(-) create mode 100644 modules/fonts.js diff --git a/index.html b/index.html index 5d82bab8..4bd3e984 100644 --- a/index.html +++ b/index.html @@ -4176,6 +4176,7 @@ + diff --git a/modules/fonts.js b/modules/fonts.js new file mode 100644 index 00000000..d2082929 --- /dev/null +++ b/modules/fonts.js @@ -0,0 +1,63 @@ +// helper finction to work with fonts + +function loadUsedFonts() { + const fontsInUse = getFontsList(svg); + const fontsToLoad = fontsInUse.filter(font => !fonts.includes(font)); + if (fontsToLoad) { + const url = "https://fonts.googleapis.com/css?family=" + fontsToLoad.join("|"); + addFonts(url); + } +} + +function getFontsList(svg) { + const fontsInUse = []; + + svg.selectAll("#labels > g").each(function () { + if (!this.hasChildNodes()) return; + const font = this.dataset.font; + if (font) fontsInUse.push(font); + }); + if (legend.node().hasChildNodes()) fontsInUse.push(legend.attr("data-font")); + + return [...new Set(fontsInUse)]; +} + +// code from Kaiido's answer https://stackoverflow.com/questions/42402584/how-to-use-google-fonts-in-canvas-when-drawing-dom-objects-in-svg +function GFontToDataURI(url) { + if (!url) return Promise.resolve(); + return fetch(url) // first fecth the embed stylesheet page + .then(resp => resp.text()) // we only need the text of it + .then(text => { + let s = document.createElement("style"); + s.innerHTML = text; + document.head.appendChild(s); + const styleSheet = Array.prototype.filter.call(document.styleSheets, sS => sS.ownerNode === s)[0]; + + const FontRule = rule => { + const src = rule.style.getPropertyValue("src"); + const url = src ? src.split("url(")[1].split(")")[0] : ""; + return {rule, src, url: url.substring(url.length - 1, 1)}; + }; + const fontProms = []; + + for (const r of styleSheet.cssRules) { + let fR = FontRule(r); + if (!fR.url) continue; + + fontProms.push( + fetch(fR.url) // fetch the actual font-file (.woff) + .then(resp => resp.blob()) + .then(blob => { + return new Promise(resolve => { + let f = new FileReader(); + f.onload = e => resolve(f.result); + f.readAsDataURL(blob); + }); + }) + .then(dataURL => fR.rule.cssText.replace(fR.url, dataURL)) + ); + } + document.head.removeChild(s); // clean up + return Promise.all(fontProms); // wait for all this has been done + }); +} diff --git a/modules/load.js b/modules/load.js index cec66434..04a7a01b 100644 --- a/modules/load.js +++ b/modules/load.js @@ -221,14 +221,7 @@ function parseLoadedData(data) { burgLabels = labels.select("#burgLabels"); })(); - void (function loadUsedFonts() { - const fontsInUse = getFontsList(svg); - const fontsToLoad = fontsInUse.filter(font => !fonts.includes(font)); - if (fontsToLoad) { - const url = "https://fonts.googleapis.com/css?family=" + fontsToLoad.join("|"); - addFonts(url); - } - })(); + loadUsedFonts(); void (function parseGridData() { grid = JSON.parse(data[6]); diff --git a/modules/save.js b/modules/save.js index c0ac85ea..24fa55dc 100644 --- a/modules/save.js +++ b/modules/save.js @@ -359,59 +359,6 @@ function inlineStyle(clone) { emptyG.remove(); } -function getFontsList(svg) { - const fontsInUse = []; - - svg.selectAll("#labels > g").each(function () { - if (!this.hasChildNodes()) return; - const font = this.dataset.font; - if (font) fontsInUse.push(font); - }); - if (legend.node().hasChildNodes()) fontsInUse.push(legend.attr("data-font")); - - return [...new Set(fontsInUse)]; -} - -// code from Kaiido's answer https://stackoverflow.com/questions/42402584/how-to-use-google-fonts-in-canvas-when-drawing-dom-objects-in-svg -function GFontToDataURI(url) { - if (!url) return Promise.resolve(); - return fetch(url) // first fecth the embed stylesheet page - .then(resp => resp.text()) // we only need the text of it - .then(text => { - let s = document.createElement("style"); - s.innerHTML = text; - document.head.appendChild(s); - const styleSheet = Array.prototype.filter.call(document.styleSheets, sS => sS.ownerNode === s)[0]; - - const FontRule = rule => { - const src = rule.style.getPropertyValue("src"); - const url = src ? src.split("url(")[1].split(")")[0] : ""; - return {rule, src, url: url.substring(url.length - 1, 1)}; - }; - const fontProms = []; - - for (const r of styleSheet.cssRules) { - let fR = FontRule(r); - if (!fR.url) continue; - - fontProms.push( - fetch(fR.url) // fetch the actual font-file (.woff) - .then(resp => resp.blob()) - .then(blob => { - return new Promise(resolve => { - let f = new FileReader(); - f.onload = e => resolve(f.result); - f.readAsDataURL(blob); - }); - }) - .then(dataURL => fR.rule.cssText.replace(fR.url, dataURL)) - ); - } - document.head.removeChild(s); // clean up - return Promise.all(fontProms); // wait for all this has been done - }); -} - // prepare map data for saving function getMapData() { TIME && console.time("createMapDataBlob"); diff --git a/modules/ui/style.js b/modules/ui/style.js index 6b9eb7d6..58029969 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -879,10 +879,8 @@ function applyStyle(style) { // change current style preset to another saved one function changeStylePreset(preset) { - if (customization) { - tip("Please exit the customization mode first", false, "error"); - return; - } + if (customization) return tip("Please exit the customization mode first", false, "error"); + alertMessage.innerHTML = "Are you sure you want to change the style preset? All unsaved style changes will be lost"; $("#alert").dialog({ resizable: false, @@ -899,6 +897,7 @@ function changeStylePreset(preset) { } } else if (defaultStyles[preset]) applyStyle(JSON.parse(defaultStyles[preset])); else applyDefaultStyle(); + loadUsedFonts(); removeStyleButton.style.display = stylePreset.selectedOptions[0].dataset.system ? "none" : "inline-block"; updateElements(); // change elements From 1ae6d73f9476c3a0463b04ef01837df5805bf496 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 19:39:03 +0300 Subject: [PATCH 20/82] move fonts function to a separate file --- modules/fonts.js | 80 ++++++++++++++++++++++++++++++++++++++++++++- modules/ui/style.js | 78 ------------------------------------------- 2 files changed, 79 insertions(+), 79 deletions(-) diff --git a/modules/fonts.js b/modules/fonts.js index d2082929..9ce75d77 100644 --- a/modules/fonts.js +++ b/modules/fonts.js @@ -1,4 +1,34 @@ -// helper finction to work with fonts +// helper finctions to work with fonts + +async function addFonts(url) { + $("head").append(''); + try { + const resp = await fetch(url); + const text = await resp.text(); + let s = document.createElement("style"); + s.innerHTML = text; + document.head.appendChild(s); + let styleSheet = Array.prototype.filter.call(document.styleSheets, sS => sS.ownerNode === s)[0]; + let FontRule = rule_1 => { + let family = rule_1.style.getPropertyValue("font-family"); + let font = family.replace(/['"]+/g, "").replace(/ /g, "+"); + let weight = rule_1.style.getPropertyValue("font-weight"); + if (weight && weight !== "400") font += ":" + weight; + if (fonts.indexOf(font) == -1) { + fonts.push(font); + fetched++; + } + }; + let fetched = 0; + for (let r of styleSheet.cssRules) { + FontRule(r); + } + document.head.removeChild(s); + return fetched; + } catch (err) { + return ERROR && console.error(err); + } +} function loadUsedFonts() { const fontsInUse = getFontsList(svg); @@ -61,3 +91,51 @@ function GFontToDataURI(url) { return Promise.all(fontProms); // wait for all this has been done }); } + +// fetch default fonts if not done before +function loadDefaultFonts() { + if (!$('link[href="fonts.css"]').length) { + $("head").append(''); + const fontsToAdd = ["Amatic+SC:700", "IM+Fell+English", "Great+Vibes", "MedievalSharp", "Metamorphous", "Nova+Script", "Uncial+Antiqua", "Underdog", "Caesar+Dressing", "Bitter", "Yellowtail", "Montez", "Shadows+Into+Light", "Fredericka+the+Great", "Orbitron", "Dancing+Script:700", "Architects+Daughter", "Kaushan+Script", "Gloria+Hallelujah", "Satisfy", "Comfortaa:700", "Cinzel"]; + fontsToAdd.forEach(function (f) { + if (fonts.indexOf(f) === -1) fonts.push(f); + }); + updateFontOptions(); + } +} + +function fetchFonts(url) { + return new Promise((resolve, reject) => { + if (url === "") return tip("Use a direct link to any @font-face declaration or just font name to fetch from Google Fonts"); + + if (url.indexOf("http") === -1) { + url = url.replace(url.charAt(0), url.charAt(0).toUpperCase()).split(" ").join("+"); + url = "https://fonts.googleapis.com/css?family=" + url; + } + + addFonts(url).then(fetched => { + if (fetched === undefined) return tip("Cannot fetch font for this value!", false, "error"); + if (fetched === 0) return tip("Already in the fonts list!", false, "error"); + + updateFontOptions(); + if (fetched === 1) { + tip("Font " + fonts[fonts.length - 1] + " is fetched"); + } else if (fetched > 1) { + tip(fetched + " fonts are added to the list"); + } + resolve(fetched); + }); + }); +} + +// Update font list for Label and Burg Editors +function updateFontOptions() { + styleSelectFont.innerHTML = ""; + for (let i = 0; i < fonts.length; i++) { + const opt = document.createElement("option"); + opt.value = i; + const font = fonts[i].split(":")[0].replace(/\+/g, " "); + opt.style.fontFamily = opt.innerHTML = font; + styleSelectFont.add(opt); + } +} diff --git a/modules/ui/style.js b/modules/ui/style.js index 58029969..60be6286 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -1134,81 +1134,3 @@ function updateMapFilter() { if (!filter) return; mapFilters.querySelector("#" + filter).classList.add("pressed"); } - -// FONTS -// fetch default fonts if not done before -function loadDefaultFonts() { - if (!$('link[href="fonts.css"]').length) { - $("head").append(''); - const fontsToAdd = ["Amatic+SC:700", "IM+Fell+English", "Great+Vibes", "MedievalSharp", "Metamorphous", "Nova+Script", "Uncial+Antiqua", "Underdog", "Caesar+Dressing", "Bitter", "Yellowtail", "Montez", "Shadows+Into+Light", "Fredericka+the+Great", "Orbitron", "Dancing+Script:700", "Architects+Daughter", "Kaushan+Script", "Gloria+Hallelujah", "Satisfy", "Comfortaa:700", "Cinzel"]; - fontsToAdd.forEach(function (f) { - if (fonts.indexOf(f) === -1) fonts.push(f); - }); - updateFontOptions(); - } -} - -function fetchFonts(url) { - return new Promise((resolve, reject) => { - if (url === "") return tip("Use a direct link to any @font-face declaration or just font name to fetch from Google Fonts"); - - if (url.indexOf("http") === -1) { - url = url.replace(url.charAt(0), url.charAt(0).toUpperCase()).split(" ").join("+"); - url = "https://fonts.googleapis.com/css?family=" + url; - } - - addFonts(url).then(fetched => { - if (fetched === undefined) return tip("Cannot fetch font for this value!", false, "error"); - if (fetched === 0) return tip("Already in the fonts list!", false, "error"); - - updateFontOptions(); - if (fetched === 1) { - tip("Font " + fonts[fonts.length - 1] + " is fetched"); - } else if (fetched > 1) { - tip(fetched + " fonts are added to the list"); - } - resolve(fetched); - }); - }); -} - -function addFonts(url) { - $("head").append(''); - return fetch(url) - .then(resp => resp.text()) - .then(text => { - let s = document.createElement("style"); - s.innerHTML = text; - document.head.appendChild(s); - let styleSheet = Array.prototype.filter.call(document.styleSheets, sS => sS.ownerNode === s)[0]; - let FontRule = rule => { - let family = rule.style.getPropertyValue("font-family"); - let font = family.replace(/['"]+/g, "").replace(/ /g, "+"); - let weight = rule.style.getPropertyValue("font-weight"); - if (weight && weight !== "400") font += ":" + weight; - if (fonts.indexOf(font) == -1) { - fonts.push(font); - fetched++; - } - }; - let fetched = 0; - for (let r of styleSheet.cssRules) { - FontRule(r); - } - document.head.removeChild(s); - return fetched; - }) - .catch(err => ERROR && console.error(err)); -} - -// Update font list for Label and Burg Editors -function updateFontOptions() { - styleSelectFont.innerHTML = ""; - for (let i = 0; i < fonts.length; i++) { - const opt = document.createElement("option"); - opt.value = i; - const font = fonts[i].split(":")[0].replace(/\+/g, " "); - opt.style.fontFamily = opt.innerHTML = font; - styleSelectFont.add(opt); - } -} From 9df7b2f7a5a47494f7e63f4490ff5a8592dd0f23 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 11 Jul 2021 20:16:38 +0300 Subject: [PATCH 21/82] lake style for ancient set --- modules/ui/style.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui/style.js b/modules/ui/style.js index 60be6286..36e35ddc 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -745,7 +745,7 @@ function fetchTextureURL(url) { } const defaultStyles = { - styleAncient: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.2,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.5,"transform":null,"filter":"url(#filter-sepia)","mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e3dfce","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":""},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":1,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":"","fill":"#a69b7d"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.7,"stroke":"#8d502a","stroke-width":1,"stroke-dasharray":3,"stroke-linecap":"inherit","filter":"","mask":null},"#trails":{"opacity":0.7,"stroke":"#924217","stroke-width":0.5,"stroke-dasharray":"1 2","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#b16925","stroke-width":0.8,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.2,"filter":"url(#filter-sepia)"},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(6px)"},"#provs":{"opacity":0.7,"fill":"#000000","font-size":10,"data-font":"Georgia","font-family":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.35,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":3,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.8,"stroke-width":0.8,"filter":"url(#dropShadow05)"},"#texture":{"opacity":0.6,"filter":"","mask":""},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"","layers":"-6,-4,-2"},"#oceanBase":{"fill":"#c99f64"},"#oceanicPattern":{"href":"./images/kiwiroo.png","opacity":0.4},"#terrs":{"opacity":null,"scheme":"bright","terracing":0,"skip":2,"relax":1,"curve":0,"filter":"url(#blur3)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":12,"font-size":12,"data-font":"Great+Vibes","font-family":"Great Vibes"},"#burgIcons > #cities":{"opacity":1,"fill":"#fdfab9","fill-opacity":0.7,"size":1,"stroke":"#6f4e1f","stroke-width":0.3,"stroke-dasharray":".3 .4","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":5,"font-size":5,"data-font":"Great+Vibes","font-family":"Great Vibes"},"#burgIcons > #towns":{"opacity":1,"fill":"#fef4d8","fill-opacity":0.7,"size":0.5,"stroke":"#72472c","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":22,"font-size":22,"data-font":"Great+Vibes","font-family":"Great Vibes","filter":"url(#filter-sepia)"},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":18,"font-size":18,"data-font":"Times+New+Roman","font-family":"Times New Roman","filter":"url(#filter-sepia)"},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`, + styleAncient: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.2,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#d4d4d4","stroke-width":1,"stroke-dasharray":5,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.5,"transform":null,"filter":"url(#filter-sepia)","mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(80 80) scale(.25)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e3dfce","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":""},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":0.6,"fill":"#c8d6e0","stroke":"#968d6e","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#339482","stroke":"#836a34","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#c3d6df","stroke":"#b29062","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#a04e18","stroke":"#835520","stroke-width":2,"filter":"url(#paper)"},"#dry":{"opacity":0.7,"fill":"#c6b795","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.5,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":1,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":"","fill":"#a69b7d"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.7,"stroke":"#8d502a","stroke-width":1,"stroke-dasharray":3,"stroke-linecap":"inherit","filter":"","mask":null},"#trails":{"opacity":0.7,"stroke":"#924217","stroke-width":0.5,"stroke-dasharray":"1 2","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#b16925","stroke-width":0.8,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.2,"filter":"url(#filter-sepia)"},"#statesHalo":{"opacity":0.4,"data-width":10,"stroke-width":10,"filter":"blur(6px)"},"#provs":{"opacity":0.7,"fill":"#000000","font-size":10,"data-font":"Georgia","font-family":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.35,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":3,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.8,"stroke-width":0.8,"filter":"url(#dropShadow05)"},"#texture":{"opacity":0.6,"filter":"","mask":""},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"","layers":"-6,-4,-2"},"#oceanBase":{"fill":"#c99f64"},"#oceanicPattern":{"href":"./images/kiwiroo.png","opacity":0.4},"#terrs":{"opacity":null,"scheme":"bright","terracing":0,"skip":2,"relax":1,"curve":0,"filter":"url(#blur3)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":12,"font-size":12,"data-font":"Great+Vibes","font-family":"Great Vibes"},"#burgIcons > #cities":{"opacity":1,"fill":"#fdfab9","fill-opacity":0.7,"size":1,"stroke":"#6f4e1f","stroke-width":0.3,"stroke-dasharray":".3 .4","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":5,"font-size":5,"data-font":"Great+Vibes","font-family":"Great Vibes"},"#burgIcons > #towns":{"opacity":1,"fill":"#fef4d8","fill-opacity":0.7,"size":0.5,"stroke":"#72472c","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":22,"font-size":22,"data-font":"Great+Vibes","font-family":"Great Vibes","filter":"url(#filter-sepia)"},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0px 0px 4px","data-size":18,"font-size":18,"data-font":"Times+New+Roman","font-family":"Times New Roman","filter":"url(#filter-sepia)"},"#fogging":{"opacity":0.98,"fill":"#30426f","filter":null}}`, styleGloom: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0.3,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":null,"filter":"url(#blur5)","mask":"url(#land)"},"#stateBorders":{"opacity":1,"stroke":"#56566d","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":1,"stroke":"#56566d","stroke-width":0.3,"stroke-dasharray":".7 1","stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":14,"font-size":14,"stroke":"#4a4a4a","stroke-width":1,"stroke-dasharray":6,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":"translate(100 100) scale(0.3)"},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":1,"filter":null},"#cults":{"opacity":0.7,"stroke":"#777777","stroke-width":1.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#e0e0e0","filter":null},"#markers":{"opacity":0.8,"rescale":1,"filter":"url(#dropShadow05)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#003dff","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000aa"},"#urban":{"stroke":"#9d0000"},"#freshwater":{"opacity":0.5,"fill":"#a6c1fd","stroke":"#5f799d","stroke-width":0.7,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#1f3846","stroke-width":0.7,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.9,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#779582"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":1,"stroke":"#8b4418","stroke-width":0.9,"stroke-dasharray":"2 3","stroke-linecap":"round","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#844017","stroke-width":0.2,"stroke-dasharray":".5 1","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#5e1865","stroke-width":0.6,"stroke-dasharray":"1.2 2.4","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.4,"filter":null},"#statesHalo":{"opacity":0.5,"data-width":12,"stroke-width":12,"filter":"blur(10px)"},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":1,"font-size":"11px","fill":"#62001b","fill-opacity":0.3,"stroke":null,"stroke-width":2,"stroke-dasharray":2,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow05)"},"#emblems": {"opacity":0.6,"stroke-width":0.5,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{"x":0,"y":0},"#zones":{"opacity":0.5,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":"url(#dropShadow01)","mask":null},"#oceanLayers":{"filter":null,"layers":"-6,-4,-2"},"#oceanBase":{"fill":"#4e6964"},"#oceanicPattern":{"href":"./images/pattern3.png", "opacity":0.2},"#terrs":{"opacity":1,"scheme":"bright","terracing":0,"skip":0,"relax":1,"curve":1,"filter":"url(#filter-grayscale)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":99,"data-y":93,"data-columns":8},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":2,"stroke":"#444444","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":0.8,"fill":"#ffffff","size":4,"stroke":"#3e3e4b","stroke-width":1},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","data-size":3,"font-size":3,"data-font":"Bitter","font-family":"Bitter"},"#burgIcons > #towns":{"opacity":0.95,"fill":"#ffffff","fill-opacity":0.7,"size":0.8,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1.6,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#4e4e4e","stroke":"#b5b5b5","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":22,"font-size":22,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#3e3e4b","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Almendra+SC","font-family":"Almendra SC","filter":null},"#fogging":{"opacity":0.98,"fill":"#1b1423","filter":null}}`, styleClean: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":6,"box-size":3,"stroke":"#000","stroke-width":0,"opacity":1,"fill-opacity":1,"filter":null},"#biomes":{"opacity":0.5,"filter":"url(#blur7)","mask":"url(#land)"},"#stateBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"butt","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.09,"filter":null,"mask":"url(#land)"},"#gridOverlay":{"opacity":0.8,"scale":1,"dx":0,"dy":"0","type":"pointyHex","stroke":"#808080","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":1,"data-size":12,"font-size":12,"stroke":"#414141","stroke-width":0.45,"stroke-dasharray":3,"stroke-linecap":null,"filter":null,"mask":null},"#compass":{"opacity":0.8,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.7,"stroke":"#404040","stroke-width":0.7,"filter":null},"#cults":{"opacity":0.6,"stroke":"#777777","stroke-width":0.5,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#eeedeb","filter":null},"#markers":{"opacity":null,"rescale":null,"filter":"url(#dropShadow01)"},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0,"fill":"#0080ff","filter":null},"#population":{"opacity":null,"stroke-width":2.58,"stroke-dasharray":0,"stroke-linecap":"butt","filter":"url(#blur3)"},"#rural":{"stroke":"#ff0000"},"#urban":{"stroke":"#800000"},"#freshwater":{"opacity":0.5,"fill":"#aadaff","stroke":"#5f799d","stroke-width":0,"filter":null},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":0.7,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":0.6,"stroke":"#595959","stroke-width":0.4,"filter":null,"auto-filter":0},"#lake_island":{"opacity":0,"stroke":"#7c8eaf","stroke-width":0,"filter":null},"#terrain":{"opacity":1,"set":"simple","size":1,"density":0.4,"filter":null,"mask":null},"#rivers":{"opacity":null,"filter":null,"fill":"#aadaff"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#f6d068","stroke-width":0.7,"stroke-dasharray":0,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":1,"stroke":"#ffffff","stroke-width":0.25,"stroke-dasharray":"","stroke-linecap":"round","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#4f82c6","stroke-width":0.45,"stroke-dasharray":2,"stroke-linecap":"butt","filter":null,"mask":"url(#water)"},"#statesBody":{"opacity":0.3,"filter":null},"#statesHalo":{"opacity":0.5,"data-width":1,"stroke-width":1,"filter":null},"#provs":{"opacity":0.7,"fill":"#000000","data-size":10,"font-size":10,"font-family":"Georgia","data-font":"Georgia","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.9,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1,"filter":"url(#dropShadow01)"},"#emblems":{"opacity":1,"stroke-width":1,"filter":null},"#texture":{"opacity":null,"filter":null,"mask":"url(#land)"},"#textureImage":{},"#zones":{"opacity":0.7,"stroke":"#ff6262","stroke-width":0,"stroke-dasharray":"","stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":null,"layers":"none"},"#oceanBase":{"fill":"#aadaff"},"#oceanicPattern":{"href":"", "opacity":0.2},"#terrs":{"opacity":0.5,"scheme":"bright","terracing":0,"skip":5,"relax":0,"curve":0,"filter":null,"mask":"url(#land)"},"#legend":{"data-size":12.74,"font-size":12.74,"data-font":"Arial","font-family":"Arial","stroke":"#909090","stroke-width":1.13,"stroke-dasharray":0,"stroke-linecap":"round","data-x":98.39,"data-y":12.67,"data-columns":null},"#legendBox":{},"#burgLabels > #cities":{"opacity":1,"fill":"#414141","text-shadow":"white 0 0 4px","data-size":7,"font-size":7,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1,"stroke":"#3e3e4b","stroke-width":0.24,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":2,"stroke":"#303030","stroke-width":1.7},"#burgLabels > #towns":{"opacity":1,"fill":"#414141","data-size":3,"font-size":3,"data-font":"Arial","font-family":"Arial"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":0.5,"stroke":"#3e3e4b","stroke-width":0.12,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":1,"stroke":"#3e3e4b","stroke-width":1.06},"#labels > #states":{"opacity":1,"fill":"#292929","stroke":"#303030","stroke-width":0,"text-shadow":"white 0 0 2px","data-size":10,"font-size":10,"data-font":"Arial","font-family":"Arial","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#414141","stroke":"#3a3a3a","stroke-width":0,"text-shadow":"white 0 0 4px","data-size":18,"font-size":18,"data-font":"Arial","font-family":"Arial","filter":null},"#fogging":{"opacity":1,"fill":"#ffffff","filter":null}}`, styleLight: `{"#map":{"background-color":"#000000","filter":null,"data-filter":null},"#armies":{"font-size":8,"box-size":4,"stroke":"#000","stroke-width":0.02,"fill-opacity":0.8,"filter":null},"#biomes":{"opacity":0.5,"filter":null,"mask":null},"#stateBorders":{"opacity":0.8,"stroke":"#4c483e","stroke-width":1,"stroke-dasharray":2,"stroke-linecap":"square","filter":null},"#provinceBorders":{"opacity":0.8,"stroke":"#56566d","stroke-width":0.2,"stroke-dasharray":1,"stroke-linecap":"butt","filter":null},"#cells":{"opacity":null,"stroke":"#808080","stroke-width":0.1,"filter":null,"mask":null},"#gridOverlay":{"opacity":0.5,"scale":1,"dx":0,"dy":0,"type":"pointyHex","stroke":"#808080","stroke-width":1,"stroke-dasharray":null,"stroke-linecap":null,"transform":null,"filter":null,"mask":null},"#coordinates":{"opacity":0.7,"data-size":15,"font-size":15,"stroke":"#734d37","stroke-width":1.5,"stroke-dasharray":5,"stroke-linecap":"square","filter":null,"mask":""},"#compass":{"opacity":0.6,"transform":null,"filter":null,"mask":"url(#water)","shape-rendering":"optimizespeed"},"#rose":{"transform":null},"#relig":{"opacity":0.5,"stroke":null,"stroke-width":0,"filter":null},"#cults":{"opacity":0.5,"stroke":"#777777","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#landmass":{"opacity":1,"fill":"#f9f2ea","filter":null},"#markers":{"opacity":null,"rescale":1,"filter":null},"#prec":{"opacity":null,"stroke":"#000000","stroke-width":0.1,"fill":"#2554ef","filter":null},"#population":{"opacity":null,"stroke-width":1.6,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null},"#rural":{"stroke":"#0000ff"},"#urban":{"stroke":"#ff0000"},"#freshwater":{"opacity":1,"fill":"#98cdc4","stroke":"#719892","stroke-width":0.46,"filter":"url(#dropShadow05)"},"#salt":{"opacity":0.5,"fill":"#409b8a","stroke":"#388985","stroke-width":0.7,"filter":null},"#sinkhole":{"opacity":1,"fill":"#5bc9fd","stroke":"#53a3b0","stroke-width":0.7,"filter":null},"#frozen":{"opacity":0.95,"fill":"#cdd4e7","stroke":"#cfe0eb","stroke-width":0,"filter":null},"#lava":{"opacity":0.7,"fill":"#90270d","stroke":"#f93e0c","stroke-width":2,"filter":"url(#crumpled)"},"#dry":{"opacity":1,"fill":"#c9bfa7","stroke":"#8e816f","stroke-width":0.7,"filter":null},"#sea_island":{"opacity":1,"stroke":"#5e5e5e","stroke-width":0.4,"filter":"url(#dropShadow)","auto-filter":1},"#lake_island":{"opacity":1,"stroke":"#7c8eaf","stroke-width":0.35,"filter":null},"#terrain":{"opacity":0.6,"set":"colored","size":1,"density":0.3,"filter":null,"mask":""},"#rivers":{"opacity":null,"filter":null,"fill":"#6d94ba"},"#ruler":{"opacity":null,"filter":null},"#roads":{"opacity":0.9,"stroke":"#3c1d0b","stroke-width":1.37,"stroke-dasharray":2,"stroke-linecap":"inherit","filter":null,"mask":null},"#trails":{"opacity":0.9,"stroke":"#95481a","stroke-width":0.88,"stroke-dasharray":".8 1.6","stroke-linecap":"butt","filter":null,"mask":null},"#searoutes":{"opacity":0.8,"stroke":"#ffffff","stroke-width":0.45,"stroke-dasharray":"1 2","stroke-linecap":"round","filter":null,"mask":null},"#statesBody":{"opacity":0.2,"filter":null},"#statesHalo":{"opacity":0.3,"data-width":25,"stroke-width":25,"filter":"blur(5px)"},"#provs":{"opacity":0.4,"fill":"#000000","font-size":5,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#temperature":{"opacity":null,"font-size":"8px","fill":"#000000","fill-opacity":0.3,"stroke":null,"stroke-width":1.8,"stroke-dasharray":null,"stroke-linecap":null,"filter":null},"#ice":{"opacity":0.5,"fill":"#e8f0f6","stroke":"#e8f0f6","stroke-width":1.5,"filter":"url(#dropShadow05)"},"#emblems":{"opacity":0.9,"stroke-width":1,"filter":null},"#texture":{"opacity":0.39,"filter":null,"mask":""},"#zones":{"opacity":0.6,"stroke":"#333333","stroke-width":0,"stroke-dasharray":null,"stroke-linecap":"butt","filter":null,"mask":null},"#oceanLayers":{"filter":"url(#dropShadow05)","layers":"-6,-3,-1"},"#oceanBase":{"fill":"#8dc1c8"},"#oceanicPattern":{"href":"./images/pattern1.png","opacity":0.2},"#terrs":{"opacity":0.4,"scheme":"light","terracing":10,"skip":5,"relax":0,"curve":0,"filter":"url(#turbulence)","mask":"url(#land)"},"#legend":{"data-size":13,"font-size":13,"data-font":"Almendra+SC","font-family":"Almendra SC","stroke":"#812929","stroke-width":2.5,"stroke-dasharray":"0 4 10 4","stroke-linecap":"round","data-x":54.73,"data-y":62.98,"data-columns":8},"#burgLabels > #cities":{"opacity":1,"fill":"#3a3a3a","text-shadow":"white 0px 0px 4px","data-size":8,"font-size":8,"data-font":"IM+Fell+English","font-family":"IM Fell English"},"#burgIcons > #cities":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":3,"stroke":"#3e3e4b","stroke-width":0.4,"stroke-dasharray":"0.5 0.25","stroke-linecap":"butt"},"#anchors > #cities":{"opacity":1,"fill":"#ffffff","size":5.5,"stroke":"#3e3e4b","stroke-width":1.2},"#burgLabels > #towns":{"opacity":1,"fill":"#3e3e4b","text-shadow":"white 0px 0px 4px","data-size":4,"font-size":4,"data-font":"IM+Fell+English","font-family":"IM Fell English"},"#burgIcons > #towns":{"opacity":1,"fill":"#ffffff","fill-opacity":0.7,"size":1.2,"stroke":"#3e3e4b","stroke-width":0.2,"stroke-dasharray":"","stroke-linecap":"butt"},"#anchors > #towns":{"opacity":1,"fill":"#ffffff","size":2.2,"stroke":"#3e3e4b","stroke-width":1.2},"#labels > #states":{"opacity":1,"fill":"#3e3e3e","stroke":"#000000","stroke-width":0.3,"text-shadow":"white 0px 0px 6px","data-size":14,"font-size":14,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#labels > #addedLabels":{"opacity":1,"fill":"#f24706","stroke":"#701b05","stroke-width":0.1,"text-shadow":"white 0px 0px 4px","data-size":6,"font-size":6,"data-font":"IM+Fell+English","font-family":"IM Fell English","filter":null},"#fogging":{"opacity":1,"fill":"#30426f","filter":null}}`, From e7b354e217af3f6c816f2d258bbdf954685ddb3c Mon Sep 17 00:00:00 2001 From: Azgaar Date: Mon, 12 Jul 2021 22:08:17 +0300 Subject: [PATCH 22/82] throttle work done on zoom --- main.js | 48 +++-- modules/ui/heightmap-editor.js | 23 +- modules/utils.js | 369 +++++++++++++++++++++------------ 3 files changed, 278 insertions(+), 162 deletions(-) diff --git a/main.js b/main.js index 6e06fb1c..17447830 100644 --- a/main.js +++ b/main.js @@ -128,9 +128,23 @@ let color = d3.scaleSequential(d3.interpolateSpectral); // default color scheme const lineGen = d3.line().curve(d3.curveBasis); // d3 line generator with default curve interpolation // d3 zoom behavior -let scale = 1, - viewX = 0, - viewY = 0; +let scale = 1; +let viewX = 0; +let viewY = 0; + +const zoomThrottled = throttle(doWorkOnZoom, 100); +function zoomed() { + const {k, x, y} = d3.event.transform; + + const isScaleChanged = Boolean(scale - k); + const isPositionChanged = Boolean(viewX - x || viewY - y); + + scale = k; + viewX = x; + viewY = y; + + zoomThrottled(isScaleChanged, isPositionChanged); +} const zoom = d3.zoom().scaleExtent([1, 20]).on("zoom", zoomed); // default options @@ -414,30 +428,24 @@ function showWelcomeMessage() { }); } -function zoomed() { - const transform = d3.event.transform; - const scaleDiff = scale - transform.k; - const positionDiff = (viewX - transform.x) | (viewY - transform.y); - if (!positionDiff && !scaleDiff) return; +function doWorkOnZoom(isScaleChanged, isPositionChanged) { + viewbox.attr("transform", `translate(${viewX} ${viewY}) scale(${scale})`); - scale = transform.k; - viewX = transform.x; - viewY = transform.y; - viewbox.attr("transform", transform); + if (isPositionChanged) drawCoordinates(); - // update grid only if view position - if (positionDiff) drawCoordinates(); - - // rescale only if zoom is changed - if (scaleDiff) { + if (isScaleChanged) { invokeActiveZooming(); drawScaleBar(); } // zoom image converter overlay - const canvas = document.getElementById("canvas"); - if (canvas && +canvas.style.opacity) { - const img = document.getElementById("image"); + if (customization === 1) { + const canvas = document.getElementById("canvas"); + if (!canvas || canvas.style.opacity === "0") return; + + const img = document.getElementById("imageToConvert"); + if (!img) return; + const ctx = canvas.getContext("2d"); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.setTransform(scale, 0, 0, scale, viewX, viewY); diff --git a/modules/ui/heightmap-editor.js b/modules/ui/heightmap-editor.js index 7c8cf5b1..053dc477 100644 --- a/modules/ui/heightmap-editor.js +++ b/modules/ui/heightmap-editor.js @@ -131,15 +131,8 @@ function editHeightmap() { // Exit customization mode function finalizeHeightmap() { - if (viewbox.select("#heights").selectAll("*").size() < 200) { - tip("Insufficient land area! There should be at least 200 land cells to finalize the heightmap", null, "error"); - return; - } - - if (document.getElementById("imageConverter").offsetParent) { - tip("Please exit the Image Conversion mode first", null, "error"); - return; - } + if (viewbox.select("#heights").selectAll("*").size() < 200) return tip("Insufficient land area! There should be at least 200 land cells to finalize the heightmap", null, "error"); + if (document.getElementById("imageConverter").offsetParent) return tip("Please exit the Image Conversion mode first", null, "error"); delete window.edits; // remove global variable redo.disabled = templateRedo.disabled = true; @@ -1103,6 +1096,10 @@ function editHeightmap() { const reader = new FileReader(); const img = new Image(); + img.id = "imageToConvert"; + img.style.display = "none"; + document.body.appendChild(img); + img.onload = function () { const ctx = document.getElementById("canvas").getContext("2d"); ctx.drawImage(img, 0, 0, graphWidth, graphHeight); @@ -1295,10 +1292,7 @@ function editHeightmap() { } function applyConversion() { - if (colorsAssigned.childElementCount < 3) { - tip("Please do the assignment first", false, "error"); - return; - } + if (colorsAssigned.childElementCount < 3) return tip("Please do the assignment first", false, "error"); viewbox .select("#heights") @@ -1324,6 +1318,9 @@ function editHeightmap() { const canvas = document.getElementById("canvas"); if (canvas) canvas.remove(); + const image = document.getElementById("imageToConvert"); + if (image) image.remove(); + d3.select("#imageConverter").selectAll("div.color-div").remove(); colorsAssigned.style.display = "none"; colorsUnassigned.style.display = "none"; diff --git a/modules/utils.js b/modules/utils.js index afe22287..0194a1ff 100644 --- a/modules/utils.js +++ b/modules/utils.js @@ -11,11 +11,11 @@ function getBoundaryPoints(width, height, spacing) { const numberY = Math.ceil(h / bSpacing) - 1; let points = []; for (let i = 0.5; i < numberX; i++) { - let x = Math.ceil(w * i / numberX + offset); + let x = Math.ceil((w * i) / numberX + offset); points.push([x, offset], [x, h + offset]); } for (let i = 0.5; i < numberY; i++) { - let y = Math.ceil(h * i / numberY + offset); + let y = Math.ceil((h * i) / numberY + offset); points.push([offset, y], [w + offset, y]); } return points; @@ -24,7 +24,7 @@ function getBoundaryPoints(width, height, spacing) { // get points on a regular square grid and jitter them a bit function getJitteredGrid(width, height, spacing) { const radius = spacing / 2; // square radius - const jittering = radius * .9; // max deviation + const jittering = radius * 0.9; // max deviation const jitter = () => Math.random() * 2 * jittering - jittering; let points = []; @@ -40,7 +40,7 @@ function getJitteredGrid(width, height, spacing) { // return cell index on a regular square grid function findGridCell(x, y) { - return Math.floor(Math.min(y / grid.spacing, grid.cellsY -1)) * grid.cellsX + Math.floor(Math.min(x / grid.spacing, grid.cellsX-1)); + return Math.floor(Math.min(y / grid.spacing, grid.cellsY - 1)) * grid.cellsX + Math.floor(Math.min(x / grid.spacing, grid.cellsX - 1)); } // return array of cell indexes in radius on a regular square grid @@ -55,14 +55,12 @@ function findGridAll(x, y, radius) { while (r > 1) { let cycle = frontier.slice(); frontier = []; - cycle.forEach(function(s) { - - c[s].forEach(function(e) { + cycle.forEach(function (s) { + c[s].forEach(function (e) { if (found.indexOf(e) !== -1) return; found.push(e); frontier.push(e); }); - }); r--; } @@ -100,7 +98,7 @@ function getGridPolygon(i) { // mbostock's poissonDiscSampler function* poissonDiscSampler(x0, y0, x1, y1, r, k = 3) { - if (!(x1 >= x0) || !(y1 >= y0) || !(r > 0)) throw new Error; + if (!(x1 >= x0) || !(y1 >= y0) || !(r > 0)) throw new Error(); const width = x1 - x0; const height = y1 - y0; @@ -113,8 +111,8 @@ function* poissonDiscSampler(x0, y0, x1, y1, r, k = 3) { const queue = []; function far(x, y) { - const i = x / cellSize | 0; - const j = y / cellSize | 0; + const i = (x / cellSize) | 0; + const j = (y / cellSize) | 0; const i0 = Math.max(i - 2, 0); const j0 = Math.max(j - 2, 0); const i1 = Math.min(i + 3, gridWidth); @@ -134,14 +132,14 @@ function* poissonDiscSampler(x0, y0, x1, y1, r, k = 3) { } function sample(x, y) { - queue.push(grid[gridWidth * (y / cellSize | 0) + (x / cellSize | 0)] = [x, y]); + queue.push((grid[gridWidth * ((y / cellSize) | 0) + ((x / cellSize) | 0)] = [x, y])); return [x + x0, y + y0]; } yield sample(width / 2, height / 2); pick: while (queue.length) { - const i = Math.random() * queue.length | 0; + const i = (Math.random() * queue.length) | 0; const parent = queue[i]; for (let j = 0; j < k; ++j) { @@ -171,20 +169,19 @@ function isWater(i) { } // convert RGB color string to HEX without # -function toHEX(rgb){ - if (rgb.charAt(0) === "#") {return rgb;} +function toHEX(rgb) { + if (rgb.charAt(0) === "#") { + return rgb; + } rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); - return (rgb && rgb.length === 4) ? "#" + - ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : ''; + return rgb && rgb.length === 4 ? "#" + ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) + ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : ""; } // return array of standard shuffled colors function getColors(number) { - const c12 = ["#dababf","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#c6b9c1","#bc80bd","#ccebc5","#ffed6f","#8dd3c7","#eb8de7"]; + const c12 = ["#dababf", "#fb8072", "#80b1d3", "#fdb462", "#b3de69", "#fccde5", "#c6b9c1", "#bc80bd", "#ccebc5", "#ffed6f", "#8dd3c7", "#eb8de7"]; const cRB = d3.scaleSequential(d3.interpolateRainbow); - const colors = d3.shuffle(d3.range(number).map(i => i < 12 ? c12[i] : d3.color(cRB((i-12)/(number-12))).hex())); + const colors = d3.shuffle(d3.range(number).map(i => (i < 12 ? c12[i] : d3.color(cRB((i - 12) / (number - 12))).hex()))); return colors; } @@ -193,30 +190,42 @@ function getRandomColor() { } // mix a color with a random color -function getMixedColor(color, mix = .2, bright = .3) { +function getMixedColor(color, mix = 0.2, bright = 0.3) { const c = color && color[0] === "#" ? color : getRandomColor(); // if provided color is not hex (e.g. harching), generate random one return d3.color(d3.interpolate(c, getRandomColor())(mix)).brighter(bright).hex(); } // conver temperature from °C to other scales function convertTemperature(c) { - switch(temperatureScale.value) { - case "°C": return c + "°C"; - case "°F": return rn(c * 9 / 5 + 32) + "°F"; - case "K": return rn(c + 273.15) + "K"; - case "°R": return rn((c + 273.15) * 9 / 5) + "°R"; - case "°De": return rn((100 - c) * 3 / 2) + "°De"; - case "°N": return rn(c * 33 / 100) + "°N"; - case "°Ré": return rn(c * 4 / 5) + "°Ré"; - case "°Rø": return rn(c * 21 / 40 + 7.5) + "°Rø"; - default: return c + "°C"; + switch (temperatureScale.value) { + case "°C": + return c + "°C"; + case "°F": + return rn((c * 9) / 5 + 32) + "°F"; + case "K": + return rn(c + 273.15) + "K"; + case "°R": + return rn(((c + 273.15) * 9) / 5) + "°R"; + case "°De": + return rn(((100 - c) * 3) / 2) + "°De"; + case "°N": + return rn((c * 33) / 100) + "°N"; + case "°Ré": + return rn((c * 4) / 5) + "°Ré"; + case "°Rø": + return rn((c * 21) / 40 + 7.5) + "°Rø"; + default: + return c + "°C"; } } // random number in a range function rand(min, max) { if (min === undefined && max === undefined) return Math.random(); - if (max === undefined) {max = min; min = 0;} + if (max === undefined) { + max = min; + min = 0; + } return Math.floor(Math.random() * (max - min + 1)) + min; } @@ -245,7 +254,9 @@ function rn(v, d = 0) { // round string to d decimals function round(s, d = 1) { - return s.replace(/[\d\.-][\d\.e-]*/g, function(n) {return rn(n, d);}) + return s.replace(/[\d\.-][\d\.e-]*/g, function (n) { + return rn(n, d); + }); } // corvent number to short string with SI postfix @@ -279,52 +290,50 @@ function capitalize(string) { // transform string to array [translateX,translateY,rotateDeg,rotateX,rotateY,scale] function parseTransform(string) { - if (!string) {return [0,0,0,0,0,1];} - const a = string.replace(/[a-z()]/g, "").replace(/[ ]/g, ",").split(","); + if (!string) { + return [0, 0, 0, 0, 0, 1]; + } + const a = string + .replace(/[a-z()]/g, "") + .replace(/[ ]/g, ",") + .split(","); return [a[0] || 0, a[1] || 0, a[2] || 0, a[3] || 0, a[4] || 0, a[5] || 1]; } // findAll d3.quandtree search from https://bl.ocks.org/lwthatcher/b41479725e0ff2277c7ac90df2de2b5e -void function addFindAll() { - const Quad = function(node, x0, y0, x1, y1) { +void (function addFindAll() { + const Quad = function (node, x0, y0, x1, y1) { this.node = node; this.x0 = x0; this.y0 = y0; this.x1 = x1; this.y1 = y1; - } + }; - const tree_filter = function(x, y, radius) { + const tree_filter = function (x, y, radius) { var t = {x, y, x0: this._x0, y0: this._y0, x3: this._x1, y3: this._y1, quads: [], node: this._root}; - if (t.node) {t.quads.push(new Quad(t.node, t.x0, t.y0, t.x3, t.y3))}; + if (t.node) { + t.quads.push(new Quad(t.node, t.x0, t.y0, t.x3, t.y3)); + } radiusSearchInit(t, radius); var i = 0; - while (t.q = t.quads.pop()) { + while ((t.q = t.quads.pop())) { i++; // Stop searching if this quadrant can’t contain a closer node. - if (!(t.node = t.q.node) - || (t.x1 = t.q.x0) > t.x3 - || (t.y1 = t.q.y0) > t.y3 - || (t.x2 = t.q.x1) < t.x0 - || (t.y2 = t.q.y1) < t.y0) continue; + if (!(t.node = t.q.node) || (t.x1 = t.q.x0) > t.x3 || (t.y1 = t.q.y0) > t.y3 || (t.x2 = t.q.x1) < t.x0 || (t.y2 = t.q.y1) < t.y0) continue; // Bisect the current quadrant. if (t.node.length) { t.node.explored = true; var xm = (t.x1 + t.x2) / 2, - ym = (t.y1 + t.y2) / 2; + ym = (t.y1 + t.y2) / 2; - t.quads.push( - new Quad(t.node[3], xm, ym, t.x2, t.y2), - new Quad(t.node[2], t.x1, ym, xm, t.y2), - new Quad(t.node[1], xm, t.y1, t.x2, ym), - new Quad(t.node[0], t.x1, t.y1, xm, ym) - ); + t.quads.push(new Quad(t.node[3], xm, ym, t.x2, t.y2), new Quad(t.node[2], t.x1, ym, xm, t.y2), new Quad(t.node[1], xm, t.y1, t.x2, ym), new Quad(t.node[0], t.x1, t.y1, xm, ym)); // Visit the closest quadrant first. - if (t.i = (y >= ym) << 1 | (x >= xm)) { + if ((t.i = ((y >= ym) << 1) | (x >= xm))) { t.q = t.quads[t.quads.length - 1]; t.quads[t.quads.length - 1] = t.quads[t.quads.length - 1 - t.i]; t.quads[t.quads.length - 1 - t.i] = t.q; @@ -334,29 +343,32 @@ void function addFindAll() { // Visit this point. (Visiting coincident points isn’t necessary!) else { var dx = x - +this._x.call(null, t.node.data), - dy = y - +this._y.call(null, t.node.data), - d2 = dx * dx + dy * dy; + dy = y - +this._y.call(null, t.node.data), + d2 = dx * dx + dy * dy; radiusSearchVisit(t, d2); } } return t.result; - } + }; d3.quadtree.prototype.findAll = tree_filter; - var radiusSearchInit = function(t, radius) { + var radiusSearchInit = function (t, radius) { t.result = []; - t.x0 = t.x - radius, t.y0 = t.y - radius; - t.x3 = t.x + radius, t.y3 = t.y + radius; + (t.x0 = t.x - radius), (t.y0 = t.y - radius); + (t.x3 = t.x + radius), (t.y3 = t.y + radius); t.radius = radius * radius; - } + }; - var radiusSearchVisit = function(t, d2) { + var radiusSearchVisit = function (t, d2) { t.node.data.scanned = true; if (d2 < t.radius) { - do {t.result.push(t.node.data); t.node.data.selected = true;} while (t.node = t.node.next); + do { + t.result.push(t.node.data); + t.node.data.selected = true; + } while ((t.node = t.node.next)); } - } -}() + }; +})(); // get segment of any point on polyline function getSegmentId(points, point, step = 10) { @@ -366,23 +378,23 @@ function getSegmentId(points, point, step = 10) { let minSegment = 1; let minDist = Infinity; - for (let i=0; i < points.length-1; i++) { + for (let i = 0; i < points.length - 1; i++) { const p1 = points[i]; - const p2 = points[i+1]; + const p2 = points[i + 1]; const length = Math.sqrt(d2(p1, p2)); const segments = Math.ceil(length / step); const dx = (p2[0] - p1[0]) / segments; const dy = (p2[1] - p1[1]) / segments; - for (let s=0; s < segments; s++) { + for (let s = 0; s < segments; s++) { const x = p1[0] + s * dx; const y = p1[1] + s * dy; const dist2 = d2(point, [x, y]); if (dist2 >= minDist) continue; minDist = dist2; - minSegment = i+1; + minSegment = i + 1; } } @@ -418,7 +430,9 @@ function vowel(c) { // remove vowels from the end of the string function trimVowels(string) { - while (string.length > 3 && vowel(last(string))) {string = string.slice(0,-1);} + while (string.length > 3 && vowel(last(string))) { + string = string.slice(0, -1); + } return string; } @@ -427,7 +441,7 @@ function getAdjective(string) { // special cases for some suffixes if (string.length > 8 && string.slice(-6) === "orszag") return string.slice(0, -6); if (string.length > 6 && string.slice(-4) === "stan") return string.slice(0, -4); - if (P(.5) && string.slice(-4) === "land") return string + "ic"; + if (P(0.5) && string.slice(-4) === "land") return string + "ic"; if (string.slice(-4) === " Guo") string = string.slice(0, -4); // don't change is name ends on suffix @@ -436,16 +450,16 @@ function getAdjective(string) { if (string.slice(-1) === "i") return string; const end = string.slice(-1); // last letter of string - if (end === "a") return string += "n"; - if (end === "o") return string = trimVowels(string) + "an"; - if (vowel(end) || end === "c") return string += "an"; // ceiuy - if (end === "m" || end === "n") return string += "ese"; - if (end === "q") return string += "i"; + if (end === "a") return (string += "n"); + if (end === "o") return (string = trimVowels(string) + "an"); + if (vowel(end) || end === "c") return (string += "an"); // ceiuy + if (end === "m" || end === "n") return (string += "ese"); + if (end === "q") return (string += "i"); return trimVowels(string) + "ian"; } // get ordinal out of integer: 1 => 1st -const nth = n => n+(["st","nd","rd"][((n+90)%100-10)%10-1]||"th"); +const nth = n => n + (["st", "nd", "rd"][((((n + 90) % 100) - 10) % 10) - 1] || "th"); // get two-letters code (abbreviation) from string function abbreviate(name, restricted = []) { @@ -453,8 +467,8 @@ function abbreviate(name, restricted = []) { const words = parsed.split(" "); const letters = words.join(""); - let code = words.length === 2 ? words[0][0]+words[1][0] : letters.slice(0,2); - for (let i = 1; i < letters.length-1 && restricted.includes(code); i++) { + let code = words.length === 2 ? words[0][0] + words[1][0] : letters.slice(0, 2); + for (let i = 1; i < letters.length - 1 && restricted.includes(code); i++) { code = letters[0] + letters[i].toUpperCase(); } return code; @@ -463,7 +477,7 @@ function abbreviate(name, restricted = []) { // conjunct array: [A,B,C] => "A, B and C" function list(array) { if (!Intl.ListFormat) return array.join(", "); - const conjunction = new Intl.ListFormat(window.lang || "en", {style:"long", type:"conjunction"}); + const conjunction = new Intl.ListFormat(window.lang || "en", {style: "long", type: "conjunction"}); return conjunction.format(array); } @@ -472,7 +486,10 @@ function splitInTwo(str) { const half = str.length / 2; const ar = str.split(" "); if (ar.length < 2) return ar; // only one word - let first = "", last = "", middle = "", rest = ""; + let first = "", + last = "", + middle = "", + rest = ""; ar.forEach((w, d) => { if (d + 1 !== ar.length) w += " "; @@ -501,10 +518,10 @@ function ra(array) { function rw(object) { const array = []; for (const key in object) { - for (let i=0; i < object[key]; i++) { + for (let i = 0; i < object[key]; i++) { array.push(key); } - }; + } return array[Math.floor(Math.random() * array.length)]; } @@ -515,33 +532,55 @@ function lim(v) { // get number from string in format "1-3" or "2" or "0.5" function getNumberInRange(r) { - if (typeof r !== "string") {ERROR && console.error("The value should be a string", r); return 0;} + if (typeof r !== "string") { + ERROR && console.error("The value should be a string", r); + return 0; + } if (!isNaN(+r)) return ~~r + +P(r - ~~r); const sign = r[0] === "-" ? -1 : 1; if (isNaN(+r[0])) r = r.slice(1); const range = r.includes("-") ? r.split("-") : null; - if (!range) {ERROR && console.error("Cannot parse the number. Check the format", r); return 0;} + if (!range) { + ERROR && console.error("Cannot parse the number. Check the format", r); + return 0; + } const count = rand(range[0] * sign, +range[1]); - if (isNaN(count) || count < 0) {ERROR && console.error("Cannot parse number. Check the format", r); return 0;} + if (isNaN(count) || count < 0) { + ERROR && console.error("Cannot parse number. Check the format", r); + return 0; + } return count; } // helper function non-used for the generation function drawCellsValue(data) { debug.selectAll("text").remove(); - debug.selectAll("text").data(data).enter().append("text") - .attr("x", (d,i) => pack.cells.p[i][0]).attr("y", (d,i) => pack.cells.p[i][1]).text(d => d); + debug + .selectAll("text") + .data(data) + .enter() + .append("text") + .attr("x", (d, i) => pack.cells.p[i][0]) + .attr("y", (d, i) => pack.cells.p[i][1]) + .text(d => d); } // helper function non-used for the generation function drawPolygons(data) { - const max = d3.max(data), min = d3.min(data), scheme = getColorScheme(); + const max = d3.max(data), + min = d3.min(data), + scheme = getColorScheme(); data = data.map(d => 1 - normalize(d, min, max)); debug.selectAll("polygon").remove(); - debug.selectAll("polygon").data(data).enter().append("polygon") - .attr("points", (d,i) => getPackPolygon(i)) - .attr("fill", d => scheme(d)).attr("stroke", d => scheme(d)); + debug + .selectAll("polygon") + .data(data) + .enter() + .append("polygon") + .attr("points", (d, i) => getPackPolygon(i)) + .attr("fill", d => scheme(d)) + .attr("stroke", d => scheme(d)); } // polyfill for composedPath @@ -552,56 +591,86 @@ function getComposedPath(node) { else if (node.defaultView) parent = node.defaultView; if (parent !== undefined) return [node].concat(getComposedPath(parent)); return [node]; -}; +} // polyfill for replaceAll if (!String.prototype.replaceAll) { - String.prototype.replaceAll = function(str, newStr){ - if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') return this.replace(str, newStr); - return this.replace(new RegExp(str, 'g'), newStr); + String.prototype.replaceAll = function (str, newStr) { + if (Object.prototype.toString.call(str).toLowerCase() === "[object regexp]") return this.replace(str, newStr); + return this.replace(new RegExp(str, "g"), newStr); }; } // get next unused id function getNextId(core, i = 1) { - while (document.getElementById(core+i)) i++; + while (document.getElementById(core + i)) i++; return core + i; } -function debounce(f, ms) { +function debounce(func, ms) { let isCooldown = false; - return function() { + return function () { if (isCooldown) return; - f.apply(this, arguments); + func.apply(this, arguments); isCooldown = true; - setTimeout(() => isCooldown = false, ms); + setTimeout(() => (isCooldown = false), ms); }; } +function throttle(func, ms) { + let isThrottled = false; + let savedArgs; + let savedThis; + + function wrapper() { + if (isThrottled) { + savedArgs = arguments; + savedThis = this; + return; + } + + func.apply(this, arguments); + isThrottled = true; + + setTimeout(function () { + isThrottled = false; + if (savedArgs) { + wrapper.apply(savedThis, savedArgs); + savedArgs = savedThis = null; + } + }, ms); + } + + return wrapper; +} + // parse error to get the readable string in Chrome and Firefox function parseError(error) { - const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; + const isFirefox = navigator.userAgent.toLowerCase().indexOf("firefox") > -1; const errorString = isFirefox ? error.toString() + " " + error.stack : error.stack; - const regex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; - const errorNoURL = errorString.replace(regex, url => '' + last(url.split("/")) + ''); - const errorParsed = errorNoURL.replace(/at /ig, "
  at "); + const regex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gi; + const errorNoURL = errorString.replace(regex, url => "" + last(url.split("/")) + ""); + const errorParsed = errorNoURL.replace(/at /gi, "
  at "); return errorParsed; } // polyfills if (Array.prototype.flat === undefined) { - Array.prototype.flat = function() { - return this.reduce((acc, val) => Array.isArray(val) ? acc.concat(val.flat()) : acc.concat(val), []); - } + Array.prototype.flat = function () { + return this.reduce((acc, val) => (Array.isArray(val) ? acc.concat(val.flat()) : acc.concat(val)), []); + }; } // check if string is a valid for JSON parse JSON.isValid = str => { - try {JSON.parse(str);} - catch(e) {return false;} + try { + JSON.parse(str); + } catch (e) { + return false; + } return true; -} +}; function getBase64(url, callback) { const xhr = new XMLHttpRequest(); @@ -640,16 +709,16 @@ function wiki(page) { // wrap URL into html a element function link(URL, description) { - return `${description}` + return `${description}`; } function isCtrlClick(event) { // meta key is cmd key on MacOs - return event.ctrlKey || event.metaKey; + return event.ctrlKey || event.metaKey; } function generateDate(from = 100, to = 1000) { - return new Date(rand(from, to),rand(12),rand(31)).toLocaleDateString("en", {year:'numeric', month:'long', day:'numeric'}); + return new Date(rand(from, to), rand(12), rand(31)).toLocaleDateString("en", {year: "numeric", month: "long", day: "numeric"}); } function getQGIScoordinates(x, y) { @@ -659,15 +728,18 @@ function getQGIScoordinates(x, y) { } // prompt replacer (prompt does not work in Electron) -void function() { +void (function () { const prompt = document.getElementById("prompt"); const form = prompt.querySelector("#promptForm"); - window.prompt = function(promptText = "Please provide an input", options = {default:1, step:.01, min:0, max:100}, callback) { - if (options.default === undefined) {ERROR && console.error("Prompt: options object does not have default value defined"); return;} + window.prompt = function (promptText = "Please provide an input", options = {default: 1, step: 0.01, min: 0, max: 100}, callback) { + if (options.default === undefined) { + ERROR && console.error("Prompt: options object does not have default value defined"); + return; + } const input = prompt.querySelector("#promptInput"); prompt.querySelector("#promptText").innerHTML = promptText; - const type = typeof(options.default) === "number" ? "number" : "text"; + const type = typeof options.default === "number" ? "number" : "text"; input.type = type; if (options.step !== undefined) input.step = options.step; if (options.min !== undefined) input.min = options.min; @@ -676,17 +748,56 @@ void function() { input.value = options.default; prompt.style.display = "block"; - form.addEventListener("submit", event => { - prompt.style.display = "none"; - const v = type === "number" ? +input.value : input.value; - event.preventDefault(); - if (callback) callback(v); - }, {once: true}); - } + form.addEventListener( + "submit", + event => { + prompt.style.display = "none"; + const v = type === "number" ? +input.value : input.value; + event.preventDefault(); + if (callback) callback(v); + }, + {once: true} + ); + }; const cancel = prompt.querySelector("#promptCancel"); - cancel.addEventListener("click", () => prompt.style.display = "none"); -}() + cancel.addEventListener("click", () => (prompt.style.display = "none")); +})(); // indexedDB; ldb object -!function(){function e(t,o){return n?void(n.transaction("s").objectStore("s").get(t).onsuccess=function(e){var t=e.target.result&&e.target.result.v||null;o(t)}):void setTimeout(function(){e(t,o)},100)}var t=window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB;if(!t)return void ERROR && console.error("indexedDB not supported");var n,o={k:"",v:""},r=t.open("d2",1);r.onsuccess=function(e){n=this.result},r.onerror=function(e){ERROR && console.error("indexedDB request error"),INFO && console.log(e)},r.onupgradeneeded=function(e){n=null;var t=e.target.result.createObjectStore("s",{keyPath:"k"});t.transaction.oncomplete=function(e){n=e.target.db}},window.ldb={get:e,set:function(e,t){o.k=e,o.v=t,n.transaction("s","readwrite").objectStore("s").put(o)}}}(); \ No newline at end of file +!(function () { + function e(t, o) { + return n + ? void (n.transaction("s").objectStore("s").get(t).onsuccess = function (e) { + var t = (e.target.result && e.target.result.v) || null; + o(t); + }) + : void setTimeout(function () { + e(t, o); + }, 100); + } + var t = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; + if (!t) return void ERROR && console.error("indexedDB not supported"); + var n, + o = {k: "", v: ""}, + r = t.open("d2", 1); + (r.onsuccess = function (e) { + n = this.result; + }), + (r.onerror = function (e) { + ERROR && console.error("indexedDB request error"), INFO && console.log(e); + }), + (r.onupgradeneeded = function (e) { + n = null; + var t = e.target.result.createObjectStore("s", {keyPath: "k"}); + t.transaction.oncomplete = function (e) { + n = e.target.db; + }; + }), + (window.ldb = { + get: e, + set: function (e, t) { + (o.k = e), (o.v = t), n.transaction("s", "readwrite").objectStore("s").put(o); + } + }); +})(); From 985e3c43f9646c9085030ce842f01c424cd4ddc2 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Mon, 12 Jul 2021 23:20:34 +0300 Subject: [PATCH 23/82] throttle work done on zoom and brush drag --- main.js | 2 +- modules/ui/heightmap-editor.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/main.js b/main.js index 17447830..9d5f7904 100644 --- a/main.js +++ b/main.js @@ -2023,7 +2023,7 @@ const regenerateMap = debounce(function () { restoreLayers(); if (ThreeD.options.isOn) ThreeD.redraw(); if ($("#worldConfigurator").is(":visible")) editWorld(); -}, 500); +}, 1000); // clear the map function undraw() { diff --git a/modules/ui/heightmap-editor.js b/modules/ui/heightmap-editor.js index 053dc477..4cac39f3 100644 --- a/modules/ui/heightmap-editor.js +++ b/modules/ui/heightmap-editor.js @@ -573,6 +573,7 @@ function editHeightmap() { document.getElementById("brushesSliders").style.display = "none"; } + const dragBrushThrottled = throttle(dragBrush, 100); function toggleBrushMode(e) { if (e.target.classList.contains("pressed")) { exitBrushMode(); @@ -581,7 +582,7 @@ function editHeightmap() { exitBrushMode(); document.getElementById("brushesSliders").style.display = "block"; e.target.classList.add("pressed"); - viewbox.style("cursor", "crosshair").call(d3.drag().on("start", dragBrush)); + viewbox.style("cursor", "crosshair").call(d3.drag().on("start", dragBrushThrottled)); } function dragBrush() { From 6dc8cad13edbbc134f7f53f833b3b08021dda1c8 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Mon, 12 Jul 2021 23:45:10 +0300 Subject: [PATCH 24/82] shapeRendering option --- index.html | 12 ++++++++++++ modules/load.js | 1 + modules/ui/options.js | 4 ++++ 3 files changed, 17 insertions(+) diff --git a/index.html b/index.html index 4bd3e984..0b2c9e7a 100644 --- a/index.html +++ b/index.html @@ -1278,6 +1278,18 @@ +
+ + + + + +
Please ensure the element is toggled on!Ensure the element visibility is toggled on!
Group - +
Halo width - - 10 -
Halo opacity - - 1 -
Column items
Body opacity + + +
Halo width + + 10 +
Halo opacity + + 1 +
Halo blur + + 4 +
Color scheme
Body filter
Halo width @@ -871,29 +876,7 @@
Filter - -
Style
Size - - 1 + +
Density @@ -848,21 +848,21 @@
State Size - +
Province Size - +
Burg Size - +
Font size - - + +
Shape rendering + +