@khanacademy/perseus 38.0.0 → 39.0.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.
Files changed (50) hide show
  1. package/dist/components/math-input.d.ts +1 -1
  2. package/dist/components/sortable.d.ts +1 -1
  3. package/dist/definition-context.d.ts +1 -1
  4. package/dist/es/index.js +48 -112
  5. package/dist/es/index.js.map +1 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.js +44 -111
  8. package/dist/index.js.map +1 -1
  9. package/dist/interactive2/movable-point.d.ts +1 -1
  10. package/dist/multi-items/prop-type-builders.d.ts +0 -6
  11. package/dist/perseus-api.d.ts +3 -1
  12. package/dist/perseus-types.d.ts +3 -42
  13. package/dist/renderer.d.ts +1 -2
  14. package/dist/server-item-renderer.d.ts +3 -2
  15. package/dist/sigfigs.d.ts +0 -16
  16. package/dist/styles/constants.d.ts +0 -18
  17. package/dist/types.d.ts +4 -6
  18. package/dist/util/math.d.ts +0 -1
  19. package/dist/util.d.ts +2 -1
  20. package/dist/validation.types.d.ts +10 -11
  21. package/dist/widgets/__shared__/noop-validator.d.ts +1 -1
  22. package/dist/widgets/definition/definition.d.ts +1 -2
  23. package/dist/widgets/explanation/explanation.d.ts +1 -2
  24. package/dist/widgets/expression/expression.d.ts +25 -12
  25. package/dist/widgets/image/image.d.ts +1 -2
  26. package/dist/widgets/input-number/input-number-validator.d.ts +2 -4
  27. package/dist/widgets/input-number/input-number.d.ts +0 -1
  28. package/dist/widgets/interaction/interaction.d.ts +1 -2
  29. package/dist/widgets/interactive-graphs/graphs/components/movable-line.d.ts +0 -11
  30. package/dist/widgets/interactive-graphs/graphs/point.d.ts +0 -2
  31. package/dist/widgets/interactive-graphs/graphs/use-transform.d.ts +0 -1
  32. package/dist/widgets/interactive-graphs/mafs-supported-graph-types.d.ts +2 -1
  33. package/dist/widgets/interactive-graphs/protractor.d.ts +0 -2
  34. package/dist/widgets/label-image/answer-choices.d.ts +1 -1
  35. package/dist/widgets/label-image/label-image-validator.d.ts +1 -1
  36. package/dist/widgets/label-image/label-image.d.ts +14 -30
  37. package/dist/widgets/matrix/matrix.d.ts +0 -1
  38. package/dist/widgets/measurer/measurer.d.ts +3 -15
  39. package/dist/widgets/molecule/molecule.d.ts +0 -21
  40. package/dist/widgets/number-line/number-line.d.ts +0 -1
  41. package/dist/widgets/numeric-input/numeric-input.d.ts +0 -1
  42. package/dist/widgets/orderer/orderer.d.ts +1 -1
  43. package/dist/widgets/passage/passage.d.ts +1 -2
  44. package/dist/widgets/passage-ref/passage-ref.d.ts +1 -2
  45. package/dist/widgets/radio/base-radio.d.ts +2 -1
  46. package/dist/widgets/table/table.d.ts +0 -1
  47. package/dist/widgets/video/video.d.ts +1 -2
  48. package/package.json +4 -4
  49. package/dist/util/fix-passage-refs.d.ts +0 -3
  50. package/dist/widgets/radio/choice.jsx.fixture.d.ts +0 -1
package/dist/index.d.ts CHANGED
@@ -84,7 +84,7 @@ export type { ILogger, LogErrorOptions } from "./logging/log";
84
84
  export type { ServerItemRenderer as ServerItemRendererComponent } from "./server-item-renderer";
85
85
  export type { Alignment, APIOptions, APIOptionsWithDefaults, ChangeHandler, DeviceType, DomInsertCheckFn, EditorMode, FocusPath, ImageDict, ImageUploader, JiptLabelStore, JiptRenderer, PerseusDependencies, PerseusScore, Version, VideoData, VideoKind, WidgetExports, SharedRendererProps, } from "./types";
86
86
  export type { ParsedValue } from "./util";
87
- export type { Hint, LegacyButtonSets, LockedFigure, LockedFigureColor, LockedFigureFillType, LockedFigureType, LockedPointType, LockedLineType, LockedVectorType, LockedEllipseType, LockedPolygonType, LockedFunctionType, LockedLabelType, PerseusGraphType, PerseusAnswerArea, PerseusExpressionWidgetOptions, Range, Size, CollinearTuple, MathFormat, InputNumberWidget, // TODO(jeremy): remove?
87
+ export type { Hint, LegacyButtonSets, LockedFigure, LockedFigureColor, LockedFigureFillType, LockedFigureType, LockedPointType, LockedLineType, LockedVectorType, LockedEllipseType, LockedPolygonType, LockedFunctionType, LockedLabelType, LockedLineStyle, PerseusGraphType, PerseusAnswerArea, PerseusExpressionWidgetOptions, Range, Size, CollinearTuple, MathFormat, InputNumberWidget, // TODO(jeremy): remove?
88
88
  PerseusImageBackground, PerseusInputNumberWidgetOptions, PerseusInteractiveGraphWidgetOptions, PerseusItem, PerseusPhetSimulationWidgetOptions, PerseusPlotterWidgetOptions, PerseusPythonProgramWidgetOptions, PerseusRadioWidgetOptions, PerseusExampleWidgetOptions, PerseusSimpleMarkdownTesterWidgetOptions, PerseusRenderer, PerseusWidget, PerseusWidgetsMap, MultiItem, } from "./perseus-types";
89
89
  export type { Coord } from "./interactive2/types";
90
90
  export type { MarkerType } from "./widgets/label-image/types";
package/dist/index.js CHANGED
@@ -2530,12 +2530,6 @@ class Expression extends React__namespace.Component {
2530
2530
  /* c8 ignore next */
2531
2531
  return [[]];
2532
2532
  };
2533
-
2534
- // TODO(Nicole): I believe this is going away and won't be needed anymore
2535
- getGrammarTypeForPath(inputPath) {
2536
- /* c8 ignore next */
2537
- return "expression";
2538
- }
2539
2533
  setInputValue(path, newValue, cb) {
2540
2534
  this.props.onChange({
2541
2535
  value: newValue
@@ -2995,7 +2989,9 @@ function flattenScores(widgetScoreMap) {
2995
2989
  function isCorrect(score) {
2996
2990
  return score.type === "points" && score.earned >= score.total;
2997
2991
  }
2998
- function keScoreFromPerseusScore(score, guess, state) {
2992
+ function keScoreFromPerseusScore(score,
2993
+ // It's weird, but this is what we're passing it
2994
+ guess, state) {
2999
2995
  if (score.type === "points") {
3000
2996
  return {
3001
2997
  empty: false,
@@ -4006,36 +4002,14 @@ const ZoomService = new ZoomServiceClass();
4006
4002
  const baseFontFamily$1 = "'Lato', sans-serif";
4007
4003
  // @boldFontFamily: "Lato-Bold", "Lato", sans-serif;
4008
4004
  const boldFontFamily = "'Lato-Bold', 'Lato', sans-serif";
4009
- // @green: #76a005;
4010
- const green$1 = "#76A005";
4011
4005
  // @kaGreen: #71b307;
4012
4006
  const kaGreen$1 = "#71B307";
4013
- // @blue: #1c758a;
4014
- const blue$1 = "#1C758A";
4015
- // @gray: #aaa;
4016
- const gray$1 = "#AAAAAA";
4017
- // @red: #ffbaba;
4018
- const red$1 = "#FFBABA";
4019
- // @grayLight: #aaa;
4020
- const grayLight$1 = "#AAAAAA";
4021
- // @grayLighter: #ddd;
4022
- const grayLighter$1 = "#DDDDDD";
4023
- // @learnstormBlue: #4898fc;
4024
- const learnstormBlue$1 = "#4898FC";
4025
4007
  const white$1 = "#FFFFFF";
4026
- const gray98 = "#FAFAFA";
4027
4008
  const gray97 = "#F6F7F7";
4028
- const gray95 = "#F0F1F2";
4029
- const gray90 = "#E3E5E6";
4030
4009
  const gray85 = "#D6D8DA";
4031
4010
  const gray76 = "#BABEC2";
4032
4011
  const gray68 = "#888D93";
4033
- const gray41 = "#626569";
4034
- const gray25 = "#3B3e40";
4035
4012
  const gray17 = "#21242c";
4036
- const black$1 = "#000000";
4037
- const warning1 = "#F86700";
4038
- const warning3 = "#C75300";
4039
4013
 
4040
4014
  // @pure-sm-min: 568px;
4041
4015
  const pureSmMin$2 = "568px";
@@ -4055,16 +4029,10 @@ const pureMdMax$2 = "1023px";
4055
4029
  const pureLgMax$2 = "1279px";
4056
4030
  // @tableBackgroundAccent: #f9f9f9; // for striping
4057
4031
  const tableBackgroundAccent$1 = "#F9F9F9";
4058
- // @zIndexScratchPad: 1;
4059
- const zIndexScratchPad = 1;
4060
4032
  // @zIndexAboveScratchpad: @zIndexScratchPad + 1;
4061
4033
  const zIndexAboveScratchpad$1 = 2;
4062
4034
  // @zIndexInteractiveComponent: @zIndexAboveScratchpad + 1;
4063
4035
  const zIndexInteractiveComponent$1 = 3;
4064
- // @zIndexCurrentlyDragging: @zIndexInteractiveComponent + 1;
4065
- const zIndexCurrentlyDragging = 4;
4066
- // @zIndexCalculator: @zIndexCurrentlyDragging + 1;
4067
- const zIndexCalculator = 5;
4068
4036
  // @phoneMargin: 16px;
4069
4037
  const phoneMargin = 16;
4070
4038
  const negativePhoneMargin = -16;
@@ -4092,28 +4060,13 @@ var constants$1 = /*#__PURE__*/Object.freeze({
4092
4060
  __proto__: null,
4093
4061
  baseFontFamily: baseFontFamily$1,
4094
4062
  boldFontFamily: boldFontFamily,
4095
- green: green$1,
4096
4063
  kaGreen: kaGreen$1,
4097
- blue: blue$1,
4098
- gray: gray$1,
4099
- red: red$1,
4100
- grayLight: grayLight$1,
4101
- grayLighter: grayLighter$1,
4102
- learnstormBlue: learnstormBlue$1,
4103
4064
  white: white$1,
4104
- gray98: gray98,
4105
4065
  gray97: gray97,
4106
- gray95: gray95,
4107
- gray90: gray90,
4108
4066
  gray85: gray85,
4109
4067
  gray76: gray76,
4110
4068
  gray68: gray68,
4111
- gray41: gray41,
4112
- gray25: gray25,
4113
4069
  gray17: gray17,
4114
- black: black$1,
4115
- warning1: warning1,
4116
- warning3: warning3,
4117
4070
  pureSmMin: pureSmMin$2,
4118
4071
  pureMdMin: pureMdMin$2,
4119
4072
  pureLgMin: pureLgMin$2,
@@ -4123,11 +4076,8 @@ var constants$1 = /*#__PURE__*/Object.freeze({
4123
4076
  pureMdMax: pureMdMax$2,
4124
4077
  pureLgMax: pureLgMax$2,
4125
4078
  tableBackgroundAccent: tableBackgroundAccent$1,
4126
- zIndexScratchPad: zIndexScratchPad,
4127
4079
  zIndexAboveScratchpad: zIndexAboveScratchpad$1,
4128
4080
  zIndexInteractiveComponent: zIndexInteractiveComponent$1,
4129
- zIndexCurrentlyDragging: zIndexCurrentlyDragging,
4130
- zIndexCalculator: zIndexCalculator,
4131
4081
  phoneMargin: phoneMargin,
4132
4082
  negativePhoneMargin: negativePhoneMargin,
4133
4083
  hintBorderWidth: hintBorderWidth,
@@ -20119,6 +20069,7 @@ class Renderer extends React__namespace.Component {
20119
20069
  onBlur: ___default["default"].partial(this._onWidgetBlur, id),
20120
20070
  findWidgets: this.findWidgets,
20121
20071
  reviewModeRubric: reviewModeRubric,
20072
+ reviewMode: this.props.reviewMode,
20122
20073
  onChange: function (newProps, cb) {
20123
20074
  let silent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
20124
20075
  _this._setWidgetProps(id, newProps, cb, silent);
@@ -20832,14 +20783,6 @@ class Renderer extends React__namespace.Component {
20832
20783
  return ReactDOM__default["default"].findDOMNode(widget);
20833
20784
  }
20834
20785
  };
20835
- getGrammarTypeForPath = path => {
20836
- // @ts-expect-error - TS2345 - Argument of type 'FocusPath' is not assignable to parameter of type 'List<any>'.
20837
- const widgetId = ___default["default"].first(path);
20838
- // @ts-expect-error - TS2345 - Argument of type 'FocusPath' is not assignable to parameter of type 'List<any>'.
20839
- const interWidgetPath = ___default["default"].rest(path);
20840
- const widget = this.getWidgetInstance(widgetId);
20841
- return widget?.getGrammarTypeForPath?.(interWidgetPath);
20842
- };
20843
20786
  getInputPaths = () => {
20844
20787
  const inputPaths = [];
20845
20788
  ___default["default"].each(this.widgetIds, widgetId => {
@@ -21040,11 +20983,11 @@ class Renderer extends React__namespace.Component {
21040
20983
  const combinedScore = Util.flattenScores(scores);
21041
20984
  return combinedScore;
21042
20985
  }
21043
- guessAndScore = () => {
20986
+ guessAndScore() {
21044
20987
  const totalGuess = this.getUserInput();
21045
20988
  const totalScore = this.score();
21046
20989
  return [totalGuess, totalScore];
21047
- };
20990
+ }
21048
20991
  examples = () => {
21049
20992
  const widgetIds = this.widgetIds;
21050
20993
  const examples = ___default["default"].compact(___default["default"].map(widgetIds, widgetId => {
@@ -21900,7 +21843,7 @@ const answerTypes = {
21900
21843
  forms: "pi"
21901
21844
  }
21902
21845
  };
21903
- function inputNumberValidator(state, rubric, strings) {
21846
+ function inputNumberValidator(userInput, rubric, strings) {
21904
21847
  if (rubric.answerType == null) {
21905
21848
  rubric.answerType = "number";
21906
21849
  }
@@ -21918,7 +21861,7 @@ function inputNumberValidator(state, rubric, strings) {
21918
21861
 
21919
21862
  // We may have received TeX; try to parse it before grading.
21920
21863
  // If `currentValue` is not TeX, this should be a no-op.
21921
- const currentValue = ParseTex$1(state.currentValue);
21864
+ const currentValue = ParseTex$1(userInput.currentValue);
21922
21865
  const result = val(currentValue);
21923
21866
 
21924
21867
  // TODO(eater): Seems silly to translate result to this invalid/points
@@ -22023,13 +21966,6 @@ class InputNumber extends React__namespace.Component {
22023
21966
  /* c8 ignore next */
22024
21967
  return [[]];
22025
21968
  };
22026
-
22027
- // Note: We believe that this isn't used anywhere but are leaving it during
22028
- // the initial refactor
22029
- getGrammarTypeForPath = path => {
22030
- /* c8 ignore next */
22031
- return "number";
22032
- };
22033
21969
  setInputValue = (path, newValue, cb) => {
22034
21970
  this.props.onChange({
22035
21971
  currentValue: newValue
@@ -22067,17 +22003,13 @@ class InputNumber extends React__namespace.Component {
22067
22003
  }
22068
22004
  return input;
22069
22005
  }
22070
- // HACK(johnsullivan): Create a function with shared logic between
22071
- // this and NumericInput.
22072
- // TODO(jeremy): Deprecate this widget and prefer numeric-input.
22073
- const rubric = this.props.reviewModeRubric;
22074
22006
 
22075
22007
  // Note: This is _very_ similar to what `numeric-input.jsx` does. If
22076
22008
  // you modify this, double-check if you also need to modify that
22077
22009
  // component.
22078
22010
  const inputStyles = [styles$A.default, this.props.size === "small" ? styles$A.small : null, this.props.rightAlign ? styles$A.rightAlign : styles$A.leftAlign];
22079
22011
  // Unanswered
22080
- if (rubric && !this.props.currentValue) {
22012
+ if (this.props.reviewMode && !this.props.currentValue) {
22081
22013
  inputStyles.push(styles$A.answerStateUnanswered);
22082
22014
  }
22083
22015
  return /*#__PURE__*/React__namespace.createElement(InputWithExamples
@@ -22378,10 +22310,6 @@ class NumericInput extends React__namespace.Component {
22378
22310
  /* c8 ignore next */
22379
22311
  return [[]];
22380
22312
  };
22381
- getGrammarTypeForPath = inputPath => {
22382
- /* c8 ignore next */
22383
- return "number";
22384
- };
22385
22313
  setInputValue = (path, newValue, cb) => {
22386
22314
  /* c8 ignore next */
22387
22315
  this.props.onChange({
@@ -22551,7 +22479,7 @@ var NumericInput$1 = {
22551
22479
  * Several widgets don't have "right"/"wrong" validation logic,
22552
22480
  * so this just says to move on past those widgets
22553
22481
  *
22554
- * TODO(LEMS-2396) widgets that use this probably shouldn't have any
22482
+ * TODO(LEMS-2543) widgets that use this probably shouldn't have any
22555
22483
  * validation logic and the thing validating an exercise
22556
22484
  * should just know to skip these
22557
22485
  */
@@ -24625,7 +24553,7 @@ class Passage extends React__namespace.Component {
24625
24553
  const enabled = this.state.stylesAreApplied;
24626
24554
 
24627
24555
  // Highlights are read-only in review mode.
24628
- const editable = !this.props.reviewModeRubric;
24556
+ const editable = !this.props.reviewMode;
24629
24557
  return /*#__PURE__*/React__namespace.createElement(HighlightableContent, {
24630
24558
  editable: editable,
24631
24559
  enabled: enabled,
@@ -25887,6 +25815,7 @@ const BaseRadio = function (props) {
25887
25815
  const {
25888
25816
  apiOptions,
25889
25817
  reviewModeRubric,
25818
+ reviewMode,
25890
25819
  choices,
25891
25820
  editMode,
25892
25821
  multipleSelect,
@@ -25999,7 +25928,6 @@ const BaseRadio = function (props) {
25999
25928
  });
26000
25929
 
26001
25930
  // some commonly used shorthands
26002
- const reviewMode = !!reviewModeRubric;
26003
25931
  const isMobile = apiOptions.isMobile;
26004
25932
  const firstChoiceHighlighted = choices[0].highlighted;
26005
25933
  const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
@@ -26600,7 +26528,7 @@ class Radio$1 extends React__namespace.Component {
26600
26528
  highlighted,
26601
26529
  previouslyAnswered
26602
26530
  } = choiceStates[i];
26603
- const reviewChoice = this.props.reviewModeRubric && this.props.reviewModeRubric.choices[i];
26531
+ const reviewChoice = this.props.reviewModeRubric?.choices[i];
26604
26532
  return {
26605
26533
  content: this._renderRenderer(content),
26606
26534
  checked: selected,
@@ -26635,6 +26563,7 @@ class Radio$1 extends React__namespace.Component {
26635
26563
  choices: choicesProp,
26636
26564
  onChange: this.updateChoices,
26637
26565
  reviewModeRubric: this.props.reviewModeRubric,
26566
+ reviewMode: this.props.reviewMode,
26638
26567
  deselectEnabled: this.props.deselectEnabled,
26639
26568
  apiOptions: this.props.apiOptions,
26640
26569
  isLastUsedWidget: this.props.isLastUsedWidget,
@@ -29393,7 +29322,7 @@ class Group extends React__namespace.Component {
29393
29322
  ref: ref => this.rendererRef = ref,
29394
29323
  apiOptions: apiOptions,
29395
29324
  findExternalWidgets: this.props.findWidgets,
29396
- reviewMode: !!this.props.reviewModeRubric,
29325
+ reviewMode: this.props.reviewMode,
29397
29326
  onInteractWithWidget: onInteractWithWidget,
29398
29327
  linterContext: this.props.linterContext,
29399
29328
  strings: this.context.strings
@@ -39035,10 +38964,12 @@ function scoreMarker(marker) {
39035
38964
  }
39036
38965
  return score;
39037
38966
  }
39038
- function labelImageValidator(state, rubric) {
38967
+
38968
+ // TODO(LEMS-2440): May need to pull answers out of PerseusLabelImageWidgetOptions[markers] for the rubric
38969
+ function labelImageValidator(userInput, rubric) {
39039
38970
  let numAnswered = 0;
39040
38971
  let numCorrect = 0;
39041
- for (const marker of state.markers) {
38972
+ for (const marker of userInput.markers) {
39042
38973
  const score = scoreMarker(marker);
39043
38974
  if (score.hasAnswers) {
39044
38975
  numAnswered++;
@@ -39049,7 +38980,7 @@ function labelImageValidator(state, rubric) {
39049
38980
  }
39050
38981
 
39051
38982
  // We expect all question markers to be answered before grading.
39052
- if (numAnswered !== state.markers.length) {
38983
+ if (numAnswered !== userInput.markers.length) {
39053
38984
  return {
39054
38985
  type: "invalid",
39055
38986
  message: null
@@ -39059,7 +38990,7 @@ function labelImageValidator(state, rubric) {
39059
38990
  type: "points",
39060
38991
  // Markers with no expected answers are graded as correct if user
39061
38992
  // makes no answer selection.
39062
- earned: numCorrect === state.markers.length ? 1 : 0,
38993
+ earned: numCorrect === userInput.markers.length ? 1 : 0,
39063
38994
  total: 1,
39064
38995
  message: null
39065
38996
  };
@@ -39325,8 +39256,6 @@ const styles$b = aphrodite.StyleSheet.create({
39325
39256
  * No diagonals allowed.
39326
39257
  */
39327
39258
 
39328
- // TODO: should this be using WidgetProps / PerseusLabelImageWidgetOptions?
39329
-
39330
39259
  class LabelImage extends React__namespace.Component {
39331
39260
  static contextType = PerseusI18nContext;
39332
39261
  // The rendered markers on the question image for labeling.
@@ -39532,6 +39461,8 @@ class LabelImage extends React__namespace.Component {
39532
39461
  markers
39533
39462
  };
39534
39463
  }
39464
+
39465
+ // TODO(LEMS-2544): Investigate impact on scoring; possibly pull out &/or remove rubric parameter.
39535
39466
  showRationalesForCurrentlySelectedChoices(rubric) {
39536
39467
  const {
39537
39468
  markers
@@ -40975,9 +40906,6 @@ class Matrix extends React__namespace.Component {
40975
40906
  });
40976
40907
  return inputPaths;
40977
40908
  };
40978
- getGrammarTypeForPath = inputPath => {
40979
- return "number";
40980
- };
40981
40909
  _handleFocus = (row, col) => {
40982
40910
  this.props.onFocus(getInputPath$1(row, col));
40983
40911
  };
@@ -41294,7 +41222,7 @@ const defaultImage = {
41294
41222
  class Measurer extends React__namespace.Component {
41295
41223
  static defaultProps = {
41296
41224
  box: [480, 480],
41297
- image: {},
41225
+ image: defaultImage,
41298
41226
  showProtractor: true,
41299
41227
  protractorX: 7.5,
41300
41228
  protractorY: 0.5,
@@ -42450,10 +42378,12 @@ const TickMarks = Graphie.createSimpleClass((graphie, props) => {
42450
42378
  };
42451
42379
 
42452
42380
  // Generate an array of tick numbers:
42453
- // `Array(props.numDivisions)` makes an array of null values - one for every division marker
42381
+ // `Array(Math.round(numDivisions))` makes an array of null values - one for every division marker
42454
42382
  // `.keys()` gets the index values for each marker placeholder
42455
42383
  // `.map()` converts the index values into actual tick numbers
42456
- const initialTicks = [...Array(numDivisions).keys()].map(index => range[0] + index * tickStep);
42384
+ // NOTE: 'numDivisions' can sometimes be a non-integer (i.e. 7.000001).
42385
+ // Using Math.round() to ensure that an integer is used in the Array setup.
42386
+ const initialTicks = [...Array(Math.round(numDivisions)).keys()].map(index => range[0] + index * tickStep);
42457
42387
 
42458
42388
  // .sort() comparator
42459
42389
  const byNumericAscending = (a, b) => a - b;
@@ -42590,11 +42520,6 @@ class NumberLine extends React__namespace.Component {
42590
42520
  }
42591
42521
  return null;
42592
42522
  }
42593
- getGrammarTypeForPath(inputPath) {
42594
- if (inputPath?.length === 1 && inputPath[0] === "tick-ctrl") {
42595
- return "number";
42596
- }
42597
- }
42598
42523
  setInputValue = (inputPath, value, callback) => {
42599
42524
  if (inputPath.length === 1 && inputPath[0] === "tick-ctrl") {
42600
42525
  this.onNumDivisionsChange(value, callback);
@@ -44883,9 +44808,6 @@ class Table extends React__namespace.Component {
44883
44808
  });
44884
44809
  return inputPaths;
44885
44810
  };
44886
- getGrammarTypeForPath = inputPath => {
44887
- return "number";
44888
- };
44889
44811
  setInputValue = (path, newValue, cb) => {
44890
44812
  // Extract row, column information
44891
44813
  const row = getRowFromPath(path);
@@ -45179,7 +45101,7 @@ const init = function (options) {
45179
45101
 
45180
45102
  // This file is processed by a Rollup plugin (replace) to inject the production
45181
45103
  const libName = "@khanacademy/perseus";
45182
- const libVersion = "38.0.0";
45104
+ const libVersion = "39.0.0";
45183
45105
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
45184
45106
 
45185
45107
  const apiVersion = {
@@ -45890,9 +45812,6 @@ class ServerItemRenderer extends React__namespace.Component {
45890
45812
  getDOMNodeForPath(path) {
45891
45813
  return this.questionRenderer.getDOMNodeForPath(path);
45892
45814
  }
45893
- getGrammarTypeForPath(path) {
45894
- return this.questionRenderer.getGrammarTypeForPath(path);
45895
- }
45896
45815
  getInputPaths() {
45897
45816
  const questionAreaInputPaths = this.questionRenderer.getInputPaths();
45898
45817
  return questionAreaInputPaths;
@@ -47193,7 +47112,6 @@ const styles = aphrodite.StyleSheet.create({
47193
47112
  * If you're writing new components, though, consider using the Item and Shape
47194
47113
  * types instead.
47195
47114
  */
47196
-
47197
47115
  /**
47198
47116
  * Return a PropType that accepts Items of the given shape, and rejects other
47199
47117
  * objects.
@@ -47425,6 +47343,21 @@ function violatingWidgets(itemData) {
47425
47343
  }
47426
47344
 
47427
47345
  /* eslint-disable eqeqeq, @typescript-eslint/no-unused-vars */
47346
+ /*
47347
+ * A class for formatting number to significant digits.
47348
+ * Copyright (C) 2001 Stephen Ostermiller
47349
+ * http://ostermiller.org/contact.pl?regarding?JavaScript+Significant+Figures
47350
+ *
47351
+ * This program is free software; you can redistribute it and/or modify
47352
+ * it under the terms of the GNU General Public License as published by
47353
+ * the Free Software Foundation; either version 2 of the License, or
47354
+ * (at your option) any later version.
47355
+ *
47356
+ * This program is distributed in the hope that it will be useful,
47357
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
47358
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47359
+ * GNU General Public License for more details.
47360
+ */
47428
47361
 
47429
47362
  /**
47430
47363
  * Format a floating point for display using the specified