@khanacademy/perseus 19.8.0 → 20.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/index.js CHANGED
@@ -29,7 +29,7 @@ import { Strut } from '@khanacademy/wonder-blocks-layout';
29
29
  import Banner from '@khanacademy/wonder-blocks-banner';
30
30
  import { OptionItem, SingleSelect, MultiSelect } from '@khanacademy/wonder-blocks-dropdown';
31
31
  import debounce$1 from 'lodash.debounce';
32
- import { vec, Line as Line$4, MovablePoint as MovablePoint$6, Coordinates, Mafs } from 'mafs';
32
+ import { vec, Line as Line$3, MovablePoint as MovablePoint$5, Coordinates, Mafs } from 'mafs';
33
33
  import createReactClass from 'create-react-class';
34
34
  import Switch from '@khanacademy/wonder-blocks-switch';
35
35
  import { LabelMedium } from '@khanacademy/wonder-blocks-typography';
@@ -13697,7 +13697,7 @@ var GraphieClasses = {
13697
13697
  };
13698
13698
 
13699
13699
  const normalizeOptions$3 = InteractiveUtil.normalizeOptions;
13700
- const assert$8 = InteractiveUtil.assert;
13700
+ const assert$7 = InteractiveUtil.assert;
13701
13701
 
13702
13702
  // Default "props" and "state". Both are added to this.state.
13703
13703
  // However, properties in DEFAULT_PROPS are updated on `modify()`,
@@ -13854,7 +13854,7 @@ class Movable {
13854
13854
  * Simulates a mouse grab event on the movable object.
13855
13855
  */
13856
13856
  grab(coord) {
13857
- assert$8(point.is(coord));
13857
+ assert$7(point.is(coord));
13858
13858
  const graphie = this.graphie;
13859
13859
  const state = this.state;
13860
13860
  state.isHovering = true;
@@ -14340,7 +14340,7 @@ var objective_ = {
14340
14340
  /**
14341
14341
  * MovableLine
14342
14342
  */
14343
- const assert$7 = InteractiveUtil.assert;
14343
+ const assert$6 = InteractiveUtil.assert;
14344
14344
  const normalizeOptions$2 = InteractiveUtil.normalizeOptions;
14345
14345
 
14346
14346
  // Default "props" and "state". Both are added to this.state and
@@ -14364,9 +14364,9 @@ const DEFAULT_STATE$2 = {
14364
14364
  visibleShape: null,
14365
14365
  mouseTarget: null
14366
14366
  };
14367
- const MovableLine$4 = function MovableLine(graphie, movable, options) {
14368
- assert$7(graphie != null);
14369
- assert$7(options != null);
14367
+ const MovableLine$3 = function MovableLine(graphie, movable, options) {
14368
+ assert$6(graphie != null);
14369
+ assert$6(options != null);
14370
14370
 
14371
14371
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
14372
14372
  _.extend(this, {
@@ -14382,10 +14382,10 @@ const MovableLine$4 = function MovableLine(graphie, movable, options) {
14382
14382
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
14383
14383
  this.modify(_.extend({}, DEFAULT_STATE$2, options));
14384
14384
  };
14385
- _.extend(MovableLine$4, MovableLineOptions);
14386
- InteractiveUtil.createGettersFor(MovableLine$4, _.extend({}, DEFAULT_PROPS$2, DEFAULT_STATE$2));
14387
- InteractiveUtil.addMovableHelperMethodsTo(MovableLine$4);
14388
- _.extend(MovableLine$4.prototype, {
14385
+ _.extend(MovableLine$3, MovableLineOptions);
14386
+ InteractiveUtil.createGettersFor(MovableLine$3, _.extend({}, DEFAULT_PROPS$2, DEFAULT_STATE$2));
14387
+ InteractiveUtil.addMovableHelperMethodsTo(MovableLine$3);
14388
+ _.extend(MovableLine$3.prototype, {
14389
14389
  cloneState: function () {
14390
14390
  return _.extend(this.movable.cloneState(), {
14391
14391
  coords: this.coords()
@@ -14927,7 +14927,7 @@ var MovablePointOptions = {
14927
14927
  }
14928
14928
  };
14929
14929
 
14930
- const assert$6 = InteractiveUtil.assert;
14930
+ const assert$5 = InteractiveUtil.assert;
14931
14931
  const normalizeOptions$1 = InteractiveUtil.normalizeOptions;
14932
14932
  const {
14933
14933
  processMath
@@ -14962,7 +14962,7 @@ const DEFAULT_STATE$1 = {
14962
14962
  // TODO(benchristel): this is a memory leak. We add items to
14963
14963
  // tooltipResetFunctions, but never remove them.
14964
14964
  const tooltipResetFunctions = [];
14965
- class MovablePoint$5 {
14965
+ class MovablePoint$4 {
14966
14966
  constructor(graphie, movable, options) {
14967
14967
  this.graphie = void 0;
14968
14968
  this.movable = void 0;
@@ -15004,7 +15004,7 @@ class MovablePoint$5 {
15004
15004
  const self = this;
15005
15005
  const graphie = self.graphie;
15006
15006
  const state = _.extend(self.state, normalizeOptions$1(options));
15007
- assert$6(point.is(state.coord));
15007
+ assert$5(point.is(state.coord));
15008
15008
 
15009
15009
  // Default things inside the state.normalStyle object, because
15010
15010
  // _.extend is not deep.
@@ -15300,12 +15300,12 @@ class MovablePoint$5 {
15300
15300
  return this.state.coord;
15301
15301
  }
15302
15302
  setCoord(coord) {
15303
- assert$6(point.is(coord, 2));
15303
+ assert$5(point.is(coord, 2));
15304
15304
  this.state.coord = _.clone(coord);
15305
15305
  this.draw();
15306
15306
  }
15307
15307
  setCoordConstrained(coord) {
15308
- assert$6(point.is(coord, 2));
15308
+ assert$5(point.is(coord, 2));
15309
15309
  const result = this._applyConstraints(coord, this.coord());
15310
15310
  if (result !== false) {
15311
15311
  this.state.coord = _.clone(result);
@@ -15479,15 +15479,15 @@ class MovablePoint$5 {
15479
15479
  this.movable.toFront();
15480
15480
  }
15481
15481
  }
15482
- MovablePoint$5.add = MovablePointOptions.add;
15483
- MovablePoint$5.modify = MovablePointOptions.modify;
15484
- MovablePoint$5.draw = MovablePointOptions.draw;
15485
- MovablePoint$5.remove = MovablePointOptions.remove;
15486
- MovablePoint$5.onMoveStart = MovablePointOptions.onMoveStart;
15487
- MovablePoint$5.constraints = MovablePointOptions.constraints;
15488
- MovablePoint$5.onMove = MovablePointOptions.onMove;
15489
- MovablePoint$5.onMoveEnd = MovablePointOptions.onMoveEnd;
15490
- MovablePoint$5.onClick = MovablePointOptions.onClick;
15482
+ MovablePoint$4.add = MovablePointOptions.add;
15483
+ MovablePoint$4.modify = MovablePointOptions.modify;
15484
+ MovablePoint$4.draw = MovablePointOptions.draw;
15485
+ MovablePoint$4.remove = MovablePointOptions.remove;
15486
+ MovablePoint$4.onMoveStart = MovablePointOptions.onMoveStart;
15487
+ MovablePoint$4.constraints = MovablePointOptions.constraints;
15488
+ MovablePoint$4.onMove = MovablePointOptions.onMove;
15489
+ MovablePoint$4.onMoveEnd = MovablePointOptions.onMoveEnd;
15490
+ MovablePoint$4.onClick = MovablePointOptions.onClick;
15491
15491
  function getKey(eventName, id) {
15492
15492
  return eventName + ":" + id;
15493
15493
  }
@@ -15813,7 +15813,7 @@ var MovablePolygonOptions = {
15813
15813
  * Creates and adds a polygon to the graph that can be dragged around.
15814
15814
  * It allows constraints on its movement and draws when moves happen.
15815
15815
  */
15816
- const assert$5 = InteractiveUtil.assert;
15816
+ const assert$4 = InteractiveUtil.assert;
15817
15817
  const normalizeOptions = InteractiveUtil.normalizeOptions;
15818
15818
 
15819
15819
  // Default "props" and "state". Both are added to this.state and
@@ -15848,8 +15848,8 @@ const DEFAULT_STATE = {
15848
15848
  mouseTarget: null
15849
15849
  };
15850
15850
  const MovablePolygon = function MovablePolygon(graphie, movable, options) {
15851
- assert$5(graphie != null);
15852
- assert$5(options != null);
15851
+ assert$4(graphie != null);
15852
+ assert$4(options != null);
15853
15853
 
15854
15854
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
15855
15855
  _.extend(this, {
@@ -16081,15 +16081,15 @@ _.extend(MovablePolygon.prototype, {
16081
16081
  });
16082
16082
 
16083
16083
  const Interactive2 = {
16084
- MovablePoint: MovablePoint$5,
16084
+ MovablePoint: MovablePoint$4,
16085
16085
  addMovablePoint: function (graphie, options) {
16086
16086
  const movable = new Movable(graphie, {});
16087
- return new MovablePoint$5(graphie, movable, options);
16087
+ return new MovablePoint$4(graphie, movable, options);
16088
16088
  },
16089
- MovableLine: MovableLine$4,
16089
+ MovableLine: MovableLine$3,
16090
16090
  addMovableLine: function (graphie, options) {
16091
16091
  const movable = new Movable(graphie, {});
16092
- return new MovableLine$4(graphie, movable, options);
16092
+ return new MovableLine$3(graphie, movable, options);
16093
16093
  },
16094
16094
  MovablePolygon: MovablePolygon,
16095
16095
  addMovablePolygon: function (graphie, options) {
@@ -16125,7 +16125,7 @@ const Interactive2 = {
16125
16125
  }
16126
16126
  };
16127
16127
 
16128
- const MovablePoint$4 = GraphieClasses.createClass({
16128
+ const MovablePoint$3 = GraphieClasses.createClass({
16129
16129
  displayName: "MovablePoint",
16130
16130
  movableProps: ["children"],
16131
16131
  _getProps: function () {
@@ -16182,8 +16182,8 @@ const MovablePoint$4 = GraphieClasses.createClass({
16182
16182
  });
16183
16183
 
16184
16184
  // Include helper methods, such as MovablePoint.constrain.snap()
16185
- _.extend(MovablePoint$4, Interactive2.MovablePoint);
16186
- const MovableLine$3 = GraphieClasses.createClass({
16185
+ _.extend(MovablePoint$3, Interactive2.MovablePoint);
16186
+ const MovableLine$2 = GraphieClasses.createClass({
16187
16187
  displayName: "MovableLine",
16188
16188
  movableProps: ["children"],
16189
16189
  add: function (graphie) {
@@ -16211,8 +16211,8 @@ const MovableLine$3 = GraphieClasses.createClass({
16211
16211
  });
16212
16212
 
16213
16213
  // Include helper methods, such as MovableLine.constrain.snap()
16214
- _.extend(MovableLine$3, Interactive2.MovableLine);
16215
- const Label$2 = GraphieClasses.createSimpleClass((graphie, props) => {
16214
+ _.extend(MovableLine$2, Interactive2.MovableLine);
16215
+ const Label$1 = GraphieClasses.createSimpleClass((graphie, props) => {
16216
16216
  let coord = props.coord;
16217
16217
  if (props.unscaled) {
16218
16218
  coord = graphie.unscalePoint(coord);
@@ -16231,7 +16231,7 @@ const Label$2 = GraphieClasses.createSimpleClass((graphie, props) => {
16231
16231
  }
16232
16232
  return elem;
16233
16233
  });
16234
- const Line$3 = GraphieClasses.createClass({
16234
+ const Line$2 = GraphieClasses.createClass({
16235
16235
  displayName: "Line",
16236
16236
  movableProps: ["children"],
16237
16237
  add: function (graphie) {
@@ -16309,7 +16309,7 @@ const Point$1 = GraphieClasses.createSimpleClass((graphie, props) => {
16309
16309
  stroke: props.color || KhanColors.BLACK
16310
16310
  });
16311
16311
  });
16312
- const Path$1 = GraphieClasses.createClass({
16312
+ const Path = GraphieClasses.createClass({
16313
16313
  displayName: "Path",
16314
16314
  movableProps: ["children"],
16315
16315
  add: function (graphie) {
@@ -16331,7 +16331,7 @@ const Path$1 = GraphieClasses.createClass({
16331
16331
  this.path.toFront();
16332
16332
  }
16333
16333
  });
16334
- const Arc$1 = GraphieClasses.createSimpleClass((graphie, props) => {
16334
+ const Arc = GraphieClasses.createSimpleClass((graphie, props) => {
16335
16335
  let center = props.center;
16336
16336
  let radius = props.radius;
16337
16337
  if (props.unscaled) {
@@ -16340,21 +16340,21 @@ const Arc$1 = GraphieClasses.createSimpleClass((graphie, props) => {
16340
16340
  }
16341
16341
  return graphie.arc(center, radius, props.startAngle, props.endAngle, props.sector, props.style);
16342
16342
  });
16343
- const Circle$1 = GraphieClasses.createSimpleClass((graphie, props) => {
16343
+ const Circle = GraphieClasses.createSimpleClass((graphie, props) => {
16344
16344
  return graphie.circle(props.center, props.radius, props.style);
16345
16345
  });
16346
16346
  const Rect$1 = GraphieClasses.createSimpleClass((graphie, props) => {
16347
16347
  return graphie.rect(props.x, props.y, props.width, props.height, props.style);
16348
16348
  });
16349
16349
  var Movables = {
16350
- Arc: Arc$1,
16351
- Circle: Circle$1,
16352
- Label: Label$2,
16353
- Line: Line$3,
16354
- MovableLine: MovableLine$3,
16355
- MovablePoint: MovablePoint$4,
16350
+ Arc: Arc,
16351
+ Circle: Circle,
16352
+ Label: Label$1,
16353
+ Line: Line$2,
16354
+ MovableLine: MovableLine$2,
16355
+ MovablePoint: MovablePoint$3,
16356
16356
  Parabola: Parabola,
16357
- Path: Path$1,
16357
+ Path: Path,
16358
16358
  Plot: Plot$2,
16359
16359
  PlotParametric: PlotParametric$1,
16360
16360
  Point: Point$1,
@@ -16369,7 +16369,7 @@ const {
16369
16369
  nestedMap
16370
16370
  } = Util;
16371
16371
  const {
16372
- assert: assert$4
16372
+ assert: assert$3
16373
16373
  } = InteractiveUtil;
16374
16374
  class Graphie extends React.Component {
16375
16375
  constructor(...args) {
@@ -16513,7 +16513,7 @@ class Graphie extends React.Component {
16513
16513
 
16514
16514
  // Instantiate the descriptor to turn it into a real Movable
16515
16515
  const child = new childDescriptor.type(childDescriptor.props);
16516
- assert$4(child instanceof GraphieMovable, "All children of a Graphie component must be Graphie " + "movables");
16516
+ assert$3(child instanceof GraphieMovable, "All children of a Graphie component must be Graphie " + "movables");
16517
16517
 
16518
16518
  // Give each child a key
16519
16519
  const keyProp = childDescriptor.key;
@@ -18716,6 +18716,13 @@ const replaceWidget = (name, replacementName) => {
18716
18716
  }
18717
18717
  registerWidget(name, substituteWidget);
18718
18718
  };
18719
+ const replaceDeprecatedWidgets = () => {
18720
+ replaceWidget("transformer", "deprecated-standin");
18721
+ replaceWidget("lights-puzzle", "deprecated-standin");
18722
+ replaceWidget("reaction-diagram", "deprecated-standin");
18723
+ replaceWidget("sequence", "deprecated-standin");
18724
+ replaceWidget("simulator", "deprecated-standin");
18725
+ };
18719
18726
  const registerEditors = editorsToRegister => {
18720
18727
  editorsToRegister.forEach(editor => {
18721
18728
  if (!editor.widgetName) {
@@ -18730,8 +18737,8 @@ const registerEditors = editorsToRegister => {
18730
18737
  * @param name - the widget that you are trying to replace
18731
18738
  * @param replacementName - the name of the widget that takes its place
18732
18739
  *
18733
- * e.g. replaceEditor("transformer", "always-correct") will make it so the
18734
- * transformer widget is replaced by the always correct widget
18740
+ * e.g. replaceEditor("transformer", "deprecated-standin") will make it so the
18741
+ * transformer widget is replaced by the deprecated stand-in widget
18735
18742
  */
18736
18743
  const replaceEditor = (name, replacementName) => {
18737
18744
  const substituteEditor = editors[replacementName];
@@ -18742,6 +18749,13 @@ const replaceEditor = (name, replacementName) => {
18742
18749
  }
18743
18750
  editors[name] = substituteEditor;
18744
18751
  };
18752
+ const replaceDeprecatedEditors = () => {
18753
+ replaceEditor("transformer", "deprecated-standin");
18754
+ replaceEditor("lights-puzzle", "deprecated-standin");
18755
+ replaceEditor("reaction-diagram", "deprecated-standin");
18756
+ replaceEditor("sequence", "deprecated-standin");
18757
+ replaceEditor("simulator", "deprecated-standin");
18758
+ };
18745
18759
  const getWidget = name => {
18746
18760
  // TODO(alex): Consider referring to these as renderers to avoid
18747
18761
  // overloading "widget"
@@ -18924,7 +18938,7 @@ const getRendererPropsForWidgetInfo = (widgetInfo, problemNum) => {
18924
18938
  // widgetInfo.options are the widgetEditor's props:
18925
18939
  return transform(widgetInfo.options, problemNum);
18926
18940
  };
18927
- const traverseChildWidgets$4 = (widgetInfo, traverseRenderer) => {
18941
+ const traverseChildWidgets$3 = (widgetInfo, traverseRenderer) => {
18928
18942
  if (!traverseRenderer) {
18929
18943
  throw new PerseusError("traverseRenderer must be provided, but was not", Errors.Internal);
18930
18944
  }
@@ -19053,8 +19067,10 @@ var widgets$1 = /*#__PURE__*/Object.freeze({
19053
19067
  registerWidget: registerWidget,
19054
19068
  registerWidgets: registerWidgets,
19055
19069
  replaceWidget: replaceWidget,
19070
+ replaceDeprecatedWidgets: replaceDeprecatedWidgets,
19056
19071
  registerEditors: registerEditors,
19057
19072
  replaceEditor: replaceEditor,
19073
+ replaceDeprecatedEditors: replaceDeprecatedEditors,
19058
19074
  getWidget: getWidget,
19059
19075
  getEditor: getEditor,
19060
19076
  getTransform: getTransform,
@@ -19065,7 +19081,7 @@ var widgets$1 = /*#__PURE__*/Object.freeze({
19065
19081
  getAllWidgetTypes: getAllWidgetTypes,
19066
19082
  upgradeWidgetInfoToLatestVersion: upgradeWidgetInfoToLatestVersion,
19067
19083
  getRendererPropsForWidgetInfo: getRendererPropsForWidgetInfo,
19068
- traverseChildWidgets: traverseChildWidgets$4,
19084
+ traverseChildWidgets: traverseChildWidgets$3,
19069
19085
  getSupportedAlignments: getSupportedAlignments,
19070
19086
  getDefaultAlignment: getDefaultAlignment,
19071
19087
  validateAlignments: validateAlignments,
@@ -21736,7 +21752,7 @@ const styles$z = StyleSheet.create({
21736
21752
  border: "solid 1px #999"
21737
21753
  }
21738
21754
  });
21739
- const propTransform$4 = widgetOptions => {
21755
+ const propTransform$3 = widgetOptions => {
21740
21756
  const {
21741
21757
  simplify,
21742
21758
  size,
@@ -21756,7 +21772,7 @@ var InputNumber$1 = {
21756
21772
  defaultAlignment: "inline-block",
21757
21773
  hidden: true,
21758
21774
  widget: InputNumber,
21759
- transform: propTransform$4,
21775
+ transform: propTransform$3,
21760
21776
  isLintable: true
21761
21777
  };
21762
21778
 
@@ -25353,7 +25369,7 @@ GradedGroup.defaultProps = {
25353
25369
  hasHint: false,
25354
25370
  linterContext: linterContextDefault
25355
25371
  };
25356
- const traverseChildWidgets$3 = function traverseChildWidgets(props, traverseRenderer) {
25372
+ const traverseChildWidgets$2 = function traverseChildWidgets(props, traverseRenderer) {
25357
25373
  return _.extend({}, props, traverseRenderer(props));
25358
25374
  };
25359
25375
  const styles$m = StyleSheet.create({
@@ -25409,7 +25425,7 @@ var GradedGroup$1 = {
25409
25425
  name: "graded-group",
25410
25426
  displayName: "Graded group (articles only)",
25411
25427
  widget: GradedGroup,
25412
- traverseChildWidgets: traverseChildWidgets$3,
25428
+ traverseChildWidgets: traverseChildWidgets$2,
25413
25429
  // TODO(aasmund): This widget should be available for articles only
25414
25430
  hidden: false,
25415
25431
  tracking: "all",
@@ -25571,7 +25587,7 @@ GradedGroupSet.defaultProps = {
25571
25587
  gradedGroups: [],
25572
25588
  linterContext: linterContextDefault
25573
25589
  };
25574
- const traverseChildWidgets$2 = function traverseChildWidgets(props, traverseRenderer) {
25590
+ const traverseChildWidgets$1 = function traverseChildWidgets(props, traverseRenderer) {
25575
25591
  // NOTE(jared): I have no idea how this works
25576
25592
  return {
25577
25593
  groups: props.gradedGroups.map(traverseRenderer)
@@ -25581,7 +25597,7 @@ var GradedGroupSet$1 = {
25581
25597
  name: "graded-group-set",
25582
25598
  displayName: "Graded group set (articles only)",
25583
25599
  widget: GradedGroupSet,
25584
- traverseChildWidgets: traverseChildWidgets$2,
25600
+ traverseChildWidgets: traverseChildWidgets$1,
25585
25601
  // TODO(michaelpolyak): This widget should be available for articles only
25586
25602
  hidden: false,
25587
25603
  tracking: "all",
@@ -26141,7 +26157,7 @@ function functionForType(
26141
26157
  type) {
26142
26158
  return functionTypeMapping[type];
26143
26159
  }
26144
- const validate$2 = (state, rubric) => {
26160
+ const validate$1 = (state, rubric) => {
26145
26161
  if (state.type !== rubric.correct.type) {
26146
26162
  return {
26147
26163
  type: "points",
@@ -26301,7 +26317,7 @@ var util = /*#__PURE__*/Object.freeze({
26301
26317
  DEFAULT_BACKGROUND_IMAGE: DEFAULT_BACKGROUND_IMAGE,
26302
26318
  allTypes: allTypes,
26303
26319
  functionForType: functionForType,
26304
- validate: validate$2,
26320
+ validate: validate$1,
26305
26321
  getEquationString: getEquationString,
26306
26322
  pointsFromNormalized: pointsFromNormalized,
26307
26323
  maybePointsFromNormalized: maybePointsFromNormalized,
@@ -26313,9 +26329,9 @@ var util = /*#__PURE__*/Object.freeze({
26313
26329
  });
26314
26330
 
26315
26331
  // @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
26316
- const MovablePoint$3 = Graphie.MovablePoint;
26332
+ const MovablePoint$2 = Graphie.MovablePoint;
26317
26333
  // @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
26318
- const MovableLine$2 = Graphie.MovableLine;
26334
+ const MovableLine$1 = Graphie.MovableLine;
26319
26335
  function isFlipped(newCoord, oldCoord, line) {
26320
26336
  const CCW = (a, b, c) => {
26321
26337
  return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]);
@@ -26370,7 +26386,7 @@ class FunctionGrapher extends React.Component {
26370
26386
  const dashed = {
26371
26387
  strokeDasharray: "- "
26372
26388
  };
26373
- return asymptote && /*#__PURE__*/React.createElement(MovableLine$2, {
26389
+ return asymptote && /*#__PURE__*/React.createElement(MovableLine$1, {
26374
26390
  onMove: (newCoord, oldCoord) => {
26375
26391
  // Calculate and apply displacement
26376
26392
  const delta = vector$1.subtract(newCoord, oldCoord);
@@ -26395,7 +26411,7 @@ class FunctionGrapher extends React.Component {
26395
26411
  }],
26396
26412
  normalStyle: dashed,
26397
26413
  highlightStyle: dashed
26398
- }, _.map(asymptote, (coord, i) => /*#__PURE__*/React.createElement(MovablePoint$3, {
26414
+ }, _.map(asymptote, (coord, i) => /*#__PURE__*/React.createElement(MovablePoint$2, {
26399
26415
  key: `asymptoteCoord-${i}`,
26400
26416
  coord: coord,
26401
26417
  static: true,
@@ -26410,7 +26426,7 @@ class FunctionGrapher extends React.Component {
26410
26426
  }
26411
26427
  render() {
26412
26428
  const pointForCoord = (coord, i) => {
26413
- return /*#__PURE__*/React.createElement(MovablePoint$3, {
26429
+ return /*#__PURE__*/React.createElement(MovablePoint$2, {
26414
26430
  key: i,
26415
26431
  coord: coord,
26416
26432
  static: this.props.static,
@@ -26662,21 +26678,21 @@ class Grapher extends React.Component {
26662
26678
  return tickStep;
26663
26679
  }
26664
26680
  simpleValidate(rubric) {
26665
- return validate$2(this.getUserInput(), rubric);
26681
+ return validate$1(this.getUserInput(), rubric);
26666
26682
  }
26667
26683
  getUserInput() {
26668
26684
  return Grapher.getUserInputFromProps(this.props);
26669
26685
  }
26670
26686
  focus() {}
26671
26687
  static validate(state, rubric) {
26672
- return validate$2(state, rubric);
26688
+ return validate$1(state, rubric);
26673
26689
  }
26674
26690
  static getUserInputFromProps(props) {
26675
26691
  return props.plot;
26676
26692
  }
26677
26693
  }
26678
26694
  Grapher.defaultProps = DEFAULT_GRAPHER_PROPS;
26679
- const propTransform$3 = editorProps => {
26695
+ const propTransform$2 = editorProps => {
26680
26696
  const widgetProps = {
26681
26697
  availableTypes: editorProps.availableTypes,
26682
26698
  graph: editorProps.graph
@@ -26695,7 +26711,7 @@ const propTransform$3 = editorProps => {
26695
26711
  // Note that in addition to the standard staticTransform, in static
26696
26712
  // mode we set static=true for the graph's handles in FunctionGrapher.
26697
26713
  const staticTransform$3 = editorProps => {
26698
- return _extends({}, propTransform$3(editorProps), {
26714
+ return _extends({}, propTransform$2(editorProps), {
26699
26715
  // Don't display graph type choices if we're in static mode
26700
26716
  availableTypes: [editorProps.correct.type],
26701
26717
  // Display the same graph marked as correct in the widget editor.
@@ -26706,7 +26722,7 @@ var Grapher$1 = {
26706
26722
  name: "grapher",
26707
26723
  displayName: "Grapher",
26708
26724
  widget: Grapher,
26709
- transform: propTransform$3,
26725
+ transform: propTransform$2,
26710
26726
  staticTransform: staticTransform$3
26711
26727
  };
26712
26728
 
@@ -26844,14 +26860,14 @@ Group.defaultProps = {
26844
26860
  images: {},
26845
26861
  linterContext: linterContextDefault
26846
26862
  };
26847
- const traverseChildWidgets$1 = function traverseChildWidgets(props, traverseRenderer) {
26863
+ const traverseChildWidgets = function traverseChildWidgets(props, traverseRenderer) {
26848
26864
  return _extends({}, props, traverseRenderer(props));
26849
26865
  };
26850
26866
  var Group$1 = {
26851
26867
  name: "group",
26852
26868
  displayName: "Group (SAT only)",
26853
26869
  widget: Group,
26854
- traverseChildWidgets: traverseChildWidgets$1,
26870
+ traverseChildWidgets: traverseChildWidgets,
26855
26871
  hidden: false,
26856
26872
  isLintable: true
26857
26873
  };
@@ -27018,7 +27034,7 @@ var Iframe$1 = {
27018
27034
  };
27019
27035
 
27020
27036
  /* eslint-disable react/sort-comp */
27021
- const defaultBoxSize$1 = 400;
27037
+ const defaultBoxSize = 400;
27022
27038
  const defaultRange = [0, 10];
27023
27039
  const defaultBackgroundImage$2 = {
27024
27040
  url: null,
@@ -27216,7 +27232,7 @@ ImageWidget.defaultProps = {
27216
27232
  alignment: DEFAULT_ALIGNMENT,
27217
27233
  title: "",
27218
27234
  range: [defaultRange, defaultRange],
27219
- box: [defaultBoxSize$1, defaultBoxSize$1],
27235
+ box: [defaultBoxSize, defaultBoxSize],
27220
27236
  backgroundImage: defaultBackgroundImage$2,
27221
27237
  labels: [],
27222
27238
  alt: "",
@@ -27240,13 +27256,13 @@ var Image$1 = {
27240
27256
 
27241
27257
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
27242
27258
  // @ts-expect-error - TS2339 - Property 'Label' does not exist on type 'typeof Graphie'.
27243
- const Label$1 = Graphie.Label;
27259
+ const Label = Graphie.Label;
27244
27260
  // @ts-expect-error - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
27245
- const Line$2 = Graphie.Line;
27261
+ const Line$1 = Graphie.Line;
27246
27262
  // @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
27247
- const MovablePoint$2 = Graphie.MovablePoint;
27263
+ const MovablePoint$1 = Graphie.MovablePoint;
27248
27264
  // @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
27249
- const MovableLine$1 = Graphie.MovableLine;
27265
+ const MovableLine = Graphie.MovableLine;
27250
27266
  // @ts-expect-error - TS2339 - Property 'Plot' does not exist on type 'typeof Graphie'.
27251
27267
  const Plot = Graphie.Plot;
27252
27268
  // @ts-expect-error - TS2339 - Property 'PlotParametric' does not exist on type 'typeof Graphie'.
@@ -27433,11 +27449,11 @@ class Interaction extends React.Component {
27433
27449
  options: this.props.graph,
27434
27450
  setup: this._setupGraphie,
27435
27451
  setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
27436
- }, this.props.graph.markings === "graph" && /*#__PURE__*/React.createElement(Label$1, {
27452
+ }, this.props.graph.markings === "graph" && /*#__PURE__*/React.createElement(Label, {
27437
27453
  coord: [0, range[1][1]],
27438
27454
  text: labels[1],
27439
27455
  direction: "above"
27440
- }), this.props.graph.markings === "graph" && /*#__PURE__*/React.createElement(Label$1, {
27456
+ }), this.props.graph.markings === "graph" && /*#__PURE__*/React.createElement(Label, {
27441
27457
  coord: [range[0][1], 0],
27442
27458
  text: labels[0],
27443
27459
  direction: "right"
@@ -27464,7 +27480,7 @@ class Interaction extends React.Component {
27464
27480
  this._eval(element.options.endX),
27465
27481
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
27466
27482
  this._eval(element.options.endY)];
27467
- return /*#__PURE__*/React.createElement(Line$2, {
27483
+ return /*#__PURE__*/React.createElement(Line$1, {
27468
27484
  key: element.key,
27469
27485
  start: start,
27470
27486
  end: end,
@@ -27493,7 +27509,7 @@ class Interaction extends React.Component {
27493
27509
  return [coordX, coordY];
27494
27510
  }];
27495
27511
  if (element.options.constraint === "snap") {
27496
- constraints.push(MovablePoint$2.constraints.snap(element.options.snap));
27512
+ constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
27497
27513
  } else if (element.options.constraint === "x") {
27498
27514
  constraints.push(coord => {
27499
27515
  return [
@@ -27515,7 +27531,7 @@ class Interaction extends React.Component {
27515
27531
  // TODO(eater): foo_[xyz] are hacky non-props to
27516
27532
  // get the component to update when constraints
27517
27533
  // change
27518
- return /*#__PURE__*/React.createElement(MovablePoint$2, {
27534
+ return /*#__PURE__*/React.createElement(MovablePoint$1, {
27519
27535
  key: element.key,
27520
27536
  coord: [
27521
27537
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
@@ -27550,7 +27566,7 @@ class Interaction extends React.Component {
27550
27566
  return [coordX, coordY];
27551
27567
  }];
27552
27568
  if (element.options.constraint === "snap") {
27553
- constraints.push(MovablePoint$2.constraints.snap(element.options.snap));
27569
+ constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
27554
27570
  } else if (element.options.constraint === "x") {
27555
27571
  constraints.push(coord => {
27556
27572
  return [
@@ -27578,7 +27594,7 @@ class Interaction extends React.Component {
27578
27594
  this.state.variables["x_" + element.options.endSubscript],
27579
27595
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
27580
27596
  this.state.variables["y_" + element.options.endSubscript]];
27581
- return /*#__PURE__*/React.createElement(MovableLine$1, {
27597
+ return /*#__PURE__*/React.createElement(MovableLine, {
27582
27598
  key: element.key,
27583
27599
  constraints: constraints
27584
27600
  // eslint-disable-next-line react/jsx-no-bind
@@ -27591,14 +27607,14 @@ class Interaction extends React.Component {
27591
27607
  foo_x: element.options.constraint,
27592
27608
  foo_y: element.options.constraintFn,
27593
27609
  foo_z: element.options.snap
27594
- }, /*#__PURE__*/React.createElement(MovablePoint$2, {
27610
+ }, /*#__PURE__*/React.createElement(MovablePoint$1, {
27595
27611
  coord: start,
27596
27612
  static: true,
27597
27613
  normalStyle: {
27598
27614
  stroke: "none",
27599
27615
  fill: "none"
27600
27616
  }
27601
- }), /*#__PURE__*/React.createElement(MovablePoint$2, {
27617
+ }), /*#__PURE__*/React.createElement(MovablePoint$1, {
27602
27618
  coord: end,
27603
27619
  static: true,
27604
27620
  normalStyle: {
@@ -27710,7 +27726,7 @@ class Interaction extends React.Component {
27710
27726
  this._eval(element.options.coordX),
27711
27727
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
27712
27728
  this._eval(element.options.coordY)];
27713
- return /*#__PURE__*/React.createElement(Label$1, {
27729
+ return /*#__PURE__*/React.createElement(Label, {
27714
27730
  key: n + 1,
27715
27731
  coord: coord,
27716
27732
  text: unescapeMathMode(element.options.label),
@@ -28213,22 +28229,22 @@ const SegmentGraph = props => {
28213
28229
  const SegmentView = props => {
28214
28230
  const [pt1, pt2] = props.segment;
28215
28231
  const midpoint = vec.midpoint(pt1, pt2);
28216
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Line$4.Segment, {
28232
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Line$3.Segment, {
28217
28233
  point1: pt1,
28218
28234
  point2: pt2
28219
- }), /*#__PURE__*/React.createElement(MovablePoint$6, {
28235
+ }), /*#__PURE__*/React.createElement(MovablePoint$5, {
28220
28236
  point: midpoint,
28221
28237
  color: Color.blue,
28222
28238
  onMove: newPoint => {
28223
28239
  props.onMoveSegment(vec.sub(newPoint, midpoint));
28224
28240
  }
28225
- }), /*#__PURE__*/React.createElement(MovablePoint$6, {
28241
+ }), /*#__PURE__*/React.createElement(MovablePoint$5, {
28226
28242
  point: pt1,
28227
28243
  color: Color.blue,
28228
28244
  onMove: newPoint => {
28229
28245
  props.onMovePoint(0, newPoint);
28230
28246
  }
28231
- }), /*#__PURE__*/React.createElement(MovablePoint$6, {
28247
+ }), /*#__PURE__*/React.createElement(MovablePoint$5, {
28232
28248
  point: pt2,
28233
28249
  color: Color.blue,
28234
28250
  onMove: newPoint => {
@@ -32890,276 +32906,6 @@ var LabelImage$1 = {
32890
32906
  isLintable: true
32891
32907
  };
32892
32908
 
32893
- /* eslint-disable @typescript-eslint/no-unused-vars, react/sort-comp */
32894
-
32895
- // Styling
32896
- const CELL_PADDING = 5;
32897
- const TABLE_STYLE = {
32898
- display: "table",
32899
- tableLayout: "fixed"
32900
- };
32901
- const ROW_STYLE = {
32902
- display: "table-row"
32903
- };
32904
- const CELL_STYLE = {
32905
- display: "table-cell",
32906
- padding: CELL_PADDING
32907
- };
32908
- const BASE_TILE_STYLE = {
32909
- borderRadius: 10,
32910
- cursor: "pointer"
32911
- };
32912
- const MOVE_COUNT_STYLE = {
32913
- padding: CELL_PADDING,
32914
- display: "inline-block"
32915
- };
32916
- const RESET_BUTTON_STYLE = {
32917
- float: "right",
32918
- paddingRight: CELL_PADDING
32919
- };
32920
- const MAIN_TILE_SIZE = 50;
32921
- const PATTERNS = {
32922
- plus: () => [[false, true, false], [true, true, true], [false, true, false]],
32923
- x: () => [[true, false, true], [false, true, false], [true, false, true]],
32924
- "plus/x": iter => {
32925
- return iter % 2 ? PATTERNS.x() : PATTERNS.plus();
32926
- }
32927
- };
32928
-
32929
- // A single glowy cell
32930
- class Tile extends React.Component {
32931
- constructor(...args) {
32932
- super(...args);
32933
- this._flip = () => {
32934
- // On change requires a value, but we don't actually have access
32935
- // to the coordinates here, so we just pass the inverse value as a workaround.
32936
- this.props.onChange({
32937
- value: !this.props.value
32938
- });
32939
- };
32940
- }
32941
- render() {
32942
- const color = this.props.value ? "#55dd55" : "#115511";
32943
- const style = _.extend({}, BASE_TILE_STYLE, {
32944
- width: this.props.size,
32945
- height: this.props.size,
32946
- backgroundColor: color
32947
- });
32948
- return /*#__PURE__*/React.createElement("div", {
32949
- style: style,
32950
- onClick: this._flip
32951
- });
32952
- }
32953
- }
32954
-
32955
- // A grid of glowy cells
32956
- Tile.propTypes = {
32957
- value: PropTypes.bool.isRequired,
32958
- size: PropTypes.number.isRequired
32959
- };
32960
- class TileGrid extends React.Component {
32961
- render() {
32962
- return /*#__PURE__*/React.createElement("div", {
32963
- style: TABLE_STYLE,
32964
- className: "no-select"
32965
- }, this.props.cells && _.map(this.props.cells, (row, y) => {
32966
- return /*#__PURE__*/React.createElement("div", {
32967
- key: y,
32968
- style: ROW_STYLE
32969
- }, _.map(row, (cell, x) => {
32970
- return /*#__PURE__*/React.createElement("div", {
32971
- key: x,
32972
- style: CELL_STYLE
32973
- }, /*#__PURE__*/React.createElement(Tile, {
32974
- value: cell,
32975
- size: this.props.size,
32976
- onChange: _.partial(this.props.onChange, {
32977
- value: {
32978
- y,
32979
- x
32980
- }
32981
- })
32982
- }));
32983
- }));
32984
- }));
32985
- }
32986
- }
32987
-
32988
- // Returns a copy of the tiles, with tiles flipped according to
32989
- // whether or not their y, x position satisfies the predicate
32990
- const flipTilesPredicate = (oldCells, predicate) => {
32991
- return _.map(oldCells, (row, y) => {
32992
- return _.map(row, (cell, x) => {
32993
- return predicate(y, x) ? !cell : cell;
32994
- });
32995
- });
32996
- };
32997
- const flipTilesPattern = (oldCells, tileY, tileX, pattern) => {
32998
- return flipTilesPredicate(oldCells, (y, x) => {
32999
- const offsetY = y - tileY;
33000
- const offsetX = x - tileX;
33001
- if (Math.abs(offsetY) <= 1 && Math.abs(offsetX) <= 1) {
33002
- return pattern[offsetY + 1][offsetX + 1];
33003
- }
33004
- return false;
33005
- });
33006
- };
33007
-
33008
- // The lights puzzle widget
33009
- class LightsPuzzle extends React.Component {
33010
- constructor(..._args) {
33011
- super(..._args);
33012
- this._currPattern = void 0;
33013
- this._nextPattern = void 0;
33014
- // @ts-expect-error - TS2564 - Property '_patternIndex' has no initializer and is not definitely assigned in the constructor.
33015
- this._patternIndex = void 0;
33016
- this.getUserInput = () => {
33017
- return WidgetJsonifyDeprecated.getUserInput.call(this);
33018
- };
33019
- this.change = (...args) => {
33020
- // @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
33021
- return change.apply(this, args);
33022
- };
33023
- this._width = () => {
33024
- if (this.props.cells && this.props.cells.length !== 0) {
33025
- return this.props.cells[0].length;
33026
- }
33027
- return 0; // default to 0
33028
- };
33029
- this._initNextPatterns = () => {
33030
- if (this.props.flipPattern) {
33031
- this._currPattern = PATTERNS[this.props.flipPattern](0);
33032
- this._nextPattern = PATTERNS[this.props.flipPattern](1);
33033
- }
33034
- this._patternIndex = 2;
33035
- };
33036
- this._shiftPatterns = () => {
33037
- if (this.props.flipPattern) {
33038
- this._currPattern = this._nextPattern;
33039
- this._nextPattern = PATTERNS[this.props.flipPattern](this._patternIndex);
33040
- this._patternIndex++;
33041
- }
33042
- };
33043
- this._flipTile = ({
33044
- value: {
33045
- y,
33046
- x
33047
- }
33048
- }) => {
33049
- const newCells = flipTilesPattern(this.props.cells, y, x, this._currPattern);
33050
- this._shiftPatterns();
33051
- this.change({
33052
- cells: newCells,
33053
- moveCount: (this.props.moveCount || 0) + 1
33054
- });
33055
- };
33056
- this._reset = () => {
33057
- this.change({
33058
- cells: this.props.startCells,
33059
- moveCount: 0
33060
- });
33061
- };
33062
- this.simpleValidate = rubric => {
33063
- return validate$1(rubric, this.getUserInput());
33064
- };
33065
- }
33066
- render() {
33067
- const width = this._width();
33068
- const tileSize = MAIN_TILE_SIZE;
33069
- const pxWidth = width * (tileSize + 2 * CELL_PADDING);
33070
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(TileGrid, {
33071
- cells: this.props.cells,
33072
- size: tileSize,
33073
- onChange: this._flipTile
33074
- }), /*#__PURE__*/React.createElement("div", {
33075
- style: {
33076
- width: pxWidth
33077
- }
33078
- }, /*#__PURE__*/React.createElement("div", {
33079
- style: MOVE_COUNT_STYLE
33080
- }, i18n.ngettext("Moves: %(num)s", "Moves: %(num)s", this.props.moveCount)), /*#__PURE__*/React.createElement("div", {
33081
- style: RESET_BUTTON_STYLE
33082
- }, /*#__PURE__*/React.createElement("input", {
33083
- type: "button",
33084
- value: "Reset",
33085
- onClick: this._reset,
33086
- className: "simple-button"
33087
- }))), /*#__PURE__*/React.createElement("div", {
33088
- className: "clearfix"
33089
- }));
33090
- }
33091
- componentDidMount() {
33092
- this._initNextPatterns();
33093
- }
33094
- componentDidUpdate(prevProps) {
33095
- if (prevProps.flipPattern !== this.props.flipPattern) {
33096
- this._initNextPatterns();
33097
- }
33098
- }
33099
- }
33100
-
33101
- // grading function
33102
- LightsPuzzle.defaultProps = {
33103
- cells: [[false, false, false], [false, false, false], [false, false, false]],
33104
- startCells: [[false, false, false], [false, false, false], [false, false, false]],
33105
- flipPattern: "plus",
33106
- moveCount: 0
33107
- };
33108
- const validate$1 = function validate(rubric, state) {
33109
- const empty = _.all(state.cells, (row, y) => {
33110
- return _.all(row, (cell, x) => {
33111
- return cell === rubric.startCells[y][x];
33112
- });
33113
- });
33114
- if (empty) {
33115
- return {
33116
- type: "invalid",
33117
- message: i18n._("Click on the tiles to change the lights.")
33118
- };
33119
- }
33120
- const correct = _.all(state.cells, row => {
33121
- return _.all(row, cell => {
33122
- return cell;
33123
- });
33124
- });
33125
- if (correct) {
33126
- return {
33127
- type: "points",
33128
- earned: 1,
33129
- total: 1,
33130
- message: null
33131
- };
33132
- }
33133
- if (rubric.gradeIncompleteAsWrong) {
33134
- return {
33135
- type: "points",
33136
- earned: 0,
33137
- total: 1,
33138
- message: null
33139
- };
33140
- }
33141
- return {
33142
- type: "invalid",
33143
- message: i18n._("You must turn on all of the lights to continue.")
33144
- };
33145
- };
33146
-
33147
- // The function run on the editor props to create the widget props
33148
- const transformProps = function transformProps(editorProps) {
33149
- return {
33150
- cells: editorProps.startCells,
33151
- startCells: editorProps.startCells,
33152
- flipPattern: editorProps.flipPattern
33153
- };
33154
- };
33155
- var LightsPuzzle$1 = {
33156
- name: "lights-puzzle",
33157
- displayName: "Lights puzzle (deprecated)",
33158
- hidden: true,
33159
- widget: LightsPuzzle,
33160
- transform: transformProps
33161
- };
33162
-
33163
32909
  let Layout = /*#__PURE__*/function (Layout) {
33164
32910
  Layout["HORIZONTAL"] = "horizontal";
33165
32911
  Layout["VERTICAL"] = "vertical";
@@ -34105,7 +33851,7 @@ var Matcher$1 = {
34105
33851
  // Type imports
34106
33852
 
34107
33853
  const {
34108
- assert: assert$3
33854
+ assert: assert$2
34109
33855
  } = InteractiveUtil;
34110
33856
  const {
34111
33857
  stringArrayOfSize
@@ -34139,12 +33885,12 @@ const getDefaultPath$1 = function getDefaultPath() {
34139
33885
  };
34140
33886
  const getRowFromPath$1 = function getRowFromPath(path) {
34141
33887
  // 'path' should be a (row, column) pair
34142
- assert$3(_.isArray(path) && path.length === 2);
33888
+ assert$2(_.isArray(path) && path.length === 2);
34143
33889
  return +path[0];
34144
33890
  };
34145
33891
  const getColumnFromPath$1 = function getColumnFromPath(path) {
34146
33892
  // 'path' should be a (row, column) pair
34147
- assert$3(_.isArray(path) && path.length === 2);
33893
+ assert$2(_.isArray(path) && path.length === 2);
34148
33894
  return +path[1];
34149
33895
  };
34150
33896
  const getRefForPath$1 = function getRefForPath(path) {
@@ -34541,7 +34287,7 @@ _.extend(Matrix, {
34541
34287
  };
34542
34288
  }
34543
34289
  });
34544
- const propTransform$2 = editorProps => {
34290
+ const propTransform$1 = editorProps => {
34545
34291
  // Remove answers before passing to widget
34546
34292
  const blankAnswers = _(editorProps.matrixBoardSize[0]).times(function () {
34547
34293
  return stringArrayOfSize(editorProps.matrixBoardSize[1]);
@@ -34566,7 +34312,7 @@ var Matrix$1 = {
34566
34312
  name: "matrix",
34567
34313
  displayName: "Matrix",
34568
34314
  widget: Matrix,
34569
- transform: propTransform$2,
34315
+ transform: propTransform$1,
34570
34316
  staticTransform: staticTransform$2,
34571
34317
  isLintable: true
34572
34318
  };
@@ -35636,11 +35382,11 @@ var Molecule$1 = {
35636
35382
  };
35637
35383
 
35638
35384
  // @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
35639
- const MovablePoint$1 = Graphie.MovablePoint;
35385
+ const MovablePoint = Graphie.MovablePoint;
35640
35386
  // @ts-expect-error - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
35641
- const Line$1 = Graphie.Line;
35387
+ const Line = Graphie.Line;
35642
35388
  const {
35643
- assert: assert$2
35389
+ assert: assert$1
35644
35390
  } = InteractiveUtil;
35645
35391
  const bound = (x, gt, lt) => Math.min(Math.max(x, gt), lt);
35646
35392
  const EN_DASH = "\u2013";
@@ -35898,7 +35644,7 @@ class NumberLine extends React.Component {
35898
35644
  const snapX = props.tickStep / props.snapDivisions;
35899
35645
  let x = bound(numLinePosition, left, right);
35900
35646
  x = left + number.roundTo(x - left, snapX);
35901
- assert$2(_.isFinite(x));
35647
+ assert$1(_.isFinite(x));
35902
35648
  return x;
35903
35649
  };
35904
35650
  // This function is intended to be used by the client code
@@ -35936,7 +35682,7 @@ class NumberLine extends React.Component {
35936
35682
  stroke: KhanColors.INTERACTIVE,
35937
35683
  "fill-opacity": isOpen ? 0 : 1
35938
35684
  } : {};
35939
- return /*#__PURE__*/React.createElement(MovablePoint$1
35685
+ return /*#__PURE__*/React.createElement(MovablePoint
35940
35686
  // eslint-disable-next-line react/no-string-refs
35941
35687
  , {
35942
35688
  ref: "numberLinePoint",
@@ -35995,7 +35741,7 @@ class NumberLine extends React.Component {
35995
35741
  strokeWidth: 3.5
35996
35742
  };
35997
35743
  const isGreater = ["ge", "gt"].includes(props.rel);
35998
- return /*#__PURE__*/React.createElement(Line$1
35744
+ return /*#__PURE__*/React.createElement(Line
35999
35745
  // We shift the line to either side of the dot so they don't
36000
35746
  // intersect
36001
35747
  , {
@@ -39881,803 +39627,6 @@ var PythonProgram$1 = {
39881
39627
  widget: PythonProgram
39882
39628
  };
39883
39629
 
39884
- class Separator extends React.Component {
39885
- constructor(...args) {
39886
- super(...args);
39887
- this.arrowLength = 100;
39888
- this.drawArrow = () => {
39889
- // eslint-disable-next-line react/no-string-refs
39890
- const canvas = this.refs["arrowCanvas" + this.props.index];
39891
- // @ts-expect-error - TS2339 - Property 'getContext' does not exist on type 'ReactInstance'.
39892
- const ctx = canvas.getContext("2d");
39893
- // @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
39894
- ctx.clearRect(0, 0, canvas.width, canvas.height);
39895
- const path = new Path2D();
39896
- ctx.strokeStyle = "rgb(0,0,0)";
39897
- ctx.lineWidth = 1.2;
39898
- ctx.lineCap = "round";
39899
- const offset = 5;
39900
- // @ts-expect-error - TS2339 - Property 'height' does not exist on type 'ReactInstance'.
39901
- path.moveTo(offset, canvas.height / 2);
39902
- // @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
39903
- path.lineTo(canvas.width - offset, canvas.height / 2);
39904
- // @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
39905
- path.moveTo(canvas.width - 2 * offset, canvas.height / 2 - offset);
39906
- // @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
39907
- path.lineTo(canvas.width - offset, canvas.height / 2);
39908
- // @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
39909
- path.moveTo(canvas.width - 2 * offset, canvas.height / 2 + offset);
39910
- // @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
39911
- path.lineTo(canvas.width - offset, canvas.height / 2);
39912
- ctx.stroke(path);
39913
- };
39914
- }
39915
- componentDidMount() {
39916
- this.drawArrow();
39917
- }
39918
- componentDidUpdate() {
39919
- this.drawArrow();
39920
- }
39921
- render() {
39922
- return /*#__PURE__*/React.createElement("div", {
39923
- className: "arrow-container"
39924
- }, /*#__PURE__*/React.createElement("div", {
39925
- className: "above-text"
39926
- }, this.props.data.topText), /*#__PURE__*/React.createElement("canvas", {
39927
- height: "30",
39928
- id: "arrowCanvas" + this.props.index,
39929
- ref: "arrowCanvas" + this.props.index,
39930
- width: this.arrowLength
39931
- }, i18n._("Reaction arrow pointing to the right.")), /*#__PURE__*/React.createElement("div", {
39932
- className: "below-text"
39933
- }, this.props.data.bottomText));
39934
- }
39935
- }
39936
- class ReactionDiagramWidget extends React.Component {
39937
- constructor(...args) {
39938
- super(...args);
39939
- this.simpleValidate = () => {
39940
- return {
39941
- type: "points",
39942
- earned: 0,
39943
- total: 0,
39944
- message: null
39945
- };
39946
- };
39947
- this.getUserInput = () => {
39948
- return [];
39949
- };
39950
- this.validate = (state, rubric) => {
39951
- // TODO(colin): this appears to be part of the perseus interface.
39952
- // Figure out if there's a more appropriate value to return.
39953
- return {
39954
- type: "points",
39955
- earned: 0,
39956
- total: 0,
39957
- message: null
39958
- };
39959
- };
39960
- this.focus = () => {
39961
- return true;
39962
- };
39963
- }
39964
- render() {
39965
- return (
39966
- /*#__PURE__*/
39967
- // eslint-disable-next-line react/no-string-refs
39968
- React.createElement("div", {
39969
- className: "reaction",
39970
- ref: "reaction"
39971
- }, this.props.smiles.map((s, i) => {
39972
- const id = this.props.widgetId + "-" + i;
39973
- return /*#__PURE__*/React.createElement("div", {
39974
- key: id,
39975
- className: "molecule-container"
39976
- }, /*#__PURE__*/React.createElement(Molecule, {
39977
- widgetId: id,
39978
- rotationAngle: this.props.rotationAngle[i],
39979
- smiles: s
39980
- }), i === this.props.smiles.length - 1 ? null : /*#__PURE__*/React.createElement(Separator, {
39981
- data: this.props.separators[i],
39982
- index: i
39983
- }));
39984
- }))
39985
- );
39986
- }
39987
- }
39988
- ReactionDiagramWidget.defaultProps = {
39989
- smiles: [],
39990
- rotationAngle: [],
39991
- separators: []
39992
- };
39993
- var ReactionDiagram = {
39994
- name: "reaction-diagram",
39995
- displayName: "Chemical reaction diagram (deprecated)",
39996
- hidden: true,
39997
- widget: ReactionDiagramWidget
39998
- };
39999
-
40000
- class Sequence extends React.Component {
40001
- constructor(..._args) {
40002
- super(..._args);
40003
- this.state = {
40004
- visible: 1
40005
- };
40006
- this.change = (...args) => {
40007
- return change.apply(this, args);
40008
- };
40009
- this._handleInteraction = groupWidgetId => {
40010
- const step = parseInt(groupWidgetId.split(" ")[1]);
40011
- if (step === this.state.visible - 1) {
40012
- // eslint-disable-next-line react/no-string-refs
40013
- // @ts-expect-error - TS2339 - Property 'getWidgetInstance' does not exist on type 'ReactInstance'.
40014
- const widget = this.refs.renderer.getWidgetInstance("group " + step);
40015
- widget.showRationalesForCurrentlySelectedChoices();
40016
- const score = widget.simpleValidate();
40017
- if (score.type === "points" && score.total === score.earned) {
40018
- this.setState({
40019
- visible: this.state.visible + 1
40020
- });
40021
- this.props.trackInteraction({
40022
- visible: this.state.visible + 1
40023
- });
40024
- }
40025
- }
40026
- };
40027
- }
40028
- shouldComponentUpdate(nextProps, nextState) {
40029
- return nextProps !== this.props || nextState !== this.state;
40030
- }
40031
- render() {
40032
- const icon = /*#__PURE__*/React.createElement(InlineIcon, _extends({}, iconOk, {
40033
- style: {
40034
- color: "green"
40035
- }
40036
- }));
40037
- const content = _.chain(this.props.json).first(this.state.visible).map((step, i) => `[[${Util.snowman} group ${i}]]`).join("\n\n").value();
40038
- const widgets = {};
40039
- _.each(this.props.json, (step, i) => {
40040
- const widgetId = `group ${i}`;
40041
- widgets[widgetId] = {
40042
- type: "group",
40043
- graded: true,
40044
- version: {
40045
- major: 0,
40046
- minor: 0
40047
- },
40048
- options: _.extend({}, step, {
40049
- icon: i < this.state.visible - 1 ? icon : null
40050
- })
40051
- };
40052
- });
40053
- return /*#__PURE__*/React.createElement("div", {
40054
- className: "perseus-sequence"
40055
- }, /*#__PURE__*/React.createElement(Renderer
40056
- // eslint-disable-next-line react/no-string-refs
40057
- , {
40058
- ref: "renderer",
40059
- content: content,
40060
- widgets: widgets,
40061
- onInteractWithWidget: this._handleInteraction,
40062
- apiOptions: this.props.apiOptions,
40063
- linterContext: this.props.linterContext
40064
- }));
40065
- }
40066
- }
40067
- Sequence.defaultProps = {
40068
- json: [{
40069
- content: "",
40070
- widgets: {},
40071
- images: {}
40072
- }],
40073
- linterContext: linterContextDefault
40074
- };
40075
- const traverseChildWidgets = function traverseChildWidgets(props, traverseRenderer) {
40076
- let oldJson = props.json;
40077
- if (!_.isArray(oldJson)) {
40078
- oldJson = [oldJson];
40079
- }
40080
- const json = _.map(oldJson, rendererOptions => {
40081
- return traverseRenderer(rendererOptions);
40082
- });
40083
- return _.extend({}, props, {
40084
- json: json
40085
- });
40086
- };
40087
- var Sequence$1 = {
40088
- name: "sequence",
40089
- displayName: "Graded sequence (deprecated)",
40090
- widget: Sequence,
40091
- traverseChildWidgets: traverseChildWidgets,
40092
- tracking: "all",
40093
- hidden: true,
40094
- isLintable: true
40095
- };
40096
-
40097
- const {
40098
- assert: assert$1
40099
- } = InteractiveUtil;
40100
- // @ts-expect-error - TS2339 - Property 'Path' does not exist on type 'typeof Graphie'. | TS2339 - Property 'Arc' does not exist on type 'typeof Graphie'. | TS2339 - Property 'Circle' does not exist on type 'typeof Graphie'. | TS2339 - Property 'Label' does not exist on type 'typeof Graphie'. | TS2339 - Property 'Line' does not exist on type 'typeof Graphie'. | TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'. | TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
40101
- const {
40102
- Path,
40103
- Arc,
40104
- Circle,
40105
- Label,
40106
- Line,
40107
- MovablePoint,
40108
- MovableLine
40109
- } = Graphie;
40110
- const defaultBoxSize = 400;
40111
- const maxSampleSize = 1000;
40112
- class Histogram extends React.Component {
40113
- constructor(...args) {
40114
- super(...args);
40115
- /* Renders the vertical line that users can drag across the histogram. */
40116
- this._renderThresholdLine = () => {
40117
- // Recall the the y-range goes from [-1, yMax] to allow for ticks on
40118
- // the x-axis.
40119
- // @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
40120
- const yRange = [0, this._range()[1][1]];
40121
- const coords = _.map(yRange, y => [this.state.threshold, y]);
40122
-
40123
- // Returns an inivisble, placeholder coord that anchors the line
40124
- const invisiblePointForCoord = (coord, i) => {
40125
- return /*#__PURE__*/React.createElement(MovablePoint, {
40126
- key: i,
40127
- static: true,
40128
- coord: coord,
40129
- normalStyle: {
40130
- stroke: "none",
40131
- fill: "none"
40132
- }
40133
- });
40134
- };
40135
- return /*#__PURE__*/React.createElement(MovableLine, {
40136
- onMove: this.handleMouseInteraction
40137
- }, _.map(coords, invisiblePointForCoord));
40138
- };
40139
- /* Renders the shaded circle in the top right. */
40140
- this._renderCircle = () => {
40141
- const data = this.props.data;
40142
-
40143
- // Get proportion of results below threshold
40144
- const total = _.reduce(data, (sum, next) => {
40145
- return sum + next;
40146
- }, 0);
40147
- const numBelow = _.reduce(data, (sum, next, i) => {
40148
- if (this.state.threshold != null && i <= this.state.threshold) {
40149
- return sum + next;
40150
- }
40151
- return sum;
40152
- }, 0);
40153
- const proportionBelow = numBelow / total;
40154
-
40155
- // This is a hack around the arc taking angles modulo 360.
40156
- // TODO(charlie): Find a better way around this.
40157
- const epsilon = 1e-5;
40158
- const radius = 20;
40159
- const center = [this.props.box[0] - 1.5 * radius, 1.5 * radius];
40160
-
40161
- // Plot little circle
40162
- const plotBelowCircle = () => {
40163
- const options = {
40164
- key: "below",
40165
- center: center,
40166
- radius: radius,
40167
- startAngle: 0,
40168
- endAngle: proportionBelow < 1 ? 360 * proportionBelow : 360 - epsilon,
40169
- sector: proportionBelow !== 1,
40170
- unscaled: true,
40171
- style: {
40172
- fill: KhanColors.LIGHT_RED,
40173
- stroke: KhanColors.RED
40174
- }
40175
- };
40176
- return /*#__PURE__*/React.createElement(Arc, options);
40177
- };
40178
- const plotAboveCircle = () => {
40179
- const options = {
40180
- key: "above",
40181
- center: center,
40182
- radius: radius,
40183
- startAngle: proportionBelow > 0 ? 360 * proportionBelow : epsilon,
40184
- endAngle: 360,
40185
- sector: proportionBelow !== 0,
40186
- unscaled: true,
40187
- style: {
40188
- fill: KhanColors.LIGHT_BLUE,
40189
- stroke: KhanColors.BLUE
40190
- }
40191
- };
40192
- return /*#__PURE__*/React.createElement(Arc, options);
40193
- };
40194
-
40195
- // Plot the label below the circle
40196
- // @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
40197
- const xRange = this._range()[0];
40198
- const formattedThreshold = Math.min(Math.max(this.state.threshold, xRange[0]), xRange[1]).toFixed(2);
40199
- const plotLabel = () => {
40200
- const options = {
40201
- key: "label",
40202
- coord: [center[0], center[1] + 1.5 * radius],
40203
- text: numBelow + " of " + total + " results below " + formattedThreshold + "%",
40204
- direction: "center",
40205
- tex: false,
40206
- unscaled: true,
40207
- style: {
40208
- fontSize: "12px"
40209
- }
40210
- };
40211
- return /*#__PURE__*/React.createElement(Label, options);
40212
- };
40213
- return [proportionBelow > 0 && plotBelowCircle(), proportionBelow < 1 && plotAboveCircle(), plotLabel()];
40214
- };
40215
- /* Renders the actual bars of the histogram. */
40216
- this._renderData = () => {
40217
- const data = this.props.data;
40218
- // @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
40219
- this._range();
40220
-
40221
- // Plot bars
40222
- const barWidth = 1;
40223
- const pathForData = (count, i) => {
40224
- // Avoid plotting bars of height 0, else you get a thick blue line
40225
- // over the x-axis. We don't filter these out of the data passed in
40226
- // to this function, however, to preserve absolute indices.
40227
- if (!count) {
40228
- return;
40229
- }
40230
- const isBelow = this.state.threshold != null && i <= this.state.threshold;
40231
- const style = {
40232
- fill: isBelow ? KhanColors.LIGHT_RED : KhanColors.LIGHT_BLUE,
40233
- stroke: isBelow ? KhanColors.RED : KhanColors.BLUE
40234
- };
40235
- const coords = [[i, 0], [i, count], [i + barWidth, count], [i + barWidth, 0]];
40236
- return /*#__PURE__*/React.createElement(Path, {
40237
- key: i,
40238
- coords: coords,
40239
- style: style
40240
- });
40241
- };
40242
- return _.map(data, pathForData);
40243
- };
40244
- this._setupGraphie = (graphie, options) => {
40245
- const data = options.data;
40246
- const range = options.range;
40247
- const scale = options.scale;
40248
-
40249
- /* Plot the bars that run parallel to the x-axis. */
40250
- const xWidth = range[0][1] - range[0][0];
40251
- const yWidth = range[1][1] - 0;
40252
- const maxYAxisEntities = 20;
40253
- const ySkip = Math.ceil(yWidth / maxYAxisEntities);
40254
- _.each(_.range(0, range[1][1], ySkip), y => {
40255
- // If there's no data, we don't label the axes
40256
- if (data) {
40257
- graphie.label([range[0][0], y], KhanMath.roundToApprox(y, 2), "left", /* isTeX */true /* for the \approx symbol */);
40258
- }
40259
-
40260
- graphie.line([range[0][0], y], [range[0][1], y], {
40261
- stroke: "#000",
40262
- strokeWidth: 1,
40263
- opacity: 0.3
40264
- });
40265
- });
40266
-
40267
- // If there's no data, we don't label the x-axis at all
40268
- if (data) {
40269
- // Plot the labels below the bars
40270
- const maxXAxisEntities = 15;
40271
- const xSkip = Math.ceil(xWidth / maxXAxisEntities);
40272
- _.each(_.range(range[0][0], range[0][1], xSkip), x => {
40273
- graphie.label([x, 0], number.round(x, 2), "below", true);
40274
- const tickHeight = 8;
40275
- graphie.line([x, 0], [x, -tickHeight / scale[1]], {
40276
- stroke: "#000",
40277
- strokeWidth: 1
40278
- });
40279
- });
40280
- }
40281
-
40282
- // Add y axis (x axis is added later to overlap the bars)
40283
- const axisStyle = {
40284
- stroke: "#000",
40285
- strokeWidth: 2,
40286
- opacity: 1.0
40287
- };
40288
- const origin = [range[0][0], 0];
40289
- const topLeft = [range[0][0], range[1][1]];
40290
- graphie.line(origin, topLeft, axisStyle);
40291
-
40292
- // Add axis labels
40293
- const xMid = range[0][0] + xWidth / 2;
40294
- const xOffset = data ? 25 : 0;
40295
- graphie.label([xMid, -xOffset / scale[1]], options.xAxisLabel, "below", false).css("font-weight", "bold");
40296
- const yMid = 0 + yWidth / 2;
40297
- const yOffset = data ? 55 : 28;
40298
- graphie.label([range[0][0] - yOffset / scale[0], yMid], options.yAxisLabel, "center", false).css("font-weight", "bold").css("-webkit-transform", "rotate(-90deg)");
40299
- };
40300
- this.handleMouseInteraction = point => {
40301
- this.setState({
40302
- threshold: point[0]
40303
- });
40304
- };
40305
- /* Convenience functions that help calculate props based on other props. */
40306
- this._range = props => {
40307
- const defaultRange = [[0, 100], [-1, 10]];
40308
- props = props || this.props;
40309
- return props.data ? this._getRangeForData(props.data) : defaultRange;
40310
- };
40311
- this._getRangeForData = data => {
40312
- // Find first/last non-zero entry and add some padding
40313
- const padding = 10;
40314
- const firstIndex = _.indexOf(data, _.find(data, n => n > 0));
40315
- const xMin = Math.max(0, firstIndex - padding);
40316
- const lastIndex = _.lastIndexOf(data, _.last(_.filter(data, n => n > 0)));
40317
- const xMax = Math.min(100 + 1, lastIndex + 1 + padding);
40318
-
40319
- // The y-axis is bounded above by largest value, and below by 0.
40320
- // However, the 'range' of the y-axis goes as low as -1 to allow
40321
- // Graphie to draw ticks on the x-Axis that extend vertically below
40322
- // y = 0.
40323
- const yMin = -1;
40324
- const yMax = _.max(data);
40325
- return [[xMin, xMax], [yMin, yMax]];
40326
- };
40327
- this._getInitialThreshold = range => {
40328
- // We pick a pretty-looking threshold, 1/3 of the way along the axis
40329
- const xRange = range[0];
40330
- return xRange[0] + (xRange[1] - xRange[0]) / 3;
40331
- };
40332
- this.state = {
40333
- // @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
40334
- threshold: this._getInitialThreshold(this._range())
40335
- };
40336
- }
40337
- UNSAFE_componentWillReceiveProps(nextProps) {
40338
- // Reset the threshold if the range has changed
40339
- // @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
40340
- const oldRange = this._range();
40341
- const nextRange = this._range(nextProps);
40342
- if (!Util.deepEq(oldRange, nextRange)) {
40343
- this.setState({
40344
- threshold: this._getInitialThreshold(nextRange)
40345
- });
40346
- }
40347
- }
40348
- render() {
40349
- const data = this.props.data;
40350
- // @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
40351
- const range = this._range();
40352
- const options = {
40353
- xAxisLabel: this.props.xAxisLabel,
40354
- yAxisLabel: this.props.yAxisLabel,
40355
- box: this.props.box,
40356
- range: range,
40357
- data: data,
40358
- scale: [Util.scaleFromExtent(range[0], this.props.box[0]), Util.scaleFromExtent(range[1], this.props.box[1])]
40359
- };
40360
- const axisStyle = {
40361
- stroke: "#000",
40362
- strokeWidth: 1,
40363
- opacity: 1.0
40364
- };
40365
- const origin = [range[0][0], 0];
40366
- const bottomRight = [range[0][1], 0];
40367
- return /*#__PURE__*/React.createElement(Graphie, {
40368
- box: options.box,
40369
- range: options.range,
40370
- options: options,
40371
- setup: this._setupGraphie,
40372
- onMouseMove: this.handleMouseInteraction,
40373
- onMouseDown: this.handleMouseInteraction,
40374
- setDrawingAreaAvailable: this.props.setDrawingAreaAvailable
40375
- }, /*#__PURE__*/React.createElement(Line, {
40376
- start: origin,
40377
- end: bottomRight,
40378
- style: axisStyle
40379
- }), data && this._renderData(), data && this._renderCircle(), data && this._renderThresholdLine());
40380
- }
40381
- }
40382
- Histogram.propTypes = {
40383
- data: PropTypes.arrayOf(PropTypes.number),
40384
- xAxisLabel: PropTypes.string,
40385
- yAxisLabel: PropTypes.string,
40386
- box: PropTypes.arrayOf(PropTypes.number)
40387
- };
40388
- Histogram.defaultProps = {
40389
- data: null,
40390
- xAxisLabel: "Proportion (%)",
40391
- yAxisLabel: "Number of times seen",
40392
- box: [defaultBoxSize, defaultBoxSize]
40393
- };
40394
- class Simulator extends React.Component {
40395
- constructor(..._args) {
40396
- super(..._args);
40397
- // @ts-expect-error - TS2564 - Property 'generateNumber' has no initializer and is not definitely assigned in the constructor.
40398
- this.generateNumber = void 0;
40399
- this.state = {
40400
- invalidInput: false
40401
- };
40402
- this.calculateDisplayProportion = () => {
40403
- const userProportion = this.props.userProportion;
40404
-
40405
- // If we want to display as a percentage, multiply proportion by 100.0.
40406
- if (this.props.proportionOrPercentage === "percentage") {
40407
- return Math.round(100 * userProportion);
40408
- }
40409
- return userProportion;
40410
- };
40411
- this.change = (...args) => {
40412
- // @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
40413
- return change.apply(this, args);
40414
- };
40415
- this.checkProportionValidity = value => {
40416
- return value >= 0.0 && this.props.proportionOrPercentage === "proportion" && value <= 1.0 || this.props.proportionOrPercentage === "percentage" && value <= 100.0;
40417
- };
40418
- this.handleUserProportionChange = (value, cb) => {
40419
- let userProportion;
40420
-
40421
- // If "percentage" mode is enabled, user will have entered value as
40422
- // a percentage. However, we always store as a proportion, so we cast.
40423
- if (this.props.proportionOrPercentage === "percentage") {
40424
- userProportion = value / 100.0;
40425
- } else {
40426
- userProportion = value;
40427
- }
40428
-
40429
- // If they entered a number, we may need to cap it
40430
- if (userProportion != null) {
40431
- userProportion = Math.min(1.0, Math.max(0.0, userProportion));
40432
- }
40433
- this.props.onChange({
40434
- userProportion: userProportion
40435
- }, cb);
40436
- };
40437
- // @ts-expect-error - TS2322 - Type '(sampleSize: any, cb: any) => void' is not assignable to type '(number: any) => void'.
40438
- this.handleSampleSizeChange = (sampleSize, cb) => {
40439
- if (sampleSize != null) {
40440
- sampleSize = Math.min(maxSampleSize, Math.max(0, Math.floor(sampleSize)));
40441
- }
40442
- this.props.onChange({
40443
- sampleSize: sampleSize
40444
- }, cb);
40445
- };
40446
- this.handleRunSimulation = () => {
40447
- // If they haven't filled out a parameter field, highlight it.
40448
- if (this.props.numTrials == null || this.props.userProportion == null || this.props.sampleSize == null) {
40449
- this.setState({
40450
- invalidInput: true
40451
- });
40452
- return;
40453
- }
40454
- this.setState({
40455
- invalidInput: false
40456
- });
40457
- this.props.onChange({
40458
- // @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
40459
- data: this.generateData()
40460
- });
40461
- this.props.trackInteraction();
40462
- };
40463
- this.generateData = props => {
40464
- props = props || this.props;
40465
- const getSampleDistribution = (sampleSize, numTrials, proportion) => {
40466
- const draw = () => {
40467
- return this.generateNumber() < proportion;
40468
- };
40469
- const sampleDistribution = _.times(100 + 1, () => 0);
40470
- _.times(numTrials, () => {
40471
- const results = _.times(sampleSize, draw);
40472
- const count = _.filter(results, _.identity).length;
40473
- const normalizedCount = Math.floor(100 * count / sampleSize);
40474
- sampleDistribution[normalizedCount]++;
40475
- });
40476
- return sampleDistribution;
40477
- };
40478
- return getSampleDistribution(props.sampleSize, props.numTrials, props.userProportion);
40479
- };
40480
- /* InputPath API */
40481
- this.getInputPaths = () => {
40482
- return [["userProportion"], ["sampleSize"]];
40483
- };
40484
- this.focus = () => {
40485
- const path = _.head(this.getInputPaths());
40486
- this.focusInputPath(path);
40487
- return true;
40488
- };
40489
- this.focusInputPath = path => {
40490
- assert$1(path.length > 0);
40491
- const inputID = _.head(path);
40492
- // eslint-disable-next-line react/no-string-refs
40493
- const inputComponent = this.refs[inputID];
40494
- // @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
40495
- inputComponent.focus();
40496
- };
40497
- this.blurInputPath = path => {
40498
- assert$1(path.length > 0);
40499
- const inputID = _.head(path);
40500
- // eslint-disable-next-line react/no-string-refs
40501
- const inputComponent = this.refs[inputID];
40502
- // @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
40503
- inputComponent.blur();
40504
- };
40505
- this.getDOMNodeForPath = path => {
40506
- assert$1(path.length > 0);
40507
- const inputID = _.head(path);
40508
- // eslint-disable-next-line react/no-string-refs
40509
- return ReactDOM__default.findDOMNode(this.refs[inputID]);
40510
- };
40511
- this.getGrammarTypeForPath = path => {
40512
- assert$1(path.length > 0);
40513
- return "number";
40514
- };
40515
- this.setInputValue = (path, newValue, cb) => {
40516
- assert$1(path.length > 0);
40517
- const inputID = _.head(path);
40518
- const capitalizedID = inputID.charAt(0).toUpperCase() + inputID.slice(1);
40519
- const functionName = "handle" + capitalizedID + "Change";
40520
- this[functionName](newValue, cb);
40521
- };
40522
- this.getUserInput = () => {
40523
- return null;
40524
- };
40525
- this.simpleValidate = rubric => {
40526
- // @ts-expect-error - TS2339 - Property 'validate' does not exist on type 'typeof Simulator'.
40527
- return Simulator.validate(this.getUserInput(), rubric);
40528
- };
40529
- }
40530
- // TODO(jangmi, CP-3288): Remove usage of `UNSAFE_componentWillMount`
40531
- UNSAFE_componentWillMount() {
40532
- if (this.props.randomSeed != null) {
40533
- this.generateNumber = Util.seededRNG(this.props.randomSeed);
40534
- }
40535
- }
40536
- UNSAFE_componentWillReceiveProps(nextProps) {
40537
- if (nextProps.randomSeed !== this.props.randomSeed) {
40538
- this.generateNumber = Util.seededRNG(nextProps.randomSeed);
40539
- }
40540
- }
40541
- render() {
40542
- const inputStyle = {
40543
- marginLeft: "5px"
40544
- };
40545
- const highlight = "0px 0px 0px 2px rgba(255, 165, 0, 1)";
40546
- const highlightStyle = _.extend({}, inputStyle, {
40547
- boxShadow: highlight,
40548
- transition: "all 0.15s"
40549
- });
40550
- const unhighlightStyle = _.extend({}, inputStyle, {
40551
- transition: "all 0.15s"
40552
- });
40553
- const style = this.state.invalidInput ? highlightStyle : unhighlightStyle;
40554
- const proportionInput = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(NumberInput
40555
- // eslint-disable-next-line react/no-string-refs
40556
- , {
40557
- ref: "userProportion",
40558
- style: style,
40559
- value: this.calculateDisplayProportion(),
40560
- checkValidity: this.checkProportionValidity,
40561
- disabled: this.props.apiOptions.readOnly,
40562
- onChange: this.handleUserProportionChange,
40563
- onFocus: () => this.props.onFocus(["userProportion"]),
40564
- onBlur: () => this.props.onBlur(["userProportion"])
40565
- }), /*#__PURE__*/React.createElement(InfoTip, null, /*#__PURE__*/React.createElement("p", null, i18n._("This controls the proportion or percentage that will be used in your simulation."))));
40566
- const sampleSizeInput = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(NumberInput
40567
- // eslint-disable-next-line react/no-string-refs
40568
- , {
40569
- ref: "sampleSize",
40570
- style: style,
40571
- value: this.props.sampleSize,
40572
- checkValidity: val => val >= 0,
40573
- disabled: this.props.apiOptions.readOnly,
40574
- onChange: this.handleSampleSizeChange,
40575
- onFocus: () => this.props.onFocus(["sampleSize"]),
40576
- onBlur: () => this.props.onBlur(["sampleSize"])
40577
- }), /*#__PURE__*/React.createElement(InfoTip, null, /*#__PURE__*/React.createElement("p", null, i18n._("This controls the sample size that will be used in your simulation. For example, if you set this to 100, then for each trial, responses from 100 participants will be simulated."))));
40578
- const numTrialsDisplay = /*#__PURE__*/React.createElement("div", {
40579
- style: {
40580
- textAlign: "right"
40581
- }
40582
- }, /*#__PURE__*/React.createElement("b", null, this.props.numTrials), /*#__PURE__*/React.createElement(InfoTip, null, /*#__PURE__*/React.createElement("p", null, i18n._("This is the number of trials used in the simulation. For example, if set to 50, then the survey will be conducted 50 times."))));
40583
-
40584
- // Generates a table from a set of titles and values.
40585
- const generateTable = contents => {
40586
- const header = /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, i18n._("Parameter")), /*#__PURE__*/React.createElement("th", null, i18n._("Value"))));
40587
- const body = /*#__PURE__*/React.createElement("tbody", null, _.map(contents, (row, i) => {
40588
- return /*#__PURE__*/React.createElement("tr", {
40589
- key: i
40590
- }, /*#__PURE__*/React.createElement("td", null, row.title), /*#__PURE__*/React.createElement("td", null, row.value));
40591
- }));
40592
- return /*#__PURE__*/React.createElement("table", null, header, body);
40593
- };
40594
-
40595
- // Contents for the table to-be generated
40596
- const contents = [{
40597
- title: this.props.proportionLabel + ":",
40598
- value: proportionInput
40599
- }, {
40600
- title: i18n._("Sample size:"),
40601
- value: sampleSizeInput
40602
- }, {
40603
- title: i18n._("Number of trials:"),
40604
- value: numTrialsDisplay
40605
- }];
40606
-
40607
- // The 'Run Simulation' button
40608
- const buttonStyle = {
40609
- margin: "20px 0"
40610
- };
40611
- const startButton = /*#__PURE__*/React.createElement("button", {
40612
- className: "simple-button",
40613
- style: buttonStyle,
40614
- disabled: this.props.apiOptions.readOnly,
40615
- onClick: this.handleRunSimulation
40616
- }, i18n._("Run simulation"));
40617
-
40618
- // When we plot data, ticks on the x-axis require some vertical padding
40619
- const histogramStyle = {
40620
- paddingBottom: this.props.data ? 40 : 0
40621
- };
40622
- const histogram = /*#__PURE__*/React.createElement("div", {
40623
- style: histogramStyle
40624
- }, /*#__PURE__*/React.createElement(Histogram, {
40625
- data: this.props.data,
40626
- xAxisLabel: this.props.xAxisLabel,
40627
- yAxisLabel: this.props.yAxisLabel,
40628
- setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
40629
- }));
40630
- return /*#__PURE__*/React.createElement("div", null, generateTable(contents), startButton, histogram);
40631
- }
40632
- }
40633
- Simulator.propTypes = _extends({}, propTypes, {
40634
- apiOptions: ApiOptions.propTypes,
40635
- data: PropTypes.arrayOf(PropTypes.number),
40636
- numTrials: PropTypes.number,
40637
- proportionLabel: PropTypes.string,
40638
- proportionOrPercentage: PropTypes.string,
40639
- randomSeed: PropTypes.number,
40640
- sampleSize: PropTypes.number,
40641
- trackInteraction: PropTypes.func.isRequired,
40642
- userProportion: PropTypes.number,
40643
- xAxisLabel: PropTypes.string,
40644
- yAxisLabel: PropTypes.string
40645
- });
40646
- Simulator.defaultProps = {
40647
- data: null,
40648
- userProportion: null,
40649
- sampleSize: null,
40650
- numTrials: null,
40651
- randomSeed: 0,
40652
- xAxisLabel: "Proportion (%)",
40653
- yAxisLabel: "Number of times seen",
40654
- proportionLabel: "Underlying proportion",
40655
- proportionOrPercentage: "proportion",
40656
- apiOptions: ApiOptions.defaults
40657
- };
40658
- _.extend(Simulator, {
40659
- validate: function (state, rubric) {
40660
- return {
40661
- type: "points",
40662
- earned: 0,
40663
- total: 0,
40664
- message: null
40665
- };
40666
- }
40667
- });
40668
- const propTransform$1 = editorProps => {
40669
- const widgetProps = _.clone(editorProps);
40670
- widgetProps.randomSeed = editorProps.problemNum;
40671
- return widgetProps;
40672
- };
40673
- var Simulator$1 = {
40674
- name: "simulator",
40675
- displayName: "Simulator (deprecated)",
40676
- widget: Simulator,
40677
- transform: propTransform$1,
40678
- hidden: true
40679
- };
40680
-
40681
39630
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
40682
39631
  const {
40683
39632
  shuffle
@@ -42178,7 +41127,7 @@ var Video$1 = {
42178
41127
  };
42179
41128
 
42180
41129
  /* eslint-disable import/no-named-as-default */
42181
- var extraWidgets = [Categorizer$1, CSProgram$1, Dropdown$1, Explanation$1, Definition$1, Grapher$1, GradedGroup$1, GradedGroupSet$1, Group$1, Iframe$1, Image$1, Interactive, InteractiveGraph$1, LabelImage$1, LightsPuzzle$1, Matrix$1, Matcher$1, Measurer$1, Molecule$1, NumberLine$1, Orderer$1, Passage$1, PassageRef$1, PassageRefTarget$1, Plotter$1, PythonProgram$1, ReactionDiagram, Sequence$1, Simulator$1, Sorter$1, Table$1, Unit, Video$1, DeprecatedStandin$1];
41130
+ var extraWidgets = [Categorizer$1, CSProgram$1, Dropdown$1, Explanation$1, Definition$1, Grapher$1, GradedGroup$1, GradedGroupSet$1, Group$1, Iframe$1, Image$1, Interactive, InteractiveGraph$1, LabelImage$1, Matrix$1, Matcher$1, Measurer$1, Molecule$1, NumberLine$1, Orderer$1, Passage$1, PassageRef$1, PassageRefTarget$1, Plotter$1, PythonProgram$1, Sorter$1, Table$1, Unit, Video$1, DeprecatedStandin$1];
42182
41131
 
42183
41132
  /**
42184
41133
  * This should be called by all clients, specifying whether extra widgets are
@@ -42192,7 +41141,7 @@ var extraWidgets = [Categorizer$1, CSProgram$1, Dropdown$1, Explanation$1, Defin
42192
41141
  const init = function init(options) {
42193
41142
  registerWidgets(basicWidgets);
42194
41143
  registerWidgets(extraWidgets);
42195
- replaceWidget("transformer", "deprecated-standin");
41144
+ replaceDeprecatedWidgets();
42196
41145
 
42197
41146
  // Pass skipMathJax: true if MathJax is already loaded and configured.
42198
41147
  const skipMathJax = options.skipMathJax;
@@ -42218,7 +41167,7 @@ const init = function init(options) {
42218
41167
 
42219
41168
  // This file is processed by a Rollup plugin (replace) to inject the production
42220
41169
  const libName = "@khanacademy/perseus";
42221
- const libVersion = "19.8.0";
41170
+ const libVersion = "20.0.0";
42222
41171
  addLibraryVersionToPerseusDebug(libName, libVersion);
42223
41172
 
42224
41173
  const apiVersion = {
@@ -42780,17 +41729,13 @@ class ServerItemRenderer extends React.Component {
42780
41729
  this.blurTimeoutID = void 0;
42781
41730
  this._handleFocusChange = (newFocus, oldFocus) => {
42782
41731
  if (newFocus != null) {
42783
- var _this$props$apiOption;
42784
41732
  this._setCurrentFocus(newFocus);
42785
-
42786
- // Call the interactionCallback, if it exists, with the current user input data
42787
- (_this$props$apiOption = this.props.apiOptions) == null || _this$props$apiOption.interactionCallback == null || _this$props$apiOption.interactionCallback(this.questionRenderer.getUserInputForWidgets());
42788
41733
  } else {
42789
41734
  this._onRendererBlur(oldFocus);
42790
41735
  }
42791
41736
  };
42792
41737
  this.handleInteractWithWidget = widgetId => {
42793
- var _this$props$apiOption2;
41738
+ var _this$props$apiOption;
42794
41739
  const withRemoved = _.difference(this.state.questionHighlightedWidgets, [widgetId]);
42795
41740
  this.setState({
42796
41741
  questionCompleted: false,
@@ -42798,7 +41743,7 @@ class ServerItemRenderer extends React.Component {
42798
41743
  });
42799
41744
 
42800
41745
  // Call the interactionCallback, if it exists, with the current user input data
42801
- (_this$props$apiOption2 = this.props.apiOptions) == null || _this$props$apiOption2.interactionCallback == null || _this$props$apiOption2.interactionCallback(this.questionRenderer.getUserInputForWidgets());
41746
+ (_this$props$apiOption = this.props.apiOptions) == null || _this$props$apiOption.interactionCallback == null || _this$props$apiOption.interactionCallback(this.questionRenderer.getUserInputForWidgets());
42802
41747
  };
42803
41748
  // This must be pre-bound otherwise SvgImage's shouldComponentUpdate
42804
41749
  // won't behave correctly and we'll get an infinite loop.
@@ -43341,14 +42286,6 @@ const ItemExtras = [
43341
42286
 
43342
42287
  // prettier-ignore
43343
42288
 
43344
- // prettier-ignore
43345
-
43346
- // prettier-ignore
43347
-
43348
- // prettier-ignore
43349
-
43350
- // prettier-ignore
43351
-
43352
42289
  //prettier-ignore
43353
42290
 
43354
42291
  // A background image applied to various widgets.
@@ -43397,7 +42334,7 @@ const deepCallbackFor = function deepCallbackFor(contentCallback, widgetCallback
43397
42334
  // on getDefaultProps, this will become easier.
43398
42335
  let newWidgetInfo;
43399
42336
  if (latestVersion && ((_upgradedWidgetInfo$v = upgradedWidgetInfo.version) == null ? void 0 : _upgradedWidgetInfo$v.major) === latestVersion.major) {
43400
- newWidgetInfo = traverseChildWidgets$4(upgradedWidgetInfo, rendererOptions => {
42337
+ newWidgetInfo = traverseChildWidgets$3(upgradedWidgetInfo, rendererOptions => {
43401
42338
  return traverseRenderer$1(rendererOptions, contentCallback,
43402
42339
  // so that we traverse grandchildren, too:
43403
42340
  deepCallback, optionsCallback);
@@ -44479,7 +43416,7 @@ function violatingWidgets(itemData) {
44479
43416
  */
44480
43417
  const registerAllWidgetsForTesting = () => {
44481
43418
  registerWidgets(allWidgets);
44482
- replaceWidget("transformer", "deprecated-standin");
43419
+ replaceDeprecatedWidgets();
44483
43420
  };
44484
43421
 
44485
43422
  /**