@jaak.ai/stamps 2.1.0-dev.2 → 2.1.0-dev.4
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/dist/cjs/jaak-stamps-webcomponent.cjs.js +1 -1
- package/dist/cjs/jaak-stamps.cjs.entry.js +192 -39
- package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
- package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/my-component/my-component.css +19 -0
- package/dist/collection/components/my-component/my-component.js +194 -45
- package/dist/collection/components/my-component/my-component.js.map +1 -1
- package/dist/components/jaak-stamps.js +194 -39
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/jaak-stamps-webcomponent.js +1 -1
- package/dist/esm/jaak-stamps.entry.js +192 -39
- package/dist/esm/jaak-stamps.entry.js.map +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
- package/dist/jaak-stamps-webcomponent/p-091d609b.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-091d609b.entry.js.map +1 -0
- package/dist/types/components/my-component/my-component.d.ts +11 -0
- package/package.json +1 -1
- package/dist/jaak-stamps-webcomponent/p-41e88688.entry.js +0 -2
- package/dist/jaak-stamps-webcomponent/p-41e88688.entry.js.map +0 -1
package/dist/cjs/loader.cjs.js
CHANGED
|
@@ -5,7 +5,7 @@ var index = require('./index-BfhtOB0D.js');
|
|
|
5
5
|
const defineCustomElements = async (win, options) => {
|
|
6
6
|
if (typeof window === 'undefined') return undefined;
|
|
7
7
|
await index.globalScripts();
|
|
8
|
-
return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"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"],"detectionBoxes":[32],"sideAlignment":[32],"isMaskReady":[32],"shouldMirrorVideo":[32],"showCameraSelector":[32],"isSwitchingCamera":[32],"hasDocumentDetected":[32],"cameraInfoWithAutofocus":[32],"currentStatus":[32],"performanceData":[32],"backDocumentTimerRemaining":[32],"showManualCaptureButton":[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);
|
|
8
|
+
return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"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"],"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],"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
9
|
};
|
|
10
10
|
|
|
11
11
|
exports.setNonce = index.setNonce;
|
|
@@ -621,6 +621,25 @@ video {
|
|
|
621
621
|
to { opacity: 1; transform: translateY(0); }
|
|
622
622
|
}
|
|
623
623
|
|
|
624
|
+
/* Performance warning animation for guide-text */
|
|
625
|
+
.guide-text.performance-warning-text {
|
|
626
|
+
animation: gentlePulse 2s ease-in-out infinite;
|
|
627
|
+
background: rgba(255, 107, 107, 0.3);
|
|
628
|
+
border: 1px solid rgba(255, 107, 107, 0.5);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
@keyframes gentlePulse {
|
|
632
|
+
0%, 100% {
|
|
633
|
+
transform: translate(-50%, -50%) scale(1);
|
|
634
|
+
background: rgba(255, 107, 107, 0.3);
|
|
635
|
+
}
|
|
636
|
+
50% {
|
|
637
|
+
transform: translate(-50%, -50%) scale(1.02);
|
|
638
|
+
background: rgba(255, 107, 107, 0.4);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
|
|
624
643
|
/* Botón para saltar reverso */
|
|
625
644
|
.skip-button {
|
|
626
645
|
pointer-events: auto;
|
|
@@ -49,6 +49,8 @@ export class JaakStamps {
|
|
|
49
49
|
};
|
|
50
50
|
backDocumentTimerRemaining = 0;
|
|
51
51
|
showManualCaptureButton = false;
|
|
52
|
+
performanceDegradedMode = false; // Auto-switched to manual mode due to performance
|
|
53
|
+
showPerformanceMessage = false; // Show performance message temporarily
|
|
52
54
|
// Services
|
|
53
55
|
serviceContainer;
|
|
54
56
|
eventBus;
|
|
@@ -72,7 +74,6 @@ export class JaakStamps {
|
|
|
72
74
|
fps: 0,
|
|
73
75
|
inferenceTime: 0,
|
|
74
76
|
memoryUsage: 0,
|
|
75
|
-
cpuUsage: 0,
|
|
76
77
|
onnxLoadTime: 0,
|
|
77
78
|
frameProcessingTime: 0,
|
|
78
79
|
totalDetections: 0,
|
|
@@ -91,6 +92,12 @@ export class JaakStamps {
|
|
|
91
92
|
MIN_INFERENCE_INTERVAL = 50;
|
|
92
93
|
performanceHistory = [];
|
|
93
94
|
PERFORMANCE_HISTORY_SIZE = 10;
|
|
95
|
+
// Sistema simplificado de monitoreo de rendimiento
|
|
96
|
+
PERFORMANCE_THRESHOLD_MS = 2000; // Umbral único para todos los frames
|
|
97
|
+
SLOW_FRAMES_TO_TRIGGER = 2; // Cuántos frames lentos consecutivos antes de cambiar
|
|
98
|
+
slowFrameCount = 0; // Contador de frames consecutivos lentos
|
|
99
|
+
processedFramesCount = 0; // Contador total de frames procesados
|
|
100
|
+
hasAutoSwitchedToManual = false;
|
|
94
101
|
// Canvas pool for optimized screenshot capture
|
|
95
102
|
canvasPool = [];
|
|
96
103
|
MAX_CANVAS_POOL_SIZE = 3;
|
|
@@ -123,14 +130,8 @@ export class JaakStamps {
|
|
|
123
130
|
this.detectionService = this.serviceContainer.getDetectionService();
|
|
124
131
|
}
|
|
125
132
|
async setupEventListeners() {
|
|
126
|
-
this.eventBus.on('state-changed', (
|
|
127
|
-
this.handleStateChange(
|
|
128
|
-
});
|
|
129
|
-
this.eventBus.on('camera-changed', () => {
|
|
130
|
-
// Camera changed event
|
|
131
|
-
});
|
|
132
|
-
this.eventBus.on('error', () => {
|
|
133
|
-
// Handle service errors
|
|
133
|
+
this.eventBus.on('state-changed', () => {
|
|
134
|
+
this.handleStateChange();
|
|
134
135
|
});
|
|
135
136
|
}
|
|
136
137
|
async initializeComponent() {
|
|
@@ -237,13 +238,8 @@ export class JaakStamps {
|
|
|
237
238
|
return false;
|
|
238
239
|
}
|
|
239
240
|
}
|
|
240
|
-
handleStateChange(
|
|
241
|
-
//
|
|
242
|
-
// This is where the component updates its internal state based on service state changes
|
|
243
|
-
if (data.changes.isLoading !== undefined) {
|
|
244
|
-
// Force re-render when loading state changes
|
|
245
|
-
// Note: Stencil automatically re-renders when @State changes
|
|
246
|
-
}
|
|
241
|
+
handleStateChange() {
|
|
242
|
+
// Handle state changes from StateManager if needed
|
|
247
243
|
}
|
|
248
244
|
initializeResizeObserver() {
|
|
249
245
|
if ('ResizeObserver' in window && this.detectionContainer) {
|
|
@@ -264,6 +260,10 @@ export class JaakStamps {
|
|
|
264
260
|
if (step === 'completed') {
|
|
265
261
|
return 'Proceso completado';
|
|
266
262
|
}
|
|
263
|
+
// Check if we should show performance message
|
|
264
|
+
if (this.showPerformanceMessage && step === 'front') {
|
|
265
|
+
return 'Modo manual activado por rendimiento. Use el botón para capturar.';
|
|
266
|
+
}
|
|
267
267
|
if (step === 'front') {
|
|
268
268
|
// Para el frente, si el detector manual está activo, mostrar instrucciones de captura manual
|
|
269
269
|
if (this.showManualCaptureButton) {
|
|
@@ -493,9 +493,23 @@ export class JaakStamps {
|
|
|
493
493
|
if (this.stateManager) {
|
|
494
494
|
this.stateManager.updateCaptureState({ isLoading: true });
|
|
495
495
|
}
|
|
496
|
-
|
|
496
|
+
try {
|
|
497
|
+
await this.detectionService.loadModel();
|
|
498
|
+
}
|
|
499
|
+
catch (modelError) {
|
|
500
|
+
console.error('Error cargando modelo de detección:', modelError);
|
|
501
|
+
this.switchToManualModeWithError('Error al cargar modelo de detección');
|
|
502
|
+
throw modelError;
|
|
503
|
+
}
|
|
497
504
|
this.updateStatus('Optimizando detección...', 'Configurando reconocimiento de documentos', 'loading');
|
|
498
|
-
|
|
505
|
+
try {
|
|
506
|
+
await this.detectionService.loadClassificationModel();
|
|
507
|
+
}
|
|
508
|
+
catch (classificationError) {
|
|
509
|
+
console.error('Error cargando modelo de clasificación:', classificationError);
|
|
510
|
+
this.switchToManualModeWithError('Error al cargar modelo de clasificación');
|
|
511
|
+
throw classificationError;
|
|
512
|
+
}
|
|
499
513
|
const loadEndTime = performance.now();
|
|
500
514
|
const loadTime = loadEndTime - loadStartTime;
|
|
501
515
|
// Record ONNX load time
|
|
@@ -612,9 +626,23 @@ export class JaakStamps {
|
|
|
612
626
|
const loadStartTime = performance.now();
|
|
613
627
|
this.updateStatus('Preparando reconocimiento...', 'Configurando detección de documentos', 'loading');
|
|
614
628
|
this.stateManager.updateCaptureState({ isLoading: true });
|
|
615
|
-
|
|
629
|
+
try {
|
|
630
|
+
await this.detectionService.loadModel();
|
|
631
|
+
}
|
|
632
|
+
catch (modelError) {
|
|
633
|
+
console.error('Error cargando modelo de detección:', modelError);
|
|
634
|
+
this.switchToManualModeWithError('Error al cargar modelo de detección');
|
|
635
|
+
throw modelError;
|
|
636
|
+
}
|
|
616
637
|
this.updateStatus('Optimizando detección...', 'Configurando reconocimiento de documentos', 'loading');
|
|
617
|
-
|
|
638
|
+
try {
|
|
639
|
+
await this.detectionService.loadClassificationModel();
|
|
640
|
+
}
|
|
641
|
+
catch (classificationError) {
|
|
642
|
+
console.error('Error cargando modelo de clasificación:', classificationError);
|
|
643
|
+
this.switchToManualModeWithError('Error al cargar modelo de clasificación');
|
|
644
|
+
throw classificationError;
|
|
645
|
+
}
|
|
618
646
|
const loadEndTime = performance.now();
|
|
619
647
|
const loadTime = loadEndTime - loadStartTime;
|
|
620
648
|
// Record ONNX load time
|
|
@@ -629,9 +657,9 @@ export class JaakStamps {
|
|
|
629
657
|
// Paso 3: Configurar cámara seleccionada
|
|
630
658
|
this.updateStatus('Ajustando cámara...', 'Configurando calidad de imagen', 'loading');
|
|
631
659
|
const stream = await this.cameraService.setupCamera();
|
|
632
|
-
// Paso 4: Inicializar video y
|
|
660
|
+
// Paso 4: Inicializar video y mostrar estado de análisis inicial
|
|
633
661
|
if (this.useDocumentDetector) {
|
|
634
|
-
this.updateStatus('
|
|
662
|
+
this.updateStatus('Analizando estabilidad...', 'Evaluando rendimiento del sistema', 'loading');
|
|
635
663
|
}
|
|
636
664
|
else {
|
|
637
665
|
this.updateStatus('Captura activa', 'Posicione su documento y use el botón para capturar', 'active');
|
|
@@ -681,8 +709,8 @@ export class JaakStamps {
|
|
|
681
709
|
const captureState = this.stateManager.getCaptureState();
|
|
682
710
|
if (!this.videoRef || !this.detectionContainer || !this.detectionService.isModelLoaded())
|
|
683
711
|
return;
|
|
684
|
-
// Show manual capture button when document detector is disabled
|
|
685
|
-
if (!this.useDocumentDetector) {
|
|
712
|
+
// Show manual capture button when document detector is disabled or performance is degraded
|
|
713
|
+
if (!this.useDocumentDetector || this.performanceDegradedMode) {
|
|
686
714
|
this.showManualCaptureButton = true;
|
|
687
715
|
// Continue the loop for UI updates but skip detection logic
|
|
688
716
|
if (captureState.step !== 'completed') {
|
|
@@ -690,7 +718,7 @@ export class JaakStamps {
|
|
|
690
718
|
}
|
|
691
719
|
return;
|
|
692
720
|
}
|
|
693
|
-
else {
|
|
721
|
+
else if (!this.performanceDegradedMode) {
|
|
694
722
|
this.showManualCaptureButton = false;
|
|
695
723
|
}
|
|
696
724
|
if (captureState.isDetectionPaused) {
|
|
@@ -720,10 +748,29 @@ export class JaakStamps {
|
|
|
720
748
|
this.lastInferenceTime = currentTime;
|
|
721
749
|
// Measure preprocessing and inference time
|
|
722
750
|
const inferenceStartTime = performance.now();
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
751
|
+
let inputTensor;
|
|
752
|
+
let detections;
|
|
753
|
+
let inferenceTime;
|
|
754
|
+
try {
|
|
755
|
+
inputTensor = this.detectionService.preprocess(this.videoRef);
|
|
756
|
+
}
|
|
757
|
+
catch (preprocessError) {
|
|
758
|
+
console.error('Error en preprocesamiento:', preprocessError);
|
|
759
|
+
this.switchToManualModeWithError('Error al procesar imagen');
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
try {
|
|
763
|
+
// Standard detection without timeout (timeout is handled by frame counting)
|
|
764
|
+
detections = await this.detectionService.runInference(inputTensor);
|
|
765
|
+
inferenceTime = performance.now() - inferenceStartTime;
|
|
766
|
+
}
|
|
767
|
+
catch (inferenceError) {
|
|
768
|
+
console.error('Error en inferencia ONNX:', inferenceError);
|
|
769
|
+
this.switchToManualModeWithError('Error en detección automática');
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
// Increment frame count
|
|
773
|
+
this.processedFramesCount++;
|
|
727
774
|
// Record ONNX performance metrics
|
|
728
775
|
if (this.debug) {
|
|
729
776
|
this.recordOnnxPerformance(0, inferenceTime);
|
|
@@ -762,9 +809,30 @@ export class JaakStamps {
|
|
|
762
809
|
}
|
|
763
810
|
this.updateMaskColor(detections);
|
|
764
811
|
// Record frame processing metrics
|
|
812
|
+
const frameEndTime = performance.now();
|
|
813
|
+
const totalFrameTime = frameEndTime - frameStartTime;
|
|
814
|
+
// Sistema simplificado: Verificar rendimiento de cada frame (solo si no se ha cambiado a manual)
|
|
815
|
+
if (this.useDocumentDetector && !this.hasAutoSwitchedToManual) {
|
|
816
|
+
// Verificar si el frame es lento
|
|
817
|
+
if (totalFrameTime >= this.PERFORMANCE_THRESHOLD_MS) {
|
|
818
|
+
this.slowFrameCount++;
|
|
819
|
+
// Si tenemos suficientes frames lentos consecutivos, cambiar a manual
|
|
820
|
+
if (this.slowFrameCount >= this.SLOW_FRAMES_TO_TRIGGER) {
|
|
821
|
+
this.switchToManualMode();
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
else {
|
|
825
|
+
// Frame rápido, reiniciar contador
|
|
826
|
+
if (this.slowFrameCount > 0) {
|
|
827
|
+
this.slowFrameCount = 0;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
// Cambiar mensaje de estado después de analizar los primeros 2 frames
|
|
831
|
+
if (this.processedFramesCount === 2) {
|
|
832
|
+
this.updateStatus('Captura activa', 'Buscando documento en el marco de captura', 'active');
|
|
833
|
+
}
|
|
834
|
+
}
|
|
765
835
|
if (this.debug) {
|
|
766
|
-
const frameEndTime = performance.now();
|
|
767
|
-
const totalFrameTime = frameEndTime - frameStartTime;
|
|
768
836
|
this.recordFrameProcessing(totalFrameTime, detections.length);
|
|
769
837
|
}
|
|
770
838
|
// Continue detection loop
|
|
@@ -800,6 +868,8 @@ export class JaakStamps {
|
|
|
800
868
|
clearTimeout(this.alignmentTimer);
|
|
801
869
|
this.alignmentTimer = undefined;
|
|
802
870
|
}
|
|
871
|
+
// Liberar recursos de ONNX al limpiar el componente
|
|
872
|
+
this.releaseOnnxResources();
|
|
803
873
|
if (this.performanceUpdateInterval) {
|
|
804
874
|
clearInterval(this.performanceUpdateInterval);
|
|
805
875
|
this.performanceUpdateInterval = undefined;
|
|
@@ -821,7 +891,7 @@ export class JaakStamps {
|
|
|
821
891
|
isCapturing: false
|
|
822
892
|
};
|
|
823
893
|
const cameraInfo = this.cameraInfoWithAutofocus;
|
|
824
|
-
return (h("div", { key: '
|
|
894
|
+
return (h("div", { key: '79f84b34f4c6641f0afce6825e9a916c5f1ce1fc', class: "detector-container" }, h("div", { key: '1784b74d259071b2c2f879d67bda08cdaf011c76', class: "video-container" }, h("video", { key: '48704208b83a9adfd6511266e1848dab8c583b2c', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), h("div", { key: 'b55b96ef64557caee6b0e0c401a96c6b20e3785f', 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: {
|
|
825
895
|
position: 'absolute',
|
|
826
896
|
left: `${box.x}px`,
|
|
827
897
|
top: `${box.y}px`,
|
|
@@ -830,9 +900,9 @@ export class JaakStamps {
|
|
|
830
900
|
border: '2px solid #32406C',
|
|
831
901
|
pointerEvents: 'none',
|
|
832
902
|
boxSizing: 'border-box'
|
|
833
|
-
} })))), this.isMaskReady && (h("div", { key: '
|
|
903
|
+
} })))), this.isMaskReady && (h("div", { key: 'd398db06f067890474b9ab3fef67fe9712a81948', class: "overlay-mask" }, h("div", { key: 'c328eef8a3da4f01aecc2c163b5c3baadee2ab7a', class: "card-outline" }, h("div", { key: 'e022c6746096b1b35d4e74295d9872092234fa3e', class: "side side-top" }), h("div", { key: '709bd54e7619572b499e8d044ead38e0baab546e', class: "side side-right" }), h("div", { key: '330de7072bbb208fad6f10a160c9794438d0dd76', class: "side side-bottom" }), h("div", { key: 'a12f18f2c2200ee74809f3bed3ee1218ced498ca', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'fb049290c464fa7137c174b2a2fcb5f8e1620f5d', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '7d027c1dfb1ea855b8d49d5b8934c81be2b73d65', class: "back-capture-section" }, h("div", { key: 'cb2f5cbd36d0fa66782a37dc8b00226a35997629', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode) && (h("button", { key: '5cee5c2176f23849eb9494505e66e27ca5bbdf6b', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: captureState.isCapturing }, captureState.isCapturing ? 'Capturando...' : 'Capturar Reverso')), h("button", { key: '24b4171ed4a56fad56a61a9daa4529de618a5f94', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button" }, this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
|
|
834
904
|
? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
|
|
835
|
-
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '
|
|
905
|
+
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: 'f0b8bfed998c950e30de0e43662a1965374c6180', class: "camera-controls" }, h("button", { key: '7c795a9aa31249f2d42bc45e6d77fba633b7400f', 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: '97ffdf5203e6d7ed1139b7d88088761c1f2adb80', class: "camera-selector-dropdown" }, h("div", { key: '0ba533fa51f946abdcc535e07c86f31fd0d1d4bb', class: "camera-selector-header" }, h("span", { key: '244b13d266e69326a81228e9b0679fd8264ea91d' }, "Seleccionar C\u00E1mara"), h("button", { key: '975c809b348f39bccb6887d710909a58a7222a88', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: '40df0a7ac0bda961362af72b5a03d448bc4481db', 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: 'ea50280fbc4e96feea026c8ff6dc590ff5e76a59', class: "device-info" }, h("small", { key: '19209e350b073e2cc5d3e713c69da863cf98e92e' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '6a91d0c3d72b9bdbf9f0b6d9d33aff440cb3bcb5', class: "manual-capture-section" }, h("button", { key: '6474971d1a21f45dfeee90b9c39d5fd7e9f142fa', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: captureState.isCapturing }, captureState.isCapturing ? 'Capturando...' : 'Capturar Frente'))))), captureState.isCapturing && (h("div", { key: '0f2cb967caa746f34f442ed17edbeeeea3be1e2d', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: 'a1a6c67d34b27639d4ca6ab3cf790d184aab64bc', class: "flip-animation" }, h("div", { key: '4b2d5fe6d18bb77d6515312f53fd189ed2af9db6', class: "id-card-icon" }), h("div", { key: '27bd058bd46ecea5ee7bf174a0aa45de519190bf', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: 'd155e5d2f926c33183f83dabf887bb785d856b14', class: "success-animation" }, h("div", { key: 'e57b7c8d6685146ac2215f52a92ff23e3fbd2d97', class: "check-icon" }), h("div", { key: '0e3de74b19434f49919b4ef78f91dd89c7a80799', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: '8401bf78d349be4900de4e0a23a9fddfafcacc4f', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '2b55d22272cd78aa39fd15dd9bdf2317a0737b9f', class: "status-spinner" })), h("div", { key: '10dfb478b8803f70c787c9d9412d517de1bcf852', class: "status-content" }, h("div", { key: '4cf6feb47ad6c2099219bb73eb0d46e3cbfb2bc3', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: 'e32df69c147070853977ceae6ec45d8c389e1905', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: '52a1512ef7b93ecef95cb727c7639661506a7f8d', class: "performance-monitor" }, h("div", { key: 'b7dfdeb4453c507338d4156e99a70c8ed8cb5436', class: "performance-expanded" }, h("div", { key: '79baa5412635f433400b127353c940d4bd1449c4', class: "metrics-row" }, h("div", { key: '12f8d4f530ddea03cbe61bbbf00eb761d55e48b2', class: "metric-compact" }, h("span", { key: '3f8d1d37bbb38424ad8def6c2b7f4aa4dfd35876', class: "metric-label" }, "FPS"), h("span", { key: '3010d0633a058f703c19776d19c88c753085af01', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'e5564951b463363ab4965a08f9f8ed37ff202ba2', class: "metric-compact" }, h("span", { key: '2b69e25dd1db6f9239c3de12af10a1ce261158c9', class: "metric-label" }, "MEM"), h("span", { key: '0e0189eb3f91ed5accc197224c55688ea7e93372', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '174c09dbf46186a14d8534a8584c262ba79873fe', class: "metrics-row" }, h("div", { key: '7af195560eeacfd310544d607feee9c3f87327b9', class: "metric-compact" }, h("span", { key: 'fc8a27ca7484635685acab3b7aa0a0fd4fa9021b', class: "metric-label" }, "INF"), h("span", { key: 'bd3ba0e8dd1bf1f21652a986558ccef732572cbc', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '16109503ddd7bd856d6f82a385bece73f1bacc05', class: "metric-compact" }, h("span", { key: '9328438dd8e9c1f0f715f6cfa28baaca27c4244f', class: "metric-label" }, "FRAME"), h("span", { key: '8fa3cf73868bc0cbdaaad3cc6bb48b25a809617c', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: 'dc616be04663364254c38b1f2e96f15ccd52a495', class: "metrics-row" }, h("div", { key: '1fa771776e4dc3b0b86c9a195a6d518aa4e7df5f', class: "metric-compact" }, h("span", { key: '2f5fb1713ab76b0c84677f9df06f53ac83065cee', class: "metric-label" }, "DET"), h("span", { key: 'fd83bda90479a6101593e9b06c7c3fd10da70b67', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: '7c7f811a14caa371ac08e7945387f58c30039f9f', class: "metric-compact" }, h("span", { key: '872b9fa154731d48edf6d08b942bdcea4771fd6c', class: "metric-label" }, "RATE"), h("span", { key: '77f9b485a575735159dfbfd846dc2fd2a3dd3413', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: 'b7ab14e0f956ffb7a6658e6d97a26fe49be94a7f', class: "watermark" }, h("img", { key: '3f3807001884966bdf6e1a045d009859f8dcd0f3', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
|
|
836
906
|
}
|
|
837
907
|
// Utility methods
|
|
838
908
|
updateDetectionBoxes(boxes) {
|
|
@@ -1020,12 +1090,18 @@ export class JaakStamps {
|
|
|
1020
1090
|
});
|
|
1021
1091
|
// Check if document classification is enabled (independent of detector)
|
|
1022
1092
|
if (this.useDocumentClassification) {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1093
|
+
try {
|
|
1094
|
+
const classification = await this.detectionService.classifyDocument(croppedCanvas);
|
|
1095
|
+
if (classification && classification.class === 'passport') {
|
|
1096
|
+
this.completeProcess(true);
|
|
1097
|
+
this.returnCanvasToPool(captureCanvas);
|
|
1098
|
+
this.returnCanvasToPool(croppedCanvas);
|
|
1099
|
+
return;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
catch (classifyError) {
|
|
1103
|
+
console.error('Error clasificando documento:', classifyError);
|
|
1104
|
+
// No cambiar a manual aquí, solo registrar el error y continuar
|
|
1029
1105
|
}
|
|
1030
1106
|
}
|
|
1031
1107
|
this.stateManager.updateCaptureState({
|
|
@@ -1087,10 +1163,16 @@ export class JaakStamps {
|
|
|
1087
1163
|
});
|
|
1088
1164
|
// Check if document classification is enabled
|
|
1089
1165
|
if (this.useDocumentClassification) {
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1166
|
+
try {
|
|
1167
|
+
const classification = await this.detectionService.classifyDocument(croppedCanvas);
|
|
1168
|
+
if (classification && classification.class === 'passport') {
|
|
1169
|
+
this.completeProcess(true);
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
catch (classifyError) {
|
|
1174
|
+
console.error('Error clasificando documento:', classifyError);
|
|
1175
|
+
// No cambiar a manual aquí, solo registrar el error y continuar
|
|
1094
1176
|
}
|
|
1095
1177
|
}
|
|
1096
1178
|
this.stateManager.updateCaptureState({
|
|
@@ -1127,6 +1209,64 @@ export class JaakStamps {
|
|
|
1127
1209
|
cardOutline?.classList.remove('capturing');
|
|
1128
1210
|
}, 600);
|
|
1129
1211
|
}
|
|
1212
|
+
// Método simplificado para cambio a modo manual
|
|
1213
|
+
switchToManualMode() {
|
|
1214
|
+
// Only switch if detector is enabled and not already switched
|
|
1215
|
+
if (!this.useDocumentDetector || this.hasAutoSwitchedToManual) {
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1218
|
+
// Detener todo el monitoreo de performance
|
|
1219
|
+
this.stopPerformanceMonitoring();
|
|
1220
|
+
// Liberar recursos de ONNX
|
|
1221
|
+
this.releaseOnnxResources();
|
|
1222
|
+
this.hasAutoSwitchedToManual = true;
|
|
1223
|
+
this.performanceDegradedMode = true;
|
|
1224
|
+
this.showManualCaptureButton = true;
|
|
1225
|
+
this.showPerformanceMessage = true;
|
|
1226
|
+
// Hide performance message after 5 seconds
|
|
1227
|
+
setTimeout(() => {
|
|
1228
|
+
this.showPerformanceMessage = false;
|
|
1229
|
+
}, 5000);
|
|
1230
|
+
}
|
|
1231
|
+
// Método para cambiar a modo manual por errores de ONNX
|
|
1232
|
+
switchToManualModeWithError(errorMessage) {
|
|
1233
|
+
console.error(`[ONNX Error] ${errorMessage}`);
|
|
1234
|
+
// Solo cambiar si el detector está habilitado y no se ha cambiado ya
|
|
1235
|
+
if (!this.useDocumentDetector || this.hasAutoSwitchedToManual) {
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
// Liberar recursos de ONNX inmediatamente
|
|
1239
|
+
this.releaseOnnxResources();
|
|
1240
|
+
// Cambiar a modo manual
|
|
1241
|
+
this.hasAutoSwitchedToManual = true;
|
|
1242
|
+
this.performanceDegradedMode = true;
|
|
1243
|
+
this.showManualCaptureButton = true;
|
|
1244
|
+
this.useDocumentDetector = false; // Desactivar detector automático
|
|
1245
|
+
// Actualizar el estado con mensaje de error
|
|
1246
|
+
this.updateStatus('Modo manual activado', errorMessage, 'error');
|
|
1247
|
+
// Ocultar mensaje después de 5 segundos
|
|
1248
|
+
setTimeout(() => {
|
|
1249
|
+
this.updateStatus('Captura manual', 'Use el botón para capturar', 'ready');
|
|
1250
|
+
}, 5000);
|
|
1251
|
+
}
|
|
1252
|
+
stopPerformanceMonitoring() {
|
|
1253
|
+
// Nota: No necesitamos limpiar más variables porque ya no se usarán
|
|
1254
|
+
// El sistema automáticamente saltará la lógica de performance una vez que hasAutoSwitchedToManual = true
|
|
1255
|
+
}
|
|
1256
|
+
// Método para liberar recursos de ONNX cuando se cambia a modo manual
|
|
1257
|
+
releaseOnnxResources() {
|
|
1258
|
+
console.log('[ONNX] Liberando recursos de modelos ONNX...');
|
|
1259
|
+
try {
|
|
1260
|
+
// Liberar recursos del servicio de detección
|
|
1261
|
+
if (this.detectionService) {
|
|
1262
|
+
this.detectionService.cleanup();
|
|
1263
|
+
console.log('[ONNX] Recursos de ONNX liberados exitosamente');
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
catch (error) {
|
|
1267
|
+
console.error('[ONNX] Error al liberar recursos:', error);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1130
1270
|
completeProcess(skippedBack = false) {
|
|
1131
1271
|
this.stateManager.updateCaptureState({
|
|
1132
1272
|
step: 'completed',
|
|
@@ -1240,6 +1380,13 @@ export class JaakStamps {
|
|
|
1240
1380
|
this.detectionBoxes = [];
|
|
1241
1381
|
this.alignmentStartTime = undefined;
|
|
1242
1382
|
this.hasDocumentDetected = false;
|
|
1383
|
+
// Reset sistema simplificado
|
|
1384
|
+
this.processedFramesCount = 0;
|
|
1385
|
+
this.slowFrameCount = 0;
|
|
1386
|
+
// Reset performance degradation state
|
|
1387
|
+
this.hasAutoSwitchedToManual = false;
|
|
1388
|
+
this.performanceDegradedMode = false;
|
|
1389
|
+
this.showPerformanceMessage = false;
|
|
1243
1390
|
if (this.alignmentTimer) {
|
|
1244
1391
|
clearTimeout(this.alignmentTimer);
|
|
1245
1392
|
this.alignmentTimer = undefined;
|
|
@@ -1602,7 +1749,9 @@ export class JaakStamps {
|
|
|
1602
1749
|
"currentStatus": {},
|
|
1603
1750
|
"performanceData": {},
|
|
1604
1751
|
"backDocumentTimerRemaining": {},
|
|
1605
|
-
"showManualCaptureButton": {}
|
|
1752
|
+
"showManualCaptureButton": {},
|
|
1753
|
+
"performanceDegradedMode": {},
|
|
1754
|
+
"showPerformanceMessage": {}
|
|
1606
1755
|
};
|
|
1607
1756
|
}
|
|
1608
1757
|
static get events() {
|