yootd 0.2.3 → 0.2.5
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/LICENSE +21 -21
- package/README.md +43 -43
- package/dist/Preview/components/preview/phone.scss +8 -8
- package/dist/Preview/index.scss +35 -35
- package/dist/Preview/types/type.d.ts +22 -22
- package/dist/anchor/index.scss +23 -23
- package/dist/approval-process/index.scss +95 -95
- package/dist/areas/index.scss +21 -21
- package/dist/areas-treeSelect/index.scss +6 -6
- package/dist/areas-treeSelect/types/type.d.ts +40 -40
- package/dist/aside/components/SortableItem.scss +111 -111
- package/dist/aside/index.scss +46 -46
- package/dist/aside/types/types.d.ts +51 -51
- package/dist/badge/index.scss +5 -5
- package/dist/buildings/types/types.d.ts +21 -21
- package/dist/button/index.scss +30 -30
- package/dist/cascader/index.scss +5 -5
- package/dist/courses/types/types.d.ts +18 -18
- package/dist/department/index.scss +6 -6
- package/dist/department/types/types.d.ts +23 -23
- package/dist/description/index.scss +10 -10
- package/dist/dictionary/types/types.d.ts +14 -14
- package/dist/drawer-modal/index.scss +42 -42
- package/dist/drawer-modal/types/types.d.ts +3 -3
- package/dist/dropdown/assets/arrow-down.svg +5 -5
- package/dist/dropdown-select/index.scss +6 -6
- package/dist/dropdown-select/types/type.d.ts +18 -18
- package/dist/empty/index.d.ts +4 -1
- package/dist/empty/index.js +3 -0
- package/dist/empty/index.scss +15 -15
- package/dist/export/index.scss +6 -6
- package/dist/go-back/components/index.scss +5 -5
- package/dist/go-back/index.scss +24 -24
- package/dist/group-title/index.scss +31 -31
- package/dist/holiday/types/types.d.ts +22 -22
- package/dist/hooks/useBem.js +10 -10
- package/dist/image/index.scss +26 -26
- package/dist/input/index.scss +5 -5
- package/dist/job-title/types/types.d.ts +17 -17
- package/dist/modal/index.d.ts +1 -1
- package/dist/modal/index.scss +76 -76
- package/dist/pagination/index.scss +47 -47
- package/dist/role/types/types.d.ts +22 -22
- package/dist/school/index.scss +21 -21
- package/dist/school/types/types.d.ts +85 -85
- package/dist/state/index.scss +89 -89
- package/dist/steps/index.scss +32 -32
- package/dist/student-dropdown/types/types.d.ts +44 -44
- package/dist/table/components/primary-header-row/index.scss +67 -67
- package/dist/table/components/primary-tbody-row/index.scss +5 -5
- package/dist/table/index.scss +33 -33
- package/dist/tabs/index.scss +86 -86
- package/dist/tag/index.scss +4 -4
- package/dist/teacher/types/types.d.ts +33 -33
- package/dist/tree/index.scss +34 -34
- package/dist/upload/index.scss +115 -115
- package/dist/user-dropdown/types/types.d.ts +45 -45
- package/dist/video-player/index.js +48 -5
- package/dist/video-player/index.scss +309 -309
- package/dist/year-term/index.scss +21 -21
- package/dist/year-term/types/types.d.ts +39 -39
- package/dist/zones/index.module.scss +23 -23
- package/dist/zones/types/types.d.ts +26 -26
- package/package.json +1 -1
package/dist/tree/index.scss
CHANGED
@@ -1,34 +1,34 @@
|
|
1
|
-
.yot-tree {
|
2
|
-
position: relative;
|
3
|
-
overflow: auto;
|
4
|
-
height: 100%;
|
5
|
-
.ant-tree-node-content-wrapper.ant-tree-node-selected {
|
6
|
-
background-color: var(--ant-color-primary-bg);
|
7
|
-
.ant-tree-title {
|
8
|
-
color: var(--ant-color-primary);
|
9
|
-
}
|
10
|
-
}
|
11
|
-
.ant-tree-node-content-wrapper {
|
12
|
-
.ant-tree-title {
|
13
|
-
color: var(--ant-color-text-secondary);
|
14
|
-
}
|
15
|
-
}
|
16
|
-
&__icon {
|
17
|
-
margin-top: 2px;
|
18
|
-
&.yot-is-selected {
|
19
|
-
.path-1 {
|
20
|
-
stroke: var(--ant-color-primary);
|
21
|
-
}
|
22
|
-
.path-2,
|
23
|
-
.rect-1 {
|
24
|
-
fill: var(--ant-color-primary);
|
25
|
-
}
|
26
|
-
}
|
27
|
-
}
|
28
|
-
&__search {
|
29
|
-
position: sticky;
|
30
|
-
top: 0px;
|
31
|
-
z-index: 1;
|
32
|
-
margin-bottom: 10px;
|
33
|
-
}
|
34
|
-
}
|
1
|
+
.yot-tree {
|
2
|
+
position: relative;
|
3
|
+
overflow: auto;
|
4
|
+
height: 100%;
|
5
|
+
.ant-tree-node-content-wrapper.ant-tree-node-selected {
|
6
|
+
background-color: var(--ant-color-primary-bg);
|
7
|
+
.ant-tree-title {
|
8
|
+
color: var(--ant-color-primary);
|
9
|
+
}
|
10
|
+
}
|
11
|
+
.ant-tree-node-content-wrapper {
|
12
|
+
.ant-tree-title {
|
13
|
+
color: var(--ant-color-text-secondary);
|
14
|
+
}
|
15
|
+
}
|
16
|
+
&__icon {
|
17
|
+
margin-top: 2px;
|
18
|
+
&.yot-is-selected {
|
19
|
+
.path-1 {
|
20
|
+
stroke: var(--ant-color-primary);
|
21
|
+
}
|
22
|
+
.path-2,
|
23
|
+
.rect-1 {
|
24
|
+
fill: var(--ant-color-primary);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
&__search {
|
29
|
+
position: sticky;
|
30
|
+
top: 0px;
|
31
|
+
z-index: 1;
|
32
|
+
margin-bottom: 10px;
|
33
|
+
}
|
34
|
+
}
|
package/dist/upload/index.scss
CHANGED
@@ -1,115 +1,115 @@
|
|
1
|
-
.yot-upload {
|
2
|
-
.ant-upload-list-item {
|
3
|
-
padding: 0;
|
4
|
-
}
|
5
|
-
.ant-upload-list-item.ant-upload-list-item-done {
|
6
|
-
.ant-upload-icon {
|
7
|
-
.anticon.anticon-paper-clip {
|
8
|
-
color: var(--ant-color-primary);
|
9
|
-
}
|
10
|
-
}
|
11
|
-
}
|
12
|
-
.ant-upload-list-item-name {
|
13
|
-
display: flex;
|
14
|
-
align-items: center;
|
15
|
-
}
|
16
|
-
|
17
|
-
&-file {
|
18
|
-
&-btn {
|
19
|
-
&__icon {
|
20
|
-
width: 16px;
|
21
|
-
height: 16px;
|
22
|
-
}
|
23
|
-
&:hover &{
|
24
|
-
&__icon {
|
25
|
-
.path-1 {
|
26
|
-
fill: var(--ant-color-primary);
|
27
|
-
width: 20px;
|
28
|
-
}
|
29
|
-
}
|
30
|
-
}
|
31
|
-
}
|
32
|
-
}
|
33
|
-
&__icon {
|
34
|
-
&--success {
|
35
|
-
width: 16px;
|
36
|
-
height: 16px;
|
37
|
-
position: absolute;
|
38
|
-
top: 0px;
|
39
|
-
right: 24px;
|
40
|
-
}
|
41
|
-
&--again {
|
42
|
-
width: 16px;
|
43
|
-
height: 16px;
|
44
|
-
position: absolute;
|
45
|
-
top: 0px;
|
46
|
-
right: 24px;
|
47
|
-
}
|
48
|
-
&--delete {
|
49
|
-
width: 16px;
|
50
|
-
height: 16px;
|
51
|
-
position: absolute;
|
52
|
-
top: 0px;
|
53
|
-
right: 2px;
|
54
|
-
}
|
55
|
-
}
|
56
|
-
|
57
|
-
&-image {
|
58
|
-
&-btn {
|
59
|
-
width: 100px;
|
60
|
-
height: 100px;
|
61
|
-
border-radius: 8px;
|
62
|
-
background-color: var(--ant-color-border-secondary);
|
63
|
-
display: flex;
|
64
|
-
align-items: center;
|
65
|
-
justify-content: center;
|
66
|
-
flex-direction: column;
|
67
|
-
&__text {
|
68
|
-
font-size: 12px;
|
69
|
-
color: var(--ant-color-text-quaternary);
|
70
|
-
margin-top: 8px;
|
71
|
-
}
|
72
|
-
}
|
73
|
-
}
|
74
|
-
&-video {
|
75
|
-
&-content {
|
76
|
-
position: relative;
|
77
|
-
width: 102px;
|
78
|
-
height: 102px;
|
79
|
-
border-radius: 4px;
|
80
|
-
cursor: pointer;
|
81
|
-
padding: 8px;
|
82
|
-
box-sizing: border-box;
|
83
|
-
border: 1px solid var(--ant-color-border-secondary);
|
84
|
-
&__video {
|
85
|
-
width: 100%;
|
86
|
-
height: 100%;
|
87
|
-
}
|
88
|
-
&:hover &{
|
89
|
-
&-icon {
|
90
|
-
z-index: 10;
|
91
|
-
transition: all;
|
92
|
-
box-sizing: border-box;
|
93
|
-
position: absolute;
|
94
|
-
top: 8px;
|
95
|
-
left: 8px;
|
96
|
-
height: 86px;
|
97
|
-
width: 86px;
|
98
|
-
/* 这里的背景色根据需求设置 */
|
99
|
-
background: rgba(0, 0, 0, 0.6) !important;
|
100
|
-
background-color: #000;
|
101
|
-
filter: Alpha(Opacity=60);
|
102
|
-
opacity: 0.6;
|
103
|
-
&--delete {
|
104
|
-
width: 16px;
|
105
|
-
height: 16px;
|
106
|
-
position: absolute;
|
107
|
-
top: 36px;
|
108
|
-
left: 40%;
|
109
|
-
cursor: pointer;
|
110
|
-
}
|
111
|
-
}
|
112
|
-
}
|
113
|
-
}
|
114
|
-
}
|
115
|
-
}
|
1
|
+
.yot-upload {
|
2
|
+
.ant-upload-list-item {
|
3
|
+
padding: 0;
|
4
|
+
}
|
5
|
+
.ant-upload-list-item.ant-upload-list-item-done {
|
6
|
+
.ant-upload-icon {
|
7
|
+
.anticon.anticon-paper-clip {
|
8
|
+
color: var(--ant-color-primary);
|
9
|
+
}
|
10
|
+
}
|
11
|
+
}
|
12
|
+
.ant-upload-list-item-name {
|
13
|
+
display: flex;
|
14
|
+
align-items: center;
|
15
|
+
}
|
16
|
+
|
17
|
+
&-file {
|
18
|
+
&-btn {
|
19
|
+
&__icon {
|
20
|
+
width: 16px;
|
21
|
+
height: 16px;
|
22
|
+
}
|
23
|
+
&:hover &{
|
24
|
+
&__icon {
|
25
|
+
.path-1 {
|
26
|
+
fill: var(--ant-color-primary);
|
27
|
+
width: 20px;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
&__icon {
|
34
|
+
&--success {
|
35
|
+
width: 16px;
|
36
|
+
height: 16px;
|
37
|
+
position: absolute;
|
38
|
+
top: 0px;
|
39
|
+
right: 24px;
|
40
|
+
}
|
41
|
+
&--again {
|
42
|
+
width: 16px;
|
43
|
+
height: 16px;
|
44
|
+
position: absolute;
|
45
|
+
top: 0px;
|
46
|
+
right: 24px;
|
47
|
+
}
|
48
|
+
&--delete {
|
49
|
+
width: 16px;
|
50
|
+
height: 16px;
|
51
|
+
position: absolute;
|
52
|
+
top: 0px;
|
53
|
+
right: 2px;
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
&-image {
|
58
|
+
&-btn {
|
59
|
+
width: 100px;
|
60
|
+
height: 100px;
|
61
|
+
border-radius: 8px;
|
62
|
+
background-color: var(--ant-color-border-secondary);
|
63
|
+
display: flex;
|
64
|
+
align-items: center;
|
65
|
+
justify-content: center;
|
66
|
+
flex-direction: column;
|
67
|
+
&__text {
|
68
|
+
font-size: 12px;
|
69
|
+
color: var(--ant-color-text-quaternary);
|
70
|
+
margin-top: 8px;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
&-video {
|
75
|
+
&-content {
|
76
|
+
position: relative;
|
77
|
+
width: 102px;
|
78
|
+
height: 102px;
|
79
|
+
border-radius: 4px;
|
80
|
+
cursor: pointer;
|
81
|
+
padding: 8px;
|
82
|
+
box-sizing: border-box;
|
83
|
+
border: 1px solid var(--ant-color-border-secondary);
|
84
|
+
&__video {
|
85
|
+
width: 100%;
|
86
|
+
height: 100%;
|
87
|
+
}
|
88
|
+
&:hover &{
|
89
|
+
&-icon {
|
90
|
+
z-index: 10;
|
91
|
+
transition: all;
|
92
|
+
box-sizing: border-box;
|
93
|
+
position: absolute;
|
94
|
+
top: 8px;
|
95
|
+
left: 8px;
|
96
|
+
height: 86px;
|
97
|
+
width: 86px;
|
98
|
+
/* 这里的背景色根据需求设置 */
|
99
|
+
background: rgba(0, 0, 0, 0.6) !important;
|
100
|
+
background-color: #000;
|
101
|
+
filter: Alpha(Opacity=60);
|
102
|
+
opacity: 0.6;
|
103
|
+
&--delete {
|
104
|
+
width: 16px;
|
105
|
+
height: 16px;
|
106
|
+
position: absolute;
|
107
|
+
top: 36px;
|
108
|
+
left: 40%;
|
109
|
+
cursor: pointer;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
@@ -1,45 +1,45 @@
|
|
1
|
-
import { SelectProps } from 'yootd';
|
2
|
-
|
3
|
-
export interface PageData<T> {
|
4
|
-
content: T[];
|
5
|
-
page: {
|
6
|
-
number: number;
|
7
|
-
size: number;
|
8
|
-
totalElements: number;
|
9
|
-
totalPages: number;
|
10
|
-
};
|
11
|
-
}
|
12
|
-
type LabelOptions =
|
13
|
-
| 'uniqueNumber'
|
14
|
-
| 'personalName'
|
15
|
-
| 'majorName'
|
16
|
-
| 'collegeMajorName'
|
17
|
-
| 'className'
|
18
|
-
| 'gradeName'
|
19
|
-
| 'genderName'
|
20
|
-
| 'deptName'
|
21
|
-
| 'credentialsNo'
|
22
|
-
| 'personalMobile';
|
23
|
-
export type UserDropdownProps = SelectProps & {
|
24
|
-
type?: number; // 1:学生2:教师3:职工
|
25
|
-
label?: LabelOptions[];
|
26
|
-
connectors?: string;
|
27
|
-
teacher_id?: number;
|
28
|
-
};
|
29
|
-
export interface IuserItem {
|
30
|
-
userId: string; // ID
|
31
|
-
uniqueNumber?: string; // 学号/工号
|
32
|
-
personalName: string; // 姓名
|
33
|
-
personalPhoto?: string; // 照片
|
34
|
-
userFaceType?: number; // 人脸类型(1白名单2黑名单3红名单)
|
35
|
-
majorName?: string; // 专业名称
|
36
|
-
collegeMajorName?: string; // 院系名称
|
37
|
-
className?: string; // 班级名称
|
38
|
-
gradeName?: string; // 年级名称
|
39
|
-
genderName?: string; // 性别
|
40
|
-
deptId?: number; // 部门ID
|
41
|
-
deptName?: string; // 部门名称
|
42
|
-
gender?: number; // 性别
|
43
|
-
credentialsNo?: string; // 证件号
|
44
|
-
personalMobile?: string; // 手机号
|
45
|
-
}
|
1
|
+
import { SelectProps } from 'yootd';
|
2
|
+
|
3
|
+
export interface PageData<T> {
|
4
|
+
content: T[];
|
5
|
+
page: {
|
6
|
+
number: number;
|
7
|
+
size: number;
|
8
|
+
totalElements: number;
|
9
|
+
totalPages: number;
|
10
|
+
};
|
11
|
+
}
|
12
|
+
type LabelOptions =
|
13
|
+
| 'uniqueNumber'
|
14
|
+
| 'personalName'
|
15
|
+
| 'majorName'
|
16
|
+
| 'collegeMajorName'
|
17
|
+
| 'className'
|
18
|
+
| 'gradeName'
|
19
|
+
| 'genderName'
|
20
|
+
| 'deptName'
|
21
|
+
| 'credentialsNo'
|
22
|
+
| 'personalMobile';
|
23
|
+
export type UserDropdownProps = SelectProps & {
|
24
|
+
type?: number; // 1:学生2:教师3:职工
|
25
|
+
label?: LabelOptions[];
|
26
|
+
connectors?: string;
|
27
|
+
teacher_id?: number;
|
28
|
+
};
|
29
|
+
export interface IuserItem {
|
30
|
+
userId: string; // ID
|
31
|
+
uniqueNumber?: string; // 学号/工号
|
32
|
+
personalName: string; // 姓名
|
33
|
+
personalPhoto?: string; // 照片
|
34
|
+
userFaceType?: number; // 人脸类型(1白名单2黑名单3红名单)
|
35
|
+
majorName?: string; // 专业名称
|
36
|
+
collegeMajorName?: string; // 院系名称
|
37
|
+
className?: string; // 班级名称
|
38
|
+
gradeName?: string; // 年级名称
|
39
|
+
genderName?: string; // 性别
|
40
|
+
deptId?: number; // 部门ID
|
41
|
+
deptName?: string; // 部门名称
|
42
|
+
gender?: number; // 性别
|
43
|
+
credentialsNo?: string; // 证件号
|
44
|
+
personalMobile?: string; // 手机号
|
45
|
+
}
|
@@ -13,9 +13,11 @@ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef,
|
|
13
13
|
import { EndPoint } from 'yootd-webrtc-sdk';
|
14
14
|
import { useBem } from "../hooks/useBem";
|
15
15
|
import "./index.scss";
|
16
|
+
import { useQuery } from '@tanstack/react-query';
|
16
17
|
import { throttle } from 'lodash';
|
17
18
|
import { Spin } from "./..";
|
18
19
|
import { useOSS } from "../hooks/useOSS";
|
20
|
+
import { useRequest } from "../hooks/useRequest";
|
19
21
|
import controlBottomBg from "./assets/control-background.png";
|
20
22
|
var PROGRESS_BAR_HEIGHT = 63;
|
21
23
|
var MIN_SCORE = 0.5; // minimum score
|
@@ -60,6 +62,7 @@ export var VideoPlayer = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
60
62
|
var poseCanvasRef = useRef(null);
|
61
63
|
var detectAllFacesRef = useRef();
|
62
64
|
var getAdjacentPairsRef = useRef();
|
65
|
+
var request = useRequest();
|
63
66
|
var _useState = useState(null),
|
64
67
|
_useState2 = _slicedToArray(_useState, 2),
|
65
68
|
poseDetector = _useState2[0],
|
@@ -163,6 +166,13 @@ export var VideoPlayer = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
163
166
|
_useState46 = _slicedToArray(_useState45, 2),
|
164
167
|
features = _useState46[0],
|
165
168
|
setFeatures = _useState46[1];
|
169
|
+
var _useQuery = useQuery({
|
170
|
+
queryKey: ['config'],
|
171
|
+
queryFn: function queryFn() {
|
172
|
+
return request.get('/v1/education/analysis/analyse/instance/config');
|
173
|
+
}
|
174
|
+
}),
|
175
|
+
configData = _useQuery.data;
|
166
176
|
useImperativeHandle(ref, function () {
|
167
177
|
return {
|
168
178
|
play: function play() {
|
@@ -371,8 +381,32 @@ export var VideoPlayer = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
371
381
|
var _iterator = _createForOfIteratorHelper(detections),
|
372
382
|
_step;
|
373
383
|
try {
|
374
|
-
|
384
|
+
var _loop = function _loop() {
|
375
385
|
var person = _step.value;
|
386
|
+
var emotionConfigMap = {
|
387
|
+
neutral: 'calm',
|
388
|
+
happy: 'happy',
|
389
|
+
sad: 'depressed',
|
390
|
+
angry: 'angry',
|
391
|
+
fearful: 'dread',
|
392
|
+
disgusted: 'detest',
|
393
|
+
surprised: 'surprised'
|
394
|
+
};
|
395
|
+
var expression = Object.entries(person.expressions).sort(function (a, b) {
|
396
|
+
return b[1] - a[1];
|
397
|
+
});
|
398
|
+
if ((configData === null || configData === void 0 ? void 0 : configData.content) != null && configData.content.length > 0) {
|
399
|
+
var _configData$content$f;
|
400
|
+
var threshold = (_configData$content$f = configData.content.find(function (item) {
|
401
|
+
return item.configKey === emotionConfigMap[expression[0][0]];
|
402
|
+
})) === null || _configData$content$f === void 0 ? void 0 : _configData$content$f.threshold;
|
403
|
+
if (threshold != null) {
|
404
|
+
if (Math.round(100 * expression[0][1]) < threshold) {
|
405
|
+
return 1; // continue
|
406
|
+
}
|
407
|
+
}
|
408
|
+
}
|
409
|
+
|
376
410
|
// draw box around each face
|
377
411
|
ctx.lineWidth = 3;
|
378
412
|
ctx.strokeStyle = '#7aff00';
|
@@ -383,9 +417,6 @@ export var VideoPlayer = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
383
417
|
ctx.stroke();
|
384
418
|
ctx.globalAlpha = 1;
|
385
419
|
// draw text labels
|
386
|
-
var expression = Object.entries(person.expressions).sort(function (a, b) {
|
387
|
-
return b[1] - a[1];
|
388
|
-
});
|
389
420
|
ctx.fillStyle = 'black';
|
390
421
|
// if (faceFeature.character) {
|
391
422
|
// ctx.fillText(
|
@@ -419,6 +450,15 @@ export var VideoPlayer = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
419
450
|
male: '男',
|
420
451
|
female: '女'
|
421
452
|
};
|
453
|
+
/* neutral: 'calm',
|
454
|
+
happy: 'happy',
|
455
|
+
sad: 'depressed',
|
456
|
+
angry: 'angry',
|
457
|
+
fearful: 'dread',
|
458
|
+
disgusted: 'detest',
|
459
|
+
surprised: 'surprised',
|
460
|
+
*/
|
461
|
+
|
422
462
|
var emotionMap = {
|
423
463
|
neutral: '平静',
|
424
464
|
happy: '开心',
|
@@ -460,13 +500,16 @@ export var VideoPlayer = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
460
500
|
ctx.fill();
|
461
501
|
}
|
462
502
|
}
|
503
|
+
};
|
504
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
505
|
+
if (_loop()) continue;
|
463
506
|
}
|
464
507
|
} catch (err) {
|
465
508
|
_iterator.e(err);
|
466
509
|
} finally {
|
467
510
|
_iterator.f();
|
468
511
|
}
|
469
|
-
}, []);
|
512
|
+
}, [configData]);
|
470
513
|
var detectFaces = useCallback(function () {
|
471
514
|
return new Promise(function (resolve, reject) {
|
472
515
|
if (videoRef.current != null && detectAllFacesRef.current != null && options != null && faceApiInitialized) {
|