@khanacademy/perseus 21.6.0 → 22.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/article-renderer.d.ts +6 -0
- package/dist/components/highlighting/ui/highlight-set-renderer.d.ts +14 -0
- package/dist/components/highlighting/ui/highlighting-ui.d.ts +17 -0
- package/dist/components/i18n-context.d.ts +16 -0
- package/dist/components/input-with-examples.d.ts +6 -0
- package/dist/components/math-input.d.ts +22 -2
- package/dist/components/number-input.d.ts +6 -0
- package/dist/es/index.js +883 -496
- package/dist/es/index.js.map +1 -1
- package/dist/es/strings.js +312 -0
- package/dist/es/strings.js.map +1 -0
- package/dist/hint-renderer.d.ts +6 -0
- package/dist/hints-renderer.d.ts +6 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1099 -534
- package/dist/index.js.map +1 -1
- package/dist/multi-items/multi-renderer.d.ts +6 -0
- package/dist/perseus-types.d.ts +3 -2
- package/dist/renderer.d.ts +2 -0
- package/dist/server-item-renderer.d.ts +6 -0
- package/dist/strings.d.ts +190 -0
- package/dist/strings.js +395 -119
- package/dist/strings.js.map +1 -0
- package/dist/types.d.ts +2 -1
- package/dist/util/answer-types.d.ts +4 -12
- package/dist/util.d.ts +2 -1
- package/dist/widgets/categorizer.d.ts +8 -1
- package/dist/widgets/definition.d.ts +6 -0
- package/dist/widgets/deprecated-standin/index.d.ts +6 -0
- package/dist/widgets/explanation.d.ts +6 -0
- package/dist/widgets/expression.d.ts +12 -1
- package/dist/widgets/graded-group-answer-bar.d.ts +6 -0
- package/dist/widgets/graded-group.d.ts +6 -0
- package/dist/widgets/group.d.ts +6 -0
- package/dist/widgets/image.d.ts +6 -0
- package/dist/widgets/input-number.d.ts +8 -1
- package/dist/widgets/interactive-graph.d.ts +6 -0
- package/dist/widgets/interactive-graphs/graphs/components/arrowhead.d.ts +1 -0
- package/dist/widgets/interactive-graphs/interactive-graph-question-builder.d.ts +21 -0
- package/dist/widgets/interactive-graphs/locked-point.d.ts +1 -1
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +1 -0
- package/dist/widgets/interactive-graphs/reducer/use-graph-config.d.ts +1 -0
- package/dist/widgets/label-image/marker.d.ts +6 -0
- package/dist/widgets/label-image.d.ts +6 -0
- package/dist/widgets/matcher.d.ts +6 -0
- package/dist/widgets/matrix.d.ts +9 -1
- package/dist/widgets/molecule.d.ts +6 -0
- package/dist/widgets/number-line.d.ts +6 -0
- package/dist/widgets/numeric-input.d.ts +8 -1
- package/dist/widgets/passage-ref-target.d.ts +6 -0
- package/dist/widgets/passage-ref.d.ts +6 -0
- package/dist/widgets/passage.d.ts +6 -0
- package/dist/widgets/plotter.d.ts +6 -0
- package/dist/widgets/radio/choice-a11y-text.d.ts +2 -1
- package/dist/widgets/radio/radio.d.ts +8 -1
- package/dist/widgets/radio/util.d.ts +2 -1
- package/dist/widgets/table.d.ts +7 -0
- package/dist/widgets/unit.d.ts +8 -1
- package/dist/widgets/video.d.ts +6 -0
- package/dist/widgets.d.ts +2 -1
- package/package.json +18 -6
- package/dist/widgets/label-image/strings.d.ts +0 -3
package/dist/index.js
CHANGED
|
@@ -6,7 +6,6 @@ var KAS = require('@khanacademy/kas');
|
|
|
6
6
|
var mathInput = require('@khanacademy/math-input');
|
|
7
7
|
var PerseusLinter = require('@khanacademy/perseus-linter');
|
|
8
8
|
var wonderBlocksCore = require('@khanacademy/wonder-blocks-core');
|
|
9
|
-
var i18n = require('@khanacademy/wonder-blocks-i18n');
|
|
10
9
|
var Tooltip$1 = require('@khanacademy/wonder-blocks-tooltip');
|
|
11
10
|
var classNames = require('classnames');
|
|
12
11
|
var React = require('react');
|
|
@@ -64,7 +63,6 @@ function _interopNamespace(e) {
|
|
|
64
63
|
|
|
65
64
|
var KAS__namespace = /*#__PURE__*/_interopNamespace(KAS);
|
|
66
65
|
var PerseusLinter__namespace = /*#__PURE__*/_interopNamespace(PerseusLinter);
|
|
67
|
-
var i18n__namespace = /*#__PURE__*/_interopNamespace(i18n);
|
|
68
66
|
var Tooltip__default = /*#__PURE__*/_interopDefaultLegacy(Tooltip$1);
|
|
69
67
|
var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames);
|
|
70
68
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
@@ -102,6 +100,290 @@ function _extends() {
|
|
|
102
100
|
return _extends.apply(this, arguments);
|
|
103
101
|
}
|
|
104
102
|
|
|
103
|
+
/**
|
|
104
|
+
* The translated strings that are used to render Perseus.
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Mock strings for the Perseus package, to be used for tests and Storybook.
|
|
109
|
+
*/
|
|
110
|
+
const mockStrings = {
|
|
111
|
+
closeKeypad: "close math keypad",
|
|
112
|
+
openKeypad: "open math keypad",
|
|
113
|
+
removeHighlight: "Remove highlight",
|
|
114
|
+
addHighlight: "Add highlight",
|
|
115
|
+
hintPos: _ref => {
|
|
116
|
+
let {
|
|
117
|
+
pos
|
|
118
|
+
} = _ref;
|
|
119
|
+
return `Hint #${pos}`;
|
|
120
|
+
},
|
|
121
|
+
errorRendering: _ref2 => {
|
|
122
|
+
let {
|
|
123
|
+
error
|
|
124
|
+
} = _ref2;
|
|
125
|
+
return `Error rendering: ${error}`;
|
|
126
|
+
},
|
|
127
|
+
APPROXIMATED_PI_ERROR: "Your answer is close, but you may " + "have approximated pi. Enter your " + "answer as a multiple of pi, like " + "<code>12\\ \\text{pi}</code> or " + "<code>2/3\\ \\text{pi}</code>",
|
|
128
|
+
EXTRA_SYMBOLS_ERROR: "We could not understand your " + "answer. Please check your answer for extra " + "text or symbols.",
|
|
129
|
+
NEEDS_TO_BE_SIMPLFIED_ERROR: "Your answer is almost correct, " + "but it needs to be simplified.",
|
|
130
|
+
MISSING_PERCENT_ERROR: "Your answer is almost correct, " + "but it is missing a " + "<code>\\%</code> at the end.",
|
|
131
|
+
MULTIPLICATION_SIGN_ERROR: "I'm a computer. I only understand " + "multiplication if you use an asterisk " + "(*) as the multiplication sign.",
|
|
132
|
+
WRONG_CASE_ERROR: "Your answer includes use of a variable with the wrong case.",
|
|
133
|
+
WRONG_LETTER_ERROR: "Your answer includes a wrong variable letter.",
|
|
134
|
+
invalidSelection: "Make sure you select something for every row.",
|
|
135
|
+
ERROR_TITLE: "Oops!",
|
|
136
|
+
ERROR_MESSAGE: "Sorry, I don't understand that!",
|
|
137
|
+
hints: "Hints",
|
|
138
|
+
getAnotherHint: "Get another hint",
|
|
139
|
+
deprecatedStandin: "Sorry, this part of the question is no longer available. 😅 Don't worry, you won't be graded on this part. Keep going!",
|
|
140
|
+
keepTrying: "Keep trying",
|
|
141
|
+
tryAgain: "Try again",
|
|
142
|
+
check: "Check",
|
|
143
|
+
correctExcited: "Correct!",
|
|
144
|
+
nextQuestion: "Next question",
|
|
145
|
+
skipToTitle: _ref3 => {
|
|
146
|
+
let {
|
|
147
|
+
title
|
|
148
|
+
} = _ref3;
|
|
149
|
+
return `Skip to ${title}`;
|
|
150
|
+
},
|
|
151
|
+
current: "Current",
|
|
152
|
+
correct: "Correct",
|
|
153
|
+
correctSelected: "Correct (selected)",
|
|
154
|
+
correctCrossedOut: "Correct (but you crossed it out)",
|
|
155
|
+
incorrect: "Incorrect",
|
|
156
|
+
incorrectSelected: "Incorrect (selected)",
|
|
157
|
+
hideExplanation: "Hide explanation",
|
|
158
|
+
explain: "Explain",
|
|
159
|
+
INVALID_MESSAGE_PREFIX: "We couldn't grade your answer.",
|
|
160
|
+
DEFAULT_INVALID_MESSAGE_1: "It looks like you left something blank or ",
|
|
161
|
+
DEFAULT_INVALID_MESSAGE_2: "entered in an invalid answer.",
|
|
162
|
+
integerExample: "an integer, like $6$",
|
|
163
|
+
properExample: "a *proper* fraction, like $1/2$ or $6/10$",
|
|
164
|
+
simplifiedProperExample: "a *simplified proper* fraction, like $3/5$",
|
|
165
|
+
improperExample: "an *improper* fraction, like $10/7$ or $14/8$",
|
|
166
|
+
simplifiedImproperExample: "a *simplified improper* fraction, like $7/4$",
|
|
167
|
+
mixedExample: "a mixed number, like $1\\ 3/4$",
|
|
168
|
+
decimalExample: "an *exact* decimal, like $0.75$",
|
|
169
|
+
percentExample: "a percent, like $12.34\\%$",
|
|
170
|
+
piExample: "a multiple of pi, like $12\\ \\text{pi}$ or $2/3\\ \\text{pi}$",
|
|
171
|
+
yourAnswer: "**Your answer should be** ",
|
|
172
|
+
yourAnswerLabel: "Your answer:",
|
|
173
|
+
addPoints: "Click to add points",
|
|
174
|
+
addVertices: "Click to add vertices",
|
|
175
|
+
tapMultiple: "Tap each dot on the image to select all answers that apply.",
|
|
176
|
+
tapSingle: "Tap each dot on the image to select an answer.",
|
|
177
|
+
clickMultiple: "Click each dot on the image to select all answers that apply.",
|
|
178
|
+
clickSingle: "Click each dot on the image to select an answer.",
|
|
179
|
+
choices: "Choices:",
|
|
180
|
+
answers: _ref4 => {
|
|
181
|
+
let {
|
|
182
|
+
num
|
|
183
|
+
} = _ref4;
|
|
184
|
+
return num === 1 ? `${num} answer` : `${num} answers`;
|
|
185
|
+
},
|
|
186
|
+
hideAnswersToggleLabel: "Hide answer choices",
|
|
187
|
+
moves: _ref5 => {
|
|
188
|
+
let {
|
|
189
|
+
num
|
|
190
|
+
} = _ref5;
|
|
191
|
+
return num === 1 ? `Moves: ${num}` : `Moves: ${num}`;
|
|
192
|
+
},
|
|
193
|
+
clickTiles: "Click on the tiles to change the lights.",
|
|
194
|
+
turnOffLights: "You must turn on all of the lights to continue.",
|
|
195
|
+
fillAllCells: "Make sure you fill in all cells in the matrix.",
|
|
196
|
+
molecularDrawing: _ref6 => {
|
|
197
|
+
let {
|
|
198
|
+
content
|
|
199
|
+
} = _ref6;
|
|
200
|
+
return `A molecular structure drawing. SMILES notation: ${content}`;
|
|
201
|
+
},
|
|
202
|
+
switchDirection: "Switch direction",
|
|
203
|
+
circleOpen: "Make circle open",
|
|
204
|
+
circleFilled: "Make circle filled",
|
|
205
|
+
numDivisions: "Number of divisions:",
|
|
206
|
+
divisions: _ref7 => {
|
|
207
|
+
let {
|
|
208
|
+
divRangeString
|
|
209
|
+
} = _ref7;
|
|
210
|
+
return `Please make sure the number of divisions is in the range ${divRangeString}.`;
|
|
211
|
+
},
|
|
212
|
+
lineRange: _ref8 => {
|
|
213
|
+
let {
|
|
214
|
+
lineRange
|
|
215
|
+
} = _ref8;
|
|
216
|
+
return `lines ${lineRange}`;
|
|
217
|
+
},
|
|
218
|
+
lineNumber: _ref9 => {
|
|
219
|
+
let {
|
|
220
|
+
lineNumber
|
|
221
|
+
} = _ref9;
|
|
222
|
+
return `line ${lineNumber}`;
|
|
223
|
+
},
|
|
224
|
+
symbolPassage: _ref10 => {
|
|
225
|
+
let {
|
|
226
|
+
questionSymbol,
|
|
227
|
+
questionNumber
|
|
228
|
+
} = _ref10;
|
|
229
|
+
return `The symbol ${questionSymbol} indicates that question ${questionNumber} references this portion of the passage.`;
|
|
230
|
+
},
|
|
231
|
+
symbolQuestion: _ref11 => {
|
|
232
|
+
let {
|
|
233
|
+
sentenceSymbol
|
|
234
|
+
} = _ref11;
|
|
235
|
+
return ` The symbol ${sentenceSymbol} indicates that the following sentence is referenced in a question.`;
|
|
236
|
+
},
|
|
237
|
+
lineLabel: "Line",
|
|
238
|
+
beginningPassage: "Beginning of reading passage.",
|
|
239
|
+
beginningFootnotes: "Beginning of reading passage footnotes.",
|
|
240
|
+
endPassage: "End of reading passage.",
|
|
241
|
+
questionMarker: _ref12 => {
|
|
242
|
+
let {
|
|
243
|
+
number
|
|
244
|
+
} = _ref12;
|
|
245
|
+
return `[Marker for question ${number}]`;
|
|
246
|
+
},
|
|
247
|
+
circleMarker: _ref13 => {
|
|
248
|
+
let {
|
|
249
|
+
number
|
|
250
|
+
} = _ref13;
|
|
251
|
+
return `[Circle marker ${number}]`;
|
|
252
|
+
},
|
|
253
|
+
sentenceMarker: _ref14 => {
|
|
254
|
+
let {
|
|
255
|
+
number
|
|
256
|
+
} = _ref14;
|
|
257
|
+
return `[Sentence ${number}]`;
|
|
258
|
+
},
|
|
259
|
+
dragHandles: "Drag handles to make graph",
|
|
260
|
+
tapAddPoints: "Tap to add points",
|
|
261
|
+
false: "False",
|
|
262
|
+
true: "True",
|
|
263
|
+
no: "No",
|
|
264
|
+
yes: "Yes",
|
|
265
|
+
chooseCorrectNum: "Please choose the correct number of answers.",
|
|
266
|
+
notNoneOfTheAbove: "'None of the above' may not be selected when other answers are selected.",
|
|
267
|
+
noneOfTheAbove: "None of the above",
|
|
268
|
+
chooseNumAnswers: _ref15 => {
|
|
269
|
+
let {
|
|
270
|
+
numCorrect
|
|
271
|
+
} = _ref15;
|
|
272
|
+
return `Choose ${numCorrect} answers:`;
|
|
273
|
+
},
|
|
274
|
+
chooseAllAnswers: "Choose all answers that apply:",
|
|
275
|
+
chooseOneAnswer: "Choose 1 answer:",
|
|
276
|
+
choiceCheckedCorrect: _ref16 => {
|
|
277
|
+
let {
|
|
278
|
+
letter
|
|
279
|
+
} = _ref16;
|
|
280
|
+
return `(Choice ${letter}, Checked, Correct)`;
|
|
281
|
+
},
|
|
282
|
+
choiceCrossedOutCorrect: _ref17 => {
|
|
283
|
+
let {
|
|
284
|
+
letter
|
|
285
|
+
} = _ref17;
|
|
286
|
+
return `(Choice ${letter}, Crossed out, Correct)`;
|
|
287
|
+
},
|
|
288
|
+
choiceCorrect: _ref18 => {
|
|
289
|
+
let {
|
|
290
|
+
letter
|
|
291
|
+
} = _ref18;
|
|
292
|
+
return `(Choice ${letter}, Correct)`;
|
|
293
|
+
},
|
|
294
|
+
choiceCheckedIncorrect: _ref19 => {
|
|
295
|
+
let {
|
|
296
|
+
letter
|
|
297
|
+
} = _ref19;
|
|
298
|
+
return `(Choice ${letter}, Checked, Incorrect)`;
|
|
299
|
+
},
|
|
300
|
+
choiceCrossedOutIncorrect: _ref20 => {
|
|
301
|
+
let {
|
|
302
|
+
letter
|
|
303
|
+
} = _ref20;
|
|
304
|
+
return `(Choice ${letter}, Crossed out, Incorrect)`;
|
|
305
|
+
},
|
|
306
|
+
choiceIncorrect: _ref21 => {
|
|
307
|
+
let {
|
|
308
|
+
letter
|
|
309
|
+
} = _ref21;
|
|
310
|
+
return `(Choice ${letter}, Incorrect)`;
|
|
311
|
+
},
|
|
312
|
+
choiceChecked: _ref22 => {
|
|
313
|
+
let {
|
|
314
|
+
letter
|
|
315
|
+
} = _ref22;
|
|
316
|
+
return `(Choice ${letter}, Checked)`;
|
|
317
|
+
},
|
|
318
|
+
choiceCrossedOut: _ref23 => {
|
|
319
|
+
let {
|
|
320
|
+
letter
|
|
321
|
+
} = _ref23;
|
|
322
|
+
return `(Choice ${letter}, Crossed out)`;
|
|
323
|
+
},
|
|
324
|
+
choice: _ref24 => {
|
|
325
|
+
let {
|
|
326
|
+
letter
|
|
327
|
+
} = _ref24;
|
|
328
|
+
return `(Choice ${letter})`;
|
|
329
|
+
},
|
|
330
|
+
crossOut: "Cross out",
|
|
331
|
+
crossOutOption: "Cross out option",
|
|
332
|
+
crossOutChoice: _ref25 => {
|
|
333
|
+
let {
|
|
334
|
+
letter
|
|
335
|
+
} = _ref25;
|
|
336
|
+
return `Cross out Choice ${letter}`;
|
|
337
|
+
},
|
|
338
|
+
bringBack: "Bring back",
|
|
339
|
+
openMenuForChoice: _ref26 => {
|
|
340
|
+
let {
|
|
341
|
+
letter
|
|
342
|
+
} = _ref26;
|
|
343
|
+
return `Open menu for Choice ${letter}`;
|
|
344
|
+
},
|
|
345
|
+
letters: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z",
|
|
346
|
+
rightArrow: "Reaction arrow pointing to the right.",
|
|
347
|
+
dontUnderstandUnits: "I couldn't understand those units.",
|
|
348
|
+
checkSigFigs: "Check your significant figures.",
|
|
349
|
+
answerNumericallyIncorrect: "That answer is numerically incorrect.",
|
|
350
|
+
checkUnits: "Check your units.",
|
|
351
|
+
dontUnderstand: "I don't understand that",
|
|
352
|
+
loading: "Loading...",
|
|
353
|
+
videoTranscript: "See video transcript",
|
|
354
|
+
somethingWrong: "Something went wrong.",
|
|
355
|
+
videoWrapper: "Khan Academy video wrapper"
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* PerseusI18nContext provides a way to set the strings and locale that are
|
|
360
|
+
* used inside the Perseus package.
|
|
361
|
+
*
|
|
362
|
+
*/
|
|
363
|
+
// @ts-expect-error - TS2322 - Type 'Context<{ strings: {}; locale: string; }>' is not assignable to type 'Context<I18nContextType>'.
|
|
364
|
+
const PerseusI18nContext = /*#__PURE__*/React__namespace.createContext(process.env.NODE_ENV === "test" || process.env.STORYBOOK ? {
|
|
365
|
+
strings: mockStrings,
|
|
366
|
+
locale: "en"
|
|
367
|
+
} :
|
|
368
|
+
// We want to return null here, not an empty object, so that we
|
|
369
|
+
// are will throw an error when attempting to access the
|
|
370
|
+
// undefined locale or strings, making it easier to debug.
|
|
371
|
+
null);
|
|
372
|
+
function PerseusI18nContextProvider(_ref) {
|
|
373
|
+
let {
|
|
374
|
+
children,
|
|
375
|
+
strings,
|
|
376
|
+
locale
|
|
377
|
+
} = _ref;
|
|
378
|
+
return /*#__PURE__*/React__namespace.createElement(PerseusI18nContext.Provider, {
|
|
379
|
+
value: {
|
|
380
|
+
strings,
|
|
381
|
+
locale
|
|
382
|
+
}
|
|
383
|
+
}, children);
|
|
384
|
+
}
|
|
385
|
+
const usePerseusI18n = () => React.useContext(PerseusI18nContext);
|
|
386
|
+
|
|
105
387
|
const debounce = (func, delay) => {
|
|
106
388
|
let timer = null;
|
|
107
389
|
return function () {
|
|
@@ -117,24 +399,11 @@ const debounce = (func, delay) => {
|
|
|
117
399
|
};
|
|
118
400
|
};
|
|
119
401
|
|
|
120
|
-
const customKeyTranslator = {
|
|
121
|
-
...mathInput.keyTranslator,
|
|
122
|
-
// If there's something in the input that can become part of a
|
|
123
|
-
// fraction, typing "/" puts it in the numerator. If not, typing
|
|
124
|
-
// "/" does nothing. In that case, enter a \frac.
|
|
125
|
-
FRAC: mathQuill => {
|
|
126
|
-
const contents = mathQuill.latex();
|
|
127
|
-
mathQuill.typedText("/");
|
|
128
|
-
if (mathQuill.latex() === contents) {
|
|
129
|
-
mathQuill.cmd("\\frac");
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
|
|
134
402
|
// A WYSIWYG math input that calls `onChange(LaTeX-string)`
|
|
135
|
-
class
|
|
403
|
+
class InnerMathInput extends React__namespace.Component {
|
|
404
|
+
static contextType = PerseusI18nContext;
|
|
136
405
|
// @ts-expect-error - TS2564 - Property 'mouseDown' has no initializer and is not definitely assigned in the constructor.
|
|
137
|
-
|
|
406
|
+
mouseDown;
|
|
138
407
|
__mathFieldWrapperRef = null;
|
|
139
408
|
__mathField = null;
|
|
140
409
|
static defaultProps = {
|
|
@@ -166,6 +435,22 @@ class MathInput extends React__namespace.Component {
|
|
|
166
435
|
}
|
|
167
436
|
insert = value => {
|
|
168
437
|
const input = this.mathField();
|
|
438
|
+
const {
|
|
439
|
+
locale
|
|
440
|
+
} = this.context;
|
|
441
|
+
const customKeyTranslator = {
|
|
442
|
+
...mathInput.getKeyTranslator(locale),
|
|
443
|
+
// If there's something in the input that can become part of a
|
|
444
|
+
// fraction, typing "/" puts it in the numerator. If not, typing
|
|
445
|
+
// "/" does nothing. In that case, enter a \frac.
|
|
446
|
+
FRAC: mathQuill => {
|
|
447
|
+
const contents = mathQuill.latex();
|
|
448
|
+
mathQuill.typedText("/");
|
|
449
|
+
if (mathQuill.latex() === contents) {
|
|
450
|
+
mathQuill.cmd("\\frac");
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
};
|
|
169
454
|
const inputModifier = customKeyTranslator[value];
|
|
170
455
|
if (inputModifier) {
|
|
171
456
|
inputModifier(input, value);
|
|
@@ -188,8 +473,11 @@ class MathInput extends React__namespace.Component {
|
|
|
188
473
|
};
|
|
189
474
|
mathField = () => {
|
|
190
475
|
if (!this.__mathField && this.__mathFieldWrapperRef) {
|
|
476
|
+
const {
|
|
477
|
+
locale
|
|
478
|
+
} = this.context;
|
|
191
479
|
// Initialize MathQuill.MathField instance
|
|
192
|
-
this.__mathField = mathInput.createMathField(this.__mathFieldWrapperRef, baseConfig => ({
|
|
480
|
+
this.__mathField = mathInput.createMathField(this.__mathFieldWrapperRef, this.props.mathInputStrings, baseConfig => ({
|
|
193
481
|
...baseConfig,
|
|
194
482
|
handlers: {
|
|
195
483
|
edit: debounce(mathField => {
|
|
@@ -206,7 +494,7 @@ class MathInput extends React__namespace.Component {
|
|
|
206
494
|
// Use the specified symbol to represent multiplication
|
|
207
495
|
// TODO(alex): Add an option to disallow variables, in
|
|
208
496
|
// which case 'x' should get converted to '\\times'
|
|
209
|
-
if (mathInput.convertDotToTimesByLocale(this.props.convertDotToTimes)) {
|
|
497
|
+
if (mathInput.convertDotToTimesByLocale(locale, this.props.convertDotToTimes)) {
|
|
210
498
|
value = value.replace(/\\cdot/g, "\\times");
|
|
211
499
|
|
|
212
500
|
// Preserve cursor position in the common case:
|
|
@@ -266,7 +554,10 @@ class MathInput extends React__namespace.Component {
|
|
|
266
554
|
focused: false
|
|
267
555
|
});
|
|
268
556
|
handleKeypadPress = (key, e) => {
|
|
269
|
-
const
|
|
557
|
+
const {
|
|
558
|
+
locale
|
|
559
|
+
} = this.context;
|
|
560
|
+
const translator = mathInput.getKeyTranslator(locale)[key];
|
|
270
561
|
const mathField = this.mathField();
|
|
271
562
|
if (mathField) {
|
|
272
563
|
if (translator) {
|
|
@@ -342,7 +633,7 @@ class MathInput extends React__namespace.Component {
|
|
|
342
633
|
focused: false,
|
|
343
634
|
active: false
|
|
344
635
|
}) : /*#__PURE__*/React__namespace.createElement(Clickable__default["default"], {
|
|
345
|
-
"aria-label": this.state.keypadOpen ?
|
|
636
|
+
"aria-label": this.state.keypadOpen ? this.context.strings.closeKeypad : this.context.strings.openKeypad,
|
|
346
637
|
"aria-checked": this.state.keypadOpen,
|
|
347
638
|
role: "switch",
|
|
348
639
|
onClick: () => this.state.keypadOpen ? this.closeKeypad() : this.openKeypad()
|
|
@@ -351,6 +642,26 @@ class MathInput extends React__namespace.Component {
|
|
|
351
642
|
}, props))))));
|
|
352
643
|
}
|
|
353
644
|
}
|
|
645
|
+
|
|
646
|
+
// We need to have two contexts (one for Perseus and one for MathInput), so we
|
|
647
|
+
// add a wrapper around the MathInput component to provide the MathInput context
|
|
648
|
+
// to it.
|
|
649
|
+
class MathInput extends React__namespace.Component {
|
|
650
|
+
static contextType = mathInput.MathInputI18nContext;
|
|
651
|
+
inputRef = /*#__PURE__*/React__namespace.createRef();
|
|
652
|
+
focus() {
|
|
653
|
+
this.inputRef.current?.focus();
|
|
654
|
+
}
|
|
655
|
+
insert(value) {
|
|
656
|
+
this.inputRef.current?.insert(value);
|
|
657
|
+
}
|
|
658
|
+
render() {
|
|
659
|
+
return /*#__PURE__*/React__namespace.createElement(InnerMathInput, _extends({}, this.props, {
|
|
660
|
+
ref: this.inputRef,
|
|
661
|
+
mathInputStrings: this.context.strings
|
|
662
|
+
}));
|
|
663
|
+
}
|
|
664
|
+
}
|
|
354
665
|
const MathInputIcon = _ref => {
|
|
355
666
|
let {
|
|
356
667
|
hovered,
|
|
@@ -547,6 +858,8 @@ const Log = {
|
|
|
547
858
|
};
|
|
548
859
|
|
|
549
860
|
class PerseusError extends Error {
|
|
861
|
+
kind;
|
|
862
|
+
metadata;
|
|
550
863
|
constructor(message, kind, options) {
|
|
551
864
|
super(message);
|
|
552
865
|
this.kind = kind;
|
|
@@ -1264,16 +1577,6 @@ const MAXERROR_EPSILON = Math.pow(2, -42);
|
|
|
1264
1577
|
// TOOD(kevinb): Figure out how this relates to KEScore in
|
|
1265
1578
|
// perseus-all-package/types.js and see if there's a way to
|
|
1266
1579
|
// unify these types.
|
|
1267
|
-
const errors = {
|
|
1268
|
-
APPROXIMATED_PI_ERROR: i18n__namespace._("Your answer is close, but you may " + "have approximated pi. Enter your " + "answer as a multiple of pi, like " + "<code>12\\ \\text{pi}</code> or " + "<code>2/3\\ \\text{pi}</code>"),
|
|
1269
|
-
EXTRA_SYMBOLS_ERROR: i18n__namespace._("We could not understand your " + "answer. Please check your answer for extra " + "text or symbols."),
|
|
1270
|
-
NEEDS_TO_BE_SIMPLFIED_ERROR: i18n__namespace._("Your answer is almost correct, " + "but it needs to be simplified."),
|
|
1271
|
-
MISSING_PERCENT_ERROR: i18n__namespace._("Your answer is almost correct, " + "but it is missing a " + "<code>\\%</code> at the end."),
|
|
1272
|
-
MULTIPLICATION_SIGN_ERROR: i18n__namespace._("I'm a computer. I only understand " + "multiplication if you use an asterisk " + "(*) as the multiplication sign."),
|
|
1273
|
-
WRONG_CASE_ERROR: i18n__namespace._("Your answer includes use of a variable with the wrong case."),
|
|
1274
|
-
WRONG_LETTER_ERROR: i18n__namespace._("Your answer includes a wrong variable letter.")
|
|
1275
|
-
};
|
|
1276
|
-
|
|
1277
1580
|
/*
|
|
1278
1581
|
* Answer types
|
|
1279
1582
|
*
|
|
@@ -1346,7 +1649,7 @@ const KhanAnswerTypes = {
|
|
|
1346
1649
|
*/
|
|
1347
1650
|
predicate: {
|
|
1348
1651
|
defaultForms: "integer, proper, improper, mixed, decimal",
|
|
1349
|
-
createValidatorFunctional: function (predicate, options) {
|
|
1652
|
+
createValidatorFunctional: function (predicate, options, strings) {
|
|
1350
1653
|
// Extract the options from the given solution object
|
|
1351
1654
|
options = ___default["default"].extend({
|
|
1352
1655
|
simplify: "required",
|
|
@@ -1735,12 +2038,12 @@ const KhanAnswerTypes = {
|
|
|
1735
2038
|
} else if (form === "percent") {
|
|
1736
2039
|
// Otherwise, an error was returned
|
|
1737
2040
|
score.empty = true;
|
|
1738
|
-
score.message =
|
|
2041
|
+
score.message = strings.MISSING_PERCENT_ERROR;
|
|
1739
2042
|
} else {
|
|
1740
2043
|
if (options.simplify !== "enforced") {
|
|
1741
2044
|
score.empty = true;
|
|
1742
2045
|
}
|
|
1743
|
-
score.message =
|
|
2046
|
+
score.message = strings.NEEDS_TO_BE_SIMPLFIED_ERROR;
|
|
1744
2047
|
}
|
|
1745
2048
|
// The return false below stops the looping of the
|
|
1746
2049
|
// callback since predicate check succeeded.
|
|
@@ -1749,7 +2052,7 @@ const KhanAnswerTypes = {
|
|
|
1749
2052
|
}
|
|
1750
2053
|
if (piApprox && predicate(val, Math.abs(val * 0.001))) {
|
|
1751
2054
|
score.empty = true;
|
|
1752
|
-
score.message =
|
|
2055
|
+
score.message = strings.APPROXIMATED_PI_ERROR;
|
|
1753
2056
|
}
|
|
1754
2057
|
}
|
|
1755
2058
|
});
|
|
@@ -1765,7 +2068,7 @@ const KhanAnswerTypes = {
|
|
|
1765
2068
|
});
|
|
1766
2069
|
if (!interpretedGuess) {
|
|
1767
2070
|
score.empty = true;
|
|
1768
|
-
score.message =
|
|
2071
|
+
score.message = strings.EXTRA_SYMBOLS_ERROR;
|
|
1769
2072
|
return score;
|
|
1770
2073
|
}
|
|
1771
2074
|
}
|
|
@@ -1788,10 +2091,10 @@ const KhanAnswerTypes = {
|
|
|
1788
2091
|
type: "predicate"
|
|
1789
2092
|
})];
|
|
1790
2093
|
},
|
|
1791
|
-
createValidatorFunctional: function (correctAnswer, options) {
|
|
2094
|
+
createValidatorFunctional: function (correctAnswer, options, strings) {
|
|
1792
2095
|
return KhanAnswerTypes.predicate.createValidatorFunctional(
|
|
1793
2096
|
// @ts-expect-error - TS2556 - A spread argument must either have a tuple type or be passed to a rest parameter.
|
|
1794
|
-
...KhanAnswerTypes.number.convertToPredicate(correctAnswer, options));
|
|
2097
|
+
...KhanAnswerTypes.number.convertToPredicate(correctAnswer, options), strings);
|
|
1795
2098
|
}
|
|
1796
2099
|
},
|
|
1797
2100
|
/*
|
|
@@ -1856,7 +2159,7 @@ const KhanAnswerTypes = {
|
|
|
1856
2159
|
}
|
|
1857
2160
|
return solution;
|
|
1858
2161
|
},
|
|
1859
|
-
createValidatorFunctional: function (solution, options) {
|
|
2162
|
+
createValidatorFunctional: function (solution, options, strings) {
|
|
1860
2163
|
return function (guess) {
|
|
1861
2164
|
const score = {
|
|
1862
2165
|
empty: false,
|
|
@@ -1907,7 +2210,7 @@ const KhanAnswerTypes = {
|
|
|
1907
2210
|
// @ts-expect-error - TS2540 - Cannot assign to 'ungraded' because it is a read-only property.
|
|
1908
2211
|
score.ungraded = true;
|
|
1909
2212
|
// @ts-expect-error - TS2540 - Cannot assign to 'message' because it is a read-only property.
|
|
1910
|
-
score.message = result.wrongVariableCase ?
|
|
2213
|
+
score.message = result.wrongVariableCase ? strings.WRONG_CASE_ERROR : strings.WRONG_LETTER_ERROR;
|
|
1911
2214
|
// Don't tell the use they're "almost there" in this case, that may not be true and isn't helpful.
|
|
1912
2215
|
// @ts-expect-error - TS2339 - Property 'suppressAlmostThere' does not exist on type '{ readonly empty: false; readonly correct: false; readonly message: string | null | undefined; readonly guess: any; readonly ungraded: false; }'.
|
|
1913
2216
|
score.suppressAlmostThere = true;
|
|
@@ -1933,7 +2236,7 @@ const KhanAnswerTypes = {
|
|
|
1933
2236
|
// @ts-expect-error - TS2540 - Cannot assign to 'ungraded' because it is a read-only property.
|
|
1934
2237
|
score.ungraded = true;
|
|
1935
2238
|
// @ts-expect-error - TS2540 - Cannot assign to 'message' because it is a read-only property.
|
|
1936
|
-
score.message =
|
|
2239
|
+
score.message = strings.MULTIPLICATION_SIGN_ERROR;
|
|
1937
2240
|
} else if (resultX.message) {
|
|
1938
2241
|
// TODO(aasmund): I18nize `score.message`
|
|
1939
2242
|
// @ts-expect-error - TS2540 - Cannot assign to 'message' because it is a read-only property.
|
|
@@ -1947,9 +2250,6 @@ const KhanAnswerTypes = {
|
|
|
1947
2250
|
}
|
|
1948
2251
|
};
|
|
1949
2252
|
|
|
1950
|
-
const ERROR_TITLE = i18n__namespace._("Oops!");
|
|
1951
|
-
const ERROR_MESSAGE = i18n__namespace._("Sorry, I don't understand that!");
|
|
1952
|
-
|
|
1953
2253
|
// Map of international operator names to their English equivalents
|
|
1954
2254
|
const englishOperators = {
|
|
1955
2255
|
arctg: "arctan",
|
|
@@ -1976,8 +2276,34 @@ const deriveKeypadVersion = apiOptions => {
|
|
|
1976
2276
|
// can remove this `virtualKeypadVersion` field entirely.
|
|
1977
2277
|
return apiOptions.nativeKeypadProxy != null ? "REACT_NATIVE_KEYPAD" : "MATH_INPUT_KEYPAD_V2";
|
|
1978
2278
|
};
|
|
2279
|
+
/**
|
|
2280
|
+
* Get the character used for separating decimals.
|
|
2281
|
+
*/
|
|
2282
|
+
const getDecimalSeparator = locale => {
|
|
2283
|
+
switch (locale) {
|
|
2284
|
+
// TODO(somewhatabstract): Remove this when Chrome supports the `ka`
|
|
2285
|
+
// locale properly.
|
|
2286
|
+
// https://github.com/formatjs/formatjs/issues/1526#issuecomment-559891201
|
|
2287
|
+
//
|
|
2288
|
+
// Supported locales in Chrome:
|
|
2289
|
+
// https://source.chromium.org/chromium/chromium/src/+/master:third_party/icu/scripts/chrome_ui_languages.list
|
|
2290
|
+
case "ka":
|
|
2291
|
+
return ",";
|
|
2292
|
+
default:
|
|
2293
|
+
const numberWithDecimalSeparator = 1.1;
|
|
2294
|
+
// TODO(FEI-3647): Update to use .formatToParts() once we no longer have to
|
|
2295
|
+
// support Safari 12.
|
|
2296
|
+
const match = new Intl.NumberFormat(locale).format(numberWithDecimalSeparator)
|
|
2297
|
+
// 0x661 is ARABIC-INDIC DIGIT ONE
|
|
2298
|
+
// 0x6F1 is EXTENDED ARABIC-INDIC DIGIT ONE
|
|
2299
|
+
.match(/[^\d\u0661\u06F1]/);
|
|
2300
|
+
return match?.[0] ?? ".";
|
|
2301
|
+
}
|
|
2302
|
+
};
|
|
2303
|
+
|
|
1979
2304
|
// The new, MathQuill input expression widget
|
|
1980
2305
|
class Expression extends React__namespace.Component {
|
|
2306
|
+
static contextType = PerseusI18nContext;
|
|
1981
2307
|
_isMounted = false;
|
|
1982
2308
|
|
|
1983
2309
|
//#region Previously a class extension
|
|
@@ -2001,9 +2327,11 @@ class Expression extends React__namespace.Component {
|
|
|
2001
2327
|
*/
|
|
2002
2328
|
static validate(userInput, rubric) {
|
|
2003
2329
|
let onInputError = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {};
|
|
2330
|
+
let strings = arguments.length > 3 ? arguments[3] : undefined;
|
|
2331
|
+
let locale = arguments.length > 4 ? arguments[4] : undefined;
|
|
2004
2332
|
const options = ___default["default"].clone(rubric);
|
|
2005
2333
|
___default["default"].extend(options, {
|
|
2006
|
-
decimal_separator:
|
|
2334
|
+
decimal_separator: getDecimalSeparator(locale)
|
|
2007
2335
|
});
|
|
2008
2336
|
const createValidator = answer => {
|
|
2009
2337
|
// We give options to KAS.parse here because it is parsing the
|
|
@@ -2026,7 +2354,7 @@ class Expression extends React__namespace.Component {
|
|
|
2026
2354
|
return KhanAnswerTypes.expression.createValidatorFunctional(expression.expr, ___default["default"]({}).extend(options, {
|
|
2027
2355
|
simplify: answer.simplify,
|
|
2028
2356
|
form: answer.form
|
|
2029
|
-
}));
|
|
2357
|
+
}), strings);
|
|
2030
2358
|
};
|
|
2031
2359
|
|
|
2032
2360
|
// Find the first answer form that matches the user's input and that
|
|
@@ -2173,7 +2501,7 @@ class Expression extends React__namespace.Component {
|
|
|
2173
2501
|
if (!this.parse(this.props.value, this.props).parsed) {
|
|
2174
2502
|
const apiResult = this.props.apiOptions.onInputError(null,
|
|
2175
2503
|
// reserved for some widget identifier
|
|
2176
|
-
this.props.value,
|
|
2504
|
+
this.props.value, this.context.strings.ERROR_TITLE);
|
|
2177
2505
|
if (apiResult !== false) {
|
|
2178
2506
|
this.setState({
|
|
2179
2507
|
invalid: true
|
|
@@ -2197,7 +2525,7 @@ class Expression extends React__namespace.Component {
|
|
|
2197
2525
|
scoring,
|
|
2198
2526
|
...rubric
|
|
2199
2527
|
} = _ref;
|
|
2200
|
-
const score = Expression.validate(this.getUserInput(), rubric, onInputError || function () {});
|
|
2528
|
+
const score = Expression.validate(this.getUserInput(), rubric, onInputError || function () {}, this.context.strings, this.context.locale);
|
|
2201
2529
|
|
|
2202
2530
|
// "scoring" is a flag that indicates when we are checking answers.
|
|
2203
2531
|
// otherwise, we may just be checking validity after changes.
|
|
@@ -2229,7 +2557,7 @@ class Expression extends React__namespace.Component {
|
|
|
2229
2557
|
// make it so that solution answers with ','s or '.'s work
|
|
2230
2558
|
const options = ___default["default"].pick(props || this.props, "functions");
|
|
2231
2559
|
___default["default"].extend(options, {
|
|
2232
|
-
decimal_separator:
|
|
2560
|
+
decimal_separator: getDecimalSeparator(this.context.locale)
|
|
2233
2561
|
});
|
|
2234
2562
|
return KAS__namespace.parse(normalizeTex(value), options);
|
|
2235
2563
|
};
|
|
@@ -2266,7 +2594,7 @@ class Expression extends React__namespace.Component {
|
|
|
2266
2594
|
blurInputPath = inputPath => {
|
|
2267
2595
|
// eslint-disable-next-line react/no-string-refs
|
|
2268
2596
|
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
2269
|
-
this.refs.input
|
|
2597
|
+
this.refs.input?.blur();
|
|
2270
2598
|
};
|
|
2271
2599
|
|
|
2272
2600
|
// HACK(joel)
|
|
@@ -2318,6 +2646,10 @@ class Expression extends React__namespace.Component {
|
|
|
2318
2646
|
"perseus-widget-expression": true,
|
|
2319
2647
|
"show-error-tooltip": this.state.showErrorTooltip
|
|
2320
2648
|
});
|
|
2649
|
+
const {
|
|
2650
|
+
ERROR_MESSAGE,
|
|
2651
|
+
ERROR_TITLE
|
|
2652
|
+
} = this.context.strings;
|
|
2321
2653
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
2322
2654
|
className: className,
|
|
2323
2655
|
onBlur: () => this.state.invalid && this.setState({
|
|
@@ -2744,7 +3076,7 @@ function keScoreFromPerseusScore(score, guess, state) {
|
|
|
2744
3076
|
* Return the first valid interpretation of 'text' as a number, in the form
|
|
2745
3077
|
* {value: 2.3, exact: true}.
|
|
2746
3078
|
*/
|
|
2747
|
-
function firstNumericalParse$1(text) {
|
|
3079
|
+
function firstNumericalParse$1(text, strings) {
|
|
2748
3080
|
// TODO(alpert): This is sort of hacky...
|
|
2749
3081
|
let first;
|
|
2750
3082
|
const val = KhanAnswerTypes.predicate.createValidatorFunctional(function (ans) {
|
|
@@ -2754,7 +3086,7 @@ function firstNumericalParse$1(text) {
|
|
|
2754
3086
|
simplify: "optional",
|
|
2755
3087
|
inexact: true,
|
|
2756
3088
|
forms: "integer, proper, improper, pi, log, mixed, decimal"
|
|
2757
|
-
});
|
|
3089
|
+
}, strings);
|
|
2758
3090
|
val(text);
|
|
2759
3091
|
return first;
|
|
2760
3092
|
}
|
|
@@ -8566,8 +8898,12 @@ const KhanColors = {
|
|
|
8566
8898
|
// DrawingTransform is responsible for transforming from "math coordinates"
|
|
8567
8899
|
// (on the Cartesian plane) to "canvas coordinates" in pixels.
|
|
8568
8900
|
class DrawingTransform {
|
|
8569
|
-
|
|
8901
|
+
raphael;
|
|
8570
8902
|
|
|
8903
|
+
// Scale is measured in pixels per unit on the Cartesian plane.
|
|
8904
|
+
xScale;
|
|
8905
|
+
yScale;
|
|
8906
|
+
bounds;
|
|
8571
8907
|
constructor(raphael, initialScale, bounds) {
|
|
8572
8908
|
this.raphael = raphael;
|
|
8573
8909
|
this.bounds = bounds;
|
|
@@ -8632,6 +8968,10 @@ class DrawingTransform {
|
|
|
8632
8968
|
// Defines the bounds of the visible area of a graph, in Cartesian coordinates.
|
|
8633
8969
|
// GraphBounds is immutable.
|
|
8634
8970
|
class GraphBounds {
|
|
8971
|
+
xMin;
|
|
8972
|
+
xMax;
|
|
8973
|
+
yMin;
|
|
8974
|
+
yMax;
|
|
8635
8975
|
constructor(xRange, yRange) {
|
|
8636
8976
|
this.xMin = xRange[0];
|
|
8637
8977
|
this.xMax = xRange[1];
|
|
@@ -8735,26 +9075,35 @@ function polar(r, th) {
|
|
|
8735
9075
|
return [r[0] * Math.cos(th), r[1] * Math.sin(th)];
|
|
8736
9076
|
}
|
|
8737
9077
|
class Graphie$1 {
|
|
9078
|
+
el;
|
|
8738
9079
|
#bounds;
|
|
8739
9080
|
#drawingTransform;
|
|
8740
9081
|
|
|
8741
9082
|
// The primary drawing layer
|
|
8742
|
-
|
|
9083
|
+
raphael;
|
|
8743
9084
|
// The layer that all visuals with mouse handlers are drawn into
|
|
8744
|
-
|
|
9085
|
+
mouselayer;
|
|
9086
|
+
_mouselayerWrapper;
|
|
9087
|
+
_visiblelayerWrapper;
|
|
8745
9088
|
isMobile = false;
|
|
8746
9089
|
// Set up some reasonable defaults
|
|
8747
9090
|
currentStyle = {
|
|
8748
9091
|
"stroke-width": 2,
|
|
8749
9092
|
fill: "none"
|
|
8750
9093
|
};
|
|
8751
|
-
|
|
9094
|
+
range;
|
|
9095
|
+
scale;
|
|
9096
|
+
dimensions;
|
|
8752
9097
|
// TODO(benchristel): xpixels and ypixels are never used by this class, but
|
|
8753
9098
|
// other code reaches in to access them :(
|
|
8754
9099
|
// Refactor to accessor methods that look at this.dimensions.
|
|
9100
|
+
xpixels;
|
|
9101
|
+
ypixels;
|
|
9102
|
+
|
|
8755
9103
|
// set by Movables
|
|
8756
9104
|
// TODO(benchristel): consider putting this state on the Movable instead of
|
|
8757
9105
|
// on the Graphie
|
|
9106
|
+
isDragging;
|
|
8758
9107
|
constructor(el) {
|
|
8759
9108
|
this.el = el;
|
|
8760
9109
|
$__default["default"](el).css("position", "relative");
|
|
@@ -10286,6 +10635,8 @@ const getClipPoint = function (graph, coord, angle) {
|
|
|
10286
10635
|
*/
|
|
10287
10636
|
|
|
10288
10637
|
class WrappedDrawing {
|
|
10638
|
+
graphie;
|
|
10639
|
+
initialPoint;
|
|
10289
10640
|
constructor(graphie, initialPoint) {
|
|
10290
10641
|
this.graphie = graphie;
|
|
10291
10642
|
this.initialPoint = initialPoint;
|
|
@@ -10346,6 +10697,8 @@ const DEFAULT_OPTIONS$2 = {
|
|
|
10346
10697
|
mouselayer: false
|
|
10347
10698
|
};
|
|
10348
10699
|
class WrappedPath extends WrappedDrawing {
|
|
10700
|
+
wrapper;
|
|
10701
|
+
visibleShape;
|
|
10349
10702
|
constructor(graphie, points, options) {
|
|
10350
10703
|
const initialPoint = graphie.scalePoint(___default["default"].head(points));
|
|
10351
10704
|
super(graphie, initialPoint);
|
|
@@ -10368,6 +10721,7 @@ class WrappedPath extends WrappedDrawing {
|
|
|
10368
10721
|
|
|
10369
10722
|
class Arrowhead$1 extends WrappedPath {
|
|
10370
10723
|
static scale = 1.4;
|
|
10724
|
+
center;
|
|
10371
10725
|
constructor(graphie, style) {
|
|
10372
10726
|
// Points that define the arrowhead
|
|
10373
10727
|
const center = [0.75, 0];
|
|
@@ -10413,6 +10767,9 @@ const DEFAULT_OPTIONS$1 = {
|
|
|
10413
10767
|
disableMouseEventsOnWrapper: false
|
|
10414
10768
|
};
|
|
10415
10769
|
class WrappedEllipse extends WrappedDrawing {
|
|
10770
|
+
initialPoint;
|
|
10771
|
+
wrapper;
|
|
10772
|
+
visibleShape;
|
|
10416
10773
|
constructor(graphie, center, radii, options) {
|
|
10417
10774
|
super(graphie, center);
|
|
10418
10775
|
options = ___default["default"].extend({}, DEFAULT_OPTIONS$1, options);
|
|
@@ -10460,6 +10817,9 @@ const DEFAULT_OPTIONS = {
|
|
|
10460
10817
|
mouselayer: false
|
|
10461
10818
|
};
|
|
10462
10819
|
class WrappedLine extends WrappedDrawing {
|
|
10820
|
+
initialLength;
|
|
10821
|
+
wrapper;
|
|
10822
|
+
visibleShape;
|
|
10463
10823
|
constructor(graphie, start, end, options) {
|
|
10464
10824
|
// Always make the line as large as possible and horizontal; this
|
|
10465
10825
|
// simplifies a lot of the transforms, e.g., we can rotate by exactly the
|
|
@@ -13753,6 +14113,9 @@ const DEFAULT_STATE$3 = {
|
|
|
13753
14113
|
mouseTarget: null
|
|
13754
14114
|
};
|
|
13755
14115
|
class Movable {
|
|
14116
|
+
graphie;
|
|
14117
|
+
state;
|
|
14118
|
+
prevState;
|
|
13756
14119
|
// TODO(benchristel): delete _listenerMap; it's unused
|
|
13757
14120
|
_listenerMap = {};
|
|
13758
14121
|
constructor(graphie, options) {
|
|
@@ -13878,12 +14241,12 @@ class Movable {
|
|
|
13878
14241
|
* Fire an onSomething type event to all functions in listeners
|
|
13879
14242
|
*/
|
|
13880
14243
|
_fireEvent(listeners) {
|
|
13881
|
-
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
13882
|
-
args[_key - 1] = arguments[_key];
|
|
13883
|
-
}
|
|
13884
14244
|
if (listeners == null) {
|
|
13885
14245
|
return;
|
|
13886
14246
|
}
|
|
14247
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
14248
|
+
args[_key - 1] = arguments[_key];
|
|
14249
|
+
}
|
|
13887
14250
|
for (const listener of listeners) {
|
|
13888
14251
|
listener.call(this, ...args);
|
|
13889
14252
|
}
|
|
@@ -15016,8 +15379,12 @@ const DEFAULT_STATE$1 = {
|
|
|
15016
15379
|
// tooltipResetFunctions, but never remove them.
|
|
15017
15380
|
const tooltipResetFunctions = [];
|
|
15018
15381
|
class MovablePoint$4 {
|
|
15382
|
+
graphie;
|
|
15383
|
+
movable;
|
|
15384
|
+
state;
|
|
15019
15385
|
// @ts-expect-error - TS2564: Property 'prevState' has no initializer and is not definitely assigned in the constructor.
|
|
15020
|
-
|
|
15386
|
+
prevState;
|
|
15387
|
+
_tooltip;
|
|
15021
15388
|
_listenerMap = {};
|
|
15022
15389
|
constructor(graphie, movable, options) {
|
|
15023
15390
|
this.graphie = graphie;
|
|
@@ -16706,6 +17073,7 @@ const Status = {
|
|
|
16706
17073
|
FAILED: "failed"
|
|
16707
17074
|
};
|
|
16708
17075
|
class ImageLoader extends React__namespace.Component {
|
|
17076
|
+
img;
|
|
16709
17077
|
constructor(props) {
|
|
16710
17078
|
super(props);
|
|
16711
17079
|
this.state = {
|
|
@@ -16942,6 +17310,7 @@ function defaultPreloader(dimensions) {
|
|
|
16942
17310
|
}));
|
|
16943
17311
|
}
|
|
16944
17312
|
class SvgImage extends React__namespace.Component {
|
|
17313
|
+
_isMounted;
|
|
16945
17314
|
static defaultProps = {
|
|
16946
17315
|
constrainHeight: false,
|
|
16947
17316
|
onUpdate: () => {},
|
|
@@ -17387,6 +17756,7 @@ class SvgImage extends React__namespace.Component {
|
|
|
17387
17756
|
* have been loaded. This tracking is facilitated by the AssetContext.
|
|
17388
17757
|
*/
|
|
17389
17758
|
class Tex extends React__namespace.Component {
|
|
17759
|
+
_hasRendered;
|
|
17390
17760
|
static defaultProps = {
|
|
17391
17761
|
onRender: () => {},
|
|
17392
17762
|
setAssetStatus: (src, status) => {}
|
|
@@ -17428,13 +17798,14 @@ class Tex extends React__namespace.Component {
|
|
|
17428
17798
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
17429
17799
|
class Zoomable extends React__namespace.Component {
|
|
17430
17800
|
// @ts-expect-error - TS2564 - Property '_isMounted' has no initializer and is not definitely assigned in the constructor.
|
|
17431
|
-
|
|
17801
|
+
_isMounted;
|
|
17432
17802
|
// @ts-expect-error - TS2564 - Property '_observer' has no initializer and is not definitely assigned in the constructor.
|
|
17433
|
-
|
|
17803
|
+
_observer;
|
|
17434
17804
|
// @ts-expect-error - TS2564 - Property '_measuringInitialized' has no initializer and is not definitely assigned in the constructor.
|
|
17435
|
-
|
|
17805
|
+
_measuringInitialized;
|
|
17806
|
+
_originalWidth;
|
|
17436
17807
|
// @ts-expect-error - TS2564 - Property '_node' has no initializer and is not definitely assigned in the constructor.
|
|
17437
|
-
|
|
17808
|
+
_node;
|
|
17438
17809
|
static defaultProps = {
|
|
17439
17810
|
animateHeight: false,
|
|
17440
17811
|
readyToMeasure: true,
|
|
@@ -17793,13 +18164,15 @@ function _noop() {}
|
|
|
17793
18164
|
*/
|
|
17794
18165
|
class InteractionTracker {
|
|
17795
18166
|
// @ts-expect-error - TS2564 - Property '_tracked' has no initializer and is not definitely assigned in the constructor.
|
|
17796
|
-
|
|
18167
|
+
_tracked;
|
|
17797
18168
|
// @ts-expect-error - TS2564 - Property 'setting' has no initializer and is not definitely assigned in the constructor.
|
|
17798
|
-
|
|
18169
|
+
setting;
|
|
18170
|
+
track;
|
|
18171
|
+
trackApi;
|
|
17799
18172
|
// @ts-expect-error - TS2564 - Property 'widgetID' has no initializer and is not definitely assigned in the constructor.
|
|
17800
|
-
|
|
18173
|
+
widgetID;
|
|
17801
18174
|
// @ts-expect-error - TS2564 - Property 'widgetType' has no initializer and is not definitely assigned in the constructor.
|
|
17802
|
-
|
|
18175
|
+
widgetType;
|
|
17803
18176
|
constructor(trackApi, widgetType, widgetID, setting) {
|
|
17804
18177
|
if (!trackApi) {
|
|
17805
18178
|
this.track = _noop;
|
|
@@ -17911,6 +18284,7 @@ var Severity = /*#__PURE__*/function (Severity) {
|
|
|
17911
18284
|
* to the left of where it belongs. And if there is more
|
|
17912
18285
|
**/
|
|
17913
18286
|
class Lint extends React__namespace.Component {
|
|
18287
|
+
_positionTimeout;
|
|
17914
18288
|
state = {
|
|
17915
18289
|
tooltipAbove: true
|
|
17916
18290
|
};
|
|
@@ -18367,7 +18741,7 @@ const rules$1 = {
|
|
|
18367
18741
|
// just a stub for testing.
|
|
18368
18742
|
return /*#__PURE__*/React__namespace.createElement("em", {
|
|
18369
18743
|
key: state.key
|
|
18370
|
-
},
|
|
18744
|
+
}, `[Widget: ${node.id}]`);
|
|
18371
18745
|
}
|
|
18372
18746
|
},
|
|
18373
18747
|
blockMath: {
|
|
@@ -18855,9 +19229,8 @@ const getWidget = name => {
|
|
|
18855
19229
|
}
|
|
18856
19230
|
|
|
18857
19231
|
// Allow widgets to specify a widget directly or via a function
|
|
18858
|
-
if (widgets[name]
|
|
18859
|
-
|
|
18860
|
-
return widgets[name].getWidget();
|
|
19232
|
+
if (widgets[name]?.getWidget) {
|
|
19233
|
+
return widgets[name].getWidget?.();
|
|
18861
19234
|
}
|
|
18862
19235
|
return widgets[name].widget;
|
|
18863
19236
|
};
|
|
@@ -19009,7 +19382,7 @@ const upgradeWidgetInfoToLatestVersion = oldWidgetInfo => {
|
|
|
19009
19382
|
options: newEditorProps
|
|
19010
19383
|
});
|
|
19011
19384
|
};
|
|
19012
|
-
const getRendererPropsForWidgetInfo = (widgetInfo, problemNum) => {
|
|
19385
|
+
const getRendererPropsForWidgetInfo = (widgetInfo, strings, problemNum) => {
|
|
19013
19386
|
const type = widgetInfo.type;
|
|
19014
19387
|
const widgetExports = widgets[type];
|
|
19015
19388
|
if (widgetExports == null) {
|
|
@@ -19030,7 +19403,7 @@ const getRendererPropsForWidgetInfo = (widgetInfo, problemNum) => {
|
|
|
19030
19403
|
transform = widgetExports.transform || ___default["default"].identity;
|
|
19031
19404
|
}
|
|
19032
19405
|
// widgetInfo.options are the widgetEditor's props:
|
|
19033
|
-
return transform(widgetInfo.options, problemNum);
|
|
19406
|
+
return transform(widgetInfo.options, strings, problemNum);
|
|
19034
19407
|
};
|
|
19035
19408
|
const traverseChildWidgets$3 = (widgetInfo, traverseRenderer) => {
|
|
19036
19409
|
if (!traverseRenderer) {
|
|
@@ -19374,24 +19747,26 @@ const isIdPathPrefix = function (prefixArray, wholeArray) {
|
|
|
19374
19747
|
* scoring, state serialization/deserialization, and focus management.
|
|
19375
19748
|
*/
|
|
19376
19749
|
class Renderer extends React__namespace.Component {
|
|
19750
|
+
_currentFocus;
|
|
19377
19751
|
// @ts-expect-error - TS2564 - Property '_foundTextNodes' has no initializer and is not definitely assigned in the constructor.
|
|
19378
|
-
|
|
19752
|
+
_foundTextNodes;
|
|
19379
19753
|
// @ts-expect-error - TS2564 - Property '_interactionTrackers' has no initializer and is not definitely assigned in the constructor.
|
|
19380
|
-
|
|
19754
|
+
_interactionTrackers;
|
|
19381
19755
|
// @ts-expect-error - TS2564 - Property '_isMounted' has no initializer and is not definitely assigned in the constructor.
|
|
19382
|
-
|
|
19756
|
+
_isMounted;
|
|
19383
19757
|
// @ts-expect-error - TS2564 - Property '_isTwoColumn' has no initializer and is not definitely assigned in the constructor.
|
|
19758
|
+
_isTwoColumn;
|
|
19384
19759
|
|
|
19385
19760
|
// The i18n linter.
|
|
19386
|
-
|
|
19761
|
+
_translationLinter;
|
|
19387
19762
|
_widgetContainers = new Map();
|
|
19388
|
-
|
|
19763
|
+
lastRenderedMarkdown;
|
|
19389
19764
|
// @ts-expect-error - TS2564 - Property 'reuseMarkdown' has no initializer and is not definitely assigned in the constructor.
|
|
19390
|
-
|
|
19765
|
+
reuseMarkdown;
|
|
19391
19766
|
// @ts-expect-error - TS2564 - Property 'translationIndex' has no initializer and is not definitely assigned in the constructor.
|
|
19392
|
-
|
|
19767
|
+
translationIndex;
|
|
19393
19768
|
// @ts-expect-error - TS2564 - Property 'widgetIds' has no initializer and is not definitely assigned in the constructor.
|
|
19394
|
-
|
|
19769
|
+
widgetIds;
|
|
19395
19770
|
static defaultProps = {
|
|
19396
19771
|
content: "",
|
|
19397
19772
|
widgets: {},
|
|
@@ -19590,9 +19965,12 @@ class Renderer extends React__namespace.Component {
|
|
|
19590
19965
|
problemNum
|
|
19591
19966
|
} = props;
|
|
19592
19967
|
const widgetsStartProps = {};
|
|
19968
|
+
const {
|
|
19969
|
+
strings
|
|
19970
|
+
} = this.props;
|
|
19593
19971
|
wonderStuffCore.entries(allWidgetInfo).forEach(_ref => {
|
|
19594
19972
|
let [key, widgetInfo] = _ref;
|
|
19595
|
-
widgetsStartProps[key] = getRendererPropsForWidgetInfo(widgetInfo, problemNum);
|
|
19973
|
+
widgetsStartProps[key] = getRendererPropsForWidgetInfo(widgetInfo, strings, problemNum);
|
|
19596
19974
|
});
|
|
19597
19975
|
|
|
19598
19976
|
// Call the onWidgetStartProps callback if it exists
|
|
@@ -21058,6 +21436,7 @@ class TextInput extends React__namespace.Component {
|
|
|
21058
21436
|
value: "",
|
|
21059
21437
|
disabled: false
|
|
21060
21438
|
};
|
|
21439
|
+
id;
|
|
21061
21440
|
constructor(props) {
|
|
21062
21441
|
super(props);
|
|
21063
21442
|
if (props.id) {
|
|
@@ -21383,6 +21762,7 @@ const {
|
|
|
21383
21762
|
captureScratchpadTouchStart: captureScratchpadTouchStart$2
|
|
21384
21763
|
} = Util;
|
|
21385
21764
|
class InputWithExamples extends React__namespace.Component {
|
|
21765
|
+
static contextType = PerseusI18nContext;
|
|
21386
21766
|
static defaultProps = {
|
|
21387
21767
|
type: "text",
|
|
21388
21768
|
shouldShowExamples: true,
|
|
@@ -21505,7 +21885,8 @@ class InputWithExamples extends React__namespace.Component {
|
|
|
21505
21885
|
id: this._getUniqueId()
|
|
21506
21886
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
21507
21887
|
content: examplesContent,
|
|
21508
|
-
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "input-with-examples")
|
|
21888
|
+
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "input-with-examples"),
|
|
21889
|
+
strings: this.context.strings
|
|
21509
21890
|
})));
|
|
21510
21891
|
}
|
|
21511
21892
|
_handleFocus = () => {
|
|
@@ -21564,7 +21945,7 @@ class SimpleKeypadInput extends React__namespace.Component {
|
|
|
21564
21945
|
|
|
21565
21946
|
blur() {
|
|
21566
21947
|
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
21567
|
-
this.refs.input
|
|
21948
|
+
this.refs.input?.blur(); // eslint-disable-line react/no-string-refs
|
|
21568
21949
|
}
|
|
21569
21950
|
|
|
21570
21951
|
getValue() {
|
|
@@ -21653,35 +22034,36 @@ const answerTypes = {
|
|
|
21653
22034
|
}
|
|
21654
22035
|
};
|
|
21655
22036
|
const formExamples$1 = {
|
|
21656
|
-
integer: function (options) {
|
|
21657
|
-
return
|
|
22037
|
+
integer: function (options, strings) {
|
|
22038
|
+
return strings.integerExample;
|
|
21658
22039
|
},
|
|
21659
|
-
proper: function (options) {
|
|
22040
|
+
proper: function (options, strings) {
|
|
21660
22041
|
if (options.simplify === "optional") {
|
|
21661
|
-
return
|
|
22042
|
+
return strings.properExample;
|
|
21662
22043
|
}
|
|
21663
|
-
return
|
|
22044
|
+
return strings.simplifiedProperExample;
|
|
21664
22045
|
},
|
|
21665
|
-
improper: function (options) {
|
|
22046
|
+
improper: function (options, strings) {
|
|
21666
22047
|
if (options.simplify === "optional") {
|
|
21667
|
-
return
|
|
22048
|
+
return strings.improperExample;
|
|
21668
22049
|
}
|
|
21669
|
-
return
|
|
22050
|
+
return strings.simplifiedImproperExample;
|
|
21670
22051
|
},
|
|
21671
|
-
mixed: function (options) {
|
|
21672
|
-
return
|
|
22052
|
+
mixed: function (options, strings) {
|
|
22053
|
+
return strings.mixedExample;
|
|
21673
22054
|
},
|
|
21674
|
-
decimal: function (options) {
|
|
21675
|
-
return
|
|
22055
|
+
decimal: function (options, strings) {
|
|
22056
|
+
return strings.decimalExample;
|
|
21676
22057
|
},
|
|
21677
|
-
percent: function (options) {
|
|
21678
|
-
return
|
|
22058
|
+
percent: function (options, strings) {
|
|
22059
|
+
return strings.percentExample;
|
|
21679
22060
|
},
|
|
21680
|
-
pi: function (options) {
|
|
21681
|
-
return
|
|
22061
|
+
pi: function (options, strings) {
|
|
22062
|
+
return strings.piExample;
|
|
21682
22063
|
}
|
|
21683
22064
|
};
|
|
21684
22065
|
class InputNumber extends React__namespace.Component {
|
|
22066
|
+
static contextType = PerseusI18nContext;
|
|
21685
22067
|
static defaultProps = {
|
|
21686
22068
|
currentValue: "",
|
|
21687
22069
|
size: "normal",
|
|
@@ -21770,7 +22152,7 @@ class InputNumber extends React__namespace.Component {
|
|
|
21770
22152
|
blurInputPath = inputPath => {
|
|
21771
22153
|
// eslint-disable-next-line react/no-string-refs
|
|
21772
22154
|
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
21773
|
-
this.refs.input
|
|
22155
|
+
this.refs.input?.blur();
|
|
21774
22156
|
};
|
|
21775
22157
|
getInputPaths = () => {
|
|
21776
22158
|
// The widget itself is an input, so we return a single empty list to
|
|
@@ -21795,21 +22177,19 @@ class InputNumber extends React__namespace.Component {
|
|
|
21795
22177
|
};
|
|
21796
22178
|
simpleValidate = (rubric, onInputError) => {
|
|
21797
22179
|
onInputError = onInputError || function () {};
|
|
21798
|
-
return InputNumber.validate(this.getUserInput(), rubric, onInputError);
|
|
22180
|
+
return InputNumber.validate(this.getUserInput(), rubric, this.context.strings, onInputError);
|
|
21799
22181
|
};
|
|
21800
22182
|
examples = () => {
|
|
22183
|
+
const {
|
|
22184
|
+
strings
|
|
22185
|
+
} = this.context;
|
|
21801
22186
|
const type = this.props.answerType;
|
|
21802
22187
|
const forms = answerTypes[type].forms.split(/\s*,\s*/);
|
|
21803
|
-
const examples = ___default["default"].map(forms,
|
|
21804
|
-
|
|
21805
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
21806
|
-
// eslint-disable-next-line @babel/no-invalid-this
|
|
21807
|
-
return formExamples$1[form](this.props);
|
|
21808
|
-
}, this);
|
|
21809
|
-
return [i18n__namespace._("**Your answer should be** ")].concat(examples);
|
|
22188
|
+
const examples = ___default["default"].map(forms, form => formExamples$1[form](this.props, strings));
|
|
22189
|
+
return [strings.yourAnswer].concat(examples);
|
|
21810
22190
|
};
|
|
21811
|
-
static validate(state, rubric) {
|
|
21812
|
-
let onInputError = arguments.length >
|
|
22191
|
+
static validate(state, rubric, strings) {
|
|
22192
|
+
let onInputError = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : () => {};
|
|
21813
22193
|
if (rubric.answerType == null) {
|
|
21814
22194
|
rubric.answerType = "number";
|
|
21815
22195
|
}
|
|
@@ -21823,7 +22203,7 @@ class InputNumber extends React__namespace.Component {
|
|
|
21823
22203
|
inexact: rubric.inexact || undefined,
|
|
21824
22204
|
maxError: rubric.maxError,
|
|
21825
22205
|
forms: answerTypes[rubric.answerType].forms
|
|
21826
|
-
});
|
|
22206
|
+
}, strings);
|
|
21827
22207
|
|
|
21828
22208
|
// We may have received TeX; try to parse it before grading.
|
|
21829
22209
|
// If `currentValue` is not TeX, this should be a no-op.
|
|
@@ -21938,14 +22318,16 @@ const answerFormButtons = [{
|
|
|
21938
22318
|
content: "\u03C0"
|
|
21939
22319
|
}];
|
|
21940
22320
|
const formExamples = {
|
|
21941
|
-
integer: () =>
|
|
21942
|
-
proper: form => form.simplify === "optional" ?
|
|
21943
|
-
improper: form => form.simplify === "optional" ?
|
|
21944
|
-
mixed: () =>
|
|
21945
|
-
decimal: () =>
|
|
21946
|
-
pi: () =>
|
|
22321
|
+
integer: (form, strings) => strings.integerExample,
|
|
22322
|
+
proper: (form, strings) => form.simplify === "optional" ? strings.properExample : strings.simplifiedProperExample,
|
|
22323
|
+
improper: (form, strings) => form.simplify === "optional" ? strings.improperExample : strings.simplifiedImproperExample,
|
|
22324
|
+
mixed: (form, strings) => strings.mixedExample,
|
|
22325
|
+
decimal: (form, strings) => strings.decimalExample,
|
|
22326
|
+
pi: (form, strings) => strings.piExample
|
|
21947
22327
|
};
|
|
21948
22328
|
class NumericInput extends React__namespace.Component {
|
|
22329
|
+
static contextType = PerseusI18nContext;
|
|
22330
|
+
inputRef;
|
|
21949
22331
|
static defaultProps = {
|
|
21950
22332
|
currentValue: "",
|
|
21951
22333
|
size: "normal",
|
|
@@ -21989,7 +22371,7 @@ class NumericInput extends React__namespace.Component {
|
|
|
21989
22371
|
}
|
|
21990
22372
|
return answerStrings[0];
|
|
21991
22373
|
}
|
|
21992
|
-
static validate(userInput, rubric) {
|
|
22374
|
+
static validate(userInput, rubric, strings) {
|
|
21993
22375
|
const defaultAnswerForms = answerFormButtons.map(e => e["value"])
|
|
21994
22376
|
// Don't default to validating the answer as a pi answer
|
|
21995
22377
|
// if answerForm isn't set on the answer
|
|
@@ -22015,7 +22397,7 @@ class NumericInput extends React__namespace.Component {
|
|
|
22015
22397
|
// TODO(merlob) backfill / delete
|
|
22016
22398
|
maxError: answer.maxError,
|
|
22017
22399
|
forms: validatorForms
|
|
22018
|
-
});
|
|
22400
|
+
}, strings);
|
|
22019
22401
|
};
|
|
22020
22402
|
|
|
22021
22403
|
// We may have received TeX; try to parse it before grading.
|
|
@@ -22098,13 +22480,12 @@ class NumericInput extends React__namespace.Component {
|
|
|
22098
22480
|
};
|
|
22099
22481
|
});
|
|
22100
22482
|
let examples = ___default["default"].map(forms, form => {
|
|
22101
|
-
|
|
22102
|
-
return formExamples[form.name](form);
|
|
22483
|
+
return formExamples[form.name](form, this.context.strings);
|
|
22103
22484
|
});
|
|
22104
22485
|
// Ensure no duplicate tooltip text from simplified and unsimplified
|
|
22105
22486
|
// versions of the same format
|
|
22106
22487
|
examples = ___default["default"].uniq(examples);
|
|
22107
|
-
return [
|
|
22488
|
+
return [this.context.strings.yourAnswer].concat(examples);
|
|
22108
22489
|
};
|
|
22109
22490
|
shouldShowExamples = () => {
|
|
22110
22491
|
const noFormsAccepted = this.props.answerForms?.length === 0;
|
|
@@ -22116,7 +22497,7 @@ class NumericInput extends React__namespace.Component {
|
|
|
22116
22497
|
return !noFormsAccepted && !allFormsAccepted;
|
|
22117
22498
|
};
|
|
22118
22499
|
simpleValidate = rubric => {
|
|
22119
|
-
return NumericInput.validate(this.getUserInput(), rubric);
|
|
22500
|
+
return NumericInput.validate(this.getUserInput(), rubric, this.context.strings);
|
|
22120
22501
|
};
|
|
22121
22502
|
focus = () => {
|
|
22122
22503
|
this.inputRef?.focus();
|
|
@@ -22162,7 +22543,7 @@ class NumericInput extends React__namespace.Component {
|
|
|
22162
22543
|
render() {
|
|
22163
22544
|
let labelText = this.props.labelText;
|
|
22164
22545
|
if (labelText == null || labelText === "") {
|
|
22165
|
-
labelText =
|
|
22546
|
+
labelText = this.context.strings.yourAnswerLabel;
|
|
22166
22547
|
}
|
|
22167
22548
|
|
|
22168
22549
|
// To right align a custom keypad we need to wrap it.
|
|
@@ -22309,11 +22690,12 @@ var NumericInput$1 = {
|
|
|
22309
22690
|
/* eslint-disable react/sort-comp */
|
|
22310
22691
|
const EN_DASH$1 = "\u2013";
|
|
22311
22692
|
class PassageRef extends React__namespace.Component {
|
|
22693
|
+
static contextType = PerseusI18nContext;
|
|
22312
22694
|
displayName = "PassageRef";
|
|
22313
22695
|
// @ts-expect-error - TS2564 - Property '_isMounted' has no initializer and is not definitely assigned in the constructor.
|
|
22314
|
-
|
|
22696
|
+
_isMounted;
|
|
22315
22697
|
// @ts-expect-error - TS2564 - Property '_throttledUpdateRange' has no initializer and is not definitely assigned in the constructor.
|
|
22316
|
-
|
|
22698
|
+
_throttledUpdateRange;
|
|
22317
22699
|
static defaultProps = {
|
|
22318
22700
|
passageNumber: 1,
|
|
22319
22701
|
referenceNumber: 1,
|
|
@@ -22333,18 +22715,21 @@ class PassageRef extends React__namespace.Component {
|
|
|
22333
22715
|
return removeDenylistProps(this.props);
|
|
22334
22716
|
};
|
|
22335
22717
|
render() {
|
|
22718
|
+
const {
|
|
22719
|
+
strings
|
|
22720
|
+
} = this.context;
|
|
22336
22721
|
const lineRange = this.state.lineRange;
|
|
22337
22722
|
let lineRangeOutput;
|
|
22338
22723
|
if (!lineRange) {
|
|
22339
|
-
lineRangeOutput =
|
|
22724
|
+
lineRangeOutput = strings.lineRange({
|
|
22340
22725
|
lineRange: `?${EN_DASH$1}?`
|
|
22341
22726
|
});
|
|
22342
22727
|
} else if (lineRange[0] === lineRange[1]) {
|
|
22343
|
-
lineRangeOutput =
|
|
22344
|
-
lineNumber: lineRange[0]
|
|
22728
|
+
lineRangeOutput = strings.lineNumber({
|
|
22729
|
+
lineNumber: String(lineRange[0])
|
|
22345
22730
|
});
|
|
22346
22731
|
} else {
|
|
22347
|
-
lineRangeOutput =
|
|
22732
|
+
lineRangeOutput = strings.lineRange({
|
|
22348
22733
|
lineRange: lineRange[0] + EN_DASH$1 + lineRange[1]
|
|
22349
22734
|
});
|
|
22350
22735
|
}
|
|
@@ -22784,7 +23169,7 @@ class Icon extends React__namespace.Component {
|
|
|
22784
23169
|
}
|
|
22785
23170
|
}
|
|
22786
23171
|
|
|
22787
|
-
function getA11yText(letter, checked, correct, crossedOut, showCorrectness) {
|
|
23172
|
+
function getA11yText(letter, checked, correct, crossedOut, showCorrectness, strings) {
|
|
22788
23173
|
// There are two pieces of metadata we want to add to each a11yText:
|
|
22789
23174
|
// whether the answer was checked/crossed-out/neither, and whether the
|
|
22790
23175
|
// answer is correct/incorrect/not-yet-revealed.
|
|
@@ -22793,45 +23178,45 @@ function getA11yText(letter, checked, correct, crossedOut, showCorrectness) {
|
|
|
22793
23178
|
// we've just enumerated all 9 possibilities as separate strings.
|
|
22794
23179
|
if (showCorrectness && correct) {
|
|
22795
23180
|
if (checked) {
|
|
22796
|
-
return
|
|
23181
|
+
return strings.choiceCheckedCorrect({
|
|
22797
23182
|
letter
|
|
22798
23183
|
});
|
|
22799
23184
|
}
|
|
22800
23185
|
if (crossedOut) {
|
|
22801
|
-
return
|
|
23186
|
+
return strings.choiceCrossedOutCorrect({
|
|
22802
23187
|
letter
|
|
22803
23188
|
});
|
|
22804
23189
|
}
|
|
22805
|
-
return
|
|
23190
|
+
return strings.choiceCorrect({
|
|
22806
23191
|
letter
|
|
22807
23192
|
});
|
|
22808
23193
|
}
|
|
22809
23194
|
if (showCorrectness && !correct) {
|
|
22810
23195
|
if (checked) {
|
|
22811
|
-
return
|
|
23196
|
+
return strings.choiceCheckedIncorrect({
|
|
22812
23197
|
letter
|
|
22813
23198
|
});
|
|
22814
23199
|
}
|
|
22815
23200
|
if (crossedOut) {
|
|
22816
|
-
return
|
|
23201
|
+
return strings.choiceCrossedOutIncorrect({
|
|
22817
23202
|
letter
|
|
22818
23203
|
});
|
|
22819
23204
|
}
|
|
22820
|
-
return
|
|
23205
|
+
return strings.choiceIncorrect({
|
|
22821
23206
|
letter
|
|
22822
23207
|
});
|
|
22823
23208
|
}
|
|
22824
23209
|
if (checked) {
|
|
22825
|
-
return
|
|
23210
|
+
return strings.choiceChecked({
|
|
22826
23211
|
letter
|
|
22827
23212
|
});
|
|
22828
23213
|
}
|
|
22829
23214
|
if (crossedOut) {
|
|
22830
|
-
return
|
|
23215
|
+
return strings.choiceCrossedOut({
|
|
22831
23216
|
letter
|
|
22832
23217
|
});
|
|
22833
23218
|
}
|
|
22834
|
-
return
|
|
23219
|
+
return strings.choice({
|
|
22835
23220
|
letter
|
|
22836
23221
|
});
|
|
22837
23222
|
}
|
|
@@ -22878,18 +23263,8 @@ const styles$z = aphrodite.StyleSheet.create({
|
|
|
22878
23263
|
* "choice letter". (For example, in English, `getChoiceLetter(0)` is "A",
|
|
22879
23264
|
* `getChoiceLetter(1)` is "B", etc.)
|
|
22880
23265
|
*/
|
|
22881
|
-
function getChoiceLetter(pos) {
|
|
22882
|
-
|
|
22883
|
-
* front of multiple-choice options. For instance, a multiple-choice
|
|
22884
|
-
* question with three options would display
|
|
22885
|
-
* (A) first option
|
|
22886
|
-
* (B) second option
|
|
22887
|
-
* (C) third option
|
|
22888
|
-
* There must be spaces between each of the different characters. The
|
|
22889
|
-
* characters will show up next to options in the order that they are
|
|
22890
|
-
* listed here. Most multiple choice questions have 5 or fewer options.
|
|
22891
|
-
*/
|
|
22892
|
-
const lettersString = i18n__namespace._("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z");
|
|
23266
|
+
function getChoiceLetter(pos, strings) {
|
|
23267
|
+
const lettersString = strings.letters;
|
|
22893
23268
|
const letters = lettersString.split(" ");
|
|
22894
23269
|
if (pos < letters.length) {
|
|
22895
23270
|
// If the position we need is listed in the localized string, use that.
|
|
@@ -22953,7 +23328,10 @@ function ChoiceInner(props) {
|
|
|
22953
23328
|
showCorrectness,
|
|
22954
23329
|
correct
|
|
22955
23330
|
} = props;
|
|
22956
|
-
const
|
|
23331
|
+
const {
|
|
23332
|
+
strings
|
|
23333
|
+
} = usePerseusI18n();
|
|
23334
|
+
const letter = getChoiceLetter(pos, strings);
|
|
22957
23335
|
if (!showCorrectness) {
|
|
22958
23336
|
return letter;
|
|
22959
23337
|
}
|
|
@@ -23099,24 +23477,24 @@ const styles$w = aphrodite.StyleSheet.create({
|
|
|
23099
23477
|
* ChoiceIcon visualizations but is meant to make the distinctions
|
|
23100
23478
|
* between the states more immediately clear to users.
|
|
23101
23479
|
*/
|
|
23102
|
-
function renderText(checked, correct, crossedOut) {
|
|
23480
|
+
function renderText(checked, correct, crossedOut, strings) {
|
|
23103
23481
|
if (correct) {
|
|
23104
23482
|
// For correct answers, we surface checked _or_ crossedOut state,
|
|
23105
23483
|
// because any interaction with the correct answer is noteworthy!
|
|
23106
23484
|
if (checked) {
|
|
23107
|
-
return
|
|
23485
|
+
return strings.correctSelected;
|
|
23108
23486
|
}
|
|
23109
23487
|
if (crossedOut) {
|
|
23110
|
-
return
|
|
23488
|
+
return strings.correctCrossedOut;
|
|
23111
23489
|
}
|
|
23112
|
-
return
|
|
23490
|
+
return strings.correct;
|
|
23113
23491
|
}
|
|
23114
23492
|
// But, for incorrect answers, we only surface checked state,
|
|
23115
23493
|
// because crossing out an incorrect answer is not noteworthy.
|
|
23116
23494
|
if (checked) {
|
|
23117
|
-
return
|
|
23495
|
+
return strings.incorrectSelected;
|
|
23118
23496
|
}
|
|
23119
|
-
return
|
|
23497
|
+
return strings.incorrect;
|
|
23120
23498
|
}
|
|
23121
23499
|
const OptionStatus = function (props) {
|
|
23122
23500
|
const {
|
|
@@ -23126,6 +23504,9 @@ const OptionStatus = function (props) {
|
|
|
23126
23504
|
previouslyAnswered,
|
|
23127
23505
|
reviewMode
|
|
23128
23506
|
} = props;
|
|
23507
|
+
const {
|
|
23508
|
+
strings
|
|
23509
|
+
} = usePerseusI18n();
|
|
23129
23510
|
|
|
23130
23511
|
// Option status is shown only in review mode, or for incorrectly
|
|
23131
23512
|
// answered items.
|
|
@@ -23145,7 +23526,7 @@ const OptionStatus = function (props) {
|
|
|
23145
23526
|
}
|
|
23146
23527
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
23147
23528
|
className: aphrodite.css(styles$v.text, textStyle)
|
|
23148
|
-
}, renderText(checked, correct, crossedOut));
|
|
23529
|
+
}, renderText(checked, correct, crossedOut, strings));
|
|
23149
23530
|
};
|
|
23150
23531
|
const styles$v = aphrodite.StyleSheet.create({
|
|
23151
23532
|
text: {
|
|
@@ -23192,6 +23573,9 @@ const Choice = function (props) {
|
|
|
23192
23573
|
forwardedRef
|
|
23193
23574
|
} = props;
|
|
23194
23575
|
const [isInputFocused, setIsInputFocused] = React.useState(false);
|
|
23576
|
+
const {
|
|
23577
|
+
strings
|
|
23578
|
+
} = usePerseusI18n();
|
|
23195
23579
|
React.useEffect(() => {
|
|
23196
23580
|
if (isInputFocused && disabled) {
|
|
23197
23581
|
setIsInputFocused(false);
|
|
@@ -23220,8 +23604,8 @@ const Choice = function (props) {
|
|
|
23220
23604
|
// However, we don't want to do this when we're in review mode in the
|
|
23221
23605
|
// content library.
|
|
23222
23606
|
const showDimmed = !reviewMode && apiOptions.readOnly || crossedOut;
|
|
23223
|
-
const letter = getChoiceLetter(pos);
|
|
23224
|
-
const a11yText = getA11yText(letter, checked, correct, crossedOut, showCorrectness);
|
|
23607
|
+
const letter = getChoiceLetter(pos, strings);
|
|
23608
|
+
const a11yText = getA11yText(letter, checked, correct, crossedOut, showCorrectness, strings);
|
|
23225
23609
|
const idFactory = wonderBlocksCore.useUniqueIdWithMock(`choice`);
|
|
23226
23610
|
const choiceId = idFactory.get(letter);
|
|
23227
23611
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
@@ -23326,15 +23710,15 @@ const Choice = function (props) {
|
|
|
23326
23710
|
close
|
|
23327
23711
|
} = _ref2;
|
|
23328
23712
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.PopoverContent, {
|
|
23329
|
-
title:
|
|
23330
|
-
content:
|
|
23713
|
+
title: strings.crossOut,
|
|
23714
|
+
content: strings.crossOutOption,
|
|
23331
23715
|
closeButtonVisible: true,
|
|
23332
23716
|
actions: /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, /*#__PURE__*/React__namespace.createElement(wonderBlocksLayout.Strut, {
|
|
23333
23717
|
size: wonderBlocksTokens.spacing.medium_16
|
|
23334
23718
|
}), /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
23335
23719
|
kind: "primary",
|
|
23336
|
-
"aria-label":
|
|
23337
|
-
letter: getChoiceLetter(pos)
|
|
23720
|
+
"aria-label": strings.crossOutChoice({
|
|
23721
|
+
letter: getChoiceLetter(pos, strings)
|
|
23338
23722
|
}),
|
|
23339
23723
|
disabled: apiOptions.readOnly || reviewMode,
|
|
23340
23724
|
onClick: () => {
|
|
@@ -23354,7 +23738,7 @@ const Choice = function (props) {
|
|
|
23354
23738
|
}
|
|
23355
23739
|
close();
|
|
23356
23740
|
}
|
|
23357
|
-
}, crossedOut ?
|
|
23741
|
+
}, crossedOut ? strings.bringBack : strings.crossOut))
|
|
23358
23742
|
});
|
|
23359
23743
|
}
|
|
23360
23744
|
}, _ref3 => {
|
|
@@ -23363,8 +23747,8 @@ const Choice = function (props) {
|
|
|
23363
23747
|
} = _ref3;
|
|
23364
23748
|
return /*#__PURE__*/React__namespace.createElement(Clickable__default["default"], {
|
|
23365
23749
|
onClick: open,
|
|
23366
|
-
"aria-label":
|
|
23367
|
-
letter: getChoiceLetter(pos)
|
|
23750
|
+
"aria-label": strings.openMenuForChoice({
|
|
23751
|
+
letter: getChoiceLetter(pos, strings)
|
|
23368
23752
|
}),
|
|
23369
23753
|
style: {
|
|
23370
23754
|
alignSelf: "center",
|
|
@@ -23414,6 +23798,9 @@ const ChoiceNoneAbove = function (props) {
|
|
|
23414
23798
|
forwardedRef,
|
|
23415
23799
|
...rest
|
|
23416
23800
|
} = props;
|
|
23801
|
+
const {
|
|
23802
|
+
strings
|
|
23803
|
+
} = usePerseusI18n();
|
|
23417
23804
|
const choiceProps = {
|
|
23418
23805
|
...rest,
|
|
23419
23806
|
content: showContent ? content :
|
|
@@ -23430,7 +23817,8 @@ const ChoiceNoneAbove = function (props) {
|
|
|
23430
23817
|
// just to render a string
|
|
23431
23818
|
React__namespace.createElement(Renderer, {
|
|
23432
23819
|
key: "noneOfTheAboveRenderer",
|
|
23433
|
-
content:
|
|
23820
|
+
content: strings.noneOfTheAbove,
|
|
23821
|
+
strings: strings
|
|
23434
23822
|
})
|
|
23435
23823
|
};
|
|
23436
23824
|
return /*#__PURE__*/React__namespace.createElement(Choice$1, _extends({}, choiceProps, {
|
|
@@ -23450,16 +23838,16 @@ const {
|
|
|
23450
23838
|
|
|
23451
23839
|
// exported for tests
|
|
23452
23840
|
|
|
23453
|
-
function getInstructionsText(multipleSelect, countChoices, numCorrect) {
|
|
23841
|
+
function getInstructionsText(multipleSelect, countChoices, numCorrect, strings) {
|
|
23454
23842
|
if (multipleSelect) {
|
|
23455
23843
|
if (countChoices) {
|
|
23456
|
-
return
|
|
23457
|
-
numCorrect: numCorrect
|
|
23844
|
+
return strings.chooseNumAnswers({
|
|
23845
|
+
numCorrect: String(numCorrect)
|
|
23458
23846
|
});
|
|
23459
23847
|
}
|
|
23460
|
-
return
|
|
23848
|
+
return strings.chooseAllAnswers;
|
|
23461
23849
|
}
|
|
23462
|
-
return
|
|
23850
|
+
return strings.chooseOneAnswer;
|
|
23463
23851
|
}
|
|
23464
23852
|
const BaseRadio = function (props) {
|
|
23465
23853
|
const {
|
|
@@ -23474,6 +23862,9 @@ const BaseRadio = function (props) {
|
|
|
23474
23862
|
isLastUsedWidget,
|
|
23475
23863
|
registerFocusFunction
|
|
23476
23864
|
} = props;
|
|
23865
|
+
const {
|
|
23866
|
+
strings
|
|
23867
|
+
} = usePerseusI18n();
|
|
23477
23868
|
|
|
23478
23869
|
// useEffect doesn't have previous props
|
|
23479
23870
|
const prevReviewModeRubric = React.useRef();
|
|
@@ -23580,7 +23971,7 @@ const BaseRadio = function (props) {
|
|
|
23580
23971
|
const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
|
|
23581
23972
|
const className = classNames__default["default"]("perseus-widget-radio", !editMode && "perseus-rendered-radio", aphrodite.css(styles$t.radio, styles$t.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$t.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$t.radioContainerLastHighlighted));
|
|
23582
23973
|
const instructionsClassName = classNames__default["default"]("instructions", aphrodite.css(styles$t.instructions, isMobile && styles$t.instructionsMobile));
|
|
23583
|
-
const instructions = getInstructionsText(multipleSelect, countChoices, numCorrect);
|
|
23974
|
+
const instructions = getInstructionsText(multipleSelect, countChoices, numCorrect, strings);
|
|
23584
23975
|
const responsiveClassName = aphrodite.css(styles$t.responsiveFieldset);
|
|
23585
23976
|
const fieldset = /*#__PURE__*/React__namespace.createElement("fieldset", {
|
|
23586
23977
|
className: `perseus-widget-radio-fieldset ${responsiveClassName}`
|
|
@@ -23803,8 +24194,9 @@ const styles$t = aphrodite.StyleSheet.create({
|
|
|
23803
24194
|
// RenderProps is the return type for radio.jsx#transform
|
|
23804
24195
|
|
|
23805
24196
|
class Radio$1 extends React__namespace.Component {
|
|
24197
|
+
static contextType = PerseusI18nContext;
|
|
23806
24198
|
// @ts-expect-error - TS2564 - Property 'focusFunction' has no initializer and is not definitely assigned in the constructor.
|
|
23807
|
-
|
|
24199
|
+
focusFunction;
|
|
23808
24200
|
static defaultProps = {
|
|
23809
24201
|
choices: [],
|
|
23810
24202
|
multipleSelect: false,
|
|
@@ -23813,7 +24205,7 @@ class Radio$1 extends React__namespace.Component {
|
|
|
23813
24205
|
linterContext: PerseusLinter.linterContextDefault,
|
|
23814
24206
|
showSolutions: "none"
|
|
23815
24207
|
};
|
|
23816
|
-
static validate(userInput, rubric) {
|
|
24208
|
+
static validate(userInput, rubric, strings) {
|
|
23817
24209
|
const numSelected = userInput.choicesSelected.reduce((sum, selected) => {
|
|
23818
24210
|
return sum + (selected ? 1 : 0);
|
|
23819
24211
|
}, 0);
|
|
@@ -23826,7 +24218,7 @@ class Radio$1 extends React__namespace.Component {
|
|
|
23826
24218
|
if (userInput.numCorrect && userInput.numCorrect > 1 && numSelected !== userInput.numCorrect) {
|
|
23827
24219
|
return {
|
|
23828
24220
|
type: "invalid",
|
|
23829
|
-
message:
|
|
24221
|
+
message: strings.chooseCorrectNum
|
|
23830
24222
|
};
|
|
23831
24223
|
// If NOTA and some other answer are checked, ...
|
|
23832
24224
|
}
|
|
@@ -23834,7 +24226,7 @@ class Radio$1 extends React__namespace.Component {
|
|
|
23834
24226
|
if (userInput.noneOfTheAboveSelected && numSelected > 1) {
|
|
23835
24227
|
return {
|
|
23836
24228
|
type: "invalid",
|
|
23837
|
-
message:
|
|
24229
|
+
message: strings.notNoneOfTheAbove
|
|
23838
24230
|
};
|
|
23839
24231
|
}
|
|
23840
24232
|
const correct = userInput.choicesSelected.every((selected, i) => {
|
|
@@ -23968,7 +24360,8 @@ class Radio$1 extends React__namespace.Component {
|
|
|
23968
24360
|
..._this.props.linterContext,
|
|
23969
24361
|
// @ts-expect-error - TS2322 - Type '{ blockHighlight: true; contentType: string; highlightLint: boolean; paths: readonly string[]; stack: readonly string[]; }' is not assignable to type 'LinterContextProps'.
|
|
23970
24362
|
blockHighlight: true
|
|
23971
|
-
}
|
|
24363
|
+
},
|
|
24364
|
+
strings: _this.context.strings
|
|
23972
24365
|
});
|
|
23973
24366
|
};
|
|
23974
24367
|
})();
|
|
@@ -24041,7 +24434,7 @@ class Radio$1 extends React__namespace.Component {
|
|
|
24041
24434
|
return Radio$1.getUserInputFromProps(this.props);
|
|
24042
24435
|
};
|
|
24043
24436
|
simpleValidate = rubric => {
|
|
24044
|
-
return Radio$1.validate(this.getUserInput(), rubric);
|
|
24437
|
+
return Radio$1.validate(this.getUserInput(), rubric, this.context.strings);
|
|
24045
24438
|
};
|
|
24046
24439
|
|
|
24047
24440
|
/**
|
|
@@ -24110,6 +24503,9 @@ class Radio$1 extends React__namespace.Component {
|
|
|
24110
24503
|
const {
|
|
24111
24504
|
choices
|
|
24112
24505
|
} = this.props;
|
|
24506
|
+
const {
|
|
24507
|
+
strings
|
|
24508
|
+
} = this.context;
|
|
24113
24509
|
let choiceStates;
|
|
24114
24510
|
if (this.props.static) {
|
|
24115
24511
|
choiceStates = choices.map(choice => ({
|
|
@@ -24164,11 +24560,7 @@ class Radio$1 extends React__namespace.Component {
|
|
|
24164
24560
|
}));
|
|
24165
24561
|
}
|
|
24166
24562
|
const choicesProp = choices.map((choice, i) => {
|
|
24167
|
-
const content = choice.isNoneOfTheAbove && !choice.content ?
|
|
24168
|
-
// we use i18n._ instead of $_ here because the content
|
|
24169
|
-
// sent to a renderer needs to be a string, not a react
|
|
24170
|
-
// node (/renderable/fragment).
|
|
24171
|
-
i18n__namespace._("None of the above") : choice.content;
|
|
24563
|
+
const content = choice.isNoneOfTheAbove && !choice.content ? strings.noneOfTheAbove : choice.content;
|
|
24172
24564
|
const {
|
|
24173
24565
|
selected,
|
|
24174
24566
|
crossedOut,
|
|
@@ -24226,14 +24618,8 @@ const {
|
|
|
24226
24618
|
random
|
|
24227
24619
|
} = Util;
|
|
24228
24620
|
|
|
24229
|
-
// Represents choices that we automatically re-order if encountered.
|
|
24230
|
-
// Note: these are in the reversed (incorrect) order that we will swap, if
|
|
24231
|
-
// found.
|
|
24232
|
-
// Note 2: these are internationalized when compared later on.
|
|
24233
|
-
const ReversedChoices = [[i18n__namespace._("False"), i18n__namespace._("True")], [i18n__namespace._("No"), i18n__namespace._("Yes")]];
|
|
24234
|
-
|
|
24235
24621
|
// Transforms the choices for display.
|
|
24236
|
-
const _choiceTransform = (widgetOptions, problemNum) => {
|
|
24622
|
+
const _choiceTransform = (widgetOptions, strings, problemNum) => {
|
|
24237
24623
|
const _maybeRandomize = function (array) {
|
|
24238
24624
|
const randomSeed = problemNum === undefined ? random : problemNum;
|
|
24239
24625
|
// NOTE: `problemNum` will only be set when the radio widget is
|
|
@@ -24262,6 +24648,11 @@ const _choiceTransform = (widgetOptions, problemNum) => {
|
|
|
24262
24648
|
return newChoices;
|
|
24263
24649
|
};
|
|
24264
24650
|
const enforceOrdering = choices => {
|
|
24651
|
+
// Represents choices that we automatically re-order if encountered.
|
|
24652
|
+
// Note: these are in the reversed (incorrect) order that we will swap, if
|
|
24653
|
+
// found.
|
|
24654
|
+
// Note 2: these are internationalized when compared later on.
|
|
24655
|
+
const ReversedChoices = [[strings.false, strings.true], [strings.no, strings.yes]];
|
|
24265
24656
|
const content = choices.map(c => c.content);
|
|
24266
24657
|
if (ReversedChoices.some(reversed => ___default["default"].isEqual(content, reversed))) {
|
|
24267
24658
|
return [choices[1], choices[0]];
|
|
@@ -24288,8 +24679,8 @@ const _choiceTransform = (widgetOptions, problemNum) => {
|
|
|
24288
24679
|
// 1) we randomize the order first
|
|
24289
24680
|
_maybeRandomize(choices)));
|
|
24290
24681
|
};
|
|
24291
|
-
const transform = (widgetOptions, problemNum) => {
|
|
24292
|
-
const choices = _choiceTransform(widgetOptions, problemNum);
|
|
24682
|
+
const transform = (widgetOptions, strings, problemNum) => {
|
|
24683
|
+
const choices = _choiceTransform(widgetOptions, strings, problemNum);
|
|
24293
24684
|
const numCorrect = ___default["default"].reduce(widgetOptions.choices, function (memo, choice) {
|
|
24294
24685
|
return choice.correct ? memo + 1 : memo;
|
|
24295
24686
|
}, 0);
|
|
@@ -24362,6 +24753,7 @@ const WidgetJsonifyDeprecated = {
|
|
|
24362
24753
|
|
|
24363
24754
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
24364
24755
|
class Categorizer extends React__namespace.Component {
|
|
24756
|
+
static contextType = PerseusI18nContext;
|
|
24365
24757
|
static defaultProps = {
|
|
24366
24758
|
items: [],
|
|
24367
24759
|
categories: [],
|
|
@@ -24410,7 +24802,8 @@ class Categorizer extends React__namespace.Component {
|
|
|
24410
24802
|
key: i
|
|
24411
24803
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
24412
24804
|
content: category,
|
|
24413
|
-
linterContext: this.props.linterContext
|
|
24805
|
+
linterContext: this.props.linterContext,
|
|
24806
|
+
strings: this.context.strings
|
|
24414
24807
|
}));
|
|
24415
24808
|
}))), /*#__PURE__*/React__namespace.createElement("tbody", null, indexedItems.map(indexedItem => {
|
|
24416
24809
|
const item = indexedItem[0];
|
|
@@ -24422,7 +24815,8 @@ class Categorizer extends React__namespace.Component {
|
|
|
24422
24815
|
// @ts-expect-error - TS2322 - Type 'string | number' is not assignable to type 'string | undefined'.
|
|
24423
24816
|
, {
|
|
24424
24817
|
content: item,
|
|
24425
|
-
linterContext: this.props.linterContext
|
|
24818
|
+
linterContext: this.props.linterContext,
|
|
24819
|
+
strings: this.context.strings
|
|
24426
24820
|
})), self.props.categories.map((catName, catNum) => {
|
|
24427
24821
|
const selected = self.props.values[itemNum] === catNum;
|
|
24428
24822
|
return /*#__PURE__*/React__namespace.createElement("td", {
|
|
@@ -24466,9 +24860,9 @@ class Categorizer extends React__namespace.Component {
|
|
|
24466
24860
|
this.props.trackInteraction();
|
|
24467
24861
|
}
|
|
24468
24862
|
simpleValidate = rubric => {
|
|
24469
|
-
return Categorizer.validate(this.getUserInput(), rubric);
|
|
24863
|
+
return Categorizer.validate(this.getUserInput(), rubric, this.context.strings);
|
|
24470
24864
|
};
|
|
24471
|
-
static validate(userInput, rubric) {
|
|
24865
|
+
static validate(userInput, rubric, strings) {
|
|
24472
24866
|
let completed = true;
|
|
24473
24867
|
let allCorrect = true;
|
|
24474
24868
|
rubric.values.forEach((value, i) => {
|
|
@@ -24482,7 +24876,7 @@ class Categorizer extends React__namespace.Component {
|
|
|
24482
24876
|
if (!completed) {
|
|
24483
24877
|
return {
|
|
24484
24878
|
type: "invalid",
|
|
24485
|
-
message:
|
|
24879
|
+
message: strings.invalidSelection
|
|
24486
24880
|
};
|
|
24487
24881
|
}
|
|
24488
24882
|
return {
|
|
@@ -24796,6 +25190,7 @@ var CSProgram$1 = {
|
|
|
24796
25190
|
// TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
|
|
24797
25191
|
|
|
24798
25192
|
class Definition extends React__namespace.Component {
|
|
25193
|
+
static contextType = PerseusI18nContext;
|
|
24799
25194
|
static defaultProps = {
|
|
24800
25195
|
togglePrompt: "define me",
|
|
24801
25196
|
definition: "definition goes here"
|
|
@@ -24828,7 +25223,8 @@ class Definition extends React__namespace.Component {
|
|
|
24828
25223
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
24829
25224
|
apiOptions: this.props.apiOptions,
|
|
24830
25225
|
content: this.props.definition,
|
|
24831
|
-
widgets: this.props.widgets
|
|
25226
|
+
widgets: this.props.widgets,
|
|
25227
|
+
strings: this.context.strings
|
|
24832
25228
|
})),
|
|
24833
25229
|
opened: activeDefinitionId === this.props.widgetId,
|
|
24834
25230
|
onClose: () => setActiveDefinitionId(null),
|
|
@@ -24874,6 +25270,7 @@ var Definition$1 = {
|
|
|
24874
25270
|
// The props are type `any` on purpose so that this can receive props
|
|
24875
25271
|
// from any deprecated widget
|
|
24876
25272
|
class DeprecatedStandin extends React__default["default"].Component {
|
|
25273
|
+
static contextType = PerseusI18nContext;
|
|
24877
25274
|
static validate(userInput, rubric) {
|
|
24878
25275
|
// Since this mean to replace an existing widget the learner
|
|
24879
25276
|
// WILL earn points for this widget
|
|
@@ -24897,7 +25294,7 @@ class DeprecatedStandin extends React__default["default"].Component {
|
|
|
24897
25294
|
paddingBottom: 8
|
|
24898
25295
|
}
|
|
24899
25296
|
}, /*#__PURE__*/React__default["default"].createElement(Banner__default["default"], {
|
|
24900
|
-
text:
|
|
25297
|
+
text: this.context.strings.deprecatedStandin,
|
|
24901
25298
|
kind: "info",
|
|
24902
25299
|
layout: "full-width"
|
|
24903
25300
|
}));
|
|
@@ -25014,6 +25411,7 @@ function mediaQueryIsMatched(mediaQuery) {
|
|
|
25014
25411
|
return window.matchMedia(mediaQuery).matches;
|
|
25015
25412
|
}
|
|
25016
25413
|
class Explanation extends React__namespace.Component {
|
|
25414
|
+
static contextType = PerseusI18nContext;
|
|
25017
25415
|
static defaultProps = {
|
|
25018
25416
|
showPrompt: "Explain",
|
|
25019
25417
|
hidePrompt: "Hide explanation",
|
|
@@ -25098,7 +25496,8 @@ class Explanation extends React__namespace.Component {
|
|
|
25098
25496
|
apiOptions: this.props.apiOptions,
|
|
25099
25497
|
content: this.props.explanation,
|
|
25100
25498
|
widgets: this.props.widgets,
|
|
25101
|
-
linterContext: this.props.linterContext
|
|
25499
|
+
linterContext: this.props.linterContext,
|
|
25500
|
+
strings: this.context.strings
|
|
25102
25501
|
})))));
|
|
25103
25502
|
}
|
|
25104
25503
|
getUserInput = () => {
|
|
@@ -25161,6 +25560,7 @@ var Explanation$1 = {
|
|
|
25161
25560
|
};
|
|
25162
25561
|
|
|
25163
25562
|
class GradedGroupAnswerBar extends React__namespace.Component {
|
|
25563
|
+
static contextType = PerseusI18nContext;
|
|
25164
25564
|
render() {
|
|
25165
25565
|
const {
|
|
25166
25566
|
apiOptions,
|
|
@@ -25168,6 +25568,13 @@ class GradedGroupAnswerBar extends React__namespace.Component {
|
|
|
25168
25568
|
onCheckAnswer,
|
|
25169
25569
|
onNextQuestion
|
|
25170
25570
|
} = this.props;
|
|
25571
|
+
const {
|
|
25572
|
+
keepTrying,
|
|
25573
|
+
tryAgain,
|
|
25574
|
+
check,
|
|
25575
|
+
correctExcited,
|
|
25576
|
+
nextQuestion
|
|
25577
|
+
} = this.context.strings;
|
|
25171
25578
|
const answerBarStyle = {
|
|
25172
25579
|
...styles$o.answerBar,
|
|
25173
25580
|
backgroundColor: answerBarState === "CORRECT" ? wonderBlocksTokens.color.offWhite : "white",
|
|
@@ -25182,10 +25589,10 @@ class GradedGroupAnswerBar extends React__namespace.Component {
|
|
|
25182
25589
|
style: {
|
|
25183
25590
|
marginLeft: 8
|
|
25184
25591
|
}
|
|
25185
|
-
},
|
|
25592
|
+
}, keepTrying)) : /*#__PURE__*/React__namespace.createElement("span", null); // empty span keeps the button on the right side
|
|
25186
25593
|
|
|
25187
25594
|
if (answerBarState !== "CORRECT") {
|
|
25188
|
-
const buttonLabel = answerBarState === "INCORRECT" ?
|
|
25595
|
+
const buttonLabel = answerBarState === "INCORRECT" ? tryAgain : check;
|
|
25189
25596
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
25190
25597
|
style: answerBarStyle
|
|
25191
25598
|
}, message, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
@@ -25208,13 +25615,13 @@ class GradedGroupAnswerBar extends React__namespace.Component {
|
|
|
25208
25615
|
}
|
|
25209
25616
|
}))), /*#__PURE__*/React__namespace.createElement("span", {
|
|
25210
25617
|
role: "alert",
|
|
25211
|
-
"aria-label":
|
|
25618
|
+
"aria-label": correctExcited,
|
|
25212
25619
|
style: {
|
|
25213
25620
|
marginLeft: 8
|
|
25214
25621
|
}
|
|
25215
|
-
},
|
|
25622
|
+
}, correctExcited)), onNextQuestion && /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
25216
25623
|
onClick: onNextQuestion
|
|
25217
|
-
},
|
|
25624
|
+
}, nextQuestion));
|
|
25218
25625
|
}
|
|
25219
25626
|
}
|
|
25220
25627
|
const fontSize = 17;
|
|
@@ -25270,10 +25677,6 @@ const getNextState = (currentState, answerable) => {
|
|
|
25270
25677
|
}
|
|
25271
25678
|
};
|
|
25272
25679
|
|
|
25273
|
-
// Prepended to all invalid messages to make the widget messages a bit clearer
|
|
25274
|
-
const INVALID_MESSAGE_PREFIX = i18n__namespace._("We couldn't grade your answer.");
|
|
25275
|
-
const DEFAULT_INVALID_MESSAGE = i18n__namespace._("It looks like you left something blank or ") + i18n__namespace._("entered in an invalid answer.");
|
|
25276
|
-
|
|
25277
25680
|
// exports has no 'transform'
|
|
25278
25681
|
|
|
25279
25682
|
// A Graded Group is more or less a Group widget that displays a check
|
|
@@ -25281,6 +25684,7 @@ const DEFAULT_INVALID_MESSAGE = i18n__namespace._("It looks like you left someth
|
|
|
25281
25684
|
// the stuff inside and displays feedback about whether the inputted answer was
|
|
25282
25685
|
// correct or not.
|
|
25283
25686
|
class GradedGroup extends React__namespace.Component {
|
|
25687
|
+
static contextType = PerseusI18nContext;
|
|
25284
25688
|
static defaultProps = {
|
|
25285
25689
|
title: "",
|
|
25286
25690
|
content: "",
|
|
@@ -25342,8 +25746,13 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25342
25746
|
// eslint-disable-next-line react/no-string-refs
|
|
25343
25747
|
// @ts-expect-error - TS2339 - Property 'score' does not exist on type 'ReactInstance'.
|
|
25344
25748
|
const score = this.refs.renderer.score();
|
|
25749
|
+
const {
|
|
25750
|
+
INVALID_MESSAGE_PREFIX,
|
|
25751
|
+
DEFAULT_INVALID_MESSAGE_1,
|
|
25752
|
+
DEFAULT_INVALID_MESSAGE_2
|
|
25753
|
+
} = this.context.strings;
|
|
25345
25754
|
const status = score.type === "points" ? score.total === score.earned ? GRADING_STATUSES.correct : GRADING_STATUSES.incorrect : GRADING_STATUSES.invalid;
|
|
25346
|
-
const message = score.type === "points" ? score.message || "" : score.message ? `${INVALID_MESSAGE_PREFIX} ${score.message}` : `${INVALID_MESSAGE_PREFIX} ${
|
|
25755
|
+
const message = score.type === "points" ? score.message || "" : score.message ? `${INVALID_MESSAGE_PREFIX} ${score.message}` : `${INVALID_MESSAGE_PREFIX} ${DEFAULT_INVALID_MESSAGE_1}${DEFAULT_INVALID_MESSAGE_2}`;
|
|
25347
25756
|
this.setState({
|
|
25348
25757
|
status: status,
|
|
25349
25758
|
message: message,
|
|
@@ -25405,8 +25814,7 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25405
25814
|
color: "#526f03"
|
|
25406
25815
|
}
|
|
25407
25816
|
}));
|
|
25408
|
-
|
|
25409
|
-
gradeStatus = i18n__namespace._("Correct");
|
|
25817
|
+
gradeStatus = this.context.strings.correct;
|
|
25410
25818
|
} else if (this.state.status === GRADING_STATUSES.incorrect) {
|
|
25411
25819
|
// TODO(jeremy): update to a WB colour
|
|
25412
25820
|
// @ts-expect-error - TS2322 - Type 'Element' is not assignable to type 'null'.
|
|
@@ -25415,8 +25823,7 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25415
25823
|
color: "#ff5454"
|
|
25416
25824
|
}
|
|
25417
25825
|
}));
|
|
25418
|
-
|
|
25419
|
-
gradeStatus = i18n__namespace._("Incorrect");
|
|
25826
|
+
gradeStatus = this.context.strings.incorrect;
|
|
25420
25827
|
}
|
|
25421
25828
|
const mobileClass = this.props.inGradedGroupSet ? aphrodite.css(styles$n.gradedGroupInSet) : aphrodite.css(styles$n.gradedGroup);
|
|
25422
25829
|
const classes = classNames__default["default"]({
|
|
@@ -25446,7 +25853,8 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25446
25853
|
readOnly
|
|
25447
25854
|
},
|
|
25448
25855
|
onInteractWithWidget: this._onInteractWithWidget,
|
|
25449
|
-
linterContext: this.props.linterContext
|
|
25856
|
+
linterContext: this.props.linterContext,
|
|
25857
|
+
strings: this.context.strings
|
|
25450
25858
|
})), !apiOptions.isMobile && icon && /*#__PURE__*/React__namespace.createElement("div", {
|
|
25451
25859
|
className: "group-icon"
|
|
25452
25860
|
}, icon), !apiOptions.isMobile && gradeStatus && /*#__PURE__*/React__namespace.createElement("div", {
|
|
@@ -25460,14 +25868,14 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25460
25868
|
kind: "secondary",
|
|
25461
25869
|
disabled: this.props.apiOptions.readOnly,
|
|
25462
25870
|
onClick: this._checkAnswer
|
|
25463
|
-
},
|
|
25871
|
+
}, this.context.strings.check), !apiOptions.isMobile && isCorrect && this.props.onNextQuestion && /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
25464
25872
|
kind: "secondary",
|
|
25465
25873
|
disabled: this.props.apiOptions.readOnly,
|
|
25466
25874
|
onClick: this.props.onNextQuestion,
|
|
25467
25875
|
style: {
|
|
25468
25876
|
marginLeft: 5
|
|
25469
25877
|
}
|
|
25470
|
-
},
|
|
25878
|
+
}, this.context.strings.nextQuestion), this.props.hint && this.props.hint.content && (this.state.showHint ? /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("button", {
|
|
25471
25879
|
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
|
|
25472
25880
|
tabIndex: "0",
|
|
25473
25881
|
className: aphrodite.css(styles$n.explanationTitle),
|
|
@@ -25481,11 +25889,12 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25481
25889
|
showHint: false
|
|
25482
25890
|
});
|
|
25483
25891
|
}
|
|
25484
|
-
},
|
|
25892
|
+
}, this.context.strings.hideExplanation), /*#__PURE__*/React__namespace.createElement(Renderer, _extends({}, this.props.hint, {
|
|
25485
25893
|
// eslint-disable-next-line react/no-string-refs
|
|
25486
25894
|
ref: "hints-renderer",
|
|
25487
25895
|
apiOptions: apiOptions,
|
|
25488
|
-
linterContext: this.props.linterContext
|
|
25896
|
+
linterContext: this.props.linterContext,
|
|
25897
|
+
strings: this.context.strings
|
|
25489
25898
|
}))) :
|
|
25490
25899
|
/*#__PURE__*/
|
|
25491
25900
|
// Not using Button here bc the styles won't work.
|
|
@@ -25503,7 +25912,7 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25503
25912
|
});
|
|
25504
25913
|
},
|
|
25505
25914
|
className: aphrodite.css(styles$n.showHintLink)
|
|
25506
|
-
},
|
|
25915
|
+
}, this.context.strings.explain)), apiOptions.isMobile && answerBarState !== "HIDDEN" && /*#__PURE__*/React__namespace.createElement(GradedGroupAnswerBar, {
|
|
25507
25916
|
apiOptions: apiOptions,
|
|
25508
25917
|
answerBarState: answerBarState,
|
|
25509
25918
|
onCheckAnswer: this._checkAnswer,
|
|
@@ -25575,6 +25984,7 @@ var GradedGroup$1 = {
|
|
|
25575
25984
|
};
|
|
25576
25985
|
|
|
25577
25986
|
class Indicators extends React__namespace.Component {
|
|
25987
|
+
static contextType = PerseusI18nContext;
|
|
25578
25988
|
handleKeyDown = (e, i) => {
|
|
25579
25989
|
if (e.key === "Enter" || e.key === " ") {
|
|
25580
25990
|
this.props.onChangeCurrentGroup(i);
|
|
@@ -25594,7 +26004,7 @@ class Indicators extends React__namespace.Component {
|
|
|
25594
26004
|
key: title
|
|
25595
26005
|
}, /*#__PURE__*/React__namespace.createElement(Clickable__default["default"], {
|
|
25596
26006
|
role: "button",
|
|
25597
|
-
"aria-label":
|
|
26007
|
+
"aria-label": this.context.strings.skipToTitle({
|
|
25598
26008
|
title
|
|
25599
26009
|
}),
|
|
25600
26010
|
style: styles$m.indicatorButton,
|
|
@@ -25612,7 +26022,7 @@ class Indicators extends React__namespace.Component {
|
|
|
25612
26022
|
style: styles$m.indicatorDotActive
|
|
25613
26023
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
25614
26024
|
className: aphrodite.css(a11y.srOnly)
|
|
25615
|
-
},
|
|
26025
|
+
}, this.context.strings.current)));
|
|
25616
26026
|
}));
|
|
25617
26027
|
}));
|
|
25618
26028
|
}
|
|
@@ -25624,7 +26034,7 @@ class Indicators extends React__namespace.Component {
|
|
|
25624
26034
|
// are currently a little confusing.
|
|
25625
26035
|
class GradedGroupSet extends React__namespace.Component {
|
|
25626
26036
|
// @ts-expect-error - TS2564 - Property '_childGroup' has no initializer and is not definitely assigned in the constructor.
|
|
25627
|
-
|
|
26037
|
+
_childGroup;
|
|
25628
26038
|
static defaultProps = {
|
|
25629
26039
|
gradedGroups: [],
|
|
25630
26040
|
linterContext: PerseusLinter.linterContextDefault
|
|
@@ -25703,7 +26113,7 @@ class GradedGroupSet extends React__namespace.Component {
|
|
|
25703
26113
|
}
|
|
25704
26114
|
const currentGroup = this.props.gradedGroups[this.state.currentGroup];
|
|
25705
26115
|
if (!currentGroup) {
|
|
25706
|
-
return /*#__PURE__*/React__namespace.createElement("span", null,
|
|
26116
|
+
return /*#__PURE__*/React__namespace.createElement("span", null, "No current group...");
|
|
25707
26117
|
}
|
|
25708
26118
|
const numGroups = this.props.gradedGroups.length;
|
|
25709
26119
|
const handleNextQuestion = this.state.currentGroup < numGroups - 1 ? this.handleNextQuestion : null;
|
|
@@ -25826,6 +26236,7 @@ const styles$m = aphrodite.StyleSheet.create({
|
|
|
25826
26236
|
* ButtonGroup is an aesthetically pleasing group of buttons.
|
|
25827
26237
|
*/
|
|
25828
26238
|
class ButtonGroup extends React__namespace.Component {
|
|
26239
|
+
container;
|
|
25829
26240
|
static defaultProps = {
|
|
25830
26241
|
value: null,
|
|
25831
26242
|
allowEmpty: true
|
|
@@ -26675,6 +27086,8 @@ class FunctionGrapher extends React__namespace.Component {
|
|
|
26675
27086
|
|
|
26676
27087
|
/* Widget and editor. */
|
|
26677
27088
|
class Grapher extends React__namespace.Component {
|
|
27089
|
+
horizHairline;
|
|
27090
|
+
vertHairline;
|
|
26678
27091
|
static defaultProps = DEFAULT_GRAPHER_PROPS;
|
|
26679
27092
|
render() {
|
|
26680
27093
|
const type = this.props.plot.type;
|
|
@@ -26881,6 +27294,8 @@ var Grapher$1 = {
|
|
|
26881
27294
|
// exports has no 'transform'
|
|
26882
27295
|
|
|
26883
27296
|
class Group extends React__namespace.Component {
|
|
27297
|
+
static contextType = PerseusI18nContext;
|
|
27298
|
+
rendererRef;
|
|
26884
27299
|
static defaultProps = {
|
|
26885
27300
|
content: "",
|
|
26886
27301
|
widgets: {},
|
|
@@ -26997,7 +27412,8 @@ class Group extends React__namespace.Component {
|
|
|
26997
27412
|
findExternalWidgets: this.props.findWidgets,
|
|
26998
27413
|
reviewMode: !!this.props.reviewModeRubric,
|
|
26999
27414
|
onInteractWithWidget: onInteractWithWidget,
|
|
27000
|
-
linterContext: this.props.linterContext
|
|
27415
|
+
linterContext: this.props.linterContext,
|
|
27416
|
+
strings: this.context.strings
|
|
27001
27417
|
}), this.props.icon &&
|
|
27002
27418
|
/*#__PURE__*/
|
|
27003
27419
|
// @ts-expect-error - TS2339 - Property 'icon' does not exist on type 'Readonly<Props> & Readonly<{ children?: ReactNode; }>'.
|
|
@@ -27202,6 +27618,7 @@ const DEFAULT_ALIGNMENT = "block";
|
|
|
27202
27618
|
// there is no transform as part of exports
|
|
27203
27619
|
|
|
27204
27620
|
class ImageWidget extends React__namespace.Component {
|
|
27621
|
+
static contextType = PerseusI18nContext;
|
|
27205
27622
|
static defaultProps = {
|
|
27206
27623
|
alignment: DEFAULT_ALIGNMENT,
|
|
27207
27624
|
title: "",
|
|
@@ -27290,7 +27707,8 @@ class ImageWidget extends React__namespace.Component {
|
|
|
27290
27707
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
27291
27708
|
content: this.props.alt,
|
|
27292
27709
|
apiOptions: apiOptions,
|
|
27293
|
-
linterContext: this.props.linterContext
|
|
27710
|
+
linterContext: this.props.linterContext,
|
|
27711
|
+
strings: this.context.strings
|
|
27294
27712
|
}));
|
|
27295
27713
|
}
|
|
27296
27714
|
|
|
@@ -27350,7 +27768,8 @@ class ImageWidget extends React__namespace.Component {
|
|
|
27350
27768
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
27351
27769
|
content: title + this.props.caption,
|
|
27352
27770
|
apiOptions: apiOptions,
|
|
27353
|
-
linterContext: this.props.linterContext
|
|
27771
|
+
linterContext: this.props.linterContext,
|
|
27772
|
+
strings: this.context.strings
|
|
27354
27773
|
})));
|
|
27355
27774
|
}
|
|
27356
27775
|
return /*#__PURE__*/React__namespace.createElement("figure", {
|
|
@@ -27368,7 +27787,8 @@ class ImageWidget extends React__namespace.Component {
|
|
|
27368
27787
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
27369
27788
|
content: this.props.title,
|
|
27370
27789
|
apiOptions: apiOptions,
|
|
27371
|
-
linterContext: this.props.linterContext
|
|
27790
|
+
linterContext: this.props.linterContext,
|
|
27791
|
+
strings: this.context.strings
|
|
27372
27792
|
}));
|
|
27373
27793
|
}
|
|
27374
27794
|
if (this.props.caption) {
|
|
@@ -27380,7 +27800,8 @@ class ImageWidget extends React__namespace.Component {
|
|
|
27380
27800
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
27381
27801
|
content: this.props.caption,
|
|
27382
27802
|
apiOptions: apiOptions,
|
|
27383
|
-
linterContext: this.props.linterContext
|
|
27803
|
+
linterContext: this.props.linterContext,
|
|
27804
|
+
strings: this.context.strings
|
|
27384
27805
|
}));
|
|
27385
27806
|
}
|
|
27386
27807
|
return /*#__PURE__*/React__namespace.createElement("figure", {
|
|
@@ -28050,10 +28471,13 @@ function numSteps$1(range, step) {
|
|
|
28050
28471
|
return Math.floor((range[1] - range[0]) / step);
|
|
28051
28472
|
}
|
|
28052
28473
|
class Graph extends React__namespace.Component {
|
|
28474
|
+
protractor;
|
|
28475
|
+
ruler;
|
|
28476
|
+
_graphie;
|
|
28053
28477
|
// @ts-expect-error - TS2564 - Property '_hasSetupGraphieThisUpdate' has no initializer and is not definitely assigned in the constructor.
|
|
28054
|
-
|
|
28478
|
+
_hasSetupGraphieThisUpdate;
|
|
28055
28479
|
// @ts-expect-error - TS2564 - Property '_shouldSetupGraphie' has no initializer and is not definitely assigned in the constructor.
|
|
28056
|
-
|
|
28480
|
+
_shouldSetupGraphie;
|
|
28057
28481
|
static defaultProps = {
|
|
28058
28482
|
labels: ["x", "y"],
|
|
28059
28483
|
range: [[-10, 10], [-10, 10]],
|
|
@@ -28322,6 +28746,123 @@ class Graph extends React__namespace.Component {
|
|
|
28322
28746
|
}
|
|
28323
28747
|
}
|
|
28324
28748
|
|
|
28749
|
+
// TODO(FEI-4010): Remove `Perseus` prefix for all types here
|
|
28750
|
+
// TODO(FEI-4011): Use types generated by https://github.com/jaredly/generate-perseus-flowtypes
|
|
28751
|
+
|
|
28752
|
+
// Range is replaced within this file with Interval, but it is used elsewhere
|
|
28753
|
+
// and exported from the package, so we need to keep it around.
|
|
28754
|
+
// TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
|
|
28755
|
+
const ItemExtras = [
|
|
28756
|
+
// The user might benefit from using a Scientific Calculator. Provided on Khan Academy when true
|
|
28757
|
+
"calculator",
|
|
28758
|
+
// The user might benefit from using a statistics Chi Squared Table like https://people.richland.edu/james/lecture/m170/tbl-chi.html
|
|
28759
|
+
"chi2Table",
|
|
28760
|
+
// The user might benefit from a monthly payments calculator. Provided on Khan Academy when true
|
|
28761
|
+
"financialCalculatorMonthlyPayment",
|
|
28762
|
+
// The user might benefit from a total amount calculator. Provided on Khan Academy when true
|
|
28763
|
+
"financialCalculatorTotalAmount",
|
|
28764
|
+
// The user might benefit from a time to pay off calculator. Provided on Khan Academy when true
|
|
28765
|
+
"financialCalculatorTimeToPayOff",
|
|
28766
|
+
// The user might benefit from using a Periodic Table of Elements. Provided on Khan Academy when true
|
|
28767
|
+
"periodicTable",
|
|
28768
|
+
// The user might benefit from using a Periodic Table of Elements with key. Provided on Khan Academy when true
|
|
28769
|
+
"periodicTableWithKey",
|
|
28770
|
+
// The user might benefit from using a statistics T Table like https://www.statisticshowto.com/tables/t-distribution-table/
|
|
28771
|
+
"tTable",
|
|
28772
|
+
// The user might benefit from using a statistics Z Table like https://www.ztable.net/
|
|
28773
|
+
"zTable"];
|
|
28774
|
+
|
|
28775
|
+
// prettier-ignore
|
|
28776
|
+
|
|
28777
|
+
// prettier-ignore
|
|
28778
|
+
|
|
28779
|
+
// prettier-ignore
|
|
28780
|
+
|
|
28781
|
+
// prettier-ignore
|
|
28782
|
+
|
|
28783
|
+
// prettier-ignore
|
|
28784
|
+
|
|
28785
|
+
// prettier-ignore
|
|
28786
|
+
|
|
28787
|
+
// prettier-ignore
|
|
28788
|
+
|
|
28789
|
+
// prettier-ignore
|
|
28790
|
+
|
|
28791
|
+
// prettier-ignore
|
|
28792
|
+
|
|
28793
|
+
// prettier-ignore
|
|
28794
|
+
|
|
28795
|
+
// prettier-ignore
|
|
28796
|
+
|
|
28797
|
+
// prettier-ignore
|
|
28798
|
+
|
|
28799
|
+
// prettier-ignore
|
|
28800
|
+
|
|
28801
|
+
// prettier-ignore
|
|
28802
|
+
|
|
28803
|
+
// prettier-ignore
|
|
28804
|
+
|
|
28805
|
+
// prettier-ignore
|
|
28806
|
+
|
|
28807
|
+
// prettier-ignore
|
|
28808
|
+
|
|
28809
|
+
// prettier-ignore
|
|
28810
|
+
|
|
28811
|
+
// prettier-ignore
|
|
28812
|
+
|
|
28813
|
+
// prettier-ignore
|
|
28814
|
+
|
|
28815
|
+
// prettier-ignore
|
|
28816
|
+
|
|
28817
|
+
// prettier-ignore
|
|
28818
|
+
|
|
28819
|
+
// prettier-ignore
|
|
28820
|
+
|
|
28821
|
+
// prettier-ignore
|
|
28822
|
+
|
|
28823
|
+
// prettier-ignore
|
|
28824
|
+
|
|
28825
|
+
// prettier-ignore
|
|
28826
|
+
|
|
28827
|
+
// prettier-ignore
|
|
28828
|
+
|
|
28829
|
+
// prettier-ignore
|
|
28830
|
+
|
|
28831
|
+
// prettier-ignore
|
|
28832
|
+
|
|
28833
|
+
// prettier-ignore
|
|
28834
|
+
|
|
28835
|
+
// prettier-ignore
|
|
28836
|
+
|
|
28837
|
+
// prettier-ignore
|
|
28838
|
+
|
|
28839
|
+
// prettier-ignore
|
|
28840
|
+
|
|
28841
|
+
// prettier-ignore
|
|
28842
|
+
|
|
28843
|
+
// prettier-ignore
|
|
28844
|
+
|
|
28845
|
+
// prettier-ignore
|
|
28846
|
+
|
|
28847
|
+
//prettier-ignore
|
|
28848
|
+
|
|
28849
|
+
// A background image applied to various widgets.
|
|
28850
|
+
|
|
28851
|
+
const PerseusExpressionAnswerFormConsidered = ["correct", "wrong", "ungraded"];
|
|
28852
|
+
const lockedFigureColors = {
|
|
28853
|
+
blue: "#3D7586",
|
|
28854
|
+
green: "#447A53",
|
|
28855
|
+
gray: "#5D5F66",
|
|
28856
|
+
grayH: "#3B3D45",
|
|
28857
|
+
grayI: "#21242C",
|
|
28858
|
+
purple: "#594094",
|
|
28859
|
+
purpleD: "#8351E8",
|
|
28860
|
+
pink: "#B25071",
|
|
28861
|
+
orange: "#946700",
|
|
28862
|
+
red: "#D92916"
|
|
28863
|
+
};
|
|
28864
|
+
const plotterPlotTypes = ["bar", "line", "pic", "histogram", "dotplot"];
|
|
28865
|
+
|
|
28325
28866
|
const LockedLine = props => {
|
|
28326
28867
|
const {
|
|
28327
28868
|
color,
|
|
@@ -28338,7 +28879,7 @@ const LockedLine = props => {
|
|
|
28338
28879
|
line = /*#__PURE__*/React__namespace.createElement(LineType, {
|
|
28339
28880
|
point1: point1.coord,
|
|
28340
28881
|
point2: point2.coord,
|
|
28341
|
-
color:
|
|
28882
|
+
color: lockedFigureColors[color],
|
|
28342
28883
|
style: lineStyle
|
|
28343
28884
|
});
|
|
28344
28885
|
} else {
|
|
@@ -28352,8 +28893,8 @@ const LockedLine = props => {
|
|
|
28352
28893
|
y: point1.coord[1],
|
|
28353
28894
|
svgCircleProps: {
|
|
28354
28895
|
style: {
|
|
28355
|
-
fill: point1.filled ?
|
|
28356
|
-
stroke:
|
|
28896
|
+
fill: point1.filled ? lockedFigureColors[point1.color] : wonderBlocksTokens.color.white,
|
|
28897
|
+
stroke: lockedFigureColors[point1.color],
|
|
28357
28898
|
strokeWidth: wonderBlocksTokens.spacing.xxxxSmall_2
|
|
28358
28899
|
}
|
|
28359
28900
|
}
|
|
@@ -28362,8 +28903,8 @@ const LockedLine = props => {
|
|
|
28362
28903
|
y: point2.coord[1],
|
|
28363
28904
|
svgCircleProps: {
|
|
28364
28905
|
style: {
|
|
28365
|
-
fill: point2.filled ?
|
|
28366
|
-
stroke:
|
|
28906
|
+
fill: point2.filled ? lockedFigureColors[point2.color] : wonderBlocksTokens.color.white,
|
|
28907
|
+
stroke: lockedFigureColors[point2.color],
|
|
28367
28908
|
strokeWidth: wonderBlocksTokens.spacing.xxxxSmall_2
|
|
28368
28909
|
}
|
|
28369
28910
|
}
|
|
@@ -28382,8 +28923,8 @@ const LockedPoint = props => {
|
|
|
28382
28923
|
y: y,
|
|
28383
28924
|
svgCircleProps: {
|
|
28384
28925
|
style: {
|
|
28385
|
-
fill: filled ?
|
|
28386
|
-
stroke:
|
|
28926
|
+
fill: filled ? lockedFigureColors[color] : wonderBlocksTokens.color.white,
|
|
28927
|
+
stroke: lockedFigureColors[color],
|
|
28387
28928
|
strokeWidth: wonderBlocksTokens.spacing.xxxxSmall_2
|
|
28388
28929
|
}
|
|
28389
28930
|
}
|
|
@@ -28629,7 +29170,7 @@ function Arrowhead(props) {
|
|
|
28629
29170
|
d: arrowPath,
|
|
28630
29171
|
fill: "none",
|
|
28631
29172
|
style: {
|
|
28632
|
-
stroke: "inherit"
|
|
29173
|
+
stroke: props.color ?? "inherit"
|
|
28633
29174
|
},
|
|
28634
29175
|
strokeLinejoin: "round",
|
|
28635
29176
|
strokeLinecap: "round"
|
|
@@ -28739,7 +29280,8 @@ const MovableLine = props => {
|
|
|
28739
29280
|
const defaultGraphConfig = {
|
|
28740
29281
|
range: [[0, 1], [0, 1]],
|
|
28741
29282
|
snapStep: [1, 1],
|
|
28742
|
-
markings: "none"
|
|
29283
|
+
markings: "none",
|
|
29284
|
+
showTooltips: false
|
|
28743
29285
|
};
|
|
28744
29286
|
const GraphConfigContext = /*#__PURE__*/React.createContext(defaultGraphConfig);
|
|
28745
29287
|
function useGraphConfig() {
|
|
@@ -28753,7 +29295,8 @@ const StyledMovablePoint = props => {
|
|
|
28753
29295
|
const {
|
|
28754
29296
|
range,
|
|
28755
29297
|
snapStep,
|
|
28756
|
-
markings
|
|
29298
|
+
markings,
|
|
29299
|
+
showTooltips
|
|
28757
29300
|
} = useGraphConfig();
|
|
28758
29301
|
const hitboxRef = React.useRef(null);
|
|
28759
29302
|
const {
|
|
@@ -28761,6 +29304,13 @@ const StyledMovablePoint = props => {
|
|
|
28761
29304
|
onMove,
|
|
28762
29305
|
color = wonderBlocksTokens.color.blue
|
|
28763
29306
|
} = props;
|
|
29307
|
+
|
|
29308
|
+
// WB Tooltip requires a color name for the background color.
|
|
29309
|
+
// Since the color in props is a hex value, a reverse lookup is needed.
|
|
29310
|
+
const wbColorName = Object.entries(wonderBlocksTokens.color).find(_ref => {
|
|
29311
|
+
let [_, value] = _ref;
|
|
29312
|
+
return value === color;
|
|
29313
|
+
})?.[0] ?? "blue";
|
|
28764
29314
|
const {
|
|
28765
29315
|
dragging
|
|
28766
29316
|
} = mafs.useMovable({
|
|
@@ -28778,19 +29328,20 @@ const StyledMovablePoint = props => {
|
|
|
28778
29328
|
const [[_, horizontalStartY]] = useTransform([0, yMin]);
|
|
28779
29329
|
const [[__, horizontalEndY]] = useTransform([0, yMax]);
|
|
28780
29330
|
const showHairlines = dragging && markings !== "none";
|
|
28781
|
-
|
|
29331
|
+
const hairlines = /*#__PURE__*/React__namespace.createElement("g", null, /*#__PURE__*/React__namespace.createElement("line", {
|
|
28782
29332
|
x1: verticalStartX,
|
|
28783
29333
|
y1: y,
|
|
28784
29334
|
x2: verticalEndX,
|
|
28785
29335
|
y2: y,
|
|
28786
|
-
stroke:
|
|
29336
|
+
stroke: color
|
|
28787
29337
|
}), /*#__PURE__*/React__namespace.createElement("line", {
|
|
28788
29338
|
x1: x,
|
|
28789
29339
|
y1: horizontalStartY,
|
|
28790
29340
|
x2: x,
|
|
28791
29341
|
y2: horizontalEndY,
|
|
28792
|
-
stroke:
|
|
28793
|
-
}))
|
|
29342
|
+
stroke: color
|
|
29343
|
+
}));
|
|
29344
|
+
const svgForPoint = /*#__PURE__*/React__namespace.createElement("g", {
|
|
28794
29345
|
ref: hitboxRef,
|
|
28795
29346
|
className: pointClasses,
|
|
28796
29347
|
tabIndex: 0,
|
|
@@ -28823,7 +29374,15 @@ const StyledMovablePoint = props => {
|
|
|
28823
29374
|
fill: color
|
|
28824
29375
|
},
|
|
28825
29376
|
"data-testid": "movable-point__center"
|
|
28826
|
-
}))
|
|
29377
|
+
}));
|
|
29378
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, showHairlines && hairlines, showTooltips ? /*#__PURE__*/React__namespace.createElement(Tooltip__default["default"], {
|
|
29379
|
+
autoUpdate: true,
|
|
29380
|
+
backgroundColor: wbColorName,
|
|
29381
|
+
content: `(${point[0]}, ${point[1]})`,
|
|
29382
|
+
contentStyle: {
|
|
29383
|
+
color: "white"
|
|
29384
|
+
}
|
|
29385
|
+
}, svgForPoint) : svgForPoint);
|
|
28827
29386
|
};
|
|
28828
29387
|
|
|
28829
29388
|
const SegmentGraph = props => {
|
|
@@ -29217,22 +29776,27 @@ function AxisArrows() {
|
|
|
29217
29776
|
const {
|
|
29218
29777
|
range: [[xMin, xMax], [yMin, yMax]]
|
|
29219
29778
|
} = useGraphConfig();
|
|
29779
|
+
const axisColor = "var(--mafs-fg)";
|
|
29220
29780
|
return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29781
|
+
color: axisColor,
|
|
29782
|
+
x: xMin,
|
|
29783
|
+
y: 0,
|
|
29784
|
+
angle: 180
|
|
29785
|
+
}), /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29786
|
+
color: axisColor,
|
|
29221
29787
|
x: xMax,
|
|
29222
29788
|
y: 0,
|
|
29223
29789
|
angle: 0
|
|
29224
29790
|
}), /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29791
|
+
color: axisColor,
|
|
29225
29792
|
x: 0,
|
|
29226
29793
|
y: yMin,
|
|
29227
|
-
angle:
|
|
29228
|
-
}), /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29229
|
-
x: xMin,
|
|
29230
|
-
y: 0,
|
|
29231
|
-
angle: 180
|
|
29794
|
+
angle: 270
|
|
29232
29795
|
}), /*#__PURE__*/React__default["default"].createElement(Arrowhead, {
|
|
29796
|
+
color: axisColor,
|
|
29233
29797
|
x: 0,
|
|
29234
29798
|
y: yMax,
|
|
29235
|
-
angle:
|
|
29799
|
+
angle: 90
|
|
29236
29800
|
}));
|
|
29237
29801
|
}
|
|
29238
29802
|
|
|
@@ -29360,7 +29924,7 @@ const Grid = props => {
|
|
|
29360
29924
|
return props.markings === "none" ? null : /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(mafs.Coordinates.Cartesian, {
|
|
29361
29925
|
xAxis: axisOptions(props, 0),
|
|
29362
29926
|
yAxis: axisOptions(props, 1)
|
|
29363
|
-
}),
|
|
29927
|
+
}),
|
|
29364
29928
|
// Only render the axis ticks and arrows if the markings are set to a full "graph"
|
|
29365
29929
|
props.markings === "graph" && /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(AxisTicks, {
|
|
29366
29930
|
range: props.range,
|
|
@@ -29727,6 +30291,7 @@ const getNumericFormat = KhanMath.getNumericFormat;
|
|
|
29727
30291
|
* Optionally takes a size ("mini", "small", "normal")
|
|
29728
30292
|
*/
|
|
29729
30293
|
class NumberInput extends React__namespace.Component {
|
|
30294
|
+
static contextType = PerseusI18nContext;
|
|
29730
30295
|
static propTypes = {
|
|
29731
30296
|
value: PropTypes__default["default"].number,
|
|
29732
30297
|
format: PropTypes__default["default"].string,
|
|
@@ -29813,7 +30378,7 @@ class NumberInput extends React__namespace.Component {
|
|
|
29813
30378
|
const placeholder = this.props.placeholder;
|
|
29814
30379
|
return ___default["default"].isFinite(placeholder) ? +placeholder : null;
|
|
29815
30380
|
}
|
|
29816
|
-
const result = firstNumericalParse(value);
|
|
30381
|
+
const result = firstNumericalParse(value, this.context.strings);
|
|
29817
30382
|
return ___default["default"].isFinite(result) ? result : this.props.value;
|
|
29818
30383
|
};
|
|
29819
30384
|
|
|
@@ -29844,7 +30409,7 @@ class NumberInput extends React__namespace.Component {
|
|
|
29844
30409
|
if (value == null) {
|
|
29845
30410
|
return true;
|
|
29846
30411
|
}
|
|
29847
|
-
const val = firstNumericalParse(value);
|
|
30412
|
+
const val = firstNumericalParse(value, this.context.strings);
|
|
29848
30413
|
const checkValidity = this.props.checkValidity;
|
|
29849
30414
|
return ___default["default"].isFinite(val) && checkValidity(val);
|
|
29850
30415
|
};
|
|
@@ -30643,7 +31208,8 @@ const MafsGraph = props => {
|
|
|
30643
31208
|
value: {
|
|
30644
31209
|
range: state.range,
|
|
30645
31210
|
snapStep: state.snapStep,
|
|
30646
|
-
markings: props.markings
|
|
31211
|
+
markings: props.markings,
|
|
31212
|
+
showTooltips: !!props.showTooltips
|
|
30647
31213
|
}
|
|
30648
31214
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
30649
31215
|
style: {
|
|
@@ -30744,10 +31310,25 @@ const makeInvalidTypeError = (functionName, graphType) => {
|
|
|
30744
31310
|
// There's no transform function in exports
|
|
30745
31311
|
|
|
30746
31312
|
class LegacyInteractiveGraph extends React__namespace.Component {
|
|
31313
|
+
static contextType = PerseusI18nContext;
|
|
31314
|
+
angle;
|
|
31315
|
+
circle;
|
|
31316
|
+
graphie;
|
|
31317
|
+
horizHairline;
|
|
31318
|
+
line;
|
|
31319
|
+
lines;
|
|
31320
|
+
parabola;
|
|
31321
|
+
pointA;
|
|
31322
|
+
pointB;
|
|
31323
|
+
pointC;
|
|
30747
31324
|
// @ts-expect-error - TS2564 - Property 'points' has no initializer and is not definitely assigned in the constructor.
|
|
30748
|
-
|
|
31325
|
+
points;
|
|
31326
|
+
polygon;
|
|
30749
31327
|
// @ts-expect-error - TS2564 - Property 'shouldResetGraphie' has no initializer and is not definitely assigned in the constructor.
|
|
30750
|
-
|
|
31328
|
+
shouldResetGraphie;
|
|
31329
|
+
sinusoid;
|
|
31330
|
+
trashCan;
|
|
31331
|
+
vertHairline;
|
|
30751
31332
|
static defaultProps = {
|
|
30752
31333
|
labels: ["x", "y"],
|
|
30753
31334
|
range: [[-10, 10], [-10, 10]],
|
|
@@ -31885,9 +32466,9 @@ class LegacyInteractiveGraph extends React__namespace.Component {
|
|
|
31885
32466
|
// isClickToAddPoints() only applies to points and polygons
|
|
31886
32467
|
if (this.isClickToAddPoints() && this.state.shouldShowInstructions) {
|
|
31887
32468
|
if (this.props.graph.type === "point") {
|
|
31888
|
-
instructions =
|
|
32469
|
+
instructions = this.context.strings.addPoints;
|
|
31889
32470
|
} else if (this.props.graph.type === "polygon") {
|
|
31890
|
-
instructions =
|
|
32471
|
+
instructions = this.context.strings.addVertices;
|
|
31891
32472
|
}
|
|
31892
32473
|
} else {
|
|
31893
32474
|
instructions = undefined;
|
|
@@ -31965,7 +32546,8 @@ class InteractiveGraph extends React__namespace.Component {
|
|
|
31965
32546
|
ref: this.mafsRef,
|
|
31966
32547
|
gridStep: gridStep,
|
|
31967
32548
|
snapStep: snapStep,
|
|
31968
|
-
box: box
|
|
32549
|
+
box: box,
|
|
32550
|
+
showTooltips: !!this.props.showTooltips
|
|
31969
32551
|
}));
|
|
31970
32552
|
}
|
|
31971
32553
|
return /*#__PURE__*/React__namespace.createElement(LegacyInteractiveGraph, _extends({
|
|
@@ -33492,6 +34074,9 @@ var globalStyles = /*#__PURE__*/Object.freeze({
|
|
|
33492
34074
|
});
|
|
33493
34075
|
|
|
33494
34076
|
const AnswerChoices = props => {
|
|
34077
|
+
const {
|
|
34078
|
+
strings
|
|
34079
|
+
} = usePerseusI18n();
|
|
33495
34080
|
const onAnswerChange = selected => {
|
|
33496
34081
|
const {
|
|
33497
34082
|
choices,
|
|
@@ -33511,6 +34096,7 @@ const AnswerChoices = props => {
|
|
|
33511
34096
|
value: content,
|
|
33512
34097
|
label: /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
33513
34098
|
content: content,
|
|
34099
|
+
strings: strings,
|
|
33514
34100
|
inline: true
|
|
33515
34101
|
})
|
|
33516
34102
|
});
|
|
@@ -33541,14 +34127,13 @@ const AnswerChoices = props => {
|
|
|
33541
34127
|
}));
|
|
33542
34128
|
};
|
|
33543
34129
|
|
|
33544
|
-
const strings = {
|
|
33545
|
-
hideAnswersToggleLabel: i18n__namespace._("Hide answer choices")
|
|
33546
|
-
};
|
|
33547
|
-
|
|
33548
34130
|
const HideAnswersToggle = props => {
|
|
33549
34131
|
const idFactory = wonderBlocksCore.useUniqueIdWithMock();
|
|
33550
34132
|
const switchId = idFactory.get("hide-answers-toggle");
|
|
33551
34133
|
const labelId = idFactory.get("hide-answers-label");
|
|
34134
|
+
const {
|
|
34135
|
+
strings
|
|
34136
|
+
} = usePerseusI18n();
|
|
33552
34137
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
33553
34138
|
style: styles$g.switchWrapper
|
|
33554
34139
|
}, /*#__PURE__*/React__namespace.createElement(Switch__default["default"], {
|
|
@@ -33589,9 +34174,12 @@ const AnswerPill = props => {
|
|
|
33589
34174
|
hovered
|
|
33590
34175
|
} = props;
|
|
33591
34176
|
const idFactory = wonderBlocksCore.useUniqueIdWithMock();
|
|
33592
|
-
const
|
|
33593
|
-
|
|
33594
|
-
|
|
34177
|
+
const {
|
|
34178
|
+
strings
|
|
34179
|
+
} = usePerseusI18n();
|
|
34180
|
+
const answerString = selectedAnswers.length > 1 ? strings.answers({
|
|
34181
|
+
num: selectedAnswers.length
|
|
34182
|
+
}) : selectedAnswers[0];
|
|
33595
34183
|
|
|
33596
34184
|
// It should no longer be possible to interact with an answer after it
|
|
33597
34185
|
// has been labeled (answered) correctly.
|
|
@@ -33620,6 +34208,7 @@ const AnswerPill = props => {
|
|
|
33620
34208
|
style: [style, popperStyle, styles$f.pill, correct && styles$f.correct, incorrect && styles$f.incorrect, (focused || hovered) && BringToFront]
|
|
33621
34209
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
33622
34210
|
content: answerString,
|
|
34211
|
+
strings: strings,
|
|
33623
34212
|
inline: true
|
|
33624
34213
|
}));
|
|
33625
34214
|
});
|
|
@@ -33646,8 +34235,9 @@ function shouldReduceMotion() {
|
|
|
33646
34235
|
}
|
|
33647
34236
|
const MARKER_SIZE = 24;
|
|
33648
34237
|
class Marker extends React__namespace.Component {
|
|
34238
|
+
static contextType = PerseusI18nContext;
|
|
33649
34239
|
// The marker icon element.
|
|
33650
|
-
|
|
34240
|
+
_icon;
|
|
33651
34241
|
static defaultProps = {
|
|
33652
34242
|
selected: []
|
|
33653
34243
|
};
|
|
@@ -33717,10 +34307,8 @@ class Marker extends React__namespace.Component {
|
|
|
33717
34307
|
const markerDisabled = showCorrectness === "correct";
|
|
33718
34308
|
const active = hovered || focused;
|
|
33719
34309
|
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
33720
|
-
style: [styles$e.marker, active && !markerDisabled && styles$e.markerActive]
|
|
33721
|
-
|
|
33722
|
-
,
|
|
33723
|
-
"aria-label": markerDisabled ? i18n__namespace._("Correct!") : label
|
|
34310
|
+
style: [styles$e.marker, active && !markerDisabled && styles$e.markerActive],
|
|
34311
|
+
"aria-label": markerDisabled ? this.context.strings.correctExcited : label
|
|
33724
34312
|
}, this.renderIcon()), !!selected && showAnswer && /*#__PURE__*/React__namespace.createElement(AnswerPill, {
|
|
33725
34313
|
selectedAnswers: selected,
|
|
33726
34314
|
showCorrectness: showCorrectness,
|
|
@@ -33820,8 +34408,9 @@ const styles$e = aphrodite.StyleSheet.create({
|
|
|
33820
34408
|
*/
|
|
33821
34409
|
|
|
33822
34410
|
class LabelImage extends React__namespace.Component {
|
|
34411
|
+
static contextType = PerseusI18nContext;
|
|
33823
34412
|
// The rendered markers on the question image for labeling.
|
|
33824
|
-
|
|
34413
|
+
_markers;
|
|
33825
34414
|
static gradeMarker(marker) {
|
|
33826
34415
|
const score = {
|
|
33827
34416
|
hasAnswers: false,
|
|
@@ -34307,8 +34896,11 @@ class LabelImage extends React__namespace.Component {
|
|
|
34307
34896
|
multipleAnswers,
|
|
34308
34897
|
hideChoicesFromInstructions: hideChoices
|
|
34309
34898
|
} = this.props;
|
|
34310
|
-
const
|
|
34311
|
-
|
|
34899
|
+
const {
|
|
34900
|
+
strings
|
|
34901
|
+
} = this.context;
|
|
34902
|
+
const promptString = isMobile ? multipleAnswers ? strings.tapMultiple : strings.tapSingle : multipleAnswers ? strings.clickMultiple : strings.clickSingle;
|
|
34903
|
+
const choicesString = strings.choices;
|
|
34312
34904
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
34313
34905
|
className: classNames__default["default"]("perseus-label-image-widget-instructions", aphrodite.css(styles$d.instructions))
|
|
34314
34906
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
@@ -34319,7 +34911,8 @@ class LabelImage extends React__namespace.Component {
|
|
|
34319
34911
|
className: aphrodite.css(styles$d.instructionsChoice),
|
|
34320
34912
|
key: index
|
|
34321
34913
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
34322
|
-
content: choice
|
|
34914
|
+
content: choice,
|
|
34915
|
+
strings: strings
|
|
34323
34916
|
})))));
|
|
34324
34917
|
}
|
|
34325
34918
|
render() {
|
|
@@ -34494,12 +35087,13 @@ class Placeholder extends React__namespace.Component {
|
|
|
34494
35087
|
// Usual flow: Static -> Dragging -> Animating -> Static
|
|
34495
35088
|
// [Dis|en]abling: Static|Dragging|Animating -> Disabled -> Static
|
|
34496
35089
|
class Draggable extends React__namespace.Component {
|
|
35090
|
+
static contextType = PerseusI18nContext;
|
|
34497
35091
|
// Handler returned by requestAnimationFrame.
|
|
34498
35092
|
animationFrameRequest = null;
|
|
34499
35093
|
// @ts-expect-error - TS2564 - Property 'isMouseMoveUpBound' has no initializer and is not definitely assigned in the constructor.
|
|
34500
|
-
|
|
35094
|
+
isMouseMoveUpBound;
|
|
34501
35095
|
// @ts-expect-error - TS2564 - Property '_mounted' has no initializer and is not definitely assigned in the constructor.
|
|
34502
|
-
|
|
35096
|
+
_mounted;
|
|
34503
35097
|
static defaultProps = {
|
|
34504
35098
|
includePadding: true,
|
|
34505
35099
|
type: ItemState.STATIC,
|
|
@@ -34602,7 +35196,8 @@ class Draggable extends React__namespace.Component {
|
|
|
34602
35196
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
34603
35197
|
content: this.props.content,
|
|
34604
35198
|
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "draggable"),
|
|
34605
|
-
onRender: this.props.onRender
|
|
35199
|
+
onRender: this.props.onRender,
|
|
35200
|
+
strings: this.context.strings
|
|
34606
35201
|
}));
|
|
34607
35202
|
}
|
|
34608
35203
|
componentDidUpdate(prevProps) {
|
|
@@ -35156,6 +35751,7 @@ const {
|
|
|
35156
35751
|
} = Util;
|
|
35157
35752
|
const HACKY_CSS_CLASSNAME = "perseus-widget-matcher";
|
|
35158
35753
|
class Matcher extends React__namespace.Component {
|
|
35754
|
+
static contextType = PerseusI18nContext;
|
|
35159
35755
|
static propTypes = {
|
|
35160
35756
|
apiOptions: ApiOptions.propTypes,
|
|
35161
35757
|
labels: PropTypes__default["default"].array,
|
|
@@ -35235,12 +35831,14 @@ class Matcher extends React__namespace.Component {
|
|
|
35235
35831
|
className: aphrodite.css(styles$b.column, styles$b.columnLabel)
|
|
35236
35832
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
35237
35833
|
content: this.props.labels[0] || "...",
|
|
35238
|
-
linterContext: this.props.linterContext
|
|
35834
|
+
linterContext: this.props.linterContext,
|
|
35835
|
+
strings: this.context.strings
|
|
35239
35836
|
})), /*#__PURE__*/React__namespace.createElement("th", {
|
|
35240
35837
|
className: aphrodite.css(styles$b.column, styles$b.columnRight, styles$b.columnLabel)
|
|
35241
35838
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
35242
35839
|
content: this.props.labels[1] || "...",
|
|
35243
|
-
linterContext: this.props.linterContext
|
|
35840
|
+
linterContext: this.props.linterContext,
|
|
35841
|
+
strings: this.context.strings
|
|
35244
35842
|
}))), /*#__PURE__*/React__namespace.createElement("tr", {
|
|
35245
35843
|
className: aphrodite.css(styles$b.row)
|
|
35246
35844
|
}, /*#__PURE__*/React__namespace.createElement("td", {
|
|
@@ -35452,8 +36050,9 @@ const getMatrixSize = function (matrix) {
|
|
|
35452
36050
|
return matrixSize;
|
|
35453
36051
|
};
|
|
35454
36052
|
class Matrix extends React__namespace.Component {
|
|
36053
|
+
static contextType = PerseusI18nContext;
|
|
35455
36054
|
// @ts-expect-error - TS2564 - Property 'cursorPosition' has no initializer and is not definitely assigned in the constructor.
|
|
35456
|
-
|
|
36055
|
+
cursorPosition;
|
|
35457
36056
|
static defaultProps = {
|
|
35458
36057
|
matrixBoardSize: [3, 3],
|
|
35459
36058
|
answers: [[]],
|
|
@@ -35463,6 +36062,57 @@ class Matrix extends React__namespace.Component {
|
|
|
35463
36062
|
apiOptions: ApiOptions.defaults,
|
|
35464
36063
|
linterContext: PerseusLinter.linterContextDefault
|
|
35465
36064
|
};
|
|
36065
|
+
static validate(state, rubric, strings) {
|
|
36066
|
+
const solution = rubric.answers;
|
|
36067
|
+
const supplied = state.answers;
|
|
36068
|
+
const solutionSize = getMatrixSize(solution);
|
|
36069
|
+
const suppliedSize = getMatrixSize(supplied);
|
|
36070
|
+
const incorrectSize = solutionSize[0] !== suppliedSize[0] || solutionSize[1] !== suppliedSize[1];
|
|
36071
|
+
const createValidator = KhanAnswerTypes.number.createValidatorFunctional;
|
|
36072
|
+
let message = null;
|
|
36073
|
+
let hasEmptyCell = false;
|
|
36074
|
+
let incorrect = false;
|
|
36075
|
+
___default["default"](suppliedSize[0]).times(row => {
|
|
36076
|
+
___default["default"](suppliedSize[1]).times(col => {
|
|
36077
|
+
if (supplied[row][col] == null || supplied[row][col].toString().length === 0) {
|
|
36078
|
+
hasEmptyCell = true;
|
|
36079
|
+
}
|
|
36080
|
+
if (!incorrectSize) {
|
|
36081
|
+
const validator = createValidator(solution[row][col], {
|
|
36082
|
+
simplify: true
|
|
36083
|
+
}, strings);
|
|
36084
|
+
const result = validator(supplied[row][col]);
|
|
36085
|
+
if (result.message) {
|
|
36086
|
+
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
|
|
36087
|
+
message = result.message;
|
|
36088
|
+
}
|
|
36089
|
+
if (!result.correct) {
|
|
36090
|
+
incorrect = true;
|
|
36091
|
+
}
|
|
36092
|
+
}
|
|
36093
|
+
});
|
|
36094
|
+
});
|
|
36095
|
+
if (hasEmptyCell) {
|
|
36096
|
+
return {
|
|
36097
|
+
type: "invalid",
|
|
36098
|
+
message: strings.fillAllCells
|
|
36099
|
+
};
|
|
36100
|
+
}
|
|
36101
|
+
if (incorrectSize) {
|
|
36102
|
+
return {
|
|
36103
|
+
type: "points",
|
|
36104
|
+
earned: 0,
|
|
36105
|
+
total: 1,
|
|
36106
|
+
message: null
|
|
36107
|
+
};
|
|
36108
|
+
}
|
|
36109
|
+
return {
|
|
36110
|
+
type: "points",
|
|
36111
|
+
earned: incorrect ? 0 : 1,
|
|
36112
|
+
total: 1,
|
|
36113
|
+
message: message
|
|
36114
|
+
};
|
|
36115
|
+
}
|
|
35466
36116
|
state = {
|
|
35467
36117
|
enterTheMatrix: 0
|
|
35468
36118
|
};
|
|
@@ -35505,7 +36155,8 @@ class Matrix extends React__namespace.Component {
|
|
|
35505
36155
|
className: "matrix-prefix"
|
|
35506
36156
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
35507
36157
|
content: this.props.prefix,
|
|
35508
|
-
linterContext: this.props.linterContext
|
|
36158
|
+
linterContext: this.props.linterContext,
|
|
36159
|
+
strings: this.context.strings
|
|
35509
36160
|
})), /*#__PURE__*/React__namespace.createElement("div", {
|
|
35510
36161
|
className: "matrix-input"
|
|
35511
36162
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
@@ -35620,7 +36271,8 @@ class Matrix extends React__namespace.Component {
|
|
|
35620
36271
|
className: "matrix-suffix"
|
|
35621
36272
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
35622
36273
|
content: this.props.suffix,
|
|
35623
|
-
linterContext: this.props.linterContext
|
|
36274
|
+
linterContext: this.props.linterContext,
|
|
36275
|
+
strings: this.context.strings
|
|
35624
36276
|
})));
|
|
35625
36277
|
}
|
|
35626
36278
|
getInputPaths = () => {
|
|
@@ -35759,63 +36411,9 @@ class Matrix extends React__namespace.Component {
|
|
|
35759
36411
|
};
|
|
35760
36412
|
};
|
|
35761
36413
|
simpleValidate = rubric => {
|
|
35762
|
-
|
|
35763
|
-
return Matrix.validate(this.getUserInput(), rubric);
|
|
36414
|
+
return Matrix.validate(this.getUserInput(), rubric, this.context.strings);
|
|
35764
36415
|
};
|
|
35765
36416
|
}
|
|
35766
|
-
___default["default"].extend(Matrix, {
|
|
35767
|
-
validate: function (state, rubric) {
|
|
35768
|
-
const solution = rubric.answers;
|
|
35769
|
-
const supplied = state.answers;
|
|
35770
|
-
const solutionSize = getMatrixSize(solution);
|
|
35771
|
-
const suppliedSize = getMatrixSize(supplied);
|
|
35772
|
-
const incorrectSize = solutionSize[0] !== suppliedSize[0] || solutionSize[1] !== suppliedSize[1];
|
|
35773
|
-
const createValidator = KhanAnswerTypes.number.createValidatorFunctional;
|
|
35774
|
-
let message = null;
|
|
35775
|
-
let hasEmptyCell = false;
|
|
35776
|
-
let incorrect = false;
|
|
35777
|
-
___default["default"](suppliedSize[0]).times(row => {
|
|
35778
|
-
___default["default"](suppliedSize[1]).times(col => {
|
|
35779
|
-
if (supplied[row][col] == null || supplied[row][col].toString().length === 0) {
|
|
35780
|
-
hasEmptyCell = true;
|
|
35781
|
-
}
|
|
35782
|
-
if (!incorrectSize) {
|
|
35783
|
-
const validator = createValidator(solution[row][col], {
|
|
35784
|
-
simplify: true
|
|
35785
|
-
});
|
|
35786
|
-
const result = validator(supplied[row][col]);
|
|
35787
|
-
if (result.message) {
|
|
35788
|
-
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
|
|
35789
|
-
message = result.message;
|
|
35790
|
-
}
|
|
35791
|
-
if (!result.correct) {
|
|
35792
|
-
incorrect = true;
|
|
35793
|
-
}
|
|
35794
|
-
}
|
|
35795
|
-
});
|
|
35796
|
-
});
|
|
35797
|
-
if (hasEmptyCell) {
|
|
35798
|
-
return {
|
|
35799
|
-
type: "invalid",
|
|
35800
|
-
message: i18n__namespace._("Make sure you fill in all cells in the matrix.")
|
|
35801
|
-
};
|
|
35802
|
-
}
|
|
35803
|
-
if (incorrectSize) {
|
|
35804
|
-
return {
|
|
35805
|
-
type: "points",
|
|
35806
|
-
earned: 0,
|
|
35807
|
-
total: 1,
|
|
35808
|
-
message: null
|
|
35809
|
-
};
|
|
35810
|
-
}
|
|
35811
|
-
return {
|
|
35812
|
-
type: "points",
|
|
35813
|
-
earned: incorrect ? 0 : 1,
|
|
35814
|
-
total: 1,
|
|
35815
|
-
message: message
|
|
35816
|
-
};
|
|
35817
|
-
}
|
|
35818
|
-
});
|
|
35819
36417
|
const propTransform$1 = editorProps => {
|
|
35820
36418
|
// Remove answers before passing to widget
|
|
35821
36419
|
const blankAnswers = ___default["default"](editorProps.matrixBoardSize[0]).times(function () {
|
|
@@ -36779,6 +37377,7 @@ const parse$1 = SmilesParser.parse;
|
|
|
36779
37377
|
const ParseError = SmilesParser.ParseError;
|
|
36780
37378
|
const borderSize = 30;
|
|
36781
37379
|
class Molecule extends React__namespace.Component {
|
|
37380
|
+
static contextType = PerseusI18nContext;
|
|
36782
37381
|
state = {
|
|
36783
37382
|
parsedSmiles: null,
|
|
36784
37383
|
error: null
|
|
@@ -36855,8 +37454,8 @@ class Molecule extends React__namespace.Component {
|
|
|
36855
37454
|
// eslint-disable-next-line react/no-string-refs
|
|
36856
37455
|
,
|
|
36857
37456
|
ref: "canvas"
|
|
36858
|
-
},
|
|
36859
|
-
content: this.props.smiles
|
|
37457
|
+
}, this.context.strings.molecularDrawing({
|
|
37458
|
+
content: this.props.smiles || ""
|
|
36860
37459
|
}));
|
|
36861
37460
|
if (this.state.error) {
|
|
36862
37461
|
content = /*#__PURE__*/React__namespace.createElement("div", {
|
|
@@ -37035,6 +37634,7 @@ const TickMarks = Graphie.createSimpleClass((graphie, props) => {
|
|
|
37035
37634
|
return results;
|
|
37036
37635
|
});
|
|
37037
37636
|
class NumberLine extends React__namespace.Component {
|
|
37637
|
+
static contextType = PerseusI18nContext;
|
|
37038
37638
|
static defaultProps = {
|
|
37039
37639
|
range: [0, 10],
|
|
37040
37640
|
labelStyle: "decimal",
|
|
@@ -37347,18 +37947,21 @@ class NumberLine extends React__namespace.Component {
|
|
|
37347
37947
|
return NumberLine.validate(this.getUserInput(), rubric);
|
|
37348
37948
|
};
|
|
37349
37949
|
render() {
|
|
37950
|
+
const {
|
|
37951
|
+
strings
|
|
37952
|
+
} = this.context;
|
|
37350
37953
|
const divisionRange = this.props.divisionRange;
|
|
37351
37954
|
const divRangeString = divisionRange[0] + EN_DASH + divisionRange[1];
|
|
37352
37955
|
const invalidNumDivisions = this.props.numDivisions < divisionRange[0] || this.props.numDivisions > divisionRange[1];
|
|
37353
37956
|
const inequalityControls = /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("input", {
|
|
37354
37957
|
type: "button",
|
|
37355
37958
|
className: "simple-button",
|
|
37356
|
-
value:
|
|
37959
|
+
value: strings.switchDirection,
|
|
37357
37960
|
onClick: this.handleReverse
|
|
37358
37961
|
}), /*#__PURE__*/React__namespace.createElement("input", {
|
|
37359
37962
|
type: "button",
|
|
37360
37963
|
className: "simple-button",
|
|
37361
|
-
value: ___default["default"](["le", "ge"]).contains(this.props.rel) ?
|
|
37964
|
+
value: ___default["default"](["le", "ge"]).contains(this.props.rel) ? strings.circleOpen : strings.circleFilled,
|
|
37362
37965
|
onClick: this.handleToggleStrict
|
|
37363
37966
|
}));
|
|
37364
37967
|
let tickCtrl;
|
|
@@ -37369,7 +37972,7 @@ class NumberLine extends React__namespace.Component {
|
|
|
37369
37972
|
} else {
|
|
37370
37973
|
Input = NumberInput;
|
|
37371
37974
|
}
|
|
37372
|
-
tickCtrl = /*#__PURE__*/React__namespace.createElement("label", null,
|
|
37975
|
+
tickCtrl = /*#__PURE__*/React__namespace.createElement("label", null, strings.numDivisions, " ", /*#__PURE__*/React__namespace.createElement(Input
|
|
37373
37976
|
// eslint-disable-next-line react/no-string-refs
|
|
37374
37977
|
, {
|
|
37375
37978
|
ref: "tick-ctrl",
|
|
@@ -37386,9 +37989,9 @@ class NumberLine extends React__namespace.Component {
|
|
|
37386
37989
|
className: "perseus-widget " + "perseus-widget-interactive-number-line"
|
|
37387
37990
|
}, tickCtrl, !this.isValid() ? /*#__PURE__*/React__namespace.createElement("div", {
|
|
37388
37991
|
className: "perseus-error"
|
|
37389
|
-
},
|
|
37992
|
+
}, "Invalid number line configuration.") : this.props.isTickCtrl && invalidNumDivisions ? /*#__PURE__*/React__namespace.createElement("div", {
|
|
37390
37993
|
className: "perseus-error"
|
|
37391
|
-
},
|
|
37994
|
+
}, strings.divisions({
|
|
37392
37995
|
divRangeString: divRangeString
|
|
37393
37996
|
})) : this._renderGraphie(), !this.props.static && this.props.isInequality && inequalityControls);
|
|
37394
37997
|
}
|
|
@@ -37520,8 +38123,9 @@ const PropTypePosition = PropTypes__default["default"].shape({
|
|
|
37520
38123
|
top: PropTypes__default["default"].number
|
|
37521
38124
|
});
|
|
37522
38125
|
class Card extends React__namespace.Component {
|
|
38126
|
+
static contextType = PerseusI18nContext;
|
|
37523
38127
|
// @ts-expect-error - TS2564 - Property 'mouseMoveUpBound' has no initializer and is not definitely assigned in the constructor.
|
|
37524
|
-
|
|
38128
|
+
mouseMoveUpBound;
|
|
37525
38129
|
static propTypes = {
|
|
37526
38130
|
floating: PropTypes__default["default"].bool.isRequired,
|
|
37527
38131
|
animating: PropTypes__default["default"].bool,
|
|
@@ -37580,7 +38184,8 @@ class Card extends React__namespace.Component {
|
|
|
37580
38184
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
37581
38185
|
className: className.join(" ")
|
|
37582
38186
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, _extends({}, rendererProps, {
|
|
37583
|
-
linterContext: this.props.linterContext
|
|
38187
|
+
linterContext: this.props.linterContext,
|
|
38188
|
+
strings: this.context.strings
|
|
37584
38189
|
}))));
|
|
37585
38190
|
}
|
|
37586
38191
|
shouldComponentUpdate(nextProps, nextState) {
|
|
@@ -38853,6 +39458,7 @@ const styles$8 = aphrodite.StyleSheet.create({
|
|
|
38853
39458
|
|
|
38854
39459
|
/* eslint-disable react/no-unsafe */
|
|
38855
39460
|
class HighlightSetRenderer extends React__namespace.PureComponent {
|
|
39461
|
+
static contextType = PerseusI18nContext;
|
|
38856
39462
|
state = {
|
|
38857
39463
|
hoveredHighlightKey: null,
|
|
38858
39464
|
hoveringTooltipFor: null
|
|
@@ -38942,7 +39548,7 @@ class HighlightSetRenderer extends React__namespace.PureComponent {
|
|
|
38942
39548
|
}
|
|
38943
39549
|
const hoveredHighlight = this.props.highlights[hoveredHighlightKey];
|
|
38944
39550
|
return /*#__PURE__*/React__namespace.createElement(HighlightTooltip, {
|
|
38945
|
-
label:
|
|
39551
|
+
label: this.context.strings.removeHighlight,
|
|
38946
39552
|
focusNode: hoveredHighlight.domRange.endContainer,
|
|
38947
39553
|
focusOffset: hoveredHighlight.domRange.endOffset,
|
|
38948
39554
|
offsetParent: this.props.offsetParent,
|
|
@@ -39113,6 +39719,7 @@ class SelectionTracker extends React__namespace.PureComponent {
|
|
|
39113
39719
|
* `HighlightingUI`.
|
|
39114
39720
|
*/
|
|
39115
39721
|
class HighlightingUI extends React__namespace.PureComponent {
|
|
39722
|
+
static contextType = PerseusI18nContext;
|
|
39116
39723
|
_handleAddHighlight(highlightToAdd) {
|
|
39117
39724
|
this.props.onAddHighlight(highlightToAdd);
|
|
39118
39725
|
|
|
@@ -39169,7 +39776,7 @@ class HighlightingUI extends React__namespace.PureComponent {
|
|
|
39169
39776
|
onRemoveHighlight: this.props.onRemoveHighlight,
|
|
39170
39777
|
zIndexes: this.props.zIndexes
|
|
39171
39778
|
}), this._selectionIsValid(trackedSelection) && !userIsMouseSelecting && /*#__PURE__*/React__namespace.createElement(HighlightTooltip, {
|
|
39172
|
-
label:
|
|
39779
|
+
label: this.context.strings.addHighlight,
|
|
39173
39780
|
onClick: () => this._handleAddHighlight(trackedSelection.proposedHighlight),
|
|
39174
39781
|
focusNode: trackedSelection.focusNode,
|
|
39175
39782
|
focusOffset: trackedSelection.focusOffset,
|
|
@@ -39192,6 +39799,7 @@ class HighlightingUI extends React__namespace.PureComponent {
|
|
|
39192
39799
|
* them amenable to binary search - see `findBoundaryWordIndex` in ranges.js.
|
|
39193
39800
|
*/
|
|
39194
39801
|
class WordIndexer extends React__namespace.PureComponent {
|
|
39802
|
+
_container;
|
|
39195
39803
|
/* eslint-enable react/sort-comp */
|
|
39196
39804
|
|
|
39197
39805
|
componentDidMount() {
|
|
@@ -39311,7 +39919,8 @@ class WordIndexer extends React__namespace.PureComponent {
|
|
|
39311
39919
|
*/
|
|
39312
39920
|
class HighlightableContent extends React__namespace.PureComponent {
|
|
39313
39921
|
// References to the mounted container and content divs.
|
|
39314
|
-
|
|
39922
|
+
_container;
|
|
39923
|
+
_content;
|
|
39315
39924
|
state = {
|
|
39316
39925
|
wordRanges: []
|
|
39317
39926
|
};
|
|
@@ -39472,7 +40081,7 @@ class RefStart extends React__namespace.Component {
|
|
|
39472
40081
|
render() {
|
|
39473
40082
|
return /*#__PURE__*/React__namespace.createElement("span", {
|
|
39474
40083
|
style: REF_STYLE
|
|
39475
|
-
},
|
|
40084
|
+
}, "_");
|
|
39476
40085
|
}
|
|
39477
40086
|
|
|
39478
40087
|
// @ts-expect-error - TS2322 - Type '() => React.ReactNode' is not assignable to type '() => ReactElement<any, string | JSXElementConstructor<any>>'.
|
|
@@ -39484,9 +40093,24 @@ class RefEnd extends React__namespace.Component {
|
|
|
39484
40093
|
render() {
|
|
39485
40094
|
return /*#__PURE__*/React__namespace.createElement("span", {
|
|
39486
40095
|
style: REF_STYLE
|
|
39487
|
-
},
|
|
40096
|
+
}, "_");
|
|
39488
40097
|
}
|
|
39489
40098
|
}
|
|
40099
|
+
const AltText = _ref => {
|
|
40100
|
+
let {
|
|
40101
|
+
id,
|
|
40102
|
+
number
|
|
40103
|
+
} = _ref;
|
|
40104
|
+
const {
|
|
40105
|
+
strings
|
|
40106
|
+
} = usePerseusI18n();
|
|
40107
|
+
return /*#__PURE__*/React__namespace.createElement("span", {
|
|
40108
|
+
key: "alt-text",
|
|
40109
|
+
className: "perseus-sr-only"
|
|
40110
|
+
}, strings[id]({
|
|
40111
|
+
number
|
|
40112
|
+
}));
|
|
40113
|
+
};
|
|
39490
40114
|
const rules = {
|
|
39491
40115
|
newline: SimpleMarkdown__default["default"].defaultRules.newline,
|
|
39492
40116
|
paragraph: SimpleMarkdown__default["default"].defaultRules.paragraph,
|
|
@@ -39655,12 +40279,10 @@ const rules = {
|
|
|
39655
40279
|
"aria-hidden": "true"
|
|
39656
40280
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
39657
40281
|
style: SQUARE_LABEL_STYLE
|
|
39658
|
-
}, node.content)), /*#__PURE__*/React__namespace.createElement(
|
|
39659
|
-
|
|
39660
|
-
className: "perseus-sr-only"
|
|
39661
|
-
}, i18n__namespace.$_("[Marker for question %(number)s]", {
|
|
40282
|
+
}, node.content)), /*#__PURE__*/React__namespace.createElement(AltText, {
|
|
40283
|
+
id: "questionMarker",
|
|
39662
40284
|
number: node.content
|
|
39663
|
-
})
|
|
40285
|
+
}), node.space ? "\u00A0" : null];
|
|
39664
40286
|
}
|
|
39665
40287
|
},
|
|
39666
40288
|
circleLabel: {
|
|
@@ -39681,12 +40303,10 @@ const rules = {
|
|
|
39681
40303
|
"aria-hidden": true
|
|
39682
40304
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
39683
40305
|
style: CIRCLE_LABEL_STYLE
|
|
39684
|
-
}, node.content)), /*#__PURE__*/React__namespace.createElement(
|
|
39685
|
-
|
|
39686
|
-
className: "perseus-sr-only"
|
|
39687
|
-
}, i18n__namespace.$_("[Circle marker %(number)s]", {
|
|
40306
|
+
}, node.content)), /*#__PURE__*/React__namespace.createElement(AltText, {
|
|
40307
|
+
id: "circleMarker",
|
|
39688
40308
|
number: node.content
|
|
39689
|
-
})
|
|
40309
|
+
}), node.space ? "\u00A0" : null];
|
|
39690
40310
|
}
|
|
39691
40311
|
},
|
|
39692
40312
|
squareBracketRef: {
|
|
@@ -39706,12 +40326,10 @@ const rules = {
|
|
|
39706
40326
|
key: "visual-brackets",
|
|
39707
40327
|
className: "perseus-passage-bracket-label",
|
|
39708
40328
|
"aria-hidden": "true"
|
|
39709
|
-
}, "[", node.content, "]"), /*#__PURE__*/React__namespace.createElement(
|
|
39710
|
-
|
|
39711
|
-
className: "perseus-sr-only"
|
|
39712
|
-
}, i18n__namespace.$_("[Sentence %(number)s]", {
|
|
40329
|
+
}, "[", node.content, "]"), /*#__PURE__*/React__namespace.createElement(AltText, {
|
|
40330
|
+
id: "sentenceMarker",
|
|
39713
40331
|
number: node.content
|
|
39714
|
-
})
|
|
40332
|
+
}), node.space ? "\u00A0" : null];
|
|
39715
40333
|
}
|
|
39716
40334
|
},
|
|
39717
40335
|
highlight: {
|
|
@@ -39811,6 +40429,7 @@ var PassageMarkdown = {
|
|
|
39811
40429
|
// A fake paragraph to measure the line height of the passage,
|
|
39812
40430
|
// so we can adapt to browser zoom
|
|
39813
40431
|
class LineHeightMeasurer extends React__namespace.Component {
|
|
40432
|
+
_line;
|
|
39814
40433
|
measureLineHeight() {
|
|
39815
40434
|
if (!this._line) {
|
|
39816
40435
|
return 0;
|
|
@@ -39843,10 +40462,13 @@ const styles$6 = aphrodite.StyleSheet.create({
|
|
|
39843
40462
|
// Information about a passage reference, used in inter-widgets.
|
|
39844
40463
|
|
|
39845
40464
|
class Passage extends React__namespace.Component {
|
|
40465
|
+
static contextType = PerseusI18nContext;
|
|
40466
|
+
_contentRef;
|
|
40467
|
+
_lineHeightMeasurerRef;
|
|
39846
40468
|
// @ts-expect-error - TS2564 - Property '_onResize' has no initializer and is not definitely assigned in the constructor.
|
|
39847
|
-
|
|
40469
|
+
_onResize;
|
|
39848
40470
|
// @ts-expect-error - TS2564 - Property '_stylesAppiedTimer' has no initializer and is not definitely assigned in the constructor.
|
|
39849
|
-
|
|
40471
|
+
_stylesAppiedTimer;
|
|
39850
40472
|
static defaultProps = {
|
|
39851
40473
|
passageTitle: "",
|
|
39852
40474
|
passageText: "",
|
|
@@ -40101,15 +40723,18 @@ class Passage extends React__namespace.Component {
|
|
|
40101
40723
|
_renderInstructions(parseState) {
|
|
40102
40724
|
const firstQuestionNumber = parseState.firstQuestionRef;
|
|
40103
40725
|
const firstSentenceRef = parseState.firstSentenceRef;
|
|
40726
|
+
const {
|
|
40727
|
+
strings
|
|
40728
|
+
} = this.context;
|
|
40104
40729
|
let instructions = "";
|
|
40105
40730
|
if (firstQuestionNumber) {
|
|
40106
|
-
instructions +=
|
|
40731
|
+
instructions += strings.symbolPassage({
|
|
40107
40732
|
questionSymbol: "[[" + firstQuestionNumber + "]]",
|
|
40108
40733
|
questionNumber: firstQuestionNumber
|
|
40109
40734
|
});
|
|
40110
40735
|
}
|
|
40111
40736
|
if (firstSentenceRef) {
|
|
40112
|
-
instructions +=
|
|
40737
|
+
instructions += strings.symbolQuestion({
|
|
40113
40738
|
sentenceSymbol: "[" + firstSentenceRef + "]"
|
|
40114
40739
|
});
|
|
40115
40740
|
}
|
|
@@ -40155,6 +40780,9 @@ class Passage extends React__namespace.Component {
|
|
|
40155
40780
|
return PassageMarkdown.output(parsed);
|
|
40156
40781
|
}
|
|
40157
40782
|
render() {
|
|
40783
|
+
const {
|
|
40784
|
+
strings
|
|
40785
|
+
} = this.context;
|
|
40158
40786
|
let lineNumbers;
|
|
40159
40787
|
const nLines = this.state.nLines;
|
|
40160
40788
|
if (this.props.showLineNumbers && nLines) {
|
|
@@ -40163,9 +40791,7 @@ class Passage extends React__namespace.Component {
|
|
|
40163
40791
|
lineNumbers = ___default["default"].range(1, nLines + 1).map(lineN => {
|
|
40164
40792
|
const lineAt = lineN + this.state.startLineNumbersAfter;
|
|
40165
40793
|
if (lineAt === 4) {
|
|
40166
|
-
|
|
40167
|
-
// I18N: a label next to a reading passage to denote the line number
|
|
40168
|
-
const translatedLine = i18n__namespace._("Line ");
|
|
40794
|
+
const translatedLine = strings.lineLabel;
|
|
40169
40795
|
return /*#__PURE__*/React__namespace.createElement("span", {
|
|
40170
40796
|
key: "line-marker",
|
|
40171
40797
|
className: "line-marker"
|
|
@@ -40195,13 +40821,14 @@ class Passage extends React__namespace.Component {
|
|
|
40195
40821
|
className: "passage-title"
|
|
40196
40822
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
40197
40823
|
content: this.props.passageTitle,
|
|
40198
|
-
linterContext: this.props.linterContext
|
|
40824
|
+
linterContext: this.props.linterContext,
|
|
40825
|
+
strings: strings
|
|
40199
40826
|
})), lineNumbers && /*#__PURE__*/React__namespace.createElement("div", {
|
|
40200
40827
|
className: "line-numbers",
|
|
40201
40828
|
"aria-hidden": true
|
|
40202
40829
|
}, lineNumbers), !hasTitle && /*#__PURE__*/React__namespace.createElement("h3", {
|
|
40203
40830
|
className: "perseus-sr-only"
|
|
40204
|
-
},
|
|
40831
|
+
}, strings.beginningPassage), /*#__PURE__*/React__namespace.createElement("div", {
|
|
40205
40832
|
className: "passage-text"
|
|
40206
40833
|
}, this.shouldRenderJipt() ?
|
|
40207
40834
|
/*#__PURE__*/
|
|
@@ -40209,16 +40836,17 @@ class Passage extends React__namespace.Component {
|
|
|
40209
40836
|
// content to a <Renderer /> which knows how
|
|
40210
40837
|
// to handle rendering JIPT text.
|
|
40211
40838
|
React__namespace.createElement(Renderer, {
|
|
40212
|
-
content: this.props.passageText
|
|
40839
|
+
content: this.props.passageText,
|
|
40840
|
+
strings: strings
|
|
40213
40841
|
}) : this._renderContent(parsedContent)), this._hasFootnotes() && [/*#__PURE__*/React__namespace.createElement("h4", {
|
|
40214
40842
|
key: "footnote-start",
|
|
40215
40843
|
className: "perseus-sr-only"
|
|
40216
|
-
},
|
|
40844
|
+
}, strings.beginningFootnotes), /*#__PURE__*/React__namespace.createElement("div", {
|
|
40217
40845
|
key: "footnotes",
|
|
40218
40846
|
className: "footnotes"
|
|
40219
40847
|
}, this._renderFootnotes())], /*#__PURE__*/React__namespace.createElement("div", {
|
|
40220
40848
|
className: "perseus-sr-only"
|
|
40221
|
-
},
|
|
40849
|
+
}, strings.endPassage))));
|
|
40222
40850
|
}
|
|
40223
40851
|
}
|
|
40224
40852
|
var Passage$1 = {
|
|
@@ -40233,6 +40861,7 @@ var Passage$1 = {
|
|
|
40233
40861
|
|
|
40234
40862
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
40235
40863
|
class PassageRefTarget extends React__namespace.Component {
|
|
40864
|
+
static contextType = PerseusI18nContext;
|
|
40236
40865
|
static defaultProps = {
|
|
40237
40866
|
content: "",
|
|
40238
40867
|
linterContext: PerseusLinter.linterContextDefault
|
|
@@ -40270,7 +40899,8 @@ class PassageRefTarget extends React__namespace.Component {
|
|
|
40270
40899
|
// inline={true}
|
|
40271
40900
|
,
|
|
40272
40901
|
apiOptions: this.props.apiOptions,
|
|
40273
|
-
linterContext: this.props.linterContext
|
|
40902
|
+
linterContext: this.props.linterContext,
|
|
40903
|
+
strings: this.context.strings
|
|
40274
40904
|
});
|
|
40275
40905
|
}
|
|
40276
40906
|
}
|
|
@@ -40295,9 +40925,13 @@ const {
|
|
|
40295
40925
|
deepEq
|
|
40296
40926
|
} = Util;
|
|
40297
40927
|
class Plotter extends React__namespace.Component {
|
|
40928
|
+
static contextType = PerseusI18nContext;
|
|
40298
40929
|
// @ts-expect-error - TS2564 - Property 'shouldSetupGraphie' has no initializer and is not definitely assigned in the constructor.
|
|
40299
|
-
|
|
40930
|
+
shouldSetupGraphie;
|
|
40300
40931
|
_isMounted = false;
|
|
40932
|
+
horizHairline;
|
|
40933
|
+
hairlineRange;
|
|
40934
|
+
graphie;
|
|
40301
40935
|
static defaultProps = {
|
|
40302
40936
|
type: "bar",
|
|
40303
40937
|
labels: ["", ""],
|
|
@@ -40484,11 +41118,11 @@ class Plotter extends React__namespace.Component {
|
|
|
40484
41118
|
}
|
|
40485
41119
|
}
|
|
40486
41120
|
if ((isBar || isLine) && isMobile && !this.props.static) {
|
|
40487
|
-
self.graphie.dragPrompt = graphie.label([c.dimX / 2, c.dimY / 2],
|
|
41121
|
+
self.graphie.dragPrompt = graphie.label([c.dimX / 2, c.dimY / 2], this.context.strings.dragHandles, "center", false).css("font-weight", "bold").css("color", KhanColors.KA_GREEN).css("display", "none");
|
|
40488
41122
|
}
|
|
40489
41123
|
self.setupCategories(config);
|
|
40490
41124
|
if (isTiledPlot && isMobile) {
|
|
40491
|
-
self.graphie.dotPrompt = graphie.label([c.dimX / 2, c.dimY / 2],
|
|
41125
|
+
self.graphie.dotPrompt = graphie.label([c.dimX / 2, c.dimY / 2], this.context.strings.tapAddPoints, "center", false).css("font-weight", "bold").css("color", KhanColors.KA_GREEN).css("display", "none");
|
|
40492
41126
|
}
|
|
40493
41127
|
if (isTiledPlot) {
|
|
40494
41128
|
self.drawPicHeights(self.state.values, prevState.values);
|
|
@@ -41163,7 +41797,7 @@ const HORIZONTAL = "horizontal";
|
|
|
41163
41797
|
const VERTICAL = "vertical";
|
|
41164
41798
|
class Sorter extends React__namespace.Component {
|
|
41165
41799
|
// @ts-expect-error - TS2564 - Property '_isMounted' has no initializer and is not definitely assigned in the constructor.
|
|
41166
|
-
|
|
41800
|
+
_isMounted;
|
|
41167
41801
|
static propTypes = {
|
|
41168
41802
|
apiOptions: ApiOptions.propTypes,
|
|
41169
41803
|
// eslint-disable-next-line react/forbid-prop-types
|
|
@@ -41306,6 +41940,7 @@ const getRefForPath = function (path) {
|
|
|
41306
41940
|
return "answer" + row + "," + column;
|
|
41307
41941
|
};
|
|
41308
41942
|
class Table extends React__namespace.Component {
|
|
41943
|
+
static contextType = PerseusI18nContext;
|
|
41309
41944
|
static propTypes = {
|
|
41310
41945
|
answers: PropTypes__default["default"].arrayOf(PropTypes__default["default"].arrayOf(PropTypes__default["default"].string)),
|
|
41311
41946
|
editableHeaders: PropTypes__default["default"].bool,
|
|
@@ -41375,7 +42010,8 @@ class Table extends React__namespace.Component {
|
|
|
41375
42010
|
key: i
|
|
41376
42011
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
41377
42012
|
content: header,
|
|
41378
|
-
linterContext: this.props.linterContext
|
|
42013
|
+
linterContext: this.props.linterContext,
|
|
42014
|
+
strings: this.context.strings
|
|
41379
42015
|
}));
|
|
41380
42016
|
}))), /*#__PURE__*/React__namespace.createElement("tbody", null, ___default["default"](rows).times(r => {
|
|
41381
42017
|
return /*#__PURE__*/React__namespace.createElement("tr", {
|
|
@@ -41420,7 +42056,7 @@ class Table extends React__namespace.Component {
|
|
|
41420
42056
|
};
|
|
41421
42057
|
simpleValidate = rubric => {
|
|
41422
42058
|
// @ts-expect-error - TS2339 - Property 'validate' does not exist on type 'typeof Table'.
|
|
41423
|
-
return Table.validate(this.getUserInput(), rubric);
|
|
42059
|
+
return Table.validate(this.getUserInput(), rubric, this.context.strings);
|
|
41424
42060
|
};
|
|
41425
42061
|
_handleFocus = inputPath => {
|
|
41426
42062
|
this.props.onFocus(inputPath);
|
|
@@ -41489,7 +42125,7 @@ class Table extends React__namespace.Component {
|
|
|
41489
42125
|
};
|
|
41490
42126
|
}
|
|
41491
42127
|
___default["default"].extend(Table, {
|
|
41492
|
-
validate: function (state, rubric) {
|
|
42128
|
+
validate: function (state, rubric, strings) {
|
|
41493
42129
|
const filterNonEmpty = function (table) {
|
|
41494
42130
|
return ___default["default"].filter(table, function (row) {
|
|
41495
42131
|
// Check if row has a cell that is nonempty
|
|
@@ -41527,7 +42163,7 @@ ___default["default"].extend(Table, {
|
|
|
41527
42163
|
const cellSolution = rowSolution[i];
|
|
41528
42164
|
const validator = createValidator(cellSolution, {
|
|
41529
42165
|
simplify: true
|
|
41530
|
-
});
|
|
42166
|
+
}, strings);
|
|
41531
42167
|
const result = validator(cellSupplied);
|
|
41532
42168
|
if (result.message) {
|
|
41533
42169
|
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
|
|
@@ -41814,6 +42450,11 @@ const str = {
|
|
|
41814
42450
|
* @param s A string representation of a floating point.
|
|
41815
42451
|
*/
|
|
41816
42452
|
class SignificantFigures {
|
|
42453
|
+
order;
|
|
42454
|
+
mantissa;
|
|
42455
|
+
positive;
|
|
42456
|
+
sigFigs;
|
|
42457
|
+
sigDecs;
|
|
41817
42458
|
constructor(s) {
|
|
41818
42459
|
this.order = parseOrder(s);
|
|
41819
42460
|
this.mantissa = parseMantissa(s);
|
|
@@ -42222,17 +42863,19 @@ const countSigfigs = function (value) {
|
|
|
42222
42863
|
* rolling two second delay, but hidden immediately on further typing.
|
|
42223
42864
|
*/
|
|
42224
42865
|
class OldUnitInput extends React__namespace.Component {
|
|
42866
|
+
static contextType = PerseusI18nContext;
|
|
42867
|
+
_errorTimeout;
|
|
42225
42868
|
static defaultProps = {
|
|
42226
42869
|
apiOptions: ApiOptions.defaults,
|
|
42227
42870
|
value: ""
|
|
42228
42871
|
};
|
|
42229
|
-
static validate(userInput, rubric) {
|
|
42872
|
+
static validate(userInput, rubric, strings) {
|
|
42230
42873
|
const answer = KAS__namespace.unitParse(rubric.value).expr;
|
|
42231
42874
|
const guess = KAS__namespace.unitParse(userInput);
|
|
42232
42875
|
if (!guess.parsed) {
|
|
42233
42876
|
return {
|
|
42234
42877
|
type: "invalid",
|
|
42235
|
-
message:
|
|
42878
|
+
message: strings.dontUnderstandUnits
|
|
42236
42879
|
};
|
|
42237
42880
|
}
|
|
42238
42881
|
|
|
@@ -42247,8 +42890,7 @@ class OldUnitInput extends React__namespace.Component {
|
|
|
42247
42890
|
const sigfigs = rubric.sigfigs;
|
|
42248
42891
|
const sigfigsCorrect = countSigfigs(guess.coefficient) === sigfigs;
|
|
42249
42892
|
if (!sigfigsCorrect) {
|
|
42250
|
-
|
|
42251
|
-
message = i18n__namespace._("Check your significant figures.");
|
|
42893
|
+
message = strings.checkSigFigs;
|
|
42252
42894
|
}
|
|
42253
42895
|
|
|
42254
42896
|
// now we need to check that the answer is correct to the precision we
|
|
@@ -42267,8 +42909,7 @@ class OldUnitInput extends React__namespace.Component {
|
|
|
42267
42909
|
numericallyCorrect = false;
|
|
42268
42910
|
}
|
|
42269
42911
|
if (!numericallyCorrect) {
|
|
42270
|
-
|
|
42271
|
-
message = i18n__namespace._("That answer is numerically incorrect.");
|
|
42912
|
+
message = strings.answerNumericallyIncorrect;
|
|
42272
42913
|
}
|
|
42273
42914
|
let kasCorrect;
|
|
42274
42915
|
const guessUnit = primUnits(guess.expr.simplify());
|
|
@@ -42288,8 +42929,7 @@ class OldUnitInput extends React__namespace.Component {
|
|
|
42288
42929
|
});
|
|
42289
42930
|
}
|
|
42290
42931
|
if (!kasCorrect) {
|
|
42291
|
-
|
|
42292
|
-
message = i18n__namespace._("Check your units.");
|
|
42932
|
+
message = strings.checkUnits;
|
|
42293
42933
|
}
|
|
42294
42934
|
const correct = kasCorrect && numericallyCorrect && sigfigsCorrect;
|
|
42295
42935
|
return {
|
|
@@ -42385,7 +43025,7 @@ class OldUnitInput extends React__namespace.Component {
|
|
|
42385
43025
|
});
|
|
42386
43026
|
};
|
|
42387
43027
|
simpleValidate = (rubric, onInputError) => {
|
|
42388
|
-
return OldUnitInput.validate(this.getUserInput(), rubric);
|
|
43028
|
+
return OldUnitInput.validate(this.getUserInput(), rubric, this.context.strings);
|
|
42389
43029
|
};
|
|
42390
43030
|
getUserInput = () => {
|
|
42391
43031
|
return this.props.value;
|
|
@@ -42460,7 +43100,7 @@ class OldUnitInput extends React__namespace.Component {
|
|
|
42460
43100
|
style: {
|
|
42461
43101
|
display: "none"
|
|
42462
43102
|
}
|
|
42463
|
-
},
|
|
43103
|
+
}, this.context.strings.dontUnderstand));
|
|
42464
43104
|
}
|
|
42465
43105
|
}
|
|
42466
43106
|
|
|
@@ -42512,9 +43152,12 @@ const VideoTranscriptLink = props => {
|
|
|
42512
43152
|
// which is used by our GraphQL framework.
|
|
42513
43153
|
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'VideoKind'.
|
|
42514
43154
|
const result = useVideo(id, kind);
|
|
43155
|
+
const {
|
|
43156
|
+
strings
|
|
43157
|
+
} = usePerseusI18n();
|
|
42515
43158
|
switch (result.status) {
|
|
42516
43159
|
case "loading":
|
|
42517
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null,
|
|
43160
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, strings.loading);
|
|
42518
43161
|
case "success":
|
|
42519
43162
|
{
|
|
42520
43163
|
const video = result.data?.video;
|
|
@@ -42526,14 +43169,14 @@ const VideoTranscriptLink = props => {
|
|
|
42526
43169
|
href: "/transcript/" + (video?.contentId || "videoNotFound"),
|
|
42527
43170
|
target: "_blank",
|
|
42528
43171
|
className: "visited-no-recolor"
|
|
42529
|
-
},
|
|
43172
|
+
}, strings.videoTranscript));
|
|
42530
43173
|
}
|
|
42531
43174
|
case "error":
|
|
42532
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null,
|
|
43175
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, strings.somethingWrong);
|
|
42533
43176
|
case "aborted":
|
|
42534
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null,
|
|
43177
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, strings.somethingWrong);
|
|
42535
43178
|
default:
|
|
42536
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null,
|
|
43179
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, strings.somethingWrong);
|
|
42537
43180
|
}
|
|
42538
43181
|
};
|
|
42539
43182
|
const styles$4 = aphrodite.StyleSheet.create({
|
|
@@ -42561,6 +43204,7 @@ const IS_VIMEO = /(vimeo\.com)/;
|
|
|
42561
43204
|
* Video renderer.
|
|
42562
43205
|
*/
|
|
42563
43206
|
class Video extends React__namespace.Component {
|
|
43207
|
+
static contextType = PerseusI18nContext;
|
|
42564
43208
|
/**
|
|
42565
43209
|
* This is the widget's grading function.
|
|
42566
43210
|
* Points for videos are tallied by the embedded video itself, in the case
|
|
@@ -42628,7 +43272,7 @@ class Video extends React__namespace.Component {
|
|
|
42628
43272
|
key: location + this.props.alignment
|
|
42629
43273
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
42630
43274
|
style: a11y.srOnly
|
|
42631
|
-
},
|
|
43275
|
+
}, this.context.strings.videoWrapper), /*#__PURE__*/React__namespace.createElement("iframe", {
|
|
42632
43276
|
// TODO(joshuan): Consider not using iframes when we're
|
|
42633
43277
|
// loading this from webapp. This iframe is problematic
|
|
42634
43278
|
// for screenreaders.
|
|
@@ -42692,7 +43336,7 @@ const init = function (options) {
|
|
|
42692
43336
|
|
|
42693
43337
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
42694
43338
|
const libName = "@khanacademy/perseus";
|
|
42695
|
-
const libVersion = "
|
|
43339
|
+
const libVersion = "22.0.1";
|
|
42696
43340
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
42697
43341
|
|
|
42698
43342
|
const apiVersion = {
|
|
@@ -42711,6 +43355,8 @@ const ItemVersion = getVersionVector();
|
|
|
42711
43355
|
ItemVersion["::renderer::"] = itemDataVersion;
|
|
42712
43356
|
|
|
42713
43357
|
class ArticleRenderer extends React__namespace.Component {
|
|
43358
|
+
static contextType = PerseusI18nContext;
|
|
43359
|
+
_currentFocus;
|
|
42714
43360
|
sectionRenderers = [];
|
|
42715
43361
|
static defaultProps = {
|
|
42716
43362
|
apiOptions: ApiOptions.defaults,
|
|
@@ -42866,8 +43512,9 @@ class ArticleRenderer extends React__namespace.Component {
|
|
|
42866
43512
|
}
|
|
42867
43513
|
},
|
|
42868
43514
|
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "article"),
|
|
42869
|
-
legacyPerseusLint: this.props.legacyPerseusLint
|
|
42870
|
-
|
|
43515
|
+
legacyPerseusLint: this.props.legacyPerseusLint,
|
|
43516
|
+
strings: this.context.strings
|
|
43517
|
+
})));
|
|
42871
43518
|
});
|
|
42872
43519
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
42873
43520
|
className: classes
|
|
@@ -42879,6 +43526,7 @@ class ArticleRenderer extends React__namespace.Component {
|
|
|
42879
43526
|
|
|
42880
43527
|
/* Renders just a hint preview */
|
|
42881
43528
|
class HintRenderer extends React__namespace.Component {
|
|
43529
|
+
static contextType = PerseusI18nContext;
|
|
42882
43530
|
static defaultProps = {
|
|
42883
43531
|
linterContext: PerseusLinter__namespace.linterContextDefault
|
|
42884
43532
|
};
|
|
@@ -42924,7 +43572,7 @@ class HintRenderer extends React__namespace.Component {
|
|
|
42924
43572
|
tabIndex: "-1"
|
|
42925
43573
|
}, !apiOptions.isMobile && /*#__PURE__*/React__namespace.createElement("span", {
|
|
42926
43574
|
className: "perseus-sr-only"
|
|
42927
|
-
},
|
|
43575
|
+
}, this.context.strings.hintPos({
|
|
42928
43576
|
pos: pos + 1
|
|
42929
43577
|
})), !apiOptions.isMobile && totalHints != null && pos != null && /*#__PURE__*/React__namespace.createElement("span", {
|
|
42930
43578
|
className: "perseus-hint-label",
|
|
@@ -42941,7 +43589,8 @@ class HintRenderer extends React__namespace.Component {
|
|
|
42941
43589
|
images: hint.images,
|
|
42942
43590
|
apiOptions: rendererApiOptions,
|
|
42943
43591
|
findExternalWidgets: this.props.findExternalWidgets,
|
|
42944
|
-
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "hint")
|
|
43592
|
+
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "hint"),
|
|
43593
|
+
strings: this.context.strings
|
|
42945
43594
|
}))
|
|
42946
43595
|
);
|
|
42947
43596
|
}
|
|
@@ -42976,6 +43625,7 @@ const styles$3 = aphrodite.StyleSheet.create({
|
|
|
42976
43625
|
// Use of UNSAFE_componentWillReceiveProps:
|
|
42977
43626
|
// eslint-disable-next-line react/no-unsafe
|
|
42978
43627
|
class HintsRenderer extends React__namespace.Component {
|
|
43628
|
+
static contextType = PerseusI18nContext;
|
|
42979
43629
|
static defaultProps = {
|
|
42980
43630
|
linterContext: PerseusLinter__namespace.linterContextDefault
|
|
42981
43631
|
};
|
|
@@ -43128,7 +43778,7 @@ class HintsRenderer extends React__namespace.Component {
|
|
|
43128
43778
|
className: classNames
|
|
43129
43779
|
}, apiOptions.isMobile && hintsVisible > 0 && /*#__PURE__*/React__namespace.createElement("div", {
|
|
43130
43780
|
className: aphrodite.css(styles$2.mobileHintStylesHintTitle, sharedStyles.responsiveLabel)
|
|
43131
|
-
},
|
|
43781
|
+
}, this.context.strings.hints), hints, showGetAnotherHint && /*#__PURE__*/React__namespace.createElement("button", {
|
|
43132
43782
|
// @ts-expect-error - TS2322 - Type '{ children: Element[]; rel: string; className: string; onClick: (evt: MouseEvent<HTMLButtonElement, MouseEvent>) => void; }' is not assignable to type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'.
|
|
43133
43783
|
rel: "button",
|
|
43134
43784
|
className: aphrodite.css(styles$2.linkButton, styles$2.getAnotherHintButton, apiOptions.isMobile && styles$2.mobileHintStylesGetAnotherHintButton),
|
|
@@ -43143,7 +43793,7 @@ class HintsRenderer extends React__namespace.Component {
|
|
|
43143
43793
|
className: aphrodite.css(styles$2.plusText, apiOptions.isMobile && styles$2.mobileHintStylesPlusText)
|
|
43144
43794
|
}, "+"), /*#__PURE__*/React__namespace.createElement("span", {
|
|
43145
43795
|
className: aphrodite.css(styles$2.getAnotherHintText)
|
|
43146
|
-
},
|
|
43796
|
+
}, this.context.strings.getAnotherHint, " ", hintRatioCopy)));
|
|
43147
43797
|
}
|
|
43148
43798
|
}
|
|
43149
43799
|
const hintIndentation = baseUnitPx + hintBorderWidth;
|
|
@@ -43246,8 +43896,13 @@ const {
|
|
|
43246
43896
|
} = objective_;
|
|
43247
43897
|
/* eslint-disable-next-line react/no-unsafe */
|
|
43248
43898
|
class ServerItemRenderer extends React__namespace.Component {
|
|
43899
|
+
static contextType = PerseusI18nContext;
|
|
43249
43900
|
// @ts-expect-error - TS2564 - Property 'questionRenderer' has no initializer and is not definitely assigned in the constructor.
|
|
43250
|
-
|
|
43901
|
+
questionRenderer;
|
|
43902
|
+
hintsRenderer;
|
|
43903
|
+
_currentFocus;
|
|
43904
|
+
_fullyRendered;
|
|
43905
|
+
blurTimeoutID;
|
|
43251
43906
|
static defaultProps = {
|
|
43252
43907
|
apiOptions: {},
|
|
43253
43908
|
// a deep default is done in `this.update()`
|
|
@@ -43539,14 +44194,16 @@ class ServerItemRenderer extends React__namespace.Component {
|
|
|
43539
44194
|
content: this.props.item.question.content,
|
|
43540
44195
|
widgets: this.props.item.question.widgets,
|
|
43541
44196
|
images: this.props.item.question.images,
|
|
43542
|
-
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "question")
|
|
44197
|
+
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "question"),
|
|
44198
|
+
strings: this.context.strings
|
|
43543
44199
|
}, this.props.dependencies)));
|
|
43544
44200
|
const hintsRenderer = /*#__PURE__*/React__namespace.createElement(HintsRenderer, {
|
|
43545
44201
|
hints: this.props.item.hints,
|
|
43546
44202
|
hintsVisible: this.props.hintsVisible,
|
|
43547
44203
|
apiOptions: apiOptions,
|
|
43548
44204
|
ref: elem => this.hintsRenderer = elem,
|
|
43549
|
-
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "hints")
|
|
44205
|
+
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "hints"),
|
|
44206
|
+
strings: this.context.strings
|
|
43550
44207
|
});
|
|
43551
44208
|
return /*#__PURE__*/React__namespace.createElement(DependenciesContext.Provider, {
|
|
43552
44209
|
value: this.props.dependencies
|
|
@@ -43719,115 +44376,6 @@ var constants = /*#__PURE__*/Object.freeze({
|
|
|
43719
44376
|
perseusFrameBorderWidth: perseusFrameBorderWidth
|
|
43720
44377
|
});
|
|
43721
44378
|
|
|
43722
|
-
// TODO(FEI-4010): Remove `Perseus` prefix for all types here
|
|
43723
|
-
// TODO(FEI-4011): Use types generated by https://github.com/jaredly/generate-perseus-flowtypes
|
|
43724
|
-
|
|
43725
|
-
// Range is replaced within this file with Interval, but it is used elsewhere
|
|
43726
|
-
// and exported from the package, so we need to keep it around.
|
|
43727
|
-
// TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
|
|
43728
|
-
const ItemExtras = [
|
|
43729
|
-
// The user might benefit from using a Scientific Calculator. Provided on Khan Academy when true
|
|
43730
|
-
"calculator",
|
|
43731
|
-
// The user might benefit from using a statistics Chi Squared Table like https://people.richland.edu/james/lecture/m170/tbl-chi.html
|
|
43732
|
-
"chi2Table",
|
|
43733
|
-
// The user might benefit from a monthly payments calculator. Provided on Khan Academy when true
|
|
43734
|
-
"financialCalculatorMonthlyPayment",
|
|
43735
|
-
// The user might benefit from a total amount calculator. Provided on Khan Academy when true
|
|
43736
|
-
"financialCalculatorTotalAmount",
|
|
43737
|
-
// The user might benefit from a time to pay off calculator. Provided on Khan Academy when true
|
|
43738
|
-
"financialCalculatorTimeToPayOff",
|
|
43739
|
-
// The user might benefit from using a Periodic Table of Elements. Provided on Khan Academy when true
|
|
43740
|
-
"periodicTable",
|
|
43741
|
-
// The user might benefit from using a Periodic Table of Elements with key. Provided on Khan Academy when true
|
|
43742
|
-
"periodicTableWithKey",
|
|
43743
|
-
// The user might benefit from using a statistics T Table like https://www.statisticshowto.com/tables/t-distribution-table/
|
|
43744
|
-
"tTable",
|
|
43745
|
-
// The user might benefit from using a statistics Z Table like https://www.ztable.net/
|
|
43746
|
-
"zTable"];
|
|
43747
|
-
|
|
43748
|
-
// prettier-ignore
|
|
43749
|
-
|
|
43750
|
-
// prettier-ignore
|
|
43751
|
-
|
|
43752
|
-
// prettier-ignore
|
|
43753
|
-
|
|
43754
|
-
// prettier-ignore
|
|
43755
|
-
|
|
43756
|
-
// prettier-ignore
|
|
43757
|
-
|
|
43758
|
-
// prettier-ignore
|
|
43759
|
-
|
|
43760
|
-
// prettier-ignore
|
|
43761
|
-
|
|
43762
|
-
// prettier-ignore
|
|
43763
|
-
|
|
43764
|
-
// prettier-ignore
|
|
43765
|
-
|
|
43766
|
-
// prettier-ignore
|
|
43767
|
-
|
|
43768
|
-
// prettier-ignore
|
|
43769
|
-
|
|
43770
|
-
// prettier-ignore
|
|
43771
|
-
|
|
43772
|
-
// prettier-ignore
|
|
43773
|
-
|
|
43774
|
-
// prettier-ignore
|
|
43775
|
-
|
|
43776
|
-
// prettier-ignore
|
|
43777
|
-
|
|
43778
|
-
// prettier-ignore
|
|
43779
|
-
|
|
43780
|
-
// prettier-ignore
|
|
43781
|
-
|
|
43782
|
-
// prettier-ignore
|
|
43783
|
-
|
|
43784
|
-
// prettier-ignore
|
|
43785
|
-
|
|
43786
|
-
// prettier-ignore
|
|
43787
|
-
|
|
43788
|
-
// prettier-ignore
|
|
43789
|
-
|
|
43790
|
-
// prettier-ignore
|
|
43791
|
-
|
|
43792
|
-
// prettier-ignore
|
|
43793
|
-
|
|
43794
|
-
// prettier-ignore
|
|
43795
|
-
|
|
43796
|
-
// prettier-ignore
|
|
43797
|
-
|
|
43798
|
-
// prettier-ignore
|
|
43799
|
-
|
|
43800
|
-
// prettier-ignore
|
|
43801
|
-
|
|
43802
|
-
// prettier-ignore
|
|
43803
|
-
|
|
43804
|
-
// prettier-ignore
|
|
43805
|
-
|
|
43806
|
-
// prettier-ignore
|
|
43807
|
-
|
|
43808
|
-
// prettier-ignore
|
|
43809
|
-
|
|
43810
|
-
// prettier-ignore
|
|
43811
|
-
|
|
43812
|
-
// prettier-ignore
|
|
43813
|
-
|
|
43814
|
-
// prettier-ignore
|
|
43815
|
-
|
|
43816
|
-
// prettier-ignore
|
|
43817
|
-
|
|
43818
|
-
// prettier-ignore
|
|
43819
|
-
|
|
43820
|
-
//prettier-ignore
|
|
43821
|
-
|
|
43822
|
-
// A background image applied to various widgets.
|
|
43823
|
-
|
|
43824
|
-
const PerseusExpressionAnswerFormConsidered = ["correct", "wrong", "ungraded"];
|
|
43825
|
-
|
|
43826
|
-
// 2D range: xMin, xMax, yMin, yMax
|
|
43827
|
-
|
|
43828
|
-
const lockedFigureColors = ["purple", "blue", "teal", "green", "gold", "red", "pink"];
|
|
43829
|
-
const plotterPlotTypes = ["bar", "line", "pic", "histogram", "dotplot"];
|
|
43830
|
-
|
|
43831
44379
|
/**
|
|
43832
44380
|
* Traverses a {content, widgets, images} renderer props object,
|
|
43833
44381
|
* such as `itemData.question`
|
|
@@ -44068,6 +44616,10 @@ var shapes = {
|
|
|
44068
44616
|
* TreeMapperForLeavesAndCollections.
|
|
44069
44617
|
*/
|
|
44070
44618
|
class TreeMapperJustForLeaves {
|
|
44619
|
+
content;
|
|
44620
|
+
hint;
|
|
44621
|
+
tags;
|
|
44622
|
+
array;
|
|
44071
44623
|
constructor(content, hint, tags) {
|
|
44072
44624
|
this.content = content;
|
|
44073
44625
|
this.hint = hint;
|
|
@@ -44098,6 +44650,10 @@ class TreeMapperJustForLeaves {
|
|
|
44098
44650
|
* ContentMapper and HintMapper are now locked in.
|
|
44099
44651
|
*/
|
|
44100
44652
|
class TreeMapperForLeavesAndCollections {
|
|
44653
|
+
content;
|
|
44654
|
+
hint;
|
|
44655
|
+
tags;
|
|
44656
|
+
array;
|
|
44101
44657
|
constructor(content, hint, tags, array) {
|
|
44102
44658
|
this.content = content;
|
|
44103
44659
|
this.hint = hint;
|
|
@@ -44356,6 +44912,9 @@ function treeToItem(node) {
|
|
|
44356
44912
|
// @ts-expect-error - TS2315 - Type 'Tree' is not generic.
|
|
44357
44913
|
// @ts-expect-error - TS2315 - Type 'Tree' is not generic.
|
|
44358
44914
|
class MultiRenderer extends React__namespace.Component {
|
|
44915
|
+
static contextType = PerseusI18nContext;
|
|
44916
|
+
rendererDataTreeMapper;
|
|
44917
|
+
getRenderersMapper;
|
|
44359
44918
|
constructor(props) {
|
|
44360
44919
|
super(props);
|
|
44361
44920
|
this.rendererDataTreeMapper = buildMapper()
|
|
@@ -44430,7 +44989,10 @@ class MultiRenderer extends React__namespace.Component {
|
|
|
44430
44989
|
onSerializedStateUpdated: _____,
|
|
44431
44990
|
...otherProps
|
|
44432
44991
|
} = this.props;
|
|
44433
|
-
return
|
|
44992
|
+
return {
|
|
44993
|
+
...otherProps,
|
|
44994
|
+
strings: this.context.strings
|
|
44995
|
+
};
|
|
44434
44996
|
}
|
|
44435
44997
|
|
|
44436
44998
|
/**
|
|
@@ -44679,7 +45241,7 @@ class MultiRenderer extends React__namespace.Component {
|
|
|
44679
45241
|
if (this.state.renderError) {
|
|
44680
45242
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
44681
45243
|
className: aphrodite.css(styles.error)
|
|
44682
|
-
},
|
|
45244
|
+
}, this.context.strings.errorRendering({
|
|
44683
45245
|
error: String(this.state.renderError)
|
|
44684
45246
|
}));
|
|
44685
45247
|
}
|
|
@@ -45821,6 +46383,8 @@ exports.MultiItems = MultiItems;
|
|
|
45821
46383
|
exports.NumericInput = NumericInput$1;
|
|
45822
46384
|
exports.PerseusError = PerseusError;
|
|
45823
46385
|
exports.PerseusExpressionAnswerFormConsidered = PerseusExpressionAnswerFormConsidered;
|
|
46386
|
+
exports.PerseusI18nContext = PerseusI18nContext;
|
|
46387
|
+
exports.PerseusI18nContextProvider = PerseusI18nContextProvider;
|
|
45824
46388
|
exports.PerseusMarkdown = PerseusMarkdown;
|
|
45825
46389
|
exports.PlotterWidget = Plotter$1;
|
|
45826
46390
|
exports.QUESTION_WIDGETS = QUESTION_WIDGETS;
|
|
@@ -45881,6 +46445,7 @@ exports.registerAllWidgetsForTesting = registerAllWidgetsForTesting;
|
|
|
45881
46445
|
exports.shapes = shapes;
|
|
45882
46446
|
exports.shouldHaveIndividualAnswer = shouldHaveIndividualAnswer;
|
|
45883
46447
|
exports.traverse = traverse;
|
|
46448
|
+
exports.usePerseusI18n = usePerseusI18n;
|
|
45884
46449
|
exports.violatingWidgets = violatingWidgets;
|
|
45885
46450
|
exports.widgets = allWidgets;
|
|
45886
46451
|
//# sourceMappingURL=index.js.map
|