@superbuilders/incept-renderer 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,202 +1,14 @@
1
1
  import { createHash } from 'crypto';
2
- import 'react';
3
- import 'clsx';
4
- import 'tailwind-merge';
5
- import 'react-dom';
6
- import 'react/jsx-runtime';
7
- import '@radix-ui/react-radio-group';
8
- import '@radix-ui/react-checkbox';
9
- import 'class-variance-authority';
10
- import '@radix-ui/react-label';
11
- import '@radix-ui/react-separator';
12
- import 'lucide-react';
13
- import '@dnd-kit/core';
14
- import '@radix-ui/react-select';
15
- import '@dnd-kit/sortable';
16
- import '@dnd-kit/utilities';
2
+ import * as errors from '@superbuilders/errors';
3
+ import * as logger2 from '@superbuilders/slog';
17
4
  import { XMLParser } from 'fast-xml-parser';
18
- import { z as z$1 } from 'zod';
5
+ import { z } from 'zod';
19
6
 
20
7
  // ../../../../../node_modules/server-only/index.js
21
8
  throw new Error(
22
9
  "This module cannot be imported from a Client Component module. It should only be used from a Server Component."
23
10
  );
24
11
 
25
- // ../../node_modules/@superbuilders/errors/dist/index.js
26
- function z() {
27
- let k2 = [], j2 = this;
28
- while (j2 != null) if (k2.push(j2.message), j2.cause instanceof Error) j2 = j2.cause;
29
- else break;
30
- return k2.join(": ");
31
- }
32
- function A(k2) {
33
- let j2 = new Error(k2);
34
- if (Error.captureStackTrace) Error.captureStackTrace(j2, A);
35
- return j2.toString = z, Object.freeze(j2);
36
- }
37
- function B(k2, j2) {
38
- let x = new Error(j2, { cause: k2 });
39
- if (Error.captureStackTrace) Error.captureStackTrace(x, B);
40
- return x.toString = z, Object.freeze(x);
41
- }
42
- function I(k2) {
43
- try {
44
- return { data: k2(), error: void 0 };
45
- } catch (j2) {
46
- return { data: void 0, error: j2 instanceof Error ? j2 : new Error(String(j2)) };
47
- }
48
- }
49
-
50
- // ../../node_modules/@superbuilders/slog/dist/index.js
51
- var b = new ArrayBuffer(8192);
52
- var K = new Uint8Array(b);
53
- var Q = new TextEncoder();
54
- var C = new ArrayBuffer(64);
55
- var L = new Uint8Array(C);
56
- var J = { DEBUG: Q.encode(" DEBUG "), INFO: Q.encode(" INFO "), WARN: Q.encode(" WARN "), ERROR: Q.encode(" ERROR "), NEWLINE: Q.encode(`
57
- `), SPACE: Q.encode(" "), EQUALS: Q.encode("="), SLASH: Q.encode("/"), COLON: Q.encode(":"), NULL: Q.encode("null"), UNDEFINED: Q.encode("undefined"), TRUE: Q.encode("true"), FALSE: Q.encode("false"), QUOTE: Q.encode('"'), BRACKET_OPEN: Q.encode("["), BRACKET_CLOSE: Q.encode("]"), BRACE_OPEN: Q.encode("{"), BRACE_CLOSE: Q.encode("}"), COMMA: Q.encode(","), ZERO: Q.encode("0"), MINUS: Q.encode("-"), DOT: Q.encode(".") };
58
- var U = new Uint8Array(19);
59
- var z2 = new Uint8Array(2);
60
- var V = 0;
61
- var F = 0;
62
- var W = 0;
63
- function j() {
64
- let x = Date.now();
65
- if (x - V >= 1e3) {
66
- let q = new Date(x), D = 0, R = q.getFullYear();
67
- U[D++] = 48 + Math.floor(R / 1e3) % 10, U[D++] = 48 + Math.floor(R / 100) % 10, U[D++] = 48 + Math.floor(R / 10) % 10, U[D++] = 48 + R % 10, U[D++] = 47;
68
- let N = q.getMonth() + 1;
69
- U[D++] = 48 + Math.floor(N / 10), U[D++] = 48 + N % 10, U[D++] = 47;
70
- let P = q.getDate();
71
- U[D++] = 48 + Math.floor(P / 10), U[D++] = 48 + P % 10, U[D++] = 32;
72
- let M = q.getHours();
73
- U[D++] = 48 + Math.floor(M / 10), U[D++] = 48 + M % 10, U[D++] = 58;
74
- let Z = q.getMinutes();
75
- U[D++] = 48 + Math.floor(Z / 10), U[D++] = 48 + Z % 10, U[D++] = 58, F = D;
76
- let X = q.getSeconds();
77
- z2[0] = 48 + Math.floor(X / 10), z2[1] = 48 + X % 10, W = 2, V = x;
78
- }
79
- }
80
- var k = 0;
81
- function H(x, G, q) {
82
- let D = 8192 - G;
83
- if (D <= 0) return G;
84
- let R = Math.min(q.length, D);
85
- return x.set(q.subarray(0, R), G), G + R;
86
- }
87
- function $(x, G, q) {
88
- let D = 8192 - G;
89
- if (D <= 0) return G;
90
- let R = true, N = q.length;
91
- for (let M = 0; M < N; M++) if (q.charCodeAt(M) > 127) {
92
- R = false;
93
- break;
94
- }
95
- if (R) {
96
- let M = Math.min(N, D);
97
- for (let Z = 0; Z < M; Z++) x[G + Z] = q.charCodeAt(Z);
98
- return G + M;
99
- }
100
- let P = Q.encodeInto(q, x.subarray(G));
101
- return G + (P.written ?? 0);
102
- }
103
- function A2(x, G, q) {
104
- if (Number.isNaN(q)) return $(x, G, "NaN");
105
- if (q === Number.POSITIVE_INFINITY) return $(x, G, "Infinity");
106
- if (q === Number.NEGATIVE_INFINITY) return $(x, G, "-Infinity");
107
- let D = G, R = q;
108
- if (R < 0) D = H(x, D, J.MINUS), R = -R;
109
- if (R === 0) return H(x, D, J.ZERO);
110
- if (Number.isInteger(R) && R < Number.MAX_SAFE_INTEGER) {
111
- let M = Math.floor(R), Z = 0, X = M;
112
- while (X > 0) Z++, X = Math.floor(X / 10);
113
- if (D + Z > x.length) return D;
114
- let Y = D + Z - 1;
115
- while (M > 0) x[Y--] = 48 + M % 10, M = Math.floor(M / 10);
116
- return D + Z;
117
- }
118
- let N = Q.encodeInto(R.toString(), L), P = Math.min(N.written ?? 0, x.length - G);
119
- if (P > 0) x.set(L.subarray(0, P), G);
120
- return G + P;
121
- }
122
- function _(x, G, q) {
123
- if (q === null) return H(x, G, J.NULL);
124
- if (q === void 0) return H(x, G, J.UNDEFINED);
125
- switch (typeof q) {
126
- case "string":
127
- return $(x, G, q);
128
- case "number":
129
- return A2(x, G, q);
130
- case "boolean":
131
- return H(x, G, q ? J.TRUE : J.FALSE);
132
- case "bigint":
133
- return $(x, G, `${q}`);
134
- case "symbol":
135
- return $(x, G, String(q));
136
- case "function":
137
- return $(x, G, `${q}`);
138
- case "object": {
139
- if (Array.isArray(q)) {
140
- let X = H(x, G, J.BRACKET_OPEN), Y = q.length;
141
- for (let O = 0; O < Y; O++) {
142
- if (O > 0) X = H(x, X, J.COMMA);
143
- X = _(x, X, q[O]);
144
- }
145
- return H(x, X, J.BRACKET_CLOSE);
146
- }
147
- let N = q.toString;
148
- if (typeof N === "function" && N !== Object.prototype.toString) return $(x, G, N.call(q));
149
- let P = q, M = H(x, G, J.BRACE_OPEN), Z = true;
150
- for (let X in P) if (Object.hasOwn(P, X)) {
151
- if (Z === false) M = H(x, M, J.COMMA);
152
- M = H(x, M, J.QUOTE), M = $(x, M, X), M = H(x, M, J.QUOTE), M = H(x, M, J.COLON), M = _(x, M, P[X]), Z = false;
153
- }
154
- return H(x, M, J.BRACE_CLOSE);
155
- }
156
- default:
157
- return $(x, G, `${q}`);
158
- }
159
- }
160
- function E(x, G, q) {
161
- if (!q) return G;
162
- let D = G, R = true;
163
- for (let N in q) {
164
- if (!R) D = H(x, D, J.SPACE);
165
- D = $(x, D, N), D = H(x, D, J.EQUALS), D = _(x, D, q[N]), R = false;
166
- }
167
- return D;
168
- }
169
- function I2(x) {
170
- let G = K.subarray(0, x);
171
- process.stderr.write(G);
172
- }
173
- function y(x, G) {
174
- if (-4 < k) return;
175
- j();
176
- let q = 0;
177
- if (q = H(K, q, U.subarray(0, F)), q = H(K, q, z2.subarray(0, W)), q = H(K, q, J.DEBUG), q = $(K, q, x), G) q = H(K, q, J.SPACE), q = E(K, q, G);
178
- if (q < 8192) q = H(K, q, J.NEWLINE);
179
- else {
180
- let D = J.NEWLINE[0];
181
- if (D !== void 0) K[8191] = D;
182
- q = 8192;
183
- }
184
- I2(q);
185
- }
186
- function l(x, G) {
187
- if (8 < k) return;
188
- j();
189
- let q = 0;
190
- if (q = H(K, q, U.subarray(0, F)), q = H(K, q, z2.subarray(0, W)), q = H(K, q, J.ERROR), q = $(K, q, x), G) q = H(K, q, J.SPACE), q = E(K, q, G);
191
- if (q < 8192) q = H(K, q, J.NEWLINE);
192
- else {
193
- let D = J.NEWLINE[0];
194
- if (D !== void 0) K[8191] = D;
195
- q = 8192;
196
- }
197
- I2(q);
198
- }
199
-
200
12
  // src/html/sanitize.ts
201
13
  var DEFAULT_CONFIG = {
202
14
  // HTML content tags
@@ -525,101 +337,101 @@ function serializeVerbatim(node) {
525
337
  }).join("");
526
338
  return `<${node.tagName}${attrs}>${inner}</${node.tagName}>`;
527
339
  }
528
- var QtiCardinalitySchema = z$1.enum(["single", "multiple", "ordered"]);
529
- var QtiBaseTypeSchema = z$1.enum(["identifier", "string", "float", "integer", "boolean", "directedPair", "pair"]);
530
- var SimpleChoiceSchema = z$1.object({
531
- identifier: z$1.string().min(1),
532
- contentHtml: z$1.string(),
340
+ var QtiCardinalitySchema = z.enum(["single", "multiple", "ordered"]);
341
+ var QtiBaseTypeSchema = z.enum(["identifier", "string", "float", "integer", "boolean", "directedPair", "pair"]);
342
+ var SimpleChoiceSchema = z.object({
343
+ identifier: z.string().min(1),
344
+ contentHtml: z.string(),
533
345
  // Allows "" for empty or image-only content
534
- inlineFeedbackHtml: z$1.string().optional()
346
+ inlineFeedbackHtml: z.string().optional()
535
347
  // Optional per-choice feedback (qti-feedback-inline)
536
348
  });
537
- var InlineChoiceSchema = z$1.object({
538
- identifier: z$1.string().min(1),
539
- contentHtml: z$1.string()
349
+ var InlineChoiceSchema = z.object({
350
+ identifier: z.string().min(1),
351
+ contentHtml: z.string()
540
352
  });
541
- var ChoiceInteractionCoreSchema = z$1.object({
542
- responseIdentifier: z$1.string().min(1),
543
- shuffle: z$1.boolean(),
544
- minChoices: z$1.number().int().min(0),
545
- maxChoices: z$1.number().int().min(1),
546
- promptHtml: z$1.string(),
547
- choices: z$1.array(SimpleChoiceSchema).min(1)
353
+ var ChoiceInteractionCoreSchema = z.object({
354
+ responseIdentifier: z.string().min(1),
355
+ shuffle: z.boolean(),
356
+ minChoices: z.number().int().min(0),
357
+ maxChoices: z.number().int().min(1),
358
+ promptHtml: z.string(),
359
+ choices: z.array(SimpleChoiceSchema).min(1)
548
360
  });
549
- var ChoiceInteractionSchema = ChoiceInteractionCoreSchema.extend({ type: z$1.literal("choiceInteraction") });
550
- var InlineChoiceInteractionCoreSchema = z$1.object({
551
- responseIdentifier: z$1.string().min(1),
552
- shuffle: z$1.boolean(),
553
- choices: z$1.array(InlineChoiceSchema).min(1)
361
+ var ChoiceInteractionSchema = ChoiceInteractionCoreSchema.extend({ type: z.literal("choiceInteraction") });
362
+ var InlineChoiceInteractionCoreSchema = z.object({
363
+ responseIdentifier: z.string().min(1),
364
+ shuffle: z.boolean(),
365
+ choices: z.array(InlineChoiceSchema).min(1)
554
366
  });
555
367
  var InlineChoiceInteractionSchema = InlineChoiceInteractionCoreSchema.extend({
556
- type: z$1.literal("inlineChoiceInteraction")
368
+ type: z.literal("inlineChoiceInteraction")
557
369
  });
558
- var TextEntryInteractionCoreSchema = z$1.object({
559
- responseIdentifier: z$1.string().min(1),
560
- expectedLength: z$1.number().int().min(0).optional(),
561
- placeholderText: z$1.string().optional(),
562
- patternMask: z$1.string().optional()
370
+ var TextEntryInteractionCoreSchema = z.object({
371
+ responseIdentifier: z.string().min(1),
372
+ expectedLength: z.number().int().min(0).optional(),
373
+ placeholderText: z.string().optional(),
374
+ patternMask: z.string().optional()
563
375
  });
564
376
  var TextEntryInteractionSchema = TextEntryInteractionCoreSchema.extend({
565
- type: z$1.literal("textEntryInteraction")
377
+ type: z.literal("textEntryInteraction")
566
378
  });
567
- var OrderInteractionCoreSchema = z$1.object({
568
- responseIdentifier: z$1.string().min(1),
569
- shuffle: z$1.boolean(),
570
- minChoices: z$1.number().int().min(0),
571
- maxChoices: z$1.number().int().min(0).optional(),
379
+ var OrderInteractionCoreSchema = z.object({
380
+ responseIdentifier: z.string().min(1),
381
+ shuffle: z.boolean(),
382
+ minChoices: z.number().int().min(0),
383
+ maxChoices: z.number().int().min(0).optional(),
572
384
  // 0 or undefined usually means "all"
573
- orientation: z$1.enum(["vertical", "horizontal"]),
574
- promptHtml: z$1.string(),
575
- choices: z$1.array(SimpleChoiceSchema).min(1)
385
+ orientation: z.enum(["vertical", "horizontal"]),
386
+ promptHtml: z.string(),
387
+ choices: z.array(SimpleChoiceSchema).min(1)
576
388
  });
577
389
  var OrderInteractionSchema = OrderInteractionCoreSchema.extend({
578
- type: z$1.literal("orderInteraction")
390
+ type: z.literal("orderInteraction")
579
391
  });
580
- var GapTextSchema = z$1.object({
581
- identifier: z$1.string().min(1),
582
- contentHtml: z$1.string(),
583
- matchMax: z$1.number().int().min(0)
392
+ var GapTextSchema = z.object({
393
+ identifier: z.string().min(1),
394
+ contentHtml: z.string(),
395
+ matchMax: z.number().int().min(0)
584
396
  // 0 = unlimited
585
397
  });
586
- var GapSchema = z$1.object({
587
- identifier: z$1.string().min(1)
398
+ var GapSchema = z.object({
399
+ identifier: z.string().min(1)
588
400
  });
589
- var GapMatchInteractionCoreSchema = z$1.object({
590
- responseIdentifier: z$1.string().min(1),
591
- shuffle: z$1.boolean(),
592
- gapTexts: z$1.array(GapTextSchema).min(1),
401
+ var GapMatchInteractionCoreSchema = z.object({
402
+ responseIdentifier: z.string().min(1),
403
+ shuffle: z.boolean(),
404
+ gapTexts: z.array(GapTextSchema).min(1),
593
405
  // Draggable source tokens
594
- gaps: z$1.array(GapSchema).min(1),
406
+ gaps: z.array(GapSchema).min(1),
595
407
  // Drop target placeholders
596
- contentHtml: z$1.string()
408
+ contentHtml: z.string()
597
409
  // HTML content with gap placeholders
598
410
  });
599
411
  var GapMatchInteractionSchema = GapMatchInteractionCoreSchema.extend({
600
- type: z$1.literal("gapMatchInteraction")
412
+ type: z.literal("gapMatchInteraction")
601
413
  });
602
- var AssociableChoiceSchema = z$1.object({
603
- identifier: z$1.string().min(1),
604
- matchMax: z$1.number().int().min(0),
414
+ var AssociableChoiceSchema = z.object({
415
+ identifier: z.string().min(1),
416
+ matchMax: z.number().int().min(0),
605
417
  // 0 = unlimited uses
606
- contentHtml: z$1.string()
418
+ contentHtml: z.string()
607
419
  });
608
- var MatchInteractionCoreSchema = z$1.object({
609
- responseIdentifier: z$1.string().min(1),
610
- shuffle: z$1.boolean(),
611
- maxAssociations: z$1.number().int().min(0),
420
+ var MatchInteractionCoreSchema = z.object({
421
+ responseIdentifier: z.string().min(1),
422
+ shuffle: z.boolean(),
423
+ maxAssociations: z.number().int().min(0),
612
424
  // 0 = unlimited total associations
613
- sourceChoices: z$1.array(AssociableChoiceSchema).min(1),
425
+ sourceChoices: z.array(AssociableChoiceSchema).min(1),
614
426
  // First <qti-simple-match-set>
615
- targetChoices: z$1.array(AssociableChoiceSchema).min(1),
427
+ targetChoices: z.array(AssociableChoiceSchema).min(1),
616
428
  // Second <qti-simple-match-set>
617
- promptHtml: z$1.string()
429
+ promptHtml: z.string()
618
430
  });
619
431
  var MatchInteractionSchema = MatchInteractionCoreSchema.extend({
620
- type: z$1.literal("matchInteraction")
432
+ type: z.literal("matchInteraction")
621
433
  });
622
- var AnyInteractionSchema = z$1.discriminatedUnion("type", [
434
+ var AnyInteractionSchema = z.discriminatedUnion("type", [
623
435
  ChoiceInteractionSchema,
624
436
  InlineChoiceInteractionSchema,
625
437
  TextEntryInteractionSchema,
@@ -627,149 +439,149 @@ var AnyInteractionSchema = z$1.discriminatedUnion("type", [
627
439
  GapMatchInteractionSchema,
628
440
  MatchInteractionSchema
629
441
  ]);
630
- var CorrectResponseSchema = z$1.object({
631
- values: z$1.array(z$1.string().min(1)).min(1)
442
+ var CorrectResponseSchema = z.object({
443
+ values: z.array(z.string().min(1)).min(1)
632
444
  });
633
- var ResponseDeclarationSchema = z$1.object({
634
- identifier: z$1.string().min(1),
445
+ var ResponseDeclarationSchema = z.object({
446
+ identifier: z.string().min(1),
635
447
  cardinality: QtiCardinalitySchema,
636
448
  baseType: QtiBaseTypeSchema,
637
449
  correctResponse: CorrectResponseSchema,
638
450
  // Optional response mapping for map-response processing (used for summed feedback/score)
639
- mapping: z$1.object({
640
- defaultValue: z$1.number().default(0),
641
- lowerBound: z$1.number().optional(),
642
- upperBound: z$1.number().optional(),
643
- entries: z$1.array(
644
- z$1.object({
645
- key: z$1.string().min(1),
646
- value: z$1.number()
451
+ mapping: z.object({
452
+ defaultValue: z.number().default(0),
453
+ lowerBound: z.number().optional(),
454
+ upperBound: z.number().optional(),
455
+ entries: z.array(
456
+ z.object({
457
+ key: z.string().min(1),
458
+ value: z.number()
647
459
  })
648
460
  )
649
461
  }).optional()
650
462
  });
651
- var OutcomeDefaultValueSchema = z$1.object({
652
- value: z$1.string()
463
+ var OutcomeDefaultValueSchema = z.object({
464
+ value: z.string()
653
465
  });
654
- var OutcomeDeclarationSchema = z$1.object({
655
- identifier: z$1.string().min(1),
466
+ var OutcomeDeclarationSchema = z.object({
467
+ identifier: z.string().min(1),
656
468
  cardinality: QtiCardinalitySchema,
657
469
  baseType: QtiBaseTypeSchema,
658
470
  defaultValue: OutcomeDefaultValueSchema.optional()
659
471
  });
660
- var FeedbackBlockSchema = z$1.object({
661
- outcomeIdentifier: z$1.string().min(1),
662
- identifier: z$1.string().min(1),
663
- showHide: z$1.enum(["show", "hide"]).default("show"),
664
- contentHtml: z$1.string()
472
+ var FeedbackBlockSchema = z.object({
473
+ outcomeIdentifier: z.string().min(1),
474
+ identifier: z.string().min(1),
475
+ showHide: z.enum(["show", "hide"]).default("show"),
476
+ contentHtml: z.string()
665
477
  });
666
- var StimulusBlockSchema = z$1.object({
667
- type: z$1.literal("stimulus"),
668
- html: z$1.string()
478
+ var StimulusBlockSchema = z.object({
479
+ type: z.literal("stimulus"),
480
+ html: z.string()
669
481
  });
670
- var RichStimulusBlockSchema = z$1.object({
671
- type: z$1.literal("richStimulus"),
672
- html: z$1.string(),
673
- inlineEmbeds: z$1.record(z$1.string(), InlineChoiceInteractionSchema),
674
- textEmbeds: z$1.record(z$1.string(), TextEntryInteractionSchema)
482
+ var RichStimulusBlockSchema = z.object({
483
+ type: z.literal("richStimulus"),
484
+ html: z.string(),
485
+ inlineEmbeds: z.record(z.string(), InlineChoiceInteractionSchema),
486
+ textEmbeds: z.record(z.string(), TextEntryInteractionSchema)
675
487
  });
676
- var InteractionBlockSchema = z$1.object({
677
- type: z$1.literal("interaction"),
488
+ var InteractionBlockSchema = z.object({
489
+ type: z.literal("interaction"),
678
490
  interaction: AnyInteractionSchema
679
491
  });
680
- var ItemBodySchema = z$1.object({
681
- contentBlocks: z$1.array(z$1.union([StimulusBlockSchema, RichStimulusBlockSchema, InteractionBlockSchema])).min(1),
682
- feedbackBlocks: z$1.array(FeedbackBlockSchema)
492
+ var ItemBodySchema = z.object({
493
+ contentBlocks: z.array(z.union([StimulusBlockSchema, RichStimulusBlockSchema, InteractionBlockSchema])).min(1),
494
+ feedbackBlocks: z.array(FeedbackBlockSchema)
683
495
  });
684
- var BaseRuleSchema = z$1.object({
685
- type: z$1.literal("setOutcomeValue"),
686
- identifier: z$1.string(),
687
- value: z$1.string()
496
+ var BaseRuleSchema = z.object({
497
+ type: z.literal("setOutcomeValue"),
498
+ identifier: z.string(),
499
+ value: z.string()
688
500
  });
689
- var MatchConditionSchema = z$1.object({
690
- type: z$1.literal("match"),
691
- variable: z$1.string(),
692
- correct: z$1.literal(true)
501
+ var MatchConditionSchema = z.object({
502
+ type: z.literal("match"),
503
+ variable: z.string(),
504
+ correct: z.literal(true)
693
505
  // Match against correct response
694
506
  });
695
- var MatchValueConditionSchema = z$1.object({
696
- type: z$1.literal("matchValue"),
697
- variable: z$1.string(),
507
+ var MatchValueConditionSchema = z.object({
508
+ type: z.literal("matchValue"),
509
+ variable: z.string(),
698
510
  // The response identifier from <qti-variable>
699
- value: z$1.string()
511
+ value: z.string()
700
512
  // The target value from <qti-base-value>
701
513
  });
702
- var StringMatchConditionSchema = z$1.object({
703
- type: z$1.literal("stringMatch"),
704
- variable: z$1.string(),
705
- value: z$1.string(),
706
- caseSensitive: z$1.boolean()
514
+ var StringMatchConditionSchema = z.object({
515
+ type: z.literal("stringMatch"),
516
+ variable: z.string(),
517
+ value: z.string(),
518
+ caseSensitive: z.boolean()
707
519
  });
708
- var MemberConditionSchema = z$1.object({
709
- type: z$1.literal("member"),
710
- variable: z$1.string(),
711
- value: z$1.string()
520
+ var MemberConditionSchema = z.object({
521
+ type: z.literal("member"),
522
+ variable: z.string(),
523
+ value: z.string()
712
524
  });
713
- var EqualMapResponseConditionSchema = z$1.object({
714
- type: z$1.literal("equalMapResponse"),
715
- variable: z$1.string(),
525
+ var EqualMapResponseConditionSchema = z.object({
526
+ type: z.literal("equalMapResponse"),
527
+ variable: z.string(),
716
528
  // The response identifier from <qti-map-response>
717
- value: z$1.string()
529
+ value: z.string()
718
530
  // The target sum value from <qti-base-value>
719
531
  });
720
- var AndConditionSchema = z$1.object({
721
- type: z$1.literal("and"),
722
- conditions: z$1.array(z$1.lazy(() => AnyConditionSchema))
532
+ var AndConditionSchema = z.object({
533
+ type: z.literal("and"),
534
+ conditions: z.array(z.lazy(() => AnyConditionSchema))
723
535
  });
724
- var OrConditionSchema = z$1.object({
725
- type: z$1.literal("or"),
726
- conditions: z$1.array(z$1.lazy(() => AnyConditionSchema))
536
+ var OrConditionSchema = z.object({
537
+ type: z.literal("or"),
538
+ conditions: z.array(z.lazy(() => AnyConditionSchema))
727
539
  });
728
- var NotConditionSchema = z$1.object({
729
- type: z$1.literal("not"),
730
- condition: z$1.lazy(() => AnyConditionSchema)
540
+ var NotConditionSchema = z.object({
541
+ type: z.literal("not"),
542
+ condition: z.lazy(() => AnyConditionSchema)
731
543
  });
732
- var AnyConditionSchema = z$1.union([
544
+ var AnyConditionSchema = z.union([
733
545
  MatchConditionSchema,
734
546
  MatchValueConditionSchema,
735
547
  StringMatchConditionSchema,
736
548
  MemberConditionSchema,
737
- z$1.lazy(() => AndConditionSchema),
738
- z$1.lazy(() => OrConditionSchema),
739
- z$1.lazy(() => NotConditionSchema),
549
+ z.lazy(() => AndConditionSchema),
550
+ z.lazy(() => OrConditionSchema),
551
+ z.lazy(() => NotConditionSchema),
740
552
  EqualMapResponseConditionSchema
741
553
  ]);
742
- var ConditionBranchSchema = z$1.object({
554
+ var ConditionBranchSchema = z.object({
743
555
  condition: AnyConditionSchema.optional(),
744
- actions: z$1.array(BaseRuleSchema),
745
- nestedRules: z$1.array(z$1.lazy(() => ResponseRuleSchema)).optional()
556
+ actions: z.array(BaseRuleSchema),
557
+ nestedRules: z.array(z.lazy(() => ResponseRuleSchema)).optional()
746
558
  });
747
- var ResponseRuleSchema = z$1.union([
748
- z$1.object({
749
- type: z$1.literal("condition"),
750
- branches: z$1.array(ConditionBranchSchema)
559
+ var ResponseRuleSchema = z.union([
560
+ z.object({
561
+ type: z.literal("condition"),
562
+ branches: z.array(ConditionBranchSchema)
751
563
  }),
752
- z$1.object({
753
- type: z$1.literal("action"),
564
+ z.object({
565
+ type: z.literal("action"),
754
566
  action: BaseRuleSchema
755
567
  })
756
568
  ]);
757
- var ScoringRuleSchema = z$1.object({
758
- responseIdentifier: z$1.string().min(1),
759
- correctScore: z$1.number(),
760
- incorrectScore: z$1.number()
569
+ var ScoringRuleSchema = z.object({
570
+ responseIdentifier: z.string().min(1),
571
+ correctScore: z.number(),
572
+ incorrectScore: z.number()
761
573
  });
762
- var ResponseProcessingSchema = z$1.object({
763
- rules: z$1.array(ResponseRuleSchema),
574
+ var ResponseProcessingSchema = z.object({
575
+ rules: z.array(ResponseRuleSchema),
764
576
  scoring: ScoringRuleSchema
765
577
  });
766
- var AssessmentItemSchema = z$1.object({
767
- identifier: z$1.string().min(1),
768
- title: z$1.string().min(1),
769
- timeDependent: z$1.boolean(),
770
- xmlLang: z$1.string().min(1),
771
- responseDeclarations: z$1.array(ResponseDeclarationSchema).min(1),
772
- outcomeDeclarations: z$1.array(OutcomeDeclarationSchema).min(1),
578
+ var AssessmentItemSchema = z.object({
579
+ identifier: z.string().min(1),
580
+ title: z.string().min(1),
581
+ timeDependent: z.boolean(),
582
+ xmlLang: z.string().min(1),
583
+ responseDeclarations: z.array(ResponseDeclarationSchema).min(1),
584
+ outcomeDeclarations: z.array(OutcomeDeclarationSchema).min(1),
773
585
  itemBody: ItemBodySchema,
774
586
  responseProcessing: ResponseProcessingSchema
775
587
  });
@@ -801,7 +613,7 @@ function normalizeNode(rawNode) {
801
613
  if (textContent != null) {
802
614
  return coerceString(textContent);
803
615
  }
804
- const tagName = Object.keys(rawNode).find((k2) => k2 !== ":@");
616
+ const tagName = Object.keys(rawNode).find((k) => k !== ":@");
805
617
  if (!tagName) return "";
806
618
  const attrsValue = rawNode[":@"];
807
619
  const attrs = isRecord(attrsValue) ? attrsValue : {};
@@ -1059,12 +871,12 @@ function extractResponseDeclarations(rootChildren) {
1059
871
  const cardinalityRaw = coerceString(node.attrs.cardinality);
1060
872
  const cardinalityResult = QtiCardinalitySchema.safeParse(cardinalityRaw);
1061
873
  if (!cardinalityResult.success) {
1062
- throw A(`invalid cardinality '${cardinalityRaw}' in response declaration`);
874
+ throw errors.new(`invalid cardinality '${cardinalityRaw}' in response declaration`);
1063
875
  }
1064
876
  const baseTypeRaw = coerceString(node.attrs["base-type"]);
1065
877
  const baseTypeResult = QtiBaseTypeSchema.safeParse(baseTypeRaw);
1066
878
  if (!baseTypeResult.success) {
1067
- throw A(`invalid base-type '${baseTypeRaw}' in response declaration`);
879
+ throw errors.new(`invalid base-type '${baseTypeRaw}' in response declaration`);
1068
880
  }
1069
881
  return {
1070
882
  identifier: coerceString(node.attrs.identifier),
@@ -1084,12 +896,12 @@ function extractOutcomeDeclarations(rootChildren) {
1084
896
  const cardinalityRaw = coerceString(node.attrs.cardinality);
1085
897
  const cardinalityResult = QtiCardinalitySchema.safeParse(cardinalityRaw);
1086
898
  if (!cardinalityResult.success) {
1087
- throw A(`invalid cardinality '${cardinalityRaw}' in outcome declaration`);
899
+ throw errors.new(`invalid cardinality '${cardinalityRaw}' in outcome declaration`);
1088
900
  }
1089
901
  const baseTypeRaw = coerceString(node.attrs["base-type"]);
1090
902
  const baseTypeResult = QtiBaseTypeSchema.safeParse(baseTypeRaw);
1091
903
  if (!baseTypeResult.success) {
1092
- throw A(`invalid base-type '${baseTypeRaw}' in outcome declaration`);
904
+ throw errors.new(`invalid base-type '${baseTypeRaw}' in outcome declaration`);
1093
905
  }
1094
906
  return {
1095
907
  identifier: coerceString(node.attrs.identifier),
@@ -1306,23 +1118,23 @@ function extractResponseProcessing(rootChildren) {
1306
1118
  }
1307
1119
  function parseAssessmentItemXml(xml) {
1308
1120
  if (!xml || typeof xml !== "string") {
1309
- throw A("xml input must be a non-empty string");
1121
+ throw errors.new("xml input must be a non-empty string");
1310
1122
  }
1311
1123
  const parser = createXmlParser();
1312
- const parseResult = I(() => {
1124
+ const parseResult = errors.trySync(() => {
1313
1125
  return parser.parse(xml, true);
1314
1126
  });
1315
1127
  if (parseResult.error) {
1316
- throw B(parseResult.error, "xml parse");
1128
+ throw errors.wrap(parseResult.error, "xml parse");
1317
1129
  }
1318
1130
  const raw = parseResult.data;
1319
1131
  if (!Array.isArray(raw)) {
1320
- throw A("expected xml parser to output an array for preserveOrder");
1132
+ throw errors.new("expected xml parser to output an array for preserveOrder");
1321
1133
  }
1322
1134
  const normalizedTree = raw.map(normalizeNode).filter((n) => typeof n !== "string");
1323
1135
  const rootNode = normalizedTree.find((n) => n.tagName.endsWith("assessment-item"));
1324
1136
  if (!rootNode) {
1325
- throw A("qti assessment item not found in xml document");
1137
+ throw errors.new("qti assessment item not found in xml document");
1326
1138
  }
1327
1139
  const rootChildren = rootNode.children.filter((c) => typeof c !== "string");
1328
1140
  const itemBodyNode = rootChildren.find((n) => n.tagName === "qti-item-body");
@@ -1394,204 +1206,32 @@ function parseAssessmentItemXml(xml) {
1394
1206
  const validation = AssessmentItemSchema.safeParse(normalizedItem);
1395
1207
  if (!validation.success) {
1396
1208
  const errorDetails = validation.error.issues.map((err) => `${err.path.join(".")}: ${err.message}`).join("; ");
1397
- throw A(`qti item validation: ${errorDetails}`);
1209
+ throw errors.new(`qti item validation: ${errorDetails}`);
1398
1210
  }
1399
1211
  return validation.data;
1400
1212
  }
1401
1213
 
1402
- // src/evaluator.ts
1403
- function normalizeString(str, caseSensitive) {
1404
- const s = (str ?? "").trim();
1405
- return caseSensitive ? s : s.toLowerCase();
1406
- }
1407
- function checkCondition(condition, item, responses, responseResults) {
1408
- if (condition.type === "and") {
1409
- const results = condition.conditions.map((c) => checkCondition(c, item, responses, responseResults));
1410
- const allTrue = results.every((r) => r === true);
1411
- y("qti evaluator: checking AND condition", {
1412
- numConditions: condition.conditions.length,
1413
- results,
1414
- allTrue
1415
- });
1416
- return allTrue;
1417
- }
1418
- if (condition.type === "or") {
1419
- const results = condition.conditions.map((c) => checkCondition(c, item, responses, responseResults));
1420
- const anyTrue = results.some((r) => r === true);
1421
- y("qti evaluator: checking OR condition", {
1422
- numConditions: condition.conditions.length,
1423
- results,
1424
- anyTrue
1425
- });
1426
- return anyTrue;
1427
- }
1428
- if (condition.type === "not") {
1429
- const result = checkCondition(condition.condition, item, responses, responseResults);
1430
- y("qti evaluator: checking NOT condition", { result, negated: !result });
1431
- return !result;
1432
- }
1433
- if (condition.type === "match") {
1434
- const result = responseResults[condition.variable];
1435
- y("qti evaluator: checking match condition", {
1436
- variable: condition.variable,
1437
- isCorrect: result,
1438
- matches: result === true
1439
- });
1440
- return result === true;
1441
- }
1442
- if (condition.type === "matchValue") {
1443
- const userResponse = responses[condition.variable];
1444
- let userValues;
1445
- if (Array.isArray(userResponse)) {
1446
- userValues = userResponse;
1447
- } else if (userResponse) {
1448
- userValues = [userResponse];
1449
- } else {
1450
- userValues = [];
1451
- }
1452
- const matches = userValues.includes(condition.value);
1453
- y("qti evaluator: checking matchValue condition", {
1454
- variable: condition.variable,
1455
- targetValue: condition.value,
1456
- userValues,
1457
- matches
1458
- });
1459
- return matches;
1460
- }
1461
- if (condition.type === "stringMatch") {
1462
- const userResponse = responses[condition.variable];
1463
- const val = Array.isArray(userResponse) ? userResponse[0] : userResponse;
1464
- if (!val) return false;
1465
- const u = normalizeString(String(val), condition.caseSensitive);
1466
- const t = normalizeString(condition.value, condition.caseSensitive);
1467
- const matches = u === t;
1468
- y("qti evaluator: checking stringMatch", {
1469
- variable: condition.variable,
1470
- caseSensitive: condition.caseSensitive,
1471
- matches
1472
- });
1473
- return matches;
1474
- }
1475
- if (condition.type === "member") {
1476
- const userResponse = responses[condition.variable];
1477
- let userValues;
1478
- if (Array.isArray(userResponse)) {
1479
- userValues = userResponse;
1480
- } else if (userResponse) {
1481
- userValues = [userResponse];
1482
- } else {
1483
- userValues = [];
1484
- }
1485
- const matches = userValues.includes(condition.value);
1486
- y("qti evaluator: checking member", {
1487
- variable: condition.variable,
1488
- target: condition.value,
1489
- userValues,
1490
- matches
1491
- });
1492
- return matches;
1493
- }
1494
- if (condition.type === "equalMapResponse") {
1495
- const responseId = condition.variable;
1496
- const userResponse = responses[responseId];
1497
- const responseDecl = item.responseDeclarations.find((rd) => rd.identifier === responseId);
1498
- if (!userResponse || !responseDecl?.mapping) return false;
1499
- const userValues = Array.isArray(userResponse) ? userResponse : [userResponse];
1500
- const valueMap = new Map(responseDecl.mapping.entries.map((e) => [e.key, e.value]));
1501
- let sum = 0;
1502
- for (const val of userValues) {
1503
- sum += valueMap.get(val) ?? responseDecl.mapping.defaultValue;
1504
- }
1505
- const target = Number(condition.value);
1506
- const diff = Math.abs(sum - target);
1507
- const matches = diff < 1e-4;
1508
- y("qti evaluator: checking equalMapResponse", {
1509
- responseId,
1510
- userValues,
1511
- sum,
1512
- target: condition.value,
1513
- matches
1514
- });
1515
- return matches;
1516
- }
1517
- return false;
1518
- }
1519
- function evaluateRule(rule, item, responses, responseResults) {
1520
- const feedbackIds = [];
1521
- if (rule.type === "action") {
1522
- const action = rule.action;
1523
- if (action.type === "setOutcomeValue" && (action.identifier === "FEEDBACK__OVERALL" || action.identifier === "FEEDBACK__PEDAGOGY" || action.identifier === "FEEDBACK")) {
1524
- y("qti evaluator: executing action", { id: action.identifier, value: action.value });
1525
- feedbackIds.push(action.value);
1526
- }
1527
- return feedbackIds;
1528
- }
1529
- if (rule.type === "condition") {
1530
- for (const branch of rule.branches) {
1531
- const isMatch = branch.condition ? checkCondition(branch.condition, item, responses, responseResults) : true;
1532
- y("qti evaluator: evaluating branch", {
1533
- hasCondition: !!branch.condition,
1534
- isMatch
1535
- });
1536
- if (isMatch) {
1537
- const feedbackActions = branch.actions.filter(
1538
- (r) => r.type === "setOutcomeValue" && (r.identifier === "FEEDBACK__OVERALL" || r.identifier === "FEEDBACK__PEDAGOGY" || r.identifier === "FEEDBACK")
1539
- );
1540
- for (const action of feedbackActions) {
1541
- feedbackIds.push(action.value);
1542
- }
1543
- if (branch.nestedRules) {
1544
- for (const nested of branch.nestedRules) {
1545
- const nestedIds = evaluateRule(nested, item, responses, responseResults);
1546
- feedbackIds.push(...nestedIds);
1547
- }
1548
- }
1549
- break;
1550
- }
1551
- }
1552
- }
1553
- return feedbackIds;
1554
- }
1555
- function evaluateFeedbackIdentifiers(item, responses, responseResults) {
1556
- const processing = item.responseProcessing;
1557
- if (!processing) {
1558
- y("qti evaluator: no response processing found");
1559
- return [];
1560
- }
1561
- y("qti evaluator: starting evaluation", {
1562
- numRules: processing.rules.length,
1563
- responseResults
1564
- });
1565
- const allFeedbackIds = [];
1566
- for (const rule of processing.rules) {
1567
- const ids = evaluateRule(rule, item, responses, responseResults);
1568
- allFeedbackIds.push(...ids);
1569
- }
1570
- y("qti evaluator: selected feedback identifiers", { feedbackIds: allFeedbackIds });
1571
- return allFeedbackIds;
1572
- }
1573
-
1574
1214
  // src/actions/internal/display.ts
1575
1215
  function shuffleArray(items) {
1576
1216
  const arr = items.slice();
1577
1217
  for (let i = arr.length - 1; i > 0; i--) {
1578
- const j2 = Math.floor(Math.random() * (i + 1));
1218
+ const j = Math.floor(Math.random() * (i + 1));
1579
1219
  const vi = arr[i];
1580
- const vj = arr[j2];
1220
+ const vj = arr[j];
1581
1221
  if (vi === void 0 || vj === void 0) {
1582
1222
  continue;
1583
1223
  }
1584
1224
  arr[i] = vj;
1585
- arr[j2] = vi;
1225
+ arr[j] = vi;
1586
1226
  }
1587
1227
  return arr;
1588
1228
  }
1589
1229
  function buildDisplayModelFromXml(qtiXml) {
1590
- y("qti build display model", {});
1591
- const parseResult = I(() => parseAssessmentItemXml(qtiXml));
1230
+ logger2.debug("qti build display model", {});
1231
+ const parseResult = errors.trySync(() => parseAssessmentItemXml(qtiXml));
1592
1232
  if (parseResult.error) {
1593
- l("qti parse failed", { error: parseResult.error });
1594
- throw B(parseResult.error, "qti parse");
1233
+ logger2.error("qti parse failed", { error: parseResult.error });
1234
+ throw errors.wrap(parseResult.error, "qti parse");
1595
1235
  }
1596
1236
  const item = parseResult.data;
1597
1237
  const shape = {};
@@ -1748,17 +1388,187 @@ function buildDisplayModelFromXml(qtiXml) {
1748
1388
  async function buildDisplayModel(qtiXml) {
1749
1389
  return buildDisplayModelFromXml(qtiXml);
1750
1390
  }
1391
+ function normalizeString(str, caseSensitive) {
1392
+ const s = (str ?? "").trim();
1393
+ return caseSensitive ? s : s.toLowerCase();
1394
+ }
1395
+ function checkCondition(condition, item, responses, responseResults) {
1396
+ if (condition.type === "and") {
1397
+ const results = condition.conditions.map((c) => checkCondition(c, item, responses, responseResults));
1398
+ const allTrue = results.every((r) => r === true);
1399
+ logger2.debug("qti evaluator: checking AND condition", {
1400
+ numConditions: condition.conditions.length,
1401
+ results,
1402
+ allTrue
1403
+ });
1404
+ return allTrue;
1405
+ }
1406
+ if (condition.type === "or") {
1407
+ const results = condition.conditions.map((c) => checkCondition(c, item, responses, responseResults));
1408
+ const anyTrue = results.some((r) => r === true);
1409
+ logger2.debug("qti evaluator: checking OR condition", {
1410
+ numConditions: condition.conditions.length,
1411
+ results,
1412
+ anyTrue
1413
+ });
1414
+ return anyTrue;
1415
+ }
1416
+ if (condition.type === "not") {
1417
+ const result = checkCondition(condition.condition, item, responses, responseResults);
1418
+ logger2.debug("qti evaluator: checking NOT condition", { result, negated: !result });
1419
+ return !result;
1420
+ }
1421
+ if (condition.type === "match") {
1422
+ const result = responseResults[condition.variable];
1423
+ logger2.debug("qti evaluator: checking match condition", {
1424
+ variable: condition.variable,
1425
+ isCorrect: result,
1426
+ matches: result === true
1427
+ });
1428
+ return result === true;
1429
+ }
1430
+ if (condition.type === "matchValue") {
1431
+ const userResponse = responses[condition.variable];
1432
+ let userValues;
1433
+ if (Array.isArray(userResponse)) {
1434
+ userValues = userResponse;
1435
+ } else if (userResponse) {
1436
+ userValues = [userResponse];
1437
+ } else {
1438
+ userValues = [];
1439
+ }
1440
+ const matches = userValues.includes(condition.value);
1441
+ logger2.debug("qti evaluator: checking matchValue condition", {
1442
+ variable: condition.variable,
1443
+ targetValue: condition.value,
1444
+ userValues,
1445
+ matches
1446
+ });
1447
+ return matches;
1448
+ }
1449
+ if (condition.type === "stringMatch") {
1450
+ const userResponse = responses[condition.variable];
1451
+ const val = Array.isArray(userResponse) ? userResponse[0] : userResponse;
1452
+ if (!val) return false;
1453
+ const u = normalizeString(String(val), condition.caseSensitive);
1454
+ const t = normalizeString(condition.value, condition.caseSensitive);
1455
+ const matches = u === t;
1456
+ logger2.debug("qti evaluator: checking stringMatch", {
1457
+ variable: condition.variable,
1458
+ caseSensitive: condition.caseSensitive,
1459
+ matches
1460
+ });
1461
+ return matches;
1462
+ }
1463
+ if (condition.type === "member") {
1464
+ const userResponse = responses[condition.variable];
1465
+ let userValues;
1466
+ if (Array.isArray(userResponse)) {
1467
+ userValues = userResponse;
1468
+ } else if (userResponse) {
1469
+ userValues = [userResponse];
1470
+ } else {
1471
+ userValues = [];
1472
+ }
1473
+ const matches = userValues.includes(condition.value);
1474
+ logger2.debug("qti evaluator: checking member", {
1475
+ variable: condition.variable,
1476
+ target: condition.value,
1477
+ userValues,
1478
+ matches
1479
+ });
1480
+ return matches;
1481
+ }
1482
+ if (condition.type === "equalMapResponse") {
1483
+ const responseId = condition.variable;
1484
+ const userResponse = responses[responseId];
1485
+ const responseDecl = item.responseDeclarations.find((rd) => rd.identifier === responseId);
1486
+ if (!userResponse || !responseDecl?.mapping) return false;
1487
+ const userValues = Array.isArray(userResponse) ? userResponse : [userResponse];
1488
+ const valueMap = new Map(responseDecl.mapping.entries.map((e) => [e.key, e.value]));
1489
+ let sum = 0;
1490
+ for (const val of userValues) {
1491
+ sum += valueMap.get(val) ?? responseDecl.mapping.defaultValue;
1492
+ }
1493
+ const target = Number(condition.value);
1494
+ const diff = Math.abs(sum - target);
1495
+ const matches = diff < 1e-4;
1496
+ logger2.debug("qti evaluator: checking equalMapResponse", {
1497
+ responseId,
1498
+ userValues,
1499
+ sum,
1500
+ target: condition.value,
1501
+ matches
1502
+ });
1503
+ return matches;
1504
+ }
1505
+ return false;
1506
+ }
1507
+ function evaluateRule(rule, item, responses, responseResults) {
1508
+ const feedbackIds = [];
1509
+ if (rule.type === "action") {
1510
+ const action = rule.action;
1511
+ if (action.type === "setOutcomeValue" && (action.identifier === "FEEDBACK__OVERALL" || action.identifier === "FEEDBACK__PEDAGOGY" || action.identifier === "FEEDBACK")) {
1512
+ logger2.debug("qti evaluator: executing action", { id: action.identifier, value: action.value });
1513
+ feedbackIds.push(action.value);
1514
+ }
1515
+ return feedbackIds;
1516
+ }
1517
+ if (rule.type === "condition") {
1518
+ for (const branch of rule.branches) {
1519
+ const isMatch = branch.condition ? checkCondition(branch.condition, item, responses, responseResults) : true;
1520
+ logger2.debug("qti evaluator: evaluating branch", {
1521
+ hasCondition: !!branch.condition,
1522
+ isMatch
1523
+ });
1524
+ if (isMatch) {
1525
+ const feedbackActions = branch.actions.filter(
1526
+ (r) => r.type === "setOutcomeValue" && (r.identifier === "FEEDBACK__OVERALL" || r.identifier === "FEEDBACK__PEDAGOGY" || r.identifier === "FEEDBACK")
1527
+ );
1528
+ for (const action of feedbackActions) {
1529
+ feedbackIds.push(action.value);
1530
+ }
1531
+ if (branch.nestedRules) {
1532
+ for (const nested of branch.nestedRules) {
1533
+ const nestedIds = evaluateRule(nested, item, responses, responseResults);
1534
+ feedbackIds.push(...nestedIds);
1535
+ }
1536
+ }
1537
+ break;
1538
+ }
1539
+ }
1540
+ }
1541
+ return feedbackIds;
1542
+ }
1543
+ function evaluateFeedbackIdentifiers(item, responses, responseResults) {
1544
+ const processing = item.responseProcessing;
1545
+ if (!processing) {
1546
+ logger2.debug("qti evaluator: no response processing found");
1547
+ return [];
1548
+ }
1549
+ logger2.debug("qti evaluator: starting evaluation", {
1550
+ numRules: processing.rules.length,
1551
+ responseResults
1552
+ });
1553
+ const allFeedbackIds = [];
1554
+ for (const rule of processing.rules) {
1555
+ const ids = evaluateRule(rule, item, responses, responseResults);
1556
+ allFeedbackIds.push(...ids);
1557
+ }
1558
+ logger2.debug("qti evaluator: selected feedback identifiers", { feedbackIds: allFeedbackIds });
1559
+ return allFeedbackIds;
1560
+ }
1751
1561
 
1752
1562
  // src/actions/internal/validate.ts
1753
1563
  function validateResponsesFromXml(qtiXml, responses) {
1754
- y("qti validate secure", {});
1755
- const parseResult = I(() => parseAssessmentItemXml(qtiXml));
1564
+ logger2.debug("qti validate secure", {});
1565
+ const parseResult = errors.trySync(() => parseAssessmentItemXml(qtiXml));
1756
1566
  if (parseResult.error) {
1757
- l("qti parse failed during validate", { error: parseResult.error });
1758
- throw B(parseResult.error, "qti parse");
1567
+ logger2.error("qti parse failed during validate", { error: parseResult.error });
1568
+ throw errors.wrap(parseResult.error, "qti parse");
1759
1569
  }
1760
1570
  const item = parseResult.data;
1761
- y("qti validate: parsed item", {
1571
+ logger2.debug("qti validate: parsed item", {
1762
1572
  title: item.title,
1763
1573
  responseCount: Object.keys(responses).length
1764
1574
  });
@@ -1772,7 +1582,7 @@ function validateResponsesFromXml(qtiXml, responses) {
1772
1582
  if (user == null) {
1773
1583
  allCorrect = false;
1774
1584
  responseCorrectness[respId] = false;
1775
- y("qti validate: missing response", { responseId: respId });
1585
+ logger2.debug("qti validate: missing response", { responseId: respId });
1776
1586
  continue;
1777
1587
  }
1778
1588
  const userVals = Array.isArray(user) ? user.filter((v) => typeof v === "string") : [user];
@@ -1780,7 +1590,7 @@ function validateResponsesFromXml(qtiXml, responses) {
1780
1590
  let isCorrect = false;
1781
1591
  if (rd.cardinality === "ordered") {
1782
1592
  isCorrect = userVals.length === correctVals.length && userVals.every((val, index) => val === correctVals[index]);
1783
- y("qti validate: ordered check", {
1593
+ logger2.debug("qti validate: ordered check", {
1784
1594
  responseId: respId,
1785
1595
  userVals,
1786
1596
  correctVals,
@@ -1790,7 +1600,7 @@ function validateResponsesFromXml(qtiXml, responses) {
1790
1600
  const correctSet2 = new Set(correctVals);
1791
1601
  const userSet = new Set(userVals);
1792
1602
  isCorrect = userSet.size === correctSet2.size && [...userSet].every((v) => correctSet2.has(v));
1793
- y("qti validate: directedPair check", {
1603
+ logger2.debug("qti validate: directedPair check", {
1794
1604
  responseId: respId,
1795
1605
  userVals,
1796
1606
  correctVals,
@@ -1808,7 +1618,7 @@ function validateResponsesFromXml(qtiXml, responses) {
1808
1618
  });
1809
1619
  }
1810
1620
  }
1811
- y("qti validate: numeric check", {
1621
+ logger2.debug("qti validate: numeric check", {
1812
1622
  responseId: respId,
1813
1623
  baseType: rd.baseType,
1814
1624
  userVal: userVals[0],
@@ -1818,7 +1628,7 @@ function validateResponsesFromXml(qtiXml, responses) {
1818
1628
  } else if (rd.cardinality === "single") {
1819
1629
  const userVal = userVals[0];
1820
1630
  isCorrect = userVal != null && correctVals.includes(userVal);
1821
- y("qti validate: single cardinality check", {
1631
+ logger2.debug("qti validate: single cardinality check", {
1822
1632
  responseId: respId,
1823
1633
  userVal,
1824
1634
  correctVals,
@@ -1828,7 +1638,7 @@ function validateResponsesFromXml(qtiXml, responses) {
1828
1638
  const correctSet2 = new Set(correctVals);
1829
1639
  const userSet = new Set(userVals);
1830
1640
  isCorrect = userSet.size === correctSet2.size && [...userSet].every((v) => correctSet2.has(v));
1831
- y("qti validate: multiple cardinality check", {
1641
+ logger2.debug("qti validate: multiple cardinality check", {
1832
1642
  responseId: respId,
1833
1643
  userVals,
1834
1644
  correctVals,
@@ -1837,7 +1647,7 @@ function validateResponsesFromXml(qtiXml, responses) {
1837
1647
  }
1838
1648
  if (!isCorrect) allCorrect = false;
1839
1649
  responseCorrectness[respId] = isCorrect;
1840
- y("qti validate: evaluated response", {
1650
+ logger2.debug("qti validate: evaluated response", {
1841
1651
  responseId: respId,
1842
1652
  selected: userVals,
1843
1653
  isCorrect
@@ -1861,7 +1671,7 @@ function validateResponsesFromXml(qtiXml, responses) {
1861
1671
  isCorrect: allCorrect,
1862
1672
  messageHtml: feedbackHtmlParts.join("")
1863
1673
  };
1864
- y("qti validate: overall feedback via response processing rules", {
1674
+ logger2.debug("qti validate: overall feedback via response processing rules", {
1865
1675
  isCorrect: allCorrect,
1866
1676
  feedbackIds: feedbackIdentifiers,
1867
1677
  numBlocks: feedbackHtmlParts.length
@@ -1874,7 +1684,7 @@ function validateResponsesFromXml(qtiXml, responses) {
1874
1684
  );
1875
1685
  if (fallbackBlock) {
1876
1686
  overallFeedback = { isCorrect: allCorrect, messageHtml: sanitizeHtml(fallbackBlock.contentHtml) };
1877
- y("qti validate: overall feedback via fallback block", {
1687
+ logger2.debug("qti validate: overall feedback via fallback block", {
1878
1688
  isCorrect: allCorrect,
1879
1689
  blockId: fallbackBlock.identifier
1880
1690
  });