@pie-element/mc-populated-blank 0.2.13-next.3 → 0.3.0-next.4

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.
@@ -1,116 +1,116 @@
1
- import { A as e, C as t, E as n, M as r, N as i, O as a, P as o, S as s, T as c, _ as l, a as u, b as d, d as f, f as p, g as m, h, j as g, k as _, m as v, n as y, p as b, t as x, u as S, v as C, w, x as T } from "../client-B0miu8E8.js";
1
+ import { A as e, C as t, E as n, M as r, N as i, O as a, P as o, S as s, T as c, _ as l, a as u, b as d, d as f, f as p, g as m, h, j as g, k as _, m as v, n as y, p as b, t as x, u as ee, v as S, w as C, x as w } from "../client-BAfWqkS6.js";
2
2
  //#region src/print/Print.svelte
3
- var E = C("<div class=\"mb-4 prose prose-sm svelte-1fx5wwa\"></div>"), D = C("<div class=\"mb-2 prose prose-sm svelte-1fx5wwa\"></div>"), O = C("<img class=\"max-h-14 object-contain\"/>"), k = C("<div class=\"mb-4 prose prose-sm svelte-1fx5wwa\"><!> <span class=\"inline-block min-w-[6rem] border-b-2 border-gray-600 print:border-black px-1\"><!></span> <!></div>"), A = C("<div><strong>Audio:</strong> </div>"), j = C("<div><strong>Transcript:</strong> </div>"), M = C("<div class=\"text-sm mb-4\"><!> <!></div>"), N = C("<span class=\"font-medium\"> </span> <!>", 1), ee = C("<span class=\"font-medium\">(key)</span>"), te = C("<!> <!>", 1), ne = C("<li><!></li>"), P = C("<div class=\"p-4 print:p-0\"><!> <!> <!> <!> <ul class=\"text-sm list-disc pl-5\"></ul></div>"), F = {
3
+ var T = S("<div class=\"mb-4 prose prose-sm svelte-1fx5wwa\"></div>"), E = S("<div class=\"mb-2 prose prose-sm svelte-1fx5wwa\"></div>"), D = S("<img class=\"max-h-14 object-contain\"/>"), O = S("<div class=\"mb-4 prose prose-sm svelte-1fx5wwa\"><!> <span class=\"inline-block min-w-[6rem] border-b-2 border-gray-600 print:border-black px-1\"><!></span> <!></div>"), k = S("<div><strong>Audio:</strong> </div>"), A = S("<div><strong>Transcript:</strong> </div>"), j = S("<div class=\"text-sm mb-4\"><!> <!></div>"), M = S("<span class=\"font-medium\"> </span> <!>", 1), N = S("<span class=\"font-medium\">(key)</span>"), P = S("<!> <!>", 1), F = S("<li><!></li>"), I = S("<div class=\"p-4 print:p-0\"><!> <!> <!> <!> <ul class=\"text-sm list-disc pl-5\"></ul></div>"), L = {
4
4
  hash: "svelte-1fx5wwa",
5
5
  code: ".prose.svelte-1fx5wwa p {margin:0.5em 0;}.prose.svelte-1fx5wwa strong {font-weight:600;}"
6
6
  };
7
- function I(x, C) {
8
- i(C, !0), S(x, F);
9
- let I = y(C, "model", 7, null), L = _(""), R = _("");
7
+ function R(x, S) {
8
+ i(S, !0), ee(x, L);
9
+ let R = y(S, "model", 7, null), z = _(""), B = _("");
10
10
  t(() => {
11
- a(L, I()?.prompt || "", !0), a(R, I()?.template || "", !0);
11
+ a(z, R()?.prompt || "", !0), a(B, R()?.template || "", !0);
12
12
  });
13
- let z = e(() => {
14
- let e = T(R).indexOf("{{blank}}");
13
+ let V = g(() => {
14
+ let e = w(B).indexOf("{{blank}}");
15
15
  return e < 0 ? {
16
- before: T(R),
16
+ before: w(B),
17
17
  after: ""
18
18
  } : {
19
- before: T(R).slice(0, e),
20
- after: T(R).slice(e + 9)
19
+ before: w(B).slice(0, e),
20
+ after: w(B).slice(e + 9)
21
21
  };
22
- }), B = e(() => Array.isArray(I()?.choices) ? I().choices : []), V = e(() => I()?.choices?.find((e) => e.id === I()?.correctChoiceId)), H = e(() => I()?.choiceMode || "text"), U = e(() => I()?.interactionMode === "audio_mc_only"), W = e(() => I()?.printAnswerKey !== !1);
23
- var G = {
22
+ }), H = g(() => Array.isArray(R()?.choices) ? R().choices : []), U = g(() => R()?.choices?.find((e) => e.id === R()?.correctChoiceId)), W = g(() => R()?.choiceMode || "text"), G = g(() => R()?.interactionMode === "audio_mc_only"), K = g(() => R()?.printAnswerKey !== !1);
23
+ var q = {
24
24
  get model() {
25
- return I();
25
+ return R();
26
26
  },
27
- set model(e = null) {
28
- I(e), g();
27
+ set model(t = null) {
28
+ R(t), e();
29
29
  }
30
- }, K = P(), q = w(K), J = (e) => {
31
- var t = E();
32
- f(t, () => T(L), !0), o(t), m(e, t);
30
+ }, J = I(), Y = C(J), te = (e) => {
31
+ var t = T();
32
+ f(t, () => w(z), !0), o(t), m(e, t);
33
33
  };
34
- v(q, (e) => {
35
- T(L) && I()?.promptEnabled !== !1 && e(J);
34
+ v(Y, (e) => {
35
+ w(z) && R()?.promptEnabled !== !1 && e(te);
36
36
  });
37
- var Y = n(q, 2), X = (e) => {
38
- var t = D();
39
- f(t, () => I().sentenceHtml, !0), o(t), m(e, t);
37
+ var X = n(Y, 2), ne = (e) => {
38
+ var t = E();
39
+ f(t, () => R().sentenceHtml, !0), o(t), m(e, t);
40
40
  };
41
- v(Y, (e) => {
42
- I()?.sentenceHtml && e(X);
41
+ v(X, (e) => {
42
+ R()?.sentenceHtml && e(ne);
43
43
  });
44
- var Z = n(Y, 2), re = (e) => {
45
- var t = k(), r = w(t);
46
- f(r, () => T(z).before);
47
- var i = n(r, 2), a = w(i), p = (e) => {
48
- var t = O();
44
+ var Z = n(X, 2), re = (e) => {
45
+ var t = O(), r = C(t);
46
+ f(r, () => w(V).before);
47
+ var i = n(r, 2), a = C(i), p = (e) => {
48
+ var t = D();
49
49
  s(() => {
50
- u(t, "src", T(V).imageUrl), u(t, "alt", T(V).imageAlt || "");
50
+ u(t, "src", w(U).imageUrl), u(t, "alt", w(U).imageAlt || "");
51
51
  }), m(e, t);
52
52
  }, h = (e) => {
53
53
  var t = l();
54
- f(c(t), () => T(V).labelHtml), m(e, t);
54
+ f(c(t), () => w(U).labelHtml), m(e, t);
55
55
  }, g = (e) => {
56
56
  m(e, d("________"));
57
57
  };
58
58
  v(a, (e) => {
59
- T(W) && T(H) === "image" && T(V)?.imageUrl ? e(p) : T(W) && T(V)?.labelHtml ? e(h, 1) : e(g, -1);
60
- }), o(i), f(n(i, 2), () => T(z).after), o(t), m(e, t);
59
+ w(K) && w(W) === "image" && w(U)?.imageUrl ? e(p) : w(K) && w(U)?.labelHtml ? e(h, 1) : e(g, -1);
60
+ }), o(i), f(n(i, 2), () => w(V).after), o(t), m(e, t);
61
61
  };
62
62
  v(Z, (e) => {
63
- T(U) || e(re);
63
+ w(G) || e(re);
64
64
  });
65
65
  var Q = n(Z, 2), ie = (e) => {
66
- var t = M(), r = w(t), i = (e) => {
67
- var t = A(), r = n(w(t));
68
- o(t), s(() => h(r, ` ${I().audioUrl ?? ""}`)), m(e, t);
66
+ var t = j(), r = C(t), i = (e) => {
67
+ var t = k(), r = n(C(t));
68
+ o(t), s(() => h(r, ` ${R().audioUrl ?? ""}`)), m(e, t);
69
69
  };
70
70
  v(r, (e) => {
71
- I()?.audioUrl && e(i);
71
+ R()?.audioUrl && e(i);
72
72
  });
73
73
  var a = n(r, 2), c = (e) => {
74
- var t = j(), r = n(w(t));
75
- o(t), s(() => h(r, ` ${I().audioTranscript ?? ""}`)), m(e, t);
74
+ var t = A(), r = n(C(t));
75
+ o(t), s(() => h(r, ` ${R().audioTranscript ?? ""}`)), m(e, t);
76
76
  };
77
77
  v(a, (e) => {
78
- I()?.audioTranscript && e(c);
78
+ R()?.audioTranscript && e(c);
79
79
  }), o(t), m(e, t);
80
80
  };
81
81
  v(Q, (e) => {
82
- I()?.hasAudio && e(ie);
82
+ R()?.hasAudio && e(ie);
83
83
  });
84
84
  var $ = n(Q, 2);
85
- return p($, 21, () => T(B), b, (e, t) => {
86
- var r = ne(), i = w(r), a = (e) => {
87
- var r = N(), i = c(r), a = w(i, !0);
85
+ return p($, 21, () => w(H), b, (e, t) => {
86
+ var r = F(), i = C(r), a = (e) => {
87
+ var r = M(), i = c(r), a = C(i, !0);
88
88
  o(i);
89
89
  var l = n(i, 2), u = (e) => {
90
90
  m(e, d("(key)"));
91
91
  };
92
92
  v(l, (e) => {
93
- T(W) && T(t).id === I()?.correctChoiceId && e(u);
94
- }), s(() => h(a, T(t).id)), m(e, r);
93
+ w(K) && w(t).id === R()?.correctChoiceId && e(u);
94
+ }), s(() => h(a, w(t).id)), m(e, r);
95
95
  }, l = (e) => {
96
- var r = te(), i = c(r);
97
- f(i, () => T(t).labelHtml || "");
96
+ var r = P(), i = c(r);
97
+ f(i, () => w(t).labelHtml || "");
98
98
  var a = n(i, 2), o = (e) => {
99
- m(e, ee());
99
+ m(e, N());
100
100
  };
101
101
  v(a, (e) => {
102
- T(W) && T(t).id === I()?.correctChoiceId && e(o);
102
+ w(K) && w(t).id === R()?.correctChoiceId && e(o);
103
103
  }), m(e, r);
104
104
  };
105
105
  v(i, (e) => {
106
- T(H) === "image" ? e(a) : e(l, -1);
106
+ w(W) === "image" ? e(a) : e(l, -1);
107
107
  }), o(r), m(e, r);
108
- }), o($), o(K), m(x, K), r(G);
108
+ }), o($), o(J), m(x, J), r(q);
109
109
  }
110
- x(I, { model: { type: "Object" } }, [], []);
110
+ x(R, { model: { type: "Object" } }, [], []);
111
111
  //#endregion
112
112
  //#region src/print/index.ts
113
- var L = I.element, R = class extends L {
113
+ var z = R.element, B = class extends z {
114
114
  _model = null;
115
115
  set model(e) {
116
116
  this._model = e, super.model = e;
@@ -120,6 +120,6 @@ var L = I.element, R = class extends L {
120
120
  }
121
121
  };
122
122
  //#endregion
123
- export { R as default };
123
+ export { B as default };
124
124
 
125
125
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/print/Print.svelte","../../../src/print/index.ts"],"sourcesContent":["<svelte:options\n customElement={{\n shadow: 'none',\n props: {\n model: { type: 'Object' },\n },\n }}\n/>\n\n<script lang=\"ts\">\nconst BLANK_TOKEN = '{{blank}}';\n\nlet { model = null }: { model?: any } = $props();\n\nlet prompt = $state('');\nlet template = $state('');\n$effect(() => {\n prompt = model?.prompt || '';\n template = model?.template || '';\n});\n\nconst parts = $derived.by(() => {\n const idx = template.indexOf(BLANK_TOKEN);\n if (idx < 0) return { before: template, after: '' };\n return { before: template.slice(0, idx), after: template.slice(idx + BLANK_TOKEN.length) };\n});\n\nconst choices = $derived(Array.isArray(model?.choices) ? model.choices : []);\nconst correct = $derived(model?.choices?.find((c: any) => c.id === model?.correctChoiceId));\nconst mode = $derived(model?.choiceMode || 'text');\nconst isAudioOnlyMode = $derived(model?.interactionMode === 'audio_mc_only');\nconst showAnswerKey = $derived(model?.printAnswerKey !== false);\n</script>\n\n<div class=\"p-4 print:p-0\">\n {#if prompt && model?.promptEnabled !== false}\n <div class=\"mb-4 prose prose-sm\">{@html prompt}</div>\n {/if}\n\n {#if model?.sentenceHtml}\n <div class=\"mb-2 prose prose-sm\">{@html model.sentenceHtml}</div>\n {/if}\n\n {#if !isAudioOnlyMode}\n <div class=\"mb-4 prose prose-sm\">\n {@html parts.before}\n <span class=\"inline-block min-w-[6rem] border-b-2 border-gray-600 print:border-black px-1\">\n {#if showAnswerKey && mode === 'image' && correct?.imageUrl}\n <img src={correct.imageUrl} alt={correct.imageAlt || ''} class=\"max-h-14 object-contain\" />\n {:else if showAnswerKey && correct?.labelHtml}\n {@html correct.labelHtml}\n {:else}\n ________\n {/if}\n </span>\n {@html parts.after}\n </div>\n {/if}\n\n {#if model?.hasAudio}\n <div class=\"text-sm mb-4\">\n {#if model?.audioUrl}\n <div><strong>Audio:</strong> {model.audioUrl}</div>\n {/if}\n {#if model?.audioTranscript}\n <div><strong>Transcript:</strong> {model.audioTranscript}</div>\n {/if}\n </div>\n {/if}\n\n <ul class=\"text-sm list-disc pl-5\">\n {#each choices as c}\n <li>\n {#if mode === 'image'}\n <span class=\"font-medium\">{c.id}</span>\n {#if showAnswerKey && c.id === model?.correctChoiceId}(key){/if}\n {:else}\n {@html c.labelHtml || ''}\n {#if showAnswerKey && c.id === model?.correctChoiceId}\n <span class=\"font-medium\"> (key)</span>\n {/if}\n {/if}\n </li>\n {/each}\n </ul>\n</div>\n\n<style>\n .prose :global(p) {\n margin: 0.5em 0;\n }\n .prose :global(strong) {\n font-weight: 600;\n }\n</style>\n","import PrintComponent from './Print.svelte';\n\nconst SvelteElementClass = (PrintComponent as any).element;\n\nclass McPopulatedBlankPrint extends SvelteElementClass {\n private _model: any = null;\n\n set model(m: any) {\n this._model = m;\n super.model = m;\n }\n\n get model() {\n return this._model;\n }\n}\n\nexport default McPopulatedBlankPrint;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/print/Print.svelte","../../../src/print/index.ts"],"sourcesContent":["<svelte:options\n customElement={{\n shadow: 'none',\n props: {\n model: { type: 'Object' },\n },\n }}\n/>\n\n<script lang=\"ts\">\nconst BLANK_TOKEN = '{{blank}}';\n\nlet { model = null }: { model?: any } = $props();\n\nlet prompt = $state('');\nlet template = $state('');\n$effect(() => {\n prompt = model?.prompt || '';\n template = model?.template || '';\n});\n\nconst parts = $derived.by(() => {\n const idx = template.indexOf(BLANK_TOKEN);\n if (idx < 0) return { before: template, after: '' };\n return { before: template.slice(0, idx), after: template.slice(idx + BLANK_TOKEN.length) };\n});\n\nconst choices = $derived(Array.isArray(model?.choices) ? model.choices : []);\nconst correct = $derived(model?.choices?.find((c: any) => c.id === model?.correctChoiceId));\nconst mode = $derived(model?.choiceMode || 'text');\nconst isAudioOnlyMode = $derived(model?.interactionMode === 'audio_mc_only');\nconst showAnswerKey = $derived(model?.printAnswerKey !== false);\n</script>\n\n<div class=\"p-4 print:p-0\">\n {#if prompt && model?.promptEnabled !== false}\n <div class=\"mb-4 prose prose-sm\">{@html prompt}</div>\n {/if}\n\n {#if model?.sentenceHtml}\n <div class=\"mb-2 prose prose-sm\">{@html model.sentenceHtml}</div>\n {/if}\n\n {#if !isAudioOnlyMode}\n <div class=\"mb-4 prose prose-sm\">\n {@html parts.before}\n <span class=\"inline-block min-w-[6rem] border-b-2 border-gray-600 print:border-black px-1\">\n {#if showAnswerKey && mode === 'image' && correct?.imageUrl}\n <img src={correct.imageUrl} alt={correct.imageAlt || ''} class=\"max-h-14 object-contain\" />\n {:else if showAnswerKey && correct?.labelHtml}\n {@html correct.labelHtml}\n {:else}\n ________\n {/if}\n </span>\n {@html parts.after}\n </div>\n {/if}\n\n {#if model?.hasAudio}\n <div class=\"text-sm mb-4\">\n {#if model?.audioUrl}\n <div><strong>Audio:</strong> {model.audioUrl}</div>\n {/if}\n {#if model?.audioTranscript}\n <div><strong>Transcript:</strong> {model.audioTranscript}</div>\n {/if}\n </div>\n {/if}\n\n <ul class=\"text-sm list-disc pl-5\">\n {#each choices as c}\n <li>\n {#if mode === 'image'}\n <span class=\"font-medium\">{c.id}</span>\n {#if showAnswerKey && c.id === model?.correctChoiceId}(key){/if}\n {:else}\n {@html c.labelHtml || ''}\n {#if showAnswerKey && c.id === model?.correctChoiceId}\n <span class=\"font-medium\"> (key)</span>\n {/if}\n {/if}\n </li>\n {/each}\n </ul>\n</div>\n\n<style>\n .prose :global(p) {\n margin: 0.5em 0;\n }\n .prose :global(strong) {\n font-weight: 600;\n }\n</style>\n","import PrintComponent from './Print.svelte';\n\nconst SvelteElementClass = (PrintComponent as any).element;\n\nclass McPopulatedBlankPrint extends SvelteElementClass {\n private _model: any = null;\n\n set model(m: any) {\n this._model = m;\n super.model = m;\n }\n\n get model() {\n return this._model;\n }\n}\n\nexport default McPopulatedBlankPrint;\n"],"mappings":"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"}
@@ -79,7 +79,6 @@ declare const _default: {
79
79
  completeAudioEnabled: boolean;
80
80
  audioUrl: string;
81
81
  audioTranscript: string;
82
- showVisibleTranscript: boolean;
83
82
  locale: string;
84
83
  teacherInstructions: string;
85
84
  teacherInstructionsEnabled: boolean;
@@ -65,7 +65,6 @@ export declare const createDefaultModel: (model?: McpbQuestion) => {
65
65
  completeAudioEnabled: boolean;
66
66
  audioUrl: string;
67
67
  audioTranscript: string;
68
- showVisibleTranscript: boolean;
69
68
  useFeatureButtonAudio?: boolean;
70
69
  locale: string;
71
70
  shuffle?: boolean;
@@ -136,7 +135,6 @@ export declare const normalize: (question?: McpbQuestion) => {
136
135
  completeAudioEnabled: boolean;
137
136
  audioUrl: string;
138
137
  audioTranscript: string;
139
- showVisibleTranscript: boolean;
140
138
  useFeatureButtonAudio?: boolean;
141
139
  locale: string;
142
140
  shuffle?: boolean;
@@ -92,7 +92,6 @@ var defaults_default = {
92
92
  completeAudioEnabled: false,
93
93
  audioUrl: "",
94
94
  audioTranscript: "",
95
- showVisibleTranscript: false,
96
95
  locale: "",
97
96
  teacherInstructions: "",
98
97
  teacherInstructionsEnabled: false
@@ -219,7 +218,6 @@ var model = async (question, session, env, updateSession) => {
219
218
  completeAudioEnabled: !!normalizedQuestion.completeAudioEnabled,
220
219
  audioUrl: normalizedQuestion.hasAudio ? normalizedQuestion.audioUrl : null,
221
220
  audioTranscript: normalizedQuestion.hasAudio ? normalizedQuestion.audioTranscript : null,
222
- showVisibleTranscript: !!normalizedQuestion.showVisibleTranscript,
223
221
  customType: normalizedQuestion.customType || "",
224
222
  useFeatureButtonAudio: typeof normalizedQuestion.useFeatureButtonAudio === "boolean" ? normalizedQuestion.useFeatureButtonAudio : void 0,
225
223
  locale: normalizedQuestion.locale || "",
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/shared/layoutLimits.ts","../../src/controller/defaults.ts","../../src/controller/index.ts"],"sourcesContent":["export type LayoutLimits = {\n blankStandaloneWidthRem: number;\n blankWideWidthRem: number;\n blankUnderlineWidthPx: number;\n blankUnderlineWideWidthPx: number;\n horizontalChoiceWidthPx: number;\n horizontalChoiceWidthVw: number;\n horizontalChoiceTileMinHeightRem: number;\n horizontalChoiceContentMinHeightRem: number;\n selectedImageMaxHeightRem: number;\n choiceImageMaxHeightRem: number;\n listenButtonSizePx: number;\n stimulusMinColumnPx: number;\n textMinColumnPx: number;\n legendMaxChars: number;\n choiceGroupGapRem: number;\n choiceRowGapRem: number;\n toggleButtonGapRem: number;\n horizontalChoiceRadioTopMarginRem: number;\n audioBlankTemplateMarginTopRem: number;\n audioBlankTemplateMarginBottomRem: number;\n audioInstructionsMaxWidthPx: number;\n narrowHorizontalChoiceMaxWidthPx: number;\n stimulusGridColumnGapRem: number;\n stimulusGridRowGapRem: number;\n stimulusSentenceMarginTopRem: number;\n stimulusChoicesMarginTopRem: number;\n tokenGridColumnGapRem: number;\n tokenGridRowGapRem: number;\n tokenTemplateMarginTopRem: number;\n tokenInlineTokenGapRem: number;\n tokenChoicesMarginTopRem: number;\n inlineGridColumnGapRem: number;\n inlineGridRowGapRem: number;\n inlineTemplateMarginTopRem: number;\n inlineChoicesMarginTopRem: number;\n};\n\n/** Baseline values tuned to match historical CQT visuals; override via model.layoutLimits. */\nexport const DEFAULT_LAYOUT_LIMITS: LayoutLimits = {\n blankStandaloneWidthRem: 7,\n blankWideWidthRem: 10,\n blankUnderlineWidthPx: 2,\n blankUnderlineWideWidthPx: 4,\n horizontalChoiceWidthPx: 170,\n horizontalChoiceWidthVw: 30,\n horizontalChoiceTileMinHeightRem: 11,\n horizontalChoiceContentMinHeightRem: 7.5,\n selectedImageMaxHeightRem: 4,\n choiceImageMaxHeightRem: 5,\n listenButtonSizePx: 128,\n stimulusMinColumnPx: 210,\n textMinColumnPx: 260,\n legendMaxChars: 120,\n choiceGroupGapRem: 0.5,\n choiceRowGapRem: 0.5,\n toggleButtonGapRem: 0.5,\n horizontalChoiceRadioTopMarginRem: 0.5,\n audioBlankTemplateMarginTopRem: 0.8,\n audioBlankTemplateMarginBottomRem: 1.8,\n audioInstructionsMaxWidthPx: 875,\n narrowHorizontalChoiceMaxWidthPx: 230,\n stimulusGridColumnGapRem: 2,\n stimulusGridRowGapRem: 0.7,\n stimulusSentenceMarginTopRem: 0.2,\n stimulusChoicesMarginTopRem: 0.9,\n tokenGridColumnGapRem: 1.5,\n tokenGridRowGapRem: 0.8,\n tokenTemplateMarginTopRem: 0.6,\n tokenInlineTokenGapRem: 0.35,\n tokenChoicesMarginTopRem: 0.2,\n inlineGridColumnGapRem: 1.5,\n inlineGridRowGapRem: 0.65,\n inlineTemplateMarginTopRem: 0.45,\n inlineChoicesMarginTopRem: 0.25,\n};\n","import { DEFAULT_LAYOUT_LIMITS } from '../shared/layoutLimits';\n\nexport { DEFAULT_LAYOUT_LIMITS };\n\n/** Token authors must include exactly once in `template` (HTML). */\nexport const BLANK_TOKEN = '{{blank}}';\n\nexport default {\n model: {\n id: '1',\n element: 'mc-populated-blank',\n prompt: '<p><strong>Demo prompt</strong></p>',\n promptEnabled: true,\n interactionMode: 'populate_blank' as const,\n layoutProfile: '',\n choiceLayout: '',\n layoutProfilePresets: {},\n layoutLimits: { ...DEFAULT_LAYOUT_LIMITS },\n audioButtonSkin: null,\n audioButtonSkinsByLocale: {},\n uiText: {\n answerChoices: 'Answer choices',\n selectedAnswerInSentence: 'blank',\n showCorrectAnswer: 'Show correct answer',\n hideCorrectAnswer: 'Hide correct answer',\n clickToEnableAutoplay: 'Click to enable audio autoplay',\n audioResourceUnavailable: 'Audio is enabled but no playable audio URL is configured.',\n transcriptLabel: 'Transcript',\n listenLabelEn: 'Listen',\n listenLabelEs: 'Escuchar',\n listenSilentAlt: 'Repeat instructions',\n listenPlayingAlt: 'Instructions are playing',\n listenSilentAltEs: 'Escuchar. Repetir las instrucciones.',\n listenPlayingAltEs: 'Escuchar. Estas son las instrucciones.',\n },\n sentenceHtml: '',\n template: `<p>The answer is ${BLANK_TOKEN}.</p>`,\n choiceMode: 'text' as const,\n choices: [\n { id: 'c1', labelHtml: '<p>Option A</p>' },\n { id: 'c2', labelHtml: '<p>Option B</p>' },\n { id: 'c3', labelHtml: '<p>Option C</p>' },\n ],\n correctChoiceId: 'c2',\n hasAudio: false,\n autoplayAudioEnabled: false,\n completeAudioEnabled: false,\n audioUrl: '',\n audioTranscript: '',\n showVisibleTranscript: false,\n locale: '',\n teacherInstructions: '',\n teacherInstructionsEnabled: false,\n },\n configuration: {\n prompt: {\n label: 'Prompt',\n settings: true,\n },\n },\n};\n","import defaults, { BLANK_TOKEN, DEFAULT_LAYOUT_LIMITS } from './defaults';\nimport type {\n McpbChoice,\n McpbQuestion,\n McpbSession,\n McpbEnv,\n McpbCorrectness,\n} from '../shared/types';\n\nconst isEmptyObject = (value: unknown): boolean =>\n !!value &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.keys(value as Record<string, unknown>).length === 0;\n\nexport function countBlankTokens(template: string): number {\n if (!template) return 0;\n const re = /\\{\\{blank\\}\\}/g;\n return (template.match(re) || []).length;\n}\n\nexport const getCorrectness = (question: McpbQuestion, session: McpbSession): McpbCorrectness => {\n if (!session?.choiceId) {\n return 'unanswered';\n }\n const correct = question?.correctChoiceId || '';\n if (session.choiceId === correct) {\n return 'correct';\n }\n return 'incorrect';\n};\n\nexport const getPartialScore = (_question: McpbQuestion, session: McpbSession) => {\n if (!session || isEmptyObject(session) || !session.choiceId) {\n return 0;\n }\n return 1;\n};\n\nexport const outcome = (question: McpbQuestion, session: McpbSession, env: McpbEnv) =>\n new Promise((resolve) => {\n if (!session || isEmptyObject(session)) {\n resolve({\n score: 0,\n empty: true,\n traceLog: ['Student did not select any answers. Score is 0.'],\n });\n return;\n }\n\n session = normalizeSession(session);\n const correctness = getCorrectness(question, session);\n\n if (correctness === 'unanswered') {\n resolve({\n score: 0,\n empty: true,\n traceLog: ['Student did not select any answers. Score is 0.'],\n });\n return;\n }\n\n const score = correctness === 'correct' ? 1 : 0;\n const traceLog = [\n `Mode: ${env?.mode || 'unknown'}.`,\n `Student selected choice: ${session.choiceId}.`,\n `Correct choice: ${question?.correctChoiceId || 'none'}.`,\n `Final score: ${score}.`,\n ];\n resolve({ score, empty: false, traceLog });\n });\n\nexport const createDefaultModel = (model: McpbQuestion = {}) => ({\n ...defaults.model,\n ...model,\n layoutLimits: {\n ...DEFAULT_LAYOUT_LIMITS,\n ...(model?.layoutLimits || {}),\n },\n});\n\nexport const normalize = (question: McpbQuestion = {}) => createDefaultModel(question);\n\nexport const normalizeSession = (s: McpbSession): McpbSession => ({ ...s });\n\nconst shouldShuffleChoices = (question: McpbQuestion) => !!question?.shuffle;\n\nconst shouldLockChoices = (question: McpbQuestion, env: McpbEnv) => {\n if (question?.lockChoiceOrder) return true;\n if (env?.['@pie-element']?.lockChoiceOrder) return true;\n return env?.role === 'instructor';\n};\n\nfunction shuffleArray<T>(items: T[]): T[] {\n const out = [...items];\n for (let i = out.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [out[i], out[j]] = [out[j], out[i]];\n }\n return out;\n}\n\nconst getStoredShuffle = (session: McpbSession): string[] =>\n Array.isArray(session?.data?.shuffledValues)\n ? session.data.shuffledValues\n : Array.isArray(session?.shuffledValues)\n ? session.shuffledValues\n : [];\n\nconst applyShuffledValues = (\n choices: McpbChoice[],\n shuffledValues: string[],\n choiceKey: keyof McpbChoice\n) => {\n const orderedChoices = shuffledValues\n .map((value) => choices.find((choice) => choice?.[choiceKey] === value))\n .filter((c): c is McpbChoice => !!c);\n\n if (orderedChoices.length === choices.length) {\n return orderedChoices;\n }\n\n const orderedValues = new Set(orderedChoices.map((choice) => choice[choiceKey]));\n const leftovers = choices.filter((choice) => !orderedValues.has(choice?.[choiceKey]));\n return [...orderedChoices, ...leftovers];\n};\n\ntype UpdateSessionFn = (\n id: string,\n element: string,\n data: { shuffledValues: string[] }\n) => Promise<void>;\n\nconst getOrderedChoices = async (\n question: McpbQuestion,\n session: McpbSession,\n env: McpbEnv,\n updateSession?: UpdateSessionFn\n) => {\n const choices = Array.isArray(question?.choices) ? [...question.choices] : [];\n if (!choices.length || !shouldShuffleChoices(question)) {\n return choices;\n }\n\n if (shouldLockChoices(question, env || {})) {\n return choices;\n }\n\n const shuffledValues = getStoredShuffle(session);\n if (shuffledValues.length) {\n return applyShuffledValues(choices, shuffledValues, 'id');\n }\n\n const shuffledChoices = shuffleArray(choices);\n\n if (updateSession && typeof updateSession === 'function' && session?.id && session?.element) {\n const shuffledIds = shuffledChoices.map((choice) => choice?.id).filter(Boolean);\n if (shuffledIds.length) {\n await updateSession(session.id, session.element, { shuffledValues: shuffledIds });\n }\n }\n\n return shuffledChoices;\n};\n\nexport const model = async (\n question: McpbQuestion,\n session: McpbSession | null,\n env: McpbEnv | null,\n updateSession?: UpdateSessionFn\n) => {\n const safeSession: McpbSession = session || {};\n const safeEnv: McpbEnv = env || {};\n const normalizedQuestion = normalize(question);\n const choices = await getOrderedChoices(normalizedQuestion, safeSession, safeEnv, updateSession);\n\n const out: Record<string, unknown> = {\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n interactionMode: normalizedQuestion.interactionMode || 'populate_blank',\n layoutProfile: normalizedQuestion.layoutProfile || '',\n choiceLayout: normalizedQuestion.choiceLayout || '',\n layoutProfilePresets:\n normalizedQuestion.layoutProfilePresets &&\n typeof normalizedQuestion.layoutProfilePresets === 'object'\n ? normalizedQuestion.layoutProfilePresets\n : {},\n layoutLimits: normalizedQuestion.layoutLimits || { ...DEFAULT_LAYOUT_LIMITS },\n audioButtonSkin:\n normalizedQuestion.audioButtonSkin && typeof normalizedQuestion.audioButtonSkin === 'object'\n ? normalizedQuestion.audioButtonSkin\n : null,\n audioButtonSkinsByLocale:\n normalizedQuestion.audioButtonSkinsByLocale &&\n typeof normalizedQuestion.audioButtonSkinsByLocale === 'object'\n ? normalizedQuestion.audioButtonSkinsByLocale\n : {},\n uiText:\n normalizedQuestion.uiText && typeof normalizedQuestion.uiText === 'object'\n ? normalizedQuestion.uiText\n : {},\n sentenceHtml: normalizedQuestion.sentenceHtml || null,\n template: normalizedQuestion.template,\n choiceMode: normalizedQuestion.choiceMode,\n choices,\n hasAudio: normalizedQuestion.hasAudio,\n autoplayAudioEnabled: !!normalizedQuestion.autoplayAudioEnabled,\n completeAudioEnabled: !!normalizedQuestion.completeAudioEnabled,\n audioUrl: normalizedQuestion.hasAudio ? normalizedQuestion.audioUrl : null,\n audioTranscript: normalizedQuestion.hasAudio ? normalizedQuestion.audioTranscript : null,\n showVisibleTranscript: !!normalizedQuestion.showVisibleTranscript,\n customType: normalizedQuestion.customType || '',\n useFeatureButtonAudio:\n typeof normalizedQuestion.useFeatureButtonAudio === 'boolean'\n ? normalizedQuestion.useFeatureButtonAudio\n : undefined,\n locale: normalizedQuestion.locale || '',\n disabled: safeEnv.mode !== 'gather',\n mode: safeEnv.mode,\n };\n\n if (safeEnv.mode === 'evaluate') {\n const correctness = getCorrectness(normalizedQuestion, safeSession);\n out.correctness = correctness;\n out.responseCorrect = correctness === 'correct';\n out.correctChoiceId = normalizedQuestion.correctChoiceId;\n }\n\n if (safeEnv.role === 'instructor' && (safeEnv.mode === 'view' || safeEnv.mode === 'evaluate')) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n return out;\n};\n\nexport const createCorrectResponseSession = (question: McpbQuestion, env: McpbEnv) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n resolve({\n id: '1',\n element: 'mc-populated-blank',\n choiceId: question?.correctChoiceId || '',\n });\n } else {\n resolve(null);\n }\n });\n};\n\nexport const validate = (question: McpbQuestion = {}, _config: Record<string, unknown> = {}) => {\n const errors: Record<string, string> = {};\n\n if (question.promptEnabled) {\n const p = question.prompt?.trim() || '';\n if (!p || p === '<p></p>') {\n errors.prompt = 'Prompt is required when prompt is enabled';\n }\n }\n\n const interactionMode = question.interactionMode || 'populate_blank';\n const template = question.template || '';\n const n = countBlankTokens(template);\n if (interactionMode === 'audio_mc_only') {\n if (n > 0) {\n errors.template = `Template cannot contain ${BLANK_TOKEN} in audio-only mode`;\n }\n } else if (interactionMode === 'populate_blank') {\n if (n === 0) {\n errors.template = `Template must contain exactly one ${BLANK_TOKEN} placeholder`;\n } else if (n > 1) {\n errors.template = `Template must contain only one ${BLANK_TOKEN} placeholder`;\n }\n } else {\n errors.interactionMode = 'Unknown interaction mode';\n }\n\n const choices = Array.isArray(question.choices) ? question.choices : [];\n if (choices.length < 2) {\n errors.choices = 'At least two choices are required';\n }\n\n const mode = question.choiceMode || 'text';\n for (let i = 0; i < choices.length; i++) {\n const c = choices[i];\n if (!c?.id) {\n errors.choices = `Choice ${i + 1} is missing an id`;\n break;\n }\n if (mode === 'text') {\n const lbl = (c.labelHtml || '').trim();\n if (!lbl || lbl === '<p></p>') {\n errors.choices = `Choice ${i + 1} needs label text`;\n break;\n }\n } else {\n if (!c.imageUrl?.trim()) {\n errors.choices = `Choice ${i + 1} needs an image URL`;\n break;\n }\n if (!c.imageAlt?.trim()) {\n errors.choices = `Choice ${i + 1} needs image alt text`;\n break;\n }\n }\n }\n\n const correct = question.correctChoiceId;\n if (!correct || !choices.some((c) => c.id === correct)) {\n errors.correctChoiceId = 'Correct choice must match one of the choice ids';\n }\n\n if (question.hasAudio) {\n const hasAudioUrl = !!question.audioUrl?.trim();\n if (!hasAudioUrl) {\n errors.audioUrl = 'A playable audio URL is required when audio is enabled';\n }\n }\n\n const limits = question?.layoutLimits;\n if (limits && typeof limits === 'object') {\n const numericLimitKeys = [\n 'blankStandaloneWidthRem',\n 'blankWideWidthRem',\n 'blankUnderlineWidthPx',\n 'blankUnderlineWideWidthPx',\n 'horizontalChoiceWidthPx',\n 'horizontalChoiceWidthVw',\n 'horizontalChoiceTileMinHeightRem',\n 'horizontalChoiceContentMinHeightRem',\n 'selectedImageMaxHeightRem',\n 'choiceImageMaxHeightRem',\n 'listenButtonSizePx',\n 'stimulusMinColumnPx',\n 'textMinColumnPx',\n 'legendMaxChars',\n 'choiceGroupGapRem',\n 'choiceRowGapRem',\n 'toggleButtonGapRem',\n 'horizontalChoiceRadioTopMarginRem',\n 'audioBlankTemplateMarginTopRem',\n 'audioBlankTemplateMarginBottomRem',\n 'audioInstructionsMaxWidthPx',\n 'narrowHorizontalChoiceMaxWidthPx',\n 'stimulusGridColumnGapRem',\n 'stimulusGridRowGapRem',\n 'stimulusSentenceMarginTopRem',\n 'stimulusChoicesMarginTopRem',\n 'tokenGridColumnGapRem',\n 'tokenGridRowGapRem',\n 'tokenTemplateMarginTopRem',\n 'tokenInlineTokenGapRem',\n 'tokenChoicesMarginTopRem',\n 'inlineGridColumnGapRem',\n 'inlineGridRowGapRem',\n 'inlineTemplateMarginTopRem',\n 'inlineChoicesMarginTopRem',\n ] as const;\n for (const key of numericLimitKeys) {\n if (limits[key] === undefined || limits[key] === null) continue;\n const value = Number(limits[key]);\n if (!Number.isFinite(value) || value <= 0) {\n errors.layoutLimits = `${key} must be a positive number when provided`;\n break;\n }\n }\n }\n\n return errors;\n};\n"],"mappings":";;AAuCA,IAAa,wBAAsC;CACjD,yBAAyB;CACzB,mBAAmB;CACnB,uBAAuB;CACvB,2BAA2B;CAC3B,yBAAyB;CACzB,yBAAyB;CACzB,kCAAkC;CAClC,qCAAqC;CACrC,2BAA2B;CAC3B,yBAAyB;CACzB,oBAAoB;CACpB,qBAAqB;CACrB,iBAAiB;CACjB,gBAAgB;CAChB,mBAAmB;CACnB,iBAAiB;CACjB,oBAAoB;CACpB,mCAAmC;CACnC,gCAAgC;CAChC,mCAAmC;CACnC,6BAA6B;CAC7B,kCAAkC;CAClC,0BAA0B;CAC1B,uBAAuB;CACvB,8BAA8B;CAC9B,6BAA6B;CAC7B,uBAAuB;CACvB,oBAAoB;CACpB,2BAA2B;CAC3B,wBAAwB;CACxB,0BAA0B;CAC1B,wBAAwB;CACxB,qBAAqB;CACrB,4BAA4B;CAC5B,2BAA2B;AAC7B;;;;ACtEA,IAAa,cAAc;AAE3B,IAAA,mBAAe;CACb,OAAO;EACL,IAAI;EACJ,SAAS;EACT,QAAQ;EACR,eAAe;EACf,iBAAiB;EACjB,eAAe;EACf,cAAc;EACd,sBAAsB,CAAC;EACvB,cAAc,EAAE,GAAG,sBAAsB;EACzC,iBAAiB;EACjB,0BAA0B,CAAC;EAC3B,QAAQ;GACN,eAAe;GACf,0BAA0B;GAC1B,mBAAmB;GACnB,mBAAmB;GACnB,uBAAuB;GACvB,0BAA0B;GAC1B,iBAAiB;GACjB,eAAe;GACf,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,mBAAmB;GACnB,oBAAoB;EACtB;EACA,cAAc;EACd,UAAU,oBAAoB,YAAY;EAC1C,YAAY;EACZ,SAAS;GACP;IAAE,IAAI;IAAM,WAAW;GAAkB;GACzC;IAAE,IAAI;IAAM,WAAW;GAAkB;GACzC;IAAE,IAAI;IAAM,WAAW;GAAkB;EAC3C;EACA,iBAAiB;EACjB,UAAU;EACV,sBAAsB;EACtB,sBAAsB;EACtB,UAAU;EACV,iBAAiB;EACjB,uBAAuB;EACvB,QAAQ;EACR,qBAAqB;EACrB,4BAA4B;CAC9B;CACA,eAAe,EACb,QAAQ;EACN,OAAO;EACP,UAAU;CACZ,EACF;AACF;;;ACnDA,IAAM,iBAAiB,UACrB,CAAC,CAAC,SACF,OAAO,UAAU,YACjB,CAAC,MAAM,QAAQ,KAAK,KACpB,OAAO,KAAK,KAAgC,EAAE,WAAW;AAE3D,SAAgB,iBAAiB,UAA0B;CACzD,IAAI,CAAC,UAAU,OAAO;CAEtB,QAAQ,SAAS,MAAM,gBAAE,KAAK,CAAC,GAAG;AACpC;AAEA,IAAa,kBAAkB,UAAwB,YAA0C;CAC/F,IAAI,CAAC,SAAS,UACZ,OAAO;CAET,MAAM,UAAU,UAAU,mBAAmB;CAC7C,IAAI,QAAQ,aAAa,SACvB,OAAO;CAET,OAAO;AACT;AAEA,IAAa,mBAAmB,WAAyB,YAAyB;CAChF,IAAI,CAAC,WAAW,cAAc,OAAO,KAAK,CAAC,QAAQ,UACjD,OAAO;CAET,OAAO;AACT;AAEA,IAAa,WAAW,UAAwB,SAAsB,QACpE,IAAI,SAAS,YAAY;CACvB,IAAI,CAAC,WAAW,cAAc,OAAO,GAAG;EACtC,QAAQ;GACN,OAAO;GACP,OAAO;GACP,UAAU,CAAC,iDAAiD;EAC9D,CAAC;EACD;CACF;CAEA,UAAU,iBAAiB,OAAO;CAClC,MAAM,cAAc,eAAe,UAAU,OAAO;CAEpD,IAAI,gBAAgB,cAAc;EAChC,QAAQ;GACN,OAAO;GACP,OAAO;GACP,UAAU,CAAC,iDAAiD;EAC9D,CAAC;EACD;CACF;CAEA,MAAM,QAAQ,gBAAgB,YAAY,IAAI;CAO9C,QAAQ;EAAE;EAAO,OAAO;EAAO,UAAA;GAL7B,SAAS,KAAK,QAAQ,UAAU;GAChC,4BAA4B,QAAQ,SAAS;GAC7C,mBAAmB,UAAU,mBAAmB,OAAO;GACvD,gBAAgB,MAAM;EAEO;CAAS,CAAC;AAC3C,CAAC;AAEH,IAAa,sBAAsB,QAAsB,CAAC,OAAO;CAC/D,GAAG,iBAAS;CACZ,GAAG;CACH,cAAc;EACZ,GAAG;EACH,GAAI,OAAO,gBAAgB,CAAC;CAC9B;AACF;AAEA,IAAa,aAAa,WAAyB,CAAC,MAAM,mBAAmB,QAAQ;AAErF,IAAa,oBAAoB,OAAiC,EAAE,GAAG,EAAE;AAEzE,IAAM,wBAAwB,aAA2B,CAAC,CAAC,UAAU;AAErE,IAAM,qBAAqB,UAAwB,QAAiB;CAClE,IAAI,UAAU,iBAAiB,OAAO;CACtC,IAAI,MAAM,iBAAiB,iBAAiB,OAAO;CACnD,OAAO,KAAK,SAAS;AACvB;AAEA,SAAS,aAAgB,OAAiB;CACxC,MAAM,MAAM,CAAC,GAAG,KAAK;CACrB,KAAK,IAAI,IAAI,IAAI,SAAS,GAAG,IAAI,GAAG,KAAK;EACvC,MAAM,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,EAAE;EAC5C,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE;CACpC;CACA,OAAO;AACT;AAEA,IAAM,oBAAoB,YACxB,MAAM,QAAQ,SAAS,MAAM,cAAc,IACvC,QAAQ,KAAK,iBACb,MAAM,QAAQ,SAAS,cAAc,IACnC,QAAQ,iBACR,CAAC;AAET,IAAM,uBACJ,SACA,gBACA,cACG;CACH,MAAM,iBAAiB,eACpB,KAAK,UAAU,QAAQ,MAAM,WAAW,SAAS,eAAe,KAAK,CAAC,EACtE,QAAQ,MAAuB,CAAC,CAAC,CAAC;CAErC,IAAI,eAAe,WAAW,QAAQ,QACpC,OAAO;CAGT,MAAM,gBAAgB,IAAI,IAAI,eAAe,KAAK,WAAW,OAAO,UAAU,CAAC;CAC/E,MAAM,YAAY,QAAQ,QAAQ,WAAW,CAAC,cAAc,IAAI,SAAS,UAAU,CAAC;CACpF,OAAO,CAAC,GAAG,gBAAgB,GAAG,SAAS;AACzC;AAQA,IAAM,oBAAoB,OACxB,UACA,SACA,KACA,kBACG;CACH,MAAM,UAAU,MAAM,QAAQ,UAAU,OAAO,IAAI,CAAC,GAAG,SAAS,OAAO,IAAI,CAAC;CAC5E,IAAI,CAAC,QAAQ,UAAU,CAAC,qBAAqB,QAAQ,GACnD,OAAO;CAGT,IAAI,kBAAkB,UAAU,OAAO,CAAC,CAAC,GACvC,OAAO;CAGT,MAAM,iBAAiB,iBAAiB,OAAO;CAC/C,IAAI,eAAe,QACjB,OAAO,oBAAoB,SAAS,gBAAgB,IAAI;CAG1D,MAAM,kBAAkB,aAAa,OAAO;CAE5C,IAAI,iBAAiB,OAAO,kBAAkB,cAAc,SAAS,MAAM,SAAS,SAAS;EAC3F,MAAM,cAAc,gBAAgB,KAAK,WAAW,QAAQ,EAAE,EAAE,OAAO,OAAO;EAC9E,IAAI,YAAY,QACd,MAAM,cAAc,QAAQ,IAAI,QAAQ,SAAS,EAAE,gBAAgB,YAAY,CAAC;CAEpF;CAEA,OAAO;AACT;AAEA,IAAa,QAAQ,OACnB,UACA,SACA,KACA,kBACG;CACH,MAAM,cAA2B,WAAW,CAAC;CAC7C,MAAM,UAAmB,OAAO,CAAC;CACjC,MAAM,qBAAqB,UAAU,QAAQ;CAC7C,MAAM,UAAU,MAAM,kBAAkB,oBAAoB,aAAa,SAAS,aAAa;CAE/F,MAAM,MAA+B;EACnC,QAAQ,mBAAmB,gBAAgB,mBAAmB,SAAS;EACvE,iBAAiB,mBAAmB,mBAAmB;EACvD,eAAe,mBAAmB,iBAAiB;EACnD,cAAc,mBAAmB,gBAAgB;EACjD,sBACE,mBAAmB,wBACnB,OAAO,mBAAmB,yBAAyB,WAC/C,mBAAmB,uBACnB,CAAC;EACP,cAAc,mBAAmB,gBAAgB,EAAE,GAAG,sBAAsB;EAC5E,iBACE,mBAAmB,mBAAmB,OAAO,mBAAmB,oBAAoB,WAChF,mBAAmB,kBACnB;EACN,0BACE,mBAAmB,4BACnB,OAAO,mBAAmB,6BAA6B,WACnD,mBAAmB,2BACnB,CAAC;EACP,QACE,mBAAmB,UAAU,OAAO,mBAAmB,WAAW,WAC9D,mBAAmB,SACnB,CAAC;EACP,cAAc,mBAAmB,gBAAgB;EACjD,UAAU,mBAAmB;EAC7B,YAAY,mBAAmB;EAC/B;EACA,UAAU,mBAAmB;EAC7B,sBAAsB,CAAC,CAAC,mBAAmB;EAC3C,sBAAsB,CAAC,CAAC,mBAAmB;EAC3C,UAAU,mBAAmB,WAAW,mBAAmB,WAAW;EACtE,iBAAiB,mBAAmB,WAAW,mBAAmB,kBAAkB;EACpF,uBAAuB,CAAC,CAAC,mBAAmB;EAC5C,YAAY,mBAAmB,cAAc;EAC7C,uBACE,OAAO,mBAAmB,0BAA0B,YAChD,mBAAmB,wBACnB,KAAA;EACN,QAAQ,mBAAmB,UAAU;EACrC,UAAU,QAAQ,SAAS;EAC3B,MAAM,QAAQ;CAChB;CAEA,IAAI,QAAQ,SAAS,YAAY;EAC/B,MAAM,cAAc,eAAe,oBAAoB,WAAW;EAClE,IAAI,cAAc;EAClB,IAAI,kBAAkB,gBAAgB;EACtC,IAAI,kBAAkB,mBAAmB;CAC3C;CAEA,IAAI,QAAQ,SAAS,iBAAiB,QAAQ,SAAS,UAAU,QAAQ,SAAS,aAChF,IAAI,sBAAsB,mBAAmB,6BACzC,mBAAmB,sBACnB;MAEJ,IAAI,sBAAsB;CAG5B,OAAO;AACT;AAEA,IAAa,gCAAgC,UAAwB,QAAiB;CACpF,OAAO,IAAI,SAAS,YAAY;EAC9B,IAAI,IAAI,SAAS,cAAc,IAAI,SAAS,cAC1C,QAAQ;GACN,IAAI;GACJ,SAAS;GACT,UAAU,UAAU,mBAAmB;EACzC,CAAC;OAED,QAAQ,IAAI;CAEhB,CAAC;AACH;AAEA,IAAa,YAAY,WAAyB,CAAC,GAAG,UAAmC,CAAC,MAAM;CAC9F,MAAM,SAAiC,CAAC;CAExC,IAAI,SAAS,eAAe;EAC1B,MAAM,IAAI,SAAS,QAAQ,KAAK,KAAK;EACrC,IAAI,CAAC,KAAK,MAAM,WACd,OAAO,SAAS;CAEpB;CAEA,MAAM,kBAAkB,SAAS,mBAAmB;CAEpD,MAAM,IAAI,iBADO,SAAS,YAAY,EACH;CACnC,IAAI,oBAAoB;MAClB,IAAI,GACN,OAAO,WAAW,2BAA2B,YAAY;CAAA,OAEtD,IAAI,oBAAoB;MACzB,MAAM,GACR,OAAO,WAAW,qCAAqC,YAAY;OAC9D,IAAI,IAAI,GACb,OAAO,WAAW,kCAAkC,YAAY;CAAA,OAGlE,OAAO,kBAAkB;CAG3B,MAAM,UAAU,MAAM,QAAQ,SAAS,OAAO,IAAI,SAAS,UAAU,CAAC;CACtE,IAAI,QAAQ,SAAS,GACnB,OAAO,UAAU;CAGnB,MAAM,OAAO,SAAS,cAAc;CACpC,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,IAAI,QAAQ;EAClB,IAAI,CAAC,GAAG,IAAI;GACV,OAAO,UAAU,UAAU,IAAI,EAAE;GACjC;EACF;EACA,IAAI,SAAS,QAAQ;GACnB,MAAM,OAAO,EAAE,aAAa,IAAI,KAAK;GACrC,IAAI,CAAC,OAAO,QAAQ,WAAW;IAC7B,OAAO,UAAU,UAAU,IAAI,EAAE;IACjC;GACF;EACF,OAAO;GACL,IAAI,CAAC,EAAE,UAAU,KAAK,GAAG;IACvB,OAAO,UAAU,UAAU,IAAI,EAAE;IACjC;GACF;GACA,IAAI,CAAC,EAAE,UAAU,KAAK,GAAG;IACvB,OAAO,UAAU,UAAU,IAAI,EAAE;IACjC;GACF;EACF;CACF;CAEA,MAAM,UAAU,SAAS;CACzB,IAAI,CAAC,WAAW,CAAC,QAAQ,MAAM,MAAM,EAAE,OAAO,OAAO,GACnD,OAAO,kBAAkB;CAG3B,IAAI,SAAS;MAEP,CAAC,CADgB,CAAC,SAAS,UAAU,KAAK,GAE5C,OAAO,WAAW;CAAA;CAItB,MAAM,SAAS,UAAU;CACzB,IAAI,UAAU,OAAO,WAAW,UAsC9B,KAAK,MAAM,OAAO;EApChB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAEgB,GAAkB;EAClC,IAAI,OAAO,SAAS,KAAA,KAAa,OAAO,SAAS,MAAM;EACvD,MAAM,QAAQ,OAAO,OAAO,IAAI;EAChC,IAAI,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,GAAG;GACzC,OAAO,eAAe,GAAG,IAAI;GAC7B;EACF;CACF;CAGF,OAAO;AACT"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/shared/layoutLimits.ts","../../src/controller/defaults.ts","../../src/controller/index.ts"],"sourcesContent":["export type LayoutLimits = {\n blankStandaloneWidthRem: number;\n blankWideWidthRem: number;\n blankUnderlineWidthPx: number;\n blankUnderlineWideWidthPx: number;\n horizontalChoiceWidthPx: number;\n horizontalChoiceWidthVw: number;\n horizontalChoiceTileMinHeightRem: number;\n horizontalChoiceContentMinHeightRem: number;\n selectedImageMaxHeightRem: number;\n choiceImageMaxHeightRem: number;\n listenButtonSizePx: number;\n stimulusMinColumnPx: number;\n textMinColumnPx: number;\n legendMaxChars: number;\n choiceGroupGapRem: number;\n choiceRowGapRem: number;\n toggleButtonGapRem: number;\n horizontalChoiceRadioTopMarginRem: number;\n audioBlankTemplateMarginTopRem: number;\n audioBlankTemplateMarginBottomRem: number;\n audioInstructionsMaxWidthPx: number;\n narrowHorizontalChoiceMaxWidthPx: number;\n stimulusGridColumnGapRem: number;\n stimulusGridRowGapRem: number;\n stimulusSentenceMarginTopRem: number;\n stimulusChoicesMarginTopRem: number;\n tokenGridColumnGapRem: number;\n tokenGridRowGapRem: number;\n tokenTemplateMarginTopRem: number;\n tokenInlineTokenGapRem: number;\n tokenChoicesMarginTopRem: number;\n inlineGridColumnGapRem: number;\n inlineGridRowGapRem: number;\n inlineTemplateMarginTopRem: number;\n inlineChoicesMarginTopRem: number;\n};\n\n/** Baseline values tuned to match historical CQT visuals; override via model.layoutLimits. */\nexport const DEFAULT_LAYOUT_LIMITS: LayoutLimits = {\n blankStandaloneWidthRem: 7,\n blankWideWidthRem: 10,\n blankUnderlineWidthPx: 2,\n blankUnderlineWideWidthPx: 4,\n horizontalChoiceWidthPx: 170,\n horizontalChoiceWidthVw: 30,\n horizontalChoiceTileMinHeightRem: 11,\n horizontalChoiceContentMinHeightRem: 7.5,\n selectedImageMaxHeightRem: 4,\n choiceImageMaxHeightRem: 5,\n listenButtonSizePx: 128,\n stimulusMinColumnPx: 210,\n textMinColumnPx: 260,\n legendMaxChars: 120,\n choiceGroupGapRem: 0.5,\n choiceRowGapRem: 0.5,\n toggleButtonGapRem: 0.5,\n horizontalChoiceRadioTopMarginRem: 0.5,\n audioBlankTemplateMarginTopRem: 0.8,\n audioBlankTemplateMarginBottomRem: 1.8,\n audioInstructionsMaxWidthPx: 875,\n narrowHorizontalChoiceMaxWidthPx: 230,\n stimulusGridColumnGapRem: 2,\n stimulusGridRowGapRem: 0.7,\n stimulusSentenceMarginTopRem: 0.2,\n stimulusChoicesMarginTopRem: 0.9,\n tokenGridColumnGapRem: 1.5,\n tokenGridRowGapRem: 0.8,\n tokenTemplateMarginTopRem: 0.6,\n tokenInlineTokenGapRem: 0.35,\n tokenChoicesMarginTopRem: 0.2,\n inlineGridColumnGapRem: 1.5,\n inlineGridRowGapRem: 0.65,\n inlineTemplateMarginTopRem: 0.45,\n inlineChoicesMarginTopRem: 0.25,\n};\n","import { DEFAULT_LAYOUT_LIMITS } from '../shared/layoutLimits';\n\nexport { DEFAULT_LAYOUT_LIMITS };\n\n/** Token authors must include exactly once in `template` (HTML). */\nexport const BLANK_TOKEN = '{{blank}}';\n\nexport default {\n model: {\n id: '1',\n element: 'mc-populated-blank',\n prompt: '<p><strong>Demo prompt</strong></p>',\n promptEnabled: true,\n interactionMode: 'populate_blank' as const,\n layoutProfile: '',\n choiceLayout: '',\n layoutProfilePresets: {},\n layoutLimits: { ...DEFAULT_LAYOUT_LIMITS },\n audioButtonSkin: null,\n audioButtonSkinsByLocale: {},\n uiText: {\n answerChoices: 'Answer choices',\n selectedAnswerInSentence: 'blank',\n showCorrectAnswer: 'Show correct answer',\n hideCorrectAnswer: 'Hide correct answer',\n clickToEnableAutoplay: 'Click to enable audio autoplay',\n audioResourceUnavailable: 'Audio is enabled but no playable audio URL is configured.',\n transcriptLabel: 'Transcript',\n listenLabelEn: 'Listen',\n listenLabelEs: 'Escuchar',\n listenSilentAlt: 'Repeat instructions',\n listenPlayingAlt: 'Instructions are playing',\n listenSilentAltEs: 'Escuchar. Repetir las instrucciones.',\n listenPlayingAltEs: 'Escuchar. Estas son las instrucciones.',\n },\n sentenceHtml: '',\n template: `<p>The answer is ${BLANK_TOKEN}.</p>`,\n choiceMode: 'text' as const,\n choices: [\n { id: 'c1', labelHtml: '<p>Option A</p>' },\n { id: 'c2', labelHtml: '<p>Option B</p>' },\n { id: 'c3', labelHtml: '<p>Option C</p>' },\n ],\n correctChoiceId: 'c2',\n hasAudio: false,\n autoplayAudioEnabled: false,\n completeAudioEnabled: false,\n audioUrl: '',\n audioTranscript: '',\n locale: '',\n teacherInstructions: '',\n teacherInstructionsEnabled: false,\n },\n configuration: {\n prompt: {\n label: 'Prompt',\n settings: true,\n },\n },\n};\n","import defaults, { BLANK_TOKEN, DEFAULT_LAYOUT_LIMITS } from './defaults';\nimport type {\n McpbChoice,\n McpbQuestion,\n McpbSession,\n McpbEnv,\n McpbCorrectness,\n} from '../shared/types';\n\nconst isEmptyObject = (value: unknown): boolean =>\n !!value &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.keys(value as Record<string, unknown>).length === 0;\n\nexport function countBlankTokens(template: string): number {\n if (!template) return 0;\n const re = /\\{\\{blank\\}\\}/g;\n return (template.match(re) || []).length;\n}\n\nexport const getCorrectness = (question: McpbQuestion, session: McpbSession): McpbCorrectness => {\n if (!session?.choiceId) {\n return 'unanswered';\n }\n const correct = question?.correctChoiceId || '';\n if (session.choiceId === correct) {\n return 'correct';\n }\n return 'incorrect';\n};\n\nexport const getPartialScore = (_question: McpbQuestion, session: McpbSession) => {\n if (!session || isEmptyObject(session) || !session.choiceId) {\n return 0;\n }\n return 1;\n};\n\nexport const outcome = (question: McpbQuestion, session: McpbSession, env: McpbEnv) =>\n new Promise((resolve) => {\n if (!session || isEmptyObject(session)) {\n resolve({\n score: 0,\n empty: true,\n traceLog: ['Student did not select any answers. Score is 0.'],\n });\n return;\n }\n\n session = normalizeSession(session);\n const correctness = getCorrectness(question, session);\n\n if (correctness === 'unanswered') {\n resolve({\n score: 0,\n empty: true,\n traceLog: ['Student did not select any answers. Score is 0.'],\n });\n return;\n }\n\n const score = correctness === 'correct' ? 1 : 0;\n const traceLog = [\n `Mode: ${env?.mode || 'unknown'}.`,\n `Student selected choice: ${session.choiceId}.`,\n `Correct choice: ${question?.correctChoiceId || 'none'}.`,\n `Final score: ${score}.`,\n ];\n resolve({ score, empty: false, traceLog });\n });\n\nexport const createDefaultModel = (model: McpbQuestion = {}) => ({\n ...defaults.model,\n ...model,\n layoutLimits: {\n ...DEFAULT_LAYOUT_LIMITS,\n ...(model?.layoutLimits || {}),\n },\n});\n\nexport const normalize = (question: McpbQuestion = {}) => createDefaultModel(question);\n\nexport const normalizeSession = (s: McpbSession): McpbSession => ({ ...s });\n\nconst shouldShuffleChoices = (question: McpbQuestion) => !!question?.shuffle;\n\nconst shouldLockChoices = (question: McpbQuestion, env: McpbEnv) => {\n if (question?.lockChoiceOrder) return true;\n if (env?.['@pie-element']?.lockChoiceOrder) return true;\n return env?.role === 'instructor';\n};\n\nfunction shuffleArray<T>(items: T[]): T[] {\n const out = [...items];\n for (let i = out.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [out[i], out[j]] = [out[j], out[i]];\n }\n return out;\n}\n\nconst getStoredShuffle = (session: McpbSession): string[] =>\n Array.isArray(session?.data?.shuffledValues)\n ? session.data.shuffledValues\n : Array.isArray(session?.shuffledValues)\n ? session.shuffledValues\n : [];\n\nconst applyShuffledValues = (\n choices: McpbChoice[],\n shuffledValues: string[],\n choiceKey: keyof McpbChoice\n) => {\n const orderedChoices = shuffledValues\n .map((value) => choices.find((choice) => choice?.[choiceKey] === value))\n .filter((c): c is McpbChoice => !!c);\n\n if (orderedChoices.length === choices.length) {\n return orderedChoices;\n }\n\n const orderedValues = new Set(orderedChoices.map((choice) => choice[choiceKey]));\n const leftovers = choices.filter((choice) => !orderedValues.has(choice?.[choiceKey]));\n return [...orderedChoices, ...leftovers];\n};\n\ntype UpdateSessionFn = (\n id: string,\n element: string,\n data: { shuffledValues: string[] }\n) => Promise<void>;\n\nconst getOrderedChoices = async (\n question: McpbQuestion,\n session: McpbSession,\n env: McpbEnv,\n updateSession?: UpdateSessionFn\n) => {\n const choices = Array.isArray(question?.choices) ? [...question.choices] : [];\n if (!choices.length || !shouldShuffleChoices(question)) {\n return choices;\n }\n\n if (shouldLockChoices(question, env || {})) {\n return choices;\n }\n\n const shuffledValues = getStoredShuffle(session);\n if (shuffledValues.length) {\n return applyShuffledValues(choices, shuffledValues, 'id');\n }\n\n const shuffledChoices = shuffleArray(choices);\n\n if (updateSession && typeof updateSession === 'function' && session?.id && session?.element) {\n const shuffledIds = shuffledChoices.map((choice) => choice?.id).filter(Boolean);\n if (shuffledIds.length) {\n await updateSession(session.id, session.element, { shuffledValues: shuffledIds });\n }\n }\n\n return shuffledChoices;\n};\n\nexport const model = async (\n question: McpbQuestion,\n session: McpbSession | null,\n env: McpbEnv | null,\n updateSession?: UpdateSessionFn\n) => {\n const safeSession: McpbSession = session || {};\n const safeEnv: McpbEnv = env || {};\n const normalizedQuestion = normalize(question);\n const choices = await getOrderedChoices(normalizedQuestion, safeSession, safeEnv, updateSession);\n\n const out: Record<string, unknown> = {\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n interactionMode: normalizedQuestion.interactionMode || 'populate_blank',\n layoutProfile: normalizedQuestion.layoutProfile || '',\n choiceLayout: normalizedQuestion.choiceLayout || '',\n layoutProfilePresets:\n normalizedQuestion.layoutProfilePresets &&\n typeof normalizedQuestion.layoutProfilePresets === 'object'\n ? normalizedQuestion.layoutProfilePresets\n : {},\n layoutLimits: normalizedQuestion.layoutLimits || { ...DEFAULT_LAYOUT_LIMITS },\n audioButtonSkin:\n normalizedQuestion.audioButtonSkin && typeof normalizedQuestion.audioButtonSkin === 'object'\n ? normalizedQuestion.audioButtonSkin\n : null,\n audioButtonSkinsByLocale:\n normalizedQuestion.audioButtonSkinsByLocale &&\n typeof normalizedQuestion.audioButtonSkinsByLocale === 'object'\n ? normalizedQuestion.audioButtonSkinsByLocale\n : {},\n uiText:\n normalizedQuestion.uiText && typeof normalizedQuestion.uiText === 'object'\n ? normalizedQuestion.uiText\n : {},\n sentenceHtml: normalizedQuestion.sentenceHtml || null,\n template: normalizedQuestion.template,\n choiceMode: normalizedQuestion.choiceMode,\n choices,\n hasAudio: normalizedQuestion.hasAudio,\n autoplayAudioEnabled: !!normalizedQuestion.autoplayAudioEnabled,\n completeAudioEnabled: !!normalizedQuestion.completeAudioEnabled,\n audioUrl: normalizedQuestion.hasAudio ? normalizedQuestion.audioUrl : null,\n audioTranscript: normalizedQuestion.hasAudio ? normalizedQuestion.audioTranscript : null,\n customType: normalizedQuestion.customType || '',\n useFeatureButtonAudio:\n typeof normalizedQuestion.useFeatureButtonAudio === 'boolean'\n ? normalizedQuestion.useFeatureButtonAudio\n : undefined,\n locale: normalizedQuestion.locale || '',\n disabled: safeEnv.mode !== 'gather',\n mode: safeEnv.mode,\n };\n\n if (safeEnv.mode === 'evaluate') {\n const correctness = getCorrectness(normalizedQuestion, safeSession);\n out.correctness = correctness;\n out.responseCorrect = correctness === 'correct';\n out.correctChoiceId = normalizedQuestion.correctChoiceId;\n }\n\n if (safeEnv.role === 'instructor' && (safeEnv.mode === 'view' || safeEnv.mode === 'evaluate')) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n return out;\n};\n\nexport const createCorrectResponseSession = (question: McpbQuestion, env: McpbEnv) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n resolve({\n id: '1',\n element: 'mc-populated-blank',\n choiceId: question?.correctChoiceId || '',\n });\n } else {\n resolve(null);\n }\n });\n};\n\nexport const validate = (question: McpbQuestion = {}, _config: Record<string, unknown> = {}) => {\n const errors: Record<string, string> = {};\n\n if (question.promptEnabled) {\n const p = question.prompt?.trim() || '';\n if (!p || p === '<p></p>') {\n errors.prompt = 'Prompt is required when prompt is enabled';\n }\n }\n\n const interactionMode = question.interactionMode || 'populate_blank';\n const template = question.template || '';\n const n = countBlankTokens(template);\n if (interactionMode === 'audio_mc_only') {\n if (n > 0) {\n errors.template = `Template cannot contain ${BLANK_TOKEN} in audio-only mode`;\n }\n } else if (interactionMode === 'populate_blank') {\n if (n === 0) {\n errors.template = `Template must contain exactly one ${BLANK_TOKEN} placeholder`;\n } else if (n > 1) {\n errors.template = `Template must contain only one ${BLANK_TOKEN} placeholder`;\n }\n } else {\n errors.interactionMode = 'Unknown interaction mode';\n }\n\n const choices = Array.isArray(question.choices) ? question.choices : [];\n if (choices.length < 2) {\n errors.choices = 'At least two choices are required';\n }\n\n const mode = question.choiceMode || 'text';\n for (let i = 0; i < choices.length; i++) {\n const c = choices[i];\n if (!c?.id) {\n errors.choices = `Choice ${i + 1} is missing an id`;\n break;\n }\n if (mode === 'text') {\n const lbl = (c.labelHtml || '').trim();\n if (!lbl || lbl === '<p></p>') {\n errors.choices = `Choice ${i + 1} needs label text`;\n break;\n }\n } else {\n if (!c.imageUrl?.trim()) {\n errors.choices = `Choice ${i + 1} needs an image URL`;\n break;\n }\n if (!c.imageAlt?.trim()) {\n errors.choices = `Choice ${i + 1} needs image alt text`;\n break;\n }\n }\n }\n\n const correct = question.correctChoiceId;\n if (!correct || !choices.some((c) => c.id === correct)) {\n errors.correctChoiceId = 'Correct choice must match one of the choice ids';\n }\n\n if (question.hasAudio) {\n const hasAudioUrl = !!question.audioUrl?.trim();\n if (!hasAudioUrl) {\n errors.audioUrl = 'A playable audio URL is required when audio is enabled';\n }\n }\n\n const limits = question?.layoutLimits;\n if (limits && typeof limits === 'object') {\n const numericLimitKeys = [\n 'blankStandaloneWidthRem',\n 'blankWideWidthRem',\n 'blankUnderlineWidthPx',\n 'blankUnderlineWideWidthPx',\n 'horizontalChoiceWidthPx',\n 'horizontalChoiceWidthVw',\n 'horizontalChoiceTileMinHeightRem',\n 'horizontalChoiceContentMinHeightRem',\n 'selectedImageMaxHeightRem',\n 'choiceImageMaxHeightRem',\n 'listenButtonSizePx',\n 'stimulusMinColumnPx',\n 'textMinColumnPx',\n 'legendMaxChars',\n 'choiceGroupGapRem',\n 'choiceRowGapRem',\n 'toggleButtonGapRem',\n 'horizontalChoiceRadioTopMarginRem',\n 'audioBlankTemplateMarginTopRem',\n 'audioBlankTemplateMarginBottomRem',\n 'audioInstructionsMaxWidthPx',\n 'narrowHorizontalChoiceMaxWidthPx',\n 'stimulusGridColumnGapRem',\n 'stimulusGridRowGapRem',\n 'stimulusSentenceMarginTopRem',\n 'stimulusChoicesMarginTopRem',\n 'tokenGridColumnGapRem',\n 'tokenGridRowGapRem',\n 'tokenTemplateMarginTopRem',\n 'tokenInlineTokenGapRem',\n 'tokenChoicesMarginTopRem',\n 'inlineGridColumnGapRem',\n 'inlineGridRowGapRem',\n 'inlineTemplateMarginTopRem',\n 'inlineChoicesMarginTopRem',\n ] as const;\n for (const key of numericLimitKeys) {\n if (limits[key] === undefined || limits[key] === null) continue;\n const value = Number(limits[key]);\n if (!Number.isFinite(value) || value <= 0) {\n errors.layoutLimits = `${key} must be a positive number when provided`;\n break;\n }\n }\n }\n\n return errors;\n};\n"],"mappings":"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"}
@@ -22,5 +22,4 @@ export declare function computeLayoutStyle(params: {
22
22
  isBlankOnlyTemplate: boolean;
23
23
  configuredLimits: unknown;
24
24
  customProfilePresets: unknown;
25
- correctAnswerStyleVars: string;
26
25
  }): LayoutStyleResult;