alexsys-exam-renderer 0.1.33 → 0.1.34

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.
@@ -0,0 +1,71 @@
1
+ export type AserAdaptiveQuestion = {
2
+ displayOrder: number;
3
+ };
4
+ export type AserAdaptiveSubjectInput<TSubject, TQuestion extends AserAdaptiveQuestion> = {
5
+ displayOrder: number;
6
+ questions: readonly TQuestion[];
7
+ subject: TSubject;
8
+ };
9
+ export type AserAdaptiveStep<TQuestion> = {
10
+ fallbackLevelCode: string | null;
11
+ levelCode: string;
12
+ questions: TQuestion[];
13
+ };
14
+ export type AserAdaptiveSubjectFlow<TSubject, TQuestion> = {
15
+ startLevelCode: string | null;
16
+ steps: AserAdaptiveStep<TQuestion>[];
17
+ subject: TSubject;
18
+ };
19
+ export type AserCardQuestion = AserAdaptiveQuestion & {
20
+ isStartingQuestion?: boolean;
21
+ };
22
+ export type AserCardStartState = 'empty' | 'missing-start' | 'multiple-starts' | 'ready';
23
+ export type AserCardSubjectFlow<TSubject, TQuestion> = {
24
+ levelCode: string;
25
+ questions: TQuestion[];
26
+ startIndex: number | null;
27
+ startState: AserCardStartState;
28
+ subject: TSubject;
29
+ };
30
+ export type AserCardOutcome = 'failure' | 'success';
31
+ export type AserCardRoutePhase = 'start' | 'after-success' | 'after-failure';
32
+ export type AserCardCompletionReason = 'upper-boundary' | 'lower-boundary' | 'success-after-failure' | 'failure-after-success';
33
+ export type AserCardTransition<TQuestion> = {
34
+ boundary: 'lower' | 'upper' | null;
35
+ completed: boolean;
36
+ completionReason: AserCardCompletionReason | null;
37
+ nextIndex: number | null;
38
+ nextPhase: AserCardRoutePhase | null;
39
+ nextQuestion: TQuestion | null;
40
+ };
41
+ /**
42
+ * Legacy ASER route grouped by the highest available CE level. New ASER
43
+ * authoring uses createAserCardFlow instead, but this export remains stable for
44
+ * existing consumers during the migration.
45
+ *
46
+ * The learner starts at the highest configured level that does not exceed the
47
+ * school level. A success continues inside the current step; a failure takes
48
+ * the learner to the following step, which is the next configured lower level.
49
+ * Missing levels are deliberately skipped.
50
+ */
51
+ export declare function createAserAdaptiveFlow<TSubject, TQuestion extends AserAdaptiveQuestion>(subjects: readonly AserAdaptiveSubjectInput<TSubject, TQuestion>[], studentLevelCode: string, getQuestionLevelCode: (question: TQuestion) => string | null | undefined): AserAdaptiveSubjectFlow<TSubject, TQuestion>[];
52
+ /**
53
+ * Resolves the exact question card for a student's school level.
54
+ *
55
+ * The card is ordered from the most demanding question at index 0 to the most
56
+ * accessible question at the last index. The starred question is the start:
57
+ * success moves upward and failure moves downward. Once a learner has moved,
58
+ * the first opposite outcome ends the test instead of returning to the start.
59
+ */
60
+ export declare function createAserCardFlow<TSubject, TQuestion extends AserCardQuestion>(subjects: readonly AserAdaptiveSubjectInput<TSubject, TQuestion>[], studentLevelCode: string, getQuestionLevelCode: (question: TQuestion) => string | null | undefined): AserCardSubjectFlow<TSubject, TQuestion>[];
61
+ /**
62
+ * Resolves the next ASER activity for a one-way route.
63
+ *
64
+ * - From the start, success moves up and failure moves down.
65
+ * - On the success route, a failure ends the test; successes keep moving up.
66
+ * - On the failure route, a success ends the test; failures keep moving down.
67
+ */
68
+ export declare function resolveAserCardTransition<TQuestion>(flow: Pick<AserCardSubjectFlow<unknown, TQuestion>, 'questions'>, currentIndex: number, outcome: AserCardOutcome, phase?: AserCardRoutePhase): AserCardTransition<TQuestion>;
69
+ export declare function getAserAdaptiveLevelRank(levelCode: string | null | undefined): number;
70
+ export declare function normalizeAserAdaptiveLevelCode(levelCode: string): string;
71
+ //# sourceMappingURL=aserAdaptiveFlow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aserAdaptiveFlow.d.ts","sourceRoot":"","sources":["../../src/aser/aserAdaptiveFlow.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export * from './renderer/shapeCatalog';
18
18
  export * from './renderer/stableOrder';
19
19
  export * from './renderer/visualScene';
20
20
  export * from './voice/evaluateVoiceAiResult';
21
+ export * from './aser/aserAdaptiveFlow';
21
22
  export { default as CoinTableResponse } from './exam-session/interactions/CoinTableResponse';
22
23
  export { default as ColorPenPicker } from './exam-session/interactions/ColorPenPicker';
23
24
  export { default as DraftSheet } from './exam-session/interactions/DraftSheet';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAA;AAErB,cAAc,iCAAiC,CAAA;AAC/C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,2BAA2B,CAAA;AACzC,cAAc,mCAAmC,CAAA;AACjD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,+BAA+B,CAAA;AAE7C,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,+CAA+C,CAAA;AAC5F,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wCAAwC,CAAA;AAC9E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,uCAAuC,CAAA;AAC5E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,qDAAqD,CAAA;AACxG,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,iDAAiD,CAAA;AAChG,cAAc,uCAAuC,CAAA;AACrD,cAAc,yCAAyC,CAAA;AACvD,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,uDAAuD,CAAA;AAC5G,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,8CAA8C,CAAA;AAC1F,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,8CAA8C,CAAA;AAC1F,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,+CAA+C,CAAA;AAC5F,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,sDAAsD,CAAA;AAC1G,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,0CAA0C,CAAA;AAClF,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,kDAAkD,CAAA;AAClG,cAAc,+CAA+C,CAAA;AAC7D,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,mDAAmD,CAAA;AACpG,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,0CAA0C,CAAA;AAClF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wCAAwC,CAAA;AAC9E,cAAc,4CAA4C,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAA;AAErB,cAAc,iCAAiC,CAAA;AAC/C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,2BAA2B,CAAA;AACzC,cAAc,mCAAmC,CAAA;AACjD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,yBAAyB,CAAA;AAEvC,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,+CAA+C,CAAA;AAC5F,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wCAAwC,CAAA;AAC9E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,uCAAuC,CAAA;AAC5E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,qDAAqD,CAAA;AACxG,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,iDAAiD,CAAA;AAChG,cAAc,uCAAuC,CAAA;AACrD,cAAc,yCAAyC,CAAA;AACvD,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,uDAAuD,CAAA;AAC5G,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,8CAA8C,CAAA;AAC1F,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,8CAA8C,CAAA;AAC1F,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,+CAA+C,CAAA;AAC5F,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,sDAAsD,CAAA;AAC1G,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,0CAA0C,CAAA;AAClF,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,kDAAkD,CAAA;AAClG,cAAc,+CAA+C,CAAA;AAC7D,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,mDAAmD,CAAA;AACpG,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,0CAA0C,CAAA;AAClF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAA;AACtF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wCAAwC,CAAA;AAC9E,cAAc,4CAA4C,CAAA"}
package/dist/index.js CHANGED
@@ -7986,8 +7986,80 @@ function Qc(e) {
7986
7986
  };
7987
7987
  }
7988
7988
  //#endregion
7989
+ //#region src/aser/aserAdaptiveFlow.ts
7990
+ function $c(e, t, n) {
7991
+ let r = rl(t);
7992
+ return [...e].sort((e, t) => e.displayOrder - t.displayOrder).map((e) => {
7993
+ let t = /* @__PURE__ */ new Map();
7994
+ [...e.questions].sort((e, t) => e.displayOrder - t.displayOrder).forEach((e) => {
7995
+ let r = il(n(e) ?? "");
7996
+ if (rl(r) === 0) return;
7997
+ let i = t.get(r) ?? [];
7998
+ i.push(e), t.set(r, i);
7999
+ });
8000
+ let i = [...t.keys()].filter((e) => rl(e) <= r).sort((e, t) => rl(t) - rl(e)), a = i.map((e, n) => ({
8001
+ fallbackLevelCode: i[n + 1] ?? null,
8002
+ levelCode: e,
8003
+ questions: t.get(e) ?? []
8004
+ }));
8005
+ return {
8006
+ startLevelCode: a[0]?.levelCode ?? null,
8007
+ steps: a,
8008
+ subject: e.subject
8009
+ };
8010
+ });
8011
+ }
8012
+ function el(e, t, n) {
8013
+ let r = il(t);
8014
+ return [...e].sort((e, t) => e.displayOrder - t.displayOrder).map((e) => {
8015
+ let t = e.questions.filter((e) => il(n(e) ?? "") === r).map((e, t) => ({
8016
+ question: e,
8017
+ sourceIndex: t
8018
+ })).sort((e, t) => e.question.displayOrder - t.question.displayOrder || e.sourceIndex - t.sourceIndex).map(({ question: e }) => e), i = t.map((e, t) => e.isStartingQuestion ? t : -1).filter((e) => e >= 0), a = t.length === 0 ? "empty" : i.length === 0 ? "missing-start" : i.length > 1 ? "multiple-starts" : "ready";
8019
+ return {
8020
+ levelCode: r,
8021
+ questions: t,
8022
+ startIndex: a === "ready" ? i[0] ?? null : null,
8023
+ startState: a,
8024
+ subject: e.subject
8025
+ };
8026
+ });
8027
+ }
8028
+ function tl(e, t, n, r = "start") {
8029
+ if (t < 0 || t >= e.questions.length) throw RangeError("The ASER current question index is outside the selected card.");
8030
+ if (r === "after-success" && n === "failure") return nl("failure-after-success");
8031
+ if (r === "after-failure" && n === "success") return nl("success-after-failure");
8032
+ let i = n === "success" ? t - 1 : t + 1;
8033
+ return i < 0 ? nl("upper-boundary", "upper") : i >= e.questions.length ? nl("lower-boundary", "lower") : {
8034
+ boundary: null,
8035
+ completed: !1,
8036
+ completionReason: null,
8037
+ nextIndex: i,
8038
+ nextPhase: n === "success" ? "after-success" : "after-failure",
8039
+ nextQuestion: e.questions[i] ?? null
8040
+ };
8041
+ }
8042
+ function nl(e, t = null) {
8043
+ return {
8044
+ boundary: t,
8045
+ completed: !0,
8046
+ completionReason: e,
8047
+ nextIndex: null,
8048
+ nextPhase: null,
8049
+ nextQuestion: null
8050
+ };
8051
+ }
8052
+ function rl(e) {
8053
+ let t = /^CE\s*([1-6])$/i.exec(e?.trim() ?? "");
8054
+ return t ? Number(t[1]) : 0;
8055
+ }
8056
+ function il(e) {
8057
+ let t = rl(e);
8058
+ return t > 0 ? `CE${t}` : e.trim().toUpperCase();
8059
+ }
8060
+ //#endregion
7989
8061
  //#region src/exam-session/interactions/DraftSheet.tsx
7990
- function $c({ disabled: e, onChange: t, value: n }) {
8062
+ function al({ disabled: e, onChange: t, value: n }) {
7991
8063
  let [r, i] = a(!1);
7992
8064
  return /* @__PURE__ */ s("aside", {
7993
8065
  className: "draft-sheet",
@@ -8023,7 +8095,7 @@ function $c({ disabled: e, onChange: t, value: n }) {
8023
8095
  }
8024
8096
  //#endregion
8025
8097
  //#region src/exam-session/interactions/ProblemSheetComposer.tsx
8026
- var el = 460, tl = [
8098
+ var ol = 460, sl = [
8027
8099
  "#0f172a",
8028
8100
  "#0b5ed7",
8029
8101
  "#18c7c9",
@@ -8031,7 +8103,7 @@ var el = 460, tl = [
8031
8103
  "#f59e0b",
8032
8104
  "#ef4444",
8033
8105
  "#7c3aed"
8034
- ], nl = {
8106
+ ], cl = {
8035
8107
  delete: "Supprimer l’élément",
8036
8108
  eraser: "Gomme",
8037
8109
  fillColor: "Remplissage",
@@ -8057,11 +8129,11 @@ var el = 460, tl = [
8057
8129
  textColor: "Couleur du texte",
8058
8130
  textPlaceholder: "Écrivez le texte à placer sur la feuille"
8059
8131
  };
8060
- function rl({ config: e, labels: t, onChange: l }) {
8132
+ function ll({ config: e, labels: t, onChange: l }) {
8061
8133
  let u = r(() => ({
8062
- ...nl,
8134
+ ...cl,
8063
8135
  ...t
8064
- }), [t]), d = i(null), f = i(null), [p, m] = a(Qa), [h, _] = a("select"), [v, y] = a(!1), [x, S] = a(null), [T, E] = a(""), [D, O] = a(tl[0]), [k, j] = a(4), [M, N] = a(null), ee = bl(e.height), F = e.elements ?? [], I = F.find((e) => e.id === x);
8136
+ }), [t]), d = i(null), f = i(null), [p, m] = a(Qa), [h, _] = a("select"), [v, y] = a(!1), [x, S] = a(null), [T, E] = a(""), [D, O] = a(sl[0]), [k, j] = a(4), [M, N] = a(null), ee = El(e.height), F = e.elements ?? [], I = F.find((e) => e.id === x);
8065
8137
  n(() => {
8066
8138
  let e = d.current;
8067
8139
  if (!e) return;
@@ -8084,10 +8156,10 @@ function rl({ config: e, labels: t, onChange: l }) {
8084
8156
  } : n));
8085
8157
  }
8086
8158
  function B(e) {
8087
- let t = vl(e), n = {
8159
+ let t = wl(e), n = {
8088
8160
  fill: "#e8f1ff",
8089
8161
  height: t.height,
8090
- id: gl(e),
8162
+ id: Sl(e),
8091
8163
  rotation: 0,
8092
8164
  shape: e,
8093
8165
  stroke: "#0f172a",
@@ -8095,13 +8167,13 @@ function rl({ config: e, labels: t, onChange: l }) {
8095
8167
  type: "shape",
8096
8168
  width: t.width,
8097
8169
  x: 140,
8098
- y: _l(F.length, ee)
8170
+ y: Cl(F.length, ee)
8099
8171
  };
8100
8172
  R(F.concat(n)), S(n.id), _("select"), y(!1);
8101
8173
  }
8102
8174
  async function re(e) {
8103
8175
  if (!e || !e.type.startsWith("image/")) return;
8104
- let { height: t, source: n, width: r } = await Sl(e), i = Math.min(320, Math.max(140, r)), a = {
8176
+ let { height: t, source: n, width: r } = await Ol(e), i = Math.min(320, Math.max(140, r)), a = {
8105
8177
  crop: {
8106
8178
  height: 1,
8107
8179
  width: 1,
@@ -8109,18 +8181,18 @@ function rl({ config: e, labels: t, onChange: l }) {
8109
8181
  y: 0
8110
8182
  },
8111
8183
  height: Math.min(300, Math.max(90, Math.round(t / r * i))),
8112
- id: gl("image"),
8184
+ id: Sl("image"),
8113
8185
  rotation: 0,
8114
8186
  source: n,
8115
8187
  type: "image",
8116
8188
  width: i,
8117
8189
  x: 140,
8118
- y: _l(F.length, ee)
8190
+ y: Cl(F.length, ee)
8119
8191
  };
8120
8192
  R(F.concat(a)), S(a.id), _("select");
8121
8193
  }
8122
8194
  function V(e, t) {
8123
- let n = xl({
8195
+ let n = Dl({
8124
8196
  height: 1,
8125
8197
  width: 1,
8126
8198
  x: 0,
@@ -8140,13 +8212,13 @@ function rl({ config: e, labels: t, onChange: l }) {
8140
8212
  }
8141
8213
  if (E(e), h !== "text" || !e) return;
8142
8214
  let t = {
8143
- color: tl[0],
8215
+ color: sl[0],
8144
8216
  fontSize: 28,
8145
- id: gl("text"),
8217
+ id: Sl("text"),
8146
8218
  text: e,
8147
8219
  type: "text",
8148
8220
  x: 120,
8149
- y: _l(F.length, ee)
8221
+ y: Cl(F.length, ee)
8150
8222
  };
8151
8223
  R(F.concat(t)), S(t.id), _("select");
8152
8224
  }
@@ -8156,8 +8228,8 @@ function rl({ config: e, labels: t, onChange: l }) {
8156
8228
  function ce(e) {
8157
8229
  let t = e.target.getStage()?.getPointerPosition();
8158
8230
  return t ? {
8159
- x: yl(t.x / L, 0, Qa),
8160
- y: yl(t.y / L, 0, ee)
8231
+ x: Tl(t.x / L, 0, Qa),
8232
+ y: Tl(t.y / L, 0, ee)
8161
8233
  } : null;
8162
8234
  }
8163
8235
  function le(e) {
@@ -8169,7 +8241,7 @@ function rl({ config: e, labels: t, onChange: l }) {
8169
8241
  let t = ce(e);
8170
8242
  t && (S(null), N({
8171
8243
  color: D,
8172
- id: gl("drawing"),
8244
+ id: Sl("drawing"),
8173
8245
  points: [0, 0],
8174
8246
  strokeWidth: k,
8175
8247
  type: "drawing",
@@ -8211,7 +8283,7 @@ function rl({ config: e, labels: t, onChange: l }) {
8211
8283
  function W(e) {
8212
8284
  let t = ce(e);
8213
8285
  if (t) {
8214
- for (let e = F.length - 1; e >= 0; --e) if (ml(F[e], t)) {
8286
+ for (let e = F.length - 1; e >= 0; --e) if (bl(F[e], t)) {
8215
8287
  R(F.filter((t, n) => n !== e)), S(null);
8216
8288
  return;
8217
8289
  }
@@ -8225,13 +8297,13 @@ function rl({ config: e, labels: t, onChange: l }) {
8225
8297
  className: "problem-sheet-composer__toolbar",
8226
8298
  role: "toolbar",
8227
8299
  children: [
8228
- /* @__PURE__ */ s(il, {
8300
+ /* @__PURE__ */ s(ul, {
8229
8301
  active: h === "select",
8230
8302
  label: u.move,
8231
8303
  onClick: () => _("select"),
8232
8304
  children: /* @__PURE__ */ s(C, { "aria-hidden": "true" })
8233
8305
  }),
8234
- /* @__PURE__ */ s(il, {
8306
+ /* @__PURE__ */ s(ul, {
8235
8307
  active: h === "text",
8236
8308
  label: u.text,
8237
8309
  onClick: ae,
@@ -8239,7 +8311,7 @@ function rl({ config: e, labels: t, onChange: l }) {
8239
8311
  }),
8240
8312
  /* @__PURE__ */ c("div", {
8241
8313
  className: "problem-sheet-composer__shape-menu",
8242
- children: [/* @__PURE__ */ s(il, {
8314
+ children: [/* @__PURE__ */ s(ul, {
8243
8315
  active: v,
8244
8316
  label: u.shapeLibrary,
8245
8317
  onClick: () => y((e) => !e),
@@ -8257,31 +8329,31 @@ function rl({ config: e, labels: t, onChange: l }) {
8257
8329
  onClick: () => B(e),
8258
8330
  title: t,
8259
8331
  type: "button",
8260
- children: [/* @__PURE__ */ s(al, { shape: e }), /* @__PURE__ */ s("span", { children: t })]
8332
+ children: [/* @__PURE__ */ s(dl, { shape: e }), /* @__PURE__ */ s("span", { children: t })]
8261
8333
  }, e);
8262
8334
  }) })]
8263
8335
  }, e.id))
8264
8336
  }) : null]
8265
8337
  }),
8266
- /* @__PURE__ */ s(il, {
8338
+ /* @__PURE__ */ s(ul, {
8267
8339
  label: u.image,
8268
8340
  onClick: () => f.current?.click(),
8269
8341
  children: /* @__PURE__ */ s(b, { "aria-hidden": "true" })
8270
8342
  }),
8271
- /* @__PURE__ */ s(il, {
8343
+ /* @__PURE__ */ s(ul, {
8272
8344
  active: h === "pen",
8273
8345
  label: u.pen,
8274
8346
  onClick: () => _((e) => e === "pen" ? "select" : "pen"),
8275
8347
  children: /* @__PURE__ */ s(w, { "aria-hidden": "true" })
8276
8348
  }),
8277
- /* @__PURE__ */ s(il, {
8349
+ /* @__PURE__ */ s(ul, {
8278
8350
  active: h === "eraser",
8279
8351
  label: u.eraser,
8280
8352
  onClick: () => _((e) => e === "eraser" ? "select" : "eraser"),
8281
8353
  children: /* @__PURE__ */ s(g, { "aria-hidden": "true" })
8282
8354
  }),
8283
8355
  /* @__PURE__ */ s("span", { className: "problem-sheet-composer__toolbar-divider" }),
8284
- /* @__PURE__ */ s(il, {
8356
+ /* @__PURE__ */ s(ul, {
8285
8357
  disabled: !I,
8286
8358
  label: u.delete,
8287
8359
  onClick: U,
@@ -8300,11 +8372,11 @@ function rl({ config: e, labels: t, onChange: l }) {
8300
8372
  rows: 3,
8301
8373
  value: I?.type === "text" ? I.text : T
8302
8374
  })]
8303
- }), I?.type === "text" ? /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(ol, {
8375
+ }), I?.type === "text" ? /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(fl, {
8304
8376
  label: u.textColor,
8305
8377
  onSelect: (e) => z(I.id, { color: e }),
8306
- value: I.color ?? tl[0]
8307
- }), /* @__PURE__ */ s(sl, {
8378
+ value: I.color ?? sl[0]
8379
+ }), /* @__PURE__ */ s(pl, {
8308
8380
  label: u.fontSize,
8309
8381
  max: 72,
8310
8382
  min: 12,
@@ -8315,24 +8387,24 @@ function rl({ config: e, labels: t, onChange: l }) {
8315
8387
  I?.type === "shape" ? /* @__PURE__ */ c("div", {
8316
8388
  className: "problem-sheet-composer__inspector problem-sheet-composer__inspector--shape",
8317
8389
  children: [
8318
- /* @__PURE__ */ s(ol, {
8390
+ /* @__PURE__ */ s(fl, {
8319
8391
  label: u.fillColor,
8320
8392
  onSelect: (e) => z(I.id, { fill: e }),
8321
8393
  value: I.fill ?? "#e8f1ff"
8322
8394
  }),
8323
- /* @__PURE__ */ s(ol, {
8395
+ /* @__PURE__ */ s(fl, {
8324
8396
  label: u.strokeColor,
8325
8397
  onSelect: (e) => z(I.id, { stroke: e }),
8326
- value: I.stroke ?? tl[0]
8398
+ value: I.stroke ?? sl[0]
8327
8399
  }),
8328
- /* @__PURE__ */ s(sl, {
8400
+ /* @__PURE__ */ s(pl, {
8329
8401
  label: u.strokeWidth,
8330
8402
  max: 12,
8331
8403
  min: 1,
8332
8404
  onChange: (e) => z(I.id, { strokeWidth: e }),
8333
8405
  value: I.strokeWidth ?? 3
8334
8406
  }),
8335
- /* @__PURE__ */ s(sl, {
8407
+ /* @__PURE__ */ s(pl, {
8336
8408
  label: I.shape === "line" ? u.lineLength : u.shapeWidth,
8337
8409
  max: 500,
8338
8410
  min: 40,
@@ -8342,7 +8414,7 @@ function rl({ config: e, labels: t, onChange: l }) {
8342
8414
  } : { width: e }),
8343
8415
  value: I.width
8344
8416
  }),
8345
- /* @__PURE__ */ s(sl, {
8417
+ /* @__PURE__ */ s(pl, {
8346
8418
  label: I.shape === "line" ? u.lineSlope : u.shapeHeight,
8347
8419
  max: I.shape === "line" ? 300 : 500,
8348
8420
  min: I.shape === "line" ? -300 : 40,
@@ -8357,28 +8429,28 @@ function rl({ config: e, labels: t, onChange: l }) {
8357
8429
  I?.type === "image" ? /* @__PURE__ */ c("div", {
8358
8430
  className: "problem-sheet-composer__inspector problem-sheet-composer__inspector--image",
8359
8431
  children: [
8360
- /* @__PURE__ */ s(sl, {
8432
+ /* @__PURE__ */ s(pl, {
8361
8433
  label: u.cropX,
8362
8434
  max: 100,
8363
8435
  min: 0,
8364
8436
  onChange: (e) => V(I, { x: e / 100 }),
8365
8437
  value: (I.crop?.x ?? 0) * 100
8366
8438
  }),
8367
- /* @__PURE__ */ s(sl, {
8439
+ /* @__PURE__ */ s(pl, {
8368
8440
  label: u.cropY,
8369
8441
  max: 100,
8370
8442
  min: 0,
8371
8443
  onChange: (e) => V(I, { y: e / 100 }),
8372
8444
  value: (I.crop?.y ?? 0) * 100
8373
8445
  }),
8374
- /* @__PURE__ */ s(sl, {
8446
+ /* @__PURE__ */ s(pl, {
8375
8447
  label: u.cropWidth,
8376
8448
  max: 100,
8377
8449
  min: 5,
8378
8450
  onChange: (e) => V(I, { width: e / 100 }),
8379
8451
  value: (I.crop?.width ?? 1) * 100
8380
8452
  }),
8381
- /* @__PURE__ */ s(sl, {
8453
+ /* @__PURE__ */ s(pl, {
8382
8454
  label: u.cropHeight,
8383
8455
  max: 100,
8384
8456
  min: 5,
@@ -8389,11 +8461,11 @@ function rl({ config: e, labels: t, onChange: l }) {
8389
8461
  }) : null,
8390
8462
  h === "pen" ? /* @__PURE__ */ c("div", {
8391
8463
  className: "problem-sheet-composer__inspector problem-sheet-composer__inspector--pen",
8392
- children: [/* @__PURE__ */ s(ol, {
8464
+ children: [/* @__PURE__ */ s(fl, {
8393
8465
  label: u.penColor,
8394
8466
  onSelect: O,
8395
8467
  value: D
8396
- }), /* @__PURE__ */ s(sl, {
8468
+ }), /* @__PURE__ */ s(pl, {
8397
8469
  label: u.penWidth,
8398
8470
  max: 12,
8399
8471
  min: 1,
@@ -8435,7 +8507,7 @@ function rl({ config: e, labels: t, onChange: l }) {
8435
8507
  height: ee,
8436
8508
  paper: e.paper ?? "squared"
8437
8509
  }),
8438
- F.map((e) => /* @__PURE__ */ s(cl, {
8510
+ F.map((e) => /* @__PURE__ */ s(ml, {
8439
8511
  draggable: h === "select",
8440
8512
  element: e,
8441
8513
  onDragEnd: (t) => z(e.id, {
@@ -8448,7 +8520,7 @@ function rl({ config: e, labels: t, onChange: l }) {
8448
8520
  onShapeTransform: (e, t) => z(e.id, t),
8449
8521
  selected: e.id === x
8450
8522
  }, e.id)),
8451
- M ? /* @__PURE__ */ s(dl, { element: M }) : null
8523
+ M ? /* @__PURE__ */ s(_l, { element: M }) : null
8452
8524
  ]
8453
8525
  })
8454
8526
  })]
@@ -8456,7 +8528,7 @@ function rl({ config: e, labels: t, onChange: l }) {
8456
8528
  ]
8457
8529
  });
8458
8530
  }
8459
- function il({ active: e = !1, children: t, disabled: n = !1, label: r, onClick: i }) {
8531
+ function ul({ active: e = !1, children: t, disabled: n = !1, label: r, onClick: i }) {
8460
8532
  return /* @__PURE__ */ s("button", {
8461
8533
  "aria-label": r,
8462
8534
  className: e ? "problem-sheet-composer__tool problem-sheet-composer__tool--active" : "problem-sheet-composer__tool",
@@ -8467,18 +8539,18 @@ function il({ active: e = !1, children: t, disabled: n = !1, label: r, onClick:
8467
8539
  children: t
8468
8540
  });
8469
8541
  }
8470
- function al({ shape: e }) {
8542
+ function dl({ shape: e }) {
8471
8543
  return /* @__PURE__ */ s("span", {
8472
8544
  "aria-hidden": "true",
8473
8545
  className: `problem-sheet-composer__shape-preview problem-sheet-composer__shape-preview--${e}`
8474
8546
  });
8475
8547
  }
8476
- function ol({ label: e, onSelect: t, value: n }) {
8548
+ function fl({ label: e, onSelect: t, value: n }) {
8477
8549
  return /* @__PURE__ */ c("div", {
8478
8550
  className: "problem-sheet-composer__color-control",
8479
8551
  children: [/* @__PURE__ */ s("span", { children: e }), /* @__PURE__ */ c("div", {
8480
8552
  className: "problem-sheet-composer__swatches",
8481
- children: [tl.map((r) => /* @__PURE__ */ s("button", {
8553
+ children: [sl.map((r) => /* @__PURE__ */ s("button", {
8482
8554
  "aria-label": `${e}: ${r}`,
8483
8555
  className: n.toLowerCase() === r ? "is-selected" : "",
8484
8556
  onClick: () => t(r),
@@ -8493,7 +8565,7 @@ function ol({ label: e, onSelect: t, value: n }) {
8493
8565
  })]
8494
8566
  });
8495
8567
  }
8496
- function sl({ label: e, max: t, min: n, onChange: r, value: i }) {
8568
+ function pl({ label: e, max: t, min: n, onChange: r, value: i }) {
8497
8569
  return /* @__PURE__ */ c("label", {
8498
8570
  className: "problem-sheet-composer__range-control",
8499
8571
  children: [/* @__PURE__ */ c("span", { children: [
@@ -8509,8 +8581,8 @@ function sl({ label: e, max: t, min: n, onChange: r, value: i }) {
8509
8581
  })]
8510
8582
  });
8511
8583
  }
8512
- function cl({ draggable: e, element: n, onDragEnd: r, onImageTransform: a, onLineEndpointChange: l, onShapeTransform: u, onSelect: d, selected: f }) {
8513
- let p = pl(n), m = i(null), h = i(null), g = n.type === "image" || n.type === "shape" && n.shape !== "line", _ = f && g;
8584
+ function ml({ draggable: e, element: n, onDragEnd: r, onImageTransform: a, onLineEndpointChange: l, onShapeTransform: u, onSelect: d, selected: f }) {
8585
+ let p = yl(n), m = i(null), h = i(null), g = n.type === "image" || n.type === "shape" && n.shape !== "line", _ = f && g;
8514
8586
  t(() => {
8515
8587
  !_ || !m.current || !h.current || (h.current.nodes([m.current]), h.current.getLayer()?.batchDraw());
8516
8588
  }, [n.id, _]);
@@ -8546,20 +8618,20 @@ function cl({ draggable: e, element: n, onDragEnd: r, onImageTransform: a, onLin
8546
8618
  y: n.y,
8547
8619
  children: [
8548
8620
  n.type === "text" ? /* @__PURE__ */ s(U, {
8549
- fill: n.color ?? tl[0],
8621
+ fill: n.color ?? sl[0],
8550
8622
  fontFamily: "Arial, sans-serif",
8551
8623
  fontSize: n.fontSize ?? 28,
8552
8624
  text: n.text,
8553
8625
  width: 320
8554
- }) : n.type === "drawing" ? /* @__PURE__ */ s(dl, { element: {
8626
+ }) : n.type === "drawing" ? /* @__PURE__ */ s(_l, { element: {
8555
8627
  ...n,
8556
8628
  x: 0,
8557
8629
  y: 0
8558
- } }) : n.type === "image" ? /* @__PURE__ */ s(ll, { element: {
8630
+ } }) : n.type === "image" ? /* @__PURE__ */ s(hl, { element: {
8559
8631
  ...n,
8560
8632
  x: 0,
8561
8633
  y: 0
8562
- } }) : /* @__PURE__ */ s(fl, { element: n }),
8634
+ } }) : /* @__PURE__ */ s(vl, { element: n }),
8563
8635
  f && n.type !== "image" && !g ? /* @__PURE__ */ s(H, {
8564
8636
  dash: [8, 5],
8565
8637
  height: p.height + 14,
@@ -8570,7 +8642,7 @@ function cl({ draggable: e, element: n, onDragEnd: r, onImageTransform: a, onLin
8570
8642
  x: p.x - 7,
8571
8643
  y: p.y - 7
8572
8644
  }) : null,
8573
- f && n.type === "shape" && n.shape === "line" ? /* @__PURE__ */ s(ul, {
8645
+ f && n.type === "shape" && n.shape === "line" ? /* @__PURE__ */ s(gl, {
8574
8646
  element: n,
8575
8647
  onChange: l
8576
8648
  }) : null
@@ -8600,7 +8672,7 @@ function cl({ draggable: e, element: n, onDragEnd: r, onImageTransform: a, onLin
8600
8672
  rotateLineVisible: !0
8601
8673
  }) : null] });
8602
8674
  }
8603
- function ll({ element: e }) {
8675
+ function hl({ element: e }) {
8604
8676
  let t = io(e.source);
8605
8677
  return t ? /* @__PURE__ */ s(re, {
8606
8678
  crop: ao(t, e.crop),
@@ -8611,7 +8683,7 @@ function ll({ element: e }) {
8611
8683
  y: e.y
8612
8684
  }) : null;
8613
8685
  }
8614
- function ul({ element: e, onChange: t }) {
8686
+ function gl({ element: e, onChange: t }) {
8615
8687
  function n(n, r) {
8616
8688
  r.cancelBubble = !0, t(e, n, r.target.x(), r.target.y());
8617
8689
  }
@@ -8642,25 +8714,25 @@ function ul({ element: e, onChange: t }) {
8642
8714
  y: e.height
8643
8715
  })] });
8644
8716
  }
8645
- function dl({ element: e }) {
8717
+ function _l({ element: e }) {
8646
8718
  return /* @__PURE__ */ s(V, {
8647
8719
  lineCap: "round",
8648
8720
  lineJoin: "round",
8649
8721
  points: e.points,
8650
- stroke: e.color ?? tl[0],
8722
+ stroke: e.color ?? sl[0],
8651
8723
  strokeWidth: e.strokeWidth ?? 4,
8652
8724
  tension: .38,
8653
8725
  x: e.x,
8654
8726
  y: e.y
8655
8727
  });
8656
8728
  }
8657
- function fl({ element: e }) {
8729
+ function vl({ element: e }) {
8658
8730
  return /* @__PURE__ */ s(Ya, {
8659
8731
  element: e,
8660
8732
  hitStrokeWidth: 32
8661
8733
  });
8662
8734
  }
8663
- function pl(e) {
8735
+ function yl(e) {
8664
8736
  if (e.type === "text") return {
8665
8737
  height: (e.fontSize ?? 28) * 1.5,
8666
8738
  width: 320,
@@ -8698,12 +8770,12 @@ function pl(e) {
8698
8770
  y: a
8699
8771
  };
8700
8772
  }
8701
- function ml(e, t) {
8773
+ function bl(e, t) {
8702
8774
  if (e.type === "text") {
8703
8775
  let n = (e.fontSize ?? 28) * 1.5;
8704
8776
  return t.x >= e.x - 12 && t.x <= e.x + 332 && t.y >= e.y - 12 && t.y <= e.y + n + 12;
8705
8777
  }
8706
- if (e.type === "shape") return e.shape === "line" ? hl(t, {
8778
+ if (e.type === "shape") return e.shape === "line" ? xl(t, {
8707
8779
  x: e.x,
8708
8780
  y: e.y
8709
8781
  }, {
@@ -8711,7 +8783,7 @@ function ml(e, t) {
8711
8783
  y: e.y + e.height
8712
8784
  }) <= 16 : t.x >= e.x - 12 && t.x <= e.x + e.width + 12 && t.y >= e.y - 12 && t.y <= e.y + e.height + 12;
8713
8785
  if (e.type === "image") return t.x >= e.x - 12 && t.x <= e.x + e.width + 12 && t.y >= e.y - 12 && t.y <= e.y + e.height + 12;
8714
- for (let n = 0; n < e.points.length - 2; n += 2) if (hl(t, {
8786
+ for (let n = 0; n < e.points.length - 2; n += 2) if (xl(t, {
8715
8787
  x: e.x + e.points[n],
8716
8788
  y: e.y + e.points[n + 1]
8717
8789
  }, {
@@ -8720,19 +8792,19 @@ function ml(e, t) {
8720
8792
  }) <= 16) return !0;
8721
8793
  return !1;
8722
8794
  }
8723
- function hl(e, t, n) {
8795
+ function xl(e, t, n) {
8724
8796
  let r = n.x - t.x, i = n.y - t.y, a = r * r + i * i;
8725
8797
  if (a === 0) return Math.hypot(e.x - t.x, e.y - t.y);
8726
- let o = yl(((e.x - t.x) * r + (e.y - t.y) * i) / a, 0, 1), s = t.x + o * r, c = t.y + o * i;
8798
+ let o = Tl(((e.x - t.x) * r + (e.y - t.y) * i) / a, 0, 1), s = t.x + o * r, c = t.y + o * i;
8727
8799
  return Math.hypot(e.x - s, e.y - c);
8728
8800
  }
8729
- function gl(e) {
8801
+ function Sl(e) {
8730
8802
  return `${e}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
8731
8803
  }
8732
- function _l(e, t) {
8804
+ function Cl(e, t) {
8733
8805
  return Math.min(t - 140, 80 + e % 5 * 70);
8734
8806
  }
8735
- function vl(e) {
8807
+ function wl(e) {
8736
8808
  return e === "line" ? {
8737
8809
  height: 0,
8738
8810
  width: 210
@@ -8750,22 +8822,22 @@ function vl(e) {
8750
8822
  width: 180
8751
8823
  };
8752
8824
  }
8753
- function yl(e, t, n) {
8825
+ function Tl(e, t, n) {
8754
8826
  return Math.min(n, Math.max(t, e));
8755
8827
  }
8756
- function bl(e) {
8757
- return Number.isFinite(e) ? Math.min(900, Math.max(220, Math.round(e ?? el))) : el;
8828
+ function El(e) {
8829
+ return Number.isFinite(e) ? Math.min(900, Math.max(220, Math.round(e ?? ol))) : ol;
8758
8830
  }
8759
- function xl(e) {
8760
- let t = yl(e.width, .05, 1), n = yl(e.height, .05, 1);
8831
+ function Dl(e) {
8832
+ let t = Tl(e.width, .05, 1), n = Tl(e.height, .05, 1);
8761
8833
  return {
8762
8834
  height: n,
8763
8835
  width: t,
8764
- x: yl(e.x, 0, 1 - t),
8765
- y: yl(e.y, 0, 1 - n)
8836
+ x: Tl(e.x, 0, 1 - t),
8837
+ y: Tl(e.y, 0, 1 - n)
8766
8838
  };
8767
8839
  }
8768
- async function Sl(e) {
8840
+ async function Ol(e) {
8769
8841
  let t = await new Promise((t, n) => {
8770
8842
  let r = new FileReader();
8771
8843
  r.onerror = () => n(/* @__PURE__ */ Error("Unable to read image file.")), r.onload = () => t(String(r.result)), r.readAsDataURL(e);
@@ -8783,7 +8855,7 @@ async function Sl(e) {
8783
8855
  }
8784
8856
  //#endregion
8785
8857
  //#region src/exam-session/interactions/SingleChoice.tsx
8786
- function Cl({ answerId: e, choices: t, value: n, onChange: r }) {
8858
+ function kl({ answerId: e, choices: t, value: n, onChange: r }) {
8787
8859
  return /* @__PURE__ */ s("div", {
8788
8860
  className: "choice-group",
8789
8861
  role: "radiogroup",
@@ -8808,4 +8880,4 @@ function Cl({ answerId: e, choices: t, value: n, onChange: r }) {
8808
8880
  });
8809
8881
  }
8810
8882
  //#endregion
8811
- export { Ln as CoinTableResponse, ui as ColorPenPicker, di as DEFAULT_GEOMETRY_COLORS, fo as DEFAULT_NATIVE_VOICE_AI_CONFIG, $c as DraftSheet, Un as DragMatch, ts as ExamSectionRenderer, Pi as GeometryCanvas, ci as HandwrittenFractionAnswer, Y as HandwrittenNumberAnswer, ii as HandwrittenTextLine, Yn as INK_ERASER_COLOR, Jn as INK_ERASER_RADIUS, Xn as INK_ERASER_TRACE_FILL, ma as KonvaDrawingGrid, ha as LabelPlacement, va as NumberLineAnswer, Ga as OFFICE_SHAPE_GROUPS, Da as OperationWorkArea, Go as PlaceValueChoice, Wo as PlaceValueRepresentationView, Ra as PrimeFactorizationAnswer, ic as PrintableExamDocument, sc as PrintableQuestionRenderer, oc as PrintableSectionRenderer, lo as ProblemSheet, rl as ProblemSheetComposer, Ya as ProblemSheetShapeNode, yo as PronunciationRecorder, nc as QuestionPreviewPanel, es as QuestionRenderer, Hn as ShapeGlyph, Cl as SingleChoice, Oo as SortableAnswer, Ao as TextAnswer, zo as VisualSceneGraphic, Ze as areEquivalentFractions, Rt as calculateExamResult, et as createFractionGuidedWorkStep, Ho as createResponseOrderSeed, Lo as createVisualSceneFromVariant, Qn as eraseInkAlongPath, Je as evaluateFractionExpression, Ye as evaluateFractionExpressionUnreduced, po as evaluateVoiceAiResult, Bn as examShapeOptions, qe as formatOperationDecimal, jn as formatPlaceValueNumber, Ie as formatScoreValue, mi as getColorValue, Te as getConfiguredSubquestionScoreTotal, pi as getDefaultColorId, we as getDetailedQuestionMaxScore, Vn as getExamShapeLabel, rt as getFractionGuidedLaneOperators, nt as getFractionGuidedStepOperators, $e as getFractionWorkSteps, he as getGreatestCommonDivisor, Qr as getLanguageInkOutline, ge as getLeastCommonMultiple, Ot as getOperationAnswerId, Ct as getOperationSolvingExpression, bt as getOperationSolvingItems, St as getOperationSolvingSteps, Et as getOperationStepAnswerId, Ko as getOptionMarker, xe as getPedagogicalSubquestions, Mn as getPlaceValueNumber, An as getPlaceValueRepresentationText, kn as getPlaceValueTerms, me as getPrimeFactorComparison, pe as getPrimeFactorSlotCount, fe as getPrimeFactorizationComparisonSubquestionIds, W as getPrimeFactors, qa as getProblemSheetShapeLabel, Le as getQuestionMaxScore, ze as getSectionMaxScore, He as getSectionMaxScoreLabel, Vo as getStableShuffledOrder, Se as getSubquestionIdForUnit, De as getSubquestionPrefix, Ce as getSubquestionScore, G as getSubquestionSettings, Ro as getVisualSceneColorValue, _e as isPrimeNumber, Ja as isProblemSheetSquareShape, Be as isQuestionScored, Qe as isSimplifiedFraction, Zr as languageInkStrokeOptions, hi as mapChoicesToGeometryColors, xt as migrateOperationExpressionToContinuations, tt as normalizeFractionWorkStep, K as normalizeOperationDecimal, wt as normalizeOperationSolvingExpression, On as normalizePlaceValueNumber, Nn as normalizePlaceValueRepresentation, Yo as normalizeQuestionContentDirection, mo as normalizeVoiceText, Ke as parseOperationDecimal, ve as parsePositiveWholeNumber, Fe as parseScoreValue, Ve as requiresDeferredAiScoring, Xo as resolveQuestionContentDirection, Re as sectionHasQuestionScores, Oe as sectionUsesDetailedSubquestionScores, be as supportsPedagogicalSubquestions, kt as toOperationSolvingQuestion, Fo as visualSceneColorOptions, Po as visualSceneIconOptions, Io as visualSceneStateOptions, Ue as withDerivedSectionScore, Ee as withDerivedSubquestionScore, $o as withDisplayQuestionNumbers };
8883
+ export { Ln as CoinTableResponse, ui as ColorPenPicker, di as DEFAULT_GEOMETRY_COLORS, fo as DEFAULT_NATIVE_VOICE_AI_CONFIG, al as DraftSheet, Un as DragMatch, ts as ExamSectionRenderer, Pi as GeometryCanvas, ci as HandwrittenFractionAnswer, Y as HandwrittenNumberAnswer, ii as HandwrittenTextLine, Yn as INK_ERASER_COLOR, Jn as INK_ERASER_RADIUS, Xn as INK_ERASER_TRACE_FILL, ma as KonvaDrawingGrid, ha as LabelPlacement, va as NumberLineAnswer, Ga as OFFICE_SHAPE_GROUPS, Da as OperationWorkArea, Go as PlaceValueChoice, Wo as PlaceValueRepresentationView, Ra as PrimeFactorizationAnswer, ic as PrintableExamDocument, sc as PrintableQuestionRenderer, oc as PrintableSectionRenderer, lo as ProblemSheet, ll as ProblemSheetComposer, Ya as ProblemSheetShapeNode, yo as PronunciationRecorder, nc as QuestionPreviewPanel, es as QuestionRenderer, Hn as ShapeGlyph, kl as SingleChoice, Oo as SortableAnswer, Ao as TextAnswer, zo as VisualSceneGraphic, Ze as areEquivalentFractions, Rt as calculateExamResult, $c as createAserAdaptiveFlow, el as createAserCardFlow, et as createFractionGuidedWorkStep, Ho as createResponseOrderSeed, Lo as createVisualSceneFromVariant, Qn as eraseInkAlongPath, Je as evaluateFractionExpression, Ye as evaluateFractionExpressionUnreduced, po as evaluateVoiceAiResult, Bn as examShapeOptions, qe as formatOperationDecimal, jn as formatPlaceValueNumber, Ie as formatScoreValue, rl as getAserAdaptiveLevelRank, mi as getColorValue, Te as getConfiguredSubquestionScoreTotal, pi as getDefaultColorId, we as getDetailedQuestionMaxScore, Vn as getExamShapeLabel, rt as getFractionGuidedLaneOperators, nt as getFractionGuidedStepOperators, $e as getFractionWorkSteps, he as getGreatestCommonDivisor, Qr as getLanguageInkOutline, ge as getLeastCommonMultiple, Ot as getOperationAnswerId, Ct as getOperationSolvingExpression, bt as getOperationSolvingItems, St as getOperationSolvingSteps, Et as getOperationStepAnswerId, Ko as getOptionMarker, xe as getPedagogicalSubquestions, Mn as getPlaceValueNumber, An as getPlaceValueRepresentationText, kn as getPlaceValueTerms, me as getPrimeFactorComparison, pe as getPrimeFactorSlotCount, fe as getPrimeFactorizationComparisonSubquestionIds, W as getPrimeFactors, qa as getProblemSheetShapeLabel, Le as getQuestionMaxScore, ze as getSectionMaxScore, He as getSectionMaxScoreLabel, Vo as getStableShuffledOrder, Se as getSubquestionIdForUnit, De as getSubquestionPrefix, Ce as getSubquestionScore, G as getSubquestionSettings, Ro as getVisualSceneColorValue, _e as isPrimeNumber, Ja as isProblemSheetSquareShape, Be as isQuestionScored, Qe as isSimplifiedFraction, Zr as languageInkStrokeOptions, hi as mapChoicesToGeometryColors, xt as migrateOperationExpressionToContinuations, il as normalizeAserAdaptiveLevelCode, tt as normalizeFractionWorkStep, K as normalizeOperationDecimal, wt as normalizeOperationSolvingExpression, On as normalizePlaceValueNumber, Nn as normalizePlaceValueRepresentation, Yo as normalizeQuestionContentDirection, mo as normalizeVoiceText, Ke as parseOperationDecimal, ve as parsePositiveWholeNumber, Fe as parseScoreValue, Ve as requiresDeferredAiScoring, tl as resolveAserCardTransition, Xo as resolveQuestionContentDirection, Re as sectionHasQuestionScores, Oe as sectionUsesDetailedSubquestionScores, be as supportsPedagogicalSubquestions, kt as toOperationSolvingQuestion, Fo as visualSceneColorOptions, Po as visualSceneIconOptions, Io as visualSceneStateOptions, Ue as withDerivedSectionScore, Ee as withDerivedSubquestionScore, $o as withDisplayQuestionNumbers };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alexsys-exam-renderer",
3
- "version": "0.1.33",
3
+ "version": "0.1.34",
4
4
  "description": "React UI library for rendering digital exam interfaces.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -23,6 +23,7 @@
23
23
  "test:ink-eraser": "npm run build && node --test tests/inkEraser.integration.test.mjs",
24
24
  "test:operation-solving": "npm run build && node --test tests/operationSolving.integration.test.mjs",
25
25
  "test:place-value": "npm run build && node --test tests/placeValueChoice.integration.test.mjs",
26
+ "test:aser-flow": "npm run build && node --test tests/aserAdaptiveFlow.integration.test.mjs",
26
27
  "prepublishOnly": "npm run build"
27
28
  },
28
29
  "exports": {