@mindexec/cli 0.2.400 → 0.2.402

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.
Files changed (19) hide show
  1. package/package.json +1 -1
  2. package/scripts/remote-registry-follower-smoke.mjs +30 -0
  3. package/server.js +23 -3
  4. package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js +133 -12
  5. package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +39 -7
  6. package/wwwroot/_framework/{MindExecution.Core.y7ffihhajj.dll → MindExecution.Core.v3wmxuk7qp.dll} +0 -0
  7. package/wwwroot/_framework/{MindExecution.Kernel.l5y3qroa7p.dll → MindExecution.Kernel.kx4xhfncsj.dll} +0 -0
  8. package/wwwroot/_framework/{MindExecution.Plugins.Admin.uuf238xa0h.dll → MindExecution.Plugins.Admin.1zm6aw94og.dll} +0 -0
  9. package/wwwroot/_framework/{MindExecution.Plugins.Business.nyr3v25v48.dll → MindExecution.Plugins.Business.aundh2fuh7.dll} +0 -0
  10. package/wwwroot/_framework/{MindExecution.Plugins.Concept.l9z9tx9svt.dll → MindExecution.Plugins.Concept.pp0hp35q6g.dll} +0 -0
  11. package/wwwroot/_framework/{MindExecution.Plugins.Directory.ju87t8h3zs.dll → MindExecution.Plugins.Directory.askhe4ifrt.dll} +0 -0
  12. package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.krn3jgvjpa.dll → MindExecution.Plugins.PlanMaster.4fq8s1zuht.dll} +0 -0
  13. package/wwwroot/_framework/{MindExecution.Plugins.YouTube.5m53srfud6.dll → MindExecution.Plugins.YouTube.1ekzvomyd2.dll} +0 -0
  14. package/wwwroot/_framework/{MindExecution.Shared.ojp3psugsm.dll → MindExecution.Shared.ndzddktvwm.dll} +0 -0
  15. package/wwwroot/_framework/MindExecution.Web.ptfprazlfv.dll +0 -0
  16. package/wwwroot/_framework/blazor.boot.json +21 -21
  17. package/wwwroot/service-worker-assets.js +24 -24
  18. package/wwwroot/service-worker.js +1 -1
  19. package/wwwroot/_framework/MindExecution.Web.zd2eb9d4hz.dll +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindexec/cli",
3
- "version": "0.2.400",
3
+ "version": "0.2.402",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
@@ -127,6 +127,7 @@ function startFakeSupabase(getTarget, setTarget = null) {
127
127
  if (req.method === 'POST' && parsed.pathname === '/rest/v1/rpc/set_remote_host_target') {
128
128
  assertRegistryAuth(req);
129
129
  const body = JSON.parse(await readBody() || '{}');
130
+ requests[requests.length - 1].body = body;
130
131
  const now = Date.now();
131
132
  const existing = getTarget();
132
133
  const sameLease = existing
@@ -505,6 +506,35 @@ async function main() {
505
506
  assert.equal(renewSetHost.payload?.hostTargetRenew?.status, 'active', JSON.stringify(renewSetHost.payload?.hostTargetRenew));
506
507
  assert.equal(currentTarget?.endpoint, renewPublicEndpoint, JSON.stringify(currentTarget));
507
508
  assert.equal(currentTarget?.node_id, 'remote-registry-renew-node', JSON.stringify(currentTarget));
509
+ const explicitSetHostPublish = fakeSupabase.requests.find(request =>
510
+ request.method === 'POST'
511
+ && request.pathname === '/rest/v1/rpc/set_remote_host_target'
512
+ && request.body?.p_node_id === 'remote-registry-renew-node');
513
+ assert.equal(explicitSetHostPublish?.body?.p_takeover, true, JSON.stringify(explicitSetHostPublish?.body));
514
+ const beforeQuietRenewPublishCount = fakeSupabase.requests.filter(request =>
515
+ request.method === 'POST'
516
+ && request.pathname === '/rest/v1/rpc/set_remote_host_target').length;
517
+ const quietRenewSetHost = await fetchJson(`${renewHost.baseUrl}/api/remote/host-target`, {
518
+ method: 'POST',
519
+ token: BRIDGE_TOKEN,
520
+ body: JSON.stringify({
521
+ nodeId: 'remote-registry-renew-node',
522
+ enabled: true,
523
+ leaseMs: 60000,
524
+ renew: true
525
+ })
526
+ });
527
+ assert.equal(quietRenewSetHost.ok, true, JSON.stringify(quietRenewSetHost.payload));
528
+ assert.equal(quietRenewSetHost.payload?.ok, true, JSON.stringify(quietRenewSetHost.payload));
529
+ assert.equal(quietRenewSetHost.payload?.active, true, JSON.stringify(quietRenewSetHost.payload));
530
+ assert.equal(quietRenewSetHost.payload?.hostTargetTakeover, false, JSON.stringify(quietRenewSetHost.payload));
531
+ const quietRenewPublish = fakeSupabase.requests
532
+ .filter(request =>
533
+ request.method === 'POST'
534
+ && request.pathname === '/rest/v1/rpc/set_remote_host_target')
535
+ .slice(beforeQuietRenewPublishCount)
536
+ .find(request => request.body?.p_node_id === 'remote-registry-renew-node');
537
+ assert.equal(quietRenewPublish?.body?.p_takeover, false, JSON.stringify(quietRenewPublish?.body));
508
538
  await waitFor(() => {
509
539
  const publishCount = fakeSupabase.requests.filter(request =>
510
540
  request.method === 'POST'
package/server.js CHANGED
@@ -12417,6 +12417,11 @@ app.post('/api/remote/host-target', async (req, res) => {
12417
12417
  res.setHeader('Cache-Control', 'no-store');
12418
12418
  try {
12419
12419
  const requestedLeaseMs = Number(req.body?.leaseMs);
12420
+ const requestedRenew = req.body?.renew === true;
12421
+ const requestedTakeover = req.body?.takeover;
12422
+ const takeover = req.body?.enabled === false
12423
+ ? false
12424
+ : requestedTakeover === true || (requestedTakeover !== false && !requestedRenew);
12420
12425
  const result = remoteHub.setHostTarget({
12421
12426
  enabled: req.body?.enabled !== false,
12422
12427
  nodeId: req.body?.nodeId,
@@ -12424,19 +12429,34 @@ app.post('/api/remote/host-target', async (req, res) => {
12424
12429
  REMOTE_HOST_TARGET_LEASE_MS,
12425
12430
  Number.isFinite(requestedLeaseMs) && requestedLeaseMs > 0 ? requestedLeaseMs : 0)
12426
12431
  });
12432
+ let responseResult = result;
12433
+ let hostTargetRenew = serializeRemoteHostTargetRenewState();
12427
12434
  if (result?.ok === true && result?.active === true && isLocalRemoteHostTargetActive()) {
12428
12435
  if (isRemoteAgentProcessRunning()) {
12429
12436
  await stopRemoteAgentConnection('local-host-target-active');
12430
12437
  logEvent('remote', 'managed RemoteAgent held stopped while local host target is active', 'remote');
12431
12438
  }
12432
- await runRemoteHostTargetRenewOnce('set-host', { takeover: true });
12439
+ hostTargetRenew = await runRemoteHostTargetRenewOnce('set-host', { takeover });
12440
+ const currentHub = remoteHub.getStatus({ includeSecrets: true });
12441
+ if (currentHub?.hostTargetActive !== true
12442
+ || currentHub.hostTargetNodeId !== result.hostTarget?.nodeId
12443
+ || currentHub.hostTargetLeaseId !== result.hostTarget?.leaseId) {
12444
+ responseResult = {
12445
+ ok: false,
12446
+ active: false,
12447
+ error: hostTargetRenew?.reason || 'host-target-superseded',
12448
+ hostTarget: null
12449
+ };
12450
+ }
12433
12451
  } else if (result?.active !== true) {
12434
12452
  stopRemoteHostTargetRenew('host-target-inactive');
12453
+ hostTargetRenew = serializeRemoteHostTargetRenewState();
12435
12454
  }
12436
12455
  res.json({
12437
- ...result,
12456
+ ...responseResult,
12438
12457
  agent: serializeRemoteAgentState(),
12439
- hostTargetRenew: serializeRemoteHostTargetRenewState()
12458
+ hostTargetRenew,
12459
+ hostTargetTakeover: takeover
12440
12460
  });
12441
12461
  } catch (err) {
12442
12462
  logError('remote', 'remote host target update failed.', err);
@@ -1456,7 +1456,7 @@
1456
1456
  overlayLayoutChanged: moduleInstance._overlayDebugLayoutChanged === true,
1457
1457
  overlayContentChanged: moduleInstance._overlayDebugContentChanged === true,
1458
1458
  overlayForceRefresh: moduleInstance._overlayDebugForceRefresh === true,
1459
- cameraMotionFastPathStatus: null,
1459
+ cameraMotionFastPathStatus: moduleInstance._lastImmediateCameraFeedbackStatus || null,
1460
1460
  metricsSnapshotMs: Number(metricsSnapshotMs.toFixed(2)),
1461
1461
  metricsSnapshotCached: false,
1462
1462
  metricsSnapshotAgeMs: 0,
@@ -3162,6 +3162,10 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
3162
3162
  this._ctrlWheelScrollInputTime = 0;
3163
3163
  this._ctrlWheelScrollLastDeltaY = 0;
3164
3164
  this._cameraNavigationOverlayInputTime = 0;
3165
+ this._lastImmediateCameraFeedbackStatus = null;
3166
+ this._immediateCameraFeedbackCount = 0;
3167
+ this._immediateCameraFeedbackCss3dCount = 0;
3168
+ this._immediateCameraFeedbackEdgeCount = 0;
3165
3169
  // Match background-themes.js 'XYGrid' size1.
3166
3170
  this.GRID_SIZE = 10;
3167
3171
  // ?�▲??[Changed] ?�▲??
@@ -4102,6 +4106,115 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
4102
4106
  }
4103
4107
  }
4104
4108
 
4109
+ applyImmediateCameraNavigationFeedback(reason = 'camera-navigation-input') {
4110
+ const now = typeof performance !== 'undefined' && typeof performance.now === 'function'
4111
+ ? performance.now()
4112
+ : Date.now();
4113
+ const status = {
4114
+ used: false,
4115
+ reason: String(reason || 'camera-navigation-input'),
4116
+ css3dCamera: false,
4117
+ automationEdges: false,
4118
+ motionGrid: false,
4119
+ localSnapGrid: false,
4120
+ skippedReason: '',
4121
+ count: Number(this._immediateCameraFeedbackCount || 0),
4122
+ updatedAt: now
4123
+ };
4124
+
4125
+ const finish = (skippedReason = '') => {
4126
+ status.skippedReason = skippedReason;
4127
+ this._lastImmediateCameraFeedbackStatus = status;
4128
+ return status.used === true;
4129
+ };
4130
+
4131
+ if (!this.camera || this._animationLoopExecuting === true || this.isLoading === true) {
4132
+ return finish('runtime-busy');
4133
+ }
4134
+
4135
+ const nextX = Number(this.targetX ?? this.camera.position.x);
4136
+ const nextY = Number(this.targetY ?? this.camera.position.y);
4137
+ const nextZ = Number(this.targetZ ?? this.camera.position.z);
4138
+ if (!Number.isFinite(nextX) || !Number.isFinite(nextY) || !Number.isFinite(nextZ)) {
4139
+ return finish('invalid-target');
4140
+ }
4141
+
4142
+ const currentX = Number(this.camera.position.x || 0);
4143
+ const currentY = Number(this.camera.position.y || 0);
4144
+ const currentZ = Number(this.camera.position.z || 0);
4145
+ if (Math.abs(nextX - currentX) < 0.001 &&
4146
+ Math.abs(nextY - currentY) < 0.001 &&
4147
+ Math.abs(nextZ - currentZ) < 0.001) {
4148
+ return finish('unchanged');
4149
+ }
4150
+
4151
+ this.camera.position.set(nextX, nextY, nextZ);
4152
+ this.camera.updateMatrixWorld(true);
4153
+ this._viewStatePersistAfterMotion = true;
4154
+ this._cameraMovingThisFrame = true;
4155
+ this._immediateCameraFeedbackCount = Number(this._immediateCameraFeedbackCount || 0) + 1;
4156
+ status.used = true;
4157
+ status.count = this._immediateCameraFeedbackCount;
4158
+
4159
+ const flags = this.renderDebugFlags || getRenderDebugFlagsSnapshot();
4160
+ const isCss3dEnabled = flags.enableCss3d !== false;
4161
+ const hasFocusedTextOverlay = !!(
4162
+ String(this._textOverlayV2State?.selectionNodeId || '').trim() ||
4163
+ String(this._selectableTextOverlayNodeId || '').trim()
4164
+ );
4165
+ const hasEditingOverlay = !!(
4166
+ String(this._textOverlayV2State?.editing?.nodeId || '').trim() ||
4167
+ String(this._editingOverlayState?.nodeId || '').trim() ||
4168
+ this.isEditingNote === true
4169
+ );
4170
+ const isNodeInteracting = !!(
4171
+ this.isDraggingNode ||
4172
+ this.isDraggingMultipleNodes ||
4173
+ this.isResizing ||
4174
+ this.isScrollbarDragging ||
4175
+ this.isSelecting
4176
+ );
4177
+ const hasCss3dDirtyTransforms = !!(
4178
+ this._cssParentRepairNeeded === true ||
4179
+ this._css3dVisualChangedThisFrame === true ||
4180
+ this._css3dVisualChangedSinceLastRender === true ||
4181
+ (this._cssTransformDirtyIds?.size || 0) > 0
4182
+ );
4183
+ const canRenderCss3dCamera = !!(
4184
+ this.cssRenderer &&
4185
+ typeof this.cssRenderer.renderCamera === 'function' &&
4186
+ isCss3dEnabled === true &&
4187
+ this.lodRenderer?.isInLODMode !== true &&
4188
+ !isNodeInteracting &&
4189
+ !hasFocusedTextOverlay &&
4190
+ !hasEditingOverlay &&
4191
+ !hasCss3dDirtyTransforms &&
4192
+ this.isWindowResizing !== true
4193
+ );
4194
+
4195
+ if (canRenderCss3dCamera === true) {
4196
+ this.cssRenderer.renderCamera(this.camera);
4197
+ this._immediateCameraFeedbackCss3dCount = Number(this._immediateCameraFeedbackCss3dCount || 0) + 1;
4198
+ status.css3dCamera = true;
4199
+ status.css3dCount = this._immediateCameraFeedbackCss3dCount;
4200
+ }
4201
+
4202
+ if (this._shouldTouchMotionGridLayerForCameraNavigation?.() === true) {
4203
+ status.motionGrid = this._syncMotionGridLayerForCameraNavigation?.() === true;
4204
+ }
4205
+
4206
+ status.localSnapGrid = syncLocalSnapGridForCameraNavigation(this, true) === true;
4207
+
4208
+ if (syncBusinessAutomationEdgesForCameraNavigation(this, true, false) === true) {
4209
+ this._immediateCameraFeedbackEdgeCount = Number(this._immediateCameraFeedbackEdgeCount || 0) + 1;
4210
+ status.automationEdges = true;
4211
+ status.edgeCount = this._immediateCameraFeedbackEdgeCount;
4212
+ }
4213
+
4214
+ this._lastImmediateCameraFeedbackStatus = status;
4215
+ return true;
4216
+ }
4217
+
4105
4218
  getCurrentBoardId() {
4106
4219
  return window.mindMap?.activeBoardId || _currentBoardId || null;
4107
4220
  }
@@ -5892,16 +6005,15 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5892
6005
  const forceUpdateFrames = Math.max(0, Number(this._forceUpdateFrames || 0));
5893
6006
  const panLiveRefreshForceFrames = Math.max(0, Number(this._panLiveRefreshForceFrames || 0));
5894
6007
  const hasForcedUpdate = forceUpdateFrames > 0;
5895
- // Mouse-pan live refresh keeps the render loop awake; it should not disable motion throttles.
5896
- const hasOnlyPanLiveRefreshForcedUpdate =
6008
+ // Camera navigation wake frames keep the render loop awake; they should not disable motion throttles.
6009
+ const hasOnlyCameraNavigationForcedUpdate =
5897
6010
  hasForcedUpdate &&
5898
- this.isPanning === true &&
5899
- this.isZooming !== true &&
5900
- panLiveRefreshForceFrames >= forceUpdateFrames;
5901
- const hasNonPanForcedUpdate =
6011
+ panLiveRefreshForceFrames >= forceUpdateFrames &&
6012
+ (this.isPanning === true || this.isZooming === true || isCameraMoving === true);
6013
+ const hasNonCameraForcedUpdate =
5902
6014
  hasForcedUpdate &&
5903
- hasOnlyPanLiveRefreshForcedUpdate !== true;
5904
- const hasNonCameraNavigationForcedUpdate = hasNonPanForcedUpdate;
6015
+ hasOnlyCameraNavigationForcedUpdate !== true;
6016
+ const hasNonCameraNavigationForcedUpdate = hasNonCameraForcedUpdate;
5905
6017
  const isLodModeActive = this.lodRenderer?.isInLODMode === true;
5906
6018
  const residentDirty = isResidentMidFarLodFrame &&
5907
6019
  this.lodRenderer?.hasResidentDirtyWork?.(this.camera, this) === true;
@@ -6687,15 +6799,22 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
6687
6799
 
6688
6800
  _profileSection('webglRender');
6689
6801
  // ?�▼??[FIX] LOD 모드(MID/FAR)?�서??CSS3D ?�더???�출 건너?�기 ?�▼?? // CSS3D가 모두 display:none?�어???�더?��? 813�?객체�??�회?�면???�간 ?�비
6802
+ const lastImmediateCameraFeedback = this._lastImmediateCameraFeedbackStatus || null;
6803
+ const lastImmediateCameraFeedbackAgeMs = frameStart - Number(lastImmediateCameraFeedback?.updatedAt || 0);
6804
+ const hasFreshImmediateCameraFeedback = !!(
6805
+ lastImmediateCameraFeedback?.used === true &&
6806
+ (this.isPanning === true || this.isZooming === true) &&
6807
+ lastImmediateCameraFeedbackAgeMs >= 0 &&
6808
+ lastImmediateCameraFeedbackAgeMs <= 120
6809
+ );
6690
6810
  const canUseCss3dCameraFastPath = !!(
6691
6811
  this.cssRenderer &&
6692
6812
  typeof this.cssRenderer.renderCamera === 'function' &&
6693
6813
  isCss3dEnabled &&
6694
6814
  !isInLodMode &&
6695
6815
  shouldUpdateCss3d &&
6696
- this.isPanning === true &&
6697
- this.isZooming !== true &&
6698
- isCameraMoving === true &&
6816
+ (this.isPanning === true || this.isZooming === true || isCameraMoving === true) &&
6817
+ (isCameraMoving === true || hasFreshImmediateCameraFeedback === true) &&
6699
6818
  !isNodeInteracting &&
6700
6819
  !hasNonCameraNavigationForcedUpdate &&
6701
6820
  !hasPendingNearCssWarmup &&
@@ -6948,9 +7067,11 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
6948
7067
  visibilityStableSkip: canSkipVisibilityCullingForStableFrame === true,
6949
7068
  visibilitySkipReason: visibilityCullingSkipReason || this._lastVisibilityCullingSkipReason || '',
6950
7069
  incrementalPanVisibility: isIncrementalPanVisibilityFrame === true,
7070
+ freshImmediateCameraFeedback: hasFreshImmediateCameraFeedback === true,
6951
7071
  shouldSyncCss3dTransforms: shouldSyncCss3dTransforms === true,
6952
7072
  shouldRenderCss3d: shouldRenderCss3dFrame === true,
6953
7073
  usedCss3dCameraFastPath: canUseCss3dCameraFastPath === true,
7074
+ immediateCameraFeedback: this._lastImmediateCameraFeedbackStatus || null,
6954
7075
  shouldSyncTextOverlays: shouldSyncTextOverlays === true,
6955
7076
  usedPassiveOverlayCameraFastPath: usedPassiveOverlayCameraFastPath === true,
6956
7077
  passiveOverlaySuppressed: isPassiveOverlaySuppressed === true,
@@ -5,7 +5,7 @@ window.MindMapInteractions = (function () {
5
5
  const MOTION_DOM_FANOUT_DELAY_MS = 180;
6
6
  const MOTION_DOM_FANOUT_ENABLED = false;
7
7
  const MOTION_WILL_CHANGE_ENABLE_DELAY_MS = 240;
8
- const WHEEL_ZOOM_TARGET_UPDATE_MODE = 'raf-coalesced-direct';
8
+ const WHEEL_ZOOM_TARGET_UPDATE_MODE = 'event-direct';
9
9
  const PRIMARY_CLICK_DELAY_MS = 280;
10
10
  const BACKGROUND_PRIMARY_CLICK_DELAY_MS = 320;
11
11
  const eventHandlers = new WeakMap();
@@ -603,10 +603,34 @@ window.MindMapInteractions = (function () {
603
603
  if (!module) {
604
604
  return;
605
605
  }
606
- wakeCameraNavigationAnimation(module, 'pan-input');
606
+ wakeCameraNavigationAnimation(module, 'pan-input', { immediate: true, forceFrames: 2 });
607
607
  }
608
608
 
609
- function wakeCameraNavigationAnimation(module, reason = 'camera-navigation-input') {
609
+ function applyImmediateCameraNavigationFeedback(module, reason = 'camera-navigation-input') {
610
+ if (module && typeof module.applyImmediateCameraNavigationFeedback === 'function') {
611
+ module.applyImmediateCameraNavigationFeedback(reason);
612
+ }
613
+ }
614
+
615
+ function markCameraNavigationForceFrames(module, frames = 2) {
616
+ if (!module) {
617
+ return;
618
+ }
619
+
620
+ const safeFrames = Math.max(0, Math.floor(Number(frames || 0)));
621
+ if (safeFrames <= 0) {
622
+ return;
623
+ }
624
+
625
+ module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), safeFrames);
626
+ module._panLiveRefreshForceFrames = Math.max(Number(module._panLiveRefreshForceFrames || 0), safeFrames);
627
+ }
628
+
629
+ function wakeCameraNavigationAnimation(module, reason = 'camera-navigation-input', options = {}) {
630
+ markCameraNavigationForceFrames(module, options?.forceFrames ?? 0);
631
+ if (options?.immediate === true) {
632
+ applyImmediateCameraNavigationFeedback(module, reason);
633
+ }
610
634
  if (module && typeof module.requestAnimationWake === 'function') {
611
635
  module.requestAnimationWake(reason);
612
636
  }
@@ -6362,7 +6386,7 @@ window.MindMapInteractions = (function () {
6362
6386
  module._lastPanInputAt = panInputAt;
6363
6387
  module._deferPassiveOverlayRefresh = true;
6364
6388
  module._cameraNavigationOverlayInputTime = panInputAt;
6365
- wakeCameraNavigationAnimation(module, 'trackpad-pan-input');
6389
+ wakeCameraNavigationAnimation(module, 'trackpad-pan-input', { immediate: true, forceFrames: 2 });
6366
6390
 
6367
6391
  if (module.isSelecting) {
6368
6392
  updateSelectionBox(module);
@@ -6387,6 +6411,13 @@ window.MindMapInteractions = (function () {
6387
6411
  return;
6388
6412
  }
6389
6413
 
6414
+ if (WHEEL_ZOOM_TARGET_UPDATE_MODE === 'event-direct') {
6415
+ const wheelNow = getWheelTimestamp();
6416
+ markCanvasWheelActivity(module, wheelNow, { throttleMs: WHEEL_ACTIVITY_BURST_INTERVAL_MS });
6417
+ performCameraZoomBuffered(module, deltaY, e.clientX, e.clientY, { inputTime: wheelNow });
6418
+ return;
6419
+ }
6420
+
6390
6421
  wheelBuffer.deltaY += deltaY;
6391
6422
  wheelBuffer.lastClientX = e.clientX;
6392
6423
  wheelBuffer.lastClientY = e.clientY;
@@ -6496,9 +6527,9 @@ window.MindMapInteractions = (function () {
6496
6527
  const newY = worldMouseY - (worldMouseY - module.targetY) * zoomRatio;
6497
6528
  module.targetX = newX;
6498
6529
  module.targetY = newY;
6530
+ applyImmediateCameraNavigationFeedback(module, 'wheel-zoom-input');
6499
6531
  const settleFrames = 2;
6500
- module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), settleFrames);
6501
- wakeCameraNavigationAnimation(module, 'wheel-zoom-input');
6532
+ wakeCameraNavigationAnimation(module, 'wheel-zoom-input', { forceFrames: settleFrames });
6502
6533
  // ▲▲▲ [Changed] ▲▲▲
6503
6534
 
6504
6535
  // ▼▼▼ [Perf] 줌 종료 감지 및 CSS3D 업데이트 타이머 ▼▼▼
@@ -6649,10 +6680,11 @@ window.MindMapInteractions = (function () {
6649
6680
 
6650
6681
  const panFactor = 0.001 * module.camera.position.z;
6651
6682
  module.targetY -= deltaY * panFactor;
6652
- module._forceUpdateFrames = Math.max(module._forceUpdateFrames || 0, 2);
6683
+ applyImmediateCameraNavigationFeedback(module, 'ctrl-wheel-pan-input');
6653
6684
  module._deferPassiveOverlayRefresh = false;
6654
6685
  module._overlayDirty = true;
6655
6686
  window.MindMapTextOverlayV2?.invalidateView?.(module);
6687
+ wakeCameraNavigationAnimation(module, 'ctrl-wheel-pan-input', { forceFrames: 2 });
6656
6688
 
6657
6689
  if (module.isSelecting) {
6658
6690
  updateSelectionBox(module);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "mainAssemblyName": "MindExecution.Web",
3
3
  "resources": {
4
- "hash": "sha256-RIIvuKuhAJlhrdGsDtU19Ym/qvsLZfYIl9SVIV+zsx8=",
4
+ "hash": "sha256-MlyoxZqdnYrP34av6RxINQa6Xh6R94zwjpBdIk4I9WA=",
5
5
  "fingerprinting": {
6
6
  "Google.Protobuf.9h59ukbel7.dll": "Google.Protobuf.dll",
7
7
  "Markdig.d1j7v41cl1.dll": "Markdig.dll",
@@ -123,16 +123,16 @@
123
123
  "System.brmz7yk5qh.dll": "System.dll",
124
124
  "netstandard.yvr3prsx0x.dll": "netstandard.dll",
125
125
  "System.Private.CoreLib.c1dbswx1b2.dll": "System.Private.CoreLib.dll",
126
- "MindExecution.Core.y7ffihhajj.dll": "MindExecution.Core.dll",
127
- "MindExecution.Kernel.l5y3qroa7p.dll": "MindExecution.Kernel.dll",
128
- "MindExecution.Plugins.Admin.uuf238xa0h.dll": "MindExecution.Plugins.Admin.dll",
129
- "MindExecution.Plugins.Business.nyr3v25v48.dll": "MindExecution.Plugins.Business.dll",
130
- "MindExecution.Plugins.Concept.l9z9tx9svt.dll": "MindExecution.Plugins.Concept.dll",
131
- "MindExecution.Plugins.Directory.ju87t8h3zs.dll": "MindExecution.Plugins.Directory.dll",
132
- "MindExecution.Plugins.PlanMaster.krn3jgvjpa.dll": "MindExecution.Plugins.PlanMaster.dll",
133
- "MindExecution.Plugins.YouTube.5m53srfud6.dll": "MindExecution.Plugins.YouTube.dll",
134
- "MindExecution.Shared.ojp3psugsm.dll": "MindExecution.Shared.dll",
135
- "MindExecution.Web.zd2eb9d4hz.dll": "MindExecution.Web.dll",
126
+ "MindExecution.Core.v3wmxuk7qp.dll": "MindExecution.Core.dll",
127
+ "MindExecution.Kernel.kx4xhfncsj.dll": "MindExecution.Kernel.dll",
128
+ "MindExecution.Plugins.Admin.1zm6aw94og.dll": "MindExecution.Plugins.Admin.dll",
129
+ "MindExecution.Plugins.Business.aundh2fuh7.dll": "MindExecution.Plugins.Business.dll",
130
+ "MindExecution.Plugins.Concept.pp0hp35q6g.dll": "MindExecution.Plugins.Concept.dll",
131
+ "MindExecution.Plugins.Directory.askhe4ifrt.dll": "MindExecution.Plugins.Directory.dll",
132
+ "MindExecution.Plugins.PlanMaster.4fq8s1zuht.dll": "MindExecution.Plugins.PlanMaster.dll",
133
+ "MindExecution.Plugins.YouTube.1ekzvomyd2.dll": "MindExecution.Plugins.YouTube.dll",
134
+ "MindExecution.Shared.ndzddktvwm.dll": "MindExecution.Shared.dll",
135
+ "MindExecution.Web.ptfprazlfv.dll": "MindExecution.Web.dll",
136
136
  "dotnet.js": "dotnet.js",
137
137
  "dotnet.native.qc8g39g30v.js": "dotnet.native.js",
138
138
  "dotnet.native.boem75ye5i.wasm": "dotnet.native.wasm",
@@ -278,18 +278,18 @@
278
278
  "System.Xml.XDocument.sn51jas17n.dll": "sha256-GNI2kFgFmPTwzuzwUn8gxK+AzGLUWRJFdg9JzIbrybQ=",
279
279
  "System.brmz7yk5qh.dll": "sha256-CfM2miyj1KHApFmqMdLYWio3S/jrdON2pW9Xr2nTwlo=",
280
280
  "netstandard.yvr3prsx0x.dll": "sha256-EksNn8Luo4bOWqJ6X7dIe9qG9oOqwOVzjH2xYyMNi+E=",
281
- "MindExecution.Core.y7ffihhajj.dll": "sha256-zsCKUWBWzDly1h5/vMtqVRb7PeG4lgfIZbQuJFyY1QU=",
282
- "MindExecution.Kernel.l5y3qroa7p.dll": "sha256-V4pQTxua0lGWpdsFpo7bHr6rPFWZeofry7e9On+OJmo=",
283
- "MindExecution.Plugins.Business.nyr3v25v48.dll": "sha256-T4c7+fDE4TQAXAoFmHnYM+tT7RSvAM7W0VinLPoD+6U=",
284
- "MindExecution.Plugins.Concept.l9z9tx9svt.dll": "sha256-N/QoILmTilvX5Zo4SCy7ENTCqMzSC6RIEQlEwtxkGPo=",
285
- "MindExecution.Plugins.PlanMaster.krn3jgvjpa.dll": "sha256-8IFpm/2fpsWD3syyl58LTSWSGC8PfcrsLdmmSKR1Sq0=",
286
- "MindExecution.Shared.ojp3psugsm.dll": "sha256-FC0pE2bsyE9i7GNSXCghKULaYYZXUEdepb2VxPfcYaA=",
287
- "MindExecution.Web.zd2eb9d4hz.dll": "sha256-l4L9FFeaEkMfR5tjzxg1v/KgOuCHBkaQbxiwSHGxkNk="
281
+ "MindExecution.Core.v3wmxuk7qp.dll": "sha256-9bpD6izq4bzR75iSm2e4S9uPoshwUG7pHxvskKk0mTo=",
282
+ "MindExecution.Kernel.kx4xhfncsj.dll": "sha256-yKtHx9Ehc/GwTtP4a5pZ8K5B790qL7GrNsxlbIZ54Zo=",
283
+ "MindExecution.Plugins.Business.aundh2fuh7.dll": "sha256-Dt3CeEVDlPitVDi6wPH3cw6HGYWOzPVcyLPTlzeKry8=",
284
+ "MindExecution.Plugins.Concept.pp0hp35q6g.dll": "sha256-3ZIA9yNyUVpgcu9l83PS/HxU+CMwdPhzFgIdMZRuJgw=",
285
+ "MindExecution.Plugins.PlanMaster.4fq8s1zuht.dll": "sha256-wCd+pFIrUTxI5yFCZQ1FXEZhJGHo6UukdoLmmPMgOQg=",
286
+ "MindExecution.Shared.ndzddktvwm.dll": "sha256-pX4Nlp3A+zDcMt/1DiByz3mdy94yPTbONL5bNvhRKIc=",
287
+ "MindExecution.Web.ptfprazlfv.dll": "sha256-Xe/l7y1++MwnCKB/q2u31O8UyHha84nFgXZgpD+pEBU="
288
288
  },
289
289
  "lazyAssembly": {
290
- "MindExecution.Plugins.Admin.uuf238xa0h.dll": "sha256-OrCIUack8nSWBBiZK65DlJ3YGM677RAA8cX/oJjhm5c=",
291
- "MindExecution.Plugins.Directory.ju87t8h3zs.dll": "sha256-dapAkel5qj7fK6BiDDmvkzZL96frl8k/3yP8SDr3rMw=",
292
- "MindExecution.Plugins.YouTube.5m53srfud6.dll": "sha256-02hOpWFNogHEBktxD4XUnDN/oKFJnO0g8n4bYCP0tAY="
290
+ "MindExecution.Plugins.Admin.1zm6aw94og.dll": "sha256-zRNSRurJPrU8J2jP5eOpu7KKyPtYdJqrPS/D8L2CvGY=",
291
+ "MindExecution.Plugins.Directory.askhe4ifrt.dll": "sha256-hj7+jZS7zce5h57jwBzZUdCmVmjwQaVrzA7k/rCasFk=",
292
+ "MindExecution.Plugins.YouTube.1ekzvomyd2.dll": "sha256-B+8XLMrj3cjfgNBevIDPtyuDyTjM8j5zYPKxTBIYwEI="
293
293
  }
294
294
  },
295
295
  "cacheBootResources": true,
@@ -1,5 +1,5 @@
1
1
  self.assetsManifest = {
2
- "version": "c7XVOGSh",
2
+ "version": "1QwFTqyQ",
3
3
  "assets": [
4
4
  {
5
5
  "hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
@@ -78,7 +78,7 @@
78
78
  "url": "_content/MindExecution.Shared/js/marked.min.js"
79
79
  },
80
80
  {
81
- "hash": "sha256-vg5A+jUp1q8pNFLDoYxZSJvnXKldtLM9x+4fE9ZVL8o=",
81
+ "hash": "sha256-w+HacmhIzPWqioCQJ3qhkvGgqtOlm8G/0tMPsAPtb4I=",
82
82
  "url": "_content/MindExecution.Shared/js/mind-map-core.js"
83
83
  },
84
84
  {
@@ -106,7 +106,7 @@
106
106
  "url": "_content/MindExecution.Shared/js/mind-map-glow-shader.js"
107
107
  },
108
108
  {
109
- "hash": "sha256-EQRL/Bpor3JV+VXC+nmVHqOTG+XxE61wV1Oi6c4tL8Q=",
109
+ "hash": "sha256-QpXY2g89ekLPTa3GDB/lse5U2wQm39lXq7V3RUNLhd0=",
110
110
  "url": "_content/MindExecution.Shared/js/mind-map-interactions.js"
111
111
  },
112
112
  {
@@ -406,44 +406,44 @@
406
406
  "url": "_framework/MimeMapping.og9ys58ylm.dll"
407
407
  },
408
408
  {
409
- "hash": "sha256-zsCKUWBWzDly1h5/vMtqVRb7PeG4lgfIZbQuJFyY1QU=",
410
- "url": "_framework/MindExecution.Core.y7ffihhajj.dll"
409
+ "hash": "sha256-9bpD6izq4bzR75iSm2e4S9uPoshwUG7pHxvskKk0mTo=",
410
+ "url": "_framework/MindExecution.Core.v3wmxuk7qp.dll"
411
411
  },
412
412
  {
413
- "hash": "sha256-V4pQTxua0lGWpdsFpo7bHr6rPFWZeofry7e9On+OJmo=",
414
- "url": "_framework/MindExecution.Kernel.l5y3qroa7p.dll"
413
+ "hash": "sha256-yKtHx9Ehc/GwTtP4a5pZ8K5B790qL7GrNsxlbIZ54Zo=",
414
+ "url": "_framework/MindExecution.Kernel.kx4xhfncsj.dll"
415
415
  },
416
416
  {
417
- "hash": "sha256-OrCIUack8nSWBBiZK65DlJ3YGM677RAA8cX/oJjhm5c=",
418
- "url": "_framework/MindExecution.Plugins.Admin.uuf238xa0h.dll"
417
+ "hash": "sha256-zRNSRurJPrU8J2jP5eOpu7KKyPtYdJqrPS/D8L2CvGY=",
418
+ "url": "_framework/MindExecution.Plugins.Admin.1zm6aw94og.dll"
419
419
  },
420
420
  {
421
- "hash": "sha256-T4c7+fDE4TQAXAoFmHnYM+tT7RSvAM7W0VinLPoD+6U=",
422
- "url": "_framework/MindExecution.Plugins.Business.nyr3v25v48.dll"
421
+ "hash": "sha256-Dt3CeEVDlPitVDi6wPH3cw6HGYWOzPVcyLPTlzeKry8=",
422
+ "url": "_framework/MindExecution.Plugins.Business.aundh2fuh7.dll"
423
423
  },
424
424
  {
425
- "hash": "sha256-N/QoILmTilvX5Zo4SCy7ENTCqMzSC6RIEQlEwtxkGPo=",
426
- "url": "_framework/MindExecution.Plugins.Concept.l9z9tx9svt.dll"
425
+ "hash": "sha256-3ZIA9yNyUVpgcu9l83PS/HxU+CMwdPhzFgIdMZRuJgw=",
426
+ "url": "_framework/MindExecution.Plugins.Concept.pp0hp35q6g.dll"
427
427
  },
428
428
  {
429
- "hash": "sha256-dapAkel5qj7fK6BiDDmvkzZL96frl8k/3yP8SDr3rMw=",
430
- "url": "_framework/MindExecution.Plugins.Directory.ju87t8h3zs.dll"
429
+ "hash": "sha256-hj7+jZS7zce5h57jwBzZUdCmVmjwQaVrzA7k/rCasFk=",
430
+ "url": "_framework/MindExecution.Plugins.Directory.askhe4ifrt.dll"
431
431
  },
432
432
  {
433
- "hash": "sha256-8IFpm/2fpsWD3syyl58LTSWSGC8PfcrsLdmmSKR1Sq0=",
434
- "url": "_framework/MindExecution.Plugins.PlanMaster.krn3jgvjpa.dll"
433
+ "hash": "sha256-wCd+pFIrUTxI5yFCZQ1FXEZhJGHo6UukdoLmmPMgOQg=",
434
+ "url": "_framework/MindExecution.Plugins.PlanMaster.4fq8s1zuht.dll"
435
435
  },
436
436
  {
437
- "hash": "sha256-02hOpWFNogHEBktxD4XUnDN/oKFJnO0g8n4bYCP0tAY=",
438
- "url": "_framework/MindExecution.Plugins.YouTube.5m53srfud6.dll"
437
+ "hash": "sha256-B+8XLMrj3cjfgNBevIDPtyuDyTjM8j5zYPKxTBIYwEI=",
438
+ "url": "_framework/MindExecution.Plugins.YouTube.1ekzvomyd2.dll"
439
439
  },
440
440
  {
441
- "hash": "sha256-FC0pE2bsyE9i7GNSXCghKULaYYZXUEdepb2VxPfcYaA=",
442
- "url": "_framework/MindExecution.Shared.ojp3psugsm.dll"
441
+ "hash": "sha256-pX4Nlp3A+zDcMt/1DiByz3mdy94yPTbONL5bNvhRKIc=",
442
+ "url": "_framework/MindExecution.Shared.ndzddktvwm.dll"
443
443
  },
444
444
  {
445
- "hash": "sha256-l4L9FFeaEkMfR5tjzxg1v/KgOuCHBkaQbxiwSHGxkNk=",
446
- "url": "_framework/MindExecution.Web.zd2eb9d4hz.dll"
445
+ "hash": "sha256-Xe/l7y1++MwnCKB/q2u31O8UyHha84nFgXZgpD+pEBU=",
446
+ "url": "_framework/MindExecution.Web.ptfprazlfv.dll"
447
447
  },
448
448
  {
449
449
  "hash": "sha256-IsZJ91/OW+fHzNqIgEc7Y072ns8z9dGritiSyvR9Wgc=",
@@ -766,7 +766,7 @@
766
766
  "url": "_framework/Websocket.Client.vapounvmnl.dll"
767
767
  },
768
768
  {
769
- "hash": "sha256-jl4mwfB/SA/7tIuyu1Qztx7K9dHprdtvvHgZSeQDYec=",
769
+ "hash": "sha256-lMTZnmctAhsMUucbhNCVu7o1rOZqIUUjDlSFE4nDlyg=",
770
770
  "url": "_framework/blazor.boot.json"
771
771
  },
772
772
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: c7XVOGSh */
1
+ /* Manifest version: 1QwFTqyQ */
2
2
  // Hosted deployments should prefer the network over stale offline caches.
3
3
  // This service worker immediately clears old Blazor offline caches and unregisters itself.
4
4