@khanacademy/perseus 23.4.0 → 23.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/input-with-examples.d.ts +0 -4
- package/dist/es/index.css +0 -17
- package/dist/es/index.js +276 -338
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +0 -17
- package/dist/index.d.ts +2 -2
- package/dist/index.js +274 -333
- package/dist/index.js.map +1 -1
- package/dist/perseus-api.d.ts +2 -1
- package/dist/perseus-types.d.ts +16 -8
- package/dist/server-item-renderer.d.ts +2 -1
- package/dist/types.d.ts +1 -1
- package/dist/widgets/expression.d.ts +12 -6
- package/dist/widgets/interactive-graphs/graphs/sinusoid.d.ts +1 -1
- package/dist/widgets/interactive-graphs/graphs/use-draggable.d.ts +13 -0
- package/dist/widgets/interactive-graphs/interactive-graph-question-builder.d.ts +9 -3
- package/dist/widgets/interactive-graphs/{locked-ellipse.d.ts → locked-figures/locked-ellipse.d.ts} +1 -1
- package/dist/widgets/interactive-graphs/{locked-line.d.ts → locked-figures/locked-line.d.ts} +1 -1
- package/dist/widgets/interactive-graphs/{locked-point.d.ts → locked-figures/locked-point.d.ts} +1 -1
- package/dist/widgets/interactive-graphs/locked-figures/locked-polygon.d.ts +4 -0
- package/dist/widgets/interactive-graphs/{locked-vector.d.ts → locked-figures/locked-vector.d.ts} +1 -1
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +2 -1
- package/dist/widgets/interactive-graphs/reducer/initialize-graph-state.d.ts +3 -2
- package/dist/widgets/interactive-graphs/reducer/interactive-graph-action.d.ts +8 -1
- package/dist/widgets/label-image.d.ts +4 -2
- package/package.json +1 -1
- package/dist/components/math-output.d.ts +0 -27
package/dist/index.js
CHANGED
|
@@ -21203,251 +21203,6 @@ const styles$B = {
|
|
|
21203
21203
|
}
|
|
21204
21204
|
};
|
|
21205
21205
|
|
|
21206
|
-
/*
|
|
21207
|
-
* In this file, an `expression` is some portion of valid TeX enclosed in
|
|
21208
|
-
* curly brackets.
|
|
21209
|
-
*/
|
|
21210
|
-
|
|
21211
|
-
/*
|
|
21212
|
-
* Find the index at which an expression ends, i.e., has an unmatched
|
|
21213
|
-
* closing curly bracket. This method assumes that we start with a non-open
|
|
21214
|
-
* bracket character and end when we've seen more left than right brackets
|
|
21215
|
-
* (rather than assuming that we start with a bracket character and wait for
|
|
21216
|
-
* bracket equality).
|
|
21217
|
-
*/
|
|
21218
|
-
function findEndpoint(tex, currentIndex) {
|
|
21219
|
-
let bracketDepth = 0;
|
|
21220
|
-
for (let i = currentIndex, len = tex.length; i < len; i++) {
|
|
21221
|
-
const c = tex[i];
|
|
21222
|
-
if (c === "{") {
|
|
21223
|
-
bracketDepth++;
|
|
21224
|
-
} else if (c === "}") {
|
|
21225
|
-
bracketDepth--;
|
|
21226
|
-
}
|
|
21227
|
-
if (bracketDepth < 0) {
|
|
21228
|
-
return i;
|
|
21229
|
-
}
|
|
21230
|
-
}
|
|
21231
|
-
// If we never see unbalanced curly brackets, default to the
|
|
21232
|
-
// entire string
|
|
21233
|
-
return tex.length;
|
|
21234
|
-
}
|
|
21235
|
-
|
|
21236
|
-
/*
|
|
21237
|
-
* Parses an individual set of curly brackets into TeX.
|
|
21238
|
-
*/
|
|
21239
|
-
function parseNextExpression(tex, currentIndex, handler) {
|
|
21240
|
-
// Find the first '{' and grab subsequent TeX
|
|
21241
|
-
// Ex) tex: '{3}{7}', and we want the '3'
|
|
21242
|
-
const openBracketIndex = tex.indexOf("{", currentIndex);
|
|
21243
|
-
const nextExpIndex = openBracketIndex + 1;
|
|
21244
|
-
|
|
21245
|
-
// Truncate to only contain remaining TeX
|
|
21246
|
-
const endpoint = findEndpoint(tex, nextExpIndex);
|
|
21247
|
-
const expressionTeX = tex.substring(nextExpIndex, endpoint);
|
|
21248
|
-
const parsedExp = walkTex(expressionTeX, handler);
|
|
21249
|
-
return {
|
|
21250
|
-
endpoint: endpoint,
|
|
21251
|
-
expression: parsedExp
|
|
21252
|
-
};
|
|
21253
|
-
}
|
|
21254
|
-
function getNextFracIndex(tex, currentIndex) {
|
|
21255
|
-
const dfrac = "\\dfrac";
|
|
21256
|
-
const frac = "\\frac";
|
|
21257
|
-
const nextFrac = tex.indexOf(frac, currentIndex);
|
|
21258
|
-
const nextDFrac = tex.indexOf(dfrac, currentIndex);
|
|
21259
|
-
if (nextFrac > -1 && nextDFrac > -1) {
|
|
21260
|
-
return Math.min(nextFrac, nextDFrac);
|
|
21261
|
-
}
|
|
21262
|
-
if (nextFrac > -1) {
|
|
21263
|
-
return nextFrac;
|
|
21264
|
-
}
|
|
21265
|
-
if (nextDFrac > -1) {
|
|
21266
|
-
return nextDFrac;
|
|
21267
|
-
}
|
|
21268
|
-
return -1;
|
|
21269
|
-
}
|
|
21270
|
-
function walkTex(tex, handler) {
|
|
21271
|
-
if (!tex) {
|
|
21272
|
-
return "";
|
|
21273
|
-
}
|
|
21274
|
-
|
|
21275
|
-
// Ex) tex: '2 \dfrac {3}{7}'
|
|
21276
|
-
let parsedString = "";
|
|
21277
|
-
let currentIndex = 0;
|
|
21278
|
-
let nextFrac = getNextFracIndex(tex, currentIndex);
|
|
21279
|
-
|
|
21280
|
-
// For each \dfrac, find the two expressions (wrapped in {}) and recur
|
|
21281
|
-
while (nextFrac > -1) {
|
|
21282
|
-
// Gather first fragment, preceding \dfrac
|
|
21283
|
-
// Ex) parsedString: '2 '
|
|
21284
|
-
parsedString += tex.substring(currentIndex, nextFrac);
|
|
21285
|
-
|
|
21286
|
-
// Remove everything preceding \dfrac, which has been parsed
|
|
21287
|
-
currentIndex = nextFrac;
|
|
21288
|
-
|
|
21289
|
-
// Parse first expression and move index past it
|
|
21290
|
-
// Ex) firstParsedExpression.expression: '3'
|
|
21291
|
-
const firstParsedExpression = parseNextExpression(tex, currentIndex, handler);
|
|
21292
|
-
currentIndex = firstParsedExpression.endpoint + 1;
|
|
21293
|
-
|
|
21294
|
-
// Parse second expression
|
|
21295
|
-
// Ex) secondParsedExpression.expression: '7'
|
|
21296
|
-
const secondParsedExpression = parseNextExpression(tex, currentIndex, handler);
|
|
21297
|
-
currentIndex = secondParsedExpression.endpoint + 1;
|
|
21298
|
-
|
|
21299
|
-
// Add expressions to running total of parsed expressions
|
|
21300
|
-
if (parsedString.length) {
|
|
21301
|
-
parsedString += " ";
|
|
21302
|
-
}
|
|
21303
|
-
|
|
21304
|
-
// Apply a custom handler based on the parsed subexpressions
|
|
21305
|
-
parsedString += handler(firstParsedExpression.expression, secondParsedExpression.expression);
|
|
21306
|
-
|
|
21307
|
-
// Find next DFrac, relative to currentIndex
|
|
21308
|
-
nextFrac = getNextFracIndex(tex, currentIndex);
|
|
21309
|
-
}
|
|
21310
|
-
|
|
21311
|
-
// Add remaining TeX, which is \dfrac-free
|
|
21312
|
-
parsedString += tex.slice(currentIndex);
|
|
21313
|
-
return parsedString;
|
|
21314
|
-
}
|
|
21315
|
-
|
|
21316
|
-
/*
|
|
21317
|
-
* Modify a TeX expression, returning another TeX expression. The resulting
|
|
21318
|
-
* expression will have its innermost fractions stubbed out with \fracs
|
|
21319
|
-
* (as opposed to \dfracs). All other content will remain untouched.
|
|
21320
|
-
*/
|
|
21321
|
-
function modifyTex(tex) {
|
|
21322
|
-
function isNestedFraction(tex) {
|
|
21323
|
-
return tex.indexOf("\\frac") > -1 || tex.indexOf("\\dfrac") > -1;
|
|
21324
|
-
}
|
|
21325
|
-
const handler = function (exp1, exp2) {
|
|
21326
|
-
let prefix;
|
|
21327
|
-
if (isNestedFraction(exp1) || isNestedFraction(exp2)) {
|
|
21328
|
-
prefix = "\\dfrac";
|
|
21329
|
-
} else {
|
|
21330
|
-
prefix = "\\frac";
|
|
21331
|
-
}
|
|
21332
|
-
return prefix + " {" + exp1 + "}{" + exp2 + "}";
|
|
21333
|
-
};
|
|
21334
|
-
return walkTex(tex, handler);
|
|
21335
|
-
}
|
|
21336
|
-
|
|
21337
|
-
/*
|
|
21338
|
-
* Parse a TeX expression into something interpretable by input-number.
|
|
21339
|
-
* The process is concerned with: (1) parsing fractions, i.e., \dfracs; and
|
|
21340
|
-
* (2) removing backslash-escaping from certain characters (right now, only
|
|
21341
|
-
* percent signs).
|
|
21342
|
-
*
|
|
21343
|
-
* The basic algorithm for handling \dfracs splits on \dfracs and then recurs
|
|
21344
|
-
* on the subsequent "expressions", i.e., the {} pairs that follow \dfrac. The
|
|
21345
|
-
* recursion is to allow for nested \dfrac elements.
|
|
21346
|
-
*
|
|
21347
|
-
* Backslash-escapes are removed with a simple search-and-replace.
|
|
21348
|
-
*/
|
|
21349
|
-
function parseTex(tex) {
|
|
21350
|
-
const handler = function (exp1, exp2) {
|
|
21351
|
-
return exp1 + "/" + exp2;
|
|
21352
|
-
};
|
|
21353
|
-
const texWithoutFracs = walkTex(tex, handler);
|
|
21354
|
-
return texWithoutFracs.replace("\\%", "%");
|
|
21355
|
-
}
|
|
21356
|
-
var TexWrangler = {
|
|
21357
|
-
parseTex,
|
|
21358
|
-
modifyTex
|
|
21359
|
-
};
|
|
21360
|
-
|
|
21361
|
-
/* eslint-disable react/sort-comp */
|
|
21362
|
-
const ModifyTex = TexWrangler.modifyTex;
|
|
21363
|
-
class MathOutput extends React__namespace.Component {
|
|
21364
|
-
static defaultProps = {
|
|
21365
|
-
value: "",
|
|
21366
|
-
onFocus: function () {},
|
|
21367
|
-
onBlur: function () {}
|
|
21368
|
-
};
|
|
21369
|
-
state = {
|
|
21370
|
-
focused: false,
|
|
21371
|
-
selectorNamespace: ___default["default"].uniqueId("math-output")
|
|
21372
|
-
};
|
|
21373
|
-
_getInputClassName = () => {
|
|
21374
|
-
let className = "math-output " + ClassNames.INPUT + " " + ClassNames.INTERACTIVE;
|
|
21375
|
-
if (this.state.focused) {
|
|
21376
|
-
className += " " + ClassNames.FOCUSED;
|
|
21377
|
-
}
|
|
21378
|
-
if (this.props.className) {
|
|
21379
|
-
className += " " + this.props.className;
|
|
21380
|
-
}
|
|
21381
|
-
return className;
|
|
21382
|
-
};
|
|
21383
|
-
_getDisplayValue = value => {
|
|
21384
|
-
// Cast from (potentially a) number to string
|
|
21385
|
-
let displayText;
|
|
21386
|
-
if (value != null) {
|
|
21387
|
-
displayText = "" + value;
|
|
21388
|
-
} else {
|
|
21389
|
-
displayText = "";
|
|
21390
|
-
}
|
|
21391
|
-
return ModifyTex(displayText);
|
|
21392
|
-
};
|
|
21393
|
-
render() {
|
|
21394
|
-
const divStyle = {
|
|
21395
|
-
textAlign: "center"
|
|
21396
|
-
};
|
|
21397
|
-
const {
|
|
21398
|
-
TeX
|
|
21399
|
-
} = getDependencies();
|
|
21400
|
-
return /*#__PURE__*/React__namespace.createElement("span", {
|
|
21401
|
-
// eslint-disable-next-line react/no-string-refs
|
|
21402
|
-
ref: "input",
|
|
21403
|
-
className: this._getInputClassName(),
|
|
21404
|
-
"aria-label": this.props.labelText,
|
|
21405
|
-
onMouseDown: this.focus,
|
|
21406
|
-
onTouchStart: this.focus
|
|
21407
|
-
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
21408
|
-
style: divStyle
|
|
21409
|
-
}, /*#__PURE__*/React__namespace.createElement(TeX, null, this._getDisplayValue(this.props.value))));
|
|
21410
|
-
}
|
|
21411
|
-
getValue = () => {
|
|
21412
|
-
return this.props.value;
|
|
21413
|
-
};
|
|
21414
|
-
focus = () => {
|
|
21415
|
-
if (!this.state.focused) {
|
|
21416
|
-
this.props.onFocus();
|
|
21417
|
-
this._bindBlurHandler();
|
|
21418
|
-
this.setState({
|
|
21419
|
-
focused: true
|
|
21420
|
-
});
|
|
21421
|
-
}
|
|
21422
|
-
};
|
|
21423
|
-
blur = () => {
|
|
21424
|
-
if (this.state.focused) {
|
|
21425
|
-
this.props.onBlur();
|
|
21426
|
-
this._unbindBlurHandler();
|
|
21427
|
-
this.setState({
|
|
21428
|
-
focused: false
|
|
21429
|
-
});
|
|
21430
|
-
}
|
|
21431
|
-
};
|
|
21432
|
-
_bindBlurHandler = () => {
|
|
21433
|
-
$__default["default"](document).bind("vclick." + this.state.selectorNamespace, e => {
|
|
21434
|
-
// Detect whether the target has our React DOM node as a parent
|
|
21435
|
-
const $closestWidget = $__default["default"](e.target).closest(
|
|
21436
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
21437
|
-
ReactDOM__default["default"].findDOMNode(this));
|
|
21438
|
-
if (!$closestWidget.length) {
|
|
21439
|
-
this.blur();
|
|
21440
|
-
}
|
|
21441
|
-
});
|
|
21442
|
-
};
|
|
21443
|
-
_unbindBlurHandler = () => {
|
|
21444
|
-
$__default["default"](document).unbind("." + this.state.selectorNamespace);
|
|
21445
|
-
};
|
|
21446
|
-
componentWillUnmount() {
|
|
21447
|
-
this._unbindBlurHandler();
|
|
21448
|
-
}
|
|
21449
|
-
}
|
|
21450
|
-
|
|
21451
21206
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
21452
21207
|
let lastId = 0;
|
|
21453
21208
|
function uniqueIdForInput() {
|
|
@@ -21788,7 +21543,6 @@ const {
|
|
|
21788
21543
|
class InputWithExamples extends React__namespace.Component {
|
|
21789
21544
|
static contextType = PerseusI18nContext;
|
|
21790
21545
|
static defaultProps = {
|
|
21791
|
-
type: "text",
|
|
21792
21546
|
shouldShowExamples: true,
|
|
21793
21547
|
onFocus: function () {},
|
|
21794
21548
|
onBlur: function () {},
|
|
@@ -21804,12 +21558,6 @@ class InputWithExamples extends React__namespace.Component {
|
|
|
21804
21558
|
return `input-with-examples-${btoa(this.props.id).replace(/=/g, "")}`;
|
|
21805
21559
|
};
|
|
21806
21560
|
_getInputClassName = () => {
|
|
21807
|
-
// <MathOutput> is a special component that manages its own class and
|
|
21808
|
-
// state, as it's a <span> that wants to act like an <input>.
|
|
21809
|
-
if (this.props.type === "tex") {
|
|
21810
|
-
return this.props.className;
|
|
21811
|
-
}
|
|
21812
|
-
|
|
21813
21561
|
// Otherwise, we need to add these INPUT and FOCUSED tags here.
|
|
21814
21562
|
let className = ClassNames.INPUT + " " + ClassNames.INTERACTIVE;
|
|
21815
21563
|
if (this.state.focused) {
|
|
@@ -21820,8 +21568,7 @@ class InputWithExamples extends React__namespace.Component {
|
|
|
21820
21568
|
}
|
|
21821
21569
|
return className;
|
|
21822
21570
|
};
|
|
21823
|
-
|
|
21824
|
-
// Minimal set of props, used by each input type
|
|
21571
|
+
_renderInput = () => {
|
|
21825
21572
|
const id = this._getUniqueId();
|
|
21826
21573
|
const inputProps = {
|
|
21827
21574
|
id: id,
|
|
@@ -21833,63 +21580,18 @@ class InputWithExamples extends React__namespace.Component {
|
|
|
21833
21580
|
onFocus: this._handleFocus,
|
|
21834
21581
|
onBlur: this._handleBlur,
|
|
21835
21582
|
disabled: this.props.disabled,
|
|
21836
|
-
style: this.props.style
|
|
21837
|
-
};
|
|
21838
|
-
if (this.props.type === "tex") {
|
|
21839
|
-
return inputProps;
|
|
21840
|
-
}
|
|
21841
|
-
|
|
21842
|
-
// Add useful props required for MATH and TEXT modes
|
|
21843
|
-
___default["default"].extend(inputProps, {
|
|
21583
|
+
style: this.props.style,
|
|
21844
21584
|
onChange: this.props.onChange,
|
|
21845
|
-
onTouchStart: captureScratchpadTouchStart$2
|
|
21846
|
-
|
|
21847
|
-
|
|
21848
|
-
|
|
21849
|
-
|
|
21850
|
-
|
|
21851
|
-
|
|
21852
|
-
buttonsVisible: this.props.buttonsVisible,
|
|
21853
|
-
convertDotToTimes: this.props.convertDotToTimes
|
|
21854
|
-
}, inputProps);
|
|
21855
|
-
}
|
|
21856
|
-
if (this.props.type === "text") {
|
|
21857
|
-
return ___default["default"].extend({
|
|
21858
|
-
autoCapitalize: "off",
|
|
21859
|
-
autoComplete: "off",
|
|
21860
|
-
autoCorrect: "off",
|
|
21861
|
-
spellCheck: "false"
|
|
21862
|
-
}, inputProps);
|
|
21863
|
-
}
|
|
21864
|
-
};
|
|
21865
|
-
_getComponentForInputType = () => {
|
|
21866
|
-
switch (this.props.type) {
|
|
21867
|
-
case "tex":
|
|
21868
|
-
return MathOutput;
|
|
21869
|
-
case "math":
|
|
21870
|
-
return MathInput;
|
|
21871
|
-
case "text":
|
|
21872
|
-
return TextInput;
|
|
21873
|
-
default:
|
|
21874
|
-
this.props.type;
|
|
21875
|
-
return null;
|
|
21876
|
-
}
|
|
21877
|
-
};
|
|
21878
|
-
_renderInput = () => {
|
|
21879
|
-
const inputProps = this._getPropsForInputType();
|
|
21880
|
-
const InputComponent = this._getComponentForInputType();
|
|
21881
|
-
return /*#__PURE__*/React__namespace.createElement(InputComponent, inputProps);
|
|
21585
|
+
onTouchStart: captureScratchpadTouchStart$2,
|
|
21586
|
+
autoCapitalize: "off",
|
|
21587
|
+
autoComplete: "off",
|
|
21588
|
+
autoCorrect: "off",
|
|
21589
|
+
spellCheck: "false"
|
|
21590
|
+
};
|
|
21591
|
+
return /*#__PURE__*/React__namespace.createElement(TextInput, inputProps);
|
|
21882
21592
|
};
|
|
21883
21593
|
render() {
|
|
21884
21594
|
const input = this._renderInput();
|
|
21885
|
-
|
|
21886
|
-
// Static rendering, which doesn't include the 'tooltip' logic that the
|
|
21887
|
-
// other types require, and is hence handled separately.
|
|
21888
|
-
if (this.props.type === "tex") {
|
|
21889
|
-
return input;
|
|
21890
|
-
}
|
|
21891
|
-
|
|
21892
|
-
// Else, we need to be able to show examples
|
|
21893
21595
|
const examplesContent = ___default["default"].map(this.props.examples, example => {
|
|
21894
21596
|
return "- " + example;
|
|
21895
21597
|
}).join("\n");
|
|
@@ -22025,6 +21727,161 @@ SimpleKeypadInput.propTypes = {
|
|
|
22025
21727
|
value: PropTypes__default["default"].oneOfType([PropTypes__default["default"].string, PropTypes__default["default"].number])
|
|
22026
21728
|
};
|
|
22027
21729
|
|
|
21730
|
+
/*
|
|
21731
|
+
* In this file, an `expression` is some portion of valid TeX enclosed in
|
|
21732
|
+
* curly brackets.
|
|
21733
|
+
*/
|
|
21734
|
+
|
|
21735
|
+
/*
|
|
21736
|
+
* Find the index at which an expression ends, i.e., has an unmatched
|
|
21737
|
+
* closing curly bracket. This method assumes that we start with a non-open
|
|
21738
|
+
* bracket character and end when we've seen more left than right brackets
|
|
21739
|
+
* (rather than assuming that we start with a bracket character and wait for
|
|
21740
|
+
* bracket equality).
|
|
21741
|
+
*/
|
|
21742
|
+
function findEndpoint(tex, currentIndex) {
|
|
21743
|
+
let bracketDepth = 0;
|
|
21744
|
+
for (let i = currentIndex, len = tex.length; i < len; i++) {
|
|
21745
|
+
const c = tex[i];
|
|
21746
|
+
if (c === "{") {
|
|
21747
|
+
bracketDepth++;
|
|
21748
|
+
} else if (c === "}") {
|
|
21749
|
+
bracketDepth--;
|
|
21750
|
+
}
|
|
21751
|
+
if (bracketDepth < 0) {
|
|
21752
|
+
return i;
|
|
21753
|
+
}
|
|
21754
|
+
}
|
|
21755
|
+
// If we never see unbalanced curly brackets, default to the
|
|
21756
|
+
// entire string
|
|
21757
|
+
return tex.length;
|
|
21758
|
+
}
|
|
21759
|
+
|
|
21760
|
+
/*
|
|
21761
|
+
* Parses an individual set of curly brackets into TeX.
|
|
21762
|
+
*/
|
|
21763
|
+
function parseNextExpression(tex, currentIndex, handler) {
|
|
21764
|
+
// Find the first '{' and grab subsequent TeX
|
|
21765
|
+
// Ex) tex: '{3}{7}', and we want the '3'
|
|
21766
|
+
const openBracketIndex = tex.indexOf("{", currentIndex);
|
|
21767
|
+
const nextExpIndex = openBracketIndex + 1;
|
|
21768
|
+
|
|
21769
|
+
// Truncate to only contain remaining TeX
|
|
21770
|
+
const endpoint = findEndpoint(tex, nextExpIndex);
|
|
21771
|
+
const expressionTeX = tex.substring(nextExpIndex, endpoint);
|
|
21772
|
+
const parsedExp = walkTex(expressionTeX, handler);
|
|
21773
|
+
return {
|
|
21774
|
+
endpoint: endpoint,
|
|
21775
|
+
expression: parsedExp
|
|
21776
|
+
};
|
|
21777
|
+
}
|
|
21778
|
+
function getNextFracIndex(tex, currentIndex) {
|
|
21779
|
+
const dfrac = "\\dfrac";
|
|
21780
|
+
const frac = "\\frac";
|
|
21781
|
+
const nextFrac = tex.indexOf(frac, currentIndex);
|
|
21782
|
+
const nextDFrac = tex.indexOf(dfrac, currentIndex);
|
|
21783
|
+
if (nextFrac > -1 && nextDFrac > -1) {
|
|
21784
|
+
return Math.min(nextFrac, nextDFrac);
|
|
21785
|
+
}
|
|
21786
|
+
if (nextFrac > -1) {
|
|
21787
|
+
return nextFrac;
|
|
21788
|
+
}
|
|
21789
|
+
if (nextDFrac > -1) {
|
|
21790
|
+
return nextDFrac;
|
|
21791
|
+
}
|
|
21792
|
+
return -1;
|
|
21793
|
+
}
|
|
21794
|
+
function walkTex(tex, handler) {
|
|
21795
|
+
if (!tex) {
|
|
21796
|
+
return "";
|
|
21797
|
+
}
|
|
21798
|
+
|
|
21799
|
+
// Ex) tex: '2 \dfrac {3}{7}'
|
|
21800
|
+
let parsedString = "";
|
|
21801
|
+
let currentIndex = 0;
|
|
21802
|
+
let nextFrac = getNextFracIndex(tex, currentIndex);
|
|
21803
|
+
|
|
21804
|
+
// For each \dfrac, find the two expressions (wrapped in {}) and recur
|
|
21805
|
+
while (nextFrac > -1) {
|
|
21806
|
+
// Gather first fragment, preceding \dfrac
|
|
21807
|
+
// Ex) parsedString: '2 '
|
|
21808
|
+
parsedString += tex.substring(currentIndex, nextFrac);
|
|
21809
|
+
|
|
21810
|
+
// Remove everything preceding \dfrac, which has been parsed
|
|
21811
|
+
currentIndex = nextFrac;
|
|
21812
|
+
|
|
21813
|
+
// Parse first expression and move index past it
|
|
21814
|
+
// Ex) firstParsedExpression.expression: '3'
|
|
21815
|
+
const firstParsedExpression = parseNextExpression(tex, currentIndex, handler);
|
|
21816
|
+
currentIndex = firstParsedExpression.endpoint + 1;
|
|
21817
|
+
|
|
21818
|
+
// Parse second expression
|
|
21819
|
+
// Ex) secondParsedExpression.expression: '7'
|
|
21820
|
+
const secondParsedExpression = parseNextExpression(tex, currentIndex, handler);
|
|
21821
|
+
currentIndex = secondParsedExpression.endpoint + 1;
|
|
21822
|
+
|
|
21823
|
+
// Add expressions to running total of parsed expressions
|
|
21824
|
+
if (parsedString.length) {
|
|
21825
|
+
parsedString += " ";
|
|
21826
|
+
}
|
|
21827
|
+
|
|
21828
|
+
// Apply a custom handler based on the parsed subexpressions
|
|
21829
|
+
parsedString += handler(firstParsedExpression.expression, secondParsedExpression.expression);
|
|
21830
|
+
|
|
21831
|
+
// Find next DFrac, relative to currentIndex
|
|
21832
|
+
nextFrac = getNextFracIndex(tex, currentIndex);
|
|
21833
|
+
}
|
|
21834
|
+
|
|
21835
|
+
// Add remaining TeX, which is \dfrac-free
|
|
21836
|
+
parsedString += tex.slice(currentIndex);
|
|
21837
|
+
return parsedString;
|
|
21838
|
+
}
|
|
21839
|
+
|
|
21840
|
+
/*
|
|
21841
|
+
* Modify a TeX expression, returning another TeX expression. The resulting
|
|
21842
|
+
* expression will have its innermost fractions stubbed out with \fracs
|
|
21843
|
+
* (as opposed to \dfracs). All other content will remain untouched.
|
|
21844
|
+
*/
|
|
21845
|
+
function modifyTex(tex) {
|
|
21846
|
+
function isNestedFraction(tex) {
|
|
21847
|
+
return tex.indexOf("\\frac") > -1 || tex.indexOf("\\dfrac") > -1;
|
|
21848
|
+
}
|
|
21849
|
+
const handler = function (exp1, exp2) {
|
|
21850
|
+
let prefix;
|
|
21851
|
+
if (isNestedFraction(exp1) || isNestedFraction(exp2)) {
|
|
21852
|
+
prefix = "\\dfrac";
|
|
21853
|
+
} else {
|
|
21854
|
+
prefix = "\\frac";
|
|
21855
|
+
}
|
|
21856
|
+
return prefix + " {" + exp1 + "}{" + exp2 + "}";
|
|
21857
|
+
};
|
|
21858
|
+
return walkTex(tex, handler);
|
|
21859
|
+
}
|
|
21860
|
+
|
|
21861
|
+
/*
|
|
21862
|
+
* Parse a TeX expression into something interpretable by input-number.
|
|
21863
|
+
* The process is concerned with: (1) parsing fractions, i.e., \dfracs; and
|
|
21864
|
+
* (2) removing backslash-escaping from certain characters (right now, only
|
|
21865
|
+
* percent signs).
|
|
21866
|
+
*
|
|
21867
|
+
* The basic algorithm for handling \dfracs splits on \dfracs and then recurs
|
|
21868
|
+
* on the subsequent "expressions", i.e., the {} pairs that follow \dfrac. The
|
|
21869
|
+
* recursion is to allow for nested \dfrac elements.
|
|
21870
|
+
*
|
|
21871
|
+
* Backslash-escapes are removed with a simple search-and-replace.
|
|
21872
|
+
*/
|
|
21873
|
+
function parseTex(tex) {
|
|
21874
|
+
const handler = function (exp1, exp2) {
|
|
21875
|
+
return exp1 + "/" + exp2;
|
|
21876
|
+
};
|
|
21877
|
+
const texWithoutFracs = walkTex(tex, handler);
|
|
21878
|
+
return texWithoutFracs.replace("\\%", "%");
|
|
21879
|
+
}
|
|
21880
|
+
var TexWrangler = {
|
|
21881
|
+
parseTex,
|
|
21882
|
+
modifyTex
|
|
21883
|
+
};
|
|
21884
|
+
|
|
22028
21885
|
/* eslint-disable react/sort-comp */
|
|
22029
21886
|
const ParseTex$1 = TexWrangler.parseTex;
|
|
22030
21887
|
const answerTypes = {
|
|
@@ -22145,7 +22002,6 @@ class InputNumber extends React__namespace.Component {
|
|
|
22145
22002
|
value: this.props.currentValue,
|
|
22146
22003
|
onChange: this.handleChange,
|
|
22147
22004
|
style: inputStyles,
|
|
22148
|
-
type: "text",
|
|
22149
22005
|
examples: this.examples(),
|
|
22150
22006
|
shouldShowExamples: this.shouldShowExamples(),
|
|
22151
22007
|
onFocus: this._handleFocus,
|
|
@@ -22612,7 +22468,6 @@ class NumericInput extends React__namespace.Component {
|
|
|
22612
22468
|
value: this.props.currentValue,
|
|
22613
22469
|
onChange: this.handleChange,
|
|
22614
22470
|
labelText: labelText,
|
|
22615
|
-
type: "text",
|
|
22616
22471
|
examples: this.examples(),
|
|
22617
22472
|
shouldShowExamples: this.shouldShowExamples(),
|
|
22618
22473
|
onFocus: this._handleFocus,
|
|
@@ -28947,13 +28802,15 @@ const ItemExtras = [
|
|
|
28947
28802
|
|
|
28948
28803
|
const PerseusExpressionAnswerFormConsidered = ["correct", "wrong", "ungraded"];
|
|
28949
28804
|
const lockedFigureColors = {
|
|
28805
|
+
blue: "#3D7586",
|
|
28950
28806
|
green: "#447A53",
|
|
28951
28807
|
grayH: "#3B3D45",
|
|
28952
28808
|
purple: "#594094",
|
|
28953
28809
|
pink: "#B25071",
|
|
28954
|
-
red: "#D92916"
|
|
28810
|
+
red: "#D92916",
|
|
28811
|
+
orange: "#946700"
|
|
28955
28812
|
};
|
|
28956
|
-
const
|
|
28813
|
+
const lockedFigureFillStyles = {
|
|
28957
28814
|
none: 0,
|
|
28958
28815
|
solid: 1,
|
|
28959
28816
|
translucent: 0.4
|
|
@@ -28973,7 +28830,7 @@ const LockedEllipse = props => {
|
|
|
28973
28830
|
center: center,
|
|
28974
28831
|
radius: radius,
|
|
28975
28832
|
angle: angle,
|
|
28976
|
-
fillOpacity:
|
|
28833
|
+
fillOpacity: lockedFigureFillStyles[fillStyle],
|
|
28977
28834
|
strokeStyle: strokeStyle,
|
|
28978
28835
|
color: lockedFigureColors[color]
|
|
28979
28836
|
});
|
|
@@ -29232,6 +29089,29 @@ const LockedPoint = props => {
|
|
|
29232
29089
|
});
|
|
29233
29090
|
};
|
|
29234
29091
|
|
|
29092
|
+
const LockedPolygon = props => {
|
|
29093
|
+
const {
|
|
29094
|
+
points,
|
|
29095
|
+
color,
|
|
29096
|
+
showVertices,
|
|
29097
|
+
fillStyle,
|
|
29098
|
+
strokeStyle
|
|
29099
|
+
} = props;
|
|
29100
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
29101
|
+
className: "locked-polygon"
|
|
29102
|
+
}, /*#__PURE__*/React__namespace.createElement(mafs.Polygon, {
|
|
29103
|
+
points: [...points],
|
|
29104
|
+
fillOpacity: lockedFigureFillStyles[fillStyle],
|
|
29105
|
+
strokeStyle: strokeStyle,
|
|
29106
|
+
color: lockedFigureColors[color]
|
|
29107
|
+
}), showVertices && points.map((point, index) => /*#__PURE__*/React__namespace.createElement(mafs.Point, {
|
|
29108
|
+
key: `locked-polygon-point-${index}`,
|
|
29109
|
+
x: point[0],
|
|
29110
|
+
y: point[1],
|
|
29111
|
+
color: lockedFigureColors[color]
|
|
29112
|
+
})));
|
|
29113
|
+
};
|
|
29114
|
+
|
|
29235
29115
|
const LockedVector = props => {
|
|
29236
29116
|
const {
|
|
29237
29117
|
color,
|
|
@@ -29262,13 +29142,17 @@ const GraphLockedLayer = props => {
|
|
|
29262
29142
|
key: `line-${index}`,
|
|
29263
29143
|
range: props.range
|
|
29264
29144
|
}, figure));
|
|
29145
|
+
case "vector":
|
|
29146
|
+
return /*#__PURE__*/React__namespace.createElement(LockedVector, _extends({
|
|
29147
|
+
key: `vector-${index}`
|
|
29148
|
+
}, figure));
|
|
29265
29149
|
case "ellipse":
|
|
29266
29150
|
return /*#__PURE__*/React__namespace.createElement(LockedEllipse, _extends({
|
|
29267
29151
|
key: `ellipse-${index}`
|
|
29268
29152
|
}, figure));
|
|
29269
|
-
case "
|
|
29270
|
-
return /*#__PURE__*/React__namespace.createElement(
|
|
29271
|
-
key: `
|
|
29153
|
+
case "polygon":
|
|
29154
|
+
return /*#__PURE__*/React__namespace.createElement(LockedPolygon, _extends({
|
|
29155
|
+
key: `polygon-${index}`
|
|
29272
29156
|
}, figure));
|
|
29273
29157
|
default:
|
|
29274
29158
|
/**
|
|
@@ -29282,6 +29166,13 @@ const GraphLockedLayer = props => {
|
|
|
29282
29166
|
}));
|
|
29283
29167
|
};
|
|
29284
29168
|
|
|
29169
|
+
const REINITIALIZE = "reinitialize";
|
|
29170
|
+
function reinitialize(params) {
|
|
29171
|
+
return {
|
|
29172
|
+
type: REINITIALIZE,
|
|
29173
|
+
params
|
|
29174
|
+
};
|
|
29175
|
+
}
|
|
29285
29176
|
const MOVE_CONTROL_POINT = "move-control-point";
|
|
29286
29177
|
function moveControlPoint(pointIndex, destination, itemIndex) {
|
|
29287
29178
|
return {
|
|
@@ -29374,6 +29265,10 @@ function snap(snapStep, point) {
|
|
|
29374
29265
|
return [Math.round(requestedX / snapX) * snapX, Math.round(requestedY / snapY) * snapY];
|
|
29375
29266
|
}
|
|
29376
29267
|
|
|
29268
|
+
function useDraggable(params) {
|
|
29269
|
+
return mafs.useMovable(params);
|
|
29270
|
+
}
|
|
29271
|
+
|
|
29377
29272
|
// The hitbox size of 48px by 48px is preserved from the legacy interactive
|
|
29378
29273
|
// graph.
|
|
29379
29274
|
const hitboxSizePx = 48;
|
|
@@ -29529,7 +29424,7 @@ function useControlPoint(point, color, onMovePoint) {
|
|
|
29529
29424
|
} = useGraphConfig();
|
|
29530
29425
|
const [focused, setFocused] = React.useState(false);
|
|
29531
29426
|
const keyboardHandleRef = React.useRef(null);
|
|
29532
|
-
|
|
29427
|
+
useDraggable({
|
|
29533
29428
|
gestureTarget: keyboardHandleRef,
|
|
29534
29429
|
point,
|
|
29535
29430
|
onMove: onMovePoint,
|
|
@@ -29538,7 +29433,7 @@ function useControlPoint(point, color, onMovePoint) {
|
|
|
29538
29433
|
const visiblePointRef = React.useRef(null);
|
|
29539
29434
|
const {
|
|
29540
29435
|
dragging
|
|
29541
|
-
} =
|
|
29436
|
+
} = useDraggable({
|
|
29542
29437
|
gestureTarget: visiblePointRef,
|
|
29543
29438
|
point,
|
|
29544
29439
|
onMove: onMovePoint,
|
|
@@ -29592,7 +29487,7 @@ const Line$1 = props => {
|
|
|
29592
29487
|
const line = React.useRef(null);
|
|
29593
29488
|
const {
|
|
29594
29489
|
dragging
|
|
29595
|
-
} =
|
|
29490
|
+
} = useDraggable({
|
|
29596
29491
|
gestureTarget: line,
|
|
29597
29492
|
point: start,
|
|
29598
29493
|
onMove: newPoint => {
|
|
@@ -29940,7 +29835,7 @@ const StyledMovablePoint = props => {
|
|
|
29940
29835
|
const snapToValue = snapTo ?? "grid";
|
|
29941
29836
|
const {
|
|
29942
29837
|
dragging
|
|
29943
|
-
} =
|
|
29838
|
+
} = useDraggable({
|
|
29944
29839
|
gestureTarget: elementRef,
|
|
29945
29840
|
point,
|
|
29946
29841
|
onMove,
|
|
@@ -29982,7 +29877,7 @@ const PolygonGraph = props => {
|
|
|
29982
29877
|
const snapToValue = snapTo ?? "grid";
|
|
29983
29878
|
const {
|
|
29984
29879
|
dragging
|
|
29985
|
-
} =
|
|
29880
|
+
} = useDraggable({
|
|
29986
29881
|
gestureTarget: ref,
|
|
29987
29882
|
point: dragReferencePoint,
|
|
29988
29883
|
onMove: newPoint => {
|
|
@@ -30157,7 +30052,7 @@ function MovableCircle(props) {
|
|
|
30157
30052
|
const draggableRef = React.useRef(null);
|
|
30158
30053
|
const {
|
|
30159
30054
|
dragging
|
|
30160
|
-
} =
|
|
30055
|
+
} = useDraggable({
|
|
30161
30056
|
gestureTarget: draggableRef,
|
|
30162
30057
|
point: center,
|
|
30163
30058
|
onMove,
|
|
@@ -30288,10 +30183,24 @@ function SinusoidGraph(props) {
|
|
|
30288
30183
|
coords
|
|
30289
30184
|
} = graphState;
|
|
30290
30185
|
|
|
30291
|
-
//
|
|
30186
|
+
// The coefficients are used to calculate the sinusoid equation, plot the graph, and to indicate
|
|
30187
|
+
// to content creators the currently selected "correct answer" in the Content Editor.
|
|
30188
|
+
// While we should technically never have invalid coordinates, we want to ensure that
|
|
30189
|
+
// we have a fallback so that the graph can still be plotted without crashing.
|
|
30190
|
+
const coeffRef = React__namespace.useRef({
|
|
30191
|
+
amplitude: 1,
|
|
30192
|
+
angularFrequency: 1,
|
|
30193
|
+
phase: 1,
|
|
30194
|
+
verticalOffset: 0
|
|
30195
|
+
});
|
|
30292
30196
|
const coeffs = getSinusoidCoefficients(coords);
|
|
30197
|
+
|
|
30198
|
+
// If the coefficients are valid, update the reference
|
|
30199
|
+
if (coeffs !== undefined) {
|
|
30200
|
+
coeffRef.current = coeffs;
|
|
30201
|
+
}
|
|
30293
30202
|
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(mafs.Plot.OfX, {
|
|
30294
|
-
y: x => computeSine(x,
|
|
30203
|
+
y: x => computeSine(x, coeffRef.current),
|
|
30295
30204
|
color: wonderBlocksTokens.color.blue
|
|
30296
30205
|
}), coords.map((coord, i) => /*#__PURE__*/React__namespace.createElement(StyledMovablePoint, {
|
|
30297
30206
|
key: "point-" + i,
|
|
@@ -30318,6 +30227,11 @@ const getSinusoidCoefficients = coords => {
|
|
|
30318
30227
|
const p1 = coords[0];
|
|
30319
30228
|
const p2 = coords[1];
|
|
30320
30229
|
|
|
30230
|
+
// If the x-coordinates are the same, we are unable to calculate the coefficients
|
|
30231
|
+
if (p2[0] === p1[0]) {
|
|
30232
|
+
return;
|
|
30233
|
+
}
|
|
30234
|
+
|
|
30321
30235
|
// Resulting coefficients are canonical for this sine curve
|
|
30322
30236
|
const amplitude = p2[1] - p1[1];
|
|
30323
30237
|
const angularFrequency = Math.PI / (2 * (p2[0] - p1[0]));
|
|
@@ -31609,6 +31523,8 @@ function getCircleCoords(graph) {
|
|
|
31609
31523
|
|
|
31610
31524
|
function interactiveGraphReducer(state, action) {
|
|
31611
31525
|
switch (action.type) {
|
|
31526
|
+
case REINITIALIZE:
|
|
31527
|
+
return initializeGraphState(action.params);
|
|
31612
31528
|
case MOVE_CONTROL_POINT:
|
|
31613
31529
|
return doMoveControlPoint(state, action);
|
|
31614
31530
|
case MOVE_LINE:
|
|
@@ -31809,11 +31725,14 @@ function doMovePoint(state, action) {
|
|
|
31809
31725
|
}
|
|
31810
31726
|
case "sinusoid":
|
|
31811
31727
|
{
|
|
31812
|
-
// First, we need to
|
|
31813
|
-
// If they are, we don't want to move the point
|
|
31728
|
+
// First, we need to make sure to bound the new coordinates to the graph range
|
|
31814
31729
|
const destination = action.destination;
|
|
31730
|
+
const boundDestination = boundAndSnapToGrid(destination, state);
|
|
31731
|
+
|
|
31732
|
+
// Then, we need to verify that the new coordinates are not on the same
|
|
31733
|
+
// vertical line. If they are, then we don't want to move the point
|
|
31815
31734
|
const newCoords = [...state.coords];
|
|
31816
|
-
newCoords[action.index] =
|
|
31735
|
+
newCoords[action.index] = boundDestination;
|
|
31817
31736
|
if (newCoords[0][0] === newCoords[1][0]) {
|
|
31818
31737
|
return state;
|
|
31819
31738
|
}
|
|
@@ -31823,7 +31742,7 @@ function doMovePoint(state, action) {
|
|
|
31823
31742
|
coords: setAtIndex({
|
|
31824
31743
|
array: state.coords,
|
|
31825
31744
|
index: action.index,
|
|
31826
|
-
newValue:
|
|
31745
|
+
newValue: boundDestination
|
|
31827
31746
|
})
|
|
31828
31747
|
};
|
|
31829
31748
|
}
|
|
@@ -31831,7 +31750,10 @@ function doMovePoint(state, action) {
|
|
|
31831
31750
|
{
|
|
31832
31751
|
// Set up the new coords and check if the quadratic coefficients are valid
|
|
31833
31752
|
const newCoords = [...state.coords];
|
|
31834
|
-
|
|
31753
|
+
|
|
31754
|
+
// Bind the new destination to the graph range/snapStep and then get the quadratic coefficients
|
|
31755
|
+
const boundDestination = boundAndSnapToGrid(action.destination, state);
|
|
31756
|
+
newCoords[action.index] = boundDestination;
|
|
31835
31757
|
const QuadraticCoefficients = getQuadraticCoefficients(newCoords);
|
|
31836
31758
|
|
|
31837
31759
|
// If the new destination results in an invalid quadratic equation, we don't want to move the point
|
|
@@ -31844,7 +31766,7 @@ function doMovePoint(state, action) {
|
|
|
31844
31766
|
coords: setAtIndex({
|
|
31845
31767
|
array: state.coords,
|
|
31846
31768
|
index: action.index,
|
|
31847
|
-
newValue:
|
|
31769
|
+
newValue: boundDestination
|
|
31848
31770
|
})
|
|
31849
31771
|
};
|
|
31850
31772
|
}
|
|
@@ -32258,11 +32180,12 @@ function mafsStateToInteractiveGraph(state) {
|
|
|
32258
32180
|
}
|
|
32259
32181
|
const StatefulMafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref) => {
|
|
32260
32182
|
const {
|
|
32261
|
-
onChange
|
|
32183
|
+
onChange,
|
|
32184
|
+
graph
|
|
32262
32185
|
} = props;
|
|
32263
32186
|
const [state, dispatch] = React__namespace.useReducer(interactiveGraphReducer, props, initializeGraphState);
|
|
32264
32187
|
React.useImperativeHandle(ref, () => ({
|
|
32265
|
-
getUserInput: () => getGradableGraph(state,
|
|
32188
|
+
getUserInput: () => getGradableGraph(state, graph)
|
|
32266
32189
|
}));
|
|
32267
32190
|
const prevState = React.useRef(state);
|
|
32268
32191
|
React.useEffect(() => {
|
|
@@ -32285,6 +32208,18 @@ const StatefulMafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref)
|
|
|
32285
32208
|
React.useEffect(() => {
|
|
32286
32209
|
dispatch(changeRange([[xMinRange, xMaxRange], [yMinRange, yMaxRange]]));
|
|
32287
32210
|
}, [dispatch, xMinRange, xMaxRange, yMinRange, yMaxRange]);
|
|
32211
|
+
const numSegments = graph.type === "segment" ? graph.numSegments : null;
|
|
32212
|
+
const originalPropsRef = React.useRef(props);
|
|
32213
|
+
const latestPropsRef = wonderBlocksCore.useLatestRef(props);
|
|
32214
|
+
React.useEffect(() => {
|
|
32215
|
+
// This conditional prevents the state from being "reinitialized" right
|
|
32216
|
+
// after the first render. This is an optimization, but also prevents
|
|
32217
|
+
// a bug where the graph would be marked "incorrect" during grading
|
|
32218
|
+
// even if the user never interacted with it.
|
|
32219
|
+
if (latestPropsRef.current !== originalPropsRef.current) {
|
|
32220
|
+
dispatch(reinitialize(latestPropsRef.current));
|
|
32221
|
+
}
|
|
32222
|
+
}, [graph.type, numSegments, latestPropsRef]);
|
|
32288
32223
|
return /*#__PURE__*/React__namespace.createElement(MafsGraph, _extends({}, props, {
|
|
32289
32224
|
state: state,
|
|
32290
32225
|
dispatch: dispatch
|
|
@@ -33647,6 +33582,12 @@ class InteractiveGraph extends React__namespace.Component {
|
|
|
33647
33582
|
return InteractiveGraph.validate(this.getUserInput?.(), rubric, this);
|
|
33648
33583
|
}
|
|
33649
33584
|
render() {
|
|
33585
|
+
if (this.props.graph.type === "polygon" && this.props.graph.numSides === "unlimited") {
|
|
33586
|
+
return /*#__PURE__*/React__namespace.createElement(LegacyInteractiveGraph, _extends({
|
|
33587
|
+
ref: this.legacyGraphRef
|
|
33588
|
+
}, this.props));
|
|
33589
|
+
}
|
|
33590
|
+
|
|
33650
33591
|
// Mafs shim
|
|
33651
33592
|
if (this.props.apiOptions?.flags?.["mafs"]?.[this.props.graph.type]) {
|
|
33652
33593
|
const box = getInteractiveBoxFromSizeClass(this.props.containerSizeClass);
|
|
@@ -44446,7 +44387,7 @@ const init = function (options) {
|
|
|
44446
44387
|
|
|
44447
44388
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
44448
44389
|
const libName = "@khanacademy/perseus";
|
|
44449
|
-
const libVersion = "23.
|
|
44390
|
+
const libVersion = "23.6.0";
|
|
44450
44391
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
44451
44392
|
|
|
44452
44393
|
const apiVersion = {
|
|
@@ -47546,8 +47487,8 @@ exports.itemDataVersion = itemDataVersion;
|
|
|
47546
47487
|
exports.itemToTree = itemToTree;
|
|
47547
47488
|
exports.itemVersion = ItemVersion;
|
|
47548
47489
|
exports.libVersion = libVersion;
|
|
47549
|
-
exports.lockedEllipseFillStyles = lockedEllipseFillStyles;
|
|
47550
47490
|
exports.lockedFigureColors = lockedFigureColors;
|
|
47491
|
+
exports.lockedFigureFillStyles = lockedFigureFillStyles;
|
|
47551
47492
|
exports.mediaQueries = mediaQueries;
|
|
47552
47493
|
exports.parsePerseusItem = parsePerseusItem;
|
|
47553
47494
|
exports.plotterPlotTypes = plotterPlotTypes;
|