@khanacademy/perseus 20.3.1 → 20.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/index.css +9 -10
- package/dist/es/index.js +355 -144
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +9 -10
- package/dist/index.js +341 -135
- package/dist/index.js.map +1 -1
- package/dist/perseus-types.d.ts +9 -7
- package/dist/widgets/interactive-graphs/graphs/components/movable-line.d.ts +14 -0
- package/dist/widgets/interactive-graphs/{movable-point.d.ts → graphs/components/movable-point.d.ts} +2 -1
- package/dist/widgets/interactive-graphs/graphs/index.d.ts +1 -0
- package/dist/widgets/interactive-graphs/graphs/linear.d.ts +5 -0
- package/dist/widgets/interactive-graphs/graphs/segment.d.ts +1 -2
- package/dist/widgets/interactive-graphs/graphs/types.d.ts +9 -0
- package/dist/widgets/interactive-graphs/interactive-graph-action.d.ts +4 -4
- package/dist/widgets/interactive-graphs/interactive-graph-reducer.d.ts +2 -2
- package/dist/widgets/interactive-graphs/interactive-graph-state.d.ts +2 -11
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +3 -3
- package/dist/widgets/interactive-graphs/types.d.ts +12 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14406,7 +14406,7 @@ const DEFAULT_STATE$2 = {
|
|
|
14406
14406
|
visibleShape: null,
|
|
14407
14407
|
mouseTarget: null
|
|
14408
14408
|
};
|
|
14409
|
-
const MovableLine$
|
|
14409
|
+
const MovableLine$4 = function (graphie, movable, options) {
|
|
14410
14410
|
assert$6(graphie != null);
|
|
14411
14411
|
assert$6(options != null);
|
|
14412
14412
|
|
|
@@ -14424,10 +14424,10 @@ const MovableLine$3 = function (graphie, movable, options) {
|
|
|
14424
14424
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
14425
14425
|
this.modify(___default["default"].extend({}, DEFAULT_STATE$2, options));
|
|
14426
14426
|
};
|
|
14427
|
-
___default["default"].extend(MovableLine$
|
|
14428
|
-
InteractiveUtil.createGettersFor(MovableLine$
|
|
14429
|
-
InteractiveUtil.addMovableHelperMethodsTo(MovableLine$
|
|
14430
|
-
___default["default"].extend(MovableLine$
|
|
14427
|
+
___default["default"].extend(MovableLine$4, MovableLineOptions);
|
|
14428
|
+
InteractiveUtil.createGettersFor(MovableLine$4, ___default["default"].extend({}, DEFAULT_PROPS$2, DEFAULT_STATE$2));
|
|
14429
|
+
InteractiveUtil.addMovableHelperMethodsTo(MovableLine$4);
|
|
14430
|
+
___default["default"].extend(MovableLine$4.prototype, {
|
|
14431
14431
|
cloneState: function () {
|
|
14432
14432
|
return ___default["default"].extend(this.movable.cloneState(), {
|
|
14433
14433
|
coords: this.coords()
|
|
@@ -15008,7 +15008,7 @@ const DEFAULT_STATE$1 = {
|
|
|
15008
15008
|
// TODO(benchristel): this is a memory leak. We add items to
|
|
15009
15009
|
// tooltipResetFunctions, but never remove them.
|
|
15010
15010
|
const tooltipResetFunctions = [];
|
|
15011
|
-
class MovablePoint$
|
|
15011
|
+
class MovablePoint$4 {
|
|
15012
15012
|
// @ts-expect-error - TS2564: Property 'prevState' has no initializer and is not definitely assigned in the constructor.
|
|
15013
15013
|
|
|
15014
15014
|
_listenerMap = {};
|
|
@@ -16136,15 +16136,15 @@ ___default["default"].extend(MovablePolygon.prototype, {
|
|
|
16136
16136
|
});
|
|
16137
16137
|
|
|
16138
16138
|
const Interactive2 = {
|
|
16139
|
-
MovablePoint: MovablePoint$
|
|
16139
|
+
MovablePoint: MovablePoint$4,
|
|
16140
16140
|
addMovablePoint: function (graphie, options) {
|
|
16141
16141
|
const movable = new Movable(graphie, {});
|
|
16142
|
-
return new MovablePoint$
|
|
16142
|
+
return new MovablePoint$4(graphie, movable, options);
|
|
16143
16143
|
},
|
|
16144
|
-
MovableLine: MovableLine$
|
|
16144
|
+
MovableLine: MovableLine$4,
|
|
16145
16145
|
addMovableLine: function (graphie, options) {
|
|
16146
16146
|
const movable = new Movable(graphie, {});
|
|
16147
|
-
return new MovableLine$
|
|
16147
|
+
return new MovableLine$4(graphie, movable, options);
|
|
16148
16148
|
},
|
|
16149
16149
|
MovablePolygon: MovablePolygon,
|
|
16150
16150
|
addMovablePolygon: function (graphie, options) {
|
|
@@ -16181,7 +16181,7 @@ const Interactive2 = {
|
|
|
16181
16181
|
}
|
|
16182
16182
|
};
|
|
16183
16183
|
|
|
16184
|
-
const MovablePoint$
|
|
16184
|
+
const MovablePoint$3 = GraphieClasses.createClass({
|
|
16185
16185
|
displayName: "MovablePoint",
|
|
16186
16186
|
movableProps: ["children"],
|
|
16187
16187
|
_getProps: function () {
|
|
@@ -16239,8 +16239,8 @@ const MovablePoint$4 = GraphieClasses.createClass({
|
|
|
16239
16239
|
});
|
|
16240
16240
|
|
|
16241
16241
|
// Include helper methods, such as MovablePoint.constrain.snap()
|
|
16242
|
-
___default["default"].extend(MovablePoint$
|
|
16243
|
-
const MovableLine$
|
|
16242
|
+
___default["default"].extend(MovablePoint$3, Interactive2.MovablePoint);
|
|
16243
|
+
const MovableLine$3 = GraphieClasses.createClass({
|
|
16244
16244
|
displayName: "MovableLine",
|
|
16245
16245
|
movableProps: ["children"],
|
|
16246
16246
|
add: function (graphie) {
|
|
@@ -16268,7 +16268,7 @@ const MovableLine$2 = GraphieClasses.createClass({
|
|
|
16268
16268
|
});
|
|
16269
16269
|
|
|
16270
16270
|
// Include helper methods, such as MovableLine.constrain.snap()
|
|
16271
|
-
___default["default"].extend(MovableLine$
|
|
16271
|
+
___default["default"].extend(MovableLine$3, Interactive2.MovableLine);
|
|
16272
16272
|
const Label$1 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
16273
16273
|
let coord = props.coord;
|
|
16274
16274
|
if (props.unscaled) {
|
|
@@ -16408,8 +16408,8 @@ var Movables = {
|
|
|
16408
16408
|
Circle: Circle,
|
|
16409
16409
|
Label: Label$1,
|
|
16410
16410
|
Line: Line$2,
|
|
16411
|
-
MovableLine: MovableLine$
|
|
16412
|
-
MovablePoint: MovablePoint$
|
|
16411
|
+
MovableLine: MovableLine$3,
|
|
16412
|
+
MovablePoint: MovablePoint$3,
|
|
16413
16413
|
Parabola: Parabola,
|
|
16414
16414
|
Path: Path,
|
|
16415
16415
|
Plot: Plot$2,
|
|
@@ -24979,6 +24979,12 @@ var Dropdown$1 = {
|
|
|
24979
24979
|
|
|
24980
24980
|
// transform = _.identity
|
|
24981
24981
|
|
|
24982
|
+
function mediaQueryIsMatched(mediaQuery) {
|
|
24983
|
+
if (typeof window.matchMedia !== "function") {
|
|
24984
|
+
return false;
|
|
24985
|
+
}
|
|
24986
|
+
return window.matchMedia(mediaQuery).matches;
|
|
24987
|
+
}
|
|
24982
24988
|
class Explanation extends React__namespace.Component {
|
|
24983
24989
|
static defaultProps = {
|
|
24984
24990
|
showPrompt: "Explain",
|
|
@@ -25016,7 +25022,7 @@ class Explanation extends React__namespace.Component {
|
|
|
25016
25022
|
render() {
|
|
25017
25023
|
const promptText = this.state.expanded ? this.props.hidePrompt : this.props.showPrompt;
|
|
25018
25024
|
const caretIcon = this.state.expanded ? caretUp__default["default"] : caretDown__default["default"];
|
|
25019
|
-
const allowTransition =
|
|
25025
|
+
const allowTransition = mediaQueryIsMatched("(prefers-reduced-motion: no-preference)");
|
|
25020
25026
|
|
|
25021
25027
|
// Special styling is needed to fit the button in a block of text without throwing off the line spacing.
|
|
25022
25028
|
// While the button is not normally included in a block of text, it needs to be able to accommodate such a case.
|
|
@@ -25027,7 +25033,7 @@ class Explanation extends React__namespace.Component {
|
|
|
25027
25033
|
};
|
|
25028
25034
|
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
25035
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.UniqueIDProvider, {
|
|
25030
|
-
mockOnFirstRender:
|
|
25036
|
+
mockOnFirstRender: true,
|
|
25031
25037
|
scope: "explanation-widget"
|
|
25032
25038
|
}, ids => /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
25033
25039
|
"aria-expanded": this.state.expanded,
|
|
@@ -26424,9 +26430,9 @@ var util = /*#__PURE__*/Object.freeze({
|
|
|
26424
26430
|
});
|
|
26425
26431
|
|
|
26426
26432
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
26427
|
-
const MovablePoint$
|
|
26433
|
+
const MovablePoint$2 = Graphie.MovablePoint;
|
|
26428
26434
|
// @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
|
|
26429
|
-
const MovableLine$
|
|
26435
|
+
const MovableLine$2 = Graphie.MovableLine;
|
|
26430
26436
|
function isFlipped(newCoord, oldCoord, line) {
|
|
26431
26437
|
const CCW = (a, b, c) => {
|
|
26432
26438
|
return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]);
|
|
@@ -26470,7 +26476,7 @@ class FunctionGrapher extends React__namespace.Component {
|
|
|
26470
26476
|
})();
|
|
26471
26477
|
render() {
|
|
26472
26478
|
const pointForCoord = (coord, i) => {
|
|
26473
|
-
return /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
26479
|
+
return /*#__PURE__*/React__namespace.createElement(MovablePoint$2, {
|
|
26474
26480
|
key: i,
|
|
26475
26481
|
coord: coord,
|
|
26476
26482
|
static: this.props.static,
|
|
@@ -26582,7 +26588,7 @@ class FunctionGrapher extends React__namespace.Component {
|
|
|
26582
26588
|
const dashed = {
|
|
26583
26589
|
strokeDasharray: "- "
|
|
26584
26590
|
};
|
|
26585
|
-
return asymptote && /*#__PURE__*/React__namespace.createElement(MovableLine$
|
|
26591
|
+
return asymptote && /*#__PURE__*/React__namespace.createElement(MovableLine$2, {
|
|
26586
26592
|
onMove: (newCoord, oldCoord) => {
|
|
26587
26593
|
// Calculate and apply displacement
|
|
26588
26594
|
const delta = kmath.vector.subtract(newCoord, oldCoord);
|
|
@@ -26607,7 +26613,7 @@ class FunctionGrapher extends React__namespace.Component {
|
|
|
26607
26613
|
}],
|
|
26608
26614
|
normalStyle: dashed,
|
|
26609
26615
|
highlightStyle: dashed
|
|
26610
|
-
}, ___default["default"].map(asymptote, (coord, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
26616
|
+
}, ___default["default"].map(asymptote, (coord, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$2, {
|
|
26611
26617
|
key: `asymptoteCoord-${i}`,
|
|
26612
26618
|
coord: coord,
|
|
26613
26619
|
static: true,
|
|
@@ -27370,9 +27376,9 @@ const Label = Graphie.Label;
|
|
|
27370
27376
|
// @ts-expect-error - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
|
|
27371
27377
|
const Line$1 = Graphie.Line;
|
|
27372
27378
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
27373
|
-
const MovablePoint$
|
|
27379
|
+
const MovablePoint$1 = Graphie.MovablePoint;
|
|
27374
27380
|
// @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
|
|
27375
|
-
const MovableLine = Graphie.MovableLine;
|
|
27381
|
+
const MovableLine$1 = Graphie.MovableLine;
|
|
27376
27382
|
// @ts-expect-error - TS2339 - Property 'Plot' does not exist on type 'typeof Graphie'.
|
|
27377
27383
|
const Plot = Graphie.Plot;
|
|
27378
27384
|
// @ts-expect-error - TS2339 - Property 'PlotParametric' does not exist on type 'typeof Graphie'.
|
|
@@ -27624,7 +27630,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27624
27630
|
return [coordX, coordY];
|
|
27625
27631
|
}];
|
|
27626
27632
|
if (element.options.constraint === "snap") {
|
|
27627
|
-
constraints.push(MovablePoint$
|
|
27633
|
+
constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
|
|
27628
27634
|
} else if (element.options.constraint === "x") {
|
|
27629
27635
|
constraints.push(coord => {
|
|
27630
27636
|
return [
|
|
@@ -27646,7 +27652,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27646
27652
|
// TODO(eater): foo_[xyz] are hacky non-props to
|
|
27647
27653
|
// get the component to update when constraints
|
|
27648
27654
|
// change
|
|
27649
|
-
return /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
27655
|
+
return /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
27650
27656
|
key: element.key,
|
|
27651
27657
|
coord: [
|
|
27652
27658
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
@@ -27681,7 +27687,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27681
27687
|
return [coordX, coordY];
|
|
27682
27688
|
}];
|
|
27683
27689
|
if (element.options.constraint === "snap") {
|
|
27684
|
-
constraints.push(MovablePoint$
|
|
27690
|
+
constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
|
|
27685
27691
|
} else if (element.options.constraint === "x") {
|
|
27686
27692
|
constraints.push(coord => {
|
|
27687
27693
|
return [
|
|
@@ -27709,7 +27715,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27709
27715
|
this.state.variables["x_" + element.options.endSubscript],
|
|
27710
27716
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
27711
27717
|
this.state.variables["y_" + element.options.endSubscript]];
|
|
27712
|
-
return /*#__PURE__*/React__namespace.createElement(MovableLine, {
|
|
27718
|
+
return /*#__PURE__*/React__namespace.createElement(MovableLine$1, {
|
|
27713
27719
|
key: element.key,
|
|
27714
27720
|
constraints: constraints
|
|
27715
27721
|
// eslint-disable-next-line react/jsx-no-bind
|
|
@@ -27722,14 +27728,14 @@ class Interaction extends React__namespace.Component {
|
|
|
27722
27728
|
foo_x: element.options.constraint,
|
|
27723
27729
|
foo_y: element.options.constraintFn,
|
|
27724
27730
|
foo_z: element.options.snap
|
|
27725
|
-
}, /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
27731
|
+
}, /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
27726
27732
|
coord: start,
|
|
27727
27733
|
static: true,
|
|
27728
27734
|
normalStyle: {
|
|
27729
27735
|
stroke: "none",
|
|
27730
27736
|
fill: "none"
|
|
27731
27737
|
}
|
|
27732
|
-
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
27738
|
+
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
27733
27739
|
coord: end,
|
|
27734
27740
|
static: true,
|
|
27735
27741
|
normalStyle: {
|
|
@@ -28310,20 +28316,142 @@ function moveControlPoint(objectIndex, pointIndex, destination) {
|
|
|
28310
28316
|
destination
|
|
28311
28317
|
};
|
|
28312
28318
|
}
|
|
28313
|
-
const
|
|
28314
|
-
function moveSegment(
|
|
28319
|
+
const MOVE_LINE = "move-line";
|
|
28320
|
+
function moveSegment(lineIndex, delta) {
|
|
28315
28321
|
return {
|
|
28316
|
-
type:
|
|
28317
|
-
|
|
28322
|
+
type: MOVE_LINE,
|
|
28323
|
+
lineIndex,
|
|
28318
28324
|
delta
|
|
28319
28325
|
};
|
|
28320
28326
|
}
|
|
28321
28327
|
|
|
28322
|
-
const
|
|
28328
|
+
const defaultStroke = "var(--movable-line-stroke-color)";
|
|
28329
|
+
const MovableLine = props => {
|
|
28330
|
+
const {
|
|
28331
|
+
start,
|
|
28332
|
+
end,
|
|
28333
|
+
onMove,
|
|
28334
|
+
extend,
|
|
28335
|
+
stroke = defaultStroke
|
|
28336
|
+
} = props;
|
|
28337
|
+
const midpoint = mafs.vec.midpoint(start, end);
|
|
28338
|
+
const {
|
|
28339
|
+
viewTransform,
|
|
28340
|
+
userTransform
|
|
28341
|
+
} = mafs.useTransformContext();
|
|
28342
|
+
const transformToPx = mafs.vec.matrixMult(viewTransform, userTransform);
|
|
28343
|
+
const startPtPx = mafs.vec.transform(start, transformToPx);
|
|
28344
|
+
const endPtPx = mafs.vec.transform(end, transformToPx);
|
|
28345
|
+
let startExtend = undefined;
|
|
28346
|
+
let endExtend = undefined;
|
|
28347
|
+
if (extend) {
|
|
28348
|
+
startExtend = extend.start ? getExtensionCoords(end, start, extend.range) : undefined;
|
|
28349
|
+
endExtend = extend.end ? getExtensionCoords(start, end, extend.range) : undefined;
|
|
28350
|
+
}
|
|
28351
|
+
const line = React.useRef(null);
|
|
28352
|
+
const {
|
|
28353
|
+
dragging
|
|
28354
|
+
} = mafs.useMovable({
|
|
28355
|
+
gestureTarget: line,
|
|
28356
|
+
point: midpoint,
|
|
28357
|
+
onMove: newPoint => {
|
|
28358
|
+
onMove(mafs.vec.sub(newPoint, midpoint));
|
|
28359
|
+
},
|
|
28360
|
+
constrain: p => p
|
|
28361
|
+
});
|
|
28362
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("g", {
|
|
28363
|
+
ref: line,
|
|
28364
|
+
tabIndex: 0,
|
|
28365
|
+
className: "movable-line",
|
|
28366
|
+
style: {
|
|
28367
|
+
cursor: dragging ? "grabbing" : "grab"
|
|
28368
|
+
}
|
|
28369
|
+
}, /*#__PURE__*/React__namespace.createElement(SVGLine, {
|
|
28370
|
+
start: startPtPx,
|
|
28371
|
+
end: endPtPx,
|
|
28372
|
+
style: {
|
|
28373
|
+
stroke: "transparent",
|
|
28374
|
+
strokeWidth: 44
|
|
28375
|
+
}
|
|
28376
|
+
}), /*#__PURE__*/React__namespace.createElement(SVGLine, {
|
|
28377
|
+
start: startPtPx,
|
|
28378
|
+
end: endPtPx,
|
|
28379
|
+
style: {
|
|
28380
|
+
stroke,
|
|
28381
|
+
strokeWidth: "var(--movable-line-stroke-weight)"
|
|
28382
|
+
},
|
|
28383
|
+
dragging: dragging
|
|
28384
|
+
})), startExtend && /*#__PURE__*/React__namespace.createElement(mafs.Vector, {
|
|
28385
|
+
tail: start,
|
|
28386
|
+
tip: startExtend,
|
|
28387
|
+
color: stroke
|
|
28388
|
+
}), endExtend && /*#__PURE__*/React__namespace.createElement(mafs.Vector, {
|
|
28389
|
+
tail: end,
|
|
28390
|
+
tip: endExtend,
|
|
28391
|
+
color: stroke
|
|
28392
|
+
}));
|
|
28393
|
+
};
|
|
28394
|
+
function SVGLine(props) {
|
|
28395
|
+
const {
|
|
28396
|
+
start,
|
|
28397
|
+
end,
|
|
28398
|
+
style,
|
|
28399
|
+
dragging
|
|
28400
|
+
} = props;
|
|
28401
|
+
return /*#__PURE__*/React__namespace.createElement("line", {
|
|
28402
|
+
x1: start[0],
|
|
28403
|
+
y1: start[1],
|
|
28404
|
+
x2: end[0],
|
|
28405
|
+
y2: end[1],
|
|
28406
|
+
style: style,
|
|
28407
|
+
className: dragging ? "movable-line-dragging" : undefined
|
|
28408
|
+
});
|
|
28409
|
+
}
|
|
28410
|
+
|
|
28411
|
+
/**
|
|
28412
|
+
* Given two points, find the tips that extends through the points to the edge of the range.
|
|
28413
|
+
* @param collinearPoint - The point that the line passes through. Needed to establish slope.
|
|
28414
|
+
* @param extendFrom - The point that the line extends from to the edge of the graph.
|
|
28415
|
+
*/
|
|
28416
|
+
const getExtensionCoords = (collinearPoint, extendFrom, range) => {
|
|
28417
|
+
// edges of the graph
|
|
28418
|
+
const [[xMin, xMax], [yMin, yMax]] = range;
|
|
28419
|
+
const [aX, aY] = collinearPoint;
|
|
28420
|
+
const [bX, bY] = extendFrom;
|
|
28421
|
+
const yDiff = bY - aY;
|
|
28422
|
+
const xDiff = bX - aX;
|
|
28423
|
+
const slope = yDiff / xDiff;
|
|
28424
|
+
const yAtXMin = slope * (xMin - aX) + aY;
|
|
28425
|
+
const yAtXMax = slope * (xMax - aX) + aY;
|
|
28426
|
+
const xAtYMin = (yMin - aY) / slope + aX;
|
|
28427
|
+
const xAtYMax = (yMax - aY) / slope + aX;
|
|
28428
|
+
|
|
28429
|
+
// clock analogy to describe quadrants
|
|
28430
|
+
switch (true) {
|
|
28431
|
+
// 12 o'clock to 2:59
|
|
28432
|
+
case yDiff > 0 && xDiff >= 0:
|
|
28433
|
+
return xAtYMax > xMax ? [xMax, yAtXMax] : [xAtYMax, yMax];
|
|
28434
|
+
// 3 o'clock to 5:59
|
|
28435
|
+
case yDiff <= 0 && xDiff > 0:
|
|
28436
|
+
// xAtYMin evaluates to -Infinity here, so we use absolute value
|
|
28437
|
+
return Math.abs(xAtYMin) > xMax ? [xMax, yAtXMax] : [xAtYMin, yMin];
|
|
28438
|
+
// 9 o'clock to 11:59
|
|
28439
|
+
case yDiff >= 0 && xDiff < 0:
|
|
28440
|
+
return xAtYMax < xMin ? [xMin, yAtXMin] : [xAtYMax, yMax];
|
|
28441
|
+
// 6 o'clock to 8:59
|
|
28442
|
+
case yDiff < 0 && xDiff <= 0:
|
|
28443
|
+
return xAtYMin < xMin ? [xMin, yAtXMin] : [xAtYMin, yMin];
|
|
28444
|
+
default:
|
|
28445
|
+
return [xMax, yAtXMax];
|
|
28446
|
+
}
|
|
28447
|
+
};
|
|
28448
|
+
|
|
28449
|
+
const StyledMovablePoint = props => {
|
|
28323
28450
|
const hitboxRef = React.useRef(null);
|
|
28324
28451
|
const {
|
|
28325
28452
|
point,
|
|
28326
|
-
onMove
|
|
28453
|
+
onMove,
|
|
28454
|
+
color = Color__default["default"].blue
|
|
28327
28455
|
} = props;
|
|
28328
28456
|
const {
|
|
28329
28457
|
dragging
|
|
@@ -28347,11 +28475,11 @@ const MovablePoint$1 = props => {
|
|
|
28347
28475
|
cursor: dragging ? "grabbing" : "grab",
|
|
28348
28476
|
touchAction: "none",
|
|
28349
28477
|
outline: "none",
|
|
28350
|
-
"--movable-point-color":
|
|
28478
|
+
"--movable-point-color": color
|
|
28351
28479
|
}
|
|
28352
28480
|
}, /*#__PURE__*/React__namespace.createElement("circle", {
|
|
28353
28481
|
className: "movable-point-hitbox",
|
|
28354
|
-
r:
|
|
28482
|
+
r: 22,
|
|
28355
28483
|
cx: x,
|
|
28356
28484
|
cy: y
|
|
28357
28485
|
}), /*#__PURE__*/React__namespace.createElement("circle", {
|
|
@@ -28367,7 +28495,7 @@ const MovablePoint$1 = props => {
|
|
|
28367
28495
|
cx: x,
|
|
28368
28496
|
cy: y,
|
|
28369
28497
|
style: {
|
|
28370
|
-
fill:
|
|
28498
|
+
fill: color
|
|
28371
28499
|
}
|
|
28372
28500
|
}));
|
|
28373
28501
|
};
|
|
@@ -28377,16 +28505,16 @@ const SegmentGraph = props => {
|
|
|
28377
28505
|
dispatch
|
|
28378
28506
|
} = props;
|
|
28379
28507
|
const {
|
|
28380
|
-
segments,
|
|
28508
|
+
coords: segments,
|
|
28381
28509
|
snapStep,
|
|
28382
28510
|
range
|
|
28383
28511
|
} = props.graphState;
|
|
28384
|
-
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, segments
|
|
28512
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, segments?.map((segment, i) => /*#__PURE__*/React__namespace.createElement(SegmentView, {
|
|
28385
28513
|
key: i,
|
|
28386
|
-
|
|
28514
|
+
collinearPair: segment,
|
|
28387
28515
|
snaps: snapStep,
|
|
28388
28516
|
range: range,
|
|
28389
|
-
|
|
28517
|
+
onMoveLine: delta => {
|
|
28390
28518
|
dispatch(moveSegment(i, delta));
|
|
28391
28519
|
},
|
|
28392
28520
|
onMovePoint: (endpointIndex, destination) => dispatch(moveControlPoint(i, endpointIndex, destination)),
|
|
@@ -28395,75 +28523,83 @@ const SegmentGraph = props => {
|
|
|
28395
28523
|
};
|
|
28396
28524
|
const SegmentView = props => {
|
|
28397
28525
|
const {
|
|
28398
|
-
onMoveSegment,
|
|
28399
|
-
|
|
28526
|
+
onMoveLine: onMoveSegment,
|
|
28527
|
+
collinearPair: [start, end]
|
|
28400
28528
|
} = props;
|
|
28401
|
-
|
|
28402
|
-
|
|
28403
|
-
|
|
28404
|
-
|
|
28405
|
-
}
|
|
28406
|
-
|
|
28407
|
-
point: midpoint,
|
|
28408
|
-
onMove: newPoint => {
|
|
28409
|
-
onMoveSegment(mafs.vec.sub(newPoint, midpoint));
|
|
28410
|
-
},
|
|
28411
|
-
constrain: p => p
|
|
28412
|
-
});
|
|
28413
|
-
const {
|
|
28414
|
-
viewTransform,
|
|
28415
|
-
userTransform
|
|
28416
|
-
} = mafs.useTransformContext();
|
|
28417
|
-
const transformToPx = mafs.vec.matrixMult(viewTransform, userTransform);
|
|
28418
|
-
const pt1Px = mafs.vec.transform(pt1, transformToPx);
|
|
28419
|
-
const pt2Px = mafs.vec.transform(pt2, transformToPx);
|
|
28420
|
-
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("g", {
|
|
28421
|
-
ref: segment,
|
|
28422
|
-
tabIndex: 0,
|
|
28423
|
-
className: "movable-segment",
|
|
28424
|
-
style: {
|
|
28425
|
-
cursor: isDraggingSegment ? "grabbing" : "grab"
|
|
28426
|
-
}
|
|
28427
|
-
}, /*#__PURE__*/React__namespace.createElement(SVGLine, {
|
|
28428
|
-
start: pt1Px,
|
|
28429
|
-
end: pt2Px,
|
|
28430
|
-
style: {
|
|
28431
|
-
stroke: "transparent",
|
|
28432
|
-
strokeWidth: 30
|
|
28433
|
-
}
|
|
28434
|
-
}), /*#__PURE__*/React__namespace.createElement(SVGLine, {
|
|
28435
|
-
start: pt1Px,
|
|
28436
|
-
end: pt2Px,
|
|
28437
|
-
style: {
|
|
28438
|
-
stroke: "var(--mafs-segment-stroke-color)",
|
|
28439
|
-
strokeWidth: "var(--mafs-segment-stroke-weight)"
|
|
28440
|
-
}
|
|
28441
|
-
})), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
28442
|
-
point: pt1,
|
|
28529
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(MovableLine, {
|
|
28530
|
+
start: start,
|
|
28531
|
+
end: end,
|
|
28532
|
+
onMove: onMoveSegment
|
|
28533
|
+
}), /*#__PURE__*/React__namespace.createElement(StyledMovablePoint, {
|
|
28534
|
+
point: start,
|
|
28443
28535
|
onMove: newPoint => {
|
|
28444
28536
|
props.onMovePoint(0, newPoint);
|
|
28445
28537
|
}
|
|
28446
|
-
}), /*#__PURE__*/React__namespace.createElement(
|
|
28447
|
-
point:
|
|
28538
|
+
}), /*#__PURE__*/React__namespace.createElement(StyledMovablePoint, {
|
|
28539
|
+
point: end,
|
|
28448
28540
|
onMove: newPoint => {
|
|
28449
28541
|
props.onMovePoint(1, newPoint);
|
|
28450
28542
|
}
|
|
28451
28543
|
}));
|
|
28452
28544
|
};
|
|
28453
|
-
|
|
28545
|
+
|
|
28546
|
+
const LinearGraph = props => {
|
|
28454
28547
|
const {
|
|
28455
|
-
|
|
28456
|
-
end,
|
|
28457
|
-
style
|
|
28548
|
+
dispatch
|
|
28458
28549
|
} = props;
|
|
28459
|
-
|
|
28460
|
-
|
|
28461
|
-
|
|
28462
|
-
|
|
28463
|
-
|
|
28464
|
-
|
|
28465
|
-
|
|
28466
|
-
|
|
28550
|
+
const {
|
|
28551
|
+
coords: lines,
|
|
28552
|
+
snapStep,
|
|
28553
|
+
range,
|
|
28554
|
+
type
|
|
28555
|
+
} = props.graphState;
|
|
28556
|
+
const colors = ["var(--movable-line-stroke-color)", "var(--mafs-violet)"];
|
|
28557
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, lines?.map((line, i) => /*#__PURE__*/React__namespace.createElement(LineView, {
|
|
28558
|
+
key: i,
|
|
28559
|
+
collinearPair: line,
|
|
28560
|
+
snaps: snapStep,
|
|
28561
|
+
range: range,
|
|
28562
|
+
onMoveLine: delta => {
|
|
28563
|
+
dispatch(moveSegment(i, delta));
|
|
28564
|
+
},
|
|
28565
|
+
onMovePoint: (endpointIndex, destination) => dispatch(moveControlPoint(i, endpointIndex, destination))
|
|
28566
|
+
// "linear" or "linear-system" + index
|
|
28567
|
+
,
|
|
28568
|
+
"data-testid": type + i,
|
|
28569
|
+
stroke: colors[i]
|
|
28570
|
+
})));
|
|
28571
|
+
};
|
|
28572
|
+
const LineView = props => {
|
|
28573
|
+
const {
|
|
28574
|
+
onMoveLine: onMoveSegment,
|
|
28575
|
+
collinearPair: [start, end],
|
|
28576
|
+
range,
|
|
28577
|
+
stroke
|
|
28578
|
+
} = props;
|
|
28579
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(MovableLine, {
|
|
28580
|
+
start: start,
|
|
28581
|
+
end: end,
|
|
28582
|
+
onMove: onMoveSegment,
|
|
28583
|
+
extend: {
|
|
28584
|
+
start: true,
|
|
28585
|
+
end: true,
|
|
28586
|
+
range
|
|
28587
|
+
},
|
|
28588
|
+
stroke: stroke
|
|
28589
|
+
}), /*#__PURE__*/React__namespace.createElement(StyledMovablePoint, {
|
|
28590
|
+
point: start,
|
|
28591
|
+
onMove: newPoint => {
|
|
28592
|
+
props.onMovePoint(0, newPoint);
|
|
28593
|
+
},
|
|
28594
|
+
color: stroke
|
|
28595
|
+
}), /*#__PURE__*/React__namespace.createElement(StyledMovablePoint, {
|
|
28596
|
+
point: end,
|
|
28597
|
+
onMove: newPoint => {
|
|
28598
|
+
props.onMovePoint(1, newPoint);
|
|
28599
|
+
},
|
|
28600
|
+
color: stroke
|
|
28601
|
+
}));
|
|
28602
|
+
};
|
|
28467
28603
|
|
|
28468
28604
|
const renderLineLabel = (n, _ref) => {
|
|
28469
28605
|
let [min, max] = _ref;
|
|
@@ -28482,35 +28618,50 @@ const Grid = props => props.markings === "none" ? null : /*#__PURE__*/React__nam
|
|
|
28482
28618
|
|
|
28483
28619
|
function interactiveGraphReducer(state, action) {
|
|
28484
28620
|
switch (action.type) {
|
|
28485
|
-
case
|
|
28621
|
+
case MOVE_CONTROL_POINT:
|
|
28486
28622
|
{
|
|
28487
|
-
const
|
|
28488
|
-
|
|
28623
|
+
const newCoords = updateAtIndex({
|
|
28624
|
+
array: state.coords,
|
|
28625
|
+
index: action.objectIndex,
|
|
28626
|
+
update: tuple => setAtIndex({
|
|
28627
|
+
array: tuple,
|
|
28628
|
+
index: action.pointIndex,
|
|
28629
|
+
newValue: snap(state, bound$1(state, action.destination))
|
|
28630
|
+
})
|
|
28631
|
+
});
|
|
28632
|
+
if (!validSegments(newCoords)) {
|
|
28489
28633
|
return state;
|
|
28490
28634
|
}
|
|
28491
28635
|
return {
|
|
28492
28636
|
...state,
|
|
28493
28637
|
hasBeenInteractedWith: true,
|
|
28494
|
-
|
|
28638
|
+
coords: newCoords
|
|
28495
28639
|
};
|
|
28496
28640
|
}
|
|
28497
|
-
case
|
|
28641
|
+
case MOVE_LINE:
|
|
28498
28642
|
{
|
|
28499
|
-
const
|
|
28500
|
-
|
|
28501
|
-
|
|
28643
|
+
const currentLine = state.coords?.[action.lineIndex];
|
|
28644
|
+
if (!currentLine) {
|
|
28645
|
+
throw new Error("No line to move");
|
|
28646
|
+
}
|
|
28647
|
+
const maxMoves = currentLine.map(point => maxMove(state, point));
|
|
28648
|
+
const minMoves = currentLine.map(point => minMove(state, point));
|
|
28502
28649
|
const maxXMove = Math.min(...maxMoves.map(move => move[0]));
|
|
28503
28650
|
const maxYMove = Math.min(...maxMoves.map(move => move[1]));
|
|
28504
28651
|
const minXMove = Math.max(...minMoves.map(move => move[0]));
|
|
28505
28652
|
const minYMove = Math.max(...minMoves.map(move => move[1]));
|
|
28506
28653
|
const dx = clamp(action.delta[0], minXMove, maxXMove);
|
|
28507
28654
|
const dy = clamp(action.delta[1], minYMove, maxYMove);
|
|
28508
|
-
const
|
|
28509
|
-
const
|
|
28655
|
+
const newValue = [snap(state, mafs.vec.add(currentLine[0], [dx, dy])), snap(state, mafs.vec.add(currentLine[1], [dx, dy]))];
|
|
28656
|
+
const newLine = setAtIndex({
|
|
28657
|
+
array: state.coords,
|
|
28658
|
+
index: action.lineIndex,
|
|
28659
|
+
newValue
|
|
28660
|
+
});
|
|
28510
28661
|
return {
|
|
28511
28662
|
...state,
|
|
28512
28663
|
hasBeenInteractedWith: true,
|
|
28513
|
-
|
|
28664
|
+
coords: newLine
|
|
28514
28665
|
};
|
|
28515
28666
|
}
|
|
28516
28667
|
default:
|
|
@@ -28559,12 +28710,28 @@ function validSegments(segments) {
|
|
|
28559
28710
|
return !kmath.vector.equal(start, end);
|
|
28560
28711
|
});
|
|
28561
28712
|
}
|
|
28562
|
-
function updateAtIndex(
|
|
28563
|
-
|
|
28713
|
+
function updateAtIndex(args) {
|
|
28714
|
+
const {
|
|
28715
|
+
array = [],
|
|
28716
|
+
index,
|
|
28717
|
+
update
|
|
28718
|
+
} = args;
|
|
28719
|
+
const newValue = update(array[index]);
|
|
28720
|
+
return setAtIndex({
|
|
28721
|
+
array,
|
|
28722
|
+
index,
|
|
28723
|
+
newValue
|
|
28724
|
+
});
|
|
28564
28725
|
}
|
|
28565
|
-
function setAtIndex(
|
|
28566
|
-
const
|
|
28726
|
+
function setAtIndex(args) {
|
|
28727
|
+
const {
|
|
28728
|
+
array,
|
|
28729
|
+
index,
|
|
28730
|
+
newValue
|
|
28731
|
+
} = args;
|
|
28732
|
+
const copy = [...(array || [])];
|
|
28567
28733
|
copy[index] = newValue;
|
|
28734
|
+
// restoring readonly to array
|
|
28568
28735
|
return copy;
|
|
28569
28736
|
}
|
|
28570
28737
|
|
|
@@ -28602,12 +28769,24 @@ function initializeGraphState(params) {
|
|
|
28602
28769
|
hasBeenInteractedWith: false,
|
|
28603
28770
|
range,
|
|
28604
28771
|
snapStep,
|
|
28605
|
-
|
|
28772
|
+
coords: getDefaultSegments({
|
|
28606
28773
|
graph,
|
|
28607
28774
|
step,
|
|
28608
28775
|
range
|
|
28609
28776
|
})
|
|
28610
28777
|
};
|
|
28778
|
+
// Ray can also fall through into this case-- same type, same default coords
|
|
28779
|
+
case "linear":
|
|
28780
|
+
case "linear-system":
|
|
28781
|
+
return {
|
|
28782
|
+
type: graph.type,
|
|
28783
|
+
hasBeenInteractedWith: false,
|
|
28784
|
+
range,
|
|
28785
|
+
snapStep,
|
|
28786
|
+
// A linear graph has a single tuple of points, while a linear
|
|
28787
|
+
// system has two tuples of points.
|
|
28788
|
+
coords: getLineCoords(graph, range, step)
|
|
28789
|
+
};
|
|
28611
28790
|
}
|
|
28612
28791
|
throw new Error("Mafs not yet implemented for graph type: " + graph.type);
|
|
28613
28792
|
}
|
|
@@ -28636,6 +28815,35 @@ const getDefaultSegments = props => {
|
|
|
28636
28815
|
});
|
|
28637
28816
|
};
|
|
28638
28817
|
|
|
28818
|
+
// TS v4 doesn't narrow return types, while v5 does.
|
|
28819
|
+
// Instead of updating to v5, using generic type to relate input and output types.
|
|
28820
|
+
function getGradableGraph(state, initialGraph) {
|
|
28821
|
+
if (!state.hasBeenInteractedWith) {
|
|
28822
|
+
return initialGraph;
|
|
28823
|
+
}
|
|
28824
|
+
switch (true) {
|
|
28825
|
+
// coords: Array of CollinearTuple
|
|
28826
|
+
case state.type === "linear-system" && initialGraph.type === "linear-system":
|
|
28827
|
+
case state.type === "segment" && initialGraph.type === "segment":
|
|
28828
|
+
return {
|
|
28829
|
+
...initialGraph,
|
|
28830
|
+
coords: state.coords
|
|
28831
|
+
};
|
|
28832
|
+
// RAY has the same type as below; can fall through
|
|
28833
|
+
// coords: CollinearTuple
|
|
28834
|
+
case state.type === "linear" && initialGraph.type === "linear":
|
|
28835
|
+
return {
|
|
28836
|
+
...initialGraph,
|
|
28837
|
+
coords: state.coords?.[0]
|
|
28838
|
+
};
|
|
28839
|
+
}
|
|
28840
|
+
throw new Error("Mafs is not yet implemented for graph type: " + initialGraph.type);
|
|
28841
|
+
}
|
|
28842
|
+
const defaultLinearCoords = [[[0.25, 0.75], [0.75, 0.75]], [[0.25, 0.25], [0.75, 0.25]]];
|
|
28843
|
+
const getLineCoords = (graph, range, step) =>
|
|
28844
|
+
// Return two lines for a linear system, one for a ray or linear
|
|
28845
|
+
graph.coords ?? graph.type === "linear-system" ? defaultLinearCoords.map(collinear => normalizePoints(range, step, collinear)) : [normalizePoints(range, step, defaultLinearCoords[0])];
|
|
28846
|
+
|
|
28639
28847
|
// Displays a stylized open eye: lint warnings are visible
|
|
28640
28848
|
const VisibleIcon = () => /*#__PURE__*/React__namespace.createElement("svg", {
|
|
28641
28849
|
width: "24",
|
|
@@ -29333,28 +29541,25 @@ const renderGraph = props => {
|
|
|
29333
29541
|
state,
|
|
29334
29542
|
dispatch
|
|
29335
29543
|
} = props;
|
|
29336
|
-
|
|
29544
|
+
const {
|
|
29545
|
+
type
|
|
29546
|
+
} = state;
|
|
29547
|
+
switch (type) {
|
|
29337
29548
|
case "segment":
|
|
29338
29549
|
return /*#__PURE__*/React__namespace.createElement(SegmentGraph, {
|
|
29339
29550
|
graphState: state,
|
|
29340
29551
|
dispatch: dispatch
|
|
29341
29552
|
});
|
|
29553
|
+
case "linear":
|
|
29554
|
+
case "linear-system":
|
|
29555
|
+
return /*#__PURE__*/React__namespace.createElement(LinearGraph, {
|
|
29556
|
+
graphState: state,
|
|
29557
|
+
dispatch: dispatch
|
|
29558
|
+
});
|
|
29559
|
+
default:
|
|
29560
|
+
return new wonderStuffCore.UnreachableCaseError(type);
|
|
29342
29561
|
}
|
|
29343
|
-
throw new Error("Mafs is not yet implemented for graph type: " + state.type);
|
|
29344
29562
|
};
|
|
29345
|
-
function getGradableGraph(state, initialGraph) {
|
|
29346
|
-
if (!state.hasBeenInteractedWith) {
|
|
29347
|
-
return initialGraph;
|
|
29348
|
-
}
|
|
29349
|
-
switch (initialGraph.type) {
|
|
29350
|
-
case "segment":
|
|
29351
|
-
return {
|
|
29352
|
-
...initialGraph,
|
|
29353
|
-
coords: state.segments
|
|
29354
|
-
};
|
|
29355
|
-
}
|
|
29356
|
-
throw new Error("Mafs is not yet implemented for graph type: " + initialGraph.type);
|
|
29357
|
-
}
|
|
29358
29563
|
const MafsGraph = /*#__PURE__*/React__namespace.forwardRef((props, ref) => {
|
|
29359
29564
|
const [width, height] = props.box;
|
|
29360
29565
|
const legacyGrid = getLegacyGrid([width, height], props.backgroundImage);
|
|
@@ -41363,7 +41568,7 @@ const init = function (options) {
|
|
|
41363
41568
|
|
|
41364
41569
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
41365
41570
|
const libName = "@khanacademy/perseus";
|
|
41366
|
-
const libVersion = "20.
|
|
41571
|
+
const libVersion = "20.4.0";
|
|
41367
41572
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
41368
41573
|
|
|
41369
41574
|
const apiVersion = {
|
|
@@ -42393,8 +42598,9 @@ var constants = /*#__PURE__*/Object.freeze({
|
|
|
42393
42598
|
// TODO(FEI-4010): Remove `Perseus` prefix for all types here
|
|
42394
42599
|
// TODO(FEI-4011): Use types generated by https://github.com/jaredly/generate-perseus-flowtypes
|
|
42395
42600
|
|
|
42601
|
+
// Range is replaced within this file with Interval, but it is used elsewhere
|
|
42602
|
+
// and exported from the package, so we need to keep it around.
|
|
42396
42603
|
// TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
|
|
42397
|
-
|
|
42398
42604
|
const ItemExtras = [
|
|
42399
42605
|
// The user might benefit from using a Scientific Calculator. Provided on Khan Academy when true
|
|
42400
42606
|
"calculator",
|