@mathscan/math-exercise-engine 1.1.16 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -55,6 +55,8 @@ export declare const AST_TYPES: {
55
55
  readonly VOP_CARRY_ROW: "VopCarryRow";
56
56
  /** Number line layout block */
57
57
  readonly NUMBER_LINE_BLOCK: "NumberLineBlock";
58
+ /** Symmetry exercise on a square grid */
59
+ readonly GRID_SYMMETRY_BLOCK: "GridSymmetryBlock";
58
60
  /** A position marker on the number line */
59
61
  readonly NUMBER_LINE_POSITION: "NumberLinePosition";
60
62
  /** A draggable cursor on the number line */
@@ -636,8 +638,15 @@ export declare function compileWithAST(dsl: string): {
636
638
  }[] | undefined;
637
639
  dragMode?: "axis" | "inputs" | undefined;
638
640
  } | {
639
- type: "TableBlock";
641
+ axis: "horizontal" | "vertical";
642
+ type: "GridSymmetryBlock";
643
+ rows: number;
640
644
  cols: number;
645
+ interactiveArea: "left" | "right" | "top" | "bottom";
646
+ cellSize: number;
647
+ cells: [number, number][];
648
+ } | {
649
+ type: "TableBlock";
641
650
  rows: {
642
651
  type: "TableRow";
643
652
  cells: {
@@ -726,7 +735,9 @@ export declare function compileWithAST(dsl: string): {
726
735
  }[];
727
736
  backgroundColor?: string | undefined;
728
737
  }[];
738
+ cols: number;
729
739
  } | {
740
+ type: "VerticalOperationBlock";
730
741
  items: ({
731
742
  type: "VopRow";
732
743
  cells: ({
@@ -797,17 +808,17 @@ export declare function compileWithAST(dsl: string): {
797
808
  } | {
798
809
  type: "VopSeparator";
799
810
  })[];
800
- type: "VerticalOperationBlock";
801
811
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
802
812
  } | {
803
- type: "RadioOptions";
804
813
  options: string[];
814
+ type: "RadioOptions";
805
815
  name: string;
806
816
  answer: string;
807
817
  } | {
808
818
  type: "MatcherBlock";
809
819
  name: string;
810
820
  rows: {
821
+ type: "MatcherRow";
811
822
  items: {
812
823
  type: "MatcherItem";
813
824
  inlines: ({
@@ -857,7 +868,6 @@ export declare function compileWithAST(dsl: string): {
857
868
  })[];
858
869
  itemId: string;
859
870
  }[];
860
- type: "MatcherRow";
861
871
  }[];
862
872
  answers: string[][];
863
873
  colors?: string[] | undefined;
@@ -964,10 +974,6 @@ export declare function compileWithAST(dsl: string): {
964
974
  itemId: string;
965
975
  }[];
966
976
  })[];
967
- question?: {
968
- value: string;
969
- type: "TextBlock";
970
- } | undefined;
971
977
  validation?: {
972
978
  type: "SimpleValidation";
973
979
  } | {
@@ -977,9 +983,13 @@ export declare function compileWithAST(dsl: string): {
977
983
  expression: string;
978
984
  type: "MixedValidation";
979
985
  } | undefined;
986
+ question?: {
987
+ value: string;
988
+ type: "TextBlock";
989
+ } | undefined;
980
990
  tools?: ({
981
- type: "DragOptions";
982
991
  options: string[];
992
+ type: "DragOptions";
983
993
  } | {
984
994
  type: "NumericKeypad";
985
995
  style?: "diamond" | "classic" | undefined;
@@ -1010,14 +1020,14 @@ export declare function compileWithAST(dsl: string): {
1010
1020
  digits: number;
1011
1021
  placeholder?: string | undefined;
1012
1022
  } | {
1013
- type: "drag-options";
1014
1023
  options: string[];
1024
+ type: "drag-options";
1015
1025
  } | {
1016
1026
  value: string;
1017
1027
  type: "inline-drag-option";
1018
1028
  } | {
1019
- type: "radio-options";
1020
1029
  options: string[];
1030
+ type: "radio-options";
1021
1031
  } | {
1022
1032
  type: "numeric-keypad";
1023
1033
  style?: "diamond" | "classic" | undefined;
@@ -1032,13 +1042,13 @@ export declare function compileWithAST(dsl: string): {
1032
1042
  } | {
1033
1043
  type: "matcher";
1034
1044
  rows: {
1045
+ type: "matcher-row";
1035
1046
  items: {
1036
1047
  type: "matcher-item";
1037
1048
  itemId: string;
1038
1049
  id: string;
1039
1050
  content: any[];
1040
1051
  }[];
1041
- type: "matcher-row";
1042
1052
  id: string;
1043
1053
  }[];
1044
1054
  groupCount: number;
@@ -1066,6 +1076,14 @@ export declare function compileWithAST(dsl: string): {
1066
1076
  orientation?: "horizontal" | "vertical" | undefined;
1067
1077
  label?: string | undefined;
1068
1078
  size?: number | undefined;
1079
+ } | {
1080
+ axis: "horizontal" | "vertical";
1081
+ type: "grid-symmetry";
1082
+ rows: number;
1083
+ cols: number;
1084
+ interactiveArea: "left" | "right" | "top" | "bottom";
1085
+ cellSize: number;
1086
+ cells: [number, number][];
1069
1087
  } | {
1070
1088
  type: "ruler";
1071
1089
  size?: number | undefined;
@@ -1079,7 +1097,7 @@ export declare function compileWithAST(dsl: string): {
1079
1097
  validation?: {
1080
1098
  mode: "simple" | "expression" | "mixed";
1081
1099
  expression?: string | undefined;
1082
- answers?: Record<string, string | number | number[] | string[][]> | undefined;
1100
+ answers?: Record<string, string | number | number[] | string[][] | [number, number][]> | undefined;
1083
1101
  variables?: string[] | undefined;
1084
1102
  } | undefined;
1085
1103
  id?: string | undefined;
@@ -1092,6 +1110,22 @@ export declare function compileWithAST(dsl: string): {
1092
1110
  };
1093
1111
  };
1094
1112
 
1113
+ export declare function computeGridSymmetryCellsToFill(data: {
1114
+ rows: number;
1115
+ cols: number;
1116
+ axis: GridSymmetryAxis;
1117
+ interactiveArea: GridSymmetryInteractiveArea;
1118
+ cells: GridCell[];
1119
+ }): GridCell[];
1120
+
1121
+ export declare function computeGridSymmetryExpectedCells(data: {
1122
+ rows: number;
1123
+ cols: number;
1124
+ axis: GridSymmetryAxis;
1125
+ interactiveArea: GridSymmetryInteractiveArea;
1126
+ cells: GridCell[];
1127
+ }): GridCell[];
1128
+
1095
1129
  export declare type ContentBlock = z.infer<typeof ContentBlockSchema>;
1096
1130
 
1097
1131
  export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
@@ -2115,7 +2149,6 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
2115
2149
  }>, "many">;
2116
2150
  }, "strip", z.ZodTypeAny, {
2117
2151
  type: "TableBlock";
2118
- cols: number;
2119
2152
  rows: {
2120
2153
  type: "TableRow";
2121
2154
  cells: {
@@ -2204,9 +2237,9 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
2204
2237
  }[];
2205
2238
  backgroundColor?: string | undefined;
2206
2239
  }[];
2240
+ cols: number;
2207
2241
  }, {
2208
2242
  type: "TableBlock";
2209
- cols: number;
2210
2243
  rows: {
2211
2244
  type: "TableRow";
2212
2245
  cells: {
@@ -2295,19 +2328,20 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
2295
2328
  }[];
2296
2329
  backgroundColor?: string | undefined;
2297
2330
  }[];
2331
+ cols: number;
2298
2332
  }>, z.ZodObject<{
2299
2333
  type: z.ZodLiteral<"RadioOptions">;
2300
2334
  name: z.ZodString;
2301
2335
  options: z.ZodArray<z.ZodString, "many">;
2302
2336
  answer: z.ZodString;
2303
2337
  }, "strip", z.ZodTypeAny, {
2304
- type: "RadioOptions";
2305
2338
  options: string[];
2339
+ type: "RadioOptions";
2306
2340
  name: string;
2307
2341
  answer: string;
2308
2342
  }, {
2309
- type: "RadioOptions";
2310
2343
  options: string[];
2344
+ type: "RadioOptions";
2311
2345
  name: string;
2312
2346
  answer: string;
2313
2347
  }>, z.ZodEffects<z.ZodEffects<z.ZodObject<{
@@ -4900,6 +4934,7 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
4900
4934
  itemId: string;
4901
4935
  }>, "many">;
4902
4936
  }, "strip", z.ZodTypeAny, {
4937
+ type: "MatcherRow";
4903
4938
  items: {
4904
4939
  type: "MatcherItem";
4905
4940
  inlines: ({
@@ -4949,8 +4984,8 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
4949
4984
  })[];
4950
4985
  itemId: string;
4951
4986
  }[];
4952
- type: "MatcherRow";
4953
4987
  }, {
4988
+ type: "MatcherRow";
4954
4989
  items: {
4955
4990
  type: "MatcherItem";
4956
4991
  inlines: ({
@@ -5000,13 +5035,13 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
5000
5035
  })[];
5001
5036
  itemId: string;
5002
5037
  }[];
5003
- type: "MatcherRow";
5004
5038
  }>, "many">;
5005
5039
  answers: z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">;
5006
5040
  }, "strip", z.ZodTypeAny, {
5007
5041
  type: "MatcherBlock";
5008
5042
  name: string;
5009
5043
  rows: {
5044
+ type: "MatcherRow";
5010
5045
  items: {
5011
5046
  type: "MatcherItem";
5012
5047
  inlines: ({
@@ -5056,7 +5091,6 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
5056
5091
  })[];
5057
5092
  itemId: string;
5058
5093
  }[];
5059
- type: "MatcherRow";
5060
5094
  }[];
5061
5095
  answers: string[][];
5062
5096
  colors?: string[] | undefined;
@@ -5064,6 +5098,7 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
5064
5098
  type: "MatcherBlock";
5065
5099
  name: string;
5066
5100
  rows: {
5101
+ type: "MatcherRow";
5067
5102
  items: {
5068
5103
  type: "MatcherItem";
5069
5104
  inlines: ({
@@ -5113,7 +5148,6 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
5113
5148
  })[];
5114
5149
  itemId: string;
5115
5150
  }[];
5116
- type: "MatcherRow";
5117
5151
  }[];
5118
5152
  answers: string[][];
5119
5153
  colors?: string[] | undefined;
@@ -5121,6 +5155,7 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
5121
5155
  type: "MatcherBlock";
5122
5156
  name: string;
5123
5157
  rows: {
5158
+ type: "MatcherRow";
5124
5159
  items: {
5125
5160
  type: "MatcherItem";
5126
5161
  inlines: ({
@@ -5170,7 +5205,6 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
5170
5205
  })[];
5171
5206
  itemId: string;
5172
5207
  }[];
5173
- type: "MatcherRow";
5174
5208
  }[];
5175
5209
  answers: string[][];
5176
5210
  colors?: string[] | undefined;
@@ -5178,6 +5212,7 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
5178
5212
  type: "MatcherBlock";
5179
5213
  name: string;
5180
5214
  rows: {
5215
+ type: "MatcherRow";
5181
5216
  items: {
5182
5217
  type: "MatcherItem";
5183
5218
  inlines: ({
@@ -5227,7 +5262,6 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
5227
5262
  })[];
5228
5263
  itemId: string;
5229
5264
  }[];
5230
- type: "MatcherRow";
5231
5265
  }[];
5232
5266
  answers: string[][];
5233
5267
  colors?: string[] | undefined;
@@ -6553,6 +6587,7 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
6553
6587
  type: "VopSeparator";
6554
6588
  }>]>, "many">;
6555
6589
  }, "strip", z.ZodTypeAny, {
6590
+ type: "VerticalOperationBlock";
6556
6591
  items: ({
6557
6592
  type: "VopRow";
6558
6593
  cells: ({
@@ -6623,9 +6658,9 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
6623
6658
  } | {
6624
6659
  type: "VopSeparator";
6625
6660
  })[];
6626
- type: "VerticalOperationBlock";
6627
6661
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
6628
6662
  }, {
6663
+ type: "VerticalOperationBlock";
6629
6664
  items: ({
6630
6665
  type: "VopRow";
6631
6666
  cells: ({
@@ -6696,8 +6731,47 @@ export declare const ContentBlockSchema: z.ZodUnion<[z.ZodObject<{
6696
6731
  } | {
6697
6732
  type: "VopSeparator";
6698
6733
  })[];
6699
- type: "VerticalOperationBlock";
6700
6734
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
6735
+ }>, z.ZodEffects<z.ZodObject<{
6736
+ type: z.ZodLiteral<"GridSymmetryBlock">;
6737
+ rows: z.ZodNumber;
6738
+ cols: z.ZodNumber;
6739
+ axis: z.ZodEnum<["vertical", "horizontal"]>;
6740
+ interactiveArea: z.ZodEnum<["left", "right", "top", "bottom"]>;
6741
+ cellSize: z.ZodDefault<z.ZodNumber>;
6742
+ cells: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, "many">;
6743
+ }, "strip", z.ZodTypeAny, {
6744
+ axis: "horizontal" | "vertical";
6745
+ type: "GridSymmetryBlock";
6746
+ rows: number;
6747
+ cols: number;
6748
+ interactiveArea: "left" | "right" | "top" | "bottom";
6749
+ cellSize: number;
6750
+ cells: [number, number][];
6751
+ }, {
6752
+ axis: "horizontal" | "vertical";
6753
+ type: "GridSymmetryBlock";
6754
+ rows: number;
6755
+ cols: number;
6756
+ interactiveArea: "left" | "right" | "top" | "bottom";
6757
+ cells: [number, number][];
6758
+ cellSize?: number | undefined;
6759
+ }>, {
6760
+ axis: "horizontal" | "vertical";
6761
+ type: "GridSymmetryBlock";
6762
+ rows: number;
6763
+ cols: number;
6764
+ interactiveArea: "left" | "right" | "top" | "bottom";
6765
+ cellSize: number;
6766
+ cells: [number, number][];
6767
+ }, {
6768
+ axis: "horizontal" | "vertical";
6769
+ type: "GridSymmetryBlock";
6770
+ rows: number;
6771
+ cols: number;
6772
+ interactiveArea: "left" | "right" | "top" | "bottom";
6773
+ cells: [number, number][];
6774
+ cellSize?: number | undefined;
6701
6775
  }>]>;
6702
6776
 
6703
6777
  /**
@@ -6751,6 +6825,8 @@ export declare function createFraction(name: string, options?: {
6751
6825
  */
6752
6826
  export declare function createFreeText(value: string): FreeTextInline;
6753
6827
 
6828
+ export declare function createGridSymmetryBlock(rows: number, cols: number, axis: GridSymmetryAxis, interactiveArea: GridSymmetryInteractiveArea, cells: GridCell[], cellSize?: number): GridSymmetryBlock;
6829
+
6754
6830
  /**
6755
6831
  * Create a highlighted text inline element
6756
6832
  */
@@ -7068,11 +7144,11 @@ export declare const DragOptionsJSONSchema: z.ZodObject<{
7068
7144
  type: z.ZodLiteral<"drag-options">;
7069
7145
  options: z.ZodArray<z.ZodString, "many">;
7070
7146
  }, "strip", z.ZodTypeAny, {
7071
- type: "drag-options";
7072
7147
  options: string[];
7073
- }, {
7074
7148
  type: "drag-options";
7149
+ }, {
7075
7150
  options: string[];
7151
+ type: "drag-options";
7076
7152
  }>;
7077
7153
 
7078
7154
  export declare type DragOptionsTool = z.infer<typeof DragOptionsToolSchema>;
@@ -7095,11 +7171,11 @@ export declare const DragOptionsToolSchema: z.ZodObject<{
7095
7171
  type: z.ZodLiteral<"DragOptions">;
7096
7172
  options: z.ZodArray<z.ZodString, "many">;
7097
7173
  }, "strip", z.ZodTypeAny, {
7098
- type: "DragOptions";
7099
7174
  options: string[];
7100
- }, {
7101
7175
  type: "DragOptions";
7176
+ }, {
7102
7177
  options: string[];
7178
+ type: "DragOptions";
7103
7179
  }>;
7104
7180
 
7105
7181
  /**
@@ -8188,7 +8264,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
8188
8264
  }>, "many">;
8189
8265
  }, "strip", z.ZodTypeAny, {
8190
8266
  type: "TableBlock";
8191
- cols: number;
8192
8267
  rows: {
8193
8268
  type: "TableRow";
8194
8269
  cells: {
@@ -8277,9 +8352,9 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
8277
8352
  }[];
8278
8353
  backgroundColor?: string | undefined;
8279
8354
  }[];
8355
+ cols: number;
8280
8356
  }, {
8281
8357
  type: "TableBlock";
8282
- cols: number;
8283
8358
  rows: {
8284
8359
  type: "TableRow";
8285
8360
  cells: {
@@ -8368,19 +8443,20 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
8368
8443
  }[];
8369
8444
  backgroundColor?: string | undefined;
8370
8445
  }[];
8446
+ cols: number;
8371
8447
  }>, z.ZodObject<{
8372
8448
  type: z.ZodLiteral<"RadioOptions">;
8373
8449
  name: z.ZodString;
8374
8450
  options: z.ZodArray<z.ZodString, "many">;
8375
8451
  answer: z.ZodString;
8376
8452
  }, "strip", z.ZodTypeAny, {
8377
- type: "RadioOptions";
8378
8453
  options: string[];
8454
+ type: "RadioOptions";
8379
8455
  name: string;
8380
8456
  answer: string;
8381
8457
  }, {
8382
- type: "RadioOptions";
8383
8458
  options: string[];
8459
+ type: "RadioOptions";
8384
8460
  name: string;
8385
8461
  answer: string;
8386
8462
  }>, z.ZodEffects<z.ZodEffects<z.ZodObject<{
@@ -10973,6 +11049,7 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
10973
11049
  itemId: string;
10974
11050
  }>, "many">;
10975
11051
  }, "strip", z.ZodTypeAny, {
11052
+ type: "MatcherRow";
10976
11053
  items: {
10977
11054
  type: "MatcherItem";
10978
11055
  inlines: ({
@@ -11022,8 +11099,8 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
11022
11099
  })[];
11023
11100
  itemId: string;
11024
11101
  }[];
11025
- type: "MatcherRow";
11026
11102
  }, {
11103
+ type: "MatcherRow";
11027
11104
  items: {
11028
11105
  type: "MatcherItem";
11029
11106
  inlines: ({
@@ -11073,13 +11150,13 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
11073
11150
  })[];
11074
11151
  itemId: string;
11075
11152
  }[];
11076
- type: "MatcherRow";
11077
11153
  }>, "many">;
11078
11154
  answers: z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">;
11079
11155
  }, "strip", z.ZodTypeAny, {
11080
11156
  type: "MatcherBlock";
11081
11157
  name: string;
11082
11158
  rows: {
11159
+ type: "MatcherRow";
11083
11160
  items: {
11084
11161
  type: "MatcherItem";
11085
11162
  inlines: ({
@@ -11129,7 +11206,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
11129
11206
  })[];
11130
11207
  itemId: string;
11131
11208
  }[];
11132
- type: "MatcherRow";
11133
11209
  }[];
11134
11210
  answers: string[][];
11135
11211
  colors?: string[] | undefined;
@@ -11137,6 +11213,7 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
11137
11213
  type: "MatcherBlock";
11138
11214
  name: string;
11139
11215
  rows: {
11216
+ type: "MatcherRow";
11140
11217
  items: {
11141
11218
  type: "MatcherItem";
11142
11219
  inlines: ({
@@ -11186,7 +11263,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
11186
11263
  })[];
11187
11264
  itemId: string;
11188
11265
  }[];
11189
- type: "MatcherRow";
11190
11266
  }[];
11191
11267
  answers: string[][];
11192
11268
  colors?: string[] | undefined;
@@ -11194,6 +11270,7 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
11194
11270
  type: "MatcherBlock";
11195
11271
  name: string;
11196
11272
  rows: {
11273
+ type: "MatcherRow";
11197
11274
  items: {
11198
11275
  type: "MatcherItem";
11199
11276
  inlines: ({
@@ -11243,7 +11320,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
11243
11320
  })[];
11244
11321
  itemId: string;
11245
11322
  }[];
11246
- type: "MatcherRow";
11247
11323
  }[];
11248
11324
  answers: string[][];
11249
11325
  colors?: string[] | undefined;
@@ -11251,6 +11327,7 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
11251
11327
  type: "MatcherBlock";
11252
11328
  name: string;
11253
11329
  rows: {
11330
+ type: "MatcherRow";
11254
11331
  items: {
11255
11332
  type: "MatcherItem";
11256
11333
  inlines: ({
@@ -11300,7 +11377,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
11300
11377
  })[];
11301
11378
  itemId: string;
11302
11379
  }[];
11303
- type: "MatcherRow";
11304
11380
  }[];
11305
11381
  answers: string[][];
11306
11382
  colors?: string[] | undefined;
@@ -12626,6 +12702,7 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
12626
12702
  type: "VopSeparator";
12627
12703
  }>]>, "many">;
12628
12704
  }, "strip", z.ZodTypeAny, {
12705
+ type: "VerticalOperationBlock";
12629
12706
  items: ({
12630
12707
  type: "VopRow";
12631
12708
  cells: ({
@@ -12696,9 +12773,9 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
12696
12773
  } | {
12697
12774
  type: "VopSeparator";
12698
12775
  })[];
12699
- type: "VerticalOperationBlock";
12700
12776
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
12701
12777
  }, {
12778
+ type: "VerticalOperationBlock";
12702
12779
  items: ({
12703
12780
  type: "VopRow";
12704
12781
  cells: ({
@@ -12769,18 +12846,57 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
12769
12846
  } | {
12770
12847
  type: "VopSeparator";
12771
12848
  })[];
12772
- type: "VerticalOperationBlock";
12773
12849
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
12850
+ }>, z.ZodEffects<z.ZodObject<{
12851
+ type: z.ZodLiteral<"GridSymmetryBlock">;
12852
+ rows: z.ZodNumber;
12853
+ cols: z.ZodNumber;
12854
+ axis: z.ZodEnum<["vertical", "horizontal"]>;
12855
+ interactiveArea: z.ZodEnum<["left", "right", "top", "bottom"]>;
12856
+ cellSize: z.ZodDefault<z.ZodNumber>;
12857
+ cells: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, "many">;
12858
+ }, "strip", z.ZodTypeAny, {
12859
+ axis: "horizontal" | "vertical";
12860
+ type: "GridSymmetryBlock";
12861
+ rows: number;
12862
+ cols: number;
12863
+ interactiveArea: "left" | "right" | "top" | "bottom";
12864
+ cellSize: number;
12865
+ cells: [number, number][];
12866
+ }, {
12867
+ axis: "horizontal" | "vertical";
12868
+ type: "GridSymmetryBlock";
12869
+ rows: number;
12870
+ cols: number;
12871
+ interactiveArea: "left" | "right" | "top" | "bottom";
12872
+ cells: [number, number][];
12873
+ cellSize?: number | undefined;
12874
+ }>, {
12875
+ axis: "horizontal" | "vertical";
12876
+ type: "GridSymmetryBlock";
12877
+ rows: number;
12878
+ cols: number;
12879
+ interactiveArea: "left" | "right" | "top" | "bottom";
12880
+ cellSize: number;
12881
+ cells: [number, number][];
12882
+ }, {
12883
+ axis: "horizontal" | "vertical";
12884
+ type: "GridSymmetryBlock";
12885
+ rows: number;
12886
+ cols: number;
12887
+ interactiveArea: "left" | "right" | "top" | "bottom";
12888
+ cells: [number, number][];
12889
+ cellSize?: number | undefined;
12774
12890
  }>]>, "many">;
12775
12891
  tools: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
12776
12892
  type: z.ZodLiteral<"DragOptions">;
12777
12893
  options: z.ZodArray<z.ZodString, "many">;
12778
12894
  }, "strip", z.ZodTypeAny, {
12779
- type: "DragOptions";
12780
12895
  options: string[];
12781
- }, {
12782
12896
  type: "DragOptions";
12897
+ }, {
12783
12898
  options: string[];
12899
+ type: "DragOptions";
12784
12900
  }>, z.ZodObject<{
12785
12901
  type: z.ZodLiteral<"NumericKeypad">;
12786
12902
  includeOperators: z.ZodOptional<z.ZodBoolean>;
@@ -13130,8 +13246,15 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
13130
13246
  }[] | undefined;
13131
13247
  dragMode?: "axis" | "inputs" | undefined;
13132
13248
  } | {
13133
- type: "TableBlock";
13249
+ axis: "horizontal" | "vertical";
13250
+ type: "GridSymmetryBlock";
13251
+ rows: number;
13134
13252
  cols: number;
13253
+ interactiveArea: "left" | "right" | "top" | "bottom";
13254
+ cellSize: number;
13255
+ cells: [number, number][];
13256
+ } | {
13257
+ type: "TableBlock";
13135
13258
  rows: {
13136
13259
  type: "TableRow";
13137
13260
  cells: {
@@ -13220,7 +13343,9 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
13220
13343
  }[];
13221
13344
  backgroundColor?: string | undefined;
13222
13345
  }[];
13346
+ cols: number;
13223
13347
  } | {
13348
+ type: "VerticalOperationBlock";
13224
13349
  items: ({
13225
13350
  type: "VopRow";
13226
13351
  cells: ({
@@ -13291,17 +13416,17 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
13291
13416
  } | {
13292
13417
  type: "VopSeparator";
13293
13418
  })[];
13294
- type: "VerticalOperationBlock";
13295
13419
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
13296
13420
  } | {
13297
- type: "RadioOptions";
13298
13421
  options: string[];
13422
+ type: "RadioOptions";
13299
13423
  name: string;
13300
13424
  answer: string;
13301
13425
  } | {
13302
13426
  type: "MatcherBlock";
13303
13427
  name: string;
13304
13428
  rows: {
13429
+ type: "MatcherRow";
13305
13430
  items: {
13306
13431
  type: "MatcherItem";
13307
13432
  inlines: ({
@@ -13351,7 +13476,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
13351
13476
  })[];
13352
13477
  itemId: string;
13353
13478
  }[];
13354
- type: "MatcherRow";
13355
13479
  }[];
13356
13480
  answers: string[][];
13357
13481
  colors?: string[] | undefined;
@@ -13458,10 +13582,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
13458
13582
  itemId: string;
13459
13583
  }[];
13460
13584
  })[];
13461
- question?: {
13462
- value: string;
13463
- type: "TextBlock";
13464
- } | undefined;
13465
13585
  validation?: {
13466
13586
  type: "SimpleValidation";
13467
13587
  } | {
@@ -13471,9 +13591,13 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
13471
13591
  expression: string;
13472
13592
  type: "MixedValidation";
13473
13593
  } | undefined;
13594
+ question?: {
13595
+ value: string;
13596
+ type: "TextBlock";
13597
+ } | undefined;
13474
13598
  tools?: ({
13475
- type: "DragOptions";
13476
13599
  options: string[];
13600
+ type: "DragOptions";
13477
13601
  } | {
13478
13602
  type: "NumericKeypad";
13479
13603
  style?: "diamond" | "classic" | undefined;
@@ -13770,8 +13894,15 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
13770
13894
  }[] | undefined;
13771
13895
  dragMode?: "axis" | "inputs" | undefined;
13772
13896
  } | {
13773
- type: "TableBlock";
13897
+ axis: "horizontal" | "vertical";
13898
+ type: "GridSymmetryBlock";
13899
+ rows: number;
13774
13900
  cols: number;
13901
+ interactiveArea: "left" | "right" | "top" | "bottom";
13902
+ cells: [number, number][];
13903
+ cellSize?: number | undefined;
13904
+ } | {
13905
+ type: "TableBlock";
13775
13906
  rows: {
13776
13907
  type: "TableRow";
13777
13908
  cells: {
@@ -13860,7 +13991,9 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
13860
13991
  }[];
13861
13992
  backgroundColor?: string | undefined;
13862
13993
  }[];
13994
+ cols: number;
13863
13995
  } | {
13996
+ type: "VerticalOperationBlock";
13864
13997
  items: ({
13865
13998
  type: "VopRow";
13866
13999
  cells: ({
@@ -13931,17 +14064,17 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
13931
14064
  } | {
13932
14065
  type: "VopSeparator";
13933
14066
  })[];
13934
- type: "VerticalOperationBlock";
13935
14067
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
13936
14068
  } | {
13937
- type: "RadioOptions";
13938
14069
  options: string[];
14070
+ type: "RadioOptions";
13939
14071
  name: string;
13940
14072
  answer: string;
13941
14073
  } | {
13942
14074
  type: "MatcherBlock";
13943
14075
  name: string;
13944
14076
  rows: {
14077
+ type: "MatcherRow";
13945
14078
  items: {
13946
14079
  type: "MatcherItem";
13947
14080
  inlines: ({
@@ -13991,7 +14124,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
13991
14124
  })[];
13992
14125
  itemId: string;
13993
14126
  }[];
13994
- type: "MatcherRow";
13995
14127
  }[];
13996
14128
  answers: string[][];
13997
14129
  colors?: string[] | undefined;
@@ -14098,10 +14230,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
14098
14230
  itemId: string;
14099
14231
  }[];
14100
14232
  })[];
14101
- question?: {
14102
- value: string;
14103
- type: "TextBlock";
14104
- } | undefined;
14105
14233
  validation?: {
14106
14234
  type: "SimpleValidation";
14107
14235
  } | {
@@ -14111,9 +14239,13 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
14111
14239
  expression: string;
14112
14240
  type: "MixedValidation";
14113
14241
  } | undefined;
14242
+ question?: {
14243
+ value: string;
14244
+ type: "TextBlock";
14245
+ } | undefined;
14114
14246
  tools?: ({
14115
- type: "DragOptions";
14116
14247
  options: string[];
14248
+ type: "DragOptions";
14117
14249
  } | {
14118
14250
  type: "NumericKeypad";
14119
14251
  style?: "diamond" | "classic" | undefined;
@@ -14410,8 +14542,15 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
14410
14542
  }[] | undefined;
14411
14543
  dragMode?: "axis" | "inputs" | undefined;
14412
14544
  } | {
14413
- type: "TableBlock";
14545
+ axis: "horizontal" | "vertical";
14546
+ type: "GridSymmetryBlock";
14547
+ rows: number;
14414
14548
  cols: number;
14549
+ interactiveArea: "left" | "right" | "top" | "bottom";
14550
+ cellSize: number;
14551
+ cells: [number, number][];
14552
+ } | {
14553
+ type: "TableBlock";
14415
14554
  rows: {
14416
14555
  type: "TableRow";
14417
14556
  cells: {
@@ -14500,7 +14639,9 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
14500
14639
  }[];
14501
14640
  backgroundColor?: string | undefined;
14502
14641
  }[];
14642
+ cols: number;
14503
14643
  } | {
14644
+ type: "VerticalOperationBlock";
14504
14645
  items: ({
14505
14646
  type: "VopRow";
14506
14647
  cells: ({
@@ -14571,17 +14712,17 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
14571
14712
  } | {
14572
14713
  type: "VopSeparator";
14573
14714
  })[];
14574
- type: "VerticalOperationBlock";
14575
14715
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
14576
14716
  } | {
14577
- type: "RadioOptions";
14578
14717
  options: string[];
14718
+ type: "RadioOptions";
14579
14719
  name: string;
14580
14720
  answer: string;
14581
14721
  } | {
14582
14722
  type: "MatcherBlock";
14583
14723
  name: string;
14584
14724
  rows: {
14725
+ type: "MatcherRow";
14585
14726
  items: {
14586
14727
  type: "MatcherItem";
14587
14728
  inlines: ({
@@ -14631,7 +14772,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
14631
14772
  })[];
14632
14773
  itemId: string;
14633
14774
  }[];
14634
- type: "MatcherRow";
14635
14775
  }[];
14636
14776
  answers: string[][];
14637
14777
  colors?: string[] | undefined;
@@ -14738,10 +14878,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
14738
14878
  itemId: string;
14739
14879
  }[];
14740
14880
  })[];
14741
- question?: {
14742
- value: string;
14743
- type: "TextBlock";
14744
- } | undefined;
14745
14881
  validation?: {
14746
14882
  type: "SimpleValidation";
14747
14883
  } | {
@@ -14751,9 +14887,13 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
14751
14887
  expression: string;
14752
14888
  type: "MixedValidation";
14753
14889
  } | undefined;
14890
+ question?: {
14891
+ value: string;
14892
+ type: "TextBlock";
14893
+ } | undefined;
14754
14894
  tools?: ({
14755
- type: "DragOptions";
14756
14895
  options: string[];
14896
+ type: "DragOptions";
14757
14897
  } | {
14758
14898
  type: "NumericKeypad";
14759
14899
  style?: "diamond" | "classic" | undefined;
@@ -15050,8 +15190,15 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
15050
15190
  }[] | undefined;
15051
15191
  dragMode?: "axis" | "inputs" | undefined;
15052
15192
  } | {
15053
- type: "TableBlock";
15193
+ axis: "horizontal" | "vertical";
15194
+ type: "GridSymmetryBlock";
15195
+ rows: number;
15054
15196
  cols: number;
15197
+ interactiveArea: "left" | "right" | "top" | "bottom";
15198
+ cells: [number, number][];
15199
+ cellSize?: number | undefined;
15200
+ } | {
15201
+ type: "TableBlock";
15055
15202
  rows: {
15056
15203
  type: "TableRow";
15057
15204
  cells: {
@@ -15140,7 +15287,9 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
15140
15287
  }[];
15141
15288
  backgroundColor?: string | undefined;
15142
15289
  }[];
15290
+ cols: number;
15143
15291
  } | {
15292
+ type: "VerticalOperationBlock";
15144
15293
  items: ({
15145
15294
  type: "VopRow";
15146
15295
  cells: ({
@@ -15211,17 +15360,17 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
15211
15360
  } | {
15212
15361
  type: "VopSeparator";
15213
15362
  })[];
15214
- type: "VerticalOperationBlock";
15215
15363
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
15216
15364
  } | {
15217
- type: "RadioOptions";
15218
15365
  options: string[];
15366
+ type: "RadioOptions";
15219
15367
  name: string;
15220
15368
  answer: string;
15221
15369
  } | {
15222
15370
  type: "MatcherBlock";
15223
15371
  name: string;
15224
15372
  rows: {
15373
+ type: "MatcherRow";
15225
15374
  items: {
15226
15375
  type: "MatcherItem";
15227
15376
  inlines: ({
@@ -15271,7 +15420,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
15271
15420
  })[];
15272
15421
  itemId: string;
15273
15422
  }[];
15274
- type: "MatcherRow";
15275
15423
  }[];
15276
15424
  answers: string[][];
15277
15425
  colors?: string[] | undefined;
@@ -15378,10 +15526,6 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
15378
15526
  itemId: string;
15379
15527
  }[];
15380
15528
  })[];
15381
- question?: {
15382
- value: string;
15383
- type: "TextBlock";
15384
- } | undefined;
15385
15529
  validation?: {
15386
15530
  type: "SimpleValidation";
15387
15531
  } | {
@@ -15391,9 +15535,13 @@ export declare const ExerciseDocumentSchema: z.ZodEffects<z.ZodObject<{
15391
15535
  expression: string;
15392
15536
  type: "MixedValidation";
15393
15537
  } | undefined;
15538
+ question?: {
15539
+ value: string;
15540
+ type: "TextBlock";
15541
+ } | undefined;
15394
15542
  tools?: ({
15395
- type: "DragOptions";
15396
15543
  options: string[];
15544
+ type: "DragOptions";
15397
15545
  } | {
15398
15546
  type: "NumericKeypad";
15399
15547
  style?: "diamond" | "classic" | undefined;
@@ -15451,11 +15599,11 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15451
15599
  type: z.ZodLiteral<"drag-options">;
15452
15600
  options: z.ZodArray<z.ZodString, "many">;
15453
15601
  }, "strip", z.ZodTypeAny, {
15454
- type: "drag-options";
15455
15602
  options: string[];
15456
- }, {
15457
15603
  type: "drag-options";
15604
+ }, {
15458
15605
  options: string[];
15606
+ type: "drag-options";
15459
15607
  }>, z.ZodObject<{
15460
15608
  type: z.ZodLiteral<"inline-drag-option">;
15461
15609
  value: z.ZodString;
@@ -15469,11 +15617,11 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15469
15617
  type: z.ZodLiteral<"radio-options">;
15470
15618
  options: z.ZodArray<z.ZodString, "many">;
15471
15619
  }, "strip", z.ZodTypeAny, {
15472
- type: "radio-options";
15473
15620
  options: string[];
15474
- }, {
15475
15621
  type: "radio-options";
15622
+ }, {
15476
15623
  options: string[];
15624
+ type: "radio-options";
15477
15625
  }>, z.ZodObject<{
15478
15626
  type: z.ZodLiteral<"numeric-keypad">;
15479
15627
  includeOperators: z.ZodOptional<z.ZodBoolean>;
@@ -15531,22 +15679,22 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15531
15679
  content: any[];
15532
15680
  }>, "many">;
15533
15681
  }, "strip", z.ZodTypeAny, {
15682
+ type: "matcher-row";
15534
15683
  items: {
15535
15684
  type: "matcher-item";
15536
15685
  itemId: string;
15537
15686
  id: string;
15538
15687
  content: any[];
15539
15688
  }[];
15540
- type: "matcher-row";
15541
15689
  id: string;
15542
15690
  }, {
15691
+ type: "matcher-row";
15543
15692
  items: {
15544
15693
  type: "matcher-item";
15545
15694
  itemId: string;
15546
15695
  id: string;
15547
15696
  content: any[];
15548
15697
  }[];
15549
- type: "matcher-row";
15550
15698
  id: string;
15551
15699
  }>, "many">;
15552
15700
  /** Optional color palette for the renderer (one color per answer group) */
@@ -15556,13 +15704,13 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15556
15704
  }, "strip", z.ZodTypeAny, {
15557
15705
  type: "matcher";
15558
15706
  rows: {
15707
+ type: "matcher-row";
15559
15708
  items: {
15560
15709
  type: "matcher-item";
15561
15710
  itemId: string;
15562
15711
  id: string;
15563
15712
  content: any[];
15564
15713
  }[];
15565
- type: "matcher-row";
15566
15714
  id: string;
15567
15715
  }[];
15568
15716
  groupCount: number;
@@ -15570,13 +15718,13 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15570
15718
  }, {
15571
15719
  type: "matcher";
15572
15720
  rows: {
15721
+ type: "matcher-row";
15573
15722
  items: {
15574
15723
  type: "matcher-item";
15575
15724
  itemId: string;
15576
15725
  id: string;
15577
15726
  content: any[];
15578
15727
  }[];
15579
- type: "matcher-row";
15580
15728
  id: string;
15581
15729
  }[];
15582
15730
  groupCount: number;
@@ -15697,6 +15845,46 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15697
15845
  orientation?: "horizontal" | "vertical" | undefined;
15698
15846
  label?: string | undefined;
15699
15847
  size?: number | undefined;
15848
+ }>, z.ZodEffects<z.ZodObject<{
15849
+ type: z.ZodLiteral<"grid-symmetry">;
15850
+ rows: z.ZodNumber;
15851
+ cols: z.ZodNumber;
15852
+ axis: z.ZodEnum<["vertical", "horizontal"]>;
15853
+ interactiveArea: z.ZodEnum<["left", "right", "top", "bottom"]>;
15854
+ cellSize: z.ZodDefault<z.ZodNumber>;
15855
+ cells: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, "many">;
15856
+ }, "strip", z.ZodTypeAny, {
15857
+ axis: "horizontal" | "vertical";
15858
+ type: "grid-symmetry";
15859
+ rows: number;
15860
+ cols: number;
15861
+ interactiveArea: "left" | "right" | "top" | "bottom";
15862
+ cellSize: number;
15863
+ cells: [number, number][];
15864
+ }, {
15865
+ axis: "horizontal" | "vertical";
15866
+ type: "grid-symmetry";
15867
+ rows: number;
15868
+ cols: number;
15869
+ interactiveArea: "left" | "right" | "top" | "bottom";
15870
+ cells: [number, number][];
15871
+ cellSize?: number | undefined;
15872
+ }>, {
15873
+ axis: "horizontal" | "vertical";
15874
+ type: "grid-symmetry";
15875
+ rows: number;
15876
+ cols: number;
15877
+ interactiveArea: "left" | "right" | "top" | "bottom";
15878
+ cellSize: number;
15879
+ cells: [number, number][];
15880
+ }, {
15881
+ axis: "horizontal" | "vertical";
15882
+ type: "grid-symmetry";
15883
+ rows: number;
15884
+ cols: number;
15885
+ interactiveArea: "left" | "right" | "top" | "bottom";
15886
+ cells: [number, number][];
15887
+ cellSize?: number | undefined;
15700
15888
  }>, z.ZodObject<{
15701
15889
  type: z.ZodLiteral<"ruler">;
15702
15890
  size: z.ZodOptional<z.ZodNumber>;
@@ -15727,18 +15915,18 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15727
15915
  }>]>>;
15728
15916
  validation: z.ZodOptional<z.ZodObject<{
15729
15917
  mode: z.ZodEnum<["simple", "expression", "mixed"]>;
15730
- answers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">, z.ZodArray<z.ZodNumber, "many">]>>>;
15918
+ answers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">, z.ZodArray<z.ZodNumber, "many">, z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, "many">]>>>;
15731
15919
  expression: z.ZodOptional<z.ZodString>;
15732
15920
  variables: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
15733
15921
  }, "strip", z.ZodTypeAny, {
15734
15922
  mode: "simple" | "expression" | "mixed";
15735
15923
  expression?: string | undefined;
15736
- answers?: Record<string, string | number | number[] | string[][]> | undefined;
15924
+ answers?: Record<string, string | number | number[] | string[][] | [number, number][]> | undefined;
15737
15925
  variables?: string[] | undefined;
15738
15926
  }, {
15739
15927
  mode: "simple" | "expression" | "mixed";
15740
15928
  expression?: string | undefined;
15741
- answers?: Record<string, string | number | number[] | string[][]> | undefined;
15929
+ answers?: Record<string, string | number | number[] | string[][] | [number, number][]> | undefined;
15742
15930
  variables?: string[] | undefined;
15743
15931
  }>>;
15744
15932
  meta: z.ZodOptional<z.ZodObject<{
@@ -15771,14 +15959,14 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15771
15959
  digits: number;
15772
15960
  placeholder?: string | undefined;
15773
15961
  } | {
15774
- type: "drag-options";
15775
15962
  options: string[];
15963
+ type: "drag-options";
15776
15964
  } | {
15777
15965
  value: string;
15778
15966
  type: "inline-drag-option";
15779
15967
  } | {
15780
- type: "radio-options";
15781
15968
  options: string[];
15969
+ type: "radio-options";
15782
15970
  } | {
15783
15971
  type: "numeric-keypad";
15784
15972
  style?: "diamond" | "classic" | undefined;
@@ -15793,13 +15981,13 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15793
15981
  } | {
15794
15982
  type: "matcher";
15795
15983
  rows: {
15984
+ type: "matcher-row";
15796
15985
  items: {
15797
15986
  type: "matcher-item";
15798
15987
  itemId: string;
15799
15988
  id: string;
15800
15989
  content: any[];
15801
15990
  }[];
15802
- type: "matcher-row";
15803
15991
  id: string;
15804
15992
  }[];
15805
15993
  groupCount: number;
@@ -15827,6 +16015,14 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15827
16015
  orientation?: "horizontal" | "vertical" | undefined;
15828
16016
  label?: string | undefined;
15829
16017
  size?: number | undefined;
16018
+ } | {
16019
+ axis: "horizontal" | "vertical";
16020
+ type: "grid-symmetry";
16021
+ rows: number;
16022
+ cols: number;
16023
+ interactiveArea: "left" | "right" | "top" | "bottom";
16024
+ cellSize: number;
16025
+ cells: [number, number][];
15830
16026
  } | {
15831
16027
  type: "ruler";
15832
16028
  size?: number | undefined;
@@ -15840,7 +16036,7 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15840
16036
  validation?: {
15841
16037
  mode: "simple" | "expression" | "mixed";
15842
16038
  expression?: string | undefined;
15843
- answers?: Record<string, string | number | number[] | string[][]> | undefined;
16039
+ answers?: Record<string, string | number | number[] | string[][] | [number, number][]> | undefined;
15844
16040
  variables?: string[] | undefined;
15845
16041
  } | undefined;
15846
16042
  id?: string | undefined;
@@ -15864,14 +16060,14 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15864
16060
  digits: number;
15865
16061
  placeholder?: string | undefined;
15866
16062
  } | {
15867
- type: "drag-options";
15868
16063
  options: string[];
16064
+ type: "drag-options";
15869
16065
  } | {
15870
16066
  value: string;
15871
16067
  type: "inline-drag-option";
15872
16068
  } | {
15873
- type: "radio-options";
15874
16069
  options: string[];
16070
+ type: "radio-options";
15875
16071
  } | {
15876
16072
  type: "numeric-keypad";
15877
16073
  style?: "diamond" | "classic" | undefined;
@@ -15886,13 +16082,13 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15886
16082
  } | {
15887
16083
  type: "matcher";
15888
16084
  rows: {
16085
+ type: "matcher-row";
15889
16086
  items: {
15890
16087
  type: "matcher-item";
15891
16088
  itemId: string;
15892
16089
  id: string;
15893
16090
  content: any[];
15894
16091
  }[];
15895
- type: "matcher-row";
15896
16092
  id: string;
15897
16093
  }[];
15898
16094
  groupCount: number;
@@ -15920,6 +16116,14 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15920
16116
  orientation?: "horizontal" | "vertical" | undefined;
15921
16117
  label?: string | undefined;
15922
16118
  size?: number | undefined;
16119
+ } | {
16120
+ axis: "horizontal" | "vertical";
16121
+ type: "grid-symmetry";
16122
+ rows: number;
16123
+ cols: number;
16124
+ interactiveArea: "left" | "right" | "top" | "bottom";
16125
+ cells: [number, number][];
16126
+ cellSize?: number | undefined;
15923
16127
  } | {
15924
16128
  type: "ruler";
15925
16129
  size?: number | undefined;
@@ -15933,7 +16137,7 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15933
16137
  validation?: {
15934
16138
  mode: "simple" | "expression" | "mixed";
15935
16139
  expression?: string | undefined;
15936
- answers?: Record<string, string | number | number[] | string[][]> | undefined;
16140
+ answers?: Record<string, string | number | number[] | string[][] | [number, number][]> | undefined;
15937
16141
  variables?: string[] | undefined;
15938
16142
  } | undefined;
15939
16143
  id?: string | undefined;
@@ -15945,6 +16149,20 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
15945
16149
  } | undefined;
15946
16150
  }>;
15947
16151
 
16152
+ /**
16153
+ * Broadcasts the exercise lock to every widget.
16154
+ *
16155
+ * A context (rather than a prop threaded through LayoutRenderer → WidgetRenderer)
16156
+ * because interactive elements sit 3–4 levels deep (number-line arcs, matcher
16157
+ * cards, DnD chips rendered into a body portal).
16158
+ */
16159
+ export declare const ExerciseLockProvider: default_2.FC<ExerciseLockProviderProps>;
16160
+
16161
+ export declare interface ExerciseLockProviderProps {
16162
+ locked: boolean;
16163
+ children: default_2.ReactNode;
16164
+ }
16165
+
15948
16166
  export declare type ExerciseMeta = z.infer<typeof ExerciseMetaSchema>;
15949
16167
 
15950
16168
  export declare const ExerciseMetaSchema: z.ZodObject<{
@@ -16156,7 +16374,117 @@ export declare function getFractionKey(widgetId: string, part: FractionPart): st
16156
16374
  * @param userInputs - User's answers
16157
16375
  * @returns Array of missing widget IDs
16158
16376
  */
16159
- export declare function getMissingInputs(exercise: ExerciseJSON, userInputs: Record<string, string | number | string[][] | number[]>): string[];
16377
+ export declare function getMissingInputs(exercise: ExerciseJSON, userInputs: Record<string, string | number | string[][] | number[] | GridCell[]>): string[];
16378
+
16379
+ export declare const GRID_SYMMETRY_AXES: readonly ["vertical", "horizontal"];
16380
+
16381
+ export declare const GRID_SYMMETRY_INTERACTIVE_AREAS: readonly ["left", "right", "top", "bottom"];
16382
+
16383
+ export declare const GRID_SYMMETRY_MAX_CELL_SIZE = 2;
16384
+
16385
+ export declare const GRID_SYMMETRY_MAX_COLS = 20;
16386
+
16387
+ export declare const GRID_SYMMETRY_MAX_ROWS = 20;
16388
+
16389
+ export declare const GRID_SYMMETRY_MIN_CELL_SIZE = 0.25;
16390
+
16391
+ /** One-based row/column coordinate shared by grid-based widgets. */
16392
+ export declare type GridCell = [row: number, col: number];
16393
+
16394
+ /** Structural validation shared by grid-based widgets. Grid bounds remain widget-specific. */
16395
+ export declare const GridCellSchema: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
16396
+
16397
+ export declare type GridSymmetryAxis = (typeof GRID_SYMMETRY_AXES)[number];
16398
+
16399
+ export declare type GridSymmetryBlock = z.infer<typeof GridSymmetryBlockSchema>;
16400
+
16401
+ export declare const GridSymmetryBlockSchema: z.ZodEffects<z.ZodObject<{
16402
+ type: z.ZodLiteral<"GridSymmetryBlock">;
16403
+ rows: z.ZodNumber;
16404
+ cols: z.ZodNumber;
16405
+ axis: z.ZodEnum<["vertical", "horizontal"]>;
16406
+ interactiveArea: z.ZodEnum<["left", "right", "top", "bottom"]>;
16407
+ cellSize: z.ZodDefault<z.ZodNumber>;
16408
+ cells: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, "many">;
16409
+ }, "strip", z.ZodTypeAny, {
16410
+ axis: "horizontal" | "vertical";
16411
+ type: "GridSymmetryBlock";
16412
+ rows: number;
16413
+ cols: number;
16414
+ interactiveArea: "left" | "right" | "top" | "bottom";
16415
+ cellSize: number;
16416
+ cells: [number, number][];
16417
+ }, {
16418
+ axis: "horizontal" | "vertical";
16419
+ type: "GridSymmetryBlock";
16420
+ rows: number;
16421
+ cols: number;
16422
+ interactiveArea: "left" | "right" | "top" | "bottom";
16423
+ cells: [number, number][];
16424
+ cellSize?: number | undefined;
16425
+ }>, {
16426
+ axis: "horizontal" | "vertical";
16427
+ type: "GridSymmetryBlock";
16428
+ rows: number;
16429
+ cols: number;
16430
+ interactiveArea: "left" | "right" | "top" | "bottom";
16431
+ cellSize: number;
16432
+ cells: [number, number][];
16433
+ }, {
16434
+ axis: "horizontal" | "vertical";
16435
+ type: "GridSymmetryBlock";
16436
+ rows: number;
16437
+ cols: number;
16438
+ interactiveArea: "left" | "right" | "top" | "bottom";
16439
+ cells: [number, number][];
16440
+ cellSize?: number | undefined;
16441
+ }>;
16442
+
16443
+ export declare type GridSymmetryInteractiveArea = (typeof GRID_SYMMETRY_INTERACTIVE_AREAS)[number];
16444
+
16445
+ export declare type GridSymmetryJSON = z.infer<typeof GridSymmetryJSONSchema>;
16446
+
16447
+ export declare const GridSymmetryJSONSchema: z.ZodEffects<z.ZodObject<{
16448
+ type: z.ZodLiteral<"grid-symmetry">;
16449
+ rows: z.ZodNumber;
16450
+ cols: z.ZodNumber;
16451
+ axis: z.ZodEnum<["vertical", "horizontal"]>;
16452
+ interactiveArea: z.ZodEnum<["left", "right", "top", "bottom"]>;
16453
+ cellSize: z.ZodDefault<z.ZodNumber>;
16454
+ cells: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, "many">;
16455
+ }, "strip", z.ZodTypeAny, {
16456
+ axis: "horizontal" | "vertical";
16457
+ type: "grid-symmetry";
16458
+ rows: number;
16459
+ cols: number;
16460
+ interactiveArea: "left" | "right" | "top" | "bottom";
16461
+ cellSize: number;
16462
+ cells: [number, number][];
16463
+ }, {
16464
+ axis: "horizontal" | "vertical";
16465
+ type: "grid-symmetry";
16466
+ rows: number;
16467
+ cols: number;
16468
+ interactiveArea: "left" | "right" | "top" | "bottom";
16469
+ cells: [number, number][];
16470
+ cellSize?: number | undefined;
16471
+ }>, {
16472
+ axis: "horizontal" | "vertical";
16473
+ type: "grid-symmetry";
16474
+ rows: number;
16475
+ cols: number;
16476
+ interactiveArea: "left" | "right" | "top" | "bottom";
16477
+ cellSize: number;
16478
+ cells: [number, number][];
16479
+ }, {
16480
+ axis: "horizontal" | "vertical";
16481
+ type: "grid-symmetry";
16482
+ rows: number;
16483
+ cols: number;
16484
+ interactiveArea: "left" | "right" | "top" | "bottom";
16485
+ cells: [number, number][];
16486
+ cellSize?: number | undefined;
16487
+ }>;
16160
16488
 
16161
16489
  export declare type GroupItem = z.infer<typeof GroupItemSchema>;
16162
16490
 
@@ -16165,20 +16493,15 @@ export declare const GroupItemSchema: z.ZodObject<{
16165
16493
  type: z.ZodLiteral<"group">;
16166
16494
  items: z.ZodArray<z.ZodType<any, z.ZodTypeDef, any>, "many">;
16167
16495
  }, "strip", z.ZodTypeAny, {
16168
- items: any[];
16169
16496
  type: "group";
16497
+ items: any[];
16170
16498
  id: string;
16171
16499
  }, {
16172
- items: any[];
16173
16500
  type: "group";
16501
+ items: any[];
16174
16502
  id: string;
16175
16503
  }>;
16176
16504
 
16177
- /**
16178
- * Validation Result Types
16179
- *
16180
- * These define the output of validation operations.
16181
- */
16182
16505
  /**
16183
16506
  * Validation result for a single matched group (works for any matcher-type widget:
16184
16507
  * Matcher groups of N items, PairMatcher pairs of 2 items, etc.)
@@ -16709,6 +17032,8 @@ export declare function isBoldText(item: LayoutItem): item is Extract<LayoutItem
16709
17032
  type: 'bold-text';
16710
17033
  }>;
16711
17034
 
17035
+ export declare function isCellInInteractiveArea(cell: GridCell, rows: number, cols: number, area: GridSymmetryInteractiveArea): boolean;
17036
+
16712
17037
  export declare function isClock(value: unknown): value is ClockInline;
16713
17038
 
16714
17039
  /**
@@ -16751,6 +17076,12 @@ export declare function isFractionKey(key: string): boolean;
16751
17076
 
16752
17077
  export declare function isFreeText(value: unknown): value is FreeTextInline;
16753
17078
 
17079
+ export declare function isGridSymmetryBlock(value: unknown): value is GridSymmetryBlock;
17080
+
17081
+ export declare function isGridSymmetryJSON(widget: WidgetJSON): widget is Extract<WidgetJSON, {
17082
+ type: 'grid-symmetry';
17083
+ }>;
17084
+
16754
17085
  /**
16755
17086
  * Type guard for GroupItem
16756
17087
  */
@@ -17031,6 +17362,8 @@ export declare const JSON_TYPES: {
17031
17362
  readonly FRACTION: "fraction";
17032
17363
  /** Visual fraction widget */
17033
17364
  readonly VISUAL_FRACTION: "visual-fraction";
17365
+ /** Interactive symmetry exercise on a grid */
17366
+ readonly GRID_SYMMETRY: "grid-symmetry";
17034
17367
  /** Ruler geometry tool widget */
17035
17368
  readonly RULER: "ruler";
17036
17369
  /** Protractor geometry tool widget */
@@ -17822,6 +18155,7 @@ export declare const MatcherBlockSchema: z.ZodEffects<z.ZodObject<{
17822
18155
  itemId: string;
17823
18156
  }>, "many">;
17824
18157
  }, "strip", z.ZodTypeAny, {
18158
+ type: "MatcherRow";
17825
18159
  items: {
17826
18160
  type: "MatcherItem";
17827
18161
  inlines: ({
@@ -17871,8 +18205,8 @@ export declare const MatcherBlockSchema: z.ZodEffects<z.ZodObject<{
17871
18205
  })[];
17872
18206
  itemId: string;
17873
18207
  }[];
17874
- type: "MatcherRow";
17875
18208
  }, {
18209
+ type: "MatcherRow";
17876
18210
  items: {
17877
18211
  type: "MatcherItem";
17878
18212
  inlines: ({
@@ -17922,13 +18256,13 @@ export declare const MatcherBlockSchema: z.ZodEffects<z.ZodObject<{
17922
18256
  })[];
17923
18257
  itemId: string;
17924
18258
  }[];
17925
- type: "MatcherRow";
17926
18259
  }>, "many">;
17927
18260
  answers: z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">;
17928
18261
  }, "strip", z.ZodTypeAny, {
17929
18262
  type: "MatcherBlock";
17930
18263
  name: string;
17931
18264
  rows: {
18265
+ type: "MatcherRow";
17932
18266
  items: {
17933
18267
  type: "MatcherItem";
17934
18268
  inlines: ({
@@ -17978,7 +18312,6 @@ export declare const MatcherBlockSchema: z.ZodEffects<z.ZodObject<{
17978
18312
  })[];
17979
18313
  itemId: string;
17980
18314
  }[];
17981
- type: "MatcherRow";
17982
18315
  }[];
17983
18316
  answers: string[][];
17984
18317
  colors?: string[] | undefined;
@@ -17986,6 +18319,7 @@ export declare const MatcherBlockSchema: z.ZodEffects<z.ZodObject<{
17986
18319
  type: "MatcherBlock";
17987
18320
  name: string;
17988
18321
  rows: {
18322
+ type: "MatcherRow";
17989
18323
  items: {
17990
18324
  type: "MatcherItem";
17991
18325
  inlines: ({
@@ -18035,7 +18369,6 @@ export declare const MatcherBlockSchema: z.ZodEffects<z.ZodObject<{
18035
18369
  })[];
18036
18370
  itemId: string;
18037
18371
  }[];
18038
- type: "MatcherRow";
18039
18372
  }[];
18040
18373
  answers: string[][];
18041
18374
  colors?: string[] | undefined;
@@ -18043,6 +18376,7 @@ export declare const MatcherBlockSchema: z.ZodEffects<z.ZodObject<{
18043
18376
  type: "MatcherBlock";
18044
18377
  name: string;
18045
18378
  rows: {
18379
+ type: "MatcherRow";
18046
18380
  items: {
18047
18381
  type: "MatcherItem";
18048
18382
  inlines: ({
@@ -18092,7 +18426,6 @@ export declare const MatcherBlockSchema: z.ZodEffects<z.ZodObject<{
18092
18426
  })[];
18093
18427
  itemId: string;
18094
18428
  }[];
18095
- type: "MatcherRow";
18096
18429
  }[];
18097
18430
  answers: string[][];
18098
18431
  colors?: string[] | undefined;
@@ -18100,6 +18433,7 @@ export declare const MatcherBlockSchema: z.ZodEffects<z.ZodObject<{
18100
18433
  type: "MatcherBlock";
18101
18434
  name: string;
18102
18435
  rows: {
18436
+ type: "MatcherRow";
18103
18437
  items: {
18104
18438
  type: "MatcherItem";
18105
18439
  inlines: ({
@@ -18149,7 +18483,6 @@ export declare const MatcherBlockSchema: z.ZodEffects<z.ZodObject<{
18149
18483
  })[];
18150
18484
  itemId: string;
18151
18485
  }[];
18152
- type: "MatcherRow";
18153
18486
  }[];
18154
18487
  answers: string[][];
18155
18488
  colors?: string[] | undefined;
@@ -18494,22 +18827,22 @@ declare const MatcherRowItemSchema: z.ZodObject<{
18494
18827
  content: any[];
18495
18828
  }>, "many">;
18496
18829
  }, "strip", z.ZodTypeAny, {
18830
+ type: "matcher-row";
18497
18831
  items: {
18498
18832
  type: "matcher-item";
18499
18833
  itemId: string;
18500
18834
  id: string;
18501
18835
  content: any[];
18502
18836
  }[];
18503
- type: "matcher-row";
18504
18837
  id: string;
18505
18838
  }, {
18839
+ type: "matcher-row";
18506
18840
  items: {
18507
18841
  type: "matcher-item";
18508
18842
  itemId: string;
18509
18843
  id: string;
18510
18844
  content: any[];
18511
18845
  }[];
18512
- type: "matcher-row";
18513
18846
  id: string;
18514
18847
  }>;
18515
18848
 
@@ -18806,6 +19139,7 @@ export declare const MatcherRowSchema: z.ZodObject<{
18806
19139
  itemId: string;
18807
19140
  }>, "many">;
18808
19141
  }, "strip", z.ZodTypeAny, {
19142
+ type: "MatcherRow";
18809
19143
  items: {
18810
19144
  type: "MatcherItem";
18811
19145
  inlines: ({
@@ -18855,8 +19189,8 @@ export declare const MatcherRowSchema: z.ZodObject<{
18855
19189
  })[];
18856
19190
  itemId: string;
18857
19191
  }[];
18858
- type: "MatcherRow";
18859
19192
  }, {
19193
+ type: "MatcherRow";
18860
19194
  items: {
18861
19195
  type: "MatcherItem";
18862
19196
  inlines: ({
@@ -18906,7 +19240,6 @@ export declare const MatcherRowSchema: z.ZodObject<{
18906
19240
  })[];
18907
19241
  itemId: string;
18908
19242
  }[];
18909
- type: "MatcherRow";
18910
19243
  }>;
18911
19244
 
18912
19245
  export declare type MatcherWidgetJSON = z.infer<typeof MatcherWidgetJSONSchema>;
@@ -18940,22 +19273,22 @@ export declare const MatcherWidgetJSONSchema: z.ZodObject<{
18940
19273
  content: any[];
18941
19274
  }>, "many">;
18942
19275
  }, "strip", z.ZodTypeAny, {
19276
+ type: "matcher-row";
18943
19277
  items: {
18944
19278
  type: "matcher-item";
18945
19279
  itemId: string;
18946
19280
  id: string;
18947
19281
  content: any[];
18948
19282
  }[];
18949
- type: "matcher-row";
18950
19283
  id: string;
18951
19284
  }, {
19285
+ type: "matcher-row";
18952
19286
  items: {
18953
19287
  type: "matcher-item";
18954
19288
  itemId: string;
18955
19289
  id: string;
18956
19290
  content: any[];
18957
19291
  }[];
18958
- type: "matcher-row";
18959
19292
  id: string;
18960
19293
  }>, "many">;
18961
19294
  /** Optional color palette for the renderer (one color per answer group) */
@@ -18965,13 +19298,13 @@ export declare const MatcherWidgetJSONSchema: z.ZodObject<{
18965
19298
  }, "strip", z.ZodTypeAny, {
18966
19299
  type: "matcher";
18967
19300
  rows: {
19301
+ type: "matcher-row";
18968
19302
  items: {
18969
19303
  type: "matcher-item";
18970
19304
  itemId: string;
18971
19305
  id: string;
18972
19306
  content: any[];
18973
19307
  }[];
18974
- type: "matcher-row";
18975
19308
  id: string;
18976
19309
  }[];
18977
19310
  groupCount: number;
@@ -18979,13 +19312,13 @@ export declare const MatcherWidgetJSONSchema: z.ZodObject<{
18979
19312
  }, {
18980
19313
  type: "matcher";
18981
19314
  rows: {
19315
+ type: "matcher-row";
18982
19316
  items: {
18983
19317
  type: "matcher-item";
18984
19318
  itemId: string;
18985
19319
  id: string;
18986
19320
  content: any[];
18987
19321
  }[];
18988
- type: "matcher-row";
18989
19322
  id: string;
18990
19323
  }[];
18991
19324
  groupCount: number;
@@ -24066,13 +24399,13 @@ declare const RadioOptionsBlockSchema: z.ZodObject<{
24066
24399
  options: z.ZodArray<z.ZodString, "many">;
24067
24400
  answer: z.ZodString;
24068
24401
  }, "strip", z.ZodTypeAny, {
24069
- type: "RadioOptions";
24070
24402
  options: string[];
24403
+ type: "RadioOptions";
24071
24404
  name: string;
24072
24405
  answer: string;
24073
24406
  }, {
24074
- type: "RadioOptions";
24075
24407
  options: string[];
24408
+ type: "RadioOptions";
24076
24409
  name: string;
24077
24410
  answer: string;
24078
24411
  }>;
@@ -24083,13 +24416,15 @@ export declare const RadioOptionsJSONSchema: z.ZodObject<{
24083
24416
  type: z.ZodLiteral<"radio-options">;
24084
24417
  options: z.ZodArray<z.ZodString, "many">;
24085
24418
  }, "strip", z.ZodTypeAny, {
24086
- type: "radio-options";
24087
24419
  options: string[];
24088
- }, {
24089
24420
  type: "radio-options";
24421
+ }, {
24090
24422
  options: string[];
24423
+ type: "radio-options";
24091
24424
  }>;
24092
24425
 
24426
+ export declare function reflectGridSymmetryCell(cell: GridCell, rows: number, cols: number, axis: GridSymmetryAxis): GridCell;
24427
+
24093
24428
  /**
24094
24429
  * DOM helper for quick usage / demos.
24095
24430
  *
@@ -24876,7 +25211,6 @@ declare const TableBlockSchema: z.ZodObject<{
24876
25211
  }>, "many">;
24877
25212
  }, "strip", z.ZodTypeAny, {
24878
25213
  type: "TableBlock";
24879
- cols: number;
24880
25214
  rows: {
24881
25215
  type: "TableRow";
24882
25216
  cells: {
@@ -24965,9 +25299,9 @@ declare const TableBlockSchema: z.ZodObject<{
24965
25299
  }[];
24966
25300
  backgroundColor?: string | undefined;
24967
25301
  }[];
25302
+ cols: number;
24968
25303
  }, {
24969
25304
  type: "TableBlock";
24970
- cols: number;
24971
25305
  rows: {
24972
25306
  type: "TableRow";
24973
25307
  cells: {
@@ -25056,6 +25390,7 @@ declare const TableBlockSchema: z.ZodObject<{
25056
25390
  }[];
25057
25391
  backgroundColor?: string | undefined;
25058
25392
  }[];
25393
+ cols: number;
25059
25394
  }>;
25060
25395
 
25061
25396
  export declare type TableCell = z.infer<typeof TableCellSchema>;
@@ -25070,15 +25405,15 @@ export declare const TableCellItemSchema: z.ZodObject<{
25070
25405
  backgroundColor: z.ZodOptional<z.ZodString>;
25071
25406
  items: z.ZodArray<z.ZodType<any, z.ZodTypeDef, any>, "many">;
25072
25407
  }, "strip", z.ZodTypeAny, {
25073
- items: any[];
25074
25408
  type: "table-cell";
25409
+ items: any[];
25075
25410
  id: string;
25076
25411
  colspan?: number | undefined;
25077
25412
  rowspan?: number | undefined;
25078
25413
  backgroundColor?: string | undefined;
25079
25414
  }, {
25080
- items: any[];
25081
25415
  type: "table-cell";
25416
+ items: any[];
25082
25417
  id: string;
25083
25418
  colspan?: number | undefined;
25084
25419
  rowspan?: number | undefined;
@@ -25528,15 +25863,15 @@ export declare const TableItemSchema: z.ZodObject<{
25528
25863
  backgroundColor: z.ZodOptional<z.ZodString>;
25529
25864
  items: z.ZodArray<z.ZodType<any, z.ZodTypeDef, any>, "many">;
25530
25865
  }, "strip", z.ZodTypeAny, {
25531
- items: any[];
25532
25866
  type: "table-cell";
25867
+ items: any[];
25533
25868
  id: string;
25534
25869
  colspan?: number | undefined;
25535
25870
  rowspan?: number | undefined;
25536
25871
  backgroundColor?: string | undefined;
25537
25872
  }, {
25538
- items: any[];
25539
25873
  type: "table-cell";
25874
+ items: any[];
25540
25875
  id: string;
25541
25876
  colspan?: number | undefined;
25542
25877
  rowspan?: number | undefined;
@@ -25545,8 +25880,8 @@ export declare const TableItemSchema: z.ZodObject<{
25545
25880
  }, "strip", z.ZodTypeAny, {
25546
25881
  type: "table-row";
25547
25882
  cells: {
25548
- items: any[];
25549
25883
  type: "table-cell";
25884
+ items: any[];
25550
25885
  id: string;
25551
25886
  colspan?: number | undefined;
25552
25887
  rowspan?: number | undefined;
@@ -25557,8 +25892,8 @@ export declare const TableItemSchema: z.ZodObject<{
25557
25892
  }, {
25558
25893
  type: "table-row";
25559
25894
  cells: {
25560
- items: any[];
25561
25895
  type: "table-cell";
25896
+ items: any[];
25562
25897
  id: string;
25563
25898
  colspan?: number | undefined;
25564
25899
  rowspan?: number | undefined;
@@ -25569,12 +25904,11 @@ export declare const TableItemSchema: z.ZodObject<{
25569
25904
  }>, "many">;
25570
25905
  }, "strip", z.ZodTypeAny, {
25571
25906
  type: "table";
25572
- cols: number;
25573
25907
  rows: {
25574
25908
  type: "table-row";
25575
25909
  cells: {
25576
- items: any[];
25577
25910
  type: "table-cell";
25911
+ items: any[];
25578
25912
  id: string;
25579
25913
  colspan?: number | undefined;
25580
25914
  rowspan?: number | undefined;
@@ -25583,15 +25917,15 @@ export declare const TableItemSchema: z.ZodObject<{
25583
25917
  id: string;
25584
25918
  backgroundColor?: string | undefined;
25585
25919
  }[];
25920
+ cols: number;
25586
25921
  id: string;
25587
25922
  }, {
25588
25923
  type: "table";
25589
- cols: number;
25590
25924
  rows: {
25591
25925
  type: "table-row";
25592
25926
  cells: {
25593
- items: any[];
25594
25927
  type: "table-cell";
25928
+ items: any[];
25595
25929
  id: string;
25596
25930
  colspan?: number | undefined;
25597
25931
  rowspan?: number | undefined;
@@ -25600,6 +25934,7 @@ export declare const TableItemSchema: z.ZodObject<{
25600
25934
  id: string;
25601
25935
  backgroundColor?: string | undefined;
25602
25936
  }[];
25937
+ cols: number;
25603
25938
  id: string;
25604
25939
  }>;
25605
25940
 
@@ -25619,15 +25954,15 @@ export declare const TableRowItemSchema: z.ZodObject<{
25619
25954
  backgroundColor: z.ZodOptional<z.ZodString>;
25620
25955
  items: z.ZodArray<z.ZodType<any, z.ZodTypeDef, any>, "many">;
25621
25956
  }, "strip", z.ZodTypeAny, {
25622
- items: any[];
25623
25957
  type: "table-cell";
25958
+ items: any[];
25624
25959
  id: string;
25625
25960
  colspan?: number | undefined;
25626
25961
  rowspan?: number | undefined;
25627
25962
  backgroundColor?: string | undefined;
25628
25963
  }, {
25629
- items: any[];
25630
25964
  type: "table-cell";
25965
+ items: any[];
25631
25966
  id: string;
25632
25967
  colspan?: number | undefined;
25633
25968
  rowspan?: number | undefined;
@@ -25636,8 +25971,8 @@ export declare const TableRowItemSchema: z.ZodObject<{
25636
25971
  }, "strip", z.ZodTypeAny, {
25637
25972
  type: "table-row";
25638
25973
  cells: {
25639
- items: any[];
25640
25974
  type: "table-cell";
25975
+ items: any[];
25641
25976
  id: string;
25642
25977
  colspan?: number | undefined;
25643
25978
  rowspan?: number | undefined;
@@ -25648,8 +25983,8 @@ export declare const TableRowItemSchema: z.ZodObject<{
25648
25983
  }, {
25649
25984
  type: "table-row";
25650
25985
  cells: {
25651
- items: any[];
25652
25986
  type: "table-cell";
25987
+ items: any[];
25653
25988
  id: string;
25654
25989
  colspan?: number | undefined;
25655
25990
  rowspan?: number | undefined;
@@ -26349,11 +26684,11 @@ export declare const ToolNodeSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObjec
26349
26684
  type: z.ZodLiteral<"DragOptions">;
26350
26685
  options: z.ZodArray<z.ZodString, "many">;
26351
26686
  }, "strip", z.ZodTypeAny, {
26352
- type: "DragOptions";
26353
26687
  options: string[];
26354
- }, {
26355
26688
  type: "DragOptions";
26689
+ }, {
26356
26690
  options: string[];
26691
+ type: "DragOptions";
26357
26692
  }>, z.ZodObject<{
26358
26693
  type: z.ZodLiteral<"NumericKeypad">;
26359
26694
  includeOperators: z.ZodOptional<z.ZodBoolean>;
@@ -26406,18 +26741,14 @@ export declare class TransformError extends EngineError {
26406
26741
  constructor(message: string, position?: SourcePosition);
26407
26742
  }
26408
26743
 
26409
- /**
26410
- * Shared value types for the renderer layer.
26411
- *
26412
- * `UserAnswerValue` is the runtime type of any answer collected by the renderer:
26413
- * - `string` — all scalar widgets (inline-input, radio-options, drag-options, number-line inputs…)
26414
- * - `string[][]` — matcher widget (groups of item IDs, no JSON serialisation needed)
26415
- * - `number[]` — visual-fraction widget (counts per shaded group)
26416
- *
26417
- * This union matches the type accepted by `validate()` and avoids any
26418
- * JSON.stringify / JSON.parse round-trips for structured widget values.
26419
- */
26420
- declare type UserAnswerValue = string | string[][] | number[];
26744
+ /** true once the exercise was checked/revealed — widgets must refuse input until reset(). */
26745
+ export declare const useExerciseLocked: () => boolean;
26746
+
26747
+ /** User answers keyed by widget ID. */
26748
+ export declare type UserAnswers = Record<string, UserAnswerValue>;
26749
+
26750
+ /** Runtime value produced by any answer-bearing widget. */
26751
+ export declare type UserAnswerValue = string | number | string[][] | number[] | [number, number][];
26421
26752
 
26422
26753
  /**
26423
26754
  * Returns `play(event)`. Safe to call outside a SoundProvider — it returns a
@@ -26445,7 +26776,7 @@ export declare function useSound(): (event: SoundEvent) => void;
26445
26776
  * }
26446
26777
  * ```
26447
26778
  */
26448
- export declare function validate(exercise: ExerciseJSON, userInputs: Record<string, string | number | string[][] | number[]>): ValidationResult;
26779
+ export declare function validate(exercise: ExerciseJSON, userInputs: Record<string, string | number | string[][] | number[] | GridCell[]>): ValidationResult;
26449
26780
 
26450
26781
  /**
26451
26782
  * Validate that an expression will return a boolean
@@ -26490,14 +26821,14 @@ export declare function validateExerciseJSON(data: unknown): {
26490
26821
  digits: number;
26491
26822
  placeholder?: string | undefined;
26492
26823
  } | {
26493
- type: "drag-options";
26494
26824
  options: string[];
26825
+ type: "drag-options";
26495
26826
  } | {
26496
26827
  value: string;
26497
26828
  type: "inline-drag-option";
26498
26829
  } | {
26499
- type: "radio-options";
26500
26830
  options: string[];
26831
+ type: "radio-options";
26501
26832
  } | {
26502
26833
  type: "numeric-keypad";
26503
26834
  style?: "diamond" | "classic" | undefined;
@@ -26512,13 +26843,13 @@ export declare function validateExerciseJSON(data: unknown): {
26512
26843
  } | {
26513
26844
  type: "matcher";
26514
26845
  rows: {
26846
+ type: "matcher-row";
26515
26847
  items: {
26516
26848
  type: "matcher-item";
26517
26849
  itemId: string;
26518
26850
  id: string;
26519
26851
  content: any[];
26520
26852
  }[];
26521
- type: "matcher-row";
26522
26853
  id: string;
26523
26854
  }[];
26524
26855
  groupCount: number;
@@ -26546,6 +26877,14 @@ export declare function validateExerciseJSON(data: unknown): {
26546
26877
  orientation?: "horizontal" | "vertical" | undefined;
26547
26878
  label?: string | undefined;
26548
26879
  size?: number | undefined;
26880
+ } | {
26881
+ axis: "horizontal" | "vertical";
26882
+ type: "grid-symmetry";
26883
+ rows: number;
26884
+ cols: number;
26885
+ interactiveArea: "left" | "right" | "top" | "bottom";
26886
+ cellSize: number;
26887
+ cells: [number, number][];
26549
26888
  } | {
26550
26889
  type: "ruler";
26551
26890
  size?: number | undefined;
@@ -26559,7 +26898,7 @@ export declare function validateExerciseJSON(data: unknown): {
26559
26898
  validation?: {
26560
26899
  mode: "simple" | "expression" | "mixed";
26561
26900
  expression?: string | undefined;
26562
- answers?: Record<string, string | number | number[] | string[][]> | undefined;
26901
+ answers?: Record<string, string | number | number[] | string[][] | [number, number][]> | undefined;
26563
26902
  variables?: string[] | undefined;
26564
26903
  } | undefined;
26565
26904
  id?: string | undefined;
@@ -26601,14 +26940,14 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
26601
26940
  digits: number;
26602
26941
  placeholder?: string | undefined;
26603
26942
  } | {
26604
- type: "drag-options";
26605
26943
  options: string[];
26944
+ type: "drag-options";
26606
26945
  } | {
26607
26946
  value: string;
26608
26947
  type: "inline-drag-option";
26609
26948
  } | {
26610
- type: "radio-options";
26611
26949
  options: string[];
26950
+ type: "radio-options";
26612
26951
  } | {
26613
26952
  type: "numeric-keypad";
26614
26953
  style?: "diamond" | "classic" | undefined;
@@ -26623,13 +26962,13 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
26623
26962
  } | {
26624
26963
  type: "matcher";
26625
26964
  rows: {
26965
+ type: "matcher-row";
26626
26966
  items: {
26627
26967
  type: "matcher-item";
26628
26968
  itemId: string;
26629
26969
  id: string;
26630
26970
  content: any[];
26631
26971
  }[];
26632
- type: "matcher-row";
26633
26972
  id: string;
26634
26973
  }[];
26635
26974
  groupCount: number;
@@ -26657,6 +26996,14 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
26657
26996
  orientation?: "horizontal" | "vertical" | undefined;
26658
26997
  label?: string | undefined;
26659
26998
  size?: number | undefined;
26999
+ } | {
27000
+ axis: "horizontal" | "vertical";
27001
+ type: "grid-symmetry";
27002
+ rows: number;
27003
+ cols: number;
27004
+ interactiveArea: "left" | "right" | "top" | "bottom";
27005
+ cells: [number, number][];
27006
+ cellSize?: number | undefined;
26660
27007
  } | {
26661
27008
  type: "ruler";
26662
27009
  size?: number | undefined;
@@ -26670,7 +27017,7 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
26670
27017
  validation?: {
26671
27018
  mode: "simple" | "expression" | "mixed";
26672
27019
  expression?: string | undefined;
26673
- answers?: Record<string, string | number | number[] | string[][]> | undefined;
27020
+ answers?: Record<string, string | number | number[] | string[][] | [number, number][]> | undefined;
26674
27021
  variables?: string[] | undefined;
26675
27022
  } | undefined;
26676
27023
  id?: string | undefined;
@@ -26694,14 +27041,14 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
26694
27041
  digits: number;
26695
27042
  placeholder?: string | undefined;
26696
27043
  } | {
26697
- type: "drag-options";
26698
27044
  options: string[];
27045
+ type: "drag-options";
26699
27046
  } | {
26700
27047
  value: string;
26701
27048
  type: "inline-drag-option";
26702
27049
  } | {
26703
- type: "radio-options";
26704
27050
  options: string[];
27051
+ type: "radio-options";
26705
27052
  } | {
26706
27053
  type: "numeric-keypad";
26707
27054
  style?: "diamond" | "classic" | undefined;
@@ -26716,13 +27063,13 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
26716
27063
  } | {
26717
27064
  type: "matcher";
26718
27065
  rows: {
27066
+ type: "matcher-row";
26719
27067
  items: {
26720
27068
  type: "matcher-item";
26721
27069
  itemId: string;
26722
27070
  id: string;
26723
27071
  content: any[];
26724
27072
  }[];
26725
- type: "matcher-row";
26726
27073
  id: string;
26727
27074
  }[];
26728
27075
  groupCount: number;
@@ -26750,6 +27097,14 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
26750
27097
  orientation?: "horizontal" | "vertical" | undefined;
26751
27098
  label?: string | undefined;
26752
27099
  size?: number | undefined;
27100
+ } | {
27101
+ axis: "horizontal" | "vertical";
27102
+ type: "grid-symmetry";
27103
+ rows: number;
27104
+ cols: number;
27105
+ interactiveArea: "left" | "right" | "top" | "bottom";
27106
+ cellSize: number;
27107
+ cells: [number, number][];
26753
27108
  } | {
26754
27109
  type: "ruler";
26755
27110
  size?: number | undefined;
@@ -26763,7 +27118,7 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
26763
27118
  validation?: {
26764
27119
  mode: "simple" | "expression" | "mixed";
26765
27120
  expression?: string | undefined;
26766
- answers?: Record<string, string | number | number[] | string[][]> | undefined;
27121
+ answers?: Record<string, string | number | number[] | string[][] | [number, number][]> | undefined;
26767
27122
  variables?: string[] | undefined;
26768
27123
  } | undefined;
26769
27124
  id?: string | undefined;
@@ -26801,7 +27156,7 @@ export declare function validateInputFormats(exercise: ExerciseJSON, userInputs:
26801
27156
  * @param userInputs - User's answers keyed by widget ID
26802
27157
  * @returns Validation result
26803
27158
  */
26804
- export declare function validateMixed(exercise: ValidatedExerciseJSON, userInputs: Record<string, string | number | string[][] | number[]>): ValidationResult;
27159
+ export declare function validateMixed(exercise: ValidatedExerciseJSON, userInputs: Record<string, string | number | string[][] | number[] | GridCell[]>): ValidationResult;
26805
27160
 
26806
27161
  /**
26807
27162
  * Validate using simple mode (predetermined answers)
@@ -26810,7 +27165,7 @@ export declare function validateMixed(exercise: ValidatedExerciseJSON, userInput
26810
27165
  * @param userInputs - User's answers keyed by widget ID
26811
27166
  * @returns Validation result
26812
27167
  */
26813
- export declare function validateSimple(exercise: ValidatedExerciseJSON, userInputs: Record<string, string | number | string[][] | number[]>): ValidationResult;
27168
+ export declare function validateSimple(exercise: ValidatedExerciseJSON, userInputs: Record<string, string | number | string[][] | number[] | GridCell[]>): ValidationResult;
26814
27169
 
26815
27170
  export declare function validateVisualFractionCapacity(data: {
26816
27171
  divisions: number;
@@ -26837,14 +27192,14 @@ export declare function validateWidgetJSON(data: unknown): {
26837
27192
  digits: number;
26838
27193
  placeholder?: string | undefined;
26839
27194
  } | {
26840
- type: "drag-options";
26841
27195
  options: string[];
27196
+ type: "drag-options";
26842
27197
  } | {
26843
27198
  value: string;
26844
27199
  type: "inline-drag-option";
26845
27200
  } | {
26846
- type: "radio-options";
26847
27201
  options: string[];
27202
+ type: "radio-options";
26848
27203
  } | {
26849
27204
  type: "numeric-keypad";
26850
27205
  style?: "diamond" | "classic" | undefined;
@@ -26859,13 +27214,13 @@ export declare function validateWidgetJSON(data: unknown): {
26859
27214
  } | {
26860
27215
  type: "matcher";
26861
27216
  rows: {
27217
+ type: "matcher-row";
26862
27218
  items: {
26863
27219
  type: "matcher-item";
26864
27220
  itemId: string;
26865
27221
  id: string;
26866
27222
  content: any[];
26867
27223
  }[];
26868
- type: "matcher-row";
26869
27224
  id: string;
26870
27225
  }[];
26871
27226
  groupCount: number;
@@ -26893,6 +27248,14 @@ export declare function validateWidgetJSON(data: unknown): {
26893
27248
  orientation?: "horizontal" | "vertical" | undefined;
26894
27249
  label?: string | undefined;
26895
27250
  size?: number | undefined;
27251
+ } | {
27252
+ axis: "horizontal" | "vertical";
27253
+ type: "grid-symmetry";
27254
+ rows: number;
27255
+ cols: number;
27256
+ interactiveArea: "left" | "right" | "top" | "bottom";
27257
+ cellSize: number;
27258
+ cells: [number, number][];
26896
27259
  } | {
26897
27260
  type: "ruler";
26898
27261
  size?: number | undefined;
@@ -26921,14 +27284,14 @@ export declare function validateWidgetJSONSafe(data: unknown): z.SafeParseReturn
26921
27284
  digits: number;
26922
27285
  placeholder?: string | undefined;
26923
27286
  } | {
26924
- type: "drag-options";
26925
27287
  options: string[];
27288
+ type: "drag-options";
26926
27289
  } | {
26927
27290
  value: string;
26928
27291
  type: "inline-drag-option";
26929
27292
  } | {
26930
- type: "radio-options";
26931
27293
  options: string[];
27294
+ type: "radio-options";
26932
27295
  } | {
26933
27296
  type: "numeric-keypad";
26934
27297
  style?: "diamond" | "classic" | undefined;
@@ -26943,13 +27306,13 @@ export declare function validateWidgetJSONSafe(data: unknown): z.SafeParseReturn
26943
27306
  } | {
26944
27307
  type: "matcher";
26945
27308
  rows: {
27309
+ type: "matcher-row";
26946
27310
  items: {
26947
27311
  type: "matcher-item";
26948
27312
  itemId: string;
26949
27313
  id: string;
26950
27314
  content: any[];
26951
27315
  }[];
26952
- type: "matcher-row";
26953
27316
  id: string;
26954
27317
  }[];
26955
27318
  groupCount: number;
@@ -26977,6 +27340,14 @@ export declare function validateWidgetJSONSafe(data: unknown): z.SafeParseReturn
26977
27340
  orientation?: "horizontal" | "vertical" | undefined;
26978
27341
  label?: string | undefined;
26979
27342
  size?: number | undefined;
27343
+ } | {
27344
+ axis: "horizontal" | "vertical";
27345
+ type: "grid-symmetry";
27346
+ rows: number;
27347
+ cols: number;
27348
+ interactiveArea: "left" | "right" | "top" | "bottom";
27349
+ cells: [number, number][];
27350
+ cellSize?: number | undefined;
26980
27351
  } | {
26981
27352
  type: "ruler";
26982
27353
  size?: number | undefined;
@@ -26997,14 +27368,14 @@ export declare function validateWidgetJSONSafe(data: unknown): z.SafeParseReturn
26997
27368
  digits: number;
26998
27369
  placeholder?: string | undefined;
26999
27370
  } | {
27000
- type: "drag-options";
27001
27371
  options: string[];
27372
+ type: "drag-options";
27002
27373
  } | {
27003
27374
  value: string;
27004
27375
  type: "inline-drag-option";
27005
27376
  } | {
27006
- type: "radio-options";
27007
27377
  options: string[];
27378
+ type: "radio-options";
27008
27379
  } | {
27009
27380
  type: "numeric-keypad";
27010
27381
  style?: "diamond" | "classic" | undefined;
@@ -27019,13 +27390,13 @@ export declare function validateWidgetJSONSafe(data: unknown): z.SafeParseReturn
27019
27390
  } | {
27020
27391
  type: "matcher";
27021
27392
  rows: {
27393
+ type: "matcher-row";
27022
27394
  items: {
27023
27395
  type: "matcher-item";
27024
27396
  itemId: string;
27025
27397
  id: string;
27026
27398
  content: any[];
27027
27399
  }[];
27028
- type: "matcher-row";
27029
27400
  id: string;
27030
27401
  }[];
27031
27402
  groupCount: number;
@@ -27053,6 +27424,14 @@ export declare function validateWidgetJSONSafe(data: unknown): z.SafeParseReturn
27053
27424
  orientation?: "horizontal" | "vertical" | undefined;
27054
27425
  label?: string | undefined;
27055
27426
  size?: number | undefined;
27427
+ } | {
27428
+ axis: "horizontal" | "vertical";
27429
+ type: "grid-symmetry";
27430
+ rows: number;
27431
+ cols: number;
27432
+ interactiveArea: "left" | "right" | "top" | "bottom";
27433
+ cellSize: number;
27434
+ cells: [number, number][];
27056
27435
  } | {
27057
27436
  type: "ruler";
27058
27437
  size?: number | undefined;
@@ -27076,18 +27455,18 @@ export declare type ValidationJSON = z.infer<typeof ValidationJSONSchema>;
27076
27455
 
27077
27456
  export declare const ValidationJSONSchema: z.ZodObject<{
27078
27457
  mode: z.ZodEnum<["simple", "expression", "mixed"]>;
27079
- answers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">, z.ZodArray<z.ZodNumber, "many">]>>>;
27458
+ answers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">, z.ZodArray<z.ZodNumber, "many">, z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, "many">]>>>;
27080
27459
  expression: z.ZodOptional<z.ZodString>;
27081
27460
  variables: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
27082
27461
  }, "strip", z.ZodTypeAny, {
27083
27462
  mode: "simple" | "expression" | "mixed";
27084
27463
  expression?: string | undefined;
27085
- answers?: Record<string, string | number | number[] | string[][]> | undefined;
27464
+ answers?: Record<string, string | number | number[] | string[][] | [number, number][]> | undefined;
27086
27465
  variables?: string[] | undefined;
27087
27466
  }, {
27088
27467
  mode: "simple" | "expression" | "mixed";
27089
27468
  expression?: string | undefined;
27090
- answers?: Record<string, string | number | number[] | string[][]> | undefined;
27469
+ answers?: Record<string, string | number | number[] | string[][] | [number, number][]> | undefined;
27091
27470
  variables?: string[] | undefined;
27092
27471
  }>;
27093
27472
 
@@ -27476,6 +27855,7 @@ export declare const VerticalOperationBlockSchema: z.ZodObject<{
27476
27855
  type: "VopSeparator";
27477
27856
  }>]>, "many">;
27478
27857
  }, "strip", z.ZodTypeAny, {
27858
+ type: "VerticalOperationBlock";
27479
27859
  items: ({
27480
27860
  type: "VopRow";
27481
27861
  cells: ({
@@ -27546,9 +27926,9 @@ export declare const VerticalOperationBlockSchema: z.ZodObject<{
27546
27926
  } | {
27547
27927
  type: "VopSeparator";
27548
27928
  })[];
27549
- type: "VerticalOperationBlock";
27550
27929
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
27551
27930
  }, {
27931
+ type: "VerticalOperationBlock";
27552
27932
  items: ({
27553
27933
  type: "VopRow";
27554
27934
  cells: ({
@@ -27619,7 +27999,6 @@ export declare const VerticalOperationBlockSchema: z.ZodObject<{
27619
27999
  } | {
27620
28000
  type: "VopSeparator";
27621
28001
  })[];
27622
- type: "VerticalOperationBlock";
27623
28002
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
27624
28003
  }>;
27625
28004
 
@@ -28018,6 +28397,7 @@ export declare const VerticalOperationItemSchema: z.ZodObject<{
28018
28397
  id: string;
28019
28398
  }>]>, "many">;
28020
28399
  }, "strip", z.ZodTypeAny, {
28400
+ type: "vertical-operation";
28021
28401
  items: ({
28022
28402
  type: "vop-row";
28023
28403
  cells: ({
@@ -28101,11 +28481,11 @@ export declare const VerticalOperationItemSchema: z.ZodObject<{
28101
28481
  type: "vop-separator";
28102
28482
  id: string;
28103
28483
  })[];
28104
- type: "vertical-operation";
28105
28484
  cols: number;
28106
28485
  id: string;
28107
28486
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
28108
28487
  }, {
28488
+ type: "vertical-operation";
28109
28489
  items: ({
28110
28490
  type: "vop-row";
28111
28491
  cells: ({
@@ -28189,7 +28569,6 @@ export declare const VerticalOperationItemSchema: z.ZodObject<{
28189
28569
  type: "vop-separator";
28190
28570
  id: string;
28191
28571
  })[];
28192
- type: "vertical-operation";
28193
28572
  cols: number;
28194
28573
  id: string;
28195
28574
  op?: "+" | "-" | "×" | "÷" | "=" | undefined;
@@ -29843,11 +30222,11 @@ export declare const WidgetJSONSchema: z.ZodUnion<[z.ZodDiscriminatedUnion<"inpu
29843
30222
  type: z.ZodLiteral<"drag-options">;
29844
30223
  options: z.ZodArray<z.ZodString, "many">;
29845
30224
  }, "strip", z.ZodTypeAny, {
29846
- type: "drag-options";
29847
30225
  options: string[];
29848
- }, {
29849
30226
  type: "drag-options";
30227
+ }, {
29850
30228
  options: string[];
30229
+ type: "drag-options";
29851
30230
  }>, z.ZodObject<{
29852
30231
  type: z.ZodLiteral<"inline-drag-option">;
29853
30232
  value: z.ZodString;
@@ -29861,11 +30240,11 @@ export declare const WidgetJSONSchema: z.ZodUnion<[z.ZodDiscriminatedUnion<"inpu
29861
30240
  type: z.ZodLiteral<"radio-options">;
29862
30241
  options: z.ZodArray<z.ZodString, "many">;
29863
30242
  }, "strip", z.ZodTypeAny, {
29864
- type: "radio-options";
29865
30243
  options: string[];
29866
- }, {
29867
30244
  type: "radio-options";
30245
+ }, {
29868
30246
  options: string[];
30247
+ type: "radio-options";
29869
30248
  }>, z.ZodObject<{
29870
30249
  type: z.ZodLiteral<"numeric-keypad">;
29871
30250
  includeOperators: z.ZodOptional<z.ZodBoolean>;
@@ -29923,22 +30302,22 @@ export declare const WidgetJSONSchema: z.ZodUnion<[z.ZodDiscriminatedUnion<"inpu
29923
30302
  content: any[];
29924
30303
  }>, "many">;
29925
30304
  }, "strip", z.ZodTypeAny, {
30305
+ type: "matcher-row";
29926
30306
  items: {
29927
30307
  type: "matcher-item";
29928
30308
  itemId: string;
29929
30309
  id: string;
29930
30310
  content: any[];
29931
30311
  }[];
29932
- type: "matcher-row";
29933
30312
  id: string;
29934
30313
  }, {
30314
+ type: "matcher-row";
29935
30315
  items: {
29936
30316
  type: "matcher-item";
29937
30317
  itemId: string;
29938
30318
  id: string;
29939
30319
  content: any[];
29940
30320
  }[];
29941
- type: "matcher-row";
29942
30321
  id: string;
29943
30322
  }>, "many">;
29944
30323
  /** Optional color palette for the renderer (one color per answer group) */
@@ -29948,13 +30327,13 @@ export declare const WidgetJSONSchema: z.ZodUnion<[z.ZodDiscriminatedUnion<"inpu
29948
30327
  }, "strip", z.ZodTypeAny, {
29949
30328
  type: "matcher";
29950
30329
  rows: {
30330
+ type: "matcher-row";
29951
30331
  items: {
29952
30332
  type: "matcher-item";
29953
30333
  itemId: string;
29954
30334
  id: string;
29955
30335
  content: any[];
29956
30336
  }[];
29957
- type: "matcher-row";
29958
30337
  id: string;
29959
30338
  }[];
29960
30339
  groupCount: number;
@@ -29962,13 +30341,13 @@ export declare const WidgetJSONSchema: z.ZodUnion<[z.ZodDiscriminatedUnion<"inpu
29962
30341
  }, {
29963
30342
  type: "matcher";
29964
30343
  rows: {
30344
+ type: "matcher-row";
29965
30345
  items: {
29966
30346
  type: "matcher-item";
29967
30347
  itemId: string;
29968
30348
  id: string;
29969
30349
  content: any[];
29970
30350
  }[];
29971
- type: "matcher-row";
29972
30351
  id: string;
29973
30352
  }[];
29974
30353
  groupCount: number;
@@ -30089,6 +30468,46 @@ export declare const WidgetJSONSchema: z.ZodUnion<[z.ZodDiscriminatedUnion<"inpu
30089
30468
  orientation?: "horizontal" | "vertical" | undefined;
30090
30469
  label?: string | undefined;
30091
30470
  size?: number | undefined;
30471
+ }>, z.ZodEffects<z.ZodObject<{
30472
+ type: z.ZodLiteral<"grid-symmetry">;
30473
+ rows: z.ZodNumber;
30474
+ cols: z.ZodNumber;
30475
+ axis: z.ZodEnum<["vertical", "horizontal"]>;
30476
+ interactiveArea: z.ZodEnum<["left", "right", "top", "bottom"]>;
30477
+ cellSize: z.ZodDefault<z.ZodNumber>;
30478
+ cells: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, "many">;
30479
+ }, "strip", z.ZodTypeAny, {
30480
+ axis: "horizontal" | "vertical";
30481
+ type: "grid-symmetry";
30482
+ rows: number;
30483
+ cols: number;
30484
+ interactiveArea: "left" | "right" | "top" | "bottom";
30485
+ cellSize: number;
30486
+ cells: [number, number][];
30487
+ }, {
30488
+ axis: "horizontal" | "vertical";
30489
+ type: "grid-symmetry";
30490
+ rows: number;
30491
+ cols: number;
30492
+ interactiveArea: "left" | "right" | "top" | "bottom";
30493
+ cells: [number, number][];
30494
+ cellSize?: number | undefined;
30495
+ }>, {
30496
+ axis: "horizontal" | "vertical";
30497
+ type: "grid-symmetry";
30498
+ rows: number;
30499
+ cols: number;
30500
+ interactiveArea: "left" | "right" | "top" | "bottom";
30501
+ cellSize: number;
30502
+ cells: [number, number][];
30503
+ }, {
30504
+ axis: "horizontal" | "vertical";
30505
+ type: "grid-symmetry";
30506
+ rows: number;
30507
+ cols: number;
30508
+ interactiveArea: "left" | "right" | "top" | "bottom";
30509
+ cells: [number, number][];
30510
+ cellSize?: number | undefined;
30092
30511
  }>, z.ZodObject<{
30093
30512
  type: z.ZodLiteral<"ruler">;
30094
30513
  size: z.ZodOptional<z.ZodNumber>;
@@ -30166,7 +30585,7 @@ export declare interface WidgetValidation {
30166
30585
  /** The widget ID */
30167
30586
  widgetId: string;
30168
30587
  /** The user's input value */
30169
- userValue: string | number | string[][] | number[] | undefined;
30588
+ userValue: UserAnswerValue | undefined;
30170
30589
  /** Whether the input is correct (aggregate verdict; for mixed mode this is simple AND expression) */
30171
30590
  isCorrect: boolean;
30172
30591
  /**