@neofaceid/web-sdk 1.25.5 → 1.25.7

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/index.d.ts CHANGED
@@ -496,6 +496,7 @@ export declare const ENVIRONMENT_URLS: Record<Environment, string>;
496
496
  */
497
497
  export declare enum ErrorType {
498
498
  NETWORK = "NetworkError",
499
+ /** @deprecated Use `ErrorType.NETWORK`. Mantido para compatibilidade com consumidores existentes do SDK. */
499
500
  NETWORK_ERROR = "NetworkError",
500
501
  INVALID_TOKEN = "InvalidTokenError",
501
502
  RECOGNITION_FAILED = "RecognitionFailedError",
@@ -1362,6 +1363,6 @@ export declare const validateToken: (applicationToken: string) => Promise<boolea
1362
1363
  * MINOR: Incrementado quando adicionamos funcionalidades mantendo compatibilidade
1363
1364
  * PATCH: Incrementado quando corrigimos bugs mantendo compatibilidade
1364
1365
  */
1365
- export declare const VERSION = "1.25.5";
1366
+ export declare const VERSION = "1.25.7";
1366
1367
 
1367
1368
  export { }
@@ -5337,10 +5337,14 @@ function init(options = {}) {
5337
5337
  if (applicationToken) {
5338
5338
  globalConfig.applicationToken = applicationToken;
5339
5339
  } else if (applicationToken === "") {
5340
- console.warn("[NeoFaceID SDK] applicationToken vazio em init() — 401 esperado em chamadas autenticadas.");
5340
+ console.warn(
5341
+ "[NeoFaceID SDK] applicationToken vazio em init() — 401 esperado em chamadas autenticadas."
5342
+ );
5341
5343
  }
5342
5344
  globalConfig.initialized = true;
5343
- console.log(`[NeoFaceID SDK] Inicializado - Ambiente: ${globalConfig.environment}, URL: ${globalConfig.baseUrl}`);
5345
+ console.log(
5346
+ `[NeoFaceID SDK] Inicializado - Ambiente: ${globalConfig.environment}, URL: ${globalConfig.baseUrl}`
5347
+ );
5344
5348
  }
5345
5349
  function getBaseUrl() {
5346
5350
  if (!globalConfig.initialized) {
@@ -5410,8 +5414,8 @@ const compressDocumentImage = async (imageBlob) => new Promise((resolve, reject)
5410
5414
  const img = new Image();
5411
5415
  img.onload = () => {
5412
5416
  const MAX_SIZE = 1280;
5413
- let width = img.width;
5414
- let height = img.height;
5417
+ let { width } = img;
5418
+ let { height } = img;
5415
5419
  if (width > height && width > MAX_SIZE) {
5416
5420
  height = height * MAX_SIZE / width;
5417
5421
  width = MAX_SIZE;
@@ -6030,7 +6034,9 @@ const registerPersonWithoutFace = async (personData, applicationToken, options)
6030
6034
  ];
6031
6035
  }
6032
6036
  if (!applicationToken) {
6033
- console.warn("[NeoFaceID SDK] registerPersonWithoutFace sem applicationToken — 401 esperado.");
6037
+ console.warn(
6038
+ "[NeoFaceID SDK] registerPersonWithoutFace sem applicationToken — 401 esperado."
6039
+ );
6034
6040
  }
6035
6041
  const response = await fetch(`${getApiBaseUrl()}/api/v1/signup/donor/`, {
6036
6042
  method: "POST",
@@ -6167,7 +6173,9 @@ const registerPersonWithBiometric = async (personData, facePhotos, applicationTo
6167
6173
  ];
6168
6174
  }
6169
6175
  if (!applicationToken) {
6170
- console.warn("[NeoFaceID SDK] registerPersonWithBiometric sem applicationToken — 401 esperado.");
6176
+ console.warn(
6177
+ "[NeoFaceID SDK] registerPersonWithBiometric sem applicationToken — 401 esperado."
6178
+ );
6171
6179
  }
6172
6180
  const response = await fetch(`${getApiBaseUrl()}/api/v1/signup/donor/`, {
6173
6181
  method: "POST",
@@ -6709,18 +6717,16 @@ const startProofOfLife = async (videoBase64, applicationToken) => {
6709
6717
  throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK_ERROR);
6710
6718
  }
6711
6719
  };
6712
- const videoToBase64 = async (videoBlob) => {
6713
- return new Promise((resolve, reject) => {
6714
- const reader = new FileReader();
6715
- reader.onload = () => {
6716
- const result = reader.result;
6717
- const base642 = result.includes(",") ? result.split(",")[1] : result;
6718
- resolve(base642);
6719
- };
6720
- reader.onerror = () => reject(new NeoFaceError("Failed to convert video to base64", ErrorType.CAPTURE_ERROR));
6721
- reader.readAsDataURL(videoBlob);
6722
- });
6723
- };
6720
+ const videoToBase64 = async (videoBlob) => new Promise((resolve, reject) => {
6721
+ const reader = new FileReader();
6722
+ reader.onload = () => {
6723
+ const result = reader.result;
6724
+ const base642 = result.includes(",") ? result.split(",")[1] : result;
6725
+ resolve(base642);
6726
+ };
6727
+ reader.onerror = () => reject(new NeoFaceError("Failed to convert video to base64", ErrorType.CAPTURE_ERROR));
6728
+ reader.readAsDataURL(videoBlob);
6729
+ });
6724
6730
  const blobToBase64 = (blob) => new Promise((resolve, reject) => {
6725
6731
  const reader = new FileReader();
6726
6732
  reader.onload = () => {
@@ -6786,7 +6792,9 @@ const registerDocumentByImage = async (personId, jwtToken, images) => {
6786
6792
  const getTaskStatus = async (taskId, applicationToken) => {
6787
6793
  const controller = createTimeoutController();
6788
6794
  {
6789
- console.warn("[NeoFaceID SDK] getTaskStatus sem applicationToken — /tasks/status/ vai responder 401.");
6795
+ console.warn(
6796
+ "[NeoFaceID SDK] getTaskStatus sem applicationToken — /tasks/status/ vai responder 401."
6797
+ );
6790
6798
  }
6791
6799
  try {
6792
6800
  const response = await fetch(`${getApiBaseUrl()}/api/v1/tasks/status/?task_id=${taskId}`, {
@@ -6825,7 +6833,7 @@ const identifyPersonAsync = async (image, applicationToken, options = {}) => {
6825
6833
  person: initialResponse.person
6826
6834
  };
6827
6835
  }
6828
- const taskId = initialResponse.taskId;
6836
+ const { taskId } = initialResponse;
6829
6837
  if (!taskId) {
6830
6838
  return { personFound: false };
6831
6839
  }
@@ -7659,7 +7667,9 @@ function BiometricRegistrationModal({
7659
7667
  const captureStateRef = useRef(null);
7660
7668
  const [state, dispatch] = useReducer(modalReducer, void 0, createInitialState);
7661
7669
  const [faceDetected, setFaceDetected] = useState(false);
7662
- const [faceDistance, setFaceDistance] = useState("ok");
7670
+ const [faceDistance, setFaceDistance] = useState(
7671
+ "ok"
7672
+ );
7663
7673
  const [cameraReady, setCameraReady] = useState(false);
7664
7674
  useEffect(() => {
7665
7675
  if (state.status === "liveness") {
@@ -7790,15 +7800,13 @@ function BiometricRegistrationModal({
7790
7800
  }
7791
7801
  }, 50);
7792
7802
  }
7793
- } else {
7794
- if (holdStartTimeRef.current) {
7795
- holdStartTimeRef.current = null;
7796
- if (progressIntervalRef.current) {
7797
- clearInterval(progressIntervalRef.current);
7798
- progressIntervalRef.current = null;
7799
- }
7800
- dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
7803
+ } else if (holdStartTimeRef.current) {
7804
+ holdStartTimeRef.current = null;
7805
+ if (progressIntervalRef.current) {
7806
+ clearInterval(progressIntervalRef.current);
7807
+ progressIntervalRef.current = null;
7801
7808
  }
7809
+ dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
7802
7810
  }
7803
7811
  };
7804
7812
  useEffect(() => {
@@ -7825,8 +7833,8 @@ function BiometricRegistrationModal({
7825
7833
  };
7826
7834
  loadModels();
7827
7835
  }, []);
7828
- useEffect(() => {
7829
- return () => {
7836
+ useEffect(
7837
+ () => () => {
7830
7838
  if (streamRef.current) {
7831
7839
  streamRef.current.getTracks().forEach((track) => {
7832
7840
  track.stop();
@@ -7848,8 +7856,9 @@ function BiometricRegistrationModal({
7848
7856
  clearTimeout(stepTimeoutTimerRef.current);
7849
7857
  stepTimeoutTimerRef.current = null;
7850
7858
  }
7851
- };
7852
- }, []);
7859
+ },
7860
+ []
7861
+ );
7853
7862
  useEffect(() => {
7854
7863
  let mounted = true;
7855
7864
  const initCamera = async () => {
@@ -7991,15 +8000,13 @@ function BiometricRegistrationModal({
7991
8000
  );
7992
8001
  manageHoldAndCapture(positionCorrect);
7993
8002
  }
7994
- } else {
7995
- if (holdStartTimeRef.current) {
7996
- holdStartTimeRef.current = null;
7997
- if (progressIntervalRef.current) {
7998
- clearInterval(progressIntervalRef.current);
7999
- progressIntervalRef.current = null;
8000
- }
8001
- dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
8003
+ } else if (holdStartTimeRef.current) {
8004
+ holdStartTimeRef.current = null;
8005
+ if (progressIntervalRef.current) {
8006
+ clearInterval(progressIntervalRef.current);
8007
+ progressIntervalRef.current = null;
8002
8008
  }
8009
+ dispatch({ type: "UPDATE_PROGRESS", progress: 0 });
8003
8010
  }
8004
8011
  } catch (error) {
8005
8012
  }
@@ -8028,38 +8035,37 @@ function BiometricRegistrationModal({
8028
8035
  }
8029
8036
  holdStartTimeRef.current = null;
8030
8037
  };
8031
- } else {
8032
- const onCanPlay = () => {
8033
- if (isRunning) startDetection();
8034
- };
8035
- let pollCount = 0;
8036
- const MAX_POLLS = 50;
8037
- const pollTimer = window.setInterval(() => {
8038
- pollCount++;
8039
- if (!isRunning) {
8040
- clearInterval(pollTimer);
8041
- return;
8042
- }
8043
- if (videoRef.current && videoRef.current.readyState >= 2) {
8044
- clearInterval(pollTimer);
8045
- videoRef.current.removeEventListener("canplay", onCanPlay);
8046
- startDetection();
8047
- } else if (pollCount >= MAX_POLLS) {
8048
- clearInterval(pollTimer);
8049
- }
8050
- }, 300);
8051
- video == null ? void 0 : video.addEventListener("canplay", onCanPlay, { once: true });
8052
- return () => {
8053
- isRunning = false;
8054
- clearInterval(pollTimer);
8055
- video == null ? void 0 : video.removeEventListener("canplay", onCanPlay);
8056
- if (progressIntervalRef.current) {
8057
- clearInterval(progressIntervalRef.current);
8058
- progressIntervalRef.current = null;
8059
- }
8060
- holdStartTimeRef.current = null;
8061
- };
8062
8038
  }
8039
+ const onCanPlay = () => {
8040
+ if (isRunning) startDetection();
8041
+ };
8042
+ let pollCount = 0;
8043
+ const MAX_POLLS = 50;
8044
+ const pollTimer = window.setInterval(() => {
8045
+ pollCount++;
8046
+ if (!isRunning) {
8047
+ clearInterval(pollTimer);
8048
+ return;
8049
+ }
8050
+ if (videoRef.current && videoRef.current.readyState >= 2) {
8051
+ clearInterval(pollTimer);
8052
+ videoRef.current.removeEventListener("canplay", onCanPlay);
8053
+ startDetection();
8054
+ } else if (pollCount >= MAX_POLLS) {
8055
+ clearInterval(pollTimer);
8056
+ }
8057
+ }, 300);
8058
+ video == null ? void 0 : video.addEventListener("canplay", onCanPlay, { once: true });
8059
+ return () => {
8060
+ isRunning = false;
8061
+ clearInterval(pollTimer);
8062
+ video == null ? void 0 : video.removeEventListener("canplay", onCanPlay);
8063
+ if (progressIntervalRef.current) {
8064
+ clearInterval(progressIntervalRef.current);
8065
+ progressIntervalRef.current = null;
8066
+ }
8067
+ holdStartTimeRef.current = null;
8068
+ };
8063
8069
  }, [state.status]);
8064
8070
  const capturePhoto = async () => {
8065
8071
  if (!videoRef.current || !canvasRef.current || isCapturingRef.current) {
@@ -8163,7 +8169,7 @@ function BiometricRegistrationModal({
8163
8169
  const renderLivenessDetection = () => {
8164
8170
  if (state.status !== "liveness") return null;
8165
8171
  const progress = `${state.currentStepIndex + 1}/${state.stepSequence.length - 1}`;
8166
- const stepProgress = state.stepProgress;
8172
+ const { stepProgress } = state;
8167
8173
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "liveness-container", children: [
8168
8174
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "progress-indicator", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "progress-text", children: progress }) }),
8169
8175
  faceDetected && faceDistance !== "ok" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `status-badge ${faceDistance === "not-centered" ? "warning" : "error"}`, children: [
@@ -8192,7 +8198,14 @@ function BiometricRegistrationModal({
8192
8198
  stepProgress > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "progress-bar", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "progress-fill", style: { width: `${stepProgress}%` } }) })
8193
8199
  ] }),
8194
8200
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "branding-small", children: [
8195
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "brand-logo-small", style: { display: "inline-flex", width: 18, height: 18, color: "currentColor" }, dangerouslySetInnerHTML: { __html: NEOFACEID_MARK_MONO_SVG } }),
8201
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
8202
+ "span",
8203
+ {
8204
+ className: "brand-logo-small",
8205
+ style: { display: "inline-flex", width: 18, height: 18, color: "currentColor" },
8206
+ dangerouslySetInnerHTML: { __html: NEOFACEID_MARK_MONO_SVG }
8207
+ }
8208
+ ),
8196
8209
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "NeoFaceId by" }),
8197
8210
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "brand-name", children: "OCTA" })
8198
8211
  ] })
@@ -8239,8 +8252,16 @@ function BiometricRegistrationModal({
8239
8252
  /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: "Não foi possível processar" }),
8240
8253
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: state.message }),
8241
8254
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "button-group", children: [
8242
- state.retryable && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "secondary-button", onClick: () => dispatch({ type: "RESET" }), children: "Tentar Novamente" }),
8243
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ghost-button", onClick: onClose, children: "Cancelar" })
8255
+ state.retryable && /* @__PURE__ */ jsxRuntimeExports.jsx(
8256
+ "button",
8257
+ {
8258
+ type: "button",
8259
+ className: "secondary-button",
8260
+ onClick: () => dispatch({ type: "RESET" }),
8261
+ children: "Tentar Novamente"
8262
+ }
8263
+ ),
8264
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ghost-button", onClick: onClose, children: "Cancelar" })
8244
8265
  ] })
8245
8266
  ] });
8246
8267
  };
@@ -8283,7 +8304,7 @@ function BiometricRegistrationModal({
8283
8304
  ] }) }),
8284
8305
  /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: onPhotosCaptured ? "Captura concluída!" : "Verificação concluída!" }),
8285
8306
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: onPhotosCaptured ? "Suas capturas faciais foram realizadas" : "Sua biometria foi registrada com sucesso" }),
8286
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary-button", onClick: onClose, children: "Continuar" })
8307
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "primary-button", onClick: onClose, children: "Continuar" })
8287
8308
  ] });
8288
8309
  const renderDuplicate = () => {
8289
8310
  if (state.status !== "duplicate") return null;
@@ -8295,6 +8316,7 @@ function BiometricRegistrationModal({
8295
8316
  /* @__PURE__ */ jsxRuntimeExports.jsx(
8296
8317
  "button",
8297
8318
  {
8319
+ type: "button",
8298
8320
  className: "primary-button",
8299
8321
  onClick: () => {
8300
8322
  onClose();
@@ -8306,6 +8328,7 @@ function BiometricRegistrationModal({
8306
8328
  /* @__PURE__ */ jsxRuntimeExports.jsx(
8307
8329
  "button",
8308
8330
  {
8331
+ type: "button",
8309
8332
  className: "secondary-button",
8310
8333
  style: { marginTop: "12px" },
8311
8334
  onClick: () => {
@@ -8320,6 +8343,7 @@ function BiometricRegistrationModal({
8320
8343
  /* @__PURE__ */ jsxRuntimeExports.jsx(
8321
8344
  "button",
8322
8345
  {
8346
+ type: "button",
8323
8347
  className: "ghost-button",
8324
8348
  onClick: () => window.open("https://support.neofaceid.com", "_blank"),
8325
8349
  children: "Falar com Suporte"
@@ -8987,7 +9011,7 @@ function BiometricRegistrationModal({
8987
9011
  }
8988
9012
  ` }),
8989
9013
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "modal-overlay", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "modal-content", children: [
8990
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "close-button", onClick: onClose, children: "×" }),
9014
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "close-button", onClick: onClose, children: "×" }),
8991
9015
  state.status === "liveness" && renderLivenessDetection(),
8992
9016
  state.status === "camera-loading" && renderCameraLoading(),
8993
9017
  state.status === "processing" && renderProcessing(),
@@ -9253,7 +9277,7 @@ class BiometricCaptureModal {
9253
9277
  } catch (error) {
9254
9278
  this.options.onError(
9255
9279
  new NeoFaceError(
9256
- "Erro ao inicializar câmera: " + error.message,
9280
+ `Erro ao inicializar câmera: ${error.message}`,
9257
9281
  ErrorType.CAMERA_ERROR
9258
9282
  )
9259
9283
  );
@@ -9335,7 +9359,7 @@ class BiometricCaptureModal {
9335
9359
  this.canvas.width = this.video.videoWidth;
9336
9360
  this.canvas.height = this.video.videoHeight;
9337
9361
  } catch (error) {
9338
- throw new Error("Não foi possível acessar a câmera: " + error.message);
9362
+ throw new Error(`Não foi possível acessar a câmera: ${error.message}`);
9339
9363
  }
9340
9364
  }
9341
9365
  /**
@@ -9389,13 +9413,13 @@ class BiometricCaptureModal {
9389
9413
  const imageData = this.canvas.toDataURL("image/jpeg", 0.8);
9390
9414
  const base64Data = imageData.split(",")[1];
9391
9415
  const dataUrl = `data:image/jpeg;base64,${base64Data}`;
9392
- let detectedType = this.options.mode === "auto" ? await this.detectBiometricType(base64Data) : this.options.mode;
9416
+ const detectedType = this.options.mode === "auto" ? await this.detectBiometricType(base64Data) : this.options.mode;
9393
9417
  this.close();
9394
9418
  this.options.onSuccess(dataUrl, detectedType);
9395
9419
  } catch (error) {
9396
9420
  this.options.onError(
9397
9421
  new NeoFaceError(
9398
- "Erro ao capturar imagem: " + error.message,
9422
+ `Erro ao capturar imagem: ${error.message}`,
9399
9423
  ErrorType.CAPTURE_ERROR
9400
9424
  )
9401
9425
  );
@@ -10699,7 +10723,7 @@ async function captureFaceSilently() {
10699
10723
  cleanup();
10700
10724
  reject(
10701
10725
  new NeoFaceError(
10702
- "Erro ao reproduzir câmera: " + err.message,
10726
+ `Erro ao reproduzir câmera: ${err.message}`,
10703
10727
  ErrorType.CAMERA_ERROR
10704
10728
  )
10705
10729
  );
@@ -10715,7 +10739,7 @@ async function captureFaceSilently() {
10715
10739
  cleanup();
10716
10740
  reject(
10717
10741
  new NeoFaceError(
10718
- "Não foi possível acessar a câmera: " + error.message,
10742
+ `Não foi possível acessar a câmera: ${error.message}`,
10719
10743
  ErrorType.CAMERA_ERROR
10720
10744
  )
10721
10745
  );
@@ -11216,9 +11240,12 @@ async function detectBiometricType(imageData) {
11216
11240
  async function detectFace(img) {
11217
11241
  try {
11218
11242
  if (typeof window !== "undefined" && window.faceapi) {
11219
- const faceapi2 = window.faceapi;
11243
+ const { faceapi: faceapi2 } = window;
11220
11244
  await loadFaceApiModels();
11221
- const tinyOptions = new faceapi2.TinyFaceDetectorOptions({ inputSize: 320, scoreThreshold: 0.5 });
11245
+ const tinyOptions = new faceapi2.TinyFaceDetectorOptions({
11246
+ inputSize: 320,
11247
+ scoreThreshold: 0.5
11248
+ });
11222
11249
  const detections = await faceapi2.detectAllFaces(img, tinyOptions).withFaceLandmarks();
11223
11250
  if (detections && detections.length > 0) {
11224
11251
  const bestDetection = detections.reduce(
@@ -11317,7 +11344,7 @@ async function loadFaceApiModels() {
11317
11344
  if (typeof window === "undefined" || !window.faceapi) {
11318
11345
  return;
11319
11346
  }
11320
- const faceapi2 = window.faceapi;
11347
+ const { faceapi: faceapi2 } = window;
11321
11348
  if (faceapi2.nets.tinyFaceDetector.isLoaded) {
11322
11349
  return;
11323
11350
  }
@@ -11348,7 +11375,7 @@ const biometricDetection = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
11348
11375
  initializeBiometricDetection,
11349
11376
  isAdvancedDetectionAvailable
11350
11377
  }, Symbol.toStringTag, { value: "Module" }));
11351
- const VERSION = "1.25.5";
11378
+ const VERSION = "1.25.7";
11352
11379
  const RELEASE_DATE = "2026-08-29";
11353
11380
  class OnboardingCaptureModal {
11354
11381
  constructor(options) {
@@ -11376,7 +11403,10 @@ class OnboardingCaptureModal {
11376
11403
  await this.runFaceCaptureCountdown();
11377
11404
  this.faceBlob = await this.captureFrame();
11378
11405
  this.step = "document";
11379
- this.updateTexts("Captura do Documento", 'Posicione seu documento visível e clique em "Capturar"');
11406
+ this.updateTexts(
11407
+ "Captura do Documento",
11408
+ 'Posicione seu documento visível e clique em "Capturar"'
11409
+ );
11380
11410
  await this.waitForUserCaptureClick();
11381
11411
  this.documentBlob = await this.captureFrame();
11382
11412
  await this.close();
@@ -11474,7 +11504,9 @@ class OnboardingCaptureModal {
11474
11504
  async runFaceCaptureCountdown() {
11475
11505
  if (!this.overlay) return;
11476
11506
  const countdownEl = this.overlay.querySelector(".neofaceid-countdown");
11477
- const countdownNumberEl = this.overlay.querySelector(".neofaceid-countdown-number");
11507
+ const countdownNumberEl = this.overlay.querySelector(
11508
+ ".neofaceid-countdown-number"
11509
+ );
11478
11510
  const statusText = this.overlay.querySelector(".neofaceid-status-text");
11479
11511
  countdownEl.style.display = "flex";
11480
11512
  statusText.textContent = "Prepare-se! Capturando seu rosto...";
@@ -11521,7 +11553,11 @@ class OnboardingCaptureModal {
11521
11553
  this.canvas.height = this.video.videoHeight;
11522
11554
  ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
11523
11555
  const blob = await new Promise((resolve, reject) => {
11524
- this.canvas.toBlob((b) => b ? resolve(b) : reject(new Error("Falha ao gerar imagem")), "image/jpeg", 0.92);
11556
+ this.canvas.toBlob(
11557
+ (b) => b ? resolve(b) : reject(new Error("Falha ao gerar imagem")),
11558
+ "image/jpeg",
11559
+ 0.92
11560
+ );
11525
11561
  });
11526
11562
  return blob;
11527
11563
  }
@@ -12151,13 +12187,15 @@ class DocumentCaptureModal {
12151
12187
 
12152
12188
  <div class="neoface-doc-body">
12153
12189
  <div class="neoface-doc-select-grid">
12154
- ${Object.entries(DOCUMENT_INFO).filter(([type]) => type !== "CPF").map(([type, info]) => `
12190
+ ${Object.entries(DOCUMENT_INFO).filter(([type]) => type !== "CPF").map(
12191
+ ([type, info]) => `
12155
12192
  <button class="neoface-doc-select-option" data-type="${type}">
12156
12193
  <span class="neoface-doc-select-icon">${info.icon}</span>
12157
12194
  <span class="neoface-doc-select-name">${info.name}</span>
12158
12195
  <svg class="neoface-doc-select-arrow" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg>
12159
12196
  </button>
12160
- `).join("")}
12197
+ `
12198
+ ).join("")}
12161
12199
  </div>
12162
12200
 
12163
12201
  <div class="neoface-doc-tips">
@@ -12375,8 +12413,8 @@ class DocumentCaptureModal {
12375
12413
  const img = new Image();
12376
12414
  img.onload = () => {
12377
12415
  const MAX_SIZE = 1280;
12378
- let width = img.width;
12379
- let height = img.height;
12416
+ let { width } = img;
12417
+ let { height } = img;
12380
12418
  if (width > height && width > MAX_SIZE) {
12381
12419
  height = height * MAX_SIZE / width;
12382
12420
  width = MAX_SIZE;
@@ -12396,7 +12434,9 @@ class DocumentCaptureModal {
12396
12434
  canvas.toBlob(
12397
12435
  (blob) => {
12398
12436
  if (blob) {
12399
- console.log(`[DocumentCapture] Compressed image from ${(file.size / 1024).toFixed(0)}KB to ${(blob.size / 1024).toFixed(0)}KB`);
12437
+ console.log(
12438
+ `[DocumentCapture] Compressed image from ${(file.size / 1024).toFixed(0)}KB to ${(blob.size / 1024).toFixed(0)}KB`
12439
+ );
12400
12440
  resolve(blob);
12401
12441
  } else {
12402
12442
  reject(new Error("Failed to compress image"));
@@ -12417,7 +12457,9 @@ class DocumentCaptureModal {
12417
12457
  const retakeBtn = (_b = this.overlay) == null ? void 0 : _b.querySelector(".neoface-doc-retake-btn");
12418
12458
  confirmBtn == null ? void 0 : confirmBtn.addEventListener("click", () => this.handleConfirm());
12419
12459
  retakeBtn == null ? void 0 : retakeBtn.addEventListener("click", () => this.handleRetake());
12420
- const previewImg = (_c = this.overlay) == null ? void 0 : _c.querySelector(".neoface-doc-preview-current");
12460
+ const previewImg = (_c = this.overlay) == null ? void 0 : _c.querySelector(
12461
+ ".neoface-doc-preview-current"
12462
+ );
12421
12463
  if (previewImg) {
12422
12464
  const blob = this.currentStep === "preview-front" ? this.frontBlob : this.backBlob;
12423
12465
  if (blob) previewImg.src = URL.createObjectURL(blob);
@@ -12486,8 +12528,8 @@ class DocumentCaptureModal {
12486
12528
  if (loading) loading.style.display = "flex";
12487
12529
  const ctx = this.canvas.getContext("2d");
12488
12530
  if (!ctx) return;
12489
- const videoWidth = this.video.videoWidth;
12490
- const videoHeight = this.video.videoHeight;
12531
+ const { videoWidth } = this.video;
12532
+ const { videoHeight } = this.video;
12491
12533
  const frameWidthPercent = 0.75;
12492
12534
  const frameHeightPercent = 0.65;
12493
12535
  const cropWidth = Math.floor(videoWidth * frameWidthPercent);