@jaak.ai/stamps 2.3.0-dev.3 → 2.4.0

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.
@@ -6,7 +6,7 @@ var appGlobals = require('./app-globals-V2Kpy_OQ.js');
6
6
  const defineCustomElements = async (win, options) => {
7
7
  if (typeof window === 'undefined') return undefined;
8
8
  await appGlobals.globalScripts();
9
- return index.bootstrapLazy([["jaak-stamps.cjs",[[257,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"maskSize":[2,"mask-size"],"cropMargin":[2,"crop-margin"],"useDocumentClassification":[4,"use-document-classification"],"useDocumentDetector":[4,"use-document-detector"],"preferredCamera":[1,"preferred-camera"],"captureDelay":[2,"capture-delay"],"enableBackDocumentTimer":[4,"enable-back-document-timer"],"backDocumentTimerDuration":[2,"back-document-timer-duration"],"telemetryCollectorUrl":[1,"telemetry-collector-url"],"metricsCollectorUrl":[1,"metrics-collector-url"],"enableTelemetry":[4,"enable-telemetry"],"enableMetrics":[4,"enable-metrics"],"customerId":[1,"customer-id"],"tenantId":[1,"tenant-id"],"environment":[1],"propagateTraceHeaderCorsUrls":[1,"propagate-trace-header-cors-urls"],"metricsExportIntervalMillis":[2,"metrics-export-interval-millis"],"license":[1],"licenseEnvironment":[1,"license-environment"],"traceId":[1,"trace-id"],"appId":[1,"app-id"],"detectionBoxes":[32],"sideAlignment":[32],"isMaskReady":[32],"shouldMirrorVideo":[32],"showCameraSelector":[32],"isSwitchingCamera":[32],"hasDocumentDetected":[32],"cameraInfoWithAutofocus":[32],"currentStatus":[32],"performanceData":[32],"backDocumentTimerRemaining":[32],"showManualCaptureButton":[32],"performanceDegradedMode":[32],"showPerformanceMessage":[32],"captureStateVersion":[32],"processingButton":[32],"licenseValid":[32],"licenseError":[32],"getCapturedImages":[64],"isProcessCompleted":[64],"startCapture":[64],"stopCapture":[64],"resetCapture":[64],"skipBackCapture":[64],"getStatus":[64],"preloadModel":[64],"getCameraInfo":[64],"setPreferredCamera":[64],"setCaptureDelay":[64],"getCaptureDelay":[64]}]]]], options);
9
+ return index.bootstrapLazy([["jaak-stamps.cjs",[[257,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"maskSize":[2,"mask-size"],"cropMargin":[2,"crop-margin"],"useDocumentClassification":[4,"use-document-classification"],"useDocumentDetector":[4,"use-document-detector"],"preferredCamera":[1,"preferred-camera"],"captureDelay":[2,"capture-delay"],"enableBackDocumentTimer":[4,"enable-back-document-timer"],"backDocumentTimerDuration":[2,"back-document-timer-duration"],"telemetryCollectorUrl":[1,"telemetry-collector-url"],"metricsCollectorUrl":[1,"metrics-collector-url"],"enableTelemetry":[4,"enable-telemetry"],"enableMetrics":[4,"enable-metrics"],"customerId":[1,"customer-id"],"tenantId":[1,"tenant-id"],"environment":[1],"propagateTraceHeaderCorsUrls":[1,"propagate-trace-header-cors-urls"],"metricsExportIntervalMillis":[2,"metrics-export-interval-millis"],"license":[1],"licenseEnvironment":[1,"license-environment"],"traceId":[1,"trace-id"],"appId":[1,"app-id"],"detectionBoxes":[32],"sideAlignment":[32],"isMaskReady":[32],"shouldMirrorVideo":[32],"showCameraSelector":[32],"isSwitchingCamera":[32],"hasDocumentDetected":[32],"cameraInfoWithAutofocus":[32],"currentStatus":[32],"performanceData":[32],"backDocumentTimerRemaining":[32],"showManualCaptureButton":[32],"performanceDegradedMode":[32],"showPerformanceMessage":[32],"captureStateVersion":[32],"processingButton":[32],"licenseValid":[32],"licenseError":[32],"classificationDisabled":[32],"getCapturedImages":[64],"isProcessCompleted":[64],"startCapture":[64],"stopCapture":[64],"resetCapture":[64],"skipBackCapture":[64],"getStatus":[64],"preloadModel":[64],"getCameraInfo":[64],"setPreferredCamera":[64],"setCaptureDelay":[64],"getCaptureDelay":[64]}]]]], options);
10
10
  };
11
11
 
12
12
  exports.setNonce = index.setNonce;
@@ -70,6 +70,7 @@ export class JaakStamps {
70
70
  processingButton = null; // Track which button is processing
71
71
  licenseValid = true; // License validation status
72
72
  licenseError = null; // License validation error message
73
+ classificationDisabled = false; // Classification disabled at runtime due to errors
73
74
  // Services
74
75
  licenseValidationService = null;
75
76
  serviceContainer;
@@ -122,19 +123,43 @@ export class JaakStamps {
122
123
  slowFrameCount = 0; // Contador de frames consecutivos lentos
123
124
  processedFramesCount = 0; // Contador total de frames procesados
124
125
  hasAutoSwitchedToManual = false;
126
+ _manualModeLoggedOnce = false;
125
127
  // Canvas pool for optimized screenshot capture
126
128
  canvasPool = [];
127
129
  MAX_CANVAS_POOL_SIZE = 3;
128
130
  async componentWillLoad() {
131
+ if (this.debug) {
132
+ console.log('[JAAK-DEBUG] componentWillLoad() - Props at initialization:');
133
+ console.log('[JAAK-DEBUG] useDocumentDetector:', this.useDocumentDetector, '(type:', typeof this.useDocumentDetector, ')');
134
+ console.log('[JAAK-DEBUG] useDocumentClassification:', this.useDocumentClassification);
135
+ console.log('[JAAK-DEBUG] debug:', this.debug);
136
+ console.log('[JAAK-DEBUG] license:', this.license ? this.license.substring(0, 8) + '...' : 'EMPTY');
137
+ console.log('[JAAK-DEBUG] licenseEnvironment:', this.licenseEnvironment);
138
+ console.log('[JAAK-DEBUG] alignmentTolerance:', this.alignmentTolerance);
139
+ console.log('[JAAK-DEBUG] maskSize:', this.maskSize);
140
+ console.log('[JAAK-DEBUG] captureDelay:', this.captureDelay);
141
+ console.log('[JAAK-DEBUG] preferredCamera:', this.preferredCamera);
142
+ console.log('[JAAK-DEBUG] appId:', this.appId);
143
+ }
129
144
  // License is required - always validate
130
145
  // Wait a bit to ensure props are set from attributes
131
146
  await new Promise(resolve => setTimeout(resolve, 50));
147
+ if (this.debug) {
148
+ console.log('[JAAK-DEBUG] Props AFTER 50ms wait:');
149
+ console.log('[JAAK-DEBUG] useDocumentDetector:', this.useDocumentDetector, '(type:', typeof this.useDocumentDetector, ')');
150
+ }
132
151
  this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
133
152
  await this.validateLicense();
134
153
  // If license validation failed, stop initialization
135
154
  if (!this.licenseValid) {
155
+ if (this.debug) {
156
+ console.error('[JAAK-DEBUG] License validation FAILED. Stopping initialization.');
157
+ }
136
158
  return;
137
159
  }
160
+ if (this.debug) {
161
+ console.log('[JAAK-DEBUG] License validation OK');
162
+ }
138
163
  }
139
164
  async componentDidLoad() {
140
165
  try {
@@ -283,10 +308,10 @@ export class JaakStamps {
283
308
  const ua = navigator.userAgent;
284
309
  const isIOS = /iPad|iPhone|iPod/.test(ua);
285
310
  if (isIOS) {
286
- script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web@1.23.0/dist/ort.wasm.min.js';
311
+ script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.wasm.min.js';
287
312
  }
288
313
  else {
289
- script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web@1.23.0/dist/ort.min.js';
314
+ script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js';
290
315
  }
291
316
  document.head.appendChild(script);
292
317
  await new Promise((resolve) => {
@@ -830,56 +855,85 @@ export class JaakStamps {
830
855
  // DETECTION METHODS
831
856
  async startDetection() {
832
857
  try {
858
+ if (this.debug) {
859
+ console.log('[JAAK-DEBUG] startDetection() called');
860
+ console.log('[JAAK-DEBUG] useDocumentDetector:', this.useDocumentDetector);
861
+ console.log('[JAAK-DEBUG] useDocumentClassification:', this.useDocumentClassification);
862
+ }
833
863
  // Verificar capacidades del dispositivo antes de cargar modelos
834
864
  const capabilities = this.checkDeviceCapabilities();
865
+ if (this.debug) {
866
+ console.log('[JAAK-DEBUG] Device capabilities:', JSON.stringify(capabilities));
867
+ }
835
868
  // Si el dispositivo no puede usar ML o tenemos problemas de memoria, usar modo manual
836
869
  if (!capabilities.canUseML && this.useDocumentDetector) {
870
+ if (this.debug) {
871
+ console.warn('[JAAK-DEBUG] MANUAL MODE: Device cannot use ML. Reason:', capabilities.reason);
872
+ }
837
873
  this.switchToManualModeWithWarning(capabilities.reason);
838
874
  return;
839
875
  }
840
876
  // Paso 1: Verificar y cargar modelos si es necesario
841
877
  if (!this.detectionService.isModelLoaded()) {
842
878
  const loadStartTime = performance.now();
879
+ if (this.debug) {
880
+ console.log('[JAAK-DEBUG] Loading detection model...');
881
+ }
843
882
  this.updateStatus('Preparando reconocimiento...', 'Configurando detección de documentos', 'loading');
844
883
  this.stateManager.updateCaptureState({ isLoading: true });
845
884
  try {
846
885
  await this.detectionService.loadModel();
886
+ if (this.debug) {
887
+ console.log('[JAAK-DEBUG] Detection model loaded successfully in', (performance.now() - loadStartTime).toFixed(0), 'ms');
888
+ }
847
889
  }
848
890
  catch (modelError) {
849
891
  // Si es un error de memoria, cambiar a modo manual con mensaje específico
850
892
  if (modelError.message.includes('Out of memory') || modelError.message.includes('no available backend')) {
851
893
  const memoryInfo = navigator.deviceMemory ? `(${navigator.deviceMemory}GB disponible)` : '';
894
+ if (this.debug) {
895
+ console.warn('[JAAK-DEBUG] MANUAL MODE: Out of memory loading detection model.', memoryInfo);
896
+ }
852
897
  this.switchToManualModeWithWarning(`Memoria insuficiente para detección automática ${memoryInfo}. Modo manual activado - funciona igual de bien!`);
853
898
  return;
854
899
  }
855
900
  else {
901
+ if (this.debug) {
902
+ console.error('[JAAK-DEBUG] MANUAL MODE: Error loading detection model:', modelError.message);
903
+ }
856
904
  this.switchToManualModeWithError('Error al cargar modelo de detección');
857
905
  throw modelError;
858
906
  }
859
907
  }
860
908
  this.updateStatus('Optimizando detección...', 'Configurando reconocimiento de documentos', 'loading');
909
+ if (this.debug) {
910
+ console.log('[JAAK-DEBUG] Loading classification model...');
911
+ }
861
912
  try {
862
913
  await this.detectionService.loadClassificationModel();
914
+ if (this.debug) {
915
+ console.log('[JAAK-DEBUG] Classification model loaded successfully');
916
+ }
863
917
  }
864
918
  catch (classificationError) {
865
- // Si es un error de memoria, cambiar a modo manual con mensaje específico
866
- if (classificationError.message.includes('Out of memory') || classificationError.message.includes('no available backend')) {
867
- const memoryInfo = navigator.deviceMemory ? `(${navigator.deviceMemory}GB disponible)` : '';
868
- this.switchToManualModeWithWarning(`Memoria insuficiente para clasificación automática ${memoryInfo}. Modo manual activado para optimizar rendimiento.`);
869
- return;
870
- }
871
- else {
872
- this.switchToManualModeWithError('Error al cargar modelo de clasificación');
873
- throw classificationError;
919
+ // La clasificacion es opcional, no debe bloquear la deteccion
920
+ if (this.debug) {
921
+ console.warn('[JAAK-DEBUG] Classification model failed to load, disabling classification. Error:', classificationError.message);
874
922
  }
923
+ this.classificationDisabled = true;
875
924
  }
876
925
  const loadEndTime = performance.now();
877
926
  const loadTime = loadEndTime - loadStartTime;
878
- // Record ONNX load time
879
927
  if (this.debug) {
928
+ console.log('[JAAK-DEBUG] All models loaded in', loadTime.toFixed(0), 'ms');
880
929
  this.recordOnnxPerformance(loadTime, 0);
881
930
  }
882
931
  }
932
+ else {
933
+ if (this.debug) {
934
+ console.log('[JAAK-DEBUG] Models already loaded, skipping load');
935
+ }
936
+ }
883
937
  // Paso 2: Detectar y configurar dispositivos
884
938
  this.updateStatus('Configurando cámara...', 'Buscando dispositivos disponibles', 'loading');
885
939
  try {
@@ -964,10 +1018,18 @@ export class JaakStamps {
964
1018
  try {
965
1019
  const frameStartTime = performance.now();
966
1020
  const captureState = this.stateManager.getCaptureState();
967
- if (!this.videoRef || !this.detectionContainer || !this.detectionService.isModelLoaded())
1021
+ if (!this.videoRef || !this.detectionContainer || !this.detectionService.isModelLoaded()) {
1022
+ if (this.debug) {
1023
+ console.log('[JAAK-DEBUG] detectFrame() skipped: videoRef=', !!this.videoRef, 'detectionContainer=', !!this.detectionContainer, 'modelLoaded=', this.detectionService.isModelLoaded());
1024
+ }
968
1025
  return;
1026
+ }
969
1027
  // Show manual capture button when document detector is disabled or performance is degraded
970
1028
  if (!this.useDocumentDetector || this.performanceDegradedMode) {
1029
+ if (this.debug && !this._manualModeLoggedOnce) {
1030
+ console.warn('[JAAK-DEBUG] detectFrame() in MANUAL MODE: useDocumentDetector=', this.useDocumentDetector, 'performanceDegradedMode=', this.performanceDegradedMode);
1031
+ this._manualModeLoggedOnce = true;
1032
+ }
971
1033
  this.showManualCaptureButton = true;
972
1034
  // Continue the loop for UI updates but skip detection logic
973
1035
  if (captureState.step !== 'completed') {
@@ -1017,6 +1079,9 @@ export class JaakStamps {
1017
1079
  inputTensor = this.detectionService.preprocess(this.videoRef);
1018
1080
  }
1019
1081
  catch (preprocessError) {
1082
+ if (this.debug) {
1083
+ console.error('[JAAK-DEBUG] MANUAL MODE: Preprocess error:', preprocessError.message);
1084
+ }
1020
1085
  this.switchToManualModeWithError('Error al procesar imagen');
1021
1086
  return;
1022
1087
  }
@@ -1026,6 +1091,9 @@ export class JaakStamps {
1026
1091
  inferenceTime = performance.now() - inferenceStartTime;
1027
1092
  }
1028
1093
  catch (inferenceError) {
1094
+ if (this.debug) {
1095
+ console.error('[JAAK-DEBUG] MANUAL MODE: Inference error:', inferenceError.message);
1096
+ }
1029
1097
  this.switchToManualModeWithError('Error en detección automática');
1030
1098
  return;
1031
1099
  }
@@ -1073,17 +1141,29 @@ export class JaakStamps {
1073
1141
  const totalFrameTime = frameEndTime - frameStartTime;
1074
1142
  // Sistema simplificado: Verificar rendimiento de cada frame (solo si no se ha cambiado a manual)
1075
1143
  if (this.useDocumentDetector && !this.hasAutoSwitchedToManual) {
1144
+ if (this.debug) {
1145
+ console.log(`[JAAK-DEBUG] Frame #${this.processedFramesCount} time: ${totalFrameTime.toFixed(0)}ms (threshold: ${this.PERFORMANCE_THRESHOLD_MS}ms) | inference: ${inferenceTime.toFixed(0)}ms | slowFrames: ${this.slowFrameCount}/${this.SLOW_FRAMES_TO_TRIGGER}`);
1146
+ }
1076
1147
  // Verificar si el frame es lento
1077
1148
  if (totalFrameTime >= this.PERFORMANCE_THRESHOLD_MS) {
1078
1149
  this.slowFrameCount++;
1150
+ if (this.debug) {
1151
+ console.warn(`[JAAK-DEBUG] SLOW FRAME detected: ${totalFrameTime.toFixed(0)}ms >= ${this.PERFORMANCE_THRESHOLD_MS}ms | slowFrameCount: ${this.slowFrameCount}/${this.SLOW_FRAMES_TO_TRIGGER}`);
1152
+ }
1079
1153
  // Si tenemos suficientes frames lentos consecutivos, cambiar a manual
1080
1154
  if (this.slowFrameCount >= this.SLOW_FRAMES_TO_TRIGGER) {
1155
+ if (this.debug) {
1156
+ console.error(`[JAAK-DEBUG] MANUAL MODE: Performance degraded. ${this.slowFrameCount} slow frames (>= ${this.PERFORMANCE_THRESHOLD_MS}ms) exceeded threshold of ${this.SLOW_FRAMES_TO_TRIGGER}`);
1157
+ }
1081
1158
  this.switchToManualMode();
1082
1159
  }
1083
1160
  }
1084
1161
  else {
1085
1162
  // Frame rápido, reiniciar contador
1086
1163
  if (this.slowFrameCount > 0) {
1164
+ if (this.debug) {
1165
+ console.log(`[JAAK-DEBUG] Fast frame, resetting slowFrameCount from ${this.slowFrameCount} to 0`);
1166
+ }
1087
1167
  this.slowFrameCount = 0;
1088
1168
  }
1089
1169
  }
@@ -1155,7 +1235,7 @@ export class JaakStamps {
1155
1235
  isCapturing: false
1156
1236
  };
1157
1237
  const cameraInfo = this.cameraInfoWithAutofocus;
1158
- return (h("div", { key: 'c5af80713fb108ab73d086f2acbdd11277d7d52c', class: "detector-container" }, !this.licenseValid && this.licenseError && (h("div", { key: '99c886b52f58e667f76dce00f09828b9962b3606', class: "license-error-container" }, h("div", { key: 'ffd643ef41b3a4b1aa8f40075232a1d70695d566', class: "license-error-card" }, h("svg", { key: '90e628f4e6e20ac8b27560833ada7486aac1c9fb', class: "license-error-icon", width: "64", height: "64", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("path", { key: 'cb442fe342c6c0ffb50dfcda42d0af43adedf143', d: "M12 22C12 22 20 18 20 12V5L12 2L4 5V12C4 18 12 22 12 22Z", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { key: '6b29651b70273f585d9870e71811c0cdb57ea659', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), h("circle", { key: '9ec1e61c3bc9e6f7046a49e45e7ef87880d8a443', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), h("h2", { key: '56de8037a70da2c0b185029d4a9da0c935fd8c2b', class: "license-error-title" }, "Licencia Requerida"), h("p", { key: 'b6634818db630b62c8a5aa6152adc8e6da5f329f', class: "license-error-message" }, this.licenseError), h("p", { key: '8c0b404805c2515912416b9a62d66680e6d4b411', class: "license-error-help" }, "Contacte a soporte: ", h("a", { key: '1cd69e09c282353548ad9b14985054e47b6ff218', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), h("div", { key: 'c2d13002c8f91a35b647199c77eb78b5643316df', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (h("div", { key: '094f1c85b06758399520cb85a461e1af755e3d45', class: "video-container" }, h("video", { key: 'e7973937fa0d77c9793e984d063ec29a80d464eb', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), h("div", { key: 'fb86b9eb362e13902d31803c187f5d2b6c5ac664', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index) => (h("div", { key: index, class: "detection-box", style: {
1238
+ return (h("div", { key: '9f2c1f21e7c18a77f519444bad87d29b2dfd2e6c', class: "detector-container" }, !this.licenseValid && this.licenseError && (h("div", { key: 'd2965c6d859e8dd36f6a883288f086b9a39f236d', class: "license-error-container" }, h("div", { key: '0db457c58ba390892ecc1046f410f35781d534fb', class: "license-error-card" }, h("svg", { key: '9d5bb7a635157c8515323e0506f5f5add50e07dc', class: "license-error-icon", width: "64", height: "64", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("path", { key: '938b6fd1b4c3f574c47d1678a87db8db7053945c', d: "M12 22C12 22 20 18 20 12V5L12 2L4 5V12C4 18 12 22 12 22Z", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { key: '8e5eb1966fa88e7f0a6f799cd8ce96fc86f0c291', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), h("circle", { key: 'd4f798caf065b269d9d246cd099499f9a9e86008', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), h("h2", { key: '109fcd76d9b0c27f33f037ed1c16031a3e9a7966', class: "license-error-title" }, "Licencia Requerida"), h("p", { key: 'c4d582a8e950498c80980faf25d50d3dea71ee8e', class: "license-error-message" }, this.licenseError), h("p", { key: '6b15b08047124e4cec49f8b6b02d5938c2071c9b', class: "license-error-help" }, "Contacte a soporte: ", h("a", { key: '0a6fd5acce763c068fe2ae929e16a3b90223a4b5', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), h("div", { key: 'bb7a438b6d8f506334086ee511c7deaa37ab59aa', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (h("div", { key: '1fd31d4721feb0c4cd8ff1621646d2b20211b22f', class: "video-container" }, h("video", { key: 'ec228d91b0e2a8e18a0acb898198983685c97572', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), h("div", { key: 'e1711ea66777df0e482d93a82b82bff63c9fe9f0', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index) => (h("div", { key: index, class: "detection-box", style: {
1159
1239
  position: 'absolute',
1160
1240
  left: `${box.x}px`,
1161
1241
  top: `${box.y}px`,
@@ -1164,9 +1244,9 @@ export class JaakStamps {
1164
1244
  border: '2px solid #32406C',
1165
1245
  pointerEvents: 'none',
1166
1246
  boxSizing: 'border-box'
1167
- } })))), this.isMaskReady && (h("div", { key: '28a8d52ace75ee2dc3f4cd31275f2feae0db31e3', class: "overlay-mask" }, h("div", { key: '16c956f26a514c67ae178da5db2c0d19b53acdac', class: "card-outline" }, h("div", { key: '578f111f358c0b66968b389f99235d1361ff035c', class: "side side-top" }), h("div", { key: 'e7854fd3363f340fd2c832815e7c8aaf8935e5f4', class: "side side-right" }), h("div", { key: 'c6f58f1c03506ec8920b914b76679730d1944b0e', class: "side side-bottom" }), h("div", { key: 'a1af9d6777819d2c941ff99b985c3430d673e534', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'fc9ec8cf13eb9b25140ebb9cfddd6636dc3b6e99', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '078ce12f5f2d24928d3f66eedac97f8c4bae3717', class: "back-capture-section" }, h("div", { key: '9bf0528cc9fc691c212cf413bafdfeb999b47682', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (h("button", { key: '8d5613bda9e823293181f4551dfc5a49683a0e3e', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: '19909120ab9576d4b820e528c1456f8ba5f17fb9', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: '6e1cfac4e73ace6a2e59ed601e82c3f5b2770681', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: '4aa6846d76295a428185ef3a83d15554eb2d9d00', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
1247
+ } })))), this.isMaskReady && (h("div", { key: '00e7b7a30d95f72fff38d37dbad7715262f4bcbc', class: "overlay-mask" }, h("div", { key: '7f2cefac16306c4db77145ff4a2e0c36bbf71b41', class: "card-outline" }, h("div", { key: '6a160a7be2fa6b39a01af7e7ac26612439726a0d', class: "side side-top" }), h("div", { key: '33317ed5d33142557198e315796fe472915988e5', class: "side side-right" }), h("div", { key: '15428b208d96c70da90540ade83ea736829b6cfc', class: "side side-bottom" }), h("div", { key: '615e5c6cd8861921a314372aa522ce678b035297', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '786fdc87ffc5977ccab04e201b68cca6624a3a75', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '87a0b3460776e267a6288800b4c27d790f874555', class: "back-capture-section" }, h("div", { key: 'f75551d152bc5f1b41d56daaa44c360d42b3c6d7', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (h("button", { key: '798801b00d7be739db78267224193a64813c92be', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: '14ecf72110b1583bd8c4e75f669cd8c71c01d074', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: 'ed12d7774f8399244913c468e118a6a9d9a6888b', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: 'e75d2a3da9167050fd315b27871eff612f6954ff', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
1168
1248
  ? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
1169
- : 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '1c2ca195f159238c1b234e97dd3871d0a1caa3c8', class: "camera-controls" }, h("button", { key: '085795c9083606fde64aeb211c242c031ebaf66a', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (h("div", { key: 'e153c9e786afc0e911c32056351fa358eca45d21', class: "camera-selector-dropdown" }, h("div", { key: 'cb611c0d0b3170da382cb54895888d465ac4bd0a', class: "camera-selector-header" }, h("span", { key: '200f7cdf43ec10163e573fbc00b077d75cc703ae' }, "Seleccionar C\u00E1mara"), h("button", { key: '86cd2942c5a499053e64d2432dfbaa2bf9612777', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: '1085775e191c43105ac4c645bb8fa227f1a230f5', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (h("span", { class: "selected-indicator" }, "\u2713")))))), h("div", { key: 'b7465daa8357fce5192ba4800b03fc200e065145', class: "device-info" }, h("small", { key: '2c824e7585afd324cefd071cdda380f3df5ada1b' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '703f54145582191eaddcecd22a718dd72e16f977', class: "manual-capture-section" }, h("button", { key: 'dcbaa7e780c4bdb0703653e25146b17248a2d8c9', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: 'cb989324a41f502ae740941ad75e6240051d8273', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: 'c3567ccbd287c39f72cbca897e5f643c68624b5e', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: 'b16f56f7fc7c710a4b41760515b2b8054d2aad4c', class: "flip-animation" }, h("div", { key: 'df905809f04bece3856545f8a6a1dcce89377377', class: "id-card-icon" }), h("div", { key: 'daa09f264bf3708e535a3be580b86145568d4f66', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: '1be7277ef588b42060808b575670872a6aa08925', class: "success-animation" }, h("div", { key: 'ce18848121423499a4bc7b2e95586f3a01bc6ceb', class: "check-icon" }), h("div", { key: '2e2ae20c3e4bffbf3ec45f2fd7016a485ea380c1', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: '951f37ba2b6366aa44e15c1dcf17b2ec6975131d', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '1718aa68ed5db592183696bc212c7066f35bf789', class: "status-spinner" })), h("div", { key: '45bf0d9ee7786578b34d25623667ee8336720270', class: "status-content" }, h("div", { key: '4fa2c1f9ddc62981cefbd63c19e04d14a503a406', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: '7f38fb0096a15467a63362979137981e84df55f9', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: '692e49518f3f78960b74f47741f2051e95ce9280', class: "performance-monitor" }, h("div", { key: 'be9f96048e16510203d8abc3b2b09ea9a0e91fe1', class: "performance-expanded" }, h("div", { key: 'ca19a5467a8bba02be34e3515af3f92839a4397a', class: "metrics-row" }, h("div", { key: '54a6b187da25a3a6af0c8fbfc023fb16b45bb606', class: "metric-compact" }, h("span", { key: '52b9bd1bbb8542011139b4556af213f64cc62c1f', class: "metric-label" }, "FPS"), h("span", { key: 'eff3acd45c407866e9c67205a4b4f0727b47afc8', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'fad4f7c5603ba7c2a95544d37f9d4b61c1840dca', class: "metric-compact" }, h("span", { key: 'e01386e6898c3f036f66795e71e65dad4d11366a', class: "metric-label" }, "MEM"), h("span", { key: '71cb13b49656c869be920080f7b53ce2e709a4c0', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '61fa2c277a2226f68d9dc036450dc086a1409b62', class: "metrics-row" }, h("div", { key: '752052d1cdc68a5d65c3ec3f0b85241527d251ae', class: "metric-compact" }, h("span", { key: 'de5fae8f627df6347e5569d31433a96476bba22d', class: "metric-label" }, "INF"), h("span", { key: '841c1a1b42e63e9fc4c56c72b54e07e47997f8be', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '194d01303155cda7b58a3bca1bd34795eac31556', class: "metric-compact" }, h("span", { key: '73f023e1de8b6fbc8976bc3fe1d9655d3d5f3c92', class: "metric-label" }, "FRAME"), h("span", { key: 'ddb8d7fa99b83f477bd8cbfe4ca856d2baa7a493', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: '37eb5780cd09e3c056e7094b6b028789529112e3', class: "metrics-row" }, h("div", { key: '236828977e1a634fddda1fef079c7780e469b815', class: "metric-compact" }, h("span", { key: 'd704dd8ba1e2080159a932c87208d2747feeb030', class: "metric-label" }, "DET"), h("span", { key: 'e0ceaf4cc91c00835bf92fdd3744a26958f39105', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: '96ad9e60657306f20efc285fd6eb5a83c3b8ee32', class: "metric-compact" }, h("span", { key: '25e0ea0b4f16118b0bf7b9b974997b9bf832d2f8', class: "metric-label" }, "RATE"), h("span", { key: '3f6f5370611d6fa6a927bc8ec1e03d0c262a3466', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: '429a70ff02a2a2de127cb6cfe3426df1fdc4bbae', class: "watermark" }, h("img", { key: 'cc4174740e58367b2e66b6029dcca8404a3dccee', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" }))))));
1249
+ : 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '019fdafddac5d9ad093f7d0adaf0f9dda29c8944', class: "camera-controls" }, h("button", { key: 'dbdeac63de4cf5f09f12b1757e87fc5c5c21fc29', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (h("div", { key: 'c62b8914fba9dec18ddcecfeccb1cbe0ec59fae2', class: "camera-selector-dropdown" }, h("div", { key: '9a1861c72c2ae75cced3a13b4e3cce28f2f2eff3', class: "camera-selector-header" }, h("span", { key: 'f4d20f3efe85bf727d3cc7bb380b9fa53bfd00e8' }, "Seleccionar C\u00E1mara"), h("button", { key: '2cae8c595fff51108c9a17786350cc42a129bb88', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: '643dbb27c6f52372819b9d2daf4b5f2ed67b5dc3', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (h("span", { class: "selected-indicator" }, "\u2713")))))), h("div", { key: '750fe47a0ae0eb1802b3126d8e49e6b8ad536879', class: "device-info" }, h("small", { key: 'a6fa21c1ae530708f830c17774e226c8f06d8b96' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'a2f91224f2166eb3a8962ba581196d64c7cec2cb', class: "manual-capture-section" }, h("button", { key: '4ce9090a4ed8e0346463ab0a77502a25990a2512', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: '4e9b12bdc735e86faadcf521083d42080f230183', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: 'd275dd3d3f62cfa943efd2e69d6898981c34f547', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '038cc4f1b245ff6fad917efb8d558e216de1771b', class: "flip-animation" }, h("div", { key: '61d9097585ed53d9b2798d826aac274b9ea42390', class: "id-card-icon" }), h("div", { key: '90db95f234a9f25aae40d3b2c480e6dc1a580a84', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: '586ac9d2e89fdd4bf13610e31c43142c84f4d8c3', class: "success-animation" }, h("div", { key: '8ed80578d1deacd808988d80d9677fb849267b1e', class: "check-icon" }), h("div", { key: '124615b15175f16946c0b3722fcf5a39b9ad4631', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: 'e587fd78705e91f5f3885e514f556288724bbc57', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: 'a9a8afa7f3653586778acc95ccecd6927a0350c8', class: "status-spinner" })), h("div", { key: 'db30d1bf772920b111e60ca22ff2fc8150e5d51f', class: "status-content" }, h("div", { key: '3dc8912cc18fc61d2f42173e2605ef9e3b7f906a', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: '9025868961082897f19b1c230346a985ea3e0ca2', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: '8f18ba02911a3605ed88cb6f93926f9412289e56', class: "performance-monitor" }, h("div", { key: '5531d873b7baed61d17f7b94106a7dd953e079c1', class: "performance-expanded" }, h("div", { key: 'af62b9f0dcfa3f4ecdc1925fe26d36a221d74afd', class: "metrics-row" }, h("div", { key: '230c75005a1c8608d97486063b23897da676f9d6', class: "metric-compact" }, h("span", { key: '48a28744a884124517e5ce55e0e47dd16c207a6f', class: "metric-label" }, "FPS"), h("span", { key: 'e6504c0075f9c730898dc5597a91475e99a5550f', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'df732632425cb06d47f14d18f2d87900f2ff293b', class: "metric-compact" }, h("span", { key: 'f32737c081480760714c3224749d67b4dffd6756', class: "metric-label" }, "MEM"), h("span", { key: 'd2d2ff4ed6721bfbc15bf20e41ea452b0a6f6670', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '7d6333691cf92a12c8b2974b68756d2d59df4301', class: "metrics-row" }, h("div", { key: '63f1b39293780e01c6119c14b46febf67ff58a89', class: "metric-compact" }, h("span", { key: '84f4ed08009d3a2414c3a6e097c78b69d8854a3b', class: "metric-label" }, "INF"), h("span", { key: '5512948dcebaadc442fe9161bc4ad05ae0960dbf', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '9e523d2a51c36d08748a4fa3c88f0aa48ad4482e', class: "metric-compact" }, h("span", { key: '38593b6e84eadc87f129bfc3d5494845063c936a', class: "metric-label" }, "FRAME"), h("span", { key: '5fcddc82c511360870875c1be5eaaedd1523eb20', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: 'ea0ff4f807a7c70fce1938dd9b8036362855b547', class: "metrics-row" }, h("div", { key: '929c04a5bee635a8de0e79208cd4c6fb47fb4120', class: "metric-compact" }, h("span", { key: '5f3b500ede8ffcaf1c824cb0760f18d441dd4c1b', class: "metric-label" }, "DET"), h("span", { key: '050ae9a0f52bc4614f35f16cf8d4f47e96b5d55b', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: '8cbee2808ec4355007a9c441495579235415f47b', class: "metric-compact" }, h("span", { key: '769941a75abbc120289c6663d69d3f73c783d79e', class: "metric-label" }, "RATE"), h("span", { key: '64b9954fd29a39bbf560833fdde393e4778fc6ec', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: 'bc87799947f87213ff5f781353aa948882bfdce3', class: "watermark" }, h("img", { key: 'c95b85725b371769eadb95c0d8b42d3ff2f4788d', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" }))))));
1170
1250
  }
1171
1251
  // Utility methods
1172
1252
  updateDetectionBoxes(boxes) {
@@ -1388,7 +1468,7 @@ export class JaakStamps {
1388
1468
  }
1389
1469
  });
1390
1470
  // Check if document classification is enabled (independent of detector)
1391
- if (this.useDocumentClassification) {
1471
+ if (this.useDocumentClassification && !this.classificationDisabled) {
1392
1472
  try {
1393
1473
  const classification = await this.detectionService.classifyDocument(croppedCanvas);
1394
1474
  if (classification && classification.class === 'passport') {
@@ -1479,7 +1559,7 @@ export class JaakStamps {
1479
1559
  this.tracingService?.setSpanAttribute(span, 'side', 'front');
1480
1560
  }
1481
1561
  // Check if document classification is enabled
1482
- if (this.useDocumentClassification) {
1562
+ if (this.useDocumentClassification && !this.classificationDisabled) {
1483
1563
  try {
1484
1564
  const classification = await this.detectionService.classifyDocument(croppedCanvas);
1485
1565
  if (classification && classification.class === 'passport') {
@@ -1548,6 +1628,11 @@ export class JaakStamps {
1548
1628
  if (!this.useDocumentDetector || this.hasAutoSwitchedToManual) {
1549
1629
  return;
1550
1630
  }
1631
+ if (this.debug) {
1632
+ console.warn('[JAAK-DEBUG] switchToManualMode() called - PERFORMANCE DEGRADED');
1633
+ console.warn('[JAAK-DEBUG] Cause: Slow frames exceeded threshold');
1634
+ console.warn('[JAAK-DEBUG] slowFrameCount:', this.slowFrameCount, '| threshold:', this.PERFORMANCE_THRESHOLD_MS, 'ms | trigger:', this.SLOW_FRAMES_TO_TRIGGER);
1635
+ }
1551
1636
  // Detener todo el monitoreo de performance
1552
1637
  this.stopPerformanceMonitoring();
1553
1638
  // Liberar recursos de ONNX
@@ -1570,6 +1655,11 @@ export class JaakStamps {
1570
1655
  if (!this.useDocumentDetector || this.hasAutoSwitchedToManual) {
1571
1656
  return;
1572
1657
  }
1658
+ if (this.debug) {
1659
+ console.warn('[JAAK-DEBUG] switchToManualModeWithWarning() called');
1660
+ console.warn('[JAAK-DEBUG] Cause:', warningMessage);
1661
+ console.warn('[JAAK-DEBUG] deviceMemory:', navigator.deviceMemory, '| hardwareConcurrency:', navigator.hardwareConcurrency);
1662
+ }
1573
1663
  // No necesitamos liberar recursos ONNX porque no se han cargado aún
1574
1664
  // Resetear máscara a blanco y limpiar detecciones
1575
1665
  this.resetMaskToWhite();
@@ -1578,7 +1668,7 @@ export class JaakStamps {
1578
1668
  this.hasAutoSwitchedToManual = true;
1579
1669
  this.performanceDegradedMode = true;
1580
1670
  this.showManualCaptureButton = true;
1581
- this.useDocumentDetector = false; // Desactivar detector automático
1671
+ // No modificar @Prop directamente (immutable). hasAutoSwitchedToManual + performanceDegradedMode ya desactivan la deteccion.
1582
1672
  // Actualizar el estado con mensaje informativo (no error)
1583
1673
  this.updateStatus('Modo manual activado', warningMessage, 'active');
1584
1674
  // Continuar con la configuración de cámara
@@ -1639,6 +1729,11 @@ export class JaakStamps {
1639
1729
  if (!this.useDocumentDetector || this.hasAutoSwitchedToManual) {
1640
1730
  return;
1641
1731
  }
1732
+ if (this.debug) {
1733
+ console.error('[JAAK-DEBUG] switchToManualModeWithError() called');
1734
+ console.error('[JAAK-DEBUG] Cause:', errorMessage);
1735
+ console.error('[JAAK-DEBUG] deviceMemory:', navigator.deviceMemory, '| hardwareConcurrency:', navigator.hardwareConcurrency);
1736
+ }
1642
1737
  // Liberar recursos de ONNX inmediatamente
1643
1738
  this.releaseOnnxResources();
1644
1739
  // Resetear máscara a blanco y limpiar detecciones
@@ -1648,7 +1743,7 @@ export class JaakStamps {
1648
1743
  this.hasAutoSwitchedToManual = true;
1649
1744
  this.performanceDegradedMode = true;
1650
1745
  this.showManualCaptureButton = true;
1651
- this.useDocumentDetector = false; // Desactivar detector automático
1746
+ // No modificar @Prop directamente (immutable). hasAutoSwitchedToManual + performanceDegradedMode ya desactivan la deteccion.
1652
1747
  // Actualizar el estado con mensaje de error
1653
1748
  this.updateStatus('Modo manual activado', errorMessage, 'error');
1654
1749
  // Continuar con la configuración de cámara para mostrar el video
@@ -2457,7 +2552,8 @@ export class JaakStamps {
2457
2552
  "captureStateVersion": {},
2458
2553
  "processingButton": {},
2459
2554
  "licenseValid": {},
2460
- "licenseError": {}
2555
+ "licenseError": {},
2556
+ "classificationDisabled": {}
2461
2557
  };
2462
2558
  }
2463
2559
  static get events() {