easyproctor 2.5.2 → 2.5.3

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,6 +263,9 @@ const {
263
263
  token: "...",
264
264
  });
265
265
  ```
266
+ ## Release Note V 2.5.3
267
+ - Fix: Resolução do video
268
+ - Melhorias no proctoring do tipo REALTIME
266
269
 
267
270
  ## Release Note V 2.5.2
268
271
  - Alteração do nome do callback 'onFinish' para 'onResultAvailable'
package/esm/index.js CHANGED
@@ -8791,6 +8791,14 @@ var BaseDetection = class {
8791
8791
  return "Face n\xE3o centralizada, mova-se para cima";
8792
8792
  case "wrong_face_position_move_bottom_detected":
8793
8793
  return "Face n\xE3o centralizada, mova-se para baixo";
8794
+ case "face_turned_left_detected":
8795
+ return "Face virada para a esquerda, centralize-a";
8796
+ case "face_turned_right_detected":
8797
+ return "Face virada para a direita, centralize-a";
8798
+ case "face_turned_up_detected":
8799
+ return "Face virada para cima, centralize-a";
8800
+ case "face_turned_down_detected":
8801
+ return "Face virada para baixo, centralize-a";
8794
8802
  default:
8795
8803
  return description;
8796
8804
  }
@@ -8821,7 +8829,14 @@ function buildVideoPreview() {
8821
8829
  // src/modules/faceDetection.ts
8822
8830
  var FaceDetection = class extends BaseDetection {
8823
8831
  constructor(options, paramsConfig, classVideo = "videoPreviewFrameDetection", classDiv = "liveViewFrameDetection") {
8824
- super("FaceDetector", `https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_short_range/float16/1/blaze_face_short_range.tflite`, options, paramsConfig, classVideo, classDiv);
8832
+ super(
8833
+ "FaceDetector",
8834
+ `https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_short_range/float16/1/blaze_face_short_range.tflite`,
8835
+ options,
8836
+ paramsConfig,
8837
+ classVideo,
8838
+ classDiv
8839
+ );
8825
8840
  this.emmitedPositionAlert = false;
8826
8841
  this.emmitedFaceAlert = false;
8827
8842
  }
@@ -8967,8 +8982,8 @@ var FaceDetection = class extends BaseDetection {
8967
8982
  for (const keypoint of detection.keypoints) {
8968
8983
  const keypointEl = document.createElement("span");
8969
8984
  keypointEl.className = "key-point";
8970
- let kpX = keypoint.x < 2 ? keypoint.x * videoElement.videoWidth : keypoint.x;
8971
- let kpY = keypoint.y < 2 ? keypoint.y * videoElement.videoHeight : keypoint.y;
8985
+ const kpX = keypoint.x < 2 ? keypoint.x * videoElement.videoWidth : keypoint.x;
8986
+ const kpY = keypoint.y < 2 ? keypoint.y * videoElement.videoHeight : keypoint.y;
8972
8987
  const mirroredKpX = videoElement.videoWidth - kpX;
8973
8988
  const screenX = mirroredKpX * scaleX;
8974
8989
  const screenY = kpY * scaleY;
@@ -9007,55 +9022,87 @@ var FaceDetection = class extends BaseDetection {
9007
9022
  }
9008
9023
  }
9009
9024
  if (result.detections.length === 0) return;
9010
- let face = result.detections[0].boundingBox;
9011
- let video = document.getElementById(this.classVideo);
9025
+ let failedFacePosition = false;
9026
+ const video = document.getElementById(this.classVideo);
9012
9027
  const imageWidth = video.videoWidth;
9013
9028
  const imageHeight = video.videoHeight;
9014
- let failedFacePosition = false;
9029
+ const detection = result.detections[0];
9030
+ const face = detection.boundingBox;
9031
+ const keypoints = detection.keypoints;
9032
+ const rightEye = keypoints[0];
9033
+ const leftEye = keypoints[1];
9034
+ const mouth = keypoints[3];
9035
+ const rightEar = keypoints[4];
9036
+ const leftEar = keypoints[5];
9037
+ const nose = keypoints[2];
9015
9038
  if (imageWidth > imageHeight) {
9016
9039
  if (face.height / imageHeight > 0.7) {
9017
- !this.emmitedPositionAlert && this.handleAlert("wrong_face_size_detected", "position_detection_on_stream");
9040
+ !this.emmitedPositionAlert && this.handleAlert(
9041
+ "wrong_face_size_detected",
9042
+ "position_detection_on_stream"
9043
+ );
9018
9044
  failedFacePosition = true;
9019
9045
  this.emmitedPositionAlert = true;
9020
9046
  } else if (face.width / imageWidth > 0.7) {
9021
- !this.emmitedPositionAlert && this.handleAlert("wrong_face_size_detected", "position_detection_on_stream");
9047
+ !this.emmitedPositionAlert && this.handleAlert(
9048
+ "wrong_face_size_detected",
9049
+ "position_detection_on_stream"
9050
+ );
9022
9051
  this.emmitedPositionAlert = true;
9023
9052
  failedFacePosition = true;
9024
9053
  }
9025
9054
  }
9026
- let start = [face.originX, face.originY];
9027
- let end = [face.originX + face.width, face.originY + face.height];
9055
+ const start = [face.originX, face.originY];
9056
+ const end = [face.originX + face.width, face.originY + face.height];
9028
9057
  if (start[0] < 0.1 * face.width || start[1] < 0.2 * face.height || end[0] > imageWidth - 0.1 * face.width || end[1] > imageHeight - 5) {
9029
- !this.emmitedPositionAlert && this.handleAlert("wrong_face_position_edge_detected", "position_detection_on_stream");
9058
+ !this.emmitedPositionAlert && this.handleAlert(
9059
+ "wrong_face_position_edge_detected",
9060
+ "position_detection_on_stream"
9061
+ );
9030
9062
  this.emmitedPositionAlert = true;
9031
9063
  failedFacePosition = true;
9032
9064
  }
9033
- let leftGap = start[0];
9034
- let rightGap = imageWidth - end[0];
9035
- let topGap = start[1];
9036
- let bottomGap = imageHeight - end[1];
9065
+ const leftGap = start[0];
9066
+ const rightGap = imageWidth - end[0];
9067
+ const topGap = start[1];
9068
+ const bottomGap = imageHeight - end[1];
9037
9069
  if (leftGap > 2 * rightGap) {
9038
- !this.emmitedPositionAlert && this.handleAlert("wrong_face_position_move_right_detected", "position_detection_on_stream");
9070
+ !this.emmitedPositionAlert && this.handleAlert(
9071
+ "wrong_face_position_move_right_detected",
9072
+ "position_detection_on_stream"
9073
+ );
9039
9074
  this.emmitedPositionAlert = true;
9040
9075
  failedFacePosition = true;
9041
9076
  }
9042
9077
  if (topGap > 4 * bottomGap) {
9043
- !this.emmitedPositionAlert && this.handleAlert("wrong_face_position_move_top_detected", "position_detection_on_stream");
9078
+ !this.emmitedPositionAlert && this.handleAlert(
9079
+ "wrong_face_position_move_top_detected",
9080
+ "position_detection_on_stream"
9081
+ );
9044
9082
  this.emmitedPositionAlert = true;
9045
9083
  failedFacePosition = true;
9046
9084
  }
9047
9085
  if (rightGap > 2 * leftGap) {
9048
- !this.emmitedPositionAlert && this.handleAlert("wrong_face_position_move_left_detected", "position_detection_on_stream");
9086
+ !this.emmitedPositionAlert && this.handleAlert(
9087
+ "wrong_face_position_move_left_detected",
9088
+ "position_detection_on_stream"
9089
+ );
9049
9090
  this.emmitedPositionAlert = true;
9050
9091
  failedFacePosition = true;
9051
9092
  }
9052
9093
  if (bottomGap > 3 * topGap) {
9053
- !this.emmitedPositionAlert && this.handleAlert("wrong_face_position_move_bottom_detected", "position_detection_on_stream");
9094
+ !this.emmitedPositionAlert && this.handleAlert(
9095
+ "wrong_face_position_move_bottom_detected",
9096
+ "position_detection_on_stream"
9097
+ );
9054
9098
  this.emmitedPositionAlert = true;
9055
9099
  failedFacePosition = true;
9056
9100
  }
9057
9101
  if (failedFacePosition == false) {
9058
- this.emmitedPositionAlert && this.handleOk("ok_position_face_detected", "position_detection_on_stream");
9102
+ this.emmitedPositionAlert && this.handleOk(
9103
+ "ok_position_face_detected",
9104
+ "position_detection_on_stream"
9105
+ );
9059
9106
  this.emmitedPositionAlert = false;
9060
9107
  }
9061
9108
  }
@@ -11772,12 +11819,12 @@ var BackendService = class {
11772
11819
  });
11773
11820
  return result.data;
11774
11821
  }
11775
- async verifyFace(proctoringId2, faceImage) {
11822
+ async verifyFace(proctoringId2, faceImage, retry) {
11776
11823
  const result = await this.makeRequestAxios({
11777
11824
  path: `/Realtime/verify-face`,
11778
11825
  method: "POST",
11779
11826
  jwt: this.token,
11780
- body: { "proctoringId": proctoringId2, "base64": faceImage }
11827
+ body: { "proctoringId": proctoringId2, "base64": faceImage, "retry": retry }
11781
11828
  });
11782
11829
  return result.data;
11783
11830
  }
@@ -12653,7 +12700,6 @@ var CameraRecorder = class {
12653
12700
  noiseLimit: 40
12654
12701
  },
12655
12702
  imageBehaviourParameters: {
12656
- frames: 40,
12657
12703
  useUploadImage: true,
12658
12704
  uploadInterval: 20,
12659
12705
  saveVideo: true
@@ -12665,7 +12711,6 @@ var CameraRecorder = class {
12665
12711
  }
12666
12712
  };
12667
12713
  // private imageParams: ImageParameters = {
12668
- // frames: 40,
12669
12714
  // useUploadImage: true,
12670
12715
  // uploadInterval: 20,
12671
12716
  // saveVideo: true
@@ -13574,8 +13619,20 @@ var DeviceCheckerUI = class {
13574
13619
  );
13575
13620
  checkmark_FacePosition.appendChild(checkmark_stem_FacePosition);
13576
13621
  checkmark_FacePosition.appendChild(checkmark_kick_FacePosition);
13622
+ const info_FacePosition = document.createElement("span");
13623
+ const info_stem_FacePosition = document.createElement("div");
13624
+ const info_kick_FacePosition = document.createElement("div");
13625
+ info_FacePosition.style.marginLeft = "10px";
13626
+ info_FacePosition.setAttribute("class", "info");
13627
+ info_FacePosition.setAttribute("id", "info_FacePosition");
13628
+ info_FacePosition.style.display = "none";
13629
+ info_stem_FacePosition.setAttribute("class", "info_stem");
13630
+ info_kick_FacePosition.setAttribute("class", "info_kick");
13631
+ info_FacePosition.appendChild(info_stem_FacePosition);
13632
+ info_FacePosition.appendChild(info_kick_FacePosition);
13577
13633
  alertDivFacePosition.appendChild(checkmark_FacePosition);
13578
13634
  alertDivFacePosition.appendChild(facePositionAlert);
13635
+ alertDivFacePosition.appendChild(info_FacePosition);
13579
13636
  const alertDivAmbientVerify = document.createElement("div");
13580
13637
  alertDivAmbientVerify.setAttribute("class", "alert-div");
13581
13638
  alertDivAmbientVerify.setAttribute("id", "alertDivAmbientVerify");
@@ -13906,6 +13963,8 @@ var DeviceCheckerUI = class {
13906
13963
  realtimeAlertsUI(response) {
13907
13964
  const facePositionAlert = document.getElementById("facePositionAlert");
13908
13965
  const ambientVerifyAlert = document.getElementById("ambientVerifyAlert");
13966
+ const alertDivFacePosition = document.getElementById("alertDivFacePosition");
13967
+ const info_FacePosition = document.getElementById("info_FacePosition");
13909
13968
  const checkmark_FacePosition = document.getElementById("checkmark_FacePosition");
13910
13969
  const checkmark_stem_FacePosition = document.getElementById("checkmark_stem_FacePosition");
13911
13970
  const checkmark_kick_FacePosition = document.getElementById("checkmark_kick_FacePosition");
@@ -13916,6 +13975,8 @@ var DeviceCheckerUI = class {
13916
13975
  if (response.status === "OK") {
13917
13976
  facePositionAlert && (facePositionAlert.style.color = "#16A34A");
13918
13977
  ambientVerifyAlert && (ambientVerifyAlert.style.color = "#16A34A");
13978
+ alertDivFacePosition && alertDivFacePosition.setAttribute("title", ``);
13979
+ info_FacePosition && (info_FacePosition.style.display = "none");
13919
13980
  alertDivAmbientVerify && alertDivAmbientVerify.setAttribute("title", ``);
13920
13981
  if (checkmark_FacePosition) {
13921
13982
  checkmark_FacePosition.setAttribute("class", "checkmark");
@@ -13930,6 +13991,8 @@ var DeviceCheckerUI = class {
13930
13991
  } else {
13931
13992
  if (checkmark_FacePosition && (response.type === "position_detection_on_stream" || response.type === "face_detection_on_stream")) {
13932
13993
  facePositionAlert && (facePositionAlert.style.color = "#FF0000");
13994
+ info_FacePosition && (info_FacePosition.style.display = "block");
13995
+ alertDivFacePosition && alertDivFacePosition.setAttribute("title", response.description);
13933
13996
  checkmark_FacePosition.setAttribute("class", "checkmark_error");
13934
13997
  checkmark_stem_FacePosition.setAttribute("class", "checkmark_stem_error");
13935
13998
  checkmark_kick_FacePosition.setAttribute("class", "checkmark_kick_error");
@@ -15040,64 +15103,186 @@ var ProctoringUploader = class {
15040
15103
  var AlertRecorder = class {
15041
15104
  constructor(options, optionsProctoring) {
15042
15105
  this.alerts = [];
15106
+ // Variáveis para controle de inatividade
15107
+ this.lastActivityTime = Date.now();
15108
+ this.IDLE_THRESHOLD_MS = 3e4;
15109
+ // ==========================================
15110
+ // HANDLERS (Funções Arrow para preservar o 'this')
15111
+ // ==========================================
15112
+ // 1. LOST / RETURN FOCUS
15113
+ this.handleLostFocus = () => {
15114
+ if (this.getRelativeTime() > 1e4) {
15115
+ const alertPayload = {
15116
+ begin: this.getRelativeTime(),
15117
+ end: 0,
15118
+ alert: 25 /* FocusOff */,
15119
+ type: 3 /* Screen */
15120
+ };
15121
+ this.onLostFocusCallback(alertPayload);
15122
+ this.alerts.push(alertPayload);
15123
+ }
15124
+ };
15125
+ this.handleReturnFocus = () => {
15126
+ const lastAlert = this.alerts[this.alerts.length - 1];
15127
+ if (lastAlert) {
15128
+ this.onFocusCallback({
15129
+ begin: lastAlert.begin,
15130
+ end: this.getRelativeTime(),
15131
+ alert: 25 /* FocusOff */,
15132
+ type: 3 /* Screen */
15133
+ });
15134
+ lastAlert.end = this.getRelativeTime();
15135
+ }
15136
+ };
15137
+ // 2. SPLIT SCREEN DETECTION
15138
+ this.handleResize = () => {
15139
+ clearTimeout(this.resizeTimeout);
15140
+ this.resizeTimeout = setTimeout(() => {
15141
+ const screenWidth = window.screen.availWidth;
15142
+ const windowWidth = window.outerWidth;
15143
+ if (windowWidth < screenWidth * 0.85) {
15144
+ const msg = `Split Screen Detectado: Janela ocupa ${(windowWidth / screenWidth * 100).toFixed(0)}% da tela`;
15145
+ this.createAlert(200 /* System */, 3 /* Screen */, msg);
15146
+ this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
15147
+ status: "ALERT",
15148
+ description: msg,
15149
+ type: "split_screen"
15150
+ });
15151
+ }
15152
+ }, 1e3);
15153
+ };
15154
+ // 3. DETECÇÃO DE INATIVIDADE (NO INPUT)
15155
+ this.handleUserActivity = (e3) => {
15156
+ this.lastActivityTime = Date.now();
15157
+ console.log("\u{1F449} handleUserActivity", e3);
15158
+ };
15159
+ // 5. CLIPBOARD HANDLERS
15160
+ this.handleCopy = (e3) => {
15161
+ e3.preventDefault();
15162
+ const msg = "Tentativa de Copiar (Clipboard)";
15163
+ this.createAlert(100 /* ForbiddenAction */, 6 /* System */, msg);
15164
+ this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
15165
+ status: "ALERT",
15166
+ description: msg,
15167
+ type: "clipboard_copy"
15168
+ });
15169
+ };
15170
+ this.handleCut = (e3) => {
15171
+ e3.preventDefault();
15172
+ const msg = "Tentativa de Recortar (Clipboard)";
15173
+ this.createAlert(100 /* ForbiddenAction */, 6 /* System */, msg);
15174
+ this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
15175
+ status: "ALERT",
15176
+ description: msg,
15177
+ type: "clipboard_cut"
15178
+ });
15179
+ };
15180
+ this.handlePaste = (e3) => {
15181
+ e3.preventDefault();
15182
+ const msg = "Tentativa de Colar (Clipboard)";
15183
+ this.createAlert(100 /* ForbiddenAction */, 6 /* System */, msg);
15184
+ this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
15185
+ status: "ALERT",
15186
+ description: msg,
15187
+ type: "clipboard_paste"
15188
+ });
15189
+ };
15043
15190
  this.onLostFocusCallback = options.onLostFocusCallback;
15044
15191
  this.onFocusCallback = options.onFocusCallback;
15192
+ this.onRealtimeAlertCallback = options.onRealtimeAlertCallback;
15045
15193
  this.optionsProctoring = optionsProctoring;
15046
15194
  }
15047
15195
  async startRecording() {
15048
15196
  this.startTime = new Date(Date.now());
15049
- if (this.optionsProctoring.captureScreen) {
15050
- window.addEventListener("blur", () => this.onLostFocus());
15051
- window.addEventListener("focus", () => this.onReturnFocus());
15052
- }
15197
+ this.alerts = [];
15198
+ this.attachListeners();
15053
15199
  }
15054
15200
  async pauseRecording() {
15055
- window.removeEventListener("blur", () => this.onLostFocus());
15056
- window.removeEventListener("focus", () => this.onReturnFocus());
15201
+ this.detachListeners();
15057
15202
  }
15058
15203
  async resumeRecording() {
15059
- if (this.optionsProctoring.captureScreen) {
15060
- window.addEventListener("blur", () => this.onLostFocus());
15061
- window.addEventListener("focus", () => this.onReturnFocus());
15062
- }
15204
+ this.attachListeners();
15063
15205
  }
15064
15206
  async stopRecording() {
15065
- window.removeEventListener("blur", () => this.onLostFocus());
15066
- window.removeEventListener("focus", () => this.onReturnFocus());
15207
+ this.detachListeners();
15067
15208
  }
15068
15209
  async saveOnSession(session) {
15069
15210
  this.alerts.forEach((alert) => {
15070
15211
  session.addAlert(alert);
15071
15212
  });
15072
15213
  }
15073
- onLostFocus() {
15074
- var _a2;
15075
- if (Date.now() - ((_a2 = this.startTime) == null ? void 0 : _a2.getTime()) > 1e4) {
15076
- this.onLostFocusCallback({
15077
- begin: Date.now() - this.startTime.getTime(),
15078
- end: 0,
15079
- alert: 25 /* FocusOff */,
15080
- type: 3 /* Screen */
15081
- });
15082
- this.alerts.push({
15083
- begin: Date.now() - this.startTime.getTime(),
15084
- end: 0,
15085
- alert: 25 /* FocusOff */,
15086
- type: 3 /* Screen */
15087
- });
15088
- }
15214
+ // ==========================================
15215
+ // GERENCIAMENTO DE LISTENERS
15216
+ // ==========================================
15217
+ attachListeners() {
15218
+ if (this.optionsProctoring.captureScreen) {
15219
+ window.addEventListener("blur", this.handleLostFocus);
15220
+ window.addEventListener("focus", this.handleReturnFocus);
15221
+ window.addEventListener("resize", this.handleResize);
15222
+ window.document.addEventListener("copy", this.handleCopy);
15223
+ window.document.addEventListener("cut", this.handleCut);
15224
+ window.document.addEventListener("paste", this.handlePaste);
15225
+ }
15226
+ }
15227
+ detachListeners() {
15228
+ window.removeEventListener("blur", this.handleLostFocus);
15229
+ window.removeEventListener("focus", this.handleReturnFocus);
15230
+ window.removeEventListener("resize", this.handleResize);
15231
+ window.document.removeEventListener("copy", this.handleCopy);
15232
+ window.document.removeEventListener("cut", this.handleCut);
15233
+ window.document.removeEventListener("paste", this.handlePaste);
15234
+ }
15235
+ // private startIdleChecker() {
15236
+ // this.stopIdleChecker(); // Garante que não tenha duplicação
15237
+ // this.idleCheckInterval = setInterval(() => {
15238
+ // const idleTime = Date.now() - this.lastActivityTime;
15239
+ // if (idleTime > this.IDLE_THRESHOLD_MS) {
15240
+ // // Verifica se já não mandamos esse alerta recentemente para não floodar
15241
+ // const lastAlert = this.alerts[this.alerts.length - 1];
15242
+ // // Se o último alerta não foi de inatividade ou foi há muito tempo, cria novo
15243
+ // if (!lastAlert || lastAlert.alert !== AlertCategory.ForbiddenAction || (this.getRelativeTime() - lastAlert.begin > 5000)) {
15244
+ // const msg = "Usuário inativo por muito tempo";
15245
+ // // Assumindo ForbiddenAction ou outra categoria adequada
15246
+ // this.createAlert(AlertCategory.ForbiddenAction, AlertType.System, msg);
15247
+ // this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
15248
+ // status: 'ALERT',
15249
+ // description: msg,
15250
+ // type: 'user_idle'
15251
+ // });
15252
+ // }
15253
+ // }
15254
+ // }, 5000); // Checa a cada 5 segundos
15255
+ // }
15256
+ // private stopIdleChecker() {
15257
+ // if (this.idleCheckInterval) {
15258
+ // clearInterval(this.idleCheckInterval);
15259
+ // this.idleCheckInterval = null;
15260
+ // }
15261
+ // }
15262
+ // 4. BACKGROUND EVENTS (Eventos disparados manualmente)
15263
+ addBackgroundEvent(description, category = 200 /* System */) {
15264
+ this.createAlert(category, 6 /* System */, description);
15265
+ this.onRealtimeAlertCallback && this.onRealtimeAlertCallback({
15266
+ status: "ALERT",
15267
+ description,
15268
+ type: "background_event"
15269
+ });
15089
15270
  }
15090
- onReturnFocus() {
15091
- const lastAlert = this.alerts[this.alerts.length - 1];
15092
- if (lastAlert) {
15093
- this.onFocusCallback({
15094
- begin: lastAlert.begin,
15095
- end: Date.now() - this.startTime.getTime(),
15096
- alert: 25 /* FocusOff */,
15097
- type: 3 /* Screen */
15098
- });
15099
- lastAlert.end = Date.now() - this.startTime.getTime();
15100
- }
15271
+ // ==========================================
15272
+ // HELPERS
15273
+ // ==========================================
15274
+ getRelativeTime() {
15275
+ return Date.now() - this.startTime.getTime();
15276
+ }
15277
+ createAlert(category, type, description) {
15278
+ this.alerts.push({
15279
+ begin: this.getRelativeTime(),
15280
+ end: this.getRelativeTime(),
15281
+ // Eventos pontuais começam e terminam no mesmo ms (exceto focus)
15282
+ alert: category,
15283
+ type
15284
+ // description: description // Se sua interface Alert suportar descrição, descomente
15285
+ });
15101
15286
  }
15102
15287
  addAlert({ alert, type }) {
15103
15288
  this.alerts.push({
@@ -21520,7 +21705,6 @@ var Proctoring = class {
21520
21705
  noiseLimit: 40
21521
21706
  },
21522
21707
  imageBehaviourParameters: {
21523
- frames: 40,
21524
21708
  useUploadImage: true,
21525
21709
  uploadInterval: 20,
21526
21710
  saveVideo: true
@@ -21738,7 +21922,8 @@ var Proctoring = class {
21738
21922
  const alertRecorder = new AlertRecorder(
21739
21923
  {
21740
21924
  onFocusCallback: (response) => this.onFocusAlertRecorderCallback(response),
21741
- onLostFocusCallback: (response) => this.onLostFocusAlertRecorderCallback(response)
21925
+ onLostFocusCallback: (response) => this.onLostFocusAlertRecorderCallback(response),
21926
+ onRealtimeAlertCallback: (response) => this.onRealtimeAlertsCallback(response)
21742
21927
  },
21743
21928
  options
21744
21929
  );
@@ -21846,11 +22031,23 @@ Navigator: ${JSON.stringify(_navigator2)}`
21846
22031
  startResponse.screenStream = this.allRecorders.screenRecorder.screenStream;
21847
22032
  }
21848
22033
  this.state = "Recording" /* Recording */;
21849
- setTimeout(async () => {
22034
+ let verifyFirstFaceIntervalCount = 0;
22035
+ let verifyingFace = false;
22036
+ this.verifyFirstFaceInterval = setInterval(async () => {
21850
22037
  if (this.sessionOptions.proctoringType === "REALTIME") {
21851
- await this.backend.verifyFace(this.proctoringId, await this.allRecorders.cameraRecorder.getCurrentImageBase64());
22038
+ if (verifyingFace) return;
22039
+ verifyingFace = true;
22040
+ verifyFirstFaceIntervalCount++;
22041
+ try {
22042
+ var response = await this.backend.verifyFace(this.proctoringId, await this.allRecorders.cameraRecorder.getCurrentImageBase64(), verifyFirstFaceIntervalCount > 5 ? false : true);
22043
+ verifyingFace = false;
22044
+ clearInterval(this.verifyFirstFaceInterval);
22045
+ } catch (error) {
22046
+ verifyingFace = false;
22047
+ return;
22048
+ }
21852
22049
  }
21853
- }, 1e3);
22050
+ }, 1500);
21854
22051
  return startResponse;
21855
22052
  } catch (error) {
21856
22053
  console.log(error);
@@ -21987,6 +22184,9 @@ Upload Services: ${uploaderServices}`,
21987
22184
  await this.backend.externalCameraFinish(externalSessionId);
21988
22185
  }
21989
22186
  }
22187
+ if (this.verifyFirstFaceInterval) {
22188
+ clearInterval(this.verifyFirstFaceInterval);
22189
+ }
21990
22190
  this.state = "Stop" /* Stop */;
21991
22191
  } catch (error) {
21992
22192
  await this.cancel();
@@ -22321,12 +22521,12 @@ function useProctoring(proctoringOptions, enviromentConfig = "prod") {
22321
22521
  const photo = new CapturePhoto();
22322
22522
  const login = proctoring.login.bind(proctoring);
22323
22523
  const originalStart = proctoring.start.bind(proctoring);
22324
- const start = async (parameters2) => {
22524
+ const start = async (parameters2, videoOptions) => {
22325
22525
  const deviceResult = checker.getDeviceCheckResult();
22326
22526
  if (deviceResult) {
22327
22527
  proctoring.setDeviceCheckData(deviceResult);
22328
22528
  }
22329
- return originalStart(parameters2);
22529
+ return originalStart(parameters2, videoOptions);
22330
22530
  };
22331
22531
  const finish = proctoring.finish.bind(proctoring);
22332
22532
  const pause = proctoring.pause.bind(proctoring);