@mathscan/math-exercise-engine 1.2.9 → 1.2.10
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/README.md +24 -0
- package/dist/{GeometryWidget-D2QyGzW-.js → GeometryWidget-DgPfqyQv.js} +2 -2
- package/dist/{GeometryWidget-D2QyGzW-.js.map → GeometryWidget-DgPfqyQv.js.map} +1 -1
- package/dist/{GeometryWidget-BRV6LLcW.mjs → GeometryWidget-gtAP_-_S.mjs} +2 -2
- package/dist/{GeometryWidget-BRV6LLcW.mjs.map → GeometryWidget-gtAP_-_S.mjs.map} +1 -1
- package/dist/{index-XAInSHXa.mjs → index-DBteHZkS.mjs} +963 -301
- package/dist/index-DBteHZkS.mjs.map +1 -0
- package/dist/{index-D-QbiBn5.js → index-tEgJE6m2.js} +773 -111
- package/dist/index-tEgJE6m2.js.map +1 -0
- package/dist/index.d.ts +9518 -3368
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +205 -191
- package/dist/style.css +128 -0
- package/package.json +1 -1
- package/dist/index-D-QbiBn5.js.map +0 -1
- package/dist/index-XAInSHXa.mjs.map +0 -1
|
@@ -100,6 +100,12 @@ const AST_TYPES = {
|
|
|
100
100
|
CHART_BAR: "ChartBar",
|
|
101
101
|
/** A single pictograph item inside a CHART[type="pictograph"] block */
|
|
102
102
|
CHART_PICTO: "ChartPicto",
|
|
103
|
+
/** A named series (color + legend label) inside a CHART[type="grouped-bar"] block */
|
|
104
|
+
CHART_SERIES: "ChartSeries",
|
|
105
|
+
/** One category cluster inside a CHART[type="grouped-bar"] block */
|
|
106
|
+
CHART_GROUP: "ChartGroup",
|
|
107
|
+
/** A single bar inside a GROUP, referencing a declared SERIES by id */
|
|
108
|
+
CHART_SERIES_BAR: "ChartSeriesBar",
|
|
103
109
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
104
110
|
// Tools
|
|
105
111
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -203,6 +209,10 @@ const JSON_TYPES = {
|
|
|
203
209
|
CHART_BAR: "chart-bar",
|
|
204
210
|
/** A single pictograph item rendered inside a chart */
|
|
205
211
|
CHART_PICTO: "chart-picto",
|
|
212
|
+
/** A single bar rendered inside a grouped-bar chart's GROUP — distinct from
|
|
213
|
+
* CHART_BAR so the JSON self-identifies which shape it is (has `seriesId`),
|
|
214
|
+
* independent of the widget type used for validation. */
|
|
215
|
+
CHART_SERIES_BAR: "chart-series-bar",
|
|
206
216
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
207
217
|
/** Inline input widget (string or numeric) */
|
|
208
218
|
INLINE_INPUT: "inline-input",
|
|
@@ -436,7 +446,7 @@ const MATCHER = createToken({
|
|
|
436
446
|
});
|
|
437
447
|
const GROUP = createToken({
|
|
438
448
|
name: "GROUP",
|
|
439
|
-
pattern: /GROUP/
|
|
449
|
+
pattern: /GROUP(?=\s*[[{])/
|
|
440
450
|
});
|
|
441
451
|
const ITEM = createToken({
|
|
442
452
|
name: "ITEM",
|
|
@@ -486,6 +496,18 @@ const PICTO = createToken({
|
|
|
486
496
|
name: "PICTO",
|
|
487
497
|
pattern: /PICTO/
|
|
488
498
|
});
|
|
499
|
+
const LABEL = createToken({
|
|
500
|
+
name: "LABEL",
|
|
501
|
+
pattern: /LABEL(?=\s*\{)/
|
|
502
|
+
});
|
|
503
|
+
const SERIES = createToken({
|
|
504
|
+
name: "SERIES",
|
|
505
|
+
pattern: /SERIES(?=\s*\[)/
|
|
506
|
+
});
|
|
507
|
+
const SERIES_BAR = createToken({
|
|
508
|
+
name: "SERIES_BAR",
|
|
509
|
+
pattern: /SERIES_BAR(?=\s*\[)/
|
|
510
|
+
});
|
|
489
511
|
const SEP = createToken({
|
|
490
512
|
name: "SEP",
|
|
491
513
|
pattern: /SEP(?![a-zA-Z0-9_])/
|
|
@@ -684,6 +706,9 @@ const allTokens = [
|
|
|
684
706
|
Y_AXIS,
|
|
685
707
|
BAR,
|
|
686
708
|
PICTO,
|
|
709
|
+
LABEL,
|
|
710
|
+
SERIES_BAR,
|
|
711
|
+
SERIES,
|
|
687
712
|
SEP,
|
|
688
713
|
CARRY,
|
|
689
714
|
INPUT,
|
|
@@ -1770,22 +1795,15 @@ class MathExerciseParser extends CstParser {
|
|
|
1770
1795
|
});
|
|
1771
1796
|
this.MANY6({
|
|
1772
1797
|
GATE: () => {
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
const t = this.LA(k).tokenType;
|
|
1776
|
-
return t === BAR || t === PICTO;
|
|
1798
|
+
const t = this.LA(1).tokenType;
|
|
1799
|
+
return t === BAR || t === PICTO || t === SERIES || t === GROUP;
|
|
1777
1800
|
},
|
|
1778
1801
|
DEF: () => {
|
|
1779
1802
|
this.OR6([
|
|
1780
|
-
{
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
return this.LA(k).tokenType === BAR;
|
|
1785
|
-
},
|
|
1786
|
-
ALT: () => this.SUBRULE(this.chartBarItem)
|
|
1787
|
-
},
|
|
1788
|
-
{ ALT: () => this.SUBRULE(this.chartPictoItem) }
|
|
1803
|
+
{ GATE: () => this.LA(1).tokenType === BAR, ALT: () => this.SUBRULE(this.chartBarItem) },
|
|
1804
|
+
{ GATE: () => this.LA(1).tokenType === PICTO, ALT: () => this.SUBRULE(this.chartPictoItem) },
|
|
1805
|
+
{ GATE: () => this.LA(1).tokenType === SERIES, ALT: () => this.SUBRULE(this.chartSeriesItem) },
|
|
1806
|
+
{ ALT: () => this.SUBRULE(this.chartGroupItem) }
|
|
1789
1807
|
]);
|
|
1790
1808
|
}
|
|
1791
1809
|
});
|
|
@@ -1906,6 +1924,92 @@ class MathExerciseParser extends CstParser {
|
|
|
1906
1924
|
this.OR5([{ ALT: () => this.CONSUME5(Space) }, { ALT: () => this.CONSUME5(Newline) }]);
|
|
1907
1925
|
});
|
|
1908
1926
|
});
|
|
1927
|
+
this.chartSeriesItem = this.RULE("chartSeriesItem", () => {
|
|
1928
|
+
this.MANY(() => {
|
|
1929
|
+
this.OR([{ ALT: () => this.CONSUME(Space) }, { ALT: () => this.CONSUME(Newline) }]);
|
|
1930
|
+
});
|
|
1931
|
+
this.CONSUME(SERIES);
|
|
1932
|
+
this.CONSUME(LBracket);
|
|
1933
|
+
this.SUBRULE(this.parameterList);
|
|
1934
|
+
this.CONSUME(RBracket);
|
|
1935
|
+
this.MANY2(() => {
|
|
1936
|
+
this.OR2([{ ALT: () => this.CONSUME2(Space) }, { ALT: () => this.CONSUME2(Newline) }]);
|
|
1937
|
+
});
|
|
1938
|
+
this.CONSUME(LBrace);
|
|
1939
|
+
this.MANY3(() => {
|
|
1940
|
+
this.OR3([{ ALT: () => this.CONSUME3(Space) }, { ALT: () => this.CONSUME3(Newline) }]);
|
|
1941
|
+
});
|
|
1942
|
+
this.MANY4(() => {
|
|
1943
|
+
this.OR4([
|
|
1944
|
+
{ ALT: () => this.SUBRULE(this.inlineElement) },
|
|
1945
|
+
{ ALT: () => this.CONSUME4(Newline) }
|
|
1946
|
+
]);
|
|
1947
|
+
});
|
|
1948
|
+
this.CONSUME(RBrace);
|
|
1949
|
+
this.MANY5(() => {
|
|
1950
|
+
this.OR5([{ ALT: () => this.CONSUME5(Space) }, { ALT: () => this.CONSUME5(Newline) }]);
|
|
1951
|
+
});
|
|
1952
|
+
});
|
|
1953
|
+
this.chartGroupLabel = this.RULE("chartGroupLabel", () => {
|
|
1954
|
+
this.CONSUME(LABEL);
|
|
1955
|
+
this.MANY(() => {
|
|
1956
|
+
this.OR([{ ALT: () => this.CONSUME(Space) }, { ALT: () => this.CONSUME(Newline) }]);
|
|
1957
|
+
});
|
|
1958
|
+
this.CONSUME(LBrace);
|
|
1959
|
+
this.MANY2(() => {
|
|
1960
|
+
this.OR2([{ ALT: () => this.CONSUME2(Space) }, { ALT: () => this.CONSUME2(Newline) }]);
|
|
1961
|
+
});
|
|
1962
|
+
this.MANY3(() => {
|
|
1963
|
+
this.OR3([
|
|
1964
|
+
{ ALT: () => this.SUBRULE(this.inlineElement) },
|
|
1965
|
+
{ ALT: () => this.CONSUME3(Newline) }
|
|
1966
|
+
]);
|
|
1967
|
+
});
|
|
1968
|
+
this.CONSUME(RBrace);
|
|
1969
|
+
this.MANY4(() => {
|
|
1970
|
+
this.OR4([{ ALT: () => this.CONSUME4(Space) }, { ALT: () => this.CONSUME4(Newline) }]);
|
|
1971
|
+
});
|
|
1972
|
+
});
|
|
1973
|
+
this.chartSeriesBarItem = this.RULE("chartSeriesBarItem", () => {
|
|
1974
|
+
this.MANY(() => {
|
|
1975
|
+
this.OR([{ ALT: () => this.CONSUME(Space) }, { ALT: () => this.CONSUME(Newline) }]);
|
|
1976
|
+
});
|
|
1977
|
+
this.CONSUME(SERIES_BAR);
|
|
1978
|
+
this.CONSUME(LBracket);
|
|
1979
|
+
this.SUBRULE(this.parameterList);
|
|
1980
|
+
this.CONSUME(RBracket);
|
|
1981
|
+
this.MANY2(() => {
|
|
1982
|
+
this.OR2([{ ALT: () => this.CONSUME2(Space) }, { ALT: () => this.CONSUME2(Newline) }]);
|
|
1983
|
+
});
|
|
1984
|
+
});
|
|
1985
|
+
this.chartGroupItem = this.RULE("chartGroupItem", () => {
|
|
1986
|
+
this.MANY(() => {
|
|
1987
|
+
this.OR([{ ALT: () => this.CONSUME(Space) }, { ALT: () => this.CONSUME(Newline) }]);
|
|
1988
|
+
});
|
|
1989
|
+
this.CONSUME(GROUP);
|
|
1990
|
+
this.CONSUME(LBracket);
|
|
1991
|
+
this.SUBRULE(this.parameterList);
|
|
1992
|
+
this.CONSUME(RBracket);
|
|
1993
|
+
this.MANY2(() => {
|
|
1994
|
+
this.OR2([{ ALT: () => this.CONSUME2(Space) }, { ALT: () => this.CONSUME2(Newline) }]);
|
|
1995
|
+
});
|
|
1996
|
+
this.CONSUME(LBrace);
|
|
1997
|
+
this.MANY3(() => {
|
|
1998
|
+
this.OR3([{ ALT: () => this.CONSUME3(Space) }, { ALT: () => this.CONSUME3(Newline) }]);
|
|
1999
|
+
});
|
|
2000
|
+
this.MANY4({
|
|
2001
|
+
GATE: () => this.LA(1).tokenType === LABEL,
|
|
2002
|
+
DEF: () => this.SUBRULE(this.chartGroupLabel)
|
|
2003
|
+
});
|
|
2004
|
+
this.MANY5({
|
|
2005
|
+
GATE: () => this.LA(1).tokenType === SERIES_BAR,
|
|
2006
|
+
DEF: () => this.SUBRULE(this.chartSeriesBarItem)
|
|
2007
|
+
});
|
|
2008
|
+
this.CONSUME(RBrace);
|
|
2009
|
+
this.MANY6(() => {
|
|
2010
|
+
this.OR4([{ ALT: () => this.CONSUME4(Space) }, { ALT: () => this.CONSUME4(Newline) }]);
|
|
2011
|
+
});
|
|
2012
|
+
});
|
|
1909
2013
|
this.performSelfAnalysis();
|
|
1910
2014
|
}
|
|
1911
2015
|
/** Distinguish `{[number, number], ...}` and the valid empty form `{}` from string lists. */
|
|
@@ -3065,7 +3169,7 @@ function isSetSquareTool(value) {
|
|
|
3065
3169
|
function isToolNode(value) {
|
|
3066
3170
|
return ToolNodeSchema.safeParse(value).success;
|
|
3067
3171
|
}
|
|
3068
|
-
const CHART_TYPES = ["bar", "pictograph"];
|
|
3172
|
+
const CHART_TYPES = ["bar", "pictograph", "grouped-bar"];
|
|
3069
3173
|
const CHART_AXIS_DEFAULTS = { min: 0, max: 100, step: 10, visible: true };
|
|
3070
3174
|
const CHART_MAX_AXIS_TICKS = 200;
|
|
3071
3175
|
const CHART_MAX_PICTO_SLOTS = 60;
|
|
@@ -3145,6 +3249,63 @@ function createChartBar(id, opts) {
|
|
|
3145
3249
|
function isChartBar(value) {
|
|
3146
3250
|
return ChartBarSchema.safeParse(value).success;
|
|
3147
3251
|
}
|
|
3252
|
+
const ChartSeriesSchema = z.object({
|
|
3253
|
+
type: z.literal(AST_TYPES.CHART_SERIES),
|
|
3254
|
+
id: z.string().min(1),
|
|
3255
|
+
color: z.string().min(1),
|
|
3256
|
+
inlines: z.array(DisplayInlineNodeSchema).default([])
|
|
3257
|
+
});
|
|
3258
|
+
function createChartSeries(id, opts) {
|
|
3259
|
+
return ChartSeriesSchema.parse({
|
|
3260
|
+
type: AST_TYPES.CHART_SERIES,
|
|
3261
|
+
id,
|
|
3262
|
+
color: opts.color,
|
|
3263
|
+
inlines: opts.inlines ?? []
|
|
3264
|
+
});
|
|
3265
|
+
}
|
|
3266
|
+
function isChartSeries(value) {
|
|
3267
|
+
return ChartSeriesSchema.safeParse(value).success;
|
|
3268
|
+
}
|
|
3269
|
+
const ChartSeriesBarSchema = z.object({
|
|
3270
|
+
type: z.literal(AST_TYPES.CHART_SERIES_BAR),
|
|
3271
|
+
id: z.string().min(1),
|
|
3272
|
+
seriesId: z.string().min(1),
|
|
3273
|
+
value: z.number().default(0),
|
|
3274
|
+
answer: z.number().optional()
|
|
3275
|
+
});
|
|
3276
|
+
function createChartSeriesBar(id, opts) {
|
|
3277
|
+
return ChartSeriesBarSchema.parse({
|
|
3278
|
+
type: AST_TYPES.CHART_SERIES_BAR,
|
|
3279
|
+
id,
|
|
3280
|
+
seriesId: opts.seriesId,
|
|
3281
|
+
value: opts.value ?? 0,
|
|
3282
|
+
answer: opts.answer
|
|
3283
|
+
});
|
|
3284
|
+
}
|
|
3285
|
+
function isChartSeriesBar(value) {
|
|
3286
|
+
return ChartSeriesBarSchema.safeParse(value).success;
|
|
3287
|
+
}
|
|
3288
|
+
const ChartGroupSchema = z.object({
|
|
3289
|
+
type: z.literal(AST_TYPES.CHART_GROUP),
|
|
3290
|
+
id: z.string().min(1),
|
|
3291
|
+
labelInlines: z.array(InlineNodeSchema).default([]),
|
|
3292
|
+
bars: z.array(ChartSeriesBarSchema).default([])
|
|
3293
|
+
});
|
|
3294
|
+
function createChartGroup(id, opts = {}) {
|
|
3295
|
+
return ChartGroupSchema.parse({
|
|
3296
|
+
type: AST_TYPES.CHART_GROUP,
|
|
3297
|
+
id,
|
|
3298
|
+
labelInlines: opts.labelInlines ?? [],
|
|
3299
|
+
bars: opts.bars ?? []
|
|
3300
|
+
});
|
|
3301
|
+
}
|
|
3302
|
+
function isChartGroup(value) {
|
|
3303
|
+
return ChartGroupSchema.safeParse(value).success;
|
|
3304
|
+
}
|
|
3305
|
+
function alignGroupBarsToSeries(group, series) {
|
|
3306
|
+
const bySeriesId = new Map(group.bars.map((bar) => [bar.seriesId, bar]));
|
|
3307
|
+
return series.map((s) => bySeriesId.get(s.id));
|
|
3308
|
+
}
|
|
3148
3309
|
const ChartBlockSchema = z.object({
|
|
3149
3310
|
type: z.literal(AST_TYPES.CHART_BLOCK),
|
|
3150
3311
|
name: z.string().optional(),
|
|
@@ -3156,7 +3317,10 @@ const ChartBlockSchema = z.object({
|
|
|
3156
3317
|
xAxis: ChartAxisSchema.optional(),
|
|
3157
3318
|
yAxis: ChartAxisSchema.optional(),
|
|
3158
3319
|
bars: z.array(ChartBarSchema).default([]),
|
|
3159
|
-
pictos: z.array(ChartPictoSchema).default([])
|
|
3320
|
+
pictos: z.array(ChartPictoSchema).default([]),
|
|
3321
|
+
legend: z.boolean().default(false),
|
|
3322
|
+
series: z.array(ChartSeriesSchema).default([]),
|
|
3323
|
+
groups: z.array(ChartGroupSchema).default([])
|
|
3160
3324
|
}).superRefine((block, ctx) => {
|
|
3161
3325
|
validateChartBlock(block, ctx);
|
|
3162
3326
|
});
|
|
@@ -3181,10 +3345,10 @@ function validateChartBlock(block, ctx) {
|
|
|
3181
3345
|
const { valueAxis } = resolveChartAxes(block);
|
|
3182
3346
|
validateValueAxisRange(valueAxis, ctx);
|
|
3183
3347
|
if (block.chartType === "bar") {
|
|
3184
|
-
if (block.pictos.length > 0) {
|
|
3348
|
+
if (block.pictos.length > 0 || block.series.length > 0 || block.groups.length > 0) {
|
|
3185
3349
|
ctx.addIssue({
|
|
3186
3350
|
code: z.ZodIssueCode.custom,
|
|
3187
|
-
message: 'CHART[type="bar"]: body must contain BAR items only, not PICTO',
|
|
3351
|
+
message: 'CHART[type="bar"]: body must contain BAR items only, not PICTO, SERIES, or GROUP',
|
|
3188
3352
|
path: ["pictos"]
|
|
3189
3353
|
});
|
|
3190
3354
|
return;
|
|
@@ -3197,16 +3361,16 @@ function validateChartBlock(block, ctx) {
|
|
|
3197
3361
|
});
|
|
3198
3362
|
return;
|
|
3199
3363
|
}
|
|
3200
|
-
validateUniqueIds(block.bars, ctx);
|
|
3364
|
+
validateUniqueIds(block.bars, ctx, (i) => ["bars", i]);
|
|
3201
3365
|
validateChartSnap(block.snap, valueAxis.step, ctx);
|
|
3202
|
-
validateBarAnswers(block.bars, valueAxis, block.snap, ctx);
|
|
3366
|
+
validateBarAnswers(block.bars, valueAxis, block.snap, ctx, (i) => ["bars", i]);
|
|
3203
3367
|
return;
|
|
3204
3368
|
}
|
|
3205
3369
|
if (block.chartType === "pictograph") {
|
|
3206
|
-
if (block.bars.length > 0) {
|
|
3370
|
+
if (block.bars.length > 0 || block.series.length > 0 || block.groups.length > 0) {
|
|
3207
3371
|
ctx.addIssue({
|
|
3208
3372
|
code: z.ZodIssueCode.custom,
|
|
3209
|
-
message: 'CHART[type="pictograph"]: body must contain PICTO items only, not BAR',
|
|
3373
|
+
message: 'CHART[type="pictograph"]: body must contain PICTO items only, not BAR, SERIES, or GROUP',
|
|
3210
3374
|
path: ["bars"]
|
|
3211
3375
|
});
|
|
3212
3376
|
return;
|
|
@@ -3227,7 +3391,7 @@ function validateChartBlock(block, ctx) {
|
|
|
3227
3391
|
});
|
|
3228
3392
|
return;
|
|
3229
3393
|
}
|
|
3230
|
-
validateUniqueIds(block.pictos, ctx);
|
|
3394
|
+
validateUniqueIds(block.pictos, ctx, (i) => ["pictos", i]);
|
|
3231
3395
|
if (!axisHasNumericParams(valueAxis.axis)) {
|
|
3232
3396
|
ctx.addIssue({
|
|
3233
3397
|
code: z.ZodIssueCode.custom,
|
|
@@ -3248,6 +3412,63 @@ function validateChartBlock(block, ctx) {
|
|
|
3248
3412
|
validatePictoAnswers(block.pictos, valueAxis, ctx);
|
|
3249
3413
|
return;
|
|
3250
3414
|
}
|
|
3415
|
+
if (block.chartType === "grouped-bar") {
|
|
3416
|
+
if (block.bars.length > 0 || block.pictos.length > 0) {
|
|
3417
|
+
ctx.addIssue({
|
|
3418
|
+
code: z.ZodIssueCode.custom,
|
|
3419
|
+
message: 'CHART[type="grouped-bar"]: body must contain SERIES and GROUP items only, not BAR or PICTO',
|
|
3420
|
+
path: ["bars"]
|
|
3421
|
+
});
|
|
3422
|
+
return;
|
|
3423
|
+
}
|
|
3424
|
+
if (block.series.length === 0) {
|
|
3425
|
+
ctx.addIssue({
|
|
3426
|
+
code: z.ZodIssueCode.custom,
|
|
3427
|
+
message: 'CHART[type="grouped-bar"]: at least one SERIES is required',
|
|
3428
|
+
path: ["series"]
|
|
3429
|
+
});
|
|
3430
|
+
return;
|
|
3431
|
+
}
|
|
3432
|
+
if (block.groups.length === 0) {
|
|
3433
|
+
ctx.addIssue({
|
|
3434
|
+
code: z.ZodIssueCode.custom,
|
|
3435
|
+
message: 'CHART[type="grouped-bar"]: at least one GROUP is required',
|
|
3436
|
+
path: ["groups"]
|
|
3437
|
+
});
|
|
3438
|
+
return;
|
|
3439
|
+
}
|
|
3440
|
+
validateUniqueIds(block.series, ctx, (i) => ["series", i]);
|
|
3441
|
+
validateUniqueIds(block.groups, ctx, (i) => ["groups", i]);
|
|
3442
|
+
const allBars = block.groups.flatMap((g, gi) => g.bars.map((bar, bi) => ({ ...bar, groupIndex: gi, barIndex: bi })));
|
|
3443
|
+
const pathForFlatBar = (i) => ["groups", allBars[i].groupIndex, "bars", allBars[i].barIndex];
|
|
3444
|
+
validateUniqueIds(allBars, ctx, pathForFlatBar);
|
|
3445
|
+
const seriesIds = new Set(block.series.map((s) => s.id));
|
|
3446
|
+
block.groups.forEach((group, gi) => {
|
|
3447
|
+
const seenInGroup = /* @__PURE__ */ new Set();
|
|
3448
|
+
group.bars.forEach((bar, bi) => {
|
|
3449
|
+
if (!seriesIds.has(bar.seriesId)) {
|
|
3450
|
+
ctx.addIssue({
|
|
3451
|
+
code: z.ZodIssueCode.custom,
|
|
3452
|
+
message: `CHART: GROUP "${group.id}" SERIES_BAR "${bar.id}" references unknown series "${bar.seriesId}" — no SERIES with that id is declared`,
|
|
3453
|
+
path: ["groups", gi, "bars", bi, "seriesId"]
|
|
3454
|
+
});
|
|
3455
|
+
return;
|
|
3456
|
+
}
|
|
3457
|
+
if (seenInGroup.has(bar.seriesId)) {
|
|
3458
|
+
ctx.addIssue({
|
|
3459
|
+
code: z.ZodIssueCode.custom,
|
|
3460
|
+
message: `CHART: GROUP "${group.id}" references series "${bar.seriesId}" twice — each SERIES can appear at most once per GROUP`,
|
|
3461
|
+
path: ["groups", gi, "bars", bi, "seriesId"]
|
|
3462
|
+
});
|
|
3463
|
+
return;
|
|
3464
|
+
}
|
|
3465
|
+
seenInGroup.add(bar.seriesId);
|
|
3466
|
+
});
|
|
3467
|
+
});
|
|
3468
|
+
validateChartSnap(block.snap, valueAxis.step, ctx);
|
|
3469
|
+
validateBarAnswers(allBars, valueAxis, block.snap, ctx, pathForFlatBar);
|
|
3470
|
+
return;
|
|
3471
|
+
}
|
|
3251
3472
|
ctx.addIssue({
|
|
3252
3473
|
code: z.ZodIssueCode.custom,
|
|
3253
3474
|
message: `CHART: unsupported chartType "${block.chartType}" — add a validation branch to validateChartBlock`,
|
|
@@ -3268,14 +3489,14 @@ function resolveNumericAxis(axis) {
|
|
|
3268
3489
|
function hasAmbiguousValueAxes(block) {
|
|
3269
3490
|
return axisHasNumericParams(block.xAxis) && axisHasNumericParams(block.yAxis);
|
|
3270
3491
|
}
|
|
3271
|
-
function validateUniqueIds(items, ctx) {
|
|
3492
|
+
function validateUniqueIds(items, ctx, pathFor) {
|
|
3272
3493
|
const seen = /* @__PURE__ */ new Set();
|
|
3273
3494
|
items.forEach((item, index) => {
|
|
3274
3495
|
if (seen.has(item.id)) {
|
|
3275
3496
|
ctx.addIssue({
|
|
3276
3497
|
code: z.ZodIssueCode.custom,
|
|
3277
3498
|
message: `CHART: duplicate id "${item.id}" — ids must be unique within the chart`,
|
|
3278
|
-
path: [index, "id"]
|
|
3499
|
+
path: [...pathFor(index), "id"]
|
|
3279
3500
|
});
|
|
3280
3501
|
return;
|
|
3281
3502
|
}
|
|
@@ -3317,14 +3538,14 @@ function validateChartSnap(snap, step, ctx) {
|
|
|
3317
3538
|
});
|
|
3318
3539
|
}
|
|
3319
3540
|
}
|
|
3320
|
-
function validateBarAnswers(bars, valueAxis, snap, ctx) {
|
|
3541
|
+
function validateBarAnswers(bars, valueAxis, snap, ctx, pathFor) {
|
|
3321
3542
|
const gridStep = snap ?? valueAxis.step;
|
|
3322
3543
|
bars.forEach((bar, index) => {
|
|
3323
3544
|
if (bar.value < valueAxis.min || bar.value > valueAxis.max) {
|
|
3324
3545
|
ctx.addIssue({
|
|
3325
3546
|
code: z.ZodIssueCode.custom,
|
|
3326
3547
|
message: `CHART: BAR "${bar.id}" value (${bar.value}) is outside axis range [${valueAxis.min}, ${valueAxis.max}] — the bar will not render correctly`,
|
|
3327
|
-
path: [
|
|
3548
|
+
path: [...pathFor(index), "value"]
|
|
3328
3549
|
});
|
|
3329
3550
|
}
|
|
3330
3551
|
if (bar.answer === void 0) return;
|
|
@@ -3332,7 +3553,7 @@ function validateBarAnswers(bars, valueAxis, snap, ctx) {
|
|
|
3332
3553
|
ctx.addIssue({
|
|
3333
3554
|
code: z.ZodIssueCode.custom,
|
|
3334
3555
|
message: `CHART: BAR "${bar.id}" answer (${bar.answer}) is outside axis range [${valueAxis.min}, ${valueAxis.max}] — the student can never reach this value`,
|
|
3335
|
-
path: [
|
|
3556
|
+
path: [...pathFor(index), "answer"]
|
|
3336
3557
|
});
|
|
3337
3558
|
return;
|
|
3338
3559
|
}
|
|
@@ -3341,7 +3562,7 @@ function validateBarAnswers(bars, valueAxis, snap, ctx) {
|
|
|
3341
3562
|
ctx.addIssue({
|
|
3342
3563
|
code: z.ZodIssueCode.custom,
|
|
3343
3564
|
message: `CHART: BAR "${bar.id}" answer (${bar.answer}) is not on the drag grid (min ${valueAxis.min} + multiples of ${gridStep}) — the student can never land on it. Align the answer to the step/snap grid.`,
|
|
3344
|
-
path: [
|
|
3565
|
+
path: [...pathFor(index), "answer"]
|
|
3345
3566
|
});
|
|
3346
3567
|
}
|
|
3347
3568
|
});
|
|
@@ -3403,7 +3624,10 @@ function createChartBlock(chartType, opts = {}) {
|
|
|
3403
3624
|
xAxis: opts.xAxis,
|
|
3404
3625
|
yAxis: opts.yAxis,
|
|
3405
3626
|
bars: opts.bars ?? [],
|
|
3406
|
-
pictos: opts.pictos ?? []
|
|
3627
|
+
pictos: opts.pictos ?? [],
|
|
3628
|
+
series: opts.series ?? [],
|
|
3629
|
+
groups: opts.groups ?? [],
|
|
3630
|
+
legend: opts.legend ?? false
|
|
3407
3631
|
});
|
|
3408
3632
|
}
|
|
3409
3633
|
function isChartBlock(value) {
|
|
@@ -3490,7 +3714,9 @@ const ExerciseDocumentSchema = z.object({
|
|
|
3490
3714
|
};
|
|
3491
3715
|
const visitInlines = (inlines, basePath) => {
|
|
3492
3716
|
inlines.forEach((inline, i) => {
|
|
3493
|
-
if (inline.type === AST_TYPES.INLINE_INPUT || inline.type === AST_TYPES.FRACTION || inline.type === AST_TYPES.IMAGE) {
|
|
3717
|
+
if (inline.type === AST_TYPES.INLINE_INPUT || inline.type === AST_TYPES.FRACTION || inline.type === AST_TYPES.IMAGE || inline.type === AST_TYPES.VISUAL_FRACTION) {
|
|
3718
|
+
record(inline.name, [...basePath, i, "name"]);
|
|
3719
|
+
} else if (inline.type === AST_TYPES.CLOCK && inline.mode === "interactive") {
|
|
3494
3720
|
record(inline.name, [...basePath, i, "name"]);
|
|
3495
3721
|
}
|
|
3496
3722
|
});
|
|
@@ -3522,6 +3748,28 @@ const ExerciseDocumentSchema = z.object({
|
|
|
3522
3748
|
pm.groups.flat().forEach((item, ii) => {
|
|
3523
3749
|
visitInlines(item.inlines, ["lines", bi, "items", ii, "inlines"]);
|
|
3524
3750
|
});
|
|
3751
|
+
} else if (block.type === AST_TYPES.CHART_BLOCK) {
|
|
3752
|
+
const chart = block;
|
|
3753
|
+
const base = ["lines", bi];
|
|
3754
|
+
chart.bars.forEach((bar, i) => {
|
|
3755
|
+
if (bar.answer !== void 0) record(bar.id, [...base, "bars", i, "id"]);
|
|
3756
|
+
visitInlines(bar.inlines, [...base, "bars", i, "inlines"]);
|
|
3757
|
+
});
|
|
3758
|
+
chart.pictos.forEach((picto, i) => {
|
|
3759
|
+
if (picto.answer !== void 0) record(picto.id, [...base, "pictos", i, "id"]);
|
|
3760
|
+
visitInlines(picto.inlines, [...base, "pictos", i, "inlines"]);
|
|
3761
|
+
});
|
|
3762
|
+
chart.groups.forEach((group, gi) => {
|
|
3763
|
+
group.bars.forEach((bar, i) => {
|
|
3764
|
+
if (bar.answer !== void 0) record(bar.id, [...base, "groups", gi, "bars", i, "id"]);
|
|
3765
|
+
});
|
|
3766
|
+
visitInlines(group.labelInlines, [...base, "groups", gi, "labelInlines"]);
|
|
3767
|
+
});
|
|
3768
|
+
chart.series.forEach((series, i) => {
|
|
3769
|
+
visitInlines(series.inlines, [...base, "series", i, "inlines"]);
|
|
3770
|
+
});
|
|
3771
|
+
if (chart.xAxis) visitInlines(chart.xAxis.inlines, [...base, "xAxis", "inlines"]);
|
|
3772
|
+
if (chart.yAxis) visitInlines(chart.yAxis.inlines, [...base, "yAxis", "inlines"]);
|
|
3525
3773
|
} else if (block.type === AST_TYPES.RADIO_OPTIONS) {
|
|
3526
3774
|
record(block.name, ["lines", bi, "name"]);
|
|
3527
3775
|
} else if (block.type === AST_TYPES.GEOMETRY_BLOCK && block.name !== void 0) {
|
|
@@ -4093,7 +4341,7 @@ class NaturalDSLVisitor extends BaseCstVisitor {
|
|
|
4093
4341
|
chartBlock(ctx) {
|
|
4094
4342
|
const params = this.visit(ctx.parameterList);
|
|
4095
4343
|
const chartType = params.type;
|
|
4096
|
-
if (!chartType) throw new Error(
|
|
4344
|
+
if (!chartType) throw new Error(`CHART: type is required (${CHART_TYPES.map((t) => `"${t}"`).join(" | ")})`);
|
|
4097
4345
|
if (!CHART_TYPES.includes(chartType)) {
|
|
4098
4346
|
throw new Error(`CHART: type must be one of ${CHART_TYPES.join(", ")} (got "${chartType}")`);
|
|
4099
4347
|
}
|
|
@@ -4112,7 +4360,26 @@ class NaturalDSLVisitor extends BaseCstVisitor {
|
|
|
4112
4360
|
const yAxis = ctx.chartYAxis ? this.visit(ctx.chartYAxis) : void 0;
|
|
4113
4361
|
const bars = ctx.chartBarItem ? ctx.chartBarItem.map((b) => this.visit(b)) : [];
|
|
4114
4362
|
const pictos = ctx.chartPictoItem ? ctx.chartPictoItem.map((p) => this.visit(p)) : [];
|
|
4115
|
-
|
|
4363
|
+
const series = ctx.chartSeriesItem ? ctx.chartSeriesItem.map((s) => this.visit(s)) : [];
|
|
4364
|
+
const groups = ctx.chartGroupItem ? ctx.chartGroupItem.map((g) => this.visit(g)) : [];
|
|
4365
|
+
if (params.legend !== void 0 && chartType !== "grouped-bar") {
|
|
4366
|
+
throw new Error(`CHART: "legend" is only supported for type="grouped-bar" (got "${chartType}")`);
|
|
4367
|
+
}
|
|
4368
|
+
const legend = params.legend === true || params.legend === "true";
|
|
4369
|
+
return createChartBlock(chartType, {
|
|
4370
|
+
bars,
|
|
4371
|
+
pictos,
|
|
4372
|
+
series,
|
|
4373
|
+
groups,
|
|
4374
|
+
legend,
|
|
4375
|
+
name,
|
|
4376
|
+
title,
|
|
4377
|
+
grid,
|
|
4378
|
+
scale,
|
|
4379
|
+
snap,
|
|
4380
|
+
xAxis,
|
|
4381
|
+
yAxis
|
|
4382
|
+
});
|
|
4116
4383
|
}
|
|
4117
4384
|
/** X_AXIS and Y_AXIS carry identical params — only the produced AST type differs.
|
|
4118
4385
|
* Chevrotain needs two separate grammar rules, but one visitor body serves both. */
|
|
@@ -4151,6 +4418,52 @@ class NaturalDSLVisitor extends BaseCstVisitor {
|
|
|
4151
4418
|
inlines
|
|
4152
4419
|
});
|
|
4153
4420
|
}
|
|
4421
|
+
chartSeriesItem(ctx) {
|
|
4422
|
+
const params = this.visit(ctx.parameterList);
|
|
4423
|
+
const inlines = ctx.inlineElement ? ctx.inlineElement.map((e) => this.visit(e)) : [];
|
|
4424
|
+
if (inlines.some((n) => !DisplayInlineNodeSchema.safeParse(n).success)) {
|
|
4425
|
+
throw new Error(
|
|
4426
|
+
`CHART: SERIES "${params.id}" label must be display-only — inputs, drag options, clocks and interactive fractions are not allowed in a legend label`
|
|
4427
|
+
);
|
|
4428
|
+
}
|
|
4429
|
+
if (!params.color) {
|
|
4430
|
+
throw new Error(`CHART: SERIES "${params.id}" requires "color"`);
|
|
4431
|
+
}
|
|
4432
|
+
return createChartSeries(params.id, {
|
|
4433
|
+
color: params.color,
|
|
4434
|
+
inlines
|
|
4435
|
+
});
|
|
4436
|
+
}
|
|
4437
|
+
chartGroupLabel(ctx) {
|
|
4438
|
+
return ctx.inlineElement ? ctx.inlineElement.map((e) => this.visit(e)) : [];
|
|
4439
|
+
}
|
|
4440
|
+
chartGroupItem(ctx) {
|
|
4441
|
+
const params = this.visit(ctx.parameterList);
|
|
4442
|
+
if (ctx.chartGroupLabel && ctx.chartGroupLabel.length > 1) {
|
|
4443
|
+
throw new Error(`CHART: GROUP "${params.id}" has more than one LABEL — only one is allowed`);
|
|
4444
|
+
}
|
|
4445
|
+
const labelInlines = ctx.chartGroupLabel ? this.visit(ctx.chartGroupLabel) : [];
|
|
4446
|
+
const bars = ctx.chartSeriesBarItem ? ctx.chartSeriesBarItem.map((b) => this.visit(b)) : [];
|
|
4447
|
+
return createChartGroup(params.id, { labelInlines, bars });
|
|
4448
|
+
}
|
|
4449
|
+
// `params.series` is the raw DSL attribute name (SERIES_BAR[series="..."])
|
|
4450
|
+
// — unrelated to the AST field's own `seriesId` name.
|
|
4451
|
+
chartSeriesBarItem(ctx) {
|
|
4452
|
+
const params = this.visit(ctx.parameterList);
|
|
4453
|
+
if (!params.series) {
|
|
4454
|
+
throw new Error(`CHART: SERIES_BAR "${params.id}" requires "series"`);
|
|
4455
|
+
}
|
|
4456
|
+
if (params.color !== void 0) {
|
|
4457
|
+
throw new Error(
|
|
4458
|
+
`CHART: SERIES_BAR "${params.id}" cannot set "color" — it comes from its SERIES`
|
|
4459
|
+
);
|
|
4460
|
+
}
|
|
4461
|
+
return createChartSeriesBar(params.id, {
|
|
4462
|
+
seriesId: params.series,
|
|
4463
|
+
value: params.value !== void 0 ? Number(params.value) : void 0,
|
|
4464
|
+
answer: params.answer !== void 0 ? Number(params.answer) : void 0
|
|
4465
|
+
});
|
|
4466
|
+
}
|
|
4154
4467
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
4155
4468
|
// Tools
|
|
4156
4469
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -4605,23 +4918,23 @@ const ChartAxisJSONSchema = z.object({
|
|
|
4605
4918
|
});
|
|
4606
4919
|
}
|
|
4607
4920
|
});
|
|
4608
|
-
const
|
|
4609
|
-
z.
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
id: z.string(),
|
|
4619
|
-
type: z.literal(JSON_TYPES.CHART_BAR),
|
|
4921
|
+
const ChartBarJSONBaseSchema = z.object({
|
|
4922
|
+
id: z.string(),
|
|
4923
|
+
type: z.literal(JSON_TYPES.CHART_BAR),
|
|
4924
|
+
value: z.number(),
|
|
4925
|
+
answer: z.number().optional(),
|
|
4926
|
+
color: z.string().optional(),
|
|
4927
|
+
label: z.array(LayoutItemSchema).optional()
|
|
4928
|
+
});
|
|
4929
|
+
const ChartBarJSONSchema = z.union([
|
|
4930
|
+
ChartBarJSONBaseSchema.extend({
|
|
4620
4931
|
interactive: z.literal(true),
|
|
4621
|
-
|
|
4622
|
-
widgetId: z.string()
|
|
4623
|
-
|
|
4624
|
-
|
|
4932
|
+
/** The widgets/answers key, equal to `id` when compiled. */
|
|
4933
|
+
widgetId: z.string()
|
|
4934
|
+
}),
|
|
4935
|
+
ChartBarJSONBaseSchema.extend({
|
|
4936
|
+
interactive: z.literal(false).optional(),
|
|
4937
|
+
widgetId: z.undefined().optional()
|
|
4625
4938
|
})
|
|
4626
4939
|
]);
|
|
4627
4940
|
const ChartPictoJSONSchema = z.object({
|
|
@@ -4635,21 +4948,55 @@ const ChartPictoJSONSchema = z.object({
|
|
|
4635
4948
|
),
|
|
4636
4949
|
label: z.array(LayoutItemSchema).optional()
|
|
4637
4950
|
});
|
|
4638
|
-
const
|
|
4951
|
+
const ChartSeriesJSONSchema = z.object({
|
|
4952
|
+
id: z.string(),
|
|
4953
|
+
color: z.string(),
|
|
4954
|
+
label: z.array(LayoutItemSchema).optional()
|
|
4955
|
+
});
|
|
4956
|
+
const ChartSeriesBarJSONSchema = z.object({
|
|
4957
|
+
id: z.string(),
|
|
4958
|
+
type: z.literal(JSON_TYPES.CHART_SERIES_BAR),
|
|
4959
|
+
value: z.number(),
|
|
4960
|
+
answer: z.number().optional(),
|
|
4961
|
+
color: z.string(),
|
|
4962
|
+
seriesId: z.string()
|
|
4963
|
+
});
|
|
4964
|
+
const ChartGroupJSONSchema = z.object({
|
|
4965
|
+
id: z.string(),
|
|
4966
|
+
label: z.array(LayoutItemSchema).optional(),
|
|
4967
|
+
bars: z.array(ChartSeriesBarJSONSchema)
|
|
4968
|
+
});
|
|
4969
|
+
const ChartItemBaseSchema = z.object({
|
|
4639
4970
|
id: z.string(),
|
|
4640
4971
|
type: z.literal(JSON_TYPES.CHART),
|
|
4641
4972
|
name: z.string().optional(),
|
|
4642
4973
|
title: z.string().optional(),
|
|
4643
|
-
chartType: z.enum(CHART_TYPES),
|
|
4644
4974
|
orientation: z.enum(["vertical", "horizontal"]).default("vertical"),
|
|
4645
4975
|
grid: z.boolean().default(false),
|
|
4646
4976
|
scale: z.number().positive().default(1),
|
|
4647
4977
|
snap: z.number().positive().optional(),
|
|
4648
4978
|
xAxis: ChartAxisJSONSchema.optional(),
|
|
4649
|
-
yAxis: ChartAxisJSONSchema.optional()
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4979
|
+
yAxis: ChartAxisJSONSchema.optional()
|
|
4980
|
+
});
|
|
4981
|
+
const ChartItemBarSchema = ChartItemBaseSchema.extend({
|
|
4982
|
+
chartType: z.literal("bar"),
|
|
4983
|
+
bars: z.array(ChartBarJSONSchema)
|
|
4984
|
+
});
|
|
4985
|
+
const ChartItemPictographSchema = ChartItemBaseSchema.extend({
|
|
4986
|
+
chartType: z.literal("pictograph"),
|
|
4987
|
+
pictos: z.array(ChartPictoJSONSchema)
|
|
4988
|
+
});
|
|
4989
|
+
const ChartItemGroupedBarSchema = ChartItemBaseSchema.extend({
|
|
4990
|
+
chartType: z.literal("grouped-bar"),
|
|
4991
|
+
series: z.array(ChartSeriesJSONSchema),
|
|
4992
|
+
groups: z.array(ChartGroupJSONSchema),
|
|
4993
|
+
legend: z.boolean().default(false)
|
|
4994
|
+
});
|
|
4995
|
+
const ChartItemSchema = z.discriminatedUnion("chartType", [
|
|
4996
|
+
ChartItemBarSchema,
|
|
4997
|
+
ChartItemPictographSchema,
|
|
4998
|
+
ChartItemGroupedBarSchema
|
|
4999
|
+
]).superRefine((item, ctx) => {
|
|
4653
5000
|
if (item.chartType === "bar" && item.bars.length === 0) {
|
|
4654
5001
|
ctx.addIssue({
|
|
4655
5002
|
code: z.ZodIssueCode.custom,
|
|
@@ -4657,18 +5004,63 @@ const ChartItemSchema = z.object({
|
|
|
4657
5004
|
path: ["bars"]
|
|
4658
5005
|
});
|
|
4659
5006
|
}
|
|
4660
|
-
if (item.chartType === "pictograph"
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
5007
|
+
if (item.chartType === "pictograph") {
|
|
5008
|
+
if (item.pictos.length === 0) {
|
|
5009
|
+
ctx.addIssue({
|
|
5010
|
+
code: z.ZodIssueCode.custom,
|
|
5011
|
+
message: 'CHART[type="pictograph"]: at least one PICTO is required',
|
|
5012
|
+
path: ["pictos"]
|
|
5013
|
+
});
|
|
5014
|
+
}
|
|
5015
|
+
if (item.snap !== void 0) {
|
|
5016
|
+
ctx.addIssue({
|
|
5017
|
+
code: z.ZodIssueCode.custom,
|
|
5018
|
+
message: 'CHART[type="pictograph"]: snap is not supported for pictograph charts',
|
|
5019
|
+
path: ["snap"]
|
|
5020
|
+
});
|
|
5021
|
+
}
|
|
4666
5022
|
}
|
|
4667
|
-
if (item.chartType === "
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
5023
|
+
if (item.chartType === "grouped-bar") {
|
|
5024
|
+
if (item.series.length === 0) {
|
|
5025
|
+
ctx.addIssue({
|
|
5026
|
+
code: z.ZodIssueCode.custom,
|
|
5027
|
+
message: 'CHART[type="grouped-bar"]: at least one SERIES is required',
|
|
5028
|
+
path: ["series"]
|
|
5029
|
+
});
|
|
5030
|
+
}
|
|
5031
|
+
if (item.groups.length === 0) {
|
|
5032
|
+
ctx.addIssue({
|
|
5033
|
+
code: z.ZodIssueCode.custom,
|
|
5034
|
+
message: 'CHART[type="grouped-bar"]: at least one GROUP is required',
|
|
5035
|
+
path: ["groups"]
|
|
5036
|
+
});
|
|
5037
|
+
}
|
|
5038
|
+
validateUniqueIds(item.series, ctx, (i) => ["series", i]);
|
|
5039
|
+
validateUniqueIds(item.groups, ctx, (i) => ["groups", i]);
|
|
5040
|
+
const allBars = item.groups.flatMap((g, gi) => g.bars.map((bar, bi) => ({ id: bar.id, gi, bi })));
|
|
5041
|
+
validateUniqueIds(allBars, ctx, (i) => ["groups", allBars[i].gi, "bars", allBars[i].bi]);
|
|
5042
|
+
const seriesIds = new Set(item.series.map((s) => s.id));
|
|
5043
|
+
item.groups.forEach((group, gi) => {
|
|
5044
|
+
const seenInGroup = /* @__PURE__ */ new Set();
|
|
5045
|
+
group.bars.forEach((bar, bi) => {
|
|
5046
|
+
if (!seriesIds.has(bar.seriesId)) {
|
|
5047
|
+
ctx.addIssue({
|
|
5048
|
+
code: z.ZodIssueCode.custom,
|
|
5049
|
+
message: `CHART[type="grouped-bar"]: GROUP "${group.id}" bar "${bar.id}" references unknown seriesId "${bar.seriesId}" — no SERIES with that id is declared`,
|
|
5050
|
+
path: ["groups", gi, "bars", bi, "seriesId"]
|
|
5051
|
+
});
|
|
5052
|
+
return;
|
|
5053
|
+
}
|
|
5054
|
+
if (seenInGroup.has(bar.seriesId)) {
|
|
5055
|
+
ctx.addIssue({
|
|
5056
|
+
code: z.ZodIssueCode.custom,
|
|
5057
|
+
message: `CHART[type="grouped-bar"]: GROUP "${group.id}" has two bars for seriesId "${bar.seriesId}" — each series can appear at most once per group`,
|
|
5058
|
+
path: ["groups", gi, "bars", bi, "seriesId"]
|
|
5059
|
+
});
|
|
5060
|
+
return;
|
|
5061
|
+
}
|
|
5062
|
+
seenInGroup.add(bar.seriesId);
|
|
5063
|
+
});
|
|
4672
5064
|
});
|
|
4673
5065
|
}
|
|
4674
5066
|
});
|
|
@@ -10767,6 +11159,8 @@ function collectAllInlines(blocks) {
|
|
|
10767
11159
|
for (const picto of chart.pictos) result.push(...picto.inlines);
|
|
10768
11160
|
if (chart.xAxis) result.push(...chart.xAxis.inlines);
|
|
10769
11161
|
if (chart.yAxis) result.push(...chart.yAxis.inlines);
|
|
11162
|
+
for (const series of chart.series) result.push(...series.inlines);
|
|
11163
|
+
for (const group of chart.groups) result.push(...group.labelInlines);
|
|
10770
11164
|
}
|
|
10771
11165
|
}
|
|
10772
11166
|
return result;
|
|
@@ -10801,27 +11195,19 @@ function transformChart(block, idGenerator, inlineDragIds) {
|
|
|
10801
11195
|
const chartAnswers = {};
|
|
10802
11196
|
const bars = block.bars.map((bar) => {
|
|
10803
11197
|
const label = toLabel(bar.inlines);
|
|
10804
|
-
|
|
10805
|
-
chartWidgets[bar.id] = { type: JSON_TYPES.CHART_BAR, value: bar.value };
|
|
10806
|
-
chartAnswers[bar.id] = bar.answer;
|
|
10807
|
-
return {
|
|
10808
|
-
id: bar.id,
|
|
10809
|
-
type: JSON_TYPES.CHART_BAR,
|
|
10810
|
-
interactive: true,
|
|
10811
|
-
value: bar.value,
|
|
10812
|
-
widgetId: bar.id,
|
|
10813
|
-
...bar.color !== void 0 && { color: bar.color },
|
|
10814
|
-
...label !== void 0 && { label }
|
|
10815
|
-
};
|
|
10816
|
-
}
|
|
10817
|
-
return {
|
|
11198
|
+
const common = {
|
|
10818
11199
|
id: bar.id,
|
|
10819
11200
|
type: JSON_TYPES.CHART_BAR,
|
|
10820
|
-
interactive: false,
|
|
10821
11201
|
value: bar.value,
|
|
10822
11202
|
...bar.color !== void 0 && { color: bar.color },
|
|
10823
11203
|
...label !== void 0 && { label }
|
|
10824
11204
|
};
|
|
11205
|
+
if (bar.answer !== void 0) {
|
|
11206
|
+
chartWidgets[bar.id] = { type: JSON_TYPES.CHART_BAR, value: bar.value };
|
|
11207
|
+
chartAnswers[bar.id] = bar.answer;
|
|
11208
|
+
return { ...common, interactive: true, widgetId: bar.id, answer: bar.answer };
|
|
11209
|
+
}
|
|
11210
|
+
return { ...common, interactive: false };
|
|
10825
11211
|
});
|
|
10826
11212
|
const pictos = block.pictos.map((picto) => {
|
|
10827
11213
|
const label = toLabel(picto.inlines);
|
|
@@ -10838,21 +11224,62 @@ function transformChart(block, idGenerator, inlineDragIds) {
|
|
|
10838
11224
|
...label !== void 0 && { label }
|
|
10839
11225
|
};
|
|
10840
11226
|
});
|
|
10841
|
-
const
|
|
11227
|
+
const series = block.series.map((s) => {
|
|
11228
|
+
const label = toLabel(s.inlines);
|
|
11229
|
+
return {
|
|
11230
|
+
id: s.id,
|
|
11231
|
+
color: s.color,
|
|
11232
|
+
...label !== void 0 && { label }
|
|
11233
|
+
};
|
|
11234
|
+
});
|
|
11235
|
+
const groups = block.groups.map((group) => {
|
|
11236
|
+
const slots = alignGroupBarsToSeries(group, block.series);
|
|
11237
|
+
const groupBars = slots.map((bar, i) => {
|
|
11238
|
+
if (bar === void 0) return void 0;
|
|
11239
|
+
const series2 = block.series[i];
|
|
11240
|
+
if (bar.answer !== void 0) {
|
|
11241
|
+
chartWidgets[bar.id] = { type: JSON_TYPES.CHART_BAR, value: bar.value };
|
|
11242
|
+
chartAnswers[bar.id] = bar.answer;
|
|
11243
|
+
}
|
|
11244
|
+
return {
|
|
11245
|
+
id: bar.id,
|
|
11246
|
+
type: JSON_TYPES.CHART_SERIES_BAR,
|
|
11247
|
+
value: bar.value,
|
|
11248
|
+
...bar.answer !== void 0 && { answer: bar.answer },
|
|
11249
|
+
color: series2.color,
|
|
11250
|
+
seriesId: series2.id
|
|
11251
|
+
};
|
|
11252
|
+
}).filter((bar) => bar !== void 0);
|
|
11253
|
+
const label = toLabel(group.labelInlines);
|
|
11254
|
+
return {
|
|
11255
|
+
id: group.id,
|
|
11256
|
+
...label !== void 0 && { label },
|
|
11257
|
+
bars: groupBars
|
|
11258
|
+
};
|
|
11259
|
+
});
|
|
11260
|
+
const base = {
|
|
10842
11261
|
id: idGenerator.generate(JSON_TYPES.CHART),
|
|
10843
11262
|
type: JSON_TYPES.CHART,
|
|
10844
11263
|
...block.name !== void 0 && { name: block.name },
|
|
10845
11264
|
...block.title !== void 0 && { title: block.title },
|
|
10846
|
-
chartType: block.chartType,
|
|
10847
11265
|
orientation,
|
|
10848
11266
|
grid: block.grid,
|
|
10849
11267
|
scale: block.scale,
|
|
10850
11268
|
...block.snap !== void 0 && { snap: block.snap },
|
|
10851
11269
|
...xAxis !== void 0 && { xAxis },
|
|
10852
|
-
...yAxis !== void 0 && { yAxis }
|
|
10853
|
-
bars,
|
|
10854
|
-
pictos
|
|
11270
|
+
...yAxis !== void 0 && { yAxis }
|
|
10855
11271
|
};
|
|
11272
|
+
let item;
|
|
11273
|
+
if (block.chartType === "bar") {
|
|
11274
|
+
item = { ...base, chartType: "bar", bars };
|
|
11275
|
+
} else if (block.chartType === "pictograph") {
|
|
11276
|
+
item = { ...base, chartType: "pictograph", pictos };
|
|
11277
|
+
} else if (block.chartType === "grouped-bar") {
|
|
11278
|
+
item = { ...base, chartType: "grouped-bar", series, groups, legend: block.legend };
|
|
11279
|
+
} else {
|
|
11280
|
+
const unhandled = block.chartType;
|
|
11281
|
+
throw new Error(`CHART: unsupported chart type "${String(unhandled)}"`);
|
|
11282
|
+
}
|
|
10856
11283
|
return { item, chartWidgets, chartAnswers };
|
|
10857
11284
|
}
|
|
10858
11285
|
function transformNumberLine(numberLine, idGenerator, inlineDragIds) {
|
|
@@ -17517,12 +17944,17 @@ const GridSymmetry = ({
|
|
|
17517
17944
|
}
|
|
17518
17945
|
) });
|
|
17519
17946
|
};
|
|
17947
|
+
function interactiveBarKey(bar) {
|
|
17948
|
+
if (bar.answer === void 0 && bar.interactive !== true) return void 0;
|
|
17949
|
+
return bar.widgetId ?? bar.id;
|
|
17950
|
+
}
|
|
17520
17951
|
function getChartClassName(item) {
|
|
17521
17952
|
const isHorizontal = item.orientation === "horizontal";
|
|
17522
17953
|
return [
|
|
17523
17954
|
"chart",
|
|
17524
17955
|
isHorizontal ? "chart--horizontal" : "",
|
|
17525
17956
|
item.chartType === "pictograph" ? "chart--pictograph" : "",
|
|
17957
|
+
item.chartType === "grouped-bar" ? "chart--grouped-bar" : "",
|
|
17526
17958
|
item.xAxis?.visible === false ? "chart--no-xaxis" : "",
|
|
17527
17959
|
item.yAxis?.visible === false ? "chart--no-yaxis" : ""
|
|
17528
17960
|
].filter(Boolean).join(" ");
|
|
@@ -17533,7 +17965,8 @@ function resolveItemValue(id, defaultValue2, values) {
|
|
|
17533
17965
|
return isNaN(parsed) ? defaultValue2 : parsed;
|
|
17534
17966
|
}
|
|
17535
17967
|
function resolveValue(bar, values) {
|
|
17536
|
-
|
|
17968
|
+
const widgetKey = interactiveBarKey(bar);
|
|
17969
|
+
return widgetKey !== void 0 ? resolveItemValue(widgetKey, bar.value, values) : bar.value;
|
|
17537
17970
|
}
|
|
17538
17971
|
function clamp(v, min, max) {
|
|
17539
17972
|
return Math.min(max, Math.max(min, v));
|
|
@@ -17592,6 +18025,8 @@ const CHART_METRICS = {
|
|
|
17592
18025
|
gapWidth: 1,
|
|
17593
18026
|
axisWidth: 2.35,
|
|
17594
18027
|
barWidth: 3.35,
|
|
18028
|
+
// Fixed narrow width so several series fit in one cluster; not derived from count.
|
|
18029
|
+
groupedBarWidth: 1.8,
|
|
17595
18030
|
fontSize: 0.9,
|
|
17596
18031
|
labelFontSize: 0.98,
|
|
17597
18032
|
handleSize: 1.15,
|
|
@@ -17644,6 +18079,41 @@ function computePictographChartStyle(scale, columnCount, totalSlots, orientation
|
|
|
17644
18079
|
"--chart-height": slotSpan
|
|
17645
18080
|
};
|
|
17646
18081
|
}
|
|
18082
|
+
function computeGroupedChartStyle(scale, groupCount, seriesCount, orientation = "vertical", isInteractive = false) {
|
|
18083
|
+
const visualScale = clamp(scale, CHART_METRICS.scaleMin, CHART_METRICS.scaleMax);
|
|
18084
|
+
const barWidth = (isInteractive ? CHART_METRICS.barWidth : CHART_METRICS.groupedBarWidth) * visualScale;
|
|
18085
|
+
const barGap = CHART_METRICS.gapWidth * visualScale * 0.5;
|
|
18086
|
+
const groupGap = CHART_METRICS.gapWidth * visualScale * 2;
|
|
18087
|
+
const seriesPerGroup = Math.max(1, seriesCount);
|
|
18088
|
+
const groupWidth = seriesPerGroup * barWidth + Math.max(0, seriesPerGroup - 1) * barGap;
|
|
18089
|
+
const trackLength = groupCount * groupWidth + Math.max(0, groupCount - 1) * groupGap + groupGap * 2;
|
|
18090
|
+
const cssVars = {
|
|
18091
|
+
"--chart-axis-width": `${CHART_METRICS.axisWidth * visualScale}rem`,
|
|
18092
|
+
"--chart-bar-width": `${barWidth}rem`,
|
|
18093
|
+
// A bar slot inside a group is just the bar; reuse the plain bar-chart var.
|
|
18094
|
+
"--chart-bar-slot-width": `${barWidth}rem`,
|
|
18095
|
+
"--chart-bar-gap": `${barGap}rem`,
|
|
18096
|
+
"--chart-group-gap": `${groupGap}rem`,
|
|
18097
|
+
"--chart-group-width": `${groupWidth}rem`,
|
|
18098
|
+
"--chart-font-size": `${CHART_METRICS.fontSize * visualScale}rem`,
|
|
18099
|
+
"--chart-label-font-size": `${CHART_METRICS.labelFontSize * visualScale}rem`,
|
|
18100
|
+
"--chart-handle-size": `${CHART_METRICS.handleSize * visualScale}rem`
|
|
18101
|
+
};
|
|
18102
|
+
if (orientation === "horizontal") {
|
|
18103
|
+
const valueWidth = CHART_METRICS.chartHeight * visualScale;
|
|
18104
|
+
return {
|
|
18105
|
+
...cssVars,
|
|
18106
|
+
"--chart-height": `${trackLength}rem`,
|
|
18107
|
+
"--chart-h-value-width": `${valueWidth}rem`,
|
|
18108
|
+
"--chart-content-width": `${valueWidth}rem`
|
|
18109
|
+
};
|
|
18110
|
+
}
|
|
18111
|
+
return {
|
|
18112
|
+
...cssVars,
|
|
18113
|
+
"--chart-height": `${CHART_METRICS.chartHeight * visualScale}rem`,
|
|
18114
|
+
"--chart-content-width": `${trackLength}rem`
|
|
18115
|
+
};
|
|
18116
|
+
}
|
|
17647
18117
|
function computeHorizontalChartStyle(scale, barCount) {
|
|
17648
18118
|
const { trackLength, visualScale, cssVars } = computeBaseChartVars(scale, barCount);
|
|
17649
18119
|
const valueWidth = CHART_METRICS.chartHeight * visualScale;
|
|
@@ -17695,6 +18165,7 @@ const DraggableBar = ({
|
|
|
17695
18165
|
const axisMax = axis.max ?? CHART_AXIS_DEFAULTS.max;
|
|
17696
18166
|
const axisStep = axis.step ?? CHART_AXIS_DEFAULTS.step;
|
|
17697
18167
|
const snapStep = snap ?? axisStep;
|
|
18168
|
+
const widgetKey = bar.widgetId ?? bar.id;
|
|
17698
18169
|
const fillFromPointer = useCallback(
|
|
17699
18170
|
(clientY, clientX) => {
|
|
17700
18171
|
const track = trackRef.current;
|
|
@@ -17712,10 +18183,10 @@ const DraggableBar = ({
|
|
|
17712
18183
|
if (snapped !== lastSnap.current) {
|
|
17713
18184
|
lastSnap.current = snapped;
|
|
17714
18185
|
playSound("bar-step");
|
|
17715
|
-
onChange(
|
|
18186
|
+
onChange(widgetKey, String(snapped));
|
|
17716
18187
|
}
|
|
17717
18188
|
},
|
|
17718
|
-
[axisMin, axisMax, snapStep,
|
|
18189
|
+
[axisMin, axisMax, snapStep, widgetKey, onChange, orientation, playSound]
|
|
17719
18190
|
);
|
|
17720
18191
|
const onPointerDown = useCallback(
|
|
17721
18192
|
(e) => {
|
|
@@ -17748,8 +18219,8 @@ const DraggableBar = ({
|
|
|
17748
18219
|
if (!dragging.current) return;
|
|
17749
18220
|
dragging.current = false;
|
|
17750
18221
|
setIsDragging(false);
|
|
17751
|
-
onChange(
|
|
17752
|
-
}, [
|
|
18222
|
+
onChange(widgetKey, String(preDragValue.current));
|
|
18223
|
+
}, [widgetKey, onChange]);
|
|
17753
18224
|
const onKeyDown = useCallback(
|
|
17754
18225
|
(e) => {
|
|
17755
18226
|
if (exerciseLocked) return;
|
|
@@ -17758,22 +18229,22 @@ const DraggableBar = ({
|
|
|
17758
18229
|
if (isInc) {
|
|
17759
18230
|
e.preventDefault();
|
|
17760
18231
|
playSound("bar-step");
|
|
17761
|
-
onChange(
|
|
18232
|
+
onChange(widgetKey, String(nextStepValue(currentValue, axis, 1, snap)));
|
|
17762
18233
|
} else if (isDec) {
|
|
17763
18234
|
e.preventDefault();
|
|
17764
18235
|
playSound("bar-step");
|
|
17765
|
-
onChange(
|
|
18236
|
+
onChange(widgetKey, String(nextStepValue(currentValue, axis, -1, snap)));
|
|
17766
18237
|
} else if (e.key === "Home") {
|
|
17767
18238
|
e.preventDefault();
|
|
17768
18239
|
playSound("bar-step");
|
|
17769
|
-
onChange(
|
|
18240
|
+
onChange(widgetKey, String(axisMin));
|
|
17770
18241
|
} else if (e.key === "End") {
|
|
17771
18242
|
e.preventDefault();
|
|
17772
18243
|
playSound("bar-step");
|
|
17773
|
-
onChange(
|
|
18244
|
+
onChange(widgetKey, String(axisMax));
|
|
17774
18245
|
}
|
|
17775
18246
|
},
|
|
17776
|
-
[axisMin, axisMax,
|
|
18247
|
+
[axisMin, axisMax, widgetKey, currentValue, axis, snap, onChange, playSound, exerciseLocked]
|
|
17777
18248
|
);
|
|
17778
18249
|
const fill = toFill(currentValue, axis);
|
|
17779
18250
|
const isAtMin = currentValue <= axisMin;
|
|
@@ -17849,7 +18320,7 @@ const StaticBar = ({
|
|
|
17849
18320
|
}
|
|
17850
18321
|
) });
|
|
17851
18322
|
};
|
|
17852
|
-
const EMPTY_SET$
|
|
18323
|
+
const EMPTY_SET$4 = /* @__PURE__ */ new Set();
|
|
17853
18324
|
const XAxisLabel = ({
|
|
17854
18325
|
bar,
|
|
17855
18326
|
widgets,
|
|
@@ -17864,14 +18335,14 @@ const XAxisLabel = ({
|
|
|
17864
18335
|
item: subItem,
|
|
17865
18336
|
widgets,
|
|
17866
18337
|
values,
|
|
17867
|
-
droppedInputs: EMPTY_SET$
|
|
18338
|
+
droppedInputs: EMPTY_SET$4,
|
|
17868
18339
|
validationDetails,
|
|
17869
18340
|
onChange
|
|
17870
18341
|
},
|
|
17871
18342
|
subItem.id
|
|
17872
18343
|
)) }) });
|
|
17873
18344
|
};
|
|
17874
|
-
const EMPTY_SET$
|
|
18345
|
+
const EMPTY_SET$3 = /* @__PURE__ */ new Set();
|
|
17875
18346
|
const BarChart = ({
|
|
17876
18347
|
item,
|
|
17877
18348
|
widgets,
|
|
@@ -17879,6 +18350,7 @@ const BarChart = ({
|
|
|
17879
18350
|
validationDetails,
|
|
17880
18351
|
onChange
|
|
17881
18352
|
}) => {
|
|
18353
|
+
if (item.chartType !== "bar") return null;
|
|
17882
18354
|
const { bars, grid } = item;
|
|
17883
18355
|
const isHorizontal = item.orientation === "horizontal";
|
|
17884
18356
|
const valueAxis = isHorizontal ? item.xAxis : item.yAxis;
|
|
@@ -17892,7 +18364,7 @@ const BarChart = ({
|
|
|
17892
18364
|
item: subItem,
|
|
17893
18365
|
widgets,
|
|
17894
18366
|
values,
|
|
17895
|
-
droppedInputs: EMPTY_SET$
|
|
18367
|
+
droppedInputs: EMPTY_SET$3,
|
|
17896
18368
|
validationDetails,
|
|
17897
18369
|
onChange
|
|
17898
18370
|
},
|
|
@@ -17902,9 +18374,10 @@ const BarChart = ({
|
|
|
17902
18374
|
const fillAxis = valueAxis ?? CHART_AXIS_DEFAULTS;
|
|
17903
18375
|
const renderBar = (bar, orient = "vertical") => {
|
|
17904
18376
|
const currentValue = resolveValue(bar, values);
|
|
17905
|
-
const
|
|
18377
|
+
const widgetKey = interactiveBarKey(bar);
|
|
18378
|
+
const vStatus = widgetKey !== void 0 ? validationDetails?.[widgetKey] : void 0;
|
|
17906
18379
|
const validationStatus = vStatus?.isCorrect === true ? "correct" : vStatus?.isCorrect === false ? "incorrect" : null;
|
|
17907
|
-
return /* @__PURE__ */ jsx("div", { className: "chart-bar-wrapper", children:
|
|
18380
|
+
return /* @__PURE__ */ jsx("div", { className: "chart-bar-wrapper", children: widgetKey !== void 0 ? /* @__PURE__ */ jsx(
|
|
17908
18381
|
DraggableBar,
|
|
17909
18382
|
{
|
|
17910
18383
|
bar,
|
|
@@ -17937,7 +18410,7 @@ const BarChart = ({
|
|
|
17937
18410
|
item: subItem,
|
|
17938
18411
|
widgets,
|
|
17939
18412
|
values,
|
|
17940
|
-
droppedInputs: EMPTY_SET$
|
|
18413
|
+
droppedInputs: EMPTY_SET$3,
|
|
17941
18414
|
validationDetails,
|
|
17942
18415
|
onChange
|
|
17943
18416
|
},
|
|
@@ -18142,7 +18615,7 @@ const PictographGrid = ({
|
|
|
18142
18615
|
))
|
|
18143
18616
|
] });
|
|
18144
18617
|
};
|
|
18145
|
-
const EMPTY_SET = /* @__PURE__ */ new Set();
|
|
18618
|
+
const EMPTY_SET$2 = /* @__PURE__ */ new Set();
|
|
18146
18619
|
const PictographChart = ({
|
|
18147
18620
|
item,
|
|
18148
18621
|
widgets,
|
|
@@ -18150,7 +18623,8 @@ const PictographChart = ({
|
|
|
18150
18623
|
validationDetails,
|
|
18151
18624
|
onChange
|
|
18152
18625
|
}) => {
|
|
18153
|
-
|
|
18626
|
+
if (item.chartType !== "pictograph") return null;
|
|
18627
|
+
const { pictos, grid } = item;
|
|
18154
18628
|
const isHorizontal = item.orientation === "horizontal";
|
|
18155
18629
|
const valueAxis = isHorizontal ? item.xAxis : item.yAxis;
|
|
18156
18630
|
const categoryAxis = isHorizontal ? item.yAxis : item.xAxis;
|
|
@@ -18163,7 +18637,7 @@ const PictographChart = ({
|
|
|
18163
18637
|
item: subItem,
|
|
18164
18638
|
widgets,
|
|
18165
18639
|
values,
|
|
18166
|
-
droppedInputs: EMPTY_SET,
|
|
18640
|
+
droppedInputs: EMPTY_SET$2,
|
|
18167
18641
|
validationDetails,
|
|
18168
18642
|
onChange
|
|
18169
18643
|
},
|
|
@@ -18201,7 +18675,7 @@ const PictographChart = ({
|
|
|
18201
18675
|
item: subItem,
|
|
18202
18676
|
widgets,
|
|
18203
18677
|
values,
|
|
18204
|
-
droppedInputs: EMPTY_SET,
|
|
18678
|
+
droppedInputs: EMPTY_SET$2,
|
|
18205
18679
|
validationDetails,
|
|
18206
18680
|
onChange
|
|
18207
18681
|
},
|
|
@@ -18222,7 +18696,7 @@ const PictographChart = ({
|
|
|
18222
18696
|
item: subItem,
|
|
18223
18697
|
widgets,
|
|
18224
18698
|
values,
|
|
18225
|
-
droppedInputs: EMPTY_SET,
|
|
18699
|
+
droppedInputs: EMPTY_SET$2,
|
|
18226
18700
|
validationDetails,
|
|
18227
18701
|
onChange
|
|
18228
18702
|
},
|
|
@@ -18241,9 +18715,183 @@ const PictographChart = ({
|
|
|
18241
18715
|
xAxisTitle
|
|
18242
18716
|
] }) }) });
|
|
18243
18717
|
};
|
|
18718
|
+
const GroupSlot = ({
|
|
18719
|
+
group,
|
|
18720
|
+
series,
|
|
18721
|
+
axis,
|
|
18722
|
+
snap,
|
|
18723
|
+
orientation = "vertical",
|
|
18724
|
+
values,
|
|
18725
|
+
validationDetails,
|
|
18726
|
+
onChange
|
|
18727
|
+
}) => {
|
|
18728
|
+
return /* @__PURE__ */ jsx("div", { className: "chart-group", children: series.map((s) => {
|
|
18729
|
+
const bar = group.bars.find((b) => b.seriesId === s.id);
|
|
18730
|
+
if (!bar) {
|
|
18731
|
+
return /* @__PURE__ */ jsx("div", { className: "chart-group-bar-gap", "aria-hidden": "true" }, s.id);
|
|
18732
|
+
}
|
|
18733
|
+
const currentValue = resolveValue(bar, values);
|
|
18734
|
+
const vStatus = bar.answer !== void 0 ? validationDetails?.[bar.id] : void 0;
|
|
18735
|
+
const validationStatus = vStatus?.isCorrect === true ? "correct" : vStatus?.isCorrect === false ? "incorrect" : null;
|
|
18736
|
+
return /* @__PURE__ */ jsx("div", { className: "chart-bar-wrapper", children: bar.answer !== void 0 ? /* @__PURE__ */ jsx(
|
|
18737
|
+
DraggableBar,
|
|
18738
|
+
{
|
|
18739
|
+
bar: { ...bar, answer: bar.answer },
|
|
18740
|
+
currentValue,
|
|
18741
|
+
axis,
|
|
18742
|
+
snap,
|
|
18743
|
+
validationStatus,
|
|
18744
|
+
orientation,
|
|
18745
|
+
onChange
|
|
18746
|
+
}
|
|
18747
|
+
) : /* @__PURE__ */ jsx(
|
|
18748
|
+
StaticBar,
|
|
18749
|
+
{
|
|
18750
|
+
bar,
|
|
18751
|
+
currentValue,
|
|
18752
|
+
axis,
|
|
18753
|
+
validationStatus,
|
|
18754
|
+
orientation
|
|
18755
|
+
}
|
|
18756
|
+
) }, bar.id);
|
|
18757
|
+
}) });
|
|
18758
|
+
};
|
|
18759
|
+
const EMPTY_SET$1 = /* @__PURE__ */ new Set();
|
|
18760
|
+
const ChartLegend = ({
|
|
18761
|
+
series,
|
|
18762
|
+
widgets,
|
|
18763
|
+
values,
|
|
18764
|
+
validationDetails,
|
|
18765
|
+
onChange
|
|
18766
|
+
}) => {
|
|
18767
|
+
return /* @__PURE__ */ jsx("div", { className: "chart-legend", children: series.map((s) => /* @__PURE__ */ jsxs("div", { className: "chart-legend-item", children: [
|
|
18768
|
+
/* @__PURE__ */ jsx("span", { className: "chart-legend-swatch", "aria-hidden": "true", style: { backgroundColor: s.color } }),
|
|
18769
|
+
/* @__PURE__ */ jsx("span", { className: "chart-legend-label", children: s.label?.map((subItem) => /* @__PURE__ */ jsx(
|
|
18770
|
+
LayoutRenderer,
|
|
18771
|
+
{
|
|
18772
|
+
item: subItem,
|
|
18773
|
+
widgets,
|
|
18774
|
+
values,
|
|
18775
|
+
droppedInputs: EMPTY_SET$1,
|
|
18776
|
+
validationDetails,
|
|
18777
|
+
onChange
|
|
18778
|
+
},
|
|
18779
|
+
subItem.id
|
|
18780
|
+
)) })
|
|
18781
|
+
] }, s.id)) });
|
|
18782
|
+
};
|
|
18783
|
+
const EMPTY_SET = /* @__PURE__ */ new Set();
|
|
18784
|
+
const GroupedBarChart = ({
|
|
18785
|
+
item,
|
|
18786
|
+
widgets,
|
|
18787
|
+
values,
|
|
18788
|
+
validationDetails,
|
|
18789
|
+
onChange
|
|
18790
|
+
}) => {
|
|
18791
|
+
if (item.chartType !== "grouped-bar") return null;
|
|
18792
|
+
const { groups, series, grid } = item;
|
|
18793
|
+
const isHorizontal = item.orientation === "horizontal";
|
|
18794
|
+
const isInteractive = groups.some((g) => g.bars.some((bar) => bar.answer !== void 0));
|
|
18795
|
+
const valueAxis = isHorizontal ? item.xAxis : item.yAxis;
|
|
18796
|
+
const categoryAxis = isHorizontal ? item.yAxis : item.xAxis;
|
|
18797
|
+
const chartClass = getChartClassName(item);
|
|
18798
|
+
const fillAxis = valueAxis ?? CHART_AXIS_DEFAULTS;
|
|
18799
|
+
const renderAxisTitle = (title) => {
|
|
18800
|
+
if (!title?.length) return null;
|
|
18801
|
+
return /* @__PURE__ */ jsx(Fragment, { children: title.map((subItem) => /* @__PURE__ */ jsx(
|
|
18802
|
+
LayoutRenderer,
|
|
18803
|
+
{
|
|
18804
|
+
item: subItem,
|
|
18805
|
+
widgets,
|
|
18806
|
+
values,
|
|
18807
|
+
droppedInputs: EMPTY_SET,
|
|
18808
|
+
validationDetails,
|
|
18809
|
+
onChange
|
|
18810
|
+
},
|
|
18811
|
+
subItem.id
|
|
18812
|
+
)) });
|
|
18813
|
+
};
|
|
18814
|
+
const renderGroupSlots = (orient) => /* @__PURE__ */ jsx("div", { className: "chart-groups", children: groups.map((group) => /* @__PURE__ */ jsx(
|
|
18815
|
+
GroupSlot,
|
|
18816
|
+
{
|
|
18817
|
+
group,
|
|
18818
|
+
series,
|
|
18819
|
+
axis: fillAxis,
|
|
18820
|
+
snap: item.snap,
|
|
18821
|
+
orientation: orient,
|
|
18822
|
+
values,
|
|
18823
|
+
validationDetails,
|
|
18824
|
+
onChange
|
|
18825
|
+
},
|
|
18826
|
+
group.id
|
|
18827
|
+
)) });
|
|
18828
|
+
const legend = item.legend ? /* @__PURE__ */ jsx(
|
|
18829
|
+
ChartLegend,
|
|
18830
|
+
{
|
|
18831
|
+
series,
|
|
18832
|
+
widgets,
|
|
18833
|
+
values,
|
|
18834
|
+
validationDetails,
|
|
18835
|
+
onChange
|
|
18836
|
+
}
|
|
18837
|
+
) : null;
|
|
18838
|
+
if (isHorizontal) {
|
|
18839
|
+
const chartStyle2 = computeGroupedChartStyle(item.scale, groups.length, series.length, "horizontal", isInteractive);
|
|
18840
|
+
return /* @__PURE__ */ jsx("div", { className: "chart-container", children: /* @__PURE__ */ jsx("div", { className: "chart-scroll", children: /* @__PURE__ */ jsxs("div", { className: chartClass, dir: "ltr", style: chartStyle2, children: [
|
|
18841
|
+
item.title && /* @__PURE__ */ jsx("div", { className: "chart-title", children: item.title }),
|
|
18842
|
+
categoryAxis?.visible && categoryAxis.title?.length ? /* @__PURE__ */ jsx("div", { className: "chart-axis-title chart-axis-title--y-h", children: renderAxisTitle(categoryAxis.title) }) : null,
|
|
18843
|
+
/* @__PURE__ */ jsx("div", { className: "chart-axis-y--categories", children: groups.map((group) => /* @__PURE__ */ jsx("div", { className: "chart-bar-y-label", children: group.label?.map((subItem) => /* @__PURE__ */ jsx(
|
|
18844
|
+
LayoutRenderer,
|
|
18845
|
+
{
|
|
18846
|
+
item: subItem,
|
|
18847
|
+
widgets,
|
|
18848
|
+
values,
|
|
18849
|
+
droppedInputs: EMPTY_SET,
|
|
18850
|
+
validationDetails,
|
|
18851
|
+
onChange
|
|
18852
|
+
},
|
|
18853
|
+
subItem.id
|
|
18854
|
+
)) }, group.id)) }),
|
|
18855
|
+
/* @__PURE__ */ jsxs("div", { className: "chart-plot", children: [
|
|
18856
|
+
grid && /* @__PURE__ */ jsx(Grid, { axis: fillAxis, orientation: "horizontal" }),
|
|
18857
|
+
renderGroupSlots("horizontal")
|
|
18858
|
+
] }),
|
|
18859
|
+
valueAxis && valueAxis.visible && /* @__PURE__ */ jsx(XAxis, { axis: valueAxis, title: renderAxisTitle(valueAxis.title) }),
|
|
18860
|
+
legend
|
|
18861
|
+
] }) }) });
|
|
18862
|
+
}
|
|
18863
|
+
const chartStyle = computeGroupedChartStyle(item.scale, groups.length, series.length, "vertical", isInteractive);
|
|
18864
|
+
const hasAnyGroupLabel = groups.some((g) => g.label && g.label.length > 0);
|
|
18865
|
+
const groupLabelRow = hasAnyGroupLabel ? /* @__PURE__ */ jsx("div", { className: "chart-axis-x", children: groups.map((group) => /* @__PURE__ */ jsx("div", { className: "chart-axis-tick-x", children: /* @__PURE__ */ jsx("div", { className: "chart-axis-tick-x-inner", children: group.label?.map((subItem) => /* @__PURE__ */ jsx(
|
|
18866
|
+
LayoutRenderer,
|
|
18867
|
+
{
|
|
18868
|
+
item: subItem,
|
|
18869
|
+
widgets,
|
|
18870
|
+
values,
|
|
18871
|
+
droppedInputs: EMPTY_SET,
|
|
18872
|
+
validationDetails,
|
|
18873
|
+
onChange
|
|
18874
|
+
},
|
|
18875
|
+
subItem.id
|
|
18876
|
+
)) }) }, group.id)) }) : null;
|
|
18877
|
+
const xAxisTitle = categoryAxis?.visible && categoryAxis.title?.length ? /* @__PURE__ */ jsx("div", { className: "chart-axis-title chart-axis-title--x-category", children: renderAxisTitle(categoryAxis.title) }) : null;
|
|
18878
|
+
return /* @__PURE__ */ jsx("div", { className: "chart-container", children: /* @__PURE__ */ jsx("div", { className: "chart-scroll", children: /* @__PURE__ */ jsxs("div", { className: chartClass, dir: "ltr", style: chartStyle, children: [
|
|
18879
|
+
item.title && /* @__PURE__ */ jsx("div", { className: "chart-title", children: item.title }),
|
|
18880
|
+
valueAxis?.visible && valueAxis.title?.length ? /* @__PURE__ */ jsx("div", { className: "chart-axis-title chart-axis-title--y", children: renderAxisTitle(valueAxis.title) }) : null,
|
|
18881
|
+
valueAxis && valueAxis.visible && /* @__PURE__ */ jsx(YAxis, { axis: valueAxis }),
|
|
18882
|
+
/* @__PURE__ */ jsxs("div", { className: "chart-plot", children: [
|
|
18883
|
+
grid && /* @__PURE__ */ jsx(Grid, { axis: fillAxis }),
|
|
18884
|
+
renderGroupSlots("vertical")
|
|
18885
|
+
] }),
|
|
18886
|
+
groupLabelRow,
|
|
18887
|
+
xAxisTitle,
|
|
18888
|
+
legend
|
|
18889
|
+
] }) }) });
|
|
18890
|
+
};
|
|
18244
18891
|
const CHART_TYPE_COMPONENTS = {
|
|
18245
18892
|
bar: BarChart,
|
|
18246
|
-
pictograph: PictographChart
|
|
18893
|
+
pictograph: PictographChart,
|
|
18894
|
+
"grouped-bar": GroupedBarChart
|
|
18247
18895
|
// line: LineChart,
|
|
18248
18896
|
// pie: PieChart,
|
|
18249
18897
|
};
|
|
@@ -18926,7 +19574,7 @@ function isGeometryWidget(widget) {
|
|
|
18926
19574
|
return widget.type === JSON_TYPES.GEOMETRY;
|
|
18927
19575
|
}
|
|
18928
19576
|
const GeometryWidget = React.lazy(async () => ({
|
|
18929
|
-
default: (await import("./GeometryWidget-
|
|
19577
|
+
default: (await import("./GeometryWidget-gtAP_-_S.mjs")).GeometryWidget
|
|
18930
19578
|
}));
|
|
18931
19579
|
const WidgetRenderer = ({
|
|
18932
19580
|
widget,
|
|
@@ -21728,7 +22376,7 @@ export {
|
|
|
21728
22376
|
isTableRowItem as Z,
|
|
21729
22377
|
isTableCellItem as _,
|
|
21730
22378
|
compileWithAST as a,
|
|
21731
|
-
|
|
22379
|
+
validateExerciseJSONSafe as a$,
|
|
21732
22380
|
isVerticalOperationItem as a0,
|
|
21733
22381
|
isClockItem as a1,
|
|
21734
22382
|
isRulerWidget as a2,
|
|
@@ -21747,25 +22395,25 @@ export {
|
|
|
21747
22395
|
ChartAxisJSONSchema as aF,
|
|
21748
22396
|
ChartBarJSONSchema as aG,
|
|
21749
22397
|
ChartPictoJSONSchema as aH,
|
|
21750
|
-
|
|
21751
|
-
|
|
21752
|
-
|
|
21753
|
-
|
|
21754
|
-
|
|
21755
|
-
|
|
21756
|
-
|
|
21757
|
-
|
|
21758
|
-
|
|
21759
|
-
|
|
21760
|
-
|
|
21761
|
-
|
|
21762
|
-
|
|
21763
|
-
|
|
21764
|
-
|
|
21765
|
-
|
|
21766
|
-
|
|
21767
|
-
|
|
21768
|
-
|
|
22398
|
+
ChartSeriesJSONSchema as aI,
|
|
22399
|
+
ChartSeriesBarJSONSchema as aJ,
|
|
22400
|
+
ChartGroupJSONSchema as aK,
|
|
22401
|
+
WidgetJSONSchema as aL,
|
|
22402
|
+
InlineInputJSONSchema as aM,
|
|
22403
|
+
DragOptionsJSONSchema as aN,
|
|
22404
|
+
RadioOptionsJSONSchema as aO,
|
|
22405
|
+
NumericKeypadJSONSchema as aP,
|
|
22406
|
+
FractionJSONSchema as aQ,
|
|
22407
|
+
MatcherWidgetJSONSchema as aR,
|
|
22408
|
+
PairMatcherWidgetJSONSchema as aS,
|
|
22409
|
+
GridSymmetryJSONSchema as aT,
|
|
22410
|
+
ChartBarWidgetJSONSchema as aU,
|
|
22411
|
+
ChartPictoWidgetJSONSchema as aV,
|
|
22412
|
+
RulerWidgetSchema as aW,
|
|
22413
|
+
ProtractorWidgetSchema as aX,
|
|
22414
|
+
SetSquareWidgetSchema as aY,
|
|
22415
|
+
GeometryJSONSchema as aZ,
|
|
22416
|
+
validateExerciseJSON as a_,
|
|
21769
22417
|
QuestionTextSchema as aa,
|
|
21770
22418
|
TextItemSchema as ab,
|
|
21771
22419
|
WidgetRefSchema as ac,
|
|
@@ -21793,178 +22441,192 @@ export {
|
|
|
21793
22441
|
VopSeparatorItemSchema as ay,
|
|
21794
22442
|
VopCellItemSchema as az,
|
|
21795
22443
|
tokenizeSafe as b,
|
|
21796
|
-
|
|
21797
|
-
|
|
21798
|
-
|
|
21799
|
-
|
|
21800
|
-
|
|
21801
|
-
|
|
21802
|
-
|
|
21803
|
-
|
|
21804
|
-
|
|
21805
|
-
|
|
21806
|
-
|
|
21807
|
-
|
|
21808
|
-
|
|
21809
|
-
|
|
21810
|
-
|
|
21811
|
-
|
|
21812
|
-
|
|
21813
|
-
|
|
21814
|
-
|
|
21815
|
-
|
|
21816
|
-
|
|
21817
|
-
|
|
21818
|
-
|
|
21819
|
-
|
|
21820
|
-
|
|
21821
|
-
|
|
21822
|
-
|
|
21823
|
-
|
|
21824
|
-
|
|
21825
|
-
|
|
21826
|
-
|
|
21827
|
-
|
|
21828
|
-
|
|
21829
|
-
|
|
21830
|
-
|
|
21831
|
-
|
|
21832
|
-
|
|
21833
|
-
|
|
21834
|
-
|
|
21835
|
-
|
|
21836
|
-
|
|
21837
|
-
|
|
21838
|
-
|
|
21839
|
-
|
|
21840
|
-
|
|
21841
|
-
|
|
21842
|
-
|
|
21843
|
-
|
|
21844
|
-
|
|
21845
|
-
|
|
21846
|
-
|
|
21847
|
-
|
|
21848
|
-
|
|
21849
|
-
|
|
21850
|
-
|
|
21851
|
-
|
|
21852
|
-
|
|
21853
|
-
|
|
21854
|
-
|
|
21855
|
-
|
|
21856
|
-
|
|
21857
|
-
|
|
21858
|
-
|
|
21859
|
-
|
|
22444
|
+
isTextBlock as b$,
|
|
22445
|
+
validateWidgetJSON as b0,
|
|
22446
|
+
validateWidgetJSONSafe as b1,
|
|
22447
|
+
EngineError as b2,
|
|
22448
|
+
LexerError as b3,
|
|
22449
|
+
ParseError as b4,
|
|
22450
|
+
TransformError as b5,
|
|
22451
|
+
ValidationError as b6,
|
|
22452
|
+
ExerciseRenderer as b7,
|
|
22453
|
+
LayoutRenderer as b8,
|
|
22454
|
+
WidgetRenderer as b9,
|
|
22455
|
+
InlineNodeSchema as bA,
|
|
22456
|
+
createFreeText as bB,
|
|
22457
|
+
createSpace as bC,
|
|
22458
|
+
createHighlightedText as bD,
|
|
22459
|
+
createColorText as bE,
|
|
22460
|
+
createBoldText as bF,
|
|
22461
|
+
createStringInput as bG,
|
|
22462
|
+
createNumericInput as bH,
|
|
22463
|
+
createImage as bI,
|
|
22464
|
+
createFraction as bJ,
|
|
22465
|
+
createVisualFraction as bK,
|
|
22466
|
+
createInlineDragOption as bL,
|
|
22467
|
+
createDisplayClock as bM,
|
|
22468
|
+
createInteractiveClock as bN,
|
|
22469
|
+
isFreeText as bO,
|
|
22470
|
+
isSpace as bP,
|
|
22471
|
+
isInlineInput as bQ,
|
|
22472
|
+
isFraction as bR,
|
|
22473
|
+
isImage as bS,
|
|
22474
|
+
isClock as bT,
|
|
22475
|
+
isInlineNode as bU,
|
|
22476
|
+
isVisualFractionInline as bV,
|
|
22477
|
+
isInlineDragOption as bW,
|
|
22478
|
+
TextBlockSchema as bX,
|
|
22479
|
+
LineBlockSchema as bY,
|
|
22480
|
+
createTextBlock as bZ,
|
|
22481
|
+
createLineBlock as b_,
|
|
22482
|
+
renderExercise as ba,
|
|
22483
|
+
SoundProvider as bb,
|
|
22484
|
+
useSound as bc,
|
|
22485
|
+
ExerciseLockProvider as bd,
|
|
22486
|
+
isPairMatcherWidget as be,
|
|
22487
|
+
isMatcherWidget as bf,
|
|
22488
|
+
VISUAL_FRACTION_SHAPES as bg,
|
|
22489
|
+
VISUAL_FRACTION_SHAPE as bh,
|
|
22490
|
+
VISUAL_FRACTION_DEFAULT_SIZE as bi,
|
|
22491
|
+
VISUAL_FRACTION_MAX_DIVISIONS as bj,
|
|
22492
|
+
FreeTextInlineSchema as bk,
|
|
22493
|
+
SpaceInlineSchema as bl,
|
|
22494
|
+
HighlightedTextInlineSchema as bm,
|
|
22495
|
+
ColorTextInlineSchema as bn,
|
|
22496
|
+
BoldTextInlineSchema as bo,
|
|
22497
|
+
InlineInputWidgetSchema as bp,
|
|
22498
|
+
FractionInlineSchema as bq,
|
|
22499
|
+
ImageInlineSchema as br,
|
|
22500
|
+
VisualFractionInlineSchema as bs,
|
|
22501
|
+
validateVisualFractionCapacity as bt,
|
|
22502
|
+
InlineDragOptionSchema as bu,
|
|
22503
|
+
CLOCK_TYPES as bv,
|
|
22504
|
+
CLOCK_MODES as bw,
|
|
22505
|
+
CLOCK_FORMATS as bx,
|
|
22506
|
+
CLOCK_TIME_REGEX as by,
|
|
22507
|
+
ClockInlineSchema as bz,
|
|
21860
22508
|
compile as c,
|
|
21861
|
-
|
|
21862
|
-
|
|
21863
|
-
|
|
21864
|
-
|
|
21865
|
-
|
|
21866
|
-
|
|
21867
|
-
|
|
21868
|
-
|
|
21869
|
-
|
|
21870
|
-
|
|
21871
|
-
|
|
21872
|
-
|
|
21873
|
-
|
|
21874
|
-
|
|
21875
|
-
|
|
21876
|
-
|
|
21877
|
-
|
|
21878
|
-
|
|
21879
|
-
|
|
21880
|
-
|
|
21881
|
-
|
|
21882
|
-
|
|
21883
|
-
|
|
21884
|
-
|
|
21885
|
-
|
|
21886
|
-
|
|
21887
|
-
|
|
21888
|
-
|
|
21889
|
-
|
|
21890
|
-
|
|
21891
|
-
|
|
21892
|
-
|
|
21893
|
-
|
|
21894
|
-
|
|
21895
|
-
|
|
21896
|
-
|
|
21897
|
-
|
|
21898
|
-
|
|
21899
|
-
|
|
21900
|
-
|
|
21901
|
-
|
|
21902
|
-
|
|
21903
|
-
|
|
21904
|
-
|
|
21905
|
-
|
|
21906
|
-
|
|
21907
|
-
|
|
21908
|
-
|
|
21909
|
-
|
|
21910
|
-
|
|
21911
|
-
|
|
21912
|
-
|
|
21913
|
-
|
|
21914
|
-
|
|
21915
|
-
|
|
21916
|
-
|
|
21917
|
-
|
|
21918
|
-
|
|
21919
|
-
|
|
21920
|
-
|
|
21921
|
-
|
|
21922
|
-
|
|
21923
|
-
|
|
21924
|
-
|
|
22509
|
+
VopRowSchema as c$,
|
|
22510
|
+
isLineBlock as c0,
|
|
22511
|
+
DisplayInlineNodeSchema as c1,
|
|
22512
|
+
MatcherItemSchema as c2,
|
|
22513
|
+
createMatcherItem as c3,
|
|
22514
|
+
isMatcherItem as c4,
|
|
22515
|
+
MatcherRowSchema as c5,
|
|
22516
|
+
createMatcherRow as c6,
|
|
22517
|
+
isMatcherRow as c7,
|
|
22518
|
+
MatcherBlockSchema as c8,
|
|
22519
|
+
createMatcherBlock as c9,
|
|
22520
|
+
createExpressionValidation as cA,
|
|
22521
|
+
createMixedValidation as cB,
|
|
22522
|
+
isSimpleValidation as cC,
|
|
22523
|
+
isExpressionValidation as cD,
|
|
22524
|
+
isMixedValidation as cE,
|
|
22525
|
+
isValidationNode as cF,
|
|
22526
|
+
ContentBlockSchema as cG,
|
|
22527
|
+
ExerciseDocumentSchema as cH,
|
|
22528
|
+
createExerciseDocument as cI,
|
|
22529
|
+
isExerciseDocument as cJ,
|
|
22530
|
+
VOP_OPERATORS as cK,
|
|
22531
|
+
normalizeVopOperator as cL,
|
|
22532
|
+
VopDigitCellSchema as cM,
|
|
22533
|
+
VopLabelCellSchema as cN,
|
|
22534
|
+
VopInputCellSchema as cO,
|
|
22535
|
+
VopEmptyCellSchema as cP,
|
|
22536
|
+
VopColorCellSchema as cQ,
|
|
22537
|
+
VopBoldCellSchema as cR,
|
|
22538
|
+
VopHighlightCellSchema as cS,
|
|
22539
|
+
VopCellSchema as cT,
|
|
22540
|
+
createVopDigitCell as cU,
|
|
22541
|
+
createVopInputCell as cV,
|
|
22542
|
+
createVopLabelCell as cW,
|
|
22543
|
+
createVopEmptyCell as cX,
|
|
22544
|
+
createVopColorCell as cY,
|
|
22545
|
+
createVopBoldCell as cZ,
|
|
22546
|
+
createVopHighlightCell as c_,
|
|
22547
|
+
isMatcherBlock as ca,
|
|
22548
|
+
PairMatcherBlockSchema as cb,
|
|
22549
|
+
createPairMatcherBlock as cc,
|
|
22550
|
+
isPairMatcherBlock as cd,
|
|
22551
|
+
DragOptionsToolSchema as ce,
|
|
22552
|
+
NumericKeypadToolSchema as cf,
|
|
22553
|
+
RulerToolSchema as cg,
|
|
22554
|
+
ProtractorToolSchema as ch,
|
|
22555
|
+
SetSquareToolSchema as ci,
|
|
22556
|
+
ToolNodeSchema as cj,
|
|
22557
|
+
createDragOptions as ck,
|
|
22558
|
+
createNumericKeypad as cl,
|
|
22559
|
+
createRulerTool as cm,
|
|
22560
|
+
createProtractorTool as cn,
|
|
22561
|
+
createSetSquareTool as co,
|
|
22562
|
+
isDragOptions as cp,
|
|
22563
|
+
isNumericKeypad as cq,
|
|
22564
|
+
isRulerTool as cr,
|
|
22565
|
+
isProtractorTool as cs,
|
|
22566
|
+
isSetSquareTool as ct,
|
|
22567
|
+
isToolNode as cu,
|
|
22568
|
+
SimpleValidationSchema as cv,
|
|
22569
|
+
ExpressionValidationSchema as cw,
|
|
22570
|
+
MixedValidationSchema as cx,
|
|
22571
|
+
ValidationNodeSchema as cy,
|
|
22572
|
+
createSimpleValidation as cz,
|
|
21925
22573
|
parse as d,
|
|
21926
|
-
|
|
21927
|
-
|
|
21928
|
-
|
|
21929
|
-
|
|
21930
|
-
|
|
21931
|
-
|
|
21932
|
-
|
|
21933
|
-
|
|
21934
|
-
|
|
21935
|
-
|
|
21936
|
-
|
|
21937
|
-
|
|
21938
|
-
|
|
21939
|
-
|
|
21940
|
-
|
|
21941
|
-
|
|
21942
|
-
|
|
21943
|
-
|
|
21944
|
-
|
|
21945
|
-
|
|
21946
|
-
|
|
21947
|
-
|
|
21948
|
-
|
|
21949
|
-
|
|
21950
|
-
|
|
21951
|
-
|
|
21952
|
-
|
|
21953
|
-
|
|
21954
|
-
|
|
21955
|
-
|
|
21956
|
-
|
|
21957
|
-
|
|
21958
|
-
|
|
21959
|
-
|
|
21960
|
-
|
|
21961
|
-
|
|
21962
|
-
|
|
21963
|
-
|
|
21964
|
-
|
|
21965
|
-
|
|
21966
|
-
|
|
21967
|
-
|
|
22574
|
+
createVopRow as d0,
|
|
22575
|
+
VopCarryRowSchema as d1,
|
|
22576
|
+
createVopCarryRow as d2,
|
|
22577
|
+
VopSeparatorSchema as d3,
|
|
22578
|
+
createVopSeparator as d4,
|
|
22579
|
+
VerticalOperationBlockSchema as d5,
|
|
22580
|
+
createVerticalOperationBlock as d6,
|
|
22581
|
+
isVopCell as d7,
|
|
22582
|
+
isVopRow as d8,
|
|
22583
|
+
isVopCarryRow as d9,
|
|
22584
|
+
ChartBarSchema as dA,
|
|
22585
|
+
createChartBar as dB,
|
|
22586
|
+
isChartBar as dC,
|
|
22587
|
+
ChartSeriesSchema as dD,
|
|
22588
|
+
createChartSeries as dE,
|
|
22589
|
+
isChartSeries as dF,
|
|
22590
|
+
ChartSeriesBarSchema as dG,
|
|
22591
|
+
createChartSeriesBar as dH,
|
|
22592
|
+
isChartSeriesBar as dI,
|
|
22593
|
+
ChartGroupSchema as dJ,
|
|
22594
|
+
createChartGroup as dK,
|
|
22595
|
+
isChartGroup as dL,
|
|
22596
|
+
alignGroupBarsToSeries as dM,
|
|
22597
|
+
ChartBlockSchema as dN,
|
|
22598
|
+
resolveChartAxes as dO,
|
|
22599
|
+
validateUniqueIds as dP,
|
|
22600
|
+
createChartBlock as dQ,
|
|
22601
|
+
isChartBlock as dR,
|
|
22602
|
+
GeometryBlockSchema as dS,
|
|
22603
|
+
createGeometryBlock as dT,
|
|
22604
|
+
isGeometryBlock as dU,
|
|
22605
|
+
isVopSeparator as da,
|
|
22606
|
+
isVerticalOperationBlock as db,
|
|
22607
|
+
GRID_SYMMETRY_AXES as dc,
|
|
22608
|
+
GRID_SYMMETRY_INTERACTIVE_AREAS as dd,
|
|
22609
|
+
GRID_SYMMETRY_MAX_ROWS as de,
|
|
22610
|
+
GRID_SYMMETRY_MAX_COLS as df,
|
|
22611
|
+
GRID_SYMMETRY_MIN_CELL_SIZE as dg,
|
|
22612
|
+
GRID_SYMMETRY_MAX_CELL_SIZE as dh,
|
|
22613
|
+
isCellInInteractiveArea as di,
|
|
22614
|
+
reflectGridSymmetryCell as dj,
|
|
22615
|
+
computeGridSymmetryExpectedCells as dk,
|
|
22616
|
+
computeGridSymmetryCellsToFill as dl,
|
|
22617
|
+
GridSymmetryBlockSchema as dm,
|
|
22618
|
+
createGridSymmetryBlock as dn,
|
|
22619
|
+
isGridSymmetryBlock as dp,
|
|
22620
|
+
CHART_TYPES as dq,
|
|
22621
|
+
CHART_AXIS_DEFAULTS as dr,
|
|
22622
|
+
CHART_MAX_AXIS_TICKS as ds,
|
|
22623
|
+
CHART_MAX_PICTO_SLOTS as dt,
|
|
22624
|
+
ChartAxisSchema as du,
|
|
22625
|
+
createChartAxis as dv,
|
|
22626
|
+
isChartAxis as dw,
|
|
22627
|
+
ChartPictoSchema as dx,
|
|
22628
|
+
createChartPicto as dy,
|
|
22629
|
+
isChartPicto as dz,
|
|
21968
22630
|
parseSafe as e,
|
|
21969
22631
|
toAST as f,
|
|
21970
22632
|
getFractionKey as g,
|
|
@@ -21988,4 +22650,4 @@ export {
|
|
|
21988
22650
|
extractVariables as y,
|
|
21989
22651
|
validateBooleanExpression as z
|
|
21990
22652
|
};
|
|
21991
|
-
//# sourceMappingURL=index-
|
|
22653
|
+
//# sourceMappingURL=index-DBteHZkS.mjs.map
|