@mindexec/cli 0.2.478 → 0.2.480
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 +323 -323
- package/codex-model-catalog.js +202 -202
- package/codex-runtime.js +1608 -1608
- package/desktop-workspace-state.cjs +120 -120
- package/electron/main.cjs +517 -517
- package/electron/preload.cjs +17 -17
- package/electron/recurring-update-owner-smoke.mjs +55 -55
- package/electron/recurring-update-owner.cjs +97 -97
- package/electron/source-smoke.mjs +108 -108
- package/electron/update-feed-resolver.cjs +79 -79
- package/electron/update-feed.json +10 -10
- package/electron/update-manager-smoke.mjs +146 -146
- package/electron/update-manager.cjs +297 -297
- package/electron/windows-package-smoke.mjs +156 -156
- package/launch-bridge.cjs +236 -236
- package/lzo1x.js +110 -110
- package/mode4-atlas-worker.js +440 -440
- package/mode4-atlas.js +130 -130
- package/package.json +1 -1
- package/port-guard.cjs +285 -285
- package/remote-fast/osx-arm64/MacScreenCaptureKitH264.swift +339 -339
- package/remote-fast/osx-arm64/MacSystemAudioCapture.swift +214 -214
- package/remote-fast/osx-arm64/UnixRawCaptureHelper.mjs +80 -80
- package/remote-fast/osx-arm64/livedesk-raw-capture-resampler.mjs +73 -73
- package/remote-fast/osx-arm64/mindexec-remote-fast.dll +0 -0
- package/remote-fast/osx-x64/MacScreenCaptureKitH264.swift +339 -339
- package/remote-fast/osx-x64/MacSystemAudioCapture.swift +214 -214
- package/remote-fast/osx-x64/UnixRawCaptureHelper.mjs +80 -80
- package/remote-fast/osx-x64/livedesk-raw-capture-resampler.mjs +73 -73
- package/remote-fast/osx-x64/mindexec-remote-fast.dll +0 -0
- package/remote-fast/win-x64/mindexec-remote-fast.dll +0 -0
- package/remote-hub.js +3698 -3698
- package/scripts/auth-session-smoke.mjs +262 -262
- package/scripts/board-render-ownership-smoke.mjs +85 -85
- package/scripts/codex-model-catalog-smoke.mjs +150 -150
- package/scripts/codex-runtime-home-smoke.mjs +58 -58
- package/scripts/codex-sdk-image-live-smoke.mjs +43 -43
- package/scripts/codex-sdk-image-runtime-smoke.mjs +122 -122
- package/scripts/codex-sdk-runtime-smoke.mjs +89 -89
- package/scripts/desktop-update-publisher-smoke.mjs +89 -89
- package/scripts/desktop-update-worker-smoke.mjs +72 -72
- package/scripts/desktop-workspace-state-smoke.mjs +81 -81
- package/scripts/drive-installed-update-smoke.mjs +67 -67
- package/scripts/npm-fresh-install-smoke.mjs +216 -216
- package/scripts/publish-mindexec-desktop-updates.mjs +224 -224
- package/scripts/remote-agent-managed-smoke.mjs +318 -318
- package/scripts/remote-agent-package-smoke.mjs +64 -64
- package/scripts/remote-agent-ws-smoke.mjs +269 -269
- package/scripts/remote-fast-live-rate-smoke.mjs +343 -343
- package/scripts/remote-fast-mdm-browser-smoke.mjs +453 -453
- package/scripts/remote-fleet-render-smoke.mjs +1350 -1350
- package/scripts/remote-frame-ws-smoke.mjs +234 -234
- package/scripts/remote-http-smoke.mjs +592 -592
- package/scripts/remote-hub-identity-smoke.mjs +146 -146
- package/scripts/remote-hub-scale-smoke.mjs +124 -124
- package/scripts/remote-hub-smoke.mjs +699 -699
- package/scripts/remote-input-ws-smoke.mjs +263 -263
- package/scripts/remote-registry-follower-smoke.mjs +815 -815
- package/scripts/setup-tree-sitter-grammars.mjs +59 -59
- package/server.js +7510 -7510
- package/start-bridge.bat +32 -32
- package/start-bridge.sh +81 -81
- package/tree-sitter-grammars/README.md +18 -0
- package/tree-sitter-grammars/tree-sitter-c_sharp.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-go.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-java.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-javascript.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-python.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-rust.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-tsx.wasm +0 -0
- package/tree-sitter-grammars/tree-sitter-typescript.wasm +0 -0
- package/wwwroot/_content/MindExecution.Plugins.Admin/css/admin-dashboard.css +546 -546
- package/wwwroot/_content/MindExecution.Plugins.Directory/background.png +0 -0
- package/wwwroot/_content/MindExecution.Plugins.YouTube/css/youtube-search.css +251 -251
- package/wwwroot/_content/MindExecution.Shared/css/mind-map-overrides.css +3789 -3789
- package/wwwroot/_content/MindExecution.Shared/fonts/NotoSansKR-Bold.ttf +0 -0
- package/wwwroot/_content/MindExecution.Shared/fonts/NotoSansKR-Regular.ttf +0 -0
- package/wwwroot/_content/MindExecution.Shared/js/agent-visualization.js +27 -27
- package/wwwroot/_content/MindExecution.Shared/js/background-themes.js +1449 -1449
- package/wwwroot/_content/MindExecution.Shared/js/code-master.js +8316 -8316
- package/wwwroot/_content/MindExecution.Shared/js/file-system-helper.js +338 -338
- package/wwwroot/_content/MindExecution.Shared/js/marked.min.js +69 -69
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-animated-image-preview.js +270 -270
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-automation-edge-motion.js +170 -170
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-board-render-ownership.js +81 -81
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js +10528 -10506
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js.backup +1059 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-hotpath.js +902 -902
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +24637 -24637
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-dev-guards.js +325 -325
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js +1491 -1491
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js.bak +434 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-glow-shader.js +70 -70
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-image-policy.js +218 -218
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +7081 -7087
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-plan-worker.js +160 -160
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-renderer.js +9960 -9958
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-video-placeholder.js +107 -107
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-logic-workers.js +1004 -1004
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-menu-manager.js +1351 -1351
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-multi-select.js +865 -865
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-node-search-worker.js +554 -554
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-nodes.js +4771 -4744
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-normal-boundary-optimizer.js +624 -624
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-object-manager.js +241 -241
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-object-manager.js.backup +372 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-pipeline.js +2290 -2290
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-remote-codecs.js +202 -202
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-render-plan.js +1971 -1971
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-text-lod-system.js +93 -93
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js +2391 -2391
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js.backup +1258 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-video-playback-controls.js +95 -95
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-visibility-worker.js +895 -895
- package/wwwroot/_content/MindExecution.Shared/js/mindmap-toolbar.js +636 -636
- package/wwwroot/_content/MindExecution.Shared/js/native-drop-handler.js +45 -45
- package/wwwroot/_content/MindExecution.Shared/js/plan-master.js +117 -117
- package/wwwroot/_content/MindExecution.Shared/js/renderers/CSS3DRenderer.js +114 -114
- package/wwwroot/_content/MindExecution.Shared/js/texture-worker-manager.js +10 -10
- package/wwwroot/_content/MindExecution.Shared/js/three.min.js +6 -6
- package/wwwroot/_content/MindExecution.Shared/js/token-manager.js +7 -7
- package/wwwroot/_content/MindExecution.Shared/js/troika-bundle.js +6 -6
- package/wwwroot/_content/MindExecution.Shared/js/troika-bundle.js.map +2 -2
- package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/css/all.min.css +8 -8
- package/wwwroot/_content/MindExecution.Shared/models/vocab.txt +30522 -30522
- package/wwwroot/_framework/{Google.Protobuf.33g2gb5is0.dll → Google.Protobuf.9h59ukbel7.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Core.z100xo4mg0.dll → MindExecution.Core.gnj3fo0pr7.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Kernel.i9cldrx8yc.dll → MindExecution.Kernel.1qygzf8o02.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Admin.48lzqddb0a.dll → MindExecution.Plugins.Admin.n3uxh144wo.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Business.7m8u1q142p.dll → MindExecution.Plugins.Business.vl5dximn25.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Concept.cl5wmr53od.dll → MindExecution.Plugins.Concept.rutru9qeoi.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Directory.slipi39041.dll → MindExecution.Plugins.Directory.fqbmq85het.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.qfge05l671.dll → MindExecution.Plugins.PlanMaster.ko11cc9pll.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.YouTube.tn7v29ut77.dll → MindExecution.Plugins.YouTube.mt39q0to2j.dll} +0 -0
- package/wwwroot/_framework/MindExecution.Shared.umgls362or.dll +0 -0
- package/wwwroot/_framework/{MindExecution.Web.rwawrxxk38.dll → MindExecution.Web.1dwoarj2hg.dll} +0 -0
- package/wwwroot/_framework/{System.Collections.23yxgetbju.dll → System.Collections.zyvbaq6mpd.dll} +0 -0
- package/wwwroot/_framework/blazor.boot.json +25 -25
- package/wwwroot/_headers +40 -40
- package/wwwroot/_redirects +1 -1
- package/wwwroot/index.html +772 -772
- package/wwwroot/js/marketing-tool.js +180 -180
- package/wwwroot/manifest.webmanifest +23 -23
- package/wwwroot/service-worker-assets.js +109 -81
- package/wwwroot/service-worker.js +33 -33
- package/wwwroot/_framework/MindExecution.Shared.rjqlf0umjn.dll +0 -0
|
@@ -1,270 +1,270 @@
|
|
|
1
|
-
// Bounded resident previews for animation-capable image formats.
|
|
2
|
-
(function () {
|
|
3
|
-
'use strict';
|
|
4
|
-
|
|
5
|
-
function normalizeAssetUrl(url) {
|
|
6
|
-
if (typeof url !== 'string') return '';
|
|
7
|
-
return url.trim()
|
|
8
|
-
.replace(/^http:\/\/localhost(?=:\d+\/assets\/)/i, 'http://127.0.0.1')
|
|
9
|
-
.replace(/^http:\/\/\[::1\](?=:\d+\/assets\/)/i, 'http://127.0.0.1');
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function getContentType(model) {
|
|
13
|
-
return String(model?.contentType || model?.ContentType || '').trim().toLowerCase();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function getMetadata(model) {
|
|
17
|
-
return model?.metadata || model?.Metadata || {};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function getMetadataValue(metadata, ...keys) {
|
|
21
|
-
for (const key of keys) {
|
|
22
|
-
const direct = metadata?.[key];
|
|
23
|
-
if (direct !== undefined && direct !== null && String(direct).trim()) {
|
|
24
|
-
return String(direct).trim();
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const wanted = new Set(keys.map(key => String(key).toLowerCase()));
|
|
29
|
-
for (const [key, value] of Object.entries(metadata || {})) {
|
|
30
|
-
if (wanted.has(String(key).toLowerCase()) && value !== undefined && value !== null && String(value).trim()) {
|
|
31
|
-
return String(value).trim();
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return '';
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function hasExtension(url, extension) {
|
|
39
|
-
const pathname = normalizeAssetUrl(url).split(/[?#]/)[0].toLowerCase();
|
|
40
|
-
return !!pathname && pathname.endsWith(extension);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function getImageReferenceCandidates(model) {
|
|
44
|
-
const metadata = getMetadata(model);
|
|
45
|
-
return [
|
|
46
|
-
model?.response,
|
|
47
|
-
model?.Response,
|
|
48
|
-
metadata?.OriginalPath,
|
|
49
|
-
metadata?.OriginalUrl,
|
|
50
|
-
metadata?.originalUrl,
|
|
51
|
-
metadata?.ImageUrl,
|
|
52
|
-
metadata?.imageUrl
|
|
53
|
-
];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function isAnimatedGifImageModel(model) {
|
|
57
|
-
if (!model || getContentType(model) !== 'image') return false;
|
|
58
|
-
const metadata = getMetadata(model);
|
|
59
|
-
const mimeType = getMetadataValue(metadata, 'fileMime', 'FileMime', 'mimeType', 'MimeType').toLowerCase();
|
|
60
|
-
return mimeType === 'image/gif' || getImageReferenceCandidates(model).some(url => hasExtension(url, '.gif'));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function isWebpImageModel(model) {
|
|
64
|
-
if (!model || getContentType(model) !== 'image') return false;
|
|
65
|
-
const metadata = getMetadata(model);
|
|
66
|
-
const mimeType = getMetadataValue(metadata, 'fileMime', 'FileMime', 'mimeType', 'MimeType').toLowerCase();
|
|
67
|
-
return mimeType === 'image/webp' || getImageReferenceCandidates(model).some(url => hasExtension(url, '.webp'));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function isSafeResidentStaticPreviewUrl(url) {
|
|
71
|
-
const normalized = normalizeAssetUrl(url).toLowerCase();
|
|
72
|
-
return normalized.includes('/assets/thumbs/') &&
|
|
73
|
-
!hasExtension(normalized, '.gif') &&
|
|
74
|
-
!hasExtension(normalized, '.webp');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function getCanonicalAssetKey(url) {
|
|
78
|
-
const normalized = normalizeAssetUrl(url);
|
|
79
|
-
if (!normalized) return '';
|
|
80
|
-
const withoutQuery = normalized.split(/[?#]/)[0];
|
|
81
|
-
const lower = withoutQuery.toLowerCase();
|
|
82
|
-
for (const marker of ['/assets/thumbs/', '/assets/']) {
|
|
83
|
-
if (!lower.includes(marker)) continue;
|
|
84
|
-
const assetName = withoutQuery.slice(lower.lastIndexOf(marker) + marker.length).split('/').pop() || '';
|
|
85
|
-
const dotIndex = assetName.lastIndexOf('.');
|
|
86
|
-
return (dotIndex > 0 ? assetName.slice(0, dotIndex) : assetName).toLowerCase();
|
|
87
|
-
}
|
|
88
|
-
return withoutQuery.toLowerCase();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function areAssetUrlsEquivalent(leftUrl, rightUrl) {
|
|
92
|
-
const leftKey = getCanonicalAssetKey(leftUrl);
|
|
93
|
-
const rightKey = getCanonicalAssetKey(rightUrl);
|
|
94
|
-
return leftKey && rightKey
|
|
95
|
-
? leftKey === rightKey
|
|
96
|
-
: normalizeAssetUrl(leftUrl) === normalizeAssetUrl(rightUrl);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function getLocalWebpAssetFilename(...urls) {
|
|
100
|
-
for (const candidate of urls) {
|
|
101
|
-
const normalized = normalizeAssetUrl(candidate);
|
|
102
|
-
if (!normalized || !hasExtension(normalized, '.webp')) continue;
|
|
103
|
-
|
|
104
|
-
let pathname = normalized.split(/[?#]/)[0];
|
|
105
|
-
try {
|
|
106
|
-
pathname = new URL(normalized, window.location?.origin || 'http://127.0.0.1').pathname;
|
|
107
|
-
} catch { }
|
|
108
|
-
|
|
109
|
-
const normalizedPath = pathname.replace(/\\/g, '/');
|
|
110
|
-
if (!/(^|\/)assets\//i.test(normalizedPath)) continue;
|
|
111
|
-
|
|
112
|
-
const rawFilename = normalizedPath.split('/').pop() || '';
|
|
113
|
-
let filename = rawFilename;
|
|
114
|
-
try { filename = decodeURIComponent(rawFilename); } catch { }
|
|
115
|
-
if (/^[^/\\]+\.webp$/i.test(filename)) return filename;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return '';
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function getBridgeOrigin() {
|
|
122
|
-
const configuredOrigin = String(window.MindExecLocalBridge?.activeBridgeUrl || '').trim();
|
|
123
|
-
return (configuredOrigin || window.location?.origin || 'http://127.0.0.1:5147').replace(/\/$/, '');
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
async function getBridgeAuthHeaders(bridgeOrigin) {
|
|
127
|
-
if (window.__mindExecutionBridgeAuthPromise) {
|
|
128
|
-
try { return await window.__mindExecutionBridgeAuthPromise; } catch { }
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const authPromise = (async () => {
|
|
132
|
-
const nonce = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
133
|
-
const response = await fetch(`${bridgeOrigin}/api/status?cb=${encodeURIComponent(nonce)}`, {
|
|
134
|
-
cache: 'no-store',
|
|
135
|
-
targetAddressSpace: 'loopback'
|
|
136
|
-
});
|
|
137
|
-
if (!response.ok) return {};
|
|
138
|
-
const status = await response.json();
|
|
139
|
-
const token = String(status?.bridgeToken || '').trim();
|
|
140
|
-
const header = String(status?.bridgeTokenHeader || 'X-Bridge-Token').trim();
|
|
141
|
-
return token && header ? { [header]: token } : {};
|
|
142
|
-
})();
|
|
143
|
-
window.__mindExecutionBridgeAuthPromise = authPromise;
|
|
144
|
-
|
|
145
|
-
try {
|
|
146
|
-
return await authPromise;
|
|
147
|
-
} catch {
|
|
148
|
-
if (window.__mindExecutionBridgeAuthPromise === authPromise) {
|
|
149
|
-
window.__mindExecutionBridgeAuthPromise = null;
|
|
150
|
-
}
|
|
151
|
-
return {};
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
async function resolveLocalWebpResidentPreview(item, assetUrls) {
|
|
156
|
-
const sourceUrl = normalizeAssetUrl(
|
|
157
|
-
item?.originalUrl ||
|
|
158
|
-
assetUrls?.fullResUrl ||
|
|
159
|
-
assetUrls?.originalUrl ||
|
|
160
|
-
assetUrls?.originalPath ||
|
|
161
|
-
item?.previewUrl || ''
|
|
162
|
-
);
|
|
163
|
-
const filename = getLocalWebpAssetFilename(
|
|
164
|
-
sourceUrl,
|
|
165
|
-
assetUrls?.originalPath,
|
|
166
|
-
assetUrls?.originalUrl,
|
|
167
|
-
item?.previewUrl
|
|
168
|
-
);
|
|
169
|
-
if (!filename || typeof fetch !== 'function') {
|
|
170
|
-
return { sourceUrl, previewUrl: '' };
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const bridgeOrigin = getBridgeOrigin();
|
|
174
|
-
const headers = await getBridgeAuthHeaders(bridgeOrigin);
|
|
175
|
-
const endpoint = `${bridgeOrigin}/api/assets/generate-thumbnail/${encodeURIComponent(filename)}`;
|
|
176
|
-
const response = await fetch(endpoint, {
|
|
177
|
-
method: 'POST',
|
|
178
|
-
headers,
|
|
179
|
-
cache: 'no-store',
|
|
180
|
-
targetAddressSpace: 'loopback'
|
|
181
|
-
});
|
|
182
|
-
if (!response.ok) {
|
|
183
|
-
throw new Error(`resident-static-preview-http-${response.status}`);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const payload = await response.json();
|
|
187
|
-
const previewUrl = normalizeAssetUrl(payload?.thumbnailUrl || '');
|
|
188
|
-
if (!isSafeResidentStaticPreviewUrl(previewUrl)) {
|
|
189
|
-
throw new Error('resident-static-preview-invalid-url');
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return { sourceUrl, previewUrl };
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
function getResidentStaticPreviewUrl(renderer, nodeId, model, assetUrls) {
|
|
196
|
-
const normalizedNodeId = String(nodeId || '').trim();
|
|
197
|
-
const previewUrl = normalizeAssetUrl(assetUrls?.previewUrl || '');
|
|
198
|
-
if (!isWebpImageModel(model)) return previewUrl;
|
|
199
|
-
|
|
200
|
-
const sourceUrl = normalizeAssetUrl(
|
|
201
|
-
assetUrls?.fullResUrl || assetUrls?.originalUrl || assetUrls?.originalPath || previewUrl
|
|
202
|
-
);
|
|
203
|
-
const record = normalizedNodeId ? renderer?._residentStaticPreviewUrls?.get(normalizedNodeId) : null;
|
|
204
|
-
if (record?.sourceUrl === sourceUrl && isSafeResidentStaticPreviewUrl(record.previewUrl)) {
|
|
205
|
-
return normalizeAssetUrl(record.previewUrl);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (normalizedNodeId && record) renderer._residentStaticPreviewUrls.delete(normalizedNodeId);
|
|
209
|
-
const existingThumbnailUrl = normalizeAssetUrl(assetUrls?.thumbnailUrl || '');
|
|
210
|
-
if (normalizedNodeId && sourceUrl && isSafeResidentStaticPreviewUrl(existingThumbnailUrl)) {
|
|
211
|
-
renderer._residentStaticPreviewUrls.set(normalizedNodeId, {
|
|
212
|
-
sourceUrl,
|
|
213
|
-
previewUrl: existingThumbnailUrl
|
|
214
|
-
});
|
|
215
|
-
return existingThumbnailUrl;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return '';
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
async function resolveSafeResidentPreviewUrl(renderer, item, assetUrls, getCurrentAssetUrls, onReady) {
|
|
222
|
-
if (!isWebpImageModel(item?.model)) {
|
|
223
|
-
return normalizeAssetUrl(item?.previewUrl || assetUrls?.previewUrl || '');
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const nodeId = String(item?.nodeId || '').trim();
|
|
227
|
-
const existingPreviewUrl = getResidentStaticPreviewUrl(renderer, nodeId, item.model, {
|
|
228
|
-
...assetUrls,
|
|
229
|
-
thumbnailUrl: item?.thumbnailUrl || assetUrls?.thumbnailUrl || ''
|
|
230
|
-
});
|
|
231
|
-
if (existingPreviewUrl) return existingPreviewUrl;
|
|
232
|
-
|
|
233
|
-
const resolved = await resolveLocalWebpResidentPreview(item, assetUrls);
|
|
234
|
-
const sourceUrl = normalizeAssetUrl(resolved?.sourceUrl || '');
|
|
235
|
-
const previewUrl = normalizeAssetUrl(resolved?.previewUrl || '');
|
|
236
|
-
if (!isSafeResidentStaticPreviewUrl(previewUrl)) return '';
|
|
237
|
-
|
|
238
|
-
if (
|
|
239
|
-
renderer?._disposed === true ||
|
|
240
|
-
item?.previewEpoch !== renderer?._residentStaticPreviewEpoch ||
|
|
241
|
-
renderer?.isInLODMode !== true
|
|
242
|
-
) {
|
|
243
|
-
return '';
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const currentEntry = renderer?._module?.nodeObjectsById?.get?.(nodeId) || null;
|
|
247
|
-
const currentAssetUrls = getCurrentAssetUrls?.(currentEntry?.model) || {};
|
|
248
|
-
const currentSourceUrl = normalizeAssetUrl(
|
|
249
|
-
currentAssetUrls?.fullResUrl ||
|
|
250
|
-
currentAssetUrls?.originalUrl ||
|
|
251
|
-
currentAssetUrls?.originalPath ||
|
|
252
|
-
currentAssetUrls?.previewUrl || ''
|
|
253
|
-
);
|
|
254
|
-
if (!currentEntry?.model || currentSourceUrl !== sourceUrl) return '';
|
|
255
|
-
|
|
256
|
-
renderer._residentStaticPreviewUrls.set(nodeId, { sourceUrl, previewUrl });
|
|
257
|
-
onReady?.({ nodeId, sourceKind: 'webp', previewUrl });
|
|
258
|
-
return previewUrl;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
window.MindMapAnimatedImagePreview = Object.freeze({
|
|
262
|
-
normalizeAssetUrl,
|
|
263
|
-
isAnimatedGifImageModel,
|
|
264
|
-
isWebpImageModel,
|
|
265
|
-
isSafeResidentStaticPreviewUrl,
|
|
266
|
-
areAssetUrlsEquivalent,
|
|
267
|
-
getResidentStaticPreviewUrl,
|
|
268
|
-
resolveSafeResidentPreviewUrl
|
|
269
|
-
});
|
|
270
|
-
})();
|
|
1
|
+
// Bounded resident previews for animation-capable image formats.
|
|
2
|
+
(function () {
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
function normalizeAssetUrl(url) {
|
|
6
|
+
if (typeof url !== 'string') return '';
|
|
7
|
+
return url.trim()
|
|
8
|
+
.replace(/^http:\/\/localhost(?=:\d+\/assets\/)/i, 'http://127.0.0.1')
|
|
9
|
+
.replace(/^http:\/\/\[::1\](?=:\d+\/assets\/)/i, 'http://127.0.0.1');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function getContentType(model) {
|
|
13
|
+
return String(model?.contentType || model?.ContentType || '').trim().toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function getMetadata(model) {
|
|
17
|
+
return model?.metadata || model?.Metadata || {};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function getMetadataValue(metadata, ...keys) {
|
|
21
|
+
for (const key of keys) {
|
|
22
|
+
const direct = metadata?.[key];
|
|
23
|
+
if (direct !== undefined && direct !== null && String(direct).trim()) {
|
|
24
|
+
return String(direct).trim();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const wanted = new Set(keys.map(key => String(key).toLowerCase()));
|
|
29
|
+
for (const [key, value] of Object.entries(metadata || {})) {
|
|
30
|
+
if (wanted.has(String(key).toLowerCase()) && value !== undefined && value !== null && String(value).trim()) {
|
|
31
|
+
return String(value).trim();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return '';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function hasExtension(url, extension) {
|
|
39
|
+
const pathname = normalizeAssetUrl(url).split(/[?#]/)[0].toLowerCase();
|
|
40
|
+
return !!pathname && pathname.endsWith(extension);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getImageReferenceCandidates(model) {
|
|
44
|
+
const metadata = getMetadata(model);
|
|
45
|
+
return [
|
|
46
|
+
model?.response,
|
|
47
|
+
model?.Response,
|
|
48
|
+
metadata?.OriginalPath,
|
|
49
|
+
metadata?.OriginalUrl,
|
|
50
|
+
metadata?.originalUrl,
|
|
51
|
+
metadata?.ImageUrl,
|
|
52
|
+
metadata?.imageUrl
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function isAnimatedGifImageModel(model) {
|
|
57
|
+
if (!model || getContentType(model) !== 'image') return false;
|
|
58
|
+
const metadata = getMetadata(model);
|
|
59
|
+
const mimeType = getMetadataValue(metadata, 'fileMime', 'FileMime', 'mimeType', 'MimeType').toLowerCase();
|
|
60
|
+
return mimeType === 'image/gif' || getImageReferenceCandidates(model).some(url => hasExtension(url, '.gif'));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function isWebpImageModel(model) {
|
|
64
|
+
if (!model || getContentType(model) !== 'image') return false;
|
|
65
|
+
const metadata = getMetadata(model);
|
|
66
|
+
const mimeType = getMetadataValue(metadata, 'fileMime', 'FileMime', 'mimeType', 'MimeType').toLowerCase();
|
|
67
|
+
return mimeType === 'image/webp' || getImageReferenceCandidates(model).some(url => hasExtension(url, '.webp'));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isSafeResidentStaticPreviewUrl(url) {
|
|
71
|
+
const normalized = normalizeAssetUrl(url).toLowerCase();
|
|
72
|
+
return normalized.includes('/assets/thumbs/') &&
|
|
73
|
+
!hasExtension(normalized, '.gif') &&
|
|
74
|
+
!hasExtension(normalized, '.webp');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getCanonicalAssetKey(url) {
|
|
78
|
+
const normalized = normalizeAssetUrl(url);
|
|
79
|
+
if (!normalized) return '';
|
|
80
|
+
const withoutQuery = normalized.split(/[?#]/)[0];
|
|
81
|
+
const lower = withoutQuery.toLowerCase();
|
|
82
|
+
for (const marker of ['/assets/thumbs/', '/assets/']) {
|
|
83
|
+
if (!lower.includes(marker)) continue;
|
|
84
|
+
const assetName = withoutQuery.slice(lower.lastIndexOf(marker) + marker.length).split('/').pop() || '';
|
|
85
|
+
const dotIndex = assetName.lastIndexOf('.');
|
|
86
|
+
return (dotIndex > 0 ? assetName.slice(0, dotIndex) : assetName).toLowerCase();
|
|
87
|
+
}
|
|
88
|
+
return withoutQuery.toLowerCase();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function areAssetUrlsEquivalent(leftUrl, rightUrl) {
|
|
92
|
+
const leftKey = getCanonicalAssetKey(leftUrl);
|
|
93
|
+
const rightKey = getCanonicalAssetKey(rightUrl);
|
|
94
|
+
return leftKey && rightKey
|
|
95
|
+
? leftKey === rightKey
|
|
96
|
+
: normalizeAssetUrl(leftUrl) === normalizeAssetUrl(rightUrl);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function getLocalWebpAssetFilename(...urls) {
|
|
100
|
+
for (const candidate of urls) {
|
|
101
|
+
const normalized = normalizeAssetUrl(candidate);
|
|
102
|
+
if (!normalized || !hasExtension(normalized, '.webp')) continue;
|
|
103
|
+
|
|
104
|
+
let pathname = normalized.split(/[?#]/)[0];
|
|
105
|
+
try {
|
|
106
|
+
pathname = new URL(normalized, window.location?.origin || 'http://127.0.0.1').pathname;
|
|
107
|
+
} catch { }
|
|
108
|
+
|
|
109
|
+
const normalizedPath = pathname.replace(/\\/g, '/');
|
|
110
|
+
if (!/(^|\/)assets\//i.test(normalizedPath)) continue;
|
|
111
|
+
|
|
112
|
+
const rawFilename = normalizedPath.split('/').pop() || '';
|
|
113
|
+
let filename = rawFilename;
|
|
114
|
+
try { filename = decodeURIComponent(rawFilename); } catch { }
|
|
115
|
+
if (/^[^/\\]+\.webp$/i.test(filename)) return filename;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return '';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function getBridgeOrigin() {
|
|
122
|
+
const configuredOrigin = String(window.MindExecLocalBridge?.activeBridgeUrl || '').trim();
|
|
123
|
+
return (configuredOrigin || window.location?.origin || 'http://127.0.0.1:5147').replace(/\/$/, '');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function getBridgeAuthHeaders(bridgeOrigin) {
|
|
127
|
+
if (window.__mindExecutionBridgeAuthPromise) {
|
|
128
|
+
try { return await window.__mindExecutionBridgeAuthPromise; } catch { }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const authPromise = (async () => {
|
|
132
|
+
const nonce = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
133
|
+
const response = await fetch(`${bridgeOrigin}/api/status?cb=${encodeURIComponent(nonce)}`, {
|
|
134
|
+
cache: 'no-store',
|
|
135
|
+
targetAddressSpace: 'loopback'
|
|
136
|
+
});
|
|
137
|
+
if (!response.ok) return {};
|
|
138
|
+
const status = await response.json();
|
|
139
|
+
const token = String(status?.bridgeToken || '').trim();
|
|
140
|
+
const header = String(status?.bridgeTokenHeader || 'X-Bridge-Token').trim();
|
|
141
|
+
return token && header ? { [header]: token } : {};
|
|
142
|
+
})();
|
|
143
|
+
window.__mindExecutionBridgeAuthPromise = authPromise;
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
return await authPromise;
|
|
147
|
+
} catch {
|
|
148
|
+
if (window.__mindExecutionBridgeAuthPromise === authPromise) {
|
|
149
|
+
window.__mindExecutionBridgeAuthPromise = null;
|
|
150
|
+
}
|
|
151
|
+
return {};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async function resolveLocalWebpResidentPreview(item, assetUrls) {
|
|
156
|
+
const sourceUrl = normalizeAssetUrl(
|
|
157
|
+
item?.originalUrl ||
|
|
158
|
+
assetUrls?.fullResUrl ||
|
|
159
|
+
assetUrls?.originalUrl ||
|
|
160
|
+
assetUrls?.originalPath ||
|
|
161
|
+
item?.previewUrl || ''
|
|
162
|
+
);
|
|
163
|
+
const filename = getLocalWebpAssetFilename(
|
|
164
|
+
sourceUrl,
|
|
165
|
+
assetUrls?.originalPath,
|
|
166
|
+
assetUrls?.originalUrl,
|
|
167
|
+
item?.previewUrl
|
|
168
|
+
);
|
|
169
|
+
if (!filename || typeof fetch !== 'function') {
|
|
170
|
+
return { sourceUrl, previewUrl: '' };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const bridgeOrigin = getBridgeOrigin();
|
|
174
|
+
const headers = await getBridgeAuthHeaders(bridgeOrigin);
|
|
175
|
+
const endpoint = `${bridgeOrigin}/api/assets/generate-thumbnail/${encodeURIComponent(filename)}`;
|
|
176
|
+
const response = await fetch(endpoint, {
|
|
177
|
+
method: 'POST',
|
|
178
|
+
headers,
|
|
179
|
+
cache: 'no-store',
|
|
180
|
+
targetAddressSpace: 'loopback'
|
|
181
|
+
});
|
|
182
|
+
if (!response.ok) {
|
|
183
|
+
throw new Error(`resident-static-preview-http-${response.status}`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const payload = await response.json();
|
|
187
|
+
const previewUrl = normalizeAssetUrl(payload?.thumbnailUrl || '');
|
|
188
|
+
if (!isSafeResidentStaticPreviewUrl(previewUrl)) {
|
|
189
|
+
throw new Error('resident-static-preview-invalid-url');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return { sourceUrl, previewUrl };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function getResidentStaticPreviewUrl(renderer, nodeId, model, assetUrls) {
|
|
196
|
+
const normalizedNodeId = String(nodeId || '').trim();
|
|
197
|
+
const previewUrl = normalizeAssetUrl(assetUrls?.previewUrl || '');
|
|
198
|
+
if (!isWebpImageModel(model)) return previewUrl;
|
|
199
|
+
|
|
200
|
+
const sourceUrl = normalizeAssetUrl(
|
|
201
|
+
assetUrls?.fullResUrl || assetUrls?.originalUrl || assetUrls?.originalPath || previewUrl
|
|
202
|
+
);
|
|
203
|
+
const record = normalizedNodeId ? renderer?._residentStaticPreviewUrls?.get(normalizedNodeId) : null;
|
|
204
|
+
if (record?.sourceUrl === sourceUrl && isSafeResidentStaticPreviewUrl(record.previewUrl)) {
|
|
205
|
+
return normalizeAssetUrl(record.previewUrl);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (normalizedNodeId && record) renderer._residentStaticPreviewUrls.delete(normalizedNodeId);
|
|
209
|
+
const existingThumbnailUrl = normalizeAssetUrl(assetUrls?.thumbnailUrl || '');
|
|
210
|
+
if (normalizedNodeId && sourceUrl && isSafeResidentStaticPreviewUrl(existingThumbnailUrl)) {
|
|
211
|
+
renderer._residentStaticPreviewUrls.set(normalizedNodeId, {
|
|
212
|
+
sourceUrl,
|
|
213
|
+
previewUrl: existingThumbnailUrl
|
|
214
|
+
});
|
|
215
|
+
return existingThumbnailUrl;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return '';
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async function resolveSafeResidentPreviewUrl(renderer, item, assetUrls, getCurrentAssetUrls, onReady) {
|
|
222
|
+
if (!isWebpImageModel(item?.model)) {
|
|
223
|
+
return normalizeAssetUrl(item?.previewUrl || assetUrls?.previewUrl || '');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const nodeId = String(item?.nodeId || '').trim();
|
|
227
|
+
const existingPreviewUrl = getResidentStaticPreviewUrl(renderer, nodeId, item.model, {
|
|
228
|
+
...assetUrls,
|
|
229
|
+
thumbnailUrl: item?.thumbnailUrl || assetUrls?.thumbnailUrl || ''
|
|
230
|
+
});
|
|
231
|
+
if (existingPreviewUrl) return existingPreviewUrl;
|
|
232
|
+
|
|
233
|
+
const resolved = await resolveLocalWebpResidentPreview(item, assetUrls);
|
|
234
|
+
const sourceUrl = normalizeAssetUrl(resolved?.sourceUrl || '');
|
|
235
|
+
const previewUrl = normalizeAssetUrl(resolved?.previewUrl || '');
|
|
236
|
+
if (!isSafeResidentStaticPreviewUrl(previewUrl)) return '';
|
|
237
|
+
|
|
238
|
+
if (
|
|
239
|
+
renderer?._disposed === true ||
|
|
240
|
+
item?.previewEpoch !== renderer?._residentStaticPreviewEpoch ||
|
|
241
|
+
renderer?.isInLODMode !== true
|
|
242
|
+
) {
|
|
243
|
+
return '';
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const currentEntry = renderer?._module?.nodeObjectsById?.get?.(nodeId) || null;
|
|
247
|
+
const currentAssetUrls = getCurrentAssetUrls?.(currentEntry?.model) || {};
|
|
248
|
+
const currentSourceUrl = normalizeAssetUrl(
|
|
249
|
+
currentAssetUrls?.fullResUrl ||
|
|
250
|
+
currentAssetUrls?.originalUrl ||
|
|
251
|
+
currentAssetUrls?.originalPath ||
|
|
252
|
+
currentAssetUrls?.previewUrl || ''
|
|
253
|
+
);
|
|
254
|
+
if (!currentEntry?.model || currentSourceUrl !== sourceUrl) return '';
|
|
255
|
+
|
|
256
|
+
renderer._residentStaticPreviewUrls.set(nodeId, { sourceUrl, previewUrl });
|
|
257
|
+
onReady?.({ nodeId, sourceKind: 'webp', previewUrl });
|
|
258
|
+
return previewUrl;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
window.MindMapAnimatedImagePreview = Object.freeze({
|
|
262
|
+
normalizeAssetUrl,
|
|
263
|
+
isAnimatedGifImageModel,
|
|
264
|
+
isWebpImageModel,
|
|
265
|
+
isSafeResidentStaticPreviewUrl,
|
|
266
|
+
areAssetUrlsEquivalent,
|
|
267
|
+
getResidentStaticPreviewUrl,
|
|
268
|
+
resolveSafeResidentPreviewUrl
|
|
269
|
+
});
|
|
270
|
+
})();
|