@mindexec/cli 0.2.477 → 0.2.478
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 +7690 -7690
- package/start-bridge.bat +32 -32
- package/start-bridge.sh +81 -81
- package/wwwroot/_content/MindExecution.Plugins.Admin/css/admin-dashboard.css +546 -546
- package/wwwroot/_content/MindExecution.Plugins.YouTube/css/youtube-search.css +251 -251
- package/wwwroot/_content/MindExecution.Shared/css/app.css +1 -1
- package/wwwroot/_content/MindExecution.Shared/css/mind-map-overrides.css +3789 -3789
- 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 +10506 -10506
- 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-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 +7065 -7065
- 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 +9956 -9956
- 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 +4744 -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-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-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.9h59ukbel7.dll → Google.Protobuf.33g2gb5is0.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Core.ty1xewqp36.dll → MindExecution.Core.z100xo4mg0.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Kernel.h7rqjoo69o.dll → MindExecution.Kernel.i9cldrx8yc.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Admin.wrfrcvhjde.dll → MindExecution.Plugins.Admin.48lzqddb0a.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Business.csbcyjurdh.dll → MindExecution.Plugins.Business.7m8u1q142p.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Concept.buomiysqjn.dll → MindExecution.Plugins.Concept.cl5wmr53od.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Directory.7k00i2v769.dll → MindExecution.Plugins.Directory.slipi39041.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.85i5ocraro.dll → MindExecution.Plugins.PlanMaster.qfge05l671.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.YouTube.nbolrfakte.dll → MindExecution.Plugins.YouTube.tn7v29ut77.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Shared.nqh4porv7x.dll → MindExecution.Shared.rjqlf0umjn.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Web.211q3bf4mr.dll → MindExecution.Web.rwawrxxk38.dll} +0 -0
- package/wwwroot/_framework/blazor.boot.json +23 -23
- 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 +78 -106
- package/wwwroot/service-worker.js +33 -33
- package/tree-sitter-grammars/README.md +0 -18
- 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.Directory/background.png +0 -0
- 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/mind-map-core.js.backup +0 -1059
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js.bak +0 -434
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-object-manager.js.backup +0 -372
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js.backup +0 -1258
package/wwwroot/index.html
CHANGED
|
@@ -1,772 +1,772 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="utf-8" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
-
<title>MindExec | Business Execution OS for solo builders</title>
|
|
8
|
-
<meta name="description" content="MindExec is an AI business execution OS for solo builders who want to turn notes, research, assets, and repeatable execution Skills into revenue-producing work." />
|
|
9
|
-
<base href="/" />
|
|
10
|
-
<meta name="theme-color" content="#f8fafc" />
|
|
11
|
-
<link rel="icon" type="image/png" sizes="32x32" href="/mindexec-favicon-v3.png" />
|
|
12
|
-
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png?v=20260815-app-icon-v2" />
|
|
13
|
-
<link rel="manifest" href="manifest.webmanifest?v=20260815-app-icon-v2" />
|
|
14
|
-
<link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260629-ai-task-flow-v863" />
|
|
15
|
-
<link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260822-selection-unified-v857" />
|
|
16
|
-
<!-- ??좎뜦堉??Font Awesome (local) ??좎뜦堉??-->
|
|
17
|
-
<link rel="stylesheet" href="_content/MindExecution.Shared/lib/font-awesome/css/all.min.css" />
|
|
18
|
-
<!-- ??좎뜦堉??-->
|
|
19
|
-
<style>
|
|
20
|
-
html,
|
|
21
|
-
body {
|
|
22
|
-
margin: 0;
|
|
23
|
-
background: #f8fafc;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
#app {
|
|
27
|
-
min-height: 100vh;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.app-static-fallback {
|
|
31
|
-
position: fixed;
|
|
32
|
-
inset: 0;
|
|
33
|
-
z-index: 10;
|
|
34
|
-
box-sizing: border-box;
|
|
35
|
-
display: flex;
|
|
36
|
-
align-items: center;
|
|
37
|
-
justify-content: center;
|
|
38
|
-
width: 100%;
|
|
39
|
-
margin: 0;
|
|
40
|
-
padding: 24px;
|
|
41
|
-
background: #f8fafc;
|
|
42
|
-
color: #64748b;
|
|
43
|
-
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.app-loading-shell {
|
|
47
|
-
display: flex;
|
|
48
|
-
flex-direction: column;
|
|
49
|
-
align-items: center;
|
|
50
|
-
gap: 14px;
|
|
51
|
-
text-align: center;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.app-loading-shell__logo {
|
|
55
|
-
display: block;
|
|
56
|
-
width: 44px;
|
|
57
|
-
height: 44px;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.app-loading-spinner {
|
|
61
|
-
box-sizing: border-box;
|
|
62
|
-
width: 34px;
|
|
63
|
-
height: 34px;
|
|
64
|
-
border: 3px solid #dbe5f0;
|
|
65
|
-
border-top-color: #2563eb;
|
|
66
|
-
border-radius: 50%;
|
|
67
|
-
animation: app-loading-spin 720ms linear infinite;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.app-loading-shell__label,
|
|
71
|
-
.app-loading-shell__noscript {
|
|
72
|
-
margin: 0;
|
|
73
|
-
font-size: 13px;
|
|
74
|
-
line-height: 1.4;
|
|
75
|
-
font-weight: 600;
|
|
76
|
-
letter-spacing: 0.01em;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
@keyframes app-loading-spin {
|
|
80
|
-
to {
|
|
81
|
-
transform: rotate(360deg);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
@media (prefers-reduced-motion: reduce) {
|
|
86
|
-
.app-loading-spinner {
|
|
87
|
-
animation-duration: 1600ms;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
#blazor-error-ui {
|
|
92
|
-
display: none;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
#blazor-error-ui.is-visible {
|
|
96
|
-
position: fixed;
|
|
97
|
-
right: 20px;
|
|
98
|
-
bottom: 20px;
|
|
99
|
-
z-index: 9999;
|
|
100
|
-
display: flex;
|
|
101
|
-
align-items: center;
|
|
102
|
-
gap: 12px;
|
|
103
|
-
max-width: 420px;
|
|
104
|
-
padding: 14px 16px;
|
|
105
|
-
border-radius: 14px;
|
|
106
|
-
background: rgba(15, 23, 42, 0.96);
|
|
107
|
-
color: #fff;
|
|
108
|
-
box-shadow: 0 18px 48px rgba(15, 23, 42, 0.28);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.blazor-error-ui__message {
|
|
112
|
-
flex: 1;
|
|
113
|
-
font-size: 14px;
|
|
114
|
-
line-height: 1.6;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
#blazor-error-ui .reload,
|
|
118
|
-
#blazor-error-ui .dismiss {
|
|
119
|
-
color: #fff;
|
|
120
|
-
font-size: 13px;
|
|
121
|
-
font-weight: 700;
|
|
122
|
-
text-decoration: none;
|
|
123
|
-
cursor: pointer;
|
|
124
|
-
}
|
|
125
|
-
</style>
|
|
126
|
-
</head>
|
|
127
|
-
|
|
128
|
-
<body>
|
|
129
|
-
<div id="app-container">
|
|
130
|
-
<div id="app">
|
|
131
|
-
<article class="app-static-fallback" id="app-static-fallback">
|
|
132
|
-
<div class="app-loading-shell" role="status" aria-live="polite" aria-label="Loading MindCanvas">
|
|
133
|
-
<img class="app-loading-shell__logo" src="icon-192.png?v=20260815-app-icon-v2" alt="" aria-hidden="true" />
|
|
134
|
-
<div class="app-loading-spinner" aria-hidden="true"></div>
|
|
135
|
-
<p class="app-loading-shell__label">Loading MindCanvas…</p>
|
|
136
|
-
<noscript>
|
|
137
|
-
<p class="app-loading-shell__noscript">JavaScript is required to start MindCanvas.</p>
|
|
138
|
-
</noscript>
|
|
139
|
-
</div>
|
|
140
|
-
</article>
|
|
141
|
-
</div>
|
|
142
|
-
</div>
|
|
143
|
-
|
|
144
|
-
<div id="three-js-container"
|
|
145
|
-
style="display: none; position: fixed; top:0; left:0; width:100%; height:100%; z-index:999; background-color: rgba(0,0,0,0.5);">
|
|
146
|
-
</div>
|
|
147
|
-
|
|
148
|
-
<!-- Selection rectangle overlay -->
|
|
149
|
-
<div id="selection-rectangle"
|
|
150
|
-
style="position: fixed; border:2px solid #1173d4; background-color: rgba(17, 115, 212, 0.15); pointer-events: none; display: none; z-index:100;">
|
|
151
|
-
</div>
|
|
152
|
-
|
|
153
|
-
<div id="blazor-error-ui" role="alert" aria-live="assertive">
|
|
154
|
-
<div class="blazor-error-ui__message"></div>
|
|
155
|
-
<a href="." class="reload">Reload</a>
|
|
156
|
-
<span class="dismiss">Dismiss</span>
|
|
157
|
-
</div>
|
|
158
|
-
|
|
159
|
-
<!-- Aggressively remove any existing service workers and caches so hosted deploys pick up new JS immediately -->
|
|
160
|
-
<script>
|
|
161
|
-
window.__swCleanup = (async () => {
|
|
162
|
-
try {
|
|
163
|
-
let hadAnything = false;
|
|
164
|
-
if ('serviceWorker' in navigator) {
|
|
165
|
-
const regs = await navigator.serviceWorker.getRegistrations();
|
|
166
|
-
hadAnything = hadAnything || regs.length > 0;
|
|
167
|
-
await Promise.allSettled(regs.map(r => r.unregister()));
|
|
168
|
-
}
|
|
169
|
-
if (window.caches) {
|
|
170
|
-
const keys = await caches.keys();
|
|
171
|
-
hadAnything = hadAnything || keys.length > 0;
|
|
172
|
-
await Promise.allSettled(keys.map(k => caches.delete(k)));
|
|
173
|
-
}
|
|
174
|
-
return hadAnything;
|
|
175
|
-
} catch (e) {
|
|
176
|
-
console.debug('SW cleanup skipped:', e);
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
})();
|
|
180
|
-
</script>
|
|
181
|
-
|
|
182
|
-
<!-- Blazor WASM loader (autostart disabled; we'll start after our scripts load) -->
|
|
183
|
-
<script src="_framework/blazor.webassembly.js" autostart="false"></script>
|
|
184
|
-
|
|
185
|
-
<!-- Global helpers and libraries -->
|
|
186
|
-
<script src="js/marketing-tool.js"></script>
|
|
187
|
-
<script>
|
|
188
|
-
window.showBlazorBootError = function (message) {
|
|
189
|
-
const errorUi = document.getElementById('blazor-error-ui');
|
|
190
|
-
if (!errorUi) return;
|
|
191
|
-
|
|
192
|
-
const messageElement = errorUi.querySelector('.blazor-error-ui__message');
|
|
193
|
-
if (messageElement) {
|
|
194
|
-
messageElement.textContent = message || 'This page could not finish loading.';
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
errorUi.classList.add('is-visible');
|
|
198
|
-
errorUi.removeAttribute('hidden');
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
window.hideBlazorBootError = function () {
|
|
202
|
-
const errorUi = document.getElementById('blazor-error-ui');
|
|
203
|
-
if (!errorUi) return;
|
|
204
|
-
errorUi.classList.remove('is-visible');
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
document.addEventListener('click', (event) => {
|
|
208
|
-
const target = event.target;
|
|
209
|
-
if (target instanceof HTMLElement && target.classList.contains('dismiss')) {
|
|
210
|
-
window.hideBlazorBootError();
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
// Global textarea handlers
|
|
215
|
-
function adjustTextareaHeight(element) {
|
|
216
|
-
if (!element) return;
|
|
217
|
-
|
|
218
|
-
// ??좎뜦堉??[Change] Add jitter-prevention logic ??좎뜦堉??
|
|
219
|
-
// Compare the previous text length. When content grows, skip the 'auto' reset.
|
|
220
|
-
// Only reset to 'auto' when shrinking (during deletion).
|
|
221
|
-
const currentLength = element.value.length;
|
|
222
|
-
const prevLength = parseInt(element.dataset.prevLength || '0');
|
|
223
|
-
|
|
224
|
-
if (currentLength < prevLength) {
|
|
225
|
-
element.style.height = 'auto'; // reset height when deleting to allow shrink
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
element.dataset.prevLength = currentLength; // store current length
|
|
229
|
-
// ??좎뜦堉??[Change] ??좎뜦堉??
|
|
230
|
-
|
|
231
|
-
const computedStyles = window.getComputedStyle(element);
|
|
232
|
-
const lineHeight = parseFloat(computedStyles.lineHeight || '24') || 24;
|
|
233
|
-
const paddingTop = parseFloat(computedStyles.paddingTop || '0') || 0;
|
|
234
|
-
const paddingBottom = parseFloat(computedStyles.paddingBottom || '0') || 0;
|
|
235
|
-
const verticalPadding = paddingTop + paddingBottom;
|
|
236
|
-
const maxLines = 6; // limit to 6 lines
|
|
237
|
-
const maxHeight = (lineHeight * maxLines) + verticalPadding;
|
|
238
|
-
const minHeightPx = Math.max(lineHeight + verticalPadding, 42);
|
|
239
|
-
|
|
240
|
-
const newHeight = Math.min(element.scrollHeight, maxHeight);
|
|
241
|
-
|
|
242
|
-
// Even if content didn't shrink, apply if scrollHeight grew
|
|
243
|
-
element.style.height = Math.max(newHeight, minHeightPx) + 'px';
|
|
244
|
-
element.style.overflowY = 'hidden';
|
|
245
|
-
}
|
|
246
|
-
function resetTextareaHeight(element) {
|
|
247
|
-
if (!element) return;
|
|
248
|
-
const computedStyles = window.getComputedStyle(element);
|
|
249
|
-
const lineHeight = parseFloat(computedStyles.lineHeight || '24') || 24;
|
|
250
|
-
const paddingTop = parseFloat(computedStyles.paddingTop || '0') || 0;
|
|
251
|
-
const paddingBottom = parseFloat(computedStyles.paddingBottom || '0') || 0;
|
|
252
|
-
const minHeightPx = Math.max(lineHeight + paddingTop + paddingBottom, 42);
|
|
253
|
-
element.style.height = minHeightPx + 'px';
|
|
254
|
-
element.style.overflowY = 'hidden';
|
|
255
|
-
}
|
|
256
|
-
function attachTextareaHandlers(element, dotNetRef) {
|
|
257
|
-
if (!element) return;
|
|
258
|
-
|
|
259
|
-
if (element.__mindexecEnterHandler) {
|
|
260
|
-
element.removeEventListener('keydown', element.__mindexecEnterHandler);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
const handleKeyDown = (e) => {
|
|
264
|
-
if (e.key === 'Enter') {
|
|
265
|
-
if (e.shiftKey) {
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (e.repeat || e.isComposing || e.keyCode === 229) {
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
e.preventDefault();
|
|
274
|
-
const now = performance.now();
|
|
275
|
-
if (element.__mindexecLastEnterAt && now - element.__mindexecLastEnterAt < 650) {
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const promptSnapshot = element.value || '';
|
|
280
|
-
if (!promptSnapshot.trim()) {
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
element.__mindexecLastEnterAt = now;
|
|
285
|
-
const submitId = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
286
|
-
element.value = '';
|
|
287
|
-
element.dispatchEvent(new Event('input', { bubbles: true }));
|
|
288
|
-
resetTextareaHeight(element);
|
|
289
|
-
|
|
290
|
-
if (dotNetRef && dotNetRef.invokeMethodAsync) {
|
|
291
|
-
dotNetRef.invokeMethodAsync('OnGlobalInputEnterPressed', promptSnapshot, submitId)
|
|
292
|
-
.catch((err) => console.warn('[GlobalInput] Enter submit failed:', err));
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
element.__mindexecEnterHandler = handleKeyDown;
|
|
298
|
-
element.addEventListener('keydown', handleKeyDown);
|
|
299
|
-
}
|
|
300
|
-
function blurElement(element) {
|
|
301
|
-
if (element) element.blur();
|
|
302
|
-
if (document && document.body) document.body.focus();
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
function focusGlobalTextarea() {
|
|
306
|
-
const textarea = document.getElementById('global-input-textarea');
|
|
307
|
-
if (textarea) {
|
|
308
|
-
textarea.focus();
|
|
309
|
-
textarea.setSelectionRange(textarea.value.length, textarea.value.length);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
window.adjustTextareaHeight = adjustTextareaHeight;
|
|
314
|
-
window.resetTextareaHeight = resetTextareaHeight;
|
|
315
|
-
window.attachTextareaHandlers = attachTextareaHandlers;
|
|
316
|
-
window.blurElement = blurElement;
|
|
317
|
-
window.focusGlobalTextarea = focusGlobalTextarea;
|
|
318
|
-
|
|
319
|
-
// Prevent default page-level DnD behavior
|
|
320
|
-
document.addEventListener('dragover', (e) => {
|
|
321
|
-
e.preventDefault();
|
|
322
|
-
// ??좎뜦堉??[Change] Remove/avoid stopPropagation (do not disrupt event flow) ??좎뜦堉??
|
|
323
|
-
// e.stopPropagation();
|
|
324
|
-
// ??좎뜦堉??[Change] ??좎뜦堉??
|
|
325
|
-
|
|
326
|
-
// ??좎뜦堉??[Change] Default is 'none', but only apply when not handled by children ??좎뜦堉??
|
|
327
|
-
// (If MindMapDnD handles it, this code won't run or will be ignored)
|
|
328
|
-
// e.dataTransfer.dropEffect = 'none';
|
|
329
|
-
}, false);
|
|
330
|
-
|
|
331
|
-
document.addEventListener('dragleave', (e) => {
|
|
332
|
-
e.preventDefault();
|
|
333
|
-
// e.stopPropagation(); // removed
|
|
334
|
-
}, false);
|
|
335
|
-
|
|
336
|
-
document.addEventListener('drop', (e) => {
|
|
337
|
-
e.preventDefault();
|
|
338
|
-
// e.stopPropagation(); // removed
|
|
339
|
-
}, false);
|
|
340
|
-
</script>
|
|
341
|
-
|
|
342
|
-
<!-- Paddle.js -->
|
|
343
|
-
<script src="https://cdn.paddle.com/paddle/v2/paddle.js"></script>
|
|
344
|
-
|
|
345
|
-
<!-- App scripts and libs REQUIRED before Blazor starts -->
|
|
346
|
-
<script>
|
|
347
|
-
window.mindExecutionStartupTiming = window.mindExecutionStartupTiming || (() => {
|
|
348
|
-
const perf = window.performance;
|
|
349
|
-
const now = () => perf && typeof perf.now === 'function'
|
|
350
|
-
? perf.now()
|
|
351
|
-
: Date.now();
|
|
352
|
-
const marks = new Map();
|
|
353
|
-
const pageStart = now();
|
|
354
|
-
marks.set('page-start', pageStart);
|
|
355
|
-
|
|
356
|
-
function toDuration(value) {
|
|
357
|
-
return `${Math.round(value)}ms`;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function formatDetails(details) {
|
|
361
|
-
if (!details || typeof details !== 'object') {
|
|
362
|
-
return '';
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
const parts = Object.entries(details)
|
|
366
|
-
.filter(([, value]) => value !== undefined && value !== null && value !== '')
|
|
367
|
-
.map(([key, value]) => `${key}=${typeof value === 'number' ? Math.round(value) : value}`);
|
|
368
|
-
|
|
369
|
-
return parts.length > 0 ? ` | ${parts.join(', ')}` : '';
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
function elapsedSince(markName, currentNow) {
|
|
373
|
-
const startedAt = marks.get(markName);
|
|
374
|
-
return typeof startedAt === 'number' ? currentNow - startedAt : null;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
return {
|
|
378
|
-
mark(stage, details) {
|
|
379
|
-
const currentNow = now();
|
|
380
|
-
marks.set(stage, currentNow);
|
|
381
|
-
const pageElapsed = elapsedSince('page-start', currentNow) ?? 0;
|
|
382
|
-
try {
|
|
383
|
-
window.dispatchEvent(new CustomEvent(`startup-timing:${stage}`, {
|
|
384
|
-
detail: {
|
|
385
|
-
stage,
|
|
386
|
-
elapsedMs: Math.round(pageElapsed),
|
|
387
|
-
details: details || null
|
|
388
|
-
}
|
|
389
|
-
}));
|
|
390
|
-
} catch { }
|
|
391
|
-
console.log(`[Startup Timing] ${stage}: ${toDuration(pageElapsed)} since page start${formatDetails(details)}`);
|
|
392
|
-
return Math.round(pageElapsed);
|
|
393
|
-
},
|
|
394
|
-
logMindCanvasReady(details) {
|
|
395
|
-
const currentNow = now();
|
|
396
|
-
marks.set('mindcanvas-ready', currentNow);
|
|
397
|
-
|
|
398
|
-
const segments = [];
|
|
399
|
-
const pageElapsed = elapsedSince('page-start', currentNow);
|
|
400
|
-
const scriptLoaderElapsed = elapsedSince('script-loader-start', currentNow);
|
|
401
|
-
const blazorElapsed = elapsedSince('blazor-start', currentNow);
|
|
402
|
-
const bootstrapElapsed = elapsedSince('mindcanvas-bootstrap-start', currentNow);
|
|
403
|
-
const boardElapsed = elapsedSince('mindcanvas-board-load-start', currentNow);
|
|
404
|
-
|
|
405
|
-
if (pageElapsed !== null) segments.push(`page=${toDuration(pageElapsed)}`);
|
|
406
|
-
if (scriptLoaderElapsed !== null) segments.push(`scriptLoader=${toDuration(scriptLoaderElapsed)}`);
|
|
407
|
-
if (blazorElapsed !== null) segments.push(`blazor=${toDuration(blazorElapsed)}`);
|
|
408
|
-
if (bootstrapElapsed !== null) segments.push(`bootstrap=${toDuration(bootstrapElapsed)}`);
|
|
409
|
-
if (boardElapsed !== null) segments.push(`board=${toDuration(boardElapsed)}`);
|
|
410
|
-
|
|
411
|
-
try {
|
|
412
|
-
window.dispatchEvent(new CustomEvent('startup-timing:mindcanvas-ready', {
|
|
413
|
-
detail: {
|
|
414
|
-
stage: 'mindcanvas-ready',
|
|
415
|
-
elapsedMs: Math.round(pageElapsed ?? 0),
|
|
416
|
-
details: details || null
|
|
417
|
-
}
|
|
418
|
-
}));
|
|
419
|
-
} catch { }
|
|
420
|
-
|
|
421
|
-
console.log(`[Startup Timing] MindCanvas ready: ${segments.join(' | ')}${formatDetails(details)}`);
|
|
422
|
-
return Math.round(pageElapsed ?? 0);
|
|
423
|
-
}
|
|
424
|
-
};
|
|
425
|
-
})();
|
|
426
|
-
window.mindExecutionStartupTiming.mark('index-html-ready', {
|
|
427
|
-
route: window.location.pathname || '/'
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
window.__marketingToolHosts = [
|
|
431
|
-
'mdview.pages.dev', 'mdview.mindexec.io', 'markdown-viewer.pages.dev', 'markdown-viewer.mindexec.io',
|
|
432
|
-
'bulkmd.pages.dev', 'bulkmd.mindexec.io', 'bulk-markdown-viewer.pages.dev', 'bulk-markdown-viewer.mindexec.io',
|
|
433
|
-
'mdoutln.pages.dev', 'mdoutln.mindexec.io', 'markdown-outline.pages.dev', 'markdown-outline.mindexec.io',
|
|
434
|
-
'mdtable.pages.dev', 'mdtable.mindexec.io', 'markdown-table-formatter.pages.dev', 'markdown-table-formatter.mindexec.io',
|
|
435
|
-
'readme.pages.dev', 'readme.mindexec.io', 'readme-previewer.pages.dev', 'readme-previewer.mindexec.io',
|
|
436
|
-
'md2html.pages.dev', 'md2html.mindexec.io', 'markdown-to-html.pages.dev', 'markdown-to-html.mindexec.io',
|
|
437
|
-
'mdcheck.pages.dev', 'mdcheck.mindexec.io', 'markdown-link-checker.pages.dev', 'markdown-link-checker.mindexec.io',
|
|
438
|
-
'quickpad.pages.dev', 'quickpad.mindexec.io', 'browser-notepad.pages.dev', 'browser-notepad.mindexec.io',
|
|
439
|
-
'clipbrd.pages.dev', 'clipbrd.mindexec.io', 'clipboard-board.pages.dev', 'clipboard-board.mindexec.io'
|
|
440
|
-
];
|
|
441
|
-
|
|
442
|
-
window.__matchesMarketingToolHost = function (configuredHost, runtimeHost) {
|
|
443
|
-
if (!configuredHost || !runtimeHost) {
|
|
444
|
-
return false;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
const normalizedConfiguredHost = configuredHost.toLowerCase();
|
|
448
|
-
const normalizedRuntimeHost = runtimeHost.toLowerCase();
|
|
449
|
-
if (normalizedConfiguredHost === normalizedRuntimeHost) {
|
|
450
|
-
return true;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
if (!normalizedConfiguredHost.endsWith('.pages.dev') || !normalizedRuntimeHost.endsWith('.pages.dev')) {
|
|
454
|
-
return false;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
const configuredPrefix = normalizedConfiguredHost.slice(0, -'.pages.dev'.length);
|
|
458
|
-
const runtimePrefix = normalizedRuntimeHost.slice(0, -'.pages.dev'.length);
|
|
459
|
-
return runtimePrefix === configuredPrefix || runtimePrefix.startsWith(`${configuredPrefix}-`);
|
|
460
|
-
};
|
|
461
|
-
|
|
462
|
-
window.__isMarketingToolHost = window.__marketingToolHosts.some(host =>
|
|
463
|
-
window.__matchesMarketingToolHost(host, location.host || '')
|
|
464
|
-
);
|
|
465
|
-
</script>
|
|
466
|
-
<!-- ??좎뜦堉??[Upgrade] Three.js r168 via ESM ??좎뜦堉??-->
|
|
467
|
-
<script type="importmap">
|
|
468
|
-
{
|
|
469
|
-
"imports": {
|
|
470
|
-
"three": "https://cdn.jsdelivr.net/npm/three@0.168.0/build/three.module.js"
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
</script>
|
|
474
|
-
<script type="module">
|
|
475
|
-
if (!window.__isMarketingToolHost) {
|
|
476
|
-
const THREE = await import('three');
|
|
477
|
-
|
|
478
|
-
window.THREE = THREE;
|
|
479
|
-
globalThis.THREE = THREE;
|
|
480
|
-
console.log('[Three.js] r' + THREE.REVISION + ' loaded (ESM ??global)');
|
|
481
|
-
|
|
482
|
-
window.THREE_LOADED = true;
|
|
483
|
-
window.dispatchEvent(new Event('three-loaded'));
|
|
484
|
-
} else {
|
|
485
|
-
console.log('[Script Loader] Marketing tool host detected. Skipping Three.js preload.');
|
|
486
|
-
}
|
|
487
|
-
</script>
|
|
488
|
-
<!-- Wait for THREE then load dependent scripts -->
|
|
489
|
-
<script>
|
|
490
|
-
function loadScript(src, options = {}) {
|
|
491
|
-
const SCRIPT_LOAD_TIMEOUT_MS = 15000;
|
|
492
|
-
const SCRIPT_LOAD_SLOW_MS = 3000;
|
|
493
|
-
window.__mindExecutionScriptLoaderState = window.__mindExecutionScriptLoaderState || {
|
|
494
|
-
pending: {},
|
|
495
|
-
completed: [],
|
|
496
|
-
lastError: null
|
|
497
|
-
};
|
|
498
|
-
|
|
499
|
-
const label = options.label || src;
|
|
500
|
-
const startAt = performance.now();
|
|
501
|
-
window.__mindExecutionScriptLoaderState.pending[label] = {
|
|
502
|
-
src,
|
|
503
|
-
label,
|
|
504
|
-
startedAt: startAt
|
|
505
|
-
};
|
|
506
|
-
|
|
507
|
-
return new Promise((resolve, reject) => {
|
|
508
|
-
const s = document.createElement('script');
|
|
509
|
-
s.src = src;
|
|
510
|
-
if (options.ordered === true) {
|
|
511
|
-
// Ordered dynamic scripts still fetch in parallel, but execute in append order.
|
|
512
|
-
s.async = false;
|
|
513
|
-
}
|
|
514
|
-
if (options.fetchPriority) {
|
|
515
|
-
s.fetchPriority = options.fetchPriority;
|
|
516
|
-
}
|
|
517
|
-
let finished = false;
|
|
518
|
-
const complete = (kind, error = null) => {
|
|
519
|
-
if (finished) return;
|
|
520
|
-
finished = true;
|
|
521
|
-
clearTimeout(timeoutHandle);
|
|
522
|
-
|
|
523
|
-
const elapsedMs = Math.max(0, performance.now() - startAt);
|
|
524
|
-
delete window.__mindExecutionScriptLoaderState.pending[label];
|
|
525
|
-
|
|
526
|
-
if (kind === 'load') {
|
|
527
|
-
window.__mindExecutionScriptLoaderState.completed.push({
|
|
528
|
-
label,
|
|
529
|
-
elapsedMs: Math.round(elapsedMs),
|
|
530
|
-
loadedAt: Date.now()
|
|
531
|
-
});
|
|
532
|
-
if (elapsedMs >= SCRIPT_LOAD_SLOW_MS) {
|
|
533
|
-
console.warn(`[Script Loader] Slow script load: ${label} (${elapsedMs.toFixed(0)}ms)`);
|
|
534
|
-
}
|
|
535
|
-
resolve();
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
const pendingLabels = Object.keys(window.__mindExecutionScriptLoaderState.pending || {});
|
|
540
|
-
const failure = error instanceof Error
|
|
541
|
-
? error
|
|
542
|
-
: new Error(String(error || `Failed to load script: ${label}`));
|
|
543
|
-
window.__mindExecutionScriptLoaderState.lastError = {
|
|
544
|
-
label,
|
|
545
|
-
src,
|
|
546
|
-
kind,
|
|
547
|
-
elapsedMs: Math.round(elapsedMs),
|
|
548
|
-
pending: pendingLabels,
|
|
549
|
-
message: failure.message
|
|
550
|
-
};
|
|
551
|
-
reject(failure);
|
|
552
|
-
};
|
|
553
|
-
|
|
554
|
-
const timeoutHandle = setTimeout(() => {
|
|
555
|
-
const pendingLabels = Object.keys(window.__mindExecutionScriptLoaderState.pending || {});
|
|
556
|
-
complete('timeout', new Error(`[Script Loader] Timeout waiting for ${label} after ${SCRIPT_LOAD_TIMEOUT_MS}ms | pending=${pendingLabels.join(', ') || '-'}`));
|
|
557
|
-
}, options.timeoutMs || SCRIPT_LOAD_TIMEOUT_MS);
|
|
558
|
-
|
|
559
|
-
s.onload = () => complete('load');
|
|
560
|
-
s.onerror = () => complete('error', new Error(`[Script Loader] Failed to load ${label}`));
|
|
561
|
-
document.head.appendChild(s);
|
|
562
|
-
});
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
function loadScriptBatchOrdered(scripts, scriptUrl, onLoaded) {
|
|
566
|
-
const scriptPromises = [];
|
|
567
|
-
|
|
568
|
-
for (const script of scripts) {
|
|
569
|
-
const promise = loadScript(scriptUrl(script), {
|
|
570
|
-
ordered: true,
|
|
571
|
-
fetchPriority: 'high',
|
|
572
|
-
label: script
|
|
573
|
-
}).then(() => {
|
|
574
|
-
onLoaded?.(script);
|
|
575
|
-
});
|
|
576
|
-
|
|
577
|
-
scriptPromises.push(promise);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
return Promise.all(scriptPromises);
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
async function loadDependentScripts() {
|
|
584
|
-
window.mindExecutionStartupTiming?.mark('script-loader-start', {
|
|
585
|
-
route: window.location.pathname || '/'
|
|
586
|
-
});
|
|
587
|
-
|
|
588
|
-
if (window.__isMarketingToolHost) {
|
|
589
|
-
console.log('[Script Loader] Marketing tool host detected. Skipping MindMap script bundle.');
|
|
590
|
-
|
|
591
|
-
try {
|
|
592
|
-
if (window.__swCleanup) {
|
|
593
|
-
const cleaned = await window.__swCleanup;
|
|
594
|
-
const flag = '__swCleanedOnce';
|
|
595
|
-
if (cleaned && !sessionStorage.getItem(flag)) {
|
|
596
|
-
sessionStorage.setItem(flag, '1');
|
|
597
|
-
location.reload();
|
|
598
|
-
return;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
} catch { }
|
|
602
|
-
|
|
603
|
-
if (window.Blazor && Blazor.start) {
|
|
604
|
-
window.mindExecutionStartupTiming?.mark('blazor-start', { marketingToolHost: true });
|
|
605
|
-
await Blazor.start();
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
return;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// Wait for THREE to be available
|
|
612
|
-
if (!window.THREE_LOADED) {
|
|
613
|
-
await new Promise(r => window.addEventListener('three-loaded', r, { once: true }));
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
const base = '_content/MindExecution.Shared/js/';
|
|
617
|
-
const scriptVersion = '20260822-particle-60fps-motion-v983';
|
|
618
|
-
const scriptUrl = (script) => `${base}${script}?v=${scriptVersion}`;
|
|
619
|
-
console.log(`[Script Loader] Shared JS version: ${scriptVersion}`);
|
|
620
|
-
const criticalScripts = [
|
|
621
|
-
'mind-map-dev-guards.js',
|
|
622
|
-
'renderers/CSS3DRenderer.js',
|
|
623
|
-
'helpers/InfiniteGridHelper.js',
|
|
624
|
-
'marked.min.js',
|
|
625
|
-
'background-themes.js',
|
|
626
|
-
'mind-map-logic-workers.js',
|
|
627
|
-
// Troika removed
|
|
628
|
-
'texture-worker-manager.js', // ??Web Worker ??좎럩?ゅ뜝???좎럩苑?
|
|
629
|
-
'mind-map-texture-factory.js',
|
|
630
|
-
'mind-map-glow-shader.js', // ??SDF Glow (no textures, GPU only)
|
|
631
|
-
'mind-map-video-playback-controls.js',
|
|
632
|
-
'mind-map-remote-codecs.js',
|
|
633
|
-
'mind-map-css3d-hotpath.js',
|
|
634
|
-
'mind-map-image-policy.js',
|
|
635
|
-
'mind-map-automation-edge-motion.js',
|
|
636
|
-
'mind-map-css3d-manager.js',
|
|
637
|
-
'mind-map-object-manager.js',
|
|
638
|
-
'mind-map-pipeline.js',
|
|
639
|
-
'mind-map-nodes.js',
|
|
640
|
-
'mind-map-animated-image-preview.js',
|
|
641
|
-
'mind-map-menu-manager.js',
|
|
642
|
-
'mind-map-multi-select.js',
|
|
643
|
-
'mind-map-interactions.js',
|
|
644
|
-
'mind-map-dnd.js',
|
|
645
|
-
'mind-map-board-render-ownership.js',
|
|
646
|
-
'mind-map-render-plan.js',
|
|
647
|
-
'mind-map-normal-boundary-optimizer.js',
|
|
648
|
-
'mind-map-lod-video-placeholder.js',
|
|
649
|
-
'mind-map-lod-renderer.js',
|
|
650
|
-
'mind-map-text-lod-system.js', // ??Text LOD ??좎럩???(??좎럩????좎럩?ゅ뜝???좎럩彛?
|
|
651
|
-
'mind-map-core.js',
|
|
652
|
-
'mindmap-toolbar.js',
|
|
653
|
-
'token-manager.js',
|
|
654
|
-
'file-system-helper.js'
|
|
655
|
-
];
|
|
656
|
-
const routePath = (location.pathname || '/').toLowerCase();
|
|
657
|
-
const routeCriticalScripts = [];
|
|
658
|
-
if (routePath === '/code' || routePath === '/agent') {
|
|
659
|
-
routeCriticalScripts.push('code-master.js', 'agent-visualization.js');
|
|
660
|
-
}
|
|
661
|
-
if (routePath === '/planmaster' || routePath === '/planagent') {
|
|
662
|
-
routeCriticalScripts.push('plan-master.js');
|
|
663
|
-
}
|
|
664
|
-
const deferredScripts = ['plan-master.js', 'code-master.js', 'agent-visualization.js']
|
|
665
|
-
.filter(script => !routeCriticalScripts.includes(script));
|
|
666
|
-
|
|
667
|
-
function queueAgentSettings(globalName, pendingKey) {
|
|
668
|
-
if (window[globalName]) return;
|
|
669
|
-
window[globalName] = {
|
|
670
|
-
applySettings(settings) {
|
|
671
|
-
window[pendingKey] = Object.assign({}, window[pendingKey] || {}, settings || {});
|
|
672
|
-
}
|
|
673
|
-
};
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
function flushQueuedAgentSettings(script) {
|
|
677
|
-
const mappings = {
|
|
678
|
-
'plan-master.js': ['planAgent', '__pendingPlanAgentSettings'],
|
|
679
|
-
'code-master.js': ['codeAgent', '__pendingCodeAgentSettings']
|
|
680
|
-
};
|
|
681
|
-
const mapping = mappings[script];
|
|
682
|
-
if (!mapping) return;
|
|
683
|
-
|
|
684
|
-
const [globalName, pendingKey] = mapping;
|
|
685
|
-
const pending = window[pendingKey];
|
|
686
|
-
if (pending && window[globalName]?.applySettings) {
|
|
687
|
-
window[pendingKey] = null;
|
|
688
|
-
window[globalName].applySettings(pending);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
queueAgentSettings('planAgent', '__pendingPlanAgentSettings');
|
|
693
|
-
queueAgentSettings('codeAgent', '__pendingCodeAgentSettings');
|
|
694
|
-
|
|
695
|
-
await loadScriptBatchOrdered(
|
|
696
|
-
[...criticalScripts, ...routeCriticalScripts],
|
|
697
|
-
scriptUrl,
|
|
698
|
-
flushQueuedAgentSettings
|
|
699
|
-
);
|
|
700
|
-
|
|
701
|
-
window.MindCanvasBuildInfo?.setRuntime?.('scriptVersion', scriptVersion);
|
|
702
|
-
window.MindCanvasBuildInfo?.validateRequiredParts?.(['devGuards', 'renderPlan', 'normalBoundaryOptimizer', 'core', 'lodRenderer']);
|
|
703
|
-
|
|
704
|
-
console.log('[Script Loader] Critical scripts loaded, starting Blazor...');
|
|
705
|
-
window.mindExecutionStartupTiming?.mark('critical-scripts-loaded', {
|
|
706
|
-
criticalCount: criticalScripts.length + routeCriticalScripts.length
|
|
707
|
-
});
|
|
708
|
-
|
|
709
|
-
// SW cleanup
|
|
710
|
-
try {
|
|
711
|
-
if (window.__swCleanup) {
|
|
712
|
-
const cleaned = await window.__swCleanup;
|
|
713
|
-
const flag = '__swCleanedOnce';
|
|
714
|
-
if (cleaned && !sessionStorage.getItem(flag)) {
|
|
715
|
-
sessionStorage.setItem(flag, '1');
|
|
716
|
-
location.reload();
|
|
717
|
-
return;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
} catch { }
|
|
721
|
-
|
|
722
|
-
// Start Blazor
|
|
723
|
-
if (window.Blazor && Blazor.start) {
|
|
724
|
-
window.mindExecutionStartupTiming?.mark('blazor-start', { marketingToolHost: false });
|
|
725
|
-
await Blazor.start();
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
const scheduleDeferredScripts = window.requestIdleCallback
|
|
729
|
-
? ((callback) => window.requestIdleCallback(callback, { timeout: 1500 }))
|
|
730
|
-
: ((callback) => setTimeout(callback, 0));
|
|
731
|
-
|
|
732
|
-
const loadDeferredScriptsNow = () => {
|
|
733
|
-
scheduleDeferredScripts(() => {
|
|
734
|
-
(async () => {
|
|
735
|
-
await loadScriptBatchOrdered(
|
|
736
|
-
deferredScripts,
|
|
737
|
-
scriptUrl,
|
|
738
|
-
flushQueuedAgentSettings
|
|
739
|
-
);
|
|
740
|
-
console.log('[Script Loader] Deferred scripts loaded.');
|
|
741
|
-
window.mindExecutionStartupTiming?.mark('deferred-scripts-loaded', {
|
|
742
|
-
deferredCount: deferredScripts.length
|
|
743
|
-
});
|
|
744
|
-
})().catch(e => console.error('[Script Loader] Deferred load failed:', e));
|
|
745
|
-
});
|
|
746
|
-
};
|
|
747
|
-
|
|
748
|
-
if (routePath === '/mindcanvas' && deferredScripts.length > 0) {
|
|
749
|
-
let deferredStarted = false;
|
|
750
|
-
const startDeferredAfterMindCanvasReady = () => {
|
|
751
|
-
if (deferredStarted) return;
|
|
752
|
-
deferredStarted = true;
|
|
753
|
-
loadDeferredScriptsNow();
|
|
754
|
-
};
|
|
755
|
-
|
|
756
|
-
window.addEventListener('startup-timing:mindcanvas-ready', startDeferredAfterMindCanvasReady, { once: true });
|
|
757
|
-
setTimeout(startDeferredAfterMindCanvasReady, 20000);
|
|
758
|
-
} else {
|
|
759
|
-
loadDeferredScriptsNow();
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
// Start loading
|
|
764
|
-
loadDependentScripts().catch(e => {
|
|
765
|
-
console.error('[Script Loader] Failed:', e);
|
|
766
|
-
window.showBlazorBootError('The page could not finish loading. Reload and try again.');
|
|
767
|
-
});
|
|
768
|
-
</script>
|
|
769
|
-
<!-- ??좎뜦堉??[Upgrade] ??좎뜦堉??-->
|
|
770
|
-
</body>
|
|
771
|
-
|
|
772
|
-
</html>
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>MindExec | Business Execution OS for solo builders</title>
|
|
8
|
+
<meta name="description" content="MindExec is an AI business execution OS for solo builders who want to turn notes, research, assets, and repeatable execution Skills into revenue-producing work." />
|
|
9
|
+
<base href="/" />
|
|
10
|
+
<meta name="theme-color" content="#f8fafc" />
|
|
11
|
+
<link rel="icon" type="image/png" sizes="32x32" href="/mindexec-favicon-v3.png" />
|
|
12
|
+
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png?v=20260815-app-icon-v2" />
|
|
13
|
+
<link rel="manifest" href="manifest.webmanifest?v=20260815-app-icon-v2" />
|
|
14
|
+
<link rel="stylesheet" href="_content/MindExecution.Shared/css/app.css?v=20260629-ai-task-flow-v863" />
|
|
15
|
+
<link rel="stylesheet" href="_content/MindExecution.Shared/css/mind-map-overrides.css?v=20260822-selection-unified-v857" />
|
|
16
|
+
<!-- ??좎뜦堉??Font Awesome (local) ??좎뜦堉??-->
|
|
17
|
+
<link rel="stylesheet" href="_content/MindExecution.Shared/lib/font-awesome/css/all.min.css" />
|
|
18
|
+
<!-- ??좎뜦堉??-->
|
|
19
|
+
<style>
|
|
20
|
+
html,
|
|
21
|
+
body {
|
|
22
|
+
margin: 0;
|
|
23
|
+
background: #f8fafc;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#app {
|
|
27
|
+
min-height: 100vh;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.app-static-fallback {
|
|
31
|
+
position: fixed;
|
|
32
|
+
inset: 0;
|
|
33
|
+
z-index: 10;
|
|
34
|
+
box-sizing: border-box;
|
|
35
|
+
display: flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
width: 100%;
|
|
39
|
+
margin: 0;
|
|
40
|
+
padding: 24px;
|
|
41
|
+
background: #f8fafc;
|
|
42
|
+
color: #64748b;
|
|
43
|
+
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.app-loading-shell {
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
align-items: center;
|
|
50
|
+
gap: 14px;
|
|
51
|
+
text-align: center;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.app-loading-shell__logo {
|
|
55
|
+
display: block;
|
|
56
|
+
width: 44px;
|
|
57
|
+
height: 44px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.app-loading-spinner {
|
|
61
|
+
box-sizing: border-box;
|
|
62
|
+
width: 34px;
|
|
63
|
+
height: 34px;
|
|
64
|
+
border: 3px solid #dbe5f0;
|
|
65
|
+
border-top-color: #2563eb;
|
|
66
|
+
border-radius: 50%;
|
|
67
|
+
animation: app-loading-spin 720ms linear infinite;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.app-loading-shell__label,
|
|
71
|
+
.app-loading-shell__noscript {
|
|
72
|
+
margin: 0;
|
|
73
|
+
font-size: 13px;
|
|
74
|
+
line-height: 1.4;
|
|
75
|
+
font-weight: 600;
|
|
76
|
+
letter-spacing: 0.01em;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@keyframes app-loading-spin {
|
|
80
|
+
to {
|
|
81
|
+
transform: rotate(360deg);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@media (prefers-reduced-motion: reduce) {
|
|
86
|
+
.app-loading-spinner {
|
|
87
|
+
animation-duration: 1600ms;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
#blazor-error-ui {
|
|
92
|
+
display: none;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
#blazor-error-ui.is-visible {
|
|
96
|
+
position: fixed;
|
|
97
|
+
right: 20px;
|
|
98
|
+
bottom: 20px;
|
|
99
|
+
z-index: 9999;
|
|
100
|
+
display: flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
gap: 12px;
|
|
103
|
+
max-width: 420px;
|
|
104
|
+
padding: 14px 16px;
|
|
105
|
+
border-radius: 14px;
|
|
106
|
+
background: rgba(15, 23, 42, 0.96);
|
|
107
|
+
color: #fff;
|
|
108
|
+
box-shadow: 0 18px 48px rgba(15, 23, 42, 0.28);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.blazor-error-ui__message {
|
|
112
|
+
flex: 1;
|
|
113
|
+
font-size: 14px;
|
|
114
|
+
line-height: 1.6;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
#blazor-error-ui .reload,
|
|
118
|
+
#blazor-error-ui .dismiss {
|
|
119
|
+
color: #fff;
|
|
120
|
+
font-size: 13px;
|
|
121
|
+
font-weight: 700;
|
|
122
|
+
text-decoration: none;
|
|
123
|
+
cursor: pointer;
|
|
124
|
+
}
|
|
125
|
+
</style>
|
|
126
|
+
</head>
|
|
127
|
+
|
|
128
|
+
<body>
|
|
129
|
+
<div id="app-container">
|
|
130
|
+
<div id="app">
|
|
131
|
+
<article class="app-static-fallback" id="app-static-fallback">
|
|
132
|
+
<div class="app-loading-shell" role="status" aria-live="polite" aria-label="Loading MindCanvas">
|
|
133
|
+
<img class="app-loading-shell__logo" src="icon-192.png?v=20260815-app-icon-v2" alt="" aria-hidden="true" />
|
|
134
|
+
<div class="app-loading-spinner" aria-hidden="true"></div>
|
|
135
|
+
<p class="app-loading-shell__label">Loading MindCanvas…</p>
|
|
136
|
+
<noscript>
|
|
137
|
+
<p class="app-loading-shell__noscript">JavaScript is required to start MindCanvas.</p>
|
|
138
|
+
</noscript>
|
|
139
|
+
</div>
|
|
140
|
+
</article>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
<div id="three-js-container"
|
|
145
|
+
style="display: none; position: fixed; top:0; left:0; width:100%; height:100%; z-index:999; background-color: rgba(0,0,0,0.5);">
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<!-- Selection rectangle overlay -->
|
|
149
|
+
<div id="selection-rectangle"
|
|
150
|
+
style="position: fixed; border:2px solid #1173d4; background-color: rgba(17, 115, 212, 0.15); pointer-events: none; display: none; z-index:100;">
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<div id="blazor-error-ui" role="alert" aria-live="assertive">
|
|
154
|
+
<div class="blazor-error-ui__message"></div>
|
|
155
|
+
<a href="." class="reload">Reload</a>
|
|
156
|
+
<span class="dismiss">Dismiss</span>
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
<!-- Aggressively remove any existing service workers and caches so hosted deploys pick up new JS immediately -->
|
|
160
|
+
<script>
|
|
161
|
+
window.__swCleanup = (async () => {
|
|
162
|
+
try {
|
|
163
|
+
let hadAnything = false;
|
|
164
|
+
if ('serviceWorker' in navigator) {
|
|
165
|
+
const regs = await navigator.serviceWorker.getRegistrations();
|
|
166
|
+
hadAnything = hadAnything || regs.length > 0;
|
|
167
|
+
await Promise.allSettled(regs.map(r => r.unregister()));
|
|
168
|
+
}
|
|
169
|
+
if (window.caches) {
|
|
170
|
+
const keys = await caches.keys();
|
|
171
|
+
hadAnything = hadAnything || keys.length > 0;
|
|
172
|
+
await Promise.allSettled(keys.map(k => caches.delete(k)));
|
|
173
|
+
}
|
|
174
|
+
return hadAnything;
|
|
175
|
+
} catch (e) {
|
|
176
|
+
console.debug('SW cleanup skipped:', e);
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
})();
|
|
180
|
+
</script>
|
|
181
|
+
|
|
182
|
+
<!-- Blazor WASM loader (autostart disabled; we'll start after our scripts load) -->
|
|
183
|
+
<script src="_framework/blazor.webassembly.js" autostart="false"></script>
|
|
184
|
+
|
|
185
|
+
<!-- Global helpers and libraries -->
|
|
186
|
+
<script src="js/marketing-tool.js"></script>
|
|
187
|
+
<script>
|
|
188
|
+
window.showBlazorBootError = function (message) {
|
|
189
|
+
const errorUi = document.getElementById('blazor-error-ui');
|
|
190
|
+
if (!errorUi) return;
|
|
191
|
+
|
|
192
|
+
const messageElement = errorUi.querySelector('.blazor-error-ui__message');
|
|
193
|
+
if (messageElement) {
|
|
194
|
+
messageElement.textContent = message || 'This page could not finish loading.';
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
errorUi.classList.add('is-visible');
|
|
198
|
+
errorUi.removeAttribute('hidden');
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
window.hideBlazorBootError = function () {
|
|
202
|
+
const errorUi = document.getElementById('blazor-error-ui');
|
|
203
|
+
if (!errorUi) return;
|
|
204
|
+
errorUi.classList.remove('is-visible');
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
document.addEventListener('click', (event) => {
|
|
208
|
+
const target = event.target;
|
|
209
|
+
if (target instanceof HTMLElement && target.classList.contains('dismiss')) {
|
|
210
|
+
window.hideBlazorBootError();
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Global textarea handlers
|
|
215
|
+
function adjustTextareaHeight(element) {
|
|
216
|
+
if (!element) return;
|
|
217
|
+
|
|
218
|
+
// ??좎뜦堉??[Change] Add jitter-prevention logic ??좎뜦堉??
|
|
219
|
+
// Compare the previous text length. When content grows, skip the 'auto' reset.
|
|
220
|
+
// Only reset to 'auto' when shrinking (during deletion).
|
|
221
|
+
const currentLength = element.value.length;
|
|
222
|
+
const prevLength = parseInt(element.dataset.prevLength || '0');
|
|
223
|
+
|
|
224
|
+
if (currentLength < prevLength) {
|
|
225
|
+
element.style.height = 'auto'; // reset height when deleting to allow shrink
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
element.dataset.prevLength = currentLength; // store current length
|
|
229
|
+
// ??좎뜦堉??[Change] ??좎뜦堉??
|
|
230
|
+
|
|
231
|
+
const computedStyles = window.getComputedStyle(element);
|
|
232
|
+
const lineHeight = parseFloat(computedStyles.lineHeight || '24') || 24;
|
|
233
|
+
const paddingTop = parseFloat(computedStyles.paddingTop || '0') || 0;
|
|
234
|
+
const paddingBottom = parseFloat(computedStyles.paddingBottom || '0') || 0;
|
|
235
|
+
const verticalPadding = paddingTop + paddingBottom;
|
|
236
|
+
const maxLines = 6; // limit to 6 lines
|
|
237
|
+
const maxHeight = (lineHeight * maxLines) + verticalPadding;
|
|
238
|
+
const minHeightPx = Math.max(lineHeight + verticalPadding, 42);
|
|
239
|
+
|
|
240
|
+
const newHeight = Math.min(element.scrollHeight, maxHeight);
|
|
241
|
+
|
|
242
|
+
// Even if content didn't shrink, apply if scrollHeight grew
|
|
243
|
+
element.style.height = Math.max(newHeight, minHeightPx) + 'px';
|
|
244
|
+
element.style.overflowY = 'hidden';
|
|
245
|
+
}
|
|
246
|
+
function resetTextareaHeight(element) {
|
|
247
|
+
if (!element) return;
|
|
248
|
+
const computedStyles = window.getComputedStyle(element);
|
|
249
|
+
const lineHeight = parseFloat(computedStyles.lineHeight || '24') || 24;
|
|
250
|
+
const paddingTop = parseFloat(computedStyles.paddingTop || '0') || 0;
|
|
251
|
+
const paddingBottom = parseFloat(computedStyles.paddingBottom || '0') || 0;
|
|
252
|
+
const minHeightPx = Math.max(lineHeight + paddingTop + paddingBottom, 42);
|
|
253
|
+
element.style.height = minHeightPx + 'px';
|
|
254
|
+
element.style.overflowY = 'hidden';
|
|
255
|
+
}
|
|
256
|
+
function attachTextareaHandlers(element, dotNetRef) {
|
|
257
|
+
if (!element) return;
|
|
258
|
+
|
|
259
|
+
if (element.__mindexecEnterHandler) {
|
|
260
|
+
element.removeEventListener('keydown', element.__mindexecEnterHandler);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const handleKeyDown = (e) => {
|
|
264
|
+
if (e.key === 'Enter') {
|
|
265
|
+
if (e.shiftKey) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (e.repeat || e.isComposing || e.keyCode === 229) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
e.preventDefault();
|
|
274
|
+
const now = performance.now();
|
|
275
|
+
if (element.__mindexecLastEnterAt && now - element.__mindexecLastEnterAt < 650) {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const promptSnapshot = element.value || '';
|
|
280
|
+
if (!promptSnapshot.trim()) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
element.__mindexecLastEnterAt = now;
|
|
285
|
+
const submitId = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
286
|
+
element.value = '';
|
|
287
|
+
element.dispatchEvent(new Event('input', { bubbles: true }));
|
|
288
|
+
resetTextareaHeight(element);
|
|
289
|
+
|
|
290
|
+
if (dotNetRef && dotNetRef.invokeMethodAsync) {
|
|
291
|
+
dotNetRef.invokeMethodAsync('OnGlobalInputEnterPressed', promptSnapshot, submitId)
|
|
292
|
+
.catch((err) => console.warn('[GlobalInput] Enter submit failed:', err));
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
element.__mindexecEnterHandler = handleKeyDown;
|
|
298
|
+
element.addEventListener('keydown', handleKeyDown);
|
|
299
|
+
}
|
|
300
|
+
function blurElement(element) {
|
|
301
|
+
if (element) element.blur();
|
|
302
|
+
if (document && document.body) document.body.focus();
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function focusGlobalTextarea() {
|
|
306
|
+
const textarea = document.getElementById('global-input-textarea');
|
|
307
|
+
if (textarea) {
|
|
308
|
+
textarea.focus();
|
|
309
|
+
textarea.setSelectionRange(textarea.value.length, textarea.value.length);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
window.adjustTextareaHeight = adjustTextareaHeight;
|
|
314
|
+
window.resetTextareaHeight = resetTextareaHeight;
|
|
315
|
+
window.attachTextareaHandlers = attachTextareaHandlers;
|
|
316
|
+
window.blurElement = blurElement;
|
|
317
|
+
window.focusGlobalTextarea = focusGlobalTextarea;
|
|
318
|
+
|
|
319
|
+
// Prevent default page-level DnD behavior
|
|
320
|
+
document.addEventListener('dragover', (e) => {
|
|
321
|
+
e.preventDefault();
|
|
322
|
+
// ??좎뜦堉??[Change] Remove/avoid stopPropagation (do not disrupt event flow) ??좎뜦堉??
|
|
323
|
+
// e.stopPropagation();
|
|
324
|
+
// ??좎뜦堉??[Change] ??좎뜦堉??
|
|
325
|
+
|
|
326
|
+
// ??좎뜦堉??[Change] Default is 'none', but only apply when not handled by children ??좎뜦堉??
|
|
327
|
+
// (If MindMapDnD handles it, this code won't run or will be ignored)
|
|
328
|
+
// e.dataTransfer.dropEffect = 'none';
|
|
329
|
+
}, false);
|
|
330
|
+
|
|
331
|
+
document.addEventListener('dragleave', (e) => {
|
|
332
|
+
e.preventDefault();
|
|
333
|
+
// e.stopPropagation(); // removed
|
|
334
|
+
}, false);
|
|
335
|
+
|
|
336
|
+
document.addEventListener('drop', (e) => {
|
|
337
|
+
e.preventDefault();
|
|
338
|
+
// e.stopPropagation(); // removed
|
|
339
|
+
}, false);
|
|
340
|
+
</script>
|
|
341
|
+
|
|
342
|
+
<!-- Paddle.js -->
|
|
343
|
+
<script src="https://cdn.paddle.com/paddle/v2/paddle.js"></script>
|
|
344
|
+
|
|
345
|
+
<!-- App scripts and libs REQUIRED before Blazor starts -->
|
|
346
|
+
<script>
|
|
347
|
+
window.mindExecutionStartupTiming = window.mindExecutionStartupTiming || (() => {
|
|
348
|
+
const perf = window.performance;
|
|
349
|
+
const now = () => perf && typeof perf.now === 'function'
|
|
350
|
+
? perf.now()
|
|
351
|
+
: Date.now();
|
|
352
|
+
const marks = new Map();
|
|
353
|
+
const pageStart = now();
|
|
354
|
+
marks.set('page-start', pageStart);
|
|
355
|
+
|
|
356
|
+
function toDuration(value) {
|
|
357
|
+
return `${Math.round(value)}ms`;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function formatDetails(details) {
|
|
361
|
+
if (!details || typeof details !== 'object') {
|
|
362
|
+
return '';
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const parts = Object.entries(details)
|
|
366
|
+
.filter(([, value]) => value !== undefined && value !== null && value !== '')
|
|
367
|
+
.map(([key, value]) => `${key}=${typeof value === 'number' ? Math.round(value) : value}`);
|
|
368
|
+
|
|
369
|
+
return parts.length > 0 ? ` | ${parts.join(', ')}` : '';
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function elapsedSince(markName, currentNow) {
|
|
373
|
+
const startedAt = marks.get(markName);
|
|
374
|
+
return typeof startedAt === 'number' ? currentNow - startedAt : null;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return {
|
|
378
|
+
mark(stage, details) {
|
|
379
|
+
const currentNow = now();
|
|
380
|
+
marks.set(stage, currentNow);
|
|
381
|
+
const pageElapsed = elapsedSince('page-start', currentNow) ?? 0;
|
|
382
|
+
try {
|
|
383
|
+
window.dispatchEvent(new CustomEvent(`startup-timing:${stage}`, {
|
|
384
|
+
detail: {
|
|
385
|
+
stage,
|
|
386
|
+
elapsedMs: Math.round(pageElapsed),
|
|
387
|
+
details: details || null
|
|
388
|
+
}
|
|
389
|
+
}));
|
|
390
|
+
} catch { }
|
|
391
|
+
console.log(`[Startup Timing] ${stage}: ${toDuration(pageElapsed)} since page start${formatDetails(details)}`);
|
|
392
|
+
return Math.round(pageElapsed);
|
|
393
|
+
},
|
|
394
|
+
logMindCanvasReady(details) {
|
|
395
|
+
const currentNow = now();
|
|
396
|
+
marks.set('mindcanvas-ready', currentNow);
|
|
397
|
+
|
|
398
|
+
const segments = [];
|
|
399
|
+
const pageElapsed = elapsedSince('page-start', currentNow);
|
|
400
|
+
const scriptLoaderElapsed = elapsedSince('script-loader-start', currentNow);
|
|
401
|
+
const blazorElapsed = elapsedSince('blazor-start', currentNow);
|
|
402
|
+
const bootstrapElapsed = elapsedSince('mindcanvas-bootstrap-start', currentNow);
|
|
403
|
+
const boardElapsed = elapsedSince('mindcanvas-board-load-start', currentNow);
|
|
404
|
+
|
|
405
|
+
if (pageElapsed !== null) segments.push(`page=${toDuration(pageElapsed)}`);
|
|
406
|
+
if (scriptLoaderElapsed !== null) segments.push(`scriptLoader=${toDuration(scriptLoaderElapsed)}`);
|
|
407
|
+
if (blazorElapsed !== null) segments.push(`blazor=${toDuration(blazorElapsed)}`);
|
|
408
|
+
if (bootstrapElapsed !== null) segments.push(`bootstrap=${toDuration(bootstrapElapsed)}`);
|
|
409
|
+
if (boardElapsed !== null) segments.push(`board=${toDuration(boardElapsed)}`);
|
|
410
|
+
|
|
411
|
+
try {
|
|
412
|
+
window.dispatchEvent(new CustomEvent('startup-timing:mindcanvas-ready', {
|
|
413
|
+
detail: {
|
|
414
|
+
stage: 'mindcanvas-ready',
|
|
415
|
+
elapsedMs: Math.round(pageElapsed ?? 0),
|
|
416
|
+
details: details || null
|
|
417
|
+
}
|
|
418
|
+
}));
|
|
419
|
+
} catch { }
|
|
420
|
+
|
|
421
|
+
console.log(`[Startup Timing] MindCanvas ready: ${segments.join(' | ')}${formatDetails(details)}`);
|
|
422
|
+
return Math.round(pageElapsed ?? 0);
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
})();
|
|
426
|
+
window.mindExecutionStartupTiming.mark('index-html-ready', {
|
|
427
|
+
route: window.location.pathname || '/'
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
window.__marketingToolHosts = [
|
|
431
|
+
'mdview.pages.dev', 'mdview.mindexec.io', 'markdown-viewer.pages.dev', 'markdown-viewer.mindexec.io',
|
|
432
|
+
'bulkmd.pages.dev', 'bulkmd.mindexec.io', 'bulk-markdown-viewer.pages.dev', 'bulk-markdown-viewer.mindexec.io',
|
|
433
|
+
'mdoutln.pages.dev', 'mdoutln.mindexec.io', 'markdown-outline.pages.dev', 'markdown-outline.mindexec.io',
|
|
434
|
+
'mdtable.pages.dev', 'mdtable.mindexec.io', 'markdown-table-formatter.pages.dev', 'markdown-table-formatter.mindexec.io',
|
|
435
|
+
'readme.pages.dev', 'readme.mindexec.io', 'readme-previewer.pages.dev', 'readme-previewer.mindexec.io',
|
|
436
|
+
'md2html.pages.dev', 'md2html.mindexec.io', 'markdown-to-html.pages.dev', 'markdown-to-html.mindexec.io',
|
|
437
|
+
'mdcheck.pages.dev', 'mdcheck.mindexec.io', 'markdown-link-checker.pages.dev', 'markdown-link-checker.mindexec.io',
|
|
438
|
+
'quickpad.pages.dev', 'quickpad.mindexec.io', 'browser-notepad.pages.dev', 'browser-notepad.mindexec.io',
|
|
439
|
+
'clipbrd.pages.dev', 'clipbrd.mindexec.io', 'clipboard-board.pages.dev', 'clipboard-board.mindexec.io'
|
|
440
|
+
];
|
|
441
|
+
|
|
442
|
+
window.__matchesMarketingToolHost = function (configuredHost, runtimeHost) {
|
|
443
|
+
if (!configuredHost || !runtimeHost) {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
const normalizedConfiguredHost = configuredHost.toLowerCase();
|
|
448
|
+
const normalizedRuntimeHost = runtimeHost.toLowerCase();
|
|
449
|
+
if (normalizedConfiguredHost === normalizedRuntimeHost) {
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
if (!normalizedConfiguredHost.endsWith('.pages.dev') || !normalizedRuntimeHost.endsWith('.pages.dev')) {
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
const configuredPrefix = normalizedConfiguredHost.slice(0, -'.pages.dev'.length);
|
|
458
|
+
const runtimePrefix = normalizedRuntimeHost.slice(0, -'.pages.dev'.length);
|
|
459
|
+
return runtimePrefix === configuredPrefix || runtimePrefix.startsWith(`${configuredPrefix}-`);
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
window.__isMarketingToolHost = window.__marketingToolHosts.some(host =>
|
|
463
|
+
window.__matchesMarketingToolHost(host, location.host || '')
|
|
464
|
+
);
|
|
465
|
+
</script>
|
|
466
|
+
<!-- ??좎뜦堉??[Upgrade] Three.js r168 via ESM ??좎뜦堉??-->
|
|
467
|
+
<script type="importmap">
|
|
468
|
+
{
|
|
469
|
+
"imports": {
|
|
470
|
+
"three": "https://cdn.jsdelivr.net/npm/three@0.168.0/build/three.module.js"
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
</script>
|
|
474
|
+
<script type="module">
|
|
475
|
+
if (!window.__isMarketingToolHost) {
|
|
476
|
+
const THREE = await import('three');
|
|
477
|
+
|
|
478
|
+
window.THREE = THREE;
|
|
479
|
+
globalThis.THREE = THREE;
|
|
480
|
+
console.log('[Three.js] r' + THREE.REVISION + ' loaded (ESM ??global)');
|
|
481
|
+
|
|
482
|
+
window.THREE_LOADED = true;
|
|
483
|
+
window.dispatchEvent(new Event('three-loaded'));
|
|
484
|
+
} else {
|
|
485
|
+
console.log('[Script Loader] Marketing tool host detected. Skipping Three.js preload.');
|
|
486
|
+
}
|
|
487
|
+
</script>
|
|
488
|
+
<!-- Wait for THREE then load dependent scripts -->
|
|
489
|
+
<script>
|
|
490
|
+
function loadScript(src, options = {}) {
|
|
491
|
+
const SCRIPT_LOAD_TIMEOUT_MS = 15000;
|
|
492
|
+
const SCRIPT_LOAD_SLOW_MS = 3000;
|
|
493
|
+
window.__mindExecutionScriptLoaderState = window.__mindExecutionScriptLoaderState || {
|
|
494
|
+
pending: {},
|
|
495
|
+
completed: [],
|
|
496
|
+
lastError: null
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
const label = options.label || src;
|
|
500
|
+
const startAt = performance.now();
|
|
501
|
+
window.__mindExecutionScriptLoaderState.pending[label] = {
|
|
502
|
+
src,
|
|
503
|
+
label,
|
|
504
|
+
startedAt: startAt
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
return new Promise((resolve, reject) => {
|
|
508
|
+
const s = document.createElement('script');
|
|
509
|
+
s.src = src;
|
|
510
|
+
if (options.ordered === true) {
|
|
511
|
+
// Ordered dynamic scripts still fetch in parallel, but execute in append order.
|
|
512
|
+
s.async = false;
|
|
513
|
+
}
|
|
514
|
+
if (options.fetchPriority) {
|
|
515
|
+
s.fetchPriority = options.fetchPriority;
|
|
516
|
+
}
|
|
517
|
+
let finished = false;
|
|
518
|
+
const complete = (kind, error = null) => {
|
|
519
|
+
if (finished) return;
|
|
520
|
+
finished = true;
|
|
521
|
+
clearTimeout(timeoutHandle);
|
|
522
|
+
|
|
523
|
+
const elapsedMs = Math.max(0, performance.now() - startAt);
|
|
524
|
+
delete window.__mindExecutionScriptLoaderState.pending[label];
|
|
525
|
+
|
|
526
|
+
if (kind === 'load') {
|
|
527
|
+
window.__mindExecutionScriptLoaderState.completed.push({
|
|
528
|
+
label,
|
|
529
|
+
elapsedMs: Math.round(elapsedMs),
|
|
530
|
+
loadedAt: Date.now()
|
|
531
|
+
});
|
|
532
|
+
if (elapsedMs >= SCRIPT_LOAD_SLOW_MS) {
|
|
533
|
+
console.warn(`[Script Loader] Slow script load: ${label} (${elapsedMs.toFixed(0)}ms)`);
|
|
534
|
+
}
|
|
535
|
+
resolve();
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const pendingLabels = Object.keys(window.__mindExecutionScriptLoaderState.pending || {});
|
|
540
|
+
const failure = error instanceof Error
|
|
541
|
+
? error
|
|
542
|
+
: new Error(String(error || `Failed to load script: ${label}`));
|
|
543
|
+
window.__mindExecutionScriptLoaderState.lastError = {
|
|
544
|
+
label,
|
|
545
|
+
src,
|
|
546
|
+
kind,
|
|
547
|
+
elapsedMs: Math.round(elapsedMs),
|
|
548
|
+
pending: pendingLabels,
|
|
549
|
+
message: failure.message
|
|
550
|
+
};
|
|
551
|
+
reject(failure);
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
const timeoutHandle = setTimeout(() => {
|
|
555
|
+
const pendingLabels = Object.keys(window.__mindExecutionScriptLoaderState.pending || {});
|
|
556
|
+
complete('timeout', new Error(`[Script Loader] Timeout waiting for ${label} after ${SCRIPT_LOAD_TIMEOUT_MS}ms | pending=${pendingLabels.join(', ') || '-'}`));
|
|
557
|
+
}, options.timeoutMs || SCRIPT_LOAD_TIMEOUT_MS);
|
|
558
|
+
|
|
559
|
+
s.onload = () => complete('load');
|
|
560
|
+
s.onerror = () => complete('error', new Error(`[Script Loader] Failed to load ${label}`));
|
|
561
|
+
document.head.appendChild(s);
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
function loadScriptBatchOrdered(scripts, scriptUrl, onLoaded) {
|
|
566
|
+
const scriptPromises = [];
|
|
567
|
+
|
|
568
|
+
for (const script of scripts) {
|
|
569
|
+
const promise = loadScript(scriptUrl(script), {
|
|
570
|
+
ordered: true,
|
|
571
|
+
fetchPriority: 'high',
|
|
572
|
+
label: script
|
|
573
|
+
}).then(() => {
|
|
574
|
+
onLoaded?.(script);
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
scriptPromises.push(promise);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
return Promise.all(scriptPromises);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
async function loadDependentScripts() {
|
|
584
|
+
window.mindExecutionStartupTiming?.mark('script-loader-start', {
|
|
585
|
+
route: window.location.pathname || '/'
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
if (window.__isMarketingToolHost) {
|
|
589
|
+
console.log('[Script Loader] Marketing tool host detected. Skipping MindMap script bundle.');
|
|
590
|
+
|
|
591
|
+
try {
|
|
592
|
+
if (window.__swCleanup) {
|
|
593
|
+
const cleaned = await window.__swCleanup;
|
|
594
|
+
const flag = '__swCleanedOnce';
|
|
595
|
+
if (cleaned && !sessionStorage.getItem(flag)) {
|
|
596
|
+
sessionStorage.setItem(flag, '1');
|
|
597
|
+
location.reload();
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
} catch { }
|
|
602
|
+
|
|
603
|
+
if (window.Blazor && Blazor.start) {
|
|
604
|
+
window.mindExecutionStartupTiming?.mark('blazor-start', { marketingToolHost: true });
|
|
605
|
+
await Blazor.start();
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Wait for THREE to be available
|
|
612
|
+
if (!window.THREE_LOADED) {
|
|
613
|
+
await new Promise(r => window.addEventListener('three-loaded', r, { once: true }));
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const base = '_content/MindExecution.Shared/js/';
|
|
617
|
+
const scriptVersion = '20260822-particle-60fps-motion-v983';
|
|
618
|
+
const scriptUrl = (script) => `${base}${script}?v=${scriptVersion}`;
|
|
619
|
+
console.log(`[Script Loader] Shared JS version: ${scriptVersion}`);
|
|
620
|
+
const criticalScripts = [
|
|
621
|
+
'mind-map-dev-guards.js',
|
|
622
|
+
'renderers/CSS3DRenderer.js',
|
|
623
|
+
'helpers/InfiniteGridHelper.js',
|
|
624
|
+
'marked.min.js',
|
|
625
|
+
'background-themes.js',
|
|
626
|
+
'mind-map-logic-workers.js',
|
|
627
|
+
// Troika removed
|
|
628
|
+
'texture-worker-manager.js', // ??Web Worker ??좎럩?ゅ뜝???좎럩苑?
|
|
629
|
+
'mind-map-texture-factory.js',
|
|
630
|
+
'mind-map-glow-shader.js', // ??SDF Glow (no textures, GPU only)
|
|
631
|
+
'mind-map-video-playback-controls.js',
|
|
632
|
+
'mind-map-remote-codecs.js',
|
|
633
|
+
'mind-map-css3d-hotpath.js',
|
|
634
|
+
'mind-map-image-policy.js',
|
|
635
|
+
'mind-map-automation-edge-motion.js',
|
|
636
|
+
'mind-map-css3d-manager.js',
|
|
637
|
+
'mind-map-object-manager.js',
|
|
638
|
+
'mind-map-pipeline.js',
|
|
639
|
+
'mind-map-nodes.js',
|
|
640
|
+
'mind-map-animated-image-preview.js',
|
|
641
|
+
'mind-map-menu-manager.js',
|
|
642
|
+
'mind-map-multi-select.js',
|
|
643
|
+
'mind-map-interactions.js',
|
|
644
|
+
'mind-map-dnd.js',
|
|
645
|
+
'mind-map-board-render-ownership.js',
|
|
646
|
+
'mind-map-render-plan.js',
|
|
647
|
+
'mind-map-normal-boundary-optimizer.js',
|
|
648
|
+
'mind-map-lod-video-placeholder.js',
|
|
649
|
+
'mind-map-lod-renderer.js',
|
|
650
|
+
'mind-map-text-lod-system.js', // ??Text LOD ??좎럩???(??좎럩????좎럩?ゅ뜝???좎럩彛?
|
|
651
|
+
'mind-map-core.js',
|
|
652
|
+
'mindmap-toolbar.js',
|
|
653
|
+
'token-manager.js',
|
|
654
|
+
'file-system-helper.js'
|
|
655
|
+
];
|
|
656
|
+
const routePath = (location.pathname || '/').toLowerCase();
|
|
657
|
+
const routeCriticalScripts = [];
|
|
658
|
+
if (routePath === '/code' || routePath === '/agent') {
|
|
659
|
+
routeCriticalScripts.push('code-master.js', 'agent-visualization.js');
|
|
660
|
+
}
|
|
661
|
+
if (routePath === '/planmaster' || routePath === '/planagent') {
|
|
662
|
+
routeCriticalScripts.push('plan-master.js');
|
|
663
|
+
}
|
|
664
|
+
const deferredScripts = ['plan-master.js', 'code-master.js', 'agent-visualization.js']
|
|
665
|
+
.filter(script => !routeCriticalScripts.includes(script));
|
|
666
|
+
|
|
667
|
+
function queueAgentSettings(globalName, pendingKey) {
|
|
668
|
+
if (window[globalName]) return;
|
|
669
|
+
window[globalName] = {
|
|
670
|
+
applySettings(settings) {
|
|
671
|
+
window[pendingKey] = Object.assign({}, window[pendingKey] || {}, settings || {});
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
function flushQueuedAgentSettings(script) {
|
|
677
|
+
const mappings = {
|
|
678
|
+
'plan-master.js': ['planAgent', '__pendingPlanAgentSettings'],
|
|
679
|
+
'code-master.js': ['codeAgent', '__pendingCodeAgentSettings']
|
|
680
|
+
};
|
|
681
|
+
const mapping = mappings[script];
|
|
682
|
+
if (!mapping) return;
|
|
683
|
+
|
|
684
|
+
const [globalName, pendingKey] = mapping;
|
|
685
|
+
const pending = window[pendingKey];
|
|
686
|
+
if (pending && window[globalName]?.applySettings) {
|
|
687
|
+
window[pendingKey] = null;
|
|
688
|
+
window[globalName].applySettings(pending);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
queueAgentSettings('planAgent', '__pendingPlanAgentSettings');
|
|
693
|
+
queueAgentSettings('codeAgent', '__pendingCodeAgentSettings');
|
|
694
|
+
|
|
695
|
+
await loadScriptBatchOrdered(
|
|
696
|
+
[...criticalScripts, ...routeCriticalScripts],
|
|
697
|
+
scriptUrl,
|
|
698
|
+
flushQueuedAgentSettings
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
window.MindCanvasBuildInfo?.setRuntime?.('scriptVersion', scriptVersion);
|
|
702
|
+
window.MindCanvasBuildInfo?.validateRequiredParts?.(['devGuards', 'renderPlan', 'normalBoundaryOptimizer', 'core', 'lodRenderer']);
|
|
703
|
+
|
|
704
|
+
console.log('[Script Loader] Critical scripts loaded, starting Blazor...');
|
|
705
|
+
window.mindExecutionStartupTiming?.mark('critical-scripts-loaded', {
|
|
706
|
+
criticalCount: criticalScripts.length + routeCriticalScripts.length
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
// SW cleanup
|
|
710
|
+
try {
|
|
711
|
+
if (window.__swCleanup) {
|
|
712
|
+
const cleaned = await window.__swCleanup;
|
|
713
|
+
const flag = '__swCleanedOnce';
|
|
714
|
+
if (cleaned && !sessionStorage.getItem(flag)) {
|
|
715
|
+
sessionStorage.setItem(flag, '1');
|
|
716
|
+
location.reload();
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
} catch { }
|
|
721
|
+
|
|
722
|
+
// Start Blazor
|
|
723
|
+
if (window.Blazor && Blazor.start) {
|
|
724
|
+
window.mindExecutionStartupTiming?.mark('blazor-start', { marketingToolHost: false });
|
|
725
|
+
await Blazor.start();
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
const scheduleDeferredScripts = window.requestIdleCallback
|
|
729
|
+
? ((callback) => window.requestIdleCallback(callback, { timeout: 1500 }))
|
|
730
|
+
: ((callback) => setTimeout(callback, 0));
|
|
731
|
+
|
|
732
|
+
const loadDeferredScriptsNow = () => {
|
|
733
|
+
scheduleDeferredScripts(() => {
|
|
734
|
+
(async () => {
|
|
735
|
+
await loadScriptBatchOrdered(
|
|
736
|
+
deferredScripts,
|
|
737
|
+
scriptUrl,
|
|
738
|
+
flushQueuedAgentSettings
|
|
739
|
+
);
|
|
740
|
+
console.log('[Script Loader] Deferred scripts loaded.');
|
|
741
|
+
window.mindExecutionStartupTiming?.mark('deferred-scripts-loaded', {
|
|
742
|
+
deferredCount: deferredScripts.length
|
|
743
|
+
});
|
|
744
|
+
})().catch(e => console.error('[Script Loader] Deferred load failed:', e));
|
|
745
|
+
});
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
if (routePath === '/mindcanvas' && deferredScripts.length > 0) {
|
|
749
|
+
let deferredStarted = false;
|
|
750
|
+
const startDeferredAfterMindCanvasReady = () => {
|
|
751
|
+
if (deferredStarted) return;
|
|
752
|
+
deferredStarted = true;
|
|
753
|
+
loadDeferredScriptsNow();
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
window.addEventListener('startup-timing:mindcanvas-ready', startDeferredAfterMindCanvasReady, { once: true });
|
|
757
|
+
setTimeout(startDeferredAfterMindCanvasReady, 20000);
|
|
758
|
+
} else {
|
|
759
|
+
loadDeferredScriptsNow();
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// Start loading
|
|
764
|
+
loadDependentScripts().catch(e => {
|
|
765
|
+
console.error('[Script Loader] Failed:', e);
|
|
766
|
+
window.showBlazorBootError('The page could not finish loading. Reload and try again.');
|
|
767
|
+
});
|
|
768
|
+
</script>
|
|
769
|
+
<!-- ??좎뜦堉??[Upgrade] ??좎뜦堉??-->
|
|
770
|
+
</body>
|
|
771
|
+
|
|
772
|
+
</html>
|