@khanacademy/perseus 20.1.0 → 20.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/graph.d.ts +1 -2
- package/dist/es/index.css +58 -4
- package/dist/es/index.js +183 -188
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +58 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +173 -177
- package/dist/index.js.map +1 -1
- package/dist/perseus-types.d.ts +1 -0
- package/dist/util.d.ts +1 -0
- package/dist/widgets/interactive-graphs/graph-locked-layer.d.ts +7 -0
- package/dist/widgets/interactive-graphs/movable-point.d.ts +8 -0
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -2363,7 +2363,7 @@ img.zoom-img {
|
|
|
2363
2363
|
}
|
|
2364
2364
|
.framework-perseus .perseus-renderer > .paragraph > ul:not(.perseus-widget-radio),
|
|
2365
2365
|
.framework-perseus .perseus-renderer > .paragraph > ol {
|
|
2366
|
-
margin:
|
|
2366
|
+
margin: 0px 0px 22px 0px;
|
|
2367
2367
|
}
|
|
2368
2368
|
.framework-perseus .paragraph ul:not(.perseus-widget-radio, .indicatorContainer) {
|
|
2369
2369
|
padding-left: 35px;
|
|
@@ -4258,18 +4258,24 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
|
|
|
4258
4258
|
--mafs-bg: transparent;
|
|
4259
4259
|
--mafs-fg: rgb(33, 36, 44); /* WB color.offBlack */
|
|
4260
4260
|
|
|
4261
|
-
--mafs-line-color:
|
|
4262
|
-
--grid-line-subdivision-color: rgba(33, 36, 44, 0.16);
|
|
4261
|
+
--mafs-line-color: rgba(33, 36, 44, 0.16); /* WB color.offBlack16*/
|
|
4263
4262
|
|
|
4264
4263
|
--mafs-blue: #1865f2; /* WB color.blue */
|
|
4265
4264
|
--mafs-red: #d92916; /* WB color.red */
|
|
4266
4265
|
--mafs-green: #00a60e; /* WB color.green */
|
|
4267
4266
|
--mafs-violet: #9059ff; /* WB color.purple */
|
|
4268
4267
|
--mafs-yellow: #ffb100; /* WB color.gold */
|
|
4268
|
+
|
|
4269
|
+
/* overridden on a per-point basis */
|
|
4270
|
+
--movable-point-color: var(--mafs-blue);
|
|
4271
|
+
--movable-point-center-radius: 6px;
|
|
4272
|
+
--movable-point-ring-radius: calc(2px + var(--movable-point-center-radius));
|
|
4273
|
+
--movable-point-halo-radius: calc(3px + var(--movable-point-ring-radius));
|
|
4274
|
+
--movable-point-hover-expansion: 2px;
|
|
4269
4275
|
}
|
|
4270
4276
|
|
|
4271
4277
|
.MafsView .movable-segment {
|
|
4272
|
-
--mafs-segment-stroke-color:
|
|
4278
|
+
--mafs-segment-stroke-color: rgba(33, 36, 44, 0.64); /* offBlack64 */
|
|
4273
4279
|
--mafs-segment-stroke-weight: 2px;
|
|
4274
4280
|
}
|
|
4275
4281
|
|
|
@@ -4282,3 +4288,51 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
|
|
|
4282
4288
|
.MafsView .movable-segment:focus {
|
|
4283
4289
|
outline: none;
|
|
4284
4290
|
}
|
|
4291
|
+
|
|
4292
|
+
.MafsView .movable-point-hitbox {
|
|
4293
|
+
fill: transparent;
|
|
4294
|
+
}
|
|
4295
|
+
|
|
4296
|
+
.MafsView :is(.movable-point-center, .movable-point-ring, .movable-point-halo) {
|
|
4297
|
+
transition: r 0.15s ease-out;
|
|
4298
|
+
}
|
|
4299
|
+
|
|
4300
|
+
.MafsView .movable-point-center {
|
|
4301
|
+
r: var(--movable-point-center-radius);
|
|
4302
|
+
}
|
|
4303
|
+
|
|
4304
|
+
.MafsView .movable-point-halo {
|
|
4305
|
+
r: var(--movable-point-halo-radius);
|
|
4306
|
+
fill: var(--movable-point-color);
|
|
4307
|
+
opacity: 0.25;
|
|
4308
|
+
filter: drop-shadow(0 5px 5px #0008);
|
|
4309
|
+
}
|
|
4310
|
+
|
|
4311
|
+
.MafsView .movable-point-ring {
|
|
4312
|
+
r: var(--movable-point-ring-radius);
|
|
4313
|
+
fill: #fff;
|
|
4314
|
+
}
|
|
4315
|
+
|
|
4316
|
+
.MafsView .movable-point:hover .movable-point-center {
|
|
4317
|
+
r: calc(
|
|
4318
|
+
var(--movable-point-hover-expansion) +
|
|
4319
|
+
var(--movable-point-center-radius)
|
|
4320
|
+
);
|
|
4321
|
+
}
|
|
4322
|
+
|
|
4323
|
+
.MafsView .movable-point:hover .movable-point-ring {
|
|
4324
|
+
r: calc(
|
|
4325
|
+
var(--movable-point-hover-expansion) + var(--movable-point-ring-radius)
|
|
4326
|
+
);
|
|
4327
|
+
}
|
|
4328
|
+
|
|
4329
|
+
.MafsView .movable-point:hover .movable-point-halo {
|
|
4330
|
+
r: calc(
|
|
4331
|
+
var(--movable-point-hover-expansion) + var(--movable-point-halo-radius)
|
|
4332
|
+
);
|
|
4333
|
+
}
|
|
4334
|
+
|
|
4335
|
+
.MafsView .movable-point:focus-visible .movable-point-halo {
|
|
4336
|
+
outline: 2px solid blue;
|
|
4337
|
+
border-radius: 99px;
|
|
4338
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -83,7 +83,7 @@ export type { ILogger, LogErrorOptions, ErrorKind } from "./logging/log";
|
|
|
83
83
|
export type { ServerItemRenderer as ServerItemRendererComponent } from "./server-item-renderer";
|
|
84
84
|
export type { Alignment, APIOptions, APIOptionsWithDefaults, ChangeHandler, DeviceType, DomInsertCheckFn, EditorMode, FocusPath, Hint, ImageDict, ImageUploader, JiptLabelStore, JiptRenderer, PerseusDependencies, PerseusScore, Version, VideoData, VideoKind, WidgetDict, WidgetExports, } from "./types";
|
|
85
85
|
export type { ParsedValue } from "./util";
|
|
86
|
-
export type { PerseusAnswerArea, PerseusExpressionWidgetOptions, Range, Size, MathFormat, InputNumberWidget, // TODO(jeremy): remove?
|
|
86
|
+
export type { LockedFigure, LockedFigureType, LockedPoint, PerseusGraphType, PerseusAnswerArea, PerseusExpressionWidgetOptions, Range, Size, MathFormat, InputNumberWidget, // TODO(jeremy): remove?
|
|
87
87
|
PerseusImageBackground, PerseusInputNumberWidgetOptions, PerseusInteractiveGraphWidgetOptions, PerseusItem, PerseusPlotterWidgetOptions, PerseusPythonProgramWidgetOptions, PerseusRadioWidgetOptions, PerseusExampleWidgetOptions, PerseusExampleGraphieWidgetOptions, PerseusSimpleMarkdownTesterWidgetOptions, PerseusRenderer, PerseusWidget, PerseusWidgetsMap, } from "./perseus-types";
|
|
88
88
|
export type { Coord } from "./interactive2/types";
|
|
89
89
|
export type { MarkerType } from "./widgets/label-image/types";
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,8 @@ var Button = require('@khanacademy/wonder-blocks-button');
|
|
|
29
29
|
var wonderBlocksLayout = require('@khanacademy/wonder-blocks-layout');
|
|
30
30
|
var Banner = require('@khanacademy/wonder-blocks-banner');
|
|
31
31
|
var wonderBlocksDropdown = require('@khanacademy/wonder-blocks-dropdown');
|
|
32
|
+
var caretDown = require('@phosphor-icons/core/assets/regular/caret-down.svg');
|
|
33
|
+
var caretUp = require('@phosphor-icons/core/assets/regular/caret-up.svg');
|
|
32
34
|
var debounce$1 = require('lodash.debounce');
|
|
33
35
|
var mafs = require('mafs');
|
|
34
36
|
var wonderBlocksIcon = require('@khanacademy/wonder-blocks-icon');
|
|
@@ -79,6 +81,8 @@ var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
|
|
|
79
81
|
var SimpleMarkdown__default = /*#__PURE__*/_interopDefaultLegacy(SimpleMarkdown);
|
|
80
82
|
var Button__default = /*#__PURE__*/_interopDefaultLegacy(Button);
|
|
81
83
|
var Banner__default = /*#__PURE__*/_interopDefaultLegacy(Banner);
|
|
84
|
+
var caretDown__default = /*#__PURE__*/_interopDefaultLegacy(caretDown);
|
|
85
|
+
var caretUp__default = /*#__PURE__*/_interopDefaultLegacy(caretUp);
|
|
82
86
|
var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce$1);
|
|
83
87
|
var questionIcon__default = /*#__PURE__*/_interopDefaultLegacy(questionIcon);
|
|
84
88
|
var createReactClass__default = /*#__PURE__*/_interopDefaultLegacy(createReactClass);
|
|
@@ -2705,11 +2709,14 @@ function combineScores(scoreA, scoreB) {
|
|
|
2705
2709
|
}
|
|
2706
2710
|
});
|
|
2707
2711
|
}
|
|
2712
|
+
function isCorrect(score) {
|
|
2713
|
+
return score.type === "points" && score.earned >= score.total;
|
|
2714
|
+
}
|
|
2708
2715
|
function keScoreFromPerseusScore(score, guess, state) {
|
|
2709
2716
|
if (score.type === "points") {
|
|
2710
2717
|
return {
|
|
2711
2718
|
empty: false,
|
|
2712
|
-
correct: score
|
|
2719
|
+
correct: isCorrect(score),
|
|
2713
2720
|
message: score.message,
|
|
2714
2721
|
guess: guess,
|
|
2715
2722
|
state: state
|
|
@@ -15001,7 +15008,7 @@ const DEFAULT_STATE$1 = {
|
|
|
15001
15008
|
// TODO(benchristel): this is a memory leak. We add items to
|
|
15002
15009
|
// tooltipResetFunctions, but never remove them.
|
|
15003
15010
|
const tooltipResetFunctions = [];
|
|
15004
|
-
class MovablePoint$
|
|
15011
|
+
class MovablePoint$5 {
|
|
15005
15012
|
// @ts-expect-error - TS2564: Property 'prevState' has no initializer and is not definitely assigned in the constructor.
|
|
15006
15013
|
|
|
15007
15014
|
_listenerMap = {};
|
|
@@ -16129,10 +16136,10 @@ ___default["default"].extend(MovablePolygon.prototype, {
|
|
|
16129
16136
|
});
|
|
16130
16137
|
|
|
16131
16138
|
const Interactive2 = {
|
|
16132
|
-
MovablePoint: MovablePoint$
|
|
16139
|
+
MovablePoint: MovablePoint$5,
|
|
16133
16140
|
addMovablePoint: function (graphie, options) {
|
|
16134
16141
|
const movable = new Movable(graphie, {});
|
|
16135
|
-
return new MovablePoint$
|
|
16142
|
+
return new MovablePoint$5(graphie, movable, options);
|
|
16136
16143
|
},
|
|
16137
16144
|
MovableLine: MovableLine$3,
|
|
16138
16145
|
addMovableLine: function (graphie, options) {
|
|
@@ -16174,7 +16181,7 @@ const Interactive2 = {
|
|
|
16174
16181
|
}
|
|
16175
16182
|
};
|
|
16176
16183
|
|
|
16177
|
-
const MovablePoint$
|
|
16184
|
+
const MovablePoint$4 = GraphieClasses.createClass({
|
|
16178
16185
|
displayName: "MovablePoint",
|
|
16179
16186
|
movableProps: ["children"],
|
|
16180
16187
|
_getProps: function () {
|
|
@@ -16232,7 +16239,7 @@ const MovablePoint$3 = GraphieClasses.createClass({
|
|
|
16232
16239
|
});
|
|
16233
16240
|
|
|
16234
16241
|
// Include helper methods, such as MovablePoint.constrain.snap()
|
|
16235
|
-
___default["default"].extend(MovablePoint$
|
|
16242
|
+
___default["default"].extend(MovablePoint$4, Interactive2.MovablePoint);
|
|
16236
16243
|
const MovableLine$2 = GraphieClasses.createClass({
|
|
16237
16244
|
displayName: "MovableLine",
|
|
16238
16245
|
movableProps: ["children"],
|
|
@@ -16402,7 +16409,7 @@ var Movables = {
|
|
|
16402
16409
|
Label: Label$1,
|
|
16403
16410
|
Line: Line$2,
|
|
16404
16411
|
MovableLine: MovableLine$2,
|
|
16405
|
-
MovablePoint: MovablePoint$
|
|
16412
|
+
MovablePoint: MovablePoint$4,
|
|
16406
16413
|
Parabola: Parabola,
|
|
16407
16414
|
Path: Path,
|
|
16408
16415
|
Plot: Plot$2,
|
|
@@ -25007,57 +25014,42 @@ class Explanation extends React__namespace.Component {
|
|
|
25007
25014
|
this.props.trackInteraction();
|
|
25008
25015
|
};
|
|
25009
25016
|
render() {
|
|
25010
|
-
const {
|
|
25011
|
-
isArticle,
|
|
25012
|
-
isMobile
|
|
25013
|
-
} = this.props.apiOptions;
|
|
25014
25017
|
const promptText = this.state.expanded ? this.props.hidePrompt : this.props.showPrompt;
|
|
25015
|
-
|
|
25016
|
-
|
|
25017
|
-
|
|
25018
|
-
//
|
|
25019
|
-
|
|
25020
|
-
const
|
|
25021
|
-
|
|
25022
|
-
|
|
25023
|
-
|
|
25024
|
-
|
|
25025
|
-
|
|
25026
|
-
|
|
25027
|
-
|
|
25028
|
-
|
|
25029
|
-
|
|
25030
|
-
|
|
25031
|
-
|
|
25032
|
-
|
|
25033
|
-
|
|
25034
|
-
|
|
25035
|
-
|
|
25036
|
-
|
|
25037
|
-
|
|
25038
|
-
|
|
25039
|
-
|
|
25040
|
-
|
|
25041
|
-
|
|
25042
|
-
|
|
25043
|
-
|
|
25044
|
-
style: viewStyling
|
|
25045
|
-
}, `[${promptText}]`));
|
|
25046
|
-
}
|
|
25047
|
-
const expandedStyle = isMobile ? styles$p.contentExpandedMobile : styles$p.contentExpanded;
|
|
25048
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
25049
|
-
className: aphrodite.css(styles$p.container)
|
|
25050
|
-
}, promptContainer, this.state.expanded && /*#__PURE__*/React__namespace.createElement("div", {
|
|
25051
|
-
className: aphrodite.css(styles$p.content, isMobile && styles$p.contentMobile, this.state.expanded && expandedStyle)
|
|
25052
|
-
// eslint-disable-next-line react/no-string-refs
|
|
25053
|
-
,
|
|
25054
|
-
ref: "content"
|
|
25018
|
+
const caretIcon = this.state.expanded ? caretUp__default["default"] : caretDown__default["default"];
|
|
25019
|
+
const allowTransition = window.matchMedia("(prefers-reduced-motion: no-preference)").matches;
|
|
25020
|
+
|
|
25021
|
+
// Special styling is needed to fit the button in a block of text without throwing off the line spacing.
|
|
25022
|
+
// While the button is not normally included in a block of text, it needs to be able to accommodate such a case.
|
|
25023
|
+
const buttonStyleOverrides = {
|
|
25024
|
+
height: "22px",
|
|
25025
|
+
marginLeft: "-2px",
|
|
25026
|
+
padding: "0 2px"
|
|
25027
|
+
};
|
|
25028
|
+
const contentStyling = [styles$p.content, this.state.expanded ? styles$p.contentExpanded : styles$p.contentCollapsed, allowTransition && (this.state.expanded ? styles$p.transitionExpanded : styles$p.transitionCollapsed)];
|
|
25029
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.UniqueIDProvider, {
|
|
25030
|
+
mockOnFirstRender: false,
|
|
25031
|
+
scope: "explanation-widget"
|
|
25032
|
+
}, ids => /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
25033
|
+
"aria-expanded": this.state.expanded,
|
|
25034
|
+
"aria-controls": ids.get("content"),
|
|
25035
|
+
endIcon: caretIcon,
|
|
25036
|
+
kind: "tertiary",
|
|
25037
|
+
onClick: this._onClick,
|
|
25038
|
+
size: "large",
|
|
25039
|
+
style: buttonStyleOverrides
|
|
25040
|
+
}, promptText), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
25041
|
+
id: ids.get("content"),
|
|
25042
|
+
style: contentStyling,
|
|
25043
|
+
"aria-hidden": !this.state.expanded,
|
|
25044
|
+
testId: "content-container"
|
|
25045
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
25046
|
+
style: styles$p.contentWrapper
|
|
25055
25047
|
}, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
25056
25048
|
apiOptions: this.props.apiOptions,
|
|
25057
25049
|
content: this.props.explanation,
|
|
25058
25050
|
widgets: this.props.widgets,
|
|
25059
25051
|
linterContext: this.props.linterContext
|
|
25060
|
-
})));
|
|
25052
|
+
})))));
|
|
25061
25053
|
}
|
|
25062
25054
|
getUserInput = () => {
|
|
25063
25055
|
return {};
|
|
@@ -25068,94 +25060,44 @@ class Explanation extends React__namespace.Component {
|
|
|
25068
25060
|
}
|
|
25069
25061
|
const leftBorderSpacing = 23;
|
|
25070
25062
|
const verticalContentPadding = 10;
|
|
25071
|
-
const arrowWidth = 30;
|
|
25072
25063
|
const arrowHeight = 14;
|
|
25073
|
-
const backgroundColor = gray95;
|
|
25074
25064
|
const styles$p = aphrodite.StyleSheet.create({
|
|
25075
|
-
|
|
25076
|
-
|
|
25065
|
+
content: {
|
|
25066
|
+
borderLeft: "0px solid #ccc",
|
|
25067
|
+
display: "inline-grid",
|
|
25077
25068
|
position: "relative"
|
|
25078
25069
|
},
|
|
25079
|
-
|
|
25080
|
-
|
|
25081
|
-
|
|
25082
|
-
|
|
25083
|
-
|
|
25084
|
-
|
|
25085
|
-
|
|
25086
|
-
|
|
25087
|
-
// Copied from .body-text in articles.less
|
|
25088
|
-
fontSize: 20,
|
|
25089
|
-
lineHeight: "30px"
|
|
25090
|
-
},
|
|
25091
|
-
exerciseLink: {
|
|
25092
|
-
// Copied from .legacy-typography in util.less
|
|
25093
|
-
fontSize: 14,
|
|
25094
|
-
lineHeight: "19.6px"
|
|
25095
|
-
},
|
|
25096
|
-
mobileExplanationLink: {
|
|
25097
|
-
color: kaGreen$1,
|
|
25098
|
-
borderBottom: `dashed 1px ${kaGreen$1}`,
|
|
25099
|
-
textDecoration: "none",
|
|
25100
|
-
// TODO(benkomalo): these should be pulled in from common typography
|
|
25101
|
-
// shared files so we have a single place where the type hierarchy is
|
|
25102
|
-
// defined; one off font sizes for individual components should be
|
|
25103
|
-
// avoided.
|
|
25104
|
-
[mediaQueries.xl]: {
|
|
25105
|
-
fontSize: 22,
|
|
25106
|
-
lineHeight: 1.4
|
|
25107
|
-
},
|
|
25108
|
-
[mediaQueries.lgOrSmaller]: {
|
|
25109
|
-
fontSize: 20,
|
|
25110
|
-
lineHeight: 1.5
|
|
25111
|
-
},
|
|
25112
|
-
[mediaQueries.smOrSmaller]: {
|
|
25113
|
-
fontSize: 18,
|
|
25114
|
-
lineHeight: 1.2
|
|
25115
|
-
}
|
|
25116
|
-
},
|
|
25117
|
-
content: {
|
|
25118
|
-
position: "relative",
|
|
25119
|
-
transition: "margin-top 0.1s"
|
|
25070
|
+
contentCollapsed: {
|
|
25071
|
+
gridTemplateColumns: "0fr",
|
|
25072
|
+
gridTemplateRows: "0fr",
|
|
25073
|
+
marginBottom: 0,
|
|
25074
|
+
marginTop: 0,
|
|
25075
|
+
minWidth: "0",
|
|
25076
|
+
paddingBottom: 0,
|
|
25077
|
+
visibility: "hidden"
|
|
25120
25078
|
},
|
|
25121
25079
|
contentExpanded: {
|
|
25122
|
-
|
|
25080
|
+
borderLeftWidth: "5px",
|
|
25081
|
+
gridTemplateColumns: "1fr",
|
|
25082
|
+
gridTemplateRows: "1fr",
|
|
25123
25083
|
marginLeft: -leftBorderSpacing,
|
|
25084
|
+
minWidth: "100%",
|
|
25124
25085
|
paddingLeft: leftBorderSpacing,
|
|
25125
25086
|
paddingBottom: verticalContentPadding,
|
|
25087
|
+
visibility: "visible",
|
|
25126
25088
|
// Note: we still use arrow height as the vertical margin, even on
|
|
25127
25089
|
// desktop when there is no arrow, but it's good enough.
|
|
25128
25090
|
marginBottom: arrowHeight,
|
|
25129
25091
|
marginTop: arrowHeight
|
|
25130
25092
|
},
|
|
25131
|
-
|
|
25132
|
-
|
|
25133
|
-
paddingTop: 32,
|
|
25134
|
-
paddingBottom: 32,
|
|
25135
|
-
marginTop: arrowHeight
|
|
25093
|
+
contentWrapper: {
|
|
25094
|
+
overflow: "hidden"
|
|
25136
25095
|
},
|
|
25137
|
-
|
|
25138
|
-
|
|
25139
|
-
|
|
25140
|
-
|
|
25141
|
-
|
|
25142
|
-
marginLeft: negativePhoneMargin,
|
|
25143
|
-
marginRight: negativePhoneMargin,
|
|
25144
|
-
paddingLeft: phoneMargin,
|
|
25145
|
-
paddingRight: phoneMargin
|
|
25146
|
-
},
|
|
25147
|
-
disclosureArrow: {
|
|
25148
|
-
// HACK - positioning at "bottom: 0", doesn't actually position it to
|
|
25149
|
-
// the real bottom, because the container is `inline-block`, and it
|
|
25150
|
-
// seems to position it to the baseline? We put in a generous
|
|
25151
|
-
// fudge factor to position it down to be flush with the content box
|
|
25152
|
-
// below it.
|
|
25153
|
-
bottom: -(arrowHeight + 5),
|
|
25154
|
-
height: arrowHeight,
|
|
25155
|
-
left: "50%",
|
|
25156
|
-
marginLeft: -(arrowWidth / 2),
|
|
25157
|
-
position: "absolute",
|
|
25158
|
-
width: arrowWidth
|
|
25096
|
+
transitionCollapsed: {
|
|
25097
|
+
transition: "all 0.25s step-end, grid-template-rows 0.25s, margin-top 0.25s, margin-bottom 0.25s, padding-bottom 0.25s"
|
|
25098
|
+
},
|
|
25099
|
+
transitionExpanded: {
|
|
25100
|
+
transition: "grid-template-rows 0.5s, margin-top 0.5s, margin-bottom 0.5s, padding-bottom 0.5s"
|
|
25159
25101
|
}
|
|
25160
25102
|
});
|
|
25161
25103
|
var Explanation$1 = {
|
|
@@ -26482,7 +26424,7 @@ var util = /*#__PURE__*/Object.freeze({
|
|
|
26482
26424
|
});
|
|
26483
26425
|
|
|
26484
26426
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
26485
|
-
const MovablePoint$
|
|
26427
|
+
const MovablePoint$3 = Graphie.MovablePoint;
|
|
26486
26428
|
// @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
|
|
26487
26429
|
const MovableLine$1 = Graphie.MovableLine;
|
|
26488
26430
|
function isFlipped(newCoord, oldCoord, line) {
|
|
@@ -26528,7 +26470,7 @@ class FunctionGrapher extends React__namespace.Component {
|
|
|
26528
26470
|
})();
|
|
26529
26471
|
render() {
|
|
26530
26472
|
const pointForCoord = (coord, i) => {
|
|
26531
|
-
return /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
26473
|
+
return /*#__PURE__*/React__namespace.createElement(MovablePoint$3, {
|
|
26532
26474
|
key: i,
|
|
26533
26475
|
coord: coord,
|
|
26534
26476
|
static: this.props.static,
|
|
@@ -26665,7 +26607,7 @@ class FunctionGrapher extends React__namespace.Component {
|
|
|
26665
26607
|
}],
|
|
26666
26608
|
normalStyle: dashed,
|
|
26667
26609
|
highlightStyle: dashed
|
|
26668
|
-
}, ___default["default"].map(asymptote, (coord, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
26610
|
+
}, ___default["default"].map(asymptote, (coord, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$3, {
|
|
26669
26611
|
key: `asymptoteCoord-${i}`,
|
|
26670
26612
|
coord: coord,
|
|
26671
26613
|
static: true,
|
|
@@ -27428,7 +27370,7 @@ const Label = Graphie.Label;
|
|
|
27428
27370
|
// @ts-expect-error - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
|
|
27429
27371
|
const Line$1 = Graphie.Line;
|
|
27430
27372
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
27431
|
-
const MovablePoint$
|
|
27373
|
+
const MovablePoint$2 = Graphie.MovablePoint;
|
|
27432
27374
|
// @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
|
|
27433
27375
|
const MovableLine = Graphie.MovableLine;
|
|
27434
27376
|
// @ts-expect-error - TS2339 - Property 'Plot' does not exist on type 'typeof Graphie'.
|
|
@@ -27682,7 +27624,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27682
27624
|
return [coordX, coordY];
|
|
27683
27625
|
}];
|
|
27684
27626
|
if (element.options.constraint === "snap") {
|
|
27685
|
-
constraints.push(MovablePoint$
|
|
27627
|
+
constraints.push(MovablePoint$2.constraints.snap(element.options.snap));
|
|
27686
27628
|
} else if (element.options.constraint === "x") {
|
|
27687
27629
|
constraints.push(coord => {
|
|
27688
27630
|
return [
|
|
@@ -27704,7 +27646,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27704
27646
|
// TODO(eater): foo_[xyz] are hacky non-props to
|
|
27705
27647
|
// get the component to update when constraints
|
|
27706
27648
|
// change
|
|
27707
|
-
return /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
27649
|
+
return /*#__PURE__*/React__namespace.createElement(MovablePoint$2, {
|
|
27708
27650
|
key: element.key,
|
|
27709
27651
|
coord: [
|
|
27710
27652
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
@@ -27739,7 +27681,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27739
27681
|
return [coordX, coordY];
|
|
27740
27682
|
}];
|
|
27741
27683
|
if (element.options.constraint === "snap") {
|
|
27742
|
-
constraints.push(MovablePoint$
|
|
27684
|
+
constraints.push(MovablePoint$2.constraints.snap(element.options.snap));
|
|
27743
27685
|
} else if (element.options.constraint === "x") {
|
|
27744
27686
|
constraints.push(coord => {
|
|
27745
27687
|
return [
|
|
@@ -27780,14 +27722,14 @@ class Interaction extends React__namespace.Component {
|
|
|
27780
27722
|
foo_x: element.options.constraint,
|
|
27781
27723
|
foo_y: element.options.constraintFn,
|
|
27782
27724
|
foo_z: element.options.snap
|
|
27783
|
-
}, /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
27725
|
+
}, /*#__PURE__*/React__namespace.createElement(MovablePoint$2, {
|
|
27784
27726
|
coord: start,
|
|
27785
27727
|
static: true,
|
|
27786
27728
|
normalStyle: {
|
|
27787
27729
|
stroke: "none",
|
|
27788
27730
|
fill: "none"
|
|
27789
27731
|
}
|
|
27790
|
-
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
27732
|
+
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$2, {
|
|
27791
27733
|
coord: end,
|
|
27792
27734
|
static: true,
|
|
27793
27735
|
normalStyle: {
|
|
@@ -28238,33 +28180,6 @@ class Graph extends React__namespace.Component {
|
|
|
28238
28180
|
allowScratchpad: true,
|
|
28239
28181
|
setDrawingAreaAvailable: this.props.setDrawingAreaAvailable
|
|
28240
28182
|
});
|
|
28241
|
-
|
|
28242
|
-
// Maybe move this out later
|
|
28243
|
-
if (this.props.lockedFigures) {
|
|
28244
|
-
for (const lockedFigure of this.props.lockedFigures) {
|
|
28245
|
-
switch (lockedFigure.type) {
|
|
28246
|
-
case "point":
|
|
28247
|
-
graphie.circle(
|
|
28248
|
-
// center
|
|
28249
|
-
lockedFigure.coord,
|
|
28250
|
-
// radius
|
|
28251
|
-
0.2,
|
|
28252
|
-
// style
|
|
28253
|
-
lockedFigure.style);
|
|
28254
|
-
break;
|
|
28255
|
-
default:
|
|
28256
|
-
/**
|
|
28257
|
-
* Devlopment-time future-proofing: This `never` should
|
|
28258
|
-
* fail during type-checking if we add a new locked
|
|
28259
|
-
* shape type and forget to handle it in any other
|
|
28260
|
-
* switch case here.
|
|
28261
|
-
*/
|
|
28262
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
28263
|
-
lockedFigure.type;
|
|
28264
|
-
throw new Error(`Unknown locked shape type: ${lockedFigure.type}`);
|
|
28265
|
-
}
|
|
28266
|
-
}
|
|
28267
|
-
}
|
|
28268
28183
|
this._updateProtractor();
|
|
28269
28184
|
this._updateRuler();
|
|
28270
28185
|
|
|
@@ -28357,6 +28272,35 @@ class Graph extends React__namespace.Component {
|
|
|
28357
28272
|
}
|
|
28358
28273
|
}
|
|
28359
28274
|
|
|
28275
|
+
const GraphLockedLayer = props => {
|
|
28276
|
+
const {
|
|
28277
|
+
lockedFigures
|
|
28278
|
+
} = props;
|
|
28279
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, lockedFigures.map((figure, index) => {
|
|
28280
|
+
switch (figure.type) {
|
|
28281
|
+
case "point":
|
|
28282
|
+
const [x, y] = figure.coord;
|
|
28283
|
+
return /*#__PURE__*/React__namespace.createElement(mafs.Point, {
|
|
28284
|
+
key: `${figure.type}-${index}`,
|
|
28285
|
+
x: x,
|
|
28286
|
+
y: y,
|
|
28287
|
+
svgCircleProps: {
|
|
28288
|
+
style: figure.style
|
|
28289
|
+
}
|
|
28290
|
+
});
|
|
28291
|
+
}
|
|
28292
|
+
|
|
28293
|
+
/**
|
|
28294
|
+
* Devlopment-time future-proofing: This `never` should
|
|
28295
|
+
* fail during type-checking if we add a new locked
|
|
28296
|
+
* shape type and forget to handle it in any other
|
|
28297
|
+
* switch case here.
|
|
28298
|
+
*/
|
|
28299
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
28300
|
+
throw new wonderStuffCore.UnreachableCaseError(figure.type);
|
|
28301
|
+
}));
|
|
28302
|
+
};
|
|
28303
|
+
|
|
28360
28304
|
const MOVE_CONTROL_POINT = "move-control-point";
|
|
28361
28305
|
function moveControlPoint(objectIndex, pointIndex, destination) {
|
|
28362
28306
|
return {
|
|
@@ -28375,6 +28319,59 @@ function moveSegment(segmentIndex, delta) {
|
|
|
28375
28319
|
};
|
|
28376
28320
|
}
|
|
28377
28321
|
|
|
28322
|
+
const MovablePoint$1 = props => {
|
|
28323
|
+
const hitboxRef = React.useRef(null);
|
|
28324
|
+
const {
|
|
28325
|
+
point,
|
|
28326
|
+
onMove
|
|
28327
|
+
} = props;
|
|
28328
|
+
const {
|
|
28329
|
+
dragging
|
|
28330
|
+
} = mafs.useMovable({
|
|
28331
|
+
gestureTarget: hitboxRef,
|
|
28332
|
+
point,
|
|
28333
|
+
onMove,
|
|
28334
|
+
constrain: p => p
|
|
28335
|
+
});
|
|
28336
|
+
const {
|
|
28337
|
+
viewTransform,
|
|
28338
|
+
userTransform
|
|
28339
|
+
} = mafs.useTransformContext();
|
|
28340
|
+
const transformToPx = mafs.vec.matrixMult(viewTransform, userTransform);
|
|
28341
|
+
const [x, y] = mafs.vec.transform(point, transformToPx);
|
|
28342
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
28343
|
+
ref: hitboxRef,
|
|
28344
|
+
className: "movable-point",
|
|
28345
|
+
tabIndex: 0,
|
|
28346
|
+
style: {
|
|
28347
|
+
cursor: dragging ? "grabbing" : "grab",
|
|
28348
|
+
touchAction: "none",
|
|
28349
|
+
outline: "none",
|
|
28350
|
+
"--movable-point-color": Color__default["default"].blue
|
|
28351
|
+
}
|
|
28352
|
+
}, /*#__PURE__*/React__namespace.createElement("circle", {
|
|
28353
|
+
className: "movable-point-hitbox",
|
|
28354
|
+
r: 30,
|
|
28355
|
+
cx: x,
|
|
28356
|
+
cy: y
|
|
28357
|
+
}), /*#__PURE__*/React__namespace.createElement("circle", {
|
|
28358
|
+
className: "movable-point-halo",
|
|
28359
|
+
cx: x,
|
|
28360
|
+
cy: y
|
|
28361
|
+
}), /*#__PURE__*/React__namespace.createElement("circle", {
|
|
28362
|
+
className: "movable-point-ring",
|
|
28363
|
+
cx: x,
|
|
28364
|
+
cy: y
|
|
28365
|
+
}), /*#__PURE__*/React__namespace.createElement("circle", {
|
|
28366
|
+
className: "movable-point-center",
|
|
28367
|
+
cx: x,
|
|
28368
|
+
cy: y,
|
|
28369
|
+
style: {
|
|
28370
|
+
fill: Color__default["default"].blue
|
|
28371
|
+
}
|
|
28372
|
+
}));
|
|
28373
|
+
};
|
|
28374
|
+
|
|
28378
28375
|
const SegmentGraph = props => {
|
|
28379
28376
|
const {
|
|
28380
28377
|
dispatch
|
|
@@ -28417,9 +28414,9 @@ const SegmentView = props => {
|
|
|
28417
28414
|
viewTransform,
|
|
28418
28415
|
userTransform
|
|
28419
28416
|
} = mafs.useTransformContext();
|
|
28420
|
-
const
|
|
28421
|
-
const
|
|
28422
|
-
const
|
|
28417
|
+
const transformToPx = mafs.vec.matrixMult(viewTransform, userTransform);
|
|
28418
|
+
const pt1Px = mafs.vec.transform(pt1, transformToPx);
|
|
28419
|
+
const pt2Px = mafs.vec.transform(pt2, transformToPx);
|
|
28423
28420
|
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("g", {
|
|
28424
28421
|
ref: segment,
|
|
28425
28422
|
tabIndex: 0,
|
|
@@ -28428,28 +28425,26 @@ const SegmentView = props => {
|
|
|
28428
28425
|
cursor: isDraggingSegment ? "grabbing" : "grab"
|
|
28429
28426
|
}
|
|
28430
28427
|
}, /*#__PURE__*/React__namespace.createElement(SVGLine, {
|
|
28431
|
-
start:
|
|
28432
|
-
end:
|
|
28428
|
+
start: pt1Px,
|
|
28429
|
+
end: pt2Px,
|
|
28433
28430
|
style: {
|
|
28434
28431
|
stroke: "transparent",
|
|
28435
28432
|
strokeWidth: 30
|
|
28436
28433
|
}
|
|
28437
28434
|
}), /*#__PURE__*/React__namespace.createElement(SVGLine, {
|
|
28438
|
-
start:
|
|
28439
|
-
end:
|
|
28435
|
+
start: pt1Px,
|
|
28436
|
+
end: pt2Px,
|
|
28440
28437
|
style: {
|
|
28441
28438
|
stroke: "var(--mafs-segment-stroke-color)",
|
|
28442
28439
|
strokeWidth: "var(--mafs-segment-stroke-weight)"
|
|
28443
28440
|
}
|
|
28444
|
-
})), /*#__PURE__*/React__namespace.createElement(
|
|
28441
|
+
})), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
28445
28442
|
point: pt1,
|
|
28446
|
-
color: Color__default["default"].blue,
|
|
28447
28443
|
onMove: newPoint => {
|
|
28448
28444
|
props.onMovePoint(0, newPoint);
|
|
28449
28445
|
}
|
|
28450
|
-
}), /*#__PURE__*/React__namespace.createElement(
|
|
28446
|
+
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
28451
28447
|
point: pt2,
|
|
28452
|
-
color: Color__default["default"].blue,
|
|
28453
28448
|
onMove: newPoint => {
|
|
28454
28449
|
props.onMovePoint(1, newPoint);
|
|
28455
28450
|
}
|
|
@@ -29389,7 +29384,9 @@ const MafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref) => {
|
|
|
29389
29384
|
zoom: false,
|
|
29390
29385
|
width: width,
|
|
29391
29386
|
height: height
|
|
29392
|
-
}, !legacyGrid && /*#__PURE__*/React__namespace.createElement(Grid, props),
|
|
29387
|
+
}, !legacyGrid && /*#__PURE__*/React__namespace.createElement(Grid, props), props.lockedFigures && /*#__PURE__*/React__namespace.createElement(GraphLockedLayer, {
|
|
29388
|
+
lockedFigures: props.lockedFigures
|
|
29389
|
+
}), renderGraph({
|
|
29393
29390
|
state,
|
|
29394
29391
|
dispatch
|
|
29395
29392
|
}))));
|
|
@@ -29568,7 +29565,7 @@ class InteractiveGraph extends React__namespace.Component {
|
|
|
29568
29565
|
this.sinusoid = null;
|
|
29569
29566
|
// eslint-disable-next-line react/no-string-refs
|
|
29570
29567
|
// @ts-expect-error - TS2339 - Property 'reset' does not exist on type 'ReactInstance'.
|
|
29571
|
-
this.refs.graph
|
|
29568
|
+
this.refs.graph?.reset();
|
|
29572
29569
|
};
|
|
29573
29570
|
setupGraphie = () => {
|
|
29574
29571
|
this.setTrashCanVisibility(0);
|
|
@@ -30644,8 +30641,7 @@ class InteractiveGraph extends React__namespace.Component {
|
|
|
30644
30641
|
onMouseDown: onMouseDown,
|
|
30645
30642
|
onGraphieUpdated: this.setGraphie,
|
|
30646
30643
|
setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable,
|
|
30647
|
-
isMobile: isMobile
|
|
30648
|
-
lockedFigures: this.props.lockedFigures
|
|
30644
|
+
isMobile: isMobile
|
|
30649
30645
|
}));
|
|
30650
30646
|
}
|
|
30651
30647
|
static getQuadraticCoefficients(coords) {
|
|
@@ -41367,7 +41363,7 @@ const init = function (options) {
|
|
|
41367
41363
|
|
|
41368
41364
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
41369
41365
|
const libName = "@khanacademy/perseus";
|
|
41370
|
-
const libVersion = "20.
|
|
41366
|
+
const libVersion = "20.3.0";
|
|
41371
41367
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
41372
41368
|
|
|
41373
41369
|
const apiVersion = {
|