@newtonschool/react_proctoring_library 0.0.1 → 0.0.2
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 +70 -66
- package/dist/assets/images/newton-school-logo.png +0 -0
- package/dist/assets/images/url-video-permission-highlight.png +0 -0
- package/dist/assets/images/vid-micro-permissions-given.png +0 -0
- package/dist/assets/images/vid-micro-permissions.png +0 -0
- package/dist/assets/videos/ask-permission.mp4 +0 -0
- package/dist/assets/videos/give-permissions.mp4 +0 -0
- package/dist/components/FullScreenPermission.js +84 -0
- package/dist/components/FullScreenTestInWebcam.js +22 -10
- package/dist/components/ProctorApp.js +92 -0
- package/dist/components/ResponseModal.js +24 -16
- package/dist/components/activity-tracker/index.js +144 -0
- package/dist/components/activity-tracker/index.scss +4 -0
- package/dist/components/full-screen-permission.scss +8 -0
- package/dist/components/index.js +31 -0
- package/dist/components/permissions/audio-video-permission.js +35 -0
- package/dist/components/permissions/audio-video-permission.scss +228 -0
- package/dist/components/permissions/blocked-permission.js +76 -0
- package/dist/components/permissions/full-screen-permission.js +43 -0
- package/dist/components/permissions/full-screen-permission.scss +8 -0
- package/dist/components/permissions/index.js +70 -0
- package/dist/components/permissions/index.scss +6 -0
- package/dist/components/permissions/initial-screen.js +52 -0
- package/dist/components/permissions/permission-body.js +53 -0
- package/dist/constants/defaults.js +38 -0
- package/dist/constants/text.js +56 -0
- package/dist/demo-code/README.md +70 -0
- package/dist/demo-code/package.json +38 -0
- package/dist/demo-code/public/favicon.ico +0 -0
- package/dist/demo-code/public/index.html +43 -0
- package/dist/demo-code/public/logo192.png +0 -0
- package/dist/demo-code/public/logo512.png +0 -0
- package/dist/demo-code/public/manifest.json +25 -0
- package/dist/demo-code/public/robots.txt +3 -0
- package/dist/demo-code/src/App.css +38 -0
- package/dist/demo-code/src/App.js +29 -0
- package/dist/demo-code/src/index.js +11 -0
- package/dist/hooks/index.js +39 -0
- package/dist/hooks/useAudioVideoPermission.js +96 -0
- package/dist/hooks/useAudioVideoPermissions.js +1 -0
- package/dist/hooks/useFullScreenData.js +55 -0
- package/dist/hooks/useFullScreenStatus.js +45 -0
- package/dist/hooks/usePageVisibility.js +31 -0
- package/dist/hooks/useTabSwitchCount.js +25 -0
- package/dist/hooks/useWebcamData.js +91 -0
- package/dist/index.js +5 -3
- package/dist/lib/index.js +19 -0
- package/dist/utils/ValidityChecks.js +1 -19
- package/dist/utils/arrayUtils.js +16 -0
- package/dist/utils/breachUtils.js +69 -0
- package/dist/utils/browserUtils.js +63 -0
- package/dist/utils/{GetBrowserDocumentProp.js → getBrowserDocumentProp.js} +0 -0
- package/dist/utils/getGlancePercentage.js +1 -43
- package/dist/utils/{GetIsDocumentHidden.js → getIsDocumentHidden.js} +2 -2
- package/dist/utils/index.js +49 -29
- package/dist/utils/localStorageUtils.js +33 -0
- package/dist/utils/webcamMicrophoneUtils.js +115 -0
- package/dist/utils/webcamUtils.js +79 -0
- package/package.json +55 -55
- package/dist/ProctorApp.js +0 -186
- package/dist/utils/TabVisibility.js +0 -32
- package/dist/utils/commonUtilConfigs.js +0 -21
- package/dist/utils/initialSetup.js +0 -15
- package/dist/utils/localStorageUtil.js +0 -27
- package/dist/utils/useFullScreenStatus.js +0 -45
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = useWebcamData;
|
|
7
|
+
|
|
8
|
+
require("core-js/modules/es.promise.js");
|
|
9
|
+
|
|
10
|
+
require("core-js/modules/web.dom-collections.iterator.js");
|
|
11
|
+
|
|
12
|
+
var _react = require("react");
|
|
13
|
+
|
|
14
|
+
var bodyPix = _interopRequireWildcard(require("@tensorflow-models/body-pix"));
|
|
15
|
+
|
|
16
|
+
var tf = _interopRequireWildcard(require("@tensorflow/tfjs"));
|
|
17
|
+
|
|
18
|
+
var _utils = require("../utils");
|
|
19
|
+
|
|
20
|
+
var _defaults = require("../constants/defaults");
|
|
21
|
+
|
|
22
|
+
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
|
+
|
|
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
|
+
|
|
26
|
+
/* https://stackoverflow.com/questions/63441878/bodypix-error-no-backend-found-in-registry */
|
|
27
|
+
const getUsers = async (network, video) => {
|
|
28
|
+
try {
|
|
29
|
+
return await network.segmentMultiPerson(video, _defaults.bodyPixConfigs);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
console.log("Error Trace:", err);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
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) {
|
|
46
|
+
const [userCount, setUserCount] = (0, _react.useState)(_defaults.initialValues.userCount);
|
|
47
|
+
const [isWatching, setIsWatching] = (0, _react.useState)(_defaults.initialValues.isWatching);
|
|
48
|
+
const [lookedAwayCount, setLookedAwayCount] = (0, _react.useState)(_defaults.initialValues.lookedAwayCount);
|
|
49
|
+
(0, _react.useEffect)(() => {
|
|
50
|
+
const loadBodyPixModel = async () => {
|
|
51
|
+
try {
|
|
52
|
+
const network = await bodyPix.load();
|
|
53
|
+
setInterval(async () => {
|
|
54
|
+
if ((0, _utils.isWebcamVideoValid)(webcamReference)) {
|
|
55
|
+
var _users$length;
|
|
56
|
+
|
|
57
|
+
const video = webcamReference.current.video;
|
|
58
|
+
const {
|
|
59
|
+
videoWidth,
|
|
60
|
+
videoHeight
|
|
61
|
+
} = video;
|
|
62
|
+
video.width = videoWidth;
|
|
63
|
+
video.height = videoHeight;
|
|
64
|
+
canvasReference.current.width = videoWidth;
|
|
65
|
+
canvasReference.current.height = videoHeight;
|
|
66
|
+
const users = await getUsers(network, video);
|
|
67
|
+
const count = (_users$length = users === null || users === void 0 ? void 0 : users.length) !== null && _users$length !== void 0 ? _users$length : 0;
|
|
68
|
+
setUserCount(count);
|
|
69
|
+
|
|
70
|
+
if (count) {
|
|
71
|
+
setIsWatching(getIsWatching(network, video));
|
|
72
|
+
} else {
|
|
73
|
+
setIsWatching(false);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}, _defaults.evaluateVideoIntervalInSeconds * 1000);
|
|
77
|
+
} catch (err) {
|
|
78
|
+
console.log("Error Trace:", err);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
loadBodyPixModel();
|
|
84
|
+
}, [webcamReference, canvasReference]);
|
|
85
|
+
(0, _react.useEffect)(() => {
|
|
86
|
+
if (!isWatching) {
|
|
87
|
+
setLookedAwayCount(lookedAwayCount => lookedAwayCount + 1);
|
|
88
|
+
}
|
|
89
|
+
}, [isWatching]);
|
|
90
|
+
return [userCount, lookedAwayCount];
|
|
91
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -6,14 +6,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
Object.defineProperty(exports, "ProctorApp", {
|
|
7
7
|
enumerable: true,
|
|
8
8
|
get: function get() {
|
|
9
|
-
return
|
|
9
|
+
return _components.ProctorApp;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
12
|
Object.defineProperty(exports, "getStatistics", {
|
|
13
13
|
enumerable: true,
|
|
14
14
|
get: function get() {
|
|
15
|
-
return
|
|
15
|
+
return _utils.getStatistics;
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
var
|
|
19
|
+
var _components = require("./components");
|
|
20
|
+
|
|
21
|
+
var _utils = require("./utils");
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "ProctorApp", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _components.ProctorApp;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "getStatistics", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function get() {
|
|
15
|
+
return _components.getStatistics;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
var _components = require("../components");
|
|
@@ -1,19 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.isArrayValid = isArrayValid;
|
|
7
|
-
exports.isWebcamVideoValid = isWebcamVideoValid;
|
|
8
|
-
|
|
9
|
-
function isWebcamVideoValid(webcamReference) {
|
|
10
|
-
return webcamReference !== null && webcamReference !== undefined && typeof webcamReference.current !== 'undefined' && webcamReference.current !== null && webcamReference.current.video.readyState === 4;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function isArrayValid(array) {
|
|
14
|
-
if (!array || !(array instanceof Array) || array.length <= 0) {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isArrayValid = void 0;
|
|
7
|
+
|
|
8
|
+
const isArrayValid = array => {
|
|
9
|
+
if (!array || !(array instanceof Array) || array.length <= 0) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return true;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
exports.isArrayValid = isArrayValid;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.sendDataOnBreach = void 0;
|
|
7
|
+
|
|
8
|
+
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
|
+
|
|
10
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
11
|
+
|
|
12
|
+
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
|
+
|
|
14
|
+
const sendDataOnBreach = (statistics, currentData, proctoringIdentifier, sendData) => {
|
|
15
|
+
const {
|
|
16
|
+
userCount,
|
|
17
|
+
tabSwitchCount,
|
|
18
|
+
fullScreenExitCount,
|
|
19
|
+
lookedAwayCount
|
|
20
|
+
} = currentData;
|
|
21
|
+
const timestamp = Date.now();
|
|
22
|
+
const data = statistics.current;
|
|
23
|
+
|
|
24
|
+
if (data.USER_COUNT_MAX < userCount) {
|
|
25
|
+
sendData({
|
|
26
|
+
proctoringIdentifier,
|
|
27
|
+
breach: "USER_COUNT_MAX",
|
|
28
|
+
timestamp,
|
|
29
|
+
data: _objectSpread(_objectSpread({}, data), {}, {
|
|
30
|
+
USER_COUNT_MAX: userCount
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (data.TAB_SWITCH_COUNT !== tabSwitchCount) {
|
|
36
|
+
sendData({
|
|
37
|
+
proctoringIdentifier,
|
|
38
|
+
breach: "TAB_SWITCH_COUNT",
|
|
39
|
+
timestamp,
|
|
40
|
+
data: _objectSpread(_objectSpread({}, data), {}, {
|
|
41
|
+
TAB_SWITCH_COUNT: tabSwitchCount
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (data.FULLSCREEN_EXIT_COUNT !== fullScreenExitCount) {
|
|
47
|
+
sendData({
|
|
48
|
+
proctoringIdentifier,
|
|
49
|
+
breach: "FULLSCREEN_EXIT_COUNT",
|
|
50
|
+
timestamp,
|
|
51
|
+
data: _objectSpread(_objectSpread({}, data), {}, {
|
|
52
|
+
FULLSCREEN_EXIT_COUNT: fullScreenExitCount
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (data.LOOKED_AWAY_COUNT !== lookedAwayCount) {
|
|
58
|
+
sendData({
|
|
59
|
+
proctoringIdentifier,
|
|
60
|
+
breach: "LOOKED_AWAY_COUNT",
|
|
61
|
+
timestamp,
|
|
62
|
+
data: _objectSpread(_objectSpread({}, data), {}, {
|
|
63
|
+
LOOKED_AWAY_COUNT: lookedAwayCount
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
exports.sendDataOnBreach = sendDataOnBreach;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getVisibilityChangeEventName = exports.getIsDocumentVisible = exports.getBrowserFullscreenElementProp = void 0;
|
|
7
|
+
const PROPERTY_TYPES = {
|
|
8
|
+
HIDDEN: "hidden",
|
|
9
|
+
VISIBILITY_CHANGE: "visibilitychange"
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const getBrowserPropPrefix = () => {
|
|
13
|
+
if (typeof document.msHidden !== "undefined") {
|
|
14
|
+
return "ms";
|
|
15
|
+
} else if (typeof document.webkitHidden !== "undefined") {
|
|
16
|
+
return "webkit";
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return "";
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const getBrowserPropForHidden = () => {
|
|
23
|
+
if (typeof document.hidden !== "undefined") {
|
|
24
|
+
return "hidden";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return "".concat(getBrowserPropPrefix(), "Hidden");
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const getBrowserDocumentProp = type => {
|
|
31
|
+
switch (type) {
|
|
32
|
+
case PROPERTY_TYPES.HIDDEN:
|
|
33
|
+
return getBrowserPropForHidden();
|
|
34
|
+
|
|
35
|
+
case PROPERTY_TYPES.VISIBILITY_CHANGE:
|
|
36
|
+
return "".concat(getBrowserPropPrefix(), "visibilitychange");
|
|
37
|
+
|
|
38
|
+
default:
|
|
39
|
+
return "";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const getIsDocumentVisible = () => !document[getBrowserDocumentProp(PROPERTY_TYPES.HIDDEN)];
|
|
44
|
+
|
|
45
|
+
exports.getIsDocumentVisible = getIsDocumentVisible;
|
|
46
|
+
|
|
47
|
+
const getVisibilityChangeEventName = () => getBrowserDocumentProp(PROPERTY_TYPES.VISIBILITY_CHANGE);
|
|
48
|
+
|
|
49
|
+
exports.getVisibilityChangeEventName = getVisibilityChangeEventName;
|
|
50
|
+
|
|
51
|
+
const getBrowserFullscreenElementProp = () => {
|
|
52
|
+
if (typeof document.fullscreenElement !== "undefined") {
|
|
53
|
+
return "fullscreenElement";
|
|
54
|
+
} else if (typeof document.mozFullScreenElement !== "undefined") {
|
|
55
|
+
return "mozFullScreenElement";
|
|
56
|
+
} else if (typeof document.msFullscreenElement !== "undefined") {
|
|
57
|
+
return "msFullscreenElement";
|
|
58
|
+
} else if (typeof document.webkitFullscreenElement !== "undefined") {
|
|
59
|
+
return "webkitFullscreenElement";
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
exports.getBrowserFullscreenElementProp = getBrowserFullscreenElementProp;
|
|
File without changes
|
|
@@ -1,43 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.getGlancePercentage = void 0;
|
|
7
|
-
|
|
8
|
-
var _ValidityChecks = require("./ValidityChecks");
|
|
9
|
-
|
|
10
|
-
const getGlancePercentage = partSegmentation => {
|
|
11
|
-
if (!partSegmentation || !(partSegmentation instanceof Object) || !(0, _ValidityChecks.isArrayValid)(partSegmentation.allPoses)) {
|
|
12
|
-
return 0.0;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const allPoses = partSegmentation.allPoses;
|
|
16
|
-
let totalScoreLeftEye = 0.0,
|
|
17
|
-
totalScoreRightEye = 0.0,
|
|
18
|
-
totalScoreNose = 0.0,
|
|
19
|
-
totalScoreLeftEar = 0.0,
|
|
20
|
-
totalScoreRightEar = 0.0;
|
|
21
|
-
let noseIndex = 0,
|
|
22
|
-
leftEyeIndex = 1,
|
|
23
|
-
rightEyeIndex = 2,
|
|
24
|
-
leftEarIndex = 3,
|
|
25
|
-
rightEarIndex = 4;
|
|
26
|
-
allPoses.forEach(poseArray => {
|
|
27
|
-
let keypointsArray = poseArray.keypoints;
|
|
28
|
-
totalScoreNose += keypointsArray[noseIndex].score;
|
|
29
|
-
totalScoreLeftEye += keypointsArray[leftEyeIndex].score;
|
|
30
|
-
totalScoreRightEye += keypointsArray[rightEyeIndex].score;
|
|
31
|
-
totalScoreLeftEar += keypointsArray[leftEarIndex].score;
|
|
32
|
-
totalScoreRightEar += keypointsArray[rightEarIndex].score;
|
|
33
|
-
});
|
|
34
|
-
const avgScoreLeftEye = totalScoreLeftEye / allPoses.length,
|
|
35
|
-
avgScoreRightEye = totalScoreRightEye / allPoses.length,
|
|
36
|
-
avgScoreNose = totalScoreNose / allPoses.length,
|
|
37
|
-
avgScoreLeftEar = totalScoreLeftEar / allPoses.length,
|
|
38
|
-
avgScoreRightEar = totalScoreRightEar / allPoses.length;
|
|
39
|
-
const avgPercentage = 100 * (avgScoreLeftEye + avgScoreRightEye + avgScoreNose + avgScoreLeftEar + avgScoreRightEar) / 5;
|
|
40
|
-
return Math.ceil(avgPercentage);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
exports.getGlancePercentage = getGlancePercentage;
|
|
1
|
+
"use strict";
|
|
@@ -5,10 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = getIsDocumentHidden;
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _getBrowserDocumentProp = _interopRequireDefault(require("./getBrowserDocumentProp"));
|
|
9
9
|
|
|
10
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
11
|
|
|
12
12
|
function getIsDocumentHidden() {
|
|
13
|
-
return !document[(0,
|
|
13
|
+
return !document[(0, _getBrowserDocumentProp.default)("hidden")];
|
|
14
14
|
}
|
package/dist/utils/index.js
CHANGED
|
@@ -6,80 +6,100 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
Object.defineProperty(exports, "addOrUpdateStatsToLocalStorage", {
|
|
7
7
|
enumerable: true,
|
|
8
8
|
get: function get() {
|
|
9
|
-
return
|
|
9
|
+
return _localStorageUtils.addOrUpdateStatsToLocalStorage;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
-
Object.defineProperty(exports, "
|
|
12
|
+
Object.defineProperty(exports, "getAudioPermission", {
|
|
13
13
|
enumerable: true,
|
|
14
14
|
get: function get() {
|
|
15
|
-
return
|
|
15
|
+
return _webcamMicrophoneUtils.getAudioPermission;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "getAudioVideoPermission", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function get() {
|
|
21
|
+
return _webcamMicrophoneUtils.getAudioVideoPermission;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "getBrowserFullscreenElementProp", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function get() {
|
|
27
|
+
return _browserUtils.getBrowserFullscreenElementProp;
|
|
16
28
|
}
|
|
17
29
|
});
|
|
18
30
|
Object.defineProperty(exports, "getGlancePercentage", {
|
|
19
31
|
enumerable: true,
|
|
20
32
|
get: function get() {
|
|
21
|
-
return
|
|
33
|
+
return _webcamMicrophoneUtils.getGlancePercentage;
|
|
22
34
|
}
|
|
23
35
|
});
|
|
24
|
-
Object.defineProperty(exports, "
|
|
36
|
+
Object.defineProperty(exports, "getIsDocumentVisible", {
|
|
25
37
|
enumerable: true,
|
|
26
38
|
get: function get() {
|
|
27
|
-
return
|
|
39
|
+
return _browserUtils.getIsDocumentVisible;
|
|
28
40
|
}
|
|
29
41
|
});
|
|
30
|
-
Object.defineProperty(exports, "
|
|
42
|
+
Object.defineProperty(exports, "getStatistics", {
|
|
31
43
|
enumerable: true,
|
|
32
44
|
get: function get() {
|
|
33
|
-
return
|
|
45
|
+
return _localStorageUtils.getStatistics;
|
|
34
46
|
}
|
|
35
47
|
});
|
|
36
|
-
Object.defineProperty(exports, "
|
|
48
|
+
Object.defineProperty(exports, "getVideoPermission", {
|
|
37
49
|
enumerable: true,
|
|
38
50
|
get: function get() {
|
|
39
|
-
return
|
|
51
|
+
return _webcamMicrophoneUtils.getVideoPermission;
|
|
40
52
|
}
|
|
41
53
|
});
|
|
42
|
-
Object.defineProperty(exports, "
|
|
54
|
+
Object.defineProperty(exports, "getVisibilityChangeEventName", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function get() {
|
|
57
|
+
return _browserUtils.getVisibilityChangeEventName;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(exports, "isArrayValid", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function get() {
|
|
63
|
+
return _arrayUtils.isArrayValid;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(exports, "isWebcamVideoValid", {
|
|
43
67
|
enumerable: true,
|
|
44
68
|
get: function get() {
|
|
45
|
-
return
|
|
69
|
+
return _webcamMicrophoneUtils.isWebcamVideoValid;
|
|
46
70
|
}
|
|
47
71
|
});
|
|
48
|
-
Object.defineProperty(exports, "
|
|
72
|
+
Object.defineProperty(exports, "removeStatsFromLocalStorage", {
|
|
49
73
|
enumerable: true,
|
|
50
74
|
get: function get() {
|
|
51
|
-
return
|
|
75
|
+
return _localStorageUtils.removeStatsFromLocalStorage;
|
|
52
76
|
}
|
|
53
77
|
});
|
|
54
|
-
Object.defineProperty(exports, "
|
|
78
|
+
Object.defineProperty(exports, "retrieveStatsFromLocalStorage", {
|
|
55
79
|
enumerable: true,
|
|
56
80
|
get: function get() {
|
|
57
|
-
return
|
|
81
|
+
return _localStorageUtils.retrieveStatsFromLocalStorage;
|
|
58
82
|
}
|
|
59
83
|
});
|
|
60
|
-
Object.defineProperty(exports, "
|
|
84
|
+
Object.defineProperty(exports, "sendDataOnBreach", {
|
|
61
85
|
enumerable: true,
|
|
62
86
|
get: function get() {
|
|
63
|
-
return
|
|
87
|
+
return _breachUtils.sendDataOnBreach;
|
|
64
88
|
}
|
|
65
89
|
});
|
|
66
|
-
Object.defineProperty(exports, "
|
|
90
|
+
Object.defineProperty(exports, "updateStatistics", {
|
|
67
91
|
enumerable: true,
|
|
68
92
|
get: function get() {
|
|
69
|
-
return
|
|
93
|
+
return _webcamMicrophoneUtils.updateStatistics;
|
|
70
94
|
}
|
|
71
95
|
});
|
|
72
96
|
|
|
73
|
-
var
|
|
74
|
-
|
|
75
|
-
var _TabVisibility = _interopRequireDefault(require("./TabVisibility"));
|
|
76
|
-
|
|
77
|
-
var _ValidityChecks = require("./ValidityChecks");
|
|
97
|
+
var _localStorageUtils = require("./localStorageUtils");
|
|
78
98
|
|
|
79
|
-
var
|
|
99
|
+
var _webcamMicrophoneUtils = require("./webcamMicrophoneUtils");
|
|
80
100
|
|
|
81
|
-
var
|
|
101
|
+
var _browserUtils = require("./browserUtils");
|
|
82
102
|
|
|
83
|
-
var
|
|
103
|
+
var _breachUtils = require("./breachUtils");
|
|
84
104
|
|
|
85
|
-
|
|
105
|
+
var _arrayUtils = require("./arrayUtils");
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.retrieveStatsFromLocalStorage = exports.removeStatsFromLocalStorage = exports.getStatistics = exports.addOrUpdateStatsToLocalStorage = void 0;
|
|
7
|
+
|
|
8
|
+
require("core-js/modules/es.json.stringify.js");
|
|
9
|
+
|
|
10
|
+
const addOrUpdateStatsToLocalStorage = (proctoringIdentifier, data) => {
|
|
11
|
+
const stringifiedData = JSON.stringify(data);
|
|
12
|
+
localStorage.setItem(proctoringIdentifier, stringifiedData);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
exports.addOrUpdateStatsToLocalStorage = addOrUpdateStatsToLocalStorage;
|
|
16
|
+
|
|
17
|
+
const retrieveStatsFromLocalStorage = proctoringIdentifier => {
|
|
18
|
+
return localStorage.getItem(proctoringIdentifier);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
exports.retrieveStatsFromLocalStorage = retrieveStatsFromLocalStorage;
|
|
22
|
+
|
|
23
|
+
const removeStatsFromLocalStorage = proctoringIdentifier => {
|
|
24
|
+
localStorage.removeItem(proctoringIdentifier);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
exports.removeStatsFromLocalStorage = removeStatsFromLocalStorage;
|
|
28
|
+
|
|
29
|
+
const getStatistics = proctoringIdentifier => {
|
|
30
|
+
return JSON.parse(retrieveStatsFromLocalStorage(proctoringIdentifier));
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
exports.getStatistics = getStatistics;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.updateVideoPermissions = exports.updateStatistics = exports.updateAudioPermissions = exports.isWebcamVideoValid = exports.getVideoPermissionQuery = exports.getVideoPermission = exports.getGlancePercentage = exports.getAudioVideoPermission = exports.getAudioPermissionQuery = exports.getAudioPermission = void 0;
|
|
7
|
+
|
|
8
|
+
var _ = require(".");
|
|
9
|
+
|
|
10
|
+
const isWebcamVideoValid = webcamReference => webcamReference !== null && webcamReference !== undefined && typeof webcamReference.current !== "undefined" && webcamReference.current !== null && webcamReference.current.video.readyState === 4;
|
|
11
|
+
|
|
12
|
+
exports.isWebcamVideoValid = isWebcamVideoValid;
|
|
13
|
+
|
|
14
|
+
const updateStatistics = (statistics, tabSwitchCount, fullScreenExitCount, lookedAwayCount, userCount) => {
|
|
15
|
+
statistics.current.TAB_SWITCH_COUNT = tabSwitchCount;
|
|
16
|
+
statistics.current.FULLSCREEN_EXIT_COUNT = fullScreenExitCount;
|
|
17
|
+
statistics.current.LOOKED_AWAY_COUNT = lookedAwayCount;
|
|
18
|
+
statistics.current.USER_COUNT_MAX = Math.max(userCount, statistics.current.USER_COUNT_MAX);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
exports.updateStatistics = updateStatistics;
|
|
22
|
+
|
|
23
|
+
const getGlancePercentage = partSegmentation => {
|
|
24
|
+
if (!partSegmentation || !(partSegmentation instanceof Object) || !(0, _.isArrayValid)(partSegmentation.allPoses)) {
|
|
25
|
+
return 0.0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const allPoses = partSegmentation.allPoses;
|
|
29
|
+
let totalScoreLeftEye = 0.0,
|
|
30
|
+
totalScoreRightEye = 0.0,
|
|
31
|
+
totalScoreNose = 0.0,
|
|
32
|
+
totalScoreLeftEar = 0.0,
|
|
33
|
+
totalScoreRightEar = 0.0;
|
|
34
|
+
let noseIndex = 0,
|
|
35
|
+
leftEyeIndex = 1,
|
|
36
|
+
rightEyeIndex = 2,
|
|
37
|
+
leftEarIndex = 3,
|
|
38
|
+
rightEarIndex = 4;
|
|
39
|
+
allPoses.forEach(poseArray => {
|
|
40
|
+
let keypointsArray = poseArray.keypoints;
|
|
41
|
+
totalScoreNose += keypointsArray[noseIndex].score;
|
|
42
|
+
totalScoreLeftEye += keypointsArray[leftEyeIndex].score;
|
|
43
|
+
totalScoreRightEye += keypointsArray[rightEyeIndex].score;
|
|
44
|
+
totalScoreLeftEar += keypointsArray[leftEarIndex].score;
|
|
45
|
+
totalScoreRightEar += keypointsArray[rightEarIndex].score;
|
|
46
|
+
});
|
|
47
|
+
const avgScoreLeftEye = totalScoreLeftEye / allPoses.length,
|
|
48
|
+
avgScoreRightEye = totalScoreRightEye / allPoses.length,
|
|
49
|
+
avgScoreNose = totalScoreNose / allPoses.length,
|
|
50
|
+
avgScoreLeftEar = totalScoreLeftEar / allPoses.length,
|
|
51
|
+
avgScoreRightEar = totalScoreRightEar / allPoses.length;
|
|
52
|
+
const avgPercentage = 100 * (avgScoreLeftEye + avgScoreRightEye + avgScoreNose + avgScoreLeftEar + avgScoreRightEar) / 5;
|
|
53
|
+
return Math.ceil(avgPercentage);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
exports.getGlancePercentage = getGlancePercentage;
|
|
57
|
+
|
|
58
|
+
const getVideoPermission = function getVideoPermission(stream) {
|
|
59
|
+
let exludeTrackId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
|
|
60
|
+
return stream.getVideoTracks().filter(track => track.enabled && track.label && track.id !== exludeTrackId).length > 0;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
exports.getVideoPermission = getVideoPermission;
|
|
64
|
+
|
|
65
|
+
const getAudioPermission = function getAudioPermission(stream) {
|
|
66
|
+
let exludeTrackId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
|
|
67
|
+
return stream.getAudioTracks().filter(track => track.enabled && track.label && !track.muted && track.id !== exludeTrackId).length > 0;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
exports.getAudioPermission = getAudioPermission;
|
|
71
|
+
|
|
72
|
+
const getAudioVideoPermission = stream => {
|
|
73
|
+
return {
|
|
74
|
+
audio: getAudioPermission(stream),
|
|
75
|
+
video: getVideoPermission(stream)
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
exports.getAudioVideoPermission = getAudioVideoPermission;
|
|
80
|
+
|
|
81
|
+
const updateAudioPermissions = setAudioPermission => {
|
|
82
|
+
navigator.mediaDevices.getUserMedia({
|
|
83
|
+
audio: true
|
|
84
|
+
}).then(() => {
|
|
85
|
+
setAudioPermission(true);
|
|
86
|
+
}).catch(err => {
|
|
87
|
+
setAudioPermission(false);
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
exports.updateAudioPermissions = updateAudioPermissions;
|
|
92
|
+
|
|
93
|
+
const updateVideoPermissions = setVideoPermission => {
|
|
94
|
+
navigator.mediaDevices.getUserMedia({
|
|
95
|
+
video: true
|
|
96
|
+
}).then(() => {
|
|
97
|
+
setVideoPermission(true);
|
|
98
|
+
}).catch(err => {
|
|
99
|
+
setVideoPermission(false);
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
exports.updateVideoPermissions = updateVideoPermissions;
|
|
104
|
+
|
|
105
|
+
const getVideoPermissionQuery = () => navigator.permissions.query({
|
|
106
|
+
name: "camera"
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
exports.getVideoPermissionQuery = getVideoPermissionQuery;
|
|
110
|
+
|
|
111
|
+
const getAudioPermissionQuery = () => navigator.permissions.query({
|
|
112
|
+
name: "microphone"
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
exports.getAudioPermissionQuery = getAudioPermissionQuery;
|