easyproctor-hml 2.5.22 → 2.5.24

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/README.md CHANGED
@@ -263,46 +263,17 @@ const {
263
263
  token: "...",
264
264
  });
265
265
  ```
266
+ ## Release Note V 2.4.0
267
+ - Compatibilidade com dispositivos móveis
266
268
 
267
- ## Release Note V 2.5.4
268
- - Fix: Correção sobre as imagens do realtime
269
-
270
- ## Release Note V 2.5.4
271
- - Novos alertas de tela (Clipboard, SplitScreen)
272
- - Ajustes na detecção de foco da tela
273
- - Melhorias na analise biométrica
274
- - Melhorias na analise do uso de dispositivos
275
- - Correção do uso de câmera externa no ambiente de produção
276
-
277
- ## Release Note V 2.5.3
278
- - Fix: Resolução do video
279
- - Melhorias no proctoring do tipo REALTIME
280
-
281
- ## Release Note V 2.5.2
282
- - Alteração do nome do callback 'onFinish' para 'onResultAvailable'
283
- - Melhorias no proctoring do tipo REALTIME
284
-
285
- ## Release Note V 2.5.1
286
- - Novos atributos no callback de 'onFinish'
287
- - scoreThreshold: limiar de aprovação da sessão de proctoring
288
- - justification: em caso de reprovação, esse campo traz o resumo das irregularidades
289
-
290
- ## Release Note V 2.5.0
291
- - Callback de 'onFinish' no hook de finish que permite o acesso ao resultado da auditoria de forma imediata
292
- - Melhorias no proctoring em tempo real
293
- - Melhorias no monitoramento ativo durante o exame
294
- - Novos tipos de alertas do onRealtimeAlerts:
295
- - position_detection_on_stream:
296
- - wrong_face_size_detected: Face muito perto da câmera, afaste-se um pouco mais
297
- - wrong_face_position_edge_detected: Face muito próxima da borda, mova-se para o centro da tela
298
- - wrong_face_position_move_right_detected: Face não centralizada, mova-se para a direita
299
- - wrong_face_position_move_top_detected: Face não centralizada, mova-se para cima
300
- - wrong_face_position_move_left_detected: Face não centralizada, mova-se para a esquerda
301
- - wrong_face_position_move_bottom_detected: Face não centralizada, mova-se para baixo
269
+ ## Release Note V 2.3.3
270
+ - Correção do reset no startSession
302
271
 
272
+ ## Release Note V 2.3.2
273
+ - Melhorias no fluxo da câmera externa (reset e goToExternalCameraPositionStep)
303
274
 
304
275
  ## Release Note V 2.4.0
305
- - Compatibilidade com dispositivos móveis
276
+ - Compatibilidade com dispositivos móveis implementada
306
277
 
307
278
  ## Release Note V 2.3.3
308
279
  - Correção do reset no startSession
package/esm/index.js CHANGED
@@ -12267,7 +12267,7 @@ function recorder(stream, buffer, videoOptions, onBufferSizeError = false, onBuf
12267
12267
  let recorderOptions = {
12268
12268
  // eslint-disable-next-line no-useless-escape
12269
12269
  mimeType: "video/webm",
12270
- videoBitsPerSecond: (videoOptions == null ? void 0 : videoOptions.videoBitsPerSecond) || 128e3,
12270
+ videoBitsPerSecond: 128e3,
12271
12271
  audioBitsPerSecond: 64 * 1e3
12272
12272
  };
12273
12273
  if (MediaRecorder.isTypeSupported("video/webm;codecs=vp9")) {
@@ -12280,13 +12280,16 @@ function recorder(stream, buffer, videoOptions, onBufferSizeError = false, onBuf
12280
12280
  if (videoOptions == null ? void 0 : videoOptions.mimeType) {
12281
12281
  recorderOptions.mimeType = videoOptions == null ? void 0 : videoOptions.mimeType;
12282
12282
  }
12283
+ if ((videoOptions == null ? void 0 : videoOptions.videoBitsPerSecond) != void 0) {
12284
+ recorderOptions.videoBitsPerSecond = videoOptions == null ? void 0 : videoOptions.videoBitsPerSecond;
12285
+ }
12283
12286
  if (audio) {
12284
12287
  recorderOptions = {
12285
12288
  mimeType: "audio/webm",
12286
12289
  audioBitsPerSecond: 64 * 1e3
12287
12290
  };
12288
12291
  }
12289
- console.log("recorderOptions bitsPerSecond", recorderOptions.bitsPerSecond);
12292
+ console.log("recorderOptions bitsPerSecond", recorderOptions.videoBitsPerSecond);
12290
12293
  const mediaRecorder = new MediaRecorder(stream, recorderOptions);
12291
12294
  mediaRecorder.ondataavailable = (e3) => {
12292
12295
  bufferSize = bufferSize + e3.data.size;
@@ -12309,6 +12312,7 @@ function recorder(stream, buffer, videoOptions, onBufferSizeError = false, onBuf
12309
12312
  proctoringId,
12310
12313
  `onBufferSizeError: Recorder size equal 0 Mb`
12311
12314
  );
12315
+ console.log("onbuffer size error" + e3.data.size);
12312
12316
  onBufferSizeErrorCallback && onBufferSizeErrorCallback();
12313
12317
  }
12314
12318
  lastEvent = e3;
@@ -12323,8 +12327,19 @@ function recorder(stream, buffer, videoOptions, onBufferSizeError = false, onBuf
12323
12327
  function startRecording() {
12324
12328
  return new Promise((resolve) => {
12325
12329
  resolvePromise = resolve;
12326
- console.log("startRecording", videoOptions == null ? void 0 : videoOptions.timeSlice);
12327
- mediaRecorder.start((videoOptions == null ? void 0 : videoOptions.timeSlice) || 1e4);
12330
+ var timeSlice = 1e4;
12331
+ if ((videoOptions == null ? void 0 : videoOptions.timeSlice) != void 0) {
12332
+ timeSlice = videoOptions == null ? void 0 : videoOptions.timeSlice;
12333
+ }
12334
+ console.log("startRecording", timeSlice);
12335
+ try {
12336
+ mediaRecorder.start(timeSlice);
12337
+ mediaRecorder.onstart = () => {
12338
+ console.log("Grava\xE7\xE3o iniciada com sucesso!");
12339
+ };
12340
+ } catch (e3) {
12341
+ console.error("Falha ao iniciar:", e3);
12342
+ }
12328
12343
  bufferSize = 0;
12329
12344
  stopped = false;
12330
12345
  });
@@ -12335,7 +12350,6 @@ function recorder(stream, buffer, videoOptions, onBufferSizeError = false, onBuf
12335
12350
  resolvePromise = resolve;
12336
12351
  mediaRecorder.stop();
12337
12352
  stopped = true;
12338
- clearInterval(onBufferSizeInterval);
12339
12353
  stream.getTracks().forEach((el) => {
12340
12354
  el.stop();
12341
12355
  });
@@ -12808,6 +12822,7 @@ var CameraRecorder = class {
12808
12822
  const retryEnabled = ((_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.retryEnabled) || false;
12809
12823
  const maxRetries = ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.maxRetries) || 3;
12810
12824
  if (retryEnabled && this.currentRetries < maxRetries) {
12825
+ console.log("buffer error Camera Recorder retry");
12811
12826
  await this.recordingStop();
12812
12827
  await this.startRecording({
12813
12828
  retry: true
@@ -12818,9 +12833,71 @@ var CameraRecorder = class {
12818
12833
  this.options.onBufferSizeErrorCallback && this.options.onBufferSizeErrorCallback();
12819
12834
  }
12820
12835
  }
12836
+ async startStream(options) {
12837
+ var _a2;
12838
+ const { cameraId, microphoneId, onBufferSizeErrorCallback } = this.options;
12839
+ const constraints = {
12840
+ audio: { deviceId: microphoneId },
12841
+ video: {
12842
+ deviceId: cameraId,
12843
+ width: this.videoOptions.width,
12844
+ height: this.videoOptions.height,
12845
+ frameRate: 15
12846
+ }
12847
+ };
12848
+ try {
12849
+ this.hardwareStream = await navigator.mediaDevices.getUserMedia(
12850
+ constraints
12851
+ );
12852
+ } catch (error) {
12853
+ if (error.toString() == "NotReadableError: Could not start video source")
12854
+ throw "N\xE3o foi poss\xEDvel conectar a camera, ela pode estar sendo utilizada por outro programa";
12855
+ throw error;
12856
+ }
12857
+ this.cameraStream = this.hardwareStream;
12858
+ const track = this.cameraStream.getVideoTracks()[0];
12859
+ const settings = track.getSettings();
12860
+ let { width = 0, height = 0 } = settings;
12861
+ const isPortrait = (_a2 = screen.orientation) == null ? void 0 : _a2.type.includes("portrait");
12862
+ if (isPortrait && isMobileDevice()) {
12863
+ if (this.videoOptions.width == height && this.videoOptions.height == width) {
12864
+ [width, height] = [height, width];
12865
+ }
12866
+ }
12867
+ if (this.videoOptions.minWidth > width || this.videoOptions.minHeight > height) {
12868
+ throw STREAM_UNDER_MINIMUM_PERMITTED;
12869
+ } else if (this.videoOptions.width !== width || this.videoOptions.height !== height) {
12870
+ trackers.registerAnotherStream(
12871
+ this.proctoringId,
12872
+ `Maybe have another stream active
12873
+ Video Options: ${JSON.stringify(
12874
+ this.videoOptions,
12875
+ null,
12876
+ 2
12877
+ )}
12878
+ Setting: ${JSON.stringify(settings, null, 2)}`
12879
+ );
12880
+ throw ANOTHER_STREAM_ACTIVE;
12881
+ }
12882
+ }
12883
+ async stopStream() {
12884
+ if (this.cameraStream) {
12885
+ this.cameraStream.getTracks().forEach((track) => track.stop());
12886
+ }
12887
+ if (this.internalClonedStream) {
12888
+ this.internalClonedStream.getTracks().forEach((track) => track.stop());
12889
+ this.internalClonedStream = null;
12890
+ }
12891
+ if (this.hardwareStream) {
12892
+ this.hardwareStream.getTracks().forEach((track) => track.stop());
12893
+ this.hardwareStream = null;
12894
+ }
12895
+ }
12821
12896
  async startRecording(options) {
12822
12897
  var _a2, _b, _c2, _d, _e3, _f, _g, _h;
12898
+ console.log("startRecording Camera Recorder");
12823
12899
  if ((((_a2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _a2.detectPerson) || ((_b = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _b.detectCellPhone) || ((_c2 = this.paramsConfig.videoBehaviourParameters) == null ? void 0 : _c2.detectFace)) && !(options == null ? void 0 : options.retry)) {
12900
+ console.log("startRecording Camera Recorder initializeDetectors");
12824
12901
  await this.initializeDetectors();
12825
12902
  }
12826
12903
  const { cameraId, microphoneId, onBufferSizeErrorCallback } = this.options;
@@ -12838,6 +12915,7 @@ var CameraRecorder = class {
12838
12915
  constraints
12839
12916
  );
12840
12917
  } catch (error) {
12918
+ console.log("startRecording Camera Recorder error", error);
12841
12919
  if (error.toString() == "NotReadableError: Could not start video source")
12842
12920
  throw "N\xE3o foi poss\xEDvel conectar a camera, ela pode estar sendo utilizada por outro programa";
12843
12921
  throw error;
@@ -12868,6 +12946,7 @@ var CameraRecorder = class {
12868
12946
  this.recordingResume = resumeRecording;
12869
12947
  this.recorderOptions = recorderOptions;
12870
12948
  this.getBufferSize = getBufferSize;
12949
+ console.log("startRecording Camera Recorder recordingStart");
12871
12950
  this.recordingStart();
12872
12951
  const isPortrait = (_d = screen.orientation) == null ? void 0 : _d.type.includes("portrait");
12873
12952
  if (isPortrait && isMobileDevice()) {
@@ -12902,6 +12981,7 @@ Setting: ${JSON.stringify(settings, null, 2)}`
12902
12981
  this.captureFrame();
12903
12982
  }
12904
12983
  this.packageCount = 0;
12984
+ console.log("startRecording Camera Recorder finished");
12905
12985
  }
12906
12986
  async stopRecording() {
12907
12987
  this.isCanvasLoopActive = false;
@@ -14220,6 +14300,7 @@ var _DeviceCheckerService = class _DeviceCheckerService {
14220
14300
  return this.deviceCheckResult;
14221
14301
  }
14222
14302
  async runCheckDevicesFlow(options, _videoOptions, onModalConfirm, onModalCancel, onUpdate) {
14303
+ var _a2;
14223
14304
  if (_DeviceCheckerService.isModalOpen) {
14224
14305
  return Promise.reject("Modal j\xE1 est\xE1 aberto");
14225
14306
  }
@@ -14237,7 +14318,9 @@ var _DeviceCheckerService = class _DeviceCheckerService {
14237
14318
  options,
14238
14319
  _videoOptions
14239
14320
  );
14240
- this.checkSpyScan();
14321
+ if ((_a2 = this.options) == null ? void 0 : _a2.useSpyScan) {
14322
+ await this.checkSpyScan();
14323
+ }
14241
14324
  const returnData = { cameraStream: this.cameraRecorder.cameraStream };
14242
14325
  this.onUpdateCb = (e3) => onUpdate(e3);
14243
14326
  const resultPromise = new Promise(
@@ -14292,6 +14375,11 @@ var _DeviceCheckerService = class _DeviceCheckerService {
14292
14375
  if (_DeviceCheckerService.isModalOpen) {
14293
14376
  return Promise.reject();
14294
14377
  }
14378
+ console.log("checkDevices started");
14379
+ this.allowedMicrophone = false;
14380
+ this.allowedResolution = false;
14381
+ this.allowedAmbient = false;
14382
+ this.allowedPositionFace = false;
14295
14383
  _DeviceCheckerService.isModalOpen = true;
14296
14384
  this.DeviceCheckerUI = new DeviceCheckerUI(options, _videoOptions);
14297
14385
  try {
@@ -14329,8 +14417,8 @@ var _DeviceCheckerService = class _DeviceCheckerService {
14329
14417
  resolve(response);
14330
14418
  });
14331
14419
  } catch (error) {
14420
+ this.DeviceCheckerUI && this.DeviceCheckerUI.closeModal();
14332
14421
  this.closeCheckDevices();
14333
- this.DeviceCheckerUI.closeModal();
14334
14422
  return Promise.reject(error);
14335
14423
  }
14336
14424
  }
@@ -14401,7 +14489,7 @@ var _DeviceCheckerService = class _DeviceCheckerService {
14401
14489
  }
14402
14490
  async changeSelectedDevice({ cameraId, microphoneId }) {
14403
14491
  var _a2;
14404
- this.cameraRecorder.stopRecording && await this.cameraRecorder.stopRecording();
14492
+ await this.cameraRecorder.stopStream();
14405
14493
  (_a2 = this.volumeMeter) == null ? void 0 : _a2.stop();
14406
14494
  this.faceDetection.stopDetection();
14407
14495
  this.cameraRecorder = new CameraRecorder(
@@ -14417,7 +14505,7 @@ var _DeviceCheckerService = class _DeviceCheckerService {
14417
14505
  height: this.videoOptions.height
14418
14506
  }
14419
14507
  );
14420
- await this.cameraRecorder.startRecording();
14508
+ await this.cameraRecorder.startStream();
14421
14509
  this.videoDeviceInterface(this.cameraRecorder.cameraStream);
14422
14510
  this.audioDeviceInterface(this.cameraRecorder.cameraStream);
14423
14511
  return {
@@ -14425,6 +14513,10 @@ var _DeviceCheckerService = class _DeviceCheckerService {
14425
14513
  };
14426
14514
  }
14427
14515
  async startCheckDevices(options = getDefaultProctoringOptions, _videoOptions) {
14516
+ this.allowedMicrophone = false;
14517
+ this.allowedResolution = false;
14518
+ this.allowedAmbient = false;
14519
+ this.allowedPositionFace = false;
14428
14520
  this.DeviceCheckerUI && this.DeviceCheckerUI.setSelectOption(
14429
14521
  options,
14430
14522
  (e3) => this.changeSelectedDevice(e3)
@@ -14444,7 +14536,7 @@ var _DeviceCheckerService = class _DeviceCheckerService {
14444
14536
  height: this.videoOptions.height
14445
14537
  }
14446
14538
  );
14447
- await this.cameraRecorder.startRecording();
14539
+ await this.cameraRecorder.startStream();
14448
14540
  this.videoDeviceInterface(this.cameraRecorder.cameraStream);
14449
14541
  this.audioDeviceInterface(this.cameraRecorder.cameraStream);
14450
14542
  if (this.DeviceCheckerUI) {
@@ -14461,7 +14553,7 @@ var _DeviceCheckerService = class _DeviceCheckerService {
14461
14553
  this.faceDetection.stopDetection();
14462
14554
  (_a2 = this.volumeMeter) == null ? void 0 : _a2.stop();
14463
14555
  this.volumeMedia = Math.ceil(this.volumeSum / this.volumeCounter);
14464
- this.cameraRecorder.stopRecording && await this.cameraRecorder.stopRecording();
14556
+ await this.cameraRecorder.stopStream();
14465
14557
  this.DeviceCheckerUI = void 0;
14466
14558
  this.onUpdateCb = void 0;
14467
14559
  }
@@ -14536,7 +14628,9 @@ var CapturePhoto = class {
14536
14628
  );
14537
14629
  await this.cameraRecorder.startRecording();
14538
14630
  cameraContainer.srcObject = this.cameraRecorder.cameraStream;
14539
- cameraContainer.play();
14631
+ cameraContainer.play().catch((e3) => {
14632
+ console.warn("Autoplay bloqueado ou erro ao iniciar v\xEDdeo:", e3);
14633
+ });
14540
14634
  }
14541
14635
  shot() {
14542
14636
  const cameraContainer = document.querySelector("#cameraStream");
@@ -14629,6 +14723,9 @@ var CapturePhoto = class {
14629
14723
  const video = document.createElement("video");
14630
14724
  video.setAttribute("id", "cameraStream");
14631
14725
  video.muted = true;
14726
+ video.setAttribute("playsinline", "true");
14727
+ video.setAttribute("webkit-playsinline", "true");
14728
+ video.autoplay = true;
14632
14729
  divCamera.style.position = "fixed";
14633
14730
  divCamera.style.top = "0";
14634
14731
  divCamera.style.left = "0";
@@ -14815,8 +14912,8 @@ var CapturePhoto = class {
14815
14912
  }
14816
14913
  };
14817
14914
 
14818
- // src/extension/extension.ts
14819
- var Extension = class {
14915
+ // src/extension/extensionEasyProctor.ts
14916
+ var ExtensionEasyProctor = class {
14820
14917
  constructor() {
14821
14918
  this.hasExtension = false;
14822
14919
  this.tryes = 0;
@@ -14861,6 +14958,89 @@ var Extension = class {
14861
14958
  }
14862
14959
  };
14863
14960
 
14961
+ // src/extension/extensionEasyCatcher.ts
14962
+ var ExtensionEasyCatcher = class {
14963
+ constructor(options) {
14964
+ this.hasExtension = false;
14965
+ this.tryes = 0;
14966
+ this.responseStart = false;
14967
+ this.options = options || {};
14968
+ }
14969
+ /**
14970
+ * Verifica se a extensão está instalada e ativa.
14971
+ * Retorna o número da versão se encontrada, ou lança erro após timeout.
14972
+ */
14973
+ checkExtensionInstalled(timeoutMs = 2e3) {
14974
+ return new Promise((resolve, reject) => {
14975
+ let handled = false;
14976
+ const handler = (event) => {
14977
+ if (event.source === window && event.data.sender === "easyproctor-extension" && event.data.message_name === "version") {
14978
+ handled = true;
14979
+ window.removeEventListener("message", handler);
14980
+ resolve(event.data.message);
14981
+ }
14982
+ };
14983
+ window.addEventListener("message", handler);
14984
+ window.postMessage({
14985
+ type: "easycatcher",
14986
+ func: "verifyExtensionEasycatcher"
14987
+ }, "*");
14988
+ setTimeout(() => {
14989
+ if (!handled) {
14990
+ window.removeEventListener("message", handler);
14991
+ reject(new Error("Extens\xE3o n\xE3o detectada ou n\xE3o respondeu."));
14992
+ }
14993
+ }, timeoutMs);
14994
+ });
14995
+ }
14996
+ /**
14997
+ * Solicita o JSON da sessão atual capturado pela extensão.
14998
+ */
14999
+ getSessionData(timeoutMs = 5e3) {
15000
+ return new Promise((resolve, reject) => {
15001
+ let handled = false;
15002
+ const handler = (event) => {
15003
+ if (event.source === window && event.data.sender === "easyproctor-extension" && event.data.message_name === "data_response") {
15004
+ handled = true;
15005
+ window.removeEventListener("message", handler);
15006
+ resolve(event.data.payload);
15007
+ }
15008
+ };
15009
+ window.addEventListener("message", handler);
15010
+ window.postMessage({
15011
+ type: "easycatcher",
15012
+ func: "getDataExtensionEasycatcher"
15013
+ }, "*");
15014
+ setTimeout(() => {
15015
+ if (!handled) {
15016
+ window.removeEventListener("message", handler);
15017
+ reject(new Error("Timeout ao aguardar dados da extens\xE3o."));
15018
+ }
15019
+ }, timeoutMs);
15020
+ });
15021
+ }
15022
+ start() {
15023
+ return new Promise((resolve, reject) => {
15024
+ let handled = false;
15025
+ const handler = (event) => {
15026
+ if (event.source === window && event.data.sender === "easyproctor-extension" && event.data.message_name === "started_confirmed") {
15027
+ handled = true;
15028
+ window.removeEventListener("message", handler);
15029
+ resolve(true);
15030
+ }
15031
+ };
15032
+ window.addEventListener("message", handler);
15033
+ window.postMessage({ type: "easycatcher", func: "startExtensionEasycatcher" }, "*");
15034
+ setTimeout(() => {
15035
+ if (!handled) {
15036
+ window.removeEventListener("message", handler);
15037
+ reject(new Error("Timeout: Extens\xE3o n\xE3o confirmou o in\xEDcio."));
15038
+ }
15039
+ }, 3e3);
15040
+ });
15041
+ }
15042
+ };
15043
+
14864
15044
  // src/modules/onChangeDevices.ts
14865
15045
  var onChangeDevices = class {
14866
15046
  constructor(repositoryDevices, proctoringId2, sessionOptions, allRecorders) {
@@ -20958,6 +21138,7 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
20958
21138
  this.connection = null;
20959
21139
  this.context = context;
20960
21140
  this.onRealtimeAlertsCallback = onRealtimeAlertsCallback;
21141
+ console.log("context -> ", context);
20961
21142
  this.backend = new BackendService({
20962
21143
  type: (context == null ? void 0 : context.type) || "prod",
20963
21144
  token: context.token
@@ -20971,6 +21152,7 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
20971
21152
  try {
20972
21153
  this.transmissionOk = false;
20973
21154
  const response = await this.backend.externalCameraCheckTransmission("" + this.externalSessionId);
21155
+ console.log(response);
20974
21156
  let attempts = 0;
20975
21157
  while (!this.transmissionOk && attempts <= 5) {
20976
21158
  await new Promise((resolve) => setTimeout(resolve, 2e3));
@@ -20987,13 +21169,16 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
20987
21169
  try {
20988
21170
  this.proctoringId = proctoringId2;
20989
21171
  const response = await this.backend.externalCameraStartTransmission("" + this.externalSessionId, proctoringId2);
21172
+ console.log(response);
20990
21173
  } catch (error) {
21174
+ console.error("Erro ao iniciar transmiss\xE3o:", error);
20991
21175
  throw new Error("N\xE3o foi poss\xEDvel iniciar a transmiss\xE3o.");
20992
21176
  }
20993
21177
  }
20994
21178
  async goToPositionGuide() {
20995
21179
  try {
20996
21180
  const response = await this.backend.goToExternalCameraPositionStep("" + this.externalSessionId);
21181
+ console.log(response);
20997
21182
  } catch (error) {
20998
21183
  console.error("Erro ao enviar comando de Position:", error);
20999
21184
  throw new Error("N\xE3o foi poss\xEDvel enviar comando de Position Guide.");
@@ -21003,6 +21188,7 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
21003
21188
  if (this.connection) {
21004
21189
  const actionMessage = new ActionMessage();
21005
21190
  actionMessage.command = "Reset";
21191
+ console.log("Enviando comando 'Reset' para o aplicativo...");
21006
21192
  this.connection.invoke(
21007
21193
  "SendAction",
21008
21194
  this.externalSessionId,
@@ -21016,6 +21202,7 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
21016
21202
  this.onTakePictureCallback = onTakePictureCallback;
21017
21203
  const actionMessage = new ActionMessage();
21018
21204
  actionMessage.command = "Capture";
21205
+ console.log("Enviando comando 'Capture' para o aplicativo...");
21019
21206
  this.connection.invoke(
21020
21207
  "SendAction",
21021
21208
  this.externalSessionId,
@@ -21034,6 +21221,7 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
21034
21221
  await this.reset();
21035
21222
  const response = await this.backend.externalCameraStartSession();
21036
21223
  this.externalSessionId = response.externalSessionId;
21224
+ console.log(this.externalSessionId);
21037
21225
  this.currentStep = 0 /* STARTED */;
21038
21226
  const pairingObject = {
21039
21227
  externalSessionId: this.externalSessionId,
@@ -21042,6 +21230,7 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
21042
21230
  };
21043
21231
  const pairingDataString = JSON.stringify(pairingObject);
21044
21232
  this.qrCodeBase64Image = await import_qrcode.default.toDataURL(pairingDataString);
21233
+ console.log(this.qrCodeBase64Image);
21045
21234
  return this.qrCodeBase64Image;
21046
21235
  } catch (error) {
21047
21236
  this.disconnectWebSocket();
@@ -21140,6 +21329,7 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
21140
21329
  var _a2;
21141
21330
  const actionMessage = new ActionMessage();
21142
21331
  actionMessage.command = "Cancel";
21332
+ console.log("Enviando comando 'Cancel' para o aplicativo...");
21143
21333
  (_a2 = this.connection) == null ? void 0 : _a2.invoke(
21144
21334
  "SendAction",
21145
21335
  this.externalSessionId,
@@ -21479,6 +21669,8 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
21479
21669
  this.connection.on(
21480
21670
  "ReceiveMessage",
21481
21671
  (sessionId, messageStr) => {
21672
+ console.log("sessionId: ", sessionId);
21673
+ console.log("Message: ", messageStr);
21482
21674
  if (sessionId !== this.externalSessionId) {
21483
21675
  console.warn("Sess\xE3o diferente!");
21484
21676
  return;
@@ -21486,6 +21678,7 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
21486
21678
  try {
21487
21679
  const messageKey = messageStr;
21488
21680
  const message = ExternalCameraStatusEnum[messageKey];
21681
+ console.log("Mensagem -> ", message);
21489
21682
  this.handleWebSocketMessage(message);
21490
21683
  } catch (e3) {
21491
21684
  console.error("Erro ao processar mensagem do WebSocket:", e3);
@@ -21495,6 +21688,8 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
21495
21688
  this.connection.on(
21496
21689
  "ReceiveAction",
21497
21690
  (sessionId, actionMessage) => {
21691
+ console.log("sessionId: ", sessionId);
21692
+ console.log("Message: ", actionMessage);
21498
21693
  if (sessionId !== this.externalSessionId) {
21499
21694
  console.warn("Sess\xE3o diferente!");
21500
21695
  return;
@@ -21508,6 +21703,7 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
21508
21703
  );
21509
21704
  try {
21510
21705
  await this.connection.start();
21706
+ console.log("Conectado ao Hub SignalR com sucesso!");
21511
21707
  } catch (err) {
21512
21708
  console.error("Falha ao conectar ou entrar no grupo do SignalR: ", err);
21513
21709
  throw new Error("N\xE3o foi poss\xEDvel conectar ao servi\xE7o em tempo real.");
@@ -21634,6 +21830,7 @@ var _ExternalCameraChecker = class _ExternalCameraChecker {
21634
21830
  if (this.connection) {
21635
21831
  try {
21636
21832
  await this.connection.stop();
21833
+ console.log("Desconectado do SignalR.");
21637
21834
  } catch (err) {
21638
21835
  console.error("Erro ao desconectar do SignalR:", err);
21639
21836
  } finally {
@@ -21667,6 +21864,7 @@ var Proctoring = class {
21667
21864
  constructor(context) {
21668
21865
  this.context = context;
21669
21866
  this.deviceData = null;
21867
+ this.sessionStartTime = 0;
21670
21868
  this.paramsConfig = {
21671
21869
  audioBehaviourParameters: {
21672
21870
  recordingBitrate: 128,
@@ -21944,7 +22142,10 @@ var Proctoring = class {
21944
22142
  if (this.context.token === void 0) {
21945
22143
  throw TOKEN_MISSING;
21946
22144
  }
21947
- this.extension = new Extension();
22145
+ if (options.useChallenge) {
22146
+ this.extensionEasycatcher = new ExtensionEasyCatcher();
22147
+ }
22148
+ this.extension = new ExtensionEasyProctor();
21948
22149
  this.extension.addEventListener();
21949
22150
  const baseURL = this.backend.selectBaseUrl(this.context.type);
21950
22151
  const devices = await enumarateDevices();
@@ -21993,6 +22194,7 @@ var Proctoring = class {
21993
22194
  } catch (error) {
21994
22195
  throw EXTERNAL_CAMERA_NOT_STARTED;
21995
22196
  }
22197
+ this.sessionStartTime = Date.now();
21996
22198
  this.allRecorders.cameraRecorder.setProctoringId(this.proctoringId);
21997
22199
  this.allRecorders.noiseRecorder.setProctoringId(this.proctoringId);
21998
22200
  this.proctoringSession.setProctoringId(this.proctoringId);
@@ -22168,6 +22370,7 @@ Upload Services: ${uploaderServices}`,
22168
22370
  });
22169
22371
  if (this.appChecker) {
22170
22372
  const externalSessionId = this.appChecker.getExternalCameraSessionId();
22373
+ console.log("externalSessionId -> ", externalSessionId);
22171
22374
  if (externalSessionId != "null") {
22172
22375
  await this.backend.externalCameraFinish(externalSessionId);
22173
22376
  }
@@ -22290,6 +22493,59 @@ Error: ` + error
22290
22493
  _screenStream: (_a2 = this.allRecorders.screenRecorder) == null ? void 0 : _a2.screenStream
22291
22494
  };
22292
22495
  }
22496
+ async startChallenge(templateId) {
22497
+ if (!this.sessionOptions.useChallenge) {
22498
+ throw new Error("useChallenge is set as false on start method");
22499
+ }
22500
+ await this.extensionEasycatcher.checkExtensionInstalled().catch((err) => {
22501
+ throw new Error("EasyCatcher Extension is not installed");
22502
+ });
22503
+ this.extensionEasycatcher.start();
22504
+ const start = Date.now() - this.sessionStartTime;
22505
+ await this.backend.startChallenge({
22506
+ proctoringId: this.proctoringId,
22507
+ templateId,
22508
+ start
22509
+ }).then((resp) => {
22510
+ console.log(resp);
22511
+ this.challengeId = resp.id;
22512
+ }).catch((reason) => {
22513
+ trackers.registerError(
22514
+ this.proctoringId,
22515
+ "N\xE3o foi poss\xEDvel iniciar desafio!"
22516
+ );
22517
+ throw reason;
22518
+ });
22519
+ this.isChallengeRunning = true;
22520
+ }
22521
+ async stopChallenge() {
22522
+ if (!this.isChallengeRunning) {
22523
+ throw new Error("Challenge not started");
22524
+ }
22525
+ try {
22526
+ const sessionData = await this.extensionEasycatcher.getSessionData();
22527
+ const end = Date.now() - this.sessionStartTime;
22528
+ await this.backend.stopChallenge(
22529
+ this.challengeId,
22530
+ {
22531
+ end,
22532
+ data: sessionData
22533
+ }
22534
+ ).catch((reason) => {
22535
+ trackers.registerError(
22536
+ this.proctoringId,
22537
+ "N\xE3o foi poss\xEDvel finalizar o desafio no backend!"
22538
+ );
22539
+ return void 0;
22540
+ });
22541
+ this.isChallengeRunning = false;
22542
+ } catch (error) {
22543
+ trackers.registerError(
22544
+ this.proctoringId,
22545
+ "Erro ao recuperar dados da extens\xE3o: " + error.message
22546
+ );
22547
+ }
22548
+ }
22293
22549
  };
22294
22550
 
22295
22551
  // src/proctoring/SignTerm.ts
@@ -22517,6 +22773,8 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
22517
22773
  return originalStart(parameters2, videoOptions);
22518
22774
  };
22519
22775
  const finish = proctoring.finish.bind(proctoring);
22776
+ const startChallenge = proctoring.startChallenge.bind(proctoring);
22777
+ const stopChallenge = proctoring.stopChallenge.bind(proctoring);
22520
22778
  const pause = proctoring.pause.bind(proctoring);
22521
22779
  const resume = proctoring.resume.bind(proctoring);
22522
22780
  const onFocus = proctoring.setOnFocusCallback.bind(proctoring);
@@ -22539,6 +22797,8 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
22539
22797
  login,
22540
22798
  start,
22541
22799
  finish,
22800
+ startChallenge,
22801
+ stopChallenge,
22542
22802
  onFocus,
22543
22803
  onLostFocus,
22544
22804
  onChangeDevices: onChangeDevices2,
@@ -0,0 +1,11 @@
1
+ import { ProctoringFinisherOptions } from "../proctoring/proctoring";
2
+ export declare class ExtensionEasyCatcher {
3
+ hasExtension: boolean;
4
+ tryes: number;
5
+ responseStart: boolean;
6
+ options: ProctoringFinisherOptions;
7
+ constructor(options?: ProctoringFinisherOptions);
8
+ checkExtensionInstalled(timeoutMs?: number): Promise<string>;
9
+ getSessionData(timeoutMs?: number): Promise<any>;
10
+ start(): Promise<boolean>;
11
+ }
@@ -1,5 +1,5 @@
1
1
  import { ProctoringFinisherOptions } from "../proctoring/proctoring";
2
- export declare class Extension {
2
+ export declare class ExtensionEasyProctor {
3
3
  hasExtension: boolean;
4
4
  tryes: number;
5
5
  responseStart: boolean;