@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/index.js
CHANGED
|
@@ -13703,7 +13703,7 @@ var GraphieClasses = {
|
|
|
13703
13703
|
* take appropriate action in onMoveStart, onMove, onMoveEnd
|
|
13704
13704
|
*/
|
|
13705
13705
|
const normalizeOptions$3 = InteractiveUtil.normalizeOptions;
|
|
13706
|
-
const assert$
|
|
13706
|
+
const assert$7 = InteractiveUtil.assert;
|
|
13707
13707
|
|
|
13708
13708
|
// Default "props" and "state". Both are added to this.state.
|
|
13709
13709
|
// However, properties in DEFAULT_PROPS are updated on `modify()`,
|
|
@@ -13871,7 +13871,7 @@ class Movable {
|
|
|
13871
13871
|
* Simulates a mouse grab event on the movable object.
|
|
13872
13872
|
*/
|
|
13873
13873
|
grab(coord) {
|
|
13874
|
-
assert$
|
|
13874
|
+
assert$7(kmath.point.is(coord));
|
|
13875
13875
|
const graphie = this.graphie;
|
|
13876
13876
|
const state = this.state;
|
|
13877
13877
|
state.isHovering = true;
|
|
@@ -14357,7 +14357,7 @@ var objective_ = {
|
|
|
14357
14357
|
/**
|
|
14358
14358
|
* MovableLine
|
|
14359
14359
|
*/
|
|
14360
|
-
const assert$
|
|
14360
|
+
const assert$6 = InteractiveUtil.assert;
|
|
14361
14361
|
const normalizeOptions$2 = InteractiveUtil.normalizeOptions;
|
|
14362
14362
|
|
|
14363
14363
|
// Default "props" and "state". Both are added to this.state and
|
|
@@ -14381,9 +14381,9 @@ const DEFAULT_STATE$2 = {
|
|
|
14381
14381
|
visibleShape: null,
|
|
14382
14382
|
mouseTarget: null
|
|
14383
14383
|
};
|
|
14384
|
-
const MovableLine$
|
|
14385
|
-
assert$
|
|
14386
|
-
assert$
|
|
14384
|
+
const MovableLine$3 = function (graphie, movable, options) {
|
|
14385
|
+
assert$6(graphie != null);
|
|
14386
|
+
assert$6(options != null);
|
|
14387
14387
|
|
|
14388
14388
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
14389
14389
|
___default["default"].extend(this, {
|
|
@@ -14399,10 +14399,10 @@ const MovableLine$4 = function (graphie, movable, options) {
|
|
|
14399
14399
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
14400
14400
|
this.modify(___default["default"].extend({}, DEFAULT_STATE$2, options));
|
|
14401
14401
|
};
|
|
14402
|
-
___default["default"].extend(MovableLine$
|
|
14403
|
-
InteractiveUtil.createGettersFor(MovableLine$
|
|
14404
|
-
InteractiveUtil.addMovableHelperMethodsTo(MovableLine$
|
|
14405
|
-
___default["default"].extend(MovableLine$
|
|
14402
|
+
___default["default"].extend(MovableLine$3, MovableLineOptions);
|
|
14403
|
+
InteractiveUtil.createGettersFor(MovableLine$3, ___default["default"].extend({}, DEFAULT_PROPS$2, DEFAULT_STATE$2));
|
|
14404
|
+
InteractiveUtil.addMovableHelperMethodsTo(MovableLine$3);
|
|
14405
|
+
___default["default"].extend(MovableLine$3.prototype, {
|
|
14406
14406
|
cloneState: function () {
|
|
14407
14407
|
return ___default["default"].extend(this.movable.cloneState(), {
|
|
14408
14408
|
coords: this.coords()
|
|
@@ -14948,7 +14948,7 @@ var MovablePointOptions = {
|
|
|
14948
14948
|
}
|
|
14949
14949
|
};
|
|
14950
14950
|
|
|
14951
|
-
const assert$
|
|
14951
|
+
const assert$5 = InteractiveUtil.assert;
|
|
14952
14952
|
const normalizeOptions$1 = InteractiveUtil.normalizeOptions;
|
|
14953
14953
|
const {
|
|
14954
14954
|
processMath
|
|
@@ -14983,7 +14983,7 @@ const DEFAULT_STATE$1 = {
|
|
|
14983
14983
|
// TODO(benchristel): this is a memory leak. We add items to
|
|
14984
14984
|
// tooltipResetFunctions, but never remove them.
|
|
14985
14985
|
const tooltipResetFunctions = [];
|
|
14986
|
-
class MovablePoint$
|
|
14986
|
+
class MovablePoint$4 {
|
|
14987
14987
|
// @ts-expect-error - TS2564: Property 'prevState' has no initializer and is not definitely assigned in the constructor.
|
|
14988
14988
|
|
|
14989
14989
|
_listenerMap = {};
|
|
@@ -15030,7 +15030,7 @@ class MovablePoint$5 {
|
|
|
15030
15030
|
const self = this;
|
|
15031
15031
|
const graphie = self.graphie;
|
|
15032
15032
|
const state = ___default["default"].extend(self.state, normalizeOptions$1(options));
|
|
15033
|
-
assert$
|
|
15033
|
+
assert$5(kmath.point.is(state.coord));
|
|
15034
15034
|
|
|
15035
15035
|
// Default things inside the state.normalStyle object, because
|
|
15036
15036
|
// _.extend is not deep.
|
|
@@ -15330,12 +15330,12 @@ class MovablePoint$5 {
|
|
|
15330
15330
|
return this.state.coord;
|
|
15331
15331
|
}
|
|
15332
15332
|
setCoord(coord) {
|
|
15333
|
-
assert$
|
|
15333
|
+
assert$5(kmath.point.is(coord, 2));
|
|
15334
15334
|
this.state.coord = ___default["default"].clone(coord);
|
|
15335
15335
|
this.draw();
|
|
15336
15336
|
}
|
|
15337
15337
|
setCoordConstrained(coord) {
|
|
15338
|
-
assert$
|
|
15338
|
+
assert$5(kmath.point.is(coord, 2));
|
|
15339
15339
|
const result = this._applyConstraints(coord, this.coord());
|
|
15340
15340
|
if (result !== false) {
|
|
15341
15341
|
this.state.coord = ___default["default"].clone(result);
|
|
@@ -15843,7 +15843,7 @@ var MovablePolygonOptions = {
|
|
|
15843
15843
|
* Creates and adds a polygon to the graph that can be dragged around.
|
|
15844
15844
|
* It allows constraints on its movement and draws when moves happen.
|
|
15845
15845
|
*/
|
|
15846
|
-
const assert$
|
|
15846
|
+
const assert$4 = InteractiveUtil.assert;
|
|
15847
15847
|
const normalizeOptions = InteractiveUtil.normalizeOptions;
|
|
15848
15848
|
|
|
15849
15849
|
// Default "props" and "state". Both are added to this.state and
|
|
@@ -15878,8 +15878,8 @@ const DEFAULT_STATE = {
|
|
|
15878
15878
|
mouseTarget: null
|
|
15879
15879
|
};
|
|
15880
15880
|
const MovablePolygon = function (graphie, movable, options) {
|
|
15881
|
-
assert$
|
|
15882
|
-
assert$
|
|
15881
|
+
assert$4(graphie != null);
|
|
15882
|
+
assert$4(options != null);
|
|
15883
15883
|
|
|
15884
15884
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
15885
15885
|
___default["default"].extend(this, {
|
|
@@ -16111,15 +16111,15 @@ ___default["default"].extend(MovablePolygon.prototype, {
|
|
|
16111
16111
|
});
|
|
16112
16112
|
|
|
16113
16113
|
const Interactive2 = {
|
|
16114
|
-
MovablePoint: MovablePoint$
|
|
16114
|
+
MovablePoint: MovablePoint$4,
|
|
16115
16115
|
addMovablePoint: function (graphie, options) {
|
|
16116
16116
|
const movable = new Movable(graphie, {});
|
|
16117
|
-
return new MovablePoint$
|
|
16117
|
+
return new MovablePoint$4(graphie, movable, options);
|
|
16118
16118
|
},
|
|
16119
|
-
MovableLine: MovableLine$
|
|
16119
|
+
MovableLine: MovableLine$3,
|
|
16120
16120
|
addMovableLine: function (graphie, options) {
|
|
16121
16121
|
const movable = new Movable(graphie, {});
|
|
16122
|
-
return new MovableLine$
|
|
16122
|
+
return new MovableLine$3(graphie, movable, options);
|
|
16123
16123
|
},
|
|
16124
16124
|
MovablePolygon: MovablePolygon,
|
|
16125
16125
|
addMovablePolygon: function (graphie, options) {
|
|
@@ -16156,7 +16156,7 @@ const Interactive2 = {
|
|
|
16156
16156
|
}
|
|
16157
16157
|
};
|
|
16158
16158
|
|
|
16159
|
-
const MovablePoint$
|
|
16159
|
+
const MovablePoint$3 = GraphieClasses.createClass({
|
|
16160
16160
|
displayName: "MovablePoint",
|
|
16161
16161
|
movableProps: ["children"],
|
|
16162
16162
|
_getProps: function () {
|
|
@@ -16214,8 +16214,8 @@ const MovablePoint$4 = GraphieClasses.createClass({
|
|
|
16214
16214
|
});
|
|
16215
16215
|
|
|
16216
16216
|
// Include helper methods, such as MovablePoint.constrain.snap()
|
|
16217
|
-
___default["default"].extend(MovablePoint$
|
|
16218
|
-
const MovableLine$
|
|
16217
|
+
___default["default"].extend(MovablePoint$3, Interactive2.MovablePoint);
|
|
16218
|
+
const MovableLine$2 = GraphieClasses.createClass({
|
|
16219
16219
|
displayName: "MovableLine",
|
|
16220
16220
|
movableProps: ["children"],
|
|
16221
16221
|
add: function (graphie) {
|
|
@@ -16243,8 +16243,8 @@ const MovableLine$3 = GraphieClasses.createClass({
|
|
|
16243
16243
|
});
|
|
16244
16244
|
|
|
16245
16245
|
// Include helper methods, such as MovableLine.constrain.snap()
|
|
16246
|
-
___default["default"].extend(MovableLine$
|
|
16247
|
-
const Label$
|
|
16246
|
+
___default["default"].extend(MovableLine$2, Interactive2.MovableLine);
|
|
16247
|
+
const Label$1 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
16248
16248
|
let coord = props.coord;
|
|
16249
16249
|
if (props.unscaled) {
|
|
16250
16250
|
coord = graphie.unscalePoint(coord);
|
|
@@ -16263,7 +16263,7 @@ const Label$2 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
|
16263
16263
|
}
|
|
16264
16264
|
return elem;
|
|
16265
16265
|
});
|
|
16266
|
-
const Line$
|
|
16266
|
+
const Line$2 = GraphieClasses.createClass({
|
|
16267
16267
|
displayName: "Line",
|
|
16268
16268
|
movableProps: ["children"],
|
|
16269
16269
|
add: function (graphie) {
|
|
@@ -16341,7 +16341,7 @@ const Point$1 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
|
16341
16341
|
stroke: props.color || KhanColors.BLACK
|
|
16342
16342
|
});
|
|
16343
16343
|
});
|
|
16344
|
-
const Path
|
|
16344
|
+
const Path = GraphieClasses.createClass({
|
|
16345
16345
|
displayName: "Path",
|
|
16346
16346
|
movableProps: ["children"],
|
|
16347
16347
|
add: function (graphie) {
|
|
@@ -16363,7 +16363,7 @@ const Path$1 = GraphieClasses.createClass({
|
|
|
16363
16363
|
this.path.toFront();
|
|
16364
16364
|
}
|
|
16365
16365
|
});
|
|
16366
|
-
const Arc
|
|
16366
|
+
const Arc = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
16367
16367
|
let center = props.center;
|
|
16368
16368
|
let radius = props.radius;
|
|
16369
16369
|
if (props.unscaled) {
|
|
@@ -16372,21 +16372,21 @@ const Arc$1 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
|
16372
16372
|
}
|
|
16373
16373
|
return graphie.arc(center, radius, props.startAngle, props.endAngle, props.sector, props.style);
|
|
16374
16374
|
});
|
|
16375
|
-
const Circle
|
|
16375
|
+
const Circle = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
16376
16376
|
return graphie.circle(props.center, props.radius, props.style);
|
|
16377
16377
|
});
|
|
16378
16378
|
const Rect$1 = GraphieClasses.createSimpleClass((graphie, props) => {
|
|
16379
16379
|
return graphie.rect(props.x, props.y, props.width, props.height, props.style);
|
|
16380
16380
|
});
|
|
16381
16381
|
var Movables = {
|
|
16382
|
-
Arc: Arc
|
|
16383
|
-
Circle: Circle
|
|
16384
|
-
Label: Label$
|
|
16385
|
-
Line: Line$
|
|
16386
|
-
MovableLine: MovableLine$
|
|
16387
|
-
MovablePoint: MovablePoint$
|
|
16382
|
+
Arc: Arc,
|
|
16383
|
+
Circle: Circle,
|
|
16384
|
+
Label: Label$1,
|
|
16385
|
+
Line: Line$2,
|
|
16386
|
+
MovableLine: MovableLine$2,
|
|
16387
|
+
MovablePoint: MovablePoint$3,
|
|
16388
16388
|
Parabola: Parabola,
|
|
16389
|
-
Path: Path
|
|
16389
|
+
Path: Path,
|
|
16390
16390
|
Plot: Plot$2,
|
|
16391
16391
|
PlotParametric: PlotParametric$1,
|
|
16392
16392
|
Point: Point$1,
|
|
@@ -16401,7 +16401,7 @@ const {
|
|
|
16401
16401
|
nestedMap
|
|
16402
16402
|
} = Util;
|
|
16403
16403
|
const {
|
|
16404
|
-
assert: assert$
|
|
16404
|
+
assert: assert$3
|
|
16405
16405
|
} = InteractiveUtil;
|
|
16406
16406
|
class Graphie extends React__namespace.Component {
|
|
16407
16407
|
graphieDivRef = /*#__PURE__*/React__namespace.createRef();
|
|
@@ -16579,7 +16579,7 @@ class Graphie extends React__namespace.Component {
|
|
|
16579
16579
|
|
|
16580
16580
|
// Instantiate the descriptor to turn it into a real Movable
|
|
16581
16581
|
const child = new childDescriptor.type(childDescriptor.props);
|
|
16582
|
-
assert$
|
|
16582
|
+
assert$3(child instanceof GraphieMovable, "All children of a Graphie component must be Graphie " + "movables");
|
|
16583
16583
|
|
|
16584
16584
|
// Give each child a key
|
|
16585
16585
|
const keyProp = childDescriptor.key;
|
|
@@ -18775,6 +18775,13 @@ const replaceWidget = (name, replacementName) => {
|
|
|
18775
18775
|
}
|
|
18776
18776
|
registerWidget(name, substituteWidget);
|
|
18777
18777
|
};
|
|
18778
|
+
const replaceDeprecatedWidgets = () => {
|
|
18779
|
+
replaceWidget("transformer", "deprecated-standin");
|
|
18780
|
+
replaceWidget("lights-puzzle", "deprecated-standin");
|
|
18781
|
+
replaceWidget("reaction-diagram", "deprecated-standin");
|
|
18782
|
+
replaceWidget("sequence", "deprecated-standin");
|
|
18783
|
+
replaceWidget("simulator", "deprecated-standin");
|
|
18784
|
+
};
|
|
18778
18785
|
const registerEditors = editorsToRegister => {
|
|
18779
18786
|
editorsToRegister.forEach(editor => {
|
|
18780
18787
|
if (!editor.widgetName) {
|
|
@@ -18789,8 +18796,8 @@ const registerEditors = editorsToRegister => {
|
|
|
18789
18796
|
* @param name - the widget that you are trying to replace
|
|
18790
18797
|
* @param replacementName - the name of the widget that takes its place
|
|
18791
18798
|
*
|
|
18792
|
-
* e.g. replaceEditor("transformer", "
|
|
18793
|
-
* transformer widget is replaced by the
|
|
18799
|
+
* e.g. replaceEditor("transformer", "deprecated-standin") will make it so the
|
|
18800
|
+
* transformer widget is replaced by the deprecated stand-in widget
|
|
18794
18801
|
*/
|
|
18795
18802
|
const replaceEditor = (name, replacementName) => {
|
|
18796
18803
|
const substituteEditor = editors[replacementName];
|
|
@@ -18801,6 +18808,13 @@ const replaceEditor = (name, replacementName) => {
|
|
|
18801
18808
|
}
|
|
18802
18809
|
editors[name] = substituteEditor;
|
|
18803
18810
|
};
|
|
18811
|
+
const replaceDeprecatedEditors = () => {
|
|
18812
|
+
replaceEditor("transformer", "deprecated-standin");
|
|
18813
|
+
replaceEditor("lights-puzzle", "deprecated-standin");
|
|
18814
|
+
replaceEditor("reaction-diagram", "deprecated-standin");
|
|
18815
|
+
replaceEditor("sequence", "deprecated-standin");
|
|
18816
|
+
replaceEditor("simulator", "deprecated-standin");
|
|
18817
|
+
};
|
|
18804
18818
|
const getWidget = name => {
|
|
18805
18819
|
// TODO(alex): Consider referring to these as renderers to avoid
|
|
18806
18820
|
// overloading "widget"
|
|
@@ -18986,7 +19000,7 @@ const getRendererPropsForWidgetInfo = (widgetInfo, problemNum) => {
|
|
|
18986
19000
|
// widgetInfo.options are the widgetEditor's props:
|
|
18987
19001
|
return transform(widgetInfo.options, problemNum);
|
|
18988
19002
|
};
|
|
18989
|
-
const traverseChildWidgets$
|
|
19003
|
+
const traverseChildWidgets$3 = (widgetInfo, traverseRenderer) => {
|
|
18990
19004
|
if (!traverseRenderer) {
|
|
18991
19005
|
throw new PerseusError("traverseRenderer must be provided, but was not", Errors.Internal);
|
|
18992
19006
|
}
|
|
@@ -19115,8 +19129,10 @@ var widgets$1 = /*#__PURE__*/Object.freeze({
|
|
|
19115
19129
|
registerWidget: registerWidget,
|
|
19116
19130
|
registerWidgets: registerWidgets,
|
|
19117
19131
|
replaceWidget: replaceWidget,
|
|
19132
|
+
replaceDeprecatedWidgets: replaceDeprecatedWidgets,
|
|
19118
19133
|
registerEditors: registerEditors,
|
|
19119
19134
|
replaceEditor: replaceEditor,
|
|
19135
|
+
replaceDeprecatedEditors: replaceDeprecatedEditors,
|
|
19120
19136
|
getWidget: getWidget,
|
|
19121
19137
|
getEditor: getEditor,
|
|
19122
19138
|
getTransform: getTransform,
|
|
@@ -19127,7 +19143,7 @@ var widgets$1 = /*#__PURE__*/Object.freeze({
|
|
|
19127
19143
|
getAllWidgetTypes: getAllWidgetTypes,
|
|
19128
19144
|
upgradeWidgetInfoToLatestVersion: upgradeWidgetInfoToLatestVersion,
|
|
19129
19145
|
getRendererPropsForWidgetInfo: getRendererPropsForWidgetInfo,
|
|
19130
|
-
traverseChildWidgets: traverseChildWidgets$
|
|
19146
|
+
traverseChildWidgets: traverseChildWidgets$3,
|
|
19131
19147
|
getSupportedAlignments: getSupportedAlignments,
|
|
19132
19148
|
getDefaultAlignment: getDefaultAlignment,
|
|
19133
19149
|
validateAlignments: validateAlignments,
|
|
@@ -21835,7 +21851,7 @@ const styles$z = aphrodite.StyleSheet.create({
|
|
|
21835
21851
|
border: "solid 1px #999"
|
|
21836
21852
|
}
|
|
21837
21853
|
});
|
|
21838
|
-
const propTransform$
|
|
21854
|
+
const propTransform$3 = widgetOptions => {
|
|
21839
21855
|
const {
|
|
21840
21856
|
simplify,
|
|
21841
21857
|
size,
|
|
@@ -21855,7 +21871,7 @@ var InputNumber$1 = {
|
|
|
21855
21871
|
defaultAlignment: "inline-block",
|
|
21856
21872
|
hidden: true,
|
|
21857
21873
|
widget: InputNumber,
|
|
21858
|
-
transform: propTransform$
|
|
21874
|
+
transform: propTransform$3,
|
|
21859
21875
|
isLintable: true
|
|
21860
21876
|
};
|
|
21861
21877
|
|
|
@@ -25485,7 +25501,7 @@ class GradedGroup extends React__namespace.Component {
|
|
|
25485
25501
|
}));
|
|
25486
25502
|
}
|
|
25487
25503
|
}
|
|
25488
|
-
const traverseChildWidgets$
|
|
25504
|
+
const traverseChildWidgets$2 = function (props, traverseRenderer) {
|
|
25489
25505
|
return ___default["default"].extend({}, props, traverseRenderer(props));
|
|
25490
25506
|
};
|
|
25491
25507
|
const styles$m = aphrodite.StyleSheet.create({
|
|
@@ -25541,7 +25557,7 @@ var GradedGroup$1 = {
|
|
|
25541
25557
|
name: "graded-group",
|
|
25542
25558
|
displayName: "Graded group (articles only)",
|
|
25543
25559
|
widget: GradedGroup,
|
|
25544
|
-
traverseChildWidgets: traverseChildWidgets$
|
|
25560
|
+
traverseChildWidgets: traverseChildWidgets$2,
|
|
25545
25561
|
// TODO(aasmund): This widget should be available for articles only
|
|
25546
25562
|
hidden: false,
|
|
25547
25563
|
tracking: "all",
|
|
@@ -25710,7 +25726,7 @@ class GradedGroupSet extends React__namespace.Component {
|
|
|
25710
25726
|
})));
|
|
25711
25727
|
}
|
|
25712
25728
|
}
|
|
25713
|
-
const traverseChildWidgets$
|
|
25729
|
+
const traverseChildWidgets$1 = function (props, traverseRenderer) {
|
|
25714
25730
|
// NOTE(jared): I have no idea how this works
|
|
25715
25731
|
return {
|
|
25716
25732
|
groups: props.gradedGroups.map(traverseRenderer)
|
|
@@ -25720,7 +25736,7 @@ var GradedGroupSet$1 = {
|
|
|
25720
25736
|
name: "graded-group-set",
|
|
25721
25737
|
displayName: "Graded group set (articles only)",
|
|
25722
25738
|
widget: GradedGroupSet,
|
|
25723
|
-
traverseChildWidgets: traverseChildWidgets$
|
|
25739
|
+
traverseChildWidgets: traverseChildWidgets$1,
|
|
25724
25740
|
// TODO(michaelpolyak): This widget should be available for articles only
|
|
25725
25741
|
hidden: false,
|
|
25726
25742
|
tracking: "all",
|
|
@@ -26276,7 +26292,7 @@ function functionForType(
|
|
|
26276
26292
|
type) {
|
|
26277
26293
|
return functionTypeMapping[type];
|
|
26278
26294
|
}
|
|
26279
|
-
const validate$
|
|
26295
|
+
const validate$1 = (state, rubric) => {
|
|
26280
26296
|
if (state.type !== rubric.correct.type) {
|
|
26281
26297
|
return {
|
|
26282
26298
|
type: "points",
|
|
@@ -26436,7 +26452,7 @@ var util = /*#__PURE__*/Object.freeze({
|
|
|
26436
26452
|
DEFAULT_BACKGROUND_IMAGE: DEFAULT_BACKGROUND_IMAGE,
|
|
26437
26453
|
allTypes: allTypes,
|
|
26438
26454
|
functionForType: functionForType,
|
|
26439
|
-
validate: validate$
|
|
26455
|
+
validate: validate$1,
|
|
26440
26456
|
getEquationString: getEquationString,
|
|
26441
26457
|
pointsFromNormalized: pointsFromNormalized,
|
|
26442
26458
|
maybePointsFromNormalized: maybePointsFromNormalized,
|
|
@@ -26448,9 +26464,9 @@ var util = /*#__PURE__*/Object.freeze({
|
|
|
26448
26464
|
});
|
|
26449
26465
|
|
|
26450
26466
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
26451
|
-
const MovablePoint$
|
|
26467
|
+
const MovablePoint$2 = Graphie.MovablePoint;
|
|
26452
26468
|
// @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
|
|
26453
|
-
const MovableLine$
|
|
26469
|
+
const MovableLine$1 = Graphie.MovableLine;
|
|
26454
26470
|
function isFlipped(newCoord, oldCoord, line) {
|
|
26455
26471
|
const CCW = (a, b, c) => {
|
|
26456
26472
|
return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]);
|
|
@@ -26494,7 +26510,7 @@ class FunctionGrapher extends React__namespace.Component {
|
|
|
26494
26510
|
})();
|
|
26495
26511
|
render() {
|
|
26496
26512
|
const pointForCoord = (coord, i) => {
|
|
26497
|
-
return /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
26513
|
+
return /*#__PURE__*/React__namespace.createElement(MovablePoint$2, {
|
|
26498
26514
|
key: i,
|
|
26499
26515
|
coord: coord,
|
|
26500
26516
|
static: this.props.static,
|
|
@@ -26606,7 +26622,7 @@ class FunctionGrapher extends React__namespace.Component {
|
|
|
26606
26622
|
const dashed = {
|
|
26607
26623
|
strokeDasharray: "- "
|
|
26608
26624
|
};
|
|
26609
|
-
return asymptote && /*#__PURE__*/React__namespace.createElement(MovableLine$
|
|
26625
|
+
return asymptote && /*#__PURE__*/React__namespace.createElement(MovableLine$1, {
|
|
26610
26626
|
onMove: (newCoord, oldCoord) => {
|
|
26611
26627
|
// Calculate and apply displacement
|
|
26612
26628
|
const delta = kmath.vector.subtract(newCoord, oldCoord);
|
|
@@ -26631,7 +26647,7 @@ class FunctionGrapher extends React__namespace.Component {
|
|
|
26631
26647
|
}],
|
|
26632
26648
|
normalStyle: dashed,
|
|
26633
26649
|
highlightStyle: dashed
|
|
26634
|
-
}, ___default["default"].map(asymptote, (coord, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
26650
|
+
}, ___default["default"].map(asymptote, (coord, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$2, {
|
|
26635
26651
|
key: `asymptoteCoord-${i}`,
|
|
26636
26652
|
coord: coord,
|
|
26637
26653
|
static: true,
|
|
@@ -26804,20 +26820,20 @@ class Grapher extends React__namespace.Component {
|
|
|
26804
26820
|
}
|
|
26805
26821
|
};
|
|
26806
26822
|
simpleValidate(rubric) {
|
|
26807
|
-
return validate$
|
|
26823
|
+
return validate$1(this.getUserInput(), rubric);
|
|
26808
26824
|
}
|
|
26809
26825
|
getUserInput() {
|
|
26810
26826
|
return Grapher.getUserInputFromProps(this.props);
|
|
26811
26827
|
}
|
|
26812
26828
|
focus() {}
|
|
26813
26829
|
static validate(state, rubric) {
|
|
26814
|
-
return validate$
|
|
26830
|
+
return validate$1(state, rubric);
|
|
26815
26831
|
}
|
|
26816
26832
|
static getUserInputFromProps(props) {
|
|
26817
26833
|
return props.plot;
|
|
26818
26834
|
}
|
|
26819
26835
|
}
|
|
26820
|
-
const propTransform$
|
|
26836
|
+
const propTransform$2 = editorProps => {
|
|
26821
26837
|
const widgetProps = {
|
|
26822
26838
|
availableTypes: editorProps.availableTypes,
|
|
26823
26839
|
graph: editorProps.graph
|
|
@@ -26837,7 +26853,7 @@ const propTransform$3 = editorProps => {
|
|
|
26837
26853
|
// mode we set static=true for the graph's handles in FunctionGrapher.
|
|
26838
26854
|
const staticTransform$3 = editorProps => {
|
|
26839
26855
|
return {
|
|
26840
|
-
...propTransform$
|
|
26856
|
+
...propTransform$2(editorProps),
|
|
26841
26857
|
// Don't display graph type choices if we're in static mode
|
|
26842
26858
|
availableTypes: [editorProps.correct.type],
|
|
26843
26859
|
// Display the same graph marked as correct in the widget editor.
|
|
@@ -26848,7 +26864,7 @@ var Grapher$1 = {
|
|
|
26848
26864
|
name: "grapher",
|
|
26849
26865
|
displayName: "Grapher",
|
|
26850
26866
|
widget: Grapher,
|
|
26851
|
-
transform: propTransform$
|
|
26867
|
+
transform: propTransform$2,
|
|
26852
26868
|
staticTransform: staticTransform$3
|
|
26853
26869
|
};
|
|
26854
26870
|
|
|
@@ -26980,7 +26996,7 @@ class Group extends React__namespace.Component {
|
|
|
26980
26996
|
}, this.props.icon));
|
|
26981
26997
|
}
|
|
26982
26998
|
}
|
|
26983
|
-
const traverseChildWidgets
|
|
26999
|
+
const traverseChildWidgets = function (props, traverseRenderer) {
|
|
26984
27000
|
return {
|
|
26985
27001
|
...props,
|
|
26986
27002
|
...traverseRenderer(props)
|
|
@@ -26990,7 +27006,7 @@ var Group$1 = {
|
|
|
26990
27006
|
name: "group",
|
|
26991
27007
|
displayName: "Group (SAT only)",
|
|
26992
27008
|
widget: Group,
|
|
26993
|
-
traverseChildWidgets: traverseChildWidgets
|
|
27009
|
+
traverseChildWidgets: traverseChildWidgets,
|
|
26994
27010
|
hidden: false,
|
|
26995
27011
|
isLintable: true
|
|
26996
27012
|
};
|
|
@@ -27163,7 +27179,7 @@ var Iframe$1 = {
|
|
|
27163
27179
|
};
|
|
27164
27180
|
|
|
27165
27181
|
/* eslint-disable react/sort-comp */
|
|
27166
|
-
const defaultBoxSize
|
|
27182
|
+
const defaultBoxSize = 400;
|
|
27167
27183
|
const defaultRange = [0, 10];
|
|
27168
27184
|
const defaultBackgroundImage$2 = {
|
|
27169
27185
|
url: null,
|
|
@@ -27180,7 +27196,7 @@ class ImageWidget extends React__namespace.Component {
|
|
|
27180
27196
|
alignment: DEFAULT_ALIGNMENT,
|
|
27181
27197
|
title: "",
|
|
27182
27198
|
range: [defaultRange, defaultRange],
|
|
27183
|
-
box: [defaultBoxSize
|
|
27199
|
+
box: [defaultBoxSize, defaultBoxSize],
|
|
27184
27200
|
backgroundImage: defaultBackgroundImage$2,
|
|
27185
27201
|
labels: [],
|
|
27186
27202
|
alt: "",
|
|
@@ -27390,13 +27406,13 @@ var Image$1 = {
|
|
|
27390
27406
|
|
|
27391
27407
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
27392
27408
|
// @ts-expect-error - TS2339 - Property 'Label' does not exist on type 'typeof Graphie'.
|
|
27393
|
-
const Label
|
|
27409
|
+
const Label = Graphie.Label;
|
|
27394
27410
|
// @ts-expect-error - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
|
|
27395
|
-
const Line$
|
|
27411
|
+
const Line$1 = Graphie.Line;
|
|
27396
27412
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
27397
|
-
const MovablePoint$
|
|
27413
|
+
const MovablePoint$1 = Graphie.MovablePoint;
|
|
27398
27414
|
// @ts-expect-error - TS2339 - Property 'MovableLine' does not exist on type 'typeof Graphie'.
|
|
27399
|
-
const MovableLine
|
|
27415
|
+
const MovableLine = Graphie.MovableLine;
|
|
27400
27416
|
// @ts-expect-error - TS2339 - Property 'Plot' does not exist on type 'typeof Graphie'.
|
|
27401
27417
|
const Plot = Graphie.Plot;
|
|
27402
27418
|
// @ts-expect-error - TS2339 - Property 'PlotParametric' does not exist on type 'typeof Graphie'.
|
|
@@ -27588,11 +27604,11 @@ class Interaction extends React__namespace.Component {
|
|
|
27588
27604
|
options: this.props.graph,
|
|
27589
27605
|
setup: this._setupGraphie,
|
|
27590
27606
|
setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
|
|
27591
|
-
}, this.props.graph.markings === "graph" && /*#__PURE__*/React__namespace.createElement(Label
|
|
27607
|
+
}, this.props.graph.markings === "graph" && /*#__PURE__*/React__namespace.createElement(Label, {
|
|
27592
27608
|
coord: [0, range[1][1]],
|
|
27593
27609
|
text: labels[1],
|
|
27594
27610
|
direction: "above"
|
|
27595
|
-
}), this.props.graph.markings === "graph" && /*#__PURE__*/React__namespace.createElement(Label
|
|
27611
|
+
}), this.props.graph.markings === "graph" && /*#__PURE__*/React__namespace.createElement(Label, {
|
|
27596
27612
|
coord: [range[0][1], 0],
|
|
27597
27613
|
text: labels[0],
|
|
27598
27614
|
direction: "right"
|
|
@@ -27619,7 +27635,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27619
27635
|
this._eval(element.options.endX),
|
|
27620
27636
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
27621
27637
|
this._eval(element.options.endY)];
|
|
27622
|
-
return /*#__PURE__*/React__namespace.createElement(Line$
|
|
27638
|
+
return /*#__PURE__*/React__namespace.createElement(Line$1, {
|
|
27623
27639
|
key: element.key,
|
|
27624
27640
|
start: start,
|
|
27625
27641
|
end: end,
|
|
@@ -27648,7 +27664,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27648
27664
|
return [coordX, coordY];
|
|
27649
27665
|
}];
|
|
27650
27666
|
if (element.options.constraint === "snap") {
|
|
27651
|
-
constraints.push(MovablePoint$
|
|
27667
|
+
constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
|
|
27652
27668
|
} else if (element.options.constraint === "x") {
|
|
27653
27669
|
constraints.push(coord => {
|
|
27654
27670
|
return [
|
|
@@ -27670,7 +27686,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27670
27686
|
// TODO(eater): foo_[xyz] are hacky non-props to
|
|
27671
27687
|
// get the component to update when constraints
|
|
27672
27688
|
// change
|
|
27673
|
-
return /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
27689
|
+
return /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
27674
27690
|
key: element.key,
|
|
27675
27691
|
coord: [
|
|
27676
27692
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
@@ -27705,7 +27721,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27705
27721
|
return [coordX, coordY];
|
|
27706
27722
|
}];
|
|
27707
27723
|
if (element.options.constraint === "snap") {
|
|
27708
|
-
constraints.push(MovablePoint$
|
|
27724
|
+
constraints.push(MovablePoint$1.constraints.snap(element.options.snap));
|
|
27709
27725
|
} else if (element.options.constraint === "x") {
|
|
27710
27726
|
constraints.push(coord => {
|
|
27711
27727
|
return [
|
|
@@ -27733,7 +27749,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27733
27749
|
this.state.variables["x_" + element.options.endSubscript],
|
|
27734
27750
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
27735
27751
|
this.state.variables["y_" + element.options.endSubscript]];
|
|
27736
|
-
return /*#__PURE__*/React__namespace.createElement(MovableLine
|
|
27752
|
+
return /*#__PURE__*/React__namespace.createElement(MovableLine, {
|
|
27737
27753
|
key: element.key,
|
|
27738
27754
|
constraints: constraints
|
|
27739
27755
|
// eslint-disable-next-line react/jsx-no-bind
|
|
@@ -27746,14 +27762,14 @@ class Interaction extends React__namespace.Component {
|
|
|
27746
27762
|
foo_x: element.options.constraint,
|
|
27747
27763
|
foo_y: element.options.constraintFn,
|
|
27748
27764
|
foo_z: element.options.snap
|
|
27749
|
-
}, /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
27765
|
+
}, /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
27750
27766
|
coord: start,
|
|
27751
27767
|
static: true,
|
|
27752
27768
|
normalStyle: {
|
|
27753
27769
|
stroke: "none",
|
|
27754
27770
|
fill: "none"
|
|
27755
27771
|
}
|
|
27756
|
-
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$
|
|
27772
|
+
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
27757
27773
|
coord: end,
|
|
27758
27774
|
static: true,
|
|
27759
27775
|
normalStyle: {
|
|
@@ -27865,7 +27881,7 @@ class Interaction extends React__namespace.Component {
|
|
|
27865
27881
|
this._eval(element.options.coordX),
|
|
27866
27882
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
27867
27883
|
this._eval(element.options.coordY)];
|
|
27868
|
-
return /*#__PURE__*/React__namespace.createElement(Label
|
|
27884
|
+
return /*#__PURE__*/React__namespace.createElement(Label, {
|
|
27869
27885
|
key: n + 1,
|
|
27870
27886
|
coord: coord,
|
|
27871
27887
|
text: unescapeMathMode(element.options.label),
|
|
@@ -33027,276 +33043,6 @@ var LabelImage$1 = {
|
|
|
33027
33043
|
isLintable: true
|
|
33028
33044
|
};
|
|
33029
33045
|
|
|
33030
|
-
/* eslint-disable @typescript-eslint/no-unused-vars, react/sort-comp */
|
|
33031
|
-
|
|
33032
|
-
// Styling
|
|
33033
|
-
const CELL_PADDING = 5;
|
|
33034
|
-
const TABLE_STYLE = {
|
|
33035
|
-
display: "table",
|
|
33036
|
-
tableLayout: "fixed"
|
|
33037
|
-
};
|
|
33038
|
-
const ROW_STYLE = {
|
|
33039
|
-
display: "table-row"
|
|
33040
|
-
};
|
|
33041
|
-
const CELL_STYLE = {
|
|
33042
|
-
display: "table-cell",
|
|
33043
|
-
padding: CELL_PADDING
|
|
33044
|
-
};
|
|
33045
|
-
const BASE_TILE_STYLE = {
|
|
33046
|
-
borderRadius: 10,
|
|
33047
|
-
cursor: "pointer"
|
|
33048
|
-
};
|
|
33049
|
-
const MOVE_COUNT_STYLE = {
|
|
33050
|
-
padding: CELL_PADDING,
|
|
33051
|
-
display: "inline-block"
|
|
33052
|
-
};
|
|
33053
|
-
const RESET_BUTTON_STYLE = {
|
|
33054
|
-
float: "right",
|
|
33055
|
-
paddingRight: CELL_PADDING
|
|
33056
|
-
};
|
|
33057
|
-
const MAIN_TILE_SIZE = 50;
|
|
33058
|
-
const PATTERNS = {
|
|
33059
|
-
plus: () => [[false, true, false], [true, true, true], [false, true, false]],
|
|
33060
|
-
x: () => [[true, false, true], [false, true, false], [true, false, true]],
|
|
33061
|
-
"plus/x": iter => {
|
|
33062
|
-
return iter % 2 ? PATTERNS.x() : PATTERNS.plus();
|
|
33063
|
-
}
|
|
33064
|
-
};
|
|
33065
|
-
|
|
33066
|
-
// A single glowy cell
|
|
33067
|
-
class Tile extends React__namespace.Component {
|
|
33068
|
-
static propTypes = {
|
|
33069
|
-
value: PropTypes__default["default"].bool.isRequired,
|
|
33070
|
-
size: PropTypes__default["default"].number.isRequired
|
|
33071
|
-
};
|
|
33072
|
-
render() {
|
|
33073
|
-
const color = this.props.value ? "#55dd55" : "#115511";
|
|
33074
|
-
const style = ___default["default"].extend({}, BASE_TILE_STYLE, {
|
|
33075
|
-
width: this.props.size,
|
|
33076
|
-
height: this.props.size,
|
|
33077
|
-
backgroundColor: color
|
|
33078
|
-
});
|
|
33079
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
33080
|
-
style: style,
|
|
33081
|
-
onClick: this._flip
|
|
33082
|
-
});
|
|
33083
|
-
}
|
|
33084
|
-
_flip = () => {
|
|
33085
|
-
// On change requires a value, but we don't actually have access
|
|
33086
|
-
// to the coordinates here, so we just pass the inverse value as a workaround.
|
|
33087
|
-
this.props.onChange({
|
|
33088
|
-
value: !this.props.value
|
|
33089
|
-
});
|
|
33090
|
-
};
|
|
33091
|
-
}
|
|
33092
|
-
|
|
33093
|
-
// A grid of glowy cells
|
|
33094
|
-
class TileGrid extends React__namespace.Component {
|
|
33095
|
-
render() {
|
|
33096
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
33097
|
-
style: TABLE_STYLE,
|
|
33098
|
-
className: "no-select"
|
|
33099
|
-
}, this.props.cells && ___default["default"].map(this.props.cells, (row, y) => {
|
|
33100
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
33101
|
-
key: y,
|
|
33102
|
-
style: ROW_STYLE
|
|
33103
|
-
}, ___default["default"].map(row, (cell, x) => {
|
|
33104
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
33105
|
-
key: x,
|
|
33106
|
-
style: CELL_STYLE
|
|
33107
|
-
}, /*#__PURE__*/React__namespace.createElement(Tile, {
|
|
33108
|
-
value: cell,
|
|
33109
|
-
size: this.props.size,
|
|
33110
|
-
onChange: ___default["default"].partial(this.props.onChange, {
|
|
33111
|
-
value: {
|
|
33112
|
-
y,
|
|
33113
|
-
x
|
|
33114
|
-
}
|
|
33115
|
-
})
|
|
33116
|
-
}));
|
|
33117
|
-
}));
|
|
33118
|
-
}));
|
|
33119
|
-
}
|
|
33120
|
-
}
|
|
33121
|
-
|
|
33122
|
-
// Returns a copy of the tiles, with tiles flipped according to
|
|
33123
|
-
// whether or not their y, x position satisfies the predicate
|
|
33124
|
-
const flipTilesPredicate = (oldCells, predicate) => {
|
|
33125
|
-
return ___default["default"].map(oldCells, (row, y) => {
|
|
33126
|
-
return ___default["default"].map(row, (cell, x) => {
|
|
33127
|
-
return predicate(y, x) ? !cell : cell;
|
|
33128
|
-
});
|
|
33129
|
-
});
|
|
33130
|
-
};
|
|
33131
|
-
const flipTilesPattern = (oldCells, tileY, tileX, pattern) => {
|
|
33132
|
-
return flipTilesPredicate(oldCells, (y, x) => {
|
|
33133
|
-
const offsetY = y - tileY;
|
|
33134
|
-
const offsetX = x - tileX;
|
|
33135
|
-
if (Math.abs(offsetY) <= 1 && Math.abs(offsetX) <= 1) {
|
|
33136
|
-
return pattern[offsetY + 1][offsetX + 1];
|
|
33137
|
-
}
|
|
33138
|
-
return false;
|
|
33139
|
-
});
|
|
33140
|
-
};
|
|
33141
|
-
|
|
33142
|
-
// The lights puzzle widget
|
|
33143
|
-
class LightsPuzzle extends React__namespace.Component {
|
|
33144
|
-
// @ts-expect-error - TS2564 - Property '_patternIndex' has no initializer and is not definitely assigned in the constructor.
|
|
33145
|
-
|
|
33146
|
-
static defaultProps = {
|
|
33147
|
-
cells: [[false, false, false], [false, false, false], [false, false, false]],
|
|
33148
|
-
startCells: [[false, false, false], [false, false, false], [false, false, false]],
|
|
33149
|
-
flipPattern: "plus",
|
|
33150
|
-
moveCount: 0
|
|
33151
|
-
};
|
|
33152
|
-
getUserInput = () => {
|
|
33153
|
-
return WidgetJsonifyDeprecated.getUserInput.call(this);
|
|
33154
|
-
};
|
|
33155
|
-
render() {
|
|
33156
|
-
const width = this._width();
|
|
33157
|
-
const tileSize = MAIN_TILE_SIZE;
|
|
33158
|
-
const pxWidth = width * (tileSize + 2 * CELL_PADDING);
|
|
33159
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(TileGrid, {
|
|
33160
|
-
cells: this.props.cells,
|
|
33161
|
-
size: tileSize,
|
|
33162
|
-
onChange: this._flipTile
|
|
33163
|
-
}), /*#__PURE__*/React__namespace.createElement("div", {
|
|
33164
|
-
style: {
|
|
33165
|
-
width: pxWidth
|
|
33166
|
-
}
|
|
33167
|
-
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
33168
|
-
style: MOVE_COUNT_STYLE
|
|
33169
|
-
}, i18n__namespace.ngettext("Moves: %(num)s", "Moves: %(num)s", this.props.moveCount)), /*#__PURE__*/React__namespace.createElement("div", {
|
|
33170
|
-
style: RESET_BUTTON_STYLE
|
|
33171
|
-
}, /*#__PURE__*/React__namespace.createElement("input", {
|
|
33172
|
-
type: "button",
|
|
33173
|
-
value: "Reset",
|
|
33174
|
-
onClick: this._reset,
|
|
33175
|
-
className: "simple-button"
|
|
33176
|
-
}))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
33177
|
-
className: "clearfix"
|
|
33178
|
-
}));
|
|
33179
|
-
}
|
|
33180
|
-
change = (() => {
|
|
33181
|
-
var _this = this;
|
|
33182
|
-
return function () {
|
|
33183
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
33184
|
-
args[_key] = arguments[_key];
|
|
33185
|
-
}
|
|
33186
|
-
// @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
|
|
33187
|
-
return change.apply(_this, args);
|
|
33188
|
-
};
|
|
33189
|
-
})();
|
|
33190
|
-
_width = () => {
|
|
33191
|
-
if (this.props.cells && this.props.cells.length !== 0) {
|
|
33192
|
-
return this.props.cells[0].length;
|
|
33193
|
-
}
|
|
33194
|
-
return 0; // default to 0
|
|
33195
|
-
};
|
|
33196
|
-
|
|
33197
|
-
componentDidMount() {
|
|
33198
|
-
this._initNextPatterns();
|
|
33199
|
-
}
|
|
33200
|
-
componentDidUpdate(prevProps) {
|
|
33201
|
-
if (prevProps.flipPattern !== this.props.flipPattern) {
|
|
33202
|
-
this._initNextPatterns();
|
|
33203
|
-
}
|
|
33204
|
-
}
|
|
33205
|
-
_initNextPatterns = () => {
|
|
33206
|
-
if (this.props.flipPattern) {
|
|
33207
|
-
this._currPattern = PATTERNS[this.props.flipPattern](0);
|
|
33208
|
-
this._nextPattern = PATTERNS[this.props.flipPattern](1);
|
|
33209
|
-
}
|
|
33210
|
-
this._patternIndex = 2;
|
|
33211
|
-
};
|
|
33212
|
-
_shiftPatterns = () => {
|
|
33213
|
-
if (this.props.flipPattern) {
|
|
33214
|
-
this._currPattern = this._nextPattern;
|
|
33215
|
-
this._nextPattern = PATTERNS[this.props.flipPattern](this._patternIndex);
|
|
33216
|
-
this._patternIndex++;
|
|
33217
|
-
}
|
|
33218
|
-
};
|
|
33219
|
-
_flipTile = _ref => {
|
|
33220
|
-
let {
|
|
33221
|
-
value: {
|
|
33222
|
-
y,
|
|
33223
|
-
x
|
|
33224
|
-
}
|
|
33225
|
-
} = _ref;
|
|
33226
|
-
const newCells = flipTilesPattern(this.props.cells, y, x, this._currPattern);
|
|
33227
|
-
this._shiftPatterns();
|
|
33228
|
-
this.change({
|
|
33229
|
-
cells: newCells,
|
|
33230
|
-
moveCount: (this.props.moveCount || 0) + 1
|
|
33231
|
-
});
|
|
33232
|
-
};
|
|
33233
|
-
_reset = () => {
|
|
33234
|
-
this.change({
|
|
33235
|
-
cells: this.props.startCells,
|
|
33236
|
-
moveCount: 0
|
|
33237
|
-
});
|
|
33238
|
-
};
|
|
33239
|
-
simpleValidate = rubric => {
|
|
33240
|
-
return validate$1(rubric, this.getUserInput());
|
|
33241
|
-
};
|
|
33242
|
-
}
|
|
33243
|
-
|
|
33244
|
-
// grading function
|
|
33245
|
-
const validate$1 = function (rubric, state) {
|
|
33246
|
-
const empty = ___default["default"].all(state.cells, (row, y) => {
|
|
33247
|
-
return ___default["default"].all(row, (cell, x) => {
|
|
33248
|
-
return cell === rubric.startCells[y][x];
|
|
33249
|
-
});
|
|
33250
|
-
});
|
|
33251
|
-
if (empty) {
|
|
33252
|
-
return {
|
|
33253
|
-
type: "invalid",
|
|
33254
|
-
message: i18n__namespace._("Click on the tiles to change the lights.")
|
|
33255
|
-
};
|
|
33256
|
-
}
|
|
33257
|
-
const correct = ___default["default"].all(state.cells, row => {
|
|
33258
|
-
return ___default["default"].all(row, cell => {
|
|
33259
|
-
return cell;
|
|
33260
|
-
});
|
|
33261
|
-
});
|
|
33262
|
-
if (correct) {
|
|
33263
|
-
return {
|
|
33264
|
-
type: "points",
|
|
33265
|
-
earned: 1,
|
|
33266
|
-
total: 1,
|
|
33267
|
-
message: null
|
|
33268
|
-
};
|
|
33269
|
-
}
|
|
33270
|
-
if (rubric.gradeIncompleteAsWrong) {
|
|
33271
|
-
return {
|
|
33272
|
-
type: "points",
|
|
33273
|
-
earned: 0,
|
|
33274
|
-
total: 1,
|
|
33275
|
-
message: null
|
|
33276
|
-
};
|
|
33277
|
-
}
|
|
33278
|
-
return {
|
|
33279
|
-
type: "invalid",
|
|
33280
|
-
message: i18n__namespace._("You must turn on all of the lights to continue.")
|
|
33281
|
-
};
|
|
33282
|
-
};
|
|
33283
|
-
|
|
33284
|
-
// The function run on the editor props to create the widget props
|
|
33285
|
-
const transformProps = function (editorProps) {
|
|
33286
|
-
return {
|
|
33287
|
-
cells: editorProps.startCells,
|
|
33288
|
-
startCells: editorProps.startCells,
|
|
33289
|
-
flipPattern: editorProps.flipPattern
|
|
33290
|
-
};
|
|
33291
|
-
};
|
|
33292
|
-
var LightsPuzzle$1 = {
|
|
33293
|
-
name: "lights-puzzle",
|
|
33294
|
-
displayName: "Lights puzzle (deprecated)",
|
|
33295
|
-
hidden: true,
|
|
33296
|
-
widget: LightsPuzzle,
|
|
33297
|
-
transform: transformProps
|
|
33298
|
-
};
|
|
33299
|
-
|
|
33300
33046
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
33301
33047
|
let Layout = /*#__PURE__*/function (Layout) {
|
|
33302
33048
|
Layout["HORIZONTAL"] = "horizontal";
|
|
@@ -34239,7 +33985,7 @@ var Matcher$1 = {
|
|
|
34239
33985
|
// Type imports
|
|
34240
33986
|
|
|
34241
33987
|
const {
|
|
34242
|
-
assert: assert$
|
|
33988
|
+
assert: assert$2
|
|
34243
33989
|
} = InteractiveUtil;
|
|
34244
33990
|
const {
|
|
34245
33991
|
stringArrayOfSize
|
|
@@ -34273,12 +34019,12 @@ const getDefaultPath$1 = function () {
|
|
|
34273
34019
|
};
|
|
34274
34020
|
const getRowFromPath$1 = function (path) {
|
|
34275
34021
|
// 'path' should be a (row, column) pair
|
|
34276
|
-
assert$
|
|
34022
|
+
assert$2(___default["default"].isArray(path) && path.length === 2);
|
|
34277
34023
|
return +path[0];
|
|
34278
34024
|
};
|
|
34279
34025
|
const getColumnFromPath$1 = function (path) {
|
|
34280
34026
|
// 'path' should be a (row, column) pair
|
|
34281
|
-
assert$
|
|
34027
|
+
assert$2(___default["default"].isArray(path) && path.length === 2);
|
|
34282
34028
|
return +path[1];
|
|
34283
34029
|
};
|
|
34284
34030
|
const getRefForPath$1 = function (path) {
|
|
@@ -34674,7 +34420,7 @@ ___default["default"].extend(Matrix, {
|
|
|
34674
34420
|
};
|
|
34675
34421
|
}
|
|
34676
34422
|
});
|
|
34677
|
-
const propTransform$
|
|
34423
|
+
const propTransform$1 = editorProps => {
|
|
34678
34424
|
// Remove answers before passing to widget
|
|
34679
34425
|
const blankAnswers = ___default["default"](editorProps.matrixBoardSize[0]).times(function () {
|
|
34680
34426
|
return stringArrayOfSize(editorProps.matrixBoardSize[1]);
|
|
@@ -34699,7 +34445,7 @@ var Matrix$1 = {
|
|
|
34699
34445
|
name: "matrix",
|
|
34700
34446
|
displayName: "Matrix",
|
|
34701
34447
|
widget: Matrix,
|
|
34702
|
-
transform: propTransform$
|
|
34448
|
+
transform: propTransform$1,
|
|
34703
34449
|
staticTransform: staticTransform$2,
|
|
34704
34450
|
isLintable: true
|
|
34705
34451
|
};
|
|
@@ -35768,11 +35514,11 @@ var Molecule$1 = {
|
|
|
35768
35514
|
};
|
|
35769
35515
|
|
|
35770
35516
|
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
35771
|
-
const MovablePoint
|
|
35517
|
+
const MovablePoint = Graphie.MovablePoint;
|
|
35772
35518
|
// @ts-expect-error - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
|
|
35773
|
-
const Line
|
|
35519
|
+
const Line = Graphie.Line;
|
|
35774
35520
|
const {
|
|
35775
|
-
assert: assert$
|
|
35521
|
+
assert: assert$1
|
|
35776
35522
|
} = InteractiveUtil;
|
|
35777
35523
|
const bound = (x, gt, lt) => Math.min(Math.max(x, gt), lt);
|
|
35778
35524
|
const EN_DASH = "\u2013";
|
|
@@ -36048,7 +35794,7 @@ class NumberLine extends React__namespace.Component {
|
|
|
36048
35794
|
const snapX = props.tickStep / props.snapDivisions;
|
|
36049
35795
|
let x = bound(numLinePosition, left, right);
|
|
36050
35796
|
x = left + kmath.number.roundTo(x - left, snapX);
|
|
36051
|
-
assert$
|
|
35797
|
+
assert$1(___default["default"].isFinite(x));
|
|
36052
35798
|
return x;
|
|
36053
35799
|
};
|
|
36054
35800
|
|
|
@@ -36087,7 +35833,7 @@ class NumberLine extends React__namespace.Component {
|
|
|
36087
35833
|
stroke: KhanColors.INTERACTIVE,
|
|
36088
35834
|
"fill-opacity": isOpen ? 0 : 1
|
|
36089
35835
|
} : {};
|
|
36090
|
-
return /*#__PURE__*/React__namespace.createElement(MovablePoint
|
|
35836
|
+
return /*#__PURE__*/React__namespace.createElement(MovablePoint
|
|
36091
35837
|
// eslint-disable-next-line react/no-string-refs
|
|
36092
35838
|
, {
|
|
36093
35839
|
ref: "numberLinePoint",
|
|
@@ -36148,7 +35894,7 @@ class NumberLine extends React__namespace.Component {
|
|
|
36148
35894
|
strokeWidth: 3.5
|
|
36149
35895
|
};
|
|
36150
35896
|
const isGreater = ["ge", "gt"].includes(props.rel);
|
|
36151
|
-
return /*#__PURE__*/React__namespace.createElement(Line
|
|
35897
|
+
return /*#__PURE__*/React__namespace.createElement(Line
|
|
36152
35898
|
// We shift the line to either side of the dot so they don't
|
|
36153
35899
|
// intersect
|
|
36154
35900
|
, {
|
|
@@ -40013,843 +39759,40 @@ var PythonProgram$1 = {
|
|
|
40013
39759
|
widget: PythonProgram
|
|
40014
39760
|
};
|
|
40015
39761
|
|
|
40016
|
-
|
|
40017
|
-
|
|
40018
|
-
|
|
40019
|
-
|
|
40020
|
-
|
|
40021
|
-
|
|
40022
|
-
|
|
40023
|
-
|
|
40024
|
-
|
|
40025
|
-
|
|
40026
|
-
|
|
40027
|
-
//
|
|
40028
|
-
|
|
40029
|
-
|
|
40030
|
-
|
|
40031
|
-
|
|
40032
|
-
|
|
40033
|
-
|
|
40034
|
-
|
|
40035
|
-
const offset = 5;
|
|
40036
|
-
// @ts-expect-error - TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
40037
|
-
path.moveTo(offset, canvas.height / 2);
|
|
40038
|
-
// @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
40039
|
-
path.lineTo(canvas.width - offset, canvas.height / 2);
|
|
40040
|
-
// @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
40041
|
-
path.moveTo(canvas.width - 2 * offset, canvas.height / 2 - offset);
|
|
40042
|
-
// @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
40043
|
-
path.lineTo(canvas.width - offset, canvas.height / 2);
|
|
40044
|
-
// @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
40045
|
-
path.moveTo(canvas.width - 2 * offset, canvas.height / 2 + offset);
|
|
40046
|
-
// @ts-expect-error - TS2339 - Property 'width' does not exist on type 'ReactInstance'. | TS2339 - Property 'height' does not exist on type 'ReactInstance'.
|
|
40047
|
-
path.lineTo(canvas.width - offset, canvas.height / 2);
|
|
40048
|
-
ctx.stroke(path);
|
|
39762
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
39763
|
+
const {
|
|
39764
|
+
shuffle
|
|
39765
|
+
} = Util;
|
|
39766
|
+
const HORIZONTAL = "horizontal";
|
|
39767
|
+
const VERTICAL = "vertical";
|
|
39768
|
+
class Sorter extends React__namespace.Component {
|
|
39769
|
+
// @ts-expect-error - TS2564 - Property '_isMounted' has no initializer and is not definitely assigned in the constructor.
|
|
39770
|
+
|
|
39771
|
+
static propTypes = {
|
|
39772
|
+
apiOptions: ApiOptions.propTypes,
|
|
39773
|
+
// eslint-disable-next-line react/forbid-prop-types
|
|
39774
|
+
correct: PropTypes__default["default"].array,
|
|
39775
|
+
layout: PropTypes__default["default"].oneOf([HORIZONTAL, VERTICAL]),
|
|
39776
|
+
onChange: PropTypes__default["default"].func,
|
|
39777
|
+
padding: PropTypes__default["default"].bool,
|
|
39778
|
+
problemNum: PropTypes__default["default"].number,
|
|
39779
|
+
trackInteraction: PropTypes__default["default"].func.isRequired,
|
|
39780
|
+
linterContext: PerseusLinter.linterContextProps
|
|
40049
39781
|
};
|
|
40050
|
-
render() {
|
|
40051
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
40052
|
-
className: "arrow-container"
|
|
40053
|
-
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
40054
|
-
className: "above-text"
|
|
40055
|
-
}, this.props.data.topText), /*#__PURE__*/React__namespace.createElement("canvas", {
|
|
40056
|
-
height: "30",
|
|
40057
|
-
id: "arrowCanvas" + this.props.index,
|
|
40058
|
-
ref: "arrowCanvas" + this.props.index,
|
|
40059
|
-
width: this.arrowLength
|
|
40060
|
-
}, i18n__namespace._("Reaction arrow pointing to the right.")), /*#__PURE__*/React__namespace.createElement("div", {
|
|
40061
|
-
className: "below-text"
|
|
40062
|
-
}, this.props.data.bottomText));
|
|
40063
|
-
}
|
|
40064
|
-
}
|
|
40065
|
-
class ReactionDiagramWidget extends React__namespace.Component {
|
|
40066
39782
|
static defaultProps = {
|
|
40067
|
-
|
|
40068
|
-
|
|
40069
|
-
|
|
40070
|
-
|
|
40071
|
-
|
|
40072
|
-
|
|
40073
|
-
type: "points",
|
|
40074
|
-
earned: 0,
|
|
40075
|
-
total: 0,
|
|
40076
|
-
message: null
|
|
40077
|
-
};
|
|
40078
|
-
};
|
|
40079
|
-
getUserInput = () => {
|
|
40080
|
-
return [];
|
|
39783
|
+
correct: [],
|
|
39784
|
+
layout: HORIZONTAL,
|
|
39785
|
+
padding: true,
|
|
39786
|
+
problemNum: 0,
|
|
39787
|
+
onChange: function () {},
|
|
39788
|
+
linterContext: PerseusLinter.linterContextDefault
|
|
40081
39789
|
};
|
|
40082
|
-
validate
|
|
40083
|
-
|
|
40084
|
-
// Figure out if there's a more appropriate value to return.
|
|
39790
|
+
static validate(state, rubric) {
|
|
39791
|
+
const correct = ___default["default"].isEqual(state.options, rubric.correct);
|
|
40085
39792
|
return {
|
|
40086
39793
|
type: "points",
|
|
40087
|
-
earned: 0,
|
|
40088
|
-
total:
|
|
40089
|
-
message: null
|
|
40090
|
-
};
|
|
40091
|
-
};
|
|
40092
|
-
focus = () => {
|
|
40093
|
-
return true;
|
|
40094
|
-
};
|
|
40095
|
-
render() {
|
|
40096
|
-
return (
|
|
40097
|
-
/*#__PURE__*/
|
|
40098
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40099
|
-
React__namespace.createElement("div", {
|
|
40100
|
-
className: "reaction",
|
|
40101
|
-
ref: "reaction"
|
|
40102
|
-
}, this.props.smiles.map((s, i) => {
|
|
40103
|
-
const id = this.props.widgetId + "-" + i;
|
|
40104
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
40105
|
-
key: id,
|
|
40106
|
-
className: "molecule-container"
|
|
40107
|
-
}, /*#__PURE__*/React__namespace.createElement(Molecule, {
|
|
40108
|
-
widgetId: id,
|
|
40109
|
-
rotationAngle: this.props.rotationAngle[i],
|
|
40110
|
-
smiles: s
|
|
40111
|
-
}), i === this.props.smiles.length - 1 ? null : /*#__PURE__*/React__namespace.createElement(Separator, {
|
|
40112
|
-
data: this.props.separators[i],
|
|
40113
|
-
index: i
|
|
40114
|
-
}));
|
|
40115
|
-
}))
|
|
40116
|
-
);
|
|
40117
|
-
}
|
|
40118
|
-
}
|
|
40119
|
-
var ReactionDiagram = {
|
|
40120
|
-
name: "reaction-diagram",
|
|
40121
|
-
displayName: "Chemical reaction diagram (deprecated)",
|
|
40122
|
-
hidden: true,
|
|
40123
|
-
widget: ReactionDiagramWidget
|
|
40124
|
-
};
|
|
40125
|
-
|
|
40126
|
-
class Sequence extends React__namespace.Component {
|
|
40127
|
-
static defaultProps = {
|
|
40128
|
-
json: [{
|
|
40129
|
-
content: "",
|
|
40130
|
-
widgets: {},
|
|
40131
|
-
images: {}
|
|
40132
|
-
}],
|
|
40133
|
-
linterContext: PerseusLinter.linterContextDefault
|
|
40134
|
-
};
|
|
40135
|
-
state = {
|
|
40136
|
-
visible: 1
|
|
40137
|
-
};
|
|
40138
|
-
shouldComponentUpdate(nextProps, nextState) {
|
|
40139
|
-
return nextProps !== this.props || nextState !== this.state;
|
|
40140
|
-
}
|
|
40141
|
-
change = (() => {
|
|
40142
|
-
var _this = this;
|
|
40143
|
-
return function () {
|
|
40144
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
40145
|
-
args[_key] = arguments[_key];
|
|
40146
|
-
}
|
|
40147
|
-
return change.apply(_this, args);
|
|
40148
|
-
};
|
|
40149
|
-
})();
|
|
40150
|
-
_handleInteraction = groupWidgetId => {
|
|
40151
|
-
const step = parseInt(groupWidgetId.split(" ")[1]);
|
|
40152
|
-
if (step === this.state.visible - 1) {
|
|
40153
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40154
|
-
// @ts-expect-error - TS2339 - Property 'getWidgetInstance' does not exist on type 'ReactInstance'.
|
|
40155
|
-
const widget = this.refs.renderer.getWidgetInstance("group " + step);
|
|
40156
|
-
widget.showRationalesForCurrentlySelectedChoices();
|
|
40157
|
-
const score = widget.simpleValidate();
|
|
40158
|
-
if (score.type === "points" && score.total === score.earned) {
|
|
40159
|
-
this.setState({
|
|
40160
|
-
visible: this.state.visible + 1
|
|
40161
|
-
});
|
|
40162
|
-
this.props.trackInteraction({
|
|
40163
|
-
visible: this.state.visible + 1
|
|
40164
|
-
});
|
|
40165
|
-
}
|
|
40166
|
-
}
|
|
40167
|
-
};
|
|
40168
|
-
render() {
|
|
40169
|
-
const icon = /*#__PURE__*/React__namespace.createElement(InlineIcon, _extends({}, iconOk, {
|
|
40170
|
-
style: {
|
|
40171
|
-
color: "green"
|
|
40172
|
-
}
|
|
40173
|
-
}));
|
|
40174
|
-
const content = ___default["default"].chain(this.props.json).first(this.state.visible).map((step, i) => `[[${Util.snowman} group ${i}]]`).join("\n\n").value();
|
|
40175
|
-
const widgets = {};
|
|
40176
|
-
___default["default"].each(this.props.json, (step, i) => {
|
|
40177
|
-
const widgetId = `group ${i}`;
|
|
40178
|
-
widgets[widgetId] = {
|
|
40179
|
-
type: "group",
|
|
40180
|
-
graded: true,
|
|
40181
|
-
version: {
|
|
40182
|
-
major: 0,
|
|
40183
|
-
minor: 0
|
|
40184
|
-
},
|
|
40185
|
-
options: ___default["default"].extend({}, step, {
|
|
40186
|
-
icon: i < this.state.visible - 1 ? icon : null
|
|
40187
|
-
})
|
|
40188
|
-
};
|
|
40189
|
-
});
|
|
40190
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
40191
|
-
className: "perseus-sequence"
|
|
40192
|
-
}, /*#__PURE__*/React__namespace.createElement(Renderer
|
|
40193
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40194
|
-
, {
|
|
40195
|
-
ref: "renderer",
|
|
40196
|
-
content: content,
|
|
40197
|
-
widgets: widgets,
|
|
40198
|
-
onInteractWithWidget: this._handleInteraction,
|
|
40199
|
-
apiOptions: this.props.apiOptions,
|
|
40200
|
-
linterContext: this.props.linterContext
|
|
40201
|
-
}));
|
|
40202
|
-
}
|
|
40203
|
-
}
|
|
40204
|
-
const traverseChildWidgets = function (props, traverseRenderer) {
|
|
40205
|
-
let oldJson = props.json;
|
|
40206
|
-
if (!___default["default"].isArray(oldJson)) {
|
|
40207
|
-
oldJson = [oldJson];
|
|
40208
|
-
}
|
|
40209
|
-
const json = ___default["default"].map(oldJson, rendererOptions => {
|
|
40210
|
-
return traverseRenderer(rendererOptions);
|
|
40211
|
-
});
|
|
40212
|
-
return ___default["default"].extend({}, props, {
|
|
40213
|
-
json: json
|
|
40214
|
-
});
|
|
40215
|
-
};
|
|
40216
|
-
var Sequence$1 = {
|
|
40217
|
-
name: "sequence",
|
|
40218
|
-
displayName: "Graded sequence (deprecated)",
|
|
40219
|
-
widget: Sequence,
|
|
40220
|
-
traverseChildWidgets: traverseChildWidgets,
|
|
40221
|
-
tracking: "all",
|
|
40222
|
-
hidden: true,
|
|
40223
|
-
isLintable: true
|
|
40224
|
-
};
|
|
40225
|
-
|
|
40226
|
-
/* eslint-disable @typescript-eslint/no-unused-vars, react/no-unsafe, react/sort-comp */
|
|
40227
|
-
const {
|
|
40228
|
-
assert: assert$1
|
|
40229
|
-
} = InteractiveUtil;
|
|
40230
|
-
// @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'.
|
|
40231
|
-
const {
|
|
40232
|
-
Path,
|
|
40233
|
-
Arc,
|
|
40234
|
-
Circle,
|
|
40235
|
-
Label,
|
|
40236
|
-
Line,
|
|
40237
|
-
MovablePoint,
|
|
40238
|
-
MovableLine
|
|
40239
|
-
} = Graphie;
|
|
40240
|
-
const defaultBoxSize = 400;
|
|
40241
|
-
const maxSampleSize = 1000;
|
|
40242
|
-
class Histogram extends React__namespace.Component {
|
|
40243
|
-
static propTypes = {
|
|
40244
|
-
data: PropTypes__default["default"].arrayOf(PropTypes__default["default"].number),
|
|
40245
|
-
xAxisLabel: PropTypes__default["default"].string,
|
|
40246
|
-
yAxisLabel: PropTypes__default["default"].string,
|
|
40247
|
-
box: PropTypes__default["default"].arrayOf(PropTypes__default["default"].number)
|
|
40248
|
-
};
|
|
40249
|
-
static defaultProps = {
|
|
40250
|
-
data: null,
|
|
40251
|
-
xAxisLabel: "Proportion (%)",
|
|
40252
|
-
yAxisLabel: "Number of times seen",
|
|
40253
|
-
box: [defaultBoxSize, defaultBoxSize]
|
|
40254
|
-
};
|
|
40255
|
-
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
40256
|
-
// Reset the threshold if the range has changed
|
|
40257
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40258
|
-
const oldRange = this._range();
|
|
40259
|
-
const nextRange = this._range(nextProps);
|
|
40260
|
-
if (!Util.deepEq(oldRange, nextRange)) {
|
|
40261
|
-
this.setState({
|
|
40262
|
-
threshold: this._getInitialThreshold(nextRange)
|
|
40263
|
-
});
|
|
40264
|
-
}
|
|
40265
|
-
}
|
|
40266
|
-
|
|
40267
|
-
/* Renders the vertical line that users can drag across the histogram. */
|
|
40268
|
-
_renderThresholdLine = () => {
|
|
40269
|
-
// Recall the the y-range goes from [-1, yMax] to allow for ticks on
|
|
40270
|
-
// the x-axis.
|
|
40271
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40272
|
-
const yRange = [0, this._range()[1][1]];
|
|
40273
|
-
const coords = ___default["default"].map(yRange, y => [this.state.threshold, y]);
|
|
40274
|
-
|
|
40275
|
-
// Returns an inivisble, placeholder coord that anchors the line
|
|
40276
|
-
const invisiblePointForCoord = (coord, i) => {
|
|
40277
|
-
return /*#__PURE__*/React__namespace.createElement(MovablePoint, {
|
|
40278
|
-
key: i,
|
|
40279
|
-
static: true,
|
|
40280
|
-
coord: coord,
|
|
40281
|
-
normalStyle: {
|
|
40282
|
-
stroke: "none",
|
|
40283
|
-
fill: "none"
|
|
40284
|
-
}
|
|
40285
|
-
});
|
|
40286
|
-
};
|
|
40287
|
-
return /*#__PURE__*/React__namespace.createElement(MovableLine, {
|
|
40288
|
-
onMove: this.handleMouseInteraction
|
|
40289
|
-
}, ___default["default"].map(coords, invisiblePointForCoord));
|
|
40290
|
-
};
|
|
40291
|
-
|
|
40292
|
-
/* Renders the shaded circle in the top right. */
|
|
40293
|
-
_renderCircle = () => {
|
|
40294
|
-
const data = this.props.data;
|
|
40295
|
-
|
|
40296
|
-
// Get proportion of results below threshold
|
|
40297
|
-
const total = ___default["default"].reduce(data, (sum, next) => {
|
|
40298
|
-
return sum + next;
|
|
40299
|
-
}, 0);
|
|
40300
|
-
const numBelow = ___default["default"].reduce(data, (sum, next, i) => {
|
|
40301
|
-
if (this.state.threshold != null && i <= this.state.threshold) {
|
|
40302
|
-
return sum + next;
|
|
40303
|
-
}
|
|
40304
|
-
return sum;
|
|
40305
|
-
}, 0);
|
|
40306
|
-
const proportionBelow = numBelow / total;
|
|
40307
|
-
|
|
40308
|
-
// This is a hack around the arc taking angles modulo 360.
|
|
40309
|
-
// TODO(charlie): Find a better way around this.
|
|
40310
|
-
const epsilon = 1e-5;
|
|
40311
|
-
const radius = 20;
|
|
40312
|
-
const center = [this.props.box[0] - 1.5 * radius, 1.5 * radius];
|
|
40313
|
-
|
|
40314
|
-
// Plot little circle
|
|
40315
|
-
const plotBelowCircle = () => {
|
|
40316
|
-
const options = {
|
|
40317
|
-
key: "below",
|
|
40318
|
-
center: center,
|
|
40319
|
-
radius: radius,
|
|
40320
|
-
startAngle: 0,
|
|
40321
|
-
endAngle: proportionBelow < 1 ? 360 * proportionBelow : 360 - epsilon,
|
|
40322
|
-
sector: proportionBelow !== 1,
|
|
40323
|
-
unscaled: true,
|
|
40324
|
-
style: {
|
|
40325
|
-
fill: KhanColors.LIGHT_RED,
|
|
40326
|
-
stroke: KhanColors.RED
|
|
40327
|
-
}
|
|
40328
|
-
};
|
|
40329
|
-
return /*#__PURE__*/React__namespace.createElement(Arc, options);
|
|
40330
|
-
};
|
|
40331
|
-
const plotAboveCircle = () => {
|
|
40332
|
-
const options = {
|
|
40333
|
-
key: "above",
|
|
40334
|
-
center: center,
|
|
40335
|
-
radius: radius,
|
|
40336
|
-
startAngle: proportionBelow > 0 ? 360 * proportionBelow : epsilon,
|
|
40337
|
-
endAngle: 360,
|
|
40338
|
-
sector: proportionBelow !== 0,
|
|
40339
|
-
unscaled: true,
|
|
40340
|
-
style: {
|
|
40341
|
-
fill: KhanColors.LIGHT_BLUE,
|
|
40342
|
-
stroke: KhanColors.BLUE
|
|
40343
|
-
}
|
|
40344
|
-
};
|
|
40345
|
-
return /*#__PURE__*/React__namespace.createElement(Arc, options);
|
|
40346
|
-
};
|
|
40347
|
-
|
|
40348
|
-
// Plot the label below the circle
|
|
40349
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40350
|
-
const xRange = this._range()[0];
|
|
40351
|
-
const formattedThreshold = Math.min(Math.max(this.state.threshold, xRange[0]), xRange[1]).toFixed(2);
|
|
40352
|
-
const plotLabel = () => {
|
|
40353
|
-
const options = {
|
|
40354
|
-
key: "label",
|
|
40355
|
-
coord: [center[0], center[1] + 1.5 * radius],
|
|
40356
|
-
text: numBelow + " of " + total + " results below " + formattedThreshold + "%",
|
|
40357
|
-
direction: "center",
|
|
40358
|
-
tex: false,
|
|
40359
|
-
unscaled: true,
|
|
40360
|
-
style: {
|
|
40361
|
-
fontSize: "12px"
|
|
40362
|
-
}
|
|
40363
|
-
};
|
|
40364
|
-
return /*#__PURE__*/React__namespace.createElement(Label, options);
|
|
40365
|
-
};
|
|
40366
|
-
return [proportionBelow > 0 && plotBelowCircle(), proportionBelow < 1 && plotAboveCircle(), plotLabel()];
|
|
40367
|
-
};
|
|
40368
|
-
|
|
40369
|
-
/* Renders the actual bars of the histogram. */
|
|
40370
|
-
_renderData = () => {
|
|
40371
|
-
const data = this.props.data;
|
|
40372
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40373
|
-
this._range();
|
|
40374
|
-
|
|
40375
|
-
// Plot bars
|
|
40376
|
-
const barWidth = 1;
|
|
40377
|
-
const pathForData = (count, i) => {
|
|
40378
|
-
// Avoid plotting bars of height 0, else you get a thick blue line
|
|
40379
|
-
// over the x-axis. We don't filter these out of the data passed in
|
|
40380
|
-
// to this function, however, to preserve absolute indices.
|
|
40381
|
-
if (!count) {
|
|
40382
|
-
return;
|
|
40383
|
-
}
|
|
40384
|
-
const isBelow = this.state.threshold != null && i <= this.state.threshold;
|
|
40385
|
-
const style = {
|
|
40386
|
-
fill: isBelow ? KhanColors.LIGHT_RED : KhanColors.LIGHT_BLUE,
|
|
40387
|
-
stroke: isBelow ? KhanColors.RED : KhanColors.BLUE
|
|
40388
|
-
};
|
|
40389
|
-
const coords = [[i, 0], [i, count], [i + barWidth, count], [i + barWidth, 0]];
|
|
40390
|
-
return /*#__PURE__*/React__namespace.createElement(Path, {
|
|
40391
|
-
key: i,
|
|
40392
|
-
coords: coords,
|
|
40393
|
-
style: style
|
|
40394
|
-
});
|
|
40395
|
-
};
|
|
40396
|
-
return ___default["default"].map(data, pathForData);
|
|
40397
|
-
};
|
|
40398
|
-
render() {
|
|
40399
|
-
const data = this.props.data;
|
|
40400
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40401
|
-
const range = this._range();
|
|
40402
|
-
const options = {
|
|
40403
|
-
xAxisLabel: this.props.xAxisLabel,
|
|
40404
|
-
yAxisLabel: this.props.yAxisLabel,
|
|
40405
|
-
box: this.props.box,
|
|
40406
|
-
range: range,
|
|
40407
|
-
data: data,
|
|
40408
|
-
scale: [Util.scaleFromExtent(range[0], this.props.box[0]), Util.scaleFromExtent(range[1], this.props.box[1])]
|
|
40409
|
-
};
|
|
40410
|
-
const axisStyle = {
|
|
40411
|
-
stroke: "#000",
|
|
40412
|
-
strokeWidth: 1,
|
|
40413
|
-
opacity: 1.0
|
|
40414
|
-
};
|
|
40415
|
-
const origin = [range[0][0], 0];
|
|
40416
|
-
const bottomRight = [range[0][1], 0];
|
|
40417
|
-
return /*#__PURE__*/React__namespace.createElement(Graphie, {
|
|
40418
|
-
box: options.box,
|
|
40419
|
-
range: options.range,
|
|
40420
|
-
options: options,
|
|
40421
|
-
setup: this._setupGraphie,
|
|
40422
|
-
onMouseMove: this.handleMouseInteraction,
|
|
40423
|
-
onMouseDown: this.handleMouseInteraction,
|
|
40424
|
-
setDrawingAreaAvailable: this.props.setDrawingAreaAvailable
|
|
40425
|
-
}, /*#__PURE__*/React__namespace.createElement(Line, {
|
|
40426
|
-
start: origin,
|
|
40427
|
-
end: bottomRight,
|
|
40428
|
-
style: axisStyle
|
|
40429
|
-
}), data && this._renderData(), data && this._renderCircle(), data && this._renderThresholdLine());
|
|
40430
|
-
}
|
|
40431
|
-
_setupGraphie = (graphie, options) => {
|
|
40432
|
-
const data = options.data;
|
|
40433
|
-
const range = options.range;
|
|
40434
|
-
const scale = options.scale;
|
|
40435
|
-
|
|
40436
|
-
/* Plot the bars that run parallel to the x-axis. */
|
|
40437
|
-
const xWidth = range[0][1] - range[0][0];
|
|
40438
|
-
const yWidth = range[1][1] - 0;
|
|
40439
|
-
const maxYAxisEntities = 20;
|
|
40440
|
-
const ySkip = Math.ceil(yWidth / maxYAxisEntities);
|
|
40441
|
-
___default["default"].each(___default["default"].range(0, range[1][1], ySkip), y => {
|
|
40442
|
-
// If there's no data, we don't label the axes
|
|
40443
|
-
if (data) {
|
|
40444
|
-
graphie.label([range[0][0], y], KhanMath.roundToApprox(y, 2), "left", /* isTeX */true /* for the \approx symbol */);
|
|
40445
|
-
}
|
|
40446
|
-
|
|
40447
|
-
graphie.line([range[0][0], y], [range[0][1], y], {
|
|
40448
|
-
stroke: "#000",
|
|
40449
|
-
strokeWidth: 1,
|
|
40450
|
-
opacity: 0.3
|
|
40451
|
-
});
|
|
40452
|
-
});
|
|
40453
|
-
|
|
40454
|
-
// If there's no data, we don't label the x-axis at all
|
|
40455
|
-
if (data) {
|
|
40456
|
-
// Plot the labels below the bars
|
|
40457
|
-
const maxXAxisEntities = 15;
|
|
40458
|
-
const xSkip = Math.ceil(xWidth / maxXAxisEntities);
|
|
40459
|
-
___default["default"].each(___default["default"].range(range[0][0], range[0][1], xSkip), x => {
|
|
40460
|
-
graphie.label([x, 0], kmath.number.round(x, 2), "below", true);
|
|
40461
|
-
const tickHeight = 8;
|
|
40462
|
-
graphie.line([x, 0], [x, -tickHeight / scale[1]], {
|
|
40463
|
-
stroke: "#000",
|
|
40464
|
-
strokeWidth: 1
|
|
40465
|
-
});
|
|
40466
|
-
});
|
|
40467
|
-
}
|
|
40468
|
-
|
|
40469
|
-
// Add y axis (x axis is added later to overlap the bars)
|
|
40470
|
-
const axisStyle = {
|
|
40471
|
-
stroke: "#000",
|
|
40472
|
-
strokeWidth: 2,
|
|
40473
|
-
opacity: 1.0
|
|
40474
|
-
};
|
|
40475
|
-
const origin = [range[0][0], 0];
|
|
40476
|
-
const topLeft = [range[0][0], range[1][1]];
|
|
40477
|
-
graphie.line(origin, topLeft, axisStyle);
|
|
40478
|
-
|
|
40479
|
-
// Add axis labels
|
|
40480
|
-
const xMid = range[0][0] + xWidth / 2;
|
|
40481
|
-
const xOffset = data ? 25 : 0;
|
|
40482
|
-
graphie.label([xMid, -xOffset / scale[1]], options.xAxisLabel, "below", false).css("font-weight", "bold");
|
|
40483
|
-
const yMid = 0 + yWidth / 2;
|
|
40484
|
-
const yOffset = data ? 55 : 28;
|
|
40485
|
-
graphie.label([range[0][0] - yOffset / scale[0], yMid], options.yAxisLabel, "center", false).css("font-weight", "bold").css("-webkit-transform", "rotate(-90deg)");
|
|
40486
|
-
};
|
|
40487
|
-
handleMouseInteraction = point => {
|
|
40488
|
-
this.setState({
|
|
40489
|
-
threshold: point[0]
|
|
40490
|
-
});
|
|
40491
|
-
};
|
|
40492
|
-
|
|
40493
|
-
/* Convenience functions that help calculate props based on other props. */
|
|
40494
|
-
_range = props => {
|
|
40495
|
-
const defaultRange = [[0, 100], [-1, 10]];
|
|
40496
|
-
props = props || this.props;
|
|
40497
|
-
return props.data ? this._getRangeForData(props.data) : defaultRange;
|
|
40498
|
-
};
|
|
40499
|
-
_getRangeForData = data => {
|
|
40500
|
-
// Find first/last non-zero entry and add some padding
|
|
40501
|
-
const padding = 10;
|
|
40502
|
-
const firstIndex = ___default["default"].indexOf(data, ___default["default"].find(data, n => n > 0));
|
|
40503
|
-
const xMin = Math.max(0, firstIndex - padding);
|
|
40504
|
-
const lastIndex = ___default["default"].lastIndexOf(data, ___default["default"].last(___default["default"].filter(data, n => n > 0)));
|
|
40505
|
-
const xMax = Math.min(100 + 1, lastIndex + 1 + padding);
|
|
40506
|
-
|
|
40507
|
-
// The y-axis is bounded above by largest value, and below by 0.
|
|
40508
|
-
// However, the 'range' of the y-axis goes as low as -1 to allow
|
|
40509
|
-
// Graphie to draw ticks on the x-Axis that extend vertically below
|
|
40510
|
-
// y = 0.
|
|
40511
|
-
const yMin = -1;
|
|
40512
|
-
const yMax = ___default["default"].max(data);
|
|
40513
|
-
return [[xMin, xMax], [yMin, yMax]];
|
|
40514
|
-
};
|
|
40515
|
-
_getInitialThreshold = range => {
|
|
40516
|
-
// We pick a pretty-looking threshold, 1/3 of the way along the axis
|
|
40517
|
-
const xRange = range[0];
|
|
40518
|
-
return xRange[0] + (xRange[1] - xRange[0]) / 3;
|
|
40519
|
-
};
|
|
40520
|
-
state = {
|
|
40521
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40522
|
-
threshold: this._getInitialThreshold(this._range())
|
|
40523
|
-
};
|
|
40524
|
-
}
|
|
40525
|
-
class Simulator extends React__namespace.Component {
|
|
40526
|
-
// @ts-expect-error - TS2564 - Property 'generateNumber' has no initializer and is not definitely assigned in the constructor.
|
|
40527
|
-
|
|
40528
|
-
static propTypes = {
|
|
40529
|
-
...propTypes,
|
|
40530
|
-
apiOptions: ApiOptions.propTypes,
|
|
40531
|
-
data: PropTypes__default["default"].arrayOf(PropTypes__default["default"].number),
|
|
40532
|
-
numTrials: PropTypes__default["default"].number,
|
|
40533
|
-
proportionLabel: PropTypes__default["default"].string,
|
|
40534
|
-
proportionOrPercentage: PropTypes__default["default"].string,
|
|
40535
|
-
randomSeed: PropTypes__default["default"].number,
|
|
40536
|
-
sampleSize: PropTypes__default["default"].number,
|
|
40537
|
-
trackInteraction: PropTypes__default["default"].func.isRequired,
|
|
40538
|
-
userProportion: PropTypes__default["default"].number,
|
|
40539
|
-
xAxisLabel: PropTypes__default["default"].string,
|
|
40540
|
-
yAxisLabel: PropTypes__default["default"].string
|
|
40541
|
-
};
|
|
40542
|
-
static defaultProps = {
|
|
40543
|
-
data: null,
|
|
40544
|
-
userProportion: null,
|
|
40545
|
-
sampleSize: null,
|
|
40546
|
-
numTrials: null,
|
|
40547
|
-
randomSeed: 0,
|
|
40548
|
-
xAxisLabel: "Proportion (%)",
|
|
40549
|
-
yAxisLabel: "Number of times seen",
|
|
40550
|
-
proportionLabel: "Underlying proportion",
|
|
40551
|
-
proportionOrPercentage: "proportion",
|
|
40552
|
-
apiOptions: ApiOptions.defaults
|
|
40553
|
-
};
|
|
40554
|
-
state = {
|
|
40555
|
-
invalidInput: false
|
|
40556
|
-
};
|
|
40557
|
-
|
|
40558
|
-
// TODO(jangmi, CP-3288): Remove usage of `UNSAFE_componentWillMount`
|
|
40559
|
-
UNSAFE_componentWillMount() {
|
|
40560
|
-
if (this.props.randomSeed != null) {
|
|
40561
|
-
this.generateNumber = Util.seededRNG(this.props.randomSeed);
|
|
40562
|
-
}
|
|
40563
|
-
}
|
|
40564
|
-
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
40565
|
-
if (nextProps.randomSeed !== this.props.randomSeed) {
|
|
40566
|
-
this.generateNumber = Util.seededRNG(nextProps.randomSeed);
|
|
40567
|
-
}
|
|
40568
|
-
}
|
|
40569
|
-
render() {
|
|
40570
|
-
const inputStyle = {
|
|
40571
|
-
marginLeft: "5px"
|
|
40572
|
-
};
|
|
40573
|
-
const highlight = "0px 0px 0px 2px rgba(255, 165, 0, 1)";
|
|
40574
|
-
const highlightStyle = ___default["default"].extend({}, inputStyle, {
|
|
40575
|
-
boxShadow: highlight,
|
|
40576
|
-
transition: "all 0.15s"
|
|
40577
|
-
});
|
|
40578
|
-
const unhighlightStyle = ___default["default"].extend({}, inputStyle, {
|
|
40579
|
-
transition: "all 0.15s"
|
|
40580
|
-
});
|
|
40581
|
-
const style = this.state.invalidInput ? highlightStyle : unhighlightStyle;
|
|
40582
|
-
const proportionInput = /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(NumberInput
|
|
40583
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40584
|
-
, {
|
|
40585
|
-
ref: "userProportion",
|
|
40586
|
-
style: style,
|
|
40587
|
-
value: this.calculateDisplayProportion(),
|
|
40588
|
-
checkValidity: this.checkProportionValidity,
|
|
40589
|
-
disabled: this.props.apiOptions.readOnly,
|
|
40590
|
-
onChange: this.handleUserProportionChange,
|
|
40591
|
-
onFocus: () => this.props.onFocus(["userProportion"]),
|
|
40592
|
-
onBlur: () => this.props.onBlur(["userProportion"])
|
|
40593
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip, null, /*#__PURE__*/React__namespace.createElement("p", null, i18n__namespace._("This controls the proportion or percentage that will be used in your simulation."))));
|
|
40594
|
-
const sampleSizeInput = /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(NumberInput
|
|
40595
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40596
|
-
, {
|
|
40597
|
-
ref: "sampleSize",
|
|
40598
|
-
style: style,
|
|
40599
|
-
value: this.props.sampleSize,
|
|
40600
|
-
checkValidity: val => val >= 0,
|
|
40601
|
-
disabled: this.props.apiOptions.readOnly,
|
|
40602
|
-
onChange: this.handleSampleSizeChange,
|
|
40603
|
-
onFocus: () => this.props.onFocus(["sampleSize"]),
|
|
40604
|
-
onBlur: () => this.props.onBlur(["sampleSize"])
|
|
40605
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip, null, /*#__PURE__*/React__namespace.createElement("p", null, i18n__namespace._("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."))));
|
|
40606
|
-
const numTrialsDisplay = /*#__PURE__*/React__namespace.createElement("div", {
|
|
40607
|
-
style: {
|
|
40608
|
-
textAlign: "right"
|
|
40609
|
-
}
|
|
40610
|
-
}, /*#__PURE__*/React__namespace.createElement("b", null, this.props.numTrials), /*#__PURE__*/React__namespace.createElement(InfoTip, null, /*#__PURE__*/React__namespace.createElement("p", null, i18n__namespace._("This is the number of trials used in the simulation. For example, if set to 50, then the survey will be conducted 50 times."))));
|
|
40611
|
-
|
|
40612
|
-
// Generates a table from a set of titles and values.
|
|
40613
|
-
const generateTable = contents => {
|
|
40614
|
-
const header = /*#__PURE__*/React__namespace.createElement("thead", null, /*#__PURE__*/React__namespace.createElement("tr", null, /*#__PURE__*/React__namespace.createElement("th", null, i18n__namespace._("Parameter")), /*#__PURE__*/React__namespace.createElement("th", null, i18n__namespace._("Value"))));
|
|
40615
|
-
const body = /*#__PURE__*/React__namespace.createElement("tbody", null, ___default["default"].map(contents, (row, i) => {
|
|
40616
|
-
return /*#__PURE__*/React__namespace.createElement("tr", {
|
|
40617
|
-
key: i
|
|
40618
|
-
}, /*#__PURE__*/React__namespace.createElement("td", null, row.title), /*#__PURE__*/React__namespace.createElement("td", null, row.value));
|
|
40619
|
-
}));
|
|
40620
|
-
return /*#__PURE__*/React__namespace.createElement("table", null, header, body);
|
|
40621
|
-
};
|
|
40622
|
-
|
|
40623
|
-
// Contents for the table to-be generated
|
|
40624
|
-
const contents = [{
|
|
40625
|
-
title: this.props.proportionLabel + ":",
|
|
40626
|
-
value: proportionInput
|
|
40627
|
-
}, {
|
|
40628
|
-
title: i18n__namespace._("Sample size:"),
|
|
40629
|
-
value: sampleSizeInput
|
|
40630
|
-
}, {
|
|
40631
|
-
title: i18n__namespace._("Number of trials:"),
|
|
40632
|
-
value: numTrialsDisplay
|
|
40633
|
-
}];
|
|
40634
|
-
|
|
40635
|
-
// The 'Run Simulation' button
|
|
40636
|
-
const buttonStyle = {
|
|
40637
|
-
margin: "20px 0"
|
|
40638
|
-
};
|
|
40639
|
-
const startButton = /*#__PURE__*/React__namespace.createElement("button", {
|
|
40640
|
-
className: "simple-button",
|
|
40641
|
-
style: buttonStyle,
|
|
40642
|
-
disabled: this.props.apiOptions.readOnly,
|
|
40643
|
-
onClick: this.handleRunSimulation
|
|
40644
|
-
}, i18n__namespace._("Run simulation"));
|
|
40645
|
-
|
|
40646
|
-
// When we plot data, ticks on the x-axis require some vertical padding
|
|
40647
|
-
const histogramStyle = {
|
|
40648
|
-
paddingBottom: this.props.data ? 40 : 0
|
|
40649
|
-
};
|
|
40650
|
-
const histogram = /*#__PURE__*/React__namespace.createElement("div", {
|
|
40651
|
-
style: histogramStyle
|
|
40652
|
-
}, /*#__PURE__*/React__namespace.createElement(Histogram, {
|
|
40653
|
-
data: this.props.data,
|
|
40654
|
-
xAxisLabel: this.props.xAxisLabel,
|
|
40655
|
-
yAxisLabel: this.props.yAxisLabel,
|
|
40656
|
-
setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
|
|
40657
|
-
}));
|
|
40658
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, generateTable(contents), startButton, histogram);
|
|
40659
|
-
}
|
|
40660
|
-
calculateDisplayProportion = () => {
|
|
40661
|
-
const userProportion = this.props.userProportion;
|
|
40662
|
-
|
|
40663
|
-
// If we want to display as a percentage, multiply proportion by 100.0.
|
|
40664
|
-
if (this.props.proportionOrPercentage === "percentage") {
|
|
40665
|
-
return Math.round(100 * userProportion);
|
|
40666
|
-
}
|
|
40667
|
-
return userProportion;
|
|
40668
|
-
};
|
|
40669
|
-
change = (() => {
|
|
40670
|
-
var _this = this;
|
|
40671
|
-
return function () {
|
|
40672
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
40673
|
-
args[_key] = arguments[_key];
|
|
40674
|
-
}
|
|
40675
|
-
// @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
|
|
40676
|
-
return change.apply(_this, args);
|
|
40677
|
-
};
|
|
40678
|
-
})();
|
|
40679
|
-
checkProportionValidity = value => {
|
|
40680
|
-
return value >= 0.0 && this.props.proportionOrPercentage === "proportion" && value <= 1.0 || this.props.proportionOrPercentage === "percentage" && value <= 100.0;
|
|
40681
|
-
};
|
|
40682
|
-
handleUserProportionChange = (value, cb) => {
|
|
40683
|
-
let userProportion;
|
|
40684
|
-
|
|
40685
|
-
// If "percentage" mode is enabled, user will have entered value as
|
|
40686
|
-
// a percentage. However, we always store as a proportion, so we cast.
|
|
40687
|
-
if (this.props.proportionOrPercentage === "percentage") {
|
|
40688
|
-
userProportion = value / 100.0;
|
|
40689
|
-
} else {
|
|
40690
|
-
userProportion = value;
|
|
40691
|
-
}
|
|
40692
|
-
|
|
40693
|
-
// If they entered a number, we may need to cap it
|
|
40694
|
-
if (userProportion != null) {
|
|
40695
|
-
userProportion = Math.min(1.0, Math.max(0.0, userProportion));
|
|
40696
|
-
}
|
|
40697
|
-
this.props.onChange({
|
|
40698
|
-
userProportion: userProportion
|
|
40699
|
-
}, cb);
|
|
40700
|
-
};
|
|
40701
|
-
|
|
40702
|
-
// @ts-expect-error - TS2322 - Type '(sampleSize: any, cb: any) => void' is not assignable to type '(number: any) => void'.
|
|
40703
|
-
handleSampleSizeChange = (sampleSize, cb) => {
|
|
40704
|
-
if (sampleSize != null) {
|
|
40705
|
-
sampleSize = Math.min(maxSampleSize, Math.max(0, Math.floor(sampleSize)));
|
|
40706
|
-
}
|
|
40707
|
-
this.props.onChange({
|
|
40708
|
-
sampleSize: sampleSize
|
|
40709
|
-
}, cb);
|
|
40710
|
-
};
|
|
40711
|
-
handleRunSimulation = () => {
|
|
40712
|
-
// If they haven't filled out a parameter field, highlight it.
|
|
40713
|
-
if (this.props.numTrials == null || this.props.userProportion == null || this.props.sampleSize == null) {
|
|
40714
|
-
this.setState({
|
|
40715
|
-
invalidInput: true
|
|
40716
|
-
});
|
|
40717
|
-
return;
|
|
40718
|
-
}
|
|
40719
|
-
this.setState({
|
|
40720
|
-
invalidInput: false
|
|
40721
|
-
});
|
|
40722
|
-
this.props.onChange({
|
|
40723
|
-
// @ts-expect-error - TS2554 - Expected 1 arguments, but got 0.
|
|
40724
|
-
data: this.generateData()
|
|
40725
|
-
});
|
|
40726
|
-
this.props.trackInteraction();
|
|
40727
|
-
};
|
|
40728
|
-
generateData = props => {
|
|
40729
|
-
props = props || this.props;
|
|
40730
|
-
const getSampleDistribution = (sampleSize, numTrials, proportion) => {
|
|
40731
|
-
const draw = () => {
|
|
40732
|
-
return this.generateNumber() < proportion;
|
|
40733
|
-
};
|
|
40734
|
-
const sampleDistribution = ___default["default"].times(100 + 1, () => 0);
|
|
40735
|
-
___default["default"].times(numTrials, () => {
|
|
40736
|
-
const results = ___default["default"].times(sampleSize, draw);
|
|
40737
|
-
const count = ___default["default"].filter(results, ___default["default"].identity).length;
|
|
40738
|
-
const normalizedCount = Math.floor(100 * count / sampleSize);
|
|
40739
|
-
sampleDistribution[normalizedCount]++;
|
|
40740
|
-
});
|
|
40741
|
-
return sampleDistribution;
|
|
40742
|
-
};
|
|
40743
|
-
return getSampleDistribution(props.sampleSize, props.numTrials, props.userProportion);
|
|
40744
|
-
};
|
|
40745
|
-
|
|
40746
|
-
/* InputPath API */
|
|
40747
|
-
getInputPaths = () => {
|
|
40748
|
-
return [["userProportion"], ["sampleSize"]];
|
|
40749
|
-
};
|
|
40750
|
-
focus = () => {
|
|
40751
|
-
const path = ___default["default"].head(this.getInputPaths());
|
|
40752
|
-
this.focusInputPath(path);
|
|
40753
|
-
return true;
|
|
40754
|
-
};
|
|
40755
|
-
focusInputPath = path => {
|
|
40756
|
-
assert$1(path.length > 0);
|
|
40757
|
-
const inputID = ___default["default"].head(path);
|
|
40758
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40759
|
-
const inputComponent = this.refs[inputID];
|
|
40760
|
-
// @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
|
|
40761
|
-
inputComponent.focus();
|
|
40762
|
-
};
|
|
40763
|
-
blurInputPath = path => {
|
|
40764
|
-
assert$1(path.length > 0);
|
|
40765
|
-
const inputID = ___default["default"].head(path);
|
|
40766
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40767
|
-
const inputComponent = this.refs[inputID];
|
|
40768
|
-
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type 'ReactInstance'.
|
|
40769
|
-
inputComponent.blur();
|
|
40770
|
-
};
|
|
40771
|
-
getDOMNodeForPath = path => {
|
|
40772
|
-
assert$1(path.length > 0);
|
|
40773
|
-
const inputID = ___default["default"].head(path);
|
|
40774
|
-
// eslint-disable-next-line react/no-string-refs
|
|
40775
|
-
return ReactDOM__default["default"].findDOMNode(this.refs[inputID]);
|
|
40776
|
-
};
|
|
40777
|
-
getGrammarTypeForPath = path => {
|
|
40778
|
-
assert$1(path.length > 0);
|
|
40779
|
-
return "number";
|
|
40780
|
-
};
|
|
40781
|
-
setInputValue = (path, newValue, cb) => {
|
|
40782
|
-
assert$1(path.length > 0);
|
|
40783
|
-
const inputID = ___default["default"].head(path);
|
|
40784
|
-
const capitalizedID = inputID.charAt(0).toUpperCase() + inputID.slice(1);
|
|
40785
|
-
const functionName = "handle" + capitalizedID + "Change";
|
|
40786
|
-
this[functionName](newValue, cb);
|
|
40787
|
-
};
|
|
40788
|
-
getUserInput = () => {
|
|
40789
|
-
return null;
|
|
40790
|
-
};
|
|
40791
|
-
simpleValidate = rubric => {
|
|
40792
|
-
// @ts-expect-error - TS2339 - Property 'validate' does not exist on type 'typeof Simulator'.
|
|
40793
|
-
return Simulator.validate(this.getUserInput(), rubric);
|
|
40794
|
-
};
|
|
40795
|
-
}
|
|
40796
|
-
___default["default"].extend(Simulator, {
|
|
40797
|
-
validate: function (state, rubric) {
|
|
40798
|
-
return {
|
|
40799
|
-
type: "points",
|
|
40800
|
-
earned: 0,
|
|
40801
|
-
total: 0,
|
|
40802
|
-
message: null
|
|
40803
|
-
};
|
|
40804
|
-
}
|
|
40805
|
-
});
|
|
40806
|
-
const propTransform$1 = editorProps => {
|
|
40807
|
-
const widgetProps = ___default["default"].clone(editorProps);
|
|
40808
|
-
widgetProps.randomSeed = editorProps.problemNum;
|
|
40809
|
-
return widgetProps;
|
|
40810
|
-
};
|
|
40811
|
-
var Simulator$1 = {
|
|
40812
|
-
name: "simulator",
|
|
40813
|
-
displayName: "Simulator (deprecated)",
|
|
40814
|
-
widget: Simulator,
|
|
40815
|
-
transform: propTransform$1,
|
|
40816
|
-
hidden: true
|
|
40817
|
-
};
|
|
40818
|
-
|
|
40819
|
-
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
40820
|
-
const {
|
|
40821
|
-
shuffle
|
|
40822
|
-
} = Util;
|
|
40823
|
-
const HORIZONTAL = "horizontal";
|
|
40824
|
-
const VERTICAL = "vertical";
|
|
40825
|
-
class Sorter extends React__namespace.Component {
|
|
40826
|
-
// @ts-expect-error - TS2564 - Property '_isMounted' has no initializer and is not definitely assigned in the constructor.
|
|
40827
|
-
|
|
40828
|
-
static propTypes = {
|
|
40829
|
-
apiOptions: ApiOptions.propTypes,
|
|
40830
|
-
// eslint-disable-next-line react/forbid-prop-types
|
|
40831
|
-
correct: PropTypes__default["default"].array,
|
|
40832
|
-
layout: PropTypes__default["default"].oneOf([HORIZONTAL, VERTICAL]),
|
|
40833
|
-
onChange: PropTypes__default["default"].func,
|
|
40834
|
-
padding: PropTypes__default["default"].bool,
|
|
40835
|
-
problemNum: PropTypes__default["default"].number,
|
|
40836
|
-
trackInteraction: PropTypes__default["default"].func.isRequired,
|
|
40837
|
-
linterContext: PerseusLinter.linterContextProps
|
|
40838
|
-
};
|
|
40839
|
-
static defaultProps = {
|
|
40840
|
-
correct: [],
|
|
40841
|
-
layout: HORIZONTAL,
|
|
40842
|
-
padding: true,
|
|
40843
|
-
problemNum: 0,
|
|
40844
|
-
onChange: function () {},
|
|
40845
|
-
linterContext: PerseusLinter.linterContextDefault
|
|
40846
|
-
};
|
|
40847
|
-
static validate(state, rubric) {
|
|
40848
|
-
const correct = ___default["default"].isEqual(state.options, rubric.correct);
|
|
40849
|
-
return {
|
|
40850
|
-
type: "points",
|
|
40851
|
-
earned: correct ? 1 : 0,
|
|
40852
|
-
total: 1,
|
|
39794
|
+
earned: correct ? 1 : 0,
|
|
39795
|
+
total: 1,
|
|
40853
39796
|
message: null
|
|
40854
39797
|
};
|
|
40855
39798
|
}
|
|
@@ -42313,7 +41256,7 @@ var Video$1 = {
|
|
|
42313
41256
|
};
|
|
42314
41257
|
|
|
42315
41258
|
/* eslint-disable import/no-named-as-default */
|
|
42316
|
-
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,
|
|
41259
|
+
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];
|
|
42317
41260
|
|
|
42318
41261
|
/**
|
|
42319
41262
|
* This should be called by all clients, specifying whether extra widgets are
|
|
@@ -42327,7 +41270,7 @@ var extraWidgets = [Categorizer$1, CSProgram$1, Dropdown$1, Explanation$1, Defin
|
|
|
42327
41270
|
const init = function (options) {
|
|
42328
41271
|
registerWidgets(basicWidgets);
|
|
42329
41272
|
registerWidgets(extraWidgets);
|
|
42330
|
-
|
|
41273
|
+
replaceDeprecatedWidgets();
|
|
42331
41274
|
|
|
42332
41275
|
// Pass skipMathJax: true if MathJax is already loaded and configured.
|
|
42333
41276
|
const skipMathJax = options.skipMathJax;
|
|
@@ -42353,7 +41296,7 @@ const init = function (options) {
|
|
|
42353
41296
|
|
|
42354
41297
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
42355
41298
|
const libName = "@khanacademy/perseus";
|
|
42356
|
-
const libVersion = "
|
|
41299
|
+
const libVersion = "20.0.1";
|
|
42357
41300
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
42358
41301
|
|
|
42359
41302
|
const apiVersion = {
|
|
@@ -43477,14 +42420,6 @@ const ItemExtras = [
|
|
|
43477
42420
|
|
|
43478
42421
|
// prettier-ignore
|
|
43479
42422
|
|
|
43480
|
-
// prettier-ignore
|
|
43481
|
-
|
|
43482
|
-
// prettier-ignore
|
|
43483
|
-
|
|
43484
|
-
// prettier-ignore
|
|
43485
|
-
|
|
43486
|
-
// prettier-ignore
|
|
43487
|
-
|
|
43488
42423
|
//prettier-ignore
|
|
43489
42424
|
|
|
43490
42425
|
// A background image applied to various widgets.
|
|
@@ -43532,7 +42467,7 @@ const deepCallbackFor = function (contentCallback, widgetCallback, optionsCallba
|
|
|
43532
42467
|
// on getDefaultProps, this will become easier.
|
|
43533
42468
|
let newWidgetInfo;
|
|
43534
42469
|
if (latestVersion && upgradedWidgetInfo.version?.major === latestVersion.major) {
|
|
43535
|
-
newWidgetInfo = traverseChildWidgets$
|
|
42470
|
+
newWidgetInfo = traverseChildWidgets$3(upgradedWidgetInfo, rendererOptions => {
|
|
43536
42471
|
return traverseRenderer$1(rendererOptions, contentCallback,
|
|
43537
42472
|
// so that we traverse grandchildren, too:
|
|
43538
42473
|
deepCallback, optionsCallback);
|
|
@@ -44607,7 +43542,7 @@ function violatingWidgets(itemData) {
|
|
|
44607
43542
|
*/
|
|
44608
43543
|
const registerAllWidgetsForTesting = () => {
|
|
44609
43544
|
registerWidgets(allWidgets);
|
|
44610
|
-
|
|
43545
|
+
replaceDeprecatedWidgets();
|
|
44611
43546
|
};
|
|
44612
43547
|
|
|
44613
43548
|
/**
|