@pie-element/multiple-choice 13.3.5-ng.0 → 13.3.6

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.
Files changed (133) hide show
  1. package/CHANGELOG.json +1972 -0
  2. package/CHANGELOG.md +2778 -0
  3. package/LICENSE.md +5 -0
  4. package/PRINT.md +35 -0
  5. package/README.md +56 -0
  6. package/choice.png +0 -0
  7. package/configure/CHANGELOG.json +1387 -0
  8. package/configure/CHANGELOG.md +2114 -0
  9. package/configure/lib/__tests__/root.test.js +279 -0
  10. package/configure/lib/defaults.js +203 -0
  11. package/configure/lib/defaults.js.map +1 -0
  12. package/configure/lib/index.js +203 -0
  13. package/configure/lib/index.js.map +1 -0
  14. package/configure/lib/main.js +484 -0
  15. package/configure/lib/main.js.map +1 -0
  16. package/configure/lib/utils.js +18 -0
  17. package/configure/lib/utils.js.map +1 -0
  18. package/configure/package.json +22 -0
  19. package/controller/CHANGELOG.json +527 -0
  20. package/controller/CHANGELOG.md +1423 -0
  21. package/controller/lib/__tests__/index.test.js +561 -0
  22. package/controller/lib/__tests__/utils.test.js +8 -0
  23. package/controller/lib/defaults.js +33 -0
  24. package/controller/lib/defaults.js.map +1 -0
  25. package/controller/lib/index.js +298 -0
  26. package/controller/lib/index.js.map +1 -0
  27. package/controller/lib/utils.js +15 -0
  28. package/controller/lib/utils.js.map +1 -0
  29. package/controller/package.json +15 -0
  30. package/docs/config-schema.json +2993 -0
  31. package/docs/config-schema.json.md +2217 -0
  32. package/docs/demo/config.js +8 -0
  33. package/docs/demo/generate.js +61 -0
  34. package/docs/demo/index.html +1 -0
  35. package/docs/demo/pie.manifest.json +11 -0
  36. package/docs/demo/session.js +7 -0
  37. package/docs/pie-schema.json +1332 -0
  38. package/docs/pie-schema.json.md +1015 -0
  39. package/lib/__tests__/choice-input-test.js +49 -0
  40. package/lib/__tests__/choice-input.test.js +49 -0
  41. package/lib/__tests__/index-test.js +206 -0
  42. package/lib/__tests__/index.test.js +221 -0
  43. package/lib/__tests__/key-events-test.js +95 -0
  44. package/lib/__tests__/key-events.test.js +107 -0
  45. package/lib/__tests__/multiple-choice-test.js +101 -0
  46. package/lib/__tests__/multiple-choice.test.js +256 -0
  47. package/lib/__tests__/session-updater-test.js +70 -0
  48. package/lib/__tests__/session-updater.test.js +70 -0
  49. package/lib/choice-input.js +383 -0
  50. package/lib/choice-input.js.map +1 -0
  51. package/lib/choice.js +192 -0
  52. package/lib/choice.js.map +1 -0
  53. package/lib/feedback-tick.js +134 -0
  54. package/lib/feedback-tick.js.map +1 -0
  55. package/lib/index.js +405 -0
  56. package/lib/index.js.map +1 -0
  57. package/lib/main.js +63 -0
  58. package/lib/main.js.map +1 -0
  59. package/lib/multiple-choice.js +399 -0
  60. package/lib/multiple-choice.js.map +1 -0
  61. package/lib/print.js +94 -0
  62. package/lib/print.js.map +1 -0
  63. package/lib/session-updater.js +37 -0
  64. package/lib/session-updater.js.map +1 -0
  65. package/lib/utils.js +14 -0
  66. package/lib/utils.js.map +1 -0
  67. package/module/configure.js +1 -0
  68. package/module/controller.js +3045 -0
  69. package/module/demo.js +86 -0
  70. package/module/element.js +1 -0
  71. package/module/index.html +21 -0
  72. package/module/manifest.json +14 -0
  73. package/module/print-demo.js +124 -0
  74. package/module/print.html +18 -0
  75. package/module/print.js +1 -17945
  76. package/package.json +28 -94
  77. package/configure.js +0 -2
  78. package/controller.js +0 -1
  79. package/dist/author/defaults.d.ts +0 -205
  80. package/dist/author/defaults.js +0 -151
  81. package/dist/author/index.d.ts +0 -26
  82. package/dist/author/index.js +0 -119
  83. package/dist/author/main.d.ts +0 -34
  84. package/dist/author/main.js +0 -287
  85. package/dist/author/utils.d.ts +0 -9
  86. package/dist/author/utils.js +0 -7
  87. package/dist/browser/Radio-Bbu0BH_k.js +0 -9581
  88. package/dist/browser/Radio-Bbu0BH_k.js.map +0 -1
  89. package/dist/browser/author/index.js +0 -37436
  90. package/dist/browser/author/index.js.map +0 -1
  91. package/dist/browser/controller/index.js +0 -204
  92. package/dist/browser/controller/index.js.map +0 -1
  93. package/dist/browser/delivery/index.js +0 -251
  94. package/dist/browser/delivery/index.js.map +0 -1
  95. package/dist/browser/dist-CHbLnyuX.js +0 -111
  96. package/dist/browser/dist-CHbLnyuX.js.map +0 -1
  97. package/dist/browser/main-DahQxQZC.js +0 -2451
  98. package/dist/browser/main-DahQxQZC.js.map +0 -1
  99. package/dist/browser/multiple-choice.css +0 -2
  100. package/dist/browser/print/index.js +0 -43
  101. package/dist/browser/print/index.js.map +0 -1
  102. package/dist/controller/defaults.d.ts +0 -35
  103. package/dist/controller/defaults.js +0 -29
  104. package/dist/controller/index.d.ts +0 -65
  105. package/dist/controller/index.js +0 -129
  106. package/dist/controller/utils.d.ts +0 -10
  107. package/dist/controller/utils.js +0 -8
  108. package/dist/delivery/choice-input.d.ts +0 -44
  109. package/dist/delivery/choice-input.js +0 -280
  110. package/dist/delivery/choice.d.ts +0 -20
  111. package/dist/delivery/choice.js +0 -105
  112. package/dist/delivery/feedback-tick.d.ts +0 -20
  113. package/dist/delivery/feedback-tick.js +0 -104
  114. package/dist/delivery/index.d.ts +0 -37
  115. package/dist/delivery/index.js +0 -215
  116. package/dist/delivery/main.d.ts +0 -31
  117. package/dist/delivery/main.js +0 -51
  118. package/dist/delivery/multiple-choice.d.ts +0 -61
  119. package/dist/delivery/multiple-choice.js +0 -245
  120. package/dist/delivery/session-updater.d.ts +0 -10
  121. package/dist/delivery/session-updater.js +0 -9
  122. package/dist/delivery/utils.d.ts +0 -10
  123. package/dist/delivery/utils.js +0 -4
  124. package/dist/index.d.ts +0 -1
  125. package/dist/index.iife.d.ts +0 -8
  126. package/dist/index.iife.js +0 -148
  127. package/dist/index.js +0 -2
  128. package/dist/node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js +0 -16
  129. package/dist/print/index.d.ts +0 -15
  130. package/dist/print/index.js +0 -43
  131. package/dist/runtime-support.d.ts +0 -12
  132. package/dist/runtime-support.js +0 -12
  133. package/module/print.js.map +0 -1
@@ -1,43 +0,0 @@
1
- import { F as e, M as t, Vt as n } from "../Radio-Bbu0BH_k.js";
2
- import { t as r } from "../main-DahQxQZC.js";
3
- import { c as i, l as a } from "../dist-CHbLnyuX.js";
4
- import o from "react";
5
- import { createRoot as s } from "react-dom/client";
6
- var c = (0, (/* @__PURE__ */ n(e(), 1)).default)("pie-element:multiple-choice:print"), l = (e, t) => {
7
- let n = t.role === "instructor";
8
- return e.prompt = e.promptEnabled === !1 ? void 0 : e.prompt, e.teacherInstructions = n && e.teacherInstructionsEnabled !== !1 ? e.teacherInstructions : void 0, e.showTeacherInstructions = n, e.alwaysShowCorrect = n, e.mode = n ? "evaluate" : e.mode, e.disabled = !0, e.animationsDisabled = !0, e.lockChoiceOrder = !0, e.choicesLayout = e.choicesLayout || "vertical", e.choices = a(e.choices).map((t) => (t.rationale = n && e.rationaleEnabled !== !1 ? t.rationale : void 0, t.hideTick = n, t.feedback = void 0, t)), e.keyMode = e.choicePrefix || "letters", e;
9
- }, u = class extends HTMLElement {
10
- constructor() {
11
- super(), this._options = null, this._model = null, this._session = [], this._root = null, this._rerender = i(() => {
12
- if (this._model && this._session) {
13
- let e = l(this._model, this._options), n = this._options && o.createElement(r, {
14
- model: e,
15
- session: {},
16
- options: this._options
17
- });
18
- this._root ||= s(this), this._root.render(n), requestAnimationFrame(() => {
19
- requestAnimationFrame(() => {
20
- c("render complete - render math"), t(this);
21
- });
22
- });
23
- } else c("skip");
24
- }, 50, {
25
- leading: !1,
26
- trailing: !0
27
- });
28
- }
29
- set options(e) {
30
- this._options = e;
31
- }
32
- set model(e) {
33
- this._model = e, this._rerender();
34
- }
35
- connectedCallback() {}
36
- disconnectedCallback() {
37
- this._root && this._root.unmount();
38
- }
39
- };
40
- //#endregion
41
- export { u as default };
42
-
43
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/print/index.tsx"],"sourcesContent":["// @ts-nocheck\n/**\n * @synced-from pie-elements/packages/multiple-choice/src/print.js\n * @auto-generated\n *\n * This file is automatically synced from pie-elements and converted to TypeScript.\n * Manual edits will be overwritten on next sync.\n * To make changes, edit the upstream JavaScript file and run sync again.\n */\n\nimport React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { cloneDeep, debounce } from '@pie-element/shared-lodash';\nimport Main from '../delivery/main.js';\nimport { renderMath } from '@pie-element/shared-math-rendering-mathjax';\nimport debug from 'debug';\n\nconst log = debug('pie-element:multiple-choice:print');\n\n/**\n * Live in same package as main element - so we can access some of the shared comps!\n *\n * - update pslb to build print if src/print.js is there\n * - update demo el\n * - get configure/controller building\n */\n\nconst preparePrintModel = (model, opts) => {\n const instr = opts.role === 'instructor';\n\n model.prompt = model.promptEnabled !== false ? model.prompt : undefined;\n model.teacherInstructions =\n instr && model.teacherInstructionsEnabled !== false ? model.teacherInstructions : undefined;\n model.showTeacherInstructions = instr;\n model.alwaysShowCorrect = instr;\n model.mode = instr ? 'evaluate' : model.mode;\n\n model.disabled = true;\n model.animationsDisabled = true;\n model.lockChoiceOrder = true;\n model.choicesLayout = model.choicesLayout || 'vertical';\n\n const choices = cloneDeep(model.choices);\n\n model.choices = choices.map((c) => {\n c.rationale = instr && model.rationaleEnabled !== false ? c.rationale : undefined;\n c.hideTick = instr;\n c.feedback = undefined;\n return c;\n });\n\n model.keyMode = model.choicePrefix || 'letters';\n\n return model;\n};\n\nexport default class MultipleChoicePrint extends HTMLElement {\n constructor() {\n super();\n this._options = null;\n this._model = null;\n this._session = [];\n this._root = null;\n this._rerender = debounce(\n () => {\n if (this._model && this._session) {\n const printModel = preparePrintModel(this._model, this._options);\n\n const element =\n this._options &&\n React.createElement(Main, {\n model: printModel,\n session: {},\n options: this._options,\n });\n\n if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(element);\n // Use double requestAnimationFrame so React has committed to the DOM before we render math\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n log('render complete - render math');\n renderMath(this);\n });\n });\n } else {\n log('skip');\n }\n },\n 50,\n { leading: false, trailing: true },\n );\n }\n set options(o) {\n this._options = o;\n }\n\n set model(s) {\n this._model = s;\n this._rerender();\n }\n\n connectedCallback() {}\n\n disconnectedCallback() {\n if (this._root) {\n this._root.unmount();\n }\n }\n}\n"],"mappings":";;;;;AAiBA,IAAM,KAAA,IAAA,wBAAA,EAAA,CAAA,QAAA,CAAY,mCAAmC,GAU/C,KAAqB,GAAO,MAAS;CACzC,IAAM,IAAQ,EAAK,SAAS;CAyB5B,OAvBA,EAAM,SAAS,EAAM,kBAAkB,KAAuB,KAAA,IAAf,EAAM,QACrD,EAAM,sBACJ,KAAS,EAAM,+BAA+B,KAAQ,EAAM,sBAAsB,KAAA,GACpF,EAAM,0BAA0B,GAChC,EAAM,oBAAoB,GAC1B,EAAM,OAAO,IAAQ,aAAa,EAAM,MAExC,EAAM,WAAW,IACjB,EAAM,qBAAqB,IAC3B,EAAM,kBAAkB,IACxB,EAAM,gBAAgB,EAAM,iBAAiB,YAI7C,EAAM,UAFU,EAAU,EAAM,OAEhB,CAAA,CAAQ,KAAK,OAC3B,EAAE,YAAY,KAAS,EAAM,qBAAqB,KAAQ,EAAE,YAAY,KAAA,GACxE,EAAE,WAAW,GACb,EAAE,WAAW,KAAA,GACN,EACR,GAED,EAAM,UAAU,EAAM,gBAAgB,WAE/B;AACT,GAEqB,IAArB,cAAiD,YAAY;CAC3D,cAAc;EAMZ,AALA,MAAM,GACN,KAAK,WAAW,MAChB,KAAK,SAAS,MACd,KAAK,WAAW,CAAC,GACjB,KAAK,QAAQ,MACb,KAAK,YAAY,QACT;GACJ,IAAI,KAAK,UAAU,KAAK,UAAU;IAChC,IAAM,IAAa,EAAkB,KAAK,QAAQ,KAAK,QAAQ,GAEzD,IACJ,KAAK,YACL,EAAM,cAAc,GAAM;KACxB,OAAO;KACP,SAAS,CAAC;KACV,SAAS,KAAK;IAChB,CAAC;IAOH,AALA,AACE,KAAK,UAAQ,EAAW,IAAI,GAE9B,KAAK,MAAM,OAAO,CAAO,GAEzB,4BAA4B;KAC1B,4BAA4B;MAE1B,AADA,EAAI,+BAA+B,GACnC,EAAW,IAAI;KACjB,CAAC;IACH,CAAC;GACH,OACE,EAAI,MAAM;EAEd,GACA,IACA;GAAE,SAAS;GAAO,UAAU;EAAK,CACnC;CACF;CACA,IAAI,QAAQ,GAAG;EACb,KAAK,WAAW;CAClB;CAEA,IAAI,MAAM,GAAG;EAEX,AADA,KAAK,SAAS,GACd,KAAK,UAAU;CACjB;CAEA,oBAAoB,CAAC;CAErB,uBAAuB;EACrB,AAAI,KAAK,SACP,KAAK,MAAM,QAAQ;CAEvB;AACF"}
@@ -1,35 +0,0 @@
1
- /**
2
- * @synced-from pie-elements/packages/multiple-choice/controller/src/defaults.js
3
- * @auto-generated
4
- *
5
- * This file is automatically synced from pie-elements and converted to TypeScript.
6
- * Manual edits will be overwritten on next sync.
7
- * To make changes, edit the upstream JavaScript file and run sync again.
8
- */
9
- declare const _default: {
10
- choiceMode: string;
11
- choicePrefix: string;
12
- choices: never[];
13
- choicesLayout: string;
14
- feedbackEnabled: boolean;
15
- gridColumns: number;
16
- lockChoiceOrder: boolean;
17
- partialScoring: boolean;
18
- prompt: string;
19
- promptEnabled: boolean;
20
- rationale: string;
21
- rationaleEnabled: boolean;
22
- scoringType: string;
23
- studentInstructionsEnabled: boolean;
24
- teacherInstructions: string;
25
- teacherInstructionsEnabled: boolean;
26
- toolbarEditorPosition: string;
27
- selectedAnswerBackgroundColor: string;
28
- selectedAnswerStrokeColor: string;
29
- selectedAnswerStrokeWidth: string;
30
- hoverAnswerBackgroundColor: string;
31
- hoverAnswerStrokeColor: string;
32
- hoverAnswerStrokeWidth: string;
33
- keyboardEventsEnabled: boolean;
34
- };
35
- export default _default;
@@ -1,29 +0,0 @@
1
- //#region src/controller/defaults.ts
2
- var e = {
3
- choiceMode: "checkbox",
4
- choicePrefix: "letters",
5
- choices: [],
6
- choicesLayout: "vertical",
7
- feedbackEnabled: !1,
8
- gridColumns: 2,
9
- lockChoiceOrder: !0,
10
- partialScoring: !0,
11
- prompt: "",
12
- promptEnabled: !0,
13
- rationale: "",
14
- rationaleEnabled: !0,
15
- scoringType: "auto",
16
- studentInstructionsEnabled: !0,
17
- teacherInstructions: "",
18
- teacherInstructionsEnabled: !0,
19
- toolbarEditorPosition: "bottom",
20
- selectedAnswerBackgroundColor: "initial",
21
- selectedAnswerStrokeColor: "initial",
22
- selectedAnswerStrokeWidth: "initial",
23
- hoverAnswerBackgroundColor: "initial",
24
- hoverAnswerStrokeColor: "initial",
25
- hoverAnswerStrokeWidth: "initial",
26
- keyboardEventsEnabled: !1
27
- };
28
- //#endregion
29
- export { e as default };
@@ -1,65 +0,0 @@
1
- /**
2
- * @synced-from pie-elements/packages/multiple-choice/controller/src/index.js
3
- * @auto-generated
4
- *
5
- * This file is automatically synced from pie-elements and converted to TypeScript.
6
- * Manual edits will be overwritten on next sync.
7
- * To make changes, edit the upstream JavaScript file and run sync again.
8
- */
9
- export declare function createDefaultModel(model?: {}): Promise<unknown>;
10
- export declare const normalize: (question: any) => any;
11
- /**
12
- *
13
- * @param {*} question
14
- * @param {*} session
15
- * @param {*} env
16
- * @param {*} updateSession - optional - a function that will set the properties passed into it on the session.
17
- */
18
- export declare function model(question: any, session: any, env: any, updateSession: any): Promise<{
19
- disabled: boolean;
20
- mode: any;
21
- prompt: any;
22
- choicesLayout: any;
23
- gridColumns: any;
24
- choiceMode: any;
25
- keyMode: any;
26
- choices: any;
27
- responseCorrect: any;
28
- language: any;
29
- extraCSSRules: any;
30
- fontSizeFactor: any;
31
- isSelectionButtonBelow: any;
32
- selectedAnswerBackgroundColor: any;
33
- selectedAnswerStrokeColor: any;
34
- selectedAnswerStrokeWidth: any;
35
- hoverAnswerBackgroundColor: any;
36
- hoverAnswerStrokeColor: any;
37
- hoverAnswerStrokeWidth: any;
38
- minSelections: any;
39
- maxSelections: any;
40
- keyboardEventsEnabled: any;
41
- autoplayAudioEnabled: any;
42
- completeAudioEnabled: any;
43
- customAudioButton: any;
44
- }>;
45
- export declare const getScore: (config: any, session: any) => number;
46
- /**
47
- * Generates detailed trace log for scoring evaluation
48
- * @param {Object} model - the question model
49
- * @param {Object} session - the student session
50
- * @param {Object} env - the environment
51
- * @returns {Array} traceLog - array of trace messages
52
- */
53
- export declare const getLogTrace: (model: any, session: any, env: any) => string[];
54
- /**
55
- *
56
- * The score is partial by default for checkbox mode, allOrNothing for radio mode.
57
- * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring = false. the value in `env` will
58
- * override the value in `model`.
59
- * @param {Object} model - the main model
60
- * @param {*} session
61
- * @param {Object} env
62
- */
63
- export declare function outcome(model: any, session: any, env: any): Promise<unknown>;
64
- export declare const createCorrectResponseSession: (question: any, env: any) => Promise<unknown>;
65
- export declare const validate: (model?: {}, config?: {}) => {};
@@ -1,129 +0,0 @@
1
- import { isResponseCorrect as e } from "./utils.js";
2
- import t from "./defaults.js";
3
- import { isEmpty as n } from "@pie-element/shared-lodash";
4
- import { getShuffledChoices as r, lockChoices as i, partialScoring as a } from "@pie-element/shared-controller-utils";
5
- //#region src/controller/index.ts
6
- var o = (e, t, n) => (r) => {
7
- let { role: i, mode: a } = t || {}, o = {
8
- label: r.label,
9
- value: r.value
10
- };
11
- if (i === "instructor" && (a === "view" || a === "evaluate") ? o.rationale = e.rationaleEnabled ? r.rationale : null : o.rationale = null, a === "evaluate" && (o.correct = !!r.correct, e.feedbackEnabled)) {
12
- let e = r.feedback && r.feedback.type || "none";
13
- e === "default" ? o.feedback = n[r.correct ? "correct" : "incorrect"] : e === "custom" && (o.feedback = r.feedback.value);
14
- }
15
- return o;
16
- };
17
- function s(e = {}) {
18
- return new Promise((n) => n({
19
- ...t,
20
- ...e
21
- }));
22
- }
23
- var c = (e) => {
24
- let { verticalMode: n, choicesLayout: r, ...i } = e || {};
25
- return {
26
- ...t,
27
- ...i,
28
- choicesLayout: r || n === !1 && "horizontal" || t.choicesLayout
29
- };
30
- };
31
- async function l(t, n, a, s) {
32
- let l = c(t), u = Object.assign({
33
- correct: "Correct",
34
- incorrect: "Incorrect"
35
- }, l.defaultFeedback), d = (l.choices || []).map(o(l, a, u));
36
- i(l, n, a) || (d = await r(d, n, s, "value"));
37
- let f = {
38
- disabled: a.mode !== "gather",
39
- mode: a.mode,
40
- prompt: l.promptEnabled ? l.prompt : null,
41
- choicesLayout: l.choicesLayout,
42
- gridColumns: l.gridColumns,
43
- choiceMode: l.choiceMode,
44
- keyMode: l.choicePrefix,
45
- choices: d,
46
- responseCorrect: a.mode === "evaluate" ? e(l, n) : void 0,
47
- language: l.language,
48
- extraCSSRules: l.extraCSSRules,
49
- fontSizeFactor: l.fontSizeFactor,
50
- isSelectionButtonBelow: l.isSelectionButtonBelow,
51
- selectedAnswerBackgroundColor: l.selectedAnswerBackgroundColor || "initial",
52
- selectedAnswerStrokeColor: l.selectedAnswerStrokeColor || "initial",
53
- selectedAnswerStrokeWidth: l.selectedAnswerStrokeWidth || "initial",
54
- hoverAnswerBackgroundColor: l.hoverAnswerBackgroundColor || "initial",
55
- hoverAnswerStrokeColor: l.hoverAnswerStrokeColor || "initial",
56
- hoverAnswerStrokeWidth: l.hoverAnswerStrokeWidth || "initial",
57
- minSelections: l.minSelections,
58
- maxSelections: l.maxSelections,
59
- keyboardEventsEnabled: l.keyboardEventsEnabled,
60
- autoplayAudioEnabled: l.autoplayAudioEnabled,
61
- completeAudioEnabled: l.completeAudioEnabled,
62
- customAudioButton: l.customAudioButton
63
- }, { role: p, mode: m } = a || {};
64
- return p === "instructor" && (m === "view" || m === "evaluate") ? f.teacherInstructions = l.teacherInstructionsEnabled ? l.teacherInstructions : null : f.teacherInstructions = null, f;
65
- }
66
- var u = (e, t) => {
67
- if (!t || n(t)) return 0;
68
- let r = t.value || [], i = (e.choices || []).filter((e) => e.correct), a = r.reduce((e, t) => e + +!!i.find((e) => e.value === t), 0);
69
- i.length < r.length && (a -= r.length - i.length, a < 0 && (a = 0));
70
- let o = i.length ? a / i.length : 0;
71
- return parseFloat(o.toFixed(2));
72
- }, d = (e, t, n) => {
73
- let r = [], i = t?.value || [], o = e.choiceMode === "radio" ? "multiple-choice (radio)" : "multiple-select (checkbox)";
74
- r.push(`Question type: ${o}.`), i.length ? r.push(`Student selected ${i.length} answer(s): ${i.join(", ")}.`) : r.push("Student did not select any answers.");
75
- let s = (e.choices || []).filter((e) => e.correct), c = s.map((e) => e.value);
76
- if (r.push(`${s.length} correct answer(s) are defined for this question.`), i.length) {
77
- let e = i.filter((e) => c.includes(e)), t = i.filter((e) => !c.includes(e));
78
- r.push(`Student selected ${e.length} correct and ${t.length} incorrect answer(s).`);
79
- }
80
- let l = a.enabled(e, n) && e.choiceMode !== "radio" ? "partial scoring" : "all-or-nothing scoring";
81
- r.push(`Score calculated using ${l}.`);
82
- let d = u(e, t);
83
- return r.push(`Final score: ${d}.`), r;
84
- };
85
- function f(e, t, r) {
86
- return new Promise((i) => {
87
- if (!t || n(t)) i({
88
- score: 0,
89
- empty: !0,
90
- traceLog: ["Student did not select any answers. Score is 0."]
91
- });
92
- else {
93
- let n = d(e, t, r), o = u(e, t);
94
- i({
95
- score: a.enabled(e, r) && e.choiceMode !== "radio" ? o : +(o === 1),
96
- empty: !1,
97
- traceLog: n
98
- });
99
- }
100
- });
101
- }
102
- var p = (e, t) => new Promise((n) => {
103
- if (t.mode !== "evaluate" && t.role === "instructor") {
104
- let { choices: t } = e || { choices: [] };
105
- n({
106
- id: "1",
107
- value: t.filter((e) => e.correct).map((e) => e.value)
108
- });
109
- } else n(null);
110
- }), m = (e) => (e || "").replace(/(<(?!img|iframe|source)([^>]+)>)/gi, ""), h = (e = {}, t = {}) => {
111
- let { choices: r } = e, { minAnswerChoices: i = 2, maxAnswerChoices: a } = t, o = [...r || []].reverse(), s = {}, c = {}, l = {};
112
- ["teacherInstructions", "prompt"].forEach((n) => {
113
- t[n]?.required && !m(e[n]) && (l[n] = "This field is required.");
114
- });
115
- let u = !1, d = 0;
116
- o.forEach((e, n) => {
117
- let { correct: r, value: i, label: a, rationale: l } = e;
118
- r && (u = !0, d++), m(a) ? o.slice(n + 1).some((e) => e.label === a) && (s[i] = "Content should be unique.") : s[i] = "Content should not be empty.", t.rationale?.required && !m(l) && (c[i] = "This field is required.");
119
- });
120
- let f = (r || []).length;
121
- if (f < i ? l.answerChoices = `There should be at least ${i} choices defined.` : f > a && (l.answerChoices = `No more than ${a} choices should be defined.`), !u) l.correctResponse = "No correct response defined.";
122
- else {
123
- let { maxSelections: t, choiceMode: n } = e;
124
- n !== "radio" && t != null && d > t && (l.correctResponse = `The number of correct answers (${d}) exceeds max selections (${t}). Students won't be able to select all correct answers.`);
125
- }
126
- return n(s) || (l.choices = s), n(c) || (l.rationale = c), l;
127
- };
128
- //#endregion
129
- export { p as createCorrectResponseSession, s as createDefaultModel, d as getLogTrace, u as getScore, l as model, c as normalize, f as outcome, h as validate };
@@ -1,10 +0,0 @@
1
- /**
2
- * @synced-from pie-elements/packages/multiple-choice/controller/src/utils.js
3
- * @auto-generated
4
- *
5
- * This file is automatically synced from pie-elements and converted to TypeScript.
6
- * Manual edits will be overwritten on next sync.
7
- * To make changes, edit the upstream JavaScript file and run sync again.
8
- */
9
- export declare const getCorrectResponse: (choices: any) => any;
10
- export declare const isResponseCorrect: (question: any, session: any) => any;
@@ -1,8 +0,0 @@
1
- import { isEqual as e } from "@pie-element/shared-lodash";
2
- //#region src/controller/utils.ts
3
- var t = (e) => e.filter((e) => e.correct).map((e) => e.value).sort(), n = (n, r) => {
4
- let i = t(n.choices);
5
- return r && e((r.value || []).sort(), i);
6
- };
7
- //#endregion
8
- export { t as getCorrectResponse, n as isResponseCorrect };
@@ -1,44 +0,0 @@
1
- /**
2
- * @synced-from pie-elements/packages/multiple-choice/src/choice-input.jsx
3
- * @auto-generated
4
- *
5
- * This file is automatically synced from pie-elements and converted to TypeScript.
6
- * Manual edits will be overwritten on next sync.
7
- * To make changes, edit the upstream JavaScript file and run sync again.
8
- */
9
- import React from 'react';
10
- import PropTypes from 'prop-types';
11
- export declare const StyledFormControlLabel: any;
12
- export declare const StyledCheckbox: (props: any) => React.JSX.Element;
13
- export declare const StyledRadio: (props: any) => React.JSX.Element;
14
- export declare class ChoiceInput extends React.Component {
15
- static propTypes: {
16
- choiceMode: PropTypes.Requireable<string>;
17
- displayKey: PropTypes.Requireable<string>;
18
- checked: PropTypes.Validator<boolean>;
19
- correctness: PropTypes.Requireable<string>;
20
- disabled: PropTypes.Validator<boolean>;
21
- feedback: PropTypes.Requireable<string>;
22
- label: PropTypes.Validator<string>;
23
- rationale: PropTypes.Requireable<string>;
24
- onChange: PropTypes.Validator<(...args: any[]) => any>;
25
- value: PropTypes.Validator<string>;
26
- className: PropTypes.Requireable<string>;
27
- tagName: PropTypes.Requireable<string>;
28
- hideTick: PropTypes.Requireable<boolean>;
29
- isEvaluateMode: PropTypes.Requireable<boolean>;
30
- choicesLayout: PropTypes.Requireable<string>;
31
- isSelectionButtonBelow: PropTypes.Requireable<boolean>;
32
- };
33
- static defaultProps: {
34
- rationale: null;
35
- checked: boolean;
36
- isEvaluateMode: boolean;
37
- };
38
- constructor(props: any);
39
- onToggleChoice(event: any): void;
40
- generateChoiceId(): string;
41
- handleKeyDown: any;
42
- render(): React.JSX.Element;
43
- }
44
- export default ChoiceInput;
@@ -1,280 +0,0 @@
1
- import { clsx as e } from "../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js";
2
- import t from "./feedback-tick.js";
3
- import n from "react";
4
- import r from "prop-types";
5
- import * as i from "@pie-lib/render-ui";
6
- import { Feedback as a, PreviewPrompt as o, color as s } from "@pie-lib/render-ui";
7
- import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
8
- import { styled as d } from "@mui/material/styles";
9
- import f from "@mui/material/Box";
10
- import p from "@mui/material/FormControlLabel";
11
- import m from "@mui/material/Checkbox";
12
- import h from "@mui/material/Radio";
13
- //#region src/delivery/choice-input.tsx
14
- function g(e) {
15
- return typeof e == "function" || typeof e == "object" && !!e && typeof e.$$typeof == "symbol";
16
- }
17
- function _(e, t) {
18
- return !e || g(e) ? e : g(e.default) ? e.default : t && g(e[t]) ? e[t] : t && g(e[t]?.default) ? e[t].default : e;
19
- }
20
- var v = _(o, "PreviewPrompt") || _(S.PreviewPrompt, "PreviewPrompt"), y = _(a, "Feedback") || _(S.Feedback, "Feedback"), b = i, x = b.default, S = x && typeof x == "object" ? x : b, C = "multiple-choice-component", w = d(f)({
21
- display: "flex",
22
- alignItems: "center",
23
- backgroundColor: s.background()
24
- }), T = d(f)({
25
- display: "flex",
26
- alignItems: "center",
27
- backgroundColor: s.background(),
28
- flex: 1,
29
- "& .MuiFormControlLabel-root": { marginLeft: "-14px" },
30
- "& label": {
31
- color: s.text(),
32
- "& > span": { fontSize: "inherit" },
33
- "& > .MuiButtonBase-root": { padding: "12px" }
34
- }
35
- }), E = d("span")(({ theme: e }) => ({
36
- display: "flex",
37
- alignItems: "center",
38
- "& > span": { marginLeft: `-${e.spacing(1)}` }
39
- })), D = d("span")({
40
- position: "absolute",
41
- left: "-10000px",
42
- top: "auto",
43
- width: "1px",
44
- height: "1px",
45
- overflow: "hidden"
46
- }), O = d(p)({
47
- "& .MuiFormControlLabel-label": {
48
- color: `${s.text()} !important`,
49
- backgroundColor: s.background(),
50
- letterSpacing: "normal"
51
- },
52
- "&.Mui-disabled *": { cursor: "not-allowed !important" }
53
- }), k = (e, t) => ({ [`&.${C}`]: { color: `var(--choice-input-${e}, ${t}) !important` } }), A = (e) => {
54
- let t = (t) => e ? `${e}-${t}` : t;
55
- return {
56
- [t("root")]: {
57
- ...k("color", s.text()),
58
- ...e === "correct" ? k("correct-color", s.text()) : {},
59
- ...e === "incorrect" ? k("incorrect-color", s.incorrect()) : {}
60
- },
61
- [t("checked")]: {
62
- ...e === "correct" ? k("correct-selected-color", s.correct()) : {},
63
- ...e === "incorrect" ? k("incorrect-checked", s.incorrect()) : {},
64
- ...e ? {} : k("selected-color", s.primary())
65
- },
66
- [t("disabled")]: {
67
- ...k("disabled-color", s.text()),
68
- ...e === "correct" ? k("correct-disabled-color", s.disabled()) : {},
69
- ...e === "incorrect" ? k("incorrect-disabled-color", s.disabled()) : {},
70
- opacity: .6,
71
- cursor: "not-allowed !important",
72
- pointerEvents: "initial !important"
73
- },
74
- focusVisibleUnchecked: {
75
- outline: `2px solid ${s.keyBoardFocusIndicator()}`,
76
- backgroundColor: "transparent"
77
- },
78
- focusVisibleChecked: {
79
- outline: `2px solid ${s.keyBoardFocusIndicator()}`,
80
- backgroundColor: "transparent"
81
- }
82
- };
83
- }, j = d(m, { shouldForwardProp: (e) => e !== "correctness" })(({ correctness: e }) => {
84
- let t = A(e), n = (t) => e ? `${e}-${t}` : t;
85
- return {
86
- [`&.${C}`]: {
87
- ...t[n("root")],
88
- "&.Mui-checked": t[n("checked")],
89
- "&.Mui-disabled": e ? {} : t[n("disabled")],
90
- "&:hover:not(.Mui-disabled) svg": {
91
- boxShadow: `0px 0px 0px 2px ${s.keyBoardFocusIndicator()}`,
92
- borderRadius: "4px"
93
- }
94
- },
95
- "&.Mui-focusVisible": {
96
- "&:not(.Mui-checked)": t.focusVisibleUnchecked,
97
- "&.Mui-checked": t.focusVisibleChecked
98
- }
99
- };
100
- }), M = (e) => {
101
- let { correctness: t, checked: n, onChange: r, disabled: i, value: a, id: o, onKeyDown: s, inputRef: c } = e;
102
- return /* @__PURE__ */ l(j, {
103
- id: o,
104
- slotProps: { input: { ref: c } },
105
- onKeyDown: s,
106
- disableRipple: !0,
107
- checked: n,
108
- onChange: r,
109
- disabled: i,
110
- value: a,
111
- correctness: t,
112
- className: C
113
- });
114
- }, N = d(h, { shouldForwardProp: (e) => e !== "correctness" })(({ correctness: e }) => {
115
- let t = A(e), n = (t) => e ? `${e}-${t}` : t;
116
- return {
117
- [`&.${C}`]: {
118
- ...t[n("root")],
119
- "&.Mui-checked": t[n("checked")],
120
- "&.Mui-disabled": e ? {} : t[n("disabled")],
121
- "&.Mui-focusVisible:not(.Mui-checked)": t.focusVisibleUnchecked,
122
- "&.Mui-focusVisible.Mui-checked": t.focusVisibleChecked,
123
- "&:hover:not(.Mui-disabled) svg": {
124
- boxShadow: `0px 0px 0px 2px ${s.keyBoardFocusIndicator()}`,
125
- borderRadius: "50%"
126
- }
127
- },
128
- "&.Mui-focusVisible": {
129
- "& input": { outline: 0 },
130
- "& .MuiTouchRipple-root": { display: "none" }
131
- }
132
- };
133
- }), P = (e) => {
134
- let { correctness: t, checked: n, onChange: r, disabled: i, value: a, id: o, tagName: s, inputRef: c } = e;
135
- return /* @__PURE__ */ l(N, {
136
- id: o,
137
- slotProps: { input: { ref: c } },
138
- disableRipple: !0,
139
- checked: n,
140
- onChange: r,
141
- disabled: i,
142
- value: a,
143
- correctness: t,
144
- className: C,
145
- name: s
146
- });
147
- }, F = class extends n.Component {
148
- static propTypes = {
149
- choiceMode: r.oneOf(["radio", "checkbox"]),
150
- displayKey: r.string,
151
- checked: r.bool.isRequired,
152
- correctness: r.string,
153
- disabled: r.bool.isRequired,
154
- feedback: r.string,
155
- label: r.string.isRequired,
156
- rationale: r.string,
157
- onChange: r.func.isRequired,
158
- value: r.string.isRequired,
159
- className: r.string,
160
- tagName: r.string,
161
- hideTick: r.bool,
162
- isEvaluateMode: r.bool,
163
- choicesLayout: r.oneOf([
164
- "vertical",
165
- "grid",
166
- "horizontal"
167
- ]),
168
- isSelectionButtonBelow: r.bool
169
- };
170
- static defaultProps = {
171
- rationale: null,
172
- checked: !1,
173
- isEvaluateMode: !1
174
- };
175
- constructor(e) {
176
- super(e), this.onToggleChoice = this.onToggleChoice.bind(this), this.choiceId = this.generateChoiceId(), this.descId = `${this.choiceId}-desc`;
177
- }
178
- onToggleChoice(e) {
179
- this.props.onChange(e);
180
- }
181
- generateChoiceId() {
182
- return "choice-" + (Math.random() * 1e4).toFixed();
183
- }
184
- handleKeyDown = (e) => {
185
- let { choiceMode: t } = this.props;
186
- if (t !== "checkbox") return;
187
- let n = e.key === "ArrowDown", r = e.key === "ArrowUp";
188
- if (!n && !r) return;
189
- e.preventDefault();
190
- let i = document.getElementById(this.choiceId);
191
- if (!i) return;
192
- let a = i.closest("fieldset");
193
- if (!a) return;
194
- let o = Array.from(a.querySelectorAll("input[type=\"checkbox\"]")), s = o.findIndex((e) => e === i);
195
- if (s === -1) return;
196
- let c = o[n ? s + 1 : s - 1];
197
- c && c.focus();
198
- };
199
- render() {
200
- let { choiceMode: n, disabled: r, displayKey: i, feedback: a, label: o, correctness: s, className: d, rationale: f, hideTick: p, isEvaluateMode: m, choicesLayout: h, value: g, checked: _, tagName: b, isSelectionButtonBelow: x } = this.props, S = n === "checkbox" ? M : P, k = n === "checkbox" ? "checkbox" : "radio-button", A = {
201
- ...h === "horizontal" && { [`& .${C}`]: {
202
- padding: "8px",
203
- margin: "4px 0 4px 4px"
204
- } },
205
- ...x && h !== "grid" && { "& > label": { alignItems: "flex-start" } },
206
- ...x && h === "grid" && {
207
- justifyContent: "center",
208
- "& > label": { alignItems: "center" }
209
- }
210
- }, j = typeof o == "string" && (o.includes("<math") || o.includes("\\(") || o.includes("\\[") || o.includes("<img") || o.includes("data-latex") || o.includes("data-raw") || o.includes("<mjx-container")), N = i ? /* @__PURE__ */ l(D, {
211
- id: this.descId,
212
- children: j ? `Pick the answer below, ${i}` : i
213
- }) : null, F = /* @__PURE__ */ l(c, { children: i && !x ? /* @__PURE__ */ u(w, {
214
- component: "span",
215
- children: [/* @__PURE__ */ u("span", {
216
- "aria-hidden": "true",
217
- children: [
218
- i,
219
- ".",
220
- "\xA0"
221
- ]
222
- }), /* @__PURE__ */ l(v, {
223
- className: "prompt-label",
224
- prompt: o,
225
- tagName: "span"
226
- })]
227
- }) : /* @__PURE__ */ l(v, {
228
- className: "prompt-label",
229
- prompt: o,
230
- tagName: "span"
231
- }) }), I = {
232
- disabled: r,
233
- checked: _,
234
- correctness: s,
235
- tagName: b,
236
- value: g,
237
- id: this.choiceId,
238
- onChange: this.onToggleChoice,
239
- onKeyDown: this.handleKeyDown,
240
- ...N ? { "aria-describedby": this.descId } : {}
241
- }, L = x ? /* @__PURE__ */ u(E, { children: [
242
- N,
243
- /* @__PURE__ */ l(S, {
244
- ...I,
245
- style: { padding: 0 }
246
- }),
247
- /* @__PURE__ */ l("span", {
248
- "aria-hidden": "true",
249
- children: i ? `${i}.` : ""
250
- })
251
- ] }) : /* @__PURE__ */ u(c, { children: [N, /* @__PURE__ */ l(S, { ...I })] });
252
- return /* @__PURE__ */ u("div", {
253
- className: e(d, "corespring-" + k, "choice-input"),
254
- children: [
255
- /* @__PURE__ */ u(w, { children: [!p && m && /* @__PURE__ */ l(t, { correctness: s }), /* @__PURE__ */ l(T, {
256
- className: "checkbox-holder",
257
- sx: A,
258
- children: /* @__PURE__ */ l(O, {
259
- label: F,
260
- value: g,
261
- htmlFor: this.choiceId,
262
- labelPlacement: x ? "top" : void 0,
263
- control: L
264
- })
265
- })] }),
266
- f && /* @__PURE__ */ l(v, {
267
- className: "rationale",
268
- defaultClassName: "rationale",
269
- prompt: f
270
- }),
271
- /* @__PURE__ */ l(y, {
272
- feedback: a,
273
- correctness: s
274
- })
275
- ]
276
- });
277
- }
278
- };
279
- //#endregion
280
- export { F as ChoiceInput, F as default, M as StyledCheckbox, O as StyledFormControlLabel, P as StyledRadio };