@enspiredigital/xlms-headless 0.0.30 → 0.0.31
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.
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { DragDropQuestionType, DragDropAnswer } from '../types';
|
|
1
|
+
import { DragDropQuestionType, DragDropAnswer, DragDropItem } from '../types';
|
|
2
2
|
export declare function useDragDrop(question: DragDropQuestionType): {
|
|
3
|
-
items:
|
|
3
|
+
items: DragDropItem[];
|
|
4
4
|
groups: import('..').DragDropGroup[];
|
|
5
5
|
answers: DragDropAnswer[];
|
|
6
|
-
availableItems:
|
|
6
|
+
availableItems: DragDropItem[] | undefined;
|
|
7
7
|
question: DragDropQuestionType;
|
|
8
8
|
draggingItemId: string | null;
|
|
9
9
|
submitted: boolean | null;
|
|
@@ -14,7 +14,7 @@ export declare function useDragDrop(question: DragDropQuestionType): {
|
|
|
14
14
|
removeItem: (itemId: string) => void;
|
|
15
15
|
moveItem: (itemId: string, blankIndex: string) => void;
|
|
16
16
|
setDraggingItemId: import('react').Dispatch<import('react').SetStateAction<string | null>>;
|
|
17
|
-
getItemByBlankId: (blankId: string) =>
|
|
17
|
+
getItemByBlankId: (blankId: string) => DragDropItem | undefined;
|
|
18
18
|
submit: () => {
|
|
19
19
|
isCorrect: boolean;
|
|
20
20
|
correctCount: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDragDrop.d.ts","sourceRoot":"","sources":["../../src/hooks/useDragDrop.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"useDragDrop.d.ts","sourceRoot":"","sources":["../../src/hooks/useDragDrop.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG9E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,oBAAoB;;;;;;;;;;;uBA0B9B,MAAM,cAAc,MAAM;yBAiBxB,MAAM;uBAKR,MAAM,cAAc,MAAM;;gCAwDjB,MAAM;;;;;;;;;EAiC1C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGrouping.d.ts","sourceRoot":"","sources":["../../src/hooks/useGrouping.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,cAAc,EACd,YAAY,EACZ,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"useGrouping.d.ts","sourceRoot":"","sources":["../../src/hooks/useGrouping.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,cAAc,EACd,YAAY,EACZ,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAG3B,wBAAgB,WAAW,CAAC,QAAQ,EAAE,oBAAoB;;;;;;;;;;;;;;;;;;;;;;mBAalC,MAAM,cAAc,MAAM;qBAYxB,MAAM;;;;;;;EAyG/B"}
|
|
@@ -6,7 +6,7 @@ export declare function useLabeling(question: LabelingQuestionType): {
|
|
|
6
6
|
imageWidth: number | undefined;
|
|
7
7
|
imageHeight: number | undefined;
|
|
8
8
|
answers: LabelingAnswer[];
|
|
9
|
-
availableLabels: LabelingLabel[];
|
|
9
|
+
availableLabels: LabelingLabel[] | undefined;
|
|
10
10
|
question: LabelingQuestionType;
|
|
11
11
|
submitted: boolean | null;
|
|
12
12
|
isCorrect: boolean | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLabeling.d.ts","sourceRoot":"","sources":["../../src/hooks/useLabeling.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"useLabeling.d.ts","sourceRoot":"","sources":["../../src/hooks/useLabeling.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG/E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,oBAAoB;;;;;;;;;;;;;2BAyB7C,MAAM,WACN,MAAM,MACX,MAAM,MACN,MAAM;2BAwBkB,MAAM;yBAMzB,MAAM,cACH,MAAM,MACd,MAAM,MACN,MAAM;+BAMsB,MAAM,KAAG,aAAa,GAAG,IAAI;gCAY5B,MAAM,KAAG,MAAM,GAAG,IAAI;;;;;;;EAmF1D"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { useState as A, useRef as
|
|
2
|
-
import { jsx as
|
|
1
|
+
import { useState as A, useRef as O, useEffect as D, useMemo as F, useCallback as B } from "react";
|
|
2
|
+
import { jsx as z, Fragment as G } from "react/jsx-runtime";
|
|
3
3
|
function E() {
|
|
4
|
-
const [t, n] = A(null), [u, f] = A(null), [
|
|
5
|
-
function
|
|
6
|
-
n(!0),
|
|
4
|
+
const [t, n] = A(null), [u, f] = A(null), [m, C] = A(0);
|
|
5
|
+
function S(l) {
|
|
6
|
+
n(!0), l !== void 0 && f(l), C((b) => b + 1);
|
|
7
7
|
}
|
|
8
8
|
function o() {
|
|
9
9
|
n(!1), f(null);
|
|
@@ -12,11 +12,11 @@ function E() {
|
|
|
12
12
|
// state
|
|
13
13
|
submitted: t,
|
|
14
14
|
isCorrect: u,
|
|
15
|
-
attempts:
|
|
15
|
+
attempts: m,
|
|
16
16
|
// derived
|
|
17
17
|
canAnswer: !t,
|
|
18
18
|
// actions
|
|
19
|
-
submitQuestion:
|
|
19
|
+
submitQuestion: S,
|
|
20
20
|
resetQuestion: o
|
|
21
21
|
};
|
|
22
22
|
}
|
|
@@ -24,11 +24,11 @@ function J(t, n) {
|
|
|
24
24
|
if (t.length !== n.length) return !1;
|
|
25
25
|
const u = new Set(t), f = new Set(n);
|
|
26
26
|
if (u.size !== f.size) return !1;
|
|
27
|
-
for (const
|
|
28
|
-
if (!f.has(
|
|
27
|
+
for (const m of u)
|
|
28
|
+
if (!f.has(m)) return !1;
|
|
29
29
|
return !0;
|
|
30
30
|
}
|
|
31
|
-
function
|
|
31
|
+
function V(t) {
|
|
32
32
|
const n = [...t];
|
|
33
33
|
for (let u = n.length - 1; u > 0; u--) {
|
|
34
34
|
const f = Math.floor(Math.random() * (u + 1));
|
|
@@ -41,36 +41,36 @@ function X(t) {
|
|
|
41
41
|
canAnswer: n,
|
|
42
42
|
submitted: u,
|
|
43
43
|
isCorrect: f,
|
|
44
|
-
attempts:
|
|
45
|
-
resetQuestion:
|
|
46
|
-
submitQuestion:
|
|
47
|
-
} = E(), [o,
|
|
48
|
-
function
|
|
49
|
-
|
|
44
|
+
attempts: m,
|
|
45
|
+
resetQuestion: C,
|
|
46
|
+
submitQuestion: S
|
|
47
|
+
} = E(), [o, l] = A([]);
|
|
48
|
+
function b(w) {
|
|
49
|
+
l((p) => t.options.allowMultipleAnswers ? p.includes(w) ? p.filter((d) => d !== w) : [...p, w] : [w]);
|
|
50
50
|
}
|
|
51
51
|
function I() {
|
|
52
52
|
if (o.length === 0) return;
|
|
53
53
|
const w = t.options.answers.reduce(
|
|
54
|
-
(
|
|
54
|
+
(d, x) => (x.is_correct && d.push(x.id), d),
|
|
55
55
|
[]
|
|
56
|
-
),
|
|
57
|
-
|
|
56
|
+
), p = J(o, w);
|
|
57
|
+
S(p);
|
|
58
58
|
}
|
|
59
59
|
function Q() {
|
|
60
|
-
|
|
60
|
+
l([]), C();
|
|
61
61
|
}
|
|
62
62
|
return {
|
|
63
63
|
// data
|
|
64
64
|
question: t,
|
|
65
65
|
selectedIds: o,
|
|
66
66
|
// actions
|
|
67
|
-
select:
|
|
67
|
+
select: b,
|
|
68
68
|
submit: I,
|
|
69
69
|
reset: Q,
|
|
70
70
|
// base
|
|
71
71
|
submitted: u,
|
|
72
72
|
isCorrect: f,
|
|
73
|
-
attempts:
|
|
73
|
+
attempts: m,
|
|
74
74
|
canAnswer: n
|
|
75
75
|
};
|
|
76
76
|
}
|
|
@@ -79,84 +79,84 @@ function Y(t) {
|
|
|
79
79
|
canAnswer: n,
|
|
80
80
|
submitted: u,
|
|
81
81
|
isCorrect: f,
|
|
82
|
-
attempts:
|
|
83
|
-
submitQuestion:
|
|
84
|
-
resetQuestion:
|
|
85
|
-
} = E(), [o,
|
|
82
|
+
attempts: m,
|
|
83
|
+
submitQuestion: C,
|
|
84
|
+
resetQuestion: S
|
|
85
|
+
} = E(), [o, l] = A([]), [b, I] = A(
|
|
86
86
|
[]
|
|
87
87
|
), [Q, w] = A(
|
|
88
88
|
[]
|
|
89
|
-
),
|
|
90
|
-
function
|
|
91
|
-
|
|
92
|
-
...
|
|
93
|
-
(
|
|
89
|
+
), p = O([]);
|
|
90
|
+
function d(e, r) {
|
|
91
|
+
l((c) => [
|
|
92
|
+
...c.filter(
|
|
93
|
+
(g) => g.targetId !== e && g.sourceId !== r
|
|
94
94
|
),
|
|
95
|
-
{ targetId: e, sourceId:
|
|
95
|
+
{ targetId: e, sourceId: r }
|
|
96
96
|
]);
|
|
97
97
|
}
|
|
98
|
-
function x(e,
|
|
99
|
-
|
|
100
|
-
(
|
|
98
|
+
function x(e, r) {
|
|
99
|
+
l(
|
|
100
|
+
(c) => c.filter((g) => g.targetId !== e || g.sourceId !== r)
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
|
-
function
|
|
104
|
-
let e = 0,
|
|
105
|
-
return t.options.targets.forEach((
|
|
106
|
-
const
|
|
107
|
-
|
|
103
|
+
function h() {
|
|
104
|
+
let e = 0, r = !0;
|
|
105
|
+
return t.options.targets.forEach((c) => {
|
|
106
|
+
const g = o.find((U) => U.targetId === c.id), v = t.options.sources[c.content.correct_position - 1];
|
|
107
|
+
g && v && g.sourceId === v.id ? e += c.content.point : r = !1;
|
|
108
108
|
}), {
|
|
109
|
-
isCorrect:
|
|
109
|
+
isCorrect: r,
|
|
110
110
|
score: e,
|
|
111
111
|
maxScore: t.options.targets.reduce(
|
|
112
|
-
(
|
|
112
|
+
(c, g) => c + g.content.point,
|
|
113
113
|
0
|
|
114
114
|
)
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
|
-
function
|
|
118
|
-
const e =
|
|
119
|
-
return
|
|
117
|
+
function s() {
|
|
118
|
+
const e = h();
|
|
119
|
+
return C(e.isCorrect), e;
|
|
120
120
|
}
|
|
121
|
-
function
|
|
122
|
-
|
|
121
|
+
function a() {
|
|
122
|
+
l([]), S();
|
|
123
123
|
}
|
|
124
|
-
function
|
|
125
|
-
const
|
|
126
|
-
return t.options.targets.find((
|
|
124
|
+
function i(e) {
|
|
125
|
+
const r = o.find((c) => c.sourceId === e)?.targetId;
|
|
126
|
+
return t.options.targets.find((c) => c.id === r);
|
|
127
127
|
}
|
|
128
|
-
return
|
|
128
|
+
return D(() => {
|
|
129
129
|
const e = t.options.sources.filter(
|
|
130
|
-
(
|
|
130
|
+
(r) => !o.some((c) => c.sourceId === r.id)
|
|
131
131
|
);
|
|
132
132
|
I(e);
|
|
133
|
-
}, [o, t.options.sources]),
|
|
134
|
-
if (
|
|
135
|
-
const e =
|
|
136
|
-
(
|
|
133
|
+
}, [o, t.options.sources]), D(() => {
|
|
134
|
+
if (p.current.length === 0) return;
|
|
135
|
+
const e = p.current.filter(
|
|
136
|
+
(r) => !o.some((c) => c.targetId === r.id)
|
|
137
137
|
);
|
|
138
138
|
w(e);
|
|
139
|
-
}, [o]),
|
|
140
|
-
|
|
139
|
+
}, [o]), D(() => {
|
|
140
|
+
p.current = V(t.options.targets);
|
|
141
141
|
}, [t.options.targets]), {
|
|
142
142
|
// data
|
|
143
143
|
sources: t.options.sources,
|
|
144
144
|
targets: t.options.targets,
|
|
145
145
|
answers: o,
|
|
146
146
|
question: t,
|
|
147
|
-
availableSources:
|
|
147
|
+
availableSources: b,
|
|
148
148
|
availableTargets: Q,
|
|
149
149
|
// base
|
|
150
150
|
submitted: u,
|
|
151
151
|
isCorrect: f,
|
|
152
|
-
attempts:
|
|
152
|
+
attempts: m,
|
|
153
153
|
canAnswer: n,
|
|
154
154
|
// actions
|
|
155
|
-
getTargetBySourceId:
|
|
156
|
-
select:
|
|
155
|
+
getTargetBySourceId: i,
|
|
156
|
+
select: d,
|
|
157
157
|
remove: x,
|
|
158
|
-
submit:
|
|
159
|
-
reset:
|
|
158
|
+
submit: s,
|
|
159
|
+
reset: a
|
|
160
160
|
};
|
|
161
161
|
}
|
|
162
162
|
function Z(t) {
|
|
@@ -164,15 +164,15 @@ function Z(t) {
|
|
|
164
164
|
canAnswer: n,
|
|
165
165
|
submitted: u,
|
|
166
166
|
isCorrect: f,
|
|
167
|
-
attempts:
|
|
168
|
-
resetQuestion:
|
|
169
|
-
submitQuestion:
|
|
167
|
+
attempts: m,
|
|
168
|
+
resetQuestion: C,
|
|
169
|
+
submitQuestion: S
|
|
170
170
|
} = E();
|
|
171
171
|
function o() {
|
|
172
|
-
|
|
172
|
+
S(!0);
|
|
173
173
|
}
|
|
174
|
-
function
|
|
175
|
-
|
|
174
|
+
function l() {
|
|
175
|
+
C();
|
|
176
176
|
}
|
|
177
177
|
return {
|
|
178
178
|
// data
|
|
@@ -181,11 +181,11 @@ function Z(t) {
|
|
|
181
181
|
type: t.options.urlType,
|
|
182
182
|
// actions
|
|
183
183
|
submit: o,
|
|
184
|
-
reset:
|
|
184
|
+
reset: l,
|
|
185
185
|
// base
|
|
186
186
|
submitted: u,
|
|
187
187
|
isCorrect: f,
|
|
188
|
-
attempts:
|
|
188
|
+
attempts: m,
|
|
189
189
|
canAnswer: n
|
|
190
190
|
};
|
|
191
191
|
}
|
|
@@ -194,83 +194,86 @@ function K(t) {
|
|
|
194
194
|
canAnswer: n,
|
|
195
195
|
submitted: u,
|
|
196
196
|
isCorrect: f,
|
|
197
|
-
attempts:
|
|
198
|
-
submitQuestion:
|
|
199
|
-
resetQuestion:
|
|
200
|
-
} = E(), [o,
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
197
|
+
attempts: m,
|
|
198
|
+
submitQuestion: C,
|
|
199
|
+
resetQuestion: S
|
|
200
|
+
} = E(), [o, l] = A([]), [b, I] = A(null), Q = O([]), w = F(() => {
|
|
201
|
+
if (Q.current.length === 0) return;
|
|
202
|
+
const e = new Set(o.map((r) => r.itemId));
|
|
203
|
+
return Q.current.filter(
|
|
204
|
+
(r) => !e.has(String(r.id))
|
|
204
205
|
);
|
|
205
|
-
}, [o
|
|
206
|
-
function
|
|
207
|
-
|
|
208
|
-
...
|
|
209
|
-
(
|
|
206
|
+
}, [o]);
|
|
207
|
+
function p(e, r) {
|
|
208
|
+
l((c) => [
|
|
209
|
+
...c.filter(
|
|
210
|
+
(v) => v.blankIndex !== r && v.itemId !== e
|
|
210
211
|
),
|
|
211
212
|
{
|
|
212
|
-
itemId:
|
|
213
|
-
blankIndex:
|
|
213
|
+
itemId: e,
|
|
214
|
+
blankIndex: r
|
|
214
215
|
}
|
|
215
216
|
]);
|
|
216
217
|
}
|
|
217
|
-
function
|
|
218
|
-
|
|
218
|
+
function d(e) {
|
|
219
|
+
l((r) => r.filter((c) => c.itemId !== e));
|
|
219
220
|
}
|
|
220
|
-
function
|
|
221
|
-
|
|
221
|
+
function x(e, r) {
|
|
222
|
+
p(e, r);
|
|
222
223
|
}
|
|
223
|
-
function
|
|
224
|
-
let
|
|
225
|
-
const
|
|
226
|
-
return Object.entries(
|
|
227
|
-
const
|
|
228
|
-
if (!
|
|
229
|
-
|
|
224
|
+
function h() {
|
|
225
|
+
let e = 0, r = !0, c = 0;
|
|
226
|
+
const g = t.correct_answers.list, v = new Map(o.map((U) => [U.blankIndex, U.itemId]));
|
|
227
|
+
return Object.entries(g).forEach(([U, k]) => {
|
|
228
|
+
const _ = U, T = v.get(_);
|
|
229
|
+
if (!T) {
|
|
230
|
+
r = !1;
|
|
230
231
|
return;
|
|
231
232
|
}
|
|
232
|
-
const M = t.options.answers.find((
|
|
233
|
-
M && String(M.group_position) === String(
|
|
233
|
+
const M = t.options.answers.find((j) => j.id === T);
|
|
234
|
+
M && String(M.group_position) === String(k) ? (e++, c += M.point) : r = !1;
|
|
234
235
|
}), {
|
|
235
|
-
isCorrect:
|
|
236
|
-
correctCount:
|
|
237
|
-
totalCount: Object.keys(
|
|
236
|
+
isCorrect: r,
|
|
237
|
+
correctCount: e,
|
|
238
|
+
totalCount: Object.keys(g).length,
|
|
238
239
|
maxScore: t.metadata.points,
|
|
239
|
-
score:
|
|
240
|
+
score: c
|
|
240
241
|
};
|
|
241
242
|
}
|
|
242
|
-
function
|
|
243
|
-
const
|
|
244
|
-
return
|
|
243
|
+
function s() {
|
|
244
|
+
const e = h();
|
|
245
|
+
return C(e.isCorrect), e;
|
|
245
246
|
}
|
|
246
|
-
function
|
|
247
|
-
|
|
247
|
+
function a() {
|
|
248
|
+
l([]), S();
|
|
248
249
|
}
|
|
249
|
-
function i(
|
|
250
|
-
const
|
|
251
|
-
return t.options.answers.find((
|
|
250
|
+
function i(e) {
|
|
251
|
+
const r = o.find((c) => c.blankIndex === e)?.itemId;
|
|
252
|
+
return t.options.answers.find((c) => c.id === r);
|
|
252
253
|
}
|
|
253
|
-
return {
|
|
254
|
+
return D(() => {
|
|
255
|
+
Q.current = V(t.options.answers);
|
|
256
|
+
}, [t.options.answers]), {
|
|
254
257
|
// data
|
|
255
258
|
items: t.options.answers,
|
|
256
259
|
groups: t.options.groups,
|
|
257
260
|
answers: o,
|
|
258
|
-
availableItems:
|
|
261
|
+
availableItems: w,
|
|
259
262
|
question: t,
|
|
260
|
-
draggingItemId:
|
|
263
|
+
draggingItemId: b,
|
|
261
264
|
// base
|
|
262
265
|
submitted: u,
|
|
263
266
|
isCorrect: f,
|
|
264
|
-
attempts:
|
|
267
|
+
attempts: m,
|
|
265
268
|
canAnswer: n,
|
|
266
269
|
// actions
|
|
267
|
-
dropItem:
|
|
268
|
-
removeItem:
|
|
269
|
-
moveItem:
|
|
270
|
+
dropItem: p,
|
|
271
|
+
removeItem: d,
|
|
272
|
+
moveItem: x,
|
|
270
273
|
setDraggingItemId: I,
|
|
271
274
|
getItemByBlankId: i,
|
|
272
|
-
submit:
|
|
273
|
-
reset:
|
|
275
|
+
submit: s,
|
|
276
|
+
reset: a
|
|
274
277
|
};
|
|
275
278
|
}
|
|
276
279
|
function H(t) {
|
|
@@ -278,73 +281,73 @@ function H(t) {
|
|
|
278
281
|
canAnswer: n,
|
|
279
282
|
submitted: u,
|
|
280
283
|
isCorrect: f,
|
|
281
|
-
attempts:
|
|
282
|
-
submitQuestion:
|
|
283
|
-
resetQuestion:
|
|
284
|
-
} = E(), [o,
|
|
285
|
-
t.options.answers.map((
|
|
286
|
-
)),
|
|
287
|
-
(
|
|
288
|
-
).filter((
|
|
289
|
-
function I(
|
|
290
|
-
|
|
291
|
-
const e = [...
|
|
292
|
-
return e.splice(
|
|
284
|
+
attempts: m,
|
|
285
|
+
submitQuestion: C,
|
|
286
|
+
resetQuestion: S
|
|
287
|
+
} = E(), [o, l] = A(() => V(
|
|
288
|
+
t.options.answers.map((s) => String(s.id))
|
|
289
|
+
)), b = F(() => o.map(
|
|
290
|
+
(s) => t.options.answers.find((a) => String(a.id) === s)
|
|
291
|
+
).filter((s) => s !== void 0), [o, t.options.answers]);
|
|
292
|
+
function I(s, a) {
|
|
293
|
+
l((i) => {
|
|
294
|
+
const e = [...i], [r] = e.splice(s, 1);
|
|
295
|
+
return e.splice(a, 0, r), e;
|
|
293
296
|
});
|
|
294
297
|
}
|
|
295
|
-
function Q(
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
+
function Q(s) {
|
|
299
|
+
const a = o.indexOf(s);
|
|
300
|
+
a > 0 && I(a, a - 1);
|
|
298
301
|
}
|
|
299
|
-
function w(
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
+
function w(s) {
|
|
303
|
+
const a = o.indexOf(s);
|
|
304
|
+
a < o.length - 1 && I(a, a + 1);
|
|
302
305
|
}
|
|
303
|
-
function
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
+
function p(s, a) {
|
|
307
|
+
const i = o.indexOf(s);
|
|
308
|
+
i !== -1 && a >= 0 && a < o.length && I(i, a);
|
|
306
309
|
}
|
|
307
|
-
function
|
|
308
|
-
let
|
|
309
|
-
return t.options.answers.forEach((
|
|
310
|
-
const
|
|
311
|
-
|
|
310
|
+
function d() {
|
|
311
|
+
let s = 0, a = !0;
|
|
312
|
+
return t.options.answers.forEach((i, e) => {
|
|
313
|
+
const r = o.indexOf(String(i.id));
|
|
314
|
+
r !== -1 && r + 1 === i.correct_position ? s += i.point : a = !1;
|
|
312
315
|
}), {
|
|
313
|
-
isCorrect:
|
|
314
|
-
score:
|
|
316
|
+
isCorrect: a,
|
|
317
|
+
score: s,
|
|
315
318
|
maxScore: t.options.answers.reduce(
|
|
316
|
-
(
|
|
319
|
+
(i, e) => i + e.point,
|
|
317
320
|
0
|
|
318
321
|
)
|
|
319
322
|
};
|
|
320
323
|
}
|
|
321
324
|
function x() {
|
|
322
|
-
const
|
|
323
|
-
return
|
|
325
|
+
const s = d();
|
|
326
|
+
return C(s.isCorrect), s;
|
|
324
327
|
}
|
|
325
|
-
function
|
|
326
|
-
|
|
328
|
+
function h() {
|
|
329
|
+
l(t.options.answers.map((s) => String(s.id))), S();
|
|
327
330
|
}
|
|
328
331
|
return {
|
|
329
332
|
// data
|
|
330
333
|
items: t.options.answers,
|
|
331
334
|
groups: t.options.groups,
|
|
332
|
-
orderedItems:
|
|
335
|
+
orderedItems: b,
|
|
333
336
|
orderedItemIds: o,
|
|
334
337
|
question: t,
|
|
335
338
|
// base
|
|
336
339
|
submitted: u,
|
|
337
340
|
isCorrect: f,
|
|
338
|
-
attempts:
|
|
341
|
+
attempts: m,
|
|
339
342
|
canAnswer: n,
|
|
340
343
|
// actions
|
|
341
|
-
setOrderedItemIds:
|
|
344
|
+
setOrderedItemIds: l,
|
|
342
345
|
moveItem: I,
|
|
343
346
|
moveUp: Q,
|
|
344
347
|
moveDown: w,
|
|
345
|
-
moveToPosition:
|
|
348
|
+
moveToPosition: p,
|
|
346
349
|
submit: x,
|
|
347
|
-
reset:
|
|
350
|
+
reset: h
|
|
348
351
|
};
|
|
349
352
|
}
|
|
350
353
|
function q(t) {
|
|
@@ -352,71 +355,74 @@ function q(t) {
|
|
|
352
355
|
canAnswer: n,
|
|
353
356
|
submitted: u,
|
|
354
357
|
isCorrect: f,
|
|
355
|
-
attempts:
|
|
356
|
-
submitQuestion:
|
|
357
|
-
resetQuestion:
|
|
358
|
-
} = E(), [o,
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
358
|
+
attempts: m,
|
|
359
|
+
submitQuestion: C,
|
|
360
|
+
resetQuestion: S
|
|
361
|
+
} = E(), [o, l] = A([]), b = O([]), I = F(() => {
|
|
362
|
+
if (b.current.length === 0) return;
|
|
363
|
+
const i = new Set(o.map((e) => e.labelId));
|
|
364
|
+
return b.current.filter(
|
|
365
|
+
(e) => !i.has(String(e.id))
|
|
362
366
|
);
|
|
363
|
-
}, [o
|
|
364
|
-
function
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
...
|
|
368
|
-
(
|
|
367
|
+
}, [o]);
|
|
368
|
+
function Q(i, e, r, c) {
|
|
369
|
+
const g = t.options.blanks.find((v) => String(v.id) === e);
|
|
370
|
+
g && l((v) => [
|
|
371
|
+
...v.filter(
|
|
372
|
+
(k) => k.labelId !== i && k.blankId !== e
|
|
369
373
|
),
|
|
370
374
|
{
|
|
371
375
|
labelId: i,
|
|
372
|
-
blankId:
|
|
373
|
-
x:
|
|
374
|
-
y:
|
|
376
|
+
blankId: e,
|
|
377
|
+
x: r ?? g.coordinates.x,
|
|
378
|
+
y: c ?? g.coordinates.y
|
|
375
379
|
}
|
|
376
380
|
]);
|
|
377
381
|
}
|
|
378
|
-
function
|
|
379
|
-
|
|
382
|
+
function w(i) {
|
|
383
|
+
l((e) => e.filter((r) => r.labelId !== i));
|
|
380
384
|
}
|
|
381
|
-
function
|
|
382
|
-
|
|
385
|
+
function p(i, e, r, c) {
|
|
386
|
+
Q(i, e, r, c);
|
|
383
387
|
}
|
|
384
|
-
function
|
|
385
|
-
const
|
|
386
|
-
return
|
|
387
|
-
(
|
|
388
|
+
function d(i) {
|
|
389
|
+
const e = o.find((r) => r.blankId === i);
|
|
390
|
+
return e && t.options.labels.find(
|
|
391
|
+
(r) => String(r.id) === e.labelId
|
|
388
392
|
) || null;
|
|
389
393
|
}
|
|
390
|
-
function
|
|
391
|
-
const
|
|
392
|
-
return
|
|
393
|
-
}
|
|
394
|
-
function
|
|
395
|
-
let i = 0,
|
|
396
|
-
return t.options.labels.forEach((
|
|
397
|
-
const
|
|
398
|
-
(
|
|
399
|
-
),
|
|
400
|
-
(
|
|
394
|
+
function x(i) {
|
|
395
|
+
const e = o.find((r) => r.labelId === i);
|
|
396
|
+
return e ? e.blankId : null;
|
|
397
|
+
}
|
|
398
|
+
function h() {
|
|
399
|
+
let i = 0, e = !0;
|
|
400
|
+
return t.options.labels.forEach((r) => {
|
|
401
|
+
const c = o.find(
|
|
402
|
+
(v) => String(v.labelId) === String(r.id)
|
|
403
|
+
), g = t.options.blanks.find(
|
|
404
|
+
(v, U) => U + 1 === r.correct_position
|
|
401
405
|
);
|
|
402
|
-
|
|
406
|
+
c && g && c.blankId === String(g.id) ? i += r.point : e = !1;
|
|
403
407
|
}), {
|
|
404
|
-
isCorrect:
|
|
408
|
+
isCorrect: e,
|
|
405
409
|
score: i,
|
|
406
410
|
maxScore: t.options.labels.reduce(
|
|
407
|
-
(
|
|
411
|
+
(r, c) => r + c.point,
|
|
408
412
|
0
|
|
409
413
|
)
|
|
410
414
|
};
|
|
411
415
|
}
|
|
412
|
-
function
|
|
413
|
-
const i =
|
|
414
|
-
return
|
|
416
|
+
function s() {
|
|
417
|
+
const i = h();
|
|
418
|
+
return C(i.isCorrect), i;
|
|
415
419
|
}
|
|
416
|
-
function
|
|
417
|
-
|
|
420
|
+
function a() {
|
|
421
|
+
l([]), S();
|
|
418
422
|
}
|
|
419
|
-
return {
|
|
423
|
+
return D(() => {
|
|
424
|
+
b.current = V(t.options.labels);
|
|
425
|
+
}, [t.options.labels]), {
|
|
420
426
|
// data
|
|
421
427
|
labels: t.options.labels,
|
|
422
428
|
blanks: t.options.blanks,
|
|
@@ -424,21 +430,21 @@ function q(t) {
|
|
|
424
430
|
imageWidth: t.image_width,
|
|
425
431
|
imageHeight: t.image_height,
|
|
426
432
|
answers: o,
|
|
427
|
-
availableLabels:
|
|
433
|
+
availableLabels: I,
|
|
428
434
|
question: t,
|
|
429
435
|
// base
|
|
430
436
|
submitted: u,
|
|
431
437
|
isCorrect: f,
|
|
432
|
-
attempts:
|
|
438
|
+
attempts: m,
|
|
433
439
|
canAnswer: n,
|
|
434
440
|
// actions
|
|
435
|
-
attachLabel:
|
|
436
|
-
removeLabel:
|
|
437
|
-
moveLabel:
|
|
438
|
-
getLabelAtBlank:
|
|
439
|
-
getBlankForLabel:
|
|
440
|
-
submit:
|
|
441
|
-
reset:
|
|
441
|
+
attachLabel: Q,
|
|
442
|
+
removeLabel: w,
|
|
443
|
+
moveLabel: p,
|
|
444
|
+
getLabelAtBlank: d,
|
|
445
|
+
getBlankForLabel: x,
|
|
446
|
+
submit: s,
|
|
447
|
+
reset: a
|
|
442
448
|
};
|
|
443
449
|
}
|
|
444
450
|
function tt(t) {
|
|
@@ -446,44 +452,44 @@ function tt(t) {
|
|
|
446
452
|
canAnswer: n,
|
|
447
453
|
submitted: u,
|
|
448
454
|
isCorrect: f,
|
|
449
|
-
attempts:
|
|
450
|
-
submitQuestion:
|
|
451
|
-
resetQuestion:
|
|
452
|
-
} = E(), [o,
|
|
453
|
-
function
|
|
454
|
-
|
|
455
|
-
const
|
|
456
|
-
if (
|
|
457
|
-
const
|
|
458
|
-
return
|
|
455
|
+
attempts: m,
|
|
456
|
+
submitQuestion: C,
|
|
457
|
+
resetQuestion: S
|
|
458
|
+
} = E(), [o, l] = A([]);
|
|
459
|
+
function b(p, d) {
|
|
460
|
+
l((x) => {
|
|
461
|
+
const h = x.findIndex((s) => s.blankId === p);
|
|
462
|
+
if (h >= 0) {
|
|
463
|
+
const s = [...x];
|
|
464
|
+
return s[h] = { blankId: p, value: d }, s;
|
|
459
465
|
}
|
|
460
|
-
return [...x, { blankId:
|
|
466
|
+
return [...x, { blankId: p, value: d }];
|
|
461
467
|
});
|
|
462
468
|
}
|
|
463
469
|
function I() {
|
|
464
|
-
let
|
|
465
|
-
const
|
|
466
|
-
Object.entries(
|
|
467
|
-
const
|
|
468
|
-
(
|
|
469
|
-
),
|
|
470
|
-
x +=
|
|
471
|
-
const
|
|
472
|
-
(
|
|
470
|
+
let p = 0, d = 0, x = 0;
|
|
471
|
+
const h = t.correct_answers.list || {}, s = Object.keys(h).length;
|
|
472
|
+
Object.entries(h).forEach(([i, e]) => {
|
|
473
|
+
const r = String(e).trim().toLowerCase(), c = t.options.answers.find(
|
|
474
|
+
(k) => k.correct_position === Number(i)
|
|
475
|
+
), g = c && c.point || 1;
|
|
476
|
+
x += g;
|
|
477
|
+
const v = o.find((k) => k.blankId === i);
|
|
478
|
+
(v ? String(v.value).trim().toLowerCase() : "") === r && (p += g, d++);
|
|
473
479
|
});
|
|
474
|
-
const
|
|
475
|
-
return x === 0 &&
|
|
476
|
-
isCorrect:
|
|
477
|
-
score: Math.round(
|
|
480
|
+
const a = d === s && s > 0;
|
|
481
|
+
return x === 0 && s > 0 && (x = s), {
|
|
482
|
+
isCorrect: a,
|
|
483
|
+
score: Math.round(p * 100) / 100,
|
|
478
484
|
maxScore: Math.round(x * 100) / 100
|
|
479
485
|
};
|
|
480
486
|
}
|
|
481
487
|
function Q() {
|
|
482
|
-
const
|
|
483
|
-
return
|
|
488
|
+
const p = I();
|
|
489
|
+
return C(p.isCorrect), p;
|
|
484
490
|
}
|
|
485
491
|
function w() {
|
|
486
|
-
|
|
492
|
+
l([]), S();
|
|
487
493
|
}
|
|
488
494
|
return {
|
|
489
495
|
// data
|
|
@@ -493,10 +499,10 @@ function tt(t) {
|
|
|
493
499
|
// base
|
|
494
500
|
submitted: u,
|
|
495
501
|
isCorrect: f,
|
|
496
|
-
attempts:
|
|
502
|
+
attempts: m,
|
|
497
503
|
canAnswer: n,
|
|
498
504
|
// actions
|
|
499
|
-
answer:
|
|
505
|
+
answer: b,
|
|
500
506
|
submit: Q,
|
|
501
507
|
reset: w
|
|
502
508
|
};
|
|
@@ -506,75 +512,77 @@ function et(t) {
|
|
|
506
512
|
canAnswer: n,
|
|
507
513
|
submitted: u,
|
|
508
514
|
isCorrect: f,
|
|
509
|
-
attempts:
|
|
510
|
-
submitQuestion:
|
|
511
|
-
resetQuestion:
|
|
512
|
-
} = E(), [o,
|
|
513
|
-
function
|
|
514
|
-
|
|
515
|
-
const
|
|
516
|
-
if (
|
|
517
|
-
const
|
|
518
|
-
return e
|
|
515
|
+
attempts: m,
|
|
516
|
+
submitQuestion: C,
|
|
517
|
+
resetQuestion: S
|
|
518
|
+
} = E(), [o, l] = A([]), b = O([]);
|
|
519
|
+
function I(s, a) {
|
|
520
|
+
l((i) => {
|
|
521
|
+
const e = i.findIndex((r) => r.itemId === s);
|
|
522
|
+
if (e >= 0) {
|
|
523
|
+
const r = [...i];
|
|
524
|
+
return r[e] = { itemId: s, categoryId: a }, r;
|
|
519
525
|
}
|
|
520
|
-
return [...i, { itemId:
|
|
526
|
+
return [...i, { itemId: s, categoryId: a }];
|
|
521
527
|
});
|
|
522
528
|
}
|
|
523
|
-
function
|
|
524
|
-
|
|
529
|
+
function Q(s) {
|
|
530
|
+
l((a) => a.filter((i) => i.itemId !== s));
|
|
525
531
|
}
|
|
526
|
-
function
|
|
527
|
-
let
|
|
528
|
-
const
|
|
529
|
-
let
|
|
530
|
-
return Object.entries(
|
|
531
|
-
const
|
|
532
|
-
|
|
533
|
-
const
|
|
534
|
-
|
|
535
|
-
}),
|
|
536
|
-
isCorrect:
|
|
537
|
-
score:
|
|
538
|
-
maxScore:
|
|
532
|
+
function w() {
|
|
533
|
+
let s = 0, a = 0;
|
|
534
|
+
const e = t.correct_answers.list || {}, r = Object.keys(e).length;
|
|
535
|
+
let c = 0;
|
|
536
|
+
return Object.entries(e).forEach(([v, U]) => {
|
|
537
|
+
const k = t.options.items.find((M) => M.id === v), _ = k ? k.point : 0;
|
|
538
|
+
c += _;
|
|
539
|
+
const T = o.find((M) => M.itemId === v);
|
|
540
|
+
T && T.categoryId === U && (s += _, a++);
|
|
541
|
+
}), s = Math.round(s * 100) / 100, c = Math.round(c * 100) / 100, {
|
|
542
|
+
isCorrect: a === r && r > 0,
|
|
543
|
+
score: s,
|
|
544
|
+
maxScore: c
|
|
539
545
|
};
|
|
540
546
|
}
|
|
541
|
-
function
|
|
542
|
-
const
|
|
543
|
-
return
|
|
547
|
+
function p() {
|
|
548
|
+
const s = w();
|
|
549
|
+
return C(s.isCorrect), s;
|
|
544
550
|
}
|
|
545
|
-
function
|
|
546
|
-
|
|
551
|
+
function d() {
|
|
552
|
+
l([]), S();
|
|
547
553
|
}
|
|
548
|
-
const
|
|
549
|
-
(
|
|
550
|
-
), [
|
|
551
|
-
const
|
|
552
|
-
...t.options.items.find((
|
|
554
|
+
const x = F(() => b.current.filter(
|
|
555
|
+
(s) => !o.some((a) => a.itemId === s.id)
|
|
556
|
+
), [o]), h = F(() => t.options.categories.map((s) => {
|
|
557
|
+
const a = o.filter((i) => i.categoryId === s.id).map((i) => ({
|
|
558
|
+
...t.options.items.find((r) => r.id === i.itemId)
|
|
553
559
|
}));
|
|
554
560
|
return {
|
|
555
|
-
...
|
|
556
|
-
items:
|
|
561
|
+
...s,
|
|
562
|
+
items: a
|
|
557
563
|
};
|
|
558
564
|
}), [t.options.categories, t.options.items, o]);
|
|
559
|
-
return {
|
|
565
|
+
return D(() => {
|
|
566
|
+
b.current = V(t.options.items);
|
|
567
|
+
}, [t.options.items]), {
|
|
560
568
|
// data
|
|
561
569
|
categories: t.options.categories,
|
|
562
570
|
allItems: t.options.items,
|
|
563
571
|
question: t,
|
|
564
|
-
categoriesWithItems:
|
|
572
|
+
categoriesWithItems: h,
|
|
565
573
|
// state
|
|
566
574
|
answers: o,
|
|
567
|
-
unassignedItems:
|
|
575
|
+
unassignedItems: x,
|
|
568
576
|
// base
|
|
569
577
|
submitted: u,
|
|
570
578
|
isCorrect: f,
|
|
571
|
-
attempts:
|
|
579
|
+
attempts: m,
|
|
572
580
|
canAnswer: n,
|
|
573
581
|
// actions
|
|
574
|
-
move:
|
|
575
|
-
remove:
|
|
576
|
-
submit:
|
|
577
|
-
reset:
|
|
582
|
+
move: I,
|
|
583
|
+
remove: Q,
|
|
584
|
+
submit: p,
|
|
585
|
+
reset: d
|
|
578
586
|
};
|
|
579
587
|
}
|
|
580
588
|
function rt(t) {
|
|
@@ -582,15 +590,15 @@ function rt(t) {
|
|
|
582
590
|
canAnswer: n,
|
|
583
591
|
submitted: u,
|
|
584
592
|
isCorrect: f,
|
|
585
|
-
attempts:
|
|
586
|
-
resetQuestion:
|
|
587
|
-
submitQuestion:
|
|
593
|
+
attempts: m,
|
|
594
|
+
resetQuestion: C,
|
|
595
|
+
submitQuestion: S
|
|
588
596
|
} = E();
|
|
589
597
|
function o() {
|
|
590
|
-
u ||
|
|
598
|
+
u || S(!0);
|
|
591
599
|
}
|
|
592
|
-
function
|
|
593
|
-
|
|
600
|
+
function l() {
|
|
601
|
+
C();
|
|
594
602
|
}
|
|
595
603
|
return {
|
|
596
604
|
// data
|
|
@@ -599,25 +607,25 @@ function rt(t) {
|
|
|
599
607
|
type: t.options.urlType,
|
|
600
608
|
// actions
|
|
601
609
|
submit: o,
|
|
602
|
-
reset:
|
|
610
|
+
reset: l,
|
|
603
611
|
// base
|
|
604
612
|
submitted: u,
|
|
605
613
|
isCorrect: f,
|
|
606
|
-
attempts:
|
|
614
|
+
attempts: m,
|
|
607
615
|
canAnswer: n
|
|
608
616
|
};
|
|
609
617
|
}
|
|
610
618
|
function nt(t, n) {
|
|
611
|
-
const { canAnswer: u, submitted: f, attempts:
|
|
619
|
+
const { canAnswer: u, submitted: f, attempts: m, submitQuestion: C, resetQuestion: S } = E(), [o, l] = A(""), [b, I] = A(void 0), [Q, w] = A(!1), [p, d] = A(void 0), x = B(
|
|
612
620
|
async (e) => {
|
|
613
621
|
if (n) {
|
|
614
|
-
w(!0),
|
|
622
|
+
w(!0), d(void 0);
|
|
615
623
|
try {
|
|
616
|
-
const
|
|
617
|
-
|
|
618
|
-
} catch (
|
|
619
|
-
console.error("File upload failed:",
|
|
620
|
-
|
|
624
|
+
const r = await n(e, e.name);
|
|
625
|
+
r.success && r.url ? I(r.url) : d(r.error || "Upload failed");
|
|
626
|
+
} catch (r) {
|
|
627
|
+
console.error("File upload failed:", r), d(
|
|
628
|
+
r instanceof Error ? r.message : "File upload failed"
|
|
621
629
|
);
|
|
622
630
|
} finally {
|
|
623
631
|
w(!1);
|
|
@@ -625,140 +633,140 @@ function nt(t, n) {
|
|
|
625
633
|
}
|
|
626
634
|
},
|
|
627
635
|
[n]
|
|
628
|
-
),
|
|
636
|
+
), h = B(async () => {
|
|
629
637
|
if (!(!n || !o)) {
|
|
630
|
-
w(!0),
|
|
638
|
+
w(!0), d(void 0);
|
|
631
639
|
try {
|
|
632
|
-
const e = new Blob([o], { type: "text/plain; charset=utf-8" }),
|
|
633
|
-
|
|
640
|
+
const e = new Blob([o], { type: "text/plain; charset=utf-8" }), r = `writing-${Date.now()}.txt`, c = await n(e, r);
|
|
641
|
+
c.success && c.url ? I(c.url) : d(c.error || "Upload failed");
|
|
634
642
|
} catch (e) {
|
|
635
|
-
console.error("Text upload failed:", e),
|
|
643
|
+
console.error("Text upload failed:", e), d(
|
|
636
644
|
e instanceof Error ? e.message : "Text upload failed"
|
|
637
645
|
);
|
|
638
646
|
} finally {
|
|
639
647
|
w(!1);
|
|
640
648
|
}
|
|
641
649
|
}
|
|
642
|
-
}, [o, n]),
|
|
650
|
+
}, [o, n]), s = F(
|
|
643
651
|
() => ({
|
|
644
652
|
type: "writing",
|
|
645
653
|
text: o,
|
|
646
|
-
fileUrl:
|
|
654
|
+
fileUrl: b
|
|
647
655
|
}),
|
|
648
|
-
[o,
|
|
649
|
-
),
|
|
650
|
-
|
|
651
|
-
}, [
|
|
656
|
+
[o, b]
|
|
657
|
+
), a = B(() => (C(), s), [C, s]), i = B(() => {
|
|
658
|
+
l(""), I(void 0), d(void 0), S();
|
|
659
|
+
}, [S]);
|
|
652
660
|
return {
|
|
653
661
|
question: t,
|
|
654
662
|
canAnswer: u,
|
|
655
663
|
submitted: f,
|
|
656
|
-
attempts:
|
|
664
|
+
attempts: m,
|
|
657
665
|
text: o,
|
|
658
|
-
setText:
|
|
659
|
-
fileUrl:
|
|
666
|
+
setText: l,
|
|
667
|
+
fileUrl: b,
|
|
660
668
|
setFileUrl: I,
|
|
661
669
|
isUploading: Q,
|
|
662
|
-
uploadError:
|
|
670
|
+
uploadError: p,
|
|
663
671
|
uploadFile: x,
|
|
664
|
-
uploadText:
|
|
665
|
-
submit:
|
|
666
|
-
reset:
|
|
667
|
-
payload:
|
|
672
|
+
uploadText: h,
|
|
673
|
+
submit: a,
|
|
674
|
+
reset: i,
|
|
675
|
+
payload: s
|
|
668
676
|
};
|
|
669
677
|
}
|
|
670
678
|
function st(t, n) {
|
|
671
|
-
const { canAnswer: u, submitted: f, attempts:
|
|
672
|
-
|
|
679
|
+
const { canAnswer: u, submitted: f, attempts: m, submitQuestion: C, resetQuestion: S } = E(), [o, l] = A(void 0), [b, I] = A("idle"), [Q, w] = A(0), [p, d] = A(!1), [x, h] = A(void 0), [s, a] = A(!1), i = O(null), e = O([]), r = O(null), c = O(null), g = B(async () => {
|
|
680
|
+
a(!0);
|
|
673
681
|
try {
|
|
674
|
-
const
|
|
675
|
-
|
|
676
|
-
const
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
},
|
|
680
|
-
const
|
|
682
|
+
const y = await navigator.mediaDevices.getUserMedia({ audio: !0 });
|
|
683
|
+
c.current = y;
|
|
684
|
+
const R = new MediaRecorder(y);
|
|
685
|
+
i.current = R, e.current = [], R.ondataavailable = (W) => {
|
|
686
|
+
W.data.size > 0 && e.current.push(W.data);
|
|
687
|
+
}, R.onstop = () => {
|
|
688
|
+
const W = new Blob(e.current, {
|
|
681
689
|
type: "audio/webm"
|
|
682
|
-
}), P = URL.createObjectURL(
|
|
683
|
-
|
|
684
|
-
},
|
|
690
|
+
}), P = URL.createObjectURL(W);
|
|
691
|
+
l(P);
|
|
692
|
+
}, R.start(), I("recording"), w(0);
|
|
685
693
|
let L = 0;
|
|
686
|
-
|
|
687
|
-
L++, w(L), L >= (t.metadata?.max_recording_time || 300) &&
|
|
694
|
+
r.current = setInterval(() => {
|
|
695
|
+
L++, w(L), L >= (t.metadata?.max_recording_time || 300) && k();
|
|
688
696
|
}, 1e3);
|
|
689
|
-
} catch (
|
|
690
|
-
console.error("Failed to start recording:",
|
|
697
|
+
} catch (y) {
|
|
698
|
+
console.error("Failed to start recording:", y), h("Failed to access microphone");
|
|
691
699
|
}
|
|
692
|
-
}, []),
|
|
693
|
-
|
|
694
|
-
}, [
|
|
695
|
-
|
|
696
|
-
w((
|
|
700
|
+
}, []), v = B(() => {
|
|
701
|
+
i.current && b === "recording" && (i.current.pause(), I("paused"), r.current && clearInterval(r.current));
|
|
702
|
+
}, [b]), U = B(() => {
|
|
703
|
+
i.current && b === "paused" && (i.current.resume(), I("recording"), r.current = setInterval(() => {
|
|
704
|
+
w((y) => y + 1);
|
|
697
705
|
}, 1e3));
|
|
698
|
-
}, [
|
|
699
|
-
|
|
700
|
-
}, []),
|
|
701
|
-
|
|
702
|
-
}, [
|
|
706
|
+
}, [b]), k = B(() => {
|
|
707
|
+
i.current && i.current.state !== "inactive" && (i.current.stop(), a(!1), I("stopped"), r.current && clearInterval(r.current), c.current && c.current.getTracks().forEach((y) => y.stop()));
|
|
708
|
+
}, []), _ = B(() => {
|
|
709
|
+
s ? k() : g();
|
|
710
|
+
}, [s, g, k]), T = B(async () => {
|
|
703
711
|
if (!(!e.current.length || !n)) {
|
|
704
|
-
|
|
712
|
+
d(!0), h(void 0);
|
|
705
713
|
try {
|
|
706
|
-
const
|
|
714
|
+
const y = new Blob(e.current, {
|
|
707
715
|
type: "audio/webm"
|
|
708
|
-
}),
|
|
709
|
-
L.success && L.url ?
|
|
710
|
-
} catch (
|
|
711
|
-
console.error("Upload failed:",
|
|
716
|
+
}), R = `speaking-${Date.now()}.webm`, L = await n(y, R);
|
|
717
|
+
L.success && L.url ? l(L.url) : h(L.error || "Upload failed");
|
|
718
|
+
} catch (y) {
|
|
719
|
+
console.error("Upload failed:", y), h(y instanceof Error ? y.message : "Upload failed");
|
|
712
720
|
} finally {
|
|
713
|
-
|
|
721
|
+
d(!1);
|
|
714
722
|
}
|
|
715
723
|
}
|
|
716
|
-
}, [t, n]),
|
|
717
|
-
async (
|
|
724
|
+
}, [t, n]), M = B(
|
|
725
|
+
async (y) => {
|
|
718
726
|
if (n) {
|
|
719
|
-
|
|
727
|
+
d(!0), h(void 0);
|
|
720
728
|
try {
|
|
721
|
-
const
|
|
722
|
-
|
|
723
|
-
} catch (
|
|
724
|
-
console.error("File upload failed:",
|
|
725
|
-
|
|
729
|
+
const R = await n(y, y.name);
|
|
730
|
+
R.success && R.url ? l(R.url) : h(R.error || "Upload failed");
|
|
731
|
+
} catch (R) {
|
|
732
|
+
console.error("File upload failed:", R), h(
|
|
733
|
+
R instanceof Error ? R.message : "File upload failed"
|
|
726
734
|
);
|
|
727
735
|
} finally {
|
|
728
|
-
|
|
736
|
+
d(!1);
|
|
729
737
|
}
|
|
730
738
|
}
|
|
731
739
|
},
|
|
732
740
|
[n]
|
|
733
|
-
), j =
|
|
741
|
+
), j = F(
|
|
734
742
|
() => ({
|
|
735
743
|
type: "speaking",
|
|
736
744
|
audioUrl: o
|
|
737
745
|
}),
|
|
738
746
|
[t, o]
|
|
739
|
-
), $ =
|
|
740
|
-
|
|
741
|
-
}, [
|
|
747
|
+
), $ = B(() => (C(), j), [C, j]), N = B(() => {
|
|
748
|
+
l(void 0), I("idle"), w(0), h(void 0), e.current = [], r.current && clearInterval(r.current), c.current && c.current.getTracks().forEach((y) => y.stop()), S();
|
|
749
|
+
}, [S]);
|
|
742
750
|
return {
|
|
743
751
|
question: t,
|
|
744
752
|
canAnswer: u,
|
|
745
753
|
submitted: f,
|
|
746
|
-
attempts:
|
|
754
|
+
attempts: m,
|
|
747
755
|
audioUrl: o,
|
|
748
|
-
recordingState:
|
|
756
|
+
recordingState: b,
|
|
749
757
|
recordingTime: Q,
|
|
750
|
-
isUploading:
|
|
758
|
+
isUploading: p,
|
|
751
759
|
uploadError: x,
|
|
752
|
-
isRecording:
|
|
760
|
+
isRecording: s,
|
|
753
761
|
payload: j,
|
|
754
|
-
setAudioUrl:
|
|
755
|
-
startRecording:
|
|
756
|
-
pauseRecording:
|
|
757
|
-
resumeRecording:
|
|
758
|
-
stopRecording:
|
|
759
|
-
toggleRecording:
|
|
760
|
-
uploadAudio:
|
|
761
|
-
uploadFile:
|
|
762
|
+
setAudioUrl: l,
|
|
763
|
+
startRecording: g,
|
|
764
|
+
pauseRecording: v,
|
|
765
|
+
resumeRecording: U,
|
|
766
|
+
stopRecording: k,
|
|
767
|
+
toggleRecording: _,
|
|
768
|
+
uploadAudio: T,
|
|
769
|
+
uploadFile: M,
|
|
762
770
|
submit: $,
|
|
763
771
|
reset: N
|
|
764
772
|
};
|
|
@@ -791,14 +799,14 @@ function lt({
|
|
|
791
799
|
const u = K(t());
|
|
792
800
|
return n(u);
|
|
793
801
|
}
|
|
794
|
-
function
|
|
802
|
+
function ft({
|
|
795
803
|
getData: t,
|
|
796
804
|
children: n
|
|
797
805
|
}) {
|
|
798
806
|
const u = H(t());
|
|
799
807
|
return n(u);
|
|
800
808
|
}
|
|
801
|
-
function
|
|
809
|
+
function dt({
|
|
802
810
|
getData: t,
|
|
803
811
|
children: n
|
|
804
812
|
}) {
|
|
@@ -831,31 +839,31 @@ function bt({
|
|
|
831
839
|
children: n,
|
|
832
840
|
uploadHandler: u
|
|
833
841
|
}) {
|
|
834
|
-
const f = t(),
|
|
835
|
-
return /* @__PURE__ */
|
|
842
|
+
const f = t(), m = nt(f, u);
|
|
843
|
+
return /* @__PURE__ */ z(G, { children: n(m) });
|
|
836
844
|
}
|
|
837
845
|
function wt({
|
|
838
846
|
getData: t,
|
|
839
847
|
children: n,
|
|
840
848
|
uploadHandler: u
|
|
841
849
|
}) {
|
|
842
|
-
const f = t(),
|
|
843
|
-
return /* @__PURE__ */
|
|
850
|
+
const f = t(), m = st(f, u);
|
|
851
|
+
return /* @__PURE__ */ z(G, { children: n(m) });
|
|
844
852
|
}
|
|
845
853
|
export {
|
|
846
854
|
lt as DragDropQuestion,
|
|
847
855
|
pt as FillInBlankQuestion,
|
|
848
856
|
mt as GroupingQuestion,
|
|
849
|
-
|
|
857
|
+
dt as LabelingQuestion,
|
|
850
858
|
ut as MatchingQuestion,
|
|
851
859
|
ct as MultipleChoicesQuestion,
|
|
852
|
-
|
|
860
|
+
ft as OrderingQuestion,
|
|
853
861
|
gt as PowerpointQuestion,
|
|
854
862
|
wt as SpeakingQuestion,
|
|
855
863
|
at as VideoQuestion,
|
|
856
864
|
bt as WritingQuestion,
|
|
857
865
|
J as isSameSet,
|
|
858
|
-
|
|
866
|
+
V as shuffleArray,
|
|
859
867
|
E as useBaseQuestion,
|
|
860
868
|
K as useDragDrop,
|
|
861
869
|
tt as useFillInBlank,
|