@jaak.ai/stamps 2.0.0-dev.26 → 2.0.0-dev.28

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.
@@ -754,4 +754,29 @@ video {
754
754
  100% {
755
755
  transform: rotate(360deg);
756
756
  }
757
+ }
758
+
759
+ /* Status bar always visible */
760
+ .status-bar {
761
+ position: absolute;
762
+ bottom: 10px;
763
+ left: 50%;
764
+ transform: translateX(-50%);
765
+ background: rgba(0, 0, 0, 0.7);
766
+ border-radius: 15px;
767
+ padding: 8px 16px;
768
+ z-index: 40;
769
+ backdrop-filter: blur(5px);
770
+ border: 1px solid rgba(255, 255, 255, 0.1);
771
+ }
772
+
773
+ .status-message {
774
+ font-size: 12px;
775
+ font-weight: 500;
776
+ text-align: center;
777
+ color: #fff;
778
+ white-space: nowrap;
779
+ max-width: 280px;
780
+ overflow: hidden;
781
+ text-overflow: ellipsis;
757
782
  }
@@ -301,8 +301,10 @@ export class JaakStamps {
301
301
  return;
302
302
  }
303
303
  // Show loading state
304
- this.statusMessage = "Cambiando cámara...";
305
- this.statusColor = "#007bff";
304
+ if (this.debug) {
305
+ this.statusMessage = "Cambiando cámara...";
306
+ this.statusColor = "#007bff";
307
+ }
306
308
  // Stop current stream
307
309
  if (this.videoStream) {
308
310
  this.videoStream.getTracks().forEach(track => track.stop());
@@ -329,15 +331,26 @@ export class JaakStamps {
329
331
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
330
332
  try {
331
333
  await this.setupCamera();
334
+ if (this.debug) {
335
+ this.statusMessage = "Cámara configurada correctamente";
336
+ this.statusColor = "#28a745";
337
+ }
332
338
  return; // Success
333
339
  }
334
340
  catch (error) {
335
341
  this.debugLog(`❌ Camera setup attempt ${attempt} failed:`, error);
336
342
  if (attempt === maxRetries) {
337
343
  // Last attempt failed, handle the error
344
+ this.statusMessage = "Error al configurar la cámara";
345
+ this.statusColor = "#ff6b6b";
338
346
  this.handleCameraPermissionError(error);
339
347
  throw error;
340
348
  }
349
+ // Update status for retry attempt
350
+ if (this.debug) {
351
+ this.statusMessage = `Reintentando configuración de cámara... (${attempt}/${maxRetries})`;
352
+ this.statusColor = "#ffb366";
353
+ }
341
354
  // Wait before retrying
342
355
  await new Promise(resolve => setTimeout(resolve, 500 * attempt));
343
356
  }
@@ -361,22 +374,48 @@ export class JaakStamps {
361
374
  await this.switchCamera(nextCamera.deviceId);
362
375
  }
363
376
  async componentDidLoad() {
377
+ if (this.debug) {
378
+ // Show detailed initialization loading state only in debug mode
379
+ this.isLoading = true;
380
+ this.statusMessage = 'Inicializando componente...';
381
+ this.statusColor = '#007bff';
382
+ // Small delay to ensure initialization message is visible
383
+ await new Promise(resolve => setTimeout(resolve, 500));
384
+ }
364
385
  this.validateMaskSize();
365
386
  this.validateCropMargin();
366
387
  this.validatePreferredCamera();
388
+ if (this.debug) {
389
+ // Update status for camera detection
390
+ this.statusMessage = 'Detectando cámaras disponibles...';
391
+ }
367
392
  await this.detectDeviceTypeAndCameras();
368
393
  if (!window.ort) {
394
+ if (this.debug) {
395
+ // Update status for ONNX runtime loading
396
+ this.statusMessage = 'Cargando librerías de IA...';
397
+ }
369
398
  const script = document.createElement('script');
370
399
  script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js';
371
400
  document.head.appendChild(script);
372
401
  // Wait for ONNX runtime to load before emitting ready event
373
402
  script.onload = () => {
374
- this.emitReadyEvent();
403
+ setTimeout(() => {
404
+ this.statusMessage = 'Presione el botón para activar la cámara';
405
+ this.statusColor = '#aaa';
406
+ this.isLoading = false;
407
+ this.emitReadyEvent();
408
+ }, 300);
375
409
  };
376
410
  }
377
411
  else {
378
412
  // ONNX runtime already loaded
379
- this.emitReadyEvent();
413
+ setTimeout(() => {
414
+ this.statusMessage = 'Presione el botón para activar la cámara';
415
+ this.statusColor = '#aaa';
416
+ this.isLoading = false;
417
+ this.emitReadyEvent();
418
+ }, 300);
380
419
  }
381
420
  // Initialize canvas pool for better performance
382
421
  this.initializeCanvasPool();
@@ -540,9 +579,36 @@ export class JaakStamps {
540
579
  this.debugLog('🤖 Preloading detection model:', modelPath);
541
580
  // Configure ONNX Runtime with device-specific optimizations
542
581
  const sessionOptions = this.getSessionOptions();
543
- this.session = await window.ort.InferenceSession.create(modelPath, sessionOptions);
582
+ const deviceInfo = this.getDeviceMemoryInfo();
583
+ try {
584
+ this.session = await window.ort.InferenceSession.create(modelPath, sessionOptions);
585
+ }
586
+ catch (error) {
587
+ if (error.message.includes('failed to allocate a buffer')) {
588
+ this.debugLog('❌ Buffer allocation failed during preload, trying with minimal settings');
589
+ const fallbackOptions = {
590
+ executionProviders: ['wasm'],
591
+ graphOptimizationLevel: 'disabled',
592
+ logSeverityLevel: 4,
593
+ enableCpuMemArena: false,
594
+ enableMemPattern: false,
595
+ executionMode: 'sequential',
596
+ interOpNumThreads: 1,
597
+ intraOpNumThreads: 1,
598
+ };
599
+ this.session = await window.ort.InferenceSession.create(modelPath, fallbackOptions);
600
+ }
601
+ else {
602
+ throw error;
603
+ }
604
+ }
544
605
  // Preload MobileNet model and classes only if classification is enabled
606
+ // For low memory devices, load sequentially to avoid memory pressure
545
607
  if (this.useDocumentClassification) {
608
+ if (deviceInfo.isLowMemory) {
609
+ this.debugLog('🔄 Sequential model loading for low memory device');
610
+ await new Promise(resolve => setTimeout(resolve, 1000));
611
+ }
546
612
  await this.loadMobileNetModel();
547
613
  }
548
614
  this.isModelPreloaded = true;
@@ -607,7 +673,28 @@ export class JaakStamps {
607
673
  this.debugLog('📋 MobileNet classes loaded:', this.mobileNetClassMap);
608
674
  // Load model
609
675
  const sessionOptions = this.getSessionOptions();
610
- this.mobileNetSession = await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, sessionOptions);
676
+ try {
677
+ this.mobileNetSession = await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, sessionOptions);
678
+ }
679
+ catch (error) {
680
+ if (error.message.includes('failed to allocate a buffer')) {
681
+ this.debugLog('❌ MobileNet buffer allocation failed, trying with minimal settings');
682
+ const fallbackOptions = {
683
+ executionProviders: ['wasm'],
684
+ graphOptimizationLevel: 'disabled',
685
+ logSeverityLevel: 4,
686
+ enableCpuMemArena: false,
687
+ enableMemPattern: false,
688
+ executionMode: 'sequential',
689
+ interOpNumThreads: 1,
690
+ intraOpNumThreads: 1,
691
+ };
692
+ this.mobileNetSession = await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH, fallbackOptions);
693
+ }
694
+ else {
695
+ throw error;
696
+ }
697
+ }
611
698
  this.debugLog('✅ MobileNet model loaded successfully');
612
699
  }
613
700
  catch (error) {
@@ -843,15 +930,39 @@ export class JaakStamps {
843
930
  const transposedData = new Float32Array(R.concat(G, B));
844
931
  return new window.ort.Tensor("float32", transposedData, [1, 3, this.INPUT_SIZE, this.INPUT_SIZE]);
845
932
  }
933
+ getDeviceMemoryInfo() {
934
+ const nav = navigator;
935
+ const memory = nav.deviceMemory || nav.hardwareConcurrency || 4;
936
+ const connection = nav.connection || nav.mozConnection || nav.webkitConnection;
937
+ const isSlowConnection = connection && (connection.effectiveType === 'slow-2g' || connection.effectiveType === '2g');
938
+ return {
939
+ estimatedRAM: memory,
940
+ isLowMemory: memory <= 4,
941
+ isSlowConnection: isSlowConnection
942
+ };
943
+ }
846
944
  getSessionOptions() {
945
+ const deviceInfo = this.getDeviceMemoryInfo();
946
+ if (deviceInfo.isLowMemory) {
947
+ return {
948
+ executionProviders: ['wasm'],
949
+ graphOptimizationLevel: 'basic',
950
+ logSeverityLevel: 4,
951
+ logVerbosityLevel: 0,
952
+ enableCpuMemArena: false,
953
+ enableMemPattern: false,
954
+ executionMode: 'sequential',
955
+ interOpNumThreads: 1,
956
+ intraOpNumThreads: 1,
957
+ };
958
+ }
847
959
  return {
848
960
  executionProviders: [
849
- // Try WebGL first for GPU acceleration, fallback to WASM
850
961
  'webgl',
851
962
  'wasm'
852
963
  ],
853
- graphOptimizationLevel: 'all', // Maximum optimization
854
- logSeverityLevel: this.debug ? 2 : 4, // Reduce logging overhead in production
964
+ graphOptimizationLevel: 'all',
965
+ logSeverityLevel: this.debug ? 2 : 4,
855
966
  logVerbosityLevel: 0,
856
967
  enableCpuMemArena: true,
857
968
  enableMemPattern: true,
@@ -865,28 +976,69 @@ export class JaakStamps {
865
976
  // Check if model is already preloaded
866
977
  if (!this.session) {
867
978
  this.isLoading = true;
868
- this.statusMessage = "Cargando modelos...";
869
- this.statusColor = "#007bff";
979
+ if (this.debug) {
980
+ this.statusMessage = "Cargando modelo de detección...";
981
+ this.statusColor = "#007bff";
982
+ }
983
+ else {
984
+ this.statusMessage = "Cargando modelos...";
985
+ this.statusColor = "#007bff";
986
+ }
870
987
  const modelPath = this.MODEL_PATH;
871
988
  this.debugLog('🤖 Loading detection model:', modelPath);
872
989
  const sessionOptions = this.getSessionOptions();
873
- this.session = await window.ort.InferenceSession.create(modelPath, sessionOptions);
990
+ try {
991
+ this.session = await window.ort.InferenceSession.create(modelPath, sessionOptions);
992
+ }
993
+ catch (error) {
994
+ if (error.message.includes('failed to allocate a buffer')) {
995
+ this.debugLog('❌ Buffer allocation failed, trying with minimal settings');
996
+ const fallbackOptions = {
997
+ executionProviders: ['wasm'],
998
+ graphOptimizationLevel: 'disabled',
999
+ logSeverityLevel: 4,
1000
+ enableCpuMemArena: false,
1001
+ enableMemPattern: false,
1002
+ executionMode: 'sequential',
1003
+ interOpNumThreads: 1,
1004
+ intraOpNumThreads: 1,
1005
+ };
1006
+ this.session = await window.ort.InferenceSession.create(modelPath, fallbackOptions);
1007
+ }
1008
+ else {
1009
+ throw error;
1010
+ }
1011
+ }
874
1012
  // Load MobileNet model if classification is enabled and not already loaded
875
1013
  if (this.useDocumentClassification && !this.mobileNetSession) {
1014
+ if (this.debug) {
1015
+ this.statusMessage = "Cargando modelo de clasificación...";
1016
+ }
876
1017
  await this.loadMobileNetModel();
877
1018
  }
878
1019
  this.isModelPreloaded = true;
1020
+ if (this.debug) {
1021
+ this.statusMessage = "Modelos cargados exitosamente";
1022
+ }
879
1023
  this.emitReadyEvent();
880
1024
  }
881
1025
  else {
882
1026
  this.debugLog('🚀 Using preloaded models');
883
- this.statusMessage = "Usando modelos precargados...";
884
- this.statusColor = "#007bff";
1027
+ if (this.debug) {
1028
+ this.statusMessage = "Usando modelos precargados...";
1029
+ this.statusColor = "#007bff";
1030
+ }
1031
+ }
1032
+ if (this.debug) {
1033
+ this.statusMessage = "Configurando cámara...";
885
1034
  }
886
- this.statusMessage = "Configurando cámara...";
887
1035
  await this.setupCamera();
888
1036
  this.startTime = Date.now();
889
1037
  this.isLoading = false;
1038
+ if (this.debug) {
1039
+ this.statusMessage = "Detección activa - Busque su identificación";
1040
+ this.statusColor = "#28a745";
1041
+ }
890
1042
  this.detectFrame();
891
1043
  }
892
1044
  catch (err) {
@@ -1358,8 +1510,14 @@ export class JaakStamps {
1358
1510
  this.videoStream.getTracks().forEach(track => track.stop());
1359
1511
  this.videoStream = undefined;
1360
1512
  this.isVideoActive = false;
1361
- this.statusMessage = "Sesión finalizada.";
1362
- this.statusColor = "#aaa";
1513
+ if (this.debug) {
1514
+ this.statusMessage = "Cámara desactivada - Listo para nueva sesión";
1515
+ this.statusColor = "#6c757d";
1516
+ }
1517
+ else {
1518
+ this.statusMessage = "Presione el botón para activar la cámara";
1519
+ this.statusColor = "#aaa";
1520
+ }
1363
1521
  }
1364
1522
  this.isLoading = false;
1365
1523
  // Limpiar canvas al finalizar sesión
@@ -1370,7 +1528,7 @@ export class JaakStamps {
1370
1528
  this.cleanup();
1371
1529
  }
1372
1530
  render() {
1373
- return (h("div", { key: 'b90673f523dbf112786eb7184f56415055765c0c', class: "detector-container" }, h("div", { key: '925c5c886e9af53b460281244958e722de670a70', class: "video-container" }, h("video", { key: '4a0074e33a81b4694c6c99e3ece256c1ac8fe1d5', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: this.isVideoActive ? 'block' : 'none' } }), h("canvas", { key: 'a7b7f3b35c0535c11f6a4a155502dbe016f590b7', ref: el => this.canvasRef = el, class: this.shouldMirrorVideo ? 'mirror' : '' }), this.isMaskReady && (h("div", { key: '695b6a2f97e29b0b9c5b9d43682a951caff376a1', class: "overlay-mask" }, h("div", { key: '768875c39d5917c6a04306037d03d9e1aed114bd', class: "card-outline" }, h("div", { key: 'a56536deb7b8c99145d1bef6fee84e5801798644', class: "side side-top" }), h("div", { key: 'df413058c7e787f9c8a95a429a4f7186de07f5f6', class: "side side-right" }), h("div", { key: '37e074e3d4c914457f97720f9ab1f1ac2c70c4f1', class: "side side-bottom" }), h("div", { key: '772d3d40925c75ba5d39e2e7dd6405f7cc88d292', class: "side side-left" }), h("div", { key: 'd4e624782b3f4b4b8dbb8286b3acf003e433928c', class: "corner corner-tl" }), h("div", { key: '63f0ccfbbe3c1d413ca6912f36cab4afa6334bb2', class: "corner corner-tr" }), h("div", { key: '20012a50fe3d98ddfa669f5283a871c757522797', class: "corner corner-bl" }), h("div", { key: '9d82646bd08a6ca2b8c5782629fc68fd93cf1287', class: "corner corner-br" }), !this.showFlipAnimation && !this.showSuccessAnimation && (h("div", { key: '79fcbdb52e434a45aa6f2748d6d84500beb2e844', class: "guide-text" }, this.statusMessage))), this.captureStep === 'back' && !this.showFlipAnimation && !this.showSuccessAnimation && (h("button", { key: '16e587d645e2489a3410fe80bfc014738f08f02f', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button" }, "Saltar reverso")), this.isVideoActive && (h("div", { key: 'd46d6881a9e1b63bdd849f5a8c6e96a2caefdefb', class: "camera-controls" }, this.isMultipleCamerasAvailable && (h("button", { key: 'afb4b44d691471f8af6e894e061aecb6c82259da', class: "flip-camera-button", onClick: () => this.flipCamera(), type: "button", title: "Cambiar c\u00E1mara" }, "Girar c\u00E1mara")), h("button", { key: '4e0680c2da9e6cc70b5880e8f5db9830c080acf9', class: "camera-selector-button", onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara" }, "C\u00E1maras"), this.debug && (h("div", { key: 'fc59922452a216273f742d3158559f6b2a1da43e', style: {
1531
+ return (h("div", { key: 'bacf8b2ded1c5015d01dd4240dda6a93fbfb629e', class: "detector-container" }, h("div", { key: '235aefbd8916d6b53ab191c654ed00f303ca73b7', class: "video-container" }, h("video", { key: '9b641c7092c5ecfa601b1f80d6bf8c310539c436', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: this.isVideoActive ? 'block' : 'none' } }), h("canvas", { key: '2c3c384436b7dd91084dbdd27a34ac9192fa3f22', ref: el => this.canvasRef = el, class: this.shouldMirrorVideo ? 'mirror' : '' }), this.isMaskReady && (h("div", { key: '9e2ca398482ebae4da984854483af3159d908d2b', class: "overlay-mask" }, h("div", { key: 'ee14fd65d752351644a281fc4cbd7d8cf8765eec', class: "card-outline" }, h("div", { key: 'c5a924145ac54e7f545b0b6571f1d7d259fc1145', class: "side side-top" }), h("div", { key: 'a88e9ab5f1a4f7041edb44008697b619bf52a85b', class: "side side-right" }), h("div", { key: '08fbf94000951ea31d029469d8158b8bd3349bf8', class: "side side-bottom" }), h("div", { key: '3b9ead8e1d2c0f7fea2878a248241681c07bd0f6', class: "side side-left" }), h("div", { key: 'f96b9a5a0f00f016b11486a63ca984b368d18c8b', class: "corner corner-tl" }), h("div", { key: '30210f2ec60913466665dea50a1e8bc6cba34b41', class: "corner corner-tr" }), h("div", { key: 'cc4644c99957a9ddf68901ddd368037e01c56899', class: "corner corner-bl" }), h("div", { key: '95b08e9b36f880dda1d614f929ceb71259f5ec38', class: "corner corner-br" }), !this.showFlipAnimation && !this.showSuccessAnimation && (h("div", { key: '9bb545a793764b258381b0e3d665472c67d65b5b', class: "guide-text" }, this.statusMessage))), this.captureStep === 'back' && !this.showFlipAnimation && !this.showSuccessAnimation && (h("button", { key: '3b78e394067ea610021fd915215fca30ed0d654b', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button" }, "Saltar reverso")), this.isVideoActive && (h("div", { key: '85fbcf97d151fbf1f37a2f6f90bbd93ef77afdba', class: "camera-controls" }, this.isMultipleCamerasAvailable && (h("button", { key: '56bab78e6ea660e42057b5e6bc322f6990116119', class: "flip-camera-button", onClick: () => this.flipCamera(), type: "button", title: "Cambiar c\u00E1mara" }, "Girar c\u00E1mara")), h("button", { key: 'c149303ed671d326efada743393e52b5a3710710', class: "camera-selector-button", onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara" }, "C\u00E1maras"), this.debug && (h("div", { key: 'ce7c0c1dbc2ba267dbd0181dd7268e2d9f7209c0', style: {
1374
1532
  position: 'absolute',
1375
1533
  top: '50px',
1376
1534
  right: '0',
@@ -1380,10 +1538,10 @@ export class JaakStamps {
1380
1538
  fontSize: '10px',
1381
1539
  borderRadius: '4px',
1382
1540
  whiteSpace: 'nowrap'
1383
- } }, "C\u00E1maras: ", this.availableCameras.length, h("br", { key: '8f112283d1e0518a395dc6d94e1caa46fee0a86b' }), "M\u00FAltiples: ", this.isMultipleCamerasAvailable ? 'Sí' : 'No', h("br", { key: 'aacfd3ee868ee5d0819ce5ef693e3ef384867332' }), "Selector: ", this.showCameraSelector ? 'Visible' : 'Oculto', h("br", { key: '9927df7f56583c7388cee25e13526efc7e032eb1' }), "Video: ", this.isVideoActive ? 'Activo' : 'Inactivo')))), this.showCameraSelector && this.availableCameras.length > 0 && (h("div", { key: 'c2914bf7f3175b8f0ddab977abbdefe3022d7d29', class: "camera-selector-dropdown" }, h("div", { key: '0b5397e77ff33944f3620d78b1ab41275dffd7ac', class: "camera-selector-header" }, h("span", { key: '78f0fb8e34a0cf2d16138522a98cbdb9eefd671f' }, "Seleccionar C\u00E1mara"), h("button", { key: '0d4ea7b191d61d1d9b9c35462ce336148be73fcb', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: 'c16c7a106493ef7633a4cd35b06a4f45327a2e23', class: "camera-list" }, this.availableCameras.map((camera) => (h("button", { key: camera.deviceId, class: `camera-option ${this.selectedCameraId === camera.deviceId ? 'selected' : ''}`, onClick: () => {
1541
+ } }, "C\u00E1maras: ", this.availableCameras.length, h("br", { key: 'd62a6ddde7160f41075b3b1d00340515019a48ca' }), "M\u00FAltiples: ", this.isMultipleCamerasAvailable ? 'Sí' : 'No', h("br", { key: 'fe8c322421809a58f49150ef877ae0502d34d002' }), "Selector: ", this.showCameraSelector ? 'Visible' : 'Oculto', h("br", { key: '084d8c5c6c0193edcaf3bd7d64d0bce8e0bb6964' }), "Video: ", this.isVideoActive ? 'Activo' : 'Inactivo')))), this.showCameraSelector && this.availableCameras.length > 0 && (h("div", { key: '03b1a66188e65f1843c50aec096db840d60bb703', class: "camera-selector-dropdown" }, h("div", { key: 'fe7e08d25dd394d893a7f6269c80a2aaa4732134', class: "camera-selector-header" }, h("span", { key: '1b8f4892c3eef6dac8c682e152abb35e2331496c' }, "Seleccionar C\u00E1mara"), h("button", { key: '396c78a3753c707619e27ef7e5f3a412ba8480c6', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: '6d56d67efe54719f21978cc6cc44cf2f421469bb', class: "camera-list" }, this.availableCameras.map((camera) => (h("button", { key: camera.deviceId, class: `camera-option ${this.selectedCameraId === camera.deviceId ? 'selected' : ''}`, onClick: () => {
1384
1542
  this.switchCamera(camera.deviceId);
1385
1543
  this.toggleCameraSelector();
1386
- }, type: "button" }, h("span", { class: "camera-label" }, camera.label || `Cámara ${this.availableCameras.indexOf(camera) + 1}`), this.selectedCameraId === camera.deviceId && (h("span", { class: "selected-indicator" }, "\u2713")))))), h("div", { key: '11d6f980c3995a8414da5f7e6921f963ca72aed4', class: "device-info" }, h("small", { key: '78f5ff030f9e6e5021234a246599eb459b05d9f7' }, "Dispositivo: ", this.deviceType)))))), this.isCapturing && (h("div", { key: 'ef7d32491d8bdb94b2d6456420c2ddbc80f03d81', class: "capture-animation" })), this.showFlipAnimation && (h("div", { key: 'cfb5868ee75a9d1d1604c52f6fce1241090e4ac2', class: "flip-animation" }, h("div", { key: '1b41035e63f88434aba6699d4e68e06bea2c1529', class: "id-card-icon" }), h("div", { key: '4e83af9d0d39ce37b7448c4a0783b60b42b858e2', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), this.showSuccessAnimation && (h("div", { key: 'c7911e8be74b0fc7d7d18d7dcb52374645ca5f12', class: "success-animation" }, h("div", { key: '18e5ea5cfa3eb35fe3b99c12e6fab8e27e09e85e', class: "check-icon" }), h("div", { key: '490d8fcd6540c3b4fdc95f7fb5e6f6697722c9ac', class: "success-text" }, "\u00A1Proceso completado!"))), this.isLoading && (h("div", { key: 'f7fbfec6be2d8e0dc4e522b85b7d67897575cf0e', class: "loading-overlay" }, h("div", { key: '8282b92f19da6a9c7d22a64a0929b2b4d67c46be', class: "loading-spinner" }), h("div", { key: '7880b689297eb9d80a9b0023ba7933148fd8710a', class: "loading-text" }, this.statusMessage))), h("div", { key: '887c951fb03097171d9bd466fe24e36d11a49954', class: "watermark" }, h("img", { key: '314c9c172a4c6795c825741ea6f02b0e1186e93d', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
1544
+ }, type: "button" }, h("span", { class: "camera-label" }, camera.label || `Cámara ${this.availableCameras.indexOf(camera) + 1}`), this.selectedCameraId === camera.deviceId && (h("span", { class: "selected-indicator" }, "\u2713")))))), h("div", { key: '7f5dda6214695d50c08d2ba4ccec236f3bd158cf', class: "device-info" }, h("small", { key: '50d2768f82b9b7f0a9c1729a5167493f731fb4f6' }, "Dispositivo: ", this.deviceType)))))), this.isCapturing && (h("div", { key: '7ed246b862639b2c6df54dbd32ebb883776bfbd7', class: "capture-animation" })), this.showFlipAnimation && (h("div", { key: 'f2d3a97dfcb9fd757b2f39ec184bce3f5dcb3595', class: "flip-animation" }, h("div", { key: '89a98223c60317d2b9449029ba393c75bec154b3', class: "id-card-icon" }), h("div", { key: '507f6f1b7f38082772bbac2fc28046618161c69b', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), this.showSuccessAnimation && (h("div", { key: '9010d5be6684759b5d99c58ee65b0a7ebe82b9cb', class: "success-animation" }, h("div", { key: '454c39a5c0d457418b8abdc6e63b1c8a249a118f', class: "check-icon" }), h("div", { key: '502e55f1496f7d8cde9178c416bd9db4cf0491eb', class: "success-text" }, "\u00A1Proceso completado!"))), this.isLoading && (h("div", { key: 'e4d6b7c5ebc8da42689150195dd837e77e152ea3', class: "loading-overlay" }, h("div", { key: '7cc39dbbe94e0730c47829291b83717476517f7f', class: "loading-spinner" }), h("div", { key: '4c1afe04fc7a627c9a57c2f7b851ce62f9305676', class: "loading-text" }, this.statusMessage))), this.debug && (h("div", { key: '8745c4603b35003bff859657c86c713b7f58e204', class: "status-bar" }, h("div", { key: 'e098f2402d58d1808052e3d213f851e66db69ee4', class: "status-message", style: { 'color': this.statusColor } }, this.statusMessage))), h("div", { key: 'af4e07b405af5b1786009b0e9ecf72551753de28', class: "watermark" }, h("img", { key: '25f4b80f13528617007aad160c855c4fff0c8af5', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
1387
1545
  }
1388
1546
  static get is() { return "jaak-stamps"; }
1389
1547
  static get encapsulation() { return "shadow"; }