@mindexec/cli 0.2.457 → 0.2.459
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/desktop-workspace-state.cjs +120 -0
- package/electron/main.cjs +17 -6
- package/electron/source-smoke.mjs +21 -0
- package/electron/windows-package-smoke.mjs +8 -2
- package/package.json +6 -5
- package/remote-fast/osx-arm64/mindexec-remote-fast.dll +0 -0
- package/remote-fast/osx-x64/mindexec-remote-fast.dll +0 -0
- package/remote-fast/win-x64/mindexec-remote-fast.dll +0 -0
- package/scripts/desktop-workspace-state-smoke.mjs +81 -0
- package/scripts/remote-fleet-render-smoke.mjs +29 -186
- package/server.js +36 -16
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-animated-image-preview.js +270 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js +57 -53
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +51 -346
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +30 -26
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-renderer.js +94 -124
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-menu-manager.js +43 -21
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-nodes.js +45 -13
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-render-plan.js +117 -1
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js +4 -1
- package/wwwroot/_framework/{MindExecution.Core.speado072l.dll → MindExecution.Core.b973f5f64y.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Kernel.mjy31ssdac.dll → MindExecution.Kernel.k4h9fvi9wb.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Admin.vbjjmdaao2.dll → MindExecution.Plugins.Admin.u2emae8cb5.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Business.0cr5jc6wqe.dll → MindExecution.Plugins.Business.cysw4qtyke.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Concept.m7p666e0jd.dll → MindExecution.Plugins.Concept.8iehgvzjio.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Directory.kmdtirnljl.dll → MindExecution.Plugins.Directory.t621fsxq2i.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.m1pfeozacj.dll → MindExecution.Plugins.PlanMaster.ft631uc7ki.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.YouTube.nvsc9q4s6b.dll → MindExecution.Plugins.YouTube.arivgu92h1.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Shared.9jaznballd.dll → MindExecution.Shared.wm997st9eb.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Web.k5jxwawryl.dll → MindExecution.Web.osdbdrue4h.dll} +0 -0
- package/wwwroot/_framework/blazor.boot.json +21 -21
- package/wwwroot/app-icon-1024.png +0 -0
- package/wwwroot/apple-touch-icon.png +0 -0
- package/wwwroot/appsettings.json +81 -81
- package/wwwroot/favicon-32x32.png +0 -0
- package/wwwroot/favicon.ico +0 -0
- package/wwwroot/icon-192.png +0 -0
- package/wwwroot/icon-512.png +0 -0
- package/wwwroot/index.html +750 -726
- package/wwwroot/manifest.webmanifest +4 -4
- package/wwwroot/mindexec-favicon-v3.png +0 -0
- package/wwwroot/service-worker-assets.js +888 -880
- package/wwwroot/service-worker.js +1 -1
|
@@ -404,65 +404,24 @@
|
|
|
404
404
|
contentType === 'embed';
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
function
|
|
408
|
-
|
|
409
|
-
if (!normalized) return false;
|
|
410
|
-
return normalized.split(/[?#]/)[0].toLowerCase().endsWith('.gif');
|
|
407
|
+
function isAnimatedGifImageModel(model) {
|
|
408
|
+
return window.MindMapAnimatedImagePreview?.isAnimatedGifImageModel?.(model) === true;
|
|
411
409
|
}
|
|
412
410
|
|
|
413
|
-
function
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
for (const key of keys) {
|
|
417
|
-
const direct = metadata[key];
|
|
418
|
-
if (direct !== undefined && direct !== null && String(direct).trim()) {
|
|
419
|
-
return String(direct).trim();
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
const wantedKeys = new Set(keys.map(key => String(key || '').toLowerCase()));
|
|
424
|
-
for (const key of Object.keys(metadata)) {
|
|
425
|
-
if (wantedKeys.has(String(key || '').toLowerCase())) {
|
|
426
|
-
const value = metadata[key];
|
|
427
|
-
if (value !== undefined && value !== null && String(value).trim()) {
|
|
428
|
-
return String(value).trim();
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
return '';
|
|
411
|
+
function isWebpImageModel(model) {
|
|
412
|
+
return window.MindMapAnimatedImagePreview?.isWebpImageModel?.(model) === true;
|
|
434
413
|
}
|
|
435
414
|
|
|
436
|
-
function
|
|
415
|
+
function isAnimationCapableImageModel(model) {
|
|
437
416
|
if (!model || getNodeContentType(model) !== 'image') {
|
|
438
417
|
return false;
|
|
439
418
|
}
|
|
440
419
|
|
|
441
|
-
if (window.MindMapNodes?.
|
|
442
|
-
return window.MindMapNodes.
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
const metadata = getNodeMetadata(model) || {};
|
|
446
|
-
const mimeType = getMetadataValueCaseInsensitive(
|
|
447
|
-
metadata,
|
|
448
|
-
'fileMime',
|
|
449
|
-
'FileMime',
|
|
450
|
-
'mimeType',
|
|
451
|
-
'MimeType'
|
|
452
|
-
).toLowerCase();
|
|
453
|
-
if (mimeType === 'image/gif') {
|
|
454
|
-
return true;
|
|
420
|
+
if (window.MindMapNodes?.isAnimationCapableImageNodeModel) {
|
|
421
|
+
return window.MindMapNodes.isAnimationCapableImageNodeModel(model) === true;
|
|
455
422
|
}
|
|
456
423
|
|
|
457
|
-
return
|
|
458
|
-
model?.response,
|
|
459
|
-
model?.Response,
|
|
460
|
-
metadata?.OriginalPath,
|
|
461
|
-
metadata?.OriginalUrl,
|
|
462
|
-
metadata?.originalUrl,
|
|
463
|
-
metadata?.ImageUrl,
|
|
464
|
-
metadata?.imageUrl
|
|
465
|
-
].some(isAnimatedGifImageUrl);
|
|
424
|
+
return isAnimatedGifImageModel(model) || isWebpImageModel(model);
|
|
466
425
|
}
|
|
467
426
|
|
|
468
427
|
function isCss3dRendererEnabled(module) {
|
|
@@ -493,40 +452,8 @@
|
|
|
493
452
|
|| normalized.startsWith('file:');
|
|
494
453
|
}
|
|
495
454
|
|
|
496
|
-
function getCanonicalImageAssetKey(url) {
|
|
497
|
-
const normalized = normalizeImageAssetUrl(url);
|
|
498
|
-
if (!normalized) {
|
|
499
|
-
return '';
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
const withoutQuery = normalized.split(/[?#]/)[0];
|
|
503
|
-
const lower = withoutQuery.toLowerCase();
|
|
504
|
-
const thumbsMarker = '/assets/thumbs/';
|
|
505
|
-
const assetsMarker = '/assets/';
|
|
506
|
-
|
|
507
|
-
if (lower.includes(thumbsMarker)) {
|
|
508
|
-
const assetName = withoutQuery.slice(lower.lastIndexOf(thumbsMarker) + thumbsMarker.length).split('/').pop() || '';
|
|
509
|
-
const dotIndex = assetName.lastIndexOf('.');
|
|
510
|
-
return (dotIndex > 0 ? assetName.slice(0, dotIndex) : assetName).toLowerCase();
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
if (lower.includes(assetsMarker)) {
|
|
514
|
-
const assetName = withoutQuery.slice(lower.lastIndexOf(assetsMarker) + assetsMarker.length).split('/').pop() || '';
|
|
515
|
-
const dotIndex = assetName.lastIndexOf('.');
|
|
516
|
-
return (dotIndex > 0 ? assetName.slice(0, dotIndex) : assetName).toLowerCase();
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
return withoutQuery.toLowerCase();
|
|
520
|
-
}
|
|
521
|
-
|
|
522
455
|
function areImageAssetUrlsEquivalent(leftUrl, rightUrl) {
|
|
523
|
-
|
|
524
|
-
const rightKey = getCanonicalImageAssetKey(rightUrl);
|
|
525
|
-
if (leftKey && rightKey) {
|
|
526
|
-
return leftKey === rightKey;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
return normalizeImageAssetUrl(leftUrl) === normalizeImageAssetUrl(rightUrl);
|
|
456
|
+
return window.MindMapAnimatedImagePreview?.areAssetUrlsEquivalent?.(leftUrl, rightUrl) === true;
|
|
530
457
|
}
|
|
531
458
|
|
|
532
459
|
function isThumbnailImageUrl(url) {
|
|
@@ -557,9 +484,9 @@
|
|
|
557
484
|
const missingAssetUrl = normalizeImageAssetUrl(metadata?.MissingAssetUrl || '');
|
|
558
485
|
const responseFullResUrl = isImageContent && !isThumbnailImageUrl(responseUrl) ? responseUrl : '';
|
|
559
486
|
const missingFullResUrl = !isThumbnailImageUrl(missingAssetUrl) ? missingAssetUrl : '';
|
|
560
|
-
const
|
|
561
|
-
const mediaPreviewUrl =
|
|
562
|
-
const responsePreviewUrl = isImageContent && !
|
|
487
|
+
const animationCapable = isAnimationCapableImageModel(model);
|
|
488
|
+
const mediaPreviewUrl = animationCapable ? '' : (thumbnailUrl || snapshotUrl || previewImageUrl);
|
|
489
|
+
const responsePreviewUrl = isImageContent && !animationCapable ? responseUrl : '';
|
|
563
490
|
const previewUrl = mediaPreviewUrl || responsePreviewUrl || originalPath || originalUrl || missingAssetUrl;
|
|
564
491
|
const fullResUrl = isImageContent
|
|
565
492
|
? (originalUrl || originalPath || responseFullResUrl || missingFullResUrl)
|
|
@@ -575,7 +502,8 @@
|
|
|
575
502
|
missingAssetUrl,
|
|
576
503
|
previewUrl,
|
|
577
504
|
fullResUrl,
|
|
578
|
-
|
|
505
|
+
animationCapable,
|
|
506
|
+
animatedGif: animationCapable
|
|
579
507
|
};
|
|
580
508
|
}
|
|
581
509
|
|
|
@@ -818,6 +746,8 @@
|
|
|
818
746
|
this._imageAtlasLoadingIds = new Set();
|
|
819
747
|
this._imageAtlasActiveLoads = 0;
|
|
820
748
|
this._imageAtlasRetryAfter = new Map();
|
|
749
|
+
this._residentStaticPreviewUrls = new Map();
|
|
750
|
+
this._residentStaticPreviewEpoch = 0;
|
|
821
751
|
this._imageAtlasBatchPendingIds = new Set();
|
|
822
752
|
this._imageAtlasBatchReadyIds = new Set();
|
|
823
753
|
this._imageAtlasBatchActive = false;
|
|
@@ -1115,6 +1045,7 @@
|
|
|
1115
1045
|
if (this._isNodeArrayDirty || this._cachedNodeArray.length !== nodeObjectsById.size) {
|
|
1116
1046
|
this._cachedNodeArray = Array.from(nodeObjectsById.values());
|
|
1117
1047
|
this._isNodeArrayDirty = false;
|
|
1048
|
+
window.MindMapRenderPlan?.prepareImageAtlasForEntries?.(this, this._cachedNodeArray);
|
|
1118
1049
|
}
|
|
1119
1050
|
}
|
|
1120
1051
|
// ▲▲▲ [Optimization] ▲▲▲
|
|
@@ -1379,14 +1310,19 @@
|
|
|
1379
1310
|
return;
|
|
1380
1311
|
}
|
|
1381
1312
|
|
|
1313
|
+
const residentPreviewUrl = this._getResidentStaticPreviewUrl(nodeId, entry.model, assetUrls);
|
|
1314
|
+
|
|
1382
1315
|
const cachedRecord = window.MindMapNodes?.imageCache?.get?.(nodeId) || null;
|
|
1383
|
-
const cachedImage =
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1316
|
+
const cachedImage = residentPreviewUrl
|
|
1317
|
+
? (window.MindMapTextureFactory?.resolveCachedImageEntry?.(cachedRecord, residentPreviewUrl, {
|
|
1318
|
+
preferOriginal: false,
|
|
1319
|
+
allowOriginalReuseForPreview: false,
|
|
1320
|
+
resizeWidth: IMAGE_ATLAS_PREVIEW_REQUEST_WIDTH,
|
|
1321
|
+
originalUrl: assetUrls.fullResUrl || assetUrls.originalUrl || ''
|
|
1322
|
+
}) || null)
|
|
1323
|
+
: null;
|
|
1388
1324
|
const cachedImageUrl = normalizeImageAssetUrl(cachedImage?.url || '');
|
|
1389
|
-
const requestedPreviewUrl = normalizeImageAssetUrl(
|
|
1325
|
+
const requestedPreviewUrl = normalizeImageAssetUrl(residentPreviewUrl);
|
|
1390
1326
|
const cachedRetryAfter = Number(cachedImage?.retryAfter || 0);
|
|
1391
1327
|
const cachedAssetUrl = cachedImageUrl || String(cachedImage?.assetKey || '');
|
|
1392
1328
|
if (
|
|
@@ -1403,11 +1339,28 @@
|
|
|
1403
1339
|
nodeId,
|
|
1404
1340
|
model: entry.model,
|
|
1405
1341
|
previewUrl: assetUrls.previewUrl,
|
|
1406
|
-
|
|
1342
|
+
thumbnailUrl: assetUrls.thumbnailUrl || '',
|
|
1343
|
+
originalUrl: assetUrls.fullResUrl || assetUrls.originalUrl || '',
|
|
1344
|
+
previewEpoch: this._residentStaticPreviewEpoch
|
|
1407
1345
|
});
|
|
1408
1346
|
this._pumpImageAtlasPreviewLoadQueue();
|
|
1409
1347
|
}
|
|
1410
1348
|
|
|
1349
|
+
_getResidentStaticPreviewUrl(nodeId, model, assetUrls = getImageModelAssetUrls(model)) {
|
|
1350
|
+
return window.MindMapAnimatedImagePreview?.getResidentStaticPreviewUrl?.(
|
|
1351
|
+
this, nodeId, model, assetUrls
|
|
1352
|
+
) || '';
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
async _resolveSafeResidentPreviewUrl(item) {
|
|
1356
|
+
const assetUrls = getImageModelAssetUrls(item?.model);
|
|
1357
|
+
const resolver = window.MindMapAnimatedImagePreview?.resolveSafeResidentPreviewUrl;
|
|
1358
|
+
return typeof resolver === 'function'
|
|
1359
|
+
? await resolver(this, item, assetUrls, getImageModelAssetUrls, details =>
|
|
1360
|
+
emitMindCanvasTrace('lod.image.staticPreview.ready', this._module, details))
|
|
1361
|
+
: '';
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1411
1364
|
_pumpImageAtlasPreviewLoadQueue() {
|
|
1412
1365
|
const textureFactory = window.MindMapTextureFactory;
|
|
1413
1366
|
const imageCache = window.MindMapNodes?.imageCache;
|
|
@@ -1440,8 +1393,13 @@
|
|
|
1440
1393
|
this._imageAtlasLoadingIds.add(item.nodeId);
|
|
1441
1394
|
let didLoadImage = false;
|
|
1442
1395
|
|
|
1443
|
-
Promise.resolve(
|
|
1444
|
-
|
|
1396
|
+
Promise.resolve(this._resolveSafeResidentPreviewUrl(item)).then((resolvedPreviewUrl) => {
|
|
1397
|
+
item.resolvedPreviewUrl = resolvedPreviewUrl;
|
|
1398
|
+
if (!resolvedPreviewUrl) {
|
|
1399
|
+
return null;
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
return textureFactory.ensureImageCached(item.nodeId, resolvedPreviewUrl, imageCache, {
|
|
1445
1403
|
authToken: this._module?.authToken || '',
|
|
1446
1404
|
resizeWidth: IMAGE_ATLAS_PREVIEW_REQUEST_WIDTH,
|
|
1447
1405
|
preferOriginal: false,
|
|
@@ -1463,12 +1421,18 @@
|
|
|
1463
1421
|
setImageModelPreviewUrl(item.model, normalized);
|
|
1464
1422
|
}
|
|
1465
1423
|
}
|
|
1466
|
-
})
|
|
1467
|
-
).then((cachedImage) => {
|
|
1424
|
+
});
|
|
1425
|
+
}).then((cachedImage) => {
|
|
1468
1426
|
didLoadImage = !!(cachedImage?.image) && cachedImage?.isError !== true;
|
|
1469
1427
|
item.cachedImage = cachedImage || null;
|
|
1470
|
-
}).catch(() => {
|
|
1428
|
+
}).catch((error) => {
|
|
1471
1429
|
didLoadImage = false;
|
|
1430
|
+
if (isWebpImageModel(item?.model)) {
|
|
1431
|
+
emitMindCanvasTrace('lod.image.staticPreview.failed', this._module, {
|
|
1432
|
+
nodeId: item.nodeId,
|
|
1433
|
+
reason: String(error?.message || error || 'unknown')
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1472
1436
|
}).finally(() => {
|
|
1473
1437
|
this._imageAtlasActiveLoads = Math.max(0, this._imageAtlasActiveLoads - 1);
|
|
1474
1438
|
this._imageAtlasQueuedIds.delete(item.nodeId);
|
|
@@ -1511,14 +1475,22 @@
|
|
|
1511
1475
|
_getImageLodSource(entry) {
|
|
1512
1476
|
const nodeId = String(entry?.model?.id || '').trim();
|
|
1513
1477
|
const assetUrls = getImageModelAssetUrls(entry?.model);
|
|
1478
|
+
const webpModel = isWebpImageModel(entry?.model);
|
|
1479
|
+
const residentPreviewUrl = this._getResidentStaticPreviewUrl(nodeId, entry?.model, assetUrls);
|
|
1480
|
+
if (webpModel && !residentPreviewUrl) {
|
|
1481
|
+
this._queueImageAtlasPreviewLoad(entry);
|
|
1482
|
+
return null;
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1514
1485
|
const cachedRecord = nodeId ? window.MindMapNodes?.imageCache?.get?.(nodeId) || null : null;
|
|
1515
1486
|
const cachedImage = nodeId
|
|
1516
1487
|
? (
|
|
1517
|
-
window.MindMapTextureFactory?.resolveCachedImageEntry?.(cachedRecord,
|
|
1488
|
+
window.MindMapTextureFactory?.resolveCachedImageEntry?.(cachedRecord, residentPreviewUrl, {
|
|
1518
1489
|
preferOriginal: false,
|
|
1519
1490
|
allowOriginalReuseForPreview: false,
|
|
1491
|
+
resizeWidth: IMAGE_ATLAS_PREVIEW_REQUEST_WIDTH,
|
|
1520
1492
|
originalUrl: assetUrls.fullResUrl || assetUrls.originalUrl || ''
|
|
1521
|
-
}) ||
|
|
1493
|
+
}) || null
|
|
1522
1494
|
)
|
|
1523
1495
|
: null;
|
|
1524
1496
|
const cachedSource = cachedImage?.image || null;
|
|
@@ -1540,6 +1512,13 @@
|
|
|
1540
1512
|
};
|
|
1541
1513
|
}
|
|
1542
1514
|
|
|
1515
|
+
if (isThumbnailImageUrl(residentPreviewUrl)) {
|
|
1516
|
+
if (!isCachedImageRetryPending) {
|
|
1517
|
+
this._queueImageAtlasPreviewLoad(entry);
|
|
1518
|
+
}
|
|
1519
|
+
return null;
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1543
1522
|
const cssImage = entry?.cssObject?.element?.querySelector?.('img') || null;
|
|
1544
1523
|
const cssImageWidth = Number(cssImage?.naturalWidth || cssImage?.width || 0);
|
|
1545
1524
|
const cssImageHeight = Number(cssImage?.naturalHeight || cssImage?.height || 0);
|
|
@@ -1640,8 +1619,6 @@
|
|
|
1640
1619
|
sy = (source.height - sh) * 0.5;
|
|
1641
1620
|
}
|
|
1642
1621
|
|
|
1643
|
-
// Match NEAR image nodes: CSS/WebGL both use object-fit: cover
|
|
1644
|
-
// against the node rectangle, then map that result over the quad.
|
|
1645
1622
|
scratchCtx.drawImage(source.image, sx, sy, sw, sh, 0, 0, size, size);
|
|
1646
1623
|
scratchCtx.restore();
|
|
1647
1624
|
|
|
@@ -1652,9 +1629,8 @@
|
|
|
1652
1629
|
ctx.fillStyle = '#eef2f7';
|
|
1653
1630
|
ctx.fillRect(x, y, size, size);
|
|
1654
1631
|
ctx.drawImage(scratch, 0, 0, size, size, x, y, size, size);
|
|
1655
|
-
if (this
|
|
1656
|
-
this.
|
|
1657
|
-
}
|
|
1632
|
+
if (!window.MindMapRenderPlan?.uploadImageAtlasTile?.(this, slot, scratch))
|
|
1633
|
+
window.MindMapRenderPlan?.scheduleImageAtlasUpload?.(this, this._module);
|
|
1658
1634
|
return true;
|
|
1659
1635
|
} catch {
|
|
1660
1636
|
try { scratchCtx.restore(); } catch { }
|
|
@@ -3417,7 +3393,7 @@
|
|
|
3417
3393
|
const pendingAnimatedGifCssFallbacks = usesAnimatedGifCssFallbacks && activeImageCssFallbackCount <= 0;
|
|
3418
3394
|
const staleImageCssFallbacks = imageCssFallbackCount > 0 &&
|
|
3419
3395
|
(usesAnyImageCssFallbacks !== true || activeImageCssFallbackCount <= 0);
|
|
3420
|
-
const lineDetailRestorePending =
|
|
3396
|
+
const lineDetailRestorePending = window.MindMapRenderPlan?.hasActionableResidentLineDetails?.(this, module, lodBand) === true;
|
|
3421
3397
|
const dirty = (
|
|
3422
3398
|
this._instancesDirty === true ||
|
|
3423
3399
|
this._imageInstancesDirty === true ||
|
|
@@ -5878,9 +5854,7 @@
|
|
|
5878
5854
|
if (this.isInLODMode === true &&
|
|
5879
5855
|
this._instancesDirty &&
|
|
5880
5856
|
this._shouldDeferResidentInstanceRebuild(module, lodBand)) {
|
|
5881
|
-
|
|
5882
|
-
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), 12);
|
|
5883
|
-
}
|
|
5857
|
+
this._keepResidentLodSettleFrames(module, 2, 'defer-resident-instance-rebuild');
|
|
5884
5858
|
if (LOD_PERF_DEBUG) {
|
|
5885
5859
|
_prof('done');
|
|
5886
5860
|
}
|
|
@@ -5896,9 +5870,7 @@
|
|
|
5896
5870
|
if (this.isInLODMode === true &&
|
|
5897
5871
|
this._lodCleanupPending === true &&
|
|
5898
5872
|
this._isResidentLodInteractionActive(module)) {
|
|
5899
|
-
|
|
5900
|
-
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), 12);
|
|
5901
|
-
}
|
|
5873
|
+
this._keepResidentLodSettleFrames(module, 2, 'defer-lod-cleanup');
|
|
5902
5874
|
if (LOD_PERF_DEBUG) {
|
|
5903
5875
|
_prof('done');
|
|
5904
5876
|
}
|
|
@@ -6174,9 +6146,7 @@
|
|
|
6174
6146
|
// ▼▼▼ [Perf] Only update instance data when dirty or node count changed ▼▼▼
|
|
6175
6147
|
// Check if node count changed (add/remove detection)
|
|
6176
6148
|
if (this._instancesDirty && this._shouldDeferResidentInstanceRebuild(module, lodBand)) {
|
|
6177
|
-
|
|
6178
|
-
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), 12);
|
|
6179
|
-
}
|
|
6149
|
+
this._keepResidentLodSettleFrames(module, 2, 'defer-resident-instance-rebuild');
|
|
6180
6150
|
if (LOD_PERF_DEBUG) {
|
|
6181
6151
|
_prof('done');
|
|
6182
6152
|
}
|
|
@@ -6388,9 +6358,7 @@
|
|
|
6388
6358
|
Number(this._residentRebuildDeferredUntil || 0),
|
|
6389
6359
|
now + LOD_RESIDENT_REBUILD_SETTLE_MS
|
|
6390
6360
|
);
|
|
6391
|
-
|
|
6392
|
-
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), 4);
|
|
6393
|
-
}
|
|
6361
|
+
this._keepResidentLodSettleFrames(module, 2, 'defer-resident-full-rebuild');
|
|
6394
6362
|
}
|
|
6395
6363
|
|
|
6396
6364
|
if (this._instancesDirty && residentFullBuildBlockedThisFrame !== true) {
|
|
@@ -7119,13 +7087,8 @@
|
|
|
7119
7087
|
}, safeDelayMs);
|
|
7120
7088
|
}
|
|
7121
7089
|
|
|
7122
|
-
_keepResidentLodSettleFrames(module = this._module,
|
|
7090
|
+
_keepResidentLodSettleFrames(module = this._module, _frames = 12, reason = 'resident-settle') {
|
|
7123
7091
|
if (module) {
|
|
7124
|
-
if (this._isResidentLodInteractionActive(module)) {
|
|
7125
|
-
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), frames);
|
|
7126
|
-
return;
|
|
7127
|
-
}
|
|
7128
|
-
|
|
7129
7092
|
this._scheduleResidentLodWake(reason, LOD_RESIDENT_REBUILD_SETTLE_MS);
|
|
7130
7093
|
}
|
|
7131
7094
|
}
|
|
@@ -9504,6 +9467,7 @@
|
|
|
9504
9467
|
clearTimeout(this._residentLodWakeTimer);
|
|
9505
9468
|
this._residentLodWakeTimer = 0;
|
|
9506
9469
|
}
|
|
9470
|
+
window.MindMapRenderPlan?.clearScheduledImageAtlasUpload?.(this);
|
|
9507
9471
|
this._residentLodWakeReason = '';
|
|
9508
9472
|
this.isInLODMode = null;
|
|
9509
9473
|
|
|
@@ -9550,6 +9514,8 @@
|
|
|
9550
9514
|
this._imageAtlasLoadingIds.clear();
|
|
9551
9515
|
this._imageAtlasActiveLoads = 0;
|
|
9552
9516
|
this._imageAtlasRetryAfter.clear();
|
|
9517
|
+
this._residentStaticPreviewUrls.clear();
|
|
9518
|
+
this._residentStaticPreviewEpoch++;
|
|
9553
9519
|
this._resetImageAtlasBatchState();
|
|
9554
9520
|
this._imageAtlasRebuildPending = false;
|
|
9555
9521
|
this._imageAtlasRebuildDeferredUntil = 0;
|
|
@@ -9669,6 +9635,7 @@
|
|
|
9669
9635
|
this._nearPriorityRecordById?.delete?.(nodeId);
|
|
9670
9636
|
this._lodConsoleProxyNodeIds?.delete?.(nodeId);
|
|
9671
9637
|
this._lodImageCssFallbackNodeIds.delete(nodeId);
|
|
9638
|
+
this._residentStaticPreviewUrls.delete(nodeId);
|
|
9672
9639
|
this._lodTemplateCssNodeIds?.delete?.(nodeId);
|
|
9673
9640
|
this._fullResCssFringePreparedIds?.delete?.(nodeId);
|
|
9674
9641
|
removedAny = true;
|
|
@@ -10253,6 +10220,8 @@
|
|
|
10253
10220
|
this._imageAtlasLoadingIds.clear();
|
|
10254
10221
|
this._imageAtlasActiveLoads = 0;
|
|
10255
10222
|
this._imageAtlasRetryAfter.clear();
|
|
10223
|
+
this._residentStaticPreviewUrls.clear();
|
|
10224
|
+
this._residentStaticPreviewEpoch++;
|
|
10256
10225
|
this._pendingSelectionRefreshIds.clear();
|
|
10257
10226
|
if (this._idleRebuildTimer) {
|
|
10258
10227
|
clearTimeout(this._idleRebuildTimer);
|
|
@@ -10262,6 +10231,7 @@
|
|
|
10262
10231
|
clearTimeout(this._residentLodWakeTimer);
|
|
10263
10232
|
this._residentLodWakeTimer = 0;
|
|
10264
10233
|
}
|
|
10234
|
+
window.MindMapRenderPlan?.clearScheduledImageAtlasUpload?.(this);
|
|
10265
10235
|
this._resetImageAtlasBatchState();
|
|
10266
10236
|
this.thumbnailMap.clear();
|
|
10267
10237
|
this.pendingNodes.clear();
|
|
@@ -1061,27 +1061,31 @@
|
|
|
1061
1061
|
}
|
|
1062
1062
|
|
|
1063
1063
|
// ▼▼▼ [New] Screen-space position using worldToScreen ▼▼▼
|
|
1064
|
-
function worldToScreen(worldX, worldY, camera, container) {
|
|
1065
|
-
const THREE = globalThis.THREE;
|
|
1066
|
-
const vector = new THREE.Vector3(worldX, worldY, 0);
|
|
1067
|
-
vector.project(camera);
|
|
1068
|
-
|
|
1069
|
-
const
|
|
1070
|
-
const
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1064
|
+
function worldToScreen(worldX, worldY, camera, container) {
|
|
1065
|
+
const THREE = globalThis.THREE;
|
|
1066
|
+
const vector = new THREE.Vector3(worldX, worldY, 0);
|
|
1067
|
+
vector.project(camera);
|
|
1068
|
+
|
|
1069
|
+
const viewportWidth = Number(_module?._lastViewportWidth || _module?._lastContainerWidth || container.clientWidth || 1);
|
|
1070
|
+
const viewportHeight = Number(_module?._lastViewportHeight || _module?._lastContainerHeight || container.clientHeight || 1);
|
|
1071
|
+
const viewportLeft = Number(_module?._lastViewportLeft || 0);
|
|
1072
|
+
const viewportTop = Number(_module?._lastViewportTop || 0);
|
|
1073
|
+
const halfWidth = viewportWidth / 2;
|
|
1074
|
+
const halfHeight = viewportHeight / 2;
|
|
1075
|
+
|
|
1076
|
+
return {
|
|
1077
|
+
x: viewportLeft + (vector.x * halfWidth) + halfWidth,
|
|
1078
|
+
y: viewportTop - (vector.y * halfHeight) + halfHeight
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
function updateMenuScreenPosition(menuEl, nodeEntry, cameraMotionOnly = false) {
|
|
1079
1083
|
if (!menuEl || !nodeEntry || !_module || !_module.camera || !_module.container) return;
|
|
1080
1084
|
|
|
1081
1085
|
const templateNode = document.getElementById(`node-${nodeEntry.model?.id || currentMenuNodeId}`);
|
|
1082
1086
|
let anchorX = null;
|
|
1083
1087
|
let anchorY = null;
|
|
1084
|
-
const shouldPreferProjectedAnchor =
|
|
1088
|
+
const shouldPreferProjectedAnchor = cameraMotionOnly === true ||
|
|
1085
1089
|
_module.isZooming === true ||
|
|
1086
1090
|
_module.isPanning === true ||
|
|
1087
1091
|
_module.isDraggingNode === true ||
|
|
@@ -1116,8 +1120,15 @@
|
|
|
1116
1120
|
anchorY = screenPos.y;
|
|
1117
1121
|
}
|
|
1118
1122
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1123
|
+
let halfMenuWidth = Number(menuEl._mindMapHalfWidth || 0);
|
|
1124
|
+
let menuHeight = Number(menuEl._mindMapHeight || 0);
|
|
1125
|
+
if (cameraMotionOnly !== true || halfMenuWidth <= 0 || menuHeight <= 0) {
|
|
1126
|
+
const menuRect = menuEl.getBoundingClientRect();
|
|
1127
|
+
halfMenuWidth = menuRect.width > 0 ? menuRect.width / 2 : 0;
|
|
1128
|
+
menuHeight = menuRect.height || 0;
|
|
1129
|
+
menuEl._mindMapHalfWidth = halfMenuWidth;
|
|
1130
|
+
menuEl._mindMapHeight = menuHeight;
|
|
1131
|
+
}
|
|
1121
1132
|
const viewportMargin = 10;
|
|
1122
1133
|
const verticalGap = 14;
|
|
1123
1134
|
|
|
@@ -1126,7 +1137,7 @@
|
|
|
1126
1137
|
Math.max(viewportMargin + halfMenuWidth, anchorX)
|
|
1127
1138
|
);
|
|
1128
1139
|
const anchoredTop = anchorY - verticalGap;
|
|
1129
|
-
const minTop = viewportMargin +
|
|
1140
|
+
const minTop = viewportMargin + menuHeight;
|
|
1130
1141
|
const clampedTop = Math.max(minTop, anchoredTop);
|
|
1131
1142
|
|
|
1132
1143
|
menuEl.style.left = `${clampedLeft}px`;
|
|
@@ -1134,7 +1145,7 @@
|
|
|
1134
1145
|
}
|
|
1135
1146
|
// ▲▲▲ [New] ▲▲▲
|
|
1136
1147
|
|
|
1137
|
-
function update() {
|
|
1148
|
+
function update() {
|
|
1138
1149
|
if (currentMenuElement && currentMenuNodeId && _module) {
|
|
1139
1150
|
const nodeEntry = _module.nodeObjectsById.get(currentMenuNodeId);
|
|
1140
1151
|
if (nodeEntry) {
|
|
@@ -1543,8 +1554,19 @@
|
|
|
1543
1554
|
});
|
|
1544
1555
|
}
|
|
1545
1556
|
}
|
|
1557
|
+
|
|
1558
|
+
function updateForCameraMotion() {
|
|
1559
|
+
if (!currentMenuElement || !currentMenuNodeId || !_module) return false;
|
|
1560
|
+
const nodeEntry = _module.nodeObjectsById.get(currentMenuNodeId);
|
|
1561
|
+
if (!nodeEntry) {
|
|
1562
|
+
hideMenu();
|
|
1563
|
+
return false;
|
|
1564
|
+
}
|
|
1565
|
+
updateMenuScreenPosition(currentMenuElement, nodeEntry, true);
|
|
1566
|
+
return true;
|
|
1567
|
+
}
|
|
1546
1568
|
|
|
1547
|
-
window.MindMapMenuManager = { init, showMenu, hideMenu, update };
|
|
1569
|
+
window.MindMapMenuManager = { init, showMenu, hideMenu, update, updateForCameraMotion };
|
|
1548
1570
|
|
|
1549
1571
|
console.log('✅ mind-map-menu-manager.js loaded');
|
|
1550
1572
|
})();
|
|
@@ -1412,10 +1412,11 @@
|
|
|
1412
1412
|
return normalizeImageAssetUrl(url).toLowerCase().includes('/assets/thumbs/');
|
|
1413
1413
|
}
|
|
1414
1414
|
|
|
1415
|
-
function
|
|
1415
|
+
function isAnimationCapableImageUrl(url) {
|
|
1416
1416
|
const normalized = normalizeImageAssetUrl(url);
|
|
1417
1417
|
if (!normalized) return false;
|
|
1418
|
-
|
|
1418
|
+
const pathname = normalized.split(/[?#]/)[0].toLowerCase();
|
|
1419
|
+
return pathname.endsWith('.gif') || pathname.endsWith('.webp');
|
|
1419
1420
|
}
|
|
1420
1421
|
|
|
1421
1422
|
function getMetadataValueCaseInsensitive(metadata, ...keys) {
|
|
@@ -1441,6 +1442,34 @@
|
|
|
1441
1442
|
return '';
|
|
1442
1443
|
}
|
|
1443
1444
|
|
|
1445
|
+
function isAnimationCapableImageNodeModel(nodeModel) {
|
|
1446
|
+
if (!nodeModel || getNodeContentTypeLower(nodeModel) !== 'image') {
|
|
1447
|
+
return false;
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
const metadata = getNodeMetadata(nodeModel) || {};
|
|
1451
|
+
const mimeType = getMetadataValueCaseInsensitive(
|
|
1452
|
+
metadata,
|
|
1453
|
+
'fileMime',
|
|
1454
|
+
'FileMime',
|
|
1455
|
+
'mimeType',
|
|
1456
|
+
'MimeType'
|
|
1457
|
+
).toLowerCase();
|
|
1458
|
+
if (mimeType === 'image/gif' || mimeType === 'image/webp') {
|
|
1459
|
+
return true;
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
return [
|
|
1463
|
+
nodeModel?.response,
|
|
1464
|
+
nodeModel?.Response,
|
|
1465
|
+
metadata?.OriginalPath,
|
|
1466
|
+
metadata?.OriginalUrl,
|
|
1467
|
+
metadata?.originalUrl,
|
|
1468
|
+
metadata?.ImageUrl,
|
|
1469
|
+
metadata?.imageUrl
|
|
1470
|
+
].some(isAnimationCapableImageUrl);
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1444
1473
|
function isAnimatedGifImageNodeModel(nodeModel) {
|
|
1445
1474
|
if (!nodeModel || getNodeContentTypeLower(nodeModel) !== 'image') {
|
|
1446
1475
|
return false;
|
|
@@ -1466,7 +1495,7 @@
|
|
|
1466
1495
|
metadata?.originalUrl,
|
|
1467
1496
|
metadata?.ImageUrl,
|
|
1468
1497
|
metadata?.imageUrl
|
|
1469
|
-
].some(
|
|
1498
|
+
].some(url => normalizeImageAssetUrl(url).split(/[?#]/)[0].toLowerCase().endsWith('.gif'));
|
|
1470
1499
|
}
|
|
1471
1500
|
|
|
1472
1501
|
function getAnimatedGifOriginalReference(nodeModel, fallback = '') {
|
|
@@ -1683,9 +1712,9 @@
|
|
|
1683
1712
|
const metadata = ensureNodeMetadataObject(nodeModel);
|
|
1684
1713
|
const normalizedContent = normalizeImageAssetUrl(nextContent);
|
|
1685
1714
|
const thumbnailUrl = normalizeImageAssetUrl(metadata?.ThumbnailUrl || metadata?.thumbnailUrl || '');
|
|
1686
|
-
const
|
|
1715
|
+
const isAnimatedImage = isAnimationCapableImageNodeModel(nodeModel);
|
|
1687
1716
|
|
|
1688
|
-
if (
|
|
1717
|
+
if (isAnimatedImage) {
|
|
1689
1718
|
const originalReference = getAnimatedGifOriginalReference(nodeModel, normalizedContent);
|
|
1690
1719
|
if (originalReference) {
|
|
1691
1720
|
setNodeImageOriginalReference(nodeModel, originalReference);
|
|
@@ -1697,7 +1726,7 @@
|
|
|
1697
1726
|
setNodeImageOriginalReference(nodeModel, normalizedContent);
|
|
1698
1727
|
}
|
|
1699
1728
|
|
|
1700
|
-
if (thumbnailUrl && !
|
|
1729
|
+
if (thumbnailUrl && !isAnimatedImage) {
|
|
1701
1730
|
setNodeImagePreviewUrl(nodeModel, thumbnailUrl);
|
|
1702
1731
|
return normalizeImageAssetUrl(nodeModel.response ?? nodeModel.Response ?? '');
|
|
1703
1732
|
}
|
|
@@ -1824,15 +1853,15 @@
|
|
|
1824
1853
|
''
|
|
1825
1854
|
);
|
|
1826
1855
|
const missingAssetUrl = normalizeImageAssetUrl(metadata?.MissingAssetUrl || '');
|
|
1827
|
-
const
|
|
1856
|
+
const isAnimatedImage = isAnimationCapableImageNodeModel(nodeModel);
|
|
1828
1857
|
const responseFullResUrl = isImageContent && canUseAsFullResImageUrl(responseUrl) ? responseUrl : '';
|
|
1829
1858
|
const missingFullResUrl = canUseAsFullResImageUrl(missingAssetUrl) ? missingAssetUrl : '';
|
|
1830
|
-
const mediaPreviewUrl =
|
|
1831
|
-
const responsePreviewUrl = isImageContent && !
|
|
1859
|
+
const mediaPreviewUrl = isAnimatedImage ? '' : (thumbnailUrl || snapshotUrl || previewImageUrl);
|
|
1860
|
+
const responsePreviewUrl = isImageContent && !isAnimatedImage ? responseUrl : '';
|
|
1832
1861
|
const fullResUrl = isImageContent
|
|
1833
1862
|
? (originalUrl || originalPath || responseFullResUrl || missingFullResUrl)
|
|
1834
1863
|
: (originalUrl || originalPath || snapshotUrl || previewImageUrl || thumbnailUrl || missingFullResUrl);
|
|
1835
|
-
const previewUrl =
|
|
1864
|
+
const previewUrl = isAnimatedImage
|
|
1836
1865
|
? (fullResUrl || responseUrl || originalPath || originalUrl || missingAssetUrl)
|
|
1837
1866
|
: (mediaPreviewUrl || responsePreviewUrl || originalPath || originalUrl || missingAssetUrl);
|
|
1838
1867
|
|
|
@@ -1846,13 +1875,14 @@
|
|
|
1846
1875
|
missingAssetUrl,
|
|
1847
1876
|
previewUrl,
|
|
1848
1877
|
fullResUrl,
|
|
1849
|
-
|
|
1878
|
+
animationCapable: isAnimatedImage,
|
|
1879
|
+
animatedGif: isAnimatedImage
|
|
1850
1880
|
};
|
|
1851
1881
|
}
|
|
1852
1882
|
|
|
1853
1883
|
function hasNodeImagePreviewSource(assetUrls) {
|
|
1854
1884
|
if (!assetUrls || typeof assetUrls !== 'object') return false;
|
|
1855
|
-
if (assetUrls.animatedGif === true) return false;
|
|
1885
|
+
if (assetUrls.animationCapable === true || assetUrls.animatedGif === true) return false;
|
|
1856
1886
|
return !!(
|
|
1857
1887
|
assetUrls.thumbnailUrl ||
|
|
1858
1888
|
(assetUrls.responseUrl && isThumbnailImageUrl(assetUrls.responseUrl))
|
|
@@ -1879,7 +1909,7 @@
|
|
|
1879
1909
|
if (!assetUrls.previewUrl) {
|
|
1880
1910
|
return;
|
|
1881
1911
|
}
|
|
1882
|
-
if (assetUrls.animatedGif === true) {
|
|
1912
|
+
if (assetUrls.animationCapable === true || assetUrls.animatedGif === true) {
|
|
1883
1913
|
return;
|
|
1884
1914
|
}
|
|
1885
1915
|
|
|
@@ -4570,6 +4600,7 @@
|
|
|
4570
4600
|
bringNodeToFront: bringNodeToFront,
|
|
4571
4601
|
updateNodeSelectionStyle: updateNodeSelectionStyle,
|
|
4572
4602
|
applySingleSelection: applySingleSelection,
|
|
4603
|
+
moveCursorAfterNodePlacement: moveCursorAfterNodePlacement,
|
|
4573
4604
|
resetState: resetState,
|
|
4574
4605
|
captureDeleteSnapshot: captureDeleteSnapshot,
|
|
4575
4606
|
// ▼▼▼ [New] Expose helper function for external callers ▼▼▼
|
|
@@ -4580,6 +4611,7 @@
|
|
|
4580
4611
|
updateAnimatedImageStatusTextures: updateAnimatedImageStatusTextures,
|
|
4581
4612
|
applyCanonicalNodeResponse: applyCanonicalNodeResponse,
|
|
4582
4613
|
isGeneratedImageNodeModel: isGeneratedImageNodeModel,
|
|
4614
|
+
isAnimationCapableImageNodeModel: isAnimationCapableImageNodeModel,
|
|
4583
4615
|
isAnimatedGifImageNodeModel: isAnimatedGifImageNodeModel,
|
|
4584
4616
|
getNodeImageAssetUrls: getNodeImageAssetUrls,
|
|
4585
4617
|
setNodeImageOriginalUrl: setNodeImageOriginalUrl,
|