@khanacademy/perseus-editor 3.0.1 → 4.1.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/index.js CHANGED
@@ -64,7 +64,7 @@ var i18n__namespace = /*#__PURE__*/_interopNamespace(i18n$1);
64
64
 
65
65
  // This file is processed by a Rollup plugin (replace) to inject the production
66
66
  const libName = "@khanacademy/perseus-editor";
67
- const libVersion = "3.0.1";
67
+ const libVersion = "4.1.0";
68
68
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
69
69
 
70
70
  function _extends() {
@@ -23456,7 +23456,7 @@ class StructuredItemDiff extends React__namespace.Component {
23456
23456
 
23457
23457
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
23458
23458
  const {
23459
- InfoTip: InfoTip$n,
23459
+ InfoTip: InfoTip$m,
23460
23460
  InlineIcon: InlineIcon$8
23461
23461
  } = perseus.components;
23462
23462
  const {
@@ -23530,7 +23530,7 @@ class HintEditor extends React__namespace.Component {
23530
23530
  type: "button",
23531
23531
  className: this.props.isFirst ? "hidden" : "",
23532
23532
  onClick: ___default["default"].partial(this.props.onMove, -1)
23533
- }, /*#__PURE__*/React__namespace.createElement(InlineIcon$8, iconCircleArrowUp$1)), " ", this.props.isLast && /*#__PURE__*/React__namespace.createElement(InfoTip$n, null, /*#__PURE__*/React__namespace.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React__namespace.createElement("input", {
23533
+ }, /*#__PURE__*/React__namespace.createElement(InlineIcon$8, iconCircleArrowUp$1)), " ", this.props.isLast && /*#__PURE__*/React__namespace.createElement(InfoTip$m, null, /*#__PURE__*/React__namespace.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React__namespace.createElement("input", {
23534
23534
  type: "checkbox"
23535
23535
  // @ts-expect-error - TS2322 - Type 'boolean | null | undefined' is not assignable to type 'boolean | undefined'.
23536
23536
  ,
@@ -23765,7 +23765,7 @@ class CombinedHintsEditor extends React__namespace.Component {
23765
23765
  }
23766
23766
 
23767
23767
  const {
23768
- InfoTip: InfoTip$m
23768
+ InfoTip: InfoTip$l
23769
23769
  } = perseus.components;
23770
23770
  class ItemExtrasEditor extends React__namespace.Component {
23771
23771
  static defaultProps = {
@@ -23922,7 +23922,7 @@ const ItemExtraCheckbox = props => /*#__PURE__*/React__namespace.createElement("
23922
23922
  type: "checkbox",
23923
23923
  checked: props.checked,
23924
23924
  onChange: props.onChange
23925
- })), /*#__PURE__*/React__namespace.createElement(InfoTip$m, null, props.infoTip));
23925
+ })), /*#__PURE__*/React__namespace.createElement(InfoTip$l, null, props.infoTip));
23926
23926
 
23927
23927
  const ITEM_DATA_VERSION = perseus.itemDataVersion;
23928
23928
  class ItemEditor extends React__namespace.Component {
@@ -24304,8 +24304,6 @@ function widgetCallback(widgetInfo, images) {
24304
24304
  images.push(widgetInfo.options.image.url);
24305
24305
  } else if (widgetInfo.type === "plotter") {
24306
24306
  images.push(widgetInfo.options.picUrl);
24307
- } else if (widgetInfo.type === "transformer") {
24308
- handleBackgroundImage(widgetInfo.options.graph, images);
24309
24307
  }
24310
24308
  }
24311
24309
  function findImagesInRenderers(renderers) {
@@ -25727,7 +25725,7 @@ const StatefulEditorPage = createReactClass__default["default"]({
25727
25725
  });
25728
25726
 
25729
25727
  const {
25730
- PropCheckBox: PropCheckBox$d,
25728
+ PropCheckBox: PropCheckBox$c,
25731
25729
  TextListEditor: TextListEditor$4
25732
25730
  } = perseus.components;
25733
25731
  const Categorizer = perseus.Categorizer.widget;
@@ -25762,7 +25760,7 @@ class CategorizerEditor extends React__namespace.Component {
25762
25760
  render() {
25763
25761
  return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", {
25764
25762
  className: "perseus-widget-row"
25765
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$d, {
25763
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$c, {
25766
25764
  label: "Randomize item order",
25767
25765
  labelAlignment: "right",
25768
25766
  randomizeItems: this.props.randomizeItems,
@@ -25860,8 +25858,8 @@ class BlurInput extends React__namespace.Component {
25860
25858
 
25861
25859
  /* eslint-disable no-useless-escape */
25862
25860
  const {
25863
- InfoTip: InfoTip$l,
25864
- PropCheckBox: PropCheckBox$c
25861
+ InfoTip: InfoTip$k,
25862
+ PropCheckBox: PropCheckBox$b
25865
25863
  } = perseus.components;
25866
25864
  const DEFAULT_WIDTH = 400;
25867
25865
  const DEFAULT_HEIGHT = 400;
@@ -26044,11 +26042,11 @@ class CSProgramEditor extends React__namespace.Component {
26044
26042
  return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Url or Program ID:", " ", /*#__PURE__*/React__namespace.createElement(BlurInput, {
26045
26043
  value: this.props.programID,
26046
26044
  onChange: this._handleProgramIDChange
26047
- })), /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement(PropCheckBox$c, {
26045
+ })), /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement(PropCheckBox$b, {
26048
26046
  label: "Show Editor",
26049
26047
  showEditor: this.props.showEditor,
26050
26048
  onChange: this.props.onChange
26051
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$l, null, "If you show the editor, you should use the \"full-width\" alignment to make room for the width of the editor."), /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement(PropCheckBox$c, {
26049
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$k, null, "If you show the editor, you should use the \"full-width\" alignment to make room for the width of the editor."), /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement(PropCheckBox$b, {
26052
26050
  label: "Show Buttons",
26053
26051
  showButtons: this.props.showButtons,
26054
26052
  onChange: this.props.onChange
@@ -26056,7 +26054,7 @@ class CSProgramEditor extends React__namespace.Component {
26056
26054
  name: "settings",
26057
26055
  pairs: this.props.settings,
26058
26056
  onChange: this._handleSettingsChange
26059
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$l, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React__namespace.createElement("code", null, "Program.settings()"))));
26057
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$k, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React__namespace.createElement("code", null, "Program.settings()"))));
26060
26058
  }
26061
26059
  }
26062
26060
 
@@ -26133,7 +26131,7 @@ class DeprecatedStandinEditor extends React__namespace.Component {
26133
26131
 
26134
26132
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
26135
26133
  const {
26136
- InfoTip: InfoTip$k,
26134
+ InfoTip: InfoTip$j,
26137
26135
  InlineIcon: InlineIcon$6
26138
26136
  } = perseus.components;
26139
26137
  const {
@@ -26214,14 +26212,14 @@ class DropdownEditor extends React__namespace.Component {
26214
26212
  className: "perseus-widget-dropdown"
26215
26213
  }, /*#__PURE__*/React__namespace.createElement("div", {
26216
26214
  className: "dropdown-info"
26217
- }, "Dropdown", /*#__PURE__*/React__namespace.createElement(InfoTip$k, null, /*#__PURE__*/React__namespace.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React__namespace.createElement("div", {
26215
+ }, "Dropdown", /*#__PURE__*/React__namespace.createElement(InfoTip$j, null, /*#__PURE__*/React__namespace.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React__namespace.createElement("div", {
26218
26216
  className: "dropdown-placeholder"
26219
26217
  }, /*#__PURE__*/React__namespace.createElement("input", {
26220
26218
  type: "text",
26221
26219
  placeholder: "Placeholder value",
26222
26220
  value: this.props.placeholder,
26223
26221
  onChange: this.onPlaceholderChange
26224
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$k, null, /*#__PURE__*/React__namespace.createElement("p", null, "This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."))), /*#__PURE__*/React__namespace.createElement("div", {
26222
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$j, null, /*#__PURE__*/React__namespace.createElement("p", null, "This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."))), /*#__PURE__*/React__namespace.createElement("div", {
26225
26223
  className: "clearfix"
26226
26224
  }), /*#__PURE__*/React__namespace.createElement("ul", {
26227
26225
  className: "dropdown-choices"
@@ -26761,8 +26759,8 @@ const SortableItem = createReactClass__default["default"]({
26761
26759
  });
26762
26760
 
26763
26761
  const {
26764
- InfoTip: InfoTip$j,
26765
- PropCheckBox: PropCheckBox$b
26762
+ InfoTip: InfoTip$i,
26763
+ PropCheckBox: PropCheckBox$a
26766
26764
  } = perseus.components;
26767
26765
 
26768
26766
  // types for iterables
@@ -26881,16 +26879,16 @@ class ExpressionEditor extends React__namespace.Component {
26881
26879
  className: "perseus-widget-expression-editor"
26882
26880
  }, /*#__PURE__*/React__namespace.createElement("h3", {
26883
26881
  className: "expression-editor-h3"
26884
- }, "Global Options"), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(PropCheckBox$b, {
26882
+ }, "Global Options"), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(PropCheckBox$a, {
26885
26883
  times: this.props.times,
26886
26884
  onChange: this.props.onChange,
26887
26885
  labelAlignment: "right",
26888
26886
  label: "Use \xD7 for rendering multiplication instead of a center dot."
26889
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$j, null, /*#__PURE__*/React__namespace.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Function variables: ", /*#__PURE__*/React__namespace.createElement("input", {
26887
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Function variables: ", /*#__PURE__*/React__namespace.createElement("input", {
26890
26888
  type: "text",
26891
26889
  defaultValue: this.props.functions.join(" "),
26892
26890
  onChange: this.handleFunctions
26893
- })), /*#__PURE__*/React__namespace.createElement(InfoTip$j, null, /*#__PURE__*/React__namespace.createElement("p", null, "Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means \"f of x\" and not \"f times x\"."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, "Button sets:"), buttonSetChoices), /*#__PURE__*/React__namespace.createElement("h3", {
26891
+ })), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means \"f of x\" and not \"f times x\"."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, "Button sets:"), buttonSetChoices), /*#__PURE__*/React__namespace.createElement("h3", {
26894
26892
  className: "expression-editor-h3"
26895
26893
  }, "Answers"), /*#__PURE__*/React__namespace.createElement("p", {
26896
26894
  style: {
@@ -27099,19 +27097,19 @@ class AnswerOption extends React__namespace.Component {
27099
27097
  className: "answer-expression"
27100
27098
  }, /*#__PURE__*/React__namespace.createElement(perseus.Expression, this.props.expressionProps))), /*#__PURE__*/React__namespace.createElement("div", {
27101
27099
  className: "answer-option"
27102
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$b, {
27100
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$a, {
27103
27101
  form: this.props.form,
27104
27102
  onChange: this.props.onChange,
27105
27103
  labelAlignment: "right",
27106
27104
  label: "Answer expression must have the same form."
27107
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$j, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React__namespace.createElement("div", {
27105
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React__namespace.createElement("div", {
27108
27106
  className: "answer-option"
27109
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$b, {
27107
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$a, {
27110
27108
  simplify: this.props.simplify,
27111
27109
  onChange: this.props.onChange,
27112
27110
  labelAlignment: "right",
27113
27111
  label: "Answer expression must be fully expanded and simplified."
27114
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$j, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student's answer must be fully expanded and simplified. Answering this equation (x^2+2x+1) with this factored equation (x+1)^2 will render this response \"Your answer is not fully expanded and simplified.\""))), /*#__PURE__*/React__namespace.createElement("div", {
27112
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student's answer must be fully expanded and simplified. Answering this equation (x^2+2x+1) with this factored equation (x+1)^2 will render this response \"Your answer is not fully expanded and simplified.\""))), /*#__PURE__*/React__namespace.createElement("div", {
27115
27113
  className: "remove-container"
27116
27114
  }, removeButton)));
27117
27115
  }
@@ -27336,14 +27334,14 @@ const setArrayItem = (list, i, value) => [...list.slice(0, i), value, ...list.sl
27336
27334
  /* eslint-disable react/forbid-prop-types, react/no-unsafe */
27337
27335
  const {
27338
27336
  ButtonGroup: ButtonGroup$3,
27339
- InfoTip: InfoTip$i,
27340
- PropCheckBox: PropCheckBox$a,
27337
+ InfoTip: InfoTip$h,
27338
+ PropCheckBox: PropCheckBox$9,
27341
27339
  RangeInput: RangeInput$5
27342
27340
  } = perseus.components;
27343
27341
  const {
27344
27342
  getDependencies: getDependencies$9
27345
27343
  } = perseus.Dependencies;
27346
- const defaultBackgroundImage$3 = {
27344
+ const defaultBackgroundImage$2 = {
27347
27345
  url: null,
27348
27346
  width: 0,
27349
27347
  height: 0
@@ -27381,7 +27379,7 @@ const GraphSettings = createReactClass__default["default"]({
27381
27379
  gridStep: [1, 1],
27382
27380
  snapStep: [1, 1],
27383
27381
  valid: true,
27384
- backgroundImage: defaultBackgroundImage$3,
27382
+ backgroundImage: defaultBackgroundImage$2,
27385
27383
  markings: "graph",
27386
27384
  showProtractor: false,
27387
27385
  showRuler: false,
@@ -27749,7 +27747,7 @@ const GraphSettings = createReactClass__default["default"]({
27749
27747
  onChange: this.change("markings")
27750
27748
  })), /*#__PURE__*/React__namespace.createElement("div", {
27751
27749
  className: "perseus-widget-left-col"
27752
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$a, {
27750
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$9, {
27753
27751
  label: "Show tooltips",
27754
27752
  showTooltips: this.props.showTooltips,
27755
27753
  onChange: this.change
@@ -27771,19 +27769,19 @@ const GraphSettings = createReactClass__default["default"]({
27771
27769
  },
27772
27770
  onKeyPress: this.changeBackgroundUrl,
27773
27771
  onBlur: this.changeBackgroundUrl
27774
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), ___default["default"].contains(this.props.editableSettings, "measure") && /*#__PURE__*/React__namespace.createElement("div", {
27772
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$h, null, /*#__PURE__*/React__namespace.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), ___default["default"].contains(this.props.editableSettings, "measure") && /*#__PURE__*/React__namespace.createElement("div", {
27775
27773
  className: "misc-settings"
27776
27774
  }, /*#__PURE__*/React__namespace.createElement("div", {
27777
27775
  className: "perseus-widget-row"
27778
27776
  }, /*#__PURE__*/React__namespace.createElement("div", {
27779
27777
  className: "perseus-widget-left-col"
27780
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$a, {
27778
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$9, {
27781
27779
  label: "Show ruler",
27782
27780
  showRuler: this.props.showRuler,
27783
27781
  onChange: this.change
27784
27782
  })), /*#__PURE__*/React__namespace.createElement("div", {
27785
27783
  className: "perseus-widget-right-col"
27786
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$a, {
27784
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$9, {
27787
27785
  label: "Show protractor",
27788
27786
  showProtractor: this.props.showProtractor,
27789
27787
  onChange: this.change
@@ -27808,7 +27806,7 @@ const GraphSettings = createReactClass__default["default"]({
27808
27806
  });
27809
27807
 
27810
27808
  const {
27811
- InfoTip: InfoTip$h,
27809
+ InfoTip: InfoTip$g,
27812
27810
  MultiButtonGroup: MultiButtonGroup$1
27813
27811
  } = perseus.components;
27814
27812
  const {
@@ -27882,7 +27880,7 @@ class GrapherEditor extends React__namespace.Component {
27882
27880
  className: "perseus-error"
27883
27881
  }, this.props.graph.valid);
27884
27882
  }
27885
- return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$h, null, /*#__PURE__*/React__namespace.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer.")), " ", ": ", equationString), /*#__PURE__*/React__namespace.createElement(GraphSettings, {
27883
+ return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$g, null, /*#__PURE__*/React__namespace.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer.")), " ", ": ", equationString), /*#__PURE__*/React__namespace.createElement(GraphSettings, {
27886
27884
  editableSettings: ["graph", "snap", "image"],
27887
27885
  box: getInteractiveBoxFromSizeClass$1(sizeClass),
27888
27886
  range: this.props.graph.range,
@@ -27994,7 +27992,7 @@ class GroupEditor extends React__namespace.Component {
27994
27992
 
27995
27993
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
27996
27994
  const {
27997
- PropCheckBox: PropCheckBox$9
27995
+ PropCheckBox: PropCheckBox$8
27998
27996
  } = perseus.components;
27999
27997
  /**
28000
27998
  * This is used for editing a name/value pair.
@@ -28134,11 +28132,11 @@ class IframeEditor extends React__namespace.Component {
28134
28132
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
28135
28133
  ,
28136
28134
  onChange: this.change("height")
28137
- })), /*#__PURE__*/React__namespace.createElement(PropCheckBox$9, {
28135
+ })), /*#__PURE__*/React__namespace.createElement(PropCheckBox$8, {
28138
28136
  label: "Allow full screen",
28139
28137
  allowFullScreen: this.props.allowFullScreen,
28140
28138
  onChange: this.props.onChange
28141
- }), /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement(PropCheckBox$9, {
28139
+ }), /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement(PropCheckBox$8, {
28142
28140
  label: "Allow iframe content to redirect the page",
28143
28141
  allowTopNavigation: this.props.allowTopNavigation,
28144
28142
  onChange: this.props.onChange
@@ -28157,13 +28155,13 @@ class IframeEditor extends React__namespace.Component {
28157
28155
 
28158
28156
  /* eslint-disable jsx-a11y/anchor-is-valid, react/sort-comp */
28159
28157
  const {
28160
- InfoTip: InfoTip$g,
28158
+ InfoTip: InfoTip$f,
28161
28159
  InlineIcon: InlineIcon$4,
28162
28160
  RangeInput: RangeInput$4
28163
28161
  } = perseus.components;
28164
28162
  const defaultBoxSize = 400;
28165
28163
  const defaultRange = [0, 10];
28166
- const defaultBackgroundImage$2 = {
28164
+ const defaultBackgroundImage$1 = {
28167
28165
  url: null,
28168
28166
  width: 0,
28169
28167
  height: 0
@@ -28180,39 +28178,31 @@ const INTERNALLY_HOSTED_URL_RE = new RegExp("^(https?|web\\+graphie)://[^/]*" +
28180
28178
  * Alignment option for captions, relative to specified coordinates.
28181
28179
  */
28182
28180
  const captionAlignments = ["center", "above", "above right", "right", "below right", "below", "below left", "left", "above left"];
28183
- const ImageEditor = createReactClass__default["default"]({
28184
- displayName: "ImageEditor",
28185
- propTypes: {
28186
- ...perseus.Changeable.propTypes
28187
- },
28188
- statics: {
28189
- widgetName: "image"
28190
- },
28191
- componentDidMount: function () {
28181
+ class ImageEditor extends React__namespace.Component {
28182
+ _isMounted = false;
28183
+ static displayName = "ImageEditor";
28184
+ static widgetName = "image";
28185
+ static defaultProps = {
28186
+ title: "",
28187
+ range: [defaultRange, defaultRange],
28188
+ box: [defaultBoxSize, defaultBoxSize],
28189
+ backgroundImage: defaultBackgroundImage$1,
28190
+ labels: [],
28191
+ alt: "",
28192
+ caption: ""
28193
+ };
28194
+ state = {
28195
+ backgroundImageError: ""
28196
+ };
28197
+ componentDidMount() {
28192
28198
  // TODO(scottgrant): This is a hack to remove the deprecated call to
28193
28199
  // this.isMounted() but is still considered an anti-pattern.
28194
28200
  this._isMounted = true;
28195
- },
28196
- componentWillUnmount: function () {
28201
+ }
28202
+ componentWillUnmount() {
28197
28203
  this._isMounted = false;
28198
- },
28199
- getDefaultProps: function () {
28200
- return {
28201
- title: "",
28202
- range: [defaultRange, defaultRange],
28203
- box: [defaultBoxSize, defaultBoxSize],
28204
- backgroundImage: defaultBackgroundImage$2,
28205
- labels: [],
28206
- alt: "",
28207
- caption: ""
28208
- };
28209
- },
28210
- getInitialState: function () {
28211
- return {
28212
- backgroundImageError: ""
28213
- };
28214
- },
28215
- render: function () {
28204
+ }
28205
+ render() {
28216
28206
  const backgroundImage = this.props.backgroundImage;
28217
28207
  const imageSettings = /*#__PURE__*/React__namespace.createElement("div", {
28218
28208
  className: "image-settings"
@@ -28222,7 +28212,7 @@ const ImageEditor = createReactClass__default["default"]({
28222
28212
  style: {
28223
28213
  width: "100%"
28224
28214
  }
28225
- }))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Dimensions:"), /*#__PURE__*/React__namespace.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Alt text:", /*#__PURE__*/React__namespace.createElement(InfoTip$g, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React__namespace.createElement(Editor, {
28215
+ }))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Dimensions:"), /*#__PURE__*/React__namespace.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Alt text:", /*#__PURE__*/React__namespace.createElement(InfoTip$f, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React__namespace.createElement(Editor, {
28226
28216
  apiOptions: this.props.apiOptions,
28227
28217
  content: this.props.alt,
28228
28218
  onChange: props => {
@@ -28246,15 +28236,15 @@ const ImageEditor = createReactClass__default["default"]({
28246
28236
  }, this.state.backgroundImageError);
28247
28237
  return /*#__PURE__*/React__namespace.createElement("div", {
28248
28238
  className: "perseus-image-editor"
28249
- }, /*#__PURE__*/React__namespace.createElement("label", null, "Image url:", /*#__PURE__*/React__namespace.createElement(InfoTip$g, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React__namespace.createElement(BlurInput, {
28239
+ }, /*#__PURE__*/React__namespace.createElement("label", null, "Image url:", /*#__PURE__*/React__namespace.createElement(InfoTip$f, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React__namespace.createElement(BlurInput, {
28250
28240
  value: backgroundImage.url || "",
28251
28241
  style: {
28252
28242
  width: 332
28253
28243
  },
28254
28244
  onChange: url => this.onUrlChange(url, false)
28255
28245
  })), backgroundImage.url && imageSettings);
28256
- },
28257
- _renderRowForLabel: function (label, i) {
28246
+ }
28247
+ _renderRowForLabel(label, i) {
28258
28248
  return /*#__PURE__*/React__namespace.createElement("tr", {
28259
28249
  key: i
28260
28250
  }, /*#__PURE__*/React__namespace.createElement("td", null, /*#__PURE__*/React__namespace.createElement(RangeInput$4, {
@@ -28293,22 +28283,22 @@ const ImageEditor = createReactClass__default["default"]({
28293
28283
  ,
28294
28284
  onClick: this.removeLabel.bind(this, i)
28295
28285
  }, /*#__PURE__*/React__namespace.createElement(InlineIcon$4, perseus.icons.iconTrash))));
28296
- },
28286
+ }
28297
28287
  change() {
28298
28288
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
28299
28289
  args[_key] = arguments[_key];
28300
28290
  }
28301
28291
  return perseus.Changeable.change.apply(this, args);
28302
- },
28303
- removeLabel: function (labelIndex, e) {
28292
+ }
28293
+ removeLabel(labelIndex, e) {
28304
28294
  e.preventDefault();
28305
- const labels = ___default["default"](this.props.labels).clone();
28295
+ const labels = [...this.props.labels];
28306
28296
  labels.splice(labelIndex, 1);
28307
28297
  this.props.onChange({
28308
28298
  labels: labels
28309
28299
  });
28310
- },
28311
- onCoordinateChange: function (labelIndex, newCoordinates) {
28300
+ }
28301
+ onCoordinateChange(labelIndex, newCoordinates) {
28312
28302
  const labels = this.props.labels.slice();
28313
28303
  labels[labelIndex] = ___default["default"].extend({}, labels[labelIndex], {
28314
28304
  coordinates: newCoordinates
@@ -28316,8 +28306,8 @@ const ImageEditor = createReactClass__default["default"]({
28316
28306
  this.props.onChange({
28317
28307
  labels: labels
28318
28308
  });
28319
- },
28320
- onContentChange: function (labelIndex, e) {
28309
+ }
28310
+ onContentChange(labelIndex, e) {
28321
28311
  const newContent = e.target.value;
28322
28312
  const labels = this.props.labels.slice();
28323
28313
  labels[labelIndex] = ___default["default"].extend({}, labels[labelIndex], {
@@ -28326,8 +28316,8 @@ const ImageEditor = createReactClass__default["default"]({
28326
28316
  this.props.onChange({
28327
28317
  labels: labels
28328
28318
  });
28329
- },
28330
- onAlignmentChange: function (labelIndex, e) {
28319
+ }
28320
+ onAlignmentChange(labelIndex, e) {
28331
28321
  const newAlignment = e.target.value;
28332
28322
  const labels = this.props.labels.slice();
28333
28323
  labels[labelIndex] = ___default["default"].extend({}, labels[labelIndex], {
@@ -28336,8 +28326,8 @@ const ImageEditor = createReactClass__default["default"]({
28336
28326
  this.props.onChange({
28337
28327
  labels: labels
28338
28328
  });
28339
- },
28340
- setUrl: function (url, width, height, silent) {
28329
+ }
28330
+ setUrl(url, width, height, silent) {
28341
28331
  // Because this calls into WidgetEditor._handleWidgetChange, which
28342
28332
  // checks for this widget's ref to serialize it.
28343
28333
  //
@@ -28355,11 +28345,12 @@ const ImageEditor = createReactClass__default["default"]({
28355
28345
  backgroundImage: image,
28356
28346
  box: box
28357
28347
  }, null, silent);
28358
- },
28348
+ }
28349
+
28359
28350
  // silently load the image when the component mounts
28360
28351
  // silently update url and sizes when the image loads
28361
28352
  // noisily load the image in response to the author changing it
28362
- onUrlChange: async function (url, silent) {
28353
+ async onUrlChange(url, silent) {
28363
28354
  // Check if we've been passed something that looks like a URL
28364
28355
  if (!url) {
28365
28356
  this.setUrl(url, 0, 0, silent);
@@ -28386,22 +28377,22 @@ const ImageEditor = createReactClass__default["default"]({
28386
28377
  backgroundImageError: `There was an error loading the image URL: ${JSON.stringify(error, null, 2)}`
28387
28378
  });
28388
28379
  }
28389
- },
28390
- onRangeChange: function (type, newRange) {
28380
+ }
28381
+ onRangeChange(type, newRange) {
28391
28382
  const range = this.props.range.slice();
28392
28383
  range[type] = newRange;
28393
28384
  this.props.onChange({
28394
28385
  range: range
28395
28386
  });
28396
- },
28387
+ }
28397
28388
  serialize() {
28398
28389
  return perseus.EditorJsonify.serialize.call(this);
28399
28390
  }
28400
- });
28391
+ }
28401
28392
 
28402
28393
  /* eslint-disable react/sort-comp */
28403
28394
  const {
28404
- InfoTip: InfoTip$f
28395
+ InfoTip: InfoTip$e
28405
28396
  } = perseus.components;
28406
28397
  const answerTypes = {
28407
28398
  number: {
@@ -28480,7 +28471,7 @@ class InputNumberEditor extends React__namespace.Component {
28480
28471
  value: "optional"
28481
28472
  }, "will be accepted"), /*#__PURE__*/React__namespace.createElement("option", {
28482
28473
  value: "enforced"
28483
- }, "will be marked wrong"))), /*#__PURE__*/React__namespace.createElement(InfoTip$f, null, /*#__PURE__*/React__namespace.createElement("p", null, "Normally select \"will not be graded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and anything after)"), /*#__PURE__*/React__namespace.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React__namespace.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("input", {
28474
+ }, "will be marked wrong"))), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("p", null, "Normally select \"will not be graded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and anything after)"), /*#__PURE__*/React__namespace.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React__namespace.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("input", {
28484
28475
  type: "checkbox",
28485
28476
  checked: this.props.inexact,
28486
28477
  onChange: e => {
@@ -28516,7 +28507,7 @@ class InputNumberEditor extends React__namespace.Component {
28516
28507
  });
28517
28508
  },
28518
28509
  "aria-label": "Answer type"
28519
- }, answerTypeOptions), /*#__PURE__*/React__namespace.createElement(InfoTip$f, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Width", " ", /*#__PURE__*/React__namespace.createElement("select", {
28510
+ }, answerTypeOptions), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Width", " ", /*#__PURE__*/React__namespace.createElement("select", {
28520
28511
  value: this.props.size,
28521
28512
  onChange: e => {
28522
28513
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type '"small" | "normal" | undefined'.
@@ -28528,7 +28519,7 @@ class InputNumberEditor extends React__namespace.Component {
28528
28519
  value: "normal"
28529
28520
  }, "Normal (80px)"), /*#__PURE__*/React__namespace.createElement("option", {
28530
28521
  value: "small"
28531
- }, "Small (40px)"))), /*#__PURE__*/React__namespace.createElement(InfoTip$f, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("input", {
28522
+ }, "Small (40px)"))), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("input", {
28532
28523
  type: "checkbox",
28533
28524
  checked: this.props.rightAlign,
28534
28525
  onChange: e => {
@@ -29741,7 +29732,7 @@ const SegmentCountSelector = _ref => {
29741
29732
  };
29742
29733
 
29743
29734
  const {
29744
- InfoTip: InfoTip$e
29735
+ InfoTip: InfoTip$d
29745
29736
  } = perseus.components;
29746
29737
  const {
29747
29738
  containerSizeClass,
@@ -29749,7 +29740,7 @@ const {
29749
29740
  } = perseus.SizingUtils;
29750
29741
  const DeprecationMixin = perseus.Util.DeprecationMixin;
29751
29742
  const InteractiveGraph = perseus.InteractiveGraphWidget.widget;
29752
- const defaultBackgroundImage$1 = {
29743
+ const defaultBackgroundImage = {
29753
29744
  url: null
29754
29745
  };
29755
29746
  const deprecatedProps = {
@@ -29788,7 +29779,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
29788
29779
  static defaultProps = {
29789
29780
  ...InteractiveGraph.defaultProps,
29790
29781
  valid: true,
29791
- backgroundImage: defaultBackgroundImage$1,
29782
+ backgroundImage: defaultBackgroundImage,
29792
29783
  showTooltips: false,
29793
29784
  correct: {
29794
29785
  type: InteractiveGraph.defaultProps.graph.type,
@@ -29928,7 +29919,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
29928
29919
  value: "angles"
29929
29920
  }, "interior angles"), /*#__PURE__*/React__namespace.createElement("option", {
29930
29921
  value: "sides"
29931
- }, "side measures"))), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("p", null, "These options affect the movement of the vertex points. The grid option will guide the points to the nearest half step along the grid."), /*#__PURE__*/React__namespace.createElement("p", null, "The interior angle and side measure options guide the points to the nearest whole angle or side"), " ", "measure respectively.")), /*#__PURE__*/React__namespace.createElement(Row, null, /*#__PURE__*/React__namespace.createElement(Typography__namespace.LabelSmall, {
29922
+ }, "side measures"))), /*#__PURE__*/React__namespace.createElement(InfoTip$d, null, /*#__PURE__*/React__namespace.createElement("p", null, "These options affect the movement of the vertex points. The grid option will guide the points to the nearest half step along the grid."), /*#__PURE__*/React__namespace.createElement("p", null, "The interior angle and side measure options guide the points to the nearest whole angle or side"), " ", "measure respectively.")), /*#__PURE__*/React__namespace.createElement(Row, null, /*#__PURE__*/React__namespace.createElement(Typography__namespace.LabelSmall, {
29932
29923
  tag: "label"
29933
29924
  }, "Show angle measures:", " ", /*#__PURE__*/React__namespace.createElement("input", {
29934
29925
  type: "checkbox",
@@ -29941,7 +29932,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
29941
29932
  }
29942
29933
  });
29943
29934
  }
29944
- })), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("p", null, "Displays the interior angle measures."))), /*#__PURE__*/React__namespace.createElement(Row, null, /*#__PURE__*/React__namespace.createElement(Typography__namespace.LabelSmall, {
29935
+ })), /*#__PURE__*/React__namespace.createElement(InfoTip$d, null, /*#__PURE__*/React__namespace.createElement("p", null, "Displays the interior angle measures."))), /*#__PURE__*/React__namespace.createElement(Row, null, /*#__PURE__*/React__namespace.createElement(Typography__namespace.LabelSmall, {
29945
29936
  tag: "label"
29946
29937
  }, "Show side measures:", " ", /*#__PURE__*/React__namespace.createElement("input", {
29947
29938
  type: "checkbox",
@@ -29954,7 +29945,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
29954
29945
  }
29955
29946
  });
29956
29947
  }
29957
- })), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("p", null, "Displays the side lengths.")))), this.props.correct?.type === "segment" && /*#__PURE__*/React__namespace.createElement(Row, null, /*#__PURE__*/React__namespace.createElement(FieldLabel, null, "Number of segments: "), /*#__PURE__*/React__namespace.createElement(SegmentCountSelector, {
29948
+ })), /*#__PURE__*/React__namespace.createElement(InfoTip$d, null, /*#__PURE__*/React__namespace.createElement("p", null, "Displays the side lengths.")))), this.props.correct?.type === "segment" && /*#__PURE__*/React__namespace.createElement(Row, null, /*#__PURE__*/React__namespace.createElement(FieldLabel, null, "Number of segments: "), /*#__PURE__*/React__namespace.createElement(SegmentCountSelector, {
29958
29949
  numSegments: this.props.correct?.numSegments,
29959
29950
  onChange: sides => {
29960
29951
  this.props.onChange({
@@ -29974,7 +29965,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
29974
29965
  borderStyle: "solid",
29975
29966
  borderWidth: 1
29976
29967
  }
29977
- }, equationString), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), /*#__PURE__*/React__namespace.createElement(GraphSettings, {
29968
+ }, equationString), /*#__PURE__*/React__namespace.createElement(InfoTip$d, null, /*#__PURE__*/React__namespace.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), /*#__PURE__*/React__namespace.createElement(GraphSettings, {
29978
29969
  box: getInteractiveBoxFromSizeClass(sizeClass),
29979
29970
  range: this.props.range,
29980
29971
  labels: this.props.labels,
@@ -30003,7 +29994,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
30003
29994
  value: "approx"
30004
29995
  }, "be approximately congruent"), /*#__PURE__*/React__namespace.createElement("option", {
30005
29996
  value: "similar"
30006
- }, "be similar"))), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("ul", null, /*#__PURE__*/React__namespace.createElement("li", null, /*#__PURE__*/React__namespace.createElement("p", null, /*#__PURE__*/React__namespace.createElement("b", null, "Match Exactly:"), " Match exactly in size, orientation, and location on the grid even if it is not shown in the background.")), /*#__PURE__*/React__namespace.createElement("li", null, /*#__PURE__*/React__namespace.createElement("p", null, /*#__PURE__*/React__namespace.createElement("b", null, "Be Congruent:"), " Be congruent in size and shape, but can be located anywhere on the grid.")), /*#__PURE__*/React__namespace.createElement("li", null, /*#__PURE__*/React__namespace.createElement("p", null, /*#__PURE__*/React__namespace.createElement("b", null, "Be Approximately Congruent:"), " Be exactly similar, and congruent in size and shape to within 0.1 units, but can be located anywhere on the grid.", " ", /*#__PURE__*/React__namespace.createElement("em", null, "Use this with snapping to angle measure."))), /*#__PURE__*/React__namespace.createElement("li", null, /*#__PURE__*/React__namespace.createElement("p", null, /*#__PURE__*/React__namespace.createElement("b", null, "Be Similar:"), " Be similar with matching interior angles, and side measures that are matching or a multiple of the correct side measures. The figure can be located anywhere on the grid."))))), this.props.correct.type === "angle" && /*#__PURE__*/React__namespace.createElement("div", {
29997
+ }, "be similar"))), /*#__PURE__*/React__namespace.createElement(InfoTip$d, null, /*#__PURE__*/React__namespace.createElement("ul", null, /*#__PURE__*/React__namespace.createElement("li", null, /*#__PURE__*/React__namespace.createElement("p", null, /*#__PURE__*/React__namespace.createElement("b", null, "Match Exactly:"), " Match exactly in size, orientation, and location on the grid even if it is not shown in the background.")), /*#__PURE__*/React__namespace.createElement("li", null, /*#__PURE__*/React__namespace.createElement("p", null, /*#__PURE__*/React__namespace.createElement("b", null, "Be Congruent:"), " Be congruent in size and shape, but can be located anywhere on the grid.")), /*#__PURE__*/React__namespace.createElement("li", null, /*#__PURE__*/React__namespace.createElement("p", null, /*#__PURE__*/React__namespace.createElement("b", null, "Be Approximately Congruent:"), " Be exactly similar, and congruent in size and shape to within 0.1 units, but can be located anywhere on the grid.", " ", /*#__PURE__*/React__namespace.createElement("em", null, "Use this with snapping to angle measure."))), /*#__PURE__*/React__namespace.createElement("li", null, /*#__PURE__*/React__namespace.createElement("p", null, /*#__PURE__*/React__namespace.createElement("b", null, "Be Similar:"), " Be similar with matching interior angles, and side measures that are matching or a multiple of the correct side measures. The figure can be located anywhere on the grid."))))), this.props.correct.type === "angle" && /*#__PURE__*/React__namespace.createElement("div", {
30007
29998
  className: "type-settings"
30008
29999
  }, /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, " ", "Student answer must", " ", /*#__PURE__*/React__namespace.createElement("select", {
30009
30000
  value: this.props.correct.match,
@@ -30012,7 +30003,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
30012
30003
  value: "exact"
30013
30004
  }, "match exactly"), /*#__PURE__*/React__namespace.createElement("option", {
30014
30005
  value: "congruent"
30015
- }, "be congruent"))), /*#__PURE__*/React__namespace.createElement(InfoTip$e, null, /*#__PURE__*/React__namespace.createElement("p", null, "Congruency requires only that the angle measures are the same. An exact match implies congruency, but also requires that the angles have the same orientation and that the vertices are in the same position.")))), graph);
30006
+ }, "be congruent"))), /*#__PURE__*/React__namespace.createElement(InfoTip$d, null, /*#__PURE__*/React__namespace.createElement("p", null, "Congruency requires only that the angle measures are the same. An exact match implies congruency, but also requires that the angles have the same orientation and that the vertices are in the same position.")))), graph);
30016
30007
  }
30017
30008
  changeMatchType(e) {
30018
30009
  const correct = ___default["default"].extend({}, this.props.correct, {
@@ -31575,9 +31566,9 @@ const styles = aphrodite.StyleSheet.create({
31575
31566
 
31576
31567
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
31577
31568
  const {
31578
- InfoTip: InfoTip$d,
31569
+ InfoTip: InfoTip$c,
31579
31570
  NumberInput: NumberInput$a,
31580
- PropCheckBox: PropCheckBox$8
31571
+ PropCheckBox: PropCheckBox$7
31581
31572
  } = perseus.components;
31582
31573
  const MAX_SIZE = 8;
31583
31574
 
@@ -31726,10 +31717,10 @@ class LightsPuzzleEditor extends React__namespace.Component {
31726
31717
  value: pattern,
31727
31718
  key: i
31728
31719
  }, pattern);
31729
- }))), /*#__PURE__*/React__namespace.createElement("div", null, "Grade incomplete puzzles as wrong:", " ", /*#__PURE__*/React__namespace.createElement(PropCheckBox$8, {
31720
+ }))), /*#__PURE__*/React__namespace.createElement("div", null, "Grade incomplete puzzles as wrong:", " ", /*#__PURE__*/React__namespace.createElement(PropCheckBox$7, {
31730
31721
  gradeIncompleteAsWrong: this.props.gradeIncompleteAsWrong,
31731
31722
  onChange: this.props.onChange
31732
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$d, null, "By default, incomplete puzzles are graded as empty.")), /*#__PURE__*/React__namespace.createElement("div", null, "Starting configuration:"), /*#__PURE__*/React__namespace.createElement("div", {
31723
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$c, null, "By default, incomplete puzzles are graded as empty.")), /*#__PURE__*/React__namespace.createElement("div", null, "Starting configuration:"), /*#__PURE__*/React__namespace.createElement("div", {
31733
31724
  style: {
31734
31725
  overflowX: "auto"
31735
31726
  }
@@ -31781,8 +31772,8 @@ class LightsPuzzleEditor extends React__namespace.Component {
31781
31772
 
31782
31773
  /* eslint-disable react/forbid-prop-types, react/sort-comp */
31783
31774
  const {
31784
- InfoTip: InfoTip$c,
31785
- PropCheckBox: PropCheckBox$7,
31775
+ InfoTip: InfoTip$b,
31776
+ PropCheckBox: PropCheckBox$6,
31786
31777
  TextListEditor: TextListEditor$3
31787
31778
  } = perseus.components;
31788
31779
  class MatcherEditor extends React__namespace.Component {
@@ -31804,7 +31795,7 @@ class MatcherEditor extends React__namespace.Component {
31804
31795
  render() {
31805
31796
  return /*#__PURE__*/React__namespace.createElement("div", {
31806
31797
  className: "perseus-matcher-editor"
31807
- }, /*#__PURE__*/React__namespace.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$c, null, /*#__PURE__*/React__namespace.createElement("p", null, "Enter the correct answers here. The preview on the right will show the cards in a randomized order, which is how the student will see them."))), /*#__PURE__*/React__namespace.createElement("div", {
31798
+ }, /*#__PURE__*/React__namespace.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$b, null, /*#__PURE__*/React__namespace.createElement("p", null, "Enter the correct answers here. The preview on the right will show the cards in a randomized order, which is how the student will see them."))), /*#__PURE__*/React__namespace.createElement("div", {
31808
31799
  className: "perseus-clearfix"
31809
31800
  }, /*#__PURE__*/React__namespace.createElement(TextListEditor$3, {
31810
31801
  options: this.props.left,
@@ -31822,7 +31813,7 @@ class MatcherEditor extends React__namespace.Component {
31822
31813
  }, cb);
31823
31814
  },
31824
31815
  layout: "vertical"
31825
- })), /*#__PURE__*/React__namespace.createElement("span", null, " ", "Labels:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$c, null, /*#__PURE__*/React__namespace.createElement("p", null, "These are entirely optional."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("input", {
31816
+ })), /*#__PURE__*/React__namespace.createElement("span", null, " ", "Labels:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$b, null, /*#__PURE__*/React__namespace.createElement("p", null, "These are entirely optional."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("input", {
31826
31817
  type: "text",
31827
31818
  defaultValue: this.props.labels[0]
31828
31819
  // eslint-disable-next-line react/jsx-no-bind
@@ -31834,15 +31825,15 @@ class MatcherEditor extends React__namespace.Component {
31834
31825
  // eslint-disable-next-line react/jsx-no-bind
31835
31826
  ,
31836
31827
  onChange: this.onLabelChange.bind(this, 1)
31837
- })), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(PropCheckBox$7, {
31828
+ })), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(PropCheckBox$6, {
31838
31829
  label: "Order of the matched pairs matters:",
31839
31830
  orderMatters: this.props.orderMatters,
31840
31831
  onChange: this.props.onChange
31841
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$c, null, /*#__PURE__*/React__namespace.createElement("p", null, "With this option enabled, only the order provided above will be treated as correct. This is useful when ordering is significant, such as in the context of a proof."), /*#__PURE__*/React__namespace.createElement("p", null, "If disabled, pairwise matching is sufficient. To make this clear, the left column becomes fixed in the provided order and only the cards in the right column can be moved."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(PropCheckBox$7, {
31832
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$b, null, /*#__PURE__*/React__namespace.createElement("p", null, "With this option enabled, only the order provided above will be treated as correct. This is useful when ordering is significant, such as in the context of a proof."), /*#__PURE__*/React__namespace.createElement("p", null, "If disabled, pairwise matching is sufficient. To make this clear, the left column becomes fixed in the provided order and only the cards in the right column can be moved."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(PropCheckBox$6, {
31842
31833
  label: "Padding:",
31843
31834
  padding: this.props.padding,
31844
31835
  onChange: this.props.onChange
31845
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$c, null, /*#__PURE__*/React__namespace.createElement("p", null, "Padding is good for text, but not needed for images."))));
31836
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$b, null, /*#__PURE__*/React__namespace.createElement("p", null, "Padding is good for text, but not needed for images."))));
31846
31837
  }
31847
31838
  onLabelChange = (index, e) => {
31848
31839
  const labels = ___default["default"].clone(this.props.labels);
@@ -31992,9 +31983,9 @@ class MatrixEditor extends React__namespace.Component {
31992
31983
 
31993
31984
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
31994
31985
  const {
31995
- InfoTip: InfoTip$b,
31986
+ InfoTip: InfoTip$a,
31996
31987
  NumberInput: NumberInput$9,
31997
- PropCheckBox: PropCheckBox$6,
31988
+ PropCheckBox: PropCheckBox$5,
31998
31989
  RangeInput: RangeInput$2
31999
31990
  } = perseus.components;
32000
31991
  const defaultImage = {
@@ -32042,7 +32033,7 @@ class MeasurerEditor extends React__namespace.Component {
32042
32033
  ref: "image-url",
32043
32034
  defaultValue: image.url,
32044
32035
  onChange: this._changeUrl
32045
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$b, null, /*#__PURE__*/React__namespace.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), image.url && /*#__PURE__*/React__namespace.createElement("div", {
32036
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$a, null, /*#__PURE__*/React__namespace.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), image.url && /*#__PURE__*/React__namespace.createElement("div", {
32046
32037
  className: "perseus-widget-row"
32047
32038
  }, /*#__PURE__*/React__namespace.createElement("label", {
32048
32039
  className: "perseus-widget-left-col"
@@ -32068,13 +32059,13 @@ class MeasurerEditor extends React__namespace.Component {
32068
32059
  className: "perseus-widget-row"
32069
32060
  }, /*#__PURE__*/React__namespace.createElement("div", {
32070
32061
  className: "perseus-widget-left-col"
32071
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$6, {
32062
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$5, {
32072
32063
  label: "Show ruler",
32073
32064
  showRuler: this.props.showRuler,
32074
32065
  onChange: this.props.onChange
32075
32066
  })), /*#__PURE__*/React__namespace.createElement("div", {
32076
32067
  className: "perseus-widget-right-col"
32077
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$6, {
32068
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$5, {
32078
32069
  label: "Show protractor",
32079
32070
  showProtractor: this.props.showProtractor,
32080
32071
  onChange: this.props.onChange
@@ -32202,9 +32193,9 @@ class MoleculeWidgetEditor extends React__namespace.Component {
32202
32193
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
32203
32194
  const {
32204
32195
  ButtonGroup: ButtonGroup$1,
32205
- InfoTip: InfoTip$a,
32196
+ InfoTip: InfoTip$9,
32206
32197
  NumberInput: NumberInput$7,
32207
- PropCheckBox: PropCheckBox$5,
32198
+ PropCheckBox: PropCheckBox$4,
32208
32199
  RangeInput: RangeInput$1
32209
32200
  } = perseus.components;
32210
32201
  const bound = (x, gt, lt) => Math.min(Math.max(x, gt), lt);
@@ -32393,7 +32384,7 @@ class NumberLineEditor extends React__namespace.Component {
32393
32384
  placeholder: "answer",
32394
32385
  size: "normal",
32395
32386
  useArrowKeys: true
32396
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$a, null, /*#__PURE__*/React__namespace.createElement("p", null, "This is the correct answer. The answer is validated (as right or wrong) by using only the end position of the point and the relation (=, <, >, \u2264, \u2265)."))), /*#__PURE__*/React__namespace.createElement("div", {
32387
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "This is the correct answer. The answer is validated (as right or wrong) by using only the end position of the point and the relation (=, <, >, \u2264, \u2265)."))), /*#__PURE__*/React__namespace.createElement("div", {
32397
32388
  className: "perseus-widget-row"
32398
32389
  }, this.props.static ? /*#__PURE__*/React__namespace.createElement("label", null, "Range:") : /*#__PURE__*/React__namespace.createElement("label", null, "Position:", " ", /*#__PURE__*/React__namespace.createElement(NumberInput$7, {
32399
32390
  value: this.props.initialX,
@@ -32411,7 +32402,7 @@ class NumberLineEditor extends React__namespace.Component {
32411
32402
  onChange: this.onRangeChange,
32412
32403
  format: this.props.labelStyle,
32413
32404
  useArrowKeys: true
32414
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$a, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the initial position of the point along the number line and the", /*#__PURE__*/React__namespace.createElement("strong", null, "range"), ", the position of the endpoints of the number line. Setting the range constrains the position of the answer and the labels."), /*#__PURE__*/React__namespace.createElement("p", null, "In static mode, the initial position of the point is determined by Correct x instead of position."))), /*#__PURE__*/React__namespace.createElement("div", {
32405
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the initial position of the point along the number line and the", /*#__PURE__*/React__namespace.createElement("strong", null, "range"), ", the position of the endpoints of the number line. Setting the range constrains the position of the answer and the labels."), /*#__PURE__*/React__namespace.createElement("p", null, "In static mode, the initial position of the point is determined by Correct x instead of position."))), /*#__PURE__*/React__namespace.createElement("div", {
32415
32406
  className: "perseus-widget-row"
32416
32407
  }, /*#__PURE__*/React__namespace.createElement("div", {
32417
32408
  className: "perseus-widget-left-col"
@@ -32433,30 +32424,30 @@ class NumberLineEditor extends React__namespace.Component {
32433
32424
  ,
32434
32425
  onChange: this.onLabelRangeChange.bind(this, 1),
32435
32426
  useArrowKeys: true
32436
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$a, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the position of the left / right labels. By default, the labels are set by the range ", /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement("strong", null, "Note:"), " Ensure that the labels line up with the tick marks, or it may be confusing for users.")))), /*#__PURE__*/React__namespace.createElement("div", {
32427
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the position of the left / right labels. By default, the labels are set by the range ", /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement("strong", null, "Note:"), " Ensure that the labels line up with the tick marks, or it may be confusing for users.")))), /*#__PURE__*/React__namespace.createElement("div", {
32437
32428
  className: "perseus-widget-row"
32438
32429
  }, "Style:", " ", /*#__PURE__*/React__namespace.createElement(ButtonGroup$1, {
32439
32430
  allowEmpty: false,
32440
32431
  value: this.props.labelStyle,
32441
32432
  buttons: labelStyleEditorButtons,
32442
32433
  onChange: this.onLabelStyleChange
32443
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$a, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the styling of the labels for the two main labels as well as all the tick mark labels, if applicable. Your choices are decimal, improper fractions, mixed fractions, and non-reduced fractions."))), /*#__PURE__*/React__namespace.createElement("div", {
32434
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the styling of the labels for the two main labels as well as all the tick mark labels, if applicable. Your choices are decimal, improper fractions, mixed fractions, and non-reduced fractions."))), /*#__PURE__*/React__namespace.createElement("div", {
32444
32435
  className: "perseus-widget-row"
32445
32436
  }, !this.props.static && /*#__PURE__*/React__namespace.createElement("div", {
32446
32437
  className: "perseus-widget-left-col"
32447
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$5, {
32438
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$4, {
32448
32439
  label: "Show tick controller",
32449
32440
  isTickCtrl: this.props.isTickCtrl,
32450
32441
  onChange: this.props.onChange
32451
32442
  })), /*#__PURE__*/React__namespace.createElement("div", {
32452
32443
  className: "perseus-widget-right-col"
32453
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$5, {
32444
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$4, {
32454
32445
  label: "Show label ticks",
32455
32446
  labelTicks: this.props.labelTicks,
32456
32447
  onChange: this.props.onChange
32457
32448
  }))), /*#__PURE__*/React__namespace.createElement("div", {
32458
32449
  className: "perseus-widget-row"
32459
- }, !this.props.static && /*#__PURE__*/React__namespace.createElement(PropCheckBox$5, {
32450
+ }, !this.props.static && /*#__PURE__*/React__namespace.createElement(PropCheckBox$4, {
32460
32451
  label: "Show tooltips",
32461
32452
  showTooltips: this.props.showTooltips,
32462
32453
  onChange: this.props.onChange
@@ -32471,7 +32462,7 @@ class NumberLineEditor extends React__namespace.Component {
32471
32462
  },
32472
32463
  placeholder: width / this.props.tickStep,
32473
32464
  useArrowKeys: true
32474
- })), /*#__PURE__*/React__namespace.createElement(InfoTip$a, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the number (and position) of the tick marks. The number of divisions is constrained to", " " + divisionRange[0] + EN_DASH + divisionRange[1], ".", /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement("strong", null, "Note:"), " The user will be able to specify the number of divisions in a number input."))), !isTickCtrl && /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement("label", null, "Num divisions:", " ", /*#__PURE__*/React__namespace.createElement(NumberInput$7, {
32465
+ })), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the number (and position) of the tick marks. The number of divisions is constrained to", " " + divisionRange[0] + EN_DASH + divisionRange[1], ".", /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement("strong", null, "Note:"), " The user will be able to specify the number of divisions in a number input."))), !isTickCtrl && /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement("label", null, "Num divisions:", " ", /*#__PURE__*/React__namespace.createElement(NumberInput$7, {
32475
32466
  value: this.props.numDivisions || null,
32476
32467
  format: "decimal",
32477
32468
  onChange: this.onNumDivisionsChange,
@@ -32489,7 +32480,7 @@ class NumberLineEditor extends React__namespace.Component {
32489
32480
  },
32490
32481
  placeholder: width / this.props.numDivisions,
32491
32482
  useArrowKeys: true
32492
- })), /*#__PURE__*/React__namespace.createElement(InfoTip$a, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the number (and position) of the tick marks; you can either set the number of divisions (2 divisions would split the entire range in two halves), or the tick step (the distance between ticks) and the other value will be updated accordingly.", " ", /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement("strong", null, "Note:"), " There is no check to see if labels coordinate with the tick marks, which may be confusing for users if the blue labels and black ticks are off-step.")))), /*#__PURE__*/React__namespace.createElement("div", {
32483
+ })), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the number (and position) of the tick marks; you can either set the number of divisions (2 divisions would split the entire range in two halves), or the tick step (the distance between ticks) and the other value will be updated accordingly.", " ", /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement("strong", null, "Note:"), " There is no check to see if labels coordinate with the tick marks, which may be confusing for users if the blue labels and black ticks are off-step.")))), /*#__PURE__*/React__namespace.createElement("div", {
32493
32484
  className: "perseus-widget-row"
32494
32485
  }, /*#__PURE__*/React__namespace.createElement("label", null, "Snap increments per tick:", " ", /*#__PURE__*/React__namespace.createElement(NumberInput$7, {
32495
32486
  value: snapDivisions,
@@ -32499,18 +32490,18 @@ class NumberLineEditor extends React__namespace.Component {
32499
32490
  ,
32500
32491
  onChange: this.onNumChange.bind(this, "snapDivisions"),
32501
32492
  useArrowKeys: true
32502
- })), /*#__PURE__*/React__namespace.createElement(InfoTip$a, null, /*#__PURE__*/React__namespace.createElement("p", null, "This determines the number of different places the point will snap between two adjacent tick marks.", " ", /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement("strong", null, "Note:"), "Ensure the required number of snap increments is provided to answer the question."))));
32493
+ })), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "This determines the number of different places the point will snap between two adjacent tick marks.", " ", /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement("strong", null, "Note:"), "Ensure the required number of snap increments is provided to answer the question."))));
32503
32494
  }
32504
32495
  }
32505
32496
 
32506
32497
  /* eslint-disable jsx-a11y/anchor-is-valid, react/sort-comp */
32507
32498
  const {
32508
32499
  ButtonGroup,
32509
- InfoTip: InfoTip$9,
32500
+ InfoTip: InfoTip$8,
32510
32501
  InlineIcon: InlineIcon$3,
32511
32502
  MultiButtonGroup,
32512
32503
  NumberInput: NumberInput$6,
32513
- PropCheckBox: PropCheckBox$4,
32504
+ PropCheckBox: PropCheckBox$3,
32514
32505
  TextInput: TextInput$3
32515
32506
  } = perseus.components;
32516
32507
  const {
@@ -32597,16 +32588,16 @@ const NumericInputEditor = createReactClass__default["default"]({
32597
32588
  content: "wrong"
32598
32589
  }],
32599
32590
  onChange: this.updateAnswer(i, "simplify")
32600
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "Normally select \"ungraded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and after)"), /*#__PURE__*/React__namespace.createElement("p", null, "Select \"accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React__namespace.createElement("p", null, "Select \"wrong\" ", /*#__PURE__*/React__namespace.createElement("em", null, "only"), " if we are specifically assessing the ability to simplify.")));
32591
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$8, null, /*#__PURE__*/React__namespace.createElement("p", null, "Normally select \"ungraded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and after)"), /*#__PURE__*/React__namespace.createElement("p", null, "Select \"accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React__namespace.createElement("p", null, "Select \"wrong\" ", /*#__PURE__*/React__namespace.createElement("em", null, "only"), " if we are specifically assessing the ability to simplify.")));
32601
32592
  const suggestedAnswerTypes = i => /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", {
32602
32593
  className: "perseus-widget-row"
32603
32594
  }, /*#__PURE__*/React__namespace.createElement("label", null, "Choose the suggested answer formats"), /*#__PURE__*/React__namespace.createElement(MultiButtonGroup, {
32604
32595
  buttons: answerFormButtons,
32605
32596
  values: answers[i]["answerForms"],
32606
32597
  onChange: this.updateAnswer(i, "answerForms")
32607
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "Formats will be autoselected for you based on the given answer; to show no suggested formats and accept all types, simply have a decimal/integer be the answer. Values with \u03C0 will have format \"pi\", and values that are fractions will have some subset (mixed will be \"mixed\" and \"proper\"; improper/proper will both be \"improper\" and \"proper\"). If you would like to specify that it is only a proper fraction (or only a mixed/improper fraction), deselect the other format. Except for specific cases, you should not need to change the autoselected formats."), /*#__PURE__*/React__namespace.createElement("p", null, "To restrict the answer to ", /*#__PURE__*/React__namespace.createElement("em", null, "only"), " an improper fraction (i.e. 7/4), select the improper fraction and toggle \"strict\" to true. This ", /*#__PURE__*/React__namespace.createElement("b", null, "will not"), " ", "accept 1.75 as an answer.", " "), /*#__PURE__*/React__namespace.createElement("p", null, "Unless you are testing that specific skill, please do not restrict the answer format."))), /*#__PURE__*/React__namespace.createElement("div", {
32598
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$8, null, /*#__PURE__*/React__namespace.createElement("p", null, "Formats will be autoselected for you based on the given answer; to show no suggested formats and accept all types, simply have a decimal/integer be the answer. Values with \u03C0 will have format \"pi\", and values that are fractions will have some subset (mixed will be \"mixed\" and \"proper\"; improper/proper will both be \"improper\" and \"proper\"). If you would like to specify that it is only a proper fraction (or only a mixed/improper fraction), deselect the other format. Except for specific cases, you should not need to change the autoselected formats."), /*#__PURE__*/React__namespace.createElement("p", null, "To restrict the answer to ", /*#__PURE__*/React__namespace.createElement("em", null, "only"), " an improper fraction (i.e. 7/4), select the improper fraction and toggle \"strict\" to true. This ", /*#__PURE__*/React__namespace.createElement("b", null, "will not"), " ", "accept 1.75 as an answer.", " "), /*#__PURE__*/React__namespace.createElement("p", null, "Unless you are testing that specific skill, please do not restrict the answer format."))), /*#__PURE__*/React__namespace.createElement("div", {
32608
32599
  className: "perseus-widget-row"
32609
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$4, {
32600
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$3, {
32610
32601
  label: "Strictly match only these formats",
32611
32602
  strict: answers[i]["strict"]
32612
32603
  // eslint-disable-next-line react/jsx-no-bind
@@ -32634,10 +32625,10 @@ const NumericInputEditor = createReactClass__default["default"]({
32634
32625
  content: "Small (40px)"
32635
32626
  }],
32636
32627
  onChange: this.change("size")
32637
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them.")));
32628
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$8, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them.")));
32638
32629
  const rightAlign = /*#__PURE__*/React__namespace.createElement("div", {
32639
32630
  className: "perseus-widget-row"
32640
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$4, {
32631
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$3, {
32641
32632
  label: "Right alignment",
32642
32633
  rightAlign: this.props.rightAlign,
32643
32634
  onChange: this.props.onChange
@@ -32647,14 +32638,14 @@ const NumericInputEditor = createReactClass__default["default"]({
32647
32638
  }, /*#__PURE__*/React__namespace.createElement("label", null, "Label text:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$3, {
32648
32639
  value: this.props.labelText,
32649
32640
  onChange: this.change("labelText")
32650
- })), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "Text to describe this input. This will be shown to users using screenreaders.")));
32641
+ })), /*#__PURE__*/React__namespace.createElement(InfoTip$8, null, /*#__PURE__*/React__namespace.createElement("p", null, "Text to describe this input. This will be shown to users using screenreaders.")));
32651
32642
  const coefficientCheck = /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", {
32652
32643
  className: "perseus-widget-row"
32653
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$4, {
32644
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$3, {
32654
32645
  label: "Coefficient",
32655
32646
  coefficient: this.props.coefficient,
32656
32647
  onChange: this.props.onChange
32657
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$9, null, /*#__PURE__*/React__namespace.createElement("p", null, "A coefficient style number allows the student to use - for -1 and an empty string to mean 1."))));
32648
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$8, null, /*#__PURE__*/React__namespace.createElement("p", null, "A coefficient style number allows the student to use - for -1 and an empty string to mean 1."))));
32658
32649
  const addAnswerButton = /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("a", {
32659
32650
  href: "javascript:void(0)",
32660
32651
  className: "simple-button orange",
@@ -32865,7 +32856,7 @@ const NumericInputEditor = createReactClass__default["default"]({
32865
32856
 
32866
32857
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
32867
32858
  const {
32868
- InfoTip: InfoTip$8,
32859
+ InfoTip: InfoTip$7,
32869
32860
  TextListEditor: TextListEditor$2
32870
32861
  } = perseus.components;
32871
32862
  const NORMAL = "normal",
@@ -32894,13 +32885,13 @@ class OrdererEditor extends React__namespace.Component {
32894
32885
  render() {
32895
32886
  return /*#__PURE__*/React__namespace.createElement("div", {
32896
32887
  className: "perseus-widget-orderer"
32897
- }, /*#__PURE__*/React__namespace.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$8, null, /*#__PURE__*/React__namespace.createElement("p", null, "Place the cards in the correct order. The same card can be used more than once in the answer but will only be displayed once at the top of a stack of identical cards."))), /*#__PURE__*/React__namespace.createElement(TextListEditor$2, {
32888
+ }, /*#__PURE__*/React__namespace.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$7, null, /*#__PURE__*/React__namespace.createElement("p", null, "Place the cards in the correct order. The same card can be used more than once in the answer but will only be displayed once at the top of a stack of identical cards."))), /*#__PURE__*/React__namespace.createElement(TextListEditor$2, {
32898
32889
  options: ___default["default"].pluck(this.props.correctOptions, "content")
32899
32890
  // eslint-disable-next-line react/jsx-no-bind
32900
32891
  ,
32901
32892
  onChange: this.onOptionsChange.bind(this, "correctOptions"),
32902
32893
  layout: this.props.layout
32903
- }), /*#__PURE__*/React__namespace.createElement("div", null, " ", "Other cards:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$8, null, /*#__PURE__*/React__namespace.createElement("p", null, "Create cards that are not part of the answer."))), /*#__PURE__*/React__namespace.createElement(TextListEditor$2, {
32894
+ }), /*#__PURE__*/React__namespace.createElement("div", null, " ", "Other cards:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$7, null, /*#__PURE__*/React__namespace.createElement("p", null, "Create cards that are not part of the answer."))), /*#__PURE__*/React__namespace.createElement(TextListEditor$2, {
32904
32895
  options: ___default["default"].pluck(this.props.otherOptions, "content")
32905
32896
  // eslint-disable-next-line react/jsx-no-bind
32906
32897
  ,
@@ -32915,7 +32906,7 @@ class OrdererEditor extends React__namespace.Component {
32915
32906
  value: HORIZONTAL$1
32916
32907
  }, "Horizontal"), /*#__PURE__*/React__namespace.createElement("option", {
32917
32908
  value: VERTICAL$1
32918
- }, "Vertical"))), /*#__PURE__*/React__namespace.createElement(InfoTip$8, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text (e.g. proofs)."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, " ", "Height:", " ", /*#__PURE__*/React__namespace.createElement("select", {
32909
+ }, "Vertical"))), /*#__PURE__*/React__namespace.createElement(InfoTip$7, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text (e.g. proofs)."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, " ", "Height:", " ", /*#__PURE__*/React__namespace.createElement("select", {
32919
32910
  value: this.props.height
32920
32911
  // @ts-expect-error - TS2322 - Type '(arg1: ChangeEvent<HTMLInputElement>) => void' is not assignable to type 'ChangeEventHandler<HTMLSelectElement>'.
32921
32912
  ,
@@ -32924,7 +32915,7 @@ class OrdererEditor extends React__namespace.Component {
32924
32915
  value: NORMAL
32925
32916
  }, "Normal"), /*#__PURE__*/React__namespace.createElement("option", {
32926
32917
  value: AUTO
32927
- }, "Automatic"))), /*#__PURE__*/React__namespace.createElement(InfoTip$8, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use \"Normal\" for text, \"Automatic\" for images."))));
32918
+ }, "Automatic"))), /*#__PURE__*/React__namespace.createElement(InfoTip$7, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use \"Normal\" for text, \"Automatic\" for images."))));
32928
32919
  }
32929
32920
  onOptionsChange = (whichOptions, options, cb) => {
32930
32921
  const props = {};
@@ -32975,8 +32966,8 @@ class OrdererEditor extends React__namespace.Component {
32975
32966
  }
32976
32967
 
32977
32968
  const {
32978
- InfoTip: InfoTip$7,
32979
- PropCheckBox: PropCheckBox$3
32969
+ InfoTip: InfoTip$6,
32970
+ PropCheckBox: PropCheckBox$2
32980
32971
  } = perseus.components;
32981
32972
  class PassageEditor extends React__namespace.Component {
32982
32973
  static propTypes = {
@@ -33041,12 +33032,12 @@ class PassageEditor extends React__namespace.Component {
33041
33032
  className: "perseus-widget-passage-editor"
33042
33033
  }, /*#__PURE__*/React__namespace.createElement("div", {
33043
33034
  className: "perseus-widget-row"
33044
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$3, {
33035
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$2, {
33045
33036
  label: "Show line numbers",
33046
33037
  labelAlignment: "right",
33047
33038
  showLineNumbers: this.props.showLineNumbers,
33048
33039
  onChange: this.props.onChange
33049
- })), /*#__PURE__*/React__namespace.createElement("div", null, "Passage title:", /*#__PURE__*/React__namespace.createElement(InfoTip$7, null, /*#__PURE__*/React__namespace.createElement("p", null, "An optional title that will appear directly above the passage in the same font style. (E.g. Passage 1)")), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("input", {
33040
+ })), /*#__PURE__*/React__namespace.createElement("div", null, "Passage title:", /*#__PURE__*/React__namespace.createElement(InfoTip$6, null, /*#__PURE__*/React__namespace.createElement("p", null, "An optional title that will appear directly above the passage in the same font style. (E.g. Passage 1)")), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("input", {
33050
33041
  type: "text",
33051
33042
  defaultValue: this.props.passageTitle,
33052
33043
  onChange: e => {
@@ -33055,13 +33046,13 @@ class PassageEditor extends React__namespace.Component {
33055
33046
  passageTitle: e.target.value
33056
33047
  });
33057
33048
  }
33058
- }))), /*#__PURE__*/React__namespace.createElement("div", null, "Passage Text:", passageEditor), /*#__PURE__*/React__namespace.createElement("div", null, "Footnotes:", /*#__PURE__*/React__namespace.createElement(InfoTip$7, null, /*#__PURE__*/React__namespace.createElement("p", null, "To add footnotes, add ^ characters where they belong in the passage. Then, add ^ in the footnotes area to reference the footnotes in the passage.")), footnotesEditor));
33049
+ }))), /*#__PURE__*/React__namespace.createElement("div", null, "Passage Text:", passageEditor), /*#__PURE__*/React__namespace.createElement("div", null, "Footnotes:", /*#__PURE__*/React__namespace.createElement(InfoTip$6, null, /*#__PURE__*/React__namespace.createElement("p", null, "To add footnotes, add ^ characters where they belong in the passage. Then, add ^ in the footnotes area to reference the footnotes in the passage.")), footnotesEditor));
33059
33050
  }
33060
33051
  }
33061
33052
 
33062
33053
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
33063
33054
  const {
33064
- InfoTip: InfoTip$6,
33055
+ InfoTip: InfoTip$5,
33065
33056
  NumberInput: NumberInput$5,
33066
33057
  TextInput: TextInput$2
33067
33058
  } = perseus.components;
@@ -33106,7 +33097,7 @@ class PassageRefEditor extends React__namespace.Component {
33106
33097
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
33107
33098
  ,
33108
33099
  onChange: this.change("summaryText")
33109
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$6, null, /*#__PURE__*/React__namespace.createElement("p", null, "Short summary of the referenced section. This will be included in parentheses and quotes automatically."), /*#__PURE__*/React__namespace.createElement("p", null, "Ex: The start ... the end")))));
33100
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$5, null, /*#__PURE__*/React__namespace.createElement("p", null, "Short summary of the referenced section. This will be included in parentheses and quotes automatically."), /*#__PURE__*/React__namespace.createElement("p", null, "Ex: The start ... the end")))));
33110
33101
  }
33111
33102
  }
33112
33103
 
@@ -33147,7 +33138,7 @@ class PassageRefTargetEditor extends React__namespace.Component {
33147
33138
  }
33148
33139
 
33149
33140
  const {
33150
- InfoTip: InfoTip$5,
33141
+ InfoTip: InfoTip$4,
33151
33142
  NumberInput: NumberInput$4,
33152
33143
  RangeInput,
33153
33144
  TextListEditor: TextListEditor$1
@@ -33403,7 +33394,7 @@ class PlotterEditor extends React__namespace.Component {
33403
33394
  useArrowKeys: true,
33404
33395
  value: this.state.tickStep,
33405
33396
  onChange: this.handleChangeTickStep
33406
- })), /*#__PURE__*/React__namespace.createElement(InfoTip$5, null, /*#__PURE__*/React__namespace.createElement("p", null, "The difference between adjacent ticks."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Range:", " ", /*#__PURE__*/React__namespace.createElement(RangeInput, {
33397
+ })), /*#__PURE__*/React__namespace.createElement(InfoTip$4, null, /*#__PURE__*/React__namespace.createElement("p", null, "The difference between adjacent ticks."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Range:", " ", /*#__PURE__*/React__namespace.createElement(RangeInput, {
33407
33398
  placeholder: [0, 10],
33408
33399
  useArrowKeys: true,
33409
33400
  value: [this.state.minX, this.state.maxX],
@@ -33414,11 +33405,11 @@ class PlotterEditor extends React__namespace.Component {
33414
33405
  useArrowKeys: true,
33415
33406
  value: this.props.labelInterval,
33416
33407
  onChange: this.changeLabelInterval
33417
- })), /*#__PURE__*/React__namespace.createElement(InfoTip$5, null, /*#__PURE__*/React__namespace.createElement("p", null, "Which ticks to display the labels for. For instance, setting this to \"4\" will only show every 4th label (plus the last one)"))), this.props.type === "pic" && /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Picture:", " ", /*#__PURE__*/React__namespace.createElement(BlurInput, {
33408
+ })), /*#__PURE__*/React__namespace.createElement(InfoTip$4, null, /*#__PURE__*/React__namespace.createElement("p", null, "Which ticks to display the labels for. For instance, setting this to \"4\" will only show every 4th label (plus the last one)"))), this.props.type === "pic" && /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Picture:", " ", /*#__PURE__*/React__namespace.createElement(BlurInput, {
33418
33409
  className: "pic-url",
33419
33410
  value: this.props.picUrl,
33420
33411
  onChange: this.changePicUrl
33421
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$5, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use the default picture of Earth, or insert the URL for a different picture using the \"Add image\" function."))), this.state.pic && this.state.pic.width !== this.state.pic.height && /*#__PURE__*/React__namespace.createElement("p", {
33412
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$4, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use the default picture of Earth, or insert the URL for a different picture using the \"Add image\" function."))), this.state.pic && this.state.pic.width !== this.state.pic.height && /*#__PURE__*/React__namespace.createElement("p", {
33422
33413
  className: "warning"
33423
33414
  }, /*#__PURE__*/React__namespace.createElement("b", null, "Warning"), ": You are using a picture which is not square. This means the image will get distorted. You should probably crop it to be square.")), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Categories:", " ", /*#__PURE__*/React__namespace.createElement(TextListEditor$1
33424
33415
  // eslint-disable-next-line react/no-string-refs
@@ -33442,14 +33433,14 @@ class PlotterEditor extends React__namespace.Component {
33442
33433
  type: "text",
33443
33434
  onChange: this.changeSnaps,
33444
33435
  defaultValue: this.props.snapsPerLine
33445
- })), /*#__PURE__*/React__namespace.createElement(InfoTip$5, null, /*#__PURE__*/React__namespace.createElement("p", null, "Creates the specified number of divisions between the horizontal lines. Fewer snaps between lines makes the graph easier for the student to create correctly."))), /*#__PURE__*/React__namespace.createElement("div", null, "Editing values:", " ", editingStates.map(editing => /*#__PURE__*/React__namespace.createElement("label", {
33436
+ })), /*#__PURE__*/React__namespace.createElement(InfoTip$4, null, /*#__PURE__*/React__namespace.createElement("p", null, "Creates the specified number of divisions between the horizontal lines. Fewer snaps between lines makes the graph easier for the student to create correctly."))), /*#__PURE__*/React__namespace.createElement("div", null, "Editing values:", " ", editingStates.map(editing => /*#__PURE__*/React__namespace.createElement("label", {
33446
33437
  key: editing
33447
33438
  }, /*#__PURE__*/React__namespace.createElement("input", {
33448
33439
  type: "radio",
33449
33440
  disabled: editing === CORRECT && this.props.static,
33450
33441
  checked: this.props.static ? editing === STARTING : this.state.editing === editing,
33451
33442
  onChange: e => this.changeEditing(editing)
33452
- }), editing)), /*#__PURE__*/React__namespace.createElement(InfoTip$5, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use this toggle to switch between editing the correct answer (what the student will be graded on) and the starting values (what the student will see plotted when they start the problem). Note: These cannot be the same."), /*#__PURE__*/React__namespace.createElement("p", null, "In static mode, the starting values are rendered out to the displayed widget."))), /*#__PURE__*/React__namespace.createElement(Plotter, _extends({}, props, {
33443
+ }), editing)), /*#__PURE__*/React__namespace.createElement(InfoTip$4, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use this toggle to switch between editing the correct answer (what the student will be graded on) and the starting values (what the student will see plotted when they start the problem). Note: These cannot be the same."), /*#__PURE__*/React__namespace.createElement("p", null, "In static mode, the starting values are rendered out to the displayed widget."))), /*#__PURE__*/React__namespace.createElement(Plotter, _extends({}, props, {
33453
33444
  starting: this.props[this.state.editing],
33454
33445
  onChange: this.handlePlotterChange
33455
33446
  })));
@@ -33459,7 +33450,7 @@ class PlotterEditor extends React__namespace.Component {
33459
33450
  /* eslint-disable jsx-a11y/anchor-is-valid, react/forbid-prop-types, react/sort-comp */
33460
33451
  const {
33461
33452
  InlineIcon: InlineIcon$2,
33462
- PropCheckBox: PropCheckBox$2
33453
+ PropCheckBox: PropCheckBox$1
33463
33454
  } = perseus.components;
33464
33455
  const {
33465
33456
  iconPlus: iconPlus$1,
@@ -33565,21 +33556,21 @@ class RadioEditor extends React__namespace.Component {
33565
33556
  target: "_blank"
33566
33557
  }, "Multiple choice style guide"), /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement("div", {
33567
33558
  className: "perseus-widget-left-col"
33568
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$2, {
33559
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$1, {
33569
33560
  label: "Multiple selections",
33570
33561
  labelAlignment: "right",
33571
33562
  multipleSelect: this.props.multipleSelect,
33572
33563
  onChange: this.onMultipleSelectChange
33573
33564
  })), /*#__PURE__*/React__namespace.createElement("div", {
33574
33565
  className: "perseus-widget-right-col"
33575
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$2, {
33566
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$1, {
33576
33567
  label: "Randomize order",
33577
33568
  labelAlignment: "right",
33578
33569
  randomize: this.props.randomize,
33579
33570
  onChange: this.props.onChange
33580
33571
  })), this.props.multipleSelect && /*#__PURE__*/React__namespace.createElement("div", {
33581
33572
  className: "perseus-widget-left-col"
33582
- }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$2, {
33573
+ }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$1, {
33583
33574
  label: "Specify number correct",
33584
33575
  labelAlignment: "right",
33585
33576
  countChoices: this.props.countChoices,
@@ -34058,7 +34049,7 @@ class SimpleMarkdownTesterEditor extends React__namespace.Component {
34058
34049
 
34059
34050
  /* eslint-disable react/sort-comp */
34060
34051
  const {
34061
- InfoTip: InfoTip$4,
34052
+ InfoTip: InfoTip$3,
34062
34053
  NumberInput: NumberInput$2
34063
34054
  } = perseus.components;
34064
34055
  const maxTrials = 5000;
@@ -34097,7 +34088,7 @@ class SimulatorEditor extends React__namespace.Component {
34097
34088
  className: "graph-settings-axis-label",
34098
34089
  value: this.props.proportionLabel,
34099
34090
  onChange: ___default["default"].partial(this.handleTargetValueChange, "proportionLabel")
34100
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$4, null, /*#__PURE__*/React__namespace.createElement("p", null, "This text will be displayed next to the box in which the user enters the sample proportion for their simulation. For example, if your question is about surveying for approval ratings, you might want this to say \"Sample approval rating\"."))), /*#__PURE__*/React__namespace.createElement("div", null, i18n__namespace._("Proportion or Percentage"), ":", /*#__PURE__*/React__namespace.createElement("select", {
34091
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$3, null, /*#__PURE__*/React__namespace.createElement("p", null, "This text will be displayed next to the box in which the user enters the sample proportion for their simulation. For example, if your question is about surveying for approval ratings, you might want this to say \"Sample approval rating\"."))), /*#__PURE__*/React__namespace.createElement("div", null, i18n__namespace._("Proportion or Percentage"), ":", /*#__PURE__*/React__namespace.createElement("select", {
34101
34092
  className: "perseus-widget-dropdown",
34102
34093
  value: this.props.proportionOrPercentage,
34103
34094
  onChange: ___default["default"].partial(this.handleTargetValueChange, "proportionOrPercentage")
@@ -34107,13 +34098,13 @@ class SimulatorEditor extends React__namespace.Component {
34107
34098
  }, "Proportion"), /*#__PURE__*/React__namespace.createElement("option", {
34108
34099
  key: "percentage",
34109
34100
  value: "percentage"
34110
- }, "Percentage")), /*#__PURE__*/React__namespace.createElement(InfoTip$4, null, /*#__PURE__*/React__namespace.createElement("p", null, "Do you want the user to describe their simulation in terms of a proportion or a percentage?"))), /*#__PURE__*/React__namespace.createElement("div", null, i18n__namespace._("Number of trials"), ":", /*#__PURE__*/React__namespace.createElement(NumberInput$2, {
34101
+ }, "Percentage")), /*#__PURE__*/React__namespace.createElement(InfoTip$3, null, /*#__PURE__*/React__namespace.createElement("p", null, "Do you want the user to describe their simulation in terms of a proportion or a percentage?"))), /*#__PURE__*/React__namespace.createElement("div", null, i18n__namespace._("Number of trials"), ":", /*#__PURE__*/React__namespace.createElement(NumberInput$2, {
34111
34102
  value: this.props.numTrials,
34112
34103
  checkValidity: val => {
34113
34104
  return val >= 0 && val <= maxTrials;
34114
34105
  },
34115
34106
  onChange: this.change("numTrials")
34116
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$4, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the number of trials used in the simulation. For example, if you set this to 50, then the survey will be conducted 50 times. Warning: setting this too high (i.e., greater than 5000 or so) will freeze the page."))));
34107
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$3, null, /*#__PURE__*/React__namespace.createElement("p", null, "This controls the number of trials used in the simulation. For example, if you set this to 50, then the survey will be conducted 50 times. Warning: setting this too high (i.e., greater than 5000 or so) will freeze the page."))));
34117
34108
  }
34118
34109
  change = (() => {
34119
34110
  var _this = this;
@@ -34135,8 +34126,8 @@ class SimulatorEditor extends React__namespace.Component {
34135
34126
 
34136
34127
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
34137
34128
  const {
34138
- InfoTip: InfoTip$3,
34139
- PropCheckBox: PropCheckBox$1,
34129
+ InfoTip: InfoTip$2,
34130
+ PropCheckBox,
34140
34131
  TextListEditor
34141
34132
  } = perseus.components;
34142
34133
  const HORIZONTAL = "horizontal";
@@ -34163,7 +34154,7 @@ class SorterEditor extends React__namespace.Component {
34163
34154
  };
34164
34155
  render() {
34165
34156
  const editor = this;
34166
- return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$3, null, /*#__PURE__*/React__namespace.createElement("p", null, "Enter the correct answer (in the correct order) here. The preview on the right will have the cards in a randomized order, which is how the student will see them."))), /*#__PURE__*/React__namespace.createElement(TextListEditor, {
34157
+ return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$2, null, /*#__PURE__*/React__namespace.createElement("p", null, "Enter the correct answer (in the correct order) here. The preview on the right will have the cards in a randomized order, which is how the student will see them."))), /*#__PURE__*/React__namespace.createElement(TextListEditor, {
34167
34158
  options: this.props.correct
34168
34159
  // eslint-disable-next-line react/jsx-no-bind
34169
34160
  ,
@@ -34182,17 +34173,17 @@ class SorterEditor extends React__namespace.Component {
34182
34173
  value: HORIZONTAL
34183
34174
  }, "Horizontal"), /*#__PURE__*/React__namespace.createElement("option", {
34184
34175
  value: VERTICAL
34185
- }, "Vertical"))), /*#__PURE__*/React__namespace.createElement(InfoTip$3, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text and larger images."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(PropCheckBox$1, {
34176
+ }, "Vertical"))), /*#__PURE__*/React__namespace.createElement(InfoTip$2, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text and larger images."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(PropCheckBox, {
34186
34177
  label: "Padding:",
34187
34178
  padding: this.props.padding,
34188
34179
  onChange: this.props.onChange
34189
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$3, null, /*#__PURE__*/React__namespace.createElement("p", null, "Padding is good for text, but not needed for images."))));
34180
+ }), /*#__PURE__*/React__namespace.createElement(InfoTip$2, null, /*#__PURE__*/React__namespace.createElement("p", null, "Padding is good for text, but not needed for images."))));
34190
34181
  }
34191
34182
  }
34192
34183
 
34193
34184
  /* eslint-disable react/sort-comp */
34194
34185
  const {
34195
- InfoTip: InfoTip$2,
34186
+ InfoTip: InfoTip$1,
34196
34187
  NumberInput: NumberInput$1
34197
34188
  } = perseus.components;
34198
34189
  const Table = perseus.TableWidget.widget;
@@ -34254,7 +34245,7 @@ class TableEditor extends React__namespace.Component {
34254
34245
  }
34255
34246
  },
34256
34247
  useArrowKeys: true
34257
- }))), /*#__PURE__*/React__namespace.createElement("div", null, " ", "Table of answers:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$2, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student has to fill out all cells in the table. For partially filled tables create a table using the template, and insert text input boxes as desired."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(Table, tableProps)));
34248
+ }))), /*#__PURE__*/React__namespace.createElement("div", null, " ", "Table of answers:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$1, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student has to fill out all cells in the table. For partially filled tables create a table using the template, and insert text input boxes as desired."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(Table, tableProps)));
34258
34249
  }
34259
34250
  onSizeInput = (numRawRows, numRawColumns) => {
34260
34251
  let rows = +numRawRows || 0;
@@ -34300,771 +34291,6 @@ class TableEditor extends React__namespace.Component {
34300
34291
  };
34301
34292
  }
34302
34293
 
34303
- /* eslint-disable camelcase, react/sort-comp */
34304
- const {
34305
- Graph,
34306
- InfoTip: InfoTip$1,
34307
- PropCheckBox
34308
- } = perseus.components;
34309
- const Transformer = perseus.TransformerWidget.widget;
34310
- const {
34311
- deepEq,
34312
- getGridStep
34313
- } = perseus.Util;
34314
- function arraySum(array) {
34315
- return ___default["default"].reduce(array, function (memo, arg) {
34316
- return memo + arg;
34317
- }, 0);
34318
- }
34319
- const defaultBackgroundImage = {
34320
- url: null
34321
- };
34322
-
34323
- /* Scales a distance from the default range of
34324
- * [-10, 10] to a given props.range pair
34325
- *
34326
- * Used for sizing various transformation tools
34327
- * (rotation handle, dilation circle)
34328
- */
34329
- function scaleToRange(dist, range) {
34330
- const spreadX = range[0][1] - range[0][0];
34331
- const spreadY = range[1][1] - range[1][0];
34332
- return dist * Math.max(spreadX, spreadY) / 20;
34333
- }
34334
- function orderInsensitiveCoordsEqual(coords1, coords2) {
34335
- coords1 = ___default["default"].clone(coords1).sort(kmath.point.compare);
34336
- coords2 = ___default["default"].clone(coords2).sort(kmath.point.compare);
34337
- return ___default["default"].all(___default["default"].map(coords1, function (coord1, i) {
34338
- const coord2 = coords2[i];
34339
- return kmath.point.equal(coord1, coord2);
34340
- }));
34341
- }
34342
- const defaultGraphProps = function (setProps, boxSize) {
34343
- setProps = setProps || {};
34344
- const labels = setProps.labels || ["x", "y"];
34345
- const range = setProps.range || [[-10, 10], [-10, 10]];
34346
- const step = setProps.step || [1, 1];
34347
- const gridStep = setProps.gridStep || getGridStep(range, step, boxSize);
34348
- return {
34349
- box: [boxSize, boxSize],
34350
- labels: labels,
34351
- range: range,
34352
- step: step,
34353
- gridStep: gridStep,
34354
- valid: true,
34355
- backgroundImage: defaultBackgroundImage,
34356
- markings: "grid",
34357
- showProtractor: false
34358
- };
34359
- };
34360
- const defaultTransformerProps = {
34361
- apiOptions: perseus.ApiOptions.defaults,
34362
- gradeEmpty: false,
34363
- graphMode: "interactive",
34364
- listMode: "dynamic",
34365
- graph: {},
34366
- tools: {
34367
- translation: {
34368
- enabled: true,
34369
- required: false,
34370
- constraints: {}
34371
- },
34372
- rotation: {
34373
- enabled: true,
34374
- required: false,
34375
- constraints: {
34376
- fixed: false
34377
- },
34378
- coord: [1, 6]
34379
- },
34380
- reflection: {
34381
- enabled: true,
34382
- required: false,
34383
- constraints: {
34384
- fixed: false
34385
- },
34386
- coords: [[2, -4], [2, 2]]
34387
- },
34388
- dilation: {
34389
- enabled: true,
34390
- required: false,
34391
- constraints: {
34392
- fixed: false
34393
- },
34394
- coord: [6, 6]
34395
- }
34396
- },
34397
- drawSolutionShape: true,
34398
- starting: {
34399
- shape: {
34400
- type: "polygon-3",
34401
- coords: [[2, 2], [2, 6], [7, 2]]
34402
- },
34403
- transformations: []
34404
- },
34405
- correct: {
34406
- shape: {
34407
- type: "polygon-3",
34408
- coords: [[2, 2], [2, 6], [7, 2]]
34409
- },
34410
- transformations: []
34411
- }
34412
- };
34413
- class ToolSettings extends React__namespace.Component {
34414
- static defaultProps = {
34415
- allowFixed: true
34416
- };
34417
- render() {
34418
- return /*#__PURE__*/React__namespace.createElement("div", null, this.props.name, ":", " ", /*#__PURE__*/React__namespace.createElement(PropCheckBox, {
34419
- label: "enabled:",
34420
- enabled: this.props.settings.enabled,
34421
- onChange: this.props.onChange
34422
- }), " ", this.props.settings.enabled && /*#__PURE__*/React__namespace.createElement(PropCheckBox, {
34423
- label: "required:",
34424
- required: this.props.settings.required,
34425
- onChange: this.props.onChange
34426
- }), this.props.settings.enabled && /*#__PURE__*/React__namespace.createElement(InfoTip$1, null, "'Required' will only grade the answer as correct if the student has used at least one such transformation."), " ", this.props.allowFixed && this.props.settings.enabled && /*#__PURE__*/React__namespace.createElement(PropCheckBox, {
34427
- label: "fixed:",
34428
- fixed: this.props.settings.constraints.fixed,
34429
- onChange: this.changeConstraints
34430
- }), this.props.allowFixed && this.props.settings.enabled && /*#__PURE__*/React__namespace.createElement(InfoTip$1, null, "Enable 'fixed' to prevent the student from repositioning the tool. The tool will appear in the position at which it is placed in the editor below."));
34431
- }
34432
- changeConstraints = changed => {
34433
- const newConstraints = ___default["default"].extend({}, this.props.constraints, changed);
34434
- this.props.onChange({
34435
- constraints: newConstraints
34436
- });
34437
- };
34438
- }
34439
- class TransformationExplorerSettings extends React__namespace.Component {
34440
- render() {
34441
- return /*#__PURE__*/React__namespace.createElement("div", {
34442
- className: "transformer-settings"
34443
- }, /*#__PURE__*/React__namespace.createElement("div", null, " ", "Mode:", " ", /*#__PURE__*/React__namespace.createElement("select", {
34444
- value: this.getMode(),
34445
- onChange: this.changeMode
34446
- }, /*#__PURE__*/React__namespace.createElement("option", {
34447
- value: "interactive,dynamic"
34448
- }, " ", "Exploration with text", " "), /*#__PURE__*/React__namespace.createElement("option", {
34449
- value: "interactive,static"
34450
- }, " ", "Exploration without text", " "), /*#__PURE__*/React__namespace.createElement("option", {
34451
- value: "dynamic,interactive"
34452
- }, " ", "Formal with movement", " "), /*#__PURE__*/React__namespace.createElement("option", {
34453
- value: "static,interactive"
34454
- }, " ", "Formal without movement", " ")), /*#__PURE__*/React__namespace.createElement(InfoTip$1, null, /*#__PURE__*/React__namespace.createElement("ul", null, /*#__PURE__*/React__namespace.createElement("li", null, /*#__PURE__*/React__namespace.createElement("b", null, "Exploration:"), " Students create transformations with tools on the graph.", " "), /*#__PURE__*/React__namespace.createElement("li", null, /*#__PURE__*/React__namespace.createElement("b", null, "Formal with movement:"), " Students specify transformations mathematically in the transformation list. Graph shows the results of these transformations.", " "), /*#__PURE__*/React__namespace.createElement("li", null, /*#__PURE__*/React__namespace.createElement("b", null, "Formal without movement:"), " Students specify transformations mathematically in the transformation list. Graph does not update.", " ")))), /*#__PURE__*/React__namespace.createElement(ToolSettings, {
34455
- name: "Translations",
34456
- settings: this.props.tools.translation,
34457
- allowFixed: false,
34458
- onChange: this.changeHandlerFor("translation")
34459
- }), /*#__PURE__*/React__namespace.createElement(ToolSettings, {
34460
- name: "Rotations",
34461
- settings: this.props.tools.rotation,
34462
- onChange: this.changeHandlerFor("rotation")
34463
- }), /*#__PURE__*/React__namespace.createElement(ToolSettings, {
34464
- name: "Reflections",
34465
- settings: this.props.tools.reflection,
34466
- onChange: this.changeHandlerFor("reflection")
34467
- }), /*#__PURE__*/React__namespace.createElement(ToolSettings, {
34468
- name: "Dilations",
34469
- settings: this.props.tools.dilation,
34470
- onChange: this.changeHandlerFor("dilation")
34471
- }), /*#__PURE__*/React__namespace.createElement(PropCheckBox, {
34472
- label: "Draw Solution:",
34473
- drawSolutionShape: this.props.drawSolutionShape,
34474
- onChange: this.props.onChange
34475
- }));
34476
- }
34477
- getMode = () => {
34478
- return this.props.graphMode + "," + this.props.listMode;
34479
- };
34480
- changeMode = e => {
34481
- const selected = e.target.value;
34482
- const modes = selected.split(",");
34483
- this.props.onChange({
34484
- graphMode: modes[0],
34485
- listMode: modes[1]
34486
- });
34487
- };
34488
- changeHandlerFor = toolName => {
34489
- return change => {
34490
- const newTools = ___default["default"].clone(this.props.tools);
34491
- newTools[toolName] = ___default["default"].extend({}, this.props.tools[toolName], change);
34492
- this.props.onChange({
34493
- tools: newTools
34494
- });
34495
- };
34496
- };
34497
- }
34498
- const ShapeTypes = {
34499
- getPointCountForType: function (type) {
34500
- const splitType = type.split("-");
34501
- if (splitType[0] === "polygon") {
34502
- return splitType[1] || 3;
34503
- }
34504
- if (splitType[0] === "line" || splitType[0] === "lineSegment") {
34505
- return 2;
34506
- }
34507
- if (splitType[0] === "angle") {
34508
- return 3;
34509
- }
34510
- if (splitType[0] === "circle") {
34511
- return 2;
34512
- }
34513
- if (splitType[0] === "point") {
34514
- return 1;
34515
- }
34516
- },
34517
- addMovableShape: function (graphie, options) {
34518
- if (options.editable && options.translatable) {
34519
- throw new perseus.PerseusError("It doesn't make sense to have a movable shape " + "where you can stretch the points and translate them " + "simultaneously.", perseus.Errors.InvalidInput, {
34520
- metadata: {
34521
- options
34522
- }
34523
- });
34524
- }
34525
- const points = ___default["default"].map(options.shape.coords, function (coord) {
34526
- let isMoving = false;
34527
- let previousCoord = coord;
34528
- const onMove = function (x, y) {
34529
- if (!isMoving) {
34530
- previousCoord = currentPoint.coord;
34531
- isMoving = true;
34532
- }
34533
- let moveVector = kmath.vector.subtract([x, y], currentPoint.coord);
34534
-
34535
- // Translate from (x, y) semantics to (dX, dY) semantics
34536
- // This is more useful for translations on multiple points,
34537
- // where we care about how the points moved, not where any
34538
- // individual point ended up
34539
- if (options.onMove) {
34540
- moveVector = options.onMove(moveVector[0], moveVector[1]);
34541
- }
34542
-
34543
- // Perform a translation on all points in this shape when
34544
- // any point moves
34545
- if (options.translatable) {
34546
- ___default["default"].each(points, function (point) {
34547
- // The point itself will be updated by the
34548
- // movablePoint class, so only translate the other
34549
- // points
34550
- if (point !== currentPoint) {
34551
- point.setCoord(kmath.vector.add(point.coord, moveVector));
34552
- }
34553
- });
34554
- }
34555
-
34556
- // Update our shape and our currentPoint
34557
- // Without this, some shapes (circles, angles) appear
34558
- // "bouncy" as they are updated with currentPoint at the
34559
- // current mouse coordinate (oldCoord), rather than newCoord
34560
- const oldCoord = currentPoint.coord;
34561
- const newCoord = kmath.vector.add(currentPoint.coord, moveVector);
34562
- // Temporarily change our coordinate so that
34563
- // shape.update() sees the new coordinate
34564
- currentPoint.coord = newCoord;
34565
- shape.update();
34566
- // ...But don't break onMove, which assumes it
34567
- // is the only thing changing our coord
34568
- currentPoint.coord = oldCoord;
34569
- return newCoord;
34570
- };
34571
- const onMoveEnd = function () {
34572
- // onMove isn't guaranteed to be called before onMoveEnd, so
34573
- // we have to take into account that we may not have moved and
34574
- // set previousCoord.
34575
- if (options.onMoveEnd && isMoving) {
34576
- isMoving = false;
34577
- // We don't use the supplied x and y parameters here
34578
- // because MovablePoint's onMoveEnd semantics suck.
34579
- // It returns the mouseX, mouseY without processing them
34580
- // through onMove, leaving us with weird fractional moves
34581
- const change = kmath.vector.subtract(currentPoint.coord, previousCoord);
34582
- options.onMoveEnd(change[0], change[1]);
34583
- }
34584
- shape.update();
34585
- };
34586
- const currentPoint = graphie.addMovablePoint({
34587
- coord: coord,
34588
- normalStyle: options.normalPointStyle,
34589
- highlightStyle: options.highlightPointStyle,
34590
- constraints: {
34591
- fixed: !options.translatable && !options.editable
34592
- },
34593
- visible: options.showPoints,
34594
- snapX: options.snap && options.snap[0] || 0,
34595
- snapY: options.snap && options.snap[1] || 0,
34596
- bounded: false,
34597
- // Don't bound it when placing it on the graph
34598
- onMove: onMove,
34599
- onMoveEnd: onMoveEnd
34600
- });
34601
-
34602
- // Bound it when moving
34603
- // We can't set this earlier, because doing so would mean any
34604
- // points outside of the graph would be moved into a moved into
34605
- // a position that doesn't preserve the shape
34606
- currentPoint.bounded = true;
34607
- return currentPoint;
34608
- });
34609
- const shape = ShapeTypes.addShape(graphie, options, points);
34610
- const removeShapeWithoutPoints = shape.remove;
34611
- shape.remove = function () {
34612
- removeShapeWithoutPoints.apply(shape);
34613
- ___default["default"].invoke(points, "remove");
34614
- };
34615
- return shape;
34616
- },
34617
- addShape: function (graphie, options, points) {
34618
- points = points || options.shape.coords;
34619
- const types = ShapeTypes._typesOf(options.shape);
34620
- const typeOptions = options.shape.options || ShapeTypes.defaultOptions(types);
34621
- const shapes = ShapeTypes._mapTypes(types, points, function (type, points, i) {
34622
- const shapeOptions = ___default["default"].extend({}, options, typeOptions[i]);
34623
- return ShapeTypes._addType(graphie, type, points, shapeOptions);
34624
- });
34625
- const updateFuncs = ___default["default"].filter(___default["default"].pluck(shapes, "update"), ___default["default"].identity);
34626
- const update = function () {
34627
- ___default["default"].invoke(updateFuncs, "call");
34628
- };
34629
- const removeFuncs = ___default["default"].filter(___default["default"].pluck(shapes, "remove"), ___default["default"].identity);
34630
- const remove = function () {
34631
- ___default["default"].invoke(removeFuncs, "call");
34632
- };
34633
- const getOptions = function () {
34634
- return ___default["default"].map(shapes, function (shape) {
34635
- if (shape.getOptions) {
34636
- return shape.getOptions();
34637
- }
34638
- return {};
34639
- });
34640
- };
34641
- const toJSON = function () {
34642
- const coords = ___default["default"].map(points, function (pt) {
34643
- if (___default["default"].isArray(pt)) {
34644
- return pt;
34645
- }
34646
- return pt.coord;
34647
- });
34648
- return {
34649
- type: types,
34650
- coords: coords,
34651
- options: getOptions()
34652
- };
34653
- };
34654
- return {
34655
- type: types,
34656
- points: points,
34657
- update: update,
34658
- remove: remove,
34659
- toJSON: toJSON,
34660
- getOptions: getOptions
34661
- };
34662
- },
34663
- equal: function (shape1, shape2) {
34664
- const types1 = ShapeTypes._typesOf(shape1);
34665
- const types2 = ShapeTypes._typesOf(shape2);
34666
- if (types1.length !== types2.length) {
34667
- return false;
34668
- }
34669
- const shapes1 = ShapeTypes._mapTypes(types1, shape1.coords, ShapeTypes._combine);
34670
- const shapes2 = ShapeTypes._mapTypes(types2, shape2.coords, ShapeTypes._combine);
34671
- return ___default["default"].all(___default["default"].map(shapes1, function (partialShape1, i) {
34672
- const partialShape2 = shapes2[i];
34673
- if (partialShape1.type !== partialShape2.type) {
34674
- return false;
34675
- }
34676
- return ShapeTypes._forType(partialShape1.type).equal(partialShape1.coords, partialShape2.coords);
34677
- }));
34678
- },
34679
- _typesOf: function (shape) {
34680
- let types = shape.type;
34681
- if (!___default["default"].isArray(types)) {
34682
- types = [types];
34683
- }
34684
- return ___default["default"].map(types, function (type) {
34685
- if (type === "polygon") {
34686
- return "polygon-3";
34687
- }
34688
- return type;
34689
- });
34690
- },
34691
- defaultOptions: function (types) {
34692
- return ___default["default"].map(types, function (type) {
34693
- const typeDefaultOptions = ShapeTypes._forType(type).defaultOptions;
34694
- return ___default["default"].extend({}, typeDefaultOptions);
34695
- });
34696
- },
34697
- _forType: function (type) {
34698
- const baseType = type.split("-")[0];
34699
- return ShapeTypes[baseType];
34700
- },
34701
- _mapTypes: function (types, points, func, context) {
34702
- return ___default["default"].map(types, function (type, i) {
34703
- const pointCount = ShapeTypes.getPointCountForType(type);
34704
- const currentPoints = ___default["default"].first(points, pointCount);
34705
- points = ___default["default"].rest(points, pointCount);
34706
- return func.call(context, type, currentPoints, i);
34707
- });
34708
- },
34709
- _addType: function (graphie, type, points, options) {
34710
- const lineCoords = ___default["default"].isArray(points[0]) ? {
34711
- coordA: points[0],
34712
- coordZ: points[1]
34713
- } : {
34714
- pointA: points[0],
34715
- pointZ: points[1]
34716
- };
34717
- type = type.split("-")[0];
34718
- if (type === "polygon") {
34719
- const polygon = graphie.addMovablePolygon(___default["default"].extend({}, options, {
34720
- fixed: !options.editable,
34721
- snapX: options.snap && options.snap[0] || 0,
34722
- snapY: options.snap && options.snap[1] || 0,
34723
- points: points,
34724
- constrainToGraph: false
34725
- }));
34726
- return {
34727
- update: polygon.transform.bind(polygon),
34728
- remove: polygon.remove.bind(polygon)
34729
- };
34730
- }
34731
- if (type === "line" || type === "lineSegment") {
34732
- const line = graphie.addMovableLineSegment(___default["default"].extend({}, options, lineCoords, {
34733
- movePointsWithLine: true,
34734
- fixed: true,
34735
- constraints: {
34736
- fixed: true
34737
- },
34738
- extendLine: type === "line"
34739
- }));
34740
-
34741
- // TODO(jack): Hide points on uneditable lines when translation
34742
- // is a vector.
34743
- // We can't just remove the points yet, because they are the
34744
- // translation handle for the line.
34745
- return {
34746
- update: line.transform.bind(line, true),
34747
- remove: line.remove.bind(line)
34748
- };
34749
- }
34750
- if (type === "angle") {
34751
- // If this angle is editable, we want to be able to make angles
34752
- // both larger and smaller than 180 degrees.
34753
- // If this angle is not editable, it should always maintain
34754
- // it's angle measure, even if it is reflected (causing the
34755
- // clockwise-ness of the points to change)
34756
- const shouldChangeReflexivity = options.editable ? null : false;
34757
- const angle = graphie.addMovableAngle({
34758
- angleLabel: "$deg0",
34759
- fixed: true,
34760
- points: points,
34761
- normalStyle: options.normalStyle,
34762
- reflex: options.reflex
34763
- });
34764
-
34765
- // Hide non-vertex points on uneditable angles
34766
- if (!___default["default"].isArray(points[0]) && !options.editable) {
34767
- points[0].remove();
34768
- points[2].remove();
34769
- }
34770
- return {
34771
- update: angle.update.bind(angle, shouldChangeReflexivity),
34772
- remove: angle.remove.bind(angle),
34773
- getOptions: function () {
34774
- return {
34775
- reflex: angle.isReflex()
34776
- };
34777
- }
34778
- };
34779
- }
34780
- if (type === "circle") {
34781
- let perimeter = {
34782
- // temporary object for the first removal
34783
- remove: ___default["default"].identity
34784
- };
34785
- const redrawPerim = function () {
34786
- const coord0 = points[0].coord || points[0];
34787
- const coord1 = points[1].coord || points[1];
34788
- const radius = kmath.point.distanceToPoint(coord0, coord1);
34789
- // @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
34790
- perimeter.remove();
34791
- perimeter = graphie.circle(coord0, radius, ___default["default"].extend({
34792
- stroke: perseus.KhanColors.DYNAMIC,
34793
- "stroke-width": 2
34794
- }, options.normalStyle));
34795
- };
34796
- redrawPerim();
34797
- if (points[1].remove && !options.editable) {
34798
- points[1].remove();
34799
- }
34800
- return {
34801
- update: redrawPerim,
34802
- remove: function () {
34803
- // Not _.bind because the remove function changes
34804
- // when the perimeter is redrawn
34805
- // @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
34806
- perimeter.remove();
34807
- }
34808
- };
34809
- }
34810
- if (type === "point") {
34811
- // do nothing
34812
- return {
34813
- update: null,
34814
- remove: null
34815
- };
34816
- }
34817
- throw new perseus.PerseusError("Invalid shape type " + type, perseus.Errors.InvalidInput);
34818
- },
34819
- _combine: function (type, coords) {
34820
- return {
34821
- type: type,
34822
- coords: coords
34823
- };
34824
- },
34825
- polygon: {
34826
- equal: orderInsensitiveCoordsEqual
34827
- },
34828
- line: {
34829
- equal: kmath.line.equal
34830
- },
34831
- lineSegment: {
34832
- equal: orderInsensitiveCoordsEqual
34833
- },
34834
- angle: {
34835
- equal: function (points1, points2) {
34836
- if (!kmath.point.equal(points1[1], points2[1])) {
34837
- return false;
34838
- }
34839
- const line1_0 = [points1[1], points1[0]];
34840
- const line1_2 = [points1[1], points1[2]];
34841
- const line2_0 = [points2[1], points2[0]];
34842
- const line2_2 = [points2[1], points2[2]];
34843
- const equalUnflipped =
34844
- // @ts-expect-error - TS2345 - Argument of type 'any[]' is not assignable to parameter of type 'Ray'. | TS2345 - Argument of type 'any[]' is not assignable to parameter of type 'Ray'.
34845
- kmath.ray.equal(line1_0, line2_0) && kmath.ray.equal(line1_2, line2_2);
34846
- const equalFlipped =
34847
- // @ts-expect-error - TS2345 - Argument of type 'any[]' is not assignable to parameter of type 'Ray'. | TS2345 - Argument of type 'any[]' is not assignable to parameter of type 'Ray'.
34848
- kmath.ray.equal(line1_0, line2_2) && kmath.ray.equal(line1_2, line2_0);
34849
- return equalUnflipped || equalFlipped;
34850
- },
34851
- defaultOptions: {
34852
- reflex: false
34853
- }
34854
- },
34855
- circle: {
34856
- equal: function (points1, points2) {
34857
- const radius1 = kmath.point.distanceToPoint(points1[0], points1[1]);
34858
- const radius2 = kmath.point.distanceToPoint(points2[0], points2[1]);
34859
- return kmath.point.equal(points1[0], points2[0]) && kmath.number.equal(radius1, radius2);
34860
- }
34861
- },
34862
- point: {
34863
- equal: kmath.point.equal
34864
- }
34865
- };
34866
- class TransformationsShapeEditor extends React__namespace.Component {
34867
- render() {
34868
- return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(Graph
34869
- // eslint-disable-next-line react/no-string-refs
34870
- , {
34871
- ref: "graph",
34872
- box: this.props.graph.box,
34873
- range: this.props.graph.range,
34874
- labels: this.props.graph.labels,
34875
- step: this.props.graph.step,
34876
- gridStep: this.props.graph.gridStep,
34877
- markings: this.props.graph.markings,
34878
- backgroundImage: this.props.graph.backgroundImage,
34879
- onGraphieUpdated: this.setupGraphie
34880
- }), /*#__PURE__*/React__namespace.createElement("select", {
34881
- key: "type-select",
34882
- value: this.getTypeString(this.props.shape.type),
34883
- onChange: this.changeType
34884
- }, /*#__PURE__*/React__namespace.createElement("option", {
34885
- value: "polygon-3"
34886
- }, "Triangle"), /*#__PURE__*/React__namespace.createElement("option", {
34887
- value: "polygon-4"
34888
- }, "Quadrilateral"), /*#__PURE__*/React__namespace.createElement("option", {
34889
- value: "polygon-5"
34890
- }, "Pentagon"), /*#__PURE__*/React__namespace.createElement("option", {
34891
- value: "polygon-6"
34892
- }, "Hexagon"), /*#__PURE__*/React__namespace.createElement("option", {
34893
- value: "line"
34894
- }, "Line"), /*#__PURE__*/React__namespace.createElement("option", {
34895
- value: "line,line"
34896
- }, "2 lines"), /*#__PURE__*/React__namespace.createElement("option", {
34897
- value: "lineSegment"
34898
- }, "Line segment"), /*#__PURE__*/React__namespace.createElement("option", {
34899
- value: "lineSegment,lineSegment"
34900
- }, " ", "2 line segments", " "), /*#__PURE__*/React__namespace.createElement("option", {
34901
- value: "angle"
34902
- }, "Angle"), /*#__PURE__*/React__namespace.createElement("option", {
34903
- value: "circle"
34904
- }, "Circle")));
34905
- }
34906
-
34907
- /* Return the option string for a given type */
34908
- getTypeString = type => {
34909
- if (___default["default"].isArray(type)) {
34910
- return ___default["default"].map(type, this.getTypeString).join(",");
34911
- }
34912
- if (type === "polygon") {
34913
- return "polygon-" + this.props.shape.coords.length;
34914
- }
34915
- return type;
34916
- };
34917
-
34918
- /* Change the type on the window event e
34919
- *
34920
- * e.target.value is the new type string
34921
- */
34922
- changeType = e => {
34923
- const types = String(e.target.value).split(",");
34924
- const pointCount = arraySum(___default["default"].map(types, ShapeTypes.getPointCountForType));
34925
-
34926
- // eslint-disable-next-line react/no-string-refs
34927
- // @ts-expect-error - TS2339 - Property 'props' does not exist on type 'ReactInstance'.
34928
- const radius = scaleToRange(4, this.refs.graph.props.range);
34929
- const offset = (1 / 2 - 1 / pointCount) * 180;
34930
- const coords = ___default["default"].times(pointCount, function (i) {
34931
- return kmath.point.rotateDeg([radius, 0], 360 * i / pointCount + offset);
34932
- });
34933
- this.props.onChange({
34934
- shape: {
34935
- type: types,
34936
- coords: coords,
34937
- options: ShapeTypes.defaultOptions(types)
34938
- }
34939
- });
34940
- };
34941
- componentDidMount() {
34942
- // eslint-disable-next-line react/no-string-refs
34943
- // @ts-expect-error - TS2339 - Property 'graphie' does not exist on type 'ReactInstance'.
34944
- this.setupGraphie(this.refs.graph.graphie());
34945
- }
34946
- componentDidUpdate(prevProps) {
34947
- if (!deepEq(prevProps.shape, this.props.shape)) {
34948
- // eslint-disable-next-line react/no-string-refs
34949
- // @ts-expect-error - TS2339 - Property 'reset' does not exist on type 'ReactInstance'.
34950
- this.refs.graph.reset();
34951
- }
34952
- }
34953
- updateCoords = () => {
34954
- this.props.onChange({
34955
- // @ts-expect-error - TS2339 - Property 'shape' does not exist on type 'TransformationsShapeEditor'.
34956
- shape: this.shape.toJSON()
34957
- });
34958
- };
34959
- setupGraphie = graphie => {
34960
- // @ts-expect-error - TS2339 - Property 'shape' does not exist on type 'TransformationsShapeEditor'.
34961
- this.shape = ShapeTypes.addMovableShape(graphie, {
34962
- editable: true,
34963
- snap: graphie.snap,
34964
- shape: this.props.shape,
34965
- onMoveEnd: this.updateCoords
34966
- });
34967
- };
34968
- }
34969
- class TransformerEditor extends React__namespace.Component {
34970
- // TODO (jack): These should be refactored into a nice object at the top
34971
- // so that we don't have all this duplication
34972
- static defaultProps = defaultTransformerProps;
34973
- static widgetName = "transformer";
34974
- render() {
34975
- // Fill in any missing value in this.props.graph
34976
- // this can happen because the graph json doesn't include
34977
- // box, for example
34978
- const graph = ___default["default"].extend(defaultGraphProps(this.props.graph, 340), this.props.graph);
34979
- return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(PropCheckBox, {
34980
- label: "Grade empty answers as wrong:",
34981
- gradeEmpty: this.props.gradeEmpty,
34982
- onChange: this.props.onChange
34983
- }), /*#__PURE__*/React__namespace.createElement(InfoTip$1, null, /*#__PURE__*/React__namespace.createElement("p", null, "We generally do not grade empty answers. This usually works well, but sometimes can result in giving away part of an answer in a multi-part question."), /*#__PURE__*/React__namespace.createElement("p", null, "If this is a multi-part question (there is another widget), you probably want to enable this option. Otherwise, you should leave it disabled."), /*#__PURE__*/React__namespace.createElement("p", null, "Confused? Talk to Elizabeth."))), /*#__PURE__*/React__namespace.createElement("div", null, "Graph settings:"), /*#__PURE__*/React__namespace.createElement(GraphSettings, {
34984
- box: graph.box,
34985
- labels: graph.labels,
34986
- range: graph.range,
34987
- step: graph.step,
34988
- gridStep: graph.gridStep,
34989
- valid: graph.valid,
34990
- backgroundImage: graph.backgroundImage,
34991
- markings: graph.markings,
34992
- showProtractor: graph.showProtractor,
34993
- onChange: this.changeGraph
34994
- }), /*#__PURE__*/React__namespace.createElement("div", null, "Transformation settings:"), /*#__PURE__*/React__namespace.createElement(TransformationExplorerSettings
34995
- // eslint-disable-next-line react/no-string-refs
34996
- , {
34997
- ref: "transformationSettings",
34998
- graphMode: this.props.graphMode,
34999
- listMode: this.props.listMode,
35000
- tools: this.props.tools,
35001
- drawSolutionShape: this.props.drawSolutionShape,
35002
- onChange: this.props.onChange
35003
- }), /*#__PURE__*/React__namespace.createElement("div", null, "Starting location:"), /*#__PURE__*/React__namespace.createElement(TransformationsShapeEditor
35004
- // eslint-disable-next-line react/no-string-refs
35005
- , {
35006
- ref: "shapeEditor",
35007
- graph: graph,
35008
- shape: this.props.starting.shape,
35009
- onChange: this.changeStarting,
35010
- setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
35011
- }), /*#__PURE__*/React__namespace.createElement("div", null, "Solution transformations:"), /*#__PURE__*/React__namespace.createElement(Transformer
35012
- // eslint-disable-next-line react/no-string-refs
35013
- , {
35014
- ref: "explorer",
35015
- graph: graph,
35016
- graphMode: this.props.graphMode,
35017
- listMode: this.props.listMode,
35018
- gradeEmpty: this.props.gradeEmpty,
35019
- tools: this.props.tools,
35020
- drawSolutionShape: this.props.drawSolutionShape,
35021
- starting: this.props.starting,
35022
- correct: this.props.starting,
35023
- transformations: this.props.correct.transformations,
35024
- onChange: this.changeTransformer,
35025
- trackInteraction: () => {}
35026
- }));
35027
- }
35028
-
35029
- // propagate a props change on our graph settings to
35030
- // this.props.graph
35031
- changeGraph = (graphChanges, callback) => {
35032
- const newGraph = ___default["default"].extend({}, this.props.graph, graphChanges);
35033
- this.props.onChange({
35034
- graph: newGraph
35035
- }, callback);
35036
- };
35037
-
35038
- // propagate a props change on our starting graph to
35039
- // this.props.starting
35040
- changeStarting = startingChanges => {
35041
- const newStarting = ___default["default"].extend({}, this.props.starting, startingChanges);
35042
- this.props.onChange({
35043
- starting: newStarting
35044
- });
35045
- };
35046
-
35047
- // propagate a transformations change onto correct.transformations
35048
- changeTransformer = (changes, callback) => {
35049
- if (changes.transformations) {
35050
- changes.correct = {
35051
- ...this.props.correct,
35052
- transformations: changes.transformations
35053
- };
35054
- delete changes.transformations;
35055
- }
35056
- this.props.onChange(changes, callback);
35057
- };
35058
- serialize = () => {
35059
- // eslint-disable-next-line react/no-string-refs
35060
- // @ts-expect-error - TS2339 - Property 'getEditorJSON' does not exist on type 'ReactInstance'.
35061
- const json = this.refs.explorer.getEditorJSON();
35062
- json.correct = json.answer;
35063
- delete json.answer;
35064
- return json;
35065
- };
35066
- }
35067
-
35068
34294
  /* eslint-disable react/no-unsafe */
35069
34295
  const {
35070
34296
  InlineIcon,
@@ -35353,7 +34579,7 @@ class VideoEditor extends React__namespace.Component {
35353
34579
  }
35354
34580
  }
35355
34581
 
35356
- var AllEditors = [CategorizerEditor, CSProgramEditor, DefinitionEditor, DropdownEditor, ExampleGraphieWidgetEditor, ExampleWidgetEditor, ExplanationEditor, ExpressionEditor, GradedGroupEditor, GradedGroupSetEditor, GrapherEditor, GroupEditor, IframeEditor, ImageEditor, InputNumberEditor, InteractionEditor, InteractiveGraphEditor, LabelImageEditor, LightsPuzzleEditor, MatcherEditor, MatrixEditor, MeasurerEditor, MoleculeWidgetEditor, NumberLineEditor, NumericInputEditor, OrdererEditor, PassageEditor, PassageRefEditor, PassageRefTargetEditor, PlotterEditor, ReactionDiagramWidgetEditor, SequenceEditor, SimpleMarkdownTesterEditor, SimulatorEditor, SorterEditor, TableEditor, TransformerEditor, UnitInputEditor, VideoEditor, RadioEditor, DeprecatedStandinEditor];
34582
+ var AllEditors = [CategorizerEditor, CSProgramEditor, DefinitionEditor, DropdownEditor, ExampleGraphieWidgetEditor, ExampleWidgetEditor, ExplanationEditor, ExpressionEditor, GradedGroupEditor, GradedGroupSetEditor, GrapherEditor, GroupEditor, IframeEditor, ImageEditor, InputNumberEditor, InteractionEditor, InteractiveGraphEditor, LabelImageEditor, LightsPuzzleEditor, MatcherEditor, MatrixEditor, MeasurerEditor, MoleculeWidgetEditor, NumberLineEditor, NumericInputEditor, OrdererEditor, PassageEditor, PassageRefEditor, PassageRefTargetEditor, PlotterEditor, ReactionDiagramWidgetEditor, SequenceEditor, SimpleMarkdownTesterEditor, SimulatorEditor, SorterEditor, TableEditor, UnitInputEditor, VideoEditor, RadioEditor, DeprecatedStandinEditor];
35357
34583
 
35358
34584
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
35359
34585
  class TextInput extends React__namespace.Component {
@@ -35581,6 +34807,8 @@ var AllWidgets = [...perseus.widgets, ...testingWidgets];
35581
34807
 
35582
34808
  perseus.Widgets.registerEditors(AllEditors);
35583
34809
  perseus.Widgets.registerWidgets(AllWidgets);
34810
+ perseus.Widgets.replaceEditor("transformer", "deprecated-standin");
34811
+ perseus.Widgets.replaceWidget("transformer", "deprecatd-standin");
35584
34812
 
35585
34813
  exports.AllEditors = AllEditors;
35586
34814
  exports.AllWidgets = AllWidgets;