diff --git a/index.html b/index.html
index 6c26b3b5..c46682cc 100644
--- a/index.html
+++ b/index.html
@@ -7664,13 +7664,6 @@
-
-
-
-
-
-
-
diff --git a/modules/burgs-and-states.js b/modules/burgs-and-states.js
index 7f535254..2471d12d 100644
--- a/modules/burgs-and-states.js
+++ b/modules/burgs-and-states.js
@@ -4,6 +4,8 @@ import {layerIsOn} from "./ui/layers";
import {getColors, getRandomColor, getMixedColor} from "/src/utils/colorUtils";
import {getMiddlePoint} from "@/utils/lineUtils";
import {rn, minmax} from "/src/utils/numberUtils";
+import {rand, P, each, gauss, ra, rw, generateSeed} from "@/utils/probabilityUtils";
+import {round, splitInTwo} from "@/utils/stringUtils";
window.BurgsAndStates = (function () {
const generate = function () {
diff --git a/modules/coa-generator.js b/modules/coa-generator.js
index 56deb52b..106b0b4c 100644
--- a/modules/coa-generator.js
+++ b/modules/coa-generator.js
@@ -1,3 +1,5 @@
+import {P, rw} from "@/utils/probabilityUtils";
+
window.COA = (function () {
const tinctures = {
field: {metals: 3, colours: 4, stains: +P(0.03), patterns: 1},
diff --git a/modules/cultures-generator.js b/modules/cultures-generator.js
index cd013f7c..7f86286e 100644
--- a/modules/cultures-generator.js
+++ b/modules/cultures-generator.js
@@ -1,6 +1,7 @@
import {TIME} from "/src/config/logging";
import {getColors} from "/src/utils/colorUtils";
import {rn, minmax} from "/src/utils/numberUtils";
+import {rand, P, rw, biased} from "@/utils/probabilityUtils";
window.Cultures = (function () {
let cells;
diff --git a/modules/dynamic/auto-update.js b/modules/dynamic/auto-update.js
index 2808b65e..cb73e4ee 100644
--- a/modules/dynamic/auto-update.js
+++ b/modules/dynamic/auto-update.js
@@ -1,5 +1,7 @@
import {findCell} from "/src/utils/graphUtils";
import {rn} from "/src/utils/numberUtils";
+import {rand, P, rw} from "@/utils/probabilityUtils";
+import {parseTransform} from "@/utils/stringUtils";
// update old .map version to the current one
export function resolveVersionConflicts(version) {
diff --git a/modules/dynamic/editors/cultures-editor.js b/modules/dynamic/editors/cultures-editor.js
index 1ff37614..c13e8e74 100644
--- a/modules/dynamic/editors/cultures-editor.js
+++ b/modules/dynamic/editors/cultures-editor.js
@@ -3,6 +3,7 @@ import {findAll, findCell, getPackPolygon, isLand} from "/src/utils/graphUtils";
import {tip, showMainTip, clearMainTip} from "/src/scripts/tooltips";
import {byId} from "/src/utils/shorthands";
import {rn} from "/src/utils/numberUtils";
+import {capitalize} from "@/utils/stringUtils";
const $body = insertEditorHtml();
addListeners();
diff --git a/modules/dynamic/editors/states-editor.js b/modules/dynamic/editors/states-editor.js
index 875ebca8..d8267560 100644
--- a/modules/dynamic/editors/states-editor.js
+++ b/modules/dynamic/editors/states-editor.js
@@ -4,6 +4,7 @@ import {byId} from "/src/utils/shorthands";
import {tip, showMainTip, clearMainTip} from "/src/scripts/tooltips";
import {getRandomColor, getMixedColor} from "/src/utils/colorUtils";
import {rn} from "/src/utils/numberUtils";
+import {rand, P} from "@/utils/probabilityUtils";
const $body = insertEditorHtml();
addListeners();
diff --git a/modules/dynamic/heightmap-selection.js b/modules/dynamic/heightmap-selection.js
index 6b5dc1e3..7bcb93dc 100644
--- a/modules/dynamic/heightmap-selection.js
+++ b/modules/dynamic/heightmap-selection.js
@@ -1,5 +1,6 @@
import {shouldRegenerateGrid, generateGrid} from "/src/utils/graphUtils";
import {byId} from "/src/utils/shorthands";
+import {generateSeed} from "@/utils/probabilityUtils";
const initialSeed = generateSeed();
let graph = getGraph(grid);
diff --git a/modules/dynamic/hierarchy-tree.js b/modules/dynamic/hierarchy-tree.js
index 3375a281..04eda6b6 100644
--- a/modules/dynamic/hierarchy-tree.js
+++ b/modules/dynamic/hierarchy-tree.js
@@ -1,5 +1,6 @@
import {byId} from "/src/utils/shorthands";
import {tip} from "/src/scripts/tooltips";
+import {capitalize} from "@/utils/stringUtils";
appendStyleSheet();
insertHtml();
diff --git a/modules/dynamic/overview/charts-overview.js b/modules/dynamic/overview/charts-overview.js
index 0b659f8f..7e64b850 100644
--- a/modules/dynamic/overview/charts-overview.js
+++ b/modules/dynamic/overview/charts-overview.js
@@ -3,6 +3,7 @@ import {isWater} from "/src/utils/graphUtils";
import {tip} from "/src/scripts/tooltips";
import {byId} from "/src/utils/shorthands";
import {rn} from "/src/utils/numberUtils";
+import {capitalize} from "@/utils/stringUtils";
const entitiesMap = {
states: {
diff --git a/modules/dynamic/supporters.js b/modules/dynamic/supporters.js
index 038da4d8..387473fc 100644
--- a/modules/dynamic/supporters.js
+++ b/modules/dynamic/supporters.js
@@ -1,3 +1,5 @@
+import {capitalize} from "@/utils/stringUtils";
+
const capitalize = text => text.charAt(0).toUpperCase() + text.slice(1);
const format = rawList =>
diff --git a/modules/heightmap-generator.js b/modules/heightmap-generator.js
index 17be7314..c14bde4d 100644
--- a/modules/heightmap-generator.js
+++ b/modules/heightmap-generator.js
@@ -2,6 +2,7 @@ import {TIME} from "/src/config/logging";
import {createTypedArray} from "/src/utils/arrayUtils";
import {findGridCell} from "/src/utils/graphUtils";
import {byId} from "/src/utils/shorthands";
+import {rand, P, getNumberInRange} from "@/utils/probabilityUtils";
window.HeightmapGenerator = (function () {
let grid = null;
diff --git a/modules/io/save.js b/modules/io/save.js
index 4b6a0e68..7f3a4178 100644
--- a/modules/io/save.js
+++ b/modules/io/save.js
@@ -1,6 +1,7 @@
import {tip} from "/src/scripts/tooltips";
import {rn} from "/src/utils/numberUtils";
import {ldb} from "@/scripts/indexedDB";
+import {ra} from "@/utils/probabilityUtils";
// functions to save project as .map file
diff --git a/modules/markers-generator.js b/modules/markers-generator.js
index 1e9d6888..2e7ad4dd 100644
--- a/modules/markers-generator.js
+++ b/modules/markers-generator.js
@@ -2,6 +2,8 @@ import {TIME} from "/src/config/logging";
import {getFriendlyHeight} from "./ui/general";
import {last} from "/src/utils/arrayUtils";
import {rn} from "/src/utils/numberUtils";
+import {rand, P, gauss, ra, rw} from "@/utils/probabilityUtils";
+import {capitalize} from "@/utils/stringUtils";
window.Markers = (function () {
let config = [];
diff --git a/modules/military-generator.js b/modules/military-generator.js
index b8a164fc..69157aea 100644
--- a/modules/military-generator.js
+++ b/modules/military-generator.js
@@ -1,5 +1,6 @@
import {TIME} from "/src/config/logging";
import {rn, minmax} from "/src/utils/numberUtils";
+import {rand, gauss, ra} from "@/utils/probabilityUtils";
window.Military = (function () {
const generate = function () {
diff --git a/modules/names-generator.js b/modules/names-generator.js
index 04517c62..69bf6795 100644
--- a/modules/names-generator.js
+++ b/modules/names-generator.js
@@ -1,6 +1,8 @@
import {last} from "/src/utils/arrayUtils";
import {locked} from "/src/scripts/options/lock";
import {tip} from "/src/scripts/tooltips";
+import {rand, P, ra} from "@/utils/probabilityUtils";
+import {capitalize} from "@/utils/stringUtils";
window.Names = (function () {
let chains = [];
diff --git a/modules/ocean-layers.js b/modules/ocean-layers.js
index 578e58dd..22a1398e 100644
--- a/modules/ocean-layers.js
+++ b/modules/ocean-layers.js
@@ -1,6 +1,8 @@
import {TIME} from "@/config/logging";
import {clipPoly} from "@/utils/lineUtils";
import {rn} from "@/utils/numberUtils";
+import {P} from "@/utils/probabilityUtils";
+import {round} from "@/utils/stringUtils";
window.OceanLayers = (function () {
let cells, vertices, pointsN, used;
diff --git a/modules/relief-icons.js b/modules/relief-icons.js
index 87c43183..2eea3633 100644
--- a/modules/relief-icons.js
+++ b/modules/relief-icons.js
@@ -1,5 +1,6 @@
import {getPackPolygon} from "/src/utils/graphUtils";
import {rn, minmax} from "/src/utils/numberUtils";
+import {rand} from "@/utils/probabilityUtils";
window.ReliefIcons = (function () {
const ReliefIcons = function () {
diff --git a/modules/religions-generator.js b/modules/religions-generator.js
index 6359463c..a156bde2 100644
--- a/modules/religions-generator.js
+++ b/modules/religions-generator.js
@@ -3,6 +3,7 @@ import {findAll} from "/src/utils/graphUtils";
import {unique} from "/src/utils/arrayUtils";
import {getRandomColor, getMixedColor} from "/src/utils/colorUtils";
import {rn} from "/src/utils/numberUtils";
+import {rand, P, ra, rw, biased} from "@/utils/probabilityUtils";
window.Religions = (function () {
// name generation approach and relative chance to be selected
diff --git a/modules/river-generator.js b/modules/river-generator.js
index 40902565..72e0126c 100644
--- a/modules/river-generator.js
+++ b/modules/river-generator.js
@@ -1,6 +1,7 @@
import {TIME} from "/src/config/logging";
import {last} from "/src/utils/arrayUtils";
import {rn} from "/src/utils/numberUtils";
+import {round} from "@/utils/stringUtils";
window.Rivers = (function () {
const generate = function (allowErosion = true) {
diff --git a/modules/routes-generator.js b/modules/routes-generator.js
index d4c61874..2dfed844 100644
--- a/modules/routes-generator.js
+++ b/modules/routes-generator.js
@@ -1,6 +1,7 @@
import {TIME} from "/src/config/logging";
import {findCell} from "/src/utils/graphUtils";
import {last} from "/src/utils/arrayUtils";
+import {round} from "@/utils/stringUtils";
window.Routes = (function () {
const getRoads = function () {
diff --git a/modules/ui/battle-screen.js b/modules/ui/battle-screen.js
index 99de89a0..73da895e 100644
--- a/modules/ui/battle-screen.js
+++ b/modules/ui/battle-screen.js
@@ -2,6 +2,8 @@ import {last} from "/src/utils/arrayUtils";
import {tip} from "/src/scripts/tooltips";
import {wiki} from "@/utils/linkUtils";
import {rn, minmax} from "/src/utils/numberUtils";
+import {rand, P, Pint} from "@/utils/probabilityUtils";
+import {capitalize} from "@/utils/stringUtils";
export class Battle {
constructor(attacker, defender) {
diff --git a/modules/ui/burg-editor.js b/modules/ui/burg-editor.js
index bd8d2f2a..a005fa0c 100644
--- a/modules/ui/burg-editor.js
+++ b/modules/ui/burg-editor.js
@@ -2,6 +2,8 @@ import {findCell} from "/src/utils/graphUtils";
import {tip, clearMainTip} from "/src/scripts/tooltips";
import {rn} from "/src/utils/numberUtils";
import {prompt} from "@/scripts/prompt";
+import {rand} from "@/utils/probabilityUtils";
+import {parseTransform} from "@/utils/stringUtils";
export function editBurg(id) {
if (customization) return;
diff --git a/modules/ui/coastline-editor.js b/modules/ui/coastline-editor.js
index e9073c0d..a092bb45 100644
--- a/modules/ui/coastline-editor.js
+++ b/modules/ui/coastline-editor.js
@@ -2,6 +2,7 @@ import {getPackPolygon} from "/src/utils/graphUtils";
import {tip} from "/src/scripts/tooltips";
import {clipPoly} from "@/utils/lineUtils";
import {rn} from "/src/utils/numberUtils";
+import {round} from "@/utils/stringUtils";
export function editCoastline(node = d3.event.target) {
if (customization) return;
diff --git a/modules/ui/editors.js b/modules/ui/editors.js
index 9c31cde6..0f91396d 100644
--- a/modules/ui/editors.js
+++ b/modules/ui/editors.js
@@ -3,6 +3,7 @@ import {findCell} from "/src/utils/graphUtils";
import {byId} from "/src/utils/shorthands";
import {tip} from "/src/scripts/tooltips";
import {rn, minmax, normalize} from "/src/utils/numberUtils";
+import {parseTransform} from "@/utils/stringUtils";
// clear elSelected variable
export function unselect() {
diff --git a/modules/ui/emblems-editor.js b/modules/ui/emblems-editor.js
index 3516706b..c938b1ed 100644
--- a/modules/ui/emblems-editor.js
+++ b/modules/ui/emblems-editor.js
@@ -2,6 +2,7 @@ import {clearMainTip} from "/src/scripts/tooltips";
import {tip} from "/src/scripts/tooltips";
import {openURL} from "@/utils/linkUtils";
import {rn} from "/src/utils/numberUtils";
+import {parseTransform} from "@/utils/stringUtils";
export function editEmblem(type, id, el) {
if (customization) return;
diff --git a/modules/ui/ice-editor.js b/modules/ui/ice-editor.js
index b9c24ad0..ccfc0d51 100644
--- a/modules/ui/ice-editor.js
+++ b/modules/ui/ice-editor.js
@@ -1,6 +1,8 @@
import {findGridCell, getGridPolygon} from "/src/utils/graphUtils";
import {tip, clearMainTip} from "/src/scripts/tooltips";
import {rn} from "/src/utils/numberUtils";
+import {ra} from "@/utils/probabilityUtils";
+import {parseTransform} from "@/utils/stringUtils";
export function editIce() {
if (customization) return;
diff --git a/modules/ui/labels-editor.js b/modules/ui/labels-editor.js
index 17541a0c..16c008c9 100644
--- a/modules/ui/labels-editor.js
+++ b/modules/ui/labels-editor.js
@@ -1,5 +1,7 @@
import {findCell} from "/src/utils/graphUtils";
import {tip, showMainTip} from "/src/scripts/tooltips";
+import {round, parseTransform} from "@/utils/stringUtils";
+import {parseTransform} from "@/utils/stringUtils";
export function editLabel() {
if (customization) return;
diff --git a/modules/ui/lakes-editor.js b/modules/ui/lakes-editor.js
index 9d1cd339..12e61db1 100644
--- a/modules/ui/lakes-editor.js
+++ b/modules/ui/lakes-editor.js
@@ -1,6 +1,8 @@
import {getPackPolygon} from "/src/utils/graphUtils";
import {tip} from "/src/scripts/tooltips";
import {rn} from "/src/utils/numberUtils";
+import {rand} from "@/utils/probabilityUtils";
+import {round} from "@/utils/stringUtils";
export function editLake() {
if (customization) return;
diff --git a/modules/ui/layers.js b/modules/ui/layers.js
index a4fec778..80b2375a 100644
--- a/modules/ui/layers.js
+++ b/modules/ui/layers.js
@@ -9,6 +9,7 @@ import {clipPoly} from "@/utils/lineUtils";
import {rn, minmax, normalize} from "/src/utils/numberUtils";
import {isCtrlClick} from "@/utils/keyboardUtils";
import {prompt} from "@/scripts/prompt";
+import {rand, P} from "@/utils/probabilityUtils";
let presets = {};
restoreCustomPresets(); // run on-load
diff --git a/modules/ui/military-overview.js b/modules/ui/military-overview.js
index 1644b3aa..3ae4c96c 100644
--- a/modules/ui/military-overview.js
+++ b/modules/ui/military-overview.js
@@ -1,6 +1,7 @@
import {tip} from "/src/scripts/tooltips";
import {wiki} from "@/utils/linkUtils";
import {rn} from "/src/utils/numberUtils";
+import {capitalize} from "@/utils/stringUtils";
export function overviewMilitary() {
if (customization) return;
diff --git a/modules/ui/options.js b/modules/ui/options.js
index cb05634f..f957e973 100644
--- a/modules/ui/options.js
+++ b/modules/ui/options.js
@@ -4,6 +4,7 @@ import {lock, locked} from "/src/scripts/options/lock";
import {tip, clearMainTip} from "/src/scripts/tooltips";
import {byId, stored} from "/src/utils/shorthands";
import {rn, minmax} from "/src/utils/numberUtils";
+import {rand, P, gauss} from "@/utils/probabilityUtils";
$("#optionsContainer").draggable({handle: ".drag-trigger", snap: "svg", snapMode: "both"});
$("#exitCustomization").draggable({handle: "div"});
diff --git a/modules/ui/provinces-editor.js b/modules/ui/provinces-editor.js
index 36990772..f02b4a87 100644
--- a/modules/ui/provinces-editor.js
+++ b/modules/ui/provinces-editor.js
@@ -4,6 +4,8 @@ import {unique} from "/src/utils/arrayUtils";
import {tip, showMainTip, clearMainTip} from "/src/scripts/tooltips";
import {getRandomColor} from "/src/utils/colorUtils";
import {rn} from "/src/utils/numberUtils";
+import {rand, P} from "@/utils/probabilityUtils";
+import {parseTransform} from "@/utils/stringUtils";
export function editProvinces() {
if (customization) return;
diff --git a/modules/ui/regiment-editor.js b/modules/ui/regiment-editor.js
index f943eb24..a0378140 100644
--- a/modules/ui/regiment-editor.js
+++ b/modules/ui/regiment-editor.js
@@ -3,6 +3,7 @@ import {findCell} from "/src/utils/graphUtils";
import {last} from "/src/utils/arrayUtils";
import {tip, clearMainTip} from "/src/scripts/tooltips";
import {rn} from "/src/utils/numberUtils";
+import {capitalize} from "@/utils/stringUtils";
export function editRegiment(selector) {
if (customization) return;
diff --git a/modules/ui/regiments-overview.js b/modules/ui/regiments-overview.js
index b8faae7e..56fa38b1 100644
--- a/modules/ui/regiments-overview.js
+++ b/modules/ui/regiments-overview.js
@@ -2,6 +2,7 @@ import {findCell} from "/src/utils/graphUtils";
import {last} from "/src/utils/arrayUtils";
import {tip, clearMainTip} from "/src/scripts/tooltips";
import {rn} from "/src/utils/numberUtils";
+import {capitalize} from "@/utils/stringUtils";
export function overviewRegiments(state) {
if (customization) return;
diff --git a/modules/ui/rivers-editor.js b/modules/ui/rivers-editor.js
index c0003183..3bcc953f 100644
--- a/modules/ui/rivers-editor.js
+++ b/modules/ui/rivers-editor.js
@@ -2,6 +2,7 @@ import {findCell, getPackPolygon} from "/src/utils/graphUtils";
import {tip, clearMainTip} from "/src/scripts/tooltips";
import {getSegmentId} from "@/utils/lineUtils";
import {rn} from "/src/utils/numberUtils";
+import {rand} from "@/utils/probabilityUtils";
export function editRiver(id) {
if (customization) return;
diff --git a/modules/ui/routes-editor.js b/modules/ui/routes-editor.js
index d4d562b5..c06f6fb9 100644
--- a/modules/ui/routes-editor.js
+++ b/modules/ui/routes-editor.js
@@ -1,6 +1,8 @@
import {tip, showMainTip, clearMainTip} from "/src/scripts/tooltips";
import {getSegmentId} from "@/utils/lineUtils";
import {rn} from "/src/utils/numberUtils";
+import {getNextId} from "@/utils/nodeUtils";
+import {round} from "@/utils/stringUtils";
export function editRoute(onClick) {
if (customization) return;
diff --git a/modules/ui/style.js b/modules/ui/style.js
index c89a70d5..c12974c3 100644
--- a/modules/ui/style.js
+++ b/modules/ui/style.js
@@ -1,5 +1,6 @@
import {tip} from "/src/scripts/tooltips";
import {rn} from "/src/utils/numberUtils";
+import {parseTransform} from "@/utils/stringUtils";
// add available filters to lists
{
diff --git a/modules/ui/stylePresets.js b/modules/ui/stylePresets.js
index 82c4de16..2f91c5e2 100644
--- a/modules/ui/stylePresets.js
+++ b/modules/ui/stylePresets.js
@@ -1,4 +1,5 @@
import {tip} from "/src/scripts/tooltips";
+import {isJsonValid} from "@/utils/stringUtils";
const systemPresets = [
"default",
@@ -45,7 +46,7 @@ async function getStylePreset(desiredPreset) {
ERROR && console.error(`Custom style ${desiredPreset} in not found in localStorage. Applying default style`);
presetToLoad = "default";
} else {
- const isValid = JSON.isValid(storedStyleJSON);
+ const isValid = isJsonValid(storedStyleJSON);
if (isValid) return [desiredPreset, JSON.parse(storedStyleJSON)];
ERROR &&
@@ -330,7 +331,7 @@ function addStylePreset() {
const desiredName = styleSaverName.value;
if (!styleJSON) return tip("Please provide a style JSON", false, "error");
- if (!JSON.isValid(styleJSON)) return tip("JSON string is not valid, please check the format", false, "error");
+ if (!isJsonValid(styleJSON)) return tip("JSON string is not valid, please check the format", false, "error");
if (!desiredName) return tip("Please provide a preset name", false, "error");
if (styleSaverTip.innerHTML === "default")
return tip("You cannot overwrite default preset, please change the name", false, "error");
@@ -350,7 +351,7 @@ function addStylePreset() {
const styleName = styleSaverName.value;
if (!styleJSON) return tip("Please provide a style JSON", false, "error");
- if (!JSON.isValid(styleJSON)) return tip("JSON string is not valid, please check the format", false, "error");
+ if (!isJsonValid(styleJSON)) return tip("JSON string is not valid, please check the format", false, "error");
if (!styleName) return tip("Please provide a preset name", false, "error");
downloadFile(styleJSON, styleName + ".json", "application/json");
@@ -362,7 +363,7 @@ function addStylePreset() {
function styleUpload(dataLoaded) {
if (!dataLoaded) return tip("Cannot load the file. Please check the data format", false, "error");
- const isValid = JSON.isValid(dataLoaded);
+ const isValid = isJsonValid(dataLoaded);
if (!isValid) return tip("Loaded data is not a valid JSON, please check the format", false, "error");
styleSaverJSON.value = JSON.stringify(JSON.parse(dataLoaded), null, 2);
diff --git a/modules/ui/temperature-graph.js b/modules/ui/temperature-graph.js
index 18bce918..2f9e7238 100644
--- a/modules/ui/temperature-graph.js
+++ b/modules/ui/temperature-graph.js
@@ -1,5 +1,6 @@
import {tip} from "/src/scripts/tooltips";
import {rn} from "/src/utils/numberUtils";
+import {round} from "@/utils/stringUtils";
export function showBurgTemperatureGraph(id) {
const b = pack.burgs[id];
diff --git a/modules/ui/tools.js b/modules/ui/tools.js
index 050d62df..8046fc37 100644
--- a/modules/ui/tools.js
+++ b/modules/ui/tools.js
@@ -5,6 +5,8 @@ import {tip, clearMainTip} from "/src/scripts/tooltips";
import {rn} from "/src/utils/numberUtils";
import {isCtrlClick} from "@/utils/keyboardUtils";
import {prompt} from "@/scripts/prompt";
+import {getNextId} from "@/utils/nodeUtils";
+import {P, generateSeed} from "@/utils/probabilityUtils";
toolsContent.addEventListener("click", function (event) {
if (customization) return tip("Please exit the customization mode first", false, "warning");
diff --git a/modules/ui/world-configurator.js b/modules/ui/world-configurator.js
index 3e04229b..0dfbe703 100644
--- a/modules/ui/world-configurator.js
+++ b/modules/ui/world-configurator.js
@@ -1,5 +1,6 @@
import {tip} from "/src/scripts/tooltips";
import {rn} from "/src/utils/numberUtils";
+import {round, parseTransform} from "@/utils/stringUtils";
export function editWorld() {
if (customization) return;
diff --git a/modules/ui/zones-editor.js b/modules/ui/zones-editor.js
index fab5163c..25273494 100644
--- a/modules/ui/zones-editor.js
+++ b/modules/ui/zones-editor.js
@@ -3,6 +3,7 @@ import {findAll, findCell, getPackPolygon} from "/src/utils/graphUtils";
import {unique} from "/src/utils/arrayUtils";
import {tip, showMainTip, clearMainTip} from "/src/scripts/tooltips";
import {rn} from "/src/utils/numberUtils";
+import {getNextId} from "@/utils/nodeUtils";
export function editZones() {
closeDialogs();
diff --git a/src/main.ts b/src/main.ts
index 4f245349..caf073b8 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -25,6 +25,7 @@ import {parseError} from "@/utils/errorUtils";
import {rn, minmax, normalize} from "./utils/numberUtils";
import {createTypedArray} from "./utils/arrayUtils";
import {clipPoly} from "@/utils/lineUtils";
+import {rand, P, gauss, ra, rw, generateSeed} from "@/utils/probabilityUtils";
import {byId} from "./utils/shorthands";
import "./components";
diff --git a/src/modules/legend.ts b/src/modules/legend.ts
index 2e0e4649..7bc21d6c 100644
--- a/src/modules/legend.ts
+++ b/src/modules/legend.ts
@@ -1,4 +1,5 @@
import {rn} from "../utils/numberUtils";
+import {parseTransform} from "@/utils/stringUtils";
export function drawLegend(name: string, data: unknown[]) {
legend.selectAll("*").remove(); // fully redraw every time
diff --git a/src/modules/measurers.js b/src/modules/measurers.js
index 21c98294..6dbe2af2 100644
--- a/src/modules/measurers.js
+++ b/src/modules/measurers.js
@@ -2,6 +2,7 @@ import {findCell} from "/src/utils/graphUtils";
import {last} from "/src/utils/arrayUtils";
import {getSegmentId} from "@/utils/lineUtils";
import {rn} from "/src/utils/numberUtils";
+import {round, parseTransform} from "@/utils/stringUtils";
export class Rulers {
constructor() {
diff --git a/src/scripts/events.ts b/src/scripts/events.ts
index e8b4924f..09e86afe 100644
--- a/src/scripts/events.ts
+++ b/src/scripts/events.ts
@@ -70,7 +70,7 @@ function showNotes(event: Event) {
// show viewbox tooltip if main tooltip is blank
function showMapTooltip(point: number[], event: Event, packCellId: number, gridCellId: number) {
tip(""); // clear tip
- const path = event.composedPath ? event.composedPath() : getComposedPath(event.target); // apply polyfill
+ const path = event.composedPath();
if (!path[path.length - 8]) return;
const group = path[path.length - 7].id;
const subgroup = path[path.length - 8].id;
diff --git a/utils/languageUtils.js b/src/utils/languageUtils.js
similarity index 99%
rename from utils/languageUtils.js
rename to src/utils/languageUtils.js
index 3b0c580e..92963994 100644
--- a/utils/languageUtils.js
+++ b/src/utils/languageUtils.js
@@ -1,4 +1,4 @@
-"use strict";
+import {P} from "@/utils/probabilityUtils";
// chars that serve as vowels
const VOWELS = `aeiouyɑ'əøɛœæɶɒɨɪɔɐʊɤɯаоиеёэыуюяàèìòùỳẁȁȅȉȍȕáéíóúýẃőűâêîôûŷŵäëïöüÿẅãẽĩõũỹąęįǫųāēīōūȳăĕĭŏŭǎěǐǒǔȧėȯẏẇạẹịọụỵẉḛḭṵṳ`;
diff --git a/src/utils/nodeUtils.ts b/src/utils/nodeUtils.ts
new file mode 100644
index 00000000..4befb5d4
--- /dev/null
+++ b/src/utils/nodeUtils.ts
@@ -0,0 +1,7 @@
+import {byId} from "./shorthands";
+
+// get next unused id
+export function getNextId(core: string, index = 1) {
+ while (byId(core + index)) index++;
+ return core + index;
+}
diff --git a/src/utils/probabilityUtils.ts b/src/utils/probabilityUtils.ts
new file mode 100644
index 00000000..c9e2c284
--- /dev/null
+++ b/src/utils/probabilityUtils.ts
@@ -0,0 +1,84 @@
+import {ERROR} from "@/config/logging";
+import {minmax, rn} from "./numberUtils";
+
+const d3 = window.d3;
+
+// random number in range
+export function rand(min: number, max: number) {
+ if (min === undefined && max === undefined) return Math.random();
+ if (max === undefined) {
+ max = min;
+ min = 0;
+ }
+ return Math.floor(Math.random() * (max - min + 1)) + min;
+}
+
+// probability shorthand
+export function P(probability: number) {
+ if (probability >= 1) return true;
+ if (probability <= 0) return false;
+ return Math.random() < probability;
+}
+
+export function each(n: number) {
+ return (i: number) => i % n === 0;
+}
+
+// random number using normal distribution
+export function gauss(expected = 100, deviation = 30, min = 0, max = 300, round = 0) {
+ const randomValue = d3.randomNormal(expected, deviation);
+ const clamped = minmax(randomValue(), min, max);
+ return rn(clamped, round);
+}
+
+// probability shorthand for floats
+export function Pint(float: number) {
+ return ~~float + +P(float % 1);
+}
+
+// return random value from the array
+export function ra(array: T[]) {
+ return array[Math.floor(Math.random() * array.length)];
+}
+
+// return random value from weighted array
+export function rw(object: {[key: string]: number}) {
+ const weightedArray = Object.entries(object)
+ .map(([choise, weight]) => new Array(weight).fill(choise))
+ .flat();
+ return ra(weightedArray);
+}
+
+// return a random integer from min to max biased towards one end based on exponent distribution (the bigger ex the higher bias towards min)
+export function biased(min: number, max: number, ex: number) {
+ return Math.round(min + (max - min) * Math.pow(Math.random(), ex));
+}
+
+// get number from string in format "1-3" or "2" or "0.5"
+export function getNumberInRange(rangeString: string) {
+ if (typeof rangeString !== "string") {
+ ERROR && console.error("The value should be a string", rangeString);
+ return 0;
+ }
+
+ const rangeNumber = Number(rangeString);
+ if (!isNaN(rangeNumber)) return Pint(rangeNumber);
+
+ const negative = rangeString.startsWith("-");
+ const sign = negative ? -1 : 1;
+ if (negative) rangeString = rangeString.substring(1);
+
+ const [min, max] = rangeString.split("-");
+ const count = rand(sign * +min, +max);
+
+ if (isNaN(count) || count < 0) {
+ ERROR && console.error("Cannot parse number. Check the format", rangeString);
+ return 0;
+ }
+
+ return count;
+}
+
+export function generateSeed() {
+ return String(Math.floor(Math.random() * 1e9));
+}
diff --git a/utils/stringUtils.js b/src/utils/stringUtils.ts
similarity index 70%
rename from utils/stringUtils.js
rename to src/utils/stringUtils.ts
index 2380e325..ffbf3b3b 100644
--- a/utils/stringUtils.js
+++ b/src/utils/stringUtils.ts
@@ -1,22 +1,21 @@
-import {rn} from "/src/utils/numberUtils";
+import {rn} from "@/utils/numberUtils";
// round numbers in string to d decimals
-function round(s, d = 1) {
- return s.replace(/[\d\.-][\d\.e-]*/g, function (n) {
- return rn(n, d);
- });
+export function round(str: string, d = 1) {
+ return str.replace(/[\d\.-][\d\.e-]*/g, n => String(rn(+n, d)));
}
// return string with 1st char capitalized
-function capitalize(string) {
- return string.charAt(0).toUpperCase() + string.slice(1);
+export function capitalize(str: string) {
+ return str.charAt(0).toUpperCase() + str.slice(1);
}
// split string into 2 almost equal parts not breaking words
-function splitInTwo(str) {
+export function splitInTwo(str: string) {
const half = str.length / 2;
const ar = str.split(" ");
if (ar.length < 2) return ar; // only one word
+
let first = "",
last = "",
middle = "",
@@ -36,10 +35,10 @@ function splitInTwo(str) {
}
// transform string to array [translateX,translateY,rotateDeg,rotateX,rotateY,scale]
-function parseTransform(string) {
- if (!string) return [0, 0, 0, 0, 0, 1];
+export function parseTransform(str: string) {
+ if (!str) return [0, 0, 0, 0, 0, 1];
- const a = string
+ const a = str
.replace(/[a-z()]/g, "")
.replace(/[ ]/g, ",")
.split(",");
@@ -47,7 +46,7 @@ function parseTransform(string) {
}
// check if string is a valid for JSON parse
-JSON.isValid = str => {
+export const isJsonValid = (str: string) => {
try {
JSON.parse(str);
} catch (e) {
diff --git a/utils/unitUtils.js b/src/utils/unitUtils.js
similarity index 100%
rename from utils/unitUtils.js
rename to src/utils/unitUtils.js
diff --git a/utils/nodeUtils.js b/utils/nodeUtils.js
deleted file mode 100644
index 0010f3d8..00000000
--- a/utils/nodeUtils.js
+++ /dev/null
@@ -1,30 +0,0 @@
-"use strict";
-// FMG utils related to nodes
-
-// remove parent element (usually if child is clicked)
-function removeParent() {
- this.parentNode.parentNode.removeChild(this.parentNode);
-}
-
-// polyfill for composedPath
-function getComposedPath(node) {
- let parent;
- if (node.parentNode) parent = node.parentNode;
- else if (node.host) parent = node.host;
- else if (node.defaultView) parent = node.defaultView;
- if (parent !== undefined) return [node].concat(getComposedPath(parent));
- return [node];
-}
-
-// get next unused id
-function getNextId(core, i = 1) {
- while (document.getElementById(core + i)) i++;
- return core + i;
-}
-
-function getAbsolutePath(href) {
- if (!href) return "";
- const link = document.createElement("a");
- link.href = href;
- return link.href;
-}
diff --git a/utils/probabilityUtils.js b/utils/probabilityUtils.js
deleted file mode 100644
index 1c098bdc..00000000
--- a/utils/probabilityUtils.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import {rn, minmax} from "/src/utils/numberUtils";
-
-// random number in a range
-function rand(min, max) {
- if (min === undefined && max === undefined) return Math.random();
- if (max === undefined) {
- max = min;
- min = 0;
- }
- return Math.floor(Math.random() * (max - min + 1)) + min;
-}
-
-// probability shorthand
-function P(probability) {
- if (probability >= 1) return true;
- if (probability <= 0) return false;
- return Math.random() < probability;
-}
-
-function each(n) {
- return i => i % n === 0;
-}
-
-// random number (normal or gaussian distribution)
-function gauss(expected = 100, deviation = 30, min = 0, max = 300, round = 0) {
- return rn(minmax(d3.randomNormal(expected, deviation)(), min, max), round);
-}
-
-// probability shorthand for floats
-function Pint(float) {
- return ~~float + +P(float % 1);
-}
-
-// return random value from the array
-function ra(array) {
- return array[Math.floor(Math.random() * array.length)];
-}
-
-// return random value from weighted array {"key1":weight1, "key2":weight2}
-function rw(object) {
- const array = [];
- for (const key in object) {
- for (let i = 0; i < object[key]; i++) {
- array.push(key);
- }
- }
- return array[Math.floor(Math.random() * array.length)];
-}
-
-// return a random integer from min to max biased towards one end based on exponent distribution (the bigger ex the higher bias towards min)
-function biased(min, max, ex) {
- return Math.round(min + (max - min) * Math.pow(Math.random(), ex));
-}
-
-// get number from string in format "1-3" or "2" or "0.5"
-function getNumberInRange(r) {
- if (typeof r !== "string") {
- ERROR && console.error("The value should be a string", r);
- return 0;
- }
- if (!isNaN(+r)) return ~~r + +P(r - ~~r);
- const sign = r[0] === "-" ? -1 : 1;
- if (isNaN(+r[0])) r = r.slice(1);
- const range = r.includes("-") ? r.split("-") : null;
- if (!range) {
- ERROR && console.error("Cannot parse the number. Check the format", r);
- return 0;
- }
- const count = rand(range[0] * sign, +range[1]);
- if (isNaN(count) || count < 0) {
- ERROR && console.error("Cannot parse number. Check the format", r);
- return 0;
- }
- return count;
-}
-
-function generateSeed() {
- return String(Math.floor(Math.random() * 1e9));
-}