From 338ce17cb8c3b179298e5c151c043466a06b29bf Mon Sep 17 00:00:00 2001 From: Brian Weasner Date: Thu, 9 Aug 2018 18:37:42 -0600 Subject: [PATCH 1/2] Small Js Fixes --- script.js | 2985 +++++++++++++++++++++++++++-------------------------- 1 file changed, 1511 insertions(+), 1474 deletions(-) diff --git a/script.js b/script.js index 7c1c408a..2a029a2c 100644 --- a/script.js +++ b/script.js @@ -37,7 +37,7 @@ function fantasyMap() { labels = viewbox.append("g").attr("id", "labels"), burgLabels = labels.append("g").attr("id", "burgLabels"), icons = viewbox.append("g").attr("id", "icons"), - burgIcons = icons.append("g").attr("id", "burgIcons") + burgIcons = icons.append("g").attr("id", "burgIcons"), ruler = viewbox.append("g").attr("id", "ruler"), debug = viewbox.append("g").attr("id", "debug"); @@ -74,8 +74,8 @@ function fantasyMap() { // Color schemes var color = d3.scaleSequential(d3.interpolateSpectral), - colors8 = d3.scaleOrdinal(d3.schemeSet2), - colors20 = d3.scaleOrdinal(d3.schemeCategory20); + colors8 = d3.scaleOrdinal(d3.schemeSet2), + colors20 = d3.scaleOrdinal(d3.schemeCategory20); // D3 drag and zoom behavior var scale = 1, viewX = 0, viewY = 0; @@ -83,7 +83,7 @@ function fantasyMap() { svg.call(zoom); // D3 Line generator variables - var lineGen = d3.line().x(function(d) {return d.scX;}).y(function(d) {return d.scY;}).curve(d3.curveCatmullRom); + var lineGen = d3.line().x(function (d) { return d.scX; }).y(function (d) { return d.scY; }).curve(d3.curveCatmullRom); applyStoredOptions(); let graphWidth = +mapWidthInput.value; // voronoi graph extention, should be stable for each map @@ -100,14 +100,14 @@ function fantasyMap() { $("#optionsTrigger").removeClass("glow"); } - $("#optionsContainer").draggable({handle: ".drag-trigger", snap: "svg", snapMode: "both"}); - $("#mapLayers").sortable({items: "li:not(.solid)", cancel: ".solid", update: moveLayer}); - $("#templateBody").sortable({items: "div:not(div[data-type='Mountain'])"}); + $("#optionsContainer").draggable({ handle: ".drag-trigger", snap: "svg", snapMode: "both" }); + $("#mapLayers").sortable({ items: "li:not(.solid)", cancel: ".solid", update: moveLayer }); + $("#templateBody").sortable({ items: "div:not(div[data-type='Mountain'])" }); $("#mapLayers, #templateBody").disableSelection(); var drag = d3.drag() - .container(function() {return this;}) - .subject(function() {var p=[d3.event.x, d3.event.y]; return [p, p];}) + .container(function () { return this; }) + .subject(function () { var p = [d3.event.x, d3.event.y]; return [p, p]; }) .on("start", dragstarted); function zoomed() { @@ -145,22 +145,22 @@ function fantasyMap() { function invokeActiveZooming() { // toggle shade/blur filter on zoom var filter = scale > 2.6 ? "url(#blurFilter)" : "url(#dropShadow)"; - if (scale > 1.5 && scale <= 2.6) {filter = null;} + if (scale > 1.5 && scale <= 2.6) { filter = null; } coastline.attr("filter", filter); // rescale lables on zoom (active zooming) - labels.selectAll("g").each(function(d) { + labels.selectAll("g").each(function (d) { var el = d3.select(this); if (el.attr("id") === "burgLabels") return; var desired = +el.attr("data-size"); var relative = rn((desired + (desired / scale)) / 2, 2); - if (relative < 2) {relative = 2;} + if (relative < 2) { relative = 2; } el.attr("font-size", relative); el.classed("hidden", hideLabels.checked && relative * scale < 6); }); if (ruler.size()) { if (ruler.style("display") !== "none") { - if (ruler.selectAll("g").size() < 1) {return;} + if (ruler.selectAll("g").size() < 1) { return; } var factor = rn(1 / Math.pow(scale, 0.3), 1); ruler.selectAll("circle:not(.center)").attr("r", 2 * factor).attr("stroke-width", 0.5 * factor); ruler.selectAll("circle.center").attr("r", 1.2 * factor).attr("stroke-width", 0.3 * factor); @@ -190,16 +190,17 @@ function fantasyMap() {

Join our Reddit community to share created maps, discuss the Generator, ask questions and propose new features.`; $("#alert").dialog( - {resizable: false, title: "Fantasy Map Generator update", width: 280, - buttons: { - "Don't show again": function() { - localStorage.setItem("version", version); - $(this).dialog("close"); + { + resizable: false, title: "Fantasy Map Generator update", width: 280, + buttons: { + "Don't show again": function () { + localStorage.setItem("version", version); + $(this).dialog("close"); + }, + Close: function () { $(this).dialog("close"); } }, - Close: function() {$(this).dialog("close");} - }, - position: {my: "center", at: "center", of: "svg"} - }); + position: { my: "center", at: "center", of: "svg" } + }); } applyNamesData(); // apply default namesbase on load @@ -297,7 +298,7 @@ function fantasyMap() { mapHeightInput.value = window.innerHeight; changeMapSize(); graphSize = sizeInput.value = sizeOutput.value = 1; - $("#options i[class^='icon-lock']").each(function() { + $("#options i[class^='icon-lock']").each(function () { this.setAttribute("data-locked", 0); this.className = "icon-lock-open"; if (this.id === "lockNeutralInput" || this.id === "lockSwampinessInput") { @@ -323,53 +324,53 @@ function fantasyMap() { } else { applyDefaultNamesData(); } - defaultCultures = [{name:"Shwazen", color:"#b3b3b3", base:0}, - {name:"Angshire", color:"#fca463", base:1}, - {name:"Luari", color:"#99acfb", base:2}, - {name:"Tallian", color:"#a6d854", base:3}, - {name:"Toledi", color:"#ffd92f", base:4}, - {name:"Slovian", color:"#e5c494", base:5}, - {name:"Norse", color:"#dca3e4", base:6}, - {name:"Elladian", color:"#96d6be", base:7}, - {name:"Latian", color:"#ff7174", base:8}, - {name:"Somi", color:"#aedff7", base:9}, - {name:"Koryo", color:"#578880", base:10}, - {name:"Hantzu", color:"#fdface", base:11}, - {name:"Yamoto", color:"#ffd9da", base:12} + defaultCultures = [{ name: "Shwazen", color: "#b3b3b3", base: 0 }, + { name: "Angshire", color: "#fca463", base: 1 }, + { name: "Luari", color: "#99acfb", base: 2 }, + { name: "Tallian", color: "#a6d854", base: 3 }, + { name: "Toledi", color: "#ffd92f", base: 4 }, + { name: "Slovian", color: "#e5c494", base: 5 }, + { name: "Norse", color: "#dca3e4", base: 6 }, + { name: "Elladian", color: "#96d6be", base: 7 }, + { name: "Latian", color: "#ff7174", base: 8 }, + { name: "Somi", color: "#aedff7", base: 9 }, + { name: "Koryo", color: "#578880", base: 10 }, + { name: "Hantzu", color: "#fdface", base: 11 }, + { name: "Yamoto", color: "#ffd9da", base: 12 } ]; } // apply default names data function applyDefaultNamesData() { nameBases = [ // min; max; mean; common - {name: "German", method: "let-to-syl", min: 4, max: 11, d: "lt", m: 0.1}, // real: 3; 17; 8.6; 8 - {name: "English", method: "let-to-syl", min: 5, max: 10, d: "", m: 0.3}, // real: 4; 13; 7.9; 8 - {name: "French", method: "let-to-syl", min: 4, max: 10, d: "lns", m: 0.3}, // real: 3; 15; 7.6; 6 - {name: "Italian", method: "let-to-syl", min: 4, max: 11, d: "clrt", m: 0.2}, // real: 4; 14; 7.7; 7 - {name: "Castillian", method: "let-to-syl", min: 4, max: 10, d: "lr", m: 0}, // real: 2; 13; 7.5; 8 - {name: "Ruthenian", method: "let-to-syl", min: 4, max: 9, d: "", m: 0}, // real: 3; 12; 7.1; 7 - {name: "Nordic", method: "let-to-syl", min: 5, max: 9, d: "kln", m: 0.1}, // real: 3; 12; 7.5; 6 - {name: "Greek", method: "let-to-syl", min: 4, max: 10, d: "ls", m: 0.2}, // real: 3; 14; 7.1; 6 - {name: "Roman", method: "let-to-syl", min: 5, max: 10, d: "", m: 1}, // real: 3; 15; 8.0; 7 - {name: "Finnic", method: "let-to-syl", min: 3, max: 10, d: "aktu", m: 0}, // real: 3; 13; 7.5; 6 - {name: "Korean", method: "let-to-syl", min: 5, max: 10, d: "", m: 0}, // real: 3; 13; 6.8; 7 - {name: "Chinese", method: "let-to-syl", min: 5, max: 9, d: "", m: 0}, // real: 4; 11; 6.9; 6 - {name: "Japanese", method: "let-to-syl", min: 3, max: 9, d: "", m: 0} // real: 2; 15; 6.8; 6 + { name: "German", method: "let-to-syl", min: 4, max: 11, d: "lt", m: 0.1 }, // real: 3; 17; 8.6; 8 + { name: "English", method: "let-to-syl", min: 5, max: 10, d: "", m: 0.3 }, // real: 4; 13; 7.9; 8 + { name: "French", method: "let-to-syl", min: 4, max: 10, d: "lns", m: 0.3 }, // real: 3; 15; 7.6; 6 + { name: "Italian", method: "let-to-syl", min: 4, max: 11, d: "clrt", m: 0.2 }, // real: 4; 14; 7.7; 7 + { name: "Castillian", method: "let-to-syl", min: 4, max: 10, d: "lr", m: 0 }, // real: 2; 13; 7.5; 8 + { name: "Ruthenian", method: "let-to-syl", min: 4, max: 9, d: "", m: 0 }, // real: 3; 12; 7.1; 7 + { name: "Nordic", method: "let-to-syl", min: 5, max: 9, d: "kln", m: 0.1 }, // real: 3; 12; 7.5; 6 + { name: "Greek", method: "let-to-syl", min: 4, max: 10, d: "ls", m: 0.2 }, // real: 3; 14; 7.1; 6 + { name: "Roman", method: "let-to-syl", min: 5, max: 10, d: "", m: 1 }, // real: 3; 15; 8.0; 7 + { name: "Finnic", method: "let-to-syl", min: 3, max: 10, d: "aktu", m: 0 }, // real: 3; 13; 7.5; 6 + { name: "Korean", method: "let-to-syl", min: 5, max: 10, d: "", m: 0 }, // real: 3; 13; 6.8; 7 + { name: "Chinese", method: "let-to-syl", min: 5, max: 9, d: "", m: 0 }, // real: 4; 11; 6.9; 6 + { name: "Japanese", method: "let-to-syl", min: 3, max: 9, d: "", m: 0 } // real: 2; 15; 6.8; 6 ]; nameBase = [ - ["Achern","Aichhalden","Aitern","Albbruck","Alpirsbach","Altensteig","Althengstett","Appenweier","Auggen","Wildbad","Badenen","Badenweiler","Baiersbronn","Ballrechten","Bellingen","Berghaupten","Bernau","Biberach","Biederbach","Binzen","Birkendorf","Birkenfeld","Bischweier","Blumberg","Bollen","Bollschweil","Bonndorf","Bosingen","Braunlingen","Breisach","Breisgau","Breitnau","Brigachtal","Buchenbach","Buggingen","Buhl","Buhlertal","Calw","Dachsberg","Dobel","Donaueschingen","Dornhan","Dornstetten","Dottingen","Dunningen","Durbach","Durrheim","Ebhausen","Ebringen","Efringen","Egenhausen","Ehrenkirchen","Ehrsberg","Eimeldingen","Eisenbach","Elzach","Elztal","Emmendingen","Endingen","Engelsbrand","Enz","Enzklosterle","Eschbronn","Ettenheim","Ettlingen","Feldberg","Fischerbach","Fischingen","Fluorn","Forbach","Freiamt","Freiburg","Freudenstadt","Friedenweiler","Friesenheim","Frohnd","Furtwangen","Gaggenau","Geisingen","Gengenbach","Gernsbach","Glatt","Glatten","Glottertal","Gorwihl","Gottenheim","Grafenhausen","Grenzach","Griesbach","Gutach","Gutenbach","Hag","Haiterbach","Hardt","Harmersbach","Hasel","Haslach","Hausach","Hausen","Hausern","Heitersheim","Herbolzheim","Herrenalb","Herrischried","Hinterzarten","Hochenschwand","Hofen","Hofstetten","Hohberg","Horb","Horben","Hornberg","Hufingen","Ibach","Ihringen","Inzlingen","Kandern","Kappel","Kappelrodeck","Karlsbad","Karlsruhe","Kehl","Keltern","Kippenheim","Kirchzarten","Konigsfeld","Krozingen","Kuppenheim","Kussaberg","Lahr","Lauchringen","Lauf","Laufenburg","Lautenbach","Lauterbach","Lenzkirch","Liebenzell","Loffenau","Loffingen","Lorrach","Lossburg","Mahlberg","Malsburg","Malsch","March","Marxzell","Marzell","Maulburg","Monchweiler","Muhlenbach","Mullheim","Munstertal","Murg","Nagold","Neubulach","Neuenburg","Neuhausen","Neuried","Neuweiler","Niedereschach","Nordrach","Oberharmersbach","Oberkirch","Oberndorf","Oberbach","Oberried","Oberwolfach","Offenburg","Ohlsbach","Oppenau","Ortenberg","otigheim","Ottenhofen","Ottersweier","Peterstal","Pfaffenweiler","Pfalzgrafenweiler","Pforzheim","Rastatt","Renchen","Rheinau","Rheinfelden","Rheinmunster","Rickenbach","Rippoldsau","Rohrdorf","Rottweil","Rummingen","Rust","Sackingen","Sasbach","Sasbachwalden","Schallbach","Schallstadt","Schapbach","Schenkenzell","Schiltach","Schliengen","Schluchsee","Schomberg","Schonach","Schonau","Schonenberg","Schonwald","Schopfheim","Schopfloch","Schramberg","Schuttertal","Schwenningen","Schworstadt","Seebach","Seelbach","Seewald","Sexau","Simmersfeld","Simonswald","Sinzheim","Solden","Staufen","Stegen","Steinach","Steinen","Steinmauern","Straubenhardt","Stuhlingen","Sulz","Sulzburg","Teinach","Tiefenbronn","Tiengen","Titisee","Todtmoos","Todtnau","Todtnauberg","Triberg","Tunau","Tuningen","uhlingen","Unterkirnach","Reichenbach","Utzenfeld","Villingen","Villingendorf","Vogtsburg","Vohrenbach","Waldachtal","Waldbronn","Waldkirch","Waldshut","Wehr","Weil","Weilheim","Weisenbach","Wembach","Wieden","Wiesental","Wildberg","Winzeln","Wittlingen","Wittnau","Wolfach","Wutach","Wutoschingen","Wyhlen","Zavelstein"], - ["Abingdon","Albrighton","Alcester","Almondbury","Altrincham","Amersham","Andover","Appleby","Ashboume","Atherstone","Aveton","Axbridge","Aylesbury","Baldock","Bamburgh","Barton","Basingstoke","Berden","Bere","Berkeley","Berwick","Betley","Bideford","Bingley","Birmingham","Blandford","Blechingley","Bodmin","Bolton","Bootham","Boroughbridge","Boscastle","Bossinney","Bramber","Brampton","Brasted","Bretford","Bridgetown","Bridlington","Bromyard","Bruton","Buckingham","Bungay","Burton","Calne","Cambridge","Canterbury","Carlisle","Castleton","Caus","Charmouth","Chawleigh","Chichester","Chillington","Chinnor","Chipping","Chisbury","Cleobury","Clifford","Clifton","Clitheroe","Cockermouth","Coleshill","Combe","Congleton","Crafthole","Crediton","Cuddenbeck","Dalton","Darlington","Dodbrooke","Drax","Dudley","Dunstable","Dunster","Dunwich","Durham","Dymock","Exeter","Exning","Faringdon","Felton","Fenny","Finedon","Flookburgh","Fowey","Frampton","Gateshead","Gatton","Godmanchester","Grampound","Grantham","Guildford","Halesowen","Halton","Harbottle","Harlow","Hatfield","Hatherleigh","Haydon","Helston","Henley","Hertford","Heytesbury","Hinckley","Hitchin","Holme","Hornby","Horsham","Kendal","Kenilworth","Kilkhampton","Kineton","Kington","Kinver","Kirby","Knaresborough","Knutsford","Launceston","Leighton","Lewes","Linton","Louth","Luton","Lyme","Lympstone","Macclesfield","Madeley","Malborough","Maldon","Manchester","Manningtree","Marazion","Marlborough","Marshfield","Mere","Merryfield","Middlewich","Midhurst","Milborne","Mitford","Modbury","Montacute","Mousehole","Newbiggin","Newborough","Newbury","Newenden","Newent","Norham","Northleach","Noss","Oakham","Olney","Orford","Ormskirk","Oswestry","Padstow","Paignton","Penkneth","Penrith","Penzance","Pershore","Petersfield","Pevensey","Pickering","Pilton","Pontefract","Portsmouth","Preston","Quatford","Reading","Redcliff","Retford","Rockingham","Romney","Rothbury","Rothwell","Salisbury","Saltash","Seaford","Seasalter","Sherston","Shifnal","Shoreham","Sidmouth","Skipsea","Skipton","Solihull","Somerton","Southam","Southwark","Standon","Stansted","Stapleton","Stottesdon","Sudbury","Swavesey","Tamerton","Tarporley","Tetbury","Thatcham","Thaxted","Thetford","Thornbury","Tintagel","Tiverton","Torksey","Totnes","Towcester","Tregoney","Trematon","Tutbury","Uxbridge","Wallingford","Wareham","Warenmouth","Wargrave","Warton","Watchet","Watford","Wendover","Westbury","Westcheap","Weymouth","Whitford","Wickwar","Wigan","Wigmore","Winchelsea","Winkleigh","Wiscombe","Witham","Witheridge","Wiveliscombe","Woodbury","Yeovil"], - ["Adon","Aillant","Amilly","Andonville","Ardon","Artenay","Ascheres","Ascoux","Attray","Aubin","Audeville","Aulnay","Autruy","Auvilliers","Auxy","Aveyron","Baccon","Bardon","Barville","Batilly","Baule","Bazoches","Beauchamps","Beaugency","Beaulieu","Beaune","Bellegarde","Boesses","Boigny","Boiscommun","Boismorand","Boisseaux","Bondaroy","Bonnee","Bonny","Bordes","Bou","Bougy","Bouilly","Boulay","Bouzonville","Bouzy","Boynes","Bray","Breteau","Briare","Briarres","Bricy","Bromeilles","Bucy","Cepoy","Cercottes","Cerdon","Cernoy","Cesarville","Chailly","Chaingy","Chalette","Chambon","Champoulet","Chanteau","Chantecoq","Chapell","Charme","Charmont","Charsonville","Chateau","Chateauneuf","Chatel","Chatenoy","Chatillon","Chaussy","Checy","Chevannes","Chevillon","Chevilly","Chevry","Chilleurs","Choux","Chuelles","Clery","Coinces","Coligny","Combleux","Combreux","Conflans","Corbeilles","Corquilleroy","Cortrat","Coudroy","Coullons","Coulmiers","Courcelles","Courcy","Courtemaux","Courtempierre","Courtenay","Cravant","Crottes","Dadonville","Dammarie","Dampierre","Darvoy","Desmonts","Dimancheville","Donnery","Dordives","Dossainville","Douchy","Dry","Echilleuses","Egry","Engenville","Epieds","Erceville","Ervauville","Escrennes","Escrignelles","Estouy","Faverelles","Fay","Feins","Ferolles","Ferrieres","Fleury","Fontenay","Foret","Foucherolles","Freville","Gatinais","Gaubertin","Gemigny","Germigny","Gidy","Gien","Girolles","Givraines","Gondreville","Grangermont","Greneville","Griselles","Guigneville","Guilly","Gyleslonains","Huetre","Huisseau","Ingrannes","Ingre","Intville","Isdes","Jargeau","Jouy","Juranville","Bussiere","Laas","Ladon","Lailly","Langesse","Leouville","Ligny","Lombreuil","Lorcy","Lorris","Loury","Louzouer","Malesherbois","Marcilly","Mardie","Mareau","Marigny","Marsainvilliers","Melleroy","Menestreau","Merinville","Messas","Meung","Mezieres","Migneres","Mignerette","Mirabeau","Montargis","Montbarrois","Montbouy","Montcresson","Montereau","Montigny","Montliard","Mormant","Morville","Moulinet","Moulon","Nancray","Nargis","Nesploy","Neuville","Neuvy","Nevoy","Nibelle","Nogent","Noyers","Ocre","Oison","Olivet","Ondreville","Onzerain","Orleans","Ormes","Orville","Oussoy","Outarville","Ouzouer","Pannecieres","Pannes","Patay","Paucourt","Pers","Pierrefitte","Pithiverais","Pithiviers","Poilly","Potier","Prefontaines","Presnoy","Pressigny","Puiseaux","Quiers","Ramoulu","Rebrechien","Rouvray","Rozieres","Rozoy","Ruan","Sandillon","Santeau","Saran","Sceaux","Seichebrieres","Semoy","Sennely","Sermaises","Sigloy","Solterre","Sougy","Sully","Sury","Tavers","Thignonville","Thimory","Thorailles","Thou","Tigy","Tivernon","Tournoisis","Trainou","Treilles","Trigueres","Trinay","Vannes","Varennes","Vennecy","Vieilles","Vienne","Viglain","Vignes","Villamblain","Villemandeur","Villemoutiers","Villemurlin","Villeneuve","Villereau","Villevoques","Villorceau","Vimory","Vitry","Vrigny","Ivre"], - ["Accumoli","Acquafondata","Acquapendente","Acuto","Affile","Agosta","Alatri","Albano","Allumiere","Alvito","Amaseno","Amatrice","Anagni","Anguillara","Anticoli","Antrodoco","Anzio","Aprilia","Aquino","Arce","Arcinazzo","Ardea","Ariccia","Arlena","Arnara","Arpino","Arsoli","Artena","Ascrea","Atina","Ausonia","Bagnoregio","Barbarano","Bassano","Bassiano","Bellegra","Belmonte","Blera","Bolsena","Bomarzo","Borbona","Borgo","Borgorose","Boville","Bracciano","Broccostella","Calcata","Camerata","Campagnano","Campodimele","Campoli","Canale","Canepina","Canino","Cantalice","Cantalupo","Canterano","Capena","Capodimonte","Capranica","Caprarola","Carbognano","Casalattico","Casalvieri","Casape","Casaprota","Casperia","Cassino","Castelforte","Castelliri","Castello","Castelnuovo","Castiglione","Castro","Castrocielo","Cave","Ceccano","Celleno","Cellere","Ceprano","Cerreto","Cervara","Cervaro","Cerveteri","Ciampino","Ciciliano","Cineto","Cisterna","Cittaducale","Cittareale","Civita","Civitavecchia","Civitella","Colfelice","Collalto","Colle","Colleferro","Collegiove","Collepardo","Collevecchio","Colli","Colonna","Concerviano","Configni","Contigliano","Corchiano","Coreno","Cori","Cottanello","Esperia","Fabrica","Faleria","Falvaterra","Fara","Farnese","Ferentino","Fiamignano","Fiano","Filacciano","Filettino","Fiuggi","Fiumicino","Fondi","Fontana","Fonte","Fontechiari","Forano","Formello","Formia","Frascati","Frasso","Frosinone","Fumone","Gaeta","Gallese","Gallicano","Gallinaro","Gavignano","Genazzano","Genzano","Gerano","Giuliano","Gorga","Gradoli","Graffignano","Greccio","Grottaferrata","Grotte","Guarcino","Guidonia","Ischia","Isola","Itri","Jenne","Labico","Labro","Ladispoli","Lanuvio","Lariano","Latera","Lenola","Leonessa","Licenza","Longone","Lubriano","Maenza","Magliano","Mandela","Manziana","Marano","Marcellina","Marcetelli","Marino","Marta","Mazzano","Mentana","Micigliano","Minturno","Mompeo","Montalto","Montasola","Monte","Montebuono","Montefiascone","Monteflavio","Montelanico","Monteleone","Montelibretti","Montenero","Monterosi","Monterotondo","Montopoli","Montorio","Moricone","Morlupo","Morolo","Morro","Nazzano","Nemi","Nepi","Nerola","Nespolo","Nettuno","Norma","Olevano","Onano","Oriolo","Orte","Orvinio","Paganico","Palestrina","Paliano","Palombara","Pastena","Patrica","Percile","Pescorocchiano","Pescosolido","Petrella","Piansano","Picinisco","Pico","Piedimonte","Piglio","Pignataro","Pisoniano","Pofi","Poggio","Poli","Pomezia","Pontecorvo","Pontinia","Ponza","Ponzano","Posta","Pozzaglia","Priverno","Proceno","Prossedi","Riano","Rieti","Rignano","Riofreddo","Ripi","Rivodutri","Rocca","Roccagiovine","Roccagorga","Roccantica","Roccasecca","Roiate","Ronciglione","Roviano","Sabaudia","Sacrofano","Salisano","Sambuci","Santa","Santi","Santopadre","Saracinesco","Scandriglia","Segni","Selci","Sermoneta","Serrone","Settefrati","Sezze","Sgurgola","Sonnino","Sora","Soriano","Sperlonga","Spigno","Stimigliano","Strangolagalli","Subiaco","Supino","Sutri","Tarano","Tarquinia","Terelle","Terracina","Tessennano","Tivoli","Toffia","Tolfa","Torre","Torri","Torrice","Torricella","Torrita","Trevi","Trevignano","Trivigliano","Turania","Tuscania","Vacone","Valentano","Vallecorsa","Vallemaio","Vallepietra","Vallerano","Vallerotonda","Vallinfreda","Valmontone","Varco","Vasanello","Vejano","Velletri","Ventotene","Veroli","Vetralla","Vicalvi","Vico","Vicovaro","Vignanello","Viterbo","Viticuso","Vitorchiano","Vivaro","Zagarolo"], - ["Abanades","Ablanque","Adobes","Ajofrin","Alameda","Alaminos","Alarilla","Albalate","Albares","Albarreal","Albendiego","Alcabon","Alcanizo","Alcaudete","Alcocer","Alcolea","Alcoroches","Aldea","Aldeanueva","Algar","Algora","Alhondiga","Alique","Almadrones","Almendral","Almoguera","Almonacid","Almorox","Alocen","Alovera","Alustante","Angon","Anguita","Anover","Anquela","Arbancon","Arbeteta","Arcicollar","Argecilla","Arges","Armallones","Armuna","Arroyo","Atanzon","Atienza","Aunon","Azuqueca","Azutan","Baides","Banos","Banuelos","Barcience","Bargas","Barriopedro","Belvis","Berninches","Borox","Brihuega","Budia","Buenaventura","Bujalaro","Burguillos","Burujon","Bustares","Cabanas","Cabanillas","Calera","Caleruela","Calzada","Camarena","Campillo","Camunas","Canizar","Canredondo","Cantalojas","Cardiel","Carmena","Carranque","Carriches","Casa","Casarrubios","Casas","Casasbuenas","Caspuenas","Castejon","Castellar","Castilforte","Castillo","Castilnuevo","Cazalegas","Cebolla","Cedillo","Cendejas","Centenera","Cervera","Checa","Chequilla","Chillaron","Chiloeches","Chozas","Chueca","Cifuentes","Cincovillas","Ciruelas","Ciruelos","Cobeja","Cobeta","Cobisa","Cogollor","Cogolludo","Condemios","Congostrina","Consuegra","Copernal","Corduente","Corral","Cuerva","Domingo","Dosbarrios","Driebes","Duron","El","Embid","Erustes","Escalona","Escalonilla","Escamilla","Escariche","Escopete","Espinosa","Espinoso","Esplegares","Esquivias","Estables","Estriegana","Fontanar","Fuembellida","Fuensalida","Fuentelsaz","Gajanejos","Galve","Galvez","Garciotum","Gascuena","Gerindote","Guadamur","Henche","Heras","Herreria","Herreruela","Hijes","Hinojosa","Hita","Hombrados","Hontanar","Hontoba","Horche","Hormigos","Huecas","Huermeces","Huerta","Hueva","Humanes","Illan","Illana","Illescas","Iniestola","Irueste","Jadraque","Jirueque","Lagartera","Las","Layos","Ledanca","Lillo","Lominchar","Loranca","Los","Lucillos","Lupiana","Luzaga","Luzon","Madridejos","Magan","Majaelrayo","Malaga","Malaguilla","Malpica","Mandayona","Mantiel","Manzaneque","Maqueda","Maranchon","Marchamalo","Marjaliza","Marrupe","Mascaraque","Masegoso","Matarrubia","Matillas","Mazarete","Mazuecos","Medranda","Megina","Mejorada","Mentrida","Mesegar","Miedes","Miguel","Millana","Milmarcos","Mirabueno","Miralrio","Mocejon","Mochales","Mohedas","Molina","Monasterio","Mondejar","Montarron","Mora","Moratilla","Morenilla","Muduex","Nambroca","Navalcan","Negredo","Noblejas","Noez","Nombela","Noves","Numancia","Nuno","Ocana","Ocentejo","Olias","Olmeda","Ontigola","Orea","Orgaz","Oropesa","Otero","Palmaces","Palomeque","Pantoja","Pardos","Paredes","Pareja","Parrillas","Pastrana","Pelahustan","Penalen","Penalver","Pepino","Peralejos","Peralveche","Pinilla","Pioz","Piqueras","Polan","Portillo","Poveda","Pozo","Pradena","Prados","Puebla","Puerto","Pulgar","Quer","Quero","Quintanar","Quismondo","Rebollosa","Recas","Renera","Retamoso","Retiendas","Riba","Rielves","Rillo","Riofrio","Robledillo","Robledo","Romanillos","Romanones","Rueda","Sacecorbo","Sacedon","Saelices","Salmeron","San","Santa","Santiuste","Santo","Sartajada","Sauca","Sayaton","Segurilla","Selas","Semillas","Sesena","Setiles","Sevilleja","Sienes","Siguenza","Solanillos","Somolinos","Sonseca","Sotillo","Sotodosos","Talavera","Tamajon","Taragudo","Taravilla","Tartanedo","Tembleque","Tendilla","Terzaga","Tierzo","Tordellego","Tordelrabano","Tordesilos","Torija","Torralba","Torre","Torrecilla","Torrecuadrada","Torrejon","Torremocha","Torrico","Torrijos","Torrubia","Tortola","Tortuera","Tortuero","Totanes","Traid","Trijueque","Trillo","Turleque","Uceda","Ugena","Ujados","Urda","Utande","Valdarachas","Valdesotos","Valhermoso","Valtablado","Valverde","Velada","Viana","Vinuelas","Yebes","Yebra","Yelamos","Yeles","Yepes","Yuncler","Yunclillos","Yuncos","Yunquera","Zaorejas","Zarzuela","Zorita"], - ["Belgorod","Beloberezhye","Belyi","Belz","Berestiy","Berezhets","Berezovets","Berezutsk","Bobruisk","Bolonets","Borisov","Borovsk","Bozhesk","Bratslav","Bryansk","Brynsk","Buryn","Byhov","Chechersk","Chemesov","Cheremosh","Cherlen","Chern","Chernigov","Chernitsa","Chernobyl","Chernogorod","Chertoryesk","Chetvertnia","Demyansk","Derevesk","Devyagoresk","Dichin","Dmitrov","Dorogobuch","Dorogobuzh","Drestvin","Drokov","Drutsk","Dubechin","Dubichi","Dubki","Dubkov","Dveren","Galich","Glebovo","Glinsk","Goloty","Gomiy","Gorodets","Gorodische","Gorodno","Gorohovets","Goroshin","Gorval","Goryshon","Holm","Horobor","Hoten","Hotin","Hotmyzhsk","Ilovech","Ivan","Izborsk","Izheslavl","Kamenets","Kanev","Karachev","Karna","Kavarna","Klechesk","Klyapech","Kolomyya","Kolyvan","Kopyl","Korec","Kornik","Korochunov","Korshev","Korsun","Koshkin","Kotelno","Kovyla","Kozelsk","Kozelsk","Kremenets","Krichev","Krylatsk","Ksniatin","Kulatsk","Kursk","Kursk","Lebedev","Lida","Logosko","Lomihvost","Loshesk","Loshichi","Lubech","Lubno","Lubutsk","Lutsk","Luchin","Luki","Lukoml","Luzha","Lvov","Mtsensk","Mdin","Medniki","Melecha","Merech","Meretsk","Mescherskoe","Meshkovsk","Metlitsk","Mezetsk","Mglin","Mihailov","Mikitin","Mikulino","Miloslavichi","Mogilev","Mologa","Moreva","Mosalsk","Moschiny","Mozyr","Mstislav","Mstislavets","Muravin","Nemech","Nemiza","Nerinsk","Nichan","Novgorod","Novogorodok","Obolichi","Obolensk","Obolensk","Oleshsk","Olgov","Omelnik","Opoka","Opoki","Oreshek","Orlets","Osechen","Oster","Ostrog","Ostrov","Perelai","Peremil","Peremyshl","Pererov","Peresechen","Perevitsk","Pereyaslav","Pinsk","Ples","Polotsk","Pronsk","Proposhesk","Punia","Putivl","Rechitsa","Rodno","Rogachev","Romanov","Romny","Roslavl","Rostislavl","Rostovets","Rsha","Ruza","Rybchesk","Rylsk","Rzhavesk","Rzhev","Rzhischev","Sambor","Serensk","Serensk","Serpeysk","Shilov","Shuya","Sinech","Sizhka","Skala","Slovensk","Slutsk","Smedin","Sneporod","Snitin","Snovsk","Sochevo","Sokolec","Starica","Starodub","Stepan","Sterzh","Streshin","Sutesk","Svinetsk","Svisloch","Terebovl","Ternov","Teshilov","Teterin","Tiversk","Torchevsk","Toropets","Torzhok","Tripolye","Trubchevsk","Tur","Turov","Usvyaty","Uteshkov","Vasilkov","Velil","Velye","Venev","Venicha","Verderev","Vereya","Veveresk","Viazma","Vidbesk","Vidychev","Voino","Volodimer","Volok","Volyn","Vorobesk","Voronich","Voronok","Vorotynsk","Vrev","Vruchiy","Vselug","Vyatichsk","Vyatka","Vyshegorod","Vyshgorod","Vysokoe","Yagniatin","Yaropolch","Yasenets","Yuryev","Yuryevets","Zaraysk","Zhitomel","Zholvazh","Zizhech","Zubkov","Zudechev","Zvenigorod"], - ["Akureyri","Aldra","Alftanes","Andenes","Austbo","Auvog","Bakkafjordur","Ballangen","Bardal","Beisfjord","Bifrost","Bildudalur","Bjerka","Bjerkvik","Bjorkosen","Bliksvaer","Blokken","Blonduos","Bolga","Bolungarvik","Borg","Borgarnes","Bosmoen","Bostad","Bostrand","Botsvika","Brautarholt","Breiddalsvik","Bringsli","Brunahlid","Budardalur","Byggdakjarni","Dalvik","Djupivogur","Donnes","Drageid","Drangsnes","Egilsstadir","Eiteroga","Elvenes","Engavogen","Ertenvog","Eskifjordur","Evenes","Eyrarbakki","Fagernes","Fallmoen","Fellabaer","Fenes","Finnoya","Fjaer","Fjelldal","Flakstad","Flateyri","Flostrand","Fludir","Gardabær","Gardur","Gimstad","Givaer","Gjeroy","Gladstad","Godoya","Godoynes","Granmoen","Gravdal","Grenivik","Grimsey","Grindavik","Grytting","Hafnir","Halsa","Hauganes","Haugland","Hauknes","Hella","Helland","Hellissandur","Hestad","Higrav","Hnifsdalur","Hofn","Hofsos","Holand","Holar","Holen","Holkestad","Holmavik","Hopen","Hovden","Hrafnagil","Hrisey","Husavik","Husvik","Hvammstangi","Hvanneyri","Hveragerdi","Hvolsvollur","Igeroy","Indre","Inndyr","Innhavet","Innes","Isafjordur","Jarklaustur","Jarnsreykir","Junkerdal","Kaldvog","Kanstad","Karlsoy","Kavosen","Keflavik","Kjelde","Kjerstad","Klakk","Kopasker","Kopavogur","Korgen","Kristnes","Krutoga","Krystad","Kvina","Lande","Laugar","Laugaras","Laugarbakki","Laugarvatn","Laupstad","Leines","Leira","Leiren","Leland","Lenvika","Loding","Lodingen","Lonsbakki","Lopsmarka","Lovund","Luroy","Maela","Melahverfi","Meloy","Mevik","Misvaer","Mornes","Mosfellsbær","Moskenes","Myken","Naurstad","Nesberg","Nesjahverfi","Nesset","Nevernes","Obygda","Ofoten","Ogskardet","Okervika","Oknes","Olafsfjordur","Oldervika","Olstad","Onstad","Oppeid","Oresvika","Orsnes","Orsvog","Osmyra","Overdal","Prestoya","Raudalaekur","Raufarhofn","Reipo","Reykholar","Reykholt","Reykjahlid","Rif","Rinoya","Rodoy","Rognan","Rosvika","Rovika","Salhus","Sanden","Sandgerdi","Sandoker","Sandset","Sandvika","Saudarkrokur","Selfoss","Selsoya","Sennesvik","Setso","Siglufjordur","Silvalen","Skagastrond","Skjerstad","Skonland","Skorvogen","Skrova","Sleneset","Snubba","Softing","Solheim","Solheimar","Sorarnoy","Sorfugloy","Sorland","Sormela","Sorvaer","Sovika","Stamsund","Stamsvika","Stave","Stokka","Stokkseyri","Storjord","Storo","Storvika","Strand","Straumen","Strendene","Sudavik","Sudureyri","Sundoya","Sydalen","Thingeyri","Thorlakshofn","Thorshofn","Tjarnabyggd","Tjotta","Tosbotn","Traelnes","Trofors","Trones","Tverro","Ulvsvog","Unnstad","Utskor","Valla","Vandved","Varmahlid","Vassos","Vevelstad","Vidrek","Vik","Vikholmen","Vogar","Vogehamn","Vopnafjordur"], - ["Abdera","Abila","Abydos","Acanthus","Acharnae","Actium","Adramyttium","Aegae","Aegina","Aegium","Aenus","Agrinion","Aigosthena","Akragas","Akrai","Akrillai","Akroinon","Akrotiri","Alalia","Alexandreia","Alexandretta","Alexandria","Alinda","Amarynthos","Amaseia","Ambracia","Amida","Amisos","Amnisos","Amphicaea","Amphigeneia","Amphipolis","Amphissa","Ankon","Antigona","Antipatrea","Antioch","Antioch","Antiochia","Andros","Apamea","Aphidnae","Apollonia","Argos","Arsuf","Artanes","Artemita","Argyroupoli","Asine","Asklepios","Aspendos","Assus","Astacus","Athenai","Athmonia","Aytos","Ancient","Baris","Bhrytos","Borysthenes","Berge","Boura","Bouthroton","Brauron","Byblos","Byllis","Byzantium","Bythinion","Callipolis","Cebrene","Chalcedon","Calydon","Carystus","Chamaizi","Chalcis","Chersonesos","Chios","Chytri","Clazomenae","Cleonae","Cnidus","Colosse","Corcyra","Croton","Cyme","Cyrene","Cythera","Decelea","Delos","Delphi","Demetrias","Dicaearchia","Dimale","Didyma","Dion","Dioscurias","Dodona","Dorylaion","Dyme","Edessa","Elateia","Eleusis","Eleutherna","Emporion","Ephesus","Ephyra","Epidamnos","Epidauros","Eresos","Eretria","Erythrae","Eubea","Gangra","Gaza","Gela","Golgi","Gonnos","Gorgippia","Gournia","Gortyn","Gythium","Hagios","Hagia","Halicarnassus","Halieis","Helike","Heliopolis","Hellespontos","Helorus","Hemeroskopeion","Heraclea","Hermione","Hermonassa","Hierapetra","Hierapolis","Himera","Histria","Hubla","Hyele","Ialysos","Iasus","Idalium","Imbros","Iolcus","Itanos","Ithaca","Juktas","Kallipolis","Kamares","Kameiros","Kannia","Kamarina","Kasmenai","Katane","Kerkinitida","Kepoi","Kimmerikon","Kios","Klazomenai","Knidos","Knossos","Korinthos","Kos","Kourion","Kume","Kydonia","Kynos","Kyrenia","Lamia","Lampsacus","Laodicea","Lapithos","Larissa","Lato","Laus","Lebena","Lefkada","Lekhaion","Leibethra","Leontinoi","Lepreum","Lessa","Lilaea","Lindus","Lissus","Epizephyrian","Madytos","Magnesia","Mallia","Mantineia","Marathon","Marmara","Maroneia","Masis","Massalia","Megalopolis","Megara","Mesembria","Messene","Metapontum","Methana","Methone","Methumna","Miletos","Misenum","Mochlos","Monastiraki","Morgantina","Mulai","Mukenai","Mylasa","Myndus","Myonia","Myra","Myrmekion","Mutilene","Myos","Nauplíos","Naucratis","Naupactus","Naxos","Neapoli","Neapolis","Nemea","Nicaea","Nicopolis","Nirou","Nymphaion","Nysa","Oenoe","Oenus","Odessos","Olbia","Olous","Olympia","Olynthus","Opus","Orchomenus","Oricos","Orestias","Oreus","Oropus","Onchesmos","Pactye","Pagasae","Palaikastro","Pandosia","Panticapaeum","Paphos","Parium","Paros","Parthenope","Patrae","Pavlopetri","Pegai","Pelion","Peiraieús","Pella","Percote","Pergamum","Petsofa","Phaistos","Phaleron","Phanagoria","Pharae","Pharnacia","Pharos","Phaselis","Philippi","Pithekussa","Philippopolis","Platanos","Phlius","Pherae","Phocaea","Pinara","Pisa","Pitane","Pitiunt","Pixous","Plataea","Poseidonia","Potidaea","Priapus","Priene","Prousa","Pseira","Psychro","Pteleum","Pydna","Pylos","Pyrgos","Rhamnus","Rhegion","Rhithymna","Rhodes","Rhypes","Rizinia","Salamis","Same","Samos","Scyllaeum","Selinus","Seleucia","Semasus","Sestos","Scidrus","Sicyon","Side","Sidon","Siteia","Sinope","Siris","Sklavokampos","Smyrna","Soli","Sozopolis","Sparta","Stagirus","Stratos","Stymphalos","Sybaris","Surakousai","Taras","Tanagra","Tanais","Tauromenion","Tegea","Temnos","Tenedos","Tenea","Teos","Thapsos","Thassos","Thebai","Theodosia","Therma","Thespiae","Thronion","Thoricus","Thurii","Thyreum","Thyria","Tiruns","Tithoraea","Tomis","Tragurion","Trapeze","Trapezus","Tripolis","Troizen","Troliton","Troy","Tylissos","Tyras","Tyros","Tyritake","Vasiliki","Vathypetros","Zakynthos","Zakros","Zankle"], - ["Abila","Adflexum","Adnicrem","Aelia","Aelius","Aeminium","Aequum","Agrippina","Agrippinae","Ala","Albanianis","Ambianum","Andautonia","Apulum","Aquae","Aquaegranni","Aquensis","Aquileia","Aquincum","Arae","Argentoratum","Ariminum","Ascrivium","Atrebatum","Atuatuca","Augusta","Aurelia","Aurelianorum","Batavar","Batavorum","Belum","Biriciana","Blestium","Bonames","Bonna","Bononia","Borbetomagus","Bovium","Bracara","Brigantium","Burgodunum","Caesaraugusta","Caesarea","Caesaromagus","Calleva","Camulodunum","Cannstatt","Cantiacorum","Capitolina","Castellum","Castra","Castrum","Cibalae","Clausentum","Colonia","Concangis","Condate","Confluentes","Conimbriga","Corduba","Coria","Corieltauvorum","Corinium","Coriovallum","Cornoviorum","Danum","Deva","Divodurum","Dobunnorum","Drusi","Dubris","Dumnoniorum","Durnovaria","Durocobrivis","Durocornovium","Duroliponte","Durovernum","Durovigutum","Eboracum","Edetanorum","Emerita","Emona","Euracini","Faventia","Flaviae","Florentia","Forum","Gerulata","Gerunda","Glevensium","Hadriani","Herculanea","Isca","Italica","Iulia","Iuliobrigensium","Iuvavum","Lactodurum","Lagentium","Lauri","Legionis","Lemanis","Lentia","Lepidi","Letocetum","Lindinis","Lindum","Londinium","Lopodunum","Lousonna","Lucus","Lugdunum","Luguvalium","Lutetia","Mancunium","Marsonia","Martius","Massa","Matilo","Mattiacorum","Mediolanum","Mod","Mogontiacum","Moridunum","Mursa","Naissus","Nervia","Nida","Nigrum","Novaesium","Noviomagus","Olicana","Ovilava","Parisiorum","Partiscum","Paterna","Pistoria","Placentia","Pollentia","Pomaria","Pons","Portus","Praetoria","Praetorium","Pullum","Ragusium","Ratae","Raurica","Regina","Regium","Regulbium","Rigomagus","Roma","Romula","Rutupiae","Salassorum","Salernum","Salona","Scalabis","Segovia","Silurum","Sirmium","Siscia","Sorviodurum","Sumelocenna","Tarraco","Taurinorum","Theranda","Traiectum","Treverorum","Tungrorum","Turicum","Ulpia","Valentia","Venetiae","Venta","Verulamium","Vesontio","Vetera","Victoriae","Victrix","Villa","Viminacium","Vindelicorum","Vindobona","Vinovia","Viroconium"], - ["Aanekoski","Abjapaluoja","Ahlainen","Aholanvaara","Ahtari","Aijala","Aimala","Akaa","Alajarvi","Alatornio","Alavus","Antsla","Aspo","Bennas","Bjorkoby","Elva","Emasalo","Espoo","Esse","Evitskog","Forssa","Haapajarvi","Haapamaki","Haapavesi","Haapsalu","Haavisto","Hameenlinna","Hameenmaki","Hamina","Hanko","Harjavalta","Hattuvaara","Haukipudas","Hautajarvi","Havumaki","Heinola","Hetta","Hinkabole","Hirmula","Hossa","Huittinen","Husula","Hyryla","Hyvinkaa","Iisalmi","Ikaalinen","Ilmola","Imatra","Inari","Iskmo","Itakoski","Jamsa","Jarvenpaa","Jeppo","Jioesuu","Jiogeva","Joensuu","Jokela","Jokikyla","Jokisuu","Jormua","Juankoski","Jungsund","Jyvaskyla","Kaamasmukka","Kaarina","Kajaani","Kalajoki","Kallaste","Kankaanpaa","Kannus","Kardla","Karesuvanto","Karigasniemi","Karkkila","Karkku","Karksinuia","Karpankyla","Kaskinen","Kasnas","Kauhajoki","Kauhava","Kauniainen","Kauvatsa","Kehra","Keila","Kellokoski","Kelottijarvi","Kemi","Kemijarvi","Kerava","Keuruu","Kiikka","Kiipu","Kilinginiomme","Kiljava","Kilpisjarvi","Kitee","Kiuruvesi","Kivesjarvi","Kiviioli","Kivisuo","Klaukkala","Klovskog","Kohtlajarve","Kokemaki","Kokkola","Kolho","Koria","Koskue","Kotka","Kouva","Kouvola","Kristiina","Kaupunki","Kuhmo","Kunda","Kuopio","Kuressaare","Kurikka","Kusans","Kuusamo","Kylmalankyla","Lahti","Laitila","Lankipohja","Lansikyla","Lappeenranta","Lapua","Laurila","Lautiosaari","Lepsama","Liedakkala","Lieksa","Lihula","Littoinen","Lohja","Loimaa","Loksa","Loviisa","Luohuanylipaa","Lusi","Maardu","Maarianhamina","Malmi","Mantta","Masaby","Masala","Matasvaara","Maula","Miiluranta","Mikkeli","Mioisakula","Munapirtti","Mustvee","Muurahainen","Naantali","Nappa","Narpio","Nickby","Niinimaa","Niinisalo","Nikkila","Nilsia","Nivala","Nokia","Nummela","Nuorgam","Nurmes","Nuvvus","Obbnas","Oitti","Ojakkala","Ollola","onningeby","Orimattila","Orivesi","Otanmaki","Otava","Otepaa","Oulainen","Oulu","Outokumpu","Paavola","Paide","Paimio","Pakankyla","Paldiski","Parainen","Parkano","Parkumaki","Parola","Perttula","Pieksamaki","Pietarsaari","Pioltsamaa","Piolva","Pohjavaara","Porhola","Pori","Porrasa","Porvoo","Pudasjarvi","Purmo","Pussi","Pyhajarvi","Raahe","Raasepori","Raisio","Rajamaki","Rakvere","Rapina","Rapla","Rauma","Rautio","Reposaari","Riihimaki","Rovaniemi","Roykka","Ruonala","Ruottala","Rutalahti","Saarijarvi","Salo","Sastamala","Saue","Savonlinna","Seinajoki","Sillamae","Sindi","Siuntio","Somero","Sompujarvi","Suonenjoki","Suurejaani","Syrjantaka","Tampere","Tamsalu","Tapa","Temmes","Tiorva","Tormasenvaara","Tornio","Tottijarvi","Tulppio","Turenki","Turi","Tuukkala","Tuurala","Tuuri","Tuuski","Ulvila","Unari","Upinniemi","Utti","Uusikaarlepyy","Uusikaupunki","Vaaksy","Vaalimaa","Vaarinmaja","Vaasa","Vainikkala","Valga","Valkeakoski","Vantaa","Varkaus","Vehkapera","Vehmasmaki","Vieki","Vierumaki","Viitasaari","Viljandi","Vilppula","Viohma","Vioru","Virrat","Ylike","Ylivieska","Ylojarvi"], - ["Sabi","Wiryeseong","Hwando","Gungnae","Ungjin","Wanggeomseong","Ganggyeong","Jochiwon","Cheorwon","Beolgyo","Gangjin","Gampo","Yecheon","Geochang","Janghang","Hadong","Goseong","Yeongdong","Yesan","Sintaein","Geumsan","Boseong","Jangheung","Uiseong","Jumunjin","Janghowon","Hongseong","Gimhwa","Gwangcheon","Guryongpo","Jinyeong","Buan","Damyang","Jangseong","Wando","Angang","Okcheon","Jeungpyeong","Waegwan","Cheongdo","Gwangyang","Gochang","Haenam","Yeonggwang","Hanam","Eumseong","Daejeong","Hanrim","Samrye","Yongjin","Hamyang","Buyeo","Changnyeong","Yeongwol","Yeonmu","Gurye","Hwasun","Hampyeong","Namji","Samnangjin","Dogye","Hongcheon","Munsan","Gapyeong","Ganghwa","Geojin","Sangdong","Jeongseon","Sabuk","Seonghwan","Heunghae","Hapdeok","Sapgyo","Taean","Boeun","Geumwang","Jincheon","Bongdong","Doyang","Geoncheon","Pungsan","Punggi","Geumho","Wonju","Gaun","Hayang","Yeoju","Paengseong","Yeoncheon","Yangpyeong","Ganseong","Yanggu","Yangyang","Inje","Galmal","Pyeongchang","Hwacheon","Hoengseong","Seocheon","Cheongyang","Goesan","Danyang","Hamyeol","Muju","Sunchang","Imsil","Jangsu","Jinan","Goheung","Gokseong","Muan","Yeongam","Jindo","Seonsan","Daegaya","Gunwi","Bonghwa","Seongju","Yeongdeok","Yeongyang","Ulleung","Uljin","Cheongsong","wayang","Namhae","Sancheong","Uiryeong","Gaya","Hapcheon","Wabu","Dongsong","Sindong","Wondeok","Maepo","Anmyeon","Okgu","Sariwon","Dolsan","Daedeok","Gwansan","Geumil","Nohwa","Baeksu","Illo","Jido","Oedong","Ocheon","Yeonil","Hamchang","Pyeonghae","Gijang","Jeonggwan","Aewor","Gujwa","Seongsan","Jeongok","Seonggeo","Seungju","Hongnong","Jangan","Jocheon","Gohan","Jinjeop","Bubal","Beobwon","Yeomchi","Hwado","Daesan","Hwawon","Apo","Nampyeong","Munsan","Sinbuk","Munmak","Judeok","Bongyang","Ungcheon","Yugu","Unbong","Mangyeong","Dong","Naeseo","Sanyang","Soheul","Onsan","Eonyang","Nongong","Dasa","Goa","Jillyang","Bongdam","Naesu","Beomseo","Opo","Gongdo","Jingeon","Onam","Baekseok","Jiksan","Mokcheon","Jori","Anjung","Samho","Ujeong","Buksam","Tongjin","Chowol","Gonjiam","Pogok","Seokjeok","Poseung","Ochang","Hyangnam","Baebang","Gochon","Songak","Samhyang","Yangchon","Osong","Aphae","Ganam","Namyang","Chirwon","Andong","Ansan","Anseong","Anyang","Asan","Boryeong","Bucheon","Busan","Changwon","Cheonan","Cheongju","Chuncheon","Chungju","Daegu","Daejeon","Dangjin","Dongducheon","Donghae","Gangneung","Geoje","Gimcheon","Gimhae","Gimje","Gimpo","Gongju","Goyang","Gumi","Gunpo","Gunsan","Guri","Gwacheon","Gwangju","Gwangju","Gwangmyeong","Gyeongju","Gyeongsan","Gyeryong","Hwaseong","Icheon","Iksan","Incheon","Jecheon","Jeongeup","Jeonju","Jeju","Jinju","Naju","Namyangju","Namwon","Nonsan","Miryang","Mokpo","Mungyeong","Osan","Paju","Pocheon","Pohang","Pyeongtaek","Sacheon","Sangju","Samcheok","Sejong","Seogwipo","Seongnam","Seosan","Seoul","Siheung","Sokcho","Suncheon","Suwon","Taebaek","Tongyeong","Uijeongbu","Uiwang","Ulsan","Yangju","Yangsan","Yeongcheon","Yeongju","Yeosu","Yongin","Chungmu","Daecheon","Donggwangyang","Geumseong","Gyeongseong","Iri","Jangseungpo","Jeomchon","Jeongju","Migeum","Onyang","Samcheonpo","Busan","Busan","Cheongju","Chuncheon","Daegu","Daegu","Daejeon","Daejeon","Gunsan","Gwangju","Gwangju","Gyeongseong","Incheon","Incheon","Iri","Jeonju","Jinhae","Jinju","Masan","Masan","Mokpo","Songjeong","Songtan","Ulsan","Yeocheon","Cheongjin","Gaeseong","Haeju","Hamheung","Heungnam","Jinnampo","Najin","Pyeongyang","Seongjin","Sineuiju","Songnim","Wonsan"], - ["Anding","Anlu","Anqing","Anshun","Baan","Baixing","Banyang","Baoding","Baoqing","Binzhou","Caozhou","Changbai","Changchun","Changde","Changling","Changsha","Changtu","Changzhou","Chaozhou","Cheli","Chengde","Chengdu","Chenzhou","Chizhou","Chongqing","Chuxiong","Chuzhou","Dading","Dali","Daming","Datong","Daxing","Dean","Dengke","Dengzhou","Deqing","Dexing","Dihua","Dingli","Dongan","Dongchang","Dongchuan","Dongping","Duyun","Fengtian","Fengxiang","Fengyang","Fenzhou","Funing","Fuzhou","Ganzhou","Gaoyao","Gaozhou","Gongchang","Guangnan","Guangning","Guangping","Guangxin","Guangzhou","Guide","Guilin","Guiyang","Hailong","Hailun","Hangzhou","Hanyang","Hanzhong","Heihe","Hejian","Henan","Hengzhou","Hezhong","Huaian","Huaide","Huaiqing","Huanglong","Huangzhou","Huining","Huizhou","Hulan","Huzhou","Jiading","Jian","Jianchang","Jiande","Jiangning","Jiankang","Jianning","Jiaxing","Jiayang","Jilin","Jinan","Jingjiang","Jingzhao","Jingzhou","Jinhua","Jinzhou","Jiujiang","Kaifeng","Kaihua","Kangding","Kuizhou","Laizhou","Lanzhou","Leizhou","Liangzhou","Lianzhou","Liaoyang","Lijiang","Linan","Linhuang","Linjiang","Lintao","Liping","Liuzhou","Longan","Longjiang","Longqing","Longxing","Luan","Lubin","Lubin","Luzhou","Mishan","Nanan","Nanchang","Nandian","Nankang","Nanning","Nanyang","Nenjiang","Ningan","Ningbo","Ningguo","Ninguo","Ningwu","Ningxia","Ningyuan","Pingjiang","Pingle","Pingliang","Pingyang","Puer","Puzhou","Qianzhou","Qingyang","Qingyuan","Qingzhou","Qiongzhou","Qujing","Quzhou","Raozhou","Rende","Ruian","Ruizhou","Runing","Shafeng","Shajing","Shaoqing","Shaowu","Shaoxing","Shaozhou","Shinan","Shiqian","Shouchun","Shuangcheng","Shulei","Shunde","Shunqing","Shuntian","Shuoping","Sicheng","Sien","Sinan","Sizhou","Songjiang","Suiding","Suihua","Suining","Suzhou","Taian","Taibei","Tainan","Taiping","Taiwan","Taiyuan","Taizhou","Taonan","Tengchong","Tieli","Tingzhou","Tongchuan","Tongqing","Tongren","Tongzhou","Weihui","Wensu","Wenzhou","Wuchang","Wuding","Wuzhou","Xian","Xianchun","Xianping","Xijin","Xiliang","Xincheng","Xingan","Xingde","Xinghua","Xingjing","Xingqing","Xingyi","Xingyuan","Xingzhong","Xining","Xinmen","Xiping","Xuanhua","Xunzhou","Xuzhou","Yanan","Yangzhou","Yanji","Yanping","Yanqi","Yanzhou","Yazhou","Yichang","Yidu","Yilan","Yili","Yingchang","Yingde","Yingtian","Yingzhou","Yizhou","Yongchang","Yongping","Yongshun","Yongzhou","Yuanzhou","Yuezhou","Yulin","Yunnan","Yunyang","Zezhou","Zhangde","Zhangzhou","Zhaoqing","Zhaotong","Zhenan","Zhending","Zhengding","Zhenhai","Zhenjiang","Zhenxi","Zhenyun","Zhongshan","Zunyi"], - ["Nanporo","Naie","Kamisunagawa","Yuni","Naganuma","Kuriyama","Tsukigata","Urausu","Shintotsukawa","Moseushi","Chippubetsu","Uryu","Hokuryu","Numata","Tobetsu","Suttsu","Kuromatsunai","Rankoshi","Niseko","Kimobetsu","Kyogoku","Kutchan","Kyowa","Iwanai","Shakotan","Furubira","Niki","Yoichi","Toyoura","Toyako","Sobetsu","Shiraoi","Atsuma","Abira","Mukawa","Hidaka","Biratori","Niikappu","Urakawa","Samani","Erimo","Shinhidaka","Matsumae","Fukushima","Shiriuchi","Kikonai","Nanae","Shikabe","Mori","Yakumo","Oshamambe","Esashi","Kaminokuni","Assabu","Otobe","Okushiri","Imakane","Setana","Takasu","Higashikagura","Toma","Pippu","Aibetsu","Kamikawa","Higashikawa","Biei","Kamifurano","Nakafurano","Minamifurano","Horokanai","Wassamu","Kenbuchi","Shimokawa","Bifuka","Nakagawa","Mashike","Obira","Tomamae","Haboro","Enbetsu","Teshio","Hamatonbetsu","Nakatonbetsu","Esashi","Toyotomi","Horonobe","Rebun","Rishiri","Rishirifuji","Bihoro","Tsubetsu","Ozora","Shari","Kiyosato","Koshimizu","Kunneppu","Oketo","Saroma","Engaru","Yubetsu","Takinoue","Okoppe","Omu","Otofuke","Shihoro","Kamishihoro","Shikaoi","Shintoku","Shimizu","Memuro","Taiki","Hiroo","Makubetsu","Ikeda","Toyokoro","Honbetsu","Ashoro","Rikubetsu","Urahoro","Kushiro","Akkeshi","Hamanaka","Shibecha","Teshikaga","Shiranuka","Betsukai","Nakashibetsu","Shibetsu","Rausu","Hiranai","Imabetsu","Sotogahama","Ajigasawa","Fukaura","Fujisaki","Owani","Itayanagi","Tsuruta","Nakadomari","Noheji","Shichinohe","Rokunohe","Yokohama","Tohoku","Oirase","Oma","Sannohe","Gonohe","Takko","Nanbu","Hashikami","Shizukuishi","Kuzumaki","Iwate","Shiwa","Yahaba","Nishiwaga","Kanegasaki","Hiraizumi","Sumita","Otsuchi","Yamada","Iwaizumi","Karumai","Hirono","Ichinohe","Zao","Shichikashuku","Ogawara","Murata","Shibata","Kawasaki","Marumori","Watari","Yamamoto","Matsushima","Shichigahama","Rifu","Taiwa","Osato","Shikama","Kami","Wakuya","Misato","Onagawa","Minamisanriku","Kosaka","Fujisato","Mitane","Happo","Gojome","Hachirogata","Ikawa","Misato","Ugo","Yamanobe","Nakayama","Kahoku","Nishikawa","Asahi","Oe","Oishida","Kaneyama","Mogami","Funagata","Mamurogawa","Takahata","Kawanishi","Oguni","Shirataka","Iide","Mikawa","Shonai","Yuza","Koori","Kunimi","Kawamata","Kagamiishi","Shimogo","Tadami","Minamiaizu","Nishiaizu","Bandai","Inawashiro","Aizubange","Yanaizu","Mishima","Kaneyama","Aizumisato","Yabuki","Tanagura","Yamatsuri","Hanawa","Ishikawa","Asakawa","Furudono","Miharu","Ono","Hirono","Naraha","Tomioka","Okuma","Futaba","Namie","Shinchi","Ibaraki","Oarai","Shirosato","Daigo","Ami","Kawachi","Yachiyo","Goka","Sakai","Tone","Kaminokawa","Mashiko","Motegi","Ichikai","Haga","Mibu","Nogi","Shioya","Takanezawa","Nasu","Nakagawa","Yoshioka","Kanna","Shimonita","Kanra","Nakanojo","Naganohara","Kusatsu","Higashiagatsuma","Minakami","Tamamura","Itakura","Meiwa","Chiyoda","Oizumi","Ora","Ina","Miyoshi","Moroyama","Ogose","Namegawa","Ranzan","Ogawa","Kawajima","Yoshimi","Hatoyama","Tokigawa","Yokoze","Minano","Nagatoro","Ogano","Misato","Kamikawa","Kamisato","Yorii","Miyashiro","Sugito","Matsubushi","Shisui","Sakae","Kozaki","Tako","Tonosho","Kujukuri","Shibayama","Yokoshibahikari","Ichinomiya","Mutsuzawa","Shirako","Nagara","Chonan","Otaki","Onjuku","Kyonan","Mizuho","Hinode","Okutama","Oshima","Hachijo","Aikawa","Hayama","Samukawa","Oiso","Ninomiya","Nakai","Oi","Matsuda","Yamakita","Kaisei","Hakone","Manazuru","Yugawara","Seiro","Tagami","Aga","Izumozaki","Yuzawa","Tsunan","Kamiichi","Tateyama","Nyuzen","Asahi","Kawakita","Tsubata","Uchinada","Shika","Hodatsushimizu","Nakanoto","Anamizu","Noto","Eiheiji","Ikeda","Minamiechizen","Echizen","Mihama","Takahama","Oi","Wakasa","Ichikawamisato","Hayakawa","Minobu","Nanbu","Fujikawa","Showa","Nishikatsura","Fujikawaguchiko","Koumi","Sakuho","Karuizawa","Miyota","Tateshina","Nagawa","Shimosuwa","Fujimi","Tatsuno","Minowa","Iijima","Matsukawa","Takamori","Anan","Agematsu","Nagiso","Kiso","Ikeda","Sakaki","Obuse","Yamanouchi","Shinano","Iizuna","Ginan","Kasamatsu","Yoro","Tarui","Sekigahara","Godo","Wanouchi","Anpachi","Ibigawa","Ono","Ikeda","Kitagata","Sakahogi","Tomika","Kawabe","Hichiso","Yaotsu","Shirakawa","Mitake","Higashiizu","Kawazu","Minamiizu","Matsuzaki","Nishiizu","Kannami","Shimizu","Nagaizumi","Oyama","Yoshida","Kawanehon","Mori","Togo","Toyoyama","Oguchi","Fuso","Oharu","Kanie","Agui","Higashiura","Minamichita","Mihama","Taketoyo","Mihama","Kota","Shitara","Toei","Kisosaki","Toin","Komono","Asahi","Kawagoe","Taki","Meiwa","Odai","Tamaki","Watarai","Taiki","Minamiise","Kihoku","Mihama","Kiho","Hino","Ryuo","Aisho","Toyosato","Kora","Taga","Oyamazaki","Kumiyama","Ide","Ujitawara","Kasagi","Wazuka","Seika","Kyotamba","Ine","Yosano","Shimamoto","Toyono","Nose","Tadaoka","Kumatori","Tajiri","Misaki","Taishi","Kanan","Inagawa","Taka","Inami","Harima","Ichikawa","Fukusaki","Kamikawa","Taishi","Kamigori","Sayo","Kami","Shin'onsen","Heguri","Sango","Ikaruga","Ando","Kawanishi","Miyake","Tawaramoto","Takatori","Kanmaki","Oji","Koryo","Kawai","Yoshino","Oyodo","Shimoichi","Kushimoto","Kimino","Katsuragi","Kudoyama","Koya","Yuasa","Hirogawa","Aridagawa","Mihama","Hidaka","Yura","Inami","Minabe","Hidakagawa","Shirahama","Kamitonda","Susami","Nachikatsuura","Taiji","Kozagawa","Iwami","Wakasa","Chizu","Yazu","Misasa","Yurihama","Kotoura","Hokuei","Daisen","Nanbu","Hoki","Nichinan","Hino","Kofu","Okuizumo","Iinan","Kawamoto","Misato","Onan","Tsuwano","Yoshika","Ama","Nishinoshima","Okinoshima","Wake","Hayashima","Satosho","Yakage","Kagamino","Shoo","Nagi","Kumenan","Misaki","Kibichuo","Fuchu","Kaita","Kumano","Saka","Kitahiroshima","Akiota","Osakikamijima","Sera","Jinsekikogen","Suooshima","Waki","Kaminoseki","Tabuse","Hirao","Abu","Katsuura","Kamikatsu","Ishii","Kamiyama","Naka","Mugi","Minami","Kaiyo","Matsushige","Kitajima","Aizumi","Itano","Kamiita","Tsurugi","Higashimiyoshi","Tonosho","Shodoshima","Miki","Naoshima","Utazu","Ayagawa","Kotohira","Tadotsu","Manno","Kamijima","Kumakogen","Masaki","Tobe","Uchiko","Ikata","Kihoku","Matsuno","Ainan","Toyo","Nahari","Tano","Yasuda","Motoyama","Otoyo","Tosa","Ino","Niyodogawa","Nakatosa","Sakawa","Ochi","Yusuhara","Tsuno","Shimanto","Otsuki","Kuroshio","Nakagawa","Umi","Sasaguri","Shime","Sue","Shingu","Hisayama","Kasuya","Ashiya","Mizumaki","Okagaki","Onga","Kotake","Kurate","Keisen","Chikuzen","Tachiarai","Oki","Hirokawa","Kawara","Soeda","Itoda","Kawasaki","Oto","Fukuchi","Kanda","Miyako","Yoshitomi","Koge","Chikujo","Yoshinogari","Kiyama","Kamimine","Miyaki","Genkai","Arita","Omachi","Kohoku","Shiroishi","Tara","Nagayo","Togitsu","Higashisonogi","Kawatana","Hasami","Ojika","Saza","Shinkamigoto","Misato","Gyokuto","Nankan","Nagasu","Nagomi","Ozu","Kikuyo","Minamioguni","Oguni","Takamori","Mifune","Kashima","Mashiki","Kosa","Yamato","Hikawa","Ashikita","Tsunagi","Nishiki","Taragi","Yunomae","Asagiri","Reihoku","Hiji","Kusu","Kokonoe","Mimata","Takaharu","Kunitomi","Aya","Takanabe","Shintomi","Kijo","Kawaminami","Tsuno","Kadogawa","Misato","Takachiho","Hinokage","Gokase","Satsuma","Nagashima","Yusui","Osaki","Higashikushira","Kinko","Minamiosumi","Kimotsuki","Nakatane","Minamitane","Yakushima","Setouchi","Tatsugo","Kikai","Tokunoshima","Amagi","Isen","Wadomari","China","Yoron","Motobu","Kin","Kadena","Chatan","Nishihara","Yonabaru","Haebaru","Kumejima","Yaese","Taketomi","Yonaguni"] + ["Achern", "Aichhalden", "Aitern", "Albbruck", "Alpirsbach", "Altensteig", "Althengstett", "Appenweier", "Auggen", "Wildbad", "Badenen", "Badenweiler", "Baiersbronn", "Ballrechten", "Bellingen", "Berghaupten", "Bernau", "Biberach", "Biederbach", "Binzen", "Birkendorf", "Birkenfeld", "Bischweier", "Blumberg", "Bollen", "Bollschweil", "Bonndorf", "Bosingen", "Braunlingen", "Breisach", "Breisgau", "Breitnau", "Brigachtal", "Buchenbach", "Buggingen", "Buhl", "Buhlertal", "Calw", "Dachsberg", "Dobel", "Donaueschingen", "Dornhan", "Dornstetten", "Dottingen", "Dunningen", "Durbach", "Durrheim", "Ebhausen", "Ebringen", "Efringen", "Egenhausen", "Ehrenkirchen", "Ehrsberg", "Eimeldingen", "Eisenbach", "Elzach", "Elztal", "Emmendingen", "Endingen", "Engelsbrand", "Enz", "Enzklosterle", "Eschbronn", "Ettenheim", "Ettlingen", "Feldberg", "Fischerbach", "Fischingen", "Fluorn", "Forbach", "Freiamt", "Freiburg", "Freudenstadt", "Friedenweiler", "Friesenheim", "Frohnd", "Furtwangen", "Gaggenau", "Geisingen", "Gengenbach", "Gernsbach", "Glatt", "Glatten", "Glottertal", "Gorwihl", "Gottenheim", "Grafenhausen", "Grenzach", "Griesbach", "Gutach", "Gutenbach", "Hag", "Haiterbach", "Hardt", "Harmersbach", "Hasel", "Haslach", "Hausach", "Hausen", "Hausern", "Heitersheim", "Herbolzheim", "Herrenalb", "Herrischried", "Hinterzarten", "Hochenschwand", "Hofen", "Hofstetten", "Hohberg", "Horb", "Horben", "Hornberg", "Hufingen", "Ibach", "Ihringen", "Inzlingen", "Kandern", "Kappel", "Kappelrodeck", "Karlsbad", "Karlsruhe", "Kehl", "Keltern", "Kippenheim", "Kirchzarten", "Konigsfeld", "Krozingen", "Kuppenheim", "Kussaberg", "Lahr", "Lauchringen", "Lauf", "Laufenburg", "Lautenbach", "Lauterbach", "Lenzkirch", "Liebenzell", "Loffenau", "Loffingen", "Lorrach", "Lossburg", "Mahlberg", "Malsburg", "Malsch", "March", "Marxzell", "Marzell", "Maulburg", "Monchweiler", "Muhlenbach", "Mullheim", "Munstertal", "Murg", "Nagold", "Neubulach", "Neuenburg", "Neuhausen", "Neuried", "Neuweiler", "Niedereschach", "Nordrach", "Oberharmersbach", "Oberkirch", "Oberndorf", "Oberbach", "Oberried", "Oberwolfach", "Offenburg", "Ohlsbach", "Oppenau", "Ortenberg", "otigheim", "Ottenhofen", "Ottersweier", "Peterstal", "Pfaffenweiler", "Pfalzgrafenweiler", "Pforzheim", "Rastatt", "Renchen", "Rheinau", "Rheinfelden", "Rheinmunster", "Rickenbach", "Rippoldsau", "Rohrdorf", "Rottweil", "Rummingen", "Rust", "Sackingen", "Sasbach", "Sasbachwalden", "Schallbach", "Schallstadt", "Schapbach", "Schenkenzell", "Schiltach", "Schliengen", "Schluchsee", "Schomberg", "Schonach", "Schonau", "Schonenberg", "Schonwald", "Schopfheim", "Schopfloch", "Schramberg", "Schuttertal", "Schwenningen", "Schworstadt", "Seebach", "Seelbach", "Seewald", "Sexau", "Simmersfeld", "Simonswald", "Sinzheim", "Solden", "Staufen", "Stegen", "Steinach", "Steinen", "Steinmauern", "Straubenhardt", "Stuhlingen", "Sulz", "Sulzburg", "Teinach", "Tiefenbronn", "Tiengen", "Titisee", "Todtmoos", "Todtnau", "Todtnauberg", "Triberg", "Tunau", "Tuningen", "uhlingen", "Unterkirnach", "Reichenbach", "Utzenfeld", "Villingen", "Villingendorf", "Vogtsburg", "Vohrenbach", "Waldachtal", "Waldbronn", "Waldkirch", "Waldshut", "Wehr", "Weil", "Weilheim", "Weisenbach", "Wembach", "Wieden", "Wiesental", "Wildberg", "Winzeln", "Wittlingen", "Wittnau", "Wolfach", "Wutach", "Wutoschingen", "Wyhlen", "Zavelstein"], + ["Abingdon", "Albrighton", "Alcester", "Almondbury", "Altrincham", "Amersham", "Andover", "Appleby", "Ashboume", "Atherstone", "Aveton", "Axbridge", "Aylesbury", "Baldock", "Bamburgh", "Barton", "Basingstoke", "Berden", "Bere", "Berkeley", "Berwick", "Betley", "Bideford", "Bingley", "Birmingham", "Blandford", "Blechingley", "Bodmin", "Bolton", "Bootham", "Boroughbridge", "Boscastle", "Bossinney", "Bramber", "Brampton", "Brasted", "Bretford", "Bridgetown", "Bridlington", "Bromyard", "Bruton", "Buckingham", "Bungay", "Burton", "Calne", "Cambridge", "Canterbury", "Carlisle", "Castleton", "Caus", "Charmouth", "Chawleigh", "Chichester", "Chillington", "Chinnor", "Chipping", "Chisbury", "Cleobury", "Clifford", "Clifton", "Clitheroe", "Cockermouth", "Coleshill", "Combe", "Congleton", "Crafthole", "Crediton", "Cuddenbeck", "Dalton", "Darlington", "Dodbrooke", "Drax", "Dudley", "Dunstable", "Dunster", "Dunwich", "Durham", "Dymock", "Exeter", "Exning", "Faringdon", "Felton", "Fenny", "Finedon", "Flookburgh", "Fowey", "Frampton", "Gateshead", "Gatton", "Godmanchester", "Grampound", "Grantham", "Guildford", "Halesowen", "Halton", "Harbottle", "Harlow", "Hatfield", "Hatherleigh", "Haydon", "Helston", "Henley", "Hertford", "Heytesbury", "Hinckley", "Hitchin", "Holme", "Hornby", "Horsham", "Kendal", "Kenilworth", "Kilkhampton", "Kineton", "Kington", "Kinver", "Kirby", "Knaresborough", "Knutsford", "Launceston", "Leighton", "Lewes", "Linton", "Louth", "Luton", "Lyme", "Lympstone", "Macclesfield", "Madeley", "Malborough", "Maldon", "Manchester", "Manningtree", "Marazion", "Marlborough", "Marshfield", "Mere", "Merryfield", "Middlewich", "Midhurst", "Milborne", "Mitford", "Modbury", "Montacute", "Mousehole", "Newbiggin", "Newborough", "Newbury", "Newenden", "Newent", "Norham", "Northleach", "Noss", "Oakham", "Olney", "Orford", "Ormskirk", "Oswestry", "Padstow", "Paignton", "Penkneth", "Penrith", "Penzance", "Pershore", "Petersfield", "Pevensey", "Pickering", "Pilton", "Pontefract", "Portsmouth", "Preston", "Quatford", "Reading", "Redcliff", "Retford", "Rockingham", "Romney", "Rothbury", "Rothwell", "Salisbury", "Saltash", "Seaford", "Seasalter", "Sherston", "Shifnal", "Shoreham", "Sidmouth", "Skipsea", "Skipton", "Solihull", "Somerton", "Southam", "Southwark", "Standon", "Stansted", "Stapleton", "Stottesdon", "Sudbury", "Swavesey", "Tamerton", "Tarporley", "Tetbury", "Thatcham", "Thaxted", "Thetford", "Thornbury", "Tintagel", "Tiverton", "Torksey", "Totnes", "Towcester", "Tregoney", "Trematon", "Tutbury", "Uxbridge", "Wallingford", "Wareham", "Warenmouth", "Wargrave", "Warton", "Watchet", "Watford", "Wendover", "Westbury", "Westcheap", "Weymouth", "Whitford", "Wickwar", "Wigan", "Wigmore", "Winchelsea", "Winkleigh", "Wiscombe", "Witham", "Witheridge", "Wiveliscombe", "Woodbury", "Yeovil"], + ["Adon", "Aillant", "Amilly", "Andonville", "Ardon", "Artenay", "Ascheres", "Ascoux", "Attray", "Aubin", "Audeville", "Aulnay", "Autruy", "Auvilliers", "Auxy", "Aveyron", "Baccon", "Bardon", "Barville", "Batilly", "Baule", "Bazoches", "Beauchamps", "Beaugency", "Beaulieu", "Beaune", "Bellegarde", "Boesses", "Boigny", "Boiscommun", "Boismorand", "Boisseaux", "Bondaroy", "Bonnee", "Bonny", "Bordes", "Bou", "Bougy", "Bouilly", "Boulay", "Bouzonville", "Bouzy", "Boynes", "Bray", "Breteau", "Briare", "Briarres", "Bricy", "Bromeilles", "Bucy", "Cepoy", "Cercottes", "Cerdon", "Cernoy", "Cesarville", "Chailly", "Chaingy", "Chalette", "Chambon", "Champoulet", "Chanteau", "Chantecoq", "Chapell", "Charme", "Charmont", "Charsonville", "Chateau", "Chateauneuf", "Chatel", "Chatenoy", "Chatillon", "Chaussy", "Checy", "Chevannes", "Chevillon", "Chevilly", "Chevry", "Chilleurs", "Choux", "Chuelles", "Clery", "Coinces", "Coligny", "Combleux", "Combreux", "Conflans", "Corbeilles", "Corquilleroy", "Cortrat", "Coudroy", "Coullons", "Coulmiers", "Courcelles", "Courcy", "Courtemaux", "Courtempierre", "Courtenay", "Cravant", "Crottes", "Dadonville", "Dammarie", "Dampierre", "Darvoy", "Desmonts", "Dimancheville", "Donnery", "Dordives", "Dossainville", "Douchy", "Dry", "Echilleuses", "Egry", "Engenville", "Epieds", "Erceville", "Ervauville", "Escrennes", "Escrignelles", "Estouy", "Faverelles", "Fay", "Feins", "Ferolles", "Ferrieres", "Fleury", "Fontenay", "Foret", "Foucherolles", "Freville", "Gatinais", "Gaubertin", "Gemigny", "Germigny", "Gidy", "Gien", "Girolles", "Givraines", "Gondreville", "Grangermont", "Greneville", "Griselles", "Guigneville", "Guilly", "Gyleslonains", "Huetre", "Huisseau", "Ingrannes", "Ingre", "Intville", "Isdes", "Jargeau", "Jouy", "Juranville", "Bussiere", "Laas", "Ladon", "Lailly", "Langesse", "Leouville", "Ligny", "Lombreuil", "Lorcy", "Lorris", "Loury", "Louzouer", "Malesherbois", "Marcilly", "Mardie", "Mareau", "Marigny", "Marsainvilliers", "Melleroy", "Menestreau", "Merinville", "Messas", "Meung", "Mezieres", "Migneres", "Mignerette", "Mirabeau", "Montargis", "Montbarrois", "Montbouy", "Montcresson", "Montereau", "Montigny", "Montliard", "Mormant", "Morville", "Moulinet", "Moulon", "Nancray", "Nargis", "Nesploy", "Neuville", "Neuvy", "Nevoy", "Nibelle", "Nogent", "Noyers", "Ocre", "Oison", "Olivet", "Ondreville", "Onzerain", "Orleans", "Ormes", "Orville", "Oussoy", "Outarville", "Ouzouer", "Pannecieres", "Pannes", "Patay", "Paucourt", "Pers", "Pierrefitte", "Pithiverais", "Pithiviers", "Poilly", "Potier", "Prefontaines", "Presnoy", "Pressigny", "Puiseaux", "Quiers", "Ramoulu", "Rebrechien", "Rouvray", "Rozieres", "Rozoy", "Ruan", "Sandillon", "Santeau", "Saran", "Sceaux", "Seichebrieres", "Semoy", "Sennely", "Sermaises", "Sigloy", "Solterre", "Sougy", "Sully", "Sury", "Tavers", "Thignonville", "Thimory", "Thorailles", "Thou", "Tigy", "Tivernon", "Tournoisis", "Trainou", "Treilles", "Trigueres", "Trinay", "Vannes", "Varennes", "Vennecy", "Vieilles", "Vienne", "Viglain", "Vignes", "Villamblain", "Villemandeur", "Villemoutiers", "Villemurlin", "Villeneuve", "Villereau", "Villevoques", "Villorceau", "Vimory", "Vitry", "Vrigny", "Ivre"], + ["Accumoli", "Acquafondata", "Acquapendente", "Acuto", "Affile", "Agosta", "Alatri", "Albano", "Allumiere", "Alvito", "Amaseno", "Amatrice", "Anagni", "Anguillara", "Anticoli", "Antrodoco", "Anzio", "Aprilia", "Aquino", "Arce", "Arcinazzo", "Ardea", "Ariccia", "Arlena", "Arnara", "Arpino", "Arsoli", "Artena", "Ascrea", "Atina", "Ausonia", "Bagnoregio", "Barbarano", "Bassano", "Bassiano", "Bellegra", "Belmonte", "Blera", "Bolsena", "Bomarzo", "Borbona", "Borgo", "Borgorose", "Boville", "Bracciano", "Broccostella", "Calcata", "Camerata", "Campagnano", "Campodimele", "Campoli", "Canale", "Canepina", "Canino", "Cantalice", "Cantalupo", "Canterano", "Capena", "Capodimonte", "Capranica", "Caprarola", "Carbognano", "Casalattico", "Casalvieri", "Casape", "Casaprota", "Casperia", "Cassino", "Castelforte", "Castelliri", "Castello", "Castelnuovo", "Castiglione", "Castro", "Castrocielo", "Cave", "Ceccano", "Celleno", "Cellere", "Ceprano", "Cerreto", "Cervara", "Cervaro", "Cerveteri", "Ciampino", "Ciciliano", "Cineto", "Cisterna", "Cittaducale", "Cittareale", "Civita", "Civitavecchia", "Civitella", "Colfelice", "Collalto", "Colle", "Colleferro", "Collegiove", "Collepardo", "Collevecchio", "Colli", "Colonna", "Concerviano", "Configni", "Contigliano", "Corchiano", "Coreno", "Cori", "Cottanello", "Esperia", "Fabrica", "Faleria", "Falvaterra", "Fara", "Farnese", "Ferentino", "Fiamignano", "Fiano", "Filacciano", "Filettino", "Fiuggi", "Fiumicino", "Fondi", "Fontana", "Fonte", "Fontechiari", "Forano", "Formello", "Formia", "Frascati", "Frasso", "Frosinone", "Fumone", "Gaeta", "Gallese", "Gallicano", "Gallinaro", "Gavignano", "Genazzano", "Genzano", "Gerano", "Giuliano", "Gorga", "Gradoli", "Graffignano", "Greccio", "Grottaferrata", "Grotte", "Guarcino", "Guidonia", "Ischia", "Isola", "Itri", "Jenne", "Labico", "Labro", "Ladispoli", "Lanuvio", "Lariano", "Latera", "Lenola", "Leonessa", "Licenza", "Longone", "Lubriano", "Maenza", "Magliano", "Mandela", "Manziana", "Marano", "Marcellina", "Marcetelli", "Marino", "Marta", "Mazzano", "Mentana", "Micigliano", "Minturno", "Mompeo", "Montalto", "Montasola", "Monte", "Montebuono", "Montefiascone", "Monteflavio", "Montelanico", "Monteleone", "Montelibretti", "Montenero", "Monterosi", "Monterotondo", "Montopoli", "Montorio", "Moricone", "Morlupo", "Morolo", "Morro", "Nazzano", "Nemi", "Nepi", "Nerola", "Nespolo", "Nettuno", "Norma", "Olevano", "Onano", "Oriolo", "Orte", "Orvinio", "Paganico", "Palestrina", "Paliano", "Palombara", "Pastena", "Patrica", "Percile", "Pescorocchiano", "Pescosolido", "Petrella", "Piansano", "Picinisco", "Pico", "Piedimonte", "Piglio", "Pignataro", "Pisoniano", "Pofi", "Poggio", "Poli", "Pomezia", "Pontecorvo", "Pontinia", "Ponza", "Ponzano", "Posta", "Pozzaglia", "Priverno", "Proceno", "Prossedi", "Riano", "Rieti", "Rignano", "Riofreddo", "Ripi", "Rivodutri", "Rocca", "Roccagiovine", "Roccagorga", "Roccantica", "Roccasecca", "Roiate", "Ronciglione", "Roviano", "Sabaudia", "Sacrofano", "Salisano", "Sambuci", "Santa", "Santi", "Santopadre", "Saracinesco", "Scandriglia", "Segni", "Selci", "Sermoneta", "Serrone", "Settefrati", "Sezze", "Sgurgola", "Sonnino", "Sora", "Soriano", "Sperlonga", "Spigno", "Stimigliano", "Strangolagalli", "Subiaco", "Supino", "Sutri", "Tarano", "Tarquinia", "Terelle", "Terracina", "Tessennano", "Tivoli", "Toffia", "Tolfa", "Torre", "Torri", "Torrice", "Torricella", "Torrita", "Trevi", "Trevignano", "Trivigliano", "Turania", "Tuscania", "Vacone", "Valentano", "Vallecorsa", "Vallemaio", "Vallepietra", "Vallerano", "Vallerotonda", "Vallinfreda", "Valmontone", "Varco", "Vasanello", "Vejano", "Velletri", "Ventotene", "Veroli", "Vetralla", "Vicalvi", "Vico", "Vicovaro", "Vignanello", "Viterbo", "Viticuso", "Vitorchiano", "Vivaro", "Zagarolo"], + ["Abanades", "Ablanque", "Adobes", "Ajofrin", "Alameda", "Alaminos", "Alarilla", "Albalate", "Albares", "Albarreal", "Albendiego", "Alcabon", "Alcanizo", "Alcaudete", "Alcocer", "Alcolea", "Alcoroches", "Aldea", "Aldeanueva", "Algar", "Algora", "Alhondiga", "Alique", "Almadrones", "Almendral", "Almoguera", "Almonacid", "Almorox", "Alocen", "Alovera", "Alustante", "Angon", "Anguita", "Anover", "Anquela", "Arbancon", "Arbeteta", "Arcicollar", "Argecilla", "Arges", "Armallones", "Armuna", "Arroyo", "Atanzon", "Atienza", "Aunon", "Azuqueca", "Azutan", "Baides", "Banos", "Banuelos", "Barcience", "Bargas", "Barriopedro", "Belvis", "Berninches", "Borox", "Brihuega", "Budia", "Buenaventura", "Bujalaro", "Burguillos", "Burujon", "Bustares", "Cabanas", "Cabanillas", "Calera", "Caleruela", "Calzada", "Camarena", "Campillo", "Camunas", "Canizar", "Canredondo", "Cantalojas", "Cardiel", "Carmena", "Carranque", "Carriches", "Casa", "Casarrubios", "Casas", "Casasbuenas", "Caspuenas", "Castejon", "Castellar", "Castilforte", "Castillo", "Castilnuevo", "Cazalegas", "Cebolla", "Cedillo", "Cendejas", "Centenera", "Cervera", "Checa", "Chequilla", "Chillaron", "Chiloeches", "Chozas", "Chueca", "Cifuentes", "Cincovillas", "Ciruelas", "Ciruelos", "Cobeja", "Cobeta", "Cobisa", "Cogollor", "Cogolludo", "Condemios", "Congostrina", "Consuegra", "Copernal", "Corduente", "Corral", "Cuerva", "Domingo", "Dosbarrios", "Driebes", "Duron", "El", "Embid", "Erustes", "Escalona", "Escalonilla", "Escamilla", "Escariche", "Escopete", "Espinosa", "Espinoso", "Esplegares", "Esquivias", "Estables", "Estriegana", "Fontanar", "Fuembellida", "Fuensalida", "Fuentelsaz", "Gajanejos", "Galve", "Galvez", "Garciotum", "Gascuena", "Gerindote", "Guadamur", "Henche", "Heras", "Herreria", "Herreruela", "Hijes", "Hinojosa", "Hita", "Hombrados", "Hontanar", "Hontoba", "Horche", "Hormigos", "Huecas", "Huermeces", "Huerta", "Hueva", "Humanes", "Illan", "Illana", "Illescas", "Iniestola", "Irueste", "Jadraque", "Jirueque", "Lagartera", "Las", "Layos", "Ledanca", "Lillo", "Lominchar", "Loranca", "Los", "Lucillos", "Lupiana", "Luzaga", "Luzon", "Madridejos", "Magan", "Majaelrayo", "Malaga", "Malaguilla", "Malpica", "Mandayona", "Mantiel", "Manzaneque", "Maqueda", "Maranchon", "Marchamalo", "Marjaliza", "Marrupe", "Mascaraque", "Masegoso", "Matarrubia", "Matillas", "Mazarete", "Mazuecos", "Medranda", "Megina", "Mejorada", "Mentrida", "Mesegar", "Miedes", "Miguel", "Millana", "Milmarcos", "Mirabueno", "Miralrio", "Mocejon", "Mochales", "Mohedas", "Molina", "Monasterio", "Mondejar", "Montarron", "Mora", "Moratilla", "Morenilla", "Muduex", "Nambroca", "Navalcan", "Negredo", "Noblejas", "Noez", "Nombela", "Noves", "Numancia", "Nuno", "Ocana", "Ocentejo", "Olias", "Olmeda", "Ontigola", "Orea", "Orgaz", "Oropesa", "Otero", "Palmaces", "Palomeque", "Pantoja", "Pardos", "Paredes", "Pareja", "Parrillas", "Pastrana", "Pelahustan", "Penalen", "Penalver", "Pepino", "Peralejos", "Peralveche", "Pinilla", "Pioz", "Piqueras", "Polan", "Portillo", "Poveda", "Pozo", "Pradena", "Prados", "Puebla", "Puerto", "Pulgar", "Quer", "Quero", "Quintanar", "Quismondo", "Rebollosa", "Recas", "Renera", "Retamoso", "Retiendas", "Riba", "Rielves", "Rillo", "Riofrio", "Robledillo", "Robledo", "Romanillos", "Romanones", "Rueda", "Sacecorbo", "Sacedon", "Saelices", "Salmeron", "San", "Santa", "Santiuste", "Santo", "Sartajada", "Sauca", "Sayaton", "Segurilla", "Selas", "Semillas", "Sesena", "Setiles", "Sevilleja", "Sienes", "Siguenza", "Solanillos", "Somolinos", "Sonseca", "Sotillo", "Sotodosos", "Talavera", "Tamajon", "Taragudo", "Taravilla", "Tartanedo", "Tembleque", "Tendilla", "Terzaga", "Tierzo", "Tordellego", "Tordelrabano", "Tordesilos", "Torija", "Torralba", "Torre", "Torrecilla", "Torrecuadrada", "Torrejon", "Torremocha", "Torrico", "Torrijos", "Torrubia", "Tortola", "Tortuera", "Tortuero", "Totanes", "Traid", "Trijueque", "Trillo", "Turleque", "Uceda", "Ugena", "Ujados", "Urda", "Utande", "Valdarachas", "Valdesotos", "Valhermoso", "Valtablado", "Valverde", "Velada", "Viana", "Vinuelas", "Yebes", "Yebra", "Yelamos", "Yeles", "Yepes", "Yuncler", "Yunclillos", "Yuncos", "Yunquera", "Zaorejas", "Zarzuela", "Zorita"], + ["Belgorod", "Beloberezhye", "Belyi", "Belz", "Berestiy", "Berezhets", "Berezovets", "Berezutsk", "Bobruisk", "Bolonets", "Borisov", "Borovsk", "Bozhesk", "Bratslav", "Bryansk", "Brynsk", "Buryn", "Byhov", "Chechersk", "Chemesov", "Cheremosh", "Cherlen", "Chern", "Chernigov", "Chernitsa", "Chernobyl", "Chernogorod", "Chertoryesk", "Chetvertnia", "Demyansk", "Derevesk", "Devyagoresk", "Dichin", "Dmitrov", "Dorogobuch", "Dorogobuzh", "Drestvin", "Drokov", "Drutsk", "Dubechin", "Dubichi", "Dubki", "Dubkov", "Dveren", "Galich", "Glebovo", "Glinsk", "Goloty", "Gomiy", "Gorodets", "Gorodische", "Gorodno", "Gorohovets", "Goroshin", "Gorval", "Goryshon", "Holm", "Horobor", "Hoten", "Hotin", "Hotmyzhsk", "Ilovech", "Ivan", "Izborsk", "Izheslavl", "Kamenets", "Kanev", "Karachev", "Karna", "Kavarna", "Klechesk", "Klyapech", "Kolomyya", "Kolyvan", "Kopyl", "Korec", "Kornik", "Korochunov", "Korshev", "Korsun", "Koshkin", "Kotelno", "Kovyla", "Kozelsk", "Kozelsk", "Kremenets", "Krichev", "Krylatsk", "Ksniatin", "Kulatsk", "Kursk", "Kursk", "Lebedev", "Lida", "Logosko", "Lomihvost", "Loshesk", "Loshichi", "Lubech", "Lubno", "Lubutsk", "Lutsk", "Luchin", "Luki", "Lukoml", "Luzha", "Lvov", "Mtsensk", "Mdin", "Medniki", "Melecha", "Merech", "Meretsk", "Mescherskoe", "Meshkovsk", "Metlitsk", "Mezetsk", "Mglin", "Mihailov", "Mikitin", "Mikulino", "Miloslavichi", "Mogilev", "Mologa", "Moreva", "Mosalsk", "Moschiny", "Mozyr", "Mstislav", "Mstislavets", "Muravin", "Nemech", "Nemiza", "Nerinsk", "Nichan", "Novgorod", "Novogorodok", "Obolichi", "Obolensk", "Obolensk", "Oleshsk", "Olgov", "Omelnik", "Opoka", "Opoki", "Oreshek", "Orlets", "Osechen", "Oster", "Ostrog", "Ostrov", "Perelai", "Peremil", "Peremyshl", "Pererov", "Peresechen", "Perevitsk", "Pereyaslav", "Pinsk", "Ples", "Polotsk", "Pronsk", "Proposhesk", "Punia", "Putivl", "Rechitsa", "Rodno", "Rogachev", "Romanov", "Romny", "Roslavl", "Rostislavl", "Rostovets", "Rsha", "Ruza", "Rybchesk", "Rylsk", "Rzhavesk", "Rzhev", "Rzhischev", "Sambor", "Serensk", "Serensk", "Serpeysk", "Shilov", "Shuya", "Sinech", "Sizhka", "Skala", "Slovensk", "Slutsk", "Smedin", "Sneporod", "Snitin", "Snovsk", "Sochevo", "Sokolec", "Starica", "Starodub", "Stepan", "Sterzh", "Streshin", "Sutesk", "Svinetsk", "Svisloch", "Terebovl", "Ternov", "Teshilov", "Teterin", "Tiversk", "Torchevsk", "Toropets", "Torzhok", "Tripolye", "Trubchevsk", "Tur", "Turov", "Usvyaty", "Uteshkov", "Vasilkov", "Velil", "Velye", "Venev", "Venicha", "Verderev", "Vereya", "Veveresk", "Viazma", "Vidbesk", "Vidychev", "Voino", "Volodimer", "Volok", "Volyn", "Vorobesk", "Voronich", "Voronok", "Vorotynsk", "Vrev", "Vruchiy", "Vselug", "Vyatichsk", "Vyatka", "Vyshegorod", "Vyshgorod", "Vysokoe", "Yagniatin", "Yaropolch", "Yasenets", "Yuryev", "Yuryevets", "Zaraysk", "Zhitomel", "Zholvazh", "Zizhech", "Zubkov", "Zudechev", "Zvenigorod"], + ["Akureyri", "Aldra", "Alftanes", "Andenes", "Austbo", "Auvog", "Bakkafjordur", "Ballangen", "Bardal", "Beisfjord", "Bifrost", "Bildudalur", "Bjerka", "Bjerkvik", "Bjorkosen", "Bliksvaer", "Blokken", "Blonduos", "Bolga", "Bolungarvik", "Borg", "Borgarnes", "Bosmoen", "Bostad", "Bostrand", "Botsvika", "Brautarholt", "Breiddalsvik", "Bringsli", "Brunahlid", "Budardalur", "Byggdakjarni", "Dalvik", "Djupivogur", "Donnes", "Drageid", "Drangsnes", "Egilsstadir", "Eiteroga", "Elvenes", "Engavogen", "Ertenvog", "Eskifjordur", "Evenes", "Eyrarbakki", "Fagernes", "Fallmoen", "Fellabaer", "Fenes", "Finnoya", "Fjaer", "Fjelldal", "Flakstad", "Flateyri", "Flostrand", "Fludir", "Gardabær", "Gardur", "Gimstad", "Givaer", "Gjeroy", "Gladstad", "Godoya", "Godoynes", "Granmoen", "Gravdal", "Grenivik", "Grimsey", "Grindavik", "Grytting", "Hafnir", "Halsa", "Hauganes", "Haugland", "Hauknes", "Hella", "Helland", "Hellissandur", "Hestad", "Higrav", "Hnifsdalur", "Hofn", "Hofsos", "Holand", "Holar", "Holen", "Holkestad", "Holmavik", "Hopen", "Hovden", "Hrafnagil", "Hrisey", "Husavik", "Husvik", "Hvammstangi", "Hvanneyri", "Hveragerdi", "Hvolsvollur", "Igeroy", "Indre", "Inndyr", "Innhavet", "Innes", "Isafjordur", "Jarklaustur", "Jarnsreykir", "Junkerdal", "Kaldvog", "Kanstad", "Karlsoy", "Kavosen", "Keflavik", "Kjelde", "Kjerstad", "Klakk", "Kopasker", "Kopavogur", "Korgen", "Kristnes", "Krutoga", "Krystad", "Kvina", "Lande", "Laugar", "Laugaras", "Laugarbakki", "Laugarvatn", "Laupstad", "Leines", "Leira", "Leiren", "Leland", "Lenvika", "Loding", "Lodingen", "Lonsbakki", "Lopsmarka", "Lovund", "Luroy", "Maela", "Melahverfi", "Meloy", "Mevik", "Misvaer", "Mornes", "Mosfellsbær", "Moskenes", "Myken", "Naurstad", "Nesberg", "Nesjahverfi", "Nesset", "Nevernes", "Obygda", "Ofoten", "Ogskardet", "Okervika", "Oknes", "Olafsfjordur", "Oldervika", "Olstad", "Onstad", "Oppeid", "Oresvika", "Orsnes", "Orsvog", "Osmyra", "Overdal", "Prestoya", "Raudalaekur", "Raufarhofn", "Reipo", "Reykholar", "Reykholt", "Reykjahlid", "Rif", "Rinoya", "Rodoy", "Rognan", "Rosvika", "Rovika", "Salhus", "Sanden", "Sandgerdi", "Sandoker", "Sandset", "Sandvika", "Saudarkrokur", "Selfoss", "Selsoya", "Sennesvik", "Setso", "Siglufjordur", "Silvalen", "Skagastrond", "Skjerstad", "Skonland", "Skorvogen", "Skrova", "Sleneset", "Snubba", "Softing", "Solheim", "Solheimar", "Sorarnoy", "Sorfugloy", "Sorland", "Sormela", "Sorvaer", "Sovika", "Stamsund", "Stamsvika", "Stave", "Stokka", "Stokkseyri", "Storjord", "Storo", "Storvika", "Strand", "Straumen", "Strendene", "Sudavik", "Sudureyri", "Sundoya", "Sydalen", "Thingeyri", "Thorlakshofn", "Thorshofn", "Tjarnabyggd", "Tjotta", "Tosbotn", "Traelnes", "Trofors", "Trones", "Tverro", "Ulvsvog", "Unnstad", "Utskor", "Valla", "Vandved", "Varmahlid", "Vassos", "Vevelstad", "Vidrek", "Vik", "Vikholmen", "Vogar", "Vogehamn", "Vopnafjordur"], + ["Abdera", "Abila", "Abydos", "Acanthus", "Acharnae", "Actium", "Adramyttium", "Aegae", "Aegina", "Aegium", "Aenus", "Agrinion", "Aigosthena", "Akragas", "Akrai", "Akrillai", "Akroinon", "Akrotiri", "Alalia", "Alexandreia", "Alexandretta", "Alexandria", "Alinda", "Amarynthos", "Amaseia", "Ambracia", "Amida", "Amisos", "Amnisos", "Amphicaea", "Amphigeneia", "Amphipolis", "Amphissa", "Ankon", "Antigona", "Antipatrea", "Antioch", "Antioch", "Antiochia", "Andros", "Apamea", "Aphidnae", "Apollonia", "Argos", "Arsuf", "Artanes", "Artemita", "Argyroupoli", "Asine", "Asklepios", "Aspendos", "Assus", "Astacus", "Athenai", "Athmonia", "Aytos", "Ancient", "Baris", "Bhrytos", "Borysthenes", "Berge", "Boura", "Bouthroton", "Brauron", "Byblos", "Byllis", "Byzantium", "Bythinion", "Callipolis", "Cebrene", "Chalcedon", "Calydon", "Carystus", "Chamaizi", "Chalcis", "Chersonesos", "Chios", "Chytri", "Clazomenae", "Cleonae", "Cnidus", "Colosse", "Corcyra", "Croton", "Cyme", "Cyrene", "Cythera", "Decelea", "Delos", "Delphi", "Demetrias", "Dicaearchia", "Dimale", "Didyma", "Dion", "Dioscurias", "Dodona", "Dorylaion", "Dyme", "Edessa", "Elateia", "Eleusis", "Eleutherna", "Emporion", "Ephesus", "Ephyra", "Epidamnos", "Epidauros", "Eresos", "Eretria", "Erythrae", "Eubea", "Gangra", "Gaza", "Gela", "Golgi", "Gonnos", "Gorgippia", "Gournia", "Gortyn", "Gythium", "Hagios", "Hagia", "Halicarnassus", "Halieis", "Helike", "Heliopolis", "Hellespontos", "Helorus", "Hemeroskopeion", "Heraclea", "Hermione", "Hermonassa", "Hierapetra", "Hierapolis", "Himera", "Histria", "Hubla", "Hyele", "Ialysos", "Iasus", "Idalium", "Imbros", "Iolcus", "Itanos", "Ithaca", "Juktas", "Kallipolis", "Kamares", "Kameiros", "Kannia", "Kamarina", "Kasmenai", "Katane", "Kerkinitida", "Kepoi", "Kimmerikon", "Kios", "Klazomenai", "Knidos", "Knossos", "Korinthos", "Kos", "Kourion", "Kume", "Kydonia", "Kynos", "Kyrenia", "Lamia", "Lampsacus", "Laodicea", "Lapithos", "Larissa", "Lato", "Laus", "Lebena", "Lefkada", "Lekhaion", "Leibethra", "Leontinoi", "Lepreum", "Lessa", "Lilaea", "Lindus", "Lissus", "Epizephyrian", "Madytos", "Magnesia", "Mallia", "Mantineia", "Marathon", "Marmara", "Maroneia", "Masis", "Massalia", "Megalopolis", "Megara", "Mesembria", "Messene", "Metapontum", "Methana", "Methone", "Methumna", "Miletos", "Misenum", "Mochlos", "Monastiraki", "Morgantina", "Mulai", "Mukenai", "Mylasa", "Myndus", "Myonia", "Myra", "Myrmekion", "Mutilene", "Myos", "Nauplíos", "Naucratis", "Naupactus", "Naxos", "Neapoli", "Neapolis", "Nemea", "Nicaea", "Nicopolis", "Nirou", "Nymphaion", "Nysa", "Oenoe", "Oenus", "Odessos", "Olbia", "Olous", "Olympia", "Olynthus", "Opus", "Orchomenus", "Oricos", "Orestias", "Oreus", "Oropus", "Onchesmos", "Pactye", "Pagasae", "Palaikastro", "Pandosia", "Panticapaeum", "Paphos", "Parium", "Paros", "Parthenope", "Patrae", "Pavlopetri", "Pegai", "Pelion", "Peiraieús", "Pella", "Percote", "Pergamum", "Petsofa", "Phaistos", "Phaleron", "Phanagoria", "Pharae", "Pharnacia", "Pharos", "Phaselis", "Philippi", "Pithekussa", "Philippopolis", "Platanos", "Phlius", "Pherae", "Phocaea", "Pinara", "Pisa", "Pitane", "Pitiunt", "Pixous", "Plataea", "Poseidonia", "Potidaea", "Priapus", "Priene", "Prousa", "Pseira", "Psychro", "Pteleum", "Pydna", "Pylos", "Pyrgos", "Rhamnus", "Rhegion", "Rhithymna", "Rhodes", "Rhypes", "Rizinia", "Salamis", "Same", "Samos", "Scyllaeum", "Selinus", "Seleucia", "Semasus", "Sestos", "Scidrus", "Sicyon", "Side", "Sidon", "Siteia", "Sinope", "Siris", "Sklavokampos", "Smyrna", "Soli", "Sozopolis", "Sparta", "Stagirus", "Stratos", "Stymphalos", "Sybaris", "Surakousai", "Taras", "Tanagra", "Tanais", "Tauromenion", "Tegea", "Temnos", "Tenedos", "Tenea", "Teos", "Thapsos", "Thassos", "Thebai", "Theodosia", "Therma", "Thespiae", "Thronion", "Thoricus", "Thurii", "Thyreum", "Thyria", "Tiruns", "Tithoraea", "Tomis", "Tragurion", "Trapeze", "Trapezus", "Tripolis", "Troizen", "Troliton", "Troy", "Tylissos", "Tyras", "Tyros", "Tyritake", "Vasiliki", "Vathypetros", "Zakynthos", "Zakros", "Zankle"], + ["Abila", "Adflexum", "Adnicrem", "Aelia", "Aelius", "Aeminium", "Aequum", "Agrippina", "Agrippinae", "Ala", "Albanianis", "Ambianum", "Andautonia", "Apulum", "Aquae", "Aquaegranni", "Aquensis", "Aquileia", "Aquincum", "Arae", "Argentoratum", "Ariminum", "Ascrivium", "Atrebatum", "Atuatuca", "Augusta", "Aurelia", "Aurelianorum", "Batavar", "Batavorum", "Belum", "Biriciana", "Blestium", "Bonames", "Bonna", "Bononia", "Borbetomagus", "Bovium", "Bracara", "Brigantium", "Burgodunum", "Caesaraugusta", "Caesarea", "Caesaromagus", "Calleva", "Camulodunum", "Cannstatt", "Cantiacorum", "Capitolina", "Castellum", "Castra", "Castrum", "Cibalae", "Clausentum", "Colonia", "Concangis", "Condate", "Confluentes", "Conimbriga", "Corduba", "Coria", "Corieltauvorum", "Corinium", "Coriovallum", "Cornoviorum", "Danum", "Deva", "Divodurum", "Dobunnorum", "Drusi", "Dubris", "Dumnoniorum", "Durnovaria", "Durocobrivis", "Durocornovium", "Duroliponte", "Durovernum", "Durovigutum", "Eboracum", "Edetanorum", "Emerita", "Emona", "Euracini", "Faventia", "Flaviae", "Florentia", "Forum", "Gerulata", "Gerunda", "Glevensium", "Hadriani", "Herculanea", "Isca", "Italica", "Iulia", "Iuliobrigensium", "Iuvavum", "Lactodurum", "Lagentium", "Lauri", "Legionis", "Lemanis", "Lentia", "Lepidi", "Letocetum", "Lindinis", "Lindum", "Londinium", "Lopodunum", "Lousonna", "Lucus", "Lugdunum", "Luguvalium", "Lutetia", "Mancunium", "Marsonia", "Martius", "Massa", "Matilo", "Mattiacorum", "Mediolanum", "Mod", "Mogontiacum", "Moridunum", "Mursa", "Naissus", "Nervia", "Nida", "Nigrum", "Novaesium", "Noviomagus", "Olicana", "Ovilava", "Parisiorum", "Partiscum", "Paterna", "Pistoria", "Placentia", "Pollentia", "Pomaria", "Pons", "Portus", "Praetoria", "Praetorium", "Pullum", "Ragusium", "Ratae", "Raurica", "Regina", "Regium", "Regulbium", "Rigomagus", "Roma", "Romula", "Rutupiae", "Salassorum", "Salernum", "Salona", "Scalabis", "Segovia", "Silurum", "Sirmium", "Siscia", "Sorviodurum", "Sumelocenna", "Tarraco", "Taurinorum", "Theranda", "Traiectum", "Treverorum", "Tungrorum", "Turicum", "Ulpia", "Valentia", "Venetiae", "Venta", "Verulamium", "Vesontio", "Vetera", "Victoriae", "Victrix", "Villa", "Viminacium", "Vindelicorum", "Vindobona", "Vinovia", "Viroconium"], + ["Aanekoski", "Abjapaluoja", "Ahlainen", "Aholanvaara", "Ahtari", "Aijala", "Aimala", "Akaa", "Alajarvi", "Alatornio", "Alavus", "Antsla", "Aspo", "Bennas", "Bjorkoby", "Elva", "Emasalo", "Espoo", "Esse", "Evitskog", "Forssa", "Haapajarvi", "Haapamaki", "Haapavesi", "Haapsalu", "Haavisto", "Hameenlinna", "Hameenmaki", "Hamina", "Hanko", "Harjavalta", "Hattuvaara", "Haukipudas", "Hautajarvi", "Havumaki", "Heinola", "Hetta", "Hinkabole", "Hirmula", "Hossa", "Huittinen", "Husula", "Hyryla", "Hyvinkaa", "Iisalmi", "Ikaalinen", "Ilmola", "Imatra", "Inari", "Iskmo", "Itakoski", "Jamsa", "Jarvenpaa", "Jeppo", "Jioesuu", "Jiogeva", "Joensuu", "Jokela", "Jokikyla", "Jokisuu", "Jormua", "Juankoski", "Jungsund", "Jyvaskyla", "Kaamasmukka", "Kaarina", "Kajaani", "Kalajoki", "Kallaste", "Kankaanpaa", "Kannus", "Kardla", "Karesuvanto", "Karigasniemi", "Karkkila", "Karkku", "Karksinuia", "Karpankyla", "Kaskinen", "Kasnas", "Kauhajoki", "Kauhava", "Kauniainen", "Kauvatsa", "Kehra", "Keila", "Kellokoski", "Kelottijarvi", "Kemi", "Kemijarvi", "Kerava", "Keuruu", "Kiikka", "Kiipu", "Kilinginiomme", "Kiljava", "Kilpisjarvi", "Kitee", "Kiuruvesi", "Kivesjarvi", "Kiviioli", "Kivisuo", "Klaukkala", "Klovskog", "Kohtlajarve", "Kokemaki", "Kokkola", "Kolho", "Koria", "Koskue", "Kotka", "Kouva", "Kouvola", "Kristiina", "Kaupunki", "Kuhmo", "Kunda", "Kuopio", "Kuressaare", "Kurikka", "Kusans", "Kuusamo", "Kylmalankyla", "Lahti", "Laitila", "Lankipohja", "Lansikyla", "Lappeenranta", "Lapua", "Laurila", "Lautiosaari", "Lepsama", "Liedakkala", "Lieksa", "Lihula", "Littoinen", "Lohja", "Loimaa", "Loksa", "Loviisa", "Luohuanylipaa", "Lusi", "Maardu", "Maarianhamina", "Malmi", "Mantta", "Masaby", "Masala", "Matasvaara", "Maula", "Miiluranta", "Mikkeli", "Mioisakula", "Munapirtti", "Mustvee", "Muurahainen", "Naantali", "Nappa", "Narpio", "Nickby", "Niinimaa", "Niinisalo", "Nikkila", "Nilsia", "Nivala", "Nokia", "Nummela", "Nuorgam", "Nurmes", "Nuvvus", "Obbnas", "Oitti", "Ojakkala", "Ollola", "onningeby", "Orimattila", "Orivesi", "Otanmaki", "Otava", "Otepaa", "Oulainen", "Oulu", "Outokumpu", "Paavola", "Paide", "Paimio", "Pakankyla", "Paldiski", "Parainen", "Parkano", "Parkumaki", "Parola", "Perttula", "Pieksamaki", "Pietarsaari", "Pioltsamaa", "Piolva", "Pohjavaara", "Porhola", "Pori", "Porrasa", "Porvoo", "Pudasjarvi", "Purmo", "Pussi", "Pyhajarvi", "Raahe", "Raasepori", "Raisio", "Rajamaki", "Rakvere", "Rapina", "Rapla", "Rauma", "Rautio", "Reposaari", "Riihimaki", "Rovaniemi", "Roykka", "Ruonala", "Ruottala", "Rutalahti", "Saarijarvi", "Salo", "Sastamala", "Saue", "Savonlinna", "Seinajoki", "Sillamae", "Sindi", "Siuntio", "Somero", "Sompujarvi", "Suonenjoki", "Suurejaani", "Syrjantaka", "Tampere", "Tamsalu", "Tapa", "Temmes", "Tiorva", "Tormasenvaara", "Tornio", "Tottijarvi", "Tulppio", "Turenki", "Turi", "Tuukkala", "Tuurala", "Tuuri", "Tuuski", "Ulvila", "Unari", "Upinniemi", "Utti", "Uusikaarlepyy", "Uusikaupunki", "Vaaksy", "Vaalimaa", "Vaarinmaja", "Vaasa", "Vainikkala", "Valga", "Valkeakoski", "Vantaa", "Varkaus", "Vehkapera", "Vehmasmaki", "Vieki", "Vierumaki", "Viitasaari", "Viljandi", "Vilppula", "Viohma", "Vioru", "Virrat", "Ylike", "Ylivieska", "Ylojarvi"], + ["Sabi", "Wiryeseong", "Hwando", "Gungnae", "Ungjin", "Wanggeomseong", "Ganggyeong", "Jochiwon", "Cheorwon", "Beolgyo", "Gangjin", "Gampo", "Yecheon", "Geochang", "Janghang", "Hadong", "Goseong", "Yeongdong", "Yesan", "Sintaein", "Geumsan", "Boseong", "Jangheung", "Uiseong", "Jumunjin", "Janghowon", "Hongseong", "Gimhwa", "Gwangcheon", "Guryongpo", "Jinyeong", "Buan", "Damyang", "Jangseong", "Wando", "Angang", "Okcheon", "Jeungpyeong", "Waegwan", "Cheongdo", "Gwangyang", "Gochang", "Haenam", "Yeonggwang", "Hanam", "Eumseong", "Daejeong", "Hanrim", "Samrye", "Yongjin", "Hamyang", "Buyeo", "Changnyeong", "Yeongwol", "Yeonmu", "Gurye", "Hwasun", "Hampyeong", "Namji", "Samnangjin", "Dogye", "Hongcheon", "Munsan", "Gapyeong", "Ganghwa", "Geojin", "Sangdong", "Jeongseon", "Sabuk", "Seonghwan", "Heunghae", "Hapdeok", "Sapgyo", "Taean", "Boeun", "Geumwang", "Jincheon", "Bongdong", "Doyang", "Geoncheon", "Pungsan", "Punggi", "Geumho", "Wonju", "Gaun", "Hayang", "Yeoju", "Paengseong", "Yeoncheon", "Yangpyeong", "Ganseong", "Yanggu", "Yangyang", "Inje", "Galmal", "Pyeongchang", "Hwacheon", "Hoengseong", "Seocheon", "Cheongyang", "Goesan", "Danyang", "Hamyeol", "Muju", "Sunchang", "Imsil", "Jangsu", "Jinan", "Goheung", "Gokseong", "Muan", "Yeongam", "Jindo", "Seonsan", "Daegaya", "Gunwi", "Bonghwa", "Seongju", "Yeongdeok", "Yeongyang", "Ulleung", "Uljin", "Cheongsong", "wayang", "Namhae", "Sancheong", "Uiryeong", "Gaya", "Hapcheon", "Wabu", "Dongsong", "Sindong", "Wondeok", "Maepo", "Anmyeon", "Okgu", "Sariwon", "Dolsan", "Daedeok", "Gwansan", "Geumil", "Nohwa", "Baeksu", "Illo", "Jido", "Oedong", "Ocheon", "Yeonil", "Hamchang", "Pyeonghae", "Gijang", "Jeonggwan", "Aewor", "Gujwa", "Seongsan", "Jeongok", "Seonggeo", "Seungju", "Hongnong", "Jangan", "Jocheon", "Gohan", "Jinjeop", "Bubal", "Beobwon", "Yeomchi", "Hwado", "Daesan", "Hwawon", "Apo", "Nampyeong", "Munsan", "Sinbuk", "Munmak", "Judeok", "Bongyang", "Ungcheon", "Yugu", "Unbong", "Mangyeong", "Dong", "Naeseo", "Sanyang", "Soheul", "Onsan", "Eonyang", "Nongong", "Dasa", "Goa", "Jillyang", "Bongdam", "Naesu", "Beomseo", "Opo", "Gongdo", "Jingeon", "Onam", "Baekseok", "Jiksan", "Mokcheon", "Jori", "Anjung", "Samho", "Ujeong", "Buksam", "Tongjin", "Chowol", "Gonjiam", "Pogok", "Seokjeok", "Poseung", "Ochang", "Hyangnam", "Baebang", "Gochon", "Songak", "Samhyang", "Yangchon", "Osong", "Aphae", "Ganam", "Namyang", "Chirwon", "Andong", "Ansan", "Anseong", "Anyang", "Asan", "Boryeong", "Bucheon", "Busan", "Changwon", "Cheonan", "Cheongju", "Chuncheon", "Chungju", "Daegu", "Daejeon", "Dangjin", "Dongducheon", "Donghae", "Gangneung", "Geoje", "Gimcheon", "Gimhae", "Gimje", "Gimpo", "Gongju", "Goyang", "Gumi", "Gunpo", "Gunsan", "Guri", "Gwacheon", "Gwangju", "Gwangju", "Gwangmyeong", "Gyeongju", "Gyeongsan", "Gyeryong", "Hwaseong", "Icheon", "Iksan", "Incheon", "Jecheon", "Jeongeup", "Jeonju", "Jeju", "Jinju", "Naju", "Namyangju", "Namwon", "Nonsan", "Miryang", "Mokpo", "Mungyeong", "Osan", "Paju", "Pocheon", "Pohang", "Pyeongtaek", "Sacheon", "Sangju", "Samcheok", "Sejong", "Seogwipo", "Seongnam", "Seosan", "Seoul", "Siheung", "Sokcho", "Suncheon", "Suwon", "Taebaek", "Tongyeong", "Uijeongbu", "Uiwang", "Ulsan", "Yangju", "Yangsan", "Yeongcheon", "Yeongju", "Yeosu", "Yongin", "Chungmu", "Daecheon", "Donggwangyang", "Geumseong", "Gyeongseong", "Iri", "Jangseungpo", "Jeomchon", "Jeongju", "Migeum", "Onyang", "Samcheonpo", "Busan", "Busan", "Cheongju", "Chuncheon", "Daegu", "Daegu", "Daejeon", "Daejeon", "Gunsan", "Gwangju", "Gwangju", "Gyeongseong", "Incheon", "Incheon", "Iri", "Jeonju", "Jinhae", "Jinju", "Masan", "Masan", "Mokpo", "Songjeong", "Songtan", "Ulsan", "Yeocheon", "Cheongjin", "Gaeseong", "Haeju", "Hamheung", "Heungnam", "Jinnampo", "Najin", "Pyeongyang", "Seongjin", "Sineuiju", "Songnim", "Wonsan"], + ["Anding", "Anlu", "Anqing", "Anshun", "Baan", "Baixing", "Banyang", "Baoding", "Baoqing", "Binzhou", "Caozhou", "Changbai", "Changchun", "Changde", "Changling", "Changsha", "Changtu", "Changzhou", "Chaozhou", "Cheli", "Chengde", "Chengdu", "Chenzhou", "Chizhou", "Chongqing", "Chuxiong", "Chuzhou", "Dading", "Dali", "Daming", "Datong", "Daxing", "Dean", "Dengke", "Dengzhou", "Deqing", "Dexing", "Dihua", "Dingli", "Dongan", "Dongchang", "Dongchuan", "Dongping", "Duyun", "Fengtian", "Fengxiang", "Fengyang", "Fenzhou", "Funing", "Fuzhou", "Ganzhou", "Gaoyao", "Gaozhou", "Gongchang", "Guangnan", "Guangning", "Guangping", "Guangxin", "Guangzhou", "Guide", "Guilin", "Guiyang", "Hailong", "Hailun", "Hangzhou", "Hanyang", "Hanzhong", "Heihe", "Hejian", "Henan", "Hengzhou", "Hezhong", "Huaian", "Huaide", "Huaiqing", "Huanglong", "Huangzhou", "Huining", "Huizhou", "Hulan", "Huzhou", "Jiading", "Jian", "Jianchang", "Jiande", "Jiangning", "Jiankang", "Jianning", "Jiaxing", "Jiayang", "Jilin", "Jinan", "Jingjiang", "Jingzhao", "Jingzhou", "Jinhua", "Jinzhou", "Jiujiang", "Kaifeng", "Kaihua", "Kangding", "Kuizhou", "Laizhou", "Lanzhou", "Leizhou", "Liangzhou", "Lianzhou", "Liaoyang", "Lijiang", "Linan", "Linhuang", "Linjiang", "Lintao", "Liping", "Liuzhou", "Longan", "Longjiang", "Longqing", "Longxing", "Luan", "Lubin", "Lubin", "Luzhou", "Mishan", "Nanan", "Nanchang", "Nandian", "Nankang", "Nanning", "Nanyang", "Nenjiang", "Ningan", "Ningbo", "Ningguo", "Ninguo", "Ningwu", "Ningxia", "Ningyuan", "Pingjiang", "Pingle", "Pingliang", "Pingyang", "Puer", "Puzhou", "Qianzhou", "Qingyang", "Qingyuan", "Qingzhou", "Qiongzhou", "Qujing", "Quzhou", "Raozhou", "Rende", "Ruian", "Ruizhou", "Runing", "Shafeng", "Shajing", "Shaoqing", "Shaowu", "Shaoxing", "Shaozhou", "Shinan", "Shiqian", "Shouchun", "Shuangcheng", "Shulei", "Shunde", "Shunqing", "Shuntian", "Shuoping", "Sicheng", "Sien", "Sinan", "Sizhou", "Songjiang", "Suiding", "Suihua", "Suining", "Suzhou", "Taian", "Taibei", "Tainan", "Taiping", "Taiwan", "Taiyuan", "Taizhou", "Taonan", "Tengchong", "Tieli", "Tingzhou", "Tongchuan", "Tongqing", "Tongren", "Tongzhou", "Weihui", "Wensu", "Wenzhou", "Wuchang", "Wuding", "Wuzhou", "Xian", "Xianchun", "Xianping", "Xijin", "Xiliang", "Xincheng", "Xingan", "Xingde", "Xinghua", "Xingjing", "Xingqing", "Xingyi", "Xingyuan", "Xingzhong", "Xining", "Xinmen", "Xiping", "Xuanhua", "Xunzhou", "Xuzhou", "Yanan", "Yangzhou", "Yanji", "Yanping", "Yanqi", "Yanzhou", "Yazhou", "Yichang", "Yidu", "Yilan", "Yili", "Yingchang", "Yingde", "Yingtian", "Yingzhou", "Yizhou", "Yongchang", "Yongping", "Yongshun", "Yongzhou", "Yuanzhou", "Yuezhou", "Yulin", "Yunnan", "Yunyang", "Zezhou", "Zhangde", "Zhangzhou", "Zhaoqing", "Zhaotong", "Zhenan", "Zhending", "Zhengding", "Zhenhai", "Zhenjiang", "Zhenxi", "Zhenyun", "Zhongshan", "Zunyi"], + ["Nanporo", "Naie", "Kamisunagawa", "Yuni", "Naganuma", "Kuriyama", "Tsukigata", "Urausu", "Shintotsukawa", "Moseushi", "Chippubetsu", "Uryu", "Hokuryu", "Numata", "Tobetsu", "Suttsu", "Kuromatsunai", "Rankoshi", "Niseko", "Kimobetsu", "Kyogoku", "Kutchan", "Kyowa", "Iwanai", "Shakotan", "Furubira", "Niki", "Yoichi", "Toyoura", "Toyako", "Sobetsu", "Shiraoi", "Atsuma", "Abira", "Mukawa", "Hidaka", "Biratori", "Niikappu", "Urakawa", "Samani", "Erimo", "Shinhidaka", "Matsumae", "Fukushima", "Shiriuchi", "Kikonai", "Nanae", "Shikabe", "Mori", "Yakumo", "Oshamambe", "Esashi", "Kaminokuni", "Assabu", "Otobe", "Okushiri", "Imakane", "Setana", "Takasu", "Higashikagura", "Toma", "Pippu", "Aibetsu", "Kamikawa", "Higashikawa", "Biei", "Kamifurano", "Nakafurano", "Minamifurano", "Horokanai", "Wassamu", "Kenbuchi", "Shimokawa", "Bifuka", "Nakagawa", "Mashike", "Obira", "Tomamae", "Haboro", "Enbetsu", "Teshio", "Hamatonbetsu", "Nakatonbetsu", "Esashi", "Toyotomi", "Horonobe", "Rebun", "Rishiri", "Rishirifuji", "Bihoro", "Tsubetsu", "Ozora", "Shari", "Kiyosato", "Koshimizu", "Kunneppu", "Oketo", "Saroma", "Engaru", "Yubetsu", "Takinoue", "Okoppe", "Omu", "Otofuke", "Shihoro", "Kamishihoro", "Shikaoi", "Shintoku", "Shimizu", "Memuro", "Taiki", "Hiroo", "Makubetsu", "Ikeda", "Toyokoro", "Honbetsu", "Ashoro", "Rikubetsu", "Urahoro", "Kushiro", "Akkeshi", "Hamanaka", "Shibecha", "Teshikaga", "Shiranuka", "Betsukai", "Nakashibetsu", "Shibetsu", "Rausu", "Hiranai", "Imabetsu", "Sotogahama", "Ajigasawa", "Fukaura", "Fujisaki", "Owani", "Itayanagi", "Tsuruta", "Nakadomari", "Noheji", "Shichinohe", "Rokunohe", "Yokohama", "Tohoku", "Oirase", "Oma", "Sannohe", "Gonohe", "Takko", "Nanbu", "Hashikami", "Shizukuishi", "Kuzumaki", "Iwate", "Shiwa", "Yahaba", "Nishiwaga", "Kanegasaki", "Hiraizumi", "Sumita", "Otsuchi", "Yamada", "Iwaizumi", "Karumai", "Hirono", "Ichinohe", "Zao", "Shichikashuku", "Ogawara", "Murata", "Shibata", "Kawasaki", "Marumori", "Watari", "Yamamoto", "Matsushima", "Shichigahama", "Rifu", "Taiwa", "Osato", "Shikama", "Kami", "Wakuya", "Misato", "Onagawa", "Minamisanriku", "Kosaka", "Fujisato", "Mitane", "Happo", "Gojome", "Hachirogata", "Ikawa", "Misato", "Ugo", "Yamanobe", "Nakayama", "Kahoku", "Nishikawa", "Asahi", "Oe", "Oishida", "Kaneyama", "Mogami", "Funagata", "Mamurogawa", "Takahata", "Kawanishi", "Oguni", "Shirataka", "Iide", "Mikawa", "Shonai", "Yuza", "Koori", "Kunimi", "Kawamata", "Kagamiishi", "Shimogo", "Tadami", "Minamiaizu", "Nishiaizu", "Bandai", "Inawashiro", "Aizubange", "Yanaizu", "Mishima", "Kaneyama", "Aizumisato", "Yabuki", "Tanagura", "Yamatsuri", "Hanawa", "Ishikawa", "Asakawa", "Furudono", "Miharu", "Ono", "Hirono", "Naraha", "Tomioka", "Okuma", "Futaba", "Namie", "Shinchi", "Ibaraki", "Oarai", "Shirosato", "Daigo", "Ami", "Kawachi", "Yachiyo", "Goka", "Sakai", "Tone", "Kaminokawa", "Mashiko", "Motegi", "Ichikai", "Haga", "Mibu", "Nogi", "Shioya", "Takanezawa", "Nasu", "Nakagawa", "Yoshioka", "Kanna", "Shimonita", "Kanra", "Nakanojo", "Naganohara", "Kusatsu", "Higashiagatsuma", "Minakami", "Tamamura", "Itakura", "Meiwa", "Chiyoda", "Oizumi", "Ora", "Ina", "Miyoshi", "Moroyama", "Ogose", "Namegawa", "Ranzan", "Ogawa", "Kawajima", "Yoshimi", "Hatoyama", "Tokigawa", "Yokoze", "Minano", "Nagatoro", "Ogano", "Misato", "Kamikawa", "Kamisato", "Yorii", "Miyashiro", "Sugito", "Matsubushi", "Shisui", "Sakae", "Kozaki", "Tako", "Tonosho", "Kujukuri", "Shibayama", "Yokoshibahikari", "Ichinomiya", "Mutsuzawa", "Shirako", "Nagara", "Chonan", "Otaki", "Onjuku", "Kyonan", "Mizuho", "Hinode", "Okutama", "Oshima", "Hachijo", "Aikawa", "Hayama", "Samukawa", "Oiso", "Ninomiya", "Nakai", "Oi", "Matsuda", "Yamakita", "Kaisei", "Hakone", "Manazuru", "Yugawara", "Seiro", "Tagami", "Aga", "Izumozaki", "Yuzawa", "Tsunan", "Kamiichi", "Tateyama", "Nyuzen", "Asahi", "Kawakita", "Tsubata", "Uchinada", "Shika", "Hodatsushimizu", "Nakanoto", "Anamizu", "Noto", "Eiheiji", "Ikeda", "Minamiechizen", "Echizen", "Mihama", "Takahama", "Oi", "Wakasa", "Ichikawamisato", "Hayakawa", "Minobu", "Nanbu", "Fujikawa", "Showa", "Nishikatsura", "Fujikawaguchiko", "Koumi", "Sakuho", "Karuizawa", "Miyota", "Tateshina", "Nagawa", "Shimosuwa", "Fujimi", "Tatsuno", "Minowa", "Iijima", "Matsukawa", "Takamori", "Anan", "Agematsu", "Nagiso", "Kiso", "Ikeda", "Sakaki", "Obuse", "Yamanouchi", "Shinano", "Iizuna", "Ginan", "Kasamatsu", "Yoro", "Tarui", "Sekigahara", "Godo", "Wanouchi", "Anpachi", "Ibigawa", "Ono", "Ikeda", "Kitagata", "Sakahogi", "Tomika", "Kawabe", "Hichiso", "Yaotsu", "Shirakawa", "Mitake", "Higashiizu", "Kawazu", "Minamiizu", "Matsuzaki", "Nishiizu", "Kannami", "Shimizu", "Nagaizumi", "Oyama", "Yoshida", "Kawanehon", "Mori", "Togo", "Toyoyama", "Oguchi", "Fuso", "Oharu", "Kanie", "Agui", "Higashiura", "Minamichita", "Mihama", "Taketoyo", "Mihama", "Kota", "Shitara", "Toei", "Kisosaki", "Toin", "Komono", "Asahi", "Kawagoe", "Taki", "Meiwa", "Odai", "Tamaki", "Watarai", "Taiki", "Minamiise", "Kihoku", "Mihama", "Kiho", "Hino", "Ryuo", "Aisho", "Toyosato", "Kora", "Taga", "Oyamazaki", "Kumiyama", "Ide", "Ujitawara", "Kasagi", "Wazuka", "Seika", "Kyotamba", "Ine", "Yosano", "Shimamoto", "Toyono", "Nose", "Tadaoka", "Kumatori", "Tajiri", "Misaki", "Taishi", "Kanan", "Inagawa", "Taka", "Inami", "Harima", "Ichikawa", "Fukusaki", "Kamikawa", "Taishi", "Kamigori", "Sayo", "Kami", "Shin'onsen", "Heguri", "Sango", "Ikaruga", "Ando", "Kawanishi", "Miyake", "Tawaramoto", "Takatori", "Kanmaki", "Oji", "Koryo", "Kawai", "Yoshino", "Oyodo", "Shimoichi", "Kushimoto", "Kimino", "Katsuragi", "Kudoyama", "Koya", "Yuasa", "Hirogawa", "Aridagawa", "Mihama", "Hidaka", "Yura", "Inami", "Minabe", "Hidakagawa", "Shirahama", "Kamitonda", "Susami", "Nachikatsuura", "Taiji", "Kozagawa", "Iwami", "Wakasa", "Chizu", "Yazu", "Misasa", "Yurihama", "Kotoura", "Hokuei", "Daisen", "Nanbu", "Hoki", "Nichinan", "Hino", "Kofu", "Okuizumo", "Iinan", "Kawamoto", "Misato", "Onan", "Tsuwano", "Yoshika", "Ama", "Nishinoshima", "Okinoshima", "Wake", "Hayashima", "Satosho", "Yakage", "Kagamino", "Shoo", "Nagi", "Kumenan", "Misaki", "Kibichuo", "Fuchu", "Kaita", "Kumano", "Saka", "Kitahiroshima", "Akiota", "Osakikamijima", "Sera", "Jinsekikogen", "Suooshima", "Waki", "Kaminoseki", "Tabuse", "Hirao", "Abu", "Katsuura", "Kamikatsu", "Ishii", "Kamiyama", "Naka", "Mugi", "Minami", "Kaiyo", "Matsushige", "Kitajima", "Aizumi", "Itano", "Kamiita", "Tsurugi", "Higashimiyoshi", "Tonosho", "Shodoshima", "Miki", "Naoshima", "Utazu", "Ayagawa", "Kotohira", "Tadotsu", "Manno", "Kamijima", "Kumakogen", "Masaki", "Tobe", "Uchiko", "Ikata", "Kihoku", "Matsuno", "Ainan", "Toyo", "Nahari", "Tano", "Yasuda", "Motoyama", "Otoyo", "Tosa", "Ino", "Niyodogawa", "Nakatosa", "Sakawa", "Ochi", "Yusuhara", "Tsuno", "Shimanto", "Otsuki", "Kuroshio", "Nakagawa", "Umi", "Sasaguri", "Shime", "Sue", "Shingu", "Hisayama", "Kasuya", "Ashiya", "Mizumaki", "Okagaki", "Onga", "Kotake", "Kurate", "Keisen", "Chikuzen", "Tachiarai", "Oki", "Hirokawa", "Kawara", "Soeda", "Itoda", "Kawasaki", "Oto", "Fukuchi", "Kanda", "Miyako", "Yoshitomi", "Koge", "Chikujo", "Yoshinogari", "Kiyama", "Kamimine", "Miyaki", "Genkai", "Arita", "Omachi", "Kohoku", "Shiroishi", "Tara", "Nagayo", "Togitsu", "Higashisonogi", "Kawatana", "Hasami", "Ojika", "Saza", "Shinkamigoto", "Misato", "Gyokuto", "Nankan", "Nagasu", "Nagomi", "Ozu", "Kikuyo", "Minamioguni", "Oguni", "Takamori", "Mifune", "Kashima", "Mashiki", "Kosa", "Yamato", "Hikawa", "Ashikita", "Tsunagi", "Nishiki", "Taragi", "Yunomae", "Asagiri", "Reihoku", "Hiji", "Kusu", "Kokonoe", "Mimata", "Takaharu", "Kunitomi", "Aya", "Takanabe", "Shintomi", "Kijo", "Kawaminami", "Tsuno", "Kadogawa", "Misato", "Takachiho", "Hinokage", "Gokase", "Satsuma", "Nagashima", "Yusui", "Osaki", "Higashikushira", "Kinko", "Minamiosumi", "Kimotsuki", "Nakatane", "Minamitane", "Yakushima", "Setouchi", "Tatsugo", "Kikai", "Tokunoshima", "Amagi", "Isen", "Wadomari", "China", "Yoron", "Motobu", "Kin", "Kadena", "Chatan", "Nishihara", "Yonabaru", "Haebaru", "Kumejima", "Yaese", "Taketomi", "Yonaguni"] ]; } @@ -407,7 +408,7 @@ function fantasyMap() { console.time("calculateVoronoi"); diagram = voronoi(points); // round edges to simplify future calculations - diagram.edges.forEach(function(e) { + diagram.edges.forEach(function (e) { e[0][0] = rn(e[0][0], 2); e[0][1] = rn(e[0][1], 2); e[1][0] = rn(e[1][0], 2); @@ -465,11 +466,13 @@ function fantasyMap() { if (debug.selectAll(".tag").size() === 1) { const x = +debug.select(".tag").attr("cx"); const y = +debug.select(".tag").attr("cy"); - if (line.size()) {line.attr("x1", x).attr("y1", y).attr("x2", point[0]).attr("y2", point[1]);} - else {debug.insert("line", ":first-child").attr("class", "line") - .attr("x1", x).attr("y1", y).attr("x2", point[0]).attr("y2", point[1]);} + if (line.size()) { line.attr("x1", x).attr("y1", y).attr("x2", point[0]).attr("y2", point[1]); } + else { + debug.insert("line", ":first-child").attr("class", "line") + .attr("x1", x).attr("y1", y).attr("x2", point[0]).attr("y2", point[1]); + } } else { - line.remove(); + line.remove(); } } @@ -523,7 +526,7 @@ function fantasyMap() { // Drag actions function dragstarted() { var x0 = d3.event.x, y0 = d3.event.y, - c0 = diagram.find(x0, y0).index, c1 = c0; + c0 = diagram.find(x0, y0).index, c1 = c0; var x1, y1; var opisometer = $("#addOpisometer").hasClass("pressed"); var planimeter = $("#addPlanimeter").hasClass("pressed"); @@ -533,7 +536,7 @@ function fantasyMap() { $("#ruler").show(); var type = opisometer ? "opisometer" : "planimeter"; var rulerNew = ruler.append("g").attr("class", type).call(d3.drag().on("start", elementDrag)); - var points = [{scX: rn(x0, 2), scY: rn(y0, 2)}]; + var points = [{ scX: rn(x0, 2), scY: rn(y0, 2) }]; if (opisometer) { var curve = rulerNew.append("path").attr("class", "opisometer white").attr("stroke-width", factor); var dash = rn(30 / distanceScale.value, 2); @@ -544,7 +547,7 @@ function fantasyMap() { var text = rulerNew.append("text").attr("dy", -1).attr("font-size", 10 * factor); } - d3.event.on("drag", function() { + d3.event.on("drag", function () { x1 = d3.event.x, y1 = d3.event.y; var c2 = diagram.find(x1, y1).index; @@ -555,8 +558,8 @@ function fantasyMap() { const brush = $("#brushesButtons > .pressed"); const id = brush.attr("id"); const power = +brushPower.value; - if (id === "brushHill") {add(c2, "hill", power); updateHeightmap();} - if (id === "brushPit") {addPit(1, power, c2); updateHeightmap();} + if (id === "brushHill") { add(c2, "hill", power); updateHeightmap(); } + if (id === "brushPit") { addPit(1, power, c2); updateHeightmap(); } if (id !== "brushRange" || id !== "brushTrough") { // move a circle to show approximate change radius moveCircle(x1, y1); @@ -582,7 +585,7 @@ function fantasyMap() { if (opisometer || planimeter) { var l = points[points.length - 1]; var diff = Math.hypot(l.scX - x1, l.scY - y1); - if (diff > 5) {points.push({scX: x1, scY: y1});} + if (diff > 5) { points.push({ scX: x1, scY: y1 }); } if (opisometer) { lineGen.curve(d3.curveBasis); var d = round(lineGen(points)); @@ -599,7 +602,7 @@ function fantasyMap() { } }); - d3.event.on("end", function() { + d3.event.on("end", function () { if (customization === 1) updateHistory(); if (opisometer || planimeter) { $("#addOpisometer, #addPlanimeter").removeClass("pressed"); @@ -611,18 +614,18 @@ function fantasyMap() { var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; var atan = p.x > c.x ? Math.atan2(p.y - c.y, p.x - c.x) : Math.atan2(c.y - p.y, c.x - p.x); var angle = rn(atan * 180 / Math.PI, 3); - var tr = "rotate(" + angle + " " + c.x + " " + c.y +")"; + var tr = "rotate(" + angle + " " + c.x + " " + c.y + ")"; text.attr("data-points", JSON.stringify(points)).attr("data-dist", dist).attr("x", c.x).attr("y", c.y).attr("transform", tr).text(label).on("click", removeParent); rulerNew.append("circle").attr("cx", points[0].scX).attr("cy", points[0].scY).attr("r", 2 * factor).attr("stroke-width", 0.5 * factor) .attr("data-edge", "start").call(d3.drag().on("start", opisometerEdgeDrag)); rulerNew.append("circle").attr("cx", points[points.length - 1].scX).attr("cy", points[points.length - 1].scY).attr("r", 2 * factor).attr("stroke-width", 0.5 * factor) .attr("data-edge", "end").call(d3.drag().on("start", opisometerEdgeDrag)); } else { - var vertices = points.map(function(p) {return [p.scX, p.scY]}); + var vertices = points.map(function (p) { return [p.scX, p.scY] }); var area = rn(Math.abs(d3.polygonArea(vertices))); // initial area as positive integer var areaConv = area * Math.pow(distanceScale.value, 2); // convert area to distanceScale areaConv = si(areaConv); - if (areaUnit.value === "square") {areaConv += " " + distanceUnit.value + "²"} else {areaConv += " " + areaUnit.value;} + if (areaUnit.value === "square") { areaConv += " " + distanceUnit.value + "²" } else { areaConv += " " + areaUnit.value; } var c = polylabel([vertices], 1.0); // pole of inaccessibility text.attr("x", rn(c[0], 2)).attr("y", rn(c[1], 2)).attr("data-area", area).text(areaConv).on("click", removeParent); } @@ -645,14 +648,14 @@ function fantasyMap() { let radius = r; let selection = [center]; if (radius > 1) selection = selection.concat(cells[center].neighbors); - selection = $.grep(selection, function(e) {return cells[e].height >= 0.2;}); + selection = $.grep(selection, function (e) { return cells[e].height >= 0.2; }); if (radius === 2) return selection; let frontier = cells[center].neighbors; while (radius > 2) { let cycle = frontier.slice(); frontier = []; - cycle.map(function(s) { - cells[s].neighbors.forEach(function(e) { + cycle.map(function (s) { + cells[s].neighbors.forEach(function (e) { if (selection.indexOf(e) !== -1) return; // if (cells[e].height < 0.2) return; selection.push(e); @@ -661,7 +664,7 @@ function fantasyMap() { }); radius--; } - selection = $.grep(selection, function(e) {return cells[e].height >= 0.2;}); + selection = $.grep(selection, function (e) { return cells[e].height >= 0.2; }); return selection; } @@ -671,9 +674,9 @@ function fantasyMap() { const temp = regions.select("#temp"); const stateNew = +$("div.selected").attr("id").slice(5); const color = states[stateNew].color === "neutral" ? "white" : states[stateNew].color; - selection.map(function(index) { + selection.map(function (index) { // keep stateOld and stateNew as integers! - const exists = temp.select("path[data-cell='"+index+"']"); + const exists = temp.select("path[data-cell='" + index + "']"); const region = cells[index].region === "neutral" ? states.length - 1 : cells[index].region const stateOld = exists.size() ? +exists.attr("data-state") : region; if (stateNew === stateOld) return; @@ -694,8 +697,8 @@ function fantasyMap() { if (selection.length === 0) return; const cultureNew = +$("div.selected").attr("id").slice(7); const clr = cultures[cultureNew].color; - selection.map(function(index) { - const cult = cults.select("#cult"+index); + selection.map(function (index) { + const cult = cults.select("#cult" + index); const cultureOld = cult.attr("data-culture") !== null ? +cult.attr("data-culture") : cells[index].culture; @@ -709,18 +712,18 @@ function fantasyMap() { const power = +brushPower.value; let radius = +brushRadius.value; const brush = $("#brushesButtons > .pressed").attr("id"); - if ($("#brushesButtons > .pressed").hasClass("feature")) {return;} + if ($("#brushesButtons > .pressed").hasClass("feature")) { return; } // define selection besed on radius let selection = [cell]; - if (radius > 1) {selection = selection.concat(cells[cell].neighbors);} + if (radius > 1) { selection = selection.concat(cells[cell].neighbors); } if (radius > 2) { let frontier = cells[cell].neighbors; while (radius > 2) { let cycle = frontier.slice(); frontier = []; - cycle.map(function(s) { - cells[s].neighbors.forEach(function(e) { - if (selection.indexOf(e) !== -1) {return;} + cycle.map(function (s) { + cells[s].neighbors.forEach(function (e) { + if (selection.indexOf(e) !== -1) { return; } selection.push(e); frontier.push(e); }); @@ -730,17 +733,17 @@ function fantasyMap() { } // change each cell in the selection const sourceHeight = cells[source].height; - selection.map(function(s) { + selection.map(function (s) { // calculate changes if (brush === "brushElevate") { - if (cells[s].height < 0.2) {cells[s].height = 0.2} - else {cells[s].height += power;} + if (cells[s].height < 0.2) { cells[s].height = 0.2 } + else { cells[s].height += power; } } - if (brush === "brushDepress") {cells[s].height -= power;} - if (brush === "brushAlign") {cells[s].height = sourceHeight;} + if (brush === "brushDepress") { cells[s].height -= power; } + if (brush === "brushAlign") { cells[s].height = sourceHeight; } if (brush === "brushSmooth") { let heights = [cells[s].height]; - cells[s].neighbors.forEach(function(e) {heights.push(cells[e].height);}); + cells[s].neighbors.forEach(function (e) { heights.push(cells[e].height); }); cells[s].height = (cells[s].height + d3.mean(heights)) / 2; } }); @@ -770,11 +773,11 @@ function fantasyMap() { console.time("detectNeighbors"); var gridPath = ""; // store grid as huge single path string cells = []; - polygons.map(function(i, d) { + polygons.map(function (i, d) { var neighbors = []; var type; // define cell type - if (withGrid) {gridPath += "M" + i.join("L") + "Z";} // grid path - diagram.cells[d].halfedges.forEach(function(e) { + if (withGrid) { gridPath += "M" + i.join("L") + "Z"; } // grid path + diagram.cells[d].halfedges.forEach(function (e) { var edge = diagram.edges[e], ea; if (edge.left && edge.right) { const ea = edge.left.index === d ? edge.right.index : edge.left.index; @@ -783,9 +786,9 @@ function fantasyMap() { type = "border"; // polygon is on border if it has edge without opposite side polygon } }) - cells.push({index: d, data: i.data, height: 0, type, neighbors}); + cells.push({ index: d, data: i.data, height: 0, type, neighbors }); }); - if (withGrid) {grid.append("path").attr("d", round(gridPath, 1));} + if (withGrid) { grid.append("path").attr("d", round(gridPath, 1)); } console.timeEnd("detectNeighbors"); } @@ -794,22 +797,22 @@ function fantasyMap() { console.time('defineHeightmap'); if (lockTemplateInput.getAttribute("data-locked") == 0) { const rnd = Math.random(); - if (rnd > 0.9) {templateInput.value = "Volcano";} - else if (rnd > 0.7) {templateInput.value = "High Island";} - else if (rnd > 0.5) {templateInput.value = "Low Island";} - else if (rnd > 0.35) {templateInput.value = "Continents";} - else if (rnd > 0.01) {templateInput.value = "Archipelago";} - else {templateInput.value = "Atoll";} + if (rnd > 0.9) { templateInput.value = "Volcano"; } + else if (rnd > 0.7) { templateInput.value = "High Island"; } + else if (rnd > 0.5) { templateInput.value = "Low Island"; } + else if (rnd > 0.35) { templateInput.value = "Continents"; } + else if (rnd > 0.01) { templateInput.value = "Archipelago"; } + else { templateInput.value = "Atoll"; } } const mapTemplate = templateInput.value; addMountain(); const mod = rn((graphWidth + graphHeight) / 1500, 2); // add mod for big screens - if (mapTemplate === "Volcano") {templateVolcano(mod);} - if (mapTemplate === "High Island") {templateHighIsland(mod);} - if (mapTemplate === "Low Island") {templateLowIsland(mod);} - if (mapTemplate === "Continents") {templateContinents(mod);} - if (mapTemplate === "Archipelago") {templateArchipelago(mod);} - if (mapTemplate === "Atoll") {templateAtoll(mod);} + if (mapTemplate === "Volcano") { templateVolcano(mod); } + if (mapTemplate === "High Island") { templateHighIsland(mod); } + if (mapTemplate === "Low Island") { templateLowIsland(mod); } + if (mapTemplate === "Continents") { templateContinents(mod); } + if (mapTemplate === "Archipelago") { templateArchipelago(mod); } + if (mapTemplate === "Atoll") { templateAtoll(mod); } console.log(" template: " + mapTemplate); console.timeEnd('defineHeightmap'); } @@ -823,7 +826,7 @@ function fantasyMap() { addRange(rn(-10 * mod)); } -// Heighmap Template: High Island + // Heighmap Template: High Island function templateHighIsland(mod) { modifyHeights("all", 0.05, 0.9); addRange(rn(4 * mod)); @@ -833,7 +836,7 @@ function fantasyMap() { addHill(rn(3 * mod), 0.15); } -// Heighmap Template: Low Island + // Heighmap Template: Low Island function templateLowIsland(mod) { smoothHeights(2); addRange(rn(5 * mod)); @@ -890,14 +893,14 @@ function fantasyMap() { function addHill(count, shift) { // shift from 0 to 0.5 - for (c = 0; c < count; c++) { + for (let c = 0; c < count; c++) { var limit = 0; do { var height = Math.random() * 0.4 + 0.1; - var x = Math.floor(Math.random() * graphWidth * (1-shift*2) + graphWidth * shift); - var y = Math.floor(Math.random() * graphHeight * (1-shift*2) + graphHeight * shift); + var x = Math.floor(Math.random() * graphWidth * (1 - shift * 2) + graphWidth * shift); + var y = Math.floor(Math.random() * graphHeight * (1 - shift * 2) + graphHeight * shift); var rnd = diagram.find(x, y).index; - limit ++; + limit++; } while (cells[rnd].height + height > 0.9 && limit < 100) add(rnd, "hill", height); } @@ -914,18 +917,18 @@ function fantasyMap() { } radius = type === "mountain" ? mRadius : hRadius; var queue = [start]; - if (type === "mountain") {cells[start].height = height;} - for (i = 0; i < queue.length && height >= 0.01; i++) { + if (type === "mountain") { cells[start].height = height; } + for (let i = 0; i < queue.length && height >= 0.01; i++) { if (type == "mountain") { height = +cells[queue[i]].height * radius - height / 100; } else { height *= radius; } - cells[queue[i]].neighbors.forEach(function(e) { - if (cells[e].used === session) {return;} + cells[queue[i]].neighbors.forEach(function (e) { + if (cells[e].used === session) { return; } var mod = Math.random() * 0.2 + 0.9; cells[e].height += height * mod; - if (cells[e].height > 1) {cells[e].height = 1;} + if (cells[e].height > 1) { cells[e].height = 1; } cells[e].used = session; queue.push(e); }); @@ -936,38 +939,38 @@ function fantasyMap() { var session = Math.ceil(Math.random() * 100000); var count = Math.abs(mod); let range = []; - for (c = 0; c < count; c++) { + for (let c = 0; c < count; c++) { range = []; var diff = 0, start = from, end = to; if (!start || !end) { do { - var xf = Math.floor(Math.random() * (graphWidth*0.7)) + graphWidth*0.15; - var yf = Math.floor(Math.random() * (graphHeight*0.6)) + graphHeight*0.2; + var xf = Math.floor(Math.random() * (graphWidth * 0.7)) + graphWidth * 0.15; + var yf = Math.floor(Math.random() * (graphHeight * 0.6)) + graphHeight * 0.2; start = diagram.find(xf, yf).index; - var xt = Math.floor(Math.random() * (graphWidth*0.7)) + graphWidth*0.15; - var yt = Math.floor(Math.random() * (graphHeight*0.6)) + graphHeight*0.2; + var xt = Math.floor(Math.random() * (graphWidth * 0.7)) + graphWidth * 0.15; + var yt = Math.floor(Math.random() * (graphHeight * 0.6)) + graphHeight * 0.2; end = diagram.find(xt, yt).index; diff = Math.hypot(xt - xf, yt - yf); - } while (diff < 150 / graphSize || diff > 300 / graphSize) + } while (diff < 150 / graphSize || diff > 300 / graphSize) } if (start && end) { - for (var l = 0; start != end && l < 10000; l++) { + for (let l = 0; start != end && l < 10000; l++) { var min = 10000; - cells[start].neighbors.forEach(function(e) { + cells[start].neighbors.forEach(function (e) { diff = Math.hypot(cells[end].data[0] - cells[e].data[0], cells[end].data[1] - cells[e].data[1]); - if (Math.random() > 0.8) {diff = diff / 2} - if (diff < min) {min = diff, start = e;} + if (Math.random() > 0.8) { diff = diff / 2 } + if (diff < min) { min = diff, start = e; } }); range.push(start); } } var change = height ? height : Math.random() * 0.1 + 0.1; - range.map(function(r) { + range.map(function (r) { var rnd = Math.random() * 0.4 + 0.8; - if (mod > 0) {cells[r].height += change * rnd;} - else if (cells[r].height >= 0.1) {cells[r].height -= change * rnd;} - cells[r].neighbors.forEach(function(e) { - if (cells[e].used === session) {return;} + if (mod > 0) { cells[r].height += change * rnd; } + else if (cells[r].height >= 0.1) { cells[r].height -= change * rnd; } + cells[r].neighbors.forEach(function (e) { + if (cells[e].used === session) { return; } cells[e].used = session; rnd = Math.random() * 0.4 + 0.8; if (mod > 0) { @@ -988,20 +991,20 @@ function fantasyMap() { var start = diagram.find(top, graphHeight * 0.2).index; var end = diagram.find(bottom, graphHeight * 0.8).index; var range = []; - for (var l = 0; start !== end && l < 1000; l++) { + for (let l = 0; start !== end && l < 1000; l++) { var min = 10000; // dummy value - cells[start].neighbors.forEach(function(e) { - diff = Math.hypot(cells[end].data[0] - cells[e].data[0], cells[end].data[1] - cells[e].data[1]); - if (Math.random() > 0.8) {diff = diff / 2} - if (diff < min) {min = diff; start = e;} + cells[start].neighbors.forEach(function (e) { + let diff = Math.hypot(cells[end].data[0] - cells[e].data[0], cells[end].data[1] - cells[e].data[1]); + if (Math.random() > 0.8) { diff = diff / 2 } + if (diff < min) { min = diff; start = e; } }); range.push(start); } var query = []; for (; width > 0; width--) { - range.map(function(r) { - cells[r].neighbors.forEach(function(e) { - if (cells[e].used === session) {return;} + range.map(function (r) { + cells[r].neighbors.forEach(function (e) { + if (cells[e].used === session) { return; } cells[e].used = session; query.push(e); var height = cells[e].height * 0.23; @@ -1014,32 +1017,32 @@ function fantasyMap() { function addPit(count, height, cell) { var session = Math.ceil(Math.random() * 100000); - for (c = 0; c < count; c++) { + for (let c = 0; c < count; c++) { var change = height ? height + 0.1 : Math.random() * 0.1 + 0.2; var start = cell; if (!start) { - var lowlands = $.grep(cells, function(e) {return (e.height >= 0.2);}); - if (lowlands.length == 0) {return;} + var lowlands = $.grep(cells, function (e) { return (e.height >= 0.2); }); + if (lowlands.length == 0) { return; } var rnd = Math.floor(Math.random() * lowlands.length); start = lowlands[rnd].index; } - var query = [start], newQuery= []; + var query = [start], newQuery = []; // depress pit center cells[start].height -= change; - if (cells[start].height < 0.05) {cells[start].height = 0.05;} + if (cells[start].height < 0.05) { cells[start].height = 0.05; } cells[start].used = session; - for (var i = 1; i < 10000; i++) { + for (let i = 1; i < 10000; i++) { var rnd = Math.random() * 0.4 + 0.8; change -= i / 60 * rnd; - if (change < 0.01) {return;} - query.map(function(p) { - cells[p].neighbors.forEach(function(e) { - if (cells[e].used === session) {return;} + if (change < 0.01) { return; } + query.map(function (p) { + cells[p].neighbors.forEach(function (e) { + if (cells[e].used === session) { return; } cells[e].used = session; - if (Math.random() > 0.8) {return;} + if (Math.random() > 0.8) { return; } newQuery.push(e); cells[e].height -= change; - if (cells[e].height < 0.05) {cells[e].height = 0.05;} + if (cells[e].height < 0.05) { cells[e].height = 0.05; } }); }); query = newQuery.slice(); @@ -1050,14 +1053,14 @@ function fantasyMap() { // Modify heights multiplying/adding by value function modifyHeights(type, add, mult) { - cells.map(function(i) { + cells.map(function (i) { if (type === "land") { if (i.height >= 0.2) { i.height += add; var dif = i.height - 0.2; var factor = mult; - if (mult == "^2") {factor = dif} - if (mult == "^3") {factor = dif * dif;} + if (mult == "^2") { factor = dif } + if (mult == "^3") { factor = dif * dif; } i.height = 0.2 + dif * factor; } } else if (type === "all") { @@ -1069,8 +1072,8 @@ function fantasyMap() { var interval = type.split("-"); if (i.height >= +interval[0] && i.height <= +interval[1]) { i.height += add; - if ($.isNumeric(mult)) {i.height *= mult; return;} - if (mult.slice(0,1) === "^") { + if ($.isNumeric(mult)) { i.height *= mult; return; } + if (mult.slice(0, 1) === "^") { pow = mult.slice(1); i.height = Math.pow(i.height, pow); } @@ -1082,18 +1085,18 @@ function fantasyMap() { // Smooth heights using mean of neighbors function smoothHeights(fraction) { var fraction = fraction || 2; - cells.map(function(i) { + cells.map(function (i) { var heights = [i.height]; - i.neighbors.forEach(function(e) {heights.push(cells[e].height);}); + i.neighbors.forEach(function (e) { heights.push(cells[e].height); }); i.height = (i.height * (fraction - 1) + d3.mean(heights)) / fraction; }); } // Randomize heights a bit function disruptHeights() { - cells.map(function(i) { - if (i.height < 0.18) {return;} - if (Math.random() > 0.5) {return;} + cells.map(function (i) { + if (i.height < 0.18) { return; } + if (Math.random() > 0.5) { return; } var rnd = rn(2 - Math.random() * 4) / 100; i.height = rn(i.height + rnd, 2); }); @@ -1103,7 +1106,7 @@ function fantasyMap() { function markFeatures() { console.time("markFeatures"); - for (let i=0, queue=[0]; queue.length > 0; i++) { + for (let i = 0, queue = [0]; queue.length > 0; i++) { const cell = cells[queue[0]]; cell.fn = i; // feature number const land = cell.height >= 0.2; @@ -1117,7 +1120,7 @@ function fantasyMap() { if (land) cells[q].ctype = 2; } - cells[q].neighbors.forEach(function(e) { + cells[q].neighbors.forEach(function (e) { const eLand = cells[e].height >= 0.2; if (land === eLand && cells[e].fn === undefined) { cells[e].fn = i; @@ -1130,10 +1133,10 @@ function fantasyMap() { } }); } - features.push({i, land, border}); + features.push({ i, land, border }); // find unmarked cell - for (let c=0; c < cells.length; c++) { + for (let c = 0; c < cells.length; c++) { if (cells[c].fn === undefined) { queue[0] = c; break; @@ -1147,16 +1150,16 @@ function fantasyMap() { function reduceClosedLakes() { console.time("reduceClosedLakes"); const fs = JSON.parse(JSON.stringify(features)); - let lakesInit = lakesNow = features.reduce(function(s, f) { + let lakesInit = lakesNow = features.reduce(function (s, f) { return !f.land && !f.border ? s + 1 : s; }, 0); - for (let c=0; c < cells.length && lakesNow > 0; c++) { + for (let c = 0; c < cells.length && lakesNow > 0; c++) { if (cells[c].height < 0.2) continue; // not land if (cells[c].ctype !== 2) continue; // not near water let ocean = null, lake = null; // find land cells with lake and ocean nearby - cells[c].neighbors.forEach(function(n) { + cells[c].neighbors.forEach(function (n) { if (cells[n].height >= 0.2) return; const fn = cells[n].fn; if (features[fn].border !== false) ocean = fn; @@ -1165,17 +1168,17 @@ function fantasyMap() { // if found, make it water and turn lake to ocean if (ocean !== null && lake !== null) { //debug.append("circle").attr("cx", cells[c].data[0]).attr("cy", cells[c].data[1]).attr("r", 2).attr("fill", "red"); - lakesNow --; + lakesNow--; fs[lake].border = ocean; cells[c].height = 0.19; cells[c].fn = ocean; cells[c].ctype = -1; - cells[c].neighbors.forEach(function(e) {if (cells[e].height >= 0.2) cells[e].ctype = 2;}); + cells[c].neighbors.forEach(function (e) { if (cells[e].height >= 0.2) cells[e].ctype = 2; }); } } if (lakesInit === lakesNow) return; // nothing was changed - for (let i=0; i < cells.length; i++) { + for (let i = 0; i < cells.length; i++) { if (cells[i].height >= 0.2) continue; // not water const fn = cells[i].fn; if (fs[fn].border !== features[fn].border) { @@ -1191,37 +1194,37 @@ function fantasyMap() { let limits = []; let odd = 0.8; // initial odd for ocean layer is 80% // Define type of ocean cells based on cell distance form land - let frontier = $.grep(cells, function(e) {return e.ctype === -1;}); - if (Math.random() < odd) {limits.push(-1); odd = 0.2;} + let frontier = $.grep(cells, function (e) { return e.ctype === -1; }); + if (Math.random() < odd) { limits.push(-1); odd = 0.2; } for (let c = -2; frontier.length > 0 && c > -10; c--) { - if (Math.random() < odd) {limits.unshift(c); odd = 0.2;} else {odd += 0.2;} - frontier.map(function(i) { - i.neighbors.forEach(function(e) { + if (Math.random() < odd) { limits.unshift(c); odd = 0.2; } else { odd += 0.2; } + frontier.map(function (i) { + i.neighbors.forEach(function (e) { if (!cells[e].ctype) cells[e].ctype = c; }); }); - frontier = $.grep(cells, function(e) {return e.ctype === c;}); + frontier = $.grep(cells, function (e) { return e.ctype === c; }); } if (outlineLayersInput.value === "none") return; if (outlineLayersInput.value !== "random") limits = outlineLayersInput.value.split(","); // Define area edges const opacity = rn(0.4 / limits.length, 2); - for (let l=0; l < limits.length; l++) { + for (let l = 0; l < limits.length; l++) { const edges = []; const lim = +limits[l]; for (let i = 0; i < cells.length; i++) { if (cells[i].ctype < lim || cells[i].ctype === undefined) continue; if (cells[i].ctype > lim && cells[i].type !== "border") continue; const cell = diagram.cells[i]; - cell.halfedges.forEach(function(e) { + cell.halfedges.forEach(function (e) { const edge = diagram.edges[e]; const start = edge[0].join(" "); const end = edge[1].join(" "); if (edge.left && edge.right) { const ea = edge.left.index === i ? edge.right.index : edge.left.index; - if (cells[ea].ctype < lim) edges.push({start, end}); + if (cells[ea].ctype < lim) edges.push({ start, end }); } else { - edges.push({start, end}); + edges.push({ start, end }); } }); } @@ -1241,7 +1244,7 @@ function fantasyMap() { // get average precipitation based on graph size const avPrec = precInput.value / 5000; const evaporation = 2; - cells.map(function(i) { + cells.map(function (i) { let height = Math.trunc(i.height * 100) / 100; const ctype = i.ctype; if (ctype !== -1 && ctype !== -2 && height < 0.2) return; // exclude all depp ocean points @@ -1257,48 +1260,48 @@ function fantasyMap() { if (height < 0) height = 0; const region = i.region; // handle value for edit heightmap mode only const culture = i.culture; // handle value for edit heightmap mode only - let copy = $.grep(newPoints, function(e) {return (e[0] == x && e[1] == y);}); + let copy = $.grep(newPoints, function (e) { return (e[0] == x && e[1] == y); }); if (!copy.length) { newPoints.push([x, y]); - tempCells.push({index:tempCells.length, data:[x, y], height, ctype, fn, harbor, lake, region, culture}); + tempCells.push({ index: tempCells.length, data: [x, y], height, ctype, fn, harbor, lake, region, culture }); } // add additional points for cells along coast if (ctype === 2 || ctype === -1) { if (i.type === "border") return; if (!features[fn].land && !features[fn].border) return; - i.neighbors.forEach(function(e) { + i.neighbors.forEach(function (e) { if (cells[e].ctype === ctype) { let x1 = (x * 2 + cells[e].data[0]) / 3; let y1 = (y * 2 + cells[e].data[1]) / 3; x1 = rn(x1, 1), y1 = rn(y1, 1); - copy = $.grep(newPoints, function(e) {return e[0] === x1 && e[1] === y1;}); + copy = $.grep(newPoints, function (e) { return e[0] === x1 && e[1] === y1; }); if (copy.length) return; newPoints.push([x1, y1]); - tempCells.push({index:tempCells.length, data:[x1, y1], height, ctype, fn, harbor, lake, region, culture}); + tempCells.push({ index: tempCells.length, data: [x1, y1], height, ctype, fn, harbor, lake, region, culture }); }; }); } if (lake === 2) { // add potential small lakes //debug.append("circle").attr("r", 0.3).attr("cx", x).attr("cy", y).attr("fill", "blue"); height = Math.trunc(height * 100 + 1) / 100; - polygons[i.index].forEach(function(e) { + polygons[i.index].forEach(function (e) { if (Math.random() > 0.8) return; let rnd = Math.random() * 0.6 + 0.8; const x1 = rn((e[0] * rnd + i.data[0]) / (1 + rnd), 2); rnd = Math.random() * 0.6 + 0.8; const y1 = rn((e[1] * rnd + i.data[1]) / (1 + rnd), 2); - copy = $.grep(newPoints, function(c) {return x1 === c[0] && y1 === c[1];}); + copy = $.grep(newPoints, function (c) { return x1 === c[0] && y1 === c[1]; }); if (copy.length) return; //debug.append("circle").attr("r", 0.2).attr("cx", x1).attr("cy", y1).attr("fill", "red"); newPoints.push([x1, y1]); - tempCells.push({index:tempCells.length, data:[x1, y1], height, ctype, fn, region, culture}); + tempCells.push({ index: tempCells.length, data: [x1, y1], height, ctype, fn, region, culture }); }); } }); cells = tempCells; // use tempCells as the only cells array calculateVoronoi(newPoints); // recalculate Voronoi diagram using new points let gridPath = ""; // store grid as huge single path string - cells.map(function(i, d) { + cells.map(function (i, d) { if (i.height >= 0.2) { // calc cell area i.area = rn(Math.abs(d3.polygonArea(polygons[d])), 2); @@ -1306,7 +1309,7 @@ function fantasyMap() { i.flux = i.lake ? prec * 10 : prec; } const neighbors = []; // re-detect neighbors - diagram.cells[d].halfedges.forEach(function(e) { + diagram.cells[d].halfedges.forEach(function (e) { const edge = diagram.edges[e]; if (edge.left === undefined || edge.right === undefined) { if (i.height >= 0.2) i.ctype = 99; // border cell @@ -1332,10 +1335,10 @@ function fantasyMap() { let landCells = 0; $("#landmass").empty(); const limit = renderOcean.checked ? -1 : 0.2; - cells.map(function(i) { + cells.map(function (i) { if (i.height < limit) return; const clr = color(1 - i.height); - landmass.append("path").attr("id", "cell"+i.index) + landmass.append("path").attr("id", "cell" + i.index) .attr("d", "M" + polygons[i.index].join("L") + "Z") .attr("fill", clr).attr("stroke", clr); }); @@ -1345,18 +1348,18 @@ function fantasyMap() { // draw or update all cells function updateHeightmap() { - cells.map(function(c) { + cells.map(function (c) { let height = c.height; if (height > 1) height = 1; if (height < 0) height = 0; c.height = height; - let cell = landmass.select("#cell"+c.index); + let cell = landmass.select("#cell" + c.index); const clr = color(1 - height); if (cell.size()) { - if (height < 0.2) {cell.remove();} - else {cell.attr("fill", clr).attr("stroke", clr);} + if (height < 0.2) { cell.remove(); } + else { cell.attr("fill", clr).attr("stroke", clr); } } else if (height >= 0.2) { - cell = landmass.append("path").attr("id", "cell"+c.index) + cell = landmass.append("path").attr("id", "cell" + c.index) .attr("d", "M" + polygons[c.index].join("L") + "Z") .attr("fill", clr).attr("stroke", clr); } @@ -1365,19 +1368,19 @@ function fantasyMap() { // draw or update cells from the selection function updateHeightmapSelection(selection) { - if (selection === undefined) {selection = cells;} - selection.map(function(s) { + if (selection === undefined) { selection = cells; } + selection.map(function (s) { let height = cells[s].height; - if (height > 1) {height = 1;} - if (height < 0) {height = 0;} + if (height > 1) { height = 1; } + if (height < 0) { height = 0; } cells[s].height = height; - let cell = landmass.select("#cell"+s); + let cell = landmass.select("#cell" + s); const clr = color(1 - height); if (cell.size()) { - if (height < 0.2) {cell.remove();} - else {cell.attr("fill", clr).attr("stroke", clr);} + if (height < 0.2) { cell.remove(); } + else { cell.attr("fill", clr).attr("stroke", clr); } } else if (height >= 0.2) { - cell = landmass.append("path").attr("id", "cell"+s) + cell = landmass.append("path").attr("id", "cell" + s) .attr("d", "M" + polygons[s].join("L") + "Z") .attr("fill", clr).attr("stroke", clr); } @@ -1387,9 +1390,9 @@ function fantasyMap() { function updateHistory() { let heights = []; let landCells = 0; - cells.map(function(c) { + cells.map(function (c) { heights.push(c.height); - if (c.height >= 0.2) {landCells++;} + if (c.height >= 0.2) { landCells++; } }); history = history.slice(0, historyStage); history[historyStage] = heights; @@ -1399,10 +1402,10 @@ function fantasyMap() { var elevationAverage = rn(d3.mean(heights), 2); var landRatio = rn(landCells / cells.length * 100); landmassCounter.innerHTML = landCells + " (" + landRatio + "%); Average Elevation: " + elevationAverage; - if (landCells > 100) {$("#getMap").attr("disabled", false).removeClass("buttonoff").addClass("glow");} - else {$("#getMap").attr("disabled", true).addClass("buttonoff").removeClass("glow");} + if (landCells > 100) { $("#getMap").attr("disabled", false).removeClass("buttonoff").addClass("glow"); } + else { $("#getMap").attr("disabled", true).addClass("buttonoff").removeClass("glow"); } // if perspective is displayed, update it - if ($("#perspectivePanel").is(":visible")) {drawPerspective();} + if ($("#perspectivePanel").is(":visible")) { drawPerspective(); } } // restoreHistory @@ -1411,8 +1414,8 @@ function fantasyMap() { redo.disabled = templateRedo.disabled = historyStage < history.length ? false : true; undo.disabled = templateUndo.disabled = historyStage > 1 ? false : true; let heights = history[historyStage - 1]; - if (heights === undefined) {return;} - cells.map(function(i, d) {i.height = heights[d];}); + if (heights === undefined) { return; } + cells.map(function (i, d) { i.height = heights[d]; }); updateHeightmap(); } @@ -1433,71 +1436,71 @@ function fantasyMap() { let minX = graphWidth, maxX = 0; // extreme points let minXedge, maxXedge; // extreme edges const oceanEdges = [], lakeEdges = []; - for (let i=0; i < land.length; i++) { + for (let i = 0; i < land.length; i++) { const id = land[i].index, cell = diagram.cells[id]; const f = land[i].fn; land[i].height = Math.trunc(land[i].height * 100) / 100; - if (!oceanEdges[f]) {oceanEdges[f] = []; lakeEdges[f] = [];} - cell.halfedges.forEach(function(e) { - const edge = diagram.edges[e]; - const start = edge[0].join(" "); - const end = edge[1].join(" "); - if (edge.left && edge.right) { - const ea = edge.left.index === id ? edge.right.index : edge.left.index; + if (!oceanEdges[f]) { oceanEdges[f] = []; lakeEdges[f] = []; } + cell.halfedges.forEach(function (e) { + const edge = diagram.edges[e]; + const start = edge[0].join(" "); + const end = edge[1].join(" "); + if (edge.left && edge.right) { + const ea = edge.left.index === id ? edge.right.index : edge.left.index; cells[ea].height = Math.trunc(cells[ea].height * 100) / 100; - if (cells[ea].height < 0.2) { + if (cells[ea].height < 0.2) { cells[ea].ctype = -1; if (land[i].ctype !== 1) { land[i].ctype = 1; // mark coastal land cells - // move cell point closer to coast - const x = (land[i].data[0] + cells[ea].data[0]) / 2; - const y = (land[i].data[1] + cells[ea].data[1]) / 2; - land[i].haven = ea; // harbor haven (oposite water cell) - land[i].coastX = x, land[i].coastY = y; - land[i].data[0] = rn(x + (land[i].data[0] - x) * 0.5, 1); - land[i].data[1] = rn(y + (land[i].data[1] - y) * 0.5, 1); + // move cell point closer to coast + const x = (land[i].data[0] + cells[ea].data[0]) / 2; + const y = (land[i].data[1] + cells[ea].data[1]) / 2; + land[i].haven = ea; // harbor haven (oposite water cell) + land[i].coastX = x, land[i].coastY = y; + land[i].data[0] = rn(x + (land[i].data[0] - x) * 0.5, 1); + land[i].data[1] = rn(y + (land[i].data[1] - y) * 0.5, 1); } - if (features[cells[ea].fn].border) { - //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "blue").attr("stroke-width", .2); - oceanEdges[f].push({start, end}); - // island extreme points - if (edge[0][0] < minX) {minX = edge[0][0]; minXedge = edge[0]} - if (edge[1][0] < minX) {minX = edge[1][0]; minXedge = edge[1]} - if (edge[0][0] > maxX) {maxX = edge[0][0]; maxXedge = edge[0]} - if (edge[1][0] > maxX) {maxX = edge[1][0]; maxXedge = edge[1]} - } else { + if (features[cells[ea].fn].border) { + //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "blue").attr("stroke-width", .2); + oceanEdges[f].push({ start, end }); + // island extreme points + if (edge[0][0] < minX) { minX = edge[0][0]; minXedge = edge[0] } + if (edge[1][0] < minX) { minX = edge[1][0]; minXedge = edge[1] } + if (edge[0][0] > maxX) { maxX = edge[0][0]; maxXedge = edge[0] } + if (edge[1][0] > maxX) { maxX = edge[1][0]; maxXedge = edge[1] } + } else { const l = cells[ea].fn; if (!lakeEdges[f][l]) lakeEdges[f][l] = []; - lakeEdges[f][l].push({start, end}); - //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "red").attr("stroke-width", .2); - } - } - } else { - oceanEdges[f].push({start, end}); - //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "black").attr("stroke-width", .5); - } - }); + lakeEdges[f][l].push({ start, end }); + //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "red").attr("stroke-width", .2); + } + } + } else { + oceanEdges[f].push({ start, end }); + //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "black").attr("stroke-width", .5); + } + }); } for (let f = 0; f < features.length; f++) { - if (!oceanEdges[f]) continue; + if (!oceanEdges[f]) continue; if (!oceanEdges[f].length && lakeEdges[f].length) { const m = lakeEdges[f].indexOf(d3.max(lakeEdges[f])); oceanEdges[f] = lakeEdges[f][m]; lakeEdges[f][m] = []; } lineGen.curve(d3.curveCatmullRomClosed.alpha(0.1)); - const oceanCoastline = getContinuousLine(oceanEdges[f], 3, 0); + const oceanCoastline = getContinuousLine(oceanEdges[f], 3, 0); if (oceanCoastline) { shape.append("path").attr("d", oceanCoastline).attr("fill", "white"); // draw the mask coastline.append("path").attr("d", oceanCoastline); // draw the coastline } lineGen.curve(d3.curveBasisClosed); - lakeEdges[f].forEach(function(l) { + lakeEdges[f].forEach(function (l) { const lakeCoastline = getContinuousLine(l, 3, 0); if (lakeCoastline) { shape.append("path").attr("d", lakeCoastline).attr("fill", "black"); // draw the mask - lakes.append("path").attr("d", lakeCoastline); // draw the lakes + lakes.append("path").attr("d", lakeCoastline); // draw the lakes } }); } @@ -1517,19 +1520,19 @@ function fantasyMap() { var scaleBar = svg.append("g").attr("id", "scaleBar").on("click", editScale).call(d3.drag().on("start", elementDrag)); const init = 100; // actual length in pixels if scale, dScale and size = 1; let val = init * size * dScale / scale; // bar length in distance unit - if (val > 900) {val = rn(val, -3);} // round to 1000 - else if (val > 90) {val = rn(val, -2);} // round to 100 - else if (val > 9) {val = rn(val, -1);} // round to 10 - else {val = rn(val)} // round to 1 + if (val > 900) { val = rn(val, -3); } // round to 1000 + else if (val > 90) { val = rn(val, -2); } // round to 100 + else if (val > 9) { val = rn(val, -1); } // round to 10 + else { val = rn(val) } // round to 1 const l = val * scale / dScale; // actual length in pixels on this scale const x = 0, y = 0; // initial position - scaleBar.append("line").attr("x1", x+0.5).attr("y1", y).attr("x2", x+l+size-0.5).attr("y2", y).attr("stroke-width", size).attr("stroke", "white"); - scaleBar.append("line").attr("x1", x).attr("y1", y + size).attr("x2", x+l+size).attr("y2", y + size).attr("stroke-width", size).attr("stroke", "#3d3d3d"); + scaleBar.append("line").attr("x1", x + 0.5).attr("y1", y).attr("x2", x + l + size - 0.5).attr("y2", y).attr("stroke-width", size).attr("stroke", "white"); + scaleBar.append("line").attr("x1", x).attr("y1", y + size).attr("x2", x + l + size).attr("y2", y + size).attr("stroke-width", size).attr("stroke", "#3d3d3d"); const dash = size + " " + rn(l / 5 - size, 2); - scaleBar.append("line").attr("x1", x).attr("y1", y).attr("x2", x+l+size).attr("y2", y) + scaleBar.append("line").attr("x1", x).attr("y1", y).attr("x2", x + l + size).attr("y2", y) .attr("stroke-width", rn(size * 3, 2)).attr("stroke-dasharray", dash).attr("stroke", "#3d3d3d"); // big scale - for (var b = 0; b < 6; b++) { + for (let b = 0; b < 6; b++) { var value = rn(b * l / 5, 2); var label = rn(value * dScale / scale); if (b === 5) { @@ -1539,7 +1542,7 @@ function fantasyMap() { } } if (barLabel.value !== "") { - scaleBar.append("text").attr("x", x + (l+1) / 2).attr("y", y + 2 * size) + scaleBar.append("text").attr("x", x + (l + 1) / 2).attr("y", y + 2 * size) .attr("dominant-baseline", "text-before-edge") .attr("font-size", rn(5 * size, 1)).text(barLabel.value); } @@ -1564,7 +1567,7 @@ function fantasyMap() { const x0 = rn((x1 + x2) / 2, 2), y0 = rn((y1 + y2) / 2, 2); rulerNew.append("circle").attr("r", 1.2).attr("cx", x0).attr("cy", y0).attr("stroke-width", 0.3).attr("class", "center").call(d3.drag().on("start", rulerCenterDrag)); const angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI; - const tr = "rotate(" + angle + " " + x0 + " " + y0 +")"; + const tr = "rotate(" + angle + " " + x0 + " " + y0 + ")"; const dist = rn(Math.hypot(x1 - x2, y1 - y2)); const label = rn(dist * distanceScale.value) + " " + distanceUnit.value; rulerNew.append("text").attr("x", x0).attr("y", y0).attr("dy", -1).attr("transform", tr).attr("data-dist", dist).text(label).on("click", removeParent).attr("font-size", 10); @@ -1577,13 +1580,13 @@ function fantasyMap() { const x = d3.event.x, y = d3.event.y; const dx = +tr[0] - x, dy = +tr[1] - y; - d3.event.on("drag", function() { + d3.event.on("drag", function () { const x = d3.event.x, y = d3.event.y; - const transform = `translate(${(dx+x)},${(dy+y)})`; + const transform = `translate(${(dx + x)},${(dy + y)})`; el.attr("transform", transform); }); - d3.event.on("end", function() { + d3.event.on("end", function () { // remember scaleBar bottom-right position if (el.attr("id") === "scaleBar") { const xEnd = d3.event.x, yEnd = d3.event.y; @@ -1616,7 +1619,7 @@ function fantasyMap() { var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; var atan = x0 > x ? Math.atan2(y0 - y, x0 - x) : Math.atan2(y - y0, x - x0); var angle = rn(atan * 180 / Math.PI, 3); - var tr = "rotate(" + angle + " " + xc + " " + yc +")"; + var tr = "rotate(" + angle + " " + xc + " " + yc + ")"; group.select("text").attr("x", xc).attr("y", yc).attr("transform", tr).attr("data-dist", dist).text(label); } @@ -1635,7 +1638,7 @@ function fantasyMap() { rulerNew.append("line").attr("class", "gray").attr("stroke-dasharray", dash).attr("stroke-width", factor); rulerNew.append("text").attr("dy", -1).on("click", removeParent).attr("font-size", 10 * factor).attr("stroke-width", factor); - d3.event.on("drag", function() { + d3.event.on("drag", function () { x = d3.event.x, y = d3.event.y; d3.select(this).attr("cx", x).attr("cy", y); // change first part @@ -1644,19 +1647,19 @@ function fantasyMap() { var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; var atan = x1 > x ? Math.atan2(y1 - y, x1 - x) : Math.atan2(y - y1, x - x1); xc1 = rn((x + x1) / 2, 2), yc1 = rn((y + y1) / 2, 2); - var tr = "rotate(" + rn(atan * 180 / Math.PI, 3) + " " + xc1 + " " + yc1 +")"; + var tr = "rotate(" + rn(atan * 180 / Math.PI, 3) + " " + xc1 + " " + yc1 + ")"; group.select("text").attr("x", xc1).attr("y", yc1).attr("transform", tr).attr("data-dist", dist).text(label); // change second (new) part dist = rn(Math.hypot(x2 - x, y2 - y)); label = rn(dist * distanceScale.value) + " " + distanceUnit.value; atan = x2 > x ? Math.atan2(y2 - y, x2 - x) : Math.atan2(y - y2, x - x2); xc2 = rn((x + x2) / 2, 2), yc2 = rn((y + y2) / 2, 2); - tr = "rotate(" + rn(atan * 180 / Math.PI, 3) + " " + xc2 + " " + yc2 +")"; + tr = "rotate(" + rn(atan * 180 / Math.PI, 3) + " " + xc2 + " " + yc2 + ")"; rulerNew.selectAll("line").attr("x1", x).attr("y1", y).attr("x2", x2).attr("y2", y2); rulerNew.select("text").attr("x", xc2).attr("y", yc2).attr("transform", tr).attr("data-dist", dist).text(label); }); - d3.event.on("end", function() { + d3.event.on("end", function () { // circles for 1st part group.selectAll("circle").remove(); group.append("circle").attr("cx", x1).attr("cy", y1).attr("r", 2 * factor).attr("stroke-width", 0.5 * factor).attr("data-edge", "left").call(d3.drag().on("drag", rulerEdgeDrag)); @@ -1677,14 +1680,14 @@ function fantasyMap() { var curveGray = group.select(".gray"); var text = group.select("text"); var points = JSON.parse(text.attr("data-points")); - if (x0 === points[0].scX && y0 === points[0].scY) {points.reverse();} + if (x0 === points[0].scX && y0 === points[0].scY) { points.reverse(); } - d3.event.on("drag", function() { + d3.event.on("drag", function () { var x = d3.event.x, y = d3.event.y; el.attr("cx", x).attr("cy", y); var l = points[points.length - 1]; var diff = Math.hypot(l.scX - x, l.scY - y); - if (diff > 5) {points.push({scX: x, scY: y});} else {return;} + if (diff > 5) { points.push({ scX: x, scY: y }); } else { return; } lineGen.curve(d3.curveBasis); var d = round(lineGen(points)); curve.attr("d", d); @@ -1694,14 +1697,14 @@ function fantasyMap() { text.attr("x", x).attr("y", y).text(label); }); - d3.event.on("end", function() { + d3.event.on("end", function () { var dist = rn(curve.node().getTotalLength()); var c = curve.node().getPointAtLength(dist / 2); var p = curve.node().getPointAtLength((dist / 2) - 1); var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; var atan = p.x > c.x ? Math.atan2(p.y - c.y, p.x - c.x) : Math.atan2(c.y - p.y, c.x - p.x); var angle = rn(atan * 180 / Math.PI, 3); - var tr = "rotate(" + angle + " " + c.x + " " + c.y +")"; + var tr = "rotate(" + angle + " " + c.x + " " + c.y + ")"; text.attr("data-points", JSON.stringify(points)).attr("data-dist", dist).attr("x", c.x).attr("y", c.y).attr("transform", tr).text(label); }); } @@ -1715,9 +1718,9 @@ function fantasyMap() { let end = edges[0].end; edges.shift(); let spl = start.split(" "); - edgesOrdered.push({scX: +spl[0], scY: +spl[1]}); + edgesOrdered.push({ scX: +spl[0], scY: +spl[1] }); spl = end.split(" "); - edgesOrdered.push({scX: +spl[0], scY: +spl[1]}); + edgesOrdered.push({ scX: +spl[0], scY: +spl[1] }); let x0 = +spl[0], y0 = +spl[1]; for (let i = 0; end !== start && i < 100000; i++) { let next = null, index = null; @@ -1738,14 +1741,14 @@ function fantasyMap() { if (indention || relax) { const dist = Math.hypot(+spl[0] - x0, +spl[1] - y0); if (dist >= indention && Math.random() > relax) { - edgesOrdered.push({scX: +spl[0], scY: +spl[1]}); + edgesOrdered.push({ scX: +spl[0], scY: +spl[1] }); x0 = +spl[0], y0 = +spl[1]; } } else { - edgesOrdered.push({scX: +spl[0], scY: +spl[1]}); + edgesOrdered.push({ scX: +spl[0], scY: +spl[1] }); } edges.splice(index, 1); - if (i === 100000-1) { + if (i === 100000 - 1) { console.error("Line not ended, limit reached"); break; } @@ -1758,11 +1761,11 @@ function fantasyMap() { // temporary elevate lakes to min neighbors heights to correctly flux the water function elevateLakes() { console.time('elevateLakes'); - const lakes = $.grep(cells, function(e) {return e.height < 0.2 && !features[e.fn].border;}); - lakes.sort(function(a, b) {return b.height - a.height;}); - for (let i=0; i < lakes.length; i++) { + const lakes = $.grep(cells, function (e) { return e.height < 0.2 && !features[e.fn].border; }); + lakes.sort(function (a, b) { return b.height - a.height; }); + for (let i = 0; i < lakes.length; i++) { const heights = []; - lakes[i].neighbors.forEach(function(n) {if (cells[n].height >= 0.2) heights.push(cells[n].height)}); + lakes[i].neighbors.forEach(function (n) { if (cells[n].height >= 0.2) heights.push(cells[n].height) }); if (heights.length) lakes[i].height = Math.trunc((d3.min(heights) - 0.01) * 100) / 100; if (cells[i].height < 0.2) lakes[i].height = 0.2; lakes[i].lake = 1; @@ -1773,14 +1776,14 @@ function fantasyMap() { // Depression filling algorithm (for a correct water flux modeling; phase1) function resolveDepressionsPrimary() { console.time('resolveDepressionsPrimary'); - land = $.grep(cells, function(e) {return e.height >= 0.2;}); - land.sort(function(a, b) {return b.height - a.height;}); + land = $.grep(cells, function (e) { return e.height >= 0.2; }); + land.sort(function (a, b) { return b.height - a.height; }); const limit = 10; for (let l = 0, depression = 1; depression > 0 && l < limit; l++) { depression = 0; for (let i = 0; i < land.length; i++) { if (land[i].type === "border") continue; - const heights = land[i].neighbors.map(function(n) {return cells[n].height}); + const heights = land[i].neighbors.map(function (n) { return cells[n].height }); const minHigh = d3.min(heights); if (land[i].height <= minHigh) { depression++; @@ -1796,14 +1799,14 @@ function fantasyMap() { // Depression filling algorithm (for a correct water flux modeling; phase2) function resolveDepressionsSecondary() { console.time('resolveDepressionsSecondary'); - land = $.grep(cells, function(e) {return e.height >= 0.2;}); - land.sort(function(a, b) {return b.height - a.height;}); + land = $.grep(cells, function (e) { return e.height >= 0.2; }); + land.sort(function (a, b) { return b.height - a.height; }); const limit = 100; for (let l = 0, depression = 1; depression > 0 && l < limit; l++) { depression = 0; for (let i = 0; i < land.length; i++) { if (land[i].ctype === 99) continue; - const heights = land[i].neighbors.map(function(n) {return cells[n].height}); + const heights = land[i].neighbors.map(function (n) { return cells[n].height }); const minHigh = d3.min(heights); if (land[i].height <= minHigh) { depression++; @@ -1818,14 +1821,14 @@ function fantasyMap() { } function restoreCustomHeights() { - land.forEach(function(l) {if (l.pit) rn(l.height -= l.pit / 50, 2);}); + land.forEach(function (l) { if (l.pit) rn(l.height -= l.pit / 50, 2); }); } function flux() { console.time('flux'); riversData = []; let riverNext = 0; - land.sort(function(a, b) {return b.height - a.height;}); + land.sort(function (a, b) { return b.height - a.height; }); for (let i = 0; i < land.length; i++) { const id = land[i].index; const sx = land[i].data[0]; @@ -1835,11 +1838,11 @@ function fantasyMap() { if (land[i].river !== undefined) { let x, y; const min = Math.min(sy, graphHeight - sy, sx, graphWidth - sx); - if (min === sy) {x = sx; y = 0;} - if (min === graphHeight - sy) {x = sx; y = graphHeight;} - if (min === sx) {x = 0; y = sy;} - if (min === graphWidth - sx) {x = graphWidth; y = sy;} - riversData.push({river: land[i].river, cell: id, x, y}); + if (min === sy) { x = sx; y = 0; } + if (min === graphHeight - sy) { x = sx; y = graphHeight; } + if (min === sx) { x = 0; y = sy; } + if (min === graphWidth - sx) { x = graphWidth; y = sy; } + riversData.push({ river: land[i].river, cell: id, x, y }); } continue; } @@ -1850,7 +1853,7 @@ function fantasyMap() { } } let minHeight = 10, min; - land[i].neighbors.forEach(function(e) { + land[i].neighbors.forEach(function (e) { if (cells[e].height < minHeight) { minHeight = cells[e].height; min = e; @@ -1861,7 +1864,7 @@ function fantasyMap() { if (land[i].river === undefined) { // State new River land[i].river = riverNext; - riversData.push({river: riverNext, cell: id, x: sx, y: sy}); + riversData.push({ river: riverNext, cell: id, x: sx, y: sy }); riverNext += 1; } // Assing existing River to the downhill cell @@ -1869,8 +1872,8 @@ function fantasyMap() { cells[min].river = land[i].river; } else { var riverTo = cells[min].river; - var iRiver = $.grep(riversData, function(e) {return (e.river == land[i].river);}); - var minRiver = $.grep(riversData, function(e) {return (e.river == riverTo);}); + var iRiver = $.grep(riversData, function (e) { return (e.river == land[i].river); }); + var minRiver = $.grep(riversData, function (e) { return (e.river == riverTo); }); var iRiverL = iRiver.length; var minRiverL = minRiver.length; // re-assing river nunber if new part is greater @@ -1882,9 +1885,9 @@ function fantasyMap() { // mark confluences if (cells[min].height >= 0.2 && iRiverL > 1 && minRiverL > 1) { if (!cells[min].confluence) { - cells[min].confluence = minRiverL-1; + cells[min].confluence = minRiverL - 1; } else { - cells[min].confluence += minRiverL-1; + cells[min].confluence += minRiverL - 1; } } } @@ -1897,14 +1900,14 @@ function fantasyMap() { // pour water to the sea const x = (px + sx) / 2 + (px - sx) / 10; const y = (py + sy) / 2 + (py - sy) / 10; - riversData.push({river: land[i].river, cell: id, x, y}); + riversData.push({ river: land[i].river, cell: id, x, y }); } else { if (cells[min].lake === 1) { fn = cells[min].fn; if (features[fn].river === undefined) features[fn].river = land[i].river; } // add next River segment - riversData.push({river: land[i].river, cell: min, x: px, y: py}); + riversData.push({ river: land[i].river, cell: min, x: px, y: py }); } } } @@ -1914,14 +1917,14 @@ function fantasyMap() { function drawRiverLines(riverNext) { console.time('drawRiverLines'); - for (var i = 0; i < riverNext; i++) { - var dataRiver = $.grep(riversData, function(e) {return e.river === i;}); + for (let i = 0; i < riverNext; i++) { + var dataRiver = $.grep(riversData, function (e) { return e.river === i; }); if (dataRiver.length > 1) { var riverAmended = amendRiver(dataRiver, 1); var width = rn(0.8 + Math.random() * 0.4, 1); var increment = rn(0.8 + Math.random() * 0.4, 1); var d = drawRiver(riverAmended, width, increment); - rivers.append("path").attr("d", d).attr("id", "river"+i).attr("data-width", width).attr("data-increment", increment); + rivers.append("path").attr("d", d).attr("id", "river" + i).attr("data-width", width).attr("data-increment", increment); } } rivers.selectAll("path").on("click", editRiver); @@ -1931,19 +1934,19 @@ function fantasyMap() { // add more river points on 1/3 and 2/3 of length function amendRiver(dataRiver, rndFactor) { var riverAmended = [], side = 1; - for (var r = 0; r < dataRiver.length; r++) { + for (let r = 0; r < dataRiver.length; r++) { var dX = dataRiver[r].x; var dY = dataRiver[r].y; var cell = dataRiver[r].cell; var c = cells[cell].confluence || 0; riverAmended.push([dX, dY, c]); - if (r+1 < dataRiver.length) { - var eX = dataRiver[r+1].x; - var eY = dataRiver[r+1].y; + if (r + 1 < dataRiver.length) { + var eX = dataRiver[r + 1].x; + var eY = dataRiver[r + 1].y; var angle = Math.atan2(eY - dY, eX - dX); - var serpentine = 1 / (r+1); + var serpentine = 1 / (r + 1); var meandr = serpentine + 0.3 + Math.random() * 0.3 * rndFactor; - if (Math.random() > 0.5) {side *= -1}; + if (Math.random() > 0.5) { side *= -1 }; var dist = Math.hypot(eX - dX, eY - dY); // if dist is big or river is small add 2 extra points if (dist > 8 || (dist > 4 && dataRiver.length < 6)) { @@ -1953,11 +1956,11 @@ function fantasyMap() { var enY = (dY + eY * 2) / 3; stX += -Math.sin(angle) * meandr * side; stY += Math.cos(angle) * meandr * side; - if (Math.random() > 0.8) {side *= -1}; + if (Math.random() > 0.8) { side *= -1 }; enX += Math.sin(angle) * meandr * side; enY += -Math.cos(angle) * meandr * side; riverAmended.push([stX, stY], [enX, enY]); - // if dist is medium or river is small add 1 extra point + // if dist is medium or river is small add 1 extra point } else if (dist > 4 || dataRiver.length < 6) { var scX = (dX + eX) / 2; var scY = (dY + eY) / 2; @@ -1972,108 +1975,108 @@ function fantasyMap() { // draw river polygon using arrpoximation function drawRiver(points, width, increment) { - lineGen.curve(d3.curveCatmullRom.alpha(0.1)); - var extraOffset = 0.03; // start offset to make river source visible - width = width || 1; // river width modifier - increment = increment || 1; // river bed widening modifier - var riverLength = 0; - points.map(function(p, i) { - if (i === 0) {return 0;} - riverLength += Math.hypot(p[0] - points[i-1][0], p[1] - points[i-1][1]); - }); - var widening = rn((1000 + (riverLength * 30)) * increment); - var riverPointsLeft = [], riverPointsRight = []; - var last = points.length - 1; - var factor = riverLength / points.length; + lineGen.curve(d3.curveCatmullRom.alpha(0.1)); + var extraOffset = 0.03; // start offset to make river source visible + width = width || 1; // river width modifier + increment = increment || 1; // river bed widening modifier + var riverLength = 0; + points.map(function (p, i) { + if (i === 0) { return 0; } + riverLength += Math.hypot(p[0] - points[i - 1][0], p[1] - points[i - 1][1]); + }); + var widening = rn((1000 + (riverLength * 30)) * increment); + var riverPointsLeft = [], riverPointsRight = []; + var last = points.length - 1; + var factor = riverLength / points.length; - // first point - var x = points[0][0], y = points[0][1], c; - var angle = Math.atan2(y - points[1][1], x - points[1][0]); - var xLeft = x + -Math.sin(angle) * extraOffset, yLeft = y + Math.cos(angle) * extraOffset; - riverPointsLeft.push({scX:xLeft, scY:yLeft}); - var xRight = x + Math.sin(angle) * extraOffset, yRight = y + -Math.cos(angle) * extraOffset; - riverPointsRight.unshift({scX:xRight, scY:yRight}); + // first point + var x = points[0][0], y = points[0][1], c; + var angle = Math.atan2(y - points[1][1], x - points[1][0]); + var xLeft = x + -Math.sin(angle) * extraOffset, yLeft = y + Math.cos(angle) * extraOffset; + riverPointsLeft.push({ scX: xLeft, scY: yLeft }); + var xRight = x + Math.sin(angle) * extraOffset, yRight = y + -Math.cos(angle) * extraOffset; + riverPointsRight.unshift({ scX: xRight, scY: yRight }); - // middle points - for (var p = 1; p < last; p ++) { - x = points[p][0], y = points[p][1], c = points[p][2]; - if (c) {extraOffset += Math.atan(c * 10 / widening);} // confluence - var xPrev = points[p-1][0], yPrev = points[p-1][1]; - var xNext = points[p+1][0], yNext = points[p+1][1]; - angle = Math.atan2(yPrev - yNext, xPrev - xNext); - var offset = (Math.atan(Math.pow(p * factor, 2) / widening) / 2 * width) + extraOffset; - xLeft = x + -Math.sin(angle) * offset, yLeft = y + Math.cos(angle) * offset; - riverPointsLeft.push({scX:xLeft, scY:yLeft}); - xRight = x + Math.sin(angle) * offset, yRight = y + -Math.cos(angle) * offset; - riverPointsRight.unshift({scX:xRight, scY:yRight}); - } - - // end point - x = points[last][0], y = points[last][1], c = points[last][2]; - if (c) {extraOffset += Math.atan(c * 10 / widening);} // confluence - angle = Math.atan2(points[last-1][1] - y, points[last-1][0] - x); + // middle points + for (let p = 1; p < last; p++) { + x = points[p][0], y = points[p][1], c = points[p][2]; + if (c) { extraOffset += Math.atan(c * 10 / widening); } // confluence + var xPrev = points[p - 1][0], yPrev = points[p - 1][1]; + var xNext = points[p + 1][0], yNext = points[p + 1][1]; + angle = Math.atan2(yPrev - yNext, xPrev - xNext); + var offset = (Math.atan(Math.pow(p * factor, 2) / widening) / 2 * width) + extraOffset; xLeft = x + -Math.sin(angle) * offset, yLeft = y + Math.cos(angle) * offset; - riverPointsLeft.push({scX:xLeft, scY:yLeft}); + riverPointsLeft.push({ scX: xLeft, scY: yLeft }); xRight = x + Math.sin(angle) * offset, yRight = y + -Math.cos(angle) * offset; - riverPointsRight.unshift({scX:xRight, scY:yRight}); + riverPointsRight.unshift({ scX: xRight, scY: yRight }); + } - // generate path and return - var right = lineGen(riverPointsRight); - var left = lineGen(riverPointsLeft); - left = left.substring(left.indexOf("C")); - return round(right + left, 2); + // end point + x = points[last][0], y = points[last][1], c = points[last][2]; + if (c) { extraOffset += Math.atan(c * 10 / widening); } // confluence + angle = Math.atan2(points[last - 1][1] - y, points[last - 1][0] - x); + xLeft = x + -Math.sin(angle) * offset, yLeft = y + Math.cos(angle) * offset; + riverPointsLeft.push({ scX: xLeft, scY: yLeft }); + xRight = x + Math.sin(angle) * offset, yRight = y + -Math.cos(angle) * offset; + riverPointsRight.unshift({ scX: xRight, scY: yRight }); + + // generate path and return + var right = lineGen(riverPointsRight); + var left = lineGen(riverPointsLeft); + left = left.substring(left.indexOf("C")); + return round(right + left, 2); } // draw river polygon with best quality function drawRiverSlow(points, width, increment) { - lineGen.curve(d3.curveCatmullRom.alpha(0.1)); - width = width || 1; - var extraOffset = 0.02 * width; - increment = increment || 1; - var riverPoints = points.map(function(p) {return {scX: p[0], scY: p[1]};}); - var river = defs.append("path").attr("d", lineGen(riverPoints)); - var riverLength = river.node().getTotalLength(); - var widening = rn((1000 + (riverLength * 30)) * increment); - var riverPointsLeft = [], riverPointsRight = []; + lineGen.curve(d3.curveCatmullRom.alpha(0.1)); + width = width || 1; + var extraOffset = 0.02 * width; + increment = increment || 1; + var riverPoints = points.map(function (p) { return { scX: p[0], scY: p[1] }; }); + var river = defs.append("path").attr("d", lineGen(riverPoints)); + var riverLength = river.node().getTotalLength(); + var widening = rn((1000 + (riverLength * 30)) * increment); + var riverPointsLeft = [], riverPointsRight = []; - for (let l = 0; l < riverLength; l++) { - var point = river.node().getPointAtLength(l); - var from = river.node().getPointAtLength(l - 0.1); - var to = river.node().getPointAtLength(l + 0.1); - var angle = Math.atan2(from.y - to.y, from.x - to.x); - var offset = (Math.atan(Math.pow(l, 2) / widening) / 2 * width) + extraOffset; - var xLeft = point.x + -Math.sin(angle) * offset; - var yLeft = point.y + Math.cos(angle) * offset; - riverPointsLeft.push({scX:xLeft, scY:yLeft}); - var xRight = point.x + Math.sin(angle) * offset; - var yRight = point.y + -Math.cos(angle) * offset; - riverPointsRight.unshift({scX:xRight, scY:yRight}); - } - - var point = river.node().getPointAtLength(riverLength); - var from = river.node().getPointAtLength(riverLength - 0.1); - var angle = Math.atan2(from.y - point.y, from.x - point.x); - var offset = (Math.atan(Math.pow(riverLength, 2) / widening) / 2 * width) + extraOffset; + for (let l = 0; l < riverLength; l++) { + var point = river.node().getPointAtLength(l); + var from = river.node().getPointAtLength(l - 0.1); + var to = river.node().getPointAtLength(l + 0.1); + var angle = Math.atan2(from.y - to.y, from.x - to.x); + var offset = (Math.atan(Math.pow(l, 2) / widening) / 2 * width) + extraOffset; var xLeft = point.x + -Math.sin(angle) * offset; var yLeft = point.y + Math.cos(angle) * offset; - riverPointsLeft.push({scX:xLeft, scY:yLeft}); + riverPointsLeft.push({ scX: xLeft, scY: yLeft }); var xRight = point.x + Math.sin(angle) * offset; var yRight = point.y + -Math.cos(angle) * offset; - riverPointsRight.unshift({scX:xRight, scY:yRight}); + riverPointsRight.unshift({ scX: xRight, scY: yRight }); + } - river.remove(); - // generate path and return - var right = lineGen(riverPointsRight); - var left = lineGen(riverPointsLeft); - left = left.substring(left.indexOf("C")); - return round(right + left, 2); + var point = river.node().getPointAtLength(riverLength); + var from = river.node().getPointAtLength(riverLength - 0.1); + var angle = Math.atan2(from.y - point.y, from.x - point.x); + var offset = (Math.atan(Math.pow(riverLength, 2) / widening) / 2 * width) + extraOffset; + var xLeft = point.x + -Math.sin(angle) * offset; + var yLeft = point.y + Math.cos(angle) * offset; + riverPointsLeft.push({ scX: xLeft, scY: yLeft }); + var xRight = point.x + Math.sin(angle) * offset; + var yRight = point.y + -Math.cos(angle) * offset; + riverPointsRight.unshift({ scX: xRight, scY: yRight }); + + river.remove(); + // generate path and return + var right = lineGen(riverPointsRight); + var left = lineGen(riverPointsLeft); + left = left.substring(left.indexOf("C")); + return round(right + left, 2); } // add lakes on depressed points on river course function addLakes() { console.time('addLakes'); let smallLakes = 0; - for (let i=0; i < land.length; i++) { + for (let i = 0; i < land.length; i++) { // elavate all big lakes if (land[i].lake === 1) { land[i].height = 0.19; @@ -2088,7 +2091,7 @@ function fantasyMap() { smallLakes++; } else { land[i].lake = undefined; - land[i].neighbors.forEach(function(n) { + land[i].neighbors.forEach(function (n) { if (cells[n].lake !== 1 && cells[n].river !== undefined) { cells[n].lake = 2; cells[n].height = 0.19; @@ -2104,7 +2107,7 @@ function fantasyMap() { } // mark small lakes - let unmarked = $.grep(land, function(e) {return e.fn === -1}); + let unmarked = $.grep(land, function (e) { return e.fn === -1 }); while (unmarked.length) { let fn = -1, queue = [unmarked[0].index], lakeCells = []; unmarked[0].session = "addLakes"; @@ -2112,7 +2115,7 @@ function fantasyMap() { const q = queue.pop(); lakeCells.push(q); if (cells[q].fn !== -1) fn = cells[q].fn; - cells[q].neighbors.forEach(function(e) { + cells[q].neighbors.forEach(function (e) { if (cells[e].lake && cells[e].session !== "addLakes") { cells[e].session = "addLakes"; queue.push(e); @@ -2121,18 +2124,18 @@ function fantasyMap() { } if (fn === -1) { fn = features.length; - features.push({i: fn, land: false, border: false}); + features.push({ i: fn, land: false, border: false }); } - lakeCells.forEach(function(c) {cells[c].fn = fn;}); - unmarked = $.grep(land, function(e) {return e.fn === -1}); + lakeCells.forEach(function (c) { cells[c].fn = fn; }); + unmarked = $.grep(land, function (e) { return e.fn === -1 }); } - land = $.grep(cells, function(e) {return e.height >= 0.2;}); + land = $.grep(cells, function (e) { return e.height >= 0.2; }); console.timeEnd('addLakes'); } function editRiver() { - if (customization) {return;} + if (customization) { return; } if (elSelected) { const self = d3.select(this).attr("id") === elSelected.attr("id"); const point = d3.mouse(this); @@ -2161,9 +2164,9 @@ function fantasyMap() { $("#riverEditor").dialog({ title: "Edit River", minHeight: 30, width: "auto", resizable: false, - position: {my: "center top+20", at: "top", of: d3.event}, - close: function() { - if ($("#riverNew").hasClass('pressed')) {completeNewRiver();} + position: { my: "center top+20", at: "top", of: d3.event }, + close: function () { + if ($("#riverNew").hasClass('pressed')) { completeNewRiver(); } unselect(); } }); @@ -2172,28 +2175,28 @@ function fantasyMap() { .attr("transform", elSelected.attr("transform")); riverDrawPoints(); - if (modules.editRiver) {return;} + if (modules.editRiver) { return; } modules.editRiver = true; function riverAddControlPoint(point) { let dists = []; - debug.select(".controlPoints").selectAll("circle").each(function() { + debug.select(".controlPoints").selectAll("circle").each(function () { const x = +d3.select(this).attr("cx"); const y = +d3.select(this).attr("cy"); dists.push(Math.hypot(point[0] - x, point[1] - y)); }); let index = dists.length; if (dists.length > 1) { - const sorted = dists.slice(0).sort(function(a, b) {return a-b;}); + const sorted = dists.slice(0).sort(function (a, b) { return a - b; }); const closest = dists.indexOf(sorted[0]); const next = dists.indexOf(sorted[1]); - if (closest <= next) {index = closest+1;} else {index = next+1;} + if (closest <= next) { index = closest + 1; } else { index = next + 1; } } const before = ":nth-child(" + (index + 1) + ")"; debug.select(".controlPoints").insert("circle", before) .attr("cx", point[0]).attr("cy", point[1]).attr("r", 0.35) .call(d3.drag().on("drag", riverPointDrag)) - .on("click", function(d) { + .on("click", function (d) { $(this).remove(); redrawRiver(); }); @@ -2206,9 +2209,9 @@ function fantasyMap() { const l = node.getTotalLength() / 2; const parts = (l / 5) >> 0; // number of points let inc = l / parts; // increment - if (inc === Infinity) {inc = l;} // 2 control points for short rivers + if (inc === Infinity) { inc = l; } // 2 control points for short rivers // draw control points - for (var i = l, c = l; i > 0; i -= inc, c += inc) { + for (let i = l, c = l; i > 0; i -= inc, c += inc) { const p1 = node.getPointAtLength(i); const p2 = node.getPointAtLength(c); const p = [(p1.x + p2.x) / 2, (p1.y + p2.y) / 2]; @@ -2225,7 +2228,7 @@ function fantasyMap() { debug.select(".controlPoints").append("circle") .attr("cx", point[0]).attr("cy", point[1]).attr("r", 0.35) .call(d3.drag().on("drag", riverPointDrag)) - .on("click", function(d) { + .on("click", function (d) { $(this).remove(); redrawRiver(); }); @@ -2239,9 +2242,9 @@ function fantasyMap() { function riverDrag() { const x = d3.event.x, y = d3.event.y; const tr = parseTransform(elSelected.attr("transform")); - d3.event.on("drag", function() { + d3.event.on("drag", function () { let xc = d3.event.x, yc = d3.event.y; - let transform = `translate(${(+tr[0]+xc-x)},${(+tr[1]+yc-y)}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; + let transform = `translate(${(+tr[0] + xc - x)},${(+tr[1] + yc - y)}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; elSelected.attr("transform", transform); debug.select(".controlPoints").attr("transform", transform); }); @@ -2249,7 +2252,7 @@ function fantasyMap() { function redrawRiver() { let points = []; - debug.select(".controlPoints").selectAll("circle").each(function() { + debug.select(".controlPoints").selectAll("circle").each(function () { const el = d3.select(this); points.push([+el.attr("cx"), +el.attr("cy")]); }); @@ -2259,21 +2262,21 @@ function fantasyMap() { elSelected.attr("d", d); } - $("#riverWidthInput, #riverIncrement").change(function() { + $("#riverWidthInput, #riverIncrement").change(function () { const width = +riverWidthInput.value; const increment = +riverIncrement.value; elSelected.attr("data-width", width).attr("data-increment", increment); redrawRiver(); }); - $("#riverRegenerate").click(function() { + $("#riverRegenerate").click(function () { let points = [], amended = [], x, y, p1, p2; const node = elSelected.node(); const l = node.getTotalLength() / 2; const parts = (l / 8) >> 0; // number of points let inc = l / parts; // increment - if (inc === Infinity) {inc = l;} // 2 control points for short rivers - for (var i = l, e = l; i > 0; i -= inc, e += inc) { + if (inc === Infinity) { inc = l; } // 2 control points for short rivers + for (let i = l, e = l; i > 0; i -= inc, e += inc) { p1 = node.getPointAtLength(i); p2 = node.getPointAtLength(e); x = (p1.x + p2.x) / 2, y = (p1.y + p2.y) / 2; @@ -2286,15 +2289,15 @@ function fantasyMap() { points.push([x, y]); // amend points const rndFactor = 0.3 + Math.random() * 1.4; // random factor in range 0.2-1.8 - for (var i = 0; i < points.length; i++) { + for (let i = 0; i < points.length; i++) { x = points[i][0], y = points[i][1]; amended.push([x, y]); // add additional semi-random point if (i + 1 < points.length) { - const x2 = points[i+1][0], y2 = points[i+1][1]; + const x2 = points[i + 1][0], y2 = points[i + 1][1]; let side = Math.random() > 0.5 ? 1 : -1; const angle = Math.atan2(y2 - y, x2 - x); - const serpentine = 2 / (i+1); + const serpentine = 2 / (i + 1); const meandr = serpentine + 0.3 + Math.random() * rndFactor; x = (x + x2) / 2, y = (y + y2) / 2; x += -Math.sin(angle) * meandr * side; @@ -2310,20 +2313,20 @@ function fantasyMap() { const d = drawRiverSlow(amended, width, increment); elSelected.attr("d", d).attr("data-width", width).attr("data-increment", increment); debug.select(".controlPoints").selectAll("*").remove(); - amended.map(function(p) {addRiverPoint(p);}); + amended.map(function (p) { addRiverPoint(p); }); }); - $("#riverAngle").change(function() { + $("#riverAngle").change(function () { const tr = parseTransform(elSelected.attr("transform")); riverAngleValue.innerHTML = Math.abs(+this.value) + "°"; var c = elSelected.node().getBBox(); const angle = +this.value, scale = +tr[5]; - const transform = `translate(${tr[0]},${tr[1]}) rotate(${angle} ${(c.x+c.width/2)*scale} ${(c.y+c.height/2)*scale}) scale(${scale})`; + const transform = `translate(${tr[0]},${tr[1]}) rotate(${angle} ${(c.x + c.width / 2) * scale} ${(c.y + c.height / 2) * scale}) scale(${scale})`; elSelected.attr("transform", transform); debug.select(".controlPoints").attr("transform", transform); }); - $("#riverReset").click(function() { + $("#riverReset").click(function () { elSelected.attr("transform", ""); debug.select(".controlPoints").attr("transform", ""); riverAngle.value = 0; @@ -2331,21 +2334,21 @@ function fantasyMap() { riverScale.value = 1; }); - $("#riverScale").change(function() { + $("#riverScale").change(function () { const tr = parseTransform(elSelected.attr("transform")); const scaleOld = +tr[5], scale = +this.value; var c = elSelected.node().getBBox(); const cx = c.x + c.width / 2, cy = c.y + c.height / 2; const trX = +tr[0] + cx * (scaleOld - scale); const trY = +tr[1] + cy * (scaleOld - scale); - const scX = +tr[3] * scale/scaleOld; - const scY = +tr[4] * scale/scaleOld; + const scX = +tr[3] * scale / scaleOld; + const scY = +tr[4] * scale / scaleOld; const transform = `translate(${trX},${trY}) rotate(${tr[2]} ${scX} ${scY}) scale(${scale})`; elSelected.attr("transform", transform); debug.select(".controlPoints").attr("transform", transform); }); - $("#riverNew").click(function() { + $("#riverNew").click(function () { if ($(this).hasClass('pressed')) { completeNewRiver(); } else { @@ -2363,7 +2366,7 @@ function fantasyMap() { addRiverPoint([point[0], point[1]]); if (elSelected.attr("data-river") !== "new") { const id = +$("#rivers > path").last().attr("id").slice(5) + 1; - elSelected = rivers.append("path").attr("data-river", "new").attr("id", "river"+id) + elSelected = rivers.append("path").attr("data-river", "new").attr("id", "river" + id) .attr("data-width", 2).attr("data-increment", 1).on("click", completeNewRiver); } else { redrawRiver(); @@ -2378,43 +2381,44 @@ function fantasyMap() { elSelected.attr("data-river", ""); elSelected.call(d3.drag().on("start", riverDrag)).on("click", editRiver); const river = +elSelected.attr("id").slice(5); - debug.select(".controlPoints").selectAll("circle").each(function() { + debug.select(".controlPoints").selectAll("circle").each(function () { const x = +d3.select(this).attr("cx"); const y = +d3.select(this).attr("cy"); const cell = diagram.find(x, y, 3); - if (!cell) {return;} - if (cells[cell.index].river === undefined) {cells[cell.index].river = r;} + if (!cell) { return; } + if (cells[cell.index].river === undefined) { cells[cell.index].river = r; } }); } } - $("#riverCopy").click(function() { + $("#riverCopy").click(function () { const tr = parseTransform(elSelected.attr("transform")); const d = elSelected.attr("d"); let x = 2, y = 2; - let transform = `translate(${tr[0]-x},${tr[1]-y}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; + let transform = `translate(${tr[0] - x},${tr[1] - y}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; while (rivers.selectAll("[transform='" + transform + "'][d='" + d + "']").size() > 0) { x += 2; y += 2; - transform = `translate(${tr[0]-x},${tr[1]-y}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; + transform = `translate(${tr[0] - x},${tr[1] - y}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; } const river = +$("#rivers > path").last().attr("id").slice(5) + 1; rivers.append("path").attr("d", d) .attr("transform", transform) - .attr("id", "river"+river).on("click", editRiver) + .attr("id", "river" + river).on("click", editRiver) .attr("data-width", elSelected.attr("data-width")) .attr("data-increment", elSelected.attr("data-increment")); unselect(); }); - $("#riverRemove").click(function() { + $("#riverRemove").click(function () { alertMessage.innerHTML = `Are you sure you want to remove the river?`; - $("#alert").dialog({resizable: false, title: "Remove river", + $("#alert").dialog({ + resizable: false, title: "Remove river", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); const river = +elSelected.attr("id").slice(5); const avPrec = rn(precInput.value / Math.sqrt(cells.length), 2); - land.map(function(l) { + land.map(function (l) { if (l.river === river) { l.river = undefined; i.flux = avPrec; @@ -2424,7 +2428,7 @@ function fantasyMap() { unselect(); $("#riverEditor").dialog("close"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }) }); @@ -2442,18 +2446,18 @@ function fantasyMap() { function parseTransform(string) { // [translateX,translateY,rotateDeg,rotateX,rotateY,scale] - if (!string) {return [0,0,0,0,0,1];} - var a = string.replace(/[a-z()]/g,"").replace(/[ ]/g,",").split(","); + if (!string) { return [0, 0, 0, 0, 0, 1]; } + var 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]; } function editRoute() { - if (customization) {return;} + if (customization) { return; } if (elSelected) { const self = d3.select(this).attr("id") === elSelected.attr("id"); const point = d3.mouse(this); if (elSelected.attr("data-route") === "new") { - addRoutePoint({x:point[0], y:point[1]}); + addRoutePoint({ x: point[0], y: point[1] }); completeNewRoute(); return; } else if (self) { @@ -2477,8 +2481,8 @@ function fantasyMap() { $("#routeEditor").dialog({ title: "Edit Route", minHeight: 30, width: "auto", resizable: false, - position: {my: "center top+20", at: "top", of: d3.event}, - close: function() { + position: { my: "center top+20", at: "top", of: d3.event }, + close: function () { if ($("#addRoute").hasClass('pressed')) completeNewRoute(); if ($("#routeSplit").hasClass('pressed')) $("#routeSplit").removeClass('pressed'); unselect(); @@ -2486,28 +2490,28 @@ function fantasyMap() { }); } - if (modules.editRoute) {return;} + if (modules.editRoute) { return; } modules.editRoute = true; function routeAddControlPoint(point) { let dists = []; - debug.select(".controlPoints").selectAll("circle").each(function() { + debug.select(".controlPoints").selectAll("circle").each(function () { const x = +d3.select(this).attr("cx"); const y = +d3.select(this).attr("cy"); dists.push(Math.hypot(point[0] - x, point[1] - y)); }); let index = dists.length; if (dists.length > 1) { - const sorted = dists.slice(0).sort(function(a, b) {return a-b;}); + const sorted = dists.slice(0).sort(function (a, b) { return a - b; }); const closest = dists.indexOf(sorted[0]); const next = dists.indexOf(sorted[1]); - if (closest <= next) {index = closest+1;} else {index = next+1;} + if (closest <= next) { index = closest + 1; } else { index = next + 1; } } const before = ":nth-child(" + (index + 1) + ")"; debug.select(".controlPoints").insert("circle", before) .attr("cx", point[0]).attr("cy", point[1]).attr("r", 0.35) .call(d3.drag().on("drag", routePointDrag)) - .on("click", function(d) { + .on("click", function (d) { $(this).remove(); routeRedraw(); }); @@ -2519,9 +2523,9 @@ function fantasyMap() { const l = node.getTotalLength(); const parts = (l / 5) >> 0; // number of points let inc = l / parts; // increment - if (inc === Infinity) {inc = l;} // 2 control points for short routes + if (inc === Infinity) { inc = l; } // 2 control points for short routes // draw control points - for (var i = 0; i <= l; i += inc) { + for (let i = 0; i <= l; i += inc) { const p = node.getPointAtLength(i); addRoutePoint(p); } @@ -2536,7 +2540,7 @@ function fantasyMap() { controlPoints.append("circle") .attr("cx", point.x).attr("cy", point.y).attr("r", 0.35) .call(d3.drag().on("drag", routePointDrag)) - .on("click", function(d) { + .on("click", function (d) { if ($("#routeSplit").hasClass('pressed')) { routeSplitInPoint(this); } else { @@ -2553,9 +2557,9 @@ function fantasyMap() { function routeRedraw() { let points = []; - debug.select(".controlPoints").selectAll("circle").each(function() { + debug.select(".controlPoints").selectAll("circle").each(function () { var el = d3.select(this); - points.push({scX: +el.attr("cx"), scY: +el.attr("cy")}); + points.push({ scX: +el.attr("cx"), scY: +el.attr("cy") }); }); lineGen.curve(d3.curveCatmullRom.alpha(0.1)); elSelected.attr("d", lineGen(points)); @@ -2574,8 +2578,8 @@ function fantasyMap() { if (height < 0.2) routeType = "searoutes"; if (routeType === "searoutes" && height >= 0.2) routeType = "roads"; } - const group = routes.select("#"+routeType); - addRoutePoint({x, y}); + const group = routes.select("#" + routeType); + addRoutePoint({ x, y }); if (!elSelected || elSelected.attr("data-route") !== "new") { const id = routeType + "" + group.selectAll("*").size(); elSelected = group.append("path").attr("data-route", "new").attr("id", id).on("click", editRoute); @@ -2584,8 +2588,8 @@ function fantasyMap() { $("#routeEditor").dialog({ title: "Edit Route", minHeight: 30, width: "auto", resizable: false, - position: {my: "center top+20", at: "top", of: d3.event}, - close: function() { + position: { my: "center top+20", at: "top", of: d3.event }, + close: function () { if ($("#addRoute").hasClass('pressed')) completeNewRoute(); if ($("#routeSplit").hasClass('pressed')) $("#routeSplit").removeClass('pressed'); unselect(); @@ -2606,16 +2610,16 @@ function fantasyMap() { const node = elSelected.node(); const l = node.getTotalLength(); let pathCells = []; - for (var i = 0; i <= l; i ++) { + for (let i = 0; i <= l; i++) { const p = node.getPointAtLength(i); const cell = diagram.find(p.x, p.y); - if (!cell) {return;} + if (!cell) { return; } pathCells.push(cell.index); } const uniqueCells = [...new Set(pathCells)]; - uniqueCells.map(function(c) { - if (cells[c].path !== undefined) {cells[c].path += 1;} - else {cells[c].path = 1;} + uniqueCells.map(function (c) { + if (cells[c].path !== undefined) { cells[c].path += 1; } + else { cells[c].path = 1; } }); } tip("", true); @@ -2625,9 +2629,9 @@ function fantasyMap() { const group = d3.select(elSelected.node().parentNode); const type = group.attr("data-type"); routeGroup.innerHTML = ""; - routes.selectAll("g").each(function(d) { + routes.selectAll("g").each(function (d) { const el = d3.select(this); - if (el.attr("data-type") !== type) {return;} + if (el.attr("data-type") !== type) { return; } const opt = document.createElement("option"); opt.value = opt.innerHTML = el.attr("id"); routeGroup.add(opt); @@ -2639,12 +2643,12 @@ function fantasyMap() { $("#routeSplit").removeClass('pressed'); const points1 = [], points2 = []; let points = points1; - debug.select(".controlPoints").selectAll("circle").each(function() { + debug.select(".controlPoints").selectAll("circle").each(function () { const el = d3.select(this); - points.push({scX: +el.attr("cx"), scY: +el.attr("cy")}); + points.push({ scX: +el.attr("cx"), scY: +el.attr("cy") }); if (this === clicked) { points = points2; - points.push({scX: +el.attr("cx"), scY: +el.attr("cy")}); + points.push({ scX: +el.attr("cx"), scY: +el.attr("cy") }); } el.remove(); }); @@ -2655,11 +2659,11 @@ function fantasyMap() { routeDrawPoints(); } - $("#routeGroup").change(function() { - $(elSelected.node()).detach().appendTo($("#"+this.value)); + $("#routeGroup").change(function () { + $(elSelected.node()).detach().appendTo($("#" + this.value)); }); - $("#routeNew").click(function() { + $("#routeNew").click(function () { if ($(this).hasClass('pressed')) { completeNewRoute(); } else { @@ -2672,16 +2676,17 @@ function fantasyMap() { } }); - $("#routeRemove").click(function() { + $("#routeRemove").click(function () { alertMessage.innerHTML = `Are you sure you want to remove the route?`; - $("#alert").dialog({resizable: false, title: "Remove route", + $("#alert").dialog({ + resizable: false, title: "Remove route", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); elSelected.remove(); $("#routeEditor").dialog("close"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }) }); @@ -2707,14 +2712,14 @@ function fantasyMap() { $("#iconEditor").dialog({ title: "Edit icon: " + group.attr("id"), minHeight: 30, width: "auto", resizable: false, - position: {my: "center top+20", at: "top", of: d3.event}, + position: { my: "center top+20", at: "top", of: d3.event }, close: unselect }); - if (modules.editIcon) {return;} + if (modules.editIcon) { return; } modules.editIcon = true; - $("#iconGroups").click(function() { + $("#iconGroups").click(function () { $("#iconEditor > button").not(this).toggle(); $("#iconGroupsSelection").toggle(); }); @@ -2722,7 +2727,7 @@ function fantasyMap() { function iconUpdateGroups() { iconGroup.innerHTML = ""; const anchor = group.attr("id").includes("anchor"); - icons.selectAll("g").each(function(d) { + icons.selectAll("g").each(function (d) { const id = d3.select(this).attr("id"); if (id === "burgs") return; if (!anchor && id.includes("anchor")) return; @@ -2733,28 +2738,28 @@ function fantasyMap() { }); } - $("#iconGroup").change(function() { + $("#iconGroup").change(function () { const newGroup = this.value; - const to = $("#icons > #"+newGroup); + const to = $("#icons > #" + newGroup); $(elSelected.node()).detach().appendTo(to); }); - $("#iconCopy").click(function() { + $("#iconCopy").click(function () { const group = d3.select(elSelected.node().parentNode); const copy = elSelected.node().cloneNode(); copy.removeAttribute("data-id"); // remove assignment to burg if any const tr = parseTransform(copy.getAttribute("transform")); const shift = 10 / Math.sqrt(scale); - let transform = "translate(" + rn(tr[0] - shift, 1) + "," + rn(tr[1] - shift, 1) + ")"; - for (let i=2; group.selectAll("[transform='" + transform + "']").size() > 0; i++) { - transform = "translate(" + rn(tr[0] - shift * i, 1) + "," + rn(tr[1] - shift * i, 1) + ")"; + let transform = "translate(" + rn(tr[0] - shift, 1) + "," + rn(tr[1] - shift, 1) + ")"; + for (let i = 2; group.selectAll("[transform='" + transform + "']").size() > 0; i++) { + transform = "translate(" + rn(tr[0] - shift * i, 1) + "," + rn(tr[1] - shift * i, 1) + ")"; } copy.setAttribute("transform", transform); group.node().insertBefore(copy, null); copy.addEventListener("click", editIcon); }); - $("#iconRemoveGroup").click(function() { + $("#iconRemoveGroup").click(function () { const group = d3.select(elSelected.node().parentNode); const count = group.selectAll("*").size(); if (count < 2) { @@ -2764,60 +2769,62 @@ function fantasyMap() { } const message = "Are you sure you want to remove all '" + iconGroup.value + "' icons (" + count + ")?"; alertMessage.innerHTML = message; - $("#alert").dialog({resizable: false, title: "Remove icon group", + $("#alert").dialog({ + resizable: false, title: "Remove icon group", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); group.remove(); $("#iconEditor").dialog("close"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }); }); - $("#iconColors").click(function() { + $("#iconColors").click(function () { $("#iconEditor > button").not(this).toggle(); $("#iconColorsSection").toggle(); }); - $("#iconFillColor").change(function() { + $("#iconFillColor").change(function () { const group = d3.select(elSelected.node().parentNode); group.attr("fill", this.value); }); - $("#iconStrokeColor").change(function() { + $("#iconStrokeColor").change(function () { const group = d3.select(elSelected.node().parentNode); group.attr("stroke", this.value); }); - $("#iconSetSize").click(function() { + $("#iconSetSize").click(function () { $("#iconEditor > button").not(this).toggle(); $("#iconSizeSection").toggle(); }); - $("#iconSize").change(function() { + $("#iconSize").change(function () { const group = d3.select(elSelected.node().parentNode); const size = +this.value group.attr("size", size); - group.selectAll("*").each(function() {d3.select(this).attr("width", size).attr("height", size)}); + group.selectAll("*").each(function () { d3.select(this).attr("width", size).attr("height", size) }); }); - $("#iconStrokeWidth").change(function() { + $("#iconStrokeWidth").change(function () { const group = d3.select(elSelected.node().parentNode); group.attr("stroke-width", this.value); }); - $("#iconRemove").click(function() { + $("#iconRemove").click(function () { alertMessage.innerHTML = `Are you sure you want to remove the icon?`; - $("#alert").dialog({resizable: false, title: "Remove icon", + $("#alert").dialog({ + resizable: false, title: "Remove icon", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); elSelected.remove(); $("#iconEditor").dialog("close"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }) }); @@ -2836,19 +2843,19 @@ function fantasyMap() { $("#reliefEditor").dialog({ title: "Edit relief icon", minHeight: 30, width: "auto", resizable: false, - position: {my: "center top+40", at: "top", of: d3.event}, + position: { my: "center top+40", at: "top", of: d3.event }, close: unselect }); - if (modules.editReliefIcon) {return;} + if (modules.editReliefIcon) { return; } modules.editReliefIcon = true; - $("#reliefGroups").click(function() { + $("#reliefGroups").click(function () { $("#reliefEditor > button").not(this).toggle(); $("#reliefGroupsSelection").toggle(); }); - $("#reliefGroup").change(function() { + $("#reliefGroup").change(function () { const type = this.value; const bbox = elSelected.node().getBBox(); const cx = bbox.x; @@ -2860,26 +2867,26 @@ function fantasyMap() { elSelected.call(d3.drag().on("start", elementDrag)); }); - $("#reliefCopy").click(function() { + $("#reliefCopy").click(function () { const group = d3.select(elSelected.node().parentNode); const copy = elSelected.node().cloneNode(true); const tr = parseTransform(copy.getAttribute("transform")); const shift = 10 / Math.sqrt(scale); - let transform = "translate(" + rn(tr[0] - shift, 1) + "," + rn(tr[1] - shift, 1) + ")"; - for (let i=2; group.selectAll("[transform='" + transform + "']").size() > 0; i++) { - transform = "translate(" + rn(tr[0] - shift * i, 1) + "," + rn(tr[1] - shift * i, 1) + ")"; + let transform = "translate(" + rn(tr[0] - shift, 1) + "," + rn(tr[1] - shift, 1) + ")"; + for (let i = 2; group.selectAll("[transform='" + transform + "']").size() > 0; i++) { + transform = "translate(" + rn(tr[0] - shift * i, 1) + "," + rn(tr[1] - shift * i, 1) + ")"; } copy.setAttribute("transform", transform); group.node().insertBefore(copy, null); copy.addEventListener("click", editReliefIcon); }); - $("#reliefAddfromEditor").click(function() { + $("#reliefAddfromEditor").click(function () { clickToAdd(); // to load on click event function $("#addRelief").click(); }); - $("#reliefRemoveGroup").click(function() { + $("#reliefRemoveGroup").click(function () { const group = d3.select(elSelected.node().parentNode); const count = group.selectAll("*").size(); if (count < 2) { @@ -2889,38 +2896,40 @@ function fantasyMap() { } const message = "Are you sure you want to remove all '" + reliefGroup.value + "' icons (" + count + ")?"; alertMessage.innerHTML = message; - $("#alert").dialog({resizable: false, title: "Remove all icons within group", + $("#alert").dialog({ + resizable: false, title: "Remove all icons within group", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); group.selectAll("*").remove(); $("#reliefEditor").dialog("close"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }); }); - $("#reliefRemove").click(function() { + $("#reliefRemove").click(function () { alertMessage.innerHTML = `Are you sure you want to remove the icon?`; - $("#alert").dialog({resizable: false, title: "Remove relief icon", + $("#alert").dialog({ + resizable: false, title: "Remove relief icon", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); elSelected.remove(); $("#reliefEditor").dialog("close"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }) }); } function editBurg() { - if (customization) {return;} + if (customization) { return; } if (elSelected) { const self = d3.select(this).attr("data-id") === elSelected.attr("data-id"); - if (self) {return;} + if (self) { return; } } closeDialogs("#burgEditor, .stable"); @@ -2931,8 +2940,8 @@ function fantasyMap() { // update Burg details const type = elSelected.node().parentNode.id; - const labelGroup = burgLabels.select("#"+type); - const iconGroup = burgIcons.select("#"+type); + const labelGroup = burgLabels.select("#" + type); + const iconGroup = burgIcons.select("#" + type); burgNameInput.value = manors[id].name; updateBurgsGroupOptions(); burgSelectGroup.value = labelGroup.attr("id"); @@ -2966,8 +2975,8 @@ function fantasyMap() { $("#burgEditor").dialog({ title: "Edit Burg: " + manors[id].name, minHeight: 30, width: "auto", resizable: false, - position: {my: "center top+40", at: "top", of: d3.event}, - close: function() { + position: { my: "center top+40", at: "top", of: d3.event }, + close: function () { d3.selectAll("[data-id='" + id + "']").call(d3.drag().on("drag", null)).classed("draggable", false); elSelected = null; } @@ -2980,14 +2989,14 @@ function fantasyMap() { function updateBurgsGroupOptions() { burgSelectGroup.innerHTML = ""; - burgIcons.selectAll("g").each(function(d) { + burgIcons.selectAll("g").each(function (d) { var opt = document.createElement("option"); opt.value = opt.innerHTML = d3.select(this).attr("id"); burgSelectGroup.add(opt); }); } - $("#burgEditor > button").not("#burgAddfromEditor").not("#burgRemove").click(function() { + $("#burgEditor > button").not("#burgAddfromEditor").not("#burgRemove").click(function () { if ($(this).next().is(":visible")) { $("#burgEditor > button").show(); $(this).next("div").hide(); @@ -2997,7 +3006,7 @@ function fantasyMap() { } }); - $("#burgEditor > div > button").click(function() { + $("#burgEditor > div > button").click(function () { if ($(this).next().is(":visible")) { $("#burgEditor > div > button").show(); $(this).parent().prev().show(); @@ -3009,11 +3018,11 @@ function fantasyMap() { } }); - $("#burgSelectGroup").change(function() { + $("#burgSelectGroup").change(function () { const id = +elSelected.attr("data-id"); const g = this.value; - $("#burgIcons [data-id=" + id + "]").detach().appendTo($("#burgIcons > #"+g)); - $("#burgLabels [data-id=" + id + "]").detach().appendTo($("#burgLabels > #"+g)); + $("#burgIcons [data-id=" + id + "]").detach().appendTo($("#burgIcons > #" + g)); + $("#burgLabels [data-id=" + id + "]").detach().appendTo($("#burgLabels > #" + g)); // special case for port icons (anchors) if (g === "towns" || g === "capitals") { const el = $("#icons g[id*='anchors'] [data-id=" + id + "]"); @@ -3023,19 +3032,19 @@ function fantasyMap() { } }); - $("#burgInputGroup").change(function() { + $("#burgInputGroup").change(function () { const newGroup = this.value.toLowerCase().replace(/ /g, "_").replace(/[^\w\s]/gi, ""); if (Number.isFinite(+newGroup.charAt(0))) newGroup = "g" + newGroup; - if (burgLabels.select("#"+newGroup).size()) { - tip('The group "'+ newGroup + ' is already exists"'); + if (burgLabels.select("#" + newGroup).size()) { + tip('The group "' + newGroup + ' is already exists"'); return; } burgInputGroup.value = ""; // clone old group assigning new id const id = elSelected.node().parentNode.id; - const l = burgLabels.select("#"+id).node().cloneNode(false); + const l = burgLabels.select("#" + id).node().cloneNode(false); l.id = newGroup; - const i = burgIcons.select("#"+id).node().cloneNode(false); + const i = burgIcons.select("#" + id).node().cloneNode(false); i.id = newGroup; burgLabels.node().insertBefore(l, null); burgIcons.node().insertBefore(i, null); @@ -3047,7 +3056,7 @@ function fantasyMap() { $("#burgSelectGroup, #burgInputGroup").toggle(); }); - $("#burgAddGroup").click(function() { + $("#burgAddGroup").click(function () { if ($("#burgInputGroup").css("display") === "none") { $("#burgInputGroup").css("display", "inline-block"); $("#burgSelectGroup").css("display", "none"); @@ -3058,43 +3067,44 @@ function fantasyMap() { } }); - $("#burgRemoveGroup").click(function() { + $("#burgRemoveGroup").click(function () { const group = d3.select(elSelected.node().parentNode); const type = group.attr("id"); const id = +elSelected.attr("data-id"); var count = group.selectAll("*").size(); const message = "Are you sure you want to remove all Burgs (" + count + ") of that group?"; alertMessage.innerHTML = message; - $("#alert").dialog({resizable: false, title: "Remove Burgs", + $("#alert").dialog({ + resizable: false, title: "Remove Burgs", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); - group.selectAll("*").each(function(d) { + group.selectAll("*").each(function (d) { const id = +d3.select(this).attr("data-id"); if (id === undefined) return; const cell = manors[id].cell; const state = manors[id].region; if (states[state]) { if (states[state].capital === id) states[state].capital = "select"; - states[state].burgs --; + states[state].burgs--; } manors[id].region = "removed"; cells[cell].manor = undefined; }); - burgLabels.select("#"+type).selectAll("*").remove(); - burgIcons.select("#"+type).selectAll("*").remove(); + burgLabels.select("#" + type).selectAll("*").remove(); + burgIcons.select("#" + type).selectAll("*").remove(); $("#icons g[id*='anchors'] [data-id=" + id + "]").parent().children().remove(); closeDialogs(".stable"); updateCountryEditors(); $("#burgEditor").dialog("close"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }) return; }); - $("#burgNameInput").on("input", function() { + $("#burgNameInput").on("input", function () { if (this.value === "") { tip("Name should not be blank, set opacity to 0 to hide label or remove button to delete"); return; @@ -3105,7 +3115,7 @@ function fantasyMap() { $("div[aria-describedby='burgEditor'] .ui-dialog-title").text("Edit Burg: " + this.value); }); - $("#burgNameReCulture, #burgNameReRandom").click(function() { + $("#burgNameReCulture, #burgNameReRandom").click(function () { const id = +elSelected.attr("data-id"); const culture = this.id === "burgNameReCulture" ? manors[id].culture : Math.floor(Math.random() * cultures.length); const name = generateName(culture); @@ -3115,7 +3125,7 @@ function fantasyMap() { $("div[aria-describedby='burgEditor'] .ui-dialog-title").text("Edit Burg: " + name); }); - $("#burgToggleExternalFont").click(function() { + $("#burgToggleExternalFont").click(function () { if ($("#burgInputExternalFont").css("display") === "none") { $("#burgInputExternalFont").css("display", "inline-block"); $("#burgSelectDefaultFont").css("display", "none"); @@ -3126,15 +3136,15 @@ function fantasyMap() { } }); - $("#burgSelectDefaultFont").change(function() { + $("#burgSelectDefaultFont").change(function () { const type = elSelected.node().parentNode.id; - const group = burgLabels.select("#"+type); + const group = burgLabels.select("#" + type); if (burgSelectDefaultFont.value === "") return; const font = fonts[burgSelectDefaultFont.value].split(':')[0].replace(/\+/g, " "); group.attr("font-family", font).attr("data-font", fonts[burgSelectDefaultFont.value]); }); - $("#burgInputExternalFont").change(function() { + $("#burgInputExternalFont").change(function () { fetchFonts(this.value).then(fetched => { if (!fetched) return; burgToggleExternalFont.click(); @@ -3143,73 +3153,73 @@ function fantasyMap() { }); }); - $("#burgSetLabelSize").on("input", function() { + $("#burgSetLabelSize").on("input", function () { const type = elSelected.node().parentNode.id; - const group = burgLabels.select("#"+type); + const group = burgLabels.select("#" + type); group.attr("data-size", +this.value); invokeActiveZooming(); }); - $("#burgLabelColorInput").on("input", function() { + $("#burgLabelColorInput").on("input", function () { const type = elSelected.node().parentNode.id; - const group = burgLabels.select("#"+type); + const group = burgLabels.select("#" + type); group.attr("fill", this.value); }); - $("#burgLabelOpacity").on("input", function() { + $("#burgLabelOpacity").on("input", function () { const type = elSelected.node().parentNode.id; - const group = burgLabels.select("#"+type); + const group = burgLabels.select("#" + type); group.attr("opacity", +this.value); }); - $("#burgLabelAngle").on("input", function() { + $("#burgLabelAngle").on("input", function () { const id = +elSelected.attr("data-id"); - const el = burgLabels.select("[data-id='"+ id +"']"); + const el = burgLabels.select("[data-id='" + id + "']"); const c = el.node().getBBox(); - const rotate = `rotate(${this.value} ${(c.x+c.width/2)} ${(c.y+c.height/2)})`; + const rotate = `rotate(${this.value} ${(c.x + c.width / 2)} ${(c.y + c.height / 2)})`; el.attr("transform", rotate); burgLabelAngleOutput.innerHTML = Math.abs(+this.value) + "°"; }); - $("#burgIconSize").on("input", function() { + $("#burgIconSize").on("input", function () { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#"+type); + const group = burgIcons.select("#" + type); const size = +this.value group.attr("size", size); - group.selectAll("*").each(function() {d3.select(this).attr("r", size)}); + group.selectAll("*").each(function () { d3.select(this).attr("r", size) }); }); - $("#burgIconFillOpacity").on("input", function() { + $("#burgIconFillOpacity").on("input", function () { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#"+type); + const group = burgIcons.select("#" + type); group.attr("fill-opacity", +this.value); }); - $("#burgIconFillColor").on("input", function() { + $("#burgIconFillColor").on("input", function () { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#"+type); + const group = burgIcons.select("#" + type); group.attr("fill", this.value); }); - $("#burgIconStrokeWidth").on("input", function() { + $("#burgIconStrokeWidth").on("input", function () { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#"+type); + const group = burgIcons.select("#" + type); group.attr("stroke-width", +this.value); }); - $("#burgIconStrokeOpacity").on("input", function() { + $("#burgIconStrokeOpacity").on("input", function () { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#"+type); + const group = burgIcons.select("#" + type); group.attr("stroke-opacity", +this.value); }); - $("#burgIconStrokeColor").on("input", function() { + $("#burgIconStrokeColor").on("input", function () { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#"+type); + const group = burgIcons.select("#" + type); group.attr("stroke", this.value); }); - $("#burgToggleCapital").click(function() { + $("#burgToggleCapital").click(function () { const id = +elSelected.attr("data-id"); const state = manors[id].region; if (states[state] === undefined) return; @@ -3224,8 +3234,8 @@ function fantasyMap() { states[state].capital = capital ? id : "select"; d3.select("#burgToggleCapital").classed("pressed", capital); const g = capital ? "capitals" : "towns"; - $("#burgIcons [data-id=" + id + "]").detach().appendTo($("#burgIcons > #"+g)); - $("#burgLabels [data-id=" + id + "]").detach().appendTo($("#burgLabels > #"+g)); + $("#burgIcons [data-id=" + id + "]").detach().appendTo($("#burgIcons > #" + g)); + $("#burgLabels [data-id=" + id + "]").detach().appendTo($("#burgLabels > #" + g)); const el = $("#icons g[id*='anchors'] [data-id=" + id + "]"); updateCountryEditors(); if (!el.length) return; @@ -3233,7 +3243,7 @@ function fantasyMap() { el.detach().appendTo(to); }); - $("#burgTogglePort").click(function() { + $("#burgTogglePort").click(function () { const id = +elSelected.attr("data-id"); const cell = cells[manors[id].cell]; const markAsPort = cell.port === undefined ? true : undefined; @@ -3254,22 +3264,23 @@ function fantasyMap() { } }); - $("#burgPopulation").on("input", function() { + $("#burgPopulation").on("input", function () { const id = +elSelected.attr("data-id"); burgPopulationFriendly.value = rn(this.value * urbanization.value * populationRate.value * 1000); manors[id].population = +this.value; }); - $("#burgAddfromEditor").click(function() { + $("#burgAddfromEditor").click(function () { clickToAdd(); // to load on click event function $("#addBurg").click(); }); - $("#burgRemove").click(function() { + $("#burgRemove").click(function () { alertMessage.innerHTML = `Are you sure you want to remove the Burg?`; - $("#alert").dialog({resizable: false, title: "Remove Burg", + $("#alert").dialog({ + resizable: false, title: "Remove Burg", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); const id = +elSelected.attr("data-id"); d3.selectAll("[data-id='" + id + "']").remove(); @@ -3277,14 +3288,14 @@ function fantasyMap() { const state = manors[id].region; if (states[state]) { if (states[state].capital === id) states[state].capital = "select"; - states[state].burgs --; + states[state].burgs--; } manors[id].region = "removed"; cells[cell].manor = undefined; closeDialogs(".stable"); updateCountryEditors(); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }) }); @@ -3294,7 +3305,7 @@ function fantasyMap() { function generateCultures() { const count = +culturesInput.value; cultures = d3.shuffle(defaultCultures).slice(0, count); - const centers = d3.range(cultures.length).map(function(d, i) { + const centers = d3.range(cultures.length).map(function (d, i) { const x = Math.floor(Math.random() * graphWidth * 0.8 + graphWidth * 0.1); const y = Math.floor(Math.random() * graphHeight * 0.8 + graphHeight * 0.1); const center = [x, y]; @@ -3327,7 +3338,7 @@ function fantasyMap() { // Assess cells geographycal suitability for settlement function rankPlacesGeography() { console.time('rankPlacesGeography'); - land.map(function(c) { + land.map(function (c) { let score = 0; // truncate decimals to keep data clear c.height = Math.trunc(c.height * 100) / 100; @@ -3342,12 +3353,12 @@ function fantasyMap() { c.score = 0; // ignore 80% of extended cells } else { if (c.harbor) { - if (c.harbor === 1) {score += 1;} else {score -= 0.3;} // good sea harbor is valued + if (c.harbor === 1) { score += 1; } else { score -= 0.3; } // good sea harbor is valued } if (c.river && c.ctype === 1) score += 1; // estuary is valued if (c.flux > 1) score += Math.pow(c.flux, 0.3); // riverbank is valued if (c.confluence) score += Math.pow(c.confluence, 0.7); // confluence is valued; - const neighbEv = c.neighbors.map(function(n) {if (cells[n].height >= 0.2) return cells[n].height;}) + const neighbEv = c.neighbors.map(function (n) { if (cells[n].height >= 0.2) return cells[n].height; }) const difEv = c.height - d3.mean(neighbEv); if (!isNaN(difEv)) { score += difEv * 10 * (1 - c.height); // local height maximums are valued @@ -3356,14 +3367,14 @@ function fantasyMap() { } c.score = rn(Math.random() * score + score, 3); // add random factor }); - land.sort(function(a, b) {return b.score - a.score;}); + land.sort(function (a, b) { return b.score - a.score; }); console.timeEnd('rankPlacesGeography'); } // Assess the cells economical suitability for settlement function rankPlacesEconomy() { console.time('rankPlacesEconomy'); - land.map(function(c) { + land.map(function (c) { var score = c.score; var path = c.path || 0; // roads are valued if (path) { @@ -3373,32 +3384,32 @@ function fantasyMap() { } c.score = rn(Math.random() * score + score, 2); // add random factor }); - land.sort(function(a, b) {return b.score - a.score;}); + land.sort(function (a, b) { return b.score - a.score; }); console.timeEnd('rankPlacesEconomy'); } - // calculate population for manors, cells and states + // calculate population for manors, cells and states function calculatePopulation() { // neutral population factors < 1 as neutral lands are usually pretty wild const ruralFactor = 0.5, urbanFactor = 0.9; // calculate population for each burg (based on trade/people attractors) - manors.map(function(m) { + manors.map(function (m) { var cell = cells[m.cell]; var score = cell.score; - if (score <= 0) {score = rn(Math.random(), 2)} - if (cell.crossroad) {score += cell.crossroad;} // crossroads - if (cell.confluence) {score += Math.pow(cell.confluence, 0.3);} // confluences - if (m.i !== m.region && cell.port) {score *= 1.5;} // ports (not capital) - if (m.i === m.region && !cell.port) {score *= 2;} // land-capitals - if (m.i === m.region && cell.port) {score *= 3;} // port-capitals + if (score <= 0) { score = rn(Math.random(), 2) } + if (cell.crossroad) { score += cell.crossroad; } // crossroads + if (cell.confluence) { score += Math.pow(cell.confluence, 0.3); } // confluences + if (m.i !== m.region && cell.port) { score *= 1.5; } // ports (not capital) + if (m.i === m.region && !cell.port) { score *= 2; } // land-capitals + if (m.i === m.region && cell.port) { score *= 3; } // port-capitals if (m.region === "neutral") score *= urbanFactor; m.population = rn(score, 1); }); // calculate rural population for each cell based on area + elevation (elevation to be changed to biome) const graphSizeAdj = 90 / Math.sqrt(cells.length, 2); // adjust to different graphSize - land.map(function(l) { + land.map(function (l) { let population = 0; const elevationFactor = Math.pow(1 - l.height, 3); population = elevationFactor * l.area * graphSizeAdj; @@ -3407,37 +3418,39 @@ function fantasyMap() { }); // calculate population for each region - states.map(function(s, i) { + states.map(function (s, i) { // define region burgs count - var burgs = $.grep(manors, function(e) {return e.region === i;}); + var burgs = $.grep(manors, function (e) { return e.region === i; }); s.burgs = burgs.length; // define region total and burgs population var burgsPop = 0; // get summ of all burgs population - burgs.map(function(b) {burgsPop += b.population;}); + burgs.map(function (b) { burgsPop += b.population; }); s.urbanPopulation = rn(burgsPop, 2); - var regionCells = $.grep(cells, function(e) {return e.region === i;}); + var regionCells = $.grep(cells, function (e) { return e.region === i; }); let cellsPop = 0; - regionCells.map(function(c) {cellsPop += c.pop}); + regionCells.map(function (c) { cellsPop += c.pop }); s.cells = regionCells.length; s.ruralPopulation = rn(cellsPop, 1); }); // collect data for neutrals - const neutralCells = $.grep(cells, function(e) {return e.region === "neutral";}); + const neutralCells = $.grep(cells, function (e) { return e.region === "neutral"; }); if (neutralCells.length) { let burgs = 0, urbanPopulation = 0, ruralPopulation = 0, area = 0; - manors.forEach(function(m) { + manors.forEach(function (m) { if (m.region !== "neutral") return; urbanPopulation += m.population; burgs++; }); - neutralCells.forEach(function(c) { + neutralCells.forEach(function (c) { ruralPopulation += c.pop; area += cells[c.index].area; }); - states.push({i: states.length, color: "neutral", name: "Neutrals", capital: "neutral", + states.push({ + i: states.length, color: "neutral", name: "Neutrals", capital: "neutral", cells: neutralCells.length, burgs, urbanPopulation: rn(urbanPopulation, 2), - ruralPopulation: rn(ruralPopulation, 2), area: rn(area)}); + ruralPopulation: rn(ruralPopulation, 2), area: rn(area) + }); } } @@ -3462,7 +3475,7 @@ function fantasyMap() { const closest = cultureTree.find(x, y); const culture = getCultureId(closest); const name = generateName(culture); - manors.push({i: region, cell, x, y, region, culture, name}); + manors.push({ i: region, cell, x, y, region, culture, name }); } if (l === land.length - 1) { console.error("Cannot place capitals with current spacing. Trying again with reduced spacing"); @@ -3473,10 +3486,10 @@ function fantasyMap() { // For each capital create a country const scheme = count <= 8 ? colors8 : colors20; const mod = +powerInput.value; - manors.forEach(function(m, i) { + manors.forEach(function (m, i) { const power = rn(Math.random() * mod / 2 + 1, 1); const color = scheme(i / count); - states.push({i, color, power, capital: i}); + states.push({ i, color, power, capital: i }); states[i].name = generateStateName(i); const p = cells[m.cell]; p.manor = i; @@ -3491,7 +3504,7 @@ function fantasyMap() { const count = +manorsInput.value; const neutral = +neutralInput.value; const manorTree = d3.quadtree(); - manors.forEach(function(m) {manorTree.add([m.x, m.y]);}); + manors.forEach(function (m) { manorTree.add([m.x, m.y]); }); for (let l = 0; manors.length < count && l < land.length; l++) { const x = land[l].data[0], y = land[l].data[1]; @@ -3504,7 +3517,7 @@ function fantasyMap() { let dist = Math.hypot(manors[c].x - x, manors[c].y - y) / states[c].power; const cap = manors[c].cell; if (cells[cell].fn !== cells[cap].fn) dist *= 3; - if (dist < closest) {region = c; closest = dist;} + if (dist < closest) { region = c; closest = dist; } } if (closest > neutral / 5 || region === "neutral") { const closestCulture = cultureTree.find(x, y); @@ -3516,7 +3529,7 @@ function fantasyMap() { land[l].manor = manors.length; land[l].culture = culture; land[l].region = region; - manors.push({i: manors.length, cell, x, y, region, culture, name}); + manors.push({ i: manors.length, cell, x, y, region, culture, name }); manorTree.add([x, y]); } if (manors.length < count) { @@ -3528,7 +3541,7 @@ function fantasyMap() { // shift settlements from cell point function shiftSettlements() { - for (let i=0; i < manors.length; i++) { + for (let i = 0; i < manors.length; i++) { const capital = i < regionsInput.value; const cell = cells[manors[i].cell]; let x = manors[i].x, y = manors[i].y; @@ -3561,11 +3574,11 @@ function fantasyMap() { console.time("checkAccessibility"); for (let f = 0; f < features.length; f++) { if (!features[f].land) continue; - var manorsOnIsland = $.grep(land, function(e) {return e.manor !== undefined && e.fn === f;}); + var manorsOnIsland = $.grep(land, function (e) { return e.manor !== undefined && e.fn === f; }); if (manorsOnIsland.length > 0) { - var ports = $.grep(manorsOnIsland, function(p) {return p.port;}); + var ports = $.grep(manorsOnIsland, function (p) { return p.port; }); if (ports.length === 0) { - var portCandidates = $.grep(manorsOnIsland, function(c) {return c.harbor && c.ctype === 1;}); + var portCandidates = $.grep(manorsOnIsland, function (c) { return c.harbor && c.ctype === 1; }); if (portCandidates.length > 0) { // No ports on island. Upgrading first burg to port const candidate = portCandidates[0]; @@ -3578,12 +3591,12 @@ function fantasyMap() { candidate.score += Math.floor((portCandidates.length - 1) / 2); } else { // No ports on island. Reducing score for burgs - manorsOnIsland.map(function(e) {e.score -= 2;}); + manorsOnIsland.map(function (e) { e.score -= 2; }); } } } } - console.timeEnd("checkAccessibility"); + console.timeEnd("checkAccessibility"); } function generateMainRoads() { @@ -3592,7 +3605,7 @@ function fantasyMap() { if (states.length < 2 || manors.length < 2) return; for (let f = 0; f < features.length; f++) { if (!features[f].land) continue; - const manorsOnIsland = $.grep(land, function(e) {return e.manor !== undefined && e.fn === f;}); + const manorsOnIsland = $.grep(land, function (e) { return e.manor !== undefined && e.fn === f; }); if (manorsOnIsland.length > 1) { for (let d = 1; d < manorsOnIsland.length; d++) { for (let m = 0; m < d; m++) { @@ -3610,17 +3623,17 @@ function fantasyMap() { console.time("generatePortRoads"); if (!states.length || manors.length < 2) return; const portless = []; - for (let s=0; s < states.length; s++) { + for (let s = 0; s < states.length; s++) { const cell = manors[s].cell; if (cells[cell].port === undefined) portless.push(s); } - for (let l=0; l < portless.length; l++) { - const ports = $.grep(land, function(l) {return l.port !== undefined && l.region === portless[l];}); + for (let l = 0; l < portless.length; l++) { + const ports = $.grep(land, function (l) { return l.port !== undefined && l.region === portless[l]; }); if (!ports.length) continue; let minDist = 1000, end = -1; - ports.map(function(p) { + ports.map(function (p) { const dist = Math.hypot(e.data[0] - p.data[0], e.data[1] - p.data[1]); - if (dist < minDist && dist > 1) {minDist = dist; end = p.index;} + if (dist < minDist && dist > 1) { minDist = dist; end = p.index; } }); if (end !== -1) { const start = manors[portless[l]].cell; @@ -3635,11 +3648,11 @@ function fantasyMap() { console.time("generateSmallRoads"); if (manors.length < 2) return; for (let f = 0; f < features.length; f++) { - var manorsOnIsland = $.grep(land, function(e) {return e.manor !== undefined && e.fn === f;}); + var manorsOnIsland = $.grep(land, function (e) { return e.manor !== undefined && e.fn === f; }); var l = manorsOnIsland.length; if (l > 1) { var secondary = rn((l + 8) / 10); - for (s = 0; s < secondary; s++) { + for (let s = 0; s < secondary; s++) { var start = manorsOnIsland[Math.floor(Math.random() * l)].index; var end = manorsOnIsland[Math.floor(Math.random() * l)].index; var dist = Math.hypot(cells[start].data[0] - cells[end].data[0], cells[start].data[1] - cells[end].data[1]); @@ -3648,15 +3661,15 @@ function fantasyMap() { restorePath(end, start, "small", path); } } - manorsOnIsland.map(function(e, d) { + manorsOnIsland.map(function (e, d) { if (!e.path && d > 0) { var start = e.index, end = -1; - var road = $.grep(land, function(e) {return e.path && e.fn === f;}); + var road = $.grep(land, function (e) { return e.path && e.fn === f; }); if (road.length > 0) { var minDist = 10000; - road.map(function(i) { + road.map(function (i) { var dist = Math.hypot(e.data[0] - i.data[0], e.data[1] - i.data[1]); - if (dist < minDist) {minDist = dist; end = i.index;} + if (dist < minDist) { minDist = dist; end = i.index; } }); } else { end = manorsOnIsland[0].index; @@ -3714,13 +3727,13 @@ function fantasyMap() { const start = onIsland[fn][0]; const paths = findOceanPaths(start, -1); - for (let h=1; h < onIsland[fn].length; h++) { + for (let h = 1; h < onIsland[fn].length; h++) { // routes from all ports on island to 1st port on island restorePath(onIsland[fn][h], start, "ocean", paths); } // inter-island routes - for (let c=fn+1; c < onIsland.length; c++) { + for (let c = fn + 1; c < onIsland.length; c++) { if (!onIsland[c]) continue; if (!onIsland[c].length) continue; if (onIsland[fn].length > 3) { @@ -3731,7 +3744,7 @@ function fantasyMap() { if (features[w].border && !features[fn].border && onIsland[fn].length > 5) { // encircle the island - onIsland[fn].sort(function(a, b) {return cells[b].cost - cells[a].cost;}); + onIsland[fn].sort(function (a, b) { return cells[b].cost - cells[a].cost; }); for (let a = 2; a < onIsland[fn].length && a < 10; a++) { const from = onIsland[fn][1], to = onIsland[fn][a]; const dist = Math.hypot(cells[from].data[0] - cells[to].data[0], cells[from].data[1] - cells[to].data[1]); @@ -3755,25 +3768,25 @@ function fantasyMap() { function findLandPath(start, end, type) { // A* algorithm - var queue = new PriorityQueue({comparator: function(a, b) {return a.p - b.p}}); + var queue = new PriorityQueue({ comparator: function (a, b) { return a.p - b.p } }); var cameFrom = []; var costTotal = []; costTotal[start] = 0; - queue.queue({e: start, p: 0}); + queue.queue({ e: start, p: 0 }); while (queue.length > 0) { var next = queue.dequeue().e; - if (next === end) {break;} + if (next === end) { break; } var pol = cells[next]; - pol.neighbors.forEach(function(e) { + pol.neighbors.forEach(function (e) { if (cells[e].height >= 0.2) { var cost = cells[e].height * 2; if (cells[e].path && type === "main") { cost = 0.15; } else { - if (typeof e.manor === "undefined") {cost += 0.1;} - if (typeof e.river !== "undefined") {cost -= 0.1;} - if (cells[e].harbor) {cost *= 0.3;} - if (cells[e].path) {cost *= 0.5;} + if (typeof e.manor === "undefined") { cost += 0.1; } + if (typeof e.river !== "undefined") { cost -= 0.1; } + if (cells[e].harbor) { cost *= 0.3; } + if (cells[e].path) { cost *= 0.5; } cost += Math.hypot(cells[e].data[0] - pol.data[0], cells[e].data[1] - pol.data[1]) / 30; } var costNew = costTotal[next] + cost; @@ -3782,7 +3795,7 @@ function fantasyMap() { cameFrom[e] = next; var dist = Math.hypot(cells[e].data[0] - cells[end].data[0], cells[e].data[1] - cells[end].data[1]) / 15; var priority = costNew + dist; - queue.queue({e, p: priority}); + queue.queue({ e, p: priority }); } } }); @@ -3792,14 +3805,14 @@ function fantasyMap() { function findLandPaths(start, type) { // Dijkstra algorithm (not used now) - const queue = new PriorityQueue({comparator: function(a, b) {return a.p - b.p}}); + const queue = new PriorityQueue({ comparator: function (a, b) { return a.p - b.p } }); const cameFrom = [], costTotal = []; cameFrom[start] = "no", costTotal[start] = 0; - queue.queue({e: start, p: 0}); + queue.queue({ e: start, p: 0 }); while (queue.length > 0) { const next = queue.dequeue().e; const pol = cells[next]; - pol.neighbors.forEach(function(e) { + pol.neighbors.forEach(function (e) { if (cells[e].height < 0.2) return; let cost = cells[e].height * 2; if (e.river !== undefined) cost -= 0.2; @@ -3810,7 +3823,7 @@ function fantasyMap() { if (!cameFrom[e]) { costTotal[e] = costNew; cameFrom[e] = next; - queue.queue({e, p: costNew}); + queue.queue({ e, p: costNew }); } }); } @@ -3818,15 +3831,15 @@ function fantasyMap() { } function findOceanPaths(start, end) { - const queue = new PriorityQueue({comparator: function(a, b) {return a.p - b.p}}); + const queue = new PriorityQueue({ comparator: function (a, b) { return a.p - b.p } }); let next; const cameFrom = [], costTotal = []; cameFrom[start] = "no", costTotal[start] = 0; - queue.queue({e: start, p: 0}); + queue.queue({ e: start, p: 0 }); while (queue.length > 0 && next !== end) { next = queue.dequeue().e; const pol = cells[next]; - pol.neighbors.forEach(function(e) { + pol.neighbors.forEach(function (e) { if (cells[e].ctype < 0 || cells[e].haven === next) { let cost = 1; if (cells[e].ctype > 0) cost += 100; @@ -3840,7 +3853,7 @@ function fantasyMap() { costTotal[e] = costNew; cells[e].cost = costNew; cameFrom[e] = next; - queue.queue({e, p: costNew}); + queue.queue({ e, p: costNew }); } } }); @@ -3849,24 +3862,24 @@ function fantasyMap() { } function getPathDist(start, end) { - var queue = new PriorityQueue({comparator: function(a, b) {return a.p - b.p}}); + var queue = new PriorityQueue({ comparator: function (a, b) { return a.p - b.p } }); var next, costNew; var cameFrom = []; var costTotal = []; cameFrom[start] = "no"; costTotal[start] = 0; - queue.queue({e: start, p: 0}); + queue.queue({ e: start, p: 0 }); while (queue.length > 0 && next !== end) { next = queue.dequeue().e; var pol = cells[next]; - pol.neighbors.forEach(function(e) { + pol.neighbors.forEach(function (e) { if (cells[e].path && (cells[e].ctype === -1 || cells[e].haven === next)) { var dist = Math.hypot(cells[e].data[0] - pol.data[0], cells[e].data[1] - pol.data[1]); costNew = costTotal[next] + dist; if (!cameFrom[e]) { costTotal[e] = costNew; cameFrom[e] = next; - queue.queue({e, p: costNew}); + queue.queue({ e, p: costNew }); } } }); @@ -3877,24 +3890,24 @@ function fantasyMap() { function restorePath(end, start, type, from) { var path = [], current = end, limit = 1000; var prev = cells[end]; - if (type === "ocean" || !prev.path) {path.push({scX: prev.data[0], scY: prev.data[1], i: end});} - if (!prev.path) {prev.path = 1;} - for (var i = 0; i < limit; i++) { + if (type === "ocean" || !prev.path) { path.push({ scX: prev.data[0], scY: prev.data[1], i: end }); } + if (!prev.path) { prev.path = 1; } + for (let i = 0; i < limit; i++) { current = from[current]; var cur = cells[current]; - if (!cur) {break;} + if (!cur) { break; } if (cur.path) { cur.path += 1; - path.push({scX: cur.data[0], scY: cur.data[1], i: current}); + path.push({ scX: cur.data[0], scY: cur.data[1], i: current }); prev = cur; drawPath(); } else { cur.path = 1; - if (prev) {path.push({scX: prev.data[0], scY: prev.data[1], i: prev.index});} + if (prev) { path.push({ scX: prev.data[0], scY: prev.data[1], i: prev.index }); } prev = undefined; - path.push({scX: cur.data[0], scY: cur.data[1], i: current}); + path.push({ scX: cur.data[0], scY: cur.data[1], i: current }); } - if (current === start || !from[current]) {break;} + if (current === start || !from[current]) { break; } } drawPath(); function drawPath() { @@ -3904,12 +3917,12 @@ function fantasyMap() { var plus = type === "main" ? 4 : 2; var f = cells[path[0].i]; if (f.path > 1) { - if (!f.crossroad) {f.crossroad = 0;} + if (!f.crossroad) { f.crossroad = 0; } f.crossroad += plus; } var t = cells[(path[path.length - 1].i)]; if (t.path > 1) { - if (!t.crossroad) {t.crossroad = 0;} + if (!t.crossroad) { t.crossroad = 0; } t.crossroad += plus; } } @@ -3919,13 +3932,13 @@ function fantasyMap() { let id = 0; // to create unique route id if (type === "main") { id = roads.selectAll("path").size(); - roads.append("path").attr("d", line).attr("id", "road"+id).on("click", editRoute); + roads.append("path").attr("d", line).attr("id", "road" + id).on("click", editRoute); } else if (type === "small") { id = trails.selectAll("path").size(); - trails.append("path").attr("d", line).attr("id", "trail"+id).on("click", editRoute); + trails.append("path").attr("d", line).attr("id", "trail" + id).on("click", editRoute); } else if (type === "ocean") { id = searoutes.selectAll("path").size(); - searoutes.append("path").attr("d", line).attr("id", "searoute"+id).on("click", editRoute); + searoutes.append("path").attr("d", line).attr("id", "searoute" + id).on("click", editRoute); } } path = []; @@ -3960,7 +3973,7 @@ function fantasyMap() { } function calculateChains() { - for (let c=0; c < nameBase.length; c++) { + for (let c = 0; c < nameBase.length; c++) { chain[c] = calculateChain(c); } } @@ -3973,15 +3986,15 @@ function fantasyMap() { for (let i = -1, prev = " ", str = ""; i < d.length - 2; prev = str, i += str.length, str = "") { let vowel = 0, f = " "; - if (method === "let-to-let") {str = d[i+1];} else { - for (let c=i+1; str.length < 5; c++) { + if (method === "let-to-let") { str = d[i + 1]; } else { + for (let c = i + 1; str.length < 5; c++) { if (d[c] === undefined) break; str += d[c]; if (str === " ") break; - if (d[c] !== "o" && d[c] !== "e" && vowels.includes(d[c]) && d[c+1] === d[c]) break; - if (d[c+2] === " ") {str += d[c+1]; break;} + if (d[c] !== "o" && d[c] !== "e" && vowels.includes(d[c]) && d[c + 1] === d[c]) break; + if (d[c + 2] === " ") { str += d[c + 1]; break; } if (vowels.includes(d[c])) vowel++; - if (vowel && vowels.includes(d[c+2])) break; + if (vowel && vowels.includes(d[c + 2])) break; } } if (i >= 0) { @@ -4012,33 +4025,33 @@ function fantasyMap() { base = 0; } const method = nameBases[base].method; - const error = function(base) { + const error = function (base) { tip("Names data for base " + nameBases[base].name + " is incorrect. Please fix in Namesbase Editor"); editNamesbase(); } if (method === "selection") { - if (nameBase[base].length < 1) {error(base); return;} + if (nameBase[base].length < 1) { error(base); return; } const rnd = rand(nameBase[base].length - 1); const name = nameBase[base][rnd]; return name; } const data = chain[base]; - if (data === undefined || data[" "] === undefined) {error(base); return;} + if (data === undefined || data[" "] === undefined) { error(base); return; } const max = nameBases[base].max; const min = nameBases[base].min; const d = nameBases[base].d; let word = "", variants = data[" "]; - if (variants === undefined) {error(base); return;}; + if (variants === undefined) { error(base); return; }; let cur = variants[rand(variants.length - 1)]; - for (let i=0; i < 21; i++) { + for (let i = 0; i < 21; i++) { if (cur === " " && Math.random() < 0.8) { // space means word end, but we don't want to end if word is too short if (word.length < min) { word = ""; variants = data[" "]; - } else {break;} + } else { break; } } else { const l = method === "let-to-syl" && cur.length > 1 ? cur[cur.length - 1] : cur; variants = data[l]; @@ -4046,7 +4059,7 @@ function fantasyMap() { word += cur; // add current el to word if (word.length > max) word = ""; } - if (variants === undefined) {error(base); return;}; + if (variants === undefined) { error(base); return; }; cur = variants[rand(variants.length - 1)]; } // very rare case, let's just select a random name @@ -4055,14 +4068,14 @@ function fantasyMap() { // do not allow multi-word name if word is foo short or not allowed for culture if (word.includes(" ")) { let words = word.split(" "), parsed; - if (Math.random() > nameBases[base].m) {word = words.join("");} + if (Math.random() > nameBases[base].m) { word = words.join(""); } else { - for (let i=0; i < words.length; i++) { + for (let i = 0; i < words.length; i++) { if (words[i].length < 2) { if (!i) words[1] = words[0] + words[1]; - if (i) words[i-1] = words[i-1] + words[i]; + if (i) words[i - 1] = words[i - 1] + words[i]; words.splice(i, 1); - i--; + i--; } } word = words.join(" "); @@ -4070,16 +4083,16 @@ function fantasyMap() { } // parse word to get a final name - const name = [...word].reduce(function(r, c, i, data) { + const name = [...word].reduce(function (r, c, i, data) { if (c === " ") { if (!r.length) return ""; - if (i+1 === data.length) return r; + if (i + 1 === data.length) return r; } if (!r.length) return c.toUpperCase(); if (r.slice(-1) === " ") return r + c.toUpperCase(); - if (c === data[i-1]) { + if (c === data[i - 1]) { if (!d.includes(c)) return r; - if (c === data[i-2]) return r; + if (c === data[i - 2]) return r; } return r + c; }, ""); @@ -4090,10 +4103,10 @@ function fantasyMap() { function defineRegions() { console.time('defineRegions'); const manorTree = d3.quadtree(); - manors.forEach(function(m) {if (m.region !== "removed") manorTree.add([m.x, m.y]);}); + manors.forEach(function (m) { if (m.region !== "removed") manorTree.add([m.x, m.y]); }); const neutral = +neutralInput.value; - land.forEach(function(i) { + land.forEach(function (i) { if (i.manor !== undefined) { i.region = manors[i.manor].region; i.culture = manors[i.manor].culture; @@ -4115,11 +4128,11 @@ function fantasyMap() { const cell = manors[manor].cell; if (cells[cell].fn !== i.fn) { let minDist = dist * 3; - land.forEach(function(l) { + land.forEach(function (l) { if (l.fn === i.fn && l.manor !== undefined) { if (manors[l.manor].region === "removed") return; const distN = Math.hypot(l.data[0] - x, l.data[1] - y); - if (distN < minDist) {minDist = distN; manor = l.manor;} + if (distN < minDist) { minDist = distN; manor = l.manor; } } }); } @@ -4137,16 +4150,16 @@ function fantasyMap() { // arrays to store edge data const edges = [], coastalEdges = [], borderEdges = [], neutralEdges = []; - for (let a=0; a < states.length; a++) { + for (let a = 0; a < states.length; a++) { edges[a] = []; coastalEdges[a] = []; } const e = diagram.edges; - for (let i=0; i < e.length; i++) { + for (let i = 0; i < e.length; i++) { if (e[i] === undefined) continue; const start = e[i][0].join(" "); const end = e[i][1].join(" "); - const p = {start, end}; + const p = { start, end }; if (e[i].left === undefined) { const r = e[i].right.index; const rr = cells[r].region; @@ -4166,17 +4179,17 @@ function fantasyMap() { if (lr === rr) continue; if (Number.isInteger(lr)) { edges[lr].push(p); - if (rr === undefined) {coastalEdges[lr].push(p);} - else if (rr === "neutral") {neutralEdges.push(p);} + if (rr === undefined) { coastalEdges[lr].push(p); } + else if (rr === "neutral") { neutralEdges.push(p); } } if (Number.isInteger(rr)) { edges[rr].push(p); - if (lr === undefined) {coastalEdges[rr].push(p);} - else if (lr === "neutral") {neutralEdges.push(p);} - else if (Number.isInteger(lr)) {borderEdges.push(p);} + if (lr === undefined) { coastalEdges[rr].push(p); } + else if (lr === "neutral") { neutralEdges.push(p); } + else if (Number.isInteger(lr)) { borderEdges.push(p); } } } - edges.map(function(e, i) { + edges.map(function (e, i) { if (e.length) { drawRegion(e, i); drawRegionCoast(coastalEdges[i], i); @@ -4196,11 +4209,11 @@ function fantasyMap() { var end = edges[0].end; edges.shift(); var spl = start.split(" "); - edgesOrdered.push({scX: spl[0], scY: spl[1]}); + edgesOrdered.push({ scX: spl[0], scY: spl[1] }); spl = end.split(" "); - edgesOrdered.push({scX: spl[0], scY: spl[1]}); - for (var i = 0; end !== start && i < 2000; i++) { - var next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); + edgesOrdered.push({ scX: spl[0], scY: spl[1] }); + for (let i = 0; end !== start && i < 2000; i++) { + var next = $.grep(edges, function (e) { return (e.start == end || e.end == end); }); if (next.length > 0) { if (next[0].start == end) { end = next[0].end; @@ -4208,22 +4221,22 @@ function fantasyMap() { end = next[0].start; } spl = end.split(" "); - edgesOrdered.push({scX: spl[0], scY: spl[1]}); + edgesOrdered.push({ scX: spl[0], scY: spl[1] }); } var rem = edges.indexOf(next[0]); edges.splice(rem, 1); } path += lineGen(edgesOrdered) + "Z "; var edgesFormatted = []; - edgesOrdered.map(function(e) {edgesFormatted.push([+e.scX, +e.scY])}); + edgesOrdered.map(function (e) { edgesFormatted.push([+e.scX, +e.scY]) }); array[array.length] = edgesFormatted; } var color = states[region].color; - regions.append("path").attr("d", round(path, 1)).attr("fill", color).attr("stroke", "none").attr("class", "region"+region); - array.sort(function(a, b){return b.length - a.length;}); + regions.append("path").attr("d", round(path, 1)).attr("fill", color).attr("stroke", "none").attr("class", "region" + region); + array.sort(function (a, b) { return b.length - a.length; }); var name = states[region].name; var c = polylabel(array, 1.0); // pole of inaccessibility - labels.select("#countries").append("text").attr("id", "regionLabel"+region).attr("x", rn(c[0])).attr("y", rn(c[1])).text(name).on("click", editLabel); + labels.select("#countries").append("text").attr("id", "regionLabel" + region).attr("x", rn(c[0])).attr("y", rn(c[1])).text(name).on("click", editLabel); states[region].area = rn(Math.abs(d3.polygonArea(array[0]))); // define region area } @@ -4235,10 +4248,10 @@ function fantasyMap() { var end = edges[0].end; edges.shift(); var spl = start.split(" "); - edgesOrdered.push({scX: spl[0], scY: spl[1]}); + edgesOrdered.push({ scX: spl[0], scY: spl[1] }); spl = end.split(" "); - edgesOrdered.push({scX: spl[0], scY: spl[1]}); - var next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); + edgesOrdered.push({ scX: spl[0], scY: spl[1] }); + var next = $.grep(edges, function (e) { return (e.start == end || e.end == end); }); while (next.length > 0) { if (next[0].start == end) { end = next[0].end; @@ -4246,30 +4259,30 @@ function fantasyMap() { end = next[0].start; } spl = end.split(" "); - edgesOrdered.push({scX: spl[0], scY: spl[1]}); + edgesOrdered.push({ scX: spl[0], scY: spl[1] }); var rem = edges.indexOf(next[0]); edges.splice(rem, 1); - next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); + next = $.grep(edges, function (e) { return (e.start == end || e.end == end); }); } path += lineGen(edgesOrdered); } var color = states[region].color; - regions.append("path").attr("d", round(path, 1)).attr("fill", "none").attr("stroke", color).attr("stroke-width", 3).attr("class", "region"+region); + regions.append("path").attr("d", round(path, 1)).attr("fill", "none").attr("stroke", color).attr("stroke-width", 3).attr("class", "region" + region); } function drawBorders(edges, type) { var path = ""; - if (edges.length < 1) {return;} + if (edges.length < 1) { return; } while (edges.length > 0) { var edgesOrdered = []; // to store points in a correct order var start = edges[0].start; var end = edges[0].end; edges.shift(); var spl = start.split(" "); - edgesOrdered.push({scX: spl[0], scY: spl[1]}); + edgesOrdered.push({ scX: spl[0], scY: spl[1] }); spl = end.split(" "); - edgesOrdered.push({scX: spl[0], scY: spl[1]}); - var next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); + edgesOrdered.push({ scX: spl[0], scY: spl[1] }); + var next = $.grep(edges, function (e) { return (e.start == end || e.end == end); }); while (next.length > 0) { if (next[0].start == end) { end = next[0].end; @@ -4277,26 +4290,26 @@ function fantasyMap() { end = next[0].start; } spl = end.split(" "); - edgesOrdered.push({scX: spl[0], scY: spl[1]}); + edgesOrdered.push({ scX: spl[0], scY: spl[1] }); var rem = edges.indexOf(next[0]); edges.splice(rem, 1); - next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); + next = $.grep(edges, function (e) { return (e.start == end || e.end == end); }); } path += lineGen(edgesOrdered); } - if (type === "state") {stateBorders.append("path").attr("d", round(path, 1));} - if (type === "neutral") {neutralBorders.append("path").attr("d", round(path, 1));} + if (type === "state") { stateBorders.append("path").attr("d", round(path, 1)); } + if (type === "neutral") { neutralBorders.append("path").attr("d", round(path, 1)); } } // generate region name function generateStateName(state) { let culture = null; - if (states[state]) if(manors[states[state].capital]) culture = manors[states[state].capital].culture; + if (states[state]) if (manors[states[state].capital]) culture = manors[states[state].capital].culture; let name = "NameIdontWant"; if (Math.random() < 0.85 || culture === null) { // culture is random if capital is not yet defined if (culture === null) culture = rand(cultures.length - 1); - while (name.length > 8) {name = generateName(culture);} + while (name.length > 8) { name = generateName(culture); } } else { name = manors[state].name; } @@ -4307,11 +4320,11 @@ function fantasyMap() { const e = name.slice(-2); if (base === 5 && (e === "sk" || e === "ev" || e === "ov")) { // remove -sk and -ev/-ov for Ruthenian - name = name.slice(0,-2); + name = name.slice(0, -2); addSuffix = true; } else if (name.length > 6 && name.slice(-4) === "berg") { // remove -berg ending for any - name = name.slice(0,-4); + name = name.slice(0, -4); addSuffix = true; } @@ -4319,11 +4332,11 @@ function fantasyMap() { let vowel = vowels.includes(name.slice(-1)); // last char is vowel if (vowel && name.length > 3) { if (Math.random() < 0.85) { - if (vowels.includes(name.slice(-2,-1))) { - name = name.slice(0,-2); + if (vowels.includes(name.slice(-2, -1))) { + name = name.slice(0, -2); addSuffix = true; // 85% for vv } else if (Math.random() < 0.7) { - name = name.slice(0,-1); + name = name.slice(0, -1); addSuffix = true; // ~60% for cv } } @@ -4349,7 +4362,7 @@ function fantasyMap() { function recalculateCultures(fullRedraw) { console.time("recalculateCultures"); // For each capital find closest culture and assign it to capital - states.forEach(function(s) { + states.forEach(function (s) { if (s.capital === "neutral" || s.capital === "select") return; const capital = manors[s.capital]; const c = cultureTree.find(capital.x, capital.y); @@ -4360,7 +4373,7 @@ function fantasyMap() { // assign closest culture to the town; else assign capital's culture const manorTree = d3.quadtree(); const neutral = +neutralInput.value; - manors.forEach(function(m) { + manors.forEach(function (m) { if (m.region === "removed") return; manorTree.add([m.x, m.y]); if (m.region !== "neutral") { @@ -4378,7 +4391,7 @@ function fantasyMap() { // For each land cell if distance to closest manor > neutral / 2, // assign closest culture to the cell; else assign manors's culture const changed = []; - land.forEach(function(i) { + land.forEach(function (i) { const x = i.data[0], y = i.data[1]; const c = manorTree.find(x, y); const culture = i.culture; @@ -4391,11 +4404,11 @@ function fantasyMap() { const cell = manors[manor].cell; if (cells[cell].fn !== i.fn) { let minDist = dist * 3; - land.forEach(function(l) { + land.forEach(function (l) { if (l.fn === i.fn && l.manor !== undefined) { if (manors[l.manor].region === "removed") return; const distN = Math.hypot(l.data[0] - x, l.data[1] - y); - if (distN < minDist) {minDist = distN; manor = l.manor;} + if (distN < minDist) { minDist = distN; manor = l.manor; } } }); } @@ -4404,7 +4417,7 @@ function fantasyMap() { // re-color cells if (i.culture !== culture || fullRedraw) { const clr = cultures[i.culture].color; - cults.select("#cult"+i.index).attr("fill", clr).attr("stroke", clr); + cults.select("#cult" + i.index).attr("fill", clr).attr("stroke", clr); } }); console.timeEnd("recalculateCultures"); @@ -4412,14 +4425,14 @@ function fantasyMap() { // get culture Id from center coordinates function getCultureId(c) { - for (let i=0; i < cultures.length; i++) { + for (let i = 0; i < cultures.length; i++) { if (cultures[i].center[0] === c[0]) if (cultures[i].center[1] === c[1]) return i; } } // get manor Id from center coordinates function getManorId(c) { - for (let i=0; i < manors.length; i++) { + for (let i = 0; i < manors.length; i++) { if (manors[i].x === c[0]) if (manors[i].y === c[1]) return i; } } @@ -4432,11 +4445,11 @@ function fantasyMap() { if (scheme === "green") hColor = d3.scaleSequential(d3.interpolateGreens); if (scheme === "monochrome") hColor = d3.scaleSequential(d3.interpolateGreys); if (!terrs.selectAll("path").size()) { - cells.map(function(i, d) { + cells.map(function (i, d) { let height = i.height; if (height < 0.2 && !i.lake) return; if (i.lake) { - const heights = i.neighbors.map(function(e) {if (cells[e].height >= 0.2) return cells[e].height;}) + const heights = i.neighbors.map(function (e) { if (cells[e].height >= 0.2) return cells[e].height; }) const mean = d3.mean(heights); if (!mean) return; height = Math.trunc(mean * 100) / 100; @@ -4455,7 +4468,7 @@ function fantasyMap() { // draw Cultures function toggleCultures() { if (cults.selectAll("path").size() == 0) { - land.map(function(i) { + land.map(function (i) { const color = cultures[i.culture].color; cults.append("path") .attr("d", "M" + polygons[i.index].join("L") + "Z") @@ -4480,17 +4493,17 @@ function fantasyMap() { var x = d3.range(size, svgWidth, size); var y = d3.range(size, svgHeight, size); overlay.append("g").selectAll("line").data(x).enter().append("line") - .attr("x1", function(d) {return d;}) - .attr("x2", function(d) {return d;}) + .attr("x1", function (d) { return d; }) + .attr("x2", function (d) { return d; }) .attr("y1", 0).attr("y2", svgHeight); overlay.append("g").selectAll("line").data(y).enter().append("line") - .attr("y1", function(d) {return d;}) - .attr("y2", function(d) {return d;}) + .attr("y1", function (d) { return d; }) + .attr("y2", function (d) { return d; }) .attr("x1", 0).attr("x2", svgWidth); } else { var tr = `translate(80 80) scale(${size / 20})`; d3.select("#rose").attr("transform", tr); - overlay.append("use").attr("xlink:href","#rose"); + overlay.append("use").attr("xlink:href", "#rose"); } overlay.call(d3.drag().on("start", elementDrag)); } else { @@ -4501,7 +4514,7 @@ function fantasyMap() { // clean data to get rid of redundand info function cleanData() { console.time("cleanData"); - cells.map(function(c) { + cells.map(function (c) { delete c.cost; delete c.used; delete c.coastX; @@ -4522,7 +4535,7 @@ function fantasyMap() { // close all dialogs except stated function closeDialogs(except) { except = except || "#except"; - $(".dialog:visible").not(except).each(function(e) { + $(".dialog:visible").not(except).each(function (e) { $(this).dialog("close"); }); } @@ -4531,7 +4544,7 @@ function fantasyMap() { function toggleFlux() { var colorFlux = d3.scaleSequential(d3.interpolateBlues); if (terrs.selectAll("path").size() == 0) { - land.map(function(i) { + land.map(function (i) { terrs.append("path") .attr("d", "M" + polygons[i.index].join("L") + "Z") .attr("fill", colorFlux(0.1 + i.flux)) @@ -4553,7 +4566,7 @@ function fantasyMap() { terrain.selectAll("g").selectAll("g").remove(); // sort the land to Draw the top element first (reduce the elements overlapping) land.sort(compareY); - for (i = 0; i < land.length; i++) { + for (let i = 0; i < land.length; i++) { const x = land[i].data[0]; const y = land[i].data[1]; const height = land[i].height; @@ -4601,7 +4614,7 @@ function fantasyMap() { swampCount++; land[i].used = 1; let swamp = drawSwamp(x, y); - land[i].neighbors.forEach(function(e) { + land[i].neighbors.forEach(function (e) { if (cells[e].height >= 0.2 && cells[e].height < 0.3 && !cells[e].river && cells[e].used != 1) { cells[e].used = 1; swamp += drawSwamp(cells[e].data[0], cells[e].data[1]); @@ -4685,7 +4698,8 @@ function fantasyMap() { function drawSwamp(x, y) { var h = 0.6, line = ""; - for (c = 0; c < 3; c++) { + for (let c = 0; c < 3; c++) { + let cx, cy; if (c == 0) { cx = x; cy = y - 0.5 - Math.random(); @@ -4715,7 +4729,7 @@ function fantasyMap() { if (matrix) { var angle = matrix.split('(')[1].split(')')[0].split(' ')[0]; var bbox = el.node().getBBox(); - var rotate = "rotate("+ angle + " " + (bbox.x + bbox.width/2) + " " + (bbox.y + bbox.height/2) + ")"; + var rotate = "rotate(" + angle + " " + (bbox.x + bbox.width / 2) + " " + (bbox.y + bbox.height / 2) + ")"; el.attr("transform", rotate); } } else { @@ -4754,13 +4768,13 @@ function fantasyMap() { } // Add support "click to add" button events - $("#customizeTab").click(function() {clickToAdd()}); + $("#customizeTab").click(function () { clickToAdd() }); function clickToAdd() { - if (modules.clickToAdd) {return;} + if (modules.clickToAdd) { return; } modules.clickToAdd = true; // add label on click - $("#addLabel").click(function() { + $("#addLabel").click(function () { if ($(this).hasClass('pressed')) { $(".pressed").removeClass('pressed'); restoreDefaultEvents(); @@ -4798,7 +4812,7 @@ function fantasyMap() { } // add burg on click - $("#addBurg").click(function() { + $("#addBurg").click(function () { if ($(this).hasClass('pressed')) { $(".pressed").removeClass('pressed'); restoreDefaultEvents(); @@ -4857,19 +4871,19 @@ function fantasyMap() { } cells[index].manor = i; let score = cells[index].score; - if (score <= 0) {score = rn(Math.random(), 2);} - if (cells[index].crossroad) {score += cells[index].crossroad;} // crossroads - if (cells[index].confluence) {score += Math.pow(cells[index].confluence, 0.3);} // confluences - if (cells[index].port !== undefined) {score *= 3;} // port-capital + if (score <= 0) { score = rn(Math.random(), 2); } + if (cells[index].crossroad) { score += cells[index].crossroad; } // crossroads + if (cells[index].confluence) { score += Math.pow(cells[index].confluence, 0.3); } // confluences + if (cells[index].port !== undefined) { score *= 3; } // port-capital var population = rn(score, 1); - manors.push({i, cell:index, x, y, region, culture, name, population}); + manors.push({ i, cell: index, x, y, region, culture, name, population }); recalculateStateData(state); updateCountryEditors(); tip("", true); } // add river on click - $("#addRiver").click(function() { + $("#addRiver").click(function () { if ($(this).hasClass('pressed')) { $(".pressed").removeClass('pressed'); unselect(); @@ -4889,7 +4903,7 @@ function fantasyMap() { var point = d3.mouse(this); var index = diagram.find(point[0], point[1]).index; var cell = cells[index]; - if (cell.river || cell.height < 0.2) {return;} + if (cell.river || cell.height < 0.2) { return; } var dataRiver = []; // to store river points const last = $("#rivers > path").last(); const river = last.length ? +last.attr("id").slice(5) + 1 : 0; @@ -4897,40 +4911,40 @@ function fantasyMap() { while (cell) { cell.river = river; var x = cell.data[0], y = cell.data[1]; - dataRiver.push({x, y, cell:index}); + dataRiver.push({ x, y, cell: index }); var heights = []; - cell.neighbors.forEach(function(e) {heights.push(cells[e].height);}); + cell.neighbors.forEach(function (e) { heights.push(cells[e].height); }); var minId = heights.indexOf(d3.min(heights)); var min = cell.neighbors[minId]; var tx = cells[min].data[0], ty = cells[min].data[1]; if (cells[min].height < 0.2) { var px = (x + tx) / 2; var py = (y + ty) / 2; - dataRiver.push({x: px, y: py, cell:index}); + dataRiver.push({ x: px, y: py, cell: index }); cell = undefined; } else { - if (cells[min].river === undefined) {cells[min].flux += cell.flux; cell = cells[min];} + if (cells[min].river === undefined) { cells[min].flux += cell.flux; cell = cells[min]; } else { const r = cells[min].river; - const riverEl = $("#river"+r); - const riverCells = $.grep(land, function(e) {return e.river === r;}); - riverCells.sort(function(a, b) {return b.height - a.height}); - const riverCellsUpper = $.grep(riverCells, function(e) {return e.height > cells[min].height;}); + const riverEl = $("#river" + r); + const riverCells = $.grep(land, function (e) { return e.river === r; }); + riverCells.sort(function (a, b) { return b.height - a.height }); + const riverCellsUpper = $.grep(riverCells, function (e) { return e.height > cells[min].height; }); if (dataRiver.length > riverCellsUpper.length) { // new river is more perspective const avPrec = rn(precInput.value / Math.sqrt(cells.length), 2); let dataRiverMin = []; - riverCells.map(function(c) { + riverCells.map(function (c) { if (c.height < cells[min].height) { cells[c.index].river = undefined; cells[c.index].flux = avPrec; } else { - dataRiverMin.push({x:c.data[0], y:c.data[1], cell:c.index}); + dataRiverMin.push({ x: c.data[0], y: c.data[1], cell: c.index }); } }); cells[min].flux += cell.flux; - if (cells[min].confluence) {cells[min].confluence += riverCellsUpper.length;} - else {cells[min].confluence = riverCellsUpper.length;} + if (cells[min].confluence) { cells[min].confluence += riverCellsUpper.length; } + else { cells[min].confluence = riverCellsUpper.length; } cell = cells[min]; // redraw old river's upper part or remove if small if (dataRiverMin.length > 1) { @@ -4939,13 +4953,13 @@ function fantasyMap() { riverEl.attr("d", d).attr("data-width", 1.3).attr("data-increment", 1); } else { riverEl.remove(); - dataRiverMin.map(function(c) {cells[c.cell].river = undefined;}); + dataRiverMin.map(function (c) { cells[c.cell].river = undefined; }); } } else { - if (cells[min].confluence) {cells[min].confluence += dataRiver.length;} - else {cells[min].confluence = dataRiver.length;} + if (cells[min].confluence) { cells[min].confluence += dataRiver.length; } + else { cells[min].confluence = dataRiver.length; } cells[min].flux += cell.flux; - dataRiver.push({x: tx, y: ty, cell:min}); + dataRiver.push({ x: tx, y: ty, cell: min }); cell = undefined; } } @@ -4954,12 +4968,12 @@ function fantasyMap() { var rndFactor = 0.2 + Math.random() * 1.6; // random factor in range 0.2-1.8 var riverAmended = amendRiver(dataRiver, rndFactor); var d = drawRiver(riverAmended, 1.3, 1); - rivers.append("path").attr("d", d).attr("id", "river"+river) + rivers.append("path").attr("d", d).attr("id", "river" + river) .attr("data-width", 1.3).attr("data-increment", 1).on("click", editRiver); } // add relief icon on click - $("#addRelief").click(function() { + $("#addRelief").click(function () { if ($(this).hasClass('pressed')) { $(".pressed").removeClass('pressed'); restoreDefaultEvents(); @@ -4993,7 +5007,7 @@ function fantasyMap() { } // add relief icon on click - $("#addRoute").click(function() { + $("#addRoute").click(function () { if (!modules.editRoute) editRoute(); $("#routeNew").click(); }); @@ -5013,14 +5027,14 @@ function fantasyMap() { function recalculateStateData(state) { const s = states[state]; if (s.capital === "neutral") state = "neutral"; - const burgs = $.grep(manors, function(e) {return e.region === state;}); + const burgs = $.grep(manors, function (e) { return e.region === state; }); s.burgs = burgs.length; let burgsPop = 0; // get summ of all burgs population - burgs.map(function(b) {burgsPop += b.population;}); + burgs.map(function (b) { burgsPop += b.population; }); s.urbanPopulation = rn(burgsPop, 1); - const regionCells = $.grep(cells, function(e) {return (e.region === state);}); + const regionCells = $.grep(cells, function (e) { return (e.region === state); }); let cellsPop = 0, area = 0; - regionCells.map(function(c) { + regionCells.map(function (c) { cellsPop += c.pop; area += c.area; }); @@ -5030,7 +5044,7 @@ function fantasyMap() { } function editLabel() { - if (customization) {return;} + if (customization) { return; } closeDialogs("#labelEditor, .stable"); elSelected = d3.select(this); elSelected.call(d3.drag().on("drag", dragged).on("end", dragended)).classed("draggable", true); @@ -5044,18 +5058,18 @@ function fantasyMap() { editOpacity.value = group.attr("opacity"); editText.value = elSelected.text(); var matrix = elSelected.attr("transform"); - var rotation = matrix ? matrix.split('(')[1].split(')')[0].split(' ')[0] : 0; + var rotation = matrix ? matrix.split('(')[1].split(')')[0].split(' ')[0] : 0; editAngle.value = rotation; editAngleValue.innerHTML = rotation + "°"; $("#labelEditor").dialog({ title: "Edit Label: " + editText.value, minHeight: 30, width: "auto", maxWidth: 275, resizable: false, - position: {my: "center top+10", at: "bottom", of: this}, + position: { my: "center top+10", at: "bottom", of: this }, close: unselect }); - if (modules.editLabel) {return;} + if (modules.editLabel) { return; } modules.editLabel = true; loadDefaultFonts(); @@ -5070,22 +5084,22 @@ function fantasyMap() { // select state if (customization === 2) { - const assigned = regions.select("#temp").select("path[data-cell='"+index+"']"); + const assigned = regions.select("#temp").select("path[data-cell='" + index + "']"); let s = assigned.size() ? assigned.attr("data-state") : cells[index].region; if (s === "neutral") s = states.length - 1; color = states[s].color; if (color === "neutral") color = "white"; - $("#state"+s).addClass("selected"); + $("#state" + s).addClass("selected"); } // select culture if (customization === 4) { - const assigned = cults.select("#cult"+index); + const assigned = cults.select("#cult" + index); const c = assigned.attr("data-culture") !== null ? +assigned.attr("data-culture") : cells[index].culture; color = cultures[c].color; - $("#culture"+c).addClass("selected"); + $("#culture" + c).addClass("selected"); } debug.selectAll(".circle").attr("stroke", color); @@ -5096,10 +5110,10 @@ function fantasyMap() { 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);}); + "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(); } } @@ -5107,28 +5121,29 @@ function fantasyMap() { // Update font list for Label and Burg Editors function updateFontOptions() { editFontSelect.innerHTML = ""; - for (let i=0; i < fonts.length; i++) { + 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; editFontSelect.add(opt); } - burgSelectDefaultFont.innerHTML = editFontSelect.innerHTML; + burgSelectDefaultFont.innerHTML = editFontSelect.innerHTML; } - $("#labelEditor .editButton, #labelEditor .editButtonS").click(function() { + $("#labelEditor .editButton, #labelEditor .editButtonS").click(function () { var group = d3.select(elSelected.node().parentNode); if (this.id == "editRemoveSingle") { alertMessage.innerHTML = "Are you sure you want to remove the label?"; - $("#alert").dialog({resizable: false, title: "Remove label", + $("#alert").dialog({ + resizable: false, title: "Remove label", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); elSelected.remove(); $("#labelEditor").dialog("close"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }) return; @@ -5142,14 +5157,15 @@ function fantasyMap() { } var message = "Are you sure you want to remove all labels (" + count + ") of that group?"; alertMessage.innerHTML = message; - $("#alert").dialog({resizable: false, title: "Remove labels", + $("#alert").dialog({ + resizable: false, title: "Remove labels", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); group.remove(); $("#labelEditor").dialog("close"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }) return; @@ -5158,7 +5174,7 @@ function fantasyMap() { var shift = +group.attr("font-size") + 1; var xn = +elSelected.attr("x") - shift; var yn = +elSelected.attr("y") - shift; - while (group.selectAll("text[x='" + xn + "']").size() > 0) {xn -= shift; yn -= shift;} + while (group.selectAll("text[x='" + xn + "']").size() > 0) { xn -= shift; yn -= shift; } group.append("text").attr("x", xn).attr("y", yn).text(elSelected.text()) .attr("transform", elSelected.attr("transform")).on("click", editLabel); return; @@ -5189,7 +5205,7 @@ function fantasyMap() { var name; // check if label is country name if (group.attr("id") === "countries") { - var state = $.grep(states, function(e) {return (e.name === editText.value);})[0]; + var state = $.grep(states, function (e) { return (e.name === editText.value); })[0]; name = generateStateName(state.i); state.name = name; } else { @@ -5206,23 +5222,23 @@ function fantasyMap() { } $("#labelEditor .editButton").toggle(); if (this.id == "editGroupButton") { - if ($("#editGroupInput").css("display") !== "none") {$("#editGroupSelect").css("display", "inline-block");} + if ($("#editGroupInput").css("display") !== "none") { $("#editGroupSelect").css("display", "inline-block"); } if ($("#editGroupRemove").css("display") === "none") { $("#editGroupRemove, #editGroupNew").css("display", "inline-block"); } else { $("#editGroupInput, #editGroupRemove, #editGroupNew").css("display", "none"); } } - if (this.id == "editFontButton") {$("#editSizeIcon, #editFontSelect, #editSize").toggle();} - if (this.id == "editStyleButton") {$("#editOpacityIcon, #editOpacity, #editShadowIcon, #editShadow").toggle();} - if (this.id == "editAngleButton") {$("#editAngleValue").toggle();} - if (this.id == "editTextButton") {$("#editTextRandom").toggle();} + if (this.id == "editFontButton") { $("#editSizeIcon, #editFontSelect, #editSize").toggle(); } + if (this.id == "editStyleButton") { $("#editOpacityIcon, #editOpacity, #editShadowIcon, #editShadow").toggle(); } + if (this.id == "editAngleButton") { $("#editAngleValue").toggle(); } + if (this.id == "editTextButton") { $("#editTextRandom").toggle(); } $(this).show().next().toggle(); }); function updateGroupOptions() { editGroupSelect.innerHTML = ""; - labels.selectAll("g").each(function(d) { + labels.selectAll("g").each(function (d) { const id = d3.select(this).attr("id"); if (id === "burgLabels") return; if (id === "capitals") return; @@ -5234,14 +5250,14 @@ function fantasyMap() { } // on editAngle change - $("#editAngle").on("input", function() { + $("#editAngle").on("input", function () { var c = elSelected.node().getBBox(); - var rotate = `rotate(${this.value} ${(c.x+c.width/2)} ${(c.y+c.height/2)})`; + var rotate = `rotate(${this.value} ${(c.x + c.width / 2)} ${(c.y + c.height / 2)})`; elSelected.attr("transform", rotate); editAngleValue.innerHTML = Math.abs(+this.value) + "°"; }); - $("#editFontInput").change(function() { + $("#editFontInput").change(function () { fetchFonts(this.value).then(fetched => { if (!fetched) return; editExternalFont.click(); @@ -5296,19 +5312,19 @@ function fantasyMap() { let font = family.replace(/['"]+/g, '').replace(/ /g, "+"); let weight = rule.style.getPropertyValue('font-weight'); if (weight !== "400") font += ":" + weight; - if (fonts.indexOf(font) == -1) {fonts.push(font); fetched++}; + if (fonts.indexOf(font) == -1) { fonts.push(font); fetched++ }; }; let fetched = 0; - for (var r of styleSheet.cssRules) {FontRule(r);} + for (let r of styleSheet.cssRules) { FontRule(r); } document.head.removeChild(s); return fetched; }) - .catch(function() {return}); + .catch(function () { return }); } // on any Editor input change - $("#labelEditor .editTrigger").change(function() { - if (!elSelected) {return;} + $("#labelEditor .editTrigger").change(function () { + if (!elSelected) { return; } $(this).attr("title", $(this).val()); elSelected.text(editText.value); // change Label text // check if Group was changed @@ -5329,20 +5345,20 @@ function fantasyMap() { } if (groupOld !== groupNew) { var removed = elSelected.remove(); - if (labels.select("#"+groupNew).size() > 0) { - group = labels.select("#"+groupNew); + if (labels.select("#" + groupNew).size() > 0) { + group = labels.select("#" + groupNew); editFontSelect.value = fonts.indexOf(group.attr("data-font")); editSize.value = group.attr("data-size"); editColor.value = toHEX(group.attr("fill")); editOpacity.value = group.attr("opacity"); } else { - if (group.selectAll("text").size() === 0) {group.remove();} + if (group.selectAll("text").size() === 0) { group.remove(); } group = labels.append("g").attr("id", groupNew); updateGroupOptions(); $("#editGroupSelect, #editGroupInput").toggle(); editGroupInput.value = ""; } - group.append(function() {return removed.node();}); + group.append(function () { return removed.node(); }); editGroupSelect.value = group.attr("id"); } // update Group attributes @@ -5358,51 +5374,51 @@ function fantasyMap() { }); // 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) : ''; } // 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; } // round value to d decimals function rn(v, d) { - var d = d || 0; - var m = Math.pow(10, d); - return Math.round(v * m) / m; + var d = d || 0; + var m = Math.pow(10, d); + return Math.round(v * m) / m; } // round string to d decimals function round(s, d) { - var d = d || 1; - return s.replace(/[\d\.-][\d\.e-]*/g, function(n) {return rn(n, d);}) + var d = d || 1; + return s.replace(/[\d\.-][\d\.e-]*/g, function (n) { return rn(n, d); }) } // corvent number to short string with SI postfix function si(n) { - if (n >= 1e9) {return rn(n / 1e9, 1) + "B";} - if (n >= 1e8) {return rn(n / 1e6) + "M";} - if (n >= 1e6) {return rn(n / 1e6, 1) + "M";} - if (n >= 1e4) {return rn(n / 1e3) + "K";} - if (n >= 1e3) {return rn(n / 1e3, 1) + "K";} + if (n >= 1e9) { return rn(n / 1e9, 1) + "B"; } + if (n >= 1e8) { return rn(n / 1e6) + "M"; } + if (n >= 1e6) { return rn(n / 1e6, 1) + "M"; } + if (n >= 1e4) { return rn(n / 1e3) + "K"; } + if (n >= 1e3) { return rn(n / 1e3, 1) + "K"; } return rn(n); } // getInteger number from user input data function getInteger(value) { var metric = value.slice(-1); - if (metric === "K") {return parseInt(value.slice(0, -1) * 1e3);} - if (metric === "M") {return parseInt(value.slice(0, -1) * 1e6);} - if (metric === "B") {return parseInt(value.slice(0, -1) * 1e9);} + if (metric === "K") { return parseInt(value.slice(0, -1) * 1e3); } + if (metric === "M") { return parseInt(value.slice(0, -1) * 1e6); } + if (metric === "B") { return parseInt(value.slice(0, -1) * 1e9); } return parseInt(value); } @@ -5411,7 +5427,7 @@ function fantasyMap() { console.time("saveAsImage"); // get all used fonts const fontsInUse = []; // to store fonts currently in use - labels.selectAll("g").each(function(d) { + labels.selectAll("g").each(function (d) { const font = d3.select(this).attr("data-font"); if (!font) return; if (fontsInUse.indexOf(font) === -1) fontsInUse.push(font); @@ -5438,7 +5454,7 @@ function fantasyMap() { } // to fix use elements sizing - clone.selectAll("use").each(function() { + clone.selectAll("use").each(function () { const size = this.parentNode.getAttribute("size") || 1; this.setAttribute("width", size + "px"); this.setAttribute("height", size + "px"); @@ -5462,16 +5478,16 @@ function fantasyMap() { const defaultStyles = window.getComputedStyle(emptyG); // show hidden labels but in reduced size - clone.select("#labels").selectAll(".hidden").each(function(e) { + clone.select("#labels").selectAll(".hidden").each(function (e) { const size = d3.select(this).attr("font-size"); d3.select(this).classed("hidden", false).attr("font-size", rn(size * 0.4, 2)); }); // save group css to style attribute - clone.selectAll("g, #ruler > g > *, #scaleBar > text").each(function(d) { + clone.selectAll("g, #ruler > g > *, #scaleBar > text").each(function (d) { const compStyle = window.getComputedStyle(this); let style = ""; - for (let i=0; i < compStyle.length; i++) { + for (let i = 0; i < compStyle.length; i++) { const key = compStyle[i]; const value = compStyle.getPropertyValue(key); // Firefox mask hack @@ -5493,7 +5509,7 @@ function fantasyMap() { clone.select("defs").append("style").text(cssRules.join('\n')); var svg_xml = (new XMLSerializer()).serializeToString(clone.node()); clone.remove(); - var blob = new Blob([svg_xml], {type:'image/svg+xml;charset=utf-8'}); + var blob = new Blob([svg_xml], { type: 'image/svg+xml;charset=utf-8' }); var url = window.URL.createObjectURL(blob); var link = document.createElement("a"); link.target = "_blank"; @@ -5503,15 +5519,15 @@ function fantasyMap() { canvas.height = svgHeight * pngResolutionInput.value; var img = new Image(); img.src = url; - img.onload = function(){ + img.onload = function () { window.URL.revokeObjectURL(url); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); link.download = "fantasy_map_" + Date.now() + ".png"; - canvas.toBlob(function(blob) { - link.href = window.URL.createObjectURL(blob); - document.body.appendChild(link); - link.click(); - window.setTimeout(function() {window.URL.revokeObjectURL(link.href);}, 5000); + canvas.toBlob(function (blob) { + link.href = window.URL.createObjectURL(blob); + document.body.appendChild(link); + link.click(); + window.setTimeout(function () { window.URL.revokeObjectURL(link.href); }, 5000); }); canvas.style.opacity = 0; canvas.width = svgWidth; @@ -5524,7 +5540,7 @@ function fantasyMap() { link.click(); } console.timeEnd("saveAsImage"); - window.setTimeout(function() {window.URL.revokeObjectURL(url);}, 5000); + window.setTimeout(function () { window.URL.revokeObjectURL(url); }, 5000); }); } @@ -5553,22 +5569,22 @@ function fantasyMap() { }; let fontRules = [], fontProms = []; - for (var r of styleSheet.cssRules) { + for (let r of styleSheet.cssRules) { let fR = FontRule(r) fontRules.push(fR); 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(resp => resp.blob()) + .then(blob => { + return new Promise(resolve => { + let f = new FileReader(); + f.onload = e => resolve(f.result); + f.readAsDataURL(blob); + }) + }) + .then(dataURL => { + return fR.rule.cssText.replace(fR.url, dataURL); }) - }) - .then(dataURL => { - return fR.rule.cssText.replace(fR.url, dataURL); - }) ) } document.head.removeChild(s); // clean up @@ -5583,9 +5599,9 @@ function fantasyMap() { // 5 - svg; 6 - options (see below); 7 - cultures; 8 - nameBase; 9 - nameBases; // size stats: points = 6%, cells = 36%, manors and states = 2%, svg = 56%; const options = customization + "|" + - distanceUnit.value + "|" + distanceScale.value + "|" + areaUnit.value + "|" + - barSize.value + "|" + barLabel.value + "|" + barBackOpacity.value + "|" + barBackColor.value + "|" + - populationRate.value + "|" + urbanization.value; + distanceUnit.value + "|" + distanceScale.value + "|" + areaUnit.value + "|" + + barSize.value + "|" + barLabel.value + "|" + barBackOpacity.value + "|" + barBackColor.value + "|" + + populationRate.value + "|" + urbanization.value; // set zoom / transform values to default svg.attr("width", graphWidth).attr("height", graphHeight); @@ -5600,7 +5616,7 @@ function fantasyMap() { var data = version + line + JSON.stringify(points) + line + JSON.stringify(cells) + line; data += JSON.stringify(manors) + line + JSON.stringify(states) + line + svg_xml + line + options + line; data += JSON.stringify(cultures) + line + JSON.stringify(nameBase) + line + JSON.stringify(nameBases) + line; - var dataBlob = new Blob([data], {type:"text/plain"}); + var dataBlob = new Blob([data], { type: "text/plain" }); var dataURL = window.URL.createObjectURL(dataBlob); var link = document.createElement("a"); link.download = "fantasy_map_" + Date.now() + ".map"; @@ -5614,11 +5630,11 @@ function fantasyMap() { oceanBack.attr("x", oceanShift[0]).attr("y", oceanShift[1]).attr("width", oceanShift[2]).attr("height", oceanShift[3]); console.timeEnd("saveMap"); - window.setTimeout(function() {window.URL.revokeObjectURL(dataURL);}, 4000); + window.setTimeout(function () { window.URL.revokeObjectURL(dataURL); }, 4000); } // Map Loader based on FileSystem API - $("#mapToLoad").change(function() { + $("#mapToLoad").change(function () { console.time("loadMap"); closeDialogs(); var fileToLoad = this.files[0]; @@ -5629,7 +5645,7 @@ function fantasyMap() { function uploadFile(file, callback) { console.time("loadMap"); var fileReader = new FileReader(); - fileReader.onload = function(fileLoadedEvent) { + fileReader.onload = function (fileLoadedEvent) { var dataLoaded = fileLoadedEvent.target.result; var data = dataLoaded.split("\r\n"); // data convention: 0 - version; 1 - all points; 2 - cells; 3 - manors; 4 - states; @@ -5639,7 +5655,7 @@ function fantasyMap() { var message = `The Map version `; // mapVersion reference was not added to downloaded map before v. 0.52b, so I cannot support really old files if (mapVersion.length <= 10) { - message += `(${mapVersion}) does not match the Generator version (${version}). The map will be auto-updated. + message += `(${mapVersion}) does not match the Generator version (${version}). The map will be auto-updated. In case of critical issues you may send the .map file to me or just keep using @@ -5651,14 +5667,18 @@ function fantasyMap() { of the Generator. Please note the Gennerator is still on demo and a lot of crusial changes are being made every month`; } alertMessage.innerHTML = message; - $("#alert").dialog({title: "Warning", buttons: {OK: function() { - loadDataFromMap(data); - }}}); - } else {loadDataFromMap(data);} - if (mapVersion.length > 10) {console.error("Cannot load map"); return;} + $("#alert").dialog({ + title: "Warning", buttons: { + OK: function () { + loadDataFromMap(data); + } + } + }); + } else { loadDataFromMap(data); } + if (mapVersion.length > 10) { console.error("Cannot load map"); return; } } fileReader.readAsText(file, "UTF-8"); - if (callback) {callback();} + if (callback) { callback(); } } function loadDataFromMap(data) { @@ -5696,18 +5716,19 @@ function fantasyMap() { const nWidth = +svg.attr("width"), nHeight = +svg.attr("height"); graphWidth = nWidth; graphHeight = nHeight; - voronoi = d3.voronoi().extent([[-1, -1], [graphWidth+1, graphHeight+1]]); + voronoi = d3.voronoi().extent([[-1, -1], [graphWidth + 1, graphHeight + 1]]); zoom.translateExtent([[0, 0], [graphWidth, graphHeight]]).scaleExtent([1, 20]).scaleTo(svg, 1); viewbox.attr("transform", null); // temporary fit loaded svg element to current canvas size svg.attr("width", svgWidth).attr("height", svgHeight); if (nWidth !== svgWidth || nHeight !== svgHeight) { - alertMessage.innerHTML = `The loaded map has size ${nWidth} x ${nHeight} pixels, while the current canvas size is ${svgWidth} x ${svgHeight} pixels. + alertMessage.innerHTML = `The loaded map has size ${nWidth} x ${nHeight} pixels, while the current canvas size is ${svgWidth} x ${svgHeight} pixels. Click "Rescale" to fit the map to the current canvas size. Click "OK" to browse the map without rescaling`; - $("#alert").dialog({title: "Map size conflict", + $("#alert").dialog({ + title: "Map size conflict", buttons: { - Rescale: function() { + Rescale: function () { applyLoadedData(data); // rescale loaded map const xRatio = svgWidth / nWidth; @@ -5721,7 +5742,7 @@ function fantasyMap() { zoom.translateExtent([[0, 0], [nWidth, nHeight]]).scaleExtent([scaleTo, 20]).scaleTo(svg, scaleTo); $(this).dialog("close"); }, - OK: function() { + OK: function () { changeMapSize(); applyLoadedData(data); $(this).dialog("close"); @@ -5766,7 +5787,7 @@ function fantasyMap() { if (!labels.select("#burgLabels").size()) { labels.append("g").attr("id", "burgLabels"); $("#labels #capitals, #labels #towns").detach().appendTo($("#burgLabels")); - labels.select("#burgLabels").selectAll("text").each(function() { + labels.select("#burgLabels").selectAll("text").each(function () { let id = this.getAttribute("id"); if (!id) return; this.removeAttribute("id"); @@ -5781,14 +5802,14 @@ function fantasyMap() { icons.select("#burgIcons").select("#towns").attr("size", .5).attr("fill-opacity", .7).attr("stroke-opacity", 1); } - icons.selectAll("g").each(function(d) { + icons.selectAll("g").each(function (d) { const size = this.getAttribute("font-size"); if (size === undefined) return; this.removeAttribute("font-size"); this.setAttribute("size", size); }); - icons.select("#burgIcons").selectAll("circle").each(function() { + icons.select("#burgIcons").selectAll("circle").each(function () { this.setAttribute("r", this.parentNode.getAttribute("size")); const id = this.getAttribute("id"); if (!id) return; @@ -5796,7 +5817,7 @@ function fantasyMap() { this.setAttribute("data-id", +id.replace("manorIcon", "")); }); - icons.selectAll("use").each(function() { + icons.selectAll("use").each(function () { const size = this.parentNode.getAttribute("size"); this.setAttribute("width", size); this.setAttribute("height", size); @@ -5835,29 +5856,29 @@ function fantasyMap() { newPoints = [], riversData = [], queue = [], elSelected = ""; points = JSON.parse(data[1]); cells = JSON.parse(data[2]); - land = $.grep(cells, function(e) {return (e.height >= 0.2);}); + land = $.grep(cells, function (e) { return (e.height >= 0.2); }); manors = JSON.parse(data[3]); - cells.map(function(e) {newPoints.push(e.data);}); + cells.map(function (e) { newPoints.push(e.data); }); calculateVoronoi(newPoints); - if(data[7]) cultures = JSON.parse(data[7]); + if (data[7]) cultures = JSON.parse(data[7]); if (data[7] === undefined) generateCultures(); - if(data[8]) nameBase = JSON.parse(data[8]); - if(data[8]) nameBases = JSON.parse(data[9]); + if (data[8]) nameBase = JSON.parse(data[8]); + if (data[8]) nameBases = JSON.parse(data[9]); // calculate areas / population for old maps const graphSizeAdj = 90 / Math.sqrt(cells.length, 2); // adjust to different graphSize - land.forEach(function(i) { - const p = i.index; - if (i.pop === undefined) { - let population = 0; - const elevationFactor = Math.pow(1 - i.height, 3); - population = elevationFactor * i.area * graphSizeAdj; - if (i.region === "neutral") population *= 0.5; - i.pop = rn(population, 1); - } - if (!polygons[p] || !polygons[p].length) return; - const area = d3.polygonArea(polygons[p]); - i.area = rn(Math.abs(area), 2); + land.forEach(function (i) { + const p = i.index; + if (i.pop === undefined) { + let population = 0; + const elevationFactor = Math.pow(1 - i.height, 3); + population = elevationFactor * i.area * graphSizeAdj; + if (i.region === "neutral") population *= 0.5; + i.pop = rn(population, 1); + } + if (!polygons[p] || !polygons[p].length) return; + const area = d3.polygonArea(polygons[p]); + i.area = rn(Math.abs(area), 2); }); // restore Heightmap customization mode @@ -5887,13 +5908,13 @@ function fantasyMap() { d3.select("#toggleGrid").classed("buttonoff", grid.style("display") === "none"); // update map to support some old versions and fetch fonts - labels.selectAll("g").each(function(d) { + labels.selectAll("g").each(function (d) { var el = d3.select(this); if (el.attr("id") === "burgLabels") return; var font = el.attr("data-font"); - if (font && fonts.indexOf(font) === -1) {addFonts("https://fonts.googleapis.com/css?family=" + font);} - if (!el.attr("data-size")) {el.attr("data-size", +el.attr("font-size"));} - if (el.style("display") === "none") {el.node().style.display = null;} + if (font && fonts.indexOf(font) === -1) { addFonts("https://fonts.googleapis.com/css?family=" + font); } + if (!el.attr("data-size")) { el.attr("data-size", +el.attr("font-size")); } + if (el.style("display") === "none") { el.node().style.display = null; } }); invokeActiveZooming(); @@ -5904,27 +5925,27 @@ function fantasyMap() { // Source: bl.ocks.org/mbostock/99049112373e12709381; Based on https://www.jasondavies.com/poisson-disc function poissonDiscSampler(width, height, radius) { var k = 5, // maximum number of points before rejection - radius2 = radius * radius, - R = 3 * radius2, - cellSize = radius * Math.SQRT1_2, - gridWidth = Math.ceil(width / cellSize), - gridHeight = Math.ceil(height / cellSize), - grid = new Array(gridWidth * gridHeight), - queue = [], - queueSize = 0, - sampleSize = 0; - return function() { + radius2 = radius * radius, + R = 3 * radius2, + cellSize = radius * Math.SQRT1_2, + gridWidth = Math.ceil(width / cellSize), + gridHeight = Math.ceil(height / cellSize), + grid = new Array(gridWidth * gridHeight), + queue = [], + queueSize = 0, + sampleSize = 0; + return function () { if (!sampleSize) return sample(Math.random() * width, Math.random() * height); // Pick a random existing sample and remove it from the queue while (queueSize) { var i = Math.random() * queueSize | 0, - s = queue[i]; + s = queue[i]; // Make a new candidate between [radius, 2 * radius] from the existing sample. - for (var j = 0; j < k; ++j) { + for (let j = 0; j < k; ++j) { var a = 2 * Math.PI * Math.random(), - r = Math.sqrt(Math.random() * R + radius2), - x = s[0] + r * Math.cos(a), - y = s[1] + r * Math.sin(a); + r = Math.sqrt(Math.random() * R + radius2), + x = s[0] + r * Math.cos(a), + y = s[1] + r * Math.sin(a); // Reject candidates that are outside the allowed extent, or closer than 2 * radius to any existing sample if (0 <= x && x < width && 0 <= y && y < height && far(x, y)) return sample(x, y); } @@ -5934,18 +5955,18 @@ function fantasyMap() { }; function far(x, y) { var i = x / cellSize | 0, - j = y / cellSize | 0, - i0 = Math.max(i - 2, 0), - j0 = Math.max(j - 2, 0), - i1 = Math.min(i + 3, gridWidth), - j1 = Math.min(j + 3, gridHeight); - for (j = j0; j < j1; ++j) { + j = y / cellSize | 0, + i0 = Math.max(i - 2, 0), + j0 = Math.max(j - 2, 0), + i1 = Math.min(i + 3, gridWidth), + j1 = Math.min(j + 3, gridHeight); + for (let j = j0; j < j1; ++j) { var o = j * gridWidth; - for (i = i0; i < i1; ++i) { + for (let i = i0; i < i1; ++i) { if (s = grid[o + i]) { var s, - dx = s[0] - x, - dy = s[1] - y; + dx = s[0] - x, + dy = s[1] - y; if (dx * dx + dy * dy < radius2) return false; } } @@ -5963,10 +5984,10 @@ function fantasyMap() { } // Hotkeys - d3.select("body").on("keydown", function() { + d3.select("body").on("keydown", function () { const active = document.activeElement.tagName; if (active === "INPUT" || active === "SELECT" || active === "TEXTAREA") return; - switch(d3.event.keyCode) { + switch (d3.event.keyCode) { case 27: // Escape to close all dialogs closeDialogs(); break; @@ -6024,11 +6045,11 @@ function fantasyMap() { if (d3.event.ctrlKey === false) return; redo.click(); break; - } + } }); // Toggle Options pane - $("#optionsTrigger").on("click", function() { + $("#optionsTrigger").on("click", function () { if (tooltip.getAttribute("data-main") === "Сlick the arrow button to open options") { tooltip.setAttribute("data-main", ""); tooltip.innerHTML = ""; @@ -6044,12 +6065,13 @@ function fantasyMap() { $("#optionsTrigger").removeClass("icon-left-open").addClass("icon-right-open"); } }); - $("#collapsible").hover(function() { + $("#collapsible").hover(function () { if ($("#optionsTrigger").hasClass("glow")) return; if ($("#options").css("display") === "none") { $("#regenerate").show(); $("#optionsTrigger").removeClass("glow"); - }}, function() { + } + }, function () { $("#regenerate").hide(); }); @@ -6059,36 +6081,36 @@ function fantasyMap() { if (el) { var prev = getLayer(ui.item.prev().attr("id")); var next = getLayer(ui.item.next().attr("id")); - if (prev) {el.insertAfter(prev);} else if (next) {el.insertBefore(next);} + if (prev) { el.insertAfter(prev); } else if (next) { el.insertBefore(next); } } } // define connection between option layer buttons and actual svg groups function getLayer(id) { - if (id === "toggleGrid") {return $("#grid");} - if (id === "toggleOverlay") {return $("#overlay");} - if (id === "toggleHeight") {return $("#terrs");} - if (id === "toggleCultures") {return $("#cults");} - if (id === "toggleRoutes") {return $("#routes");} - if (id === "toggleRivers") {return $("#rivers");} - if (id === "toggleCountries") {return $("#regions");} - if (id === "toggleBorders") {return $("#borders");} - if (id === "toggleRelief") {return $("#terrain");} - if (id === "toggleLabels") {return $("#labels");} - if (id === "toggleIcons") {return $("#icons");} + if (id === "toggleGrid") { return $("#grid"); } + if (id === "toggleOverlay") { return $("#overlay"); } + if (id === "toggleHeight") { return $("#terrs"); } + if (id === "toggleCultures") { return $("#cults"); } + if (id === "toggleRoutes") { return $("#routes"); } + if (id === "toggleRivers") { return $("#rivers"); } + if (id === "toggleCountries") { return $("#regions"); } + if (id === "toggleBorders") { return $("#borders"); } + if (id === "toggleRelief") { return $("#terrain"); } + if (id === "toggleLabels") { return $("#labels"); } + if (id === "toggleIcons") { return $("#icons"); } } // UI Button handlers - $("button, a, li, i").on("click", function() { + $("button, a, li, i").on("click", function () { var id = this.id; var parent = this.parentNode.id; - if (debug.selectAll(".tag").size()) {debug.selectAll(".tag, .line").remove();} - if (id === "toggleHeight") {toggleHeight();} - if (id === "toggleCountries") {$('#regions').fadeToggle();} - if (id === "toggleCultures") {toggleCultures();} - if (id === "toggleOverlay") {toggleOverlay();} - if (id === "toggleFlux") {toggleFlux();} - if (parent === "mapLayers" || parent === "styleContent") {$(this).toggleClass("buttonoff");} + if (debug.selectAll(".tag").size()) { debug.selectAll(".tag, .line").remove(); } + if (id === "toggleHeight") { toggleHeight(); } + if (id === "toggleCountries") { $('#regions').fadeToggle(); } + if (id === "toggleCultures") { toggleCultures(); } + if (id === "toggleOverlay") { toggleOverlay(); } + if (id === "toggleFlux") { toggleFlux(); } + if (parent === "mapLayers" || parent === "styleContent") { $(this).toggleClass("buttonoff"); } if (id === "randomMap" || id === "regenerate") { exitCustomization(); undraw(); @@ -6096,9 +6118,9 @@ function fantasyMap() { generate(); return; } - if (id === "editCountries") {editCountries();} - if (id === "editCultures") {editCultures();} - if (id === "editScale" || id === "editScaleCountries" || id === "editScaleBurgs") {editScale();} + if (id === "editCountries") { editCountries(); } + if (id === "editCultures") { editCultures(); } + if (id === "editScale" || id === "editScaleCountries" || id === "editScaleBurgs") { editScale(); } if (id === "countriesManually") { customization = 2; tip("Click to select a country, drag the circle to re-assign", true); @@ -6107,7 +6129,7 @@ function fantasyMap() { $("#countriesBottom").children().hide(); $("#countriesManuallyButtons").show(); // highlight capital cells as it's not allowed to change capital's state that way - states.map(function(s) { + states.map(function (s) { if (s.capital === "neutral" || s.capital === "select") return; const capital = s.capital; const index = manors[capital].cell; @@ -6132,32 +6154,32 @@ function fantasyMap() { debug.selectAll(".circle").remove(); var changedCells = regions.select("#temp").selectAll("path"); var changedStates = []; - changedCells.each(function() { + changedCells.each(function () { var el = d3.select(this); var cell = +el.attr("data-cell"); var stateOld = cells[cell].region; - if (stateOld === "neutral") {stateOld = states.length - 1;} + if (stateOld === "neutral") { stateOld = states.length - 1; } var stateNew = +el.attr("data-state"); const region = states[stateNew].color === "neutral" ? "neutral" : stateNew; cells[cell].region = region; - if (cells[cell].manor !== undefined) {manors[cells[cell].manor].region = region;} + if (cells[cell].manor !== undefined) { manors[cells[cell].manor].region = region; } changedStates.push(stateNew, stateOld); }); changedStates = [...new Set(changedStates)]; - changedStates.map(function(s) {recalculateStateData(s);}); + changedStates.map(function (s) { recalculateStateData(s); }); var last = states.length - 1; if (states[last].capital === "neutral" && states[last].cells === 0) { $("#state" + last).remove(); states.splice(-1); } $("#countriesManuallyCancel").click(); - if (changedStates.length) {editCountries();} + if (changedStates.length) { editCountries(); } } if (id === "countriesManuallyCancel") { redrawRegions(); debug.selectAll(".circle").remove(); - if (grid.style("display") === "inline") {toggleGrid.click();} - if (labels.style("display") === "none") {toggleLabels.click();} + if (grid.style("display") === "inline") { toggleGrid.click(); } + if (labels.style("display") === "none") { toggleLabels.click(); } $("#countriesBottom").children().show(); $("#countriesManuallyButtons, #countriesRegenerateButtons").hide(); $(".selected").removeClass("selected"); @@ -6167,10 +6189,10 @@ function fantasyMap() { tip("", true); restoreDefaultEvents(); } - if (id === "countriesApply") {$("#countriesManuallyCancel").click();} + if (id === "countriesApply") { $("#countriesManuallyCancel").click(); } if (id === "countriesRandomize") { const mod = +powerInput.value * 2; - $(".statePower").each(function(e, i) { + $(".statePower").each(function (e, i) { const state = +(this.parentNode.id).slice(5); if (states[state].capital === "neutral") return; const power = rn(Math.random() * mod / 2 + 1, 1); @@ -6183,20 +6205,20 @@ function fantasyMap() { if (id === "countriesAddM" || id === "countriesAddR" || id === "countriesAddG") { var i = states.length; // move neutrals to the last line - if (states[i-1].capital === "neutral") {states[i-1].i = i; i -= 1;} + if (states[i - 1].capital === "neutral") { states[i - 1].i = i; i -= 1; } var name = generateStateName(0); var color = colors20(i); - states.push({i, color, name, capital: "select", cells: 0, burgs: 0, urbanPopulation: 0, ruralPopulation: 0, area: 0, power: 1}); - states.sort(function(a, b){return a.i - b.i}); + states.push({ i, color, name, capital: "select", cells: 0, burgs: 0, urbanPopulation: 0, ruralPopulation: 0, area: 0, power: 1 }); + states.sort(function (a, b) { return a.i - b.i }); editCountries(); } if (id === "countriesRegenerateNames") { const editor = d3.select("#countriesBody"); - states.forEach(function(s) { + states.forEach(function (s) { if (s.capital === "neutral") return; s.name = generateStateName(s.i); - labels.select("#regionLabel"+s.i).text(s.name); - editor.select("#state"+s.i).select(".stateName").attr("value", s.name); + labels.select("#regionLabel" + s.i).text(s.name); + editor.select("#state" + s.i).select(".stateName").attr("value", s.name); }); } if (id === "countriesPercentage") { @@ -6208,7 +6230,7 @@ function fantasyMap() { var totalArea = countriesFooterArea.innerHTML; totalArea = getInteger(totalArea.split(" ")[0]); var totalPopulation = getInteger(countriesFooterPopulation.innerHTML); - $("#countriesBody > .states").each(function() { + $("#countriesBody > .states").each(function () { var cells = rn($(this).attr("data-cells") / totalCells * 100); var burgs = rn($(this).attr("data-burgs") / totalBurgs * 100); var area = rn($(this).attr("data-area") / totalArea * 100); @@ -6224,14 +6246,14 @@ function fantasyMap() { } } if (id === "countriesExport") { - if ($(".statePower").length === 0) {return;} + if ($(".statePower").length === 0) { return; } var unit = areaUnit.value === "square" ? distanceUnit.value + "2" : areaUnit.value; - var data = "Country,Capital,Cells,Burgs,Area ("+ unit +"),Population\n"; // countries headers - $("#countriesBody > .states").each(function() { + var data = "Country,Capital,Cells,Burgs,Area (" + unit + "),Population\n"; // countries headers + $("#countriesBody > .states").each(function () { var country = $(this).attr("data-country"); - if (country === "bottom") {data += "neutral,"} else {data += country + ",";} + if (country === "bottom") { data += "neutral," } else { data += country + ","; } var capital = $(this).attr("data-capital"); - if (capital === "bottom" || capital === "select") {data += ","} else {data += capital + ",";} + if (capital === "bottom" || capital === "select") { data += "," } else { data += capital + ","; } data += $(this).attr("data-cells") + ","; data += $(this).attr("data-burgs") + ","; data += $(this).attr("data-area") + ","; @@ -6239,7 +6261,7 @@ function fantasyMap() { data += population + "\n"; }); data += "\nBurg,Country,Culture,Population\n"; // burgs headers - manors.map(function(m) { + manors.map(function (m) { if (m.region === "removed") return; // skip removed burgs data += m.name + ","; var country = m.region === "neutral" ? "neutral" : states[m.region].name; @@ -6248,27 +6270,28 @@ function fantasyMap() { var population = m.population * urbanization.value * populationRate.value * 1000; data += population + "\n"; }); - var dataBlob = new Blob([data], {type:"text/plain"}); + var dataBlob = new Blob([data], { type: "text/plain" }); var url = window.URL.createObjectURL(dataBlob); var link = document.createElement("a"); document.body.appendChild(link); link.download = "countries_data" + Date.now() + ".csv"; link.href = url; link.click(); - window.setTimeout(function() {window.URL.revokeObjectURL(url);}, 2000); + window.setTimeout(function () { window.URL.revokeObjectURL(url); }, 2000); } - if (id === "burgNamesImport") {burgsListToLoad.click();} + if (id === "burgNamesImport") { burgsListToLoad.click(); } if (id === "removeCountries") { alertMessage.innerHTML = `Are you sure you want remove all countries?`; - $("#alert").dialog({resizable: false, title: "Remove countries", + $("#alert").dialog({ + resizable: false, title: "Remove countries", buttons: { - Cancel: function() {$(this).dialog("close");}, - Remove: function() { + Cancel: function () { $(this).dialog("close"); }, + Remove: function () { $(this).dialog("close"); $("#countriesBody").empty(); - manors.map(function(m) {m.region = "neutral";}); - land.map(function(l) {l.region = "neutral";}); - states.map(function(s) { + manors.map(function (m) { m.region = "neutral"; }); + land.map(function (l) { l.region = "neutral"; }); + states.map(function (s) { const c = +s.capital; if (isNaN(c)) return; $("#burgLabels [data-id=" + c + "]").detach().appendTo($("#burgLabels #towns")); @@ -6277,9 +6300,9 @@ function fantasyMap() { labels.select("#countries").selectAll("text").remove(); regions.selectAll("path").remove(); states = []; - states.push({i: 0, color: "neutral", capital: "neutral", name: "Neutrals"}); + states.push({ i: 0, color: "neutral", capital: "neutral", name: "Neutrals" }); recalculateStateData(0); - if ($("#burgsEditor").is(":visible")) {$("#burgsEditor").dialog("close");} + if ($("#burgsEditor").is(":visible")) { $("#burgsEditor").dialog("close"); } editCountries(); } } @@ -6287,16 +6310,17 @@ function fantasyMap() { } if (id === "removeBurgs") { alertMessage.innerHTML = `Are you sure you want to remove all burgs associated with the country?`; - $("#alert").dialog({resizable: false, title: "Remove associated burgs", + $("#alert").dialog({ + resizable: false, title: "Remove associated burgs", buttons: { - Cancel: function() {$(this).dialog("close");}, - Remove: function() { + Cancel: function () { $(this).dialog("close"); }, + Remove: function () { $(this).dialog("close"); var state = +$("#burgsEditor").attr("data-state"); var region = states[state].capital === "neutral" ? "neutral" : state; $("#burgsBody").empty(); - manors.map(function(m) { - if (m.region !== region) {return;} + manors.map(function (m) { + if (m.region !== region) { return; } m.region = "removed"; cells[m.cell].manor = undefined; labels.select("[data-id='" + m.i + "']").remove(); @@ -6325,7 +6349,7 @@ function fantasyMap() { } if (id === "regenerateBurgNames") { var s = +$("#burgsEditor").attr("data-state"); - $(".burgName").each(function(e, i) { + $(".burgName").each(function (e, i) { var b = +(this.parentNode.id).slice(5); var name = generateName(manors[b].culture); $(this).val(name); @@ -6334,10 +6358,10 @@ function fantasyMap() { labels.select("[data-id='" + b + "']").text(name); }); if ($("#countriesEditor").is(":visible")) { - if (states[s].capital === "neutral") {return;} + if (states[s].capital === "neutral") { return; } var c = states[s].capital; - $("#state"+s).attr("data-capital", manors[c].name); - $("#state"+s+" > .stateCapital").val(manors[c].name); + $("#state" + s).attr("data-capital", manors[c].name); + $("#state" + s + " > .stateCapital").val(manors[c].name); } } if (id === "burgAdd") { @@ -6345,7 +6369,7 @@ function fantasyMap() { clickToAdd(); // to load on click event function $("#addBurg").click().attr("data-state", state); } - if (id === "toggleScaleBar") {$("#scaleBar").toggleClass("hidden");} + if (id === "toggleScaleBar") { $("#scaleBar").toggleClass("hidden"); } if (id === "addRuler") { $("#ruler").show(); var rulerNew = ruler.append("g").attr("class", "linear").call(d3.drag().on("start", elementDrag)); @@ -6374,26 +6398,28 @@ function fantasyMap() { return; } if (id === "removeAllRulers") { - if ($("#ruler > g").length < 1) {return;} + if ($("#ruler > g").length < 1) { return; } alertMessage.innerHTML = `Are you sure you want to remove all placed rulers?`; - $("#alert").dialog({resizable: false, title: "Remove all rulers", + $("#alert").dialog({ + resizable: false, title: "Remove all rulers", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); $("#ruler > g").remove(); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }); return; } - if (id === "editHeightmap") {$("#customizeHeightmap").slideToggle();} + if (id === "editHeightmap") { $("#customizeHeightmap").slideToggle(); } if (id === "fromScratch") { alertMessage.innerHTML = "Are you sure you want to clear the map? All progress will be lost"; - $("#alert").dialog({resizable: false, title: "Clear map", + $("#alert").dialog({ + resizable: false, title: "Clear map", buttons: { - Cancel: function() {$(this).dialog("close");}, - Clear: function() { + Cancel: function () { $(this).dialog("close"); }, + Clear: function () { closeDialogs(); undraw(); placePoints(); @@ -6412,42 +6438,43 @@ function fantasyMap() { message += "If you want to edit a map, it's better to clean up all the data except on heights. "; message += "You may also keep the data, but it can cause unexpected errors"; alertMessage.innerHTML = message; - $("#alert").dialog({resizable: false, title: "Edit Heightmap", + $("#alert").dialog({ + resizable: false, title: "Edit Heightmap", buttons: { - "Clean up": function() { + "Clean up": function () { editHeightmap("clean"); $(this).dialog("close"); }, - Keep: function() { + Keep: function () { $(this).dialog("close"); editHeightmap("keep"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }); return; } // heightmap customization buttons if (customization === 1) { - if (id === "paintBrushes") {openBrushesPanel();} + if (id === "paintBrushes") { openBrushesPanel(); } if (id === "rescaleExecute") { var subject = rescaleLower.value + "-" + rescaleHigher.value; var sign = conditionSign.value; var modifier = rescaleModifier.value; - if (sign === "×") {modifyHeights(subject, 0, +modifier);} - if (sign === "÷") {modifyHeights(subject, 0, (1 / modifier));} - if (sign === "+") {modifyHeights(subject, +modifier, 1);} - if (sign === "-") {modifyHeights(subject, (-1 * modifier), 1);} - if (sign === "^") {modifyHeights(subject, 0, "^" + modifier);} + if (sign === "×") { modifyHeights(subject, 0, +modifier); } + if (sign === "÷") { modifyHeights(subject, 0, (1 / modifier)); } + if (sign === "+") { modifyHeights(subject, +modifier, 1); } + if (sign === "-") { modifyHeights(subject, (-1 * modifier), 1); } + if (sign === "^") { modifyHeights(subject, 0, "^" + modifier); } updateHeightmap(); updateHistory(); } if (id === "rescaleButton") { $("#modifyButtons").children().not("#rescaleButton, .condition").toggle(); } - if (id === "rescaleCondButton") {$("#modifyButtons").children().not("#rescaleCondButton, #rescaler").toggle();} - if (id === "undo" || id === "templateUndo") {restoreHistory(historyStage - 1);} - if (id === "redo" || id === "templateRedo") {restoreHistory(historyStage + 1);} + if (id === "rescaleCondButton") { $("#modifyButtons").children().not("#rescaleCondButton, #rescaler").toggle(); } + if (id === "undo" || id === "templateUndo") { restoreHistory(historyStage - 1); } + if (id === "redo" || id === "templateRedo") { restoreHistory(historyStage + 1); } if (id === "smoothHeights") { smoothHeights(4); updateHeightmap(); @@ -6459,56 +6486,56 @@ function fantasyMap() { updateHistory(); } if (id === "getMap") { - if (states.length && manors.length) {getMap("keep");} else {getMap();} + if (states.length && manors.length) { getMap("keep"); } else { getMap(); } } if (id === "applyTemplate") { - if ($("#templateEditor").is(":visible")) {return;} + if ($("#templateEditor").is(":visible")) { return; } $("#templateEditor").dialog({ title: "Template Editor", minHeight: "auto", width: "auto", resizable: false, - position: {my: "right top", at: "right-10 top+10", of: "svg"} + position: { my: "right top", at: "right-10 top+10", of: "svg" } }); } - if (id === "convertImage") {convertImage();} - if (id === "convertImageGrid") {$("#grid").fadeToggle();} - if (id === "convertImageHeights") {$("#landmass").fadeToggle();} + if (id === "convertImage") { convertImage(); } + if (id === "convertImageGrid") { $("#grid").fadeToggle(); } + if (id === "convertImageHeights") { $("#landmass").fadeToggle(); } if (id === "perspectiveView") { // Inputs control - if ($("#perspectivePanel").is(":visible")) {return;} + if ($("#perspectivePanel").is(":visible")) { return; } const line = +$("#lineHandle0").attr("data-value"); const grad = +$("#lineHandle1").attr("data-value"); $("#lineSlider").slider({ min: 10, max: 320, step: 1, values: [line, grad], - create: function() { - $("#lineHandle0").text("x:"+line); - $("#lineHandle1").text("y:"+grad); + create: function () { + $("#lineHandle0").text("x:" + line); + $("#lineHandle1").text("y:" + grad); }, - slide: function(event, ui) { - $("#lineHandle0").text("x:"+ui.values[0]).attr("data-value", ui.values[0]); - $("#lineHandle1").text("y:"+ui.values[1]).attr("data-value", ui.values[1]); + slide: function (event, ui) { + $("#lineHandle0").text("x:" + ui.values[0]).attr("data-value", ui.values[0]); + $("#lineHandle1").text("y:" + ui.values[1]).attr("data-value", ui.values[1]); drawPerspective(); } }); $("#ySlider").slider({ min: 1, max: 5, step: 0.1, value: +$("#yHandle").attr("data-value"), - create: function() {$("#yHandle").text($("#yHandle").attr("data-value"));}, - slide: function(event, ui) { + create: function () { $("#yHandle").text($("#yHandle").attr("data-value")); }, + slide: function (event, ui) { $("#yHandle").text(ui.value).attr("data-value", ui.value); drawPerspective(); } }); $("#scaleSlider").slider({ min: 0.5, max: 2, step: 0.1, value: +$("#scaleHandle").attr("data-value"), - create: function() {$("#scaleHandle").text($("#scaleHandle").attr("data-value"));}, - slide: function(event, ui) { + create: function () { $("#scaleHandle").text($("#scaleHandle").attr("data-value")); }, + slide: function (event, ui) { $("#scaleHandle").text(ui.value).attr("data-value", ui.value); drawPerspective(); } }); $("#heightSlider").slider({ min: 1, max: 50, step: 1, value: +$("#heightHandle").attr("data-value"), - create: function() {$("#heightHandle").text($("#heightHandle").attr("data-value"));}, - slide: function(event, ui) { + create: function () { $("#heightHandle").text($("#heightHandle").attr("data-value")); }, + slide: function (event, ui) { $("#heightHandle").text(ui.value).attr("data-value", ui.value); drawPerspective(); } @@ -6516,7 +6543,7 @@ function fantasyMap() { $("#perspectivePanel").dialog({ title: "Perspective View", width: 520, height: 360, - position: {my: "center center", at: "center center", of: "svg"} + position: { my: "center center", at: "center center", of: "svg" } }); drawPerspective(); return; @@ -6524,13 +6551,14 @@ function fantasyMap() { } if (id === "restoreStyle") { alertMessage.innerHTML = "Are you sure you want to restore default style?"; - $("#alert").dialog({resizable: false, title: "Restore style", + $("#alert").dialog({ + resizable: false, title: "Restore style", buttons: { - Restore: function() { + Restore: function () { applyDefaultStyle(); $(this).dialog("close"); }, - Cancel: function() { + Cancel: function () { $(this).dialog("close"); } } @@ -6559,26 +6587,26 @@ function fantasyMap() { zoomExtentMax.value = 20; zoom.scaleExtent([1, 20]).scaleTo(svg, 1); } - if (id === "saveButton") {$("#saveDropdown").slideToggle();} - if (id === "loadMap") {mapToLoad.click();} - if (id === "zoomReset") {resetZoom(1000);} + if (id === "saveButton") { $("#saveDropdown").slideToggle(); } + if (id === "loadMap") { mapToLoad.click(); } + if (id === "zoomReset") { resetZoom(1000); } if (id === "zoomPlus") { scale += 1; - if (scale > 40) {scale = 40;} + if (scale > 40) { scale = 40; } invokeActiveZooming(); } if (id === "zoomMinus") { scale -= 1; - if (scale <= 1) {scale = 1; viewX = 0; viewY = 0;} + if (scale <= 1) { scale = 1; viewX = 0; viewY = 0; } invokeActiveZooming(); } if (id === "styleFontPlus" || id === "styleFontMinus") { - var el = viewbox.select("#"+styleElementSelect.value); + var el = viewbox.select("#" + styleElementSelect.value); var mod = id === "styleFontPlus" ? 1.1 : 0.9; - el.selectAll("g").each(function() { + el.selectAll("g").each(function () { var el = d3.select(this); var size = rn(el.attr("data-size") * mod, 2); - if (size < 2) {size = 2;} + if (size < 2) { size = 2; } el.attr("data-size", size).attr("font-size", rn((size + (size / scale)) / 2, 2)); }); invokeActiveZooming(); @@ -6588,22 +6616,23 @@ function fantasyMap() { if (customization === 1) { var message = "Are you sure you want to clear the map?"; alertMessage.innerHTML = message; - $("#alert").dialog({resizable: false, title: "Clear map", + $("#alert").dialog({ + resizable: false, title: "Clear map", buttons: { - Clear: function() { + Clear: function () { $(this).dialog("close"); viewbox.style("cursor", "crosshair").call(drag); landmassCounter.innerHTML = "0"; $("#landmass").empty(); - cells.map(function(i) {i.height = 0;}); + cells.map(function (i) { i.height = 0; }); // clear history history = []; historyStage = 0; updateHistory(); redo.disabled = templateRedo.disabled = true; - undo.disabled = templateUndo.disabled = true; + undo.disabled = templateUndo.disabled = true; }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }); } else { @@ -6611,30 +6640,30 @@ function fantasyMap() { } } if (id === "templateComplete") { - if (customization === 1 && !$("#getMap").attr("disabled")) {getMap();} + if (customization === 1 && !$("#getMap").attr("disabled")) { getMap(); } } if (id === "convertColorsMinus") { var current = +convertColors.value - 1; - if (current < 4) {current = 3;} + if (current < 4) { current = 3; } convertColors.value = current; heightsFromImage(current); } if (id === "convertColorsPlus") { var current = +convertColors.value + 1; - if (current > 255) {current = 256;} + if (current > 255) { current = 256; } convertColors.value = current; heightsFromImage(current); } if (id === "convertOverlayButton") { $("#convertImageButtons").children().not(this).not("#convertColors").toggle(); } - if (id === "convertAutoLum") {autoAssing("lum");} - if (id === "convertAutoHue") {autoAssing("hue");} - if (id === "convertComplete") {completeConvertion();} + if (id === "convertAutoLum") { autoAssing("lum"); } + if (id === "convertAutoHue") { autoAssing("hue"); } + if (id === "convertComplete") { completeConvertion(); } }); // support save options - $("#saveDropdown > div").click(function() { + $("#saveDropdown > div").click(function () { var id = this.id; var dns_allow_popup_message = localStorage.getItem("dns_allow_popup_message"); if (!dns_allow_popup_message) { @@ -6642,32 +6671,33 @@ function fantasyMap() { message += "Please ensure your browser does not block popups. "; message += "Please check browser settings and turn off adBlocker if it is enabled"; alertMessage.innerHTML = message; - $("#alert").dialog({title: "File saver. Please enable popups!", + $("#alert").dialog({ + title: "File saver. Please enable popups!", buttons: { - "Don't show again": function() { + "Don't show again": function () { localStorage.setItem("dns_allow_popup_message", true); $(this).dialog("close"); }, - Close: function() {$(this).dialog("close");} + Close: function () { $(this).dialog("close"); } }, - position: {my: "center", at: "center", of: "svg"} + position: { my: "center", at: "center", of: "svg" } }); } - if (id === "saveMap") {saveMap();} - if (id === "saveSVG") {saveAsImage("svg");} - if (id === "savePNG") {saveAsImage("png");} + if (id === "saveMap") { saveMap(); } + if (id === "saveSVG") { saveAsImage("svg"); } + if (id === "savePNG") { saveAsImage("png"); } $("#saveDropdown").slideUp("fast"); }); // lock / unlock option randomization - $("#options i[class^='icon-lock']").click(function() { + $("#options i[class^='icon-lock']").click(function () { $(this).toggleClass("icon-lock icon-lock-open"); const locked = +$(this).hasClass("icon-lock"); $(this).attr("data-locked", locked); const option = (this.id).slice(4, -5).toLowerCase(); - const value = $("#"+option+"Input").val(); - if (locked) {localStorage.setItem(option, value);} - else {localStorage.removeItem(option);} + const value = $("#" + option + "Input").val(); + if (locked) { localStorage.setItem(option, value); } + else { localStorage.removeItem(option); } }); function editHeightmap(type) { @@ -6687,7 +6717,7 @@ function fantasyMap() { calculateVoronoi(points); detectNeighbors("grid"); drawScaleBar(); - for (let i = 0; i < points.length; i++) {cells[i].height = heights[i];} + for (let i = 0; i < points.length; i++) { cells[i].height = heights[i]; } if (type === "keep") { svg.selectAll("#lakes, #coastline, #terrain, #rivers, #grid, #terrs, #landmass, #ocean, #regions") .selectAll("path, circle, line").remove(); @@ -6703,12 +6733,12 @@ function fantasyMap() { } function openBrushesPanel() { - if ($("#brushesPanel").is(":visible")) {return;} + if ($("#brushesPanel").is(":visible")) { return; } $("#brushesPanel").dialog({ title: "Paint Brushes", minHeight: 40, width: "auto", maxWidth: 200, resizable: false, - position: {my: "right top", at: "right-10 top+10", of: "svg"} - }).on('dialogclose', function() { + position: { my: "right top", at: "right-10 top+10", of: "svg" } + }).on('dialogclose', function () { restoreDefaultEvents(); $("#brushesButtons > .pressed").removeClass('pressed'); }); @@ -6716,7 +6746,7 @@ function fantasyMap() { if (modules.openBrushesPanel) return; modules.openBrushesPanel = true; - $("#brushesButtons > button").on("click", function() { + $("#brushesButtons > button").on("click", function () { const rSlider = $("#brushRadiusLabel, #brushRadius"); debug.selectAll(".circle, .tag, .line").remove(); if ($(this).hasClass('pressed')) { @@ -6728,10 +6758,10 @@ function fantasyMap() { $(this).addClass('pressed'); viewbox.style("cursor", "crosshair"); const id = this.id; - if (id === "brushRange" || id === "brushTrough") {viewbox.on("click", placeLinearFeature);} // on click brushes - else {viewbox.call(drag).on("click", null);} // on drag brushes - if ($(this).hasClass("feature")) {rSlider.attr("disabled", true).addClass("disabled");} - else {rSlider.attr("disabled", false).removeClass("disabled");} + if (id === "brushRange" || id === "brushTrough") { viewbox.on("click", placeLinearFeature); } // on click brushes + else { viewbox.call(drag).on("click", null); } // on drag brushes + if ($(this).hasClass("feature")) { rSlider.attr("disabled", true).addClass("disabled"); } + else { rSlider.attr("disabled", false).removeClass("disabled"); } } }); } @@ -6754,7 +6784,7 @@ function fantasyMap() { while (j--) { const y = j / lineGranularity * height | 0; let h = getHeightInPoint(x * wRatio, y * hRatio) - 0.2; - if (h < 0) {h = 0;} + if (h < 0) { h = 0; } canvasPoints.push([x, y, h]); } } @@ -6768,7 +6798,7 @@ function fantasyMap() { pContext.moveTo(...transformPt(pt1)); pContext.lineTo(...transformPt(pt2)); let clr = "rgb(81, 103, 169)"; // water - if (avHeight !== 0) {clr = color(1 - avHeight - 0.2);} + if (avHeight !== 0) { clr = color(1 - avHeight - 0.2); } pContext.strokeStyle = clr; pContext.stroke(); } @@ -6796,12 +6826,12 @@ function fantasyMap() { } // templateEditor Button handlers - $("#templateTools > button").on("click", function() { + $("#templateTools > button").on("click", function () { var id = this.id; id = id.replace("template", ""); if (id === "Mountain") { var steps = $("#templateBody > div").length; - if (steps > 0) {return;} + if (steps > 0) { return; } } $("#templateBody").attr("data-changed", 1); $("#templateBody").append('
' + id + '
'); @@ -6828,9 +6858,9 @@ function fantasyMap() { var count = ''; } el.append(''); - $("#templateBody .icon-trash-empty").on("click", function() {$(this).parent().remove();}); - if (dist) {el.append(dist);} - if (count) {el.append(count);} + $("#templateBody .icon-trash-empty").on("click", function () { $(this).parent().remove(); }); + if (dist) { el.append(dist); } + if (count) { el.append(count); } el.find("select.templateElDist").on("input", fireTemplateElDist); $("#templateBody").attr("data-changed", 1); }); @@ -6847,19 +6877,20 @@ function fantasyMap() { } // templateSelect on change listener - $("#templateSelect").on("input", function() { + $("#templateSelect").on("input", function () { var steps = $("#templateBody > div").length; var changed = +$("#templateBody").attr("data-changed"); var template = this.value; if (steps && changed === 1) { alertMessage.innerHTML = "Are you sure you want to change the base template? All the changes will be lost."; - $("#alert").dialog({resizable: false, title: "Change Template", + $("#alert").dialog({ + resizable: false, title: "Change Template", buttons: { - Change: function() { + Change: function () { changeTemplate(template); $(this).dialog("close"); }, - Cancel: function() { + Cancel: function () { var prev = $("#templateSelect").attr("data-prev"); $("#templateSelect").val(prev); $(this).dialog("close"); @@ -6867,7 +6898,7 @@ function fantasyMap() { } }); } - if (steps === 0 || changed === 0) {changeTemplate(template);} + if (steps === 0 || changed === 0) { changeTemplate(template); } }); function changeTemplate(template) { @@ -6934,17 +6965,17 @@ function fantasyMap() { // interprete template function function addStep(feature, count, dist) { - if (!feature) {return;} - if (feature === "Mountain") {templateMountain.click();} - if (feature === "Hill") {templateHill.click();} - if (feature === "Pit") {templatePit.click();} - if (feature === "Range") {templateRange.click();} - if (feature === "Trough") {templateTrough.click();} - if (feature === "Strait") {templateStrait.click();} - if (feature === "Add") {templateAdd.click();} - if (feature === "Multiply") {templateMultiply.click();} - if (feature === "Smooth") {templateSmooth.click();} - if (count) {$("#templateBody div:last-child .templateElCount").val(count);} + if (!feature) { return; } + if (feature === "Mountain") { templateMountain.click(); } + if (feature === "Hill") { templateHill.click(); } + if (feature === "Pit") { templatePit.click(); } + if (feature === "Range") { templateRange.click(); } + if (feature === "Trough") { templateTrough.click(); } + if (feature === "Strait") { templateStrait.click(); } + if (feature === "Add") { templateAdd.click(); } + if (feature === "Multiply") { templateMultiply.click(); } + if (feature === "Smooth") { templateSmooth.click(); } + if (count) { $("#templateBody div:last-child .templateElCount").val(count); } if (dist) { if (dist !== "land") { var option = ''; @@ -6955,14 +6986,14 @@ function fantasyMap() { } // Execute custom template - $("#templateRun").on("click", function() { - if (customization !== 1) {return;} + $("#templateRun").on("click", function () { + if (customization !== 1) { return; } var steps = $("#templateBody > div").length; - if (steps) {cells.map(function(i) {i.height = 0;});} - for (var step=1; step <= steps; step++) { + if (steps) { cells.map(function (i) { i.height = 0; }); } + for (let step = 1; step <= steps; step++) { var element = $("#templateBody div:nth-child(" + step + ")"); var type = element.attr("data-type"); - if (type === "Mountain") {addMountain(); continue;} + if (type === "Mountain") { addMountain(); continue; } var count = $("#templateBody div:nth-child(" + step + ") .templateElCount").val(); var dist = $("#templateBody div:nth-child(" + step + ") .templateElDist").val(); if (count) { @@ -6973,32 +7004,32 @@ function fantasyMap() { count = +count; // parse string } } - if (type === "Hill") {addHill(count, +dist);} - if (type === "Pit") {addPit(count);} - if (type === "Range") {addRange(count);} - if (type === "Trough") {addRange(-1 * count);} - if (type === "Strait") {addStrait(count);} - if (type === "Add") {modifyHeights(dist, count, 1);} - if (type === "Multiply") {modifyHeights(dist, 0, count);} - if (type === "Smooth") {smoothHeights(count);} + if (type === "Hill") { addHill(count, +dist); } + if (type === "Pit") { addPit(count); } + if (type === "Range") { addRange(count); } + if (type === "Trough") { addRange(-1 * count); } + if (type === "Strait") { addStrait(count); } + if (type === "Add") { modifyHeights(dist, count, 1); } + if (type === "Multiply") { modifyHeights(dist, 0, count); } + if (type === "Smooth") { smoothHeights(count); } } - if (steps) {mockHeightmap(); updateHistory();} + if (steps) { mockHeightmap(); updateHistory(); } }); // Save custom template as text file - $("#templateSave").on("click", function() { + $("#templateSave").on("click", function () { var steps = $("#templateBody > div").length; var stepsData = ""; - for (var step=1; step <= steps; step++) { + for (let step = 1; step <= steps; step++) { var element = $("#templateBody div:nth-child(" + step + ")"); var type = element.attr("data-type"); var count = $("#templateBody div:nth-child(" + step + ") .templateElCount").val(); var dist = $("#templateBody div:nth-child(" + step + ") .templateElDist").val(); - if (!count) {count = "0";} - if (!dist) {dist = "0";} + if (!count) { count = "0"; } + if (!dist) { dist = "0"; } stepsData += type + " " + count + " " + dist + "\r\n"; } - var dataBlob = new Blob([stepsData], {type:"text/plain"}); + var dataBlob = new Blob([stepsData], { type: "text/plain" }); var url = window.URL.createObjectURL(dataBlob); var link = document.createElement("a"); link.download = "template_" + Date.now() + ".txt"; @@ -7008,12 +7039,12 @@ function fantasyMap() { }); // Load custom template as text file - $("#templateLoad").on("click", function() {templateToLoad.click();}); - $("#templateToLoad").change(function() { + $("#templateLoad").on("click", function () { templateToLoad.click(); }); + $("#templateToLoad").change(function () { var fileToLoad = this.files[0]; this.value = ""; var fileReader = new FileReader(); - fileReader.onload = function(fileLoadedEvent) { + fileReader.onload = function (fileLoadedEvent) { var dataLoaded = fileLoadedEvent.target.result; var data = dataLoaded.split("\r\n"); $("#templateBody").empty(); @@ -7021,7 +7052,7 @@ function fantasyMap() { $("#templateBody").attr("data-changed", 1); $("#templateSelect").attr("data-prev", "templateCustom").val("templateCustom"); } - for (var i=0; i < data.length; i++) { + for (let i = 0; i < data.length; i++) { var line = data[i].split(" "); addStep(line[0], line[1], line[2]); } @@ -7038,26 +7069,27 @@ function fantasyMap() { restoreDefaultEvents(); var div = d3.select("#colorScheme"); if (div.selectAll("*").size() === 0) { - for (var i = 0; i <= 100; i++) { + for (let i = 0; i <= 100; i++) { var width = i < 20 || i > 70 ? "1px" : "3px"; - if (i === 0) {width = "4px";} - var clr = color(1-i/100); + if (i === 0) { width = "4px"; } + var clr = color(1 - i / 100); var style = "background-color: " + clr + "; width: " + width; - div.append("div").attr("data-color", i/100).attr("style", style); + div.append("div").attr("data-color", i / 100).attr("style", style); } div.selectAll("*").on("touchmove mousemove", showHeight).on("click", assignHeight); } - if ($("#imageConverter").is(":visible")) {return;} + if ($("#imageConverter").is(":visible")) { return; } $("#imageConverter").dialog({ title: "Image to Heightmap Converter", minHeight: 30, width: 260, resizable: false, - position: {my: "right top", at: "right-10 top+10", of: "svg"}}) - .on('dialogclose', function() {completeConvertion();}); + position: { my: "right top", at: "right-10 top+10", of: "svg" } + }) + .on('dialogclose', function () { completeConvertion(); }); } // Load image to convert - $("#convertImageLoad").on("click", function() {imageToLoad.click();}); - $("#imageToLoad").change(function() { + $("#convertImageLoad").on("click", function () { imageToLoad.click(); }); + $("#imageToLoad").change(function () { console.time("loadImage"); // set style resetZoom(); @@ -7068,12 +7100,12 @@ function fantasyMap() { var reader = new FileReader(); var img = new Image; // draw image - img.onload = function() { + img.onload = function () { ctx.drawImage(img, 0, 0, svgWidth, svgHeight); heightsFromImage(+convertColors.value); console.timeEnd("loadImage"); } - reader.onloadend = function() {img.src = reader.result;} + reader.onloadend = function () { img.src = reader.result; } reader.readAsDataURL(file); }); @@ -7084,27 +7116,27 @@ function fantasyMap() { $("#landmass, #colorsUnassigned").fadeIn(); $("#colorsAssigned").fadeOut(); var colors = [], palette = []; - points.map(function(i) { + points.map(function (i) { var x = rn(i[0]), y = rn(i[1]); - if (y == svgHeight) {y--;} - if (x == svgWidth) {x--;} + if (y == svgHeight) { y--; } + if (x == svgWidth) { x--; } var p = (x + y * svgWidth) * 4; var r = data[p], g = data[p + 1], b = data[p + 2]; colors.push([r, g, b]); }); var cmap = MMCQ.quantize(colors, count); - polygons.map(function(i, d) { + polygons.map(function (i, d) { cells[d].height = undefined; var nearest = cmap.nearest(colors[d]); var rgb = "rgb(" + nearest[0] + ", " + nearest[1] + ", " + nearest[2] + ")"; var hex = toHEX(rgb); - if (palette.indexOf(hex) === -1) {palette.push(hex);} + if (palette.indexOf(hex) === -1) { palette.push(hex); } landmass.append("path") .attr("d", "M" + i.join("L") + "Z").attr("data-i", d) .attr("fill", hex).attr("stroke", hex); }); landmass.selectAll("path").on("click", landmassClicked); - palette.sort(function(a, b) {return d3.lab(a).b - d3.lab(b).b;}).map(function(i) { + palette.sort(function (a, b) { return d3.lab(a).b - d3.lab(b).b; }).map(function (i) { $("#colorsUnassigned").append('
'); }); $(".color-div").click(selectColor); @@ -7112,7 +7144,7 @@ function fantasyMap() { function landmassClicked() { var color = d3.select(this).attr("fill"); - $("#"+color.slice(1)).click(); + $("#" + color.slice(1)).click(); } function selectColor() { @@ -7147,13 +7179,13 @@ function fantasyMap() { function assignHeight() { var sel = $(".selectedColor")[0]; var height = +d3.select(this).attr("data-color"); - var rgb = color(1-height); + var rgb = color(1 - height); var hex = toHEX(rgb); sel.style.backgroundColor = rgb; sel.setAttribute("data-height", height); var cur = "#" + sel.id; sel.id = hex.substr(1); - landmass.selectAll(".selectedCell").each(function() { + landmass.selectAll(".selectedCell").each(function () { d3.select(this).attr("fill", hex).attr("stroke", hex); var i = +d3.select(this).attr("data-i"); cells[i].height = height; @@ -7162,22 +7194,22 @@ function fantasyMap() { if (parent.id === "colorsUnassigned") { colorsAssigned.appendChild(sel); $("#colorsAssigned").fadeIn(); - if ($("#colorsUnassigned .color-div").length < 1) {$("#colorsUnassigned").fadeOut();} + if ($("#colorsUnassigned .color-div").length < 1) { $("#colorsUnassigned").fadeOut(); } } - if ($("#colorsAssigned .color-div").length > 1) {sortAssignedColors();} + if ($("#colorsAssigned .color-div").length > 1) { sortAssignedColors(); } } // sort colors based on assigned height function sortAssignedColors() { var data = []; var colors = d3.select("#colorsAssigned").selectAll(".color-div"); - colors.each(function(d) { + colors.each(function (d) { var id = d3.select(this).attr("id"); var height = +d3.select(this).attr("data-height"); - data.push({id, height}); + data.push({ id, height }); }); - data.sort(function(a, b) {return a.height - b.height}).map(function(i) { - $("#colorsAssigned").append($("#"+i.id)); + data.sort(function (a, b) { return a.height - b.height }).map(function (i) { + $("#colorsAssigned").append($("#" + i.id)); }); } @@ -7189,10 +7221,10 @@ function fantasyMap() { $("#colorsAssigned").fadeIn(); $("#colorsUnassigned").fadeOut(); var heights = []; - polygons.map(function(i, d) { + polygons.map(function (i, d) { var x = rn(i.data[0]), y = rn(i.data[1]); - if (y == svgHeight) {y--;} - if (x == svgWidth) {x--;} + if (y == svgHeight) { y--; } + if (x == svgWidth) { x--; } var p = (x + y * svgWidth) * 4; var r = data[p], g = data[p + 1], b = data[p + 2]; var lab = d3.lab("rgb(" + r + ", " + g + ", " + b + ")"); @@ -7207,9 +7239,9 @@ function fantasyMap() { cells[d].height = normalized; landmass.append("path").attr("d", "M" + i.join("L") + "Z").attr("data-i", d).attr("fill", hex).attr("stroke", hex); }); - heights.sort(function(a, b) {return a - b;}); + heights.sort(function (a, b) { return a - b; }); var unique = [...new Set(heights)]; - unique.map(function(i) { + unique.map(function (i) { var rgb = color(1 - i); var hex = toHEX(rgb); $("#colorsAssigned").append('
'); @@ -7219,8 +7251,8 @@ function fantasyMap() { function normalize(val, min, max) { var normalized = (val - min) / (max - min); - if (normalized < 0) {normalized = 0;} - if (normalized > 1) {normalized = 1;} + if (normalized < 0) { normalized = 0; } + if (normalized > 1) { normalized = 1; } return normalized; } @@ -7268,7 +7300,7 @@ function fantasyMap() { $('#grid').empty().fadeOut(); $('#toggleGrid').addClass("buttonoff"); restoreDefaultEvents(); - if (!$("#toggleHeight").hasClass("buttonoff")) {toggleHeight();} + if (!$("#toggleHeight").hasClass("buttonoff")) { toggleHeight(); } closeDialogs(); history = []; historyStage = 0; @@ -7286,9 +7318,9 @@ function fantasyMap() { $("#countriesBody").empty(); $("#countriesHeader").children().removeClass("icon-sort-name-up icon-sort-name-down icon-sort-number-up icon-sort-number-down"); var totalArea = 0, totalBurgs = 0, unit, areaConv; - if (areaUnit.value === "square") {unit = " " + distanceUnit.value + "²";} else {unit = " " + areaUnit.value;} + if (areaUnit.value === "square") { unit = " " + distanceUnit.value + "²"; } else { unit = " " + areaUnit.value; } var totalPopulation = 0; - for (var s = 0; s < states.length; s++) { + for (let s = 0; s < states.length; s++) { $("#countriesBody").append('
'); var el = $("#countriesBody div:last-child"); var burgsCount = states[s].burgs; @@ -7302,7 +7334,7 @@ function fantasyMap() { var population = (urban + rural) * 1000; totalPopulation += population; var populationConv = si(population); - var title = '\'Total population: '+populationConv+'; Rural population: '+rural+'K; Urban population: '+urban+'K\''; + var title = '\'Total population: ' + populationConv + '; Rural population: ' + rural + 'K; Urban population: ' + urban + 'K\''; var neutral = states[s].color === "neutral" || states[s].capital === "neutral"; // append elements to countriesBody if (!neutral) { @@ -7347,9 +7379,9 @@ function fantasyMap() { $("#countriesEditor").dialog({ title: "Countries Editor", minHeight: "auto", minWidth: Math.min(svgWidth, 390), - position: {my: "right top", at: "right-10 top+10", of: "svg"} - }).on("dialogclose", function() { - if (customization === 2 || customization === 3) {$("#countriesManuallyCancel").click()}; + position: { my: "right top", at: "right-10 top+10", of: "svg" } + }).on("dialogclose", function () { + if (customization === 2 || customization === 3) { $("#countriesManuallyCancel").click() }; }); } // restore customization Editor version @@ -7362,22 +7394,22 @@ function fantasyMap() { } // populate total line on footer countriesFooterCountries.innerHTML = states.length; - if (states[states.length-1].capital === "neutral") {countriesFooterCountries.innerHTML = states.length - 1;} + if (states[states.length - 1].capital === "neutral") { countriesFooterCountries.innerHTML = states.length - 1; } countriesFooterBurgs.innerHTML = totalBurgs; countriesFooterArea.innerHTML = si(totalArea) + unit; countriesFooterPopulation.innerHTML = si(totalPopulation); // handle events - $(".enlange").click(function() { + $(".enlange").click(function () { var s = +(this.parentNode.id).slice(5); var capital = states[s].capital; - var l = labels.select("[data-id='" + capital +"']"); + var l = labels.select("[data-id='" + capital + "']"); var x = +l.attr("x"), y = +l.attr("y"); zoomTo(x, y, 8, 1600); }); - $(".stateName").on("input", function() { + $(".stateName").on("input", function () { var s = +(this.parentNode.id).slice(5); states[s].name = this.value; - labels.select("#regionLabel"+s).text(this.value); + labels.select("#regionLabel" + s).text(this.value); if ($("#burgsEditor").is(":visible")) { if ($("#burgsEditor").attr("data-state") == s) { var color = ''; @@ -7385,41 +7417,41 @@ function fantasyMap() { } } }).hover(focusStates, unfocus); - $(".states > .stateColor").on("change", function() { + $(".states > .stateColor").on("change", function () { var s = +(this.parentNode.id).slice(5); states[s].color = this.value; - regions.selectAll(".region"+s).attr("fill", this.value).attr("stroke", this.value); + regions.selectAll(".region" + s).attr("fill", this.value).attr("stroke", this.value); if ($("#burgsEditor").is(":visible")) { if ($("#burgsEditor").attr("data-state") == s) { $(".ui-dialog-title > .stateColor").val(this.value); } } }); - $(".stateCapital").on("input", function() { + $(".stateCapital").on("input", function () { var s = +(this.parentNode.id).slice(5); var capital = states[s].capital; manors[capital].name = this.value; - labels.select("[data-id='" + capital +"']").text(this.value); + labels.select("[data-id='" + capital + "']").text(this.value); if ($("#burgsEditor").is(":visible")) { if ($("#burgsEditor").attr("data-state") == s) { - $("#burgs"+capital+" > .burgName").val(this.value); + $("#burgs" + capital + " > .burgName").val(this.value); } } }).hover(focusCapital, unfocus); $(".stateBurgs, .stateBIcon").on("click", editBurgs).hover(focusBurgs, unfocus); - $("#countriesBody > .states").on("click", function() { + $("#countriesBody > .states").on("click", function () { if (customization === 2) { $(".selected").removeClass("selected"); $(this).addClass("selected"); const state = +$(this).attr("id").slice(5); let color = states[state].color; - if (color === "neutral") {color = "white";} + if (color === "neutral") { color = "white"; } if (debug.selectAll(".circle").size()) debug.selectAll(".circle").attr("stroke", color); } }); - $(".selectCapital").on("click", function() { + $(".selectCapital").on("click", function () { if ($(this).hasClass("pressed")) { $(this).removeClass("pressed"); tooltip.setAttribute("data-main", ""); @@ -7442,7 +7474,7 @@ function fantasyMap() { } var state = +$(".selectCapital.pressed").attr("id").replace("selectCapital", ""); var oldState = cells[index].region; - if (oldState === "neutral") {oldState = states.length - 1;} + if (oldState === "neutral") { oldState = states.length - 1; } if (cells[index].manor !== undefined) { // cell has burg var burg = cells[index].manor; @@ -7453,7 +7485,7 @@ function fantasyMap() { // make this burg a new capital var urbanFactor = 0.9; // for old neutrals manors[burg].region = state; - if (oldState === "neutral") {manors[burg].population *= (1 / urbanFactor);} + if (oldState === "neutral") { manors[burg].population *= (1 / urbanFactor); } manors[burg].population *= 2; // give capital x2 population bonus states[state].capital = burg; $("#burgLabels [data-id=" + burg + "]").detach().appendTo($("#burgLabels #capitals")); @@ -7468,19 +7500,19 @@ function fantasyMap() { cells[index].manor = i; states[state].capital = i; var score = cells[index].score; - if (score <= 0) {score = rn(Math.random(), 2);} - if (cells[index].crossroad) {score += cells[index].crossroad;} // crossroads - if (cells[index].confluence) {score += Math.pow(cells[index].confluence, 0.3);} // confluences - if (cells[index].port !== undefined) {score *= 3;} // port-capital + if (score <= 0) { score = rn(Math.random(), 2); } + if (cells[index].crossroad) { score += cells[index].crossroad; } // crossroads + if (cells[index].confluence) { score += Math.pow(cells[index].confluence, 0.3); } // confluences + if (cells[index].port !== undefined) { score *= 3; } // port-capital var population = rn(score, 1); - manors.push({i, cell:index, x, y, region: state, culture, name, population}); + manors.push({ i, cell: index, x, y, region: state, culture, name, population }); burgIcons.select("#capitals").append("circle").attr("data-id", i).attr("cx", x).attr("cy", y).attr("r", 1).on("click", editBurg); burgLabels.select("#capitals").append("text").attr("data-id", i).attr("x", x).attr("y", y).attr("dy", "-0.35em").text(name).on("click", editBurg); } cells[index].region = state; - cells[index].neighbors.map(function(n) { - if (cells[n].height < 0.2) {return;} - if (cells[n].manor !== undefined) {return;} + cells[index].neighbors.map(function (n) { + if (cells[n].height < 0.2) { return; } + if (cells[n].manor !== undefined) { return; } cells[n].region = state; }); redrawRegions(); @@ -7491,12 +7523,12 @@ function fantasyMap() { tip("", true); } - $(".statePower").on("input", function() { + $(".statePower").on("input", function () { var s = +(this.parentNode.id).slice(5); states[s].power = +this.value; regenerateCountries(); }); - $(".statePopulation").on("change", function() { + $(".statePopulation").on("change", function () { var s = +(this.parentNode.id).slice(5); var popOr = +$(this).parent().attr("data-population"); var popNew = getInteger(this.value); @@ -7508,44 +7540,46 @@ function fantasyMap() { states[s].urbanPopulation = rn(states[s].urbanPopulation * change, 2); states[s].ruralPopulation = rn(states[s].ruralPopulation * change, 2); var urban = rn(states[s].urbanPopulation * urbanization.value * populationRate.value); - var rural = rn(states[s].ruralPopulation * populationRate.value); + var rural = rn(states[s].ruralPopulation * populationRate.value); var population = (urban + rural) * 1000; $(this).parent().attr("data-population", population); this.value = si(population); var total = 0; - $("#countriesBody > div").each(function(e, i) { + $("#countriesBody > div").each(function (e, i) { total += +$(this).attr("data-population"); }); countriesFooterPopulation.innerHTML = si(total); - if (states[s].capital === "neutral") {s = "neutral";} - manors.map(function(m) { - if (m.region !== s) {return;} + if (states[s].capital === "neutral") { s = "neutral"; } + manors.map(function (m) { + if (m.region !== s) { return; } m.population = rn(m.population * change, 2); }); }); // fully remove country - $("#countriesBody .icon-trash-empty").on("click", function() { + $("#countriesBody .icon-trash-empty").on("click", function () { var s = +(this.parentNode.id).slice(5); if (states[s].capital === "select") { removeCountry(s); return; } alertMessage.innerHTML = `Are you sure you want to remove the country?`; - $("#alert").dialog({resizable: false, title: "Remove country", buttons: { - Remove: function() { - removeCountry(s); - $(this).dialog("close"); - }, - Cancel: function() {$(this).dialog("close");} - }}); + $("#alert").dialog({ + resizable: false, title: "Remove country", buttons: { + Remove: function () { + removeCountry(s); + $(this).dialog("close"); + }, + Cancel: function () { $(this).dialog("close"); } + } + }); }); function removeCountry(s) { const cellsCount = states[s].cells; const capital = states[s].capital; states.splice(s, 1); - states.map(function(s, i) {s.i = i;}); - cells.map(function(c) { + states.map(function (s, i) { s.i = i; }); + cells.map(function (c) { if (c.region === s) c.region = "neutral"; else if (c.region > s) c.region -= 1; }); @@ -7554,16 +7588,16 @@ function fantasyMap() { // change capital to burg $("#burgLabels [data-id=" + capital + "]").detach().appendTo($("#burgLabels #towns")); $("#burgIcons [data-id=" + capital + "]").detach().appendTo($("#burgIcons #towns")); - var burgsSelection = $.grep(manors, function(e) {return (e.region === s);}); + var burgsSelection = $.grep(manors, function (e) { return (e.region === s); }); var urbanFactor = 0.9; - burgsSelection.map(function(b) { - if (b.i === capital) {b.population *= 0.5;} + burgsSelection.map(function (b) { + if (b.i === capital) { b.population *= 0.5; } b.population *= urbanFactor; b.region = "neutral"; }); // re-calculate neutral data - if (states[states.length-1].capital !== "neutral") { - states.push({i: states.length, color: "neutral", name: "Neutrals", capital: "neutral"}); + if (states[states.length - 1].capital !== "neutral") { + states.push({ i: states.length, color: "neutral", name: "Neutrals", capital: "neutral" }); } recalculateStateData(states.length - 1); // re-calc data for neutrals redrawRegions(); @@ -7576,14 +7610,14 @@ function fantasyMap() { // burgs list + editor function editBurgs(context, s) { - if (s === undefined) {s = +(this.parentNode.id).slice(5);} + if (s === undefined) { s = +(this.parentNode.id).slice(5); } $("#burgsEditor").attr("data-state", s); $("#burgsBody").empty(); $("#burgsHeader").children().removeClass("icon-sort-name-up icon-sort-name-down icon-sort-number-up icon-sort-number-down"); var region = states[s].capital === "neutral" ? "neutral" : s; - var burgs = $.grep(manors, function(e) {return (e.region === region);}); + var burgs = $.grep(manors, function (e) { return (e.region === region); }); var populationArray = []; - burgs.map(function(b) { + burgs.map(function (b) { $("#burgsBody").append('
'); var el = $("#burgsBody div:last-child"); el.append(''); @@ -7597,42 +7631,42 @@ function fantasyMap() { el.append(''); var capital = states[s].capital; var type = "z-burg"; // usual burg by default - if (b.i === capital) {el.append(''); type = "c-capital";} - else {el.append('');} + if (b.i === capital) { el.append(''); type = "c-capital"; } + else { el.append(''); } if (cells[b.cell].port !== undefined) { el.append(''); - if (type === "c-capital") {type = "a-capital-port";} else {type = "p-port";} + if (type === "c-capital") { type = "a-capital-port"; } else { type = "p-port"; } } else { el.append(''); } - if (b.i !== capital) {el.append('');} + if (b.i !== capital) { el.append(''); } el.attr("data-burg", b.name).attr("data-culture", cultures[b.culture].name).attr("data-population", b.population).attr("data-type", type); }); if (!$("#burgsEditor").is(":visible")) { $("#burgsEditor").dialog({ title: "Burgs of " + states[s].name, minHeight: "auto", width: "auto", - position: {my: "right bottom", at: "right-10 bottom-10", of: "svg"} + position: { my: "right bottom", at: "right-10 bottom-10", of: "svg" } }); var color = ''; - if (region !== "neutral") {$("div[aria-describedby='burgsEditor'] .ui-dialog-title").prepend(color);} + if (region !== "neutral") { $("div[aria-describedby='burgsEditor'] .ui-dialog-title").prepend(color); } } // populate total line on footer burgsFooterBurgs.innerHTML = burgs.length; burgsFooterCulture.innerHTML = $("#burgsBody div:first-child .burgCulture").text(); var avPop = rn(d3.mean(populationArray), -1); burgsFooterPopulation.value = avPop; - $(".enlange").click(function() { + $(".enlange").click(function () { var b = +(this.parentNode.id).slice(5); var l = labels.select("[data-id='" + b + "']"); var x = +l.attr("x"), y = +l.attr("y"); zoomTo(x, y, 8, 1600); }); $("#burgsBody > div").hover(focusBurg, unfocus); - $("#burgsBody > div").click(function() { - if (!$("#changeCapital").hasClass("pressed")) {return;} + $("#burgsBody > div").click(function () { + if (!$("#changeCapital").hasClass("pressed")) { return; } var type = $(this).attr("data-type"); - if (type.includes("capital")) {return;} + if (type.includes("capital")) { return; } var s = +$("#burgsEditor").attr("data-state"); var b = +$(this).attr("id").slice(5); var oldCap = states[s].capital; @@ -7647,22 +7681,22 @@ function fantasyMap() { updateCountryEditors(); $("#changeCapital").removeClass("pressed"); }); - $(".burgName").on("input", function() { + $(".burgName").on("input", function () { var b = +(this.parentNode.id).slice(5); manors[b].name = this.value; labels.select("[data-id='" + b + "']").text(this.value); if (b === s && $("#countriesEditor").is(":visible")) { - $("#state"+s+" > .stateCapital").val(this.value); + $("#state" + s + " > .stateCapital").val(this.value); } }); - $(".ui-dialog-title > .stateColor").on("change", function() { + $(".ui-dialog-title > .stateColor").on("change", function () { states[s].color = this.value; - regions.selectAll(".region"+s).attr("fill", this.value).attr("stroke", this.value); + regions.selectAll(".region" + s).attr("fill", this.value).attr("stroke", this.value); if ($("#countriesEditor").is(":visible")) { - $("#state"+s+" > .stateColor").val(this.value); + $("#state" + s + " > .stateColor").val(this.value); } }); - $(".burgPopulation").on("change", function() { + $(".burgPopulation").on("change", function () { var b = +(this.parentNode.id).slice(5); var pop = getInteger(this.value); if (!Number.isInteger(pop) || pop < 10) { @@ -7676,19 +7710,19 @@ function fantasyMap() { $(this).parent().attr("data-population", populationRaw); this.value = si(pop); var state = manors[b].region; - if (state === "neutral") {state = states.length - 1;} + if (state === "neutral") { state = states.length - 1; } states[state].urbanPopulation += change; updateCountryPopulationUI(state); var average = states[state].urbanPopulation / states[state].burgs * urbanization.value * populationRate.value * 1000; burgsFooterPopulation.value = rn(average, -1); }); - $("#burgsFooterPopulation").on("change", function() { + $("#burgsFooterPopulation").on("change", function () { var state = +$("#burgsEditor").attr("data-state"); var newPop = +this.value; var avPop = states[state].urbanPopulation / states[state].burgs * urbanization.value * populationRate.value * 1000; - if (!Number.isInteger(newPop) || newPop < 10) {this.value = rn(avPop, -1); return;} + if (!Number.isInteger(newPop) || newPop < 10) { this.value = rn(avPop, -1); return; } var change = +this.value / avPop; - $("#burgsBody > div").each(function(e, i) { + $("#burgsBody > div").each(function (e, i) { var b = +(this.id).slice(5); var pop = rn(manors[b].population * change, 2); manors[b].population = pop; @@ -7700,15 +7734,16 @@ function fantasyMap() { states[state].urbanPopulation = rn(states[state].urbanPopulation * change, 2); updateCountryPopulationUI(state); }); - $("#burgsBody .icon-trash-empty").on("click", function() { + $("#burgsBody .icon-trash-empty").on("click", function () { alertMessage.innerHTML = `Are you sure you want to remove the burg?`; var b = +(this.parentNode.id).slice(5); - $("#alert").dialog({resizable: false, title: "Remove burg", + $("#alert").dialog({ + resizable: false, title: "Remove burg", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); var state = +$("#burgsEditor").attr("data-state"); - $("#burgs"+b).remove(); + $("#burgs" + b).remove(); var cell = manors[b].cell; manors[b].region = "removed"; cells[cell].manor = undefined; @@ -7719,12 +7754,12 @@ function fantasyMap() { var avPop = states[state].urbanPopulation / states[state].burgs * urbanization.value * populationRate.value * 1000; burgsFooterPopulation.value = rn(avPop, -1); if ($("#countriesEditor").is(":visible")) { - $("#state"+state+" > .stateBurgs").text(states[state].burgs); + $("#state" + state + " > .stateBurgs").text(states[state].burgs); } labels.select("[data-id='" + b + "']").remove(); icons.select("[data-id='" + b + "']").remove(); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }); }); @@ -7733,7 +7768,7 @@ function fantasyMap() { // onhover style functions function focusStates() { var s = +(this.parentNode.id).slice(5); - var l = labels.select("#regionLabel"+s); + var l = labels.select("#regionLabel" + s); l.classed("drag", true); } @@ -7746,8 +7781,8 @@ function fantasyMap() { function focusBurgs() { var s = +(this.parentNode.id).slice(5); - var stateManors = $.grep(manors, function(e) {return (e.region === s);}); - stateManors.map(function(m) { + var stateManors = $.grep(manors, function (e) { return (e.region === s); }); + stateManors.map(function (m) { labels.select("[data-id='" + m.i + "']").classed("drag", true); icons.select("[data-id='" + m.i + "']").classed("drag", true); }); @@ -7759,21 +7794,21 @@ function fantasyMap() { l.classed("drag", true); } - function unfocus() {$(".drag").removeClass("drag");} + function unfocus() { $(".drag").removeClass("drag"); } // save dialog position if "stable" dialog window is dragged - $(".stable").on("dialogdragstop", function(event, ui) { + $(".stable").on("dialogdragstop", function (event, ui) { sessionStorage.setItem(this.id, [ui.offset.left, ui.offset.top]); }); // restore saved dialog position on "stable" dialog window open - $(".stable").on("dialogopen", function(event, ui) { + $(".stable").on("dialogopen", function (event, ui) { var pos = sessionStorage.getItem(this.id); - if (!pos) {return;} + if (!pos) { return; } pos = pos.split(","); - if (pos[0] > $(window).width() - 100 || pos[1] > $(window).width() - 40) {return;} // prevent showing out of screen + if (pos[0] > $(window).width() - 100 || pos[1] > $(window).width() - 40) { return; } // prevent showing out of screen var at = `left+${pos[0]} top+${pos[1]}`; - $(this).dialog("option", "position", {my: "left top", at: at, of: "svg"}); + $(this).dialog("option", "position", { my: "left top", at: at, of: "svg" }); }); // open editCultures dialog @@ -7787,7 +7822,7 @@ function fantasyMap() { // collect data const cellsC = [], areas = [], rurPops = [], urbPops = []; const unit = areaUnit.value === "square" ? " " + distanceUnit.value + "²" : " " + areaUnit.value; - land.map(function(l) { + land.map(function (l) { const c = l.culture; if (c === undefined) return; cellsC[c] = cellsC[c] ? cellsC[c] + 1 : 1; @@ -7795,7 +7830,7 @@ function fantasyMap() { rurPops[c] = rurPops[c] ? rurPops[c] + l.pop : l.pop; }); - manors.map(function(m) { + manors.map(function (m) { const r = m.region; if (r === undefined || r === "removed") return; urbPops[r] = urbPops[r] ? urbPops[r] + m.population : m.population; @@ -7815,7 +7850,7 @@ function fantasyMap() { const rural = rn(rurPops[c] * populationRate.value); const population = (urban + rural) * 1000; const populationConv = si(population); - const title = '\'Total population: '+populationConv+'; Rural population: '+rural+'K; Urban population: '+urban+'K\''; + const title = '\'Total population: ' + populationConv + '; Rural population: ' + rural + 'K; Urban population: ' + urban + 'K\''; const base = nameBases[cultures[c].base].name; const el = $("#culturesBody div:last-child"); el.append(''); @@ -7838,14 +7873,14 @@ function fantasyMap() { addCultureBaseOptions(); drawCultureCenters(); - let activeCultures = cellsC.reduce(function(s, v) {if(v) {return s + 1;} else {return s;}}, 0); + let activeCultures = cellsC.reduce(function (s, v) { if (v) { return s + 1; } else { return s; } }, 0); culturesFooterCultures.innerHTML = activeCultures + "/" + cultures.length; culturesFooterCells.innerHTML = land.length; - let totalArea = areas.reduce(function(s, v) {return s + v;}); + let totalArea = areas.reduce(function (s, v) { return s + v; }); totalArea = rn(totalArea * Math.pow(distanceScale.value, 2)); culturesFooterArea.innerHTML = si(totalArea) + unit; - let totalPopulation = rurPops.reduce(function(s, v) {return s + v;}) * urbanization.value; - totalPopulation += urbPops.reduce(function(s, v) {return s + v;}); + let totalPopulation = rurPops.reduce(function (s, v) { return s + v; }) * urbanization.value; + totalPopulation += urbPops.reduce(function (s, v) { return s + v; }); culturesFooterPopulation.innerHTML = si(totalPopulation * 1000 * populationRate.value); // initialize jQuery dialog @@ -7853,23 +7888,23 @@ function fantasyMap() { $("#culturesEditor").dialog({ title: "Cultures Editor", minHeight: "auto", minWidth: Math.min(svgWidth, 336), - position: {my: "right top", at: "right-10 top+10", of: "svg"}, - close: function() { + position: { my: "right top", at: "right-10 top+10", of: "svg" }, + close: function () { debug.select("#cultureCenters").selectAll("*").remove(); exitCulturesManualAssignment(); } }); } - $(".cultures").hover(function() { + $(".cultures").hover(function () { const c = +(this.id).slice(7); - debug.select("#cultureCenter"+c).attr("stroke", "#000000e6"); - }, function() { + debug.select("#cultureCenter" + c).attr("stroke", "#000000e6"); + }, function () { const c = +(this.id).slice(7); - debug.select("#cultureCenter"+c).attr("stroke", "#00000080"); + debug.select("#cultureCenter" + c).attr("stroke", "#00000080"); }); - $(".cultures").on("click", function() { + $(".cultures").on("click", function () { if (customization !== 4) return; const c = +(this.id).slice(7); $(".selected").removeClass("selected"); @@ -7878,33 +7913,33 @@ function fantasyMap() { debug.selectAll(".circle").attr("stroke", color); }); - $(".cultures .stateColor").on("input", function() { + $(".cultures .stateColor").on("input", function () { const c = +(this.parentNode.id).slice(7); const old = cultures[c].color; cultures[c].color = this.value; - debug.select("#cultureCenter"+c).attr("fill", this.value); - cults.selectAll('[fill="'+old+'"]').attr("fill", this.value).attr("stroke", this.value); + debug.select("#cultureCenter" + c).attr("fill", this.value); + cults.selectAll('[fill="' + old + '"]').attr("fill", this.value).attr("stroke", this.value); }); - $(".cultures .cultureName").on("input", function() { + $(".cultures .cultureName").on("input", function () { const c = +(this.parentNode.id).slice(7); cultures[c].name = this.value; }); - $(".cultures .icon-arrows-cw").on("click", function() { + $(".cultures .icon-arrows-cw").on("click", function () { const c = +(this.parentNode.id).slice(7); - manors.forEach(function(m) { + manors.forEach(function (m) { if (m.region === "removed") return; if (m.culture !== c) return; m.name = generateName(c); - labels.select("[data-id='" + m.i +"']").text(m.name); + labels.select("[data-id='" + m.i + "']").text(m.name); }); }); - $("#culturesBody .icon-trash-empty").on("click", function() { + $("#culturesBody .icon-trash-empty").on("click", function () { const c = +(this.parentNode.id).slice(7); cultures.splice(c, 1); - const centers = cultures.map(function(c) {return c.center;}); + const centers = cultures.map(function (c) { return c.center; }); cultureTree = d3.quadtree(centers); recalculateCultures("fullRedraw"); editCultures(); @@ -7914,13 +7949,13 @@ function fantasyMap() { modules.editCultures = true; function addCultureBaseOptions() { - $(".cultureBase").each(function() { + $(".cultureBase").each(function () { const c = +(this.parentNode.id).slice(7); - for (let i=0; i < nameBases.length; i++) { + for (let i = 0; i < nameBases.length; i++) { this.options.add(new Option(nameBases[i].name, i)); } this.value = cultures[c].base; - this.addEventListener("change", function() { + this.addEventListener("change", function () { cultures[c].base = +this.value; }) }); @@ -7928,13 +7963,13 @@ function fantasyMap() { function drawCultureCenters() { let cultureCenters = debug.select("#cultureCenters"); - if (cultureCenters.size()) {cultureCenters.selectAll("*").remove();} - else {cultureCenters = debug.append("g").attr("id", "cultureCenters");} - for (let c=0; c < cultures.length; c++) { - cultureCenters.append("circle").attr("id", "cultureCenter"+c) + if (cultureCenters.size()) { cultureCenters.selectAll("*").remove(); } + else { cultureCenters = debug.append("g").attr("id", "cultureCenters"); } + for (let c = 0; c < cultures.length; c++) { + cultureCenters.append("circle").attr("id", "cultureCenter" + c) .attr("cx", cultures[c].center[0]).attr("cy", cultures[c].center[1]) .attr("r", 6).attr("stroke-width", 2).attr("stroke", "#00000080").attr("fill", cultures[c].color) - .on("mousemove", cultureCenterTip).on("mouseleave", function() {tip("", true)}) + .on("mousemove", cultureCenterTip).on("mouseleave", function () { tip("", true) }) .call(d3.drag().on("start", cultureCenterDrag)); } } @@ -7947,17 +7982,17 @@ function fantasyMap() { const el = d3.select(this); const c = +this.id.slice(13); - d3.event.on("drag", function() { + d3.event.on("drag", function () { const x = d3.event.x, y = d3.event.y; el.attr("cx", x).attr("cy", y); cultures[c].center = [x, y]; - const centers = cultures.map(function(c) {return c.center;}); + const centers = cultures.map(function (c) { return c.center; }); cultureTree = d3.quadtree(centers); recalculateCultures(); }); } - $("#culturesPercentage").on("click", function() { + $("#culturesPercentage").on("click", function () { const el = $("#culturesEditor"); if (el.attr("data-type") === "absolute") { el.attr("data-type", "percentage"); @@ -7965,7 +8000,7 @@ function fantasyMap() { let totalArea = culturesFooterArea.innerHTML; totalArea = getInteger(totalArea.split(" ")[0]); const totalPopulation = getInteger(culturesFooterPopulation.innerHTML); - $("#culturesBody > .cultures").each(function() { + $("#culturesBody > .cultures").each(function () { const cells = rn($(this).attr("data-cells") / totalCells * 100); const area = rn($(this).attr("data-area") / totalArea * 100); const population = rn($(this).attr("data-population") / totalPopulation * 100); @@ -7979,7 +8014,7 @@ function fantasyMap() { } }); - $("#culturesManually").on("click", function() { + $("#culturesManually").on("click", function () { customization = 4; tip("Click to select a culture, drag the circle to re-assign", true); $("#culturesBottom").children().hide(); @@ -7988,9 +8023,9 @@ function fantasyMap() { debug.select("#cultureCenters").selectAll("*").remove(); }); - $("#culturesManuallyComplete").on("click", function() { + $("#culturesManuallyComplete").on("click", function () { const changed = cults.selectAll("[data-culture]"); - changed.each(function() { + changed.each(function () { const i = +(this.id).slice(4); const c = +this.getAttribute("data-culture"); this.removeAttribute("data-culture"); @@ -8002,8 +8037,8 @@ function fantasyMap() { if (changed.size()) editCultures(); }); - $("#culturesManuallyCancel").on("click", function() { - cults.selectAll("[data-culture]").each(function() { + $("#culturesManuallyCancel").on("click", function () { + cults.selectAll("[data-culture]").each(function () { const i = +(this.id).slice(4); const c = cells[i].culture; this.removeAttribute("data-culture"); @@ -8025,8 +8060,8 @@ function fantasyMap() { restoreDefaultEvents(); } - $("#culturesRandomize").on("click", function() { - const centers = cultures.map(function(c) { + $("#culturesRandomize").on("click", function () { + const centers = cultures.map(function (c) { const x = Math.floor(Math.random() * graphWidth * 0.8 + graphWidth * 0.1); const y = Math.floor(Math.random() * graphHeight * 0.8 + graphHeight * 0.1); const center = [x, y]; @@ -8039,10 +8074,10 @@ function fantasyMap() { editCultures(); }); - $("#culturesExport").on("click", function() { + $("#culturesExport").on("click", function () { const unit = areaUnit.value === "square" ? distanceUnit.value + "2" : areaUnit.value; - let data = "Culture,Cells,Area ("+ unit +"),Population,Namesbase\n"; // headers - $("#culturesBody > .cultures").each(function() { + let data = "Culture,Cells,Area (" + unit + "),Population,Namesbase\n"; // headers + $("#culturesBody > .cultures").each(function () { data += $(this).attr("data-culture") + ","; data += $(this).attr("data-cells") + ","; data += $(this).attr("data-area") + ","; @@ -8050,28 +8085,28 @@ function fantasyMap() { data += $(this).attr("data-base") + "\n"; }); - var dataBlob = new Blob([data], {type:"text/plain"}); + var dataBlob = new Blob([data], { type: "text/plain" }); var url = window.URL.createObjectURL(dataBlob); var link = document.createElement("a"); document.body.appendChild(link); link.download = "cultures_data" + Date.now() + ".csv"; link.href = url; link.click(); - window.setTimeout(function() {window.URL.revokeObjectURL(url);}, 2000); + window.setTimeout(function () { window.URL.revokeObjectURL(url); }, 2000); }); - $("#culturesRegenerateNames").on("click", function() { - manors.forEach(function(m) { + $("#culturesRegenerateNames").on("click", function () { + manors.forEach(function (m) { if (m.region === "removed") return; const culture = m.culture; m.name = generateName(culture); - labels.select("[data-id='" + m.i +"']").text(m.name); + labels.select("[data-id='" + m.i + "']").text(m.name); }); }); $("#culturesEditNamesBase").on("click", editNamesbase); - $("#culturesAdd").on("click", function() { + $("#culturesAdd").on("click", function () { const x = Math.floor(Math.random() * graphWidth * 0.8 + graphWidth * 0.1); const y = Math.floor(Math.random() * graphHeight * 0.8 + graphHeight * 0.1); const center = [x, y]; @@ -8090,8 +8125,8 @@ function fantasyMap() { color = colors20(cultures.length % 20); base = cultures[culture].base; } - cultures.push({name, color, base, center}); - const centers = cultures.map(function(c) {return c.center;}); + cultures.push({ name, color, base, center }); + const centers = cultures.map(function (c) { return c.center; }); cultureTree = d3.quadtree(centers); recalculateCultures(); editCultures(); @@ -8120,8 +8155,8 @@ function fantasyMap() { $("#namesbaseEditor").dialog({ title: "Namesbase Editor", minHeight: "auto", minWidth: Math.min(svgWidth, 400), - position: {my: "center", at: "center", of: "svg"}, - close: function() { + position: { my: "center", at: "center", of: "svg" }, + close: function () { localStorage.setItem("nameBase", JSON.stringify(nameBase)); localStorage.setItem("nameBases", JSON.stringify(nameBases)); } @@ -8149,7 +8184,7 @@ function fantasyMap() { function namesbaseUpdateExamples(selected) { const examples = document.getElementById("namesbaseExamples"); let text = ""; - for (let i=0; i < 10; i++) { + for (let i = 0; i < 10; i++) { const name = generateName(false, selected); if (name === undefined) { text = "Cannot generate examples. Please verify the data"; @@ -8161,20 +8196,20 @@ function fantasyMap() { examples.innerHTML = text; } - $("#namesbaseSelect").on("change", function() { + $("#namesbaseSelect").on("change", function () { const selected = +this.value; namesbaseUpdateInputs(selected); namesbaseUpdateExamples(selected); }); - $("#namesbaseName").on("input", function() { + $("#namesbaseName").on("input", function () { const base = +textarea.getAttribute("data-base"); const select = document.getElementById("namesbaseSelect"); select.options[base].innerHTML = this.value; nameBases[base].name = this.value; }); - $("#namesbaseTextarea").on("input", function() { + $("#namesbaseTextarea").on("input", function () { const base = +this.getAttribute("data-base"); const data = textarea.value.replace(/ /g, "").split(","); nameBase[base] = data; @@ -8188,13 +8223,13 @@ function fantasyMap() { if (method !== "selection") chain[base] = calculateChain(base); }); - $("#namesbaseMethod").on("change", function() { + $("#namesbaseMethod").on("change", function () { const base = +textarea.getAttribute("data-base"); nameBases[base].method = this.value; if (this.value !== "selection") chain[base] = calculateChain(base); }); - $("#namesbaseMin").on("change", function() { + $("#namesbaseMin").on("change", function () { const base = +textarea.getAttribute("data-base"); if (+this.value > nameBases[base].max) { tip("Minimal length cannot be greated that maximal"); @@ -8203,7 +8238,7 @@ function fantasyMap() { } }); - $("#namesbaseMax").on("change", function() { + $("#namesbaseMax").on("change", function () { const base = +textarea.getAttribute("data-base"); if (+this.value < nameBases[base].min) { tip("Maximal length cannot be less than minimal"); @@ -8212,18 +8247,19 @@ function fantasyMap() { } }); - $("#namesbaseDouble").on("change", function() { + $("#namesbaseDouble").on("change", function () { const base = +textarea.getAttribute("data-base"); nameBases[base].d = this.value; }); - $("#namesbaseDefault").on("click", function() { + $("#namesbaseDefault").on("click", function () { alertMessage.innerHTML = `Are you sure you want to restore the default namesbase? All custom bases will be removed and default ones will be assigned to existing cultures. Meanwhile existing names will not be changed.`; - $("#alert").dialog({resizable: false, title: "Restore default data", + $("#alert").dialog({ + resizable: false, title: "Restore default data", buttons: { - Restore: function() { + Restore: function () { $(this).dialog("close"); $("#namesbaseEditor").dialog("close"); const select = document.getElementById("namesbaseSelect"); @@ -8235,25 +8271,25 @@ function fantasyMap() { localStorage.removeItem("nameBase"); applyDefaultNamesData(); const baseMax = nameBases.length - 1; - cultures.forEach(function(c) {if (c.base > baseMax) c.base = baseMax;}); + cultures.forEach(function (c) { if (c.base > baseMax) c.base = baseMax; }); chains = {}; calculateChains(); editCultures(); editNamesbase(); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { $(this).dialog("close"); } } }); }); - $("#namesbaseAdd").on("click", function() { + $("#namesbaseAdd").on("click", function () { const base = nameBases.length; const name = "Base" + base; const method = document.getElementById("namesbaseMethod").value; const select = document.getElementById("namesbaseSelect"); select.options.add(new Option(name, base)); select.value = base; - nameBases.push({name, method, min: 4, max: 10, d: "", m: 1}); + nameBases.push({ name, method, min: 4, max: 10, d: "", m: 1 }); nameBase.push([]); document.getElementById("namesbaseName").value = name; const textarea = document.getElementById("namesbaseTextarea"); @@ -8264,15 +8300,15 @@ function fantasyMap() { editCultures(); }); - $("#namesbaseExamples, #namesbaseUpdateExamples").on("click", function() { + $("#namesbaseExamples, #namesbaseUpdateExamples").on("click", function () { const select = document.getElementById("namesbaseSelect"); namesbaseUpdateExamples(+select.value); }); - $("#namesbaseDownload").on("click", function() { + $("#namesbaseDownload").on("click", function () { const nameBaseString = JSON.stringify(nameBase) + "\r\n"; const nameBasesString = JSON.stringify(nameBases); - const dataBlob = new Blob([nameBaseString + nameBasesString], {type:"text/plain"}); + const dataBlob = new Blob([nameBaseString + nameBasesString], { type: "text/plain" }); const url = window.URL.createObjectURL(dataBlob); const link = document.createElement("a"); link.download = "namebase" + Date.now() + ".txt"; @@ -8280,12 +8316,12 @@ function fantasyMap() { link.click(); }); - $("#namesbaseUpload").on("click", function() {namesbaseToLoad.click();}); - $("#namesbaseToLoad").change(function() { + $("#namesbaseUpload").on("click", function () { namesbaseToLoad.click(); }); + $("#namesbaseToLoad").change(function () { const fileToLoad = this.files[0]; this.value = ""; const fileReader = new FileReader(); - fileReader.onload = function(fileLoadedEvent) { + fileReader.onload = function (fileLoadedEvent) { const dataLoaded = fileLoadedEvent.target.result; const data = dataLoaded.split("\r\n"); if (data[0] && data[1]) { @@ -8297,7 +8333,7 @@ function fantasyMap() { document.getElementById("namesbaseTextarea").setAttribute("data-base", 0); document.getElementById("namesbaseExamples").innerHTML === ""; const baseMax = nameBases.length - 1; - cultures.forEach(function(c) {if (c.base > baseMax) c.base = baseMax;}); + cultures.forEach(function (c) { if (c.base > baseMax) c.base = baseMax; }); chains = {}; calculateChains(); editCultures(); @@ -8316,7 +8352,7 @@ function fantasyMap() { $("#scaleEditor").dialog({ title: "Scale Editor", minHeight: "auto", width: "auto", resizable: false, - position: {my: "center bottom", at: "center bottom-10", of: "svg"} + position: { my: "center bottom", at: "center bottom-10", of: "svg" } }); } @@ -8324,16 +8360,16 @@ function fantasyMap() { function updateCountryPopulationUI(s) { if ($("#countriesEditor").is(":visible")) { var urban = rn(states[s].urbanPopulation * +urbanization.value * populationRate.value); - var rural = rn(states[s].ruralPopulation * populationRate.value); + var rural = rn(states[s].ruralPopulation * populationRate.value); var population = (urban + rural) * 1000; - $("#state"+s).attr("data-population", population); - $("#state"+s).children().filter(".statePopulation").val(si(population)); + $("#state" + s).attr("data-population", population); + $("#state" + s).children().filter(".statePopulation").val(si(population)); } } // update dialogs if measurements are changed function updateCountryEditors() { - if ($("#countriesEditor").is(":visible")) {editCountries();} + if ($("#countriesEditor").is(":visible")) { editCountries(); } if ($("#burgsEditor").is(":visible")) { var s = +$("#burgsEditor").attr("data-state"); editBurgs(this, s); @@ -8352,7 +8388,7 @@ function fantasyMap() { function restoreRegions() { borders.selectAll("path").remove(); labels.select("#countries").selectAll("text").remove(); - manors.map(function(m) { + manors.map(function (m) { const cell = diagram.find(m.x, m.y).index; if (cells[cell].height < 0.2) { // remove manor in ocean @@ -8365,7 +8401,7 @@ function fantasyMap() { cells[cell].manor = m.i; } }); - cells.map(function(c) { + cells.map(function (c) { if (c.height < 0.2) { // no longer a land cell delete c.region; @@ -8375,7 +8411,7 @@ function fantasyMap() { if (c.region === undefined) { c.region = "neutral"; if (states[states.length - 1].capital !== "neutral") { - states.push({i: states.length, color: "neutral", capital: "neutral", name: "Neutrals"}); + states.push({ i: states.length, color: "neutral", capital: "neutral", name: "Neutrals" }); } } if (c.culture === undefined) { @@ -8383,22 +8419,22 @@ function fantasyMap() { c.culture = cultureTree.data().indexOf(closest); } }); - states.map(function(s) {recalculateStateData(s.i);}) + states.map(function (s) { recalculateStateData(s.i); }) drawRegions(); } function regenerateCountries() { regions.selectAll("*").remove(); const neutral = neutralInput.value = +countriesNeutral.value; - manors.forEach(function(m) { + manors.forEach(function (m) { if (m.region === "removed") return; let state = "neutral", closest = neutral; - states.map(function(s) { + states.map(function (s) { if (s.capital === "neutral" || s.capital === "select") return; const c = manors[s.capital]; let dist = Math.hypot(c.x - m.x, c.y - m.y) / s.power; if (cells[m.cell].fn !== cells[c.cell].fn) dist *= 3; - if (dist < closest) {state = s.i; closest = dist;} + if (dist < closest) { state = s.i; closest = dist; } }); m.region = state; cells[m.cell].region = state; @@ -8406,7 +8442,7 @@ function fantasyMap() { defineRegions(); const temp = regions.append("g").attr("id", "temp"); - land.forEach(function(l) { + land.forEach(function (l) { if (l.region === undefined) return; if (l.region === "neutral") return; const color = states[l.region].color; @@ -8415,7 +8451,7 @@ function fantasyMap() { .attr("d", "M" + polygons[l.index].join("L") + "Z") .attr("fill", color).attr("stroke", color); }); - const neutralCells = $.grep(cells, function(e) {return e.region === "neutral";}); + const neutralCells = $.grep(cells, function (e) { return e.region === "neutral"; }); const last = states.length - 1; const type = states[last].color; if (type === "neutral" && !neutralCells.length) { @@ -8424,23 +8460,23 @@ function fantasyMap() { states.splice(-1); } // recalculate data for all countries - states.map(function(s) { + states.map(function (s) { recalculateStateData(s.i); - $("#state"+s.i+" > .stateCells").text(s.cells); - $("#state"+s.i+" > .stateBurgs").text(s.burgs); + $("#state" + s.i + " > .stateCells").text(s.cells); + $("#state" + s.i + " > .stateBurgs").text(s.burgs); const area = rn(s.area * Math.pow(distanceScale.value, 2)); const unit = areaUnit.value === "square" ? " " + distanceUnit.value + "²" : " " + areaUnit.value; - $("#state"+s.i+" > .stateArea").text(si(area) + unit); + $("#state" + s.i + " > .stateArea").text(si(area) + unit); const urban = rn(s.urbanPopulation * urbanization.value * populationRate.value); - const rural = rn(s.ruralPopulation * populationRate.value); + const rural = rn(s.ruralPopulation * populationRate.value); const population = (urban + rural) * 1000; - $("#state"+s.i+" > .statePopulation").val(si(population)); - $("#state"+s.i).attr("data-cells", s.cells).attr("data-burgs", s.burgs) + $("#state" + s.i + " > .statePopulation").val(si(population)); + $("#state" + s.i).attr("data-cells", s.cells).attr("data-burgs", s.burgs) .attr("data-area", area).attr("data-population", population); }); if (type !== "neutral" && neutralCells.length) { // add neutral line - states.push({i: states.length, color: "neutral", capital: "neutral", name: "Neutrals"}); + states.push({ i: states.length, color: "neutral", capital: "neutral", name: "Neutrals" }); recalculateStateData(states.length - 1); editCountries(); } @@ -8448,49 +8484,49 @@ function fantasyMap() { // enter state edit mode function mockRegions() { - if (grid.style("display") !== "inline") {toggleGrid.click();} - if (labels.style("display") !== "none") {toggleLabels.click();} + if (grid.style("display") !== "inline") { toggleGrid.click(); } + if (labels.style("display") !== "none") { toggleLabels.click(); } stateBorders.selectAll("*").remove(); neutralBorders.selectAll("*").remove(); } // handle DOM elements sorting on header click - $(".sortable").on("click", function() { + $(".sortable").on("click", function () { var el = $(this); // remove sorting for all siglings except of clicked element el.siblings().removeClass("icon-sort-name-up icon-sort-name-down icon-sort-number-up icon-sort-number-down"); var type = el.hasClass("alphabetically") ? "name" : "number"; var state = "no"; - if (el.is("[class*='down']")) {state = "asc";} - if (el.is("[class*='up']")) {state = "desc";} + if (el.is("[class*='down']")) { state = "asc"; } + if (el.is("[class*='up']")) { state = "desc"; } var sortby = el.attr("data-sortby"); var list = el.parent().next(); // get list container element (e.g. "countriesBody") var lines = list.children("div"); // get list elements if (state === "no" || state === "asc") { // sort desc el.removeClass("icon-sort-" + type + "-down"); el.addClass("icon-sort-" + type + "-up"); - lines.sort(function(a, b) { + lines.sort(function (a, b) { var an = a.getAttribute("data-" + sortby); - if (an === "bottom") {return 1;} + if (an === "bottom") { return 1; } var bn = b.getAttribute("data-" + sortby); - if (bn === "bottom") {return -1;} - if (type === "number") {an = +an; bn = +bn;} - if (an > bn) {return 1;} - if (an < bn) {return -1;} + if (bn === "bottom") { return -1; } + if (type === "number") { an = +an; bn = +bn; } + if (an > bn) { return 1; } + if (an < bn) { return -1; } return 0; }); } if (state === "desc") { // sort asc el.removeClass("icon-sort-" + type + "-up"); el.addClass("icon-sort-" + type + "-down"); - lines.sort(function(a, b) { + lines.sort(function (a, b) { var an = a.getAttribute("data-" + sortby); - if (an === "bottom") {return 1;} + if (an === "bottom") { return 1; } var bn = b.getAttribute("data-" + sortby); - if (bn === "bottom") {return -1;} - if (type === "number") {an = +an; bn = +bn;} - if (an < bn) {return 1;} - if (an > bn) {return -1;} + if (bn === "bottom") { return -1; } + if (type === "number") { an = +an; bn = +bn; } + if (an < bn) { return 1; } + if (an > bn) { return -1; } return 0; }); } @@ -8498,31 +8534,32 @@ function fantasyMap() { }); // load text file with new burg names - $("#burgsListToLoad").change(function() { + $("#burgsListToLoad").change(function () { var fileToLoad = this.files[0]; this.value = ""; var fileReader = new FileReader(); - fileReader.onload = function(fileLoadedEvent) { + fileReader.onload = function (fileLoadedEvent) { var dataLoaded = fileLoadedEvent.target.result; var data = dataLoaded.split("\r\n"); - if (data.length === 0) {return;} + if (data.length === 0) { return; } let change = []; let message = `Burgs will be renamed as below. Please confirm`; message += `
`; - for (var i=0; i < data.length && i < manors.length; i++) { + for (let i = 0; i < data.length && i < manors.length; i++) { const v = data[i]; - if (v === "" || v === undefined) {continue;} - if (v === manors[i].name) {continue;} - change.push({i, name: v}); + if (v === "" || v === undefined) { continue; } + if (v === manors[i].name) { continue; } + change.push({ i, name: v }); message += ``; } message += `
IdCurrent nameNew Name
${i}${manors[i].name}${v}
`; alertMessage.innerHTML = message; - $("#alert").dialog({title: "Burgs bulk renaming", position: {my: "center", at: "center", of: "svg"}, + $("#alert").dialog({ + title: "Burgs bulk renaming", position: { my: "center", at: "center", of: "svg" }, buttons: { - Cancel: function() {$(this).dialog("close");}, - Confirm: function() { - for (var i=0; i < change.length; i++) { + Cancel: function () { $(this).dialog("close"); }, + Confirm: function () { + for (let i = 0; i < change.length; i++) { const id = change[i].i; manors[id].name = change[i].name; labels.select("[data-id='" + id + "']").text(change[i].name); @@ -8542,7 +8579,7 @@ function fantasyMap() { svgHeight = graphHeight = +mapHeightInput.value; svg.attr("width", svgWidth).attr("height", svgHeight); // set extent to map borders + 100px to get infinity world reception - voronoi = d3.voronoi().extent([[-1, -1], [graphWidth+1, graphHeight+1]]); + voronoi = d3.voronoi().extent([[-1, -1], [graphWidth + 1, graphHeight + 1]]); zoom.translateExtent([[0, 0], [graphWidth, graphHeight]]).scaleExtent([1, 20]).scaleTo(svg, 1); viewbox.attr("transform", null); ocean.selectAll("rect").attr("x", 0).attr("y", 0).attr("width", graphWidth).attr("height", graphHeight); @@ -8561,7 +8598,7 @@ function fantasyMap() { } // fit full-screen map if window is resized - $(window).resize(function(e) { + $(window).resize(function (e) { // trick to prevent resize on download bar opening if (autoResize === false) return; mapWidthInput.value = window.innerWidth; @@ -8626,12 +8663,12 @@ function fantasyMap() { } // Options handlers - $("input, select").on("input change", function() { + $("input, select").on("input change", function () { var id = this.id; - if (id === "hideLabels") {invokeActiveZooming();} + if (id === "hideLabels") { invokeActiveZooming(); } if (id === "styleElementSelect") { const sel = this.value; - let el = viewbox.select("#"+sel); + let el = viewbox.select("#" + sel); if (sel == "ocean") el = oceanLayers.select("rect"); $("#styleInputs div").hide(); // opacity @@ -8657,8 +8694,8 @@ function fantasyMap() { styleStrokeDasharrayInput.value = el.attr("stroke-dasharray") || ""; styleStrokeLinecapInput.value = el.attr("stroke-linecap") || "inherit"; } - if (sel === "terrs") {$("#styleScheme").css("display", "block");} - if (sel === "heightmap") {$("#styleScheme").css("display", "block");} + if (sel === "terrs") { $("#styleScheme").css("display", "block"); } + if (sel === "heightmap") { $("#styleScheme").css("display", "block"); } if (sel === "labels") { $("#styleFill, #styleFontSize").css("display", "inline-block"); styleFillInput.value = styleFillOutput.value = el.select("g").attr("fill"); @@ -8675,9 +8712,9 @@ function fantasyMap() { } if (id === "styleFillInput") { styleFillOutput.value = this.value; - var el = svg.select("#"+styleElementSelect.value); + var el = svg.select("#" + styleElementSelect.value); if (styleElementSelect.value !== "labels") { - el.attr('fill', this.value); + el.attr('fill', this.value); } else { el.selectAll("g").attr('fill', this.value); } @@ -8685,36 +8722,36 @@ function fantasyMap() { } if (id === "styleStrokeInput") { styleStrokeOutput.value = this.value; - var el = svg.select("#"+styleElementSelect.value); + var el = svg.select("#" + styleElementSelect.value); el.attr('stroke', this.value); return; } if (id === "styleStrokeWidthInput") { styleStrokeWidthOutput.value = this.value; var sel = styleElementSelect.value; - svg.select("#"+sel).attr('stroke-width', +this.value); + svg.select("#" + sel).attr('stroke-width', +this.value); return; } if (id === "styleStrokeDasharrayInput") { var sel = styleElementSelect.value; - svg.select("#"+sel).attr('stroke-dasharray', this.value); + svg.select("#" + sel).attr('stroke-dasharray', this.value); return; } if (id === "styleStrokeLinecapInput") { var sel = styleElementSelect.value; - svg.select("#"+sel).attr('stroke-linecap', this.value); + svg.select("#" + sel).attr('stroke-linecap', this.value); return; } if (id === "styleOpacityInput") { styleOpacityOutput.value = this.value; var sel = styleElementSelect.value; - svg.select("#"+sel).attr('opacity', this.value); + svg.select("#" + sel).attr('opacity', this.value); return; } if (id === "styleFilterInput") { let sel = styleElementSelect.value; if (sel == "ocean") sel = "oceanLayers"; - const el = svg.select("#"+sel); + const el = svg.select("#" + sel); el.attr('filter', this.value); zoom.scaleBy(svg, 1.00001); // enforce browser re-draw return; @@ -8761,36 +8798,36 @@ function fantasyMap() { } if (id === "sizeInput") { graphSize = sizeOutput.value = +this.value; - if (graphSize === 3) {sizeOutput.style.color = "red";} - if (graphSize === 2) {sizeOutput.style.color = "yellow";} - if (graphSize === 1) {sizeOutput.style.color = "green";} + if (graphSize === 3) { sizeOutput.style.color = "red"; } + if (graphSize === 2) { sizeOutput.style.color = "yellow"; } + if (graphSize === 1) { sizeOutput.style.color = "green"; } // localStorage.setItem("graphSize", this.value); - temp off to always start with size 1 } - if (id === "templateInput") {localStorage.setItem("template", this.value);} - if (id === "manorsInput") {manorsOutput.value = this.value; localStorage.setItem("manors", this.value);} + if (id === "templateInput") { localStorage.setItem("template", this.value); } + if (id === "manorsInput") { manorsOutput.value = this.value; localStorage.setItem("manors", this.value); } if (id === "regionsInput") { regionsOutput.value = this.value; var size = rn(6 - this.value / 20); - if (size < 3) {size = 3;} + if (size < 3) { size = 3; } burgLabels.select("#capitals").attr("data-size", size); size = rn(18 - this.value / 6); - if (size < 4) {size = 4;} + if (size < 4) { size = 4; } labels.select("#countries").attr("data-size", size); localStorage.setItem("regions", this.value); } - if (id === "powerInput") {powerOutput.value = this.value; localStorage.setItem("power", this.value);} - if (id === "neutralInput") {neutralOutput.value = countriesNeutral.value = this.value; localStorage.setItem("neutal", this.value);} - if (id === "culturesInput") {culturesOutput.value = this.value; localStorage.setItem("cultures", this.value);} - if (id === "precInput") {precOutput.value = +precInput.value; localStorage.setItem("prec", this.value);} - if (id === "swampinessInput") {swampinessOutput.value = this.value; localStorage.setItem("swampiness", this.value);} - if (id === "outlineLayersInput") {localStorage.setItem("outlineLayers", this.value);} - if (id === "pngResolutionInput") {localStorage.setItem("pngResolution", this.value);} + if (id === "powerInput") { powerOutput.value = this.value; localStorage.setItem("power", this.value); } + if (id === "neutralInput") { neutralOutput.value = countriesNeutral.value = this.value; localStorage.setItem("neutal", this.value); } + if (id === "culturesInput") { culturesOutput.value = this.value; localStorage.setItem("cultures", this.value); } + if (id === "precInput") { precOutput.value = +precInput.value; localStorage.setItem("prec", this.value); } + if (id === "swampinessInput") { swampinessOutput.value = this.value; localStorage.setItem("swampiness", this.value); } + if (id === "outlineLayersInput") { localStorage.setItem("outlineLayers", this.value); } + if (id === "pngResolutionInput") { localStorage.setItem("pngResolution", this.value); } if (id === "zoomExtentMin" || id === "zoomExtentMax") { zoom.scaleExtent([+zoomExtentMin.value, +zoomExtentMax.value]); zoom.scaleTo(svg, +this.value); } - if (id === "convertOverlay") {canvas.style.opacity = convertOverlayValue.innerHTML = +this.value;} + if (id === "convertOverlay") { canvas.style.opacity = convertOverlayValue.innerHTML = +this.value; } if (id === "populationRate") { populationRateOutput.value = si(+populationRate.value * 1000); updateCountryEditors(); @@ -8814,14 +8851,14 @@ function fantasyMap() { } var scale = distanceScale.value; scaleOutput.value = scale + " " + dUnit; - ruler.selectAll("g").each(function() { + ruler.selectAll("g").each(function () { var label; var g = d3.select(this); var area = +g.select("text").attr("data-area"); if (area) { var areaConv = area * Math.pow(scale, 2); // convert area to distanceScale var unit = areaUnit.value; - if (unit === "square") {unit = dUnit + "²"} else {unit = areaUnit.value;} + if (unit === "square") { unit = dUnit + "²" } else { unit = areaUnit.value; } label = si(areaConv) + " " + unit; } else { var dist = +g.select("text").attr("data-dist"); @@ -8850,7 +8887,7 @@ function fantasyMap() { } }); - $("#scaleOutput").change(function() { + $("#scaleOutput").change(function () { if (this.value === "" || isNaN(+this.value) || this.value < 0.01 || this.value > 10) { tip("Manually entered distance scale should be a number in a [0.01; 10] range"); this.value = distanceScale.value + " " + distanceUnit.value; @@ -8861,7 +8898,7 @@ function fantasyMap() { updateCountryEditors(); }); - $("#populationRateOutput").change(function() { + $("#populationRateOutput").change(function () { if (this.value === "" || isNaN(+this.value) || this.value < 0.001 || this.value > 10) { tip("Manually entered population rate should be a number in a [0.001; 10] range"); this.value = si(populationRate.value * 1000); @@ -8872,7 +8909,7 @@ function fantasyMap() { updateCountryEditors(); }); - $("#urbanizationOutput").change(function() { + $("#urbanizationOutput").change(function () { if (this.value === "" || isNaN(+this.value) || this.value < 0 || this.value > 10) { tip("Manually entered urbanization rate should be a number in a [0; 10] range"); this.value = urbanization.value; @@ -8886,7 +8923,7 @@ function fantasyMap() { // lock manually changed option to restrict it randomization - $("#optionsContent input, #optionsContent select").change(function() { + $("#optionsContent input, #optionsContent select").change(function () { const icon = "lock" + this.id.charAt(0).toUpperCase() + this.id.slice(1); const el = document.getElementById(icon); if (!el) return; @@ -8896,15 +8933,15 @@ function fantasyMap() { $("#optionsReset").click(restoreDefaultOptions); - $("#rescaler").change(function() { - var change = rn((+this.value - 5) / 10, 2); - modifyHeights("all", change, 1); - updateHeightmap(); - updateHistory(); - rescaler.value = 5; + $("#rescaler").change(function () { + var change = rn((+this.value - 5) / 10, 2); + modifyHeights("all", change, 1); + updateHeightmap(); + updateHistory(); + rescaler.value = 5; }); - $("#layoutPreset").on("change", function() { + $("#layoutPreset").on("change", function () { var preset = this.value; $("#mapLayers li").not("#toggleOcean").addClass("buttonoff"); $("#toggleOcean").removeClass("buttonoff"); @@ -8944,37 +8981,37 @@ function fantasyMap() { }); // UI Button handlers - $(".tab > button").on("click", function() { + $(".tab > button").on("click", function () { $(".tabcontent").hide(); $(".tab > button").removeClass("active"); $(this).addClass("active"); var id = this.id; - if (id === "layoutTab") {$("#layoutContent").show();} - if (id === "styleTab") {$("#styleContent").show();} - if (id === "optionsTab") {$("#optionsContent").show();} - if (id === "customizeTab") {$("#customizeContent").show();} - if (id === "aboutTab") {$("#aboutContent").show();} + if (id === "layoutTab") { $("#layoutContent").show(); } + if (id === "styleTab") { $("#styleContent").show(); } + if (id === "optionsTab") { $("#optionsContent").show(); } + if (id === "customizeTab") { $("#customizeContent").show(); } + if (id === "aboutTab") { $("#aboutContent").show(); } }); // Pull request from @evyatron // https://github.com/Azgaar/Fantasy-Map-Generator/pull/49 function addDragToUpload() { - document.addEventListener('dragover', function(e) { - e.stopPropagation(); - e.preventDefault(); - $('#map-dragged').show(); + document.addEventListener('dragover', function (e) { + e.stopPropagation(); + e.preventDefault(); + $('#map-dragged').show(); }); - document.addEventListener('dragleave', function(e) { - $('#map-dragged').hide(); + document.addEventListener('dragleave', function (e) { + $('#map-dragged').hide(); }); - document.addEventListener('drop', function(e) { + document.addEventListener('drop', function (e) { e.stopPropagation(); e.preventDefault(); $('#map-dragged').hide(); // no files or more than one - if (e.dataTransfer.items == null || e.dataTransfer.items.length != 1) {return;} + if (e.dataTransfer.items == null || e.dataTransfer.items.length != 1) { return; } var file = e.dataTransfer.items[0].getAsFile(); // not a .map file if (file.name.indexOf('.map') == -1) { @@ -8982,8 +9019,8 @@ function fantasyMap() { $("#alert").dialog({ resizable: false, title: "Invalid file format", width: 400, buttons: { - Close: function() { $(this).dialog("close"); } - }, position: {my: "center", at: "center", of: "svg"} + Close: function () { $(this).dialog("close"); } + }, position: { my: "center", at: "center", of: "svg" } }); return; } @@ -8998,9 +9035,9 @@ function fantasyMap() { function tip(tip, main) { tooltip.innerHTML = tip; - if (main) {tooltip.setAttribute("data-main", tip);} + if (main) { tooltip.setAttribute("data-main", tip); } } -$("#optionsContainer *").on("mouseout", function() { +$("#optionsContainer *").on("mouseout", function () { tooltip.innerHTML = tooltip.getAttribute("data-main"); }); From 05bb3a2c502c8275a62face17a2b73c66aa90de6 Mon Sep 17 00:00:00 2001 From: Brian Weasner Date: Tue, 14 Aug 2018 16:06:25 -0600 Subject: [PATCH 2/2] Reverted formatting changes This reverts commit 338ce17cb8c3b179298e5c151c043466a06b29bf. Only small js fixes --- script.js | 2936 ++++++++++++++++++++++++++--------------------------- 1 file changed, 1450 insertions(+), 1486 deletions(-) diff --git a/script.js b/script.js index 2a029a2c..ce30fafe 100644 --- a/script.js +++ b/script.js @@ -74,8 +74,8 @@ function fantasyMap() { // Color schemes var color = d3.scaleSequential(d3.interpolateSpectral), - colors8 = d3.scaleOrdinal(d3.schemeSet2), - colors20 = d3.scaleOrdinal(d3.schemeCategory20); + colors8 = d3.scaleOrdinal(d3.schemeSet2), + colors20 = d3.scaleOrdinal(d3.schemeCategory20); // D3 drag and zoom behavior var scale = 1, viewX = 0, viewY = 0; @@ -83,7 +83,7 @@ function fantasyMap() { svg.call(zoom); // D3 Line generator variables - var lineGen = d3.line().x(function (d) { return d.scX; }).y(function (d) { return d.scY; }).curve(d3.curveCatmullRom); + var lineGen = d3.line().x(function(d) {return d.scX;}).y(function(d) {return d.scY;}).curve(d3.curveCatmullRom); applyStoredOptions(); let graphWidth = +mapWidthInput.value; // voronoi graph extention, should be stable for each map @@ -100,14 +100,14 @@ function fantasyMap() { $("#optionsTrigger").removeClass("glow"); } - $("#optionsContainer").draggable({ handle: ".drag-trigger", snap: "svg", snapMode: "both" }); - $("#mapLayers").sortable({ items: "li:not(.solid)", cancel: ".solid", update: moveLayer }); - $("#templateBody").sortable({ items: "div:not(div[data-type='Mountain'])" }); + $("#optionsContainer").draggable({handle: ".drag-trigger", snap: "svg", snapMode: "both"}); + $("#mapLayers").sortable({items: "li:not(.solid)", cancel: ".solid", update: moveLayer}); + $("#templateBody").sortable({items: "div:not(div[data-type='Mountain'])"}); $("#mapLayers, #templateBody").disableSelection(); var drag = d3.drag() - .container(function () { return this; }) - .subject(function () { var p = [d3.event.x, d3.event.y]; return [p, p]; }) + .container(function() {return this;}) + .subject(function() {var p=[d3.event.x, d3.event.y]; return [p, p];}) .on("start", dragstarted); function zoomed() { @@ -145,22 +145,22 @@ function fantasyMap() { function invokeActiveZooming() { // toggle shade/blur filter on zoom var filter = scale > 2.6 ? "url(#blurFilter)" : "url(#dropShadow)"; - if (scale > 1.5 && scale <= 2.6) { filter = null; } + if (scale > 1.5 && scale <= 2.6) {filter = null;} coastline.attr("filter", filter); // rescale lables on zoom (active zooming) - labels.selectAll("g").each(function (d) { + labels.selectAll("g").each(function(d) { var el = d3.select(this); if (el.attr("id") === "burgLabels") return; var desired = +el.attr("data-size"); var relative = rn((desired + (desired / scale)) / 2, 2); - if (relative < 2) { relative = 2; } + if (relative < 2) {relative = 2;} el.attr("font-size", relative); el.classed("hidden", hideLabels.checked && relative * scale < 6); }); if (ruler.size()) { if (ruler.style("display") !== "none") { - if (ruler.selectAll("g").size() < 1) { return; } + if (ruler.selectAll("g").size() < 1) {return;} var factor = rn(1 / Math.pow(scale, 0.3), 1); ruler.selectAll("circle:not(.center)").attr("r", 2 * factor).attr("stroke-width", 0.5 * factor); ruler.selectAll("circle.center").attr("r", 1.2 * factor).attr("stroke-width", 0.3 * factor); @@ -190,17 +190,16 @@ function fantasyMap() {

Join our Reddit community to share created maps, discuss the Generator, ask questions and propose new features.`; $("#alert").dialog( - { - resizable: false, title: "Fantasy Map Generator update", width: 280, - buttons: { - "Don't show again": function () { - localStorage.setItem("version", version); - $(this).dialog("close"); - }, - Close: function () { $(this).dialog("close"); } + {resizable: false, title: "Fantasy Map Generator update", width: 280, + buttons: { + "Don't show again": function() { + localStorage.setItem("version", version); + $(this).dialog("close"); }, - position: { my: "center", at: "center", of: "svg" } - }); + Close: function() {$(this).dialog("close");} + }, + position: {my: "center", at: "center", of: "svg"} + }); } applyNamesData(); // apply default namesbase on load @@ -298,7 +297,7 @@ function fantasyMap() { mapHeightInput.value = window.innerHeight; changeMapSize(); graphSize = sizeInput.value = sizeOutput.value = 1; - $("#options i[class^='icon-lock']").each(function () { + $("#options i[class^='icon-lock']").each(function() { this.setAttribute("data-locked", 0); this.className = "icon-lock-open"; if (this.id === "lockNeutralInput" || this.id === "lockSwampinessInput") { @@ -324,53 +323,53 @@ function fantasyMap() { } else { applyDefaultNamesData(); } - defaultCultures = [{ name: "Shwazen", color: "#b3b3b3", base: 0 }, - { name: "Angshire", color: "#fca463", base: 1 }, - { name: "Luari", color: "#99acfb", base: 2 }, - { name: "Tallian", color: "#a6d854", base: 3 }, - { name: "Toledi", color: "#ffd92f", base: 4 }, - { name: "Slovian", color: "#e5c494", base: 5 }, - { name: "Norse", color: "#dca3e4", base: 6 }, - { name: "Elladian", color: "#96d6be", base: 7 }, - { name: "Latian", color: "#ff7174", base: 8 }, - { name: "Somi", color: "#aedff7", base: 9 }, - { name: "Koryo", color: "#578880", base: 10 }, - { name: "Hantzu", color: "#fdface", base: 11 }, - { name: "Yamoto", color: "#ffd9da", base: 12 } + defaultCultures = [{name:"Shwazen", color:"#b3b3b3", base:0}, + {name:"Angshire", color:"#fca463", base:1}, + {name:"Luari", color:"#99acfb", base:2}, + {name:"Tallian", color:"#a6d854", base:3}, + {name:"Toledi", color:"#ffd92f", base:4}, + {name:"Slovian", color:"#e5c494", base:5}, + {name:"Norse", color:"#dca3e4", base:6}, + {name:"Elladian", color:"#96d6be", base:7}, + {name:"Latian", color:"#ff7174", base:8}, + {name:"Somi", color:"#aedff7", base:9}, + {name:"Koryo", color:"#578880", base:10}, + {name:"Hantzu", color:"#fdface", base:11}, + {name:"Yamoto", color:"#ffd9da", base:12} ]; } // apply default names data function applyDefaultNamesData() { nameBases = [ // min; max; mean; common - { name: "German", method: "let-to-syl", min: 4, max: 11, d: "lt", m: 0.1 }, // real: 3; 17; 8.6; 8 - { name: "English", method: "let-to-syl", min: 5, max: 10, d: "", m: 0.3 }, // real: 4; 13; 7.9; 8 - { name: "French", method: "let-to-syl", min: 4, max: 10, d: "lns", m: 0.3 }, // real: 3; 15; 7.6; 6 - { name: "Italian", method: "let-to-syl", min: 4, max: 11, d: "clrt", m: 0.2 }, // real: 4; 14; 7.7; 7 - { name: "Castillian", method: "let-to-syl", min: 4, max: 10, d: "lr", m: 0 }, // real: 2; 13; 7.5; 8 - { name: "Ruthenian", method: "let-to-syl", min: 4, max: 9, d: "", m: 0 }, // real: 3; 12; 7.1; 7 - { name: "Nordic", method: "let-to-syl", min: 5, max: 9, d: "kln", m: 0.1 }, // real: 3; 12; 7.5; 6 - { name: "Greek", method: "let-to-syl", min: 4, max: 10, d: "ls", m: 0.2 }, // real: 3; 14; 7.1; 6 - { name: "Roman", method: "let-to-syl", min: 5, max: 10, d: "", m: 1 }, // real: 3; 15; 8.0; 7 - { name: "Finnic", method: "let-to-syl", min: 3, max: 10, d: "aktu", m: 0 }, // real: 3; 13; 7.5; 6 - { name: "Korean", method: "let-to-syl", min: 5, max: 10, d: "", m: 0 }, // real: 3; 13; 6.8; 7 - { name: "Chinese", method: "let-to-syl", min: 5, max: 9, d: "", m: 0 }, // real: 4; 11; 6.9; 6 - { name: "Japanese", method: "let-to-syl", min: 3, max: 9, d: "", m: 0 } // real: 2; 15; 6.8; 6 + {name: "German", method: "let-to-syl", min: 4, max: 11, d: "lt", m: 0.1}, // real: 3; 17; 8.6; 8 + {name: "English", method: "let-to-syl", min: 5, max: 10, d: "", m: 0.3}, // real: 4; 13; 7.9; 8 + {name: "French", method: "let-to-syl", min: 4, max: 10, d: "lns", m: 0.3}, // real: 3; 15; 7.6; 6 + {name: "Italian", method: "let-to-syl", min: 4, max: 11, d: "clrt", m: 0.2}, // real: 4; 14; 7.7; 7 + {name: "Castillian", method: "let-to-syl", min: 4, max: 10, d: "lr", m: 0}, // real: 2; 13; 7.5; 8 + {name: "Ruthenian", method: "let-to-syl", min: 4, max: 9, d: "", m: 0}, // real: 3; 12; 7.1; 7 + {name: "Nordic", method: "let-to-syl", min: 5, max: 9, d: "kln", m: 0.1}, // real: 3; 12; 7.5; 6 + {name: "Greek", method: "let-to-syl", min: 4, max: 10, d: "ls", m: 0.2}, // real: 3; 14; 7.1; 6 + {name: "Roman", method: "let-to-syl", min: 5, max: 10, d: "", m: 1}, // real: 3; 15; 8.0; 7 + {name: "Finnic", method: "let-to-syl", min: 3, max: 10, d: "aktu", m: 0}, // real: 3; 13; 7.5; 6 + {name: "Korean", method: "let-to-syl", min: 5, max: 10, d: "", m: 0}, // real: 3; 13; 6.8; 7 + {name: "Chinese", method: "let-to-syl", min: 5, max: 9, d: "", m: 0}, // real: 4; 11; 6.9; 6 + {name: "Japanese", method: "let-to-syl", min: 3, max: 9, d: "", m: 0} // real: 2; 15; 6.8; 6 ]; nameBase = [ - ["Achern", "Aichhalden", "Aitern", "Albbruck", "Alpirsbach", "Altensteig", "Althengstett", "Appenweier", "Auggen", "Wildbad", "Badenen", "Badenweiler", "Baiersbronn", "Ballrechten", "Bellingen", "Berghaupten", "Bernau", "Biberach", "Biederbach", "Binzen", "Birkendorf", "Birkenfeld", "Bischweier", "Blumberg", "Bollen", "Bollschweil", "Bonndorf", "Bosingen", "Braunlingen", "Breisach", "Breisgau", "Breitnau", "Brigachtal", "Buchenbach", "Buggingen", "Buhl", "Buhlertal", "Calw", "Dachsberg", "Dobel", "Donaueschingen", "Dornhan", "Dornstetten", "Dottingen", "Dunningen", "Durbach", "Durrheim", "Ebhausen", "Ebringen", "Efringen", "Egenhausen", "Ehrenkirchen", "Ehrsberg", "Eimeldingen", "Eisenbach", "Elzach", "Elztal", "Emmendingen", "Endingen", "Engelsbrand", "Enz", "Enzklosterle", "Eschbronn", "Ettenheim", "Ettlingen", "Feldberg", "Fischerbach", "Fischingen", "Fluorn", "Forbach", "Freiamt", "Freiburg", "Freudenstadt", "Friedenweiler", "Friesenheim", "Frohnd", "Furtwangen", "Gaggenau", "Geisingen", "Gengenbach", "Gernsbach", "Glatt", "Glatten", "Glottertal", "Gorwihl", "Gottenheim", "Grafenhausen", "Grenzach", "Griesbach", "Gutach", "Gutenbach", "Hag", "Haiterbach", "Hardt", "Harmersbach", "Hasel", "Haslach", "Hausach", "Hausen", "Hausern", "Heitersheim", "Herbolzheim", "Herrenalb", "Herrischried", "Hinterzarten", "Hochenschwand", "Hofen", "Hofstetten", "Hohberg", "Horb", "Horben", "Hornberg", "Hufingen", "Ibach", "Ihringen", "Inzlingen", "Kandern", "Kappel", "Kappelrodeck", "Karlsbad", "Karlsruhe", "Kehl", "Keltern", "Kippenheim", "Kirchzarten", "Konigsfeld", "Krozingen", "Kuppenheim", "Kussaberg", "Lahr", "Lauchringen", "Lauf", "Laufenburg", "Lautenbach", "Lauterbach", "Lenzkirch", "Liebenzell", "Loffenau", "Loffingen", "Lorrach", "Lossburg", "Mahlberg", "Malsburg", "Malsch", "March", "Marxzell", "Marzell", "Maulburg", "Monchweiler", "Muhlenbach", "Mullheim", "Munstertal", "Murg", "Nagold", "Neubulach", "Neuenburg", "Neuhausen", "Neuried", "Neuweiler", "Niedereschach", "Nordrach", "Oberharmersbach", "Oberkirch", "Oberndorf", "Oberbach", "Oberried", "Oberwolfach", "Offenburg", "Ohlsbach", "Oppenau", "Ortenberg", "otigheim", "Ottenhofen", "Ottersweier", "Peterstal", "Pfaffenweiler", "Pfalzgrafenweiler", "Pforzheim", "Rastatt", "Renchen", "Rheinau", "Rheinfelden", "Rheinmunster", "Rickenbach", "Rippoldsau", "Rohrdorf", "Rottweil", "Rummingen", "Rust", "Sackingen", "Sasbach", "Sasbachwalden", "Schallbach", "Schallstadt", "Schapbach", "Schenkenzell", "Schiltach", "Schliengen", "Schluchsee", "Schomberg", "Schonach", "Schonau", "Schonenberg", "Schonwald", "Schopfheim", "Schopfloch", "Schramberg", "Schuttertal", "Schwenningen", "Schworstadt", "Seebach", "Seelbach", "Seewald", "Sexau", "Simmersfeld", "Simonswald", "Sinzheim", "Solden", "Staufen", "Stegen", "Steinach", "Steinen", "Steinmauern", "Straubenhardt", "Stuhlingen", "Sulz", "Sulzburg", "Teinach", "Tiefenbronn", "Tiengen", "Titisee", "Todtmoos", "Todtnau", "Todtnauberg", "Triberg", "Tunau", "Tuningen", "uhlingen", "Unterkirnach", "Reichenbach", "Utzenfeld", "Villingen", "Villingendorf", "Vogtsburg", "Vohrenbach", "Waldachtal", "Waldbronn", "Waldkirch", "Waldshut", "Wehr", "Weil", "Weilheim", "Weisenbach", "Wembach", "Wieden", "Wiesental", "Wildberg", "Winzeln", "Wittlingen", "Wittnau", "Wolfach", "Wutach", "Wutoschingen", "Wyhlen", "Zavelstein"], - ["Abingdon", "Albrighton", "Alcester", "Almondbury", "Altrincham", "Amersham", "Andover", "Appleby", "Ashboume", "Atherstone", "Aveton", "Axbridge", "Aylesbury", "Baldock", "Bamburgh", "Barton", "Basingstoke", "Berden", "Bere", "Berkeley", "Berwick", "Betley", "Bideford", "Bingley", "Birmingham", "Blandford", "Blechingley", "Bodmin", "Bolton", "Bootham", "Boroughbridge", "Boscastle", "Bossinney", "Bramber", "Brampton", "Brasted", "Bretford", "Bridgetown", "Bridlington", "Bromyard", "Bruton", "Buckingham", "Bungay", "Burton", "Calne", "Cambridge", "Canterbury", "Carlisle", "Castleton", "Caus", "Charmouth", "Chawleigh", "Chichester", "Chillington", "Chinnor", "Chipping", "Chisbury", "Cleobury", "Clifford", "Clifton", "Clitheroe", "Cockermouth", "Coleshill", "Combe", "Congleton", "Crafthole", "Crediton", "Cuddenbeck", "Dalton", "Darlington", "Dodbrooke", "Drax", "Dudley", "Dunstable", "Dunster", "Dunwich", "Durham", "Dymock", "Exeter", "Exning", "Faringdon", "Felton", "Fenny", "Finedon", "Flookburgh", "Fowey", "Frampton", "Gateshead", "Gatton", "Godmanchester", "Grampound", "Grantham", "Guildford", "Halesowen", "Halton", "Harbottle", "Harlow", "Hatfield", "Hatherleigh", "Haydon", "Helston", "Henley", "Hertford", "Heytesbury", "Hinckley", "Hitchin", "Holme", "Hornby", "Horsham", "Kendal", "Kenilworth", "Kilkhampton", "Kineton", "Kington", "Kinver", "Kirby", "Knaresborough", "Knutsford", "Launceston", "Leighton", "Lewes", "Linton", "Louth", "Luton", "Lyme", "Lympstone", "Macclesfield", "Madeley", "Malborough", "Maldon", "Manchester", "Manningtree", "Marazion", "Marlborough", "Marshfield", "Mere", "Merryfield", "Middlewich", "Midhurst", "Milborne", "Mitford", "Modbury", "Montacute", "Mousehole", "Newbiggin", "Newborough", "Newbury", "Newenden", "Newent", "Norham", "Northleach", "Noss", "Oakham", "Olney", "Orford", "Ormskirk", "Oswestry", "Padstow", "Paignton", "Penkneth", "Penrith", "Penzance", "Pershore", "Petersfield", "Pevensey", "Pickering", "Pilton", "Pontefract", "Portsmouth", "Preston", "Quatford", "Reading", "Redcliff", "Retford", "Rockingham", "Romney", "Rothbury", "Rothwell", "Salisbury", "Saltash", "Seaford", "Seasalter", "Sherston", "Shifnal", "Shoreham", "Sidmouth", "Skipsea", "Skipton", "Solihull", "Somerton", "Southam", "Southwark", "Standon", "Stansted", "Stapleton", "Stottesdon", "Sudbury", "Swavesey", "Tamerton", "Tarporley", "Tetbury", "Thatcham", "Thaxted", "Thetford", "Thornbury", "Tintagel", "Tiverton", "Torksey", "Totnes", "Towcester", "Tregoney", "Trematon", "Tutbury", "Uxbridge", "Wallingford", "Wareham", "Warenmouth", "Wargrave", "Warton", "Watchet", "Watford", "Wendover", "Westbury", "Westcheap", "Weymouth", "Whitford", "Wickwar", "Wigan", "Wigmore", "Winchelsea", "Winkleigh", "Wiscombe", "Witham", "Witheridge", "Wiveliscombe", "Woodbury", "Yeovil"], - ["Adon", "Aillant", "Amilly", "Andonville", "Ardon", "Artenay", "Ascheres", "Ascoux", "Attray", "Aubin", "Audeville", "Aulnay", "Autruy", "Auvilliers", "Auxy", "Aveyron", "Baccon", "Bardon", "Barville", "Batilly", "Baule", "Bazoches", "Beauchamps", "Beaugency", "Beaulieu", "Beaune", "Bellegarde", "Boesses", "Boigny", "Boiscommun", "Boismorand", "Boisseaux", "Bondaroy", "Bonnee", "Bonny", "Bordes", "Bou", "Bougy", "Bouilly", "Boulay", "Bouzonville", "Bouzy", "Boynes", "Bray", "Breteau", "Briare", "Briarres", "Bricy", "Bromeilles", "Bucy", "Cepoy", "Cercottes", "Cerdon", "Cernoy", "Cesarville", "Chailly", "Chaingy", "Chalette", "Chambon", "Champoulet", "Chanteau", "Chantecoq", "Chapell", "Charme", "Charmont", "Charsonville", "Chateau", "Chateauneuf", "Chatel", "Chatenoy", "Chatillon", "Chaussy", "Checy", "Chevannes", "Chevillon", "Chevilly", "Chevry", "Chilleurs", "Choux", "Chuelles", "Clery", "Coinces", "Coligny", "Combleux", "Combreux", "Conflans", "Corbeilles", "Corquilleroy", "Cortrat", "Coudroy", "Coullons", "Coulmiers", "Courcelles", "Courcy", "Courtemaux", "Courtempierre", "Courtenay", "Cravant", "Crottes", "Dadonville", "Dammarie", "Dampierre", "Darvoy", "Desmonts", "Dimancheville", "Donnery", "Dordives", "Dossainville", "Douchy", "Dry", "Echilleuses", "Egry", "Engenville", "Epieds", "Erceville", "Ervauville", "Escrennes", "Escrignelles", "Estouy", "Faverelles", "Fay", "Feins", "Ferolles", "Ferrieres", "Fleury", "Fontenay", "Foret", "Foucherolles", "Freville", "Gatinais", "Gaubertin", "Gemigny", "Germigny", "Gidy", "Gien", "Girolles", "Givraines", "Gondreville", "Grangermont", "Greneville", "Griselles", "Guigneville", "Guilly", "Gyleslonains", "Huetre", "Huisseau", "Ingrannes", "Ingre", "Intville", "Isdes", "Jargeau", "Jouy", "Juranville", "Bussiere", "Laas", "Ladon", "Lailly", "Langesse", "Leouville", "Ligny", "Lombreuil", "Lorcy", "Lorris", "Loury", "Louzouer", "Malesherbois", "Marcilly", "Mardie", "Mareau", "Marigny", "Marsainvilliers", "Melleroy", "Menestreau", "Merinville", "Messas", "Meung", "Mezieres", "Migneres", "Mignerette", "Mirabeau", "Montargis", "Montbarrois", "Montbouy", "Montcresson", "Montereau", "Montigny", "Montliard", "Mormant", "Morville", "Moulinet", "Moulon", "Nancray", "Nargis", "Nesploy", "Neuville", "Neuvy", "Nevoy", "Nibelle", "Nogent", "Noyers", "Ocre", "Oison", "Olivet", "Ondreville", "Onzerain", "Orleans", "Ormes", "Orville", "Oussoy", "Outarville", "Ouzouer", "Pannecieres", "Pannes", "Patay", "Paucourt", "Pers", "Pierrefitte", "Pithiverais", "Pithiviers", "Poilly", "Potier", "Prefontaines", "Presnoy", "Pressigny", "Puiseaux", "Quiers", "Ramoulu", "Rebrechien", "Rouvray", "Rozieres", "Rozoy", "Ruan", "Sandillon", "Santeau", "Saran", "Sceaux", "Seichebrieres", "Semoy", "Sennely", "Sermaises", "Sigloy", "Solterre", "Sougy", "Sully", "Sury", "Tavers", "Thignonville", "Thimory", "Thorailles", "Thou", "Tigy", "Tivernon", "Tournoisis", "Trainou", "Treilles", "Trigueres", "Trinay", "Vannes", "Varennes", "Vennecy", "Vieilles", "Vienne", "Viglain", "Vignes", "Villamblain", "Villemandeur", "Villemoutiers", "Villemurlin", "Villeneuve", "Villereau", "Villevoques", "Villorceau", "Vimory", "Vitry", "Vrigny", "Ivre"], - ["Accumoli", "Acquafondata", "Acquapendente", "Acuto", "Affile", "Agosta", "Alatri", "Albano", "Allumiere", "Alvito", "Amaseno", "Amatrice", "Anagni", "Anguillara", "Anticoli", "Antrodoco", "Anzio", "Aprilia", "Aquino", "Arce", "Arcinazzo", "Ardea", "Ariccia", "Arlena", "Arnara", "Arpino", "Arsoli", "Artena", "Ascrea", "Atina", "Ausonia", "Bagnoregio", "Barbarano", "Bassano", "Bassiano", "Bellegra", "Belmonte", "Blera", "Bolsena", "Bomarzo", "Borbona", "Borgo", "Borgorose", "Boville", "Bracciano", "Broccostella", "Calcata", "Camerata", "Campagnano", "Campodimele", "Campoli", "Canale", "Canepina", "Canino", "Cantalice", "Cantalupo", "Canterano", "Capena", "Capodimonte", "Capranica", "Caprarola", "Carbognano", "Casalattico", "Casalvieri", "Casape", "Casaprota", "Casperia", "Cassino", "Castelforte", "Castelliri", "Castello", "Castelnuovo", "Castiglione", "Castro", "Castrocielo", "Cave", "Ceccano", "Celleno", "Cellere", "Ceprano", "Cerreto", "Cervara", "Cervaro", "Cerveteri", "Ciampino", "Ciciliano", "Cineto", "Cisterna", "Cittaducale", "Cittareale", "Civita", "Civitavecchia", "Civitella", "Colfelice", "Collalto", "Colle", "Colleferro", "Collegiove", "Collepardo", "Collevecchio", "Colli", "Colonna", "Concerviano", "Configni", "Contigliano", "Corchiano", "Coreno", "Cori", "Cottanello", "Esperia", "Fabrica", "Faleria", "Falvaterra", "Fara", "Farnese", "Ferentino", "Fiamignano", "Fiano", "Filacciano", "Filettino", "Fiuggi", "Fiumicino", "Fondi", "Fontana", "Fonte", "Fontechiari", "Forano", "Formello", "Formia", "Frascati", "Frasso", "Frosinone", "Fumone", "Gaeta", "Gallese", "Gallicano", "Gallinaro", "Gavignano", "Genazzano", "Genzano", "Gerano", "Giuliano", "Gorga", "Gradoli", "Graffignano", "Greccio", "Grottaferrata", "Grotte", "Guarcino", "Guidonia", "Ischia", "Isola", "Itri", "Jenne", "Labico", "Labro", "Ladispoli", "Lanuvio", "Lariano", "Latera", "Lenola", "Leonessa", "Licenza", "Longone", "Lubriano", "Maenza", "Magliano", "Mandela", "Manziana", "Marano", "Marcellina", "Marcetelli", "Marino", "Marta", "Mazzano", "Mentana", "Micigliano", "Minturno", "Mompeo", "Montalto", "Montasola", "Monte", "Montebuono", "Montefiascone", "Monteflavio", "Montelanico", "Monteleone", "Montelibretti", "Montenero", "Monterosi", "Monterotondo", "Montopoli", "Montorio", "Moricone", "Morlupo", "Morolo", "Morro", "Nazzano", "Nemi", "Nepi", "Nerola", "Nespolo", "Nettuno", "Norma", "Olevano", "Onano", "Oriolo", "Orte", "Orvinio", "Paganico", "Palestrina", "Paliano", "Palombara", "Pastena", "Patrica", "Percile", "Pescorocchiano", "Pescosolido", "Petrella", "Piansano", "Picinisco", "Pico", "Piedimonte", "Piglio", "Pignataro", "Pisoniano", "Pofi", "Poggio", "Poli", "Pomezia", "Pontecorvo", "Pontinia", "Ponza", "Ponzano", "Posta", "Pozzaglia", "Priverno", "Proceno", "Prossedi", "Riano", "Rieti", "Rignano", "Riofreddo", "Ripi", "Rivodutri", "Rocca", "Roccagiovine", "Roccagorga", "Roccantica", "Roccasecca", "Roiate", "Ronciglione", "Roviano", "Sabaudia", "Sacrofano", "Salisano", "Sambuci", "Santa", "Santi", "Santopadre", "Saracinesco", "Scandriglia", "Segni", "Selci", "Sermoneta", "Serrone", "Settefrati", "Sezze", "Sgurgola", "Sonnino", "Sora", "Soriano", "Sperlonga", "Spigno", "Stimigliano", "Strangolagalli", "Subiaco", "Supino", "Sutri", "Tarano", "Tarquinia", "Terelle", "Terracina", "Tessennano", "Tivoli", "Toffia", "Tolfa", "Torre", "Torri", "Torrice", "Torricella", "Torrita", "Trevi", "Trevignano", "Trivigliano", "Turania", "Tuscania", "Vacone", "Valentano", "Vallecorsa", "Vallemaio", "Vallepietra", "Vallerano", "Vallerotonda", "Vallinfreda", "Valmontone", "Varco", "Vasanello", "Vejano", "Velletri", "Ventotene", "Veroli", "Vetralla", "Vicalvi", "Vico", "Vicovaro", "Vignanello", "Viterbo", "Viticuso", "Vitorchiano", "Vivaro", "Zagarolo"], - ["Abanades", "Ablanque", "Adobes", "Ajofrin", "Alameda", "Alaminos", "Alarilla", "Albalate", "Albares", "Albarreal", "Albendiego", "Alcabon", "Alcanizo", "Alcaudete", "Alcocer", "Alcolea", "Alcoroches", "Aldea", "Aldeanueva", "Algar", "Algora", "Alhondiga", "Alique", "Almadrones", "Almendral", "Almoguera", "Almonacid", "Almorox", "Alocen", "Alovera", "Alustante", "Angon", "Anguita", "Anover", "Anquela", "Arbancon", "Arbeteta", "Arcicollar", "Argecilla", "Arges", "Armallones", "Armuna", "Arroyo", "Atanzon", "Atienza", "Aunon", "Azuqueca", "Azutan", "Baides", "Banos", "Banuelos", "Barcience", "Bargas", "Barriopedro", "Belvis", "Berninches", "Borox", "Brihuega", "Budia", "Buenaventura", "Bujalaro", "Burguillos", "Burujon", "Bustares", "Cabanas", "Cabanillas", "Calera", "Caleruela", "Calzada", "Camarena", "Campillo", "Camunas", "Canizar", "Canredondo", "Cantalojas", "Cardiel", "Carmena", "Carranque", "Carriches", "Casa", "Casarrubios", "Casas", "Casasbuenas", "Caspuenas", "Castejon", "Castellar", "Castilforte", "Castillo", "Castilnuevo", "Cazalegas", "Cebolla", "Cedillo", "Cendejas", "Centenera", "Cervera", "Checa", "Chequilla", "Chillaron", "Chiloeches", "Chozas", "Chueca", "Cifuentes", "Cincovillas", "Ciruelas", "Ciruelos", "Cobeja", "Cobeta", "Cobisa", "Cogollor", "Cogolludo", "Condemios", "Congostrina", "Consuegra", "Copernal", "Corduente", "Corral", "Cuerva", "Domingo", "Dosbarrios", "Driebes", "Duron", "El", "Embid", "Erustes", "Escalona", "Escalonilla", "Escamilla", "Escariche", "Escopete", "Espinosa", "Espinoso", "Esplegares", "Esquivias", "Estables", "Estriegana", "Fontanar", "Fuembellida", "Fuensalida", "Fuentelsaz", "Gajanejos", "Galve", "Galvez", "Garciotum", "Gascuena", "Gerindote", "Guadamur", "Henche", "Heras", "Herreria", "Herreruela", "Hijes", "Hinojosa", "Hita", "Hombrados", "Hontanar", "Hontoba", "Horche", "Hormigos", "Huecas", "Huermeces", "Huerta", "Hueva", "Humanes", "Illan", "Illana", "Illescas", "Iniestola", "Irueste", "Jadraque", "Jirueque", "Lagartera", "Las", "Layos", "Ledanca", "Lillo", "Lominchar", "Loranca", "Los", "Lucillos", "Lupiana", "Luzaga", "Luzon", "Madridejos", "Magan", "Majaelrayo", "Malaga", "Malaguilla", "Malpica", "Mandayona", "Mantiel", "Manzaneque", "Maqueda", "Maranchon", "Marchamalo", "Marjaliza", "Marrupe", "Mascaraque", "Masegoso", "Matarrubia", "Matillas", "Mazarete", "Mazuecos", "Medranda", "Megina", "Mejorada", "Mentrida", "Mesegar", "Miedes", "Miguel", "Millana", "Milmarcos", "Mirabueno", "Miralrio", "Mocejon", "Mochales", "Mohedas", "Molina", "Monasterio", "Mondejar", "Montarron", "Mora", "Moratilla", "Morenilla", "Muduex", "Nambroca", "Navalcan", "Negredo", "Noblejas", "Noez", "Nombela", "Noves", "Numancia", "Nuno", "Ocana", "Ocentejo", "Olias", "Olmeda", "Ontigola", "Orea", "Orgaz", "Oropesa", "Otero", "Palmaces", "Palomeque", "Pantoja", "Pardos", "Paredes", "Pareja", "Parrillas", "Pastrana", "Pelahustan", "Penalen", "Penalver", "Pepino", "Peralejos", "Peralveche", "Pinilla", "Pioz", "Piqueras", "Polan", "Portillo", "Poveda", "Pozo", "Pradena", "Prados", "Puebla", "Puerto", "Pulgar", "Quer", "Quero", "Quintanar", "Quismondo", "Rebollosa", "Recas", "Renera", "Retamoso", "Retiendas", "Riba", "Rielves", "Rillo", "Riofrio", "Robledillo", "Robledo", "Romanillos", "Romanones", "Rueda", "Sacecorbo", "Sacedon", "Saelices", "Salmeron", "San", "Santa", "Santiuste", "Santo", "Sartajada", "Sauca", "Sayaton", "Segurilla", "Selas", "Semillas", "Sesena", "Setiles", "Sevilleja", "Sienes", "Siguenza", "Solanillos", "Somolinos", "Sonseca", "Sotillo", "Sotodosos", "Talavera", "Tamajon", "Taragudo", "Taravilla", "Tartanedo", "Tembleque", "Tendilla", "Terzaga", "Tierzo", "Tordellego", "Tordelrabano", "Tordesilos", "Torija", "Torralba", "Torre", "Torrecilla", "Torrecuadrada", "Torrejon", "Torremocha", "Torrico", "Torrijos", "Torrubia", "Tortola", "Tortuera", "Tortuero", "Totanes", "Traid", "Trijueque", "Trillo", "Turleque", "Uceda", "Ugena", "Ujados", "Urda", "Utande", "Valdarachas", "Valdesotos", "Valhermoso", "Valtablado", "Valverde", "Velada", "Viana", "Vinuelas", "Yebes", "Yebra", "Yelamos", "Yeles", "Yepes", "Yuncler", "Yunclillos", "Yuncos", "Yunquera", "Zaorejas", "Zarzuela", "Zorita"], - ["Belgorod", "Beloberezhye", "Belyi", "Belz", "Berestiy", "Berezhets", "Berezovets", "Berezutsk", "Bobruisk", "Bolonets", "Borisov", "Borovsk", "Bozhesk", "Bratslav", "Bryansk", "Brynsk", "Buryn", "Byhov", "Chechersk", "Chemesov", "Cheremosh", "Cherlen", "Chern", "Chernigov", "Chernitsa", "Chernobyl", "Chernogorod", "Chertoryesk", "Chetvertnia", "Demyansk", "Derevesk", "Devyagoresk", "Dichin", "Dmitrov", "Dorogobuch", "Dorogobuzh", "Drestvin", "Drokov", "Drutsk", "Dubechin", "Dubichi", "Dubki", "Dubkov", "Dveren", "Galich", "Glebovo", "Glinsk", "Goloty", "Gomiy", "Gorodets", "Gorodische", "Gorodno", "Gorohovets", "Goroshin", "Gorval", "Goryshon", "Holm", "Horobor", "Hoten", "Hotin", "Hotmyzhsk", "Ilovech", "Ivan", "Izborsk", "Izheslavl", "Kamenets", "Kanev", "Karachev", "Karna", "Kavarna", "Klechesk", "Klyapech", "Kolomyya", "Kolyvan", "Kopyl", "Korec", "Kornik", "Korochunov", "Korshev", "Korsun", "Koshkin", "Kotelno", "Kovyla", "Kozelsk", "Kozelsk", "Kremenets", "Krichev", "Krylatsk", "Ksniatin", "Kulatsk", "Kursk", "Kursk", "Lebedev", "Lida", "Logosko", "Lomihvost", "Loshesk", "Loshichi", "Lubech", "Lubno", "Lubutsk", "Lutsk", "Luchin", "Luki", "Lukoml", "Luzha", "Lvov", "Mtsensk", "Mdin", "Medniki", "Melecha", "Merech", "Meretsk", "Mescherskoe", "Meshkovsk", "Metlitsk", "Mezetsk", "Mglin", "Mihailov", "Mikitin", "Mikulino", "Miloslavichi", "Mogilev", "Mologa", "Moreva", "Mosalsk", "Moschiny", "Mozyr", "Mstislav", "Mstislavets", "Muravin", "Nemech", "Nemiza", "Nerinsk", "Nichan", "Novgorod", "Novogorodok", "Obolichi", "Obolensk", "Obolensk", "Oleshsk", "Olgov", "Omelnik", "Opoka", "Opoki", "Oreshek", "Orlets", "Osechen", "Oster", "Ostrog", "Ostrov", "Perelai", "Peremil", "Peremyshl", "Pererov", "Peresechen", "Perevitsk", "Pereyaslav", "Pinsk", "Ples", "Polotsk", "Pronsk", "Proposhesk", "Punia", "Putivl", "Rechitsa", "Rodno", "Rogachev", "Romanov", "Romny", "Roslavl", "Rostislavl", "Rostovets", "Rsha", "Ruza", "Rybchesk", "Rylsk", "Rzhavesk", "Rzhev", "Rzhischev", "Sambor", "Serensk", "Serensk", "Serpeysk", "Shilov", "Shuya", "Sinech", "Sizhka", "Skala", "Slovensk", "Slutsk", "Smedin", "Sneporod", "Snitin", "Snovsk", "Sochevo", "Sokolec", "Starica", "Starodub", "Stepan", "Sterzh", "Streshin", "Sutesk", "Svinetsk", "Svisloch", "Terebovl", "Ternov", "Teshilov", "Teterin", "Tiversk", "Torchevsk", "Toropets", "Torzhok", "Tripolye", "Trubchevsk", "Tur", "Turov", "Usvyaty", "Uteshkov", "Vasilkov", "Velil", "Velye", "Venev", "Venicha", "Verderev", "Vereya", "Veveresk", "Viazma", "Vidbesk", "Vidychev", "Voino", "Volodimer", "Volok", "Volyn", "Vorobesk", "Voronich", "Voronok", "Vorotynsk", "Vrev", "Vruchiy", "Vselug", "Vyatichsk", "Vyatka", "Vyshegorod", "Vyshgorod", "Vysokoe", "Yagniatin", "Yaropolch", "Yasenets", "Yuryev", "Yuryevets", "Zaraysk", "Zhitomel", "Zholvazh", "Zizhech", "Zubkov", "Zudechev", "Zvenigorod"], - ["Akureyri", "Aldra", "Alftanes", "Andenes", "Austbo", "Auvog", "Bakkafjordur", "Ballangen", "Bardal", "Beisfjord", "Bifrost", "Bildudalur", "Bjerka", "Bjerkvik", "Bjorkosen", "Bliksvaer", "Blokken", "Blonduos", "Bolga", "Bolungarvik", "Borg", "Borgarnes", "Bosmoen", "Bostad", "Bostrand", "Botsvika", "Brautarholt", "Breiddalsvik", "Bringsli", "Brunahlid", "Budardalur", "Byggdakjarni", "Dalvik", "Djupivogur", "Donnes", "Drageid", "Drangsnes", "Egilsstadir", "Eiteroga", "Elvenes", "Engavogen", "Ertenvog", "Eskifjordur", "Evenes", "Eyrarbakki", "Fagernes", "Fallmoen", "Fellabaer", "Fenes", "Finnoya", "Fjaer", "Fjelldal", "Flakstad", "Flateyri", "Flostrand", "Fludir", "Gardabær", "Gardur", "Gimstad", "Givaer", "Gjeroy", "Gladstad", "Godoya", "Godoynes", "Granmoen", "Gravdal", "Grenivik", "Grimsey", "Grindavik", "Grytting", "Hafnir", "Halsa", "Hauganes", "Haugland", "Hauknes", "Hella", "Helland", "Hellissandur", "Hestad", "Higrav", "Hnifsdalur", "Hofn", "Hofsos", "Holand", "Holar", "Holen", "Holkestad", "Holmavik", "Hopen", "Hovden", "Hrafnagil", "Hrisey", "Husavik", "Husvik", "Hvammstangi", "Hvanneyri", "Hveragerdi", "Hvolsvollur", "Igeroy", "Indre", "Inndyr", "Innhavet", "Innes", "Isafjordur", "Jarklaustur", "Jarnsreykir", "Junkerdal", "Kaldvog", "Kanstad", "Karlsoy", "Kavosen", "Keflavik", "Kjelde", "Kjerstad", "Klakk", "Kopasker", "Kopavogur", "Korgen", "Kristnes", "Krutoga", "Krystad", "Kvina", "Lande", "Laugar", "Laugaras", "Laugarbakki", "Laugarvatn", "Laupstad", "Leines", "Leira", "Leiren", "Leland", "Lenvika", "Loding", "Lodingen", "Lonsbakki", "Lopsmarka", "Lovund", "Luroy", "Maela", "Melahverfi", "Meloy", "Mevik", "Misvaer", "Mornes", "Mosfellsbær", "Moskenes", "Myken", "Naurstad", "Nesberg", "Nesjahverfi", "Nesset", "Nevernes", "Obygda", "Ofoten", "Ogskardet", "Okervika", "Oknes", "Olafsfjordur", "Oldervika", "Olstad", "Onstad", "Oppeid", "Oresvika", "Orsnes", "Orsvog", "Osmyra", "Overdal", "Prestoya", "Raudalaekur", "Raufarhofn", "Reipo", "Reykholar", "Reykholt", "Reykjahlid", "Rif", "Rinoya", "Rodoy", "Rognan", "Rosvika", "Rovika", "Salhus", "Sanden", "Sandgerdi", "Sandoker", "Sandset", "Sandvika", "Saudarkrokur", "Selfoss", "Selsoya", "Sennesvik", "Setso", "Siglufjordur", "Silvalen", "Skagastrond", "Skjerstad", "Skonland", "Skorvogen", "Skrova", "Sleneset", "Snubba", "Softing", "Solheim", "Solheimar", "Sorarnoy", "Sorfugloy", "Sorland", "Sormela", "Sorvaer", "Sovika", "Stamsund", "Stamsvika", "Stave", "Stokka", "Stokkseyri", "Storjord", "Storo", "Storvika", "Strand", "Straumen", "Strendene", "Sudavik", "Sudureyri", "Sundoya", "Sydalen", "Thingeyri", "Thorlakshofn", "Thorshofn", "Tjarnabyggd", "Tjotta", "Tosbotn", "Traelnes", "Trofors", "Trones", "Tverro", "Ulvsvog", "Unnstad", "Utskor", "Valla", "Vandved", "Varmahlid", "Vassos", "Vevelstad", "Vidrek", "Vik", "Vikholmen", "Vogar", "Vogehamn", "Vopnafjordur"], - ["Abdera", "Abila", "Abydos", "Acanthus", "Acharnae", "Actium", "Adramyttium", "Aegae", "Aegina", "Aegium", "Aenus", "Agrinion", "Aigosthena", "Akragas", "Akrai", "Akrillai", "Akroinon", "Akrotiri", "Alalia", "Alexandreia", "Alexandretta", "Alexandria", "Alinda", "Amarynthos", "Amaseia", "Ambracia", "Amida", "Amisos", "Amnisos", "Amphicaea", "Amphigeneia", "Amphipolis", "Amphissa", "Ankon", "Antigona", "Antipatrea", "Antioch", "Antioch", "Antiochia", "Andros", "Apamea", "Aphidnae", "Apollonia", "Argos", "Arsuf", "Artanes", "Artemita", "Argyroupoli", "Asine", "Asklepios", "Aspendos", "Assus", "Astacus", "Athenai", "Athmonia", "Aytos", "Ancient", "Baris", "Bhrytos", "Borysthenes", "Berge", "Boura", "Bouthroton", "Brauron", "Byblos", "Byllis", "Byzantium", "Bythinion", "Callipolis", "Cebrene", "Chalcedon", "Calydon", "Carystus", "Chamaizi", "Chalcis", "Chersonesos", "Chios", "Chytri", "Clazomenae", "Cleonae", "Cnidus", "Colosse", "Corcyra", "Croton", "Cyme", "Cyrene", "Cythera", "Decelea", "Delos", "Delphi", "Demetrias", "Dicaearchia", "Dimale", "Didyma", "Dion", "Dioscurias", "Dodona", "Dorylaion", "Dyme", "Edessa", "Elateia", "Eleusis", "Eleutherna", "Emporion", "Ephesus", "Ephyra", "Epidamnos", "Epidauros", "Eresos", "Eretria", "Erythrae", "Eubea", "Gangra", "Gaza", "Gela", "Golgi", "Gonnos", "Gorgippia", "Gournia", "Gortyn", "Gythium", "Hagios", "Hagia", "Halicarnassus", "Halieis", "Helike", "Heliopolis", "Hellespontos", "Helorus", "Hemeroskopeion", "Heraclea", "Hermione", "Hermonassa", "Hierapetra", "Hierapolis", "Himera", "Histria", "Hubla", "Hyele", "Ialysos", "Iasus", "Idalium", "Imbros", "Iolcus", "Itanos", "Ithaca", "Juktas", "Kallipolis", "Kamares", "Kameiros", "Kannia", "Kamarina", "Kasmenai", "Katane", "Kerkinitida", "Kepoi", "Kimmerikon", "Kios", "Klazomenai", "Knidos", "Knossos", "Korinthos", "Kos", "Kourion", "Kume", "Kydonia", "Kynos", "Kyrenia", "Lamia", "Lampsacus", "Laodicea", "Lapithos", "Larissa", "Lato", "Laus", "Lebena", "Lefkada", "Lekhaion", "Leibethra", "Leontinoi", "Lepreum", "Lessa", "Lilaea", "Lindus", "Lissus", "Epizephyrian", "Madytos", "Magnesia", "Mallia", "Mantineia", "Marathon", "Marmara", "Maroneia", "Masis", "Massalia", "Megalopolis", "Megara", "Mesembria", "Messene", "Metapontum", "Methana", "Methone", "Methumna", "Miletos", "Misenum", "Mochlos", "Monastiraki", "Morgantina", "Mulai", "Mukenai", "Mylasa", "Myndus", "Myonia", "Myra", "Myrmekion", "Mutilene", "Myos", "Nauplíos", "Naucratis", "Naupactus", "Naxos", "Neapoli", "Neapolis", "Nemea", "Nicaea", "Nicopolis", "Nirou", "Nymphaion", "Nysa", "Oenoe", "Oenus", "Odessos", "Olbia", "Olous", "Olympia", "Olynthus", "Opus", "Orchomenus", "Oricos", "Orestias", "Oreus", "Oropus", "Onchesmos", "Pactye", "Pagasae", "Palaikastro", "Pandosia", "Panticapaeum", "Paphos", "Parium", "Paros", "Parthenope", "Patrae", "Pavlopetri", "Pegai", "Pelion", "Peiraieús", "Pella", "Percote", "Pergamum", "Petsofa", "Phaistos", "Phaleron", "Phanagoria", "Pharae", "Pharnacia", "Pharos", "Phaselis", "Philippi", "Pithekussa", "Philippopolis", "Platanos", "Phlius", "Pherae", "Phocaea", "Pinara", "Pisa", "Pitane", "Pitiunt", "Pixous", "Plataea", "Poseidonia", "Potidaea", "Priapus", "Priene", "Prousa", "Pseira", "Psychro", "Pteleum", "Pydna", "Pylos", "Pyrgos", "Rhamnus", "Rhegion", "Rhithymna", "Rhodes", "Rhypes", "Rizinia", "Salamis", "Same", "Samos", "Scyllaeum", "Selinus", "Seleucia", "Semasus", "Sestos", "Scidrus", "Sicyon", "Side", "Sidon", "Siteia", "Sinope", "Siris", "Sklavokampos", "Smyrna", "Soli", "Sozopolis", "Sparta", "Stagirus", "Stratos", "Stymphalos", "Sybaris", "Surakousai", "Taras", "Tanagra", "Tanais", "Tauromenion", "Tegea", "Temnos", "Tenedos", "Tenea", "Teos", "Thapsos", "Thassos", "Thebai", "Theodosia", "Therma", "Thespiae", "Thronion", "Thoricus", "Thurii", "Thyreum", "Thyria", "Tiruns", "Tithoraea", "Tomis", "Tragurion", "Trapeze", "Trapezus", "Tripolis", "Troizen", "Troliton", "Troy", "Tylissos", "Tyras", "Tyros", "Tyritake", "Vasiliki", "Vathypetros", "Zakynthos", "Zakros", "Zankle"], - ["Abila", "Adflexum", "Adnicrem", "Aelia", "Aelius", "Aeminium", "Aequum", "Agrippina", "Agrippinae", "Ala", "Albanianis", "Ambianum", "Andautonia", "Apulum", "Aquae", "Aquaegranni", "Aquensis", "Aquileia", "Aquincum", "Arae", "Argentoratum", "Ariminum", "Ascrivium", "Atrebatum", "Atuatuca", "Augusta", "Aurelia", "Aurelianorum", "Batavar", "Batavorum", "Belum", "Biriciana", "Blestium", "Bonames", "Bonna", "Bononia", "Borbetomagus", "Bovium", "Bracara", "Brigantium", "Burgodunum", "Caesaraugusta", "Caesarea", "Caesaromagus", "Calleva", "Camulodunum", "Cannstatt", "Cantiacorum", "Capitolina", "Castellum", "Castra", "Castrum", "Cibalae", "Clausentum", "Colonia", "Concangis", "Condate", "Confluentes", "Conimbriga", "Corduba", "Coria", "Corieltauvorum", "Corinium", "Coriovallum", "Cornoviorum", "Danum", "Deva", "Divodurum", "Dobunnorum", "Drusi", "Dubris", "Dumnoniorum", "Durnovaria", "Durocobrivis", "Durocornovium", "Duroliponte", "Durovernum", "Durovigutum", "Eboracum", "Edetanorum", "Emerita", "Emona", "Euracini", "Faventia", "Flaviae", "Florentia", "Forum", "Gerulata", "Gerunda", "Glevensium", "Hadriani", "Herculanea", "Isca", "Italica", "Iulia", "Iuliobrigensium", "Iuvavum", "Lactodurum", "Lagentium", "Lauri", "Legionis", "Lemanis", "Lentia", "Lepidi", "Letocetum", "Lindinis", "Lindum", "Londinium", "Lopodunum", "Lousonna", "Lucus", "Lugdunum", "Luguvalium", "Lutetia", "Mancunium", "Marsonia", "Martius", "Massa", "Matilo", "Mattiacorum", "Mediolanum", "Mod", "Mogontiacum", "Moridunum", "Mursa", "Naissus", "Nervia", "Nida", "Nigrum", "Novaesium", "Noviomagus", "Olicana", "Ovilava", "Parisiorum", "Partiscum", "Paterna", "Pistoria", "Placentia", "Pollentia", "Pomaria", "Pons", "Portus", "Praetoria", "Praetorium", "Pullum", "Ragusium", "Ratae", "Raurica", "Regina", "Regium", "Regulbium", "Rigomagus", "Roma", "Romula", "Rutupiae", "Salassorum", "Salernum", "Salona", "Scalabis", "Segovia", "Silurum", "Sirmium", "Siscia", "Sorviodurum", "Sumelocenna", "Tarraco", "Taurinorum", "Theranda", "Traiectum", "Treverorum", "Tungrorum", "Turicum", "Ulpia", "Valentia", "Venetiae", "Venta", "Verulamium", "Vesontio", "Vetera", "Victoriae", "Victrix", "Villa", "Viminacium", "Vindelicorum", "Vindobona", "Vinovia", "Viroconium"], - ["Aanekoski", "Abjapaluoja", "Ahlainen", "Aholanvaara", "Ahtari", "Aijala", "Aimala", "Akaa", "Alajarvi", "Alatornio", "Alavus", "Antsla", "Aspo", "Bennas", "Bjorkoby", "Elva", "Emasalo", "Espoo", "Esse", "Evitskog", "Forssa", "Haapajarvi", "Haapamaki", "Haapavesi", "Haapsalu", "Haavisto", "Hameenlinna", "Hameenmaki", "Hamina", "Hanko", "Harjavalta", "Hattuvaara", "Haukipudas", "Hautajarvi", "Havumaki", "Heinola", "Hetta", "Hinkabole", "Hirmula", "Hossa", "Huittinen", "Husula", "Hyryla", "Hyvinkaa", "Iisalmi", "Ikaalinen", "Ilmola", "Imatra", "Inari", "Iskmo", "Itakoski", "Jamsa", "Jarvenpaa", "Jeppo", "Jioesuu", "Jiogeva", "Joensuu", "Jokela", "Jokikyla", "Jokisuu", "Jormua", "Juankoski", "Jungsund", "Jyvaskyla", "Kaamasmukka", "Kaarina", "Kajaani", "Kalajoki", "Kallaste", "Kankaanpaa", "Kannus", "Kardla", "Karesuvanto", "Karigasniemi", "Karkkila", "Karkku", "Karksinuia", "Karpankyla", "Kaskinen", "Kasnas", "Kauhajoki", "Kauhava", "Kauniainen", "Kauvatsa", "Kehra", "Keila", "Kellokoski", "Kelottijarvi", "Kemi", "Kemijarvi", "Kerava", "Keuruu", "Kiikka", "Kiipu", "Kilinginiomme", "Kiljava", "Kilpisjarvi", "Kitee", "Kiuruvesi", "Kivesjarvi", "Kiviioli", "Kivisuo", "Klaukkala", "Klovskog", "Kohtlajarve", "Kokemaki", "Kokkola", "Kolho", "Koria", "Koskue", "Kotka", "Kouva", "Kouvola", "Kristiina", "Kaupunki", "Kuhmo", "Kunda", "Kuopio", "Kuressaare", "Kurikka", "Kusans", "Kuusamo", "Kylmalankyla", "Lahti", "Laitila", "Lankipohja", "Lansikyla", "Lappeenranta", "Lapua", "Laurila", "Lautiosaari", "Lepsama", "Liedakkala", "Lieksa", "Lihula", "Littoinen", "Lohja", "Loimaa", "Loksa", "Loviisa", "Luohuanylipaa", "Lusi", "Maardu", "Maarianhamina", "Malmi", "Mantta", "Masaby", "Masala", "Matasvaara", "Maula", "Miiluranta", "Mikkeli", "Mioisakula", "Munapirtti", "Mustvee", "Muurahainen", "Naantali", "Nappa", "Narpio", "Nickby", "Niinimaa", "Niinisalo", "Nikkila", "Nilsia", "Nivala", "Nokia", "Nummela", "Nuorgam", "Nurmes", "Nuvvus", "Obbnas", "Oitti", "Ojakkala", "Ollola", "onningeby", "Orimattila", "Orivesi", "Otanmaki", "Otava", "Otepaa", "Oulainen", "Oulu", "Outokumpu", "Paavola", "Paide", "Paimio", "Pakankyla", "Paldiski", "Parainen", "Parkano", "Parkumaki", "Parola", "Perttula", "Pieksamaki", "Pietarsaari", "Pioltsamaa", "Piolva", "Pohjavaara", "Porhola", "Pori", "Porrasa", "Porvoo", "Pudasjarvi", "Purmo", "Pussi", "Pyhajarvi", "Raahe", "Raasepori", "Raisio", "Rajamaki", "Rakvere", "Rapina", "Rapla", "Rauma", "Rautio", "Reposaari", "Riihimaki", "Rovaniemi", "Roykka", "Ruonala", "Ruottala", "Rutalahti", "Saarijarvi", "Salo", "Sastamala", "Saue", "Savonlinna", "Seinajoki", "Sillamae", "Sindi", "Siuntio", "Somero", "Sompujarvi", "Suonenjoki", "Suurejaani", "Syrjantaka", "Tampere", "Tamsalu", "Tapa", "Temmes", "Tiorva", "Tormasenvaara", "Tornio", "Tottijarvi", "Tulppio", "Turenki", "Turi", "Tuukkala", "Tuurala", "Tuuri", "Tuuski", "Ulvila", "Unari", "Upinniemi", "Utti", "Uusikaarlepyy", "Uusikaupunki", "Vaaksy", "Vaalimaa", "Vaarinmaja", "Vaasa", "Vainikkala", "Valga", "Valkeakoski", "Vantaa", "Varkaus", "Vehkapera", "Vehmasmaki", "Vieki", "Vierumaki", "Viitasaari", "Viljandi", "Vilppula", "Viohma", "Vioru", "Virrat", "Ylike", "Ylivieska", "Ylojarvi"], - ["Sabi", "Wiryeseong", "Hwando", "Gungnae", "Ungjin", "Wanggeomseong", "Ganggyeong", "Jochiwon", "Cheorwon", "Beolgyo", "Gangjin", "Gampo", "Yecheon", "Geochang", "Janghang", "Hadong", "Goseong", "Yeongdong", "Yesan", "Sintaein", "Geumsan", "Boseong", "Jangheung", "Uiseong", "Jumunjin", "Janghowon", "Hongseong", "Gimhwa", "Gwangcheon", "Guryongpo", "Jinyeong", "Buan", "Damyang", "Jangseong", "Wando", "Angang", "Okcheon", "Jeungpyeong", "Waegwan", "Cheongdo", "Gwangyang", "Gochang", "Haenam", "Yeonggwang", "Hanam", "Eumseong", "Daejeong", "Hanrim", "Samrye", "Yongjin", "Hamyang", "Buyeo", "Changnyeong", "Yeongwol", "Yeonmu", "Gurye", "Hwasun", "Hampyeong", "Namji", "Samnangjin", "Dogye", "Hongcheon", "Munsan", "Gapyeong", "Ganghwa", "Geojin", "Sangdong", "Jeongseon", "Sabuk", "Seonghwan", "Heunghae", "Hapdeok", "Sapgyo", "Taean", "Boeun", "Geumwang", "Jincheon", "Bongdong", "Doyang", "Geoncheon", "Pungsan", "Punggi", "Geumho", "Wonju", "Gaun", "Hayang", "Yeoju", "Paengseong", "Yeoncheon", "Yangpyeong", "Ganseong", "Yanggu", "Yangyang", "Inje", "Galmal", "Pyeongchang", "Hwacheon", "Hoengseong", "Seocheon", "Cheongyang", "Goesan", "Danyang", "Hamyeol", "Muju", "Sunchang", "Imsil", "Jangsu", "Jinan", "Goheung", "Gokseong", "Muan", "Yeongam", "Jindo", "Seonsan", "Daegaya", "Gunwi", "Bonghwa", "Seongju", "Yeongdeok", "Yeongyang", "Ulleung", "Uljin", "Cheongsong", "wayang", "Namhae", "Sancheong", "Uiryeong", "Gaya", "Hapcheon", "Wabu", "Dongsong", "Sindong", "Wondeok", "Maepo", "Anmyeon", "Okgu", "Sariwon", "Dolsan", "Daedeok", "Gwansan", "Geumil", "Nohwa", "Baeksu", "Illo", "Jido", "Oedong", "Ocheon", "Yeonil", "Hamchang", "Pyeonghae", "Gijang", "Jeonggwan", "Aewor", "Gujwa", "Seongsan", "Jeongok", "Seonggeo", "Seungju", "Hongnong", "Jangan", "Jocheon", "Gohan", "Jinjeop", "Bubal", "Beobwon", "Yeomchi", "Hwado", "Daesan", "Hwawon", "Apo", "Nampyeong", "Munsan", "Sinbuk", "Munmak", "Judeok", "Bongyang", "Ungcheon", "Yugu", "Unbong", "Mangyeong", "Dong", "Naeseo", "Sanyang", "Soheul", "Onsan", "Eonyang", "Nongong", "Dasa", "Goa", "Jillyang", "Bongdam", "Naesu", "Beomseo", "Opo", "Gongdo", "Jingeon", "Onam", "Baekseok", "Jiksan", "Mokcheon", "Jori", "Anjung", "Samho", "Ujeong", "Buksam", "Tongjin", "Chowol", "Gonjiam", "Pogok", "Seokjeok", "Poseung", "Ochang", "Hyangnam", "Baebang", "Gochon", "Songak", "Samhyang", "Yangchon", "Osong", "Aphae", "Ganam", "Namyang", "Chirwon", "Andong", "Ansan", "Anseong", "Anyang", "Asan", "Boryeong", "Bucheon", "Busan", "Changwon", "Cheonan", "Cheongju", "Chuncheon", "Chungju", "Daegu", "Daejeon", "Dangjin", "Dongducheon", "Donghae", "Gangneung", "Geoje", "Gimcheon", "Gimhae", "Gimje", "Gimpo", "Gongju", "Goyang", "Gumi", "Gunpo", "Gunsan", "Guri", "Gwacheon", "Gwangju", "Gwangju", "Gwangmyeong", "Gyeongju", "Gyeongsan", "Gyeryong", "Hwaseong", "Icheon", "Iksan", "Incheon", "Jecheon", "Jeongeup", "Jeonju", "Jeju", "Jinju", "Naju", "Namyangju", "Namwon", "Nonsan", "Miryang", "Mokpo", "Mungyeong", "Osan", "Paju", "Pocheon", "Pohang", "Pyeongtaek", "Sacheon", "Sangju", "Samcheok", "Sejong", "Seogwipo", "Seongnam", "Seosan", "Seoul", "Siheung", "Sokcho", "Suncheon", "Suwon", "Taebaek", "Tongyeong", "Uijeongbu", "Uiwang", "Ulsan", "Yangju", "Yangsan", "Yeongcheon", "Yeongju", "Yeosu", "Yongin", "Chungmu", "Daecheon", "Donggwangyang", "Geumseong", "Gyeongseong", "Iri", "Jangseungpo", "Jeomchon", "Jeongju", "Migeum", "Onyang", "Samcheonpo", "Busan", "Busan", "Cheongju", "Chuncheon", "Daegu", "Daegu", "Daejeon", "Daejeon", "Gunsan", "Gwangju", "Gwangju", "Gyeongseong", "Incheon", "Incheon", "Iri", "Jeonju", "Jinhae", "Jinju", "Masan", "Masan", "Mokpo", "Songjeong", "Songtan", "Ulsan", "Yeocheon", "Cheongjin", "Gaeseong", "Haeju", "Hamheung", "Heungnam", "Jinnampo", "Najin", "Pyeongyang", "Seongjin", "Sineuiju", "Songnim", "Wonsan"], - ["Anding", "Anlu", "Anqing", "Anshun", "Baan", "Baixing", "Banyang", "Baoding", "Baoqing", "Binzhou", "Caozhou", "Changbai", "Changchun", "Changde", "Changling", "Changsha", "Changtu", "Changzhou", "Chaozhou", "Cheli", "Chengde", "Chengdu", "Chenzhou", "Chizhou", "Chongqing", "Chuxiong", "Chuzhou", "Dading", "Dali", "Daming", "Datong", "Daxing", "Dean", "Dengke", "Dengzhou", "Deqing", "Dexing", "Dihua", "Dingli", "Dongan", "Dongchang", "Dongchuan", "Dongping", "Duyun", "Fengtian", "Fengxiang", "Fengyang", "Fenzhou", "Funing", "Fuzhou", "Ganzhou", "Gaoyao", "Gaozhou", "Gongchang", "Guangnan", "Guangning", "Guangping", "Guangxin", "Guangzhou", "Guide", "Guilin", "Guiyang", "Hailong", "Hailun", "Hangzhou", "Hanyang", "Hanzhong", "Heihe", "Hejian", "Henan", "Hengzhou", "Hezhong", "Huaian", "Huaide", "Huaiqing", "Huanglong", "Huangzhou", "Huining", "Huizhou", "Hulan", "Huzhou", "Jiading", "Jian", "Jianchang", "Jiande", "Jiangning", "Jiankang", "Jianning", "Jiaxing", "Jiayang", "Jilin", "Jinan", "Jingjiang", "Jingzhao", "Jingzhou", "Jinhua", "Jinzhou", "Jiujiang", "Kaifeng", "Kaihua", "Kangding", "Kuizhou", "Laizhou", "Lanzhou", "Leizhou", "Liangzhou", "Lianzhou", "Liaoyang", "Lijiang", "Linan", "Linhuang", "Linjiang", "Lintao", "Liping", "Liuzhou", "Longan", "Longjiang", "Longqing", "Longxing", "Luan", "Lubin", "Lubin", "Luzhou", "Mishan", "Nanan", "Nanchang", "Nandian", "Nankang", "Nanning", "Nanyang", "Nenjiang", "Ningan", "Ningbo", "Ningguo", "Ninguo", "Ningwu", "Ningxia", "Ningyuan", "Pingjiang", "Pingle", "Pingliang", "Pingyang", "Puer", "Puzhou", "Qianzhou", "Qingyang", "Qingyuan", "Qingzhou", "Qiongzhou", "Qujing", "Quzhou", "Raozhou", "Rende", "Ruian", "Ruizhou", "Runing", "Shafeng", "Shajing", "Shaoqing", "Shaowu", "Shaoxing", "Shaozhou", "Shinan", "Shiqian", "Shouchun", "Shuangcheng", "Shulei", "Shunde", "Shunqing", "Shuntian", "Shuoping", "Sicheng", "Sien", "Sinan", "Sizhou", "Songjiang", "Suiding", "Suihua", "Suining", "Suzhou", "Taian", "Taibei", "Tainan", "Taiping", "Taiwan", "Taiyuan", "Taizhou", "Taonan", "Tengchong", "Tieli", "Tingzhou", "Tongchuan", "Tongqing", "Tongren", "Tongzhou", "Weihui", "Wensu", "Wenzhou", "Wuchang", "Wuding", "Wuzhou", "Xian", "Xianchun", "Xianping", "Xijin", "Xiliang", "Xincheng", "Xingan", "Xingde", "Xinghua", "Xingjing", "Xingqing", "Xingyi", "Xingyuan", "Xingzhong", "Xining", "Xinmen", "Xiping", "Xuanhua", "Xunzhou", "Xuzhou", "Yanan", "Yangzhou", "Yanji", "Yanping", "Yanqi", "Yanzhou", "Yazhou", "Yichang", "Yidu", "Yilan", "Yili", "Yingchang", "Yingde", "Yingtian", "Yingzhou", "Yizhou", "Yongchang", "Yongping", "Yongshun", "Yongzhou", "Yuanzhou", "Yuezhou", "Yulin", "Yunnan", "Yunyang", "Zezhou", "Zhangde", "Zhangzhou", "Zhaoqing", "Zhaotong", "Zhenan", "Zhending", "Zhengding", "Zhenhai", "Zhenjiang", "Zhenxi", "Zhenyun", "Zhongshan", "Zunyi"], - ["Nanporo", "Naie", "Kamisunagawa", "Yuni", "Naganuma", "Kuriyama", "Tsukigata", "Urausu", "Shintotsukawa", "Moseushi", "Chippubetsu", "Uryu", "Hokuryu", "Numata", "Tobetsu", "Suttsu", "Kuromatsunai", "Rankoshi", "Niseko", "Kimobetsu", "Kyogoku", "Kutchan", "Kyowa", "Iwanai", "Shakotan", "Furubira", "Niki", "Yoichi", "Toyoura", "Toyako", "Sobetsu", "Shiraoi", "Atsuma", "Abira", "Mukawa", "Hidaka", "Biratori", "Niikappu", "Urakawa", "Samani", "Erimo", "Shinhidaka", "Matsumae", "Fukushima", "Shiriuchi", "Kikonai", "Nanae", "Shikabe", "Mori", "Yakumo", "Oshamambe", "Esashi", "Kaminokuni", "Assabu", "Otobe", "Okushiri", "Imakane", "Setana", "Takasu", "Higashikagura", "Toma", "Pippu", "Aibetsu", "Kamikawa", "Higashikawa", "Biei", "Kamifurano", "Nakafurano", "Minamifurano", "Horokanai", "Wassamu", "Kenbuchi", "Shimokawa", "Bifuka", "Nakagawa", "Mashike", "Obira", "Tomamae", "Haboro", "Enbetsu", "Teshio", "Hamatonbetsu", "Nakatonbetsu", "Esashi", "Toyotomi", "Horonobe", "Rebun", "Rishiri", "Rishirifuji", "Bihoro", "Tsubetsu", "Ozora", "Shari", "Kiyosato", "Koshimizu", "Kunneppu", "Oketo", "Saroma", "Engaru", "Yubetsu", "Takinoue", "Okoppe", "Omu", "Otofuke", "Shihoro", "Kamishihoro", "Shikaoi", "Shintoku", "Shimizu", "Memuro", "Taiki", "Hiroo", "Makubetsu", "Ikeda", "Toyokoro", "Honbetsu", "Ashoro", "Rikubetsu", "Urahoro", "Kushiro", "Akkeshi", "Hamanaka", "Shibecha", "Teshikaga", "Shiranuka", "Betsukai", "Nakashibetsu", "Shibetsu", "Rausu", "Hiranai", "Imabetsu", "Sotogahama", "Ajigasawa", "Fukaura", "Fujisaki", "Owani", "Itayanagi", "Tsuruta", "Nakadomari", "Noheji", "Shichinohe", "Rokunohe", "Yokohama", "Tohoku", "Oirase", "Oma", "Sannohe", "Gonohe", "Takko", "Nanbu", "Hashikami", "Shizukuishi", "Kuzumaki", "Iwate", "Shiwa", "Yahaba", "Nishiwaga", "Kanegasaki", "Hiraizumi", "Sumita", "Otsuchi", "Yamada", "Iwaizumi", "Karumai", "Hirono", "Ichinohe", "Zao", "Shichikashuku", "Ogawara", "Murata", "Shibata", "Kawasaki", "Marumori", "Watari", "Yamamoto", "Matsushima", "Shichigahama", "Rifu", "Taiwa", "Osato", "Shikama", "Kami", "Wakuya", "Misato", "Onagawa", "Minamisanriku", "Kosaka", "Fujisato", "Mitane", "Happo", "Gojome", "Hachirogata", "Ikawa", "Misato", "Ugo", "Yamanobe", "Nakayama", "Kahoku", "Nishikawa", "Asahi", "Oe", "Oishida", "Kaneyama", "Mogami", "Funagata", "Mamurogawa", "Takahata", "Kawanishi", "Oguni", "Shirataka", "Iide", "Mikawa", "Shonai", "Yuza", "Koori", "Kunimi", "Kawamata", "Kagamiishi", "Shimogo", "Tadami", "Minamiaizu", "Nishiaizu", "Bandai", "Inawashiro", "Aizubange", "Yanaizu", "Mishima", "Kaneyama", "Aizumisato", "Yabuki", "Tanagura", "Yamatsuri", "Hanawa", "Ishikawa", "Asakawa", "Furudono", "Miharu", "Ono", "Hirono", "Naraha", "Tomioka", "Okuma", "Futaba", "Namie", "Shinchi", "Ibaraki", "Oarai", "Shirosato", "Daigo", "Ami", "Kawachi", "Yachiyo", "Goka", "Sakai", "Tone", "Kaminokawa", "Mashiko", "Motegi", "Ichikai", "Haga", "Mibu", "Nogi", "Shioya", "Takanezawa", "Nasu", "Nakagawa", "Yoshioka", "Kanna", "Shimonita", "Kanra", "Nakanojo", "Naganohara", "Kusatsu", "Higashiagatsuma", "Minakami", "Tamamura", "Itakura", "Meiwa", "Chiyoda", "Oizumi", "Ora", "Ina", "Miyoshi", "Moroyama", "Ogose", "Namegawa", "Ranzan", "Ogawa", "Kawajima", "Yoshimi", "Hatoyama", "Tokigawa", "Yokoze", "Minano", "Nagatoro", "Ogano", "Misato", "Kamikawa", "Kamisato", "Yorii", "Miyashiro", "Sugito", "Matsubushi", "Shisui", "Sakae", "Kozaki", "Tako", "Tonosho", "Kujukuri", "Shibayama", "Yokoshibahikari", "Ichinomiya", "Mutsuzawa", "Shirako", "Nagara", "Chonan", "Otaki", "Onjuku", "Kyonan", "Mizuho", "Hinode", "Okutama", "Oshima", "Hachijo", "Aikawa", "Hayama", "Samukawa", "Oiso", "Ninomiya", "Nakai", "Oi", "Matsuda", "Yamakita", "Kaisei", "Hakone", "Manazuru", "Yugawara", "Seiro", "Tagami", "Aga", "Izumozaki", "Yuzawa", "Tsunan", "Kamiichi", "Tateyama", "Nyuzen", "Asahi", "Kawakita", "Tsubata", "Uchinada", "Shika", "Hodatsushimizu", "Nakanoto", "Anamizu", "Noto", "Eiheiji", "Ikeda", "Minamiechizen", "Echizen", "Mihama", "Takahama", "Oi", "Wakasa", "Ichikawamisato", "Hayakawa", "Minobu", "Nanbu", "Fujikawa", "Showa", "Nishikatsura", "Fujikawaguchiko", "Koumi", "Sakuho", "Karuizawa", "Miyota", "Tateshina", "Nagawa", "Shimosuwa", "Fujimi", "Tatsuno", "Minowa", "Iijima", "Matsukawa", "Takamori", "Anan", "Agematsu", "Nagiso", "Kiso", "Ikeda", "Sakaki", "Obuse", "Yamanouchi", "Shinano", "Iizuna", "Ginan", "Kasamatsu", "Yoro", "Tarui", "Sekigahara", "Godo", "Wanouchi", "Anpachi", "Ibigawa", "Ono", "Ikeda", "Kitagata", "Sakahogi", "Tomika", "Kawabe", "Hichiso", "Yaotsu", "Shirakawa", "Mitake", "Higashiizu", "Kawazu", "Minamiizu", "Matsuzaki", "Nishiizu", "Kannami", "Shimizu", "Nagaizumi", "Oyama", "Yoshida", "Kawanehon", "Mori", "Togo", "Toyoyama", "Oguchi", "Fuso", "Oharu", "Kanie", "Agui", "Higashiura", "Minamichita", "Mihama", "Taketoyo", "Mihama", "Kota", "Shitara", "Toei", "Kisosaki", "Toin", "Komono", "Asahi", "Kawagoe", "Taki", "Meiwa", "Odai", "Tamaki", "Watarai", "Taiki", "Minamiise", "Kihoku", "Mihama", "Kiho", "Hino", "Ryuo", "Aisho", "Toyosato", "Kora", "Taga", "Oyamazaki", "Kumiyama", "Ide", "Ujitawara", "Kasagi", "Wazuka", "Seika", "Kyotamba", "Ine", "Yosano", "Shimamoto", "Toyono", "Nose", "Tadaoka", "Kumatori", "Tajiri", "Misaki", "Taishi", "Kanan", "Inagawa", "Taka", "Inami", "Harima", "Ichikawa", "Fukusaki", "Kamikawa", "Taishi", "Kamigori", "Sayo", "Kami", "Shin'onsen", "Heguri", "Sango", "Ikaruga", "Ando", "Kawanishi", "Miyake", "Tawaramoto", "Takatori", "Kanmaki", "Oji", "Koryo", "Kawai", "Yoshino", "Oyodo", "Shimoichi", "Kushimoto", "Kimino", "Katsuragi", "Kudoyama", "Koya", "Yuasa", "Hirogawa", "Aridagawa", "Mihama", "Hidaka", "Yura", "Inami", "Minabe", "Hidakagawa", "Shirahama", "Kamitonda", "Susami", "Nachikatsuura", "Taiji", "Kozagawa", "Iwami", "Wakasa", "Chizu", "Yazu", "Misasa", "Yurihama", "Kotoura", "Hokuei", "Daisen", "Nanbu", "Hoki", "Nichinan", "Hino", "Kofu", "Okuizumo", "Iinan", "Kawamoto", "Misato", "Onan", "Tsuwano", "Yoshika", "Ama", "Nishinoshima", "Okinoshima", "Wake", "Hayashima", "Satosho", "Yakage", "Kagamino", "Shoo", "Nagi", "Kumenan", "Misaki", "Kibichuo", "Fuchu", "Kaita", "Kumano", "Saka", "Kitahiroshima", "Akiota", "Osakikamijima", "Sera", "Jinsekikogen", "Suooshima", "Waki", "Kaminoseki", "Tabuse", "Hirao", "Abu", "Katsuura", "Kamikatsu", "Ishii", "Kamiyama", "Naka", "Mugi", "Minami", "Kaiyo", "Matsushige", "Kitajima", "Aizumi", "Itano", "Kamiita", "Tsurugi", "Higashimiyoshi", "Tonosho", "Shodoshima", "Miki", "Naoshima", "Utazu", "Ayagawa", "Kotohira", "Tadotsu", "Manno", "Kamijima", "Kumakogen", "Masaki", "Tobe", "Uchiko", "Ikata", "Kihoku", "Matsuno", "Ainan", "Toyo", "Nahari", "Tano", "Yasuda", "Motoyama", "Otoyo", "Tosa", "Ino", "Niyodogawa", "Nakatosa", "Sakawa", "Ochi", "Yusuhara", "Tsuno", "Shimanto", "Otsuki", "Kuroshio", "Nakagawa", "Umi", "Sasaguri", "Shime", "Sue", "Shingu", "Hisayama", "Kasuya", "Ashiya", "Mizumaki", "Okagaki", "Onga", "Kotake", "Kurate", "Keisen", "Chikuzen", "Tachiarai", "Oki", "Hirokawa", "Kawara", "Soeda", "Itoda", "Kawasaki", "Oto", "Fukuchi", "Kanda", "Miyako", "Yoshitomi", "Koge", "Chikujo", "Yoshinogari", "Kiyama", "Kamimine", "Miyaki", "Genkai", "Arita", "Omachi", "Kohoku", "Shiroishi", "Tara", "Nagayo", "Togitsu", "Higashisonogi", "Kawatana", "Hasami", "Ojika", "Saza", "Shinkamigoto", "Misato", "Gyokuto", "Nankan", "Nagasu", "Nagomi", "Ozu", "Kikuyo", "Minamioguni", "Oguni", "Takamori", "Mifune", "Kashima", "Mashiki", "Kosa", "Yamato", "Hikawa", "Ashikita", "Tsunagi", "Nishiki", "Taragi", "Yunomae", "Asagiri", "Reihoku", "Hiji", "Kusu", "Kokonoe", "Mimata", "Takaharu", "Kunitomi", "Aya", "Takanabe", "Shintomi", "Kijo", "Kawaminami", "Tsuno", "Kadogawa", "Misato", "Takachiho", "Hinokage", "Gokase", "Satsuma", "Nagashima", "Yusui", "Osaki", "Higashikushira", "Kinko", "Minamiosumi", "Kimotsuki", "Nakatane", "Minamitane", "Yakushima", "Setouchi", "Tatsugo", "Kikai", "Tokunoshima", "Amagi", "Isen", "Wadomari", "China", "Yoron", "Motobu", "Kin", "Kadena", "Chatan", "Nishihara", "Yonabaru", "Haebaru", "Kumejima", "Yaese", "Taketomi", "Yonaguni"] + ["Achern","Aichhalden","Aitern","Albbruck","Alpirsbach","Altensteig","Althengstett","Appenweier","Auggen","Wildbad","Badenen","Badenweiler","Baiersbronn","Ballrechten","Bellingen","Berghaupten","Bernau","Biberach","Biederbach","Binzen","Birkendorf","Birkenfeld","Bischweier","Blumberg","Bollen","Bollschweil","Bonndorf","Bosingen","Braunlingen","Breisach","Breisgau","Breitnau","Brigachtal","Buchenbach","Buggingen","Buhl","Buhlertal","Calw","Dachsberg","Dobel","Donaueschingen","Dornhan","Dornstetten","Dottingen","Dunningen","Durbach","Durrheim","Ebhausen","Ebringen","Efringen","Egenhausen","Ehrenkirchen","Ehrsberg","Eimeldingen","Eisenbach","Elzach","Elztal","Emmendingen","Endingen","Engelsbrand","Enz","Enzklosterle","Eschbronn","Ettenheim","Ettlingen","Feldberg","Fischerbach","Fischingen","Fluorn","Forbach","Freiamt","Freiburg","Freudenstadt","Friedenweiler","Friesenheim","Frohnd","Furtwangen","Gaggenau","Geisingen","Gengenbach","Gernsbach","Glatt","Glatten","Glottertal","Gorwihl","Gottenheim","Grafenhausen","Grenzach","Griesbach","Gutach","Gutenbach","Hag","Haiterbach","Hardt","Harmersbach","Hasel","Haslach","Hausach","Hausen","Hausern","Heitersheim","Herbolzheim","Herrenalb","Herrischried","Hinterzarten","Hochenschwand","Hofen","Hofstetten","Hohberg","Horb","Horben","Hornberg","Hufingen","Ibach","Ihringen","Inzlingen","Kandern","Kappel","Kappelrodeck","Karlsbad","Karlsruhe","Kehl","Keltern","Kippenheim","Kirchzarten","Konigsfeld","Krozingen","Kuppenheim","Kussaberg","Lahr","Lauchringen","Lauf","Laufenburg","Lautenbach","Lauterbach","Lenzkirch","Liebenzell","Loffenau","Loffingen","Lorrach","Lossburg","Mahlberg","Malsburg","Malsch","March","Marxzell","Marzell","Maulburg","Monchweiler","Muhlenbach","Mullheim","Munstertal","Murg","Nagold","Neubulach","Neuenburg","Neuhausen","Neuried","Neuweiler","Niedereschach","Nordrach","Oberharmersbach","Oberkirch","Oberndorf","Oberbach","Oberried","Oberwolfach","Offenburg","Ohlsbach","Oppenau","Ortenberg","otigheim","Ottenhofen","Ottersweier","Peterstal","Pfaffenweiler","Pfalzgrafenweiler","Pforzheim","Rastatt","Renchen","Rheinau","Rheinfelden","Rheinmunster","Rickenbach","Rippoldsau","Rohrdorf","Rottweil","Rummingen","Rust","Sackingen","Sasbach","Sasbachwalden","Schallbach","Schallstadt","Schapbach","Schenkenzell","Schiltach","Schliengen","Schluchsee","Schomberg","Schonach","Schonau","Schonenberg","Schonwald","Schopfheim","Schopfloch","Schramberg","Schuttertal","Schwenningen","Schworstadt","Seebach","Seelbach","Seewald","Sexau","Simmersfeld","Simonswald","Sinzheim","Solden","Staufen","Stegen","Steinach","Steinen","Steinmauern","Straubenhardt","Stuhlingen","Sulz","Sulzburg","Teinach","Tiefenbronn","Tiengen","Titisee","Todtmoos","Todtnau","Todtnauberg","Triberg","Tunau","Tuningen","uhlingen","Unterkirnach","Reichenbach","Utzenfeld","Villingen","Villingendorf","Vogtsburg","Vohrenbach","Waldachtal","Waldbronn","Waldkirch","Waldshut","Wehr","Weil","Weilheim","Weisenbach","Wembach","Wieden","Wiesental","Wildberg","Winzeln","Wittlingen","Wittnau","Wolfach","Wutach","Wutoschingen","Wyhlen","Zavelstein"], + ["Abingdon","Albrighton","Alcester","Almondbury","Altrincham","Amersham","Andover","Appleby","Ashboume","Atherstone","Aveton","Axbridge","Aylesbury","Baldock","Bamburgh","Barton","Basingstoke","Berden","Bere","Berkeley","Berwick","Betley","Bideford","Bingley","Birmingham","Blandford","Blechingley","Bodmin","Bolton","Bootham","Boroughbridge","Boscastle","Bossinney","Bramber","Brampton","Brasted","Bretford","Bridgetown","Bridlington","Bromyard","Bruton","Buckingham","Bungay","Burton","Calne","Cambridge","Canterbury","Carlisle","Castleton","Caus","Charmouth","Chawleigh","Chichester","Chillington","Chinnor","Chipping","Chisbury","Cleobury","Clifford","Clifton","Clitheroe","Cockermouth","Coleshill","Combe","Congleton","Crafthole","Crediton","Cuddenbeck","Dalton","Darlington","Dodbrooke","Drax","Dudley","Dunstable","Dunster","Dunwich","Durham","Dymock","Exeter","Exning","Faringdon","Felton","Fenny","Finedon","Flookburgh","Fowey","Frampton","Gateshead","Gatton","Godmanchester","Grampound","Grantham","Guildford","Halesowen","Halton","Harbottle","Harlow","Hatfield","Hatherleigh","Haydon","Helston","Henley","Hertford","Heytesbury","Hinckley","Hitchin","Holme","Hornby","Horsham","Kendal","Kenilworth","Kilkhampton","Kineton","Kington","Kinver","Kirby","Knaresborough","Knutsford","Launceston","Leighton","Lewes","Linton","Louth","Luton","Lyme","Lympstone","Macclesfield","Madeley","Malborough","Maldon","Manchester","Manningtree","Marazion","Marlborough","Marshfield","Mere","Merryfield","Middlewich","Midhurst","Milborne","Mitford","Modbury","Montacute","Mousehole","Newbiggin","Newborough","Newbury","Newenden","Newent","Norham","Northleach","Noss","Oakham","Olney","Orford","Ormskirk","Oswestry","Padstow","Paignton","Penkneth","Penrith","Penzance","Pershore","Petersfield","Pevensey","Pickering","Pilton","Pontefract","Portsmouth","Preston","Quatford","Reading","Redcliff","Retford","Rockingham","Romney","Rothbury","Rothwell","Salisbury","Saltash","Seaford","Seasalter","Sherston","Shifnal","Shoreham","Sidmouth","Skipsea","Skipton","Solihull","Somerton","Southam","Southwark","Standon","Stansted","Stapleton","Stottesdon","Sudbury","Swavesey","Tamerton","Tarporley","Tetbury","Thatcham","Thaxted","Thetford","Thornbury","Tintagel","Tiverton","Torksey","Totnes","Towcester","Tregoney","Trematon","Tutbury","Uxbridge","Wallingford","Wareham","Warenmouth","Wargrave","Warton","Watchet","Watford","Wendover","Westbury","Westcheap","Weymouth","Whitford","Wickwar","Wigan","Wigmore","Winchelsea","Winkleigh","Wiscombe","Witham","Witheridge","Wiveliscombe","Woodbury","Yeovil"], + ["Adon","Aillant","Amilly","Andonville","Ardon","Artenay","Ascheres","Ascoux","Attray","Aubin","Audeville","Aulnay","Autruy","Auvilliers","Auxy","Aveyron","Baccon","Bardon","Barville","Batilly","Baule","Bazoches","Beauchamps","Beaugency","Beaulieu","Beaune","Bellegarde","Boesses","Boigny","Boiscommun","Boismorand","Boisseaux","Bondaroy","Bonnee","Bonny","Bordes","Bou","Bougy","Bouilly","Boulay","Bouzonville","Bouzy","Boynes","Bray","Breteau","Briare","Briarres","Bricy","Bromeilles","Bucy","Cepoy","Cercottes","Cerdon","Cernoy","Cesarville","Chailly","Chaingy","Chalette","Chambon","Champoulet","Chanteau","Chantecoq","Chapell","Charme","Charmont","Charsonville","Chateau","Chateauneuf","Chatel","Chatenoy","Chatillon","Chaussy","Checy","Chevannes","Chevillon","Chevilly","Chevry","Chilleurs","Choux","Chuelles","Clery","Coinces","Coligny","Combleux","Combreux","Conflans","Corbeilles","Corquilleroy","Cortrat","Coudroy","Coullons","Coulmiers","Courcelles","Courcy","Courtemaux","Courtempierre","Courtenay","Cravant","Crottes","Dadonville","Dammarie","Dampierre","Darvoy","Desmonts","Dimancheville","Donnery","Dordives","Dossainville","Douchy","Dry","Echilleuses","Egry","Engenville","Epieds","Erceville","Ervauville","Escrennes","Escrignelles","Estouy","Faverelles","Fay","Feins","Ferolles","Ferrieres","Fleury","Fontenay","Foret","Foucherolles","Freville","Gatinais","Gaubertin","Gemigny","Germigny","Gidy","Gien","Girolles","Givraines","Gondreville","Grangermont","Greneville","Griselles","Guigneville","Guilly","Gyleslonains","Huetre","Huisseau","Ingrannes","Ingre","Intville","Isdes","Jargeau","Jouy","Juranville","Bussiere","Laas","Ladon","Lailly","Langesse","Leouville","Ligny","Lombreuil","Lorcy","Lorris","Loury","Louzouer","Malesherbois","Marcilly","Mardie","Mareau","Marigny","Marsainvilliers","Melleroy","Menestreau","Merinville","Messas","Meung","Mezieres","Migneres","Mignerette","Mirabeau","Montargis","Montbarrois","Montbouy","Montcresson","Montereau","Montigny","Montliard","Mormant","Morville","Moulinet","Moulon","Nancray","Nargis","Nesploy","Neuville","Neuvy","Nevoy","Nibelle","Nogent","Noyers","Ocre","Oison","Olivet","Ondreville","Onzerain","Orleans","Ormes","Orville","Oussoy","Outarville","Ouzouer","Pannecieres","Pannes","Patay","Paucourt","Pers","Pierrefitte","Pithiverais","Pithiviers","Poilly","Potier","Prefontaines","Presnoy","Pressigny","Puiseaux","Quiers","Ramoulu","Rebrechien","Rouvray","Rozieres","Rozoy","Ruan","Sandillon","Santeau","Saran","Sceaux","Seichebrieres","Semoy","Sennely","Sermaises","Sigloy","Solterre","Sougy","Sully","Sury","Tavers","Thignonville","Thimory","Thorailles","Thou","Tigy","Tivernon","Tournoisis","Trainou","Treilles","Trigueres","Trinay","Vannes","Varennes","Vennecy","Vieilles","Vienne","Viglain","Vignes","Villamblain","Villemandeur","Villemoutiers","Villemurlin","Villeneuve","Villereau","Villevoques","Villorceau","Vimory","Vitry","Vrigny","Ivre"], + ["Accumoli","Acquafondata","Acquapendente","Acuto","Affile","Agosta","Alatri","Albano","Allumiere","Alvito","Amaseno","Amatrice","Anagni","Anguillara","Anticoli","Antrodoco","Anzio","Aprilia","Aquino","Arce","Arcinazzo","Ardea","Ariccia","Arlena","Arnara","Arpino","Arsoli","Artena","Ascrea","Atina","Ausonia","Bagnoregio","Barbarano","Bassano","Bassiano","Bellegra","Belmonte","Blera","Bolsena","Bomarzo","Borbona","Borgo","Borgorose","Boville","Bracciano","Broccostella","Calcata","Camerata","Campagnano","Campodimele","Campoli","Canale","Canepina","Canino","Cantalice","Cantalupo","Canterano","Capena","Capodimonte","Capranica","Caprarola","Carbognano","Casalattico","Casalvieri","Casape","Casaprota","Casperia","Cassino","Castelforte","Castelliri","Castello","Castelnuovo","Castiglione","Castro","Castrocielo","Cave","Ceccano","Celleno","Cellere","Ceprano","Cerreto","Cervara","Cervaro","Cerveteri","Ciampino","Ciciliano","Cineto","Cisterna","Cittaducale","Cittareale","Civita","Civitavecchia","Civitella","Colfelice","Collalto","Colle","Colleferro","Collegiove","Collepardo","Collevecchio","Colli","Colonna","Concerviano","Configni","Contigliano","Corchiano","Coreno","Cori","Cottanello","Esperia","Fabrica","Faleria","Falvaterra","Fara","Farnese","Ferentino","Fiamignano","Fiano","Filacciano","Filettino","Fiuggi","Fiumicino","Fondi","Fontana","Fonte","Fontechiari","Forano","Formello","Formia","Frascati","Frasso","Frosinone","Fumone","Gaeta","Gallese","Gallicano","Gallinaro","Gavignano","Genazzano","Genzano","Gerano","Giuliano","Gorga","Gradoli","Graffignano","Greccio","Grottaferrata","Grotte","Guarcino","Guidonia","Ischia","Isola","Itri","Jenne","Labico","Labro","Ladispoli","Lanuvio","Lariano","Latera","Lenola","Leonessa","Licenza","Longone","Lubriano","Maenza","Magliano","Mandela","Manziana","Marano","Marcellina","Marcetelli","Marino","Marta","Mazzano","Mentana","Micigliano","Minturno","Mompeo","Montalto","Montasola","Monte","Montebuono","Montefiascone","Monteflavio","Montelanico","Monteleone","Montelibretti","Montenero","Monterosi","Monterotondo","Montopoli","Montorio","Moricone","Morlupo","Morolo","Morro","Nazzano","Nemi","Nepi","Nerola","Nespolo","Nettuno","Norma","Olevano","Onano","Oriolo","Orte","Orvinio","Paganico","Palestrina","Paliano","Palombara","Pastena","Patrica","Percile","Pescorocchiano","Pescosolido","Petrella","Piansano","Picinisco","Pico","Piedimonte","Piglio","Pignataro","Pisoniano","Pofi","Poggio","Poli","Pomezia","Pontecorvo","Pontinia","Ponza","Ponzano","Posta","Pozzaglia","Priverno","Proceno","Prossedi","Riano","Rieti","Rignano","Riofreddo","Ripi","Rivodutri","Rocca","Roccagiovine","Roccagorga","Roccantica","Roccasecca","Roiate","Ronciglione","Roviano","Sabaudia","Sacrofano","Salisano","Sambuci","Santa","Santi","Santopadre","Saracinesco","Scandriglia","Segni","Selci","Sermoneta","Serrone","Settefrati","Sezze","Sgurgola","Sonnino","Sora","Soriano","Sperlonga","Spigno","Stimigliano","Strangolagalli","Subiaco","Supino","Sutri","Tarano","Tarquinia","Terelle","Terracina","Tessennano","Tivoli","Toffia","Tolfa","Torre","Torri","Torrice","Torricella","Torrita","Trevi","Trevignano","Trivigliano","Turania","Tuscania","Vacone","Valentano","Vallecorsa","Vallemaio","Vallepietra","Vallerano","Vallerotonda","Vallinfreda","Valmontone","Varco","Vasanello","Vejano","Velletri","Ventotene","Veroli","Vetralla","Vicalvi","Vico","Vicovaro","Vignanello","Viterbo","Viticuso","Vitorchiano","Vivaro","Zagarolo"], + ["Abanades","Ablanque","Adobes","Ajofrin","Alameda","Alaminos","Alarilla","Albalate","Albares","Albarreal","Albendiego","Alcabon","Alcanizo","Alcaudete","Alcocer","Alcolea","Alcoroches","Aldea","Aldeanueva","Algar","Algora","Alhondiga","Alique","Almadrones","Almendral","Almoguera","Almonacid","Almorox","Alocen","Alovera","Alustante","Angon","Anguita","Anover","Anquela","Arbancon","Arbeteta","Arcicollar","Argecilla","Arges","Armallones","Armuna","Arroyo","Atanzon","Atienza","Aunon","Azuqueca","Azutan","Baides","Banos","Banuelos","Barcience","Bargas","Barriopedro","Belvis","Berninches","Borox","Brihuega","Budia","Buenaventura","Bujalaro","Burguillos","Burujon","Bustares","Cabanas","Cabanillas","Calera","Caleruela","Calzada","Camarena","Campillo","Camunas","Canizar","Canredondo","Cantalojas","Cardiel","Carmena","Carranque","Carriches","Casa","Casarrubios","Casas","Casasbuenas","Caspuenas","Castejon","Castellar","Castilforte","Castillo","Castilnuevo","Cazalegas","Cebolla","Cedillo","Cendejas","Centenera","Cervera","Checa","Chequilla","Chillaron","Chiloeches","Chozas","Chueca","Cifuentes","Cincovillas","Ciruelas","Ciruelos","Cobeja","Cobeta","Cobisa","Cogollor","Cogolludo","Condemios","Congostrina","Consuegra","Copernal","Corduente","Corral","Cuerva","Domingo","Dosbarrios","Driebes","Duron","El","Embid","Erustes","Escalona","Escalonilla","Escamilla","Escariche","Escopete","Espinosa","Espinoso","Esplegares","Esquivias","Estables","Estriegana","Fontanar","Fuembellida","Fuensalida","Fuentelsaz","Gajanejos","Galve","Galvez","Garciotum","Gascuena","Gerindote","Guadamur","Henche","Heras","Herreria","Herreruela","Hijes","Hinojosa","Hita","Hombrados","Hontanar","Hontoba","Horche","Hormigos","Huecas","Huermeces","Huerta","Hueva","Humanes","Illan","Illana","Illescas","Iniestola","Irueste","Jadraque","Jirueque","Lagartera","Las","Layos","Ledanca","Lillo","Lominchar","Loranca","Los","Lucillos","Lupiana","Luzaga","Luzon","Madridejos","Magan","Majaelrayo","Malaga","Malaguilla","Malpica","Mandayona","Mantiel","Manzaneque","Maqueda","Maranchon","Marchamalo","Marjaliza","Marrupe","Mascaraque","Masegoso","Matarrubia","Matillas","Mazarete","Mazuecos","Medranda","Megina","Mejorada","Mentrida","Mesegar","Miedes","Miguel","Millana","Milmarcos","Mirabueno","Miralrio","Mocejon","Mochales","Mohedas","Molina","Monasterio","Mondejar","Montarron","Mora","Moratilla","Morenilla","Muduex","Nambroca","Navalcan","Negredo","Noblejas","Noez","Nombela","Noves","Numancia","Nuno","Ocana","Ocentejo","Olias","Olmeda","Ontigola","Orea","Orgaz","Oropesa","Otero","Palmaces","Palomeque","Pantoja","Pardos","Paredes","Pareja","Parrillas","Pastrana","Pelahustan","Penalen","Penalver","Pepino","Peralejos","Peralveche","Pinilla","Pioz","Piqueras","Polan","Portillo","Poveda","Pozo","Pradena","Prados","Puebla","Puerto","Pulgar","Quer","Quero","Quintanar","Quismondo","Rebollosa","Recas","Renera","Retamoso","Retiendas","Riba","Rielves","Rillo","Riofrio","Robledillo","Robledo","Romanillos","Romanones","Rueda","Sacecorbo","Sacedon","Saelices","Salmeron","San","Santa","Santiuste","Santo","Sartajada","Sauca","Sayaton","Segurilla","Selas","Semillas","Sesena","Setiles","Sevilleja","Sienes","Siguenza","Solanillos","Somolinos","Sonseca","Sotillo","Sotodosos","Talavera","Tamajon","Taragudo","Taravilla","Tartanedo","Tembleque","Tendilla","Terzaga","Tierzo","Tordellego","Tordelrabano","Tordesilos","Torija","Torralba","Torre","Torrecilla","Torrecuadrada","Torrejon","Torremocha","Torrico","Torrijos","Torrubia","Tortola","Tortuera","Tortuero","Totanes","Traid","Trijueque","Trillo","Turleque","Uceda","Ugena","Ujados","Urda","Utande","Valdarachas","Valdesotos","Valhermoso","Valtablado","Valverde","Velada","Viana","Vinuelas","Yebes","Yebra","Yelamos","Yeles","Yepes","Yuncler","Yunclillos","Yuncos","Yunquera","Zaorejas","Zarzuela","Zorita"], + ["Belgorod","Beloberezhye","Belyi","Belz","Berestiy","Berezhets","Berezovets","Berezutsk","Bobruisk","Bolonets","Borisov","Borovsk","Bozhesk","Bratslav","Bryansk","Brynsk","Buryn","Byhov","Chechersk","Chemesov","Cheremosh","Cherlen","Chern","Chernigov","Chernitsa","Chernobyl","Chernogorod","Chertoryesk","Chetvertnia","Demyansk","Derevesk","Devyagoresk","Dichin","Dmitrov","Dorogobuch","Dorogobuzh","Drestvin","Drokov","Drutsk","Dubechin","Dubichi","Dubki","Dubkov","Dveren","Galich","Glebovo","Glinsk","Goloty","Gomiy","Gorodets","Gorodische","Gorodno","Gorohovets","Goroshin","Gorval","Goryshon","Holm","Horobor","Hoten","Hotin","Hotmyzhsk","Ilovech","Ivan","Izborsk","Izheslavl","Kamenets","Kanev","Karachev","Karna","Kavarna","Klechesk","Klyapech","Kolomyya","Kolyvan","Kopyl","Korec","Kornik","Korochunov","Korshev","Korsun","Koshkin","Kotelno","Kovyla","Kozelsk","Kozelsk","Kremenets","Krichev","Krylatsk","Ksniatin","Kulatsk","Kursk","Kursk","Lebedev","Lida","Logosko","Lomihvost","Loshesk","Loshichi","Lubech","Lubno","Lubutsk","Lutsk","Luchin","Luki","Lukoml","Luzha","Lvov","Mtsensk","Mdin","Medniki","Melecha","Merech","Meretsk","Mescherskoe","Meshkovsk","Metlitsk","Mezetsk","Mglin","Mihailov","Mikitin","Mikulino","Miloslavichi","Mogilev","Mologa","Moreva","Mosalsk","Moschiny","Mozyr","Mstislav","Mstislavets","Muravin","Nemech","Nemiza","Nerinsk","Nichan","Novgorod","Novogorodok","Obolichi","Obolensk","Obolensk","Oleshsk","Olgov","Omelnik","Opoka","Opoki","Oreshek","Orlets","Osechen","Oster","Ostrog","Ostrov","Perelai","Peremil","Peremyshl","Pererov","Peresechen","Perevitsk","Pereyaslav","Pinsk","Ples","Polotsk","Pronsk","Proposhesk","Punia","Putivl","Rechitsa","Rodno","Rogachev","Romanov","Romny","Roslavl","Rostislavl","Rostovets","Rsha","Ruza","Rybchesk","Rylsk","Rzhavesk","Rzhev","Rzhischev","Sambor","Serensk","Serensk","Serpeysk","Shilov","Shuya","Sinech","Sizhka","Skala","Slovensk","Slutsk","Smedin","Sneporod","Snitin","Snovsk","Sochevo","Sokolec","Starica","Starodub","Stepan","Sterzh","Streshin","Sutesk","Svinetsk","Svisloch","Terebovl","Ternov","Teshilov","Teterin","Tiversk","Torchevsk","Toropets","Torzhok","Tripolye","Trubchevsk","Tur","Turov","Usvyaty","Uteshkov","Vasilkov","Velil","Velye","Venev","Venicha","Verderev","Vereya","Veveresk","Viazma","Vidbesk","Vidychev","Voino","Volodimer","Volok","Volyn","Vorobesk","Voronich","Voronok","Vorotynsk","Vrev","Vruchiy","Vselug","Vyatichsk","Vyatka","Vyshegorod","Vyshgorod","Vysokoe","Yagniatin","Yaropolch","Yasenets","Yuryev","Yuryevets","Zaraysk","Zhitomel","Zholvazh","Zizhech","Zubkov","Zudechev","Zvenigorod"], + ["Akureyri","Aldra","Alftanes","Andenes","Austbo","Auvog","Bakkafjordur","Ballangen","Bardal","Beisfjord","Bifrost","Bildudalur","Bjerka","Bjerkvik","Bjorkosen","Bliksvaer","Blokken","Blonduos","Bolga","Bolungarvik","Borg","Borgarnes","Bosmoen","Bostad","Bostrand","Botsvika","Brautarholt","Breiddalsvik","Bringsli","Brunahlid","Budardalur","Byggdakjarni","Dalvik","Djupivogur","Donnes","Drageid","Drangsnes","Egilsstadir","Eiteroga","Elvenes","Engavogen","Ertenvog","Eskifjordur","Evenes","Eyrarbakki","Fagernes","Fallmoen","Fellabaer","Fenes","Finnoya","Fjaer","Fjelldal","Flakstad","Flateyri","Flostrand","Fludir","Gardabær","Gardur","Gimstad","Givaer","Gjeroy","Gladstad","Godoya","Godoynes","Granmoen","Gravdal","Grenivik","Grimsey","Grindavik","Grytting","Hafnir","Halsa","Hauganes","Haugland","Hauknes","Hella","Helland","Hellissandur","Hestad","Higrav","Hnifsdalur","Hofn","Hofsos","Holand","Holar","Holen","Holkestad","Holmavik","Hopen","Hovden","Hrafnagil","Hrisey","Husavik","Husvik","Hvammstangi","Hvanneyri","Hveragerdi","Hvolsvollur","Igeroy","Indre","Inndyr","Innhavet","Innes","Isafjordur","Jarklaustur","Jarnsreykir","Junkerdal","Kaldvog","Kanstad","Karlsoy","Kavosen","Keflavik","Kjelde","Kjerstad","Klakk","Kopasker","Kopavogur","Korgen","Kristnes","Krutoga","Krystad","Kvina","Lande","Laugar","Laugaras","Laugarbakki","Laugarvatn","Laupstad","Leines","Leira","Leiren","Leland","Lenvika","Loding","Lodingen","Lonsbakki","Lopsmarka","Lovund","Luroy","Maela","Melahverfi","Meloy","Mevik","Misvaer","Mornes","Mosfellsbær","Moskenes","Myken","Naurstad","Nesberg","Nesjahverfi","Nesset","Nevernes","Obygda","Ofoten","Ogskardet","Okervika","Oknes","Olafsfjordur","Oldervika","Olstad","Onstad","Oppeid","Oresvika","Orsnes","Orsvog","Osmyra","Overdal","Prestoya","Raudalaekur","Raufarhofn","Reipo","Reykholar","Reykholt","Reykjahlid","Rif","Rinoya","Rodoy","Rognan","Rosvika","Rovika","Salhus","Sanden","Sandgerdi","Sandoker","Sandset","Sandvika","Saudarkrokur","Selfoss","Selsoya","Sennesvik","Setso","Siglufjordur","Silvalen","Skagastrond","Skjerstad","Skonland","Skorvogen","Skrova","Sleneset","Snubba","Softing","Solheim","Solheimar","Sorarnoy","Sorfugloy","Sorland","Sormela","Sorvaer","Sovika","Stamsund","Stamsvika","Stave","Stokka","Stokkseyri","Storjord","Storo","Storvika","Strand","Straumen","Strendene","Sudavik","Sudureyri","Sundoya","Sydalen","Thingeyri","Thorlakshofn","Thorshofn","Tjarnabyggd","Tjotta","Tosbotn","Traelnes","Trofors","Trones","Tverro","Ulvsvog","Unnstad","Utskor","Valla","Vandved","Varmahlid","Vassos","Vevelstad","Vidrek","Vik","Vikholmen","Vogar","Vogehamn","Vopnafjordur"], + ["Abdera","Abila","Abydos","Acanthus","Acharnae","Actium","Adramyttium","Aegae","Aegina","Aegium","Aenus","Agrinion","Aigosthena","Akragas","Akrai","Akrillai","Akroinon","Akrotiri","Alalia","Alexandreia","Alexandretta","Alexandria","Alinda","Amarynthos","Amaseia","Ambracia","Amida","Amisos","Amnisos","Amphicaea","Amphigeneia","Amphipolis","Amphissa","Ankon","Antigona","Antipatrea","Antioch","Antioch","Antiochia","Andros","Apamea","Aphidnae","Apollonia","Argos","Arsuf","Artanes","Artemita","Argyroupoli","Asine","Asklepios","Aspendos","Assus","Astacus","Athenai","Athmonia","Aytos","Ancient","Baris","Bhrytos","Borysthenes","Berge","Boura","Bouthroton","Brauron","Byblos","Byllis","Byzantium","Bythinion","Callipolis","Cebrene","Chalcedon","Calydon","Carystus","Chamaizi","Chalcis","Chersonesos","Chios","Chytri","Clazomenae","Cleonae","Cnidus","Colosse","Corcyra","Croton","Cyme","Cyrene","Cythera","Decelea","Delos","Delphi","Demetrias","Dicaearchia","Dimale","Didyma","Dion","Dioscurias","Dodona","Dorylaion","Dyme","Edessa","Elateia","Eleusis","Eleutherna","Emporion","Ephesus","Ephyra","Epidamnos","Epidauros","Eresos","Eretria","Erythrae","Eubea","Gangra","Gaza","Gela","Golgi","Gonnos","Gorgippia","Gournia","Gortyn","Gythium","Hagios","Hagia","Halicarnassus","Halieis","Helike","Heliopolis","Hellespontos","Helorus","Hemeroskopeion","Heraclea","Hermione","Hermonassa","Hierapetra","Hierapolis","Himera","Histria","Hubla","Hyele","Ialysos","Iasus","Idalium","Imbros","Iolcus","Itanos","Ithaca","Juktas","Kallipolis","Kamares","Kameiros","Kannia","Kamarina","Kasmenai","Katane","Kerkinitida","Kepoi","Kimmerikon","Kios","Klazomenai","Knidos","Knossos","Korinthos","Kos","Kourion","Kume","Kydonia","Kynos","Kyrenia","Lamia","Lampsacus","Laodicea","Lapithos","Larissa","Lato","Laus","Lebena","Lefkada","Lekhaion","Leibethra","Leontinoi","Lepreum","Lessa","Lilaea","Lindus","Lissus","Epizephyrian","Madytos","Magnesia","Mallia","Mantineia","Marathon","Marmara","Maroneia","Masis","Massalia","Megalopolis","Megara","Mesembria","Messene","Metapontum","Methana","Methone","Methumna","Miletos","Misenum","Mochlos","Monastiraki","Morgantina","Mulai","Mukenai","Mylasa","Myndus","Myonia","Myra","Myrmekion","Mutilene","Myos","Nauplíos","Naucratis","Naupactus","Naxos","Neapoli","Neapolis","Nemea","Nicaea","Nicopolis","Nirou","Nymphaion","Nysa","Oenoe","Oenus","Odessos","Olbia","Olous","Olympia","Olynthus","Opus","Orchomenus","Oricos","Orestias","Oreus","Oropus","Onchesmos","Pactye","Pagasae","Palaikastro","Pandosia","Panticapaeum","Paphos","Parium","Paros","Parthenope","Patrae","Pavlopetri","Pegai","Pelion","Peiraieús","Pella","Percote","Pergamum","Petsofa","Phaistos","Phaleron","Phanagoria","Pharae","Pharnacia","Pharos","Phaselis","Philippi","Pithekussa","Philippopolis","Platanos","Phlius","Pherae","Phocaea","Pinara","Pisa","Pitane","Pitiunt","Pixous","Plataea","Poseidonia","Potidaea","Priapus","Priene","Prousa","Pseira","Psychro","Pteleum","Pydna","Pylos","Pyrgos","Rhamnus","Rhegion","Rhithymna","Rhodes","Rhypes","Rizinia","Salamis","Same","Samos","Scyllaeum","Selinus","Seleucia","Semasus","Sestos","Scidrus","Sicyon","Side","Sidon","Siteia","Sinope","Siris","Sklavokampos","Smyrna","Soli","Sozopolis","Sparta","Stagirus","Stratos","Stymphalos","Sybaris","Surakousai","Taras","Tanagra","Tanais","Tauromenion","Tegea","Temnos","Tenedos","Tenea","Teos","Thapsos","Thassos","Thebai","Theodosia","Therma","Thespiae","Thronion","Thoricus","Thurii","Thyreum","Thyria","Tiruns","Tithoraea","Tomis","Tragurion","Trapeze","Trapezus","Tripolis","Troizen","Troliton","Troy","Tylissos","Tyras","Tyros","Tyritake","Vasiliki","Vathypetros","Zakynthos","Zakros","Zankle"], + ["Abila","Adflexum","Adnicrem","Aelia","Aelius","Aeminium","Aequum","Agrippina","Agrippinae","Ala","Albanianis","Ambianum","Andautonia","Apulum","Aquae","Aquaegranni","Aquensis","Aquileia","Aquincum","Arae","Argentoratum","Ariminum","Ascrivium","Atrebatum","Atuatuca","Augusta","Aurelia","Aurelianorum","Batavar","Batavorum","Belum","Biriciana","Blestium","Bonames","Bonna","Bononia","Borbetomagus","Bovium","Bracara","Brigantium","Burgodunum","Caesaraugusta","Caesarea","Caesaromagus","Calleva","Camulodunum","Cannstatt","Cantiacorum","Capitolina","Castellum","Castra","Castrum","Cibalae","Clausentum","Colonia","Concangis","Condate","Confluentes","Conimbriga","Corduba","Coria","Corieltauvorum","Corinium","Coriovallum","Cornoviorum","Danum","Deva","Divodurum","Dobunnorum","Drusi","Dubris","Dumnoniorum","Durnovaria","Durocobrivis","Durocornovium","Duroliponte","Durovernum","Durovigutum","Eboracum","Edetanorum","Emerita","Emona","Euracini","Faventia","Flaviae","Florentia","Forum","Gerulata","Gerunda","Glevensium","Hadriani","Herculanea","Isca","Italica","Iulia","Iuliobrigensium","Iuvavum","Lactodurum","Lagentium","Lauri","Legionis","Lemanis","Lentia","Lepidi","Letocetum","Lindinis","Lindum","Londinium","Lopodunum","Lousonna","Lucus","Lugdunum","Luguvalium","Lutetia","Mancunium","Marsonia","Martius","Massa","Matilo","Mattiacorum","Mediolanum","Mod","Mogontiacum","Moridunum","Mursa","Naissus","Nervia","Nida","Nigrum","Novaesium","Noviomagus","Olicana","Ovilava","Parisiorum","Partiscum","Paterna","Pistoria","Placentia","Pollentia","Pomaria","Pons","Portus","Praetoria","Praetorium","Pullum","Ragusium","Ratae","Raurica","Regina","Regium","Regulbium","Rigomagus","Roma","Romula","Rutupiae","Salassorum","Salernum","Salona","Scalabis","Segovia","Silurum","Sirmium","Siscia","Sorviodurum","Sumelocenna","Tarraco","Taurinorum","Theranda","Traiectum","Treverorum","Tungrorum","Turicum","Ulpia","Valentia","Venetiae","Venta","Verulamium","Vesontio","Vetera","Victoriae","Victrix","Villa","Viminacium","Vindelicorum","Vindobona","Vinovia","Viroconium"], + ["Aanekoski","Abjapaluoja","Ahlainen","Aholanvaara","Ahtari","Aijala","Aimala","Akaa","Alajarvi","Alatornio","Alavus","Antsla","Aspo","Bennas","Bjorkoby","Elva","Emasalo","Espoo","Esse","Evitskog","Forssa","Haapajarvi","Haapamaki","Haapavesi","Haapsalu","Haavisto","Hameenlinna","Hameenmaki","Hamina","Hanko","Harjavalta","Hattuvaara","Haukipudas","Hautajarvi","Havumaki","Heinola","Hetta","Hinkabole","Hirmula","Hossa","Huittinen","Husula","Hyryla","Hyvinkaa","Iisalmi","Ikaalinen","Ilmola","Imatra","Inari","Iskmo","Itakoski","Jamsa","Jarvenpaa","Jeppo","Jioesuu","Jiogeva","Joensuu","Jokela","Jokikyla","Jokisuu","Jormua","Juankoski","Jungsund","Jyvaskyla","Kaamasmukka","Kaarina","Kajaani","Kalajoki","Kallaste","Kankaanpaa","Kannus","Kardla","Karesuvanto","Karigasniemi","Karkkila","Karkku","Karksinuia","Karpankyla","Kaskinen","Kasnas","Kauhajoki","Kauhava","Kauniainen","Kauvatsa","Kehra","Keila","Kellokoski","Kelottijarvi","Kemi","Kemijarvi","Kerava","Keuruu","Kiikka","Kiipu","Kilinginiomme","Kiljava","Kilpisjarvi","Kitee","Kiuruvesi","Kivesjarvi","Kiviioli","Kivisuo","Klaukkala","Klovskog","Kohtlajarve","Kokemaki","Kokkola","Kolho","Koria","Koskue","Kotka","Kouva","Kouvola","Kristiina","Kaupunki","Kuhmo","Kunda","Kuopio","Kuressaare","Kurikka","Kusans","Kuusamo","Kylmalankyla","Lahti","Laitila","Lankipohja","Lansikyla","Lappeenranta","Lapua","Laurila","Lautiosaari","Lepsama","Liedakkala","Lieksa","Lihula","Littoinen","Lohja","Loimaa","Loksa","Loviisa","Luohuanylipaa","Lusi","Maardu","Maarianhamina","Malmi","Mantta","Masaby","Masala","Matasvaara","Maula","Miiluranta","Mikkeli","Mioisakula","Munapirtti","Mustvee","Muurahainen","Naantali","Nappa","Narpio","Nickby","Niinimaa","Niinisalo","Nikkila","Nilsia","Nivala","Nokia","Nummela","Nuorgam","Nurmes","Nuvvus","Obbnas","Oitti","Ojakkala","Ollola","onningeby","Orimattila","Orivesi","Otanmaki","Otava","Otepaa","Oulainen","Oulu","Outokumpu","Paavola","Paide","Paimio","Pakankyla","Paldiski","Parainen","Parkano","Parkumaki","Parola","Perttula","Pieksamaki","Pietarsaari","Pioltsamaa","Piolva","Pohjavaara","Porhola","Pori","Porrasa","Porvoo","Pudasjarvi","Purmo","Pussi","Pyhajarvi","Raahe","Raasepori","Raisio","Rajamaki","Rakvere","Rapina","Rapla","Rauma","Rautio","Reposaari","Riihimaki","Rovaniemi","Roykka","Ruonala","Ruottala","Rutalahti","Saarijarvi","Salo","Sastamala","Saue","Savonlinna","Seinajoki","Sillamae","Sindi","Siuntio","Somero","Sompujarvi","Suonenjoki","Suurejaani","Syrjantaka","Tampere","Tamsalu","Tapa","Temmes","Tiorva","Tormasenvaara","Tornio","Tottijarvi","Tulppio","Turenki","Turi","Tuukkala","Tuurala","Tuuri","Tuuski","Ulvila","Unari","Upinniemi","Utti","Uusikaarlepyy","Uusikaupunki","Vaaksy","Vaalimaa","Vaarinmaja","Vaasa","Vainikkala","Valga","Valkeakoski","Vantaa","Varkaus","Vehkapera","Vehmasmaki","Vieki","Vierumaki","Viitasaari","Viljandi","Vilppula","Viohma","Vioru","Virrat","Ylike","Ylivieska","Ylojarvi"], + ["Sabi","Wiryeseong","Hwando","Gungnae","Ungjin","Wanggeomseong","Ganggyeong","Jochiwon","Cheorwon","Beolgyo","Gangjin","Gampo","Yecheon","Geochang","Janghang","Hadong","Goseong","Yeongdong","Yesan","Sintaein","Geumsan","Boseong","Jangheung","Uiseong","Jumunjin","Janghowon","Hongseong","Gimhwa","Gwangcheon","Guryongpo","Jinyeong","Buan","Damyang","Jangseong","Wando","Angang","Okcheon","Jeungpyeong","Waegwan","Cheongdo","Gwangyang","Gochang","Haenam","Yeonggwang","Hanam","Eumseong","Daejeong","Hanrim","Samrye","Yongjin","Hamyang","Buyeo","Changnyeong","Yeongwol","Yeonmu","Gurye","Hwasun","Hampyeong","Namji","Samnangjin","Dogye","Hongcheon","Munsan","Gapyeong","Ganghwa","Geojin","Sangdong","Jeongseon","Sabuk","Seonghwan","Heunghae","Hapdeok","Sapgyo","Taean","Boeun","Geumwang","Jincheon","Bongdong","Doyang","Geoncheon","Pungsan","Punggi","Geumho","Wonju","Gaun","Hayang","Yeoju","Paengseong","Yeoncheon","Yangpyeong","Ganseong","Yanggu","Yangyang","Inje","Galmal","Pyeongchang","Hwacheon","Hoengseong","Seocheon","Cheongyang","Goesan","Danyang","Hamyeol","Muju","Sunchang","Imsil","Jangsu","Jinan","Goheung","Gokseong","Muan","Yeongam","Jindo","Seonsan","Daegaya","Gunwi","Bonghwa","Seongju","Yeongdeok","Yeongyang","Ulleung","Uljin","Cheongsong","wayang","Namhae","Sancheong","Uiryeong","Gaya","Hapcheon","Wabu","Dongsong","Sindong","Wondeok","Maepo","Anmyeon","Okgu","Sariwon","Dolsan","Daedeok","Gwansan","Geumil","Nohwa","Baeksu","Illo","Jido","Oedong","Ocheon","Yeonil","Hamchang","Pyeonghae","Gijang","Jeonggwan","Aewor","Gujwa","Seongsan","Jeongok","Seonggeo","Seungju","Hongnong","Jangan","Jocheon","Gohan","Jinjeop","Bubal","Beobwon","Yeomchi","Hwado","Daesan","Hwawon","Apo","Nampyeong","Munsan","Sinbuk","Munmak","Judeok","Bongyang","Ungcheon","Yugu","Unbong","Mangyeong","Dong","Naeseo","Sanyang","Soheul","Onsan","Eonyang","Nongong","Dasa","Goa","Jillyang","Bongdam","Naesu","Beomseo","Opo","Gongdo","Jingeon","Onam","Baekseok","Jiksan","Mokcheon","Jori","Anjung","Samho","Ujeong","Buksam","Tongjin","Chowol","Gonjiam","Pogok","Seokjeok","Poseung","Ochang","Hyangnam","Baebang","Gochon","Songak","Samhyang","Yangchon","Osong","Aphae","Ganam","Namyang","Chirwon","Andong","Ansan","Anseong","Anyang","Asan","Boryeong","Bucheon","Busan","Changwon","Cheonan","Cheongju","Chuncheon","Chungju","Daegu","Daejeon","Dangjin","Dongducheon","Donghae","Gangneung","Geoje","Gimcheon","Gimhae","Gimje","Gimpo","Gongju","Goyang","Gumi","Gunpo","Gunsan","Guri","Gwacheon","Gwangju","Gwangju","Gwangmyeong","Gyeongju","Gyeongsan","Gyeryong","Hwaseong","Icheon","Iksan","Incheon","Jecheon","Jeongeup","Jeonju","Jeju","Jinju","Naju","Namyangju","Namwon","Nonsan","Miryang","Mokpo","Mungyeong","Osan","Paju","Pocheon","Pohang","Pyeongtaek","Sacheon","Sangju","Samcheok","Sejong","Seogwipo","Seongnam","Seosan","Seoul","Siheung","Sokcho","Suncheon","Suwon","Taebaek","Tongyeong","Uijeongbu","Uiwang","Ulsan","Yangju","Yangsan","Yeongcheon","Yeongju","Yeosu","Yongin","Chungmu","Daecheon","Donggwangyang","Geumseong","Gyeongseong","Iri","Jangseungpo","Jeomchon","Jeongju","Migeum","Onyang","Samcheonpo","Busan","Busan","Cheongju","Chuncheon","Daegu","Daegu","Daejeon","Daejeon","Gunsan","Gwangju","Gwangju","Gyeongseong","Incheon","Incheon","Iri","Jeonju","Jinhae","Jinju","Masan","Masan","Mokpo","Songjeong","Songtan","Ulsan","Yeocheon","Cheongjin","Gaeseong","Haeju","Hamheung","Heungnam","Jinnampo","Najin","Pyeongyang","Seongjin","Sineuiju","Songnim","Wonsan"], + ["Anding","Anlu","Anqing","Anshun","Baan","Baixing","Banyang","Baoding","Baoqing","Binzhou","Caozhou","Changbai","Changchun","Changde","Changling","Changsha","Changtu","Changzhou","Chaozhou","Cheli","Chengde","Chengdu","Chenzhou","Chizhou","Chongqing","Chuxiong","Chuzhou","Dading","Dali","Daming","Datong","Daxing","Dean","Dengke","Dengzhou","Deqing","Dexing","Dihua","Dingli","Dongan","Dongchang","Dongchuan","Dongping","Duyun","Fengtian","Fengxiang","Fengyang","Fenzhou","Funing","Fuzhou","Ganzhou","Gaoyao","Gaozhou","Gongchang","Guangnan","Guangning","Guangping","Guangxin","Guangzhou","Guide","Guilin","Guiyang","Hailong","Hailun","Hangzhou","Hanyang","Hanzhong","Heihe","Hejian","Henan","Hengzhou","Hezhong","Huaian","Huaide","Huaiqing","Huanglong","Huangzhou","Huining","Huizhou","Hulan","Huzhou","Jiading","Jian","Jianchang","Jiande","Jiangning","Jiankang","Jianning","Jiaxing","Jiayang","Jilin","Jinan","Jingjiang","Jingzhao","Jingzhou","Jinhua","Jinzhou","Jiujiang","Kaifeng","Kaihua","Kangding","Kuizhou","Laizhou","Lanzhou","Leizhou","Liangzhou","Lianzhou","Liaoyang","Lijiang","Linan","Linhuang","Linjiang","Lintao","Liping","Liuzhou","Longan","Longjiang","Longqing","Longxing","Luan","Lubin","Lubin","Luzhou","Mishan","Nanan","Nanchang","Nandian","Nankang","Nanning","Nanyang","Nenjiang","Ningan","Ningbo","Ningguo","Ninguo","Ningwu","Ningxia","Ningyuan","Pingjiang","Pingle","Pingliang","Pingyang","Puer","Puzhou","Qianzhou","Qingyang","Qingyuan","Qingzhou","Qiongzhou","Qujing","Quzhou","Raozhou","Rende","Ruian","Ruizhou","Runing","Shafeng","Shajing","Shaoqing","Shaowu","Shaoxing","Shaozhou","Shinan","Shiqian","Shouchun","Shuangcheng","Shulei","Shunde","Shunqing","Shuntian","Shuoping","Sicheng","Sien","Sinan","Sizhou","Songjiang","Suiding","Suihua","Suining","Suzhou","Taian","Taibei","Tainan","Taiping","Taiwan","Taiyuan","Taizhou","Taonan","Tengchong","Tieli","Tingzhou","Tongchuan","Tongqing","Tongren","Tongzhou","Weihui","Wensu","Wenzhou","Wuchang","Wuding","Wuzhou","Xian","Xianchun","Xianping","Xijin","Xiliang","Xincheng","Xingan","Xingde","Xinghua","Xingjing","Xingqing","Xingyi","Xingyuan","Xingzhong","Xining","Xinmen","Xiping","Xuanhua","Xunzhou","Xuzhou","Yanan","Yangzhou","Yanji","Yanping","Yanqi","Yanzhou","Yazhou","Yichang","Yidu","Yilan","Yili","Yingchang","Yingde","Yingtian","Yingzhou","Yizhou","Yongchang","Yongping","Yongshun","Yongzhou","Yuanzhou","Yuezhou","Yulin","Yunnan","Yunyang","Zezhou","Zhangde","Zhangzhou","Zhaoqing","Zhaotong","Zhenan","Zhending","Zhengding","Zhenhai","Zhenjiang","Zhenxi","Zhenyun","Zhongshan","Zunyi"], + ["Nanporo","Naie","Kamisunagawa","Yuni","Naganuma","Kuriyama","Tsukigata","Urausu","Shintotsukawa","Moseushi","Chippubetsu","Uryu","Hokuryu","Numata","Tobetsu","Suttsu","Kuromatsunai","Rankoshi","Niseko","Kimobetsu","Kyogoku","Kutchan","Kyowa","Iwanai","Shakotan","Furubira","Niki","Yoichi","Toyoura","Toyako","Sobetsu","Shiraoi","Atsuma","Abira","Mukawa","Hidaka","Biratori","Niikappu","Urakawa","Samani","Erimo","Shinhidaka","Matsumae","Fukushima","Shiriuchi","Kikonai","Nanae","Shikabe","Mori","Yakumo","Oshamambe","Esashi","Kaminokuni","Assabu","Otobe","Okushiri","Imakane","Setana","Takasu","Higashikagura","Toma","Pippu","Aibetsu","Kamikawa","Higashikawa","Biei","Kamifurano","Nakafurano","Minamifurano","Horokanai","Wassamu","Kenbuchi","Shimokawa","Bifuka","Nakagawa","Mashike","Obira","Tomamae","Haboro","Enbetsu","Teshio","Hamatonbetsu","Nakatonbetsu","Esashi","Toyotomi","Horonobe","Rebun","Rishiri","Rishirifuji","Bihoro","Tsubetsu","Ozora","Shari","Kiyosato","Koshimizu","Kunneppu","Oketo","Saroma","Engaru","Yubetsu","Takinoue","Okoppe","Omu","Otofuke","Shihoro","Kamishihoro","Shikaoi","Shintoku","Shimizu","Memuro","Taiki","Hiroo","Makubetsu","Ikeda","Toyokoro","Honbetsu","Ashoro","Rikubetsu","Urahoro","Kushiro","Akkeshi","Hamanaka","Shibecha","Teshikaga","Shiranuka","Betsukai","Nakashibetsu","Shibetsu","Rausu","Hiranai","Imabetsu","Sotogahama","Ajigasawa","Fukaura","Fujisaki","Owani","Itayanagi","Tsuruta","Nakadomari","Noheji","Shichinohe","Rokunohe","Yokohama","Tohoku","Oirase","Oma","Sannohe","Gonohe","Takko","Nanbu","Hashikami","Shizukuishi","Kuzumaki","Iwate","Shiwa","Yahaba","Nishiwaga","Kanegasaki","Hiraizumi","Sumita","Otsuchi","Yamada","Iwaizumi","Karumai","Hirono","Ichinohe","Zao","Shichikashuku","Ogawara","Murata","Shibata","Kawasaki","Marumori","Watari","Yamamoto","Matsushima","Shichigahama","Rifu","Taiwa","Osato","Shikama","Kami","Wakuya","Misato","Onagawa","Minamisanriku","Kosaka","Fujisato","Mitane","Happo","Gojome","Hachirogata","Ikawa","Misato","Ugo","Yamanobe","Nakayama","Kahoku","Nishikawa","Asahi","Oe","Oishida","Kaneyama","Mogami","Funagata","Mamurogawa","Takahata","Kawanishi","Oguni","Shirataka","Iide","Mikawa","Shonai","Yuza","Koori","Kunimi","Kawamata","Kagamiishi","Shimogo","Tadami","Minamiaizu","Nishiaizu","Bandai","Inawashiro","Aizubange","Yanaizu","Mishima","Kaneyama","Aizumisato","Yabuki","Tanagura","Yamatsuri","Hanawa","Ishikawa","Asakawa","Furudono","Miharu","Ono","Hirono","Naraha","Tomioka","Okuma","Futaba","Namie","Shinchi","Ibaraki","Oarai","Shirosato","Daigo","Ami","Kawachi","Yachiyo","Goka","Sakai","Tone","Kaminokawa","Mashiko","Motegi","Ichikai","Haga","Mibu","Nogi","Shioya","Takanezawa","Nasu","Nakagawa","Yoshioka","Kanna","Shimonita","Kanra","Nakanojo","Naganohara","Kusatsu","Higashiagatsuma","Minakami","Tamamura","Itakura","Meiwa","Chiyoda","Oizumi","Ora","Ina","Miyoshi","Moroyama","Ogose","Namegawa","Ranzan","Ogawa","Kawajima","Yoshimi","Hatoyama","Tokigawa","Yokoze","Minano","Nagatoro","Ogano","Misato","Kamikawa","Kamisato","Yorii","Miyashiro","Sugito","Matsubushi","Shisui","Sakae","Kozaki","Tako","Tonosho","Kujukuri","Shibayama","Yokoshibahikari","Ichinomiya","Mutsuzawa","Shirako","Nagara","Chonan","Otaki","Onjuku","Kyonan","Mizuho","Hinode","Okutama","Oshima","Hachijo","Aikawa","Hayama","Samukawa","Oiso","Ninomiya","Nakai","Oi","Matsuda","Yamakita","Kaisei","Hakone","Manazuru","Yugawara","Seiro","Tagami","Aga","Izumozaki","Yuzawa","Tsunan","Kamiichi","Tateyama","Nyuzen","Asahi","Kawakita","Tsubata","Uchinada","Shika","Hodatsushimizu","Nakanoto","Anamizu","Noto","Eiheiji","Ikeda","Minamiechizen","Echizen","Mihama","Takahama","Oi","Wakasa","Ichikawamisato","Hayakawa","Minobu","Nanbu","Fujikawa","Showa","Nishikatsura","Fujikawaguchiko","Koumi","Sakuho","Karuizawa","Miyota","Tateshina","Nagawa","Shimosuwa","Fujimi","Tatsuno","Minowa","Iijima","Matsukawa","Takamori","Anan","Agematsu","Nagiso","Kiso","Ikeda","Sakaki","Obuse","Yamanouchi","Shinano","Iizuna","Ginan","Kasamatsu","Yoro","Tarui","Sekigahara","Godo","Wanouchi","Anpachi","Ibigawa","Ono","Ikeda","Kitagata","Sakahogi","Tomika","Kawabe","Hichiso","Yaotsu","Shirakawa","Mitake","Higashiizu","Kawazu","Minamiizu","Matsuzaki","Nishiizu","Kannami","Shimizu","Nagaizumi","Oyama","Yoshida","Kawanehon","Mori","Togo","Toyoyama","Oguchi","Fuso","Oharu","Kanie","Agui","Higashiura","Minamichita","Mihama","Taketoyo","Mihama","Kota","Shitara","Toei","Kisosaki","Toin","Komono","Asahi","Kawagoe","Taki","Meiwa","Odai","Tamaki","Watarai","Taiki","Minamiise","Kihoku","Mihama","Kiho","Hino","Ryuo","Aisho","Toyosato","Kora","Taga","Oyamazaki","Kumiyama","Ide","Ujitawara","Kasagi","Wazuka","Seika","Kyotamba","Ine","Yosano","Shimamoto","Toyono","Nose","Tadaoka","Kumatori","Tajiri","Misaki","Taishi","Kanan","Inagawa","Taka","Inami","Harima","Ichikawa","Fukusaki","Kamikawa","Taishi","Kamigori","Sayo","Kami","Shin'onsen","Heguri","Sango","Ikaruga","Ando","Kawanishi","Miyake","Tawaramoto","Takatori","Kanmaki","Oji","Koryo","Kawai","Yoshino","Oyodo","Shimoichi","Kushimoto","Kimino","Katsuragi","Kudoyama","Koya","Yuasa","Hirogawa","Aridagawa","Mihama","Hidaka","Yura","Inami","Minabe","Hidakagawa","Shirahama","Kamitonda","Susami","Nachikatsuura","Taiji","Kozagawa","Iwami","Wakasa","Chizu","Yazu","Misasa","Yurihama","Kotoura","Hokuei","Daisen","Nanbu","Hoki","Nichinan","Hino","Kofu","Okuizumo","Iinan","Kawamoto","Misato","Onan","Tsuwano","Yoshika","Ama","Nishinoshima","Okinoshima","Wake","Hayashima","Satosho","Yakage","Kagamino","Shoo","Nagi","Kumenan","Misaki","Kibichuo","Fuchu","Kaita","Kumano","Saka","Kitahiroshima","Akiota","Osakikamijima","Sera","Jinsekikogen","Suooshima","Waki","Kaminoseki","Tabuse","Hirao","Abu","Katsuura","Kamikatsu","Ishii","Kamiyama","Naka","Mugi","Minami","Kaiyo","Matsushige","Kitajima","Aizumi","Itano","Kamiita","Tsurugi","Higashimiyoshi","Tonosho","Shodoshima","Miki","Naoshima","Utazu","Ayagawa","Kotohira","Tadotsu","Manno","Kamijima","Kumakogen","Masaki","Tobe","Uchiko","Ikata","Kihoku","Matsuno","Ainan","Toyo","Nahari","Tano","Yasuda","Motoyama","Otoyo","Tosa","Ino","Niyodogawa","Nakatosa","Sakawa","Ochi","Yusuhara","Tsuno","Shimanto","Otsuki","Kuroshio","Nakagawa","Umi","Sasaguri","Shime","Sue","Shingu","Hisayama","Kasuya","Ashiya","Mizumaki","Okagaki","Onga","Kotake","Kurate","Keisen","Chikuzen","Tachiarai","Oki","Hirokawa","Kawara","Soeda","Itoda","Kawasaki","Oto","Fukuchi","Kanda","Miyako","Yoshitomi","Koge","Chikujo","Yoshinogari","Kiyama","Kamimine","Miyaki","Genkai","Arita","Omachi","Kohoku","Shiroishi","Tara","Nagayo","Togitsu","Higashisonogi","Kawatana","Hasami","Ojika","Saza","Shinkamigoto","Misato","Gyokuto","Nankan","Nagasu","Nagomi","Ozu","Kikuyo","Minamioguni","Oguni","Takamori","Mifune","Kashima","Mashiki","Kosa","Yamato","Hikawa","Ashikita","Tsunagi","Nishiki","Taragi","Yunomae","Asagiri","Reihoku","Hiji","Kusu","Kokonoe","Mimata","Takaharu","Kunitomi","Aya","Takanabe","Shintomi","Kijo","Kawaminami","Tsuno","Kadogawa","Misato","Takachiho","Hinokage","Gokase","Satsuma","Nagashima","Yusui","Osaki","Higashikushira","Kinko","Minamiosumi","Kimotsuki","Nakatane","Minamitane","Yakushima","Setouchi","Tatsugo","Kikai","Tokunoshima","Amagi","Isen","Wadomari","China","Yoron","Motobu","Kin","Kadena","Chatan","Nishihara","Yonabaru","Haebaru","Kumejima","Yaese","Taketomi","Yonaguni"] ]; } @@ -408,7 +407,7 @@ function fantasyMap() { console.time("calculateVoronoi"); diagram = voronoi(points); // round edges to simplify future calculations - diagram.edges.forEach(function (e) { + diagram.edges.forEach(function(e) { e[0][0] = rn(e[0][0], 2); e[0][1] = rn(e[0][1], 2); e[1][0] = rn(e[1][0], 2); @@ -466,13 +465,11 @@ function fantasyMap() { if (debug.selectAll(".tag").size() === 1) { const x = +debug.select(".tag").attr("cx"); const y = +debug.select(".tag").attr("cy"); - if (line.size()) { line.attr("x1", x).attr("y1", y).attr("x2", point[0]).attr("y2", point[1]); } - else { - debug.insert("line", ":first-child").attr("class", "line") - .attr("x1", x).attr("y1", y).attr("x2", point[0]).attr("y2", point[1]); - } + if (line.size()) {line.attr("x1", x).attr("y1", y).attr("x2", point[0]).attr("y2", point[1]);} + else {debug.insert("line", ":first-child").attr("class", "line") + .attr("x1", x).attr("y1", y).attr("x2", point[0]).attr("y2", point[1]);} } else { - line.remove(); + line.remove(); } } @@ -526,7 +523,7 @@ function fantasyMap() { // Drag actions function dragstarted() { var x0 = d3.event.x, y0 = d3.event.y, - c0 = diagram.find(x0, y0).index, c1 = c0; + c0 = diagram.find(x0, y0).index, c1 = c0; var x1, y1; var opisometer = $("#addOpisometer").hasClass("pressed"); var planimeter = $("#addPlanimeter").hasClass("pressed"); @@ -536,7 +533,7 @@ function fantasyMap() { $("#ruler").show(); var type = opisometer ? "opisometer" : "planimeter"; var rulerNew = ruler.append("g").attr("class", type).call(d3.drag().on("start", elementDrag)); - var points = [{ scX: rn(x0, 2), scY: rn(y0, 2) }]; + var points = [{scX: rn(x0, 2), scY: rn(y0, 2)}]; if (opisometer) { var curve = rulerNew.append("path").attr("class", "opisometer white").attr("stroke-width", factor); var dash = rn(30 / distanceScale.value, 2); @@ -547,7 +544,7 @@ function fantasyMap() { var text = rulerNew.append("text").attr("dy", -1).attr("font-size", 10 * factor); } - d3.event.on("drag", function () { + d3.event.on("drag", function() { x1 = d3.event.x, y1 = d3.event.y; var c2 = diagram.find(x1, y1).index; @@ -558,8 +555,8 @@ function fantasyMap() { const brush = $("#brushesButtons > .pressed"); const id = brush.attr("id"); const power = +brushPower.value; - if (id === "brushHill") { add(c2, "hill", power); updateHeightmap(); } - if (id === "brushPit") { addPit(1, power, c2); updateHeightmap(); } + if (id === "brushHill") {add(c2, "hill", power); updateHeightmap();} + if (id === "brushPit") {addPit(1, power, c2); updateHeightmap();} if (id !== "brushRange" || id !== "brushTrough") { // move a circle to show approximate change radius moveCircle(x1, y1); @@ -585,7 +582,7 @@ function fantasyMap() { if (opisometer || planimeter) { var l = points[points.length - 1]; var diff = Math.hypot(l.scX - x1, l.scY - y1); - if (diff > 5) { points.push({ scX: x1, scY: y1 }); } + if (diff > 5) {points.push({scX: x1, scY: y1});} if (opisometer) { lineGen.curve(d3.curveBasis); var d = round(lineGen(points)); @@ -602,7 +599,7 @@ function fantasyMap() { } }); - d3.event.on("end", function () { + d3.event.on("end", function() { if (customization === 1) updateHistory(); if (opisometer || planimeter) { $("#addOpisometer, #addPlanimeter").removeClass("pressed"); @@ -614,18 +611,18 @@ function fantasyMap() { var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; var atan = p.x > c.x ? Math.atan2(p.y - c.y, p.x - c.x) : Math.atan2(c.y - p.y, c.x - p.x); var angle = rn(atan * 180 / Math.PI, 3); - var tr = "rotate(" + angle + " " + c.x + " " + c.y + ")"; + var tr = "rotate(" + angle + " " + c.x + " " + c.y +")"; text.attr("data-points", JSON.stringify(points)).attr("data-dist", dist).attr("x", c.x).attr("y", c.y).attr("transform", tr).text(label).on("click", removeParent); rulerNew.append("circle").attr("cx", points[0].scX).attr("cy", points[0].scY).attr("r", 2 * factor).attr("stroke-width", 0.5 * factor) .attr("data-edge", "start").call(d3.drag().on("start", opisometerEdgeDrag)); rulerNew.append("circle").attr("cx", points[points.length - 1].scX).attr("cy", points[points.length - 1].scY).attr("r", 2 * factor).attr("stroke-width", 0.5 * factor) .attr("data-edge", "end").call(d3.drag().on("start", opisometerEdgeDrag)); } else { - var vertices = points.map(function (p) { return [p.scX, p.scY] }); + var vertices = points.map(function(p) {return [p.scX, p.scY]}); var area = rn(Math.abs(d3.polygonArea(vertices))); // initial area as positive integer var areaConv = area * Math.pow(distanceScale.value, 2); // convert area to distanceScale areaConv = si(areaConv); - if (areaUnit.value === "square") { areaConv += " " + distanceUnit.value + "²" } else { areaConv += " " + areaUnit.value; } + if (areaUnit.value === "square") {areaConv += " " + distanceUnit.value + "²"} else {areaConv += " " + areaUnit.value;} var c = polylabel([vertices], 1.0); // pole of inaccessibility text.attr("x", rn(c[0], 2)).attr("y", rn(c[1], 2)).attr("data-area", area).text(areaConv).on("click", removeParent); } @@ -648,14 +645,14 @@ function fantasyMap() { let radius = r; let selection = [center]; if (radius > 1) selection = selection.concat(cells[center].neighbors); - selection = $.grep(selection, function (e) { return cells[e].height >= 0.2; }); + selection = $.grep(selection, function(e) {return cells[e].height >= 0.2;}); if (radius === 2) return selection; let frontier = cells[center].neighbors; while (radius > 2) { let cycle = frontier.slice(); frontier = []; - cycle.map(function (s) { - cells[s].neighbors.forEach(function (e) { + cycle.map(function(s) { + cells[s].neighbors.forEach(function(e) { if (selection.indexOf(e) !== -1) return; // if (cells[e].height < 0.2) return; selection.push(e); @@ -664,7 +661,7 @@ function fantasyMap() { }); radius--; } - selection = $.grep(selection, function (e) { return cells[e].height >= 0.2; }); + selection = $.grep(selection, function(e) {return cells[e].height >= 0.2;}); return selection; } @@ -674,9 +671,9 @@ function fantasyMap() { const temp = regions.select("#temp"); const stateNew = +$("div.selected").attr("id").slice(5); const color = states[stateNew].color === "neutral" ? "white" : states[stateNew].color; - selection.map(function (index) { + selection.map(function(index) { // keep stateOld and stateNew as integers! - const exists = temp.select("path[data-cell='" + index + "']"); + const exists = temp.select("path[data-cell='"+index+"']"); const region = cells[index].region === "neutral" ? states.length - 1 : cells[index].region const stateOld = exists.size() ? +exists.attr("data-state") : region; if (stateNew === stateOld) return; @@ -697,8 +694,8 @@ function fantasyMap() { if (selection.length === 0) return; const cultureNew = +$("div.selected").attr("id").slice(7); const clr = cultures[cultureNew].color; - selection.map(function (index) { - const cult = cults.select("#cult" + index); + selection.map(function(index) { + const cult = cults.select("#cult"+index); const cultureOld = cult.attr("data-culture") !== null ? +cult.attr("data-culture") : cells[index].culture; @@ -712,18 +709,18 @@ function fantasyMap() { const power = +brushPower.value; let radius = +brushRadius.value; const brush = $("#brushesButtons > .pressed").attr("id"); - if ($("#brushesButtons > .pressed").hasClass("feature")) { return; } + if ($("#brushesButtons > .pressed").hasClass("feature")) {return;} // define selection besed on radius let selection = [cell]; - if (radius > 1) { selection = selection.concat(cells[cell].neighbors); } + if (radius > 1) {selection = selection.concat(cells[cell].neighbors);} if (radius > 2) { let frontier = cells[cell].neighbors; while (radius > 2) { let cycle = frontier.slice(); frontier = []; - cycle.map(function (s) { - cells[s].neighbors.forEach(function (e) { - if (selection.indexOf(e) !== -1) { return; } + cycle.map(function(s) { + cells[s].neighbors.forEach(function(e) { + if (selection.indexOf(e) !== -1) {return;} selection.push(e); frontier.push(e); }); @@ -733,17 +730,17 @@ function fantasyMap() { } // change each cell in the selection const sourceHeight = cells[source].height; - selection.map(function (s) { + selection.map(function(s) { // calculate changes if (brush === "brushElevate") { - if (cells[s].height < 0.2) { cells[s].height = 0.2 } - else { cells[s].height += power; } + if (cells[s].height < 0.2) {cells[s].height = 0.2} + else {cells[s].height += power;} } - if (brush === "brushDepress") { cells[s].height -= power; } - if (brush === "brushAlign") { cells[s].height = sourceHeight; } + if (brush === "brushDepress") {cells[s].height -= power;} + if (brush === "brushAlign") {cells[s].height = sourceHeight;} if (brush === "brushSmooth") { let heights = [cells[s].height]; - cells[s].neighbors.forEach(function (e) { heights.push(cells[e].height); }); + cells[s].neighbors.forEach(function(e) {heights.push(cells[e].height);}); cells[s].height = (cells[s].height + d3.mean(heights)) / 2; } }); @@ -773,11 +770,11 @@ function fantasyMap() { console.time("detectNeighbors"); var gridPath = ""; // store grid as huge single path string cells = []; - polygons.map(function (i, d) { + polygons.map(function(i, d) { var neighbors = []; var type; // define cell type - if (withGrid) { gridPath += "M" + i.join("L") + "Z"; } // grid path - diagram.cells[d].halfedges.forEach(function (e) { + if (withGrid) {gridPath += "M" + i.join("L") + "Z";} // grid path + diagram.cells[d].halfedges.forEach(function(e) { var edge = diagram.edges[e], ea; if (edge.left && edge.right) { const ea = edge.left.index === d ? edge.right.index : edge.left.index; @@ -786,9 +783,9 @@ function fantasyMap() { type = "border"; // polygon is on border if it has edge without opposite side polygon } }) - cells.push({ index: d, data: i.data, height: 0, type, neighbors }); + cells.push({index: d, data: i.data, height: 0, type, neighbors}); }); - if (withGrid) { grid.append("path").attr("d", round(gridPath, 1)); } + if (withGrid) {grid.append("path").attr("d", round(gridPath, 1));} console.timeEnd("detectNeighbors"); } @@ -797,22 +794,22 @@ function fantasyMap() { console.time('defineHeightmap'); if (lockTemplateInput.getAttribute("data-locked") == 0) { const rnd = Math.random(); - if (rnd > 0.9) { templateInput.value = "Volcano"; } - else if (rnd > 0.7) { templateInput.value = "High Island"; } - else if (rnd > 0.5) { templateInput.value = "Low Island"; } - else if (rnd > 0.35) { templateInput.value = "Continents"; } - else if (rnd > 0.01) { templateInput.value = "Archipelago"; } - else { templateInput.value = "Atoll"; } + if (rnd > 0.9) {templateInput.value = "Volcano";} + else if (rnd > 0.7) {templateInput.value = "High Island";} + else if (rnd > 0.5) {templateInput.value = "Low Island";} + else if (rnd > 0.35) {templateInput.value = "Continents";} + else if (rnd > 0.01) {templateInput.value = "Archipelago";} + else {templateInput.value = "Atoll";} } const mapTemplate = templateInput.value; addMountain(); const mod = rn((graphWidth + graphHeight) / 1500, 2); // add mod for big screens - if (mapTemplate === "Volcano") { templateVolcano(mod); } - if (mapTemplate === "High Island") { templateHighIsland(mod); } - if (mapTemplate === "Low Island") { templateLowIsland(mod); } - if (mapTemplate === "Continents") { templateContinents(mod); } - if (mapTemplate === "Archipelago") { templateArchipelago(mod); } - if (mapTemplate === "Atoll") { templateAtoll(mod); } + if (mapTemplate === "Volcano") {templateVolcano(mod);} + if (mapTemplate === "High Island") {templateHighIsland(mod);} + if (mapTemplate === "Low Island") {templateLowIsland(mod);} + if (mapTemplate === "Continents") {templateContinents(mod);} + if (mapTemplate === "Archipelago") {templateArchipelago(mod);} + if (mapTemplate === "Atoll") {templateAtoll(mod);} console.log(" template: " + mapTemplate); console.timeEnd('defineHeightmap'); } @@ -826,7 +823,7 @@ function fantasyMap() { addRange(rn(-10 * mod)); } - // Heighmap Template: High Island +// Heighmap Template: High Island function templateHighIsland(mod) { modifyHeights("all", 0.05, 0.9); addRange(rn(4 * mod)); @@ -836,7 +833,7 @@ function fantasyMap() { addHill(rn(3 * mod), 0.15); } - // Heighmap Template: Low Island +// Heighmap Template: Low Island function templateLowIsland(mod) { smoothHeights(2); addRange(rn(5 * mod)); @@ -897,10 +894,10 @@ function fantasyMap() { var limit = 0; do { var height = Math.random() * 0.4 + 0.1; - var x = Math.floor(Math.random() * graphWidth * (1 - shift * 2) + graphWidth * shift); - var y = Math.floor(Math.random() * graphHeight * (1 - shift * 2) + graphHeight * shift); + var x = Math.floor(Math.random() * graphWidth * (1-shift*2) + graphWidth * shift); + var y = Math.floor(Math.random() * graphHeight * (1-shift*2) + graphHeight * shift); var rnd = diagram.find(x, y).index; - limit++; + limit ++; } while (cells[rnd].height + height > 0.9 && limit < 100) add(rnd, "hill", height); } @@ -917,18 +914,18 @@ function fantasyMap() { } radius = type === "mountain" ? mRadius : hRadius; var queue = [start]; - if (type === "mountain") { cells[start].height = height; } + if (type === "mountain") {cells[start].height = height;} for (let i = 0; i < queue.length && height >= 0.01; i++) { if (type == "mountain") { height = +cells[queue[i]].height * radius - height / 100; } else { height *= radius; } - cells[queue[i]].neighbors.forEach(function (e) { - if (cells[e].used === session) { return; } + cells[queue[i]].neighbors.forEach(function(e) { + if (cells[e].used === session) {return;} var mod = Math.random() * 0.2 + 0.9; cells[e].height += height * mod; - if (cells[e].height > 1) { cells[e].height = 1; } + if (cells[e].height > 1) {cells[e].height = 1;} cells[e].used = session; queue.push(e); }); @@ -944,33 +941,33 @@ function fantasyMap() { var diff = 0, start = from, end = to; if (!start || !end) { do { - var xf = Math.floor(Math.random() * (graphWidth * 0.7)) + graphWidth * 0.15; - var yf = Math.floor(Math.random() * (graphHeight * 0.6)) + graphHeight * 0.2; + var xf = Math.floor(Math.random() * (graphWidth*0.7)) + graphWidth*0.15; + var yf = Math.floor(Math.random() * (graphHeight*0.6)) + graphHeight*0.2; start = diagram.find(xf, yf).index; - var xt = Math.floor(Math.random() * (graphWidth * 0.7)) + graphWidth * 0.15; - var yt = Math.floor(Math.random() * (graphHeight * 0.6)) + graphHeight * 0.2; + var xt = Math.floor(Math.random() * (graphWidth*0.7)) + graphWidth*0.15; + var yt = Math.floor(Math.random() * (graphHeight*0.6)) + graphHeight*0.2; end = diagram.find(xt, yt).index; diff = Math.hypot(xt - xf, yt - yf); - } while (diff < 150 / graphSize || diff > 300 / graphSize) + } while (diff < 150 / graphSize || diff > 300 / graphSize) } if (start && end) { for (let l = 0; start != end && l < 10000; l++) { var min = 10000; - cells[start].neighbors.forEach(function (e) { + cells[start].neighbors.forEach(function(e) { diff = Math.hypot(cells[end].data[0] - cells[e].data[0], cells[end].data[1] - cells[e].data[1]); - if (Math.random() > 0.8) { diff = diff / 2 } - if (diff < min) { min = diff, start = e; } + if (Math.random() > 0.8) {diff = diff / 2} + if (diff < min) {min = diff, start = e;} }); range.push(start); } } var change = height ? height : Math.random() * 0.1 + 0.1; - range.map(function (r) { + range.map(function(r) { var rnd = Math.random() * 0.4 + 0.8; - if (mod > 0) { cells[r].height += change * rnd; } - else if (cells[r].height >= 0.1) { cells[r].height -= change * rnd; } - cells[r].neighbors.forEach(function (e) { - if (cells[e].used === session) { return; } + if (mod > 0) {cells[r].height += change * rnd;} + else if (cells[r].height >= 0.1) {cells[r].height -= change * rnd;} + cells[r].neighbors.forEach(function(e) { + if (cells[e].used === session) {return;} cells[e].used = session; rnd = Math.random() * 0.4 + 0.8; if (mod > 0) { @@ -993,18 +990,18 @@ function fantasyMap() { var range = []; for (let l = 0; start !== end && l < 1000; l++) { var min = 10000; // dummy value - cells[start].neighbors.forEach(function (e) { - let diff = Math.hypot(cells[end].data[0] - cells[e].data[0], cells[end].data[1] - cells[e].data[1]); - if (Math.random() > 0.8) { diff = diff / 2 } - if (diff < min) { min = diff; start = e; } + cells[start].neighbors.forEach(function(e) { + diff = Math.hypot(cells[end].data[0] - cells[e].data[0], cells[end].data[1] - cells[e].data[1]); + if (Math.random() > 0.8) {diff = diff / 2} + if (diff < min) {min = diff; start = e;} }); range.push(start); } var query = []; for (; width > 0; width--) { - range.map(function (r) { - cells[r].neighbors.forEach(function (e) { - if (cells[e].used === session) { return; } + range.map(function(r) { + cells[r].neighbors.forEach(function(e) { + if (cells[e].used === session) {return;} cells[e].used = session; query.push(e); var height = cells[e].height * 0.23; @@ -1021,28 +1018,28 @@ function fantasyMap() { var change = height ? height + 0.1 : Math.random() * 0.1 + 0.2; var start = cell; if (!start) { - var lowlands = $.grep(cells, function (e) { return (e.height >= 0.2); }); - if (lowlands.length == 0) { return; } + var lowlands = $.grep(cells, function(e) {return (e.height >= 0.2);}); + if (lowlands.length == 0) {return;} var rnd = Math.floor(Math.random() * lowlands.length); start = lowlands[rnd].index; } - var query = [start], newQuery = []; + var query = [start], newQuery= []; // depress pit center cells[start].height -= change; - if (cells[start].height < 0.05) { cells[start].height = 0.05; } + if (cells[start].height < 0.05) {cells[start].height = 0.05;} cells[start].used = session; for (let i = 1; i < 10000; i++) { var rnd = Math.random() * 0.4 + 0.8; change -= i / 60 * rnd; - if (change < 0.01) { return; } - query.map(function (p) { - cells[p].neighbors.forEach(function (e) { - if (cells[e].used === session) { return; } + if (change < 0.01) {return;} + query.map(function(p) { + cells[p].neighbors.forEach(function(e) { + if (cells[e].used === session) {return;} cells[e].used = session; - if (Math.random() > 0.8) { return; } + if (Math.random() > 0.8) {return;} newQuery.push(e); cells[e].height -= change; - if (cells[e].height < 0.05) { cells[e].height = 0.05; } + if (cells[e].height < 0.05) {cells[e].height = 0.05;} }); }); query = newQuery.slice(); @@ -1053,14 +1050,14 @@ function fantasyMap() { // Modify heights multiplying/adding by value function modifyHeights(type, add, mult) { - cells.map(function (i) { + cells.map(function(i) { if (type === "land") { if (i.height >= 0.2) { i.height += add; var dif = i.height - 0.2; var factor = mult; - if (mult == "^2") { factor = dif } - if (mult == "^3") { factor = dif * dif; } + if (mult == "^2") {factor = dif} + if (mult == "^3") {factor = dif * dif;} i.height = 0.2 + dif * factor; } } else if (type === "all") { @@ -1072,8 +1069,8 @@ function fantasyMap() { var interval = type.split("-"); if (i.height >= +interval[0] && i.height <= +interval[1]) { i.height += add; - if ($.isNumeric(mult)) { i.height *= mult; return; } - if (mult.slice(0, 1) === "^") { + if ($.isNumeric(mult)) {i.height *= mult; return;} + if (mult.slice(0,1) === "^") { pow = mult.slice(1); i.height = Math.pow(i.height, pow); } @@ -1085,18 +1082,18 @@ function fantasyMap() { // Smooth heights using mean of neighbors function smoothHeights(fraction) { var fraction = fraction || 2; - cells.map(function (i) { + cells.map(function(i) { var heights = [i.height]; - i.neighbors.forEach(function (e) { heights.push(cells[e].height); }); + i.neighbors.forEach(function(e) {heights.push(cells[e].height);}); i.height = (i.height * (fraction - 1) + d3.mean(heights)) / fraction; }); } // Randomize heights a bit function disruptHeights() { - cells.map(function (i) { - if (i.height < 0.18) { return; } - if (Math.random() > 0.5) { return; } + cells.map(function(i) { + if (i.height < 0.18) {return;} + if (Math.random() > 0.5) {return;} var rnd = rn(2 - Math.random() * 4) / 100; i.height = rn(i.height + rnd, 2); }); @@ -1106,7 +1103,7 @@ function fantasyMap() { function markFeatures() { console.time("markFeatures"); - for (let i = 0, queue = [0]; queue.length > 0; i++) { + for (let i=0, queue=[0]; queue.length > 0; i++) { const cell = cells[queue[0]]; cell.fn = i; // feature number const land = cell.height >= 0.2; @@ -1120,7 +1117,7 @@ function fantasyMap() { if (land) cells[q].ctype = 2; } - cells[q].neighbors.forEach(function (e) { + cells[q].neighbors.forEach(function(e) { const eLand = cells[e].height >= 0.2; if (land === eLand && cells[e].fn === undefined) { cells[e].fn = i; @@ -1133,10 +1130,10 @@ function fantasyMap() { } }); } - features.push({ i, land, border }); + features.push({i, land, border}); // find unmarked cell - for (let c = 0; c < cells.length; c++) { + for (let c=0; c < cells.length; c++) { if (cells[c].fn === undefined) { queue[0] = c; break; @@ -1150,16 +1147,16 @@ function fantasyMap() { function reduceClosedLakes() { console.time("reduceClosedLakes"); const fs = JSON.parse(JSON.stringify(features)); - let lakesInit = lakesNow = features.reduce(function (s, f) { + let lakesInit = lakesNow = features.reduce(function(s, f) { return !f.land && !f.border ? s + 1 : s; }, 0); - for (let c = 0; c < cells.length && lakesNow > 0; c++) { + for (let c=0; c < cells.length && lakesNow > 0; c++) { if (cells[c].height < 0.2) continue; // not land if (cells[c].ctype !== 2) continue; // not near water let ocean = null, lake = null; // find land cells with lake and ocean nearby - cells[c].neighbors.forEach(function (n) { + cells[c].neighbors.forEach(function(n) { if (cells[n].height >= 0.2) return; const fn = cells[n].fn; if (features[fn].border !== false) ocean = fn; @@ -1168,17 +1165,17 @@ function fantasyMap() { // if found, make it water and turn lake to ocean if (ocean !== null && lake !== null) { //debug.append("circle").attr("cx", cells[c].data[0]).attr("cy", cells[c].data[1]).attr("r", 2).attr("fill", "red"); - lakesNow--; + lakesNow --; fs[lake].border = ocean; cells[c].height = 0.19; cells[c].fn = ocean; cells[c].ctype = -1; - cells[c].neighbors.forEach(function (e) { if (cells[e].height >= 0.2) cells[e].ctype = 2; }); + cells[c].neighbors.forEach(function(e) {if (cells[e].height >= 0.2) cells[e].ctype = 2;}); } } if (lakesInit === lakesNow) return; // nothing was changed - for (let i = 0; i < cells.length; i++) { + for (let i=0; i < cells.length; i++) { if (cells[i].height >= 0.2) continue; // not water const fn = cells[i].fn; if (fs[fn].border !== features[fn].border) { @@ -1194,37 +1191,37 @@ function fantasyMap() { let limits = []; let odd = 0.8; // initial odd for ocean layer is 80% // Define type of ocean cells based on cell distance form land - let frontier = $.grep(cells, function (e) { return e.ctype === -1; }); - if (Math.random() < odd) { limits.push(-1); odd = 0.2; } + let frontier = $.grep(cells, function(e) {return e.ctype === -1;}); + if (Math.random() < odd) {limits.push(-1); odd = 0.2;} for (let c = -2; frontier.length > 0 && c > -10; c--) { - if (Math.random() < odd) { limits.unshift(c); odd = 0.2; } else { odd += 0.2; } - frontier.map(function (i) { - i.neighbors.forEach(function (e) { + if (Math.random() < odd) {limits.unshift(c); odd = 0.2;} else {odd += 0.2;} + frontier.map(function(i) { + i.neighbors.forEach(function(e) { if (!cells[e].ctype) cells[e].ctype = c; }); }); - frontier = $.grep(cells, function (e) { return e.ctype === c; }); + frontier = $.grep(cells, function(e) {return e.ctype === c;}); } if (outlineLayersInput.value === "none") return; if (outlineLayersInput.value !== "random") limits = outlineLayersInput.value.split(","); // Define area edges const opacity = rn(0.4 / limits.length, 2); - for (let l = 0; l < limits.length; l++) { + for (let l=0; l < limits.length; l++) { const edges = []; const lim = +limits[l]; for (let i = 0; i < cells.length; i++) { if (cells[i].ctype < lim || cells[i].ctype === undefined) continue; if (cells[i].ctype > lim && cells[i].type !== "border") continue; const cell = diagram.cells[i]; - cell.halfedges.forEach(function (e) { + cell.halfedges.forEach(function(e) { const edge = diagram.edges[e]; const start = edge[0].join(" "); const end = edge[1].join(" "); if (edge.left && edge.right) { const ea = edge.left.index === i ? edge.right.index : edge.left.index; - if (cells[ea].ctype < lim) edges.push({ start, end }); + if (cells[ea].ctype < lim) edges.push({start, end}); } else { - edges.push({ start, end }); + edges.push({start, end}); } }); } @@ -1244,7 +1241,7 @@ function fantasyMap() { // get average precipitation based on graph size const avPrec = precInput.value / 5000; const evaporation = 2; - cells.map(function (i) { + cells.map(function(i) { let height = Math.trunc(i.height * 100) / 100; const ctype = i.ctype; if (ctype !== -1 && ctype !== -2 && height < 0.2) return; // exclude all depp ocean points @@ -1260,48 +1257,48 @@ function fantasyMap() { if (height < 0) height = 0; const region = i.region; // handle value for edit heightmap mode only const culture = i.culture; // handle value for edit heightmap mode only - let copy = $.grep(newPoints, function (e) { return (e[0] == x && e[1] == y); }); + let copy = $.grep(newPoints, function(e) {return (e[0] == x && e[1] == y);}); if (!copy.length) { newPoints.push([x, y]); - tempCells.push({ index: tempCells.length, data: [x, y], height, ctype, fn, harbor, lake, region, culture }); + tempCells.push({index:tempCells.length, data:[x, y], height, ctype, fn, harbor, lake, region, culture}); } // add additional points for cells along coast if (ctype === 2 || ctype === -1) { if (i.type === "border") return; if (!features[fn].land && !features[fn].border) return; - i.neighbors.forEach(function (e) { + i.neighbors.forEach(function(e) { if (cells[e].ctype === ctype) { let x1 = (x * 2 + cells[e].data[0]) / 3; let y1 = (y * 2 + cells[e].data[1]) / 3; x1 = rn(x1, 1), y1 = rn(y1, 1); - copy = $.grep(newPoints, function (e) { return e[0] === x1 && e[1] === y1; }); + copy = $.grep(newPoints, function(e) {return e[0] === x1 && e[1] === y1;}); if (copy.length) return; newPoints.push([x1, y1]); - tempCells.push({ index: tempCells.length, data: [x1, y1], height, ctype, fn, harbor, lake, region, culture }); + tempCells.push({index:tempCells.length, data:[x1, y1], height, ctype, fn, harbor, lake, region, culture}); }; }); } if (lake === 2) { // add potential small lakes //debug.append("circle").attr("r", 0.3).attr("cx", x).attr("cy", y).attr("fill", "blue"); height = Math.trunc(height * 100 + 1) / 100; - polygons[i.index].forEach(function (e) { + polygons[i.index].forEach(function(e) { if (Math.random() > 0.8) return; let rnd = Math.random() * 0.6 + 0.8; const x1 = rn((e[0] * rnd + i.data[0]) / (1 + rnd), 2); rnd = Math.random() * 0.6 + 0.8; const y1 = rn((e[1] * rnd + i.data[1]) / (1 + rnd), 2); - copy = $.grep(newPoints, function (c) { return x1 === c[0] && y1 === c[1]; }); + copy = $.grep(newPoints, function(c) {return x1 === c[0] && y1 === c[1];}); if (copy.length) return; //debug.append("circle").attr("r", 0.2).attr("cx", x1).attr("cy", y1).attr("fill", "red"); newPoints.push([x1, y1]); - tempCells.push({ index: tempCells.length, data: [x1, y1], height, ctype, fn, region, culture }); + tempCells.push({index:tempCells.length, data:[x1, y1], height, ctype, fn, region, culture}); }); } }); cells = tempCells; // use tempCells as the only cells array calculateVoronoi(newPoints); // recalculate Voronoi diagram using new points let gridPath = ""; // store grid as huge single path string - cells.map(function (i, d) { + cells.map(function(i, d) { if (i.height >= 0.2) { // calc cell area i.area = rn(Math.abs(d3.polygonArea(polygons[d])), 2); @@ -1309,7 +1306,7 @@ function fantasyMap() { i.flux = i.lake ? prec * 10 : prec; } const neighbors = []; // re-detect neighbors - diagram.cells[d].halfedges.forEach(function (e) { + diagram.cells[d].halfedges.forEach(function(e) { const edge = diagram.edges[e]; if (edge.left === undefined || edge.right === undefined) { if (i.height >= 0.2) i.ctype = 99; // border cell @@ -1335,10 +1332,10 @@ function fantasyMap() { let landCells = 0; $("#landmass").empty(); const limit = renderOcean.checked ? -1 : 0.2; - cells.map(function (i) { + cells.map(function(i) { if (i.height < limit) return; const clr = color(1 - i.height); - landmass.append("path").attr("id", "cell" + i.index) + landmass.append("path").attr("id", "cell"+i.index) .attr("d", "M" + polygons[i.index].join("L") + "Z") .attr("fill", clr).attr("stroke", clr); }); @@ -1348,18 +1345,18 @@ function fantasyMap() { // draw or update all cells function updateHeightmap() { - cells.map(function (c) { + cells.map(function(c) { let height = c.height; if (height > 1) height = 1; if (height < 0) height = 0; c.height = height; - let cell = landmass.select("#cell" + c.index); + let cell = landmass.select("#cell"+c.index); const clr = color(1 - height); if (cell.size()) { - if (height < 0.2) { cell.remove(); } - else { cell.attr("fill", clr).attr("stroke", clr); } + if (height < 0.2) {cell.remove();} + else {cell.attr("fill", clr).attr("stroke", clr);} } else if (height >= 0.2) { - cell = landmass.append("path").attr("id", "cell" + c.index) + cell = landmass.append("path").attr("id", "cell"+c.index) .attr("d", "M" + polygons[c.index].join("L") + "Z") .attr("fill", clr).attr("stroke", clr); } @@ -1368,19 +1365,19 @@ function fantasyMap() { // draw or update cells from the selection function updateHeightmapSelection(selection) { - if (selection === undefined) { selection = cells; } - selection.map(function (s) { + if (selection === undefined) {selection = cells;} + selection.map(function(s) { let height = cells[s].height; - if (height > 1) { height = 1; } - if (height < 0) { height = 0; } + if (height > 1) {height = 1;} + if (height < 0) {height = 0;} cells[s].height = height; - let cell = landmass.select("#cell" + s); + let cell = landmass.select("#cell"+s); const clr = color(1 - height); if (cell.size()) { - if (height < 0.2) { cell.remove(); } - else { cell.attr("fill", clr).attr("stroke", clr); } + if (height < 0.2) {cell.remove();} + else {cell.attr("fill", clr).attr("stroke", clr);} } else if (height >= 0.2) { - cell = landmass.append("path").attr("id", "cell" + s) + cell = landmass.append("path").attr("id", "cell"+s) .attr("d", "M" + polygons[s].join("L") + "Z") .attr("fill", clr).attr("stroke", clr); } @@ -1390,9 +1387,9 @@ function fantasyMap() { function updateHistory() { let heights = []; let landCells = 0; - cells.map(function (c) { + cells.map(function(c) { heights.push(c.height); - if (c.height >= 0.2) { landCells++; } + if (c.height >= 0.2) {landCells++;} }); history = history.slice(0, historyStage); history[historyStage] = heights; @@ -1402,10 +1399,10 @@ function fantasyMap() { var elevationAverage = rn(d3.mean(heights), 2); var landRatio = rn(landCells / cells.length * 100); landmassCounter.innerHTML = landCells + " (" + landRatio + "%); Average Elevation: " + elevationAverage; - if (landCells > 100) { $("#getMap").attr("disabled", false).removeClass("buttonoff").addClass("glow"); } - else { $("#getMap").attr("disabled", true).addClass("buttonoff").removeClass("glow"); } + if (landCells > 100) {$("#getMap").attr("disabled", false).removeClass("buttonoff").addClass("glow");} + else {$("#getMap").attr("disabled", true).addClass("buttonoff").removeClass("glow");} // if perspective is displayed, update it - if ($("#perspectivePanel").is(":visible")) { drawPerspective(); } + if ($("#perspectivePanel").is(":visible")) {drawPerspective();} } // restoreHistory @@ -1414,8 +1411,8 @@ function fantasyMap() { redo.disabled = templateRedo.disabled = historyStage < history.length ? false : true; undo.disabled = templateUndo.disabled = historyStage > 1 ? false : true; let heights = history[historyStage - 1]; - if (heights === undefined) { return; } - cells.map(function (i, d) { i.height = heights[d]; }); + if (heights === undefined) {return;} + cells.map(function(i, d) {i.height = heights[d];}); updateHeightmap(); } @@ -1436,71 +1433,71 @@ function fantasyMap() { let minX = graphWidth, maxX = 0; // extreme points let minXedge, maxXedge; // extreme edges const oceanEdges = [], lakeEdges = []; - for (let i = 0; i < land.length; i++) { + for (let i=0; i < land.length; i++) { const id = land[i].index, cell = diagram.cells[id]; const f = land[i].fn; land[i].height = Math.trunc(land[i].height * 100) / 100; - if (!oceanEdges[f]) { oceanEdges[f] = []; lakeEdges[f] = []; } - cell.halfedges.forEach(function (e) { - const edge = diagram.edges[e]; - const start = edge[0].join(" "); - const end = edge[1].join(" "); - if (edge.left && edge.right) { - const ea = edge.left.index === id ? edge.right.index : edge.left.index; + if (!oceanEdges[f]) {oceanEdges[f] = []; lakeEdges[f] = [];} + cell.halfedges.forEach(function(e) { + const edge = diagram.edges[e]; + const start = edge[0].join(" "); + const end = edge[1].join(" "); + if (edge.left && edge.right) { + const ea = edge.left.index === id ? edge.right.index : edge.left.index; cells[ea].height = Math.trunc(cells[ea].height * 100) / 100; - if (cells[ea].height < 0.2) { + if (cells[ea].height < 0.2) { cells[ea].ctype = -1; if (land[i].ctype !== 1) { land[i].ctype = 1; // mark coastal land cells - // move cell point closer to coast - const x = (land[i].data[0] + cells[ea].data[0]) / 2; - const y = (land[i].data[1] + cells[ea].data[1]) / 2; - land[i].haven = ea; // harbor haven (oposite water cell) - land[i].coastX = x, land[i].coastY = y; - land[i].data[0] = rn(x + (land[i].data[0] - x) * 0.5, 1); - land[i].data[1] = rn(y + (land[i].data[1] - y) * 0.5, 1); + // move cell point closer to coast + const x = (land[i].data[0] + cells[ea].data[0]) / 2; + const y = (land[i].data[1] + cells[ea].data[1]) / 2; + land[i].haven = ea; // harbor haven (oposite water cell) + land[i].coastX = x, land[i].coastY = y; + land[i].data[0] = rn(x + (land[i].data[0] - x) * 0.5, 1); + land[i].data[1] = rn(y + (land[i].data[1] - y) * 0.5, 1); } - if (features[cells[ea].fn].border) { - //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "blue").attr("stroke-width", .2); - oceanEdges[f].push({ start, end }); - // island extreme points - if (edge[0][0] < minX) { minX = edge[0][0]; minXedge = edge[0] } - if (edge[1][0] < minX) { minX = edge[1][0]; minXedge = edge[1] } - if (edge[0][0] > maxX) { maxX = edge[0][0]; maxXedge = edge[0] } - if (edge[1][0] > maxX) { maxX = edge[1][0]; maxXedge = edge[1] } - } else { + if (features[cells[ea].fn].border) { + //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "blue").attr("stroke-width", .2); + oceanEdges[f].push({start, end}); + // island extreme points + if (edge[0][0] < minX) {minX = edge[0][0]; minXedge = edge[0]} + if (edge[1][0] < minX) {minX = edge[1][0]; minXedge = edge[1]} + if (edge[0][0] > maxX) {maxX = edge[0][0]; maxXedge = edge[0]} + if (edge[1][0] > maxX) {maxX = edge[1][0]; maxXedge = edge[1]} + } else { const l = cells[ea].fn; if (!lakeEdges[f][l]) lakeEdges[f][l] = []; - lakeEdges[f][l].push({ start, end }); - //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "red").attr("stroke-width", .2); - } - } - } else { - oceanEdges[f].push({ start, end }); - //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "black").attr("stroke-width", .5); - } - }); + lakeEdges[f][l].push({start, end}); + //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "red").attr("stroke-width", .2); + } + } + } else { + oceanEdges[f].push({start, end}); + //debug.append("line").attr("x1", edge[0][0]).attr("y1", edge[0][1]).attr("x2", edge[1][0]).attr("y2", edge[1][1]).attr("stroke", "black").attr("stroke-width", .5); + } + }); } for (let f = 0; f < features.length; f++) { - if (!oceanEdges[f]) continue; + if (!oceanEdges[f]) continue; if (!oceanEdges[f].length && lakeEdges[f].length) { const m = lakeEdges[f].indexOf(d3.max(lakeEdges[f])); oceanEdges[f] = lakeEdges[f][m]; lakeEdges[f][m] = []; } lineGen.curve(d3.curveCatmullRomClosed.alpha(0.1)); - const oceanCoastline = getContinuousLine(oceanEdges[f], 3, 0); + const oceanCoastline = getContinuousLine(oceanEdges[f], 3, 0); if (oceanCoastline) { shape.append("path").attr("d", oceanCoastline).attr("fill", "white"); // draw the mask coastline.append("path").attr("d", oceanCoastline); // draw the coastline } lineGen.curve(d3.curveBasisClosed); - lakeEdges[f].forEach(function (l) { + lakeEdges[f].forEach(function(l) { const lakeCoastline = getContinuousLine(l, 3, 0); if (lakeCoastline) { shape.append("path").attr("d", lakeCoastline).attr("fill", "black"); // draw the mask - lakes.append("path").attr("d", lakeCoastline); // draw the lakes + lakes.append("path").attr("d", lakeCoastline); // draw the lakes } }); } @@ -1520,16 +1517,16 @@ function fantasyMap() { var scaleBar = svg.append("g").attr("id", "scaleBar").on("click", editScale).call(d3.drag().on("start", elementDrag)); const init = 100; // actual length in pixels if scale, dScale and size = 1; let val = init * size * dScale / scale; // bar length in distance unit - if (val > 900) { val = rn(val, -3); } // round to 1000 - else if (val > 90) { val = rn(val, -2); } // round to 100 - else if (val > 9) { val = rn(val, -1); } // round to 10 - else { val = rn(val) } // round to 1 + if (val > 900) {val = rn(val, -3);} // round to 1000 + else if (val > 90) {val = rn(val, -2);} // round to 100 + else if (val > 9) {val = rn(val, -1);} // round to 10 + else {val = rn(val)} // round to 1 const l = val * scale / dScale; // actual length in pixels on this scale const x = 0, y = 0; // initial position - scaleBar.append("line").attr("x1", x + 0.5).attr("y1", y).attr("x2", x + l + size - 0.5).attr("y2", y).attr("stroke-width", size).attr("stroke", "white"); - scaleBar.append("line").attr("x1", x).attr("y1", y + size).attr("x2", x + l + size).attr("y2", y + size).attr("stroke-width", size).attr("stroke", "#3d3d3d"); + scaleBar.append("line").attr("x1", x+0.5).attr("y1", y).attr("x2", x+l+size-0.5).attr("y2", y).attr("stroke-width", size).attr("stroke", "white"); + scaleBar.append("line").attr("x1", x).attr("y1", y + size).attr("x2", x+l+size).attr("y2", y + size).attr("stroke-width", size).attr("stroke", "#3d3d3d"); const dash = size + " " + rn(l / 5 - size, 2); - scaleBar.append("line").attr("x1", x).attr("y1", y).attr("x2", x + l + size).attr("y2", y) + scaleBar.append("line").attr("x1", x).attr("y1", y).attr("x2", x+l+size).attr("y2", y) .attr("stroke-width", rn(size * 3, 2)).attr("stroke-dasharray", dash).attr("stroke", "#3d3d3d"); // big scale for (let b = 0; b < 6; b++) { @@ -1542,7 +1539,7 @@ function fantasyMap() { } } if (barLabel.value !== "") { - scaleBar.append("text").attr("x", x + (l + 1) / 2).attr("y", y + 2 * size) + scaleBar.append("text").attr("x", x + (l+1) / 2).attr("y", y + 2 * size) .attr("dominant-baseline", "text-before-edge") .attr("font-size", rn(5 * size, 1)).text(barLabel.value); } @@ -1567,7 +1564,7 @@ function fantasyMap() { const x0 = rn((x1 + x2) / 2, 2), y0 = rn((y1 + y2) / 2, 2); rulerNew.append("circle").attr("r", 1.2).attr("cx", x0).attr("cy", y0).attr("stroke-width", 0.3).attr("class", "center").call(d3.drag().on("start", rulerCenterDrag)); const angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI; - const tr = "rotate(" + angle + " " + x0 + " " + y0 + ")"; + const tr = "rotate(" + angle + " " + x0 + " " + y0 +")"; const dist = rn(Math.hypot(x1 - x2, y1 - y2)); const label = rn(dist * distanceScale.value) + " " + distanceUnit.value; rulerNew.append("text").attr("x", x0).attr("y", y0).attr("dy", -1).attr("transform", tr).attr("data-dist", dist).text(label).on("click", removeParent).attr("font-size", 10); @@ -1580,13 +1577,13 @@ function fantasyMap() { const x = d3.event.x, y = d3.event.y; const dx = +tr[0] - x, dy = +tr[1] - y; - d3.event.on("drag", function () { + d3.event.on("drag", function() { const x = d3.event.x, y = d3.event.y; - const transform = `translate(${(dx + x)},${(dy + y)})`; + const transform = `translate(${(dx+x)},${(dy+y)})`; el.attr("transform", transform); }); - d3.event.on("end", function () { + d3.event.on("end", function() { // remember scaleBar bottom-right position if (el.attr("id") === "scaleBar") { const xEnd = d3.event.x, yEnd = d3.event.y; @@ -1619,7 +1616,7 @@ function fantasyMap() { var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; var atan = x0 > x ? Math.atan2(y0 - y, x0 - x) : Math.atan2(y - y0, x - x0); var angle = rn(atan * 180 / Math.PI, 3); - var tr = "rotate(" + angle + " " + xc + " " + yc + ")"; + var tr = "rotate(" + angle + " " + xc + " " + yc +")"; group.select("text").attr("x", xc).attr("y", yc).attr("transform", tr).attr("data-dist", dist).text(label); } @@ -1638,7 +1635,7 @@ function fantasyMap() { rulerNew.append("line").attr("class", "gray").attr("stroke-dasharray", dash).attr("stroke-width", factor); rulerNew.append("text").attr("dy", -1).on("click", removeParent).attr("font-size", 10 * factor).attr("stroke-width", factor); - d3.event.on("drag", function () { + d3.event.on("drag", function() { x = d3.event.x, y = d3.event.y; d3.select(this).attr("cx", x).attr("cy", y); // change first part @@ -1647,19 +1644,19 @@ function fantasyMap() { var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; var atan = x1 > x ? Math.atan2(y1 - y, x1 - x) : Math.atan2(y - y1, x - x1); xc1 = rn((x + x1) / 2, 2), yc1 = rn((y + y1) / 2, 2); - var tr = "rotate(" + rn(atan * 180 / Math.PI, 3) + " " + xc1 + " " + yc1 + ")"; + var tr = "rotate(" + rn(atan * 180 / Math.PI, 3) + " " + xc1 + " " + yc1 +")"; group.select("text").attr("x", xc1).attr("y", yc1).attr("transform", tr).attr("data-dist", dist).text(label); // change second (new) part dist = rn(Math.hypot(x2 - x, y2 - y)); label = rn(dist * distanceScale.value) + " " + distanceUnit.value; atan = x2 > x ? Math.atan2(y2 - y, x2 - x) : Math.atan2(y - y2, x - x2); xc2 = rn((x + x2) / 2, 2), yc2 = rn((y + y2) / 2, 2); - tr = "rotate(" + rn(atan * 180 / Math.PI, 3) + " " + xc2 + " " + yc2 + ")"; + tr = "rotate(" + rn(atan * 180 / Math.PI, 3) + " " + xc2 + " " + yc2 +")"; rulerNew.selectAll("line").attr("x1", x).attr("y1", y).attr("x2", x2).attr("y2", y2); rulerNew.select("text").attr("x", xc2).attr("y", yc2).attr("transform", tr).attr("data-dist", dist).text(label); }); - d3.event.on("end", function () { + d3.event.on("end", function() { // circles for 1st part group.selectAll("circle").remove(); group.append("circle").attr("cx", x1).attr("cy", y1).attr("r", 2 * factor).attr("stroke-width", 0.5 * factor).attr("data-edge", "left").call(d3.drag().on("drag", rulerEdgeDrag)); @@ -1680,14 +1677,14 @@ function fantasyMap() { var curveGray = group.select(".gray"); var text = group.select("text"); var points = JSON.parse(text.attr("data-points")); - if (x0 === points[0].scX && y0 === points[0].scY) { points.reverse(); } + if (x0 === points[0].scX && y0 === points[0].scY) {points.reverse();} - d3.event.on("drag", function () { + d3.event.on("drag", function() { var x = d3.event.x, y = d3.event.y; el.attr("cx", x).attr("cy", y); var l = points[points.length - 1]; var diff = Math.hypot(l.scX - x, l.scY - y); - if (diff > 5) { points.push({ scX: x, scY: y }); } else { return; } + if (diff > 5) {points.push({scX: x, scY: y});} else {return;} lineGen.curve(d3.curveBasis); var d = round(lineGen(points)); curve.attr("d", d); @@ -1697,14 +1694,14 @@ function fantasyMap() { text.attr("x", x).attr("y", y).text(label); }); - d3.event.on("end", function () { + d3.event.on("end", function() { var dist = rn(curve.node().getTotalLength()); var c = curve.node().getPointAtLength(dist / 2); var p = curve.node().getPointAtLength((dist / 2) - 1); var label = rn(dist * distanceScale.value) + " " + distanceUnit.value; var atan = p.x > c.x ? Math.atan2(p.y - c.y, p.x - c.x) : Math.atan2(c.y - p.y, c.x - p.x); var angle = rn(atan * 180 / Math.PI, 3); - var tr = "rotate(" + angle + " " + c.x + " " + c.y + ")"; + var tr = "rotate(" + angle + " " + c.x + " " + c.y +")"; text.attr("data-points", JSON.stringify(points)).attr("data-dist", dist).attr("x", c.x).attr("y", c.y).attr("transform", tr).text(label); }); } @@ -1718,9 +1715,9 @@ function fantasyMap() { let end = edges[0].end; edges.shift(); let spl = start.split(" "); - edgesOrdered.push({ scX: +spl[0], scY: +spl[1] }); + edgesOrdered.push({scX: +spl[0], scY: +spl[1]}); spl = end.split(" "); - edgesOrdered.push({ scX: +spl[0], scY: +spl[1] }); + edgesOrdered.push({scX: +spl[0], scY: +spl[1]}); let x0 = +spl[0], y0 = +spl[1]; for (let i = 0; end !== start && i < 100000; i++) { let next = null, index = null; @@ -1741,14 +1738,14 @@ function fantasyMap() { if (indention || relax) { const dist = Math.hypot(+spl[0] - x0, +spl[1] - y0); if (dist >= indention && Math.random() > relax) { - edgesOrdered.push({ scX: +spl[0], scY: +spl[1] }); + edgesOrdered.push({scX: +spl[0], scY: +spl[1]}); x0 = +spl[0], y0 = +spl[1]; } } else { - edgesOrdered.push({ scX: +spl[0], scY: +spl[1] }); + edgesOrdered.push({scX: +spl[0], scY: +spl[1]}); } edges.splice(index, 1); - if (i === 100000 - 1) { + if (i === 100000-1) { console.error("Line not ended, limit reached"); break; } @@ -1761,11 +1758,11 @@ function fantasyMap() { // temporary elevate lakes to min neighbors heights to correctly flux the water function elevateLakes() { console.time('elevateLakes'); - const lakes = $.grep(cells, function (e) { return e.height < 0.2 && !features[e.fn].border; }); - lakes.sort(function (a, b) { return b.height - a.height; }); - for (let i = 0; i < lakes.length; i++) { + const lakes = $.grep(cells, function(e) {return e.height < 0.2 && !features[e.fn].border;}); + lakes.sort(function(a, b) {return b.height - a.height;}); + for (let i=0; i < lakes.length; i++) { const heights = []; - lakes[i].neighbors.forEach(function (n) { if (cells[n].height >= 0.2) heights.push(cells[n].height) }); + lakes[i].neighbors.forEach(function(n) {if (cells[n].height >= 0.2) heights.push(cells[n].height)}); if (heights.length) lakes[i].height = Math.trunc((d3.min(heights) - 0.01) * 100) / 100; if (cells[i].height < 0.2) lakes[i].height = 0.2; lakes[i].lake = 1; @@ -1776,14 +1773,14 @@ function fantasyMap() { // Depression filling algorithm (for a correct water flux modeling; phase1) function resolveDepressionsPrimary() { console.time('resolveDepressionsPrimary'); - land = $.grep(cells, function (e) { return e.height >= 0.2; }); - land.sort(function (a, b) { return b.height - a.height; }); + land = $.grep(cells, function(e) {return e.height >= 0.2;}); + land.sort(function(a, b) {return b.height - a.height;}); const limit = 10; for (let l = 0, depression = 1; depression > 0 && l < limit; l++) { depression = 0; for (let i = 0; i < land.length; i++) { if (land[i].type === "border") continue; - const heights = land[i].neighbors.map(function (n) { return cells[n].height }); + const heights = land[i].neighbors.map(function(n) {return cells[n].height}); const minHigh = d3.min(heights); if (land[i].height <= minHigh) { depression++; @@ -1799,14 +1796,14 @@ function fantasyMap() { // Depression filling algorithm (for a correct water flux modeling; phase2) function resolveDepressionsSecondary() { console.time('resolveDepressionsSecondary'); - land = $.grep(cells, function (e) { return e.height >= 0.2; }); - land.sort(function (a, b) { return b.height - a.height; }); + land = $.grep(cells, function(e) {return e.height >= 0.2;}); + land.sort(function(a, b) {return b.height - a.height;}); const limit = 100; for (let l = 0, depression = 1; depression > 0 && l < limit; l++) { depression = 0; for (let i = 0; i < land.length; i++) { if (land[i].ctype === 99) continue; - const heights = land[i].neighbors.map(function (n) { return cells[n].height }); + const heights = land[i].neighbors.map(function(n) {return cells[n].height}); const minHigh = d3.min(heights); if (land[i].height <= minHigh) { depression++; @@ -1821,14 +1818,14 @@ function fantasyMap() { } function restoreCustomHeights() { - land.forEach(function (l) { if (l.pit) rn(l.height -= l.pit / 50, 2); }); + land.forEach(function(l) {if (l.pit) rn(l.height -= l.pit / 50, 2);}); } function flux() { console.time('flux'); riversData = []; let riverNext = 0; - land.sort(function (a, b) { return b.height - a.height; }); + land.sort(function(a, b) {return b.height - a.height;}); for (let i = 0; i < land.length; i++) { const id = land[i].index; const sx = land[i].data[0]; @@ -1838,11 +1835,11 @@ function fantasyMap() { if (land[i].river !== undefined) { let x, y; const min = Math.min(sy, graphHeight - sy, sx, graphWidth - sx); - if (min === sy) { x = sx; y = 0; } - if (min === graphHeight - sy) { x = sx; y = graphHeight; } - if (min === sx) { x = 0; y = sy; } - if (min === graphWidth - sx) { x = graphWidth; y = sy; } - riversData.push({ river: land[i].river, cell: id, x, y }); + if (min === sy) {x = sx; y = 0;} + if (min === graphHeight - sy) {x = sx; y = graphHeight;} + if (min === sx) {x = 0; y = sy;} + if (min === graphWidth - sx) {x = graphWidth; y = sy;} + riversData.push({river: land[i].river, cell: id, x, y}); } continue; } @@ -1853,7 +1850,7 @@ function fantasyMap() { } } let minHeight = 10, min; - land[i].neighbors.forEach(function (e) { + land[i].neighbors.forEach(function(e) { if (cells[e].height < minHeight) { minHeight = cells[e].height; min = e; @@ -1864,7 +1861,7 @@ function fantasyMap() { if (land[i].river === undefined) { // State new River land[i].river = riverNext; - riversData.push({ river: riverNext, cell: id, x: sx, y: sy }); + riversData.push({river: riverNext, cell: id, x: sx, y: sy}); riverNext += 1; } // Assing existing River to the downhill cell @@ -1872,8 +1869,8 @@ function fantasyMap() { cells[min].river = land[i].river; } else { var riverTo = cells[min].river; - var iRiver = $.grep(riversData, function (e) { return (e.river == land[i].river); }); - var minRiver = $.grep(riversData, function (e) { return (e.river == riverTo); }); + var iRiver = $.grep(riversData, function(e) {return (e.river == land[i].river);}); + var minRiver = $.grep(riversData, function(e) {return (e.river == riverTo);}); var iRiverL = iRiver.length; var minRiverL = minRiver.length; // re-assing river nunber if new part is greater @@ -1885,9 +1882,9 @@ function fantasyMap() { // mark confluences if (cells[min].height >= 0.2 && iRiverL > 1 && minRiverL > 1) { if (!cells[min].confluence) { - cells[min].confluence = minRiverL - 1; + cells[min].confluence = minRiverL-1; } else { - cells[min].confluence += minRiverL - 1; + cells[min].confluence += minRiverL-1; } } } @@ -1900,14 +1897,14 @@ function fantasyMap() { // pour water to the sea const x = (px + sx) / 2 + (px - sx) / 10; const y = (py + sy) / 2 + (py - sy) / 10; - riversData.push({ river: land[i].river, cell: id, x, y }); + riversData.push({river: land[i].river, cell: id, x, y}); } else { if (cells[min].lake === 1) { fn = cells[min].fn; if (features[fn].river === undefined) features[fn].river = land[i].river; } // add next River segment - riversData.push({ river: land[i].river, cell: min, x: px, y: py }); + riversData.push({river: land[i].river, cell: min, x: px, y: py}); } } } @@ -1918,13 +1915,13 @@ function fantasyMap() { function drawRiverLines(riverNext) { console.time('drawRiverLines'); for (let i = 0; i < riverNext; i++) { - var dataRiver = $.grep(riversData, function (e) { return e.river === i; }); + var dataRiver = $.grep(riversData, function(e) {return e.river === i;}); if (dataRiver.length > 1) { var riverAmended = amendRiver(dataRiver, 1); var width = rn(0.8 + Math.random() * 0.4, 1); var increment = rn(0.8 + Math.random() * 0.4, 1); var d = drawRiver(riverAmended, width, increment); - rivers.append("path").attr("d", d).attr("id", "river" + i).attr("data-width", width).attr("data-increment", increment); + rivers.append("path").attr("d", d).attr("id", "river"+i).attr("data-width", width).attr("data-increment", increment); } } rivers.selectAll("path").on("click", editRiver); @@ -1940,13 +1937,13 @@ function fantasyMap() { var cell = dataRiver[r].cell; var c = cells[cell].confluence || 0; riverAmended.push([dX, dY, c]); - if (r + 1 < dataRiver.length) { - var eX = dataRiver[r + 1].x; - var eY = dataRiver[r + 1].y; + if (r+1 < dataRiver.length) { + var eX = dataRiver[r+1].x; + var eY = dataRiver[r+1].y; var angle = Math.atan2(eY - dY, eX - dX); - var serpentine = 1 / (r + 1); + var serpentine = 1 / (r+1); var meandr = serpentine + 0.3 + Math.random() * 0.3 * rndFactor; - if (Math.random() > 0.5) { side *= -1 }; + if (Math.random() > 0.5) {side *= -1}; var dist = Math.hypot(eX - dX, eY - dY); // if dist is big or river is small add 2 extra points if (dist > 8 || (dist > 4 && dataRiver.length < 6)) { @@ -1956,11 +1953,11 @@ function fantasyMap() { var enY = (dY + eY * 2) / 3; stX += -Math.sin(angle) * meandr * side; stY += Math.cos(angle) * meandr * side; - if (Math.random() > 0.8) { side *= -1 }; + if (Math.random() > 0.8) {side *= -1}; enX += Math.sin(angle) * meandr * side; enY += -Math.cos(angle) * meandr * side; riverAmended.push([stX, stY], [enX, enY]); - // if dist is medium or river is small add 1 extra point + // if dist is medium or river is small add 1 extra point } else if (dist > 4 || dataRiver.length < 6) { var scX = (dX + eX) / 2; var scY = (dY + eY) / 2; @@ -1975,108 +1972,108 @@ function fantasyMap() { // draw river polygon using arrpoximation function drawRiver(points, width, increment) { - lineGen.curve(d3.curveCatmullRom.alpha(0.1)); - var extraOffset = 0.03; // start offset to make river source visible - width = width || 1; // river width modifier - increment = increment || 1; // river bed widening modifier - var riverLength = 0; - points.map(function (p, i) { - if (i === 0) { return 0; } - riverLength += Math.hypot(p[0] - points[i - 1][0], p[1] - points[i - 1][1]); - }); - var widening = rn((1000 + (riverLength * 30)) * increment); - var riverPointsLeft = [], riverPointsRight = []; - var last = points.length - 1; - var factor = riverLength / points.length; + lineGen.curve(d3.curveCatmullRom.alpha(0.1)); + var extraOffset = 0.03; // start offset to make river source visible + width = width || 1; // river width modifier + increment = increment || 1; // river bed widening modifier + var riverLength = 0; + points.map(function(p, i) { + if (i === 0) {return 0;} + riverLength += Math.hypot(p[0] - points[i-1][0], p[1] - points[i-1][1]); + }); + var widening = rn((1000 + (riverLength * 30)) * increment); + var riverPointsLeft = [], riverPointsRight = []; + var last = points.length - 1; + var factor = riverLength / points.length; - // first point - var x = points[0][0], y = points[0][1], c; - var angle = Math.atan2(y - points[1][1], x - points[1][0]); - var xLeft = x + -Math.sin(angle) * extraOffset, yLeft = y + Math.cos(angle) * extraOffset; - riverPointsLeft.push({ scX: xLeft, scY: yLeft }); - var xRight = x + Math.sin(angle) * extraOffset, yRight = y + -Math.cos(angle) * extraOffset; - riverPointsRight.unshift({ scX: xRight, scY: yRight }); + // first point + var x = points[0][0], y = points[0][1], c; + var angle = Math.atan2(y - points[1][1], x - points[1][0]); + var xLeft = x + -Math.sin(angle) * extraOffset, yLeft = y + Math.cos(angle) * extraOffset; + riverPointsLeft.push({scX:xLeft, scY:yLeft}); + var xRight = x + Math.sin(angle) * extraOffset, yRight = y + -Math.cos(angle) * extraOffset; + riverPointsRight.unshift({scX:xRight, scY:yRight}); - // middle points - for (let p = 1; p < last; p++) { - x = points[p][0], y = points[p][1], c = points[p][2]; - if (c) { extraOffset += Math.atan(c * 10 / widening); } // confluence - var xPrev = points[p - 1][0], yPrev = points[p - 1][1]; - var xNext = points[p + 1][0], yNext = points[p + 1][1]; - angle = Math.atan2(yPrev - yNext, xPrev - xNext); - var offset = (Math.atan(Math.pow(p * factor, 2) / widening) / 2 * width) + extraOffset; + // middle points + for (let p = 1; p < last; p ++) { + x = points[p][0], y = points[p][1], c = points[p][2]; + if (c) {extraOffset += Math.atan(c * 10 / widening);} // confluence + var xPrev = points[p-1][0], yPrev = points[p-1][1]; + var xNext = points[p+1][0], yNext = points[p+1][1]; + angle = Math.atan2(yPrev - yNext, xPrev - xNext); + var offset = (Math.atan(Math.pow(p * factor, 2) / widening) / 2 * width) + extraOffset; + xLeft = x + -Math.sin(angle) * offset, yLeft = y + Math.cos(angle) * offset; + riverPointsLeft.push({scX:xLeft, scY:yLeft}); + xRight = x + Math.sin(angle) * offset, yRight = y + -Math.cos(angle) * offset; + riverPointsRight.unshift({scX:xRight, scY:yRight}); + } + + // end point + x = points[last][0], y = points[last][1], c = points[last][2]; + if (c) {extraOffset += Math.atan(c * 10 / widening);} // confluence + angle = Math.atan2(points[last-1][1] - y, points[last-1][0] - x); xLeft = x + -Math.sin(angle) * offset, yLeft = y + Math.cos(angle) * offset; - riverPointsLeft.push({ scX: xLeft, scY: yLeft }); + riverPointsLeft.push({scX:xLeft, scY:yLeft}); xRight = x + Math.sin(angle) * offset, yRight = y + -Math.cos(angle) * offset; - riverPointsRight.unshift({ scX: xRight, scY: yRight }); - } + riverPointsRight.unshift({scX:xRight, scY:yRight}); - // end point - x = points[last][0], y = points[last][1], c = points[last][2]; - if (c) { extraOffset += Math.atan(c * 10 / widening); } // confluence - angle = Math.atan2(points[last - 1][1] - y, points[last - 1][0] - x); - xLeft = x + -Math.sin(angle) * offset, yLeft = y + Math.cos(angle) * offset; - riverPointsLeft.push({ scX: xLeft, scY: yLeft }); - xRight = x + Math.sin(angle) * offset, yRight = y + -Math.cos(angle) * offset; - riverPointsRight.unshift({ scX: xRight, scY: yRight }); - - // generate path and return - var right = lineGen(riverPointsRight); - var left = lineGen(riverPointsLeft); - left = left.substring(left.indexOf("C")); - return round(right + left, 2); + // generate path and return + var right = lineGen(riverPointsRight); + var left = lineGen(riverPointsLeft); + left = left.substring(left.indexOf("C")); + return round(right + left, 2); } // draw river polygon with best quality function drawRiverSlow(points, width, increment) { - lineGen.curve(d3.curveCatmullRom.alpha(0.1)); - width = width || 1; - var extraOffset = 0.02 * width; - increment = increment || 1; - var riverPoints = points.map(function (p) { return { scX: p[0], scY: p[1] }; }); - var river = defs.append("path").attr("d", lineGen(riverPoints)); - var riverLength = river.node().getTotalLength(); - var widening = rn((1000 + (riverLength * 30)) * increment); - var riverPointsLeft = [], riverPointsRight = []; + lineGen.curve(d3.curveCatmullRom.alpha(0.1)); + width = width || 1; + var extraOffset = 0.02 * width; + increment = increment || 1; + var riverPoints = points.map(function(p) {return {scX: p[0], scY: p[1]};}); + var river = defs.append("path").attr("d", lineGen(riverPoints)); + var riverLength = river.node().getTotalLength(); + var widening = rn((1000 + (riverLength * 30)) * increment); + var riverPointsLeft = [], riverPointsRight = []; - for (let l = 0; l < riverLength; l++) { - var point = river.node().getPointAtLength(l); - var from = river.node().getPointAtLength(l - 0.1); - var to = river.node().getPointAtLength(l + 0.1); - var angle = Math.atan2(from.y - to.y, from.x - to.x); - var offset = (Math.atan(Math.pow(l, 2) / widening) / 2 * width) + extraOffset; + for (let l = 0; l < riverLength; l++) { + var point = river.node().getPointAtLength(l); + var from = river.node().getPointAtLength(l - 0.1); + var to = river.node().getPointAtLength(l + 0.1); + var angle = Math.atan2(from.y - to.y, from.x - to.x); + var offset = (Math.atan(Math.pow(l, 2) / widening) / 2 * width) + extraOffset; + var xLeft = point.x + -Math.sin(angle) * offset; + var yLeft = point.y + Math.cos(angle) * offset; + riverPointsLeft.push({scX:xLeft, scY:yLeft}); + var xRight = point.x + Math.sin(angle) * offset; + var yRight = point.y + -Math.cos(angle) * offset; + riverPointsRight.unshift({scX:xRight, scY:yRight}); + } + + var point = river.node().getPointAtLength(riverLength); + var from = river.node().getPointAtLength(riverLength - 0.1); + var angle = Math.atan2(from.y - point.y, from.x - point.x); + var offset = (Math.atan(Math.pow(riverLength, 2) / widening) / 2 * width) + extraOffset; var xLeft = point.x + -Math.sin(angle) * offset; var yLeft = point.y + Math.cos(angle) * offset; - riverPointsLeft.push({ scX: xLeft, scY: yLeft }); + riverPointsLeft.push({scX:xLeft, scY:yLeft}); var xRight = point.x + Math.sin(angle) * offset; var yRight = point.y + -Math.cos(angle) * offset; - riverPointsRight.unshift({ scX: xRight, scY: yRight }); - } + riverPointsRight.unshift({scX:xRight, scY:yRight}); - var point = river.node().getPointAtLength(riverLength); - var from = river.node().getPointAtLength(riverLength - 0.1); - var angle = Math.atan2(from.y - point.y, from.x - point.x); - var offset = (Math.atan(Math.pow(riverLength, 2) / widening) / 2 * width) + extraOffset; - var xLeft = point.x + -Math.sin(angle) * offset; - var yLeft = point.y + Math.cos(angle) * offset; - riverPointsLeft.push({ scX: xLeft, scY: yLeft }); - var xRight = point.x + Math.sin(angle) * offset; - var yRight = point.y + -Math.cos(angle) * offset; - riverPointsRight.unshift({ scX: xRight, scY: yRight }); - - river.remove(); - // generate path and return - var right = lineGen(riverPointsRight); - var left = lineGen(riverPointsLeft); - left = left.substring(left.indexOf("C")); - return round(right + left, 2); + river.remove(); + // generate path and return + var right = lineGen(riverPointsRight); + var left = lineGen(riverPointsLeft); + left = left.substring(left.indexOf("C")); + return round(right + left, 2); } // add lakes on depressed points on river course function addLakes() { console.time('addLakes'); let smallLakes = 0; - for (let i = 0; i < land.length; i++) { + for (let i=0; i < land.length; i++) { // elavate all big lakes if (land[i].lake === 1) { land[i].height = 0.19; @@ -2091,7 +2088,7 @@ function fantasyMap() { smallLakes++; } else { land[i].lake = undefined; - land[i].neighbors.forEach(function (n) { + land[i].neighbors.forEach(function(n) { if (cells[n].lake !== 1 && cells[n].river !== undefined) { cells[n].lake = 2; cells[n].height = 0.19; @@ -2107,7 +2104,7 @@ function fantasyMap() { } // mark small lakes - let unmarked = $.grep(land, function (e) { return e.fn === -1 }); + let unmarked = $.grep(land, function(e) {return e.fn === -1}); while (unmarked.length) { let fn = -1, queue = [unmarked[0].index], lakeCells = []; unmarked[0].session = "addLakes"; @@ -2115,7 +2112,7 @@ function fantasyMap() { const q = queue.pop(); lakeCells.push(q); if (cells[q].fn !== -1) fn = cells[q].fn; - cells[q].neighbors.forEach(function (e) { + cells[q].neighbors.forEach(function(e) { if (cells[e].lake && cells[e].session !== "addLakes") { cells[e].session = "addLakes"; queue.push(e); @@ -2124,18 +2121,18 @@ function fantasyMap() { } if (fn === -1) { fn = features.length; - features.push({ i: fn, land: false, border: false }); + features.push({i: fn, land: false, border: false}); } - lakeCells.forEach(function (c) { cells[c].fn = fn; }); - unmarked = $.grep(land, function (e) { return e.fn === -1 }); + lakeCells.forEach(function(c) {cells[c].fn = fn;}); + unmarked = $.grep(land, function(e) {return e.fn === -1}); } - land = $.grep(cells, function (e) { return e.height >= 0.2; }); + land = $.grep(cells, function(e) {return e.height >= 0.2;}); console.timeEnd('addLakes'); } function editRiver() { - if (customization) { return; } + if (customization) {return;} if (elSelected) { const self = d3.select(this).attr("id") === elSelected.attr("id"); const point = d3.mouse(this); @@ -2164,9 +2161,9 @@ function fantasyMap() { $("#riverEditor").dialog({ title: "Edit River", minHeight: 30, width: "auto", resizable: false, - position: { my: "center top+20", at: "top", of: d3.event }, - close: function () { - if ($("#riverNew").hasClass('pressed')) { completeNewRiver(); } + position: {my: "center top+20", at: "top", of: d3.event}, + close: function() { + if ($("#riverNew").hasClass('pressed')) {completeNewRiver();} unselect(); } }); @@ -2175,28 +2172,28 @@ function fantasyMap() { .attr("transform", elSelected.attr("transform")); riverDrawPoints(); - if (modules.editRiver) { return; } + if (modules.editRiver) {return;} modules.editRiver = true; function riverAddControlPoint(point) { let dists = []; - debug.select(".controlPoints").selectAll("circle").each(function () { + debug.select(".controlPoints").selectAll("circle").each(function() { const x = +d3.select(this).attr("cx"); const y = +d3.select(this).attr("cy"); dists.push(Math.hypot(point[0] - x, point[1] - y)); }); let index = dists.length; if (dists.length > 1) { - const sorted = dists.slice(0).sort(function (a, b) { return a - b; }); + const sorted = dists.slice(0).sort(function(a, b) {return a-b;}); const closest = dists.indexOf(sorted[0]); const next = dists.indexOf(sorted[1]); - if (closest <= next) { index = closest + 1; } else { index = next + 1; } + if (closest <= next) {index = closest+1;} else {index = next+1;} } const before = ":nth-child(" + (index + 1) + ")"; debug.select(".controlPoints").insert("circle", before) .attr("cx", point[0]).attr("cy", point[1]).attr("r", 0.35) .call(d3.drag().on("drag", riverPointDrag)) - .on("click", function (d) { + .on("click", function(d) { $(this).remove(); redrawRiver(); }); @@ -2209,7 +2206,7 @@ function fantasyMap() { const l = node.getTotalLength() / 2; const parts = (l / 5) >> 0; // number of points let inc = l / parts; // increment - if (inc === Infinity) { inc = l; } // 2 control points for short rivers + if (inc === Infinity) {inc = l;} // 2 control points for short rivers // draw control points for (let i = l, c = l; i > 0; i -= inc, c += inc) { const p1 = node.getPointAtLength(i); @@ -2228,7 +2225,7 @@ function fantasyMap() { debug.select(".controlPoints").append("circle") .attr("cx", point[0]).attr("cy", point[1]).attr("r", 0.35) .call(d3.drag().on("drag", riverPointDrag)) - .on("click", function (d) { + .on("click", function(d) { $(this).remove(); redrawRiver(); }); @@ -2242,9 +2239,9 @@ function fantasyMap() { function riverDrag() { const x = d3.event.x, y = d3.event.y; const tr = parseTransform(elSelected.attr("transform")); - d3.event.on("drag", function () { + d3.event.on("drag", function() { let xc = d3.event.x, yc = d3.event.y; - let transform = `translate(${(+tr[0] + xc - x)},${(+tr[1] + yc - y)}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; + let transform = `translate(${(+tr[0]+xc-x)},${(+tr[1]+yc-y)}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; elSelected.attr("transform", transform); debug.select(".controlPoints").attr("transform", transform); }); @@ -2252,7 +2249,7 @@ function fantasyMap() { function redrawRiver() { let points = []; - debug.select(".controlPoints").selectAll("circle").each(function () { + debug.select(".controlPoints").selectAll("circle").each(function() { const el = d3.select(this); points.push([+el.attr("cx"), +el.attr("cy")]); }); @@ -2262,20 +2259,20 @@ function fantasyMap() { elSelected.attr("d", d); } - $("#riverWidthInput, #riverIncrement").change(function () { + $("#riverWidthInput, #riverIncrement").change(function() { const width = +riverWidthInput.value; const increment = +riverIncrement.value; elSelected.attr("data-width", width).attr("data-increment", increment); redrawRiver(); }); - $("#riverRegenerate").click(function () { + $("#riverRegenerate").click(function() { let points = [], amended = [], x, y, p1, p2; const node = elSelected.node(); const l = node.getTotalLength() / 2; const parts = (l / 8) >> 0; // number of points let inc = l / parts; // increment - if (inc === Infinity) { inc = l; } // 2 control points for short rivers + if (inc === Infinity) {inc = l;} // 2 control points for short rivers for (let i = l, e = l; i > 0; i -= inc, e += inc) { p1 = node.getPointAtLength(i); p2 = node.getPointAtLength(e); @@ -2294,10 +2291,10 @@ function fantasyMap() { amended.push([x, y]); // add additional semi-random point if (i + 1 < points.length) { - const x2 = points[i + 1][0], y2 = points[i + 1][1]; + const x2 = points[i+1][0], y2 = points[i+1][1]; let side = Math.random() > 0.5 ? 1 : -1; const angle = Math.atan2(y2 - y, x2 - x); - const serpentine = 2 / (i + 1); + const serpentine = 2 / (i+1); const meandr = serpentine + 0.3 + Math.random() * rndFactor; x = (x + x2) / 2, y = (y + y2) / 2; x += -Math.sin(angle) * meandr * side; @@ -2313,20 +2310,20 @@ function fantasyMap() { const d = drawRiverSlow(amended, width, increment); elSelected.attr("d", d).attr("data-width", width).attr("data-increment", increment); debug.select(".controlPoints").selectAll("*").remove(); - amended.map(function (p) { addRiverPoint(p); }); + amended.map(function(p) {addRiverPoint(p);}); }); - $("#riverAngle").change(function () { + $("#riverAngle").change(function() { const tr = parseTransform(elSelected.attr("transform")); riverAngleValue.innerHTML = Math.abs(+this.value) + "°"; var c = elSelected.node().getBBox(); const angle = +this.value, scale = +tr[5]; - const transform = `translate(${tr[0]},${tr[1]}) rotate(${angle} ${(c.x + c.width / 2) * scale} ${(c.y + c.height / 2) * scale}) scale(${scale})`; + const transform = `translate(${tr[0]},${tr[1]}) rotate(${angle} ${(c.x+c.width/2)*scale} ${(c.y+c.height/2)*scale}) scale(${scale})`; elSelected.attr("transform", transform); debug.select(".controlPoints").attr("transform", transform); }); - $("#riverReset").click(function () { + $("#riverReset").click(function() { elSelected.attr("transform", ""); debug.select(".controlPoints").attr("transform", ""); riverAngle.value = 0; @@ -2334,21 +2331,21 @@ function fantasyMap() { riverScale.value = 1; }); - $("#riverScale").change(function () { + $("#riverScale").change(function() { const tr = parseTransform(elSelected.attr("transform")); const scaleOld = +tr[5], scale = +this.value; var c = elSelected.node().getBBox(); const cx = c.x + c.width / 2, cy = c.y + c.height / 2; const trX = +tr[0] + cx * (scaleOld - scale); const trY = +tr[1] + cy * (scaleOld - scale); - const scX = +tr[3] * scale / scaleOld; - const scY = +tr[4] * scale / scaleOld; + const scX = +tr[3] * scale/scaleOld; + const scY = +tr[4] * scale/scaleOld; const transform = `translate(${trX},${trY}) rotate(${tr[2]} ${scX} ${scY}) scale(${scale})`; elSelected.attr("transform", transform); debug.select(".controlPoints").attr("transform", transform); }); - $("#riverNew").click(function () { + $("#riverNew").click(function() { if ($(this).hasClass('pressed')) { completeNewRiver(); } else { @@ -2366,7 +2363,7 @@ function fantasyMap() { addRiverPoint([point[0], point[1]]); if (elSelected.attr("data-river") !== "new") { const id = +$("#rivers > path").last().attr("id").slice(5) + 1; - elSelected = rivers.append("path").attr("data-river", "new").attr("id", "river" + id) + elSelected = rivers.append("path").attr("data-river", "new").attr("id", "river"+id) .attr("data-width", 2).attr("data-increment", 1).on("click", completeNewRiver); } else { redrawRiver(); @@ -2381,44 +2378,43 @@ function fantasyMap() { elSelected.attr("data-river", ""); elSelected.call(d3.drag().on("start", riverDrag)).on("click", editRiver); const river = +elSelected.attr("id").slice(5); - debug.select(".controlPoints").selectAll("circle").each(function () { + debug.select(".controlPoints").selectAll("circle").each(function() { const x = +d3.select(this).attr("cx"); const y = +d3.select(this).attr("cy"); const cell = diagram.find(x, y, 3); - if (!cell) { return; } - if (cells[cell.index].river === undefined) { cells[cell.index].river = r; } + if (!cell) {return;} + if (cells[cell.index].river === undefined) {cells[cell.index].river = r;} }); } } - $("#riverCopy").click(function () { + $("#riverCopy").click(function() { const tr = parseTransform(elSelected.attr("transform")); const d = elSelected.attr("d"); let x = 2, y = 2; - let transform = `translate(${tr[0] - x},${tr[1] - y}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; + let transform = `translate(${tr[0]-x},${tr[1]-y}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; while (rivers.selectAll("[transform='" + transform + "'][d='" + d + "']").size() > 0) { x += 2; y += 2; - transform = `translate(${tr[0] - x},${tr[1] - y}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; + transform = `translate(${tr[0]-x},${tr[1]-y}) rotate(${tr[2]} ${tr[3]} ${tr[4]}) scale(${tr[5]})`; } const river = +$("#rivers > path").last().attr("id").slice(5) + 1; rivers.append("path").attr("d", d) .attr("transform", transform) - .attr("id", "river" + river).on("click", editRiver) + .attr("id", "river"+river).on("click", editRiver) .attr("data-width", elSelected.attr("data-width")) .attr("data-increment", elSelected.attr("data-increment")); unselect(); }); - $("#riverRemove").click(function () { + $("#riverRemove").click(function() { alertMessage.innerHTML = `Are you sure you want to remove the river?`; - $("#alert").dialog({ - resizable: false, title: "Remove river", + $("#alert").dialog({resizable: false, title: "Remove river", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); const river = +elSelected.attr("id").slice(5); const avPrec = rn(precInput.value / Math.sqrt(cells.length), 2); - land.map(function (l) { + land.map(function(l) { if (l.river === river) { l.river = undefined; i.flux = avPrec; @@ -2428,7 +2424,7 @@ function fantasyMap() { unselect(); $("#riverEditor").dialog("close"); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }) }); @@ -2446,18 +2442,18 @@ function fantasyMap() { function parseTransform(string) { // [translateX,translateY,rotateDeg,rotateX,rotateY,scale] - if (!string) { return [0, 0, 0, 0, 0, 1]; } - var a = string.replace(/[a-z()]/g, "").replace(/[ ]/g, ",").split(","); + if (!string) {return [0,0,0,0,0,1];} + var 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]; } function editRoute() { - if (customization) { return; } + if (customization) {return;} if (elSelected) { const self = d3.select(this).attr("id") === elSelected.attr("id"); const point = d3.mouse(this); if (elSelected.attr("data-route") === "new") { - addRoutePoint({ x: point[0], y: point[1] }); + addRoutePoint({x:point[0], y:point[1]}); completeNewRoute(); return; } else if (self) { @@ -2481,8 +2477,8 @@ function fantasyMap() { $("#routeEditor").dialog({ title: "Edit Route", minHeight: 30, width: "auto", resizable: false, - position: { my: "center top+20", at: "top", of: d3.event }, - close: function () { + position: {my: "center top+20", at: "top", of: d3.event}, + close: function() { if ($("#addRoute").hasClass('pressed')) completeNewRoute(); if ($("#routeSplit").hasClass('pressed')) $("#routeSplit").removeClass('pressed'); unselect(); @@ -2490,28 +2486,28 @@ function fantasyMap() { }); } - if (modules.editRoute) { return; } + if (modules.editRoute) {return;} modules.editRoute = true; function routeAddControlPoint(point) { let dists = []; - debug.select(".controlPoints").selectAll("circle").each(function () { + debug.select(".controlPoints").selectAll("circle").each(function() { const x = +d3.select(this).attr("cx"); const y = +d3.select(this).attr("cy"); dists.push(Math.hypot(point[0] - x, point[1] - y)); }); let index = dists.length; if (dists.length > 1) { - const sorted = dists.slice(0).sort(function (a, b) { return a - b; }); + const sorted = dists.slice(0).sort(function(a, b) {return a-b;}); const closest = dists.indexOf(sorted[0]); const next = dists.indexOf(sorted[1]); - if (closest <= next) { index = closest + 1; } else { index = next + 1; } + if (closest <= next) {index = closest+1;} else {index = next+1;} } const before = ":nth-child(" + (index + 1) + ")"; debug.select(".controlPoints").insert("circle", before) .attr("cx", point[0]).attr("cy", point[1]).attr("r", 0.35) .call(d3.drag().on("drag", routePointDrag)) - .on("click", function (d) { + .on("click", function(d) { $(this).remove(); routeRedraw(); }); @@ -2523,7 +2519,7 @@ function fantasyMap() { const l = node.getTotalLength(); const parts = (l / 5) >> 0; // number of points let inc = l / parts; // increment - if (inc === Infinity) { inc = l; } // 2 control points for short routes + if (inc === Infinity) {inc = l;} // 2 control points for short routes // draw control points for (let i = 0; i <= l; i += inc) { const p = node.getPointAtLength(i); @@ -2540,7 +2536,7 @@ function fantasyMap() { controlPoints.append("circle") .attr("cx", point.x).attr("cy", point.y).attr("r", 0.35) .call(d3.drag().on("drag", routePointDrag)) - .on("click", function (d) { + .on("click", function(d) { if ($("#routeSplit").hasClass('pressed')) { routeSplitInPoint(this); } else { @@ -2557,9 +2553,9 @@ function fantasyMap() { function routeRedraw() { let points = []; - debug.select(".controlPoints").selectAll("circle").each(function () { + debug.select(".controlPoints").selectAll("circle").each(function() { var el = d3.select(this); - points.push({ scX: +el.attr("cx"), scY: +el.attr("cy") }); + points.push({scX: +el.attr("cx"), scY: +el.attr("cy")}); }); lineGen.curve(d3.curveCatmullRom.alpha(0.1)); elSelected.attr("d", lineGen(points)); @@ -2578,8 +2574,8 @@ function fantasyMap() { if (height < 0.2) routeType = "searoutes"; if (routeType === "searoutes" && height >= 0.2) routeType = "roads"; } - const group = routes.select("#" + routeType); - addRoutePoint({ x, y }); + const group = routes.select("#"+routeType); + addRoutePoint({x, y}); if (!elSelected || elSelected.attr("data-route") !== "new") { const id = routeType + "" + group.selectAll("*").size(); elSelected = group.append("path").attr("data-route", "new").attr("id", id).on("click", editRoute); @@ -2588,8 +2584,8 @@ function fantasyMap() { $("#routeEditor").dialog({ title: "Edit Route", minHeight: 30, width: "auto", resizable: false, - position: { my: "center top+20", at: "top", of: d3.event }, - close: function () { + position: {my: "center top+20", at: "top", of: d3.event}, + close: function() { if ($("#addRoute").hasClass('pressed')) completeNewRoute(); if ($("#routeSplit").hasClass('pressed')) $("#routeSplit").removeClass('pressed'); unselect(); @@ -2610,16 +2606,16 @@ function fantasyMap() { const node = elSelected.node(); const l = node.getTotalLength(); let pathCells = []; - for (let i = 0; i <= l; i++) { + for (let i = 0; i <= l; i ++) { const p = node.getPointAtLength(i); const cell = diagram.find(p.x, p.y); - if (!cell) { return; } + if (!cell) {return;} pathCells.push(cell.index); } const uniqueCells = [...new Set(pathCells)]; - uniqueCells.map(function (c) { - if (cells[c].path !== undefined) { cells[c].path += 1; } - else { cells[c].path = 1; } + uniqueCells.map(function(c) { + if (cells[c].path !== undefined) {cells[c].path += 1;} + else {cells[c].path = 1;} }); } tip("", true); @@ -2629,9 +2625,9 @@ function fantasyMap() { const group = d3.select(elSelected.node().parentNode); const type = group.attr("data-type"); routeGroup.innerHTML = ""; - routes.selectAll("g").each(function (d) { + routes.selectAll("g").each(function(d) { const el = d3.select(this); - if (el.attr("data-type") !== type) { return; } + if (el.attr("data-type") !== type) {return;} const opt = document.createElement("option"); opt.value = opt.innerHTML = el.attr("id"); routeGroup.add(opt); @@ -2643,12 +2639,12 @@ function fantasyMap() { $("#routeSplit").removeClass('pressed'); const points1 = [], points2 = []; let points = points1; - debug.select(".controlPoints").selectAll("circle").each(function () { + debug.select(".controlPoints").selectAll("circle").each(function() { const el = d3.select(this); - points.push({ scX: +el.attr("cx"), scY: +el.attr("cy") }); + points.push({scX: +el.attr("cx"), scY: +el.attr("cy")}); if (this === clicked) { points = points2; - points.push({ scX: +el.attr("cx"), scY: +el.attr("cy") }); + points.push({scX: +el.attr("cx"), scY: +el.attr("cy")}); } el.remove(); }); @@ -2659,11 +2655,11 @@ function fantasyMap() { routeDrawPoints(); } - $("#routeGroup").change(function () { - $(elSelected.node()).detach().appendTo($("#" + this.value)); + $("#routeGroup").change(function() { + $(elSelected.node()).detach().appendTo($("#"+this.value)); }); - $("#routeNew").click(function () { + $("#routeNew").click(function() { if ($(this).hasClass('pressed')) { completeNewRoute(); } else { @@ -2676,17 +2672,16 @@ function fantasyMap() { } }); - $("#routeRemove").click(function () { + $("#routeRemove").click(function() { alertMessage.innerHTML = `Are you sure you want to remove the route?`; - $("#alert").dialog({ - resizable: false, title: "Remove route", + $("#alert").dialog({resizable: false, title: "Remove route", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); elSelected.remove(); $("#routeEditor").dialog("close"); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }) }); @@ -2712,14 +2707,14 @@ function fantasyMap() { $("#iconEditor").dialog({ title: "Edit icon: " + group.attr("id"), minHeight: 30, width: "auto", resizable: false, - position: { my: "center top+20", at: "top", of: d3.event }, + position: {my: "center top+20", at: "top", of: d3.event}, close: unselect }); - if (modules.editIcon) { return; } + if (modules.editIcon) {return;} modules.editIcon = true; - $("#iconGroups").click(function () { + $("#iconGroups").click(function() { $("#iconEditor > button").not(this).toggle(); $("#iconGroupsSelection").toggle(); }); @@ -2727,7 +2722,7 @@ function fantasyMap() { function iconUpdateGroups() { iconGroup.innerHTML = ""; const anchor = group.attr("id").includes("anchor"); - icons.selectAll("g").each(function (d) { + icons.selectAll("g").each(function(d) { const id = d3.select(this).attr("id"); if (id === "burgs") return; if (!anchor && id.includes("anchor")) return; @@ -2738,28 +2733,28 @@ function fantasyMap() { }); } - $("#iconGroup").change(function () { + $("#iconGroup").change(function() { const newGroup = this.value; - const to = $("#icons > #" + newGroup); + const to = $("#icons > #"+newGroup); $(elSelected.node()).detach().appendTo(to); }); - $("#iconCopy").click(function () { + $("#iconCopy").click(function() { const group = d3.select(elSelected.node().parentNode); const copy = elSelected.node().cloneNode(); copy.removeAttribute("data-id"); // remove assignment to burg if any const tr = parseTransform(copy.getAttribute("transform")); const shift = 10 / Math.sqrt(scale); - let transform = "translate(" + rn(tr[0] - shift, 1) + "," + rn(tr[1] - shift, 1) + ")"; - for (let i = 2; group.selectAll("[transform='" + transform + "']").size() > 0; i++) { - transform = "translate(" + rn(tr[0] - shift * i, 1) + "," + rn(tr[1] - shift * i, 1) + ")"; + let transform = "translate(" + rn(tr[0] - shift, 1) + "," + rn(tr[1] - shift, 1) + ")"; + for (let i=2; group.selectAll("[transform='" + transform + "']").size() > 0; i++) { + transform = "translate(" + rn(tr[0] - shift * i, 1) + "," + rn(tr[1] - shift * i, 1) + ")"; } copy.setAttribute("transform", transform); group.node().insertBefore(copy, null); copy.addEventListener("click", editIcon); }); - $("#iconRemoveGroup").click(function () { + $("#iconRemoveGroup").click(function() { const group = d3.select(elSelected.node().parentNode); const count = group.selectAll("*").size(); if (count < 2) { @@ -2769,62 +2764,60 @@ function fantasyMap() { } const message = "Are you sure you want to remove all '" + iconGroup.value + "' icons (" + count + ")?"; alertMessage.innerHTML = message; - $("#alert").dialog({ - resizable: false, title: "Remove icon group", + $("#alert").dialog({resizable: false, title: "Remove icon group", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); group.remove(); $("#iconEditor").dialog("close"); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }); }); - $("#iconColors").click(function () { + $("#iconColors").click(function() { $("#iconEditor > button").not(this).toggle(); $("#iconColorsSection").toggle(); }); - $("#iconFillColor").change(function () { + $("#iconFillColor").change(function() { const group = d3.select(elSelected.node().parentNode); group.attr("fill", this.value); }); - $("#iconStrokeColor").change(function () { + $("#iconStrokeColor").change(function() { const group = d3.select(elSelected.node().parentNode); group.attr("stroke", this.value); }); - $("#iconSetSize").click(function () { + $("#iconSetSize").click(function() { $("#iconEditor > button").not(this).toggle(); $("#iconSizeSection").toggle(); }); - $("#iconSize").change(function () { + $("#iconSize").change(function() { const group = d3.select(elSelected.node().parentNode); const size = +this.value group.attr("size", size); - group.selectAll("*").each(function () { d3.select(this).attr("width", size).attr("height", size) }); + group.selectAll("*").each(function() {d3.select(this).attr("width", size).attr("height", size)}); }); - $("#iconStrokeWidth").change(function () { + $("#iconStrokeWidth").change(function() { const group = d3.select(elSelected.node().parentNode); group.attr("stroke-width", this.value); }); - $("#iconRemove").click(function () { + $("#iconRemove").click(function() { alertMessage.innerHTML = `Are you sure you want to remove the icon?`; - $("#alert").dialog({ - resizable: false, title: "Remove icon", + $("#alert").dialog({resizable: false, title: "Remove icon", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); elSelected.remove(); $("#iconEditor").dialog("close"); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }) }); @@ -2843,19 +2836,19 @@ function fantasyMap() { $("#reliefEditor").dialog({ title: "Edit relief icon", minHeight: 30, width: "auto", resizable: false, - position: { my: "center top+40", at: "top", of: d3.event }, + position: {my: "center top+40", at: "top", of: d3.event}, close: unselect }); - if (modules.editReliefIcon) { return; } + if (modules.editReliefIcon) {return;} modules.editReliefIcon = true; - $("#reliefGroups").click(function () { + $("#reliefGroups").click(function() { $("#reliefEditor > button").not(this).toggle(); $("#reliefGroupsSelection").toggle(); }); - $("#reliefGroup").change(function () { + $("#reliefGroup").change(function() { const type = this.value; const bbox = elSelected.node().getBBox(); const cx = bbox.x; @@ -2867,26 +2860,26 @@ function fantasyMap() { elSelected.call(d3.drag().on("start", elementDrag)); }); - $("#reliefCopy").click(function () { + $("#reliefCopy").click(function() { const group = d3.select(elSelected.node().parentNode); const copy = elSelected.node().cloneNode(true); const tr = parseTransform(copy.getAttribute("transform")); const shift = 10 / Math.sqrt(scale); - let transform = "translate(" + rn(tr[0] - shift, 1) + "," + rn(tr[1] - shift, 1) + ")"; - for (let i = 2; group.selectAll("[transform='" + transform + "']").size() > 0; i++) { - transform = "translate(" + rn(tr[0] - shift * i, 1) + "," + rn(tr[1] - shift * i, 1) + ")"; + let transform = "translate(" + rn(tr[0] - shift, 1) + "," + rn(tr[1] - shift, 1) + ")"; + for (let i=2; group.selectAll("[transform='" + transform + "']").size() > 0; i++) { + transform = "translate(" + rn(tr[0] - shift * i, 1) + "," + rn(tr[1] - shift * i, 1) + ")"; } copy.setAttribute("transform", transform); group.node().insertBefore(copy, null); copy.addEventListener("click", editReliefIcon); }); - $("#reliefAddfromEditor").click(function () { + $("#reliefAddfromEditor").click(function() { clickToAdd(); // to load on click event function $("#addRelief").click(); }); - $("#reliefRemoveGroup").click(function () { + $("#reliefRemoveGroup").click(function() { const group = d3.select(elSelected.node().parentNode); const count = group.selectAll("*").size(); if (count < 2) { @@ -2896,40 +2889,38 @@ function fantasyMap() { } const message = "Are you sure you want to remove all '" + reliefGroup.value + "' icons (" + count + ")?"; alertMessage.innerHTML = message; - $("#alert").dialog({ - resizable: false, title: "Remove all icons within group", + $("#alert").dialog({resizable: false, title: "Remove all icons within group", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); group.selectAll("*").remove(); $("#reliefEditor").dialog("close"); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }); }); - $("#reliefRemove").click(function () { + $("#reliefRemove").click(function() { alertMessage.innerHTML = `Are you sure you want to remove the icon?`; - $("#alert").dialog({ - resizable: false, title: "Remove relief icon", + $("#alert").dialog({resizable: false, title: "Remove relief icon", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); elSelected.remove(); $("#reliefEditor").dialog("close"); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }) }); } function editBurg() { - if (customization) { return; } + if (customization) {return;} if (elSelected) { const self = d3.select(this).attr("data-id") === elSelected.attr("data-id"); - if (self) { return; } + if (self) {return;} } closeDialogs("#burgEditor, .stable"); @@ -2940,8 +2931,8 @@ function fantasyMap() { // update Burg details const type = elSelected.node().parentNode.id; - const labelGroup = burgLabels.select("#" + type); - const iconGroup = burgIcons.select("#" + type); + const labelGroup = burgLabels.select("#"+type); + const iconGroup = burgIcons.select("#"+type); burgNameInput.value = manors[id].name; updateBurgsGroupOptions(); burgSelectGroup.value = labelGroup.attr("id"); @@ -2975,8 +2966,8 @@ function fantasyMap() { $("#burgEditor").dialog({ title: "Edit Burg: " + manors[id].name, minHeight: 30, width: "auto", resizable: false, - position: { my: "center top+40", at: "top", of: d3.event }, - close: function () { + position: {my: "center top+40", at: "top", of: d3.event}, + close: function() { d3.selectAll("[data-id='" + id + "']").call(d3.drag().on("drag", null)).classed("draggable", false); elSelected = null; } @@ -2989,14 +2980,14 @@ function fantasyMap() { function updateBurgsGroupOptions() { burgSelectGroup.innerHTML = ""; - burgIcons.selectAll("g").each(function (d) { + burgIcons.selectAll("g").each(function(d) { var opt = document.createElement("option"); opt.value = opt.innerHTML = d3.select(this).attr("id"); burgSelectGroup.add(opt); }); } - $("#burgEditor > button").not("#burgAddfromEditor").not("#burgRemove").click(function () { + $("#burgEditor > button").not("#burgAddfromEditor").not("#burgRemove").click(function() { if ($(this).next().is(":visible")) { $("#burgEditor > button").show(); $(this).next("div").hide(); @@ -3006,7 +2997,7 @@ function fantasyMap() { } }); - $("#burgEditor > div > button").click(function () { + $("#burgEditor > div > button").click(function() { if ($(this).next().is(":visible")) { $("#burgEditor > div > button").show(); $(this).parent().prev().show(); @@ -3018,11 +3009,11 @@ function fantasyMap() { } }); - $("#burgSelectGroup").change(function () { + $("#burgSelectGroup").change(function() { const id = +elSelected.attr("data-id"); const g = this.value; - $("#burgIcons [data-id=" + id + "]").detach().appendTo($("#burgIcons > #" + g)); - $("#burgLabels [data-id=" + id + "]").detach().appendTo($("#burgLabels > #" + g)); + $("#burgIcons [data-id=" + id + "]").detach().appendTo($("#burgIcons > #"+g)); + $("#burgLabels [data-id=" + id + "]").detach().appendTo($("#burgLabels > #"+g)); // special case for port icons (anchors) if (g === "towns" || g === "capitals") { const el = $("#icons g[id*='anchors'] [data-id=" + id + "]"); @@ -3032,19 +3023,19 @@ function fantasyMap() { } }); - $("#burgInputGroup").change(function () { + $("#burgInputGroup").change(function() { const newGroup = this.value.toLowerCase().replace(/ /g, "_").replace(/[^\w\s]/gi, ""); if (Number.isFinite(+newGroup.charAt(0))) newGroup = "g" + newGroup; - if (burgLabels.select("#" + newGroup).size()) { - tip('The group "' + newGroup + ' is already exists"'); + if (burgLabels.select("#"+newGroup).size()) { + tip('The group "'+ newGroup + ' is already exists"'); return; } burgInputGroup.value = ""; // clone old group assigning new id const id = elSelected.node().parentNode.id; - const l = burgLabels.select("#" + id).node().cloneNode(false); + const l = burgLabels.select("#"+id).node().cloneNode(false); l.id = newGroup; - const i = burgIcons.select("#" + id).node().cloneNode(false); + const i = burgIcons.select("#"+id).node().cloneNode(false); i.id = newGroup; burgLabels.node().insertBefore(l, null); burgIcons.node().insertBefore(i, null); @@ -3056,7 +3047,7 @@ function fantasyMap() { $("#burgSelectGroup, #burgInputGroup").toggle(); }); - $("#burgAddGroup").click(function () { + $("#burgAddGroup").click(function() { if ($("#burgInputGroup").css("display") === "none") { $("#burgInputGroup").css("display", "inline-block"); $("#burgSelectGroup").css("display", "none"); @@ -3067,44 +3058,43 @@ function fantasyMap() { } }); - $("#burgRemoveGroup").click(function () { + $("#burgRemoveGroup").click(function() { const group = d3.select(elSelected.node().parentNode); const type = group.attr("id"); const id = +elSelected.attr("data-id"); var count = group.selectAll("*").size(); const message = "Are you sure you want to remove all Burgs (" + count + ") of that group?"; alertMessage.innerHTML = message; - $("#alert").dialog({ - resizable: false, title: "Remove Burgs", + $("#alert").dialog({resizable: false, title: "Remove Burgs", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); - group.selectAll("*").each(function (d) { + group.selectAll("*").each(function(d) { const id = +d3.select(this).attr("data-id"); if (id === undefined) return; const cell = manors[id].cell; const state = manors[id].region; if (states[state]) { if (states[state].capital === id) states[state].capital = "select"; - states[state].burgs--; + states[state].burgs --; } manors[id].region = "removed"; cells[cell].manor = undefined; }); - burgLabels.select("#" + type).selectAll("*").remove(); - burgIcons.select("#" + type).selectAll("*").remove(); + burgLabels.select("#"+type).selectAll("*").remove(); + burgIcons.select("#"+type).selectAll("*").remove(); $("#icons g[id*='anchors'] [data-id=" + id + "]").parent().children().remove(); closeDialogs(".stable"); updateCountryEditors(); $("#burgEditor").dialog("close"); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }) return; }); - $("#burgNameInput").on("input", function () { + $("#burgNameInput").on("input", function() { if (this.value === "") { tip("Name should not be blank, set opacity to 0 to hide label or remove button to delete"); return; @@ -3115,7 +3105,7 @@ function fantasyMap() { $("div[aria-describedby='burgEditor'] .ui-dialog-title").text("Edit Burg: " + this.value); }); - $("#burgNameReCulture, #burgNameReRandom").click(function () { + $("#burgNameReCulture, #burgNameReRandom").click(function() { const id = +elSelected.attr("data-id"); const culture = this.id === "burgNameReCulture" ? manors[id].culture : Math.floor(Math.random() * cultures.length); const name = generateName(culture); @@ -3125,7 +3115,7 @@ function fantasyMap() { $("div[aria-describedby='burgEditor'] .ui-dialog-title").text("Edit Burg: " + name); }); - $("#burgToggleExternalFont").click(function () { + $("#burgToggleExternalFont").click(function() { if ($("#burgInputExternalFont").css("display") === "none") { $("#burgInputExternalFont").css("display", "inline-block"); $("#burgSelectDefaultFont").css("display", "none"); @@ -3136,15 +3126,15 @@ function fantasyMap() { } }); - $("#burgSelectDefaultFont").change(function () { + $("#burgSelectDefaultFont").change(function() { const type = elSelected.node().parentNode.id; - const group = burgLabels.select("#" + type); + const group = burgLabels.select("#"+type); if (burgSelectDefaultFont.value === "") return; const font = fonts[burgSelectDefaultFont.value].split(':')[0].replace(/\+/g, " "); group.attr("font-family", font).attr("data-font", fonts[burgSelectDefaultFont.value]); }); - $("#burgInputExternalFont").change(function () { + $("#burgInputExternalFont").change(function() { fetchFonts(this.value).then(fetched => { if (!fetched) return; burgToggleExternalFont.click(); @@ -3153,73 +3143,73 @@ function fantasyMap() { }); }); - $("#burgSetLabelSize").on("input", function () { + $("#burgSetLabelSize").on("input", function() { const type = elSelected.node().parentNode.id; - const group = burgLabels.select("#" + type); + const group = burgLabels.select("#"+type); group.attr("data-size", +this.value); invokeActiveZooming(); }); - $("#burgLabelColorInput").on("input", function () { + $("#burgLabelColorInput").on("input", function() { const type = elSelected.node().parentNode.id; - const group = burgLabels.select("#" + type); + const group = burgLabels.select("#"+type); group.attr("fill", this.value); }); - $("#burgLabelOpacity").on("input", function () { + $("#burgLabelOpacity").on("input", function() { const type = elSelected.node().parentNode.id; - const group = burgLabels.select("#" + type); + const group = burgLabels.select("#"+type); group.attr("opacity", +this.value); }); - $("#burgLabelAngle").on("input", function () { + $("#burgLabelAngle").on("input", function() { const id = +elSelected.attr("data-id"); - const el = burgLabels.select("[data-id='" + id + "']"); + const el = burgLabels.select("[data-id='"+ id +"']"); const c = el.node().getBBox(); - const rotate = `rotate(${this.value} ${(c.x + c.width / 2)} ${(c.y + c.height / 2)})`; + const rotate = `rotate(${this.value} ${(c.x+c.width/2)} ${(c.y+c.height/2)})`; el.attr("transform", rotate); burgLabelAngleOutput.innerHTML = Math.abs(+this.value) + "°"; }); - $("#burgIconSize").on("input", function () { + $("#burgIconSize").on("input", function() { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#" + type); + const group = burgIcons.select("#"+type); const size = +this.value group.attr("size", size); - group.selectAll("*").each(function () { d3.select(this).attr("r", size) }); + group.selectAll("*").each(function() {d3.select(this).attr("r", size)}); }); - $("#burgIconFillOpacity").on("input", function () { + $("#burgIconFillOpacity").on("input", function() { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#" + type); + const group = burgIcons.select("#"+type); group.attr("fill-opacity", +this.value); }); - $("#burgIconFillColor").on("input", function () { + $("#burgIconFillColor").on("input", function() { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#" + type); + const group = burgIcons.select("#"+type); group.attr("fill", this.value); }); - $("#burgIconStrokeWidth").on("input", function () { + $("#burgIconStrokeWidth").on("input", function() { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#" + type); + const group = burgIcons.select("#"+type); group.attr("stroke-width", +this.value); }); - $("#burgIconStrokeOpacity").on("input", function () { + $("#burgIconStrokeOpacity").on("input", function() { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#" + type); + const group = burgIcons.select("#"+type); group.attr("stroke-opacity", +this.value); }); - $("#burgIconStrokeColor").on("input", function () { + $("#burgIconStrokeColor").on("input", function() { const type = elSelected.node().parentNode.id; - const group = burgIcons.select("#" + type); + const group = burgIcons.select("#"+type); group.attr("stroke", this.value); }); - $("#burgToggleCapital").click(function () { + $("#burgToggleCapital").click(function() { const id = +elSelected.attr("data-id"); const state = manors[id].region; if (states[state] === undefined) return; @@ -3234,8 +3224,8 @@ function fantasyMap() { states[state].capital = capital ? id : "select"; d3.select("#burgToggleCapital").classed("pressed", capital); const g = capital ? "capitals" : "towns"; - $("#burgIcons [data-id=" + id + "]").detach().appendTo($("#burgIcons > #" + g)); - $("#burgLabels [data-id=" + id + "]").detach().appendTo($("#burgLabels > #" + g)); + $("#burgIcons [data-id=" + id + "]").detach().appendTo($("#burgIcons > #"+g)); + $("#burgLabels [data-id=" + id + "]").detach().appendTo($("#burgLabels > #"+g)); const el = $("#icons g[id*='anchors'] [data-id=" + id + "]"); updateCountryEditors(); if (!el.length) return; @@ -3243,7 +3233,7 @@ function fantasyMap() { el.detach().appendTo(to); }); - $("#burgTogglePort").click(function () { + $("#burgTogglePort").click(function() { const id = +elSelected.attr("data-id"); const cell = cells[manors[id].cell]; const markAsPort = cell.port === undefined ? true : undefined; @@ -3264,23 +3254,22 @@ function fantasyMap() { } }); - $("#burgPopulation").on("input", function () { + $("#burgPopulation").on("input", function() { const id = +elSelected.attr("data-id"); burgPopulationFriendly.value = rn(this.value * urbanization.value * populationRate.value * 1000); manors[id].population = +this.value; }); - $("#burgAddfromEditor").click(function () { + $("#burgAddfromEditor").click(function() { clickToAdd(); // to load on click event function $("#addBurg").click(); }); - $("#burgRemove").click(function () { + $("#burgRemove").click(function() { alertMessage.innerHTML = `Are you sure you want to remove the Burg?`; - $("#alert").dialog({ - resizable: false, title: "Remove Burg", + $("#alert").dialog({resizable: false, title: "Remove Burg", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); const id = +elSelected.attr("data-id"); d3.selectAll("[data-id='" + id + "']").remove(); @@ -3288,14 +3277,14 @@ function fantasyMap() { const state = manors[id].region; if (states[state]) { if (states[state].capital === id) states[state].capital = "select"; - states[state].burgs--; + states[state].burgs --; } manors[id].region = "removed"; cells[cell].manor = undefined; closeDialogs(".stable"); updateCountryEditors(); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }) }); @@ -3305,7 +3294,7 @@ function fantasyMap() { function generateCultures() { const count = +culturesInput.value; cultures = d3.shuffle(defaultCultures).slice(0, count); - const centers = d3.range(cultures.length).map(function (d, i) { + const centers = d3.range(cultures.length).map(function(d, i) { const x = Math.floor(Math.random() * graphWidth * 0.8 + graphWidth * 0.1); const y = Math.floor(Math.random() * graphHeight * 0.8 + graphHeight * 0.1); const center = [x, y]; @@ -3338,7 +3327,7 @@ function fantasyMap() { // Assess cells geographycal suitability for settlement function rankPlacesGeography() { console.time('rankPlacesGeography'); - land.map(function (c) { + land.map(function(c) { let score = 0; // truncate decimals to keep data clear c.height = Math.trunc(c.height * 100) / 100; @@ -3353,12 +3342,12 @@ function fantasyMap() { c.score = 0; // ignore 80% of extended cells } else { if (c.harbor) { - if (c.harbor === 1) { score += 1; } else { score -= 0.3; } // good sea harbor is valued + if (c.harbor === 1) {score += 1;} else {score -= 0.3;} // good sea harbor is valued } if (c.river && c.ctype === 1) score += 1; // estuary is valued if (c.flux > 1) score += Math.pow(c.flux, 0.3); // riverbank is valued if (c.confluence) score += Math.pow(c.confluence, 0.7); // confluence is valued; - const neighbEv = c.neighbors.map(function (n) { if (cells[n].height >= 0.2) return cells[n].height; }) + const neighbEv = c.neighbors.map(function(n) {if (cells[n].height >= 0.2) return cells[n].height;}) const difEv = c.height - d3.mean(neighbEv); if (!isNaN(difEv)) { score += difEv * 10 * (1 - c.height); // local height maximums are valued @@ -3367,14 +3356,14 @@ function fantasyMap() { } c.score = rn(Math.random() * score + score, 3); // add random factor }); - land.sort(function (a, b) { return b.score - a.score; }); + land.sort(function(a, b) {return b.score - a.score;}); console.timeEnd('rankPlacesGeography'); } // Assess the cells economical suitability for settlement function rankPlacesEconomy() { console.time('rankPlacesEconomy'); - land.map(function (c) { + land.map(function(c) { var score = c.score; var path = c.path || 0; // roads are valued if (path) { @@ -3384,32 +3373,32 @@ function fantasyMap() { } c.score = rn(Math.random() * score + score, 2); // add random factor }); - land.sort(function (a, b) { return b.score - a.score; }); + land.sort(function(a, b) {return b.score - a.score;}); console.timeEnd('rankPlacesEconomy'); } - // calculate population for manors, cells and states + // calculate population for manors, cells and states function calculatePopulation() { // neutral population factors < 1 as neutral lands are usually pretty wild const ruralFactor = 0.5, urbanFactor = 0.9; // calculate population for each burg (based on trade/people attractors) - manors.map(function (m) { + manors.map(function(m) { var cell = cells[m.cell]; var score = cell.score; - if (score <= 0) { score = rn(Math.random(), 2) } - if (cell.crossroad) { score += cell.crossroad; } // crossroads - if (cell.confluence) { score += Math.pow(cell.confluence, 0.3); } // confluences - if (m.i !== m.region && cell.port) { score *= 1.5; } // ports (not capital) - if (m.i === m.region && !cell.port) { score *= 2; } // land-capitals - if (m.i === m.region && cell.port) { score *= 3; } // port-capitals + if (score <= 0) {score = rn(Math.random(), 2)} + if (cell.crossroad) {score += cell.crossroad;} // crossroads + if (cell.confluence) {score += Math.pow(cell.confluence, 0.3);} // confluences + if (m.i !== m.region && cell.port) {score *= 1.5;} // ports (not capital) + if (m.i === m.region && !cell.port) {score *= 2;} // land-capitals + if (m.i === m.region && cell.port) {score *= 3;} // port-capitals if (m.region === "neutral") score *= urbanFactor; m.population = rn(score, 1); }); // calculate rural population for each cell based on area + elevation (elevation to be changed to biome) const graphSizeAdj = 90 / Math.sqrt(cells.length, 2); // adjust to different graphSize - land.map(function (l) { + land.map(function(l) { let population = 0; const elevationFactor = Math.pow(1 - l.height, 3); population = elevationFactor * l.area * graphSizeAdj; @@ -3418,39 +3407,37 @@ function fantasyMap() { }); // calculate population for each region - states.map(function (s, i) { + states.map(function(s, i) { // define region burgs count - var burgs = $.grep(manors, function (e) { return e.region === i; }); + var burgs = $.grep(manors, function(e) {return e.region === i;}); s.burgs = burgs.length; // define region total and burgs population var burgsPop = 0; // get summ of all burgs population - burgs.map(function (b) { burgsPop += b.population; }); + burgs.map(function(b) {burgsPop += b.population;}); s.urbanPopulation = rn(burgsPop, 2); - var regionCells = $.grep(cells, function (e) { return e.region === i; }); + var regionCells = $.grep(cells, function(e) {return e.region === i;}); let cellsPop = 0; - regionCells.map(function (c) { cellsPop += c.pop }); + regionCells.map(function(c) {cellsPop += c.pop}); s.cells = regionCells.length; s.ruralPopulation = rn(cellsPop, 1); }); // collect data for neutrals - const neutralCells = $.grep(cells, function (e) { return e.region === "neutral"; }); + const neutralCells = $.grep(cells, function(e) {return e.region === "neutral";}); if (neutralCells.length) { let burgs = 0, urbanPopulation = 0, ruralPopulation = 0, area = 0; - manors.forEach(function (m) { + manors.forEach(function(m) { if (m.region !== "neutral") return; urbanPopulation += m.population; burgs++; }); - neutralCells.forEach(function (c) { + neutralCells.forEach(function(c) { ruralPopulation += c.pop; area += cells[c.index].area; }); - states.push({ - i: states.length, color: "neutral", name: "Neutrals", capital: "neutral", + states.push({i: states.length, color: "neutral", name: "Neutrals", capital: "neutral", cells: neutralCells.length, burgs, urbanPopulation: rn(urbanPopulation, 2), - ruralPopulation: rn(ruralPopulation, 2), area: rn(area) - }); + ruralPopulation: rn(ruralPopulation, 2), area: rn(area)}); } } @@ -3475,7 +3462,7 @@ function fantasyMap() { const closest = cultureTree.find(x, y); const culture = getCultureId(closest); const name = generateName(culture); - manors.push({ i: region, cell, x, y, region, culture, name }); + manors.push({i: region, cell, x, y, region, culture, name}); } if (l === land.length - 1) { console.error("Cannot place capitals with current spacing. Trying again with reduced spacing"); @@ -3486,10 +3473,10 @@ function fantasyMap() { // For each capital create a country const scheme = count <= 8 ? colors8 : colors20; const mod = +powerInput.value; - manors.forEach(function (m, i) { + manors.forEach(function(m, i) { const power = rn(Math.random() * mod / 2 + 1, 1); const color = scheme(i / count); - states.push({ i, color, power, capital: i }); + states.push({i, color, power, capital: i}); states[i].name = generateStateName(i); const p = cells[m.cell]; p.manor = i; @@ -3504,7 +3491,7 @@ function fantasyMap() { const count = +manorsInput.value; const neutral = +neutralInput.value; const manorTree = d3.quadtree(); - manors.forEach(function (m) { manorTree.add([m.x, m.y]); }); + manors.forEach(function(m) {manorTree.add([m.x, m.y]);}); for (let l = 0; manors.length < count && l < land.length; l++) { const x = land[l].data[0], y = land[l].data[1]; @@ -3517,7 +3504,7 @@ function fantasyMap() { let dist = Math.hypot(manors[c].x - x, manors[c].y - y) / states[c].power; const cap = manors[c].cell; if (cells[cell].fn !== cells[cap].fn) dist *= 3; - if (dist < closest) { region = c; closest = dist; } + if (dist < closest) {region = c; closest = dist;} } if (closest > neutral / 5 || region === "neutral") { const closestCulture = cultureTree.find(x, y); @@ -3529,7 +3516,7 @@ function fantasyMap() { land[l].manor = manors.length; land[l].culture = culture; land[l].region = region; - manors.push({ i: manors.length, cell, x, y, region, culture, name }); + manors.push({i: manors.length, cell, x, y, region, culture, name}); manorTree.add([x, y]); } if (manors.length < count) { @@ -3541,7 +3528,7 @@ function fantasyMap() { // shift settlements from cell point function shiftSettlements() { - for (let i = 0; i < manors.length; i++) { + for (let i=0; i < manors.length; i++) { const capital = i < regionsInput.value; const cell = cells[manors[i].cell]; let x = manors[i].x, y = manors[i].y; @@ -3574,11 +3561,11 @@ function fantasyMap() { console.time("checkAccessibility"); for (let f = 0; f < features.length; f++) { if (!features[f].land) continue; - var manorsOnIsland = $.grep(land, function (e) { return e.manor !== undefined && e.fn === f; }); + var manorsOnIsland = $.grep(land, function(e) {return e.manor !== undefined && e.fn === f;}); if (manorsOnIsland.length > 0) { - var ports = $.grep(manorsOnIsland, function (p) { return p.port; }); + var ports = $.grep(manorsOnIsland, function(p) {return p.port;}); if (ports.length === 0) { - var portCandidates = $.grep(manorsOnIsland, function (c) { return c.harbor && c.ctype === 1; }); + var portCandidates = $.grep(manorsOnIsland, function(c) {return c.harbor && c.ctype === 1;}); if (portCandidates.length > 0) { // No ports on island. Upgrading first burg to port const candidate = portCandidates[0]; @@ -3591,12 +3578,12 @@ function fantasyMap() { candidate.score += Math.floor((portCandidates.length - 1) / 2); } else { // No ports on island. Reducing score for burgs - manorsOnIsland.map(function (e) { e.score -= 2; }); + manorsOnIsland.map(function(e) {e.score -= 2;}); } } } } - console.timeEnd("checkAccessibility"); + console.timeEnd("checkAccessibility"); } function generateMainRoads() { @@ -3605,7 +3592,7 @@ function fantasyMap() { if (states.length < 2 || manors.length < 2) return; for (let f = 0; f < features.length; f++) { if (!features[f].land) continue; - const manorsOnIsland = $.grep(land, function (e) { return e.manor !== undefined && e.fn === f; }); + const manorsOnIsland = $.grep(land, function(e) {return e.manor !== undefined && e.fn === f;}); if (manorsOnIsland.length > 1) { for (let d = 1; d < manorsOnIsland.length; d++) { for (let m = 0; m < d; m++) { @@ -3623,17 +3610,17 @@ function fantasyMap() { console.time("generatePortRoads"); if (!states.length || manors.length < 2) return; const portless = []; - for (let s = 0; s < states.length; s++) { + for (let s=0; s < states.length; s++) { const cell = manors[s].cell; if (cells[cell].port === undefined) portless.push(s); } - for (let l = 0; l < portless.length; l++) { - const ports = $.grep(land, function (l) { return l.port !== undefined && l.region === portless[l]; }); + for (let l=0; l < portless.length; l++) { + const ports = $.grep(land, function(l) {return l.port !== undefined && l.region === portless[l];}); if (!ports.length) continue; let minDist = 1000, end = -1; - ports.map(function (p) { + ports.map(function(p) { const dist = Math.hypot(e.data[0] - p.data[0], e.data[1] - p.data[1]); - if (dist < minDist && dist > 1) { minDist = dist; end = p.index; } + if (dist < minDist && dist > 1) {minDist = dist; end = p.index;} }); if (end !== -1) { const start = manors[portless[l]].cell; @@ -3648,7 +3635,7 @@ function fantasyMap() { console.time("generateSmallRoads"); if (manors.length < 2) return; for (let f = 0; f < features.length; f++) { - var manorsOnIsland = $.grep(land, function (e) { return e.manor !== undefined && e.fn === f; }); + var manorsOnIsland = $.grep(land, function(e) {return e.manor !== undefined && e.fn === f;}); var l = manorsOnIsland.length; if (l > 1) { var secondary = rn((l + 8) / 10); @@ -3661,15 +3648,15 @@ function fantasyMap() { restorePath(end, start, "small", path); } } - manorsOnIsland.map(function (e, d) { + manorsOnIsland.map(function(e, d) { if (!e.path && d > 0) { var start = e.index, end = -1; - var road = $.grep(land, function (e) { return e.path && e.fn === f; }); + var road = $.grep(land, function(e) {return e.path && e.fn === f;}); if (road.length > 0) { var minDist = 10000; - road.map(function (i) { + road.map(function(i) { var dist = Math.hypot(e.data[0] - i.data[0], e.data[1] - i.data[1]); - if (dist < minDist) { minDist = dist; end = i.index; } + if (dist < minDist) {minDist = dist; end = i.index;} }); } else { end = manorsOnIsland[0].index; @@ -3727,13 +3714,13 @@ function fantasyMap() { const start = onIsland[fn][0]; const paths = findOceanPaths(start, -1); - for (let h = 1; h < onIsland[fn].length; h++) { + for (let h=1; h < onIsland[fn].length; h++) { // routes from all ports on island to 1st port on island restorePath(onIsland[fn][h], start, "ocean", paths); } // inter-island routes - for (let c = fn + 1; c < onIsland.length; c++) { + for (let c=fn+1; c < onIsland.length; c++) { if (!onIsland[c]) continue; if (!onIsland[c].length) continue; if (onIsland[fn].length > 3) { @@ -3744,7 +3731,7 @@ function fantasyMap() { if (features[w].border && !features[fn].border && onIsland[fn].length > 5) { // encircle the island - onIsland[fn].sort(function (a, b) { return cells[b].cost - cells[a].cost; }); + onIsland[fn].sort(function(a, b) {return cells[b].cost - cells[a].cost;}); for (let a = 2; a < onIsland[fn].length && a < 10; a++) { const from = onIsland[fn][1], to = onIsland[fn][a]; const dist = Math.hypot(cells[from].data[0] - cells[to].data[0], cells[from].data[1] - cells[to].data[1]); @@ -3768,25 +3755,25 @@ function fantasyMap() { function findLandPath(start, end, type) { // A* algorithm - var queue = new PriorityQueue({ comparator: function (a, b) { return a.p - b.p } }); + var queue = new PriorityQueue({comparator: function(a, b) {return a.p - b.p}}); var cameFrom = []; var costTotal = []; costTotal[start] = 0; - queue.queue({ e: start, p: 0 }); + queue.queue({e: start, p: 0}); while (queue.length > 0) { var next = queue.dequeue().e; - if (next === end) { break; } + if (next === end) {break;} var pol = cells[next]; - pol.neighbors.forEach(function (e) { + pol.neighbors.forEach(function(e) { if (cells[e].height >= 0.2) { var cost = cells[e].height * 2; if (cells[e].path && type === "main") { cost = 0.15; } else { - if (typeof e.manor === "undefined") { cost += 0.1; } - if (typeof e.river !== "undefined") { cost -= 0.1; } - if (cells[e].harbor) { cost *= 0.3; } - if (cells[e].path) { cost *= 0.5; } + if (typeof e.manor === "undefined") {cost += 0.1;} + if (typeof e.river !== "undefined") {cost -= 0.1;} + if (cells[e].harbor) {cost *= 0.3;} + if (cells[e].path) {cost *= 0.5;} cost += Math.hypot(cells[e].data[0] - pol.data[0], cells[e].data[1] - pol.data[1]) / 30; } var costNew = costTotal[next] + cost; @@ -3795,7 +3782,7 @@ function fantasyMap() { cameFrom[e] = next; var dist = Math.hypot(cells[e].data[0] - cells[end].data[0], cells[e].data[1] - cells[end].data[1]) / 15; var priority = costNew + dist; - queue.queue({ e, p: priority }); + queue.queue({e, p: priority}); } } }); @@ -3805,14 +3792,14 @@ function fantasyMap() { function findLandPaths(start, type) { // Dijkstra algorithm (not used now) - const queue = new PriorityQueue({ comparator: function (a, b) { return a.p - b.p } }); + const queue = new PriorityQueue({comparator: function(a, b) {return a.p - b.p}}); const cameFrom = [], costTotal = []; cameFrom[start] = "no", costTotal[start] = 0; - queue.queue({ e: start, p: 0 }); + queue.queue({e: start, p: 0}); while (queue.length > 0) { const next = queue.dequeue().e; const pol = cells[next]; - pol.neighbors.forEach(function (e) { + pol.neighbors.forEach(function(e) { if (cells[e].height < 0.2) return; let cost = cells[e].height * 2; if (e.river !== undefined) cost -= 0.2; @@ -3823,7 +3810,7 @@ function fantasyMap() { if (!cameFrom[e]) { costTotal[e] = costNew; cameFrom[e] = next; - queue.queue({ e, p: costNew }); + queue.queue({e, p: costNew}); } }); } @@ -3831,15 +3818,15 @@ function fantasyMap() { } function findOceanPaths(start, end) { - const queue = new PriorityQueue({ comparator: function (a, b) { return a.p - b.p } }); + const queue = new PriorityQueue({comparator: function(a, b) {return a.p - b.p}}); let next; const cameFrom = [], costTotal = []; cameFrom[start] = "no", costTotal[start] = 0; - queue.queue({ e: start, p: 0 }); + queue.queue({e: start, p: 0}); while (queue.length > 0 && next !== end) { next = queue.dequeue().e; const pol = cells[next]; - pol.neighbors.forEach(function (e) { + pol.neighbors.forEach(function(e) { if (cells[e].ctype < 0 || cells[e].haven === next) { let cost = 1; if (cells[e].ctype > 0) cost += 100; @@ -3853,7 +3840,7 @@ function fantasyMap() { costTotal[e] = costNew; cells[e].cost = costNew; cameFrom[e] = next; - queue.queue({ e, p: costNew }); + queue.queue({e, p: costNew}); } } }); @@ -3862,24 +3849,24 @@ function fantasyMap() { } function getPathDist(start, end) { - var queue = new PriorityQueue({ comparator: function (a, b) { return a.p - b.p } }); + var queue = new PriorityQueue({comparator: function(a, b) {return a.p - b.p}}); var next, costNew; var cameFrom = []; var costTotal = []; cameFrom[start] = "no"; costTotal[start] = 0; - queue.queue({ e: start, p: 0 }); + queue.queue({e: start, p: 0}); while (queue.length > 0 && next !== end) { next = queue.dequeue().e; var pol = cells[next]; - pol.neighbors.forEach(function (e) { + pol.neighbors.forEach(function(e) { if (cells[e].path && (cells[e].ctype === -1 || cells[e].haven === next)) { var dist = Math.hypot(cells[e].data[0] - pol.data[0], cells[e].data[1] - pol.data[1]); costNew = costTotal[next] + dist; if (!cameFrom[e]) { costTotal[e] = costNew; cameFrom[e] = next; - queue.queue({ e, p: costNew }); + queue.queue({e, p: costNew}); } } }); @@ -3890,24 +3877,24 @@ function fantasyMap() { function restorePath(end, start, type, from) { var path = [], current = end, limit = 1000; var prev = cells[end]; - if (type === "ocean" || !prev.path) { path.push({ scX: prev.data[0], scY: prev.data[1], i: end }); } - if (!prev.path) { prev.path = 1; } + if (type === "ocean" || !prev.path) {path.push({scX: prev.data[0], scY: prev.data[1], i: end});} + if (!prev.path) {prev.path = 1;} for (let i = 0; i < limit; i++) { current = from[current]; var cur = cells[current]; - if (!cur) { break; } + if (!cur) {break;} if (cur.path) { cur.path += 1; - path.push({ scX: cur.data[0], scY: cur.data[1], i: current }); + path.push({scX: cur.data[0], scY: cur.data[1], i: current}); prev = cur; drawPath(); } else { cur.path = 1; - if (prev) { path.push({ scX: prev.data[0], scY: prev.data[1], i: prev.index }); } + if (prev) {path.push({scX: prev.data[0], scY: prev.data[1], i: prev.index});} prev = undefined; - path.push({ scX: cur.data[0], scY: cur.data[1], i: current }); + path.push({scX: cur.data[0], scY: cur.data[1], i: current}); } - if (current === start || !from[current]) { break; } + if (current === start || !from[current]) {break;} } drawPath(); function drawPath() { @@ -3917,12 +3904,12 @@ function fantasyMap() { var plus = type === "main" ? 4 : 2; var f = cells[path[0].i]; if (f.path > 1) { - if (!f.crossroad) { f.crossroad = 0; } + if (!f.crossroad) {f.crossroad = 0;} f.crossroad += plus; } var t = cells[(path[path.length - 1].i)]; if (t.path > 1) { - if (!t.crossroad) { t.crossroad = 0; } + if (!t.crossroad) {t.crossroad = 0;} t.crossroad += plus; } } @@ -3932,13 +3919,13 @@ function fantasyMap() { let id = 0; // to create unique route id if (type === "main") { id = roads.selectAll("path").size(); - roads.append("path").attr("d", line).attr("id", "road" + id).on("click", editRoute); + roads.append("path").attr("d", line).attr("id", "road"+id).on("click", editRoute); } else if (type === "small") { id = trails.selectAll("path").size(); - trails.append("path").attr("d", line).attr("id", "trail" + id).on("click", editRoute); + trails.append("path").attr("d", line).attr("id", "trail"+id).on("click", editRoute); } else if (type === "ocean") { id = searoutes.selectAll("path").size(); - searoutes.append("path").attr("d", line).attr("id", "searoute" + id).on("click", editRoute); + searoutes.append("path").attr("d", line).attr("id", "searoute"+id).on("click", editRoute); } } path = []; @@ -3973,7 +3960,7 @@ function fantasyMap() { } function calculateChains() { - for (let c = 0; c < nameBase.length; c++) { + for (let c=0; c < nameBase.length; c++) { chain[c] = calculateChain(c); } } @@ -3986,15 +3973,15 @@ function fantasyMap() { for (let i = -1, prev = " ", str = ""; i < d.length - 2; prev = str, i += str.length, str = "") { let vowel = 0, f = " "; - if (method === "let-to-let") { str = d[i + 1]; } else { - for (let c = i + 1; str.length < 5; c++) { + if (method === "let-to-let") {str = d[i+1];} else { + for (let c=i+1; str.length < 5; c++) { if (d[c] === undefined) break; str += d[c]; if (str === " ") break; - if (d[c] !== "o" && d[c] !== "e" && vowels.includes(d[c]) && d[c + 1] === d[c]) break; - if (d[c + 2] === " ") { str += d[c + 1]; break; } + if (d[c] !== "o" && d[c] !== "e" && vowels.includes(d[c]) && d[c+1] === d[c]) break; + if (d[c+2] === " ") {str += d[c+1]; break;} if (vowels.includes(d[c])) vowel++; - if (vowel && vowels.includes(d[c + 2])) break; + if (vowel && vowels.includes(d[c+2])) break; } } if (i >= 0) { @@ -4025,33 +4012,33 @@ function fantasyMap() { base = 0; } const method = nameBases[base].method; - const error = function (base) { + const error = function(base) { tip("Names data for base " + nameBases[base].name + " is incorrect. Please fix in Namesbase Editor"); editNamesbase(); } if (method === "selection") { - if (nameBase[base].length < 1) { error(base); return; } + if (nameBase[base].length < 1) {error(base); return;} const rnd = rand(nameBase[base].length - 1); const name = nameBase[base][rnd]; return name; } const data = chain[base]; - if (data === undefined || data[" "] === undefined) { error(base); return; } + if (data === undefined || data[" "] === undefined) {error(base); return;} const max = nameBases[base].max; const min = nameBases[base].min; const d = nameBases[base].d; let word = "", variants = data[" "]; - if (variants === undefined) { error(base); return; }; + if (variants === undefined) {error(base); return;}; let cur = variants[rand(variants.length - 1)]; - for (let i = 0; i < 21; i++) { + for (let i=0; i < 21; i++) { if (cur === " " && Math.random() < 0.8) { // space means word end, but we don't want to end if word is too short if (word.length < min) { word = ""; variants = data[" "]; - } else { break; } + } else {break;} } else { const l = method === "let-to-syl" && cur.length > 1 ? cur[cur.length - 1] : cur; variants = data[l]; @@ -4059,7 +4046,7 @@ function fantasyMap() { word += cur; // add current el to word if (word.length > max) word = ""; } - if (variants === undefined) { error(base); return; }; + if (variants === undefined) {error(base); return;}; cur = variants[rand(variants.length - 1)]; } // very rare case, let's just select a random name @@ -4068,14 +4055,14 @@ function fantasyMap() { // do not allow multi-word name if word is foo short or not allowed for culture if (word.includes(" ")) { let words = word.split(" "), parsed; - if (Math.random() > nameBases[base].m) { word = words.join(""); } + if (Math.random() > nameBases[base].m) {word = words.join("");} else { - for (let i = 0; i < words.length; i++) { + for (let i=0; i < words.length; i++) { if (words[i].length < 2) { if (!i) words[1] = words[0] + words[1]; - if (i) words[i - 1] = words[i - 1] + words[i]; + if (i) words[i-1] = words[i-1] + words[i]; words.splice(i, 1); - i--; + i--; } } word = words.join(" "); @@ -4083,16 +4070,16 @@ function fantasyMap() { } // parse word to get a final name - const name = [...word].reduce(function (r, c, i, data) { + const name = [...word].reduce(function(r, c, i, data) { if (c === " ") { if (!r.length) return ""; - if (i + 1 === data.length) return r; + if (i+1 === data.length) return r; } if (!r.length) return c.toUpperCase(); if (r.slice(-1) === " ") return r + c.toUpperCase(); - if (c === data[i - 1]) { + if (c === data[i-1]) { if (!d.includes(c)) return r; - if (c === data[i - 2]) return r; + if (c === data[i-2]) return r; } return r + c; }, ""); @@ -4103,10 +4090,10 @@ function fantasyMap() { function defineRegions() { console.time('defineRegions'); const manorTree = d3.quadtree(); - manors.forEach(function (m) { if (m.region !== "removed") manorTree.add([m.x, m.y]); }); + manors.forEach(function(m) {if (m.region !== "removed") manorTree.add([m.x, m.y]);}); const neutral = +neutralInput.value; - land.forEach(function (i) { + land.forEach(function(i) { if (i.manor !== undefined) { i.region = manors[i.manor].region; i.culture = manors[i.manor].culture; @@ -4128,11 +4115,11 @@ function fantasyMap() { const cell = manors[manor].cell; if (cells[cell].fn !== i.fn) { let minDist = dist * 3; - land.forEach(function (l) { + land.forEach(function(l) { if (l.fn === i.fn && l.manor !== undefined) { if (manors[l.manor].region === "removed") return; const distN = Math.hypot(l.data[0] - x, l.data[1] - y); - if (distN < minDist) { minDist = distN; manor = l.manor; } + if (distN < minDist) {minDist = distN; manor = l.manor;} } }); } @@ -4150,16 +4137,16 @@ function fantasyMap() { // arrays to store edge data const edges = [], coastalEdges = [], borderEdges = [], neutralEdges = []; - for (let a = 0; a < states.length; a++) { + for (let a=0; a < states.length; a++) { edges[a] = []; coastalEdges[a] = []; } const e = diagram.edges; - for (let i = 0; i < e.length; i++) { + for (let i=0; i < e.length; i++) { if (e[i] === undefined) continue; const start = e[i][0].join(" "); const end = e[i][1].join(" "); - const p = { start, end }; + const p = {start, end}; if (e[i].left === undefined) { const r = e[i].right.index; const rr = cells[r].region; @@ -4179,17 +4166,17 @@ function fantasyMap() { if (lr === rr) continue; if (Number.isInteger(lr)) { edges[lr].push(p); - if (rr === undefined) { coastalEdges[lr].push(p); } - else if (rr === "neutral") { neutralEdges.push(p); } + if (rr === undefined) {coastalEdges[lr].push(p);} + else if (rr === "neutral") {neutralEdges.push(p);} } if (Number.isInteger(rr)) { edges[rr].push(p); - if (lr === undefined) { coastalEdges[rr].push(p); } - else if (lr === "neutral") { neutralEdges.push(p); } - else if (Number.isInteger(lr)) { borderEdges.push(p); } + if (lr === undefined) {coastalEdges[rr].push(p);} + else if (lr === "neutral") {neutralEdges.push(p);} + else if (Number.isInteger(lr)) {borderEdges.push(p);} } } - edges.map(function (e, i) { + edges.map(function(e, i) { if (e.length) { drawRegion(e, i); drawRegionCoast(coastalEdges[i], i); @@ -4209,11 +4196,11 @@ function fantasyMap() { var end = edges[0].end; edges.shift(); var spl = start.split(" "); - edgesOrdered.push({ scX: spl[0], scY: spl[1] }); + edgesOrdered.push({scX: spl[0], scY: spl[1]}); spl = end.split(" "); - edgesOrdered.push({ scX: spl[0], scY: spl[1] }); + edgesOrdered.push({scX: spl[0], scY: spl[1]}); for (let i = 0; end !== start && i < 2000; i++) { - var next = $.grep(edges, function (e) { return (e.start == end || e.end == end); }); + var next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); if (next.length > 0) { if (next[0].start == end) { end = next[0].end; @@ -4221,22 +4208,22 @@ function fantasyMap() { end = next[0].start; } spl = end.split(" "); - edgesOrdered.push({ scX: spl[0], scY: spl[1] }); + edgesOrdered.push({scX: spl[0], scY: spl[1]}); } var rem = edges.indexOf(next[0]); edges.splice(rem, 1); } path += lineGen(edgesOrdered) + "Z "; var edgesFormatted = []; - edgesOrdered.map(function (e) { edgesFormatted.push([+e.scX, +e.scY]) }); + edgesOrdered.map(function(e) {edgesFormatted.push([+e.scX, +e.scY])}); array[array.length] = edgesFormatted; } var color = states[region].color; - regions.append("path").attr("d", round(path, 1)).attr("fill", color).attr("stroke", "none").attr("class", "region" + region); - array.sort(function (a, b) { return b.length - a.length; }); + regions.append("path").attr("d", round(path, 1)).attr("fill", color).attr("stroke", "none").attr("class", "region"+region); + array.sort(function(a, b){return b.length - a.length;}); var name = states[region].name; var c = polylabel(array, 1.0); // pole of inaccessibility - labels.select("#countries").append("text").attr("id", "regionLabel" + region).attr("x", rn(c[0])).attr("y", rn(c[1])).text(name).on("click", editLabel); + labels.select("#countries").append("text").attr("id", "regionLabel"+region).attr("x", rn(c[0])).attr("y", rn(c[1])).text(name).on("click", editLabel); states[region].area = rn(Math.abs(d3.polygonArea(array[0]))); // define region area } @@ -4248,10 +4235,10 @@ function fantasyMap() { var end = edges[0].end; edges.shift(); var spl = start.split(" "); - edgesOrdered.push({ scX: spl[0], scY: spl[1] }); + edgesOrdered.push({scX: spl[0], scY: spl[1]}); spl = end.split(" "); - edgesOrdered.push({ scX: spl[0], scY: spl[1] }); - var next = $.grep(edges, function (e) { return (e.start == end || e.end == end); }); + edgesOrdered.push({scX: spl[0], scY: spl[1]}); + var next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); while (next.length > 0) { if (next[0].start == end) { end = next[0].end; @@ -4259,30 +4246,30 @@ function fantasyMap() { end = next[0].start; } spl = end.split(" "); - edgesOrdered.push({ scX: spl[0], scY: spl[1] }); + edgesOrdered.push({scX: spl[0], scY: spl[1]}); var rem = edges.indexOf(next[0]); edges.splice(rem, 1); - next = $.grep(edges, function (e) { return (e.start == end || e.end == end); }); + next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); } path += lineGen(edgesOrdered); } var color = states[region].color; - regions.append("path").attr("d", round(path, 1)).attr("fill", "none").attr("stroke", color).attr("stroke-width", 3).attr("class", "region" + region); + regions.append("path").attr("d", round(path, 1)).attr("fill", "none").attr("stroke", color).attr("stroke-width", 3).attr("class", "region"+region); } function drawBorders(edges, type) { var path = ""; - if (edges.length < 1) { return; } + if (edges.length < 1) {return;} while (edges.length > 0) { var edgesOrdered = []; // to store points in a correct order var start = edges[0].start; var end = edges[0].end; edges.shift(); var spl = start.split(" "); - edgesOrdered.push({ scX: spl[0], scY: spl[1] }); + edgesOrdered.push({scX: spl[0], scY: spl[1]}); spl = end.split(" "); - edgesOrdered.push({ scX: spl[0], scY: spl[1] }); - var next = $.grep(edges, function (e) { return (e.start == end || e.end == end); }); + edgesOrdered.push({scX: spl[0], scY: spl[1]}); + var next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); while (next.length > 0) { if (next[0].start == end) { end = next[0].end; @@ -4290,26 +4277,26 @@ function fantasyMap() { end = next[0].start; } spl = end.split(" "); - edgesOrdered.push({ scX: spl[0], scY: spl[1] }); + edgesOrdered.push({scX: spl[0], scY: spl[1]}); var rem = edges.indexOf(next[0]); edges.splice(rem, 1); - next = $.grep(edges, function (e) { return (e.start == end || e.end == end); }); + next = $.grep(edges, function(e) {return (e.start == end || e.end == end);}); } path += lineGen(edgesOrdered); } - if (type === "state") { stateBorders.append("path").attr("d", round(path, 1)); } - if (type === "neutral") { neutralBorders.append("path").attr("d", round(path, 1)); } + if (type === "state") {stateBorders.append("path").attr("d", round(path, 1));} + if (type === "neutral") {neutralBorders.append("path").attr("d", round(path, 1));} } // generate region name function generateStateName(state) { let culture = null; - if (states[state]) if (manors[states[state].capital]) culture = manors[states[state].capital].culture; + if (states[state]) if(manors[states[state].capital]) culture = manors[states[state].capital].culture; let name = "NameIdontWant"; if (Math.random() < 0.85 || culture === null) { // culture is random if capital is not yet defined if (culture === null) culture = rand(cultures.length - 1); - while (name.length > 8) { name = generateName(culture); } + while (name.length > 8) {name = generateName(culture);} } else { name = manors[state].name; } @@ -4320,11 +4307,11 @@ function fantasyMap() { const e = name.slice(-2); if (base === 5 && (e === "sk" || e === "ev" || e === "ov")) { // remove -sk and -ev/-ov for Ruthenian - name = name.slice(0, -2); + name = name.slice(0,-2); addSuffix = true; } else if (name.length > 6 && name.slice(-4) === "berg") { // remove -berg ending for any - name = name.slice(0, -4); + name = name.slice(0,-4); addSuffix = true; } @@ -4332,11 +4319,11 @@ function fantasyMap() { let vowel = vowels.includes(name.slice(-1)); // last char is vowel if (vowel && name.length > 3) { if (Math.random() < 0.85) { - if (vowels.includes(name.slice(-2, -1))) { - name = name.slice(0, -2); + if (vowels.includes(name.slice(-2,-1))) { + name = name.slice(0,-2); addSuffix = true; // 85% for vv } else if (Math.random() < 0.7) { - name = name.slice(0, -1); + name = name.slice(0,-1); addSuffix = true; // ~60% for cv } } @@ -4362,7 +4349,7 @@ function fantasyMap() { function recalculateCultures(fullRedraw) { console.time("recalculateCultures"); // For each capital find closest culture and assign it to capital - states.forEach(function (s) { + states.forEach(function(s) { if (s.capital === "neutral" || s.capital === "select") return; const capital = manors[s.capital]; const c = cultureTree.find(capital.x, capital.y); @@ -4373,7 +4360,7 @@ function fantasyMap() { // assign closest culture to the town; else assign capital's culture const manorTree = d3.quadtree(); const neutral = +neutralInput.value; - manors.forEach(function (m) { + manors.forEach(function(m) { if (m.region === "removed") return; manorTree.add([m.x, m.y]); if (m.region !== "neutral") { @@ -4391,7 +4378,7 @@ function fantasyMap() { // For each land cell if distance to closest manor > neutral / 2, // assign closest culture to the cell; else assign manors's culture const changed = []; - land.forEach(function (i) { + land.forEach(function(i) { const x = i.data[0], y = i.data[1]; const c = manorTree.find(x, y); const culture = i.culture; @@ -4404,11 +4391,11 @@ function fantasyMap() { const cell = manors[manor].cell; if (cells[cell].fn !== i.fn) { let minDist = dist * 3; - land.forEach(function (l) { + land.forEach(function(l) { if (l.fn === i.fn && l.manor !== undefined) { if (manors[l.manor].region === "removed") return; const distN = Math.hypot(l.data[0] - x, l.data[1] - y); - if (distN < minDist) { minDist = distN; manor = l.manor; } + if (distN < minDist) {minDist = distN; manor = l.manor;} } }); } @@ -4417,7 +4404,7 @@ function fantasyMap() { // re-color cells if (i.culture !== culture || fullRedraw) { const clr = cultures[i.culture].color; - cults.select("#cult" + i.index).attr("fill", clr).attr("stroke", clr); + cults.select("#cult"+i.index).attr("fill", clr).attr("stroke", clr); } }); console.timeEnd("recalculateCultures"); @@ -4425,14 +4412,14 @@ function fantasyMap() { // get culture Id from center coordinates function getCultureId(c) { - for (let i = 0; i < cultures.length; i++) { + for (let i=0; i < cultures.length; i++) { if (cultures[i].center[0] === c[0]) if (cultures[i].center[1] === c[1]) return i; } } // get manor Id from center coordinates function getManorId(c) { - for (let i = 0; i < manors.length; i++) { + for (let i=0; i < manors.length; i++) { if (manors[i].x === c[0]) if (manors[i].y === c[1]) return i; } } @@ -4445,11 +4432,11 @@ function fantasyMap() { if (scheme === "green") hColor = d3.scaleSequential(d3.interpolateGreens); if (scheme === "monochrome") hColor = d3.scaleSequential(d3.interpolateGreys); if (!terrs.selectAll("path").size()) { - cells.map(function (i, d) { + cells.map(function(i, d) { let height = i.height; if (height < 0.2 && !i.lake) return; if (i.lake) { - const heights = i.neighbors.map(function (e) { if (cells[e].height >= 0.2) return cells[e].height; }) + const heights = i.neighbors.map(function(e) {if (cells[e].height >= 0.2) return cells[e].height;}) const mean = d3.mean(heights); if (!mean) return; height = Math.trunc(mean * 100) / 100; @@ -4468,7 +4455,7 @@ function fantasyMap() { // draw Cultures function toggleCultures() { if (cults.selectAll("path").size() == 0) { - land.map(function (i) { + land.map(function(i) { const color = cultures[i.culture].color; cults.append("path") .attr("d", "M" + polygons[i.index].join("L") + "Z") @@ -4493,17 +4480,17 @@ function fantasyMap() { var x = d3.range(size, svgWidth, size); var y = d3.range(size, svgHeight, size); overlay.append("g").selectAll("line").data(x).enter().append("line") - .attr("x1", function (d) { return d; }) - .attr("x2", function (d) { return d; }) + .attr("x1", function(d) {return d;}) + .attr("x2", function(d) {return d;}) .attr("y1", 0).attr("y2", svgHeight); overlay.append("g").selectAll("line").data(y).enter().append("line") - .attr("y1", function (d) { return d; }) - .attr("y2", function (d) { return d; }) + .attr("y1", function(d) {return d;}) + .attr("y2", function(d) {return d;}) .attr("x1", 0).attr("x2", svgWidth); } else { var tr = `translate(80 80) scale(${size / 20})`; d3.select("#rose").attr("transform", tr); - overlay.append("use").attr("xlink:href", "#rose"); + overlay.append("use").attr("xlink:href","#rose"); } overlay.call(d3.drag().on("start", elementDrag)); } else { @@ -4514,7 +4501,7 @@ function fantasyMap() { // clean data to get rid of redundand info function cleanData() { console.time("cleanData"); - cells.map(function (c) { + cells.map(function(c) { delete c.cost; delete c.used; delete c.coastX; @@ -4535,7 +4522,7 @@ function fantasyMap() { // close all dialogs except stated function closeDialogs(except) { except = except || "#except"; - $(".dialog:visible").not(except).each(function (e) { + $(".dialog:visible").not(except).each(function(e) { $(this).dialog("close"); }); } @@ -4544,7 +4531,7 @@ function fantasyMap() { function toggleFlux() { var colorFlux = d3.scaleSequential(d3.interpolateBlues); if (terrs.selectAll("path").size() == 0) { - land.map(function (i) { + land.map(function(i) { terrs.append("path") .attr("d", "M" + polygons[i.index].join("L") + "Z") .attr("fill", colorFlux(0.1 + i.flux)) @@ -4614,7 +4601,7 @@ function fantasyMap() { swampCount++; land[i].used = 1; let swamp = drawSwamp(x, y); - land[i].neighbors.forEach(function (e) { + land[i].neighbors.forEach(function(e) { if (cells[e].height >= 0.2 && cells[e].height < 0.3 && !cells[e].river && cells[e].used != 1) { cells[e].used = 1; swamp += drawSwamp(cells[e].data[0], cells[e].data[1]); @@ -4729,7 +4716,7 @@ function fantasyMap() { if (matrix) { var angle = matrix.split('(')[1].split(')')[0].split(' ')[0]; var bbox = el.node().getBBox(); - var rotate = "rotate(" + angle + " " + (bbox.x + bbox.width / 2) + " " + (bbox.y + bbox.height / 2) + ")"; + var rotate = "rotate("+ angle + " " + (bbox.x + bbox.width/2) + " " + (bbox.y + bbox.height/2) + ")"; el.attr("transform", rotate); } } else { @@ -4768,13 +4755,13 @@ function fantasyMap() { } // Add support "click to add" button events - $("#customizeTab").click(function () { clickToAdd() }); + $("#customizeTab").click(function() {clickToAdd()}); function clickToAdd() { - if (modules.clickToAdd) { return; } + if (modules.clickToAdd) {return;} modules.clickToAdd = true; // add label on click - $("#addLabel").click(function () { + $("#addLabel").click(function() { if ($(this).hasClass('pressed')) { $(".pressed").removeClass('pressed'); restoreDefaultEvents(); @@ -4812,7 +4799,7 @@ function fantasyMap() { } // add burg on click - $("#addBurg").click(function () { + $("#addBurg").click(function() { if ($(this).hasClass('pressed')) { $(".pressed").removeClass('pressed'); restoreDefaultEvents(); @@ -4871,19 +4858,19 @@ function fantasyMap() { } cells[index].manor = i; let score = cells[index].score; - if (score <= 0) { score = rn(Math.random(), 2); } - if (cells[index].crossroad) { score += cells[index].crossroad; } // crossroads - if (cells[index].confluence) { score += Math.pow(cells[index].confluence, 0.3); } // confluences - if (cells[index].port !== undefined) { score *= 3; } // port-capital + if (score <= 0) {score = rn(Math.random(), 2);} + if (cells[index].crossroad) {score += cells[index].crossroad;} // crossroads + if (cells[index].confluence) {score += Math.pow(cells[index].confluence, 0.3);} // confluences + if (cells[index].port !== undefined) {score *= 3;} // port-capital var population = rn(score, 1); - manors.push({ i, cell: index, x, y, region, culture, name, population }); + manors.push({i, cell:index, x, y, region, culture, name, population}); recalculateStateData(state); updateCountryEditors(); tip("", true); } // add river on click - $("#addRiver").click(function () { + $("#addRiver").click(function() { if ($(this).hasClass('pressed')) { $(".pressed").removeClass('pressed'); unselect(); @@ -4903,7 +4890,7 @@ function fantasyMap() { var point = d3.mouse(this); var index = diagram.find(point[0], point[1]).index; var cell = cells[index]; - if (cell.river || cell.height < 0.2) { return; } + if (cell.river || cell.height < 0.2) {return;} var dataRiver = []; // to store river points const last = $("#rivers > path").last(); const river = last.length ? +last.attr("id").slice(5) + 1 : 0; @@ -4911,40 +4898,40 @@ function fantasyMap() { while (cell) { cell.river = river; var x = cell.data[0], y = cell.data[1]; - dataRiver.push({ x, y, cell: index }); + dataRiver.push({x, y, cell:index}); var heights = []; - cell.neighbors.forEach(function (e) { heights.push(cells[e].height); }); + cell.neighbors.forEach(function(e) {heights.push(cells[e].height);}); var minId = heights.indexOf(d3.min(heights)); var min = cell.neighbors[minId]; var tx = cells[min].data[0], ty = cells[min].data[1]; if (cells[min].height < 0.2) { var px = (x + tx) / 2; var py = (y + ty) / 2; - dataRiver.push({ x: px, y: py, cell: index }); + dataRiver.push({x: px, y: py, cell:index}); cell = undefined; } else { - if (cells[min].river === undefined) { cells[min].flux += cell.flux; cell = cells[min]; } + if (cells[min].river === undefined) {cells[min].flux += cell.flux; cell = cells[min];} else { const r = cells[min].river; - const riverEl = $("#river" + r); - const riverCells = $.grep(land, function (e) { return e.river === r; }); - riverCells.sort(function (a, b) { return b.height - a.height }); - const riverCellsUpper = $.grep(riverCells, function (e) { return e.height > cells[min].height; }); + const riverEl = $("#river"+r); + const riverCells = $.grep(land, function(e) {return e.river === r;}); + riverCells.sort(function(a, b) {return b.height - a.height}); + const riverCellsUpper = $.grep(riverCells, function(e) {return e.height > cells[min].height;}); if (dataRiver.length > riverCellsUpper.length) { // new river is more perspective const avPrec = rn(precInput.value / Math.sqrt(cells.length), 2); let dataRiverMin = []; - riverCells.map(function (c) { + riverCells.map(function(c) { if (c.height < cells[min].height) { cells[c.index].river = undefined; cells[c.index].flux = avPrec; } else { - dataRiverMin.push({ x: c.data[0], y: c.data[1], cell: c.index }); + dataRiverMin.push({x:c.data[0], y:c.data[1], cell:c.index}); } }); cells[min].flux += cell.flux; - if (cells[min].confluence) { cells[min].confluence += riverCellsUpper.length; } - else { cells[min].confluence = riverCellsUpper.length; } + if (cells[min].confluence) {cells[min].confluence += riverCellsUpper.length;} + else {cells[min].confluence = riverCellsUpper.length;} cell = cells[min]; // redraw old river's upper part or remove if small if (dataRiverMin.length > 1) { @@ -4953,13 +4940,13 @@ function fantasyMap() { riverEl.attr("d", d).attr("data-width", 1.3).attr("data-increment", 1); } else { riverEl.remove(); - dataRiverMin.map(function (c) { cells[c.cell].river = undefined; }); + dataRiverMin.map(function(c) {cells[c.cell].river = undefined;}); } } else { - if (cells[min].confluence) { cells[min].confluence += dataRiver.length; } - else { cells[min].confluence = dataRiver.length; } + if (cells[min].confluence) {cells[min].confluence += dataRiver.length;} + else {cells[min].confluence = dataRiver.length;} cells[min].flux += cell.flux; - dataRiver.push({ x: tx, y: ty, cell: min }); + dataRiver.push({x: tx, y: ty, cell:min}); cell = undefined; } } @@ -4968,12 +4955,12 @@ function fantasyMap() { var rndFactor = 0.2 + Math.random() * 1.6; // random factor in range 0.2-1.8 var riverAmended = amendRiver(dataRiver, rndFactor); var d = drawRiver(riverAmended, 1.3, 1); - rivers.append("path").attr("d", d).attr("id", "river" + river) + rivers.append("path").attr("d", d).attr("id", "river"+river) .attr("data-width", 1.3).attr("data-increment", 1).on("click", editRiver); } // add relief icon on click - $("#addRelief").click(function () { + $("#addRelief").click(function() { if ($(this).hasClass('pressed')) { $(".pressed").removeClass('pressed'); restoreDefaultEvents(); @@ -5007,7 +4994,7 @@ function fantasyMap() { } // add relief icon on click - $("#addRoute").click(function () { + $("#addRoute").click(function() { if (!modules.editRoute) editRoute(); $("#routeNew").click(); }); @@ -5027,14 +5014,14 @@ function fantasyMap() { function recalculateStateData(state) { const s = states[state]; if (s.capital === "neutral") state = "neutral"; - const burgs = $.grep(manors, function (e) { return e.region === state; }); + const burgs = $.grep(manors, function(e) {return e.region === state;}); s.burgs = burgs.length; let burgsPop = 0; // get summ of all burgs population - burgs.map(function (b) { burgsPop += b.population; }); + burgs.map(function(b) {burgsPop += b.population;}); s.urbanPopulation = rn(burgsPop, 1); - const regionCells = $.grep(cells, function (e) { return (e.region === state); }); + const regionCells = $.grep(cells, function(e) {return (e.region === state);}); let cellsPop = 0, area = 0; - regionCells.map(function (c) { + regionCells.map(function(c) { cellsPop += c.pop; area += c.area; }); @@ -5044,7 +5031,7 @@ function fantasyMap() { } function editLabel() { - if (customization) { return; } + if (customization) {return;} closeDialogs("#labelEditor, .stable"); elSelected = d3.select(this); elSelected.call(d3.drag().on("drag", dragged).on("end", dragended)).classed("draggable", true); @@ -5058,18 +5045,18 @@ function fantasyMap() { editOpacity.value = group.attr("opacity"); editText.value = elSelected.text(); var matrix = elSelected.attr("transform"); - var rotation = matrix ? matrix.split('(')[1].split(')')[0].split(' ')[0] : 0; + var rotation = matrix ? matrix.split('(')[1].split(')')[0].split(' ')[0] : 0; editAngle.value = rotation; editAngleValue.innerHTML = rotation + "°"; $("#labelEditor").dialog({ title: "Edit Label: " + editText.value, minHeight: 30, width: "auto", maxWidth: 275, resizable: false, - position: { my: "center top+10", at: "bottom", of: this }, + position: {my: "center top+10", at: "bottom", of: this}, close: unselect }); - if (modules.editLabel) { return; } + if (modules.editLabel) {return;} modules.editLabel = true; loadDefaultFonts(); @@ -5084,22 +5071,22 @@ function fantasyMap() { // select state if (customization === 2) { - const assigned = regions.select("#temp").select("path[data-cell='" + index + "']"); + const assigned = regions.select("#temp").select("path[data-cell='"+index+"']"); let s = assigned.size() ? assigned.attr("data-state") : cells[index].region; if (s === "neutral") s = states.length - 1; color = states[s].color; if (color === "neutral") color = "white"; - $("#state" + s).addClass("selected"); + $("#state"+s).addClass("selected"); } // select culture if (customization === 4) { - const assigned = cults.select("#cult" + index); + const assigned = cults.select("#cult"+index); const c = assigned.attr("data-culture") !== null ? +assigned.attr("data-culture") : cells[index].culture; color = cultures[c].color; - $("#culture" + c).addClass("selected"); + $("#culture"+c).addClass("selected"); } debug.selectAll(".circle").attr("stroke", color); @@ -5110,10 +5097,10 @@ function fantasyMap() { 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); }); + "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(); } } @@ -5121,29 +5108,28 @@ function fantasyMap() { // Update font list for Label and Burg Editors function updateFontOptions() { editFontSelect.innerHTML = ""; - for (let i = 0; i < fonts.length; i++) { + 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; editFontSelect.add(opt); } - burgSelectDefaultFont.innerHTML = editFontSelect.innerHTML; + burgSelectDefaultFont.innerHTML = editFontSelect.innerHTML; } - $("#labelEditor .editButton, #labelEditor .editButtonS").click(function () { + $("#labelEditor .editButton, #labelEditor .editButtonS").click(function() { var group = d3.select(elSelected.node().parentNode); if (this.id == "editRemoveSingle") { alertMessage.innerHTML = "Are you sure you want to remove the label?"; - $("#alert").dialog({ - resizable: false, title: "Remove label", + $("#alert").dialog({resizable: false, title: "Remove label", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); elSelected.remove(); $("#labelEditor").dialog("close"); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }) return; @@ -5157,15 +5143,14 @@ function fantasyMap() { } var message = "Are you sure you want to remove all labels (" + count + ") of that group?"; alertMessage.innerHTML = message; - $("#alert").dialog({ - resizable: false, title: "Remove labels", + $("#alert").dialog({resizable: false, title: "Remove labels", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); group.remove(); $("#labelEditor").dialog("close"); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }) return; @@ -5174,7 +5159,7 @@ function fantasyMap() { var shift = +group.attr("font-size") + 1; var xn = +elSelected.attr("x") - shift; var yn = +elSelected.attr("y") - shift; - while (group.selectAll("text[x='" + xn + "']").size() > 0) { xn -= shift; yn -= shift; } + while (group.selectAll("text[x='" + xn + "']").size() > 0) {xn -= shift; yn -= shift;} group.append("text").attr("x", xn).attr("y", yn).text(elSelected.text()) .attr("transform", elSelected.attr("transform")).on("click", editLabel); return; @@ -5205,7 +5190,7 @@ function fantasyMap() { var name; // check if label is country name if (group.attr("id") === "countries") { - var state = $.grep(states, function (e) { return (e.name === editText.value); })[0]; + var state = $.grep(states, function(e) {return (e.name === editText.value);})[0]; name = generateStateName(state.i); state.name = name; } else { @@ -5222,23 +5207,23 @@ function fantasyMap() { } $("#labelEditor .editButton").toggle(); if (this.id == "editGroupButton") { - if ($("#editGroupInput").css("display") !== "none") { $("#editGroupSelect").css("display", "inline-block"); } + if ($("#editGroupInput").css("display") !== "none") {$("#editGroupSelect").css("display", "inline-block");} if ($("#editGroupRemove").css("display") === "none") { $("#editGroupRemove, #editGroupNew").css("display", "inline-block"); } else { $("#editGroupInput, #editGroupRemove, #editGroupNew").css("display", "none"); } } - if (this.id == "editFontButton") { $("#editSizeIcon, #editFontSelect, #editSize").toggle(); } - if (this.id == "editStyleButton") { $("#editOpacityIcon, #editOpacity, #editShadowIcon, #editShadow").toggle(); } - if (this.id == "editAngleButton") { $("#editAngleValue").toggle(); } - if (this.id == "editTextButton") { $("#editTextRandom").toggle(); } + if (this.id == "editFontButton") {$("#editSizeIcon, #editFontSelect, #editSize").toggle();} + if (this.id == "editStyleButton") {$("#editOpacityIcon, #editOpacity, #editShadowIcon, #editShadow").toggle();} + if (this.id == "editAngleButton") {$("#editAngleValue").toggle();} + if (this.id == "editTextButton") {$("#editTextRandom").toggle();} $(this).show().next().toggle(); }); function updateGroupOptions() { editGroupSelect.innerHTML = ""; - labels.selectAll("g").each(function (d) { + labels.selectAll("g").each(function(d) { const id = d3.select(this).attr("id"); if (id === "burgLabels") return; if (id === "capitals") return; @@ -5250,14 +5235,14 @@ function fantasyMap() { } // on editAngle change - $("#editAngle").on("input", function () { + $("#editAngle").on("input", function() { var c = elSelected.node().getBBox(); - var rotate = `rotate(${this.value} ${(c.x + c.width / 2)} ${(c.y + c.height / 2)})`; + var rotate = `rotate(${this.value} ${(c.x+c.width/2)} ${(c.y+c.height/2)})`; elSelected.attr("transform", rotate); editAngleValue.innerHTML = Math.abs(+this.value) + "°"; }); - $("#editFontInput").change(function () { + $("#editFontInput").change(function() { fetchFonts(this.value).then(fetched => { if (!fetched) return; editExternalFont.click(); @@ -5312,19 +5297,19 @@ function fantasyMap() { let font = family.replace(/['"]+/g, '').replace(/ /g, "+"); let weight = rule.style.getPropertyValue('font-weight'); if (weight !== "400") font += ":" + weight; - if (fonts.indexOf(font) == -1) { fonts.push(font); fetched++ }; + if (fonts.indexOf(font) == -1) {fonts.push(font); fetched++}; }; let fetched = 0; - for (let r of styleSheet.cssRules) { FontRule(r); } + for (let r of styleSheet.cssRules) {FontRule(r);} document.head.removeChild(s); return fetched; }) - .catch(function () { return }); + .catch(function() {return}); } // on any Editor input change - $("#labelEditor .editTrigger").change(function () { - if (!elSelected) { return; } + $("#labelEditor .editTrigger").change(function() { + if (!elSelected) {return;} $(this).attr("title", $(this).val()); elSelected.text(editText.value); // change Label text // check if Group was changed @@ -5345,20 +5330,20 @@ function fantasyMap() { } if (groupOld !== groupNew) { var removed = elSelected.remove(); - if (labels.select("#" + groupNew).size() > 0) { - group = labels.select("#" + groupNew); + if (labels.select("#"+groupNew).size() > 0) { + group = labels.select("#"+groupNew); editFontSelect.value = fonts.indexOf(group.attr("data-font")); editSize.value = group.attr("data-size"); editColor.value = toHEX(group.attr("fill")); editOpacity.value = group.attr("opacity"); } else { - if (group.selectAll("text").size() === 0) { group.remove(); } + if (group.selectAll("text").size() === 0) {group.remove();} group = labels.append("g").attr("id", groupNew); updateGroupOptions(); $("#editGroupSelect, #editGroupInput").toggle(); editGroupInput.value = ""; } - group.append(function () { return removed.node(); }); + group.append(function() {return removed.node();}); editGroupSelect.value = group.attr("id"); } // update Group attributes @@ -5374,51 +5359,51 @@ function fantasyMap() { }); // 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) : ''; } // 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; } // round value to d decimals function rn(v, d) { - var d = d || 0; - var m = Math.pow(10, d); - return Math.round(v * m) / m; + var d = d || 0; + var m = Math.pow(10, d); + return Math.round(v * m) / m; } // round string to d decimals function round(s, d) { - var d = d || 1; - return s.replace(/[\d\.-][\d\.e-]*/g, function (n) { return rn(n, d); }) + var d = d || 1; + return s.replace(/[\d\.-][\d\.e-]*/g, function(n) {return rn(n, d);}) } // corvent number to short string with SI postfix function si(n) { - if (n >= 1e9) { return rn(n / 1e9, 1) + "B"; } - if (n >= 1e8) { return rn(n / 1e6) + "M"; } - if (n >= 1e6) { return rn(n / 1e6, 1) + "M"; } - if (n >= 1e4) { return rn(n / 1e3) + "K"; } - if (n >= 1e3) { return rn(n / 1e3, 1) + "K"; } + if (n >= 1e9) {return rn(n / 1e9, 1) + "B";} + if (n >= 1e8) {return rn(n / 1e6) + "M";} + if (n >= 1e6) {return rn(n / 1e6, 1) + "M";} + if (n >= 1e4) {return rn(n / 1e3) + "K";} + if (n >= 1e3) {return rn(n / 1e3, 1) + "K";} return rn(n); } // getInteger number from user input data function getInteger(value) { var metric = value.slice(-1); - if (metric === "K") { return parseInt(value.slice(0, -1) * 1e3); } - if (metric === "M") { return parseInt(value.slice(0, -1) * 1e6); } - if (metric === "B") { return parseInt(value.slice(0, -1) * 1e9); } + if (metric === "K") {return parseInt(value.slice(0, -1) * 1e3);} + if (metric === "M") {return parseInt(value.slice(0, -1) * 1e6);} + if (metric === "B") {return parseInt(value.slice(0, -1) * 1e9);} return parseInt(value); } @@ -5427,7 +5412,7 @@ function fantasyMap() { console.time("saveAsImage"); // get all used fonts const fontsInUse = []; // to store fonts currently in use - labels.selectAll("g").each(function (d) { + labels.selectAll("g").each(function(d) { const font = d3.select(this).attr("data-font"); if (!font) return; if (fontsInUse.indexOf(font) === -1) fontsInUse.push(font); @@ -5454,7 +5439,7 @@ function fantasyMap() { } // to fix use elements sizing - clone.selectAll("use").each(function () { + clone.selectAll("use").each(function() { const size = this.parentNode.getAttribute("size") || 1; this.setAttribute("width", size + "px"); this.setAttribute("height", size + "px"); @@ -5478,16 +5463,16 @@ function fantasyMap() { const defaultStyles = window.getComputedStyle(emptyG); // show hidden labels but in reduced size - clone.select("#labels").selectAll(".hidden").each(function (e) { + clone.select("#labels").selectAll(".hidden").each(function(e) { const size = d3.select(this).attr("font-size"); d3.select(this).classed("hidden", false).attr("font-size", rn(size * 0.4, 2)); }); // save group css to style attribute - clone.selectAll("g, #ruler > g > *, #scaleBar > text").each(function (d) { + clone.selectAll("g, #ruler > g > *, #scaleBar > text").each(function(d) { const compStyle = window.getComputedStyle(this); let style = ""; - for (let i = 0; i < compStyle.length; i++) { + for (let i=0; i < compStyle.length; i++) { const key = compStyle[i]; const value = compStyle.getPropertyValue(key); // Firefox mask hack @@ -5509,7 +5494,7 @@ function fantasyMap() { clone.select("defs").append("style").text(cssRules.join('\n')); var svg_xml = (new XMLSerializer()).serializeToString(clone.node()); clone.remove(); - var blob = new Blob([svg_xml], { type: 'image/svg+xml;charset=utf-8' }); + var blob = new Blob([svg_xml], {type:'image/svg+xml;charset=utf-8'}); var url = window.URL.createObjectURL(blob); var link = document.createElement("a"); link.target = "_blank"; @@ -5519,15 +5504,15 @@ function fantasyMap() { canvas.height = svgHeight * pngResolutionInput.value; var img = new Image(); img.src = url; - img.onload = function () { + img.onload = function(){ window.URL.revokeObjectURL(url); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); link.download = "fantasy_map_" + Date.now() + ".png"; - canvas.toBlob(function (blob) { - link.href = window.URL.createObjectURL(blob); - document.body.appendChild(link); - link.click(); - window.setTimeout(function () { window.URL.revokeObjectURL(link.href); }, 5000); + canvas.toBlob(function(blob) { + link.href = window.URL.createObjectURL(blob); + document.body.appendChild(link); + link.click(); + window.setTimeout(function() {window.URL.revokeObjectURL(link.href);}, 5000); }); canvas.style.opacity = 0; canvas.width = svgWidth; @@ -5540,7 +5525,7 @@ function fantasyMap() { link.click(); } console.timeEnd("saveAsImage"); - window.setTimeout(function () { window.URL.revokeObjectURL(url); }, 5000); + window.setTimeout(function() {window.URL.revokeObjectURL(url);}, 5000); }); } @@ -5574,17 +5559,17 @@ function fantasyMap() { fontRules.push(fR); 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 => { - return fR.rule.cssText.replace(fR.url, dataURL); + .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 => { + return fR.rule.cssText.replace(fR.url, dataURL); + }) ) } document.head.removeChild(s); // clean up @@ -5599,9 +5584,9 @@ function fantasyMap() { // 5 - svg; 6 - options (see below); 7 - cultures; 8 - nameBase; 9 - nameBases; // size stats: points = 6%, cells = 36%, manors and states = 2%, svg = 56%; const options = customization + "|" + - distanceUnit.value + "|" + distanceScale.value + "|" + areaUnit.value + "|" + - barSize.value + "|" + barLabel.value + "|" + barBackOpacity.value + "|" + barBackColor.value + "|" + - populationRate.value + "|" + urbanization.value; + distanceUnit.value + "|" + distanceScale.value + "|" + areaUnit.value + "|" + + barSize.value + "|" + barLabel.value + "|" + barBackOpacity.value + "|" + barBackColor.value + "|" + + populationRate.value + "|" + urbanization.value; // set zoom / transform values to default svg.attr("width", graphWidth).attr("height", graphHeight); @@ -5616,7 +5601,7 @@ function fantasyMap() { var data = version + line + JSON.stringify(points) + line + JSON.stringify(cells) + line; data += JSON.stringify(manors) + line + JSON.stringify(states) + line + svg_xml + line + options + line; data += JSON.stringify(cultures) + line + JSON.stringify(nameBase) + line + JSON.stringify(nameBases) + line; - var dataBlob = new Blob([data], { type: "text/plain" }); + var dataBlob = new Blob([data], {type:"text/plain"}); var dataURL = window.URL.createObjectURL(dataBlob); var link = document.createElement("a"); link.download = "fantasy_map_" + Date.now() + ".map"; @@ -5630,11 +5615,11 @@ function fantasyMap() { oceanBack.attr("x", oceanShift[0]).attr("y", oceanShift[1]).attr("width", oceanShift[2]).attr("height", oceanShift[3]); console.timeEnd("saveMap"); - window.setTimeout(function () { window.URL.revokeObjectURL(dataURL); }, 4000); + window.setTimeout(function() {window.URL.revokeObjectURL(dataURL);}, 4000); } // Map Loader based on FileSystem API - $("#mapToLoad").change(function () { + $("#mapToLoad").change(function() { console.time("loadMap"); closeDialogs(); var fileToLoad = this.files[0]; @@ -5645,7 +5630,7 @@ function fantasyMap() { function uploadFile(file, callback) { console.time("loadMap"); var fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { + fileReader.onload = function(fileLoadedEvent) { var dataLoaded = fileLoadedEvent.target.result; var data = dataLoaded.split("\r\n"); // data convention: 0 - version; 1 - all points; 2 - cells; 3 - manors; 4 - states; @@ -5655,7 +5640,7 @@ function fantasyMap() { var message = `The Map version `; // mapVersion reference was not added to downloaded map before v. 0.52b, so I cannot support really old files if (mapVersion.length <= 10) { - message += `(${mapVersion}) does not match the Generator version (${version}). The map will be auto-updated. + message += `(${mapVersion}) does not match the Generator version (${version}). The map will be auto-updated. In case of critical issues you may send the .map file to me or just keep using @@ -5667,18 +5652,14 @@ function fantasyMap() { of the Generator. Please note the Gennerator is still on demo and a lot of crusial changes are being made every month`; } alertMessage.innerHTML = message; - $("#alert").dialog({ - title: "Warning", buttons: { - OK: function () { - loadDataFromMap(data); - } - } - }); - } else { loadDataFromMap(data); } - if (mapVersion.length > 10) { console.error("Cannot load map"); return; } + $("#alert").dialog({title: "Warning", buttons: {OK: function() { + loadDataFromMap(data); + }}}); + } else {loadDataFromMap(data);} + if (mapVersion.length > 10) {console.error("Cannot load map"); return;} } fileReader.readAsText(file, "UTF-8"); - if (callback) { callback(); } + if (callback) {callback();} } function loadDataFromMap(data) { @@ -5716,19 +5697,18 @@ function fantasyMap() { const nWidth = +svg.attr("width"), nHeight = +svg.attr("height"); graphWidth = nWidth; graphHeight = nHeight; - voronoi = d3.voronoi().extent([[-1, -1], [graphWidth + 1, graphHeight + 1]]); + voronoi = d3.voronoi().extent([[-1, -1], [graphWidth+1, graphHeight+1]]); zoom.translateExtent([[0, 0], [graphWidth, graphHeight]]).scaleExtent([1, 20]).scaleTo(svg, 1); viewbox.attr("transform", null); // temporary fit loaded svg element to current canvas size svg.attr("width", svgWidth).attr("height", svgHeight); if (nWidth !== svgWidth || nHeight !== svgHeight) { - alertMessage.innerHTML = `The loaded map has size ${nWidth} x ${nHeight} pixels, while the current canvas size is ${svgWidth} x ${svgHeight} pixels. + alertMessage.innerHTML = `The loaded map has size ${nWidth} x ${nHeight} pixels, while the current canvas size is ${svgWidth} x ${svgHeight} pixels. Click "Rescale" to fit the map to the current canvas size. Click "OK" to browse the map without rescaling`; - $("#alert").dialog({ - title: "Map size conflict", + $("#alert").dialog({title: "Map size conflict", buttons: { - Rescale: function () { + Rescale: function() { applyLoadedData(data); // rescale loaded map const xRatio = svgWidth / nWidth; @@ -5742,7 +5722,7 @@ function fantasyMap() { zoom.translateExtent([[0, 0], [nWidth, nHeight]]).scaleExtent([scaleTo, 20]).scaleTo(svg, scaleTo); $(this).dialog("close"); }, - OK: function () { + OK: function() { changeMapSize(); applyLoadedData(data); $(this).dialog("close"); @@ -5787,7 +5767,7 @@ function fantasyMap() { if (!labels.select("#burgLabels").size()) { labels.append("g").attr("id", "burgLabels"); $("#labels #capitals, #labels #towns").detach().appendTo($("#burgLabels")); - labels.select("#burgLabels").selectAll("text").each(function () { + labels.select("#burgLabels").selectAll("text").each(function() { let id = this.getAttribute("id"); if (!id) return; this.removeAttribute("id"); @@ -5802,14 +5782,14 @@ function fantasyMap() { icons.select("#burgIcons").select("#towns").attr("size", .5).attr("fill-opacity", .7).attr("stroke-opacity", 1); } - icons.selectAll("g").each(function (d) { + icons.selectAll("g").each(function(d) { const size = this.getAttribute("font-size"); if (size === undefined) return; this.removeAttribute("font-size"); this.setAttribute("size", size); }); - icons.select("#burgIcons").selectAll("circle").each(function () { + icons.select("#burgIcons").selectAll("circle").each(function() { this.setAttribute("r", this.parentNode.getAttribute("size")); const id = this.getAttribute("id"); if (!id) return; @@ -5817,7 +5797,7 @@ function fantasyMap() { this.setAttribute("data-id", +id.replace("manorIcon", "")); }); - icons.selectAll("use").each(function () { + icons.selectAll("use").each(function() { const size = this.parentNode.getAttribute("size"); this.setAttribute("width", size); this.setAttribute("height", size); @@ -5856,29 +5836,29 @@ function fantasyMap() { newPoints = [], riversData = [], queue = [], elSelected = ""; points = JSON.parse(data[1]); cells = JSON.parse(data[2]); - land = $.grep(cells, function (e) { return (e.height >= 0.2); }); + land = $.grep(cells, function(e) {return (e.height >= 0.2);}); manors = JSON.parse(data[3]); - cells.map(function (e) { newPoints.push(e.data); }); + cells.map(function(e) {newPoints.push(e.data);}); calculateVoronoi(newPoints); - if (data[7]) cultures = JSON.parse(data[7]); + if(data[7]) cultures = JSON.parse(data[7]); if (data[7] === undefined) generateCultures(); - if (data[8]) nameBase = JSON.parse(data[8]); - if (data[8]) nameBases = JSON.parse(data[9]); + if(data[8]) nameBase = JSON.parse(data[8]); + if(data[8]) nameBases = JSON.parse(data[9]); // calculate areas / population for old maps const graphSizeAdj = 90 / Math.sqrt(cells.length, 2); // adjust to different graphSize - land.forEach(function (i) { - const p = i.index; - if (i.pop === undefined) { - let population = 0; - const elevationFactor = Math.pow(1 - i.height, 3); - population = elevationFactor * i.area * graphSizeAdj; - if (i.region === "neutral") population *= 0.5; - i.pop = rn(population, 1); - } - if (!polygons[p] || !polygons[p].length) return; - const area = d3.polygonArea(polygons[p]); - i.area = rn(Math.abs(area), 2); + land.forEach(function(i) { + const p = i.index; + if (i.pop === undefined) { + let population = 0; + const elevationFactor = Math.pow(1 - i.height, 3); + population = elevationFactor * i.area * graphSizeAdj; + if (i.region === "neutral") population *= 0.5; + i.pop = rn(population, 1); + } + if (!polygons[p] || !polygons[p].length) return; + const area = d3.polygonArea(polygons[p]); + i.area = rn(Math.abs(area), 2); }); // restore Heightmap customization mode @@ -5908,13 +5888,13 @@ function fantasyMap() { d3.select("#toggleGrid").classed("buttonoff", grid.style("display") === "none"); // update map to support some old versions and fetch fonts - labels.selectAll("g").each(function (d) { + labels.selectAll("g").each(function(d) { var el = d3.select(this); if (el.attr("id") === "burgLabels") return; var font = el.attr("data-font"); - if (font && fonts.indexOf(font) === -1) { addFonts("https://fonts.googleapis.com/css?family=" + font); } - if (!el.attr("data-size")) { el.attr("data-size", +el.attr("font-size")); } - if (el.style("display") === "none") { el.node().style.display = null; } + if (font && fonts.indexOf(font) === -1) {addFonts("https://fonts.googleapis.com/css?family=" + font);} + if (!el.attr("data-size")) {el.attr("data-size", +el.attr("font-size"));} + if (el.style("display") === "none") {el.node().style.display = null;} }); invokeActiveZooming(); @@ -5925,27 +5905,27 @@ function fantasyMap() { // Source: bl.ocks.org/mbostock/99049112373e12709381; Based on https://www.jasondavies.com/poisson-disc function poissonDiscSampler(width, height, radius) { var k = 5, // maximum number of points before rejection - radius2 = radius * radius, - R = 3 * radius2, - cellSize = radius * Math.SQRT1_2, - gridWidth = Math.ceil(width / cellSize), - gridHeight = Math.ceil(height / cellSize), - grid = new Array(gridWidth * gridHeight), - queue = [], - queueSize = 0, - sampleSize = 0; - return function () { + radius2 = radius * radius, + R = 3 * radius2, + cellSize = radius * Math.SQRT1_2, + gridWidth = Math.ceil(width / cellSize), + gridHeight = Math.ceil(height / cellSize), + grid = new Array(gridWidth * gridHeight), + queue = [], + queueSize = 0, + sampleSize = 0; + return function() { if (!sampleSize) return sample(Math.random() * width, Math.random() * height); // Pick a random existing sample and remove it from the queue while (queueSize) { var i = Math.random() * queueSize | 0, - s = queue[i]; + s = queue[i]; // Make a new candidate between [radius, 2 * radius] from the existing sample. for (let j = 0; j < k; ++j) { var a = 2 * Math.PI * Math.random(), - r = Math.sqrt(Math.random() * R + radius2), - x = s[0] + r * Math.cos(a), - y = s[1] + r * Math.sin(a); + r = Math.sqrt(Math.random() * R + radius2), + x = s[0] + r * Math.cos(a), + y = s[1] + r * Math.sin(a); // Reject candidates that are outside the allowed extent, or closer than 2 * radius to any existing sample if (0 <= x && x < width && 0 <= y && y < height && far(x, y)) return sample(x, y); } @@ -5955,18 +5935,18 @@ function fantasyMap() { }; function far(x, y) { var i = x / cellSize | 0, - j = y / cellSize | 0, - i0 = Math.max(i - 2, 0), - j0 = Math.max(j - 2, 0), - i1 = Math.min(i + 3, gridWidth), - j1 = Math.min(j + 3, gridHeight); - for (let j = j0; j < j1; ++j) { + j = y / cellSize | 0, + i0 = Math.max(i - 2, 0), + j0 = Math.max(j - 2, 0), + i1 = Math.min(i + 3, gridWidth), + j1 = Math.min(j + 3, gridHeight); + for (j = j0; j < j1; ++j) { var o = j * gridWidth; - for (let i = i0; i < i1; ++i) { + for (i = i0; i < i1; ++i) { if (s = grid[o + i]) { var s, - dx = s[0] - x, - dy = s[1] - y; + dx = s[0] - x, + dy = s[1] - y; if (dx * dx + dy * dy < radius2) return false; } } @@ -5984,10 +5964,10 @@ function fantasyMap() { } // Hotkeys - d3.select("body").on("keydown", function () { + d3.select("body").on("keydown", function() { const active = document.activeElement.tagName; if (active === "INPUT" || active === "SELECT" || active === "TEXTAREA") return; - switch (d3.event.keyCode) { + switch(d3.event.keyCode) { case 27: // Escape to close all dialogs closeDialogs(); break; @@ -6045,11 +6025,11 @@ function fantasyMap() { if (d3.event.ctrlKey === false) return; redo.click(); break; - } + } }); // Toggle Options pane - $("#optionsTrigger").on("click", function () { + $("#optionsTrigger").on("click", function() { if (tooltip.getAttribute("data-main") === "Сlick the arrow button to open options") { tooltip.setAttribute("data-main", ""); tooltip.innerHTML = ""; @@ -6065,13 +6045,12 @@ function fantasyMap() { $("#optionsTrigger").removeClass("icon-left-open").addClass("icon-right-open"); } }); - $("#collapsible").hover(function () { + $("#collapsible").hover(function() { if ($("#optionsTrigger").hasClass("glow")) return; if ($("#options").css("display") === "none") { $("#regenerate").show(); $("#optionsTrigger").removeClass("glow"); - } - }, function () { + }}, function() { $("#regenerate").hide(); }); @@ -6081,36 +6060,36 @@ function fantasyMap() { if (el) { var prev = getLayer(ui.item.prev().attr("id")); var next = getLayer(ui.item.next().attr("id")); - if (prev) { el.insertAfter(prev); } else if (next) { el.insertBefore(next); } + if (prev) {el.insertAfter(prev);} else if (next) {el.insertBefore(next);} } } // define connection between option layer buttons and actual svg groups function getLayer(id) { - if (id === "toggleGrid") { return $("#grid"); } - if (id === "toggleOverlay") { return $("#overlay"); } - if (id === "toggleHeight") { return $("#terrs"); } - if (id === "toggleCultures") { return $("#cults"); } - if (id === "toggleRoutes") { return $("#routes"); } - if (id === "toggleRivers") { return $("#rivers"); } - if (id === "toggleCountries") { return $("#regions"); } - if (id === "toggleBorders") { return $("#borders"); } - if (id === "toggleRelief") { return $("#terrain"); } - if (id === "toggleLabels") { return $("#labels"); } - if (id === "toggleIcons") { return $("#icons"); } + if (id === "toggleGrid") {return $("#grid");} + if (id === "toggleOverlay") {return $("#overlay");} + if (id === "toggleHeight") {return $("#terrs");} + if (id === "toggleCultures") {return $("#cults");} + if (id === "toggleRoutes") {return $("#routes");} + if (id === "toggleRivers") {return $("#rivers");} + if (id === "toggleCountries") {return $("#regions");} + if (id === "toggleBorders") {return $("#borders");} + if (id === "toggleRelief") {return $("#terrain");} + if (id === "toggleLabels") {return $("#labels");} + if (id === "toggleIcons") {return $("#icons");} } // UI Button handlers - $("button, a, li, i").on("click", function () { + $("button, a, li, i").on("click", function() { var id = this.id; var parent = this.parentNode.id; - if (debug.selectAll(".tag").size()) { debug.selectAll(".tag, .line").remove(); } - if (id === "toggleHeight") { toggleHeight(); } - if (id === "toggleCountries") { $('#regions').fadeToggle(); } - if (id === "toggleCultures") { toggleCultures(); } - if (id === "toggleOverlay") { toggleOverlay(); } - if (id === "toggleFlux") { toggleFlux(); } - if (parent === "mapLayers" || parent === "styleContent") { $(this).toggleClass("buttonoff"); } + if (debug.selectAll(".tag").size()) {debug.selectAll(".tag, .line").remove();} + if (id === "toggleHeight") {toggleHeight();} + if (id === "toggleCountries") {$('#regions').fadeToggle();} + if (id === "toggleCultures") {toggleCultures();} + if (id === "toggleOverlay") {toggleOverlay();} + if (id === "toggleFlux") {toggleFlux();} + if (parent === "mapLayers" || parent === "styleContent") {$(this).toggleClass("buttonoff");} if (id === "randomMap" || id === "regenerate") { exitCustomization(); undraw(); @@ -6118,9 +6097,9 @@ function fantasyMap() { generate(); return; } - if (id === "editCountries") { editCountries(); } - if (id === "editCultures") { editCultures(); } - if (id === "editScale" || id === "editScaleCountries" || id === "editScaleBurgs") { editScale(); } + if (id === "editCountries") {editCountries();} + if (id === "editCultures") {editCultures();} + if (id === "editScale" || id === "editScaleCountries" || id === "editScaleBurgs") {editScale();} if (id === "countriesManually") { customization = 2; tip("Click to select a country, drag the circle to re-assign", true); @@ -6129,7 +6108,7 @@ function fantasyMap() { $("#countriesBottom").children().hide(); $("#countriesManuallyButtons").show(); // highlight capital cells as it's not allowed to change capital's state that way - states.map(function (s) { + states.map(function(s) { if (s.capital === "neutral" || s.capital === "select") return; const capital = s.capital; const index = manors[capital].cell; @@ -6154,32 +6133,32 @@ function fantasyMap() { debug.selectAll(".circle").remove(); var changedCells = regions.select("#temp").selectAll("path"); var changedStates = []; - changedCells.each(function () { + changedCells.each(function() { var el = d3.select(this); var cell = +el.attr("data-cell"); var stateOld = cells[cell].region; - if (stateOld === "neutral") { stateOld = states.length - 1; } + if (stateOld === "neutral") {stateOld = states.length - 1;} var stateNew = +el.attr("data-state"); const region = states[stateNew].color === "neutral" ? "neutral" : stateNew; cells[cell].region = region; - if (cells[cell].manor !== undefined) { manors[cells[cell].manor].region = region; } + if (cells[cell].manor !== undefined) {manors[cells[cell].manor].region = region;} changedStates.push(stateNew, stateOld); }); changedStates = [...new Set(changedStates)]; - changedStates.map(function (s) { recalculateStateData(s); }); + changedStates.map(function(s) {recalculateStateData(s);}); var last = states.length - 1; if (states[last].capital === "neutral" && states[last].cells === 0) { $("#state" + last).remove(); states.splice(-1); } $("#countriesManuallyCancel").click(); - if (changedStates.length) { editCountries(); } + if (changedStates.length) {editCountries();} } if (id === "countriesManuallyCancel") { redrawRegions(); debug.selectAll(".circle").remove(); - if (grid.style("display") === "inline") { toggleGrid.click(); } - if (labels.style("display") === "none") { toggleLabels.click(); } + if (grid.style("display") === "inline") {toggleGrid.click();} + if (labels.style("display") === "none") {toggleLabels.click();} $("#countriesBottom").children().show(); $("#countriesManuallyButtons, #countriesRegenerateButtons").hide(); $(".selected").removeClass("selected"); @@ -6189,10 +6168,10 @@ function fantasyMap() { tip("", true); restoreDefaultEvents(); } - if (id === "countriesApply") { $("#countriesManuallyCancel").click(); } + if (id === "countriesApply") {$("#countriesManuallyCancel").click();} if (id === "countriesRandomize") { const mod = +powerInput.value * 2; - $(".statePower").each(function (e, i) { + $(".statePower").each(function(e, i) { const state = +(this.parentNode.id).slice(5); if (states[state].capital === "neutral") return; const power = rn(Math.random() * mod / 2 + 1, 1); @@ -6205,20 +6184,20 @@ function fantasyMap() { if (id === "countriesAddM" || id === "countriesAddR" || id === "countriesAddG") { var i = states.length; // move neutrals to the last line - if (states[i - 1].capital === "neutral") { states[i - 1].i = i; i -= 1; } + if (states[i-1].capital === "neutral") {states[i-1].i = i; i -= 1;} var name = generateStateName(0); var color = colors20(i); - states.push({ i, color, name, capital: "select", cells: 0, burgs: 0, urbanPopulation: 0, ruralPopulation: 0, area: 0, power: 1 }); - states.sort(function (a, b) { return a.i - b.i }); + states.push({i, color, name, capital: "select", cells: 0, burgs: 0, urbanPopulation: 0, ruralPopulation: 0, area: 0, power: 1}); + states.sort(function(a, b){return a.i - b.i}); editCountries(); } if (id === "countriesRegenerateNames") { const editor = d3.select("#countriesBody"); - states.forEach(function (s) { + states.forEach(function(s) { if (s.capital === "neutral") return; s.name = generateStateName(s.i); - labels.select("#regionLabel" + s.i).text(s.name); - editor.select("#state" + s.i).select(".stateName").attr("value", s.name); + labels.select("#regionLabel"+s.i).text(s.name); + editor.select("#state"+s.i).select(".stateName").attr("value", s.name); }); } if (id === "countriesPercentage") { @@ -6230,7 +6209,7 @@ function fantasyMap() { var totalArea = countriesFooterArea.innerHTML; totalArea = getInteger(totalArea.split(" ")[0]); var totalPopulation = getInteger(countriesFooterPopulation.innerHTML); - $("#countriesBody > .states").each(function () { + $("#countriesBody > .states").each(function() { var cells = rn($(this).attr("data-cells") / totalCells * 100); var burgs = rn($(this).attr("data-burgs") / totalBurgs * 100); var area = rn($(this).attr("data-area") / totalArea * 100); @@ -6246,14 +6225,14 @@ function fantasyMap() { } } if (id === "countriesExport") { - if ($(".statePower").length === 0) { return; } + if ($(".statePower").length === 0) {return;} var unit = areaUnit.value === "square" ? distanceUnit.value + "2" : areaUnit.value; - var data = "Country,Capital,Cells,Burgs,Area (" + unit + "),Population\n"; // countries headers - $("#countriesBody > .states").each(function () { + var data = "Country,Capital,Cells,Burgs,Area ("+ unit +"),Population\n"; // countries headers + $("#countriesBody > .states").each(function() { var country = $(this).attr("data-country"); - if (country === "bottom") { data += "neutral," } else { data += country + ","; } + if (country === "bottom") {data += "neutral,"} else {data += country + ",";} var capital = $(this).attr("data-capital"); - if (capital === "bottom" || capital === "select") { data += "," } else { data += capital + ","; } + if (capital === "bottom" || capital === "select") {data += ","} else {data += capital + ",";} data += $(this).attr("data-cells") + ","; data += $(this).attr("data-burgs") + ","; data += $(this).attr("data-area") + ","; @@ -6261,7 +6240,7 @@ function fantasyMap() { data += population + "\n"; }); data += "\nBurg,Country,Culture,Population\n"; // burgs headers - manors.map(function (m) { + manors.map(function(m) { if (m.region === "removed") return; // skip removed burgs data += m.name + ","; var country = m.region === "neutral" ? "neutral" : states[m.region].name; @@ -6270,28 +6249,27 @@ function fantasyMap() { var population = m.population * urbanization.value * populationRate.value * 1000; data += population + "\n"; }); - var dataBlob = new Blob([data], { type: "text/plain" }); + var dataBlob = new Blob([data], {type:"text/plain"}); var url = window.URL.createObjectURL(dataBlob); var link = document.createElement("a"); document.body.appendChild(link); link.download = "countries_data" + Date.now() + ".csv"; link.href = url; link.click(); - window.setTimeout(function () { window.URL.revokeObjectURL(url); }, 2000); + window.setTimeout(function() {window.URL.revokeObjectURL(url);}, 2000); } - if (id === "burgNamesImport") { burgsListToLoad.click(); } + if (id === "burgNamesImport") {burgsListToLoad.click();} if (id === "removeCountries") { alertMessage.innerHTML = `Are you sure you want remove all countries?`; - $("#alert").dialog({ - resizable: false, title: "Remove countries", + $("#alert").dialog({resizable: false, title: "Remove countries", buttons: { - Cancel: function () { $(this).dialog("close"); }, - Remove: function () { + Cancel: function() {$(this).dialog("close");}, + Remove: function() { $(this).dialog("close"); $("#countriesBody").empty(); - manors.map(function (m) { m.region = "neutral"; }); - land.map(function (l) { l.region = "neutral"; }); - states.map(function (s) { + manors.map(function(m) {m.region = "neutral";}); + land.map(function(l) {l.region = "neutral";}); + states.map(function(s) { const c = +s.capital; if (isNaN(c)) return; $("#burgLabels [data-id=" + c + "]").detach().appendTo($("#burgLabels #towns")); @@ -6300,9 +6278,9 @@ function fantasyMap() { labels.select("#countries").selectAll("text").remove(); regions.selectAll("path").remove(); states = []; - states.push({ i: 0, color: "neutral", capital: "neutral", name: "Neutrals" }); + states.push({i: 0, color: "neutral", capital: "neutral", name: "Neutrals"}); recalculateStateData(0); - if ($("#burgsEditor").is(":visible")) { $("#burgsEditor").dialog("close"); } + if ($("#burgsEditor").is(":visible")) {$("#burgsEditor").dialog("close");} editCountries(); } } @@ -6310,17 +6288,16 @@ function fantasyMap() { } if (id === "removeBurgs") { alertMessage.innerHTML = `Are you sure you want to remove all burgs associated with the country?`; - $("#alert").dialog({ - resizable: false, title: "Remove associated burgs", + $("#alert").dialog({resizable: false, title: "Remove associated burgs", buttons: { - Cancel: function () { $(this).dialog("close"); }, - Remove: function () { + Cancel: function() {$(this).dialog("close");}, + Remove: function() { $(this).dialog("close"); var state = +$("#burgsEditor").attr("data-state"); var region = states[state].capital === "neutral" ? "neutral" : state; $("#burgsBody").empty(); - manors.map(function (m) { - if (m.region !== region) { return; } + manors.map(function(m) { + if (m.region !== region) {return;} m.region = "removed"; cells[m.cell].manor = undefined; labels.select("[data-id='" + m.i + "']").remove(); @@ -6349,7 +6326,7 @@ function fantasyMap() { } if (id === "regenerateBurgNames") { var s = +$("#burgsEditor").attr("data-state"); - $(".burgName").each(function (e, i) { + $(".burgName").each(function(e, i) { var b = +(this.parentNode.id).slice(5); var name = generateName(manors[b].culture); $(this).val(name); @@ -6358,10 +6335,10 @@ function fantasyMap() { labels.select("[data-id='" + b + "']").text(name); }); if ($("#countriesEditor").is(":visible")) { - if (states[s].capital === "neutral") { return; } + if (states[s].capital === "neutral") {return;} var c = states[s].capital; - $("#state" + s).attr("data-capital", manors[c].name); - $("#state" + s + " > .stateCapital").val(manors[c].name); + $("#state"+s).attr("data-capital", manors[c].name); + $("#state"+s+" > .stateCapital").val(manors[c].name); } } if (id === "burgAdd") { @@ -6369,7 +6346,7 @@ function fantasyMap() { clickToAdd(); // to load on click event function $("#addBurg").click().attr("data-state", state); } - if (id === "toggleScaleBar") { $("#scaleBar").toggleClass("hidden"); } + if (id === "toggleScaleBar") {$("#scaleBar").toggleClass("hidden");} if (id === "addRuler") { $("#ruler").show(); var rulerNew = ruler.append("g").attr("class", "linear").call(d3.drag().on("start", elementDrag)); @@ -6398,28 +6375,26 @@ function fantasyMap() { return; } if (id === "removeAllRulers") { - if ($("#ruler > g").length < 1) { return; } + if ($("#ruler > g").length < 1) {return;} alertMessage.innerHTML = `Are you sure you want to remove all placed rulers?`; - $("#alert").dialog({ - resizable: false, title: "Remove all rulers", + $("#alert").dialog({resizable: false, title: "Remove all rulers", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); $("#ruler > g").remove(); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }); return; } - if (id === "editHeightmap") { $("#customizeHeightmap").slideToggle(); } + if (id === "editHeightmap") {$("#customizeHeightmap").slideToggle();} if (id === "fromScratch") { alertMessage.innerHTML = "Are you sure you want to clear the map? All progress will be lost"; - $("#alert").dialog({ - resizable: false, title: "Clear map", + $("#alert").dialog({resizable: false, title: "Clear map", buttons: { - Cancel: function () { $(this).dialog("close"); }, - Clear: function () { + Cancel: function() {$(this).dialog("close");}, + Clear: function() { closeDialogs(); undraw(); placePoints(); @@ -6438,43 +6413,42 @@ function fantasyMap() { message += "If you want to edit a map, it's better to clean up all the data except on heights. "; message += "You may also keep the data, but it can cause unexpected errors"; alertMessage.innerHTML = message; - $("#alert").dialog({ - resizable: false, title: "Edit Heightmap", + $("#alert").dialog({resizable: false, title: "Edit Heightmap", buttons: { - "Clean up": function () { + "Clean up": function() { editHeightmap("clean"); $(this).dialog("close"); }, - Keep: function () { + Keep: function() { $(this).dialog("close"); editHeightmap("keep"); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }); return; } // heightmap customization buttons if (customization === 1) { - if (id === "paintBrushes") { openBrushesPanel(); } + if (id === "paintBrushes") {openBrushesPanel();} if (id === "rescaleExecute") { var subject = rescaleLower.value + "-" + rescaleHigher.value; var sign = conditionSign.value; var modifier = rescaleModifier.value; - if (sign === "×") { modifyHeights(subject, 0, +modifier); } - if (sign === "÷") { modifyHeights(subject, 0, (1 / modifier)); } - if (sign === "+") { modifyHeights(subject, +modifier, 1); } - if (sign === "-") { modifyHeights(subject, (-1 * modifier), 1); } - if (sign === "^") { modifyHeights(subject, 0, "^" + modifier); } + if (sign === "×") {modifyHeights(subject, 0, +modifier);} + if (sign === "÷") {modifyHeights(subject, 0, (1 / modifier));} + if (sign === "+") {modifyHeights(subject, +modifier, 1);} + if (sign === "-") {modifyHeights(subject, (-1 * modifier), 1);} + if (sign === "^") {modifyHeights(subject, 0, "^" + modifier);} updateHeightmap(); updateHistory(); } if (id === "rescaleButton") { $("#modifyButtons").children().not("#rescaleButton, .condition").toggle(); } - if (id === "rescaleCondButton") { $("#modifyButtons").children().not("#rescaleCondButton, #rescaler").toggle(); } - if (id === "undo" || id === "templateUndo") { restoreHistory(historyStage - 1); } - if (id === "redo" || id === "templateRedo") { restoreHistory(historyStage + 1); } + if (id === "rescaleCondButton") {$("#modifyButtons").children().not("#rescaleCondButton, #rescaler").toggle();} + if (id === "undo" || id === "templateUndo") {restoreHistory(historyStage - 1);} + if (id === "redo" || id === "templateRedo") {restoreHistory(historyStage + 1);} if (id === "smoothHeights") { smoothHeights(4); updateHeightmap(); @@ -6486,56 +6460,56 @@ function fantasyMap() { updateHistory(); } if (id === "getMap") { - if (states.length && manors.length) { getMap("keep"); } else { getMap(); } + if (states.length && manors.length) {getMap("keep");} else {getMap();} } if (id === "applyTemplate") { - if ($("#templateEditor").is(":visible")) { return; } + if ($("#templateEditor").is(":visible")) {return;} $("#templateEditor").dialog({ title: "Template Editor", minHeight: "auto", width: "auto", resizable: false, - position: { my: "right top", at: "right-10 top+10", of: "svg" } + position: {my: "right top", at: "right-10 top+10", of: "svg"} }); } - if (id === "convertImage") { convertImage(); } - if (id === "convertImageGrid") { $("#grid").fadeToggle(); } - if (id === "convertImageHeights") { $("#landmass").fadeToggle(); } + if (id === "convertImage") {convertImage();} + if (id === "convertImageGrid") {$("#grid").fadeToggle();} + if (id === "convertImageHeights") {$("#landmass").fadeToggle();} if (id === "perspectiveView") { // Inputs control - if ($("#perspectivePanel").is(":visible")) { return; } + if ($("#perspectivePanel").is(":visible")) {return;} const line = +$("#lineHandle0").attr("data-value"); const grad = +$("#lineHandle1").attr("data-value"); $("#lineSlider").slider({ min: 10, max: 320, step: 1, values: [line, grad], - create: function () { - $("#lineHandle0").text("x:" + line); - $("#lineHandle1").text("y:" + grad); + create: function() { + $("#lineHandle0").text("x:"+line); + $("#lineHandle1").text("y:"+grad); }, - slide: function (event, ui) { - $("#lineHandle0").text("x:" + ui.values[0]).attr("data-value", ui.values[0]); - $("#lineHandle1").text("y:" + ui.values[1]).attr("data-value", ui.values[1]); + slide: function(event, ui) { + $("#lineHandle0").text("x:"+ui.values[0]).attr("data-value", ui.values[0]); + $("#lineHandle1").text("y:"+ui.values[1]).attr("data-value", ui.values[1]); drawPerspective(); } }); $("#ySlider").slider({ min: 1, max: 5, step: 0.1, value: +$("#yHandle").attr("data-value"), - create: function () { $("#yHandle").text($("#yHandle").attr("data-value")); }, - slide: function (event, ui) { + create: function() {$("#yHandle").text($("#yHandle").attr("data-value"));}, + slide: function(event, ui) { $("#yHandle").text(ui.value).attr("data-value", ui.value); drawPerspective(); } }); $("#scaleSlider").slider({ min: 0.5, max: 2, step: 0.1, value: +$("#scaleHandle").attr("data-value"), - create: function () { $("#scaleHandle").text($("#scaleHandle").attr("data-value")); }, - slide: function (event, ui) { + create: function() {$("#scaleHandle").text($("#scaleHandle").attr("data-value"));}, + slide: function(event, ui) { $("#scaleHandle").text(ui.value).attr("data-value", ui.value); drawPerspective(); } }); $("#heightSlider").slider({ min: 1, max: 50, step: 1, value: +$("#heightHandle").attr("data-value"), - create: function () { $("#heightHandle").text($("#heightHandle").attr("data-value")); }, - slide: function (event, ui) { + create: function() {$("#heightHandle").text($("#heightHandle").attr("data-value"));}, + slide: function(event, ui) { $("#heightHandle").text(ui.value).attr("data-value", ui.value); drawPerspective(); } @@ -6543,7 +6517,7 @@ function fantasyMap() { $("#perspectivePanel").dialog({ title: "Perspective View", width: 520, height: 360, - position: { my: "center center", at: "center center", of: "svg" } + position: {my: "center center", at: "center center", of: "svg"} }); drawPerspective(); return; @@ -6551,14 +6525,13 @@ function fantasyMap() { } if (id === "restoreStyle") { alertMessage.innerHTML = "Are you sure you want to restore default style?"; - $("#alert").dialog({ - resizable: false, title: "Restore style", + $("#alert").dialog({resizable: false, title: "Restore style", buttons: { - Restore: function () { + Restore: function() { applyDefaultStyle(); $(this).dialog("close"); }, - Cancel: function () { + Cancel: function() { $(this).dialog("close"); } } @@ -6587,26 +6560,26 @@ function fantasyMap() { zoomExtentMax.value = 20; zoom.scaleExtent([1, 20]).scaleTo(svg, 1); } - if (id === "saveButton") { $("#saveDropdown").slideToggle(); } - if (id === "loadMap") { mapToLoad.click(); } - if (id === "zoomReset") { resetZoom(1000); } + if (id === "saveButton") {$("#saveDropdown").slideToggle();} + if (id === "loadMap") {mapToLoad.click();} + if (id === "zoomReset") {resetZoom(1000);} if (id === "zoomPlus") { scale += 1; - if (scale > 40) { scale = 40; } + if (scale > 40) {scale = 40;} invokeActiveZooming(); } if (id === "zoomMinus") { scale -= 1; - if (scale <= 1) { scale = 1; viewX = 0; viewY = 0; } + if (scale <= 1) {scale = 1; viewX = 0; viewY = 0;} invokeActiveZooming(); } if (id === "styleFontPlus" || id === "styleFontMinus") { - var el = viewbox.select("#" + styleElementSelect.value); + var el = viewbox.select("#"+styleElementSelect.value); var mod = id === "styleFontPlus" ? 1.1 : 0.9; - el.selectAll("g").each(function () { + el.selectAll("g").each(function() { var el = d3.select(this); var size = rn(el.attr("data-size") * mod, 2); - if (size < 2) { size = 2; } + if (size < 2) {size = 2;} el.attr("data-size", size).attr("font-size", rn((size + (size / scale)) / 2, 2)); }); invokeActiveZooming(); @@ -6616,23 +6589,22 @@ function fantasyMap() { if (customization === 1) { var message = "Are you sure you want to clear the map?"; alertMessage.innerHTML = message; - $("#alert").dialog({ - resizable: false, title: "Clear map", + $("#alert").dialog({resizable: false, title: "Clear map", buttons: { - Clear: function () { + Clear: function() { $(this).dialog("close"); viewbox.style("cursor", "crosshair").call(drag); landmassCounter.innerHTML = "0"; $("#landmass").empty(); - cells.map(function (i) { i.height = 0; }); + cells.map(function(i) {i.height = 0;}); // clear history history = []; historyStage = 0; updateHistory(); redo.disabled = templateRedo.disabled = true; - undo.disabled = templateUndo.disabled = true; + undo.disabled = templateUndo.disabled = true; }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }); } else { @@ -6640,30 +6612,30 @@ function fantasyMap() { } } if (id === "templateComplete") { - if (customization === 1 && !$("#getMap").attr("disabled")) { getMap(); } + if (customization === 1 && !$("#getMap").attr("disabled")) {getMap();} } if (id === "convertColorsMinus") { var current = +convertColors.value - 1; - if (current < 4) { current = 3; } + if (current < 4) {current = 3;} convertColors.value = current; heightsFromImage(current); } if (id === "convertColorsPlus") { var current = +convertColors.value + 1; - if (current > 255) { current = 256; } + if (current > 255) {current = 256;} convertColors.value = current; heightsFromImage(current); } if (id === "convertOverlayButton") { $("#convertImageButtons").children().not(this).not("#convertColors").toggle(); } - if (id === "convertAutoLum") { autoAssing("lum"); } - if (id === "convertAutoHue") { autoAssing("hue"); } - if (id === "convertComplete") { completeConvertion(); } + if (id === "convertAutoLum") {autoAssing("lum");} + if (id === "convertAutoHue") {autoAssing("hue");} + if (id === "convertComplete") {completeConvertion();} }); // support save options - $("#saveDropdown > div").click(function () { + $("#saveDropdown > div").click(function() { var id = this.id; var dns_allow_popup_message = localStorage.getItem("dns_allow_popup_message"); if (!dns_allow_popup_message) { @@ -6671,33 +6643,32 @@ function fantasyMap() { message += "Please ensure your browser does not block popups. "; message += "Please check browser settings and turn off adBlocker if it is enabled"; alertMessage.innerHTML = message; - $("#alert").dialog({ - title: "File saver. Please enable popups!", + $("#alert").dialog({title: "File saver. Please enable popups!", buttons: { - "Don't show again": function () { + "Don't show again": function() { localStorage.setItem("dns_allow_popup_message", true); $(this).dialog("close"); }, - Close: function () { $(this).dialog("close"); } + Close: function() {$(this).dialog("close");} }, - position: { my: "center", at: "center", of: "svg" } + position: {my: "center", at: "center", of: "svg"} }); } - if (id === "saveMap") { saveMap(); } - if (id === "saveSVG") { saveAsImage("svg"); } - if (id === "savePNG") { saveAsImage("png"); } + if (id === "saveMap") {saveMap();} + if (id === "saveSVG") {saveAsImage("svg");} + if (id === "savePNG") {saveAsImage("png");} $("#saveDropdown").slideUp("fast"); }); // lock / unlock option randomization - $("#options i[class^='icon-lock']").click(function () { + $("#options i[class^='icon-lock']").click(function() { $(this).toggleClass("icon-lock icon-lock-open"); const locked = +$(this).hasClass("icon-lock"); $(this).attr("data-locked", locked); const option = (this.id).slice(4, -5).toLowerCase(); - const value = $("#" + option + "Input").val(); - if (locked) { localStorage.setItem(option, value); } - else { localStorage.removeItem(option); } + const value = $("#"+option+"Input").val(); + if (locked) {localStorage.setItem(option, value);} + else {localStorage.removeItem(option);} }); function editHeightmap(type) { @@ -6717,7 +6688,7 @@ function fantasyMap() { calculateVoronoi(points); detectNeighbors("grid"); drawScaleBar(); - for (let i = 0; i < points.length; i++) { cells[i].height = heights[i]; } + for (let i = 0; i < points.length; i++) {cells[i].height = heights[i];} if (type === "keep") { svg.selectAll("#lakes, #coastline, #terrain, #rivers, #grid, #terrs, #landmass, #ocean, #regions") .selectAll("path, circle, line").remove(); @@ -6733,12 +6704,12 @@ function fantasyMap() { } function openBrushesPanel() { - if ($("#brushesPanel").is(":visible")) { return; } + if ($("#brushesPanel").is(":visible")) {return;} $("#brushesPanel").dialog({ title: "Paint Brushes", minHeight: 40, width: "auto", maxWidth: 200, resizable: false, - position: { my: "right top", at: "right-10 top+10", of: "svg" } - }).on('dialogclose', function () { + position: {my: "right top", at: "right-10 top+10", of: "svg"} + }).on('dialogclose', function() { restoreDefaultEvents(); $("#brushesButtons > .pressed").removeClass('pressed'); }); @@ -6746,7 +6717,7 @@ function fantasyMap() { if (modules.openBrushesPanel) return; modules.openBrushesPanel = true; - $("#brushesButtons > button").on("click", function () { + $("#brushesButtons > button").on("click", function() { const rSlider = $("#brushRadiusLabel, #brushRadius"); debug.selectAll(".circle, .tag, .line").remove(); if ($(this).hasClass('pressed')) { @@ -6758,10 +6729,10 @@ function fantasyMap() { $(this).addClass('pressed'); viewbox.style("cursor", "crosshair"); const id = this.id; - if (id === "brushRange" || id === "brushTrough") { viewbox.on("click", placeLinearFeature); } // on click brushes - else { viewbox.call(drag).on("click", null); } // on drag brushes - if ($(this).hasClass("feature")) { rSlider.attr("disabled", true).addClass("disabled"); } - else { rSlider.attr("disabled", false).removeClass("disabled"); } + if (id === "brushRange" || id === "brushTrough") {viewbox.on("click", placeLinearFeature);} // on click brushes + else {viewbox.call(drag).on("click", null);} // on drag brushes + if ($(this).hasClass("feature")) {rSlider.attr("disabled", true).addClass("disabled");} + else {rSlider.attr("disabled", false).removeClass("disabled");} } }); } @@ -6784,7 +6755,7 @@ function fantasyMap() { while (j--) { const y = j / lineGranularity * height | 0; let h = getHeightInPoint(x * wRatio, y * hRatio) - 0.2; - if (h < 0) { h = 0; } + if (h < 0) {h = 0;} canvasPoints.push([x, y, h]); } } @@ -6798,7 +6769,7 @@ function fantasyMap() { pContext.moveTo(...transformPt(pt1)); pContext.lineTo(...transformPt(pt2)); let clr = "rgb(81, 103, 169)"; // water - if (avHeight !== 0) { clr = color(1 - avHeight - 0.2); } + if (avHeight !== 0) {clr = color(1 - avHeight - 0.2);} pContext.strokeStyle = clr; pContext.stroke(); } @@ -6826,12 +6797,12 @@ function fantasyMap() { } // templateEditor Button handlers - $("#templateTools > button").on("click", function () { + $("#templateTools > button").on("click", function() { var id = this.id; id = id.replace("template", ""); if (id === "Mountain") { var steps = $("#templateBody > div").length; - if (steps > 0) { return; } + if (steps > 0) {return;} } $("#templateBody").attr("data-changed", 1); $("#templateBody").append('
' + id + '
'); @@ -6858,9 +6829,9 @@ function fantasyMap() { var count = ''; } el.append(''); - $("#templateBody .icon-trash-empty").on("click", function () { $(this).parent().remove(); }); - if (dist) { el.append(dist); } - if (count) { el.append(count); } + $("#templateBody .icon-trash-empty").on("click", function() {$(this).parent().remove();}); + if (dist) {el.append(dist);} + if (count) {el.append(count);} el.find("select.templateElDist").on("input", fireTemplateElDist); $("#templateBody").attr("data-changed", 1); }); @@ -6877,20 +6848,19 @@ function fantasyMap() { } // templateSelect on change listener - $("#templateSelect").on("input", function () { + $("#templateSelect").on("input", function() { var steps = $("#templateBody > div").length; var changed = +$("#templateBody").attr("data-changed"); var template = this.value; if (steps && changed === 1) { alertMessage.innerHTML = "Are you sure you want to change the base template? All the changes will be lost."; - $("#alert").dialog({ - resizable: false, title: "Change Template", + $("#alert").dialog({resizable: false, title: "Change Template", buttons: { - Change: function () { + Change: function() { changeTemplate(template); $(this).dialog("close"); }, - Cancel: function () { + Cancel: function() { var prev = $("#templateSelect").attr("data-prev"); $("#templateSelect").val(prev); $(this).dialog("close"); @@ -6898,7 +6868,7 @@ function fantasyMap() { } }); } - if (steps === 0 || changed === 0) { changeTemplate(template); } + if (steps === 0 || changed === 0) {changeTemplate(template);} }); function changeTemplate(template) { @@ -6965,17 +6935,17 @@ function fantasyMap() { // interprete template function function addStep(feature, count, dist) { - if (!feature) { return; } - if (feature === "Mountain") { templateMountain.click(); } - if (feature === "Hill") { templateHill.click(); } - if (feature === "Pit") { templatePit.click(); } - if (feature === "Range") { templateRange.click(); } - if (feature === "Trough") { templateTrough.click(); } - if (feature === "Strait") { templateStrait.click(); } - if (feature === "Add") { templateAdd.click(); } - if (feature === "Multiply") { templateMultiply.click(); } - if (feature === "Smooth") { templateSmooth.click(); } - if (count) { $("#templateBody div:last-child .templateElCount").val(count); } + if (!feature) {return;} + if (feature === "Mountain") {templateMountain.click();} + if (feature === "Hill") {templateHill.click();} + if (feature === "Pit") {templatePit.click();} + if (feature === "Range") {templateRange.click();} + if (feature === "Trough") {templateTrough.click();} + if (feature === "Strait") {templateStrait.click();} + if (feature === "Add") {templateAdd.click();} + if (feature === "Multiply") {templateMultiply.click();} + if (feature === "Smooth") {templateSmooth.click();} + if (count) {$("#templateBody div:last-child .templateElCount").val(count);} if (dist) { if (dist !== "land") { var option = ''; @@ -6986,14 +6956,14 @@ function fantasyMap() { } // Execute custom template - $("#templateRun").on("click", function () { - if (customization !== 1) { return; } + $("#templateRun").on("click", function() { + if (customization !== 1) {return;} var steps = $("#templateBody > div").length; - if (steps) { cells.map(function (i) { i.height = 0; }); } - for (let step = 1; step <= steps; step++) { + if (steps) {cells.map(function(i) {i.height = 0;});} + for (let step=1; step <= steps; step++) { var element = $("#templateBody div:nth-child(" + step + ")"); var type = element.attr("data-type"); - if (type === "Mountain") { addMountain(); continue; } + if (type === "Mountain") {addMountain(); continue;} var count = $("#templateBody div:nth-child(" + step + ") .templateElCount").val(); var dist = $("#templateBody div:nth-child(" + step + ") .templateElDist").val(); if (count) { @@ -7004,32 +6974,32 @@ function fantasyMap() { count = +count; // parse string } } - if (type === "Hill") { addHill(count, +dist); } - if (type === "Pit") { addPit(count); } - if (type === "Range") { addRange(count); } - if (type === "Trough") { addRange(-1 * count); } - if (type === "Strait") { addStrait(count); } - if (type === "Add") { modifyHeights(dist, count, 1); } - if (type === "Multiply") { modifyHeights(dist, 0, count); } - if (type === "Smooth") { smoothHeights(count); } + if (type === "Hill") {addHill(count, +dist);} + if (type === "Pit") {addPit(count);} + if (type === "Range") {addRange(count);} + if (type === "Trough") {addRange(-1 * count);} + if (type === "Strait") {addStrait(count);} + if (type === "Add") {modifyHeights(dist, count, 1);} + if (type === "Multiply") {modifyHeights(dist, 0, count);} + if (type === "Smooth") {smoothHeights(count);} } - if (steps) { mockHeightmap(); updateHistory(); } + if (steps) {mockHeightmap(); updateHistory();} }); // Save custom template as text file - $("#templateSave").on("click", function () { + $("#templateSave").on("click", function() { var steps = $("#templateBody > div").length; var stepsData = ""; - for (let step = 1; step <= steps; step++) { + for (let step=1; step <= steps; step++) { var element = $("#templateBody div:nth-child(" + step + ")"); var type = element.attr("data-type"); var count = $("#templateBody div:nth-child(" + step + ") .templateElCount").val(); var dist = $("#templateBody div:nth-child(" + step + ") .templateElDist").val(); - if (!count) { count = "0"; } - if (!dist) { dist = "0"; } + if (!count) {count = "0";} + if (!dist) {dist = "0";} stepsData += type + " " + count + " " + dist + "\r\n"; } - var dataBlob = new Blob([stepsData], { type: "text/plain" }); + var dataBlob = new Blob([stepsData], {type:"text/plain"}); var url = window.URL.createObjectURL(dataBlob); var link = document.createElement("a"); link.download = "template_" + Date.now() + ".txt"; @@ -7039,12 +7009,12 @@ function fantasyMap() { }); // Load custom template as text file - $("#templateLoad").on("click", function () { templateToLoad.click(); }); - $("#templateToLoad").change(function () { + $("#templateLoad").on("click", function() {templateToLoad.click();}); + $("#templateToLoad").change(function() { var fileToLoad = this.files[0]; this.value = ""; var fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { + fileReader.onload = function(fileLoadedEvent) { var dataLoaded = fileLoadedEvent.target.result; var data = dataLoaded.split("\r\n"); $("#templateBody").empty(); @@ -7052,7 +7022,7 @@ function fantasyMap() { $("#templateBody").attr("data-changed", 1); $("#templateSelect").attr("data-prev", "templateCustom").val("templateCustom"); } - for (let i = 0; i < data.length; i++) { + for (let i=0; i < data.length; i++) { var line = data[i].split(" "); addStep(line[0], line[1], line[2]); } @@ -7071,25 +7041,24 @@ function fantasyMap() { if (div.selectAll("*").size() === 0) { for (let i = 0; i <= 100; i++) { var width = i < 20 || i > 70 ? "1px" : "3px"; - if (i === 0) { width = "4px"; } - var clr = color(1 - i / 100); + if (i === 0) {width = "4px";} + var clr = color(1-i/100); var style = "background-color: " + clr + "; width: " + width; - div.append("div").attr("data-color", i / 100).attr("style", style); + div.append("div").attr("data-color", i/100).attr("style", style); } div.selectAll("*").on("touchmove mousemove", showHeight).on("click", assignHeight); } - if ($("#imageConverter").is(":visible")) { return; } + if ($("#imageConverter").is(":visible")) {return;} $("#imageConverter").dialog({ title: "Image to Heightmap Converter", minHeight: 30, width: 260, resizable: false, - position: { my: "right top", at: "right-10 top+10", of: "svg" } - }) - .on('dialogclose', function () { completeConvertion(); }); + position: {my: "right top", at: "right-10 top+10", of: "svg"}}) + .on('dialogclose', function() {completeConvertion();}); } // Load image to convert - $("#convertImageLoad").on("click", function () { imageToLoad.click(); }); - $("#imageToLoad").change(function () { + $("#convertImageLoad").on("click", function() {imageToLoad.click();}); + $("#imageToLoad").change(function() { console.time("loadImage"); // set style resetZoom(); @@ -7100,12 +7069,12 @@ function fantasyMap() { var reader = new FileReader(); var img = new Image; // draw image - img.onload = function () { + img.onload = function() { ctx.drawImage(img, 0, 0, svgWidth, svgHeight); heightsFromImage(+convertColors.value); console.timeEnd("loadImage"); } - reader.onloadend = function () { img.src = reader.result; } + reader.onloadend = function() {img.src = reader.result;} reader.readAsDataURL(file); }); @@ -7116,27 +7085,27 @@ function fantasyMap() { $("#landmass, #colorsUnassigned").fadeIn(); $("#colorsAssigned").fadeOut(); var colors = [], palette = []; - points.map(function (i) { + points.map(function(i) { var x = rn(i[0]), y = rn(i[1]); - if (y == svgHeight) { y--; } - if (x == svgWidth) { x--; } + if (y == svgHeight) {y--;} + if (x == svgWidth) {x--;} var p = (x + y * svgWidth) * 4; var r = data[p], g = data[p + 1], b = data[p + 2]; colors.push([r, g, b]); }); var cmap = MMCQ.quantize(colors, count); - polygons.map(function (i, d) { + polygons.map(function(i, d) { cells[d].height = undefined; var nearest = cmap.nearest(colors[d]); var rgb = "rgb(" + nearest[0] + ", " + nearest[1] + ", " + nearest[2] + ")"; var hex = toHEX(rgb); - if (palette.indexOf(hex) === -1) { palette.push(hex); } + if (palette.indexOf(hex) === -1) {palette.push(hex);} landmass.append("path") .attr("d", "M" + i.join("L") + "Z").attr("data-i", d) .attr("fill", hex).attr("stroke", hex); }); landmass.selectAll("path").on("click", landmassClicked); - palette.sort(function (a, b) { return d3.lab(a).b - d3.lab(b).b; }).map(function (i) { + palette.sort(function(a, b) {return d3.lab(a).b - d3.lab(b).b;}).map(function(i) { $("#colorsUnassigned").append('
'); }); $(".color-div").click(selectColor); @@ -7144,7 +7113,7 @@ function fantasyMap() { function landmassClicked() { var color = d3.select(this).attr("fill"); - $("#" + color.slice(1)).click(); + $("#"+color.slice(1)).click(); } function selectColor() { @@ -7179,13 +7148,13 @@ function fantasyMap() { function assignHeight() { var sel = $(".selectedColor")[0]; var height = +d3.select(this).attr("data-color"); - var rgb = color(1 - height); + var rgb = color(1-height); var hex = toHEX(rgb); sel.style.backgroundColor = rgb; sel.setAttribute("data-height", height); var cur = "#" + sel.id; sel.id = hex.substr(1); - landmass.selectAll(".selectedCell").each(function () { + landmass.selectAll(".selectedCell").each(function() { d3.select(this).attr("fill", hex).attr("stroke", hex); var i = +d3.select(this).attr("data-i"); cells[i].height = height; @@ -7194,22 +7163,22 @@ function fantasyMap() { if (parent.id === "colorsUnassigned") { colorsAssigned.appendChild(sel); $("#colorsAssigned").fadeIn(); - if ($("#colorsUnassigned .color-div").length < 1) { $("#colorsUnassigned").fadeOut(); } + if ($("#colorsUnassigned .color-div").length < 1) {$("#colorsUnassigned").fadeOut();} } - if ($("#colorsAssigned .color-div").length > 1) { sortAssignedColors(); } + if ($("#colorsAssigned .color-div").length > 1) {sortAssignedColors();} } // sort colors based on assigned height function sortAssignedColors() { var data = []; var colors = d3.select("#colorsAssigned").selectAll(".color-div"); - colors.each(function (d) { + colors.each(function(d) { var id = d3.select(this).attr("id"); var height = +d3.select(this).attr("data-height"); - data.push({ id, height }); + data.push({id, height}); }); - data.sort(function (a, b) { return a.height - b.height }).map(function (i) { - $("#colorsAssigned").append($("#" + i.id)); + data.sort(function(a, b) {return a.height - b.height}).map(function(i) { + $("#colorsAssigned").append($("#"+i.id)); }); } @@ -7221,10 +7190,10 @@ function fantasyMap() { $("#colorsAssigned").fadeIn(); $("#colorsUnassigned").fadeOut(); var heights = []; - polygons.map(function (i, d) { + polygons.map(function(i, d) { var x = rn(i.data[0]), y = rn(i.data[1]); - if (y == svgHeight) { y--; } - if (x == svgWidth) { x--; } + if (y == svgHeight) {y--;} + if (x == svgWidth) {x--;} var p = (x + y * svgWidth) * 4; var r = data[p], g = data[p + 1], b = data[p + 2]; var lab = d3.lab("rgb(" + r + ", " + g + ", " + b + ")"); @@ -7239,9 +7208,9 @@ function fantasyMap() { cells[d].height = normalized; landmass.append("path").attr("d", "M" + i.join("L") + "Z").attr("data-i", d).attr("fill", hex).attr("stroke", hex); }); - heights.sort(function (a, b) { return a - b; }); + heights.sort(function(a, b) {return a - b;}); var unique = [...new Set(heights)]; - unique.map(function (i) { + unique.map(function(i) { var rgb = color(1 - i); var hex = toHEX(rgb); $("#colorsAssigned").append('
'); @@ -7251,8 +7220,8 @@ function fantasyMap() { function normalize(val, min, max) { var normalized = (val - min) / (max - min); - if (normalized < 0) { normalized = 0; } - if (normalized > 1) { normalized = 1; } + if (normalized < 0) {normalized = 0;} + if (normalized > 1) {normalized = 1;} return normalized; } @@ -7300,7 +7269,7 @@ function fantasyMap() { $('#grid').empty().fadeOut(); $('#toggleGrid').addClass("buttonoff"); restoreDefaultEvents(); - if (!$("#toggleHeight").hasClass("buttonoff")) { toggleHeight(); } + if (!$("#toggleHeight").hasClass("buttonoff")) {toggleHeight();} closeDialogs(); history = []; historyStage = 0; @@ -7318,7 +7287,7 @@ function fantasyMap() { $("#countriesBody").empty(); $("#countriesHeader").children().removeClass("icon-sort-name-up icon-sort-name-down icon-sort-number-up icon-sort-number-down"); var totalArea = 0, totalBurgs = 0, unit, areaConv; - if (areaUnit.value === "square") { unit = " " + distanceUnit.value + "²"; } else { unit = " " + areaUnit.value; } + if (areaUnit.value === "square") {unit = " " + distanceUnit.value + "²";} else {unit = " " + areaUnit.value;} var totalPopulation = 0; for (let s = 0; s < states.length; s++) { $("#countriesBody").append('
'); @@ -7334,7 +7303,7 @@ function fantasyMap() { var population = (urban + rural) * 1000; totalPopulation += population; var populationConv = si(population); - var title = '\'Total population: ' + populationConv + '; Rural population: ' + rural + 'K; Urban population: ' + urban + 'K\''; + var title = '\'Total population: '+populationConv+'; Rural population: '+rural+'K; Urban population: '+urban+'K\''; var neutral = states[s].color === "neutral" || states[s].capital === "neutral"; // append elements to countriesBody if (!neutral) { @@ -7379,9 +7348,9 @@ function fantasyMap() { $("#countriesEditor").dialog({ title: "Countries Editor", minHeight: "auto", minWidth: Math.min(svgWidth, 390), - position: { my: "right top", at: "right-10 top+10", of: "svg" } - }).on("dialogclose", function () { - if (customization === 2 || customization === 3) { $("#countriesManuallyCancel").click() }; + position: {my: "right top", at: "right-10 top+10", of: "svg"} + }).on("dialogclose", function() { + if (customization === 2 || customization === 3) {$("#countriesManuallyCancel").click()}; }); } // restore customization Editor version @@ -7394,22 +7363,22 @@ function fantasyMap() { } // populate total line on footer countriesFooterCountries.innerHTML = states.length; - if (states[states.length - 1].capital === "neutral") { countriesFooterCountries.innerHTML = states.length - 1; } + if (states[states.length-1].capital === "neutral") {countriesFooterCountries.innerHTML = states.length - 1;} countriesFooterBurgs.innerHTML = totalBurgs; countriesFooterArea.innerHTML = si(totalArea) + unit; countriesFooterPopulation.innerHTML = si(totalPopulation); // handle events - $(".enlange").click(function () { + $(".enlange").click(function() { var s = +(this.parentNode.id).slice(5); var capital = states[s].capital; - var l = labels.select("[data-id='" + capital + "']"); + var l = labels.select("[data-id='" + capital +"']"); var x = +l.attr("x"), y = +l.attr("y"); zoomTo(x, y, 8, 1600); }); - $(".stateName").on("input", function () { + $(".stateName").on("input", function() { var s = +(this.parentNode.id).slice(5); states[s].name = this.value; - labels.select("#regionLabel" + s).text(this.value); + labels.select("#regionLabel"+s).text(this.value); if ($("#burgsEditor").is(":visible")) { if ($("#burgsEditor").attr("data-state") == s) { var color = ''; @@ -7417,41 +7386,41 @@ function fantasyMap() { } } }).hover(focusStates, unfocus); - $(".states > .stateColor").on("change", function () { + $(".states > .stateColor").on("change", function() { var s = +(this.parentNode.id).slice(5); states[s].color = this.value; - regions.selectAll(".region" + s).attr("fill", this.value).attr("stroke", this.value); + regions.selectAll(".region"+s).attr("fill", this.value).attr("stroke", this.value); if ($("#burgsEditor").is(":visible")) { if ($("#burgsEditor").attr("data-state") == s) { $(".ui-dialog-title > .stateColor").val(this.value); } } }); - $(".stateCapital").on("input", function () { + $(".stateCapital").on("input", function() { var s = +(this.parentNode.id).slice(5); var capital = states[s].capital; manors[capital].name = this.value; - labels.select("[data-id='" + capital + "']").text(this.value); + labels.select("[data-id='" + capital +"']").text(this.value); if ($("#burgsEditor").is(":visible")) { if ($("#burgsEditor").attr("data-state") == s) { - $("#burgs" + capital + " > .burgName").val(this.value); + $("#burgs"+capital+" > .burgName").val(this.value); } } }).hover(focusCapital, unfocus); $(".stateBurgs, .stateBIcon").on("click", editBurgs).hover(focusBurgs, unfocus); - $("#countriesBody > .states").on("click", function () { + $("#countriesBody > .states").on("click", function() { if (customization === 2) { $(".selected").removeClass("selected"); $(this).addClass("selected"); const state = +$(this).attr("id").slice(5); let color = states[state].color; - if (color === "neutral") { color = "white"; } + if (color === "neutral") {color = "white";} if (debug.selectAll(".circle").size()) debug.selectAll(".circle").attr("stroke", color); } }); - $(".selectCapital").on("click", function () { + $(".selectCapital").on("click", function() { if ($(this).hasClass("pressed")) { $(this).removeClass("pressed"); tooltip.setAttribute("data-main", ""); @@ -7474,7 +7443,7 @@ function fantasyMap() { } var state = +$(".selectCapital.pressed").attr("id").replace("selectCapital", ""); var oldState = cells[index].region; - if (oldState === "neutral") { oldState = states.length - 1; } + if (oldState === "neutral") {oldState = states.length - 1;} if (cells[index].manor !== undefined) { // cell has burg var burg = cells[index].manor; @@ -7485,7 +7454,7 @@ function fantasyMap() { // make this burg a new capital var urbanFactor = 0.9; // for old neutrals manors[burg].region = state; - if (oldState === "neutral") { manors[burg].population *= (1 / urbanFactor); } + if (oldState === "neutral") {manors[burg].population *= (1 / urbanFactor);} manors[burg].population *= 2; // give capital x2 population bonus states[state].capital = burg; $("#burgLabels [data-id=" + burg + "]").detach().appendTo($("#burgLabels #capitals")); @@ -7500,19 +7469,19 @@ function fantasyMap() { cells[index].manor = i; states[state].capital = i; var score = cells[index].score; - if (score <= 0) { score = rn(Math.random(), 2); } - if (cells[index].crossroad) { score += cells[index].crossroad; } // crossroads - if (cells[index].confluence) { score += Math.pow(cells[index].confluence, 0.3); } // confluences - if (cells[index].port !== undefined) { score *= 3; } // port-capital + if (score <= 0) {score = rn(Math.random(), 2);} + if (cells[index].crossroad) {score += cells[index].crossroad;} // crossroads + if (cells[index].confluence) {score += Math.pow(cells[index].confluence, 0.3);} // confluences + if (cells[index].port !== undefined) {score *= 3;} // port-capital var population = rn(score, 1); - manors.push({ i, cell: index, x, y, region: state, culture, name, population }); + manors.push({i, cell:index, x, y, region: state, culture, name, population}); burgIcons.select("#capitals").append("circle").attr("data-id", i).attr("cx", x).attr("cy", y).attr("r", 1).on("click", editBurg); burgLabels.select("#capitals").append("text").attr("data-id", i).attr("x", x).attr("y", y).attr("dy", "-0.35em").text(name).on("click", editBurg); } cells[index].region = state; - cells[index].neighbors.map(function (n) { - if (cells[n].height < 0.2) { return; } - if (cells[n].manor !== undefined) { return; } + cells[index].neighbors.map(function(n) { + if (cells[n].height < 0.2) {return;} + if (cells[n].manor !== undefined) {return;} cells[n].region = state; }); redrawRegions(); @@ -7523,12 +7492,12 @@ function fantasyMap() { tip("", true); } - $(".statePower").on("input", function () { + $(".statePower").on("input", function() { var s = +(this.parentNode.id).slice(5); states[s].power = +this.value; regenerateCountries(); }); - $(".statePopulation").on("change", function () { + $(".statePopulation").on("change", function() { var s = +(this.parentNode.id).slice(5); var popOr = +$(this).parent().attr("data-population"); var popNew = getInteger(this.value); @@ -7540,46 +7509,44 @@ function fantasyMap() { states[s].urbanPopulation = rn(states[s].urbanPopulation * change, 2); states[s].ruralPopulation = rn(states[s].ruralPopulation * change, 2); var urban = rn(states[s].urbanPopulation * urbanization.value * populationRate.value); - var rural = rn(states[s].ruralPopulation * populationRate.value); + var rural = rn(states[s].ruralPopulation * populationRate.value); var population = (urban + rural) * 1000; $(this).parent().attr("data-population", population); this.value = si(population); var total = 0; - $("#countriesBody > div").each(function (e, i) { + $("#countriesBody > div").each(function(e, i) { total += +$(this).attr("data-population"); }); countriesFooterPopulation.innerHTML = si(total); - if (states[s].capital === "neutral") { s = "neutral"; } - manors.map(function (m) { - if (m.region !== s) { return; } + if (states[s].capital === "neutral") {s = "neutral";} + manors.map(function(m) { + if (m.region !== s) {return;} m.population = rn(m.population * change, 2); }); }); // fully remove country - $("#countriesBody .icon-trash-empty").on("click", function () { + $("#countriesBody .icon-trash-empty").on("click", function() { var s = +(this.parentNode.id).slice(5); if (states[s].capital === "select") { removeCountry(s); return; } alertMessage.innerHTML = `Are you sure you want to remove the country?`; - $("#alert").dialog({ - resizable: false, title: "Remove country", buttons: { - Remove: function () { - removeCountry(s); - $(this).dialog("close"); - }, - Cancel: function () { $(this).dialog("close"); } - } - }); + $("#alert").dialog({resizable: false, title: "Remove country", buttons: { + Remove: function() { + removeCountry(s); + $(this).dialog("close"); + }, + Cancel: function() {$(this).dialog("close");} + }}); }); function removeCountry(s) { const cellsCount = states[s].cells; const capital = states[s].capital; states.splice(s, 1); - states.map(function (s, i) { s.i = i; }); - cells.map(function (c) { + states.map(function(s, i) {s.i = i;}); + cells.map(function(c) { if (c.region === s) c.region = "neutral"; else if (c.region > s) c.region -= 1; }); @@ -7588,16 +7555,16 @@ function fantasyMap() { // change capital to burg $("#burgLabels [data-id=" + capital + "]").detach().appendTo($("#burgLabels #towns")); $("#burgIcons [data-id=" + capital + "]").detach().appendTo($("#burgIcons #towns")); - var burgsSelection = $.grep(manors, function (e) { return (e.region === s); }); + var burgsSelection = $.grep(manors, function(e) {return (e.region === s);}); var urbanFactor = 0.9; - burgsSelection.map(function (b) { - if (b.i === capital) { b.population *= 0.5; } + burgsSelection.map(function(b) { + if (b.i === capital) {b.population *= 0.5;} b.population *= urbanFactor; b.region = "neutral"; }); // re-calculate neutral data - if (states[states.length - 1].capital !== "neutral") { - states.push({ i: states.length, color: "neutral", name: "Neutrals", capital: "neutral" }); + if (states[states.length-1].capital !== "neutral") { + states.push({i: states.length, color: "neutral", name: "Neutrals", capital: "neutral"}); } recalculateStateData(states.length - 1); // re-calc data for neutrals redrawRegions(); @@ -7610,14 +7577,14 @@ function fantasyMap() { // burgs list + editor function editBurgs(context, s) { - if (s === undefined) { s = +(this.parentNode.id).slice(5); } + if (s === undefined) {s = +(this.parentNode.id).slice(5);} $("#burgsEditor").attr("data-state", s); $("#burgsBody").empty(); $("#burgsHeader").children().removeClass("icon-sort-name-up icon-sort-name-down icon-sort-number-up icon-sort-number-down"); var region = states[s].capital === "neutral" ? "neutral" : s; - var burgs = $.grep(manors, function (e) { return (e.region === region); }); + var burgs = $.grep(manors, function(e) {return (e.region === region);}); var populationArray = []; - burgs.map(function (b) { + burgs.map(function(b) { $("#burgsBody").append('
'); var el = $("#burgsBody div:last-child"); el.append(''); @@ -7631,42 +7598,42 @@ function fantasyMap() { el.append(''); var capital = states[s].capital; var type = "z-burg"; // usual burg by default - if (b.i === capital) { el.append(''); type = "c-capital"; } - else { el.append(''); } + if (b.i === capital) {el.append(''); type = "c-capital";} + else {el.append('');} if (cells[b.cell].port !== undefined) { el.append(''); - if (type === "c-capital") { type = "a-capital-port"; } else { type = "p-port"; } + if (type === "c-capital") {type = "a-capital-port";} else {type = "p-port";} } else { el.append(''); } - if (b.i !== capital) { el.append(''); } + if (b.i !== capital) {el.append('');} el.attr("data-burg", b.name).attr("data-culture", cultures[b.culture].name).attr("data-population", b.population).attr("data-type", type); }); if (!$("#burgsEditor").is(":visible")) { $("#burgsEditor").dialog({ title: "Burgs of " + states[s].name, minHeight: "auto", width: "auto", - position: { my: "right bottom", at: "right-10 bottom-10", of: "svg" } + position: {my: "right bottom", at: "right-10 bottom-10", of: "svg"} }); var color = ''; - if (region !== "neutral") { $("div[aria-describedby='burgsEditor'] .ui-dialog-title").prepend(color); } + if (region !== "neutral") {$("div[aria-describedby='burgsEditor'] .ui-dialog-title").prepend(color);} } // populate total line on footer burgsFooterBurgs.innerHTML = burgs.length; burgsFooterCulture.innerHTML = $("#burgsBody div:first-child .burgCulture").text(); var avPop = rn(d3.mean(populationArray), -1); burgsFooterPopulation.value = avPop; - $(".enlange").click(function () { + $(".enlange").click(function() { var b = +(this.parentNode.id).slice(5); var l = labels.select("[data-id='" + b + "']"); var x = +l.attr("x"), y = +l.attr("y"); zoomTo(x, y, 8, 1600); }); $("#burgsBody > div").hover(focusBurg, unfocus); - $("#burgsBody > div").click(function () { - if (!$("#changeCapital").hasClass("pressed")) { return; } + $("#burgsBody > div").click(function() { + if (!$("#changeCapital").hasClass("pressed")) {return;} var type = $(this).attr("data-type"); - if (type.includes("capital")) { return; } + if (type.includes("capital")) {return;} var s = +$("#burgsEditor").attr("data-state"); var b = +$(this).attr("id").slice(5); var oldCap = states[s].capital; @@ -7681,22 +7648,22 @@ function fantasyMap() { updateCountryEditors(); $("#changeCapital").removeClass("pressed"); }); - $(".burgName").on("input", function () { + $(".burgName").on("input", function() { var b = +(this.parentNode.id).slice(5); manors[b].name = this.value; labels.select("[data-id='" + b + "']").text(this.value); if (b === s && $("#countriesEditor").is(":visible")) { - $("#state" + s + " > .stateCapital").val(this.value); + $("#state"+s+" > .stateCapital").val(this.value); } }); - $(".ui-dialog-title > .stateColor").on("change", function () { + $(".ui-dialog-title > .stateColor").on("change", function() { states[s].color = this.value; - regions.selectAll(".region" + s).attr("fill", this.value).attr("stroke", this.value); + regions.selectAll(".region"+s).attr("fill", this.value).attr("stroke", this.value); if ($("#countriesEditor").is(":visible")) { - $("#state" + s + " > .stateColor").val(this.value); + $("#state"+s+" > .stateColor").val(this.value); } }); - $(".burgPopulation").on("change", function () { + $(".burgPopulation").on("change", function() { var b = +(this.parentNode.id).slice(5); var pop = getInteger(this.value); if (!Number.isInteger(pop) || pop < 10) { @@ -7710,19 +7677,19 @@ function fantasyMap() { $(this).parent().attr("data-population", populationRaw); this.value = si(pop); var state = manors[b].region; - if (state === "neutral") { state = states.length - 1; } + if (state === "neutral") {state = states.length - 1;} states[state].urbanPopulation += change; updateCountryPopulationUI(state); var average = states[state].urbanPopulation / states[state].burgs * urbanization.value * populationRate.value * 1000; burgsFooterPopulation.value = rn(average, -1); }); - $("#burgsFooterPopulation").on("change", function () { + $("#burgsFooterPopulation").on("change", function() { var state = +$("#burgsEditor").attr("data-state"); var newPop = +this.value; var avPop = states[state].urbanPopulation / states[state].burgs * urbanization.value * populationRate.value * 1000; - if (!Number.isInteger(newPop) || newPop < 10) { this.value = rn(avPop, -1); return; } + if (!Number.isInteger(newPop) || newPop < 10) {this.value = rn(avPop, -1); return;} var change = +this.value / avPop; - $("#burgsBody > div").each(function (e, i) { + $("#burgsBody > div").each(function(e, i) { var b = +(this.id).slice(5); var pop = rn(manors[b].population * change, 2); manors[b].population = pop; @@ -7734,16 +7701,15 @@ function fantasyMap() { states[state].urbanPopulation = rn(states[state].urbanPopulation * change, 2); updateCountryPopulationUI(state); }); - $("#burgsBody .icon-trash-empty").on("click", function () { + $("#burgsBody .icon-trash-empty").on("click", function() { alertMessage.innerHTML = `Are you sure you want to remove the burg?`; var b = +(this.parentNode.id).slice(5); - $("#alert").dialog({ - resizable: false, title: "Remove burg", + $("#alert").dialog({resizable: false, title: "Remove burg", buttons: { - Remove: function () { + Remove: function() { $(this).dialog("close"); var state = +$("#burgsEditor").attr("data-state"); - $("#burgs" + b).remove(); + $("#burgs"+b).remove(); var cell = manors[b].cell; manors[b].region = "removed"; cells[cell].manor = undefined; @@ -7754,12 +7720,12 @@ function fantasyMap() { var avPop = states[state].urbanPopulation / states[state].burgs * urbanization.value * populationRate.value * 1000; burgsFooterPopulation.value = rn(avPop, -1); if ($("#countriesEditor").is(":visible")) { - $("#state" + state + " > .stateBurgs").text(states[state].burgs); + $("#state"+state+" > .stateBurgs").text(states[state].burgs); } labels.select("[data-id='" + b + "']").remove(); icons.select("[data-id='" + b + "']").remove(); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }); }); @@ -7768,7 +7734,7 @@ function fantasyMap() { // onhover style functions function focusStates() { var s = +(this.parentNode.id).slice(5); - var l = labels.select("#regionLabel" + s); + var l = labels.select("#regionLabel"+s); l.classed("drag", true); } @@ -7781,8 +7747,8 @@ function fantasyMap() { function focusBurgs() { var s = +(this.parentNode.id).slice(5); - var stateManors = $.grep(manors, function (e) { return (e.region === s); }); - stateManors.map(function (m) { + var stateManors = $.grep(manors, function(e) {return (e.region === s);}); + stateManors.map(function(m) { labels.select("[data-id='" + m.i + "']").classed("drag", true); icons.select("[data-id='" + m.i + "']").classed("drag", true); }); @@ -7794,21 +7760,21 @@ function fantasyMap() { l.classed("drag", true); } - function unfocus() { $(".drag").removeClass("drag"); } + function unfocus() {$(".drag").removeClass("drag");} // save dialog position if "stable" dialog window is dragged - $(".stable").on("dialogdragstop", function (event, ui) { + $(".stable").on("dialogdragstop", function(event, ui) { sessionStorage.setItem(this.id, [ui.offset.left, ui.offset.top]); }); // restore saved dialog position on "stable" dialog window open - $(".stable").on("dialogopen", function (event, ui) { + $(".stable").on("dialogopen", function(event, ui) { var pos = sessionStorage.getItem(this.id); - if (!pos) { return; } + if (!pos) {return;} pos = pos.split(","); - if (pos[0] > $(window).width() - 100 || pos[1] > $(window).width() - 40) { return; } // prevent showing out of screen + if (pos[0] > $(window).width() - 100 || pos[1] > $(window).width() - 40) {return;} // prevent showing out of screen var at = `left+${pos[0]} top+${pos[1]}`; - $(this).dialog("option", "position", { my: "left top", at: at, of: "svg" }); + $(this).dialog("option", "position", {my: "left top", at: at, of: "svg"}); }); // open editCultures dialog @@ -7822,7 +7788,7 @@ function fantasyMap() { // collect data const cellsC = [], areas = [], rurPops = [], urbPops = []; const unit = areaUnit.value === "square" ? " " + distanceUnit.value + "²" : " " + areaUnit.value; - land.map(function (l) { + land.map(function(l) { const c = l.culture; if (c === undefined) return; cellsC[c] = cellsC[c] ? cellsC[c] + 1 : 1; @@ -7830,7 +7796,7 @@ function fantasyMap() { rurPops[c] = rurPops[c] ? rurPops[c] + l.pop : l.pop; }); - manors.map(function (m) { + manors.map(function(m) { const r = m.region; if (r === undefined || r === "removed") return; urbPops[r] = urbPops[r] ? urbPops[r] + m.population : m.population; @@ -7850,7 +7816,7 @@ function fantasyMap() { const rural = rn(rurPops[c] * populationRate.value); const population = (urban + rural) * 1000; const populationConv = si(population); - const title = '\'Total population: ' + populationConv + '; Rural population: ' + rural + 'K; Urban population: ' + urban + 'K\''; + const title = '\'Total population: '+populationConv+'; Rural population: '+rural+'K; Urban population: '+urban+'K\''; const base = nameBases[cultures[c].base].name; const el = $("#culturesBody div:last-child"); el.append(''); @@ -7873,14 +7839,14 @@ function fantasyMap() { addCultureBaseOptions(); drawCultureCenters(); - let activeCultures = cellsC.reduce(function (s, v) { if (v) { return s + 1; } else { return s; } }, 0); + let activeCultures = cellsC.reduce(function(s, v) {if(v) {return s + 1;} else {return s;}}, 0); culturesFooterCultures.innerHTML = activeCultures + "/" + cultures.length; culturesFooterCells.innerHTML = land.length; - let totalArea = areas.reduce(function (s, v) { return s + v; }); + let totalArea = areas.reduce(function(s, v) {return s + v;}); totalArea = rn(totalArea * Math.pow(distanceScale.value, 2)); culturesFooterArea.innerHTML = si(totalArea) + unit; - let totalPopulation = rurPops.reduce(function (s, v) { return s + v; }) * urbanization.value; - totalPopulation += urbPops.reduce(function (s, v) { return s + v; }); + let totalPopulation = rurPops.reduce(function(s, v) {return s + v;}) * urbanization.value; + totalPopulation += urbPops.reduce(function(s, v) {return s + v;}); culturesFooterPopulation.innerHTML = si(totalPopulation * 1000 * populationRate.value); // initialize jQuery dialog @@ -7888,23 +7854,23 @@ function fantasyMap() { $("#culturesEditor").dialog({ title: "Cultures Editor", minHeight: "auto", minWidth: Math.min(svgWidth, 336), - position: { my: "right top", at: "right-10 top+10", of: "svg" }, - close: function () { + position: {my: "right top", at: "right-10 top+10", of: "svg"}, + close: function() { debug.select("#cultureCenters").selectAll("*").remove(); exitCulturesManualAssignment(); } }); } - $(".cultures").hover(function () { + $(".cultures").hover(function() { const c = +(this.id).slice(7); - debug.select("#cultureCenter" + c).attr("stroke", "#000000e6"); - }, function () { + debug.select("#cultureCenter"+c).attr("stroke", "#000000e6"); + }, function() { const c = +(this.id).slice(7); - debug.select("#cultureCenter" + c).attr("stroke", "#00000080"); + debug.select("#cultureCenter"+c).attr("stroke", "#00000080"); }); - $(".cultures").on("click", function () { + $(".cultures").on("click", function() { if (customization !== 4) return; const c = +(this.id).slice(7); $(".selected").removeClass("selected"); @@ -7913,33 +7879,33 @@ function fantasyMap() { debug.selectAll(".circle").attr("stroke", color); }); - $(".cultures .stateColor").on("input", function () { + $(".cultures .stateColor").on("input", function() { const c = +(this.parentNode.id).slice(7); const old = cultures[c].color; cultures[c].color = this.value; - debug.select("#cultureCenter" + c).attr("fill", this.value); - cults.selectAll('[fill="' + old + '"]').attr("fill", this.value).attr("stroke", this.value); + debug.select("#cultureCenter"+c).attr("fill", this.value); + cults.selectAll('[fill="'+old+'"]').attr("fill", this.value).attr("stroke", this.value); }); - $(".cultures .cultureName").on("input", function () { + $(".cultures .cultureName").on("input", function() { const c = +(this.parentNode.id).slice(7); cultures[c].name = this.value; }); - $(".cultures .icon-arrows-cw").on("click", function () { + $(".cultures .icon-arrows-cw").on("click", function() { const c = +(this.parentNode.id).slice(7); - manors.forEach(function (m) { + manors.forEach(function(m) { if (m.region === "removed") return; if (m.culture !== c) return; m.name = generateName(c); - labels.select("[data-id='" + m.i + "']").text(m.name); + labels.select("[data-id='" + m.i +"']").text(m.name); }); }); - $("#culturesBody .icon-trash-empty").on("click", function () { + $("#culturesBody .icon-trash-empty").on("click", function() { const c = +(this.parentNode.id).slice(7); cultures.splice(c, 1); - const centers = cultures.map(function (c) { return c.center; }); + const centers = cultures.map(function(c) {return c.center;}); cultureTree = d3.quadtree(centers); recalculateCultures("fullRedraw"); editCultures(); @@ -7949,13 +7915,13 @@ function fantasyMap() { modules.editCultures = true; function addCultureBaseOptions() { - $(".cultureBase").each(function () { + $(".cultureBase").each(function() { const c = +(this.parentNode.id).slice(7); - for (let i = 0; i < nameBases.length; i++) { + for (let i=0; i < nameBases.length; i++) { this.options.add(new Option(nameBases[i].name, i)); } this.value = cultures[c].base; - this.addEventListener("change", function () { + this.addEventListener("change", function() { cultures[c].base = +this.value; }) }); @@ -7963,13 +7929,13 @@ function fantasyMap() { function drawCultureCenters() { let cultureCenters = debug.select("#cultureCenters"); - if (cultureCenters.size()) { cultureCenters.selectAll("*").remove(); } - else { cultureCenters = debug.append("g").attr("id", "cultureCenters"); } - for (let c = 0; c < cultures.length; c++) { - cultureCenters.append("circle").attr("id", "cultureCenter" + c) + if (cultureCenters.size()) {cultureCenters.selectAll("*").remove();} + else {cultureCenters = debug.append("g").attr("id", "cultureCenters");} + for (let c=0; c < cultures.length; c++) { + cultureCenters.append("circle").attr("id", "cultureCenter"+c) .attr("cx", cultures[c].center[0]).attr("cy", cultures[c].center[1]) .attr("r", 6).attr("stroke-width", 2).attr("stroke", "#00000080").attr("fill", cultures[c].color) - .on("mousemove", cultureCenterTip).on("mouseleave", function () { tip("", true) }) + .on("mousemove", cultureCenterTip).on("mouseleave", function() {tip("", true)}) .call(d3.drag().on("start", cultureCenterDrag)); } } @@ -7982,17 +7948,17 @@ function fantasyMap() { const el = d3.select(this); const c = +this.id.slice(13); - d3.event.on("drag", function () { + d3.event.on("drag", function() { const x = d3.event.x, y = d3.event.y; el.attr("cx", x).attr("cy", y); cultures[c].center = [x, y]; - const centers = cultures.map(function (c) { return c.center; }); + const centers = cultures.map(function(c) {return c.center;}); cultureTree = d3.quadtree(centers); recalculateCultures(); }); } - $("#culturesPercentage").on("click", function () { + $("#culturesPercentage").on("click", function() { const el = $("#culturesEditor"); if (el.attr("data-type") === "absolute") { el.attr("data-type", "percentage"); @@ -8000,7 +7966,7 @@ function fantasyMap() { let totalArea = culturesFooterArea.innerHTML; totalArea = getInteger(totalArea.split(" ")[0]); const totalPopulation = getInteger(culturesFooterPopulation.innerHTML); - $("#culturesBody > .cultures").each(function () { + $("#culturesBody > .cultures").each(function() { const cells = rn($(this).attr("data-cells") / totalCells * 100); const area = rn($(this).attr("data-area") / totalArea * 100); const population = rn($(this).attr("data-population") / totalPopulation * 100); @@ -8014,7 +7980,7 @@ function fantasyMap() { } }); - $("#culturesManually").on("click", function () { + $("#culturesManually").on("click", function() { customization = 4; tip("Click to select a culture, drag the circle to re-assign", true); $("#culturesBottom").children().hide(); @@ -8023,9 +7989,9 @@ function fantasyMap() { debug.select("#cultureCenters").selectAll("*").remove(); }); - $("#culturesManuallyComplete").on("click", function () { + $("#culturesManuallyComplete").on("click", function() { const changed = cults.selectAll("[data-culture]"); - changed.each(function () { + changed.each(function() { const i = +(this.id).slice(4); const c = +this.getAttribute("data-culture"); this.removeAttribute("data-culture"); @@ -8037,8 +8003,8 @@ function fantasyMap() { if (changed.size()) editCultures(); }); - $("#culturesManuallyCancel").on("click", function () { - cults.selectAll("[data-culture]").each(function () { + $("#culturesManuallyCancel").on("click", function() { + cults.selectAll("[data-culture]").each(function() { const i = +(this.id).slice(4); const c = cells[i].culture; this.removeAttribute("data-culture"); @@ -8060,8 +8026,8 @@ function fantasyMap() { restoreDefaultEvents(); } - $("#culturesRandomize").on("click", function () { - const centers = cultures.map(function (c) { + $("#culturesRandomize").on("click", function() { + const centers = cultures.map(function(c) { const x = Math.floor(Math.random() * graphWidth * 0.8 + graphWidth * 0.1); const y = Math.floor(Math.random() * graphHeight * 0.8 + graphHeight * 0.1); const center = [x, y]; @@ -8074,10 +8040,10 @@ function fantasyMap() { editCultures(); }); - $("#culturesExport").on("click", function () { + $("#culturesExport").on("click", function() { const unit = areaUnit.value === "square" ? distanceUnit.value + "2" : areaUnit.value; - let data = "Culture,Cells,Area (" + unit + "),Population,Namesbase\n"; // headers - $("#culturesBody > .cultures").each(function () { + let data = "Culture,Cells,Area ("+ unit +"),Population,Namesbase\n"; // headers + $("#culturesBody > .cultures").each(function() { data += $(this).attr("data-culture") + ","; data += $(this).attr("data-cells") + ","; data += $(this).attr("data-area") + ","; @@ -8085,28 +8051,28 @@ function fantasyMap() { data += $(this).attr("data-base") + "\n"; }); - var dataBlob = new Blob([data], { type: "text/plain" }); + var dataBlob = new Blob([data], {type:"text/plain"}); var url = window.URL.createObjectURL(dataBlob); var link = document.createElement("a"); document.body.appendChild(link); link.download = "cultures_data" + Date.now() + ".csv"; link.href = url; link.click(); - window.setTimeout(function () { window.URL.revokeObjectURL(url); }, 2000); + window.setTimeout(function() {window.URL.revokeObjectURL(url);}, 2000); }); - $("#culturesRegenerateNames").on("click", function () { - manors.forEach(function (m) { + $("#culturesRegenerateNames").on("click", function() { + manors.forEach(function(m) { if (m.region === "removed") return; const culture = m.culture; m.name = generateName(culture); - labels.select("[data-id='" + m.i + "']").text(m.name); + labels.select("[data-id='" + m.i +"']").text(m.name); }); }); $("#culturesEditNamesBase").on("click", editNamesbase); - $("#culturesAdd").on("click", function () { + $("#culturesAdd").on("click", function() { const x = Math.floor(Math.random() * graphWidth * 0.8 + graphWidth * 0.1); const y = Math.floor(Math.random() * graphHeight * 0.8 + graphHeight * 0.1); const center = [x, y]; @@ -8125,8 +8091,8 @@ function fantasyMap() { color = colors20(cultures.length % 20); base = cultures[culture].base; } - cultures.push({ name, color, base, center }); - const centers = cultures.map(function (c) { return c.center; }); + cultures.push({name, color, base, center}); + const centers = cultures.map(function(c) {return c.center;}); cultureTree = d3.quadtree(centers); recalculateCultures(); editCultures(); @@ -8155,8 +8121,8 @@ function fantasyMap() { $("#namesbaseEditor").dialog({ title: "Namesbase Editor", minHeight: "auto", minWidth: Math.min(svgWidth, 400), - position: { my: "center", at: "center", of: "svg" }, - close: function () { + position: {my: "center", at: "center", of: "svg"}, + close: function() { localStorage.setItem("nameBase", JSON.stringify(nameBase)); localStorage.setItem("nameBases", JSON.stringify(nameBases)); } @@ -8184,7 +8150,7 @@ function fantasyMap() { function namesbaseUpdateExamples(selected) { const examples = document.getElementById("namesbaseExamples"); let text = ""; - for (let i = 0; i < 10; i++) { + for (let i=0; i < 10; i++) { const name = generateName(false, selected); if (name === undefined) { text = "Cannot generate examples. Please verify the data"; @@ -8196,20 +8162,20 @@ function fantasyMap() { examples.innerHTML = text; } - $("#namesbaseSelect").on("change", function () { + $("#namesbaseSelect").on("change", function() { const selected = +this.value; namesbaseUpdateInputs(selected); namesbaseUpdateExamples(selected); }); - $("#namesbaseName").on("input", function () { + $("#namesbaseName").on("input", function() { const base = +textarea.getAttribute("data-base"); const select = document.getElementById("namesbaseSelect"); select.options[base].innerHTML = this.value; nameBases[base].name = this.value; }); - $("#namesbaseTextarea").on("input", function () { + $("#namesbaseTextarea").on("input", function() { const base = +this.getAttribute("data-base"); const data = textarea.value.replace(/ /g, "").split(","); nameBase[base] = data; @@ -8223,13 +8189,13 @@ function fantasyMap() { if (method !== "selection") chain[base] = calculateChain(base); }); - $("#namesbaseMethod").on("change", function () { + $("#namesbaseMethod").on("change", function() { const base = +textarea.getAttribute("data-base"); nameBases[base].method = this.value; if (this.value !== "selection") chain[base] = calculateChain(base); }); - $("#namesbaseMin").on("change", function () { + $("#namesbaseMin").on("change", function() { const base = +textarea.getAttribute("data-base"); if (+this.value > nameBases[base].max) { tip("Minimal length cannot be greated that maximal"); @@ -8238,7 +8204,7 @@ function fantasyMap() { } }); - $("#namesbaseMax").on("change", function () { + $("#namesbaseMax").on("change", function() { const base = +textarea.getAttribute("data-base"); if (+this.value < nameBases[base].min) { tip("Maximal length cannot be less than minimal"); @@ -8247,19 +8213,18 @@ function fantasyMap() { } }); - $("#namesbaseDouble").on("change", function () { + $("#namesbaseDouble").on("change", function() { const base = +textarea.getAttribute("data-base"); nameBases[base].d = this.value; }); - $("#namesbaseDefault").on("click", function () { + $("#namesbaseDefault").on("click", function() { alertMessage.innerHTML = `Are you sure you want to restore the default namesbase? All custom bases will be removed and default ones will be assigned to existing cultures. Meanwhile existing names will not be changed.`; - $("#alert").dialog({ - resizable: false, title: "Restore default data", + $("#alert").dialog({resizable: false, title: "Restore default data", buttons: { - Restore: function () { + Restore: function() { $(this).dialog("close"); $("#namesbaseEditor").dialog("close"); const select = document.getElementById("namesbaseSelect"); @@ -8271,25 +8236,25 @@ function fantasyMap() { localStorage.removeItem("nameBase"); applyDefaultNamesData(); const baseMax = nameBases.length - 1; - cultures.forEach(function (c) { if (c.base > baseMax) c.base = baseMax; }); + cultures.forEach(function(c) {if (c.base > baseMax) c.base = baseMax;}); chains = {}; calculateChains(); editCultures(); editNamesbase(); }, - Cancel: function () { $(this).dialog("close"); } + Cancel: function() {$(this).dialog("close");} } }); }); - $("#namesbaseAdd").on("click", function () { + $("#namesbaseAdd").on("click", function() { const base = nameBases.length; const name = "Base" + base; const method = document.getElementById("namesbaseMethod").value; const select = document.getElementById("namesbaseSelect"); select.options.add(new Option(name, base)); select.value = base; - nameBases.push({ name, method, min: 4, max: 10, d: "", m: 1 }); + nameBases.push({name, method, min: 4, max: 10, d: "", m: 1}); nameBase.push([]); document.getElementById("namesbaseName").value = name; const textarea = document.getElementById("namesbaseTextarea"); @@ -8300,15 +8265,15 @@ function fantasyMap() { editCultures(); }); - $("#namesbaseExamples, #namesbaseUpdateExamples").on("click", function () { + $("#namesbaseExamples, #namesbaseUpdateExamples").on("click", function() { const select = document.getElementById("namesbaseSelect"); namesbaseUpdateExamples(+select.value); }); - $("#namesbaseDownload").on("click", function () { + $("#namesbaseDownload").on("click", function() { const nameBaseString = JSON.stringify(nameBase) + "\r\n"; const nameBasesString = JSON.stringify(nameBases); - const dataBlob = new Blob([nameBaseString + nameBasesString], { type: "text/plain" }); + const dataBlob = new Blob([nameBaseString + nameBasesString], {type:"text/plain"}); const url = window.URL.createObjectURL(dataBlob); const link = document.createElement("a"); link.download = "namebase" + Date.now() + ".txt"; @@ -8316,12 +8281,12 @@ function fantasyMap() { link.click(); }); - $("#namesbaseUpload").on("click", function () { namesbaseToLoad.click(); }); - $("#namesbaseToLoad").change(function () { + $("#namesbaseUpload").on("click", function() {namesbaseToLoad.click();}); + $("#namesbaseToLoad").change(function() { const fileToLoad = this.files[0]; this.value = ""; const fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { + fileReader.onload = function(fileLoadedEvent) { const dataLoaded = fileLoadedEvent.target.result; const data = dataLoaded.split("\r\n"); if (data[0] && data[1]) { @@ -8333,7 +8298,7 @@ function fantasyMap() { document.getElementById("namesbaseTextarea").setAttribute("data-base", 0); document.getElementById("namesbaseExamples").innerHTML === ""; const baseMax = nameBases.length - 1; - cultures.forEach(function (c) { if (c.base > baseMax) c.base = baseMax; }); + cultures.forEach(function(c) {if (c.base > baseMax) c.base = baseMax;}); chains = {}; calculateChains(); editCultures(); @@ -8352,7 +8317,7 @@ function fantasyMap() { $("#scaleEditor").dialog({ title: "Scale Editor", minHeight: "auto", width: "auto", resizable: false, - position: { my: "center bottom", at: "center bottom-10", of: "svg" } + position: {my: "center bottom", at: "center bottom-10", of: "svg"} }); } @@ -8360,16 +8325,16 @@ function fantasyMap() { function updateCountryPopulationUI(s) { if ($("#countriesEditor").is(":visible")) { var urban = rn(states[s].urbanPopulation * +urbanization.value * populationRate.value); - var rural = rn(states[s].ruralPopulation * populationRate.value); + var rural = rn(states[s].ruralPopulation * populationRate.value); var population = (urban + rural) * 1000; - $("#state" + s).attr("data-population", population); - $("#state" + s).children().filter(".statePopulation").val(si(population)); + $("#state"+s).attr("data-population", population); + $("#state"+s).children().filter(".statePopulation").val(si(population)); } } // update dialogs if measurements are changed function updateCountryEditors() { - if ($("#countriesEditor").is(":visible")) { editCountries(); } + if ($("#countriesEditor").is(":visible")) {editCountries();} if ($("#burgsEditor").is(":visible")) { var s = +$("#burgsEditor").attr("data-state"); editBurgs(this, s); @@ -8388,7 +8353,7 @@ function fantasyMap() { function restoreRegions() { borders.selectAll("path").remove(); labels.select("#countries").selectAll("text").remove(); - manors.map(function (m) { + manors.map(function(m) { const cell = diagram.find(m.x, m.y).index; if (cells[cell].height < 0.2) { // remove manor in ocean @@ -8401,7 +8366,7 @@ function fantasyMap() { cells[cell].manor = m.i; } }); - cells.map(function (c) { + cells.map(function(c) { if (c.height < 0.2) { // no longer a land cell delete c.region; @@ -8411,7 +8376,7 @@ function fantasyMap() { if (c.region === undefined) { c.region = "neutral"; if (states[states.length - 1].capital !== "neutral") { - states.push({ i: states.length, color: "neutral", capital: "neutral", name: "Neutrals" }); + states.push({i: states.length, color: "neutral", capital: "neutral", name: "Neutrals"}); } } if (c.culture === undefined) { @@ -8419,22 +8384,22 @@ function fantasyMap() { c.culture = cultureTree.data().indexOf(closest); } }); - states.map(function (s) { recalculateStateData(s.i); }) + states.map(function(s) {recalculateStateData(s.i);}) drawRegions(); } function regenerateCountries() { regions.selectAll("*").remove(); const neutral = neutralInput.value = +countriesNeutral.value; - manors.forEach(function (m) { + manors.forEach(function(m) { if (m.region === "removed") return; let state = "neutral", closest = neutral; - states.map(function (s) { + states.map(function(s) { if (s.capital === "neutral" || s.capital === "select") return; const c = manors[s.capital]; let dist = Math.hypot(c.x - m.x, c.y - m.y) / s.power; if (cells[m.cell].fn !== cells[c.cell].fn) dist *= 3; - if (dist < closest) { state = s.i; closest = dist; } + if (dist < closest) {state = s.i; closest = dist;} }); m.region = state; cells[m.cell].region = state; @@ -8442,7 +8407,7 @@ function fantasyMap() { defineRegions(); const temp = regions.append("g").attr("id", "temp"); - land.forEach(function (l) { + land.forEach(function(l) { if (l.region === undefined) return; if (l.region === "neutral") return; const color = states[l.region].color; @@ -8451,7 +8416,7 @@ function fantasyMap() { .attr("d", "M" + polygons[l.index].join("L") + "Z") .attr("fill", color).attr("stroke", color); }); - const neutralCells = $.grep(cells, function (e) { return e.region === "neutral"; }); + const neutralCells = $.grep(cells, function(e) {return e.region === "neutral";}); const last = states.length - 1; const type = states[last].color; if (type === "neutral" && !neutralCells.length) { @@ -8460,23 +8425,23 @@ function fantasyMap() { states.splice(-1); } // recalculate data for all countries - states.map(function (s) { + states.map(function(s) { recalculateStateData(s.i); - $("#state" + s.i + " > .stateCells").text(s.cells); - $("#state" + s.i + " > .stateBurgs").text(s.burgs); + $("#state"+s.i+" > .stateCells").text(s.cells); + $("#state"+s.i+" > .stateBurgs").text(s.burgs); const area = rn(s.area * Math.pow(distanceScale.value, 2)); const unit = areaUnit.value === "square" ? " " + distanceUnit.value + "²" : " " + areaUnit.value; - $("#state" + s.i + " > .stateArea").text(si(area) + unit); + $("#state"+s.i+" > .stateArea").text(si(area) + unit); const urban = rn(s.urbanPopulation * urbanization.value * populationRate.value); - const rural = rn(s.ruralPopulation * populationRate.value); + const rural = rn(s.ruralPopulation * populationRate.value); const population = (urban + rural) * 1000; - $("#state" + s.i + " > .statePopulation").val(si(population)); - $("#state" + s.i).attr("data-cells", s.cells).attr("data-burgs", s.burgs) + $("#state"+s.i+" > .statePopulation").val(si(population)); + $("#state"+s.i).attr("data-cells", s.cells).attr("data-burgs", s.burgs) .attr("data-area", area).attr("data-population", population); }); if (type !== "neutral" && neutralCells.length) { // add neutral line - states.push({ i: states.length, color: "neutral", capital: "neutral", name: "Neutrals" }); + states.push({i: states.length, color: "neutral", capital: "neutral", name: "Neutrals"}); recalculateStateData(states.length - 1); editCountries(); } @@ -8484,49 +8449,49 @@ function fantasyMap() { // enter state edit mode function mockRegions() { - if (grid.style("display") !== "inline") { toggleGrid.click(); } - if (labels.style("display") !== "none") { toggleLabels.click(); } + if (grid.style("display") !== "inline") {toggleGrid.click();} + if (labels.style("display") !== "none") {toggleLabels.click();} stateBorders.selectAll("*").remove(); neutralBorders.selectAll("*").remove(); } // handle DOM elements sorting on header click - $(".sortable").on("click", function () { + $(".sortable").on("click", function() { var el = $(this); // remove sorting for all siglings except of clicked element el.siblings().removeClass("icon-sort-name-up icon-sort-name-down icon-sort-number-up icon-sort-number-down"); var type = el.hasClass("alphabetically") ? "name" : "number"; var state = "no"; - if (el.is("[class*='down']")) { state = "asc"; } - if (el.is("[class*='up']")) { state = "desc"; } + if (el.is("[class*='down']")) {state = "asc";} + if (el.is("[class*='up']")) {state = "desc";} var sortby = el.attr("data-sortby"); var list = el.parent().next(); // get list container element (e.g. "countriesBody") var lines = list.children("div"); // get list elements if (state === "no" || state === "asc") { // sort desc el.removeClass("icon-sort-" + type + "-down"); el.addClass("icon-sort-" + type + "-up"); - lines.sort(function (a, b) { + lines.sort(function(a, b) { var an = a.getAttribute("data-" + sortby); - if (an === "bottom") { return 1; } + if (an === "bottom") {return 1;} var bn = b.getAttribute("data-" + sortby); - if (bn === "bottom") { return -1; } - if (type === "number") { an = +an; bn = +bn; } - if (an > bn) { return 1; } - if (an < bn) { return -1; } + if (bn === "bottom") {return -1;} + if (type === "number") {an = +an; bn = +bn;} + if (an > bn) {return 1;} + if (an < bn) {return -1;} return 0; }); } if (state === "desc") { // sort asc el.removeClass("icon-sort-" + type + "-up"); el.addClass("icon-sort-" + type + "-down"); - lines.sort(function (a, b) { + lines.sort(function(a, b) { var an = a.getAttribute("data-" + sortby); - if (an === "bottom") { return 1; } + if (an === "bottom") {return 1;} var bn = b.getAttribute("data-" + sortby); - if (bn === "bottom") { return -1; } - if (type === "number") { an = +an; bn = +bn; } - if (an < bn) { return 1; } - if (an > bn) { return -1; } + if (bn === "bottom") {return -1;} + if (type === "number") {an = +an; bn = +bn;} + if (an < bn) {return 1;} + if (an > bn) {return -1;} return 0; }); } @@ -8534,32 +8499,31 @@ function fantasyMap() { }); // load text file with new burg names - $("#burgsListToLoad").change(function () { + $("#burgsListToLoad").change(function() { var fileToLoad = this.files[0]; this.value = ""; var fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { + fileReader.onload = function(fileLoadedEvent) { var dataLoaded = fileLoadedEvent.target.result; var data = dataLoaded.split("\r\n"); - if (data.length === 0) { return; } + if (data.length === 0) {return;} let change = []; let message = `Burgs will be renamed as below. Please confirm`; message += `
`; - for (let i = 0; i < data.length && i < manors.length; i++) { + for (let i=0; i < data.length && i < manors.length; i++) { const v = data[i]; - if (v === "" || v === undefined) { continue; } - if (v === manors[i].name) { continue; } - change.push({ i, name: v }); + if (v === "" || v === undefined) {continue;} + if (v === manors[i].name) {continue;} + change.push({i, name: v}); message += ``; } message += `
IdCurrent nameNew Name
${i}${manors[i].name}${v}
`; alertMessage.innerHTML = message; - $("#alert").dialog({ - title: "Burgs bulk renaming", position: { my: "center", at: "center", of: "svg" }, + $("#alert").dialog({title: "Burgs bulk renaming", position: {my: "center", at: "center", of: "svg"}, buttons: { - Cancel: function () { $(this).dialog("close"); }, - Confirm: function () { - for (let i = 0; i < change.length; i++) { + Cancel: function() {$(this).dialog("close");}, + Confirm: function() { + for (let i=0; i < change.length; i++) { const id = change[i].i; manors[id].name = change[i].name; labels.select("[data-id='" + id + "']").text(change[i].name); @@ -8579,7 +8543,7 @@ function fantasyMap() { svgHeight = graphHeight = +mapHeightInput.value; svg.attr("width", svgWidth).attr("height", svgHeight); // set extent to map borders + 100px to get infinity world reception - voronoi = d3.voronoi().extent([[-1, -1], [graphWidth + 1, graphHeight + 1]]); + voronoi = d3.voronoi().extent([[-1, -1], [graphWidth+1, graphHeight+1]]); zoom.translateExtent([[0, 0], [graphWidth, graphHeight]]).scaleExtent([1, 20]).scaleTo(svg, 1); viewbox.attr("transform", null); ocean.selectAll("rect").attr("x", 0).attr("y", 0).attr("width", graphWidth).attr("height", graphHeight); @@ -8598,7 +8562,7 @@ function fantasyMap() { } // fit full-screen map if window is resized - $(window).resize(function (e) { + $(window).resize(function(e) { // trick to prevent resize on download bar opening if (autoResize === false) return; mapWidthInput.value = window.innerWidth; @@ -8663,12 +8627,12 @@ function fantasyMap() { } // Options handlers - $("input, select").on("input change", function () { + $("input, select").on("input change", function() { var id = this.id; - if (id === "hideLabels") { invokeActiveZooming(); } + if (id === "hideLabels") {invokeActiveZooming();} if (id === "styleElementSelect") { const sel = this.value; - let el = viewbox.select("#" + sel); + let el = viewbox.select("#"+sel); if (sel == "ocean") el = oceanLayers.select("rect"); $("#styleInputs div").hide(); // opacity @@ -8694,8 +8658,8 @@ function fantasyMap() { styleStrokeDasharrayInput.value = el.attr("stroke-dasharray") || ""; styleStrokeLinecapInput.value = el.attr("stroke-linecap") || "inherit"; } - if (sel === "terrs") { $("#styleScheme").css("display", "block"); } - if (sel === "heightmap") { $("#styleScheme").css("display", "block"); } + if (sel === "terrs") {$("#styleScheme").css("display", "block");} + if (sel === "heightmap") {$("#styleScheme").css("display", "block");} if (sel === "labels") { $("#styleFill, #styleFontSize").css("display", "inline-block"); styleFillInput.value = styleFillOutput.value = el.select("g").attr("fill"); @@ -8712,9 +8676,9 @@ function fantasyMap() { } if (id === "styleFillInput") { styleFillOutput.value = this.value; - var el = svg.select("#" + styleElementSelect.value); + var el = svg.select("#"+styleElementSelect.value); if (styleElementSelect.value !== "labels") { - el.attr('fill', this.value); + el.attr('fill', this.value); } else { el.selectAll("g").attr('fill', this.value); } @@ -8722,36 +8686,36 @@ function fantasyMap() { } if (id === "styleStrokeInput") { styleStrokeOutput.value = this.value; - var el = svg.select("#" + styleElementSelect.value); + var el = svg.select("#"+styleElementSelect.value); el.attr('stroke', this.value); return; } if (id === "styleStrokeWidthInput") { styleStrokeWidthOutput.value = this.value; var sel = styleElementSelect.value; - svg.select("#" + sel).attr('stroke-width', +this.value); + svg.select("#"+sel).attr('stroke-width', +this.value); return; } if (id === "styleStrokeDasharrayInput") { var sel = styleElementSelect.value; - svg.select("#" + sel).attr('stroke-dasharray', this.value); + svg.select("#"+sel).attr('stroke-dasharray', this.value); return; } if (id === "styleStrokeLinecapInput") { var sel = styleElementSelect.value; - svg.select("#" + sel).attr('stroke-linecap', this.value); + svg.select("#"+sel).attr('stroke-linecap', this.value); return; } if (id === "styleOpacityInput") { styleOpacityOutput.value = this.value; var sel = styleElementSelect.value; - svg.select("#" + sel).attr('opacity', this.value); + svg.select("#"+sel).attr('opacity', this.value); return; } if (id === "styleFilterInput") { let sel = styleElementSelect.value; if (sel == "ocean") sel = "oceanLayers"; - const el = svg.select("#" + sel); + const el = svg.select("#"+sel); el.attr('filter', this.value); zoom.scaleBy(svg, 1.00001); // enforce browser re-draw return; @@ -8798,36 +8762,36 @@ function fantasyMap() { } if (id === "sizeInput") { graphSize = sizeOutput.value = +this.value; - if (graphSize === 3) { sizeOutput.style.color = "red"; } - if (graphSize === 2) { sizeOutput.style.color = "yellow"; } - if (graphSize === 1) { sizeOutput.style.color = "green"; } + if (graphSize === 3) {sizeOutput.style.color = "red";} + if (graphSize === 2) {sizeOutput.style.color = "yellow";} + if (graphSize === 1) {sizeOutput.style.color = "green";} // localStorage.setItem("graphSize", this.value); - temp off to always start with size 1 } - if (id === "templateInput") { localStorage.setItem("template", this.value); } - if (id === "manorsInput") { manorsOutput.value = this.value; localStorage.setItem("manors", this.value); } + if (id === "templateInput") {localStorage.setItem("template", this.value);} + if (id === "manorsInput") {manorsOutput.value = this.value; localStorage.setItem("manors", this.value);} if (id === "regionsInput") { regionsOutput.value = this.value; var size = rn(6 - this.value / 20); - if (size < 3) { size = 3; } + if (size < 3) {size = 3;} burgLabels.select("#capitals").attr("data-size", size); size = rn(18 - this.value / 6); - if (size < 4) { size = 4; } + if (size < 4) {size = 4;} labels.select("#countries").attr("data-size", size); localStorage.setItem("regions", this.value); } - if (id === "powerInput") { powerOutput.value = this.value; localStorage.setItem("power", this.value); } - if (id === "neutralInput") { neutralOutput.value = countriesNeutral.value = this.value; localStorage.setItem("neutal", this.value); } - if (id === "culturesInput") { culturesOutput.value = this.value; localStorage.setItem("cultures", this.value); } - if (id === "precInput") { precOutput.value = +precInput.value; localStorage.setItem("prec", this.value); } - if (id === "swampinessInput") { swampinessOutput.value = this.value; localStorage.setItem("swampiness", this.value); } - if (id === "outlineLayersInput") { localStorage.setItem("outlineLayers", this.value); } - if (id === "pngResolutionInput") { localStorage.setItem("pngResolution", this.value); } + if (id === "powerInput") {powerOutput.value = this.value; localStorage.setItem("power", this.value);} + if (id === "neutralInput") {neutralOutput.value = countriesNeutral.value = this.value; localStorage.setItem("neutal", this.value);} + if (id === "culturesInput") {culturesOutput.value = this.value; localStorage.setItem("cultures", this.value);} + if (id === "precInput") {precOutput.value = +precInput.value; localStorage.setItem("prec", this.value);} + if (id === "swampinessInput") {swampinessOutput.value = this.value; localStorage.setItem("swampiness", this.value);} + if (id === "outlineLayersInput") {localStorage.setItem("outlineLayers", this.value);} + if (id === "pngResolutionInput") {localStorage.setItem("pngResolution", this.value);} if (id === "zoomExtentMin" || id === "zoomExtentMax") { zoom.scaleExtent([+zoomExtentMin.value, +zoomExtentMax.value]); zoom.scaleTo(svg, +this.value); } - if (id === "convertOverlay") { canvas.style.opacity = convertOverlayValue.innerHTML = +this.value; } + if (id === "convertOverlay") {canvas.style.opacity = convertOverlayValue.innerHTML = +this.value;} if (id === "populationRate") { populationRateOutput.value = si(+populationRate.value * 1000); updateCountryEditors(); @@ -8851,14 +8815,14 @@ function fantasyMap() { } var scale = distanceScale.value; scaleOutput.value = scale + " " + dUnit; - ruler.selectAll("g").each(function () { + ruler.selectAll("g").each(function() { var label; var g = d3.select(this); var area = +g.select("text").attr("data-area"); if (area) { var areaConv = area * Math.pow(scale, 2); // convert area to distanceScale var unit = areaUnit.value; - if (unit === "square") { unit = dUnit + "²" } else { unit = areaUnit.value; } + if (unit === "square") {unit = dUnit + "²"} else {unit = areaUnit.value;} label = si(areaConv) + " " + unit; } else { var dist = +g.select("text").attr("data-dist"); @@ -8887,7 +8851,7 @@ function fantasyMap() { } }); - $("#scaleOutput").change(function () { + $("#scaleOutput").change(function() { if (this.value === "" || isNaN(+this.value) || this.value < 0.01 || this.value > 10) { tip("Manually entered distance scale should be a number in a [0.01; 10] range"); this.value = distanceScale.value + " " + distanceUnit.value; @@ -8898,7 +8862,7 @@ function fantasyMap() { updateCountryEditors(); }); - $("#populationRateOutput").change(function () { + $("#populationRateOutput").change(function() { if (this.value === "" || isNaN(+this.value) || this.value < 0.001 || this.value > 10) { tip("Manually entered population rate should be a number in a [0.001; 10] range"); this.value = si(populationRate.value * 1000); @@ -8909,7 +8873,7 @@ function fantasyMap() { updateCountryEditors(); }); - $("#urbanizationOutput").change(function () { + $("#urbanizationOutput").change(function() { if (this.value === "" || isNaN(+this.value) || this.value < 0 || this.value > 10) { tip("Manually entered urbanization rate should be a number in a [0; 10] range"); this.value = urbanization.value; @@ -8923,7 +8887,7 @@ function fantasyMap() { // lock manually changed option to restrict it randomization - $("#optionsContent input, #optionsContent select").change(function () { + $("#optionsContent input, #optionsContent select").change(function() { const icon = "lock" + this.id.charAt(0).toUpperCase() + this.id.slice(1); const el = document.getElementById(icon); if (!el) return; @@ -8933,15 +8897,15 @@ function fantasyMap() { $("#optionsReset").click(restoreDefaultOptions); - $("#rescaler").change(function () { - var change = rn((+this.value - 5) / 10, 2); - modifyHeights("all", change, 1); - updateHeightmap(); - updateHistory(); - rescaler.value = 5; + $("#rescaler").change(function() { + var change = rn((+this.value - 5) / 10, 2); + modifyHeights("all", change, 1); + updateHeightmap(); + updateHistory(); + rescaler.value = 5; }); - $("#layoutPreset").on("change", function () { + $("#layoutPreset").on("change", function() { var preset = this.value; $("#mapLayers li").not("#toggleOcean").addClass("buttonoff"); $("#toggleOcean").removeClass("buttonoff"); @@ -8981,37 +8945,37 @@ function fantasyMap() { }); // UI Button handlers - $(".tab > button").on("click", function () { + $(".tab > button").on("click", function() { $(".tabcontent").hide(); $(".tab > button").removeClass("active"); $(this).addClass("active"); var id = this.id; - if (id === "layoutTab") { $("#layoutContent").show(); } - if (id === "styleTab") { $("#styleContent").show(); } - if (id === "optionsTab") { $("#optionsContent").show(); } - if (id === "customizeTab") { $("#customizeContent").show(); } - if (id === "aboutTab") { $("#aboutContent").show(); } + if (id === "layoutTab") {$("#layoutContent").show();} + if (id === "styleTab") {$("#styleContent").show();} + if (id === "optionsTab") {$("#optionsContent").show();} + if (id === "customizeTab") {$("#customizeContent").show();} + if (id === "aboutTab") {$("#aboutContent").show();} }); // Pull request from @evyatron // https://github.com/Azgaar/Fantasy-Map-Generator/pull/49 function addDragToUpload() { - document.addEventListener('dragover', function (e) { - e.stopPropagation(); - e.preventDefault(); - $('#map-dragged').show(); + document.addEventListener('dragover', function(e) { + e.stopPropagation(); + e.preventDefault(); + $('#map-dragged').show(); }); - document.addEventListener('dragleave', function (e) { - $('#map-dragged').hide(); + document.addEventListener('dragleave', function(e) { + $('#map-dragged').hide(); }); - document.addEventListener('drop', function (e) { + document.addEventListener('drop', function(e) { e.stopPropagation(); e.preventDefault(); $('#map-dragged').hide(); // no files or more than one - if (e.dataTransfer.items == null || e.dataTransfer.items.length != 1) { return; } + if (e.dataTransfer.items == null || e.dataTransfer.items.length != 1) {return;} var file = e.dataTransfer.items[0].getAsFile(); // not a .map file if (file.name.indexOf('.map') == -1) { @@ -9019,8 +8983,8 @@ function fantasyMap() { $("#alert").dialog({ resizable: false, title: "Invalid file format", width: 400, buttons: { - Close: function () { $(this).dialog("close"); } - }, position: { my: "center", at: "center", of: "svg" } + Close: function() { $(this).dialog("close"); } + }, position: {my: "center", at: "center", of: "svg"} }); return; } @@ -9035,9 +8999,9 @@ function fantasyMap() { function tip(tip, main) { tooltip.innerHTML = tip; - if (main) { tooltip.setAttribute("data-main", tip); } + if (main) {tooltip.setAttribute("data-main", tip);} } -$("#optionsContainer *").on("mouseout", function () { +$("#optionsContainer *").on("mouseout", function() { tooltip.innerHTML = tooltip.getAttribute("data-main"); });