@caspingus/lt
Version:
A utility library of helpers and extensions useful when working with Learnosity APIs.
664 lines (663 loc) • 16.3 kB
JavaScript
import { n as e } from "./chunk-BPfpcrXh.js";
import t from "./logger.js";
//#region src/assessment/core/questions.js
var n = /* @__PURE__ */ e({
hasCheckAnswer: () => r,
isAutoScorable: () => i,
question: () => a,
questionInstance: () => o,
questionResponse: () => s,
questionResponseIds: () => c,
questionScore: () => ee,
questions: () => l
});
function r(e) {
if (!i(e)) return !1;
let t = y()?.config?.questions_api_init_options?.attribute_overrides && y().config.questions_api_init_options.attribute_overrides.hasOwnProperty("instant_feedback") && typeof y().config.questions_api_init_options.attribute_overrides.instant_feedback == "boolean", n = a(e);
return t ? y().config.questions_api_init_options.attribute_overrides.instant_feedback : n.hasOwnProperty("instant_feedback") && typeof n.instant_feedback == "boolean" ? n.instant_feedback : !1;
}
function i(e) {
return o(e).checkValidation().has_validation;
}
function a(e) {
let n = e || c()[0];
return n ? W().question(n).getQuestion() : (t.error(`Question not found (index ${n})`), {});
}
function o(e) {
let t = e ?? c()[0];
return t && W().question(t) || null;
}
function s(e) {
let n = e || c()[0];
return n ? W().question(n) ? W().question(n).getResponse() : (t.error(`Response not found ${n}`), null) : null;
}
function c() {
return l().map((e) => e.response_id);
}
function l() {
return d().questions;
}
function ee(e) {
let t = e || c()[0];
return t && W().getScores()[t] || null;
}
//#endregion
//#region src/assessment/core/items.js
var te = /* @__PURE__ */ e({
dynamic: () => ne,
flag: () => re,
isDynamicItem: () => ie,
isFirstItem: () => ae,
isFlagged: () => oe,
isItemFullyAttempted: () => se,
isLastItem: () => u,
isMaskingEnabled: () => ce,
item: () => d,
itemAttemptStatus: () => le,
itemByResponseId: () => ue,
itemElement: () => de,
itemPosition: () => fe,
itemReference: () => f,
itemTags: () => pe
});
function ne() {
let e = f();
return K().item(e).dynamic || {};
}
function re() {
let e = f();
K().item(e).flag();
}
function ie() {
return d()?.source.hasOwnProperty("data_table_seed");
}
function ae() {
let e;
return A() ? (e = typeof g()[0].items[0] == "object" ? g()[0].items[0].reference : g()[0].items[0], e === d().reference) : (e = typeof y().items[0] == "object" ? y().items[0].reference : y().items[0], e === d().reference);
}
function u() {
return d().is_last_item;
}
function oe() {
return d().user_flagged;
}
function se(e = void 0) {
let t, n, r;
if (t = e ? W().getItems()[e].questions : l(), Array.isArray(t) && t.length) for (let e = 0; e < t.length; e++) {
let i = t[e];
if (r = s(i.response_id), r) {
if (i.hasOwnProperty("metadata") && i.metadata.hasOwnProperty("valid_response_count") && Array.isArray(r.value) && (r.value.filter((e) => e === void 0).length || r.value.filter((e) => e === null).length)) return !1;
n = !0;
} else return !1;
}
else n = !0;
return n;
}
function ce() {
return !!document.querySelector(".lrn-masking");
}
function d(e = void 0) {
return e ? W().getItems()[e] || null : W().getCurrentItem();
}
function le() {
return W().getCurrentItem().attempt_status;
}
function ue(e) {
let t = W().getItems(), n = null;
for (let r in t) if (t[r].response_ids.includes(e)) {
n = t[r];
break;
}
return n;
}
function de() {
return document.querySelector(`div[data-reference='${f()}']`);
}
function fe() {
return W().assessApp().getItemPosition(f()) + 1;
}
function f() {
return W().getCurrentItem()?.reference;
}
function pe(e = void 0) {
return W().getTags()[e || f()] || [];
}
//#endregion
//#region src/assessment/core/sections.js
var p = /* @__PURE__ */ e({
isFirstItemInSection: () => me,
isLastItemInSection: () => he,
section: () => m,
sectionHasShuffledItems: () => ge,
sectionIndex: () => _e,
sectionItemPosition: () => h,
sections: () => g,
totalItemsInSection: () => _
});
function me() {
return h() === 1;
}
function he() {
return h() === _();
}
function m() {
if (!A()) return {};
let e = f(), t = g(), n = -1, r = !1;
for (let i = 0; i < t.length && !r; i++) {
++n;
for (let n = 0; n < t[i].items.length; n++) if (e === t[i].items[n]) {
r = !0;
break;
}
}
return g()[n];
}
function ge() {
return !!m()?.config?.configuration?.shuffle_items;
}
function _e() {
if (!A()) return 0;
let e = f(), t = g(), n = 0, r = !1;
for (let i = 0; i < t.length && !r; i++) {
++n;
for (let n = 0; n < t[i].items.length; n++) if (e === t[i].items[n]) {
r = !0;
break;
}
}
return r && n || 0;
}
function h() {
let e = f(), t = m(), n = 0;
if (!Object.keys(t).length) return -1;
for (let r = 0; r < t.items.length && (++n, e !== t.items[r]); r++);
return n;
}
function g() {
return y()?.sections ?? [];
}
function _() {
return m()?.items?.length || -1;
}
//#endregion
//#region src/assessment/core/activity.js
var ve = /* @__PURE__ */ e({
activity: () => y,
activityId: () => b,
activitySubTitle: () => ye,
activityTags: () => be,
activityTemplateId: () => x,
activityTitle: () => xe,
adaptiveType: () => Se,
annotationsConfig: () => S,
autoSaveConfig: () => C,
elapsedTime: () => w,
hasActivityTemplate: () => Ce,
hasAnnotations: () => T,
hasAnswerMasking: () => we,
hasAutoSave: () => E,
hasEvents: () => k,
hasItemPool: () => Te,
hasLineReader: () => Ee,
hasReadingMode: () => D,
hasResourceItems: () => De,
hasSections: () => A,
hasShuffledItems: () => O,
hasTryAgain: () => Oe,
isAdaptive: () => j,
isResuming: () => ke,
isVerticalLayout: () => Ae,
itemBank: () => M,
itemPool: () => N,
maxTime: () => P,
region: () => je,
resourceItems: () => Me,
sessionId: () => F,
state: () => I,
timeRemaining: () => Ne,
totalItems: () => Pe,
userId: () => L
}), v = {
activity: null,
maxTime: -1
};
function y() {
return v.activity === null && (v.activity = W().getActivity()), v.activity;
}
function b() {
return y().activity_id;
}
function ye() {
return y().config?.subtitle ?? null;
}
function be() {
return W().getTags() ?? [];
}
function x() {
return y()?.activity_template_id ?? null;
}
function xe() {
return y().config?.title ?? null;
}
function Se() {
return j() && y().adaptive.hasOwnProperty("type") ? y().adaptive.type : null;
}
function S() {
return T() && y()?.config?.annotations_api_init_options ? y().config.annotations_api_init_options : {};
}
function C() {
let e = y();
return e?.config?.navigation?.auto_save ? e.config.navigation.auto_save : {};
}
function w() {
return W().getTime();
}
function Ce() {
return y().hasOwnProperty("activity_template_id");
}
function T() {
let e = y();
return !!(e?.config?.annotations === !0 || e?.config?.annotations_api_init_options);
}
function we() {
return !!document.querySelector(".test-answer-masking");
}
function E() {
let e = y();
return e.hasOwnProperty("config") && e.config.hasOwnProperty("navigation") && e.config.navigation.hasOwnProperty("auto_save") && e.config.navigation.auto_save !== !1;
}
function D() {
return (y()?.config?.configuration?.reading_mode?.reading_time || 0) > 0;
}
function O() {
return !!y()?.config?.configuration?.shuffle_items;
}
function k() {
let e = y();
return e.hasOwnProperty("events") && e.events !== !1;
}
function Te() {
return y().hasOwnProperty("item_pool_id");
}
function Ee() {
return !!document.querySelector(".lrn_linereader-toggle");
}
function De() {
return !!y()?.config?.navigation?.resource_items;
}
function A() {
return y().hasOwnProperty("sections");
}
function Oe() {
return y()?.dynamic_items.hasOwnProperty("try_again");
}
function j() {
return y().hasOwnProperty("adaptive");
}
function ke() {
return y().existing_session;
}
function Ae() {
let e = y().config?.regions?.items;
return e ? e.some((e) => e.type === "vertical_element") : !1;
}
function M() {
return y()?.organisation_id ?? null;
}
function N() {
return y()?.item_pool_id ?? null;
}
function P() {
return v.maxTime === -1 && (v.maxTime = y()?.config?.time?.max_time ?? 0), v.maxTime;
}
function je() {
return y()?.config?.regions ?? null;
}
function Me() {
return y()?.config?.navigation?.resource_items ?? [];
}
function F() {
return y()?.session_id;
}
function I() {
let e;
switch (y()?.state) {
case void 0:
e = "initial";
break;
default:
e = y().state;
break;
}
return e;
}
function Ne() {
let e = P();
return e ? e - w() : null;
}
function Pe() {
if (A()) {
let e = 0, t = g();
for (let n = 0; n < t.length; n++) e += t[n].items.length;
return e;
} else if (j()) return y().hasOwnProperty("items") ? y().items.length : (t.info("This is an adaptive session, no items array found"), 0);
else return y().items.length;
}
function L() {
return y()?.user_id;
}
//#endregion
//#region src/assessment/core/diagnostics.js
var Fe = /* @__PURE__ */ e({
diagnostics: () => Ie,
extensionsListener: () => B,
filterEvent: () => Le,
handleEvent: () => z,
listen: () => Re
}), R = {
events: {
broadcast: !1,
listenFor: "item"
},
extensions: { running: [] },
initialised: !1
};
function Ie() {
let e = window.LearnosityApp ? LearnosityApp.versions : {};
return {
apps: {
annotations: {
app: G(),
config: S(),
enabled: T()
},
assess: { app: K() },
events: {
app: q(),
enabled: k()
},
items: {
app: W(),
metadata: y().config.metadata
},
questions: { app: J() }
},
activity: {
activity: b(),
activityTemplate: x(),
autoSave: {
config: C(),
enabled: E()
},
itemBank: M(),
itemPool: N(),
session: F(),
state: I(),
type: y().type,
user: L()
},
LT: {
extensions: R.extensions,
version: "3.0.3"
},
versions: e
};
}
function Le(e) {
/^[a-zA-Z:*]*$/.test(e) ? R.events.listenFor = e : t.warn("Invalid event type");
}
function z(e) {
if (R.events.broadcast) {
let n = R.events.listenFor, r = n.replaceAll("*", "");
n.length === 1 && n === "*" || n === "all" ? t.info(e) : n.startsWith("*") && !n.endsWith("*") ? e.endsWith(r) && t.info(e) : n.endsWith("*") && !n.startsWith("*") ? e.startsWith(r) && t.info(e) : n.startsWith("*") && n.endsWith("*") ? e.includes(r) && t.info(e) : e.startsWith(r) && t.info(e);
}
}
function Re(e = !0) {
R.events.broadcast = !!e, e ? t.info(`👂 listening for '${R.events.listenFor}'`) : t.info("🚫👂 not listening");
}
function B() {
R.initialised ||= (window.addEventListener("extension:run", (e) => {
let { name: t, timestamp: n } = e.detail;
R.extensions.running.push({
name: t,
timestamp: n
});
}), !0);
}
//#endregion
//#region src/utils/eventBus.js
var ze = [
"item:load",
"item:changed",
"test:start",
"test:reading:start"
], V = new class {
constructor() {
this.listeners = /* @__PURE__ */ new Map(), this.bufferedEvents = /* @__PURE__ */ new Map(), this.extensionsReady = !1;
}
on(e, n, r) {
if (this.listeners.has(e) || this.listeners.set(e, /* @__PURE__ */ new Set()), this.listeners.get(e).add(n), this.bufferedEvents.has(e)) {
let { args: i } = this.bufferedEvents.get(e), a = r ? ` (${r})` : "";
t.debug(`[EventBus] Replaying buffered "${e}" to new listener${a}`);
try {
n(...i);
} catch (n) {
t.error(`[EventBus] Error replaying "${e}"${a}`, n);
}
}
return () => this.off(e, n);
}
off(e, t) {
let n = this.listeners.get(e);
n && n.delete(t);
}
emit(e, ...n) {
ze.includes(e) && !this.bufferedEvents.has(e) && (this.bufferedEvents.set(e, {
args: n,
timestamp: Date.now()
}), t.debug(`[EventBus] Buffered first occurrence of "${e}"`));
let r = this.listeners.get(e);
r && r.size > 0 && r.forEach((r) => {
try {
r(...n);
} catch (n) {
t.error(`[EventBus] Error in listener for "${e}"`, n);
}
});
}
markReady() {
this.extensionsReady = !0, this.bufferedEvents.clear(), t.debug("[EventBus] Extensions ready, buffer cleared");
}
hasBuffered(e) {
return this.bufferedEvents.has(e);
}
listenerCount(e) {
let t = this.listeners.get(e);
return t ? t.size : 0;
}
}(), Be = /* @__PURE__ */ e({
annotationsApp: () => G,
assessApp: () => K,
eventsApp: () => q,
itemsApp: () => W,
questionsApp: () => J,
setup: () => U
}), H = {}, Ve = [
"item:load",
"item:changed",
"test:start",
"test:reading:start",
"test:reading:end",
"unfocused",
"focused",
"item:warningOnChange",
"items:fetch:done",
"section:changed",
"test:panel:show",
"test:panel:shown",
"test:pause",
"test:resume",
"test:save",
"test:save:success",
"test:save:error",
"test:submit",
"test:submit:success",
"test:submit:error",
"test:finished:save",
"test:finished:submit",
"test:finished:discard",
"time:end",
"item:beforeunload"
];
function U(e) {
H.app = e, He(e), Ue();
}
function He(e) {
Ve.forEach((t) => {
e.on(t, (...e) => {
V.emit(t, ...e);
});
});
}
function W() {
return H.app;
}
function G() {
return W().annotationsApp() === void 0 ? null : W().annotationsApp();
}
function K() {
return W().assessApp();
}
function q() {
return W().eventsApp();
}
function J() {
return W().questionsApp();
}
function Ue() {
H.app.on("all", (e) => {
z(e);
}), H.app.on("item:load", () => {
c().forEach((e) => {
let t = H.app.question(e);
[
"changed",
"beforeValidate",
"rendered",
"validated"
].forEach((e) => {
t.on(e, () => z(e));
});
});
}), B();
}
//#endregion
//#region src/assessment/core/player.js
var We = /* @__PURE__ */ e({
answerMasking: () => Ge,
dialog: () => Ke,
hideDialog: () => qe,
isFullscreen: () => X,
isIntroScreen: () => Z,
isReadingMode: () => Q,
isResponsiveMode: () => Je,
isReviewScreen: () => Ye,
lineReader: () => Xe,
navigate: () => $,
next: () => Ze,
previous: () => Qe,
review: () => $e,
submit: () => et
}), Y = {
answerMasking: { enabled: null },
lineReader: {
enabled: null,
id: null
}
};
function Ge(e) {
Y.answerMasking.enabled === null && (document.querySelector(".test-answer-masking") ? Y.answerMasking.enabled = !0 : Y.answerMasking.enabled = !1), Y.answerMasking.enabled ? e !== void 0 && W().questionsApp().masking(e) : t.warn("Answer masking is not enabled in the Items API configuration.");
}
function Ke(e) {
K().dialogs().custom.show(e);
}
function qe() {
K().dialogs().custom.hide();
}
function X() {
return document.querySelector(".lrn-assess")?.classList.contains("lrn-fullscreen") ?? !1;
}
function Z() {
return !K().hasStarted();
}
function Q() {
return !!(D() && w() === 0);
}
function Je() {
return !!document.querySelector(".has-menu-region");
}
function Ye() {
return document.getElementsByClassName("review-screen")[0].getAttribute("aria-hidden") === null;
}
function Xe(e) {
if (Y.lineReader.enabled === null) {
let e = document.querySelector(".lrn_linereader-toggle");
if (e) {
Y.lineReader.enabled = !0;
let n = e.querySelector("[data-lrn-widget-container]").getAttribute("data-lrn-widget-container").match(/\d+$/);
n ? Y.lineReader.id = n[0] : t.warn("Could not find the line reader unique id.");
} else Y.lineReader.enabled = !1;
}
if (Y.lineReader.enabled && Y.lineReader.id !== null) {
let t = W().features()[`lrn-assessapp-feature_${Y.lineReader.id}`];
switch (e) {
case "show":
t.show();
break;
case "hide":
t.hide();
break;
default: t.toggle();
}
} else t.warn("Line reader is not enabled in the Items API configuration.");
}
function $(e) {
switch (e) {
case "previous":
W().items().previous();
break;
case "next":
u() || W().items().next();
break;
case "review":
document.getElementsByClassName("review-screen")[0].getAttribute("aria-hidden") === null ? W().dialogs().reviewScreen.hide() : W().dialogs().reviewScreen.show();
break;
case "submit":
W().submit({
show_submit_confirmation: !0,
show_submit_ui: !0,
success: () => {
alert("Test saved!");
},
error: (e) => {
alert("Test submit failed...check browser log"), t.error("Submission failed: ", e);
}
});
break;
default: typeof Number(e) == "number" && Number(e) >= 0 ? W().items().goto(Number(e)) : t.warn(`Invalid target (${e})`);
}
}
function Ze() {
$("next");
}
function Qe() {
$("previous");
}
function $e() {
$("review");
}
function et() {
$("submit");
}
//#endregion
export { U as a, ve as c, n as d, Be as i, p as l, Q as n, V as o, We as r, Fe as s, Z as t, te as u };