@newtonschool/react_proctoring_library 0.0.16 → 0.0.17

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.
@@ -17,8 +17,6 @@ var _utils = require("../utils");
17
17
 
18
18
  var _hooks = require("../hooks");
19
19
 
20
- var _defaults = require("../constants/defaults");
21
-
22
20
  var _permissions = require("./permissions");
23
21
 
24
22
  var _useWebcamData = _interopRequireDefault(require("../hooks/useWebcamData"));
@@ -27,6 +25,8 @@ var _breachUtils = require("../utils/breachUtils");
27
25
 
28
26
  var _webcamMicrophoneUtils = require("../utils/webcamMicrophoneUtils");
29
27
 
28
+ var _defaults = require("../constants/defaults");
29
+
30
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
31
 
32
32
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -53,40 +53,54 @@ const ProctorApp = _ref => {
53
53
  const webcamReference = (0, _react.useRef)(null);
54
54
  const canvasReference = (0, _react.useRef)(null);
55
55
  const screenshareReference = (0, _react.useRef)(null);
56
- const statistics = (0, _react.useRef)(_defaults.INITIAL_STATISTICS);
57
-
58
- const proctorParams = _objectSpread(_objectSpread({}, {
59
- people: true,
60
- tabSwitch: true,
61
- fullscreenExit: true,
62
- lookedAway: true
63
- }), config.proctorParams);
64
-
56
+ const proctorParams = (0, _react.useMemo)(() => _objectSpread(_objectSpread({}, _defaults.defaultConfig), config.proctorParams), [config.proctorParams]);
57
+ const statistics = (0, _react.useRef)((0, _breachUtils.getInitialStats)(proctorParams));
65
58
  const {
66
59
  recurring = false,
67
60
  recurringFetchInterval = 0
68
61
  } = config;
69
62
  const [audioPermission, setAudioPermission] = (0, _react.useState)();
70
63
  const [videoPermission, setVideoPermission] = (0, _react.useState)();
71
- const [screensharePermission, setScreensharePermission] = (0, _react.useState)();
64
+ const [screensharePermission, setScreensharePermission] = (0, _react.useState)(!proctorParams.screenshareSnapshots);
72
65
  const firstFullScreenDone = (0, _react.useRef)(false);
73
66
  const recurringFetchIntervalRef = (0, _react.useRef)(null);
74
67
  const sendScreengrab = (0, _react.useCallback)(async function () {
75
68
  let isBreach = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
76
- let breachData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
77
- const screenshot = await (0, _webcamMicrophoneUtils.captureScreenshot)();
78
- getScreengrab(proctoringIdentifier, screenshot, isBreach, breachData.breachedParam);
79
- }, [getScreengrab, proctoringIdentifier]);
69
+ let breachedParam = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
70
+
71
+ if (proctorParams.screenshareSnapshots) {
72
+ const screenshot = await (0, _webcamMicrophoneUtils.captureScreenshot)();
73
+ getScreengrab(proctoringIdentifier, screenshot, isBreach, breachedParam);
74
+ }
75
+ }, [getScreengrab, proctoringIdentifier, proctorParams.screenshareSnapshots]);
76
+ const sendWebcamSnapshot = (0, _react.useCallback)(function () {
77
+ let isBreach = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
78
+ let breachedParam = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
79
+
80
+ if (proctorParams.webcamSnapshots) {
81
+ const webcamSnapshot = (0, _utils.captureWebcamSnapshot)(webcamReference);
82
+
83
+ if (webcamReference) {
84
+ getWebcamSnapshot(proctoringIdentifier, webcamSnapshot, isBreach, breachedParam);
85
+ }
86
+ }
87
+ }, [proctoringIdentifier, getWebcamSnapshot, proctorParams.webcamSnapshots]);
88
+ const sendProctoredParamValues = (0, _react.useCallback)(function () {
89
+ let isBreach = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
90
+ let breachParam = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
91
+ getProctorParamValues(proctoringIdentifier, statistics.current, isBreach, breachParam);
92
+ }, [proctoringIdentifier, getProctorParamValues]);
93
+ const {
94
+ isFullscreen,
95
+ setFullscreen
96
+ } = (0, _hooks.useFullscreenData)(firstFullScreenDone, proctorParams.fullscreenExit);
97
+ const [userCount, lookedAwayCount] = (0, _useWebcamData.default)(webcamReference, canvasReference, proctorParams);
98
+ const isTabSwitched = !(0, _hooks.usePageVisibility)(proctorParams.tabSwitch) && firstFullScreenDone.current;
80
99
  (0, _react.useEffect)(() => {
81
100
  if (recurring) {
82
101
  recurringFetchIntervalRef.current = setInterval(() => {
83
- getProctorParamValues(proctoringIdentifier, statistics.current, false);
84
- const webcamSnapshot = (0, _utils.captureWebcamSnapshot)(webcamReference);
85
-
86
- if (webcamReference) {
87
- getWebcamSnapshot(proctoringIdentifier, webcamSnapshot, false);
88
- }
89
-
102
+ sendProctoredParamValues();
103
+ sendWebcamSnapshot();
90
104
  sendScreengrab();
91
105
  }, recurringFetchInterval);
92
106
  }
@@ -94,50 +108,34 @@ const ProctorApp = _ref => {
94
108
  return () => {
95
109
  clearInterval(recurringFetchIntervalRef.current);
96
110
  };
97
- }, [recurring, recurringFetchInterval, proctoringIdentifier, getWebcamSnapshot, getProctorParamValues, sendScreengrab]);
98
- const {
99
- isFullscreen,
100
- setFullscreen,
101
- fullScreenExitCount
102
- } = (0, _hooks.useFullscreenData)(firstFullScreenDone);
103
- const [userCount, lookedAwayCount] = (0, _useWebcamData.default)(webcamReference, canvasReference);
104
- const tabSwitchCount = (0, _hooks.useTabSwitchCount)(firstFullScreenDone);
111
+ }, [recurring, recurringFetchInterval, sendProctoredParamValues, sendWebcamSnapshot, sendScreengrab]);
105
112
  (0, _react.useEffect)(() => {
106
113
  const currentStats = {
107
114
  userCount,
108
- tabSwitchCount,
109
- fullScreenExitCount,
115
+ isTabSwitched,
116
+ isFullscreen,
110
117
  lookedAwayCount,
111
118
  isWebcamDataReliable: isWebcamProcessingReliable
112
119
  };
113
- const breachData = (0, _breachUtils.getDataOnBreach)(statistics, currentStats);
120
+ const breachData = (0, _breachUtils.getDataOnBreach)(statistics, currentStats, proctorParams);
121
+ (0, _utils.updateStatistics)(statistics, currentStats, proctorParams);
114
122
 
115
123
  if (breachData) {
116
- getProctorParamValues(breachData.proctoringIdentifier, breachData.data, true, breachData.breachedParam);
117
-
118
- if (breachData.breachedParam === "LOOKED_AWAY_COUNT" || breachData.breachedParam === "USER_COUNT_MAX") {
119
- const webcamSnapshot = (0, _utils.captureWebcamSnapshot)(webcamReference);
120
-
121
- if (webcamSnapshot) {
122
- getWebcamSnapshot(proctoringIdentifier, webcamSnapshot, true, breachData.breachedParam);
123
- }
124
- } else {
125
- sendScreengrab(true, breachData);
126
- }
124
+ sendProctoredParamValues(true, breachData.breachedParam);
125
+ sendWebcamSnapshot(true, breachData.breachedParam);
126
+ sendScreengrab(true, breachData.breachedParam);
127
127
  }
128
-
129
- (0, _utils.updateStatistics)(statistics, currentStats);
130
- }, [userCount, tabSwitchCount, fullScreenExitCount, lookedAwayCount, getProctorParamValues, getWebcamSnapshot, sendScreengrab, proctoringIdentifier]);
128
+ }, [userCount, isTabSwitched, isFullscreen, lookedAwayCount, sendProctoredParamValues, sendWebcamSnapshot, sendScreengrab, proctorParams]);
131
129
  const updateScreensharePermission = (0, _react.useCallback)(() => {
132
130
  (0, _webcamMicrophoneUtils.setupScreensharePermission)(setScreensharePermission, screenshareReference);
133
131
  }, []);
134
-
135
- if (proctoringIdentifier === undefined) {
136
- // todo
137
- return;
138
- }
139
-
140
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isFullscreen && audioPermission && videoPermission && screensharePermission && children, /*#__PURE__*/_react.default.createElement(_permissions.Permission, {
132
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, (0, _breachUtils.showProctoredComponent)(proctorParams, {
133
+ isFullscreen,
134
+ audioPermission,
135
+ videoPermission,
136
+ screensharePermission
137
+ }) && children, /*#__PURE__*/_react.default.createElement(_permissions.Permission, {
138
+ proctorParams: proctorParams,
141
139
  isFullscreen: isFullscreen,
142
140
  audioPermisison: audioPermission,
143
141
  videoPermission: videoPermission,
@@ -145,6 +143,7 @@ const ProctorApp = _ref => {
145
143
  screensharePermission: screensharePermission,
146
144
  updateScreensharePermission: updateScreensharePermission
147
145
  }), /*#__PURE__*/_react.default.createElement(_.ActivityTracker, {
146
+ proctorParams: proctorParams,
148
147
  setAudioPermission: setAudioPermission,
149
148
  setVideoPermission: setVideoPermission,
150
149
  webcamReference: webcamReference,
@@ -7,16 +7,16 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.default = void 0;
9
9
 
10
- require("core-js/modules/es.regexp.exec.js");
11
-
12
- require("core-js/modules/es.string.match.js");
13
-
14
10
  var _react = _interopRequireWildcard(require("react"));
15
11
 
16
12
  var _reactWebcam = _interopRequireDefault(require("react-webcam"));
17
13
 
18
14
  var _utils = require("../../utils");
19
15
 
16
+ var _breachUtils = require("../../utils/breachUtils");
17
+
18
+ var _browserUtils = require("../../utils/browserUtils");
19
+
20
20
  var _webcamMicrophoneUtils = require("../../utils/webcamMicrophoneUtils");
21
21
 
22
22
  require("./index.scss");
@@ -27,10 +27,9 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
27
27
 
28
28
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
29
29
 
30
- const isChrome = !!navigator.userAgent.match(/chrome|chromium/i);
31
-
32
30
  const ActivityTracker = _ref => {
33
31
  let {
32
+ proctorParams,
34
33
  webcamReference,
35
34
  canvasReference,
36
35
  setAudioPermission,
@@ -38,32 +37,34 @@ const ActivityTracker = _ref => {
38
37
  screenshareReference
39
38
  } = _ref;
40
39
  (0, _react.useEffect)(() => {
41
- if (isChrome) {
42
- (0, _webcamMicrophoneUtils.updateVideoPermissions)(setVideoPermission);
43
- (0, _webcamMicrophoneUtils.updateAudioPermissions)(setAudioPermission);
44
- (0, _webcamMicrophoneUtils.getVideoPermissionQuery)().then(status => {
45
- status.onchange = evt => {
46
- (0, _webcamMicrophoneUtils.updateVideoPermissions)(setVideoPermission);
47
- };
48
- }).catch(err => {
49
- console.log("Video Permission", err);
50
- });
51
- (0, _webcamMicrophoneUtils.getAudioPermissionQuery)().then(status => {
52
- status.onchange = evt => {
53
- (0, _webcamMicrophoneUtils.updateAudioPermissions)(setAudioPermission);
54
- };
55
- }).catch(err => {
56
- (0, _webcamMicrophoneUtils.updateAudioPermissions)("Audio Permission", err);
57
- });
40
+ if ((0, _browserUtils.isChrome)()) {
41
+ if ((0, _breachUtils.isWebcamRequired)(proctorParams)) {
42
+ (0, _webcamMicrophoneUtils.updateVideoPermissions)(setVideoPermission);
43
+ (0, _webcamMicrophoneUtils.updateAudioPermissions)(setAudioPermission);
44
+ (0, _webcamMicrophoneUtils.getVideoPermissionQuery)().then(status => {
45
+ status.onchange = evt => {
46
+ (0, _webcamMicrophoneUtils.updateVideoPermissions)(setVideoPermission);
47
+ };
48
+ }).catch(err => {
49
+ console.log("Video Permission", err);
50
+ });
51
+ (0, _webcamMicrophoneUtils.getAudioPermissionQuery)().then(status => {
52
+ status.onchange = evt => {
53
+ (0, _webcamMicrophoneUtils.updateAudioPermissions)(setAudioPermission);
54
+ };
55
+ }).catch(err => {
56
+ (0, _webcamMicrophoneUtils.updateAudioPermissions)("Audio Permission", err);
57
+ });
58
+ }
58
59
  }
59
- }, [setVideoPermission, setAudioPermission]);
60
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactWebcam.default, {
60
+ }, [setVideoPermission, setAudioPermission, proctorParams]);
61
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, (0, _breachUtils.isWebcamRequired)(proctorParams) && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactWebcam.default, {
61
62
  audio: true,
62
63
  muted: true,
63
64
  screenshotFormat: "image/jpeg",
64
65
  ref: webcamReference,
65
66
  onUserMedia: stream => {
66
- if (!isChrome) {
67
+ if (!(0, _browserUtils.isChrome)()) {
67
68
  const {
68
69
  audio,
69
70
  video
@@ -130,7 +131,7 @@ const ActivityTracker = _ref => {
130
131
  }
131
132
  },
132
133
  onUserMediaError: error => {
133
- if (!isChrome) {
134
+ if (!(0, _browserUtils.isChrome)()) {
134
135
  setVideoPermission(false);
135
136
  setAudioPermission(false);
136
137
  }
@@ -140,7 +141,7 @@ const ActivityTracker = _ref => {
140
141
  ref: canvasReference,
141
142
  className: "captured-video-canvas",
142
143
  id: "wc-ref"
143
- }), /*#__PURE__*/_react.default.createElement("video", {
144
+ })), proctorParams.screenshareSnapshots && /*#__PURE__*/_react.default.createElement("video", {
144
145
  ref: screenshareReference,
145
146
  className: "captured-video-canvas",
146
147
  id: "ss-ref"
@@ -19,6 +19,8 @@ var text = _interopRequireWildcard(require("../../constants/text"));
19
19
 
20
20
  var _permissionBody = require("./permission-body");
21
21
 
22
+ var _breachUtils = require("../../utils/breachUtils");
23
+
22
24
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
23
25
 
24
26
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -27,6 +29,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
27
29
 
28
30
  const Permission = _ref => {
29
31
  let {
32
+ proctorParams,
30
33
  isFullscreen,
31
34
  audioPermisison,
32
35
  videoPermission,
@@ -34,7 +37,7 @@ const Permission = _ref => {
34
37
  screensharePermission,
35
38
  updateScreensharePermission
36
39
  } = _ref;
37
- const showPermissionModal = isFullscreen === false || audioPermisison === false || videoPermission === false || !screensharePermission;
40
+ const showPermissionModal = isFullscreen === false || (0, _breachUtils.isWebcamRequired)(proctorParams) && audioPermisison === false || (0, _breachUtils.isWebcamRequired)(proctorParams) && videoPermission === false || !screensharePermission;
38
41
  return /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal, {
39
42
  show: showPermissionModal,
40
43
  size: "lg",
@@ -59,10 +62,10 @@ const Permission = _ref => {
59
62
  src: _askPermission.default
60
63
  }), text.VIDEO_UNSUPPORTED_IN_BROWSER)), /*#__PURE__*/_react.default.createElement(_permissionBody.PermissionBody, {
61
64
  showFullscreenText: !isFullscreen,
62
- showAudioPermissionText: !audioPermisison,
63
- showVideoPermissionText: !videoPermission,
64
- showScreensharePermission: !screensharePermission
65
- })), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Footer, null, !screensharePermission && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
65
+ showAudioPermissionText: !audioPermisison && (0, _breachUtils.isWebcamRequired)(proctorParams),
66
+ showVideoPermissionText: !videoPermission && (0, _breachUtils.isWebcamRequired)(proctorParams),
67
+ showScreensharePermission: !screensharePermission && proctorParams.screenshareSnapshots
68
+ })), /*#__PURE__*/_react.default.createElement(_reactBootstrap.Modal.Footer, null, !screensharePermission && proctorParams.screenshareSnapshots && /*#__PURE__*/_react.default.createElement(_reactBootstrap.Button, {
66
69
  onClick: () => {
67
70
  updateScreensharePermission();
68
71
  }
@@ -15,6 +15,8 @@ require("./index.scss");
15
15
 
16
16
  var text = _interopRequireWildcard(require("../../constants/text"));
17
17
 
18
+ var _browserUtils = require("../../utils/browserUtils");
19
+
18
20
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
19
21
 
20
22
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -32,7 +34,7 @@ const PermissionBody = _ref => {
32
34
  className: "mb-2"
33
35
  }, text.PERMISSION_GENERIC), showScreensharePermission && /*#__PURE__*/_react.default.createElement("div", {
34
36
  className: "mb-2"
35
- }, /*#__PURE__*/_react.default.createElement("span", {
37
+ }, (0, _browserUtils.isChrome)() && /*#__PURE__*/_react.default.createElement("strong", null, "Please switch to chrome"), /*#__PURE__*/_react.default.createElement("span", {
36
38
  className: "pr-2 font-weight-bold"
37
39
  }, "Screenshare:"), text.PERMISSION_SCREENSHARE), showAudioPermissionText && showVideoPermissionText ? /*#__PURE__*/_react.default.createElement("div", {
38
40
  className: "mb-2"
@@ -3,40 +3,44 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.initialValues = exports.gpuTypes = exports.glancePercentageToPass = exports.evaluateVideoIntervalInSeconds = exports.bodyPixConfigs = exports.INITIAL_STATISTICS = void 0;
6
+ exports.initialValues = exports.gpuTypes = exports.evaluateVideoIntervalInSeconds = exports.defaultConfig = exports.STATS_PARAMS = exports.INITIAL_STATISTICS = void 0;
7
+ const defaultConfig = {
8
+ people: true,
9
+ tabSwitch: true,
10
+ fullscreenExit: true,
11
+ lookedAway: true,
12
+ webcamSnapshots: true,
13
+ screenshareSnapshots: true
14
+ };
15
+ exports.defaultConfig = defaultConfig;
7
16
  const initialValues = {
8
- tabSwitchCount: 0,
17
+ isTabSwitched: false,
9
18
  userCount: 0,
10
19
  isWebcamDataReliable: true,
11
20
  isWatching: true,
12
21
  canOpenFullScreen: false,
13
- fullScreenExitCount: 0,
22
+ isFullscreen: false,
14
23
  lookedAwayCount: 0,
15
24
  firstTimeFullScreen: true
16
25
  };
17
26
  exports.initialValues = initialValues;
27
+ const STATS_PARAMS = {
28
+ isTabSwitched: "IS_TAB_SWITCHED",
29
+ isFullscreen: "IS_FULLSCREEN",
30
+ lookedAwayCount: "LOOKED_AWAY_COUNT",
31
+ userCountMax: "USER_COUNT_MAX",
32
+ isWebcamReliable: "IS_WEBCAM_DATA_RELIABLE"
33
+ };
34
+ exports.STATS_PARAMS = STATS_PARAMS;
18
35
  const INITIAL_STATISTICS = {
19
- TAB_SWITCH_COUNT: initialValues.tabSwitchCount,
20
- FULLSCREEN_EXIT_COUNT: initialValues.fullScreenExitCount,
21
- LOOKED_AWAY_COUNT: initialValues.lookedAwayCount,
22
- USER_COUNT_MAX: initialValues.userCount,
23
- IS_WEBCAM_DATA_RELIABLE: initialValues.isWebcamDataReliable
36
+ [STATS_PARAMS.isTabSwitched]: initialValues.isTabSwitched,
37
+ [STATS_PARAMS.isFullscreen]: initialValues.isFullscreen,
38
+ [STATS_PARAMS.lookedAwayCount]: initialValues.lookedAwayCount,
39
+ [STATS_PARAMS.userCountMax]: initialValues.userCount,
40
+ [STATS_PARAMS.isWebcamReliable]: initialValues.isWebcamDataReliable
24
41
  };
25
42
  exports.INITIAL_STATISTICS = INITIAL_STATISTICS;
26
- const bodyPixConfigs = {
27
- flipHorizontal: false,
28
- internalResolution: "medium",
29
- segmentationThreshold: 0.4,
30
- maxDetections: 10,
31
- scoreThreshold: 0.2,
32
- nmsRadius: 20,
33
- minKeypointScore: 0.3,
34
- refineSteps: 10
35
- };
36
- exports.bodyPixConfigs = bodyPixConfigs;
37
- const glancePercentageToPass = 60;
38
- exports.glancePercentageToPass = glancePercentageToPass;
39
- const evaluateVideoIntervalInSeconds = 1;
43
+ const evaluateVideoIntervalInSeconds = 5;
40
44
  exports.evaluateVideoIntervalInSeconds = evaluateVideoIntervalInSeconds;
41
45
  const gpuTypes = ["intel", "apple", "amd", "radeon", "nvidia", "geforce"];
42
46
  exports.gpuTypes = gpuTypes;
@@ -15,17 +15,9 @@ Object.defineProperty(exports, "usePageVisibility", {
15
15
  return _usePageVisibility.default;
16
16
  }
17
17
  });
18
- Object.defineProperty(exports, "useTabSwitchCount", {
19
- enumerable: true,
20
- get: function get() {
21
- return _useTabSwitchCount.default;
22
- }
23
- });
24
18
 
25
19
  var _useFullScreenData = _interopRequireDefault(require("./useFullScreenData"));
26
20
 
27
21
  var _usePageVisibility = _interopRequireDefault(require("./usePageVisibility"));
28
22
 
29
- var _useTabSwitchCount = _interopRequireDefault(require("./useTabSwitchCount"));
30
-
31
23
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -9,25 +9,18 @@ require("core-js/modules/web.dom-collections.iterator.js");
9
9
 
10
10
  var _react = require("react");
11
11
 
12
- var _defaults = require("../constants/defaults");
13
-
14
12
  var _utils = require("../utils");
15
13
 
16
14
  const browserFullscreenElementProp = (0, _utils.getBrowserFullscreenElementProp)();
17
15
 
18
- function useFullscreenData(firstFullScreenDone) {
16
+ function useFullscreenData(firstFullScreenDone, isProctorParam) {
19
17
  const fullScreenElement = (0, _react.useRef)(document.documentElement);
20
18
  const [isFullscreen, setIsFullscreen] = (0, _react.useState)(document[browserFullscreenElementProp] != null);
21
- const [fullScreenExitCount, setFullScreenExitCount] = (0, _react.useState)(_defaults.initialValues.fullScreenExitCount);
22
19
  (0, _react.useEffect)(() => {
23
- if (!isFullscreen && firstFullScreenDone.current) {
24
- setFullScreenExitCount(fullScreenExitCount => fullScreenExitCount + 1);
25
- }
26
-
27
- if (isFullscreen && !firstFullScreenDone.current) {
20
+ if (isFullscreen && !firstFullScreenDone.current || !isProctorParam) {
28
21
  firstFullScreenDone.current = true;
29
22
  }
30
- }, [isFullscreen, firstFullScreenDone]);
23
+ }, [isFullscreen, firstFullScreenDone, isProctorParam]);
31
24
 
32
25
  const setFullscreen = () => {
33
26
  if (!fullScreenElement || !fullScreenElement.current) {
@@ -42,13 +35,14 @@ function useFullscreenData(firstFullScreenDone) {
42
35
  };
43
36
 
44
37
  (0, _react.useEffect)(() => {
45
- document.onfullscreenchange = () => setIsFullscreen(document[browserFullscreenElementProp] != null);
38
+ if (isProctorParam) {
39
+ document.onfullscreenchange = () => setIsFullscreen(document[browserFullscreenElementProp] != null);
40
+ }
46
41
 
47
42
  return () => document.onfullscreenchange = undefined;
48
- }, []);
43
+ }, [isProctorParam]);
49
44
  return {
50
45
  isFullscreen,
51
- setFullscreen,
52
- fullScreenExitCount
46
+ setFullscreen
53
47
  };
54
48
  }
@@ -13,7 +13,7 @@ var _utils = require("../utils");
13
13
 
14
14
  const visibilityChangeEvent = (0, _utils.getVisibilityChangeEventName)();
15
15
 
16
- function usePageVisibility() {
16
+ function usePageVisibility(isProctorParam) {
17
17
  const [isVisible, setIsVisible] = (0, _react.useState)((0, _utils.getIsDocumentVisible)());
18
18
 
19
19
  const updateVisibility = () => {
@@ -27,5 +27,5 @@ function usePageVisibility() {
27
27
  document.removeEventListener(visibilityChangeEvent, updateVisibility);
28
28
  };
29
29
  }, []);
30
- return isVisible;
30
+ return !isVisible && isProctorParam;
31
31
  }
@@ -11,7 +11,7 @@ require("core-js/modules/web.dom-collections.iterator.js");
11
11
 
12
12
  var _react = require("react");
13
13
 
14
- var bodyPix = _interopRequireWildcard(require("@tensorflow-models/body-pix"));
14
+ var cocoSsd = _interopRequireWildcard(require("@tensorflow-models/coco-ssd"));
15
15
 
16
16
  var tf = _interopRequireWildcard(require("@tensorflow/tfjs"));
17
17
 
@@ -23,56 +23,48 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
23
23
 
24
24
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
25
25
 
26
- /* https://stackoverflow.com/questions/63441878/bodypix-error-no-backend-found-in-registry */
27
- const getUsers = async (network, video) => {
26
+ const getUserCount = async (model, image) => {
28
27
  try {
29
- return await network.segmentMultiPerson(video, _defaults.bodyPixConfigs);
28
+ let predictions = await model.detect(image);
29
+ let numOfUsers = 0;
30
+ predictions.forEach(prediction => {
31
+ if (prediction.class === "person") {
32
+ numOfUsers += 1;
33
+ }
34
+ });
35
+ return numOfUsers;
30
36
  } catch (err) {
31
37
  console.log("Error Trace:", err);
32
38
  }
33
39
  };
34
40
 
35
- const getIsWatching = async (network, video) => {
36
- try {
37
- const partSegmentation = await network.segmentPersonParts(video, _defaults.bodyPixConfigs);
38
- const currentPercentage = (0, _utils.getGlancePercentage)(partSegmentation);
39
- return currentPercentage >= _defaults.glancePercentageToPass;
40
- } catch (err) {
41
- console.log("Error Trace:", err);
42
- }
43
- };
44
-
45
- function useWebcamData(webcamReference, canvasReference) {
41
+ function useWebcamData(webcamReference, canvasReference, proctorParams) {
46
42
  const [userCount, setUserCount] = (0, _react.useState)(_defaults.initialValues.userCount);
47
- const [isWatching, setIsWatching] = (0, _react.useState)(_defaults.initialValues.isWatching);
43
+ const isWatching = (0, _react.useState)(_defaults.initialValues.isWatching);
48
44
  const [lookedAwayCount, setLookedAwayCount] = (0, _react.useState)(_defaults.initialValues.lookedAwayCount);
49
45
  (0, _react.useEffect)(() => {
50
- if ((0, _utils.isGPUAvailable)()) {
51
- const loadBodyPixModel = async () => {
46
+ if ((0, _utils.isGPUAvailable)() && proctorParams.people && proctorParams.lookedAwayCount) {
47
+ const loadCocoSSDModel = async () => {
52
48
  try {
53
- const network = await bodyPix.load();
49
+ const model = await cocoSsd.load();
54
50
  setInterval(async () => {
55
51
  if ((0, _utils.isWebcamVideoValid)(webcamReference)) {
56
- var _users$length;
57
-
58
52
  const video = webcamReference.current.video;
59
53
  const {
60
54
  videoWidth,
61
55
  videoHeight
62
56
  } = video;
63
- video.width = videoWidth;
64
- video.height = videoHeight;
57
+ const b64Snapshot = webcamReference.current.getScreenshot();
58
+ const webcamSnapShot = new Image(videoWidth, videoHeight);
59
+ webcamSnapShot.src = b64Snapshot;
60
+
61
+ webcamSnapShot.onload = async () => {
62
+ const count = await getUserCount(model, webcamSnapShot);
63
+ setUserCount(count);
64
+ };
65
+
65
66
  canvasReference.current.width = videoWidth;
66
67
  canvasReference.current.height = videoHeight;
67
- const users = await getUsers(network, video);
68
- const count = (_users$length = users === null || users === void 0 ? void 0 : users.length) !== null && _users$length !== void 0 ? _users$length : 0;
69
- setUserCount(count);
70
-
71
- if (count) {
72
- setIsWatching(getIsWatching(network, video));
73
- } else {
74
- setIsWatching(false);
75
- }
76
68
  }
77
69
  }, _defaults.evaluateVideoIntervalInSeconds * 1000);
78
70
  } catch (err) {
@@ -81,9 +73,9 @@ function useWebcamData(webcamReference, canvasReference) {
81
73
  }
82
74
  };
83
75
 
84
- loadBodyPixModel();
76
+ loadCocoSSDModel();
85
77
  }
86
- }, [webcamReference, canvasReference]);
78
+ }, [webcamReference, canvasReference, proctorParams.people, proctorParams.lookedAwayCount]);
87
79
  (0, _react.useEffect)(() => {
88
80
  if (!isWatching) {
89
81
  setLookedAwayCount(lookedAwayCount => lookedAwayCount + 1);
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getDataOnBreach = void 0;
6
+ exports.showProctoredComponent = exports.isWebcamRequired = exports.getInitialStats = exports.getDataOnBreach = void 0;
7
+
8
+ var _defaults = require("../constants/defaults");
7
9
 
8
10
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
9
11
 
@@ -11,63 +13,106 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
11
13
 
12
14
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
13
15
 
14
- const getDataOnBreach = (statistics, currentData) => {
16
+ const getInitialStats = proctorParams => {
17
+ const initialStats = {};
18
+
19
+ if (proctorParams.people) {
20
+ initialStats[_defaults.STATS_PARAMS.userCountMax] = _defaults.initialValues.userCount;
21
+ }
22
+
23
+ if (proctorParams.tabSwitch) {
24
+ initialStats[_defaults.STATS_PARAMS.isTabSwitched] = _defaults.initialValues.isTabSwitched;
25
+ }
26
+
27
+ if (proctorParams.fullscreenExit) {
28
+ initialStats[_defaults.STATS_PARAMS.isFullscreen] = _defaults.initialValues.isFullscreen;
29
+ }
30
+
31
+ if (proctorParams.lookedAway) {
32
+ initialStats[_defaults.STATS_PARAMS.lookedAwayCount] = _defaults.initialValues.lookedAwayCount;
33
+ }
34
+
35
+ return initialStats;
36
+ };
37
+
38
+ exports.getInitialStats = getInitialStats;
39
+
40
+ const isWebcamRequired = proctorParams => proctorParams.people || proctorParams.lookedAway || proctorParams.webcamSnapshots;
41
+
42
+ exports.isWebcamRequired = isWebcamRequired;
43
+
44
+ const showProctoredComponent = (proctorParams, permissions) => {
45
+ return (!proctorParams.fullscreenExit || permissions.isFullscreen) && (!isWebcamRequired(proctorParams) || permissions.audioPermission && permissions.videoPermission) && (!proctorParams.screenshareSnapshots || permissions.screensharePermission);
46
+ };
47
+
48
+ exports.showProctoredComponent = showProctoredComponent;
49
+
50
+ const getDataOnBreach = (statistics, currentData, proctorParams) => {
15
51
  const {
16
52
  userCount,
17
- tabSwitchCount,
18
- fullScreenExitCount,
53
+ isTabSwitched,
54
+ isFullscreen,
19
55
  lookedAwayCount,
20
56
  isWebcamDataReliable
21
57
  } = currentData;
22
58
  const timestamp = Date.now();
23
59
  const data = statistics.current;
60
+ const isWebCamReliableParam = _defaults.STATS_PARAMS.isWebcamReliable;
24
61
 
25
- if (data.IS_WEBCAM_DATA_RELIABLE !== isWebcamDataReliable) {
62
+ if (isWebcamRequired(proctorParams) && data[isWebCamReliableParam] !== isWebcamDataReliable) {
26
63
  return {
27
- breachedParam: "IS_WEBCAM_DATA_RELIABLE",
64
+ breachedParam: isWebCamReliableParam,
28
65
  timestamp,
29
66
  data: _objectSpread(_objectSpread({}, data), {}, {
30
- IS_WEBCAM_DATA_RELIABLE: isWebcamDataReliable
67
+ [isWebCamReliableParam]: isWebcamDataReliable
31
68
  })
32
69
  };
33
70
  }
34
71
 
35
- if (data.USER_COUNT_MAX < userCount) {
72
+ const userCountMaxParam = _defaults.STATS_PARAMS.userCountMax;
73
+
74
+ if (proctorParams.people && data[userCountMaxParam] < userCount) {
36
75
  return {
37
- breachedParam: "USER_COUNT_MAX",
76
+ breachedParam: userCountMaxParam,
38
77
  timestamp,
39
78
  data: _objectSpread(_objectSpread({}, data), {}, {
40
- USER_COUNT_MAX: userCount
79
+ [userCountMaxParam]: userCount
41
80
  })
42
81
  };
43
82
  }
44
83
 
45
- if (data.TAB_SWITCH_COUNT !== tabSwitchCount) {
84
+ const isTabSwitchedParam = _defaults.STATS_PARAMS.isTabSwitched;
85
+
86
+ if (proctorParams.tabSwitch && isTabSwitched && !data[isTabSwitchedParam]) {
46
87
  return {
47
- breachedParam: "TAB_SWITCH_COUNT",
88
+ breachedParam: isTabSwitchedParam,
48
89
  timestamp,
49
90
  data: _objectSpread(_objectSpread({}, data), {}, {
50
- TAB_SWITCH_COUNT: tabSwitchCount
91
+ [isTabSwitchedParam]: isTabSwitched
51
92
  })
52
93
  };
53
94
  }
54
95
 
55
- if (data.FULLSCREEN_EXIT_COUNT !== fullScreenExitCount) {
96
+ const fullscreenExitParam = _defaults.STATS_PARAMS.isFullscreen;
97
+
98
+ if (proctorParams.fullscreenExit && !isFullscreen && data[fullscreenExitParam]) {
56
99
  return {
57
- breachedParam: "FULLSCREEN_EXIT_COUNT",
100
+ breachedParam: fullscreenExitParam,
58
101
  timestamp,
59
102
  data: _objectSpread(_objectSpread({}, data), {}, {
60
- FULLSCREEN_EXIT_COUNT: fullScreenExitCount
103
+ [fullscreenExitParam]: isFullscreen
61
104
  })
62
105
  };
63
106
  }
64
107
 
65
- if (data.LOOKED_AWAY_COUNT !== lookedAwayCount) {
108
+ const lookedAwayParam = _defaults.STATS_PARAMS.lookedAwayCount;
109
+
110
+ if (proctorParams.lookedAway && data[lookedAwayParam] !== lookedAwayCount) {
66
111
  return {
67
- breachedParam: "LOOKED_AWAY_COUNT",
112
+ breachedParam: lookedAwayParam,
68
113
  timestamp,
69
114
  data: _objectSpread(_objectSpread({}, data), {}, {
70
- LOOKED_AWAY_COUNT: lookedAwayCount
115
+ [lookedAwayParam]: lookedAwayCount
71
116
  })
72
117
  };
73
118
  }
@@ -3,7 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getVisibilityChangeEventName = exports.getIsDocumentVisible = exports.getBrowserFullscreenElementProp = void 0;
6
+ exports.isChrome = exports.getVisibilityChangeEventName = exports.getIsDocumentVisible = exports.getBrowserFullscreenElementProp = void 0;
7
+
8
+ require("core-js/modules/es.regexp.exec.js");
9
+
10
+ require("core-js/modules/es.string.match.js");
11
+
7
12
  const PROPERTY_TYPES = {
8
13
  HIDDEN: "hidden",
9
14
  VISIBILITY_CHANGE: "visibilitychange"
@@ -60,4 +65,8 @@ const getBrowserFullscreenElementProp = () => {
60
65
  }
61
66
  };
62
67
 
63
- exports.getBrowserFullscreenElementProp = getBrowserFullscreenElementProp;
68
+ exports.getBrowserFullscreenElementProp = getBrowserFullscreenElementProp;
69
+
70
+ const isChrome = () => !!navigator.userAgent.match(/chrome|chromium/i);
71
+
72
+ exports.isChrome = isChrome;
@@ -3,12 +3,6 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- Object.defineProperty(exports, "addOrUpdateStatsToLocalStorage", {
7
- enumerable: true,
8
- get: function get() {
9
- return _localStorageUtils.addOrUpdateStatsToLocalStorage;
10
- }
11
- });
12
6
  Object.defineProperty(exports, "captureWebcamSnapshot", {
13
7
  enumerable: true,
14
8
  get: function get() {
@@ -33,24 +27,12 @@ Object.defineProperty(exports, "getBrowserFullscreenElementProp", {
33
27
  return _browserUtils.getBrowserFullscreenElementProp;
34
28
  }
35
29
  });
36
- Object.defineProperty(exports, "getGlancePercentage", {
37
- enumerable: true,
38
- get: function get() {
39
- return _webcamMicrophoneUtils.getGlancePercentage;
40
- }
41
- });
42
30
  Object.defineProperty(exports, "getIsDocumentVisible", {
43
31
  enumerable: true,
44
32
  get: function get() {
45
33
  return _browserUtils.getIsDocumentVisible;
46
34
  }
47
35
  });
48
- Object.defineProperty(exports, "getStatistics", {
49
- enumerable: true,
50
- get: function get() {
51
- return _localStorageUtils.getStatistics;
52
- }
53
- });
54
36
  Object.defineProperty(exports, "getVideoPermission", {
55
37
  enumerable: true,
56
38
  get: function get() {
@@ -81,24 +63,6 @@ Object.defineProperty(exports, "isWebcamVideoValid", {
81
63
  return _webcamMicrophoneUtils.isWebcamVideoValid;
82
64
  }
83
65
  });
84
- Object.defineProperty(exports, "removeStatsFromLocalStorage", {
85
- enumerable: true,
86
- get: function get() {
87
- return _localStorageUtils.removeStatsFromLocalStorage;
88
- }
89
- });
90
- Object.defineProperty(exports, "retrieveStatsFromLocalStorage", {
91
- enumerable: true,
92
- get: function get() {
93
- return _localStorageUtils.retrieveStatsFromLocalStorage;
94
- }
95
- });
96
- Object.defineProperty(exports, "sendDataOnBreach", {
97
- enumerable: true,
98
- get: function get() {
99
- return _breachUtils.sendDataOnBreach;
100
- }
101
- });
102
66
  Object.defineProperty(exports, "updateStatistics", {
103
67
  enumerable: true,
104
68
  get: function get() {
@@ -106,14 +70,10 @@ Object.defineProperty(exports, "updateStatistics", {
106
70
  }
107
71
  });
108
72
 
109
- var _localStorageUtils = require("./localStorageUtils");
110
-
111
73
  var _webcamMicrophoneUtils = require("./webcamMicrophoneUtils");
112
74
 
113
75
  var _browserUtils = require("./browserUtils");
114
76
 
115
- var _breachUtils = require("./breachUtils");
116
-
117
77
  var _arrayUtils = require("./arrayUtils");
118
78
 
119
79
  var _gpuUtils = require("./gpuUtils");
@@ -25,24 +25,39 @@ var _ = require(".");
25
25
 
26
26
  var _html2canvas = _interopRequireDefault(require("html2canvas"));
27
27
 
28
+ var _defaults = require("../constants/defaults");
29
+
28
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
31
 
30
32
  const isWebcamVideoValid = webcamReference => webcamReference !== null && webcamReference !== undefined && typeof webcamReference.current !== "undefined" && webcamReference.current !== null && webcamReference.current.video.readyState === 4;
31
33
 
32
34
  exports.isWebcamVideoValid = isWebcamVideoValid;
33
35
 
34
- const updateStatistics = (statistics, currentStats) => {
36
+ const updateStatistics = (statistics, currentStats, proctorParams) => {
35
37
  const {
36
- tabSwitchCount,
37
- fullScreenExitCount,
38
+ isTabSwitched,
39
+ isFullscreen,
38
40
  lookedAwayCount,
39
41
  userCount,
40
42
  isWebcamDataReliable
41
43
  } = currentStats;
42
- statistics.current.TAB_SWITCH_COUNT = tabSwitchCount;
43
- statistics.current.FULLSCREEN_EXIT_COUNT = fullScreenExitCount;
44
- statistics.current.LOOKED_AWAY_COUNT = lookedAwayCount;
45
- statistics.current.USER_COUNT_MAX = Math.max(userCount, statistics.current.USER_COUNT_MAX);
44
+
45
+ if (proctorParams.tabSwitch) {
46
+ statistics.current[_defaults.STATS_PARAMS.isTabSwitched] = isTabSwitched;
47
+ }
48
+
49
+ if (proctorParams.fullscreenExit) {
50
+ statistics.current[_defaults.STATS_PARAMS.isFullscreen] = isFullscreen;
51
+ }
52
+
53
+ if (proctorParams.lookedAway) {
54
+ statistics.current[_defaults.STATS_PARAMS.lookedAwayCount] = lookedAwayCount;
55
+ }
56
+
57
+ if (proctorParams.people) {
58
+ statistics.current[_defaults.STATS_PARAMS.userCountMax] = Math.max(userCount, statistics.current[_defaults.STATS_PARAMS.userCountMax]);
59
+ }
60
+
46
61
  statistics.current.IS_WEBCAM_DATA_RELIABLE = isWebcamDataReliable;
47
62
  };
48
63
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newtonschool/react_proctoring_library",
3
- "version": "0.0.16",
3
+ "version": "0.0.17",
4
4
  "description": "Used to proctor online tests",
5
5
  "author": "ayushkagrawal,shreyachandra",
6
6
  "main": "dist/index.js",
@@ -13,7 +13,7 @@
13
13
  ""
14
14
  ],
15
15
  "dependencies": {
16
- "@tensorflow-models/body-pix": "^2.2.0",
16
+ "@tensorflow-models/coco-ssd": "^2.2.2",
17
17
  "@tensorflow/tfjs": "^3.9.0",
18
18
  "bootstrap": "^5.1.3",
19
19
  "core-js": "^3.22.7",