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 | Current name | New Name |
|---|---|---|
| ${i} | ${manors[i].name} | ${v} |