@intellectif/lk-react 9.0.0 → 10.0.0
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/CHANGELOG.md +25 -0
- package/README.md +2 -1
- package/dist/{WrittenResponse-Du5CZnwn.d.ts → WrittenResponse-BgcpEM-e.d.ts} +1 -1
- package/dist/{WrittenResponse-BJr9gBpY.d.cts → WrittenResponse-ByzXYEoW.d.cts} +1 -1
- package/dist/{chunk-7OHPBLPH.js → chunk-2Y6V5E7H.js} +3 -3
- package/dist/{chunk-7OHPBLPH.js.map → chunk-2Y6V5E7H.js.map} +1 -1
- package/dist/{chunk-HEJPEJW7.js → chunk-5IH3NRXE.js} +4 -4
- package/dist/{chunk-HEJPEJW7.js.map → chunk-5IH3NRXE.js.map} +1 -1
- package/dist/{chunk-7H4C6XOA.js → chunk-5S2YDMEJ.js} +18 -7
- package/dist/chunk-5S2YDMEJ.js.map +1 -0
- package/dist/{chunk-4AHZBTBF.cjs → chunk-64AJVB6O.cjs} +13 -13
- package/dist/{chunk-4AHZBTBF.cjs.map → chunk-64AJVB6O.cjs.map} +1 -1
- package/dist/{chunk-YND3O2ES.cjs → chunk-6KMEB7TF.cjs} +23 -12
- package/dist/chunk-6KMEB7TF.cjs.map +1 -0
- package/dist/{chunk-7C66CLJZ.js → chunk-AP6NX3XF.js} +21 -9
- package/dist/chunk-AP6NX3XF.js.map +1 -0
- package/dist/{chunk-T4CKODCJ.js → chunk-CK7Z275S.js} +4 -2
- package/dist/chunk-CK7Z275S.js.map +1 -0
- package/dist/{chunk-4XPKKNJQ.cjs → chunk-EWTAMY6L.cjs} +5 -5
- package/dist/{chunk-4XPKKNJQ.cjs.map → chunk-EWTAMY6L.cjs.map} +1 -1
- package/dist/{chunk-2VLKSNYJ.cjs → chunk-FX7VMZHQ.cjs} +5 -5
- package/dist/{chunk-2VLKSNYJ.cjs.map → chunk-FX7VMZHQ.cjs.map} +1 -1
- package/dist/{chunk-LQGY6XGH.cjs → chunk-G6PUWKQC.cjs} +14 -14
- package/dist/{chunk-LQGY6XGH.cjs.map → chunk-G6PUWKQC.cjs.map} +1 -1
- package/dist/{chunk-BLQBFI7Z.js → chunk-GWD75Q25.js} +5 -5
- package/dist/{chunk-BLQBFI7Z.js.map → chunk-GWD75Q25.js.map} +1 -1
- package/dist/{chunk-7VIXWVFN.cjs → chunk-KSXEBV2H.cjs} +6 -6
- package/dist/{chunk-7VIXWVFN.cjs.map → chunk-KSXEBV2H.cjs.map} +1 -1
- package/dist/{chunk-AHEV52U7.cjs → chunk-KYOCDRUO.cjs} +4 -2
- package/dist/chunk-KYOCDRUO.cjs.map +1 -0
- package/dist/{chunk-VVZ7SAE7.cjs → chunk-LIHKQEIP.cjs} +14 -14
- package/dist/{chunk-VVZ7SAE7.cjs.map → chunk-LIHKQEIP.cjs.map} +1 -1
- package/dist/{chunk-ZC2EJL6E.cjs → chunk-MYGFVEYU.cjs} +27 -15
- package/dist/chunk-MYGFVEYU.cjs.map +1 -0
- package/dist/chunk-NK5EVL5C.cjs +320 -0
- package/dist/chunk-NK5EVL5C.cjs.map +1 -0
- package/dist/{chunk-FBLHXAN5.js → chunk-QXYAOILF.js} +5 -5
- package/dist/{chunk-FBLHXAN5.js.map → chunk-QXYAOILF.js.map} +1 -1
- package/dist/{chunk-EQ5BZTLV.js → chunk-XKGBD3UK.js} +5 -5
- package/dist/{chunk-EQ5BZTLV.js.map → chunk-XKGBD3UK.js.map} +1 -1
- package/dist/chunk-ZFSRMGWO.js +318 -0
- package/dist/chunk-ZFSRMGWO.js.map +1 -0
- package/dist/{chunk-ESWHIC4Z.js → chunk-ZFWC4KZC.js} +3 -3
- package/dist/{chunk-ESWHIC4Z.js.map → chunk-ZFWC4KZC.js.map} +1 -1
- package/dist/components/ActivityPreview.cjs +9 -8
- package/dist/components/ActivityPreview.d.cts +2 -2
- package/dist/components/ActivityPreview.d.ts +2 -2
- package/dist/components/ActivityPreview.js +8 -7
- package/dist/components/ActivitySequence.cjs +10 -9
- package/dist/components/ActivitySequence.d.cts +2 -2
- package/dist/components/ActivitySequence.d.ts +2 -2
- package/dist/components/ActivitySequence.js +9 -8
- package/dist/components/FillInTheBlanks.cjs +5 -5
- package/dist/components/FillInTheBlanks.d.cts +1 -1
- package/dist/components/FillInTheBlanks.d.ts +1 -1
- package/dist/components/FillInTheBlanks.js +4 -4
- package/dist/components/GapSelect.cjs +17 -0
- package/dist/components/GapSelect.cjs.map +1 -0
- package/dist/components/GapSelect.d.cts +24 -0
- package/dist/components/GapSelect.d.ts +24 -0
- package/dist/components/GapSelect.js +8 -0
- package/dist/components/GapSelect.js.map +1 -0
- package/dist/components/MultipleChoice.cjs +5 -5
- package/dist/components/MultipleChoice.d.cts +1 -1
- package/dist/components/MultipleChoice.d.ts +1 -1
- package/dist/components/MultipleChoice.js +4 -4
- package/dist/components/StimulusPanel.cjs +4 -4
- package/dist/components/StimulusPanel.d.cts +1 -1
- package/dist/components/StimulusPanel.d.ts +1 -1
- package/dist/components/StimulusPanel.js +3 -3
- package/dist/components/WrittenResponse.cjs +5 -5
- package/dist/components/WrittenResponse.d.cts +3 -3
- package/dist/components/WrittenResponse.d.ts +3 -3
- package/dist/components/WrittenResponse.js +4 -4
- package/dist/i18n/LkIntlProvider.cjs +7 -7
- package/dist/i18n/LkIntlProvider.d.cts +2 -2
- package/dist/i18n/LkIntlProvider.d.ts +2 -2
- package/dist/i18n/LkIntlProvider.js +1 -1
- package/dist/index.cjs +30 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/{strings-vQDqESTS.d.cts → strings-CN7n-BlE.d.cts} +7 -0
- package/dist/{strings-vQDqESTS.d.ts → strings-CN7n-BlE.d.ts} +7 -0
- package/dist/theme/skin.css +58 -0
- package/package.json +13 -3
- package/dist/chunk-7C66CLJZ.js.map +0 -1
- package/dist/chunk-7H4C6XOA.js.map +0 -1
- package/dist/chunk-AHEV52U7.cjs.map +0 -1
- package/dist/chunk-T4CKODCJ.js.map +0 -1
- package/dist/chunk-YND3O2ES.cjs.map +0 -1
- package/dist/chunk-ZC2EJL6E.cjs.map +0 -1
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { ActivityErrorBoundary, isDevelopment, randomSessionId, FeedbackRegion, ANONYMOUS_ACTOR, objectIdFor } from './chunk-ZFWC4KZC.js';
|
|
3
|
+
import { useActivityState } from './chunk-6N43WDVG.js';
|
|
4
|
+
import { ActivityMedia } from './chunk-2Y6V5E7H.js';
|
|
5
|
+
import { useLkStrings } from './chunk-CK7Z275S.js';
|
|
6
|
+
import { assertRedacted, validateActivity, ActivitySchemaError, seededShuffle, score, xAPIBuilder, xapiDefinitionFor } from '@intellectif/lk-core';
|
|
7
|
+
import { useMemo, useState, useRef, useEffect } from 'react';
|
|
8
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
var PLACEHOLDER = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
11
|
+
function parsePassage(passage) {
|
|
12
|
+
const segments = [];
|
|
13
|
+
const re = new RegExp(PLACEHOLDER);
|
|
14
|
+
let last = 0;
|
|
15
|
+
let ordinal = 0;
|
|
16
|
+
let match = re.exec(passage);
|
|
17
|
+
while (match !== null) {
|
|
18
|
+
if (match.index > last) {
|
|
19
|
+
segments.push({ kind: "text", value: passage.slice(last, match.index) });
|
|
20
|
+
}
|
|
21
|
+
ordinal += 1;
|
|
22
|
+
segments.push({ kind: "gap", id: match[1], ordinal });
|
|
23
|
+
last = match.index + match[0].length;
|
|
24
|
+
match = re.exec(passage);
|
|
25
|
+
}
|
|
26
|
+
if (last < passage.length) {
|
|
27
|
+
segments.push({ kind: "text", value: passage.slice(last) });
|
|
28
|
+
}
|
|
29
|
+
return segments;
|
|
30
|
+
}
|
|
31
|
+
var NO_SELECTIONS = {};
|
|
32
|
+
function selectionsOf(response) {
|
|
33
|
+
return response !== void 0 && response.type === "gap-select" ? response.selections : NO_SELECTIONS;
|
|
34
|
+
}
|
|
35
|
+
function correctnessByItem(details) {
|
|
36
|
+
const map = /* @__PURE__ */ new Map();
|
|
37
|
+
for (const detail of details) {
|
|
38
|
+
map.set(
|
|
39
|
+
detail.itemId,
|
|
40
|
+
detail.outcome !== void 0 ? detail.outcome === "correct" : detail.correct
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return map;
|
|
44
|
+
}
|
|
45
|
+
function choicesFor(banks, gap) {
|
|
46
|
+
if (gap.choices !== void 0) {
|
|
47
|
+
return gap.choices;
|
|
48
|
+
}
|
|
49
|
+
return banks?.find((bank) => bank.id === gap.bankId)?.choices ?? [];
|
|
50
|
+
}
|
|
51
|
+
function GapSelect({
|
|
52
|
+
data,
|
|
53
|
+
onComplete,
|
|
54
|
+
onSubmit,
|
|
55
|
+
onChange,
|
|
56
|
+
onInteraction,
|
|
57
|
+
value,
|
|
58
|
+
defaultValue,
|
|
59
|
+
defaultSubmitted,
|
|
60
|
+
renderMode = "practice",
|
|
61
|
+
outcome,
|
|
62
|
+
mediaBudget,
|
|
63
|
+
mediaStrings,
|
|
64
|
+
strings,
|
|
65
|
+
theme,
|
|
66
|
+
locale,
|
|
67
|
+
disabled,
|
|
68
|
+
shuffleSeed
|
|
69
|
+
}) {
|
|
70
|
+
const isExam = renderMode === "exam";
|
|
71
|
+
const isReview = renderMode === "review";
|
|
72
|
+
const s = useLkStrings(strings);
|
|
73
|
+
const devError = useMemo(() => {
|
|
74
|
+
if (!isDevelopment()) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
if (data.redacted === true) {
|
|
78
|
+
try {
|
|
79
|
+
assertRedacted(data);
|
|
80
|
+
return null;
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const result2 = validateActivity("gap-select", data);
|
|
86
|
+
return result2.success ? null : new ActivitySchemaError("gap-select", result2.errors);
|
|
87
|
+
}, [data]);
|
|
88
|
+
const { state, start, complete, getTimeSpent, reset } = useActivityState(
|
|
89
|
+
defaultSubmitted === true ? "completed" : "idle"
|
|
90
|
+
);
|
|
91
|
+
const isControlled = value !== void 0;
|
|
92
|
+
const [internalSelections, setInternalSelections] = useState(
|
|
93
|
+
() => selectionsOf(defaultValue)
|
|
94
|
+
);
|
|
95
|
+
const [result, setResult] = useState(null);
|
|
96
|
+
const [summary, setSummary] = useState(null);
|
|
97
|
+
const [feedbackHidden, setFeedbackHidden] = useState(false);
|
|
98
|
+
const selections = isControlled ? selectionsOf(value) : internalSelections;
|
|
99
|
+
const defaultValueRef = useRef(defaultValue);
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
defaultValueRef.current = defaultValue;
|
|
102
|
+
}, [defaultValue]);
|
|
103
|
+
const defaultSubmittedRef = useRef(defaultSubmitted);
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
defaultSubmittedRef.current = defaultSubmitted;
|
|
106
|
+
}, [defaultSubmitted]);
|
|
107
|
+
const lastDataRef = useRef(data);
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
if (lastDataRef.current === data) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
lastDataRef.current = data;
|
|
113
|
+
setInternalSelections(selectionsOf(defaultValueRef.current));
|
|
114
|
+
setResult(null);
|
|
115
|
+
setSummary(null);
|
|
116
|
+
setFeedbackHidden(false);
|
|
117
|
+
reset(defaultSubmittedRef.current === true ? "completed" : "idle");
|
|
118
|
+
}, [data, reset]);
|
|
119
|
+
const segments = useMemo(() => parsePassage(data.passage), [data.passage]);
|
|
120
|
+
const gapById = useMemo(() => new Map(data.gaps.map((gap) => [gap.id, gap])), [data.gaps]);
|
|
121
|
+
const sessionIdRef = useRef(null);
|
|
122
|
+
const choicesByGap = useMemo(() => {
|
|
123
|
+
const map = /* @__PURE__ */ new Map();
|
|
124
|
+
const seedSource = shuffleSeed ?? (sessionIdRef.current ??= randomSessionId());
|
|
125
|
+
for (const gap of data.gaps) {
|
|
126
|
+
const choices = choicesFor(data.banks, gap);
|
|
127
|
+
map.set(
|
|
128
|
+
gap.id,
|
|
129
|
+
data.shuffleChoices === true ? seededShuffle(choices, `${seedSource}:${data.id}:${gap.id}`) : choices
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
return map;
|
|
133
|
+
}, [data, shuffleSeed]);
|
|
134
|
+
if (devError) {
|
|
135
|
+
throw devError;
|
|
136
|
+
}
|
|
137
|
+
if (data.redacted === true && renderMode === "practice") {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`Gap Select "${data.id}" received redacted activity data in renderMode "practice", which grades locally and has no answer key to grade against. Render redacted data with renderMode="exam" (server grades) or "review" (pass \`outcome\`).`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
const submitted = state === "completed";
|
|
143
|
+
const inactive = disabled === true || submitted || isReview;
|
|
144
|
+
const revealing = isReview ? outcome?.status === "scored" : !isExam && submitted;
|
|
145
|
+
const fireInteraction = (type, payload) => {
|
|
146
|
+
onInteraction?.({ type, activityId: data.id, timestamp: Date.now(), payload });
|
|
147
|
+
};
|
|
148
|
+
const handleSelect = (gapId, choiceId) => {
|
|
149
|
+
if (inactive) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (state === "idle") {
|
|
153
|
+
start();
|
|
154
|
+
}
|
|
155
|
+
const next = { ...selections, [gapId]: choiceId };
|
|
156
|
+
if (!isControlled) {
|
|
157
|
+
setInternalSelections(next);
|
|
158
|
+
}
|
|
159
|
+
onChange?.({ type: "gap-select", selections: next });
|
|
160
|
+
fireInteraction("gap-selected", { gapId, choiceId });
|
|
161
|
+
};
|
|
162
|
+
const handleSubmit = (event) => {
|
|
163
|
+
event.preventDefault();
|
|
164
|
+
if (inactive) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const response = { type: "gap-select", selections };
|
|
168
|
+
onSubmit?.(response);
|
|
169
|
+
if (isExam) {
|
|
170
|
+
complete();
|
|
171
|
+
setSummary(s.answerSubmitted);
|
|
172
|
+
fireInteraction("submitted", { selections });
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const scoringResult = score("gap-select", data, response);
|
|
176
|
+
complete();
|
|
177
|
+
const timeSpent = getTimeSpent();
|
|
178
|
+
const xapiStatement = xAPIBuilder.buildAnsweredStatement({
|
|
179
|
+
actor: ANONYMOUS_ACTOR,
|
|
180
|
+
object: {
|
|
181
|
+
id: objectIdFor(data.id),
|
|
182
|
+
name: { [data.locale ?? "en-US"]: data.title },
|
|
183
|
+
...xapiDefinitionFor(data)
|
|
184
|
+
},
|
|
185
|
+
scoringResult,
|
|
186
|
+
timeSpentMs: timeSpent,
|
|
187
|
+
response: JSON.stringify(selections)
|
|
188
|
+
});
|
|
189
|
+
setResult(scoringResult);
|
|
190
|
+
onComplete?.({
|
|
191
|
+
score: scoringResult.score,
|
|
192
|
+
maxScore: scoringResult.maxScore,
|
|
193
|
+
passed: scoringResult.passed,
|
|
194
|
+
timeSpent,
|
|
195
|
+
xapiStatement
|
|
196
|
+
});
|
|
197
|
+
const overall = scoringResult.feedback;
|
|
198
|
+
setSummary(
|
|
199
|
+
`${s.answerSubmitted} ${s.scoreAnnouncement(
|
|
200
|
+
Math.round(scoringResult.score * 100),
|
|
201
|
+
scoringResult.passed
|
|
202
|
+
)}${overall ? ` ${overall}` : ""}`
|
|
203
|
+
);
|
|
204
|
+
fireInteraction("submitted", { selections, score: scoringResult.score });
|
|
205
|
+
};
|
|
206
|
+
const correctByGap = useMemo(() => {
|
|
207
|
+
if (isExam) {
|
|
208
|
+
return /* @__PURE__ */ new Map();
|
|
209
|
+
}
|
|
210
|
+
if (isReview) {
|
|
211
|
+
return outcome?.status === "scored" ? correctnessByItem(outcome.details) : /* @__PURE__ */ new Map();
|
|
212
|
+
}
|
|
213
|
+
return correctnessByItem(result?.details ?? []);
|
|
214
|
+
}, [isExam, isReview, outcome, result]);
|
|
215
|
+
const reviewSummary = useMemo(() => {
|
|
216
|
+
if (!isReview || outcome === void 0) {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
if (outcome.status === "scored") {
|
|
220
|
+
return `${s.scoreAnnouncement(Math.round(outcome.score * 100), outcome.passed)}${outcome.feedback ? ` ${outcome.feedback}` : ""}`;
|
|
221
|
+
}
|
|
222
|
+
if (outcome.status === "deferred") {
|
|
223
|
+
return s.notGradedYet;
|
|
224
|
+
}
|
|
225
|
+
if (outcome.status === "graded") {
|
|
226
|
+
const percent = outcome.maxScore > 0 ? Math.round(outcome.score / outcome.maxScore * 100) : Math.round(outcome.score * 100);
|
|
227
|
+
return `${s.scoreAnnouncement(percent, outcome.passed)}${outcome.feedback ? ` ${outcome.feedback}` : ""}`;
|
|
228
|
+
}
|
|
229
|
+
return s.noGradeAvailable;
|
|
230
|
+
}, [isReview, outcome, s]);
|
|
231
|
+
const anyFeedback = data.gaps.some((gap) => gap.feedback !== void 0);
|
|
232
|
+
return /* @__PURE__ */ jsxs(
|
|
233
|
+
"form",
|
|
234
|
+
{
|
|
235
|
+
className: "lk-gs",
|
|
236
|
+
"aria-label": data.title,
|
|
237
|
+
lang: locale,
|
|
238
|
+
"data-render-mode": renderMode,
|
|
239
|
+
style: theme,
|
|
240
|
+
onSubmit: handleSubmit,
|
|
241
|
+
children: [
|
|
242
|
+
data.media ? /* @__PURE__ */ jsx(
|
|
243
|
+
ActivityMedia,
|
|
244
|
+
{
|
|
245
|
+
media: data.media,
|
|
246
|
+
renderMode,
|
|
247
|
+
...mediaBudget !== void 0 ? { mediaBudget } : {},
|
|
248
|
+
...mediaStrings !== void 0 ? { mediaStrings } : {},
|
|
249
|
+
...strings !== void 0 ? { strings } : {},
|
|
250
|
+
...onInteraction !== void 0 ? { onInteraction } : {},
|
|
251
|
+
...locale !== void 0 ? { locale } : {}
|
|
252
|
+
}
|
|
253
|
+
) : null,
|
|
254
|
+
/* @__PURE__ */ jsxs("fieldset", { disabled: inactive, children: [
|
|
255
|
+
/* @__PURE__ */ jsx("p", { className: "lk-gs-passage", children: segments.map((seg, i) => {
|
|
256
|
+
if (seg.kind === "text") {
|
|
257
|
+
return /* @__PURE__ */ jsx("span", { children: seg.value }, `t${i}`);
|
|
258
|
+
}
|
|
259
|
+
const gap = gapById.get(seg.id);
|
|
260
|
+
if (!gap) {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
const choices = choicesByGap.get(seg.id) ?? [];
|
|
264
|
+
const correctness = correctByGap.get(seg.id);
|
|
265
|
+
const gapFeedback = isExam ? void 0 : gap.feedback;
|
|
266
|
+
return /* @__PURE__ */ jsxs("span", { className: "lk-gs-gap", children: [
|
|
267
|
+
/* @__PURE__ */ jsxs(
|
|
268
|
+
"select",
|
|
269
|
+
{
|
|
270
|
+
className: "lk-gs-select",
|
|
271
|
+
"aria-label": s.gapLabel(seg.ordinal),
|
|
272
|
+
value: selections[seg.id] ?? "",
|
|
273
|
+
disabled: inactive,
|
|
274
|
+
"aria-disabled": inactive || void 0,
|
|
275
|
+
"data-correct": revealing && correctness !== void 0 ? String(correctness) : void 0,
|
|
276
|
+
onChange: (e) => handleSelect(seg.id, e.target.value),
|
|
277
|
+
children: [
|
|
278
|
+
/* @__PURE__ */ jsx("option", { value: "", children: s.gapPlaceholder }),
|
|
279
|
+
choices.map((choice) => /* @__PURE__ */ jsx("option", { value: choice.id, children: choice.text }, choice.id))
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
),
|
|
283
|
+
revealing && !feedbackHidden && gapFeedback ? /* @__PURE__ */ jsx(
|
|
284
|
+
"span",
|
|
285
|
+
{
|
|
286
|
+
className: "lk-gs-gap-feedback",
|
|
287
|
+
role: "note",
|
|
288
|
+
"data-correct": correctness !== void 0 ? String(correctness) : void 0,
|
|
289
|
+
children: gapFeedback
|
|
290
|
+
}
|
|
291
|
+
) : null
|
|
292
|
+
] }, seg.id);
|
|
293
|
+
}) }),
|
|
294
|
+
isReview ? null : /* @__PURE__ */ jsx("button", { type: "submit", disabled: inactive, children: isExam ? s.submitAnswers : s.checkAnswers })
|
|
295
|
+
] }),
|
|
296
|
+
revealing && anyFeedback ? /* @__PURE__ */ jsx(
|
|
297
|
+
"button",
|
|
298
|
+
{
|
|
299
|
+
type: "button",
|
|
300
|
+
className: "lk-gs-feedback-toggle",
|
|
301
|
+
"aria-expanded": !feedbackHidden,
|
|
302
|
+
onClick: () => setFeedbackHidden((h) => !h),
|
|
303
|
+
children: feedbackHidden ? s.showFeedback : s.hideFeedback
|
|
304
|
+
}
|
|
305
|
+
) : null,
|
|
306
|
+
/* @__PURE__ */ jsx(FeedbackRegion, { id: `${data.id}-feedback`, children: isReview ? reviewSummary : summary })
|
|
307
|
+
]
|
|
308
|
+
}
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
function GapSelect2(props) {
|
|
312
|
+
const strings = useLkStrings(props.strings);
|
|
313
|
+
return /* @__PURE__ */ jsx(ActivityErrorBoundary, { activityTitle: props.data?.title, strings, children: /* @__PURE__ */ jsx(GapSelect, { ...props }) });
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export { GapSelect2 as GapSelect };
|
|
317
|
+
//# sourceMappingURL=chunk-ZFSRMGWO.js.map
|
|
318
|
+
//# sourceMappingURL=chunk-ZFSRMGWO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/GapSelect/GapSelect.tsx","../src/components/GapSelect/index.tsx"],"names":["result","GapSelect","jsx"],"mappings":"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","file":"chunk-ZFSRMGWO.js","sourcesContent":["'use client';\n\nimport {\n ActivitySchemaError,\n assertRedacted,\n type GapSelectBank,\n type GapSelectChoice,\n type GapSelectData,\n type GapSelectGap,\n type GapSelectLearnerResponse,\n type LearnerResponse,\n type ScoringDetail,\n type ScoringResult,\n score,\n seededShuffle,\n validateActivity,\n xAPIBuilder,\n xapiDefinitionFor,\n} from '@intellectif/lk-core';\nimport { type CSSProperties, useEffect, useMemo, useRef, useState } from 'react';\nimport { useActivityState } from '../../hooks/useActivityState.js';\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ANONYMOUS_ACTOR, isDevelopment, objectIdFor, randomSessionId } from '../_internal.js';\nimport { ActivityMedia } from '../shared/ActivityMedia.js';\nimport { FeedbackRegion } from '../shared/FeedbackRegion.js';\nimport type { ActivityProps } from '../types.js';\n\nexport interface GapSelectProps extends ActivityProps<GapSelectData> {\n /**\n * Seeds the per-gap choice shuffle when `data.shuffleChoices` is set. Pass\n * the attempt id, exactly as on `<MultipleChoice>`: an order nobody can\n * reproduce cannot be reconciled with the attempt a server recorded. Without\n * one, a random per-mount seed is used — stable within the mount, and\n * deliberately not reproducible.\n */\n shuffleSeed?: string;\n}\n\nconst PLACEHOLDER = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n\ntype Segment = { kind: 'text'; value: string } | { kind: 'gap'; id: string; ordinal: number };\n\n/** Splits a passage into literal text and its `{{id}}` gaps, in order. */\nfunction parsePassage(passage: string): Segment[] {\n const segments: Segment[] = [];\n const re = new RegExp(PLACEHOLDER);\n let last = 0;\n let ordinal = 0;\n let match = re.exec(passage);\n while (match !== null) {\n if (match.index > last) {\n segments.push({ kind: 'text', value: passage.slice(last, match.index) });\n }\n ordinal += 1;\n segments.push({ kind: 'gap', id: match[1] as string, ordinal });\n last = match.index + match[0].length;\n match = re.exec(passage);\n }\n if (last < passage.length) {\n segments.push({ kind: 'text', value: passage.slice(last) });\n }\n return segments;\n}\n\nconst NO_SELECTIONS: Record<string, string> = {};\n\n/**\n * The selections out of a `LearnerResponse`. A response of another activity\n * type reads as \"nothing selected\" rather than throwing — a controlled host\n * that has not yet swapped its state on an activity change would otherwise\n * crash the attempt.\n */\nfunction selectionsOf(response: LearnerResponse | undefined): Record<string, string> {\n return response !== undefined && response.type === 'gap-select'\n ? response.selections\n : NO_SELECTIONS;\n}\n\n/** Per-gap correctness keyed by gap id, preferring the unambiguous `outcome`. */\nfunction correctnessByItem(details: readonly ScoringDetail[]): Map<string, boolean> {\n const map = new Map<string, boolean>();\n for (const detail of details) {\n map.set(\n detail.itemId,\n detail.outcome !== undefined ? detail.outcome === 'correct' : detail.correct,\n );\n }\n return map;\n}\n\n/**\n * The choices a gap offers: its own list, or the bank it names.\n *\n * Both survive redaction — they are what the learner picks from — so this is\n * the one resolution that works identically on full and redacted data.\n */\nfunction choicesFor(\n banks: readonly GapSelectBank[] | undefined,\n gap: GapSelectGap,\n): readonly GapSelectChoice[] {\n if (gap.choices !== undefined) {\n return gap.choices;\n }\n return banks?.find((bank) => bank.id === gap.bankId)?.choices ?? [];\n}\n\nexport function GapSelect({\n data,\n onComplete,\n onSubmit,\n onChange,\n onInteraction,\n value,\n defaultValue,\n defaultSubmitted,\n renderMode = 'practice',\n outcome,\n mediaBudget,\n mediaStrings,\n strings,\n theme,\n locale,\n disabled,\n shuffleSeed,\n}: GapSelectProps) {\n const isExam = renderMode === 'exam';\n const isReview = renderMode === 'review';\n const s = useLkStrings(strings);\n\n const devError = useMemo(() => {\n if (!isDevelopment()) {\n return null;\n }\n if (data.redacted === true) {\n try {\n assertRedacted(data);\n return null;\n } catch (error) {\n return error instanceof Error ? error : new Error(String(error));\n }\n }\n const result = validateActivity('gap-select', data);\n return result.success ? null : new ActivitySchemaError('gap-select', result.errors);\n }, [data]);\n\n const { state, start, complete, getTimeSpent, reset } = useActivityState(\n defaultSubmitted === true ? 'completed' : 'idle',\n );\n const isControlled = value !== undefined;\n const [internalSelections, setInternalSelections] = useState<Record<string, string>>(() =>\n selectionsOf(defaultValue),\n );\n const [result, setResult] = useState<ScoringResult | null>(null);\n const [summary, setSummary] = useState<string | null>(null);\n const [feedbackHidden, setFeedbackHidden] = useState(false);\n\n const selections = isControlled ? selectionsOf(value) : internalSelections;\n\n const defaultValueRef = useRef(defaultValue);\n useEffect(() => {\n defaultValueRef.current = defaultValue;\n }, [defaultValue]);\n\n const defaultSubmittedRef = useRef(defaultSubmitted);\n useEffect(() => {\n defaultSubmittedRef.current = defaultSubmitted;\n }, [defaultSubmitted]);\n\n // Identity-guarded so the mount run is a no-op: without it this fires after\n // the first paint and undoes every seed it was just given (Req 3.7).\n const lastDataRef = useRef(data);\n // biome-ignore lint/correctness/useExhaustiveDependencies: data is the reset trigger (Req 3.7)\n useEffect(() => {\n if (lastDataRef.current === data) {\n return;\n }\n lastDataRef.current = data;\n setInternalSelections(selectionsOf(defaultValueRef.current));\n setResult(null);\n setSummary(null);\n setFeedbackHidden(false);\n reset(defaultSubmittedRef.current === true ? 'completed' : 'idle');\n }, [data, reset]);\n\n const segments = useMemo(() => parsePassage(data.passage), [data.passage]);\n const gapById = useMemo(() => new Map(data.gaps.map((gap) => [gap.id, gap])), [data.gaps]);\n\n const sessionIdRef = useRef<string | null>(null);\n /**\n * The choices each gap shows, in the order it shows them.\n *\n * Seeded PER GAP, not once for the activity: two gaps drawing on the same\n * word bank must not be dealt the same order, or the bank's distractors line\n * up column-wise and the second gap becomes easier than the first.\n */\n const choicesByGap = useMemo(() => {\n const map = new Map<string, readonly GapSelectChoice[]>();\n // biome-ignore lint/suspicious/noAssignInExpressions: sanctioned lazy ref initialization\n const seedSource = shuffleSeed ?? (sessionIdRef.current ??= randomSessionId());\n for (const gap of data.gaps) {\n const choices = choicesFor(data.banks, gap);\n map.set(\n gap.id,\n data.shuffleChoices === true\n ? seededShuffle(choices, `${seedSource}:${data.id}:${gap.id}`)\n : choices,\n );\n }\n return map;\n }, [data, shuffleSeed]);\n\n // All hooks are called before these throws, so hook order stays stable.\n if (devError) {\n throw devError;\n }\n // Practice grades locally, and a redacted projection has no answer key to\n // grade against — `score()` would throw RedactedScoringError from the submit\n // handler, where no error boundary can reach it and after the learner has\n // answered. Fail at render instead, in production too, exactly as the other\n // three built-ins do.\n if (data.redacted === true && renderMode === 'practice') {\n throw new Error(\n `Gap Select \"${data.id}\" received redacted activity data in renderMode \"practice\", ` +\n 'which grades locally and has no answer key to grade against. ' +\n 'Render redacted data with renderMode=\"exam\" (server grades) or \"review\" (pass `outcome`).',\n );\n }\n\n const submitted = state === 'completed';\n const inactive = disabled === true || submitted || isReview;\n\n /**\n * Whether answer-key-derived information may be shown. Never in `exam`; in\n * `practice` only once this component has scored; in `review` only once the\n * caller supplies a SCORED outcome.\n */\n const revealing = isReview ? outcome?.status === 'scored' : !isExam && submitted;\n\n const fireInteraction = (\n type: 'gap-selected' | 'submitted',\n payload: Record<string, unknown>,\n ): void => {\n onInteraction?.({ type, activityId: data.id, timestamp: Date.now(), payload });\n };\n\n const handleSelect = (gapId: string, choiceId: string): void => {\n if (inactive) {\n return;\n }\n if (state === 'idle') {\n start();\n }\n const next = { ...selections, [gapId]: choiceId };\n if (!isControlled) {\n setInternalSelections(next);\n }\n onChange?.({ type: 'gap-select', selections: next });\n fireInteraction('gap-selected', { gapId, choiceId });\n };\n\n const handleSubmit = (event: React.FormEvent): void => {\n event.preventDefault();\n if (inactive) {\n return;\n }\n const response: GapSelectLearnerResponse = { type: 'gap-select', selections };\n onSubmit?.(response);\n\n if (isExam) {\n // The client neither grades nor reveals: no score(), no read of any\n // answer-key field, no onComplete, and no xAPI statement — its\n // correctResponsesPattern IS the answer key.\n complete();\n setSummary(s.answerSubmitted);\n fireInteraction('submitted', { selections });\n return;\n }\n\n const scoringResult = score('gap-select', data as GapSelectData, response);\n complete();\n const timeSpent = getTimeSpent();\n const xapiStatement = xAPIBuilder.buildAnsweredStatement({\n actor: ANONYMOUS_ACTOR,\n object: {\n id: objectIdFor(data.id),\n name: { [data.locale ?? 'en-US']: data.title },\n ...xapiDefinitionFor(data),\n },\n scoringResult,\n timeSpentMs: timeSpent,\n response: JSON.stringify(selections),\n });\n setResult(scoringResult);\n onComplete?.({\n score: scoringResult.score,\n maxScore: scoringResult.maxScore,\n passed: scoringResult.passed,\n timeSpent,\n xapiStatement,\n });\n const overall = scoringResult.feedback;\n setSummary(\n `${s.answerSubmitted} ${s.scoreAnnouncement(\n Math.round(scoringResult.score * 100),\n scoringResult.passed,\n )}${overall ? ` ${overall}` : ''}`,\n );\n fireInteraction('submitted', { selections, score: scoringResult.score });\n };\n\n const correctByGap = useMemo(() => {\n if (isExam) {\n return new Map<string, boolean>();\n }\n if (isReview) {\n return outcome?.status === 'scored'\n ? correctnessByItem(outcome.details)\n : new Map<string, boolean>();\n }\n return correctnessByItem(result?.details ?? []);\n }, [isExam, isReview, outcome, result]);\n\n const reviewSummary = useMemo(() => {\n if (!isReview || outcome === undefined) {\n return null;\n }\n if (outcome.status === 'scored') {\n return `${s.scoreAnnouncement(Math.round(outcome.score * 100), outcome.passed)}${\n outcome.feedback ? ` ${outcome.feedback}` : ''\n }`;\n }\n if (outcome.status === 'deferred') {\n return s.notGradedYet;\n }\n if (outcome.status === 'graded') {\n const percent =\n outcome.maxScore > 0\n ? Math.round((outcome.score / outcome.maxScore) * 100)\n : Math.round(outcome.score * 100);\n return `${s.scoreAnnouncement(percent, outcome.passed)}${\n outcome.feedback ? ` ${outcome.feedback}` : ''\n }`;\n }\n return s.noGradeAvailable;\n }, [isReview, outcome, s]);\n\n const anyFeedback = data.gaps.some((gap) => gap.feedback !== undefined);\n\n return (\n <form\n className=\"lk-gs\"\n aria-label={data.title}\n lang={locale}\n data-render-mode={renderMode}\n style={theme as CSSProperties | undefined}\n onSubmit={handleSubmit}\n >\n {data.media ? (\n <ActivityMedia\n media={data.media}\n renderMode={renderMode}\n {...(mediaBudget !== undefined ? { mediaBudget } : {})}\n {...(mediaStrings !== undefined ? { mediaStrings } : {})}\n {...(strings !== undefined ? { strings } : {})}\n {...(onInteraction !== undefined ? { onInteraction } : {})}\n {...(locale !== undefined ? { locale } : {})}\n />\n ) : null}\n <fieldset disabled={inactive}>\n <p className=\"lk-gs-passage\">\n {segments.map((seg, i) => {\n if (seg.kind === 'text') {\n // biome-ignore lint/suspicious/noArrayIndexKey: passage segments are positional and static\n return <span key={`t${i}`}>{seg.value}</span>;\n }\n const gap = gapById.get(seg.id);\n if (!gap) {\n return null;\n }\n const choices = choicesByGap.get(seg.id) ?? [];\n const correctness = correctByGap.get(seg.id);\n // Read defensively and never in exam: a redact() projection omits\n // both at runtime while the type still says they are there.\n const gapFeedback = isExam ? undefined : gap.feedback;\n return (\n <span key={seg.id} className=\"lk-gs-gap\">\n <select\n className=\"lk-gs-select\"\n aria-label={s.gapLabel(seg.ordinal)}\n value={selections[seg.id] ?? ''}\n disabled={inactive}\n aria-disabled={inactive || undefined}\n data-correct={\n revealing && correctness !== undefined ? String(correctness) : undefined\n }\n onChange={(e) => handleSelect(seg.id, e.target.value)}\n >\n {/*\n The empty entry is part of the contract, not a decoration.\n It is how a learner leaves a gap alone — and how they take\n an answer back — so \"not answered\" stays distinguishable\n from \"answered wrongly\" all the way into ItemOutcome, where\n the scorer reports it as `incorrect-omission`.\n */}\n <option value=\"\">{s.gapPlaceholder}</option>\n {choices.map((choice) => (\n <option key={choice.id} value={choice.id}>\n {choice.text}\n </option>\n ))}\n </select>\n {revealing && !feedbackHidden && gapFeedback ? (\n <span\n className=\"lk-gs-gap-feedback\"\n role=\"note\"\n data-correct={correctness !== undefined ? String(correctness) : undefined}\n >\n {gapFeedback}\n </span>\n ) : null}\n </span>\n );\n })}\n </p>\n {isReview ? null : (\n <button type=\"submit\" disabled={inactive}>\n {isExam ? s.submitAnswers : s.checkAnswers}\n </button>\n )}\n </fieldset>\n {revealing && anyFeedback ? (\n <button\n type=\"button\"\n className=\"lk-gs-feedback-toggle\"\n aria-expanded={!feedbackHidden}\n onClick={() => setFeedbackHidden((h) => !h)}\n >\n {feedbackHidden ? s.showFeedback : s.hideFeedback}\n </button>\n ) : null}\n <FeedbackRegion id={`${data.id}-feedback`}>\n {isReview ? reviewSummary : summary}\n </FeedbackRegion>\n </form>\n );\n}\n","'use client';\n\nimport { useLkStrings } from '../../i18n/LkIntlProvider.js';\nimport { ActivityErrorBoundary } from '../ActivityErrorBoundary.js';\nimport { GapSelect as GapSelectCore, type GapSelectProps } from './GapSelect.js';\n\nexport type { GapSelectProps } from './GapSelect.js';\n\n/**\n * Public Gap Select activity: the core wrapped in `ActivityErrorBoundary` so a\n * render failure (including the dev schema-validation throw and the\n * redacted-in-`practice` guard) degrades to an accessible fallback instead of\n * crashing the host.\n */\nexport function GapSelect(props: GapSelectProps) {\n const strings = useLkStrings(props.strings);\n return (\n <ActivityErrorBoundary activityTitle={props.data?.title} strings={strings}>\n <GapSelectCore {...props} />\n </ActivityErrorBoundary>\n );\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { DEFAULT_STRINGS } from './chunk-
|
|
2
|
+
import { DEFAULT_STRINGS } from './chunk-CK7Z275S.js';
|
|
3
3
|
import { Component } from 'react';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -51,5 +51,5 @@ function FeedbackRegion({ id, className, children }) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export { ANONYMOUS_ACTOR, ActivityErrorBoundary, FeedbackRegion, isDevelopment, objectIdFor, randomSessionId };
|
|
54
|
-
//# sourceMappingURL=chunk-
|
|
55
|
-
//# sourceMappingURL=chunk-
|
|
54
|
+
//# sourceMappingURL=chunk-ZFWC4KZC.js.map
|
|
55
|
+
//# sourceMappingURL=chunk-ZFWC4KZC.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ActivityErrorBoundary.tsx","../src/components/_internal.ts","../src/components/shared/FeedbackRegion.tsx"],"names":["jsx"],"mappings":";;;;AAMA,SAAS,YAAA,GAAwB;AAC/B,EAAA,MAAM,CAAA,GAAI,UAAA;AACV,EAAA,OAAO,CAAA,CAAE,OAAA,EAAS,GAAA,EAAK,QAAA,KAAa,YAAA;AACtC;AAuBO,IAAM,qBAAA,GAAN,cAAoC,SAAA,CAGzC;AAAA,EACA,KAAA,GAAoC,EAAE,KAAA,EAAO,IAAA,EAAK;AAAA,EAElD,OAAO,yBAAyB,KAAA,EAA0C;AACxE,IAAA,OAAO,EAAE,KAAA,EAAM;AAAA,EACjB;AAAA,EAEA,MAAA,GAAoB;AAClB,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,IAAA,CAAK,KAAA;AACvB,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,OAAO,KAAK,KAAA,CAAM,QAAA;AAAA,IACpB;AAEA,IAAA,IAAI,CAAC,cAAa,EAAG;AACnB,MAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,IAAA,EAAK,OAAA,EACR,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,QAAA,EAAA,CAAA,IAAA,CAAK,KAAA,CAAM,OAAA,IAAW,iBAAiB,cAAA,EAAe,CAAA;AAAA,wBAChE,GAAA,CAAC,KAAA,EAAA,EAAK,QAAA,EAAA,KAAA,CAAM,KAAA,IAAS,MAAM,OAAA,EAAQ;AAAA,OAAA,EACrC,CAAA;AAAA,IAEJ;AAEA,IAAA,uBACE,GAAA,CAAC,SAAI,IAAA,EAAK,OAAA,EACP,eAAK,KAAA,CAAM,aAAA,GAAA,CACP,KAAK,KAAA,CAAM,OAAA,IAAW,iBAAiB,mBAAA,CAAoB,IAAA,CAAK,MAAM,aAAa,CAAA,GAAA,CACnF,KAAK,KAAA,CAAM,OAAA,IAAW,iBAAiB,qBAAA,EAC9C,CAAA;AAAA,EAEJ;AACF;;;AC9DO,SAAS,aAAA,GAAyB;AACvC,EAAA,MAAM,CAAA,GAAI,UAAA;AACV,EAAA,OAAO,CAAA,CAAE,OAAA,EAAS,GAAA,EAAK,QAAA,KAAa,YAAA;AACtC;AAOO,IAAM,eAAA,GAA6B;AAAA,EACxC,UAAA,EAAY,OAAA;AAAA,EACZ,OAAA,EAAS,EAAE,QAAA,EAAU,6CAAA,EAA+C,MAAM,WAAA;AAC5E;AAGO,SAAS,YAAY,EAAA,EAAoB;AAC9C,EAAA,OAAO,CAAA,0BAAA,EAA6B,kBAAA,CAAmB,EAAE,CAAC,CAAA,CAAA;AAC5D;AAQO,SAAS,eAAA,GAA0B;AACxC,EAAA,MAAM,IAAK,UAAA,CAA0D,MAAA;AACrE,EAAA,IAAI,GAAG,UAAA,EAAY;AACjB,IAAA,OAAO,EAAE,UAAA,EAAW;AAAA,EACtB;AACA,EAAA,OAAO,KAAK,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,EAAE,EAAE,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,IAAA,CAAK,QAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACvF;ACrBO,SAAS,cAAA,CAAe,EAAE,EAAA,EAAI,SAAA,EAAW,UAAS,EAAwB;AAC/E,EAAA,uBACEA,IAAC,KAAA,EAAA,EAAI,EAAA,EAAQ,WAAsB,WAAA,EAAU,QAAA,EAAS,aAAA,EAAY,MAAA,EAC/D,QAAA,EACH,CAAA;AAEJ","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/components/ActivityErrorBoundary.tsx","../src/components/_internal.ts","../src/components/shared/FeedbackRegion.tsx"],"names":["jsx"],"mappings":";;;;AAMA,SAAS,YAAA,GAAwB;AAC/B,EAAA,MAAM,CAAA,GAAI,UAAA;AACV,EAAA,OAAO,CAAA,CAAE,OAAA,EAAS,GAAA,EAAK,QAAA,KAAa,YAAA;AACtC;AAuBO,IAAM,qBAAA,GAAN,cAAoC,SAAA,CAGzC;AAAA,EACA,KAAA,GAAoC,EAAE,KAAA,EAAO,IAAA,EAAK;AAAA,EAElD,OAAO,yBAAyB,KAAA,EAA0C;AACxE,IAAA,OAAO,EAAE,KAAA,EAAM;AAAA,EACjB;AAAA,EAEA,MAAA,GAAoB;AAClB,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,IAAA,CAAK,KAAA;AACvB,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,OAAO,KAAK,KAAA,CAAM,QAAA;AAAA,IACpB;AAEA,IAAA,IAAI,CAAC,cAAa,EAAG;AACnB,MAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,IAAA,EAAK,OAAA,EACR,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,QAAA,EAAA,CAAA,IAAA,CAAK,KAAA,CAAM,OAAA,IAAW,iBAAiB,cAAA,EAAe,CAAA;AAAA,wBAChE,GAAA,CAAC,KAAA,EAAA,EAAK,QAAA,EAAA,KAAA,CAAM,KAAA,IAAS,MAAM,OAAA,EAAQ;AAAA,OAAA,EACrC,CAAA;AAAA,IAEJ;AAEA,IAAA,uBACE,GAAA,CAAC,SAAI,IAAA,EAAK,OAAA,EACP,eAAK,KAAA,CAAM,aAAA,GAAA,CACP,KAAK,KAAA,CAAM,OAAA,IAAW,iBAAiB,mBAAA,CAAoB,IAAA,CAAK,MAAM,aAAa,CAAA,GAAA,CACnF,KAAK,KAAA,CAAM,OAAA,IAAW,iBAAiB,qBAAA,EAC9C,CAAA;AAAA,EAEJ;AACF;;;AC9DO,SAAS,aAAA,GAAyB;AACvC,EAAA,MAAM,CAAA,GAAI,UAAA;AACV,EAAA,OAAO,CAAA,CAAE,OAAA,EAAS,GAAA,EAAK,QAAA,KAAa,YAAA;AACtC;AAOO,IAAM,eAAA,GAA6B;AAAA,EACxC,UAAA,EAAY,OAAA;AAAA,EACZ,OAAA,EAAS,EAAE,QAAA,EAAU,6CAAA,EAA+C,MAAM,WAAA;AAC5E;AAGO,SAAS,YAAY,EAAA,EAAoB;AAC9C,EAAA,OAAO,CAAA,0BAAA,EAA6B,kBAAA,CAAmB,EAAE,CAAC,CAAA,CAAA;AAC5D;AAQO,SAAS,eAAA,GAA0B;AACxC,EAAA,MAAM,IAAK,UAAA,CAA0D,MAAA;AACrE,EAAA,IAAI,GAAG,UAAA,EAAY;AACjB,IAAA,OAAO,EAAE,UAAA,EAAW;AAAA,EACtB;AACA,EAAA,OAAO,KAAK,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,EAAE,EAAE,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,IAAA,CAAK,QAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACvF;ACrBO,SAAS,cAAA,CAAe,EAAE,EAAA,EAAI,SAAA,EAAW,UAAS,EAAwB;AAC/E,EAAA,uBACEA,IAAC,KAAA,EAAA,EAAI,EAAA,EAAQ,WAAsB,WAAA,EAAU,QAAA,EAAS,aAAA,EAAY,MAAA,EAC/D,QAAA,EACH,CAAA;AAEJ","file":"chunk-ZFWC4KZC.js","sourcesContent":["'use client';\n\nimport { Component, type ReactNode } from 'react';\nimport type { LkStrings } from '../i18n/strings.js';\nimport { DEFAULT_STRINGS } from '../i18n/strings.js';\n\nfunction isProduction(): boolean {\n const g = globalThis as { process?: { env?: Record<string, string | undefined> } };\n return g.process?.env?.NODE_ENV === 'production';\n}\n\nexport interface ActivityErrorBoundaryProps {\n /** Shown in the production fallback when a render error occurs. */\n activityTitle?: string;\n /**\n * Chrome text. A class component cannot call `useLkStrings`, so the public\n * wrapper reads the hook and hands the resolved dictionary down.\n */\n strings?: LkStrings;\n children: ReactNode;\n}\n\ninterface ActivityErrorBoundaryState {\n error: Error | null;\n}\n\n/**\n * Catches render errors in an activity subtree. In development it renders the\n * full error stack to aid debugging; in production it renders an accessible,\n * generic fallback (optionally naming the activity) so a single broken\n * activity never crashes the host application.\n */\nexport class ActivityErrorBoundary extends Component<\n ActivityErrorBoundaryProps,\n ActivityErrorBoundaryState\n> {\n state: ActivityErrorBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: Error): ActivityErrorBoundaryState {\n return { error };\n }\n\n render(): ReactNode {\n const { error } = this.state;\n if (!error) {\n return this.props.children;\n }\n\n if (!isProduction()) {\n return (\n <div role=\"alert\">\n <strong>{(this.props.strings ?? DEFAULT_STRINGS).activityFailed}</strong>\n <pre>{error.stack ?? error.message}</pre>\n </div>\n );\n }\n\n return (\n <div role=\"alert\">\n {this.props.activityTitle\n ? (this.props.strings ?? DEFAULT_STRINGS).activityFailedNamed(this.props.activityTitle)\n : (this.props.strings ?? DEFAULT_STRINGS).activityFailedUnnamed}\n </div>\n );\n }\n}\n","import type { XAPIActor } from '@intellectif/lk-core';\n\n/** Dev = anything other than an explicit production NODE_ENV (browser-safe). */\nexport function isDevelopment(): boolean {\n const g = globalThis as { process?: { env?: Record<string, string | undefined> } };\n return g.process?.env?.NODE_ENV !== 'production';\n}\n\n/**\n * Activity components cannot know the learner's identity (Req 3.1 fixes the\n * prop set). They emit a structurally-valid statement with this anonymous\n * actor; real identity is applied by the useXAPI/LRS layer (XAPIConfig.actor).\n */\nexport const ANONYMOUS_ACTOR: XAPIActor = {\n objectType: 'Agent',\n account: { homePage: 'https://github.com/intellectif/learning-kit', name: 'anonymous' },\n};\n\n/** `data.id` is not an IRI; xAPI object ids must be. Wrap it as a URN. */\nexport function objectIdFor(id: string): string {\n return `urn:learning-kit:activity:${encodeURIComponent(id)}`;\n}\n\n/**\n * Random per-mount session id for the shuffle seed. `crypto.randomUUID` is\n * unavailable outside secure contexts (plain-http LAN/staging hosts), so a\n * Math.random fallback keeps the component from crashing there — the seed\n * only randomises presentation order, so cryptographic strength is not needed.\n */\nexport function randomSessionId(): string {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (c?.randomUUID) {\n return c.randomUUID();\n }\n return `s-${Math.random().toString(36).slice(2)}${Math.random().toString(36).slice(2)}`;\n}\n","import type { ReactNode } from 'react';\n\nexport interface FeedbackRegionProps {\n /** Identifier so activity inputs can reference this region via aria. */\n id?: string;\n className?: string;\n children?: ReactNode;\n}\n\n/**\n * A polite ARIA live region. Screen readers announce content injected here\n * (score, feedback, state changes) without moving focus. Pure/presentational\n * — safe to render in any environment.\n */\nexport function FeedbackRegion({ id, className, children }: FeedbackRegionProps) {\n return (\n <div id={id} className={className} aria-live=\"polite\" aria-atomic=\"true\">\n {children}\n </div>\n );\n}\n"]}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
require('../chunk-
|
|
6
|
-
require('../chunk-
|
|
7
|
-
require('../chunk-
|
|
8
|
-
require('../chunk-
|
|
9
|
-
require('../chunk-
|
|
10
|
-
require('../chunk-AHEV52U7.cjs');
|
|
4
|
+
var chunk6KMEB7TF_cjs = require('../chunk-6KMEB7TF.cjs');
|
|
5
|
+
require('../chunk-G6PUWKQC.cjs');
|
|
6
|
+
require('../chunk-LIHKQEIP.cjs');
|
|
7
|
+
require('../chunk-NK5EVL5C.cjs');
|
|
8
|
+
require('../chunk-64AJVB6O.cjs');
|
|
9
|
+
require('../chunk-EWTAMY6L.cjs');
|
|
11
10
|
require('../chunk-XOR4MPEN.cjs');
|
|
11
|
+
require('../chunk-FX7VMZHQ.cjs');
|
|
12
|
+
require('../chunk-KYOCDRUO.cjs');
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
Object.defineProperty(exports, "ActivityPreview", {
|
|
16
17
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
18
|
+
get: function () { return chunk6KMEB7TF_cjs.ActivityPreview; }
|
|
18
19
|
});
|
|
19
20
|
//# sourceMappingURL=ActivityPreview.cjs.map
|
|
20
21
|
//# sourceMappingURL=ActivityPreview.cjs.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { LearnerResponse, ItemOutcome, DraftNotComplete, ThemeTokens } from '@intellectif/lk-core';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
|
-
import { R as RenderMode, H as HtmlSanitizer, a as LkStringsOverride } from '../strings-
|
|
4
|
+
import { R as RenderMode, H as HtmlSanitizer, a as LkStringsOverride } from '../strings-CN7n-BlE.cjs';
|
|
5
5
|
import { ActivityRenderer } from './ActivitySequence.cjs';
|
|
6
|
-
import '../WrittenResponse-
|
|
6
|
+
import '../WrittenResponse-ByzXYEoW.cjs';
|
|
7
7
|
|
|
8
8
|
interface ActivityPreviewProps {
|
|
9
9
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { LearnerResponse, ItemOutcome, DraftNotComplete, ThemeTokens } from '@intellectif/lk-core';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
|
-
import { R as RenderMode, H as HtmlSanitizer, a as LkStringsOverride } from '../strings-
|
|
4
|
+
import { R as RenderMode, H as HtmlSanitizer, a as LkStringsOverride } from '../strings-CN7n-BlE.js';
|
|
5
5
|
import { ActivityRenderer } from './ActivitySequence.js';
|
|
6
|
-
import '../WrittenResponse-
|
|
6
|
+
import '../WrittenResponse-BgcpEM-e.js';
|
|
7
7
|
|
|
8
8
|
interface ActivityPreviewProps {
|
|
9
9
|
/**
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { ActivityPreview } from '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
5
|
-
import '../chunk-
|
|
6
|
-
import '../chunk-
|
|
7
|
-
import '../chunk-
|
|
8
|
-
import '../chunk-T4CKODCJ.js';
|
|
2
|
+
export { ActivityPreview } from '../chunk-5S2YDMEJ.js';
|
|
3
|
+
import '../chunk-QXYAOILF.js';
|
|
4
|
+
import '../chunk-XKGBD3UK.js';
|
|
5
|
+
import '../chunk-ZFSRMGWO.js';
|
|
6
|
+
import '../chunk-GWD75Q25.js';
|
|
7
|
+
import '../chunk-ZFWC4KZC.js';
|
|
9
8
|
import '../chunk-6N43WDVG.js';
|
|
9
|
+
import '../chunk-2Y6V5E7H.js';
|
|
10
|
+
import '../chunk-CK7Z275S.js';
|
|
10
11
|
//# sourceMappingURL=ActivityPreview.js.map
|
|
11
12
|
//# sourceMappingURL=ActivityPreview.js.map
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
require('../chunk-
|
|
6
|
-
require('../chunk-
|
|
7
|
-
require('../chunk-
|
|
8
|
-
require('../chunk-
|
|
9
|
-
require('../chunk-
|
|
10
|
-
require('../chunk-2VLKSNYJ.cjs');
|
|
11
|
-
require('../chunk-AHEV52U7.cjs');
|
|
4
|
+
var chunkMYGFVEYU_cjs = require('../chunk-MYGFVEYU.cjs');
|
|
5
|
+
require('../chunk-G6PUWKQC.cjs');
|
|
6
|
+
require('../chunk-LIHKQEIP.cjs');
|
|
7
|
+
require('../chunk-NK5EVL5C.cjs');
|
|
8
|
+
require('../chunk-64AJVB6O.cjs');
|
|
9
|
+
require('../chunk-EWTAMY6L.cjs');
|
|
12
10
|
require('../chunk-XOR4MPEN.cjs');
|
|
11
|
+
require('../chunk-KSXEBV2H.cjs');
|
|
12
|
+
require('../chunk-FX7VMZHQ.cjs');
|
|
13
|
+
require('../chunk-KYOCDRUO.cjs');
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
Object.defineProperty(exports, "ActivitySequence", {
|
|
17
18
|
enumerable: true,
|
|
18
|
-
get: function () { return
|
|
19
|
+
get: function () { return chunkMYGFVEYU_cjs.ActivitySequence; }
|
|
19
20
|
});
|
|
20
21
|
//# sourceMappingURL=ActivitySequence.cjs.map
|
|
21
22
|
//# sourceMappingURL=ActivitySequence.cjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SequenceEntry, ActivityResult, LearnerResponse, InteractionEvent, ItemOutcome, ThemeTokens } from '@intellectif/lk-core';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
|
-
import { A as ActivityProps, d as RenderableActivity, R as RenderMode, S as SequenceMediaBudget, a as LkStringsOverride, H as HtmlSanitizer } from '../strings-
|
|
4
|
-
import { a as WrittenResponseSubmission } from '../WrittenResponse-
|
|
3
|
+
import { A as ActivityProps, d as RenderableActivity, R as RenderMode, S as SequenceMediaBudget, a as LkStringsOverride, H as HtmlSanitizer } from '../strings-CN7n-BlE.cjs';
|
|
4
|
+
import { a as WrittenResponseSubmission } from '../WrittenResponse-ByzXYEoW.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* What one finished slot in a sequence produced. Two kinds, because two kinds
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SequenceEntry, ActivityResult, LearnerResponse, InteractionEvent, ItemOutcome, ThemeTokens } from '@intellectif/lk-core';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
|
-
import { A as ActivityProps, d as RenderableActivity, R as RenderMode, S as SequenceMediaBudget, a as LkStringsOverride, H as HtmlSanitizer } from '../strings-
|
|
4
|
-
import { a as WrittenResponseSubmission } from '../WrittenResponse-
|
|
3
|
+
import { A as ActivityProps, d as RenderableActivity, R as RenderMode, S as SequenceMediaBudget, a as LkStringsOverride, H as HtmlSanitizer } from '../strings-CN7n-BlE.js';
|
|
4
|
+
import { a as WrittenResponseSubmission } from '../WrittenResponse-BgcpEM-e.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* What one finished slot in a sequence produced. Two kinds, because two kinds
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { ActivitySequence } from '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
5
|
-
import '../chunk-
|
|
6
|
-
import '../chunk-
|
|
7
|
-
import '../chunk-
|
|
8
|
-
import '../chunk-7OHPBLPH.js';
|
|
9
|
-
import '../chunk-T4CKODCJ.js';
|
|
2
|
+
export { ActivitySequence } from '../chunk-AP6NX3XF.js';
|
|
3
|
+
import '../chunk-QXYAOILF.js';
|
|
4
|
+
import '../chunk-XKGBD3UK.js';
|
|
5
|
+
import '../chunk-ZFSRMGWO.js';
|
|
6
|
+
import '../chunk-GWD75Q25.js';
|
|
7
|
+
import '../chunk-ZFWC4KZC.js';
|
|
10
8
|
import '../chunk-6N43WDVG.js';
|
|
9
|
+
import '../chunk-5IH3NRXE.js';
|
|
10
|
+
import '../chunk-2Y6V5E7H.js';
|
|
11
|
+
import '../chunk-CK7Z275S.js';
|
|
11
12
|
//# sourceMappingURL=ActivitySequence.js.map
|
|
12
13
|
//# sourceMappingURL=ActivitySequence.js.map
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
require('../chunk-
|
|
6
|
-
require('../chunk-2VLKSNYJ.cjs');
|
|
7
|
-
require('../chunk-AHEV52U7.cjs');
|
|
4
|
+
var chunkLIHKQEIP_cjs = require('../chunk-LIHKQEIP.cjs');
|
|
5
|
+
require('../chunk-EWTAMY6L.cjs');
|
|
8
6
|
require('../chunk-XOR4MPEN.cjs');
|
|
7
|
+
require('../chunk-FX7VMZHQ.cjs');
|
|
8
|
+
require('../chunk-KYOCDRUO.cjs');
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
Object.defineProperty(exports, "FillInTheBlanks", {
|
|
13
13
|
enumerable: true,
|
|
14
|
-
get: function () { return
|
|
14
|
+
get: function () { return chunkLIHKQEIP_cjs.FillInTheBlanks; }
|
|
15
15
|
});
|
|
16
16
|
//# sourceMappingURL=FillInTheBlanks.cjs.map
|
|
17
17
|
//# sourceMappingURL=FillInTheBlanks.cjs.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { FillInTheBlanksData } from '@intellectif/lk-core';
|
|
3
|
-
import { A as ActivityProps } from '../strings-
|
|
3
|
+
import { A as ActivityProps } from '../strings-CN7n-BlE.cjs';
|
|
4
4
|
|
|
5
5
|
interface FillInTheBlanksProps extends ActivityProps<FillInTheBlanksData> {
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { FillInTheBlanksData } from '@intellectif/lk-core';
|
|
3
|
-
import { A as ActivityProps } from '../strings-
|
|
3
|
+
import { A as ActivityProps } from '../strings-CN7n-BlE.js';
|
|
4
4
|
|
|
5
5
|
interface FillInTheBlanksProps extends ActivityProps<FillInTheBlanksData> {
|
|
6
6
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { FillInTheBlanks } from '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-7OHPBLPH.js';
|
|
5
|
-
import '../chunk-T4CKODCJ.js';
|
|
2
|
+
export { FillInTheBlanks } from '../chunk-XKGBD3UK.js';
|
|
3
|
+
import '../chunk-ZFWC4KZC.js';
|
|
6
4
|
import '../chunk-6N43WDVG.js';
|
|
5
|
+
import '../chunk-2Y6V5E7H.js';
|
|
6
|
+
import '../chunk-CK7Z275S.js';
|
|
7
7
|
//# sourceMappingURL=FillInTheBlanks.js.map
|
|
8
8
|
//# sourceMappingURL=FillInTheBlanks.js.map
|