@jaak.ai/stamps 2.5.3 → 2.5.4-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/jaak-stamps.cjs.entry.js +293 -12
- package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
- package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
- package/dist/collection/components/my-component/my-component.js +293 -12
- package/dist/collection/components/my-component/my-component.js.map +1 -1
- package/dist/components/jaak-stamps.js +293 -12
- package/dist/components/jaak-stamps.js.map +1 -1
- package/dist/esm/jaak-stamps.entry.js +293 -12
- package/dist/esm/jaak-stamps.entry.js.map +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-adece4d2.entry.js → p-0f4d77b3.entry.js} +3 -3
- package/dist/jaak-stamps-webcomponent/p-0f4d77b3.entry.js.map +1 -0
- package/dist/types/components/my-component/my-component.d.ts +10 -0
- package/package.json +1 -1
- package/dist/jaak-stamps-webcomponent/p-adece4d2.entry.js.map +0 -1
|
@@ -18781,6 +18781,18 @@ const JaakStamps = class {
|
|
|
18781
18781
|
processedFramesCount = 0; // Contador total de frames procesados
|
|
18782
18782
|
hasAutoSwitchedToManual = false;
|
|
18783
18783
|
_manualModeLoggedOnce = false;
|
|
18784
|
+
VIDEO_DIAGNOSTIC_EVENTS = [
|
|
18785
|
+
'loadstart',
|
|
18786
|
+
'loadedmetadata',
|
|
18787
|
+
'loadeddata',
|
|
18788
|
+
'canplay',
|
|
18789
|
+
'playing',
|
|
18790
|
+
'pause',
|
|
18791
|
+
'stalled',
|
|
18792
|
+
'suspend',
|
|
18793
|
+
'abort',
|
|
18794
|
+
'emptied',
|
|
18795
|
+
];
|
|
18784
18796
|
// Canvas pool for optimized screenshot capture
|
|
18785
18797
|
canvasPool = [];
|
|
18786
18798
|
MAX_CANVAS_POOL_SIZE = 3;
|
|
@@ -19509,6 +19521,130 @@ const JaakStamps = class {
|
|
|
19509
19521
|
memoryMB: deviceMemory ? deviceMemory * 1024 : null
|
|
19510
19522
|
};
|
|
19511
19523
|
}
|
|
19524
|
+
debugLog(message, details) {
|
|
19525
|
+
if (!this.debug) {
|
|
19526
|
+
return;
|
|
19527
|
+
}
|
|
19528
|
+
if (typeof details === 'undefined') {
|
|
19529
|
+
console.log(`[jaak-stamps][diag] ${message}`);
|
|
19530
|
+
return;
|
|
19531
|
+
}
|
|
19532
|
+
console.log(`[jaak-stamps][diag] ${message}`, details);
|
|
19533
|
+
}
|
|
19534
|
+
debugWarn(message, details) {
|
|
19535
|
+
if (!this.debug) {
|
|
19536
|
+
return;
|
|
19537
|
+
}
|
|
19538
|
+
if (typeof details === 'undefined') {
|
|
19539
|
+
console.warn(`[jaak-stamps][diag] ${message}`);
|
|
19540
|
+
return;
|
|
19541
|
+
}
|
|
19542
|
+
console.warn(`[jaak-stamps][diag] ${message}`, details);
|
|
19543
|
+
}
|
|
19544
|
+
summarizeId(id) {
|
|
19545
|
+
if (!id) {
|
|
19546
|
+
return null;
|
|
19547
|
+
}
|
|
19548
|
+
return id.length <= 8 ? id : `${id.slice(0, 8)}...`;
|
|
19549
|
+
}
|
|
19550
|
+
getCameraDevicesSnapshot() {
|
|
19551
|
+
return this.cameraService.getAvailableCameras().map(camera => ({
|
|
19552
|
+
label: camera.label || '(sin label)',
|
|
19553
|
+
deviceId: this.summarizeId(camera.deviceId),
|
|
19554
|
+
groupId: this.summarizeId(camera.groupId),
|
|
19555
|
+
kind: camera.kind,
|
|
19556
|
+
}));
|
|
19557
|
+
}
|
|
19558
|
+
sanitizeTrackSettings(settings) {
|
|
19559
|
+
if (!settings) {
|
|
19560
|
+
return null;
|
|
19561
|
+
}
|
|
19562
|
+
return {
|
|
19563
|
+
...settings,
|
|
19564
|
+
deviceId: this.summarizeId(settings.deviceId),
|
|
19565
|
+
groupId: this.summarizeId(settings.groupId),
|
|
19566
|
+
};
|
|
19567
|
+
}
|
|
19568
|
+
sanitizeTrackConstraints(track) {
|
|
19569
|
+
if (!track) {
|
|
19570
|
+
return null;
|
|
19571
|
+
}
|
|
19572
|
+
const constraints = track.getConstraints ? track.getConstraints() : {};
|
|
19573
|
+
const sanitizedConstraints = { ...constraints };
|
|
19574
|
+
if (typeof sanitizedConstraints.deviceId === 'string') {
|
|
19575
|
+
sanitizedConstraints.deviceId = this.summarizeId(sanitizedConstraints.deviceId);
|
|
19576
|
+
}
|
|
19577
|
+
return sanitizedConstraints;
|
|
19578
|
+
}
|
|
19579
|
+
getStreamSnapshot(stream) {
|
|
19580
|
+
if (!stream) {
|
|
19581
|
+
return { hasStream: false };
|
|
19582
|
+
}
|
|
19583
|
+
const videoTrack = stream.getVideoTracks()[0];
|
|
19584
|
+
if (!videoTrack) {
|
|
19585
|
+
return {
|
|
19586
|
+
hasStream: true,
|
|
19587
|
+
streamActive: stream.active,
|
|
19588
|
+
trackCount: stream.getTracks().length,
|
|
19589
|
+
hasVideoTrack: false,
|
|
19590
|
+
};
|
|
19591
|
+
}
|
|
19592
|
+
return {
|
|
19593
|
+
hasStream: true,
|
|
19594
|
+
streamActive: stream.active,
|
|
19595
|
+
trackCount: stream.getTracks().length,
|
|
19596
|
+
trackLabel: videoTrack.label || '(sin label)',
|
|
19597
|
+
trackEnabled: videoTrack.enabled,
|
|
19598
|
+
trackMuted: videoTrack.muted,
|
|
19599
|
+
trackReadyState: videoTrack.readyState,
|
|
19600
|
+
settings: this.sanitizeTrackSettings(videoTrack.getSettings ? videoTrack.getSettings() : undefined),
|
|
19601
|
+
constraints: this.sanitizeTrackConstraints(videoTrack),
|
|
19602
|
+
};
|
|
19603
|
+
}
|
|
19604
|
+
getVideoElementSnapshot() {
|
|
19605
|
+
if (!this.videoRef) {
|
|
19606
|
+
return { hasVideoRef: false };
|
|
19607
|
+
}
|
|
19608
|
+
const computedStyle = this.el.ownerDocument?.defaultView?.getComputedStyle(this.videoRef);
|
|
19609
|
+
return {
|
|
19610
|
+
hasVideoRef: true,
|
|
19611
|
+
isConnected: this.videoRef.isConnected,
|
|
19612
|
+
readyState: this.videoRef.readyState,
|
|
19613
|
+
networkState: this.videoRef.networkState,
|
|
19614
|
+
paused: this.videoRef.paused,
|
|
19615
|
+
muted: this.videoRef.muted,
|
|
19616
|
+
autoplay: this.videoRef.autoplay,
|
|
19617
|
+
playsInline: this.videoRef.playsInline,
|
|
19618
|
+
currentTime: Number.isFinite(this.videoRef.currentTime)
|
|
19619
|
+
? Number(this.videoRef.currentTime.toFixed(3))
|
|
19620
|
+
: this.videoRef.currentTime,
|
|
19621
|
+
videoWidth: this.videoRef.videoWidth,
|
|
19622
|
+
videoHeight: this.videoRef.videoHeight,
|
|
19623
|
+
clientWidth: this.videoRef.clientWidth,
|
|
19624
|
+
clientHeight: this.videoRef.clientHeight,
|
|
19625
|
+
hasSrcObject: !!this.videoRef.srcObject,
|
|
19626
|
+
display: computedStyle?.display ?? 'unknown',
|
|
19627
|
+
visibility: computedStyle?.visibility ?? 'unknown',
|
|
19628
|
+
};
|
|
19629
|
+
}
|
|
19630
|
+
attachVideoDiagnosticListeners() {
|
|
19631
|
+
if (!this.debug || !this.videoRef) {
|
|
19632
|
+
return () => undefined;
|
|
19633
|
+
}
|
|
19634
|
+
const video = this.videoRef;
|
|
19635
|
+
const listeners = this.VIDEO_DIAGNOSTIC_EVENTS.map(eventName => {
|
|
19636
|
+
const handler = () => {
|
|
19637
|
+
this.debugLog(`video event "${eventName}"`, this.getVideoElementSnapshot());
|
|
19638
|
+
};
|
|
19639
|
+
video.addEventListener(eventName, handler);
|
|
19640
|
+
return { eventName, handler };
|
|
19641
|
+
});
|
|
19642
|
+
return () => {
|
|
19643
|
+
listeners.forEach(({ eventName, handler }) => {
|
|
19644
|
+
video.removeEventListener(eventName, handler);
|
|
19645
|
+
});
|
|
19646
|
+
};
|
|
19647
|
+
}
|
|
19512
19648
|
// DETECTION METHODS
|
|
19513
19649
|
async startDetection() {
|
|
19514
19650
|
try {
|
|
@@ -19595,12 +19731,19 @@ const JaakStamps = class {
|
|
|
19595
19731
|
this.updateStatus('Configurando cámara...', 'Buscando dispositivos disponibles', 'loading');
|
|
19596
19732
|
try {
|
|
19597
19733
|
await this.cameraService.enumerateDevices();
|
|
19734
|
+
this.debugLog('step 2/5 enumerateDevices()', {
|
|
19735
|
+
cameras: this.getCameraDevicesSnapshot(),
|
|
19736
|
+
selectedCameraId: this.summarizeId(this.cameraService.getSelectedCameraId() || undefined),
|
|
19737
|
+
});
|
|
19598
19738
|
}
|
|
19599
19739
|
catch (enumerateError) {
|
|
19600
19740
|
throw new Error(`Error al enumerar dispositivos: ${enumerateError.message}`);
|
|
19601
19741
|
}
|
|
19602
19742
|
try {
|
|
19603
19743
|
await this.updateCameraInfoWithAutofocus();
|
|
19744
|
+
this.debugLog('step 2/5 updateCameraInfoWithAutofocus()', {
|
|
19745
|
+
cameraInfo: this.cameraInfoWithAutofocus,
|
|
19746
|
+
});
|
|
19604
19747
|
}
|
|
19605
19748
|
catch (cameraInfoError) {
|
|
19606
19749
|
throw new Error(`Error al actualizar información de cámara: ${cameraInfoError.message}`);
|
|
@@ -19610,6 +19753,10 @@ const JaakStamps = class {
|
|
|
19610
19753
|
let stream;
|
|
19611
19754
|
try {
|
|
19612
19755
|
stream = await this.cameraService.setupCamera();
|
|
19756
|
+
this.debugLog('step 3/5 setupCamera() resolved', {
|
|
19757
|
+
stream: this.getStreamSnapshot(stream),
|
|
19758
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19759
|
+
});
|
|
19613
19760
|
}
|
|
19614
19761
|
catch (setupError) {
|
|
19615
19762
|
throw new Error(`Error al configurar cámara: ${setupError.message}`);
|
|
@@ -19622,7 +19769,15 @@ const JaakStamps = class {
|
|
|
19622
19769
|
this.updateStatus('Captura activa', 'Posicione su documento y use el botón para capturar', 'active');
|
|
19623
19770
|
}
|
|
19624
19771
|
try {
|
|
19772
|
+
this.debugLog('step 4/5 initializeVideoStream() start', {
|
|
19773
|
+
stream: this.getStreamSnapshot(stream),
|
|
19774
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19775
|
+
});
|
|
19625
19776
|
await this.initializeVideoStream(stream);
|
|
19777
|
+
this.debugLog('step 4/5 initializeVideoStream() completed', {
|
|
19778
|
+
stream: this.getStreamSnapshot(stream),
|
|
19779
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19780
|
+
});
|
|
19626
19781
|
}
|
|
19627
19782
|
catch (videoError) {
|
|
19628
19783
|
throw new Error(`Error al inicializar video: ${videoError.message}`);
|
|
@@ -19640,9 +19795,19 @@ const JaakStamps = class {
|
|
|
19640
19795
|
if (!this.useDocumentDetector) {
|
|
19641
19796
|
this.showManualCaptureButton = true;
|
|
19642
19797
|
}
|
|
19798
|
+
this.debugLog('step 5/5 capture loop ready', {
|
|
19799
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19800
|
+
stream: this.getStreamSnapshot(this.videoStream),
|
|
19801
|
+
useDocumentDetector: this.useDocumentDetector,
|
|
19802
|
+
});
|
|
19643
19803
|
this.detectFrame();
|
|
19644
19804
|
}
|
|
19645
19805
|
catch (err) {
|
|
19806
|
+
this.debugWarn('startDetection() failed', {
|
|
19807
|
+
error: err instanceof Error ? err.message : String(err),
|
|
19808
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19809
|
+
stream: this.getStreamSnapshot(this.videoStream),
|
|
19810
|
+
});
|
|
19646
19811
|
console.error('[jaak-stamps] Error al preparar captura:', err);
|
|
19647
19812
|
this.updateStatus('Error al iniciar', 'No se pudo preparar la captura', 'error');
|
|
19648
19813
|
this.stateManager.updateCaptureState({ isLoading: false });
|
|
@@ -19652,11 +19817,93 @@ const JaakStamps = class {
|
|
|
19652
19817
|
if (!this.videoRef) {
|
|
19653
19818
|
throw new Error('Video element not available');
|
|
19654
19819
|
}
|
|
19820
|
+
const detachVideoDiagnosticListeners = this.attachVideoDiagnosticListeners();
|
|
19821
|
+
this.debugLog('initializeVideoStream() pre-assign', {
|
|
19822
|
+
stream: this.getStreamSnapshot(stream),
|
|
19823
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19824
|
+
});
|
|
19655
19825
|
this.videoRef.srcObject = stream;
|
|
19656
19826
|
this.videoStream = stream;
|
|
19827
|
+
this.debugLog('initializeVideoStream() post-srcObject assignment', {
|
|
19828
|
+
stream: this.getStreamSnapshot(stream),
|
|
19829
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19830
|
+
});
|
|
19657
19831
|
const isRear = this.cameraService.isRearCamera(stream);
|
|
19658
19832
|
this.shouldMirrorVideo = !isRear;
|
|
19659
19833
|
const LOAD_METADATA_TIMEOUT_MS = 10000;
|
|
19834
|
+
// Diagnostic instrumentation: when the timeout fires we need enough
|
|
19835
|
+
// context to distinguish between "OS muted the track", "permission
|
|
19836
|
+
// revoked mid-flight", "device never produced frames" and other modes
|
|
19837
|
+
// that all surface as the same generic timeout error.
|
|
19838
|
+
const track = stream.getVideoTracks()[0];
|
|
19839
|
+
const waitStart = performance.now();
|
|
19840
|
+
const trackEvents = [];
|
|
19841
|
+
const recordTrackEvent = (event) => {
|
|
19842
|
+
trackEvents.push({
|
|
19843
|
+
at: Math.round(performance.now() - waitStart),
|
|
19844
|
+
event,
|
|
19845
|
+
state: track?.readyState,
|
|
19846
|
+
});
|
|
19847
|
+
};
|
|
19848
|
+
const onTrackMute = () => recordTrackEvent('mute');
|
|
19849
|
+
const onTrackUnmute = () => recordTrackEvent('unmute');
|
|
19850
|
+
const onTrackEnded = () => recordTrackEvent('ended');
|
|
19851
|
+
if (track) {
|
|
19852
|
+
track.addEventListener('mute', onTrackMute);
|
|
19853
|
+
track.addEventListener('unmute', onTrackUnmute);
|
|
19854
|
+
track.addEventListener('ended', onTrackEnded);
|
|
19855
|
+
}
|
|
19856
|
+
const cleanupTrackListeners = () => {
|
|
19857
|
+
if (!track)
|
|
19858
|
+
return;
|
|
19859
|
+
track.removeEventListener('mute', onTrackMute);
|
|
19860
|
+
track.removeEventListener('unmute', onTrackUnmute);
|
|
19861
|
+
track.removeEventListener('ended', onTrackEnded);
|
|
19862
|
+
};
|
|
19863
|
+
const captureDiagnostics = () => {
|
|
19864
|
+
const settings = track?.getSettings?.();
|
|
19865
|
+
const computed = this.videoRef ? getComputedStyle(this.videoRef) : null;
|
|
19866
|
+
return {
|
|
19867
|
+
reason: 'VIDEO_METADATA_TIMEOUT',
|
|
19868
|
+
waitedMs: Math.round(performance.now() - waitStart),
|
|
19869
|
+
stream: {
|
|
19870
|
+
videoTrackCount: stream.getVideoTracks().length,
|
|
19871
|
+
audioTrackCount: stream.getAudioTracks().length,
|
|
19872
|
+
},
|
|
19873
|
+
track: track ? {
|
|
19874
|
+
readyState: track.readyState,
|
|
19875
|
+
muted: track.muted,
|
|
19876
|
+
enabled: track.enabled,
|
|
19877
|
+
label: track.label,
|
|
19878
|
+
kind: track.kind,
|
|
19879
|
+
settings: settings ? {
|
|
19880
|
+
width: settings.width,
|
|
19881
|
+
height: settings.height,
|
|
19882
|
+
frameRate: settings.frameRate,
|
|
19883
|
+
deviceId: settings.deviceId,
|
|
19884
|
+
facingMode: settings.facingMode,
|
|
19885
|
+
} : null,
|
|
19886
|
+
} : null,
|
|
19887
|
+
video: this.videoRef ? {
|
|
19888
|
+
readyState: this.videoRef.readyState,
|
|
19889
|
+
networkState: this.videoRef.networkState,
|
|
19890
|
+
error: this.videoRef.error ? { code: this.videoRef.error.code, message: this.videoRef.error.message } : null,
|
|
19891
|
+
paused: this.videoRef.paused,
|
|
19892
|
+
offsetWidth: this.videoRef.offsetWidth,
|
|
19893
|
+
offsetHeight: this.videoRef.offsetHeight,
|
|
19894
|
+
videoWidth: this.videoRef.videoWidth,
|
|
19895
|
+
videoHeight: this.videoRef.videoHeight,
|
|
19896
|
+
display: computed?.display,
|
|
19897
|
+
visibility: computed?.visibility,
|
|
19898
|
+
} : null,
|
|
19899
|
+
document: {
|
|
19900
|
+
visibilityState: document.visibilityState,
|
|
19901
|
+
hasFocus: document.hasFocus(),
|
|
19902
|
+
},
|
|
19903
|
+
trackEvents,
|
|
19904
|
+
userAgent: navigator.userAgent,
|
|
19905
|
+
};
|
|
19906
|
+
};
|
|
19660
19907
|
const finalizeStreamInitialization = async () => {
|
|
19661
19908
|
try {
|
|
19662
19909
|
await this.videoRef.play();
|
|
@@ -19671,24 +19918,39 @@ const JaakStamps = class {
|
|
|
19671
19918
|
const rect = container.getBoundingClientRect();
|
|
19672
19919
|
this.updateMaskDimensions(rect);
|
|
19673
19920
|
}
|
|
19921
|
+
this.debugLog('initializeVideoStream() finalized after play()', {
|
|
19922
|
+
stream: this.getStreamSnapshot(stream),
|
|
19923
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19924
|
+
});
|
|
19674
19925
|
};
|
|
19675
19926
|
// If metadata is already available (readyState >= HAVE_METADATA = 1),
|
|
19676
19927
|
// the 'loadedmetadata' event will not fire again. Handle both cases.
|
|
19677
19928
|
if (this.videoRef.readyState >= 1) {
|
|
19678
|
-
|
|
19679
|
-
|
|
19680
|
-
}
|
|
19929
|
+
this.debugLog('video metadata already available, skipping event wait', this.getVideoElementSnapshot());
|
|
19930
|
+
cleanupTrackListeners();
|
|
19681
19931
|
await finalizeStreamInitialization();
|
|
19932
|
+
detachVideoDiagnosticListeners();
|
|
19682
19933
|
return;
|
|
19683
19934
|
}
|
|
19684
19935
|
return new Promise((resolve, reject) => {
|
|
19685
19936
|
let settled = false;
|
|
19937
|
+
const cleanup = () => {
|
|
19938
|
+
this.videoRef.onloadedmetadata = null;
|
|
19939
|
+
this.videoRef.onerror = null;
|
|
19940
|
+
detachVideoDiagnosticListeners();
|
|
19941
|
+
};
|
|
19686
19942
|
const timeoutId = setTimeout(() => {
|
|
19687
19943
|
if (settled)
|
|
19688
19944
|
return;
|
|
19689
19945
|
settled = true;
|
|
19690
|
-
|
|
19691
|
-
this.
|
|
19946
|
+
const diagnostics = captureDiagnostics();
|
|
19947
|
+
this.debugWarn(`initializeVideoStream() timeout after ${LOAD_METADATA_TIMEOUT_MS}ms`, {
|
|
19948
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19949
|
+
stream: this.getStreamSnapshot(stream),
|
|
19950
|
+
});
|
|
19951
|
+
console.error('[jaak-stamps] Video metadata timeout diagnostics (json):', JSON.stringify(diagnostics));
|
|
19952
|
+
cleanup();
|
|
19953
|
+
cleanupTrackListeners();
|
|
19692
19954
|
reject(new Error(`Video metadata load timeout after ${LOAD_METADATA_TIMEOUT_MS}ms`));
|
|
19693
19955
|
}, LOAD_METADATA_TIMEOUT_MS);
|
|
19694
19956
|
this.videoRef.onloadedmetadata = async () => {
|
|
@@ -19696,13 +19958,18 @@ const JaakStamps = class {
|
|
|
19696
19958
|
return;
|
|
19697
19959
|
settled = true;
|
|
19698
19960
|
clearTimeout(timeoutId);
|
|
19699
|
-
this.
|
|
19700
|
-
|
|
19961
|
+
this.debugLog('initializeVideoStream() onloadedmetadata fired', {
|
|
19962
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19963
|
+
stream: this.getStreamSnapshot(stream),
|
|
19964
|
+
});
|
|
19965
|
+
cleanupTrackListeners();
|
|
19701
19966
|
try {
|
|
19702
19967
|
await finalizeStreamInitialization();
|
|
19968
|
+
cleanup();
|
|
19703
19969
|
resolve();
|
|
19704
19970
|
}
|
|
19705
19971
|
catch (err) {
|
|
19972
|
+
cleanup();
|
|
19706
19973
|
reject(err);
|
|
19707
19974
|
}
|
|
19708
19975
|
};
|
|
@@ -19711,8 +19978,13 @@ const JaakStamps = class {
|
|
|
19711
19978
|
return;
|
|
19712
19979
|
settled = true;
|
|
19713
19980
|
clearTimeout(timeoutId);
|
|
19714
|
-
this.
|
|
19715
|
-
|
|
19981
|
+
this.debugWarn('initializeVideoStream() video element emitted error', {
|
|
19982
|
+
event,
|
|
19983
|
+
videoRef: this.getVideoElementSnapshot(),
|
|
19984
|
+
stream: this.getStreamSnapshot(stream),
|
|
19985
|
+
});
|
|
19986
|
+
cleanup();
|
|
19987
|
+
cleanupTrackListeners();
|
|
19716
19988
|
reject(new Error(`Video element error: ${event}`));
|
|
19717
19989
|
};
|
|
19718
19990
|
});
|
|
@@ -19937,7 +20209,16 @@ const JaakStamps = class {
|
|
|
19937
20209
|
isCapturing: false
|
|
19938
20210
|
};
|
|
19939
20211
|
const cameraInfo = this.cameraInfoWithAutofocus;
|
|
19940
|
-
return (index.h("div", { key: '
|
|
20212
|
+
return (index.h("div", { key: '958fb0a94dcab5e15b2da9b2f6e1219d85e1f03a', class: "detector-container" }, !this.licenseValid && this.licenseError && (index.h("div", { key: 'b455ba5f14b5415d2b49c8ace3ead469cd2a7acc', class: "license-error-container" }, index.h("div", { key: '4c1e7f980319cf125b5186e26158c37a7a97842c', class: "license-error-card" }, index.h("svg", { key: '4c411ef193d03c543fe9298bc3aa077dcaf6b7ea', 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: '24f0eb292901ee9cef24afdc2161bc69f6a51cd0', 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: 'e5e61abf14d9422633d1c3de9efb7d1a909c941c', d: "M12 8V12", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" }), index.h("circle", { key: 'f5612a5748a26d33fbfa9a60ea084614f53197f9', cx: "12", cy: "16", r: "0.5", fill: "currentColor", stroke: "currentColor", "stroke-width": "1" })), index.h("h2", { key: '5ba51ab22b3dc341a5a59661a5f4f87d6dcc4f96', class: "license-error-title" }, "Licencia Requerida"), index.h("p", { key: 'd162830f9b888ff9d179abd4d532287c3edd2b44', class: "license-error-message" }, this.licenseError), index.h("p", { key: '8ac80117990849f03c4cac091a9642160b49c109', class: "license-error-help" }, "Contacte a soporte: ", index.h("a", { key: 'df4b871006f2d4e5f95be43b4a2c3699288d3773', href: "mailto:support@jaak.ai" }, "support@jaak.ai")), index.h("div", { key: 'aa1aacb0dc56c76cce5d6bdac373f2e64d7b3f18', class: "license-error-footer" }, "JAAK Stamps")))), this.licenseValid && (index.h("div", { key: '0a5a3ad11c511d0d8f1b33a4a2fff32aede47277', class: "video-container" }, index.h("video", { key: 'db9c667c035c27aec76625385bb7b1ec0624736e', ref: el => this.videoRef = el, autoplay: true, muted: true, playsinline: true, class: this.shouldMirrorVideo ? 'mirror' : '', style: {
|
|
20213
|
+
// Keep the element rendered (display: block) so the browser
|
|
20214
|
+
// loads stream metadata and fires 'loadedmetadata'. Hiding it
|
|
20215
|
+
// with display:none prevents metadata loading in Chrome and
|
|
20216
|
+
// causes initializeVideoStream to hang waiting for the event.
|
|
20217
|
+
// Use opacity + visibility to hide visually while keeping the
|
|
20218
|
+
// render context alive.
|
|
20219
|
+
opacity: captureState.isVideoActive ? '1' : '0',
|
|
20220
|
+
visibility: captureState.isVideoActive ? 'visible' : 'hidden',
|
|
20221
|
+
} }), index.h("div", { key: '424765f58b596d8459ae903245ee8e0717eaf14a', 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
20222
|
position: 'absolute',
|
|
19942
20223
|
left: `${box.x}px`,
|
|
19943
20224
|
top: `${box.y}px`,
|
|
@@ -19946,9 +20227,9 @@ const JaakStamps = class {
|
|
|
19946
20227
|
border: '2px solid #32406C',
|
|
19947
20228
|
pointerEvents: 'none',
|
|
19948
20229
|
boxSizing: 'border-box'
|
|
19949
|
-
} })))), this.isMaskReady && (index.h("div", { key: '
|
|
20230
|
+
} })))), this.isMaskReady && (index.h("div", { key: '26b11d2375ac441dbd8b5eaec4f5976df4d1f0aa', class: "overlay-mask" }, index.h("div", { key: '51d95dab401719ed84533a76e58ce00c12d4f72a', class: "card-outline" }, index.h("div", { key: 'd2b87cb68858e74340611a46ea7e3efc1691f46e', class: "side side-top" }), index.h("div", { key: '55ff7658fcc123535c9710133ef4d8973bca1d2e', class: "side side-right" }), index.h("div", { key: '0dfa4f296ff756afa2003eb4fb368d208128c47e', class: "side side-bottom" }), index.h("div", { key: '9aefe3fef283ee27cbe412d27a1a873cd871eb1a', class: "side side-left" })), !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: 'ae93e17580fe8d6efa460857011ebf36d4b162b6', class: `guide-text ${this.showPerformanceMessage ? 'performance-warning-text' : ''}` }, this.getGuideText(captureState.step))), captureState.step === 'back' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: 'a9835585d26c8819ffb12e5a278d19c89d17ec6a', class: "back-capture-section" }, index.h("div", { key: '7563c10750eb649c337379bcd1966ebbe4c0a7be', class: "back-capture-buttons" }, (!this.useDocumentDetector || this.performanceDegradedMode || this.showManualCaptureButton) && (index.h("button", { key: '0c44faf4123197765b0bad30f5674ce7b1cc4f00', class: "capture-button primary-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-back' && (index.h("span", { key: 'efed4645446e3ac5189dcc909998bda49771e61d', class: "button-spinner" })), "Capturar Reverso")), index.h("button", { key: '7f21e533d151507cb8aefeb232e2e6924ec4a935', class: "skip-button", onClick: () => this.skipBackCapture(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'skip-back' && (index.h("span", { key: '2634e6953b71e30b658dc632d853124f5ce5bb91', class: "button-spinner" })), this.enableBackDocumentTimer && this.backDocumentTimerRemaining > 0
|
|
19950
20231
|
? `Saltar reverso (${this.backDocumentTimerRemaining}s)`
|
|
19951
|
-
: 'Saltar reverso')))), captureState.isVideoActive && (index.h("div", { key: '
|
|
20232
|
+
: 'Saltar reverso')))), captureState.isVideoActive && (index.h("div", { key: 'ed8cf74950d02b58d4c8628663ec692d964757f0', class: "camera-controls" }, index.h("button", { key: 'd309850ed774ac08e63e1eb1ea0019f7c80d3db6', 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: '4a70996d233bffbeac7badc52537d94453db30d3', class: "camera-selector-dropdown" }, index.h("div", { key: '7f893af0afeff55fe63e4971d0afc24516d2b6a6', class: "camera-selector-header" }, index.h("span", { key: 'd20382742b5ee5d90f678988d0d2c1c964f615d6' }, "Seleccionar C\u00E1mara"), index.h("button", { key: '1542d189db50740dd10e2ea843f7c5dccc5e24f2', class: "close-selector", onClick: () => this.toggleCameraSelector(), type: "button" }, "\u00D7")), index.h("div", { key: 'e7907a23b4c7571c455f906333ccbd8e4172d3c9', 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: '8615ca9b81f57bbf5d52d40fd827b79a637f5e4f', class: "device-info" }, index.h("small", { key: '6f07c1bfb1a2b3824ccdfae4ebca11b0fa0297fe' }, "Dispositivo: ", cameraInfo.deviceType)))), this.showManualCaptureButton && captureState.step === 'front' && !captureState.showFlipAnimation && !captureState.showSuccessAnimation && (index.h("div", { key: 'c1c18723517003f2bcb9f68c527a13c4e6f30095', class: "manual-capture-section" }, index.h("button", { key: '94d21c348697cd28ecb44a5144e1e105f10e377c', class: "manual-capture-button", onClick: () => this.takeManualScreenshot(), type: "button", disabled: this.processingButton !== null }, this.processingButton === 'capture-front' && (index.h("span", { key: '74333b317328ad70da763e5d127635f3b6dc13d1', class: "button-spinner" })), "Capturar Frente"))))), captureState.isCapturing && (index.h("div", { key: '6761b16e393c5d496c5fde729b6b36580cfede0c', class: "capture-animation" })), captureState.showFlipAnimation && (index.h("div", { key: '7556dddec2de2c134f9b09fbd38569366c35da48', class: "flip-animation" }, index.h("div", { key: 'baa3cd8993ef761ebfb94ccda6d66896959f32ee', class: "id-card-icon" }), index.h("div", { key: '3c5027ada509290b9abbf599849dbd19e50113af', class: "flip-text" }, "\u00A1Voltea tu identificaci\u00F3n!"))), captureState.showSuccessAnimation && (index.h("div", { key: '1826a908ea94637428d9e800668d9ee02f0f03de', class: "success-animation" }, index.h("div", { key: '60d8e894ceed0c5198edb67a1e3e0fa24b9aaa3b', class: "check-icon" }), index.h("div", { key: '106d6ccec79f64b94273baeb8984f23e71987076', class: "success-text" }, "\u00A1Proceso completado!"))), index.h("div", { key: '804e4fe62de056dca22964283282e32336f8eb00', class: `component-status status-${this.currentStatus.type}` }, (this.currentStatus.type === 'loading' || this.currentStatus.type === 'initializing') && (index.h("div", { key: '108d6cab9eb7826cbe396806652a6b096ce0736d', class: "status-spinner" })), index.h("div", { key: '4abe0717c6b66b2bf44eb2da513fb6c22af31725', class: "status-content" }, index.h("div", { key: '77fb79d89df1f9e25c3c4962235b0605c7b6237f', class: "status-message" }, this.currentStatus.message), this.currentStatus.description && (index.h("div", { key: '2b24b09eabbbbbedd1270ebbf72f32f19ee063cb', class: "status-description" }, this.currentStatus.description)))), this.debug && (index.h("div", { key: '7c6bf594cdb26334bfe62ee09d860b19399b4fd2', class: "performance-monitor" }, index.h("div", { key: '06f2b94e8a08e8afe94a2947d928a4c3c1ec260f', class: "performance-expanded" }, index.h("div", { key: 'c9302538e10e53e81a5685226c89a293ffd1608b', class: "metrics-row" }, index.h("div", { key: '7499bee1d362bf9910b401c2f85961847facc9f8', class: "metric-compact" }, index.h("span", { key: 'f005aab118350af46520ece3615544976b5d533f', class: "metric-label" }, "FPS"), index.h("span", { key: '69102a7df1fdc559883f807a8d26ae9268e56b01', class: `metric-value ${this.performanceData.fps < 15 ? 'warning' : this.performanceData.fps < 10 ? 'danger' : 'good'}` }, this.performanceData.fps)), index.h("div", { key: '0a63031beb60eeeb19cd50637f506661cdb1da16', class: "metric-compact" }, index.h("span", { key: '0231014ed6f077d780252c3b822a269148675d2f', class: "metric-label" }, "MEM"), index.h("span", { key: '859eda6914fdab077635f983fd4ca01daaf47ce7', class: `metric-value ${this.performanceData.memoryUsage > 100 ? 'warning' : this.performanceData.memoryUsage > 200 ? 'danger' : 'good'}` }, this.performanceData.memoryUsage, "MB"))), index.h("div", { key: '102218bc7cf2d29c3c8ef7f91febf924ecb418a3', class: "metrics-row" }, index.h("div", { key: '205e50b3dbc43c541b76c21ef8e19a3defe065ce', class: "metric-compact" }, index.h("span", { key: '42eace007731c4642040e33f3e20462d7e150494', class: "metric-label" }, "INF"), index.h("span", { key: 'ff2d169c660011b24fa3340479d91befc9c2d06c', class: `metric-value ${this.performanceData.inferenceTime > 100 ? 'warning' : this.performanceData.inferenceTime > 200 ? 'danger' : 'good'}` }, this.performanceData.inferenceTime, "ms")), index.h("div", { key: 'ec3ec57e442b3aefb38acf774873b0b181731523', class: "metric-compact" }, index.h("span", { key: '27d6d74dcdffbdafb4382c40b60f032b20dc5ade', class: "metric-label" }, "FRAME"), index.h("span", { key: 'e55795508f97a27c0b03736de2e5960560970378', class: `metric-value ${this.performanceData.frameProcessingTime > 50 ? 'warning' : this.performanceData.frameProcessingTime > 100 ? 'danger' : 'good'}` }, this.performanceData.frameProcessingTime, "ms"))), index.h("div", { key: '60e80821ed57f1a724409e26a232fa2792886011', class: "metrics-row" }, index.h("div", { key: '7deb1504fb3705affaab105782ed7107d6e1a501', class: "metric-compact" }, index.h("span", { key: '0658ce3204ce120557caa248505def48a8a205dd', class: "metric-label" }, "DET"), index.h("span", { key: '6b14fafc3903912380edda27e5024e1221917db7', class: "metric-value good" }, this.performanceData.successfulDetections, "/", this.performanceData.totalDetections)), index.h("div", { key: 'ec602c3b4d7d8ab0ffbf165d98e8b2e7d7d0b0ec', class: "metric-compact" }, index.h("span", { key: '9615ae1d383d383f116d2953f05ddb252336f7be', class: "metric-label" }, "RATE"), index.h("span", { key: 'eca7277e9185b9ff4232e556e707a3f1ce80365f', class: `metric-value ${this.performanceData.detectionRate < 30 ? 'danger' : this.performanceData.detectionRate < 60 ? 'warning' : 'good'}` }, this.performanceData.detectionRate, "%")))))), index.h("div", { key: '3b6b9368797965d5795c9752d2b4a08a9934b441', class: "watermark" }, index.h("img", { key: 'b40ffaeb6f88d1a744bffeb64ac11d4f19be6220', src: "https://static.jaak.ai/commons/powered-by-jaak.png", alt: "Powered by Jaak" }))))));
|
|
19952
20233
|
}
|
|
19953
20234
|
// Utility methods
|
|
19954
20235
|
updateDetectionBoxes(boxes) {
|