@mindexec/cli 0.2.101 → 0.2.103
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/package.json +2 -2
- package/remote-hub.js +51 -2
- package/scripts/remote-hub-smoke.mjs +8 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +446 -19
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js +64 -3
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +10 -7
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-renderer.js +3 -2
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-node-search-worker.js +1 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-nodes.js +3 -2
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-pipeline.js +9 -2
- package/wwwroot/_framework/MindExecution.Core.fc9cjbjplq.dll +0 -0
- package/wwwroot/_framework/{MindExecution.Kernel.7k773jan4j.dll → MindExecution.Kernel.pbzp3jfync.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Admin.nr5ioavpvn.dll → MindExecution.Plugins.Admin.gxzwlji1cf.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Business.qq63kom73x.dll → MindExecution.Plugins.Business.vtaey8c59y.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Concept.w4znwcrl6x.dll → MindExecution.Plugins.Concept.ksc3wkuptm.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Directory.u6p6pxpwxp.dll → MindExecution.Plugins.Directory.zc8ffaoknd.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.0w4vr40lnz.dll → MindExecution.Plugins.PlanMaster.flzcb87jvl.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.YouTube.sdl5n9uv68.dll → MindExecution.Plugins.YouTube.q4tvods1po.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Shared.6us6j8zcea.dll → MindExecution.Shared.jv6r2n1bvg.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Web.xhlvm1d8ex.dll → MindExecution.Web.3b8az6ed0q.dll} +0 -0
- package/wwwroot/_framework/blazor.boot.json +21 -21
- package/wwwroot/index.html +3 -3
- package/wwwroot/service-worker-assets.js +30 -30
- package/wwwroot/service-worker.js +1 -1
- package/wwwroot/_framework/MindExecution.Core.cdplo34sb2.dll +0 -0
|
@@ -29,6 +29,9 @@
|
|
|
29
29
|
let _cssImageDisplayPumpScheduled = false;
|
|
30
30
|
const CSS_VIDEO_PROXY_MAX_DEVICE_PIXEL_RATIO = 2;
|
|
31
31
|
const VIDEO_PLAYBACK_INTENT_METADATA_KEY = 'VideoPlaybackIntent';
|
|
32
|
+
const CSV_TABLE_CONTENT_TYPE = 'csv-table';
|
|
33
|
+
const CSV_TABLE_MAX_RENDER_ROWS = 500;
|
|
34
|
+
const CSV_TABLE_MAX_RENDER_COLUMNS = 80;
|
|
32
35
|
const REMOTE_FLEET_DISPLAY_NAME = 'Multi Desktop Monitor';
|
|
33
36
|
const REMOTE_FLEET_LEGACY_DISPLAY_NAME = 'Remote Fleet Monitor';
|
|
34
37
|
const _cssVideoProxyStateByVideo = new WeakMap();
|
|
@@ -53,6 +56,254 @@
|
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
syncMindCanvasPlatformRenderClasses();
|
|
59
|
+
|
|
60
|
+
function detectCsvDelimiter(csvText) {
|
|
61
|
+
const text = String(csvText || '');
|
|
62
|
+
const candidates = [',', '\t', ';', '|'];
|
|
63
|
+
const scores = new Map(candidates.map(candidate => [candidate, 0]));
|
|
64
|
+
let inQuotes = false;
|
|
65
|
+
let currentLine = 0;
|
|
66
|
+
|
|
67
|
+
for (let i = 0; i < text.length && currentLine < 12; i++) {
|
|
68
|
+
const ch = text[i];
|
|
69
|
+
const next = text[i + 1];
|
|
70
|
+
if (ch === '"') {
|
|
71
|
+
if (inQuotes && next === '"') {
|
|
72
|
+
i++;
|
|
73
|
+
} else {
|
|
74
|
+
inQuotes = !inQuotes;
|
|
75
|
+
}
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (!inQuotes && (ch === '\n' || ch === '\r')) {
|
|
79
|
+
currentLine++;
|
|
80
|
+
if (ch === '\r' && next === '\n') i++;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (!inQuotes && scores.has(ch)) {
|
|
84
|
+
scores.set(ch, scores.get(ch) + 1);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let best = ',';
|
|
89
|
+
let bestScore = -1;
|
|
90
|
+
scores.forEach((score, delimiter) => {
|
|
91
|
+
if (score > bestScore) {
|
|
92
|
+
best = delimiter;
|
|
93
|
+
bestScore = score;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return best;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function parseCsvRows(csvText, options = {}) {
|
|
100
|
+
const text = String(csvText || '');
|
|
101
|
+
if (!text) {
|
|
102
|
+
return { rows: [], delimiter: options.delimiter || ',', truncatedRows: false };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const delimiter = options.delimiter || detectCsvDelimiter(text);
|
|
106
|
+
const maxRows = Math.max(1, Number(options.maxRows || 1000));
|
|
107
|
+
const maxColumns = Math.max(1, Number(options.maxColumns || 200));
|
|
108
|
+
const rows = [];
|
|
109
|
+
let row = [];
|
|
110
|
+
let cell = '';
|
|
111
|
+
let inQuotes = false;
|
|
112
|
+
let truncatedRows = false;
|
|
113
|
+
|
|
114
|
+
const pushCell = () => {
|
|
115
|
+
if (row.length < maxColumns) {
|
|
116
|
+
row.push(cell);
|
|
117
|
+
}
|
|
118
|
+
cell = '';
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const pushRow = () => {
|
|
122
|
+
pushCell();
|
|
123
|
+
if (row.length > 1 || String(row[0] || '').length > 0) {
|
|
124
|
+
if (rows.length < maxRows) {
|
|
125
|
+
rows.push(row);
|
|
126
|
+
} else {
|
|
127
|
+
truncatedRows = true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
row = [];
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
for (let i = 0; i < text.length; i++) {
|
|
134
|
+
const ch = text[i];
|
|
135
|
+
const next = text[i + 1];
|
|
136
|
+
|
|
137
|
+
if (ch === '"') {
|
|
138
|
+
if (inQuotes && next === '"') {
|
|
139
|
+
cell += '"';
|
|
140
|
+
i++;
|
|
141
|
+
} else {
|
|
142
|
+
inQuotes = !inQuotes;
|
|
143
|
+
}
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (!inQuotes && ch === delimiter) {
|
|
148
|
+
pushCell();
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (!inQuotes && (ch === '\n' || ch === '\r')) {
|
|
153
|
+
pushRow();
|
|
154
|
+
if (ch === '\r' && next === '\n') i++;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
cell += ch;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (cell.length > 0 || row.length > 0 || text.endsWith(delimiter)) {
|
|
162
|
+
pushRow();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return { rows, delimiter, truncatedRows };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function summarizeCsv(csvText) {
|
|
169
|
+
const parsed = parseCsvRows(csvText, {
|
|
170
|
+
maxRows: 10001,
|
|
171
|
+
maxColumns: CSV_TABLE_MAX_RENDER_COLUMNS
|
|
172
|
+
});
|
|
173
|
+
const columnCount = parsed.rows.reduce((max, row) => Math.max(max, row.length), 0);
|
|
174
|
+
return {
|
|
175
|
+
rowCount: Math.max(0, parsed.rows.length - 1),
|
|
176
|
+
columnCount,
|
|
177
|
+
delimiter: parsed.delimiter,
|
|
178
|
+
truncatedRows: parsed.truncatedRows
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function compareCsvCells(a, b) {
|
|
183
|
+
const left = String(a ?? '').trim();
|
|
184
|
+
const right = String(b ?? '').trim();
|
|
185
|
+
const leftNumber = Number(left.replace(/,/g, ''));
|
|
186
|
+
const rightNumber = Number(right.replace(/,/g, ''));
|
|
187
|
+
if (left && right && Number.isFinite(leftNumber) && Number.isFinite(rightNumber)) {
|
|
188
|
+
return leftNumber - rightNumber;
|
|
189
|
+
}
|
|
190
|
+
return left.localeCompare(right, undefined, {
|
|
191
|
+
numeric: true,
|
|
192
|
+
sensitivity: 'base'
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function renderCsvTableContent(responseDiv, nodeModel, csvText) {
|
|
197
|
+
if (!(responseDiv instanceof HTMLElement)) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
responseDiv.innerHTML = '';
|
|
202
|
+
const parsed = parseCsvRows(csvText, {
|
|
203
|
+
maxRows: CSV_TABLE_MAX_RENDER_ROWS + 1,
|
|
204
|
+
maxColumns: CSV_TABLE_MAX_RENDER_COLUMNS
|
|
205
|
+
});
|
|
206
|
+
const rows = parsed.rows;
|
|
207
|
+
const columnCount = rows.reduce((max, row) => Math.max(max, row.length), 0);
|
|
208
|
+
|
|
209
|
+
if (columnCount === 0) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const headerRow = rows[0] || [];
|
|
214
|
+
const headers = Array.from({ length: columnCount }, (_, index) => {
|
|
215
|
+
const value = String(headerRow[index] ?? '').trim();
|
|
216
|
+
return value || `Column ${index + 1}`;
|
|
217
|
+
});
|
|
218
|
+
const dataRows = rows.slice(1).map((cells, index) => ({
|
|
219
|
+
cells,
|
|
220
|
+
originalIndex: index
|
|
221
|
+
}));
|
|
222
|
+
|
|
223
|
+
const table = document.createElement('table');
|
|
224
|
+
table.className = 'csv-table';
|
|
225
|
+
table.dataset.nodeId = nodeModel.id || nodeModel.Id || '';
|
|
226
|
+
|
|
227
|
+
const thead = document.createElement('thead');
|
|
228
|
+
const headerTr = document.createElement('tr');
|
|
229
|
+
const tbody = document.createElement('tbody');
|
|
230
|
+
let sortColumn = -1;
|
|
231
|
+
let sortDirection = 'asc';
|
|
232
|
+
|
|
233
|
+
const renderBody = () => {
|
|
234
|
+
tbody.innerHTML = '';
|
|
235
|
+
const nextRows = dataRows.slice();
|
|
236
|
+
if (sortColumn >= 0) {
|
|
237
|
+
nextRows.sort((a, b) => {
|
|
238
|
+
const result = compareCsvCells(a.cells[sortColumn], b.cells[sortColumn]);
|
|
239
|
+
if (result !== 0) {
|
|
240
|
+
return sortDirection === 'asc' ? result : -result;
|
|
241
|
+
}
|
|
242
|
+
return a.originalIndex - b.originalIndex;
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
nextRows.forEach(rowData => {
|
|
247
|
+
const tr = document.createElement('tr');
|
|
248
|
+
for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
|
|
249
|
+
const td = document.createElement('td');
|
|
250
|
+
td.className = 'csv-table-cell';
|
|
251
|
+
td.textContent = String(rowData.cells[columnIndex] ?? '');
|
|
252
|
+
tr.appendChild(td);
|
|
253
|
+
}
|
|
254
|
+
tbody.appendChild(tr);
|
|
255
|
+
});
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const updateHeaderSortState = () => {
|
|
259
|
+
headerTr.querySelectorAll('.csv-table-header-button').forEach((button, index) => {
|
|
260
|
+
const active = index === sortColumn;
|
|
261
|
+
button.dataset.sort = active ? sortDirection : '';
|
|
262
|
+
button.setAttribute('aria-sort', active ? (sortDirection === 'asc' ? 'ascending' : 'descending') : 'none');
|
|
263
|
+
});
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
headers.forEach((header, index) => {
|
|
267
|
+
const th = document.createElement('th');
|
|
268
|
+
const button = document.createElement('button');
|
|
269
|
+
button.type = 'button';
|
|
270
|
+
button.className = 'csv-table-header-button';
|
|
271
|
+
button.textContent = header;
|
|
272
|
+
button.dataset.columnIndex = String(index);
|
|
273
|
+
button.setAttribute('aria-sort', 'none');
|
|
274
|
+
button.addEventListener('mousedown', event => {
|
|
275
|
+
event.preventDefault();
|
|
276
|
+
event.stopPropagation();
|
|
277
|
+
});
|
|
278
|
+
button.addEventListener('click', event => {
|
|
279
|
+
event.preventDefault();
|
|
280
|
+
event.stopPropagation();
|
|
281
|
+
if (sortColumn === index) {
|
|
282
|
+
sortDirection = sortDirection === 'asc' ? 'desc' : 'asc';
|
|
283
|
+
} else {
|
|
284
|
+
sortColumn = index;
|
|
285
|
+
sortDirection = 'asc';
|
|
286
|
+
}
|
|
287
|
+
updateHeaderSortState();
|
|
288
|
+
renderBody();
|
|
289
|
+
});
|
|
290
|
+
th.appendChild(button);
|
|
291
|
+
headerTr.appendChild(th);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
thead.appendChild(headerTr);
|
|
295
|
+
table.appendChild(thead);
|
|
296
|
+
table.appendChild(tbody);
|
|
297
|
+
responseDiv.appendChild(table);
|
|
298
|
+
renderBody();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
window.MindMapCsvTable = {
|
|
302
|
+
detectCsvDelimiter,
|
|
303
|
+
parseCsvRows,
|
|
304
|
+
summarizeCsv,
|
|
305
|
+
renderCsvTableContent
|
|
306
|
+
};
|
|
56
307
|
// ▲▲▲ [Perf] ▲▲▲
|
|
57
308
|
|
|
58
309
|
// ▼▼▼ [New] 기본 마크다운 스타일 주입 ▼▼▼
|
|
@@ -98,11 +349,118 @@
|
|
|
98
349
|
.markdown-body a:hover { text-decoration: underline; }
|
|
99
350
|
.markdown-body img { max-width: 100%; box-sizing: content-box; background-color: #fff; }
|
|
100
351
|
.markdown-body table { border-spacing: 0; border-collapse: collapse; width: 100%; margin-bottom: 1em; }
|
|
101
|
-
.markdown-body table th, .markdown-body table td { padding: 6px 13px; border: 1px solid #dfe2e5; }
|
|
102
|
-
.markdown-body table th { font-weight: 600; background-color: #f6f8fa; }
|
|
103
|
-
.markdown-body hr { height: 0.25em; padding: 0; margin: 24px 0; background-color: #e1e4e8; border: 0; }
|
|
104
|
-
|
|
105
|
-
|
|
352
|
+
.markdown-body table th, .markdown-body table td { padding: 6px 13px; border: 1px solid #dfe2e5; }
|
|
353
|
+
.markdown-body table th { font-weight: 600; background-color: #f6f8fa; }
|
|
354
|
+
.markdown-body hr { height: 0.25em; padding: 0; margin: 24px 0; background-color: #e1e4e8; border: 0; }
|
|
355
|
+
.map-node-csv-table {
|
|
356
|
+
border: 1px solid rgba(203, 213, 225, 0.92);
|
|
357
|
+
box-shadow: 0 8px 24px rgba(15, 23, 42, 0.10);
|
|
358
|
+
}
|
|
359
|
+
.csv-table-scroll {
|
|
360
|
+
width: 100%;
|
|
361
|
+
height: 100%;
|
|
362
|
+
flex: 1 1 auto;
|
|
363
|
+
min-height: 0;
|
|
364
|
+
overflow: auto;
|
|
365
|
+
background: #ffffff;
|
|
366
|
+
border: 1px solid rgba(226, 232, 240, 0.96);
|
|
367
|
+
border-radius: 6px;
|
|
368
|
+
box-sizing: border-box;
|
|
369
|
+
scrollbar-width: thin;
|
|
370
|
+
scrollbar-color: rgba(100, 116, 139, 0.36) transparent;
|
|
371
|
+
pointer-events: auto;
|
|
372
|
+
padding-right: 0 !important;
|
|
373
|
+
user-select: text;
|
|
374
|
+
-webkit-user-select: text;
|
|
375
|
+
}
|
|
376
|
+
.csv-table-scroll::-webkit-scrollbar {
|
|
377
|
+
width: 8px;
|
|
378
|
+
height: 8px;
|
|
379
|
+
}
|
|
380
|
+
.csv-table-scroll::-webkit-scrollbar-thumb {
|
|
381
|
+
background: rgba(100, 116, 139, 0.34);
|
|
382
|
+
border-radius: 999px;
|
|
383
|
+
}
|
|
384
|
+
.csv-table-scroll:hover::-webkit-scrollbar-thumb {
|
|
385
|
+
background: rgba(71, 85, 105, 0.48);
|
|
386
|
+
}
|
|
387
|
+
.csv-table {
|
|
388
|
+
width: max-content;
|
|
389
|
+
min-width: 100%;
|
|
390
|
+
border-collapse: separate;
|
|
391
|
+
border-spacing: 0;
|
|
392
|
+
color: #111827;
|
|
393
|
+
font-size: 12px;
|
|
394
|
+
line-height: 1.45;
|
|
395
|
+
}
|
|
396
|
+
.csv-table th {
|
|
397
|
+
position: sticky;
|
|
398
|
+
top: 0;
|
|
399
|
+
z-index: 2;
|
|
400
|
+
padding: 0;
|
|
401
|
+
border-bottom: 1px solid #cbd5e1;
|
|
402
|
+
border-right: 1px solid #e2e8f0;
|
|
403
|
+
background: #f8fafc;
|
|
404
|
+
text-align: left;
|
|
405
|
+
white-space: nowrap;
|
|
406
|
+
}
|
|
407
|
+
.csv-table th:last-child,
|
|
408
|
+
.csv-table td:last-child {
|
|
409
|
+
border-right: 0;
|
|
410
|
+
}
|
|
411
|
+
.csv-table-header-button {
|
|
412
|
+
width: 100%;
|
|
413
|
+
min-width: 88px;
|
|
414
|
+
border: 0;
|
|
415
|
+
background: transparent;
|
|
416
|
+
color: #334155;
|
|
417
|
+
cursor: pointer;
|
|
418
|
+
display: flex;
|
|
419
|
+
align-items: center;
|
|
420
|
+
justify-content: space-between;
|
|
421
|
+
gap: 10px;
|
|
422
|
+
padding: 8px 10px;
|
|
423
|
+
font: inherit;
|
|
424
|
+
font-weight: 700;
|
|
425
|
+
text-align: left;
|
|
426
|
+
white-space: nowrap;
|
|
427
|
+
}
|
|
428
|
+
.csv-table-header-button::after {
|
|
429
|
+
content: "";
|
|
430
|
+
width: 0;
|
|
431
|
+
height: 0;
|
|
432
|
+
border-left: 4px solid transparent;
|
|
433
|
+
border-right: 4px solid transparent;
|
|
434
|
+
opacity: 0.38;
|
|
435
|
+
}
|
|
436
|
+
.csv-table-header-button[data-sort="asc"]::after {
|
|
437
|
+
border-bottom: 6px solid #2563eb;
|
|
438
|
+
opacity: 1;
|
|
439
|
+
}
|
|
440
|
+
.csv-table-header-button[data-sort="desc"]::after {
|
|
441
|
+
border-top: 6px solid #2563eb;
|
|
442
|
+
opacity: 1;
|
|
443
|
+
}
|
|
444
|
+
.csv-table-header-button:hover,
|
|
445
|
+
.csv-table-header-button:focus-visible {
|
|
446
|
+
background: #eef2ff;
|
|
447
|
+
outline: none;
|
|
448
|
+
}
|
|
449
|
+
.csv-table td {
|
|
450
|
+
max-width: 280px;
|
|
451
|
+
padding: 7px 10px;
|
|
452
|
+
border-right: 1px solid #eef2f7;
|
|
453
|
+
border-bottom: 1px solid #eef2f7;
|
|
454
|
+
overflow: hidden;
|
|
455
|
+
text-overflow: ellipsis;
|
|
456
|
+
white-space: nowrap;
|
|
457
|
+
background: #ffffff;
|
|
458
|
+
}
|
|
459
|
+
.csv-table tr:nth-child(even) td {
|
|
460
|
+
background: #fbfdff;
|
|
461
|
+
}
|
|
462
|
+
/* Force list markers to be visible */
|
|
463
|
+
.markdown-body ul li { list-style-type: disc; }
|
|
106
464
|
.markdown-body ol li { list-style-type: decimal; }
|
|
107
465
|
|
|
108
466
|
/* ▼▼▼ [NEW] 슬림 스크롤바 스타일 - 모든 텍스트/노트/코드 영역 (Razor + JS 동적노드 전체) ▼▼▼ */
|
|
@@ -3514,14 +3872,15 @@
|
|
|
3514
3872
|
const CSS3D_WRAPPER_WEBKIT_TRANSITION = '-webkit-box-shadow .22s ease, -webkit-filter .22s ease';
|
|
3515
3873
|
const TEXT_OVERLAY_SUPPORTED_TYPES = new Set(['text', 'markdown', 'note', 'code', 'memo']);
|
|
3516
3874
|
const TEXT_SELECTION_OVERLAY_SUPPORTED_TYPES = new Set(['text', 'markdown']);
|
|
3517
|
-
const TEXT_INTERACTION_SCROLLABLE_SELECTORS = '.node-response, .note-content, .markdown-body, .prose, .note-textarea, .code-body, .code-content, .pdf-content, .text-content, .file-content, .map-node-memo__body, .map-node-memo__body-view, .map-node-memo__agent-plan-body, .map-node-memo__agent-console-body, pre, code';
|
|
3518
|
-
const TEXT_INTERACTION_CONTENT_SELECTORS = '.node-response, .code-body, .text-content, .markdown-body, .prose';
|
|
3875
|
+
const TEXT_INTERACTION_SCROLLABLE_SELECTORS = '.node-response, .note-content, .markdown-body, .prose, .note-textarea, .code-body, .code-content, .csv-table-scroll, .csv-table-scroll *, .pdf-content, .text-content, .file-content, .map-node-memo__body, .map-node-memo__body-view, .map-node-memo__agent-plan-body, .map-node-memo__agent-console-body, pre, code';
|
|
3876
|
+
const TEXT_INTERACTION_CONTENT_SELECTORS = '.node-response, .code-body, .text-content, .markdown-body, .prose, .csv-table-scroll, .csv-table-cell';
|
|
3519
3877
|
const TEXT_OVERLAY_SCROLL_SYNC_SELECTORS = [
|
|
3520
3878
|
'.node-response',
|
|
3521
3879
|
'.note-content',
|
|
3522
3880
|
'.markdown-body',
|
|
3523
3881
|
'.prose',
|
|
3524
3882
|
'.code-body',
|
|
3883
|
+
'.csv-table-scroll',
|
|
3525
3884
|
'.note-textarea',
|
|
3526
3885
|
'.map-node-memo__body',
|
|
3527
3886
|
'.map-node-memo__body-view',
|
|
@@ -3625,7 +3984,7 @@
|
|
|
3625
3984
|
}
|
|
3626
3985
|
|
|
3627
3986
|
const contentType = String(nodeModel?.contentType ?? nodeModel?.ContentType ?? '').trim().toLowerCase();
|
|
3628
|
-
return ['memo', 'note', 'text', 'markdown', 'code', 'embed', 'pdf', 'image', 'video'].includes(contentType);
|
|
3987
|
+
return ['memo', 'note', 'text', 'markdown', 'code', CSV_TABLE_CONTENT_TYPE, 'embed', 'pdf', 'image', 'video'].includes(contentType);
|
|
3629
3988
|
}
|
|
3630
3989
|
|
|
3631
3990
|
function isAgentStyledMemoNode(nodeModel) {
|
|
@@ -13278,7 +13637,10 @@
|
|
|
13278
13637
|
frameUrl: source,
|
|
13279
13638
|
receivedAt: String(readRemoteFleetObjectField(frame, 'receivedAt', 'ReceivedAt', '') || '').trim(),
|
|
13280
13639
|
capturedAt: String(readRemoteFleetObjectField(frame, 'capturedAt', 'CapturedAt', '') || '').trim(),
|
|
13281
|
-
streamId: String(readRemoteFleetObjectField(frame, 'streamId', 'StreamId', '') || '').trim()
|
|
13640
|
+
streamId: String(readRemoteFleetObjectField(frame, 'streamId', 'StreamId', '') || '').trim(),
|
|
13641
|
+
contentHash: String(readRemoteFleetObjectField(frame, 'contentHash', 'ContentHash', '') || '').trim(),
|
|
13642
|
+
captureMs: Number(readRemoteFleetObjectField(frame, 'captureMs', 'CaptureMs', 0)) || 0,
|
|
13643
|
+
sameContentStreak: Number(readRemoteFleetObjectField(frame, 'sameContentStreak', 'SameContentStreak', 0)) || 0
|
|
13282
13644
|
};
|
|
13283
13645
|
}
|
|
13284
13646
|
|
|
@@ -13551,7 +13913,10 @@
|
|
|
13551
13913
|
frameUrl: String(frame?.frameUrl || '').trim(),
|
|
13552
13914
|
receivedAt: String(frame?.receivedAt || '').trim(),
|
|
13553
13915
|
capturedAt: String(frame?.capturedAt || '').trim(),
|
|
13554
|
-
streamId: String(frame?.streamId || '').trim()
|
|
13916
|
+
streamId: String(frame?.streamId || '').trim(),
|
|
13917
|
+
contentHash: String(frame?.contentHash || '').trim(),
|
|
13918
|
+
captureMs: Number(frame?.captureMs || 0) || 0,
|
|
13919
|
+
sameContentStreak: Number(frame?.sameContentStreak || 0) || 0
|
|
13555
13920
|
};
|
|
13556
13921
|
}
|
|
13557
13922
|
|
|
@@ -13643,6 +14008,9 @@
|
|
|
13643
14008
|
preview.dataset.remoteFleetFrameSeq = String(nextSeq || 0);
|
|
13644
14009
|
preview.dataset.remoteFleetFrameUrl = frame.frameUrl;
|
|
13645
14010
|
preview.dataset.remoteFleetFrameAt = frame.receivedAt || frame.capturedAt || '';
|
|
14011
|
+
preview.dataset.remoteFleetFrameHash = frame.contentHash || '';
|
|
14012
|
+
preview.dataset.remoteFleetFrameCaptureMs = String(Number(frame.captureMs || 0) || 0);
|
|
14013
|
+
preview.dataset.remoteFleetFrameSameContentStreak = String(Number(frame.sameContentStreak || 0) || 0);
|
|
13646
14014
|
|
|
13647
14015
|
const placeholder = preview.querySelector('[data-remote-fleet-screen-placeholder="true"]');
|
|
13648
14016
|
if (placeholder) {
|
|
@@ -13679,6 +14047,9 @@
|
|
|
13679
14047
|
image.dataset.remoteFleetFrameKind = frame.kind;
|
|
13680
14048
|
image.dataset.remoteFleetFrameSeq = String(nextSeq || 0);
|
|
13681
14049
|
image.dataset.remoteFleetFrameUrl = frame.frameUrl;
|
|
14050
|
+
image.dataset.remoteFleetFrameHash = frame.contentHash || '';
|
|
14051
|
+
image.dataset.remoteFleetFrameCaptureMs = String(Number(frame.captureMs || 0) || 0);
|
|
14052
|
+
image.dataset.remoteFleetFrameSameContentStreak = String(Number(frame.sameContentStreak || 0) || 0);
|
|
13682
14053
|
image.loading = frame.kind === 'thumbnail' ? 'lazy' : 'eager';
|
|
13683
14054
|
image.style.display = 'block';
|
|
13684
14055
|
if (image.src !== frame.frameUrl) {
|
|
@@ -13879,6 +14250,36 @@
|
|
|
13879
14250
|
}
|
|
13880
14251
|
|
|
13881
14252
|
function applyRemoteFleetFramePatchToPreview(preview, frame) {
|
|
14253
|
+
if (String(frame?.kind || '').toLowerCase() === 'live') {
|
|
14254
|
+
if (!preview || !isRemoteFleetFrameNewerForPreview(preview, frame, false)) {
|
|
14255
|
+
return false;
|
|
14256
|
+
}
|
|
14257
|
+
|
|
14258
|
+
const image = ensureRemoteFleetFrameImage(preview, frame);
|
|
14259
|
+
if (!image) {
|
|
14260
|
+
return false;
|
|
14261
|
+
}
|
|
14262
|
+
|
|
14263
|
+
preview._remoteFleetPendingFrame = null;
|
|
14264
|
+
delete preview.dataset.remoteFleetPendingFrameKind;
|
|
14265
|
+
delete preview.dataset.remoteFleetPendingFrameSeq;
|
|
14266
|
+
delete preview.dataset.remoteFleetPendingFrameUrl;
|
|
14267
|
+
|
|
14268
|
+
const committed = commitRemoteFleetFrameToPreview(preview, image, cloneRemoteFleetFramePatch(frame));
|
|
14269
|
+
if (committed) {
|
|
14270
|
+
window.RuntimeTrace?.emit?.('remote.frame.uiPatched', {
|
|
14271
|
+
count: 1,
|
|
14272
|
+
kind: frame.kind,
|
|
14273
|
+
seq: frame.frameSeq,
|
|
14274
|
+
surface: 'img-direct-live',
|
|
14275
|
+
contentHash: frame.contentHash || '',
|
|
14276
|
+
sameContentStreak: Number(frame.sameContentStreak || 0) || 0,
|
|
14277
|
+
captureMs: Number(frame.captureMs || 0) || 0
|
|
14278
|
+
});
|
|
14279
|
+
}
|
|
14280
|
+
return committed;
|
|
14281
|
+
}
|
|
14282
|
+
|
|
13882
14283
|
return queueRemoteFleetFramePaint(preview, frame);
|
|
13883
14284
|
}
|
|
13884
14285
|
|
|
@@ -19154,7 +19555,8 @@
|
|
|
19154
19555
|
const hasContent = !!(`${content}`.trim());
|
|
19155
19556
|
const defaultPrompts = ['Note', 'Pasted Text', '에이전트 메모'];
|
|
19156
19557
|
const shouldShowPrompt = !!prompt && !defaultPrompts.includes(prompt);
|
|
19157
|
-
const
|
|
19558
|
+
const isCsvTableNode = contentTypeLower === CSV_TABLE_CONTENT_TYPE;
|
|
19559
|
+
const isTextualCardNode = ['note', 'code', 'text', 'markdown', CSV_TABLE_CONTENT_TYPE].includes(contentTypeLower);
|
|
19158
19560
|
const copyablePromptText = getCopyablePromptText(nodeModel, prompt);
|
|
19159
19561
|
const shouldShowPromptCopyButton = contentTypeLower === 'note' && shouldShowPrompt && !!copyablePromptText;
|
|
19160
19562
|
ensurePromptCopyDelegation();
|
|
@@ -19167,7 +19569,7 @@
|
|
|
19167
19569
|
// [Fix] Add 'map-node-note' class for Note nodes so interactions module recognizes them
|
|
19168
19570
|
const isNoteNode = contentTypeLower === 'note';
|
|
19169
19571
|
const isCodeClassNode = contentTypeLower === 'code';
|
|
19170
|
-
container.className = `map-node css3d-dynamic-node${isImageNode ? ' map-node-image-container' : ''}${isEmbedNode ? ' map-node-embed' : ''}${isNoteNode ? ' map-node-note' : ''}${isCodeClassNode ? ' map-node-code' : ''}${isAgentNode ? ' map-node-agent' : ''}`;
|
|
19572
|
+
container.className = `map-node css3d-dynamic-node${isImageNode ? ' map-node-image-container' : ''}${isEmbedNode ? ' map-node-embed' : ''}${isNoteNode ? ' map-node-note' : ''}${isCodeClassNode ? ' map-node-code' : ''}${isCsvTableNode ? ' map-node-csv-table' : ''}${isAgentNode ? ' map-node-agent' : ''}`;
|
|
19171
19573
|
container.dataset.nodeId = nodeModel.id;
|
|
19172
19574
|
container.style.cssText = `
|
|
19173
19575
|
width: ${width}px;
|
|
@@ -19175,7 +19577,7 @@
|
|
|
19175
19577
|
background: ${isMediaNode ? 'transparent' : 'white'};
|
|
19176
19578
|
${isMediaNode ? 'border: 0; outline: 0;' : ''}
|
|
19177
19579
|
border-radius: 0px;
|
|
19178
|
-
padding: ${isMediaNode ? '0' : (isCodeClassNode ? '12px 8px 12px 14px' : (isTextualCardNode ? '12px 8px 12px 14px' : '12px 4px 12px 12px'))};
|
|
19580
|
+
padding: ${isMediaNode ? '0' : (isCsvTableNode ? '10px' : (isCodeClassNode ? '12px 8px 12px 14px' : (isTextualCardNode ? '12px 8px 12px 14px' : '12px 4px 12px 12px')))};
|
|
19179
19581
|
box-sizing: border-box;
|
|
19180
19582
|
overflow: hidden;
|
|
19181
19583
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
@@ -19285,7 +19687,23 @@
|
|
|
19285
19687
|
// Variable isNoteNode declared above
|
|
19286
19688
|
const isMarkdownType = ['text', 'markdown'].includes(contentTypeLower); // Removed 'note'
|
|
19287
19689
|
|
|
19288
|
-
if (
|
|
19690
|
+
if (isCsvTableNode) {
|
|
19691
|
+
responseDiv.className = 'node-response csv-table-scroll';
|
|
19692
|
+
responseDiv.style.cssText = `
|
|
19693
|
+
width: 100%;
|
|
19694
|
+
height: 100%;
|
|
19695
|
+
flex: 1 1 auto;
|
|
19696
|
+
min-height: 0;
|
|
19697
|
+
overflow: auto;
|
|
19698
|
+
pointer-events: auto;
|
|
19699
|
+
box-sizing: border-box;
|
|
19700
|
+
user-select: text;
|
|
19701
|
+
-webkit-user-select: text;
|
|
19702
|
+
`;
|
|
19703
|
+
responseDiv.dataset.src = content;
|
|
19704
|
+
responseDiv.dataset.nodeId = nodeModel.id;
|
|
19705
|
+
renderCsvTableContent(responseDiv, nodeModel, content);
|
|
19706
|
+
} else if (isCodeNode) {
|
|
19289
19707
|
responseDiv.className = 'node-response code-body';
|
|
19290
19708
|
// ▼▼▼ [FIX] 슬림 스크롤바 인라인 스타일 추가 ▼▼▼
|
|
19291
19709
|
responseDiv.style.cssText = `
|
|
@@ -19559,6 +19977,7 @@
|
|
|
19559
19977
|
|| contentTypeLower === 'markdown'
|
|
19560
19978
|
|| contentTypeLower === 'note'
|
|
19561
19979
|
|| contentTypeLower === 'memo'
|
|
19980
|
+
|| contentTypeLower === CSV_TABLE_CONTENT_TYPE
|
|
19562
19981
|
|| contentTypeLower === 'templatelauncher'
|
|
19563
19982
|
|| contentTypeLower === 'image'
|
|
19564
19983
|
|| contentTypeLower === 'video'
|
|
@@ -19572,7 +19991,7 @@
|
|
|
19572
19991
|
// text/markdown type has no Blazor template, so create dynamically.
|
|
19573
19992
|
// [FIX] 'note' type also falls back to dynamic creation if not found (or if we force dynamic for consistent MD)
|
|
19574
19993
|
// But usually 'note' comes from Razor. If missing, we create it.
|
|
19575
|
-
const dynamicTypes = ['text', 'markdown', 'code', 'note', 'memo', 'templatelauncher', 'image', 'video', 'embed'];
|
|
19994
|
+
const dynamicTypes = ['text', 'markdown', 'code', 'note', 'memo', CSV_TABLE_CONTENT_TYPE, 'templatelauncher', 'image', 'video', 'embed'];
|
|
19576
19995
|
|
|
19577
19996
|
if (remoteFleetMonitor || dynamicTypes.includes(contentTypeLower)) {
|
|
19578
19997
|
log(`[MindMapCss3DManager] Creating dynamic DOM element for ${visualContentTypeLower || contentTypeLower} node ${nodeModel.id}`);
|
|
@@ -19724,7 +20143,7 @@
|
|
|
19724
20143
|
&& !isRemoteFleetMonitorNode(nodeModel);
|
|
19725
20144
|
// Enable pointer events for scrollable content so user can scroll/select text
|
|
19726
20145
|
const scrollables = clonedElement.querySelectorAll(
|
|
19727
|
-
'.node-response, .note-content, .markdown-body, .prose, .note-textarea, textarea, [id^="node-response-"], [id^="node-textarea-"], .code-body, .text-content, .embed-content, .embed-card, .embed-card *, .embed-action, .embed-play-button, .node-prompt-copy-button, .node-prompt-copy-button *, iframe, .map-node-memo__title, .map-node-memo__body, .map-node-memo__icon-button, .map-node-memo__icon-popover, .map-node-memo__icon-option, .map-node-memo__agent-role-select, .map-node-memo__agent-role-select-button, .map-node-memo__agent-role-menu, .map-node-memo__agent-role-option, .map-node-memo__agent-action, .map-node-memo__agent-plan-panel, .map-node-memo__agent-plan-body, .map-node-memo__agent-plan-body *, .map-node-memo__agent-console-panel, .map-node-memo__agent-console-body, .map-node-memo__agent-console-resize, .map-node-memo__agent-console-resize *, .map-node-memo__agent-result-link, .map-node-template-card, .map-node-template-card *, [data-template-card-interactive="true"]'
|
|
20146
|
+
'.node-response, .note-content, .markdown-body, .prose, .note-textarea, textarea, [id^="node-response-"], [id^="node-textarea-"], .code-body, .text-content, .csv-table-scroll, .csv-table-scroll *, .csv-table-header-button, .embed-content, .embed-card, .embed-card *, .embed-action, .embed-play-button, .node-prompt-copy-button, .node-prompt-copy-button *, iframe, .map-node-memo__title, .map-node-memo__body, .map-node-memo__icon-button, .map-node-memo__icon-popover, .map-node-memo__icon-option, .map-node-memo__agent-role-select, .map-node-memo__agent-role-select-button, .map-node-memo__agent-role-menu, .map-node-memo__agent-role-option, .map-node-memo__agent-action, .map-node-memo__agent-plan-panel, .map-node-memo__agent-plan-body, .map-node-memo__agent-plan-body *, .map-node-memo__agent-console-panel, .map-node-memo__agent-console-body, .map-node-memo__agent-console-resize, .map-node-memo__agent-console-resize *, .map-node-memo__agent-result-link, .map-node-template-card, .map-node-template-card *, [data-template-card-interactive="true"]'
|
|
19728
20147
|
);
|
|
19729
20148
|
scrollables.forEach(el => {
|
|
19730
20149
|
el.style.pointerEvents = 'auto';
|
|
@@ -19732,7 +20151,7 @@
|
|
|
19732
20151
|
el.style.userSelect = 'none';
|
|
19733
20152
|
el.style.webkitUserSelect = 'none';
|
|
19734
20153
|
el.style.cursor = 'ns-resize';
|
|
19735
|
-
} else if (el.matches('.embed-action, .embed-play-button, .embed-card, .embed-card *, .node-prompt-copy-button, .node-prompt-copy-button *, iframe, .map-node-memo__icon-button, .map-node-memo__icon-popover, .map-node-memo__icon-option, .map-node-memo__agent-role-select, .map-node-memo__agent-role-select-button, .map-node-memo__agent-role-menu, .map-node-memo__agent-role-option, .map-node-memo__agent-action, .map-node-memo__agent-result-link, .template-card__option, .template-card__generate')) {
|
|
20154
|
+
} else if (el.matches('.csv-table-header-button, .embed-action, .embed-play-button, .embed-card, .embed-card *, .node-prompt-copy-button, .node-prompt-copy-button *, iframe, .map-node-memo__icon-button, .map-node-memo__icon-popover, .map-node-memo__icon-option, .map-node-memo__agent-role-select, .map-node-memo__agent-role-select-button, .map-node-memo__agent-role-menu, .map-node-memo__agent-role-option, .map-node-memo__agent-action, .map-node-memo__agent-result-link, .template-card__option, .template-card__generate')) {
|
|
19736
20155
|
el.style.userSelect = 'none';
|
|
19737
20156
|
el.style.webkitUserSelect = 'none';
|
|
19738
20157
|
el.style.cursor = 'pointer';
|
|
@@ -20197,8 +20616,16 @@
|
|
|
20197
20616
|
if (responseEl) {
|
|
20198
20617
|
responseEl.style.display = (isLoading && !hasContent) ? 'none' : '';
|
|
20199
20618
|
const isCodeNode = contentTypeLower === 'code';
|
|
20200
|
-
|
|
20201
|
-
|
|
20619
|
+
const isCsvTableNode = contentTypeLower === CSV_TABLE_CONTENT_TYPE;
|
|
20620
|
+
|
|
20621
|
+
if (isCsvTableNode) {
|
|
20622
|
+
if (!responseEl.classList.contains('csv-table-scroll')) {
|
|
20623
|
+
responseEl.className = 'node-response csv-table-scroll';
|
|
20624
|
+
}
|
|
20625
|
+
responseEl.dataset.src = content || '';
|
|
20626
|
+
responseEl.dataset.nodeId = nodeModel.id || nodeModel.Id || '';
|
|
20627
|
+
renderCsvTableContent(responseEl, nodeModel, content);
|
|
20628
|
+
} else if (isCodeNode) {
|
|
20202
20629
|
renderCodeBodyContent(responseEl, content);
|
|
20203
20630
|
} else {
|
|
20204
20631
|
// Unified Markdown Rendering with Caching
|