@citolab/qti-components 7.15.1 → 7.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base.js +2 -49
- package/dist/base.js.map +1 -1
- package/dist/elements.js +2 -41
- package/dist/elements.js.map +1 -1
- package/dist/index.js +9 -327
- package/dist/index.js.map +1 -1
- package/dist/interactions.js +2 -71
- package/dist/interactions.js.map +1 -1
- package/dist/item.js +2 -22
- package/dist/item.js.map +1 -1
- package/dist/loader.js +2 -10
- package/dist/loader.js.map +1 -1
- package/dist/processing.js +2 -102
- package/dist/processing.js.map +1 -1
- package/dist/test.js +2 -60
- package/dist/test.js.map +1 -1
- package/dist/transformers.js +2 -11
- package/dist/transformers.js.map +1 -1
- package/package.json +10 -8
- package/dist/chunk-2DOYPVF5.js +0 -481
- package/dist/chunk-2DOYPVF5.js.map +0 -1
- package/dist/chunk-2ZEJ3RR5.js +0 -89
- package/dist/chunk-2ZEJ3RR5.js.map +0 -1
- package/dist/chunk-352OTVTY.js +0 -3330
- package/dist/chunk-352OTVTY.js.map +0 -1
- package/dist/chunk-C2HQFI2C.js +0 -5927
- package/dist/chunk-C2HQFI2C.js.map +0 -1
- package/dist/chunk-DWIRLYDS.js +0 -20
- package/dist/chunk-DWIRLYDS.js.map +0 -1
- package/dist/chunk-EUXUH3YW.js +0 -15
- package/dist/chunk-EUXUH3YW.js.map +0 -1
- package/dist/chunk-F44CI35W.js +0 -145
- package/dist/chunk-F44CI35W.js.map +0 -1
- package/dist/chunk-INKI27D5.js +0 -493
- package/dist/chunk-INKI27D5.js.map +0 -1
- package/dist/chunk-JEUY3MYB.js +0 -2010
- package/dist/chunk-JEUY3MYB.js.map +0 -1
- package/dist/chunk-O4XIWHTF.js +0 -1139
- package/dist/chunk-O4XIWHTF.js.map +0 -1
- package/dist/chunk-RI47B4ZT.js +0 -1753
- package/dist/chunk-RI47B4ZT.js.map +0 -1
- package/dist/chunk-VEV4DGPH.js +0 -31
- package/dist/chunk-VEV4DGPH.js.map +0 -1
- package/dist/chunk-W4SQRNWO.js +0 -3844
- package/dist/chunk-W4SQRNWO.js.map +0 -1
package/dist/chunk-352OTVTY.js
DELETED
|
@@ -1,3330 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
QtiModalFeedback
|
|
3
|
-
} from "./chunk-O4XIWHTF.js";
|
|
4
|
-
import {
|
|
5
|
-
item_default,
|
|
6
|
-
m
|
|
7
|
-
} from "./chunk-W4SQRNWO.js";
|
|
8
|
-
import {
|
|
9
|
-
watch
|
|
10
|
-
} from "./chunk-2ZEJ3RR5.js";
|
|
11
|
-
import {
|
|
12
|
-
qtiTransformItem,
|
|
13
|
-
qtiTransformTest
|
|
14
|
-
} from "./chunk-INKI27D5.js";
|
|
15
|
-
import {
|
|
16
|
-
E,
|
|
17
|
-
INITIAL_SESSION_CONTEXT,
|
|
18
|
-
INITIAL_TEST_CONTEXT,
|
|
19
|
-
W,
|
|
20
|
-
c,
|
|
21
|
-
computedContext,
|
|
22
|
-
configContext,
|
|
23
|
-
e,
|
|
24
|
-
i,
|
|
25
|
-
i2,
|
|
26
|
-
n,
|
|
27
|
-
qtiContext,
|
|
28
|
-
r,
|
|
29
|
-
sessionContext,
|
|
30
|
-
t,
|
|
31
|
-
testContext,
|
|
32
|
-
w,
|
|
33
|
-
x
|
|
34
|
-
} from "./chunk-JEUY3MYB.js";
|
|
35
|
-
import {
|
|
36
|
-
__decorateClass
|
|
37
|
-
} from "./chunk-EUXUH3YW.js";
|
|
38
|
-
|
|
39
|
-
// ../qti-test/src/mixins/test-navigation.mixin.ts
|
|
40
|
-
var TestNavigationMixin = (superClass) => {
|
|
41
|
-
class TestNavigationClass extends superClass {
|
|
42
|
-
constructor(...args) {
|
|
43
|
-
super(...args);
|
|
44
|
-
this.navigate = null;
|
|
45
|
-
this.cacheTransform = false;
|
|
46
|
-
this.requestTimeout = 3e4;
|
|
47
|
-
this.postLoadTransformCallback = null;
|
|
48
|
-
this.postLoadTestTransformCallback = null;
|
|
49
|
-
// Navigation state tracking
|
|
50
|
-
this._activeController = null;
|
|
51
|
-
this._loadResults = [];
|
|
52
|
-
// Simple loading progress tracking
|
|
53
|
-
this._loadingState = {
|
|
54
|
-
expectedItems: 0,
|
|
55
|
-
connectedItems: 0,
|
|
56
|
-
expectedStimulus: 0,
|
|
57
|
-
loadedStimulus: 0,
|
|
58
|
-
isComplete: false
|
|
59
|
-
};
|
|
60
|
-
// Track loaded/loading stimulus hrefs to prevent duplicates
|
|
61
|
-
this._loadedStimulusHrefs = /* @__PURE__ */ new Set();
|
|
62
|
-
this._loadingStimulusHrefs = /* @__PURE__ */ new Set();
|
|
63
|
-
this._bindEventHandlers();
|
|
64
|
-
}
|
|
65
|
-
// ===========================================
|
|
66
|
-
// PUBLIC API
|
|
67
|
-
// ===========================================
|
|
68
|
-
/**
|
|
69
|
-
* Navigate to a specific item or section
|
|
70
|
-
* @param type - Navigation type ('item' or 'section')
|
|
71
|
-
* @param id - Target identifier (optional, falls back to first available)
|
|
72
|
-
*/
|
|
73
|
-
navigateTo(type, id) {
|
|
74
|
-
const targetId = id || this._getDefaultNavigationId(type);
|
|
75
|
-
if (targetId) {
|
|
76
|
-
this.dispatchEvent(
|
|
77
|
-
new CustomEvent("qti-request-navigation", {
|
|
78
|
-
detail: { type, id: targetId },
|
|
79
|
-
bubbles: true,
|
|
80
|
-
composed: true
|
|
81
|
-
})
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
// ===========================================
|
|
86
|
-
// EVENT HANDLER SETUP
|
|
87
|
-
// ===========================================
|
|
88
|
-
_bindEventHandlers() {
|
|
89
|
-
this.addEventListener("qti-request-navigation", this._handleNavigationRequest.bind(this));
|
|
90
|
-
this.addEventListener("qti-assessment-test-connected", this._handleTestConnected.bind(this));
|
|
91
|
-
this.addEventListener("qti-assessment-item-connected", this._handleItemConnected.bind(this));
|
|
92
|
-
this.addEventListener("qti-assessment-stimulus-ref-connected", this._handleStimulusRefConnected.bind(this));
|
|
93
|
-
}
|
|
94
|
-
_handleTestConnected(e2) {
|
|
95
|
-
this._testElement = e2.detail;
|
|
96
|
-
this._initializeNavigation();
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Handle item connection events - track connected items and discover stimulus references
|
|
100
|
-
*/
|
|
101
|
-
_handleItemConnected(e2) {
|
|
102
|
-
const itemRef = e2.detail;
|
|
103
|
-
this._loadingState.connectedItems++;
|
|
104
|
-
const stimulusRefs = itemRef.querySelectorAll("qti-assessment-stimulus-ref");
|
|
105
|
-
this._loadingState.expectedStimulus += stimulusRefs.length;
|
|
106
|
-
this._checkLoadingComplete();
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Handle stimulus reference connection events with duplicate prevention
|
|
110
|
-
*/
|
|
111
|
-
async _handleStimulusRefConnected(e2) {
|
|
112
|
-
e2.preventDefault();
|
|
113
|
-
const { element, item } = e2;
|
|
114
|
-
console.info("Stimulus ref connected:", {
|
|
115
|
-
identifier: element.identifier,
|
|
116
|
-
href: element.href,
|
|
117
|
-
item: item.identifier
|
|
118
|
-
});
|
|
119
|
-
if (this._loadedStimulusHrefs.has(element.href)) {
|
|
120
|
-
console.info("Stimulus already loaded, skipping:", element.href);
|
|
121
|
-
this._loadingState.loadedStimulus++;
|
|
122
|
-
this._checkLoadingComplete();
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
if (this._loadingStimulusHrefs.has(element.href)) {
|
|
126
|
-
console.info("Stimulus already loading, skipping duplicate:", element.href);
|
|
127
|
-
this._loadingState.loadedStimulus++;
|
|
128
|
-
this._checkLoadingComplete();
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
this._loadingStimulusHrefs.add(element.href);
|
|
132
|
-
console.info("Starting stimulus load:", element.href);
|
|
133
|
-
try {
|
|
134
|
-
await this._loadStimulusRef(element, item);
|
|
135
|
-
this._loadedStimulusHrefs.add(element.href);
|
|
136
|
-
this._loadingState.loadedStimulus++;
|
|
137
|
-
console.info("Stimulus loaded successfully:", element.href);
|
|
138
|
-
this._checkLoadingComplete();
|
|
139
|
-
} catch (error) {
|
|
140
|
-
if (error.name !== "AbortError") {
|
|
141
|
-
console.warn(`Failed to load stimulus ${element.identifier}:`, error);
|
|
142
|
-
}
|
|
143
|
-
this._loadingState.loadedStimulus++;
|
|
144
|
-
this._checkLoadingComplete();
|
|
145
|
-
} finally {
|
|
146
|
-
this._loadingStimulusHrefs.delete(element.href);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
// ===========================================
|
|
150
|
-
// NAVIGATION FLOW
|
|
151
|
-
// ===========================================
|
|
152
|
-
_getDefaultNavigationId(type) {
|
|
153
|
-
if (type === "section") {
|
|
154
|
-
return this._testElement?.querySelector("qti-assessment-section")?.identifier;
|
|
155
|
-
}
|
|
156
|
-
return this.sessionContext?.navItemRefId ?? this._testElement?.querySelector("qti-assessment-item-ref")?.identifier;
|
|
157
|
-
}
|
|
158
|
-
_initializeNavigation() {
|
|
159
|
-
if (!this.navigate) return;
|
|
160
|
-
const id = this._getDefaultNavigationId(this.navigate);
|
|
161
|
-
if (id) {
|
|
162
|
-
this.navigateTo(this.navigate, id);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Main navigation request handler with proper lifecycle management
|
|
167
|
-
*/
|
|
168
|
-
async _handleNavigationRequest({ detail }) {
|
|
169
|
-
if (!detail?.id) return;
|
|
170
|
-
this._cancelPreviousNavigation();
|
|
171
|
-
try {
|
|
172
|
-
this._dispatchLoadingStarted(detail.type, detail.id);
|
|
173
|
-
this._activeController = new AbortController();
|
|
174
|
-
await this._executeNavigation(detail.type, detail.id);
|
|
175
|
-
} catch (error) {
|
|
176
|
-
this._handleNavigationError(error, detail.type, detail.id);
|
|
177
|
-
} finally {
|
|
178
|
-
this._activeController = null;
|
|
179
|
-
this._dispatchLoadingEnded(detail.type, detail.id);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
_handleNavigationError(error, type, id) {
|
|
183
|
-
if (error.name !== "AbortError") {
|
|
184
|
-
this._dispatchError(this._createNavigationError(error, type, id));
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
async _executeNavigation(type, id) {
|
|
188
|
-
if (type === "item") {
|
|
189
|
-
await this._navigateToItem(id);
|
|
190
|
-
} else {
|
|
191
|
-
await this._navigateToSection(id);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Navigate to specific item with simple state tracking
|
|
196
|
-
*/
|
|
197
|
-
async _navigateToItem(itemId) {
|
|
198
|
-
const itemRef = this._findItemRef(itemId);
|
|
199
|
-
this._updateSessionContext(itemRef, itemId);
|
|
200
|
-
this._resetLoadingState();
|
|
201
|
-
this._loadingState.expectedItems = 1;
|
|
202
|
-
await this._loadItems([itemId]);
|
|
203
|
-
await this._waitForLoadingComplete();
|
|
204
|
-
this._dispatchTestLoaded(this._loadResults);
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Navigate to section with simple state tracking
|
|
208
|
-
*/
|
|
209
|
-
async _navigateToSection(sectionId) {
|
|
210
|
-
const sectionEl = this._findSection(sectionId);
|
|
211
|
-
const navPartId = sectionEl?.closest("qti-test-part")?.identifier;
|
|
212
|
-
this.sessionContext = {
|
|
213
|
-
...this.sessionContext,
|
|
214
|
-
navPartId,
|
|
215
|
-
navSectionId: sectionId,
|
|
216
|
-
navItemRefId: null
|
|
217
|
-
};
|
|
218
|
-
const itemIds = this._getSectionItemIds(sectionId);
|
|
219
|
-
this._resetLoadingState();
|
|
220
|
-
this._loadingState.expectedItems = itemIds.length;
|
|
221
|
-
await this._loadItems(itemIds);
|
|
222
|
-
await this._waitForLoadingComplete();
|
|
223
|
-
this._dispatchTestLoaded(this._loadResults);
|
|
224
|
-
}
|
|
225
|
-
// ===========================================
|
|
226
|
-
// LOADING STATE MANAGEMENT
|
|
227
|
-
// ===========================================
|
|
228
|
-
/**
|
|
229
|
-
* Reset loading state for new navigation
|
|
230
|
-
*/
|
|
231
|
-
_resetLoadingState() {
|
|
232
|
-
this._loadingState = {
|
|
233
|
-
expectedItems: 0,
|
|
234
|
-
connectedItems: 0,
|
|
235
|
-
expectedStimulus: 0,
|
|
236
|
-
loadedStimulus: 0,
|
|
237
|
-
isComplete: false
|
|
238
|
-
};
|
|
239
|
-
this._loadedStimulusHrefs.clear();
|
|
240
|
-
this._loadingStimulusHrefs.clear();
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Check if loading is complete and dispatch events accordingly
|
|
244
|
-
*/
|
|
245
|
-
_checkLoadingComplete() {
|
|
246
|
-
const allItemsConnected = this._loadingState.connectedItems >= this._loadingState.expectedItems;
|
|
247
|
-
const allStimulusLoaded = this._loadingState.loadedStimulus >= this._loadingState.expectedStimulus;
|
|
248
|
-
if (allItemsConnected && allStimulusLoaded && !this._loadingState.isComplete) {
|
|
249
|
-
this._loadingState.isComplete = true;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Wait for loading to complete with simple polling
|
|
254
|
-
*/
|
|
255
|
-
async _waitForLoadingComplete() {
|
|
256
|
-
while (!this._loadingState.isComplete) {
|
|
257
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Get current loading progress for external consumption
|
|
262
|
-
*/
|
|
263
|
-
getLoadingProgress() {
|
|
264
|
-
return { ...this._loadingState };
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Load stimulus reference with simple tracking
|
|
268
|
-
*/
|
|
269
|
-
async _loadStimulusRef(element, item) {
|
|
270
|
-
console.info("Loading stimulus:", element.href);
|
|
271
|
-
const stimulus = await this._loadStimulus(element.href);
|
|
272
|
-
console.info("Stimulus loaded, applying content:", stimulus ? "has content" : "no content");
|
|
273
|
-
this._applyStimulusContent(stimulus, element, item);
|
|
274
|
-
}
|
|
275
|
-
_applyStimulusContent(stimulus, element, item) {
|
|
276
|
-
if (!stimulus) {
|
|
277
|
-
console.warn("No stimulus content to apply");
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
const elements = stimulus.querySelectorAll("qti-stimulus-body, qti-stylesheet");
|
|
281
|
-
console.info(`Found ${elements.length} stimulus elements to apply for ${element.identifier}`);
|
|
282
|
-
if (elements.length === 0) {
|
|
283
|
-
console.warn("No qti-stimulus-body or qti-stylesheet elements found in stimulus");
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
let targets = [];
|
|
287
|
-
const specificTarget = document.querySelector(
|
|
288
|
-
`qti-assessment-item[identifier="${item.identifier}"] [data-stimulus-idref="${element.identifier}"]`
|
|
289
|
-
);
|
|
290
|
-
if (specificTarget) {
|
|
291
|
-
targets.push(specificTarget);
|
|
292
|
-
console.info("Found specific target:", specificTarget);
|
|
293
|
-
} else {
|
|
294
|
-
const allTargetsWithId = Array.from(this.querySelectorAll(`[data-stimulus-idref="${element.identifier}"]`));
|
|
295
|
-
if (allTargetsWithId.length > 0) {
|
|
296
|
-
targets = allTargetsWithId;
|
|
297
|
-
console.info("Found targets by identifier:", allTargetsWithId.length);
|
|
298
|
-
} else {
|
|
299
|
-
const allStimulusTargets = Array.from(this.querySelectorAll("[data-stimulus-idref]"));
|
|
300
|
-
targets = allStimulusTargets;
|
|
301
|
-
console.info("Using fallback targets:", allStimulusTargets.length);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
if (targets.length === 0) {
|
|
305
|
-
console.warn("No targets found for stimulus content");
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
targets.forEach((target, index) => {
|
|
309
|
-
target.innerHTML = "";
|
|
310
|
-
const clonedElements = Array.from(elements).map((el) => el.cloneNode(true));
|
|
311
|
-
target.append(...clonedElements);
|
|
312
|
-
console.info(`Applied stimulus content to target ${index + 1}/${targets.length}`);
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
// ===========================================
|
|
316
|
-
// LOADING INFRASTRUCTURE
|
|
317
|
-
// ===========================================
|
|
318
|
-
/**
|
|
319
|
-
* Cancel previous navigation and clean up all state
|
|
320
|
-
*/
|
|
321
|
-
_cancelPreviousNavigation() {
|
|
322
|
-
if (this._activeController) {
|
|
323
|
-
this._activeController.abort();
|
|
324
|
-
console.info("Previous navigation request cancelled");
|
|
325
|
-
}
|
|
326
|
-
this._clearNavigationState();
|
|
327
|
-
}
|
|
328
|
-
_clearNavigationState() {
|
|
329
|
-
this._clearLoadedItems();
|
|
330
|
-
this._resetLoadingState();
|
|
331
|
-
this._loadResults = [];
|
|
332
|
-
}
|
|
333
|
-
/**
|
|
334
|
-
* Load items with simple tracking
|
|
335
|
-
*/
|
|
336
|
-
async _loadItems(itemIds) {
|
|
337
|
-
if (!this._testElement || itemIds.length === 0) return;
|
|
338
|
-
const itemRefs = itemIds.map((id) => this._findItemRef(id));
|
|
339
|
-
this._clearLoadedItems();
|
|
340
|
-
this._clearStimulusRef();
|
|
341
|
-
const results = await Promise.all(itemRefs.map((ref) => this._loadSingleItem(ref)));
|
|
342
|
-
const validResults = results.filter(Boolean);
|
|
343
|
-
validResults.forEach(({ itemRef, doc }) => {
|
|
344
|
-
if (itemRef && doc) itemRef.xmlDoc = doc;
|
|
345
|
-
});
|
|
346
|
-
this._loadResults = validResults;
|
|
347
|
-
}
|
|
348
|
-
async _loadSingleItem(itemRef) {
|
|
349
|
-
try {
|
|
350
|
-
let transformer = await qtiTransformItem(this.cacheTransform).load(
|
|
351
|
-
itemRef.href,
|
|
352
|
-
this._activeController?.signal
|
|
353
|
-
);
|
|
354
|
-
if (this.postLoadTransformCallback) {
|
|
355
|
-
transformer = await this.postLoadTransformCallback(transformer, itemRef);
|
|
356
|
-
}
|
|
357
|
-
return { itemRef, doc: transformer.htmlDoc() };
|
|
358
|
-
} catch (error) {
|
|
359
|
-
if (error.name === "AbortError") {
|
|
360
|
-
console.info(`Item load for ${itemRef.identifier} was aborted`);
|
|
361
|
-
throw error;
|
|
362
|
-
}
|
|
363
|
-
console.warn(`Failed to load item ${itemRef.identifier}:`, error);
|
|
364
|
-
return null;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
async _loadStimulus(href) {
|
|
368
|
-
const transformer = await qtiTransformItem().load(href, this._activeController?.signal);
|
|
369
|
-
return transformer.htmlDoc();
|
|
370
|
-
}
|
|
371
|
-
// ===========================================
|
|
372
|
-
// UTILITIES
|
|
373
|
-
// ===========================================
|
|
374
|
-
_findItemRef(itemId) {
|
|
375
|
-
const itemRef = this._testElement?.querySelector(
|
|
376
|
-
`qti-assessment-item-ref[identifier="${itemId}"]`
|
|
377
|
-
);
|
|
378
|
-
if (!itemRef) {
|
|
379
|
-
throw new Error(`Item with identifier "${itemId}" not found`);
|
|
380
|
-
}
|
|
381
|
-
return itemRef;
|
|
382
|
-
}
|
|
383
|
-
_findSection(sectionId) {
|
|
384
|
-
return this._testElement?.querySelector(`qti-assessment-section[identifier="${sectionId}"]`) || null;
|
|
385
|
-
}
|
|
386
|
-
_updateSessionContext(itemRef, itemId) {
|
|
387
|
-
const navPartId = itemRef.closest("qti-test-part")?.identifier;
|
|
388
|
-
const navSectionId = itemRef.closest("qti-assessment-section")?.identifier;
|
|
389
|
-
this.sessionContext = {
|
|
390
|
-
...this.sessionContext,
|
|
391
|
-
navPartId,
|
|
392
|
-
navSectionId,
|
|
393
|
-
navItemRefId: itemId
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
_getSectionItemIds(sectionId) {
|
|
397
|
-
return Array.from(
|
|
398
|
-
this._testElement.querySelectorAll(
|
|
399
|
-
`qti-assessment-section[identifier="${sectionId}"] > qti-assessment-item-ref`
|
|
400
|
-
)
|
|
401
|
-
).map((ref) => ref.identifier).filter(Boolean);
|
|
402
|
-
}
|
|
403
|
-
_clearLoadedItems() {
|
|
404
|
-
const itemRefs = this._testElement?.querySelectorAll("qti-assessment-item-ref");
|
|
405
|
-
Array.from(itemRefs || []).forEach((element) => {
|
|
406
|
-
element.xmlDoc = null;
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
_clearStimulusRef() {
|
|
410
|
-
this.querySelectorAll("[data-stimulus-idref]").forEach((el) => el.innerHTML = "");
|
|
411
|
-
}
|
|
412
|
-
_createNavigationError(error, type, id) {
|
|
413
|
-
return {
|
|
414
|
-
message: error.message || `Failed to load ${type}: ${id}`,
|
|
415
|
-
details: error,
|
|
416
|
-
itemId: type === "item" ? id : void 0,
|
|
417
|
-
sectionId: type === "section" ? id : void 0
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
// ===========================================
|
|
421
|
-
// EVENT DISPATCHING
|
|
422
|
-
// ===========================================
|
|
423
|
-
_dispatchLoadingStarted(type, id) {
|
|
424
|
-
this.dispatchEvent(
|
|
425
|
-
new CustomEvent("qti-navigation-loading-started", {
|
|
426
|
-
detail: { type, id },
|
|
427
|
-
bubbles: true,
|
|
428
|
-
composed: true
|
|
429
|
-
})
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
_dispatchLoadingEnded(type, id) {
|
|
433
|
-
this.dispatchEvent(
|
|
434
|
-
new CustomEvent("qti-navigation-loading-ended", {
|
|
435
|
-
detail: { type, id },
|
|
436
|
-
bubbles: true,
|
|
437
|
-
composed: true
|
|
438
|
-
})
|
|
439
|
-
);
|
|
440
|
-
}
|
|
441
|
-
_dispatchError(error) {
|
|
442
|
-
this.dispatchEvent(
|
|
443
|
-
new CustomEvent("qti-navigation-error", {
|
|
444
|
-
detail: error,
|
|
445
|
-
bubbles: true,
|
|
446
|
-
composed: true
|
|
447
|
-
})
|
|
448
|
-
);
|
|
449
|
-
}
|
|
450
|
-
_dispatchTestLoaded(results) {
|
|
451
|
-
requestAnimationFrame(() => {
|
|
452
|
-
this.dispatchEvent(
|
|
453
|
-
new CustomEvent("qti-test-loaded", {
|
|
454
|
-
detail: results.map(({ itemRef }) => ({
|
|
455
|
-
identifier: itemRef?.identifier,
|
|
456
|
-
element: itemRef
|
|
457
|
-
})),
|
|
458
|
-
bubbles: true,
|
|
459
|
-
composed: true
|
|
460
|
-
})
|
|
461
|
-
);
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
__decorateClass([
|
|
466
|
-
n({ type: String })
|
|
467
|
-
], TestNavigationClass.prototype, "navigate", 2);
|
|
468
|
-
__decorateClass([
|
|
469
|
-
n({ type: Boolean, attribute: "cache-transform" })
|
|
470
|
-
], TestNavigationClass.prototype, "cacheTransform", 2);
|
|
471
|
-
__decorateClass([
|
|
472
|
-
n({ type: Number })
|
|
473
|
-
], TestNavigationClass.prototype, "requestTimeout", 2);
|
|
474
|
-
__decorateClass([
|
|
475
|
-
n({ attribute: false })
|
|
476
|
-
], TestNavigationClass.prototype, "postLoadTransformCallback", 2);
|
|
477
|
-
__decorateClass([
|
|
478
|
-
n({ attribute: false })
|
|
479
|
-
], TestNavigationClass.prototype, "postLoadTestTransformCallback", 2);
|
|
480
|
-
return TestNavigationClass;
|
|
481
|
-
};
|
|
482
|
-
|
|
483
|
-
// ../qti-test/src/mixins/test-view.mixin.ts
|
|
484
|
-
var TestViewMixin = (superClass) => {
|
|
485
|
-
class TestViewClass extends superClass {
|
|
486
|
-
constructor(...args) {
|
|
487
|
-
super(...args);
|
|
488
|
-
this.sessionContext = { ...this.sessionContext, view: "candidate" };
|
|
489
|
-
this.addEventListener("on-test-switch-view", (e2) => {
|
|
490
|
-
this.sessionContext = { ...this.sessionContext, view: e2.detail };
|
|
491
|
-
this._updateElementView();
|
|
492
|
-
});
|
|
493
|
-
this.addEventListener("qti-assessment-test-connected", () => {
|
|
494
|
-
this._updateElementView();
|
|
495
|
-
});
|
|
496
|
-
this.addEventListener("qti-assessment-item-connected", (e2) => {
|
|
497
|
-
this._updateElementView();
|
|
498
|
-
this._setCorrectResponseVisibility(e2.detail);
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
willUpdate(changedProperties) {
|
|
502
|
-
super.willUpdate(changedProperties);
|
|
503
|
-
if (changedProperties.has("sessionContext")) {
|
|
504
|
-
this._updateElementView();
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
// Method to handle view updates for elements based on the current context view
|
|
508
|
-
_updateElementView() {
|
|
509
|
-
if (this._testElement) {
|
|
510
|
-
const viewElements = Array.from(this._testElement.querySelectorAll("[view]"));
|
|
511
|
-
viewElements.forEach((element) => {
|
|
512
|
-
element.classList.toggle("show", element.getAttribute("view") === this.sessionContext.view);
|
|
513
|
-
});
|
|
514
|
-
const assessmentItemRef = this._testElement.querySelector(
|
|
515
|
-
`qti-assessment-item-ref[identifier="${this.sessionContext.navItemRefId}"]`
|
|
516
|
-
);
|
|
517
|
-
const assessmentItem = assessmentItemRef?.assessmentItem;
|
|
518
|
-
if (assessmentItem) {
|
|
519
|
-
assessmentItem.showCorrectResponse(this.sessionContext.view === "scorer");
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
// Event handler for connected QTI assessment items
|
|
524
|
-
_setCorrectResponseVisibility(assessmentItem) {
|
|
525
|
-
assessmentItem.showCorrectResponse(this.sessionContext.view === "scorer");
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
return TestViewClass;
|
|
529
|
-
};
|
|
530
|
-
|
|
531
|
-
// ../qti-test/src/mixins/test-base.ts
|
|
532
|
-
var TestBaseMixin = (superClass) => {
|
|
533
|
-
class TestBaseClass extends superClass {
|
|
534
|
-
constructor(...args) {
|
|
535
|
-
super(...args);
|
|
536
|
-
this.testContext = INITIAL_TEST_CONTEXT;
|
|
537
|
-
this.sessionContext = INITIAL_SESSION_CONTEXT;
|
|
538
|
-
/**
|
|
539
|
-
* Updates the variables of an assessment item in the test context.
|
|
540
|
-
* - Matches the assessment item with the corresponding test context item.
|
|
541
|
-
* - If the item is not found, logs a warning.
|
|
542
|
-
* - Updates variables in the test context if exactly one variable exists.
|
|
543
|
-
* - Otherwise, syncs the assessment item's variables with the test context.
|
|
544
|
-
*
|
|
545
|
-
* @param assessmentItem - The assessment item to update.
|
|
546
|
-
*/
|
|
547
|
-
this._updateItemInTestContext = (assessmentItem) => {
|
|
548
|
-
const context = assessmentItem._context;
|
|
549
|
-
const identifier = context.identifier;
|
|
550
|
-
const fullVariables = context.variables;
|
|
551
|
-
const itemContext = this.testContext.items.find((i4) => i4?.identifier === identifier);
|
|
552
|
-
if (!itemContext) {
|
|
553
|
-
console.warn(`Item IDs between assessment.xml and item.xml should match: ${identifier} is not found!`);
|
|
554
|
-
return;
|
|
555
|
-
}
|
|
556
|
-
if (itemContext.variables?.length === 1) {
|
|
557
|
-
this._updateItemVariablesInTestContext(identifier, fullVariables);
|
|
558
|
-
} else {
|
|
559
|
-
const newVariables = [...assessmentItem.variables];
|
|
560
|
-
for (const variable of itemContext.variables) {
|
|
561
|
-
const currentVariable = newVariables.find((v) => v.identifier === variable.identifier);
|
|
562
|
-
if (currentVariable) {
|
|
563
|
-
currentVariable.value = variable.value;
|
|
564
|
-
} else {
|
|
565
|
-
newVariables.push(variable);
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
assessmentItem.variables = newVariables;
|
|
569
|
-
}
|
|
570
|
-
};
|
|
571
|
-
this._initializeEventListeners();
|
|
572
|
-
}
|
|
573
|
-
updateItemVariables(itemRefID, variables) {
|
|
574
|
-
const itemContext = this.testContext.items.find((item) => item.identifier === itemRefID);
|
|
575
|
-
if (itemContext) {
|
|
576
|
-
itemContext.variables = itemContext.variables.map((variable) => {
|
|
577
|
-
const updatedVariable = variables.find((v) => v.identifier === variable.identifier);
|
|
578
|
-
return updatedVariable ? { ...variable, ...updatedVariable } : variable;
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
const itemRef = this._testElement.querySelector(
|
|
582
|
-
`qti-assessment-item-ref[identifier="${itemRefID}"]`
|
|
583
|
-
);
|
|
584
|
-
if (itemRef && itemRef.assessmentItem) {
|
|
585
|
-
itemRef.assessmentItem.variables = variables;
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
_initializeEventListeners() {
|
|
589
|
-
this.addEventListener("qti-assessment-test-connected", (e2) => {
|
|
590
|
-
this.testContext = INITIAL_TEST_CONTEXT;
|
|
591
|
-
this.sessionContext = INITIAL_SESSION_CONTEXT;
|
|
592
|
-
if (this.testContext && this.testContext.items.length > 0) return;
|
|
593
|
-
this._testElement = e2.detail;
|
|
594
|
-
const items = Array.from(this._testElement.querySelectorAll("qti-assessment-item-ref")).map((itemRef) => {
|
|
595
|
-
return {
|
|
596
|
-
href: itemRef.href,
|
|
597
|
-
identifier: itemRef.identifier,
|
|
598
|
-
category: itemRef.category,
|
|
599
|
-
variables: [
|
|
600
|
-
{
|
|
601
|
-
identifier: "completionStatus",
|
|
602
|
-
value: "not_attempted",
|
|
603
|
-
type: "outcome"
|
|
604
|
-
}
|
|
605
|
-
]
|
|
606
|
-
};
|
|
607
|
-
});
|
|
608
|
-
this.testContext = { ...this.testContext, items };
|
|
609
|
-
});
|
|
610
|
-
this.addEventListener("qti-assessment-item-connected", (e2) => {
|
|
611
|
-
const assessmentItem = e2.detail;
|
|
612
|
-
const assessmentRefId = assessmentItem.closest("qti-assessment-item-ref")?.identifier;
|
|
613
|
-
if (assessmentRefId) {
|
|
614
|
-
assessmentItem.assessmentItemRefId = assessmentRefId;
|
|
615
|
-
}
|
|
616
|
-
this._updateItemInTestContext(e2.detail);
|
|
617
|
-
});
|
|
618
|
-
this.addEventListener("qti-item-context-updated", (e2) => {
|
|
619
|
-
this._updateItemVariablesInTestContext(e2.detail.itemContext.identifier, e2.detail.itemContext.variables);
|
|
620
|
-
});
|
|
621
|
-
}
|
|
622
|
-
_updateItemVariablesInTestContext(identifier, variables) {
|
|
623
|
-
this.testContext = {
|
|
624
|
-
...this.testContext,
|
|
625
|
-
// Spread existing test context properties
|
|
626
|
-
items: this.testContext.items.map((itemContext) => {
|
|
627
|
-
if (itemContext.identifier !== identifier) {
|
|
628
|
-
return itemContext;
|
|
629
|
-
}
|
|
630
|
-
return {
|
|
631
|
-
...itemContext,
|
|
632
|
-
// Keep other properties of the item context
|
|
633
|
-
variables: variables.map((variable) => {
|
|
634
|
-
const matchingVariable = itemContext.variables.find((v) => v.identifier === variable.identifier);
|
|
635
|
-
return matchingVariable ? { ...matchingVariable, ...variable } : variable;
|
|
636
|
-
})
|
|
637
|
-
};
|
|
638
|
-
})
|
|
639
|
-
};
|
|
640
|
-
this.dispatchEvent(
|
|
641
|
-
new CustomEvent("qti-test-context-updated", { detail: this.testContext, bubbles: false, composed: false })
|
|
642
|
-
);
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
__decorateClass([
|
|
646
|
-
n({ attribute: false, type: Object }),
|
|
647
|
-
e({ context: testContext })
|
|
648
|
-
], TestBaseClass.prototype, "testContext", 2);
|
|
649
|
-
__decorateClass([
|
|
650
|
-
n({ attribute: false, type: Object }),
|
|
651
|
-
e({ context: sessionContext })
|
|
652
|
-
], TestBaseClass.prototype, "sessionContext", 2);
|
|
653
|
-
return TestBaseClass;
|
|
654
|
-
};
|
|
655
|
-
var TestBase = class extends TestBaseMixin(i2) {
|
|
656
|
-
};
|
|
657
|
-
|
|
658
|
-
// ../qti-test/src/mixins/test-processing.mixin.ts
|
|
659
|
-
var TestProcessingMixin = (superClass) => {
|
|
660
|
-
class TestProcessingElement extends superClass {
|
|
661
|
-
constructor(...args) {
|
|
662
|
-
super(...args);
|
|
663
|
-
this.addEventListener("qti-register-variable", (e2) => {
|
|
664
|
-
this.testContext = {
|
|
665
|
-
...this.testContext,
|
|
666
|
-
testOutcomeVariables: [...this.testContext.testOutcomeVariables || [], e2.detail.variable]
|
|
667
|
-
};
|
|
668
|
-
e2.stopPropagation();
|
|
669
|
-
});
|
|
670
|
-
this.addEventListener(
|
|
671
|
-
"qti-set-outcome-value",
|
|
672
|
-
(e2) => {
|
|
673
|
-
const { outcomeIdentifier, value } = e2.detail;
|
|
674
|
-
this.updateOutcomeVariable(outcomeIdentifier, value);
|
|
675
|
-
e2.stopPropagation();
|
|
676
|
-
}
|
|
677
|
-
);
|
|
678
|
-
}
|
|
679
|
-
outcomeProcessing() {
|
|
680
|
-
const outcomeProcessor = this.querySelector("qti-outcome-processing");
|
|
681
|
-
if (!outcomeProcessor) return false;
|
|
682
|
-
outcomeProcessor?.process();
|
|
683
|
-
return true;
|
|
684
|
-
}
|
|
685
|
-
/* --------------------------- ENABLED WHEN UNIT TESTING OUTCOME PROCESSING ------------------------------------ */
|
|
686
|
-
updateOutcomeVariable(identifier, value) {
|
|
687
|
-
const outcomeVariable = this.getOutcome(identifier);
|
|
688
|
-
if (!outcomeVariable) {
|
|
689
|
-
console.warn(`Can not set qti-outcome-identifier: ${identifier}, it is not available`);
|
|
690
|
-
return;
|
|
691
|
-
}
|
|
692
|
-
this.testContext = {
|
|
693
|
-
...this.testContext,
|
|
694
|
-
testOutcomeVariables: this.testContext.testOutcomeVariables?.map((v) => {
|
|
695
|
-
if (v.identifier !== identifier) {
|
|
696
|
-
return v;
|
|
697
|
-
}
|
|
698
|
-
return {
|
|
699
|
-
...v,
|
|
700
|
-
value: outcomeVariable.cardinality === "single" ? value : [...v.value, value]
|
|
701
|
-
};
|
|
702
|
-
})
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
|
-
getOutcome(identifier) {
|
|
706
|
-
return this.getVariable(identifier);
|
|
707
|
-
}
|
|
708
|
-
getVariable(identifier) {
|
|
709
|
-
return this.testContext.testOutcomeVariables?.find((v) => v.identifier === identifier) || null;
|
|
710
|
-
}
|
|
711
|
-
/* --------------------------- ENABLED WHEN UNIT TESTING OUTCOME PROCESSING ------------------------------------ */
|
|
712
|
-
}
|
|
713
|
-
return TestProcessingElement;
|
|
714
|
-
};
|
|
715
|
-
|
|
716
|
-
// ../qti-test/src/components/qti-test/qti-test.ts
|
|
717
|
-
var QtiTest = class extends TestNavigationMixin(TestViewMixin(TestProcessingMixin(TestBaseMixin(i2)))) {
|
|
718
|
-
// TODO: Properly implement IQtiTest interface
|
|
719
|
-
// export class QtiTest extends TestLoaderMixin(TestNavigationMixin(TestViewMixin(TestBase))) {
|
|
720
|
-
/**
|
|
721
|
-
* Renders the component's template.
|
|
722
|
-
* Provides a default `<slot>` for content projection.
|
|
723
|
-
*/
|
|
724
|
-
async connectedCallback() {
|
|
725
|
-
super.connectedCallback();
|
|
726
|
-
await this.updateComplete;
|
|
727
|
-
this.dispatchEvent(new CustomEvent("qti-test-connected", { detail: this }));
|
|
728
|
-
}
|
|
729
|
-
render() {
|
|
730
|
-
return x`<slot></slot>`;
|
|
731
|
-
}
|
|
732
|
-
};
|
|
733
|
-
QtiTest = __decorateClass([
|
|
734
|
-
t("qti-test")
|
|
735
|
-
], QtiTest);
|
|
736
|
-
|
|
737
|
-
// ../qti-test/src/components/qti-assessment-item-ref/qti-assessment-item-ref.ts
|
|
738
|
-
var stringToBooleanConverter = {
|
|
739
|
-
fromAttribute(value) {
|
|
740
|
-
return value === "true";
|
|
741
|
-
},
|
|
742
|
-
toAttribute(value) {
|
|
743
|
-
return value ? "true" : "false";
|
|
744
|
-
}
|
|
745
|
-
};
|
|
746
|
-
var QtiAssessmentItemRef = class extends i2 {
|
|
747
|
-
constructor() {
|
|
748
|
-
super(...arguments);
|
|
749
|
-
// @consume({ context: computedContext, subscribe: true })
|
|
750
|
-
// private computedContext: ComputedContext;
|
|
751
|
-
this.weigths = /* @__PURE__ */ new Map();
|
|
752
|
-
}
|
|
753
|
-
// the XMLDocument
|
|
754
|
-
createRenderRoot() {
|
|
755
|
-
return this;
|
|
756
|
-
}
|
|
757
|
-
get assessmentItem() {
|
|
758
|
-
return this.renderRoot?.querySelector("qti-assessment-item");
|
|
759
|
-
}
|
|
760
|
-
async connectedCallback() {
|
|
761
|
-
super.connectedCallback();
|
|
762
|
-
await this.updateComplete;
|
|
763
|
-
this.dispatchEvent(
|
|
764
|
-
new CustomEvent("qti-assessment-item-ref-connected", {
|
|
765
|
-
bubbles: true,
|
|
766
|
-
composed: true,
|
|
767
|
-
detail: { identifier: this.identifier, href: this.href, category: this.category }
|
|
768
|
-
})
|
|
769
|
-
);
|
|
770
|
-
}
|
|
771
|
-
render() {
|
|
772
|
-
return this.myTemplate ? this.myTemplate({ xmlDoc: this.xmlDoc }) : this.xmlDoc;
|
|
773
|
-
}
|
|
774
|
-
};
|
|
775
|
-
__decorateClass([
|
|
776
|
-
n({ type: String })
|
|
777
|
-
], QtiAssessmentItemRef.prototype, "category", 2);
|
|
778
|
-
__decorateClass([
|
|
779
|
-
n({ type: String })
|
|
780
|
-
], QtiAssessmentItemRef.prototype, "identifier", 2);
|
|
781
|
-
__decorateClass([
|
|
782
|
-
n({ type: Boolean, converter: stringToBooleanConverter })
|
|
783
|
-
], QtiAssessmentItemRef.prototype, "required", 2);
|
|
784
|
-
__decorateClass([
|
|
785
|
-
n({ type: Boolean, converter: stringToBooleanConverter })
|
|
786
|
-
], QtiAssessmentItemRef.prototype, "fixed", 2);
|
|
787
|
-
__decorateClass([
|
|
788
|
-
n({ type: String })
|
|
789
|
-
], QtiAssessmentItemRef.prototype, "href", 2);
|
|
790
|
-
__decorateClass([
|
|
791
|
-
n({ type: Object, attribute: false })
|
|
792
|
-
], QtiAssessmentItemRef.prototype, "xmlDoc", 2);
|
|
793
|
-
if (!customElements.get("qti-assessment-item-ref")) {
|
|
794
|
-
customElements.define("qti-assessment-item-ref", QtiAssessmentItemRef);
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
// ../qti-test/src/components/qti-assessment-section/qti-assessment-section.ts
|
|
798
|
-
var stringToBooleanConverter2 = {
|
|
799
|
-
fromAttribute(value) {
|
|
800
|
-
return value === "true";
|
|
801
|
-
},
|
|
802
|
-
toAttribute(value) {
|
|
803
|
-
return value ? "true" : "false";
|
|
804
|
-
}
|
|
805
|
-
};
|
|
806
|
-
var QtiAssessmentSection = class extends i2 {
|
|
807
|
-
constructor() {
|
|
808
|
-
super(...arguments);
|
|
809
|
-
this._title = "";
|
|
810
|
-
}
|
|
811
|
-
get title() {
|
|
812
|
-
return this._title;
|
|
813
|
-
}
|
|
814
|
-
set title(value) {
|
|
815
|
-
this._title = value;
|
|
816
|
-
this.removeAttribute("title");
|
|
817
|
-
this.setAttribute("data-title", value);
|
|
818
|
-
}
|
|
819
|
-
async connectedCallback() {
|
|
820
|
-
this._title = this.getAttribute("title") || "";
|
|
821
|
-
super.connectedCallback();
|
|
822
|
-
await this.updateComplete;
|
|
823
|
-
this.dispatchEvent(
|
|
824
|
-
new Event("qti-assessment-section-connected", {
|
|
825
|
-
bubbles: true,
|
|
826
|
-
composed: true
|
|
827
|
-
})
|
|
828
|
-
);
|
|
829
|
-
}
|
|
830
|
-
render() {
|
|
831
|
-
return x`<slot name="qti-rubric-block"></slot><slot></slot>`;
|
|
832
|
-
}
|
|
833
|
-
};
|
|
834
|
-
__decorateClass([
|
|
835
|
-
n({ type: String })
|
|
836
|
-
], QtiAssessmentSection.prototype, "identifier", 2);
|
|
837
|
-
__decorateClass([
|
|
838
|
-
n({ type: String })
|
|
839
|
-
], QtiAssessmentSection.prototype, "required", 2);
|
|
840
|
-
__decorateClass([
|
|
841
|
-
n({ type: Boolean, converter: stringToBooleanConverter2 })
|
|
842
|
-
], QtiAssessmentSection.prototype, "fixed", 2);
|
|
843
|
-
__decorateClass([
|
|
844
|
-
n({ type: Boolean, converter: stringToBooleanConverter2 })
|
|
845
|
-
], QtiAssessmentSection.prototype, "visible", 2);
|
|
846
|
-
__decorateClass([
|
|
847
|
-
n({ type: Boolean, converter: stringToBooleanConverter2, attribute: "keep-together" })
|
|
848
|
-
], QtiAssessmentSection.prototype, "keepTogether", 2);
|
|
849
|
-
__decorateClass([
|
|
850
|
-
c({ context: testContext, subscribe: true })
|
|
851
|
-
], QtiAssessmentSection.prototype, "_testContext", 2);
|
|
852
|
-
if (!customElements.get("qti-assessment-section")) {
|
|
853
|
-
customElements.define("qti-assessment-section", QtiAssessmentSection);
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
// ../qti-test/src/components/qti-assessment-test/qti-assessment-test.ts
|
|
857
|
-
var QtiAssessmentTest = class extends i2 {
|
|
858
|
-
constructor() {
|
|
859
|
-
super(...arguments);
|
|
860
|
-
this._title = "";
|
|
861
|
-
}
|
|
862
|
-
get title() {
|
|
863
|
-
return this._title;
|
|
864
|
-
}
|
|
865
|
-
set title(value) {
|
|
866
|
-
this._title = value;
|
|
867
|
-
this.removeAttribute("title");
|
|
868
|
-
this.setAttribute("data-title", value);
|
|
869
|
-
}
|
|
870
|
-
async connectedCallback() {
|
|
871
|
-
super.connectedCallback();
|
|
872
|
-
await this.updateComplete;
|
|
873
|
-
this.dispatchEvent(
|
|
874
|
-
new CustomEvent("qti-assessment-test-connected", {
|
|
875
|
-
detail: this,
|
|
876
|
-
bubbles: true,
|
|
877
|
-
composed: true
|
|
878
|
-
})
|
|
879
|
-
);
|
|
880
|
-
}
|
|
881
|
-
render() {
|
|
882
|
-
return x` <slot></slot>`;
|
|
883
|
-
}
|
|
884
|
-
};
|
|
885
|
-
__decorateClass([
|
|
886
|
-
n({ type: String })
|
|
887
|
-
], QtiAssessmentTest.prototype, "identifier", 2);
|
|
888
|
-
__decorateClass([
|
|
889
|
-
n({ type: String })
|
|
890
|
-
], QtiAssessmentTest.prototype, "title", 1);
|
|
891
|
-
__decorateClass([
|
|
892
|
-
c({ context: testContext, subscribe: true })
|
|
893
|
-
], QtiAssessmentTest.prototype, "_testContext", 2);
|
|
894
|
-
QtiAssessmentTest = __decorateClass([
|
|
895
|
-
t("qti-assessment-test")
|
|
896
|
-
], QtiAssessmentTest);
|
|
897
|
-
|
|
898
|
-
// ../qti-test/src/components/qti-test-part/qti-test-part.ts
|
|
899
|
-
var QtiTestPart = class extends i2 {
|
|
900
|
-
constructor() {
|
|
901
|
-
super(...arguments);
|
|
902
|
-
this.identifier = "";
|
|
903
|
-
this.class = "";
|
|
904
|
-
this.navigationMode = "nonlinear";
|
|
905
|
-
this.submissionMode = "individual";
|
|
906
|
-
this._title = "";
|
|
907
|
-
}
|
|
908
|
-
get title() {
|
|
909
|
-
return this._title;
|
|
910
|
-
}
|
|
911
|
-
set title(value) {
|
|
912
|
-
this._title = value;
|
|
913
|
-
this.removeAttribute("title");
|
|
914
|
-
this.setAttribute("data-title", value);
|
|
915
|
-
}
|
|
916
|
-
async connectedCallback() {
|
|
917
|
-
super.connectedCallback();
|
|
918
|
-
await this.updateComplete;
|
|
919
|
-
this.dispatchEvent(
|
|
920
|
-
new Event("qti-test-part-connected", {
|
|
921
|
-
bubbles: true,
|
|
922
|
-
composed: true
|
|
923
|
-
})
|
|
924
|
-
);
|
|
925
|
-
}
|
|
926
|
-
render() {
|
|
927
|
-
return x` <slot></slot>`;
|
|
928
|
-
}
|
|
929
|
-
};
|
|
930
|
-
__decorateClass([
|
|
931
|
-
n({ type: String })
|
|
932
|
-
], QtiTestPart.prototype, "identifier", 2);
|
|
933
|
-
__decorateClass([
|
|
934
|
-
n({ type: String })
|
|
935
|
-
], QtiTestPart.prototype, "class", 2);
|
|
936
|
-
__decorateClass([
|
|
937
|
-
n({ type: String, attribute: "navigation-mode" })
|
|
938
|
-
], QtiTestPart.prototype, "navigationMode", 2);
|
|
939
|
-
__decorateClass([
|
|
940
|
-
n({ type: String, attribute: "submission-mode" })
|
|
941
|
-
], QtiTestPart.prototype, "submissionMode", 2);
|
|
942
|
-
QtiTestPart = __decorateClass([
|
|
943
|
-
t("qti-test-part")
|
|
944
|
-
], QtiTestPart);
|
|
945
|
-
if (!customElements.get("qti-test-part")) {
|
|
946
|
-
customElements.define("qti-test-part", QtiTestPart);
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
// ../qti-test/src/components/qti-test-feedback/qti-test-feedback.ts
|
|
950
|
-
var QtiTestFeedback = class extends QtiModalFeedback {
|
|
951
|
-
render() {
|
|
952
|
-
return x``;
|
|
953
|
-
}
|
|
954
|
-
};
|
|
955
|
-
QtiTestFeedback.styles = i`
|
|
956
|
-
:host {
|
|
957
|
-
color: gray;
|
|
958
|
-
}
|
|
959
|
-
`;
|
|
960
|
-
QtiTestFeedback = __decorateClass([
|
|
961
|
-
t("qti-test-feedback")
|
|
962
|
-
], QtiTestFeedback);
|
|
963
|
-
|
|
964
|
-
// ../qti-test/src/components/test-navigation/test-navigation.ts
|
|
965
|
-
var TestNavigation = class extends i2 {
|
|
966
|
-
constructor() {
|
|
967
|
-
super();
|
|
968
|
-
this.identifier = void 0;
|
|
969
|
-
this.initContext = [];
|
|
970
|
-
this.qtiContext = {
|
|
971
|
-
QTI_CONTEXT: {
|
|
972
|
-
testIdentifier: "",
|
|
973
|
-
candidateIdentifier: "",
|
|
974
|
-
environmentIdentifier: "default"
|
|
975
|
-
}
|
|
976
|
-
};
|
|
977
|
-
this.configContext = {};
|
|
978
|
-
this.autoScoreItems = false;
|
|
979
|
-
this.addEventListener("qti-assessment-test-connected", this._handleTestConnected.bind(this));
|
|
980
|
-
this.addEventListener("qti-assessment-item-connected", this._handleItemConnected.bind(this));
|
|
981
|
-
this.addEventListener("qti-interaction-changed", this._handleInteractionChanged.bind(this));
|
|
982
|
-
this.addEventListener("test-end-attempt", this._handleTestEndAttempt.bind(this));
|
|
983
|
-
this.addEventListener("test-show-correct-response", this._handleTestShowCorrectResponse.bind(this));
|
|
984
|
-
this.addEventListener("test-show-candidate-correction", this._handleTestShowCandidateCorrection.bind(this));
|
|
985
|
-
this.addEventListener("test-update-outcome-variable", this._handleTestUpdateOutcomeVariable.bind(this));
|
|
986
|
-
}
|
|
987
|
-
/**
|
|
988
|
-
* Handles the 'test-end-attempt' event.
|
|
989
|
-
* @private
|
|
990
|
-
* @listens TestNavigation#test-end-attempt
|
|
991
|
-
* @param {CustomEvent} event - The custom event object.
|
|
992
|
-
*/
|
|
993
|
-
_handleTestEndAttempt(_event) {
|
|
994
|
-
const qtiItemEl = this._testElement.querySelector(
|
|
995
|
-
`qti-assessment-item-ref[identifier="${this._sessionContext.navItemRefId}"]`
|
|
996
|
-
);
|
|
997
|
-
const qtiAssessmentItemEl = qtiItemEl.assessmentItem;
|
|
998
|
-
const reportValidityAfterScoring = this.configContext?.reportValidityAfterScoring === true ? true : false;
|
|
999
|
-
qtiAssessmentItemEl.processResponse(true, reportValidityAfterScoring);
|
|
1000
|
-
}
|
|
1001
|
-
// protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
1002
|
-
// return this;
|
|
1003
|
-
// }
|
|
1004
|
-
// myTemplate: TemplateFunction;
|
|
1005
|
-
// connectedCallback(): void {
|
|
1006
|
-
// super.connectedCallback();
|
|
1007
|
-
// const templateElement = this.querySelector<HTMLTemplateElement>('template');
|
|
1008
|
-
// if (!templateElement) {
|
|
1009
|
-
// this.myTemplate = null;
|
|
1010
|
-
// return;
|
|
1011
|
-
// }
|
|
1012
|
-
// this.myTemplate = prepareTemplate(templateElement);
|
|
1013
|
-
// }
|
|
1014
|
-
/**
|
|
1015
|
-
* Handles the 'test-show-correct-response' event.
|
|
1016
|
-
* @private
|
|
1017
|
-
* @listens TestNavigation#test-show-correct-response
|
|
1018
|
-
* @param {CustomEvent} event - The custom event object.
|
|
1019
|
-
*/
|
|
1020
|
-
_handleTestShowCorrectResponse(event) {
|
|
1021
|
-
const qtiItemEl = this._testElement.querySelector(
|
|
1022
|
-
`qti-assessment-item-ref[identifier="${this._sessionContext.navItemRefId}"]`
|
|
1023
|
-
);
|
|
1024
|
-
const qtiAssessmentItemEl = qtiItemEl.assessmentItem;
|
|
1025
|
-
if (!qtiAssessmentItemEl) return;
|
|
1026
|
-
qtiAssessmentItemEl.showCorrectResponse(event.detail);
|
|
1027
|
-
}
|
|
1028
|
-
/**
|
|
1029
|
-
* Handles the 'test-show-candidate-correction' event.
|
|
1030
|
-
* @private
|
|
1031
|
-
* @listens TestNavigation#test-show-candidate-correction
|
|
1032
|
-
* @param {CustomEvent} event - The custom event object.
|
|
1033
|
-
*/
|
|
1034
|
-
_handleTestShowCandidateCorrection(event) {
|
|
1035
|
-
const qtiItemEl = this._testElement.querySelector(
|
|
1036
|
-
`qti-assessment-item-ref[identifier="${this._sessionContext.navItemRefId}"]`
|
|
1037
|
-
);
|
|
1038
|
-
const qtiAssessmentItemEl = qtiItemEl.assessmentItem;
|
|
1039
|
-
qtiAssessmentItemEl.showCandidateCorrection(event.detail);
|
|
1040
|
-
}
|
|
1041
|
-
_handleTestUpdateOutcomeVariable(event) {
|
|
1042
|
-
const qtiItemEl = this._testElement.querySelector(
|
|
1043
|
-
`qti-assessment-item-ref[identifier="${event.detail.assessmentItemRefId}"]`
|
|
1044
|
-
);
|
|
1045
|
-
const qtiAssessmentItemEl = qtiItemEl.assessmentItem;
|
|
1046
|
-
qtiAssessmentItemEl.setOutcomeVariable(event.detail.outcomeVariableId, event.detail.value);
|
|
1047
|
-
}
|
|
1048
|
-
_handleInteractionChanged(_event) {
|
|
1049
|
-
if (this.autoScoreItems) {
|
|
1050
|
-
const assessmentItem = _event.composedPath()[0].closest(
|
|
1051
|
-
"qti-assessment-item"
|
|
1052
|
-
);
|
|
1053
|
-
const scoreOutcomeIdentifier = assessmentItem.variables.find((v) => v.identifier === "SCORE");
|
|
1054
|
-
if (scoreOutcomeIdentifier && scoreOutcomeIdentifier.externalScored === null && assessmentItem.adaptive === "false") {
|
|
1055
|
-
const reportValidityAfterScoring = this.configContext?.reportValidityAfterScoring === true ? true : false;
|
|
1056
|
-
assessmentItem.processResponse(true, reportValidityAfterScoring);
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
render() {
|
|
1061
|
-
return x`<slot></slot>`;
|
|
1062
|
-
}
|
|
1063
|
-
/* PK: on test connected we can build the computed context */
|
|
1064
|
-
_handleTestConnected(event) {
|
|
1065
|
-
this._testElement = event.detail;
|
|
1066
|
-
if (!this.qtiContext.QTI_CONTEXT?.testIdentifier) {
|
|
1067
|
-
const currentContext = this.qtiContext.QTI_CONTEXT || {
|
|
1068
|
-
testIdentifier: "",
|
|
1069
|
-
candidateIdentifier: "not set",
|
|
1070
|
-
environmentIdentifier: "default"
|
|
1071
|
-
};
|
|
1072
|
-
this.qtiContext = {
|
|
1073
|
-
QTI_CONTEXT: {
|
|
1074
|
-
...currentContext,
|
|
1075
|
-
testIdentifier: this._testElement.identifier,
|
|
1076
|
-
environmentIdentifier: currentContext.environmentIdentifier || "default"
|
|
1077
|
-
}
|
|
1078
|
-
};
|
|
1079
|
-
}
|
|
1080
|
-
const contextDeclarations = this._testElement.querySelectorAll('qti-context-declaration[identifier="QTI_CONTEXT"]');
|
|
1081
|
-
contextDeclarations.forEach((declaration) => {
|
|
1082
|
-
const defaultValues = this._extractDefaultValues(declaration);
|
|
1083
|
-
if (Object.keys(defaultValues).length > 0) {
|
|
1084
|
-
this.qtiContext = {
|
|
1085
|
-
QTI_CONTEXT: {
|
|
1086
|
-
...defaultValues,
|
|
1087
|
-
// Default values first
|
|
1088
|
-
...this.qtiContext.QTI_CONTEXT
|
|
1089
|
-
// Runtime values override defaults
|
|
1090
|
-
}
|
|
1091
|
-
};
|
|
1092
|
-
}
|
|
1093
|
-
});
|
|
1094
|
-
const testPartElements = Array.from(this._testElement?.querySelectorAll(`qti-test-part`) || []);
|
|
1095
|
-
this.computedContext = {
|
|
1096
|
-
identifier: this._testElement.identifier,
|
|
1097
|
-
title: this._testElement.title,
|
|
1098
|
-
view: this._sessionContext?.view,
|
|
1099
|
-
testParts: testPartElements.map((testPart) => {
|
|
1100
|
-
const sectionElements = [...testPart.querySelectorAll(`qti-assessment-section`)];
|
|
1101
|
-
return {
|
|
1102
|
-
active: false,
|
|
1103
|
-
identifier: testPart.identifier,
|
|
1104
|
-
navigationMode: testPart.navigationMode,
|
|
1105
|
-
submissionMode: testPart.submissionMode,
|
|
1106
|
-
sections: sectionElements.map((section) => {
|
|
1107
|
-
const itemElements = [...section.querySelectorAll(`qti-assessment-item-ref`)];
|
|
1108
|
-
return {
|
|
1109
|
-
active: false,
|
|
1110
|
-
identifier: section.identifier,
|
|
1111
|
-
title: section.title,
|
|
1112
|
-
items: itemElements.map((item) => ({
|
|
1113
|
-
...this.initContext?.find((i4) => i4.identifier === item.identifier),
|
|
1114
|
-
active: false,
|
|
1115
|
-
identifier: item.identifier,
|
|
1116
|
-
categories: item.category ? item.category?.split(" ") : [],
|
|
1117
|
-
href: item.href,
|
|
1118
|
-
variables: []
|
|
1119
|
-
}))
|
|
1120
|
-
};
|
|
1121
|
-
})
|
|
1122
|
-
};
|
|
1123
|
-
})
|
|
1124
|
-
};
|
|
1125
|
-
}
|
|
1126
|
-
/**
|
|
1127
|
-
* Extract default values from a qti-context-declaration element
|
|
1128
|
-
*/
|
|
1129
|
-
_extractDefaultValues(declaration) {
|
|
1130
|
-
const defaultValues = {};
|
|
1131
|
-
const defaultValueElement = declaration.querySelector("qti-default-value");
|
|
1132
|
-
if (!defaultValueElement) {
|
|
1133
|
-
return defaultValues;
|
|
1134
|
-
}
|
|
1135
|
-
const valueElements = defaultValueElement.querySelectorAll("qti-value[field-identifier]");
|
|
1136
|
-
valueElements.forEach((valueElement) => {
|
|
1137
|
-
const fieldIdentifier = valueElement.getAttribute("field-identifier");
|
|
1138
|
-
const baseType = valueElement.getAttribute("base-type") || "string";
|
|
1139
|
-
const textContent = valueElement.textContent?.trim() || "";
|
|
1140
|
-
if (fieldIdentifier) {
|
|
1141
|
-
let value = textContent;
|
|
1142
|
-
switch (baseType) {
|
|
1143
|
-
case "integer":
|
|
1144
|
-
value = parseInt(textContent, 10);
|
|
1145
|
-
break;
|
|
1146
|
-
case "float":
|
|
1147
|
-
case "duration":
|
|
1148
|
-
value = parseFloat(textContent);
|
|
1149
|
-
break;
|
|
1150
|
-
case "boolean":
|
|
1151
|
-
value = textContent.toLowerCase() === "true";
|
|
1152
|
-
break;
|
|
1153
|
-
case "string":
|
|
1154
|
-
default:
|
|
1155
|
-
value = textContent;
|
|
1156
|
-
break;
|
|
1157
|
-
}
|
|
1158
|
-
defaultValues[fieldIdentifier] = value;
|
|
1159
|
-
}
|
|
1160
|
-
});
|
|
1161
|
-
return defaultValues;
|
|
1162
|
-
}
|
|
1163
|
-
/* PK: on item connected we can add item only properties in the xml */
|
|
1164
|
-
_handleItemConnected(event) {
|
|
1165
|
-
const itemElement = event.detail;
|
|
1166
|
-
this.computedContext = {
|
|
1167
|
-
...this.computedContext,
|
|
1168
|
-
testParts: this.computedContext.testParts.map((testPart) => {
|
|
1169
|
-
return {
|
|
1170
|
-
...testPart,
|
|
1171
|
-
sections: testPart.sections.map((section) => {
|
|
1172
|
-
return {
|
|
1173
|
-
...section,
|
|
1174
|
-
items: section.items.map((item) => {
|
|
1175
|
-
if (item.identifier !== itemElement.parentElement.getAttribute("identifier")) {
|
|
1176
|
-
return item;
|
|
1177
|
-
}
|
|
1178
|
-
const scoreOutcome = itemElement.querySelector(
|
|
1179
|
-
"qti-outcome-declaration[identifier='SCORE']"
|
|
1180
|
-
);
|
|
1181
|
-
const externalScored = scoreOutcome?.getAttribute("externalScored");
|
|
1182
|
-
const responseDeclarations = itemElement.querySelectorAll("qti-response-declaration");
|
|
1183
|
-
const containsCorrectResponse = Array.from(responseDeclarations).some(
|
|
1184
|
-
(r3) => r3.querySelector("qti-correct-response")
|
|
1185
|
-
);
|
|
1186
|
-
const containsMapping = Array.from(responseDeclarations).some((r3) => {
|
|
1187
|
-
const mapping = r3.querySelector("qti-mapping");
|
|
1188
|
-
const areaMapping = r3.querySelector("qti-area-mapping");
|
|
1189
|
-
return mapping?.querySelector("qti-map-entry") || areaMapping?.querySelector("qti-area-map-entry");
|
|
1190
|
-
});
|
|
1191
|
-
const hasCorrectResponse = containsCorrectResponse || containsMapping;
|
|
1192
|
-
const hasResponseProcessing = itemElement.querySelector("qti-response-processing") ? true : false;
|
|
1193
|
-
return {
|
|
1194
|
-
...item,
|
|
1195
|
-
assessmentItemIdentifier: itemElement.getAttribute("identifier"),
|
|
1196
|
-
label: itemElement.getAttribute("label"),
|
|
1197
|
-
title: itemElement.title,
|
|
1198
|
-
externalScored,
|
|
1199
|
-
adaptive: itemElement.adaptive == "true" || false,
|
|
1200
|
-
timeDependent: itemElement.timeDependent == "true" || false,
|
|
1201
|
-
variables: itemElement.variables,
|
|
1202
|
-
hasCorrectResponse,
|
|
1203
|
-
hasResponseProcessing
|
|
1204
|
-
};
|
|
1205
|
-
})
|
|
1206
|
-
};
|
|
1207
|
-
})
|
|
1208
|
-
};
|
|
1209
|
-
})
|
|
1210
|
-
};
|
|
1211
|
-
}
|
|
1212
|
-
/* PK: on every change of the candidate we will recomputed the computedContext */
|
|
1213
|
-
willUpdate(_changedProperties) {
|
|
1214
|
-
if (!this.computedContext) return;
|
|
1215
|
-
let itemIndex = 1;
|
|
1216
|
-
this.computedContext = {
|
|
1217
|
-
...this.computedContext,
|
|
1218
|
-
view: this._sessionContext?.view,
|
|
1219
|
-
testParts: this.computedContext.testParts.map((testPart) => {
|
|
1220
|
-
return {
|
|
1221
|
-
...testPart,
|
|
1222
|
-
active: this._sessionContext?.navPartId === testPart.identifier || false,
|
|
1223
|
-
sections: testPart.sections.map((section) => {
|
|
1224
|
-
return {
|
|
1225
|
-
...section,
|
|
1226
|
-
active: this._sessionContext?.navSectionId === section.identifier || false,
|
|
1227
|
-
completed: section.items.every(
|
|
1228
|
-
(item) => this._testContext.items.find((i4) => i4.identifier === item.identifier)?.variables.find((v) => v.identifier === "completionStatus").value === "completed"
|
|
1229
|
-
),
|
|
1230
|
-
items: section.items.map((item) => {
|
|
1231
|
-
const itemContext = this._testContext?.items.find((i4) => i4.identifier === item.identifier);
|
|
1232
|
-
const computedItem = {
|
|
1233
|
-
...item,
|
|
1234
|
-
...itemContext,
|
|
1235
|
-
...this.initContext?.find((i4) => i4.identifier === item.identifier)
|
|
1236
|
-
};
|
|
1237
|
-
const rawscore = computedItem.variables?.find((vr) => vr.identifier == "SCORE")?.value;
|
|
1238
|
-
const score = rawscore === void 0 || rawscore === null ? null : parseFloat(rawscore?.toString());
|
|
1239
|
-
const completionStatus = computedItem.variables?.find((v) => v.identifier === "completionStatus")?.value;
|
|
1240
|
-
const response = computedItem.variables?.find((v) => v.identifier === "RESPONSE")?.value || "";
|
|
1241
|
-
const numAttempts = computedItem.variables?.find((v) => v.identifier === "numAttempts")?.value || 0;
|
|
1242
|
-
const active = this._sessionContext?.navItemRefId === computedItem.identifier || false;
|
|
1243
|
-
const index = item.categories.includes(this.configContext?.infoItemCategory) ? null : itemIndex++;
|
|
1244
|
-
const rawMaxScore = item.variables?.find((vr) => vr.identifier == "MAXSCORE")?.value;
|
|
1245
|
-
const maxScore = rawMaxScore === void 0 || rawMaxScore === null ? null : parseFloat(rawMaxScore?.toString());
|
|
1246
|
-
return {
|
|
1247
|
-
...computedItem,
|
|
1248
|
-
completionStatus,
|
|
1249
|
-
numAttempts,
|
|
1250
|
-
score,
|
|
1251
|
-
response,
|
|
1252
|
-
index,
|
|
1253
|
-
// type,
|
|
1254
|
-
active,
|
|
1255
|
-
// correct,
|
|
1256
|
-
maxScore
|
|
1257
|
-
// incorrect,
|
|
1258
|
-
// completed
|
|
1259
|
-
};
|
|
1260
|
-
})
|
|
1261
|
-
};
|
|
1262
|
-
})
|
|
1263
|
-
};
|
|
1264
|
-
})
|
|
1265
|
-
};
|
|
1266
|
-
this.dispatchEvent(
|
|
1267
|
-
new CustomEvent("qti-computed-context-updated", {
|
|
1268
|
-
detail: this.computedContext,
|
|
1269
|
-
bubbles: true
|
|
1270
|
-
})
|
|
1271
|
-
);
|
|
1272
|
-
}
|
|
1273
|
-
};
|
|
1274
|
-
__decorateClass([
|
|
1275
|
-
n({ type: String })
|
|
1276
|
-
], TestNavigation.prototype, "identifier", 2);
|
|
1277
|
-
__decorateClass([
|
|
1278
|
-
r()
|
|
1279
|
-
], TestNavigation.prototype, "initContext", 2);
|
|
1280
|
-
__decorateClass([
|
|
1281
|
-
r(),
|
|
1282
|
-
e({ context: qtiContext })
|
|
1283
|
-
], TestNavigation.prototype, "qtiContext", 2);
|
|
1284
|
-
__decorateClass([
|
|
1285
|
-
r(),
|
|
1286
|
-
e({ context: configContext })
|
|
1287
|
-
], TestNavigation.prototype, "configContext", 2);
|
|
1288
|
-
__decorateClass([
|
|
1289
|
-
r(),
|
|
1290
|
-
c({ context: testContext, subscribe: true })
|
|
1291
|
-
], TestNavigation.prototype, "_testContext", 2);
|
|
1292
|
-
__decorateClass([
|
|
1293
|
-
r(),
|
|
1294
|
-
c({ context: sessionContext, subscribe: true })
|
|
1295
|
-
], TestNavigation.prototype, "_sessionContext", 2);
|
|
1296
|
-
__decorateClass([
|
|
1297
|
-
r(),
|
|
1298
|
-
e({ context: computedContext })
|
|
1299
|
-
], TestNavigation.prototype, "computedContext", 2);
|
|
1300
|
-
__decorateClass([
|
|
1301
|
-
n({ type: Boolean, attribute: "auto-score-items" })
|
|
1302
|
-
], TestNavigation.prototype, "autoScoreItems", 2);
|
|
1303
|
-
TestNavigation = __decorateClass([
|
|
1304
|
-
t("test-navigation")
|
|
1305
|
-
], TestNavigation);
|
|
1306
|
-
|
|
1307
|
-
// ../qti-test/src/components/styles.ts
|
|
1308
|
-
var form = i`
|
|
1309
|
-
display: inline-flex;
|
|
1310
|
-
align-items: center;
|
|
1311
|
-
cursor: pointer;
|
|
1312
|
-
padding: 0.5rem 1rem;
|
|
1313
|
-
border-radius: 0.25rem;
|
|
1314
|
-
user-select: none;
|
|
1315
|
-
`;
|
|
1316
|
-
var btn = i`
|
|
1317
|
-
background-color: lightgray;
|
|
1318
|
-
${form};
|
|
1319
|
-
`;
|
|
1320
|
-
var dis = i`
|
|
1321
|
-
cursor: not-allowed;
|
|
1322
|
-
opacity: 0.8;
|
|
1323
|
-
`;
|
|
1324
|
-
var ind = i`
|
|
1325
|
-
${form};
|
|
1326
|
-
border: 1px solid gray;
|
|
1327
|
-
`;
|
|
1328
|
-
|
|
1329
|
-
// ../qti-test/src/components/test-next/test-next.ts
|
|
1330
|
-
var TestNext = class extends i2 {
|
|
1331
|
-
constructor() {
|
|
1332
|
-
super();
|
|
1333
|
-
this._internalDisabled = true;
|
|
1334
|
-
this._internals = this.attachInternals();
|
|
1335
|
-
this._internals.role = "button";
|
|
1336
|
-
this._internals.ariaLabel = "Next item";
|
|
1337
|
-
this.addEventListener("click", (e2) => {
|
|
1338
|
-
e2.preventDefault();
|
|
1339
|
-
if (!this._internalDisabled) this._requestItem(this.sectionItems[this.itemIndex + 1].identifier);
|
|
1340
|
-
});
|
|
1341
|
-
}
|
|
1342
|
-
_handleTestElementChange(_oldValue, newValue) {
|
|
1343
|
-
if (newValue) {
|
|
1344
|
-
this._internalDisabled = false;
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1347
|
-
connectedCallback() {
|
|
1348
|
-
super.connectedCallback();
|
|
1349
|
-
this.checkDisabled();
|
|
1350
|
-
}
|
|
1351
|
-
willUpdate(_changedProperties) {
|
|
1352
|
-
if (!this.computedContext) return;
|
|
1353
|
-
const testPart = this.computedContext?.testParts.find((testPart2) => testPart2.active);
|
|
1354
|
-
if (!testPart) return;
|
|
1355
|
-
this.sectionItems = testPart.sections.flatMap((section) => section.items);
|
|
1356
|
-
this.itemIndex = this.sectionItems.findIndex((item) => item.active);
|
|
1357
|
-
this.checkDisabled();
|
|
1358
|
-
}
|
|
1359
|
-
checkDisabled() {
|
|
1360
|
-
this._internalDisabled = !this.computedContext || this.itemIndex < 0 || this.itemIndex >= this.sectionItems?.length - 1;
|
|
1361
|
-
}
|
|
1362
|
-
_requestItem(identifier) {
|
|
1363
|
-
this.dispatchEvent(
|
|
1364
|
-
new CustomEvent("qti-request-navigation", {
|
|
1365
|
-
composed: true,
|
|
1366
|
-
bubbles: true,
|
|
1367
|
-
detail: {
|
|
1368
|
-
type: "item",
|
|
1369
|
-
id: identifier
|
|
1370
|
-
}
|
|
1371
|
-
})
|
|
1372
|
-
);
|
|
1373
|
-
}
|
|
1374
|
-
render() {
|
|
1375
|
-
return x`<slot></slot>`;
|
|
1376
|
-
}
|
|
1377
|
-
};
|
|
1378
|
-
TestNext.styles = i`
|
|
1379
|
-
:host {
|
|
1380
|
-
${btn};
|
|
1381
|
-
}
|
|
1382
|
-
:host([disabled]) {
|
|
1383
|
-
${dis};
|
|
1384
|
-
}
|
|
1385
|
-
`;
|
|
1386
|
-
__decorateClass([
|
|
1387
|
-
n({ type: Boolean, reflect: true, attribute: "disabled" })
|
|
1388
|
-
], TestNext.prototype, "_internalDisabled", 2);
|
|
1389
|
-
__decorateClass([
|
|
1390
|
-
c({ context: computedContext, subscribe: true })
|
|
1391
|
-
], TestNext.prototype, "computedContext", 2);
|
|
1392
|
-
__decorateClass([
|
|
1393
|
-
watch("computedContext")
|
|
1394
|
-
], TestNext.prototype, "_handleTestElementChange", 1);
|
|
1395
|
-
TestNext = __decorateClass([
|
|
1396
|
-
t("test-next")
|
|
1397
|
-
], TestNext);
|
|
1398
|
-
|
|
1399
|
-
// ../qti-test/src/components/test-prev/test-prev.ts
|
|
1400
|
-
var TestPrev = class extends i2 {
|
|
1401
|
-
constructor() {
|
|
1402
|
-
super();
|
|
1403
|
-
this._internalDisabled = true;
|
|
1404
|
-
this.addEventListener("click", (e2) => {
|
|
1405
|
-
e2.preventDefault();
|
|
1406
|
-
if (!this._internalDisabled) this._requestItem(this.sectionItems[this.itemIndex - 1].identifier);
|
|
1407
|
-
});
|
|
1408
|
-
}
|
|
1409
|
-
_handleTestElementChange(_oldValue, newValue) {
|
|
1410
|
-
if (newValue) {
|
|
1411
|
-
this._internalDisabled = false;
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
willUpdate(_changedProperties) {
|
|
1415
|
-
if (!this.computedContext) return;
|
|
1416
|
-
const testPart = this.computedContext?.testParts.find((testPart2) => testPart2.active);
|
|
1417
|
-
if (!testPart) return;
|
|
1418
|
-
this.sectionItems = testPart.sections.flatMap((section) => section.items);
|
|
1419
|
-
this.itemIndex = this.sectionItems.findIndex((item) => item.active);
|
|
1420
|
-
this.checkDisabled();
|
|
1421
|
-
}
|
|
1422
|
-
checkDisabled() {
|
|
1423
|
-
this._internalDisabled = !this.computedContext || this.itemIndex === 0 || this.itemIndex === -1;
|
|
1424
|
-
}
|
|
1425
|
-
_requestItem(identifier) {
|
|
1426
|
-
this.dispatchEvent(
|
|
1427
|
-
new CustomEvent("qti-request-navigation", {
|
|
1428
|
-
composed: true,
|
|
1429
|
-
bubbles: true,
|
|
1430
|
-
detail: {
|
|
1431
|
-
type: "item",
|
|
1432
|
-
id: identifier
|
|
1433
|
-
}
|
|
1434
|
-
})
|
|
1435
|
-
);
|
|
1436
|
-
}
|
|
1437
|
-
render() {
|
|
1438
|
-
return x`<slot></slot>`;
|
|
1439
|
-
}
|
|
1440
|
-
};
|
|
1441
|
-
TestPrev.styles = i`
|
|
1442
|
-
:host {
|
|
1443
|
-
${btn};
|
|
1444
|
-
}
|
|
1445
|
-
:host([disabled]) {
|
|
1446
|
-
${dis};
|
|
1447
|
-
}
|
|
1448
|
-
`;
|
|
1449
|
-
__decorateClass([
|
|
1450
|
-
n({ type: Boolean, reflect: true, attribute: "disabled" })
|
|
1451
|
-
], TestPrev.prototype, "_internalDisabled", 2);
|
|
1452
|
-
__decorateClass([
|
|
1453
|
-
c({ context: computedContext, subscribe: true })
|
|
1454
|
-
], TestPrev.prototype, "computedContext", 2);
|
|
1455
|
-
__decorateClass([
|
|
1456
|
-
watch("computedContext")
|
|
1457
|
-
], TestPrev.prototype, "_handleTestElementChange", 1);
|
|
1458
|
-
TestPrev = __decorateClass([
|
|
1459
|
-
t("test-prev")
|
|
1460
|
-
], TestPrev);
|
|
1461
|
-
|
|
1462
|
-
// ../qti-test/src/components/test-view-toggle/test-view.ts
|
|
1463
|
-
var TestView = class extends i2 {
|
|
1464
|
-
constructor() {
|
|
1465
|
-
super(...arguments);
|
|
1466
|
-
this.label = "view";
|
|
1467
|
-
this._handleViewOptionsChange = () => {
|
|
1468
|
-
this.updateViewOptions();
|
|
1469
|
-
};
|
|
1470
|
-
this._viewOptions = TestView.DEFAULT_VIEW_OPTIONS;
|
|
1471
|
-
}
|
|
1472
|
-
connectedCallback() {
|
|
1473
|
-
super.connectedCallback();
|
|
1474
|
-
this.updateViewOptions();
|
|
1475
|
-
}
|
|
1476
|
-
updateViewOptions() {
|
|
1477
|
-
if (this.viewOptions) {
|
|
1478
|
-
const options = this.viewOptions.split(",").map((opt) => opt.trim());
|
|
1479
|
-
this._viewOptions = options.filter((opt) => TestView.DEFAULT_VIEW_OPTIONS.includes(opt));
|
|
1480
|
-
} else {
|
|
1481
|
-
this._viewOptions = TestView.DEFAULT_VIEW_OPTIONS;
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
_switchView(view) {
|
|
1485
|
-
this.dispatchEvent(
|
|
1486
|
-
new CustomEvent("on-test-switch-view", {
|
|
1487
|
-
composed: true,
|
|
1488
|
-
bubbles: true,
|
|
1489
|
-
detail: view
|
|
1490
|
-
})
|
|
1491
|
-
);
|
|
1492
|
-
}
|
|
1493
|
-
render() {
|
|
1494
|
-
return x`
|
|
1495
|
-
<label part="label" for="viewSelect">${this.label}</label>
|
|
1496
|
-
<select
|
|
1497
|
-
part="select"
|
|
1498
|
-
id="viewSelect"
|
|
1499
|
-
@change=${(e2) => {
|
|
1500
|
-
const el = e2.target;
|
|
1501
|
-
this._switchView(el.value);
|
|
1502
|
-
}}
|
|
1503
|
-
>
|
|
1504
|
-
${this._viewOptions.map(
|
|
1505
|
-
(v) => x`<option value="${v}" ?selected=${v === this.sessionContext.view}>${v}</option>`
|
|
1506
|
-
)}
|
|
1507
|
-
</select>
|
|
1508
|
-
`;
|
|
1509
|
-
}
|
|
1510
|
-
};
|
|
1511
|
-
TestView.DEFAULT_VIEW_OPTIONS = ["author", "candidate", "proctor", "scorer", "testConstructor", "tutor"];
|
|
1512
|
-
__decorateClass([
|
|
1513
|
-
c({ context: sessionContext, subscribe: true })
|
|
1514
|
-
], TestView.prototype, "sessionContext", 2);
|
|
1515
|
-
__decorateClass([
|
|
1516
|
-
n({ type: String })
|
|
1517
|
-
], TestView.prototype, "label", 2);
|
|
1518
|
-
__decorateClass([
|
|
1519
|
-
n({ type: String, attribute: "view-options" })
|
|
1520
|
-
], TestView.prototype, "viewOptions", 2);
|
|
1521
|
-
__decorateClass([
|
|
1522
|
-
watch("viewOptions", { waitUntilFirstUpdate: true })
|
|
1523
|
-
], TestView.prototype, "_handleViewOptionsChange", 2);
|
|
1524
|
-
__decorateClass([
|
|
1525
|
-
r()
|
|
1526
|
-
], TestView.prototype, "_viewOptions", 2);
|
|
1527
|
-
TestView = __decorateClass([
|
|
1528
|
-
t("test-view")
|
|
1529
|
-
], TestView);
|
|
1530
|
-
|
|
1531
|
-
// ../qti-test/src/components/test-item-link/test-item-link.ts
|
|
1532
|
-
var TestItemLink = class extends i2 {
|
|
1533
|
-
constructor() {
|
|
1534
|
-
super();
|
|
1535
|
-
this.itemId = null;
|
|
1536
|
-
this.addEventListener("click", () => this._requestItem(this.itemId));
|
|
1537
|
-
}
|
|
1538
|
-
_requestItem(identifier) {
|
|
1539
|
-
this.dispatchEvent(
|
|
1540
|
-
new CustomEvent("qti-request-navigation", {
|
|
1541
|
-
composed: true,
|
|
1542
|
-
bubbles: true,
|
|
1543
|
-
detail: {
|
|
1544
|
-
type: "item",
|
|
1545
|
-
id: identifier
|
|
1546
|
-
}
|
|
1547
|
-
})
|
|
1548
|
-
);
|
|
1549
|
-
}
|
|
1550
|
-
render() {
|
|
1551
|
-
return x` <slot></slot> `;
|
|
1552
|
-
}
|
|
1553
|
-
};
|
|
1554
|
-
TestItemLink.styles = i`
|
|
1555
|
-
:host {
|
|
1556
|
-
${btn};
|
|
1557
|
-
}
|
|
1558
|
-
:host([disabled]) {
|
|
1559
|
-
${dis};
|
|
1560
|
-
}
|
|
1561
|
-
`;
|
|
1562
|
-
__decorateClass([
|
|
1563
|
-
n({ type: String, attribute: "item-id" })
|
|
1564
|
-
], TestItemLink.prototype, "itemId", 2);
|
|
1565
|
-
TestItemLink = __decorateClass([
|
|
1566
|
-
t("test-item-link")
|
|
1567
|
-
], TestItemLink);
|
|
1568
|
-
|
|
1569
|
-
// ../qti-test/src/components/test-end-attempt/test-end-attempt.ts
|
|
1570
|
-
var TestEndAttempt = class extends i2 {
|
|
1571
|
-
constructor() {
|
|
1572
|
-
super();
|
|
1573
|
-
this.addEventListener("click", () => this.dispatchEvent(new CustomEvent("test-end-attempt", { bubbles: true })));
|
|
1574
|
-
}
|
|
1575
|
-
render() {
|
|
1576
|
-
return x` <slot></slot> `;
|
|
1577
|
-
}
|
|
1578
|
-
};
|
|
1579
|
-
TestEndAttempt.styles = i`
|
|
1580
|
-
:host {
|
|
1581
|
-
${btn};
|
|
1582
|
-
}
|
|
1583
|
-
:host([disabled]) {
|
|
1584
|
-
${dis};
|
|
1585
|
-
}
|
|
1586
|
-
`;
|
|
1587
|
-
TestEndAttempt = __decorateClass([
|
|
1588
|
-
t("test-end-attempt")
|
|
1589
|
-
], TestEndAttempt);
|
|
1590
|
-
|
|
1591
|
-
// ../qti-test/src/components/test-show-correct-response/test-show-correct-response.ts
|
|
1592
|
-
var TestShowCorrectResponse = class extends i2 {
|
|
1593
|
-
constructor() {
|
|
1594
|
-
super(...arguments);
|
|
1595
|
-
this.shown = false;
|
|
1596
|
-
this.disabled = false;
|
|
1597
|
-
this.showCorrectText = "Show correct response";
|
|
1598
|
-
this.hideCorrectText = "Hide correct response";
|
|
1599
|
-
this.noCorrectResponseText = "No correct response specified";
|
|
1600
|
-
}
|
|
1601
|
-
// Store previous active item reference
|
|
1602
|
-
willUpdate(_changedProperties) {
|
|
1603
|
-
const activeItem = this.computedContext?.testParts.flatMap((testPart) => testPart.sections.flatMap((section) => section.items)).find((item) => item.active);
|
|
1604
|
-
if (this._previousActiveItem !== activeItem) {
|
|
1605
|
-
this.shown = false;
|
|
1606
|
-
this._previousActiveItem = activeItem;
|
|
1607
|
-
}
|
|
1608
|
-
if (activeItem) {
|
|
1609
|
-
const containsCorrectResponse = !!activeItem?.variables?.some((v) => v["correctResponse"]);
|
|
1610
|
-
const containsMapping = !!activeItem?.variables?.some((v) => {
|
|
1611
|
-
return v["mapping"]?.mapEntries?.length > 0 || v["areaMapping"]?.areaMapEntries?.length > 0;
|
|
1612
|
-
});
|
|
1613
|
-
this.disabled = !containsCorrectResponse && !containsMapping;
|
|
1614
|
-
} else {
|
|
1615
|
-
this.disabled = true;
|
|
1616
|
-
}
|
|
1617
|
-
}
|
|
1618
|
-
_toggleState() {
|
|
1619
|
-
if (this.disabled) return;
|
|
1620
|
-
this.shown = !this.shown;
|
|
1621
|
-
this.dispatchEvent(
|
|
1622
|
-
new CustomEvent("test-show-correct-response", {
|
|
1623
|
-
detail: this.shown,
|
|
1624
|
-
bubbles: true
|
|
1625
|
-
})
|
|
1626
|
-
);
|
|
1627
|
-
}
|
|
1628
|
-
_getDisplayedText() {
|
|
1629
|
-
return this.disabled ? this.noCorrectResponseText : this.shown ? this.hideCorrectText : this.showCorrectText;
|
|
1630
|
-
}
|
|
1631
|
-
render() {
|
|
1632
|
-
return x` <div @click="${this._toggleState}">${this._getDisplayedText()}</div> `;
|
|
1633
|
-
}
|
|
1634
|
-
};
|
|
1635
|
-
TestShowCorrectResponse.styles = i`
|
|
1636
|
-
:host {
|
|
1637
|
-
${btn};
|
|
1638
|
-
}
|
|
1639
|
-
:host([disabled]) {
|
|
1640
|
-
${dis};
|
|
1641
|
-
}
|
|
1642
|
-
`;
|
|
1643
|
-
__decorateClass([
|
|
1644
|
-
c({ context: computedContext, subscribe: true })
|
|
1645
|
-
], TestShowCorrectResponse.prototype, "computedContext", 2);
|
|
1646
|
-
__decorateClass([
|
|
1647
|
-
n({ type: Boolean, reflect: true })
|
|
1648
|
-
], TestShowCorrectResponse.prototype, "shown", 2);
|
|
1649
|
-
__decorateClass([
|
|
1650
|
-
n({ type: Boolean, reflect: true })
|
|
1651
|
-
], TestShowCorrectResponse.prototype, "disabled", 2);
|
|
1652
|
-
__decorateClass([
|
|
1653
|
-
n({ type: String })
|
|
1654
|
-
], TestShowCorrectResponse.prototype, "showCorrectText", 2);
|
|
1655
|
-
__decorateClass([
|
|
1656
|
-
n({ type: String })
|
|
1657
|
-
], TestShowCorrectResponse.prototype, "hideCorrectText", 2);
|
|
1658
|
-
__decorateClass([
|
|
1659
|
-
n({ type: String })
|
|
1660
|
-
], TestShowCorrectResponse.prototype, "noCorrectResponseText", 2);
|
|
1661
|
-
TestShowCorrectResponse = __decorateClass([
|
|
1662
|
-
t("test-show-correct-response")
|
|
1663
|
-
], TestShowCorrectResponse);
|
|
1664
|
-
|
|
1665
|
-
// ../../node_modules/.pnpm/@heximal+expressions@0.1.5/node_modules/@heximal/expressions/lib/constants.js
|
|
1666
|
-
var KEYWORDS = ["this"];
|
|
1667
|
-
var UNARY_OPERATORS = ["+", "-", "!"];
|
|
1668
|
-
var BINARY_OPERATORS = [
|
|
1669
|
-
"=",
|
|
1670
|
-
"+",
|
|
1671
|
-
"-",
|
|
1672
|
-
"*",
|
|
1673
|
-
"/",
|
|
1674
|
-
"%",
|
|
1675
|
-
"^",
|
|
1676
|
-
"==",
|
|
1677
|
-
"!=",
|
|
1678
|
-
">",
|
|
1679
|
-
"<",
|
|
1680
|
-
">=",
|
|
1681
|
-
"<=",
|
|
1682
|
-
"||",
|
|
1683
|
-
"&&",
|
|
1684
|
-
"??",
|
|
1685
|
-
"&",
|
|
1686
|
-
"===",
|
|
1687
|
-
"!==",
|
|
1688
|
-
"|",
|
|
1689
|
-
"|>"
|
|
1690
|
-
];
|
|
1691
|
-
var PRECEDENCE = {
|
|
1692
|
-
"!": 0,
|
|
1693
|
-
":": 0,
|
|
1694
|
-
",": 0,
|
|
1695
|
-
")": 0,
|
|
1696
|
-
"]": 0,
|
|
1697
|
-
"}": 0,
|
|
1698
|
-
"|>": 1,
|
|
1699
|
-
"?": 2,
|
|
1700
|
-
"??": 3,
|
|
1701
|
-
"||": 4,
|
|
1702
|
-
"&&": 5,
|
|
1703
|
-
"|": 6,
|
|
1704
|
-
"^": 7,
|
|
1705
|
-
"&": 8,
|
|
1706
|
-
// equality
|
|
1707
|
-
"!=": 9,
|
|
1708
|
-
"==": 9,
|
|
1709
|
-
"!==": 9,
|
|
1710
|
-
"===": 9,
|
|
1711
|
-
// relational
|
|
1712
|
-
">=": 10,
|
|
1713
|
-
">": 10,
|
|
1714
|
-
"<=": 10,
|
|
1715
|
-
"<": 10,
|
|
1716
|
-
// additive
|
|
1717
|
-
"+": 11,
|
|
1718
|
-
"-": 11,
|
|
1719
|
-
// multiplicative
|
|
1720
|
-
"%": 12,
|
|
1721
|
-
"/": 12,
|
|
1722
|
-
"*": 12,
|
|
1723
|
-
// postfix
|
|
1724
|
-
"(": 13,
|
|
1725
|
-
"[": 13,
|
|
1726
|
-
".": 13,
|
|
1727
|
-
"{": 13
|
|
1728
|
-
// not sure this is correct
|
|
1729
|
-
};
|
|
1730
|
-
var POSTFIX_PRECEDENCE = 13;
|
|
1731
|
-
|
|
1732
|
-
// ../../node_modules/.pnpm/@heximal+expressions@0.1.5/node_modules/@heximal/expressions/lib/tokenizer.js
|
|
1733
|
-
var TWO_CHAR_OPS = ["==", "!=", "<=", ">=", "||", "&&", "??", "|>"];
|
|
1734
|
-
var THREE_CHAR_OPS = ["===", "!=="];
|
|
1735
|
-
var Kind;
|
|
1736
|
-
(function(Kind2) {
|
|
1737
|
-
Kind2[Kind2["STRING"] = 1] = "STRING";
|
|
1738
|
-
Kind2[Kind2["IDENTIFIER"] = 2] = "IDENTIFIER";
|
|
1739
|
-
Kind2[Kind2["DOT"] = 3] = "DOT";
|
|
1740
|
-
Kind2[Kind2["COMMA"] = 4] = "COMMA";
|
|
1741
|
-
Kind2[Kind2["COLON"] = 5] = "COLON";
|
|
1742
|
-
Kind2[Kind2["INTEGER"] = 6] = "INTEGER";
|
|
1743
|
-
Kind2[Kind2["DECIMAL"] = 7] = "DECIMAL";
|
|
1744
|
-
Kind2[Kind2["OPERATOR"] = 8] = "OPERATOR";
|
|
1745
|
-
Kind2[Kind2["GROUPER"] = 9] = "GROUPER";
|
|
1746
|
-
Kind2[Kind2["KEYWORD"] = 10] = "KEYWORD";
|
|
1747
|
-
Kind2[Kind2["ARROW"] = 11] = "ARROW";
|
|
1748
|
-
})(Kind || (Kind = {}));
|
|
1749
|
-
var token = (kind, value, precedence = 0) => ({
|
|
1750
|
-
kind,
|
|
1751
|
-
value,
|
|
1752
|
-
precedence
|
|
1753
|
-
});
|
|
1754
|
-
var isWhitespace = (ch) => ch === 9 || ch === 10 || ch === 13 || ch === 32;
|
|
1755
|
-
var isIdentOrKeywordStart = (ch) => ch === 95 || ch === 36 || // ch &= ~32 puts ch into the range [65,90] [A-Z] only if ch was already in
|
|
1756
|
-
// the that range or in the range [97,122] [a-z]. We must mutate ch only after
|
|
1757
|
-
// checking other characters, thus the comma operator.
|
|
1758
|
-
(ch &= ~32, 65 <= ch && ch <= 90);
|
|
1759
|
-
var isIdentifier = (ch) => isIdentOrKeywordStart(ch) || isNumber(ch);
|
|
1760
|
-
var isKeyword = (str) => KEYWORDS.indexOf(str) !== -1;
|
|
1761
|
-
var isQuote = (ch) => ch === 34 || ch === 39;
|
|
1762
|
-
var isNumber = (ch) => 48 <= ch && ch <= 57;
|
|
1763
|
-
var isOperator = (ch) => ch === 43 || ch === 45 || ch === 42 || ch === 47 || ch === 33 || ch === 38 || ch === 37 || ch === 60 || ch === 61 || ch === 62 || ch === 63 || ch === 94 || ch === 124;
|
|
1764
|
-
var _isGrouper = (ch) => ch === 40 || ch === 41 || ch === 91 || ch === 93 || ch === 123 || ch === 125;
|
|
1765
|
-
var escapeString = (str) => str.replace(/\\(.)/g, (_match, group) => {
|
|
1766
|
-
switch (group) {
|
|
1767
|
-
case "n":
|
|
1768
|
-
return "\n";
|
|
1769
|
-
case "r":
|
|
1770
|
-
return "\r";
|
|
1771
|
-
case "t":
|
|
1772
|
-
return " ";
|
|
1773
|
-
case "b":
|
|
1774
|
-
return "\b";
|
|
1775
|
-
case "f":
|
|
1776
|
-
return "\f";
|
|
1777
|
-
default:
|
|
1778
|
-
return group;
|
|
1779
|
-
}
|
|
1780
|
-
});
|
|
1781
|
-
var Tokenizer = class {
|
|
1782
|
-
#input;
|
|
1783
|
-
#index = -1;
|
|
1784
|
-
#tokenStart = 0;
|
|
1785
|
-
#next;
|
|
1786
|
-
constructor(input) {
|
|
1787
|
-
this.#input = input;
|
|
1788
|
-
this.#advance();
|
|
1789
|
-
}
|
|
1790
|
-
nextToken() {
|
|
1791
|
-
while (isWhitespace(this.#next)) {
|
|
1792
|
-
this.#advance(true);
|
|
1793
|
-
}
|
|
1794
|
-
if (isQuote(this.#next))
|
|
1795
|
-
return this.#tokenizeString();
|
|
1796
|
-
if (isIdentOrKeywordStart(this.#next)) {
|
|
1797
|
-
return this.#tokenizeIdentOrKeyword();
|
|
1798
|
-
}
|
|
1799
|
-
if (isNumber(this.#next))
|
|
1800
|
-
return this.#tokenizeNumber();
|
|
1801
|
-
if (this.#next === 46)
|
|
1802
|
-
return this.#tokenizeDot();
|
|
1803
|
-
if (this.#next === 44)
|
|
1804
|
-
return this.#tokenizeComma();
|
|
1805
|
-
if (this.#next === 58)
|
|
1806
|
-
return this.#tokenizeColon();
|
|
1807
|
-
if (isOperator(this.#next))
|
|
1808
|
-
return this.#tokenizeOperator();
|
|
1809
|
-
if (_isGrouper(this.#next))
|
|
1810
|
-
return this.#tokenizeGrouper();
|
|
1811
|
-
this.#advance();
|
|
1812
|
-
if (this.#next !== void 0) {
|
|
1813
|
-
throw new Error(`Expected end of input, got ${this.#next}`);
|
|
1814
|
-
}
|
|
1815
|
-
return void 0;
|
|
1816
|
-
}
|
|
1817
|
-
#advance(resetTokenStart) {
|
|
1818
|
-
this.#index++;
|
|
1819
|
-
if (this.#index < this.#input.length) {
|
|
1820
|
-
this.#next = this.#input.charCodeAt(this.#index);
|
|
1821
|
-
if (resetTokenStart === true) {
|
|
1822
|
-
this.#tokenStart = this.#index;
|
|
1823
|
-
}
|
|
1824
|
-
} else {
|
|
1825
|
-
this.#next = void 0;
|
|
1826
|
-
}
|
|
1827
|
-
}
|
|
1828
|
-
#getValue(lookahead = 0) {
|
|
1829
|
-
const v = this.#input.substring(this.#tokenStart, this.#index + lookahead);
|
|
1830
|
-
if (lookahead === 0) {
|
|
1831
|
-
this.#clearValue();
|
|
1832
|
-
}
|
|
1833
|
-
return v;
|
|
1834
|
-
}
|
|
1835
|
-
#clearValue() {
|
|
1836
|
-
this.#tokenStart = this.#index;
|
|
1837
|
-
}
|
|
1838
|
-
#tokenizeString() {
|
|
1839
|
-
const _us = "unterminated string";
|
|
1840
|
-
const quoteChar = this.#next;
|
|
1841
|
-
this.#advance(true);
|
|
1842
|
-
while (this.#next !== quoteChar) {
|
|
1843
|
-
if (this.#next === void 0)
|
|
1844
|
-
throw new Error(_us);
|
|
1845
|
-
if (this.#next === 92) {
|
|
1846
|
-
this.#advance();
|
|
1847
|
-
if (this.#next === void 0)
|
|
1848
|
-
throw new Error(_us);
|
|
1849
|
-
}
|
|
1850
|
-
this.#advance();
|
|
1851
|
-
}
|
|
1852
|
-
const t2 = token(Kind.STRING, escapeString(this.#getValue()));
|
|
1853
|
-
this.#advance();
|
|
1854
|
-
return t2;
|
|
1855
|
-
}
|
|
1856
|
-
#tokenizeIdentOrKeyword() {
|
|
1857
|
-
do {
|
|
1858
|
-
this.#advance();
|
|
1859
|
-
} while (isIdentifier(this.#next));
|
|
1860
|
-
const value = this.#getValue();
|
|
1861
|
-
const kind = isKeyword(value) ? Kind.KEYWORD : Kind.IDENTIFIER;
|
|
1862
|
-
return token(kind, value);
|
|
1863
|
-
}
|
|
1864
|
-
#tokenizeNumber() {
|
|
1865
|
-
do {
|
|
1866
|
-
this.#advance();
|
|
1867
|
-
} while (isNumber(this.#next));
|
|
1868
|
-
if (this.#next === 46)
|
|
1869
|
-
return this.#tokenizeDot();
|
|
1870
|
-
return token(Kind.INTEGER, this.#getValue());
|
|
1871
|
-
}
|
|
1872
|
-
#tokenizeDot() {
|
|
1873
|
-
this.#advance();
|
|
1874
|
-
if (isNumber(this.#next))
|
|
1875
|
-
return this.#tokenizeFraction();
|
|
1876
|
-
this.#clearValue();
|
|
1877
|
-
return token(Kind.DOT, ".", POSTFIX_PRECEDENCE);
|
|
1878
|
-
}
|
|
1879
|
-
#tokenizeComma() {
|
|
1880
|
-
this.#advance(true);
|
|
1881
|
-
return token(Kind.COMMA, ",");
|
|
1882
|
-
}
|
|
1883
|
-
#tokenizeColon() {
|
|
1884
|
-
this.#advance(true);
|
|
1885
|
-
return token(Kind.COLON, ":");
|
|
1886
|
-
}
|
|
1887
|
-
#tokenizeFraction() {
|
|
1888
|
-
do {
|
|
1889
|
-
this.#advance();
|
|
1890
|
-
} while (isNumber(this.#next));
|
|
1891
|
-
return token(Kind.DECIMAL, this.#getValue());
|
|
1892
|
-
}
|
|
1893
|
-
#tokenizeOperator() {
|
|
1894
|
-
this.#advance();
|
|
1895
|
-
let op = this.#getValue(2);
|
|
1896
|
-
if (THREE_CHAR_OPS.indexOf(op) !== -1) {
|
|
1897
|
-
this.#advance();
|
|
1898
|
-
this.#advance();
|
|
1899
|
-
} else {
|
|
1900
|
-
op = this.#getValue(1);
|
|
1901
|
-
if (op === "=>") {
|
|
1902
|
-
this.#advance();
|
|
1903
|
-
return token(Kind.ARROW, op);
|
|
1904
|
-
}
|
|
1905
|
-
if (TWO_CHAR_OPS.indexOf(op) !== -1) {
|
|
1906
|
-
this.#advance();
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
1909
|
-
op = this.#getValue();
|
|
1910
|
-
return token(Kind.OPERATOR, op, PRECEDENCE[op]);
|
|
1911
|
-
}
|
|
1912
|
-
#tokenizeGrouper() {
|
|
1913
|
-
const value = String.fromCharCode(this.#next);
|
|
1914
|
-
const t2 = token(Kind.GROUPER, value, PRECEDENCE[value]);
|
|
1915
|
-
this.#advance(true);
|
|
1916
|
-
return t2;
|
|
1917
|
-
}
|
|
1918
|
-
};
|
|
1919
|
-
|
|
1920
|
-
// ../../node_modules/.pnpm/@heximal+expressions@0.1.5/node_modules/@heximal/expressions/lib/parser.js
|
|
1921
|
-
var parse = (expr, astFactory2) => new Parser(expr, astFactory2).parse();
|
|
1922
|
-
var Parser = class {
|
|
1923
|
-
#kind;
|
|
1924
|
-
#tokenizer;
|
|
1925
|
-
#ast;
|
|
1926
|
-
#token;
|
|
1927
|
-
#value;
|
|
1928
|
-
constructor(input, astFactory2) {
|
|
1929
|
-
this.#tokenizer = new Tokenizer(input);
|
|
1930
|
-
this.#ast = astFactory2;
|
|
1931
|
-
}
|
|
1932
|
-
parse() {
|
|
1933
|
-
this.#advance();
|
|
1934
|
-
return this.#parseExpression();
|
|
1935
|
-
}
|
|
1936
|
-
#advance(kind, value) {
|
|
1937
|
-
if (!this._matches(kind, value)) {
|
|
1938
|
-
throw new Error(`Expected kind ${kind} (${value}), was ${this.#token?.kind} (${this.#token?.value})`);
|
|
1939
|
-
}
|
|
1940
|
-
const t2 = this.#tokenizer.nextToken();
|
|
1941
|
-
this.#token = t2;
|
|
1942
|
-
this.#kind = t2?.kind;
|
|
1943
|
-
this.#value = t2?.value;
|
|
1944
|
-
}
|
|
1945
|
-
_matches(kind, value) {
|
|
1946
|
-
return !(kind && this.#kind !== kind || value && this.#value !== value);
|
|
1947
|
-
}
|
|
1948
|
-
#parseExpression() {
|
|
1949
|
-
if (!this.#token)
|
|
1950
|
-
return this.#ast.empty();
|
|
1951
|
-
const expr = this.#parseUnary();
|
|
1952
|
-
return expr === void 0 ? void 0 : this.#parsePrecedence(expr, 0);
|
|
1953
|
-
}
|
|
1954
|
-
// #parsePrecedence and #parseBinary implement the precedence climbing
|
|
1955
|
-
// algorithm as described in:
|
|
1956
|
-
// http://en.wikipedia.org/wiki/Operator-precedence_parser#Precedence_climbing_method
|
|
1957
|
-
#parsePrecedence(left, precedence) {
|
|
1958
|
-
if (left === void 0) {
|
|
1959
|
-
throw new Error("Expected left to be defined.");
|
|
1960
|
-
}
|
|
1961
|
-
while (this.#token) {
|
|
1962
|
-
if (this._matches(Kind.GROUPER, "(")) {
|
|
1963
|
-
const args = this.#parseArguments();
|
|
1964
|
-
left = this.#ast.invoke(left, void 0, args);
|
|
1965
|
-
} else if (this._matches(Kind.GROUPER, "[")) {
|
|
1966
|
-
const indexExpr = this.#parseIndex();
|
|
1967
|
-
left = this.#ast.index(left, indexExpr);
|
|
1968
|
-
} else if (this._matches(Kind.DOT)) {
|
|
1969
|
-
this.#advance();
|
|
1970
|
-
const right = this.#parseUnary();
|
|
1971
|
-
left = this.#makeInvokeOrGetter(left, right);
|
|
1972
|
-
} else if (this._matches(Kind.KEYWORD)) {
|
|
1973
|
-
break;
|
|
1974
|
-
} else if (this._matches(Kind.OPERATOR) && this.#token.precedence >= precedence) {
|
|
1975
|
-
left = this.#value === "?" ? this.#parseTernary(left) : this.#parseBinary(left, this.#token);
|
|
1976
|
-
} else {
|
|
1977
|
-
break;
|
|
1978
|
-
}
|
|
1979
|
-
}
|
|
1980
|
-
return left;
|
|
1981
|
-
}
|
|
1982
|
-
#makeInvokeOrGetter(left, right) {
|
|
1983
|
-
if (right === void 0) {
|
|
1984
|
-
throw new Error("expected identifier");
|
|
1985
|
-
}
|
|
1986
|
-
if (right.type === "ID") {
|
|
1987
|
-
return this.#ast.getter(left, right.value);
|
|
1988
|
-
} else if (right.type === "Invoke" && right.receiver.type === "ID") {
|
|
1989
|
-
const method = right.receiver;
|
|
1990
|
-
return this.#ast.invoke(left, method.value, right.arguments);
|
|
1991
|
-
} else {
|
|
1992
|
-
throw new Error(`expected identifier: ${right}`);
|
|
1993
|
-
}
|
|
1994
|
-
}
|
|
1995
|
-
#parseBinary(left, op) {
|
|
1996
|
-
if (BINARY_OPERATORS.indexOf(op.value) === -1) {
|
|
1997
|
-
throw new Error(`unknown operator: ${op.value}`);
|
|
1998
|
-
}
|
|
1999
|
-
this.#advance();
|
|
2000
|
-
let right = this.#parseUnary();
|
|
2001
|
-
while ((this.#kind === Kind.OPERATOR || this.#kind === Kind.DOT || this.#kind === Kind.GROUPER) && this.#token.precedence > op.precedence) {
|
|
2002
|
-
right = this.#parsePrecedence(right, this.#token.precedence);
|
|
2003
|
-
}
|
|
2004
|
-
return this.#ast.binary(left, op.value, right);
|
|
2005
|
-
}
|
|
2006
|
-
#parseUnary() {
|
|
2007
|
-
if (this._matches(Kind.OPERATOR)) {
|
|
2008
|
-
const value = this.#value;
|
|
2009
|
-
this.#advance();
|
|
2010
|
-
if (value === "+" || value === "-") {
|
|
2011
|
-
if (this._matches(Kind.INTEGER)) {
|
|
2012
|
-
return this.#parseInteger(value);
|
|
2013
|
-
} else if (this._matches(Kind.DECIMAL)) {
|
|
2014
|
-
return this.#parseDecimal(value);
|
|
2015
|
-
}
|
|
2016
|
-
}
|
|
2017
|
-
if (UNARY_OPERATORS.indexOf(value) === -1)
|
|
2018
|
-
throw new Error(`unexpected token: ${value}`);
|
|
2019
|
-
const expr = this.#parsePrecedence(this.#parsePrimary(), POSTFIX_PRECEDENCE);
|
|
2020
|
-
return this.#ast.unary(value, expr);
|
|
2021
|
-
}
|
|
2022
|
-
return this.#parsePrimary();
|
|
2023
|
-
}
|
|
2024
|
-
#parseTernary(condition) {
|
|
2025
|
-
this.#advance(Kind.OPERATOR, "?");
|
|
2026
|
-
const trueExpr = this.#parseExpression();
|
|
2027
|
-
this.#advance(Kind.COLON);
|
|
2028
|
-
const falseExpr = this.#parseExpression();
|
|
2029
|
-
return this.#ast.ternary(condition, trueExpr, falseExpr);
|
|
2030
|
-
}
|
|
2031
|
-
#parsePrimary() {
|
|
2032
|
-
switch (this.#kind) {
|
|
2033
|
-
case Kind.KEYWORD:
|
|
2034
|
-
const keyword = this.#value;
|
|
2035
|
-
if (keyword === "this") {
|
|
2036
|
-
this.#advance();
|
|
2037
|
-
return this.#ast.id(keyword);
|
|
2038
|
-
} else if (KEYWORDS.indexOf(keyword) !== -1) {
|
|
2039
|
-
throw new Error(`unexpected keyword: ${keyword}`);
|
|
2040
|
-
}
|
|
2041
|
-
throw new Error(`unrecognized keyword: ${keyword}`);
|
|
2042
|
-
case Kind.IDENTIFIER:
|
|
2043
|
-
return this.#parseInvokeOrIdentifier();
|
|
2044
|
-
case Kind.STRING:
|
|
2045
|
-
return this.#parseString();
|
|
2046
|
-
case Kind.INTEGER:
|
|
2047
|
-
return this.#parseInteger();
|
|
2048
|
-
case Kind.DECIMAL:
|
|
2049
|
-
return this.#parseDecimal();
|
|
2050
|
-
case Kind.GROUPER:
|
|
2051
|
-
if (this.#value === "(") {
|
|
2052
|
-
return this.#parseParenOrFunction();
|
|
2053
|
-
} else if (this.#value === "{") {
|
|
2054
|
-
return this.#parseMap();
|
|
2055
|
-
} else if (this.#value === "[") {
|
|
2056
|
-
return this.#parseList();
|
|
2057
|
-
}
|
|
2058
|
-
return void 0;
|
|
2059
|
-
case Kind.COLON:
|
|
2060
|
-
throw new Error('unexpected token ":"');
|
|
2061
|
-
default:
|
|
2062
|
-
return void 0;
|
|
2063
|
-
}
|
|
2064
|
-
}
|
|
2065
|
-
#parseList() {
|
|
2066
|
-
const items = [];
|
|
2067
|
-
do {
|
|
2068
|
-
this.#advance();
|
|
2069
|
-
if (this._matches(Kind.GROUPER, "]"))
|
|
2070
|
-
break;
|
|
2071
|
-
items.push(this.#parseExpression());
|
|
2072
|
-
} while (this._matches(Kind.COMMA));
|
|
2073
|
-
this.#advance(Kind.GROUPER, "]");
|
|
2074
|
-
return this.#ast.list(items);
|
|
2075
|
-
}
|
|
2076
|
-
#parseMap() {
|
|
2077
|
-
const entries = {};
|
|
2078
|
-
do {
|
|
2079
|
-
this.#advance();
|
|
2080
|
-
if (this._matches(Kind.GROUPER, "}"))
|
|
2081
|
-
break;
|
|
2082
|
-
const key = this.#value;
|
|
2083
|
-
if (this._matches(Kind.STRING) || this._matches(Kind.IDENTIFIER)) {
|
|
2084
|
-
this.#advance();
|
|
2085
|
-
}
|
|
2086
|
-
this.#advance(Kind.COLON);
|
|
2087
|
-
entries[key] = this.#parseExpression();
|
|
2088
|
-
} while (this._matches(Kind.COMMA));
|
|
2089
|
-
this.#advance(Kind.GROUPER, "}");
|
|
2090
|
-
return this.#ast.map(entries);
|
|
2091
|
-
}
|
|
2092
|
-
#parseInvokeOrIdentifier() {
|
|
2093
|
-
const value = this.#value;
|
|
2094
|
-
if (value === "true") {
|
|
2095
|
-
this.#advance();
|
|
2096
|
-
return this.#ast.literal(true);
|
|
2097
|
-
}
|
|
2098
|
-
if (value === "false") {
|
|
2099
|
-
this.#advance();
|
|
2100
|
-
return this.#ast.literal(false);
|
|
2101
|
-
}
|
|
2102
|
-
if (value === "null") {
|
|
2103
|
-
this.#advance();
|
|
2104
|
-
return this.#ast.literal(null);
|
|
2105
|
-
}
|
|
2106
|
-
if (value === "undefined") {
|
|
2107
|
-
this.#advance();
|
|
2108
|
-
return this.#ast.literal(void 0);
|
|
2109
|
-
}
|
|
2110
|
-
const identifier = this.#parseIdentifier();
|
|
2111
|
-
const args = this.#parseArguments();
|
|
2112
|
-
return !args ? identifier : this.#ast.invoke(identifier, void 0, args);
|
|
2113
|
-
}
|
|
2114
|
-
#parseIdentifier() {
|
|
2115
|
-
if (!this._matches(Kind.IDENTIFIER)) {
|
|
2116
|
-
throw new Error(`expected identifier: ${this.#value}`);
|
|
2117
|
-
}
|
|
2118
|
-
const value = this.#value;
|
|
2119
|
-
this.#advance();
|
|
2120
|
-
return this.#ast.id(value);
|
|
2121
|
-
}
|
|
2122
|
-
#parseArguments() {
|
|
2123
|
-
if (!this._matches(Kind.GROUPER, "(")) {
|
|
2124
|
-
return void 0;
|
|
2125
|
-
}
|
|
2126
|
-
const args = [];
|
|
2127
|
-
do {
|
|
2128
|
-
this.#advance();
|
|
2129
|
-
if (this._matches(Kind.GROUPER, ")")) {
|
|
2130
|
-
break;
|
|
2131
|
-
}
|
|
2132
|
-
const expr = this.#parseExpression();
|
|
2133
|
-
args.push(expr);
|
|
2134
|
-
} while (this._matches(Kind.COMMA));
|
|
2135
|
-
this.#advance(Kind.GROUPER, ")");
|
|
2136
|
-
return args;
|
|
2137
|
-
}
|
|
2138
|
-
#parseIndex() {
|
|
2139
|
-
this.#advance();
|
|
2140
|
-
const expr = this.#parseExpression();
|
|
2141
|
-
this.#advance(Kind.GROUPER, "]");
|
|
2142
|
-
return expr;
|
|
2143
|
-
}
|
|
2144
|
-
#parseParenOrFunction() {
|
|
2145
|
-
const expressions = this.#parseArguments();
|
|
2146
|
-
if (this._matches(Kind.ARROW)) {
|
|
2147
|
-
this.#advance();
|
|
2148
|
-
const body = this.#parseExpression();
|
|
2149
|
-
const params = expressions?.map((e2) => e2.value) ?? [];
|
|
2150
|
-
return this.#ast.arrowFunction(params, body);
|
|
2151
|
-
} else {
|
|
2152
|
-
return this.#ast.paren(expressions[0]);
|
|
2153
|
-
}
|
|
2154
|
-
}
|
|
2155
|
-
#parseString() {
|
|
2156
|
-
const value = this.#ast.literal(this.#value);
|
|
2157
|
-
this.#advance();
|
|
2158
|
-
return value;
|
|
2159
|
-
}
|
|
2160
|
-
#parseInteger(prefix = "") {
|
|
2161
|
-
const value = this.#ast.literal(parseInt(`${prefix}${this.#value}`, 10));
|
|
2162
|
-
this.#advance();
|
|
2163
|
-
return value;
|
|
2164
|
-
}
|
|
2165
|
-
#parseDecimal(prefix = "") {
|
|
2166
|
-
const value = this.#ast.literal(parseFloat(`${prefix}${this.#value}`));
|
|
2167
|
-
this.#advance();
|
|
2168
|
-
return value;
|
|
2169
|
-
}
|
|
2170
|
-
};
|
|
2171
|
-
|
|
2172
|
-
// ../../node_modules/.pnpm/@heximal+expressions@0.1.5/node_modules/@heximal/expressions/lib/eval.js
|
|
2173
|
-
var { hasOwn, fromEntries } = Object;
|
|
2174
|
-
var _BINARY_OPERATORS = {
|
|
2175
|
-
"+": (a, b) => a + b,
|
|
2176
|
-
"-": (a, b) => a - b,
|
|
2177
|
-
"*": (a, b) => a * b,
|
|
2178
|
-
"/": (a, b) => a / b,
|
|
2179
|
-
"%": (a, b) => a % b,
|
|
2180
|
-
"==": (a, b) => a == b,
|
|
2181
|
-
"!=": (a, b) => a != b,
|
|
2182
|
-
"===": (a, b) => a === b,
|
|
2183
|
-
"!==": (a, b) => a !== b,
|
|
2184
|
-
">": (a, b) => a > b,
|
|
2185
|
-
">=": (a, b) => a >= b,
|
|
2186
|
-
"<": (a, b) => a < b,
|
|
2187
|
-
"<=": (a, b) => a <= b,
|
|
2188
|
-
"||": (a, b) => a || b,
|
|
2189
|
-
"&&": (a, b) => a && b,
|
|
2190
|
-
"??": (a, b) => a ?? b,
|
|
2191
|
-
"|": (a, f) => f(a),
|
|
2192
|
-
"|>": (a, f) => f(a)
|
|
2193
|
-
};
|
|
2194
|
-
var _UNARY_OPERATORS = {
|
|
2195
|
-
"+": (a) => a,
|
|
2196
|
-
"-": (a) => -a,
|
|
2197
|
-
"!": (a) => !a
|
|
2198
|
-
};
|
|
2199
|
-
var EvalAstFactory = class {
|
|
2200
|
-
empty() {
|
|
2201
|
-
return {
|
|
2202
|
-
type: "Empty",
|
|
2203
|
-
evaluate(scope) {
|
|
2204
|
-
return scope;
|
|
2205
|
-
},
|
|
2206
|
-
getIds(idents) {
|
|
2207
|
-
return idents;
|
|
2208
|
-
}
|
|
2209
|
-
};
|
|
2210
|
-
}
|
|
2211
|
-
// TODO(justinfagnani): just use a JS literal?
|
|
2212
|
-
literal(v) {
|
|
2213
|
-
return {
|
|
2214
|
-
type: "Literal",
|
|
2215
|
-
value: v,
|
|
2216
|
-
evaluate(_scope) {
|
|
2217
|
-
return this.value;
|
|
2218
|
-
},
|
|
2219
|
-
getIds(idents) {
|
|
2220
|
-
return idents;
|
|
2221
|
-
}
|
|
2222
|
-
};
|
|
2223
|
-
}
|
|
2224
|
-
id(v) {
|
|
2225
|
-
return {
|
|
2226
|
-
type: "ID",
|
|
2227
|
-
value: v,
|
|
2228
|
-
evaluate(scope) {
|
|
2229
|
-
if (this.value === "this")
|
|
2230
|
-
return scope;
|
|
2231
|
-
return scope?.[this.value];
|
|
2232
|
-
},
|
|
2233
|
-
getIds(idents) {
|
|
2234
|
-
idents.push(this.value);
|
|
2235
|
-
return idents;
|
|
2236
|
-
}
|
|
2237
|
-
};
|
|
2238
|
-
}
|
|
2239
|
-
unary(op, expr) {
|
|
2240
|
-
const f = _UNARY_OPERATORS[op];
|
|
2241
|
-
return {
|
|
2242
|
-
type: "Unary",
|
|
2243
|
-
operator: op,
|
|
2244
|
-
child: expr,
|
|
2245
|
-
evaluate(scope) {
|
|
2246
|
-
return f(this.child.evaluate(scope));
|
|
2247
|
-
},
|
|
2248
|
-
getIds(idents) {
|
|
2249
|
-
return this.child.getIds(idents);
|
|
2250
|
-
}
|
|
2251
|
-
};
|
|
2252
|
-
}
|
|
2253
|
-
binary(l, op, r3) {
|
|
2254
|
-
const f = _BINARY_OPERATORS[op];
|
|
2255
|
-
return {
|
|
2256
|
-
type: "Binary",
|
|
2257
|
-
operator: op,
|
|
2258
|
-
left: l,
|
|
2259
|
-
right: r3,
|
|
2260
|
-
evaluate(scope) {
|
|
2261
|
-
if (this.operator === "=") {
|
|
2262
|
-
if (this.left.type !== "ID" && this.left.type !== "Getter" && this.left.type !== "Index") {
|
|
2263
|
-
throw new Error(`Invalid assignment target: ${this.left}`);
|
|
2264
|
-
}
|
|
2265
|
-
const value = this.right.evaluate(scope);
|
|
2266
|
-
let receiver = void 0;
|
|
2267
|
-
let property;
|
|
2268
|
-
if (this.left.type === "Getter") {
|
|
2269
|
-
receiver = this.left.receiver.evaluate(scope);
|
|
2270
|
-
property = this.left.name;
|
|
2271
|
-
} else if (this.left.type === "Index") {
|
|
2272
|
-
receiver = this.left.receiver.evaluate(scope);
|
|
2273
|
-
property = this.left.argument.evaluate(scope);
|
|
2274
|
-
} else if (this.left.type === "ID") {
|
|
2275
|
-
receiver = scope;
|
|
2276
|
-
property = this.left.value;
|
|
2277
|
-
}
|
|
2278
|
-
return receiver === void 0 ? void 0 : receiver[property] = value;
|
|
2279
|
-
}
|
|
2280
|
-
return f(this.left.evaluate(scope), this.right.evaluate(scope));
|
|
2281
|
-
},
|
|
2282
|
-
getIds(idents) {
|
|
2283
|
-
this.left.getIds(idents);
|
|
2284
|
-
this.right.getIds(idents);
|
|
2285
|
-
return idents;
|
|
2286
|
-
}
|
|
2287
|
-
};
|
|
2288
|
-
}
|
|
2289
|
-
getter(g, n2) {
|
|
2290
|
-
return {
|
|
2291
|
-
type: "Getter",
|
|
2292
|
-
receiver: g,
|
|
2293
|
-
name: n2,
|
|
2294
|
-
evaluate(scope) {
|
|
2295
|
-
return this.receiver.evaluate(scope)?.[this.name];
|
|
2296
|
-
},
|
|
2297
|
-
getIds(idents) {
|
|
2298
|
-
this.receiver.getIds(idents);
|
|
2299
|
-
return idents;
|
|
2300
|
-
}
|
|
2301
|
-
};
|
|
2302
|
-
}
|
|
2303
|
-
invoke(receiver, method, args) {
|
|
2304
|
-
if (method != null && typeof method !== "string") {
|
|
2305
|
-
throw new Error("method not a string");
|
|
2306
|
-
}
|
|
2307
|
-
return {
|
|
2308
|
-
type: "Invoke",
|
|
2309
|
-
receiver,
|
|
2310
|
-
method,
|
|
2311
|
-
arguments: args,
|
|
2312
|
-
evaluate(scope) {
|
|
2313
|
-
const receiver2 = this.receiver.evaluate(scope);
|
|
2314
|
-
const _this = this.method ? receiver2 : scope?.["this"] ?? scope;
|
|
2315
|
-
const f = this.method ? receiver2?.[method] : receiver2;
|
|
2316
|
-
const args2 = this.arguments ?? [];
|
|
2317
|
-
const argValues = args2.map((a) => a?.evaluate(scope));
|
|
2318
|
-
return f?.apply?.(_this, argValues);
|
|
2319
|
-
},
|
|
2320
|
-
getIds(idents) {
|
|
2321
|
-
this.receiver.getIds(idents);
|
|
2322
|
-
this.arguments?.forEach((a) => a?.getIds(idents));
|
|
2323
|
-
return idents;
|
|
2324
|
-
}
|
|
2325
|
-
};
|
|
2326
|
-
}
|
|
2327
|
-
paren(e2) {
|
|
2328
|
-
return e2;
|
|
2329
|
-
}
|
|
2330
|
-
index(e2, a) {
|
|
2331
|
-
return {
|
|
2332
|
-
type: "Index",
|
|
2333
|
-
receiver: e2,
|
|
2334
|
-
argument: a,
|
|
2335
|
-
evaluate(scope) {
|
|
2336
|
-
return this.receiver.evaluate(scope)?.[this.argument.evaluate(scope)];
|
|
2337
|
-
},
|
|
2338
|
-
getIds(idents) {
|
|
2339
|
-
this.receiver.getIds(idents);
|
|
2340
|
-
return idents;
|
|
2341
|
-
}
|
|
2342
|
-
};
|
|
2343
|
-
}
|
|
2344
|
-
ternary(c2, t2, f) {
|
|
2345
|
-
return {
|
|
2346
|
-
type: "Ternary",
|
|
2347
|
-
condition: c2,
|
|
2348
|
-
trueExpr: t2,
|
|
2349
|
-
falseExpr: f,
|
|
2350
|
-
evaluate(scope) {
|
|
2351
|
-
const c3 = this.condition.evaluate(scope);
|
|
2352
|
-
if (c3) {
|
|
2353
|
-
return this.trueExpr.evaluate(scope);
|
|
2354
|
-
} else {
|
|
2355
|
-
return this.falseExpr.evaluate(scope);
|
|
2356
|
-
}
|
|
2357
|
-
},
|
|
2358
|
-
getIds(idents) {
|
|
2359
|
-
this.condition.getIds(idents);
|
|
2360
|
-
this.trueExpr.getIds(idents);
|
|
2361
|
-
this.falseExpr.getIds(idents);
|
|
2362
|
-
return idents;
|
|
2363
|
-
}
|
|
2364
|
-
};
|
|
2365
|
-
}
|
|
2366
|
-
map(entries) {
|
|
2367
|
-
return {
|
|
2368
|
-
type: "Map",
|
|
2369
|
-
entries,
|
|
2370
|
-
evaluate(scope) {
|
|
2371
|
-
const map = {};
|
|
2372
|
-
if (entries && this.entries) {
|
|
2373
|
-
for (const key in entries) {
|
|
2374
|
-
const val = this.entries[key];
|
|
2375
|
-
if (val) {
|
|
2376
|
-
map[key] = val.evaluate(scope);
|
|
2377
|
-
}
|
|
2378
|
-
}
|
|
2379
|
-
}
|
|
2380
|
-
return map;
|
|
2381
|
-
},
|
|
2382
|
-
getIds(idents) {
|
|
2383
|
-
if (entries && this.entries) {
|
|
2384
|
-
for (const key in entries) {
|
|
2385
|
-
const val = this.entries[key];
|
|
2386
|
-
if (val) {
|
|
2387
|
-
val.getIds(idents);
|
|
2388
|
-
}
|
|
2389
|
-
}
|
|
2390
|
-
}
|
|
2391
|
-
return idents;
|
|
2392
|
-
}
|
|
2393
|
-
};
|
|
2394
|
-
}
|
|
2395
|
-
// TODO(justinfagnani): if the list is deeply literal
|
|
2396
|
-
list(l) {
|
|
2397
|
-
return {
|
|
2398
|
-
type: "List",
|
|
2399
|
-
items: l,
|
|
2400
|
-
evaluate(scope) {
|
|
2401
|
-
return this.items?.map((a) => a?.evaluate(scope));
|
|
2402
|
-
},
|
|
2403
|
-
getIds(idents) {
|
|
2404
|
-
this.items?.forEach((i4) => i4?.getIds(idents));
|
|
2405
|
-
return idents;
|
|
2406
|
-
}
|
|
2407
|
-
};
|
|
2408
|
-
}
|
|
2409
|
-
arrowFunction(params, body) {
|
|
2410
|
-
return {
|
|
2411
|
-
type: "ArrowFunction",
|
|
2412
|
-
params,
|
|
2413
|
-
body,
|
|
2414
|
-
evaluate(scope) {
|
|
2415
|
-
const params2 = this.params;
|
|
2416
|
-
const body2 = this.body;
|
|
2417
|
-
return function(...args) {
|
|
2418
|
-
const paramsObj = fromEntries(params2.map((p, i4) => [p, args[i4]]));
|
|
2419
|
-
const newScope = new Proxy(scope ?? {}, {
|
|
2420
|
-
set(target, prop, value) {
|
|
2421
|
-
if (hasOwn(paramsObj, prop)) {
|
|
2422
|
-
paramsObj[prop] = value;
|
|
2423
|
-
}
|
|
2424
|
-
return target[prop] = value;
|
|
2425
|
-
},
|
|
2426
|
-
get(target, prop) {
|
|
2427
|
-
if (hasOwn(paramsObj, prop)) {
|
|
2428
|
-
return paramsObj[prop];
|
|
2429
|
-
}
|
|
2430
|
-
return target[prop];
|
|
2431
|
-
}
|
|
2432
|
-
});
|
|
2433
|
-
return body2.evaluate(newScope);
|
|
2434
|
-
};
|
|
2435
|
-
},
|
|
2436
|
-
getIds(idents) {
|
|
2437
|
-
return this.body.getIds(idents).filter((id) => !this.params.includes(id));
|
|
2438
|
-
}
|
|
2439
|
-
};
|
|
2440
|
-
}
|
|
2441
|
-
};
|
|
2442
|
-
|
|
2443
|
-
// ../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/node/private-ssr-support.js
|
|
2444
|
-
var r2 = null;
|
|
2445
|
-
var i3 = { boundAttributeSuffix: W.M, marker: W.P, markerMatch: W.A, HTML_RESULT: W.C, getTemplateHtml: W.L, overrideDirectiveResolve: (e2, t2) => class extends e2 {
|
|
2446
|
-
_$AS(e3, r3) {
|
|
2447
|
-
return t2(this, r3);
|
|
2448
|
-
}
|
|
2449
|
-
}, patchDirectiveResolve: (e2, t2) => {
|
|
2450
|
-
if (e2.prototype._$AS.name !== t2.name) {
|
|
2451
|
-
r2 ??= e2.prototype._$AS.name;
|
|
2452
|
-
for (let i4 = e2.prototype; i4 !== Object.prototype; i4 = Object.getPrototypeOf(i4)) if (i4.hasOwnProperty(r2)) return void (i4[r2] = t2);
|
|
2453
|
-
throw Error("Internal error: It is possible that both dev mode and production mode Lit was mixed together during SSR. Please comment on the issue: https://github.com/lit/lit/issues/4527");
|
|
2454
|
-
}
|
|
2455
|
-
}, setDirectiveClass(e2, t2) {
|
|
2456
|
-
e2._$litDirective$ = t2;
|
|
2457
|
-
}, getAttributePartCommittedValue: (e2, r3, i4) => {
|
|
2458
|
-
let o = w;
|
|
2459
|
-
return e2.j = (e3) => o = e3, e2._$AI(r3, e2, i4), o;
|
|
2460
|
-
}, connectedDisconnectable: (e2) => ({ ...e2, _$AU: true }), resolveDirective: W.V, AttributePart: W.H, PropertyPart: W.B, BooleanAttributePart: W.N, EventPart: W.U, ElementPart: W.F, TemplateInstance: W.R, isIterable: W.D, ChildPart: W.I };
|
|
2461
|
-
|
|
2462
|
-
// ../../node_modules/.pnpm/@heximal+templates@0.1.5/node_modules/@heximal/templates/index.js
|
|
2463
|
-
var { AttributePart, PropertyPart, BooleanAttributePart, EventPart } = i3;
|
|
2464
|
-
var astFactory = new EvalAstFactory();
|
|
2465
|
-
var expressionCache = /* @__PURE__ */ new Map();
|
|
2466
|
-
var toCamelCase = (s) => s.replace(/-(-|\w)/g, (_, p1) => p1.toUpperCase());
|
|
2467
|
-
var getSingleValue = (s, model) => {
|
|
2468
|
-
let ast = expressionCache.get(s);
|
|
2469
|
-
if (ast === void 0) {
|
|
2470
|
-
if (expressionCache.has(s)) {
|
|
2471
|
-
return void 0;
|
|
2472
|
-
}
|
|
2473
|
-
s = s.trim();
|
|
2474
|
-
if (s.startsWith("{{") && s.endsWith("}}")) {
|
|
2475
|
-
const expression = s.substring(2, s.length - 2).trim();
|
|
2476
|
-
ast = new Parser(expression, astFactory).parse();
|
|
2477
|
-
expressionCache.set(s, ast);
|
|
2478
|
-
}
|
|
2479
|
-
}
|
|
2480
|
-
return ast?.evaluate(model);
|
|
2481
|
-
};
|
|
2482
|
-
var ifHandler = (template, model, handlers, renderers) => {
|
|
2483
|
-
const ifAttribute = template.getAttribute("if");
|
|
2484
|
-
if (ifAttribute !== null && getSingleValue(ifAttribute, model)) {
|
|
2485
|
-
return evaluateTemplate(template, model, handlers, renderers);
|
|
2486
|
-
}
|
|
2487
|
-
return void 0;
|
|
2488
|
-
};
|
|
2489
|
-
var bindingRegex = /(?<!\\){{(.*?)(?:(?<!\\)}})/g;
|
|
2490
|
-
var hasEscapedBindingMarkers = (s) => /(?:\\{{)|(?:\\}})/g.test(s);
|
|
2491
|
-
var unescapeBindingMarkers = (s) => s.replaceAll(/\\{{/g, "{{").replace(/\\}}/g, "}}");
|
|
2492
|
-
var repeatHandler = (template, model, handlers, renderers) => {
|
|
2493
|
-
const repeatAttribute = template.getAttribute("repeat");
|
|
2494
|
-
if (repeatAttribute !== null) {
|
|
2495
|
-
const items = getSingleValue(repeatAttribute, model);
|
|
2496
|
-
if (!items[Symbol.iterator]) {
|
|
2497
|
-
return E;
|
|
2498
|
-
}
|
|
2499
|
-
const litTemplate = getLitTemplate(template);
|
|
2500
|
-
let index = -1;
|
|
2501
|
-
const result = [];
|
|
2502
|
-
for (const item of items) {
|
|
2503
|
-
index++;
|
|
2504
|
-
const itemModel = Object.create(model);
|
|
2505
|
-
itemModel.item = item;
|
|
2506
|
-
itemModel.index = index;
|
|
2507
|
-
itemModel["this"] = model["this"] ?? model;
|
|
2508
|
-
const values = [];
|
|
2509
|
-
for (const part of litTemplate.parts) {
|
|
2510
|
-
const value = part.update(itemModel, handlers, renderers);
|
|
2511
|
-
if (part.type === 1) {
|
|
2512
|
-
values.push(...value);
|
|
2513
|
-
} else {
|
|
2514
|
-
values.push(value);
|
|
2515
|
-
}
|
|
2516
|
-
}
|
|
2517
|
-
const templateResult = {
|
|
2518
|
-
_$litType$: litTemplate,
|
|
2519
|
-
values
|
|
2520
|
-
};
|
|
2521
|
-
result.push(templateResult);
|
|
2522
|
-
}
|
|
2523
|
-
return result;
|
|
2524
|
-
}
|
|
2525
|
-
return void 0;
|
|
2526
|
-
};
|
|
2527
|
-
var defaultHandlers = {
|
|
2528
|
-
if: ifHandler,
|
|
2529
|
-
repeat: repeatHandler
|
|
2530
|
-
};
|
|
2531
|
-
var prepareTemplate = (template, handlers = defaultHandlers, renderers = {}, superTemplate) => {
|
|
2532
|
-
const litTemplate = getLitTemplate(template);
|
|
2533
|
-
const templateRenderers = litTemplate.renderers;
|
|
2534
|
-
if (superTemplate) {
|
|
2535
|
-
const superLitTemplate = getLitTemplate(superTemplate);
|
|
2536
|
-
const superRenderers = superLitTemplate.renderers;
|
|
2537
|
-
const superCallRenderer = templateRenderers["super"];
|
|
2538
|
-
if (superCallRenderer !== void 0) {
|
|
2539
|
-
renderers = {
|
|
2540
|
-
// sub template's own renderes
|
|
2541
|
-
...templateRenderers,
|
|
2542
|
-
// passed-in renderers
|
|
2543
|
-
...renderers,
|
|
2544
|
-
// a super call renderer
|
|
2545
|
-
super: (model, handlers2, renderers2) => {
|
|
2546
|
-
renderers2 = {
|
|
2547
|
-
// super template's own blocks
|
|
2548
|
-
...superRenderers,
|
|
2549
|
-
// passed-in renderers
|
|
2550
|
-
...renderers2,
|
|
2551
|
-
// sub template's overrides will be added by the inner super call
|
|
2552
|
-
super: (model2, handlers3, renderers3) => {
|
|
2553
|
-
return evaluateTemplate(superTemplate, model2, handlers3, renderers3);
|
|
2554
|
-
}
|
|
2555
|
-
};
|
|
2556
|
-
return superCallRenderer(model, handlers2, renderers2);
|
|
2557
|
-
}
|
|
2558
|
-
};
|
|
2559
|
-
} else {
|
|
2560
|
-
renderers = {
|
|
2561
|
-
// super template's own blocks
|
|
2562
|
-
...superRenderers,
|
|
2563
|
-
// sub template's overrides
|
|
2564
|
-
...templateRenderers,
|
|
2565
|
-
// passed-in renderers
|
|
2566
|
-
...renderers
|
|
2567
|
-
};
|
|
2568
|
-
template = superTemplate;
|
|
2569
|
-
}
|
|
2570
|
-
} else {
|
|
2571
|
-
renderers = {
|
|
2572
|
-
// template's named blocks
|
|
2573
|
-
...templateRenderers,
|
|
2574
|
-
// passed-in renderers
|
|
2575
|
-
...renderers
|
|
2576
|
-
};
|
|
2577
|
-
}
|
|
2578
|
-
return (model) => evaluateTemplate(template, model, handlers, renderers);
|
|
2579
|
-
};
|
|
2580
|
-
var evaluateTemplate = (template, model, handlers = defaultHandlers, renderers = {}) => {
|
|
2581
|
-
const litTemplate = getLitTemplate(template);
|
|
2582
|
-
const values = [];
|
|
2583
|
-
for (const part of litTemplate.parts) {
|
|
2584
|
-
const value = part.update(model, handlers, renderers);
|
|
2585
|
-
if (part.type === 1) {
|
|
2586
|
-
values.push(...value);
|
|
2587
|
-
} else {
|
|
2588
|
-
values.push(value);
|
|
2589
|
-
}
|
|
2590
|
-
}
|
|
2591
|
-
const templateResult = {
|
|
2592
|
-
_$litType$: litTemplate,
|
|
2593
|
-
values
|
|
2594
|
-
};
|
|
2595
|
-
return templateResult;
|
|
2596
|
-
};
|
|
2597
|
-
var litTemplateCache = /* @__PURE__ */ new Map();
|
|
2598
|
-
var getLitTemplate = (template) => {
|
|
2599
|
-
let litTemplate = litTemplateCache.get(template);
|
|
2600
|
-
if (litTemplate === void 0) {
|
|
2601
|
-
litTemplateCache.set(template, litTemplate = makeLitTemplate(template));
|
|
2602
|
-
}
|
|
2603
|
-
return litTemplate;
|
|
2604
|
-
};
|
|
2605
|
-
var makeLitTemplate = (template) => {
|
|
2606
|
-
const litTemplate = {
|
|
2607
|
-
h: void 0,
|
|
2608
|
-
el: template.cloneNode(true),
|
|
2609
|
-
parts: [],
|
|
2610
|
-
renderers: {}
|
|
2611
|
-
};
|
|
2612
|
-
const walker = document.createTreeWalker(litTemplate.el.content, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT);
|
|
2613
|
-
let node = walker.currentNode;
|
|
2614
|
-
let nodeIndex = -1;
|
|
2615
|
-
const elementsToRemove = [];
|
|
2616
|
-
while ((node = walker.nextNode()) !== null) {
|
|
2617
|
-
if (node.nodeType === Node.COMMENT_NODE) {
|
|
2618
|
-
nodeIndex++;
|
|
2619
|
-
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
2620
|
-
nodeIndex++;
|
|
2621
|
-
const element = node;
|
|
2622
|
-
if (element.tagName === "TEMPLATE") {
|
|
2623
|
-
const type = element.getAttribute("type");
|
|
2624
|
-
const name = element.getAttribute("name");
|
|
2625
|
-
const call = element.getAttribute("call");
|
|
2626
|
-
if (call !== null || type !== null || name !== null) {
|
|
2627
|
-
element.parentNode.insertBefore(document.createComment(""), element);
|
|
2628
|
-
elementsToRemove.push(element);
|
|
2629
|
-
let update;
|
|
2630
|
-
if (call !== null) {
|
|
2631
|
-
const templateName = call.trim();
|
|
2632
|
-
const templateNameIsExpression = templateName.startsWith("{{") && templateName.endsWith("}}");
|
|
2633
|
-
update = (model, handlers, renderers) => {
|
|
2634
|
-
const dataAttr = element.getAttribute("data");
|
|
2635
|
-
const data = dataAttr === null ? void 0 : getSingleValue(dataAttr, model);
|
|
2636
|
-
const renderer = templateNameIsExpression ? getSingleValue(templateName, model) : renderers[call];
|
|
2637
|
-
return renderer?.(data, handlers, renderers);
|
|
2638
|
-
};
|
|
2639
|
-
} else if (type !== null) {
|
|
2640
|
-
update = (model, handlers, renderers) => {
|
|
2641
|
-
const handler = handlers[type];
|
|
2642
|
-
return handler?.(element, model, handlers, renderers);
|
|
2643
|
-
};
|
|
2644
|
-
} else {
|
|
2645
|
-
if (name === "super") {
|
|
2646
|
-
litTemplate.renderers["super"] = (model, handlers, renderers) => {
|
|
2647
|
-
const superRenderer = renderers["super"];
|
|
2648
|
-
const superCallTemplate = getLitTemplate(element);
|
|
2649
|
-
renderers = {
|
|
2650
|
-
...renderers,
|
|
2651
|
-
...superCallTemplate.renderers
|
|
2652
|
-
};
|
|
2653
|
-
return superRenderer(model, handlers, renderers);
|
|
2654
|
-
};
|
|
2655
|
-
} else {
|
|
2656
|
-
litTemplate.renderers[name] = (model, handlers, renderers) => {
|
|
2657
|
-
return evaluateTemplate(element, model, handlers, renderers);
|
|
2658
|
-
};
|
|
2659
|
-
}
|
|
2660
|
-
update = (model, handlers, renderers) => {
|
|
2661
|
-
const renderer = renderers[name];
|
|
2662
|
-
return renderer?.(model, handlers, renderers);
|
|
2663
|
-
};
|
|
2664
|
-
}
|
|
2665
|
-
litTemplate.parts.push({
|
|
2666
|
-
type: 2,
|
|
2667
|
-
// text binding
|
|
2668
|
-
index: nodeIndex,
|
|
2669
|
-
update
|
|
2670
|
-
});
|
|
2671
|
-
continue;
|
|
2672
|
-
}
|
|
2673
|
-
}
|
|
2674
|
-
const attributeNames = element.getAttributeNames();
|
|
2675
|
-
for (const attributeName of attributeNames) {
|
|
2676
|
-
const attributeValue = element.getAttribute(attributeName);
|
|
2677
|
-
const splitValue = attributeValue.split(bindingRegex);
|
|
2678
|
-
if (splitValue.length === 1) {
|
|
2679
|
-
if (hasEscapedBindingMarkers(attributeValue)) {
|
|
2680
|
-
element.setAttribute(attributeName, unescapeBindingMarkers(attributeValue));
|
|
2681
|
-
}
|
|
2682
|
-
continue;
|
|
2683
|
-
}
|
|
2684
|
-
element.removeAttribute(attributeName);
|
|
2685
|
-
let name = attributeName;
|
|
2686
|
-
let ctor = AttributePart;
|
|
2687
|
-
const prefix = attributeName[0];
|
|
2688
|
-
if (prefix === ".") {
|
|
2689
|
-
name = toCamelCase(attributeName.substring(1));
|
|
2690
|
-
ctor = PropertyPart;
|
|
2691
|
-
} else if (prefix === "?") {
|
|
2692
|
-
name = attributeName.substring(1);
|
|
2693
|
-
ctor = BooleanAttributePart;
|
|
2694
|
-
} else if (prefix === "@") {
|
|
2695
|
-
name = toCamelCase(attributeName.substring(1));
|
|
2696
|
-
ctor = EventPart;
|
|
2697
|
-
}
|
|
2698
|
-
const strings = [unescapeBindingMarkers(splitValue[0])];
|
|
2699
|
-
const exprs = [];
|
|
2700
|
-
for (let i4 = 1; i4 < splitValue.length; i4 += 2) {
|
|
2701
|
-
const exprText = splitValue[i4];
|
|
2702
|
-
exprs.push(parse(exprText, astFactory));
|
|
2703
|
-
strings.push(unescapeBindingMarkers(splitValue[i4 + 1]));
|
|
2704
|
-
}
|
|
2705
|
-
litTemplate.parts.push({
|
|
2706
|
-
type: 1,
|
|
2707
|
-
// attribute binding
|
|
2708
|
-
index: nodeIndex,
|
|
2709
|
-
name,
|
|
2710
|
-
strings,
|
|
2711
|
-
ctor,
|
|
2712
|
-
update: (model, _handlers, _renderers) => {
|
|
2713
|
-
return exprs.map((expr) => expr.evaluate(model));
|
|
2714
|
-
}
|
|
2715
|
-
});
|
|
2716
|
-
}
|
|
2717
|
-
} else if (node.nodeType === Node.TEXT_NODE) {
|
|
2718
|
-
let textNode = node;
|
|
2719
|
-
const text = textNode.textContent;
|
|
2720
|
-
const strings = text.split(bindingRegex);
|
|
2721
|
-
if (strings.length > 1) {
|
|
2722
|
-
textNode.textContent = unescapeBindingMarkers(strings[0]);
|
|
2723
|
-
} else if (hasEscapedBindingMarkers(text)) {
|
|
2724
|
-
textNode.textContent = unescapeBindingMarkers(text);
|
|
2725
|
-
}
|
|
2726
|
-
for (let i4 = 1; i4 < strings.length; i4 += 2) {
|
|
2727
|
-
const exprText = strings[i4];
|
|
2728
|
-
const expr = parse(exprText, astFactory);
|
|
2729
|
-
litTemplate.parts.push({
|
|
2730
|
-
type: 2,
|
|
2731
|
-
index: ++nodeIndex,
|
|
2732
|
-
update: (model, _handlers) => expr.evaluate(model)
|
|
2733
|
-
});
|
|
2734
|
-
const newTextNode = new Text(strings[i4 + 1].replace("\\{{", "{{"));
|
|
2735
|
-
textNode.parentNode.insertBefore(newTextNode, textNode.nextSibling);
|
|
2736
|
-
textNode.parentNode.insertBefore(document.createComment(""), textNode.nextSibling);
|
|
2737
|
-
textNode = newTextNode;
|
|
2738
|
-
walker.currentNode = newTextNode;
|
|
2739
|
-
}
|
|
2740
|
-
}
|
|
2741
|
-
}
|
|
2742
|
-
for (const e2 of elementsToRemove) {
|
|
2743
|
-
e2.remove();
|
|
2744
|
-
}
|
|
2745
|
-
return litTemplate;
|
|
2746
|
-
};
|
|
2747
|
-
|
|
2748
|
-
// ../qti-test/src/components/test-paging-buttons-stamp/test-paging-buttons-stamp.ts
|
|
2749
|
-
var TestPagingButtonsStamp = class extends i2 {
|
|
2750
|
-
createRenderRoot() {
|
|
2751
|
-
return this;
|
|
2752
|
-
}
|
|
2753
|
-
constructor() {
|
|
2754
|
-
super();
|
|
2755
|
-
this._internals = this.attachInternals();
|
|
2756
|
-
this._internals.ariaLabel = "pagination";
|
|
2757
|
-
}
|
|
2758
|
-
connectedCallback() {
|
|
2759
|
-
super.connectedCallback();
|
|
2760
|
-
const templateElement = this.querySelector("template");
|
|
2761
|
-
this.myTemplate = prepareTemplate(templateElement);
|
|
2762
|
-
}
|
|
2763
|
-
render() {
|
|
2764
|
-
if (!this.computedContext) return x``;
|
|
2765
|
-
const items = this.computedContext.testParts.flatMap(
|
|
2766
|
-
(testPart) => testPart.sections.flatMap((section) => section.items)
|
|
2767
|
-
);
|
|
2768
|
-
return x` ${items.map((item) => this.myTemplate({ item, view: this.computedContext.view }))} `;
|
|
2769
|
-
}
|
|
2770
|
-
};
|
|
2771
|
-
__decorateClass([
|
|
2772
|
-
c({ context: computedContext, subscribe: true })
|
|
2773
|
-
], TestPagingButtonsStamp.prototype, "computedContext", 2);
|
|
2774
|
-
TestPagingButtonsStamp = __decorateClass([
|
|
2775
|
-
t("test-paging-buttons-stamp")
|
|
2776
|
-
], TestPagingButtonsStamp);
|
|
2777
|
-
|
|
2778
|
-
// ../qti-test/src/components/test-container/test-container.ts
|
|
2779
|
-
var TestContainer = class extends i2 {
|
|
2780
|
-
constructor() {
|
|
2781
|
-
super(...arguments);
|
|
2782
|
-
this.testURL = null;
|
|
2783
|
-
this.testDoc = null;
|
|
2784
|
-
this.testXML = null;
|
|
2785
|
-
/** Template content if provided */
|
|
2786
|
-
this.templateContent = null;
|
|
2787
|
-
}
|
|
2788
|
-
async handleTestURLChange() {
|
|
2789
|
-
if (!this.testURL) return;
|
|
2790
|
-
try {
|
|
2791
|
-
let api = await qtiTransformTest().load(this.testURL);
|
|
2792
|
-
const qtiTest = this.closest("qti-test");
|
|
2793
|
-
if (qtiTest?.postLoadTestTransformCallback) {
|
|
2794
|
-
const tempDoc = api.htmlDoc();
|
|
2795
|
-
const testElement = tempDoc.querySelector("qti-assessment-test");
|
|
2796
|
-
if (testElement) {
|
|
2797
|
-
api = await qtiTest.postLoadTestTransformCallback(api, testElement);
|
|
2798
|
-
}
|
|
2799
|
-
}
|
|
2800
|
-
this.testDoc = api.htmlDoc();
|
|
2801
|
-
} catch (error) {
|
|
2802
|
-
console.error("Error loading or parsing XML:", error);
|
|
2803
|
-
}
|
|
2804
|
-
}
|
|
2805
|
-
handleTestXMLChange() {
|
|
2806
|
-
if (!this.testXML) return;
|
|
2807
|
-
try {
|
|
2808
|
-
this.testDoc = qtiTransformTest().parse(this.testXML).htmlDoc();
|
|
2809
|
-
} catch (error) {
|
|
2810
|
-
console.error("Error parsing XML:", error);
|
|
2811
|
-
}
|
|
2812
|
-
}
|
|
2813
|
-
async connectedCallback() {
|
|
2814
|
-
super.connectedCallback();
|
|
2815
|
-
this.initializeTemplateContent();
|
|
2816
|
-
this.applyStyles();
|
|
2817
|
-
if (this.testURL) {
|
|
2818
|
-
this.handleTestURLChange();
|
|
2819
|
-
}
|
|
2820
|
-
if (this.testXML) {
|
|
2821
|
-
this.handleTestXMLChange();
|
|
2822
|
-
}
|
|
2823
|
-
}
|
|
2824
|
-
initializeTemplateContent() {
|
|
2825
|
-
const template = this.querySelector("template");
|
|
2826
|
-
this.templateContent = template ? template.content : x``;
|
|
2827
|
-
}
|
|
2828
|
-
applyStyles() {
|
|
2829
|
-
const sheet = new CSSStyleSheet();
|
|
2830
|
-
sheet.replaceSync(item_default);
|
|
2831
|
-
this.shadowRoot.adoptedStyleSheets = [sheet];
|
|
2832
|
-
}
|
|
2833
|
-
render() {
|
|
2834
|
-
return x`
|
|
2835
|
-
${this.templateContent}
|
|
2836
|
-
<slot></slot>
|
|
2837
|
-
${m(this.testDoc, x`<span>Loading...</span>`)}
|
|
2838
|
-
`;
|
|
2839
|
-
}
|
|
2840
|
-
};
|
|
2841
|
-
__decorateClass([
|
|
2842
|
-
n({ type: String, attribute: "test-url" })
|
|
2843
|
-
], TestContainer.prototype, "testURL", 2);
|
|
2844
|
-
__decorateClass([
|
|
2845
|
-
r()
|
|
2846
|
-
], TestContainer.prototype, "testDoc", 2);
|
|
2847
|
-
__decorateClass([
|
|
2848
|
-
r()
|
|
2849
|
-
], TestContainer.prototype, "testXML", 2);
|
|
2850
|
-
__decorateClass([
|
|
2851
|
-
watch("testURL", { waitUntilFirstUpdate: true })
|
|
2852
|
-
], TestContainer.prototype, "handleTestURLChange", 1);
|
|
2853
|
-
__decorateClass([
|
|
2854
|
-
watch("testXML", { waitUntilFirstUpdate: true })
|
|
2855
|
-
], TestContainer.prototype, "handleTestXMLChange", 1);
|
|
2856
|
-
TestContainer = __decorateClass([
|
|
2857
|
-
t("test-container")
|
|
2858
|
-
], TestContainer);
|
|
2859
|
-
|
|
2860
|
-
// ../qti-test/src/components/test-print-item-variables/test-print-item-variables.ts
|
|
2861
|
-
var TestPrintVariables = class extends i2 {
|
|
2862
|
-
render() {
|
|
2863
|
-
const activeItem = this.computedContext?.testParts.flatMap((testPart) => testPart.sections.flatMap((section) => section.items)).find((item) => item.active);
|
|
2864
|
-
if (!activeItem || !activeItem.variables) return x``;
|
|
2865
|
-
const responseVariables = activeItem.variables.filter((v) => v.type === "response");
|
|
2866
|
-
const outcomeVariables = activeItem.variables.filter((v) => v.type === "outcome");
|
|
2867
|
-
const renderTable = (variables, title) => x`
|
|
2868
|
-
<h3>${title}</h3>
|
|
2869
|
-
<table>
|
|
2870
|
-
<thead>
|
|
2871
|
-
<tr>
|
|
2872
|
-
<th>Identifier</th>
|
|
2873
|
-
<th>Value</th>
|
|
2874
|
-
<th>Cardinality</th>
|
|
2875
|
-
<th>Base Type</th>
|
|
2876
|
-
<th>Correct Response / Mappings</th>
|
|
2877
|
-
</tr>
|
|
2878
|
-
</thead>
|
|
2879
|
-
<tbody>
|
|
2880
|
-
${variables.map((v) => {
|
|
2881
|
-
const correctResponse = v.correctResponse ? Array.isArray(v.correctResponse) ? v.correctResponse.join(", ") : v.correctResponse : "";
|
|
2882
|
-
const mapEntries = v.mapping?.mapEntries?.map((m2) => `${m2.mapKey}=${m2.mappedValue}pt`).join(", ") || "";
|
|
2883
|
-
const areaMapEntries = v.areaMapping?.areaMapEntries?.map((m2) => `${m2.shape}(${m2.coords})=${m2.mappedValue}pt`).join(", ") || "";
|
|
2884
|
-
return x`
|
|
2885
|
-
<tr>
|
|
2886
|
-
<td>${v.identifier}</td>
|
|
2887
|
-
<td>${Array.isArray(v.value) ? v.value.join(", ") : v.value}</td>
|
|
2888
|
-
<td>${v.cardinality}</td>
|
|
2889
|
-
<td>${v.baseType}</td>
|
|
2890
|
-
<td>${correctResponse || mapEntries || areaMapEntries}</td>
|
|
2891
|
-
</tr>
|
|
2892
|
-
`;
|
|
2893
|
-
})}
|
|
2894
|
-
</tbody>
|
|
2895
|
-
</table>
|
|
2896
|
-
`;
|
|
2897
|
-
return x`
|
|
2898
|
-
${renderTable(responseVariables, "Response Variables")} ${renderTable(outcomeVariables, "Outcome Variables")}
|
|
2899
|
-
`;
|
|
2900
|
-
}
|
|
2901
|
-
};
|
|
2902
|
-
TestPrintVariables.styles = i`
|
|
2903
|
-
table {
|
|
2904
|
-
width: 100%;
|
|
2905
|
-
border-collapse: collapse;
|
|
2906
|
-
margin: 20px 0;
|
|
2907
|
-
font-size: 14px;
|
|
2908
|
-
text-align: left;
|
|
2909
|
-
}
|
|
2910
|
-
th,
|
|
2911
|
-
td {
|
|
2912
|
-
border: 1px solid #ddd;
|
|
2913
|
-
padding: 8px;
|
|
2914
|
-
}
|
|
2915
|
-
th {
|
|
2916
|
-
background-color: #f4f4f4;
|
|
2917
|
-
font-weight: bold;
|
|
2918
|
-
}
|
|
2919
|
-
h3 {
|
|
2920
|
-
margin-top: 20px;
|
|
2921
|
-
font-size: 16px;
|
|
2922
|
-
}
|
|
2923
|
-
`;
|
|
2924
|
-
__decorateClass([
|
|
2925
|
-
c({ context: computedContext, subscribe: true })
|
|
2926
|
-
], TestPrintVariables.prototype, "computedContext", 2);
|
|
2927
|
-
TestPrintVariables = __decorateClass([
|
|
2928
|
-
t("test-print-item-variables")
|
|
2929
|
-
], TestPrintVariables);
|
|
2930
|
-
|
|
2931
|
-
// ../qti-test/src/components/test-section-buttons-stamp/test-section-buttons-stamp.ts
|
|
2932
|
-
var TestSectionButtonsStamp = class extends i2 {
|
|
2933
|
-
createRenderRoot() {
|
|
2934
|
-
return this;
|
|
2935
|
-
}
|
|
2936
|
-
constructor() {
|
|
2937
|
-
super();
|
|
2938
|
-
this._internals = this.attachInternals();
|
|
2939
|
-
this._internals.ariaLabel = "pagination";
|
|
2940
|
-
}
|
|
2941
|
-
connectedCallback() {
|
|
2942
|
-
super.connectedCallback();
|
|
2943
|
-
const templateElement = this.querySelector("template");
|
|
2944
|
-
this.myTemplate = prepareTemplate(templateElement);
|
|
2945
|
-
}
|
|
2946
|
-
render() {
|
|
2947
|
-
if (!this.computedContext) return x``;
|
|
2948
|
-
const sections = this.computedContext.testParts.flatMap((testPart) => testPart.sections);
|
|
2949
|
-
return x` ${sections.map((item) => this.myTemplate({ item }))} `;
|
|
2950
|
-
}
|
|
2951
|
-
};
|
|
2952
|
-
__decorateClass([
|
|
2953
|
-
c({ context: computedContext, subscribe: true })
|
|
2954
|
-
], TestSectionButtonsStamp.prototype, "computedContext", 2);
|
|
2955
|
-
TestSectionButtonsStamp = __decorateClass([
|
|
2956
|
-
t("test-section-buttons-stamp")
|
|
2957
|
-
], TestSectionButtonsStamp);
|
|
2958
|
-
|
|
2959
|
-
// ../qti-test/src/components/test-section-link/test-section-link.ts
|
|
2960
|
-
var TestSectionLink = class extends i2 {
|
|
2961
|
-
constructor() {
|
|
2962
|
-
super();
|
|
2963
|
-
this.sectionId = null;
|
|
2964
|
-
this.addEventListener("click", () => this._requestItem(this.sectionId));
|
|
2965
|
-
}
|
|
2966
|
-
_requestItem(identifier) {
|
|
2967
|
-
this.dispatchEvent(
|
|
2968
|
-
new CustomEvent("qti-request-navigation", {
|
|
2969
|
-
composed: true,
|
|
2970
|
-
bubbles: true,
|
|
2971
|
-
detail: {
|
|
2972
|
-
type: "section",
|
|
2973
|
-
id: identifier
|
|
2974
|
-
}
|
|
2975
|
-
})
|
|
2976
|
-
);
|
|
2977
|
-
}
|
|
2978
|
-
render() {
|
|
2979
|
-
return x` <slot></slot> `;
|
|
2980
|
-
}
|
|
2981
|
-
};
|
|
2982
|
-
TestSectionLink.styles = i`
|
|
2983
|
-
:host {
|
|
2984
|
-
${btn};
|
|
2985
|
-
}
|
|
2986
|
-
:host([disabled]) {
|
|
2987
|
-
${dis};
|
|
2988
|
-
}
|
|
2989
|
-
`;
|
|
2990
|
-
__decorateClass([
|
|
2991
|
-
n({ type: String, attribute: "section-id" })
|
|
2992
|
-
], TestSectionLink.prototype, "sectionId", 2);
|
|
2993
|
-
TestSectionLink = __decorateClass([
|
|
2994
|
-
t("test-section-link")
|
|
2995
|
-
], TestSectionLink);
|
|
2996
|
-
|
|
2997
|
-
// ../qti-test/src/components/test-print-context/test-print-context.ts
|
|
2998
|
-
var TestPrintContext = class extends i2 {
|
|
2999
|
-
render() {
|
|
3000
|
-
return x` <small><pre>${JSON.stringify(this.computedContext, null, 2)}</pre></small> `;
|
|
3001
|
-
}
|
|
3002
|
-
};
|
|
3003
|
-
__decorateClass([
|
|
3004
|
-
r(),
|
|
3005
|
-
c({ context: computedContext, subscribe: true })
|
|
3006
|
-
], TestPrintContext.prototype, "computedContext", 2);
|
|
3007
|
-
TestPrintContext = __decorateClass([
|
|
3008
|
-
t("test-print-context")
|
|
3009
|
-
], TestPrintContext);
|
|
3010
|
-
|
|
3011
|
-
// ../qti-test/src/components/test-stamp/test-stamp.ts
|
|
3012
|
-
var TestStamp = class extends i2 {
|
|
3013
|
-
constructor() {
|
|
3014
|
-
super(...arguments);
|
|
3015
|
-
this.debug = false;
|
|
3016
|
-
this.stampContext = {
|
|
3017
|
-
view: "candidate",
|
|
3018
|
-
activeItem: {},
|
|
3019
|
-
activeSection: {
|
|
3020
|
-
items: []
|
|
3021
|
-
},
|
|
3022
|
-
activeTestpart: {
|
|
3023
|
-
items: [],
|
|
3024
|
-
sections: []
|
|
3025
|
-
},
|
|
3026
|
-
test: {}
|
|
3027
|
-
};
|
|
3028
|
-
}
|
|
3029
|
-
createRenderRoot() {
|
|
3030
|
-
return this;
|
|
3031
|
-
}
|
|
3032
|
-
connectedCallback() {
|
|
3033
|
-
super.connectedCallback();
|
|
3034
|
-
const templateElement = this.querySelector("template");
|
|
3035
|
-
if (!templateElement) {
|
|
3036
|
-
this.myTemplate = null;
|
|
3037
|
-
return;
|
|
3038
|
-
}
|
|
3039
|
-
this.myTemplate = prepareTemplate(templateElement);
|
|
3040
|
-
}
|
|
3041
|
-
willUpdate(_changedProperties) {
|
|
3042
|
-
if (!this.computedContext) {
|
|
3043
|
-
return;
|
|
3044
|
-
}
|
|
3045
|
-
const activeTestPart = this.computedContext.testParts.find((testPart) => testPart.active);
|
|
3046
|
-
const activeSection = activeTestPart?.sections.find((section) => section.active);
|
|
3047
|
-
const activeItem = activeSection?.items.find((item) => item.active);
|
|
3048
|
-
const { variables, ...augmentedItem } = activeItem || {};
|
|
3049
|
-
if (!activeTestPart || !activeSection || !activeItem) {
|
|
3050
|
-
return;
|
|
3051
|
-
}
|
|
3052
|
-
const augmentedTestPart = {
|
|
3053
|
-
...activeTestPart,
|
|
3054
|
-
items: activeTestPart.sections.flatMap((section) => section.items.map(({ variables: variables2, ...rest }) => rest)),
|
|
3055
|
-
sections: activeTestPart.sections.map((section) => ({
|
|
3056
|
-
...section,
|
|
3057
|
-
items: section.items.map(({ variables: variables2, ...rest }) => rest)
|
|
3058
|
-
}))
|
|
3059
|
-
};
|
|
3060
|
-
const augmentedSection = { ...activeSection, items: activeSection.items.map(({ variables: variables2, ...rest }) => rest) };
|
|
3061
|
-
const { testParts, ...activeTest } = this.computedContext;
|
|
3062
|
-
this.stampContext = {
|
|
3063
|
-
view: this.computedContext.view,
|
|
3064
|
-
activeItem: augmentedItem,
|
|
3065
|
-
activeSection: augmentedSection,
|
|
3066
|
-
activeTestpart: augmentedTestPart,
|
|
3067
|
-
test: activeTest
|
|
3068
|
-
};
|
|
3069
|
-
this.dispatchEvent(
|
|
3070
|
-
new CustomEvent("qti-stamp-context-updated", {
|
|
3071
|
-
detail: this.stampContext,
|
|
3072
|
-
bubbles: true
|
|
3073
|
-
})
|
|
3074
|
-
);
|
|
3075
|
-
}
|
|
3076
|
-
render() {
|
|
3077
|
-
return x` ${this.debug ? x`<small><pre>${JSON.stringify(this.stampContext, null, 2)}</pre></small>` : E}
|
|
3078
|
-
${this.myTemplate ? this.myTemplate(this.stampContext) : E}`;
|
|
3079
|
-
}
|
|
3080
|
-
};
|
|
3081
|
-
__decorateClass([
|
|
3082
|
-
n({ type: Boolean, reflect: true })
|
|
3083
|
-
], TestStamp.prototype, "debug", 2);
|
|
3084
|
-
__decorateClass([
|
|
3085
|
-
r(),
|
|
3086
|
-
c({ context: computedContext, subscribe: true })
|
|
3087
|
-
], TestStamp.prototype, "computedContext", 2);
|
|
3088
|
-
__decorateClass([
|
|
3089
|
-
r()
|
|
3090
|
-
], TestStamp.prototype, "stampContext", 2);
|
|
3091
|
-
TestStamp = __decorateClass([
|
|
3092
|
-
t("test-stamp")
|
|
3093
|
-
], TestStamp);
|
|
3094
|
-
|
|
3095
|
-
// ../qti-test/src/components/test-scoring-buttons/test-scoring-buttons.ts
|
|
3096
|
-
var TestScoringButtons = class extends i2 {
|
|
3097
|
-
constructor() {
|
|
3098
|
-
super();
|
|
3099
|
-
this.view = "";
|
|
3100
|
-
this.disabled = false;
|
|
3101
|
-
this.myTemplate = null;
|
|
3102
|
-
this.addEventListener("click", (e2) => {
|
|
3103
|
-
const target = e2.target;
|
|
3104
|
-
const value = parseFloat(target.value);
|
|
3105
|
-
if (target.tagName === "INPUT") {
|
|
3106
|
-
this._changeOutcomeScore(value);
|
|
3107
|
-
}
|
|
3108
|
-
});
|
|
3109
|
-
}
|
|
3110
|
-
createRenderRoot() {
|
|
3111
|
-
return this;
|
|
3112
|
-
}
|
|
3113
|
-
connectedCallback() {
|
|
3114
|
-
super.connectedCallback();
|
|
3115
|
-
const templateElement = this.querySelector("template");
|
|
3116
|
-
if (!templateElement) {
|
|
3117
|
-
this.myTemplate = null;
|
|
3118
|
-
return;
|
|
3119
|
-
}
|
|
3120
|
-
this.myTemplate = prepareTemplate(templateElement);
|
|
3121
|
-
}
|
|
3122
|
-
_changeOutcomeScore(value) {
|
|
3123
|
-
const testPart = this.computedContext?.testParts.find((testPart2) => testPart2.active);
|
|
3124
|
-
const sectionItems = testPart.sections.flatMap((section) => section.items);
|
|
3125
|
-
const currentItemIdentifier = sectionItems.find((item) => item.active)?.identifier;
|
|
3126
|
-
this.dispatchEvent(
|
|
3127
|
-
new CustomEvent("test-update-outcome-variable", {
|
|
3128
|
-
detail: {
|
|
3129
|
-
assessmentItemRefId: currentItemIdentifier,
|
|
3130
|
-
outcomeVariableId: "SCORE",
|
|
3131
|
-
value
|
|
3132
|
-
},
|
|
3133
|
-
bubbles: true
|
|
3134
|
-
})
|
|
3135
|
-
);
|
|
3136
|
-
}
|
|
3137
|
-
render() {
|
|
3138
|
-
const activeItem = this.computedContext?.testParts.flatMap((testPart) => testPart.sections.flatMap((section) => section.items)).find((item) => item.active);
|
|
3139
|
-
if (!activeItem || !activeItem.variables) return x``;
|
|
3140
|
-
const maxScore = activeItem.variables.find((vr) => vr.identifier == "MAXSCORE")?.value;
|
|
3141
|
-
const scoreOutcome = activeItem.variables.find((vr) => vr.identifier == "SCORE");
|
|
3142
|
-
const score = scoreOutcome?.value;
|
|
3143
|
-
const disabled = !(scoreOutcome?.externalScored === "human");
|
|
3144
|
-
if (!maxScore || !scoreOutcome) return E;
|
|
3145
|
-
const scores = [...Array(Number(maxScore) + 1).keys()];
|
|
3146
|
-
return x`${this.myTemplate ? this.myTemplate({ scores, score, disabled }) : E}`;
|
|
3147
|
-
}
|
|
3148
|
-
};
|
|
3149
|
-
__decorateClass([
|
|
3150
|
-
n({ type: String, attribute: "view" })
|
|
3151
|
-
], TestScoringButtons.prototype, "view", 2);
|
|
3152
|
-
__decorateClass([
|
|
3153
|
-
n({ type: Boolean })
|
|
3154
|
-
], TestScoringButtons.prototype, "disabled", 2);
|
|
3155
|
-
__decorateClass([
|
|
3156
|
-
c({ context: computedContext, subscribe: true })
|
|
3157
|
-
], TestScoringButtons.prototype, "computedContext", 2);
|
|
3158
|
-
TestScoringButtons = __decorateClass([
|
|
3159
|
-
t("test-scoring-buttons")
|
|
3160
|
-
], TestScoringButtons);
|
|
3161
|
-
|
|
3162
|
-
// ../qti-test/src/components/test-view-toggle/test-view-toggle.ts
|
|
3163
|
-
var TestViewToggle = class extends i2 {
|
|
3164
|
-
createRenderRoot() {
|
|
3165
|
-
return this;
|
|
3166
|
-
}
|
|
3167
|
-
connectedCallback() {
|
|
3168
|
-
super.connectedCallback();
|
|
3169
|
-
const templateElement = this.querySelector("template");
|
|
3170
|
-
if (!templateElement) {
|
|
3171
|
-
this.myTemplate = null;
|
|
3172
|
-
return;
|
|
3173
|
-
}
|
|
3174
|
-
this.myTemplate = prepareTemplate(templateElement);
|
|
3175
|
-
}
|
|
3176
|
-
_switchView(view) {
|
|
3177
|
-
this.dispatchEvent(
|
|
3178
|
-
new CustomEvent("on-test-switch-view", {
|
|
3179
|
-
composed: true,
|
|
3180
|
-
bubbles: true,
|
|
3181
|
-
detail: view
|
|
3182
|
-
})
|
|
3183
|
-
);
|
|
3184
|
-
}
|
|
3185
|
-
firstUpdated(_changedProperties) {
|
|
3186
|
-
this.addEventListener("click", () => {
|
|
3187
|
-
if (this.sessionContext?.view === "scorer") {
|
|
3188
|
-
this._switchView("candidate");
|
|
3189
|
-
} else {
|
|
3190
|
-
this._switchView("scorer");
|
|
3191
|
-
}
|
|
3192
|
-
});
|
|
3193
|
-
}
|
|
3194
|
-
render() {
|
|
3195
|
-
return x`${this.myTemplate ? this.myTemplate({
|
|
3196
|
-
view: this.sessionContext?.view
|
|
3197
|
-
}) : E}`;
|
|
3198
|
-
}
|
|
3199
|
-
};
|
|
3200
|
-
__decorateClass([
|
|
3201
|
-
c({ context: sessionContext, subscribe: true })
|
|
3202
|
-
], TestViewToggle.prototype, "sessionContext", 2);
|
|
3203
|
-
TestViewToggle = __decorateClass([
|
|
3204
|
-
t("test-view-toggle")
|
|
3205
|
-
], TestViewToggle);
|
|
3206
|
-
|
|
3207
|
-
// ../qti-test/src/components/test-scoring-feedback/test-scoring-feedback.ts
|
|
3208
|
-
var TestScoringFeedback = class extends i2 {
|
|
3209
|
-
constructor() {
|
|
3210
|
-
super(...arguments);
|
|
3211
|
-
this.view = null;
|
|
3212
|
-
}
|
|
3213
|
-
render() {
|
|
3214
|
-
const activeItem = this.computedContext?.testParts.flatMap((testPart) => testPart.sections.flatMap((section) => section.items)).find((item) => item.active);
|
|
3215
|
-
if (!activeItem || !activeItem.variables) return x``;
|
|
3216
|
-
if (activeItem["category"] === "dep-informational") return x`<div>${this.dataset.informational}</div>`;
|
|
3217
|
-
const completionStatus = activeItem?.variables.find((v) => v.identifier === "completionStatus")?.value;
|
|
3218
|
-
const scoreOutcome = activeItem?.variables.find((vr) => vr.identifier == "SCORE");
|
|
3219
|
-
const score = parseFloat(scoreOutcome?.value);
|
|
3220
|
-
const externalScored = activeItem["externalScored"];
|
|
3221
|
-
const feedbackText = () => {
|
|
3222
|
-
if (completionStatus !== "completed") {
|
|
3223
|
-
return this.dataset.textNoResponse;
|
|
3224
|
-
}
|
|
3225
|
-
if (!externalScored && score !== void 0 && !Number.isNaN(score)) {
|
|
3226
|
-
return score > 0 ? this.dataset.textCorrect : this.dataset.textIncorrect;
|
|
3227
|
-
}
|
|
3228
|
-
if (externalScored === "externalMachine") {
|
|
3229
|
-
return Number.isNaN(score) || score === void 0 ? this.dataset.scoreUnknown : `We hebben je antwoord ${score === 0 ? "geen punten" : score == 1 ? "\xE9\xE9n punt" : `${score} punten`} gegeven. Je kunt je score zelf aanpassen als je denkt dat dat niet klopt.`;
|
|
3230
|
-
}
|
|
3231
|
-
if (externalScored === "human") {
|
|
3232
|
-
return Number.isNaN(score) ? "" : "Deze score heb je zelf toegekend.";
|
|
3233
|
-
}
|
|
3234
|
-
return this.dataset.inProgress;
|
|
3235
|
-
};
|
|
3236
|
-
return x`<div>${feedbackText()}</div>`;
|
|
3237
|
-
}
|
|
3238
|
-
};
|
|
3239
|
-
__decorateClass([
|
|
3240
|
-
c({ context: computedContext, subscribe: true })
|
|
3241
|
-
], TestScoringFeedback.prototype, "computedContext", 2);
|
|
3242
|
-
__decorateClass([
|
|
3243
|
-
n({ type: String, attribute: "view" })
|
|
3244
|
-
], TestScoringFeedback.prototype, "view", 2);
|
|
3245
|
-
TestScoringFeedback = __decorateClass([
|
|
3246
|
-
t("test-scoring-feedback")
|
|
3247
|
-
], TestScoringFeedback);
|
|
3248
|
-
|
|
3249
|
-
// ../qti-test/src/components/test-check-item/test-check-item.ts
|
|
3250
|
-
var TestCheckItem = class extends i2 {
|
|
3251
|
-
constructor() {
|
|
3252
|
-
super();
|
|
3253
|
-
this.addEventListener("click", () => {
|
|
3254
|
-
this.dispatchEvent(new CustomEvent("test-end-attempt", { bubbles: true }));
|
|
3255
|
-
this.dispatchEvent(
|
|
3256
|
-
new CustomEvent("test-show-correct-response", {
|
|
3257
|
-
detail: true,
|
|
3258
|
-
bubbles: true
|
|
3259
|
-
})
|
|
3260
|
-
);
|
|
3261
|
-
const qtiTest = this.closest("qti-test");
|
|
3262
|
-
const testContainer = qtiTest.querySelector("test-container");
|
|
3263
|
-
const viewElements = Array.from(testContainer.shadowRoot.querySelectorAll("[view]"));
|
|
3264
|
-
viewElements.forEach((element) => {
|
|
3265
|
-
element.classList.toggle("show", true);
|
|
3266
|
-
});
|
|
3267
|
-
});
|
|
3268
|
-
}
|
|
3269
|
-
render() {
|
|
3270
|
-
return x` <slot></slot> `;
|
|
3271
|
-
}
|
|
3272
|
-
};
|
|
3273
|
-
TestCheckItem.styles = i`
|
|
3274
|
-
:host {
|
|
3275
|
-
${btn};
|
|
3276
|
-
}
|
|
3277
|
-
:host([disabled]) {
|
|
3278
|
-
${dis};
|
|
3279
|
-
}
|
|
3280
|
-
`;
|
|
3281
|
-
TestCheckItem = __decorateClass([
|
|
3282
|
-
t("test-check-item")
|
|
3283
|
-
], TestCheckItem);
|
|
3284
|
-
|
|
3285
|
-
export {
|
|
3286
|
-
QtiTest,
|
|
3287
|
-
QtiAssessmentItemRef,
|
|
3288
|
-
QtiAssessmentSection,
|
|
3289
|
-
QtiAssessmentTest,
|
|
3290
|
-
QtiTestPart,
|
|
3291
|
-
QtiTestFeedback,
|
|
3292
|
-
TestNavigation,
|
|
3293
|
-
TestNext,
|
|
3294
|
-
TestPrev,
|
|
3295
|
-
TestView,
|
|
3296
|
-
TestItemLink,
|
|
3297
|
-
TestEndAttempt,
|
|
3298
|
-
TestShowCorrectResponse,
|
|
3299
|
-
TestPagingButtonsStamp,
|
|
3300
|
-
TestContainer,
|
|
3301
|
-
TestPrintVariables,
|
|
3302
|
-
TestSectionButtonsStamp,
|
|
3303
|
-
TestSectionLink,
|
|
3304
|
-
TestPrintContext,
|
|
3305
|
-
TestStamp,
|
|
3306
|
-
TestScoringButtons,
|
|
3307
|
-
TestViewToggle,
|
|
3308
|
-
TestScoringFeedback,
|
|
3309
|
-
TestCheckItem
|
|
3310
|
-
};
|
|
3311
|
-
/*! Bundled license information:
|
|
3312
|
-
|
|
3313
|
-
@heximal/expressions/lib/constants.js:
|
|
3314
|
-
@heximal/expressions/lib/tokenizer.js:
|
|
3315
|
-
@heximal/expressions/lib/parser.js:
|
|
3316
|
-
@heximal/expressions/lib/ast_factory.js:
|
|
3317
|
-
@heximal/expressions/lib/eval.js:
|
|
3318
|
-
(*
|
|
3319
|
-
* @license
|
|
3320
|
-
* Portions Copyright (c) 2013, the Dart project authors.
|
|
3321
|
-
*)
|
|
3322
|
-
|
|
3323
|
-
lit-html/node/private-ssr-support.js:
|
|
3324
|
-
(**
|
|
3325
|
-
* @license
|
|
3326
|
-
* Copyright 2019 Google LLC
|
|
3327
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
3328
|
-
*)
|
|
3329
|
-
*/
|
|
3330
|
-
//# sourceMappingURL=chunk-352OTVTY.js.map
|