@khanacademy/perseus 37.0.0 → 38.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/all-widgets.d.ts +1 -0
- package/dist/basic-widgets.d.ts +1 -0
- package/dist/es/index.js +134 -114
- package/dist/es/index.js.map +1 -1
- package/dist/extra-widgets.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +131 -112
- package/dist/index.js.map +1 -1
- package/dist/multi-items/item-types.d.ts +4 -3
- package/dist/perseus-api.d.ts +7 -6
- package/dist/perseus-types.d.ts +31 -30
- package/dist/server-item-renderer.d.ts +8 -9
- package/dist/types.d.ts +3 -5
- package/dist/util/extract-perseus-data.d.ts +1 -1
- package/dist/validation.types.d.ts +4 -11
- package/dist/widgets/categorizer/categorizer.d.ts +1 -0
- package/dist/widgets/cs-program/cs-program.d.ts +1 -0
- package/dist/widgets/definition/definition.d.ts +1 -0
- package/dist/widgets/deprecated-standin/deprecated-standin.d.ts +1 -0
- package/dist/widgets/dropdown/dropdown.d.ts +1 -0
- package/dist/widgets/explanation/explanation.d.ts +1 -0
- package/dist/widgets/expression/expression.d.ts +43 -37
- package/dist/widgets/graded-group/graded-group.d.ts +1 -0
- package/dist/widgets/graded-group-set/graded-group-set.d.ts +1 -0
- package/dist/widgets/grapher/grapher-types.d.ts +58 -0
- package/dist/widgets/grapher/grapher-validator.d.ts +1 -1
- package/dist/widgets/grapher/grapher.d.ts +1 -0
- package/dist/widgets/grapher/util.d.ts +16 -3
- package/dist/widgets/group/group.d.ts +1 -0
- package/dist/widgets/iframe/iframe.d.ts +1 -0
- package/dist/widgets/image/image.d.ts +1 -0
- package/dist/widgets/input-number/input-number.d.ts +1 -1
- package/dist/widgets/interaction/interaction.d.ts +1 -0
- package/dist/widgets/interactive-graph.d.ts +1 -0
- package/dist/widgets/interactive-graphs/mafs-supported-graph-types.d.ts +1 -1
- package/dist/widgets/label-image/label-image.d.ts +15 -12
- package/dist/widgets/matcher/matcher.d.ts +1 -0
- package/dist/widgets/matrix/matrix.d.ts +1 -0
- package/dist/widgets/measurer/measurer.d.ts +1 -0
- package/dist/widgets/molecule/molecule.d.ts +1 -0
- package/dist/widgets/number-line/number-line.d.ts +1 -0
- package/dist/widgets/numeric-input/numeric-input.d.ts +1 -1
- package/dist/widgets/orderer/orderer.d.ts +1 -0
- package/dist/widgets/passage/passage.d.ts +1 -0
- package/dist/widgets/passage-ref/passage-ref.d.ts +1 -0
- package/dist/widgets/passage-ref-target/passage-ref-target.d.ts +1 -0
- package/dist/widgets/phet-simulation/phet-simulation.d.ts +1 -0
- package/dist/widgets/plotter/plotter.d.ts +1 -0
- package/dist/widgets/python-program/python-program.d.ts +1 -0
- package/dist/widgets/radio/radio.d.ts +1 -0
- package/dist/widgets/sorter/sorter.d.ts +1 -0
- package/dist/widgets/table/table.d.ts +1 -0
- package/dist/widgets/video/video.d.ts +1 -0
- package/dist/widgets.d.ts +1 -0
- package/package.json +1 -1
package/dist/extra-widgets.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ declare const _default: readonly Readonly<{
|
|
|
16
16
|
transform?: import("./types").WidgetTransform | undefined;
|
|
17
17
|
staticTransform?: import("./types").WidgetTransform | undefined;
|
|
18
18
|
validator?: import("./types").WidgetValidatorFunction | undefined;
|
|
19
|
+
getOneCorrectAnswerFromRubric?: ((rubric: import("./validation.types").Rubric) => string | null | undefined) | undefined;
|
|
19
20
|
propUpgrades?: {
|
|
20
21
|
[key: string]: (arg1: any) => any;
|
|
21
22
|
} | undefined;
|
package/dist/index.d.ts
CHANGED
|
@@ -82,7 +82,7 @@ export { default as WIDGET_PROP_DENYLIST } from "./mixins/widget-prop-denylist";
|
|
|
82
82
|
export type { PerseusOptions } from "./init";
|
|
83
83
|
export type { ILogger, LogErrorOptions } from "./logging/log";
|
|
84
84
|
export type { ServerItemRenderer as ServerItemRendererComponent } from "./server-item-renderer";
|
|
85
|
-
export type { Alignment, APIOptions, APIOptionsWithDefaults, ChangeHandler, DeviceType, DomInsertCheckFn, EditorMode, FocusPath, ImageDict, ImageUploader, JiptLabelStore, JiptRenderer, PerseusDependencies, PerseusScore, Version, VideoData, VideoKind,
|
|
85
|
+
export type { Alignment, APIOptions, APIOptionsWithDefaults, ChangeHandler, DeviceType, DomInsertCheckFn, EditorMode, FocusPath, ImageDict, ImageUploader, JiptLabelStore, JiptRenderer, PerseusDependencies, PerseusScore, Version, VideoData, VideoKind, WidgetExports, SharedRendererProps, } from "./types";
|
|
86
86
|
export type { ParsedValue } from "./util";
|
|
87
87
|
export type { Hint, LegacyButtonSets, LockedFigure, LockedFigureColor, LockedFigureFillType, LockedFigureType, LockedPointType, LockedLineType, LockedVectorType, LockedEllipseType, LockedPolygonType, LockedFunctionType, LockedLabelType, PerseusGraphType, PerseusAnswerArea, PerseusExpressionWidgetOptions, Range, Size, CollinearTuple, MathFormat, InputNumberWidget, // TODO(jeremy): remove?
|
|
88
88
|
PerseusImageBackground, PerseusInputNumberWidgetOptions, PerseusInteractiveGraphWidgetOptions, PerseusItem, PerseusPhetSimulationWidgetOptions, PerseusPlotterWidgetOptions, PerseusPythonProgramWidgetOptions, PerseusRadioWidgetOptions, PerseusExampleWidgetOptions, PerseusSimpleMarkdownTesterWidgetOptions, PerseusRenderer, PerseusWidget, PerseusWidgetsMap, MultiItem, } from "./perseus-types";
|
package/dist/index.js
CHANGED
|
@@ -2394,15 +2394,6 @@ class Expression extends React__namespace.Component {
|
|
|
2394
2394
|
static getUserInputFromProps(props) {
|
|
2395
2395
|
return normalizeTex(props.value);
|
|
2396
2396
|
}
|
|
2397
|
-
static getOneCorrectAnswerFromRubric(rubric) {
|
|
2398
|
-
const correctAnswers = (rubric.answerForms || []).filter(answerForm => answerForm.considered === "correct");
|
|
2399
|
-
if (correctAnswers.length === 0) {
|
|
2400
|
-
return;
|
|
2401
|
-
}
|
|
2402
|
-
return correctAnswers[0].value;
|
|
2403
|
-
}
|
|
2404
|
-
//#endregion
|
|
2405
|
-
|
|
2406
2397
|
static defaultProps = {
|
|
2407
2398
|
value: "",
|
|
2408
2399
|
times: false,
|
|
@@ -2728,11 +2719,7 @@ const ExpressionWithDependencies = /*#__PURE__*/React__namespace.forwardRef((pro
|
|
|
2728
2719
|
// methods and instead adjust Perseus to provide these facilities through
|
|
2729
2720
|
// instance methods on our Renderers.
|
|
2730
2721
|
// @ts-expect-error - TS2339 - Property 'validate' does not exist on type
|
|
2731
|
-
ExpressionWithDependencies.validate = expressionValidator;
|
|
2732
|
-
// @ts-expect-error - TS2339 - Property 'validate' does not exist on type
|
|
2733
2722
|
ExpressionWithDependencies.getUserInputFromProps = Expression.getUserInputFromProps;
|
|
2734
|
-
// @ts-expect-error - TS2339 - Property 'validate' does not exist on type
|
|
2735
|
-
ExpressionWithDependencies.getOneCorrectAnswerFromRubric = Expression.getOneCorrectAnswerFromRubric;
|
|
2736
2723
|
var Expression$1 = {
|
|
2737
2724
|
name: "expression",
|
|
2738
2725
|
displayName: "Expression / Equation",
|
|
@@ -2765,7 +2752,14 @@ var Expression$1 = {
|
|
|
2765
2752
|
propUpgrades: propUpgrades$2,
|
|
2766
2753
|
// For use by the editor
|
|
2767
2754
|
isLintable: true,
|
|
2768
|
-
validator: expressionValidator
|
|
2755
|
+
validator: expressionValidator,
|
|
2756
|
+
getOneCorrectAnswerFromRubric(rubric) {
|
|
2757
|
+
const correctAnswers = (rubric.answerForms || []).filter(answerForm => answerForm.considered === "correct");
|
|
2758
|
+
if (correctAnswers.length === 0) {
|
|
2759
|
+
return;
|
|
2760
|
+
}
|
|
2761
|
+
return correctAnswers[0].value;
|
|
2762
|
+
}
|
|
2769
2763
|
};
|
|
2770
2764
|
|
|
2771
2765
|
/**
|
|
@@ -10090,9 +10084,6 @@ const setLabelMargins = function (span, size) {
|
|
|
10090
10084
|
// Inherited line-height values can really mess up placement.
|
|
10091
10085
|
$container.css("line-height", "normal");
|
|
10092
10086
|
|
|
10093
|
-
// TODO: Verify that this change doesn't impact other graphies
|
|
10094
|
-
// Check the full list of consuming widgets.
|
|
10095
|
-
|
|
10096
10087
|
// If the change in line-height affected the height of the element,
|
|
10097
10088
|
// then the height used for calculations should be updated.
|
|
10098
10089
|
// This can happen when the first label in the container calls this method,
|
|
@@ -19087,6 +19078,9 @@ const getWidget = name => {
|
|
|
19087
19078
|
}
|
|
19088
19079
|
return widgets[name].widget;
|
|
19089
19080
|
};
|
|
19081
|
+
const getWidgetExport = name => {
|
|
19082
|
+
return widgets[name] ?? null;
|
|
19083
|
+
};
|
|
19090
19084
|
const getWidgetValidator = name => {
|
|
19091
19085
|
return widgets[name]?.validator ?? null;
|
|
19092
19086
|
};
|
|
@@ -19395,6 +19389,7 @@ var widgets$1 = /*#__PURE__*/Object.freeze({
|
|
|
19395
19389
|
replaceEditor: replaceEditor,
|
|
19396
19390
|
replaceDeprecatedEditors: replaceDeprecatedEditors,
|
|
19397
19391
|
getWidget: getWidget,
|
|
19392
|
+
getWidgetExport: getWidgetExport,
|
|
19398
19393
|
getWidgetValidator: getWidgetValidator,
|
|
19399
19394
|
getEditor: getEditor,
|
|
19400
19395
|
getTransform: getTransform,
|
|
@@ -21988,16 +21983,6 @@ class InputNumber extends React__namespace.Component {
|
|
|
21988
21983
|
currentValue: props.currentValue
|
|
21989
21984
|
};
|
|
21990
21985
|
}
|
|
21991
|
-
static getOneCorrectAnswerFromRubric(rubric) {
|
|
21992
|
-
if (rubric.value == null) {
|
|
21993
|
-
return;
|
|
21994
|
-
}
|
|
21995
|
-
let answerString = String(rubric.value);
|
|
21996
|
-
if (rubric.inexact && rubric.maxError) {
|
|
21997
|
-
answerString += " \u00B1 " + rubric.maxError;
|
|
21998
|
-
}
|
|
21999
|
-
return answerString;
|
|
22000
|
-
}
|
|
22001
21986
|
shouldShowExamples = () => {
|
|
22002
21987
|
return this.props.answerType !== "number";
|
|
22003
21988
|
};
|
|
@@ -22156,7 +22141,17 @@ var InputNumber$1 = {
|
|
|
22156
22141
|
widget: InputNumber,
|
|
22157
22142
|
transform: propTransform$3,
|
|
22158
22143
|
isLintable: true,
|
|
22159
|
-
validator: inputNumberValidator
|
|
22144
|
+
validator: inputNumberValidator,
|
|
22145
|
+
getOneCorrectAnswerFromRubric(rubric) {
|
|
22146
|
+
if (rubric.value == null) {
|
|
22147
|
+
return;
|
|
22148
|
+
}
|
|
22149
|
+
let answerString = String(rubric.value);
|
|
22150
|
+
if (rubric.inexact && rubric.maxError) {
|
|
22151
|
+
answerString += " \u00B1 " + rubric.maxError;
|
|
22152
|
+
}
|
|
22153
|
+
return answerString;
|
|
22154
|
+
}
|
|
22160
22155
|
};
|
|
22161
22156
|
|
|
22162
22157
|
const ParseTex = TexWrangler.parseTex;
|
|
@@ -22335,34 +22330,6 @@ class NumericInput extends React__namespace.Component {
|
|
|
22335
22330
|
currentValue: props.currentValue
|
|
22336
22331
|
};
|
|
22337
22332
|
}
|
|
22338
|
-
static getOneCorrectAnswerFromRubric(rubric) {
|
|
22339
|
-
const correctAnswers = rubric.answers.filter(answer => answer.status === "correct");
|
|
22340
|
-
const answerStrings = correctAnswers.map(answer => {
|
|
22341
|
-
// Figure out how this answer is supposed to be
|
|
22342
|
-
// displayed
|
|
22343
|
-
let format = "decimal";
|
|
22344
|
-
if (answer.answerForms && answer.answerForms[0]) {
|
|
22345
|
-
// NOTE(johnsullivan): This isn't exactly ideal, but
|
|
22346
|
-
// it does behave well for all the currently known
|
|
22347
|
-
// problems. See D14742 for some discussion on
|
|
22348
|
-
// alternate strategies.
|
|
22349
|
-
format = answer.answerForms[0];
|
|
22350
|
-
}
|
|
22351
|
-
|
|
22352
|
-
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'MathFormat | undefined'.
|
|
22353
|
-
let answerString = KhanMath.toNumericString(answer.value, format);
|
|
22354
|
-
if (answer.maxError) {
|
|
22355
|
-
answerString += " \u00B1 " +
|
|
22356
|
-
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'MathFormat | undefined'.
|
|
22357
|
-
KhanMath.toNumericString(answer.maxError, format);
|
|
22358
|
-
}
|
|
22359
|
-
return answerString;
|
|
22360
|
-
});
|
|
22361
|
-
if (answerStrings.length === 0) {
|
|
22362
|
-
return;
|
|
22363
|
-
}
|
|
22364
|
-
return answerStrings[0];
|
|
22365
|
-
}
|
|
22366
22333
|
state = {
|
|
22367
22334
|
// keeps track of the other set of values when switching
|
|
22368
22335
|
// between 0 and finite solutions
|
|
@@ -22549,7 +22516,35 @@ var NumericInput$1 = {
|
|
|
22549
22516
|
widget: NumericInput,
|
|
22550
22517
|
transform: propsTransform,
|
|
22551
22518
|
isLintable: true,
|
|
22552
|
-
validator: numericInputValidator
|
|
22519
|
+
validator: numericInputValidator,
|
|
22520
|
+
getOneCorrectAnswerFromRubric(rubric) {
|
|
22521
|
+
const correctAnswers = rubric.answers.filter(answer => answer.status === "correct");
|
|
22522
|
+
const answerStrings = correctAnswers.map(answer => {
|
|
22523
|
+
// Figure out how this answer is supposed to be
|
|
22524
|
+
// displayed
|
|
22525
|
+
let format = "decimal";
|
|
22526
|
+
if (answer.answerForms && answer.answerForms[0]) {
|
|
22527
|
+
// NOTE(johnsullivan): This isn't exactly ideal, but
|
|
22528
|
+
// it does behave well for all the currently known
|
|
22529
|
+
// problems. See D14742 for some discussion on
|
|
22530
|
+
// alternate strategies.
|
|
22531
|
+
format = answer.answerForms[0];
|
|
22532
|
+
}
|
|
22533
|
+
|
|
22534
|
+
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'MathFormat | undefined'.
|
|
22535
|
+
let answerString = KhanMath.toNumericString(answer.value, format);
|
|
22536
|
+
if (answer.maxError) {
|
|
22537
|
+
answerString += " \u00B1 " +
|
|
22538
|
+
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'MathFormat | undefined'.
|
|
22539
|
+
KhanMath.toNumericString(answer.maxError, format);
|
|
22540
|
+
}
|
|
22541
|
+
return answerString;
|
|
22542
|
+
});
|
|
22543
|
+
if (answerStrings.length === 0) {
|
|
22544
|
+
return;
|
|
22545
|
+
}
|
|
22546
|
+
return answerStrings[0];
|
|
22547
|
+
}
|
|
22553
22548
|
};
|
|
22554
22549
|
|
|
22555
22550
|
/**
|
|
@@ -28541,7 +28536,7 @@ const Exponential = ___default["default"].extend({}, PlotDefaults, {
|
|
|
28541
28536
|
* coordinate, and `false` uses oldCoord as the resulting coordinate.
|
|
28542
28537
|
*/
|
|
28543
28538
|
extraCoordConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
|
|
28544
|
-
const y =
|
|
28539
|
+
const y = asymptote[0][1];
|
|
28545
28540
|
return ___default["default"].all(coords, coord => coord[1] !== y);
|
|
28546
28541
|
},
|
|
28547
28542
|
extraAsymptoteConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
|
|
@@ -28565,7 +28560,7 @@ const Exponential = ___default["default"].extend({}, PlotDefaults, {
|
|
|
28565
28560
|
getCoefficients: function (coords, asymptote) {
|
|
28566
28561
|
const p1 = coords[0];
|
|
28567
28562
|
const p2 = coords[1];
|
|
28568
|
-
const c =
|
|
28563
|
+
const c = asymptote[0][1];
|
|
28569
28564
|
const b = Math.log((p1[1] - c) / (p2[1] - c)) / (p1[0] - p2[0]);
|
|
28570
28565
|
const a = (p1[1] - c) / Math.exp(b * p1[0]);
|
|
28571
28566
|
return [a, b, c];
|
|
@@ -28592,7 +28587,7 @@ const Logarithm = ___default["default"].extend({}, PlotDefaults, {
|
|
|
28592
28587
|
defaultCoords: [[0.55, 0.5], [0.75, 0.75]],
|
|
28593
28588
|
defaultAsymptote: [[0.5, 0], [0.5, 1.0]],
|
|
28594
28589
|
extraCoordConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
|
|
28595
|
-
const x =
|
|
28590
|
+
const x = asymptote[0][0];
|
|
28596
28591
|
return ___default["default"].all(coords, coord => coord[0] !== x) && coords[0][1] !== coords[1][1];
|
|
28597
28592
|
},
|
|
28598
28593
|
extraAsymptoteConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
|
|
@@ -28620,10 +28615,12 @@ const Logarithm = ___default["default"].extend({}, PlotDefaults, {
|
|
|
28620
28615
|
// logic between the two 'models'.
|
|
28621
28616
|
const flip = coord => [coord[1], coord[0]];
|
|
28622
28617
|
const inverseCoeffs = Exponential.getCoefficients(___default["default"].map(coords, flip), ___default["default"].map(asymptote, flip));
|
|
28623
|
-
|
|
28624
|
-
|
|
28625
|
-
|
|
28626
|
-
|
|
28618
|
+
if (inverseCoeffs) {
|
|
28619
|
+
const c = -inverseCoeffs[2] / inverseCoeffs[0];
|
|
28620
|
+
const b = 1 / inverseCoeffs[0];
|
|
28621
|
+
const a = 1 / inverseCoeffs[1];
|
|
28622
|
+
return [a, b, c];
|
|
28623
|
+
}
|
|
28627
28624
|
},
|
|
28628
28625
|
getFunctionForCoeffs: function (coeffs, x, asymptote) {
|
|
28629
28626
|
const a = coeffs[0],
|
|
@@ -28687,11 +28684,9 @@ const functionTypeMapping = {
|
|
|
28687
28684
|
absolute_value: AbsoluteValue
|
|
28688
28685
|
};
|
|
28689
28686
|
const allTypes = ___default["default"].keys(functionTypeMapping);
|
|
28690
|
-
function functionForType(
|
|
28691
|
-
//
|
|
28692
|
-
//
|
|
28693
|
-
// is a big amount of work/change.
|
|
28694
|
-
type) {
|
|
28687
|
+
function functionForType(type) {
|
|
28688
|
+
// @ts-expect-error: TypeScript doesn't know how to use deal with generics
|
|
28689
|
+
// and conditional types in this way.
|
|
28695
28690
|
return functionTypeMapping[type];
|
|
28696
28691
|
}
|
|
28697
28692
|
const getEquationString = props => {
|
|
@@ -28756,12 +28751,13 @@ const defaultPlotProps = (type, graph) => {
|
|
|
28756
28751
|
// widget before even reading the question; you can't lose, but you
|
|
28757
28752
|
// might get a free win.
|
|
28758
28753
|
const model = functionForType(type);
|
|
28754
|
+
const defaultAsymptote = "defaultAsymptote" in model ? model.defaultAsymptote : null;
|
|
28759
28755
|
const gridStep = [1, 1];
|
|
28760
28756
|
// @ts-expect-error - TS2345 - Argument of type 'number[]' is not assignable to parameter of type '[number, number]'.
|
|
28761
28757
|
const snapStep = Util.snapStepFromGridStep(gridStep);
|
|
28762
28758
|
return {
|
|
28763
28759
|
type,
|
|
28764
|
-
asymptote: maybePointsFromNormalized(
|
|
28760
|
+
asymptote: maybePointsFromNormalized(defaultAsymptote, graph.range, graph.step, snapStep),
|
|
28765
28761
|
coords: null
|
|
28766
28762
|
};
|
|
28767
28763
|
};
|
|
@@ -28821,8 +28817,19 @@ var util = /*#__PURE__*/Object.freeze({
|
|
|
28821
28817
|
typeToButton: typeToButton
|
|
28822
28818
|
});
|
|
28823
28819
|
|
|
28824
|
-
function
|
|
28825
|
-
if (
|
|
28820
|
+
function getCoefficientsByType(data) {
|
|
28821
|
+
if (data.type === "exponential" || data.type === "logarithm") {
|
|
28822
|
+
const grader = functionForType(data.type);
|
|
28823
|
+
return grader.getCoefficients(data.coords, data.asymptote);
|
|
28824
|
+
} else if (data.type === "linear" || data.type === "quadratic" || data.type === "absolute_value" || data.type === "sinusoid" || data.type === "tangent") {
|
|
28825
|
+
const grader = functionForType(data.type);
|
|
28826
|
+
return grader.getCoefficients(data.coords);
|
|
28827
|
+
} else {
|
|
28828
|
+
throw new perseusCore.PerseusError("Invalid grapher type", perseusCore.Errors.InvalidInput);
|
|
28829
|
+
}
|
|
28830
|
+
}
|
|
28831
|
+
function grapherValidator(userInput, rubric) {
|
|
28832
|
+
if (userInput.type !== rubric.correct.type) {
|
|
28826
28833
|
return {
|
|
28827
28834
|
type: "points",
|
|
28828
28835
|
earned: 0,
|
|
@@ -28832,7 +28839,7 @@ function grapherValidator(state, rubric) {
|
|
|
28832
28839
|
}
|
|
28833
28840
|
|
|
28834
28841
|
// We haven't moved the coords
|
|
28835
|
-
if (
|
|
28842
|
+
if (userInput.coords == null) {
|
|
28836
28843
|
return {
|
|
28837
28844
|
type: "invalid",
|
|
28838
28845
|
message: null
|
|
@@ -28840,11 +28847,9 @@ function grapherValidator(state, rubric) {
|
|
|
28840
28847
|
}
|
|
28841
28848
|
|
|
28842
28849
|
// Get new function handler for grading
|
|
28843
|
-
const grader = functionForType(
|
|
28844
|
-
const guessCoeffs =
|
|
28845
|
-
const correctCoeffs =
|
|
28846
|
-
// @ts-expect-error - TS(2339) - Property 'asymptote' does not exist on type '{ type: "absolute_value"; coords: [Coord, Coord]; }'
|
|
28847
|
-
rubric.correct.asymptote);
|
|
28850
|
+
const grader = functionForType(userInput.type);
|
|
28851
|
+
const guessCoeffs = getCoefficientsByType(userInput);
|
|
28852
|
+
const correctCoeffs = getCoefficientsByType(rubric.correct);
|
|
28848
28853
|
if (guessCoeffs == null || correctCoeffs == null) {
|
|
28849
28854
|
return {
|
|
28850
28855
|
type: "invalid",
|
|
@@ -37937,7 +37942,7 @@ function shouldUseMafs(mafsFlags, graph) {
|
|
|
37937
37942
|
// TODO(benchristel): add a feature flag for the "unlimited"
|
|
37938
37943
|
// case once we've implemented polygon graphs with unlimited
|
|
37939
37944
|
// sides
|
|
37940
|
-
return
|
|
37945
|
+
return Boolean(mafsFlags["unlimited-polygon"]);
|
|
37941
37946
|
}
|
|
37942
37947
|
return Boolean(mafsFlags["polygon"]);
|
|
37943
37948
|
default:
|
|
@@ -42411,17 +42416,23 @@ const TickMarks = Graphie.createSimpleClass((graphie, props) => {
|
|
|
42411
42416
|
const results = [];
|
|
42412
42417
|
|
|
42413
42418
|
// For convenience, extract some props into separate variables
|
|
42414
|
-
const
|
|
42415
|
-
|
|
42419
|
+
const {
|
|
42420
|
+
range,
|
|
42421
|
+
labelRange,
|
|
42422
|
+
labelStyle,
|
|
42423
|
+
labelTicks,
|
|
42424
|
+
tickStep,
|
|
42425
|
+
numDivisions
|
|
42426
|
+
} = props;
|
|
42416
42427
|
const leftLabel = labelRange[0] == null ? range[0] : labelRange[0];
|
|
42417
42428
|
const rightLabel = labelRange[1] == null ? range[1] : labelRange[1];
|
|
42418
42429
|
|
|
42419
42430
|
// Find base via GCD for non-reduced fractions
|
|
42420
42431
|
let base;
|
|
42421
|
-
if (
|
|
42432
|
+
if (labelStyle === "non-reduced") {
|
|
42422
42433
|
const fractions = [leftLabel, rightLabel];
|
|
42423
|
-
for (let i = 0; i <=
|
|
42424
|
-
const x = range[0] + i *
|
|
42434
|
+
for (let i = 0; i <= numDivisions; i++) {
|
|
42435
|
+
const x = range[0] + i * tickStep;
|
|
42425
42436
|
fractions.push(x);
|
|
42426
42437
|
}
|
|
42427
42438
|
const getDenom = x => kmath.number.toFraction(x)[1];
|
|
@@ -42430,30 +42441,40 @@ const TickMarks = Graphie.createSimpleClass((graphie, props) => {
|
|
|
42430
42441
|
} else {
|
|
42431
42442
|
base = undefined;
|
|
42432
42443
|
}
|
|
42433
|
-
|
|
42434
|
-
// Draw and save the tick marks and tick labels
|
|
42435
|
-
for (let i = 0; i <= props.numDivisions; i++) {
|
|
42436
|
-
const x = range[0] + i * props.tickStep;
|
|
42437
|
-
results.push(graphie.line([x, -0.2], [x, 0.2]));
|
|
42438
|
-
const labelTicks = props.labelTicks;
|
|
42439
|
-
if (labelTicks || props.labelStyle === "decimal ticks") {
|
|
42440
|
-
if (x === leftLabel || x === rightLabel) {
|
|
42441
|
-
results.push(graphie.style({
|
|
42442
|
-
color: KhanColors.BLUE
|
|
42443
|
-
}, () => _label(graphie, props.labelStyle, x, x, base)));
|
|
42444
|
-
} else {
|
|
42445
|
-
results.push(_label(graphie, props.labelStyle, x, x, base));
|
|
42446
|
-
}
|
|
42447
|
-
}
|
|
42448
|
-
}
|
|
42449
|
-
|
|
42450
|
-
// Render the labels' lines
|
|
42451
|
-
graphie.style({
|
|
42444
|
+
const highlightedLineStyle = {
|
|
42452
42445
|
stroke: KhanColors.BLUE,
|
|
42453
42446
|
strokeWidth: 3.5
|
|
42454
|
-
}
|
|
42455
|
-
|
|
42456
|
-
|
|
42447
|
+
};
|
|
42448
|
+
const highlightedTextStyle = {
|
|
42449
|
+
color: KhanColors.BLUE
|
|
42450
|
+
};
|
|
42451
|
+
|
|
42452
|
+
// Generate an array of tick numbers:
|
|
42453
|
+
// `Array(props.numDivisions)` makes an array of null values - one for every division marker
|
|
42454
|
+
// `.keys()` gets the index values for each marker placeholder
|
|
42455
|
+
// `.map()` converts the index values into actual tick numbers
|
|
42456
|
+
const initialTicks = [...Array(numDivisions).keys()].map(index => range[0] + index * tickStep);
|
|
42457
|
+
|
|
42458
|
+
// .sort() comparator
|
|
42459
|
+
const byNumericAscending = (a, b) => a - b;
|
|
42460
|
+
|
|
42461
|
+
// Ensure that any label markers and range endpoints are included in the array
|
|
42462
|
+
// Using `Set()` prevents duplication of tick numbers (and is quite performant)
|
|
42463
|
+
const allTicks = [...new Set([...initialTicks, leftLabel, rightLabel, ...range])].sort(byNumericAscending);
|
|
42464
|
+
|
|
42465
|
+
// Cycle through each tick number and add a tick line, and a label (if needed)
|
|
42466
|
+
allTicks.forEach(tick => {
|
|
42467
|
+
const tickIsHighlighted = tick === leftLabel || tick === rightLabel;
|
|
42468
|
+
const lineStyle = tickIsHighlighted ? highlightedLineStyle : null;
|
|
42469
|
+
const textStyle = tickIsHighlighted ? highlightedTextStyle : null;
|
|
42470
|
+
graphie.style(lineStyle, () => {
|
|
42471
|
+
results.push(graphie.line([tick, -0.2], [tick, 0.2]));
|
|
42472
|
+
});
|
|
42473
|
+
if (labelTicks || tickIsHighlighted || labelStyle === "decimal ticks") {
|
|
42474
|
+
graphie.style(textStyle, () => {
|
|
42475
|
+
results.push(_label(graphie, labelStyle, tick, tick, base));
|
|
42476
|
+
});
|
|
42477
|
+
}
|
|
42457
42478
|
});
|
|
42458
42479
|
return results;
|
|
42459
42480
|
});
|
|
@@ -43147,7 +43168,7 @@ class Orderer extends React__namespace.Component {
|
|
|
43147
43168
|
list.splice(index, 0, newCard);
|
|
43148
43169
|
}
|
|
43149
43170
|
this.props.onChange({
|
|
43150
|
-
// @ts-expect-error - TS2345 - Argument of type '{ current: any[]; }' is not assignable to parameter of type '{ hints?: readonly Hint[] | undefined; replace?: boolean | undefined; content?: string | undefined; widgets?:
|
|
43171
|
+
// @ts-expect-error - TS2345 - Argument of type '{ current: any[]; }' is not assignable to parameter of type '{ hints?: readonly Hint[] | undefined; replace?: boolean | undefined; content?: string | undefined; widgets?: PerseusWidgetsMap | undefined; images?: ImageDict | undefined; ... 13 more ...; plot?: any; }'.
|
|
43151
43172
|
current: list
|
|
43152
43173
|
});
|
|
43153
43174
|
this.setState({
|
|
@@ -43310,7 +43331,7 @@ class Orderer extends React__namespace.Component {
|
|
|
43310
43331
|
};
|
|
43311
43332
|
});
|
|
43312
43333
|
this.props.onChange({
|
|
43313
|
-
// @ts-expect-error - TS2345 - Argument of type '{ current: { content: string; }[]; }' is not assignable to parameter of type '{ hints?: readonly Hint[] | undefined; replace?: boolean | undefined; content?: string | undefined; widgets?:
|
|
43334
|
+
// @ts-expect-error - TS2345 - Argument of type '{ current: { content: string; }[]; }' is not assignable to parameter of type '{ hints?: readonly Hint[] | undefined; replace?: boolean | undefined; content?: string | undefined; widgets?: PerseusWidgetsMap | undefined; images?: ImageDict | undefined; ... 13 more ...; plot?: any; }'.
|
|
43314
43335
|
current: list
|
|
43315
43336
|
});
|
|
43316
43337
|
this.setState({
|
|
@@ -45158,7 +45179,7 @@ const init = function (options) {
|
|
|
45158
45179
|
|
|
45159
45180
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
45160
45181
|
const libName = "@khanacademy/perseus";
|
|
45161
|
-
const libVersion = "
|
|
45182
|
+
const libVersion = "38.0.0";
|
|
45162
45183
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
45163
45184
|
|
|
45164
45185
|
const apiVersion = {
|
|
@@ -48417,9 +48438,7 @@ const getCorrectAnswerForWidgetId = (widgetId, itemData) => {
|
|
|
48417
48438
|
const rubric = itemData.question.widgets[widgetId].options;
|
|
48418
48439
|
const widgetMap = getWidgetsMapFromItemData(itemData);
|
|
48419
48440
|
const widgetType = getWidgetTypeByWidgetId(widgetId, widgetMap);
|
|
48420
|
-
const widget =
|
|
48421
|
-
|
|
48422
|
-
// @ts-expect-error - TS2339 - Property 'getOneCorrectAnswerFromRubric' does not exist on type 'ComponentType<any>'.
|
|
48441
|
+
const widget = getWidgetExport(widgetType);
|
|
48423
48442
|
return widget?.getOneCorrectAnswerFromRubric?.(rubric);
|
|
48424
48443
|
};
|
|
48425
48444
|
|