@khanacademy/perseus 20.0.2 → 20.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/index.js CHANGED
@@ -23,16 +23,18 @@ import { entries, UnreachableCaseError, keys } from '@khanacademy/wonder-stuff-c
23
23
  import { CircularSpinner } from '@khanacademy/wonder-blocks-progress-spinner';
24
24
  import SimpleMarkdown from '@khanacademy/simple-markdown';
25
25
  import { pureMarkdownRules } from '@khanacademy/pure-markdown';
26
- import { TextField } from '@khanacademy/wonder-blocks-form';
26
+ import { TextField, Checkbox } from '@khanacademy/wonder-blocks-form';
27
27
  import Button from '@khanacademy/wonder-blocks-button';
28
28
  import { Strut } from '@khanacademy/wonder-blocks-layout';
29
29
  import Banner from '@khanacademy/wonder-blocks-banner';
30
30
  import { OptionItem, SingleSelect, MultiSelect } from '@khanacademy/wonder-blocks-dropdown';
31
31
  import debounce$2 from 'lodash.debounce';
32
- import { vec, Line as Line$3, MovablePoint as MovablePoint$5, Coordinates, Mafs } from 'mafs';
32
+ import { Point as Point$2, useMovable, useTransformContext, vec, Coordinates, Mafs } from 'mafs';
33
+ import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
34
+ import questionIcon from '@phosphor-icons/core/regular/question.svg';
35
+ import { LabelSmall, LabelMedium } from '@khanacademy/wonder-blocks-typography';
33
36
  import createReactClass from 'create-react-class';
34
37
  import Switch from '@khanacademy/wonder-blocks-switch';
35
- import { LabelMedium } from '@khanacademy/wonder-blocks-typography';
36
38
  import Pill from '@khanacademy/wonder-blocks-pill';
37
39
  import { Popper } from 'react-popper';
38
40
  import Link from '@khanacademy/wonder-blocks-link';
@@ -42,12 +44,14 @@ function _extends() {
42
44
  _extends = Object.assign ? Object.assign.bind() : function (target) {
43
45
  for (var i = 1; i < arguments.length; i++) {
44
46
  var source = arguments[i];
47
+
45
48
  for (var key in source) {
46
49
  if (Object.prototype.hasOwnProperty.call(source, key)) {
47
50
  target[key] = source[key];
48
51
  }
49
52
  }
50
53
  }
54
+
51
55
  return target;
52
56
  };
53
57
  return _extends.apply(this, arguments);
@@ -58,11 +62,13 @@ function _objectWithoutPropertiesLoose(source, excluded) {
58
62
  var target = {};
59
63
  var sourceKeys = Object.keys(source);
60
64
  var key, i;
65
+
61
66
  for (i = 0; i < sourceKeys.length; i++) {
62
67
  key = sourceKeys[i];
63
68
  if (excluded.indexOf(key) >= 0) continue;
64
69
  target[key] = source[key];
65
70
  }
71
+
66
72
  return target;
67
73
  }
68
74
 
@@ -257,7 +263,7 @@ class MathInput extends React.Component {
257
263
  className = className + " " + this.props.className;
258
264
  }
259
265
  return /*#__PURE__*/React.createElement(View, {
260
- style: [styles$C.outerWrapper, this.state.focused && styles$C.wrapperFocused, this.props.hasError && styles$C.wrapperError]
266
+ style: [styles$D.outerWrapper, this.state.focused && styles$D.wrapperFocused, this.props.hasError && styles$D.wrapperError]
261
267
  }, /*#__PURE__*/React.createElement("div", {
262
268
  style: {
263
269
  display: "flex",
@@ -290,7 +296,7 @@ class MathInput extends React.Component {
290
296
  var _this$props$keypadBut, _this$props;
291
297
  return /*#__PURE__*/React.createElement(PopoverContentCore, {
292
298
  closeButtonVisible: true,
293
- style: styles$C.popoverContent
299
+ style: styles$D.popoverContent
294
300
  }, /*#__PURE__*/React.createElement(DesktopKeypad, _extends({
295
301
  onAnalyticsEvent: this.props.analytics.onAnalyticsEvent,
296
302
  extraKeys: this.props.extraKeys,
@@ -334,9 +340,9 @@ const MathInputIcon = ({
334
340
  color = Color.offBlack;
335
341
  break;
336
342
  }
337
- const dynamicClass = active || focused ? styles$C.iconActive : styles$C.iconInactive;
343
+ const dynamicClass = active || focused ? styles$D.iconActive : styles$D.iconInactive;
338
344
  return /*#__PURE__*/React.createElement(View, {
339
- style: [styles$C.iconContainer, dynamicClass]
345
+ style: [styles$D.iconContainer, dynamicClass]
340
346
  }, /*#__PURE__*/React.createElement("svg", {
341
347
  xmlns: "http://www.w3.org/2000/svg",
342
348
  width: "16",
@@ -381,7 +387,7 @@ const inputFocused = {
381
387
  borderColor: Color.blue,
382
388
  margin: -1
383
389
  };
384
- const styles$C = StyleSheet.create({
390
+ const styles$D = StyleSheet.create({
385
391
  iconContainer: {
386
392
  display: "flex",
387
393
  justifyContent: "center",
@@ -2674,11 +2680,14 @@ function combineScores(scoreA, scoreB) {
2674
2680
  }
2675
2681
  });
2676
2682
  }
2683
+ function isCorrect(score) {
2684
+ return score.type === "points" && score.earned >= score.total;
2685
+ }
2677
2686
  function keScoreFromPerseusScore(score, guess, state) {
2678
2687
  if (score.type === "points") {
2679
2688
  return {
2680
2689
  empty: false,
2681
- correct: score.earned >= score.total,
2690
+ correct: isCorrect(score),
2682
2691
  message: score.message,
2683
2692
  guess: guess,
2684
2693
  state: state
@@ -4235,6 +4244,7 @@ function _classPrivateFieldBase(receiver, privateKey) {
4235
4244
  if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
4236
4245
  throw new TypeError("attempted to use private field on non-instance");
4237
4246
  }
4247
+
4238
4248
  return receiver;
4239
4249
  }
4240
4250
 
@@ -14974,7 +14984,7 @@ const DEFAULT_STATE$1 = {
14974
14984
  // TODO(benchristel): this is a memory leak. We add items to
14975
14985
  // tooltipResetFunctions, but never remove them.
14976
14986
  const tooltipResetFunctions = [];
14977
- class MovablePoint$4 {
14987
+ class MovablePoint$5 {
14978
14988
  constructor(graphie, movable, options) {
14979
14989
  this.graphie = void 0;
14980
14990
  this.movable = void 0;
@@ -15491,15 +15501,15 @@ class MovablePoint$4 {
15491
15501
  this.movable.toFront();
15492
15502
  }
15493
15503
  }
15494
- MovablePoint$4.add = MovablePointOptions.add;
15495
- MovablePoint$4.modify = MovablePointOptions.modify;
15496
- MovablePoint$4.draw = MovablePointOptions.draw;
15497
- MovablePoint$4.remove = MovablePointOptions.remove;
15498
- MovablePoint$4.onMoveStart = MovablePointOptions.onMoveStart;
15499
- MovablePoint$4.constraints = MovablePointOptions.constraints;
15500
- MovablePoint$4.onMove = MovablePointOptions.onMove;
15501
- MovablePoint$4.onMoveEnd = MovablePointOptions.onMoveEnd;
15502
- MovablePoint$4.onClick = MovablePointOptions.onClick;
15504
+ MovablePoint$5.add = MovablePointOptions.add;
15505
+ MovablePoint$5.modify = MovablePointOptions.modify;
15506
+ MovablePoint$5.draw = MovablePointOptions.draw;
15507
+ MovablePoint$5.remove = MovablePointOptions.remove;
15508
+ MovablePoint$5.onMoveStart = MovablePointOptions.onMoveStart;
15509
+ MovablePoint$5.constraints = MovablePointOptions.constraints;
15510
+ MovablePoint$5.onMove = MovablePointOptions.onMove;
15511
+ MovablePoint$5.onMoveEnd = MovablePointOptions.onMoveEnd;
15512
+ MovablePoint$5.onClick = MovablePointOptions.onClick;
15503
15513
  function getKey(eventName, id) {
15504
15514
  return eventName + ":" + id;
15505
15515
  }
@@ -16093,10 +16103,10 @@ _.extend(MovablePolygon.prototype, {
16093
16103
  });
16094
16104
 
16095
16105
  const Interactive2 = {
16096
- MovablePoint: MovablePoint$4,
16106
+ MovablePoint: MovablePoint$5,
16097
16107
  addMovablePoint: function (graphie, options) {
16098
16108
  const movable = new Movable(graphie, {});
16099
- return new MovablePoint$4(graphie, movable, options);
16109
+ return new MovablePoint$5(graphie, movable, options);
16100
16110
  },
16101
16111
  MovableLine: MovableLine$3,
16102
16112
  addMovableLine: function (graphie, options) {
@@ -16137,7 +16147,7 @@ const Interactive2 = {
16137
16147
  }
16138
16148
  };
16139
16149
 
16140
- const MovablePoint$3 = GraphieClasses.createClass({
16150
+ const MovablePoint$4 = GraphieClasses.createClass({
16141
16151
  displayName: "MovablePoint",
16142
16152
  movableProps: ["children"],
16143
16153
  _getProps: function () {
@@ -16194,7 +16204,7 @@ const MovablePoint$3 = GraphieClasses.createClass({
16194
16204
  });
16195
16205
 
16196
16206
  // Include helper methods, such as MovablePoint.constrain.snap()
16197
- _.extend(MovablePoint$3, Interactive2.MovablePoint);
16207
+ _.extend(MovablePoint$4, Interactive2.MovablePoint);
16198
16208
  const MovableLine$2 = GraphieClasses.createClass({
16199
16209
  displayName: "MovableLine",
16200
16210
  movableProps: ["children"],
@@ -16364,7 +16374,7 @@ var Movables = {
16364
16374
  Label: Label$1,
16365
16375
  Line: Line$2,
16366
16376
  MovableLine: MovableLine$2,
16367
- MovablePoint: MovablePoint$3,
16377
+ MovablePoint: MovablePoint$4,
16368
16378
  Parabola: Parabola,
16369
16379
  Path: Path,
16370
16380
  Plot: Plot$2,
@@ -17876,33 +17886,33 @@ class Lint extends React.Component {
17876
17886
  let warningText;
17877
17887
  let warningTextStyle;
17878
17888
  if (this.props.severity === Severity.Error) {
17879
- severityStyle = styles$B.indicatorError;
17889
+ severityStyle = styles$C.indicatorError;
17880
17890
  warningText = "Error";
17881
- warningTextStyle = styles$B.publishBlockingError;
17891
+ warningTextStyle = styles$C.publishBlockingError;
17882
17892
  } else if (this.props.severity === Severity.Warning) {
17883
- severityStyle = styles$B.indicatorWarning;
17893
+ severityStyle = styles$C.indicatorWarning;
17884
17894
  warningText = "Warning";
17885
- warningTextStyle = styles$B.warning;
17895
+ warningTextStyle = styles$C.warning;
17886
17896
  } else {
17887
- severityStyle = styles$B.indicatorGuideline;
17897
+ severityStyle = styles$C.indicatorGuideline;
17888
17898
  warningText = "Recommendation";
17889
- warningTextStyle = styles$B.warning;
17899
+ warningTextStyle = styles$C.warning;
17890
17900
  }
17891
17901
  return /*#__PURE__*/React.createElement("a", {
17892
17902
  href: `https://khanacademy.org/r/linter-rules#${this.props.ruleName}`,
17893
17903
  target: "lint-help-window",
17894
17904
  className: css(style)
17895
17905
  }, /*#__PURE__*/React.createElement("span", {
17896
- className: css(styles$B.indicator, severityStyle)
17906
+ className: css(styles$C.indicator, severityStyle)
17897
17907
  }, this.props.severity === 1 && /*#__PURE__*/React.createElement(InlineIcon, exclamationIcon)), /*#__PURE__*/React.createElement("div", {
17898
- className: css(styles$B.tooltip, tooltipAbove && styles$B.tooltipAbove)
17908
+ className: css(styles$C.tooltip, tooltipAbove && styles$C.tooltipAbove)
17899
17909
  }, this.props.message.split("\n\n").map((m, i) => /*#__PURE__*/React.createElement("p", {
17900
17910
  key: i,
17901
- className: css(styles$B.tooltipParagraph)
17911
+ className: css(styles$C.tooltipParagraph)
17902
17912
  }, /*#__PURE__*/React.createElement("span", {
17903
17913
  className: css(warningTextStyle)
17904
17914
  }, warningText, ":", " "), m)), /*#__PURE__*/React.createElement("div", {
17905
- className: css(styles$B.tail, tooltipAbove && styles$B.tailAbove)
17915
+ className: css(styles$C.tail, tooltipAbove && styles$C.tailAbove)
17906
17916
  })));
17907
17917
  };
17908
17918
  }
@@ -17940,20 +17950,20 @@ class Lint extends React.Component {
17940
17950
  }
17941
17951
  if (blockHighlight) {
17942
17952
  return /*#__PURE__*/React.createElement("span", {
17943
- className: css(styles$B.lintContainer, styles$B.lintContainerBlock)
17944
- }, this.renderLink(styles$B.radioWidgetHoverTarget), /*#__PURE__*/React.createElement("span", null, children));
17953
+ className: css(styles$C.lintContainer, styles$C.lintContainerBlock)
17954
+ }, this.renderLink(styles$C.radioWidgetHoverTarget), /*#__PURE__*/React.createElement("span", null, children));
17945
17955
  }
17946
17956
  if (inline) {
17947
17957
  return /*#__PURE__*/React.createElement("span", {
17948
- className: css(styles$B.lintContainer)
17949
- }, this.renderLink(styles$B.inlineHoverTarget), /*#__PURE__*/React.createElement("span", null, children));
17958
+ className: css(styles$C.lintContainer)
17959
+ }, this.renderLink(styles$C.inlineHoverTarget), /*#__PURE__*/React.createElement("span", null, children));
17950
17960
  }
17951
17961
  return /*#__PURE__*/React.createElement("div", {
17952
- className: css(styles$B.lintContainer)
17953
- }, this.renderLink(styles$B.hoverTarget), /*#__PURE__*/React.createElement("div", null, children));
17962
+ className: css(styles$C.lintContainer)
17963
+ }, this.renderLink(styles$C.hoverTarget), /*#__PURE__*/React.createElement("div", null, children));
17954
17964
  }
17955
17965
  }
17956
- const styles$B = StyleSheet.create({
17966
+ const styles$C = StyleSheet.create({
17957
17967
  // This is the class of the outermost element.
17958
17968
  // We use relative positioning so that the lint indicator can be
17959
17969
  // positioned absolutely relative to the position of the linty container.
@@ -19878,7 +19888,7 @@ class Renderer extends React.Component {
19878
19888
  paddingLeft: margin,
19879
19889
  paddingRight: margin
19880
19890
  };
19881
- const mobileInnerStyle = _extends({}, innerStyle, styles$A.mobileZoomableParentFix);
19891
+ const mobileInnerStyle = _extends({}, innerStyle, styles$B.mobileZoomableParentFix);
19882
19892
  return /*#__PURE__*/React.createElement("div", {
19883
19893
  key: state.key,
19884
19894
  className: "perseus-block-math",
@@ -19999,7 +20009,7 @@ class Renderer extends React.Component {
19999
20009
  paddingLeft: 0,
20000
20010
  paddingRight: 0
20001
20011
  };
20002
- const mobileInnerStyle = _extends({}, innerStyle, styles$A.mobileZoomableParentFix);
20012
+ const mobileInnerStyle = _extends({}, innerStyle, styles$B.mobileZoomableParentFix);
20003
20013
  const wrappedOutput = /*#__PURE__*/React.createElement("div", {
20004
20014
  style: _extends({}, mobileInnerStyle, {
20005
20015
  overflowX: "auto"
@@ -20646,7 +20656,7 @@ Renderer.defaultProps = {
20646
20656
  onSerializedStateUpdated: () => {},
20647
20657
  linterContext: PerseusLinter.linterContextDefault
20648
20658
  };
20649
- const styles$A = {
20659
+ const styles$B = {
20650
20660
  mobileZoomableParentFix: {
20651
20661
  // NOTE(abdul): There is an issue where transform animations will
20652
20662
  // cause the Zoomable component to disappear when running on the
@@ -21654,10 +21664,10 @@ class InputNumber extends React.Component {
21654
21664
  // Note: This is _very_ similar to what `numeric-input.jsx` does. If
21655
21665
  // you modify this, double-check if you also need to modify that
21656
21666
  // component.
21657
- const inputStyles = [styles$z.default, this.props.size === "small" ? styles$z.small : null, this.props.rightAlign ? styles$z.rightAlign : styles$z.leftAlign];
21667
+ const inputStyles = [styles$A.default, this.props.size === "small" ? styles$A.small : null, this.props.rightAlign ? styles$A.rightAlign : styles$A.leftAlign];
21658
21668
  // Unanswered
21659
21669
  if (rubric && !this.props.currentValue) {
21660
- inputStyles.push(styles$z.answerStateUnanswered);
21670
+ inputStyles.push(styles$A.answerStateUnanswered);
21661
21671
  }
21662
21672
  return /*#__PURE__*/React.createElement(InputWithExamples
21663
21673
  // eslint-disable-next-line react/no-string-refs
@@ -21742,7 +21752,7 @@ InputNumber.defaultProps = {
21742
21752
  apiOptions: ApiOptions.defaults,
21743
21753
  linterContext: linterContextDefault
21744
21754
  };
21745
- const styles$z = StyleSheet.create({
21755
+ const styles$A = StyleSheet.create({
21746
21756
  default: {
21747
21757
  width: 80,
21748
21758
  height: "auto"
@@ -22734,7 +22744,7 @@ const FocusRing = function FocusRing(props) {
22734
22744
  };
22735
22745
  return /*#__PURE__*/React.createElement("span", {
22736
22746
  "data-test-id": "focus-ring",
22737
- className: css(styles$y.ring),
22747
+ className: css(styles$z.ring),
22738
22748
  style: style
22739
22749
  }, children);
22740
22750
  };
@@ -22743,7 +22753,7 @@ FocusRing.defaultProps = {
22743
22753
  color: kaGreen$1,
22744
22754
  multipleSelect: false
22745
22755
  };
22746
- const styles$y = StyleSheet.create({
22756
+ const styles$z = StyleSheet.create({
22747
22757
  ring: {
22748
22758
  margin: "auto",
22749
22759
  display: "inline-block",
@@ -22780,7 +22790,7 @@ function getChoiceLetter(pos) {
22780
22790
  }
22781
22791
 
22782
22792
  const CHOICE_ICON_SIZE = 24;
22783
- const styles$x = StyleSheet.create({
22793
+ const styles$y = StyleSheet.create({
22784
22794
  iconWrapper: {
22785
22795
  display: "inline-block",
22786
22796
  position: "relative"
@@ -22803,7 +22813,7 @@ const CrossOutLine = function CrossOutLine(props) {
22803
22813
  width: CROSS_OUT_LINE_SIZE,
22804
22814
  height: CROSS_OUT_LINE_SIZE,
22805
22815
  viewBox: `0 0 ${CROSS_OUT_LINE_SIZE} ${CROSS_OUT_LINE_SIZE}`,
22806
- className: css(styles$w.crossOutLine),
22816
+ className: css(styles$x.crossOutLine),
22807
22817
  "data-test-id": "choice-icon__cross-out-line"
22808
22818
  }, /*#__PURE__*/React.createElement("line", {
22809
22819
  // The line stretches from the bottom-left to top-right.
@@ -22818,7 +22828,7 @@ const CrossOutLine = function CrossOutLine(props) {
22818
22828
  strokeLinecap: "round"
22819
22829
  }));
22820
22830
  };
22821
- const styles$w = StyleSheet.create({
22831
+ const styles$x = StyleSheet.create({
22822
22832
  crossOutLine: {
22823
22833
  // Center the icon within the container.
22824
22834
  position: "absolute",
@@ -22899,7 +22909,7 @@ const ChoiceIcon = function ChoiceIcon(props) {
22899
22909
  } = props;
22900
22910
  const dynamicStyles = getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, correct);
22901
22911
  return /*#__PURE__*/React.createElement("div", {
22902
- className: css(styles$x.iconWrapper)
22912
+ className: css(styles$y.iconWrapper)
22903
22913
  }, /*#__PURE__*/React.createElement(FocusRing, {
22904
22914
  color: Color.blue,
22905
22915
  visible: focused || hovered,
@@ -22908,13 +22918,13 @@ const ChoiceIcon = function ChoiceIcon(props) {
22908
22918
  // @ts-expect-error - TS2322 - Type '{ backgroundColor: string | null | undefined; borderColor: string; color: string; borderRadius: number; }' is not assignable to type 'Properties<string | number, string & {}>'.
22909
22919
  style: dynamicStyles,
22910
22920
  "data-test-id": "choice-icon__library-choice-icon",
22911
- className: css(styles$v.circle, showCorrectness && correct && styles$v.circleCorrect, showCorrectness && !correct && styles$v.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$v.circleIncorrectAnswered)
22921
+ className: css(styles$w.circle, showCorrectness && correct && styles$w.circleCorrect, showCorrectness && !correct && styles$w.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$w.circleIncorrectAnswered)
22912
22922
  // used in BaseRadio editMode to check
22913
22923
  // if we actually clicked on the radio icon
22914
22924
  ,
22915
22925
  "data-is-radio-icon": true
22916
22926
  }, /*#__PURE__*/React.createElement("div", {
22917
- className: css(styles$v.innerWrapper)
22927
+ className: css(styles$w.innerWrapper)
22918
22928
  }, /*#__PURE__*/React.createElement(ChoiceInner, {
22919
22929
  pos: pos,
22920
22930
  showCorrectness: showCorrectness,
@@ -22923,7 +22933,7 @@ const ChoiceIcon = function ChoiceIcon(props) {
22923
22933
  color: dynamicStyles.borderColor
22924
22934
  }));
22925
22935
  };
22926
- const styles$v = StyleSheet.create({
22936
+ const styles$w = StyleSheet.create({
22927
22937
  innerWrapper: {
22928
22938
  width: CHOICE_ICON_SIZE,
22929
22939
  height: CHOICE_ICON_SIZE,
@@ -23015,19 +23025,19 @@ const OptionStatus = function OptionStatus(props) {
23015
23025
  }
23016
23026
  let textStyle;
23017
23027
  if (correct) {
23018
- textStyle = styles$u.correct;
23028
+ textStyle = styles$v.correct;
23019
23029
  } else {
23020
23030
  if (checked || previouslyAnswered) {
23021
- textStyle = styles$u.incorrectAnswered;
23031
+ textStyle = styles$v.incorrectAnswered;
23022
23032
  } else {
23023
- textStyle = styles$u.incorrect;
23033
+ textStyle = styles$v.incorrect;
23024
23034
  }
23025
23035
  }
23026
23036
  return /*#__PURE__*/React.createElement("div", {
23027
- className: css(styles$u.text, textStyle)
23037
+ className: css(styles$v.text, textStyle)
23028
23038
  }, renderText(checked, correct, crossedOut));
23029
23039
  };
23030
- const styles$u = StyleSheet.create({
23040
+ const styles$v = StyleSheet.create({
23031
23041
  text: {
23032
23042
  alignItems: "center",
23033
23043
  display: "flex",
@@ -23102,8 +23112,8 @@ const Choice = function Choice(props) {
23102
23112
  crossedOut: updatedCrossedOut
23103
23113
  });
23104
23114
  }
23105
- const descriptionClassName = classNames("description", css(styles$t.description));
23106
- const rationaleClassName = classNames("perseus-radio-rationale-content", css(styles$t.rationale));
23115
+ const descriptionClassName = classNames("description", css(styles$u.description));
23116
+ const rationaleClassName = classNames("perseus-radio-rationale-content", css(styles$u.rationale));
23107
23117
 
23108
23118
  // We want to show the choices as dimmed out when the choices are disabled.
23109
23119
  // However, we don't want to do this when we're in review mode in the
@@ -23267,7 +23277,7 @@ const Choice = function Choice(props) {
23267
23277
  "data-test-id": `perseus-radio-rationale-content-${pos}`
23268
23278
  }, rationale));
23269
23279
  };
23270
- const styles$t = StyleSheet.create({
23280
+ const styles$u = StyleSheet.create({
23271
23281
  description: {
23272
23282
  display: "inline-block",
23273
23283
  width: "100%"
@@ -23459,10 +23469,10 @@ const BaseRadio = function BaseRadio(props) {
23459
23469
  const isMobile = apiOptions.isMobile;
23460
23470
  const firstChoiceHighlighted = choices[0].highlighted;
23461
23471
  const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
23462
- const className = classNames("perseus-widget-radio", !editMode && "perseus-rendered-radio", css(styles$s.radio, styles$s.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$s.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$s.radioContainerLastHighlighted));
23463
- const instructionsClassName = classNames("instructions", css(styles$s.instructions, isMobile && styles$s.instructionsMobile));
23472
+ const className = classNames("perseus-widget-radio", !editMode && "perseus-rendered-radio", css(styles$t.radio, styles$t.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$t.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$t.radioContainerLastHighlighted));
23473
+ const instructionsClassName = classNames("instructions", css(styles$t.instructions, isMobile && styles$t.instructionsMobile));
23464
23474
  const instructions = getInstructionsText(multipleSelect, countChoices, numCorrect);
23465
- const responsiveClassName = css(styles$s.responsiveFieldset);
23475
+ const responsiveClassName = css(styles$t.responsiveFieldset);
23466
23476
  const fieldset = /*#__PURE__*/React.createElement("fieldset", {
23467
23477
  className: `perseus-widget-radio-fieldset ${responsiveClassName}`
23468
23478
  }, /*#__PURE__*/React.createElement("legend", {
@@ -23513,7 +23523,7 @@ const BaseRadio = function BaseRadio(props) {
23513
23523
  const aphroditeClassName = checked => {
23514
23524
  // Whether or not to show correctness borders
23515
23525
  // for this choice and the next choice.
23516
- return css(sharedStyles.aboveScratchpad, styles$s.item, styles$s.responsiveItem, checked && styles$s.selectedItem, checked && choice.highlighted && styles$s.aboveBackdrop, checked && choice.highlighted && apiOptions.isMobile && styles$s.aboveBackdropMobile, nextChoiceHighlighted && apiOptions.isMobile && styles$s.nextHighlighted);
23526
+ return css(sharedStyles.aboveScratchpad, styles$t.item, styles$t.responsiveItem, checked && styles$t.selectedItem, checked && choice.highlighted && styles$t.aboveBackdrop, checked && choice.highlighted && apiOptions.isMobile && styles$t.aboveBackdropMobile, nextChoiceHighlighted && apiOptions.isMobile && styles$t.nextHighlighted);
23517
23527
  };
23518
23528
 
23519
23529
  // HACK(abdulrahman): Preloads the selection-state
@@ -23587,14 +23597,14 @@ const BaseRadio = function BaseRadio(props) {
23587
23597
  // Allow for horizontal scrolling if content is too wide, which may be
23588
23598
  // an issue especially on phones.
23589
23599
  return /*#__PURE__*/React.createElement("div", {
23590
- className: css(styles$s.responsiveContainer)
23600
+ className: css(styles$t.responsiveContainer)
23591
23601
  }, fieldset);
23592
23602
  };
23593
23603
  BaseRadio.defaultProps = {
23594
23604
  editMode: false,
23595
23605
  multipleSelect: false
23596
23606
  };
23597
- const styles$s = StyleSheet.create({
23607
+ const styles$t = StyleSheet.create({
23598
23608
  instructions: {
23599
23609
  display: "block",
23600
23610
  color: gray17,
@@ -24235,9 +24245,9 @@ class Categorizer extends React.Component {
24235
24245
  indexedItems = Util.shuffle(indexedItems, this.props.problemNum);
24236
24246
  }
24237
24247
  const table = /*#__PURE__*/React.createElement("table", {
24238
- className: "categorizer-table " + css(styles$r.mobileTable)
24248
+ className: "categorizer-table " + css(styles$s.mobileTable)
24239
24249
  }, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
24240
- className: css(styles$r.emptyHeaderCell)
24250
+ className: css(styles$s.emptyHeaderCell)
24241
24251
  }), this.props.categories.map((category, i) => {
24242
24252
  // Array index is the correct key here, as that's
24243
24253
  // how category grading actually works -- no way
@@ -24245,7 +24255,7 @@ class Categorizer extends React.Component {
24245
24255
  // middle. (If we later add that, this should be
24246
24256
  // fixed.)
24247
24257
  return /*#__PURE__*/React.createElement("th", {
24248
- className: css(styles$r.header),
24258
+ className: css(styles$s.header),
24249
24259
  key: i
24250
24260
  }, /*#__PURE__*/React.createElement(Renderer, {
24251
24261
  content: category,
@@ -24265,7 +24275,7 @@ class Categorizer extends React.Component {
24265
24275
  })), self.props.categories.map((catName, catNum) => {
24266
24276
  const selected = self.props.values[itemNum] === catNum;
24267
24277
  return /*#__PURE__*/React.createElement("td", {
24268
- className: "category " + css(styles$r.cell),
24278
+ className: "category " + css(styles$s.cell),
24269
24279
  key: catNum
24270
24280
  }, /*#__PURE__*/React.createElement("div", {
24271
24281
  className: ClassNames.INTERACTIVE,
@@ -24280,7 +24290,7 @@ class Categorizer extends React.Component {
24280
24290
  onChange: () => this.onChange(itemNum, catNum),
24281
24291
  onClick: e => e.stopPropagation()
24282
24292
  }), !isMobile && /*#__PURE__*/React.createElement("span", {
24283
- className: css(styles$r.radioSpan, selected && styles$r.checkedRadioSpan, this.props.static && selected && styles$r.staticCheckedRadioSpan)
24293
+ className: css(styles$s.radioSpan, selected && styles$s.checkedRadioSpan, this.props.static && selected && styles$s.staticCheckedRadioSpan)
24284
24294
  }, selected ? /*#__PURE__*/React.createElement(InlineIcon, iconCircle) : /*#__PURE__*/React.createElement(InlineIcon, iconCircleThin))));
24285
24295
  }));
24286
24296
  /* eslint-enable max-len */
@@ -24292,7 +24302,7 @@ class Categorizer extends React.Component {
24292
24302
  "categorizer-container": true,
24293
24303
  "static-mode": this.props.static
24294
24304
  });
24295
- const inlineStyles = this.props.apiOptions.isMobile ? [styles$r.fullBleedContainer] : [];
24305
+ const inlineStyles = this.props.apiOptions.isMobile ? [styles$s.fullBleedContainer] : [];
24296
24306
  return /*#__PURE__*/React.createElement("div", {
24297
24307
  className: extraClassNames + " " + css(...inlineStyles)
24298
24308
  }, table);
@@ -24344,7 +24354,7 @@ const pageMargin = 16;
24344
24354
 
24345
24355
  // Stylesheets aren't directly testable
24346
24356
  /* c8 ignore next */
24347
- const styles$r = StyleSheet.create({
24357
+ const styles$s = StyleSheet.create({
24348
24358
  mobileTable: {
24349
24359
  [mediaQueries.smOrSmaller]: {
24350
24360
  minWidth: "auto"
@@ -24580,7 +24590,7 @@ class CSProgram extends React.Component {
24580
24590
  // creator "went wild".
24581
24591
  // http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
24582
24592
  return /*#__PURE__*/React.createElement("div", {
24583
- className: css(styles$q.widthOverride, styleContainer && styles$q.container)
24593
+ className: css(styles$r.widthOverride, styleContainer && styles$r.container)
24584
24594
  }, /*#__PURE__*/React.createElement("iframe", {
24585
24595
  sandbox: sandboxOptions,
24586
24596
  src: url,
@@ -24609,7 +24619,7 @@ CSProgram.defaultProps = {
24609
24619
  // optional message
24610
24620
  message: null
24611
24621
  };
24612
- const styles$q = StyleSheet.create({
24622
+ const styles$r = StyleSheet.create({
24613
24623
  // Override the inherited width from the perseus paragraph class
24614
24624
  // 820 is minimum width for 420px editor and 400px canvas
24615
24625
  widthOverride: {
@@ -24654,7 +24664,7 @@ class Definition extends React.Component {
24654
24664
  }) => /*#__PURE__*/React.createElement(Popover, {
24655
24665
  content: /*#__PURE__*/React.createElement(PopoverContentCore, {
24656
24666
  color: "white",
24657
- style: styles$p.tooltipBody,
24667
+ style: styles$q.tooltipBody,
24658
24668
  closeButtonVisible: true
24659
24669
  }, /*#__PURE__*/React.createElement(Renderer, {
24660
24670
  apiOptions: this.props.apiOptions,
@@ -24685,7 +24695,7 @@ Definition.defaultProps = {
24685
24695
  togglePrompt: "define me",
24686
24696
  definition: "definition goes here"
24687
24697
  };
24688
- const styles$p = {
24698
+ const styles$q = {
24689
24699
  tooltipBody: {
24690
24700
  color: Color.offBlack,
24691
24701
  fontSize: 20,
@@ -24888,15 +24898,15 @@ class Explanation extends React.Component {
24888
24898
  const onClick = this._onClick;
24889
24899
  if (isMobile) {
24890
24900
  promptContainer = /*#__PURE__*/React.createElement("div", {
24891
- className: css(styles$o.linkContainer)
24901
+ className: css(styles$p.linkContainer)
24892
24902
  }, /*#__PURE__*/React.createElement("a", {
24893
- className: css(styles$o.mobileExplanationLink),
24903
+ className: css(styles$p.mobileExplanationLink),
24894
24904
  href: href,
24895
24905
  onClick: onClick,
24896
24906
  role: "button",
24897
24907
  "aria-expanded": this.state.expanded
24898
24908
  }, promptText), this.state.expanded && /*#__PURE__*/React.createElement("svg", {
24899
- className: css(styles$o.disclosureArrow)
24909
+ className: css(styles$p.disclosureArrow)
24900
24910
  }, /*#__PURE__*/React.createElement("polygon", {
24901
24911
  style: {
24902
24912
  fill: backgroundColor
@@ -24904,7 +24914,7 @@ class Explanation extends React.Component {
24904
24914
  points: `0,${arrowHeight} ` + `${arrowWidth},${arrowHeight} ` + `${arrowWidth / 2},0`
24905
24915
  })));
24906
24916
  } else {
24907
- const viewStyling = isArticle ? [styles$o.explanationLink, styles$o.articleLink] : [styles$o.explanationLink, styles$o.exerciseLink];
24917
+ const viewStyling = isArticle ? [styles$p.explanationLink, styles$p.articleLink] : [styles$p.explanationLink, styles$p.exerciseLink];
24908
24918
  promptContainer = /*#__PURE__*/React.createElement(Clickable, {
24909
24919
  onClick: onClick,
24910
24920
  "aria-expanded": this.state.expanded
@@ -24912,11 +24922,11 @@ class Explanation extends React.Component {
24912
24922
  style: viewStyling
24913
24923
  }, `[${promptText}]`));
24914
24924
  }
24915
- const expandedStyle = isMobile ? styles$o.contentExpandedMobile : styles$o.contentExpanded;
24925
+ const expandedStyle = isMobile ? styles$p.contentExpandedMobile : styles$p.contentExpanded;
24916
24926
  return /*#__PURE__*/React.createElement("div", {
24917
- className: css(styles$o.container)
24927
+ className: css(styles$p.container)
24918
24928
  }, promptContainer, this.state.expanded && /*#__PURE__*/React.createElement("div", {
24919
- className: css(styles$o.content, isMobile && styles$o.contentMobile, this.state.expanded && expandedStyle)
24929
+ className: css(styles$p.content, isMobile && styles$p.contentMobile, this.state.expanded && expandedStyle)
24920
24930
  // eslint-disable-next-line react/no-string-refs
24921
24931
  ,
24922
24932
  ref: "content"
@@ -24940,7 +24950,7 @@ const verticalContentPadding = 10;
24940
24950
  const arrowWidth = 30;
24941
24951
  const arrowHeight = 14;
24942
24952
  const backgroundColor = gray95;
24943
- const styles$o = StyleSheet.create({
24953
+ const styles$p = StyleSheet.create({
24944
24954
  container: {
24945
24955
  display: "inline",
24946
24956
  position: "relative"
@@ -25045,15 +25055,15 @@ class GradedGroupAnswerBar extends React.Component {
25045
25055
  onCheckAnswer,
25046
25056
  onNextQuestion
25047
25057
  } = this.props;
25048
- const answerBarStyle = _extends({}, styles$n.answerBar, {
25058
+ const answerBarStyle = _extends({}, styles$o.answerBar, {
25049
25059
  backgroundColor: answerBarState === "CORRECT" ? Color.offWhite : "white",
25050
25060
  // Center the "Correct!" message only when there's no next question
25051
25061
  justifyContent: answerBarState === "CORRECT" && !onNextQuestion ? "center" : "space-between"
25052
25062
  });
25053
25063
  const message = answerBarState === "INCORRECT" ? /*#__PURE__*/React.createElement("span", {
25054
- style: styles$n.text
25064
+ style: styles$o.text
25055
25065
  }, /*#__PURE__*/React.createElement("span", {
25056
- style: styles$n.tryAgainIcon
25066
+ style: styles$o.tryAgainIcon
25057
25067
  }, /*#__PURE__*/React.createElement(InlineIcon, iconTryAgain)), /*#__PURE__*/React.createElement("span", {
25058
25068
  style: {
25059
25069
  marginLeft: 8
@@ -25072,7 +25082,7 @@ class GradedGroupAnswerBar extends React.Component {
25072
25082
  return /*#__PURE__*/React.createElement("div", {
25073
25083
  style: answerBarStyle
25074
25084
  }, /*#__PURE__*/React.createElement("span", {
25075
- style: styles$n.text
25085
+ style: styles$o.text
25076
25086
  }, /*#__PURE__*/React.createElement("span", {
25077
25087
  style: {
25078
25088
  fontSize: 28,
@@ -25094,7 +25104,7 @@ class GradedGroupAnswerBar extends React.Component {
25094
25104
  }
25095
25105
  }
25096
25106
  const fontSize = 17;
25097
- const styles$n = {
25107
+ const styles$o = {
25098
25108
  answerBar: {
25099
25109
  display: "flex",
25100
25110
  alignItems: "center",
@@ -25280,7 +25290,7 @@ class GradedGroup extends React.Component {
25280
25290
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
25281
25291
  gradeStatus = i18n._("Incorrect");
25282
25292
  }
25283
- const mobileClass = this.props.inGradedGroupSet ? css(styles$m.gradedGroupInSet) : css(styles$m.gradedGroup);
25293
+ const mobileClass = this.props.inGradedGroupSet ? css(styles$n.gradedGroupInSet) : css(styles$n.gradedGroup);
25284
25294
  const classes = classNames({
25285
25295
  [mobileClass]: apiOptions.isMobile,
25286
25296
  "perseus-graded-group": true,
@@ -25299,7 +25309,7 @@ class GradedGroup extends React.Component {
25299
25309
  return /*#__PURE__*/React.createElement("div", {
25300
25310
  className: classes
25301
25311
  }, !!this.props.title && /*#__PURE__*/React.createElement("div", {
25302
- className: css(styles$m.title)
25312
+ className: css(styles$n.title)
25303
25313
  }, this.props.title), /*#__PURE__*/React.createElement(Renderer, _extends({}, this.props, {
25304
25314
  // eslint-disable-next-line react/no-string-refs
25305
25315
  ref: "renderer",
@@ -25331,7 +25341,7 @@ class GradedGroup extends React.Component {
25331
25341
  }, i18n._("Next question")), this.props.hint && this.props.hint.content && (this.state.showHint ? /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("button", {
25332
25342
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
25333
25343
  tabIndex: "0",
25334
- className: css(styles$m.explanationTitle),
25344
+ className: css(styles$n.explanationTitle),
25335
25345
  onClick: () => this.setState({
25336
25346
  showHint: false
25337
25347
  }),
@@ -25363,7 +25373,7 @@ class GradedGroup extends React.Component {
25363
25373
  showHint: true
25364
25374
  });
25365
25375
  },
25366
- className: css(styles$m.showHintLink)
25376
+ className: css(styles$n.showHintLink)
25367
25377
  }, i18n._("Explain"))), apiOptions.isMobile && answerBarState !== "HIDDEN" && /*#__PURE__*/React.createElement(GradedGroupAnswerBar, {
25368
25378
  apiOptions: apiOptions,
25369
25379
  answerBarState: answerBarState,
@@ -25384,7 +25394,7 @@ GradedGroup.defaultProps = {
25384
25394
  const traverseChildWidgets$2 = function traverseChildWidgets(props, traverseRenderer) {
25385
25395
  return _.extend({}, props, traverseRenderer(props));
25386
25396
  };
25387
- const styles$m = StyleSheet.create({
25397
+ const styles$n = StyleSheet.create({
25388
25398
  gradedGroupInSet: {
25389
25399
  // Reset a few desktop-only styles that come from graded-group.less
25390
25400
  marginLeft: 0,
@@ -25457,18 +25467,18 @@ class Indicators extends React.Component {
25457
25467
  return /*#__PURE__*/React.createElement("ul", {
25458
25468
  // reduntantly add class name for use in .less files--
25459
25469
  // the styles object key gets hashed
25460
- className: classNames(css(styles$l.indicatorContainer), "indicatorContainer")
25470
+ className: classNames(css(styles$m.indicatorContainer), "indicatorContainer")
25461
25471
  }, this.props.gradedGroups.map(({
25462
25472
  title
25463
25473
  }, i) => /*#__PURE__*/React.createElement("li", {
25464
- className: css(styles$l.indicator),
25474
+ className: css(styles$m.indicator),
25465
25475
  key: title
25466
25476
  }, /*#__PURE__*/React.createElement(Clickable, {
25467
25477
  role: "button",
25468
25478
  "aria-label": i18n._("Skip to %(title)s", {
25469
25479
  title
25470
25480
  }),
25471
- style: styles$l.indicatorButton,
25481
+ style: styles$m.indicatorButton,
25472
25482
  onClick: () => this.props.onChangeCurrentGroup(i),
25473
25483
  onKeyDown: e => this.handleKeyDown(e, i)
25474
25484
  }, ({
@@ -25476,9 +25486,9 @@ class Indicators extends React.Component {
25476
25486
  focused,
25477
25487
  pressed
25478
25488
  }) => /*#__PURE__*/React.createElement(View, {
25479
- style: [styles$l.indicatorDot, (hovered || focused || pressed) && styles$l.indicatorDotFocused]
25489
+ style: [styles$m.indicatorDot, (hovered || focused || pressed) && styles$m.indicatorDotFocused]
25480
25490
  }, i === this.props.currentGroup && /*#__PURE__*/React.createElement(View, {
25481
- style: styles$l.indicatorDotActive
25491
+ style: styles$m.indicatorDotActive
25482
25492
  }, /*#__PURE__*/React.createElement("span", {
25483
25493
  className: css(a11y.srOnly)
25484
25494
  }, i18n._("Current"))))))));
@@ -25544,7 +25554,7 @@ class GradedGroupSet extends React.Component {
25544
25554
  } = getDependencies();
25545
25555
  if (JIPT.useJIPT && this.props.gradedGroups.length > 1) {
25546
25556
  return /*#__PURE__*/React.createElement("div", {
25547
- className: css(styles$l.container)
25557
+ className: css(styles$m.container)
25548
25558
  }, this.props.gradedGroups.map((gradedGroup, i) => {
25549
25559
  return (
25550
25560
  /*#__PURE__*/
@@ -25567,13 +25577,13 @@ class GradedGroupSet extends React.Component {
25567
25577
  const numGroups = this.props.gradedGroups.length;
25568
25578
  const handleNextQuestion = this.state.currentGroup < numGroups - 1 ? this.handleNextQuestion : null;
25569
25579
  return /*#__PURE__*/React.createElement("div", {
25570
- className: css(styles$l.container)
25580
+ className: css(styles$m.container)
25571
25581
  }, /*#__PURE__*/React.createElement("div", {
25572
- className: css(styles$l.top)
25582
+ className: css(styles$m.top)
25573
25583
  }, /*#__PURE__*/React.createElement("div", {
25574
- className: css(styles$l.title)
25584
+ className: css(styles$m.title)
25575
25585
  }, currentGroup.title), /*#__PURE__*/React.createElement("div", {
25576
- className: css(styles$l.spacer)
25586
+ className: css(styles$m.spacer)
25577
25587
  }), /*#__PURE__*/React.createElement(Indicators, {
25578
25588
  currentGroup: this.state.currentGroup,
25579
25589
  gradedGroups: this.props.gradedGroups,
@@ -25615,7 +25625,7 @@ var GradedGroupSet$1 = {
25615
25625
  tracking: "all",
25616
25626
  isLintable: true
25617
25627
  };
25618
- const styles$l = StyleSheet.create({
25628
+ const styles$m = StyleSheet.create({
25619
25629
  top: {
25620
25630
  display: "flex",
25621
25631
  flexDirection: "row"
@@ -25720,7 +25730,7 @@ class ButtonGroup extends React.Component {
25720
25730
  id: "" + i,
25721
25731
  ref: "button" + i,
25722
25732
  key: "" + i,
25723
- className: css(styles$k.buttonStyle, button.value === value && styles$k.selectedStyle),
25733
+ className: css(styles$l.buttonStyle, button.value === value && styles$l.selectedStyle),
25724
25734
  onClick: () => this.toggleSelect(button.value)
25725
25735
  }, button.content || "" + button.value);
25726
25736
  });
@@ -25737,7 +25747,7 @@ ButtonGroup.defaultProps = {
25737
25747
  value: null,
25738
25748
  allowEmpty: true
25739
25749
  };
25740
- const styles$k = StyleSheet.create({
25750
+ const styles$l = StyleSheet.create({
25741
25751
  buttonStyle: {
25742
25752
  backgroundColor: "white",
25743
25753
  border: "1px solid #ccc",
@@ -26341,7 +26351,7 @@ var util = /*#__PURE__*/Object.freeze({
26341
26351
  });
26342
26352
 
26343
26353
  // @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
26344
- const MovablePoint$2 = Graphie.MovablePoint;
26354
+ const MovablePoint$3 = Graphie.MovablePoint;
26345
26355
  // @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
26346
26356
  const MovableLine$1 = Graphie.MovableLine;
26347
26357
  function isFlipped(newCoord, oldCoord, line) {
@@ -26423,7 +26433,7 @@ class FunctionGrapher extends React.Component {
26423
26433
  }],
26424
26434
  normalStyle: dashed,
26425
26435
  highlightStyle: dashed
26426
- }, _.map(asymptote, (coord, i) => /*#__PURE__*/React.createElement(MovablePoint$2, {
26436
+ }, _.map(asymptote, (coord, i) => /*#__PURE__*/React.createElement(MovablePoint$3, {
26427
26437
  key: `asymptoteCoord-${i}`,
26428
26438
  coord: coord,
26429
26439
  static: true,
@@ -26438,7 +26448,7 @@ class FunctionGrapher extends React.Component {
26438
26448
  }
26439
26449
  render() {
26440
26450
  const pointForCoord = (coord, i) => {
26441
- return /*#__PURE__*/React.createElement(MovablePoint$2, {
26451
+ return /*#__PURE__*/React.createElement(MovablePoint$3, {
26442
26452
  key: i,
26443
26453
  coord: coord,
26444
26454
  static: this.props.static,
@@ -27272,7 +27282,7 @@ const Label = Graphie.Label;
27272
27282
  // @ts-expect-error - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
27273
27283
  const Line$1 = Graphie.Line;
27274
27284
  // @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
27275
- const MovablePoint$1 = Graphie.MovablePoint;
27285
+ const MovablePoint$2 = Graphie.MovablePoint;
27276
27286
  // @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
27277
27287
  const MovableLine = Graphie.MovableLine;
27278
27288
  // @ts-expect-error - TS2339 - Property 'Plot' does not exist on type 'typeof Graphie'.
@@ -27521,7 +27531,7 @@ class Interaction extends React.Component {
27521
27531
  return [coordX, coordY];
27522
27532
  }];
27523
27533
  if (element.options.constraint === "snap") {
27524
- constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
27534
+ constraints.push(MovablePoint$2.constraints.snap(element.options.snap));
27525
27535
  } else if (element.options.constraint === "x") {
27526
27536
  constraints.push(coord => {
27527
27537
  return [
@@ -27543,7 +27553,7 @@ class Interaction extends React.Component {
27543
27553
  // TODO(eater): foo_[xyz] are hacky non-props to
27544
27554
  // get the component to update when constraints
27545
27555
  // change
27546
- return /*#__PURE__*/React.createElement(MovablePoint$1, {
27556
+ return /*#__PURE__*/React.createElement(MovablePoint$2, {
27547
27557
  key: element.key,
27548
27558
  coord: [
27549
27559
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
@@ -27578,7 +27588,7 @@ class Interaction extends React.Component {
27578
27588
  return [coordX, coordY];
27579
27589
  }];
27580
27590
  if (element.options.constraint === "snap") {
27581
- constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
27591
+ constraints.push(MovablePoint$2.constraints.snap(element.options.snap));
27582
27592
  } else if (element.options.constraint === "x") {
27583
27593
  constraints.push(coord => {
27584
27594
  return [
@@ -27619,14 +27629,14 @@ class Interaction extends React.Component {
27619
27629
  foo_x: element.options.constraint,
27620
27630
  foo_y: element.options.constraintFn,
27621
27631
  foo_z: element.options.snap
27622
- }, /*#__PURE__*/React.createElement(MovablePoint$1, {
27632
+ }, /*#__PURE__*/React.createElement(MovablePoint$2, {
27623
27633
  coord: start,
27624
27634
  static: true,
27625
27635
  normalStyle: {
27626
27636
  stroke: "none",
27627
27637
  fill: "none"
27628
27638
  }
27629
- }), /*#__PURE__*/React.createElement(MovablePoint$1, {
27639
+ }), /*#__PURE__*/React.createElement(MovablePoint$2, {
27630
27640
  coord: end,
27631
27641
  static: true,
27632
27642
  normalStyle: {
@@ -28047,33 +28057,6 @@ class Graph extends React.Component {
28047
28057
  allowScratchpad: true,
28048
28058
  setDrawingAreaAvailable: this.props.setDrawingAreaAvailable
28049
28059
  });
28050
-
28051
- // Maybe move this out later
28052
- if (this.props.lockedFigures) {
28053
- for (const lockedFigure of this.props.lockedFigures) {
28054
- switch (lockedFigure.type) {
28055
- case "point":
28056
- graphie.circle(
28057
- // center
28058
- lockedFigure.coord,
28059
- // radius
28060
- 0.2,
28061
- // style
28062
- lockedFigure.style);
28063
- break;
28064
- default:
28065
- /**
28066
- * Devlopment-time future-proofing: This `never` should
28067
- * fail during type-checking if we add a new locked
28068
- * shape type and forget to handle it in any other
28069
- * switch case here.
28070
- */
28071
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
28072
- lockedFigure.type;
28073
- throw new Error(`Unknown locked shape type: ${lockedFigure.type}`);
28074
- }
28075
- }
28076
- }
28077
28060
  this._updateProtractor();
28078
28061
  this._updateRuler();
28079
28062
 
@@ -28199,6 +28182,35 @@ Graph.defaultProps = {
28199
28182
  isMobile: false
28200
28183
  };
28201
28184
 
28185
+ const GraphLockedLayer = props => {
28186
+ const {
28187
+ lockedFigures
28188
+ } = props;
28189
+ return /*#__PURE__*/React.createElement(React.Fragment, null, lockedFigures.map((figure, index) => {
28190
+ switch (figure.type) {
28191
+ case "point":
28192
+ const [x, y] = figure.coord;
28193
+ return /*#__PURE__*/React.createElement(Point$2, {
28194
+ key: `${figure.type}-${index}`,
28195
+ x: x,
28196
+ y: y,
28197
+ svgCircleProps: {
28198
+ style: figure.style
28199
+ }
28200
+ });
28201
+ }
28202
+
28203
+ /**
28204
+ * Devlopment-time future-proofing: This `never` should
28205
+ * fail during type-checking if we add a new locked
28206
+ * shape type and forget to handle it in any other
28207
+ * switch case here.
28208
+ */
28209
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
28210
+ throw new UnreachableCaseError(figure.type);
28211
+ }));
28212
+ };
28213
+
28202
28214
  const MOVE_CONTROL_POINT = "move-control-point";
28203
28215
  function moveControlPoint(objectIndex, pointIndex, destination) {
28204
28216
  return {
@@ -28217,6 +28229,59 @@ function moveSegment(segmentIndex, delta) {
28217
28229
  };
28218
28230
  }
28219
28231
 
28232
+ const MovablePoint$1 = props => {
28233
+ const hitboxRef = useRef(null);
28234
+ const {
28235
+ point,
28236
+ onMove
28237
+ } = props;
28238
+ const {
28239
+ dragging
28240
+ } = useMovable({
28241
+ gestureTarget: hitboxRef,
28242
+ point,
28243
+ onMove,
28244
+ constrain: p => p
28245
+ });
28246
+ const {
28247
+ viewTransform,
28248
+ userTransform
28249
+ } = useTransformContext();
28250
+ const transformToPx = vec.matrixMult(viewTransform, userTransform);
28251
+ const [x, y] = vec.transform(point, transformToPx);
28252
+ return /*#__PURE__*/React.createElement("g", {
28253
+ ref: hitboxRef,
28254
+ className: "movable-point",
28255
+ tabIndex: 0,
28256
+ style: {
28257
+ cursor: dragging ? "grabbing" : "grab",
28258
+ touchAction: "none",
28259
+ outline: "none",
28260
+ "--movable-point-color": Color.blue
28261
+ }
28262
+ }, /*#__PURE__*/React.createElement("circle", {
28263
+ className: "movable-point-hitbox",
28264
+ r: 30,
28265
+ cx: x,
28266
+ cy: y
28267
+ }), /*#__PURE__*/React.createElement("circle", {
28268
+ className: "movable-point-halo",
28269
+ cx: x,
28270
+ cy: y
28271
+ }), /*#__PURE__*/React.createElement("circle", {
28272
+ className: "movable-point-ring",
28273
+ cx: x,
28274
+ cy: y
28275
+ }), /*#__PURE__*/React.createElement("circle", {
28276
+ className: "movable-point-center",
28277
+ cx: x,
28278
+ cy: y,
28279
+ style: {
28280
+ fill: Color.blue
28281
+ }
28282
+ }));
28283
+ };
28284
+
28220
28285
  const SegmentGraph = props => {
28221
28286
  const {
28222
28287
  dispatch
@@ -28239,31 +28304,76 @@ const SegmentGraph = props => {
28239
28304
  })));
28240
28305
  };
28241
28306
  const SegmentView = props => {
28242
- const [pt1, pt2] = props.segment;
28307
+ const {
28308
+ onMoveSegment,
28309
+ segment: [pt1, pt2]
28310
+ } = props;
28243
28311
  const midpoint = vec.midpoint(pt1, pt2);
28244
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Line$3.Segment, {
28245
- point1: pt1,
28246
- point2: pt2
28247
- }), /*#__PURE__*/React.createElement(MovablePoint$5, {
28312
+ const segment = useRef(null);
28313
+ const {
28314
+ dragging: isDraggingSegment
28315
+ } = useMovable({
28316
+ gestureTarget: segment,
28248
28317
  point: midpoint,
28249
- color: Color.blue,
28250
28318
  onMove: newPoint => {
28251
- props.onMoveSegment(vec.sub(newPoint, midpoint));
28319
+ onMoveSegment(vec.sub(newPoint, midpoint));
28320
+ },
28321
+ constrain: p => p
28322
+ });
28323
+ const {
28324
+ viewTransform,
28325
+ userTransform
28326
+ } = useTransformContext();
28327
+ const transformToPx = vec.matrixMult(viewTransform, userTransform);
28328
+ const pt1Px = vec.transform(pt1, transformToPx);
28329
+ const pt2Px = vec.transform(pt2, transformToPx);
28330
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("g", {
28331
+ ref: segment,
28332
+ tabIndex: 0,
28333
+ className: "movable-segment",
28334
+ style: {
28335
+ cursor: isDraggingSegment ? "grabbing" : "grab"
28252
28336
  }
28253
- }), /*#__PURE__*/React.createElement(MovablePoint$5, {
28337
+ }, /*#__PURE__*/React.createElement(SVGLine, {
28338
+ start: pt1Px,
28339
+ end: pt2Px,
28340
+ style: {
28341
+ stroke: "transparent",
28342
+ strokeWidth: 30
28343
+ }
28344
+ }), /*#__PURE__*/React.createElement(SVGLine, {
28345
+ start: pt1Px,
28346
+ end: pt2Px,
28347
+ style: {
28348
+ stroke: "var(--mafs-segment-stroke-color)",
28349
+ strokeWidth: "var(--mafs-segment-stroke-weight)"
28350
+ }
28351
+ })), /*#__PURE__*/React.createElement(MovablePoint$1, {
28254
28352
  point: pt1,
28255
- color: Color.blue,
28256
28353
  onMove: newPoint => {
28257
28354
  props.onMovePoint(0, newPoint);
28258
28355
  }
28259
- }), /*#__PURE__*/React.createElement(MovablePoint$5, {
28356
+ }), /*#__PURE__*/React.createElement(MovablePoint$1, {
28260
28357
  point: pt2,
28261
- color: Color.blue,
28262
28358
  onMove: newPoint => {
28263
28359
  props.onMovePoint(1, newPoint);
28264
28360
  }
28265
28361
  }));
28266
28362
  };
28363
+ function SVGLine(props) {
28364
+ const {
28365
+ start,
28366
+ end,
28367
+ style
28368
+ } = props;
28369
+ return /*#__PURE__*/React.createElement("line", {
28370
+ x1: start[0],
28371
+ y1: start[1],
28372
+ x2: end[0],
28373
+ y2: end[1],
28374
+ style: style
28375
+ });
28376
+ }
28267
28377
 
28268
28378
  const renderLineLabel = (n, [min, max]) => n !== -1 && n !== min && n !== max;
28269
28379
  const axisOptions = (props, index) => ({
@@ -28433,7 +28543,7 @@ const VisibleIcon = () => /*#__PURE__*/React.createElement("svg", {
28433
28543
  width: "24",
28434
28544
  height: "24",
28435
28545
  viewBox: "0 0 24 24",
28436
- className: css(styles$j.icon)
28546
+ className: css(styles$k.icon)
28437
28547
  }, /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("path", {
28438
28548
  id: "a",
28439
28549
  d: "M7.401 10.035c-1.424.748-2.599 1.905-3.544 " + "3.48a1 1 0 0 1-1.714-1.03C4.325 8.849 7.652 7 " + "12 7c4.348 0 7.675 1.848 9.857 5.486a1 1 0 0 " + "1-1.714 1.028c-.945-1.574-2.12-2.73-3.544-" + "3.48a5 5 0 1 1-9.198 0zM12 15a3 3 0 1 0 0-6 3 3 " + "0 0 0 0 6z"
@@ -28464,7 +28574,7 @@ const HiddenIcon = () => /*#__PURE__*/React.createElement("svg", {
28464
28574
  width: "24",
28465
28575
  height: "24",
28466
28576
  viewBox: "0 0 24 24",
28467
- className: css(styles$j.icon)
28577
+ className: css(styles$k.icon)
28468
28578
  }, /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("path", {
28469
28579
  id: "a",
28470
28580
  d: "M8.794 7.38C9.791 7.127 10.86 7 12 7c4.348 0 " + "7.675 1.848 9.857 5.486a1 1 0 0 1-1.714 " + "1.028c-.945-1.574-2.12-2.73-3.544-3.48.258." + "604.401 1.268.401 1.966 0 1.02-.305 " + "1.967-.828 2.757l2.535 2.536a1 1 0 0 " + "1-1.414 1.414l-12-12a1 1 0 0 1 " + "1.414-1.414L8.794 7.38zm5.914 5.913a3 3 0 0 " + "0-4.001-4.001l4 4.001zM6.072 8.486l2.976 " + "2.976a3 3 0 0 0 3.49 3.49l1.579 1.58A5 5 0 " + "0 1 7.4 10.035c-1.424.747-2.599 1.904-3.544 " + "3.478a1 1 0 0 1-1.714-1.028c1.049-1.75 " + "2.363-3.085 3.929-4z"
@@ -28498,20 +28608,20 @@ const HUD = ({
28498
28608
  let state;
28499
28609
  let icon;
28500
28610
  if (enabled) {
28501
- state = styles$j.enabled;
28611
+ state = styles$k.enabled;
28502
28612
  icon = /*#__PURE__*/React.createElement(VisibleIcon, null);
28503
28613
  } else {
28504
- state = styles$j.disabled;
28614
+ state = styles$k.disabled;
28505
28615
  icon = /*#__PURE__*/React.createElement(HiddenIcon, null);
28506
28616
  }
28507
28617
  return /*#__PURE__*/React.createElement("button", {
28508
- className: css(styles$j.hud, _fixedPosition && styles$j.hudFixedPosition, state),
28618
+ className: css(styles$k.hud, _fixedPosition && styles$k.hudFixedPosition, state),
28509
28619
  onClick: e => {
28510
28620
  onClick();
28511
28621
  }
28512
28622
  }, icon, message);
28513
28623
  };
28514
- const styles$j = StyleSheet.create({
28624
+ const styles$k = StyleSheet.create({
28515
28625
  hud: {
28516
28626
  boxSizing: "border-box",
28517
28627
  height: 36,
@@ -28575,7 +28685,7 @@ const triangleBeforeAfter = {
28575
28685
  top: "0",
28576
28686
  width: "0"
28577
28687
  };
28578
- const styles$i = StyleSheet.create({
28688
+ const styles$j = StyleSheet.create({
28579
28689
  infoTip: {
28580
28690
  display: "inline-block",
28581
28691
  marginLeft: "5px",
@@ -28614,7 +28724,6 @@ const styles$i = StyleSheet.create({
28614
28724
  width: "240px"
28615
28725
  }
28616
28726
  });
28617
- const questionMark = "data:image/png;base64," + "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGXRFWHRTb2Z0d2FyZQBB" + "ZG9iZSBJbWFnZVJlYWR5ccllPAAAA3NpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/" + "eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+" + "IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2Jl" + "IFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAg" + "ICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5" + "LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9" + "IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHht" + "bG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3Vy" + "Y2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHht" + "cE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo2N2M3NTAxYS04YmVlLTQ0M2Mt" + "YmRiNS04OGM2N2IxN2NhYzEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUJCRTk4" + "Qjc4NjAwMTFFMzg3QUJDNEI4Mzk2QTRGQkQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5p" + "aWQ6OUJCRTk4QjY4NjAwMTFFMzg3QUJDNEI4Mzk2QTRGQkQiIHhtcDpDcmVhdG9yVG9v" + "bD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRG" + "cm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NGE5ZDI0OTMtODk1NC00OGFkLTlh" + "MTgtZDAwM2MwYWNjNDJlIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjY3Yzc1MDFh" + "LThiZWUtNDQzYy1iZGI1LTg4YzY3YjE3Y2FjMSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4g" + "PC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pqm89uYAAADM" + "SURBVHjaXJA9DoJAEIUH1M4TUHIFsCMGen9OwCGw1YRGW2ntKel0exsojHIBC0ouQAyU" + "viFDstmXfNmZeS+zm7XSNCXRFiRgJf0bXIHixpbhGdxBBJYC1w/xaA424MhNEATkui71" + "fU9KqfEU78UbD9PdbJRlOdae55GmhIP+1NV1TcMwkOM41DSNHvRtMhTHMRVFQW3b6mOL" + "gx99kue5GRp/gIOZuZGvNpTNwjD8oliANU+qqqKu6/TQBdymN57AHjzBT+B6Jx79BRgA" + "vc49kQA4yxgAAAAASUVORK5CYII=";
28618
28727
  class InfoTip$1 extends React.Component {
28619
28728
  constructor(...args) {
28620
28729
  super(...args);
@@ -28634,23 +28743,22 @@ class InfoTip$1 extends React.Component {
28634
28743
  }
28635
28744
  render() {
28636
28745
  return /*#__PURE__*/React.createElement("div", {
28637
- className: css(styles$i.infoTip)
28638
- }, /*#__PURE__*/React.createElement("img", {
28639
- alt: "",
28640
- width: 10,
28641
- height: 10,
28642
- src: questionMark,
28746
+ className: css(styles$j.infoTip)
28747
+ }, /*#__PURE__*/React.createElement(View, {
28643
28748
  onMouseEnter: this.handleMouseEnter,
28644
28749
  onMouseLeave: this.handleMouseLeave
28645
- }), /*#__PURE__*/React.createElement("div", {
28646
- className: css(styles$i.infoTipContainer),
28750
+ }, /*#__PURE__*/React.createElement(PhosphorIcon, {
28751
+ size: "small",
28752
+ icon: questionIcon
28753
+ })), /*#__PURE__*/React.createElement("div", {
28754
+ className: css(styles$j.infoTipContainer),
28647
28755
  style: {
28648
28756
  display: this.state.hover ? "block" : "none"
28649
28757
  }
28650
28758
  }, /*#__PURE__*/React.createElement("div", {
28651
- className: css(styles$i.infoTipTriangle)
28759
+ className: css(styles$j.infoTipTriangle)
28652
28760
  }), /*#__PURE__*/React.createElement("div", {
28653
- className: css(styles$i.verticalShadow, styles$i.infoTipContentContainer)
28761
+ className: css(styles$j.verticalShadow, styles$j.infoTipContentContainer)
28654
28762
  }, this.props.children)));
28655
28763
  }
28656
28764
  }
@@ -28725,7 +28833,7 @@ class MultiButtonGroup extends React.Component {
28725
28833
  id: "" + i,
28726
28834
  key: "" + i,
28727
28835
  ref: "button" + i,
28728
- className: css(styles$h.buttonStyle, selected && styles$h.selectedStyle),
28836
+ className: css(styles$i.buttonStyle, selected && styles$i.selectedStyle),
28729
28837
  onClick: () => this.toggleSelect(button.value)
28730
28838
  }, button.content || "" + button.value);
28731
28839
  });
@@ -28741,7 +28849,7 @@ MultiButtonGroup.defaultProps = {
28741
28849
  values: [],
28742
28850
  allowEmpty: true
28743
28851
  };
28744
- const styles$h = StyleSheet.create({
28852
+ const styles$i = StyleSheet.create({
28745
28853
  buttonStyle: {
28746
28854
  backgroundColor: "white",
28747
28855
  border: "1px solid #ccc",
@@ -28999,11 +29107,12 @@ const PropCheckBox = createReactClass({
28999
29107
  },
29000
29108
  render: function () {
29001
29109
  const propName = this.propName();
29002
- return /*#__PURE__*/React.createElement("label", null, this._labelAlignLeft() && this.props.label, /*#__PURE__*/React.createElement("input", {
29003
- type: "checkbox",
29110
+ return /*#__PURE__*/React.createElement("label", {
29111
+ className: css(styles$h.labeledCheckbox)
29112
+ }, this._labelAlignLeft() && /*#__PURE__*/React.createElement(LabelSmall, null, this.props.label), /*#__PURE__*/React.createElement(Checkbox, {
29004
29113
  checked: this.props[propName],
29005
29114
  onChange: this.toggle
29006
- }), !this._labelAlignLeft() && this.props.label);
29115
+ }), !this._labelAlignLeft() && /*#__PURE__*/React.createElement(LabelSmall, null, this.props.label));
29007
29116
  },
29008
29117
  toggle: function () {
29009
29118
  const propName = this.propName();
@@ -29012,6 +29121,13 @@ const PropCheckBox = createReactClass({
29012
29121
  this.props.onChange(changes);
29013
29122
  }
29014
29123
  });
29124
+ const styles$h = StyleSheet.create({
29125
+ labeledCheckbox: {
29126
+ display: "flex",
29127
+ flexDirection: "row",
29128
+ alignItems: "center"
29129
+ }
29130
+ });
29015
29131
 
29016
29132
  const truth = () => true;
29017
29133
 
@@ -29170,7 +29286,9 @@ const MafsGraph = /*#__PURE__*/React.forwardRef((props, ref) => {
29170
29286
  zoom: false,
29171
29287
  width: width,
29172
29288
  height: height
29173
- }, !legacyGrid && /*#__PURE__*/React.createElement(Grid, props), renderGraph({
29289
+ }, !legacyGrid && /*#__PURE__*/React.createElement(Grid, props), props.lockedFigures && /*#__PURE__*/React.createElement(GraphLockedLayer, {
29290
+ lockedFigures: props.lockedFigures
29291
+ }), renderGraph({
29174
29292
  state,
29175
29293
  dispatch
29176
29294
  }))));
@@ -29309,12 +29427,13 @@ class InteractiveGraph extends React.Component {
29309
29427
  }
29310
29428
  };
29311
29429
  this.resetGraphie = () => {
29430
+ var _this$refs$graph;
29312
29431
  this.shouldResetGraphie = false;
29313
29432
  this.parabola = null;
29314
29433
  this.sinusoid = null;
29315
29434
  // eslint-disable-next-line react/no-string-refs
29316
29435
  // @ts-expect-error - TS2339 - Property 'reset' does not exist on type 'ReactInstance'.
29317
- this.refs.graph.reset();
29436
+ (_this$refs$graph = this.refs.graph) == null || _this$refs$graph.reset();
29318
29437
  };
29319
29438
  this.setupGraphie = () => {
29320
29439
  this.setTrashCanVisibility(0);
@@ -30447,8 +30566,7 @@ class InteractiveGraph extends React.Component {
30447
30566
  onMouseDown: onMouseDown,
30448
30567
  onGraphieUpdated: this.setGraphie,
30449
30568
  setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable,
30450
- isMobile: isMobile,
30451
- lockedFigures: this.props.lockedFigures
30569
+ isMobile: isMobile
30452
30570
  }));
30453
30571
  }
30454
30572
  static getQuadraticCoefficients(coords) {
@@ -41179,7 +41297,7 @@ const init = function init(options) {
41179
41297
 
41180
41298
  // This file is processed by a Rollup plugin (replace) to inject the production
41181
41299
  const libName = "@khanacademy/perseus";
41182
- const libVersion = "20.0.2";
41300
+ const libVersion = "20.2.0";
41183
41301
  addLibraryVersionToPerseusDebug(libName, libVersion);
41184
41302
 
41185
41303
  const apiVersion = {