@longsightgroup/qti3-migrator 0.9.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.
Files changed (68) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +13 -0
  3. package/dist/diagnostics.d.ts +7 -0
  4. package/dist/diagnostics.d.ts.map +1 -0
  5. package/dist/diagnostics.js +7 -0
  6. package/dist/diagnostics.js.map +1 -0
  7. package/dist/index.d.ts +7 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +262 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/options.d.ts +3 -0
  12. package/dist/options.d.ts.map +1 -0
  13. package/dist/options.js +7 -0
  14. package/dist/options.js.map +1 -0
  15. package/dist/qti12-item.d.ts +7 -0
  16. package/dist/qti12-item.d.ts.map +1 -0
  17. package/dist/qti12-item.js +393 -0
  18. package/dist/qti12-item.js.map +1 -0
  19. package/dist/qti2-body.d.ts +11 -0
  20. package/dist/qti2-body.d.ts.map +1 -0
  21. package/dist/qti2-body.js +90 -0
  22. package/dist/qti2-body.js.map +1 -0
  23. package/dist/qti2-choices.d.ts +7 -0
  24. package/dist/qti2-choices.d.ts.map +1 -0
  25. package/dist/qti2-choices.js +74 -0
  26. package/dist/qti2-choices.js.map +1 -0
  27. package/dist/qti2-graphic.d.ts +10 -0
  28. package/dist/qti2-graphic.d.ts.map +1 -0
  29. package/dist/qti2-graphic.js +30 -0
  30. package/dist/qti2-graphic.js.map +1 -0
  31. package/dist/qti2-item.d.ts +8 -0
  32. package/dist/qti2-item.d.ts.map +1 -0
  33. package/dist/qti2-item.js +494 -0
  34. package/dist/qti2-item.js.map +1 -0
  35. package/dist/qti2-response.d.ts +9 -0
  36. package/dist/qti2-response.d.ts.map +1 -0
  37. package/dist/qti2-response.js +32 -0
  38. package/dist/qti2-response.js.map +1 -0
  39. package/dist/source.d.ts +30 -0
  40. package/dist/source.d.ts.map +1 -0
  41. package/dist/source.js +197 -0
  42. package/dist/source.js.map +1 -0
  43. package/dist/text.d.ts +5 -0
  44. package/dist/text.d.ts.map +1 -0
  45. package/dist/text.js +19 -0
  46. package/dist/text.js.map +1 -0
  47. package/dist/types.d.ts +61 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +2 -0
  50. package/dist/types.js.map +1 -0
  51. package/dist/xml.d.ts +16 -0
  52. package/dist/xml.d.ts.map +1 -0
  53. package/dist/xml.js +101 -0
  54. package/dist/xml.js.map +1 -0
  55. package/package.json +56 -0
  56. package/src/diagnostics.ts +21 -0
  57. package/src/index.ts +393 -0
  58. package/src/options.ts +8 -0
  59. package/src/qti12-item.ts +507 -0
  60. package/src/qti2-body.ts +138 -0
  61. package/src/qti2-choices.ts +96 -0
  62. package/src/qti2-graphic.ts +32 -0
  63. package/src/qti2-item.ts +650 -0
  64. package/src/qti2-response.ts +41 -0
  65. package/src/source.ts +251 -0
  66. package/src/text.ts +21 -0
  67. package/src/types.ts +73 -0
  68. package/src/xml.ts +119 -0
@@ -0,0 +1,393 @@
1
+ import { qti3TrustedXmlFragment, } from "@longsightgroup/qti3-writer";
2
+ import { diagnostic } from "./diagnostics.js";
3
+ import { escapeText, normalizeIdentifier } from "./text.js";
4
+ import { attr, childElements, findAllDescendantsByLocalName, findDescendantByLocalName, localName, parseXml, serializeChildren, textOf, } from "./xml.js";
5
+ export function migrateQti12Xml(xml, path, options) {
6
+ const doc = parseXml(xml, path);
7
+ const root = doc.documentElement;
8
+ const itemElements = localName(root) === "item" ? [root] : findAllDescendantsByLocalName(root, "item");
9
+ if (!itemElements.length) {
10
+ return [
11
+ {
12
+ diagnostics: [
13
+ diagnostic("qti12_item_missing", "error", "No QTI 1.2 item elements found.", {
14
+ path,
15
+ sourceFormat: "qti12",
16
+ }),
17
+ ],
18
+ },
19
+ ];
20
+ }
21
+ return itemElements.map((item, index) => migrateQti12ItemElement(item, index, path, options));
22
+ }
23
+ function migrateQti12ItemElement(item, index, path, options) {
24
+ const identifier = normalizeIdentifier(attr(item, "ident"), `ITEM_${index + 1}`);
25
+ const title = attr(item, "title")?.trim() || `Item ${index + 1}`;
26
+ const presentation = findDescendantByLocalName(item, "presentation");
27
+ const bodyHtml = qti3TrustedXmlFragment(presentation ? materialHtml(presentation) : "<p></p>");
28
+ const responseLids = findAllDescendantsByLocalName(item, "response_lid");
29
+ const responseStrs = findAllDescendantsByLocalName(item, "response_str");
30
+ const responseNums = findAllDescendantsByLocalName(item, "response_num");
31
+ const responseGrps = findAllDescendantsByLocalName(item, "response_grp");
32
+ const correct = correctEntries(item);
33
+ const itemType = (attr(item, "title") ?? "").toLowerCase();
34
+ if (itemType.includes("essay")) {
35
+ return {
36
+ authoringItem: {
37
+ interactionType: "extendedText",
38
+ identifier,
39
+ title,
40
+ bodyHtml,
41
+ responseIdentifier: "RESPONSE",
42
+ responseBaseType: "string",
43
+ responseCardinality: "single",
44
+ expectedLines: 8,
45
+ },
46
+ diagnostics: [],
47
+ };
48
+ }
49
+ const hotspotResponse = responseLids.find((response) => findDescendantByLocalName(response, "render_hotspot"));
50
+ if (hotspotResponse) {
51
+ return {
52
+ ...mapQti12Hotspot(identifier, title, hotspotResponse, bodyHtml, correct, options),
53
+ };
54
+ }
55
+ const groupedChoice = responseGrps.find((response) => findDescendantByLocalName(response, "render_choice"));
56
+ if (groupedChoice) {
57
+ return {
58
+ ...mapQti12Associate(identifier, title, groupedChoice, bodyHtml, correct, options),
59
+ };
60
+ }
61
+ const choiceResponses = responseLids.filter((response) => findDescendantByLocalName(response, "render_choice"));
62
+ if (choiceResponses.length > 1) {
63
+ return {
64
+ ...mapQti12CanvasMatch(identifier, title, choiceResponses, bodyHtml, correct, options),
65
+ };
66
+ }
67
+ const choiceResponse = choiceResponses[0];
68
+ if (choiceResponse) {
69
+ return {
70
+ ...mapQti12Choice(identifier, title, choiceResponse, bodyHtml, correct, options),
71
+ };
72
+ }
73
+ const fibResponse = [...responseLids, ...responseStrs, ...responseNums].find((response) => findDescendantByLocalName(response, "render_fib"));
74
+ if (fibResponse) {
75
+ return {
76
+ ...mapQti12TextEntry(identifier, title, fibResponse, presentation, correct, options),
77
+ };
78
+ }
79
+ return {
80
+ diagnostics: [
81
+ diagnostic("qti12_interaction_unsupported", "error", "Unsupported QTI 1.2 interaction.", {
82
+ path,
83
+ sourceFormat: "qti12",
84
+ }),
85
+ ],
86
+ };
87
+ }
88
+ function mapQti12CanvasMatch(identifier, title, responses, bodyHtml, correct, options) {
89
+ const sources = responses.map((response, index) => {
90
+ const responseIdentifier = normalizeIdentifier(attr(response, "ident"), `SOURCE_${index + 1}`);
91
+ const material = findDescendantByLocalName(response, "material");
92
+ return {
93
+ identifier: responseIdentifier,
94
+ contentHtml: qti3TrustedXmlFragment(material ? materialHtml(material) : responseIdentifier),
95
+ text: textOf(material) || responseIdentifier,
96
+ matchMax: 1,
97
+ };
98
+ });
99
+ const targets = canvasMatchTargets(responses);
100
+ const targetIdentifiers = new Set(targets.map((target) => target.identifier));
101
+ const correctResponse = sources.flatMap((source) => {
102
+ const targetIdentifier = (correct.get(source.identifier) ?? [])
103
+ .map((entry) => normalizeIdentifier(entry))
104
+ .find((entry) => targetIdentifiers.has(entry));
105
+ return targetIdentifier ? [{ sourceIdentifier: source.identifier, targetIdentifier }] : [];
106
+ });
107
+ const repair = repairOrError({
108
+ needed: correctResponse.length !== sources.length,
109
+ options,
110
+ code: "qti12_canvas_match_correct_response_incomplete",
111
+ message: "Canvas QTI 1.2 matching item has incomplete or invalid correct pairs.",
112
+ repairMessage: "Canvas QTI 1.2 matching item has incomplete correct pairs; migrating available pairs for review.",
113
+ });
114
+ if (repair.blocked)
115
+ return { diagnostics: repair.diagnostics };
116
+ return {
117
+ authoringItem: {
118
+ interactionType: "match",
119
+ identifier,
120
+ title,
121
+ bodyHtml,
122
+ responseIdentifier: "RESPONSE",
123
+ sources,
124
+ targets,
125
+ correctResponse,
126
+ shuffle: false,
127
+ },
128
+ diagnostics: repair.diagnostics,
129
+ };
130
+ }
131
+ function canvasMatchTargets(responses) {
132
+ const targets = [];
133
+ const seen = new Set();
134
+ for (const response of responses) {
135
+ const renderChoice = findDescendantByLocalName(response, "render_choice");
136
+ const labels = renderChoice
137
+ ? findAllDescendantsByLocalName(renderChoice, "response_label")
138
+ : [];
139
+ for (const [index, label] of labels.entries()) {
140
+ const identifier = normalizeIdentifier(attr(label, "ident"), `TARGET_${index + 1}`);
141
+ if (seen.has(identifier))
142
+ continue;
143
+ seen.add(identifier);
144
+ targets.push({
145
+ identifier,
146
+ contentHtml: qti3TrustedXmlFragment(materialHtml(label)),
147
+ text: textOf(label) || identifier,
148
+ matchMax: 1,
149
+ });
150
+ }
151
+ }
152
+ return targets;
153
+ }
154
+ function mapQti12Choice(identifier, title, response, bodyHtml, correct, options) {
155
+ const responseIdentifier = normalizeIdentifier(attr(response, "ident"), "RESPONSE");
156
+ const choices = responseChoices(response, "CHOICE");
157
+ const rawCorrect = correct.get(responseIdentifier) ?? [];
158
+ const correctResponse = (correct.get(responseIdentifier) ?? [])
159
+ .map((value) => normalizeIdentifier(value))
160
+ .filter((value) => choices.some((choice) => choice.identifier === value));
161
+ const repair = repairOrError({
162
+ needed: !correctResponse.length,
163
+ options,
164
+ code: "qti12_choice_correct_response_missing",
165
+ message: "QTI 1.2 choice response has no valid correct response.",
166
+ repairMessage: rawCorrect.length
167
+ ? "QTI 1.2 choice correct response referenced unknown labels; using the first declared choice."
168
+ : "QTI 1.2 choice response did not declare a correct response; using the first declared choice.",
169
+ });
170
+ if (repair.blocked)
171
+ return { diagnostics: repair.diagnostics };
172
+ const isMultiple = (attr(response, "rcardinality") ?? "").toLowerCase() === "multiple" ||
173
+ correctResponse.length > 1;
174
+ return {
175
+ authoringItem: {
176
+ interactionType: "choice",
177
+ identifier,
178
+ title,
179
+ bodyHtml,
180
+ responseIdentifier,
181
+ responseCardinality: isMultiple ? "multiple" : "single",
182
+ choices,
183
+ correctResponse: correctResponse.length
184
+ ? correctResponse
185
+ : choices.slice(0, 1).map((choice) => choice.identifier),
186
+ maxChoices: isMultiple ? undefined : 1,
187
+ },
188
+ diagnostics: repair.diagnostics,
189
+ };
190
+ }
191
+ function mapQti12Associate(identifier, title, response, bodyHtml, correct, options) {
192
+ const responseIdentifier = normalizeIdentifier(attr(response, "ident"), "RESPONSE");
193
+ const choices = responseChoices(response, "CHOICE").map((choice) => ({ ...choice, matchMax: 2 }));
194
+ const pairs = (correct.get(responseIdentifier) ?? [])
195
+ .map((entry) => {
196
+ const [sourceIdentifier = "", targetIdentifier = ""] = entry.split(/\s+/);
197
+ return {
198
+ sourceIdentifier: normalizeIdentifier(sourceIdentifier),
199
+ targetIdentifier: normalizeIdentifier(targetIdentifier),
200
+ };
201
+ })
202
+ .filter((pair) => pair.sourceIdentifier && pair.targetIdentifier);
203
+ const repair = repairOrError({
204
+ needed: !pairs.length,
205
+ options,
206
+ code: "qti12_associate_correct_response_missing",
207
+ message: "QTI 1.2 associate response has no valid correct pair.",
208
+ repairMessage: "QTI 1.2 associate response did not declare a valid pair; using the first two choices.",
209
+ });
210
+ if (repair.blocked)
211
+ return { diagnostics: repair.diagnostics };
212
+ return {
213
+ authoringItem: {
214
+ interactionType: "associate",
215
+ identifier,
216
+ title,
217
+ bodyHtml,
218
+ responseIdentifier,
219
+ choices,
220
+ correctResponse: pairs.length
221
+ ? pairs
222
+ : choices.length >= 2
223
+ ? [{ sourceIdentifier: choices[0].identifier, targetIdentifier: choices[1].identifier }]
224
+ : [],
225
+ },
226
+ diagnostics: repair.diagnostics,
227
+ };
228
+ }
229
+ function mapQti12TextEntry(identifier, title, response, presentation, correct, options) {
230
+ const responseIdentifier = normalizeIdentifier(attr(response, "ident"), "RESPONSE");
231
+ const values = correct.get(responseIdentifier) ?? [];
232
+ const repair = repairOrError({
233
+ needed: !values.length,
234
+ options,
235
+ code: "qti12_text_entry_correct_response_missing",
236
+ message: "QTI 1.2 text entry response has no correct text value.",
237
+ repairMessage: "QTI 1.2 text entry response did not declare a correct value; using an empty answer.",
238
+ });
239
+ if (repair.blocked)
240
+ return { diagnostics: repair.diagnostics };
241
+ return {
242
+ authoringItem: {
243
+ interactionType: "textEntry",
244
+ identifier,
245
+ title,
246
+ bodyHtml: qti3TrustedXmlFragment(`${presentation ? materialHtml(presentation) : "<p></p>"}<p><qti-text-entry-interaction response-identifier="${escapeText(responseIdentifier)}"/></p>`),
247
+ responses: [
248
+ {
249
+ responseIdentifier,
250
+ answers: values.length
251
+ ? values.map((value) => ({ value, score: 1, caseSensitive: false }))
252
+ : [{ value: "", score: 1, caseSensitive: false }],
253
+ },
254
+ ],
255
+ },
256
+ diagnostics: repair.diagnostics,
257
+ };
258
+ }
259
+ function mapQti12Hotspot(identifier, title, response, bodyHtml, correct, options) {
260
+ const responseIdentifier = normalizeIdentifier(attr(response, "ident"), "RESPONSE");
261
+ const labels = findAllDescendantsByLocalName(response, "response_label");
262
+ const choices = labels.map((label, index) => ({
263
+ identifier: normalizeIdentifier(attr(label, "ident"), `H${index + 1}`),
264
+ shape: qti12AreaToShape(attr(label, "rarea")),
265
+ coords: attr(label, "coords") ?? attr(label, "xy") ?? "0,0,1,1",
266
+ }));
267
+ const dimensions = inferImageDimensions(choices.map((choice) => choice.coords));
268
+ const correctResponse = (correct.get(responseIdentifier) ?? []).map((value) => normalizeIdentifier(value));
269
+ const correctRepair = repairOrError({
270
+ needed: !correctResponse.length,
271
+ options,
272
+ code: "qti12_hotspot_correct_response_missing",
273
+ message: "QTI 1.2 hotspot response has no correct hotspot identifier.",
274
+ repairMessage: "QTI 1.2 hotspot response did not declare a correct hotspot; using the first hotspot.",
275
+ });
276
+ if (correctRepair.blocked)
277
+ return { diagnostics: correctRepair.diagnostics };
278
+ const imageRepair = repairOrError({
279
+ needed: true,
280
+ options,
281
+ code: "qti12_hotspot_image_missing",
282
+ message: "QTI 1.2 hotspot migration could not identify the source image.",
283
+ repairMessage: "QTI 1.2 hotspot source image was not identified; using review placeholder image.png.",
284
+ });
285
+ if (imageRepair.blocked)
286
+ return { diagnostics: imageRepair.diagnostics };
287
+ return {
288
+ authoringItem: {
289
+ interactionType: "hotspot",
290
+ identifier,
291
+ title,
292
+ bodyHtml,
293
+ responseIdentifier,
294
+ object: {
295
+ data: "image.png",
296
+ alt: "Image",
297
+ width: dimensions.width,
298
+ height: dimensions.height,
299
+ },
300
+ choices,
301
+ correctResponse: correctResponse.length
302
+ ? correctResponse
303
+ : choices.slice(0, 1).map((choice) => choice.identifier),
304
+ maxChoices: 1,
305
+ },
306
+ diagnostics: [...correctRepair.diagnostics, ...imageRepair.diagnostics],
307
+ };
308
+ }
309
+ function responseChoices(response, prefix) {
310
+ return findAllDescendantsByLocalName(response, "response_label").map((label, index) => ({
311
+ identifier: normalizeIdentifier(attr(label, "ident"), `${prefix}_${index + 1}`),
312
+ contentHtml: qti3TrustedXmlFragment(materialHtml(label)),
313
+ text: textOf(label) || undefined,
314
+ }));
315
+ }
316
+ function materialHtml(root) {
317
+ const materials = findAllDescendantsByLocalName(root, "material");
318
+ if (!materials.length)
319
+ return serializeChildren(root).trim() || "<p></p>";
320
+ return materials
321
+ .map((material) => {
322
+ const mattext = findDescendantByLocalName(material, "mattext");
323
+ if (mattext)
324
+ return `<p>${serializeChildren(mattext) || escapeText(textOf(mattext))}</p>`;
325
+ const matimage = findDescendantByLocalName(material, "matimage");
326
+ if (matimage) {
327
+ const src = attr(matimage, "uri") ?? "";
328
+ return `<p><img src="${escapeText(src)}"/></p>`;
329
+ }
330
+ return `<p>${escapeText(textOf(material))}</p>`;
331
+ })
332
+ .join("\n");
333
+ }
334
+ function correctEntries(item) {
335
+ const out = new Map();
336
+ for (const condition of findAllDescendantsByLocalName(item, "respcondition")) {
337
+ const varequal = findAllDescendantsByLocalName(condition, "varequal");
338
+ for (const value of varequal) {
339
+ const responseIdentifier = normalizeIdentifier(attr(value, "respident"), "RESPONSE");
340
+ const values = out.get(responseIdentifier) ?? [];
341
+ values.push(textOf(value));
342
+ out.set(responseIdentifier, values);
343
+ }
344
+ }
345
+ for (const response of findAllDescendantsByLocalName(item, "response_lid")) {
346
+ const responseIdentifier = normalizeIdentifier(attr(response, "ident"), "RESPONSE");
347
+ if (out.has(responseIdentifier))
348
+ continue;
349
+ const labels = childElements(findDescendantByLocalName(response, "render_choice") ?? response).filter((child) => localName(child) === "response_label");
350
+ const correct = labels.find((label) => attr(label, "rshuffle") === "No");
351
+ if (correct)
352
+ out.set(responseIdentifier, [attr(correct, "ident") ?? ""]);
353
+ }
354
+ return out;
355
+ }
356
+ function qti12AreaToShape(value) {
357
+ const normalized = value?.toLowerCase();
358
+ if (normalized === "ellipse")
359
+ return "circle";
360
+ if (normalized === "bounded")
361
+ return "poly";
362
+ return "rect";
363
+ }
364
+ function inferImageDimensions(coords) {
365
+ let maxX = 1;
366
+ let maxY = 1;
367
+ for (const entry of coords) {
368
+ const values = entry
369
+ .split(/[\s,]+/)
370
+ .map(Number)
371
+ .filter(Number.isFinite);
372
+ for (let index = 0; index < values.length; index += 2) {
373
+ maxX = Math.max(maxX, values[index] ?? 1);
374
+ maxY = Math.max(maxY, values[index + 1] ?? 1);
375
+ }
376
+ }
377
+ return { width: Math.ceil(maxX), height: Math.ceil(maxY) };
378
+ }
379
+ function repairOrError(input) {
380
+ if (!input.needed)
381
+ return { blocked: false, diagnostics: [] };
382
+ if (input.options.repairPolicy === "safe") {
383
+ return {
384
+ blocked: false,
385
+ diagnostics: [diagnostic(`${input.code}_repaired`, "warning", input.repairMessage)],
386
+ };
387
+ }
388
+ return {
389
+ blocked: true,
390
+ diagnostics: [diagnostic(input.code, "error", input.message)],
391
+ };
392
+ }
393
+ //# sourceMappingURL=qti12-item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qti12-item.js","sourceRoot":"","sources":["../src/qti12-item.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { qti3TrustedXmlFragment } from "@longsightgroup/qti3-writer";
2
+ import { type XmlElement } from "./xml.js";
3
+ export declare function prompt(interaction: XmlElement): ReturnType<typeof qti3TrustedXmlFragment> | undefined;
4
+ export declare function bodyWithoutInteraction(body: XmlElement, interaction: XmlElement): ReturnType<typeof qti3TrustedXmlFragment>;
5
+ export declare function bodyWithInlineChoicePlaceholders(body: XmlElement, interactions: readonly XmlElement[], responseIdentifierFor: (interaction: XmlElement, fallback?: string) => string): ReturnType<typeof qti3TrustedXmlFragment>;
6
+ export declare function bodyWithTextEntryPlaceholders(body: XmlElement, interactions: readonly XmlElement[], responseIdentifierFor: (interaction: XmlElement, fallback?: string) => string): ReturnType<typeof qti3TrustedXmlFragment>;
7
+ export declare function bodyWithHottextPlaceholders(interaction: XmlElement, hottexts: readonly XmlElement[]): ReturnType<typeof qti3TrustedXmlFragment>;
8
+ export declare function bodyWithGapPlaceholders(interaction: XmlElement): ReturnType<typeof qti3TrustedXmlFragment>;
9
+ export declare function trusted(html: string): ReturnType<typeof qti3TrustedXmlFragment>;
10
+ export declare function collectInteractionElements(root: XmlElement): XmlElement[];
11
+ //# sourceMappingURL=qti2-body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qti2-body.d.ts","sourceRoot":"","sources":["../src/qti2-body.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,OAAO,EASL,KAAK,UAAU,EAEhB,MAAM,UAAU,CAAC;AAElB,wBAAgB,MAAM,CACpB,WAAW,EAAE,UAAU,GACtB,UAAU,CAAC,OAAO,sBAAsB,CAAC,GAAG,SAAS,CAIvD;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,UAAU,GACtB,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAI3C;AAED,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,UAAU,EAChB,YAAY,EAAE,SAAS,UAAU,EAAE,EACnC,qBAAqB,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,GAC5E,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAU3C;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,UAAU,EAChB,YAAY,EAAE,SAAS,UAAU,EAAE,EACnC,qBAAqB,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,GAC5E,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAU3C;AAED,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,UAAU,EACvB,QAAQ,EAAE,SAAS,UAAU,EAAE,GAC9B,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAO3C;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,UAAU,GACtB,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAU3C;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAE/E;AAmCD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,EAAE,CAUzE"}
@@ -0,0 +1,90 @@
1
+ import { qti3TrustedXmlFragment } from "@longsightgroup/qti3-writer";
2
+ import { escapeText, normalizeIdentifier } from "./text.js";
3
+ import { attr, childElements, findAllDescendantsByAnyLocalName, findAllDescendantsByLocalName, findDescendantByLocalName, isXmlElement, localName, serializeNode, } from "./xml.js";
4
+ export function prompt(interaction) {
5
+ const promptElement = findDescendantByLocalName(interaction, "prompt");
6
+ const html = promptElement ? serializeChildrenReplacing(promptElement, new Map()).trim() : "";
7
+ return html ? trusted(html) : undefined;
8
+ }
9
+ export function bodyWithoutInteraction(body, interaction) {
10
+ return trusted(serializeChildrenReplacing(body, new Map([[interaction, ""]])).trim() || "<p></p>");
11
+ }
12
+ export function bodyWithInlineChoicePlaceholders(body, interactions, responseIdentifierFor) {
13
+ const replacements = new Map();
14
+ for (const [index, interaction] of interactions.entries()) {
15
+ const responseIdentifier = responseIdentifierFor(interaction, `RESPONSE_${index + 1}`);
16
+ replacements.set(interaction, `<qti-inline-choice-interaction response-identifier="${escapeText(responseIdentifier)}"/>`);
17
+ }
18
+ return trusted(serializeChildrenReplacing(body, replacements));
19
+ }
20
+ export function bodyWithTextEntryPlaceholders(body, interactions, responseIdentifierFor) {
21
+ const replacements = new Map();
22
+ for (const [index, interaction] of interactions.entries()) {
23
+ const responseIdentifier = responseIdentifierFor(interaction, `RESPONSE_${index + 1}`);
24
+ replacements.set(interaction, `<qti-text-entry-interaction response-identifier="${escapeText(responseIdentifier)}"/>`);
25
+ }
26
+ return trusted(serializeChildrenReplacing(body, replacements));
27
+ }
28
+ export function bodyWithHottextPlaceholders(interaction, hottexts) {
29
+ const replacements = new Map();
30
+ for (const [index, hottext] of hottexts.entries()) {
31
+ const identifier = normalizeIdentifier(attr(hottext, "identifier"), `H${index + 1}`);
32
+ replacements.set(hottext, `<qti-hottext identifier="${escapeText(identifier)}"/>`);
33
+ }
34
+ return trusted(serializeChildrenReplacing(interaction, replacements) || "<p></p>");
35
+ }
36
+ export function bodyWithGapPlaceholders(interaction) {
37
+ const replacements = new Map();
38
+ for (const choice of findAllDescendantsByAnyLocalName(interaction, ["gaptext", "gapimg"])) {
39
+ replacements.set(choice, "");
40
+ }
41
+ for (const gap of findAllDescendantsByLocalName(interaction, "gap")) {
42
+ const identifier = normalizeIdentifier(attr(gap, "identifier"), "GAP");
43
+ replacements.set(gap, `<qti-gap identifier="${escapeText(identifier)}"/>`);
44
+ }
45
+ return trusted(serializeChildrenReplacing(interaction, replacements) || "<p></p>");
46
+ }
47
+ export function trusted(html) {
48
+ return qti3TrustedXmlFragment(html.trim() || "<p></p>");
49
+ }
50
+ function serializeChildrenReplacing(element, replacements) {
51
+ let out = "";
52
+ for (let index = 0; index < element.childNodes.length; index += 1) {
53
+ out += serializeReplacing(element.childNodes.item(index), replacements);
54
+ }
55
+ return out;
56
+ }
57
+ function serializeReplacing(node, replacements) {
58
+ if (!isXmlElement(node))
59
+ return serializeNode(node);
60
+ const element = node;
61
+ const replacement = replacements.get(element);
62
+ if (replacement !== undefined)
63
+ return replacement;
64
+ return `<${element.nodeName}${attributesXml(element)}>${serializeChildrenReplacing(element, replacements)}</${element.nodeName}>`;
65
+ }
66
+ function attributesXml(element) {
67
+ const attrs = [];
68
+ for (let index = 0; index < element.attributes.length; index += 1) {
69
+ const attribute = element.attributes.item(index);
70
+ if (!attribute)
71
+ continue;
72
+ if (attribute.name === "xmlns" || attribute.name.startsWith("xmlns:"))
73
+ continue;
74
+ attrs.push(`${attribute.name}="${escapeText(attribute.value)}"`);
75
+ }
76
+ return attrs.length ? ` ${attrs.join(" ")}` : "";
77
+ }
78
+ export function collectInteractionElements(root) {
79
+ const out = [];
80
+ const walk = (element) => {
81
+ for (const child of childElements(element)) {
82
+ if (localName(child).endsWith("interaction"))
83
+ out.push(child);
84
+ walk(child);
85
+ }
86
+ };
87
+ walk(root);
88
+ return out;
89
+ }
90
+ //# sourceMappingURL=qti2-body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qti2-body.js","sourceRoot":"","sources":["../src/qti2-body.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type Qti3AssociateChoice, type Qti3AuthoringChoice, type Qti3GapMatchChoice, type Qti3GraphicGapChoice, type Qti3MatchChoice } from "@longsightgroup/qti3-writer";
2
+ import { type XmlElement } from "./xml.js";
3
+ export declare function simpleChoices(root: XmlElement): Qti3AuthoringChoice[];
4
+ export declare function associableChoices(root: XmlElement | undefined, prefix: string): (Qti3MatchChoice | Qti3AssociateChoice)[];
5
+ export declare function gapChoice(choice: XmlElement, index: number): Qti3GapMatchChoice;
6
+ export declare function graphicGapChoice(choice: XmlElement, index: number): Qti3GraphicGapChoice;
7
+ //# sourceMappingURL=qti2-choices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qti2-choices.d.ts","sourceRoot":"","sources":["../src/qti2-choices.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAQL,KAAK,UAAU,EAChB,MAAM,UAAU,CAAC;AAElB,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,mBAAmB,EAAE,CAOrE;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GACb,CAAC,eAAe,GAAG,mBAAmB,CAAC,EAAE,CAS3C;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAuB/E;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAuBxF"}
@@ -0,0 +1,74 @@
1
+ import { qti3TrustedXmlFragment, } from "@longsightgroup/qti3-writer";
2
+ import { normalizeIdentifier } from "./text.js";
3
+ import { attr, findAllDescendantsByLocalName, findDescendantByLocalName, localName, serializeChildren, textOf, toNumber, } from "./xml.js";
4
+ export function simpleChoices(root) {
5
+ return findAllDescendantsByLocalName(root, "simplechoice").map((choice, index) => ({
6
+ identifier: normalizeIdentifier(attr(choice, "identifier"), `CHOICE_${index + 1}`),
7
+ contentHtml: trusted(serializeChildren(choice)),
8
+ text: textOf(choice) || undefined,
9
+ fixed: attr(choice, "fixed") === "true",
10
+ }));
11
+ }
12
+ export function associableChoices(root, prefix) {
13
+ if (!root)
14
+ return [];
15
+ return findAllDescendantsByLocalName(root, "simpleassociablechoice").map((choice, index) => ({
16
+ identifier: normalizeIdentifier(attr(choice, "identifier"), `${prefix}_${index + 1}`),
17
+ contentHtml: trusted(serializeChildren(choice)),
18
+ text: textOf(choice) || undefined,
19
+ fixed: attr(choice, "fixed") === "true",
20
+ matchMax: toNumber(attr(choice, "matchMax")),
21
+ }));
22
+ }
23
+ export function gapChoice(choice, index) {
24
+ if (localName(choice) === "gapimg") {
25
+ const object = findDescendantByLocalName(choice, "object");
26
+ return {
27
+ identifier: normalizeIdentifier(attr(choice, "identifier"), `G${index + 1}`),
28
+ kind: "image",
29
+ object: {
30
+ data: attr(object, "data") ?? "",
31
+ alt: attr(object, "alt") ?? attr(object, "label") ?? "Image",
32
+ type: attr(object, "type") ?? undefined,
33
+ },
34
+ matchMax: toNumber(attr(choice, "matchMax")),
35
+ fixed: attr(choice, "fixed") === "true",
36
+ };
37
+ }
38
+ return {
39
+ identifier: normalizeIdentifier(attr(choice, "identifier"), `G${index + 1}`),
40
+ kind: "text",
41
+ contentHtml: trusted(serializeChildren(choice)),
42
+ text: textOf(choice) || undefined,
43
+ matchMax: toNumber(attr(choice, "matchMax")),
44
+ fixed: attr(choice, "fixed") === "true",
45
+ };
46
+ }
47
+ export function graphicGapChoice(choice, index) {
48
+ if (localName(choice) === "gapimg") {
49
+ const object = findDescendantByLocalName(choice, "object");
50
+ return {
51
+ identifier: normalizeIdentifier(attr(choice, "identifier"), `G${index + 1}`),
52
+ kind: "image",
53
+ object: {
54
+ data: attr(object, "data") ?? "",
55
+ alt: attr(object, "alt") ?? attr(object, "label") ?? "Image",
56
+ type: attr(object, "type") ?? undefined,
57
+ },
58
+ matchMax: toNumber(attr(choice, "matchMax")),
59
+ fixed: attr(choice, "fixed") === "true",
60
+ };
61
+ }
62
+ return {
63
+ identifier: normalizeIdentifier(attr(choice, "identifier"), `G${index + 1}`),
64
+ kind: "text",
65
+ contentHtml: trusted(serializeChildren(choice)),
66
+ text: textOf(choice) || undefined,
67
+ matchMax: toNumber(attr(choice, "matchMax")),
68
+ fixed: attr(choice, "fixed") === "true",
69
+ };
70
+ }
71
+ function trusted(html) {
72
+ return qti3TrustedXmlFragment(html.trim() || "<p></p>");
73
+ }
74
+ //# sourceMappingURL=qti2-choices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qti2-choices.js","sourceRoot":"","sources":["../src/qti2-choices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { type XmlElement } from "./xml.js";
2
+ export declare function graphicObject(object: XmlElement | null, coords: readonly string[]): {
3
+ data: string;
4
+ alt: string;
5
+ type: string | undefined;
6
+ width: number;
7
+ height: number;
8
+ };
9
+ export declare function hotspotShape(value: string | null): "circle" | "rect" | "poly";
10
+ //# sourceMappingURL=qti2-graphic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qti2-graphic.d.ts","sourceRoot":"","sources":["../src/qti2-graphic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3D,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE;;;;;;EASjF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAE7E"}