math-exercises 3.0.163 → 3.0.164
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/lib/exercises/math/functions/trinoms/roots/index.d.ts +1 -0
- package/lib/exercises/math/functions/trinoms/roots/index.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/roots/index.js +1 -0
- package/lib/exercises/math/functions/trinoms/roots/rootsFromFactorizedForm.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/roots/rootsFromFactorizedForm.js +42 -9
- package/lib/exercises/math/functions/trinoms/roots/trinomAlgebraicFormFromRootsAndPoint.d.ts +13 -0
- package/lib/exercises/math/functions/trinoms/roots/trinomAlgebraicFormFromRootsAndPoint.d.ts.map +1 -0
- package/lib/exercises/math/functions/trinoms/roots/trinomAlgebraicFormFromRootsAndPoint.js +252 -0
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/devFormFromSummitAndPoint.d.ts +4 -1
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/devFormFromSummitAndPoint.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/devFormFromSummitAndPoint.js +70 -46
- package/lib/index.d.ts +8 -1
- package/lib/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/roots/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/roots/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,2CAA2C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rootsFromFactorizedForm.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/roots/rootsFromFactorizedForm.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"rootsFromFactorizedForm.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/roots/rootsFromFactorizedForm.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAcrC,KAAK,WAAW,GAAG;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAiJF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,WAAW,CAczD,CAAC"}
|
|
@@ -4,18 +4,48 @@ import { Trinom, TrinomConstructor } from "../../../../../math/polynomials/trino
|
|
|
4
4
|
import { randint } from "../../../../../math/utils/random/randint.js";
|
|
5
5
|
import { OppositeNode } from "../../../../../tree/nodes/functions/oppositeNode.js";
|
|
6
6
|
import { NumberNode } from "../../../../../tree/nodes/numbers/numberNode.js";
|
|
7
|
+
import { square } from "../../../../../tree/nodes/operators/powerNode.js";
|
|
8
|
+
import { substract } from "../../../../../tree/nodes/operators/substractNode.js";
|
|
7
9
|
import { discreteSetParser } from "../../../../../tree/parsers/discreteSetParser.js";
|
|
8
10
|
import { shuffle } from "../../../../../utils/alea/shuffle.js";
|
|
9
11
|
import { handleVEAError } from "../../../../../utils/errors/handleVEAError.js";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
const getHint = () => {
|
|
13
|
+
return `Un produit est nul si et seulement si un de ses facteurs est nul.
|
|
14
|
+
|
|
15
|
+
Il faut donc trouver les valeurs de $x$ qui rendent un des facteurs nuls.`;
|
|
16
|
+
};
|
|
17
|
+
const getCorrection = (identifiers) => {
|
|
18
|
+
const { a, b, c } = identifiers;
|
|
19
|
+
const trinom = new Trinom(a, b, c);
|
|
20
|
+
const roots = trinom.getRootsNode();
|
|
21
|
+
const factors = roots.map((r) => substract("x", r).simplify());
|
|
22
|
+
return `Un produit est nul si et seulement si un de ses facteurs est nul.
|
|
23
|
+
|
|
24
|
+
${roots.length === 2
|
|
25
|
+
? `Or,
|
|
26
|
+
|
|
27
|
+
$$
|
|
28
|
+
${factors[0].toTex()} = 0 \\iff x = ${roots[0].toTex()}
|
|
29
|
+
$$
|
|
30
|
+
|
|
31
|
+
et
|
|
32
|
+
|
|
33
|
+
$$
|
|
34
|
+
${factors[1].toTex()} = 0 \\iff x = ${roots[1].toTex()}
|
|
35
|
+
$$
|
|
36
|
+
`
|
|
37
|
+
: `Or,
|
|
38
|
+
|
|
39
|
+
$$
|
|
40
|
+
${square(factors[0]).toTex()} = 0 \\iff x = ${roots[0].toTex()}
|
|
41
|
+
$$`}
|
|
42
|
+
|
|
43
|
+
L'ensemble des solutions de $f(x) = 0$ est donc :
|
|
44
|
+
|
|
45
|
+
$$
|
|
46
|
+
${getAnswer(identifiers)}
|
|
47
|
+
$$`;
|
|
48
|
+
};
|
|
19
49
|
const getInstruction = (identifiers) => {
|
|
20
50
|
const { a, b, c } = identifiers;
|
|
21
51
|
const trinom = new Trinom(a, b, c);
|
|
@@ -45,6 +75,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
45
75
|
keys: ["S", "equal", "lbrace", "semicolon", "rbrace", "varnothing"],
|
|
46
76
|
answerFormat: "tex",
|
|
47
77
|
identifiers,
|
|
78
|
+
hint: getHint(identifiers),
|
|
79
|
+
correction: getCorrection(identifiers),
|
|
48
80
|
};
|
|
49
81
|
return question;
|
|
50
82
|
};
|
|
@@ -94,4 +126,5 @@ export const rootsFromFactorizedForm = {
|
|
|
94
126
|
isAnswerValid,
|
|
95
127
|
subject: "Mathématiques",
|
|
96
128
|
getQuestionFromIdentifiers,
|
|
129
|
+
hasHintAndCorrection: true,
|
|
97
130
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Exercise } from "../../../../../exercises/exercise.js";
|
|
2
|
+
import { PointIdentifiers } from "../../../../../math/geometry/point.js";
|
|
3
|
+
import { NodeIdentifiers } from "../../../../../tree/nodes/nodeConstructor.js";
|
|
4
|
+
type Identifiers = {
|
|
5
|
+
rootsIds: NodeIdentifiers[];
|
|
6
|
+
pointIds: PointIdentifiers;
|
|
7
|
+
};
|
|
8
|
+
type Options = {
|
|
9
|
+
expectedForm: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const trinomAlgebraicFormFromRootsAndPoint: Exercise<Identifiers, Options>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=trinomAlgebraicFormFromRootsAndPoint.d.ts.map
|
package/lib/exercises/math/functions/trinoms/roots/trinomAlgebraicFormFromRootsAndPoint.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trinomAlgebraicFormFromRootsAndPoint.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/roots/trinomAlgebraicFormFromRootsAndPoint.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAkBT,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAGL,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,eAAe,EAEhB,MAAM,qCAAqC,CAAC;AAU7C,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,CAAC;AA4RF,KAAK,OAAO,GAAG;IACb,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAWF,eAAO,MAAM,oCAAoC,EAAE,QAAQ,CACzD,WAAW,EACX,OAAO,CAwBR,CAAC"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { addValidProp, shuffleProps, GeneratorOptionTarget, GeneratorOptionType, propWhile, tryToAddWrongProp, } from "../../../../../exercises/exercise.js";
|
|
2
|
+
import { getDistinctQuestions } from "../../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
|
+
import { Point, PointConstructor, } from "../../../../../math/geometry/point.js";
|
|
4
|
+
import { randint } from "../../../../../math/utils/random/randint.js";
|
|
5
|
+
import { randTupleInt } from "../../../../../math/utils/random/randTupleInt.js";
|
|
6
|
+
import { reifyAlgebraic, } from "../../../../../tree/nodes/nodeConstructor.js";
|
|
7
|
+
import { frac } from "../../../../../tree/nodes/operators/fractionNode.js";
|
|
8
|
+
import { multiply } from "../../../../../tree/nodes/operators/multiplyNode.js";
|
|
9
|
+
import { square } from "../../../../../tree/nodes/operators/powerNode.js";
|
|
10
|
+
import { substract } from "../../../../../tree/nodes/operators/substractNode.js";
|
|
11
|
+
import { parseAlgebraic } from "../../../../../tree/parsers/latexParser.js";
|
|
12
|
+
import { coinFlip } from "../../../../../utils/alea/coinFlip.js";
|
|
13
|
+
import { handleVEAError } from "../../../../../utils/errors/handleVEAError.js";
|
|
14
|
+
import { alignTex } from "../../../../../utils/latex/alignTex.js";
|
|
15
|
+
const getPropositions = (n, { answer }, opts) => {
|
|
16
|
+
const propositions = [];
|
|
17
|
+
addValidProp(propositions, answer);
|
|
18
|
+
propWhile(propositions, n, () => {
|
|
19
|
+
tryToAddWrongProp(propositions, getAnswer(generateIdentifiers(), opts));
|
|
20
|
+
});
|
|
21
|
+
return shuffleProps(propositions, n);
|
|
22
|
+
};
|
|
23
|
+
const getAnswerNode = (identifiers, options) => {
|
|
24
|
+
const { pointIds, rootsIds } = identifiers;
|
|
25
|
+
const point = PointConstructor.fromIdentifiers(pointIds);
|
|
26
|
+
const roots = rootsIds.map((rootId) => reifyAlgebraic(rootId));
|
|
27
|
+
const partialTrinom = roots.length === 1
|
|
28
|
+
? square(substract("x", roots[0]).simplify())
|
|
29
|
+
: multiply(substract("x", roots[0]).simplify(), substract("x", roots[1]).simplify());
|
|
30
|
+
const partialImage = partialTrinom
|
|
31
|
+
.toDetailedEvaluation({ x: point.x })
|
|
32
|
+
.simplify();
|
|
33
|
+
const a = frac(point.y, partialImage).simplify();
|
|
34
|
+
const facto = multiply(a, partialTrinom).simplify({ forbidFactorize: true });
|
|
35
|
+
if (options?.expectedForm === "Forme développée")
|
|
36
|
+
return facto.simplify({ towardsDistribute: true, forbidFactorize: true });
|
|
37
|
+
return facto;
|
|
38
|
+
};
|
|
39
|
+
const getAnswer = (identifiers, opts) => {
|
|
40
|
+
return getAnswerNode(identifiers, opts).toTex();
|
|
41
|
+
};
|
|
42
|
+
const getInstruction = (identifiers, opts) => {
|
|
43
|
+
const { pointIds, rootsIds } = identifiers;
|
|
44
|
+
const point = PointConstructor.fromIdentifiers(pointIds);
|
|
45
|
+
const roots = rootsIds.map((rootId) => reifyAlgebraic(rootId));
|
|
46
|
+
return `Soit $f$ une fonction polynôme du second degré, dont la parabole passe par le point $${point.toTexWithCoords()}$, et qui a ${roots.length === 1
|
|
47
|
+
? `pour seule racine : $${roots[0].toTex()}$`
|
|
48
|
+
: `deux racines : $${roots[0].toTex()}$ et $${roots[1].toTex()}$`}
|
|
49
|
+
|
|
50
|
+
Déterminer la forme ${opts?.expectedForm === "Forme développée" ? "développée" : "factorisée"} de $f(x)$.
|
|
51
|
+
`;
|
|
52
|
+
};
|
|
53
|
+
const getHint = () => {
|
|
54
|
+
return `Si $f$ est une fonction polynôme du second degré ayant deux racines $x_1$ et $x_2$, alors sa forme factorisée est :
|
|
55
|
+
|
|
56
|
+
$$
|
|
57
|
+
f(x) = a(x-x_1)(x-x_2)
|
|
58
|
+
$$
|
|
59
|
+
|
|
60
|
+
Si elle n'admet qu'une racine $x_0$, alors sa forme factorisée est :
|
|
61
|
+
|
|
62
|
+
$$
|
|
63
|
+
f(x) = a(x-x_0)^2
|
|
64
|
+
$$
|
|
65
|
+
|
|
66
|
+
Sers-toi ensuite du fait que $A$ appartient à la courbe de $f$ pour déterminer $a$.
|
|
67
|
+
`;
|
|
68
|
+
};
|
|
69
|
+
const getCorrection = (identifiers, opts) => {
|
|
70
|
+
const { pointIds, rootsIds } = identifiers;
|
|
71
|
+
const point = PointConstructor.fromIdentifiers(pointIds);
|
|
72
|
+
const roots = rootsIds.map((rootId) => reifyAlgebraic(rootId));
|
|
73
|
+
const partialTrinom = roots.length === 1
|
|
74
|
+
? square(substract("x", roots[0]).simplify())
|
|
75
|
+
: multiply(substract("x", roots[0]).simplify(), substract("x", roots[1]).simplify());
|
|
76
|
+
const partialImage = partialTrinom
|
|
77
|
+
.toDetailedEvaluation({ x: point.x })
|
|
78
|
+
.simplify();
|
|
79
|
+
const a = frac(point.y, partialImage).simplify();
|
|
80
|
+
if (roots.length === 1) {
|
|
81
|
+
return `Puisque $f$ a une seule racine $${roots[0].toTex()}$, sa forme factorisée est :
|
|
82
|
+
|
|
83
|
+
$$
|
|
84
|
+
f(x) = ${multiply("a", square(substract("x", roots[0]).simplify())).toTex()}
|
|
85
|
+
$$
|
|
86
|
+
|
|
87
|
+
Pour déterminer $a$, on utilise le fait que $${point.toTexWithCoords()}$ appartient à la parabole représentative de $f$. Cela implique que $f(${point.x.toTex()})=${point.y.toTex()}$. Donc :
|
|
88
|
+
|
|
89
|
+
$$
|
|
90
|
+
${multiply("a", square(substract(point.x, roots[0]))).toTex()}=${point.y.toTex()}
|
|
91
|
+
$$
|
|
92
|
+
|
|
93
|
+
d'où $a =${a.toTex()}$.
|
|
94
|
+
|
|
95
|
+
La forme factorisée de $f$ est donc :
|
|
96
|
+
|
|
97
|
+
$$
|
|
98
|
+
f(x) = ${multiply(a, partialTrinom).toTex()}
|
|
99
|
+
$$
|
|
100
|
+
|
|
101
|
+
${opts?.expectedForm === "Forme développée"
|
|
102
|
+
? `
|
|
103
|
+
Il suffit alors de développer et réduire pour obtenir la forme développée :
|
|
104
|
+
|
|
105
|
+
${alignTex([
|
|
106
|
+
["f(x)", "=", multiply(a, partialTrinom).toTex()],
|
|
107
|
+
[
|
|
108
|
+
"",
|
|
109
|
+
"=",
|
|
110
|
+
multiply(a, partialTrinom.simplify({
|
|
111
|
+
towardsDistribute: true,
|
|
112
|
+
forbidFactorize: true,
|
|
113
|
+
})).toTex(),
|
|
114
|
+
],
|
|
115
|
+
[
|
|
116
|
+
"",
|
|
117
|
+
"=",
|
|
118
|
+
multiply(a, partialTrinom)
|
|
119
|
+
.simplify({ towardsDistribute: true, forbidFactorize: true })
|
|
120
|
+
.toTex(),
|
|
121
|
+
],
|
|
122
|
+
])}
|
|
123
|
+
`
|
|
124
|
+
: ""}
|
|
125
|
+
`;
|
|
126
|
+
}
|
|
127
|
+
return `Puisque $f$ a deux racines $${roots[0].toTex()}$ et $${roots[1].toTex()}$, sa forme factorisée est :
|
|
128
|
+
|
|
129
|
+
$$
|
|
130
|
+
f(x) = ${multiply("a", multiply(substract("x", roots[0]).simplify(), substract("x", roots[1]).simplify())).toTex()}
|
|
131
|
+
$$
|
|
132
|
+
|
|
133
|
+
Pour déterminer $a$, on utilise le fait que $${point.toTexWithCoords()}$ appartient à la parabole représentative de $f$. Cela implique que $f(${point.x.toTex()})=${point.y.toTex()}$. Donc :
|
|
134
|
+
|
|
135
|
+
$$
|
|
136
|
+
${multiply("a", multiply(substract(point.x, roots[0]).simplify(), substract(point.x, roots[1]).simplify())).toTex()}=${point.y.toTex()}
|
|
137
|
+
$$
|
|
138
|
+
|
|
139
|
+
d'où $a =${a.toTex()}$.
|
|
140
|
+
|
|
141
|
+
La forme factorisée de $f$ est donc :
|
|
142
|
+
|
|
143
|
+
$$
|
|
144
|
+
f(x) = ${multiply(a, partialTrinom).toTex()}
|
|
145
|
+
$$
|
|
146
|
+
|
|
147
|
+
${opts?.expectedForm === "Forme développée"
|
|
148
|
+
? `
|
|
149
|
+
Il suffit alors de développer et réduire pour obtenir la forme développée :
|
|
150
|
+
|
|
151
|
+
${alignTex([
|
|
152
|
+
["f(x)", "=", multiply(a, partialTrinom).toTex()],
|
|
153
|
+
[
|
|
154
|
+
"",
|
|
155
|
+
"=",
|
|
156
|
+
multiply(a, partialTrinom.simplify({
|
|
157
|
+
towardsDistribute: true,
|
|
158
|
+
forbidFactorize: true,
|
|
159
|
+
})).toTex(),
|
|
160
|
+
],
|
|
161
|
+
[
|
|
162
|
+
"",
|
|
163
|
+
"=",
|
|
164
|
+
multiply(a, partialTrinom)
|
|
165
|
+
.simplify({ towardsDistribute: true, forbidFactorize: true })
|
|
166
|
+
.toTex(),
|
|
167
|
+
],
|
|
168
|
+
])}
|
|
169
|
+
`
|
|
170
|
+
: ""}`;
|
|
171
|
+
};
|
|
172
|
+
const getKeys = () => {
|
|
173
|
+
return ["xsquare", "x"];
|
|
174
|
+
};
|
|
175
|
+
const isAnswerValid = (ans, { answer, ...identifiers }, opts) => {
|
|
176
|
+
try {
|
|
177
|
+
const parsed = parseAlgebraic(ans);
|
|
178
|
+
const ansNode = getAnswerNode(identifiers, opts);
|
|
179
|
+
return (parsed
|
|
180
|
+
.simplify({ towardsDistribute: true, forbidFactorize: true })
|
|
181
|
+
.toTex() ===
|
|
182
|
+
ansNode
|
|
183
|
+
.simplify({ towardsDistribute: true, forbidFactorize: true })
|
|
184
|
+
.toTex());
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
return handleVEAError(err);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
const generateIdentifiers = (_options) => {
|
|
191
|
+
const uniqueRoot = coinFlip();
|
|
192
|
+
const roots = uniqueRoot
|
|
193
|
+
? [randint(-9, 10, [0])]
|
|
194
|
+
: randTupleInt(2, {
|
|
195
|
+
from: -9,
|
|
196
|
+
to: 10,
|
|
197
|
+
allDifferent: true,
|
|
198
|
+
}).sort((a, b) => a - b);
|
|
199
|
+
const a = randint(-9, 10, [0]);
|
|
200
|
+
const pointX = randint(-9, 10, roots);
|
|
201
|
+
const pointY = multiply(a, uniqueRoot
|
|
202
|
+
? square(substract(pointX, roots[0]))
|
|
203
|
+
: multiply(substract(pointX, roots[0]), substract(pointX, roots[1]))).simplify();
|
|
204
|
+
const point = new Point("A", pointX, pointY);
|
|
205
|
+
return {
|
|
206
|
+
pointIds: point.toIdentifiers(),
|
|
207
|
+
rootsIds: roots.map((r) => r.toTree().toIdentifiers()),
|
|
208
|
+
};
|
|
209
|
+
};
|
|
210
|
+
const getTrinomAlgebraicFormFromRootsAndPointQuestion = (opts) => {
|
|
211
|
+
return getQuestionFromIdentifiers(generateIdentifiers(opts), opts);
|
|
212
|
+
};
|
|
213
|
+
const getQuestionFromIdentifiers = (identifiers, opts) => {
|
|
214
|
+
return {
|
|
215
|
+
answer: getAnswer(identifiers, opts),
|
|
216
|
+
instruction: getInstruction(identifiers, opts),
|
|
217
|
+
keys: getKeys(identifiers),
|
|
218
|
+
answerFormat: "tex",
|
|
219
|
+
identifiers,
|
|
220
|
+
hint: getHint(identifiers, opts),
|
|
221
|
+
correction: getCorrection(identifiers, opts),
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
const options = [
|
|
225
|
+
{
|
|
226
|
+
id: "expectedForm",
|
|
227
|
+
label: "Forme attendue",
|
|
228
|
+
target: GeneratorOptionTarget.answer,
|
|
229
|
+
type: GeneratorOptionType.select,
|
|
230
|
+
values: ["Forme développée", "Forme factorisée"],
|
|
231
|
+
defaultValue: "Forme factorisée",
|
|
232
|
+
},
|
|
233
|
+
];
|
|
234
|
+
export const trinomAlgebraicFormFromRootsAndPoint = {
|
|
235
|
+
id: "trinomAlgebraicFormFromRootsAndPoint",
|
|
236
|
+
connector: "=",
|
|
237
|
+
label: "Déterminer l'expression algébrique d'un trinôme en connaissant ses racines et un point de la parabole",
|
|
238
|
+
isSingleStep: true,
|
|
239
|
+
generator: (nb, opts) => getDistinctQuestions(() => getTrinomAlgebraicFormFromRootsAndPointQuestion(opts), nb),
|
|
240
|
+
qcmTimer: 60,
|
|
241
|
+
freeTimer: 60,
|
|
242
|
+
getPropositions,
|
|
243
|
+
isAnswerValid,
|
|
244
|
+
subject: "Mathématiques",
|
|
245
|
+
getInstruction,
|
|
246
|
+
getHint,
|
|
247
|
+
getCorrection,
|
|
248
|
+
getAnswer,
|
|
249
|
+
getQuestionFromIdentifiers,
|
|
250
|
+
hasHintAndCorrection: true,
|
|
251
|
+
options,
|
|
252
|
+
};
|
package/lib/exercises/math/functions/trinoms/summitAndCanonical/devFormFromSummitAndPoint.d.ts
CHANGED
|
@@ -4,6 +4,9 @@ type Identifiers = {
|
|
|
4
4
|
summitIds: PointIdentifiers;
|
|
5
5
|
pointIds: PointIdentifiers;
|
|
6
6
|
};
|
|
7
|
-
|
|
7
|
+
type Options = {
|
|
8
|
+
expectedForm: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const devFormFromSummitAndPoint: Exercise<Identifiers, Options>;
|
|
8
11
|
export {};
|
|
9
12
|
//# sourceMappingURL=devFormFromSummitAndPoint.d.ts.map
|
package/lib/exercises/math/functions/trinoms/summitAndCanonical/devFormFromSummitAndPoint.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devFormFromSummitAndPoint.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/summitAndCanonical/devFormFromSummitAndPoint.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,
|
|
1
|
+
{"version":3,"file":"devFormFromSummitAndPoint.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/summitAndCanonical/devFormFromSummitAndPoint.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAkBT,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAGL,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAWtC,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,CAAC;AAyNF,KAAK,OAAO,GAAG;IACb,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAaF,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAoBpE,CAAC"}
|
package/lib/exercises/math/functions/trinoms/summitAndCanonical/devFormFromSummitAndPoint.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addValidProp, shuffleProps, propWhile, tryToAddWrongProp, } from "../../../../../exercises/exercise.js";
|
|
1
|
+
import { addValidProp, shuffleProps, propWhile, tryToAddWrongProp, GeneratorOptionTarget, GeneratorOptionType, } from "../../../../../exercises/exercise.js";
|
|
2
2
|
import { getDistinctQuestions } from "../../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
3
|
import { Point, PointConstructor, } from "../../../../../math/geometry/point.js";
|
|
4
4
|
import { randint } from "../../../../../math/utils/random/randint.js";
|
|
@@ -10,7 +10,7 @@ import { substract } from "../../../../../tree/nodes/operators/substractNode.js"
|
|
|
10
10
|
import { parseAlgebraic } from "../../../../../tree/parsers/latexParser.js";
|
|
11
11
|
import { handleVEAError } from "../../../../../utils/errors/handleVEAError.js";
|
|
12
12
|
import { alignTex } from "../../../../../utils/latex/alignTex.js";
|
|
13
|
-
const getPropositions = (n, { answer }) => {
|
|
13
|
+
const getPropositions = (n, { answer }, opts) => {
|
|
14
14
|
const propositions = [];
|
|
15
15
|
addValidProp(propositions, answer);
|
|
16
16
|
propWhile(propositions, n, () => {
|
|
@@ -23,27 +23,30 @@ const getPropositions = (n, { answer }) => {
|
|
|
23
23
|
pointIds: point.toIdentifiers(),
|
|
24
24
|
summitIds: summit.toIdentifiers(),
|
|
25
25
|
};
|
|
26
|
-
tryToAddWrongProp(propositions, getAnswer(fakeIds));
|
|
26
|
+
tryToAddWrongProp(propositions, getAnswer(fakeIds, opts));
|
|
27
27
|
});
|
|
28
28
|
return shuffleProps(propositions, n);
|
|
29
29
|
};
|
|
30
|
-
const
|
|
30
|
+
const getAnswerNode = (identifiers, opts) => {
|
|
31
31
|
const { pointIds, summitIds } = identifiers;
|
|
32
32
|
const point = PointConstructor.fromIdentifiers(pointIds);
|
|
33
33
|
const summit = PointConstructor.fromIdentifiers(summitIds);
|
|
34
34
|
const a = frac(substract(point.y, summit.y), square(substract(point.x, summit.x))).simplify();
|
|
35
|
-
const cano = add(multiply(a, square(substract("x", summit.x))), summit.y);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
const cano = add(multiply(a, square(substract("x", summit.x).simplify())), summit.y);
|
|
36
|
+
if (opts?.expectedForm === "Forme canonique")
|
|
37
|
+
return cano;
|
|
38
|
+
return cano.simplify({ towardsDistribute: true, forbidFactorize: true });
|
|
39
39
|
};
|
|
40
|
-
const
|
|
40
|
+
const getAnswer = (identifiers, opts) => {
|
|
41
|
+
return getAnswerNode(identifiers, opts).toTex();
|
|
42
|
+
};
|
|
43
|
+
const getInstruction = (identifiers, opts) => {
|
|
41
44
|
const { pointIds, summitIds } = identifiers;
|
|
42
45
|
const point = PointConstructor.fromIdentifiers(pointIds);
|
|
43
46
|
const summit = PointConstructor.fromIdentifiers(summitIds);
|
|
44
47
|
return `On considère une fonction polynôme du second degré $f$. Sa parabole passe par le point $${point.toTexWithCoords()}$, et son sommet est $${summit.toTexWithCoords()}$.
|
|
45
48
|
|
|
46
|
-
Déterminer la forme développée de $f$.`;
|
|
49
|
+
Déterminer la forme ${opts?.expectedForm === "Forme canonique" ? "canonique" : "développée"} de $f$.`;
|
|
47
50
|
};
|
|
48
51
|
const getHint = (identifiers) => {
|
|
49
52
|
return `La forme canonique d'une fonction polynôme du second degré $f$ est :
|
|
@@ -56,7 +59,7 @@ où $\\alpha$ est l'abscisse du sommet de la parabole, et $\\beta$ son ordonnée
|
|
|
56
59
|
|
|
57
60
|
Utilise cette formule ici, puis le fait que le point $${PointConstructor.fromIdentifiers(identifiers.pointIds).toTexWithCoords()}$ est un point de la parabole pour déterminer $a$.`;
|
|
58
61
|
};
|
|
59
|
-
const getCorrection = (identifiers) => {
|
|
62
|
+
const getCorrection = (identifiers, opts) => {
|
|
60
63
|
const { pointIds, summitIds } = identifiers;
|
|
61
64
|
const point = PointConstructor.fromIdentifiers(pointIds);
|
|
62
65
|
const summit = PointConstructor.fromIdentifiers(summitIds);
|
|
@@ -88,49 +91,59 @@ ${alignTex([
|
|
|
88
91
|
["a", "=", a.simplify().toTex()],
|
|
89
92
|
])}
|
|
90
93
|
|
|
91
|
-
|
|
94
|
+
${opts?.expectedForm === "Forme canonique"
|
|
95
|
+
? `La forme canonique de $f$ est donc :
|
|
96
|
+
|
|
97
|
+
$$
|
|
98
|
+
f(x) = ${getAnswer(identifiers, opts)}
|
|
99
|
+
$$`
|
|
100
|
+
: `Il ne reste plus qu'à développer la forme canonique de $f$ :
|
|
92
101
|
|
|
93
102
|
${alignTex([
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
`;
|
|
103
|
+
[
|
|
104
|
+
"f(x)",
|
|
105
|
+
"=",
|
|
106
|
+
add(multiply(a, square(substract("x", alpha))), beta)
|
|
107
|
+
.simplify()
|
|
108
|
+
.toTex(),
|
|
109
|
+
],
|
|
110
|
+
[
|
|
111
|
+
"",
|
|
112
|
+
"=",
|
|
113
|
+
add(multiply(a, square(substract("x", alpha)).simplify({
|
|
114
|
+
towardsDistribute: true,
|
|
115
|
+
forbidFactorize: true,
|
|
116
|
+
})), beta).toTex(),
|
|
117
|
+
],
|
|
118
|
+
[
|
|
119
|
+
"",
|
|
120
|
+
"=",
|
|
121
|
+
add(multiply(a, square(substract("x", alpha))), beta)
|
|
122
|
+
.simplify({ towardsDistribute: true, forbidFactorize: true })
|
|
123
|
+
.toTex(),
|
|
124
|
+
],
|
|
125
|
+
])}
|
|
126
|
+
`}`;
|
|
118
127
|
};
|
|
119
128
|
const getKeys = () => {
|
|
120
129
|
return ["xsquare", "x"];
|
|
121
130
|
};
|
|
122
|
-
const isAnswerValid = (ans, { answer }) => {
|
|
131
|
+
const isAnswerValid = (ans, { answer, ...identifiers }, opts) => {
|
|
123
132
|
try {
|
|
124
133
|
const parsed = parseAlgebraic(ans);
|
|
134
|
+
const ansNode = getAnswerNode(identifiers, opts);
|
|
125
135
|
return (parsed
|
|
126
136
|
.simplify({ towardsDistribute: true, forbidFactorize: true })
|
|
127
|
-
.toTex() ===
|
|
137
|
+
.toTex() ===
|
|
138
|
+
ansNode
|
|
139
|
+
.simplify({ towardsDistribute: true, forbidFactorize: true })
|
|
140
|
+
.toTex());
|
|
128
141
|
}
|
|
129
142
|
catch (err) {
|
|
130
143
|
return handleVEAError(err);
|
|
131
144
|
}
|
|
132
145
|
};
|
|
133
|
-
const getDevFormFromSummitAndPointQuestion = () => {
|
|
146
|
+
const getDevFormFromSummitAndPointQuestion = (opts) => {
|
|
134
147
|
const summit = PointConstructor.random("S");
|
|
135
148
|
const a = randint(-10, 10, [0]);
|
|
136
149
|
const pointX = randint(-10, 10, [summit.x.evaluate()]);
|
|
@@ -140,23 +153,33 @@ const getDevFormFromSummitAndPointQuestion = () => {
|
|
|
140
153
|
pointIds: point.toIdentifiers(),
|
|
141
154
|
summitIds: summit.toIdentifiers(),
|
|
142
155
|
};
|
|
143
|
-
return getQuestionFromIdentifiers(identifiers);
|
|
156
|
+
return getQuestionFromIdentifiers(identifiers, opts);
|
|
144
157
|
};
|
|
145
|
-
const getQuestionFromIdentifiers = (identifiers) => {
|
|
158
|
+
const getQuestionFromIdentifiers = (identifiers, opts) => {
|
|
146
159
|
return {
|
|
147
|
-
answer: getAnswer(identifiers),
|
|
148
|
-
instruction: getInstruction(identifiers),
|
|
160
|
+
answer: getAnswer(identifiers, opts),
|
|
161
|
+
instruction: getInstruction(identifiers, opts),
|
|
149
162
|
keys: getKeys(identifiers),
|
|
150
163
|
answerFormat: "tex",
|
|
151
164
|
identifiers,
|
|
152
|
-
hint: getHint(identifiers),
|
|
153
|
-
correction: getCorrection(identifiers),
|
|
165
|
+
hint: getHint(identifiers, opts),
|
|
166
|
+
correction: getCorrection(identifiers, opts),
|
|
154
167
|
};
|
|
155
168
|
};
|
|
169
|
+
const options = [
|
|
170
|
+
{
|
|
171
|
+
id: "expectedForm",
|
|
172
|
+
label: "Forme attendue",
|
|
173
|
+
target: GeneratorOptionTarget.answer,
|
|
174
|
+
type: GeneratorOptionType.select,
|
|
175
|
+
values: ["Forme développée", "Forme canonique"],
|
|
176
|
+
defaultValue: "Forme développée",
|
|
177
|
+
},
|
|
178
|
+
];
|
|
156
179
|
export const devFormFromSummitAndPoint = {
|
|
157
180
|
id: "devFormFromSummitAndPoint",
|
|
158
181
|
connector: "=",
|
|
159
|
-
label: "Déterminer
|
|
182
|
+
label: "Déterminer l'expression algébrique d'un trinôme en connaissant un point et le sommet de la parabole",
|
|
160
183
|
isSingleStep: true,
|
|
161
184
|
generator: (nb, opts) => getDistinctQuestions(() => getDevFormFromSummitAndPointQuestion(opts), nb),
|
|
162
185
|
qcmTimer: 60,
|
|
@@ -169,5 +192,6 @@ export const devFormFromSummitAndPoint = {
|
|
|
169
192
|
getCorrection,
|
|
170
193
|
getAnswer,
|
|
171
194
|
getQuestionFromIdentifiers,
|
|
195
|
+
options,
|
|
172
196
|
hasHintAndCorrection: true,
|
|
173
197
|
};
|
package/lib/index.d.ts
CHANGED
|
@@ -1397,6 +1397,11 @@ declare const mathExercises: (Exercise<{
|
|
|
1397
1397
|
}> | Exercise<{
|
|
1398
1398
|
trinomIdentifiers: import("./tree/nodes/polynomials/trinomNode.js").TrinomNodeIdentifiers;
|
|
1399
1399
|
}, Record<string, string | boolean | string[]>> | Exercise<{
|
|
1400
|
+
rootsIds: import("./tree/nodes/nodeConstructor.js").NodeIdentifiers[];
|
|
1401
|
+
pointIds: import("./math/geometry/point.js").PointIdentifiers;
|
|
1402
|
+
}, {
|
|
1403
|
+
expectedForm: string;
|
|
1404
|
+
}> | Exercise<{
|
|
1400
1405
|
trinomCoeffs: number[];
|
|
1401
1406
|
isAskingPositive: boolean;
|
|
1402
1407
|
}, Record<string, string | boolean | string[]>> | Exercise<{
|
|
@@ -1442,7 +1447,9 @@ declare const mathExercises: (Exercise<{
|
|
|
1442
1447
|
}, Record<string, string | boolean | string[]>> | Exercise<{
|
|
1443
1448
|
summitIds: import("./math/geometry/point.js").PointIdentifiers;
|
|
1444
1449
|
pointIds: import("./math/geometry/point.js").PointIdentifiers;
|
|
1445
|
-
},
|
|
1450
|
+
}, {
|
|
1451
|
+
expectedForm: string;
|
|
1452
|
+
}> | Exercise<{
|
|
1446
1453
|
type: number;
|
|
1447
1454
|
points: number[][];
|
|
1448
1455
|
}, Record<string, string | boolean | string[]>> | Exercise<{
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAE3D,OAAO,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,QAAA,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAE3D,OAAO,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDAA+B,CAAC;AACnD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDAA6B,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC"}
|