@jaak.ai/stamps 2.1.0-dev.9 → 2.2.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +42 -9
  2. package/dist/cjs/app-globals-V2Kpy_OQ.js +8 -0
  3. package/dist/cjs/app-globals-V2Kpy_OQ.js.map +1 -0
  4. package/dist/cjs/{index-BfhtOB0D.js → index-D6NBn_qu.js} +203 -121
  5. package/dist/cjs/index-D6NBn_qu.js.map +1 -0
  6. package/dist/cjs/jaak-stamps-webcomponent.cjs.js +5 -4
  7. package/dist/cjs/jaak-stamps-webcomponent.cjs.js.map +1 -1
  8. package/dist/cjs/jaak-stamps.cjs.entry.js +20219 -420
  9. package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
  10. package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
  11. package/dist/cjs/loader.cjs.js +4 -3
  12. package/dist/cjs/loader.cjs.js.map +1 -1
  13. package/dist/collection/collection-manifest.json +1 -1
  14. package/dist/collection/components/my-component/my-component.css +83 -3
  15. package/dist/collection/components/my-component/my-component.js +521 -302
  16. package/dist/collection/components/my-component/my-component.js.map +1 -1
  17. package/dist/collection/services/CameraService.js +84 -2
  18. package/dist/collection/services/CameraService.js.map +1 -1
  19. package/dist/collection/services/DetectionService.js +7 -148
  20. package/dist/collection/services/DetectionService.js.map +1 -1
  21. package/dist/collection/services/LicenseValidationService.js +111 -0
  22. package/dist/collection/services/LicenseValidationService.js.map +1 -0
  23. package/dist/collection/services/MetricsService.js +350 -0
  24. package/dist/collection/services/MetricsService.js.map +1 -0
  25. package/dist/collection/services/ServiceContainer.js +66 -1
  26. package/dist/collection/services/ServiceContainer.js.map +1 -1
  27. package/dist/collection/services/TracingService.js +442 -0
  28. package/dist/collection/services/TracingService.js.map +1 -0
  29. package/dist/collection/services/interfaces/IDetectionService.js.map +1 -1
  30. package/dist/collection/services/interfaces/ILicenseValidationService.js +2 -0
  31. package/dist/collection/services/interfaces/ILicenseValidationService.js.map +1 -0
  32. package/dist/collection/services/interfaces/IMetricsService.js +2 -0
  33. package/dist/collection/services/interfaces/IMetricsService.js.map +1 -0
  34. package/dist/collection/services/interfaces/ITracingService.js +2 -0
  35. package/dist/collection/services/interfaces/ITracingService.js.map +1 -0
  36. package/dist/components/index.js +192 -115
  37. package/dist/components/index.js.map +1 -1
  38. package/dist/components/jaak-stamps.js +20235 -423
  39. package/dist/components/jaak-stamps.js.map +1 -1
  40. package/dist/esm/app-globals-DQuL1Twl.js +6 -0
  41. package/dist/esm/app-globals-DQuL1Twl.js.map +1 -0
  42. package/dist/esm/{index-BP1Q4KOg.js → index-BCfAsrzL.js} +204 -121
  43. package/dist/esm/index-BCfAsrzL.js.map +1 -0
  44. package/dist/esm/jaak-stamps-webcomponent.js +5 -4
  45. package/dist/esm/jaak-stamps-webcomponent.js.map +1 -1
  46. package/dist/esm/jaak-stamps.entry.js +20219 -420
  47. package/dist/esm/jaak-stamps.entry.js.map +1 -1
  48. package/dist/esm/loader.js +4 -3
  49. package/dist/esm/loader.js.map +1 -1
  50. package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
  51. package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js.map +1 -1
  52. package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
  53. package/dist/jaak-stamps-webcomponent/loader.esm.js.map +1 -1
  54. package/dist/jaak-stamps-webcomponent/p-8c49893d.entry.js +7 -0
  55. package/dist/jaak-stamps-webcomponent/p-8c49893d.entry.js.map +1 -0
  56. package/dist/jaak-stamps-webcomponent/p-BCfAsrzL.js +3 -0
  57. package/dist/jaak-stamps-webcomponent/p-BCfAsrzL.js.map +1 -0
  58. package/dist/jaak-stamps-webcomponent/p-DQuL1Twl.js +2 -0
  59. package/dist/jaak-stamps-webcomponent/p-DQuL1Twl.js.map +1 -0
  60. package/dist/types/components/my-component/my-component.d.ts +24 -27
  61. package/dist/types/components.d.ts +77 -3
  62. package/dist/types/services/CameraService.d.ts +1 -0
  63. package/dist/types/services/DetectionService.d.ts +1 -9
  64. package/dist/types/services/LicenseValidationService.d.ts +59 -0
  65. package/dist/types/services/MetricsService.d.ts +74 -0
  66. package/dist/types/services/ServiceContainer.d.ts +14 -1
  67. package/dist/types/services/TracingService.d.ts +67 -0
  68. package/dist/types/services/interfaces/IDetectionService.d.ts +0 -6
  69. package/dist/types/services/interfaces/ILicenseValidationService.d.ts +4 -0
  70. package/dist/types/services/interfaces/IMetricsService.d.ts +70 -0
  71. package/dist/types/services/interfaces/ITracingService.d.ts +59 -0
  72. package/dist/types/stencil-public-runtime.d.ts +12 -5
  73. package/package.json +20 -2
  74. package/dist/cjs/index-BfhtOB0D.js.map +0 -1
  75. package/dist/esm/index-BP1Q4KOg.js.map +0 -1
  76. package/dist/jaak-stamps-webcomponent/p-BP1Q4KOg.js +0 -3
  77. package/dist/jaak-stamps-webcomponent/p-BP1Q4KOg.js.map +0 -1
  78. package/dist/jaak-stamps-webcomponent/p-c115e01a.entry.js +0 -2
  79. package/dist/jaak-stamps-webcomponent/p-c115e01a.entry.js.map +0 -1
@@ -1,5 +1,6 @@
1
1
  import { h } from "@stencil/core";
2
2
  import { ServiceContainer } from "../../services/ServiceContainer";
3
+ import { LicenseValidationService } from "../../services/LicenseValidationService";
3
4
  export class JaakStamps {
4
5
  el;
5
6
  debug = false;
@@ -12,8 +13,22 @@ export class JaakStamps {
12
13
  captureDelay = 1500;
13
14
  enableBackDocumentTimer = false;
14
15
  backDocumentTimerDuration = 20;
16
+ telemetryCollectorUrl = 'https://collector.jaak.ai/v1/traces';
17
+ metricsCollectorUrl = 'https://collector.jaak.ai/v1/metrics';
18
+ enableTelemetry = true;
19
+ enableMetrics = true;
20
+ customerId;
21
+ tenantId;
22
+ environment = 'production';
23
+ propagateTraceHeaderCorsUrls; // Comma-separated URLs or regex patterns
24
+ metricsExportIntervalMillis = 60000; // Export metrics every 60 seconds
25
+ license; // License key for validation
26
+ licenseEnvironment = 'prod'; // Environment for license validation
27
+ traceId; // Optional trace ID for tracking
28
+ appId = 'jaak-stamps-web'; // Application ID for license validation
15
29
  captureCompleted;
16
30
  isReady;
31
+ traceIdGenerated;
17
32
  // State derived from services
18
33
  detectionBoxes = [];
19
34
  sideAlignment = {
@@ -53,12 +68,17 @@ export class JaakStamps {
53
68
  showPerformanceMessage = false; // Show performance message temporarily
54
69
  captureStateVersion = 0; // Triggers re-render when StateManager changes
55
70
  processingButton = null; // Track which button is processing
71
+ licenseValid = true; // License validation status
72
+ licenseError = null; // License validation error message
56
73
  // Services
74
+ licenseValidationService = null;
57
75
  serviceContainer;
58
76
  eventBus;
59
77
  stateManager;
60
78
  cameraService;
61
79
  detectionService;
80
+ tracingService;
81
+ metricsService;
62
82
  // UI References
63
83
  videoRef;
64
84
  detectionContainer;
@@ -71,6 +91,7 @@ export class JaakStamps {
71
91
  alignmentStartTime;
72
92
  alignmentTimer;
73
93
  backDocumentTimer;
94
+ orientationTimer;
74
95
  // Performance monitoring
75
96
  performanceMetrics = {
76
97
  fps: 0,
@@ -103,8 +124,23 @@ export class JaakStamps {
103
124
  // Canvas pool for optimized screenshot capture
104
125
  canvasPool = [];
105
126
  MAX_CANVAS_POOL_SIZE = 3;
127
+ async componentWillLoad() {
128
+ // License is required - always validate
129
+ // Wait a bit to ensure props are set from attributes
130
+ await new Promise(resolve => setTimeout(resolve, 50));
131
+ this.updateStatus('Validando licencia...', 'Verificando autorización de uso', 'initializing');
132
+ await this.validateLicense();
133
+ // If license validation failed, stop initialization
134
+ if (!this.licenseValid) {
135
+ return;
136
+ }
137
+ }
106
138
  async componentDidLoad() {
107
139
  try {
140
+ // If license validation failed, stop initialization
141
+ if (!this.licenseValid) {
142
+ return;
143
+ }
108
144
  this.updateStatus('Preparando capturador...', 'Configurando herramientas de captura', 'initializing');
109
145
  await this.initializeServices();
110
146
  this.updateStatus('Preparando funciones...', 'Configurando herramientas de trabajo', 'initializing');
@@ -120,6 +156,10 @@ export class JaakStamps {
120
156
  }
121
157
  }
122
158
  async initializeServices() {
159
+ // Parse propagateTraceHeaderCorsUrls from comma-separated string
160
+ const propagateUrls = this.propagateTraceHeaderCorsUrls
161
+ ? this.propagateTraceHeaderCorsUrls.split(',').map(url => url.trim())
162
+ : [];
123
163
  const config = {
124
164
  debug: this.debug,
125
165
  alignmentTolerance: this.alignmentTolerance,
@@ -128,13 +168,72 @@ export class JaakStamps {
128
168
  useDocumentClassification: this.useDocumentClassification,
129
169
  useDocumentDetector: this.useDocumentDetector,
130
170
  preferredCamera: this.preferredCamera,
131
- captureDelay: this.captureDelay
171
+ captureDelay: this.captureDelay,
172
+ telemetryCollectorUrl: this.telemetryCollectorUrl,
173
+ metricsCollectorUrl: this.metricsCollectorUrl,
174
+ enableTelemetry: this.enableTelemetry,
175
+ enableMetrics: this.enableMetrics,
176
+ customerId: this.customerId,
177
+ tenantId: this.tenantId,
178
+ environment: this.environment,
179
+ propagateTraceHeaderCorsUrls: propagateUrls,
180
+ metricsExportIntervalMillis: this.metricsExportIntervalMillis
132
181
  };
133
182
  this.serviceContainer = new ServiceContainer(config);
134
183
  this.eventBus = this.serviceContainer.getEventBus();
135
184
  this.stateManager = this.serviceContainer.getStateManager();
136
185
  this.cameraService = this.serviceContainer.getCameraService();
137
186
  this.detectionService = this.serviceContainer.getDetectionService();
187
+ this.tracingService = this.serviceContainer.getTracingService();
188
+ this.metricsService = this.serviceContainer.getMetricsService();
189
+ // Record component initialization
190
+ if (this.tracingService) {
191
+ const span = this.tracingService.startSpan('component.initialize', {
192
+ 'component.debug': this.debug,
193
+ 'component.useDocumentDetector': this.useDocumentDetector,
194
+ 'component.useDocumentClassification': this.useDocumentClassification,
195
+ });
196
+ this.tracingService.endSpan(span);
197
+ }
198
+ }
199
+ async validateLicense() {
200
+ if (!this.license) {
201
+ console.error('❌ No license provided for JAAK Stamps component');
202
+ this.licenseError = 'Este componente requiere una licencia válida. Por favor, proporcione una licencia usando el atributo "license".';
203
+ this.licenseValid = false;
204
+ this.updateStatus('Error de licencia', 'Licencia no proporcionada', 'error');
205
+ return;
206
+ }
207
+ try {
208
+ console.log('🔑 Validating license for JAAK Stamps...');
209
+ // Initialize license validation service
210
+ this.licenseValidationService = new LicenseValidationService(this.licenseEnvironment);
211
+ // Validate the license, passing traceId and appId if provided
212
+ const response = await this.licenseValidationService.validateLicense(this.license, this.traceId, this.appId);
213
+ if (response && response.access_token) {
214
+ this.licenseValid = true;
215
+ this.licenseError = null;
216
+ console.log('✅ License validated successfully for JAAK Stamps');
217
+ // Emit the traceId (either provided or generated)
218
+ if (response.traceId) {
219
+ this.traceIdGenerated.emit({ traceId: response.traceId });
220
+ console.log('📋 TraceId:', response.traceId);
221
+ }
222
+ }
223
+ else {
224
+ this.licenseValid = false;
225
+ this.licenseError = 'La licencia proporcionada no es válida. Por favor, verifique su licencia e intente nuevamente.';
226
+ this.updateStatus('Error de licencia', 'Licencia inválida', 'error');
227
+ console.error('❌ Invalid license for JAAK Stamps');
228
+ }
229
+ }
230
+ catch (error) {
231
+ this.licenseValid = false;
232
+ const licenseError = error;
233
+ this.licenseError = licenseError.error_description || 'Error al validar la licencia. Por favor, verifique su conexión e intente nuevamente.';
234
+ this.updateStatus('Error de licencia', 'Fallo en la validación', 'error');
235
+ console.error('❌ License validation failed for JAAK Stamps:', error);
236
+ }
138
237
  }
139
238
  async setupEventListeners() {
140
239
  this.eventBus.on('state-changed', () => {
@@ -174,7 +273,7 @@ export class JaakStamps {
174
273
  if (!window.ort) {
175
274
  this.updateStatus('Preparando herramientas...', 'Configurando funciones de captura', 'initializing');
176
275
  const script = document.createElement('script');
177
- script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js';
276
+ script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web@1.23.0/dist/ort.min.js';
178
277
  document.head.appendChild(script);
179
278
  await new Promise((resolve) => {
180
279
  script.onload = () => {
@@ -255,6 +354,18 @@ export class JaakStamps {
255
354
  });
256
355
  resizeObserver.observe(this.detectionContainer.parentElement);
257
356
  }
357
+ // Handle mobile device orientation changes
358
+ window.addEventListener('orientationchange', () => {
359
+ // Clear any existing orientation timer
360
+ if (this.orientationTimer) {
361
+ clearTimeout(this.orientationTimer);
362
+ }
363
+ // Add delay to ensure video dimensions are updated after rotation
364
+ this.orientationTimer = window.setTimeout(() => {
365
+ this.handleResize();
366
+ this.orientationTimer = undefined;
367
+ }, 300);
368
+ });
258
369
  }
259
370
  handleResize() {
260
371
  if (this.detectionContainer) {
@@ -390,17 +501,31 @@ export class JaakStamps {
390
501
  return this.stateManager.isProcessCompleted();
391
502
  }
392
503
  async startCapture() {
504
+ const span = this.tracingService?.startSpan('capture.start');
393
505
  const readyCheck = this.isComponentReady();
394
506
  if (!readyCheck.ready) {
395
507
  this.updateStatus(readyCheck.message, 'Espere a que termine la inicialización', readyCheck.status);
508
+ if (span) {
509
+ this.tracingService?.setSpanAttribute(span, 'error', true);
510
+ this.tracingService?.setSpanAttribute(span, 'error.message', readyCheck.message);
511
+ this.tracingService?.endSpan(span);
512
+ }
396
513
  return { success: false, error: readyCheck.message };
397
514
  }
398
515
  try {
399
516
  await this.startDetection();
517
+ if (span) {
518
+ this.tracingService?.setSpanAttribute(span, 'success', true);
519
+ this.tracingService?.endSpan(span);
520
+ }
400
521
  return { success: true };
401
522
  }
402
523
  catch (error) {
403
524
  this.updateStatus('Error al iniciar captura', error.message, 'error');
525
+ if (span) {
526
+ this.tracingService?.recordException(span, error);
527
+ this.tracingService?.endSpan(span);
528
+ }
404
529
  return { success: false, error: error.message };
405
530
  }
406
531
  }
@@ -411,13 +536,7 @@ export class JaakStamps {
411
536
  }
412
537
  try {
413
538
  this.exitSession();
414
- // Aggressive cleanup when stopping capture
415
- const cleanupResult = await this.aggressiveResourceCleanup();
416
- return {
417
- success: true,
418
- resourcesFreed: cleanupResult.freed,
419
- cleanupErrors: cleanupResult.errors
420
- };
539
+ return { success: true };
421
540
  }
422
541
  catch (error) {
423
542
  return { success: false, error: error.message };
@@ -504,13 +623,22 @@ export class JaakStamps {
504
623
  }
505
624
  }
506
625
  async preloadModel() {
626
+ const span = this.tracingService?.startSpan('model.preload');
507
627
  const readyCheck = this.isComponentReady();
508
628
  if (!readyCheck.ready) {
509
629
  this.updateStatus(readyCheck.message, 'Espere a que termine la inicialización', readyCheck.status);
630
+ if (span) {
631
+ this.tracingService?.setSpanAttribute(span, 'error', true);
632
+ this.tracingService?.endSpan(span);
633
+ }
510
634
  return { success: false, error: readyCheck.message };
511
635
  }
512
636
  if (this.detectionService.isModelLoaded()) {
513
637
  this.updateStatus('Reconocimiento listo', '', 'ready');
638
+ if (span) {
639
+ this.tracingService?.setSpanAttribute(span, 'cached', true);
640
+ this.tracingService?.endSpan(span);
641
+ }
514
642
  return { success: true, message: 'Model already loaded' };
515
643
  }
516
644
  try {
@@ -520,17 +648,31 @@ export class JaakStamps {
520
648
  this.stateManager.updateCaptureState({ isLoading: true });
521
649
  }
522
650
  try {
651
+ const detectionStartTime = performance.now();
652
+ const modelSpan = this.tracingService?.startSpan('model.detection.load');
523
653
  await this.detectionService.loadModel();
654
+ if (modelSpan)
655
+ this.tracingService?.endSpan(modelSpan);
656
+ const detectionLoadTime = performance.now() - detectionStartTime;
657
+ this.metricsService?.recordModelLoad('detection', detectionLoadTime, false);
524
658
  }
525
659
  catch (modelError) {
660
+ this.metricsService?.recordError('model_load_failed', 'detection');
526
661
  this.switchToManualModeWithError('Error al cargar modelo de detección');
527
662
  throw modelError;
528
663
  }
529
664
  this.updateStatus('Optimizando detección...', 'Configurando reconocimiento de documentos', 'loading');
530
665
  try {
666
+ const classificationStartTime = performance.now();
667
+ const classSpan = this.tracingService?.startSpan('model.classification.load');
531
668
  await this.detectionService.loadClassificationModel();
669
+ if (classSpan)
670
+ this.tracingService?.endSpan(classSpan);
671
+ const classificationLoadTime = performance.now() - classificationStartTime;
672
+ this.metricsService?.recordModelLoad('classification', classificationLoadTime, false);
532
673
  }
533
674
  catch (classificationError) {
675
+ this.metricsService?.recordError('model_load_failed', 'classification');
534
676
  this.switchToManualModeWithError('Error al cargar modelo de clasificación');
535
677
  throw classificationError;
536
678
  }
@@ -540,6 +682,9 @@ export class JaakStamps {
540
682
  if (this.debug) {
541
683
  this.recordOnnxPerformance(loadTime, 0);
542
684
  }
685
+ if (span) {
686
+ this.tracingService?.setSpanAttribute(span, 'loadTime', loadTime);
687
+ }
543
688
  this.updateStatus('Finalizando configuración...', 'Preparando herramientas para captura', 'loading');
544
689
  await new Promise(resolve => setTimeout(resolve, 300));
545
690
  this.updateStatus('Reconocimiento preparado', '', 'ready');
@@ -547,6 +692,10 @@ export class JaakStamps {
547
692
  this.stateManager.updateCaptureState({ isLoading: false });
548
693
  }
549
694
  this.emitReadyEvent();
695
+ if (span) {
696
+ this.tracingService?.setSpanAttribute(span, 'success', true);
697
+ this.tracingService?.endSpan(span);
698
+ }
550
699
  return { success: true, message: 'Models preloaded successfully' };
551
700
  }
552
701
  catch (error) {
@@ -554,6 +703,10 @@ export class JaakStamps {
554
703
  if (this.stateManager) {
555
704
  this.stateManager.updateCaptureState({ isLoading: false });
556
705
  }
706
+ if (span) {
707
+ this.tracingService?.recordException(span, error);
708
+ this.tracingService?.endSpan(span);
709
+ }
557
710
  return { success: false, error: error.message };
558
711
  }
559
712
  }
@@ -642,65 +795,11 @@ export class JaakStamps {
642
795
  // Always allow getting capture delay, even during initialization
643
796
  return this.captureDelay;
644
797
  }
645
- async getResourceReport() {
646
- // Public method to get resource usage report
647
- return this.getResourceReportInternal();
648
- }
649
- async forceResourceCleanup() {
650
- // Public method to force aggressive resource cleanup
651
- const readyCheck = this.isComponentReady();
652
- if (!readyCheck.ready) {
653
- return { success: false, error: readyCheck.message };
654
- }
655
- try {
656
- const cleanupResult = await this.aggressiveResourceCleanup();
657
- return {
658
- success: true,
659
- resourcesFreed: cleanupResult.freed,
660
- errors: cleanupResult.errors,
661
- timestamp: new Date().toISOString()
662
- };
663
- }
664
- catch (error) {
665
- return { success: false, error: error.message };
666
- }
667
- }
668
798
  // Memory and device capability detection
669
799
  checkDeviceCapabilities() {
670
800
  const deviceMemory = navigator.deviceMemory;
671
- const hardwareConcurrency = navigator.hardwareConcurrency || 1;
672
- const isLowEndDevice = hardwareConcurrency <= 2;
673
- const isMobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
674
- const isSafari = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
675
- // Si tenemos info de memoria del dispositivo
676
- if (deviceMemory && deviceMemory < 4) {
677
- return {
678
- canUseML: false,
679
- reason: `Memoria del dispositivo (${deviceMemory}GB) insuficiente para detección automática. Modo manual activado para mejor rendimiento.`,
680
- memoryMB: deviceMemory * 1024
681
- };
682
- }
683
- // Dispositivos móviles de gama baja
684
- if (isMobile && isLowEndDevice) {
685
- return {
686
- canUseML: false,
687
- reason: 'Dispositivo móvil optimizado detectado. Modo manual activado para mejor rendimiento y duración de batería.',
688
- memoryMB: null
689
- };
690
- }
691
- // Safari moderno soporta WASM, solo bloquearlo en versiones muy antiguas
692
- if (isSafari) {
693
- const safariMatch = navigator.userAgent.match(/Version\/(\d+)/);
694
- const safariVersion = safariMatch ? parseInt(safariMatch[1]) : 0;
695
- // Solo bloquear Safari muy antiguo (< version 14)
696
- if (safariVersion > 0 && safariVersion < 14) {
697
- return {
698
- canUseML: false,
699
- reason: 'Safari antiguo detectado. Modo manual activado por compatibilidad.',
700
- memoryMB: null
701
- };
702
- }
703
- }
801
+ // Siempre intentar usar ML, independientemente del dispositivo
802
+ // Las restricciones anteriores no eran confiables
704
803
  return {
705
804
  canUseML: true,
706
805
  reason: 'Dispositivo compatible con detección automática.',
@@ -826,6 +925,12 @@ export class JaakStamps {
826
925
  this.videoRef.onloadedmetadata = async () => {
827
926
  await this.videoRef.play();
828
927
  this.stateManager.updateCaptureState({ isVideoActive: true });
928
+ // Recalculate mask dimensions when new camera stream loads
929
+ if (this.detectionContainer) {
930
+ const container = this.detectionContainer.parentElement;
931
+ const rect = container.getBoundingClientRect();
932
+ this.updateMaskDimensions(rect);
933
+ }
829
934
  resolve();
830
935
  };
831
936
  });
@@ -997,6 +1102,10 @@ export class JaakStamps {
997
1102
  clearTimeout(this.alignmentTimer);
998
1103
  this.alignmentTimer = undefined;
999
1104
  }
1105
+ if (this.orientationTimer) {
1106
+ clearTimeout(this.orientationTimer);
1107
+ this.orientationTimer = undefined;
1108
+ }
1000
1109
  // Liberar recursos de ONNX al limpiar el componente
1001
1110
  this.releaseOnnxResources();
1002
1111
  if (this.performanceUpdateInterval) {
@@ -1005,182 +1114,11 @@ export class JaakStamps {
1005
1114
  }
1006
1115
  // Clear canvas pool
1007
1116
  this.canvasPool = [];
1008
- // Clean DOM references and memory leaks
1009
- this.cleanupDOMReferences();
1010
1117
  this.detectionBoxes = [];
1011
1118
  this.alignmentStartTime = undefined;
1012
1119
  this.hasDocumentDetected = false;
1013
1120
  this.serviceContainer?.cleanup();
1014
1121
  }
1015
- // AGGRESSIVE RESOURCE CLEANUP METHODS
1016
- // Clean DOM references and memory leaks
1017
- cleanupDOMReferences() {
1018
- // Remove event listeners that could maintain references
1019
- if (this.videoRef) {
1020
- // Remove common event listeners (if any were added)
1021
- this.videoRef.srcObject = null;
1022
- this.videoRef = undefined;
1023
- }
1024
- // Clean detection container
1025
- if (this.detectionContainer) {
1026
- this.detectionContainer = undefined;
1027
- }
1028
- // Clean references to images in the DOM and revoke blob URLs
1029
- const images = this.el.shadowRoot?.querySelectorAll('img');
1030
- images?.forEach(img => {
1031
- if (img.src.startsWith('blob:')) {
1032
- URL.revokeObjectURL(img.src);
1033
- }
1034
- img.src = '';
1035
- });
1036
- }
1037
- // Clear browser cache and storage
1038
- async clearBrowserCache() {
1039
- try {
1040
- // 1. Clear Service Worker cache if exists
1041
- if ('serviceWorker' in navigator) {
1042
- const registrations = await navigator.serviceWorker.getRegistrations();
1043
- await Promise.all(registrations.map(registration => registration.unregister()));
1044
- }
1045
- // 2. Clear Cache API specific to the component
1046
- const cacheNames = await caches.keys();
1047
- const componentCaches = cacheNames.filter(name => name.includes('jaak') || name.includes('stamps'));
1048
- await Promise.all(componentCaches.map(cacheName => caches.delete(cacheName)));
1049
- // 3. Force garbage collection if available (only in dev)
1050
- if (this.debug && window.gc) {
1051
- window.gc();
1052
- }
1053
- }
1054
- catch (error) {
1055
- console.warn('Error clearing browser cache:', error);
1056
- }
1057
- }
1058
- // Clear local storage specific to the component
1059
- async clearLocalStorage() {
1060
- try {
1061
- // Clear localStorage specific to the component
1062
- const keysToRemove = [];
1063
- for (let i = 0; i < localStorage.length; i++) {
1064
- const key = localStorage.key(i);
1065
- if (key && (key.includes('jaak') || key.includes('onnx') || key.includes('stamps'))) {
1066
- keysToRemove.push(key);
1067
- }
1068
- }
1069
- keysToRemove.forEach(key => localStorage.removeItem(key));
1070
- // Clear sessionStorage
1071
- const sessionKeysToRemove = [];
1072
- for (let i = 0; i < sessionStorage.length; i++) {
1073
- const key = sessionStorage.key(i);
1074
- if (key && (key.includes('jaak') || key.includes('onnx'))) {
1075
- sessionKeysToRemove.push(key);
1076
- }
1077
- }
1078
- sessionKeysToRemove.forEach(key => sessionStorage.removeItem(key));
1079
- }
1080
- catch (error) {
1081
- console.warn('Error clearing local storage:', error);
1082
- }
1083
- }
1084
- // Aggressive resource cleanup combining all strategies
1085
- async aggressiveResourceCleanup() {
1086
- const freed = [];
1087
- const errors = [];
1088
- try {
1089
- // 1. Release ONNX resources
1090
- this.releaseOnnxResources();
1091
- freed.push('ONNX models');
1092
- // 2. Clear model cache in detection service
1093
- if (this.detectionService) {
1094
- await this.detectionService.clearModelCache();
1095
- freed.push('Model cache');
1096
- }
1097
- // 3. Clear browser cache
1098
- await this.clearBrowserCache();
1099
- freed.push('Browser cache');
1100
- // 4. Clear local storage
1101
- await this.clearLocalStorage();
1102
- freed.push('Local storage');
1103
- // 5. Clean DOM references
1104
- this.cleanupDOMReferences();
1105
- freed.push('DOM references');
1106
- // 6. Optimize canvas pools
1107
- if (this.detectionService) {
1108
- this.detectionService.optimizeCanvasPool(0);
1109
- freed.push('Canvas pools');
1110
- }
1111
- // 7. Clear component canvas pool
1112
- this.canvasPool = [];
1113
- freed.push('Component canvas pool');
1114
- // 8. Force garbage collection (if available)
1115
- if (this.debug && window.gc) {
1116
- window.gc();
1117
- freed.push('Garbage collection');
1118
- }
1119
- }
1120
- catch (error) {
1121
- errors.push(error.message);
1122
- }
1123
- return { freed, errors };
1124
- }
1125
- // Progressive resource release after front capture
1126
- async onFrontCaptureComplete() {
1127
- try {
1128
- // Release classification model if not needed for back
1129
- if (this.detectionService && !this.useDocumentClassification) {
1130
- await this.detectionService.releaseMobileNetResources();
1131
- }
1132
- // Optimize canvas pool to minimum needed for back capture
1133
- if (this.detectionService) {
1134
- this.detectionService.optimizeCanvasPool(1);
1135
- }
1136
- // Reduce component canvas pool
1137
- while (this.canvasPool.length > 1) {
1138
- const canvas = this.canvasPool.pop();
1139
- if (canvas) {
1140
- const ctx = canvas.getContext('2d');
1141
- if (ctx) {
1142
- ctx.clearRect(0, 0, canvas.width, canvas.height);
1143
- }
1144
- }
1145
- }
1146
- if (this.debug) {
1147
- console.log('🧹 Progressive cleanup after front capture completed');
1148
- }
1149
- }
1150
- catch (error) {
1151
- console.warn('Error in progressive cleanup:', error);
1152
- }
1153
- }
1154
- // Resource reporting for debugging
1155
- getResourceReportInternal() {
1156
- const report = {
1157
- timestamp: new Date().toISOString(),
1158
- component: {
1159
- hasVideoStream: !!this.videoStream,
1160
- hasAnimationFrame: !!this.animationId,
1161
- canvasPoolSize: this.canvasPool.length,
1162
- detectionBoxesCount: this.detectionBoxes.length,
1163
- performanceMonitorActive: !!this.performanceUpdateInterval
1164
- }
1165
- };
1166
- // Add detection service stats if available
1167
- if (this.detectionService) {
1168
- report.detectionService = {
1169
- isModelLoaded: this.detectionService.isModelLoaded(),
1170
- canvasPoolStats: this.detectionService.getPoolStats()
1171
- };
1172
- }
1173
- // Add memory info if available
1174
- if ('memory' in performance) {
1175
- const memInfo = performance.memory;
1176
- report.memory = {
1177
- usedJSHeapSize: Math.round(memInfo.usedJSHeapSize / 1048576), // MB
1178
- totalJSHeapSize: Math.round(memInfo.totalJSHeapSize / 1048576), // MB
1179
- jsHeapSizeLimit: Math.round(memInfo.jsHeapSizeLimit / 1048576) // MB
1180
- };
1181
- }
1182
- return report;
1183
- }
1184
1122
  render() {
1185
1123
  const captureState = this.stateManager?.getCaptureState() || {
1186
1124
  isVideoActive: false,
@@ -1191,7 +1129,7 @@ export class JaakStamps {
1191
1129
  isCapturing: false
1192
1130
  };
1193
1131
  const cameraInfo = this.cameraInfoWithAutofocus;
1194
- return (h("div", { key: 'd32941c10b3b7193b2113691dae712a80315b430', class: "detector-container" }, h("div", { key: '7704c993cb9e6e3d29edf6b0adfe341dc1cc8e04', class: "video-container" }, h("video", { key: '2d0d46f1973c86e91f9fe9ede0aa938326c6071f', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), h("div", { key: '9d62ea5221271a18938a9f80535ec7d960745ddb', 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: {
1132
+ return (h("div", { key: '69b36b10f1a790caa352acd5e149fe012ddebd3d', class: "detector-container" }, !this.licenseValid && this.licenseError && (h("div", { key: 'b96d8b52f6bb366b1d6239922a95b100befa5735', class: "license-error-container" }, h("div", { key: '58fb20b1acae97631c35730ed395acf9fa583df2', class: "license-error-card" }, h("svg", { key: 'f2726621e000bad3c62b1106778bb50e32ece973', 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: '18a51f219cdc93f717867f61502c55b35d250532', 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: '0f157178a69c10590dd55f55c2223fdef31c2569', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), h("circle", { key: '0352746bef8e2e5a6be0c3868406005aae574a71', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), h("h2", { key: 'c63de740aa94503f1cf5e1cd1b366b11bc3253b3', class: "license-error-title" }, "Licencia Requerida"), h("p", { key: 'e36cefd08b510fc38f326de557ffc16425a0b324', class: "license-error-message" }, this.licenseError), h("p", { key: 'c77c6545b5186f7fb77a414120d3f6f5ba4a45f0', class: "license-error-help" }, "Contacte a soporte: ", h("a", { key: 'bef70b41a7ec454bed38c4162ce3cafc02c81071', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), h("div", { key: '7fd679252453474021494c8dac3ec44da60b40eb', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (h("div", { key: '369edcb3d7fcaa18059ae89f340f5e65bd0f0785', class: "video-container" }, h("video", { key: '88a67cf2451ebd53cb4fa709d34d11c7fa98cfc9', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), h("div", { key: 'd309664c7a9e64f33dd45e0925f27768483b6795', 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: {
1195
1133
  position: 'absolute',
1196
1134
  left: `${box.x}px`,
1197
1135
  top: `${box.y}px`,
@@ -1200,9 +1138,9 @@ export class JaakStamps {
1200
1138
  border: '2px solid #32406C',
1201
1139
  pointerEvents: 'none',
1202
1140
  boxSizing: 'border-box'
1203
- } })))), this.isMaskReady && (h("div", { key: '38ebb5be5c55a184644411f06fe20221bdbdf693', class: "overlay-mask" }, h("div", { key: '6200c59e7a1212267e7335e1495cf9d9db2bca62', class: "card-outline" }, h("div", { key: 'c5321d2b5c09734cbca69fc8bb7849eef465a0ce', class: "side side-top" }), h("div", { key: 'd73b5afcb6781307460b8827c491673ebbfc40ef', class: "side side-right" }), h("div", { key: '787dfa0792c5a00f8a83feaa423ca22092e0a8bf', class: "side side-bottom" }), h("div", { key: '50736a6b9c7c8847d1dabaa22464e26f284da11e', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'ec8cc90cd589e4f713becb57b6787ce4f57318d4', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'd9d391c02855ac754607cbf77c119153d1f6e56f', class: "back-capture-section" }, h("div", { key: 'a3ebe694f74958b7910fc355a66cbf1394fb5a2a', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode) && (h("button", { key: 'bc6baf4e00199dfdd50bbfbf8abbcede0fb719e9', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: '3a56f9132fce454c792818925c8bed5557e69eed', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: '2fe7e44bc91b73581d6333b7c404ec018a390372', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: 'ebb2d40cbcb646c9bd70ebe278b0643f9335779b', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
1141
+ } })))), this.isMaskReady && (h("div", { key: 'fbfc808e22ec640ddd9e34d52fab476d7a9becc1', class: "overlay-mask" }, h("div", { key: '40846a04d852bbcc2ac6c4a0ca356adae1c67765', class: "card-outline" }, h("div", { key: '452fe1786b67d0f9194e5d03ad2aaee08868a5fd', class: "side side-top" }), h("div", { key: 'a462c388ea55cd022b9616571f0012bd5eb380d4', class: "side side-right" }), h("div", { key: 'bfa2232443e23f2e72f009c62f7a866b9ff1b084', class: "side side-bottom" }), h("div", { key: '581746eca6fde6340d78e8ab48d6e21d17e7dfd3', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '8e57ac550ea3718322ba954682f93239acbabc78', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '81cfab68789796d901afadc895d28f398e8c15cf', class: "back-capture-section" }, h("div", { key: 'd80455bd916c2d7ac47eb0ce3c62b0e5efbe4dff', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (h("button", { key: 'c6d427cb32ecfb1ff40150d39f1d8ad7565f7156', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: 'cb57aec75ff91f2887fa258bd79b8efb98614d13', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: 'c76f356a34fcbc790ebe2d900ed61cc4a6a02e28', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: 'd8fe69623902a5f41587f630552ef28a352733c6', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
1204
1142
  ? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
1205
- : 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '4373e4f9ab73d93ce32ae52fbdc14f7bcb69e68e', class: "camera-controls" }, h("button", { key: '5d2afe5b71b02d379fe2ec82bd57a86f614fbea6', 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: '4fe5e10260a1299a0dc8517646bed8134fe38d9a', class: "camera-selector-dropdown" }, h("div", { key: 'b041acd0b0292864d20ad256301e7be714854424', class: "camera-selector-header" }, h("span", { key: '2769170dc9ce382b420a719cad6f9bb1f5e4420f' }, "Seleccionar C\u00E1mara"), h("button", { key: '0c54f73bb29041ba88e1838c5b1c8a54eafdc67d', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: 'd72ae015c5e89cc3396c14406591308eda4d4c4a', 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: '5933bb5c8345debf2eb78fc2cd3900cb09a29335', class: "device-info" }, h("small", { key: 'a126d886feaede4f9657abee9b45d1eff1910e25' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '62ab98c6afa629583ff13f1792422ef1c5012883', class: "manual-capture-section" }, h("button", { key: '93a42f7b0626a63ab795652eb9eb81657f4fec13', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: '77b5aaf62edab4fe8eb68f37083121d9f8493797', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: '399242238fd4a2a4985af0f30faed504d73a0adc', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '06add02bc244511dc0dc82bf206f41d9ce3cdcd3', class: "flip-animation" }, h("div", { key: 'e3949d8e41bc496bf503d1dcd34df53d2bf876aa', class: "id-card-icon" }), h("div", { key: 'e8ebdd9d29e0b33dcfc506b40e67e0d4af8cb0bb', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: 'f72f6fc4d42c7b10d98c8aff7541596afe131883', class: "success-animation" }, h("div", { key: '8d0d422b37caa97f695f62c0094c52c3c12c7bda', class: "check-icon" }), h("div", { key: 'd9d673dbfd2af4a1b8ca1a775e5b318326d70446', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: 'fdfa1239ddea40bbbabf032542a7160fae3f3c96', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '34bb9d5b83e4383c4f640ccf11189484514e4efd', class: "status-spinner" })), h("div", { key: '131bcd252fc7e1f6eb27332d64fd249b5889aa9d', class: "status-content" }, h("div", { key: '911b7324456e84842fa3c14c9a6fd3ba475804cf', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: 'e938b9294ee3c6125b133bf737caa4a33a016872', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: 'cab385a12f6ccf8579d2d073c1ed987bf815efeb', class: "performance-monitor" }, h("div", { key: '903f8a7005a98c4b99eb7d4c91662911cee8beae', class: "performance-expanded" }, h("div", { key: 'f1ba17573d53442a23212e2c8fdd132bd3ddf4f0', class: "metrics-row" }, h("div", { key: '71357107dcc19749e5af2d5668df535db65cb986', class: "metric-compact" }, h("span", { key: '9ad542fb9445340c669c3d18fc293e2364fc5dcc', class: "metric-label" }, "FPS"), h("span", { key: 'ab0fb401df5dc792c0a641a574851aec48093862', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'a650ab2a1af27829d4a63a264f00907dfba363c6', class: "metric-compact" }, h("span", { key: '56e195b0fd468f2a457a66b2342ed6a80fbef0a0', class: "metric-label" }, "MEM"), h("span", { key: '265445131d4492c6e2f7571d367f52c93e00b711', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '56023a82a1978c7c2f8f08edac729f39efcafa63', class: "metrics-row" }, h("div", { key: '6f1ceb668fc246ec11bfeee3f14c745f21d4986e', class: "metric-compact" }, h("span", { key: '92efba3ee31c5b9a382f1e205584950217482722', class: "metric-label" }, "INF"), h("span", { key: 'fc2baec34fd2f0696a216c487753b94b8bacaf7e', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '683eeb875e96c94cf36c403385c2764239fb5a4d', class: "metric-compact" }, h("span", { key: '33ba3f357868f7feaaeefab35e3ecc35d3b5b726', class: "metric-label" }, "FRAME"), h("span", { key: 'f496be674b0328556d27a9a9b2f24ffa50ff76ea', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: '521f275481d35c2132dbcf138e4bbda84a0b97b2', class: "metrics-row" }, h("div", { key: '17acc0238696816077b80b66aee317ae9ab20e75', class: "metric-compact" }, h("span", { key: 'cac1a4ee661de14739623a1a6f0149ba72fa918c', class: "metric-label" }, "DET"), h("span", { key: '70071c404c5e50001d813f1f3e0d1002776ed887', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: '26a00ad1c95e6c2b8feaafc36103fb7fb869039f', class: "metric-compact" }, h("span", { key: 'a1c7fb80b6795f10111c1ed403de933aadcbe450', class: "metric-label" }, "RATE"), h("span", { key: '49471b7bfa2d6ca6357a39bf611738fd6344764a', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: '3870b7399d2d5068e7f59177225476b00bef7fc7', class: "watermark" }, h("img", { key: '5030e9f14eebd4546207ced129d7d00d85abb189', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" })))));
1143
+ : 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '08f4037c20b4dfed59553a7f29474940f5f3eb49', class: "camera-controls" }, h("button", { key: 'e873835d5d6587b19eb5e61e0073e4992fe115b6', 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: '8fca7e29f868570bb99dd2d09ca7da807656dad0', class: "camera-selector-dropdown" }, h("div", { key: 'abfac31042d3b362c094a297429e0272dabb2511', class: "camera-selector-header" }, h("span", { key: 'ffcd0e3c262aa86c431617568c1070548d88f38a' }, "Seleccionar C\u00E1mara"), h("button", { key: '8351be02ccbfa818cab352a37a29d2cd5bfd53ef', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: 'b42d7a5855ec2f76bc105f7b03369b3d4c950762', 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: 'cf3ca9fe1d626320ad2653a3db44cd86e998bcdf', class: "device-info" }, h("small", { key: '9b908dc6e759f1a5311b068dba10428ebd22cdc3' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '9aa48412eaac0b2adf19f1defb3bc835ab031d9f', class: "manual-capture-section" }, h("button", { key: '1828e293ae4e544b00d0dd17a86401ff0436de37', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: 'bbea1d654f80e537ff6616920fb6a2cb410e55f0', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: '532f72395868ecf58bef350aed4da4e4fc0fa13c', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '555cbc7504660b722f23389899956cf979a27e6c', class: "flip-animation" }, h("div", { key: 'e5de939b02cfb65697c70f265492f1f30f75c771', class: "id-card-icon" }), h("div", { key: '35867c2fbdf463d5b28f0bd3a58313d0d6f15e7b', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: '4a96d077e993012ed333384219ba27d5a68787ea', class: "success-animation" }, h("div", { key: '836809412d0674a0061aadaaa7c712a22f8770da', class: "check-icon" }), h("div", { key: 'd541dbdfa548760b196dd09dc44c3d1a6af8093c', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: '89a9d99fbeedff1bbcf723ba13d551c3290150fe', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: 'f100984baef7602ea40cea9bb74b4c84fd1f6ed9', class: "status-spinner" })), h("div", { key: 'ad4161c71f438174117e306e5084bfdff3d18dce', class: "status-content" }, h("div", { key: '26310245b58f331075dd344a6497e90631d5d78c', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: 'f739148b45f7d43a3015cca3de8efc8b71d3d5e4', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: '0397b96391dff4f0662c913068a62c714df168bf', class: "performance-monitor" }, h("div", { key: 'da3c3638b3c048a425bf691b29755762ad40aa5c', class: "performance-expanded" }, h("div", { key: '467f5e2dc207cfd9fd31cef24d434452b3247c5f', class: "metrics-row" }, h("div", { key: 'e620d9017402317e09ec554bf933a4f5a5d0b0de', class: "metric-compact" }, h("span", { key: '8d21fa081bbf3ec7ad54f553b60b0a64ae41fb01', class: "metric-label" }, "FPS"), h("span", { key: '8e99113c7b93c128d7e390900a63f16c5b9483c0', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: '67927ff90810b0c4d6717d520ad50142d5d6c0dd', class: "metric-compact" }, h("span", { key: '4810964d65c18248f01aff90dca36d732b80a05c', class: "metric-label" }, "MEM"), h("span", { key: 'e82ff493a2bc1d3baf60c1f638154e9208d0991f', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: '6ef07b3f3dc4c3d991f4bbae34e902a9efc1a359', class: "metrics-row" }, h("div", { key: 'b5eed3b30cb99d4d088a05494cda2eff0ba393cc', class: "metric-compact" }, h("span", { key: '52749839a61316b90f424b0920f4c82c6683dd29', class: "metric-label" }, "INF"), h("span", { key: '8509cf19af19b6ac2efc7ab68ac46d9d053c5464', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '34a8540d0840056a525a7afc35ca956943b527af', class: "metric-compact" }, h("span", { key: 'bdc2d8cd180b92ee7b84c8372aba5c2f33289669', class: "metric-label" }, "FRAME"), h("span", { key: '481a0735a5b7258fecdc1bab65a4d4018cc0e7b9', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: '7b5aa0a6fe97970f09db23103f7f0301fd98c4f8', class: "metrics-row" }, h("div", { key: '1c691159409e021176557904a1ceec05abc329e1', class: "metric-compact" }, h("span", { key: '5ab6c25d80548aa4e63c79ecf88d2386393ae707', class: "metric-label" }, "DET"), h("span", { key: '7641532633bc764d4dc209ba7e1827a2f3f59338', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: 'feee52f464eeb965eeadfd944a65e94600591ed5', class: "metric-compact" }, h("span", { key: 'c7962650a7bf1bc86f8c733eb01d5eeb9e08d37e', class: "metric-label" }, "RATE"), h("span", { key: '337529444c8e7bacb47d686d0be33721a066eebe', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: '49717c49e5316bfe10690733c5bf07eb0475a3e2', class: "watermark" }, h("img", { key: 'f86ff4364196627bb3f169e5ee1c14696126cd68', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" }))))));
1206
1144
  }
1207
1145
  // Utility methods
1208
1146
  updateDetectionBoxes(boxes) {
@@ -1319,24 +1257,44 @@ export class JaakStamps {
1319
1257
  }
1320
1258
  async takeManualScreenshot() {
1321
1259
  console.log('🔵 Botón clicked: Capturar (Frente/Reverso)');
1260
+ const captureStartTime = performance.now();
1261
+ const span = this.tracingService?.startSpan('capture.screenshot.manual');
1322
1262
  // Set processing state immediately
1323
1263
  const captureState = this.stateManager?.getCaptureState();
1264
+ const side = captureState?.step === 'front' ? 'front' : 'back';
1324
1265
  if (captureState?.step === 'front') {
1325
1266
  this.processingButton = 'capture-front';
1267
+ if (span)
1268
+ this.tracingService?.setSpanAttribute(span, 'side', 'front');
1326
1269
  }
1327
1270
  else if (captureState?.step === 'back') {
1328
1271
  this.processingButton = 'capture-back';
1272
+ if (span)
1273
+ this.tracingService?.setSpanAttribute(span, 'side', 'back');
1329
1274
  }
1275
+ // Record user interaction
1276
+ this.metricsService?.recordUserInteraction('manual_capture_button');
1330
1277
  console.log('🔵 processingButton set to:', this.processingButton);
1331
1278
  // Add small delay to show spinner
1332
1279
  await new Promise(resolve => setTimeout(resolve, 100));
1333
1280
  if (!this.videoRef) {
1334
1281
  this.processingButton = null;
1282
+ if (span) {
1283
+ this.tracingService?.setSpanAttribute(span, 'error', 'no_video_ref');
1284
+ this.tracingService?.endSpan(span);
1285
+ }
1335
1286
  return;
1336
1287
  }
1337
1288
  // When using manual capture, use mask coordinates for cropping
1338
1289
  // Note: processingButton will be cleared inside takeScreenshotWithMaskCoordinates
1339
1290
  await this.takeScreenshotWithMaskCoordinates();
1291
+ // Record metrics
1292
+ const captureDuration = performance.now() - captureStartTime;
1293
+ this.metricsService?.recordCapture(side, 'manual', captureDuration);
1294
+ if (span) {
1295
+ this.tracingService?.setSpanAttribute(span, 'success', true);
1296
+ this.tracingService?.endSpan(span);
1297
+ }
1340
1298
  }
1341
1299
  async takeScreenshotWithMaskCoordinates() {
1342
1300
  if (!this.videoRef || !this.detectionContainer)
@@ -1399,8 +1357,8 @@ export class JaakStamps {
1399
1357
  if (captureState.step === 'front') {
1400
1358
  this.stateManager.setCapturedImages({
1401
1359
  front: {
1402
- fullFrame: captureCanvas.toDataURL('image/png'),
1403
- cropped: croppedCanvas.toDataURL('image/png')
1360
+ fullFrame: captureCanvas.toDataURL('image/jpeg'),
1361
+ cropped: croppedCanvas.toDataURL('image/jpeg')
1404
1362
  }
1405
1363
  });
1406
1364
  // Check if document classification is enabled (independent of detector)
@@ -1426,8 +1384,6 @@ export class JaakStamps {
1426
1384
  showFlipAnimation: true
1427
1385
  });
1428
1386
  this.triggerRerender();
1429
- // Progressive resource cleanup after front capture
1430
- await this.onFrontCaptureComplete();
1431
1387
  setTimeout(() => {
1432
1388
  this.stateManager.updateCaptureState({
1433
1389
  showFlipAnimation: false,
@@ -1442,8 +1398,8 @@ export class JaakStamps {
1442
1398
  else if (captureState.step === 'back') {
1443
1399
  this.stateManager.setCapturedImages({
1444
1400
  back: {
1445
- fullFrame: captureCanvas.toDataURL('image/png'),
1446
- cropped: croppedCanvas.toDataURL('image/png')
1401
+ fullFrame: captureCanvas.toDataURL('image/jpeg'),
1402
+ cropped: croppedCanvas.toDataURL('image/jpeg')
1447
1403
  }
1448
1404
  });
1449
1405
  this.completeProcess(false);
@@ -1457,6 +1413,8 @@ export class JaakStamps {
1457
1413
  async takeScreenshot() {
1458
1414
  if (!this.videoRef || !this.lastDetectedBox)
1459
1415
  return;
1416
+ const captureStartTime = performance.now();
1417
+ const span = this.tracingService?.startSpan('capture.screenshot.auto');
1460
1418
  this.stateManager.updateCaptureState({ isCapturing: true });
1461
1419
  this.triggerCaptureAnimation();
1462
1420
  // Use pooled canvas for optimization
@@ -1479,17 +1437,30 @@ export class JaakStamps {
1479
1437
  croppedCtx.drawImage(this.videoRef, cropX, cropY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);
1480
1438
  const captureState = this.stateManager.getCaptureState();
1481
1439
  if (captureState.step === 'front') {
1440
+ const frontImageData = captureCanvas.toDataURL('image/jpeg');
1441
+ const croppedImageData = croppedCanvas.toDataURL('image/jpeg');
1482
1442
  this.stateManager.setCapturedImages({
1483
1443
  front: {
1484
- fullFrame: captureCanvas.toDataURL('image/png'),
1485
- cropped: croppedCanvas.toDataURL('image/png')
1444
+ fullFrame: frontImageData,
1445
+ cropped: croppedImageData
1486
1446
  }
1487
1447
  });
1448
+ // Record metrics
1449
+ const captureDuration = performance.now() - captureStartTime;
1450
+ this.metricsService?.recordCapture('front', 'auto', captureDuration);
1451
+ this.metricsService?.recordImageSize('front', frontImageData.length);
1452
+ if (span) {
1453
+ this.tracingService?.setSpanAttribute(span, 'side', 'front');
1454
+ }
1488
1455
  // Check if document classification is enabled
1489
1456
  if (this.useDocumentClassification) {
1490
1457
  try {
1491
1458
  const classification = await this.detectionService.classifyDocument(croppedCanvas);
1492
1459
  if (classification && classification.class === 'passport') {
1460
+ if (span) {
1461
+ this.tracingService?.setSpanAttribute(span, 'document.type', 'passport');
1462
+ this.tracingService?.endSpan(span);
1463
+ }
1493
1464
  this.completeProcess(true);
1494
1465
  return;
1495
1466
  }
@@ -1503,8 +1474,9 @@ export class JaakStamps {
1503
1474
  isDetectionPaused: true,
1504
1475
  showFlipAnimation: true
1505
1476
  });
1506
- // Progressive resource cleanup after front capture
1507
- await this.onFrontCaptureComplete();
1477
+ if (span) {
1478
+ this.tracingService?.endSpan(span);
1479
+ }
1508
1480
  setTimeout(() => {
1509
1481
  this.stateManager.updateCaptureState({
1510
1482
  showFlipAnimation: false,
@@ -1514,12 +1486,22 @@ export class JaakStamps {
1514
1486
  }, 3000);
1515
1487
  }
1516
1488
  else if (captureState.step === 'back') {
1489
+ const backImageData = captureCanvas.toDataURL('image/jpeg');
1490
+ const croppedBackImageData = croppedCanvas.toDataURL('image/jpeg');
1517
1491
  this.stateManager.setCapturedImages({
1518
1492
  back: {
1519
- fullFrame: captureCanvas.toDataURL('image/png'),
1520
- cropped: croppedCanvas.toDataURL('image/png')
1493
+ fullFrame: backImageData,
1494
+ cropped: croppedBackImageData
1521
1495
  }
1522
1496
  });
1497
+ // Record metrics
1498
+ const captureDuration = performance.now() - captureStartTime;
1499
+ this.metricsService?.recordCapture('back', 'auto', captureDuration);
1500
+ this.metricsService?.recordImageSize('back', backImageData.length);
1501
+ if (span) {
1502
+ this.tracingService?.setSpanAttribute(span, 'side', 'back');
1503
+ this.tracingService?.endSpan(span);
1504
+ }
1523
1505
  this.completeProcess(false);
1524
1506
  }
1525
1507
  // Return canvases to pool after use
@@ -1643,10 +1625,13 @@ export class JaakStamps {
1643
1625
  this.useDocumentDetector = false; // Desactivar detector automático
1644
1626
  // Actualizar el estado con mensaje de error
1645
1627
  this.updateStatus('Modo manual activado', errorMessage, 'error');
1646
- // Ocultar mensaje después de 5 segundos
1647
- setTimeout(() => {
1648
- this.updateStatus('Captura manual', 'Use el botón para capturar', 'ready');
1649
- }, 5000);
1628
+ // Continuar con la configuración de cámara para mostrar el video
1629
+ this.continueWithCameraSetup().catch(() => {
1630
+ // Si falla la configuración de cámara, mantener el mensaje de error pero cambiar el estado
1631
+ setTimeout(() => {
1632
+ this.updateStatus('Captura manual', 'Use el botón para capturar', 'ready');
1633
+ }, 5000);
1634
+ });
1650
1635
  }
1651
1636
  stopPerformanceMonitoring() {
1652
1637
  // Nota: No necesitamos limpiar más variables porque ya no se usarán
@@ -1682,16 +1667,6 @@ export class JaakStamps {
1682
1667
  setTimeout(() => {
1683
1668
  this.stateManager.updateCaptureState({ showSuccessAnimation: false });
1684
1669
  }, 3000);
1685
- // Aggressive cleanup after process completion with delay
1686
- setTimeout(async () => {
1687
- const cleanupResult = await this.aggressiveResourceCleanup();
1688
- if (this.debug) {
1689
- console.log('🧹 Post-completion cleanup:', cleanupResult.freed);
1690
- if (cleanupResult.errors.length > 0) {
1691
- console.warn('⚠️ Cleanup errors:', cleanupResult.errors);
1692
- }
1693
- }
1694
- }, 1000); // Wait 1 second after completion
1695
1670
  }
1696
1671
  stopDetection() {
1697
1672
  if (this.animationId) {
@@ -1743,6 +1718,12 @@ export class JaakStamps {
1743
1718
  try {
1744
1719
  // Close the selector immediately when user selects a camera
1745
1720
  this.showCameraSelector = false;
1721
+ // Check if user selected the same camera that's already active
1722
+ const currentCameraId = this.cameraService.getSelectedCameraId();
1723
+ if (currentCameraId === cameraId) {
1724
+ // Same camera selected, just close the selector without switching
1725
+ return;
1726
+ }
1746
1727
  this.isSwitchingCamera = true;
1747
1728
  // Stop current video stream
1748
1729
  if (this.videoStream) {
@@ -2157,6 +2138,261 @@ export class JaakStamps {
2157
2138
  "setter": false,
2158
2139
  "reflect": false,
2159
2140
  "defaultValue": "20"
2141
+ },
2142
+ "telemetryCollectorUrl": {
2143
+ "type": "string",
2144
+ "attribute": "telemetry-collector-url",
2145
+ "mutable": false,
2146
+ "complexType": {
2147
+ "original": "string",
2148
+ "resolved": "string",
2149
+ "references": {}
2150
+ },
2151
+ "required": false,
2152
+ "optional": true,
2153
+ "docs": {
2154
+ "tags": [],
2155
+ "text": ""
2156
+ },
2157
+ "getter": false,
2158
+ "setter": false,
2159
+ "reflect": false,
2160
+ "defaultValue": "'https://collector.jaak.ai/v1/traces'"
2161
+ },
2162
+ "metricsCollectorUrl": {
2163
+ "type": "string",
2164
+ "attribute": "metrics-collector-url",
2165
+ "mutable": false,
2166
+ "complexType": {
2167
+ "original": "string",
2168
+ "resolved": "string",
2169
+ "references": {}
2170
+ },
2171
+ "required": false,
2172
+ "optional": true,
2173
+ "docs": {
2174
+ "tags": [],
2175
+ "text": ""
2176
+ },
2177
+ "getter": false,
2178
+ "setter": false,
2179
+ "reflect": false,
2180
+ "defaultValue": "'https://collector.jaak.ai/v1/metrics'"
2181
+ },
2182
+ "enableTelemetry": {
2183
+ "type": "boolean",
2184
+ "attribute": "enable-telemetry",
2185
+ "mutable": false,
2186
+ "complexType": {
2187
+ "original": "boolean",
2188
+ "resolved": "boolean",
2189
+ "references": {}
2190
+ },
2191
+ "required": false,
2192
+ "optional": false,
2193
+ "docs": {
2194
+ "tags": [],
2195
+ "text": ""
2196
+ },
2197
+ "getter": false,
2198
+ "setter": false,
2199
+ "reflect": false,
2200
+ "defaultValue": "true"
2201
+ },
2202
+ "enableMetrics": {
2203
+ "type": "boolean",
2204
+ "attribute": "enable-metrics",
2205
+ "mutable": false,
2206
+ "complexType": {
2207
+ "original": "boolean",
2208
+ "resolved": "boolean",
2209
+ "references": {}
2210
+ },
2211
+ "required": false,
2212
+ "optional": false,
2213
+ "docs": {
2214
+ "tags": [],
2215
+ "text": ""
2216
+ },
2217
+ "getter": false,
2218
+ "setter": false,
2219
+ "reflect": false,
2220
+ "defaultValue": "true"
2221
+ },
2222
+ "customerId": {
2223
+ "type": "string",
2224
+ "attribute": "customer-id",
2225
+ "mutable": false,
2226
+ "complexType": {
2227
+ "original": "string",
2228
+ "resolved": "string",
2229
+ "references": {}
2230
+ },
2231
+ "required": false,
2232
+ "optional": true,
2233
+ "docs": {
2234
+ "tags": [],
2235
+ "text": ""
2236
+ },
2237
+ "getter": false,
2238
+ "setter": false,
2239
+ "reflect": false
2240
+ },
2241
+ "tenantId": {
2242
+ "type": "string",
2243
+ "attribute": "tenant-id",
2244
+ "mutable": false,
2245
+ "complexType": {
2246
+ "original": "string",
2247
+ "resolved": "string",
2248
+ "references": {}
2249
+ },
2250
+ "required": false,
2251
+ "optional": true,
2252
+ "docs": {
2253
+ "tags": [],
2254
+ "text": ""
2255
+ },
2256
+ "getter": false,
2257
+ "setter": false,
2258
+ "reflect": false
2259
+ },
2260
+ "environment": {
2261
+ "type": "string",
2262
+ "attribute": "environment",
2263
+ "mutable": false,
2264
+ "complexType": {
2265
+ "original": "string",
2266
+ "resolved": "string",
2267
+ "references": {}
2268
+ },
2269
+ "required": false,
2270
+ "optional": true,
2271
+ "docs": {
2272
+ "tags": [],
2273
+ "text": ""
2274
+ },
2275
+ "getter": false,
2276
+ "setter": false,
2277
+ "reflect": false,
2278
+ "defaultValue": "'production'"
2279
+ },
2280
+ "propagateTraceHeaderCorsUrls": {
2281
+ "type": "string",
2282
+ "attribute": "propagate-trace-header-cors-urls",
2283
+ "mutable": false,
2284
+ "complexType": {
2285
+ "original": "string",
2286
+ "resolved": "string",
2287
+ "references": {}
2288
+ },
2289
+ "required": false,
2290
+ "optional": true,
2291
+ "docs": {
2292
+ "tags": [],
2293
+ "text": ""
2294
+ },
2295
+ "getter": false,
2296
+ "setter": false,
2297
+ "reflect": false
2298
+ },
2299
+ "metricsExportIntervalMillis": {
2300
+ "type": "number",
2301
+ "attribute": "metrics-export-interval-millis",
2302
+ "mutable": false,
2303
+ "complexType": {
2304
+ "original": "number",
2305
+ "resolved": "number",
2306
+ "references": {}
2307
+ },
2308
+ "required": false,
2309
+ "optional": true,
2310
+ "docs": {
2311
+ "tags": [],
2312
+ "text": ""
2313
+ },
2314
+ "getter": false,
2315
+ "setter": false,
2316
+ "reflect": false,
2317
+ "defaultValue": "60000"
2318
+ },
2319
+ "license": {
2320
+ "type": "string",
2321
+ "attribute": "license",
2322
+ "mutable": false,
2323
+ "complexType": {
2324
+ "original": "string",
2325
+ "resolved": "string",
2326
+ "references": {}
2327
+ },
2328
+ "required": false,
2329
+ "optional": true,
2330
+ "docs": {
2331
+ "tags": [],
2332
+ "text": ""
2333
+ },
2334
+ "getter": false,
2335
+ "setter": false,
2336
+ "reflect": false
2337
+ },
2338
+ "licenseEnvironment": {
2339
+ "type": "string",
2340
+ "attribute": "license-environment",
2341
+ "mutable": false,
2342
+ "complexType": {
2343
+ "original": "'dev' | 'qa' | 'staging' | 'prod'",
2344
+ "resolved": "\"dev\" | \"prod\" | \"qa\" | \"staging\"",
2345
+ "references": {}
2346
+ },
2347
+ "required": false,
2348
+ "optional": true,
2349
+ "docs": {
2350
+ "tags": [],
2351
+ "text": ""
2352
+ },
2353
+ "getter": false,
2354
+ "setter": false,
2355
+ "reflect": false,
2356
+ "defaultValue": "'prod'"
2357
+ },
2358
+ "traceId": {
2359
+ "type": "string",
2360
+ "attribute": "trace-id",
2361
+ "mutable": false,
2362
+ "complexType": {
2363
+ "original": "string",
2364
+ "resolved": "string",
2365
+ "references": {}
2366
+ },
2367
+ "required": false,
2368
+ "optional": true,
2369
+ "docs": {
2370
+ "tags": [],
2371
+ "text": ""
2372
+ },
2373
+ "getter": false,
2374
+ "setter": false,
2375
+ "reflect": false
2376
+ },
2377
+ "appId": {
2378
+ "type": "string",
2379
+ "attribute": "app-id",
2380
+ "mutable": false,
2381
+ "complexType": {
2382
+ "original": "string",
2383
+ "resolved": "string",
2384
+ "references": {}
2385
+ },
2386
+ "required": false,
2387
+ "optional": true,
2388
+ "docs": {
2389
+ "tags": [],
2390
+ "text": ""
2391
+ },
2392
+ "getter": false,
2393
+ "setter": false,
2394
+ "reflect": false,
2395
+ "defaultValue": "'jaak-stamps-web'"
2160
2396
  }
2161
2397
  };
2162
2398
  }
@@ -2177,7 +2413,9 @@ export class JaakStamps {
2177
2413
  "performanceDegradedMode": {},
2178
2414
  "showPerformanceMessage": {},
2179
2415
  "captureStateVersion": {},
2180
- "processingButton": {}
2416
+ "processingButton": {},
2417
+ "licenseValid": {},
2418
+ "licenseError": {}
2181
2419
  };
2182
2420
  }
2183
2421
  static get events() {
@@ -2211,6 +2449,21 @@ export class JaakStamps {
2211
2449
  "resolved": "boolean",
2212
2450
  "references": {}
2213
2451
  }
2452
+ }, {
2453
+ "method": "traceIdGenerated",
2454
+ "name": "traceIdGenerated",
2455
+ "bubbles": true,
2456
+ "cancelable": true,
2457
+ "composed": true,
2458
+ "docs": {
2459
+ "tags": [],
2460
+ "text": ""
2461
+ },
2462
+ "complexType": {
2463
+ "original": "{traceId: string}",
2464
+ "resolved": "{ traceId: string; }",
2465
+ "references": {}
2466
+ }
2214
2467
  }];
2215
2468
  }
2216
2469
  static get methods() {
@@ -2273,7 +2526,7 @@ export class JaakStamps {
2273
2526
  },
2274
2527
  "stopCapture": {
2275
2528
  "complexType": {
2276
- "signature": "() => Promise<{ success: boolean; resourcesFreed: string[]; cleanupErrors: string[]; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; cleanupErrors?: undefined; }>",
2529
+ "signature": "() => Promise<{ success: boolean; error?: undefined; } | { success: boolean; error: any; }>",
2277
2530
  "parameters": [],
2278
2531
  "references": {
2279
2532
  "Promise": {
@@ -2281,7 +2534,7 @@ export class JaakStamps {
2281
2534
  "id": "global::Promise"
2282
2535
  }
2283
2536
  },
2284
- "return": "Promise<{ success: boolean; resourcesFreed: string[]; cleanupErrors: string[]; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; cleanupErrors?: undefined; }>"
2537
+ "return": "Promise<{ success: boolean; error?: undefined; } | { success: boolean; error: any; }>"
2285
2538
  },
2286
2539
  "docs": {
2287
2540
  "text": "",
@@ -2441,40 +2694,6 @@ export class JaakStamps {
2441
2694
  "text": "",
2442
2695
  "tags": []
2443
2696
  }
2444
- },
2445
- "getResourceReport": {
2446
- "complexType": {
2447
- "signature": "() => Promise<any>",
2448
- "parameters": [],
2449
- "references": {
2450
- "Promise": {
2451
- "location": "global",
2452
- "id": "global::Promise"
2453
- }
2454
- },
2455
- "return": "Promise<any>"
2456
- },
2457
- "docs": {
2458
- "text": "",
2459
- "tags": []
2460
- }
2461
- },
2462
- "forceResourceCleanup": {
2463
- "complexType": {
2464
- "signature": "() => Promise<{ success: boolean; resourcesFreed: string[]; errors: string[]; timestamp: string; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; errors?: undefined; timestamp?: undefined; }>",
2465
- "parameters": [],
2466
- "references": {
2467
- "Promise": {
2468
- "location": "global",
2469
- "id": "global::Promise"
2470
- }
2471
- },
2472
- "return": "Promise<{ success: boolean; resourcesFreed: string[]; errors: string[]; timestamp: string; error?: undefined; } | { success: boolean; error: any; resourcesFreed?: undefined; errors?: undefined; timestamp?: undefined; }>"
2473
- },
2474
- "docs": {
2475
- "text": "",
2476
- "tags": []
2477
- }
2478
2697
  }
2479
2698
  };
2480
2699
  }