@jaak.ai/stamps 2.5.3 → 2.5.4-dev.2
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/{index-D6NBn_qu.js → index-ucw61xdq.js} +9 -2
- package/dist/cjs/{index-D6NBn_qu.js.map → index-ucw61xdq.js.map} +1 -1
- package/dist/cjs/jaak-stamps-webcomponent.cjs.js +1 -1
- package/dist/cjs/jaak-stamps.cjs.entry.js +295 -31
- 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/assets/powered-by-jaak.png +0 -0
- package/dist/collection/components/my-component/my-component.js +295 -13
- package/dist/collection/components/my-component/my-component.js.map +1 -1
- package/dist/collection/services/DetectionService.js +0 -18
- package/dist/collection/services/DetectionService.js.map +1 -1
- package/dist/components/jaak-stamps.js +295 -31
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/{index-BCfAsrzL.js → index-CqdAwiLj.js} +9 -3
- package/dist/esm/{index-BCfAsrzL.js.map → index-CqdAwiLj.js.map} +1 -1
- package/dist/esm/jaak-stamps-webcomponent.js +2 -2
- package/dist/esm/jaak-stamps.entry.js +295 -31
- package/dist/esm/jaak-stamps.entry.js.map +1 -1
- package/dist/esm/loader.js +2 -2
- 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-178aea65.entry.js +7 -0
- package/dist/jaak-stamps-webcomponent/p-178aea65.entry.js.map +1 -0
- package/dist/jaak-stamps-webcomponent/p-CqdAwiLj.js +3 -0
- package/dist/jaak-stamps-webcomponent/{p-BCfAsrzL.js.map → p-CqdAwiLj.js.map} +1 -1
- package/dist/types/components/my-component/my-component.d.ts +10 -0
- package/package.json +1 -1
- package/dist/jaak-stamps-webcomponent/p-BCfAsrzL.js +0 -3
- package/dist/jaak-stamps-webcomponent/p-adece4d2.entry.js +0 -7
- package/dist/jaak-stamps-webcomponent/p-adece4d2.entry.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { p as promiseResolve, b as bootstrapLazy } from './index-
|
|
2
|
-
export { s as setNonce } from './index-
|
|
1
|
+
import { p as promiseResolve, b as bootstrapLazy } from './index-CqdAwiLj.js';
|
|
2
|
+
export { s as setNonce } from './index-CqdAwiLj.js';
|
|
3
3
|
import { g as globalScripts } from './app-globals-DQuL1Twl.js';
|
|
4
4
|
|
|
5
5
|
/*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as registerInstance, c as createEvent, g as getElement, h } from './index-
|
|
1
|
+
import { r as registerInstance, c as createEvent, g as getElement, h, a as getAssetPath } from './index-CqdAwiLj.js';
|
|
2
2
|
|
|
3
3
|
class EventBusService {
|
|
4
4
|
events = new Map();
|
|
@@ -835,24 +835,12 @@ class DetectionService {
|
|
|
835
835
|
errorMsg.includes('FLOAT16') ||
|
|
836
836
|
errorMsg.includes('float16');
|
|
837
837
|
if (isFloat16Error) {
|
|
838
|
-
// El modelo fp16 no es compatible con este backend.
|
|
839
|
-
// Cargar el modelo fp32 que funciona en cualquier backend.
|
|
840
|
-
if (this.debug) {
|
|
841
|
-
console.log('[JAAK-DEBUG] float16 model not supported, loading fp32 model:', this.MODEL_PATH_FP32);
|
|
842
|
-
}
|
|
843
838
|
this.useFloat16 = false;
|
|
844
839
|
try {
|
|
845
840
|
this.session = await window.ort.InferenceSession.create(this.MODEL_PATH_FP32, sessionOptions);
|
|
846
|
-
if (this.debug) {
|
|
847
|
-
console.log('[JAAK-DEBUG] fp32 model loaded successfully');
|
|
848
|
-
}
|
|
849
841
|
}
|
|
850
842
|
catch (fp32Error) {
|
|
851
843
|
// Intentar con opciones minimas de WASM
|
|
852
|
-
if (this.debug) {
|
|
853
|
-
console.log('[JAAK-DEBUG] fp32 model failed with default options:', fp32Error.message);
|
|
854
|
-
console.log('[JAAK-DEBUG] Retrying fp32 model with WASM fallback options');
|
|
855
|
-
}
|
|
856
844
|
const wasmOptions = {
|
|
857
845
|
executionProviders: ['wasm'],
|
|
858
846
|
graphOptimizationLevel: 'all',
|
|
@@ -887,9 +875,6 @@ class DetectionService {
|
|
|
887
875
|
throw error;
|
|
888
876
|
}
|
|
889
877
|
}
|
|
890
|
-
if (this.debug) {
|
|
891
|
-
console.log('[JAAK-DEBUG] Model loaded. useFloat16:', this.useFloat16);
|
|
892
|
-
}
|
|
893
878
|
this.modelLoaded = true;
|
|
894
879
|
}
|
|
895
880
|
catch (error) {
|
|
@@ -1178,9 +1163,6 @@ class DetectionService {
|
|
|
1178
1163
|
}
|
|
1179
1164
|
catch {
|
|
1180
1165
|
this.useFloat16 = false;
|
|
1181
|
-
if (this.debug) {
|
|
1182
|
-
console.log('[JAAK-DEBUG] float16 not supported by current backend, using float32');
|
|
1183
|
-
}
|
|
1184
1166
|
}
|
|
1185
1167
|
}
|
|
1186
1168
|
float32ToFloat16(value) {
|
|
@@ -18779,6 +18761,18 @@ const JaakStamps = class {
|
|
|
18779
18761
|
processedFramesCount = 0; // Contador total de frames procesados
|
|
18780
18762
|
hasAutoSwitchedToManual = false;
|
|
18781
18763
|
_manualModeLoggedOnce = false;
|
|
18764
|
+
VIDEO_DIAGNOSTIC_EVENTS = [
|
|
18765
|
+
'loadstart',
|
|
18766
|
+
'loadedmetadata',
|
|
18767
|
+
'loadeddata',
|
|
18768
|
+
'canplay',
|
|
18769
|
+
'playing',
|
|
18770
|
+
'pause',
|
|
18771
|
+
'stalled',
|
|
18772
|
+
'suspend',
|
|
18773
|
+
'abort',
|
|
18774
|
+
'emptied',
|
|
18775
|
+
];
|
|
18782
18776
|
// Canvas pool for optimized screenshot capture
|
|
18783
18777
|
canvasPool = [];
|
|
18784
18778
|
MAX_CANVAS_POOL_SIZE = 3;
|
|
@@ -19507,6 +19501,130 @@ const JaakStamps = class {
|
|
|
19507
19501
|
memoryMB: deviceMemory ? deviceMemory * 1024 : null
|
|
19508
19502
|
};
|
|
19509
19503
|
}
|
|
19504
|
+
debugLog(message, details) {
|
|
19505
|
+
if (!this.debug) {
|
|
19506
|
+
return;
|
|
19507
|
+
}
|
|
19508
|
+
if (typeof details === 'undefined') {
|
|
19509
|
+
console.log(`[jaak-stamps][diag] ${message}`);
|
|
19510
|
+
return;
|
|
19511
|
+
}
|
|
19512
|
+
console.log(`[jaak-stamps][diag] ${message}`, details);
|
|
19513
|
+
}
|
|
19514
|
+
debugWarn(message, details) {
|
|
19515
|
+
if (!this.debug) {
|
|
19516
|
+
return;
|
|
19517
|
+
}
|
|
19518
|
+
if (typeof details === 'undefined') {
|
|
19519
|
+
console.warn(`[jaak-stamps][diag] ${message}`);
|
|
19520
|
+
return;
|
|
19521
|
+
}
|
|
19522
|
+
console.warn(`[jaak-stamps][diag] ${message}`, details);
|
|
19523
|
+
}
|
|
19524
|
+
summarizeId(id) {
|
|
19525
|
+
if (!id) {
|
|
19526
|
+
return null;
|
|
19527
|
+
}
|
|
19528
|
+
return id.length <= 8 ? id : `${id.slice(0, 8)}...`;
|
|
19529
|
+
}
|
|
19530
|
+
getCameraDevicesSnapshot() {
|
|
19531
|
+
return this.cameraService.getAvailableCameras().map(camera => ({
|
|
19532
|
+
label: camera.label || '(sin label)',
|
|
19533
|
+
deviceId: this.summarizeId(camera.deviceId),
|
|
19534
|
+
groupId: this.summarizeId(camera.groupId),
|
|
19535
|
+
kind: camera.kind,
|
|
19536
|
+
}));
|
|
19537
|
+
}
|
|
19538
|
+
sanitizeTrackSettings(settings) {
|
|
19539
|
+
if (!settings) {
|
|
19540
|
+
return null;
|
|
19541
|
+
}
|
|
19542
|
+
return {
|
|
19543
|
+
...settings,
|
|
19544
|
+
deviceId: this.summarizeId(settings.deviceId),
|
|
19545
|
+
groupId: this.summarizeId(settings.groupId),
|
|
19546
|
+
};
|
|
19547
|
+
}
|
|
19548
|
+
sanitizeTrackConstraints(track) {
|
|
19549
|
+
if (!track) {
|
|
19550
|
+
return null;
|
|
19551
|
+
}
|
|
19552
|
+
const constraints = track.getConstraints ? track.getConstraints() : {};
|
|
19553
|
+
const sanitizedConstraints = { ...constraints };
|
|
19554
|
+
if (typeof sanitizedConstraints.deviceId === 'string') {
|
|
19555
|
+
sanitizedConstraints.deviceId = this.summarizeId(sanitizedConstraints.deviceId);
|
|
19556
|
+
}
|
|
19557
|
+
return sanitizedConstraints;
|
|
19558
|
+
}
|
|
19559
|
+
getStreamSnapshot(stream) {
|
|
19560
|
+
if (!stream) {
|
|
19561
|
+
return { hasStream: false };
|
|
19562
|
+
}
|
|
19563
|
+
const videoTrack = stream.getVideoTracks()[0];
|
|
19564
|
+
if (!videoTrack) {
|
|
19565
|
+
return {
|
|
19566
|
+
hasStream: true,
|
|
19567
|
+
streamActive: stream.active,
|
|
19568
|
+
trackCount: stream.getTracks().length,
|
|
19569
|
+
hasVideoTrack: false,
|
|
19570
|
+
};
|
|
19571
|
+
}
|
|
19572
|
+
return {
|
|
19573
|
+
hasStream: true,
|
|
19574
|
+
streamActive: stream.active,
|
|
19575
|
+
trackCount: stream.getTracks().length,
|
|
19576
|
+
trackLabel: videoTrack.label || '(sin label)',
|
|
19577
|
+
trackEnabled: videoTrack.enabled,
|
|
19578
|
+
trackMuted: videoTrack.muted,
|
|
19579
|
+
trackReadyState: videoTrack.readyState,
|
|
19580
|
+
settings: this.sanitizeTrackSettings(videoTrack.getSettings ? videoTrack.getSettings() : undefined),
|
|
19581
|
+
constraints: this.sanitizeTrackConstraints(videoTrack),
|
|
19582
|
+
};
|
|
19583
|
+
}
|
|
19584
|
+
getVideoElementSnapshot() {
|
|
19585
|
+
if (!this.videoRef) {
|
|
19586
|
+
return { hasVideoRef: false };
|
|
19587
|
+
}
|
|
19588
|
+
const computedStyle = this.el.ownerDocument?.defaultView?.getComputedStyle(this.videoRef);
|
|
19589
|
+
return {
|
|
19590
|
+
hasVideoRef: true,
|
|
19591
|
+
isConnected: this.videoRef.isConnected,
|
|
19592
|
+
readyState: this.videoRef.readyState,
|
|
19593
|
+
networkState: this.videoRef.networkState,
|
|
19594
|
+
paused: this.videoRef.paused,
|
|
19595
|
+
muted: this.videoRef.muted,
|
|
19596
|
+
autoplay: this.videoRef.autoplay,
|
|
19597
|
+
playsInline: this.videoRef.playsInline,
|
|
19598
|
+
currentTime: Number.isFinite(this.videoRef.currentTime)
|
|
19599
|
+
? Number(this.videoRef.currentTime.toFixed(3))
|
|
19600
|
+
: this.videoRef.currentTime,
|
|
19601
|
+
videoWidth: this.videoRef.videoWidth,
|
|
19602
|
+
videoHeight: this.videoRef.videoHeight,
|
|
19603
|
+
clientWidth: this.videoRef.clientWidth,
|
|
19604
|
+
clientHeight: this.videoRef.clientHeight,
|
|
19605
|
+
hasSrcObject: !!this.videoRef.srcObject,
|
|
19606
|
+
display: computedStyle?.display ?? 'unknown',
|
|
19607
|
+
visibility: computedStyle?.visibility ?? 'unknown',
|
|
19608
|
+
};
|
|
19609
|
+
}
|
|
19610
|
+
attachVideoDiagnosticListeners() {
|
|
19611
|
+
if (!this.debug || !this.videoRef) {
|
|
19612
|
+
return () => undefined;
|
|
19613
|
+
}
|
|
19614
|
+
const video = this.videoRef;
|
|
19615
|
+
const listeners = this.VIDEO_DIAGNOSTIC_EVENTS.map(eventName => {
|
|
19616
|
+
const handler = () => {
|
|
19617
|
+
this.debugLog(`video event "${eventName}"`, this.getVideoElementSnapshot());
|
|
19618
|
+
};
|
|
19619
|
+
video.addEventListener(eventName, handler);
|
|
19620
|
+
return { eventName, handler };
|
|
19621
|
+
});
|
|
19622
|
+
return () => {
|
|
19623
|
+
listeners.forEach(({ eventName, handler }) => {
|
|
19624
|
+
video.removeEventListener(eventName, handler);
|
|
19625
|
+
});
|
|
19626
|
+
};
|
|
19627
|
+
}
|
|
19510
19628
|
// DETECTION METHODS
|
|
19511
19629
|
async startDetection() {
|
|
19512
19630
|
try {
|
|
@@ -19593,12 +19711,19 @@ const JaakStamps = class {
|
|
|
19593
19711
|
this.updateStatus('Configurando cámara...', 'Buscando dispositivos disponibles', 'loading');
|
|
19594
19712
|
try {
|
|
19595
19713
|
await this.cameraService.enumerateDevices();
|
|
19714
|
+
this.debugLog('step 2/5 enumerateDevices()', {
|
|
19715
|
+
cameras: this.getCameraDevicesSnapshot(),
|
|
19716
|
+
selectedCameraId: this.summarizeId(this.cameraService.getSelectedCameraId() || undefined),
|
|
19717
|
+
});
|
|
19596
19718
|
}
|
|
19597
19719
|
catch (enumerateError) {
|
|
19598
19720
|
throw new Error(`Error al enumerar dispositivos: ${enumerateError.message}`);
|
|
19599
19721
|
}
|
|
19600
19722
|
try {
|
|
19601
19723
|
await this.updateCameraInfoWithAutofocus();
|
|
19724
|
+
this.debugLog('step 2/5 updateCameraInfoWithAutofocus()', {
|
|
19725
|
+
cameraInfo: this.cameraInfoWithAutofocus,
|
|
19726
|
+
});
|
|
19602
19727
|
}
|
|
19603
19728
|
catch (cameraInfoError) {
|
|
19604
19729
|
throw new Error(`Error al actualizar información de cámara: ${cameraInfoError.message}`);
|
|
@@ -19608,6 +19733,10 @@ const JaakStamps = class {
|
|
|
19608
19733
|
let stream;
|
|
19609
19734
|
try {
|
|
19610
19735
|
stream = await this.cameraService.setupCamera();
|
|
19736
|
+
this.debugLog('step 3/5 setupCamera() resolved', {
|
|
19737
|
+
stream: this.getStreamSnapshot(stream),
|
|
19738
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19739
|
+
});
|
|
19611
19740
|
}
|
|
19612
19741
|
catch (setupError) {
|
|
19613
19742
|
throw new Error(`Error al configurar cámara: ${setupError.message}`);
|
|
@@ -19620,7 +19749,15 @@ const JaakStamps = class {
|
|
|
19620
19749
|
this.updateStatus('Captura activa', 'Posicione su documento y use el botón para capturar', 'active');
|
|
19621
19750
|
}
|
|
19622
19751
|
try {
|
|
19752
|
+
this.debugLog('step 4/5 initializeVideoStream() start', {
|
|
19753
|
+
stream: this.getStreamSnapshot(stream),
|
|
19754
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19755
|
+
});
|
|
19623
19756
|
await this.initializeVideoStream(stream);
|
|
19757
|
+
this.debugLog('step 4/5 initializeVideoStream() completed', {
|
|
19758
|
+
stream: this.getStreamSnapshot(stream),
|
|
19759
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19760
|
+
});
|
|
19624
19761
|
}
|
|
19625
19762
|
catch (videoError) {
|
|
19626
19763
|
throw new Error(`Error al inicializar video: ${videoError.message}`);
|
|
@@ -19638,9 +19775,19 @@ const JaakStamps = class {
|
|
|
19638
19775
|
if (!this.useDocumentDetector) {
|
|
19639
19776
|
this.showManualCaptureButton = true;
|
|
19640
19777
|
}
|
|
19778
|
+
this.debugLog('step 5/5 capture loop ready', {
|
|
19779
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19780
|
+
stream: this.getStreamSnapshot(this.videoStream),
|
|
19781
|
+
useDocumentDetector: this.useDocumentDetector,
|
|
19782
|
+
});
|
|
19641
19783
|
this.detectFrame();
|
|
19642
19784
|
}
|
|
19643
19785
|
catch (err) {
|
|
19786
|
+
this.debugWarn('startDetection() failed', {
|
|
19787
|
+
error: err instanceof Error ? err.message : String(err),
|
|
19788
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19789
|
+
stream: this.getStreamSnapshot(this.videoStream),
|
|
19790
|
+
});
|
|
19644
19791
|
console.error('[jaak-stamps] Error al preparar captura:', err);
|
|
19645
19792
|
this.updateStatus('Error al iniciar', 'No se pudo preparar la captura', 'error');
|
|
19646
19793
|
this.stateManager.updateCaptureState({ isLoading: false });
|
|
@@ -19650,11 +19797,93 @@ const JaakStamps = class {
|
|
|
19650
19797
|
if (!this.videoRef) {
|
|
19651
19798
|
throw new Error('Video element not available');
|
|
19652
19799
|
}
|
|
19800
|
+
const detachVideoDiagnosticListeners = this.attachVideoDiagnosticListeners();
|
|
19801
|
+
this.debugLog('initializeVideoStream() pre-assign', {
|
|
19802
|
+
stream: this.getStreamSnapshot(stream),
|
|
19803
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19804
|
+
});
|
|
19653
19805
|
this.videoRef.srcObject = stream;
|
|
19654
19806
|
this.videoStream = stream;
|
|
19807
|
+
this.debugLog('initializeVideoStream() post-srcObject assignment', {
|
|
19808
|
+
stream: this.getStreamSnapshot(stream),
|
|
19809
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19810
|
+
});
|
|
19655
19811
|
const isRear = this.cameraService.isRearCamera(stream);
|
|
19656
19812
|
this.shouldMirrorVideo = !isRear;
|
|
19657
19813
|
const LOAD_METADATA_TIMEOUT_MS = 10000;
|
|
19814
|
+
// Diagnostic instrumentation: when the timeout fires we need enough
|
|
19815
|
+
// context to distinguish between "OS muted the track", "permission
|
|
19816
|
+
// revoked mid-flight", "device never produced frames" and other modes
|
|
19817
|
+
// that all surface as the same generic timeout error.
|
|
19818
|
+
const track = stream.getVideoTracks()[0];
|
|
19819
|
+
const waitStart = performance.now();
|
|
19820
|
+
const trackEvents = [];
|
|
19821
|
+
const recordTrackEvent = (event) => {
|
|
19822
|
+
trackEvents.push({
|
|
19823
|
+
at: Math.round(performance.now() - waitStart),
|
|
19824
|
+
event,
|
|
19825
|
+
state: track?.readyState,
|
|
19826
|
+
});
|
|
19827
|
+
};
|
|
19828
|
+
const onTrackMute = () => recordTrackEvent('mute');
|
|
19829
|
+
const onTrackUnmute = () => recordTrackEvent('unmute');
|
|
19830
|
+
const onTrackEnded = () => recordTrackEvent('ended');
|
|
19831
|
+
if (track) {
|
|
19832
|
+
track.addEventListener('mute', onTrackMute);
|
|
19833
|
+
track.addEventListener('unmute', onTrackUnmute);
|
|
19834
|
+
track.addEventListener('ended', onTrackEnded);
|
|
19835
|
+
}
|
|
19836
|
+
const cleanupTrackListeners = () => {
|
|
19837
|
+
if (!track)
|
|
19838
|
+
return;
|
|
19839
|
+
track.removeEventListener('mute', onTrackMute);
|
|
19840
|
+
track.removeEventListener('unmute', onTrackUnmute);
|
|
19841
|
+
track.removeEventListener('ended', onTrackEnded);
|
|
19842
|
+
};
|
|
19843
|
+
const captureDiagnostics = () => {
|
|
19844
|
+
const settings = track?.getSettings?.();
|
|
19845
|
+
const computed = this.videoRef ? getComputedStyle(this.videoRef) : null;
|
|
19846
|
+
return {
|
|
19847
|
+
reason: 'VIDEO_METADATA_TIMEOUT',
|
|
19848
|
+
waitedMs: Math.round(performance.now() - waitStart),
|
|
19849
|
+
stream: {
|
|
19850
|
+
videoTrackCount: stream.getVideoTracks().length,
|
|
19851
|
+
audioTrackCount: stream.getAudioTracks().length,
|
|
19852
|
+
},
|
|
19853
|
+
track: track ? {
|
|
19854
|
+
readyState: track.readyState,
|
|
19855
|
+
muted: track.muted,
|
|
19856
|
+
enabled: track.enabled,
|
|
19857
|
+
label: track.label,
|
|
19858
|
+
kind: track.kind,
|
|
19859
|
+
settings: settings ? {
|
|
19860
|
+
width: settings.width,
|
|
19861
|
+
height: settings.height,
|
|
19862
|
+
frameRate: settings.frameRate,
|
|
19863
|
+
deviceId: settings.deviceId,
|
|
19864
|
+
facingMode: settings.facingMode,
|
|
19865
|
+
} : null,
|
|
19866
|
+
} : null,
|
|
19867
|
+
video: this.videoRef ? {
|
|
19868
|
+
readyState: this.videoRef.readyState,
|
|
19869
|
+
networkState: this.videoRef.networkState,
|
|
19870
|
+
error: this.videoRef.error ? { code: this.videoRef.error.code, message: this.videoRef.error.message } : null,
|
|
19871
|
+
paused: this.videoRef.paused,
|
|
19872
|
+
offsetWidth: this.videoRef.offsetWidth,
|
|
19873
|
+
offsetHeight: this.videoRef.offsetHeight,
|
|
19874
|
+
videoWidth: this.videoRef.videoWidth,
|
|
19875
|
+
videoHeight: this.videoRef.videoHeight,
|
|
19876
|
+
display: computed?.display,
|
|
19877
|
+
visibility: computed?.visibility,
|
|
19878
|
+
} : null,
|
|
19879
|
+
document: {
|
|
19880
|
+
visibilityState: document.visibilityState,
|
|
19881
|
+
hasFocus: document.hasFocus(),
|
|
19882
|
+
},
|
|
19883
|
+
trackEvents,
|
|
19884
|
+
userAgent: navigator.userAgent,
|
|
19885
|
+
};
|
|
19886
|
+
};
|
|
19658
19887
|
const finalizeStreamInitialization = async () => {
|
|
19659
19888
|
try {
|
|
19660
19889
|
await this.videoRef.play();
|
|
@@ -19669,24 +19898,39 @@ const JaakStamps = class {
|
|
|
19669
19898
|
const rect = container.getBoundingClientRect();
|
|
19670
19899
|
this.updateMaskDimensions(rect);
|
|
19671
19900
|
}
|
|
19901
|
+
this.debugLog('initializeVideoStream() finalized after play()', {
|
|
19902
|
+
stream: this.getStreamSnapshot(stream),
|
|
19903
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19904
|
+
});
|
|
19672
19905
|
};
|
|
19673
19906
|
// If metadata is already available (readyState >= HAVE_METADATA = 1),
|
|
19674
19907
|
// the 'loadedmetadata' event will not fire again. Handle both cases.
|
|
19675
19908
|
if (this.videoRef.readyState >= 1) {
|
|
19676
|
-
|
|
19677
|
-
|
|
19678
|
-
}
|
|
19909
|
+
this.debugLog('video metadata already available, skipping event wait', this.getVideoElementSnapshot());
|
|
19910
|
+
cleanupTrackListeners();
|
|
19679
19911
|
await finalizeStreamInitialization();
|
|
19912
|
+
detachVideoDiagnosticListeners();
|
|
19680
19913
|
return;
|
|
19681
19914
|
}
|
|
19682
19915
|
return new Promise((resolve, reject) => {
|
|
19683
19916
|
let settled = false;
|
|
19917
|
+
const cleanup = () => {
|
|
19918
|
+
this.videoRef.onloadedmetadata = null;
|
|
19919
|
+
this.videoRef.onerror = null;
|
|
19920
|
+
detachVideoDiagnosticListeners();
|
|
19921
|
+
};
|
|
19684
19922
|
const timeoutId = setTimeout(() => {
|
|
19685
19923
|
if (settled)
|
|
19686
19924
|
return;
|
|
19687
19925
|
settled = true;
|
|
19688
|
-
|
|
19689
|
-
this.
|
|
19926
|
+
const diagnostics = captureDiagnostics();
|
|
19927
|
+
this.debugWarn(`initializeVideoStream() timeout after ${LOAD_METADATA_TIMEOUT_MS}ms`, {
|
|
19928
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19929
|
+
stream: this.getStreamSnapshot(stream),
|
|
19930
|
+
});
|
|
19931
|
+
console.error('[jaak-stamps] Video metadata timeout diagnostics (json):', JSON.stringify(diagnostics));
|
|
19932
|
+
cleanup();
|
|
19933
|
+
cleanupTrackListeners();
|
|
19690
19934
|
reject(new Error(`Video metadata load timeout after ${LOAD_METADATA_TIMEOUT_MS}ms`));
|
|
19691
19935
|
}, LOAD_METADATA_TIMEOUT_MS);
|
|
19692
19936
|
this.videoRef.onloadedmetadata = async () => {
|
|
@@ -19694,13 +19938,18 @@ const JaakStamps = class {
|
|
|
19694
19938
|
return;
|
|
19695
19939
|
settled = true;
|
|
19696
19940
|
clearTimeout(timeoutId);
|
|
19697
|
-
this.
|
|
19698
|
-
|
|
19941
|
+
this.debugLog('initializeVideoStream() onloadedmetadata fired', {
|
|
19942
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19943
|
+
stream: this.getStreamSnapshot(stream),
|
|
19944
|
+
});
|
|
19945
|
+
cleanupTrackListeners();
|
|
19699
19946
|
try {
|
|
19700
19947
|
await finalizeStreamInitialization();
|
|
19948
|
+
cleanup();
|
|
19701
19949
|
resolve();
|
|
19702
19950
|
}
|
|
19703
19951
|
catch (err) {
|
|
19952
|
+
cleanup();
|
|
19704
19953
|
reject(err);
|
|
19705
19954
|
}
|
|
19706
19955
|
};
|
|
@@ -19709,8 +19958,13 @@ const JaakStamps = class {
|
|
|
19709
19958
|
return;
|
|
19710
19959
|
settled = true;
|
|
19711
19960
|
clearTimeout(timeoutId);
|
|
19712
|
-
this.
|
|
19713
|
-
|
|
19961
|
+
this.debugWarn('initializeVideoStream() video element emitted error', {
|
|
19962
|
+
event,
|
|
19963
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19964
|
+
stream: this.getStreamSnapshot(stream),
|
|
19965
|
+
});
|
|
19966
|
+
cleanup();
|
|
19967
|
+
cleanupTrackListeners();
|
|
19714
19968
|
reject(new Error(`Video element error: ${event}`));
|
|
19715
19969
|
};
|
|
19716
19970
|
});
|
|
@@ -19935,7 +20189,16 @@ const JaakStamps = class {
|
|
|
19935
20189
|
isCapturing: false
|
|
19936
20190
|
};
|
|
19937
20191
|
const cameraInfo = this.cameraInfoWithAutofocus;
|
|
19938
|
-
return (h("div", { key: '
|
|
20192
|
+
return (h("div", { key: '20689d87a0b2f3ec851837a57f97b4bb79ecf10a', class: "detector-container" }, !this.licenseValid && this.licenseError && (h("div", { key: '3dccc3f6fd3ed0db2c2e7034d5cb0940625bade1', class: "license-error-container" }, h("div", { key: '5f39d0762dc5fea0f5d5402cd61f696090e96865', class: "license-error-card" }, h("svg", { key: '34d8290684decfe194328eba1b4af1b582f02518', class: "license-error-icon", width: "64", height: "64", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("path", { key: '2cc8b54522b550f127c1b05a6f8069b78156f84a', d: "M12 22C12 22 20 18 20 12V5L12 2L4 5V12C4 18 12 22 12 22Z", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { key: 'b3c7918292661cfc92fbc0d3ec237acb80364fa5', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), h("circle", { key: '86a258f69cdf26588436cba2056bdf7c92d08244', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), h("h2", { key: '06e4fbde528663e485ae9a3b04945e6c95595ab2', class: "license-error-title" }, "Licencia Requerida"), h("p", { key: '7466b075c8cf31d67535512e4bdaa1473e89ed47', class: "license-error-message" }, this.licenseError), h("p", { key: 'ba4d06029ef7e896e51ad5c6e2dd72a9a162ef08', class: "license-error-help" }, "Contacte a soporte: ", h("a", { key: '177832433d66cf581743d8774a055405fa1f83fc', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), h("div", { key: 'ce1b33ae5289689c3e07cbb2a68f4411aa3ed2d2', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (h("div", { key: '394ee2b3c487c9673c1df3b483900720beb42ea5', class: "video-container" }, h("video", { key: '50ba3fb80f05ed35bdc58f9d75538d083cd7af32', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: {
|
|
20193
|
+
// Keep the element rendered (display: block) so the browser
|
|
20194
|
+
// loads stream metadata and fires 'loadedmetadata'. Hiding it
|
|
20195
|
+
// with display:none prevents metadata loading in Chrome and
|
|
20196
|
+
// causes initializeVideoStream to hang waiting for the event.
|
|
20197
|
+
// Use opacity + visibility to hide visually while keeping the
|
|
20198
|
+
// render context alive.
|
|
20199
|
+
opacity: captureState.isVideoActive ? '1' : '0',
|
|
20200
|
+
visibility: captureState.isVideoActive ? 'visible' : 'hidden',
|
|
20201
|
+
} }), h("div", { key: 'a4ff51674115afeeb2c36aedbbbdf3769bf0af96', ref: el => this.detectionContainer = el, class: `detection-overlay ${this.shouldMirrorVideo ? 'mirror' : ''}` }, this.debug && this.detectionBoxes.map((box, index) => (h("div", { key: index, class: "detection-box", style: {
|
|
19939
20202
|
position: 'absolute',
|
|
19940
20203
|
left: `${box.x}px`,
|
|
19941
20204
|
top: `${box.y}px`,
|
|
@@ -19944,9 +20207,9 @@ const JaakStamps = class {
|
|
|
19944
20207
|
border: '2px solid #32406C',
|
|
19945
20208
|
pointerEvents: 'none',
|
|
19946
20209
|
boxSizing: 'border-box'
|
|
19947
|
-
} })))), this.isMaskReady && (h("div", { key: '
|
|
20210
|
+
} })))), this.isMaskReady && (h("div", { key: '6c4e710e25971692bd933486f05a231b56150e5a', class: "overlay-mask" }, h("div", { key: 'd7ec408535cd68a5a9c12e51061f3fd61745b566', class: "card-outline" }, h("div", { key: '0e4c6066cf35cdb13843e54500db8e94603203fa', class: "side side-top" }), h("div", { key: '0c61ebf0940a01b09d509675d021051ac433ba1b', class: "side side-right" }), h("div", { key: 'e1c113fa666ba1ab0b77bac98ac4b08d99bea3af', class: "side side-bottom" }), h("div", { key: '666527c49665fe1d9d04a5d3620686b7471b8d44', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '71eae3c5e89eeaffd95bc32d7ed9139a5b741cc6', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: 'b4d6abc22c58eabd5afb6f440701f5b909bf949e', class: "back-capture-section" }, h("div", { key: '6d4bf99ff92829efb64d6dbc7d2d14c16b7c691c', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (h("button", { key: 'f8965079e936e32722b5eb1f8dfb63a84160aa5d', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (h("span", { key: '7defab9f244899e188659fd07bf114897737bd48', class: "button-spinner" })), "Capturar Reverso")), h("button", { key: 'd5a501876ce24f25d21df5e8d47183e80be602f3', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (h("span", { key: '54e08bed19e50abdd5f5faf9e0a21d8c2cb6a368', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
|
|
19948
20211
|
? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
|
|
19949
|
-
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '
|
|
20212
|
+
: 'Saltar reverso')))), captureState.isVideoActive && (h("div", { key: '85998cae72d19792d41f94b3fa08fd7054e25c5e', class: "camera-controls" }, h("button", { key: 'fe0471dad8bdc5b45327da52af8b47f94fe2531a', class: `camera-selector-button ${this.isSwitchingCamera ? 'loading' : ''}`, onClick: () => this.toggleCameraSelector(), type: "button", title: "Seleccionar c\u00E1mara", disabled: this.isSwitchingCamera }, this.isSwitchingCamera ? (h("div", { class: "button-spinner" })) : ('Cámaras')))), this.showCameraSelector && cameraInfo.availableCameras.length > 0 && (h("div", { key: 'de26a8eda76aeec8e7095f793750b2336e2ff6c6', class: "camera-selector-dropdown" }, h("div", { key: '9b4085d7be39ab227a33d02b55dd46e96a68d330', class: "camera-selector-header" }, h("span", { key: '84104fb85d91ccd258c78365cad2e66b62d787b0' }, "Seleccionar C\u00E1mara"), h("button", { key: 'ad1d2b52e64ab8f0028e2cb083f495c2b432c054', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), h("div", { key: 'e9f56e92ed01afac36ad0986dc78bfc816e60520', class: "camera-list" }, cameraInfo.availableCameras.map((camera) => (h("button", { key: camera.id, class: `camera-option ${cameraInfo.selectedCameraId === camera.id ? 'selected' : ''}`, onClick: () => this.handleCameraSwitch(camera.id), type: "button" }, h("span", { class: "camera-label" }, camera.label || `Cámara ${cameraInfo.availableCameras.indexOf(camera) + 1}`, camera.hasAutofocus && (h("span", { class: "autofocus-icon", title: "Autofoco disponible" }, "\u29BF"))), cameraInfo.selectedCameraId === camera.id && (h("span", { class: "selected-indicator" }, "\u2713")))))), h("div", { key: '6fa215b5f99d33272cd96a27b2295c95113bc257', class: "device-info" }, h("small", { key: 'f8399e02a4f2a288c09df9065e138ab8def9be5f' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (h("div", { key: '4a169ae520fd5ca67716f0fe190889ace448044e', class: "manual-capture-section" }, h("button", { key: '7d7808f0d1017f6eb4c701a8582152905a228e85', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (h("span", { key: '89ee5a34898a8ba78777177001fa4406531dac3e', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (h("div", { key: '0711e1cb5619acbade20f63f6d46bdfdf827ed12', class: "capture-animation" })), captureState.showFlipAnimation && (h("div", { key: '720c0b1dcdb85646b4973ae15abeaef0f3a91a95', class: "flip-animation" }, h("div", { key: 'a31a9500ee6f2f35f762e2f5135219ed869c6188', class: "id-card-icon" }), h("div", { key: '7237f4284d4a5b8fb471d8a568a9c3dd2eae6409', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (h("div", { key: '94a28257187330f5aaca2302840300460f288f71', class: "success-animation" }, h("div", { key: 'ef9d9072507faac3ae29c31b87c9439f67576c14', class: "check-icon" }), h("div", { key: '7f1c077a2b3b67ebba5d12c9b69ff943b74936e9', class: "success-text" }, "\u00A1Proceso completado!"))), h("div", { key: 'b9cae83d9d9717728a27bd969293fe28702befe3', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (h("div", { key: '59382426b18de9f04dcfb179acd9a49b68af45ed', class: "status-spinner" })), h("div", { key: 'baa1972a55d439a95b3f91f38f91d9f35eecd7bd', class: "status-content" }, h("div", { key: '3fac24107d04a2b0abcbe6a3a0bff6d395c096b6', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (h("div", { key: '196c12a4fc3e8f213b17bdd366da9e61c594a0b1', class: "status-description" }, this.currentStatus.description)))), this.debug && (h("div", { key: 'd5c36522d3bd46f434b19e8323a30f441d69c67c', class: "performance-monitor" }, h("div", { key: 'ccc8ae6b27be8d5d89e2722319cfc66a92c3a32f', class: "performance-expanded" }, h("div", { key: 'd7bed7384567663fafe4fa49dd24da4bdd05c9a3', class: "metrics-row" }, h("div", { key: 'a4409744d7d9e8a6288caf077ba5ebdc6aaa5371', class: "metric-compact" }, h("span", { key: '939e03d6aa0138c2b0c1cce16bebf158b9b74bd6', class: "metric-label" }, "FPS"), h("span", { key: '76c20f96b11725d41493b627e7a6b0fb0d594d60', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), h("div", { key: 'fafe6b165149f1f590a0b7e26b4001b09a5c70c5', class: "metric-compact" }, h("span", { key: 'a7e99f9c05aced0cb951297ce3a6011500445421', class: "metric-label" }, "MEM"), h("span", { key: '68bd733671a9664c4533e0b24b04ad0422053f77', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), h("div", { key: 'a53f1ac37527de249425529aff022858c8d924c5', class: "metrics-row" }, h("div", { key: '2213e3646b22056999d29107bb32e43c61dd202f', class: "metric-compact" }, h("span", { key: '31d84002498094f88f71858a91828f42b7157d23', class: "metric-label" }, "INF"), h("span", { key: 'f0ed4e90a338a05bd5193992e7f004df9d31239a', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), h("div", { key: '1288cf2f5a119f146886c08f8b7f036425ead78e', class: "metric-compact" }, h("span", { key: 'db75cca343f7c6ea588e9b62da04fc5d444604a6', class: "metric-label" }, "FRAME"), h("span", { key: '40aee793f30a9cf175be6372981ce7b7be82ed07', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), h("div", { key: 'd193a9b4c56c6a712213a779dbc6ee161b82e828', class: "metrics-row" }, h("div", { key: '89d060083973e1931232aac0d0c0f813b8aab7ef', class: "metric-compact" }, h("span", { key: '35808d7a448e3f4c6dc27b2b325adf628b9aee16', class: "metric-label" }, "DET"), h("span", { key: 'b60da4f5a4d56e738a65fd0bc480626d4839a048', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), h("div", { key: 'da779be083f58be8e914d062379b565fdbf7333d', class: "metric-compact" }, h("span", { key: '44645db15818eab212bc5b966213dda67f461d14', class: "metric-label" }, "RATE"), h("span", { key: '39209bdf5a5fa7c74718492218ff4fa404e94879', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), h("div", { key: 'bb0fb66ffefa86eb6e4b72215acb930c81cb6b01', class: "watermark" }, h("img", { key: '93a1812ab9a1c91c4a81cdc939ef8410170dd6b9', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak", onError: (e) => { e.target.src = getAssetPath('/assets/powered-by-jaak.png'); } }))))));
|
|
19950
20213
|
}
|
|
19951
20214
|
// Utility methods
|
|
19952
20215
|
updateDetectionBoxes(boxes) {
|
|
@@ -20762,6 +21025,7 @@ const JaakStamps = class {
|
|
|
20762
21025
|
}
|
|
20763
21026
|
// If pool is full, let the canvas be garbage collected
|
|
20764
21027
|
}
|
|
21028
|
+
static get assetsDirs() { return ["../../assets"]; }
|
|
20765
21029
|
};
|
|
20766
21030
|
JaakStamps.style = myComponentCss;
|
|
20767
21031
|
|