worldorbit 2.5.15 → 2.5.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/browser/core/dist/index.js +2444 -342
- package/dist/browser/editor/dist/index.js +11702 -0
- package/dist/browser/markdown/dist/index.js +2207 -392
- package/dist/browser/viewer/dist/index.js +2302 -382
- package/dist/unpkg/core/dist/index.js +2447 -345
- package/dist/unpkg/editor/dist/index.js +11727 -0
- package/dist/unpkg/markdown/dist/index.js +2210 -395
- package/dist/unpkg/viewer/dist/index.js +2305 -385
- package/dist/unpkg/worldorbit-core.min.js +12 -12
- package/dist/unpkg/worldorbit-editor.min.js +894 -0
- package/dist/unpkg/worldorbit-markdown.min.js +66 -58
- package/dist/unpkg/worldorbit-viewer.min.js +76 -68
- package/dist/unpkg/worldorbit.js +797 -78
- package/dist/unpkg/worldorbit.min.js +80 -72
- package/package.json +3 -2
- package/packages/core/dist/atlas-edit.js +74 -0
- package/packages/core/dist/atlas-validate.js +122 -8
- package/packages/core/dist/draft-parse.js +212 -8
- package/packages/core/dist/draft.d.ts +5 -2
- package/packages/core/dist/draft.js +59 -3
- package/packages/core/dist/format.js +63 -1
- package/packages/core/dist/normalize.js +1 -0
- package/packages/core/dist/scene.js +248 -46
- package/packages/core/dist/types.d.ts +41 -2
- package/packages/editor/dist/editor.d.ts +2 -0
- package/packages/editor/dist/editor.js +3578 -0
- package/packages/editor/dist/index.d.ts +2 -0
- package/packages/editor/dist/index.js +1 -0
- package/packages/editor/dist/types.d.ts +55 -0
- package/packages/editor/dist/types.js +1 -0
- package/packages/markdown/dist/html.d.ts +3 -0
- package/packages/markdown/dist/html.js +57 -0
- package/packages/markdown/dist/index.d.ts +4 -0
- package/packages/markdown/dist/index.js +3 -0
- package/packages/markdown/dist/rehype.d.ts +10 -0
- package/packages/markdown/dist/rehype.js +49 -0
- package/packages/markdown/dist/remark.d.ts +9 -0
- package/packages/markdown/dist/remark.js +28 -0
- package/packages/markdown/dist/types.d.ts +11 -0
- package/packages/markdown/dist/types.js +1 -0
- package/packages/viewer/dist/atlas-state.js +6 -0
- package/packages/viewer/dist/atlas-viewer.js +1 -0
- package/packages/viewer/dist/render.js +31 -2
- package/packages/viewer/dist/theme.js +1 -0
- package/packages/viewer/dist/tooltip.js +9 -0
- package/packages/viewer/dist/types.d.ts +8 -1
- package/packages/viewer/dist/viewer.js +12 -1
package/dist/unpkg/worldorbit.js
CHANGED
|
@@ -647,6 +647,7 @@ var WorldOrbit = (() => {
|
|
|
647
647
|
system,
|
|
648
648
|
groups: [],
|
|
649
649
|
relations: [],
|
|
650
|
+
events: [],
|
|
650
651
|
objects
|
|
651
652
|
};
|
|
652
653
|
}
|
|
@@ -1104,8 +1105,10 @@ var WorldOrbit = (() => {
|
|
|
1104
1105
|
const scaleModel = resolveScaleModel(layoutPreset, options.scaleModel);
|
|
1105
1106
|
const spacingFactor = layoutPresetSpacing(layoutPreset);
|
|
1106
1107
|
const systemId = document2.system?.id ?? null;
|
|
1107
|
-
const
|
|
1108
|
-
const
|
|
1108
|
+
const activeEventId = options.activeEventId ?? null;
|
|
1109
|
+
const effectiveObjects = createEffectiveObjects(document2.objects, document2.events ?? [], activeEventId);
|
|
1110
|
+
const objectMap = new Map(effectiveObjects.map((object) => [object.id, object]));
|
|
1111
|
+
const relationships = buildSceneRelationships(effectiveObjects, objectMap);
|
|
1109
1112
|
const positions = /* @__PURE__ */ new Map();
|
|
1110
1113
|
const orbitDrafts = [];
|
|
1111
1114
|
const leaderDrafts = [];
|
|
@@ -1114,7 +1117,7 @@ var WorldOrbit = (() => {
|
|
|
1114
1117
|
const atObjects = [];
|
|
1115
1118
|
const surfaceChildren = /* @__PURE__ */ new Map();
|
|
1116
1119
|
const orbitChildren = /* @__PURE__ */ new Map();
|
|
1117
|
-
for (const object of
|
|
1120
|
+
for (const object of effectiveObjects) {
|
|
1118
1121
|
const placement = object.placement;
|
|
1119
1122
|
if (!placement) {
|
|
1120
1123
|
rootObjects.push(object);
|
|
@@ -1209,13 +1212,14 @@ var WorldOrbit = (() => {
|
|
|
1209
1212
|
const objects = [...positions.values()].map((position) => createSceneObject(position, scaleModel, relationships));
|
|
1210
1213
|
const orbitVisuals = orbitDrafts.map((draft) => createOrbitVisual(draft, relationships.groupIds.get(draft.object.id) ?? null));
|
|
1211
1214
|
const leaders = leaderDrafts.map((draft) => createLeaderLine(draft));
|
|
1212
|
-
const labels = createSceneLabels(objects, height, scaleModel.labelMultiplier);
|
|
1215
|
+
const labels = createSceneLabels(objects, width, height, scaleModel.labelMultiplier);
|
|
1213
1216
|
const relations = createSceneRelations(document2, objects);
|
|
1214
|
-
const
|
|
1215
|
-
const
|
|
1217
|
+
const events = createSceneEvents(document2.events ?? [], objects, activeEventId);
|
|
1218
|
+
const layers = createSceneLayers(orbitVisuals, relations, events, leaders, objects, labels);
|
|
1219
|
+
const groups = createSceneGroups(objects, orbitVisuals, leaders, labels, relationships, scaleModel.labelMultiplier);
|
|
1216
1220
|
const semanticGroups = createSceneSemanticGroups(document2, objects);
|
|
1217
1221
|
const viewpoints = createSceneViewpoints(document2, projection, frame.preset, relationships, objectMap);
|
|
1218
|
-
const contentBounds = calculateContentBounds(width, height, objects, orbitVisuals, leaders, labels);
|
|
1222
|
+
const contentBounds = calculateContentBounds(width, height, objects, orbitVisuals, leaders, labels, scaleModel.labelMultiplier);
|
|
1219
1223
|
return {
|
|
1220
1224
|
width,
|
|
1221
1225
|
height,
|
|
@@ -1241,6 +1245,8 @@ var WorldOrbit = (() => {
|
|
|
1241
1245
|
groups,
|
|
1242
1246
|
semanticGroups,
|
|
1243
1247
|
viewpoints,
|
|
1248
|
+
events,
|
|
1249
|
+
activeEventId,
|
|
1244
1250
|
objects,
|
|
1245
1251
|
orbitVisuals,
|
|
1246
1252
|
relations,
|
|
@@ -1259,6 +1265,35 @@ var WorldOrbit = (() => {
|
|
|
1259
1265
|
y: center.y + dx * sin + dy * cos
|
|
1260
1266
|
};
|
|
1261
1267
|
}
|
|
1268
|
+
function createEffectiveObjects(objects, events, activeEventId) {
|
|
1269
|
+
const cloned = objects.map((object) => structuredClone(object));
|
|
1270
|
+
if (!activeEventId) {
|
|
1271
|
+
return cloned;
|
|
1272
|
+
}
|
|
1273
|
+
const activeEvent = events.find((event) => event.id === activeEventId);
|
|
1274
|
+
if (!activeEvent) {
|
|
1275
|
+
return cloned;
|
|
1276
|
+
}
|
|
1277
|
+
const objectMap = new Map(cloned.map((object) => [object.id, object]));
|
|
1278
|
+
for (const pose of activeEvent.positions) {
|
|
1279
|
+
const object = objectMap.get(pose.objectId);
|
|
1280
|
+
if (!object) {
|
|
1281
|
+
continue;
|
|
1282
|
+
}
|
|
1283
|
+
object.placement = pose.placement ? structuredClone(pose.placement) : null;
|
|
1284
|
+
if (pose.inner) {
|
|
1285
|
+
object.properties.inner = { ...pose.inner };
|
|
1286
|
+
} else {
|
|
1287
|
+
delete object.properties.inner;
|
|
1288
|
+
}
|
|
1289
|
+
if (pose.outer) {
|
|
1290
|
+
object.properties.outer = { ...pose.outer };
|
|
1291
|
+
} else {
|
|
1292
|
+
delete object.properties.outer;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
return cloned;
|
|
1296
|
+
}
|
|
1262
1297
|
function resolveLayoutPreset(document2) {
|
|
1263
1298
|
const rawScale = String(document2.system?.properties.scale ?? "balanced").toLowerCase();
|
|
1264
1299
|
switch (rawScale) {
|
|
@@ -1414,24 +1449,14 @@ var WorldOrbit = (() => {
|
|
|
1414
1449
|
hidden: draft.object.properties.hidden === true
|
|
1415
1450
|
};
|
|
1416
1451
|
}
|
|
1417
|
-
function createSceneLabels(objects, sceneHeight, labelMultiplier) {
|
|
1452
|
+
function createSceneLabels(objects, sceneWidth, sceneHeight, labelMultiplier) {
|
|
1418
1453
|
const labels = [];
|
|
1419
1454
|
const occupied = [];
|
|
1420
|
-
const
|
|
1455
|
+
const objectMap = new Map(objects.map((object) => [object.objectId, object]));
|
|
1456
|
+
const visibleObjects = [...objects].filter((object) => !object.hidden && object.object.renderHints?.renderLabel !== false).sort(compareLabelPlacementOrder);
|
|
1421
1457
|
for (const object of visibleObjects) {
|
|
1422
|
-
const
|
|
1423
|
-
|
|
1424
|
-
let labelY = object.y + direction * (object.radius + 18 * labelMultiplier);
|
|
1425
|
-
let secondaryY = labelY + direction * (16 * labelMultiplier);
|
|
1426
|
-
let bounds = createLabelRect(object.x, labelY, secondaryY, labelHalfWidth, direction);
|
|
1427
|
-
let attempts = 0;
|
|
1428
|
-
while (occupied.some((entry) => rectsOverlap(entry, bounds)) && attempts < 10) {
|
|
1429
|
-
labelY += direction * 14 * labelMultiplier;
|
|
1430
|
-
secondaryY += direction * 14 * labelMultiplier;
|
|
1431
|
-
bounds = createLabelRect(object.x, labelY, secondaryY, labelHalfWidth, direction);
|
|
1432
|
-
attempts += 1;
|
|
1433
|
-
}
|
|
1434
|
-
occupied.push(bounds);
|
|
1458
|
+
const placement = selectLabelPlacement(object, objectMap, occupied, sceneWidth, sceneHeight, labelMultiplier) ?? createLabelPlacement(object, defaultVerticalDirection(object, objectMap.get(object.parentId ?? "") ?? null, sceneHeight), 0, labelMultiplier);
|
|
1459
|
+
occupied.push(createLabelRect(object, placement, labelMultiplier));
|
|
1435
1460
|
labels.push({
|
|
1436
1461
|
renderId: `${object.renderId}-label`,
|
|
1437
1462
|
objectId: object.objectId,
|
|
@@ -1440,17 +1465,128 @@ var WorldOrbit = (() => {
|
|
|
1440
1465
|
semanticGroupIds: [...object.semanticGroupIds],
|
|
1441
1466
|
label: object.label,
|
|
1442
1467
|
secondaryLabel: object.secondaryLabel,
|
|
1443
|
-
x:
|
|
1444
|
-
y: labelY,
|
|
1445
|
-
secondaryY,
|
|
1446
|
-
textAnchor:
|
|
1447
|
-
direction: direction
|
|
1468
|
+
x: placement.x,
|
|
1469
|
+
y: placement.labelY,
|
|
1470
|
+
secondaryY: placement.secondaryY,
|
|
1471
|
+
textAnchor: placement.textAnchor,
|
|
1472
|
+
direction: placement.direction,
|
|
1448
1473
|
hidden: object.hidden
|
|
1449
1474
|
});
|
|
1450
1475
|
}
|
|
1451
1476
|
return labels;
|
|
1452
1477
|
}
|
|
1453
|
-
function
|
|
1478
|
+
function compareLabelPlacementOrder(left, right) {
|
|
1479
|
+
const priorityDiff = labelPlacementPriority(left) - labelPlacementPriority(right);
|
|
1480
|
+
if (priorityDiff !== 0) {
|
|
1481
|
+
return priorityDiff;
|
|
1482
|
+
}
|
|
1483
|
+
const renderPriorityDiff = (right.object.renderHints?.renderPriority ?? 0) - (left.object.renderHints?.renderPriority ?? 0);
|
|
1484
|
+
if (renderPriorityDiff !== 0) {
|
|
1485
|
+
return renderPriorityDiff;
|
|
1486
|
+
}
|
|
1487
|
+
return left.sortKey - right.sortKey;
|
|
1488
|
+
}
|
|
1489
|
+
function labelPlacementPriority(object) {
|
|
1490
|
+
switch (object.object.type) {
|
|
1491
|
+
case "star":
|
|
1492
|
+
return 0;
|
|
1493
|
+
case "planet":
|
|
1494
|
+
return 1;
|
|
1495
|
+
case "moon":
|
|
1496
|
+
return 2;
|
|
1497
|
+
case "belt":
|
|
1498
|
+
case "ring":
|
|
1499
|
+
return 3;
|
|
1500
|
+
case "asteroid":
|
|
1501
|
+
case "comet":
|
|
1502
|
+
return 4;
|
|
1503
|
+
case "structure":
|
|
1504
|
+
case "phenomenon":
|
|
1505
|
+
return 5;
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
function selectLabelPlacement(object, objectMap, occupied, sceneWidth, sceneHeight, labelMultiplier) {
|
|
1509
|
+
for (const direction of preferredLabelDirections(object, objectMap, sceneWidth, sceneHeight)) {
|
|
1510
|
+
const maxAttempts = direction === "left" || direction === "right" ? 4 : 6;
|
|
1511
|
+
for (let attempt = 0; attempt <= maxAttempts; attempt += 1) {
|
|
1512
|
+
const placement = createLabelPlacement(object, direction, attempt, labelMultiplier);
|
|
1513
|
+
const rect = createLabelRect(object, placement, labelMultiplier);
|
|
1514
|
+
if (!occupied.some((entry) => rectsOverlap(entry, rect))) {
|
|
1515
|
+
return placement;
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
return null;
|
|
1520
|
+
}
|
|
1521
|
+
function preferredLabelDirections(object, objectMap, sceneWidth, sceneHeight) {
|
|
1522
|
+
const parent = object.parentId ? objectMap.get(object.parentId) ?? null : null;
|
|
1523
|
+
const vertical = defaultVerticalDirection(object, parent, sceneHeight);
|
|
1524
|
+
const oppositeVertical = vertical === "below" ? "above" : "below";
|
|
1525
|
+
const horizontal = defaultHorizontalDirection(object, parent, sceneWidth);
|
|
1526
|
+
const oppositeHorizontal = horizontal === "right" ? "left" : "right";
|
|
1527
|
+
const preferHorizontal = object.object.type === "structure" || object.object.type === "phenomenon" || object.object.placement?.mode === "at" || object.object.placement?.mode === "surface" || object.object.placement?.mode === "free";
|
|
1528
|
+
return preferHorizontal ? [horizontal, vertical, oppositeHorizontal, oppositeVertical] : [vertical, horizontal, oppositeVertical, oppositeHorizontal];
|
|
1529
|
+
}
|
|
1530
|
+
function defaultVerticalDirection(object, parent, sceneHeight) {
|
|
1531
|
+
if (parent && Math.abs(object.y - parent.y) > 6) {
|
|
1532
|
+
return object.y >= parent.y ? "below" : "above";
|
|
1533
|
+
}
|
|
1534
|
+
return object.y > sceneHeight * 0.62 ? "above" : "below";
|
|
1535
|
+
}
|
|
1536
|
+
function defaultHorizontalDirection(object, parent, sceneWidth) {
|
|
1537
|
+
if (parent && Math.abs(object.x - parent.x) > 6) {
|
|
1538
|
+
return object.x >= parent.x ? "right" : "left";
|
|
1539
|
+
}
|
|
1540
|
+
return object.x >= sceneWidth / 2 ? "right" : "left";
|
|
1541
|
+
}
|
|
1542
|
+
function createLabelPlacement(object, direction, attempt, labelMultiplier) {
|
|
1543
|
+
const step = 14 * labelMultiplier;
|
|
1544
|
+
switch (direction) {
|
|
1545
|
+
case "above": {
|
|
1546
|
+
const labelY = object.y - (object.radius + 18 * labelMultiplier + attempt * step);
|
|
1547
|
+
return {
|
|
1548
|
+
x: object.x,
|
|
1549
|
+
labelY,
|
|
1550
|
+
secondaryY: labelY - 16 * labelMultiplier,
|
|
1551
|
+
textAnchor: "middle",
|
|
1552
|
+
direction
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
case "below": {
|
|
1556
|
+
const labelY = object.y + object.radius + 18 * labelMultiplier + attempt * step;
|
|
1557
|
+
return {
|
|
1558
|
+
x: object.x,
|
|
1559
|
+
labelY,
|
|
1560
|
+
secondaryY: labelY + 16 * labelMultiplier,
|
|
1561
|
+
textAnchor: "middle",
|
|
1562
|
+
direction
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1565
|
+
case "left": {
|
|
1566
|
+
const x = object.x - (object.visualRadius + 16 * labelMultiplier + attempt * step);
|
|
1567
|
+
const labelY = object.y - 4 * labelMultiplier;
|
|
1568
|
+
return {
|
|
1569
|
+
x,
|
|
1570
|
+
labelY,
|
|
1571
|
+
secondaryY: labelY + 16 * labelMultiplier,
|
|
1572
|
+
textAnchor: "end",
|
|
1573
|
+
direction
|
|
1574
|
+
};
|
|
1575
|
+
}
|
|
1576
|
+
case "right": {
|
|
1577
|
+
const x = object.x + object.visualRadius + 16 * labelMultiplier + attempt * step;
|
|
1578
|
+
const labelY = object.y - 4 * labelMultiplier;
|
|
1579
|
+
return {
|
|
1580
|
+
x,
|
|
1581
|
+
labelY,
|
|
1582
|
+
secondaryY: labelY + 16 * labelMultiplier,
|
|
1583
|
+
textAnchor: "start",
|
|
1584
|
+
direction
|
|
1585
|
+
};
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
function createSceneLayers(orbitVisuals, relations, events, leaders, objects, labels) {
|
|
1454
1590
|
const backOrbitIds = orbitVisuals.filter((visual) => !visual.hidden && Boolean(visual.backArcPath)).map((visual) => visual.renderId);
|
|
1455
1591
|
const frontOrbitIds = orbitVisuals.filter((visual) => !visual.hidden).map((visual) => visual.renderId);
|
|
1456
1592
|
return [
|
|
@@ -1465,6 +1601,10 @@ var WorldOrbit = (() => {
|
|
|
1465
1601
|
id: "relations",
|
|
1466
1602
|
renderIds: relations.filter((relation) => !relation.hidden).map((relation) => relation.renderId)
|
|
1467
1603
|
},
|
|
1604
|
+
{
|
|
1605
|
+
id: "events",
|
|
1606
|
+
renderIds: events.filter((event) => !event.hidden).map((event) => event.renderId)
|
|
1607
|
+
},
|
|
1468
1608
|
{
|
|
1469
1609
|
id: "objects",
|
|
1470
1610
|
renderIds: objects.filter((object) => !object.hidden).map((object) => object.renderId)
|
|
@@ -1476,7 +1616,7 @@ var WorldOrbit = (() => {
|
|
|
1476
1616
|
{ id: "metadata", renderIds: ["wo-title", "wo-subtitle", "wo-meta"] }
|
|
1477
1617
|
];
|
|
1478
1618
|
}
|
|
1479
|
-
function createSceneGroups(objects, orbitVisuals, leaders, labels, relationships) {
|
|
1619
|
+
function createSceneGroups(objects, orbitVisuals, leaders, labels, relationships, labelMultiplier) {
|
|
1480
1620
|
const groups = /* @__PURE__ */ new Map();
|
|
1481
1621
|
const ensureGroup = (groupId) => {
|
|
1482
1622
|
if (!groupId) {
|
|
@@ -1525,7 +1665,7 @@ var WorldOrbit = (() => {
|
|
|
1525
1665
|
}
|
|
1526
1666
|
}
|
|
1527
1667
|
for (const group of groups.values()) {
|
|
1528
|
-
group.contentBounds = calculateGroupBounds(group, objects, orbitVisuals, leaders, labels);
|
|
1668
|
+
group.contentBounds = calculateGroupBounds(group, objects, orbitVisuals, leaders, labels, labelMultiplier);
|
|
1529
1669
|
}
|
|
1530
1670
|
return [...groups.values()].sort((left, right) => left.label.localeCompare(right.label));
|
|
1531
1671
|
}
|
|
@@ -1559,6 +1699,29 @@ var WorldOrbit = (() => {
|
|
|
1559
1699
|
};
|
|
1560
1700
|
}).sort((left, right) => left.relation.id.localeCompare(right.relation.id));
|
|
1561
1701
|
}
|
|
1702
|
+
function createSceneEvents(events, objects, activeEventId) {
|
|
1703
|
+
const objectMap = new Map(objects.map((object) => [object.objectId, object]));
|
|
1704
|
+
return events.map((event) => {
|
|
1705
|
+
const objectIds = [.../* @__PURE__ */ new Set([
|
|
1706
|
+
...event.targetObjectId ? [event.targetObjectId] : [],
|
|
1707
|
+
...event.participantObjectIds
|
|
1708
|
+
])];
|
|
1709
|
+
const positions = objectIds.map((objectId) => objectMap.get(objectId)).filter(Boolean);
|
|
1710
|
+
const centroidX = positions.length > 0 ? positions.reduce((sum, object) => sum + object.x, 0) / positions.length : 0;
|
|
1711
|
+
const centroidY = positions.length > 0 ? positions.reduce((sum, object) => sum + object.y, 0) / positions.length : 0;
|
|
1712
|
+
return {
|
|
1713
|
+
renderId: `${createRenderId(event.id)}-event`,
|
|
1714
|
+
eventId: event.id,
|
|
1715
|
+
event,
|
|
1716
|
+
objectIds,
|
|
1717
|
+
participantIds: [...event.participantObjectIds],
|
|
1718
|
+
targetObjectId: event.targetObjectId,
|
|
1719
|
+
x: centroidX,
|
|
1720
|
+
y: centroidY,
|
|
1721
|
+
hidden: event.hidden || positions.length === 0 || positions.every((object) => object.hidden) || activeEventId !== null && event.id !== activeEventId
|
|
1722
|
+
};
|
|
1723
|
+
}).sort((left, right) => left.event.id.localeCompare(right.event.id));
|
|
1724
|
+
}
|
|
1562
1725
|
function createSceneViewpoints(document2, projection, preset, relationships, objectMap) {
|
|
1563
1726
|
const generatedOverview = createGeneratedOverviewViewpoint(document2, projection, preset);
|
|
1564
1727
|
const drafts = /* @__PURE__ */ new Map();
|
|
@@ -1612,6 +1775,7 @@ var WorldOrbit = (() => {
|
|
|
1612
1775
|
summary: "Fit the whole system with the current atlas defaults.",
|
|
1613
1776
|
objectId: null,
|
|
1614
1777
|
selectedObjectId: null,
|
|
1778
|
+
eventIds: [],
|
|
1615
1779
|
projection,
|
|
1616
1780
|
preset,
|
|
1617
1781
|
rotationDeg: 0,
|
|
@@ -1648,6 +1812,9 @@ var WorldOrbit = (() => {
|
|
|
1648
1812
|
draft.select = normalizedValue;
|
|
1649
1813
|
}
|
|
1650
1814
|
return;
|
|
1815
|
+
case "events":
|
|
1816
|
+
draft.eventIds = splitListValue(normalizedValue);
|
|
1817
|
+
return;
|
|
1651
1818
|
case "projection":
|
|
1652
1819
|
case "view":
|
|
1653
1820
|
draft.projection = parseViewProjection(normalizedValue) ?? projection;
|
|
@@ -1704,6 +1871,7 @@ var WorldOrbit = (() => {
|
|
|
1704
1871
|
summary: draft.summary?.trim() || createViewpointSummary(label, objectId, filter),
|
|
1705
1872
|
objectId,
|
|
1706
1873
|
selectedObjectId,
|
|
1874
|
+
eventIds: [...new Set(draft.eventIds ?? [])],
|
|
1707
1875
|
projection: draft.projection ?? projection,
|
|
1708
1876
|
preset: draft.preset ?? preset,
|
|
1709
1877
|
rotationDeg: draft.rotationDeg ?? 0,
|
|
@@ -1761,7 +1929,7 @@ var WorldOrbit = (() => {
|
|
|
1761
1929
|
next["orbits-front"] = enabled;
|
|
1762
1930
|
continue;
|
|
1763
1931
|
}
|
|
1764
|
-
if (rawLayer === "background" || rawLayer === "guides" || rawLayer === "orbits-back" || rawLayer === "orbits-front" || rawLayer === "relations" || rawLayer === "objects" || rawLayer === "labels" || rawLayer === "metadata") {
|
|
1932
|
+
if (rawLayer === "background" || rawLayer === "guides" || rawLayer === "orbits-back" || rawLayer === "orbits-front" || rawLayer === "relations" || rawLayer === "events" || rawLayer === "objects" || rawLayer === "labels" || rawLayer === "metadata") {
|
|
1765
1933
|
next[rawLayer] = enabled;
|
|
1766
1934
|
}
|
|
1767
1935
|
}
|
|
@@ -1809,7 +1977,7 @@ var WorldOrbit = (() => {
|
|
|
1809
1977
|
}
|
|
1810
1978
|
return parts.join(" - ");
|
|
1811
1979
|
}
|
|
1812
|
-
function calculateContentBounds(width, height, objects, orbitVisuals, leaders, labels) {
|
|
1980
|
+
function calculateContentBounds(width, height, objects, orbitVisuals, leaders, labels, labelMultiplier) {
|
|
1813
1981
|
let minX = Number.POSITIVE_INFINITY;
|
|
1814
1982
|
let minY = Number.POSITIVE_INFINITY;
|
|
1815
1983
|
let maxX = Number.NEGATIVE_INFINITY;
|
|
@@ -1839,7 +2007,7 @@ var WorldOrbit = (() => {
|
|
|
1839
2007
|
for (const label of labels) {
|
|
1840
2008
|
if (label.hidden)
|
|
1841
2009
|
continue;
|
|
1842
|
-
includeLabelBounds(label, include);
|
|
2010
|
+
includeLabelBounds(label, include, labelMultiplier);
|
|
1843
2011
|
}
|
|
1844
2012
|
if (!Number.isFinite(minX) || !Number.isFinite(minY)) {
|
|
1845
2013
|
return createBounds(0, 0, width, height);
|
|
@@ -1877,13 +2045,10 @@ var WorldOrbit = (() => {
|
|
|
1877
2045
|
include(object.x - object.visualRadius - 24, object.y - object.visualRadius - 16);
|
|
1878
2046
|
include(object.x + object.visualRadius + 24, object.y + object.visualRadius + 36);
|
|
1879
2047
|
}
|
|
1880
|
-
function includeLabelBounds(label, include) {
|
|
1881
|
-
const
|
|
1882
|
-
|
|
1883
|
-
include(
|
|
1884
|
-
include(label.x + labelHalfWidth, label.y + 8);
|
|
1885
|
-
include(label.x - labelHalfWidth, label.secondaryY - 14);
|
|
1886
|
-
include(label.x + labelHalfWidth, label.secondaryY + 8);
|
|
2048
|
+
function includeLabelBounds(label, include, labelMultiplier) {
|
|
2049
|
+
const bounds = createLabelRectFromText(label.x, label.y, label.secondaryY, label.textAnchor, label.direction, label.label, label.secondaryLabel, labelMultiplier);
|
|
2050
|
+
include(bounds.left, bounds.top);
|
|
2051
|
+
include(bounds.right, bounds.bottom);
|
|
1887
2052
|
}
|
|
1888
2053
|
function placeObject(object, x, y, depth, positions, orbitDrafts, leaderDrafts, context) {
|
|
1889
2054
|
if (positions.has(object.id)) {
|
|
@@ -2273,7 +2438,7 @@ var WorldOrbit = (() => {
|
|
|
2273
2438
|
return null;
|
|
2274
2439
|
}
|
|
2275
2440
|
}
|
|
2276
|
-
function calculateGroupBounds(group, objects, orbitVisuals, leaders, labels) {
|
|
2441
|
+
function calculateGroupBounds(group, objects, orbitVisuals, leaders, labels, labelMultiplier) {
|
|
2277
2442
|
let minX = Number.POSITIVE_INFINITY;
|
|
2278
2443
|
let minY = Number.POSITIVE_INFINITY;
|
|
2279
2444
|
let maxX = Number.NEGATIVE_INFINITY;
|
|
@@ -2302,7 +2467,7 @@ var WorldOrbit = (() => {
|
|
|
2302
2467
|
}
|
|
2303
2468
|
for (const label of labels) {
|
|
2304
2469
|
if (!label.hidden && group.labelIds.includes(label.objectId)) {
|
|
2305
|
-
includeLabelBounds(label, include);
|
|
2470
|
+
includeLabelBounds(label, include, labelMultiplier);
|
|
2306
2471
|
}
|
|
2307
2472
|
}
|
|
2308
2473
|
if (!Number.isFinite(minX) || !Number.isFinite(minY)) {
|
|
@@ -2327,12 +2492,28 @@ var WorldOrbit = (() => {
|
|
|
2327
2492
|
}
|
|
2328
2493
|
return current.id;
|
|
2329
2494
|
}
|
|
2330
|
-
function createLabelRect(
|
|
2495
|
+
function createLabelRect(object, placement, labelMultiplier) {
|
|
2496
|
+
return createLabelRectFromText(placement.x, placement.labelY, placement.secondaryY, placement.textAnchor, placement.direction, object.label, object.secondaryLabel, labelMultiplier);
|
|
2497
|
+
}
|
|
2498
|
+
function createLabelRectFromText(x, labelY, secondaryY, textAnchor, direction, label, secondaryLabel, labelMultiplier) {
|
|
2499
|
+
const labelHalfWidth = estimateLabelHalfWidthFromText(label, secondaryLabel, labelMultiplier);
|
|
2500
|
+
const labelWidth = labelHalfWidth * 2;
|
|
2501
|
+
const topPadding = direction === "above" ? 18 : 12;
|
|
2502
|
+
const bottomPadding = direction === "above" ? 8 : 12;
|
|
2503
|
+
let left = x - labelHalfWidth;
|
|
2504
|
+
let right = x + labelHalfWidth;
|
|
2505
|
+
if (textAnchor === "start") {
|
|
2506
|
+
left = x;
|
|
2507
|
+
right = x + labelWidth;
|
|
2508
|
+
} else if (textAnchor === "end") {
|
|
2509
|
+
left = x - labelWidth;
|
|
2510
|
+
right = x;
|
|
2511
|
+
}
|
|
2331
2512
|
return {
|
|
2332
|
-
left
|
|
2333
|
-
right
|
|
2334
|
-
top: Math.min(labelY, secondaryY) -
|
|
2335
|
-
bottom: Math.max(labelY, secondaryY) +
|
|
2513
|
+
left,
|
|
2514
|
+
right,
|
|
2515
|
+
top: Math.min(labelY, secondaryY) - topPadding,
|
|
2516
|
+
bottom: Math.max(labelY, secondaryY) + bottomPadding
|
|
2336
2517
|
};
|
|
2337
2518
|
}
|
|
2338
2519
|
function rectsOverlap(left, right) {
|
|
@@ -2519,11 +2700,6 @@ var WorldOrbit = (() => {
|
|
|
2519
2700
|
function customColorFor(value) {
|
|
2520
2701
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
2521
2702
|
}
|
|
2522
|
-
function estimateLabelHalfWidth(object, labelMultiplier) {
|
|
2523
|
-
const primaryWidth = object.label.length * 4.6 * labelMultiplier + 18;
|
|
2524
|
-
const secondaryWidth = object.secondaryLabel.length * 3.9 * labelMultiplier + 18;
|
|
2525
|
-
return Math.max(primaryWidth, secondaryWidth, object.visualRadius + 18);
|
|
2526
|
-
}
|
|
2527
2703
|
function estimateLabelHalfWidthFromText(label, secondaryLabel, labelMultiplier) {
|
|
2528
2704
|
const primaryWidth = label.length * 4.6 * labelMultiplier + 18;
|
|
2529
2705
|
const secondaryWidth = secondaryLabel.length * 3.9 * labelMultiplier + 18;
|
|
@@ -2563,6 +2739,7 @@ var WorldOrbit = (() => {
|
|
|
2563
2739
|
system,
|
|
2564
2740
|
groups: structuredClone(document2.groups ?? []),
|
|
2565
2741
|
relations: structuredClone(document2.relations ?? []),
|
|
2742
|
+
events: structuredClone(document2.events ?? []),
|
|
2566
2743
|
objects: document2.objects.map(cloneWorldOrbitObject),
|
|
2567
2744
|
diagnostics
|
|
2568
2745
|
};
|
|
@@ -2570,7 +2747,7 @@ var WorldOrbit = (() => {
|
|
|
2570
2747
|
function upgradeDocumentToDraftV2(document2, options = {}) {
|
|
2571
2748
|
return convertAtlasDocumentToLegacyDraft(upgradeDocumentToV2(document2, options));
|
|
2572
2749
|
}
|
|
2573
|
-
function materializeAtlasDocument(document2) {
|
|
2750
|
+
function materializeAtlasDocument(document2, options = {}) {
|
|
2574
2751
|
const system = document2.system ? {
|
|
2575
2752
|
type: "system",
|
|
2576
2753
|
id: document2.system.id,
|
|
@@ -2581,6 +2758,8 @@ var WorldOrbit = (() => {
|
|
|
2581
2758
|
properties: materializeDraftSystemProperties(document2.system),
|
|
2582
2759
|
info: materializeDraftSystemInfo(document2.system)
|
|
2583
2760
|
} : null;
|
|
2761
|
+
const objects = document2.objects.map(cloneWorldOrbitObject);
|
|
2762
|
+
applyEventPoseOverrides(objects, document2.events ?? [], options.activeEventId ?? null);
|
|
2584
2763
|
return {
|
|
2585
2764
|
format: "worldorbit",
|
|
2586
2765
|
version: "1.0",
|
|
@@ -2588,7 +2767,8 @@ var WorldOrbit = (() => {
|
|
|
2588
2767
|
system,
|
|
2589
2768
|
groups: structuredClone(document2.groups ?? []),
|
|
2590
2769
|
relations: structuredClone(document2.relations ?? []),
|
|
2591
|
-
|
|
2770
|
+
events: document2.events.map(cloneWorldOrbitEvent),
|
|
2771
|
+
objects
|
|
2592
2772
|
};
|
|
2593
2773
|
}
|
|
2594
2774
|
function materializeDraftDocument(document2) {
|
|
@@ -2716,6 +2896,7 @@ var WorldOrbit = (() => {
|
|
|
2716
2896
|
summary: viewpoint.summary,
|
|
2717
2897
|
focusObjectId: viewpoint.objectId,
|
|
2718
2898
|
selectedObjectId: viewpoint.selectedObjectId,
|
|
2899
|
+
events: [...viewpoint.eventIds],
|
|
2719
2900
|
projection: viewpoint.projection,
|
|
2720
2901
|
preset: viewpoint.preset,
|
|
2721
2902
|
zoom: viewpoint.scale,
|
|
@@ -2748,6 +2929,52 @@ var WorldOrbit = (() => {
|
|
|
2748
2929
|
info: { ...object.info }
|
|
2749
2930
|
};
|
|
2750
2931
|
}
|
|
2932
|
+
function cloneWorldOrbitEvent(event) {
|
|
2933
|
+
return {
|
|
2934
|
+
...event,
|
|
2935
|
+
participantObjectIds: [...event.participantObjectIds],
|
|
2936
|
+
tags: [...event.tags],
|
|
2937
|
+
positions: event.positions.map(cloneWorldOrbitEventPose)
|
|
2938
|
+
};
|
|
2939
|
+
}
|
|
2940
|
+
function cloneWorldOrbitEventPose(pose) {
|
|
2941
|
+
return {
|
|
2942
|
+
objectId: pose.objectId,
|
|
2943
|
+
placement: clonePlacement(pose.placement),
|
|
2944
|
+
inner: pose.inner ? { ...pose.inner } : void 0,
|
|
2945
|
+
outer: pose.outer ? { ...pose.outer } : void 0
|
|
2946
|
+
};
|
|
2947
|
+
}
|
|
2948
|
+
function clonePlacement(placement) {
|
|
2949
|
+
return placement ? structuredClone(placement) : null;
|
|
2950
|
+
}
|
|
2951
|
+
function applyEventPoseOverrides(objects, events, activeEventId) {
|
|
2952
|
+
if (!activeEventId) {
|
|
2953
|
+
return;
|
|
2954
|
+
}
|
|
2955
|
+
const event = events.find((entry) => entry.id === activeEventId);
|
|
2956
|
+
if (!event) {
|
|
2957
|
+
return;
|
|
2958
|
+
}
|
|
2959
|
+
const objectMap = new Map(objects.map((object) => [object.id, object]));
|
|
2960
|
+
for (const pose of event.positions) {
|
|
2961
|
+
const object = objectMap.get(pose.objectId);
|
|
2962
|
+
if (!object) {
|
|
2963
|
+
continue;
|
|
2964
|
+
}
|
|
2965
|
+
object.placement = clonePlacement(pose.placement);
|
|
2966
|
+
if (pose.inner) {
|
|
2967
|
+
object.properties.inner = { ...pose.inner };
|
|
2968
|
+
} else {
|
|
2969
|
+
delete object.properties.inner;
|
|
2970
|
+
}
|
|
2971
|
+
if (pose.outer) {
|
|
2972
|
+
object.properties.outer = { ...pose.outer };
|
|
2973
|
+
} else {
|
|
2974
|
+
delete object.properties.outer;
|
|
2975
|
+
}
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2751
2978
|
function cloneProperties(properties) {
|
|
2752
2979
|
const next = {};
|
|
2753
2980
|
for (const [key, value] of Object.entries(properties)) {
|
|
@@ -2845,6 +3072,9 @@ var WorldOrbit = (() => {
|
|
|
2845
3072
|
if ((viewpoint.filter?.groupIds.length ?? 0) > 0) {
|
|
2846
3073
|
info2[`${prefix}.groups`] = viewpoint.filter?.groupIds.join(" ") ?? "";
|
|
2847
3074
|
}
|
|
3075
|
+
if (viewpoint.events.length > 0) {
|
|
3076
|
+
info2[`${prefix}.events`] = viewpoint.events.join(" ");
|
|
3077
|
+
}
|
|
2848
3078
|
}
|
|
2849
3079
|
for (const annotation of system.annotations) {
|
|
2850
3080
|
const prefix = `annotation.${annotation.id}`;
|
|
@@ -2869,7 +3099,7 @@ var WorldOrbit = (() => {
|
|
|
2869
3099
|
if (orbitFront !== void 0 || orbitBack !== void 0) {
|
|
2870
3100
|
tokens.push(orbitFront !== false || orbitBack !== false ? "orbits" : "-orbits");
|
|
2871
3101
|
}
|
|
2872
|
-
for (const key of ["background", "guides", "relations", "objects", "labels", "metadata"]) {
|
|
3102
|
+
for (const key of ["background", "guides", "relations", "events", "objects", "labels", "metadata"]) {
|
|
2873
3103
|
if (layers[key] !== void 0) {
|
|
2874
3104
|
tokens.push(layers[key] ? key : `-${key}`);
|
|
2875
3105
|
}
|
|
@@ -2973,6 +3203,10 @@ var WorldOrbit = (() => {
|
|
|
2973
3203
|
lines.push("");
|
|
2974
3204
|
lines.push(...formatAtlasRelation(relation));
|
|
2975
3205
|
}
|
|
3206
|
+
for (const event of [...document2.events].sort(compareIdLike)) {
|
|
3207
|
+
lines.push("");
|
|
3208
|
+
lines.push(...formatAtlasEvent(event));
|
|
3209
|
+
}
|
|
2976
3210
|
const sortedObjects = [...document2.objects].sort(compareObjects);
|
|
2977
3211
|
if (sortedObjects.length > 0 && lines.at(-1) !== "") {
|
|
2978
3212
|
lines.push("");
|
|
@@ -3003,6 +3237,10 @@ var WorldOrbit = (() => {
|
|
|
3003
3237
|
lines.push("");
|
|
3004
3238
|
lines.push(...formatAtlasRelation(relation));
|
|
3005
3239
|
}
|
|
3240
|
+
for (const event of [...legacy.events].sort(compareIdLike)) {
|
|
3241
|
+
lines.push("");
|
|
3242
|
+
lines.push(...formatAtlasEvent(event));
|
|
3243
|
+
}
|
|
3006
3244
|
const sortedObjects = [...legacy.objects].sort(compareObjects);
|
|
3007
3245
|
if (sortedObjects.length > 0 && lines.at(-1) !== "") {
|
|
3008
3246
|
lines.push("");
|
|
@@ -3214,6 +3452,9 @@ var WorldOrbit = (() => {
|
|
|
3214
3452
|
if (layerTokens.length > 0) {
|
|
3215
3453
|
lines.push(` layers ${layerTokens.join(" ")}`);
|
|
3216
3454
|
}
|
|
3455
|
+
if (viewpoint.events.length > 0) {
|
|
3456
|
+
lines.push(` events ${viewpoint.events.join(" ")}`);
|
|
3457
|
+
}
|
|
3217
3458
|
if (viewpoint.filter) {
|
|
3218
3459
|
lines.push(" filter");
|
|
3219
3460
|
if (viewpoint.filter.query) {
|
|
@@ -3286,6 +3527,54 @@ var WorldOrbit = (() => {
|
|
|
3286
3527
|
}
|
|
3287
3528
|
return lines;
|
|
3288
3529
|
}
|
|
3530
|
+
function formatAtlasEvent(event) {
|
|
3531
|
+
const lines = [`event ${event.id}`, ` kind ${quoteIfNeeded(event.kind)}`];
|
|
3532
|
+
if (event.label) {
|
|
3533
|
+
lines.push(` label ${quoteIfNeeded(event.label)}`);
|
|
3534
|
+
}
|
|
3535
|
+
if (event.summary) {
|
|
3536
|
+
lines.push(` summary ${quoteIfNeeded(event.summary)}`);
|
|
3537
|
+
}
|
|
3538
|
+
if (event.targetObjectId) {
|
|
3539
|
+
lines.push(` target ${event.targetObjectId}`);
|
|
3540
|
+
}
|
|
3541
|
+
if (event.participantObjectIds.length > 0) {
|
|
3542
|
+
lines.push(` participants ${event.participantObjectIds.join(" ")}`);
|
|
3543
|
+
}
|
|
3544
|
+
if (event.timing) {
|
|
3545
|
+
lines.push(` timing ${quoteIfNeeded(event.timing)}`);
|
|
3546
|
+
}
|
|
3547
|
+
if (event.visibility) {
|
|
3548
|
+
lines.push(` visibility ${quoteIfNeeded(event.visibility)}`);
|
|
3549
|
+
}
|
|
3550
|
+
if (event.tags.length > 0) {
|
|
3551
|
+
lines.push(` tags ${event.tags.map(quoteIfNeeded).join(" ")}`);
|
|
3552
|
+
}
|
|
3553
|
+
if (event.color) {
|
|
3554
|
+
lines.push(` color ${quoteIfNeeded(event.color)}`);
|
|
3555
|
+
}
|
|
3556
|
+
if (event.hidden) {
|
|
3557
|
+
lines.push(" hidden true");
|
|
3558
|
+
}
|
|
3559
|
+
if (event.positions.length > 0) {
|
|
3560
|
+
lines.push("");
|
|
3561
|
+
lines.push(" positions");
|
|
3562
|
+
for (const pose of [...event.positions].sort(comparePoseObjectId)) {
|
|
3563
|
+
lines.push(` pose ${pose.objectId}`);
|
|
3564
|
+
for (const fieldLine of formatEventPoseFields(pose)) {
|
|
3565
|
+
lines.push(` ${fieldLine}`);
|
|
3566
|
+
}
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
return lines;
|
|
3570
|
+
}
|
|
3571
|
+
function formatEventPoseFields(pose) {
|
|
3572
|
+
return [
|
|
3573
|
+
...formatPlacement(pose.placement),
|
|
3574
|
+
...formatOptionalUnit("inner", pose.inner),
|
|
3575
|
+
...formatOptionalUnit("outer", pose.outer)
|
|
3576
|
+
];
|
|
3577
|
+
}
|
|
3289
3578
|
function formatValue(value) {
|
|
3290
3579
|
if (Array.isArray(value)) {
|
|
3291
3580
|
return value.map((item) => quoteIfNeeded(item)).join(" ");
|
|
@@ -3327,7 +3616,7 @@ var WorldOrbit = (() => {
|
|
|
3327
3616
|
if (orbitFront !== void 0 || orbitBack !== void 0) {
|
|
3328
3617
|
tokens.push(orbitFront !== false || orbitBack !== false ? "orbits" : "-orbits");
|
|
3329
3618
|
}
|
|
3330
|
-
for (const key of ["background", "guides", "relations", "objects", "labels", "metadata"]) {
|
|
3619
|
+
for (const key of ["background", "guides", "relations", "events", "objects", "labels", "metadata"]) {
|
|
3331
3620
|
if (layers[key] !== void 0) {
|
|
3332
3621
|
tokens.push(layers[key] ? key : `-${key}`);
|
|
3333
3622
|
}
|
|
@@ -3355,6 +3644,9 @@ var WorldOrbit = (() => {
|
|
|
3355
3644
|
function compareIdLike(left, right) {
|
|
3356
3645
|
return left.id.localeCompare(right.id);
|
|
3357
3646
|
}
|
|
3647
|
+
function comparePoseObjectId(left, right) {
|
|
3648
|
+
return left.objectId.localeCompare(right.objectId);
|
|
3649
|
+
}
|
|
3358
3650
|
function objectTypeIndex(objectType) {
|
|
3359
3651
|
switch (objectType) {
|
|
3360
3652
|
case "star":
|
|
@@ -3550,6 +3842,7 @@ var WorldOrbit = (() => {
|
|
|
3550
3842
|
const diagnostics = [];
|
|
3551
3843
|
const objectMap = new Map(document2.objects.map((object) => [object.id, object]));
|
|
3552
3844
|
const groupIds = new Set(document2.groups.map((group) => group.id));
|
|
3845
|
+
const eventIds = new Set(document2.events.map((event) => event.id));
|
|
3553
3846
|
if (!document2.system) {
|
|
3554
3847
|
diagnostics.push(error("validate.system.required", "Atlas documents must declare exactly one system."));
|
|
3555
3848
|
}
|
|
@@ -3559,6 +3852,7 @@ var WorldOrbit = (() => {
|
|
|
3559
3852
|
["viewpoint", document2.system?.viewpoints.map((viewpoint) => viewpoint.id) ?? []],
|
|
3560
3853
|
["annotation", document2.system?.annotations.map((annotation) => annotation.id) ?? []],
|
|
3561
3854
|
["relation", document2.relations.map((relation) => relation.id)],
|
|
3855
|
+
["event", document2.events.map((event) => event.id)],
|
|
3562
3856
|
["object", document2.objects.map((object) => object.id)]
|
|
3563
3857
|
]) {
|
|
3564
3858
|
for (const id of ids) {
|
|
@@ -3574,11 +3868,14 @@ var WorldOrbit = (() => {
|
|
|
3574
3868
|
validateRelation(relation, objectMap, diagnostics);
|
|
3575
3869
|
}
|
|
3576
3870
|
for (const viewpoint of document2.system?.viewpoints ?? []) {
|
|
3577
|
-
|
|
3871
|
+
validateViewpoint(viewpoint.filter, viewpoint.events ?? [], groupIds, eventIds, sourceSchemaVersion, diagnostics, viewpoint.id);
|
|
3578
3872
|
}
|
|
3579
3873
|
for (const object of document2.objects) {
|
|
3580
3874
|
validateObject(object, document2.system, objectMap, groupIds, diagnostics);
|
|
3581
3875
|
}
|
|
3876
|
+
for (const event of document2.events) {
|
|
3877
|
+
validateEvent(event, objectMap, diagnostics);
|
|
3878
|
+
}
|
|
3582
3879
|
return diagnostics;
|
|
3583
3880
|
}
|
|
3584
3881
|
function validateRelation(relation, objectMap, diagnostics) {
|
|
@@ -3596,13 +3893,19 @@ var WorldOrbit = (() => {
|
|
|
3596
3893
|
diagnostics.push(error("validate.relation.kind.required", `Relation "${relation.id}" is missing a "kind" value.`));
|
|
3597
3894
|
}
|
|
3598
3895
|
}
|
|
3599
|
-
function
|
|
3600
|
-
if (
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3896
|
+
function validateViewpoint(filter, eventRefs, groupIds, eventIds, sourceSchemaVersion, diagnostics, viewpointId) {
|
|
3897
|
+
if (sourceSchemaVersion === "2.1") {
|
|
3898
|
+
if (filter) {
|
|
3899
|
+
for (const groupId of filter.groupIds) {
|
|
3900
|
+
if (!groupIds.has(groupId)) {
|
|
3901
|
+
diagnostics.push(warn("validate.viewpoint.group.unknown", `Unknown group "${groupId}" in viewpoint "${viewpointId}".`, void 0, `viewpoint.${viewpointId}.groups`));
|
|
3902
|
+
}
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
for (const eventId of eventRefs) {
|
|
3906
|
+
if (!eventIds.has(eventId)) {
|
|
3907
|
+
diagnostics.push(warn("validate.viewpoint.event.unknown", `Unknown event "${eventId}" in viewpoint "${viewpointId}".`, void 0, `viewpoint.${viewpointId}.events`));
|
|
3908
|
+
}
|
|
3606
3909
|
}
|
|
3607
3910
|
}
|
|
3608
3911
|
}
|
|
@@ -3688,6 +3991,103 @@ var WorldOrbit = (() => {
|
|
|
3688
3991
|
}
|
|
3689
3992
|
}
|
|
3690
3993
|
}
|
|
3994
|
+
function validateEvent(event, objectMap, diagnostics) {
|
|
3995
|
+
const fieldPrefix = `event.${event.id}`;
|
|
3996
|
+
const referencedIds = /* @__PURE__ */ new Set();
|
|
3997
|
+
if (!event.kind.trim()) {
|
|
3998
|
+
diagnostics.push(error("validate.event.kind.required", `Event "${event.id}" is missing a "kind" value.`, void 0, `${fieldPrefix}.kind`));
|
|
3999
|
+
}
|
|
4000
|
+
if (!event.targetObjectId && event.participantObjectIds.length === 0) {
|
|
4001
|
+
diagnostics.push(error("validate.event.references.required", `Event "${event.id}" must define a "target" or at least one participant.`, void 0, `${fieldPrefix}.participants`));
|
|
4002
|
+
}
|
|
4003
|
+
if (event.targetObjectId) {
|
|
4004
|
+
referencedIds.add(event.targetObjectId);
|
|
4005
|
+
if (!objectMap.has(event.targetObjectId)) {
|
|
4006
|
+
diagnostics.push(error("validate.event.target.unknown", `Unknown event target "${event.targetObjectId}" on "${event.id}".`, void 0, `${fieldPrefix}.target`));
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
const seenParticipants = /* @__PURE__ */ new Set();
|
|
4010
|
+
for (const participantId of event.participantObjectIds) {
|
|
4011
|
+
referencedIds.add(participantId);
|
|
4012
|
+
if (seenParticipants.has(participantId)) {
|
|
4013
|
+
diagnostics.push(warn("validate.event.participants.duplicate", `Event "${event.id}" repeats participant "${participantId}".`, void 0, `${fieldPrefix}.participants`));
|
|
4014
|
+
continue;
|
|
4015
|
+
}
|
|
4016
|
+
seenParticipants.add(participantId);
|
|
4017
|
+
if (!objectMap.has(participantId)) {
|
|
4018
|
+
diagnostics.push(error("validate.event.participants.unknown", `Unknown event participant "${participantId}" on "${event.id}".`, void 0, `${fieldPrefix}.participants`));
|
|
4019
|
+
}
|
|
4020
|
+
}
|
|
4021
|
+
if (event.targetObjectId && event.participantObjectIds.length > 0 && !event.participantObjectIds.includes(event.targetObjectId)) {
|
|
4022
|
+
diagnostics.push(warn("validate.event.target.notParticipant", `Event "${event.id}" defines a target outside its participants list.`, void 0, `${fieldPrefix}.target`));
|
|
4023
|
+
}
|
|
4024
|
+
if (event.positions.length === 0) {
|
|
4025
|
+
diagnostics.push(warn("validate.event.positions.missing", `Event "${event.id}" has no positions block and cannot drive a scene snapshot.`, void 0, `${fieldPrefix}.positions`));
|
|
4026
|
+
}
|
|
4027
|
+
if (/(?:^|[-_])(solar-eclipse|lunar-eclipse|transit|occultation)(?:$|[-_])/.test(event.kind) && referencedIds.size < 3) {
|
|
4028
|
+
diagnostics.push(warn("validate.event.kind.participants", `Event "${event.id}" looks like an eclipse or transit but references fewer than three bodies.`, void 0, `${fieldPrefix}.participants`));
|
|
4029
|
+
}
|
|
4030
|
+
const poseIds = /* @__PURE__ */ new Set();
|
|
4031
|
+
for (const pose of event.positions) {
|
|
4032
|
+
const poseFieldPrefix = `${fieldPrefix}.pose.${pose.objectId}`;
|
|
4033
|
+
if (poseIds.has(pose.objectId)) {
|
|
4034
|
+
diagnostics.push(error("validate.event.pose.duplicate", `Event "${event.id}" defines "${pose.objectId}" more than once in positions.`, void 0, poseFieldPrefix));
|
|
4035
|
+
continue;
|
|
4036
|
+
}
|
|
4037
|
+
poseIds.add(pose.objectId);
|
|
4038
|
+
const object = objectMap.get(pose.objectId);
|
|
4039
|
+
if (!object) {
|
|
4040
|
+
diagnostics.push(error("validate.event.pose.object.unknown", `Unknown event pose object "${pose.objectId}" on "${event.id}".`, void 0, poseFieldPrefix));
|
|
4041
|
+
continue;
|
|
4042
|
+
}
|
|
4043
|
+
if (!referencedIds.has(pose.objectId)) {
|
|
4044
|
+
diagnostics.push(warn("validate.event.pose.unreferenced", `Event pose "${pose.objectId}" on "${event.id}" is not listed in target/participants.`, void 0, poseFieldPrefix));
|
|
4045
|
+
}
|
|
4046
|
+
validateEventPose(pose, object, objectMap, diagnostics, poseFieldPrefix, event.id);
|
|
4047
|
+
}
|
|
4048
|
+
}
|
|
4049
|
+
function validateEventPose(pose, object, objectMap, diagnostics, fieldPrefix, eventId) {
|
|
4050
|
+
const placement = pose.placement;
|
|
4051
|
+
if (!placement) {
|
|
4052
|
+
diagnostics.push(error("validate.event.pose.placement.required", `Event "${eventId}" pose "${pose.objectId}" is missing a placement mode.`, void 0, fieldPrefix));
|
|
4053
|
+
return;
|
|
4054
|
+
}
|
|
4055
|
+
if (placement.mode === "orbit") {
|
|
4056
|
+
if (!objectMap.has(placement.target)) {
|
|
4057
|
+
diagnostics.push(error("validate.event.pose.orbit.target.unknown", `Unknown event orbit target "${placement.target}" on "${eventId}:${pose.objectId}".`, void 0, `${fieldPrefix}.orbit`));
|
|
4058
|
+
}
|
|
4059
|
+
if (placement.distance && placement.semiMajor) {
|
|
4060
|
+
diagnostics.push(error("validate.event.pose.orbit.distanceConflict", `Event "${eventId}" pose "${pose.objectId}" cannot declare both "distance" and "semiMajor".`, void 0, `${fieldPrefix}.distance`));
|
|
4061
|
+
}
|
|
4062
|
+
return;
|
|
4063
|
+
}
|
|
4064
|
+
if (placement.mode === "surface") {
|
|
4065
|
+
const target = objectMap.get(placement.target);
|
|
4066
|
+
if (!target) {
|
|
4067
|
+
diagnostics.push(error("validate.event.pose.surface.target.unknown", `Unknown event surface target "${placement.target}" on "${eventId}:${pose.objectId}".`, void 0, `${fieldPrefix}.surface`));
|
|
4068
|
+
} else if (!SURFACE_TARGET_TYPES2.has(target.type)) {
|
|
4069
|
+
diagnostics.push(error("validate.event.pose.surface.target.invalid", `Event surface target "${placement.target}" on "${eventId}:${pose.objectId}" is not surface-capable.`, void 0, `${fieldPrefix}.surface`));
|
|
4070
|
+
}
|
|
4071
|
+
return;
|
|
4072
|
+
}
|
|
4073
|
+
if (placement.mode === "at") {
|
|
4074
|
+
if (object.type !== "structure" && object.type !== "phenomenon") {
|
|
4075
|
+
diagnostics.push(error("validate.event.pose.at.objectType", `Only structures and phenomena may use "at" placement in events; found "${object.type}" on "${eventId}:${pose.objectId}".`, void 0, `${fieldPrefix}.at`));
|
|
4076
|
+
}
|
|
4077
|
+
const reference = placement.reference;
|
|
4078
|
+
if (reference.kind === "named" && !objectMap.has(reference.name)) {
|
|
4079
|
+
diagnostics.push(error("validate.event.pose.at.target.unknown", `Unknown event at-reference target "${placement.target}" on "${eventId}:${pose.objectId}".`, void 0, `${fieldPrefix}.at`));
|
|
4080
|
+
} else if (reference.kind === "anchor" && !objectMap.has(reference.objectId)) {
|
|
4081
|
+
diagnostics.push(error("validate.event.pose.anchor.target.unknown", `Unknown event anchor target "${reference.objectId}" on "${eventId}:${pose.objectId}".`, void 0, `${fieldPrefix}.at`));
|
|
4082
|
+
} else if (reference.kind === "lagrange") {
|
|
4083
|
+
if (!objectMap.has(reference.primary)) {
|
|
4084
|
+
diagnostics.push(error("validate.event.pose.lagrange.primary.unknown", `Unknown event Lagrange target "${reference.primary}" on "${eventId}:${pose.objectId}".`, void 0, `${fieldPrefix}.at`));
|
|
4085
|
+
} else if (reference.secondary && !objectMap.has(reference.secondary)) {
|
|
4086
|
+
diagnostics.push(error("validate.event.pose.lagrange.secondary.unknown", `Unknown event Lagrange target "${reference.secondary}" on "${eventId}:${pose.objectId}".`, void 0, `${fieldPrefix}.at`));
|
|
4087
|
+
}
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
3691
4091
|
function validateAtTarget(object, objectMap, diagnostics) {
|
|
3692
4092
|
const reference = object.placement?.mode === "at" ? object.placement.reference : null;
|
|
3693
4093
|
if (!reference) {
|
|
@@ -3888,6 +4288,21 @@ var WorldOrbit = (() => {
|
|
|
3888
4288
|
});
|
|
3889
4289
|
}
|
|
3890
4290
|
var DRAFT_OBJECT_FIELD_KEYS = new Set(DRAFT_OBJECT_FIELD_SPECS.keys());
|
|
4291
|
+
var EVENT_POSE_FIELD_KEYS = /* @__PURE__ */ new Set([
|
|
4292
|
+
"orbit",
|
|
4293
|
+
"distance",
|
|
4294
|
+
"semiMajor",
|
|
4295
|
+
"eccentricity",
|
|
4296
|
+
"period",
|
|
4297
|
+
"angle",
|
|
4298
|
+
"inclination",
|
|
4299
|
+
"phase",
|
|
4300
|
+
"at",
|
|
4301
|
+
"surface",
|
|
4302
|
+
"free",
|
|
4303
|
+
"inner",
|
|
4304
|
+
"outer"
|
|
4305
|
+
]);
|
|
3891
4306
|
function parseWorldOrbitAtlas(source) {
|
|
3892
4307
|
return parseAtlasSource(source);
|
|
3893
4308
|
}
|
|
@@ -3905,12 +4320,15 @@ var WorldOrbit = (() => {
|
|
|
3905
4320
|
const objectNodes = [];
|
|
3906
4321
|
const groups = [];
|
|
3907
4322
|
const relations = [];
|
|
4323
|
+
const events = [];
|
|
4324
|
+
const eventPoseNodes = /* @__PURE__ */ new Map();
|
|
3908
4325
|
let sawDefaults = false;
|
|
3909
4326
|
let sawAtlas = false;
|
|
3910
4327
|
const viewpointIds = /* @__PURE__ */ new Set();
|
|
3911
4328
|
const annotationIds = /* @__PURE__ */ new Set();
|
|
3912
4329
|
const groupIds = /* @__PURE__ */ new Set();
|
|
3913
4330
|
const relationIds = /* @__PURE__ */ new Set();
|
|
4331
|
+
const eventIds = /* @__PURE__ */ new Set();
|
|
3914
4332
|
for (let index = 0; index < lines.length; index++) {
|
|
3915
4333
|
const rawLine = lines[index];
|
|
3916
4334
|
const lineNumber = index + 1;
|
|
@@ -3941,7 +4359,7 @@ var WorldOrbit = (() => {
|
|
|
3941
4359
|
continue;
|
|
3942
4360
|
}
|
|
3943
4361
|
if (indent === 0) {
|
|
3944
|
-
section = startTopLevelSection(tokens, lineNumber, sourceSchemaVersion, diagnostics, system, objectNodes, groups, relations, viewpointIds, annotationIds, groupIds, relationIds, { sawDefaults, sawAtlas });
|
|
4362
|
+
section = startTopLevelSection(tokens, lineNumber, sourceSchemaVersion, diagnostics, system, objectNodes, groups, relations, events, eventPoseNodes, viewpointIds, annotationIds, groupIds, relationIds, eventIds, { sawDefaults, sawAtlas });
|
|
3945
4363
|
if (section.kind === "system") {
|
|
3946
4364
|
system = section.system;
|
|
3947
4365
|
} else if (section.kind === "defaults") {
|
|
@@ -3960,6 +4378,7 @@ var WorldOrbit = (() => {
|
|
|
3960
4378
|
throw new WorldOrbitError('Missing required atlas schema header "schema 2.0"');
|
|
3961
4379
|
}
|
|
3962
4380
|
const objects = objectNodes.map((node) => normalizeDraftObject(node, sourceSchemaVersion, diagnostics));
|
|
4381
|
+
const normalizedEvents = events.map((event) => normalizeDraftEvent(event, eventPoseNodes.get(event.id) ?? []));
|
|
3963
4382
|
const outputVersion = forcedOutputVersion ?? (sourceSchemaVersion === "2.0-draft" ? "2.0" : sourceSchemaVersion);
|
|
3964
4383
|
const baseDocument = {
|
|
3965
4384
|
format: "worldorbit",
|
|
@@ -3967,6 +4386,7 @@ var WorldOrbit = (() => {
|
|
|
3967
4386
|
system,
|
|
3968
4387
|
groups,
|
|
3969
4388
|
relations,
|
|
4389
|
+
events: normalizedEvents,
|
|
3970
4390
|
objects,
|
|
3971
4391
|
diagnostics
|
|
3972
4392
|
};
|
|
@@ -4002,7 +4422,7 @@ var WorldOrbit = (() => {
|
|
|
4002
4422
|
const version = tokens[1].value.toLowerCase();
|
|
4003
4423
|
return version === "2.1" ? "2.1" : version === "2.0-draft" ? "2.0-draft" : "2.0";
|
|
4004
4424
|
}
|
|
4005
|
-
function startTopLevelSection(tokens, line, sourceSchemaVersion, diagnostics, system, objectNodes, groups, relations, viewpointIds, annotationIds, groupIds, relationIds, flags) {
|
|
4425
|
+
function startTopLevelSection(tokens, line, sourceSchemaVersion, diagnostics, system, objectNodes, groups, relations, events, eventPoseNodes, viewpointIds, annotationIds, groupIds, relationIds, eventIds, flags) {
|
|
4006
4426
|
const keyword = tokens[0]?.value.toLowerCase();
|
|
4007
4427
|
switch (keyword) {
|
|
4008
4428
|
case "system":
|
|
@@ -4039,7 +4459,7 @@ var WorldOrbit = (() => {
|
|
|
4039
4459
|
if (!system) {
|
|
4040
4460
|
throw new WorldOrbitError('Atlas section "viewpoint" requires a preceding system declaration', line, tokens[0].column);
|
|
4041
4461
|
}
|
|
4042
|
-
return startViewpointSection(tokens, line, system, viewpointIds);
|
|
4462
|
+
return startViewpointSection(tokens, line, system, viewpointIds, sourceSchemaVersion, diagnostics);
|
|
4043
4463
|
case "annotation":
|
|
4044
4464
|
if (!system) {
|
|
4045
4465
|
throw new WorldOrbitError('Atlas section "annotation" requires a preceding system declaration', line, tokens[0].column);
|
|
@@ -4051,6 +4471,9 @@ var WorldOrbit = (() => {
|
|
|
4051
4471
|
case "relation":
|
|
4052
4472
|
warnIfSchema21Feature(sourceSchemaVersion, diagnostics, "relation", { line, column: tokens[0].column });
|
|
4053
4473
|
return startRelationSection(tokens, line, relations, relationIds);
|
|
4474
|
+
case "event":
|
|
4475
|
+
warnIfSchema21Feature(sourceSchemaVersion, diagnostics, "event", { line, column: tokens[0].column });
|
|
4476
|
+
return startEventSection(tokens, line, events, eventPoseNodes, eventIds, sourceSchemaVersion, diagnostics);
|
|
4054
4477
|
case "object":
|
|
4055
4478
|
return startObjectSection(tokens, line, sourceSchemaVersion, diagnostics, objectNodes);
|
|
4056
4479
|
default:
|
|
@@ -4087,7 +4510,7 @@ var WorldOrbit = (() => {
|
|
|
4087
4510
|
seenFields: /* @__PURE__ */ new Set()
|
|
4088
4511
|
};
|
|
4089
4512
|
}
|
|
4090
|
-
function startViewpointSection(tokens, line, system, viewpointIds) {
|
|
4513
|
+
function startViewpointSection(tokens, line, system, viewpointIds, sourceSchemaVersion, diagnostics) {
|
|
4091
4514
|
if (tokens.length !== 2) {
|
|
4092
4515
|
throw new WorldOrbitError("Invalid viewpoint declaration", line, tokens[0]?.column ?? 1);
|
|
4093
4516
|
}
|
|
@@ -4104,6 +4527,7 @@ var WorldOrbit = (() => {
|
|
|
4104
4527
|
summary: "",
|
|
4105
4528
|
focusObjectId: null,
|
|
4106
4529
|
selectedObjectId: null,
|
|
4530
|
+
events: [],
|
|
4107
4531
|
projection: system.defaults.view,
|
|
4108
4532
|
preset: system.defaults.preset,
|
|
4109
4533
|
zoom: null,
|
|
@@ -4116,6 +4540,8 @@ var WorldOrbit = (() => {
|
|
|
4116
4540
|
return {
|
|
4117
4541
|
kind: "viewpoint",
|
|
4118
4542
|
viewpoint,
|
|
4543
|
+
sourceSchemaVersion,
|
|
4544
|
+
diagnostics,
|
|
4119
4545
|
seenFields: /* @__PURE__ */ new Set(),
|
|
4120
4546
|
inFilter: false,
|
|
4121
4547
|
filterIndent: null,
|
|
@@ -4206,6 +4632,49 @@ var WorldOrbit = (() => {
|
|
|
4206
4632
|
seenFields: /* @__PURE__ */ new Set()
|
|
4207
4633
|
};
|
|
4208
4634
|
}
|
|
4635
|
+
function startEventSection(tokens, line, events, eventPoseNodes, eventIds, sourceSchemaVersion, diagnostics) {
|
|
4636
|
+
if (tokens.length !== 2) {
|
|
4637
|
+
throw new WorldOrbitError("Invalid event declaration", line, tokens[0]?.column ?? 1);
|
|
4638
|
+
}
|
|
4639
|
+
const id = normalizeIdentifier2(tokens[1].value);
|
|
4640
|
+
if (!id) {
|
|
4641
|
+
throw new WorldOrbitError("Event id must not be empty", line, tokens[1].column);
|
|
4642
|
+
}
|
|
4643
|
+
if (eventIds.has(id)) {
|
|
4644
|
+
throw new WorldOrbitError(`Duplicate event id "${id}"`, line, tokens[1].column);
|
|
4645
|
+
}
|
|
4646
|
+
const event = {
|
|
4647
|
+
id,
|
|
4648
|
+
kind: "",
|
|
4649
|
+
label: humanizeIdentifier3(id),
|
|
4650
|
+
summary: null,
|
|
4651
|
+
targetObjectId: null,
|
|
4652
|
+
participantObjectIds: [],
|
|
4653
|
+
timing: null,
|
|
4654
|
+
visibility: null,
|
|
4655
|
+
tags: [],
|
|
4656
|
+
color: null,
|
|
4657
|
+
hidden: false,
|
|
4658
|
+
positions: []
|
|
4659
|
+
};
|
|
4660
|
+
const rawPoses = [];
|
|
4661
|
+
events.push(event);
|
|
4662
|
+
eventPoseNodes.set(id, rawPoses);
|
|
4663
|
+
eventIds.add(id);
|
|
4664
|
+
return {
|
|
4665
|
+
kind: "event",
|
|
4666
|
+
event,
|
|
4667
|
+
sourceSchemaVersion,
|
|
4668
|
+
diagnostics,
|
|
4669
|
+
seenFields: /* @__PURE__ */ new Set(),
|
|
4670
|
+
rawPoses,
|
|
4671
|
+
inPositions: false,
|
|
4672
|
+
positionsIndent: null,
|
|
4673
|
+
activePose: null,
|
|
4674
|
+
poseIndent: null,
|
|
4675
|
+
activePoseSeenFields: /* @__PURE__ */ new Set()
|
|
4676
|
+
};
|
|
4677
|
+
}
|
|
4209
4678
|
function startObjectSection(tokens, line, sourceSchemaVersion, diagnostics, objectNodes) {
|
|
4210
4679
|
if (tokens.length < 3) {
|
|
4211
4680
|
throw new WorldOrbitError("Invalid atlas object declaration", line, tokens[0]?.column ?? 1);
|
|
@@ -4262,6 +4731,9 @@ var WorldOrbit = (() => {
|
|
|
4262
4731
|
case "relation":
|
|
4263
4732
|
applyRelationField(section, tokens, line);
|
|
4264
4733
|
return;
|
|
4734
|
+
case "event":
|
|
4735
|
+
applyEventField(section, indent, tokens, line);
|
|
4736
|
+
return;
|
|
4265
4737
|
case "object":
|
|
4266
4738
|
applyObjectField(section, indent, tokens, line);
|
|
4267
4739
|
return;
|
|
@@ -4388,7 +4860,14 @@ var WorldOrbit = (() => {
|
|
|
4388
4860
|
section.viewpoint.rotationDeg = parseFiniteNumber2(value, line, tokens[0].column, "rotation");
|
|
4389
4861
|
return;
|
|
4390
4862
|
case "layers":
|
|
4391
|
-
section.viewpoint.layers = parseLayerTokens(tokens.slice(1), line);
|
|
4863
|
+
section.viewpoint.layers = parseLayerTokens(tokens.slice(1), line, section.sourceSchemaVersion, section.diagnostics);
|
|
4864
|
+
return;
|
|
4865
|
+
case "events":
|
|
4866
|
+
warnIfSchema21Feature(section.sourceSchemaVersion, section.diagnostics, "viewpoint.events", {
|
|
4867
|
+
line,
|
|
4868
|
+
column: tokens[0].column
|
|
4869
|
+
});
|
|
4870
|
+
section.viewpoint.events = parseTokenList(tokens.slice(1), line, "events");
|
|
4392
4871
|
return;
|
|
4393
4872
|
default:
|
|
4394
4873
|
throw new WorldOrbitError(`Unknown viewpoint field "${tokens[0].value}"`, line, tokens[0].column);
|
|
@@ -4493,6 +4972,106 @@ var WorldOrbit = (() => {
|
|
|
4493
4972
|
throw new WorldOrbitError(`Unknown relation field "${tokens[0].value}"`, line, tokens[0].column);
|
|
4494
4973
|
}
|
|
4495
4974
|
}
|
|
4975
|
+
function applyEventField(section, indent, tokens, line) {
|
|
4976
|
+
if (section.activePose && indent <= (section.poseIndent ?? 0)) {
|
|
4977
|
+
section.activePose = null;
|
|
4978
|
+
section.poseIndent = null;
|
|
4979
|
+
section.activePoseSeenFields.clear();
|
|
4980
|
+
}
|
|
4981
|
+
if (!section.activePose && section.inPositions && indent <= (section.positionsIndent ?? 0)) {
|
|
4982
|
+
section.inPositions = false;
|
|
4983
|
+
section.positionsIndent = null;
|
|
4984
|
+
}
|
|
4985
|
+
if (section.activePose) {
|
|
4986
|
+
section.activePose.fields.push(parseEventPoseField(tokens, line, section.activePoseSeenFields));
|
|
4987
|
+
return;
|
|
4988
|
+
}
|
|
4989
|
+
if (section.inPositions) {
|
|
4990
|
+
if (tokens.length !== 2 || tokens[0].value.toLowerCase() !== "pose") {
|
|
4991
|
+
throw new WorldOrbitError(`Unknown event positions field "${tokens[0].value}"`, line, tokens[0]?.column ?? 1);
|
|
4992
|
+
}
|
|
4993
|
+
const objectId = tokens[1].value;
|
|
4994
|
+
if (!objectId.trim()) {
|
|
4995
|
+
throw new WorldOrbitError("Event pose object id must not be empty", line, tokens[1].column);
|
|
4996
|
+
}
|
|
4997
|
+
const rawPose = {
|
|
4998
|
+
objectId,
|
|
4999
|
+
fields: [],
|
|
5000
|
+
location: { line, column: tokens[0].column }
|
|
5001
|
+
};
|
|
5002
|
+
section.rawPoses.push(rawPose);
|
|
5003
|
+
section.activePose = rawPose;
|
|
5004
|
+
section.poseIndent = indent;
|
|
5005
|
+
section.activePoseSeenFields = /* @__PURE__ */ new Set();
|
|
5006
|
+
return;
|
|
5007
|
+
}
|
|
5008
|
+
if (tokens.length === 1 && tokens[0].value.toLowerCase() === "positions") {
|
|
5009
|
+
if (section.seenFields.has("positions")) {
|
|
5010
|
+
throw new WorldOrbitError('Duplicate event field "positions"', line, tokens[0].column);
|
|
5011
|
+
}
|
|
5012
|
+
section.seenFields.add("positions");
|
|
5013
|
+
section.inPositions = true;
|
|
5014
|
+
section.positionsIndent = indent;
|
|
5015
|
+
return;
|
|
5016
|
+
}
|
|
5017
|
+
const key = requireUniqueField(tokens, section.seenFields, line);
|
|
5018
|
+
switch (key) {
|
|
5019
|
+
case "kind":
|
|
5020
|
+
section.event.kind = joinFieldValue(tokens, line);
|
|
5021
|
+
return;
|
|
5022
|
+
case "label":
|
|
5023
|
+
section.event.label = joinFieldValue(tokens, line);
|
|
5024
|
+
return;
|
|
5025
|
+
case "summary":
|
|
5026
|
+
section.event.summary = joinFieldValue(tokens, line);
|
|
5027
|
+
return;
|
|
5028
|
+
case "target":
|
|
5029
|
+
section.event.targetObjectId = joinFieldValue(tokens, line);
|
|
5030
|
+
return;
|
|
5031
|
+
case "participants":
|
|
5032
|
+
section.event.participantObjectIds = parseTokenList(tokens.slice(1), line, "participants");
|
|
5033
|
+
return;
|
|
5034
|
+
case "timing":
|
|
5035
|
+
section.event.timing = joinFieldValue(tokens, line);
|
|
5036
|
+
return;
|
|
5037
|
+
case "visibility":
|
|
5038
|
+
section.event.visibility = joinFieldValue(tokens, line);
|
|
5039
|
+
return;
|
|
5040
|
+
case "tags":
|
|
5041
|
+
section.event.tags = parseTokenList(tokens.slice(1), line, "tags");
|
|
5042
|
+
return;
|
|
5043
|
+
case "color":
|
|
5044
|
+
section.event.color = joinFieldValue(tokens, line);
|
|
5045
|
+
return;
|
|
5046
|
+
case "hidden":
|
|
5047
|
+
section.event.hidden = parseAtlasBoolean(joinFieldValue(tokens, line), "hidden", {
|
|
5048
|
+
line,
|
|
5049
|
+
column: tokens[0].column
|
|
5050
|
+
});
|
|
5051
|
+
return;
|
|
5052
|
+
default:
|
|
5053
|
+
throw new WorldOrbitError(`Unknown event field "${tokens[0].value}"`, line, tokens[0].column);
|
|
5054
|
+
}
|
|
5055
|
+
}
|
|
5056
|
+
function parseEventPoseField(tokens, line, seenFields) {
|
|
5057
|
+
if (tokens.length < 2) {
|
|
5058
|
+
throw new WorldOrbitError("Invalid event pose field line", line, tokens[0]?.column ?? 1);
|
|
5059
|
+
}
|
|
5060
|
+
const key = tokens[0].value;
|
|
5061
|
+
if (!EVENT_POSE_FIELD_KEYS.has(key)) {
|
|
5062
|
+
throw new WorldOrbitError(`Unknown event pose field "${key}"`, line, tokens[0].column);
|
|
5063
|
+
}
|
|
5064
|
+
if (seenFields.has(key)) {
|
|
5065
|
+
throw new WorldOrbitError(`Duplicate event pose field "${key}"`, line, tokens[0].column);
|
|
5066
|
+
}
|
|
5067
|
+
seenFields.add(key);
|
|
5068
|
+
return {
|
|
5069
|
+
type: "field",
|
|
5070
|
+
key,
|
|
5071
|
+
values: tokens.slice(1).map((token) => token.value),
|
|
5072
|
+
location: { line, column: tokens[0].column }
|
|
5073
|
+
};
|
|
5074
|
+
}
|
|
4496
5075
|
function applyObjectField(section, indent, tokens, line) {
|
|
4497
5076
|
if (section.activeBlock && indent <= (section.blockIndent ?? 0)) {
|
|
4498
5077
|
section.activeBlock = null;
|
|
@@ -4551,7 +5130,7 @@ var WorldOrbit = (() => {
|
|
|
4551
5130
|
function parseObjectTypeTokens(tokens, line) {
|
|
4552
5131
|
return parseTokenList(tokens, line, "objectTypes").filter((value) => value === "star" || value === "planet" || value === "moon" || value === "belt" || value === "asteroid" || value === "comet" || value === "ring" || value === "structure" || value === "phenomenon");
|
|
4553
5132
|
}
|
|
4554
|
-
function parseLayerTokens(tokens, line) {
|
|
5133
|
+
function parseLayerTokens(tokens, line, sourceSchemaVersion, diagnostics) {
|
|
4555
5134
|
const layers = {};
|
|
4556
5135
|
for (const token of parseTokenList(tokens, line, "layers")) {
|
|
4557
5136
|
const enabled = !token.startsWith("-") && !token.startsWith("!");
|
|
@@ -4561,7 +5140,13 @@ var WorldOrbit = (() => {
|
|
|
4561
5140
|
layers["orbits-front"] = enabled;
|
|
4562
5141
|
continue;
|
|
4563
5142
|
}
|
|
4564
|
-
if (raw === "background" || raw === "guides" || raw === "orbits-back" || raw === "orbits-front" || raw === "relations" || raw === "objects" || raw === "labels" || raw === "metadata") {
|
|
5143
|
+
if (raw === "background" || raw === "guides" || raw === "orbits-back" || raw === "orbits-front" || raw === "relations" || raw === "events" || raw === "objects" || raw === "labels" || raw === "metadata") {
|
|
5144
|
+
if (raw === "events" && sourceSchemaVersion && diagnostics) {
|
|
5145
|
+
warnIfSchema21Feature(sourceSchemaVersion, diagnostics, "layers.events", {
|
|
5146
|
+
line,
|
|
5147
|
+
column: tokens[0]?.column ?? 1
|
|
5148
|
+
});
|
|
5149
|
+
}
|
|
4565
5150
|
layers[raw] = enabled;
|
|
4566
5151
|
}
|
|
4567
5152
|
}
|
|
@@ -4700,7 +5285,7 @@ var WorldOrbit = (() => {
|
|
|
4700
5285
|
}
|
|
4701
5286
|
function normalizeDraftObject(node, sourceSchemaVersion, diagnostics) {
|
|
4702
5287
|
const fieldMap = collectDraftFields(node.fields);
|
|
4703
|
-
const placement =
|
|
5288
|
+
const placement = extractPlacementFromFieldMap(fieldMap);
|
|
4704
5289
|
const properties = normalizeDraftProperties(node.objectType, fieldMap);
|
|
4705
5290
|
const groups = parseOptionalTokenList(fieldMap.get("groups")?.[0]);
|
|
4706
5291
|
const epoch = parseOptionalJoinedValue(fieldMap.get("epoch")?.[0]);
|
|
@@ -4752,6 +5337,24 @@ var WorldOrbit = (() => {
|
|
|
4752
5337
|
}
|
|
4753
5338
|
return object;
|
|
4754
5339
|
}
|
|
5340
|
+
function normalizeDraftEvent(event, rawPoses) {
|
|
5341
|
+
return {
|
|
5342
|
+
...event,
|
|
5343
|
+
participantObjectIds: [...new Set(event.participantObjectIds)],
|
|
5344
|
+
tags: [...new Set(event.tags)],
|
|
5345
|
+
positions: rawPoses.map((pose) => normalizeDraftEventPose(pose))
|
|
5346
|
+
};
|
|
5347
|
+
}
|
|
5348
|
+
function normalizeDraftEventPose(rawPose) {
|
|
5349
|
+
const fieldMap = collectDraftFields(rawPose.fields);
|
|
5350
|
+
const placement = extractPlacementFromFieldMap(fieldMap);
|
|
5351
|
+
return {
|
|
5352
|
+
objectId: rawPose.objectId,
|
|
5353
|
+
placement,
|
|
5354
|
+
inner: parseOptionalUnitField(fieldMap.get("inner")?.[0], "inner"),
|
|
5355
|
+
outer: parseOptionalUnitField(fieldMap.get("outer")?.[0], "outer")
|
|
5356
|
+
};
|
|
5357
|
+
}
|
|
4755
5358
|
function collectDraftFields(fields) {
|
|
4756
5359
|
const grouped = /* @__PURE__ */ new Map();
|
|
4757
5360
|
for (const field of fields) {
|
|
@@ -4768,7 +5371,7 @@ var WorldOrbit = (() => {
|
|
|
4768
5371
|
}
|
|
4769
5372
|
return grouped;
|
|
4770
5373
|
}
|
|
4771
|
-
function
|
|
5374
|
+
function extractPlacementFromFieldMap(fieldMap) {
|
|
4772
5375
|
const orbitField = fieldMap.get("orbit")?.[0];
|
|
4773
5376
|
const atField = fieldMap.get("at")?.[0];
|
|
4774
5377
|
const surfaceField = fieldMap.get("surface")?.[0];
|
|
@@ -5061,6 +5664,7 @@ var WorldOrbit = (() => {
|
|
|
5061
5664
|
},
|
|
5062
5665
|
groups: [],
|
|
5063
5666
|
relations: [],
|
|
5667
|
+
events: [],
|
|
5064
5668
|
objects: [],
|
|
5065
5669
|
diagnostics: []
|
|
5066
5670
|
};
|
|
@@ -5087,6 +5691,12 @@ var WorldOrbit = (() => {
|
|
|
5087
5691
|
for (const relation of [...document2.relations].sort(compareIdLike2)) {
|
|
5088
5692
|
paths.push({ kind: "relation", id: relation.id });
|
|
5089
5693
|
}
|
|
5694
|
+
for (const event of [...document2.events].sort(compareIdLike2)) {
|
|
5695
|
+
paths.push({ kind: "event", id: event.id });
|
|
5696
|
+
for (const pose of [...event.positions].sort(comparePoseObjectId2)) {
|
|
5697
|
+
paths.push({ kind: "event-pose", id: event.id, key: pose.objectId });
|
|
5698
|
+
}
|
|
5699
|
+
}
|
|
5090
5700
|
for (const object of [...document2.objects].sort(compareIdLike2)) {
|
|
5091
5701
|
paths.push({ kind: "object", id: object.id });
|
|
5092
5702
|
}
|
|
@@ -5102,6 +5712,10 @@ var WorldOrbit = (() => {
|
|
|
5102
5712
|
return path.key ? document2.system?.atlasMetadata[path.key] ?? null : null;
|
|
5103
5713
|
case "group":
|
|
5104
5714
|
return path.id ? findGroup(document2, path.id) : null;
|
|
5715
|
+
case "event":
|
|
5716
|
+
return path.id ? findEvent(document2, path.id) : null;
|
|
5717
|
+
case "event-pose":
|
|
5718
|
+
return path.id && path.key ? findEventPose(document2, path.id, path.key) : null;
|
|
5105
5719
|
case "object":
|
|
5106
5720
|
return path.id ? findObject(document2, path.id) : null;
|
|
5107
5721
|
case "viewpoint":
|
|
@@ -5141,6 +5755,18 @@ var WorldOrbit = (() => {
|
|
|
5141
5755
|
}
|
|
5142
5756
|
upsertById(next.groups, value);
|
|
5143
5757
|
return next;
|
|
5758
|
+
case "event":
|
|
5759
|
+
if (!path.id) {
|
|
5760
|
+
throw new Error('Event updates require an "id" value.');
|
|
5761
|
+
}
|
|
5762
|
+
upsertById(next.events, value);
|
|
5763
|
+
return next;
|
|
5764
|
+
case "event-pose":
|
|
5765
|
+
if (!path.id || !path.key) {
|
|
5766
|
+
throw new Error('Event pose updates require an event "id" and pose "key" value.');
|
|
5767
|
+
}
|
|
5768
|
+
upsertEventPose(next.events, path.id, value);
|
|
5769
|
+
return next;
|
|
5144
5770
|
case "object":
|
|
5145
5771
|
if (!path.id) {
|
|
5146
5772
|
throw new Error('Object updates require an "id" value.');
|
|
@@ -5189,6 +5815,19 @@ var WorldOrbit = (() => {
|
|
|
5189
5815
|
next.groups = next.groups.filter((group) => group.id !== path.id);
|
|
5190
5816
|
}
|
|
5191
5817
|
return next;
|
|
5818
|
+
case "event":
|
|
5819
|
+
if (path.id) {
|
|
5820
|
+
next.events = next.events.filter((event) => event.id !== path.id);
|
|
5821
|
+
}
|
|
5822
|
+
return next;
|
|
5823
|
+
case "event-pose":
|
|
5824
|
+
if (path.id && path.key) {
|
|
5825
|
+
const event = findEvent(next, path.id);
|
|
5826
|
+
if (event) {
|
|
5827
|
+
event.positions = event.positions.filter((pose) => pose.objectId !== path.key);
|
|
5828
|
+
}
|
|
5829
|
+
}
|
|
5830
|
+
return next;
|
|
5192
5831
|
case "viewpoint":
|
|
5193
5832
|
if (path.id) {
|
|
5194
5833
|
system.viewpoints = system.viewpoints.filter((viewpoint) => viewpoint.id !== path.id);
|
|
@@ -5257,6 +5896,22 @@ var WorldOrbit = (() => {
|
|
|
5257
5896
|
};
|
|
5258
5897
|
}
|
|
5259
5898
|
}
|
|
5899
|
+
if (diagnostic.field?.startsWith("event.")) {
|
|
5900
|
+
const parts = diagnostic.field.split(".");
|
|
5901
|
+
if (parts[1] && findEvent(document2, parts[1])) {
|
|
5902
|
+
if (parts[2] === "pose" && parts[3] && findEventPose(document2, parts[1], parts[3])) {
|
|
5903
|
+
return {
|
|
5904
|
+
kind: "event-pose",
|
|
5905
|
+
id: parts[1],
|
|
5906
|
+
key: parts[3]
|
|
5907
|
+
};
|
|
5908
|
+
}
|
|
5909
|
+
return {
|
|
5910
|
+
kind: "event",
|
|
5911
|
+
id: parts[1]
|
|
5912
|
+
};
|
|
5913
|
+
}
|
|
5914
|
+
}
|
|
5260
5915
|
if (diagnostic.field && diagnostic.field in ensureSystem(document2).atlasMetadata) {
|
|
5261
5916
|
return {
|
|
5262
5917
|
kind: "metadata",
|
|
@@ -5288,6 +5943,12 @@ var WorldOrbit = (() => {
|
|
|
5288
5943
|
function findRelation(document2, relationId) {
|
|
5289
5944
|
return document2.relations.find((relation) => relation.id === relationId) ?? null;
|
|
5290
5945
|
}
|
|
5946
|
+
function findEvent(document2, eventId) {
|
|
5947
|
+
return document2.events.find((event) => event.id === eventId) ?? null;
|
|
5948
|
+
}
|
|
5949
|
+
function findEventPose(document2, eventId, objectId) {
|
|
5950
|
+
return findEvent(document2, eventId)?.positions.find((pose) => pose.objectId === objectId) ?? null;
|
|
5951
|
+
}
|
|
5291
5952
|
function findViewpoint(system, viewpointId) {
|
|
5292
5953
|
return system?.viewpoints.find((viewpoint) => viewpoint.id === viewpointId) ?? null;
|
|
5293
5954
|
}
|
|
@@ -5303,9 +5964,25 @@ var WorldOrbit = (() => {
|
|
|
5303
5964
|
}
|
|
5304
5965
|
items[index] = value;
|
|
5305
5966
|
}
|
|
5967
|
+
function upsertEventPose(events, eventId, value) {
|
|
5968
|
+
const event = events.find((entry) => entry.id === eventId);
|
|
5969
|
+
if (!event) {
|
|
5970
|
+
throw new Error(`Unknown event "${eventId}" for pose update.`);
|
|
5971
|
+
}
|
|
5972
|
+
const index = event.positions.findIndex((entry) => entry.objectId === value.objectId);
|
|
5973
|
+
if (index === -1) {
|
|
5974
|
+
event.positions.push(value);
|
|
5975
|
+
event.positions.sort(comparePoseObjectId2);
|
|
5976
|
+
return;
|
|
5977
|
+
}
|
|
5978
|
+
event.positions[index] = value;
|
|
5979
|
+
}
|
|
5306
5980
|
function compareIdLike2(left, right) {
|
|
5307
5981
|
return left.id.localeCompare(right.id);
|
|
5308
5982
|
}
|
|
5983
|
+
function comparePoseObjectId2(left, right) {
|
|
5984
|
+
return left.objectId.localeCompare(right.objectId);
|
|
5985
|
+
}
|
|
5309
5986
|
|
|
5310
5987
|
// packages/core/dist/load.js
|
|
5311
5988
|
var ATLAS_SCHEMA_PATTERN = /^schema\s+2(?:\.0|\.1)?$/i;
|
|
@@ -5540,6 +6217,7 @@ var WorldOrbit = (() => {
|
|
|
5540
6217
|
background: true,
|
|
5541
6218
|
guides: true,
|
|
5542
6219
|
relations: true,
|
|
6220
|
+
events: true,
|
|
5543
6221
|
orbits: true,
|
|
5544
6222
|
objects: true,
|
|
5545
6223
|
labels: true,
|
|
@@ -5691,12 +6369,14 @@ var WorldOrbit = (() => {
|
|
|
5691
6369
|
return {
|
|
5692
6370
|
version: "2.0",
|
|
5693
6371
|
viewpointId,
|
|
6372
|
+
activeEventId: renderOptions.activeEventId ?? null,
|
|
5694
6373
|
viewerState: { ...viewerState },
|
|
5695
6374
|
renderOptions: {
|
|
5696
6375
|
preset: renderOptions.preset,
|
|
5697
6376
|
projection: renderOptions.projection,
|
|
5698
6377
|
layers: renderOptions.layers ? { ...renderOptions.layers } : void 0,
|
|
5699
|
-
scaleModel: renderOptions.scaleModel ? { ...renderOptions.scaleModel } : void 0
|
|
6378
|
+
scaleModel: renderOptions.scaleModel ? { ...renderOptions.scaleModel } : void 0,
|
|
6379
|
+
activeEventId: renderOptions.activeEventId ?? null
|
|
5700
6380
|
},
|
|
5701
6381
|
filter: normalizeViewerFilter(filter)
|
|
5702
6382
|
};
|
|
@@ -5709,6 +6389,7 @@ var WorldOrbit = (() => {
|
|
|
5709
6389
|
return {
|
|
5710
6390
|
version: "2.0",
|
|
5711
6391
|
viewpointId: raw.viewpointId ?? null,
|
|
6392
|
+
activeEventId: raw.activeEventId ?? raw.renderOptions?.activeEventId ?? null,
|
|
5712
6393
|
viewerState: {
|
|
5713
6394
|
scale: raw.viewerState?.scale ?? 1,
|
|
5714
6395
|
rotationDeg: raw.viewerState?.rotationDeg ?? 0,
|
|
@@ -5720,7 +6401,8 @@ var WorldOrbit = (() => {
|
|
|
5720
6401
|
preset: raw.renderOptions?.preset,
|
|
5721
6402
|
projection: raw.renderOptions?.projection,
|
|
5722
6403
|
layers: raw.renderOptions?.layers ? { ...raw.renderOptions.layers } : void 0,
|
|
5723
|
-
scaleModel: raw.renderOptions?.scaleModel ? { ...raw.renderOptions.scaleModel } : void 0
|
|
6404
|
+
scaleModel: raw.renderOptions?.scaleModel ? { ...raw.renderOptions.scaleModel } : void 0,
|
|
6405
|
+
activeEventId: raw.activeEventId ?? raw.renderOptions?.activeEventId ?? null
|
|
5724
6406
|
},
|
|
5725
6407
|
filter: normalizeViewerFilter(raw.filter ?? null)
|
|
5726
6408
|
};
|
|
@@ -5736,7 +6418,8 @@ var WorldOrbit = (() => {
|
|
|
5736
6418
|
renderOptions: {
|
|
5737
6419
|
...atlasState.renderOptions,
|
|
5738
6420
|
layers: atlasState.renderOptions.layers ? { ...atlasState.renderOptions.layers } : void 0,
|
|
5739
|
-
scaleModel: atlasState.renderOptions.scaleModel ? { ...atlasState.renderOptions.scaleModel } : void 0
|
|
6421
|
+
scaleModel: atlasState.renderOptions.scaleModel ? { ...atlasState.renderOptions.scaleModel } : void 0,
|
|
6422
|
+
activeEventId: atlasState.renderOptions.activeEventId ?? null
|
|
5740
6423
|
},
|
|
5741
6424
|
filter: atlasState.filter ? { ...atlasState.filter } : null
|
|
5742
6425
|
}
|
|
@@ -5754,6 +6437,7 @@ var WorldOrbit = (() => {
|
|
|
5754
6437
|
background: viewpoint.layers.background,
|
|
5755
6438
|
guides: viewpoint.layers.guides,
|
|
5756
6439
|
relations: viewpoint.layers.relations,
|
|
6440
|
+
events: viewpoint.layers.events,
|
|
5757
6441
|
orbits: viewpoint.layers["orbits-front"] === void 0 && viewpoint.layers["orbits-back"] === void 0 ? void 0 : viewpoint.layers["orbits-front"] !== false || viewpoint.layers["orbits-back"] !== false,
|
|
5758
6442
|
objects: viewpoint.layers.objects,
|
|
5759
6443
|
labels: viewpoint.layers.labels,
|
|
@@ -6040,6 +6724,7 @@ var WorldOrbit = (() => {
|
|
|
6040
6724
|
const orbitMarkup = layers.orbits ? renderOrbitLayer(scene, visibleObjectIds, layers.structures) : { back: "", front: "" };
|
|
6041
6725
|
const leaderMarkup = layers.guides ? scene.leaders.filter((leader) => !leader.hidden).filter((leader) => visibleObjectIds.has(leader.objectId)).filter((leader) => layers.structures || !isStructureLike(leader.object)).map((leader) => `<line class="wo-leader wo-leader-${leader.mode}" x1="${leader.x1}" y1="${leader.y1}" x2="${leader.x2}" y2="${leader.y2}" data-render-id="${escapeXml(leader.renderId)}" data-group-id="${escapeAttribute(leader.groupId ?? "")}" />`).join("") : "";
|
|
6042
6726
|
const relationMarkup = layers.relations ? scene.relations.filter((relation) => !relation.hidden).filter((relation) => visibleObjectIds.has(relation.fromObjectId) && visibleObjectIds.has(relation.toObjectId)).map((relation) => `<line class="wo-relation" x1="${relation.x1}" y1="${relation.y1}" x2="${relation.x2}" y2="${relation.y2}" data-render-id="${escapeXml(relation.renderId)}" data-relation-id="${escapeAttribute(relation.relationId)}" />`).join("") : "";
|
|
6727
|
+
const eventMarkup = layers.events ? scene.events.filter((event) => !event.hidden).map((event) => renderSceneEventOverlay(scene, event, visibleObjectIds, theme)).join("") : "";
|
|
6043
6728
|
const objectMarkup = layers.objects ? visibleObjects.map((object) => renderSceneObject(object, options.selectedObjectId ?? null, theme)).join("") : "";
|
|
6044
6729
|
const labelMarkup = layers.labels ? visibleLabels.map((label) => renderSceneLabel(scene, label, options.selectedObjectId ?? null)).join("") : "";
|
|
6045
6730
|
const metadataMarkup = layers.metadata ? `<text class="wo-title" x="56" y="64">${escapeXml(scene.title)}</text>
|
|
@@ -6075,6 +6760,9 @@ var WorldOrbit = (() => {
|
|
|
6075
6760
|
.wo-orbit-front { opacity: 0.9; }
|
|
6076
6761
|
.wo-orbit-band { stroke: ${theme.orbitBand}; stroke-linecap: round; }
|
|
6077
6762
|
.wo-relation { stroke: ${theme.relation}; stroke-width: 2; stroke-dasharray: 10 6; }
|
|
6763
|
+
.wo-event-line { stroke: ${theme.accent}; stroke-width: 1.6; stroke-dasharray: 5 5; opacity: 0.72; }
|
|
6764
|
+
.wo-event-node { fill: ${theme.accent}; stroke: ${theme.selected}; stroke-width: 1.4; opacity: 0.92; }
|
|
6765
|
+
.wo-event-label { fill: ${theme.accent}; font-family: ${theme.fontFamily}; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
|
|
6078
6766
|
.wo-leader { stroke: ${theme.leader}; stroke-width: 1.5; stroke-dasharray: 6 5; }
|
|
6079
6767
|
.wo-label { fill: ${theme.ink}; font-family: ${theme.fontFamily}; font-weight: 600; letter-spacing: 0.02em; }
|
|
6080
6768
|
.wo-label-secondary { fill: ${theme.muted}; font-family: ${theme.fontFamily}; font-weight: 500; }
|
|
@@ -6109,6 +6797,7 @@ var WorldOrbit = (() => {
|
|
|
6109
6797
|
${layers.orbits ? `<g data-layer-id="orbits-back">${orbitMarkup.back}</g>` : ""}
|
|
6110
6798
|
${layers.guides ? `<g data-layer-id="guides">${leaderMarkup}</g>` : ""}
|
|
6111
6799
|
${layers.relations ? `<g data-layer-id="relations">${relationMarkup}</g>` : ""}
|
|
6800
|
+
${layers.events ? `<g data-layer-id="events">${eventMarkup}</g>` : ""}
|
|
6112
6801
|
${layers.objects ? `<g data-layer-id="objects">${objectMarkup}</g>` : ""}
|
|
6113
6802
|
${layers.orbits ? `<g data-layer-id="orbits-front">${orbitMarkup.front}</g>` : ""}
|
|
6114
6803
|
${layers.labels ? `<g data-layer-id="labels">${labelMarkup}</g>` : ""}
|
|
@@ -6116,6 +6805,20 @@ var WorldOrbit = (() => {
|
|
|
6116
6805
|
</g>
|
|
6117
6806
|
</g>
|
|
6118
6807
|
</svg>`;
|
|
6808
|
+
}
|
|
6809
|
+
function renderSceneEventOverlay(scene, event, visibleObjectIds, theme) {
|
|
6810
|
+
const participants = event.objectIds.filter((objectId) => visibleObjectIds.has(objectId)).map((objectId) => scene.objects.find((object) => object.objectId === objectId && !object.hidden)).filter(Boolean);
|
|
6811
|
+
if (participants.length === 0) {
|
|
6812
|
+
return "";
|
|
6813
|
+
}
|
|
6814
|
+
const stroke = event.event.color || theme.accent;
|
|
6815
|
+
const label = event.event.label || event.event.id;
|
|
6816
|
+
const lineMarkup = participants.map((object) => `<line class="wo-event-line" x1="${event.x}" y1="${event.y}" x2="${object.x}" y2="${object.y}" stroke="${escapeAttribute(stroke)}" data-event-id="${escapeAttribute(event.eventId)}" data-object-id="${escapeAttribute(object.objectId)}" />`).join("");
|
|
6817
|
+
return `<g class="wo-event" data-render-id="${escapeXml(event.renderId)}" data-event-id="${escapeAttribute(event.eventId)}">
|
|
6818
|
+
${lineMarkup}
|
|
6819
|
+
<circle class="wo-event-node" cx="${event.x}" cy="${event.y}" r="5" fill="${escapeAttribute(stroke)}" />
|
|
6820
|
+
<text class="wo-event-label" x="${event.x}" y="${event.y - 10}" text-anchor="middle" font-size="10">${escapeXml(label)}</text>
|
|
6821
|
+
</g>`;
|
|
6119
6822
|
}
|
|
6120
6823
|
function renderDocumentToSvg(document2, options = {}) {
|
|
6121
6824
|
return renderSceneToSvg(renderDocumentToScene(document2, options), options);
|
|
@@ -6715,6 +7418,13 @@ var WorldOrbit = (() => {
|
|
|
6715
7418
|
value: `${details.object.resonance.targetObjectId} ${details.object.resonance.ratio}`
|
|
6716
7419
|
});
|
|
6717
7420
|
}
|
|
7421
|
+
if (details.relatedEvents.length > 0) {
|
|
7422
|
+
fields.set("events", {
|
|
7423
|
+
key: "events",
|
|
7424
|
+
label: "Events",
|
|
7425
|
+
value: details.relatedEvents.map((event) => event.event.label || event.event.id).join(", ")
|
|
7426
|
+
});
|
|
7427
|
+
}
|
|
6718
7428
|
if (placement?.mode === "at") {
|
|
6719
7429
|
fields.set("placement", {
|
|
6720
7430
|
key: "placement",
|
|
@@ -7129,6 +7839,12 @@ var WorldOrbit = (() => {
|
|
|
7129
7839
|
emitAtlasStateChange();
|
|
7130
7840
|
return true;
|
|
7131
7841
|
},
|
|
7842
|
+
getActiveEventId() {
|
|
7843
|
+
return renderOptions.activeEventId ?? null;
|
|
7844
|
+
},
|
|
7845
|
+
setActiveEvent(id) {
|
|
7846
|
+
api.setRenderOptions({ activeEventId: id });
|
|
7847
|
+
},
|
|
7132
7848
|
search(query, limit = 12) {
|
|
7133
7849
|
return searchSceneObjects(scene, query, limit);
|
|
7134
7850
|
},
|
|
@@ -7393,6 +8109,7 @@ var WorldOrbit = (() => {
|
|
|
7393
8109
|
orbit: scene.orbitVisuals.find((orbit) => orbit.objectId === renderObject.objectId && !orbit.hidden) ?? null,
|
|
7394
8110
|
relatedOrbits: scene.orbitVisuals.filter((orbit) => !orbit.hidden && (orbit.objectId === renderObject.objectId || renderObject.ancestorIds.includes(orbit.objectId) || renderObject.childIds.includes(orbit.objectId))),
|
|
7395
8111
|
relations: scene.relations.filter((relation) => !relation.hidden && (relation.fromObjectId === renderObject.objectId || relation.toObjectId === renderObject.objectId)),
|
|
8112
|
+
relatedEvents: scene.events.filter((event) => !event.hidden && (event.targetObjectId === renderObject.objectId || event.objectIds.includes(renderObject.objectId))),
|
|
7396
8113
|
parent: getObjectById(renderObject.parentId),
|
|
7397
8114
|
children: renderObject.childIds.map((childId) => getObjectById(childId)).filter(Boolean),
|
|
7398
8115
|
ancestors: renderObject.ancestorIds.map((ancestorId) => getObjectById(ancestorId)).filter(Boolean),
|
|
@@ -7709,7 +8426,8 @@ var WorldOrbit = (() => {
|
|
|
7709
8426
|
filter: renderOptions.filter ? { ...renderOptions.filter } : void 0,
|
|
7710
8427
|
scaleModel: renderOptions.scaleModel ? { ...renderOptions.scaleModel } : void 0,
|
|
7711
8428
|
layers: renderOptions.layers ? { ...renderOptions.layers } : void 0,
|
|
7712
|
-
theme: renderOptions.theme && typeof renderOptions.theme === "object" ? { ...renderOptions.theme } : renderOptions.theme
|
|
8429
|
+
theme: renderOptions.theme && typeof renderOptions.theme === "object" ? { ...renderOptions.theme } : renderOptions.theme,
|
|
8430
|
+
activeEventId: renderOptions.activeEventId ?? null
|
|
7713
8431
|
};
|
|
7714
8432
|
}
|
|
7715
8433
|
function mergeRenderOptions(current, next) {
|
|
@@ -7729,7 +8447,7 @@ var WorldOrbit = (() => {
|
|
|
7729
8447
|
};
|
|
7730
8448
|
}
|
|
7731
8449
|
function hasSceneAffectingRenderOptions(options) {
|
|
7732
|
-
return options.width !== void 0 || options.height !== void 0 || options.padding !== void 0 || options.preset !== void 0 || options.projection !== void 0 || options.scaleModel !== void 0;
|
|
8450
|
+
return options.width !== void 0 || options.height !== void 0 || options.padding !== void 0 || options.preset !== void 0 || options.projection !== void 0 || options.scaleModel !== void 0 || options.activeEventId !== void 0;
|
|
7733
8451
|
}
|
|
7734
8452
|
function resolveSourceRenderOptions2(loaded, renderOptions) {
|
|
7735
8453
|
const atlasDocument = loaded.atlasDocument ?? loaded.draftDocument;
|
|
@@ -8339,6 +9057,7 @@ var WorldOrbit = (() => {
|
|
|
8339
9057
|
groupCount: activeViewer.getScene().groups.length,
|
|
8340
9058
|
semanticGroupCount: activeViewer.getScene().semanticGroups.length,
|
|
8341
9059
|
relationCount: activeViewer.getScene().relations.length,
|
|
9060
|
+
eventCount: activeViewer.getScene().events.length,
|
|
8342
9061
|
viewpointCount: activeViewer.getScene().viewpoints.length
|
|
8343
9062
|
}
|
|
8344
9063
|
};
|