Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
b2437e3
add/data/any-imports [1.2.3-add-data-any-imports.0]
SUNsung Feb 11, 2026
60760b8
add/data/any-imports [1.2.3-add-data-any-imports.0]
SUNsung Feb 11, 2026
a31f98a
add/data/any-imports [1.2.3-add-data-any-imports.0]
SUNsung Feb 11, 2026
4c7604d
add/data/any-imports [1.2.3]
SUNsung Feb 12, 2026
489e854
add/data/any-imports [1.2.4-add-data-any-imports.0]
SUNsung Feb 12, 2026
4248e83
add/data/any-imports [1.2.4-add-data-any-imports.0]
SUNsung Feb 12, 2026
37cd88b
add/data/any-imports [1.2.4-add-data-any-imports.0]
SUNsung Feb 12, 2026
037532a
add/data/any-imports [1.2.4-add-data-any-imports.1]
SUNsung Feb 12, 2026
32ca416
add/data/any-imports [1.2.4-add-data-any-imports.1]
SUNsung Feb 12, 2026
bda099e
add/data/any-imports [1.2.4-add-data-any-imports.1]
SUNsung Feb 13, 2026
c2daf3a
add/data/any-imports [1.2.4-add-data-any-imports.1]
SUNsung Feb 13, 2026
083350d
add/data/any-imports [1.2.4-add-data-any-imports.1]
SUNsung Feb 14, 2026
d70d1b9
add/data/any-imports [1.2.4-add-data-any-imports.1]
SUNsung Feb 14, 2026
ecd4999
add/data/any-imports [1.2.4-add-data-any-imports.1]
SUNsung Feb 14, 2026
8f559a8
add/data/any-imports [1.2.4-add-data-any-imports.1]
SUNsung Feb 14, 2026
ac620b0
add/data/any-imports [1.2.4-add-data-any-imports.1]
SUNsung Feb 14, 2026
1b56b5f
add/data/any-imports [1.2.4-add-data-any-imports.1]
SUNsung Feb 14, 2026
dfd8f9c
add/data/any-imports [1.2.4-add-data-any-imports.2]
SUNsung Feb 14, 2026
65d5605
add/data/any-imports [1.2.4-add-data-any-imports.2]
SUNsung Feb 14, 2026
63ca2e7
add/data/any-imports [1.2.4-add-data-any-imports.2]
SUNsung Feb 14, 2026
e94f49c
add/data/any-imports [1.2.4-add-data-any-imports.2]
SUNsung Feb 14, 2026
f4896b4
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
eb45920
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
8cb76e0
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
b6ec3ad
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
9da791b
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
6bd1067
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
6fa3f46
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
4c55727
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
d6ef2df
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
f66d709
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
be0a72d
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
fb7fdb5
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
679e606
add/data/any-imports [1.2.4-add-data-any-imports.3]
SUNsung Feb 14, 2026
a1ec699
add/data/any-imports [1.2.4-add-data-any-imports.4]
SUNsung Feb 14, 2026
c0e70f8
add/data/any-imports [1.2.4-add-data-any-imports.5]
SUNsung Feb 15, 2026
3340a4c
add/data/any-imports [1.2.4-add-data-any-imports.5]
SUNsung Feb 15, 2026
4acb6a5
add/data/any-imports [1.2.4-add-data-any-imports.5]
SUNsung Feb 15, 2026
d3bb90b
add/data/any-imports [1.2.4-add-data-any-imports.5]
SUNsung Feb 15, 2026
908a940
add/data/any-imports [1.2.4-add-data-any-imports.5]
SUNsung Feb 15, 2026
1bd36b8
add/data/any-imports [1.2.4-add-data-any-imports.6]
SUNsung Feb 15, 2026
9aa7c3e
add/data/any-imports [1.2.4-add-data-any-imports.6]
SUNsung Feb 15, 2026
0a1ae56
add/data/any-imports [1.2.4-add-data-any-imports.6]
SUNsung Feb 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ When deploying to a server, it’s enough to move the contents of the `dist` fol

This project is built based on predefined values and page templates; to make changes, it’s enough to interact with these files:

-[package.json](./package.json)
-[static.config.mjs](./static.config.mjs)
-[pages.config.mjs](./pages.config.mjs)
- [package.json](./package.json)
- [static.config.mjs](./static.config.mjs)
- [pages.config.mjs](./pages.config.mjs)

If needed, you can “cut out” only one specific generator — at the code level they are self-contained and independent of their neighbors.

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "fantasy-maphub",
"name_full": "Fantasy MapHub Generators",
"version": "1.2.3",
"version": "1.2.4-add-data-any-imports.6",
"description": "An offline-first hub that bundles several Watabou map generators into one consistent web app: same UI patterns, local assets, and modern import/export. It adds OpenAPI docs, proto-first serialization (including pure protobuf files), and a PWA build so everything works without an internet connection.",
"license": "MPL-2.0",
"author": "mail@sunsung.fun",
Expand Down
93 changes: 1 addition & 92 deletions protobuf/data/geo/editor.proto
Original file line number Diff line number Diff line change
Expand Up @@ -7,99 +7,8 @@ import "data/geo/enum.proto";

// // // //

message EditorPoint2DObj {
double x = 1;
double y = 2;
}

message EditorPolylineObj {
repeated EditorPoint2DObj points = 1;
bool closed = 2;
}

message EditorBezierObj {
repeated EditorPoint2DObj control_points = 1;

bool closed = 2;
uint32 segments = 3;
}

message EditorArcObj {
EditorPoint2DObj center = 1;
double radius = 2;
double start_angle_rad = 3;
double end_angle_rad = 4;
bool ccw = 5;
}

message EditorLinkObj {
string a_uid = 1;
string b_uid = 2;
EditorLinkType type = 3;
google.protobuf.Struct props = 4;
}

message EditorLayerStateObj {
string layer_id = 1;
bool visible = 2;
bool locked = 3;
int32 z_index = 4;
}

message EditorGroupObj {
string group_uid = 1;
string name = 2;
repeated string member_uids = 3;
google.protobuf.Struct props = 4;
}

message EditorRoadModelObj {
string target_uid = 1;
EditorPolylineObj centerline = 2;
double width = 3;
bool closed = 4;
google.protobuf.Struct props = 5;
}

message EditorShapeModelObj {
string target_uid = 1;

oneof model {
EditorPolylineObj polyline = 2;
EditorBezierObj bezier = 3;
EditorArcObj arc = 4;
}

google.protobuf.Struct props = 10;
}

message EditorSnapNodeObj {
string node_uid = 1;
EditorPoint2DObj pos = 2;
repeated string incident_uids = 3;
google.protobuf.Struct props = 4;
}

message EditorConstraintObj {
string constraint_uid = 1;
EditorConstraintType type = 2;
repeated string target_uids = 3;
google.protobuf.Struct params = 4;
}

message EditorPayloadObj {
uint32 payload_rev = 1;
EditorCoordSpaceType coord_space = 2;

repeated EditorLayerStateObj layers = 10;
repeated EditorGroupObj groups = 11;
repeated EditorLinkObj links = 12;

repeated EditorRoadModelObj road_models = 20;
repeated EditorShapeModelObj shape_models = 21;

repeated EditorSnapNodeObj snap_nodes = 30;
repeated EditorConstraintObj constraints = 31;

google.protobuf.Struct props = 40;
google.protobuf.Struct props = 3;
}
16 changes: 0 additions & 16 deletions protobuf/data/geo/enum.proto
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,3 @@ enum EditorCoordSpaceType {
export = 2;
}

enum EditorLinkType {
EDITOR_LINK_TYPE_UNSPECIFIED = 0;
EDITOR_LINK_TYPE_PARENT_CHILD = 1;
EDITOR_LINK_TYPE_GROUP_MEMBER = 2;
EDITOR_LINK_TYPE_ATTACH = 3;
EDITOR_LINK_TYPE_OVER_UNDER = 4;
EDITOR_LINK_TYPE_ALONG = 5;
}

enum EditorConstraintType {
EDITOR_CONSTRAINT_TYPE_UNSPECIFIED = 0;
EDITOR_CONSTRAINT_TYPE_SNAP = 1;
EDITOR_CONSTRAINT_TYPE_FIXED_LENGTH = 2;
EDITOR_CONSTRAINT_TYPE_PARALLEL = 3;
EDITOR_CONSTRAINT_TYPE_PERPENDICULAR = 4;
}
8 changes: 2 additions & 6 deletions protobuf/data/geo/obj.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ message GeoObj {
GeoType type = 1;
GeoObj geometry = 2;
google.protobuf.ListValue coordinates = 3;
reserved 4 to 8;
string embed_uid = 9;
reserved 4 to 9;

repeated GeoObj features = 10;
repeated GeoObj geometries = 11;
reserved 12 to 16;
repeated GeoPartObj embed_parts = 17;
GeoTransformObj embed_export_transform = 18;
GeoBBoxObj embed_bbox = 19;
reserved 12 to 19;

optional GeoGeneratorType generator = 20;
optional GeoFeatureType id = 21;
Expand Down
194 changes: 157 additions & 37 deletions src/js/Cave.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as DataCave from "./shared/data/Cave.js";
import * as DataGlade from "./shared/data/Glade.js";

const params = FuncProto.initParams(JSON.parse(String.raw`{{EMBED_PARAMETERS_JSON_CAVE}}`));
const isFrame = typeof window.parent.pingFrame === "function"

var $lime_init = function (A, r) {
var C = function (r, C) {
Expand Down Expand Up @@ -5559,6 +5560,111 @@ var $lime_init = function (A, r) {
v = fb.embedded.h[a];
return null != v ? (Ma.addImport(v.url), v.name) : Ma.substituteGenerics(a)
};
fb._busyOverlay = {
active: !1,
el: null,
textEl: null,
listeners: null,
ensure: function () {
if (null != this.el) return;
var a = window.document;
var b = a.createElement("div");
b.id = "cave-busy-overlay";
b.style.cssText = "position:fixed;inset:0;display:none;align-items:center;justify-content:center;text-align:center;background:rgba(0,0,0,0.55);color:#fff;z-index:2147483647;pointer-events:auto;";
var c = a.createElement("div");
c.style.cssText = "display:flex;flex-direction:column;align-items:center;gap:12px;padding:18px 22px;border-radius:10px;background:rgba(0,0,0,0.6);box-shadow:0 8px 24px rgba(0,0,0,0.4);max-width:80vw;";
var d = a.createElement("div");
d.style.cssText = "width:28px;height:28px;border:3px solid rgba(255,255,255,0.35);border-top-color:#fff;border-radius:50%;animation:cave-busy-spin 0.8s linear infinite;";
var f = a.createElement("div");
f.style.cssText = "font:16px/1.4 'Share Tech Mono', monospace;letter-spacing:0.02em;";
f.textContent = "Please wait...";
c.appendChild(d);
c.appendChild(f);
b.appendChild(c);
this.el = b;
this.textEl = f;
(a.body || a.documentElement).appendChild(b);
if (null == a.getElementById("cave-busy-style")) {
var h = a.createElement("style");
h.id = "cave-busy-style";
h.textContent = "@keyframes cave-busy-spin{to{transform:rotate(360deg);}}";
(a.head || a.documentElement).appendChild(h)
}
},
attach: function () {
if (null != this.listeners) return;
var a = this;
var b = function (c) {
if (!a.active) return;
c.preventDefault();
c.stopPropagation();
return !1
};
var c = {
capture: !0,
passive: !1
};
var d = window.document;
var f = ["keydown", "keyup", "keypress", "mousedown", "mouseup", "click", "dblclick", "contextmenu", "wheel", "touchstart", "touchmove", "touchend", "touchcancel", "pointerdown", "pointermove", "pointerup"];
var h = 0;
for (; h < f.length;) d.addEventListener(f[h++], b, c);
this.listeners = {
handler: b,
options: c,
events: f
};
try {
null != d.activeElement && d.activeElement.blur()
} catch (k) {
}
},
detach: function () {
if (null == this.listeners) return;
var a = window.document;
var b = this.listeners.events;
var c = this.listeners.handler;
var d = this.listeners.options;
var f = 0;
for (; f < b.length;) a.removeEventListener(b[f++], c, d);
this.listeners = null
},
show: function (a) {
this.ensure();
this.textEl.textContent = null != a && "" !== a ? a : "Please wait...";
this.el.style.display = "flex";
this.active = !0;
this.attach()
},
hide: function () {
if (null == this.el) return;
this.active = !1;
this.el.style.display = "none";
this.detach()
}
};
fb.runBusy = function (a, b, c) {
fb._busyOverlay.show(a);
var d = function () {
try {
b()
} catch (f) {
if ("function" == typeof c) {
c(f);
return
}
throw f
} finally {
fb._busyOverlay.hide()
}
};
if (null != window.requestAnimationFrame) {
window.requestAnimationFrame(function () {
window.requestAnimationFrame(function () {
window.setTimeout(d, 0)
})
})
} else window.setTimeout(d, 0)
};
fb.__super__ = Kd;
fb.prototype = u(Kd.prototype, {
layout: function () {
Expand Down Expand Up @@ -5866,44 +5972,58 @@ var $lime_init = function (A, r) {
}))
},
exportPNG: function () {
var a = this.rWidth,
b = this.rHeight,
c = this.model.rect.width,
d = this.model.rect.height,
f = .2 * Math.max(c, d);
c += f;
d += f;
this.setSize(c, d);
var h = Math.sqrt(16777215 / (c * d));
c = c * h | 0;
d = d * h | 0;
f = new wa;
f.scale(h, h);
h = new Wb(c, d, !1, this.getBgColor());
h.draw(this, f);
fb.showTitle && (this.removeChild(this.title),
this.addChild(this.title = mc.get(this.model.name, mc.format("title", 48))), this.title.set_textColor(this.view.getTextColor()));
this.setSize(a, b);
Ld.savePNG(h, this.model.name);
h.dispose()
var a = this;
fb.runBusy("Exporting PNG file...", function () {
var b = a.rWidth,
c = a.rHeight,
d = a.model.rect.width,
f = a.model.rect.height,
h = .2 * Math.max(d, f);
d += h;
f += h;
a.setSize(d, f);
var k = Math.sqrt(16777215 / (d * f));
d = d * k | 0;
f = f * k | 0;
h = new wa;
h.scale(k, k);
k = new Wb(d, f, !1, a.getBgColor());
k.draw(a, h);
fb.showTitle && (a.removeChild(a.title),
a.addChild(a.title = mc.get(a.model.name, mc.format("title", 48))), a.title.set_textColor(a.view.getTextColor()));
a.setSize(b, c);
Ld.savePNG(k, a.model.name);
k.dispose()
}, function (b) {
var msg = b && b.message || "" + b;
console.error(msg);
Fa.showToast(msg)
})
},
exportSVG: function () {
var a = this.rWidth,
b = this.rHeight,
c = this.model.rect.width,
d = this.model.rect.height,
f = .2 * Math.max(c, d);
this.setSize(c + f, d + f);
Ma.substituteFont = fb.fixFontNames;
c = Ma.create(this.rWidth, this.rHeight, this.getBgColor());
d = Ma.drawSprite(this);
c.root.addChild(d);
this.setSize(a, b);
d = Ma.getImports();
c.root.addChild(d);
d = Ma.getGradients();
c.root.addChild(d);
Ld.saveText('<?xml version="1.0" encoding="UTF-8" standalone="no"?>' + Ke.print(c.root), this.model.name + ".cv.svg", "image/svg+xml")
var a = this;
fb.runBusy("Exporting SVG file...", function () {
var b = a.rWidth,
c = a.rHeight,
d = a.model.rect.width,
f = a.model.rect.height,
h = .2 * Math.max(d, f);
a.setSize(d + h, f + h);
Ma.substituteFont = fb.fixFontNames;
d = Ma.create(a.rWidth, a.rHeight, a.getBgColor());
f = Ma.drawSprite(a);
d.root.addChild(f);
a.setSize(b, c);
f = Ma.getImports();
d.root.addChild(f);
f = Ma.getGradients();
d.root.addChild(f);
Ld.saveText('<?xml version="1.0" encoding="UTF-8" standalone="no"?>' + Ke.print(d.root), a.model.name + ".cv.svg", "image/svg+xml")
}, function (b) {
var msg = b && b.message || "" + b;
console.error(msg);
Fa.showToast(msg)
})
},
toggleGlade: function () {
fb.showGlade = !fb.showGlade;
Expand Down Expand Up @@ -46112,4 +46232,4 @@ var $lime_init = function (A, r) {
if (params !== null) {
console.debug(params);
$lime_init("undefined" !== typeof exports ? exports : "function" === typeof define && define.amd ? {} : "undefined" !== typeof window ? window : "undefined" !== typeof self ? self : this, "undefined" !== typeof window ? window : "undefined" !== typeof global ? global : "undefined" !== typeof self ? self : this);
}
}
Loading