@khanacademy/perseus 19.9.0 → 20.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.css +0 -35
- package/dist/es/index.js +126 -1185
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +0 -35
- package/dist/index.js +141 -1206
- package/dist/index.js.map +1 -1
- package/dist/perseus-types.d.ts +2 -14
- package/dist/strings.js +0 -8
- package/dist/widgets.d.ts +4 -2
- package/package.json +26 -26
- package/dist/widgets/sequence.d.ts +0 -44
- package/dist/widgets/simulator.d.ts +0 -89
package/dist/es/index.js
CHANGED
|
@@ -29,7 +29,7 @@ import { Strut } from '@khanacademy/wonder-blocks-layout';
|
|
|
29
29
|
import Banner from '@khanacademy/wonder-blocks-banner';
|
|
30
30
|
import { OptionItem, SingleSelect, MultiSelect } from '@khanacademy/wonder-blocks-dropdown';
|
|
31
31
|
import debounce$1 from 'lodash.debounce';
|
|
32
|
-
import { vec, Line as Line$
|
|
32
|
+
import { vec, Line as Line$3, MovablePoint as MovablePoint$5, Coordinates, Mafs } from 'mafs';
|
|
33
33
|
import createReactClass from 'create-react-class';
|
|
34
34
|
import Switch from '@khanacademy/wonder-blocks-switch';
|
|
35
35
|
import { LabelMedium } from '@khanacademy/wonder-blocks-typography';
|
|
@@ -13697,7 +13697,7 @@ var GraphieClasses = {
|
|
|
13697
13697
|
};
|
|
13698
13698
|
|
|
13699
13699
|
const normalizeOptions$3 = InteractiveUtil.normalizeOptions;
|
|
13700
|
-
const assert$
|
|
13700
|
+
const assert$7 = InteractiveUtil.assert;
|
|
13701
13701
|
|
|
13702
13702
|
// Default "props" and "state". Both are added to this.state.
|
|
13703
13703
|
// However, properties in DEFAULT_PROPS are updated on `modify()`,
|
|
@@ -13854,7 +13854,7 @@ class Movable {
|
|
|
13854
13854
|
* Simulates a mouse grab event on the movable object.
|
|
13855
13855
|
*/
|
|
13856
13856
|
grab(coord) {
|
|
13857
|
-
assert$
|
|
13857
|
+
assert$7(point.is(coord));
|
|
13858
13858
|
const graphie = this.graphie;
|
|
13859
13859
|
const state = this.state;
|
|
13860
13860
|
state.isHovering = true;
|
|
@@ -14340,7 +14340,7 @@ var objective_ = {
|
|
|
14340
14340
|
/**
|
|
14341
14341
|
* MovableLine
|
|
14342
14342
|
*/
|
|
14343
|
-
const assert$
|
|
14343
|
+
const assert$6 = InteractiveUtil.assert;
|
|
14344
14344
|
const normalizeOptions$2 = InteractiveUtil.normalizeOptions;
|
|
14345
14345
|
|
|
14346
14346
|
// Default "props" and "state". Both are added to this.state and
|
|
@@ -14364,9 +14364,9 @@ const DEFAULT_STATE$2 = {
|
|
|
14364
14364
|
visibleShape: null,
|
|
14365
14365
|
mouseTarget: null
|
|
14366
14366
|
};
|
|
14367
|
-
const MovableLine$
|
|
14368
|
-
assert$
|
|
14369
|
-
assert$
|
|
14367
|
+
const MovableLine$3 = function MovableLine(graphie, movable, options) {
|
|
14368
|
+
assert$6(graphie != null);
|
|
14369
|
+
assert$6(options != null);
|
|
14370
14370
|
|
|
14371
14371
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
14372
14372
|
_.extend(this, {
|
|
@@ -14382,10 +14382,10 @@ const MovableLine$4 = function MovableLine(graphie, movable, options) {
|
|
|
14382
14382
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
14383
14383
|
this.modify(_.extend({}, DEFAULT_STATE$2, options));
|
|
14384
14384
|
};
|
|
14385
|
-
_.extend(MovableLine$
|
|
14386
|
-
InteractiveUtil.createGettersFor(MovableLine$
|
|
14387
|
-
InteractiveUtil.addMovableHelperMethodsTo(MovableLine$
|
|
14388
|
-
_.extend(MovableLine$
|
|
14385
|
+
_.extend(MovableLine$3, MovableLineOptions);
|
|
14386
|
+
InteractiveUtil.createGettersFor(MovableLine$3, _.extend({}, DEFAULT_PROPS$2, DEFAULT_STATE$2));
|
|
14387
|
+
InteractiveUtil.addMovableHelperMethodsTo(MovableLine$3);
|
|
14388
|
+
_.extend(MovableLine$3.prototype, {
|
|
14389
14389
|
cloneState: function () {
|
|
14390
14390
|
return _.extend(this.movable.cloneState(), {
|
|
14391
14391
|
coords: this.coords()
|
|
@@ -14927,7 +14927,7 @@ var MovablePointOptions = {
|
|
|
14927
14927
|
}
|
|
14928
14928
|
};
|
|
14929
14929
|
|
|
14930
|
-
const assert$
|
|
14930
|
+
const assert$5 = InteractiveUtil.assert;
|
|
14931
14931
|
const normalizeOptions$1 = InteractiveUtil.normalizeOptions;
|
|
14932
14932
|
const {
|
|
14933
14933
|
processMath
|
|
@@ -14962,7 +14962,7 @@ const DEFAULT_STATE$1 = {
|
|
|
14962
14962
|
// TODO(benchristel): this is a memory leak. We add items to
|
|
14963
14963
|
// tooltipResetFunctions, but never remove them.
|
|
14964
14964
|
const tooltipResetFunctions = [];
|
|
14965
|
-
class MovablePoint$
|
|
14965
|
+
class MovablePoint$4 {
|
|
14966
14966
|
constructor(graphie, movable, options) {
|
|
14967
14967
|
this.graphie = void 0;
|
|
14968
14968
|
this.movable = void 0;
|
|
@@ -15004,7 +15004,7 @@ class MovablePoint$5 {
|
|
|
15004
15004
|
const self = this;
|
|
15005
15005
|
const graphie = self.graphie;
|
|
15006
15006
|
const state = _.extend(self.state, normalizeOptions$1(options));
|
|
15007
|
-
assert$
|
|
15007
|
+
assert$5(point.is(state.coord));
|
|
15008
15008
|
|
|
15009
15009
|
// Default things inside the state.normalStyle object, because
|
|
15010
15010
|
// _.extend is not deep.
|
|
@@ -15300,12 +15300,12 @@ class MovablePoint$5 {
|
|
|
15300
15300
|
return this.state.coord;
|
|
15301
15301
|
}
|
|
15302
15302
|
setCoord(coord) {
|
|
15303
|
-
assert$
|
|
15303
|
+
assert$5(point.is(coord, 2));
|
|
15304
15304
|
this.state.coord = _.clone(coord);
|
|
15305
15305
|
this.draw();
|
|
15306
15306
|
}
|
|
15307
15307
|
setCoordConstrained(coord) {
|
|
15308
|
-
assert$
|
|
15308
|
+
assert$5(point.is(coord, 2));
|
|
15309
15309
|
const result = this._applyConstraints(coord, this.coord());
|
|
15310
15310
|
if (result !== false) {
|
|
15311
15311
|
this.state.coord = _.clone(result);
|
|
@@ -15479,15 +15479,15 @@ class MovablePoint$5 {
|
|
|
15479
15479
|
this.movable.toFront();
|
|
15480
15480
|
}
|
|
15481
15481
|
}
|
|
15482
|
-
MovablePoint$
|
|
15483
|
-
MovablePoint$
|
|
15484
|
-
MovablePoint$
|
|
15485
|
-
MovablePoint$
|
|
15486
|
-
MovablePoint$
|
|
15487
|
-
MovablePoint$
|
|
15488
|
-
MovablePoint$
|
|
15489
|
-
MovablePoint$
|
|
15490
|
-
MovablePoint$
|
|
15482
|
+
MovablePoint$4.add = MovablePointOptions.add;
|
|
15483
|
+
MovablePoint$4.modify = MovablePointOptions.modify;
|
|
15484
|
+
MovablePoint$4.draw = MovablePointOptions.draw;
|
|
15485
|
+
MovablePoint$4.remove = MovablePointOptions.remove;
|
|
15486
|
+
MovablePoint$4.onMoveStart = MovablePointOptions.onMoveStart;
|
|
15487
|
+
MovablePoint$4.constraints = MovablePointOptions.constraints;
|
|
15488
|
+
MovablePoint$4.onMove = MovablePointOptions.onMove;
|
|
15489
|
+
MovablePoint$4.onMoveEnd = MovablePointOptions.onMoveEnd;
|
|
15490
|
+
MovablePoint$4.onClick = MovablePointOptions.onClick;
|
|
15491
15491
|
function getKey(eventName, id) {
|
|
15492
15492
|
return eventName + ":" + id;
|
|
15493
15493
|
}
|
|
@@ -15813,7 +15813,7 @@ var MovablePolygonOptions = {
|
|
|
15813
15813
|
* Creates and adds a polygon to the graph that can be dragged around.
|
|
15814
15814
|
* It allows constraints on its movement and draws when moves happen.
|
|
15815
15815
|
*/
|
|
15816
|
-
const assert$
|
|
15816
|
+
const assert$4 = InteractiveUtil.assert;
|
|
15817
15817
|
const normalizeOptions = InteractiveUtil.normalizeOptions;
|
|
15818
15818
|
|
|
15819
15819
|
// Default "props" and "state". Both are added to this.state and
|
|
@@ -15848,8 +15848,8 @@ const DEFAULT_STATE = {
|
|
|
15848
15848
|
mouseTarget: null
|
|
15849
15849
|
};
|
|
15850
15850
|
const MovablePolygon = function MovablePolygon(graphie, movable, options) {
|
|
15851
|
-
assert$
|
|
15852
|
-
assert$
|
|
15851
|
+
assert$4(graphie != null);
|
|
15852
|
+
assert$4(options != null);
|
|
15853
15853
|
|
|
15854
15854
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
15855
15855
|
_.extend(this, {
|
|
@@ -16081,15 +16081,15 @@ _.extend(MovablePolygon.prototype, {
|
|
|
16081
16081
|
});
|
|
16082
16082
|
|
|
16083
16083
|
const Interactive2 = {
|
|
16084
|
-
MovablePoint: MovablePoint$
|
|
16084
|
+
MovablePoint: MovablePoint$4,
|
|
16085
16085
|
addMovablePoint: function (graphie, options) {
|
|
16086
16086
|
const movable = new Movable(graphie, {});
|
|
16087
|
-
return new MovablePoint$
|
|
16087
|
+
return new MovablePoint$4(graphie, movable, options);
|
|
16088
16088
|
},
|
|
16089
|
-
MovableLine: MovableLine$
|
|
16089
|
+
MovableLine: MovableLine$3,
|
|
16090
16090
|
addMovableLine: function (graphie, options) {
|
|
16091
16091
|
const movable = new Movable(graphie, {});
|
|
16092
|
-
return new MovableLine$
|
|
16092
|
+
return new MovableLine$3(graphie, movable, options);
|
|
16093
16093
|
},
|
|
16094
16094
|
MovablePolygon: MovablePolygon,
|
|
16095
16095
|
addMovablePolygon: function (graphie, options) {
|
|
@@ -16125,7 +16125,7 @@ const Interactive2 = {
|
|
|
16125
16125
|
}
|
|
16126
16126
|
};
|
|
16127
16127
|
|
|
16128
|
-
const MovablePoint$
|
|
16128
|
+
const MovablePoint$3 = GraphieClasses.createClass({
|
|
16129
16129
|
displayName: "MovablePoint",
|
|
16130
16130
|
movableProps: ["children"],
|
|
16131
16131
|
_getProps: function () {
|
|
@@ -16182,8 +16182,8 @@ const MovablePoint$4 = GraphieClasses.createClass({
|
|
|
16182
16182
|
});
|
|
16183
16183
|
|
|
16184
16184
|
// Include helper methods, such as MovablePoint.constrain.snap()
|
|
16185
|
-
_.extend(MovablePoint$
|
|
16186
|
-
const MovableLine$
|
|
16185
|
+
_.extend(MovablePoint$3, Interactive2.MovablePoint);
|
|
16186
|
+
const MovableLine$2 = GraphieClasses.createClass({
|
|
16187
16187
|
displayName: "MovableLine",
|
|
16188
16188
|
movableProps: ["children"],
|
|
16189
16189
|
add: function (graphie) {
|
|
@@ -16211,8 +16211,8 @@ const MovableLine$3 = GraphieClasses.createClass({
|
|
|
16211
16211
|
});
|
|
16212
16212
|
|
|
16213
16213
|
// Include helper methods, such as MovableLine.constrain.snap()
|
|
16214
|
-
_.extend(MovableLine$
|
|
16215
|
-
const Label$
|
|
16214
|
+
_.extend(MovableLine$2, Interactive2.MovableLine);
|
|
16215
|
+
const Label$1 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
16216
16216
|
let coord = props.coord;
|
|
16217
16217
|
if (props.unscaled) {
|
|
16218
16218
|
coord = graphie.unscalePoint(coord);
|
|
@@ -16231,7 +16231,7 @@ const Label$2 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
|
16231
16231
|
}
|
|
16232
16232
|
return elem;
|
|
16233
16233
|
});
|
|
16234
|
-
const Line$
|
|
16234
|
+
const Line$2 = GraphieClasses.createClass({
|
|
16235
16235
|
displayName: "Line",
|
|
16236
16236
|
movableProps: ["children"],
|
|
16237
16237
|
add: function (graphie) {
|
|
@@ -16309,7 +16309,7 @@ const Point$1 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
|
16309
16309
|
stroke: props.color || KhanColors.BLACK
|
|
16310
16310
|
});
|
|
16311
16311
|
});
|
|
16312
|
-
const Path
|
|
16312
|
+
const Path = GraphieClasses.createClass({
|
|
16313
16313
|
displayName: "Path",
|
|
16314
16314
|
movableProps: ["children"],
|
|
16315
16315
|
add: function (graphie) {
|
|
@@ -16331,7 +16331,7 @@ const Path$1 = GraphieClasses.createClass({
|
|
|
16331
16331
|
this.path.toFront();
|
|
16332
16332
|
}
|
|
16333
16333
|
});
|
|
16334
|
-
const Arc
|
|
16334
|
+
const Arc = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
16335
16335
|
let center = props.center;
|
|
16336
16336
|
let radius = props.radius;
|
|
16337
16337
|
if (props.unscaled) {
|
|
@@ -16340,21 +16340,21 @@ const Arc$1 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
|
16340
16340
|
}
|
|
16341
16341
|
return graphie.arc(center, radius, props.startAngle, props.endAngle, props.sector, props.style);
|
|
16342
16342
|
});
|
|
16343
|
-
const Circle
|
|
16343
|
+
const Circle = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
16344
16344
|
return graphie.circle(props.center, props.radius, props.style);
|
|
16345
16345
|
});
|
|
16346
16346
|
const Rect$1 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
16347
16347
|
return graphie.rect(props.x, props.y, props.width, props.height, props.style);
|
|
16348
16348
|
});
|
|
16349
16349
|
var Movables = {
|
|
16350
|
-
Arc: Arc
|
|
16351
|
-
Circle: Circle
|
|
16352
|
-
Label: Label$
|
|
16353
|
-
Line: Line$
|
|
16354
|
-
MovableLine: MovableLine$
|
|
16355
|
-
MovablePoint: MovablePoint$
|
|
16350
|
+
Arc: Arc,
|
|
16351
|
+
Circle: Circle,
|
|
16352
|
+
Label: Label$1,
|
|
16353
|
+
Line: Line$2,
|
|
16354
|
+
MovableLine: MovableLine$2,
|
|
16355
|
+
MovablePoint: MovablePoint$3,
|
|
16356
16356
|
Parabola: Parabola,
|
|
16357
|
-
Path: Path
|
|
16357
|
+
Path: Path,
|
|
16358
16358
|
Plot: Plot$2,
|
|
16359
16359
|
PlotParametric: PlotParametric$1,
|
|
16360
16360
|
Point: Point$1,
|
|
@@ -16369,7 +16369,7 @@ const {
|
|
|
16369
16369
|
nestedMap
|
|
16370
16370
|
} = Util;
|
|
16371
16371
|
const {
|
|
16372
|
-
assert: assert$
|
|
16372
|
+
assert: assert$3
|
|
16373
16373
|
} = InteractiveUtil;
|
|
16374
16374
|
class Graphie extends React.Component {
|
|
16375
16375
|
constructor(...args) {
|
|
@@ -16513,7 +16513,7 @@ class Graphie extends React.Component {
|
|
|
16513
16513
|
|
|
16514
16514
|
// Instantiate the descriptor to turn it into a real Movable
|
|
16515
16515
|
const child = new childDescriptor.type(childDescriptor.props);
|
|
16516
|
-
assert$
|
|
16516
|
+
assert$3(child instanceof GraphieMovable, "All children of a Graphie component must be Graphie " + "movables");
|
|
16517
16517
|
|
|
16518
16518
|
// Give each child a key
|
|
16519
16519
|
const keyProp = childDescriptor.key;
|
|
@@ -18716,6 +18716,13 @@ const replaceWidget = (name, replacementName) => {
|
|
|
18716
18716
|
}
|
|
18717
18717
|
registerWidget(name, substituteWidget);
|
|
18718
18718
|
};
|
|
18719
|
+
const replaceDeprecatedWidgets = () => {
|
|
18720
|
+
replaceWidget("transformer", "deprecated-standin");
|
|
18721
|
+
replaceWidget("lights-puzzle", "deprecated-standin");
|
|
18722
|
+
replaceWidget("reaction-diagram", "deprecated-standin");
|
|
18723
|
+
replaceWidget("sequence", "deprecated-standin");
|
|
18724
|
+
replaceWidget("simulator", "deprecated-standin");
|
|
18725
|
+
};
|
|
18719
18726
|
const registerEditors = editorsToRegister => {
|
|
18720
18727
|
editorsToRegister.forEach(editor => {
|
|
18721
18728
|
if (!editor.widgetName) {
|
|
@@ -18730,8 +18737,8 @@ const registerEditors = editorsToRegister => {
|
|
|
18730
18737
|
* @param name - the widget that you are trying to replace
|
|
18731
18738
|
* @param replacementName - the name of the widget that takes its place
|
|
18732
18739
|
*
|
|
18733
|
-
* e.g. replaceEditor("transformer", "
|
|
18734
|
-
* transformer widget is replaced by the
|
|
18740
|
+
* e.g. replaceEditor("transformer", "deprecated-standin") will make it so the
|
|
18741
|
+
* transformer widget is replaced by the deprecated stand-in widget
|
|
18735
18742
|
*/
|
|
18736
18743
|
const replaceEditor = (name, replacementName) => {
|
|
18737
18744
|
const substituteEditor = editors[replacementName];
|
|
@@ -18742,6 +18749,13 @@ const replaceEditor = (name, replacementName) => {
|
|
|
18742
18749
|
}
|
|
18743
18750
|
editors[name] = substituteEditor;
|
|
18744
18751
|
};
|
|
18752
|
+
const replaceDeprecatedEditors = () => {
|
|
18753
|
+
replaceEditor("transformer", "deprecated-standin");
|
|
18754
|
+
replaceEditor("lights-puzzle", "deprecated-standin");
|
|
18755
|
+
replaceEditor("reaction-diagram", "deprecated-standin");
|
|
18756
|
+
replaceEditor("sequence", "deprecated-standin");
|
|
18757
|
+
replaceEditor("simulator", "deprecated-standin");
|
|
18758
|
+
};
|
|
18745
18759
|
const getWidget = name => {
|
|
18746
18760
|
// TODO(alex): Consider referring to these as renderers to avoid
|
|
18747
18761
|
// overloading "widget"
|
|
@@ -18924,7 +18938,7 @@ const getRendererPropsForWidgetInfo = (widgetInfo, problemNum) => {
|
|
|
18924
18938
|
// widgetInfo.options are the widgetEditor's props:
|
|
18925
18939
|
return transform(widgetInfo.options, problemNum);
|
|
18926
18940
|
};
|
|
18927
|
-
const traverseChildWidgets$
|
|
18941
|
+
const traverseChildWidgets$3 = (widgetInfo, traverseRenderer) => {
|
|
18928
18942
|
if (!traverseRenderer) {
|
|
18929
18943
|
throw new PerseusError("traverseRenderer must be provided, but was not", Errors.Internal);
|
|
18930
18944
|
}
|
|
@@ -19053,8 +19067,10 @@ var widgets$1 = /*#__PURE__*/Object.freeze({
|
|
|
19053
19067
|
registerWidget: registerWidget,
|
|
19054
19068
|
registerWidgets: registerWidgets,
|
|
19055
19069
|
replaceWidget: replaceWidget,
|
|
19070
|
+
replaceDeprecatedWidgets: replaceDeprecatedWidgets,
|
|
19056
19071
|
registerEditors: registerEditors,
|
|
19057
19072
|
replaceEditor: replaceEditor,
|
|
19073
|
+
replaceDeprecatedEditors: replaceDeprecatedEditors,
|
|
19058
19074
|
getWidget: getWidget,
|
|
19059
19075
|
getEditor: getEditor,
|
|
19060
19076
|
getTransform: getTransform,
|
|
@@ -19065,7 +19081,7 @@ var widgets$1 = /*#__PURE__*/Object.freeze({
|
|
|
19065
19081
|
getAllWidgetTypes: getAllWidgetTypes,
|
|
19066
19082
|
upgradeWidgetInfoToLatestVersion: upgradeWidgetInfoToLatestVersion,
|
|
19067
19083
|
getRendererPropsForWidgetInfo: getRendererPropsForWidgetInfo,
|
|
19068
|
-
traverseChildWidgets: traverseChildWidgets$
|
|
19084
|
+
traverseChildWidgets: traverseChildWidgets$3,
|
|
19069
19085
|
getSupportedAlignments: getSupportedAlignments,
|
|
19070
19086
|
getDefaultAlignment: getDefaultAlignment,
|
|
19071
19087
|
validateAlignments: validateAlignments,
|
|
@@ -21736,7 +21752,7 @@ const styles$z = StyleSheet.create({
|
|
|
21736
21752
|
border: "solid 1px #999"
|
|
21737
21753
|
}
|
|
21738
21754
|
});
|
|
21739
|
-
const propTransform$
|
|
21755
|
+
const propTransform$3 = widgetOptions => {
|
|
21740
21756
|
const {
|
|
21741
21757
|
simplify,
|
|
21742
21758
|
size,
|
|
@@ -21756,7 +21772,7 @@ var InputNumber$1 = {
|
|
|
21756
21772
|
defaultAlignment: "inline-block",
|
|
21757
21773
|
hidden: true,
|
|
21758
21774
|
widget: InputNumber,
|
|
21759
|
-
transform: propTransform$
|
|
21775
|
+
transform: propTransform$3,
|
|
21760
21776
|
isLintable: true
|
|
21761
21777
|
};
|
|
21762
21778
|
|
|
@@ -25353,7 +25369,7 @@ GradedGroup.defaultProps = {
|
|
|
25353
25369
|
hasHint: false,
|
|
25354
25370
|
linterContext: linterContextDefault
|
|
25355
25371
|
};
|
|
25356
|
-
const traverseChildWidgets$
|
|
25372
|
+
const traverseChildWidgets$2 = function traverseChildWidgets(props, traverseRenderer) {
|
|
25357
25373
|
return _.extend({}, props, traverseRenderer(props));
|
|
25358
25374
|
};
|
|
25359
25375
|
const styles$m = StyleSheet.create({
|
|
@@ -25409,7 +25425,7 @@ var GradedGroup$1 = {
|
|
|
25409
25425
|
name: "graded-group",
|
|
25410
25426
|
displayName: "Graded group (articles only)",
|
|
25411
25427
|
widget: GradedGroup,
|
|
25412
|
-
traverseChildWidgets: traverseChildWidgets$
|
|
25428
|
+
traverseChildWidgets: traverseChildWidgets$2,
|
|
25413
25429
|
// TODO(aasmund): This widget should be available for articles only
|
|
25414
25430
|
hidden: false,
|
|
25415
25431
|
tracking: "all",
|
|
@@ -25571,7 +25587,7 @@ GradedGroupSet.defaultProps = {
|
|
|
25571
25587
|
gradedGroups: [],
|
|
25572
25588
|
linterContext: linterContextDefault
|
|
25573
25589
|
};
|
|
25574
|
-
const traverseChildWidgets$
|
|
25590
|
+
const traverseChildWidgets$1 = function traverseChildWidgets(props, traverseRenderer) {
|
|
25575
25591
|
// NOTE(jared): I have no idea how this works
|
|
25576
25592
|
return {
|
|
25577
25593
|
groups: props.gradedGroups.map(traverseRenderer)
|
|
@@ -25581,7 +25597,7 @@ var GradedGroupSet$1 = {
|
|
|
25581
25597
|
name: "graded-group-set",
|
|
25582
25598
|
displayName: "Graded group set (articles only)",
|
|
25583
25599
|
widget: GradedGroupSet,
|
|
25584
|
-
traverseChildWidgets: traverseChildWidgets$
|
|
25600
|
+
traverseChildWidgets: traverseChildWidgets$1,
|
|
25585
25601
|
// TODO(michaelpolyak): This widget should be available for articles only
|
|
25586
25602
|
hidden: false,
|
|
25587
25603
|
tracking: "all",
|
|
@@ -26141,7 +26157,7 @@ function functionForType(
|
|
|
26141
26157
|
type) {
|
|
26142
26158
|
return functionTypeMapping[type];
|
|
26143
26159
|
}
|
|
26144
|
-
const validate$
|
|
26160
|
+
const validate$1 = (state, rubric) => {
|
|
26145
26161
|
if (state.type !== rubric.correct.type) {
|
|
26146
26162
|
return {
|
|
26147
26163
|
type: "points",
|
|
@@ -26301,7 +26317,7 @@ var util = /*#__PURE__*/Object.freeze({
|
|
|
26301
26317
|
DEFAULT_BACKGROUND_IMAGE: DEFAULT_BACKGROUND_IMAGE,
|
|
26302
26318
|
allTypes: allTypes,
|
|
26303
26319
|
functionForType: functionForType,
|
|
26304
|
-
validate: validate$
|
|
26320
|
+
validate: validate$1,
|
|
26305
26321
|
getEquationString: getEquationString,
|
|
26306
26322
|
pointsFromNormalized: pointsFromNormalized,
|
|
26307
26323
|
maybePointsFromNormalized: maybePointsFromNormalized,
|
|
@@ -26313,9 +26329,9 @@ var util = /*#__PURE__*/Object.freeze({
|
|
|
26313
26329
|
});
|
|
26314
26330
|
|
|
26315
26331
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
26316
|
-
const MovablePoint$
|
|
26332
|
+
const MovablePoint$2 = Graphie.MovablePoint;
|
|
26317
26333
|
// @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
|
|
26318
|
-
const MovableLine$
|
|
26334
|
+
const MovableLine$1 = Graphie.MovableLine;
|
|
26319
26335
|
function isFlipped(newCoord, oldCoord, line) {
|
|
26320
26336
|
const CCW = (a, b, c) => {
|
|
26321
26337
|
return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]);
|
|
@@ -26370,7 +26386,7 @@ class FunctionGrapher extends React.Component {
|
|
|
26370
26386
|
const dashed = {
|
|
26371
26387
|
strokeDasharray: "- "
|
|
26372
26388
|
};
|
|
26373
|
-
return asymptote && /*#__PURE__*/React.createElement(MovableLine$
|
|
26389
|
+
return asymptote && /*#__PURE__*/React.createElement(MovableLine$1, {
|
|
26374
26390
|
onMove: (newCoord, oldCoord) => {
|
|
26375
26391
|
// Calculate and apply displacement
|
|
26376
26392
|
const delta = vector$1.subtract(newCoord, oldCoord);
|
|
@@ -26395,7 +26411,7 @@ class FunctionGrapher extends React.Component {
|
|
|
26395
26411
|
}],
|
|
26396
26412
|
normalStyle: dashed,
|
|
26397
26413
|
highlightStyle: dashed
|
|
26398
|
-
}, _.map(asymptote, (coord, i) => /*#__PURE__*/React.createElement(MovablePoint$
|
|
26414
|
+
}, _.map(asymptote, (coord, i) => /*#__PURE__*/React.createElement(MovablePoint$2, {
|
|
26399
26415
|
key: `asymptoteCoord-${i}`,
|
|
26400
26416
|
coord: coord,
|
|
26401
26417
|
static: true,
|
|
@@ -26410,7 +26426,7 @@ class FunctionGrapher extends React.Component {
|
|
|
26410
26426
|
}
|
|
26411
26427
|
render() {
|
|
26412
26428
|
const pointForCoord = (coord, i) => {
|
|
26413
|
-
return /*#__PURE__*/React.createElement(MovablePoint$
|
|
26429
|
+
return /*#__PURE__*/React.createElement(MovablePoint$2, {
|
|
26414
26430
|
key: i,
|
|
26415
26431
|
coord: coord,
|
|
26416
26432
|
static: this.props.static,
|
|
@@ -26662,21 +26678,21 @@ class Grapher extends React.Component {
|
|
|
26662
26678
|
return tickStep;
|
|
26663
26679
|
}
|
|
26664
26680
|
simpleValidate(rubric) {
|
|
26665
|
-
return validate$
|
|
26681
|
+
return validate$1(this.getUserInput(), rubric);
|
|
26666
26682
|
}
|
|
26667
26683
|
getUserInput() {
|
|
26668
26684
|
return Grapher.getUserInputFromProps(this.props);
|
|
26669
26685
|
}
|
|
26670
26686
|
focus() {}
|
|
26671
26687
|
static validate(state, rubric) {
|
|
26672
|
-
return validate$
|
|
26688
|
+
return validate$1(state, rubric);
|
|
26673
26689
|
}
|
|
26674
26690
|
static getUserInputFromProps(props) {
|
|
26675
26691
|
return props.plot;
|
|
26676
26692
|
}
|
|
26677
26693
|
}
|
|
26678
26694
|
Grapher.defaultProps = DEFAULT_GRAPHER_PROPS;
|
|
26679
|
-
const propTransform$
|
|
26695
|
+
const propTransform$2 = editorProps => {
|
|
26680
26696
|
const widgetProps = {
|
|
26681
26697
|
availableTypes: editorProps.availableTypes,
|
|
26682
26698
|
graph: editorProps.graph
|
|
@@ -26695,7 +26711,7 @@ const propTransform$3 = editorProps => {
|
|
|
26695
26711
|
// Note that in addition to the standard staticTransform, in static
|
|
26696
26712
|
// mode we set static=true for the graph's handles in FunctionGrapher.
|
|
26697
26713
|
const staticTransform$3 = editorProps => {
|
|
26698
|
-
return _extends({}, propTransform$
|
|
26714
|
+
return _extends({}, propTransform$2(editorProps), {
|
|
26699
26715
|
// Don't display graph type choices if we're in static mode
|
|
26700
26716
|
availableTypes: [editorProps.correct.type],
|
|
26701
26717
|
// Display the same graph marked as correct in the widget editor.
|
|
@@ -26706,7 +26722,7 @@ var Grapher$1 = {
|
|
|
26706
26722
|
name: "grapher",
|
|
26707
26723
|
displayName: "Grapher",
|
|
26708
26724
|
widget: Grapher,
|
|
26709
|
-
transform: propTransform$
|
|
26725
|
+
transform: propTransform$2,
|
|
26710
26726
|
staticTransform: staticTransform$3
|
|
26711
26727
|
};
|
|
26712
26728
|
|
|
@@ -26844,14 +26860,14 @@ Group.defaultProps = {
|
|
|
26844
26860
|
images: {},
|
|
26845
26861
|
linterContext: linterContextDefault
|
|
26846
26862
|
};
|
|
26847
|
-
const traverseChildWidgets
|
|
26863
|
+
const traverseChildWidgets = function traverseChildWidgets(props, traverseRenderer) {
|
|
26848
26864
|
return _extends({}, props, traverseRenderer(props));
|
|
26849
26865
|
};
|
|
26850
26866
|
var Group$1 = {
|
|
26851
26867
|
name: "group",
|
|
26852
26868
|
displayName: "Group (SAT only)",
|
|
26853
26869
|
widget: Group,
|
|
26854
|
-
traverseChildWidgets: traverseChildWidgets
|
|
26870
|
+
traverseChildWidgets: traverseChildWidgets,
|
|
26855
26871
|
hidden: false,
|
|
26856
26872
|
isLintable: true
|
|
26857
26873
|
};
|
|
@@ -27018,7 +27034,7 @@ var Iframe$1 = {
|
|
|
27018
27034
|
};
|
|
27019
27035
|
|
|
27020
27036
|
/* eslint-disable react/sort-comp */
|
|
27021
|
-
const defaultBoxSize
|
|
27037
|
+
const defaultBoxSize = 400;
|
|
27022
27038
|
const defaultRange = [0, 10];
|
|
27023
27039
|
const defaultBackgroundImage$2 = {
|
|
27024
27040
|
url: null,
|
|
@@ -27216,7 +27232,7 @@ ImageWidget.defaultProps = {
|
|
|
27216
27232
|
alignment: DEFAULT_ALIGNMENT,
|
|
27217
27233
|
title: "",
|
|
27218
27234
|
range: [defaultRange, defaultRange],
|
|
27219
|
-
box: [defaultBoxSize
|
|
27235
|
+
box: [defaultBoxSize, defaultBoxSize],
|
|
27220
27236
|
backgroundImage: defaultBackgroundImage$2,
|
|
27221
27237
|
labels: [],
|
|
27222
27238
|
alt: "",
|
|
@@ -27240,13 +27256,13 @@ var Image$1 = {
|
|
|
27240
27256
|
|
|
27241
27257
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
27242
27258
|
// @ts-expect-error - TS2339 - Property 'Label' does not exist on type 'typeof Graphie'.
|
|
27243
|
-
const Label
|
|
27259
|
+
const Label = Graphie.Label;
|
|
27244
27260
|
// @ts-expect-error - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
|
|
27245
|
-
const Line$
|
|
27261
|
+
const Line$1 = Graphie.Line;
|
|
27246
27262
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
27247
|
-
const MovablePoint$
|
|
27263
|
+
const MovablePoint$1 = Graphie.MovablePoint;
|
|
27248
27264
|
// @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
|
|
27249
|
-
const MovableLine
|
|
27265
|
+
const MovableLine = Graphie.MovableLine;
|
|
27250
27266
|
// @ts-expect-error - TS2339 - Property 'Plot' does not exist on type 'typeof Graphie'.
|
|
27251
27267
|
const Plot = Graphie.Plot;
|
|
27252
27268
|
// @ts-expect-error - TS2339 - Property 'PlotParametric' does not exist on type 'typeof Graphie'.
|
|
@@ -27433,11 +27449,11 @@ class Interaction extends React.Component {
|
|
|
27433
27449
|
options: this.props.graph,
|
|
27434
27450
|
setup: this._setupGraphie,
|
|
27435
27451
|
setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
|
|
27436
|
-
}, this.props.graph.markings === "graph" && /*#__PURE__*/React.createElement(Label
|
|
27452
|
+
}, this.props.graph.markings === "graph" && /*#__PURE__*/React.createElement(Label, {
|
|
27437
27453
|
coord: [0, range[1][1]],
|
|
27438
27454
|
text: labels[1],
|
|
27439
27455
|
direction: "above"
|
|
27440
|
-
}), this.props.graph.markings === "graph" && /*#__PURE__*/React.createElement(Label
|
|
27456
|
+
}), this.props.graph.markings === "graph" && /*#__PURE__*/React.createElement(Label, {
|
|
27441
27457
|
coord: [range[0][1], 0],
|
|
27442
27458
|
text: labels[0],
|
|
27443
27459
|
direction: "right"
|
|
@@ -27464,7 +27480,7 @@ class Interaction extends React.Component {
|
|
|
27464
27480
|
this._eval(element.options.endX),
|
|
27465
27481
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
27466
27482
|
this._eval(element.options.endY)];
|
|
27467
|
-
return /*#__PURE__*/React.createElement(Line$
|
|
27483
|
+
return /*#__PURE__*/React.createElement(Line$1, {
|
|
27468
27484
|
key: element.key,
|
|
27469
27485
|
start: start,
|
|
27470
27486
|
end: end,
|
|
@@ -27493,7 +27509,7 @@ class Interaction extends React.Component {
|
|
|
27493
27509
|
return [coordX, coordY];
|
|
27494
27510
|
}];
|
|
27495
27511
|
if (element.options.constraint === "snap") {
|
|
27496
|
-
constraints.push(MovablePoint$
|
|
27512
|
+
constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
|
|
27497
27513
|
} else if (element.options.constraint === "x") {
|
|
27498
27514
|
constraints.push(coord => {
|
|
27499
27515
|
return [
|
|
@@ -27515,7 +27531,7 @@ class Interaction extends React.Component {
|
|
|
27515
27531
|
// TODO(eater): foo_[xyz] are hacky non-props to
|
|
27516
27532
|
// get the component to update when constraints
|
|
27517
27533
|
// change
|
|
27518
|
-
return /*#__PURE__*/React.createElement(MovablePoint$
|
|
27534
|
+
return /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
27519
27535
|
key: element.key,
|
|
27520
27536
|
coord: [
|
|
27521
27537
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
@@ -27550,7 +27566,7 @@ class Interaction extends React.Component {
|
|
|
27550
27566
|
return [coordX, coordY];
|
|
27551
27567
|
}];
|
|
27552
27568
|
if (element.options.constraint === "snap") {
|
|
27553
|
-
constraints.push(MovablePoint$
|
|
27569
|
+
constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
|
|
27554
27570
|
} else if (element.options.constraint === "x") {
|
|
27555
27571
|
constraints.push(coord => {
|
|
27556
27572
|
return [
|
|
@@ -27578,7 +27594,7 @@ class Interaction extends React.Component {
|
|
|
27578
27594
|
this.state.variables["x_" + element.options.endSubscript],
|
|
27579
27595
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
27580
27596
|
this.state.variables["y_" + element.options.endSubscript]];
|
|
27581
|
-
return /*#__PURE__*/React.createElement(MovableLine
|
|
27597
|
+
return /*#__PURE__*/React.createElement(MovableLine, {
|
|
27582
27598
|
key: element.key,
|
|
27583
27599
|
constraints: constraints
|
|
27584
27600
|
// eslint-disable-next-line react/jsx-no-bind
|
|
@@ -27591,14 +27607,14 @@ class Interaction extends React.Component {
|
|
|
27591
27607
|
foo_x: element.options.constraint,
|
|
27592
27608
|
foo_y: element.options.constraintFn,
|
|
27593
27609
|
foo_z: element.options.snap
|
|
27594
|
-
}, /*#__PURE__*/React.createElement(MovablePoint$
|
|
27610
|
+
}, /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
27595
27611
|
coord: start,
|
|
27596
27612
|
static: true,
|
|
27597
27613
|
normalStyle: {
|
|
27598
27614
|
stroke: "none",
|
|
27599
27615
|
fill: "none"
|
|
27600
27616
|
}
|
|
27601
|
-
}), /*#__PURE__*/React.createElement(MovablePoint$
|
|
27617
|
+
}), /*#__PURE__*/React.createElement(MovablePoint$1, {
|
|
27602
27618
|
coord: end,
|
|
27603
27619
|
static: true,
|
|
27604
27620
|
normalStyle: {
|
|
@@ -27710,7 +27726,7 @@ class Interaction extends React.Component {
|
|
|
27710
27726
|
this._eval(element.options.coordX),
|
|
27711
27727
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
27712
27728
|
this._eval(element.options.coordY)];
|
|
27713
|
-
return /*#__PURE__*/React.createElement(Label
|
|
27729
|
+
return /*#__PURE__*/React.createElement(Label, {
|
|
27714
27730
|
key: n + 1,
|
|
27715
27731
|
coord: coord,
|
|
27716
27732
|
text: unescapeMathMode(element.options.label),
|
|
@@ -28213,22 +28229,22 @@ const SegmentGraph = props => {
|
|
|
28213
28229
|
const SegmentView = props => {
|
|
28214
28230
|
const [pt1, pt2] = props.segment;
|
|
28215
28231
|
const midpoint = vec.midpoint(pt1, pt2);
|
|
28216
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Line$
|
|
28232
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Line$3.Segment, {
|
|
28217
28233
|
point1: pt1,
|
|
28218
28234
|
point2: pt2
|
|
28219
|
-
}), /*#__PURE__*/React.createElement(MovablePoint$
|
|
28235
|
+
}), /*#__PURE__*/React.createElement(MovablePoint$5, {
|
|
28220
28236
|
point: midpoint,
|
|
28221
28237
|
color: Color.blue,
|
|
28222
28238
|
onMove: newPoint => {
|
|
28223
28239
|
props.onMoveSegment(vec.sub(newPoint, midpoint));
|
|
28224
28240
|
}
|
|
28225
|
-
}), /*#__PURE__*/React.createElement(MovablePoint$
|
|
28241
|
+
}), /*#__PURE__*/React.createElement(MovablePoint$5, {
|
|
28226
28242
|
point: pt1,
|
|
28227
28243
|
color: Color.blue,
|
|
28228
28244
|
onMove: newPoint => {
|
|
28229
28245
|
props.onMovePoint(0, newPoint);
|
|
28230
28246
|
}
|
|
28231
|
-
}), /*#__PURE__*/React.createElement(MovablePoint$
|
|
28247
|
+
}), /*#__PURE__*/React.createElement(MovablePoint$5, {
|
|
28232
28248
|
point: pt2,
|
|
28233
28249
|
color: Color.blue,
|
|
28234
28250
|
onMove: newPoint => {
|
|
@@ -32890,276 +32906,6 @@ var LabelImage$1 = {
|
|
|
32890
32906
|
isLintable: true
|
|
32891
32907
|
};
|
|
32892
32908
|
|
|
32893
|
-
/* eslint-disable @typescript-eslint/no-unused-vars, react/sort-comp */
|
|
32894
|
-
|
|
32895
|
-
// Styling
|
|
32896
|
-
const CELL_PADDING = 5;
|
|
32897
|
-
const TABLE_STYLE = {
|
|
32898
|
-
display: "table",
|
|
32899
|
-
tableLayout: "fixed"
|
|
32900
|
-
};
|
|
32901
|
-
const ROW_STYLE = {
|
|
32902
|
-
display: "table-row"
|
|
32903
|
-
};
|
|
32904
|
-
const CELL_STYLE = {
|
|
32905
|
-
display: "table-cell",
|
|
32906
|
-
padding: CELL_PADDING
|
|
32907
|
-
};
|
|
32908
|
-
const BASE_TILE_STYLE = {
|
|
32909
|
-
borderRadius: 10,
|
|
32910
|
-
cursor: "pointer"
|
|
32911
|
-
};
|
|
32912
|
-
const MOVE_COUNT_STYLE = {
|
|
32913
|
-
padding: CELL_PADDING,
|
|
32914
|
-
display: "inline-block"
|
|
32915
|
-
};
|
|
32916
|
-
const RESET_BUTTON_STYLE = {
|
|
32917
|
-
float: "right",
|
|
32918
|
-
paddingRight: CELL_PADDING
|
|
32919
|
-
};
|
|
32920
|
-
const MAIN_TILE_SIZE = 50;
|
|
32921
|
-
const PATTERNS = {
|
|
32922
|
-
plus: () => [[false, true, false], [true, true, true], [false, true, false]],
|
|
32923
|
-
x: () => [[true, false, true], [false, true, false], [true, false, true]],
|
|
32924
|
-
"plus/x": iter => {
|
|
32925
|
-
return iter % 2 ? PATTERNS.x() : PATTERNS.plus();
|
|
32926
|
-
}
|
|
32927
|
-
};
|
|
32928
|
-
|
|
32929
|
-
// A single glowy cell
|
|
32930
|
-
class Tile extends React.Component {
|
|
32931
|
-
constructor(...args) {
|
|
32932
|
-
super(...args);
|
|
32933
|
-
this._flip = () => {
|
|
32934
|
-
// On change requires a value, but we don't actually have access
|
|
32935
|
-
// to the coordinates here, so we just pass the inverse value as a workaround.
|
|
32936
|
-
this.props.onChange({
|
|
32937
|
-
value: !this.props.value
|
|
32938
|
-
});
|
|
32939
|
-
};
|
|
32940
|
-
}
|
|
32941
|
-
render() {
|
|
32942
|
-
const color = this.props.value ? "#55dd55" : "#115511";
|
|
32943
|
-
const style = _.extend({}, BASE_TILE_STYLE, {
|
|
32944
|
-
width: this.props.size,
|
|
32945
|
-
height: this.props.size,
|
|
32946
|
-
backgroundColor: color
|
|
32947
|
-
});
|
|
32948
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
32949
|
-
style: style,
|
|
32950
|
-
onClick: this._flip
|
|
32951
|
-
});
|
|
32952
|
-
}
|
|
32953
|
-
}
|
|
32954
|
-
|
|
32955
|
-
// A grid of glowy cells
|
|
32956
|
-
Tile.propTypes = {
|
|
32957
|
-
value: PropTypes.bool.isRequired,
|
|
32958
|
-
size: PropTypes.number.isRequired
|
|
32959
|
-
};
|
|
32960
|
-
class TileGrid extends React.Component {
|
|
32961
|
-
render() {
|
|
32962
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
32963
|
-
style: TABLE_STYLE,
|
|
32964
|
-
className: "no-select"
|
|
32965
|
-
}, this.props.cells && _.map(this.props.cells, (row, y) => {
|
|
32966
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
32967
|
-
key: y,
|
|
32968
|
-
style: ROW_STYLE
|
|
32969
|
-
}, _.map(row, (cell, x) => {
|
|
32970
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
32971
|
-
key: x,
|
|
32972
|
-
style: CELL_STYLE
|
|
32973
|
-
}, /*#__PURE__*/React.createElement(Tile, {
|
|
32974
|
-
value: cell,
|
|
32975
|
-
size: this.props.size,
|
|
32976
|
-
onChange: _.partial(this.props.onChange, {
|
|
32977
|
-
value: {
|
|
32978
|
-
y,
|
|
32979
|
-
x
|
|
32980
|
-
}
|
|
32981
|
-
})
|
|
32982
|
-
}));
|
|
32983
|
-
}));
|
|
32984
|
-
}));
|
|
32985
|
-
}
|
|
32986
|
-
}
|
|
32987
|
-
|
|
32988
|
-
// Returns a copy of the tiles, with tiles flipped according to
|
|
32989
|
-
// whether or not their y, x position satisfies the predicate
|
|
32990
|
-
const flipTilesPredicate = (oldCells, predicate) => {
|
|
32991
|
-
return _.map(oldCells, (row, y) => {
|
|
32992
|
-
return _.map(row, (cell, x) => {
|
|
32993
|
-
return predicate(y, x) ? !cell : cell;
|
|
32994
|
-
});
|
|
32995
|
-
});
|
|
32996
|
-
};
|
|
32997
|
-
const flipTilesPattern = (oldCells, tileY, tileX, pattern) => {
|
|
32998
|
-
return flipTilesPredicate(oldCells, (y, x) => {
|
|
32999
|
-
const offsetY = y - tileY;
|
|
33000
|
-
const offsetX = x - tileX;
|
|
33001
|
-
if (Math.abs(offsetY) <= 1 && Math.abs(offsetX) <= 1) {
|
|
33002
|
-
return pattern[offsetY + 1][offsetX + 1];
|
|
33003
|
-
}
|
|
33004
|
-
return false;
|
|
33005
|
-
});
|
|
33006
|
-
};
|
|
33007
|
-
|
|
33008
|
-
// The lights puzzle widget
|
|
33009
|
-
class LightsPuzzle extends React.Component {
|
|
33010
|
-
constructor(..._args) {
|
|
33011
|
-
super(..._args);
|
|
33012
|
-
this._currPattern = void 0;
|
|
33013
|
-
this._nextPattern = void 0;
|
|
33014
|
-
// @ts-expect-error - TS2564 - Property '_patternIndex' has no initializer and is not definitely assigned in the constructor.
|
|
33015
|
-
this._patternIndex = void 0;
|
|
33016
|
-
this.getUserInput = () => {
|
|
33017
|
-
return WidgetJsonifyDeprecated.getUserInput.call(this);
|
|
33018
|
-
};
|
|
33019
|
-
this.change = (...args) => {
|
|
33020
|
-
// @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
|
|
33021
|
-
return change.apply(this, args);
|
|
33022
|
-
};
|
|
33023
|
-
this._width = () => {
|
|
33024
|
-
if (this.props.cells && this.props.cells.length !== 0) {
|
|
33025
|
-
return this.props.cells[0].length;
|
|
33026
|
-
}
|
|
33027
|
-
return 0; // default to 0
|
|
33028
|
-
};
|
|
33029
|
-
this._initNextPatterns = () => {
|
|
33030
|
-
if (this.props.flipPattern) {
|
|
33031
|
-
this._currPattern = PATTERNS[this.props.flipPattern](0);
|
|
33032
|
-
this._nextPattern = PATTERNS[this.props.flipPattern](1);
|
|
33033
|
-
}
|
|
33034
|
-
this._patternIndex = 2;
|
|
33035
|
-
};
|
|
33036
|
-
this._shiftPatterns = () => {
|
|
33037
|
-
if (this.props.flipPattern) {
|
|
33038
|
-
this._currPattern = this._nextPattern;
|
|
33039
|
-
this._nextPattern = PATTERNS[this.props.flipPattern](this._patternIndex);
|
|
33040
|
-
this._patternIndex++;
|
|
33041
|
-
}
|
|
33042
|
-
};
|
|
33043
|
-
this._flipTile = ({
|
|
33044
|
-
value: {
|
|
33045
|
-
y,
|
|
33046
|
-
x
|
|
33047
|
-
}
|
|
33048
|
-
}) => {
|
|
33049
|
-
const newCells = flipTilesPattern(this.props.cells, y, x, this._currPattern);
|
|
33050
|
-
this._shiftPatterns();
|
|
33051
|
-
this.change({
|
|
33052
|
-
cells: newCells,
|
|
33053
|
-
moveCount: (this.props.moveCount || 0) + 1
|
|
33054
|
-
});
|
|
33055
|
-
};
|
|
33056
|
-
this._reset = () => {
|
|
33057
|
-
this.change({
|
|
33058
|
-
cells: this.props.startCells,
|
|
33059
|
-
moveCount: 0
|
|
33060
|
-
});
|
|
33061
|
-
};
|
|
33062
|
-
this.simpleValidate = rubric => {
|
|
33063
|
-
return validate$1(rubric, this.getUserInput());
|
|
33064
|
-
};
|
|
33065
|
-
}
|
|
33066
|
-
render() {
|
|
33067
|
-
const width = this._width();
|
|
33068
|
-
const tileSize = MAIN_TILE_SIZE;
|
|
33069
|
-
const pxWidth = width * (tileSize + 2 * CELL_PADDING);
|
|
33070
|
-
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(TileGrid, {
|
|
33071
|
-
cells: this.props.cells,
|
|
33072
|
-
size: tileSize,
|
|
33073
|
-
onChange: this._flipTile
|
|
33074
|
-
}), /*#__PURE__*/React.createElement("div", {
|
|
33075
|
-
style: {
|
|
33076
|
-
width: pxWidth
|
|
33077
|
-
}
|
|
33078
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
33079
|
-
style: MOVE_COUNT_STYLE
|
|
33080
|
-
}, i18n.ngettext("Moves: %(num)s", "Moves: %(num)s", this.props.moveCount)), /*#__PURE__*/React.createElement("div", {
|
|
33081
|
-
style: RESET_BUTTON_STYLE
|
|
33082
|
-
}, /*#__PURE__*/React.createElement("input", {
|
|
33083
|
-
type: "button",
|
|
33084
|
-
value: "Reset",
|
|
33085
|
-
onClick: this._reset,
|
|
33086
|
-
className: "simple-button"
|
|
33087
|
-
}))), /*#__PURE__*/React.createElement("div", {
|
|
33088
|
-
className: "clearfix"
|
|
33089
|
-
}));
|
|
33090
|
-
}
|
|
33091
|
-
componentDidMount() {
|
|
33092
|
-
this._initNextPatterns();
|
|
33093
|
-
}
|
|
33094
|
-
componentDidUpdate(prevProps) {
|
|
33095
|
-
if (prevProps.flipPattern !== this.props.flipPattern) {
|
|
33096
|
-
this._initNextPatterns();
|
|
33097
|
-
}
|
|
33098
|
-
}
|
|
33099
|
-
}
|
|
33100
|
-
|
|
33101
|
-
// grading function
|
|
33102
|
-
LightsPuzzle.defaultProps = {
|
|
33103
|
-
cells: [[false, false, false], [false, false, false], [false, false, false]],
|
|
33104
|
-
startCells: [[false, false, false], [false, false, false], [false, false, false]],
|
|
33105
|
-
flipPattern: "plus",
|
|
33106
|
-
moveCount: 0
|
|
33107
|
-
};
|
|
33108
|
-
const validate$1 = function validate(rubric, state) {
|
|
33109
|
-
const empty = _.all(state.cells, (row, y) => {
|
|
33110
|
-
return _.all(row, (cell, x) => {
|
|
33111
|
-
return cell === rubric.startCells[y][x];
|
|
33112
|
-
});
|
|
33113
|
-
});
|
|
33114
|
-
if (empty) {
|
|
33115
|
-
return {
|
|
33116
|
-
type: "invalid",
|
|
33117
|
-
message: i18n._("Click on the tiles to change the lights.")
|
|
33118
|
-
};
|
|
33119
|
-
}
|
|
33120
|
-
const correct = _.all(state.cells, row => {
|
|
33121
|
-
return _.all(row, cell => {
|
|
33122
|
-
return cell;
|
|
33123
|
-
});
|
|
33124
|
-
});
|
|
33125
|
-
if (correct) {
|
|
33126
|
-
return {
|
|
33127
|
-
type: "points",
|
|
33128
|
-
earned: 1,
|
|
33129
|
-
total: 1,
|
|
33130
|
-
message: null
|
|
33131
|
-
};
|
|
33132
|
-
}
|
|
33133
|
-
if (rubric.gradeIncompleteAsWrong) {
|
|
33134
|
-
return {
|
|
33135
|
-
type: "points",
|
|
33136
|
-
earned: 0,
|
|
33137
|
-
total: 1,
|
|
33138
|
-
message: null
|
|
33139
|
-
};
|
|
33140
|
-
}
|
|
33141
|
-
return {
|
|
33142
|
-
type: "invalid",
|
|
33143
|
-
message: i18n._("You must turn on all of the lights to continue.")
|
|
33144
|
-
};
|
|
33145
|
-
};
|
|
33146
|
-
|
|
33147
|
-
// The function run on the editor props to create the widget props
|
|
33148
|
-
const transformProps = function transformProps(editorProps) {
|
|
33149
|
-
return {
|
|
33150
|
-
cells: editorProps.startCells,
|
|
33151
|
-
startCells: editorProps.startCells,
|
|
33152
|
-
flipPattern: editorProps.flipPattern
|
|
33153
|
-
};
|
|
33154
|
-
};
|
|
33155
|
-
var LightsPuzzle$1 = {
|
|
33156
|
-
name: "lights-puzzle",
|
|
33157
|
-
displayName: "Lights puzzle (deprecated)",
|
|
33158
|
-
hidden: true,
|
|
33159
|
-
widget: LightsPuzzle,
|
|
33160
|
-
transform: transformProps
|
|
33161
|
-
};
|
|
33162
|
-
|
|
33163
32909
|
let Layout = /*#__PURE__*/function (Layout) {
|
|
33164
32910
|
Layout["HORIZONTAL"] = "horizontal";
|
|
33165
32911
|
Layout["VERTICAL"] = "vertical";
|
|
@@ -34105,7 +33851,7 @@ var Matcher$1 = {
|
|
|
34105
33851
|
// Type imports
|
|
34106
33852
|
|
|
34107
33853
|
const {
|
|
34108
|
-
assert: assert$
|
|
33854
|
+
assert: assert$2
|
|
34109
33855
|
} = InteractiveUtil;
|
|
34110
33856
|
const {
|
|
34111
33857
|
stringArrayOfSize
|
|
@@ -34139,12 +33885,12 @@ const getDefaultPath$1 = function getDefaultPath() {
|
|
|
34139
33885
|
};
|
|
34140
33886
|
const getRowFromPath$1 = function getRowFromPath(path) {
|
|
34141
33887
|
// 'path' should be a (row, column) pair
|
|
34142
|
-
assert$
|
|
33888
|
+
assert$2(_.isArray(path) && path.length === 2);
|
|
34143
33889
|
return +path[0];
|
|
34144
33890
|
};
|
|
34145
33891
|
const getColumnFromPath$1 = function getColumnFromPath(path) {
|
|
34146
33892
|
// 'path' should be a (row, column) pair
|
|
34147
|
-
assert$
|
|
33893
|
+
assert$2(_.isArray(path) && path.length === 2);
|
|
34148
33894
|
return +path[1];
|
|
34149
33895
|
};
|
|
34150
33896
|
const getRefForPath$1 = function getRefForPath(path) {
|
|
@@ -34541,7 +34287,7 @@ _.extend(Matrix, {
|
|
|
34541
34287
|
};
|
|
34542
34288
|
}
|
|
34543
34289
|
});
|
|
34544
|
-
const propTransform$
|
|
34290
|
+
const propTransform$1 = editorProps => {
|
|
34545
34291
|
// Remove answers before passing to widget
|
|
34546
34292
|
const blankAnswers = _(editorProps.matrixBoardSize[0]).times(function () {
|
|
34547
34293
|
return stringArrayOfSize(editorProps.matrixBoardSize[1]);
|
|
@@ -34566,7 +34312,7 @@ var Matrix$1 = {
|
|
|
34566
34312
|
name: "matrix",
|
|
34567
34313
|
displayName: "Matrix",
|
|
34568
34314
|
widget: Matrix,
|
|
34569
|
-
transform: propTransform$
|
|
34315
|
+
transform: propTransform$1,
|
|
34570
34316
|
staticTransform: staticTransform$2,
|
|
34571
34317
|
isLintable: true
|
|
34572
34318
|
};
|
|
@@ -35636,11 +35382,11 @@ var Molecule$1 = {
|
|
|
35636
35382
|
};
|
|
35637
35383
|
|
|
35638
35384
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
35639
|
-
const MovablePoint
|
|
35385
|
+
const MovablePoint = Graphie.MovablePoint;
|
|
35640
35386
|
// @ts-expect-error - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
|
|
35641
|
-
const Line
|
|
35387
|
+
const Line = Graphie.Line;
|
|
35642
35388
|
const {
|
|
35643
|
-
assert: assert$
|
|
35389
|
+
assert: assert$1
|
|
35644
35390
|
} = InteractiveUtil;
|
|
35645
35391
|
const bound = (x, gt, lt) => Math.min(Math.max(x, gt), lt);
|
|
35646
35392
|
const EN_DASH = "\u2013";
|
|
@@ -35898,7 +35644,7 @@ class NumberLine extends React.Component {
|
|
|
35898
35644
|
const snapX = props.tickStep / props.snapDivisions;
|
|
35899
35645
|
let x = bound(numLinePosition, left, right);
|
|
35900
35646
|
x = left + number.roundTo(x - left, snapX);
|
|
35901
|
-
assert$
|
|
35647
|
+
assert$1(_.isFinite(x));
|
|
35902
35648
|
return x;
|
|
35903
35649
|
};
|
|
35904
35650
|
// This function is intended to be used by the client code
|
|
@@ -35936,7 +35682,7 @@ class NumberLine extends React.Component {
|
|
|
35936
35682
|
stroke: KhanColors.INTERACTIVE,
|
|
35937
35683
|
"fill-opacity": isOpen ? 0 : 1
|
|
35938
35684
|
} : {};
|
|
35939
|
-
return /*#__PURE__*/React.createElement(MovablePoint
|
|
35685
|
+
return /*#__PURE__*/React.createElement(MovablePoint
|
|
35940
35686
|
// eslint-disable-next-line react/no-string-refs
|
|
35941
35687
|
, {
|
|
35942
35688
|
ref: "numberLinePoint",
|
|
@@ -35995,7 +35741,7 @@ class NumberLine extends React.Component {
|
|
|
35995
35741
|
strokeWidth: 3.5
|
|
35996
35742
|
};
|
|
35997
35743
|
const isGreater = ["ge", "gt"].includes(props.rel);
|
|
35998
|
-
return /*#__PURE__*/React.createElement(Line
|
|
35744
|
+
return /*#__PURE__*/React.createElement(Line
|
|
35999
35745
|
// We shift the line to either side of the dot so they don't
|
|
36000
35746
|
// intersect
|
|
36001
35747
|
, {
|
|
@@ -39881,803 +39627,6 @@ var PythonProgram$1 = {
|
|
|
39881
39627
|
widget: PythonProgram
|
|
39882
39628
|
};
|
|
39883
39629
|
|
|
39884
|
-
class Separator extends React.Component {
|
|
39885
|
-
constructor(...args) {
|
|
39886
|
-
super(...args);
|
|
39887
|
-
this.arrowLength = 100;
|
|
39888
|
-
this.drawArrow = () => {
|
|
39889
|
-
// eslint-disable-next-line react/no-string-refs
|
|
39890
|
-
const canvas = this.refs["arrowCanvas" + this.props.index];
|
|
39891
|
-
// @ts-expect-error - TS2339 - Property 'getContext' does not exist on type 'ReactInstance'.
|
|
39892
|
-
const ctx = canvas.getContext("2d");
|
|
39893
|
-
// @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
39894
|
-
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
39895
|
-
const path = new Path2D();
|
|
39896
|
-
ctx.strokeStyle = "rgb(0,0,0)";
|
|
39897
|
-
ctx.lineWidth = 1.2;
|
|
39898
|
-
ctx.lineCap = "round";
|
|
39899
|
-
const offset = 5;
|
|
39900
|
-
// @ts-expect-error - TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
39901
|
-
path.moveTo(offset, canvas.height / 2);
|
|
39902
|
-
// @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
39903
|
-
path.lineTo(canvas.width - offset, canvas.height / 2);
|
|
39904
|
-
// @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
39905
|
-
path.moveTo(canvas.width - 2 * offset, canvas.height / 2 - offset);
|
|
39906
|
-
// @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
39907
|
-
path.lineTo(canvas.width - offset, canvas.height / 2);
|
|
39908
|
-
// @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
39909
|
-
path.moveTo(canvas.width - 2 * offset, canvas.height / 2 + offset);
|
|
39910
|
-
// @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
39911
|
-
path.lineTo(canvas.width - offset, canvas.height / 2);
|
|
39912
|
-
ctx.stroke(path);
|
|
39913
|
-
};
|
|
39914
|
-
}
|
|
39915
|
-
componentDidMount() {
|
|
39916
|
-
this.drawArrow();
|
|
39917
|
-
}
|
|
39918
|
-
componentDidUpdate() {
|
|
39919
|
-
this.drawArrow();
|
|
39920
|
-
}
|
|
39921
|
-
render() {
|
|
39922
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
39923
|
-
className: "arrow-container"
|
|
39924
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
39925
|
-
className: "above-text"
|
|
39926
|
-
}, this.props.data.topText), /*#__PURE__*/React.createElement("canvas", {
|
|
39927
|
-
height: "30",
|
|
39928
|
-
id: "arrowCanvas" + this.props.index,
|
|
39929
|
-
ref: "arrowCanvas" + this.props.index,
|
|
39930
|
-
width: this.arrowLength
|
|
39931
|
-
}, i18n._("Reaction arrow pointing to the right.")), /*#__PURE__*/React.createElement("div", {
|
|
39932
|
-
className: "below-text"
|
|
39933
|
-
}, this.props.data.bottomText));
|
|
39934
|
-
}
|
|
39935
|
-
}
|
|
39936
|
-
class ReactionDiagramWidget extends React.Component {
|
|
39937
|
-
constructor(...args) {
|
|
39938
|
-
super(...args);
|
|
39939
|
-
this.simpleValidate = () => {
|
|
39940
|
-
return {
|
|
39941
|
-
type: "points",
|
|
39942
|
-
earned: 0,
|
|
39943
|
-
total: 0,
|
|
39944
|
-
message: null
|
|
39945
|
-
};
|
|
39946
|
-
};
|
|
39947
|
-
this.getUserInput = () => {
|
|
39948
|
-
return [];
|
|
39949
|
-
};
|
|
39950
|
-
this.validate = (state, rubric) => {
|
|
39951
|
-
// TODO(colin): this appears to be part of the perseus interface.
|
|
39952
|
-
// Figure out if there's a more appropriate value to return.
|
|
39953
|
-
return {
|
|
39954
|
-
type: "points",
|
|
39955
|
-
earned: 0,
|
|
39956
|
-
total: 0,
|
|
39957
|
-
message: null
|
|
39958
|
-
};
|
|
39959
|
-
};
|
|
39960
|
-
this.focus = () => {
|
|
39961
|
-
return true;
|
|
39962
|
-
};
|
|
39963
|
-
}
|
|
39964
|
-
render() {
|
|
39965
|
-
return (
|
|
39966
|
-
/*#__PURE__*/
|
|
39967
|
-
// eslint-disable-next-line react/no-string-refs
|
|
39968
|
-
React.createElement("div", {
|
|
39969
|
-
className: "reaction",
|
|
39970
|
-
ref: "reaction"
|
|
39971
|
-
}, this.props.smiles.map((s, i) => {
|
|
39972
|
-
const id = this.props.widgetId + "-" + i;
|
|
39973
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
39974
|
-
key: id,
|
|
39975
|
-
className: "molecule-container"
|
|
39976
|
-
}, /*#__PURE__*/React.createElement(Molecule, {
|
|
39977
|
-
widgetId: id,
|
|
39978
|
-
rotationAngle: this.props.rotationAngle[i],
|
|
39979
|
-
smiles: s
|
|
39980
|
-
}), i === this.props.smiles.length - 1 ? null : /*#__PURE__*/React.createElement(Separator, {
|
|
39981
|
-
data: this.props.separators[i],
|
|
39982
|
-
index: i
|
|
39983
|
-
}));
|
|
39984
|
-
}))
|
|
39985
|
-
);
|
|
39986
|
-
}
|
|
39987
|
-
}
|
|
39988
|
-
ReactionDiagramWidget.defaultProps = {
|
|
39989
|
-
smiles: [],
|
|
39990
|
-
rotationAngle: [],
|
|
39991
|
-
separators: []
|
|
39992
|
-
};
|
|
39993
|
-
var ReactionDiagram = {
|
|
39994
|
-
name: "reaction-diagram",
|
|
39995
|
-
displayName: "Chemical reaction diagram (deprecated)",
|
|
39996
|
-
hidden: true,
|
|
39997
|
-
widget: ReactionDiagramWidget
|
|
39998
|
-
};
|
|
39999
|
-
|
|
40000
|
-
class Sequence extends React.Component {
|
|
40001
|
-
constructor(..._args) {
|
|
40002
|
-
super(..._args);
|
|
40003
|
-
this.state = {
|
|
40004
|
-
visible: 1
|
|
40005
|
-
};
|
|
40006
|
-
this.change = (...args) => {
|
|
40007
|
-
return change.apply(this, args);
|
|
40008
|
-
};
|
|
40009
|
-
this._handleInteraction = groupWidgetId => {
|
|
40010
|
-
const step = parseInt(groupWidgetId.split(" ")[1]);
|
|
40011
|
-
if (step === this.state.visible - 1) {
|
|
40012
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40013
|
-
// @ts-expect-error - TS2339 - Property 'getWidgetInstance' does not exist on type 'ReactInstance'.
|
|
40014
|
-
const widget = this.refs.renderer.getWidgetInstance("group " + step);
|
|
40015
|
-
widget.showRationalesForCurrentlySelectedChoices();
|
|
40016
|
-
const score = widget.simpleValidate();
|
|
40017
|
-
if (score.type === "points" && score.total === score.earned) {
|
|
40018
|
-
this.setState({
|
|
40019
|
-
visible: this.state.visible + 1
|
|
40020
|
-
});
|
|
40021
|
-
this.props.trackInteraction({
|
|
40022
|
-
visible: this.state.visible + 1
|
|
40023
|
-
});
|
|
40024
|
-
}
|
|
40025
|
-
}
|
|
40026
|
-
};
|
|
40027
|
-
}
|
|
40028
|
-
shouldComponentUpdate(nextProps, nextState) {
|
|
40029
|
-
return nextProps !== this.props || nextState !== this.state;
|
|
40030
|
-
}
|
|
40031
|
-
render() {
|
|
40032
|
-
const icon = /*#__PURE__*/React.createElement(InlineIcon, _extends({}, iconOk, {
|
|
40033
|
-
style: {
|
|
40034
|
-
color: "green"
|
|
40035
|
-
}
|
|
40036
|
-
}));
|
|
40037
|
-
const content = _.chain(this.props.json).first(this.state.visible).map((step, i) => `[[${Util.snowman} group ${i}]]`).join("\n\n").value();
|
|
40038
|
-
const widgets = {};
|
|
40039
|
-
_.each(this.props.json, (step, i) => {
|
|
40040
|
-
const widgetId = `group ${i}`;
|
|
40041
|
-
widgets[widgetId] = {
|
|
40042
|
-
type: "group",
|
|
40043
|
-
graded: true,
|
|
40044
|
-
version: {
|
|
40045
|
-
major: 0,
|
|
40046
|
-
minor: 0
|
|
40047
|
-
},
|
|
40048
|
-
options: _.extend({}, step, {
|
|
40049
|
-
icon: i < this.state.visible - 1 ? icon : null
|
|
40050
|
-
})
|
|
40051
|
-
};
|
|
40052
|
-
});
|
|
40053
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
40054
|
-
className: "perseus-sequence"
|
|
40055
|
-
}, /*#__PURE__*/React.createElement(Renderer
|
|
40056
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40057
|
-
, {
|
|
40058
|
-
ref: "renderer",
|
|
40059
|
-
content: content,
|
|
40060
|
-
widgets: widgets,
|
|
40061
|
-
onInteractWithWidget: this._handleInteraction,
|
|
40062
|
-
apiOptions: this.props.apiOptions,
|
|
40063
|
-
linterContext: this.props.linterContext
|
|
40064
|
-
}));
|
|
40065
|
-
}
|
|
40066
|
-
}
|
|
40067
|
-
Sequence.defaultProps = {
|
|
40068
|
-
json: [{
|
|
40069
|
-
content: "",
|
|
40070
|
-
widgets: {},
|
|
40071
|
-
images: {}
|
|
40072
|
-
}],
|
|
40073
|
-
linterContext: linterContextDefault
|
|
40074
|
-
};
|
|
40075
|
-
const traverseChildWidgets = function traverseChildWidgets(props, traverseRenderer) {
|
|
40076
|
-
let oldJson = props.json;
|
|
40077
|
-
if (!_.isArray(oldJson)) {
|
|
40078
|
-
oldJson = [oldJson];
|
|
40079
|
-
}
|
|
40080
|
-
const json = _.map(oldJson, rendererOptions => {
|
|
40081
|
-
return traverseRenderer(rendererOptions);
|
|
40082
|
-
});
|
|
40083
|
-
return _.extend({}, props, {
|
|
40084
|
-
json: json
|
|
40085
|
-
});
|
|
40086
|
-
};
|
|
40087
|
-
var Sequence$1 = {
|
|
40088
|
-
name: "sequence",
|
|
40089
|
-
displayName: "Graded sequence (deprecated)",
|
|
40090
|
-
widget: Sequence,
|
|
40091
|
-
traverseChildWidgets: traverseChildWidgets,
|
|
40092
|
-
tracking: "all",
|
|
40093
|
-
hidden: true,
|
|
40094
|
-
isLintable: true
|
|
40095
|
-
};
|
|
40096
|
-
|
|
40097
|
-
const {
|
|
40098
|
-
assert: assert$1
|
|
40099
|
-
} = InteractiveUtil;
|
|
40100
|
-
// @ts-expect-error - TS2339 - Property 'Path' does not exist on type 'typeof Graphie'. | TS2339 - Property 'Arc' does not exist on type 'typeof Graphie'. | TS2339 - Property 'Circle' does not exist on type 'typeof Graphie'. | TS2339 - Property 'Label' does not exist on type 'typeof Graphie'. | TS2339 - Property 'Line' does not exist on type 'typeof Graphie'. | TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'. | TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
|
|
40101
|
-
const {
|
|
40102
|
-
Path,
|
|
40103
|
-
Arc,
|
|
40104
|
-
Circle,
|
|
40105
|
-
Label,
|
|
40106
|
-
Line,
|
|
40107
|
-
MovablePoint,
|
|
40108
|
-
MovableLine
|
|
40109
|
-
} = Graphie;
|
|
40110
|
-
const defaultBoxSize = 400;
|
|
40111
|
-
const maxSampleSize = 1000;
|
|
40112
|
-
class Histogram extends React.Component {
|
|
40113
|
-
constructor(...args) {
|
|
40114
|
-
super(...args);
|
|
40115
|
-
/* Renders the vertical line that users can drag across the histogram. */
|
|
40116
|
-
this._renderThresholdLine = () => {
|
|
40117
|
-
// Recall the the y-range goes from [-1, yMax] to allow for ticks on
|
|
40118
|
-
// the x-axis.
|
|
40119
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40120
|
-
const yRange = [0, this._range()[1][1]];
|
|
40121
|
-
const coords = _.map(yRange, y => [this.state.threshold, y]);
|
|
40122
|
-
|
|
40123
|
-
// Returns an inivisble, placeholder coord that anchors the line
|
|
40124
|
-
const invisiblePointForCoord = (coord, i) => {
|
|
40125
|
-
return /*#__PURE__*/React.createElement(MovablePoint, {
|
|
40126
|
-
key: i,
|
|
40127
|
-
static: true,
|
|
40128
|
-
coord: coord,
|
|
40129
|
-
normalStyle: {
|
|
40130
|
-
stroke: "none",
|
|
40131
|
-
fill: "none"
|
|
40132
|
-
}
|
|
40133
|
-
});
|
|
40134
|
-
};
|
|
40135
|
-
return /*#__PURE__*/React.createElement(MovableLine, {
|
|
40136
|
-
onMove: this.handleMouseInteraction
|
|
40137
|
-
}, _.map(coords, invisiblePointForCoord));
|
|
40138
|
-
};
|
|
40139
|
-
/* Renders the shaded circle in the top right. */
|
|
40140
|
-
this._renderCircle = () => {
|
|
40141
|
-
const data = this.props.data;
|
|
40142
|
-
|
|
40143
|
-
// Get proportion of results below threshold
|
|
40144
|
-
const total = _.reduce(data, (sum, next) => {
|
|
40145
|
-
return sum + next;
|
|
40146
|
-
}, 0);
|
|
40147
|
-
const numBelow = _.reduce(data, (sum, next, i) => {
|
|
40148
|
-
if (this.state.threshold != null && i <= this.state.threshold) {
|
|
40149
|
-
return sum + next;
|
|
40150
|
-
}
|
|
40151
|
-
return sum;
|
|
40152
|
-
}, 0);
|
|
40153
|
-
const proportionBelow = numBelow / total;
|
|
40154
|
-
|
|
40155
|
-
// This is a hack around the arc taking angles modulo 360.
|
|
40156
|
-
// TODO(charlie): Find a better way around this.
|
|
40157
|
-
const epsilon = 1e-5;
|
|
40158
|
-
const radius = 20;
|
|
40159
|
-
const center = [this.props.box[0] - 1.5 * radius, 1.5 * radius];
|
|
40160
|
-
|
|
40161
|
-
// Plot little circle
|
|
40162
|
-
const plotBelowCircle = () => {
|
|
40163
|
-
const options = {
|
|
40164
|
-
key: "below",
|
|
40165
|
-
center: center,
|
|
40166
|
-
radius: radius,
|
|
40167
|
-
startAngle: 0,
|
|
40168
|
-
endAngle: proportionBelow < 1 ? 360 * proportionBelow : 360 - epsilon,
|
|
40169
|
-
sector: proportionBelow !== 1,
|
|
40170
|
-
unscaled: true,
|
|
40171
|
-
style: {
|
|
40172
|
-
fill: KhanColors.LIGHT_RED,
|
|
40173
|
-
stroke: KhanColors.RED
|
|
40174
|
-
}
|
|
40175
|
-
};
|
|
40176
|
-
return /*#__PURE__*/React.createElement(Arc, options);
|
|
40177
|
-
};
|
|
40178
|
-
const plotAboveCircle = () => {
|
|
40179
|
-
const options = {
|
|
40180
|
-
key: "above",
|
|
40181
|
-
center: center,
|
|
40182
|
-
radius: radius,
|
|
40183
|
-
startAngle: proportionBelow > 0 ? 360 * proportionBelow : epsilon,
|
|
40184
|
-
endAngle: 360,
|
|
40185
|
-
sector: proportionBelow !== 0,
|
|
40186
|
-
unscaled: true,
|
|
40187
|
-
style: {
|
|
40188
|
-
fill: KhanColors.LIGHT_BLUE,
|
|
40189
|
-
stroke: KhanColors.BLUE
|
|
40190
|
-
}
|
|
40191
|
-
};
|
|
40192
|
-
return /*#__PURE__*/React.createElement(Arc, options);
|
|
40193
|
-
};
|
|
40194
|
-
|
|
40195
|
-
// Plot the label below the circle
|
|
40196
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40197
|
-
const xRange = this._range()[0];
|
|
40198
|
-
const formattedThreshold = Math.min(Math.max(this.state.threshold, xRange[0]), xRange[1]).toFixed(2);
|
|
40199
|
-
const plotLabel = () => {
|
|
40200
|
-
const options = {
|
|
40201
|
-
key: "label",
|
|
40202
|
-
coord: [center[0], center[1] + 1.5 * radius],
|
|
40203
|
-
text: numBelow + " of " + total + " results below " + formattedThreshold + "%",
|
|
40204
|
-
direction: "center",
|
|
40205
|
-
tex: false,
|
|
40206
|
-
unscaled: true,
|
|
40207
|
-
style: {
|
|
40208
|
-
fontSize: "12px"
|
|
40209
|
-
}
|
|
40210
|
-
};
|
|
40211
|
-
return /*#__PURE__*/React.createElement(Label, options);
|
|
40212
|
-
};
|
|
40213
|
-
return [proportionBelow > 0 && plotBelowCircle(), proportionBelow < 1 && plotAboveCircle(), plotLabel()];
|
|
40214
|
-
};
|
|
40215
|
-
/* Renders the actual bars of the histogram. */
|
|
40216
|
-
this._renderData = () => {
|
|
40217
|
-
const data = this.props.data;
|
|
40218
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40219
|
-
this._range();
|
|
40220
|
-
|
|
40221
|
-
// Plot bars
|
|
40222
|
-
const barWidth = 1;
|
|
40223
|
-
const pathForData = (count, i) => {
|
|
40224
|
-
// Avoid plotting bars of height 0, else you get a thick blue line
|
|
40225
|
-
// over the x-axis. We don't filter these out of the data passed in
|
|
40226
|
-
// to this function, however, to preserve absolute indices.
|
|
40227
|
-
if (!count) {
|
|
40228
|
-
return;
|
|
40229
|
-
}
|
|
40230
|
-
const isBelow = this.state.threshold != null && i <= this.state.threshold;
|
|
40231
|
-
const style = {
|
|
40232
|
-
fill: isBelow ? KhanColors.LIGHT_RED : KhanColors.LIGHT_BLUE,
|
|
40233
|
-
stroke: isBelow ? KhanColors.RED : KhanColors.BLUE
|
|
40234
|
-
};
|
|
40235
|
-
const coords = [[i, 0], [i, count], [i + barWidth, count], [i + barWidth, 0]];
|
|
40236
|
-
return /*#__PURE__*/React.createElement(Path, {
|
|
40237
|
-
key: i,
|
|
40238
|
-
coords: coords,
|
|
40239
|
-
style: style
|
|
40240
|
-
});
|
|
40241
|
-
};
|
|
40242
|
-
return _.map(data, pathForData);
|
|
40243
|
-
};
|
|
40244
|
-
this._setupGraphie = (graphie, options) => {
|
|
40245
|
-
const data = options.data;
|
|
40246
|
-
const range = options.range;
|
|
40247
|
-
const scale = options.scale;
|
|
40248
|
-
|
|
40249
|
-
/* Plot the bars that run parallel to the x-axis. */
|
|
40250
|
-
const xWidth = range[0][1] - range[0][0];
|
|
40251
|
-
const yWidth = range[1][1] - 0;
|
|
40252
|
-
const maxYAxisEntities = 20;
|
|
40253
|
-
const ySkip = Math.ceil(yWidth / maxYAxisEntities);
|
|
40254
|
-
_.each(_.range(0, range[1][1], ySkip), y => {
|
|
40255
|
-
// If there's no data, we don't label the axes
|
|
40256
|
-
if (data) {
|
|
40257
|
-
graphie.label([range[0][0], y], KhanMath.roundToApprox(y, 2), "left", /* isTeX */true /* for the \approx symbol */);
|
|
40258
|
-
}
|
|
40259
|
-
|
|
40260
|
-
graphie.line([range[0][0], y], [range[0][1], y], {
|
|
40261
|
-
stroke: "#000",
|
|
40262
|
-
strokeWidth: 1,
|
|
40263
|
-
opacity: 0.3
|
|
40264
|
-
});
|
|
40265
|
-
});
|
|
40266
|
-
|
|
40267
|
-
// If there's no data, we don't label the x-axis at all
|
|
40268
|
-
if (data) {
|
|
40269
|
-
// Plot the labels below the bars
|
|
40270
|
-
const maxXAxisEntities = 15;
|
|
40271
|
-
const xSkip = Math.ceil(xWidth / maxXAxisEntities);
|
|
40272
|
-
_.each(_.range(range[0][0], range[0][1], xSkip), x => {
|
|
40273
|
-
graphie.label([x, 0], number.round(x, 2), "below", true);
|
|
40274
|
-
const tickHeight = 8;
|
|
40275
|
-
graphie.line([x, 0], [x, -tickHeight / scale[1]], {
|
|
40276
|
-
stroke: "#000",
|
|
40277
|
-
strokeWidth: 1
|
|
40278
|
-
});
|
|
40279
|
-
});
|
|
40280
|
-
}
|
|
40281
|
-
|
|
40282
|
-
// Add y axis (x axis is added later to overlap the bars)
|
|
40283
|
-
const axisStyle = {
|
|
40284
|
-
stroke: "#000",
|
|
40285
|
-
strokeWidth: 2,
|
|
40286
|
-
opacity: 1.0
|
|
40287
|
-
};
|
|
40288
|
-
const origin = [range[0][0], 0];
|
|
40289
|
-
const topLeft = [range[0][0], range[1][1]];
|
|
40290
|
-
graphie.line(origin, topLeft, axisStyle);
|
|
40291
|
-
|
|
40292
|
-
// Add axis labels
|
|
40293
|
-
const xMid = range[0][0] + xWidth / 2;
|
|
40294
|
-
const xOffset = data ? 25 : 0;
|
|
40295
|
-
graphie.label([xMid, -xOffset / scale[1]], options.xAxisLabel, "below", false).css("font-weight", "bold");
|
|
40296
|
-
const yMid = 0 + yWidth / 2;
|
|
40297
|
-
const yOffset = data ? 55 : 28;
|
|
40298
|
-
graphie.label([range[0][0] - yOffset / scale[0], yMid], options.yAxisLabel, "center", false).css("font-weight", "bold").css("-webkit-transform", "rotate(-90deg)");
|
|
40299
|
-
};
|
|
40300
|
-
this.handleMouseInteraction = point => {
|
|
40301
|
-
this.setState({
|
|
40302
|
-
threshold: point[0]
|
|
40303
|
-
});
|
|
40304
|
-
};
|
|
40305
|
-
/* Convenience functions that help calculate props based on other props. */
|
|
40306
|
-
this._range = props => {
|
|
40307
|
-
const defaultRange = [[0, 100], [-1, 10]];
|
|
40308
|
-
props = props || this.props;
|
|
40309
|
-
return props.data ? this._getRangeForData(props.data) : defaultRange;
|
|
40310
|
-
};
|
|
40311
|
-
this._getRangeForData = data => {
|
|
40312
|
-
// Find first/last non-zero entry and add some padding
|
|
40313
|
-
const padding = 10;
|
|
40314
|
-
const firstIndex = _.indexOf(data, _.find(data, n => n > 0));
|
|
40315
|
-
const xMin = Math.max(0, firstIndex - padding);
|
|
40316
|
-
const lastIndex = _.lastIndexOf(data, _.last(_.filter(data, n => n > 0)));
|
|
40317
|
-
const xMax = Math.min(100 + 1, lastIndex + 1 + padding);
|
|
40318
|
-
|
|
40319
|
-
// The y-axis is bounded above by largest value, and below by 0.
|
|
40320
|
-
// However, the 'range' of the y-axis goes as low as -1 to allow
|
|
40321
|
-
// Graphie to draw ticks on the x-Axis that extend vertically below
|
|
40322
|
-
// y = 0.
|
|
40323
|
-
const yMin = -1;
|
|
40324
|
-
const yMax = _.max(data);
|
|
40325
|
-
return [[xMin, xMax], [yMin, yMax]];
|
|
40326
|
-
};
|
|
40327
|
-
this._getInitialThreshold = range => {
|
|
40328
|
-
// We pick a pretty-looking threshold, 1/3 of the way along the axis
|
|
40329
|
-
const xRange = range[0];
|
|
40330
|
-
return xRange[0] + (xRange[1] - xRange[0]) / 3;
|
|
40331
|
-
};
|
|
40332
|
-
this.state = {
|
|
40333
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40334
|
-
threshold: this._getInitialThreshold(this._range())
|
|
40335
|
-
};
|
|
40336
|
-
}
|
|
40337
|
-
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
40338
|
-
// Reset the threshold if the range has changed
|
|
40339
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40340
|
-
const oldRange = this._range();
|
|
40341
|
-
const nextRange = this._range(nextProps);
|
|
40342
|
-
if (!Util.deepEq(oldRange, nextRange)) {
|
|
40343
|
-
this.setState({
|
|
40344
|
-
threshold: this._getInitialThreshold(nextRange)
|
|
40345
|
-
});
|
|
40346
|
-
}
|
|
40347
|
-
}
|
|
40348
|
-
render() {
|
|
40349
|
-
const data = this.props.data;
|
|
40350
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40351
|
-
const range = this._range();
|
|
40352
|
-
const options = {
|
|
40353
|
-
xAxisLabel: this.props.xAxisLabel,
|
|
40354
|
-
yAxisLabel: this.props.yAxisLabel,
|
|
40355
|
-
box: this.props.box,
|
|
40356
|
-
range: range,
|
|
40357
|
-
data: data,
|
|
40358
|
-
scale: [Util.scaleFromExtent(range[0], this.props.box[0]), Util.scaleFromExtent(range[1], this.props.box[1])]
|
|
40359
|
-
};
|
|
40360
|
-
const axisStyle = {
|
|
40361
|
-
stroke: "#000",
|
|
40362
|
-
strokeWidth: 1,
|
|
40363
|
-
opacity: 1.0
|
|
40364
|
-
};
|
|
40365
|
-
const origin = [range[0][0], 0];
|
|
40366
|
-
const bottomRight = [range[0][1], 0];
|
|
40367
|
-
return /*#__PURE__*/React.createElement(Graphie, {
|
|
40368
|
-
box: options.box,
|
|
40369
|
-
range: options.range,
|
|
40370
|
-
options: options,
|
|
40371
|
-
setup: this._setupGraphie,
|
|
40372
|
-
onMouseMove: this.handleMouseInteraction,
|
|
40373
|
-
onMouseDown: this.handleMouseInteraction,
|
|
40374
|
-
setDrawingAreaAvailable: this.props.setDrawingAreaAvailable
|
|
40375
|
-
}, /*#__PURE__*/React.createElement(Line, {
|
|
40376
|
-
start: origin,
|
|
40377
|
-
end: bottomRight,
|
|
40378
|
-
style: axisStyle
|
|
40379
|
-
}), data && this._renderData(), data && this._renderCircle(), data && this._renderThresholdLine());
|
|
40380
|
-
}
|
|
40381
|
-
}
|
|
40382
|
-
Histogram.propTypes = {
|
|
40383
|
-
data: PropTypes.arrayOf(PropTypes.number),
|
|
40384
|
-
xAxisLabel: PropTypes.string,
|
|
40385
|
-
yAxisLabel: PropTypes.string,
|
|
40386
|
-
box: PropTypes.arrayOf(PropTypes.number)
|
|
40387
|
-
};
|
|
40388
|
-
Histogram.defaultProps = {
|
|
40389
|
-
data: null,
|
|
40390
|
-
xAxisLabel: "Proportion (%)",
|
|
40391
|
-
yAxisLabel: "Number of times seen",
|
|
40392
|
-
box: [defaultBoxSize, defaultBoxSize]
|
|
40393
|
-
};
|
|
40394
|
-
class Simulator extends React.Component {
|
|
40395
|
-
constructor(..._args) {
|
|
40396
|
-
super(..._args);
|
|
40397
|
-
// @ts-expect-error - TS2564 - Property 'generateNumber' has no initializer and is not definitely assigned in the constructor.
|
|
40398
|
-
this.generateNumber = void 0;
|
|
40399
|
-
this.state = {
|
|
40400
|
-
invalidInput: false
|
|
40401
|
-
};
|
|
40402
|
-
this.calculateDisplayProportion = () => {
|
|
40403
|
-
const userProportion = this.props.userProportion;
|
|
40404
|
-
|
|
40405
|
-
// If we want to display as a percentage, multiply proportion by 100.0.
|
|
40406
|
-
if (this.props.proportionOrPercentage === "percentage") {
|
|
40407
|
-
return Math.round(100 * userProportion);
|
|
40408
|
-
}
|
|
40409
|
-
return userProportion;
|
|
40410
|
-
};
|
|
40411
|
-
this.change = (...args) => {
|
|
40412
|
-
// @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
|
|
40413
|
-
return change.apply(this, args);
|
|
40414
|
-
};
|
|
40415
|
-
this.checkProportionValidity = value => {
|
|
40416
|
-
return value >= 0.0 && this.props.proportionOrPercentage === "proportion" && value <= 1.0 || this.props.proportionOrPercentage === "percentage" && value <= 100.0;
|
|
40417
|
-
};
|
|
40418
|
-
this.handleUserProportionChange = (value, cb) => {
|
|
40419
|
-
let userProportion;
|
|
40420
|
-
|
|
40421
|
-
// If "percentage" mode is enabled, user will have entered value as
|
|
40422
|
-
// a percentage. However, we always store as a proportion, so we cast.
|
|
40423
|
-
if (this.props.proportionOrPercentage === "percentage") {
|
|
40424
|
-
userProportion = value / 100.0;
|
|
40425
|
-
} else {
|
|
40426
|
-
userProportion = value;
|
|
40427
|
-
}
|
|
40428
|
-
|
|
40429
|
-
// If they entered a number, we may need to cap it
|
|
40430
|
-
if (userProportion != null) {
|
|
40431
|
-
userProportion = Math.min(1.0, Math.max(0.0, userProportion));
|
|
40432
|
-
}
|
|
40433
|
-
this.props.onChange({
|
|
40434
|
-
userProportion: userProportion
|
|
40435
|
-
}, cb);
|
|
40436
|
-
};
|
|
40437
|
-
// @ts-expect-error - TS2322 - Type '(sampleSize: any, cb: any) => void' is not assignable to type '(number: any) => void'.
|
|
40438
|
-
this.handleSampleSizeChange = (sampleSize, cb) => {
|
|
40439
|
-
if (sampleSize != null) {
|
|
40440
|
-
sampleSize = Math.min(maxSampleSize, Math.max(0, Math.floor(sampleSize)));
|
|
40441
|
-
}
|
|
40442
|
-
this.props.onChange({
|
|
40443
|
-
sampleSize: sampleSize
|
|
40444
|
-
}, cb);
|
|
40445
|
-
};
|
|
40446
|
-
this.handleRunSimulation = () => {
|
|
40447
|
-
// If they haven't filled out a parameter field, highlight it.
|
|
40448
|
-
if (this.props.numTrials == null || this.props.userProportion == null || this.props.sampleSize == null) {
|
|
40449
|
-
this.setState({
|
|
40450
|
-
invalidInput: true
|
|
40451
|
-
});
|
|
40452
|
-
return;
|
|
40453
|
-
}
|
|
40454
|
-
this.setState({
|
|
40455
|
-
invalidInput: false
|
|
40456
|
-
});
|
|
40457
|
-
this.props.onChange({
|
|
40458
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40459
|
-
data: this.generateData()
|
|
40460
|
-
});
|
|
40461
|
-
this.props.trackInteraction();
|
|
40462
|
-
};
|
|
40463
|
-
this.generateData = props => {
|
|
40464
|
-
props = props || this.props;
|
|
40465
|
-
const getSampleDistribution = (sampleSize, numTrials, proportion) => {
|
|
40466
|
-
const draw = () => {
|
|
40467
|
-
return this.generateNumber() < proportion;
|
|
40468
|
-
};
|
|
40469
|
-
const sampleDistribution = _.times(100 + 1, () => 0);
|
|
40470
|
-
_.times(numTrials, () => {
|
|
40471
|
-
const results = _.times(sampleSize, draw);
|
|
40472
|
-
const count = _.filter(results, _.identity).length;
|
|
40473
|
-
const normalizedCount = Math.floor(100 * count / sampleSize);
|
|
40474
|
-
sampleDistribution[normalizedCount]++;
|
|
40475
|
-
});
|
|
40476
|
-
return sampleDistribution;
|
|
40477
|
-
};
|
|
40478
|
-
return getSampleDistribution(props.sampleSize, props.numTrials, props.userProportion);
|
|
40479
|
-
};
|
|
40480
|
-
/* InputPath API */
|
|
40481
|
-
this.getInputPaths = () => {
|
|
40482
|
-
return [["userProportion"], ["sampleSize"]];
|
|
40483
|
-
};
|
|
40484
|
-
this.focus = () => {
|
|
40485
|
-
const path = _.head(this.getInputPaths());
|
|
40486
|
-
this.focusInputPath(path);
|
|
40487
|
-
return true;
|
|
40488
|
-
};
|
|
40489
|
-
this.focusInputPath = path => {
|
|
40490
|
-
assert$1(path.length > 0);
|
|
40491
|
-
const inputID = _.head(path);
|
|
40492
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40493
|
-
const inputComponent = this.refs[inputID];
|
|
40494
|
-
// @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
|
|
40495
|
-
inputComponent.focus();
|
|
40496
|
-
};
|
|
40497
|
-
this.blurInputPath = path => {
|
|
40498
|
-
assert$1(path.length > 0);
|
|
40499
|
-
const inputID = _.head(path);
|
|
40500
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40501
|
-
const inputComponent = this.refs[inputID];
|
|
40502
|
-
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
40503
|
-
inputComponent.blur();
|
|
40504
|
-
};
|
|
40505
|
-
this.getDOMNodeForPath = path => {
|
|
40506
|
-
assert$1(path.length > 0);
|
|
40507
|
-
const inputID = _.head(path);
|
|
40508
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40509
|
-
return ReactDOM__default.findDOMNode(this.refs[inputID]);
|
|
40510
|
-
};
|
|
40511
|
-
this.getGrammarTypeForPath = path => {
|
|
40512
|
-
assert$1(path.length > 0);
|
|
40513
|
-
return "number";
|
|
40514
|
-
};
|
|
40515
|
-
this.setInputValue = (path, newValue, cb) => {
|
|
40516
|
-
assert$1(path.length > 0);
|
|
40517
|
-
const inputID = _.head(path);
|
|
40518
|
-
const capitalizedID = inputID.charAt(0).toUpperCase() + inputID.slice(1);
|
|
40519
|
-
const functionName = "handle" + capitalizedID + "Change";
|
|
40520
|
-
this[functionName](newValue, cb);
|
|
40521
|
-
};
|
|
40522
|
-
this.getUserInput = () => {
|
|
40523
|
-
return null;
|
|
40524
|
-
};
|
|
40525
|
-
this.simpleValidate = rubric => {
|
|
40526
|
-
// @ts-expect-error - TS2339 - Property 'validate' does not exist on type 'typeof Simulator'.
|
|
40527
|
-
return Simulator.validate(this.getUserInput(), rubric);
|
|
40528
|
-
};
|
|
40529
|
-
}
|
|
40530
|
-
// TODO(jangmi, CP-3288): Remove usage of `UNSAFE_componentWillMount`
|
|
40531
|
-
UNSAFE_componentWillMount() {
|
|
40532
|
-
if (this.props.randomSeed != null) {
|
|
40533
|
-
this.generateNumber = Util.seededRNG(this.props.randomSeed);
|
|
40534
|
-
}
|
|
40535
|
-
}
|
|
40536
|
-
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
40537
|
-
if (nextProps.randomSeed !== this.props.randomSeed) {
|
|
40538
|
-
this.generateNumber = Util.seededRNG(nextProps.randomSeed);
|
|
40539
|
-
}
|
|
40540
|
-
}
|
|
40541
|
-
render() {
|
|
40542
|
-
const inputStyle = {
|
|
40543
|
-
marginLeft: "5px"
|
|
40544
|
-
};
|
|
40545
|
-
const highlight = "0px 0px 0px 2px rgba(255, 165, 0, 1)";
|
|
40546
|
-
const highlightStyle = _.extend({}, inputStyle, {
|
|
40547
|
-
boxShadow: highlight,
|
|
40548
|
-
transition: "all 0.15s"
|
|
40549
|
-
});
|
|
40550
|
-
const unhighlightStyle = _.extend({}, inputStyle, {
|
|
40551
|
-
transition: "all 0.15s"
|
|
40552
|
-
});
|
|
40553
|
-
const style = this.state.invalidInput ? highlightStyle : unhighlightStyle;
|
|
40554
|
-
const proportionInput = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(NumberInput
|
|
40555
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40556
|
-
, {
|
|
40557
|
-
ref: "userProportion",
|
|
40558
|
-
style: style,
|
|
40559
|
-
value: this.calculateDisplayProportion(),
|
|
40560
|
-
checkValidity: this.checkProportionValidity,
|
|
40561
|
-
disabled: this.props.apiOptions.readOnly,
|
|
40562
|
-
onChange: this.handleUserProportionChange,
|
|
40563
|
-
onFocus: () => this.props.onFocus(["userProportion"]),
|
|
40564
|
-
onBlur: () => this.props.onBlur(["userProportion"])
|
|
40565
|
-
}), /*#__PURE__*/React.createElement(InfoTip, null, /*#__PURE__*/React.createElement("p", null, i18n._("This controls the proportion or percentage that will be used in your simulation."))));
|
|
40566
|
-
const sampleSizeInput = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(NumberInput
|
|
40567
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40568
|
-
, {
|
|
40569
|
-
ref: "sampleSize",
|
|
40570
|
-
style: style,
|
|
40571
|
-
value: this.props.sampleSize,
|
|
40572
|
-
checkValidity: val => val >= 0,
|
|
40573
|
-
disabled: this.props.apiOptions.readOnly,
|
|
40574
|
-
onChange: this.handleSampleSizeChange,
|
|
40575
|
-
onFocus: () => this.props.onFocus(["sampleSize"]),
|
|
40576
|
-
onBlur: () => this.props.onBlur(["sampleSize"])
|
|
40577
|
-
}), /*#__PURE__*/React.createElement(InfoTip, null, /*#__PURE__*/React.createElement("p", null, i18n._("This controls the sample size that will be used in your simulation. For example, if you set this to 100, then for each trial, responses from 100 participants will be simulated."))));
|
|
40578
|
-
const numTrialsDisplay = /*#__PURE__*/React.createElement("div", {
|
|
40579
|
-
style: {
|
|
40580
|
-
textAlign: "right"
|
|
40581
|
-
}
|
|
40582
|
-
}, /*#__PURE__*/React.createElement("b", null, this.props.numTrials), /*#__PURE__*/React.createElement(InfoTip, null, /*#__PURE__*/React.createElement("p", null, i18n._("This is the number of trials used in the simulation. For example, if set to 50, then the survey will be conducted 50 times."))));
|
|
40583
|
-
|
|
40584
|
-
// Generates a table from a set of titles and values.
|
|
40585
|
-
const generateTable = contents => {
|
|
40586
|
-
const header = /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, i18n._("Parameter")), /*#__PURE__*/React.createElement("th", null, i18n._("Value"))));
|
|
40587
|
-
const body = /*#__PURE__*/React.createElement("tbody", null, _.map(contents, (row, i) => {
|
|
40588
|
-
return /*#__PURE__*/React.createElement("tr", {
|
|
40589
|
-
key: i
|
|
40590
|
-
}, /*#__PURE__*/React.createElement("td", null, row.title), /*#__PURE__*/React.createElement("td", null, row.value));
|
|
40591
|
-
}));
|
|
40592
|
-
return /*#__PURE__*/React.createElement("table", null, header, body);
|
|
40593
|
-
};
|
|
40594
|
-
|
|
40595
|
-
// Contents for the table to-be generated
|
|
40596
|
-
const contents = [{
|
|
40597
|
-
title: this.props.proportionLabel + ":",
|
|
40598
|
-
value: proportionInput
|
|
40599
|
-
}, {
|
|
40600
|
-
title: i18n._("Sample size:"),
|
|
40601
|
-
value: sampleSizeInput
|
|
40602
|
-
}, {
|
|
40603
|
-
title: i18n._("Number of trials:"),
|
|
40604
|
-
value: numTrialsDisplay
|
|
40605
|
-
}];
|
|
40606
|
-
|
|
40607
|
-
// The 'Run Simulation' button
|
|
40608
|
-
const buttonStyle = {
|
|
40609
|
-
margin: "20px 0"
|
|
40610
|
-
};
|
|
40611
|
-
const startButton = /*#__PURE__*/React.createElement("button", {
|
|
40612
|
-
className: "simple-button",
|
|
40613
|
-
style: buttonStyle,
|
|
40614
|
-
disabled: this.props.apiOptions.readOnly,
|
|
40615
|
-
onClick: this.handleRunSimulation
|
|
40616
|
-
}, i18n._("Run simulation"));
|
|
40617
|
-
|
|
40618
|
-
// When we plot data, ticks on the x-axis require some vertical padding
|
|
40619
|
-
const histogramStyle = {
|
|
40620
|
-
paddingBottom: this.props.data ? 40 : 0
|
|
40621
|
-
};
|
|
40622
|
-
const histogram = /*#__PURE__*/React.createElement("div", {
|
|
40623
|
-
style: histogramStyle
|
|
40624
|
-
}, /*#__PURE__*/React.createElement(Histogram, {
|
|
40625
|
-
data: this.props.data,
|
|
40626
|
-
xAxisLabel: this.props.xAxisLabel,
|
|
40627
|
-
yAxisLabel: this.props.yAxisLabel,
|
|
40628
|
-
setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
|
|
40629
|
-
}));
|
|
40630
|
-
return /*#__PURE__*/React.createElement("div", null, generateTable(contents), startButton, histogram);
|
|
40631
|
-
}
|
|
40632
|
-
}
|
|
40633
|
-
Simulator.propTypes = _extends({}, propTypes, {
|
|
40634
|
-
apiOptions: ApiOptions.propTypes,
|
|
40635
|
-
data: PropTypes.arrayOf(PropTypes.number),
|
|
40636
|
-
numTrials: PropTypes.number,
|
|
40637
|
-
proportionLabel: PropTypes.string,
|
|
40638
|
-
proportionOrPercentage: PropTypes.string,
|
|
40639
|
-
randomSeed: PropTypes.number,
|
|
40640
|
-
sampleSize: PropTypes.number,
|
|
40641
|
-
trackInteraction: PropTypes.func.isRequired,
|
|
40642
|
-
userProportion: PropTypes.number,
|
|
40643
|
-
xAxisLabel: PropTypes.string,
|
|
40644
|
-
yAxisLabel: PropTypes.string
|
|
40645
|
-
});
|
|
40646
|
-
Simulator.defaultProps = {
|
|
40647
|
-
data: null,
|
|
40648
|
-
userProportion: null,
|
|
40649
|
-
sampleSize: null,
|
|
40650
|
-
numTrials: null,
|
|
40651
|
-
randomSeed: 0,
|
|
40652
|
-
xAxisLabel: "Proportion (%)",
|
|
40653
|
-
yAxisLabel: "Number of times seen",
|
|
40654
|
-
proportionLabel: "Underlying proportion",
|
|
40655
|
-
proportionOrPercentage: "proportion",
|
|
40656
|
-
apiOptions: ApiOptions.defaults
|
|
40657
|
-
};
|
|
40658
|
-
_.extend(Simulator, {
|
|
40659
|
-
validate: function (state, rubric) {
|
|
40660
|
-
return {
|
|
40661
|
-
type: "points",
|
|
40662
|
-
earned: 0,
|
|
40663
|
-
total: 0,
|
|
40664
|
-
message: null
|
|
40665
|
-
};
|
|
40666
|
-
}
|
|
40667
|
-
});
|
|
40668
|
-
const propTransform$1 = editorProps => {
|
|
40669
|
-
const widgetProps = _.clone(editorProps);
|
|
40670
|
-
widgetProps.randomSeed = editorProps.problemNum;
|
|
40671
|
-
return widgetProps;
|
|
40672
|
-
};
|
|
40673
|
-
var Simulator$1 = {
|
|
40674
|
-
name: "simulator",
|
|
40675
|
-
displayName: "Simulator (deprecated)",
|
|
40676
|
-
widget: Simulator,
|
|
40677
|
-
transform: propTransform$1,
|
|
40678
|
-
hidden: true
|
|
40679
|
-
};
|
|
40680
|
-
|
|
40681
39630
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
40682
39631
|
const {
|
|
40683
39632
|
shuffle
|
|
@@ -42178,7 +41127,7 @@ var Video$1 = {
|
|
|
42178
41127
|
};
|
|
42179
41128
|
|
|
42180
41129
|
/* eslint-disable import/no-named-as-default */
|
|
42181
|
-
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,
|
|
41130
|
+
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, Unit, Video$1, DeprecatedStandin$1];
|
|
42182
41131
|
|
|
42183
41132
|
/**
|
|
42184
41133
|
* This should be called by all clients, specifying whether extra widgets are
|
|
@@ -42192,7 +41141,7 @@ var extraWidgets = [Categorizer$1, CSProgram$1, Dropdown$1, Explanation$1, Defin
|
|
|
42192
41141
|
const init = function init(options) {
|
|
42193
41142
|
registerWidgets(basicWidgets);
|
|
42194
41143
|
registerWidgets(extraWidgets);
|
|
42195
|
-
|
|
41144
|
+
replaceDeprecatedWidgets();
|
|
42196
41145
|
|
|
42197
41146
|
// Pass skipMathJax: true if MathJax is already loaded and configured.
|
|
42198
41147
|
const skipMathJax = options.skipMathJax;
|
|
@@ -42218,7 +41167,7 @@ const init = function init(options) {
|
|
|
42218
41167
|
|
|
42219
41168
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
42220
41169
|
const libName = "@khanacademy/perseus";
|
|
42221
|
-
const libVersion = "
|
|
41170
|
+
const libVersion = "20.0.1";
|
|
42222
41171
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
42223
41172
|
|
|
42224
41173
|
const apiVersion = {
|
|
@@ -43337,14 +42286,6 @@ const ItemExtras = [
|
|
|
43337
42286
|
|
|
43338
42287
|
// prettier-ignore
|
|
43339
42288
|
|
|
43340
|
-
// prettier-ignore
|
|
43341
|
-
|
|
43342
|
-
// prettier-ignore
|
|
43343
|
-
|
|
43344
|
-
// prettier-ignore
|
|
43345
|
-
|
|
43346
|
-
// prettier-ignore
|
|
43347
|
-
|
|
43348
42289
|
//prettier-ignore
|
|
43349
42290
|
|
|
43350
42291
|
// A background image applied to various widgets.
|
|
@@ -43393,7 +42334,7 @@ const deepCallbackFor = function deepCallbackFor(contentCallback, widgetCallback
|
|
|
43393
42334
|
// on getDefaultProps, this will become easier.
|
|
43394
42335
|
let newWidgetInfo;
|
|
43395
42336
|
if (latestVersion && ((_upgradedWidgetInfo$v = upgradedWidgetInfo.version) == null ? void 0 : _upgradedWidgetInfo$v.major) === latestVersion.major) {
|
|
43396
|
-
newWidgetInfo = traverseChildWidgets$
|
|
42337
|
+
newWidgetInfo = traverseChildWidgets$3(upgradedWidgetInfo, rendererOptions => {
|
|
43397
42338
|
return traverseRenderer$1(rendererOptions, contentCallback,
|
|
43398
42339
|
// so that we traverse grandchildren, too:
|
|
43399
42340
|
deepCallback, optionsCallback);
|
|
@@ -44475,7 +43416,7 @@ function violatingWidgets(itemData) {
|
|
|
44475
43416
|
*/
|
|
44476
43417
|
const registerAllWidgetsForTesting = () => {
|
|
44477
43418
|
registerWidgets(allWidgets);
|
|
44478
|
-
|
|
43419
|
+
replaceDeprecatedWidgets();
|
|
44479
43420
|
};
|
|
44480
43421
|
|
|
44481
43422
|
/**
|