@jaak.ai/stamps 2.0.0-dev.58 → 2.0.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.
- package/dist/cjs/jaak-stamps-webcomponent.cjs.js +1 -1
- package/dist/cjs/jaak-stamps.cjs.entry.js +611 -546
- package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
- package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/my-component/my-component.css +2 -14
- package/dist/collection/components/my-component/my-component.js +237 -346
- package/dist/collection/components/my-component/my-component.js.map +1 -1
- package/dist/collection/services/CameraService.js +344 -156
- package/dist/collection/services/CameraService.js.map +1 -1
- package/dist/collection/services/DetectionService.js +38 -53
- package/dist/collection/services/DetectionService.js.map +1 -1
- package/dist/collection/services/EventBusService.js +1 -1
- package/dist/collection/services/EventBusService.js.map +1 -1
- package/dist/collection/services/LoggerService.js +40 -0
- package/dist/collection/services/LoggerService.js.map +1 -0
- package/dist/collection/services/ServiceContainer.js +12 -2
- package/dist/collection/services/ServiceContainer.js.map +1 -1
- package/dist/collection/services/interfaces/ICameraService.js.map +1 -1
- package/dist/collection/services/interfaces/ILogger.js +2 -0
- package/dist/collection/services/interfaces/ILogger.js.map +1 -0
- package/dist/collection/types/component-types.js.map +1 -1
- package/dist/components/jaak-stamps.js +614 -548
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/jaak-stamps-webcomponent.js +1 -1
- package/dist/esm/jaak-stamps.entry.js +611 -546
- package/dist/esm/jaak-stamps.entry.js.map +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
- package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
- package/dist/jaak-stamps-webcomponent/p-2264b5b4.entry.js +2 -0
- package/dist/jaak-stamps-webcomponent/p-2264b5b4.entry.js.map +1 -0
- package/dist/types/components/my-component/my-component.d.ts +17 -62
- package/dist/types/components.d.ts +8 -6
- package/dist/types/services/CameraService.d.ts +14 -12
- package/dist/types/services/DetectionService.d.ts +3 -9
- package/dist/types/services/LoggerService.d.ts +12 -0
- package/dist/types/services/ServiceContainer.d.ts +2 -0
- package/dist/types/services/interfaces/ICameraService.d.ts +12 -3
- package/dist/types/services/interfaces/ILogger.d.ts +8 -0
- package/dist/types/types/component-types.d.ts +0 -3
- package/package.json +4 -4
- package/dist/jaak-stamps-webcomponent/p-39560f23.entry.js +0 -2
- package/dist/jaak-stamps-webcomponent/p-39560f23.entry.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e,c as t,a as i,h as s}from"./p-BP1Q4KOg.js";class a{debugMode;constructor(e=false){this.debugMode=e}setDebugMode(e){this.debugMode=e}info(...e){if(this.debugMode){console.log(`[JAAK-STAMPS] [INFO] [${(new Date).toLocaleTimeString()}]`,...e)}}warn(...e){if(this.debugMode){console.warn(`[JAAK-STAMPS] [WARN] [${(new Date).toLocaleTimeString()}]`,...e)}}error(...e){if(this.debugMode){console.error(`[JAAK-STAMPS] [ERROR] [${(new Date).toLocaleTimeString()}]`,...e)}}debug(...e){if(this.debugMode){console.debug(`[JAAK-STAMPS] [DEBUG] [${(new Date).toLocaleTimeString()}]`,...e)}}state(e,t){if(this.debugMode){console.log(`[JAAK-STAMPS] [STATE] [${(new Date).toLocaleTimeString()}] ${e}`,t||"")}}performance(e,t){if(this.debugMode){console.log(`[JAAK-STAMPS] [PERF] [${(new Date).toLocaleTimeString()}] ${e}: ${t}ms`)}}}class o{events=new Map;on(e,t){if(!this.events.has(e)){this.events.set(e,[])}this.events.get(e).push(t)}off(e,t){const i=this.events.get(e);if(i){const e=i.indexOf(t);if(e>-1){i.splice(e,1)}}}emit(e,t){const i=this.events.get(e);if(i){i.forEach((i=>{try{i(t)}catch(t){console.error(`Error in event callback for ${e}:`,t)}}))}}once(e,t){const i=s=>{t(s);this.off(e,i)};this.on(e,i)}clear(){this.events.clear()}}class r{eventBus;captureState={step:"front",isCapturing:false,isDetectionPaused:false,isVideoActive:false,isLoading:false,showFlipAnimation:false,showSuccessAnimation:false,bestScore:0,hasScreenshotTaken:false};capturedImages={front:{fullFrame:null,cropped:null},back:{fullFrame:null,cropped:null},metadata:{totalImages:0,processCompleted:false,backCaptureSkipped:false}};constructor(e){this.eventBus=e}getCaptureState(){return{...this.captureState}}updateCaptureState(e){const t={...this.captureState};this.captureState={...this.captureState,...e};this.eventBus.emit("state-changed",{previous:t,current:this.captureState,changes:e})}getCapturedImages(){return JSON.parse(JSON.stringify(this.capturedImages))}setCapturedImages(e){this.capturedImages={...this.capturedImages,...e,metadata:{...this.capturedImages.metadata,...e.metadata}};let t=0;if(this.capturedImages.front.fullFrame&&this.capturedImages.front.cropped){t+=2}if(this.capturedImages.back.fullFrame&&this.capturedImages.back.cropped){t+=2}this.capturedImages.metadata.totalImages=t}reset(){this.captureState={step:"front",isCapturing:false,isDetectionPaused:false,isVideoActive:false,isLoading:false,showFlipAnimation:false,showSuccessAnimation:false,bestScore:0,hasScreenshotTaken:false};this.capturedImages={front:{fullFrame:null,cropped:null},back:{fullFrame:null,cropped:null},metadata:{totalImages:0,processCompleted:false,backCaptureSkipped:false}};this.eventBus.emit("state-changed",{previous:null,current:this.captureState,changes:{reset:true}})}isProcessCompleted(){return this.captureState.step==="completed"}canProceedToBack(){return this.captureState.step==="front"&&this.capturedImages.front.fullFrame!==null&&this.capturedImages.front.cropped!==null}}class n{logger;eventBus;availableCameras=[];selectedCameraId=null;deviceType="desktop";preferredCameraFacing=null;preferredCamera="auto";isManuallySelected=false;constructor(e,t,i="auto"){this.logger=e;this.eventBus=t;this.preferredCamera=i}async detectDeviceType(){const e=navigator.userAgent;const t=/Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(e);const i=/iPad|Android/i.test(e)&&window.innerWidth>=768;if(i){this.deviceType="tablet"}else if(t){this.deviceType="mobile"}else{this.deviceType="desktop"}this.logger.state("DISPOSITIVO_DETECTADO",{deviceType:this.deviceType,userAgent:navigator.userAgent,screenDimensions:{width:window.innerWidth,height:window.innerHeight}});return this.deviceType}async enumerateDevices(){try{const e=await this.checkCameraPermission();if(e==="denied"){this.logger.error("Permiso de cámara denegado por el usuario");return[]}if(e==="prompt"){const e=await navigator.mediaDevices.getUserMedia({video:true});e.getTracks().forEach((e=>e.stop()))}const t=await navigator.mediaDevices.enumerateDevices();this.availableCameras=t.filter((e=>e.kind==="videoinput"));this.logger.state("CAMARAS_DETECTADAS",{count:this.availableCameras.length,cameras:this.availableCameras.map((e=>({id:e.deviceId,label:e.label||"Unknown Camera"})))});this.setInitialCameraPreference();this.logger.state("PREFERENCIA_INICIAL_APLICADA",{selectedCameraId:this.selectedCameraId,preferredCameraFacing:this.preferredCameraFacing,preferredCamera:this.preferredCamera});this.eventBus.emit("camera-changed",this.selectedCameraId);return this.availableCameras}catch(e){this.logger.error("Error al enumerar cámaras disponibles:",e);this.handleCameraPermissionError(e);return[]}}getAvailableCameras(){return[...this.availableCameras]}isMultipleCamerasAvailable(){return this.availableCameras.length>1}getSelectedCameraId(){return this.selectedCameraId}async setSelectedCamera(e){const t=this.availableCameras.find((t=>t.deviceId===e));if(!t){throw new Error(`Camera with ID ${e} not found`)}this.selectedCameraId=e;this.updatePreferredFacing(t);this.isManuallySelected=true;this.savePreference();this.eventBus.emit("camera-changed",e)}getPreferredFacing(){return this.preferredCameraFacing}async setupCamera(e){try{const t=e||await this.getMaxResolution();const i=await navigator.mediaDevices.getUserMedia({video:t,audio:false});return i}catch(e){this.logger.error("Error en setupCamera, intentando con restricciones básicas:",e);const t={width:{ideal:1280},height:{ideal:720}};if(this.deviceType!=="desktop"&&this.preferredCameraFacing){t.facingMode=this.preferredCameraFacing}this.logger.state("USANDO_RESTRICCIONES_BASICAS",{constraints:t});return await navigator.mediaDevices.getUserMedia({video:t,audio:false})}}async switchCamera(e){const t=this.availableCameras.find((t=>t.deviceId===e));if(!t){this.logger.warn("Cámara seleccionada no encontrada, re-enumerando dispositivos...");await this.enumerateDevices();return}await this.setSelectedCamera(e);this.logger.state("CAMARA_CAMBIADA",{label:t.label,deviceId:t.deviceId,isManuallySelected:this.isManuallySelected})}async flipToNextCamera(){if(!this.isMultipleCamerasAvailable())return;const e=this.availableCameras.findIndex((e=>e.deviceId===this.selectedCameraId));const t=(e+1)%this.availableCameras.length;const i=this.availableCameras[t];await this.switchCamera(i.deviceId)}savePreference(){try{const e={cameraId:this.selectedCameraId,facing:this.preferredCameraFacing,timestamp:Date.now()};localStorage.setItem("jaak-stamps-camera-preference",JSON.stringify(e));this.logger.state("PREFERENCIA_CAMARA_GUARDADA",e)}catch(e){this.logger.warn("Error al guardar preferencia de cámara:",e)}}loadPreference(){try{const e=localStorage.getItem("jaak-stamps-camera-preference");if(e){const t=JSON.parse(e);const i=this.availableCameras.some((e=>e.deviceId===t.cameraId));if(i){this.selectedCameraId=t.cameraId;this.preferredCameraFacing=t.facing;this.logger.state("PREFERENCIA_CAMARA_CARGADA",t)}}}catch(e){this.logger.warn("Error al cargar preferencia de cámara:",e)}}isRearCamera(e){const t=e.getVideoTracks()[0];if(!t)return false;const i=t.getSettings();return i.facingMode==="environment"}getCameraInfo(){return{availableCameras:this.availableCameras.map((e=>({id:e.deviceId,label:e.label||"Unknown Camera",selected:e.deviceId===this.selectedCameraId}))),selectedCameraId:this.selectedCameraId,deviceType:this.deviceType,isMultipleCamerasAvailable:this.isMultipleCamerasAvailable(),preferredFacing:this.preferredCameraFacing}}async checkCameraPermission(){try{if(!navigator.permissions){return"prompt"}const e=await navigator.permissions.query({name:"camera"});return e.state}catch(e){this.logger.warn("No se pudo verificar permisos de cámara:",e);return"prompt"}}handleCameraPermissionError(e){this.availableCameras=[];this.eventBus.emit("error",new Error(`Camera permission error: ${e.message}`))}setInitialCameraPreference(){if(this.availableCameras.length===0)return;localStorage.removeItem("jaak-stamps-camera-preference");this.logger.state("APLICANDO_PREFERENCIA_INICIAL",{preferredCamera:this.preferredCamera,availableCamerasCount:this.availableCameras.length});this.isManuallySelected=false;if(this.preferredCamera==="front"){this.selectFrontCamera()}else if(this.preferredCamera==="back"){this.selectBackCamera()}else{this.selectAutoCamera()}}selectFrontCamera(){this.preferredCameraFacing="user";this.logger.state("BUSCANDO_CAMARA_FRONTAL",{availableCameras:this.availableCameras.map((e=>({id:e.deviceId,label:e.label})))});const e=this.availableCameras.find((e=>{const t=e.label.toLowerCase();return t.includes("front")||t.includes("user")||t.includes("selfie")||t.includes("frontal")||!t.includes("back")&&!t.includes("rear")&&!t.includes("environment")}));this.selectedCameraId=e?e.deviceId:this.availableCameras[0].deviceId;this.logger.state("CAMARA_FRONTAL_SELECCIONADA",{found:!!e,label:e?.label||this.availableCameras[0].label,deviceId:this.selectedCameraId})}selectBackCamera(){this.preferredCameraFacing="environment";this.logger.state("BUSCANDO_CAMARA_TRASERA",{availableCameras:this.availableCameras.map((e=>({id:e.deviceId,label:e.label})))});let e=this.availableCameras.find((e=>{const t=e.label.toLowerCase();return t.includes("back")||t.includes("rear")||t.includes("environment")||t.includes("trasera")||t.includes("posterior")}));if(!e&&this.availableCameras.length>1){e=this.availableCameras[this.availableCameras.length-1];this.logger.state("USANDO_ULTIMA_CAMARA_COMO_TRASERA",{label:e.label,deviceId:e.deviceId})}this.selectedCameraId=e?e.deviceId:this.availableCameras[0].deviceId;this.logger.state("CAMARA_TRASERA_SELECCIONADA",{found:!!e,label:e?.label||this.availableCameras[0].label,deviceId:this.selectedCameraId})}selectAutoCamera(){if(this.deviceType==="mobile"||this.deviceType==="tablet"){this.selectBackCamera();this.logger.state("CAMARA_AUTO_SELECCIONADA_MOBILE",{type:"rear"})}else{this.selectFrontCamera();this.logger.state("CAMARA_AUTO_SELECCIONADA_DESKTOP",{type:"front",label:this.availableCameras[0].label,deviceId:this.selectedCameraId})}}updatePreferredFacing(e){const t=e.label.toLowerCase().includes("back")||e.label.toLowerCase().includes("rear")||e.label.toLowerCase().includes("environment");this.preferredCameraFacing=t?"environment":"user"}async getMaxResolution(){try{if(!this.deviceType||this.deviceType==="desktop"){await this.detectDeviceType()}const e={};this.logger.state("CONFIGURANDO_CONSTRAINS_CAMARA",{selectedCameraId:this.selectedCameraId,preferredCameraFacing:this.preferredCameraFacing,preferredCamera:this.preferredCamera,deviceType:this.deviceType,isManuallySelected:this.isManuallySelected});if(this.isManuallySelected&&this.selectedCameraId){e.deviceId={exact:this.selectedCameraId};this.logger.state("USANDO_CAMARA_MANUAL",{deviceId:this.selectedCameraId})}else if(this.preferredCameraFacing){const t=this.deviceType==="desktop"?{ideal:this.preferredCameraFacing}:{exact:this.preferredCameraFacing};e.facingMode=t;this.logger.state("USANDO_FACING_CONSTRAINT",{facingMode:this.preferredCameraFacing,constraintType:this.deviceType==="desktop"?"ideal":"exact"})}else if(this.selectedCameraId){e.deviceId={exact:this.selectedCameraId};this.logger.state("USANDO_CAMARA_SELECCIONADA",{deviceId:this.selectedCameraId})}else{if(this.preferredCamera==="front"){e.facingMode="user"}else if(this.preferredCamera==="back"){e.facingMode="environment"}else{e.facingMode=this.deviceType==="mobile"||this.deviceType==="tablet"?"environment":"user"}this.logger.state("USANDO_PREFERENCIA_CONFIGURADA",{facingMode:e.facingMode,preferredCamera:this.preferredCamera,deviceType:this.deviceType})}const t=await navigator.mediaDevices.getUserMedia({video:e});const i=t.getVideoTracks()[0];const s=i.getCapabilities();t.getTracks().forEach((e=>e.stop()));const a={...e};this.applyAdvancedCameraSettings(a,s);if(s.width&&s.height){const e=Math.min(s.width.max,1920);const t=Math.min(s.height.max,1080);const i=/iPad|Android/i.test(navigator.userAgent)&&window.innerWidth>=768;if(i){a.width={ideal:Math.min(e,1280)};a.height={ideal:Math.min(t,720)}}else{a.width={ideal:e};a.height={ideal:t}}}this.logger.state("CONFIGURACION_CAMARA_OPTIMIZADA",{constraints:a,capabilities:this.getCapabilitiesSummary(s)});return a}catch(e){this.logger.warn("No se pudieron obtener capacidades de cámara, usando configuración de respaldo");if(!this.deviceType||this.deviceType==="desktop"){await this.detectDeviceType()}const t=/iPad|Android/i.test(navigator.userAgent)&&window.innerWidth>=768;const i={width:{ideal:t?1280:1920},height:{ideal:t?720:1080}};this.applyBasicFocusSettings(i);if(this.isManuallySelected&&this.selectedCameraId){i.deviceId={exact:this.selectedCameraId}}else if(this.preferredCameraFacing){const e=this.deviceType==="desktop"?{ideal:this.preferredCameraFacing}:{exact:this.preferredCameraFacing};i.facingMode=e}else if(this.selectedCameraId){i.deviceId={exact:this.selectedCameraId}}else{if(this.preferredCamera==="front"){i.facingMode="user"}else if(this.preferredCamera==="back"){i.facingMode="environment"}else{i.facingMode=this.deviceType==="mobile"||this.deviceType==="tablet"?"environment":"user"}}return i}}applyAdvancedCameraSettings(e,t){if(t.frameRate){e.frameRate={ideal:30,min:15,max:60}}if(t.width&&t.height){e.width={ideal:Math.min(1920,t.width.max||1920),min:640};e.height={ideal:Math.min(1080,t.height.max||1080),min:480}}const i=[];const s={};if(t.focusMode){if(t.focusMode.includes("continuous")){s.focusMode="continuous"}else if(t.focusMode.includes("single-shot")){s.focusMode="single-shot"}}if(t.focusDistance){s.focusDistance={ideal:.4,min:.2,max:1}}if(t.zoom){s.zoom={ideal:1,min:t.zoom.min,max:Math.min(t.zoom.max,3)}}if(Object.keys(s).length>0){i.push(s)}if(i.length>0){e.advanced=i}}applyBasicFocusSettings(e){const t={focusMode:"continuous",exposureMode:"continuous",whiteBalanceMode:"continuous"};if(!e.advanced){e.advanced=[]}e.advanced.push(t);e.frameRate={ideal:30}}getCapabilitiesSummary(e){return{hasAutoFocus:!!e.focusMode,hasFocusDistance:!!e.focusDistance,hasExposureControl:!!e.exposureMode,hasWhiteBalance:!!e.whiteBalanceMode,hasZoom:!!e.zoom,hasTorch:e.torch!==undefined,hasImageControls:!!(e.brightness||e.contrast||e.saturation||e.sharpness),resolutionRange:e.width&&e.height?`${e.width.min}x${e.height.min} - ${e.width.max}x${e.height.max}`:"unknown"}}async setTorchEnabled(e,t){try{if(!t){this.logger.warn("No hay stream disponible para controlar el flash");return false}const i=t.getVideoTracks()[0];if(!i){this.logger.warn("No hay track de video disponible");return false}const s=i.getCapabilities();if(s.torch===undefined){this.logger.warn("El dispositivo no soporta control de flash");return false}await i.applyConstraints({advanced:[{torch:e}]});this.logger.state("FLASH_CONTROLADO",{enabled:e});return true}catch(e){this.logger.error("Error al controlar el flash:",e);return false}}async focusAtPoint(e,t,i){try{if(!i){this.logger.warn("No hay stream disponible para enfocar");return false}const s=i.getVideoTracks()[0];if(!s){this.logger.warn("No hay track de video disponible");return false}const a=s.getCapabilities();if(!a.focusMode||!a.focusMode.includes("single-shot")){this.logger.warn("El dispositivo no soporta enfoque manual");return false}await s.applyConstraints({advanced:[{focusMode:"single-shot"}]});setTimeout((async()=>{try{await s.applyConstraints({advanced:[{focusMode:"continuous"}]})}catch(e){this.logger.warn("Error al volver a enfoque continuo:",e)}}),1e3);this.logger.state("ENFOQUE_MANUAL_ACTIVADO",{x:e,y:t});return true}catch(e){this.logger.error("Error al enfocar manualmente:",e);return false}}}class c{getDeviceInfo(){const e=navigator;const t=e.deviceMemory||e.hardwareConcurrency||4;const i=e.connection||e.mozConnection||e.webkitConnection;const s=i&&(i.effectiveType==="slow-2g"||i.effectiveType==="2g");return{estimatedRAM:t,isLowMemory:true,isSlowConnection:s}}getSessionOptions(e){return{executionProviders:["wasm"],graphOptimizationLevel:"basic",logSeverityLevel:4,logVerbosityLevel:0,enableCpuMemArena:false,enableMemPattern:false,executionMode:"sequential",interOpNumThreads:1,intraOpNumThreads:1}}shouldUseSequentialLoading(){return true}}class d{getDeviceInfo(){const e=navigator;const t=e.deviceMemory||e.hardwareConcurrency||4;const i=e.connection||e.mozConnection||e.webkitConnection;const s=i&&(i.effectiveType==="slow-2g"||i.effectiveType==="2g");return{estimatedRAM:t,isLowMemory:false,isSlowConnection:s}}getSessionOptions(e){return{executionProviders:["webgl","wasm"],graphOptimizationLevel:"all",logSeverityLevel:e?2:4,logVerbosityLevel:0,enableCpuMemArena:true,enableMemPattern:true,executionMode:"parallel",interOpNumThreads:2,intraOpNumThreads:2}}shouldUseSequentialLoading(){return false}}class l{static createStrategy(){const e=navigator;const t=e.deviceMemory||e.hardwareConcurrency||4;const i=t<=4;if(i){return new c}else{return new d}}}class h{logger;debug;useDocumentClassification;session;mobileNetSession;mobileNetClassMap;modelLoaded=false;deviceStrategy;MODEL_PATH="https://storage.googleapis.com/jaak-static/web/component/stamps/ddmyp-v2.onnx";MOBILENET_MODEL_PATH="https://storage.googleapis.com/jaak-static/web/component/stamps/squeezenet_new_fp32.onnx";MOBILENET_CLASSES_PATH="https://storage.googleapis.com/jaak-static/web/component/stamps/cdmmp-v1.json";INPUT_SIZE=320;CONFIDENCE_THRESHOLD=.6;preprocessCanvas;preprocessCtx;captureCanvas;constructor(e,t=false,i=false){this.logger=e;this.debug=t;this.useDocumentClassification=i;this.deviceStrategy=l.createStrategy();this.initializeCanvasPool()}async loadModel(){if(this.modelLoaded||this.session){this.logger.state("MODELO_YA_PRECARGADO",{sessionExists:!!this.session,modelPreloaded:this.modelLoaded});return}try{this.logger.state("PRECARGANDO_MODELO_DETECCION",{modelPath:this.MODEL_PATH});const e=this.deviceStrategy.getSessionOptions(this.debug);try{this.session=await window.ort.InferenceSession.create(this.MODEL_PATH,e)}catch(e){if(e.message.includes("failed to allocate a buffer")){this.logger.warn("Fallo en asignación de buffer durante precarga, intentando con configuración mínima");const e={executionProviders:["wasm"],graphOptimizationLevel:"disabled",logSeverityLevel:4,enableCpuMemArena:false,enableMemPattern:false,executionMode:"sequential",interOpNumThreads:1,intraOpNumThreads:1};this.session=await window.ort.InferenceSession.create(this.MODEL_PATH,e)}else{throw e}}this.modelLoaded=true;this.logger.state("MODELO_DETECCION_CARGADO_EXITOSAMENTE",{sessionCreated:!!this.session})}catch(e){this.logger.error("Error al precargar modelo de detección:",e);throw e}}async loadClassificationModel(){if(!this.useDocumentClassification){return}try{this.logger.state("CARGANDO_MODELO_MOBILENET",{path:this.MOBILENET_MODEL_PATH});try{const e=await fetch(this.MOBILENET_CLASSES_PATH);if(e.ok){this.mobileNetClassMap=await e.json();this.logger.state("CLASES_MOBILENET_CARGADAS",{classCount:Object.keys(this.mobileNetClassMap).length})}}catch(e){this.logger.warn("No se pudo cargar el mapa de clases de MobileNet, usando clasificación básica");this.mobileNetClassMap={0:"document",1:"id_card",2:"passport",3:"license",4:"other"}}const e=this.deviceStrategy.getSessionOptions(this.debug);try{this.mobileNetSession=await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH,e)}catch(e){if(e.message.includes("failed to allocate a buffer")){this.logger.warn("Fallo en asignación de buffer de MobileNet, intentando con configuración mínima");const e={executionProviders:["wasm"],graphOptimizationLevel:"disabled",logSeverityLevel:4,enableCpuMemArena:false,enableMemPattern:false,executionMode:"sequential",interOpNumThreads:1,intraOpNumThreads:1};this.mobileNetSession=await window.ort.InferenceSession.create(this.MOBILENET_MODEL_PATH,e)}else{throw e}}this.logger.state("MODELO_MOBILENET_CARGADO_EXITOSAMENTE",{sessionCreated:!!this.mobileNetSession})}catch(e){this.logger.error("Error al cargar modelo MobileNet:",e);throw e}}isModelLoaded(){return this.modelLoaded&&!!this.session}preprocess(e){if(!this.preprocessCanvas||!this.preprocessCtx){this.initializeCanvasPool()}this.preprocessCtx.clearRect(0,0,this.INPUT_SIZE,this.INPUT_SIZE);this.preprocessCtx.drawImage(e,0,0,this.INPUT_SIZE,this.INPUT_SIZE);const t=this.preprocessCtx.getImageData(0,0,this.INPUT_SIZE,this.INPUT_SIZE);const[i,s,a]=[[],[],[]];const{data:o}=t;for(let e=0;e<o.length;e+=4){i.push(o[e]/255);s.push(o[e+1]/255);a.push(o[e+2]/255)}const r=new Float32Array(i.concat(s,a));const n=new Uint16Array(r.length);for(let e=0;e<r.length;e++){n[e]=this.float32ToFloat16(r[e])}return new window.ort.Tensor("float16",n,[1,3,this.INPUT_SIZE,this.INPUT_SIZE])}async runInference(e){if(!this.session){throw new Error("Detection model not loaded")}const t={[this.session.inputNames[0]]:e};const i=await this.session.run(t);const s=i[this.session.outputNames[0]].data;const a=[];for(let e=0;e<s.length;e+=6){const[t,i,o,r,n,c]=s.slice(e,e+6);if(n>this.CONFIDENCE_THRESHOLD){a.push({x:t,y:i,w:o-t,h:r-i,score:n,classId:c})}}return a}async classifyDocument(e){if(!this.mobileNetSession||!this.mobileNetClassMap){this.logger.warn("Modelo MobileNet no está cargado, saltando clasificación");return null}try{this.logger.state("CLASIFICANDO_DOCUMENTO",{timestamp:Date.now()});const t=this.preprocessMobileNet(e);const i={[this.mobileNetSession.inputNames[0]]:t};const s=await this.mobileNetSession.run(i);const a=s[Object.keys(s)[0]].data;const o=a.reduce(((e,t,i,s)=>t>s[e]?i:e),0);const r=a[o];const n=this.mobileNetClassMap[o.toString()]||"unknown";this.logger.state("DOCUMENTO_CLASIFICADO",{class:n,confidence:r.toFixed(3),classIndex:o,timestamp:Date.now(),results:s});return{class:n,confidence:r,classIndex:o}}catch(e){this.logger.error("Error al clasificar documento:",e);return null}}checkSideAlignment(e,t){const{INPUT_SIZE:i,ID1_ASPECT_RATIO:s,shouldMirrorVideo:a,alignmentTolerance:o,maskSize:r,videoRef:n}=t;if(!n){return{top:false,right:false,bottom:false,left:false}}const c=n.videoWidth;const d=n.videoHeight;if(c===0||d===0){return{top:false,right:false,bottom:false,left:false}}const l=c/d;const h=1;let f,p;if(l>h){f=i;p=i/l}else{p=i;f=i*l}const m=p*s;let u,b;const g=r/100;if(m<=f){b=p*g;u=b*s}else{u=f*g;b=u/s}const x=u*(i/f);const y=b*(i/p);const w=i/2;const A=i/2;const v=w-x/2;const C=w+x/2;const k=A-y/2;const E=A+y/2;let I=e.x;let S=e.x+e.w;const M=e.y;const D=e.y+e.h;if(a){const e=I;const t=S;I=i-t;S=i-e}const T=o;const O=Math.abs(M-k)<=T;const N=Math.abs(S-C)<=T;const _=Math.abs(D-E)<=T;const R=Math.abs(I-v)<=T;return{top:O&&R,right:O&&N,bottom:_&&R,left:_&&N}}isCardInFrame(e){const t=e.x+e.w/2;const i=e.y+e.h/2;const s=this.INPUT_SIZE/2;const a=this.INPUT_SIZE/2;const o=40;const r=30;const n=Math.abs(t-s)<o&&Math.abs(i-a)<r;const c=e.w>150&&e.w<300&&e.h>90&&e.h<200;return n&&c}areAllSidesAligned(e){return e.top&&e.right&&e.bottom&&e.left}cleanup(){this.cleanupCanvasPool();if(this.session){this.session.release?.();this.session=undefined}if(this.mobileNetSession){this.mobileNetSession.release?.();this.mobileNetSession=undefined}this.mobileNetClassMap=undefined;this.modelLoaded=false;this.logger.state("DETECCION_SERVICE_LIMPIADO",{timestamp:Date.now()})}initializeCanvasPool(){this.preprocessCanvas=document.createElement("canvas");this.preprocessCanvas.width=this.INPUT_SIZE;this.preprocessCanvas.height=this.INPUT_SIZE;this.preprocessCtx=this.preprocessCanvas.getContext("2d",{alpha:false,willReadFrequently:true});this.captureCanvas=document.createElement("canvas");this.logger.state("CANVAS_POOL_INICIALIZADO",{preprocessCanvasSize:this.INPUT_SIZE})}cleanupCanvasPool(){if(this.preprocessCanvas){this.preprocessCtx=undefined;this.preprocessCanvas=undefined}if(this.captureCanvas){this.captureCanvas=undefined}}float32ToFloat16(e){const t=new ArrayBuffer(4);const i=new DataView(t);i.setFloat32(0,e,true);const s=i.getUint32(0,true);const a=s>>31&1;const o=s>>23&255;const r=s&8388607;let n=o-127+15;if(o===0){n=0}else if(o===255){n=31}else if(n>=31){n=31;return a<<15|n<<10}else if(n<=0){return a<<15}return a<<15|n<<10|r>>13}preprocessMobileNet(e){const t=document.createElement("canvas");t.width=224;t.height=224;const i=t.getContext("2d");i.drawImage(e,0,0,224,224);const s=i.getImageData(0,0,224,224);const a=s.data;const o=224*224;const r=new Float32Array(3*o);for(let e=0;e<o;e++){r[e]=a[e*4+0]/255;r[o+e]=a[e*4+1]/255;r[2*o+e]=a[e*4+2]/255}return new window.ort.Tensor("float32",r,[1,3,224,224])}}class f{services=new Map;constructor(e){this.initializeServices(e)}initializeServices(e){const t=new o;const i=new a(e.debug);const s=new r(t);const c=new n(i,t,e.preferredCamera);const d=new h(i,e.debug,e.useDocumentClassification);this.services.set("eventBus",t);this.services.set("logger",i);this.services.set("stateManager",s);this.services.set("cameraService",c);this.services.set("detectionService",d)}get(e){const t=this.services.get(e);if(!t){throw new Error(`Service ${e} not found`)}return t}getLogger(){return this.get("logger")}getEventBus(){return this.get("eventBus")}getStateManager(){return this.get("stateManager")}getCameraService(){return this.get("cameraService")}getDetectionService(){return this.get("detectionService")}updateConfig(e){if(e.debug!==undefined){const t=this.services.get("logger");t.setDebugMode(e.debug)}}cleanup(){this.getDetectionService().cleanup();this.getEventBus().clear();this.services.clear()}}const p=":host{display:block;width:100%;height:100%;font-family:system-ui, -apple-system, sans-serif;color:#1a1a1a}.detector-container{display:flex;flex-direction:column;align-items:center;width:100%;height:100%}h1{font-size:24px;font-weight:500;color:#333;margin:0 0 24px 0}.video-container{position:relative;width:100%;height:100%;background:#333;border:1px solid #e0e0e0;border-radius:8px;overflow:hidden}video,.detection-overlay{position:absolute;width:100%;height:100%;border-radius:8px}video.mirror,.detection-overlay.mirror{transform:rotateY(180deg)}.detection-overlay{z-index:1;pointer-events:none}video{z-index:0}.detection-box{transition:opacity 0.2s ease}.status{margin-top:16px;font-size:12px;color:#666}.overlay-mask{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10;display:block;pointer-events:none}.card-outline{position:absolute;top:var(--mask-center-y, 50%);left:var(--mask-center-x, 50%);transform:translate(-50%, -50%);width:var(--mask-width, 88%);height:var(--mask-height, 55%);border:none;border-radius:4px;background:transparent;opacity:0.8}.side{position:absolute;background:#999;transition:background-color 0.3s ease;border-radius:1px}.side-top.aligned{border-left-color:#28a745;border-top-color:#28a745}.side-right.aligned{border-right-color:#28a745;border-top-color:#28a745}.side-bottom.aligned{border-left-color:#28a745;border-bottom-color:#28a745}.side-left.aligned{border-right-color:#28a745;border-bottom-color:#28a745}.side-top{top:-3px;left:-3px;width:30px;height:30px;border-left:6px solid #ffffff;border-top:6px solid #ffffff;background:transparent}.side-right{top:-3px;right:-3px;width:30px;height:30px;border-right:6px solid #ffffff;border-top:6px solid #ffffff;background:transparent}.side-bottom{bottom:-3px;left:-3px;width:30px;height:30px;border-left:6px solid #ffffff;border-bottom:6px solid #ffffff;background:transparent}.side-left{bottom:-3px;right:-3px;width:30px;height:30px;border-right:6px solid #ffffff;border-bottom:6px solid #ffffff;background:transparent}.guide-text{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);color:#fff;font-size:14px;font-weight:600;text-align:center;white-space:normal;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(12px);padding:12px 20px;border-radius:8px;max-width:300px;z-index:20;border:1px solid rgba(255, 255, 255, 0.1)}.quality-indicator{position:absolute;top:20px;right:20px;display:flex;align-items:center;gap:8px;background:rgba(0, 0, 0, 0.8);padding:8px 12px;border-radius:20px;z-index:25;transition:all 0.3s ease}.quality-indicator.warning{background:rgba(255, 152, 0, 0.9)}.quality-indicator.good{background:rgba(76, 175, 80, 0.9)}.quality-score{color:#fff;font-size:12px;font-weight:600;min-width:30px;text-align:center}.quality-status{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;color:#fff;transition:all 0.3s ease}.quality-status.ready{background:#4CAF50}.quality-status.not-ready{background:#f44336}.card-outline.quality-warning{animation:qualityWarning 1s ease-in-out infinite alternate}@keyframes qualityWarning{0%{box-shadow:0 0 0 3px rgba(255, 152, 0, 0.6)}100%{box-shadow:0 0 0 6px rgba(255, 152, 0, 0.3)}}.capture-animation{position:absolute;top:0;left:0;width:100%;height:100%;background:#fff;opacity:0;z-index:30;pointer-events:none;animation:captureFlash 0.6s ease-out}@keyframes captureFlash{0%{opacity:0}15%{opacity:0.8}30%{opacity:0}45%{opacity:0.4}60%{opacity:0}100%{opacity:0}}.card-outline.capturing{animation:pulseGreen 0.6s ease-out}@keyframes pulseGreen{0%{border-color:#28a745;box-shadow:0 0 0 4px rgba(40, 167, 69, 0)}50%{border-color:#28a745;box-shadow:0 0 0 8px rgba(40, 167, 69, 0.6)}100%{border-color:#28a745;box-shadow:0 0 0 4px rgba(40, 167, 69, 0)}}.flip-animation{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);z-index:35;pointer-events:none;opacity:0;animation:showFlipInstruction 3s ease-in-out;display:flex;flex-direction:column;align-items:center;justify-content:center}.id-card-icon{width:80px;height:50px;background:linear-gradient(135deg, #6c757d 0%, #495057 100%);border-radius:8px;position:relative;animation:flipCard 2s ease-in-out infinite;box-shadow:0 4px 12px rgba(0, 0, 0, 0.3)}.id-card-icon::before{content:'';position:absolute;top:8px;left:8px;width:16px;height:12px;background:rgba(255, 255, 255, 0.9);border-radius:2px}.id-card-icon::after{content:'';position:absolute;top:25px;left:8px;width:64px;height:3px;background:rgba(255, 255, 255, 0.7);border-radius:1px;box-shadow:0 6px 0 rgba(255, 255, 255, 0.7), 0 12px 0 rgba(255, 255, 255, 0.7)}.flip-text{margin-top:12px;color:#fff;font-size:14px;font-weight:600;text-align:center;background:rgba(128, 128, 128, 0.8);padding:12px 20px;border-radius:20px;max-width:300px}@keyframes showFlipInstruction{0%{opacity:0;transform:translate(-50%, -50%) scale(0.8)}15%{opacity:1;transform:translate(-50%, -50%) scale(1)}85%{opacity:1;transform:translate(-50%, -50%) scale(1)}100%{opacity:0;transform:translate(-50%, -50%) scale(0.8)}}@keyframes flipCard{0%{transform:rotateY(0deg)}50%{transform:rotateY(180deg)}100%{transform:rotateY(360deg)}}.success-animation{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);z-index:35;pointer-events:none;opacity:0;animation:showSuccessMessage 3s ease-in-out;display:flex;flex-direction:column;align-items:center;justify-content:center}.check-icon{width:80px;height:80px;background:linear-gradient(135deg, #6c757d 0%, #495057 100%);border-radius:50%;position:relative;animation:bounceSuccess 0.6s ease-out;box-shadow:0 4px 16px rgba(108, 117, 125, 0.4);display:flex;align-items:center;justify-content:center}.check-icon::before{content:'';position:absolute;width:20px;height:35px;border:4px solid #fff;border-top:none;border-left:none;transform:rotate(45deg);animation:drawCheck 0.4s ease-out 0.2s both}.success-text{margin-top:16px;color:#fff;font-size:14px;font-weight:600;text-align:center;background:rgba(128, 128, 128, 0.8);padding:12px 20px;border-radius:20px;max-width:300px;animation:fadeInUp 0.5s ease-out 0.4s both}@keyframes showSuccessMessage{0%{opacity:0;transform:translate(-50%, -50%) scale(0.5)}15%{opacity:1;transform:translate(-50%, -50%) scale(1)}85%{opacity:1;transform:translate(-50%, -50%) scale(1)}100%{opacity:0;transform:translate(-50%, -50%) scale(0.9)}}@keyframes bounceSuccess{0%{transform:scale(0)}50%{transform:scale(1.1)}100%{transform:scale(1)}}@keyframes drawCheck{0%{width:0;height:0}50%{width:20px;height:0}100%{width:20px;height:35px}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}100%{opacity:1;transform:translateY(0)}}.skip-section{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);z-index:25;display:flex;flex-direction:column;align-items:center;width:100%;max-width:300px}.skip-explanation{background:rgba(0, 0, 0, 0.5);color:#ffffff;padding:10px 16px;border-radius:8px;font-size:14px;font-weight:500;text-align:center;margin-bottom:12px;box-shadow:0 2px 8px rgba(0, 0, 0, 0.2);backdrop-filter:blur(12px);border:1px solid rgba(255, 255, 255, 0.1);animation:fadeIn 0.3s ease-in-out}@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.skip-button{pointer-events:auto;background:#fff;color:#333;border:none;border-radius:25px;padding:12px 24px;font-size:14px;font-weight:600;cursor:pointer;transition:all 0.3s ease}.skip-button:hover{background:#f8f9fa}.skip-button:active{background:#e9ecef;transform:translateY(1px)}.camera-controls{position:absolute;top:16px;right:16px;z-index:25;display:flex;gap:8px;pointer-events:auto}.camera-selector-button{height:32px;padding:0 10px;border:none;border-radius:8px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(12px);color:#ffffff;font-size:12px;font-weight:500;cursor:pointer;transition:all 0.2s ease;display:flex;align-items:center;justify-content:center;border:1px solid rgba(255, 255, 255, 0.1);white-space:nowrap;min-width:fit-content}.camera-selector-button:hover{background:rgba(0, 0, 0, 0.8);border-color:rgba(255, 255, 255, 0.2);transform:translateY(-1px)}.camera-selector-button:active{transform:translateY(0);background:rgba(0, 0, 0, 0.9)}.camera-selector-button:disabled,.camera-selector-button.loading{opacity:0.7;cursor:not-allowed;pointer-events:none}.camera-selector-button:disabled:hover,.camera-selector-button.loading:hover{transform:none;background:rgba(0, 0, 0, 0.6);border-color:rgba(255, 255, 255, 0.1)}.button-spinner{width:16px;height:16px;border:2px solid rgba(255, 255, 255, 0.3);border-top:2px solid #ffffff;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.camera-selector-dropdown{position:absolute;top:56px;right:16px;z-index:30;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;min-width:260px;max-width:300px;border:1px solid rgba(255, 255, 255, 0.1);overflow:hidden;pointer-events:auto;animation:slideInFromTop 0.3s ease-out}@keyframes slideInFromTop{0%{opacity:0;transform:translateY(-8px) scale(0.95)}100%{opacity:1;transform:translateY(0) scale(1)}}.camera-selector-header{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;border-bottom:1px solid rgba(255, 255, 255, 0.1)}.camera-selector-header span{font-weight:500;color:#ffffff;font-size:13px;opacity:0.9}.close-selector{width:20px;height:20px;border:none;background:none;color:rgba(255, 255, 255, 0.7);font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all 0.2s ease}.close-selector:hover{background:rgba(255, 255, 255, 0.1);color:#ffffff}.camera-list{padding:4px 0;max-height:240px;overflow-y:auto}.camera-option{width:100%;padding:8px 12px;border:none;background:none;text-align:left;cursor:pointer;transition:all 0.2s ease;display:flex;justify-content:space-between;align-items:center;color:rgba(255, 255, 255, 0.9)}.camera-option:hover{background:rgba(255, 255, 255, 0.08)}.camera-option.selected{background:rgba(255, 255, 255, 0.12);color:#ffffff}.camera-label{font-size:13px;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-right:8px;font-weight:400}.selected-indicator{font-size:14px;color:#ffffff;opacity:0.9}.device-info{padding:6px 12px;border-top:1px solid rgba(255, 255, 255, 0.1);background:rgba(255, 255, 255, 0.05)}.device-info small{color:rgba(255, 255, 255, 0.6);font-size:11px;text-transform:capitalize;font-weight:400}@media (max-width: 480px){.camera-controls{top:12px;right:12px;gap:6px}.camera-selector-button{height:36px;padding:0 12px;font-size:11px;border-radius:6px}.camera-selector-dropdown{right:12px;top:48px;min-width:240px;max-width:calc(100vw - 24px)}.camera-selector-header{padding:6px 10px}.camera-option{padding:6px 10px}.device-info{padding:4px 10px}}.watermark{position:absolute;bottom:12px;right:12px;z-index:15;pointer-events:none;opacity:0.7}.watermark img{height:24px;width:auto;filter:drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3))}.component-status{position:absolute;top:16px;left:16px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;border:1px solid rgba(255, 255, 255, 0.1);display:flex;align-items:center;gap:6px;padding:6px 10px;z-index:40;height:32px;width:fit-content;animation:slideInFromTop 0.3s ease-out}.status-spinner{width:16px;height:16px;border:1px solid rgba(255, 255, 255, 0.3);border-top:1px solid #ffffff;border-radius:50%;animation:statusSpin 1s linear infinite;flex-shrink:0}.status-content{display:flex;flex-direction:column;gap:1px}.status-message{color:#ffffff;font-size:12px;font-weight:500;margin:0}.status-description{color:rgba(255, 255, 255, 0.7);font-size:10px;line-height:1.2;margin:0}@keyframes statusSpin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@media (max-width: 480px){.component-status{top:12px;left:12px;padding:4px 8px;gap:4px;height:28px;border-radius:8px}.status-spinner{width:14px;height:14px}.status-message{font-size:11px}.status-description{font-size:9px}}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0, 0, 0, 0.85);backdrop-filter:blur(4px);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:30;border-radius:8px}.loading-spinner{width:50px;height:50px;border:3px solid rgba(255, 255, 255, 0.15);border-top:3px solid #28a745;border-radius:50%;animation:spin 1s ease-in-out infinite;margin-bottom:16px}.loading-text{color:#ffffff;font-size:14px;font-weight:500;text-align:center;opacity:0.9;margin-bottom:4px}.loading-description{color:rgba(255, 255, 255, 0.7);font-size:12px;text-align:center;opacity:0.8}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.performance-monitor{position:absolute;top:70px;left:16px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;border:1px solid rgba(255, 255, 255, 0.1);z-index:35;width:fit-content;animation:slideInFromLeft 0.3s ease-out;transition:all 0.3s ease}@keyframes slideInFromLeft{0%{opacity:0;transform:translateX(-20px) scale(0.95)}100%{opacity:1;transform:translateX(0) scale(1)}}.performance-expanded{padding:6px 10px}.metrics-row{display:flex;gap:8px;margin-bottom:4px}.metrics-row:last-child{margin-bottom:0}.metric-compact{display:flex;flex-direction:column;align-items:center;gap:2px;min-width:50px}.metric-label{font-size:9px;color:rgba(255, 255, 255, 0.6);font-weight:500;text-transform:uppercase;letter-spacing:0.3px}.metric-value{font-size:10px;font-weight:600;font-family:'Monaco', 'Menlo', 'Consolas', monospace;padding:2px 4px;border-radius:3px;text-align:center;white-space:nowrap}.metric-value.good{color:#4ade80;background:rgba(74, 222, 128, 0.1);border:1px solid rgba(74, 222, 128, 0.2)}.metric-value.warning{color:#fbbf24;background:rgba(251, 191, 36, 0.1);border:1px solid rgba(251, 191, 36, 0.2)}.metric-value.danger{color:#f87171;background:rgba(248, 113, 113, 0.1);border:1px solid rgba(248, 113, 113, 0.2)}@media (max-width: 480px){.performance-monitor{top:60px;left:12px;width:fit-content}.performance-expanded{padding:4px 8px}.metrics-row{gap:6px;margin-bottom:3px}.metric-compact{min-width:45px;gap:1px}.metric-label{font-size:8px}.metric-value{font-size:9px;padding:1px 3px}}.quality-monitor{position:absolute;top:200px;left:16px;background:rgba(0, 0, 0, 0.25);backdrop-filter:blur(20px);border-radius:12px;border:1px solid rgba(255, 255, 255, 0.1);z-index:35;width:fit-content;animation:slideInFromLeft 0.3s ease-out;transition:all 0.3s ease}.quality-text{padding:6px 10px;font-size:11px;color:white;font-family:'Monaco', 'Menlo', 'Consolas', monospace;line-height:1.4}.quality-fail{color:#ff9999}@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.7}}.metric-value.danger{animation:pulse 2s infinite}@media (max-width: 480px){.quality-monitor{top:160px;left:12px}.quality-text{padding:4px 8px;font-size:10px}}";const m=class{constructor(i){e(this,i);this.captureCompleted=t(this,"captureCompleted");this.isReady=t(this,"isReady")}get el(){return i(this)}debug=false;alignmentTolerance=15;maskSize=90;cropMargin=20;useDocumentClassification=false;preferredCamera="auto";captureDelay=1500;enableBackDocumentTimer=false;backDocumentTimerDuration=20;captureCompleted;isReady;detectionBoxes=[];sideAlignment={top:false,right:false,bottom:false,left:false};isMaskReady=false;shouldMirrorVideo=true;showCameraSelector=false;isSwitchingCamera=false;hasDocumentDetected=false;currentStatus={message:"Inicializando componente...",description:"Configurando servicios y cargando recursos",type:"initializing",isInitialized:false};performanceData={fps:0,inferenceTime:0,memoryUsage:0,onnxLoadTime:0,frameProcessingTime:0,totalDetections:0,successfulDetections:0,detectionRate:0};backDocumentTimerRemaining=0;serviceContainer;logger;eventBus;stateManager;cameraService;detectionService;videoRef;detectionContainer;videoStream;animationId;lastDetectedBox;startTime;hasScreenshotTaken=false;alignmentStartTime;alignmentTimer;backDocumentTimer;performanceMetrics={fps:0,inferenceTime:0,memoryUsage:0,cpuUsage:0,onnxLoadTime:0,frameProcessingTime:0,totalDetections:0,successfulDetections:0,detectionRate:0,lastUpdateTime:0};performanceUpdateInterval;frameSkipCounter=0;FRAME_SKIP=2;consecutiveFailures=0;MAX_FAILURES=30;lastInferenceTime=0;MIN_INFERENCE_INTERVAL=50;async componentDidLoad(){this.updateStatus("Iniciando servicios...","Configurando módulos internos","initializing");await this.initializeServices();this.updateStatus("Configurando eventos...","Preparando comunicación entre servicios","initializing");await this.setupEventListeners();this.updateStatus("Inicializando cámara...","Detectando dispositivos disponibles","initializing");await this.initializeComponent();if(this.debug){this.initializePerformanceMonitor()}}async initializeServices(){const e={debug:this.debug,alignmentTolerance:this.alignmentTolerance,maskSize:this.maskSize,cropMargin:this.cropMargin,useDocumentClassification:this.useDocumentClassification,preferredCamera:this.preferredCamera,captureDelay:this.captureDelay};this.serviceContainer=new f(e);this.logger=this.serviceContainer.getLogger();this.eventBus=this.serviceContainer.getEventBus();this.stateManager=this.serviceContainer.getStateManager();this.cameraService=this.serviceContainer.getCameraService();this.detectionService=this.serviceContainer.getDetectionService();this.logger.state("SERVICIOS_INICIALIZADOS",{timestamp:Date.now()})}async setupEventListeners(){this.eventBus.on("state-changed",(e=>{this.handleStateChange(e)}));this.eventBus.on("camera-changed",(e=>{this.logger.state("CAMARA_CAMBIADA_EVENT",{cameraId:e})}));this.eventBus.on("error",(e=>{this.logger.error("Error en servicio:",e)}))}async initializeComponent(){this.logger.state("COMPONENTE_INICIALIZANDO",{debug:this.debug,maskSize:this.maskSize,cropMargin:this.cropMargin,useDocumentClassification:this.useDocumentClassification,preferredCamera:this.preferredCamera,captureDelay:this.captureDelay});this.validateProps();if(this.debug){this.stateManager.updateCaptureState({isLoading:true});await new Promise((e=>setTimeout(e,500)))}this.updateStatus("Detectando cámaras...","Buscando dispositivos de captura","initializing");await this.cameraService.detectDeviceType();await this.cameraService.enumerateDevices();this.updateStatus("Cargando modelo IA...","Preparando reconocimiento de documentos","initializing");await this.loadOnnxRuntime();this.initializeResizeObserver()}validateProps(){if(this.maskSize<50||this.maskSize>100){this.logger.warn(`Propiedad maskSize inválida. Valor: ${this.maskSize}, esperado: 50-100. Usando valor por defecto: 90`);this.maskSize=90}if(this.cropMargin<0||this.cropMargin>100){this.logger.warn(`Propiedad cropMargin inválida. Valor: ${this.cropMargin}, esperado: 0-100. Usando valor por defecto: 0`);this.cropMargin=0}const e=["auto","front","back"];if(!e.includes(this.preferredCamera)){this.logger.warn(`Propiedad preferredCamera inválida. Valor: ${this.preferredCamera}, esperado: ${e.join(", ")}. Usando valor por defecto: 'auto'`);this.preferredCamera="auto"}if(this.captureDelay<0||this.captureDelay>1e4){this.logger.warn(`Propiedad captureDelay inválida. Valor: ${this.captureDelay}, esperado: 0-10000. Usando valor por defecto: 1500`);this.captureDelay=1500}}async loadOnnxRuntime(){if(!window.ort){this.updateStatus("Descargando librerías...","Obteniendo recursos de reconocimiento","initializing");const e=document.createElement("script");e.src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js";document.head.appendChild(e);await new Promise((t=>{e.onload=()=>{setTimeout((()=>{this.finalizeInitialization();t(undefined)}),300)}}))}else{setTimeout((()=>{this.finalizeInitialization()}),300)}}finalizeInitialization(){this.stateManager.updateCaptureState({isLoading:false});this.currentStatus={message:"Listo para capturar",description:"",type:"ready",isInitialized:true};this.emitReadyEvent()}updateStatus(e,t,i="loading"){this.currentStatus={message:e,description:t,type:i,isInitialized:this.currentStatus.isInitialized}}emitReadyEvent(){const e=!!window.ort&&this.detectionService.isModelLoaded();this.isReady.emit(e);this.logger.state("COMPONENTE_LISTO",{ortLibraryLoaded:!!window.ort,modelPreloaded:this.detectionService.isModelLoaded(),isReady:e})}handleStateChange(e){}initializeResizeObserver(){if("ResizeObserver"in window&&this.detectionContainer){const e=new ResizeObserver((()=>{this.handleResize()}));e.observe(this.detectionContainer.parentElement)}}handleResize(){if(this.detectionContainer){const e=this.detectionContainer.parentElement;const t=e.getBoundingClientRect();this.updateMaskDimensions(t);this.logger.debug("Container redimensionado:",{width:t.width,height:t.height})}}updateMaskDimensions(e){if(!this.videoRef)return;const t=this.videoRef.videoWidth;const i=this.videoRef.videoHeight;if(t===0||i===0)return;const s=t/i;const a=e.width/e.height;let o,r;let n=0,c=0;if(s>a){o=e.width;r=e.width/s;c=(e.height-r)/2}else{r=e.height;o=e.height*s;n=(e.width-o)/2}const d=85.6/53.98;const l=r*d;let h,f;const p=this.maskSize/100;if(l<=o){f=r*p;h=f*d}else{h=o*p;f=h/d}const m=h/e.width*100;const u=f/e.height*100;const b=n+o/2;const g=c+r/2;const x=b/e.width*100;const y=g/e.height*100;this.el.style.setProperty("--mask-width",`${m}%`);this.el.style.setProperty("--mask-height",`${u}%`);this.el.style.setProperty("--mask-center-x",`${x}%`);this.el.style.setProperty("--mask-center-y",`${y}%`);this.isMaskReady=true;this.logger.state("DIMENSIONES_MASCARA_ACTUALIZADAS",{video:{width:t,height:i},displayed:{width:o,height:r},mask:{widthPercent:m,heightPercent:u},center:{x,y},offset:{x:n,y:c}})}async getCapturedImages(){const e=this.stateManager.getCaptureState();if(e.step!=="completed"){throw new Error("El proceso de captura no ha sido completado")}return this.stateManager.getCapturedImages()}async isProcessCompleted(){return this.stateManager.isProcessCompleted()}async startCapture(){await this.startDetection()}async stopCapture(){this.exitSession()}async resetCapture(){this.resetDetection()}async skipBackCapture(){const e=this.stateManager.getCaptureState();const t=this.stateManager.getCapturedImages();if(e.step==="back"&&t.front.fullFrame){this.completeProcess(true)}}async getStatus(){const e=this.stateManager.getCaptureState();const t=this.stateManager.getCapturedImages();return{isVideoActive:e.isVideoActive,captureStep:e.step,hasImages:!!(t.front.fullFrame||t.back.fullFrame),isProcessCompleted:this.stateManager.isProcessCompleted(),isModelPreloaded:this.detectionService.isModelLoaded()}}async preloadModel(){if(this.detectionService.isModelLoaded()){this.logger.state("MODELO_YA_PRECARGADO");this.updateStatus("Modelos ya cargados","","ready");return{success:true,message:"Model already loaded"}}try{const e=performance.now();this.updateStatus("Descargando modelo de detección...","Obteniendo red neuronal para reconocimiento de documentos","loading");this.stateManager.updateCaptureState({isLoading:true});await this.detectionService.loadModel();this.updateStatus("Cargando clasificador...","Preparando modelo de clasificación de tipos de documento","loading");await this.detectionService.loadClassificationModel();const t=performance.now();const i=t-e;if(this.debug){this.recordOnnxPerformance(i,0)}this.updateStatus("Optimizando modelos...","Configurando parámetros de rendimiento","loading");await new Promise((e=>setTimeout(e,300)));this.updateStatus("Modelos precargados","","ready");this.stateManager.updateCaptureState({isLoading:false});this.emitReadyEvent();this.logger.state("MODELOS_PRECARGADOS_EXITOSAMENTE",{loadTime:Math.round(i)});return{success:true,message:"Models preloaded successfully"}}catch(e){this.logger.error("Error al precargar modelos:",e);this.updateStatus("Error al cargar modelos","No se pudieron descargar los recursos necesarios","error");this.stateManager.updateCaptureState({isLoading:false});return{success:false,error:e.message}}}async getCameraInfo(){return this.cameraService.getCameraInfo()}async setPreferredCamera(e){this.preferredCamera=e;this.serviceContainer.updateConfig({preferredCamera:e});await this.cameraService.enumerateDevices();const t=this.stateManager.getCaptureState();if(t.isVideoActive){const e=this.cameraService.getSelectedCameraId();if(e){await this.cameraService.switchCamera(e)}}return{success:true,selectedCamera:this.cameraService.getSelectedCameraId(),availableCameras:this.cameraService.getAvailableCameras().length}}async setCaptureDelay(e){if(e<0||e>1e4){throw new Error("Capture delay must be between 0 and 10000 milliseconds")}this.captureDelay=e;this.serviceContainer.updateConfig({captureDelay:e});return{success:true,captureDelay:this.captureDelay}}async getCaptureDelay(){return this.captureDelay}async setTorchEnabled(e){const t=await this.cameraService.setTorchEnabled(e,this.videoStream);return{success:t,enabled:t?e:false}}async focusAtPoint(e,t){const i=await this.cameraService.focusAtPoint(e,t,this.videoStream);return{success:i,coordinates:{x:e,y:t}}}async startDetection(){this.logger.state("INICIANDO_DETECCION");try{if(!this.detectionService.isModelLoaded()){const e=performance.now();this.updateStatus("Cargando modelo de detección...","Descargando red neuronal para reconocimiento","loading");this.stateManager.updateCaptureState({isLoading:true});await this.detectionService.loadModel();this.updateStatus("Cargando clasificador...","Preparando modelo de clasificación de documentos","loading");await this.detectionService.loadClassificationModel();const t=performance.now();const i=t-e;if(this.debug){this.recordOnnxPerformance(i,0)}this.logger.state("MODELOS_CARGADOS_EN_DETECCION",{loadTime:Math.round(i)})}this.updateStatus("Detectando cámaras...","Buscando dispositivos de captura disponibles","loading");await this.cameraService.enumerateDevices();this.updateStatus("Configurando cámara...","Estableciendo resolución y parámetros óptimos","loading");const e=await this.cameraService.setupCamera();this.updateStatus("Captura activa","Buscando documento en el marco de captura","active");await this.initializeVideoStream(e);if(this.detectionContainer){const e=this.detectionContainer.parentElement;const t=e.getBoundingClientRect();this.updateMaskDimensions(t)}this.startTime=Date.now();this.stateManager.updateCaptureState({isLoading:false});this.detectFrame()}catch(e){this.logger.error("Error al inicializar detección:",e);this.updateStatus("Error al iniciar captura","No se pudo completar la inicialización","error");this.stateManager.updateCaptureState({isLoading:false})}}async initializeVideoStream(e){if(this.videoRef){this.videoRef.srcObject=e;this.videoStream=e;const t=this.cameraService.isRearCamera(e);this.shouldMirrorVideo=!t;this.logger.state("CAMARA_CONFIGURADA",{isRearCamera:t,shouldMirrorVideo:this.shouldMirrorVideo});return new Promise((e=>{this.videoRef.onloadedmetadata=async()=>{await this.videoRef.play();this.stateManager.updateCaptureState({isVideoActive:true});e()}}))}else{throw new Error("Video element not available")}}async detectFrame(){try{const e=performance.now();const t=this.stateManager.getCaptureState();if(!this.videoRef||!this.detectionContainer||!this.detectionService.isModelLoaded())return;if(t.isDetectionPaused){if(t.step!=="completed"){this.animationId=requestAnimationFrame((()=>this.detectFrame()))}return}this.frameSkipCounter++;if(this.frameSkipCounter<=this.FRAME_SKIP){if(t.step!=="completed"){this.animationId=requestAnimationFrame((()=>this.detectFrame()))}return}this.frameSkipCounter=0;const i=Date.now();if(i-this.lastInferenceTime<this.MIN_INFERENCE_INTERVAL){if(t.step!=="completed"){this.animationId=requestAnimationFrame((()=>this.detectFrame()))}return}this.lastInferenceTime=i;const s=performance.now();const a=this.detectionService.preprocess(this.videoRef);const o=await this.detectionService.runInference(a);const r=performance.now()-s;if(this.debug){this.recordOnnxPerformance(0,r)}if(this.startTime&&Date.now()-this.startTime<5e3){o.forEach((e=>{const i=this.detectionService.isCardInFrame(e);const s=i?e.score*1.2:e.score;if(s>t.bestScore){this.stateManager.updateCaptureState({bestScore:s})}}))}const n=this.hasDocumentDetected;this.hasDocumentDetected=o.length>0;if(!n&&this.hasDocumentDetected&&t.step==="back"&&this.enableBackDocumentTimer){this.startBackDocumentTimer()}if(o.length===0){this.consecutiveFailures++}else{this.consecutiveFailures=0}if(this.debug){this.updateDetectionBoxes(o)}else{this.detectionBoxes=[]}this.updateMaskColor(o);if(this.debug){const t=performance.now();const i=t-e;this.recordFrameProcessing(i,o.length)}if(t.step!=="completed"){if(this.consecutiveFailures>this.MAX_FAILURES){setTimeout((()=>this.detectFrame()),200)}else{this.animationId=requestAnimationFrame((()=>this.detectFrame()))}}}catch(e){this.logger.error("Error en inferencia de modelo:",e);const t=this.stateManager.getCaptureState();if(t.step!=="completed"){setTimeout((()=>this.detectFrame()),100)}}}disconnectedCallback(){this.cleanup()}cleanup(){if(this.animationId){cancelAnimationFrame(this.animationId)}if(this.videoStream){this.videoStream.getTracks().forEach((e=>e.stop()))}if(this.alignmentTimer){clearTimeout(this.alignmentTimer);this.alignmentTimer=undefined}if(this.performanceUpdateInterval){clearInterval(this.performanceUpdateInterval);this.performanceUpdateInterval=undefined}this.detectionBoxes=[];this.alignmentStartTime=undefined;this.hasDocumentDetected=false;this.serviceContainer?.cleanup()}render(){const e=this.stateManager?.getCaptureState()||{isVideoActive:false,showFlipAnimation:false,showSuccessAnimation:false,step:"front",isCapturing:false};const t=this.cameraService?.getCameraInfo()||{availableCameras:[],selectedCameraId:null,deviceType:"desktop"};return s("div",{key:"9d4d77042218ab3d0bc4fb1ce879db09dc3e78b4",class:"detector-container"},s("div",{key:"51ac8ccb1275637282b038ad8364d19f14ef61b1",class:"video-container"},s("video",{key:"a34f0481da20ec5b7b62b21aa275ec5f6dfec5d1",ref:e=>this.videoRef=e,autoplay:true,muted:true,playsinline:true,class:this.shouldMirrorVideo?"mirror":"",style:{display:e.isVideoActive?"block":"none"}}),s("div",{key:"43b71dfe3eaf20ffa66a4139e24b1af6a2074631",ref:e=>this.detectionContainer=e,class:`detection-overlay ${this.shouldMirrorVideo?"mirror":""}`},this.debug&&this.detectionBoxes.map(((e,t)=>s("div",{key:t,class:"detection-box",style:{position:"absolute",left:`${e.x}px`,top:`${e.y}px`,width:`${e.w}px`,height:`${e.h}px`,border:"2px solid #32406C",pointerEvents:"none",boxSizing:"border-box"}})))),this.isMaskReady&&s("div",{key:"c2596f8cabb227e3ea3b082495f52b141cb1690f",class:"overlay-mask"},s("div",{key:"ba1ea39b5df1cd312a9bd9410b7225a29cfb8a29",class:"card-outline"},s("div",{key:"6ce4d4d969d5f3fbcf75a4eb285f61d434c5633b",class:"side side-top"}),s("div",{key:"36653ecc4fcda25dfc84bc4d1f4c4c5dfb71ced7",class:"side side-right"}),s("div",{key:"8b108fa8fb370b229a0d1a77cb1ff044319a8f75",class:"side side-bottom"}),s("div",{key:"a7aa3b45c065a50445aafd5c3ccefb57b0c9c769",class:"side side-left"}),!e.showFlipAnimation&&!e.showSuccessAnimation&&s("div",{key:"b94b92273e12a019238e11ae57f21e140f13c3f1",class:"guide-text"},"Alinee su identificación con el marco")),e.step==="back"&&!e.showFlipAnimation&&!e.showSuccessAnimation&&s("div",{key:"144c3741003ec0cc148bb6ce92012d7b3cd110c8",class:"skip-section"},s("div",{key:"f0a984a6b75afa374c5d47da9d53e39f98071da0",class:"skip-explanation"},"Si tu documento no tiene lado trasero, da clic en el botón para continuar con el proceso"),s("button",{key:"57ac30d776e30709aab6e0a621cef889da3cc677",class:"skip-button",onClick:()=>this.skipBackCapture(),type:"button"},this.enableBackDocumentTimer&&this.backDocumentTimerRemaining>0?`Saltar reverso (${this.backDocumentTimerRemaining}s)`:"Saltar reverso")),e.isVideoActive&&s("div",{key:"bd45628707e0169317ed3dd4247e1056d7046104",class:"camera-controls"},s("button",{key:"e750fbf4d5d76d9e9596823bb2b86801ef19e485",class:`camera-selector-button ${this.isSwitchingCamera?"loading":""}`,onClick:()=>this.toggleCameraSelector(),type:"button",title:"Seleccionar cámara",disabled:this.isSwitchingCamera},this.isSwitchingCamera?s("div",{class:"button-spinner"}):"Cámaras")),this.showCameraSelector&&t.availableCameras.length>0&&s("div",{key:"40ada780a8ea13aeeaee9cb39bc6496f69f2679d",class:"camera-selector-dropdown"},s("div",{key:"3a920bb02ba024f0359513f10544bf0528ecee6d",class:"camera-selector-header"},s("span",{key:"e5efd478a602b13821ba53cb9a7a59d1b4a71178"},"Seleccionar Cámara"),s("button",{key:"2df6cc11e162be74862029e33815927e3fa8f2f8",class:"close-selector",onClick:()=>this.toggleCameraSelector(),type:"button"},"×")),s("div",{key:"06934642dff134c9e1a6872f935a5892a9c7b835",class:"camera-list"},t.availableCameras.map((e=>s("button",{key:e.id,class:`camera-option ${t.selectedCameraId===e.id?"selected":""}`,onClick:()=>this.handleCameraSwitch(e.id),type:"button"},s("span",{class:"camera-label"},e.label||`Cámara ${t.availableCameras.indexOf(e)+1}`),t.selectedCameraId===e.id&&s("span",{class:"selected-indicator"},"✓"))))),s("div",{key:"8d5ede287c2efb0ebe418bee8dc7fb310443c991",class:"device-info"},s("small",{key:"b7dd10565113694b09f01ab28ffa29262ae1d2bc"},"Dispositivo: ",t.deviceType)))),e.isCapturing&&s("div",{key:"2f9e549e6c0c56d4db5835e58361fb17bba6cf90",class:"capture-animation"}),e.showFlipAnimation&&s("div",{key:"a6ef0ed127f23e9d764896ed743ca8d8454851a6",class:"flip-animation"},s("div",{key:"0b04411f88a634bb3243b00ca2d5a45fd6962dea",class:"id-card-icon"}),s("div",{key:"9327be58879b407cea87f455989406e58302e9d1",class:"flip-text"},"¡Voltea tu identificación!")),e.showSuccessAnimation&&s("div",{key:"bd268578b5003e99256e3340b4a9a6fb7656be64",class:"success-animation"},s("div",{key:"064e0a5b9851de14bc6829f028e7ea7161fd1633",class:"check-icon"}),s("div",{key:"bdcd94a8806399e396e218a359c10b11d05f38d6",class:"success-text"},"¡Proceso completado!")),s("div",{key:"3d9af617376c16e44e065873919c3d90ff46110a",class:`component-status status-${this.currentStatus.type}`},(this.currentStatus.type==="loading"||this.currentStatus.type==="initializing")&&s("div",{key:"be7b56decfd6f12dcca46b2a9456480e3d5ac00e",class:"status-spinner"}),s("div",{key:"5fe9850883cb749cebaa18c3e9c13ca21325e373",class:"status-content"},s("div",{key:"43fdb50691e4b98e56126af1a129f625061128bf",class:"status-message"},this.currentStatus.message),this.currentStatus.description&&s("div",{key:"b76cbfa4a0349421fcd535d3fd8bf40c89ca3aef",class:"status-description"},this.currentStatus.description))),this.debug&&s("div",{key:"eddefb464af0487ab9ab2a0f76dccbb6a2092e51",class:"performance-monitor"},s("div",{key:"7b7d93b56cb4cd4fbb1bdde89c6150b282fa805e",class:"performance-expanded"},s("div",{key:"f302e8b9d985fb8cad53c4c4e0d37a3bf5a63261",class:"metrics-row"},s("div",{key:"e8d8f2420ee8643a7f454d38065c75b5be598f77",class:"metric-compact"},s("span",{key:"6e52eb5bb06e0df57e61774de38c31349f45e22b",class:"metric-label"},"FPS"),s("span",{key:"6636f9cea20c49b49c17db86188e2f6b214c45c3",class:`metric-value ${this.performanceData.fps<15?"warning":this.performanceData.fps<10?"danger":"good"}`},this.performanceData.fps)),s("div",{key:"afa1d9dec05b14256a1b1fcec8638b8c21a56e37",class:"metric-compact"},s("span",{key:"9c55e30f5d01582648bacc1fb38ca1990485a591",class:"metric-label"},"MEM"),s("span",{key:"ca263601e8715027f95ffb2d5413a643dc570cf2",class:`metric-value ${this.performanceData.memoryUsage>100?"warning":this.performanceData.memoryUsage>200?"danger":"good"}`},this.performanceData.memoryUsage,"MB"))),s("div",{key:"03caf19961fd01b7781484d49d8121b1e78c161f",class:"metrics-row"},s("div",{key:"bffb08f01f703411f7c8605e4f8d95b1c37b5c0f",class:"metric-compact"},s("span",{key:"9b92279b3253cc669412733facb3751f4344d69f",class:"metric-label"},"INF"),s("span",{key:"3234d4150e2e1479e3b552767af8123e69911d6c",class:`metric-value ${this.performanceData.inferenceTime>100?"warning":this.performanceData.inferenceTime>200?"danger":"good"}`},this.performanceData.inferenceTime,"ms")),s("div",{key:"77082d2669db53f19fb50b3bbfa1ebefb0b86ff4",class:"metric-compact"},s("span",{key:"cc6ef96c72c800ba36dab2a388f1de863b2dacd5",class:"metric-label"},"FRAME"),s("span",{key:"e2bb4b7351869a76e810f8bbf20d805154495e35",class:`metric-value ${this.performanceData.frameProcessingTime>50?"warning":this.performanceData.frameProcessingTime>100?"danger":"good"}`},this.performanceData.frameProcessingTime,"ms"))),s("div",{key:"5700d7ef839fa77686299d79445203090dc8079f",class:"metrics-row"},s("div",{key:"a2999a035fccb7f250c01b084075490678513c87",class:"metric-compact"},s("span",{key:"3677d58665996fa5969507dbaff9e956b2ea54ee",class:"metric-label"},"DET"),s("span",{key:"c584312438b339c82a3bdc33f00fb985ff2a6f55",class:"metric-value good"},this.performanceData.successfulDetections,"/",this.performanceData.totalDetections)),s("div",{key:"58866219f213bf8607083f30be2d5ca5d0515cea",class:"metric-compact"},s("span",{key:"d90b450051331347f219b6c0f197536d0dcee9b7",class:"metric-label"},"RATE"),s("span",{key:"f6e6cd7948e06014e5a0416e4e81394fa36ec61d",class:`metric-value ${this.performanceData.detectionRate<30?"danger":this.performanceData.detectionRate<60?"warning":"good"}`},this.performanceData.detectionRate,"%"))))),s("div",{key:"c1d0194f181a0082cc1aa5452de382908da61b65",class:"watermark"},s("img",{key:"e04d35f3c79a2b4a3922ab5b0f102220171fa7c0",src:"https://storage.googleapis.com/jaak-static/commons/powered-by-jaak.png",alt:"Powered by Jaak"}))))}updateDetectionBoxes(e){if(!this.videoRef||!this.detectionContainer)return;const t=this.videoRef.videoWidth;const i=this.videoRef.videoHeight;const s=this.detectionContainer.parentElement;const a=s.getBoundingClientRect();const o=a.width;const r=a.height;if(t===0||i===0)return;const n=t/i;const c=o/r;let d,l;let h=0,f=0;if(n>c){d=o;l=o/n;f=(r-l)/2}else{l=r;d=r*n;h=(o-d)/2}const p=320;const m=d/p;const u=l/p;this.detectionBoxes=e.map((e=>({x:e.x*m+h,y:e.y*u+f,w:e.w*m,h:e.h*u,score:e.score})))}updateMaskColor(e){const t=this.el.shadowRoot?.querySelector(".card-outline");const i=this.el.shadowRoot?.querySelectorAll(".corner");const s=this.el.shadowRoot?.querySelector(".side-top");const a=this.el.shadowRoot?.querySelector(".side-right");const o=this.el.shadowRoot?.querySelector(".side-bottom");const r=this.el.shadowRoot?.querySelector(".side-left");let n=null;let c={top:false,right:false,bottom:false,left:false};if(e.length>0){n=e.reduce(((e,t)=>t.score>e.score?t:e));const t={INPUT_SIZE:320,ID1_ASPECT_RATIO:85.6/53.98,shouldMirrorVideo:this.shouldMirrorVideo,alignmentTolerance:this.alignmentTolerance,maskSize:this.maskSize,videoRef:this.videoRef};c=this.detectionService.checkSideAlignment(n,t);this.sideAlignment=c}else{this.sideAlignment={top:false,right:false,bottom:false,left:false}}s?.classList.toggle("aligned",c.top);a?.classList.toggle("aligned",c.right);o?.classList.toggle("aligned",c.bottom);r?.classList.toggle("aligned",c.left);const d=this.detectionService.areAllSidesAligned(c);const l=this.stateManager.getCaptureState();if(l.step==="back"&&this.enableBackDocumentTimer&&n){const e=c.top||c.right||c.bottom||c.left;if(e){this.startBackDocumentTimer()}}if(d&&n){t?.classList.add("perfect-match");i?.forEach((e=>e.classList.add("perfect-match")));this.logger.state("CAPTURE_EVALUATION",{allSidesAligned:true,hasScreenshotTaken:this.hasScreenshotTaken,captureDelay:this.captureDelay,alignmentStartTime:this.alignmentStartTime});if(!this.hasScreenshotTaken){const e=Date.now();if(!this.alignmentStartTime){this.alignmentStartTime=e;this.logger.state("ALIGNMENT_TIMER_STARTED",{startTime:e})}const t=e-this.alignmentStartTime;this.logger.state("ALIGNMENT_DURATION_CHECK",{alignmentDuration:t,captureDelay:this.captureDelay,readyToCapture:t>=this.captureDelay});if(t>=this.captureDelay){this.logger.state("TRIGGERING_CAPTURE",{alignmentDuration:t,captureDelay:this.captureDelay});this.lastDetectedBox=n;this.takeScreenshot().catch((e=>{this.logger.error("Error al tomar captura de pantalla:",e)}));this.hasScreenshotTaken=true;this.alignmentStartTime=undefined;setTimeout((()=>{this.hasScreenshotTaken=false}),2e3)}}}else{t?.classList.remove("perfect-match");i?.forEach((e=>e.classList.remove("perfect-match")));if(this.alignmentStartTime){this.alignmentStartTime=undefined}if(this.alignmentTimer){clearTimeout(this.alignmentTimer);this.alignmentTimer=undefined}}}async takeScreenshot(){if(!this.videoRef||!this.lastDetectedBox)return;this.logger.state("INICIANDO_CAPTURA",{captureStep:this.stateManager.getCaptureState().step,detectedBox:this.lastDetectedBox,videoResolution:{width:this.videoRef.videoWidth,height:this.videoRef.videoHeight}});this.stateManager.updateCaptureState({isCapturing:true});this.triggerCaptureAnimation();const e=document.createElement("canvas");e.width=this.videoRef.videoWidth;e.height=this.videoRef.videoHeight;const t=e.getContext("2d",{alpha:false});t.drawImage(this.videoRef,0,0,e.width,e.height);const i=320;const s=this.videoRef.videoWidth/i;const a=this.videoRef.videoHeight/i;const o=Math.max(0,this.lastDetectedBox.x*s-this.cropMargin);const r=Math.max(0,this.lastDetectedBox.y*a-this.cropMargin);const n=Math.min(this.lastDetectedBox.w*s+2*this.cropMargin,this.videoRef.videoWidth-o);const c=Math.min(this.lastDetectedBox.h*a+2*this.cropMargin,this.videoRef.videoHeight-r);const d=document.createElement("canvas");d.width=n;d.height=c;const l=d.getContext("2d",{alpha:false});l.drawImage(this.videoRef,o,r,n,c,0,0,n,c);const h=this.stateManager.getCaptureState();if(h.step==="front"){this.stateManager.setCapturedImages({front:{fullFrame:e.toDataURL("image/png"),cropped:d.toDataURL("image/png")}});if(this.useDocumentClassification){const e=await this.detectionService.classifyDocument(d);if(e&&e.class==="passport"){this.logger.state("PASAPORTE_DETECTADO_SALTANDO_REVERSO",{classification:e?.class});this.completeProcess(true);return}}this.stateManager.updateCaptureState({step:"back",isDetectionPaused:true,showFlipAnimation:true});setTimeout((()=>{this.stateManager.updateCaptureState({showFlipAnimation:false,isDetectionPaused:false});this.startBackDocumentTimer()}),3e3)}else if(h.step==="back"){this.stateManager.setCapturedImages({back:{fullFrame:e.toDataURL("image/png"),cropped:d.toDataURL("image/png")}});this.completeProcess(false)}}triggerCaptureAnimation(){const e=this.el.shadowRoot?.querySelector(".card-outline");e?.classList.add("capturing");setTimeout((()=>{this.stateManager.updateCaptureState({isCapturing:false});e?.classList.remove("capturing")}),600)}completeProcess(e=false){this.stateManager.updateCaptureState({step:"completed",showSuccessAnimation:true});const t=this.stateManager.getCapturedImages();t.metadata.processCompleted=true;t.metadata.backCaptureSkipped=e;this.stateManager.setCapturedImages(t);this.stopDetection();this.updateStatus("Proceso completado",`Imágenes capturadas exitosamente`,"ready");const i={...t,timestamp:(new Date).toISOString()};this.captureCompleted.emit(i);setTimeout((()=>{this.stateManager.updateCaptureState({showSuccessAnimation:false})}),3e3);this.logger.state("PROCESO_COMPLETADO",{skippedBack:e,totalImages:t.metadata.totalImages,timestamp:(new Date).toISOString()})}stopDetection(){if(this.animationId){cancelAnimationFrame(this.animationId);this.animationId=undefined}this.clearBackDocumentTimer();this.detectionBoxes=[];this.logger.state("DETECTOR_DETENIDO",{timestamp:Date.now()})}startBackDocumentTimer(){if(!this.enableBackDocumentTimer)return;if(this.backDocumentTimer){clearInterval(this.backDocumentTimer)}this.backDocumentTimerRemaining=this.backDocumentTimerDuration;this.backDocumentTimer=window.setInterval((()=>{this.backDocumentTimerRemaining--;if(this.backDocumentTimerRemaining<=0){this.clearBackDocumentTimer();this.skipBackCapture()}}),1e3)}clearBackDocumentTimer(){if(this.backDocumentTimer){clearInterval(this.backDocumentTimer);this.backDocumentTimer=undefined}this.backDocumentTimerRemaining=0}toggleCameraSelector(){if(this.isSwitchingCamera)return;this.showCameraSelector=!this.showCameraSelector}async handleCameraSwitch(e){if(this.isSwitchingCamera)return;try{this.showCameraSelector=false;this.isSwitchingCamera=true;this.logger.state("INICIANDO_CAMBIO_CAMARA",{from:this.cameraService.getSelectedCameraId(),to:e});if(this.videoStream){this.videoStream.getTracks().forEach((e=>e.stop()))}await this.cameraService.switchCamera(e);const t=await this.cameraService.setupCamera();await this.initializeVideoStream(t);this.logger.state("CAMBIO_CAMARA_EXITOSO",{newCameraId:e,isRearCamera:this.cameraService.isRearCamera(t)})}catch(e){this.logger.error("Error al cambiar cámara:",e);try{const e=await this.cameraService.setupCamera();await this.initializeVideoStream(e)}catch(e){this.logger.error("Error al restaurar cámara anterior:",e);this.updateStatus("Error al cambiar cámara","No se pudo completar el cambio de dispositivo","error")}}finally{this.isSwitchingCamera=false}}resetDetection(){const e=this.stateManager.getCaptureState();const t=e.isVideoActive;this.stateManager.reset();if(t){this.stateManager.updateCaptureState({isVideoActive:true})}this.hasScreenshotTaken=false;this.startTime=Date.now();this.frameSkipCounter=0;this.consecutiveFailures=0;this.lastInferenceTime=0;this.detectionBoxes=[];this.alignmentStartTime=undefined;this.hasDocumentDetected=false;if(this.alignmentTimer){clearTimeout(this.alignmentTimer);this.alignmentTimer=undefined}if(t&&this.detectionService.isModelLoaded()){this.updateStatus("Captura reiniciada","Buscando documento en el marco de captura","active");this.detectFrame()}else{this.updateStatus("Listo para capturar","","ready")}}exitSession(){if(this.videoStream){this.videoStream.getTracks().forEach((e=>e.stop()));this.videoStream=undefined;this.stateManager.updateCaptureState({isVideoActive:false,isLoading:false})}this.isMaskReady=false;this.updateStatus("Sesión finalizada","","ready");this.detectionBoxes=[];this.cleanup()}initializePerformanceMonitor(){this.performanceMetrics.lastUpdateTime=performance.now();this.performanceUpdateInterval=window.setInterval((()=>{this.updatePerformanceMetrics()}),500);this.logger.debug("Monitor de performance inicializado")}updatePerformanceMetrics(){const e=performance.now();const t=e-this.performanceMetrics.lastUpdateTime;if(t>0){this.performanceMetrics.fps=Math.round(1e3/(t/this.frameSkipCounter||1))}if("memory"in performance){const e=performance.memory;this.performanceMetrics.memoryUsage=Math.round(e.usedJSHeapSize/1048576)}if(this.performanceMetrics.totalDetections>0){this.performanceMetrics.successfulDetections=this.performanceMetrics.successfulDetections;const e=this.performanceMetrics.successfulDetections/this.performanceMetrics.totalDetections*100;this.performanceMetrics.detectionRate=Math.round(e)}this.performanceData={fps:this.performanceMetrics.fps,inferenceTime:this.performanceMetrics.inferenceTime,memoryUsage:this.performanceMetrics.memoryUsage,onnxLoadTime:this.performanceMetrics.onnxLoadTime,frameProcessingTime:this.performanceMetrics.frameProcessingTime,totalDetections:this.performanceMetrics.totalDetections,successfulDetections:this.performanceMetrics.successfulDetections,detectionRate:this.performanceMetrics.detectionRate};this.performanceMetrics.lastUpdateTime=e}recordOnnxPerformance(e,t){this.performanceMetrics.onnxLoadTime=Math.round(e);this.performanceMetrics.inferenceTime=Math.round(t)}recordFrameProcessing(e,t){this.performanceMetrics.frameProcessingTime=Math.round(e);this.performanceMetrics.totalDetections++;if(t>0){this.performanceMetrics.successfulDetections++}}};m.style=p;export{m as jaak_stamps};
|
|
2
|
+
//# sourceMappingURL=p-2264b5b4.entry.js.map
|