@khanacademy/perseus 56.2.0 → 57.0.1

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
@@ -354,8 +354,8 @@ const mockStrings = {
354
354
  simulationLocaleWarning: "Sorry, this simulation isn't available in your language.",
355
355
  selectAnAnswer: "Select an answer",
356
356
  // The following strings are used for interactive graph SR descriptions.
357
- srGraphInstructions: "Use the Tab key to move through the interactive elements in the graph. When an interactive element has focus, use the Arrow keys to move it.",
358
- srUnlimitedGraphInstructions: "Press Shift + Enter to interact with the graph. Use the Tab key to move through the interactive elements in the graph and access the graph Action Bar. When an interactive element has focus, use the Arrow keys to move it or use the Delete key to remove it from the graph. Use the buttons in the Action Bar to add or adjust elements within the graph.",
357
+ srGraphInstructions: "Use the Tab key to move through the interactive elements in the graph. When an interactive element has focus, use Control + Shift + Arrows to move it.",
358
+ srUnlimitedGraphInstructions: "Press Shift + Enter to interact with the graph. Use the Tab key to move through the interactive elements in the graph and access the graph Action Bar. When an interactive element has focus, use Control + Shift + Arrows to move it or use the Delete key to remove it from the graph. Use the buttons in the Action Bar to add or adjust elements within the graph.",
359
359
  xAxis: "X-axis",
360
360
  yAxis: "Y-axis",
361
361
  graphKeyboardPrompt: "Press Shift + Enter to interact with the graph",
@@ -16854,7 +16854,7 @@ class Zoomable extends React__namespace.Component {
16854
16854
  * measurements.
16855
16855
  */
16856
16856
  const computeMathBounds = (parentNode, parentBounds) => {
16857
- const textElement = parentNode.querySelector(".katex-html") || parentNode.querySelector(".MathJax");
16857
+ const textElement = parentNode.querySelector(".MathJax");
16858
16858
  const textBounds = {
16859
16859
  // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'offsetWidth' does not exist on type 'Element'.
16860
16860
  width: textElement.offsetWidth,
@@ -19177,14 +19177,7 @@ class Renderer extends React__namespace.Component {
19177
19177
  }))));
19178
19178
  }
19179
19179
  if (node.type === "math") {
19180
- // Replace uses of \begin{align}...\end{align} which KaTeX doesn't
19181
- // support (yet) with \begin{aligned}...\end{aligned} which renders
19182
- // the same is supported by KaTeX. It does the same for align*.
19183
- // TODO(kevinb) update content to use aligned instead of align.
19184
- // TODO(LEMS-1608) Remove this replacement as MathJax supports the
19185
- // "align" macro correctly (and, in fact, it is not synonymous with
19186
- // "aligned").
19187
- const tex = node.content.replace(/\{align[*]?\}/g, "{aligned}");
19180
+ const tex = node.content;
19188
19181
 
19189
19182
  // We render math here instead of in perseus-markdown.jsx
19190
19183
  // because we need to pass it our onRender callback.
@@ -24419,7 +24412,8 @@ const _choiceTransform = (widgetOptions, strings, problemNum) => {
24419
24412
  const choices = widgetOptions.choices.map((choice, i) => {
24420
24413
  return {
24421
24414
  ...choice,
24422
- originalIndex: i
24415
+ originalIndex: i,
24416
+ correct: Boolean(choice.correct)
24423
24417
  };
24424
24418
  });
24425
24419
 
@@ -25420,7 +25414,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
25420
25414
  }, nextQuestion));
25421
25415
  }
25422
25416
  }
25423
- const fontSize = 17;
25417
+ const fontSize$1 = 17;
25424
25418
  const styles$j = {
25425
25419
  answerBar: {
25426
25420
  display: "flex",
@@ -25445,7 +25439,7 @@ const styles$j = {
25445
25439
  flexDirection: "row",
25446
25440
  alignItems: "center",
25447
25441
  fontWeight: "bold",
25448
- fontSize: fontSize
25442
+ fontSize: fontSize$1
25449
25443
  }
25450
25444
  };
25451
25445
 
@@ -28132,6 +28126,7 @@ const defaultGraphConfig = {
28132
28126
  width: 0,
28133
28127
  height: 0,
28134
28128
  labels: [],
28129
+ labelLocation: "onAxis",
28135
28130
  disableKeyboardInteraction: false,
28136
28131
  interactiveColor: "var(--mafs-blue)"
28137
28132
  };
@@ -28355,6 +28350,8 @@ function escapeIfUnescaped(character) {
28355
28350
  }
28356
28351
  }
28357
28352
 
28353
+ // Exported for testing purposes
28354
+ const fontSize = 14;
28358
28355
  function AxisLabels(_ref) {
28359
28356
  let {
28360
28357
  i18n
@@ -28363,24 +28360,26 @@ function AxisLabels(_ref) {
28363
28360
  range,
28364
28361
  labels,
28365
28362
  width,
28366
- height
28363
+ height,
28364
+ labelLocation
28367
28365
  } = useGraphConfig();
28368
28366
  const {
28369
28367
  strings
28370
28368
  } = i18n;
28371
- const yAxisLabelLocation = [0, range[Y][MAX]];
28372
- const xAxisLabelLocation = [range[X][MAX], 0];
28373
- const [xAxisLabelText, yAxisLabelText] = labels;
28374
28369
  const graphInfo = {
28375
28370
  range,
28376
28371
  width,
28377
28372
  height
28378
28373
  };
28379
- const [x1, y1] = pointToPixel(xAxisLabelLocation, graphInfo);
28380
- // The default location for the y-axis-label is at the maximum y point
28381
- // This is just underneath the tick line for that point. The -24 moves the
28382
- // label up one grid square, so it sits on top of the graph
28383
- const [x2, y2] = mafs.vec.add(pointToPixel(yAxisLabelLocation, graphInfo), [0, -24]);
28374
+
28375
+ // Get the position of the main axis labels
28376
+ const [xAxisLabelLocation, yAxisLabelLocation] = getLabelPosition(graphInfo, labelLocation);
28377
+ const [xAxisLabelText, yAxisLabelText] = labels;
28378
+
28379
+ // If the labels are rotated, we need to center the
28380
+ // x-axis label along the bottom of the graph.
28381
+ const xLabelTransform = labelLocation === "onAxis" ? "translate(7px, -50%)" : "translate(-50%, -50%)";
28382
+ const yLabelTransform = labelLocation === "onAxis" ? "translate(-50%, 0px)" : "translate(-50%, 0px) rotate(-90deg)";
28384
28383
  const {
28385
28384
  TeX
28386
28385
  } = getDependencies();
@@ -28388,22 +28387,53 @@ function AxisLabels(_ref) {
28388
28387
  "aria-label": strings.xAxis,
28389
28388
  style: {
28390
28389
  position: "absolute",
28391
- left: x1,
28392
- top: y1,
28393
- fontSize: "14px",
28394
- transform: "translate(7px, -50%)"
28390
+ left: xAxisLabelLocation[X],
28391
+ top: xAxisLabelLocation[Y],
28392
+ fontSize: fontSize + "px",
28393
+ transform: xLabelTransform
28395
28394
  }
28396
28395
  }, /*#__PURE__*/React__default["default"].createElement(TeX, null, replaceOutsideTeX(xAxisLabelText))), /*#__PURE__*/React__default["default"].createElement("span", {
28397
28396
  "aria-label": strings.yAxis,
28398
28397
  style: {
28399
28398
  position: "absolute",
28400
- left: x2,
28401
- top: y2,
28402
- fontSize: "14px",
28403
- transform: "translate(-50%, 0px)"
28399
+ left: yAxisLabelLocation[X],
28400
+ top: yAxisLabelLocation[Y],
28401
+ fontSize: fontSize + "px",
28402
+ transform: yLabelTransform
28404
28403
  }
28405
28404
  }, /*#__PURE__*/React__default["default"].createElement(TeX, null, replaceOutsideTeX(yAxisLabelText))));
28406
28405
  }
28406
+ const getLabelPosition = (graphInfo, labelLocation) => {
28407
+ // If the labels are placed along the edge of the graph, we need to place them at the
28408
+ // center of the graph, which is the average of the min and max values of the axes.
28409
+ if (labelLocation === "alongEdge") {
28410
+ // Offset the labels by a certain amount based on the range of the graph, to ensure that
28411
+ // the labels do not overlap with the axis tick if they are out of the graph bounds.
28412
+ const xAxisLabelOffset = graphInfo.range[Y][MIN] >= 0 ? [0, fontSize * 3] // Move the label down by 3 font sizes if the y-axis min is positive
28413
+ : [0, fontSize]; // Move the label down by 1 font size if the y-axis min is negative
28414
+ const yAxisLabelOffset = graphInfo.range[X][MIN] >= 0 ? [-fontSize * 3, -fontSize] // Move the label left by 3 font sizes if the x-axis min is positive
28415
+ : [-fontSize, -fontSize]; // Move the label left by 1 font size if the x-axis min is negative
28416
+
28417
+ // Calculate the location of the labels to be halfway between the min and max values of the axes
28418
+ const xAxisLabelLocation = [(graphInfo.range[X][MIN] + graphInfo.range[X][MAX]) / 2, graphInfo.range[Y][MIN]];
28419
+ const yAxisLabelLocation = [graphInfo.range[X][MIN], (graphInfo.range[Y][MIN] + graphInfo.range[Y][MAX]) / 2];
28420
+
28421
+ // Convert the Vector2 coordinates to pixel coordinates and add the offsets
28422
+ const xLabel = mafs.vec.add(pointToPixel(xAxisLabelLocation, graphInfo), xAxisLabelOffset);
28423
+ const yLabel = mafs.vec.add(pointToPixel(yAxisLabelLocation, graphInfo), yAxisLabelOffset);
28424
+ return [xLabel, yLabel];
28425
+ }
28426
+
28427
+ // Otherwise, the labels are placed on the axes (default), and we need to
28428
+ // place them at the end of the axis, which is the maximum value of the axis.
28429
+ const xLabelInitial = [graphInfo.range[X][MAX], 0];
28430
+ const yLabelInitial = [0, graphInfo.range[Y][MAX]];
28431
+ const yLabelOffset = [0, -fontSize * 2]; // Move the y-axis label up by 2 font sizes
28432
+
28433
+ const xLabel = pointToPixel(xLabelInitial, graphInfo);
28434
+ const yLabel = mafs.vec.add(pointToPixel(yLabelInitial, graphInfo), yLabelOffset);
28435
+ return [xLabel, yLabel];
28436
+ };
28407
28437
 
28408
28438
  // The size of the ticks and labels in pixels
28409
28439
  const tickSize = 10;
@@ -30636,6 +30666,7 @@ function useDraggable(args) {
30636
30666
  const {
30637
30667
  direction: yDownDirection,
30638
30668
  altKey,
30669
+ ctrlKey,
30639
30670
  metaKey,
30640
30671
  shiftKey
30641
30672
  } = state;
@@ -30645,7 +30676,7 @@ function useDraggable(args) {
30645
30676
  if (altKey || metaKey) {
30646
30677
  divisions = 200;
30647
30678
  }
30648
- if (shiftKey) {
30679
+ if (shiftKey && !ctrlKey) {
30649
30680
  divisions = 10;
30650
30681
  }
30651
30682
  const min = span / (divisions * 2);
@@ -31179,6 +31210,35 @@ const MovablePoint$1 = /*#__PURE__*/React__namespace.forwardRef((props, pointRef
31179
31210
  return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, focusableHandle, visiblePoint);
31180
31211
  });
31181
31212
 
31213
+ /**
31214
+ * If an element has an `aria-describedby` attribute, it needs to point to
31215
+ * a separate description element that contains the description for that
31216
+ * element.
31217
+ *
31218
+ * If the element is within an SVG, the description element must be a
31219
+ * `<span>` within a `<foreignObject>` in order for some browser/SR
31220
+ * combos to be able to access it.
31221
+ *
31222
+ * Use this SRDescInSVG component to create the <foreignObject>
31223
+ * and styling for this description element.
31224
+ */
31225
+ function SRDescInSVG(props) {
31226
+ const {
31227
+ id,
31228
+ children
31229
+ } = props;
31230
+ return /*#__PURE__*/React__namespace.createElement("foreignObject", null, /*#__PURE__*/React__namespace.createElement("span", {
31231
+ id: id
31232
+ // Hidden visually
31233
+ ,
31234
+ style: a11y.srOnly
31235
+ // Hidden from screen readers so they don't read this
31236
+ // again outside of the element that it describes.
31237
+ ,
31238
+ "aria-hidden": true
31239
+ }, children));
31240
+ }
31241
+
31182
31242
  const {
31183
31243
  calculateAngleInDegrees: calculateAngleInDegrees$1,
31184
31244
  getClockwiseAngle: getClockwiseAngle$2,
@@ -31286,9 +31346,8 @@ function AngleGraph(props) {
31286
31346
  constrain: getAngleSideConstraint(coords[2], coords[1], snapDegrees || 1),
31287
31347
  onMove: destination => dispatch(actions.angle.movePoint(2, destination)),
31288
31348
  ariaLabel: srAngleStartingSide
31289
- }), /*#__PURE__*/React__namespace.createElement("g", {
31290
- id: descriptionId,
31291
- style: a11y.srOnly
31349
+ }), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
31350
+ id: descriptionId
31292
31351
  }, srAngleGraphAriaDescription));
31293
31352
  }
31294
31353
  function getAngleGraphDescription(state, i18n) {
@@ -31577,12 +31636,10 @@ function CircleGraph(props) {
31577
31636
  dispatch(actions.circle.moveRadiusPoint(newRadiusPoint));
31578
31637
  },
31579
31638
  constrain: getCircleKeyboardConstraint(center, radiusPoint, snapStep)
31580
- }), /*#__PURE__*/React__namespace.createElement("g", {
31581
- id: radiusId,
31582
- style: a11y.srOnly
31583
- }, srCircleRadius), /*#__PURE__*/React__namespace.createElement("g", {
31584
- id: outerPointsId,
31585
- style: a11y.srOnly
31639
+ }), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
31640
+ id: radiusId
31641
+ }, srCircleRadius), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
31642
+ id: outerPointsId
31586
31643
  }, srCircleOuterPoints));
31587
31644
  }
31588
31645
  function MovableCircle(props) {
@@ -31829,15 +31886,12 @@ const LinearGraph = (props, key) => {
31829
31886
  end: true
31830
31887
  },
31831
31888
  onMovePoint: (endpointIndex, destination) => dispatch(actions.linear.movePoint(endpointIndex, destination))
31832
- }), /*#__PURE__*/React__namespace.createElement("g", {
31833
- id: pointsDescriptionId,
31834
- style: a11y.srOnly
31835
- }, srLinearGraphPoints), /*#__PURE__*/React__namespace.createElement("g", {
31836
- id: interceptDescriptionId,
31837
- style: a11y.srOnly
31838
- }, interceptString), /*#__PURE__*/React__namespace.createElement("g", {
31839
- id: slopeDescriptionId,
31840
- style: a11y.srOnly
31889
+ }), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
31890
+ id: pointsDescriptionId
31891
+ }, srLinearGraphPoints), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
31892
+ id: interceptDescriptionId
31893
+ }, interceptString), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
31894
+ id: slopeDescriptionId
31841
31895
  }, slopeString));
31842
31896
  };
31843
31897
  function getLinearGraphDescription(state, i18n) {
@@ -31971,7 +32025,7 @@ const LinearSystemGraph = props => {
31971
32025
  end: true
31972
32026
  },
31973
32027
  onMovePoint: (endpointIndex, destination) => dispatch(actions.linearSystem.movePointInFigure(i, endpointIndex, destination))
31974
- })), linesAriaInfo.map(_ref2 => {
32028
+ })), linesAriaInfo.map((_ref2, i) => {
31975
32029
  let {
31976
32030
  pointsDescriptionId,
31977
32031
  interceptDescriptionId,
@@ -31980,22 +32034,17 @@ const LinearSystemGraph = props => {
31980
32034
  interceptDescription,
31981
32035
  slopeDescription
31982
32036
  } = _ref2;
31983
- return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("g", {
31984
- key: pointsDescriptionId,
31985
- id: pointsDescriptionId,
31986
- style: a11y.srOnly
31987
- }, pointsDescription), /*#__PURE__*/React__namespace.createElement("g", {
31988
- key: interceptDescriptionId,
31989
- id: interceptDescriptionId,
31990
- style: a11y.srOnly
31991
- }, interceptDescription), /*#__PURE__*/React__namespace.createElement("g", {
31992
- key: slopeDescriptionId,
31993
- id: slopeDescriptionId,
31994
- style: a11y.srOnly
32037
+ return /*#__PURE__*/React__namespace.createElement("span", {
32038
+ key: `line-descriptions-${i}`
32039
+ }, /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
32040
+ id: pointsDescriptionId
32041
+ }, pointsDescription), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
32042
+ id: interceptDescriptionId
32043
+ }, interceptDescription), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
32044
+ id: slopeDescriptionId
31995
32045
  }, slopeDescription));
31996
- }), /*#__PURE__*/React__namespace.createElement("g", {
31997
- id: intersectionId,
31998
- style: a11y.srOnly
32046
+ }), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
32047
+ id: intersectionId
31999
32048
  }, intersectionDescription));
32000
32049
  };
32001
32050
 
@@ -33597,23 +33646,21 @@ const LimitedPolygonGraph = statefulProps => {
33597
33646
  // point is "polite".
33598
33647
  setAriaLives(["off", ...newPointAriaLives]);
33599
33648
  }
33600
- }), angleDegree && /*#__PURE__*/React__namespace.createElement("g", {
33649
+ }), angleDegree && /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
33601
33650
  id: angleId
33602
33651
  }, Number.isInteger(angleDegree) ? strings.srPolygonPointAngle({
33603
33652
  angle: angleDegree
33604
33653
  }) : strings.srPolygonPointAngleApprox({
33605
33654
  angle: srFormatNumber(angleDegree, locale, 1)
33606
- })), /*#__PURE__*/React__namespace.createElement("g", {
33655
+ })), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
33607
33656
  id: side1Id
33608
- }, getPolygonSideString(side1Length, point1Index, strings, locale)), /*#__PURE__*/React__namespace.createElement("g", {
33657
+ }, getPolygonSideString(side1Length, point1Index, strings, locale)), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
33609
33658
  id: side2Id
33610
33659
  }, getPolygonSideString(side2Length, point2Index, strings, locale)));
33611
- }), /*#__PURE__*/React__namespace.createElement("g", {
33612
- id: polygonPointsNumId,
33613
- style: a11y.srOnly
33614
- }, srPolygonGraphPointsNum), srPolygonGraphPoints && /*#__PURE__*/React__namespace.createElement("g", {
33615
- id: polygonPointsId,
33616
- style: a11y.srOnly
33660
+ }), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
33661
+ id: polygonPointsNumId
33662
+ }, srPolygonGraphPointsNum), srPolygonGraphPoints && /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
33663
+ id: polygonPointsId
33617
33664
  }, srPolygonGraphPoints));
33618
33665
  };
33619
33666
  const UnlimitedPolygonGraph = statefulProps => {
@@ -33749,7 +33796,7 @@ const UnlimitedPolygonGraph = statefulProps => {
33749
33796
  }
33750
33797
  dispatch(actions.polygon.clickPoint(i));
33751
33798
  }
33752
- }), angleDegree && /*#__PURE__*/React__namespace.createElement("g", {
33799
+ }), angleDegree && /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
33753
33800
  id: angleId
33754
33801
  }, Number.isInteger(angleDegree) ? strings.srPolygonPointAngle({
33755
33802
  angle: angleDegree
@@ -33760,17 +33807,15 @@ const UnlimitedPolygonGraph = statefulProps => {
33760
33807
  pointIndex,
33761
33808
  sideLength
33762
33809
  } = _ref2;
33763
- return /*#__PURE__*/React__namespace.createElement("g", {
33810
+ return /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
33764
33811
  key: `${id}-point-${i}-side-${j}`,
33765
33812
  id: `${id}-point-${i}-side-${j}`
33766
33813
  }, getPolygonSideString(sideLength, pointIndex, strings, locale));
33767
33814
  }));
33768
- }), coords.length > 0 && /*#__PURE__*/React__namespace.createElement("g", {
33769
- id: polygonPointsNumId,
33770
- style: a11y.srOnly
33771
- }, srPolygonGraphPointsNum), srPolygonGraphPoints && /*#__PURE__*/React__namespace.createElement("g", {
33772
- id: polygonPointsId,
33773
- style: a11y.srOnly
33815
+ }), coords.length > 0 && /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
33816
+ id: polygonPointsNumId
33817
+ }, srPolygonGraphPointsNum), srPolygonGraphPoints && /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
33818
+ id: polygonPointsId
33774
33819
  }, srPolygonGraphPoints));
33775
33820
  };
33776
33821
  function getLines(points) {
@@ -34024,15 +34069,12 @@ function QuadraticGraph(props) {
34024
34069
  constrain: getQuadraticKeyboardConstraint(coords, snapStep, i),
34025
34070
  onMove: destination => dispatch(actions.quadratic.movePoint(i, destination))
34026
34071
  });
34027
- }), srQuadraticDirection && /*#__PURE__*/React__namespace.createElement("g", {
34028
- id: quadraticDirectionId,
34029
- style: a11y.srOnly
34030
- }, srQuadraticDirection), srQuadraticVertex && /*#__PURE__*/React__namespace.createElement("g", {
34031
- id: quadraticVertexId,
34032
- style: a11y.srOnly
34033
- }, srQuadraticVertex), /*#__PURE__*/React__namespace.createElement("g", {
34034
- id: quadraticInterceptsId,
34035
- style: a11y.srOnly
34072
+ }), srQuadraticDirection && /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
34073
+ id: quadraticDirectionId
34074
+ }, srQuadraticDirection), srQuadraticVertex && /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
34075
+ id: quadraticVertexId
34076
+ }, srQuadraticVertex), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
34077
+ id: quadraticInterceptsId
34036
34078
  }, srQuadraticXIntercepts ? `${srQuadraticXIntercepts} ${srQuadraticYIntercept}` : `${srQuadraticYIntercept}`));
34037
34079
  }
34038
34080
 
@@ -34220,9 +34262,8 @@ const RayGraph = props => {
34220
34262
  start: false,
34221
34263
  end: true
34222
34264
  }
34223
- }), /*#__PURE__*/React__namespace.createElement("g", {
34224
- id: pointsDescriptionId,
34225
- style: a11y.srOnly
34265
+ }), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
34266
+ id: pointsDescriptionId
34226
34267
  }, srRayPoints));
34227
34268
  };
34228
34269
  function getRayGraphDescription(state, i18n) {
@@ -34362,13 +34403,11 @@ const SegmentGraph = _ref => {
34362
34403
  point2Y: srFormatNumber(segment[1][Y], locale)
34363
34404
  })
34364
34405
  }
34365
- }), /*#__PURE__*/React__namespace.createElement("g", {
34366
- id: lengthDescriptionId,
34367
- style: a11y.srOnly
34406
+ }), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
34407
+ id: lengthDescriptionId
34368
34408
  }, strings.srSegmentLength({
34369
34409
  length: srFormatNumber(getLengthOfSegment(segment), locale)
34370
- })))), /*#__PURE__*/React__namespace.createElement("g", {
34371
- style: a11y.srOnly,
34410
+ })))), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
34372
34411
  id: wholeGraphDescriptionId
34373
34412
  }, getWholeSegmentGraphAriaDescription()));
34374
34413
  };
@@ -34470,7 +34509,7 @@ function SinusoidGraph(props) {
34470
34509
  sequenceNumber: i + 1,
34471
34510
  constrain: getSinusoidKeyboardConstraint(coords, snapStep, i),
34472
34511
  onMove: destination => dispatch(actions.sinusoid.movePoint(i, destination))
34473
- })), /*#__PURE__*/React__namespace.createElement("g", {
34512
+ })), /*#__PURE__*/React__namespace.createElement(SRDescInSVG, {
34474
34513
  id: descriptionId
34475
34514
  }, srSinusoidDescription));
34476
34515
  }
@@ -34744,6 +34783,7 @@ const MafsGraph = props => {
34744
34783
  state,
34745
34784
  dispatch,
34746
34785
  labels,
34786
+ labelLocation,
34747
34787
  readOnly,
34748
34788
  fullGraphAriaLabel,
34749
34789
  fullGraphAriaDescription
@@ -34824,6 +34864,7 @@ const MafsGraph = props => {
34824
34864
  width,
34825
34865
  height,
34826
34866
  labels,
34867
+ labelLocation,
34827
34868
  disableKeyboardInteraction: disableInteraction,
34828
34869
  // If the graph is read-only or static, we want to make it
34829
34870
  // visually clear that the graph is no longer interactive.
@@ -41951,7 +41992,7 @@ const addLibraryVersionToPerseusDebug = (libraryName, libraryVersion) => {
41951
41992
 
41952
41993
  // This file is processed by a Rollup plugin (replace) to inject the production
41953
41994
  const libName = "@khanacademy/perseus";
41954
- const libVersion = "56.2.0";
41995
+ const libVersion = "57.0.1";
41955
41996
  addLibraryVersionToPerseusDebug(libName, libVersion);
41956
41997
 
41957
41998
  const apiVersion = {