@khanacademy/perseus-score 2.3.7 → 4.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/index.js CHANGED
@@ -7,10 +7,10 @@ var kmath = require('@khanacademy/kmath');
7
7
  var perseusCore = require('@khanacademy/perseus-core');
8
8
  var _ = require('underscore');
9
9
 
10
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
11
11
 
12
- function _interopNamespace(e) {
13
- if (e && e.__esModule) return e;
12
+ function _interopNamespaceCompat(e) {
13
+ if (e && typeof e === 'object' && 'default' in e) return e;
14
14
  var n = Object.create(null);
15
15
  if (e) {
16
16
  Object.keys(e).forEach(function (k) {
@@ -23,12 +23,12 @@ function _interopNamespace(e) {
23
23
  }
24
24
  });
25
25
  }
26
- n["default"] = e;
26
+ n.default = e;
27
27
  return Object.freeze(n);
28
28
  }
29
29
 
30
- var KAS__namespace = /*#__PURE__*/_interopNamespace(KAS);
31
- var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
30
+ var KAS__namespace = /*#__PURE__*/_interopNamespaceCompat(KAS);
31
+ var ___default = /*#__PURE__*/_interopDefaultCompat(_);
32
32
 
33
33
  const MISSING_PERCENT_ERROR = "MISSING_PERCENT_ERROR";
34
34
  const NEEDS_TO_BE_SIMPLIFIED_ERROR = "NEEDS_TO_BE_SIMPLIFIED_ERROR";
@@ -135,7 +135,7 @@ const KhanAnswerTypes = {
135
135
  defaultForms: "integer, proper, improper, mixed, decimal",
136
136
  createValidatorFunctional: function (predicate, options) {
137
137
  // Extract the options from the given solution object
138
- options = ___default["default"].extend({
138
+ options = ___default.default.extend({
139
139
  simplify: "required",
140
140
  ratio: false,
141
141
  forms: KhanAnswerTypes.predicate.defaultForms
@@ -143,7 +143,7 @@ const KhanAnswerTypes = {
143
143
  let acceptableForms;
144
144
  // this is maintaining backwards compatibility
145
145
  // TODO(merlob) fix all places that depend on this, then delete
146
- if (!___default["default"].isArray(options.forms)) {
146
+ if (!___default.default.isArray(options.forms)) {
147
147
  acceptableForms = options.forms.split(/\s*,\s*/);
148
148
  } else {
149
149
  acceptableForms = options.forms;
@@ -164,8 +164,8 @@ const KhanAnswerTypes = {
164
164
  // in the list so we don't prematurely complain about not having
165
165
  // a percent sign when the user entered the correct answer in a
166
166
  // different form (such as a decimal or fraction)
167
- if (___default["default"].contains(acceptableForms, "percent")) {
168
- acceptableForms = ___default["default"].without(acceptableForms, "percent");
167
+ if (___default.default.contains(acceptableForms, "percent")) {
168
+ acceptableForms = ___default.default.without(acceptableForms, "percent");
169
169
  acceptableForms.push("percent");
170
170
  }
171
171
 
@@ -323,7 +323,7 @@ const KhanAnswerTypes = {
323
323
  } else if (match = text.match(/^(.+)\s*\*?\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)$/i)) {
324
324
  possibilities = forms.decimal(match[1]);
325
325
  } else {
326
- possibilities = ___default["default"].reduce(KhanAnswerTypes.predicate.defaultForms.split(/\s*,\s*/), function (memo, form) {
326
+ possibilities = ___default.default.reduce(KhanAnswerTypes.predicate.defaultForms.split(/\s*,\s*/), function (memo, form) {
327
327
  return memo.concat(forms[form](text));
328
328
  }, []);
329
329
 
@@ -348,7 +348,7 @@ const KhanAnswerTypes = {
348
348
  approximatesPi = true;
349
349
  }
350
350
  if (approximatesPi) {
351
- ___default["default"].each(possibilities, function (possibility) {
351
+ ___default.default.each(possibilities, function (possibility) {
352
352
  possibility.piApprox = true;
353
353
  });
354
354
  }
@@ -552,9 +552,9 @@ const KhanAnswerTypes = {
552
552
  });
553
553
  if (score.correct === false) {
554
554
  let interpretedGuess = false;
555
- ___default["default"].each(forms, function (form) {
556
- const anyAreNaN = ___default["default"].any(form(guess), function (t) {
557
- return t.value != null && !___default["default"].isNaN(t.value);
555
+ ___default.default.each(forms, function (form) {
556
+ const anyAreNaN = ___default.default.any(form(guess), function (t) {
557
+ return t.value != null && !___default.default.isNaN(t.value);
558
558
  });
559
559
  if (anyAreNaN) {
560
560
  interpretedGuess = true;
@@ -845,8 +845,8 @@ function validateDropdown(userInput) {
845
845
  * - Otherwise, pass through the resulting points and message.
846
846
  */
847
847
  function scoreExpression(userInput, rubric, locale) {
848
- const options = ___default["default"].clone(rubric);
849
- ___default["default"].extend(options, {
848
+ const options = ___default.default.clone(rubric);
849
+ ___default.default.extend(options, {
850
850
  decimal_separator: perseusCore.getDecimalSeparator(locale)
851
851
  });
852
852
  const createValidator = answer => {
@@ -866,7 +866,7 @@ function scoreExpression(userInput, rubric, locale) {
866
866
  }
867
867
  });
868
868
  }
869
- return KhanAnswerTypes.expression.createValidatorFunctional(expression.expr, ___default["default"]({}).extend(options, {
869
+ return KhanAnswerTypes.expression.createValidatorFunctional(expression.expr, ___default.default({}).extend(options, {
870
870
  simplify: answer.simplify,
871
871
  form: answer.form
872
872
  }));
@@ -887,8 +887,10 @@ function scoreExpression(userInput, rubric, locale) {
887
887
  let matchMessage;
888
888
  let allEmpty = true;
889
889
  let firstUngradedResult;
890
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
890
891
  for (const answerForm of rubric.answerForms || []) {
891
892
  const validator = createValidator(answerForm);
893
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
892
894
  if (!validator) {
893
895
  continue;
894
896
  }
@@ -1203,8 +1205,8 @@ function scoreInteractiveGraph(userInput, rubric) {
1203
1205
  } else if (userInput.type === "segment" && rubric.correct.type === "segment" && userInput.coords != null) {
1204
1206
  let guess = perseusCore.deepClone(userInput.coords);
1205
1207
  let correct = perseusCore.deepClone(rubric.correct.coords);
1206
- guess = ___default["default"].invoke(guess, "sort").sort();
1207
- correct = ___default["default"].invoke(correct, "sort").sort();
1208
+ guess = ___default.default.invoke(guess, "sort").sort();
1209
+ correct = ___default.default.invoke(correct, "sort").sort();
1208
1210
  if (perseusCore.approximateDeepEqual(guess, correct)) {
1209
1211
  return {
1210
1212
  type: "points",
@@ -1248,7 +1250,8 @@ function scoreInteractiveGraph(userInput, rubric) {
1248
1250
  const guess = shouldReverseCoords ? coords.slice().reverse() : coords;
1249
1251
  let match;
1250
1252
  if (rubric.correct.match === "congruent") {
1251
- const angles = ___default["default"].map([guess, correct], function (coords) {
1253
+ const angles = ___default.default.map([guess, correct], function (coords) {
1254
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
1252
1255
  if (!coords) {
1253
1256
  return false;
1254
1257
  }
@@ -1274,7 +1277,7 @@ function scoreInteractiveGraph(userInput, rubric) {
1274
1277
 
1275
1278
  // The input wasn't correct, so check if it's a blank input or if it's
1276
1279
  // actually just wrong
1277
- if (!hasValue || ___default["default"].isEqual(userInput, rubric.graph)) {
1280
+ if (!hasValue || ___default.default.isEqual(userInput, rubric.graph)) {
1278
1281
  // We're where we started.
1279
1282
  return {
1280
1283
  type: "invalid",
@@ -1329,7 +1332,7 @@ function scoreLabelImage(userInput, rubric) {
1329
1332
  }
1330
1333
 
1331
1334
  function scoreMatcher(userInput, rubric) {
1332
- const correct = ___default["default"].isEqual(userInput.left, rubric.left) && ___default["default"].isEqual(userInput.right, rubric.right);
1335
+ const correct = ___default.default.isEqual(userInput.left, rubric.left) && ___default.default.isEqual(userInput.right, rubric.right);
1333
1336
  return {
1334
1337
  type: "points",
1335
1338
  earned: correct ? 1 : 0,
@@ -1347,8 +1350,8 @@ function scoreMatrix(userInput, rubric) {
1347
1350
  const createValidator = KhanAnswerTypes.number.createValidatorFunctional;
1348
1351
  let message = null;
1349
1352
  let incorrect = false;
1350
- ___default["default"](suppliedSize[0]).times(row => {
1351
- ___default["default"](suppliedSize[1]).times(col => {
1353
+ ___default.default(suppliedSize[0]).times(row => {
1354
+ ___default.default(suppliedSize[1]).times(col => {
1352
1355
  if (!incorrectSize) {
1353
1356
  const validator = createValidator(
1354
1357
  // @ts-expect-error - TS2345 - Argument of type 'number' is not assignable to parameter of type 'string'.
@@ -1411,7 +1414,9 @@ function scoreNumberLine(userInput, rubric) {
1411
1414
  const start = rubric.initialX != null ? rubric.initialX : range[0];
1412
1415
  const startRel = rubric.isInequality ? "ge" : "eq";
1413
1416
  const correctRel = rubric.correctRel || "eq";
1414
- const correctPos = kmath.number.equal(userInput.numLinePosition, rubric.correctX || 0);
1417
+ const correctPos = kmath.number.equal(userInput.numLinePosition,
1418
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
1419
+ rubric.correctX || 0);
1415
1420
  if (correctPos && correctRel === userInput.rel) {
1416
1421
  return {
1417
1422
  type: "points",
@@ -1559,6 +1564,7 @@ function walkTex(tex, handler) {
1559
1564
  currentIndex = secondParsedExpression.endpoint + 1;
1560
1565
 
1561
1566
  // Add expressions to running total of parsed expressions
1567
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
1562
1568
  if (parsedString.length) {
1563
1569
  parsedString += " ";
1564
1570
  }
@@ -1710,9 +1716,7 @@ function scoreNumericInput(userInput, rubric) {
1710
1716
  const result = matchedAnswer?.status === "correct" ? matchedAnswer.score : {
1711
1717
  empty: matchedAnswer?.status === "ungraded",
1712
1718
  correct: matchedAnswer?.status === "correct",
1713
- message: matchedAnswer?.message ?? null,
1714
- guess: localValue
1715
- };
1719
+ message: matchedAnswer?.message ?? null};
1716
1720
  if (result.empty) {
1717
1721
  return {
1718
1722
  type: "invalid",
@@ -1728,7 +1732,7 @@ function scoreNumericInput(userInput, rubric) {
1728
1732
  }
1729
1733
 
1730
1734
  function scoreOrderer(userInput, rubric) {
1731
- const correct = ___default["default"].isEqual(userInput.current, rubric.correctOptions.map(option => option.content));
1735
+ const correct = ___default.default.isEqual(userInput.current, rubric.correctOptions.map(option => option.content));
1732
1736
  return {
1733
1737
  type: "points",
1734
1738
  earned: correct ? 1 : 0,
@@ -1892,6 +1896,8 @@ function validateTable(userInput) {
1892
1896
  return cell === "";
1893
1897
  });
1894
1898
  });
1899
+
1900
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
1895
1901
  if (hasEmptyCell || !supplied.length) {
1896
1902
  return {
1897
1903
  type: "invalid",
@@ -2034,6 +2040,7 @@ function scoreNoop() {
2034
2040
  }
2035
2041
 
2036
2042
  // The `group` widget is basically a widget hosting a full Perseus system in
2043
+
2037
2044
  // it. As such, scoring a group means scoring all widgets it contains.
2038
2045
  function scoreGroup(userInput, rubric, locale) {
2039
2046
  const scores = scoreWidgetsFunctional(rubric.widgets, Object.keys(rubric.widgets), userInput, locale);