@khanacademy/perseus 10.0.0 → 10.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
@@ -2994,6 +2994,17 @@ const ExpressionWithDependencies = /*#__PURE__*/React__namespace.forwardRef((pro
2994
2994
  analytics: deps.analytics
2995
2995
  }, props));
2996
2996
  });
2997
+
2998
+ // HACK: Propogate "static" methods onto our wrapper component.
2999
+ // In the future we should adjust client apps to not depend on these static
3000
+ // methods and instead adjust Peresus to provide these facilities through
3001
+ // instance methods on our Renderers.
3002
+ // @ts-expect-error - TS2339 - Property 'validate' does not exist on type
3003
+ ExpressionWithDependencies.validate = Expression.validate;
3004
+ // @ts-expect-error - TS2339 - Property 'validate' does not exist on type
3005
+ ExpressionWithDependencies.getUserInputFromProps = Expression.getUserInputFromProps;
3006
+ // @ts-expect-error - TS2339 - Property 'validate' does not exist on type
3007
+ ExpressionWithDependencies.getOneCorrectAnswerFromRubric = Expression.getOneCorrectAnswerFromRubric;
2997
3008
  var Expression$1 = {
2998
3009
  name: "expression",
2999
3010
  displayName: "Expression / Equation",
@@ -17620,7 +17631,8 @@ class Zoomable extends React__namespace.Component {
17620
17631
  zoomed
17621
17632
  } = this.state;
17622
17633
  const {
17623
- animateHeight
17634
+ animateHeight,
17635
+ disableEntranceAnimation
17624
17636
  } = this.props;
17625
17637
  const property = animateHeight ? "opacity transform height" : "opacity transform";
17626
17638
 
@@ -17632,7 +17644,9 @@ class Zoomable extends React__namespace.Component {
17632
17644
  } : {};
17633
17645
 
17634
17646
  // Do a fancy little slide as we fade the contents in the first time.
17635
- const translateOffset = visible ? "" : " translate(0, 8px)";
17647
+ const shouldSlide = !disableEntranceAnimation && !visible;
17648
+ const translateOffset = shouldSlide ? " translate(0, 8px)" : "";
17649
+ const opacity = shouldSlide ? 0 : 1;
17636
17650
  const scaleString = (scale !== null && scale !== void 0 ? scale : 1).toString();
17637
17651
  const transform = zoomed ? "scale(1, 1) ".concat(translateOffset) : "scale(".concat(scaleString, ", ").concat(scaleString, ") ").concat(translateOffset);
17638
17652
  const style = {
@@ -17641,7 +17655,7 @@ class Zoomable extends React__namespace.Component {
17641
17655
  height: zoomed ? expandedHeight : compactHeight,
17642
17656
  transform: transform,
17643
17657
  transformOrigin: "0 0",
17644
- opacity: visible ? 1 : 0,
17658
+ opacity: opacity,
17645
17659
  WebkitTapHighlightColor: "transparent",
17646
17660
  ...transitionStyle
17647
17661
  };
@@ -17660,6 +17674,7 @@ class Zoomable extends React__namespace.Component {
17660
17674
  _defineProperty(Zoomable, "defaultProps", {
17661
17675
  animateHeight: false,
17662
17676
  readyToMeasure: true,
17677
+ disableEntranceAnimation: false,
17663
17678
  computeChildBounds: parentNode => {
17664
17679
  const firstChild = parentNode.firstElementChild;
17665
17680
  return {
@@ -17705,7 +17720,9 @@ class ZoomableTeX extends React__namespace.Component {
17705
17720
  render() {
17706
17721
  return /*#__PURE__*/React__namespace.createElement(Zoomable, {
17707
17722
  readyToMeasure: this.state.isRendered,
17708
- computeChildBounds: computeMathBounds
17723
+ computeChildBounds: computeMathBounds,
17724
+ animateHeight: false,
17725
+ disableEntranceAnimation: true
17709
17726
  }, /*#__PURE__*/React__namespace.createElement(context$1.Consumer, null, _ref => {
17710
17727
  let {
17711
17728
  setAssetStatus
@@ -17950,33 +17967,33 @@ class Lint extends React__namespace.Component {
17950
17967
  let warningText;
17951
17968
  let warningTextStyle;
17952
17969
  if (this.props.severity === Severity.Error) {
17953
- severityStyle = styles$A.indicatorError;
17970
+ severityStyle = styles$z.indicatorError;
17954
17971
  warningText = "Error";
17955
- warningTextStyle = styles$A.publishBlockingError;
17972
+ warningTextStyle = styles$z.publishBlockingError;
17956
17973
  } else if (this.props.severity === Severity.Warning) {
17957
- severityStyle = styles$A.indicatorWarning;
17974
+ severityStyle = styles$z.indicatorWarning;
17958
17975
  warningText = "Warning";
17959
- warningTextStyle = styles$A.warning;
17976
+ warningTextStyle = styles$z.warning;
17960
17977
  } else {
17961
- severityStyle = styles$A.indicatorGuideline;
17978
+ severityStyle = styles$z.indicatorGuideline;
17962
17979
  warningText = "Recommendation";
17963
- warningTextStyle = styles$A.warning;
17980
+ warningTextStyle = styles$z.warning;
17964
17981
  }
17965
17982
  return /*#__PURE__*/React__namespace.createElement("a", {
17966
17983
  href: "https://khanacademy.org/r/linter-rules#".concat(this.props.ruleName),
17967
17984
  target: "lint-help-window",
17968
17985
  className: aphrodite.css(style)
17969
17986
  }, /*#__PURE__*/React__namespace.createElement("span", {
17970
- className: aphrodite.css(styles$A.indicator, severityStyle)
17987
+ className: aphrodite.css(styles$z.indicator, severityStyle)
17971
17988
  }, this.props.severity === 1 && /*#__PURE__*/React__namespace.createElement(InlineIcon, exclamationIcon)), /*#__PURE__*/React__namespace.createElement("div", {
17972
- className: aphrodite.css(styles$A.tooltip, tooltipAbove && styles$A.tooltipAbove)
17989
+ className: aphrodite.css(styles$z.tooltip, tooltipAbove && styles$z.tooltipAbove)
17973
17990
  }, this.props.message.split("\n\n").map((m, i) => /*#__PURE__*/React__namespace.createElement("p", {
17974
17991
  key: i,
17975
- className: aphrodite.css(styles$A.tooltipParagraph)
17992
+ className: aphrodite.css(styles$z.tooltipParagraph)
17976
17993
  }, /*#__PURE__*/React__namespace.createElement("span", {
17977
17994
  className: aphrodite.css(warningTextStyle)
17978
17995
  }, warningText, ":", " "), m)), /*#__PURE__*/React__namespace.createElement("div", {
17979
- className: aphrodite.css(styles$A.tail, tooltipAbove && styles$A.tailAbove)
17996
+ className: aphrodite.css(styles$z.tail, tooltipAbove && styles$z.tailAbove)
17980
17997
  })));
17981
17998
  });
17982
17999
  }
@@ -18020,20 +18037,20 @@ class Lint extends React__namespace.Component {
18020
18037
  }
18021
18038
  if (blockHighlight) {
18022
18039
  return /*#__PURE__*/React__namespace.createElement("span", {
18023
- className: aphrodite.css(styles$A.lintContainer, styles$A.lintContainerBlock)
18024
- }, this.renderLink(styles$A.radioWidgetHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
18040
+ className: aphrodite.css(styles$z.lintContainer, styles$z.lintContainerBlock)
18041
+ }, this.renderLink(styles$z.radioWidgetHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
18025
18042
  }
18026
18043
  if (inline) {
18027
18044
  return /*#__PURE__*/React__namespace.createElement("span", {
18028
- className: aphrodite.css(styles$A.lintContainer)
18029
- }, this.renderLink(styles$A.inlineHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
18045
+ className: aphrodite.css(styles$z.lintContainer)
18046
+ }, this.renderLink(styles$z.inlineHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
18030
18047
  }
18031
18048
  return /*#__PURE__*/React__namespace.createElement("div", {
18032
- className: aphrodite.css(styles$A.lintContainer)
18033
- }, this.renderLink(styles$A.hoverTarget), /*#__PURE__*/React__namespace.createElement("div", null, children));
18049
+ className: aphrodite.css(styles$z.lintContainer)
18050
+ }, this.renderLink(styles$z.hoverTarget), /*#__PURE__*/React__namespace.createElement("div", null, children));
18034
18051
  }
18035
18052
  }
18036
- const styles$A = aphrodite.StyleSheet.create({
18053
+ const styles$z = aphrodite.StyleSheet.create({
18037
18054
  // This is the class of the outermost element.
18038
18055
  // We use relative positioning so that the lint indicator can be
18039
18056
  // positioned absolutely relative to the position of the linty container.
@@ -19814,7 +19831,7 @@ class Renderer extends React__namespace.Component {
19814
19831
  };
19815
19832
  const mobileInnerStyle = {
19816
19833
  ...innerStyle,
19817
- ...styles$z.mobileZoomableParentFix
19834
+ ...styles$y.mobileZoomableParentFix
19818
19835
  };
19819
19836
  return /*#__PURE__*/React__namespace.createElement("div", {
19820
19837
  key: state.key,
@@ -19951,7 +19968,7 @@ class Renderer extends React__namespace.Component {
19951
19968
  };
19952
19969
  const mobileInnerStyle = {
19953
19970
  ...innerStyle,
19954
- ...styles$z.mobileZoomableParentFix
19971
+ ...styles$y.mobileZoomableParentFix
19955
19972
  };
19956
19973
  const wrappedOutput = /*#__PURE__*/React__namespace.createElement("div", {
19957
19974
  style: {
@@ -20576,7 +20593,7 @@ _defineProperty(Renderer, "defaultProps", {
20576
20593
  onSerializedStateUpdated: () => {},
20577
20594
  linterContext: PerseusLinter__namespace.linterContextDefault
20578
20595
  });
20579
- const styles$z = {
20596
+ const styles$y = {
20580
20597
  mobileZoomableParentFix: {
20581
20598
  // NOTE(abdul): There is an issue where transform animations will
20582
20599
  // cause the Zoomable component to disappear when running on the
@@ -21334,10 +21351,10 @@ class InputNumber extends React__namespace.Component {
21334
21351
  // Note: This is _very_ similar to what `numeric-input.jsx` does. If
21335
21352
  // you modify this, double-check if you also need to modify that
21336
21353
  // component.
21337
- const inputStyles = [styles$y.default, this.props.size === "small" ? styles$y.small : null, this.props.rightAlign ? styles$y.rightAlign : styles$y.leftAlign];
21354
+ const inputStyles = [styles$x.default, this.props.size === "small" ? styles$x.small : null, this.props.rightAlign ? styles$x.rightAlign : styles$x.leftAlign];
21338
21355
  // Unanswered
21339
21356
  if (rubric && !this.props.currentValue) {
21340
- inputStyles.push(styles$y.answerStateUnanswered);
21357
+ inputStyles.push(styles$x.answerStateUnanswered);
21341
21358
  }
21342
21359
  return /*#__PURE__*/React__namespace.createElement(InputWithExamples
21343
21360
  // eslint-disable-next-line react/no-string-refs
@@ -21423,7 +21440,7 @@ _defineProperty(InputNumber, "defaultProps", {
21423
21440
  apiOptions: ApiOptions.defaults,
21424
21441
  linterContext: PerseusLinter.linterContextDefault
21425
21442
  });
21426
- const styles$y = aphrodite.StyleSheet.create({
21443
+ const styles$x = aphrodite.StyleSheet.create({
21427
21444
  default: {
21428
21445
  width: 80,
21429
21446
  height: "auto"
@@ -22417,7 +22434,7 @@ const FocusRing = function (props) {
22417
22434
  };
22418
22435
  return /*#__PURE__*/React__namespace.createElement("span", {
22419
22436
  "data-test-id": "focus-ring",
22420
- className: aphrodite.css(styles$x.ring),
22437
+ className: aphrodite.css(styles$w.ring),
22421
22438
  style: style
22422
22439
  }, children);
22423
22440
  };
@@ -22426,7 +22443,7 @@ FocusRing.defaultProps = {
22426
22443
  color: kaGreen$1,
22427
22444
  multipleSelect: false
22428
22445
  };
22429
- const styles$x = aphrodite.StyleSheet.create({
22446
+ const styles$w = aphrodite.StyleSheet.create({
22430
22447
  ring: {
22431
22448
  margin: "auto",
22432
22449
  display: "inline-block",
@@ -22463,7 +22480,7 @@ function getChoiceLetter(pos) {
22463
22480
  }
22464
22481
 
22465
22482
  const CHOICE_ICON_SIZE = 24;
22466
- const styles$w = aphrodite.StyleSheet.create({
22483
+ const styles$v = aphrodite.StyleSheet.create({
22467
22484
  iconWrapper: {
22468
22485
  display: "inline-block",
22469
22486
  position: "relative"
@@ -22486,7 +22503,7 @@ const CrossOutLine = function (props) {
22486
22503
  width: CROSS_OUT_LINE_SIZE,
22487
22504
  height: CROSS_OUT_LINE_SIZE,
22488
22505
  viewBox: "0 0 ".concat(CROSS_OUT_LINE_SIZE, " ").concat(CROSS_OUT_LINE_SIZE),
22489
- className: aphrodite.css(styles$v.crossOutLine),
22506
+ className: aphrodite.css(styles$u.crossOutLine),
22490
22507
  "data-test-id": "choice-icon__cross-out-line"
22491
22508
  }, /*#__PURE__*/React__namespace.createElement("line", {
22492
22509
  // The line stretches from the bottom-left to top-right.
@@ -22501,7 +22518,7 @@ const CrossOutLine = function (props) {
22501
22518
  strokeLinecap: "round"
22502
22519
  }));
22503
22520
  };
22504
- const styles$v = aphrodite.StyleSheet.create({
22521
+ const styles$u = aphrodite.StyleSheet.create({
22505
22522
  crossOutLine: {
22506
22523
  // Center the icon within the container.
22507
22524
  position: "absolute",
@@ -22582,7 +22599,7 @@ const ChoiceIcon = function (props) {
22582
22599
  } = props;
22583
22600
  const dynamicStyles = getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, correct);
22584
22601
  return /*#__PURE__*/React__namespace.createElement("div", {
22585
- className: aphrodite.css(styles$w.iconWrapper)
22602
+ className: aphrodite.css(styles$v.iconWrapper)
22586
22603
  }, /*#__PURE__*/React__namespace.createElement(FocusRing, {
22587
22604
  color: Color__default["default"].blue,
22588
22605
  visible: focused || hovered,
@@ -22591,13 +22608,13 @@ const ChoiceIcon = function (props) {
22591
22608
  // @ts-expect-error - TS2322 - Type '{ backgroundColor: string | null | undefined; borderColor: string; color: string; borderRadius: number; }' is not assignable to type 'Properties<string | number, string & {}>'.
22592
22609
  style: dynamicStyles,
22593
22610
  "data-test-id": "choice-icon__library-choice-icon",
22594
- className: aphrodite.css(styles$u.circle, showCorrectness && correct && styles$u.circleCorrect, showCorrectness && !correct && styles$u.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$u.circleIncorrectAnswered)
22611
+ className: aphrodite.css(styles$t.circle, showCorrectness && correct && styles$t.circleCorrect, showCorrectness && !correct && styles$t.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$t.circleIncorrectAnswered)
22595
22612
  // used in BaseRadio editMode to check
22596
22613
  // if we actually clicked on the radio icon
22597
22614
  ,
22598
22615
  "data-is-radio-icon": true
22599
22616
  }, /*#__PURE__*/React__namespace.createElement("div", {
22600
- className: aphrodite.css(styles$u.innerWrapper)
22617
+ className: aphrodite.css(styles$t.innerWrapper)
22601
22618
  }, /*#__PURE__*/React__namespace.createElement(ChoiceInner, {
22602
22619
  pos: pos,
22603
22620
  showCorrectness: showCorrectness,
@@ -22606,7 +22623,7 @@ const ChoiceIcon = function (props) {
22606
22623
  color: dynamicStyles.borderColor
22607
22624
  }));
22608
22625
  };
22609
- const styles$u = aphrodite.StyleSheet.create({
22626
+ const styles$t = aphrodite.StyleSheet.create({
22610
22627
  innerWrapper: {
22611
22628
  width: CHOICE_ICON_SIZE,
22612
22629
  height: CHOICE_ICON_SIZE,
@@ -22698,19 +22715,19 @@ const OptionStatus = function (props) {
22698
22715
  }
22699
22716
  let textStyle;
22700
22717
  if (correct) {
22701
- textStyle = styles$t.correct;
22718
+ textStyle = styles$s.correct;
22702
22719
  } else {
22703
22720
  if (checked || previouslyAnswered) {
22704
- textStyle = styles$t.incorrectAnswered;
22721
+ textStyle = styles$s.incorrectAnswered;
22705
22722
  } else {
22706
- textStyle = styles$t.incorrect;
22723
+ textStyle = styles$s.incorrect;
22707
22724
  }
22708
22725
  }
22709
22726
  return /*#__PURE__*/React__namespace.createElement("div", {
22710
- className: aphrodite.css(styles$t.text, textStyle)
22727
+ className: aphrodite.css(styles$s.text, textStyle)
22711
22728
  }, renderText(checked, correct, crossedOut));
22712
22729
  };
22713
- const styles$t = aphrodite.StyleSheet.create({
22730
+ const styles$s = aphrodite.StyleSheet.create({
22714
22731
  text: {
22715
22732
  alignItems: "center",
22716
22733
  display: "flex",
@@ -22785,8 +22802,8 @@ const Choice = function (props) {
22785
22802
  crossedOut: updatedCrossedOut
22786
22803
  });
22787
22804
  }
22788
- const descriptionClassName = classNames__default["default"]("description", aphrodite.css(styles$s.description));
22789
- const rationaleClassName = classNames__default["default"]("perseus-radio-rationale-content", aphrodite.css(styles$s.rationale));
22805
+ const descriptionClassName = classNames__default["default"]("description", aphrodite.css(styles$r.description));
22806
+ const rationaleClassName = classNames__default["default"]("perseus-radio-rationale-content", aphrodite.css(styles$r.rationale));
22790
22807
 
22791
22808
  // We want to show the choices as dimmed out when the choices are disabled.
22792
22809
  // However, we don't want to do this when we're in review mode in the
@@ -22952,7 +22969,7 @@ const Choice = function (props) {
22952
22969
  "data-test-id": "perseus-radio-rationale-content-".concat(pos)
22953
22970
  }, rationale));
22954
22971
  };
22955
- const styles$s = aphrodite.StyleSheet.create({
22972
+ const styles$r = aphrodite.StyleSheet.create({
22956
22973
  description: {
22957
22974
  display: "inline-block",
22958
22975
  width: "100%"
@@ -23143,10 +23160,10 @@ const BaseRadio = function (props) {
23143
23160
  const isMobile = apiOptions.isMobile;
23144
23161
  const firstChoiceHighlighted = choices[0].highlighted;
23145
23162
  const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
23146
- const className = classNames__default["default"]("perseus-widget-radio", !editMode && "perseus-rendered-radio", aphrodite.css(styles$r.radio, styles$r.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$r.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$r.radioContainerLastHighlighted));
23147
- const instructionsClassName = classNames__default["default"]("instructions", aphrodite.css(styles$r.instructions, isMobile && styles$r.instructionsMobile));
23163
+ const className = classNames__default["default"]("perseus-widget-radio", !editMode && "perseus-rendered-radio", aphrodite.css(styles$q.radio, styles$q.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$q.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$q.radioContainerLastHighlighted));
23164
+ const instructionsClassName = classNames__default["default"]("instructions", aphrodite.css(styles$q.instructions, isMobile && styles$q.instructionsMobile));
23148
23165
  const instructions = getInstructionsText(multipleSelect, countChoices, numCorrect);
23149
- const responsiveClassName = aphrodite.css(styles$r.responsiveFieldset);
23166
+ const responsiveClassName = aphrodite.css(styles$q.responsiveFieldset);
23150
23167
  const fieldset = /*#__PURE__*/React__namespace.createElement("fieldset", {
23151
23168
  className: "perseus-widget-radio-fieldset ".concat(responsiveClassName)
23152
23169
  }, /*#__PURE__*/React__namespace.createElement("legend", {
@@ -23197,7 +23214,7 @@ const BaseRadio = function (props) {
23197
23214
  const aphroditeClassName = checked => {
23198
23215
  // Whether or not to show correctness borders
23199
23216
  // for this choice and the next choice.
23200
- return aphrodite.css(sharedStyles.aboveScratchpad, styles$r.item, styles$r.responsiveItem, checked && styles$r.selectedItem, checked && choice.highlighted && styles$r.aboveBackdrop, checked && choice.highlighted && apiOptions.isMobile && styles$r.aboveBackdropMobile, nextChoiceHighlighted && apiOptions.isMobile && styles$r.nextHighlighted);
23217
+ return aphrodite.css(sharedStyles.aboveScratchpad, styles$q.item, styles$q.responsiveItem, checked && styles$q.selectedItem, checked && choice.highlighted && styles$q.aboveBackdrop, checked && choice.highlighted && apiOptions.isMobile && styles$q.aboveBackdropMobile, nextChoiceHighlighted && apiOptions.isMobile && styles$q.nextHighlighted);
23201
23218
  };
23202
23219
 
23203
23220
  // HACK(abdulrahman): Preloads the selection-state
@@ -23271,14 +23288,14 @@ const BaseRadio = function (props) {
23271
23288
  // Allow for horizontal scrolling if content is too wide, which may be
23272
23289
  // an issue especially on phones.
23273
23290
  return /*#__PURE__*/React__namespace.createElement("div", {
23274
- className: aphrodite.css(styles$r.responsiveContainer)
23291
+ className: aphrodite.css(styles$q.responsiveContainer)
23275
23292
  }, fieldset);
23276
23293
  };
23277
23294
  BaseRadio.defaultProps = {
23278
23295
  editMode: false,
23279
23296
  multipleSelect: false
23280
23297
  };
23281
- const styles$r = aphrodite.StyleSheet.create({
23298
+ const styles$q = aphrodite.StyleSheet.create({
23282
23299
  instructions: {
23283
23300
  display: "block",
23284
23301
  color: gray17,
@@ -23930,9 +23947,9 @@ class Categorizer extends React__namespace.Component {
23930
23947
  indexedItems = Util.shuffle(indexedItems, this.props.problemNum);
23931
23948
  }
23932
23949
  const table = /*#__PURE__*/React__namespace.createElement("table", {
23933
- className: "categorizer-table " + aphrodite.css(styles$q.mobileTable)
23950
+ className: "categorizer-table " + aphrodite.css(styles$p.mobileTable)
23934
23951
  }, /*#__PURE__*/React__namespace.createElement("thead", null, /*#__PURE__*/React__namespace.createElement("tr", null, /*#__PURE__*/React__namespace.createElement("td", {
23935
- className: aphrodite.css(styles$q.emptyHeaderCell)
23952
+ className: aphrodite.css(styles$p.emptyHeaderCell)
23936
23953
  }), this.props.categories.map((category, i) => {
23937
23954
  // Array index is the correct key here, as that's
23938
23955
  // how category grading actually works -- no way
@@ -23940,7 +23957,7 @@ class Categorizer extends React__namespace.Component {
23940
23957
  // middle. (If we later add that, this should be
23941
23958
  // fixed.)
23942
23959
  return /*#__PURE__*/React__namespace.createElement("th", {
23943
- className: aphrodite.css(styles$q.header),
23960
+ className: aphrodite.css(styles$p.header),
23944
23961
  key: i
23945
23962
  }, /*#__PURE__*/React__namespace.createElement(Renderer, {
23946
23963
  content: category,
@@ -23960,7 +23977,7 @@ class Categorizer extends React__namespace.Component {
23960
23977
  })), self.props.categories.map((catName, catNum) => {
23961
23978
  const selected = self.props.values[itemNum] === catNum;
23962
23979
  return /*#__PURE__*/React__namespace.createElement("td", {
23963
- className: "category " + aphrodite.css(styles$q.cell),
23980
+ className: "category " + aphrodite.css(styles$p.cell),
23964
23981
  key: catNum
23965
23982
  }, /*#__PURE__*/React__namespace.createElement("div", {
23966
23983
  className: ClassNames.INTERACTIVE,
@@ -23979,7 +23996,7 @@ class Categorizer extends React__namespace.Component {
23979
23996
  onChange: this.onChange.bind(this, itemNum, catNum),
23980
23997
  onClick: e => e.stopPropagation()
23981
23998
  }), !isMobile && /*#__PURE__*/React__namespace.createElement("span", {
23982
- className: aphrodite.css(styles$q.radioSpan, selected && styles$q.checkedRadioSpan, this.props.static && selected && styles$q.staticCheckedRadioSpan)
23999
+ className: aphrodite.css(styles$p.radioSpan, selected && styles$p.checkedRadioSpan, this.props.static && selected && styles$p.staticCheckedRadioSpan)
23983
24000
  }, selected ? /*#__PURE__*/React__namespace.createElement(InlineIcon, iconCircle) : /*#__PURE__*/React__namespace.createElement(InlineIcon, iconCircleThin))));
23984
24001
  }));
23985
24002
  /* eslint-enable max-len */
@@ -23991,7 +24008,7 @@ class Categorizer extends React__namespace.Component {
23991
24008
  "categorizer-container": true,
23992
24009
  "static-mode": this.props.static
23993
24010
  });
23994
- const inlineStyles = this.props.apiOptions.isMobile ? [styles$q.fullBleedContainer] : [];
24011
+ const inlineStyles = this.props.apiOptions.isMobile ? [styles$p.fullBleedContainer] : [];
23995
24012
  return /*#__PURE__*/React__namespace.createElement("div", {
23996
24013
  className: extraClassNames + " " + aphrodite.css(...inlineStyles)
23997
24014
  }, table);
@@ -24036,7 +24053,7 @@ const pageMargin = 16;
24036
24053
 
24037
24054
  // Stylesheets aren't directly testable
24038
24055
  /* c8 ignore next */
24039
- const styles$q = aphrodite.StyleSheet.create({
24056
+ const styles$p = aphrodite.StyleSheet.create({
24040
24057
  mobileTable: {
24041
24058
  [mediaQueries.smOrSmaller]: {
24042
24059
  minWidth: "auto"
@@ -24277,7 +24294,7 @@ class CSProgram extends React__namespace.Component {
24277
24294
  // creator "went wild".
24278
24295
  // http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
24279
24296
  return /*#__PURE__*/React__namespace.createElement("div", {
24280
- className: aphrodite.css(styles$p.widthOverride, styleContainer && styles$p.container)
24297
+ className: aphrodite.css(styles$o.widthOverride, styleContainer && styles$o.container)
24281
24298
  }, /*#__PURE__*/React__namespace.createElement("iframe", {
24282
24299
  sandbox: sandboxOptions,
24283
24300
  src: url,
@@ -24307,7 +24324,7 @@ _defineProperty(CSProgram, "defaultProps", {
24307
24324
  // optional message
24308
24325
  message: null
24309
24326
  });
24310
- const styles$p = aphrodite.StyleSheet.create({
24327
+ const styles$o = aphrodite.StyleSheet.create({
24311
24328
  // Override the inherited width from the perseus paragraph class
24312
24329
  // 820 is minimum width for 420px editor and 400px canvas
24313
24330
  widthOverride: {
@@ -24352,7 +24369,7 @@ class Definition extends React__namespace.Component {
24352
24369
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.Popover, {
24353
24370
  content: /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.PopoverContentCore, {
24354
24371
  color: "white",
24355
- style: styles$o.tooltipBody,
24372
+ style: styles$n.tooltipBody,
24356
24373
  closeButtonVisible: true
24357
24374
  }, /*#__PURE__*/React__namespace.createElement(Renderer, {
24358
24375
  apiOptions: this.props.apiOptions,
@@ -24387,7 +24404,7 @@ _defineProperty(Definition, "defaultProps", {
24387
24404
  togglePrompt: "define me",
24388
24405
  definition: "definition goes here"
24389
24406
  });
24390
- const styles$o = {
24407
+ const styles$n = {
24391
24408
  tooltipBody: {
24392
24409
  color: Color__default["default"].offBlack,
24393
24410
  fontSize: 20,
@@ -24550,15 +24567,15 @@ class Explanation extends React__namespace.Component {
24550
24567
  const onClick = this._onClick;
24551
24568
  if (isMobile) {
24552
24569
  linkContainer = /*#__PURE__*/React__namespace.createElement("div", {
24553
- className: aphrodite.css(styles$n.linkContainer)
24570
+ className: aphrodite.css(styles$m.linkContainer)
24554
24571
  }, /*#__PURE__*/React__namespace.createElement("a", {
24555
- className: aphrodite.css(styles$n.mobileExplanationLink),
24572
+ className: aphrodite.css(styles$m.mobileExplanationLink),
24556
24573
  href: href,
24557
24574
  onClick: onClick,
24558
24575
  role: "button",
24559
24576
  "aria-expanded": this.state.expanded
24560
24577
  }, linkAnchor), this.state.expanded && /*#__PURE__*/React__namespace.createElement("svg", {
24561
- className: aphrodite.css(styles$n.disclosureArrow)
24578
+ className: aphrodite.css(styles$m.disclosureArrow)
24562
24579
  }, /*#__PURE__*/React__namespace.createElement("polygon", {
24563
24580
  style: {
24564
24581
  fill: backgroundColor
@@ -24571,13 +24588,13 @@ class Explanation extends React__namespace.Component {
24571
24588
  // an anchor tag (if rendered in a modal) or a Wonder Blocks
24572
24589
  // link component in lesson page, see: `article-page.jsx`.
24573
24590
  linkContainer = /*#__PURE__*/React__namespace.createElement("div", {
24574
- className: aphrodite.css(styles$n.linkContainer, styles$n.articleLink)
24591
+ className: aphrodite.css(styles$m.linkContainer, styles$m.articleLink)
24575
24592
  }, /*#__PURE__*/React__namespace.createElement(Link, {
24576
- className: aphrodite.css(styles$n.explanationLink)
24593
+ className: aphrodite.css(styles$m.explanationLink)
24577
24594
  // HACK(michaelpolyak): WB Link doesn't passthrough
24578
24595
  // class name.
24579
24596
  ,
24580
- style: styles$n.explanationLink,
24597
+ style: styles$m.explanationLink,
24581
24598
  href: href,
24582
24599
  onClick: onClick,
24583
24600
  role: "button",
@@ -24587,9 +24604,9 @@ class Explanation extends React__namespace.Component {
24587
24604
  // NOTE: For exercises, the baseElements `Link` is an
24588
24605
  // anchor tag, see: `perseus-api.jsx`.
24589
24606
  linkContainer = /*#__PURE__*/React__namespace.createElement("div", {
24590
- className: aphrodite.css(styles$n.linkContainer, styles$n.exerciseLink)
24607
+ className: aphrodite.css(styles$m.linkContainer, styles$m.exerciseLink)
24591
24608
  }, /*#__PURE__*/React__namespace.createElement(Link, {
24592
- className: aphrodite.css(styles$n.explanationLink),
24609
+ className: aphrodite.css(styles$m.explanationLink),
24593
24610
  href: href,
24594
24611
  onClick: onClick,
24595
24612
  role: "button",
@@ -24597,11 +24614,11 @@ class Explanation extends React__namespace.Component {
24597
24614
  }, "[".concat(linkAnchor, "]")));
24598
24615
  }
24599
24616
  }
24600
- const expandedStyle = isMobile ? styles$n.contentExpandedMobile : styles$n.contentExpanded;
24617
+ const expandedStyle = isMobile ? styles$m.contentExpandedMobile : styles$m.contentExpanded;
24601
24618
  return /*#__PURE__*/React__namespace.createElement("div", {
24602
- className: aphrodite.css(styles$n.container)
24619
+ className: aphrodite.css(styles$m.container)
24603
24620
  }, linkContainer, this.state.expanded && /*#__PURE__*/React__namespace.createElement("div", {
24604
- className: aphrodite.css(styles$n.content, isMobile && styles$n.contentMobile, this.state.expanded && expandedStyle)
24621
+ className: aphrodite.css(styles$m.content, isMobile && styles$m.contentMobile, this.state.expanded && expandedStyle)
24605
24622
  // eslint-disable-next-line react/no-string-refs
24606
24623
  ,
24607
24624
  ref: "content"
@@ -24625,7 +24642,7 @@ const verticalContentPadding = 10;
24625
24642
  const arrowWidth = 30;
24626
24643
  const arrowHeight = 14;
24627
24644
  const backgroundColor = gray95;
24628
- const styles$n = aphrodite.StyleSheet.create({
24645
+ const styles$m = aphrodite.StyleSheet.create({
24629
24646
  container: {
24630
24647
  display: "inline",
24631
24648
  position: "relative"
@@ -24751,15 +24768,15 @@ class GradedGroupAnswerBar extends React__namespace.Component {
24751
24768
  onNextQuestion
24752
24769
  } = this.props;
24753
24770
  const answerBarStyle = {
24754
- ...styles$m.answerBar,
24771
+ ...styles$l.answerBar,
24755
24772
  backgroundColor: answerBarState === "CORRECT" ? Color__default["default"].offWhite : "white",
24756
24773
  // Center the "Correct!" message only when there's no next question
24757
24774
  justifyContent: answerBarState === "CORRECT" && !onNextQuestion ? "center" : "space-between"
24758
24775
  };
24759
24776
  const message = answerBarState === "INCORRECT" ? /*#__PURE__*/React__namespace.createElement("span", {
24760
- style: styles$m.text
24777
+ style: styles$l.text
24761
24778
  }, /*#__PURE__*/React__namespace.createElement("span", {
24762
- style: styles$m.tryAgainIcon
24779
+ style: styles$l.tryAgainIcon
24763
24780
  }, /*#__PURE__*/React__namespace.createElement(InlineIcon, iconTryAgain)), /*#__PURE__*/React__namespace.createElement("span", {
24764
24781
  style: {
24765
24782
  marginLeft: 8
@@ -24778,7 +24795,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
24778
24795
  return /*#__PURE__*/React__namespace.createElement("div", {
24779
24796
  style: answerBarStyle
24780
24797
  }, /*#__PURE__*/React__namespace.createElement("span", {
24781
- style: styles$m.text
24798
+ style: styles$l.text
24782
24799
  }, /*#__PURE__*/React__namespace.createElement("span", {
24783
24800
  style: {
24784
24801
  fontSize: 28,
@@ -24800,7 +24817,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
24800
24817
  }
24801
24818
  }
24802
24819
  const fontSize = 17;
24803
- const styles$m = {
24820
+ const styles$l = {
24804
24821
  answerBar: {
24805
24822
  display: "flex",
24806
24823
  alignItems: "center",
@@ -24982,7 +24999,7 @@ class GradedGroup extends React__namespace.Component {
24982
24999
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
24983
25000
  gradeStatus = i18n__namespace._("Incorrect");
24984
25001
  }
24985
- const mobileClass = this.props.inGradedGroupSet ? aphrodite.css(styles$l.gradedGroupInSet) : aphrodite.css(styles$l.gradedGroup);
25002
+ const mobileClass = this.props.inGradedGroupSet ? aphrodite.css(styles$k.gradedGroupInSet) : aphrodite.css(styles$k.gradedGroup);
24986
25003
  const classes = classNames__default["default"]({
24987
25004
  [mobileClass]: apiOptions.isMobile,
24988
25005
  "perseus-graded-group": true,
@@ -25001,7 +25018,7 @@ class GradedGroup extends React__namespace.Component {
25001
25018
  return /*#__PURE__*/React__namespace.createElement("div", {
25002
25019
  className: classes
25003
25020
  }, !!this.props.title && /*#__PURE__*/React__namespace.createElement("div", {
25004
- className: aphrodite.css(styles$l.title)
25021
+ className: aphrodite.css(styles$k.title)
25005
25022
  }, this.props.title), /*#__PURE__*/React__namespace.createElement(Renderer, _extends({}, this.props, {
25006
25023
  // eslint-disable-next-line react/no-string-refs
25007
25024
  ref: "renderer",
@@ -25034,7 +25051,7 @@ class GradedGroup extends React__namespace.Component {
25034
25051
  }, i18n__namespace._("Next question")), this.props.hint && this.props.hint.content && (this.state.showHint ? /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("button", {
25035
25052
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
25036
25053
  tabIndex: "0",
25037
- className: aphrodite.css(styles$l.explanationTitle),
25054
+ className: aphrodite.css(styles$k.explanationTitle),
25038
25055
  onClick: () => this.setState({
25039
25056
  showHint: false
25040
25057
  }),
@@ -25066,7 +25083,7 @@ class GradedGroup extends React__namespace.Component {
25066
25083
  showHint: true
25067
25084
  });
25068
25085
  },
25069
- className: aphrodite.css(styles$l.showHintLink)
25086
+ className: aphrodite.css(styles$k.showHintLink)
25070
25087
  }, i18n__namespace._("Explain"))), apiOptions.isMobile && answerBarState !== "HIDDEN" && /*#__PURE__*/React__namespace.createElement(GradedGroupAnswerBar, {
25071
25088
  apiOptions: apiOptions,
25072
25089
  answerBarState: answerBarState,
@@ -25087,7 +25104,7 @@ _defineProperty(GradedGroup, "defaultProps", {
25087
25104
  const traverseChildWidgets$3 = function (props, traverseRenderer) {
25088
25105
  return ___default["default"].extend({}, props, traverseRenderer(props));
25089
25106
  };
25090
- const styles$l = aphrodite.StyleSheet.create({
25107
+ const styles$k = aphrodite.StyleSheet.create({
25091
25108
  gradedGroupInSet: {
25092
25109
  // Reset a few desktop-only styles that come from graded-group.less
25093
25110
  marginLeft: 0,
@@ -25158,7 +25175,7 @@ class Indicators extends React__namespace.Component {
25158
25175
  }
25159
25176
  render() {
25160
25177
  return /*#__PURE__*/React__namespace.createElement("ul", {
25161
- className: aphrodite.css(styles$k.indicatorContainer)
25178
+ className: aphrodite.css(styles$j.indicatorContainer)
25162
25179
  }, this.props.gradedGroups.map((_ref, i) => {
25163
25180
  let {
25164
25181
  title
@@ -25169,7 +25186,7 @@ class Indicators extends React__namespace.Component {
25169
25186
  title
25170
25187
  }),
25171
25188
  key: title,
25172
- className: aphrodite.css(styles$k.indicator, i === this.props.currentGroup && styles$k.selectedIndicator),
25189
+ className: aphrodite.css(styles$j.indicator, i === this.props.currentGroup && styles$j.selectedIndicator),
25173
25190
  tabIndex: 0,
25174
25191
  onClick: () => this.props.onChangeCurrentGroup(i),
25175
25192
  onKeyDown: e => this.handleKeyDown(e, i)
@@ -25239,7 +25256,7 @@ class GradedGroupSet extends React__namespace.Component {
25239
25256
  } = getDependencies();
25240
25257
  if (JIPT.useJIPT && this.props.gradedGroups.length > 1) {
25241
25258
  return /*#__PURE__*/React__namespace.createElement("div", {
25242
- className: aphrodite.css(styles$k.container)
25259
+ className: aphrodite.css(styles$j.container)
25243
25260
  }, this.props.gradedGroups.map((gradedGroup, i) => {
25244
25261
  return (
25245
25262
  /*#__PURE__*/
@@ -25262,13 +25279,13 @@ class GradedGroupSet extends React__namespace.Component {
25262
25279
  const numGroups = this.props.gradedGroups.length;
25263
25280
  const handleNextQuestion = this.state.currentGroup < numGroups - 1 ? this.handleNextQuestion : null;
25264
25281
  return /*#__PURE__*/React__namespace.createElement("div", {
25265
- className: aphrodite.css(styles$k.container)
25282
+ className: aphrodite.css(styles$j.container)
25266
25283
  }, /*#__PURE__*/React__namespace.createElement("div", {
25267
- className: aphrodite.css(styles$k.top)
25284
+ className: aphrodite.css(styles$j.top)
25268
25285
  }, /*#__PURE__*/React__namespace.createElement("div", {
25269
- className: aphrodite.css(styles$k.title)
25286
+ className: aphrodite.css(styles$j.title)
25270
25287
  }, currentGroup.title), /*#__PURE__*/React__namespace.createElement("div", {
25271
- className: aphrodite.css(styles$k.spacer)
25288
+ className: aphrodite.css(styles$j.spacer)
25272
25289
  }), /*#__PURE__*/React__namespace.createElement(Indicators, {
25273
25290
  currentGroup: this.state.currentGroup,
25274
25291
  gradedGroups: this.props.gradedGroups,
@@ -25310,7 +25327,7 @@ var GradedGroupSet$1 = {
25310
25327
  tracking: "all",
25311
25328
  isLintable: true
25312
25329
  };
25313
- const styles$k = aphrodite.StyleSheet.create({
25330
+ const styles$j = aphrodite.StyleSheet.create({
25314
25331
  top: {
25315
25332
  display: "flex",
25316
25333
  flexDirection: "row"
@@ -25392,7 +25409,7 @@ class ButtonGroup extends React__namespace.Component {
25392
25409
  id: "" + i,
25393
25410
  ref: "button" + i,
25394
25411
  key: "" + i,
25395
- className: aphrodite.css(styles$j.buttonStyle, button.value === value && styles$j.selectedStyle),
25412
+ className: aphrodite.css(styles$i.buttonStyle, button.value === value && styles$i.selectedStyle),
25396
25413
  onClick: () => this.toggleSelect(button.value)
25397
25414
  }, button.content || "" + button.value);
25398
25415
  });
@@ -25409,7 +25426,7 @@ _defineProperty(ButtonGroup, "defaultProps", {
25409
25426
  value: null,
25410
25427
  allowEmpty: true
25411
25428
  });
25412
- const styles$j = aphrodite.StyleSheet.create({
25429
+ const styles$i = aphrodite.StyleSheet.create({
25413
25430
  buttonStyle: {
25414
25431
  backgroundColor: "white",
25415
25432
  border: "1px solid #ccc",
@@ -26876,10 +26893,9 @@ class ImageWidget extends React__namespace.Component {
26876
26893
  // This minWidth takes precedence over minWidth applied via
26877
26894
  // Aphrodite.
26878
26895
  const minWidth = isImageFullWidth ? null : "0 !important";
26879
- titleAndCaption = /*#__PURE__*/React__namespace.createElement("div", {
26896
+ titleAndCaption = /*#__PURE__*/React__namespace.createElement("figcaption", {
26880
26897
  className: className
26881
26898
  }, /*#__PURE__*/React__namespace.createElement("div", {
26882
- className: aphrodite.css(styles$i.caption),
26883
26899
  style: {
26884
26900
  // @ts-expect-error - TS2322 - Type 'string | null' is not assignable to type 'MinWidth<string | number> | undefined'.
26885
26901
  minWidth: minWidth
@@ -26890,7 +26906,7 @@ class ImageWidget extends React__namespace.Component {
26890
26906
  linterContext: this.props.linterContext
26891
26907
  })));
26892
26908
  }
26893
- return /*#__PURE__*/React__namespace.createElement("div", {
26909
+ return /*#__PURE__*/React__namespace.createElement("figure", {
26894
26910
  className: "perseus-image-widget"
26895
26911
  }, image, alt, titleAndCaption);
26896
26912
  }
@@ -26906,7 +26922,7 @@ class ImageWidget extends React__namespace.Component {
26906
26922
  }));
26907
26923
  }
26908
26924
  if (this.props.caption) {
26909
- caption = /*#__PURE__*/React__namespace.createElement("div", {
26925
+ caption = /*#__PURE__*/React__namespace.createElement("figcaption", {
26910
26926
  className: "perseus-image-caption"
26911
26927
  }, /*#__PURE__*/React__namespace.createElement(Renderer, {
26912
26928
  content: this.props.caption,
@@ -26914,7 +26930,7 @@ class ImageWidget extends React__namespace.Component {
26914
26930
  linterContext: this.props.linterContext
26915
26931
  }));
26916
26932
  }
26917
- return /*#__PURE__*/React__namespace.createElement("div", {
26933
+ return /*#__PURE__*/React__namespace.createElement("figure", {
26918
26934
  className: "perseus-image-widget"
26919
26935
  }, title, image, alt, caption);
26920
26936
  }
@@ -26938,22 +26954,6 @@ _defineProperty(ImageWidget, "defaultProps", {
26938
26954
  caption: "",
26939
26955
  linterContext: PerseusLinter.linterContextDefault
26940
26956
  });
26941
- const styles$i = aphrodite.StyleSheet.create({
26942
- caption: {
26943
- display: "inline-block",
26944
- marginTop: baseUnitPx,
26945
- maxWidth: 640,
26946
- [mediaQueries.lgOrSmaller]: {
26947
- // TODO(david): This maxWidth is not being used because
26948
- // it's overriden by the 512px max-width we have on
26949
- // paragraphs.
26950
- maxWidth: 540
26951
- },
26952
- [mediaQueries.smOrSmaller]: {
26953
- maxWidth: 450
26954
- }
26955
- }
26956
- });
26957
26957
  var Image$1 = {
26958
26958
  name: "image",
26959
26959
  // This widget's accessibility depends on its contents: if the image has