@khanacademy/perseus 30.0.1 → 31.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/es/index.js +611 -231
- package/dist/es/index.js.map +1 -1
- package/dist/es/strings.js +6 -2
- package/dist/es/strings.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +623 -235
- package/dist/index.js.map +1 -1
- package/dist/perseus-api.d.ts +2 -0
- package/dist/perseus-types.d.ts +17 -3
- package/dist/server-item-renderer.d.ts +2 -0
- package/dist/strings.d.ts +2 -0
- package/dist/strings.js +6 -2
- package/dist/strings.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/util/widget-enum-utils.d.ts +1 -1
- package/dist/widgets/expression.d.ts +12 -0
- package/dist/widgets/interactive-graphs/graph-locked-labels-layer.d.ts +7 -0
- package/dist/widgets/interactive-graphs/graphs/point.d.ts +2 -0
- package/dist/widgets/interactive-graphs/graphs/use-transform.d.ts +2 -0
- package/dist/widgets/interactive-graphs/interactive-graph-question-builder.d.ts +4 -0
- package/dist/widgets/interactive-graphs/locked-figures/locked-label.d.ts +3 -0
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +1 -0
- package/dist/widgets/interactive-graphs/mafs-supported-graph-types.d.ts +1 -1
- package/dist/widgets/interactive-graphs/reducer/interactive-graph-action.d.ts +8 -1
- package/dist/widgets/interactive-graphs/stateful-mafs-graph.d.ts +1 -0
- package/dist/widgets/interactive-graphs/types.d.ts +1 -0
- package/dist/widgets/label-image.d.ts +4 -0
- package/dist/widgets/phet-simulation.d.ts +61 -0
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -41,6 +41,8 @@ var Switch = require('@khanacademy/wonder-blocks-switch');
|
|
|
41
41
|
var Pill = require('@khanacademy/wonder-blocks-pill');
|
|
42
42
|
var reactPopper = require('react-popper');
|
|
43
43
|
var createReactClass = require('create-react-class');
|
|
44
|
+
var IconButton = require('@khanacademy/wonder-blocks-icon-button');
|
|
45
|
+
var cornersOutIcon = require('@phosphor-icons/core/regular/corners-out.svg');
|
|
44
46
|
var Link = require('@khanacademy/wonder-blocks-link');
|
|
45
47
|
|
|
46
48
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -85,6 +87,8 @@ var questionIcon__default = /*#__PURE__*/_interopDefaultLegacy(questionIcon);
|
|
|
85
87
|
var Switch__default = /*#__PURE__*/_interopDefaultLegacy(Switch);
|
|
86
88
|
var Pill__default = /*#__PURE__*/_interopDefaultLegacy(Pill);
|
|
87
89
|
var createReactClass__default = /*#__PURE__*/_interopDefaultLegacy(createReactClass);
|
|
90
|
+
var IconButton__default = /*#__PURE__*/_interopDefaultLegacy(IconButton);
|
|
91
|
+
var cornersOutIcon__default = /*#__PURE__*/_interopDefaultLegacy(cornersOutIcon);
|
|
88
92
|
var Link__default = /*#__PURE__*/_interopDefaultLegacy(Link);
|
|
89
93
|
|
|
90
94
|
function _extends() {
|
|
@@ -360,7 +364,9 @@ const mockStrings = {
|
|
|
360
364
|
mathInputDescription: "Use keyboard/mouse to interact with math-based input fields",
|
|
361
365
|
sin: "sin",
|
|
362
366
|
cos: "cos",
|
|
363
|
-
tan: "tan"
|
|
367
|
+
tan: "tan",
|
|
368
|
+
simulationLoadFail: "Sorry, this simulation cannot load.",
|
|
369
|
+
simulationLocaleWarning: "Sorry, this simulation isn't available in your language."
|
|
364
370
|
};
|
|
365
371
|
|
|
366
372
|
/**
|
|
@@ -619,7 +625,7 @@ class InnerMathInput extends React__namespace.Component {
|
|
|
619
625
|
className = className + " " + this.props.className;
|
|
620
626
|
}
|
|
621
627
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
622
|
-
style: [styles$
|
|
628
|
+
style: [styles$E.outerWrapper, this.state.focused && styles$E.wrapperFocused, this.props.hasError && styles$E.wrapperError]
|
|
623
629
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
624
630
|
style: {
|
|
625
631
|
display: "flex",
|
|
@@ -654,7 +660,7 @@ class InnerMathInput extends React__namespace.Component {
|
|
|
654
660
|
style: a11y.srOnly
|
|
655
661
|
}, this.context.strings.mathInputDescription), /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.PopoverContentCore, {
|
|
656
662
|
closeButtonVisible: true,
|
|
657
|
-
style: styles$
|
|
663
|
+
style: styles$E.popoverContent
|
|
658
664
|
}, /*#__PURE__*/React__namespace.createElement(mathInput.DesktopKeypad, _extends({
|
|
659
665
|
onAnalyticsEvent: this.props.analytics.onAnalyticsEvent,
|
|
660
666
|
extraKeys: this.props.extraKeys,
|
|
@@ -719,9 +725,9 @@ const MathInputIcon = _ref => {
|
|
|
719
725
|
fillColor = wonderBlocksTokens.color.offBlack;
|
|
720
726
|
break;
|
|
721
727
|
}
|
|
722
|
-
const dynamicClass = active || focused ? styles$
|
|
728
|
+
const dynamicClass = active || focused ? styles$E.iconActive : styles$E.iconInactive;
|
|
723
729
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
724
|
-
style: [styles$
|
|
730
|
+
style: [styles$E.iconContainer, dynamicClass]
|
|
725
731
|
}, /*#__PURE__*/React__namespace.createElement("svg", {
|
|
726
732
|
xmlns: "http://www.w3.org/2000/svg",
|
|
727
733
|
width: "16",
|
|
@@ -766,7 +772,7 @@ const inputFocused = {
|
|
|
766
772
|
borderColor: wonderBlocksTokens.color.blue,
|
|
767
773
|
margin: -1
|
|
768
774
|
};
|
|
769
|
-
const styles$
|
|
775
|
+
const styles$E = aphrodite.StyleSheet.create({
|
|
770
776
|
iconContainer: {
|
|
771
777
|
display: "flex",
|
|
772
778
|
justifyContent: "center",
|
|
@@ -2601,7 +2607,7 @@ class Expression extends React__namespace.Component {
|
|
|
2601
2607
|
render() {
|
|
2602
2608
|
if (this.props.apiOptions.customKeypad) {
|
|
2603
2609
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
2604
|
-
className: aphrodite.css(styles$
|
|
2610
|
+
className: aphrodite.css(styles$D.mobileLabelInputWrapper)
|
|
2605
2611
|
}, !!this.props.visibleLabel && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
|
|
2606
2612
|
htmlFor: this._textareaId,
|
|
2607
2613
|
tag: "label"
|
|
@@ -2635,7 +2641,7 @@ class Expression extends React__namespace.Component {
|
|
|
2635
2641
|
ERROR_TITLE
|
|
2636
2642
|
} = this.context.strings;
|
|
2637
2643
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
2638
|
-
className: aphrodite.css(styles$
|
|
2644
|
+
className: aphrodite.css(styles$D.desktopLabelInputWrapper)
|
|
2639
2645
|
}, !!this.props.visibleLabel && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
|
|
2640
2646
|
htmlFor: this._textareaId,
|
|
2641
2647
|
tag: "label"
|
|
@@ -2676,7 +2682,7 @@ class Expression extends React__namespace.Component {
|
|
|
2676
2682
|
}))));
|
|
2677
2683
|
}
|
|
2678
2684
|
}
|
|
2679
|
-
const styles$
|
|
2685
|
+
const styles$D = aphrodite.StyleSheet.create({
|
|
2680
2686
|
mobileLabelInputWrapper: {
|
|
2681
2687
|
padding: "15px 4px 0"
|
|
2682
2688
|
},
|
|
@@ -18371,33 +18377,33 @@ class Lint extends React__namespace.Component {
|
|
|
18371
18377
|
let warningText;
|
|
18372
18378
|
let warningTextStyle;
|
|
18373
18379
|
if (this.props.severity === Severity.Error) {
|
|
18374
|
-
severityStyle = styles$
|
|
18380
|
+
severityStyle = styles$C.indicatorError;
|
|
18375
18381
|
warningText = "Error";
|
|
18376
|
-
warningTextStyle = styles$
|
|
18382
|
+
warningTextStyle = styles$C.publishBlockingError;
|
|
18377
18383
|
} else if (this.props.severity === Severity.Warning) {
|
|
18378
|
-
severityStyle = styles$
|
|
18384
|
+
severityStyle = styles$C.indicatorWarning;
|
|
18379
18385
|
warningText = "Warning";
|
|
18380
|
-
warningTextStyle = styles$
|
|
18386
|
+
warningTextStyle = styles$C.warning;
|
|
18381
18387
|
} else {
|
|
18382
|
-
severityStyle = styles$
|
|
18388
|
+
severityStyle = styles$C.indicatorGuideline;
|
|
18383
18389
|
warningText = "Recommendation";
|
|
18384
|
-
warningTextStyle = styles$
|
|
18390
|
+
warningTextStyle = styles$C.warning;
|
|
18385
18391
|
}
|
|
18386
18392
|
return /*#__PURE__*/React__namespace.createElement("a", {
|
|
18387
18393
|
href: `https://khanacademy.org/r/linter-rules#${this.props.ruleName}`,
|
|
18388
18394
|
target: "lint-help-window",
|
|
18389
18395
|
className: aphrodite.css(style)
|
|
18390
18396
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
18391
|
-
className: aphrodite.css(styles$
|
|
18397
|
+
className: aphrodite.css(styles$C.indicator, severityStyle)
|
|
18392
18398
|
}, this.props.severity === 1 && /*#__PURE__*/React__namespace.createElement(InlineIcon, exclamationIcon)), /*#__PURE__*/React__namespace.createElement("div", {
|
|
18393
|
-
className: aphrodite.css(styles$
|
|
18399
|
+
className: aphrodite.css(styles$C.tooltip, tooltipAbove && styles$C.tooltipAbove)
|
|
18394
18400
|
}, this.props.message.split("\n\n").map((m, i) => /*#__PURE__*/React__namespace.createElement("p", {
|
|
18395
18401
|
key: i,
|
|
18396
|
-
className: aphrodite.css(styles$
|
|
18402
|
+
className: aphrodite.css(styles$C.tooltipParagraph)
|
|
18397
18403
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
18398
18404
|
className: aphrodite.css(warningTextStyle)
|
|
18399
18405
|
}, warningText, ":", " "), m)), /*#__PURE__*/React__namespace.createElement("div", {
|
|
18400
|
-
className: aphrodite.css(styles$
|
|
18406
|
+
className: aphrodite.css(styles$C.tail, tooltipAbove && styles$C.tailAbove)
|
|
18401
18407
|
})));
|
|
18402
18408
|
};
|
|
18403
18409
|
|
|
@@ -18425,20 +18431,20 @@ class Lint extends React__namespace.Component {
|
|
|
18425
18431
|
}
|
|
18426
18432
|
if (blockHighlight) {
|
|
18427
18433
|
return /*#__PURE__*/React__namespace.createElement("span", {
|
|
18428
|
-
className: aphrodite.css(styles$
|
|
18429
|
-
}, this.renderLink(styles$
|
|
18434
|
+
className: aphrodite.css(styles$C.lintContainer, styles$C.lintContainerBlock)
|
|
18435
|
+
}, this.renderLink(styles$C.radioWidgetHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
|
|
18430
18436
|
}
|
|
18431
18437
|
if (inline) {
|
|
18432
18438
|
return /*#__PURE__*/React__namespace.createElement("span", {
|
|
18433
|
-
className: aphrodite.css(styles$
|
|
18434
|
-
}, this.renderLink(styles$
|
|
18439
|
+
className: aphrodite.css(styles$C.lintContainer)
|
|
18440
|
+
}, this.renderLink(styles$C.inlineHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
|
|
18435
18441
|
}
|
|
18436
18442
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
18437
|
-
className: aphrodite.css(styles$
|
|
18438
|
-
}, this.renderLink(styles$
|
|
18443
|
+
className: aphrodite.css(styles$C.lintContainer)
|
|
18444
|
+
}, this.renderLink(styles$C.hoverTarget), /*#__PURE__*/React__namespace.createElement("div", null, children));
|
|
18439
18445
|
}
|
|
18440
18446
|
}
|
|
18441
|
-
const styles$
|
|
18447
|
+
const styles$C = aphrodite.StyleSheet.create({
|
|
18442
18448
|
// This is the class of the outermost element.
|
|
18443
18449
|
// We use relative positioning so that the lint indicator can be
|
|
18444
18450
|
// positioned absolutely relative to the position of the linty container.
|
|
@@ -20572,7 +20578,7 @@ class Renderer extends React__namespace.Component {
|
|
|
20572
20578
|
};
|
|
20573
20579
|
const mobileInnerStyle = {
|
|
20574
20580
|
...innerStyle,
|
|
20575
|
-
...styles$
|
|
20581
|
+
...styles$B.mobileZoomableParentFix
|
|
20576
20582
|
};
|
|
20577
20583
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
20578
20584
|
key: state.key,
|
|
@@ -20712,7 +20718,7 @@ class Renderer extends React__namespace.Component {
|
|
|
20712
20718
|
};
|
|
20713
20719
|
const mobileInnerStyle = {
|
|
20714
20720
|
...innerStyle,
|
|
20715
|
-
...styles$
|
|
20721
|
+
...styles$B.mobileZoomableParentFix
|
|
20716
20722
|
};
|
|
20717
20723
|
const wrappedOutput = /*#__PURE__*/React__namespace.createElement("div", {
|
|
20718
20724
|
style: {
|
|
@@ -21220,7 +21226,7 @@ class Renderer extends React__namespace.Component {
|
|
|
21220
21226
|
return this.lastRenderedMarkdown;
|
|
21221
21227
|
}
|
|
21222
21228
|
}
|
|
21223
|
-
const styles$
|
|
21229
|
+
const styles$B = {
|
|
21224
21230
|
mobileZoomableParentFix: {
|
|
21225
21231
|
// NOTE(abdul): There is an issue where transform animations will
|
|
21226
21232
|
// cause the Zoomable component to disappear when running on the
|
|
@@ -22016,10 +22022,10 @@ class InputNumber extends React__namespace.Component {
|
|
|
22016
22022
|
// Note: This is _very_ similar to what `numeric-input.jsx` does. If
|
|
22017
22023
|
// you modify this, double-check if you also need to modify that
|
|
22018
22024
|
// component.
|
|
22019
|
-
const inputStyles = [styles$
|
|
22025
|
+
const inputStyles = [styles$A.default, this.props.size === "small" ? styles$A.small : null, this.props.rightAlign ? styles$A.rightAlign : styles$A.leftAlign];
|
|
22020
22026
|
// Unanswered
|
|
22021
22027
|
if (rubric && !this.props.currentValue) {
|
|
22022
|
-
inputStyles.push(styles$
|
|
22028
|
+
inputStyles.push(styles$A.answerStateUnanswered);
|
|
22023
22029
|
}
|
|
22024
22030
|
return /*#__PURE__*/React__namespace.createElement(InputWithExamples
|
|
22025
22031
|
// eslint-disable-next-line react/no-string-refs
|
|
@@ -22159,7 +22165,7 @@ class InputNumber extends React__namespace.Component {
|
|
|
22159
22165
|
return answerString;
|
|
22160
22166
|
}
|
|
22161
22167
|
}
|
|
22162
|
-
const styles$
|
|
22168
|
+
const styles$A = aphrodite.StyleSheet.create({
|
|
22163
22169
|
default: {
|
|
22164
22170
|
width: 80,
|
|
22165
22171
|
height: "auto"
|
|
@@ -23152,7 +23158,7 @@ const FocusRing = function (props) {
|
|
|
23152
23158
|
};
|
|
23153
23159
|
return /*#__PURE__*/React__namespace.createElement("span", {
|
|
23154
23160
|
"data-testid": "focus-ring",
|
|
23155
|
-
className: aphrodite.css(styles$
|
|
23161
|
+
className: aphrodite.css(styles$z.ring),
|
|
23156
23162
|
style: style
|
|
23157
23163
|
}, children);
|
|
23158
23164
|
};
|
|
@@ -23161,7 +23167,7 @@ FocusRing.defaultProps = {
|
|
|
23161
23167
|
color: kaGreen$1,
|
|
23162
23168
|
multipleSelect: false
|
|
23163
23169
|
};
|
|
23164
|
-
const styles$
|
|
23170
|
+
const styles$z = aphrodite.StyleSheet.create({
|
|
23165
23171
|
ring: {
|
|
23166
23172
|
margin: "auto",
|
|
23167
23173
|
display: "inline-block",
|
|
@@ -23188,7 +23194,7 @@ function getChoiceLetter(pos, strings) {
|
|
|
23188
23194
|
}
|
|
23189
23195
|
|
|
23190
23196
|
const CHOICE_ICON_SIZE = 24;
|
|
23191
|
-
const styles$
|
|
23197
|
+
const styles$y = aphrodite.StyleSheet.create({
|
|
23192
23198
|
iconWrapper: {
|
|
23193
23199
|
display: "inline-block",
|
|
23194
23200
|
position: "relative"
|
|
@@ -23211,7 +23217,7 @@ const CrossOutLine = function (props) {
|
|
|
23211
23217
|
width: CROSS_OUT_LINE_SIZE,
|
|
23212
23218
|
height: CROSS_OUT_LINE_SIZE,
|
|
23213
23219
|
viewBox: `0 0 ${CROSS_OUT_LINE_SIZE} ${CROSS_OUT_LINE_SIZE}`,
|
|
23214
|
-
className: aphrodite.css(styles$
|
|
23220
|
+
className: aphrodite.css(styles$x.crossOutLine),
|
|
23215
23221
|
"data-testid": "choice-icon__cross-out-line"
|
|
23216
23222
|
}, /*#__PURE__*/React__namespace.createElement("line", {
|
|
23217
23223
|
// The line stretches from the bottom-left to top-right.
|
|
@@ -23226,7 +23232,7 @@ const CrossOutLine = function (props) {
|
|
|
23226
23232
|
strokeLinecap: "round"
|
|
23227
23233
|
}));
|
|
23228
23234
|
};
|
|
23229
|
-
const styles$
|
|
23235
|
+
const styles$x = aphrodite.StyleSheet.create({
|
|
23230
23236
|
crossOutLine: {
|
|
23231
23237
|
// Center the icon within the container.
|
|
23232
23238
|
position: "absolute",
|
|
@@ -23310,7 +23316,7 @@ const ChoiceIcon = function (props) {
|
|
|
23310
23316
|
} = props;
|
|
23311
23317
|
const dynamicStyles = getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, correct);
|
|
23312
23318
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
23313
|
-
className: aphrodite.css(styles$
|
|
23319
|
+
className: aphrodite.css(styles$y.iconWrapper)
|
|
23314
23320
|
}, /*#__PURE__*/React__namespace.createElement(FocusRing, {
|
|
23315
23321
|
color: wonderBlocksTokens.color.blue,
|
|
23316
23322
|
visible: focused || hovered,
|
|
@@ -23319,13 +23325,13 @@ const ChoiceIcon = function (props) {
|
|
|
23319
23325
|
// @ts-expect-error - TS2322 - Type '{ backgroundColor: string | null | undefined; borderColor: string; color: string; borderRadius: number; }' is not assignable to type 'Properties<string | number, string & {}>'.
|
|
23320
23326
|
style: dynamicStyles,
|
|
23321
23327
|
"data-testid": "choice-icon__library-choice-icon",
|
|
23322
|
-
className: aphrodite.css(styles$
|
|
23328
|
+
className: aphrodite.css(styles$w.circle, showCorrectness && correct && styles$w.circleCorrect, showCorrectness && !correct && styles$w.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$w.circleIncorrectAnswered)
|
|
23323
23329
|
// used in BaseRadio editMode to check
|
|
23324
23330
|
// if we actually clicked on the radio icon
|
|
23325
23331
|
,
|
|
23326
23332
|
"data-is-radio-icon": true
|
|
23327
23333
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
23328
|
-
className: aphrodite.css(styles$
|
|
23334
|
+
className: aphrodite.css(styles$w.innerWrapper)
|
|
23329
23335
|
}, /*#__PURE__*/React__namespace.createElement(ChoiceInner, {
|
|
23330
23336
|
pos: pos,
|
|
23331
23337
|
showCorrectness: showCorrectness,
|
|
@@ -23334,7 +23340,7 @@ const ChoiceIcon = function (props) {
|
|
|
23334
23340
|
color: dynamicStyles.borderColor
|
|
23335
23341
|
}));
|
|
23336
23342
|
};
|
|
23337
|
-
const styles$
|
|
23343
|
+
const styles$w = aphrodite.StyleSheet.create({
|
|
23338
23344
|
innerWrapper: {
|
|
23339
23345
|
width: CHOICE_ICON_SIZE,
|
|
23340
23346
|
height: CHOICE_ICON_SIZE,
|
|
@@ -23429,19 +23435,19 @@ const OptionStatus = function (props) {
|
|
|
23429
23435
|
}
|
|
23430
23436
|
let textStyle;
|
|
23431
23437
|
if (correct) {
|
|
23432
|
-
textStyle = styles$
|
|
23438
|
+
textStyle = styles$v.correct;
|
|
23433
23439
|
} else {
|
|
23434
23440
|
if (checked || previouslyAnswered) {
|
|
23435
|
-
textStyle = styles$
|
|
23441
|
+
textStyle = styles$v.incorrectAnswered;
|
|
23436
23442
|
} else {
|
|
23437
|
-
textStyle = styles$
|
|
23443
|
+
textStyle = styles$v.incorrect;
|
|
23438
23444
|
}
|
|
23439
23445
|
}
|
|
23440
23446
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
23441
|
-
className: aphrodite.css(styles$
|
|
23447
|
+
className: aphrodite.css(styles$v.text, textStyle)
|
|
23442
23448
|
}, renderText(checked, correct, crossedOut, strings));
|
|
23443
23449
|
};
|
|
23444
|
-
const styles$
|
|
23450
|
+
const styles$v = aphrodite.StyleSheet.create({
|
|
23445
23451
|
text: {
|
|
23446
23452
|
alignItems: "center",
|
|
23447
23453
|
display: "flex",
|
|
@@ -23510,8 +23516,8 @@ const Choice = function (props) {
|
|
|
23510
23516
|
crossedOut: updatedCrossedOut
|
|
23511
23517
|
});
|
|
23512
23518
|
}
|
|
23513
|
-
const descriptionClassName = classNames__default["default"]("description", aphrodite.css(styles$
|
|
23514
|
-
const rationaleClassName = classNames__default["default"]("perseus-radio-rationale-content", aphrodite.css(styles$
|
|
23519
|
+
const descriptionClassName = classNames__default["default"]("description", aphrodite.css(styles$u.description));
|
|
23520
|
+
const rationaleClassName = classNames__default["default"]("perseus-radio-rationale-content", aphrodite.css(styles$u.rationale));
|
|
23515
23521
|
|
|
23516
23522
|
// We want to show the choices as dimmed out when the choices are disabled.
|
|
23517
23523
|
// However, we don't want to do this when we're in review mode in the
|
|
@@ -23678,7 +23684,7 @@ const Choice = function (props) {
|
|
|
23678
23684
|
"data-testid": `perseus-radio-rationale-content-${pos}`
|
|
23679
23685
|
}, rationale));
|
|
23680
23686
|
};
|
|
23681
|
-
const styles$
|
|
23687
|
+
const styles$u = aphrodite.StyleSheet.create({
|
|
23682
23688
|
description: {
|
|
23683
23689
|
display: "inline-block",
|
|
23684
23690
|
width: "100%"
|
|
@@ -23877,10 +23883,10 @@ const BaseRadio = function (props) {
|
|
|
23877
23883
|
const isMobile = apiOptions.isMobile;
|
|
23878
23884
|
const firstChoiceHighlighted = choices[0].highlighted;
|
|
23879
23885
|
const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
|
|
23880
|
-
const className = classNames__default["default"]("perseus-widget-radio", !editMode && "perseus-rendered-radio", aphrodite.css(styles$
|
|
23881
|
-
const instructionsClassName = classNames__default["default"]("instructions", aphrodite.css(styles$
|
|
23886
|
+
const className = classNames__default["default"]("perseus-widget-radio", !editMode && "perseus-rendered-radio", aphrodite.css(styles$t.radio, styles$t.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$t.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$t.radioContainerLastHighlighted));
|
|
23887
|
+
const instructionsClassName = classNames__default["default"]("instructions", aphrodite.css(styles$t.instructions, isMobile && styles$t.instructionsMobile));
|
|
23882
23888
|
const instructions = getInstructionsText(multipleSelect, countChoices, numCorrect, strings);
|
|
23883
|
-
const responsiveClassName = aphrodite.css(styles$
|
|
23889
|
+
const responsiveClassName = aphrodite.css(styles$t.responsiveFieldset);
|
|
23884
23890
|
const fieldset = /*#__PURE__*/React__namespace.createElement("fieldset", {
|
|
23885
23891
|
className: `perseus-widget-radio-fieldset ${responsiveClassName}`
|
|
23886
23892
|
}, /*#__PURE__*/React__namespace.createElement("legend", {
|
|
@@ -23931,7 +23937,7 @@ const BaseRadio = function (props) {
|
|
|
23931
23937
|
const aphroditeClassName = checked => {
|
|
23932
23938
|
// Whether or not to show correctness borders
|
|
23933
23939
|
// for this choice and the next choice.
|
|
23934
|
-
return aphrodite.css(sharedStyles.aboveScratchpad, styles$
|
|
23940
|
+
return aphrodite.css(sharedStyles.aboveScratchpad, styles$t.item, styles$t.responsiveItem, checked && styles$t.selectedItem, checked && choice.highlighted && styles$t.aboveBackdrop, checked && choice.highlighted && apiOptions.isMobile && styles$t.aboveBackdropMobile, nextChoiceHighlighted && apiOptions.isMobile && styles$t.nextHighlighted);
|
|
23935
23941
|
};
|
|
23936
23942
|
|
|
23937
23943
|
// HACK(abdulrahman): Preloads the selection-state
|
|
@@ -24005,14 +24011,14 @@ const BaseRadio = function (props) {
|
|
|
24005
24011
|
// Allow for horizontal scrolling if content is too wide, which may be
|
|
24006
24012
|
// an issue especially on phones.
|
|
24007
24013
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
24008
|
-
className: aphrodite.css(styles$
|
|
24014
|
+
className: aphrodite.css(styles$t.responsiveContainer)
|
|
24009
24015
|
}, fieldset);
|
|
24010
24016
|
};
|
|
24011
24017
|
BaseRadio.defaultProps = {
|
|
24012
24018
|
editMode: false,
|
|
24013
24019
|
multipleSelect: false
|
|
24014
24020
|
};
|
|
24015
|
-
const styles$
|
|
24021
|
+
const styles$t = aphrodite.StyleSheet.create({
|
|
24016
24022
|
instructions: {
|
|
24017
24023
|
display: "block",
|
|
24018
24024
|
color: gray17,
|
|
@@ -24696,9 +24702,9 @@ class Categorizer extends React__namespace.Component {
|
|
|
24696
24702
|
indexedItems = Util.shuffle(indexedItems, this.props.problemNum);
|
|
24697
24703
|
}
|
|
24698
24704
|
const table = /*#__PURE__*/React__namespace.createElement("table", {
|
|
24699
|
-
className: "categorizer-table " + aphrodite.css(styles$
|
|
24705
|
+
className: "categorizer-table " + aphrodite.css(styles$s.mobileTable)
|
|
24700
24706
|
}, /*#__PURE__*/React__namespace.createElement("thead", null, /*#__PURE__*/React__namespace.createElement("tr", null, /*#__PURE__*/React__namespace.createElement("td", {
|
|
24701
|
-
className: aphrodite.css(styles$
|
|
24707
|
+
className: aphrodite.css(styles$s.emptyHeaderCell)
|
|
24702
24708
|
}), this.props.categories.map((category, i) => {
|
|
24703
24709
|
// Array index is the correct key here, as that's
|
|
24704
24710
|
// how category grading actually works -- no way
|
|
@@ -24706,7 +24712,7 @@ class Categorizer extends React__namespace.Component {
|
|
|
24706
24712
|
// middle. (If we later add that, this should be
|
|
24707
24713
|
// fixed.)
|
|
24708
24714
|
return /*#__PURE__*/React__namespace.createElement("th", {
|
|
24709
|
-
className: aphrodite.css(styles$
|
|
24715
|
+
className: aphrodite.css(styles$s.header),
|
|
24710
24716
|
key: i
|
|
24711
24717
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
24712
24718
|
content: category,
|
|
@@ -24728,7 +24734,7 @@ class Categorizer extends React__namespace.Component {
|
|
|
24728
24734
|
})), self.props.categories.map((catName, catNum) => {
|
|
24729
24735
|
const selected = self.props.values[itemNum] === catNum;
|
|
24730
24736
|
return /*#__PURE__*/React__namespace.createElement("td", {
|
|
24731
|
-
className: "category " + aphrodite.css(styles$
|
|
24737
|
+
className: "category " + aphrodite.css(styles$s.cell),
|
|
24732
24738
|
key: catNum
|
|
24733
24739
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24734
24740
|
className: ClassNames.INTERACTIVE,
|
|
@@ -24743,7 +24749,7 @@ class Categorizer extends React__namespace.Component {
|
|
|
24743
24749
|
onChange: () => this.onChange(itemNum, catNum),
|
|
24744
24750
|
onClick: e => e.stopPropagation()
|
|
24745
24751
|
}), !isMobile && /*#__PURE__*/React__namespace.createElement("span", {
|
|
24746
|
-
className: aphrodite.css(styles$
|
|
24752
|
+
className: aphrodite.css(styles$s.radioSpan, selected && styles$s.checkedRadioSpan, this.props.static && selected && styles$s.staticCheckedRadioSpan)
|
|
24747
24753
|
}, selected ? /*#__PURE__*/React__namespace.createElement(InlineIcon, iconCircle) : /*#__PURE__*/React__namespace.createElement(InlineIcon, iconCircleThin))));
|
|
24748
24754
|
}));
|
|
24749
24755
|
/* eslint-enable max-len */
|
|
@@ -24755,7 +24761,7 @@ class Categorizer extends React__namespace.Component {
|
|
|
24755
24761
|
"categorizer-container": true,
|
|
24756
24762
|
"static-mode": this.props.static
|
|
24757
24763
|
});
|
|
24758
|
-
const inlineStyles = this.props.apiOptions.isMobile ? [styles$
|
|
24764
|
+
const inlineStyles = this.props.apiOptions.isMobile ? [styles$s.fullBleedContainer] : [];
|
|
24759
24765
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
24760
24766
|
className: extraClassNames + " " + aphrodite.css(...inlineStyles)
|
|
24761
24767
|
}, table);
|
|
@@ -24804,7 +24810,7 @@ const pageMargin = 16;
|
|
|
24804
24810
|
|
|
24805
24811
|
// Stylesheets aren't directly testable
|
|
24806
24812
|
/* c8 ignore next */
|
|
24807
|
-
const styles$
|
|
24813
|
+
const styles$s = aphrodite.StyleSheet.create({
|
|
24808
24814
|
mobileTable: {
|
|
24809
24815
|
[mediaQueries.smOrSmaller]: {
|
|
24810
24816
|
minWidth: "auto"
|
|
@@ -25067,7 +25073,7 @@ class CSProgram extends React__namespace.Component {
|
|
|
25067
25073
|
// creator "went wild".
|
|
25068
25074
|
// http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
|
|
25069
25075
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
25070
|
-
className: aphrodite.css(styles$
|
|
25076
|
+
className: aphrodite.css(styles$r.widthOverride, styleContainer && styles$r.container)
|
|
25071
25077
|
}, /*#__PURE__*/React__namespace.createElement("iframe", {
|
|
25072
25078
|
sandbox: sandboxOptions,
|
|
25073
25079
|
src: url,
|
|
@@ -25077,7 +25083,7 @@ class CSProgram extends React__namespace.Component {
|
|
|
25077
25083
|
}));
|
|
25078
25084
|
}
|
|
25079
25085
|
}
|
|
25080
|
-
const styles$
|
|
25086
|
+
const styles$r = aphrodite.StyleSheet.create({
|
|
25081
25087
|
// Override the inherited width from the perseus paragraph class
|
|
25082
25088
|
// 820 is minimum width for 420px editor and 400px canvas
|
|
25083
25089
|
widthOverride: {
|
|
@@ -25124,7 +25130,7 @@ class Definition extends React__namespace.Component {
|
|
|
25124
25130
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.Popover, {
|
|
25125
25131
|
content: /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.PopoverContentCore, {
|
|
25126
25132
|
color: "white",
|
|
25127
|
-
style: styles$
|
|
25133
|
+
style: styles$q.tooltipBody,
|
|
25128
25134
|
closeButtonVisible: true
|
|
25129
25135
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
25130
25136
|
apiOptions: this.props.apiOptions,
|
|
@@ -25156,7 +25162,7 @@ class Definition extends React__namespace.Component {
|
|
|
25156
25162
|
});
|
|
25157
25163
|
}
|
|
25158
25164
|
}
|
|
25159
|
-
const styles$
|
|
25165
|
+
const styles$q = {
|
|
25160
25166
|
tooltipBody: {
|
|
25161
25167
|
color: wonderBlocksTokens.color.offBlack,
|
|
25162
25168
|
fontSize: 20,
|
|
@@ -25383,7 +25389,7 @@ class Explanation extends React__namespace.Component {
|
|
|
25383
25389
|
marginRight: "-6px",
|
|
25384
25390
|
"white-space": "normal"
|
|
25385
25391
|
};
|
|
25386
|
-
const contentStyling = [styles$
|
|
25392
|
+
const contentStyling = [styles$p.content, this.state.expanded ? styles$p.contentExpanded : styles$p.contentCollapsed, allowTransition && (this.state.expanded ? styles$p.transitionExpanded : styles$p.transitionCollapsed)];
|
|
25387
25393
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.UniqueIDProvider, {
|
|
25388
25394
|
mockOnFirstRender: true,
|
|
25389
25395
|
scope: "explanation-widget"
|
|
@@ -25402,7 +25408,7 @@ class Explanation extends React__namespace.Component {
|
|
|
25402
25408
|
"aria-hidden": !this.state.expanded,
|
|
25403
25409
|
testId: "content-container"
|
|
25404
25410
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
25405
|
-
style: styles$
|
|
25411
|
+
style: styles$p.contentWrapper
|
|
25406
25412
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
25407
25413
|
apiOptions: this.props.apiOptions,
|
|
25408
25414
|
content: this.props.explanation,
|
|
@@ -25421,7 +25427,7 @@ class Explanation extends React__namespace.Component {
|
|
|
25421
25427
|
const leftBorderSpacing = 23;
|
|
25422
25428
|
const verticalContentPadding = 10;
|
|
25423
25429
|
const arrowHeight = 14;
|
|
25424
|
-
const styles$
|
|
25430
|
+
const styles$p = aphrodite.StyleSheet.create({
|
|
25425
25431
|
content: {
|
|
25426
25432
|
borderLeft: "0px solid #ccc",
|
|
25427
25433
|
display: "inline-grid",
|
|
@@ -25487,15 +25493,15 @@ class GradedGroupAnswerBar extends React__namespace.Component {
|
|
|
25487
25493
|
nextQuestion
|
|
25488
25494
|
} = this.context.strings;
|
|
25489
25495
|
const answerBarStyle = {
|
|
25490
|
-
...styles$
|
|
25496
|
+
...styles$o.answerBar,
|
|
25491
25497
|
backgroundColor: answerBarState === "CORRECT" ? wonderBlocksTokens.color.offWhite : "white",
|
|
25492
25498
|
// Center the "Correct!" message only when there's no next question
|
|
25493
25499
|
justifyContent: answerBarState === "CORRECT" && !onNextQuestion ? "center" : "space-between"
|
|
25494
25500
|
};
|
|
25495
25501
|
const message = answerBarState === "INCORRECT" ? /*#__PURE__*/React__namespace.createElement("span", {
|
|
25496
|
-
style: styles$
|
|
25502
|
+
style: styles$o.text
|
|
25497
25503
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
25498
|
-
style: styles$
|
|
25504
|
+
style: styles$o.tryAgainIcon
|
|
25499
25505
|
}, /*#__PURE__*/React__namespace.createElement(InlineIcon, iconTryAgain)), /*#__PURE__*/React__namespace.createElement("span", {
|
|
25500
25506
|
style: {
|
|
25501
25507
|
marginLeft: 8
|
|
@@ -25514,7 +25520,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
|
|
|
25514
25520
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
25515
25521
|
style: answerBarStyle
|
|
25516
25522
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
25517
|
-
style: styles$
|
|
25523
|
+
style: styles$o.text
|
|
25518
25524
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
25519
25525
|
style: {
|
|
25520
25526
|
fontSize: 28,
|
|
@@ -25536,7 +25542,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
|
|
|
25536
25542
|
}
|
|
25537
25543
|
}
|
|
25538
25544
|
const fontSize = 17;
|
|
25539
|
-
const styles$
|
|
25545
|
+
const styles$o = {
|
|
25540
25546
|
answerBar: {
|
|
25541
25547
|
display: "flex",
|
|
25542
25548
|
alignItems: "center",
|
|
@@ -25736,7 +25742,7 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25736
25742
|
}));
|
|
25737
25743
|
gradeStatus = this.context.strings.incorrect;
|
|
25738
25744
|
}
|
|
25739
|
-
const mobileClass = this.props.inGradedGroupSet ? aphrodite.css(styles$
|
|
25745
|
+
const mobileClass = this.props.inGradedGroupSet ? aphrodite.css(styles$n.gradedGroupInSet) : aphrodite.css(styles$n.gradedGroup);
|
|
25740
25746
|
const classes = classNames__default["default"]({
|
|
25741
25747
|
[mobileClass]: apiOptions.isMobile,
|
|
25742
25748
|
"perseus-graded-group": true,
|
|
@@ -25755,7 +25761,7 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25755
25761
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
25756
25762
|
className: classes
|
|
25757
25763
|
}, !!this.props.title && /*#__PURE__*/React__namespace.createElement("div", {
|
|
25758
|
-
className: aphrodite.css(styles$
|
|
25764
|
+
className: aphrodite.css(styles$n.title)
|
|
25759
25765
|
}, this.props.title), /*#__PURE__*/React__namespace.createElement(Renderer, _extends({}, this.props, {
|
|
25760
25766
|
// eslint-disable-next-line react/no-string-refs
|
|
25761
25767
|
ref: "renderer",
|
|
@@ -25789,7 +25795,7 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25789
25795
|
}, this.context.strings.nextQuestion), this.props.hint && this.props.hint.content && (this.state.showHint ? /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("button", {
|
|
25790
25796
|
// @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
|
|
25791
25797
|
tabIndex: "0",
|
|
25792
|
-
className: aphrodite.css(styles$
|
|
25798
|
+
className: aphrodite.css(styles$n.explanationTitle),
|
|
25793
25799
|
onClick: () => this.setState({
|
|
25794
25800
|
showHint: false
|
|
25795
25801
|
}),
|
|
@@ -25822,7 +25828,7 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25822
25828
|
showHint: true
|
|
25823
25829
|
});
|
|
25824
25830
|
},
|
|
25825
|
-
className: aphrodite.css(styles$
|
|
25831
|
+
className: aphrodite.css(styles$n.showHintLink)
|
|
25826
25832
|
}, this.context.strings.explain)), apiOptions.isMobile && answerBarState !== "HIDDEN" && /*#__PURE__*/React__namespace.createElement(GradedGroupAnswerBar, {
|
|
25827
25833
|
apiOptions: apiOptions,
|
|
25828
25834
|
answerBarState: answerBarState,
|
|
@@ -25834,7 +25840,7 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25834
25840
|
const traverseChildWidgets$2 = function (props, traverseRenderer) {
|
|
25835
25841
|
return ___default["default"].extend({}, props, traverseRenderer(props));
|
|
25836
25842
|
};
|
|
25837
|
-
const styles$
|
|
25843
|
+
const styles$n = aphrodite.StyleSheet.create({
|
|
25838
25844
|
gradedGroupInSet: {
|
|
25839
25845
|
// Reset a few desktop-only styles that come from graded-group.less
|
|
25840
25846
|
marginLeft: 0,
|
|
@@ -25905,20 +25911,20 @@ class Indicators extends React__namespace.Component {
|
|
|
25905
25911
|
return /*#__PURE__*/React__namespace.createElement("ul", {
|
|
25906
25912
|
// reduntantly add class name for use in .less files--
|
|
25907
25913
|
// the styles object key gets hashed
|
|
25908
|
-
className: classNames__default["default"](aphrodite.css(styles$
|
|
25914
|
+
className: classNames__default["default"](aphrodite.css(styles$m.indicatorContainer), "indicatorContainer")
|
|
25909
25915
|
}, this.props.gradedGroups.map((_ref, i) => {
|
|
25910
25916
|
let {
|
|
25911
25917
|
title
|
|
25912
25918
|
} = _ref;
|
|
25913
25919
|
return /*#__PURE__*/React__namespace.createElement("li", {
|
|
25914
|
-
className: aphrodite.css(styles$
|
|
25920
|
+
className: aphrodite.css(styles$m.indicator),
|
|
25915
25921
|
key: title
|
|
25916
25922
|
}, /*#__PURE__*/React__namespace.createElement(Clickable__default["default"], {
|
|
25917
25923
|
role: "button",
|
|
25918
25924
|
"aria-label": this.context.strings.skipToTitle({
|
|
25919
25925
|
title
|
|
25920
25926
|
}),
|
|
25921
|
-
style: styles$
|
|
25927
|
+
style: styles$m.indicatorButton,
|
|
25922
25928
|
onClick: () => this.props.onChangeCurrentGroup(i),
|
|
25923
25929
|
onKeyDown: e => this.handleKeyDown(e, i)
|
|
25924
25930
|
}, _ref2 => {
|
|
@@ -25928,9 +25934,9 @@ class Indicators extends React__namespace.Component {
|
|
|
25928
25934
|
pressed
|
|
25929
25935
|
} = _ref2;
|
|
25930
25936
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
25931
|
-
style: [styles$
|
|
25937
|
+
style: [styles$m.indicatorDot, (hovered || focused || pressed) && styles$m.indicatorDotFocused]
|
|
25932
25938
|
}, i === this.props.currentGroup && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
25933
|
-
style: styles$
|
|
25939
|
+
style: styles$m.indicatorDotActive
|
|
25934
25940
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
25935
25941
|
className: aphrodite.css(a11y.srOnly)
|
|
25936
25942
|
}, this.context.strings.current)));
|
|
@@ -26006,7 +26012,7 @@ class GradedGroupSet extends React__namespace.Component {
|
|
|
26006
26012
|
} = getDependencies();
|
|
26007
26013
|
if (JIPT.useJIPT && this.props.gradedGroups.length > 1) {
|
|
26008
26014
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
26009
|
-
className: aphrodite.css(styles$
|
|
26015
|
+
className: aphrodite.css(styles$m.container)
|
|
26010
26016
|
}, this.props.gradedGroups.map((gradedGroup, i) => {
|
|
26011
26017
|
return (
|
|
26012
26018
|
/*#__PURE__*/
|
|
@@ -26029,13 +26035,13 @@ class GradedGroupSet extends React__namespace.Component {
|
|
|
26029
26035
|
const numGroups = this.props.gradedGroups.length;
|
|
26030
26036
|
const handleNextQuestion = this.state.currentGroup < numGroups - 1 ? this.handleNextQuestion : null;
|
|
26031
26037
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
26032
|
-
className: aphrodite.css(styles$
|
|
26038
|
+
className: aphrodite.css(styles$m.container)
|
|
26033
26039
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
26034
|
-
className: aphrodite.css(styles$
|
|
26040
|
+
className: aphrodite.css(styles$m.top)
|
|
26035
26041
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
26036
|
-
className: aphrodite.css(styles$
|
|
26042
|
+
className: aphrodite.css(styles$m.title)
|
|
26037
26043
|
}, currentGroup.title), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26038
|
-
className: aphrodite.css(styles$
|
|
26044
|
+
className: aphrodite.css(styles$m.spacer)
|
|
26039
26045
|
}), /*#__PURE__*/React__namespace.createElement(Indicators, {
|
|
26040
26046
|
currentGroup: this.state.currentGroup,
|
|
26041
26047
|
gradedGroups: this.props.gradedGroups,
|
|
@@ -26073,7 +26079,7 @@ var GradedGroupSet$1 = {
|
|
|
26073
26079
|
tracking: "all",
|
|
26074
26080
|
isLintable: true
|
|
26075
26081
|
};
|
|
26076
|
-
const styles$
|
|
26082
|
+
const styles$m = aphrodite.StyleSheet.create({
|
|
26077
26083
|
top: {
|
|
26078
26084
|
display: "flex",
|
|
26079
26085
|
flexDirection: "row"
|
|
@@ -26179,7 +26185,7 @@ class ButtonGroup extends React__namespace.Component {
|
|
|
26179
26185
|
id: "" + i,
|
|
26180
26186
|
ref: "button" + i,
|
|
26181
26187
|
key: "" + i,
|
|
26182
|
-
className: aphrodite.css(styles$
|
|
26188
|
+
className: aphrodite.css(styles$l.buttonStyle, button.value === value && styles$l.selectedStyle),
|
|
26183
26189
|
onClick: () => this.toggleSelect(button.value)
|
|
26184
26190
|
}, button.content || "" + button.value);
|
|
26185
26191
|
});
|
|
@@ -26192,7 +26198,7 @@ class ButtonGroup extends React__namespace.Component {
|
|
|
26192
26198
|
}, buttons);
|
|
26193
26199
|
}
|
|
26194
26200
|
}
|
|
26195
|
-
const styles$
|
|
26201
|
+
const styles$l = aphrodite.StyleSheet.create({
|
|
26196
26202
|
buttonStyle: {
|
|
26197
26203
|
backgroundColor: "white",
|
|
26198
26204
|
border: "1px solid #ccc",
|
|
@@ -28625,72 +28631,6 @@ class Graph extends React__namespace.Component {
|
|
|
28625
28631
|
}
|
|
28626
28632
|
}
|
|
28627
28633
|
|
|
28628
|
-
const defaultGraphConfig = {
|
|
28629
|
-
range: [[0, 1], [0, 1]],
|
|
28630
|
-
tickStep: [1, 1],
|
|
28631
|
-
gridStep: [1, 1],
|
|
28632
|
-
snapStep: [1, 1],
|
|
28633
|
-
markings: "none",
|
|
28634
|
-
showTooltips: false,
|
|
28635
|
-
graphDimensionsInPixels: [1, 1],
|
|
28636
|
-
width: 0,
|
|
28637
|
-
height: 0,
|
|
28638
|
-
labels: [],
|
|
28639
|
-
disableKeyboardInteraction: false
|
|
28640
|
-
};
|
|
28641
|
-
const GraphConfigContext = /*#__PURE__*/React.createContext(defaultGraphConfig);
|
|
28642
|
-
function useGraphConfig() {
|
|
28643
|
-
return React__default["default"].useContext(GraphConfigContext);
|
|
28644
|
-
}
|
|
28645
|
-
|
|
28646
|
-
const matrixBuilder = mafs.vec.matrixBuilder;
|
|
28647
|
-
|
|
28648
|
-
// When converting vectors, we don't need to translate because a vector
|
|
28649
|
-
// is like a pair of x and y distances, which are not bound to specific graph locations.
|
|
28650
|
-
function vectorsToPixels(vectors, graphState) {
|
|
28651
|
-
let translation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [0, 0];
|
|
28652
|
-
const {
|
|
28653
|
-
range,
|
|
28654
|
-
width,
|
|
28655
|
-
height
|
|
28656
|
-
} = graphState;
|
|
28657
|
-
const [[xMin, xMax], [yMin, yMax]] = range;
|
|
28658
|
-
const transformToPx = matrixBuilder().translate(...translation).scale(width / (xMax - xMin), -height / (yMax - yMin)).get();
|
|
28659
|
-
return vectors.map(p => mafs.vec.transform(p, transformToPx));
|
|
28660
|
-
}
|
|
28661
|
-
function dimensionsToPixels(dimens, graphState) {
|
|
28662
|
-
const {
|
|
28663
|
-
range,
|
|
28664
|
-
width,
|
|
28665
|
-
height
|
|
28666
|
-
} = graphState;
|
|
28667
|
-
const [[xMin, xMax], [yMin, yMax]] = range;
|
|
28668
|
-
const transformToPx = matrixBuilder().scale(width / (xMax - xMin), height / (yMax - yMin)).get();
|
|
28669
|
-
return dimens.map(d => mafs.vec.transform(d, transformToPx));
|
|
28670
|
-
}
|
|
28671
|
-
|
|
28672
|
-
// When converting points, we translate so the pixel point ends up in the right location.
|
|
28673
|
-
// This is because points are specific locations on graphs, unlike vectors.
|
|
28674
|
-
function pointToPixel(point, graphState) {
|
|
28675
|
-
const [[xMin], [, yMax]] = graphState.range;
|
|
28676
|
-
const [a, b] = [-xMin, -yMax];
|
|
28677
|
-
return vectorsToPixels([point], graphState, [a, b])[0];
|
|
28678
|
-
}
|
|
28679
|
-
const useTransformVectorsToPixels = function () {
|
|
28680
|
-
const graphState = useGraphConfig();
|
|
28681
|
-
for (var _len = arguments.length, vectors = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
28682
|
-
vectors[_key] = arguments[_key];
|
|
28683
|
-
}
|
|
28684
|
-
return vectorsToPixels(vectors, graphState);
|
|
28685
|
-
};
|
|
28686
|
-
const useTransformDimensionsToPixels = function () {
|
|
28687
|
-
const graphState = useGraphConfig();
|
|
28688
|
-
for (var _len2 = arguments.length, dimens = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
28689
|
-
dimens[_key2] = arguments[_key2];
|
|
28690
|
-
}
|
|
28691
|
-
return dimensionsToPixels(dimens, graphState);
|
|
28692
|
-
};
|
|
28693
|
-
|
|
28694
28634
|
// Restricts `value` to be between `min` and `max`.
|
|
28695
28635
|
function clamp(value, min, max) {
|
|
28696
28636
|
if (value < min) {
|
|
@@ -28840,6 +28780,86 @@ const findAngle = (point1, point2, vertex) => {
|
|
|
28840
28780
|
return findAngle(point1, vertex) - findAngle(point2, vertex);
|
|
28841
28781
|
};
|
|
28842
28782
|
|
|
28783
|
+
const defaultGraphConfig = {
|
|
28784
|
+
range: [[0, 1], [0, 1]],
|
|
28785
|
+
tickStep: [1, 1],
|
|
28786
|
+
gridStep: [1, 1],
|
|
28787
|
+
snapStep: [1, 1],
|
|
28788
|
+
markings: "none",
|
|
28789
|
+
showTooltips: false,
|
|
28790
|
+
graphDimensionsInPixels: [1, 1],
|
|
28791
|
+
width: 0,
|
|
28792
|
+
height: 0,
|
|
28793
|
+
labels: [],
|
|
28794
|
+
disableKeyboardInteraction: false
|
|
28795
|
+
};
|
|
28796
|
+
const GraphConfigContext = /*#__PURE__*/React.createContext(defaultGraphConfig);
|
|
28797
|
+
function useGraphConfig() {
|
|
28798
|
+
return React__default["default"].useContext(GraphConfigContext);
|
|
28799
|
+
}
|
|
28800
|
+
|
|
28801
|
+
const matrixBuilder = mafs.vec.matrixBuilder;
|
|
28802
|
+
|
|
28803
|
+
// When converting vectors, we don't need to translate because a vector
|
|
28804
|
+
// is like a pair of x and y distances, which are not bound to specific graph locations.
|
|
28805
|
+
function vectorsToPixels(vectors, graphState) {
|
|
28806
|
+
let translation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [0, 0];
|
|
28807
|
+
const {
|
|
28808
|
+
range,
|
|
28809
|
+
width,
|
|
28810
|
+
height
|
|
28811
|
+
} = graphState;
|
|
28812
|
+
const [[xMin, xMax], [yMin, yMax]] = range;
|
|
28813
|
+
const transformToPx = matrixBuilder().translate(...translation).scale(width / (xMax - xMin), -height / (yMax - yMin)).get();
|
|
28814
|
+
return vectors.map(p => mafs.vec.transform(p, transformToPx));
|
|
28815
|
+
}
|
|
28816
|
+
function dimensionsToPixels(dimens, graphState) {
|
|
28817
|
+
const {
|
|
28818
|
+
range,
|
|
28819
|
+
width,
|
|
28820
|
+
height
|
|
28821
|
+
} = graphState;
|
|
28822
|
+
const [[xMin, xMax], [yMin, yMax]] = range;
|
|
28823
|
+
const transformToPx = matrixBuilder().scale(width / (xMax - xMin), height / (yMax - yMin)).get();
|
|
28824
|
+
return dimens.map(d => mafs.vec.transform(d, transformToPx));
|
|
28825
|
+
}
|
|
28826
|
+
|
|
28827
|
+
// When converting points, we translate so the pixel point ends up in the right location.
|
|
28828
|
+
// This is because points are specific locations on graphs, unlike vectors.
|
|
28829
|
+
function pointToPixel(point, graphState) {
|
|
28830
|
+
const [[xMin], [, yMax]] = graphState.range;
|
|
28831
|
+
const [a, b] = [-xMin, -yMax];
|
|
28832
|
+
return vectorsToPixels([point], graphState, [a, b])[0];
|
|
28833
|
+
}
|
|
28834
|
+
const useTransformVectorsToPixels = function () {
|
|
28835
|
+
const graphState = useGraphConfig();
|
|
28836
|
+
for (var _len = arguments.length, vectors = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
28837
|
+
vectors[_key] = arguments[_key];
|
|
28838
|
+
}
|
|
28839
|
+
return vectorsToPixels(vectors, graphState);
|
|
28840
|
+
};
|
|
28841
|
+
const useTransformDimensionsToPixels = function () {
|
|
28842
|
+
const graphState = useGraphConfig();
|
|
28843
|
+
for (var _len2 = arguments.length, dimens = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
28844
|
+
dimens[_key2] = arguments[_key2];
|
|
28845
|
+
}
|
|
28846
|
+
return dimensionsToPixels(dimens, graphState);
|
|
28847
|
+
};
|
|
28848
|
+
function pixelsToVectors(pixels, graphState) {
|
|
28849
|
+
const [[xMin, xMax], [yMin, yMax]] = graphState.range;
|
|
28850
|
+
const {
|
|
28851
|
+
width,
|
|
28852
|
+
height
|
|
28853
|
+
} = graphState;
|
|
28854
|
+
const xSpan = xMax - xMin;
|
|
28855
|
+
const ySpan = yMax - yMin;
|
|
28856
|
+
return pixels.map(pixel => {
|
|
28857
|
+
const x = pixel[X] / width * xSpan + xMin;
|
|
28858
|
+
const y = yMax - pixel[Y] / height * ySpan;
|
|
28859
|
+
return [x, y];
|
|
28860
|
+
});
|
|
28861
|
+
}
|
|
28862
|
+
|
|
28843
28863
|
function AxisLabels() {
|
|
28844
28864
|
const {
|
|
28845
28865
|
range,
|
|
@@ -29430,7 +29450,7 @@ const VisibleIcon = () => /*#__PURE__*/React__namespace.createElement("svg", {
|
|
|
29430
29450
|
width: "24",
|
|
29431
29451
|
height: "24",
|
|
29432
29452
|
viewBox: "0 0 24 24",
|
|
29433
|
-
className: aphrodite.css(styles$
|
|
29453
|
+
className: aphrodite.css(styles$k.icon)
|
|
29434
29454
|
}, /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("path", {
|
|
29435
29455
|
id: "a",
|
|
29436
29456
|
d: "M7.401 10.035c-1.424.748-2.599 1.905-3.544 " + "3.48a1 1 0 0 1-1.714-1.03C4.325 8.849 7.652 7 " + "12 7c4.348 0 7.675 1.848 9.857 5.486a1 1 0 0 " + "1-1.714 1.028c-.945-1.574-2.12-2.73-3.544-" + "3.48a5 5 0 1 1-9.198 0zM12 15a3 3 0 1 0 0-6 3 3 " + "0 0 0 0 6z"
|
|
@@ -29461,7 +29481,7 @@ const HiddenIcon = () => /*#__PURE__*/React__namespace.createElement("svg", {
|
|
|
29461
29481
|
width: "24",
|
|
29462
29482
|
height: "24",
|
|
29463
29483
|
viewBox: "0 0 24 24",
|
|
29464
|
-
className: aphrodite.css(styles$
|
|
29484
|
+
className: aphrodite.css(styles$k.icon)
|
|
29465
29485
|
}, /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("path", {
|
|
29466
29486
|
id: "a",
|
|
29467
29487
|
d: "M8.794 7.38C9.791 7.127 10.86 7 12 7c4.348 0 " + "7.675 1.848 9.857 5.486a1 1 0 0 1-1.714 " + "1.028c-.945-1.574-2.12-2.73-3.544-3.48.258." + "604.401 1.268.401 1.966 0 1.02-.305 " + "1.967-.828 2.757l2.535 2.536a1 1 0 0 " + "1-1.414 1.414l-12-12a1 1 0 0 1 " + "1.414-1.414L8.794 7.38zm5.914 5.913a3 3 0 0 " + "0-4.001-4.001l4 4.001zM6.072 8.486l2.976 " + "2.976a3 3 0 0 0 3.49 3.49l1.579 1.58A5 5 0 " + "0 1 7.4 10.035c-1.424.747-2.599 1.904-3.544 " + "3.478a1 1 0 0 1-1.714-1.028c1.049-1.75 " + "2.363-3.085 3.929-4z"
|
|
@@ -29496,20 +29516,20 @@ const HUD = _ref => {
|
|
|
29496
29516
|
let state;
|
|
29497
29517
|
let icon;
|
|
29498
29518
|
if (enabled) {
|
|
29499
|
-
state = styles$
|
|
29519
|
+
state = styles$k.enabled;
|
|
29500
29520
|
icon = /*#__PURE__*/React__namespace.createElement(VisibleIcon, null);
|
|
29501
29521
|
} else {
|
|
29502
|
-
state = styles$
|
|
29522
|
+
state = styles$k.disabled;
|
|
29503
29523
|
icon = /*#__PURE__*/React__namespace.createElement(HiddenIcon, null);
|
|
29504
29524
|
}
|
|
29505
29525
|
return /*#__PURE__*/React__namespace.createElement("button", {
|
|
29506
|
-
className: aphrodite.css(styles$
|
|
29526
|
+
className: aphrodite.css(styles$k.hud, fixedPosition && styles$k.hudFixedPosition, state),
|
|
29507
29527
|
onClick: e => {
|
|
29508
29528
|
onClick();
|
|
29509
29529
|
}
|
|
29510
29530
|
}, icon, message);
|
|
29511
29531
|
};
|
|
29512
|
-
const styles$
|
|
29532
|
+
const styles$k = aphrodite.StyleSheet.create({
|
|
29513
29533
|
hud: {
|
|
29514
29534
|
boxSizing: "border-box",
|
|
29515
29535
|
height: 36,
|
|
@@ -29562,16 +29582,16 @@ const styles$j = aphrodite.StyleSheet.create({
|
|
|
29562
29582
|
const InfoTipBase = props => {
|
|
29563
29583
|
return /*#__PURE__*/React__namespace.createElement(Tooltip__default["default"], {
|
|
29564
29584
|
content: /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.Body, {
|
|
29565
|
-
style: styles$
|
|
29585
|
+
style: styles$j.body
|
|
29566
29586
|
}, props.children),
|
|
29567
29587
|
placement: "right"
|
|
29568
29588
|
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
|
|
29569
29589
|
size: "small",
|
|
29570
29590
|
icon: questionIcon__default["default"],
|
|
29571
|
-
style: styles$
|
|
29591
|
+
style: styles$j.spacingLeft
|
|
29572
29592
|
}));
|
|
29573
29593
|
};
|
|
29574
|
-
const styles$
|
|
29594
|
+
const styles$j = aphrodite.StyleSheet.create({
|
|
29575
29595
|
spacingLeft: {
|
|
29576
29596
|
marginInlineStart: wonderBlocksTokens.spacing.xxxSmall_4
|
|
29577
29597
|
},
|
|
@@ -29647,7 +29667,7 @@ class MultiButtonGroup extends React__namespace.Component {
|
|
|
29647
29667
|
id: "" + i,
|
|
29648
29668
|
key: "" + i,
|
|
29649
29669
|
ref: "button" + i,
|
|
29650
|
-
className: aphrodite.css(styles$
|
|
29670
|
+
className: aphrodite.css(styles$i.buttonStyle, selected && styles$i.selectedStyle),
|
|
29651
29671
|
onClick: () => this.toggleSelect(button.value)
|
|
29652
29672
|
}, button.content || "" + button.value);
|
|
29653
29673
|
});
|
|
@@ -29659,7 +29679,7 @@ class MultiButtonGroup extends React__namespace.Component {
|
|
|
29659
29679
|
}, buttons);
|
|
29660
29680
|
}
|
|
29661
29681
|
}
|
|
29662
|
-
const styles$
|
|
29682
|
+
const styles$i = aphrodite.StyleSheet.create({
|
|
29663
29683
|
buttonStyle: {
|
|
29664
29684
|
backgroundColor: "white",
|
|
29665
29685
|
border: "1px solid #ccc",
|
|
@@ -30102,6 +30122,8 @@ const ItemExtras = [
|
|
|
30102
30122
|
|
|
30103
30123
|
// prettier-ignore
|
|
30104
30124
|
|
|
30125
|
+
// prettier-ignore
|
|
30126
|
+
|
|
30105
30127
|
//prettier-ignore
|
|
30106
30128
|
|
|
30107
30129
|
// A background image applied to various widgets.
|
|
@@ -30122,8 +30144,53 @@ const lockedFigureFillStyles = {
|
|
|
30122
30144
|
translucent: 0.4,
|
|
30123
30145
|
solid: 1
|
|
30124
30146
|
};
|
|
30147
|
+
|
|
30148
|
+
// Not associated with a specific figure
|
|
30149
|
+
|
|
30125
30150
|
const plotterPlotTypes = ["bar", "line", "pic", "histogram", "dotplot"];
|
|
30126
30151
|
|
|
30152
|
+
function LockedLabel(props) {
|
|
30153
|
+
const {
|
|
30154
|
+
coord,
|
|
30155
|
+
text,
|
|
30156
|
+
color,
|
|
30157
|
+
size
|
|
30158
|
+
} = props;
|
|
30159
|
+
const [x, y] = pointToPixel(coord, useGraphConfig());
|
|
30160
|
+
const {
|
|
30161
|
+
TeX
|
|
30162
|
+
} = getDependencies();
|
|
30163
|
+
|
|
30164
|
+
// Move this all outside the SVG element
|
|
30165
|
+
return /*#__PURE__*/React__namespace.createElement("span", {
|
|
30166
|
+
className: "locked-label",
|
|
30167
|
+
style: {
|
|
30168
|
+
position: "absolute",
|
|
30169
|
+
left: x,
|
|
30170
|
+
top: y,
|
|
30171
|
+
color: lockedFigureColors[color],
|
|
30172
|
+
fontSize: wonderBlocksTokens.font.size[size]
|
|
30173
|
+
}
|
|
30174
|
+
}, /*#__PURE__*/React__namespace.createElement(TeX, null, text));
|
|
30175
|
+
}
|
|
30176
|
+
|
|
30177
|
+
function GraphLockedLabelsLayer(props) {
|
|
30178
|
+
const {
|
|
30179
|
+
lockedFigures
|
|
30180
|
+
} = props;
|
|
30181
|
+
return lockedFigures.map((figure, i) => {
|
|
30182
|
+
if (figure.type === "label") {
|
|
30183
|
+
return /*#__PURE__*/React__namespace.createElement(LockedLabel, _extends({
|
|
30184
|
+
key: `label-${i}`
|
|
30185
|
+
}, figure));
|
|
30186
|
+
}
|
|
30187
|
+
|
|
30188
|
+
// TODO(LEMS-2271): Add support for labels within
|
|
30189
|
+
// other locked figure types
|
|
30190
|
+
return null;
|
|
30191
|
+
});
|
|
30192
|
+
}
|
|
30193
|
+
|
|
30127
30194
|
const LockedEllipse = props => {
|
|
30128
30195
|
const {
|
|
30129
30196
|
center,
|
|
@@ -30438,6 +30505,12 @@ const GraphLockedLayer = props => {
|
|
|
30438
30505
|
return /*#__PURE__*/React__namespace.createElement(LockedFunction, _extends({
|
|
30439
30506
|
key: `function-${index}`
|
|
30440
30507
|
}, figure));
|
|
30508
|
+
case "label":
|
|
30509
|
+
// This is rendered outside the SVG element, since
|
|
30510
|
+
// TeX cannot be rendered inside an SVG.
|
|
30511
|
+
// See graph-locked-labels-layer.tsx for
|
|
30512
|
+
// the component that renders these.
|
|
30513
|
+
return null;
|
|
30441
30514
|
default:
|
|
30442
30515
|
/**
|
|
30443
30516
|
* Devlopment-time future-proofing: This should
|
|
@@ -30467,7 +30540,8 @@ const actions = {
|
|
|
30467
30540
|
movePointInFigure
|
|
30468
30541
|
},
|
|
30469
30542
|
pointGraph: {
|
|
30470
|
-
movePoint
|
|
30543
|
+
movePoint,
|
|
30544
|
+
addPoint
|
|
30471
30545
|
},
|
|
30472
30546
|
polygon: {
|
|
30473
30547
|
movePoint,
|
|
@@ -30496,6 +30570,13 @@ function moveLine(itemIndex, delta) {
|
|
|
30496
30570
|
delta
|
|
30497
30571
|
};
|
|
30498
30572
|
}
|
|
30573
|
+
const ADD_POINT = "add-point";
|
|
30574
|
+
function addPoint(location) {
|
|
30575
|
+
return {
|
|
30576
|
+
type: ADD_POINT,
|
|
30577
|
+
location
|
|
30578
|
+
};
|
|
30579
|
+
}
|
|
30499
30580
|
const MOVE_ALL = "move-all";
|
|
30500
30581
|
function moveAll(delta) {
|
|
30501
30582
|
return {
|
|
@@ -32054,7 +32135,7 @@ function getAngleSideConstraint(sidePoint, vertex, snapDegrees) {
|
|
|
32054
32135
|
};
|
|
32055
32136
|
}
|
|
32056
32137
|
|
|
32057
|
-
function
|
|
32138
|
+
function LimitedPointGraph(props) {
|
|
32058
32139
|
const {
|
|
32059
32140
|
dispatch
|
|
32060
32141
|
} = props;
|
|
@@ -32064,6 +32145,46 @@ function PointGraph(props) {
|
|
|
32064
32145
|
onMove: destination => dispatch(actions.pointGraph.movePoint(i, destination))
|
|
32065
32146
|
})));
|
|
32066
32147
|
}
|
|
32148
|
+
function UnlimitedPointGraph(props) {
|
|
32149
|
+
const {
|
|
32150
|
+
dispatch
|
|
32151
|
+
} = props;
|
|
32152
|
+
const graphState = useGraphConfig();
|
|
32153
|
+
const {
|
|
32154
|
+
range: [[minX, maxX], [minY, maxY]]
|
|
32155
|
+
} = graphState;
|
|
32156
|
+
const width = maxX - minX;
|
|
32157
|
+
const height = maxY - minY;
|
|
32158
|
+
const [[widthPx, heightPx]] = useTransformDimensionsToPixels([width, height]);
|
|
32159
|
+
const [[left, top]] = useTransformVectorsToPixels([minX, maxY]);
|
|
32160
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("rect", {
|
|
32161
|
+
style: {
|
|
32162
|
+
fill: "rgba(0,0,0,0)"
|
|
32163
|
+
},
|
|
32164
|
+
width: widthPx,
|
|
32165
|
+
height: heightPx,
|
|
32166
|
+
x: left,
|
|
32167
|
+
y: top,
|
|
32168
|
+
onClick: event => {
|
|
32169
|
+
const elementRect = event.currentTarget.getBoundingClientRect();
|
|
32170
|
+
const x = event.clientX - elementRect.x;
|
|
32171
|
+
const y = event.clientY - elementRect.y;
|
|
32172
|
+
const graphCoordinates = pixelsToVectors([[x, y]], graphState);
|
|
32173
|
+
dispatch(actions.pointGraph.addPoint(graphCoordinates[0]));
|
|
32174
|
+
}
|
|
32175
|
+
}), props.graphState.coords.map((point, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
32176
|
+
key: i,
|
|
32177
|
+
point: point,
|
|
32178
|
+
onMove: destination => dispatch(actions.pointGraph.movePoint(i, destination))
|
|
32179
|
+
})));
|
|
32180
|
+
}
|
|
32181
|
+
function PointGraph(props) {
|
|
32182
|
+
const numPoints = props.graphState.numPoints;
|
|
32183
|
+
if (numPoints === "unlimited") {
|
|
32184
|
+
return UnlimitedPointGraph(props);
|
|
32185
|
+
}
|
|
32186
|
+
return LimitedPointGraph(props);
|
|
32187
|
+
}
|
|
32067
32188
|
|
|
32068
32189
|
const protractorImage = "https://ka-perseus-graphie.s3.amazonaws.com/e9d032f2ab8b95979f674fbfa67056442ba1ff6a.png";
|
|
32069
32190
|
|
|
@@ -32224,11 +32345,11 @@ const MafsGraph = props => {
|
|
|
32224
32345
|
labels,
|
|
32225
32346
|
disableKeyboardInteraction: readOnly || !!props.static
|
|
32226
32347
|
}
|
|
32227
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
32348
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
32228
32349
|
className: "mafs-graph",
|
|
32229
32350
|
style: {
|
|
32230
|
-
width,
|
|
32231
32351
|
height,
|
|
32352
|
+
width: "intrinsic",
|
|
32232
32353
|
position: "relative",
|
|
32233
32354
|
padding: "25px 25px 0 0",
|
|
32234
32355
|
boxSizing: "content-box",
|
|
@@ -32240,6 +32361,8 @@ const MafsGraph = props => {
|
|
|
32240
32361
|
}, /*#__PURE__*/React__namespace.createElement(LegacyGrid, {
|
|
32241
32362
|
box: props.box,
|
|
32242
32363
|
backgroundImage: props.backgroundImage
|
|
32364
|
+
}), props.showLabelsFlag && props.lockedFigures && /*#__PURE__*/React__namespace.createElement(GraphLockedLabelsLayer, {
|
|
32365
|
+
lockedFigures: props.lockedFigures
|
|
32243
32366
|
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
32244
32367
|
style: {
|
|
32245
32368
|
position: "absolute",
|
|
@@ -32269,7 +32392,41 @@ const MafsGraph = props => {
|
|
|
32269
32392
|
}), props.showProtractor && /*#__PURE__*/React__namespace.createElement(Protractor, null), renderGraph({
|
|
32270
32393
|
state,
|
|
32271
32394
|
dispatch
|
|
32272
|
-
}))))
|
|
32395
|
+
})))), renderGraphControls({
|
|
32396
|
+
state,
|
|
32397
|
+
dispatch
|
|
32398
|
+
})));
|
|
32399
|
+
};
|
|
32400
|
+
const renderPointGraphControls = props => /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
32401
|
+
kind: "secondary",
|
|
32402
|
+
style: {
|
|
32403
|
+
width: "100%",
|
|
32404
|
+
marginLeft: "20px"
|
|
32405
|
+
},
|
|
32406
|
+
onClick: () => {
|
|
32407
|
+
props.dispatch(actions.pointGraph.addPoint([0, 0]));
|
|
32408
|
+
}
|
|
32409
|
+
}, "Add Point");
|
|
32410
|
+
const renderGraphControls = props => {
|
|
32411
|
+
const {
|
|
32412
|
+
state,
|
|
32413
|
+
dispatch
|
|
32414
|
+
} = props;
|
|
32415
|
+
const {
|
|
32416
|
+
type
|
|
32417
|
+
} = state;
|
|
32418
|
+
switch (type) {
|
|
32419
|
+
case "point":
|
|
32420
|
+
if (state.numPoints === "unlimited") {
|
|
32421
|
+
return renderPointGraphControls({
|
|
32422
|
+
state,
|
|
32423
|
+
dispatch
|
|
32424
|
+
});
|
|
32425
|
+
}
|
|
32426
|
+
return null;
|
|
32427
|
+
default:
|
|
32428
|
+
return null;
|
|
32429
|
+
}
|
|
32273
32430
|
};
|
|
32274
32431
|
const renderGraph = props => {
|
|
32275
32432
|
const {
|
|
@@ -32385,7 +32542,8 @@ function initializeGraphState(params) {
|
|
|
32385
32542
|
return {
|
|
32386
32543
|
...shared,
|
|
32387
32544
|
type: graph.type,
|
|
32388
|
-
coords: getPointCoords(graph, range, step)
|
|
32545
|
+
coords: getPointCoords(graph, range, step),
|
|
32546
|
+
numPoints: graph.numPoints || 0
|
|
32389
32547
|
};
|
|
32390
32548
|
case "circle":
|
|
32391
32549
|
return {
|
|
@@ -32641,6 +32799,8 @@ function interactiveGraphReducer(state, action) {
|
|
|
32641
32799
|
return doChangeSnapStep(state, action);
|
|
32642
32800
|
case CHANGE_RANGE:
|
|
32643
32801
|
return doChangeRange(state, action);
|
|
32802
|
+
case ADD_POINT:
|
|
32803
|
+
return doAddPoint(state, action);
|
|
32644
32804
|
default:
|
|
32645
32805
|
throw new wonderStuffCore.UnreachableCaseError(action);
|
|
32646
32806
|
}
|
|
@@ -32981,6 +33141,29 @@ function doChangeRange(state, action) {
|
|
|
32981
33141
|
range: action.range
|
|
32982
33142
|
};
|
|
32983
33143
|
}
|
|
33144
|
+
function doAddPoint(state, action) {
|
|
33145
|
+
if (state.type !== "point") {
|
|
33146
|
+
return state;
|
|
33147
|
+
}
|
|
33148
|
+
const {
|
|
33149
|
+
snapStep
|
|
33150
|
+
} = state;
|
|
33151
|
+
const snappedPoint = snap(snapStep, action.location);
|
|
33152
|
+
|
|
33153
|
+
// Check if there's already a point in that spot
|
|
33154
|
+
for (const point of state.coords) {
|
|
33155
|
+
if (point[X] === snappedPoint[X] && point[Y] === snappedPoint[Y]) {
|
|
33156
|
+
return state;
|
|
33157
|
+
}
|
|
33158
|
+
}
|
|
33159
|
+
|
|
33160
|
+
// If there's no point in spot where we want the new point to go we add it there
|
|
33161
|
+
return {
|
|
33162
|
+
...state,
|
|
33163
|
+
hasBeenInteractedWith: true,
|
|
33164
|
+
coords: [...state.coords, snappedPoint]
|
|
33165
|
+
};
|
|
33166
|
+
}
|
|
32984
33167
|
const getDeltaVertex = (maxMoves, minMoves, delta) => {
|
|
32985
33168
|
const [deltaX, deltaY] = delta;
|
|
32986
33169
|
const maxXMove = Math.min(...maxMoves.map(move => move[X]));
|
|
@@ -34698,6 +34881,7 @@ class InteractiveGraph extends React__namespace.Component {
|
|
|
34698
34881
|
const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, box[0]);
|
|
34699
34882
|
const snapStep = this.props.snapStep || Util.snapStepFromGridStep(gridStep);
|
|
34700
34883
|
return /*#__PURE__*/React__namespace.createElement(StatefulMafsGraph, _extends({}, this.props, {
|
|
34884
|
+
showLabelsFlag: this.props.apiOptions?.flags?.["mafs"]?.["interactive-graph-locked-features-labels"],
|
|
34701
34885
|
ref: this.mafsRef,
|
|
34702
34886
|
gridStep: gridStep,
|
|
34703
34887
|
snapStep: snapStep,
|
|
@@ -35260,10 +35444,7 @@ function shouldUseMafs(mafsFlags, graph) {
|
|
|
35260
35444
|
switch (graph.type) {
|
|
35261
35445
|
case "point":
|
|
35262
35446
|
if (graph.numPoints === UNLIMITED) {
|
|
35263
|
-
|
|
35264
|
-
// case once we've implemented point graphs with unlimited
|
|
35265
|
-
// points
|
|
35266
|
-
return false;
|
|
35447
|
+
return Boolean(mafsFlags["unlimited-point"]);
|
|
35267
35448
|
}
|
|
35268
35449
|
return Boolean(mafsFlags["point"]);
|
|
35269
35450
|
case "polygon":
|
|
@@ -36319,7 +36500,7 @@ const HideAnswersToggle = props => {
|
|
|
36319
36500
|
strings
|
|
36320
36501
|
} = usePerseusI18n();
|
|
36321
36502
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
36322
|
-
style: styles$
|
|
36503
|
+
style: styles$h.switchWrapper
|
|
36323
36504
|
}, /*#__PURE__*/React__namespace.createElement(Switch__default["default"], {
|
|
36324
36505
|
id: switchId,
|
|
36325
36506
|
checked: props.areAnswersHidden,
|
|
@@ -36331,7 +36512,7 @@ const HideAnswersToggle = props => {
|
|
|
36331
36512
|
tag: "label"
|
|
36332
36513
|
}, strings.hideAnswersToggleLabel));
|
|
36333
36514
|
};
|
|
36334
|
-
const styles$
|
|
36515
|
+
const styles$h = aphrodite.StyleSheet.create({
|
|
36335
36516
|
switchWrapper: {
|
|
36336
36517
|
display: "flex",
|
|
36337
36518
|
flexDirection: "row",
|
|
@@ -36389,7 +36570,7 @@ const AnswerPill = props => {
|
|
|
36389
36570
|
id: idFactory.get("perseus-label-image-widget-answer-pill"),
|
|
36390
36571
|
onClick: correct ? undefined : onClick,
|
|
36391
36572
|
ref: ref,
|
|
36392
|
-
style: [style, popperStyle, styles$
|
|
36573
|
+
style: [style, popperStyle, styles$g.pill, correct && styles$g.correct, incorrect && styles$g.incorrect, (focused || hovered) && BringToFront]
|
|
36393
36574
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
36394
36575
|
content: answerString,
|
|
36395
36576
|
strings: strings,
|
|
@@ -36397,7 +36578,7 @@ const AnswerPill = props => {
|
|
|
36397
36578
|
}));
|
|
36398
36579
|
});
|
|
36399
36580
|
};
|
|
36400
|
-
const styles$
|
|
36581
|
+
const styles$g = aphrodite.StyleSheet.create({
|
|
36401
36582
|
correct: {
|
|
36402
36583
|
// WB green darkened by 18%
|
|
36403
36584
|
backgroundColor: "#00880b"
|
|
@@ -36463,25 +36644,25 @@ class Marker extends React__namespace.Component {
|
|
|
36463
36644
|
icon: iconNull
|
|
36464
36645
|
};
|
|
36465
36646
|
if (showCorrectness) {
|
|
36466
|
-
iconStyles = [styles$
|
|
36647
|
+
iconStyles = [styles$f.markerGraded, showCorrectness === "correct" ? styles$f.markerCorrect : styles$f.markerIncorrect, isOpen && styles$f.markerSelected];
|
|
36467
36648
|
args = {
|
|
36468
36649
|
...args,
|
|
36469
36650
|
icon: showCorrectness === "correct" ? iconCheck : iconMinus
|
|
36470
36651
|
};
|
|
36471
36652
|
} else if (selectedAnswers && selectedAnswers.length > 0) {
|
|
36472
|
-
iconStyles = [styles$
|
|
36653
|
+
iconStyles = [styles$f.markerFilled, isOpen && styles$f.markerSelected];
|
|
36473
36654
|
} else if (isOpen) {
|
|
36474
|
-
iconStyles = [styles$
|
|
36655
|
+
iconStyles = [styles$f.markerSelected];
|
|
36475
36656
|
args = {
|
|
36476
36657
|
...args,
|
|
36477
36658
|
icon: iconChevronDown,
|
|
36478
36659
|
size: 8
|
|
36479
36660
|
};
|
|
36480
36661
|
} else if (showPulsate) {
|
|
36481
|
-
iconStyles = [styles$
|
|
36662
|
+
iconStyles = [styles$f.markerPulsateBase, this._mounted && shouldReduceMotion() ? showPulsate && styles$f.markerUnfilledPulsateOnce : showPulsate && styles$f.markerUnfilledPulsateInfinite];
|
|
36482
36663
|
}
|
|
36483
36664
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
36484
|
-
style: [styles$
|
|
36665
|
+
style: [styles$f.markerIcon, iconStyles],
|
|
36485
36666
|
ref: node => this._icon = node
|
|
36486
36667
|
}, /*#__PURE__*/React__namespace.createElement(Icon, args));
|
|
36487
36668
|
}
|
|
@@ -36502,7 +36683,7 @@ class Marker extends React__namespace.Component {
|
|
|
36502
36683
|
const markerDisabled = showCorrectness === "correct";
|
|
36503
36684
|
const active = hovered || focused;
|
|
36504
36685
|
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
36505
|
-
style: [styles$
|
|
36686
|
+
style: [styles$f.marker, active && !markerDisabled && styles$f.markerActive],
|
|
36506
36687
|
"aria-label": markerDisabled ? this.context.strings.correctExcited : label
|
|
36507
36688
|
}, this.renderIcon()), !!selected && showAnswer && /*#__PURE__*/React__namespace.createElement(AnswerPill, {
|
|
36508
36689
|
selectedAnswers: selected,
|
|
@@ -36515,7 +36696,7 @@ class Marker extends React__namespace.Component {
|
|
|
36515
36696
|
}));
|
|
36516
36697
|
}
|
|
36517
36698
|
}
|
|
36518
|
-
const styles$
|
|
36699
|
+
const styles$f = aphrodite.StyleSheet.create({
|
|
36519
36700
|
marker: {
|
|
36520
36701
|
position: "absolute",
|
|
36521
36702
|
backgroundColor: wonderBlocksTokens.color.white,
|
|
@@ -37105,13 +37286,13 @@ class LabelImage extends React__namespace.Component {
|
|
|
37105
37286
|
const promptString = isMobile ? multipleAnswers ? strings.tapMultiple : strings.tapSingle : multipleAnswers ? strings.clickMultiple : strings.clickSingle;
|
|
37106
37287
|
const choicesString = strings.choices;
|
|
37107
37288
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
37108
|
-
className: classNames__default["default"]("perseus-label-image-widget-instructions", aphrodite.css(styles$
|
|
37289
|
+
className: classNames__default["default"]("perseus-label-image-widget-instructions", aphrodite.css(styles$e.instructions))
|
|
37109
37290
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
37110
|
-
className: aphrodite.css(styles$
|
|
37291
|
+
className: aphrodite.css(styles$e.instructionsCaption)
|
|
37111
37292
|
}, promptString, " ", !hideChoices && choicesString), !hideChoices && /*#__PURE__*/React__namespace.createElement("div", {
|
|
37112
|
-
className: aphrodite.css(styles$
|
|
37293
|
+
className: aphrodite.css(styles$e.instructionsChoices)
|
|
37113
37294
|
}, choices.map((choice, index) => /*#__PURE__*/React__namespace.createElement("div", {
|
|
37114
|
-
className: aphrodite.css(styles$
|
|
37295
|
+
className: aphrodite.css(styles$e.instructionsChoice),
|
|
37115
37296
|
key: index
|
|
37116
37297
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
37117
37298
|
content: choice,
|
|
@@ -37129,20 +37310,20 @@ class LabelImage extends React__namespace.Component {
|
|
|
37129
37310
|
activeMarkerIndex
|
|
37130
37311
|
} = this.state;
|
|
37131
37312
|
return /*#__PURE__*/React__namespace.createElement("div", null, this.renderInstructions(), /*#__PURE__*/React__namespace.createElement("div", {
|
|
37132
|
-
className: aphrodite.css(styles$
|
|
37313
|
+
className: aphrodite.css(styles$e.markersCanvas),
|
|
37133
37314
|
style: {
|
|
37134
37315
|
maxWidth: imageWidth,
|
|
37135
37316
|
maxHeight: imageHeight
|
|
37136
37317
|
}
|
|
37137
37318
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
37138
|
-
className: aphrodite.css(styles$
|
|
37319
|
+
className: aphrodite.css(styles$e.imageContainer,
|
|
37139
37320
|
// Ensure image interaction is disabled while answer
|
|
37140
37321
|
// choices popup is visible. This addresses specific
|
|
37141
37322
|
// case where user may click on question image to
|
|
37142
37323
|
// dismiss the popup. If the image is larger in size
|
|
37143
37324
|
// than its rendered in the widget, this would
|
|
37144
37325
|
// result in a zoom of the image.
|
|
37145
|
-
activeMarkerIndex !== -1 && styles$
|
|
37326
|
+
activeMarkerIndex !== -1 && styles$e.imageInteractionDisabled)
|
|
37146
37327
|
}, /*#__PURE__*/React__namespace.createElement(context$1.Consumer, null, _ref3 => {
|
|
37147
37328
|
let {
|
|
37148
37329
|
setAssetStatus
|
|
@@ -37168,7 +37349,7 @@ class LabelImage extends React__namespace.Component {
|
|
|
37168
37349
|
}));
|
|
37169
37350
|
}
|
|
37170
37351
|
}
|
|
37171
|
-
const styles$
|
|
37352
|
+
const styles$e = aphrodite.StyleSheet.create({
|
|
37172
37353
|
instructions: {
|
|
37173
37354
|
paddingBottom: 16
|
|
37174
37355
|
},
|
|
@@ -37267,7 +37448,7 @@ class Placeholder extends React__namespace.Component {
|
|
|
37267
37448
|
const {
|
|
37268
37449
|
layout
|
|
37269
37450
|
} = this.props;
|
|
37270
|
-
const className = aphrodite.css(styles$
|
|
37451
|
+
const className = aphrodite.css(styles$d.card, styles$d.placeholder, layout === Layout.HORIZONTAL && styles$d.horizontalCard);
|
|
37271
37452
|
const style = {
|
|
37272
37453
|
width: this.props.width,
|
|
37273
37454
|
height: this.props.height
|
|
@@ -37366,7 +37547,7 @@ class Draggable extends React__namespace.Component {
|
|
|
37366
37547
|
// We need to keep backwards compatbility with rules specified directly
|
|
37367
37548
|
// in CSS. Hence the hacky tacking on of manual classNames.
|
|
37368
37549
|
// See sortable.less for details.
|
|
37369
|
-
let className = aphrodite.css(styles$
|
|
37550
|
+
let className = aphrodite.css(styles$d.card, styles$d.draggable, layout === Layout.HORIZONTAL && styles$d.horizontalCard, layout === Layout.VERTICAL && styles$d.verticalCard, type === ItemState.DRAGGING && styles$d.dragging, type === ItemState.DISABLED && styles$d.disabled, !includePadding && styles$d.unpaddedCard) + " " + ClassNames.INTERACTIVE + " perseus-sortable-draggable";
|
|
37370
37551
|
if (!includePadding) {
|
|
37371
37552
|
className += " perseus-sortable-draggable-unpadded";
|
|
37372
37553
|
}
|
|
@@ -37667,7 +37848,7 @@ class Sortable extends React__namespace.Component {
|
|
|
37667
37848
|
} = this.props;
|
|
37668
37849
|
// We need to keep backwards compatbility with rules specified directly
|
|
37669
37850
|
// in CSS. See sortable.less for details.
|
|
37670
|
-
const className = aphrodite.css(styles$
|
|
37851
|
+
const className = aphrodite.css(styles$d.sortable) + " perseus-sortable";
|
|
37671
37852
|
const syncWidth = this.props.constraints?.width || layout === Layout.VERTICAL;
|
|
37672
37853
|
const syncHeight = this.props.constraints?.height || layout === Layout.HORIZONTAL;
|
|
37673
37854
|
___default["default"].each(this.state.items, function (item, i, items) {
|
|
@@ -37898,7 +38079,7 @@ class Sortable extends React__namespace.Component {
|
|
|
37898
38079
|
return ___default["default"].pluck(this.state.items, "option");
|
|
37899
38080
|
}
|
|
37900
38081
|
}
|
|
37901
|
-
const styles$
|
|
38082
|
+
const styles$d = aphrodite.StyleSheet.create({
|
|
37902
38083
|
sortable: {
|
|
37903
38084
|
boxSizing: "border-box",
|
|
37904
38085
|
float: "left",
|
|
@@ -38027,25 +38208,25 @@ class Matcher extends React__namespace.Component {
|
|
|
38027
38208
|
};
|
|
38028
38209
|
const cellMarginPx = this.props.apiOptions.isMobile ? 8 : 5;
|
|
38029
38210
|
return /*#__PURE__*/React__namespace.createElement("table", {
|
|
38030
|
-
className: aphrodite.css(styles$
|
|
38211
|
+
className: aphrodite.css(styles$c.widget) + " " + HACKY_CSS_CLASSNAME
|
|
38031
38212
|
}, /*#__PURE__*/React__namespace.createElement("tbody", null, showLabels && /*#__PURE__*/React__namespace.createElement("tr", {
|
|
38032
|
-
className: aphrodite.css(styles$
|
|
38213
|
+
className: aphrodite.css(styles$c.row)
|
|
38033
38214
|
}, /*#__PURE__*/React__namespace.createElement("th", {
|
|
38034
|
-
className: aphrodite.css(styles$
|
|
38215
|
+
className: aphrodite.css(styles$c.column, styles$c.columnLabel)
|
|
38035
38216
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
38036
38217
|
content: this.props.labels[0] || "...",
|
|
38037
38218
|
linterContext: this.props.linterContext,
|
|
38038
38219
|
strings: this.context.strings
|
|
38039
38220
|
})), /*#__PURE__*/React__namespace.createElement("th", {
|
|
38040
|
-
className: aphrodite.css(styles$
|
|
38221
|
+
className: aphrodite.css(styles$c.column, styles$c.columnRight, styles$c.columnLabel)
|
|
38041
38222
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
38042
38223
|
content: this.props.labels[1] || "...",
|
|
38043
38224
|
linterContext: this.props.linterContext,
|
|
38044
38225
|
strings: this.context.strings
|
|
38045
38226
|
}))), /*#__PURE__*/React__namespace.createElement("tr", {
|
|
38046
|
-
className: aphrodite.css(styles$
|
|
38227
|
+
className: aphrodite.css(styles$c.row)
|
|
38047
38228
|
}, /*#__PURE__*/React__namespace.createElement("td", {
|
|
38048
|
-
className: aphrodite.css(styles$
|
|
38229
|
+
className: aphrodite.css(styles$c.column)
|
|
38049
38230
|
}, /*#__PURE__*/React__namespace.createElement(Sortable, {
|
|
38050
38231
|
options: left,
|
|
38051
38232
|
layout: Layout.VERTICAL,
|
|
@@ -38060,7 +38241,7 @@ class Matcher extends React__namespace.Component {
|
|
|
38060
38241
|
,
|
|
38061
38242
|
ref: "left"
|
|
38062
38243
|
})), /*#__PURE__*/React__namespace.createElement("td", {
|
|
38063
|
-
className: aphrodite.css(styles$
|
|
38244
|
+
className: aphrodite.css(styles$c.column, styles$c.columnRight)
|
|
38064
38245
|
}, /*#__PURE__*/React__namespace.createElement(Sortable
|
|
38065
38246
|
// @ts-expect-error - TS2322 - Type 'readonly unknown[]' is not assignable to type 'readonly string[]'.
|
|
38066
38247
|
, {
|
|
@@ -38146,7 +38327,7 @@ ___default["default"].extend(Matcher, {
|
|
|
38146
38327
|
});
|
|
38147
38328
|
const padding = 5;
|
|
38148
38329
|
const border = "1px solid #444";
|
|
38149
|
-
const styles$
|
|
38330
|
+
const styles$c = aphrodite.StyleSheet.create({
|
|
38150
38331
|
widget: {
|
|
38151
38332
|
paddingTop: padding,
|
|
38152
38333
|
maxWidth: "100%",
|
|
@@ -38821,9 +39002,9 @@ function drawText(ctx, item) {
|
|
|
38821
39002
|
if (item.value === null) {
|
|
38822
39003
|
return;
|
|
38823
39004
|
}
|
|
38824
|
-
ctx.fillStyle = styles$
|
|
38825
|
-
ctx.font = styles$
|
|
38826
|
-
ctx.fillText(item.value, item.pos[0] - styles$
|
|
39005
|
+
ctx.fillStyle = styles$b.fgColor;
|
|
39006
|
+
ctx.font = styles$b.font;
|
|
39007
|
+
ctx.fillText(item.value, item.pos[0] - styles$b.fontSizePx / 2 + 1, item.pos[1] + styles$b.fontSizePx / 2);
|
|
38827
39008
|
}
|
|
38828
39009
|
|
|
38829
39010
|
/**
|
|
@@ -38844,16 +39025,16 @@ function drawText(ctx, item) {
|
|
|
38844
39025
|
function drawDoubleLine(ctx, item) {
|
|
38845
39026
|
// Outer line that forms both of the bond lines.
|
|
38846
39027
|
let path = new Path2D();
|
|
38847
|
-
ctx.lineWidth = 5 * styles$
|
|
38848
|
-
ctx.strokeStyle = styles$
|
|
39028
|
+
ctx.lineWidth = 5 * styles$b.lineWidth;
|
|
39029
|
+
ctx.strokeStyle = styles$b.fgColor;
|
|
38849
39030
|
path.moveTo(item.startPos[0], item.startPos[1]);
|
|
38850
39031
|
path.lineTo(item.endPos[0], item.endPos[1]);
|
|
38851
39032
|
ctx.stroke(path);
|
|
38852
39033
|
|
|
38853
39034
|
// Inner white line that separates the two bond lines.
|
|
38854
39035
|
path = new Path2D();
|
|
38855
|
-
ctx.lineWidth = 3 * styles$
|
|
38856
|
-
ctx.strokeStyle = styles$
|
|
39036
|
+
ctx.lineWidth = 3 * styles$b.lineWidth;
|
|
39037
|
+
ctx.strokeStyle = styles$b.bgColor;
|
|
38857
39038
|
path.moveTo(item.startPos[0], item.startPos[1]);
|
|
38858
39039
|
path.lineTo(item.endPos[0], item.endPos[1]);
|
|
38859
39040
|
ctx.stroke(path);
|
|
@@ -38880,16 +39061,16 @@ function drawTripleLine(ctx, item) {
|
|
|
38880
39061
|
|
|
38881
39062
|
// Outer line that will form the two outer bond lines.
|
|
38882
39063
|
let path = new Path2D();
|
|
38883
|
-
ctx.lineWidth = 7 * styles$
|
|
38884
|
-
ctx.strokeStyle = styles$
|
|
39064
|
+
ctx.lineWidth = 7 * styles$b.lineWidth;
|
|
39065
|
+
ctx.strokeStyle = styles$b.fgColor;
|
|
38885
39066
|
path.moveTo(item.startPos[0], item.startPos[1]);
|
|
38886
39067
|
path.lineTo(item.endPos[0], item.endPos[1]);
|
|
38887
39068
|
ctx.stroke(path);
|
|
38888
39069
|
|
|
38889
39070
|
// Middle white line that separates the bonds
|
|
38890
39071
|
path = new Path2D();
|
|
38891
|
-
ctx.lineWidth = 5 * styles$
|
|
38892
|
-
ctx.strokeStyle = styles$
|
|
39072
|
+
ctx.lineWidth = 5 * styles$b.lineWidth;
|
|
39073
|
+
ctx.strokeStyle = styles$b.bgColor;
|
|
38893
39074
|
path.moveTo(item.startPos[0], item.startPos[1]);
|
|
38894
39075
|
path.lineTo(item.endPos[0], item.endPos[1]);
|
|
38895
39076
|
ctx.stroke(path);
|
|
@@ -38911,8 +39092,8 @@ function drawTripleLine(ctx, item) {
|
|
|
38911
39092
|
*/
|
|
38912
39093
|
function drawLine(ctx, item) {
|
|
38913
39094
|
const path = new Path2D();
|
|
38914
|
-
ctx.lineWidth = styles$
|
|
38915
|
-
ctx.strokeStyle = styles$
|
|
39095
|
+
ctx.lineWidth = styles$b.lineWidth;
|
|
39096
|
+
ctx.strokeStyle = styles$b.fgColor;
|
|
38916
39097
|
path.moveTo(item.startPos[0], item.startPos[1]);
|
|
38917
39098
|
path.lineTo(item.endPos[0], item.endPos[1]);
|
|
38918
39099
|
ctx.stroke(path);
|
|
@@ -38964,7 +39145,7 @@ function compareElements(item0, item1) {
|
|
|
38964
39145
|
function draw(ctx, items) {
|
|
38965
39146
|
items.sort(compareElements).forEach(drawItem(ctx));
|
|
38966
39147
|
}
|
|
38967
|
-
const styles$
|
|
39148
|
+
const styles$b = {
|
|
38968
39149
|
bgColor: "rgb(255, 255, 255)",
|
|
38969
39150
|
fgColor: "rgb(0, 0, 0)",
|
|
38970
39151
|
fontSizePx: 12,
|
|
@@ -41525,7 +41706,7 @@ class HighlightRenderer extends React__namespace.PureComponent {
|
|
|
41525
41706
|
const rects = this.state.cachedHighlightRects;
|
|
41526
41707
|
return /*#__PURE__*/React__namespace.createElement("div", null, rects.map((rect, index) => /*#__PURE__*/React__namespace.createElement("div", {
|
|
41527
41708
|
key: index,
|
|
41528
|
-
className: aphrodite.css(styles$
|
|
41709
|
+
className: aphrodite.css(styles$a.highlightRect),
|
|
41529
41710
|
style: {
|
|
41530
41711
|
// NOTE(mdr): We apply `position: absolute` here
|
|
41531
41712
|
// rather than in Aphrodite styles, because
|
|
@@ -41544,7 +41725,7 @@ class HighlightRenderer extends React__namespace.PureComponent {
|
|
|
41544
41725
|
})));
|
|
41545
41726
|
}
|
|
41546
41727
|
}
|
|
41547
|
-
const styles$
|
|
41728
|
+
const styles$a = aphrodite.StyleSheet.create({
|
|
41548
41729
|
highlightRect: {
|
|
41549
41730
|
background: "#fffabe" // highlighter yellow :)
|
|
41550
41731
|
}
|
|
@@ -41625,7 +41806,7 @@ class HighlightTooltip extends React__namespace.PureComponent {
|
|
|
41625
41806
|
// TooltipContent wouldn't let me overwrite
|
|
41626
41807
|
// user-select and onClick
|
|
41627
41808
|
const content = /*#__PURE__*/React__namespace.createElement("div", {
|
|
41628
|
-
className: aphrodite.css(styles$
|
|
41809
|
+
className: aphrodite.css(styles$9.tooltipLabel),
|
|
41629
41810
|
onClick: this.props.onClick
|
|
41630
41811
|
}, this.props.label);
|
|
41631
41812
|
const style = {
|
|
@@ -41645,7 +41826,7 @@ class HighlightTooltip extends React__namespace.PureComponent {
|
|
|
41645
41826
|
}, /*#__PURE__*/React__namespace.createElement("div", null)));
|
|
41646
41827
|
}
|
|
41647
41828
|
}
|
|
41648
|
-
const styles$
|
|
41829
|
+
const styles$9 = aphrodite.StyleSheet.create({
|
|
41649
41830
|
tooltipLabel: {
|
|
41650
41831
|
// Unlike most tooltip contents, we don't want this label to be
|
|
41651
41832
|
// selectable. Selecting it is not only unhelpful, but dangerous: if
|
|
@@ -42207,7 +42388,7 @@ class HighlightableContent extends React__namespace.PureComponent {
|
|
|
42207
42388
|
// starting point: https://phabricator.khanacademy.org/D35623?id=170698
|
|
42208
42389
|
const buildHighlight = r => this._buildHighlight(r);
|
|
42209
42390
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
42210
|
-
className: aphrodite.css(styles$
|
|
42391
|
+
className: aphrodite.css(styles$8.container),
|
|
42211
42392
|
ref: container => this._container = container
|
|
42212
42393
|
}, /*#__PURE__*/React__namespace.createElement("div", null, this.props.enabled && this._container && this._content && /*#__PURE__*/React__namespace.createElement(HighlightingUI, {
|
|
42213
42394
|
buildHighlight: buildHighlight,
|
|
@@ -42228,14 +42409,14 @@ class HighlightableContent extends React__namespace.PureComponent {
|
|
|
42228
42409
|
onAddHighlight: this._handleAddHighlight,
|
|
42229
42410
|
onRemoveHighlight: this._handleRemoveHighlight
|
|
42230
42411
|
})), /*#__PURE__*/React__namespace.createElement("div", {
|
|
42231
|
-
className: aphrodite.css(styles$
|
|
42412
|
+
className: aphrodite.css(styles$8.content),
|
|
42232
42413
|
ref: content => this._content = content
|
|
42233
42414
|
}, /*#__PURE__*/React__namespace.createElement(WordIndexer, {
|
|
42234
42415
|
onWordsUpdate: this._handleWordsUpdate
|
|
42235
42416
|
}, this.props.children)));
|
|
42236
42417
|
}
|
|
42237
42418
|
}
|
|
42238
|
-
const styles$
|
|
42419
|
+
const styles$8 = aphrodite.StyleSheet.create({
|
|
42239
42420
|
// We render content with z-index 1, and highlights with z-index 0, so that
|
|
42240
42421
|
// content will receive the browser's native pointer events. (Highlights
|
|
42241
42422
|
// have their own magic code to manage hover detection, despite being
|
|
@@ -42645,7 +42826,7 @@ class LineHeightMeasurer extends React__namespace.Component {
|
|
|
42645
42826
|
}
|
|
42646
42827
|
render() {
|
|
42647
42828
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
42648
|
-
className: aphrodite.css(styles$
|
|
42829
|
+
className: aphrodite.css(styles$7.measurer),
|
|
42649
42830
|
"aria-hidden": "true"
|
|
42650
42831
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
42651
42832
|
ref: ref => this._line = ref,
|
|
@@ -42653,7 +42834,7 @@ class LineHeightMeasurer extends React__namespace.Component {
|
|
|
42653
42834
|
}, "Line Height Measurement"));
|
|
42654
42835
|
}
|
|
42655
42836
|
}
|
|
42656
|
-
const styles$
|
|
42837
|
+
const styles$7 = aphrodite.StyleSheet.create({
|
|
42657
42838
|
measurer: {
|
|
42658
42839
|
position: "absolute",
|
|
42659
42840
|
top: 0,
|
|
@@ -43127,6 +43308,212 @@ var PassageRefTarget$1 = {
|
|
|
43127
43308
|
isLintable: true
|
|
43128
43309
|
};
|
|
43129
43310
|
|
|
43311
|
+
/* eslint-disable react/forbid-prop-types, react/sort-comp */
|
|
43312
|
+
|
|
43313
|
+
// For returning user input, but currently the PhET widget
|
|
43314
|
+
// does not support accessing user input
|
|
43315
|
+
// This renders the PhET sim
|
|
43316
|
+
class PhetSimulation extends React__namespace.Component {
|
|
43317
|
+
static contextType = PerseusI18nContext;
|
|
43318
|
+
iframeRef = /*#__PURE__*/React__namespace.createRef();
|
|
43319
|
+
locale;
|
|
43320
|
+
state = {
|
|
43321
|
+
url: null,
|
|
43322
|
+
banner: null
|
|
43323
|
+
};
|
|
43324
|
+
constructor(props) {
|
|
43325
|
+
super(props);
|
|
43326
|
+
this.locale = this.getPhetCompatibleLocale(getDependencies().kaLocale);
|
|
43327
|
+
}
|
|
43328
|
+
getUserInput() {
|
|
43329
|
+
return null;
|
|
43330
|
+
}
|
|
43331
|
+
async componentDidMount() {
|
|
43332
|
+
await this.updateSimState(this.props.url);
|
|
43333
|
+
}
|
|
43334
|
+
async componentDidUpdate(prevProps) {
|
|
43335
|
+
// If the URL has changed, update our state
|
|
43336
|
+
if (prevProps.url !== this.props.url) {
|
|
43337
|
+
await this.updateSimState(this.props.url);
|
|
43338
|
+
}
|
|
43339
|
+
}
|
|
43340
|
+
render() {
|
|
43341
|
+
// We sandbox the iframe so that we allowlist only the functionality
|
|
43342
|
+
// that we need. This makes it safer to present third-party content
|
|
43343
|
+
// from the PhET website.
|
|
43344
|
+
// http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
|
|
43345
|
+
const sandboxProperties = "allow-same-origin allow-scripts";
|
|
43346
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
43347
|
+
style: styles$6.container
|
|
43348
|
+
}, this.state.banner !== null &&
|
|
43349
|
+
/*#__PURE__*/
|
|
43350
|
+
// TODO(anna): Make this banner focusable
|
|
43351
|
+
React__namespace.createElement(wonderBlocksCore.View, {
|
|
43352
|
+
style: {
|
|
43353
|
+
marginBottom: phoneMargin
|
|
43354
|
+
}
|
|
43355
|
+
}, /*#__PURE__*/React__namespace.createElement(Banner__default["default"], {
|
|
43356
|
+
layout: "floating",
|
|
43357
|
+
kind: this.state.banner.kind,
|
|
43358
|
+
text: this.state.banner.message
|
|
43359
|
+
})), /*#__PURE__*/React__namespace.createElement("iframe", {
|
|
43360
|
+
ref: this.iframeRef,
|
|
43361
|
+
title: this.props.description,
|
|
43362
|
+
sandbox: sandboxProperties,
|
|
43363
|
+
style: {
|
|
43364
|
+
minWidth: 400,
|
|
43365
|
+
height: 360,
|
|
43366
|
+
width: "100%",
|
|
43367
|
+
borderWidth: 0
|
|
43368
|
+
},
|
|
43369
|
+
src: this.state.url?.toString(),
|
|
43370
|
+
allow: "fullscreen"
|
|
43371
|
+
}), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
|
|
43372
|
+
icon: cornersOutIcon__default["default"],
|
|
43373
|
+
onClick: () => {
|
|
43374
|
+
this.iframeRef.current?.requestFullscreen();
|
|
43375
|
+
},
|
|
43376
|
+
kind: "secondary",
|
|
43377
|
+
"aria-label": "Fullscreen",
|
|
43378
|
+
style: {
|
|
43379
|
+
marginTop: 5,
|
|
43380
|
+
marginBottom: 5,
|
|
43381
|
+
alignSelf: "flex-end"
|
|
43382
|
+
},
|
|
43383
|
+
disabled: this.state.url === null
|
|
43384
|
+
}));
|
|
43385
|
+
}
|
|
43386
|
+
change = (() => {
|
|
43387
|
+
var _this = this;
|
|
43388
|
+
return function () {
|
|
43389
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
43390
|
+
args[_key] = arguments[_key];
|
|
43391
|
+
}
|
|
43392
|
+
// @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
|
|
43393
|
+
return change.apply(_this, args);
|
|
43394
|
+
};
|
|
43395
|
+
})();
|
|
43396
|
+
simpleValidate = rubric => {
|
|
43397
|
+
// @ts-expect-error - TS2339 - Property 'validate' does not exist on type 'typeof PhetSimulation'.
|
|
43398
|
+
return PhetSimulation.validate(this.getUserInput(), rubric);
|
|
43399
|
+
};
|
|
43400
|
+
|
|
43401
|
+
// kaLocales and PhET locales use different formats and abbreviations.
|
|
43402
|
+
// PhET accepts different formats, i.e. kaLocale's hyphens, but it does not accept
|
|
43403
|
+
// different abbreviations, so in points of divergence of abbreviations, we need to
|
|
43404
|
+
// convert kaLocale abbreviations into abbreviations recognized by PhET.
|
|
43405
|
+
getPhetCompatibleLocale = kaLocale => {
|
|
43406
|
+
switch (kaLocale) {
|
|
43407
|
+
case "pt-pt":
|
|
43408
|
+
return "pt";
|
|
43409
|
+
case "zh-hans":
|
|
43410
|
+
return "zh_CN";
|
|
43411
|
+
case "zh-hant":
|
|
43412
|
+
return "zh_TW";
|
|
43413
|
+
case "fa-af":
|
|
43414
|
+
return "fa_DA";
|
|
43415
|
+
default:
|
|
43416
|
+
return kaLocale;
|
|
43417
|
+
}
|
|
43418
|
+
};
|
|
43419
|
+
displayLoadFailure = () => {
|
|
43420
|
+
this.setState({
|
|
43421
|
+
url: null,
|
|
43422
|
+
banner: {
|
|
43423
|
+
message: this.context.strings.simulationLoadFail,
|
|
43424
|
+
kind: "critical"
|
|
43425
|
+
}
|
|
43426
|
+
});
|
|
43427
|
+
};
|
|
43428
|
+
async updateSimState(urlString) {
|
|
43429
|
+
const url = makeSafeUrl(urlString, this.locale);
|
|
43430
|
+
if (url === null) {
|
|
43431
|
+
this.displayLoadFailure();
|
|
43432
|
+
return;
|
|
43433
|
+
}
|
|
43434
|
+
const response = await fetch(url);
|
|
43435
|
+
if (!response.ok) {
|
|
43436
|
+
this.displayLoadFailure();
|
|
43437
|
+
return;
|
|
43438
|
+
}
|
|
43439
|
+
const showLocaleWarning = await this.showLocaleWarning(url);
|
|
43440
|
+
this.setState({
|
|
43441
|
+
url: url,
|
|
43442
|
+
banner: showLocaleWarning ? {
|
|
43443
|
+
message: this.context.strings.simulationLocaleWarning,
|
|
43444
|
+
kind: "warning"
|
|
43445
|
+
} : null
|
|
43446
|
+
});
|
|
43447
|
+
}
|
|
43448
|
+
async showLocaleWarning(url) {
|
|
43449
|
+
// Do not show a locale warning on an invalid URL
|
|
43450
|
+
if (!url) {
|
|
43451
|
+
return false;
|
|
43452
|
+
}
|
|
43453
|
+
// Grab the simulation name
|
|
43454
|
+
const phetRegex = /https:\/\/phet\.colorado\.edu\/sims\/html\/([a-zA-Z0-9-]+)\/.*/g;
|
|
43455
|
+
const match = phetRegex.exec(url.toString());
|
|
43456
|
+
// Do not show a locale warning on a non-simulation URL
|
|
43457
|
+
if (match === null) {
|
|
43458
|
+
return false;
|
|
43459
|
+
}
|
|
43460
|
+
const simName = match[1];
|
|
43461
|
+
const response = await fetch(`https://phet.colorado.edu/sims/html/${simName}/latest/string-map.json`);
|
|
43462
|
+
if (!response.ok) {
|
|
43463
|
+
return false;
|
|
43464
|
+
}
|
|
43465
|
+
let responseJson;
|
|
43466
|
+
try {
|
|
43467
|
+
responseJson = await response.json();
|
|
43468
|
+
} catch {
|
|
43469
|
+
// If the file exists but there is no content to parse into a JSON,
|
|
43470
|
+
// response.json() will throw an error that we want to catch.
|
|
43471
|
+
return false;
|
|
43472
|
+
}
|
|
43473
|
+
const locales = Object.keys(responseJson);
|
|
43474
|
+
|
|
43475
|
+
// Only display a locale warning if there is no fallback language
|
|
43476
|
+
const baseLocale = this.locale.split("_")[0];
|
|
43477
|
+
for (const l of locales) {
|
|
43478
|
+
if (baseLocale === l.split("_")[0]) {
|
|
43479
|
+
return false;
|
|
43480
|
+
}
|
|
43481
|
+
}
|
|
43482
|
+
return true;
|
|
43483
|
+
}
|
|
43484
|
+
}
|
|
43485
|
+
|
|
43486
|
+
// Setting URL to null will display an error message in the iframe
|
|
43487
|
+
const makeSafeUrl = (urlString, locale) => {
|
|
43488
|
+
if (!URL.canParse(urlString)) {
|
|
43489
|
+
return null;
|
|
43490
|
+
}
|
|
43491
|
+
const url = new URL(urlString);
|
|
43492
|
+
if (url.origin !== "https://phet.colorado.edu") {
|
|
43493
|
+
return null;
|
|
43494
|
+
}
|
|
43495
|
+
url.searchParams.set("locale", locale);
|
|
43496
|
+
return url;
|
|
43497
|
+
};
|
|
43498
|
+
var PhetSimulation$1 = {
|
|
43499
|
+
name: "phet-simulation",
|
|
43500
|
+
displayName: "PhET Simulation",
|
|
43501
|
+
widget: PhetSimulation,
|
|
43502
|
+
// Hides widget from content creators until full release
|
|
43503
|
+
hidden: true,
|
|
43504
|
+
isLintable: true
|
|
43505
|
+
};
|
|
43506
|
+
const styles$6 = aphrodite.StyleSheet.create({
|
|
43507
|
+
container: {
|
|
43508
|
+
borderRadius: borderRadiusLarge,
|
|
43509
|
+
borderWidth: 1,
|
|
43510
|
+
borderColor: basicBorderColor,
|
|
43511
|
+
padding: phoneMargin,
|
|
43512
|
+
paddingBottom: 0,
|
|
43513
|
+
width: 650
|
|
43514
|
+
}
|
|
43515
|
+
});
|
|
43516
|
+
|
|
43130
43517
|
/* eslint-disable react/no-unsafe */
|
|
43131
43518
|
const {
|
|
43132
43519
|
deepEq
|
|
@@ -44588,7 +44975,7 @@ var Video$1 = {
|
|
|
44588
44975
|
};
|
|
44589
44976
|
|
|
44590
44977
|
/* eslint-disable import/no-named-as-default */
|
|
44591
|
-
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, Video$1, DeprecatedStandin$1];
|
|
44978
|
+
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, PhetSimulation$1, Plotter$1, PythonProgram$1, Sorter$1, Table$1, Video$1, DeprecatedStandin$1];
|
|
44592
44979
|
|
|
44593
44980
|
/**
|
|
44594
44981
|
* This should be called by all clients, specifying whether extra widgets are
|
|
@@ -44628,7 +45015,7 @@ const init = function (options) {
|
|
|
44628
45015
|
|
|
44629
45016
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
44630
45017
|
const libName = "@khanacademy/perseus";
|
|
44631
|
-
const libVersion = "
|
|
45018
|
+
const libVersion = "31.0.1";
|
|
44632
45019
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
44633
45020
|
|
|
44634
45021
|
const apiVersion = {
|
|
@@ -48203,6 +48590,7 @@ const widgetNameToEnum = {
|
|
|
48203
48590
|
passage: "PASSAGE",
|
|
48204
48591
|
"passage-ref": "PASSAGE_REF",
|
|
48205
48592
|
"passage-ref-target": "PASSAGE_REF_TARGET",
|
|
48593
|
+
"phet-simulation": "PHET_SIMULATION",
|
|
48206
48594
|
plotter: "PLOTTER",
|
|
48207
48595
|
"python-program": "PYTHON_PROGRAM",
|
|
48208
48596
|
"reaction-diagram": "REACTION_DIAGRAM",
|