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