@conform-ed/qti-react 0.0.17 → 0.0.18

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.
@@ -0,0 +1,3062 @@
1
+ // src/graphic.ts
2
+ function parseCoords(coords) {
3
+ return coords.split(",").map((entry) => Number(entry.trim())).filter((value) => !Number.isNaN(value));
4
+ }
5
+ function parsePoint(value) {
6
+ const [x, y, ...rest] = value.trim().split(/\s+/u).map(Number);
7
+ if (x === undefined || y === undefined || rest.length > 0 || Number.isNaN(x) || Number.isNaN(y)) {
8
+ return null;
9
+ }
10
+ return { x, y };
11
+ }
12
+ function formatPoint(point) {
13
+ return `${point.x} ${point.y}`;
14
+ }
15
+ function pointInPolygon(coords, point) {
16
+ let inside = false;
17
+ for (let i = 0, j = coords.length - 2;i < coords.length; j = i, i += 2) {
18
+ const xi = coords[i];
19
+ const yi = coords[i + 1];
20
+ const xj = coords[j];
21
+ const yj = coords[j + 1];
22
+ const intersects = yi > point.y !== yj > point.y && point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi;
23
+ if (intersects) {
24
+ inside = !inside;
25
+ }
26
+ }
27
+ return inside;
28
+ }
29
+ function pointInShape(shape, coords, point) {
30
+ switch (shape) {
31
+ case "default":
32
+ return true;
33
+ case "circle": {
34
+ const [cx, cy, r] = coords;
35
+ if (cx === undefined || cy === undefined || r === undefined) {
36
+ return false;
37
+ }
38
+ return (point.x - cx) ** 2 + (point.y - cy) ** 2 <= r ** 2;
39
+ }
40
+ case "rect": {
41
+ const [left, top, right, bottom] = coords;
42
+ if (left === undefined || top === undefined || right === undefined || bottom === undefined) {
43
+ return false;
44
+ }
45
+ return point.x >= left && point.x <= right && point.y >= top && point.y <= bottom;
46
+ }
47
+ case "ellipse": {
48
+ const [cx, cy, rx, ry] = coords;
49
+ if (cx === undefined || cy === undefined || rx === undefined || ry === undefined || rx === 0 || ry === 0) {
50
+ return false;
51
+ }
52
+ return (point.x - cx) ** 2 / rx ** 2 + (point.y - cy) ** 2 / ry ** 2 <= 1;
53
+ }
54
+ case "poly":
55
+ return coords.length >= 6 && pointInPolygon(coords, point);
56
+ default:
57
+ return false;
58
+ }
59
+ }
60
+
61
+ // src/normalized-item.ts
62
+ function isRecord(value) {
63
+ return typeof value === "object" && value !== null && !Array.isArray(value);
64
+ }
65
+ function asRecords(value) {
66
+ return Array.isArray(value) ? value.filter(isRecord) : [];
67
+ }
68
+ var kindRenames = {
69
+ hotTextInteraction: "hottextInteraction",
70
+ hotText: "hottext"
71
+ };
72
+ function numberValue(value) {
73
+ if (typeof value === "number") {
74
+ return value;
75
+ }
76
+ if (typeof value === "string" && value !== "") {
77
+ const parsed = Number(value);
78
+ return Number.isNaN(parsed) ? undefined : parsed;
79
+ }
80
+ return;
81
+ }
82
+ function findImageSource(node) {
83
+ if (!isRecord(node)) {
84
+ return {};
85
+ }
86
+ const attributes = isRecord(node["attributes"]) ? node["attributes"] : {};
87
+ if (typeof attributes["data"] === "string" || typeof attributes["src"] === "string") {
88
+ return attributes;
89
+ }
90
+ for (const child of asRecords(node["children"])) {
91
+ const found = findImageSource(child);
92
+ if (typeof found["data"] === "string" || typeof found["src"] === "string") {
93
+ return found;
94
+ }
95
+ }
96
+ return attributes;
97
+ }
98
+ function toStageObject(node) {
99
+ const attributes = findImageSource(node);
100
+ const data = attributes["data"] ?? attributes["src"];
101
+ const width = numberValue(attributes["width"]);
102
+ const height = numberValue(attributes["height"]);
103
+ return {
104
+ data: typeof data === "string" ? data : "",
105
+ ...width !== undefined ? { width } : {},
106
+ ...height !== undefined ? { height } : {},
107
+ ...typeof attributes["type"] === "string" ? { type: attributes["type"] } : {}
108
+ };
109
+ }
110
+ function flattenText(value) {
111
+ if (typeof value === "string") {
112
+ return value;
113
+ }
114
+ if (Array.isArray(value)) {
115
+ return value.map(flattenText).join("");
116
+ }
117
+ if (!isRecord(value)) {
118
+ return "";
119
+ }
120
+ if (value["kind"] === "text") {
121
+ return typeof value["value"] === "string" ? value["value"] : "";
122
+ }
123
+ return flattenText(value["children"]) + flattenText(value["content"]) + flattenText(value["value"]);
124
+ }
125
+ function withNumericCoords(node) {
126
+ return typeof node["coords"] === "string" ? { ...node, coords: parseCoords(node["coords"]) } : node;
127
+ }
128
+ function reshapeContentNode(node) {
129
+ const kind = node["kind"];
130
+ if (typeof kind !== "string") {
131
+ return node;
132
+ }
133
+ const renamed = kindRenames[kind];
134
+ if (renamed !== undefined) {
135
+ return { ...node, kind: renamed };
136
+ }
137
+ switch (kind) {
138
+ case "hotspotChoice":
139
+ case "associableHotspot":
140
+ return withNumericCoords(node);
141
+ case "hotspotInteraction":
142
+ case "graphicOrderInteraction":
143
+ case "graphicAssociateInteraction":
144
+ case "selectPointInteraction": {
145
+ const { image, ...rest } = node;
146
+ return { ...rest, object: toStageObject(image) };
147
+ }
148
+ case "drawingInteraction": {
149
+ const { content, ...rest } = node;
150
+ const media = asRecords(content).find((fragment) => fragment["kind"] === "xml" && typeof fragment["name"] === "string" && ["object", "picture", "img"].includes(fragment["name"]));
151
+ return { ...rest, object: toStageObject(media) };
152
+ }
153
+ case "graphicGapMatchInteraction": {
154
+ const { image, gapChoices, ...rest } = node;
155
+ const gapImgs = asRecords(gapChoices).map(({ media, content, ...choice }) => choice["kind"] === "gapImg" ? { ...choice, object: toStageObject(media) } : { ...choice, label: flattenText(content) });
156
+ return { ...rest, object: toStageObject(image), gapImgs };
157
+ }
158
+ case "gapMatchInteraction": {
159
+ const gapTexts = asRecords(node["gapChoices"]).filter((choice) => choice["kind"] === "gapText");
160
+ return { ...node, gapTexts };
161
+ }
162
+ case "mediaInteraction": {
163
+ const { media, ...rest } = node;
164
+ return { ...rest, content: media === undefined ? [] : [media] };
165
+ }
166
+ case "uploadInteraction": {
167
+ const acceptedTypes = node["acceptedTypes"];
168
+ return Array.isArray(acceptedTypes) ? { ...node, type: acceptedTypes.join(",") } : node;
169
+ }
170
+ case "positionObjectStage": {
171
+ const interactions = asRecords(node["positionObjectInteractions"]);
172
+ const [first] = interactions;
173
+ if (interactions.length === 1 && first) {
174
+ return {
175
+ kind: "positionObjectStage",
176
+ responseIdentifier: first["responseIdentifier"],
177
+ stageObject: toStageObject(node["image"]),
178
+ object: toStageObject(first["image"]),
179
+ ...first["maxChoices"] !== undefined ? { maxChoices: first["maxChoices"] } : {},
180
+ ...first["minChoices"] !== undefined ? { minChoices: first["minChoices"] } : {}
181
+ };
182
+ }
183
+ const responseIdentifier = first?.["responseIdentifier"];
184
+ return { ...node, ...typeof responseIdentifier === "string" ? { responseIdentifier } : {} };
185
+ }
186
+ default:
187
+ return node;
188
+ }
189
+ }
190
+ function convertContentEntry(entry) {
191
+ if (typeof entry === "string") {
192
+ return { kind: "text", value: entry };
193
+ }
194
+ return convertContentValue(entry);
195
+ }
196
+ function convertContentValue(value) {
197
+ if (Array.isArray(value)) {
198
+ return value.map(convertContentValue);
199
+ }
200
+ if (!isRecord(value)) {
201
+ return value;
202
+ }
203
+ const converted = Object.fromEntries(Object.entries(value).map(([key, entry]) => {
204
+ if ((key === "children" || key === "content") && Array.isArray(entry)) {
205
+ return [key, entry.map(convertContentEntry)];
206
+ }
207
+ return [key, convertContentValue(entry)];
208
+ }));
209
+ return reshapeContentNode(converted);
210
+ }
211
+ function convertExpression(expression) {
212
+ const record = isRecord(expression) ? expression : {};
213
+ const { children, ...rest } = record;
214
+ return {
215
+ ...rest,
216
+ ...Array.isArray(children) ? { expressions: children.map(convertExpression) } : {}
217
+ };
218
+ }
219
+ function convertBranch(branch, convertRule) {
220
+ const record = isRecord(branch) ? branch : {};
221
+ return {
222
+ expression: convertExpression(record["expression"]),
223
+ rules: (Array.isArray(record["actions"]) ? record["actions"] : []).map(convertRule)
224
+ };
225
+ }
226
+ function convertRpRule(rule) {
227
+ const record = isRecord(rule) ? rule : {};
228
+ const kind = typeof record["kind"] === "string" ? record["kind"] : "";
229
+ if (kind === "responseCondition") {
230
+ const elseIfs = Array.isArray(record["responseElseIf"]) ? record["responseElseIf"].map((branch) => convertBranch(branch, convertRpRule)) : [];
231
+ return {
232
+ kind,
233
+ responseIf: convertBranch(record["responseIf"], convertRpRule),
234
+ ...elseIfs.length ? { responseElseIfs: elseIfs } : {},
235
+ ...isRecord(record["responseElse"]) ? {
236
+ responseElse: {
237
+ rules: (Array.isArray(record["responseElse"]["actions"]) ? record["responseElse"]["actions"] : []).map(convertRpRule)
238
+ }
239
+ } : {}
240
+ };
241
+ }
242
+ if (kind === "responseProcessingFragment") {
243
+ return { kind, rules: (Array.isArray(record["rules"]) ? record["rules"] : []).map(convertRpRule) };
244
+ }
245
+ return {
246
+ kind,
247
+ ...typeof record["identifier"] === "string" ? { identifier: record["identifier"] } : {},
248
+ ...record["expression"] !== undefined ? { expression: convertExpression(record["expression"]) } : {}
249
+ };
250
+ }
251
+ function convertTemplateRule(rule) {
252
+ const record = isRecord(rule) ? rule : {};
253
+ const kind = typeof record["kind"] === "string" ? record["kind"] : "";
254
+ if (kind === "templateCondition") {
255
+ const elseIfs = Array.isArray(record["templateElseIf"]) ? record["templateElseIf"].map((branch) => convertBranch(branch, convertTemplateRule)) : [];
256
+ return {
257
+ kind,
258
+ templateIf: convertBranch(record["templateIf"], convertTemplateRule),
259
+ ...elseIfs.length ? { templateElseIfs: elseIfs } : {},
260
+ ...isRecord(record["templateElse"]) ? {
261
+ templateElse: {
262
+ rules: (Array.isArray(record["templateElse"]["actions"]) ? record["templateElse"]["actions"] : []).map(convertTemplateRule)
263
+ }
264
+ } : {}
265
+ };
266
+ }
267
+ return {
268
+ kind,
269
+ ...typeof record["identifier"] === "string" ? { identifier: record["identifier"] } : {},
270
+ ...record["expression"] !== undefined ? { expression: convertExpression(record["expression"]) } : {}
271
+ };
272
+ }
273
+ function convertResponseProcessing(value) {
274
+ return {
275
+ ...typeof value["template"] === "string" ? { template: value["template"] } : {},
276
+ ...Array.isArray(value["rules"]) ? { rules: value["rules"].map(convertRpRule) } : {}
277
+ };
278
+ }
279
+ function convertResponseDeclaration(declaration) {
280
+ const areaMapping = declaration["areaMapping"];
281
+ if (!isRecord(areaMapping)) {
282
+ return declaration;
283
+ }
284
+ const areaMapEntries = asRecords(areaMapping["areaMapEntries"]).map((entry) => withNumericCoords(entry));
285
+ return { ...declaration, areaMapping: { ...areaMapping, areaMapEntries } };
286
+ }
287
+ function appendCatalogViews(target, value) {
288
+ if (Array.isArray(value)) {
289
+ for (const entry of value) {
290
+ appendCatalogViews(target, entry);
291
+ }
292
+ return;
293
+ }
294
+ if (!isRecord(value)) {
295
+ return;
296
+ }
297
+ const catalogInfo = value["catalogInfo"];
298
+ if (isRecord(catalogInfo) && Array.isArray(catalogInfo["catalogs"])) {
299
+ target.push(...catalogInfo["catalogs"]);
300
+ }
301
+ appendCatalogViews(target, value["content"]);
302
+ appendCatalogViews(target, value["children"]);
303
+ }
304
+ function documentCatalogViews(root, convertedContent) {
305
+ const catalogs = [];
306
+ appendCatalogViews(catalogs, isRecord(root["catalogInfo"]) ? { catalogInfo: convertContentValue(root["catalogInfo"]) } : undefined);
307
+ appendCatalogViews(catalogs, convertedContent);
308
+ return catalogs;
309
+ }
310
+ function assessmentItemViewFromNormalized(document) {
311
+ if (!isRecord(document) || !isRecord(document["assessmentItem"])) {
312
+ return null;
313
+ }
314
+ const item = document["assessmentItem"];
315
+ const itemBody = isRecord(item["itemBody"]) ? item["itemBody"] : {};
316
+ const content = Array.isArray(itemBody["content"]) ? itemBody["content"].map(convertContentEntry) : [];
317
+ const templateRules = isRecord(item["templateProcessing"]) ? item["templateProcessing"]["rules"] : undefined;
318
+ const convertedModalFeedbacks = Array.isArray(item["modalFeedbacks"]) ? item["modalFeedbacks"].map(convertContentValue) : undefined;
319
+ const catalogs = documentCatalogViews(item, [content, convertedModalFeedbacks]);
320
+ return {
321
+ responseDeclarations: asRecords(item["responseDeclarations"]).map(convertResponseDeclaration),
322
+ outcomeDeclarations: item["outcomeDeclarations"] ?? [],
323
+ ...isRecord(item["responseProcessing"]) ? { responseProcessing: convertResponseProcessing(item["responseProcessing"]) } : {},
324
+ ...Array.isArray(item["templateDeclarations"]) ? { templateDeclarations: item["templateDeclarations"] } : {},
325
+ ...Array.isArray(templateRules) ? {
326
+ templateProcessing: {
327
+ rules: templateRules.map(convertTemplateRule)
328
+ }
329
+ } : {},
330
+ ...typeof item["adaptive"] === "boolean" ? { adaptive: item["adaptive"] } : {},
331
+ ...convertedModalFeedbacks ? { modalFeedbacks: convertedModalFeedbacks } : {},
332
+ ...catalogs.length ? { catalogs } : {},
333
+ ...isRecord(item["companionMaterialsInfo"]) ? { companionMaterials: item["companionMaterialsInfo"] } : {},
334
+ ...Array.isArray(item["assessmentStimulusRefs"]) ? {
335
+ assessmentStimulusRefs: asRecords(item["assessmentStimulusRefs"]).map((ref) => ({
336
+ identifier: typeof ref["identifier"] === "string" ? ref["identifier"] : "",
337
+ href: typeof ref["href"] === "string" ? ref["href"] : "",
338
+ ...typeof ref["title"] === "string" ? { title: ref["title"] } : {}
339
+ }))
340
+ } : {},
341
+ itemBody: { content }
342
+ };
343
+ }
344
+ function stimulusContentFromNormalized(document) {
345
+ if (!isRecord(document) || !isRecord(document["assessmentStimulus"])) {
346
+ return null;
347
+ }
348
+ const stimulus = document["assessmentStimulus"];
349
+ const body = isRecord(stimulus["stimulusBody"]) ? stimulus["stimulusBody"] : {};
350
+ const content = Array.isArray(body["content"]) ? body["content"].map(convertContentEntry) : [];
351
+ const catalogs = documentCatalogViews(stimulus, content);
352
+ return { content, ...catalogs.length ? { catalogs } : {} };
353
+ }
354
+ function convertPreConditions(value) {
355
+ return asRecords(value).map((wrapper) => convertExpression(wrapper["expression"]));
356
+ }
357
+ function convertBranchRules(value) {
358
+ return asRecords(value).map((rule) => ({
359
+ target: typeof rule["target"] === "string" ? rule["target"] : "",
360
+ expression: convertExpression(rule["expression"])
361
+ }));
362
+ }
363
+ function convertOutcomeRule(rule) {
364
+ const record = isRecord(rule) ? rule : {};
365
+ const kind = typeof record["kind"] === "string" ? record["kind"] : "";
366
+ if (kind === "outcomeCondition") {
367
+ const elseIfs = Array.isArray(record["outcomeElseIf"]) ? record["outcomeElseIf"].map((branch) => convertBranch(branch, convertOutcomeRule)) : [];
368
+ return {
369
+ kind,
370
+ outcomeIf: convertBranch(record["outcomeIf"], convertOutcomeRule),
371
+ ...elseIfs.length ? { outcomeElseIfs: elseIfs } : {},
372
+ ...isRecord(record["outcomeElse"]) ? {
373
+ outcomeElse: {
374
+ rules: (Array.isArray(record["outcomeElse"]["actions"]) ? record["outcomeElse"]["actions"] : []).map(convertOutcomeRule)
375
+ }
376
+ } : {}
377
+ };
378
+ }
379
+ if (kind === "outcomeProcessingFragment") {
380
+ return { kind, rules: (Array.isArray(record["rules"]) ? record["rules"] : []).map(convertOutcomeRule) };
381
+ }
382
+ return {
383
+ kind,
384
+ ...typeof record["identifier"] === "string" ? { identifier: record["identifier"] } : {},
385
+ ...record["expression"] !== undefined ? { expression: convertExpression(record["expression"]) } : {}
386
+ };
387
+ }
388
+ function sessionControlAndTimeLimits(record) {
389
+ return {
390
+ ...isRecord(record["itemSessionControl"]) ? { itemSessionControl: record["itemSessionControl"] } : {},
391
+ ...isRecord(record["timeLimits"]) ? { timeLimits: record["timeLimits"] } : {}
392
+ };
393
+ }
394
+ function convertItemRef(ref) {
395
+ return {
396
+ kind: "assessmentItemRef",
397
+ identifier: typeof ref["identifier"] === "string" ? ref["identifier"] : "",
398
+ ...typeof ref["href"] === "string" ? { href: ref["href"] } : {},
399
+ ...Array.isArray(ref["category"]) ? { categories: ref["category"] } : {},
400
+ ...typeof ref["fixed"] === "boolean" ? { fixed: ref["fixed"] } : {},
401
+ ...typeof ref["required"] === "boolean" ? { required: ref["required"] } : {},
402
+ ...ref["preConditions"] !== undefined ? { preConditions: convertPreConditions(ref["preConditions"]) } : {},
403
+ ...ref["branchRules"] !== undefined ? { branchRules: convertBranchRules(ref["branchRules"]) } : {},
404
+ ...Array.isArray(ref["weights"]) ? { weights: ref["weights"] } : {},
405
+ ...Array.isArray(ref["templateDefaults"]) ? {
406
+ templateDefaults: asRecords(ref["templateDefaults"]).map((entry) => ({
407
+ templateIdentifier: typeof entry["templateIdentifier"] === "string" ? entry["templateIdentifier"] : "",
408
+ expression: convertExpression(entry["expression"])
409
+ }))
410
+ } : {},
411
+ ...sessionControlAndTimeLimits(ref)
412
+ };
413
+ }
414
+ function convertSection(section) {
415
+ const children = asRecords(section["children"]).map((child) => child["visible"] !== undefined || child["children"] !== undefined ? convertSection(child) : convertItemRef(child));
416
+ return {
417
+ kind: "assessmentSection",
418
+ identifier: typeof section["identifier"] === "string" ? section["identifier"] : "",
419
+ ...typeof section["title"] === "string" ? { title: section["title"] } : {},
420
+ ...typeof section["visible"] === "boolean" ? { visible: section["visible"] } : {},
421
+ ...typeof section["fixed"] === "boolean" ? { fixed: section["fixed"] } : {},
422
+ ...typeof section["required"] === "boolean" ? { required: section["required"] } : {},
423
+ ...typeof section["keepTogether"] === "boolean" ? { keepTogether: section["keepTogether"] } : {},
424
+ ...isRecord(section["selection"]) ? { selection: section["selection"] } : {},
425
+ ...isRecord(section["ordering"]) ? { ordering: section["ordering"] } : {},
426
+ ...section["preConditions"] !== undefined ? { preConditions: convertPreConditions(section["preConditions"]) } : {},
427
+ ...section["branchRules"] !== undefined ? { branchRules: convertBranchRules(section["branchRules"]) } : {},
428
+ ...sessionControlAndTimeLimits(section),
429
+ children
430
+ };
431
+ }
432
+ function convertTestFeedback(feedback) {
433
+ const converted = convertContentValue(feedback);
434
+ return {
435
+ outcomeIdentifier: typeof converted["outcomeIdentifier"] === "string" ? converted["outcomeIdentifier"] : "",
436
+ identifier: typeof converted["identifier"] === "string" ? converted["identifier"] : "",
437
+ ...converted["access"] === "atEnd" || converted["access"] === "during" ? { access: converted["access"] } : {},
438
+ ...converted["showHide"] === "show" || converted["showHide"] === "hide" ? { showHide: converted["showHide"] } : {},
439
+ ...Array.isArray(converted["content"]) ? { content: converted["content"] } : {}
440
+ };
441
+ }
442
+ function assessmentTestViewFromNormalized(document) {
443
+ if (!isRecord(document) || !isRecord(document["assessmentTest"])) {
444
+ return null;
445
+ }
446
+ const testDocument = document["assessmentTest"];
447
+ const outcomeRules = isRecord(testDocument["outcomeProcessing"]) ? testDocument["outcomeProcessing"]["rules"] : undefined;
448
+ const testParts = asRecords(testDocument["testParts"]).map((part) => ({
449
+ identifier: typeof part["identifier"] === "string" ? part["identifier"] : "",
450
+ navigationMode: part["navigationMode"] === "nonlinear" ? "nonlinear" : "linear",
451
+ submissionMode: part["submissionMode"] === "simultaneous" ? "simultaneous" : "individual",
452
+ ...part["preConditions"] !== undefined ? { preConditions: convertPreConditions(part["preConditions"]) } : {},
453
+ ...part["branchRules"] !== undefined ? { branchRules: convertBranchRules(part["branchRules"]) } : {},
454
+ ...sessionControlAndTimeLimits(part),
455
+ assessmentSections: asRecords(part["children"]).map(convertSection)
456
+ }));
457
+ return {
458
+ identifier: typeof testDocument["identifier"] === "string" ? testDocument["identifier"] : "",
459
+ ...typeof testDocument["title"] === "string" ? { title: testDocument["title"] } : {},
460
+ outcomeDeclarations: testDocument["outcomeDeclarations"] ?? [],
461
+ ...isRecord(testDocument["timeLimits"]) ? { timeLimits: testDocument["timeLimits"] } : {},
462
+ testParts,
463
+ ...Array.isArray(outcomeRules) ? { outcomeProcessing: { rules: outcomeRules.map(convertOutcomeRule) } } : {},
464
+ ...Array.isArray(testDocument["testFeedbacks"]) ? { testFeedbacks: asRecords(testDocument["testFeedbacks"]).map(convertTestFeedback) } : {}
465
+ };
466
+ }
467
+ // src/content-model.ts
468
+ var v0InteractionKinds = [
469
+ "associateInteraction",
470
+ "choiceInteraction",
471
+ "drawingInteraction",
472
+ "endAttemptInteraction",
473
+ "extendedTextInteraction",
474
+ "gapMatchInteraction",
475
+ "graphicAssociateInteraction",
476
+ "graphicGapMatchInteraction",
477
+ "graphicOrderInteraction",
478
+ "hotspotInteraction",
479
+ "hottextInteraction",
480
+ "inlineChoiceInteraction",
481
+ "matchInteraction",
482
+ "mediaInteraction",
483
+ "orderInteraction",
484
+ "positionObjectStage",
485
+ "selectPointInteraction",
486
+ "sliderInteraction",
487
+ "textEntryInteraction",
488
+ "uploadInteraction"
489
+ ];
490
+ var v0FlowElements = new Set([
491
+ "p",
492
+ "span",
493
+ "strong",
494
+ "em",
495
+ "b",
496
+ "i",
497
+ "sub",
498
+ "sup",
499
+ "br",
500
+ "ul",
501
+ "ol",
502
+ "li",
503
+ "ruby",
504
+ "rb",
505
+ "rt",
506
+ "rp",
507
+ "rtc",
508
+ "bdo",
509
+ "bdi",
510
+ "img",
511
+ "audio",
512
+ "video",
513
+ "source",
514
+ "track",
515
+ "picture",
516
+ "figure",
517
+ "figcaption",
518
+ "object",
519
+ "div",
520
+ "section",
521
+ "h1",
522
+ "h2",
523
+ "h3",
524
+ "h4",
525
+ "h5",
526
+ "h6",
527
+ "blockquote",
528
+ "hr",
529
+ "table",
530
+ "caption",
531
+ "thead",
532
+ "tbody",
533
+ "tfoot",
534
+ "tr",
535
+ "th",
536
+ "td",
537
+ "a",
538
+ "abbr",
539
+ "acronym",
540
+ "address",
541
+ "article",
542
+ "aside",
543
+ "big",
544
+ "code",
545
+ "details",
546
+ "summary",
547
+ "dfn",
548
+ "dl",
549
+ "dt",
550
+ "dd",
551
+ "kbd",
552
+ "label",
553
+ "nav",
554
+ "pre",
555
+ "q",
556
+ "samp",
557
+ "small",
558
+ "tt",
559
+ "var",
560
+ "footer",
561
+ "header"
562
+ ]);
563
+ var v0ElementAttributes = new Map([
564
+ ["a", new Set(["href", "type"])],
565
+ ["img", new Set(["src", "alt", "width", "height"])],
566
+ ["audio", new Set(["src", "controls", "loop", "muted", "preload"])],
567
+ ["video", new Set(["src", "controls", "loop", "muted", "preload", "poster", "width", "height"])],
568
+ ["source", new Set(["src", "type"])],
569
+ ["track", new Set(["src", "kind", "srclang", "label", "default"])],
570
+ ["object", new Set(["data", "type", "width", "height"])]
571
+ ]);
572
+ var v0UrlAttributes = new Set(["src", "poster", "data", "href"]);
573
+ var v0MathRoot = "math";
574
+ var v0GlobalAttributes = new Set(["id", "class", "lang", "xml:lang", "dir"]);
575
+ var v0ContentModel = {
576
+ interactionKinds: new Set(v0InteractionKinds),
577
+ flowElements: v0FlowElements,
578
+ mathRoot: v0MathRoot,
579
+ globalAttributes: v0GlobalAttributes,
580
+ elementAttributes: v0ElementAttributes,
581
+ urlAttributes: v0UrlAttributes
582
+ };
583
+ function isAllowedFlowElement(model, name) {
584
+ return model.flowElements.has(name) || name === model.mathRoot;
585
+ }
586
+ function isInteractionKind(model, kind) {
587
+ return model.interactionKinds.has(kind);
588
+ }
589
+ function isUnsafeAttribute(name, value) {
590
+ const lowerName = name.toLowerCase();
591
+ if (lowerName.startsWith("on")) {
592
+ return true;
593
+ }
594
+ if (typeof value === "string" && /^\s*javascript:/iu.test(value)) {
595
+ return true;
596
+ }
597
+ return false;
598
+ }
599
+ function sanitizeAttributes(model, elementName, attributes) {
600
+ const safe = {};
601
+ if (!attributes) {
602
+ return safe;
603
+ }
604
+ const elementAllowed = model.elementAttributes.get(elementName);
605
+ for (const [name, value] of Object.entries(attributes)) {
606
+ if (isUnsafeAttribute(name, value)) {
607
+ continue;
608
+ }
609
+ const ariaOrData = name === "role" || name.startsWith("aria-") || name.startsWith("data-");
610
+ if (!ariaOrData && !model.globalAttributes.has(name) && !elementAllowed?.has(name)) {
611
+ continue;
612
+ }
613
+ if (typeof value === "string") {
614
+ safe[name] = value;
615
+ }
616
+ }
617
+ return safe;
618
+ }
619
+ function sanitizeMathAttributes(attributes) {
620
+ const safe = {};
621
+ if (!attributes) {
622
+ return safe;
623
+ }
624
+ for (const [name, value] of Object.entries(attributes)) {
625
+ if (!isUnsafeAttribute(name, value) && typeof value === "string") {
626
+ safe[name] = value;
627
+ }
628
+ }
629
+ return safe;
630
+ }
631
+
632
+ // ../../node_modules/.bun/whynot@5.0.0/node_modules/whynot/dist/whynot.esm.js
633
+ function t(t2, s, r, i) {
634
+ const n = { op: s, func: r, data: i };
635
+ return t2.push(n), n;
636
+ }
637
+ function s(t2, s2) {
638
+ return t2;
639
+ }
640
+
641
+ class r {
642
+ constructor() {
643
+ this.program = [];
644
+ }
645
+ test(s2, r2) {
646
+ return t(this.program, 5, s2, r2 === undefined ? null : r2);
647
+ }
648
+ jump(s2) {
649
+ return t(this.program, 3, null, s2);
650
+ }
651
+ record(r2, i) {
652
+ return t(this.program, 4, i === undefined ? s : i, r2);
653
+ }
654
+ bad(s2 = 1) {
655
+ return t(this.program, 1, null, s2);
656
+ }
657
+ accept() {
658
+ return t(this.program, 0, null, null);
659
+ }
660
+ fail(s2) {
661
+ return t(this.program, 2, s2 || null, null);
662
+ }
663
+ }
664
+
665
+ class i {
666
+ constructor(t2, s2, r2) {
667
+ this.programLength = t2, this.maxFromByPc = s2, this.maxSurvivorFromByPc = r2;
668
+ }
669
+ static fromProgram(t2) {
670
+ const s2 = t2.length, r2 = [], n = [];
671
+ return t2.forEach((t3) => {
672
+ r2.push(0), n.push(0);
673
+ }), t2.forEach((t3, i2) => {
674
+ switch (t3.op) {
675
+ case 2:
676
+ if (t3.func === null)
677
+ return;
678
+ if (i2 + 1 >= s2)
679
+ throw new Error("Invalid program: program could run past end");
680
+ r2[i2 + 1] += 1;
681
+ break;
682
+ case 1:
683
+ case 4:
684
+ if (i2 + 1 >= s2)
685
+ throw new Error("Invalid program: program could run past end");
686
+ r2[i2 + 1] += 1;
687
+ break;
688
+ case 3:
689
+ t3.data.forEach((t4) => {
690
+ if (t4 < 0 || t4 >= s2)
691
+ throw new Error("Invalid program: program could run past end");
692
+ r2[t4] += 1;
693
+ });
694
+ break;
695
+ case 5:
696
+ if (i2 + 1 >= s2)
697
+ throw new Error("Invalid program: program could run past end");
698
+ n[i2 + 1] += 1;
699
+ break;
700
+ case 0:
701
+ n[i2] += 1;
702
+ }
703
+ }), new i(s2, r2, n);
704
+ }
705
+ static createStub(t2) {
706
+ const s2 = [], r2 = [];
707
+ for (let i2 = 0;i2 < t2; ++i2)
708
+ s2.push(t2), r2.push(t2);
709
+ return new i(t2, s2, r2);
710
+ }
711
+ }
712
+
713
+ class n {
714
+ constructor(t2) {
715
+ this.acceptingTraces = t2, this.success = t2.length > 0;
716
+ }
717
+ }
718
+
719
+ class h {
720
+ constructor(t2) {
721
+ this.t = 0, this.i = 0, this.h = new Uint16Array(t2), this.l = new Uint8Array(t2);
722
+ }
723
+ getBadness(t2) {
724
+ return this.l[t2];
725
+ }
726
+ add(t2, s2) {
727
+ this.l[t2] = s2 > 255 ? 255 : s2;
728
+ const r2 = function(t3, s3, r3, i2, n2) {
729
+ let h2 = i2, e = n2;
730
+ for (;h2 < e; ) {
731
+ const i3 = h2 + e >>> 1;
732
+ r3 < s3[t3[i3]] ? e = i3 : h2 = i3 + 1;
733
+ }
734
+ return h2;
735
+ }(this.h, this.l, s2, this.i, this.t);
736
+ this.h.copyWithin(r2 + 1, r2, this.t), this.h[r2] = t2, this.t += 1;
737
+ }
738
+ reschedule(t2, s2) {
739
+ const r2 = Math.max(this.l[t2], s2 > 255 ? 255 : s2);
740
+ if (this.l[t2] !== r2) {
741
+ const s3 = this.h.indexOf(t2, this.i);
742
+ if (s3 < 0 || s3 >= this.t)
743
+ return void (this.l[t2] = r2);
744
+ this.h.copyWithin(s3, s3 + 1, this.t), this.t -= 1, this.add(t2, r2);
745
+ }
746
+ }
747
+ getNextPc() {
748
+ return this.i >= this.t ? null : this.h[this.i++];
749
+ }
750
+ reset() {
751
+ this.t = 0, this.i = 0, this.l.fill(0);
752
+ }
753
+ }
754
+
755
+ class e {
756
+ constructor(t2) {
757
+ this.o = [];
758
+ let s2 = t2.length;
759
+ t2.forEach((t3) => {
760
+ this.o.push(t3 > 0 ? s2 : -1), s2 += t3;
761
+ }), this.u = new Uint16Array(s2);
762
+ }
763
+ clear() {
764
+ this.u.fill(0, 0, this.o.length);
765
+ }
766
+ add(t2, s2) {
767
+ const r2 = this.u[s2], i2 = this.o[s2];
768
+ this.u[s2] += 1, this.u[i2 + r2] = t2;
769
+ }
770
+ has(t2) {
771
+ return this.u[t2] > 0;
772
+ }
773
+ forEach(t2, s2) {
774
+ const r2 = this.u[t2], i2 = this.o[t2];
775
+ for (let t3 = i2;t3 < i2 + r2; ++t3)
776
+ s2(this.u[t3]);
777
+ }
778
+ }
779
+ function l(t2, s2, r2 = false) {
780
+ return t2 === null ? s2 : Array.isArray(t2) ? (t2.indexOf(s2) === -1 && (r2 && (t2 = t2.slice()), t2.push(s2)), t2) : t2 === s2 ? t2 : [t2, s2];
781
+ }
782
+
783
+ class c {
784
+ constructor(t2, s2) {
785
+ this.prefixes = t2, this.record = s2;
786
+ }
787
+ }
788
+ function o(t2, s2) {
789
+ let r2;
790
+ if (s2 === null) {
791
+ if (!Array.isArray(t2))
792
+ return t2;
793
+ r2 = t2;
794
+ } else
795
+ r2 = t2 === c.EMPTY ? [] : Array.isArray(t2) ? t2 : [t2];
796
+ return new c(r2, s2);
797
+ }
798
+ c.EMPTY = new c([], null);
799
+
800
+ class u {
801
+ constructor(t2) {
802
+ this.p = [], this.v = [];
803
+ for (let s2 = 0;s2 < t2; ++s2)
804
+ this.p.push(0), this.v.push(null);
805
+ }
806
+ mergeTraces(t2, s2, r2, i2, n2, h2) {
807
+ let e2 = false;
808
+ return r2.forEach(s2, (s3) => {
809
+ const r3 = this.trace(s3, i2, n2, h2);
810
+ var c2, o2, u2;
811
+ o2 = r3, u2 = e2, t2 = (c2 = t2) === null ? o2 : o2 === null ? c2 : Array.isArray(o2) ? o2.reduce((t3, s4) => l(t3, s4, t3 === o2), c2) : l(c2, o2, u2), e2 = t2 === r3;
812
+ }), t2;
813
+ }
814
+ trace(t2, s2, r2, i2) {
815
+ switch (this.p[t2]) {
816
+ case 2:
817
+ return this.v[t2];
818
+ case 1:
819
+ return null;
820
+ }
821
+ this.p[t2] = 1;
822
+ let n2 = null;
823
+ const h2 = s2[t2];
824
+ if (h2 !== null)
825
+ n2 = h2;
826
+ else if (!r2.has(t2))
827
+ throw new Error("Trace without source at pc " + t2);
828
+ if (n2 = this.mergeTraces(n2, t2, r2, s2, r2, i2), n2 !== null) {
829
+ const s3 = i2[t2];
830
+ s3 !== null && (n2 = o(n2, s3));
831
+ }
832
+ return this.v[t2] = n2, this.p[t2] = 2, n2;
833
+ }
834
+ buildSurvivorTraces(t2, s2, r2, i2, n2) {
835
+ for (let h2 = 0, e2 = t2.length;h2 < e2; ++h2) {
836
+ if (!r2.has(h2)) {
837
+ s2[h2] = null;
838
+ continue;
839
+ }
840
+ this.v.fill(null), this.p.fill(0);
841
+ const e3 = this.mergeTraces(null, h2, r2, t2, i2, n2);
842
+ if (e3 === null)
843
+ throw new Error("No non-cyclic paths found to survivor " + h2);
844
+ s2[h2] = o(e3, null);
845
+ }
846
+ this.v.fill(null);
847
+ }
848
+ }
849
+
850
+ class a {
851
+ constructor(t2) {
852
+ this.g = [], this.k = [], this.m = [], this.A = new e(t2.maxFromByPc), this.T = new e(t2.maxSurvivorFromByPc), this.S = new u(t2.programLength);
853
+ for (let s2 = 0;s2 < t2.programLength; ++s2)
854
+ this.g.push(null), this.k.push(null), this.m.push(null);
855
+ this.k[0] = c.EMPTY;
856
+ }
857
+ reset(t2) {
858
+ this.A.clear(), this.T.clear(), this.g.fill(null), t2 && (this.k.fill(null), this.m.fill(null), this.k[0] = c.EMPTY);
859
+ }
860
+ record(t2, s2) {
861
+ this.g[t2] = s2;
862
+ }
863
+ has(t2) {
864
+ return this.A.has(t2) || this.k[t2] !== null;
865
+ }
866
+ add(t2, s2) {
867
+ this.A.add(t2, s2);
868
+ }
869
+ hasSurvivor(t2) {
870
+ return this.T.has(t2);
871
+ }
872
+ addSurvivor(t2, s2) {
873
+ this.T.add(t2, s2);
874
+ }
875
+ buildSurvivorTraces() {
876
+ const t2 = this.k;
877
+ this.S.buildSurvivorTraces(t2, this.m, this.T, this.A, this.g), this.k = this.m, this.m = t2;
878
+ }
879
+ getTraces(t2) {
880
+ const s2 = t2.reduce((t3, s3) => l(t3, this.k[s3]), null);
881
+ return s2 === null ? [] : Array.isArray(s2) ? s2 : [s2];
882
+ }
883
+ }
884
+
885
+ class f {
886
+ constructor(t2) {
887
+ this.I = [], this.N = new h(t2.programLength), this.M = new h(t2.programLength), this.P = new a(t2);
888
+ }
889
+ reset() {
890
+ this.N.reset(), this.N.add(0, 0), this.I.length = 0, this.P.reset(true);
891
+ }
892
+ getNextThreadPc() {
893
+ return this.N.getNextPc();
894
+ }
895
+ step(t2, s2, r2) {
896
+ const i2 = this.P.has(s2);
897
+ this.P.add(t2, s2);
898
+ const n2 = this.N.getBadness(t2) + r2;
899
+ i2 ? this.N.reschedule(s2, n2) : this.N.add(s2, n2);
900
+ }
901
+ stepToNextGeneration(t2, s2) {
902
+ const r2 = this.P.hasSurvivor(s2);
903
+ this.P.addSurvivor(t2, s2);
904
+ const i2 = this.N.getBadness(t2);
905
+ r2 ? this.M.reschedule(s2, i2) : this.M.add(s2, i2);
906
+ }
907
+ accept(t2) {
908
+ this.I.push(t2), this.P.addSurvivor(t2, t2);
909
+ }
910
+ fail(t2) {}
911
+ record(t2, s2) {
912
+ this.P.record(t2, s2);
913
+ }
914
+ nextGeneration() {
915
+ this.P.buildSurvivorTraces(), this.P.reset(false);
916
+ const t2 = this.N;
917
+ t2.reset(), this.N = this.M, this.M = t2;
918
+ }
919
+ getAcceptingTraces() {
920
+ return this.P.getTraces(this.I);
921
+ }
922
+ }
923
+
924
+ class d {
925
+ constructor(t2) {
926
+ this.U = [], this.G = t2, this.V = i.fromProgram(t2), this.U.push(new f(this.V));
927
+ }
928
+ execute(t2, s2) {
929
+ const r2 = this.U.pop() || new f(this.V);
930
+ r2.reset();
931
+ const i2 = t2.length;
932
+ let h2, e2 = -1;
933
+ do {
934
+ let n2 = r2.getNextThreadPc();
935
+ if (n2 === null)
936
+ break;
937
+ for (++e2, h2 = e2 >= i2 ? null : t2[e2];n2 !== null; ) {
938
+ const t3 = this.G[n2];
939
+ switch (t3.op) {
940
+ case 0:
941
+ h2 === null ? r2.accept(n2) : r2.fail(n2);
942
+ break;
943
+ case 2: {
944
+ const i3 = t3.func;
945
+ if (i3 === null || i3(s2)) {
946
+ r2.fail(n2);
947
+ break;
948
+ }
949
+ r2.step(n2, n2 + 1, 0);
950
+ break;
951
+ }
952
+ case 1:
953
+ r2.step(n2, n2 + 1, t3.data);
954
+ break;
955
+ case 5:
956
+ if (h2 === null) {
957
+ r2.fail(n2);
958
+ break;
959
+ }
960
+ if (!(0, t3.func)(h2, t3.data, s2)) {
961
+ r2.fail(n2);
962
+ break;
963
+ }
964
+ r2.stepToNextGeneration(n2, n2 + 1);
965
+ break;
966
+ case 3: {
967
+ const s3 = t3.data, i3 = s3.length;
968
+ if (i3 === 0) {
969
+ r2.fail(n2);
970
+ break;
971
+ }
972
+ for (let t4 = 0;t4 < i3; ++t4)
973
+ r2.step(n2, s3[t4], 0);
974
+ break;
975
+ }
976
+ case 4: {
977
+ const i3 = (0, t3.func)(t3.data, e2, s2);
978
+ i3 != null && r2.record(n2, i3), r2.step(n2, n2 + 1, 0);
979
+ break;
980
+ }
981
+ }
982
+ n2 = r2.getNextThreadPc();
983
+ }
984
+ r2.nextGeneration();
985
+ } while (h2 !== null);
986
+ const l2 = new n(r2.getAcceptingTraces());
987
+ return r2.reset(), this.U.push(r2), l2;
988
+ }
989
+ }
990
+ function w(t2) {
991
+ const s2 = new r;
992
+ return t2(s2), new d(s2.program);
993
+ }
994
+
995
+ // ../../node_modules/.bun/xspattern@3.1.0/node_modules/xspattern/dist/xspattern.esm.js
996
+ function B(A) {
997
+ return (B2) => B2 === A;
998
+ }
999
+ function a2(A, B2) {
1000
+ if (A === null || B2 === null)
1001
+ throw new Error("unescaped hyphen may not be used as a range endpoint");
1002
+ if (B2 < A)
1003
+ throw new Error("character range is in the wrong order");
1004
+ return (a3) => A <= a3 && a3 <= B2;
1005
+ }
1006
+ function n2(A) {
1007
+ return true;
1008
+ }
1009
+ function e2() {
1010
+ return false;
1011
+ }
1012
+ function t2(A, B2) {
1013
+ return (a3) => A(a3) || B2(a3);
1014
+ }
1015
+ function G(A, B2) {
1016
+ switch (B2.kind) {
1017
+ case "predicate":
1018
+ return void A.test(B2.value);
1019
+ case "regexp":
1020
+ return void r2(A, B2.value, false);
1021
+ }
1022
+ }
1023
+ function i2(A, B2) {
1024
+ B2.forEach((B3) => {
1025
+ (function(A2, B4) {
1026
+ const [a3, { min: n3, max: e3 }] = B4;
1027
+ if (e3 !== null) {
1028
+ for (let B5 = 0;B5 < n3; ++B5)
1029
+ G(A2, a3);
1030
+ for (let B5 = n3;B5 < e3; ++B5) {
1031
+ const B6 = A2.jump([]);
1032
+ B6.data.push(A2.program.length), G(A2, a3), B6.data.push(A2.program.length);
1033
+ }
1034
+ } else if (n3 > 0) {
1035
+ for (let B6 = 0;B6 < n3 - 1; ++B6)
1036
+ G(A2, a3);
1037
+ const B5 = A2.program.length;
1038
+ G(A2, a3), A2.jump([B5]).data.push(A2.program.length);
1039
+ } else {
1040
+ const B5 = A2.program.length, n4 = A2.jump([]);
1041
+ n4.data.push(A2.program.length), G(A2, a3), A2.jump([B5]), n4.data.push(A2.program.length);
1042
+ }
1043
+ })(A, B3);
1044
+ });
1045
+ }
1046
+ function r2(A, B2, a3) {
1047
+ const n3 = A.program.length, e3 = A.jump([]);
1048
+ a3 && (e3.data.push(A.program.length), A.test(() => true), A.jump([n3]));
1049
+ const t3 = [];
1050
+ if (B2.forEach((B3) => {
1051
+ e3.data.push(A.program.length), i2(A, B3), t3.push(A.jump([]));
1052
+ }), t3.forEach((B3) => {
1053
+ B3.data.push(A.program.length);
1054
+ }), a3) {
1055
+ const B3 = A.program.length, a4 = A.jump([]);
1056
+ a4.data.push(A.program.length), A.test(() => true), A.jump([B3]), a4.data.push(A.program.length);
1057
+ }
1058
+ }
1059
+ function o2(A, B2) {
1060
+ return { success: true, offset: A, value: B2 };
1061
+ }
1062
+ function l2(A) {
1063
+ return o2(A, undefined);
1064
+ }
1065
+ function H(A, B2, a3 = false) {
1066
+ return { success: false, offset: A, expected: B2, fatal: a3 };
1067
+ }
1068
+ function C(A) {
1069
+ return (B2, a3) => {
1070
+ const n3 = a3 + A.length;
1071
+ return B2.slice(a3, n3) === A ? o2(n3, A) : H(a3, [A]);
1072
+ };
1073
+ }
1074
+ function u2(A, B2) {
1075
+ return (a3, n3) => {
1076
+ const e3 = A(a3, n3);
1077
+ return e3.success ? o2(e3.offset, B2(e3.value)) : e3;
1078
+ };
1079
+ }
1080
+ function s2(A, B2, a3, n3) {
1081
+ return (e3, t3) => {
1082
+ const G2 = A(e3, t3);
1083
+ return G2.success ? B2(G2.value) ? G2 : H(t3, a3, n3) : G2;
1084
+ };
1085
+ }
1086
+ function c2(A, B2) {
1087
+ return (a3, n3) => {
1088
+ let e3 = null;
1089
+ for (const t3 of A) {
1090
+ const A2 = t3(a3, n3);
1091
+ if (A2.success)
1092
+ return A2;
1093
+ if (e3 === null || A2.offset > e3.offset ? e3 = A2 : A2.offset === e3.offset && B2 === undefined && (e3.expected = e3.expected.concat(A2.expected)), A2.fatal)
1094
+ return A2;
1095
+ }
1096
+ return B2 = B2 || (e3 == null ? undefined : e3.expected) || [], e3 && (e3.expected = B2), e3 || H(n3, B2);
1097
+ };
1098
+ }
1099
+ function D(A) {
1100
+ return (B2, a3) => {
1101
+ const n3 = A(B2, a3);
1102
+ return n3.success || n3.fatal ? n3 : o2(a3, null);
1103
+ };
1104
+ }
1105
+ function m(A) {
1106
+ return (B2, a3) => {
1107
+ let n3 = [], e3 = a3;
1108
+ for (;; ) {
1109
+ const a4 = A(B2, e3);
1110
+ if (!a4.success) {
1111
+ if (a4.fatal)
1112
+ return a4;
1113
+ break;
1114
+ }
1115
+ if (n3.push(a4.value), a4.offset === e3)
1116
+ break;
1117
+ e3 = a4.offset;
1118
+ }
1119
+ return o2(e3, n3);
1120
+ };
1121
+ }
1122
+ function I(A, B2, a3) {
1123
+ return (n3, e3) => {
1124
+ const t3 = A(n3, e3);
1125
+ if (!t3.success)
1126
+ return t3;
1127
+ const G2 = B2(n3, t3.offset);
1128
+ return G2.success ? o2(G2.offset, a3(t3.value, G2.value)) : G2;
1129
+ };
1130
+ }
1131
+ function d2(A) {
1132
+ return I(A, m(A), (A2, B2) => [A2].concat(B2));
1133
+ }
1134
+ function h2(A, B2) {
1135
+ return A;
1136
+ }
1137
+ function p(A, B2) {
1138
+ return B2;
1139
+ }
1140
+ function T(A, B2) {
1141
+ return I(A, B2, p);
1142
+ }
1143
+ function F(A, B2) {
1144
+ return I(A, B2, h2);
1145
+ }
1146
+ function E(A, B2, a3, n3 = false) {
1147
+ return T(A, n3 ? f2(F(B2, a3)) : F(B2, a3));
1148
+ }
1149
+ function g(A, B2) {
1150
+ return (a3, n3) => A(a3, n3).success ? H(n3, B2) : l2(n3);
1151
+ }
1152
+ function f2(A) {
1153
+ return (B2, a3) => {
1154
+ const n3 = A(B2, a3);
1155
+ return n3.success ? n3 : H(n3.offset, n3.expected, true);
1156
+ };
1157
+ }
1158
+ var P = (A, B2) => A.length === B2 ? l2(B2) : H(B2, ["end of input"]);
1159
+ var M = ["Lu", "Ll", "Lt", "Lm", "Lo", "Mn", "Mc", "Me", "Nd", "Nl", "No", "Pc", "Pd", "Ps", "Pe", "Pi", "Pf", "Po", "Zs", "Zl", "Zp", "Sm", "Sc", "Sk", "So", "Cc", "Cf", "Co", "Cn"];
1160
+ var J = {};
1161
+ function S(A) {
1162
+ return A.codePointAt(0);
1163
+ }
1164
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("").forEach((A, B2) => {
1165
+ J[A] = B2;
1166
+ });
1167
+ var K = (A) => A === -1 || A === -2;
1168
+ function b(A) {
1169
+ return (B2) => !K(B2) && !A(B2);
1170
+ }
1171
+ function y(A, B2) {
1172
+ return B2 === null ? A : (a3) => A(a3) && !B2(a3);
1173
+ }
1174
+ var Q = function(A, B2) {
1175
+ const n3 = new Map;
1176
+ let e3 = 0;
1177
+ return A.forEach((A2, G2) => {
1178
+ const i3 = B2[G2];
1179
+ A2 !== null && A2.split("|").forEach((A3) => {
1180
+ const B3 = n3.get(A3), G3 = a2(e3, e3 + i3 - 1);
1181
+ n3.set(A3, B3 ? t2(B3, G3) : G3);
1182
+ }), e3 += i3;
1183
+ }), n3;
1184
+ }(["BasicLatin", "Latin-1Supplement", "LatinExtended-A", "LatinExtended-B", "IPAExtensions", "SpacingModifierLetters", "CombiningDiacriticalMarks", "GreekandCoptic|Greek", "Cyrillic", "CyrillicSupplement", "Armenian", "Hebrew", "Arabic", "Syriac", "ArabicSupplement", "Thaana", "NKo", "Samaritan", "Mandaic", "SyriacSupplement", "ArabicExtended-B", "ArabicExtended-A", "Devanagari", "Bengali", "Gurmukhi", "Gujarati", "Oriya", "Tamil", "Telugu", "Kannada", "Malayalam", "Sinhala", "Thai", "Lao", "Tibetan", "Myanmar", "Georgian", "HangulJamo", "Ethiopic", "EthiopicSupplement", "Cherokee", "UnifiedCanadianAboriginalSyllabics", "Ogham", "Runic", "Tagalog", "Hanunoo", "Buhid", "Tagbanwa", "Khmer", "Mongolian", "UnifiedCanadianAboriginalSyllabicsExtended", "Limbu", "TaiLe", "NewTaiLue", "KhmerSymbols", "Buginese", "TaiTham", "CombiningDiacriticalMarksExtended", "Balinese", "Sundanese", "Batak", "Lepcha", "OlChiki", "CyrillicExtended-C", "GeorgianExtended", "SundaneseSupplement", "VedicExtensions", "PhoneticExtensions", "PhoneticExtensionsSupplement", "CombiningDiacriticalMarksSupplement", "LatinExtendedAdditional", "GreekExtended", "GeneralPunctuation", "SuperscriptsandSubscripts", "CurrencySymbols", "CombiningDiacriticalMarksforSymbols|CombiningMarksforSymbols", "LetterlikeSymbols", "NumberForms", "Arrows", "MathematicalOperators", "MiscellaneousTechnical", "ControlPictures", "OpticalCharacterRecognition", "EnclosedAlphanumerics", "BoxDrawing", "BlockElements", "GeometricShapes", "MiscellaneousSymbols", "Dingbats", "MiscellaneousMathematicalSymbols-A", "SupplementalArrows-A", "BraillePatterns", "SupplementalArrows-B", "MiscellaneousMathematicalSymbols-B", "SupplementalMathematicalOperators", "MiscellaneousSymbolsandArrows", "Glagolitic", "LatinExtended-C", "Coptic", "GeorgianSupplement", "Tifinagh", "EthiopicExtended", "CyrillicExtended-A", "SupplementalPunctuation", "CJKRadicalsSupplement", "KangxiRadicals", null, "IdeographicDescriptionCharacters", "CJKSymbolsandPunctuation", "Hiragana", "Katakana", "Bopomofo", "HangulCompatibilityJamo", "Kanbun", "BopomofoExtended", "CJKStrokes", "KatakanaPhoneticExtensions", "EnclosedCJKLettersandMonths", "CJKCompatibility", "CJKUnifiedIdeographsExtensionA", "YijingHexagramSymbols", "CJKUnifiedIdeographs", "YiSyllables", "YiRadicals", "Lisu", "Vai", "CyrillicExtended-B", "Bamum", "ModifierToneLetters", "LatinExtended-D", "SylotiNagri", "CommonIndicNumberForms", "Phags-pa", "Saurashtra", "DevanagariExtended", "KayahLi", "Rejang", "HangulJamoExtended-A", "Javanese", "MyanmarExtended-B", "Cham", "MyanmarExtended-A", "TaiViet", "MeeteiMayekExtensions", "EthiopicExtended-A", "LatinExtended-E", "CherokeeSupplement", "MeeteiMayek", "HangulSyllables", "HangulJamoExtended-B", "HighSurrogates", "HighPrivateUseSurrogates", "LowSurrogates", "PrivateUseArea|PrivateUse", "CJKCompatibilityIdeographs", "AlphabeticPresentationForms", "ArabicPresentationForms-A", "VariationSelectors", "VerticalForms", "CombiningHalfMarks", "CJKCompatibilityForms", "SmallFormVariants", "ArabicPresentationForms-B", "HalfwidthandFullwidthForms", "Specials", "LinearBSyllabary", "LinearBIdeograms", "AegeanNumbers", "AncientGreekNumbers", "AncientSymbols", "PhaistosDisc", null, "Lycian", "Carian", "CopticEpactNumbers", "OldItalic", "Gothic", "OldPermic", "Ugaritic", "OldPersian", null, "Deseret", "Shavian", "Osmanya", "Osage", "Elbasan", "CaucasianAlbanian", "Vithkuqi", null, "LinearA", "LatinExtended-F", null, "CypriotSyllabary", "ImperialAramaic", "Palmyrene", "Nabataean", null, "Hatran", "Phoenician", "Lydian", null, "MeroiticHieroglyphs", "MeroiticCursive", "Kharoshthi", "OldSouthArabian", "OldNorthArabian", null, "Manichaean", "Avestan", "InscriptionalParthian", "InscriptionalPahlavi", "PsalterPahlavi", null, "OldTurkic", null, "OldHungarian", "HanifiRohingya", null, "RumiNumeralSymbols", "Yezidi", "ArabicExtended-C", "OldSogdian", "Sogdian", "OldUyghur", "Chorasmian", "Elymaic", "Brahmi", "Kaithi", "SoraSompeng", "Chakma", "Mahajani", "Sharada", "SinhalaArchaicNumbers", "Khojki", null, "Multani", "Khudawadi", "Grantha", null, "Newa", "Tirhuta", null, "Siddham", "Modi", "MongolianSupplement", "Takri", null, "Ahom", null, "Dogra", null, "WarangCiti", "DivesAkuru", null, "Nandinagari", "ZanabazarSquare", "Soyombo", "UnifiedCanadianAboriginalSyllabicsExtended-A", "PauCinHau", "DevanagariExtended-A", null, "Bhaiksuki", "Marchen", null, "MasaramGondi", "GunjalaGondi", null, "Makasar", "Kawi", null, "LisuSupplement", "TamilSupplement", "Cuneiform", "CuneiformNumbersandPunctuation", "EarlyDynasticCuneiform", null, "Cypro-Minoan", "EgyptianHieroglyphs", "EgyptianHieroglyphFormatControls", null, "AnatolianHieroglyphs", null, "BamumSupplement", "Mro", "Tangsa", "BassaVah", "PahawhHmong", null, "Medefaidrin", null, "Miao", null, "IdeographicSymbolsandPunctuation", "Tangut", "TangutComponents", "KhitanSmallScript", "TangutSupplement", null, "KanaExtended-B", "KanaSupplement", "KanaExtended-A", "SmallKanaExtension", "Nushu", null, "Duployan", "ShorthandFormatControls", null, "ZnamennyMusicalNotation", null, "ByzantineMusicalSymbols", "MusicalSymbols", "AncientGreekMusicalNotation", null, "KaktovikNumerals", "MayanNumerals", "TaiXuanJingSymbols", "CountingRodNumerals", null, "MathematicalAlphanumericSymbols", "SuttonSignWriting", null, "LatinExtended-G", "GlagoliticSupplement", "CyrillicExtended-D", null, "NyiakengPuachueHmong", null, "Toto", "Wancho", null, "NagMundari", null, "EthiopicExtended-B", "MendeKikakui", null, "Adlam", null, "IndicSiyaqNumbers", null, "OttomanSiyaqNumbers", null, "ArabicMathematicalAlphabeticSymbols", null, "MahjongTiles", "DominoTiles", "PlayingCards", "EnclosedAlphanumericSupplement", "EnclosedIdeographicSupplement", "MiscellaneousSymbolsandPictographs", "Emoticons", "OrnamentalDingbats", "TransportandMapSymbols", "AlchemicalSymbols", "GeometricShapesExtended", "SupplementalArrows-C", "SupplementalSymbolsandPictographs", "ChessSymbols", "SymbolsandPictographsExtended-A", "SymbolsforLegacyComputing", null, "CJKUnifiedIdeographsExtensionB", null, "CJKUnifiedIdeographsExtensionC", "CJKUnifiedIdeographsExtensionD", "CJKUnifiedIdeographsExtensionE", "CJKUnifiedIdeographsExtensionF", null, "CJKCompatibilityIdeographsSupplement", null, "CJKUnifiedIdeographsExtensionG", "CJKUnifiedIdeographsExtensionH", null, "Tags", null, "VariationSelectorsSupplement", null, "SupplementaryPrivateUseArea-A|PrivateUse", "SupplementaryPrivateUseArea-B|PrivateUse"], [128, 128, 128, 208, 96, 80, 112, 144, 256, 48, 96, 112, 256, 80, 48, 64, 64, 64, 32, 16, 48, 96, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 256, 160, 96, 256, 384, 32, 96, 640, 32, 96, 32, 32, 32, 32, 128, 176, 80, 80, 48, 96, 32, 32, 144, 80, 128, 64, 64, 80, 48, 16, 48, 16, 48, 128, 64, 64, 256, 256, 112, 48, 48, 48, 80, 64, 112, 256, 256, 64, 32, 160, 128, 32, 96, 256, 192, 48, 16, 256, 128, 128, 256, 256, 96, 32, 128, 48, 80, 96, 32, 128, 128, 224, 16, 16, 64, 96, 96, 48, 96, 16, 32, 48, 16, 256, 256, 6592, 64, 20992, 1168, 64, 48, 320, 96, 96, 32, 224, 48, 16, 64, 96, 32, 48, 48, 32, 96, 32, 96, 32, 96, 32, 48, 64, 80, 64, 11184, 80, 896, 128, 1024, 6400, 512, 80, 688, 16, 16, 16, 32, 32, 144, 240, 16, 128, 128, 64, 80, 64, 48, 128, 32, 64, 32, 48, 32, 48, 32, 64, 32, 80, 48, 48, 80, 48, 64, 80, 64, 384, 64, 64, 64, 32, 32, 48, 48, 32, 32, 32, 64, 32, 96, 96, 32, 32, 32, 64, 64, 32, 32, 48, 80, 80, 48, 128, 64, 288, 32, 64, 64, 48, 64, 64, 48, 32, 128, 80, 48, 80, 48, 96, 32, 80, 48, 48, 80, 128, 128, 128, 96, 160, 128, 96, 32, 80, 48, 80, 176, 80, 80, 96, 96, 64, 96, 80, 96, 16, 64, 96, 160, 112, 80, 64, 96, 80, 304, 32, 96, 80, 16, 64, 1024, 128, 208, 2624, 112, 1072, 48, 4000, 640, 8576, 576, 48, 96, 48, 144, 688, 96, 96, 160, 64, 32, 6144, 768, 512, 128, 8816, 16, 256, 48, 64, 400, 2304, 160, 16, 4688, 208, 48, 256, 256, 80, 112, 32, 32, 96, 32, 128, 1024, 688, 1104, 256, 48, 96, 112, 80, 320, 48, 64, 464, 48, 736, 32, 224, 32, 96, 784, 80, 64, 80, 176, 256, 256, 48, 112, 96, 256, 256, 768, 80, 48, 128, 128, 128, 256, 256, 112, 144, 256, 1024, 42720, 32, 4160, 224, 5776, 7488, 3088, 544, 1504, 4944, 4192, 711760, 128, 128, 240, 65040, 65536, 65536]);
1185
+ var x = function(A) {
1186
+ const n3 = new Map, G2 = A.split(""), i3 = M.map(() => []);
1187
+ let r3 = 0, o3 = 0;
1188
+ for (;o3 < G2.length; ) {
1189
+ const A2 = J[G2[o3]], n4 = (31 & A2) - 2;
1190
+ let e3 = 1 + J[G2[o3 + 1]];
1191
+ switch (32 & A2 ? (e3 += J[G2[o3 + 2]] << 6, e3 += J[G2[o3 + 3]] << 12, e3 += J[G2[o3 + 4]] << 18, o3 += 5) : o3 += 2, n4) {
1192
+ case -2: {
1193
+ let A3 = 0;
1194
+ for (let a3 = r3;a3 < r3 + e3; ++a3) {
1195
+ i3[A3].push(B(a3)), A3 = (A3 + 1) % 2;
1196
+ }
1197
+ break;
1198
+ }
1199
+ case -1:
1200
+ break;
1201
+ default: {
1202
+ const A3 = i3[n4];
1203
+ e3 === 1 ? A3.push(B(r3)) : A3.push(a2(r3, r3 + e3 - 1));
1204
+ break;
1205
+ }
1206
+ }
1207
+ r3 += e3;
1208
+ }
1209
+ const l3 = new Map;
1210
+ return M.forEach((A2, B2) => {
1211
+ const a3 = i3[B2].reduce(t2, e2);
1212
+ n3.set(A2, a3);
1213
+ const G3 = A2.charAt(0), r4 = l3.get(G3) || [];
1214
+ l3.set(G3, r4), r4.push(a3);
1215
+ }), l3.forEach((A2, B2) => {
1216
+ n3.set(B2, A2.reduce(t2, e2));
1217
+ }), n3;
1218
+ }("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");
1219
+ function L(A) {
1220
+ return A === 32 || A === 9 || A === 10 || A === 13;
1221
+ }
1222
+ var X = [B(S(":")), a2(S("A"), S("Z")), B(S("_")), a2(S("a"), S("z")), a2(192, 214), a2(216, 246), a2(192, 214), a2(216, 246), a2(248, 767), a2(880, 893), a2(895, 8191), a2(8204, 8205), a2(8304, 8591), a2(11264, 12271), a2(12289, 55295), a2(63744, 64975), a2(65008, 65533), a2(65536, 983039)].reduce(t2);
1223
+ var Z = [X, B(S("-")), B(S(".")), a2(S("0"), S("9")), B(183), a2(768, 879), a2(8255, 8256)].reduce(t2);
1224
+ var O = x.get("Nd");
1225
+ var k = b(O);
1226
+ var N = y(a2(0, 1114111), [x.get("P"), x.get("Z"), x.get("C")].reduce(t2));
1227
+ var v = b(N);
1228
+ function w2(A) {
1229
+ return A !== 10 && A !== 13 && !K(A);
1230
+ }
1231
+ var Y = { s: L, S: b(L), i: X, I: b(X), c: Z, C: b(Z), d: O, D: k, w: N, W: v };
1232
+ var U = C("*");
1233
+ var j = C("\\");
1234
+ var R = C("{");
1235
+ var V = C("}");
1236
+ var W = C("[");
1237
+ var q = C("]");
1238
+ var z = C("^");
1239
+ var $ = C("$");
1240
+ var _ = C(",");
1241
+ var AA = C("-");
1242
+ var BA = C("(");
1243
+ var aA = C(")");
1244
+ var nA = C(".");
1245
+ var eA = C("|");
1246
+ var tA = C("+");
1247
+ var GA = C("?");
1248
+ var iA = C("-[");
1249
+ var rA = S("0");
1250
+ function oA(A) {
1251
+ function e3(A2) {
1252
+ return new Set(A2.split("").map((A3) => S(A3)));
1253
+ }
1254
+ function G2(A2, B2) {
1255
+ const a3 = A2.codePointAt(B2);
1256
+ return a3 === undefined ? H(B2, ["any character"]) : o2(B2 + String.fromCodePoint(a3).length, a3);
1257
+ }
1258
+ const i3 = A.language === "xpath" ? T(j, c2([u2(C("n"), () => 10), u2(C("r"), () => 13), u2(C("t"), () => 9), u2(c2([j, eA, nA, AA, z, GA, U, tA, R, V, $, BA, aA, W, q]), (A2) => S(A2))])) : T(j, c2([u2(C("n"), () => 10), u2(C("r"), () => 13), u2(C("t"), () => 9), u2(c2([j, eA, nA, AA, z, GA, U, tA, R, V, BA, aA, W, q]), (A2) => S(A2))]));
1259
+ function r3(A2, B2) {
1260
+ const a3 = e3(B2);
1261
+ return I(C(A2), D(s2(G2, (A3) => a3.has(A3), B2.split(""))), (A3, B3) => function(A4) {
1262
+ const B4 = x.get(A4);
1263
+ if (B4 == null)
1264
+ throw new Error(A4 + " is not a valid unicode category");
1265
+ return B4;
1266
+ }(B3 === null ? A3 : A3 + String.fromCodePoint(B3)));
1267
+ }
1268
+ const l3 = c2([r3("L", "ultmo"), r3("M", "nce"), r3("N", "dlo"), r3("P", "cdseifo"), r3("Z", "slp"), r3("S", "mcko"), r3("C", "cfon")]), p2 = [a2(S("a"), S("z")), a2(S("A"), S("Z")), a2(S("0"), S("9")), B(45)].reduce(t2), M2 = c2([l3, u2(T(C("Is"), function(A2) {
1269
+ return (B2, a3) => {
1270
+ const n3 = A2(B2, a3);
1271
+ return n3.success ? o2(n3.offset, B2.slice(a3, n3.offset)) : n3;
1272
+ };
1273
+ }(d2(s2(G2, p2, ["block identifier"])))), (B2) => function(A2, B3) {
1274
+ const a3 = Q.get(A2);
1275
+ if (a3 === undefined) {
1276
+ if (B3)
1277
+ return n2;
1278
+ throw new Error(`The unicode block identifier "${A2}" is not known.`);
1279
+ }
1280
+ return a3;
1281
+ }(B2, A.language !== "xpath"))]), J2 = E(C("\\p{"), M2, V, true), K2 = u2(E(C("\\P{"), M2, V, true), b), L2 = T(j, u2(c2("sSiIcCdDwW".split("").map((A2) => C(A2))), (A2) => Y[A2])), X2 = u2(nA, () => w2), Z2 = c2([L2, J2, K2]), O2 = e3("\\[]"), k2 = c2([i3, s2(G2, (A2) => !O2.has(A2), ["unescaped character"])]), N2 = c2([u2(AA, () => null), k2]), v2 = I(N2, T(AA, N2), a2);
1282
+ function oA2(A2, B2) {
1283
+ return [A2].concat(B2 || []);
1284
+ }
1285
+ const lA = u2(function(A2) {
1286
+ return (B2, a3) => {
1287
+ const n3 = A2(B2, a3);
1288
+ return n3.success ? o2(a3, n3.value) : n3;
1289
+ };
1290
+ }(c2([q, iA])), () => null), HA = S("-"), CA = c2([u2(F(F(AA, g(W, ["not ["])), lA), () => HA), T(g(AA, ["not -"]), k2)]), uA = c2([I(u2(CA, B), c2([function(A2, B2) {
1291
+ return uA(A2, B2);
1292
+ }, lA]), oA2), I(c2([v2, Z2]), c2([cA, lA]), oA2)]);
1293
+ const sA = c2([I(u2(k2, B), c2([uA, lA]), oA2), I(c2([v2, Z2]), c2([cA, lA]), oA2)]);
1294
+ function cA(A2, B2) {
1295
+ return sA(A2, B2);
1296
+ }
1297
+ const DA = u2(sA, (A2) => A2.reduce(t2)), mA = u2(T(z, DA), b), IA = I(c2([T(g(z, ["not ^"]), DA), mA]), D(T(AA, function(A2, B2) {
1298
+ return dA(A2, B2);
1299
+ })), y), dA = E(W, IA, q, true);
1300
+ const hA = A.language === "xpath" ? c2([u2(i3, B), Z2, dA, X2, u2(z, () => (A2) => A2 === -1), u2($, () => (A2) => A2 === -2)]) : c2([u2(i3, B), Z2, dA, X2]), pA = A.language === "xpath" ? e3(".\\?*+{}()|^$[]") : e3(".\\?*+{}()|[]"), TA = s2(G2, (A2) => !pA.has(A2), ["NormalChar"]), FA = u2(T(j, I(u2(s2(G2, a2(S("1"), S("9")), ["digit"]), (A2) => A2 - rA), m(u2(s2(G2, a2(rA, S("9")), ["digit"]), (A2) => A2 - rA)), (A2, B2) => {
1301
+ B2.reduce((A3, B3) => 10 * A3 + B3, A2);
1302
+ })), (A2) => {
1303
+ throw new Error("Backreferences in XPath patterns are not yet implemented.");
1304
+ }), EA = A.language === "xpath" ? c2([u2(TA, (A2) => ({ kind: "predicate", value: B(A2) })), u2(hA, (A2) => ({ kind: "predicate", value: A2 })), u2(E(BA, T(D(C("?:")), SA), aA, true), (A2) => ({ kind: "regexp", value: A2 })), FA]) : c2([u2(TA, (A2) => ({ kind: "predicate", value: B(A2) })), u2(hA, (A2) => ({ kind: "predicate", value: A2 })), u2(E(BA, SA, aA, true), (A2) => ({ kind: "regexp", value: A2 }))]), gA = u2(d2(u2(s2(G2, a2(rA, S("9")), ["digit"]), (A2) => A2 - rA)), (A2) => A2.reduce((A3, B2) => 10 * A3 + B2)), fA = c2([I(gA, T(_, gA), (A2, B2) => {
1305
+ if (B2 < A2)
1306
+ throw new Error("quantifier range is in the wrong order");
1307
+ return { min: A2, max: B2 };
1308
+ }), I(gA, _, (A2) => ({ min: A2, max: null })), u2(gA, (A2) => ({ min: A2, max: A2 }))]), PA = A.language === "xpath" ? I(c2([u2(GA, () => ({ min: 0, max: 1 })), u2(U, () => ({ min: 0, max: null })), u2(tA, () => ({ min: 1, max: null })), E(R, fA, V, true)]), D(GA), (A2, B2) => A2) : c2([u2(GA, () => ({ min: 0, max: 1 })), u2(U, () => ({ min: 0, max: null })), u2(tA, () => ({ min: 1, max: null })), E(R, fA, V, true)]), MA = m(I(EA, u2(D(PA), (A2) => A2 === null ? { min: 1, max: 1 } : A2), (A2, B2) => [A2, B2])), JA = I(MA, m(T(eA, f2(MA))), (A2, B2) => [A2].concat(B2));
1309
+ function SA(A2, B2) {
1310
+ return JA(A2, B2);
1311
+ }
1312
+ const KA = function(A2) {
1313
+ return I(A2, P, h2);
1314
+ }(JA);
1315
+ return function(A2) {
1316
+ let B2;
1317
+ try {
1318
+ B2 = KA(A2, 0);
1319
+ } catch (B3) {
1320
+ throw new Error(`Error parsing pattern "${A2}": ${B3 instanceof Error ? B3.message : B3}`);
1321
+ }
1322
+ return B2.success ? B2.value : function(A3, B3, a3) {
1323
+ const n3 = a3.map((A4) => `"${A4}"`);
1324
+ throw new Error(`Error parsing pattern "${A3}" at offset ${B3}: expected ${n3.length > 1 ? "one of " + n3.join(", ") : n3[0]} but found "${A3.slice(B3, B3 + 1)}"`);
1325
+ }(A2, B2.offset, B2.expected);
1326
+ };
1327
+ }
1328
+ function lA(A) {
1329
+ return [...A].map((A2) => A2.codePointAt(0));
1330
+ }
1331
+ function HA(B2, a3 = { language: "xsd" }) {
1332
+ const n3 = oA(a3)(B2), e3 = w((A) => {
1333
+ r2(A, n3, a3.language === "xpath"), A.accept();
1334
+ });
1335
+ return function(A) {
1336
+ const B3 = a3.language === "xpath" ? [-1, ...lA(A), -2] : lA(A);
1337
+ return e3.execute(B3).success;
1338
+ };
1339
+ }
1340
+
1341
+ // src/response-processing.ts
1342
+ function foldString(value) {
1343
+ return value.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLocaleLowerCase();
1344
+ }
1345
+ function asList(response) {
1346
+ if (response === null) {
1347
+ return [];
1348
+ }
1349
+ return typeof response === "string" ? [response] : Array.isArray(response) ? [...response] : [];
1350
+ }
1351
+ function isStringBaseType(declaration) {
1352
+ return declaration.baseType === "string" || declaration.baseType === undefined;
1353
+ }
1354
+ function pairsEqual(a3, b2, directed) {
1355
+ const [a1, a22] = a3.trim().split(/\s+/u);
1356
+ const [b1, b22] = b2.trim().split(/\s+/u);
1357
+ if (a1 === undefined || a22 === undefined || b1 === undefined || b22 === undefined) {
1358
+ return false;
1359
+ }
1360
+ if (a1 === b1 && a22 === b22) {
1361
+ return true;
1362
+ }
1363
+ return !directed && a1 === b22 && a22 === b1;
1364
+ }
1365
+ var numericBaseTypes = new Set(["float", "integer"]);
1366
+ function makeValueComparator(declaration, normalize) {
1367
+ if (declaration.baseType === "pair") {
1368
+ return (a3, b2) => pairsEqual(a3, b2, false);
1369
+ }
1370
+ if (declaration.baseType === "directedPair") {
1371
+ return (a3, b2) => pairsEqual(a3, b2, true);
1372
+ }
1373
+ if (declaration.baseType !== undefined && numericBaseTypes.has(declaration.baseType)) {
1374
+ return (a3, b2) => a3.trim() !== "" && b2.trim() !== "" && Number(a3) === Number(b2);
1375
+ }
1376
+ if (declaration.baseType === "point") {
1377
+ return (a3, b2) => {
1378
+ const pointA = parsePoint(a3);
1379
+ const pointB = parsePoint(b2);
1380
+ return pointA !== null && pointB !== null && pointA.x === pointB.x && pointA.y === pointB.y;
1381
+ };
1382
+ }
1383
+ if (normalize && isStringBaseType(declaration)) {
1384
+ return (a3, b2) => normalize(a3, declaration) === normalize(b2, declaration);
1385
+ }
1386
+ return (a3, b2) => a3 === b2;
1387
+ }
1388
+ function matchCorrect(declaration, response, normalize) {
1389
+ const correct = declaration.correctResponse;
1390
+ if (!correct) {
1391
+ return false;
1392
+ }
1393
+ const equals = makeValueComparator(declaration, normalize);
1394
+ const expected = correct.values.map((entry) => entry.value);
1395
+ const actual = asList(response);
1396
+ if (expected.length !== actual.length) {
1397
+ return false;
1398
+ }
1399
+ if (declaration.cardinality === "ordered") {
1400
+ return expected.every((value, index) => equals(value, actual[index] ?? ""));
1401
+ }
1402
+ const remaining = [...actual];
1403
+ for (const value of expected) {
1404
+ const matchIndex = remaining.findIndex((candidate) => equals(candidate, value));
1405
+ if (matchIndex === -1) {
1406
+ return false;
1407
+ }
1408
+ remaining.splice(matchIndex, 1);
1409
+ }
1410
+ return remaining.length === 0;
1411
+ }
1412
+ function clamp(value, lower, upper) {
1413
+ let result = value;
1414
+ if (lower !== undefined && result < lower) {
1415
+ result = lower;
1416
+ }
1417
+ if (upper !== undefined && result > upper) {
1418
+ result = upper;
1419
+ }
1420
+ return result;
1421
+ }
1422
+ function mapResponse(declaration, response, normalize) {
1423
+ const mapping = declaration.mapping;
1424
+ if (!mapping) {
1425
+ return 0;
1426
+ }
1427
+ const isPairType = declaration.baseType === "pair" || declaration.baseType === "directedPair";
1428
+ const applyNormalize = normalize && isStringBaseType(declaration) ? normalize : undefined;
1429
+ const defaultValue = mapping.defaultValue ?? 0;
1430
+ let total = 0;
1431
+ for (const member of asList(response)) {
1432
+ const entry = mapping.mapEntries.find((candidate) => {
1433
+ if (isPairType) {
1434
+ return pairsEqual(candidate.mapKey, member, declaration.baseType === "directedPair");
1435
+ }
1436
+ let key = candidate.mapKey;
1437
+ let candidateMember = member;
1438
+ if (candidate.caseSensitive === false) {
1439
+ key = key.toLocaleLowerCase();
1440
+ candidateMember = candidateMember.toLocaleLowerCase();
1441
+ }
1442
+ if (applyNormalize) {
1443
+ key = applyNormalize(key, declaration);
1444
+ candidateMember = applyNormalize(candidateMember, declaration);
1445
+ }
1446
+ return key === candidateMember;
1447
+ });
1448
+ total += entry ? entry.mappedValue : defaultValue;
1449
+ }
1450
+ return clamp(total, mapping.lowerBound, mapping.upperBound);
1451
+ }
1452
+ function mapResponsePoint(declaration, response) {
1453
+ const areaMapping = declaration.areaMapping;
1454
+ if (!areaMapping) {
1455
+ return 0;
1456
+ }
1457
+ const defaultValue = areaMapping.defaultValue ?? 0;
1458
+ const usedAreas = new Set;
1459
+ let total = 0;
1460
+ for (const member of asList(response)) {
1461
+ const point = parsePoint(member);
1462
+ if (!point) {
1463
+ continue;
1464
+ }
1465
+ const areaIndex = areaMapping.areaMapEntries.findIndex((entry, index) => !usedAreas.has(index) && pointInShape(entry.shape, entry.coords, point));
1466
+ if (areaIndex === -1) {
1467
+ total += defaultValue;
1468
+ } else {
1469
+ usedAreas.add(areaIndex);
1470
+ total += areaMapping.areaMapEntries[areaIndex].mappedValue;
1471
+ }
1472
+ }
1473
+ return clamp(total, areaMapping.lowerBound, areaMapping.upperBound);
1474
+ }
1475
+ function scoreResponse(declaration, response, normalize) {
1476
+ if (declaration.areaMapping) {
1477
+ const score = mapResponsePoint(declaration, response);
1478
+ const positiveSum = declaration.areaMapping.areaMapEntries.reduce((sum, entry) => sum + Math.max(entry.mappedValue, 0), 0);
1479
+ const maxScore = declaration.areaMapping.upperBound ?? positiveSum;
1480
+ return {
1481
+ identifier: declaration.identifier,
1482
+ score,
1483
+ maxScore,
1484
+ correct: maxScore > 0 && score >= maxScore
1485
+ };
1486
+ }
1487
+ if (declaration.mapping) {
1488
+ const score = mapResponse(declaration, response, normalize);
1489
+ const positiveSum = declaration.mapping.mapEntries.reduce((sum, entry) => sum + Math.max(entry.mappedValue, 0), 0);
1490
+ const maxScore = declaration.mapping.upperBound ?? positiveSum;
1491
+ return {
1492
+ identifier: declaration.identifier,
1493
+ score,
1494
+ maxScore,
1495
+ correct: maxScore > 0 && score >= maxScore
1496
+ };
1497
+ }
1498
+ const correct = matchCorrect(declaration, response, normalize);
1499
+ return {
1500
+ identifier: declaration.identifier,
1501
+ score: correct ? 1 : 0,
1502
+ maxScore: 1,
1503
+ correct
1504
+ };
1505
+ }
1506
+
1507
+ // src/types.ts
1508
+ function isResponseRecord(value) {
1509
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1510
+ }
1511
+
1512
+ // src/rp/values.ts
1513
+ var numericBaseTypes2 = new Set(["float", "integer", "duration"]);
1514
+ function isNumericBaseType(baseType) {
1515
+ return baseType !== undefined && numericBaseTypes2.has(baseType);
1516
+ }
1517
+ function coerceScalar(value, baseType) {
1518
+ if (isNumericBaseType(baseType) && typeof value === "string" && value.trim() !== "") {
1519
+ const parsed = Number(value);
1520
+ if (!Number.isNaN(parsed)) {
1521
+ return parsed;
1522
+ }
1523
+ }
1524
+ if (baseType === "boolean" && typeof value === "string") {
1525
+ return value === "true";
1526
+ }
1527
+ return value;
1528
+ }
1529
+ function fieldBaseType(value) {
1530
+ return typeof value === "boolean" ? "boolean" : typeof value === "number" ? "float" : "string";
1531
+ }
1532
+ function fromResponse(declaration, response) {
1533
+ if (response === null) {
1534
+ return null;
1535
+ }
1536
+ if (isResponseRecord(response)) {
1537
+ const fields = Object.entries(response).flatMap(([name, member]) => member === null ? [] : [{ name, baseType: fieldBaseType(member), value: member }]);
1538
+ return fields.length === 0 ? null : { cardinality: "record", fields, values: fields.map((field) => field.value) };
1539
+ }
1540
+ const raw = typeof response === "string" ? [response] : [...response];
1541
+ if (raw.length === 0) {
1542
+ return null;
1543
+ }
1544
+ return rpValue(declaration.cardinality, raw.map((value) => coerceScalar(value, declaration.baseType)), declaration.baseType);
1545
+ }
1546
+ function singleNumber(value) {
1547
+ if (value === null || value.values.length !== 1) {
1548
+ return null;
1549
+ }
1550
+ const member = value.values[0];
1551
+ return typeof member === "number" ? member : null;
1552
+ }
1553
+ function singleBoolean(value) {
1554
+ if (value === null || value.values.length !== 1) {
1555
+ return null;
1556
+ }
1557
+ const member = value.values[0];
1558
+ return typeof member === "boolean" ? member : null;
1559
+ }
1560
+ function rpValue(cardinality, values, baseType) {
1561
+ return {
1562
+ cardinality,
1563
+ values,
1564
+ ...baseType !== undefined ? { baseType } : {}
1565
+ };
1566
+ }
1567
+ function booleanValue(value) {
1568
+ return { cardinality: "single", baseType: "boolean", values: [value] };
1569
+ }
1570
+ function floatValue(value) {
1571
+ return { cardinality: "single", baseType: "float", values: [value] };
1572
+ }
1573
+ function pairsEqual2(a3, b2, directed) {
1574
+ const [a1, a22] = a3.trim().split(/\s+/u);
1575
+ const [b1, b22] = b2.trim().split(/\s+/u);
1576
+ if (a1 === undefined || a22 === undefined || b1 === undefined || b22 === undefined) {
1577
+ return false;
1578
+ }
1579
+ if (a1 === b1 && a22 === b22) {
1580
+ return true;
1581
+ }
1582
+ return !directed && a1 === b22 && a22 === b1;
1583
+ }
1584
+ function scalarsEqual(a3, b2, baseType, normalize) {
1585
+ if (baseType === "pair" || baseType === "directedPair") {
1586
+ return typeof a3 === "string" && typeof b2 === "string" && pairsEqual2(a3, b2, baseType === "directedPair");
1587
+ }
1588
+ if (baseType === "point") {
1589
+ if (typeof a3 !== "string" || typeof b2 !== "string") {
1590
+ return false;
1591
+ }
1592
+ const pointA = parsePoint(a3);
1593
+ const pointB = parsePoint(b2);
1594
+ return pointA !== null && pointB !== null && pointA.x === pointB.x && pointA.y === pointB.y;
1595
+ }
1596
+ if (typeof a3 === "number" || typeof b2 === "number") {
1597
+ return Number(a3) === Number(b2);
1598
+ }
1599
+ if (normalize && baseType === "string" && typeof a3 === "string" && typeof b2 === "string") {
1600
+ return normalize(a3) === normalize(b2);
1601
+ }
1602
+ return a3 === b2;
1603
+ }
1604
+ function valuesMatch(a3, b2, normalize) {
1605
+ const baseType = a3.baseType ?? b2.baseType;
1606
+ if (a3.values.length !== b2.values.length) {
1607
+ return false;
1608
+ }
1609
+ if (a3.cardinality === "ordered" || b2.cardinality === "ordered") {
1610
+ return a3.values.every((value, index) => scalarsEqual(value, b2.values[index], baseType, normalize));
1611
+ }
1612
+ const remaining = [...b2.values];
1613
+ for (const value of a3.values) {
1614
+ const matchIndex = remaining.findIndex((candidate) => scalarsEqual(candidate, value, baseType, normalize));
1615
+ if (matchIndex === -1) {
1616
+ return false;
1617
+ }
1618
+ remaining.splice(matchIndex, 1);
1619
+ }
1620
+ return true;
1621
+ }
1622
+ function fromFlatValue(value, cardinality, baseType) {
1623
+ if (value === null) {
1624
+ return null;
1625
+ }
1626
+ const values = Array.isArray(value) ? [...value] : [value];
1627
+ if (values.length === 0) {
1628
+ return null;
1629
+ }
1630
+ return rpValue(cardinality, values.map((member) => coerceScalar(member, baseType)), baseType);
1631
+ }
1632
+ function toOutcomeValue(value) {
1633
+ if (value === null || value.values.length === 0) {
1634
+ return null;
1635
+ }
1636
+ if (value.cardinality === "single") {
1637
+ return value.values[0] ?? null;
1638
+ }
1639
+ return value.values;
1640
+ }
1641
+
1642
+ // src/rp/evaluate.ts
1643
+ var deterministicExpressionKinds = new Set([
1644
+ "and",
1645
+ "anyN",
1646
+ "baseValue",
1647
+ "containerSize",
1648
+ "contains",
1649
+ "correct",
1650
+ "default",
1651
+ "delete",
1652
+ "divide",
1653
+ "durationGte",
1654
+ "durationLt",
1655
+ "equal",
1656
+ "equalRounded",
1657
+ "fieldValue",
1658
+ "gcd",
1659
+ "gt",
1660
+ "gte",
1661
+ "index",
1662
+ "inside",
1663
+ "lcm",
1664
+ "integerDivide",
1665
+ "integerModulus",
1666
+ "integerToFloat",
1667
+ "isNull",
1668
+ "lt",
1669
+ "lte",
1670
+ "mapResponse",
1671
+ "mapResponsePoint",
1672
+ "match",
1673
+ "mathConstant",
1674
+ "mathOperator",
1675
+ "max",
1676
+ "member",
1677
+ "min",
1678
+ "multiple",
1679
+ "not",
1680
+ "null",
1681
+ "or",
1682
+ "ordered",
1683
+ "patternMatch",
1684
+ "power",
1685
+ "product",
1686
+ "repeat",
1687
+ "round",
1688
+ "roundTo",
1689
+ "statsOperator",
1690
+ "stringMatch",
1691
+ "substring",
1692
+ "subtract",
1693
+ "sum",
1694
+ "truncate",
1695
+ "variable"
1696
+ ]);
1697
+ var randomExpressionKinds = new Set(["random", "randomFloat", "randomInteger"]);
1698
+
1699
+ class RpUnsupportedError extends Error {
1700
+ kindName;
1701
+ constructor(kindName) {
1702
+ super(`Unsupported response-processing construct: ${kindName}`);
1703
+ this.kindName = kindName;
1704
+ }
1705
+ }
1706
+ var mathConstants = { pi: Math.PI, e: Math.E };
1707
+ var xsdPatternMatchers = new Map;
1708
+ function xsdPatternMatcher(pattern) {
1709
+ const cached = xsdPatternMatchers.get(pattern);
1710
+ if (cached !== undefined) {
1711
+ return cached;
1712
+ }
1713
+ let matcher;
1714
+ try {
1715
+ matcher = HA(pattern);
1716
+ } catch {
1717
+ matcher = null;
1718
+ }
1719
+ xsdPatternMatchers.set(pattern, matcher);
1720
+ return matcher;
1721
+ }
1722
+ var encVariableStringPattern = /^\{[^{}]+\}$/u;
1723
+ function applyMathOperator(name, x2, y2) {
1724
+ switch (name) {
1725
+ case "sin":
1726
+ return Math.sin(x2);
1727
+ case "cos":
1728
+ return Math.cos(x2);
1729
+ case "tan":
1730
+ return Math.tan(x2);
1731
+ case "sec":
1732
+ return 1 / Math.cos(x2);
1733
+ case "csc":
1734
+ return 1 / Math.sin(x2);
1735
+ case "cot":
1736
+ return Math.cos(x2) / Math.sin(x2);
1737
+ case "asin":
1738
+ return Math.asin(x2);
1739
+ case "acos":
1740
+ return Math.acos(x2);
1741
+ case "atan":
1742
+ return Math.atan(x2);
1743
+ case "atan2":
1744
+ return Math.atan2(x2, y2);
1745
+ case "asec":
1746
+ return Math.acos(1 / x2);
1747
+ case "acsc":
1748
+ return Math.asin(1 / x2);
1749
+ case "acot":
1750
+ return Math.atan(1 / x2);
1751
+ case "sinh":
1752
+ return Math.sinh(x2);
1753
+ case "cosh":
1754
+ return Math.cosh(x2);
1755
+ case "tanh":
1756
+ return Math.tanh(x2);
1757
+ case "sech":
1758
+ return 1 / Math.cosh(x2);
1759
+ case "csch":
1760
+ return 1 / Math.sinh(x2);
1761
+ case "coth":
1762
+ return Math.cosh(x2) / Math.sinh(x2);
1763
+ case "log":
1764
+ return Math.log10(x2);
1765
+ case "ln":
1766
+ return Math.log(x2);
1767
+ case "exp":
1768
+ return Math.exp(x2);
1769
+ case "abs":
1770
+ return Math.abs(x2);
1771
+ case "signum":
1772
+ return Math.sign(x2);
1773
+ case "floor":
1774
+ return Math.floor(x2);
1775
+ case "ceil":
1776
+ return Math.ceil(x2);
1777
+ case "toDegrees":
1778
+ return x2 * 180 / Math.PI;
1779
+ case "toRadians":
1780
+ return x2 * Math.PI / 180;
1781
+ default:
1782
+ return;
1783
+ }
1784
+ }
1785
+ function resolveNumericAttribute(raw, env) {
1786
+ if (raw === undefined) {
1787
+ return;
1788
+ }
1789
+ if (typeof raw === "number") {
1790
+ return raw;
1791
+ }
1792
+ const identifier = raw.startsWith("{") && raw.endsWith("}") ? raw.slice(1, -1) : raw;
1793
+ return singleNumber(env.lookupVariable(identifier));
1794
+ }
1795
+ function roundToFigures(value, mode, figures) {
1796
+ if (mode === "decimalPlaces") {
1797
+ const scale2 = 10 ** figures;
1798
+ return Math.round(value * scale2) / scale2;
1799
+ }
1800
+ if (figures < 1) {
1801
+ return null;
1802
+ }
1803
+ if (value === 0) {
1804
+ return 0;
1805
+ }
1806
+ const magnitude = Math.floor(Math.log10(Math.abs(value)));
1807
+ const scale = 10 ** (figures - 1 - magnitude);
1808
+ return Math.round(value * scale) / scale;
1809
+ }
1810
+ function evaluateExpression(expression, env) {
1811
+ function evaluate(child) {
1812
+ return evaluateExpression(child, env);
1813
+ }
1814
+ switch (expression.kind) {
1815
+ case "baseValue": {
1816
+ const baseType = expression.baseType;
1817
+ const value = expression.value;
1818
+ return value === undefined ? null : rpValue("single", [coerceScalar(value, baseType)], baseType);
1819
+ }
1820
+ case "variable":
1821
+ return env.lookupVariable(expression.identifier ?? "");
1822
+ case "correct": {
1823
+ const declaration = env.responseDeclaration(expression.identifier ?? "");
1824
+ if (!declaration?.correctResponse) {
1825
+ return null;
1826
+ }
1827
+ return rpValue(declaration.cardinality, declaration.correctResponse.values.map((entry) => coerceScalar(entry.value, declaration.baseType)), declaration.baseType);
1828
+ }
1829
+ case "mapResponse": {
1830
+ const identifier = expression.identifier ?? "";
1831
+ const declaration = env.responseDeclaration(identifier);
1832
+ if (!declaration) {
1833
+ return null;
1834
+ }
1835
+ return floatValue(mapResponse(declaration, env.responseValue(identifier), env.normalization));
1836
+ }
1837
+ case "mapResponsePoint": {
1838
+ const identifier = expression.identifier ?? "";
1839
+ const declaration = env.responseDeclaration(identifier);
1840
+ if (!declaration) {
1841
+ return null;
1842
+ }
1843
+ return floatValue(mapResponsePoint(declaration, env.responseValue(identifier)));
1844
+ }
1845
+ case "match": {
1846
+ const [a3, b2] = (expression.expressions ?? []).map(evaluate);
1847
+ if (a3 === undefined || b2 === undefined || a3 === null || b2 === null) {
1848
+ return null;
1849
+ }
1850
+ return booleanValue(valuesMatch(a3, b2, env.normalization));
1851
+ }
1852
+ case "isNull": {
1853
+ const operand = expression.expressions?.[0];
1854
+ return booleanValue(operand === undefined || evaluate(operand) === null);
1855
+ }
1856
+ case "not": {
1857
+ const operand = expression.expressions?.[0];
1858
+ const value = operand === undefined ? null : singleBoolean(evaluate(operand));
1859
+ return value === null ? null : booleanValue(!value);
1860
+ }
1861
+ case "fieldValue": {
1862
+ const operand = expression.expressions?.[0];
1863
+ const value = operand === undefined ? null : evaluate(operand);
1864
+ const field = value?.fields?.find((entry) => entry.name === expression.fieldIdentifier);
1865
+ return field === undefined ? null : rpValue("single", [field.value], field.baseType);
1866
+ }
1867
+ case "and":
1868
+ case "or": {
1869
+ const members = (expression.expressions ?? []).map((child) => singleBoolean(evaluate(child)));
1870
+ if (expression.kind === "and") {
1871
+ if (members.some((member) => member === false)) {
1872
+ return booleanValue(false);
1873
+ }
1874
+ return members.some((member) => member === null) ? null : booleanValue(true);
1875
+ }
1876
+ if (members.some((member) => member === true)) {
1877
+ return booleanValue(true);
1878
+ }
1879
+ return members.some((member) => member === null) ? null : booleanValue(false);
1880
+ }
1881
+ case "sum":
1882
+ case "product": {
1883
+ let result = expression.kind === "sum" ? 0 : 1;
1884
+ for (const child of expression.expressions ?? []) {
1885
+ const value = evaluate(child);
1886
+ if (value === null) {
1887
+ return null;
1888
+ }
1889
+ for (const member of value.values) {
1890
+ if (typeof member !== "number") {
1891
+ return null;
1892
+ }
1893
+ result = expression.kind === "sum" ? result + member : result * member;
1894
+ }
1895
+ }
1896
+ return floatValue(result);
1897
+ }
1898
+ case "subtract":
1899
+ case "divide": {
1900
+ const [a3, b2] = (expression.expressions ?? []).map((child) => singleNumber(evaluate(child)));
1901
+ if (a3 === undefined || b2 === undefined || a3 === null || b2 === null) {
1902
+ return null;
1903
+ }
1904
+ if (expression.kind === "divide") {
1905
+ return b2 === 0 ? null : floatValue(a3 / b2);
1906
+ }
1907
+ return floatValue(a3 - b2);
1908
+ }
1909
+ case "gt":
1910
+ case "gte":
1911
+ case "lt":
1912
+ case "lte": {
1913
+ const [a3, b2] = (expression.expressions ?? []).map((child) => singleNumber(evaluate(child)));
1914
+ if (a3 === undefined || b2 === undefined || a3 === null || b2 === null) {
1915
+ return null;
1916
+ }
1917
+ const comparisons = { gt: a3 > b2, gte: a3 >= b2, lt: a3 < b2, lte: a3 <= b2 };
1918
+ return booleanValue(comparisons[expression.kind]);
1919
+ }
1920
+ case "equal": {
1921
+ const [a3, b2] = (expression.expressions ?? []).map((child) => singleNumber(evaluate(child)));
1922
+ if (a3 === undefined || b2 === undefined || a3 === null || b2 === null) {
1923
+ return null;
1924
+ }
1925
+ const mode = expression.toleranceMode ?? "exact";
1926
+ if (mode === "exact") {
1927
+ return booleanValue(a3 === b2);
1928
+ }
1929
+ const t0 = resolveNumericAttribute(expression.tolerance?.[0], env);
1930
+ const t1raw = expression.tolerance?.[1];
1931
+ const t1 = t1raw === undefined ? t0 : resolveNumericAttribute(t1raw, env);
1932
+ if (typeof t0 !== "number" || typeof t1 !== "number") {
1933
+ return null;
1934
+ }
1935
+ const lower = mode === "absolute" ? a3 - t0 : a3 * (1 - t0 / 100);
1936
+ const upper = mode === "absolute" ? a3 + t1 : a3 * (1 + t1 / 100);
1937
+ const aboveLower = expression.includeLowerBound ?? true ? b2 >= lower : b2 > lower;
1938
+ const belowUpper = expression.includeUpperBound ?? true ? b2 <= upper : b2 < upper;
1939
+ return booleanValue(aboveLower && belowUpper);
1940
+ }
1941
+ case "round":
1942
+ case "truncate": {
1943
+ const operand = expression.expressions?.[0];
1944
+ const value = operand === undefined ? null : singleNumber(evaluate(operand));
1945
+ if (value === null) {
1946
+ return null;
1947
+ }
1948
+ const rounded = expression.kind === "round" ? Math.round(value) : Math.trunc(value);
1949
+ return { cardinality: "single", baseType: "integer", values: [rounded] };
1950
+ }
1951
+ case "index": {
1952
+ const n3 = resolveNumericAttribute(expression.n, env);
1953
+ if (typeof n3 !== "number") {
1954
+ return null;
1955
+ }
1956
+ const operand = expression.expressions?.[0];
1957
+ const container = operand === undefined ? null : evaluate(operand);
1958
+ if (container === null) {
1959
+ return null;
1960
+ }
1961
+ const member = container.values[n3 - 1];
1962
+ if (member === undefined) {
1963
+ return null;
1964
+ }
1965
+ return rpValue("single", [member], container.baseType);
1966
+ }
1967
+ case "mathConstant": {
1968
+ const constant = expression.name === undefined ? undefined : mathConstants[expression.name];
1969
+ if (constant === undefined) {
1970
+ throw new RpUnsupportedError("mathConstant");
1971
+ }
1972
+ return floatValue(constant);
1973
+ }
1974
+ case "mathOperator": {
1975
+ const [x2, y2] = (expression.expressions ?? []).map((child) => singleNumber(evaluate(child)));
1976
+ if (x2 === undefined || x2 === null || expression.name === "atan2" && (y2 === undefined || y2 === null)) {
1977
+ return null;
1978
+ }
1979
+ const result = expression.name === undefined ? undefined : applyMathOperator(expression.name, x2, y2 ?? NaN);
1980
+ if (result === undefined) {
1981
+ throw new RpUnsupportedError("mathOperator");
1982
+ }
1983
+ return Number.isFinite(result) ? floatValue(result) : null;
1984
+ }
1985
+ case "integerDivide":
1986
+ case "integerModulus": {
1987
+ const [a3, b2] = (expression.expressions ?? []).map((child) => singleNumber(evaluate(child)));
1988
+ if (a3 === undefined || b2 === undefined || a3 === null || b2 === null || b2 === 0) {
1989
+ return null;
1990
+ }
1991
+ const result = expression.kind === "integerDivide" ? Math.trunc(a3 / b2) : a3 % b2;
1992
+ return { cardinality: "single", baseType: "integer", values: [result] };
1993
+ }
1994
+ case "integerToFloat": {
1995
+ const operand = expression.expressions?.[0];
1996
+ const value = operand === undefined ? null : singleNumber(evaluate(operand));
1997
+ return value === null ? null : floatValue(value);
1998
+ }
1999
+ case "min":
2000
+ case "max": {
2001
+ const members = [];
2002
+ for (const child of expression.expressions ?? []) {
2003
+ const value = evaluate(child);
2004
+ if (value === null) {
2005
+ return null;
2006
+ }
2007
+ for (const member of value.values) {
2008
+ if (typeof member !== "number") {
2009
+ return null;
2010
+ }
2011
+ members.push(member);
2012
+ }
2013
+ }
2014
+ if (members.length === 0) {
2015
+ return null;
2016
+ }
2017
+ return floatValue(expression.kind === "min" ? Math.min(...members) : Math.max(...members));
2018
+ }
2019
+ case "gcd":
2020
+ case "lcm": {
2021
+ const members = [];
2022
+ for (const child of expression.expressions ?? []) {
2023
+ const value = evaluate(child);
2024
+ if (value === null) {
2025
+ return null;
2026
+ }
2027
+ for (const member of value.values) {
2028
+ if (typeof member !== "number" || !Number.isInteger(member)) {
2029
+ return null;
2030
+ }
2031
+ members.push(Math.abs(member));
2032
+ }
2033
+ }
2034
+ if (members.length === 0) {
2035
+ return null;
2036
+ }
2037
+ const gcdOf = (a3, b2) => b2 === 0 ? a3 : gcdOf(b2, a3 % b2);
2038
+ const result = expression.kind === "gcd" ? members.reduce(gcdOf) : members.reduce((a3, b2) => a3 === 0 || b2 === 0 ? 0 : a3 / gcdOf(a3, b2) * b2);
2039
+ return { cardinality: "single", baseType: "integer", values: [result] };
2040
+ }
2041
+ case "roundTo": {
2042
+ const figures = resolveNumericAttribute(expression.figures, env);
2043
+ if (typeof figures !== "number") {
2044
+ return null;
2045
+ }
2046
+ const operand = expression.expressions?.[0];
2047
+ const value = operand === undefined ? null : singleNumber(evaluate(operand));
2048
+ if (value === null) {
2049
+ return null;
2050
+ }
2051
+ const rounded = roundToFigures(value, expression.roundingMode ?? "significantFigures", figures);
2052
+ return rounded === null ? null : floatValue(rounded);
2053
+ }
2054
+ case "equalRounded": {
2055
+ const figures = resolveNumericAttribute(expression.figures, env);
2056
+ if (typeof figures !== "number") {
2057
+ return null;
2058
+ }
2059
+ const [a3, b2] = (expression.expressions ?? []).map((child) => singleNumber(evaluate(child)));
2060
+ if (a3 === undefined || b2 === undefined || a3 === null || b2 === null) {
2061
+ return null;
2062
+ }
2063
+ const mode = expression.roundingMode ?? "significantFigures";
2064
+ const roundedA = roundToFigures(a3, mode, figures);
2065
+ const roundedB = roundToFigures(b2, mode, figures);
2066
+ return roundedA === null || roundedB === null ? null : booleanValue(roundedA === roundedB);
2067
+ }
2068
+ case "statsOperator": {
2069
+ const operand = expression.expressions?.[0];
2070
+ const container = operand === undefined ? null : evaluate(operand);
2071
+ if (container === null) {
2072
+ return null;
2073
+ }
2074
+ const members = [];
2075
+ for (const member of container.values) {
2076
+ if (typeof member !== "number") {
2077
+ return null;
2078
+ }
2079
+ members.push(member);
2080
+ }
2081
+ const count = members.length;
2082
+ if (count === 0) {
2083
+ return null;
2084
+ }
2085
+ const mean = members.reduce((sum, member) => sum + member, 0) / count;
2086
+ const sumSquares = members.reduce((sum, member) => sum + (member - mean) ** 2, 0);
2087
+ switch (expression.name) {
2088
+ case "mean":
2089
+ return floatValue(mean);
2090
+ case "popVariance":
2091
+ return floatValue(sumSquares / count);
2092
+ case "popSD":
2093
+ return floatValue(Math.sqrt(sumSquares / count));
2094
+ case "sampleVariance":
2095
+ return count < 2 ? null : floatValue(sumSquares / (count - 1));
2096
+ case "sampleSD":
2097
+ return count < 2 ? null : floatValue(Math.sqrt(sumSquares / (count - 1)));
2098
+ default:
2099
+ throw new RpUnsupportedError("statsOperator");
2100
+ }
2101
+ }
2102
+ case "delete": {
2103
+ const [valueExpression, containerExpression] = expression.expressions ?? [];
2104
+ if (valueExpression === undefined || containerExpression === undefined) {
2105
+ return null;
2106
+ }
2107
+ const value = evaluate(valueExpression);
2108
+ const container = evaluate(containerExpression);
2109
+ if (value === null || container === null) {
2110
+ return null;
2111
+ }
2112
+ const scalar = value.values[0];
2113
+ if (scalar === undefined) {
2114
+ return null;
2115
+ }
2116
+ const baseType = container.baseType ?? value.baseType;
2117
+ const remaining = container.values.filter((member) => !scalarsEqual(member, scalar, baseType, env.normalization));
2118
+ return remaining.length === 0 ? null : rpValue(container.cardinality, remaining, container.baseType);
2119
+ }
2120
+ case "repeat": {
2121
+ const numberRepeats = resolveNumericAttribute(expression.numberRepeats, env);
2122
+ if (typeof numberRepeats !== "number" || numberRepeats < 1) {
2123
+ return null;
2124
+ }
2125
+ const members = [];
2126
+ let baseType;
2127
+ for (let pass = 0;pass < numberRepeats; pass += 1) {
2128
+ for (const child of expression.expressions ?? []) {
2129
+ const value = evaluate(child);
2130
+ if (value === null) {
2131
+ continue;
2132
+ }
2133
+ baseType ??= value.baseType;
2134
+ members.push(...value.values);
2135
+ }
2136
+ }
2137
+ return members.length === 0 ? null : rpValue("ordered", members, baseType);
2138
+ }
2139
+ case "null":
2140
+ return null;
2141
+ case "durationGte":
2142
+ case "durationLt": {
2143
+ const [a3, b2] = (expression.expressions ?? []).map((child) => singleNumber(evaluate(child)));
2144
+ if (a3 === undefined || b2 === undefined || a3 === null || b2 === null) {
2145
+ return null;
2146
+ }
2147
+ return booleanValue(expression.kind === "durationGte" ? a3 >= b2 : a3 < b2);
2148
+ }
2149
+ case "default":
2150
+ return env.variableDefault?.(expression.identifier ?? "") ?? null;
2151
+ case "patternMatch": {
2152
+ const operand = expression.expressions?.[0];
2153
+ const value = operand === undefined ? null : evaluate(operand);
2154
+ const member = value?.values[0];
2155
+ if (value === null || typeof member !== "string") {
2156
+ return null;
2157
+ }
2158
+ if (expression.pattern === undefined) {
2159
+ throw new RpUnsupportedError("patternMatch");
2160
+ }
2161
+ const pattern = encVariableStringPattern.test(expression.pattern) ? env.lookupVariable(expression.pattern.slice(1, -1))?.values[0] : expression.pattern;
2162
+ if (typeof pattern !== "string") {
2163
+ return null;
2164
+ }
2165
+ const matcher = xsdPatternMatcher(pattern);
2166
+ if (matcher === null) {
2167
+ throw new RpUnsupportedError("patternMatch");
2168
+ }
2169
+ return booleanValue(matcher(member));
2170
+ }
2171
+ case "power": {
2172
+ const [a3, b2] = (expression.expressions ?? []).map((child) => singleNumber(evaluate(child)));
2173
+ if (a3 === undefined || b2 === undefined || a3 === null || b2 === null) {
2174
+ return null;
2175
+ }
2176
+ const result = a3 ** b2;
2177
+ return Number.isFinite(result) ? floatValue(result) : null;
2178
+ }
2179
+ case "containerSize": {
2180
+ const operand = expression.expressions?.[0];
2181
+ const container = operand === undefined ? null : evaluate(operand);
2182
+ return {
2183
+ cardinality: "single",
2184
+ baseType: "integer",
2185
+ values: [container === null ? 0 : container.values.length]
2186
+ };
2187
+ }
2188
+ case "contains": {
2189
+ const [firstExpression, secondExpression] = expression.expressions ?? [];
2190
+ if (firstExpression === undefined || secondExpression === undefined) {
2191
+ return null;
2192
+ }
2193
+ const first = evaluate(firstExpression);
2194
+ const second = evaluate(secondExpression);
2195
+ if (first === null || second === null || first.cardinality === "record" || second.cardinality === "record") {
2196
+ return null;
2197
+ }
2198
+ const baseType = first.baseType ?? second.baseType;
2199
+ if (first.cardinality === "ordered") {
2200
+ const found = first.values.some((_2, start) => start + second.values.length <= first.values.length && second.values.every((member, offset) => scalarsEqual(first.values[start + offset], member, baseType, env.normalization)));
2201
+ return booleanValue(found);
2202
+ }
2203
+ const remaining = [...first.values];
2204
+ for (const member of second.values) {
2205
+ const at = remaining.findIndex((candidate) => scalarsEqual(candidate, member, baseType, env.normalization));
2206
+ if (at === -1) {
2207
+ return booleanValue(false);
2208
+ }
2209
+ remaining.splice(at, 1);
2210
+ }
2211
+ return booleanValue(true);
2212
+ }
2213
+ case "anyN": {
2214
+ const min = resolveNumericAttribute(expression.min, env);
2215
+ const max = resolveNumericAttribute(expression.max, env);
2216
+ if (typeof min !== "number" || typeof max !== "number") {
2217
+ return null;
2218
+ }
2219
+ const members = (expression.expressions ?? []).map((child) => singleBoolean(evaluate(child)));
2220
+ const trueCount = members.filter((member) => member === true).length;
2221
+ const nullCount = members.filter((member) => member === null).length;
2222
+ if (trueCount >= min && trueCount + nullCount <= max) {
2223
+ return booleanValue(true);
2224
+ }
2225
+ if (trueCount + nullCount < min || trueCount > max) {
2226
+ return booleanValue(false);
2227
+ }
2228
+ return null;
2229
+ }
2230
+ case "stringMatch":
2231
+ case "substring": {
2232
+ const [a3, b2] = (expression.expressions ?? []).map((child) => {
2233
+ const value = evaluate(child);
2234
+ const member = value?.values[0];
2235
+ return typeof member === "string" ? member : null;
2236
+ });
2237
+ if (a3 === undefined || b2 === undefined || a3 === null || b2 === null) {
2238
+ return null;
2239
+ }
2240
+ const normalize = (input) => {
2241
+ const normalized = env.normalization?.(input) ?? input;
2242
+ return expression.caseSensitive === false ? normalized.toLowerCase() : normalized;
2243
+ };
2244
+ const [left, right] = [normalize(a3), normalize(b2)];
2245
+ const contains = expression.kind === "substring" || expression.substring === true;
2246
+ return booleanValue(contains ? right.includes(left) : left === right);
2247
+ }
2248
+ case "inside": {
2249
+ if (typeof expression.shape !== "string" || typeof expression.coords !== "string") {
2250
+ throw new RpUnsupportedError("inside");
2251
+ }
2252
+ const operand = expression.expressions?.[0];
2253
+ const value = operand === undefined ? null : evaluate(operand);
2254
+ const member = value?.values[0];
2255
+ if (value === null || typeof member !== "string") {
2256
+ return null;
2257
+ }
2258
+ const point = parsePoint(member);
2259
+ if (point === null) {
2260
+ return null;
2261
+ }
2262
+ return booleanValue(pointInShape(expression.shape, parseCoords(expression.coords), point));
2263
+ }
2264
+ case "member": {
2265
+ const [needleExpression, containerExpression] = expression.expressions ?? [];
2266
+ if (needleExpression === undefined || containerExpression === undefined) {
2267
+ return null;
2268
+ }
2269
+ const needle = evaluate(needleExpression);
2270
+ const container = evaluate(containerExpression);
2271
+ if (needle === null || container === null) {
2272
+ return null;
2273
+ }
2274
+ const scalar = needle.values[0];
2275
+ if (scalar === undefined) {
2276
+ return null;
2277
+ }
2278
+ const baseType = container.baseType ?? needle.baseType;
2279
+ return booleanValue(container.values.some((member) => scalarsEqual(member, scalar, baseType, env.normalization)));
2280
+ }
2281
+ case "multiple":
2282
+ case "ordered": {
2283
+ const members = [];
2284
+ let baseType;
2285
+ for (const child of expression.expressions ?? []) {
2286
+ const value = evaluate(child);
2287
+ if (value === null) {
2288
+ continue;
2289
+ }
2290
+ baseType ??= value.baseType;
2291
+ members.push(...value.values);
2292
+ }
2293
+ if (members.length === 0) {
2294
+ return null;
2295
+ }
2296
+ return rpValue(expression.kind, members, baseType);
2297
+ }
2298
+ case "randomInteger": {
2299
+ if (!env.random) {
2300
+ throw new RpUnsupportedError(expression.kind);
2301
+ }
2302
+ const min = resolveNumericAttribute(expression.min, env) ?? 0;
2303
+ const max = resolveNumericAttribute(expression.max, env) ?? min;
2304
+ const step = resolveNumericAttribute(expression.step, env) ?? 1;
2305
+ const count = Math.max(1, Math.floor((max - min) / step) + 1);
2306
+ return { cardinality: "single", baseType: "integer", values: [min + Math.floor(env.random() * count) * step] };
2307
+ }
2308
+ case "randomFloat": {
2309
+ if (!env.random) {
2310
+ throw new RpUnsupportedError(expression.kind);
2311
+ }
2312
+ const min = resolveNumericAttribute(expression.min, env) ?? 0;
2313
+ const max = resolveNumericAttribute(expression.max, env) ?? min;
2314
+ return floatValue(min + env.random() * (max - min));
2315
+ }
2316
+ case "testVariables": {
2317
+ if (!env.testVariables) {
2318
+ throw new RpUnsupportedError(expression.kind);
2319
+ }
2320
+ return env.testVariables(expression);
2321
+ }
2322
+ case "customOperator": {
2323
+ const implementation = env.customOperators?.[expression.class ?? ""];
2324
+ if (!implementation) {
2325
+ throw new RpUnsupportedError(expression.kind);
2326
+ }
2327
+ return implementation((expression.expressions ?? []).map(evaluate), expression);
2328
+ }
2329
+ case "numberCorrect":
2330
+ case "numberIncorrect":
2331
+ case "numberPresented":
2332
+ case "numberResponded":
2333
+ case "numberSelected":
2334
+ case "outcomeMinimum":
2335
+ case "outcomeMaximum": {
2336
+ if (!env.testAggregate) {
2337
+ throw new RpUnsupportedError(expression.kind);
2338
+ }
2339
+ return env.testAggregate(expression);
2340
+ }
2341
+ case "random": {
2342
+ if (!env.random) {
2343
+ throw new RpUnsupportedError(expression.kind);
2344
+ }
2345
+ const container = expression.expressions?.[0] === undefined ? null : evaluate(expression.expressions[0]);
2346
+ if (container === null || container.values.length === 0) {
2347
+ return null;
2348
+ }
2349
+ const pick = container.values[Math.floor(env.random() * container.values.length)];
2350
+ return rpValue("single", [pick], container.baseType);
2351
+ }
2352
+ default:
2353
+ throw new RpUnsupportedError(expression.kind);
2354
+ }
2355
+ }
2356
+ function collectExpressionIssues(expression, allowedKinds, report, customOperatorClasses) {
2357
+ if (expression.kind === "customOperator") {
2358
+ if (!customOperatorClasses?.has(expression.class ?? "")) {
2359
+ report(expression.kind);
2360
+ }
2361
+ } else if (!allowedKinds.has(expression.kind)) {
2362
+ report(expression.kind);
2363
+ } else if (expression.kind === "patternMatch" && expression.pattern !== undefined && !encVariableStringPattern.test(expression.pattern) && xsdPatternMatcher(expression.pattern) === null) {
2364
+ report(expression.kind);
2365
+ }
2366
+ for (const child of expression.expressions ?? []) {
2367
+ collectExpressionIssues(child, allowedKinds, report, customOperatorClasses);
2368
+ }
2369
+ }
2370
+
2371
+ // src/rp/lookup-table.ts
2372
+ function hasLookupTable(declaration) {
2373
+ return declaration?.matchTable !== undefined || declaration?.interpolationTable !== undefined;
2374
+ }
2375
+ function lookupTableValue(declaration, source) {
2376
+ const value = singleNumber(source);
2377
+ const table = declaration.matchTable ?? declaration.interpolationTable;
2378
+ const target = value === null ? undefined : matchedTarget(declaration, value);
2379
+ const result = target ?? table?.defaultValue;
2380
+ if (result === undefined) {
2381
+ return null;
2382
+ }
2383
+ return rpValue("single", [coerceScalar(result, declaration.baseType)], declaration.baseType);
2384
+ }
2385
+ function matchedTarget(declaration, value) {
2386
+ if (declaration.matchTable) {
2387
+ return declaration.matchTable.matchTableEntries.find((entry) => entry.sourceValue === value)?.targetValue;
2388
+ }
2389
+ return declaration.interpolationTable?.interpolationTableEntries.find((entry) => entry.includeBoundary ?? true ? entry.sourceValue <= value : entry.sourceValue < value)?.targetValue;
2390
+ }
2391
+
2392
+ // src/rp/templates.ts
2393
+ var matchCorrectRules = [
2394
+ {
2395
+ kind: "responseCondition",
2396
+ responseIf: {
2397
+ expression: {
2398
+ kind: "match",
2399
+ expressions: [
2400
+ { kind: "variable", identifier: "RESPONSE" },
2401
+ { kind: "correct", identifier: "RESPONSE" }
2402
+ ]
2403
+ },
2404
+ rules: [
2405
+ {
2406
+ kind: "setOutcomeValue",
2407
+ identifier: "SCORE",
2408
+ expression: { kind: "baseValue", baseType: "float", value: 1 }
2409
+ }
2410
+ ]
2411
+ },
2412
+ responseElse: {
2413
+ rules: [
2414
+ {
2415
+ kind: "setOutcomeValue",
2416
+ identifier: "SCORE",
2417
+ expression: { kind: "baseValue", baseType: "float", value: 0 }
2418
+ }
2419
+ ]
2420
+ }
2421
+ }
2422
+ ];
2423
+ var mapResponseRules = [
2424
+ {
2425
+ kind: "responseCondition",
2426
+ responseIf: {
2427
+ expression: { kind: "isNull", expressions: [{ kind: "variable", identifier: "RESPONSE" }] },
2428
+ rules: [
2429
+ {
2430
+ kind: "setOutcomeValue",
2431
+ identifier: "SCORE",
2432
+ expression: { kind: "baseValue", baseType: "float", value: 0 }
2433
+ }
2434
+ ]
2435
+ },
2436
+ responseElse: {
2437
+ rules: [
2438
+ { kind: "setOutcomeValue", identifier: "SCORE", expression: { kind: "mapResponse", identifier: "RESPONSE" } }
2439
+ ]
2440
+ }
2441
+ }
2442
+ ];
2443
+ var mapResponsePointRules = [
2444
+ {
2445
+ kind: "responseCondition",
2446
+ responseIf: {
2447
+ expression: { kind: "isNull", expressions: [{ kind: "variable", identifier: "RESPONSE" }] },
2448
+ rules: [
2449
+ {
2450
+ kind: "setOutcomeValue",
2451
+ identifier: "SCORE",
2452
+ expression: { kind: "baseValue", baseType: "float", value: 0 }
2453
+ }
2454
+ ]
2455
+ },
2456
+ responseElse: {
2457
+ rules: [
2458
+ {
2459
+ kind: "setOutcomeValue",
2460
+ identifier: "SCORE",
2461
+ expression: { kind: "mapResponsePoint", identifier: "RESPONSE" }
2462
+ }
2463
+ ]
2464
+ }
2465
+ }
2466
+ ];
2467
+ var cc2MatchBasicRules = [
2468
+ {
2469
+ kind: "responseCondition",
2470
+ responseIf: {
2471
+ expression: {
2472
+ kind: "match",
2473
+ expressions: [
2474
+ { kind: "variable", identifier: "RESPONSE" },
2475
+ { kind: "correct", identifier: "RESPONSE" }
2476
+ ]
2477
+ },
2478
+ rules: [
2479
+ { kind: "setOutcomeValue", identifier: "SCORE", expression: { kind: "variable", identifier: "MAXSCORE" } },
2480
+ {
2481
+ kind: "setOutcomeValue",
2482
+ identifier: "FEEDBACKBASIC",
2483
+ expression: { kind: "baseValue", baseType: "identifier", value: "correct" }
2484
+ }
2485
+ ]
2486
+ },
2487
+ responseElse: {
2488
+ rules: [
2489
+ {
2490
+ kind: "setOutcomeValue",
2491
+ identifier: "FEEDBACKBASIC",
2492
+ expression: { kind: "baseValue", baseType: "identifier", value: "incorrect" }
2493
+ }
2494
+ ]
2495
+ }
2496
+ }
2497
+ ];
2498
+ var cc2MapResponseRules = [
2499
+ {
2500
+ kind: "responseCondition",
2501
+ responseIf: {
2502
+ expression: { kind: "isNull", expressions: [{ kind: "variable", identifier: "RESPONSE" }] },
2503
+ rules: [
2504
+ {
2505
+ kind: "setOutcomeValue",
2506
+ identifier: "SCORE",
2507
+ expression: { kind: "baseValue", baseType: "float", value: 0 }
2508
+ }
2509
+ ]
2510
+ },
2511
+ responseElse: {
2512
+ rules: [
2513
+ { kind: "setOutcomeValue", identifier: "SCORE", expression: { kind: "mapResponse", identifier: "RESPONSE" } }
2514
+ ]
2515
+ }
2516
+ },
2517
+ {
2518
+ kind: "responseCondition",
2519
+ responseIf: {
2520
+ expression: {
2521
+ kind: "equal",
2522
+ toleranceMode: "exact",
2523
+ expressions: [
2524
+ { kind: "variable", identifier: "MAXSCORE" },
2525
+ { kind: "variable", identifier: "SCORE" }
2526
+ ]
2527
+ },
2528
+ rules: [
2529
+ {
2530
+ kind: "setOutcomeValue",
2531
+ identifier: "FEEDBACK",
2532
+ expression: { kind: "baseValue", baseType: "identifier", value: "correct" }
2533
+ }
2534
+ ]
2535
+ },
2536
+ responseElse: {
2537
+ rules: [
2538
+ {
2539
+ kind: "setOutcomeValue",
2540
+ identifier: "FEEDBACK",
2541
+ expression: { kind: "baseValue", baseType: "identifier", value: "incorrect" }
2542
+ }
2543
+ ]
2544
+ }
2545
+ }
2546
+ ];
2547
+ var templatesBySegment = new Map([
2548
+ ["match_correct", matchCorrectRules],
2549
+ ["map_response", mapResponseRules],
2550
+ ["map_response_point", mapResponsePointRules],
2551
+ ["CC2_match", matchCorrectRules],
2552
+ ["CC2_match_basic", cc2MatchBasicRules],
2553
+ ["CC2_map_response", cc2MapResponseRules]
2554
+ ]);
2555
+ function resolveTemplate(uri) {
2556
+ const segment = uri.split("/").at(-1)?.replace(/\.xml$/u, "") ?? "";
2557
+ return templatesBySegment.get(segment) ?? null;
2558
+ }
2559
+
2560
+ // src/rp/interpreter.ts
2561
+ var supportedRuleKinds = new Set([
2562
+ "responseCondition",
2563
+ "setOutcomeValue",
2564
+ "lookupOutcomeValue",
2565
+ "responseProcessingFragment",
2566
+ "exitResponse"
2567
+ ]);
2568
+ var rpExpressionKinds = new Set([...deterministicExpressionKinds, "random", "randomInteger", "randomFloat"]);
2569
+
2570
+ class ExitResponseSignal extends Error {
2571
+ }
2572
+ function defaultOutcomes(declarations) {
2573
+ const outcomes = new Map;
2574
+ for (const declaration of declarations) {
2575
+ if (declaration.defaultValue) {
2576
+ outcomes.set(declaration.identifier, rpValue(declaration.cardinality, declaration.defaultValue.values.map((entry) => coerceScalar(entry.value, declaration.baseType)), declaration.baseType));
2577
+ continue;
2578
+ }
2579
+ outcomes.set(declaration.identifier, isNumericBaseType(declaration.baseType) ? floatValue(0) : null);
2580
+ }
2581
+ return outcomes;
2582
+ }
2583
+ function executeResponseProcessing(view, context) {
2584
+ const issues = [];
2585
+ const declarationsById = new Map(context.responseDeclarations.map((declaration) => [declaration.identifier, declaration]));
2586
+ const templateDeclarationsById = new Map((context.templateDeclarations ?? []).map((declaration) => [declaration.identifier, declaration]));
2587
+ function initialOutcomes() {
2588
+ const outcomes2 = defaultOutcomes(context.outcomeDeclarations);
2589
+ if (!outcomes2.has("completionStatus")) {
2590
+ outcomes2.set("completionStatus", rpValue("single", [context.completionStatus ?? "not_attempted"], "identifier"));
2591
+ }
2592
+ for (const [identifier, prior] of Object.entries(context.priorOutcomes ?? {})) {
2593
+ const declaration = context.outcomeDeclarations.find((entry) => entry.identifier === identifier);
2594
+ outcomes2.set(identifier, fromFlatValue(prior, declaration?.cardinality ?? "single", declaration?.baseType));
2595
+ }
2596
+ return outcomes2;
2597
+ }
2598
+ let outcomes = initialOutcomes();
2599
+ let rules = view?.rules ?? [];
2600
+ if (view && !view.rules && view.template) {
2601
+ const resolved = resolveTemplate(view.template);
2602
+ if (resolved) {
2603
+ rules = resolved;
2604
+ } else {
2605
+ issues.push({ type: "unsupported-rp", name: view.template, detail: "Unknown response-processing template URI." });
2606
+ }
2607
+ }
2608
+ const env = {
2609
+ lookupVariable: (identifier) => {
2610
+ if (identifier === "duration") {
2611
+ return context.duration === undefined ? null : rpValue("single", [context.duration], "duration");
2612
+ }
2613
+ if (identifier === "numAttempts") {
2614
+ return context.numAttempts === undefined ? null : rpValue("single", [context.numAttempts], "integer");
2615
+ }
2616
+ const declaration = declarationsById.get(identifier);
2617
+ if (declaration) {
2618
+ return fromResponse(declaration, context.responses[identifier] ?? null);
2619
+ }
2620
+ const templateDeclaration = templateDeclarationsById.get(identifier);
2621
+ if (templateDeclaration) {
2622
+ return fromFlatValue(context.templateValues?.[identifier] ?? null, templateDeclaration.cardinality, templateDeclaration.baseType);
2623
+ }
2624
+ return outcomes.get(identifier) ?? null;
2625
+ },
2626
+ responseDeclaration: (identifier) => declarationsById.get(identifier),
2627
+ responseValue: (identifier) => context.responses[identifier] ?? null,
2628
+ variableDefault: (identifier) => {
2629
+ const declaration = declarationsById.get(identifier) ?? context.outcomeDeclarations.find((entry) => entry.identifier === identifier) ?? templateDeclarationsById.get(identifier);
2630
+ if (!declaration?.defaultValue) {
2631
+ return null;
2632
+ }
2633
+ return rpValue(declaration.cardinality, declaration.defaultValue.values.map((entry) => coerceScalar(entry.value, declaration.baseType)), declaration.baseType);
2634
+ },
2635
+ normalization: context.normalization,
2636
+ random: context.random,
2637
+ customOperators: context.customOperators
2638
+ };
2639
+ function branchTaken(branch) {
2640
+ if (singleBoolean(evaluateExpression(branch.expression, env)) !== true) {
2641
+ return false;
2642
+ }
2643
+ executeRules(branch.rules);
2644
+ return true;
2645
+ }
2646
+ function executeRules(rules_) {
2647
+ for (const rule of rules_) {
2648
+ if (!supportedRuleKinds.has(rule.kind)) {
2649
+ throw new RpUnsupportedError(rule.kind);
2650
+ }
2651
+ if (rule.kind === "exitResponse") {
2652
+ throw new ExitResponseSignal;
2653
+ }
2654
+ if (rule.kind === "setOutcomeValue") {
2655
+ if (rule.identifier !== undefined && rule.expression !== undefined) {
2656
+ outcomes.set(rule.identifier, evaluateExpression(rule.expression, env));
2657
+ }
2658
+ continue;
2659
+ }
2660
+ if (rule.kind === "responseProcessingFragment") {
2661
+ executeRules(rule.rules ?? []);
2662
+ continue;
2663
+ }
2664
+ if (rule.kind === "lookupOutcomeValue") {
2665
+ if (rule.identifier !== undefined && rule.expression !== undefined) {
2666
+ const declaration = context.outcomeDeclarations.find((entry) => entry.identifier === rule.identifier);
2667
+ if (!hasLookupTable(declaration)) {
2668
+ throw new RpUnsupportedError("lookupOutcomeValue");
2669
+ }
2670
+ outcomes.set(rule.identifier, lookupTableValue(declaration, evaluateExpression(rule.expression, env)));
2671
+ }
2672
+ continue;
2673
+ }
2674
+ if (rule.responseIf && branchTaken(rule.responseIf)) {
2675
+ continue;
2676
+ }
2677
+ const elseIfTaken = (rule.responseElseIfs ?? []).some((branch) => branchTaken(branch));
2678
+ if (!elseIfTaken && rule.responseElse) {
2679
+ executeRules(rule.responseElse.rules);
2680
+ }
2681
+ }
2682
+ }
2683
+ try {
2684
+ executeRules(rules);
2685
+ } catch (error) {
2686
+ if (error instanceof RpUnsupportedError) {
2687
+ issues.push({ type: "unsupported-rp", name: error.kindName });
2688
+ outcomes = initialOutcomes();
2689
+ } else if (!(error instanceof ExitResponseSignal)) {
2690
+ throw error;
2691
+ }
2692
+ }
2693
+ return {
2694
+ outcomes: Object.fromEntries([...outcomes].map(([identifier, value]) => [identifier, toOutcomeValue(value)])),
2695
+ issues
2696
+ };
2697
+ }
2698
+ function collectRpIssues(view, options) {
2699
+ if (!view) {
2700
+ return [];
2701
+ }
2702
+ const issues = [];
2703
+ const seen = new Set;
2704
+ function report(name, detail) {
2705
+ if (!seen.has(name)) {
2706
+ seen.add(name);
2707
+ issues.push({ type: "unsupported-rp", name, ...detail === undefined ? {} : { detail } });
2708
+ }
2709
+ }
2710
+ function walkRules(rules) {
2711
+ for (const rule of rules) {
2712
+ if (!supportedRuleKinds.has(rule.kind)) {
2713
+ report(rule.kind);
2714
+ continue;
2715
+ }
2716
+ if (rule.kind === "lookupOutcomeValue" && options?.outcomeDeclarations !== undefined) {
2717
+ const declaration = options.outcomeDeclarations.find((entry) => entry.identifier === rule.identifier);
2718
+ if (!hasLookupTable(declaration)) {
2719
+ report("lookupOutcomeValue", "Outcome declaration has no matchTable/interpolationTable.");
2720
+ }
2721
+ }
2722
+ if (rule.expression) {
2723
+ collectExpressionIssues(rule.expression, rpExpressionKinds, report, options?.customOperatorClasses);
2724
+ }
2725
+ if (rule.rules) {
2726
+ walkRules(rule.rules);
2727
+ }
2728
+ for (const branch of [rule.responseIf, ...rule.responseElseIfs ?? []]) {
2729
+ if (branch) {
2730
+ collectExpressionIssues(branch.expression, rpExpressionKinds, report, options?.customOperatorClasses);
2731
+ walkRules(branch.rules);
2732
+ }
2733
+ }
2734
+ if (rule.responseElse) {
2735
+ walkRules(rule.responseElse.rules);
2736
+ }
2737
+ }
2738
+ }
2739
+ if (view.rules) {
2740
+ walkRules(view.rules);
2741
+ } else if (view.template) {
2742
+ const resolved = resolveTemplate(view.template);
2743
+ if (resolved === null) {
2744
+ report(view.template, "Unknown response-processing template URI.");
2745
+ }
2746
+ }
2747
+ return issues;
2748
+ }
2749
+ // src/rp/template-processing.ts
2750
+ var supportedTemplateRuleKinds = new Set([
2751
+ "setTemplateValue",
2752
+ "templateCondition",
2753
+ "templateConstraint",
2754
+ "setCorrectResponse",
2755
+ "exitTemplate"
2756
+ ]);
2757
+ var templateExpressionKinds = new Set([...deterministicExpressionKinds, ...randomExpressionKinds]);
2758
+
2759
+ class ExitTemplateSignal extends Error {
2760
+ }
2761
+
2762
+ class TemplateConstraintSignal extends Error {
2763
+ }
2764
+ var maxConstraintAttempts = 100;
2765
+ function mulberry32(seed) {
2766
+ let state = seed >>> 0;
2767
+ return () => {
2768
+ state = state + 1831565813 >>> 0;
2769
+ let t3 = state;
2770
+ t3 = Math.imul(t3 ^ t3 >>> 15, t3 | 1);
2771
+ t3 ^= t3 + Math.imul(t3 ^ t3 >>> 7, t3 | 61);
2772
+ return ((t3 ^ t3 >>> 14) >>> 0) / 4294967296;
2773
+ };
2774
+ }
2775
+ function executeTemplateProcessing(view, context) {
2776
+ const issues = [];
2777
+ const declarationsById = new Map(context.templateDeclarations.map((entry) => [entry.identifier, entry]));
2778
+ const responseDeclarationsById = new Map(context.responseDeclarations.map((entry) => [entry.identifier, entry]));
2779
+ const correctResponseOverrides = {};
2780
+ function initialValues() {
2781
+ const values = new Map;
2782
+ for (const declaration of context.templateDeclarations) {
2783
+ values.set(declaration.identifier, declaration.defaultValue ? rpValue(declaration.cardinality, declaration.defaultValue.values.map((entry) => coerceScalar(entry.value, declaration.baseType)), declaration.baseType) : null);
2784
+ }
2785
+ return values;
2786
+ }
2787
+ let templateValues = initialValues();
2788
+ const env = {
2789
+ lookupVariable: (identifier) => templateValues.get(identifier) ?? null,
2790
+ responseDeclaration: (identifier) => responseDeclarationsById.get(identifier),
2791
+ responseValue: () => null,
2792
+ variableDefault: (identifier) => {
2793
+ const declaration = declarationsById.get(identifier) ?? responseDeclarationsById.get(identifier);
2794
+ if (!declaration?.defaultValue) {
2795
+ return null;
2796
+ }
2797
+ return rpValue(declaration.cardinality, declaration.defaultValue.values.map((entry) => coerceScalar(entry.value, declaration.baseType)), declaration.baseType);
2798
+ },
2799
+ random: mulberry32(context.seed),
2800
+ customOperators: context.customOperators
2801
+ };
2802
+ function branchTaken(branch) {
2803
+ if (singleBoolean(evaluateExpression(branch.expression, env)) !== true) {
2804
+ return false;
2805
+ }
2806
+ executeRules(branch.rules);
2807
+ return true;
2808
+ }
2809
+ function executeRules(rules) {
2810
+ for (const rule of rules) {
2811
+ if (!supportedTemplateRuleKinds.has(rule.kind)) {
2812
+ throw new RpUnsupportedError(rule.kind);
2813
+ }
2814
+ if (rule.kind === "exitTemplate") {
2815
+ throw new ExitTemplateSignal;
2816
+ }
2817
+ if (rule.kind === "setTemplateValue") {
2818
+ if (rule.identifier !== undefined && rule.expression !== undefined) {
2819
+ const declaration = declarationsById.get(rule.identifier);
2820
+ const value = evaluateExpression(rule.expression, env);
2821
+ templateValues.set(rule.identifier, value === null || !declaration ? value : rpValue(declaration.cardinality, value.values, declaration.baseType ?? value.baseType));
2822
+ }
2823
+ continue;
2824
+ }
2825
+ if (rule.kind === "setCorrectResponse") {
2826
+ if (rule.identifier !== undefined && rule.expression !== undefined) {
2827
+ const value = evaluateExpression(rule.expression, env);
2828
+ if (value !== null) {
2829
+ correctResponseOverrides[rule.identifier] = {
2830
+ values: value.values.map((member) => ({ value: String(member) }))
2831
+ };
2832
+ }
2833
+ }
2834
+ continue;
2835
+ }
2836
+ if (rule.kind === "templateConstraint") {
2837
+ if (rule.expression !== undefined && singleBoolean(evaluateExpression(rule.expression, env)) !== true) {
2838
+ throw new TemplateConstraintSignal;
2839
+ }
2840
+ continue;
2841
+ }
2842
+ if (rule.templateIf && branchTaken(rule.templateIf)) {
2843
+ continue;
2844
+ }
2845
+ const elseIfTaken = (rule.templateElseIfs ?? []).some((branch) => branchTaken(branch));
2846
+ if (!elseIfTaken && rule.templateElse) {
2847
+ executeRules(rule.templateElse.rules);
2848
+ }
2849
+ }
2850
+ }
2851
+ for (let attempt = 0;attempt < maxConstraintAttempts; attempt += 1) {
2852
+ try {
2853
+ executeRules(view?.rules ?? []);
2854
+ break;
2855
+ } catch (error) {
2856
+ if (error instanceof TemplateConstraintSignal) {
2857
+ templateValues = initialValues();
2858
+ for (const key of Object.keys(correctResponseOverrides)) {
2859
+ delete correctResponseOverrides[key];
2860
+ }
2861
+ continue;
2862
+ }
2863
+ if (error instanceof RpUnsupportedError) {
2864
+ issues.push({ type: "unsupported-rp", name: error.kindName });
2865
+ templateValues = initialValues();
2866
+ } else if (!(error instanceof ExitTemplateSignal)) {
2867
+ throw error;
2868
+ }
2869
+ break;
2870
+ }
2871
+ }
2872
+ return {
2873
+ templateValues: Object.fromEntries([...templateValues].map(([identifier, value]) => [identifier, toOutcomeValue(value)])),
2874
+ correctResponseOverrides,
2875
+ issues
2876
+ };
2877
+ }
2878
+ function applyTemplateDefaultOverrides(declarations, overrides) {
2879
+ return declarations.map((declaration) => {
2880
+ if (!(declaration.identifier in overrides)) {
2881
+ return declaration;
2882
+ }
2883
+ const value = overrides[declaration.identifier];
2884
+ if (value === null || value === undefined) {
2885
+ const { defaultValue: _cleared, ...rest } = declaration;
2886
+ return rest;
2887
+ }
2888
+ return {
2889
+ ...declaration,
2890
+ defaultValue: { values: (Array.isArray(value) ? value : [value]).map((member) => ({ value: member })) }
2891
+ };
2892
+ });
2893
+ }
2894
+ function applyCorrectResponseOverrides(declarations, overrides) {
2895
+ return declarations.map((declaration) => {
2896
+ const override = overrides[declaration.identifier];
2897
+ return override ? { ...declaration, correctResponse: override } : declaration;
2898
+ });
2899
+ }
2900
+ function collectTemplateIssues(view, options) {
2901
+ if (!view) {
2902
+ return [];
2903
+ }
2904
+ const issues = [];
2905
+ const seen = new Set;
2906
+ function report(name) {
2907
+ if (!seen.has(name)) {
2908
+ seen.add(name);
2909
+ issues.push({ type: "unsupported-rp", name });
2910
+ }
2911
+ }
2912
+ function walkRules(rules) {
2913
+ for (const rule of rules) {
2914
+ if (!supportedTemplateRuleKinds.has(rule.kind)) {
2915
+ report(rule.kind);
2916
+ continue;
2917
+ }
2918
+ if (rule.expression) {
2919
+ collectExpressionIssues(rule.expression, templateExpressionKinds, report, options?.customOperatorClasses);
2920
+ }
2921
+ for (const branch of [rule.templateIf, ...rule.templateElseIfs ?? []]) {
2922
+ if (branch) {
2923
+ collectExpressionIssues(branch.expression, templateExpressionKinds, report, options?.customOperatorClasses);
2924
+ walkRules(branch.rules);
2925
+ }
2926
+ }
2927
+ if (rule.templateElse) {
2928
+ walkRules(rule.templateElse.rules);
2929
+ }
2930
+ }
2931
+ }
2932
+ walkRules(view.rules);
2933
+ return issues;
2934
+ }
2935
+ // src/item-capability.ts
2936
+ var feedbackKinds = new Set(["feedbackInline", "feedbackBlock"]);
2937
+ var templateContentKinds = new Set(["templateInline", "templateBlock"]);
2938
+ var intrinsicLeafKinds = new Set(["text", "printedVariable"]);
2939
+ function isFeedbackNode(node) {
2940
+ return feedbackKinds.has(node.kind);
2941
+ }
2942
+ function isTemplateContentNode(node) {
2943
+ return templateContentKinds.has(node.kind);
2944
+ }
2945
+ function isInteractionNode(node) {
2946
+ return node.kind !== "xml" && typeof node.responseIdentifier === "string";
2947
+ }
2948
+ function reportItemCapability(item, options) {
2949
+ const model = options.model ?? v0ContentModel;
2950
+ const customOperatorClasses = options.customOperatorClasses ?? new Set;
2951
+ const issues = [];
2952
+ const seen = new Set;
2953
+ function report(issue) {
2954
+ const dedupeKey = `${issue.type}:${issue.name}:${issue.responseIdentifier ?? ""}`;
2955
+ if (!seen.has(dedupeKey)) {
2956
+ seen.add(dedupeKey);
2957
+ issues.push(issue);
2958
+ }
2959
+ }
2960
+ function walk(node) {
2961
+ if (isFeedbackNode(node) || isTemplateContentNode(node) || node.kind === "rubricBlock") {
2962
+ for (const child of node.content ?? []) {
2963
+ walk(child);
2964
+ }
2965
+ return;
2966
+ }
2967
+ if (isInteractionNode(node)) {
2968
+ if (!options.supportedInteractions.has(node.kind)) {
2969
+ report({ type: "unsupported-interaction", name: node.kind, responseIdentifier: node.responseIdentifier });
2970
+ return;
2971
+ }
2972
+ const schema = options.interactionSchemas?.get(node.kind);
2973
+ if (schema) {
2974
+ const parsed = schema.safeParse(node);
2975
+ if (!parsed.success) {
2976
+ const detail = parsed.error.issues[0]?.message;
2977
+ report({
2978
+ type: "invalid-interaction",
2979
+ name: node.kind,
2980
+ responseIdentifier: node.responseIdentifier,
2981
+ ...detail !== undefined ? { detail } : {}
2982
+ });
2983
+ }
2984
+ }
2985
+ return;
2986
+ }
2987
+ if (node.kind === "xml") {
2988
+ const xmlNode = node;
2989
+ if (xmlNode.name === model.mathRoot) {
2990
+ return;
2991
+ }
2992
+ if (!isAllowedFlowElement(model, xmlNode.name)) {
2993
+ report({ type: "unsupported-element", name: xmlNode.name });
2994
+ }
2995
+ for (const child of xmlNode.children ?? []) {
2996
+ walk(child);
2997
+ }
2998
+ return;
2999
+ }
3000
+ if (intrinsicLeafKinds.has(node.kind)) {
3001
+ return;
3002
+ }
3003
+ report({ type: "unsupported-element", name: node.kind });
3004
+ }
3005
+ for (const node of item.itemBody.content ?? []) {
3006
+ walk(node);
3007
+ }
3008
+ for (const ref of item.assessmentStimulusRefs ?? []) {
3009
+ const stimulus = options.resolveStimulus?.(ref) ?? null;
3010
+ if (stimulus === null) {
3011
+ report({ type: "unsupported-element", name: "assessmentStimulusRef", detail: ref.href });
3012
+ continue;
3013
+ }
3014
+ for (const node of stimulus.content) {
3015
+ walk(node);
3016
+ }
3017
+ }
3018
+ for (const feedback of item.modalFeedbacks ?? []) {
3019
+ for (const child of feedback.content ?? []) {
3020
+ walk(child);
3021
+ }
3022
+ }
3023
+ for (const issue of collectRpIssues(item.responseProcessing, {
3024
+ customOperatorClasses,
3025
+ outcomeDeclarations: item.outcomeDeclarations ?? []
3026
+ })) {
3027
+ report(issue);
3028
+ }
3029
+ for (const issue of collectTemplateIssues(item.templateProcessing, { customOperatorClasses })) {
3030
+ report(issue);
3031
+ }
3032
+ return { deliverable: issues.length === 0, issues };
3033
+ }
3034
+ var referenceInteractionKinds = [
3035
+ "associateInteraction",
3036
+ "choiceInteraction",
3037
+ "drawingInteraction",
3038
+ "endAttemptInteraction",
3039
+ "extendedTextInteraction",
3040
+ "gapMatchInteraction",
3041
+ "graphicAssociateInteraction",
3042
+ "graphicGapMatchInteraction",
3043
+ "graphicOrderInteraction",
3044
+ "hotspotInteraction",
3045
+ "hottextInteraction",
3046
+ "inlineChoiceInteraction",
3047
+ "matchInteraction",
3048
+ "mediaInteraction",
3049
+ "orderInteraction",
3050
+ "positionObjectStage",
3051
+ "selectPointInteraction",
3052
+ "sliderInteraction",
3053
+ "textEntryInteraction",
3054
+ "uploadInteraction"
3055
+ ];
3056
+ export {
3057
+ stimulusContentFromNormalized,
3058
+ reportItemCapability,
3059
+ referenceInteractionKinds,
3060
+ assessmentTestViewFromNormalized,
3061
+ assessmentItemViewFromNormalized
3062
+ };