@lxpack/runtime 0.2.1 → 0.3.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/runtime.js CHANGED
@@ -1,31 +1,37 @@
1
- var M = Object.defineProperty;
2
- var T = (t, s, e) => s in t ? M(t, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[s] = e;
3
- var a = (t, s, e) => T(t, typeof s != "symbol" ? s + "" : s, e);
4
- import { p as f, d as F, s as I } from "./scorm12-DpGWvsHb.js";
5
- import { S as Q, a as W, b as Y, c as Z, f as ss, i as es, t as ts } from "./scorm12-DpGWvsHb.js";
6
- import { createScorm2004Connection as N } from "./scorm2004.js";
7
- const x = "v:";
8
- function g(t) {
9
- return `${x}${t}`;
10
- }
11
- function y(t, s) {
1
+ var V = Object.defineProperty;
2
+ var M = (t, s, e) => s in t ? V(t, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[s] = e;
3
+ var a = (t, s, e) => M(t, typeof s != "symbol" ? s + "" : s, e);
4
+ import { p as P, s as U } from "./size-policy-DIyTdXTZ.js";
5
+ import { S as ks } from "./size-policy-DIyTdXTZ.js";
6
+ import { createScormConnection as F, installScormAPI as B } from "./scorm12.js";
7
+ import { Scorm12API as $s, Scorm12Adapter as Rs, Scorm12Simulator as Vs, findLmsApi as Ms, trimSuspendData as Us } from "./scorm12.js";
8
+ import { createScorm2004Connection as j, installScorm2004API as O } from "./scorm2004.js";
9
+ import { enumerateActivities as q } from "@lxpack/validators";
10
+ const G = "v:";
11
+ function C(t) {
12
+ return `${G}${t}`;
13
+ }
14
+ function x(t, s) {
12
15
  for (const [e, n] of Object.entries(t.variables ?? {})) {
13
- const i = g(e);
16
+ const i = C(e);
14
17
  s[i] === void 0 && (s[i] = n.default);
15
18
  }
16
19
  }
17
- function _(t, s) {
18
- return t[g(s)];
20
+ function T(t, s) {
21
+ return t[C(s)];
19
22
  }
20
- function $(t, s, e) {
21
- t[g(s)] = e;
23
+ function X(t, s, e) {
24
+ t[C(s)] = e;
25
+ }
26
+ function z(t, s, e) {
27
+ return e === "number" ? Number(t) === Number(s) : e === "boolean" ? !!t == !!s : e === "string" ? String(t) === String(s) : t === s;
22
28
  }
23
- const R = [
29
+ const J = [
24
30
  (t, s) => {
25
- var e;
31
+ var e, n;
26
32
  if ("variable" in t && ((e = t.variable) != null && e.eq)) {
27
- const [n, i] = t.variable.eq;
28
- return s.getVariable(n) === i;
33
+ const [i, o] = t.variable.eq, r = (n = s.getVariableType) == null ? void 0 : n.call(s, i);
34
+ return z(s.getVariable(i), o, r);
29
35
  }
30
36
  return null;
31
37
  },
@@ -37,26 +43,29 @@ const R = [
37
43
  var e;
38
44
  return "interaction" in t && ((e = t.interaction) != null && e.done) ? s.isInteractionDone(t.interaction.done) : null;
39
45
  },
40
- (t, s) => "all" in t && t.all ? t.all.every((e) => d(e, s)) : null,
41
- (t, s) => "any" in t && t.any ? t.any.some((e) => d(e, s)) : null
46
+ (t, s) => "all" in t && t.all ? t.all.every((e) => v(e, s)) : null,
47
+ (t, s) => "any" in t && t.any ? t.any.some((e) => v(e, s)) : null
42
48
  ];
43
- function d(t, s) {
44
- for (const e of R) {
49
+ function v(t, s) {
50
+ for (const e of J) {
45
51
  const n = e(t, s);
46
52
  if (n !== null)
47
53
  return n;
48
54
  }
49
55
  return !1;
50
56
  }
51
- function k(t, s) {
57
+ function K(t, s) {
52
58
  const e = t.flow;
53
59
  if (!(e != null && e.length)) return null;
54
60
  for (const n of e)
55
- if (d(n.when, s))
61
+ if (v(n.when, s))
56
62
  return n.goto;
57
63
  return null;
58
64
  }
59
- class G {
65
+ const W = {
66
+ maxAttempts: 1
67
+ };
68
+ class D {
60
69
  constructor(s) {
61
70
  this.connection = s;
62
71
  }
@@ -66,8 +75,8 @@ class G {
66
75
  restoreProgress(s) {
67
76
  const e = this.connection.LMSGetValue("cmi.suspend_data");
68
77
  if (e) {
69
- const { progress: i, parsed: c } = f(e, s);
70
- if (c) return i;
78
+ const { progress: i, parsed: o } = P(e, s);
79
+ if (o) return i;
71
80
  const r = this.connection.LMSGetValue("cmi.core.lesson_location");
72
81
  return r ? { ...s, currentLessonId: r } : s;
73
82
  }
@@ -89,7 +98,7 @@ class G {
89
98
  this.connection.LMSFinish();
90
99
  }
91
100
  }
92
- class B {
101
+ class k {
93
102
  constructor(s) {
94
103
  this.connection = s;
95
104
  }
@@ -99,8 +108,8 @@ class B {
99
108
  restoreProgress(s) {
100
109
  const e = this.connection.GetValue("cmi.suspend_data");
101
110
  if (e) {
102
- const { progress: i, parsed: c } = f(e, s);
103
- if (c) return i;
111
+ const { progress: i, parsed: o } = P(e, s);
112
+ if (o) return i;
104
113
  const r = this.connection.GetValue("cmi.location");
105
114
  return r ? { ...s, currentLessonId: r } : s;
106
115
  }
@@ -120,7 +129,7 @@ class B {
120
129
  this.connection.Terminate();
121
130
  }
122
131
  }
123
- class D {
132
+ class L {
124
133
  constructor(s) {
125
134
  this.storageKey = s;
126
135
  }
@@ -130,7 +139,7 @@ class D {
130
139
  try {
131
140
  const e = localStorage.getItem(this.storageKey);
132
141
  if (e) {
133
- const { progress: n, parsed: i } = f(e, s);
142
+ const { progress: n, parsed: i } = P(e, s);
134
143
  if (i) return n;
135
144
  }
136
145
  } catch {
@@ -150,25 +159,26 @@ class D {
150
159
  terminate() {
151
160
  }
152
161
  }
153
- function K(t, s) {
162
+ function H(t, s) {
154
163
  const e = `${t}::${s}`;
155
164
  let n = 0;
156
165
  for (let i = 0; i < e.length; i++)
157
166
  n = (n << 5) - n + e.charCodeAt(i), n |= 0;
158
167
  return `lxpack_progress_${Math.abs(n)}`;
159
168
  }
160
- function z(t, s) {
161
- return t === "scorm12" ? new G(F("scorm12")) : t === "scorm2004" ? new B(N("scorm2004")) : t === "preview" || t === "standalone" ? new D(s) : new D(s);
169
+ function Q(t, s, e = "local") {
170
+ return t === "scorm12" ? new D(F("scorm12")) : t === "scorm2004" ? new k(j("scorm2004")) : t === "preview" ? e === "scorm12" ? new D(B("preview")) : e === "scorm2004" ? new k(O("preview")) : new L(s) : t === "standalone" || t === "xapi" || t === "cmi5" ? new L(s) : new L(s);
162
171
  }
163
- function S(t, s) {
172
+ function w(t, s) {
164
173
  const e = t[`assessment_attempts_${s}`];
165
- return typeof e == "number" ? e : typeof e == "string" && e !== "" && !Number.isNaN(Number(e)) ? Number(e) : 0;
174
+ let n = 0;
175
+ return typeof e == "number" ? n = e : typeof e == "string" && e !== "" && !Number.isNaN(Number(e)) && (n = Number(e)), !Number.isFinite(n) || n < 0 ? 0 : Math.floor(n);
166
176
  }
167
- function O(t, s) {
168
- const e = S(t, s) + 1;
177
+ function Y(t, s) {
178
+ const e = w(t, s) + 1;
169
179
  return t[`assessment_attempts_${s}`] = e, e;
170
180
  }
171
- class j {
181
+ class Z {
172
182
  constructor(s, e, n) {
173
183
  a(this, "progress");
174
184
  a(this, "passedAssessments", /* @__PURE__ */ new Set());
@@ -187,10 +197,10 @@ class j {
187
197
  this.progress.assessmentScores[s] = e, this.progress.suspendData[`assessment_passing_${s}`] = n, e >= n ? this.passedAssessments.add(s) : this.passedAssessments.delete(s);
188
198
  }
189
199
  recordAssessmentAttempt(s) {
190
- return O(this.progress.suspendData, s);
200
+ return Y(this.progress.suspendData, s);
191
201
  }
192
202
  getAssessmentAttemptCount(s) {
193
- return S(this.progress.suspendData, s);
203
+ return w(this.progress.suspendData, s);
194
204
  }
195
205
  completeLesson(s) {
196
206
  new Set(this.manifest.lessons.map((n) => n.id)).has(s) && (this.progress.completedLessons.includes(s) || this.progress.completedLessons.push(s));
@@ -208,60 +218,367 @@ class j {
208
218
  return this.getAssessmentPassingScore(s);
209
219
  }
210
220
  }
211
- function w(t, s) {
212
- var A, L, C, P;
213
- const { manifest: e, completionThreshold: n, passedAssessments: i } = s, c = e.lessons.length, r = ((A = e.assessments) == null ? void 0 : A.length) ?? 0, l = c + r, m = t.completedLessons.filter(
214
- (o) => e.lessons.some((p) => p.id === o)
215
- ).length, u = l === 0 ? 0 : (m + i.size) / l, h = e.lessons.every(
216
- (o) => t.completedLessons.includes(o.id)
217
- ), V = !((L = e.assessments) != null && L.length) || e.assessments.every((o) => i.has(o.id)), v = (C = e.assessments) == null ? void 0 : C.some((o) => {
218
- var b;
219
- if (!(o.id in t.assessmentScores) || i.has(o.id)) return !1;
220
- const p = ((b = s.assessmentConfigs[o.id]) == null ? void 0 : b.maxAttempts) ?? 1;
221
- return S(t.suspendData, o.id) >= p;
221
+ function N(t, s) {
222
+ var h, d, _, E;
223
+ const { manifest: e, completionThreshold: n, passedAssessments: i } = s, o = e.lessons.length, r = ((h = e.assessments) == null ? void 0 : h.length) ?? 0, l = o + r, c = t.completedLessons.filter(
224
+ (p) => e.lessons.some((b) => b.id === p)
225
+ ).length, m = l === 0 ? 0 : (c + i.size) / l, g = e.lessons.every(
226
+ (p) => t.completedLessons.includes(p.id)
227
+ ), y = !((d = e.assessments) != null && d.length) || e.assessments.every((p) => i.has(p.id)), u = (_ = e.assessments) == null ? void 0 : _.some((p) => {
228
+ var I;
229
+ if (!(p.id in t.assessmentScores) || i.has(p.id)) return !1;
230
+ const b = ((I = s.assessmentConfigs[p.id]) == null ? void 0 : I.maxAttempts) ?? 1;
231
+ return w(t.suspendData, p.id) >= b;
222
232
  });
223
233
  return {
224
- ratio: u,
225
- scorePercent: Math.round(u * 100),
226
- allLessonsComplete: h,
227
- allAssessmentsPassed: V,
228
- anyAssessmentFailed: !!v,
229
- hasAssessments: (((P = e.assessments) == null ? void 0 : P.length) ?? 0) > 0,
234
+ ratio: m,
235
+ scorePercent: Math.round(m * 100),
236
+ allLessonsComplete: g,
237
+ allAssessmentsPassed: y,
238
+ anyAssessmentFailed: !!u,
239
+ hasAssessments: (((E = e.assessments) == null ? void 0 : E.length) ?? 0) > 0,
230
240
  completionThreshold: n
231
241
  };
232
242
  }
233
- class X {
243
+ class ss {
244
+ onLaunched() {
245
+ }
246
+ onExperienced(s) {
247
+ }
248
+ onInteraction(s, e) {
249
+ }
250
+ onAssessmentSubmitted(s, e, n) {
251
+ }
252
+ onLessonCompleted(s) {
253
+ }
254
+ onTerminated() {
255
+ }
256
+ }
257
+ var f = "http://adlnet.gov/expapi/verbs", es = {
258
+ id: `${f}/launched`,
259
+ display: { "en-US": "launched" }
260
+ }, ts = {
261
+ id: `${f}/experienced`,
262
+ display: { "en-US": "experienced" }
263
+ }, ns = {
264
+ id: `${f}/answered`,
265
+ display: { "en-US": "answered" }
266
+ }, is = {
267
+ id: `${f}/completed`,
268
+ display: { "en-US": "completed" }
269
+ }, os = {
270
+ id: `${f}/passed`,
271
+ display: { "en-US": "passed" }
272
+ }, rs = {
273
+ id: `${f}/failed`,
274
+ display: { "en-US": "failed" }
275
+ }, as = {
276
+ id: `${f}/interacted`,
277
+ display: { "en-US": "interacted" }
278
+ };
279
+ function cs(t, s) {
280
+ return `${t.replace(/\/$/, "")}/activities/${s}`;
281
+ }
282
+ function R(t, s) {
283
+ return {
284
+ objectType: "Activity",
285
+ id: t,
286
+ definition: {
287
+ name: { "en-US": s },
288
+ type: "http://adlnet.gov/expapi/activities/course"
289
+ }
290
+ };
291
+ }
292
+ function A(t, s) {
293
+ const e = s.kind === "assessment" ? "http://adlnet.gov/expapi/activities/assessment" : "http://adlnet.gov/expapi/activities/module";
294
+ return {
295
+ objectType: "Activity",
296
+ id: cs(t, s.id),
297
+ definition: {
298
+ name: { "en-US": s.title },
299
+ type: e
300
+ }
301
+ };
302
+ }
303
+ function ls() {
304
+ return typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : `urn:uuid:${Date.now()}-${Math.random().toString(16).slice(2)}`;
305
+ }
306
+ function S(t, s, e, n) {
307
+ const i = {
308
+ registration: t.registration,
309
+ contextActivities: {
310
+ parent: [R(t.courseIri, t.courseTitle)]
311
+ },
312
+ ...n == null ? void 0 : n.context
313
+ };
314
+ return {
315
+ id: ls(),
316
+ actor: t.actor,
317
+ verb: s,
318
+ object: e,
319
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
320
+ ...n,
321
+ context: i
322
+ };
323
+ }
324
+ function us(t) {
325
+ return S(
326
+ t,
327
+ es,
328
+ R(t.courseIri, t.courseTitle)
329
+ );
330
+ }
331
+ function ms(t, s) {
332
+ return S(t, ts, A(t.courseIri, s));
333
+ }
334
+ function ps(t, s) {
335
+ return S(t, is, A(t.courseIri, s), {
336
+ result: { completion: !0 }
337
+ });
338
+ }
339
+ function hs(t, s, e, n) {
340
+ return S(t, ns, A(t.courseIri, s), {
341
+ result: {
342
+ score: { scaled: Math.max(0, Math.min(1, e)) },
343
+ success: n,
344
+ completion: !0
345
+ }
346
+ });
347
+ }
348
+ function ds(t, s, e) {
349
+ return S(
350
+ t,
351
+ e ? os : rs,
352
+ A(t.courseIri, s),
353
+ { result: { success: e, completion: !0 } }
354
+ );
355
+ }
356
+ function $(t, s, e) {
357
+ const n = {
358
+ id: s,
359
+ title: s,
360
+ kind: "lesson"
361
+ }, i = {};
362
+ if ((e == null ? void 0 : e.simulation) != null && typeof e.simulation == "object")
363
+ i["https://lxpack.dev/xapi/extensions/simulation"] = e.simulation;
364
+ else if (e != null)
365
+ for (const [o, r] of Object.entries(e))
366
+ o !== "type" && o !== "simulation" && (i[o] = r);
367
+ return S(t, as, A(t.courseIri, n), {
368
+ result: Object.keys(i).length ? { extensions: i } : void 0
369
+ });
370
+ }
371
+ function fs(t) {
372
+ try {
373
+ const s = decodeURIComponent(t), e = JSON.parse(s);
374
+ if (e && typeof e == "object") return e;
375
+ } catch {
376
+ try {
377
+ const s = atob(t.replace(/-/g, "+").replace(/_/g, "/")), e = JSON.parse(s);
378
+ if (e && typeof e == "object") return e;
379
+ } catch {
380
+ return;
381
+ }
382
+ }
383
+ }
384
+ function gs(t, s = "") {
385
+ const e = new URLSearchParams(t || s.replace(/^#/, "")), n = e.get("endpoint") ?? void 0, i = e.get("auth") ?? void 0, o = e.get("registration") ?? void 0, r = e.get("activityId") ?? void 0, l = e.get("fetch") ?? void 0;
386
+ let c;
387
+ const m = e.get("actor");
388
+ return m && (c = fs(m)), {
389
+ endpoint: n ?? void 0,
390
+ auth: i ?? void 0,
391
+ actor: c,
392
+ registration: o ?? void 0,
393
+ activityId: r ?? void 0,
394
+ fetch: l ?? void 0
395
+ };
396
+ }
397
+ function Ss() {
398
+ const t = globalThis.location;
399
+ return t ? gs(t.search, t.hash) : {};
400
+ }
401
+ function As() {
402
+ return {
403
+ objectType: "Agent",
404
+ name: "LXPack Preview Learner",
405
+ mbox: "mailto:preview@lxpack.local"
406
+ };
407
+ }
408
+ var ys = class {
409
+ constructor(t) {
410
+ a(this, "options");
411
+ a(this, "queue", []);
412
+ a(this, "flushing", !1);
413
+ this.options = t;
414
+ }
415
+ enqueue(t) {
416
+ var s, e, n;
417
+ (e = (s = this.options).onStatement) == null || e.call(s, t), !(this.options.mock || !((n = this.options.credentials) != null && n.endpoint)) && (this.queue.push(t), this.flush());
418
+ }
419
+ async flush() {
420
+ var s, e, n;
421
+ if (this.flushing || !((s = this.options.credentials) != null && s.endpoint)) return;
422
+ this.flushing = !0;
423
+ const t = bs(this.options.credentials.endpoint);
424
+ for (; this.queue.length > 0; ) {
425
+ const i = this.queue.shift();
426
+ try {
427
+ await Ls(t, this.options.credentials.auth, i);
428
+ } catch (o) {
429
+ this.queue.unshift(i), (n = (e = this.options).onError) == null || n.call(e, o, i);
430
+ break;
431
+ }
432
+ }
433
+ this.flushing = !1;
434
+ }
435
+ };
436
+ function bs(t) {
437
+ const s = t.replace(/\/$/, "");
438
+ return s.endsWith("/statements") ? s : `${s}/statements`;
439
+ }
440
+ async function Ls(t, s, e) {
441
+ const n = {
442
+ "Content-Type": "application/json",
443
+ "X-Experience-API-Version": "1.0.3"
444
+ };
445
+ s && (n.Authorization = s.startsWith("Basic ") ? s : `Basic ${s}`);
446
+ const i = await fetch(t, {
447
+ method: "POST",
448
+ headers: n,
449
+ body: JSON.stringify(e)
450
+ });
451
+ if (!i.ok)
452
+ throw new Error(`LRS returned ${i.status}: ${await i.text()}`);
453
+ }
454
+ class vs {
455
+ constructor(s, e, n) {
456
+ a(this, "session");
457
+ a(this, "activities");
458
+ a(this, "queue");
459
+ a(this, "options");
460
+ a(this, "lastExperienced");
461
+ var r, l;
462
+ this.options = n;
463
+ const i = globalThis.location != null ? Ss() : {}, o = i.actor ?? As();
464
+ i.fetch && console.warn(
465
+ "[lxpack cmi5] Launch fetch URL is present but cmi5 session bootstrap via fetch is not implemented in v0.3.0"
466
+ ), this.session = {
467
+ actor: o,
468
+ registration: i.registration,
469
+ courseIri: e,
470
+ courseTitle: ((l = (r = s.tracking) == null ? void 0 : r.xapi) == null ? void 0 : l.displayName) ?? s.title
471
+ }, this.activities = new Map(
472
+ q(s).map((c) => [c.id, c])
473
+ ), this.queue = new ys({
474
+ mock: (n == null ? void 0 : n.mockLrs) ?? !i.endpoint,
475
+ credentials: i.endpoint ? { endpoint: i.endpoint, auth: i.auth } : void 0,
476
+ onError: (c) => {
477
+ console.warn("[lxpack xAPI] LRS error:", c);
478
+ }
479
+ });
480
+ }
481
+ emit(s) {
482
+ var e, n;
483
+ (n = (e = this.options) == null ? void 0 : e.onStatement) == null || n.call(e, s), this.queue.enqueue(s);
484
+ }
485
+ onLaunched() {
486
+ this.emit(us(this.session));
487
+ }
488
+ onExperienced(s) {
489
+ if (this.lastExperienced === s) return;
490
+ this.lastExperienced = s;
491
+ const e = this.activities.get(s);
492
+ e && this.emit(ms(this.session, e));
493
+ }
494
+ onInteraction(s, e) {
495
+ if (((e == null ? void 0 : e.simulation) != null || typeof (e == null ? void 0 : e.type) == "string" && e.type === "simulation") && (e != null && e.simulation) && typeof e.simulation == "object") {
496
+ this.emit(
497
+ $(this.session, s, {
498
+ simulation: e.simulation
499
+ })
500
+ );
501
+ return;
502
+ }
503
+ this.emit($(this.session, s, e));
504
+ }
505
+ onAssessmentSubmitted(s, e, n) {
506
+ const i = this.activities.get(s);
507
+ i && (this.emit(hs(this.session, i, e, n)), this.emit(ds(this.session, i, n)));
508
+ }
509
+ onLessonCompleted(s) {
510
+ const e = this.activities.get(s);
511
+ e && this.emit(ps(this.session, e));
512
+ }
513
+ onTerminated() {
514
+ this.queue.flush();
515
+ }
516
+ }
517
+ function Ps(t) {
518
+ var l, c, m, g, y;
519
+ const s = t.activityIri ?? ((c = (l = t.manifest.tracking) == null ? void 0 : l.xapi) == null ? void 0 : c.activityIri);
520
+ if (!(t.mode === "xapi" || t.mode === "cmi5" || t.mode === "preview" && !!((m = t.xapi) != null && m.previewLog && s)) || !s)
521
+ return new ss();
522
+ const i = ((g = t.xapi) == null ? void 0 : g.previewLog) ?? t.mode === "preview" ? (u) => {
523
+ if (typeof console < "u" && console.debug && console.debug("[lxpack xAPI]", u.verb.id, u.object.id), typeof localStorage < "u")
524
+ try {
525
+ const h = "lxpack_xapi_preview_statements", d = JSON.parse(localStorage.getItem(h) ?? "[]");
526
+ d.push(u), localStorage.setItem(h, JSON.stringify(d.slice(-200)));
527
+ } catch {
528
+ }
529
+ } : void 0, o = new vs(t.manifest, s, {
530
+ mockLrs: ((y = t.xapi) == null ? void 0 : y.mockLrs) ?? t.mode === "preview",
531
+ onStatement: i
532
+ });
533
+ let r = !1;
534
+ return {
535
+ onLaunched: () => {
536
+ r || (r = !0, o.onLaunched());
537
+ },
538
+ onExperienced: (u) => o.onExperienced(u),
539
+ onInteraction: (u, h) => o.onInteraction(u, h),
540
+ onAssessmentSubmitted: (u, h, d) => o.onAssessmentSubmitted(u, h, d),
541
+ onLessonCompleted: (u) => o.onLessonCompleted(u),
542
+ onTerminated: () => o.onTerminated()
543
+ };
544
+ }
545
+ class xs {
234
546
  constructor(s) {
235
547
  a(this, "manifest");
236
548
  a(this, "state");
237
549
  a(this, "bridge");
550
+ a(this, "analytics");
238
551
  a(this, "completionThreshold");
239
552
  a(this, "assessmentConfigs");
240
553
  a(this, "defaultPassingScores");
241
554
  a(this, "terminated", !1);
242
- var r, l, m;
555
+ var r, l, c;
243
556
  this.manifest = s.manifest, this.completionThreshold = ((l = (r = s.manifest.tracking) == null ? void 0 : r.completion) == null ? void 0 : l.threshold) ?? 0.9;
244
- const e = K(
557
+ const e = H(
245
558
  s.manifest.title,
246
559
  s.manifest.version
247
560
  );
248
- this.bridge = z(s.mode, e), this.defaultPassingScores = {};
249
- for (const [u, h] of Object.entries(s.assessments ?? {}))
250
- this.defaultPassingScores[u] = h.passingScore;
561
+ this.bridge = Q(
562
+ s.mode,
563
+ e,
564
+ s.previewScormMode ?? "local"
565
+ ), this.analytics = Ps(s), this.defaultPassingScores = {};
566
+ for (const [m, g] of Object.entries(s.assessments ?? {}))
567
+ this.defaultPassingScores[m] = g.passingScore;
251
568
  this.assessmentConfigs = s.assessmentConfigs ?? {};
252
- const n = s.activityId ?? ((m = s.manifest.lessons[0]) == null ? void 0 : m.id) ?? "", i = s.progress ?? {
569
+ const n = s.activityId ?? ((c = s.manifest.lessons[0]) == null ? void 0 : c.id) ?? "", i = s.progress ?? {
253
570
  currentLessonId: n,
254
571
  completedLessons: [],
255
572
  assessmentScores: {},
256
573
  suspendData: {}
257
574
  };
258
- y(this.manifest, i.suspendData), this.bridge.init();
259
- const c = this.bridge.restoreProgress(i);
260
- this.state = new j(
261
- c,
575
+ x(this.manifest, i.suspendData), this.bridge.init();
576
+ const o = this.bridge.restoreProgress(i);
577
+ this.state = new Z(
578
+ o,
262
579
  this.manifest,
263
580
  this.defaultPassingScores
264
- ), y(this.manifest, this.state.progress.suspendData), this.state.syncPassedAssessments(), s.activityId && this.state.setCurrentLesson(s.activityId);
581
+ ), x(this.manifest, this.state.progress.suspendData), this.state.syncPassedAssessments(), s.activityId && this.state.setCurrentLesson(s.activityId), this.analytics.onLaunched(), this.analytics.onExperienced(this.state.progress.currentLessonId);
265
582
  }
266
583
  getAPI() {
267
584
  return {
@@ -269,18 +586,24 @@ class X {
269
586
  completeLesson: (s) => this.completeLesson(s),
270
587
  getProgress: () => this.getProgress(),
271
588
  setVariable: (s, e) => {
272
- this.manifest.variables && s in this.manifest.variables ? $(this.state.progress.suspendData, s, e) : this.state.progress.suspendData[s] = e, this.persist();
589
+ this.manifest.variables && s in this.manifest.variables ? X(this.state.progress.suspendData, s, e) : this.state.progress.suspendData[s] = e, this.persist();
273
590
  },
274
- getVariable: (s) => this.manifest.variables && s in this.manifest.variables ? _(this.state.progress.suspendData, s) : this.state.progress.suspendData[s],
591
+ getVariable: (s) => this.manifest.variables && s in this.manifest.variables ? T(this.state.progress.suspendData, s) : this.state.progress.suspendData[s],
275
592
  submitAssessment: (s, e, n) => this.submitAssessment(s, e, n)
276
593
  };
277
594
  }
278
595
  track(s, e) {
279
596
  var n, i;
280
- if (s.type === "interaction" && s.id && (this.state.progress.suspendData[`interaction_${s.id}`] = s.data ?? !0, console.debug("[lxpack] interaction:", s.id, s.data)), s.type === "assessment" && s.id) {
281
- const c = typeof ((n = s.data) == null ? void 0 : n.passingScore) == "number" ? Number(s.data.passingScore) : this.state.getAssessmentPassingScoreForTrack(s.id), r = ((i = s.data) == null ? void 0 : i.score) != null ? Number(s.data.score) : void 0;
597
+ if (s.type === "interaction" && s.id && (this.state.progress.suspendData[`interaction_${s.id}`] = s.data ?? !0, console.debug("[lxpack] interaction:", s.id, s.data), this.analytics.onInteraction(
598
+ s.id,
599
+ s.data
600
+ )), s.type === "simulation" && s.id && this.analytics.onInteraction(s.id, {
601
+ type: "simulation",
602
+ simulation: s.data ?? {}
603
+ }), s.type === "assessment" && s.id) {
604
+ const o = typeof ((n = s.data) == null ? void 0 : n.passingScore) == "number" ? Number(s.data.passingScore) : this.state.getAssessmentPassingScoreForTrack(s.id), r = ((i = s.data) == null ? void 0 : i.score) != null ? Number(s.data.score) : void 0;
282
605
  if (r != null && !Number.isNaN(r)) {
283
- this.state.applyAssessmentResult(s.id, r, c), (e == null ? void 0 : e.persist) !== !1 && (this.updateCompletion(), this.persist());
606
+ this.submitAssessment(s.id, r, o);
284
607
  return;
285
608
  }
286
609
  }
@@ -293,13 +616,27 @@ class X {
293
616
  return this.state.getAssessmentAttemptCount(s);
294
617
  }
295
618
  submitAssessment(s, e, n) {
296
- this.state.recordAssessmentAttempt(s), this.state.applyAssessmentResult(s, e, n), this.updateCompletion(), this.persist();
619
+ if (!this.canAcceptAssessmentSubmission(s))
620
+ return;
621
+ this.state.recordAssessmentAttempt(s), this.state.applyAssessmentResult(s, e, n);
622
+ const i = this.isAssessmentPassed(s);
623
+ this.analytics.onAssessmentSubmitted(s, e, i), this.updateCompletion(), this.persist();
624
+ }
625
+ getMaxAttempts(s) {
626
+ const e = this.assessmentConfigs[s];
627
+ return (e == null ? void 0 : e.maxAttempts) ?? W.maxAttempts;
628
+ }
629
+ canAcceptAssessmentSubmission(s) {
630
+ if (this.isAssessmentPassed(s))
631
+ return !1;
632
+ const e = this.getMaxAttempts(s);
633
+ return this.getAssessmentAttemptCount(s) < e;
297
634
  }
298
635
  completeLesson(s) {
299
- this.state.completeLesson(s), this.updateCompletion(), this.persist();
636
+ this.state.completeLesson(s), this.analytics.onLessonCompleted(s), this.updateCompletion(), this.persist();
300
637
  }
301
638
  setCurrentLesson(s) {
302
- this.state.setCurrentLesson(s), this.bridge.setLocation(s), this.persist();
639
+ this.state.setCurrentLesson(s), this.bridge.setLocation(s), this.analytics.onExperienced(s), this.persist();
303
640
  }
304
641
  getProgress() {
305
642
  const s = this.state.progress;
@@ -325,7 +662,7 @@ class X {
325
662
  return this.manifest.lessons.length + s;
326
663
  }
327
664
  getCompletionRatio() {
328
- return w(this.state.progress, {
665
+ return N(this.state.progress, {
329
666
  manifest: this.manifest,
330
667
  completionThreshold: this.completionThreshold,
331
668
  assessmentConfigs: this.assessmentConfigs,
@@ -334,7 +671,7 @@ class X {
334
671
  }).ratio;
335
672
  }
336
673
  updateCompletion() {
337
- const s = w(this.state.progress, {
674
+ const s = N(this.state.progress, {
338
675
  manifest: this.manifest,
339
676
  completionThreshold: this.completionThreshold,
340
677
  assessmentConfigs: this.assessmentConfigs,
@@ -344,31 +681,38 @@ class X {
344
681
  this.bridge.applyCompletion(s);
345
682
  }
346
683
  persist() {
347
- const s = I(this.state.progress);
684
+ const s = U(this.state.progress);
348
685
  this.bridge.persist(this.state.progress, s);
349
686
  }
350
687
  getFlowContext() {
351
688
  return {
352
- getVariable: (s) => _(this.state.progress.suspendData, s),
689
+ getVariable: (s) => T(this.state.progress.suspendData, s),
690
+ getVariableType: (s) => {
691
+ var e, n;
692
+ return (n = (e = this.manifest.variables) == null ? void 0 : e[s]) == null ? void 0 : n.type;
693
+ },
353
694
  isAssessmentPassed: (s) => this.isAssessmentPassed(s),
354
- isInteractionDone: (s) => this.state.progress.suspendData[`interaction_${s}`] !== void 0
695
+ isInteractionDone: (s) => {
696
+ const e = this.state.progress.suspendData[`interaction_${s}`];
697
+ return e !== void 0 && e !== !1 && e !== null;
698
+ }
355
699
  };
356
700
  }
357
701
  resolveFlowNavigation() {
358
- return k(this.manifest, this.getFlowContext());
702
+ return K(this.manifest, this.getFlowContext());
359
703
  }
360
704
  terminate() {
361
- this.terminated || (this.terminated = !0, this.bridge.terminate());
705
+ this.terminated || (this.terminated = !0, this.analytics.onTerminated(), this.bridge.terminate());
362
706
  }
363
707
  }
364
708
  export {
365
- X as LxpackRuntime,
366
- Q as SCORM_SUSPEND_DATA_MAX,
367
- W as Scorm12API,
368
- Y as Scorm12Adapter,
369
- Z as Scorm12Simulator,
709
+ xs as LxpackRuntime,
710
+ ks as SCORM_SUSPEND_DATA_MAX,
711
+ $s as Scorm12API,
712
+ Rs as Scorm12Adapter,
713
+ Vs as Scorm12Simulator,
370
714
  F as createScormConnection,
371
- ss as findLmsApi,
372
- es as installScormAPI,
373
- ts as trimSuspendData
715
+ Ms as findLmsApi,
716
+ B as installScormAPI,
717
+ Us as trimSuspendData
374
718
  };