@khanacademy/perseus-core 5.4.2 → 7.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
@@ -6,10 +6,10 @@ var _ = require('underscore');
6
6
  var KAS = require('@khanacademy/kas');
7
7
  var perseusUtils = require('@khanacademy/perseus-utils');
8
8
 
9
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
10
10
 
11
- function _interopNamespace(e) {
12
- if (e && e.__esModule) return e;
11
+ function _interopNamespaceCompat(e) {
12
+ if (e && typeof e === 'object' && 'default' in e) return e;
13
13
  var n = Object.create(null);
14
14
  if (e) {
15
15
  Object.keys(e).forEach(function (k) {
@@ -22,21 +22,22 @@ function _interopNamespace(e) {
22
22
  }
23
23
  });
24
24
  }
25
- n["default"] = e;
25
+ n.default = e;
26
26
  return Object.freeze(n);
27
27
  }
28
28
 
29
- var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
30
- var KAS__namespace = /*#__PURE__*/_interopNamespace(KAS);
29
+ var ___default = /*#__PURE__*/_interopDefaultCompat(_);
30
+ var KAS__namespace = /*#__PURE__*/_interopNamespaceCompat(KAS);
31
31
 
32
32
  function getMatrixSize(matrix) {
33
33
  const matrixSize = [1, 1];
34
34
 
35
35
  // We need to find the widest row and tallest column to get the correct
36
36
  // matrix size.
37
- ___default["default"](matrix).each((matrixRow, row) => {
37
+ ___default.default(matrix).each((matrixRow, row) => {
38
38
  let rowWidth = 0;
39
- ___default["default"](matrixRow).each((matrixCol, col) => {
39
+ ___default.default(matrixRow).each((matrixCol, col) => {
40
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
40
41
  if (matrixCol != null && matrixCol.toString().length) {
41
42
  rowWidth = col + 1;
42
43
  }
@@ -116,10 +117,10 @@ function approximateDeepEqual(x, y) {
116
117
  return false;
117
118
  }
118
119
  if (typeof x === "object" && typeof y === "object" && !!x && !!y) {
119
- return x === y || ___default["default"].all(x, function (v, k) {
120
+ return x === y || ___default.default.all(x, function (v, k) {
120
121
  // @ts-expect-error - TS2536 - Type 'CollectionKey<T>' cannot be used to index type 'T'.
121
122
  return approximateDeepEqual(y[k], v);
122
- }) && ___default["default"].all(y, function (v, k) {
123
+ }) && ___default.default.all(y, function (v, k) {
123
124
  // @ts-expect-error - TS2536 - Type 'CollectionKey<T>' cannot be used to index type 'T'.
124
125
  return approximateDeepEqual(x[k], v);
125
126
  });
@@ -284,11 +285,11 @@ const PlotDefaults = {
284
285
  getPropsForCoeffs: function (coeffs) {
285
286
  return {
286
287
  // @ts-expect-error - TS2339 - Property 'getFunctionForCoeffs' does not exist on type '{ readonly areEqual: (coeffs1: any, coeffs2: any) => boolean; readonly Movable: any; readonly getPropsForCoeffs: (coeffs: any) => any; }'.
287
- fn: ___default["default"].partial(this.getFunctionForCoeffs, coeffs)
288
+ fn: ___default.default.partial(this.getFunctionForCoeffs, coeffs)
288
289
  };
289
290
  }
290
291
  };
291
- const Linear = ___default["default"].extend({}, PlotDefaults, {
292
+ const Linear = ___default.default.extend({}, PlotDefaults, {
292
293
  url: "https://ka-perseus-graphie.s3.amazonaws.com/67aaf581e6d9ef9038c10558a1f70ac21c11c9f8.png",
293
294
  defaultCoords: [[0.25, 0.75], [0.75, 0.75]],
294
295
  getCoefficients: function (coords) {
@@ -315,7 +316,7 @@ const Linear = ___default["default"].extend({}, PlotDefaults, {
315
316
  return "y = " + m.toFixed(3) + "x + " + b.toFixed(3);
316
317
  }
317
318
  });
318
- const Quadratic = ___default["default"].extend({}, PlotDefaults, {
319
+ const Quadratic = ___default.default.extend({}, PlotDefaults, {
319
320
  url: "https://ka-perseus-graphie.s3.amazonaws.com/e23d36e6fc29ee37174e92c9daba2a66677128ab.png",
320
321
  defaultCoords: [[0.5, 0.5], [0.75, 0.75]],
321
322
  movable: MOVABLES.PARABOLA,
@@ -354,7 +355,7 @@ const Quadratic = ___default["default"].extend({}, PlotDefaults, {
354
355
  return "y = " + a.toFixed(3) + "x^2 + " + b.toFixed(3) + "x + " + c.toFixed(3);
355
356
  }
356
357
  });
357
- const Sinusoid = ___default["default"].extend({}, PlotDefaults, {
358
+ const Sinusoid = ___default.default.extend({}, PlotDefaults, {
358
359
  url: "https://ka-perseus-graphie.s3.amazonaws.com/3d68e7718498475f53b206c2ab285626baf8857e.png",
359
360
  defaultCoords: [[0.5, 0.5], [0.6, 0.6]],
360
361
  movable: MOVABLES.SINUSOID,
@@ -394,7 +395,7 @@ const Sinusoid = ___default["default"].extend({}, PlotDefaults, {
394
395
  return approximateDeepEqual(canonicalSineCoefficients(coeffs1), canonicalSineCoefficients(coeffs2));
395
396
  }
396
397
  });
397
- const Tangent = ___default["default"].extend({}, PlotDefaults, {
398
+ const Tangent = ___default.default.extend({}, PlotDefaults, {
398
399
  url: "https://ka-perseus-graphie.s3.amazonaws.com/7db80d23c35214f98659fe1cf0765811c1bbfbba.png",
399
400
  defaultCoords: [[0.5, 0.5], [0.75, 0.75]],
400
401
  getCoefficients: function (coords) {
@@ -425,7 +426,7 @@ const Tangent = ___default["default"].extend({}, PlotDefaults, {
425
426
  return approximateDeepEqual(canonicalTangentCoefficients(coeffs1), canonicalTangentCoefficients(coeffs2));
426
427
  }
427
428
  });
428
- const Exponential = ___default["default"].extend({}, PlotDefaults, {
429
+ const Exponential = ___default.default.extend({}, PlotDefaults, {
429
430
  url: "https://ka-perseus-graphie.s3.amazonaws.com/9cbfad55525e3ce755a31a631b074670a5dad611.png",
430
431
  defaultCoords: [[0.5, 0.55], [0.75, 0.75]],
431
432
  defaultAsymptote: [[0, 0.5], [1.0, 0.5]],
@@ -448,23 +449,23 @@ const Exponential = ___default["default"].extend({}, PlotDefaults, {
448
449
  */
449
450
  extraCoordConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
450
451
  const y = asymptote[0][1];
451
- return ___default["default"].all(coords, coord => coord[1] !== y);
452
+ return ___default.default.all(coords, coord => coord[1] !== y);
452
453
  },
453
454
  extraAsymptoteConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
454
455
  const y = newCoord[1];
455
- const isValid = ___default["default"].all(coords, coord => coord[1] > y) || ___default["default"].all(coords, coord => coord[1] < y);
456
+ const isValid = ___default.default.all(coords, coord => coord[1] > y) || ___default.default.all(coords, coord => coord[1] < y);
456
457
  if (isValid) {
457
458
  return [oldCoord[0], y];
458
459
  }
459
460
  // Snap the asymptote as close as possible, i.e., if the user moves
460
461
  // the mouse really quickly into an invalid region
461
462
  const oldY = oldCoord[1];
462
- const wasBelow = ___default["default"].all(coords, coord => coord[1] > oldY);
463
+ const wasBelow = ___default.default.all(coords, coord => coord[1] > oldY);
463
464
  if (wasBelow) {
464
- const bottomMost = ___default["default"].min(___default["default"].map(coords, coord => coord[1]));
465
+ const bottomMost = ___default.default.min(___default.default.map(coords, coord => coord[1]));
465
466
  return [oldCoord[0], bottomMost - graph.snapStep[1]];
466
467
  }
467
- const topMost = ___default["default"].max(___default["default"].map(coords, coord => coord[1]));
468
+ const topMost = ___default.default.max(___default.default.map(coords, coord => coord[1]));
468
469
  return [oldCoord[0], topMost + graph.snapStep[1]];
469
470
  },
470
471
  allowReflectOverAsymptote: true,
@@ -483,6 +484,7 @@ const Exponential = ___default["default"].extend({}, PlotDefaults, {
483
484
  return a * Math.exp(b * x) + c;
484
485
  },
485
486
  getEquationString: function (coords, asymptote) {
487
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
486
488
  if (!asymptote) {
487
489
  return null;
488
490
  }
@@ -493,29 +495,29 @@ const Exponential = ___default["default"].extend({}, PlotDefaults, {
493
495
  return "y = " + a.toFixed(3) + "e^(" + b.toFixed(3) + "x) + " + c.toFixed(3);
494
496
  }
495
497
  });
496
- const Logarithm = ___default["default"].extend({}, PlotDefaults, {
498
+ const Logarithm = ___default.default.extend({}, PlotDefaults, {
497
499
  url: "https://ka-perseus-graphie.s3.amazonaws.com/f6491e99d34af34d924bfe0231728ad912068dc3.png",
498
500
  defaultCoords: [[0.55, 0.5], [0.75, 0.75]],
499
501
  defaultAsymptote: [[0.5, 0], [0.5, 1.0]],
500
502
  extraCoordConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
501
503
  const x = asymptote[0][0];
502
- return ___default["default"].all(coords, coord => coord[0] !== x) && coords[0][1] !== coords[1][1];
504
+ return ___default.default.all(coords, coord => coord[0] !== x) && coords[0][1] !== coords[1][1];
503
505
  },
504
506
  extraAsymptoteConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
505
507
  const x = newCoord[0];
506
- const isValid = ___default["default"].all(coords, coord => coord[0] > x) || ___default["default"].all(coords, coord => coord[0] < x);
508
+ const isValid = ___default.default.all(coords, coord => coord[0] > x) || ___default.default.all(coords, coord => coord[0] < x);
507
509
  if (isValid) {
508
510
  return [x, oldCoord[1]];
509
511
  }
510
512
  // Snap the asymptote as close as possible, i.e., if the user moves
511
513
  // the mouse really quickly into an invalid region
512
514
  const oldX = oldCoord[0];
513
- const wasLeft = ___default["default"].all(coords, coord => coord[0] > oldX);
515
+ const wasLeft = ___default.default.all(coords, coord => coord[0] > oldX);
514
516
  if (wasLeft) {
515
- const leftMost = ___default["default"].min(___default["default"].map(coords, coord => coord[0]));
517
+ const leftMost = ___default.default.min(___default.default.map(coords, coord => coord[0]));
516
518
  return [leftMost - graph.snapStep[0], oldCoord[1]];
517
519
  }
518
- const rightMost = ___default["default"].max(___default["default"].map(coords, coord => coord[0]));
520
+ const rightMost = ___default.default.max(___default.default.map(coords, coord => coord[0]));
519
521
  return [rightMost + graph.snapStep[0], oldCoord[1]];
520
522
  },
521
523
  allowReflectOverAsymptote: true,
@@ -525,7 +527,7 @@ const Logarithm = ___default["default"].extend({}, PlotDefaults, {
525
527
  // perform some algebra on the coefficients. This also unifies the
526
528
  // logic between the two 'models'.
527
529
  const flip = coord => [coord[1], coord[0]];
528
- const inverseCoeffs = Exponential.getCoefficients(___default["default"].map(coords, flip), ___default["default"].map(asymptote, flip));
530
+ const inverseCoeffs = Exponential.getCoefficients(___default.default.map(coords, flip), ___default.default.map(asymptote, flip));
529
531
  if (inverseCoeffs) {
530
532
  const c = -inverseCoeffs[2] / inverseCoeffs[0];
531
533
  const b = 1 / inverseCoeffs[0];
@@ -540,6 +542,7 @@ const Logarithm = ___default["default"].extend({}, PlotDefaults, {
540
542
  return a * Math.log(b * x + c);
541
543
  },
542
544
  getEquationString: function (coords, asymptote) {
545
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
543
546
  if (!asymptote) {
544
547
  return null;
545
548
  }
@@ -550,7 +553,7 @@ const Logarithm = ___default["default"].extend({}, PlotDefaults, {
550
553
  return "y = ln(" + a.toFixed(3) + "x + " + b.toFixed(3) + ") + " + c.toFixed(3);
551
554
  }
552
555
  });
553
- const AbsoluteValue = ___default["default"].extend({}, PlotDefaults, {
556
+ const AbsoluteValue = ___default.default.extend({}, PlotDefaults, {
554
557
  url: "https://ka-perseus-graphie.s3.amazonaws.com/8256a630175a0cb1d11de223d6de0266daf98721.png",
555
558
  defaultCoords: [[0.5, 0.5], [0.75, 0.75]],
556
559
  getCoefficients: function (coords) {
@@ -594,7 +597,7 @@ const functionTypeMapping = {
594
597
  logarithm: Logarithm,
595
598
  absolute_value: AbsoluteValue
596
599
  };
597
- const allTypes = ___default["default"].keys(functionTypeMapping);
600
+ const allTypes = ___default.default.keys(functionTypeMapping);
598
601
  function functionForType(type) {
599
602
  // @ts-expect-error: TypeScript doesn't know how to use deal with generics
600
603
  // and conditional types in this way.
@@ -691,8 +694,6 @@ function buildTestData(testObject) {
691
694
  return `{"data":{"assessmentItem":{"__typename":"AssessmentItemOrError","error":null,"item":{"__typename":"AssessmentItem","id":"x890b3c70f3e8f4a6","itemData":"${testObject}","problemType":"Type 1","sha":"c7284a3ad65214b4e62bccce236d92f7f5d35941"}}}}`;
692
695
  }
693
696
 
694
- process.env.NODE_ENV === 'production';
695
-
696
697
  function success(value) {
697
698
  return {
698
699
  type: "success",
@@ -1177,6 +1178,7 @@ function deriveExtraKeys(widgetOptions) {
1177
1178
  const extraVariables = Object.keys(uniqueExtraVariables).sort();
1178
1179
  const extraConstants = Object.keys(uniqueExtraConstants).sort();
1179
1180
  const extraKeys = [...extraVariables, ...extraConstants];
1181
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
1180
1182
  if (!extraKeys.length) {
1181
1183
  return defaultKeys;
1182
1184
  }
@@ -2861,8 +2863,11 @@ function throwErrorIfCheatingDetected() {
2861
2863
  }
2862
2864
 
2863
2865
  // This file is processed by a Rollup plugin (replace) to inject the production
2866
+ // version number during the release build.
2867
+ // In dev, you'll never see the version number.
2868
+
2864
2869
  const libName = "@khanacademy/perseus-core";
2865
- const libVersion = "5.4.2";
2870
+ const libVersion = "7.0.0";
2866
2871
  perseusUtils.addLibraryVersionToPerseusDebug(libName, libVersion);
2867
2872
 
2868
2873
  /**
@@ -2921,6 +2926,7 @@ class PerseusError extends Error {
2921
2926
  * _ utilities for objects
2922
2927
  */
2923
2928
 
2929
+
2924
2930
  /**
2925
2931
  * Does a pluck on keys inside objects in an object
2926
2932
  *
@@ -2939,7 +2945,7 @@ class PerseusError extends Error {
2939
2945
  * }
2940
2946
  */
2941
2947
  const pluck = function (table, subKey) {
2942
- return ___default["default"].object(___default["default"].map(table, function (value, key) {
2948
+ return ___default.default.object(___default.default.map(table, function (value, key) {
2943
2949
  return [key, value[subKey]];
2944
2950
  }));
2945
2951
  };
@@ -3349,6 +3355,7 @@ const labelImageWidgetLogic = {
3349
3355
  /* Note(tamara): Brought over from the perseus package packages/perseus/src/util.ts file.
3350
3356
  May be useful to bring other perseus package utilities here. Contains utility functions
3351
3357
  and types used across multiple widgets for randomization and shuffling. */
3358
+
3352
3359
  const seededRNG = function (seed) {
3353
3360
  let randomSeed = seed;
3354
3361
  return function () {
@@ -3370,11 +3377,13 @@ const seededRNG = function (seed) {
3370
3377
  function shuffle(array, randomSeed) {
3371
3378
  let ensurePermuted = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
3372
3379
  // Always return a copy of the input array
3373
- const shuffled = ___default["default"].clone(array);
3380
+ const shuffled = ___default.default.clone(array);
3374
3381
 
3375
3382
  // Handle edge cases (input array is empty or uniform)
3376
- if (!shuffled.length || ___default["default"].all(shuffled, function (value) {
3377
- return ___default["default"].isEqual(value, shuffled[0]);
3383
+ if (
3384
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
3385
+ !shuffled.length || ___default.default.all(shuffled, function (value) {
3386
+ return ___default.default.isEqual(value, shuffled[0]);
3378
3387
  })) {
3379
3388
  return shuffled;
3380
3389
  }
@@ -3395,7 +3404,7 @@ function shuffle(array, randomSeed) {
3395
3404
  // @ts-expect-error - TS2542 - Index signature in type 'readonly T[]' only permits reading.
3396
3405
  shuffled[top - 1] = temp;
3397
3406
  }
3398
- } while (ensurePermuted && ___default["default"].isEqual(array, shuffled));
3407
+ } while (ensurePermuted && ___default.default.isEqual(array, shuffled));
3399
3408
  return shuffled;
3400
3409
  }
3401
3410
  const random = seededRNG(new Date().getTime() & 0xffffffff);
@@ -3797,6 +3806,7 @@ function getRadioPublicWidgetOptions(options) {
3797
3806
  } = options;
3798
3807
  return {
3799
3808
  ...options,
3809
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
3800
3810
  numCorrect: usesNumCorrect(multipleSelect, countChoices, numCorrect) ? numCorrect : undefined,
3801
3811
  choices: choices.map(getRadioChoicePublicData)
3802
3812
  };
@@ -3984,13 +3994,13 @@ registerWidget("video", videoWidgetLogic);
3984
3994
 
3985
3995
  var coreWidgetRegistry = /*#__PURE__*/Object.freeze({
3986
3996
  __proto__: null,
3987
- isWidgetRegistered: isWidgetRegistered,
3988
3997
  getCurrentVersion: getCurrentVersion,
3989
- getPublicWidgetOptionsFunction: getPublicWidgetOptionsFunction,
3990
- getWidgetOptionsUpgrades: getWidgetOptionsUpgrades,
3998
+ getDefaultAlignment: getDefaultAlignment,
3991
3999
  getDefaultWidgetOptions: getDefaultWidgetOptions,
4000
+ getPublicWidgetOptionsFunction: getPublicWidgetOptionsFunction,
3992
4001
  getSupportedAlignments: getSupportedAlignments,
3993
- getDefaultAlignment: getDefaultAlignment
4002
+ getWidgetOptionsUpgrades: getWidgetOptionsUpgrades,
4003
+ isWidgetRegistered: isWidgetRegistered
3994
4004
  });
3995
4005
 
3996
4006
  const DEFAULT_STATIC = false;
@@ -4000,7 +4010,7 @@ const upgradeWidgetInfoToLatestVersion = oldWidgetInfo => {
4000
4010
  // that `type` is non-optional. But we're seeing this in Sentry today so I
4001
4011
  // suspect we have legacy data (potentially unpublished) and we should
4002
4012
  // figure that out before depending solely on types.
4003
- if (!___default["default"].isString(type)) {
4013
+ if (!___default.default.isString(type)) {
4004
4014
  throw new PerseusError("widget type must be a string, but was: " + type, Errors.Internal);
4005
4015
  }
4006
4016
  if (!isWidgetRegistered(type)) {
@@ -4026,14 +4036,15 @@ const upgradeWidgetInfoToLatestVersion = oldWidgetInfo => {
4026
4036
  // We do a clone here so that it's safe to mutate the input parameter
4027
4037
  // in propUpgrades functions (which I will probably accidentally do at
4028
4038
  // some point, and we would like to not break when that happens).
4029
- let newEditorOptions = ___default["default"].clone(oldWidgetInfo.options) || {};
4039
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
4040
+ let newEditorOptions = ___default.default.clone(oldWidgetInfo.options) || {};
4030
4041
  const upgradePropsMap = getWidgetOptionsUpgrades(type);
4031
4042
 
4032
4043
  // Empty props usually mean a newly created widget by the editor,
4033
4044
  // and are always considerered up-to-date.
4034
4045
  // Mostly, we'd rather not run upgrade functions on props that are
4035
4046
  // not complete.
4036
- if (___default["default"].keys(newEditorOptions).length !== 0) {
4047
+ if (___default.default.keys(newEditorOptions).length !== 0) {
4037
4048
  // We loop through all the versions after the current version of
4038
4049
  // the loaded widget, up to and including the latest version of the
4039
4050
  // loaded widget, and run the upgrade function to bring our loaded
@@ -4125,7 +4136,7 @@ function getUpgradedWidgetOptions(oldWidgetOptions) {
4125
4136
  * @param originalItem - the original, full Perseus item (which includes the rubric - aka answer data)
4126
4137
  */
4127
4138
  function splitPerseusItem(originalItem) {
4128
- const item = ___default["default"].clone(originalItem);
4139
+ const item = ___default.default.clone(originalItem);
4129
4140
  const originalWidgets = item.widgets ?? {};
4130
4141
  const upgradedWidgets = getUpgradedWidgetOptions(originalWidgets);
4131
4142
  const splitWidgets = {};