@jaak.ai/stamps 2.2.0 → 2.3.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.
@@ -729,9 +729,48 @@ class HighPerformanceDeviceStrategy {
729
729
  }
730
730
  }
731
731
 
732
+ /**
733
+ * Strategy for iOS Safari to prevent jetsam memory kills.
734
+ * WebKit 26+ has a known bug with ONNX Runtime JSEP mode that causes memory exhaustion.
735
+ * This strategy forces pure WASM execution without GPU acceleration.
736
+ * See: https://github.com/microsoft/onnxruntime/issues/26827
737
+ */
738
+ class IOSSafariStrategy {
739
+ getDeviceInfo() {
740
+ return {
741
+ estimatedRAM: 3, // Assume low memory for iOS
742
+ isLowMemory: true,
743
+ isSlowConnection: false
744
+ };
745
+ }
746
+ getSessionOptions(_debug) {
747
+ return {
748
+ // Force pure WASM - no WebGL, no WebGPU, no JSEP
749
+ executionProviders: ['wasm'],
750
+ graphOptimizationLevel: 'disabled', // Disable graph optimization to reduce memory
751
+ logSeverityLevel: 4,
752
+ logVerbosityLevel: 0,
753
+ enableCpuMemArena: false, // Don't use CPU memory arena
754
+ enableMemPattern: false, // Don't use memory pattern optimization
755
+ executionMode: 'sequential', // Sequential execution uses less memory
756
+ interOpNumThreads: 1, // Single thread
757
+ intraOpNumThreads: 1, // Single thread
758
+ };
759
+ }
760
+ shouldUseSequentialLoading() {
761
+ return true;
762
+ }
763
+ }
764
+
732
765
  class DeviceStrategyFactory {
733
766
  static createStrategy() {
734
767
  const nav = navigator;
768
+ const ua = navigator.userAgent;
769
+ // iOS Safari requires special handling due to WebKit memory constraints
770
+ const isIOSSafari = /iPad|iPhone|iPod/.test(ua) && /Safari/.test(ua) && !/CriOS|FxiOS|OPiOS|EdgiOS/.test(ua);
771
+ if (isIOSSafari) {
772
+ return new IOSSafariStrategy();
773
+ }
735
774
  const memory = nav.deviceMemory || nav.hardwareConcurrency || 4;
736
775
  const isLowMemory = memory <= 4;
737
776
  if (isLowMemory) {
@@ -18876,10 +18915,25 @@ const JaakStamps = class {
18876
18915
  if (!window.ort) {
18877
18916
  this.updateStatus('Preparando herramientas...', 'Configurando funciones de captura', 'initializing');
18878
18917
  const script = document.createElement('script');
18879
- script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web@1.23.0/dist/ort.min.js';
18918
+ // iOS Safari uses WASM-only build to prevent memory issues (WebKit 26+ bug)
18919
+ const ua = navigator.userAgent;
18920
+ const isIOSSafari = /iPad|iPhone|iPod/.test(ua) && /Safari/.test(ua) && !/CriOS|FxiOS|OPiOS|EdgiOS/.test(ua);
18921
+ if (isIOSSafari) {
18922
+ script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web@1.23.0/dist/ort.wasm.min.js';
18923
+ }
18924
+ else {
18925
+ script.src = 'https://cdn.jsdelivr.net/npm/onnxruntime-web@1.23.0/dist/ort.min.js';
18926
+ }
18880
18927
  document.head.appendChild(script);
18881
18928
  await new Promise((resolve) => {
18882
18929
  script.onload = () => {
18930
+ // Configure ONNX for iOS Safari low memory mode
18931
+ if (isIOSSafari && window.ort?.env) {
18932
+ const ort = window.ort;
18933
+ ort.env.wasm.simd = false;
18934
+ ort.env.wasm.numThreads = 1;
18935
+ ort.env.wasm.proxy = false;
18936
+ }
18883
18937
  setTimeout(async () => {
18884
18938
  await this.finalizeInitialization();
18885
18939
  resolve(undefined);
@@ -19736,7 +19790,7 @@ const JaakStamps = class {
19736
19790
  isCapturing: false
19737
19791
  };
19738
19792
  const cameraInfo = this.cameraInfoWithAutofocus;
19739
- return (index.h("div", { key: 'df70f4fa13b2997a19312125c8b236651cb2b81e', class: "detector-container" }, !this.licenseValid && this.licenseError && (index.h("div", { key: 'c4f7b51515843177bc3063dd7cf9383e3a4c6c73', class: "license-error-container" }, index.h("div", { key: 'a4a7e95a23690f9f59c971dd2af9bd096ae13ef0', class: "license-error-card" }, index.h("svg", { key: '6489a82c60fc9c1a7d89c2b3a537c04c1766cbd4', class: "license-error-icon", width: "64", height: "64", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { key: 'b90b16b0ee155c8baeee321237470de7b6fa1ff5', 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" }), index.h("path", { key: 'c90ec519befb073208dbc5e30e1237dda7f0a18f', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), index.h("circle", { key: 'b926e97a83e19c7ca9b66472fedd53b12d22b7d8', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), index.h("h2", { key: '1f1fce48179331b0150e0c55a6d5efcd0bf95762', class: "license-error-title" }, "Licencia Requerida"), index.h("p", { key: '1f28787cea92c5160664bd8e445fb514ac55eff4', class: "license-error-message" }, this.licenseError), index.h("p", { key: '552aecf92fd34fbdd802fc80cdba46596edb115b', class: "license-error-help" }, "Contacte a soporte: ", index.h("a", { key: '8c44e1e33fbd22a2319acd6c6b27766bec4355f0', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), index.h("div", { key: 'c2e139fdedcb8e8922f37e915caa7ae3a1b09cb9', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (index.h("div", { key: 'c7876bbe35cd28b52433aab6e97de4a0282e25d5', class: "video-container" }, index.h("video", { key: 'a5fa99c086eb3730ceee7750ece0842539defa3d', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), index.h("div", { key: '2c7923dfa706f65cfc3fe71a6ec626cb2ccce7d4', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index$1) => (index.h("div", { key: index$1, class: "detection-box", style: {
19793
+ return (index.h("div", { key: 'dc3aed0b4d2d84039b4a123d4bdfe484ea3320ef', class: "detector-container" }, !this.licenseValid && this.licenseError && (index.h("div", { key: 'a9da275905e2d051252f191be944675781632d10', class: "license-error-container" }, index.h("div", { key: 'a36f7408f0d862edd1183ba813c64d9be91f15c6', class: "license-error-card" }, index.h("svg", { key: 'a8e5f3eefc224e16fb62fc0b6d152c85cee249d1', class: "license-error-icon", width: "64", height: "64", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("path", { key: 'f645fb46a62004309dee1ede871d980c104fedc5', 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" }), index.h("path", { key: 'ee472eb3d17cddf46bef7e96561296ff6fbb1aed', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), index.h("circle", { key: 'c58c787c6c9e307159b3103fdd240e282823aa2f', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), index.h("h2", { key: 'f737ae630fb7661d12a17b7e48cb2c3a1cb6cb4e', class: "license-error-title" }, "Licencia Requerida"), index.h("p", { key: 'fb5cf8d815cddc79f7b5e9ff39f34852a43bc976', class: "license-error-message" }, this.licenseError), index.h("p", { key: 'b47831ee55110b100aa0ea9cbe21d39d2fc19306', class: "license-error-help" }, "Contacte a soporte: ", index.h("a", { key: '52eb8dea1dfdc989b921134f57f1f3f188429061', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), index.h("div", { key: 'fd78565f67049165236694de5ddd415421d0063e', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (index.h("div", { key: '19e5854e1683f57dbde2d857289095db75084496', class: "video-container" }, index.h("video", { key: 'e44fbc4c020317899620e8aa9e7e3c854ca5a2d9', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: { display: captureState.isVideoActive ? 'block' : 'none' } }), index.h("div", { key: '2b3af557f8ccb39fd7dbcef07fa6d41d021fd772', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index$1) => (index.h("div", { key: index$1, class: "detection-box", style: {
19740
19794
  position: 'absolute',
19741
19795
  left: `${box.x}px`,
19742
19796
  top: `${box.y}px`,
@@ -19745,9 +19799,9 @@ const JaakStamps = class {
19745
19799
  border: '2px solid #32406C',
19746
19800
  pointerEvents: 'none',
19747
19801
  boxSizing: 'border-box'
19748
- } })))), this.isMaskReady && (index.h("div", { key: '3e1f77d89a00e4ad1519875cacd5c541c9b16f91', class: "overlay-mask" }, index.h("div", { key: '3c717afa809ef2fa102fdaab3418915602516d39', class: "card-outline" }, index.h("div", { key: 'd3dcd1a85290f3fb2216b1182dce9a4b62cc59c6', class: "side side-top" }), index.h("div", { key: '4280c1e0f0900ec69b905a6226c1afe9a0a993ad', class: "side side-right" }), index.h("div", { key: '9b88c21f5eb28d74872409335cd6ca83a284bd9b', class: "side side-bottom" }), index.h("div", { key: '46b4ef3fca60fcf807da8f574a43cba7f148165b', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '2222975293bebfd04fa2d4ac4878bce48fd35880', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '836fbeadb849cb9df66e03ef0cb791dd0e179df8', class: "back-capture-section" }, index.h("div", { key: 'f0e8119b79f30ffd40ae206783a83869196757ac', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (index.h("button", { key: 'e245e800e2378989bfa011524cca66026ace52d9', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (index.h("span", { key: 'd98a692f9ff883d05e24122b54c4e36f5f96e82f', class: "button-spinner" })), "Capturar Reverso")), index.h("button", { key: 'c32b7784e2bbb89947219f0d458d0a4d62b5352a', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (index.h("span", { key: 'bb935e91f07c4c1052576c52aa2a82a726877217', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
19802
+ } })))), this.isMaskReady && (index.h("div", { key: '2cf20cef5e5dc4d5d3282413dce2af0f75b1babe', class: "overlay-mask" }, index.h("div", { key: '241879ebba739d63a736eca258b735c5c8fdac00', class: "card-outline" }, index.h("div", { key: '30d895b1a438636d9cd9a759b0fc096446e256a1', class: "side side-top" }), index.h("div", { key: 'dcca6a422e4c1c20bfc1bd17d7f45305422386a8', class: "side side-right" }), index.h("div", { key: '2cec938bd863737ae9c0906ed0bce2f16b7461fa', class: "side side-bottom" }), index.h("div", { key: 'c6045def438350be85f4333b9166111a9820c8fd', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '187bb5013fe6e7454bfc498b3f24844bb16881a3', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: 'a8ffba382875432493eb6564e4d8872d5d7e485a', class: "back-capture-section" }, index.h("div", { key: '562c149a1f81b8a73df631c81dc2119c1b9427cd', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (index.h("button", { key: '6dc9a222959df902caec68d72c885fba11e41a79', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (index.h("span", { key: 'dd3ae6cdba5f4e6085d4d31abebda12f1c1367f8', class: "button-spinner" })), "Capturar Reverso")), index.h("button", { key: 'cddd1951d4370da5165bf0fa450e3c176ec6cf61', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (index.h("span", { key: 'da8c1c0af97e164150110cce97d4f4d83e9ffb20', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
19749
19803
  ? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
19750
- : 'Saltar reverso')))), captureState.isVideoActive && (index.h("div", { key: '471a1292e9d093cce0a0d3fa7f96f3665de749fb', class: "camera-controls" }, index.h("button", { key: '406911235a06723310ff577c27e3858912e522c4', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (index.h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (index.h("div", { key: 'b8fd729b78a3c5cb52b7f17d031bb12b894aaf41', class: "camera-selector-dropdown" }, index.h("div", { key: '2b9b451440d6b6be4103419694ff6a53c92e68ad', class: "camera-selector-header" }, index.h("span", { key: '2271f4694aa6c0b32ab23a02a7a8d6d4c1bd4144' }, "Seleccionar C\u00E1mara"), index.h("button", { key: 'ccfc02eb031da17a4907cd835642785bc2ef5e77', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), index.h("div", { key: '073d6e9e09cde8523e926850dfa73704b579c899', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (index.h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, index.h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (index.h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (index.h("span", { class: "selected-indicator" }, "\u2713")))))), index.h("div", { key: '8f914f855727a6ab02a2941fee91283bf3882df2', class: "device-info" }, index.h("small", { key: '295433a43a539034992f04a29355deed12082092' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: 'cc780583a636e7d4910851789710837c9e188d40', class: "manual-capture-section" }, index.h("button", { key: '40c5e212a3a4eab4d2edf44e29e6b4fe0e4c5e37', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (index.h("span", { key: '1245a13523250b5959a1c303ca20662c2d6750c7', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (index.h("div", { key: '10a0a26b346ecf0945688f82292720871f8dc0b7', class: "capture-animation" })), captureState.showFlipAnimation && (index.h("div", { key: '68dc7effe82d2f043d778239e2aecb847d159818', class: "flip-animation" }, index.h("div", { key: '153e0c2229c39c5b9402b9610eaee586d98f84c1', class: "id-card-icon" }), index.h("div", { key: 'b60b249c43ac5f8417c15b8ce46f60d2cb3134d5', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (index.h("div", { key: 'fefa7bf80546a463a54a275e425241545ace5c77', class: "success-animation" }, index.h("div", { key: 'cda9d64b3b30cc636d976c2c644a927a8ebe341e', class: "check-icon" }), index.h("div", { key: 'fd00554df841cdb6e1a167b7e6cc4a6b9b60957a', class: "success-text" }, "\u00A1Proceso completado!"))), index.h("div", { key: 'cd5fa1fbfa5e3a4e362281553dde2c37601b1078', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (index.h("div", { key: 'cb0d76938d8ccab99632920ffc9d73a1fa7dec79', class: "status-spinner" })), index.h("div", { key: 'bcfdc2a24e12dc0bcc19ae0d647be5ce810994d5', class: "status-content" }, index.h("div", { key: 'a4b6dad22b40aed65a9c81e9581e61a9ca064e40', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (index.h("div", { key: '236084444d4d156b672f823349f95b462a8a9bba', class: "status-description" }, this.currentStatus.description)))), this.debug && (index.h("div", { key: '7423d6c8c7e37b7baffc27fc243536e2659475cc', class: "performance-monitor" }, index.h("div", { key: '892736f4be3d1cd563ec919c5a504ca8e0d55db0', class: "performance-expanded" }, index.h("div", { key: 'aa0464f739f838ac4c9e553c79f4c7815f7f65cf', class: "metrics-row" }, index.h("div", { key: '5dca0c5fe0f91ecfaa25c5775c18a99d53eb8f73', class: "metric-compact" }, index.h("span", { key: '8e498b185cdefb97286356b56e45dc7b514f667e', class: "metric-label" }, "FPS"), index.h("span", { key: '3a90611c84b338314ae1503aef6208c67d1282ff', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), index.h("div", { key: '568e492ef7dad971f1613132028999a81f38f457', class: "metric-compact" }, index.h("span", { key: '222fd2b522dd9f7172ad9adb442b10c1ce4c6455', class: "metric-label" }, "MEM"), index.h("span", { key: '8cbe2cf9fd7dd9e22e9a0df6f214165a09e03045', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), index.h("div", { key: 'e5d946afd1cc80a15a52c9ba1cb252e6e146e929', class: "metrics-row" }, index.h("div", { key: '65aaaa92e3ce7b5567560d94f98e16226ecf9fd5', class: "metric-compact" }, index.h("span", { key: '80c6ad0923e729912274a05fffca039e88aa5719', class: "metric-label" }, "INF"), index.h("span", { key: '4a87270ebdad3be718b86d1382b2a54092e53a16', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), index.h("div", { key: '41ddc923cdfab0012a2f5d3e19aee33dad6116fe', class: "metric-compact" }, index.h("span", { key: '84e9f4fb3d5bf60235d71d61dc1d6a8ad429293c', class: "metric-label" }, "FRAME"), index.h("span", { key: '88fd6964307399ac1547c7086f489af90a92a925', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), index.h("div", { key: '22409e8dfb349e66ac54c20c6043b414b7ddba34', class: "metrics-row" }, index.h("div", { key: 'bbe72cb477f4bc313e7978d98c217a4789765df1', class: "metric-compact" }, index.h("span", { key: '56df43d72df8d3549fa42b2bc32fa5491c3cdb41', class: "metric-label" }, "DET"), index.h("span", { key: '7ceedb73086eccaed0e25177d76218e9bae1262d', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), index.h("div", { key: '9407541b4f975b20843c19e7081d1c26bb3f4fd4', class: "metric-compact" }, index.h("span", { key: '511ffc66436ffe2f14300122213de11f50fbbc30', class: "metric-label" }, "RATE"), index.h("span", { key: '6a0c864b46314937043831be7646fbfa3d994c86', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), index.h("div", { key: '72f26e4248c87e428a10bbd7b67bd77a9a32f321', class: "watermark" }, index.h("img", { key: '32e3f23ca1ff81699dd2a4922f8f7d4aeaa3cc2b', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" }))))));
19804
+ : 'Saltar reverso')))), captureState.isVideoActive && (index.h("div", { key: 'd6478c7161d61e1f9f95a9d7bd13cd0cde157061', class: "camera-controls" }, index.h("button", { key: 'dfede9b72f07c88fc5133d3951ddfb6e507b8e8a', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (index.h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (index.h("div", { key: '9218f824cc57b7a8b08f87ed0728c3995fa8b57e', class: "camera-selector-dropdown" }, index.h("div", { key: '48828e7532f49c3e9eece8051585aa803ea3c69e', class: "camera-selector-header" }, index.h("span", { key: '49488cbea9f196788e4110cb9b1f132b8097a771' }, "Seleccionar C\u00E1mara"), index.h("button", { key: '5b762a2da1719c645a490e5234703ba07c50d294', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), index.h("div", { key: '4c13d185e4166dc59621dd8a79a2e7123d810dff', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (index.h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, index.h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (index.h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (index.h("span", { class: "selected-indicator" }, "\u2713")))))), index.h("div", { key: '6860e0fbc0578a74fcd59b3567dd6e4f9a5a4139', class: "device-info" }, index.h("small", { key: '45e6045c7fdc0f4d58bc3c4da059a6b7c2ce09f6' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: '600d4932b6a7ae7529ef9dc8c22bb352e0f3ae5d', class: "manual-capture-section" }, index.h("button", { key: '6ad22fbe065602d9214530c374aed05d728114cc', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (index.h("span", { key: 'd54d5624764ef2774bac1f77551d4c657f4b3e92', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (index.h("div", { key: 'ab8c46dd497c3911e72d685310c4dccd0e5aca57', class: "capture-animation" })), captureState.showFlipAnimation && (index.h("div", { key: '545fc8d38085825921e5d61e9d20960b5767a50a', class: "flip-animation" }, index.h("div", { key: 'fd8540ca1e388070233e366aef791e00c1970de1', class: "id-card-icon" }), index.h("div", { key: 'f952bdf0b5eccffe5d6b36930250e699ebfb8fd8', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (index.h("div", { key: 'cd9b11e3de2f799096b610582b66e044eda64c2e', class: "success-animation" }, index.h("div", { key: '73091c9dae5e6c0f2dbd23bf2e0b760f2495f33b', class: "check-icon" }), index.h("div", { key: 'ad2f9b0b90190b385740bb2fd4ed9454858f13a2', class: "success-text" }, "\u00A1Proceso completado!"))), index.h("div", { key: 'd74d66f12fab510f0aff01f0e233482ed6f63e46', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (index.h("div", { key: '9060ae79961c7b1b473d5148493fda6462e50388', class: "status-spinner" })), index.h("div", { key: 'fd0c61e49a751afd826d30ed9f63b96b58c8e275', class: "status-content" }, index.h("div", { key: 'd0f0e155fba7a09658f7c21beae5f07c26c0701e', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (index.h("div", { key: '0694da4ec0ef14750097e69e8caf1db88cf58ed5', class: "status-description" }, this.currentStatus.description)))), this.debug && (index.h("div", { key: '277369112303b12a3cef89c1b7218fdc6f130723', class: "performance-monitor" }, index.h("div", { key: 'f6456cfd210c0d4b8b02b2b73d2405fa7c12923d', class: "performance-expanded" }, index.h("div", { key: '2cd33cbccf2cf3422f09bd3b914a3bc37b0a1190', class: "metrics-row" }, index.h("div", { key: '7871e7fe4f63249731ff33f87023351d9c5ded77', class: "metric-compact" }, index.h("span", { key: 'b864eb43b44838fd5c67c8e430bfa04553130473', class: "metric-label" }, "FPS"), index.h("span", { key: '7a0e6f4ebcf80b1483102094e0906b2b1a5aa83b', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), index.h("div", { key: 'ef5e590957e12bd6e9371710654278396baa5314', class: "metric-compact" }, index.h("span", { key: '5cc740e4a2a1e07eb53bcb0cc8c5c3df59f27730', class: "metric-label" }, "MEM"), index.h("span", { key: '758018f1731d7f26aa5d84e7563b059f352be361', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), index.h("div", { key: '1bedd37486ae4b8ba547507f2664ea19c67a18c7', class: "metrics-row" }, index.h("div", { key: '4f99be14cda01b199cae93905043a6e03a852d1b', class: "metric-compact" }, index.h("span", { key: 'c29a4a3461633e776cd86168c59c89c6b39af18d', class: "metric-label" }, "INF"), index.h("span", { key: '9401828ffd1d3e41ce473ba3d0aec592a683472f', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), index.h("div", { key: '7d4fdad150bb665640add08464ea361aeaa8ef6b', class: "metric-compact" }, index.h("span", { key: '7c21d775970466b339fdbb392227ec7006b87e31', class: "metric-label" }, "FRAME"), index.h("span", { key: '255d408312a11f350ea75654fc64edf0d4bcfef2', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), index.h("div", { key: '54ab129c3ffda4f1a32a2b0f437a7c38cb480aba', class: "metrics-row" }, index.h("div", { key: 'a246db2ef3a69d0d64827a73dd32968cb1e978e9', class: "metric-compact" }, index.h("span", { key: '8da1c9a5be45bcc23584234cb04f0e75fa3662c6', class: "metric-label" }, "DET"), index.h("span", { key: 'ad05c2b885a6b344391f70ce3acee8b41523743d', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), index.h("div", { key: '7449e8f7cbd15a6b828b90c923212c3578de3d11', class: "metric-compact" }, index.h("span", { key: 'da37f89e9641edfdfd60de7fdbf2f6285a2a4120', class: "metric-label" }, "RATE"), index.h("span", { key: 'de71b2072ce451a304ceb6b158d32b0ecde6d64a', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), index.h("div", { key: '6e2c10e239bca24062cd2972b5e4a3eb0951d0eb', class: "watermark" }, index.h("img", { key: '63fbe0ade07a191ccc9c007fc2813ac8f6e5ab2f', src: "https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png", alt: "Powered by Jaak" }))))));
19751
19805
  }
19752
19806
  // Utility methods
19753
19807
  updateDetectionBoxes(boxes) {