@khanacademy/perseus 57.2.2 → 59.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/es/index.js +430 -127
- package/dist/es/index.js.map +1 -1
- package/dist/es/strings.js +0 -4
- package/dist/es/strings.js.map +1 -1
- package/dist/index.js +1405 -1076
- package/dist/index.js.map +1 -1
- package/dist/strings.d.ts +0 -4
- package/dist/strings.js +0 -4
- package/dist/strings.js.map +1 -1
- package/package.json +12 -12
package/dist/es/index.js
CHANGED
|
@@ -27,7 +27,7 @@ import { KeypadContext } from '@khanacademy/keypad-context';
|
|
|
27
27
|
import { TextField } from '@khanacademy/wonder-blocks-form';
|
|
28
28
|
import { entries, UnreachableCaseError, keys } from '@khanacademy/wonder-stuff-core';
|
|
29
29
|
import { CircularSpinner } from '@khanacademy/wonder-blocks-progress-spinner';
|
|
30
|
-
import { point, KhanMath, vector as vector$3,
|
|
30
|
+
import { point, KhanMath, number, vector as vector$3, geometry, line, angles, coefficients } from '@khanacademy/kmath';
|
|
31
31
|
import _classPrivateFieldLooseBase from '@babel/runtime/helpers/classPrivateFieldLooseBase';
|
|
32
32
|
import _classPrivateFieldLooseKey from '@babel/runtime/helpers/classPrivateFieldLooseKey';
|
|
33
33
|
import SimpleMarkdown from '@khanacademy/simple-markdown';
|
|
@@ -54,6 +54,7 @@ import { addLibraryVersionToPerseusDebug } from '@khanacademy/perseus-utils';
|
|
|
54
54
|
* The translated strings that are used to render Perseus.
|
|
55
55
|
*/
|
|
56
56
|
|
|
57
|
+
|
|
57
58
|
/**
|
|
58
59
|
* Mock strings for the Perseus package, to be used for tests and Storybook.
|
|
59
60
|
*/
|
|
@@ -237,8 +238,6 @@ const mockStrings = {
|
|
|
237
238
|
// The following strings are used for interactive graph SR descriptions.
|
|
238
239
|
srGraphInstructions: "Use the Tab key to move through the interactive elements in the graph. When an interactive element has focus, use Control + Shift + Arrows to move it.",
|
|
239
240
|
srUnlimitedGraphInstructions: "Press Shift + Enter to interact with the graph. Use the Tab key to move through the interactive elements in the graph and access the graph Action Bar. When an interactive element has focus, use Control + Shift + Arrows to move it or use the Delete key to remove it from the graph. Use the buttons in the Action Bar to add or adjust elements within the graph.",
|
|
240
|
-
xAxis: "X-axis",
|
|
241
|
-
yAxis: "Y-axis",
|
|
242
241
|
graphKeyboardPrompt: "Press Shift + Enter to interact with the graph",
|
|
243
242
|
addPoint: "Add Point",
|
|
244
243
|
removePoint: "Remove Point",
|
|
@@ -755,6 +754,7 @@ class InnerMathInput extends React.Component {
|
|
|
755
754
|
const translator = getKeyTranslator(locale, this.context.strings)[key];
|
|
756
755
|
const mathField = this.mathField();
|
|
757
756
|
if (mathField) {
|
|
757
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
758
758
|
if (translator) {
|
|
759
759
|
translator(mathField, key);
|
|
760
760
|
}
|
|
@@ -1040,9 +1040,9 @@ const useDependencies = () => {
|
|
|
1040
1040
|
|
|
1041
1041
|
var dependencies = /*#__PURE__*/Object.freeze({
|
|
1042
1042
|
__proto__: null,
|
|
1043
|
-
setDependencies: setDependencies,
|
|
1044
|
-
getDependencies: getDependencies,
|
|
1045
1043
|
DependenciesContext: DependenciesContext,
|
|
1044
|
+
getDependencies: getDependencies,
|
|
1045
|
+
setDependencies: setDependencies,
|
|
1046
1046
|
useDependencies: useDependencies
|
|
1047
1047
|
});
|
|
1048
1048
|
|
|
@@ -1073,6 +1073,15 @@ const denylist = [
|
|
|
1073
1073
|
"onBlur", "onFocus", "trackInteraction", "keypadElement"];
|
|
1074
1074
|
|
|
1075
1075
|
/* eslint-disable @babel/no-invalid-this */
|
|
1076
|
+
/**
|
|
1077
|
+
* Changeable
|
|
1078
|
+
*
|
|
1079
|
+
* Adds a this.change() function to a component
|
|
1080
|
+
*
|
|
1081
|
+
* This.change takes prop changes as parameters, and calls
|
|
1082
|
+
* this.props.onChange with the modified props.
|
|
1083
|
+
*/
|
|
1084
|
+
|
|
1076
1085
|
const USAGE = "Usage:\n" + " this.change({propName: 5}, callback);\n" + ' this.change("propName", 5, callback);\n' + ' this.change("propName")';
|
|
1077
1086
|
|
|
1078
1087
|
/**
|
|
@@ -1153,6 +1162,7 @@ var changeable = /*#__PURE__*/Object.freeze({
|
|
|
1153
1162
|
});
|
|
1154
1163
|
|
|
1155
1164
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
1165
|
+
/* eslint-disable @babel/no-invalid-this, react/forbid-prop-types, react/no-unsafe */
|
|
1156
1166
|
const textWidthCache = {};
|
|
1157
1167
|
function getTextWidth(text) {
|
|
1158
1168
|
if (!textWidthCache[text]) {
|
|
@@ -1531,6 +1541,7 @@ class Expression extends React.Component {
|
|
|
1531
1541
|
// HACK: imperatively add an ID onto the Mathquill input
|
|
1532
1542
|
// (which in mobile is a span; desktop a textarea)
|
|
1533
1543
|
// in order to associate a visual label with it
|
|
1544
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
1534
1545
|
if (this.refs.input) {
|
|
1535
1546
|
const isMobile = this.props.apiOptions.customKeypad;
|
|
1536
1547
|
const container = ReactDOM__default.findDOMNode(this.refs.input);
|
|
@@ -1573,6 +1584,7 @@ class Expression extends React.Component {
|
|
|
1573
1584
|
this.parse = (value, props) => {
|
|
1574
1585
|
// TODO(jack): Disable icu for content creators here, or
|
|
1575
1586
|
// make it so that solution answers with ','s or '.'s work
|
|
1587
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
1576
1588
|
const options = _.pick(props || this.props, "functions");
|
|
1577
1589
|
_.extend(options, {
|
|
1578
1590
|
decimal_separator: getDecimalSeparator(this.context.locale)
|
|
@@ -1800,6 +1812,7 @@ var Expression$1 = {
|
|
|
1800
1812
|
// TODO(LEMS-2656): remove TS suppression
|
|
1801
1813
|
// @ts-expect-error: Type 'Rubric' is not assignable to type 'PerseusExpressionRubric'.
|
|
1802
1814
|
getOneCorrectAnswerFromRubric(rubric) {
|
|
1815
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
1803
1816
|
const correctAnswers = (rubric.answerForms || []).filter(answerForm => answerForm.considered === "correct");
|
|
1804
1817
|
if (correctAnswers.length === 0) {
|
|
1805
1818
|
return;
|
|
@@ -1990,6 +2003,7 @@ TextInput.defaultProps = {
|
|
|
1990
2003
|
* loaded. This is used to know when SvgImage and (Zoomable)TeX are finished
|
|
1991
2004
|
* renderering.
|
|
1992
2005
|
*/
|
|
2006
|
+
|
|
1993
2007
|
const defaultContext$2 = {
|
|
1994
2008
|
assetStatuses: {},
|
|
1995
2009
|
setAssetStatus: (assetKey, loaded) => {}
|
|
@@ -2083,6 +2097,7 @@ const snowman = "\u2603";
|
|
|
2083
2097
|
* Drop this custom split thing.
|
|
2084
2098
|
*/
|
|
2085
2099
|
// In IE8, split doesn't work right. Implement it ourselves.
|
|
2100
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
2086
2101
|
const split = "x".split(/(.)/g).length ? function (str, r) {
|
|
2087
2102
|
return str.split(r);
|
|
2088
2103
|
} : function (str, r) {
|
|
@@ -2614,6 +2629,7 @@ function getUrlHash(url) {
|
|
|
2614
2629
|
if (match == null) {
|
|
2615
2630
|
throw new PerseusError("not a valid URL", Errors.InvalidInput);
|
|
2616
2631
|
}
|
|
2632
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
2617
2633
|
return match && match[1];
|
|
2618
2634
|
}
|
|
2619
2635
|
|
|
@@ -2722,6 +2738,8 @@ function loadGraphie(url, onDataLoaded) {
|
|
|
2722
2738
|
}
|
|
2723
2739
|
|
|
2724
2740
|
// Derived from the MIT-licensed:
|
|
2741
|
+
// https://github.com/fat/zoom.js/blob/fd4f3e43153da7596da0bade198e99f98b47791e/js/zoom.js
|
|
2742
|
+
|
|
2725
2743
|
|
|
2726
2744
|
/*jshint browser:true, node:true */
|
|
2727
2745
|
|
|
@@ -2979,6 +2997,7 @@ Zoom._OFFSET = 80;
|
|
|
2979
2997
|
Zoom._MAX_WIDTH = 2560;
|
|
2980
2998
|
Zoom._MAX_HEIGHT = 4096;
|
|
2981
2999
|
Zoom.getOffset = function (zoomToFitOnMobile) {
|
|
3000
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
2982
3001
|
return zoomToFitOnMobile ? 0 : Zoom._OFFSET;
|
|
2983
3002
|
};
|
|
2984
3003
|
Zoom.prototype.getOffset = function () {
|
|
@@ -3229,39 +3248,39 @@ const articleMaxWidthTableInPx = 512;
|
|
|
3229
3248
|
|
|
3230
3249
|
var constants = /*#__PURE__*/Object.freeze({
|
|
3231
3250
|
__proto__: null,
|
|
3251
|
+
articleMaxWidthInPx: articleMaxWidthInPx,
|
|
3252
|
+
articleMaxWidthTableInPx: articleMaxWidthTableInPx,
|
|
3232
3253
|
baseFontFamily: baseFontFamily,
|
|
3254
|
+
baseUnitPx: baseUnitPx,
|
|
3233
3255
|
boldFontFamily: boldFontFamily,
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
gray97: gray97,
|
|
3237
|
-
gray85: gray85,
|
|
3238
|
-
gray76: gray76,
|
|
3239
|
-
gray68: gray68,
|
|
3256
|
+
checkedColor: checkedColor$1,
|
|
3257
|
+
circleSize: circleSize$1,
|
|
3240
3258
|
gray17: gray17,
|
|
3241
|
-
|
|
3242
|
-
|
|
3259
|
+
gray68: gray68,
|
|
3260
|
+
gray76: gray76,
|
|
3261
|
+
gray85: gray85,
|
|
3262
|
+
gray97: gray97,
|
|
3263
|
+
hintBorderWidth: hintBorderWidth,
|
|
3264
|
+
interactiveSizes: interactiveSizes$1,
|
|
3265
|
+
kaGreen: kaGreen,
|
|
3266
|
+
negativePhoneMargin: negativePhoneMargin,
|
|
3267
|
+
phoneMargin: phoneMargin,
|
|
3268
|
+
publishBlockingErrorColor: publishBlockingErrorColor,
|
|
3269
|
+
pureLgMax: pureLgMax$1,
|
|
3243
3270
|
pureLgMin: pureLgMin$1,
|
|
3271
|
+
pureMdMax: pureMdMax$1,
|
|
3272
|
+
pureMdMin: pureMdMin$1,
|
|
3273
|
+
pureSmMax: pureSmMax$1,
|
|
3274
|
+
pureSmMin: pureSmMin$1,
|
|
3244
3275
|
pureXlMin: pureXlMin$1,
|
|
3245
3276
|
pureXsMax: pureXsMax$1,
|
|
3246
|
-
|
|
3247
|
-
pureMdMax: pureMdMax$1,
|
|
3248
|
-
pureLgMax: pureLgMax$1,
|
|
3249
|
-
tableBackgroundAccent: tableBackgroundAccent,
|
|
3250
|
-
phoneMargin: phoneMargin,
|
|
3251
|
-
negativePhoneMargin: negativePhoneMargin,
|
|
3252
|
-
hintBorderWidth: hintBorderWidth,
|
|
3253
|
-
baseUnitPx: baseUnitPx,
|
|
3254
|
-
interactiveSizes: interactiveSizes$1,
|
|
3255
|
-
circleSize: circleSize$1,
|
|
3277
|
+
radioBorderColor: radioBorderColor$1,
|
|
3256
3278
|
radioMarginWidth: radioMarginWidth$1,
|
|
3279
|
+
tableBackgroundAccent: tableBackgroundAccent,
|
|
3257
3280
|
warningColor: warningColor,
|
|
3258
|
-
warningColorHover: warningColorHover,
|
|
3259
3281
|
warningColorActive: warningColorActive,
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
checkedColor: checkedColor$1,
|
|
3263
|
-
articleMaxWidthInPx: articleMaxWidthInPx,
|
|
3264
|
-
articleMaxWidthTableInPx: articleMaxWidthTableInPx
|
|
3282
|
+
warningColorHover: warningColorHover,
|
|
3283
|
+
white: white
|
|
3265
3284
|
});
|
|
3266
3285
|
|
|
3267
3286
|
/**
|
|
@@ -3368,6 +3387,8 @@ class FixedToResponsive extends React.Component {
|
|
|
3368
3387
|
style: style
|
|
3369
3388
|
}, spacer, this.props.children);
|
|
3370
3389
|
const shouldFullBleed = this.props.allowFullBleed && this.state.viewportWidth && width >= this.state.viewportWidth;
|
|
3390
|
+
|
|
3391
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
3371
3392
|
if (shouldFullBleed) {
|
|
3372
3393
|
return /*#__PURE__*/React.createElement("div", {
|
|
3373
3394
|
style: {
|
|
@@ -3595,6 +3616,7 @@ const InteractiveUtil = {
|
|
|
3595
3616
|
getPrefixedTransform: function () {
|
|
3596
3617
|
// Cache result to avoid re-computation
|
|
3597
3618
|
// @ts-expect-error - TS2322 - Type 'string | null | undefined' is not assignable to type 'null'.
|
|
3619
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
3598
3620
|
prefixedTransform = prefixedTransform || computePrefixedTransform();
|
|
3599
3621
|
return prefixedTransform;
|
|
3600
3622
|
},
|
|
@@ -7979,24 +8001,42 @@ class GraphBounds {
|
|
|
7979
8001
|
}
|
|
7980
8002
|
}
|
|
7981
8003
|
|
|
7982
|
-
var
|
|
8004
|
+
var client = {};
|
|
7983
8005
|
|
|
7984
|
-
var
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
8006
|
+
var hasRequiredClient;
|
|
8007
|
+
|
|
8008
|
+
function requireClient () {
|
|
8009
|
+
if (hasRequiredClient) return client;
|
|
8010
|
+
hasRequiredClient = 1;
|
|
8011
|
+
|
|
8012
|
+
var m = ReactDOM__default;
|
|
8013
|
+
if (process.env.NODE_ENV === 'production') {
|
|
8014
|
+
client.createRoot = m.createRoot;
|
|
8015
|
+
client.hydrateRoot = m.hydrateRoot;
|
|
8016
|
+
} else {
|
|
8017
|
+
var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
8018
|
+
client.createRoot = function(c, o) {
|
|
8019
|
+
i.usingClientEntryPoint = true;
|
|
8020
|
+
try {
|
|
8021
|
+
return m.createRoot(c, o);
|
|
8022
|
+
} finally {
|
|
8023
|
+
i.usingClientEntryPoint = false;
|
|
8024
|
+
}
|
|
8025
|
+
};
|
|
8026
|
+
client.hydrateRoot = function(c, h, o) {
|
|
8027
|
+
i.usingClientEntryPoint = true;
|
|
8028
|
+
try {
|
|
8029
|
+
return m.hydrateRoot(c, h, o);
|
|
8030
|
+
} finally {
|
|
8031
|
+
i.usingClientEntryPoint = false;
|
|
8032
|
+
}
|
|
8033
|
+
};
|
|
8034
|
+
}
|
|
8035
|
+
return client;
|
|
7998
8036
|
}
|
|
7999
8037
|
|
|
8038
|
+
var clientExports = requireClient();
|
|
8039
|
+
|
|
8000
8040
|
// We keep a cache of elements that have already had createRoot() called on
|
|
8001
8041
|
// them. If we don't do this, React 18 warns every subsequent call:
|
|
8002
8042
|
// > You are calling ReactDOMClient.createRoot() on a container that has
|
|
@@ -8026,7 +8066,7 @@ function render(element, container) {
|
|
|
8026
8066
|
}, element);
|
|
8027
8067
|
let root = reactRootCache.get(container);
|
|
8028
8068
|
if (root == null) {
|
|
8029
|
-
root = createRoot(container);
|
|
8069
|
+
root = clientExports.createRoot(container);
|
|
8030
8070
|
reactRootCache.set(container, root);
|
|
8031
8071
|
}
|
|
8032
8072
|
root.render(children);
|
|
@@ -8105,7 +8145,7 @@ function polar$2(r, th) {
|
|
|
8105
8145
|
}
|
|
8106
8146
|
var _bounds = /*#__PURE__*/_classPrivateFieldLooseKey("bounds");
|
|
8107
8147
|
var _drawingTransform = /*#__PURE__*/_classPrivateFieldLooseKey("drawingTransform");
|
|
8108
|
-
|
|
8148
|
+
let Graphie$1 = class Graphie {
|
|
8109
8149
|
constructor(el) {
|
|
8110
8150
|
this.el = void 0;
|
|
8111
8151
|
Object.defineProperty(this, _bounds, {
|
|
@@ -8301,6 +8341,7 @@ class Graphie$1 {
|
|
|
8301
8341
|
}
|
|
8302
8342
|
init(options) {
|
|
8303
8343
|
var _options$isMobile;
|
|
8344
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8304
8345
|
let scale = options.scale || [40, 40];
|
|
8305
8346
|
scale = typeof scale === "number" ? [scale, scale] : scale;
|
|
8306
8347
|
|
|
@@ -8340,6 +8381,7 @@ class Graphie$1 {
|
|
|
8340
8381
|
// - yLabelFormat: fn to format label string for y-axis
|
|
8341
8382
|
// - xLabelFormat: fn to format label string for x-axis
|
|
8342
8383
|
graphInit(options) {
|
|
8384
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8343
8385
|
options = options || {};
|
|
8344
8386
|
for (const [prop, val] of entries(options)) {
|
|
8345
8387
|
// allow options to be specified by a single number for shorthand if
|
|
@@ -8355,22 +8397,28 @@ class Graphie$1 {
|
|
|
8355
8397
|
}
|
|
8356
8398
|
const range = normalizeRange(options.range || [[-10, 10], [-10, 10]]);
|
|
8357
8399
|
const gridRange = normalizeRange(options.gridRange || range);
|
|
8400
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8358
8401
|
const scale = options.scale || [20, 20];
|
|
8359
8402
|
const grid = options.grid != null ? options.grid : true;
|
|
8360
8403
|
const gridOpacity = options.gridOpacity || 0.1;
|
|
8404
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8361
8405
|
const gridStep = toPair(options.gridStep || [1, 1]);
|
|
8362
8406
|
const axes = options.axes != null ? options.axes : true;
|
|
8407
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8363
8408
|
const axisArrows = options.axisArrows || "";
|
|
8364
8409
|
const axisOpacity = options.axisOpacity || 1.0;
|
|
8365
8410
|
const axisCenter = options.axisCenter || [Math.min(Math.max(range[0][0], 0), range[0][1]), Math.min(Math.max(range[1][0], 0), range[1][1])];
|
|
8366
8411
|
const axisLabels = options.axisLabels != null ? options.axisLabels : false;
|
|
8367
8412
|
const ticks = options.ticks != null ? options.ticks : true;
|
|
8413
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8368
8414
|
const tickStep = options.tickStep || [2, 2];
|
|
8415
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8369
8416
|
const tickLen = options.tickLen || [5, 5];
|
|
8370
8417
|
const tickOpacity = options.tickOpacity || 1.0;
|
|
8371
8418
|
const labels = options.labels || options.labelStep || false;
|
|
8372
8419
|
const labelStep = options.labelStep || [1, 1];
|
|
8373
8420
|
const labelOpacity = options.labelOpacity || 1.0;
|
|
8421
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8374
8422
|
let unityLabels = options.unityLabels || false;
|
|
8375
8423
|
const labelFormat = options.labelFormat || function (a) {
|
|
8376
8424
|
return a;
|
|
@@ -8439,6 +8487,8 @@ class Graphie$1 {
|
|
|
8439
8487
|
thisGraphie.path([[axisCenter[0], gridRange[1][0]], [axisCenter[0], gridRange[1][1]]]);
|
|
8440
8488
|
});
|
|
8441
8489
|
}
|
|
8490
|
+
|
|
8491
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8442
8492
|
if (axisLabels && axisLabels.length === 2) {
|
|
8443
8493
|
this.label([gridRange[0][1], axisCenter[1]], axisLabels[0], "right");
|
|
8444
8494
|
this.label([axisCenter[0], gridRange[1][1]], axisLabels[1], "above");
|
|
@@ -8461,11 +8511,13 @@ class Graphie$1 {
|
|
|
8461
8511
|
let stop = gridRange[0][1];
|
|
8462
8512
|
if (range[1][0] < 0 && range[1][1] > 0) {
|
|
8463
8513
|
for (let x = step + axisCenter[0]; x <= stop; x += step) {
|
|
8514
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8464
8515
|
if (x < stop || !axisArrows) {
|
|
8465
8516
|
thisGraphie.line([x, -len + axisCenter[1]], [x, halfWidthTicks ? 0 : len + axisCenter[1]]);
|
|
8466
8517
|
}
|
|
8467
8518
|
}
|
|
8468
8519
|
for (let x = -step + axisCenter[0]; x >= start; x -= step) {
|
|
8520
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8469
8521
|
if (x > start || !axisArrows) {
|
|
8470
8522
|
thisGraphie.line([x, -len + axisCenter[1]], [x, halfWidthTicks ? 0 : len + axisCenter[1]]);
|
|
8471
8523
|
}
|
|
@@ -8479,11 +8531,13 @@ class Graphie$1 {
|
|
|
8479
8531
|
stop = gridRange[1][1];
|
|
8480
8532
|
if (range[0][0] < 0 && range[0][1] > 0) {
|
|
8481
8533
|
for (let y = step + axisCenter[1]; y <= stop; y += step) {
|
|
8534
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8482
8535
|
if (y < stop || !axisArrows) {
|
|
8483
8536
|
this.line([-len + axisCenter[0], y], [halfWidthTicks ? 0 : len + axisCenter[0], y]);
|
|
8484
8537
|
}
|
|
8485
8538
|
}
|
|
8486
8539
|
for (let y = -step + axisCenter[1]; y >= start; y -= step) {
|
|
8540
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8487
8541
|
if (y > start || !axisArrows) {
|
|
8488
8542
|
this.line([-len + axisCenter[0], y], [halfWidthTicks ? 0 : len + axisCenter[0], y]);
|
|
8489
8543
|
}
|
|
@@ -8493,6 +8547,7 @@ class Graphie$1 {
|
|
|
8493
8547
|
}
|
|
8494
8548
|
|
|
8495
8549
|
// draw axis labels
|
|
8550
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8496
8551
|
if (labels) {
|
|
8497
8552
|
const thisGraphie = this;
|
|
8498
8553
|
this.style({
|
|
@@ -8513,6 +8568,7 @@ class Graphie$1 {
|
|
|
8513
8568
|
|
|
8514
8569
|
// positive x-axis
|
|
8515
8570
|
for (let x = (xShowZero ? 0 : step) + axisCenter[0]; x <= stop; x += step) {
|
|
8571
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8516
8572
|
if (x < stop || !axisArrows) {
|
|
8517
8573
|
thisGraphie.label([x, axisCenter[1]], xLabelFormat(x), xAxisPosition);
|
|
8518
8574
|
}
|
|
@@ -8520,6 +8576,7 @@ class Graphie$1 {
|
|
|
8520
8576
|
|
|
8521
8577
|
// negative x-axis
|
|
8522
8578
|
for (let x = -step * (showUnityX ? 1 : 2) + axisCenter[0]; x >= start; x -= step) {
|
|
8579
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8523
8580
|
if (x > start || !axisArrows) {
|
|
8524
8581
|
thisGraphie.label([x, axisCenter[1]], xLabelFormat(x), xAxisPosition);
|
|
8525
8582
|
}
|
|
@@ -8530,6 +8587,7 @@ class Graphie$1 {
|
|
|
8530
8587
|
|
|
8531
8588
|
// positive y-axis
|
|
8532
8589
|
for (let y = (yShowZero ? 0 : step) + axisCenter[1]; y <= stop; y += step) {
|
|
8590
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8533
8591
|
if (y < stop || !axisArrows) {
|
|
8534
8592
|
thisGraphie.label([axisCenter[0], y], yLabelFormat(y), yAxisPosition);
|
|
8535
8593
|
}
|
|
@@ -8537,6 +8595,7 @@ class Graphie$1 {
|
|
|
8537
8595
|
|
|
8538
8596
|
// negative y-axis
|
|
8539
8597
|
for (let y = -step * (showUnityY ? 1 : 2) + axisCenter[1]; y >= start; y -= step) {
|
|
8598
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8540
8599
|
if (y > start || !axisArrows) {
|
|
8541
8600
|
thisGraphie.label([axisCenter[0], y], yLabelFormat(y), yAxisPosition);
|
|
8542
8601
|
}
|
|
@@ -8675,6 +8734,7 @@ class Graphie$1 {
|
|
|
8675
8734
|
fixedPath(points, center, createPath) {
|
|
8676
8735
|
points = points.map(this.scalePoint);
|
|
8677
8736
|
center = center ? this.scalePoint(center) : null;
|
|
8737
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
8678
8738
|
createPath = createPath || this.svgPath;
|
|
8679
8739
|
|
|
8680
8740
|
// Compute bounding box
|
|
@@ -8805,7 +8865,7 @@ class Graphie$1 {
|
|
|
8805
8865
|
// write these functions the way we do to handle undefined.
|
|
8806
8866
|
const clip = xy => {
|
|
8807
8867
|
if (Math.abs(xy[1]) > 500000) {
|
|
8808
|
-
return [xy[0], Math.min(Math.max(xy[1], -
|
|
8868
|
+
return [xy[0], Math.min(Math.max(xy[1], -5e5), 500000)];
|
|
8809
8869
|
}
|
|
8810
8870
|
return xy;
|
|
8811
8871
|
};
|
|
@@ -9085,17 +9145,17 @@ class Graphie$1 {
|
|
|
9085
9145
|
getMouseCoord(event) {
|
|
9086
9146
|
return this.unscalePoint(this.getMousePx(event));
|
|
9087
9147
|
}
|
|
9088
|
-
}
|
|
9148
|
+
};
|
|
9089
9149
|
const labelDirections = {
|
|
9090
9150
|
center: [-0.5, -0.5],
|
|
9091
|
-
above: [-0.5, -1
|
|
9092
|
-
"above right": [0.0, -1
|
|
9151
|
+
above: [-0.5, -1],
|
|
9152
|
+
"above right": [0.0, -1],
|
|
9093
9153
|
right: [0.0, -0.5],
|
|
9094
9154
|
"below right": [0.0, 0.0],
|
|
9095
9155
|
below: [-0.5, 0.0],
|
|
9096
|
-
"below left": [-1
|
|
9097
|
-
left: [-1
|
|
9098
|
-
"above left": [-1
|
|
9156
|
+
"below left": [-1, 0.0],
|
|
9157
|
+
left: [-1, -0.5],
|
|
9158
|
+
"above left": [-1, -1]
|
|
9099
9159
|
};
|
|
9100
9160
|
|
|
9101
9161
|
// A range for a Graphie can be specified in one of three forms:
|
|
@@ -9272,6 +9332,7 @@ const GraphUtils = {
|
|
|
9272
9332
|
if (vertex === undefined) {
|
|
9273
9333
|
const x = point1[0] - point2[0];
|
|
9274
9334
|
const y = point1[1] - point2[1];
|
|
9335
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
9275
9336
|
if (!x && !y) {
|
|
9276
9337
|
return 0;
|
|
9277
9338
|
}
|
|
@@ -9283,6 +9344,13 @@ const GraphUtils = {
|
|
|
9283
9344
|
};
|
|
9284
9345
|
|
|
9285
9346
|
/* eslint-disable */
|
|
9347
|
+
/*
|
|
9348
|
+
* jQuery Mobile Framework : "mouse" plugin
|
|
9349
|
+
* Copyright (c) jQuery Project
|
|
9350
|
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
9351
|
+
* http://jquery.org/license
|
|
9352
|
+
*/
|
|
9353
|
+
|
|
9286
9354
|
(function ($, window, document, undefined$1) {
|
|
9287
9355
|
if (typeof $ === "undefined") {
|
|
9288
9356
|
return;
|
|
@@ -9730,6 +9798,7 @@ const getClipPoint = function getClipPoint(graph, coord, angle) {
|
|
|
9730
9798
|
* Default methods for a wrapped movable.
|
|
9731
9799
|
*/
|
|
9732
9800
|
|
|
9801
|
+
|
|
9733
9802
|
/*
|
|
9734
9803
|
* attr() and animate() simply pass the
|
|
9735
9804
|
* arguments to the underlying Raphael object.
|
|
@@ -9820,14 +9889,14 @@ class WrappedPath extends WrappedDrawing {
|
|
|
9820
9889
|
}
|
|
9821
9890
|
}
|
|
9822
9891
|
|
|
9823
|
-
|
|
9892
|
+
let Arrowhead$1 = class Arrowhead extends WrappedPath {
|
|
9824
9893
|
constructor(graphie, style) {
|
|
9825
9894
|
// Points that define the arrowhead
|
|
9826
9895
|
const center = [0.75, 0];
|
|
9827
9896
|
const points = [[-3, 4], [-2.75, 2.5], [0, 0.25], center, [0, -0.25], [-2.75, -2.5], [-3, -4]].map(point => {
|
|
9828
9897
|
// Scale points by `Arrowhead.scale` around `center`
|
|
9829
9898
|
const pv = vector$3.subtract(point, center);
|
|
9830
|
-
const pvScaled = vector$3.scale(pv, Arrowhead
|
|
9899
|
+
const pvScaled = vector$3.scale(pv, Arrowhead.scale);
|
|
9831
9900
|
return vector$3.add(center, pvScaled);
|
|
9832
9901
|
});
|
|
9833
9902
|
const unscaledPoints = points.map(graphie.unscalePoint);
|
|
@@ -9845,9 +9914,9 @@ class Arrowhead$1 extends WrappedPath {
|
|
|
9845
9914
|
}
|
|
9846
9915
|
toCoordAtAngle(coord, angle) {
|
|
9847
9916
|
const clipPoint = this.graphie.scalePoint(getClipPoint(this.graphie, coord, angle));
|
|
9848
|
-
this.transform("translateX(" + (clipPoint[0] + Arrowhead
|
|
9917
|
+
this.transform("translateX(" + (clipPoint[0] + Arrowhead.scale * this.center[0]) + "px) " + "translateY(" + (clipPoint[1] + Arrowhead.scale * this.center[1]) + "px) " + "translateZ(0) " + "rotate(" + (360 - KhanMath.bound(angle)) + "deg)");
|
|
9849
9918
|
}
|
|
9850
|
-
}
|
|
9919
|
+
};
|
|
9851
9920
|
|
|
9852
9921
|
// We can't just pass in a path to `graph.fixedPath` as we need to modify
|
|
9853
9922
|
// the points in some way, so instead we provide a function for creating
|
|
@@ -9982,6 +10051,13 @@ class WrappedLine extends WrappedDrawing {
|
|
|
9982
10051
|
}
|
|
9983
10052
|
|
|
9984
10053
|
/* eslint-disable @babel/no-invalid-this */
|
|
10054
|
+
/**
|
|
10055
|
+
* Interactive graphie utilities.
|
|
10056
|
+
*
|
|
10057
|
+
* This file exposes a couple functions, but mostly it adds functions to the
|
|
10058
|
+
* `Graphie` prototype for dealing with interactive graphie elements.
|
|
10059
|
+
*/
|
|
10060
|
+
|
|
9985
10061
|
const {
|
|
9986
10062
|
clockwise: clockwise$2,
|
|
9987
10063
|
reverseVector: reverseVector$1
|
|
@@ -11658,7 +11734,7 @@ _.extend(GraphUtils.Graphie.prototype, {
|
|
|
11658
11734
|
// and maximum angle values bounding a circle sector, and
|
|
11659
11735
|
// the third column refers to the cursor name that will be
|
|
11660
11736
|
// applied if the mouse position falls inside the given sector.
|
|
11661
|
-
const cursorAxes = [[Math.PI * -1
|
|
11737
|
+
const cursorAxes = [[Math.PI * -1, Math.PI * -0.875, "ew-resize"], [Math.PI * -0.875, Math.PI * -0.625, "nesw-resize"], [Math.PI * -0.625, Math.PI * -0.375, "ns-resize"], [Math.PI * -0.375, Math.PI * -0.125, "nwse-resize"], [Math.PI * -0.125, Math.PI * 0.125, "ew-resize"], [Math.PI * 0.125, Math.PI * 0.375, "nesw-resize"], [Math.PI * 0.375, Math.PI * 0.625, "ns-resize"], [Math.PI * 0.625, Math.PI * 0.875, "nwse-resize"], [Math.PI * 0.875, Math.PI * 1.0, "ew-resize"]];
|
|
11662
11738
|
|
|
11663
11739
|
// When the mouse moves along the circle's perimeter, we
|
|
11664
11740
|
// dynamically set a CSS rule to show the correct
|
|
@@ -11959,6 +12035,7 @@ _.extend(GraphUtils.Graphie.prototype, {
|
|
|
11959
12035
|
return isHovering;
|
|
11960
12036
|
};
|
|
11961
12037
|
const styles = _.map([0, 1], function (isHighlight) {
|
|
12038
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
11962
12039
|
const baseStyle = isHighlight ? options.highlightStyle : options.normalStyle;
|
|
11963
12040
|
return _.map([0, 1], function (opacity) {
|
|
11964
12041
|
return _.defaults({
|
|
@@ -11968,6 +12045,7 @@ _.extend(GraphUtils.Graphie.prototype, {
|
|
|
11968
12045
|
});
|
|
11969
12046
|
const getStyle = function getStyle(isRight) {
|
|
11970
12047
|
if (isFlipped) {
|
|
12048
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
11971
12049
|
isRight = !isRight;
|
|
11972
12050
|
}
|
|
11973
12051
|
return styles[+isHighlight()][+isRight];
|
|
@@ -12316,7 +12394,7 @@ function Ruler(graphie, options) {
|
|
|
12316
12394
|
});
|
|
12317
12395
|
const width = options.units * options.pixelsPerUnit;
|
|
12318
12396
|
const height = 50;
|
|
12319
|
-
const leftBottom = graphie.unscalePoint(vector$3.subtract(graphie.scalePoint(options.center), vector$3.scale([width, -
|
|
12397
|
+
const leftBottom = graphie.unscalePoint(vector$3.subtract(graphie.scalePoint(options.center), vector$3.scale([width, -50], 0.5)));
|
|
12320
12398
|
const graphieUnitsPerUnit = options.pixelsPerUnit / graphie.scale[0];
|
|
12321
12399
|
const graphieUnitsHeight = height / graphie.scale[0];
|
|
12322
12400
|
const rightTop = vector$3.add(leftBottom, [options.units * graphieUnitsPerUnit, graphieUnitsHeight]);
|
|
@@ -12831,6 +12909,7 @@ _.extend(MovableAngle.prototype, {
|
|
|
12831
12909
|
});
|
|
12832
12910
|
|
|
12833
12911
|
/* eslint-disable @babel/no-invalid-this */
|
|
12912
|
+
|
|
12834
12913
|
const nestedMap$1 = Util.nestedMap;
|
|
12835
12914
|
|
|
12836
12915
|
/**
|
|
@@ -13016,6 +13095,7 @@ class Movable {
|
|
|
13016
13095
|
// the invisible shape in front of the point that gets mouse events
|
|
13017
13096
|
if (state.mouseTarget && !prevState.mouseTarget) {
|
|
13018
13097
|
let $mouseTarget;
|
|
13098
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
13019
13099
|
if (state.mouseTarget.getMouseTarget) {
|
|
13020
13100
|
$mouseTarget = $(state.mouseTarget.getMouseTarget());
|
|
13021
13101
|
} else {
|
|
@@ -13063,6 +13143,7 @@ class Movable {
|
|
|
13063
13143
|
}
|
|
13064
13144
|
if (state.mouseTarget && state.cursor !== undefined) {
|
|
13065
13145
|
let $mouseTarget;
|
|
13146
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
13066
13147
|
if (state.mouseTarget.getMouseTarget) {
|
|
13067
13148
|
$mouseTarget = $(state.mouseTarget.getMouseTarget());
|
|
13068
13149
|
} else {
|
|
@@ -13070,6 +13151,7 @@ class Movable {
|
|
|
13070
13151
|
}
|
|
13071
13152
|
|
|
13072
13153
|
// "" removes the css cursor if state.cursor is null
|
|
13154
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
13073
13155
|
$mouseTarget.css("cursor", state.cursor || "");
|
|
13074
13156
|
}
|
|
13075
13157
|
|
|
@@ -13214,12 +13296,15 @@ class Movable {
|
|
|
13214
13296
|
* (state, prevState)]
|
|
13215
13297
|
*/
|
|
13216
13298
|
listen(eventName, id, func) {
|
|
13299
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
13217
13300
|
this._listenerMap = this._listenerMap || {};
|
|
13218
13301
|
|
|
13219
13302
|
// If there's an existing handler, replace it by using its index in
|
|
13220
13303
|
// `this.state[eventName]`; otherwise, add this handler to the end
|
|
13221
13304
|
const key = getKey$1(eventName, id);
|
|
13222
|
-
const index = this._listenerMap[key] =
|
|
13305
|
+
const index = this._listenerMap[key] =
|
|
13306
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
13307
|
+
this._listenerMap[key] || this.state[eventName].length;
|
|
13223
13308
|
this.state[eventName][index] = func;
|
|
13224
13309
|
}
|
|
13225
13310
|
|
|
@@ -13230,6 +13315,7 @@ class Movable {
|
|
|
13230
13315
|
* If the given id has not been registered already, this is a no-op
|
|
13231
13316
|
*/
|
|
13232
13317
|
unlisten(eventName, id) {
|
|
13318
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
13233
13319
|
this._listenerMap = this._listenerMap || {};
|
|
13234
13320
|
const key = getKey$1(eventName, id);
|
|
13235
13321
|
const index = this._listenerMap[key];
|
|
@@ -13283,6 +13369,9 @@ function getEventName$1(key) {
|
|
|
13283
13369
|
}
|
|
13284
13370
|
|
|
13285
13371
|
/* eslint-disable @babel/no-invalid-this */
|
|
13372
|
+
/**
|
|
13373
|
+
* A library of options to pass to add/draw/remove/constraints
|
|
13374
|
+
*/
|
|
13286
13375
|
/**
|
|
13287
13376
|
* Helper functions
|
|
13288
13377
|
*/
|
|
@@ -13853,6 +13942,9 @@ const iconMinus = {
|
|
|
13853
13942
|
};
|
|
13854
13943
|
|
|
13855
13944
|
/* eslint-disable @babel/no-invalid-this */
|
|
13945
|
+
/**
|
|
13946
|
+
* A library of options to pass to add/draw/remove/constraints
|
|
13947
|
+
*/
|
|
13856
13948
|
const add$1 = {
|
|
13857
13949
|
constrain: function () {
|
|
13858
13950
|
this.constrain();
|
|
@@ -13994,10 +14086,14 @@ const constraints$1 = {
|
|
|
13994
14086
|
let upper = graphie.unscalePoint([
|
|
13995
14087
|
// @ts-expect-error - 'graphie.ypixels' is possibly 'undefined'.
|
|
13996
14088
|
graphie.xpixels - paddingPx, paddingPx]);
|
|
14089
|
+
|
|
14090
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
13997
14091
|
if (snap) {
|
|
13998
14092
|
lower = point.ceilTo(lower, snap);
|
|
13999
14093
|
upper = point.floorTo(upper, snap);
|
|
14000
14094
|
}
|
|
14095
|
+
|
|
14096
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
14001
14097
|
if (!!options && !!options.onOutOfBounds) {
|
|
14002
14098
|
if (coord[0] > upper[0] || coord[0] < lower[0] || coord[1] > upper[1] || coord[1] < lower[1]) {
|
|
14003
14099
|
options.onSkipRemaining();
|
|
@@ -14069,7 +14165,7 @@ const DEFAULT_STATE$1 = {
|
|
|
14069
14165
|
// TODO(benchristel): this is a memory leak. We add items to
|
|
14070
14166
|
// tooltipResetFunctions, but never remove them.
|
|
14071
14167
|
const tooltipResetFunctions = [];
|
|
14072
|
-
|
|
14168
|
+
let MovablePoint$5 = class MovablePoint {
|
|
14073
14169
|
constructor(graphie, movable, options) {
|
|
14074
14170
|
this.graphie = void 0;
|
|
14075
14171
|
this.movable = void 0;
|
|
@@ -14438,12 +14534,15 @@ class MovablePoint$5 {
|
|
|
14438
14534
|
*/
|
|
14439
14535
|
// TODO(benchristel): listen() is duplicated in movable.ts
|
|
14440
14536
|
listen(eventName, id, func) {
|
|
14537
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
14441
14538
|
this._listenerMap = this._listenerMap || {};
|
|
14442
14539
|
|
|
14443
14540
|
// If there's an existing handler, replace it by using its index in
|
|
14444
14541
|
// `this.state[eventName]`; otherwise, add this handler to the end
|
|
14445
14542
|
const key = getKey(eventName, id);
|
|
14446
|
-
const index = this._listenerMap[key] =
|
|
14543
|
+
const index = this._listenerMap[key] =
|
|
14544
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
14545
|
+
this._listenerMap[key] || this.state[eventName].length;
|
|
14447
14546
|
this.state[eventName][index] = func;
|
|
14448
14547
|
}
|
|
14449
14548
|
|
|
@@ -14456,6 +14555,7 @@ class MovablePoint$5 {
|
|
|
14456
14555
|
// TODO(benchristel): I don't think unlisten is used. Delete it?
|
|
14457
14556
|
// TODO(benchristel): unlisten is duplicated in movable.ts
|
|
14458
14557
|
unlisten(eventName, id) {
|
|
14558
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
14459
14559
|
this._listenerMap = this._listenerMap || {};
|
|
14460
14560
|
const key = getKey(eventName, id);
|
|
14461
14561
|
const index = this._listenerMap[key];
|
|
@@ -14514,6 +14614,7 @@ class MovablePoint$5 {
|
|
|
14514
14614
|
remove() {
|
|
14515
14615
|
this.state.added = false;
|
|
14516
14616
|
this._fireEvent(this.state.remove);
|
|
14617
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
14517
14618
|
if (this.movable) {
|
|
14518
14619
|
this.movable.remove();
|
|
14519
14620
|
}
|
|
@@ -14574,6 +14675,7 @@ class MovablePoint$5 {
|
|
|
14574
14675
|
// Change z-order to back
|
|
14575
14676
|
toBack() {
|
|
14576
14677
|
this.movable.toBack();
|
|
14678
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
14577
14679
|
if (this.state.visibleShape) {
|
|
14578
14680
|
this.state.visibleShape.toBack();
|
|
14579
14681
|
}
|
|
@@ -14581,12 +14683,13 @@ class MovablePoint$5 {
|
|
|
14581
14683
|
|
|
14582
14684
|
// Change z-order to front
|
|
14583
14685
|
toFront() {
|
|
14686
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
14584
14687
|
if (this.state.visibleShape) {
|
|
14585
14688
|
this.state.visibleShape.toFront();
|
|
14586
14689
|
}
|
|
14587
14690
|
this.movable.toFront();
|
|
14588
14691
|
}
|
|
14589
|
-
}
|
|
14692
|
+
};
|
|
14590
14693
|
MovablePoint$5.add = MovablePointOptions.add;
|
|
14591
14694
|
MovablePoint$5.modify = MovablePointOptions.modify;
|
|
14592
14695
|
MovablePoint$5.draw = MovablePointOptions.draw;
|
|
@@ -14604,6 +14707,10 @@ function getEventName(key) {
|
|
|
14604
14707
|
}
|
|
14605
14708
|
|
|
14606
14709
|
/* eslint-disable @babel/no-invalid-this */
|
|
14710
|
+
/**
|
|
14711
|
+
* A library of options to pass to add/draw/remove/constraints
|
|
14712
|
+
*/
|
|
14713
|
+
|
|
14607
14714
|
function sum(array) {
|
|
14608
14715
|
return _.reduce(array, function (memo, arg) {
|
|
14609
14716
|
return memo + arg;
|
|
@@ -15632,6 +15739,7 @@ class Graphie extends React.Component {
|
|
|
15632
15739
|
// corresponding with those descriptors.
|
|
15633
15740
|
renderChildren(child);
|
|
15634
15741
|
const prevMovable = oldMovables[key];
|
|
15742
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
15635
15743
|
if (!prevMovable) {
|
|
15636
15744
|
// We're creating a new child
|
|
15637
15745
|
child.add(graphie);
|
|
@@ -15866,6 +15974,7 @@ class ImageLoader extends React.Component {
|
|
|
15866
15974
|
case Status.LOADED:
|
|
15867
15975
|
return this.renderImg();
|
|
15868
15976
|
case Status.FAILED:
|
|
15977
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
15869
15978
|
if (this.props.children) {
|
|
15870
15979
|
return this.props.children;
|
|
15871
15980
|
}
|
|
@@ -16083,6 +16192,7 @@ class SvgImage extends React.Component {
|
|
|
16083
16192
|
}
|
|
16084
16193
|
loadResources() {
|
|
16085
16194
|
loadGraphie(this.props.src, (data, localized) => {
|
|
16195
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
16086
16196
|
if (this._isMounted && data.labels && data.range) {
|
|
16087
16197
|
const labelsRendered = {};
|
|
16088
16198
|
data.labels.forEach(label => {
|
|
@@ -16112,6 +16222,7 @@ class SvgImage extends React.Component {
|
|
|
16112
16222
|
return null;
|
|
16113
16223
|
}
|
|
16114
16224
|
// parseFloat() ignores trailing non-numerical characters.
|
|
16225
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
16115
16226
|
return parseFloat(value) || null;
|
|
16116
16227
|
}
|
|
16117
16228
|
render() {
|
|
@@ -16147,6 +16258,7 @@ class SvgImage extends React.Component {
|
|
|
16147
16258
|
// is tricky because web+graphie doesn't support labels on non-graphie
|
|
16148
16259
|
// images.
|
|
16149
16260
|
let extraGraphie;
|
|
16261
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
16150
16262
|
if (this.props.extraGraphie && this.props.extraGraphie.labels.length) {
|
|
16151
16263
|
extraGraphie = /*#__PURE__*/React.createElement(Graphie, {
|
|
16152
16264
|
box: this.props.extraGraphie.box,
|
|
@@ -16163,12 +16275,15 @@ class SvgImage extends React.Component {
|
|
|
16163
16275
|
// If preloader is undefined, we use the default. If it's
|
|
16164
16276
|
// null, there will be no preloader in use.
|
|
16165
16277
|
const preloaderBaseFunc = this.props.preloader === undefined ? defaultPreloader : this.props.preloader;
|
|
16278
|
+
|
|
16279
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
16166
16280
|
const preloader = preloaderBaseFunc ? () => preloaderBaseFunc(dimensions) : null;
|
|
16167
16281
|
|
|
16168
16282
|
// Just use a normal image if a normal image is provided
|
|
16169
16283
|
if (!Util.isLabeledSVG(imageSrc)) {
|
|
16170
16284
|
if (responsive) {
|
|
16171
16285
|
const wrapperClasses = classNames$1({
|
|
16286
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
16172
16287
|
zoomable: (width || 0) > ZOOMABLE_THRESHOLD,
|
|
16173
16288
|
"svg-image": true
|
|
16174
16289
|
});
|
|
@@ -16372,6 +16487,7 @@ class Zoomable extends React.Component {
|
|
|
16372
16487
|
}
|
|
16373
16488
|
componentWillUnmount() {
|
|
16374
16489
|
window.removeEventListener("resize", this.reset);
|
|
16490
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
16375
16491
|
if (this._observer) {
|
|
16376
16492
|
this._observer.disconnect();
|
|
16377
16493
|
}
|
|
@@ -16396,6 +16512,8 @@ class Zoomable extends React.Component {
|
|
|
16396
16512
|
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API
|
|
16397
16513
|
// eslint-disable-next-line no-restricted-syntax
|
|
16398
16514
|
setTimeout(() => this.measureAndScaleChildToFit(false), 0);
|
|
16515
|
+
|
|
16516
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
16399
16517
|
if (window.MutationObserver) {
|
|
16400
16518
|
this._observer = new MutationObserver(mutations => {
|
|
16401
16519
|
if (this._isMounted) {
|
|
@@ -16553,6 +16671,7 @@ Zoomable.defaultProps = {
|
|
|
16553
16671
|
* TeX we run into issues of measuring at the incorrect time resulting in bad
|
|
16554
16672
|
* measurements.
|
|
16555
16673
|
*/
|
|
16674
|
+
|
|
16556
16675
|
const computeMathBounds = (parentNode, parentBounds) => {
|
|
16557
16676
|
const textElement = parentNode.querySelector(".MathJax");
|
|
16558
16677
|
const textBounds = {
|
|
@@ -16602,6 +16721,7 @@ class ZoomableTeX extends React.Component {
|
|
|
16602
16721
|
/**
|
|
16603
16722
|
* A React context for ensuring there is one and only one definition showing at a time
|
|
16604
16723
|
*/
|
|
16724
|
+
|
|
16605
16725
|
const defaultContext$1 = {
|
|
16606
16726
|
activeDefinitionId: null,
|
|
16607
16727
|
setActiveDefinitionId: () => {}
|
|
@@ -16746,6 +16866,7 @@ class InteractionTracker {
|
|
|
16746
16866
|
/**
|
|
16747
16867
|
* Paragraph parsing/splitting for article jipt i18n
|
|
16748
16868
|
*/
|
|
16869
|
+
|
|
16749
16870
|
const arrayRules = {
|
|
16750
16871
|
fence: {
|
|
16751
16872
|
match: SimpleMarkdown.defaultRules.fence.match,
|
|
@@ -17448,6 +17569,8 @@ const getContent = ast => {
|
|
|
17448
17569
|
// arbitrarily nested lists that are direct properties.
|
|
17449
17570
|
// 2) Only AST nodes have a 'type' property.
|
|
17450
17571
|
const children = _.chain(ast).values().flatten().filter(object => object != null && _.has(object, "type")).value();
|
|
17572
|
+
|
|
17573
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17451
17574
|
if (!children.length) {
|
|
17452
17575
|
return [];
|
|
17453
17576
|
}
|
|
@@ -17584,6 +17707,7 @@ class TranslationLinter {
|
|
|
17584
17707
|
applyLintErrors(parsedMarkdown, translationLintErrors) {
|
|
17585
17708
|
// These lint errors do not have position data associated with
|
|
17586
17709
|
// them, so we just plop them at the top.
|
|
17710
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17587
17711
|
if (translationLintErrors.length) {
|
|
17588
17712
|
const errorText = translationLintErrors.join("\n\n");
|
|
17589
17713
|
parsedMarkdown.unshift({
|
|
@@ -17634,6 +17758,7 @@ const containerSizeClass = {
|
|
|
17634
17758
|
XLARGE: "xlarge"
|
|
17635
17759
|
};
|
|
17636
17760
|
const getClassFromWidth = width => {
|
|
17761
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17637
17762
|
if (!width) {
|
|
17638
17763
|
return containerSizeClass.MEDIUM;
|
|
17639
17764
|
}
|
|
@@ -17684,6 +17809,7 @@ const replaceWidget = (name, replacementName) => {
|
|
|
17684
17809
|
// If the replacement widget isn't found, we need to throw. Otherwise after
|
|
17685
17810
|
// removing the deprecated widget, we'll have data asking for a widget type
|
|
17686
17811
|
// that doesn't exist at all.
|
|
17812
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17687
17813
|
if (!substituteWidget) {
|
|
17688
17814
|
const errorMsg = `Failed to replace ${name} with ${replacementName}`;
|
|
17689
17815
|
throw new PerseusError(errorMsg, Errors.Internal);
|
|
@@ -17717,6 +17843,8 @@ const registerEditors = editorsToRegister => {
|
|
|
17717
17843
|
*/
|
|
17718
17844
|
const replaceEditor = (name, replacementName) => {
|
|
17719
17845
|
const substituteEditor = editors[replacementName];
|
|
17846
|
+
|
|
17847
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17720
17848
|
if (!substituteEditor && Log) {
|
|
17721
17849
|
const errorMsg = `Failed to replace editor ${name} with ${replacementName}`;
|
|
17722
17850
|
Log.error(errorMsg, Errors.Internal);
|
|
@@ -17759,6 +17887,7 @@ const getTransform = name => {
|
|
|
17759
17887
|
};
|
|
17760
17888
|
const getVersion = name => {
|
|
17761
17889
|
const widgetInfo = widgets[name];
|
|
17890
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17762
17891
|
if (widgetInfo) {
|
|
17763
17892
|
return widgets[name].version || {
|
|
17764
17893
|
major: 0,
|
|
@@ -17820,11 +17949,15 @@ const traverseChildWidgets$3 = (widgetInfo, traverseRenderer) => {
|
|
|
17820
17949
|
if (!traverseRenderer) {
|
|
17821
17950
|
throw new PerseusError("traverseRenderer must be provided, but was not", Errors.Internal);
|
|
17822
17951
|
}
|
|
17952
|
+
|
|
17953
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17823
17954
|
if (!widgetInfo || !widgetInfo.type || !widgets[widgetInfo.type]) {
|
|
17824
17955
|
return widgetInfo;
|
|
17825
17956
|
}
|
|
17826
17957
|
const widgetExports = widgets[widgetInfo.type];
|
|
17827
17958
|
const props = widgetInfo.options;
|
|
17959
|
+
|
|
17960
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17828
17961
|
if (widgetExports.traverseChildWidgets && props) {
|
|
17829
17962
|
const newProps = widgetExports.traverseChildWidgets(props, traverseRenderer);
|
|
17830
17963
|
return _.extend({}, widgetInfo, {
|
|
@@ -17845,6 +17978,7 @@ const traverseChildWidgets$3 = (widgetInfo, traverseRenderer) => {
|
|
|
17845
17978
|
*/
|
|
17846
17979
|
const supportsStaticMode = type => {
|
|
17847
17980
|
const widgetInfo = widgets[type];
|
|
17981
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17848
17982
|
return widgetInfo && widgetInfo.staticTransform != null;
|
|
17849
17983
|
};
|
|
17850
17984
|
|
|
@@ -17854,6 +17988,7 @@ const supportsStaticMode = type => {
|
|
|
17854
17988
|
*/
|
|
17855
17989
|
const getStaticTransform = type => {
|
|
17856
17990
|
const widgetInfo = widgets[type];
|
|
17991
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17857
17992
|
return widgetInfo && widgetInfo.staticTransform;
|
|
17858
17993
|
};
|
|
17859
17994
|
|
|
@@ -17864,6 +17999,7 @@ const getStaticTransform = type => {
|
|
|
17864
17999
|
*/
|
|
17865
18000
|
const getTracking = type => {
|
|
17866
18001
|
const widgetExport = widgets[type];
|
|
18002
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17867
18003
|
return widgetExport && widgetExport.tracking || DEFAULT_TRACKING;
|
|
17868
18004
|
};
|
|
17869
18005
|
|
|
@@ -17873,33 +18009,34 @@ const getTracking = type => {
|
|
|
17873
18009
|
*/
|
|
17874
18010
|
const isLintable = type => {
|
|
17875
18011
|
const widgetExports = widgets[type];
|
|
18012
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
17876
18013
|
return widgetExports && widgetExports.isLintable || DEFAULT_LINTABLE;
|
|
17877
18014
|
};
|
|
17878
18015
|
|
|
17879
18016
|
var widgets$1 = /*#__PURE__*/Object.freeze({
|
|
17880
18017
|
__proto__: null,
|
|
17881
|
-
|
|
17882
|
-
registerWidgets: registerWidgets,
|
|
17883
|
-
replaceWidget: replaceWidget,
|
|
17884
|
-
replaceDeprecatedWidgets: replaceDeprecatedWidgets,
|
|
17885
|
-
registerEditors: registerEditors,
|
|
17886
|
-
replaceEditor: replaceEditor,
|
|
17887
|
-
replaceDeprecatedEditors: replaceDeprecatedEditors,
|
|
17888
|
-
getWidget: getWidget,
|
|
17889
|
-
getWidgetExport: getWidgetExport,
|
|
18018
|
+
getAllWidgetTypes: getAllWidgetTypes,
|
|
17890
18019
|
getEditor: getEditor,
|
|
18020
|
+
getPublicWidgets: getPublicWidgets,
|
|
18021
|
+
getRendererPropsForWidgetInfo: getRendererPropsForWidgetInfo,
|
|
18022
|
+
getStaticTransform: getStaticTransform,
|
|
18023
|
+
getTracking: getTracking,
|
|
17891
18024
|
getTransform: getTransform,
|
|
17892
18025
|
getVersion: getVersion,
|
|
17893
18026
|
getVersionVector: getVersionVector,
|
|
17894
|
-
|
|
18027
|
+
getWidget: getWidget,
|
|
18028
|
+
getWidgetExport: getWidgetExport,
|
|
17895
18029
|
isAccessible: isAccessible,
|
|
17896
|
-
|
|
17897
|
-
|
|
17898
|
-
|
|
18030
|
+
isLintable: isLintable,
|
|
18031
|
+
registerEditors: registerEditors,
|
|
18032
|
+
registerWidget: registerWidget,
|
|
18033
|
+
registerWidgets: registerWidgets,
|
|
18034
|
+
replaceDeprecatedEditors: replaceDeprecatedEditors,
|
|
18035
|
+
replaceDeprecatedWidgets: replaceDeprecatedWidgets,
|
|
18036
|
+
replaceEditor: replaceEditor,
|
|
18037
|
+
replaceWidget: replaceWidget,
|
|
17899
18038
|
supportsStaticMode: supportsStaticMode,
|
|
17900
|
-
|
|
17901
|
-
getTracking: getTracking,
|
|
17902
|
-
isLintable: isLintable
|
|
18039
|
+
traverseChildWidgets: traverseChildWidgets$3
|
|
17903
18040
|
});
|
|
17904
18041
|
|
|
17905
18042
|
class WidgetContainer extends React.Component {
|
|
@@ -18549,6 +18686,8 @@ class Renderer extends React.Component {
|
|
|
18549
18686
|
const imagePlaceholder = apiOptions.imagePlaceholder;
|
|
18550
18687
|
if (node.type === "widget") {
|
|
18551
18688
|
const widgetPlaceholder = apiOptions.widgetPlaceholder;
|
|
18689
|
+
|
|
18690
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
18552
18691
|
if (widgetPlaceholder) {
|
|
18553
18692
|
return widgetPlaceholder;
|
|
18554
18693
|
}
|
|
@@ -18607,8 +18746,8 @@ class Renderer extends React.Component {
|
|
|
18607
18746
|
// TODO(kevinb) automatically determine the margin size
|
|
18608
18747
|
const margin = 16;
|
|
18609
18748
|
const outerStyle = {
|
|
18610
|
-
marginLeft: -
|
|
18611
|
-
marginRight: -
|
|
18749
|
+
marginLeft: -16,
|
|
18750
|
+
marginRight: -16
|
|
18612
18751
|
};
|
|
18613
18752
|
const horizontalPadding = {
|
|
18614
18753
|
paddingLeft: margin,
|
|
@@ -18656,6 +18795,7 @@ class Renderer extends React.Component {
|
|
|
18656
18795
|
}, tex)), /*#__PURE__*/React.createElement("span", null)));
|
|
18657
18796
|
}
|
|
18658
18797
|
if (node.type === "image") {
|
|
18798
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
18659
18799
|
if (imagePlaceholder) {
|
|
18660
18800
|
return imagePlaceholder;
|
|
18661
18801
|
}
|
|
@@ -18709,6 +18849,7 @@ class Renderer extends React.Component {
|
|
|
18709
18849
|
// Used by the translator portal to replace image URLs with
|
|
18710
18850
|
// placeholders, see preprocessWidgets in manticore-utils.js
|
|
18711
18851
|
// for more details.
|
|
18852
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
18712
18853
|
if (imagePlaceholder && rImageURL.test(node.content)) {
|
|
18713
18854
|
return imagePlaceholder;
|
|
18714
18855
|
}
|
|
@@ -18722,10 +18863,9 @@ class Renderer extends React.Component {
|
|
|
18722
18863
|
if (!apiOptions.isMobile) {
|
|
18723
18864
|
return output;
|
|
18724
18865
|
}
|
|
18725
|
-
const margin = 16;
|
|
18726
18866
|
const outerStyle = {
|
|
18727
|
-
marginLeft: -
|
|
18728
|
-
marginRight: -
|
|
18867
|
+
marginLeft: -16,
|
|
18868
|
+
marginRight: -16
|
|
18729
18869
|
};
|
|
18730
18870
|
const innerStyle = {
|
|
18731
18871
|
paddingLeft: 0,
|
|
@@ -18802,6 +18942,7 @@ class Renderer extends React.Component {
|
|
|
18802
18942
|
const widgetId = this.widgetIds[i];
|
|
18803
18943
|
const widget = this.getWidgetInstance(widgetId);
|
|
18804
18944
|
const widgetFocusResult = widget == null || widget.focus == null ? void 0 : widget.focus();
|
|
18945
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
18805
18946
|
if (widgetFocusResult) {
|
|
18806
18947
|
id = widgetId;
|
|
18807
18948
|
focusResult = widgetFocusResult;
|
|
@@ -18954,6 +19095,7 @@ class Renderer extends React.Component {
|
|
|
18954
19095
|
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API
|
|
18955
19096
|
// eslint-disable-next-line no-restricted-syntax
|
|
18956
19097
|
setTimeout(() => {
|
|
19098
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
18957
19099
|
const cbResult = cb && cb();
|
|
18958
19100
|
if (!silent) {
|
|
18959
19101
|
this.props.onInteractWithWidget(id);
|
|
@@ -19145,10 +19287,13 @@ class Renderer extends React.Component {
|
|
|
19145
19287
|
// mode (which is really just part of its widget info).
|
|
19146
19288
|
const widgetInfo = this.state.widgetInfo[widgetId];
|
|
19147
19289
|
const reviewModeRubric = this.props.reviewMode && widgetInfo ? widgetInfo.options : null;
|
|
19290
|
+
|
|
19291
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
19148
19292
|
if (!this._interactionTrackers) {
|
|
19149
19293
|
this._interactionTrackers = {};
|
|
19150
19294
|
}
|
|
19151
19295
|
let interactionTracker = this._interactionTrackers[widgetId];
|
|
19296
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
19152
19297
|
if (!interactionTracker) {
|
|
19153
19298
|
interactionTracker = this._interactionTrackers[widgetId] = new InteractionTracker(apiOptions.trackInteraction, widgetInfo && widgetInfo.type, widgetId, getTracking(widgetInfo && widgetInfo.type));
|
|
19154
19299
|
}
|
|
@@ -19269,6 +19414,7 @@ class Renderer extends React.Component {
|
|
|
19269
19414
|
// before jipt has a chance to replace its contents, so this check
|
|
19270
19415
|
// will keep us from adding the component to the registry a second
|
|
19271
19416
|
// time.
|
|
19417
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
19272
19418
|
if (!this.translationIndex) {
|
|
19273
19419
|
this.translationIndex = getDependencies().rendererTranslationComponents.addComponent(this);
|
|
19274
19420
|
}
|
|
@@ -20026,6 +20172,7 @@ var NumericInput$1 = {
|
|
|
20026
20172
|
};
|
|
20027
20173
|
|
|
20028
20174
|
const getPromptJSON$q = (renderProps, userInput) => {
|
|
20175
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
20029
20176
|
const choices = renderProps.choices || [];
|
|
20030
20177
|
const options = choices.map(choice => {
|
|
20031
20178
|
return {
|
|
@@ -20303,6 +20450,7 @@ function findFirstAndLastWordIndexes(selectionRange, wordRanges) {
|
|
|
20303
20450
|
/**
|
|
20304
20451
|
* Utility functions for manipulating highlights.
|
|
20305
20452
|
*/
|
|
20453
|
+
|
|
20306
20454
|
/**
|
|
20307
20455
|
* Given a list of DOMHighlights, return a new list that also includes the
|
|
20308
20456
|
* given DOMRange as a new DOMHighlight. If the DOMHighlight intersects
|
|
@@ -20429,6 +20577,7 @@ function deserializeHighlight(serializedHighlight, wordRanges) {
|
|
|
20429
20577
|
lastWordIndex
|
|
20430
20578
|
} = serializedHighlight.range;
|
|
20431
20579
|
const firstWord = wordRanges[firstWordIndex];
|
|
20580
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
20432
20581
|
if (!firstWord) {
|
|
20433
20582
|
throw new PerseusError(`first word index ${firstWord} is out of bounds: ` + `must be 0–${wordRanges.length - 1} inclusive`, Errors.InvalidInput, {
|
|
20434
20583
|
metadata: {
|
|
@@ -20438,6 +20587,7 @@ function deserializeHighlight(serializedHighlight, wordRanges) {
|
|
|
20438
20587
|
});
|
|
20439
20588
|
}
|
|
20440
20589
|
const lastWord = wordRanges[lastWordIndex];
|
|
20590
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
20441
20591
|
if (!lastWord) {
|
|
20442
20592
|
throw new PerseusError(`last word index ${lastWord} is out of bounds: ` + `must be 0–${wordRanges.length - 1} inclusive`, Errors.InvalidInput, {
|
|
20443
20593
|
metadata: {
|
|
@@ -20611,6 +20761,17 @@ function addClientRectsForText(textNode, textRange, mutableRects) {
|
|
|
20611
20761
|
}
|
|
20612
20762
|
|
|
20613
20763
|
/* eslint-disable react/no-unsafe */
|
|
20764
|
+
/**
|
|
20765
|
+
* This component, given a single DOMHighlight, draws highlight rectangles in
|
|
20766
|
+
* the same absolute position as the highlighted content, as computed via
|
|
20767
|
+
* `getClientRects`.
|
|
20768
|
+
*
|
|
20769
|
+
* TODO(mdr): Many things can affect the correct positioning of highlighting,
|
|
20770
|
+
* and this component does not attempt to anticipate them. If we start
|
|
20771
|
+
* using this highlighting library on content with a more dynamic layout,
|
|
20772
|
+
* we should add a hook to allow the parent to `forceUpdate` the
|
|
20773
|
+
* `HighlightRenderer`.
|
|
20774
|
+
*/
|
|
20614
20775
|
class HighlightRenderer extends React.PureComponent {
|
|
20615
20776
|
constructor(...args) {
|
|
20616
20777
|
super(...args);
|
|
@@ -20766,6 +20927,7 @@ class HighlightTooltip extends React.PureComponent {
|
|
|
20766
20927
|
// but let's catch that case and bail out.
|
|
20767
20928
|
// TODO(mdr): Instead, we should somehow walk back the range until we
|
|
20768
20929
|
// find an appropriate position for the tooltip. Sounds tricky!
|
|
20930
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
20769
20931
|
if (!focusRect) {
|
|
20770
20932
|
Log.log("[Highlighting] Known bug: Could not determine the focus " + 'position, so did not show an "Add Highlight" tooltip. ' + "https://app.asana.com/0/329800276300868/413878480039713 " + "(see also /r/asana-links)");
|
|
20771
20933
|
return null;
|
|
@@ -20840,6 +21002,14 @@ const styles$x = StyleSheet.create({
|
|
|
20840
21002
|
});
|
|
20841
21003
|
|
|
20842
21004
|
/* eslint-disable react/no-unsafe */
|
|
21005
|
+
/**
|
|
21006
|
+
* Render a set of highlights. See HighlightRenderer for more details about how
|
|
21007
|
+
* each highlight is rendered.
|
|
21008
|
+
*
|
|
21009
|
+
* This component manages the state of the "Remove highlight" tooltip. To
|
|
21010
|
+
* determine the currently-hovered highlight, it calls the `isHovered` method
|
|
21011
|
+
* on each HighlightRenderer.
|
|
21012
|
+
*/
|
|
20843
21013
|
class HighlightSetRenderer extends React.PureComponent {
|
|
20844
21014
|
constructor(...args) {
|
|
20845
21015
|
super(...args);
|
|
@@ -20919,7 +21089,10 @@ class HighlightSetRenderer extends React.PureComponent {
|
|
|
20919
21089
|
const highlightKeys = Object.keys(this.props.highlights);
|
|
20920
21090
|
return highlightKeys.find(key => {
|
|
20921
21091
|
const highlightRenderer = this._highlightRenderers[key];
|
|
20922
|
-
return
|
|
21092
|
+
return (
|
|
21093
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
21094
|
+
highlightRenderer && highlightRenderer.isHovered(mouseClientPosition)
|
|
21095
|
+
);
|
|
20923
21096
|
});
|
|
20924
21097
|
}
|
|
20925
21098
|
_renderTooltip() {
|
|
@@ -20964,6 +21137,10 @@ class HighlightSetRenderer extends React.PureComponent {
|
|
|
20964
21137
|
HighlightSetRenderer.contextType = PerseusI18nContext;
|
|
20965
21138
|
|
|
20966
21139
|
/* eslint-disable react/no-unsafe */
|
|
21140
|
+
/**
|
|
21141
|
+
* Tracks the user's current selection, and exposes it to the subtree using the
|
|
21142
|
+
* function-as-children pattern.
|
|
21143
|
+
*/
|
|
20967
21144
|
class SelectionTracker extends React.PureComponent {
|
|
20968
21145
|
constructor(...args) {
|
|
20969
21146
|
super(...args);
|
|
@@ -21185,6 +21362,7 @@ HighlightingUI.contextType = PerseusI18nContext;
|
|
|
21185
21362
|
* The words yielded by WordIndexer are sorted in document order, which makes
|
|
21186
21363
|
* them amenable to binary search - see `findBoundaryWordIndex` in ranges.js.
|
|
21187
21364
|
*/
|
|
21365
|
+
|
|
21188
21366
|
class WordIndexer extends React.PureComponent {
|
|
21189
21367
|
constructor(...args) {
|
|
21190
21368
|
super(...args);
|
|
@@ -21253,6 +21431,7 @@ class WordIndexer extends React.PureComponent {
|
|
|
21253
21431
|
const startOffset = wordMatch.index;
|
|
21254
21432
|
const endOffset = wordMatch.index + wordMatch[0].length;
|
|
21255
21433
|
let range;
|
|
21434
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
21256
21435
|
if (startOffset === 0 && trailingWordRange) {
|
|
21257
21436
|
// This word is at the start of this text node, and
|
|
21258
21437
|
// there's a trailing word from the previous text node,
|
|
@@ -21815,6 +21994,7 @@ var PassageMarkdown = {
|
|
|
21815
21994
|
getInitialParseState
|
|
21816
21995
|
};
|
|
21817
21996
|
|
|
21997
|
+
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
|
|
21818
21998
|
// A fake paragraph to measure the line height of the passage,
|
|
21819
21999
|
// so we can adapt to browser zoom
|
|
21820
22000
|
class LineHeightMeasurer extends React.Component {
|
|
@@ -21999,6 +22179,7 @@ class Passage extends React.Component {
|
|
|
21999
22179
|
_getStartRefLineNumber(referenceNumber) {
|
|
22000
22180
|
const refRef = PassageMarkdown.START_REF_PREFIX + referenceNumber;
|
|
22001
22181
|
const ref = this.refs[refRef];
|
|
22182
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
22002
22183
|
if (!ref) {
|
|
22003
22184
|
return null;
|
|
22004
22185
|
}
|
|
@@ -22020,6 +22201,7 @@ class Passage extends React.Component {
|
|
|
22020
22201
|
_getEndRefLineNumber(referenceNumber) {
|
|
22021
22202
|
const refRef = PassageMarkdown.END_REF_PREFIX + referenceNumber;
|
|
22022
22203
|
const ref = this.refs[refRef];
|
|
22204
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
22023
22205
|
if (!ref) {
|
|
22024
22206
|
return null;
|
|
22025
22207
|
}
|
|
@@ -22060,6 +22242,7 @@ class Passage extends React.Component {
|
|
|
22060
22242
|
_getRefContent(referenceNumber) {
|
|
22061
22243
|
const refRef = PassageMarkdown.START_REF_PREFIX + referenceNumber;
|
|
22062
22244
|
const ref = this.refs[refRef];
|
|
22245
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
22063
22246
|
if (!ref) {
|
|
22064
22247
|
return null;
|
|
22065
22248
|
}
|
|
@@ -22379,6 +22562,7 @@ var PassageRef$1 = {
|
|
|
22379
22562
|
* },
|
|
22380
22563
|
* });
|
|
22381
22564
|
*/
|
|
22565
|
+
|
|
22382
22566
|
const {
|
|
22383
22567
|
pureXsMax,
|
|
22384
22568
|
pureSmMin,
|
|
@@ -22410,6 +22594,7 @@ var mediaQueries = {
|
|
|
22410
22594
|
*/
|
|
22411
22595
|
|
|
22412
22596
|
// Polyfill scrollTo if it doesn't exist
|
|
22597
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
22413
22598
|
if (typeof HTMLElement !== "undefined" && !HTMLElement.prototype.scrollTo) {
|
|
22414
22599
|
// @ts-expect-error - TS2322 - Type '(left: number, top: any) => void' is not assignable to type '{ (options?: ScrollToOptions | undefined): void; (x: number, y: number): void; }'.
|
|
22415
22600
|
HTMLElement.prototype.scrollTo = function (left, top) {
|
|
@@ -22469,7 +22654,6 @@ const scrollElementToOffset = (elementOrWindow, offset, duration = 0, callback)
|
|
|
22469
22654
|
// TODO(jeff, WEB-1378): Use Wonder Blocks Timing API
|
|
22470
22655
|
// eslint-disable-next-line no-restricted-syntax
|
|
22471
22656
|
clearInterval(scrollInterval);
|
|
22472
|
-
callback == null || callback();
|
|
22473
22657
|
}
|
|
22474
22658
|
}, tickLength);
|
|
22475
22659
|
};
|
|
@@ -22528,11 +22712,12 @@ const scrollElementIntoView = (element, callback) => {
|
|
|
22528
22712
|
const distanceToScroll = childBounds.top - containerBounds.top;
|
|
22529
22713
|
offset = currentScrollTop + distanceToScroll;
|
|
22530
22714
|
}
|
|
22531
|
-
scrollElementToOffset(scrollContainer, offset, SCROLL_ANIMATION_DURATION
|
|
22715
|
+
scrollElementToOffset(scrollContainer, offset, SCROLL_ANIMATION_DURATION);
|
|
22532
22716
|
}, 0);
|
|
22533
22717
|
};
|
|
22534
22718
|
|
|
22535
22719
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
22720
|
+
|
|
22536
22721
|
// WARNING: This determines the *viewport* width and height, so a change here
|
|
22537
22722
|
// requires scaling the values of every SVG path passed in as a string
|
|
22538
22723
|
// without corresponding `width` and `height` values.
|
|
@@ -22692,6 +22877,7 @@ function getA11yText(letter, checked, correct, crossedOut, showCorrectness, stri
|
|
|
22692
22877
|
/**
|
|
22693
22878
|
* Renders a circular selection ring around the child.
|
|
22694
22879
|
*/
|
|
22880
|
+
|
|
22695
22881
|
const FocusRing = function FocusRing({
|
|
22696
22882
|
visible = true,
|
|
22697
22883
|
color = kaGreen,
|
|
@@ -22746,6 +22932,7 @@ const styles$t = StyleSheet.create({
|
|
|
22746
22932
|
|
|
22747
22933
|
/* Component for rendering a letter icon in radio choice */
|
|
22748
22934
|
|
|
22935
|
+
|
|
22749
22936
|
// The "cross-out line" SVG is a bit bigger than the choice icon, to provide
|
|
22750
22937
|
// extra space for the cute rounded line cap.
|
|
22751
22938
|
const CROSS_OUT_LINE_PADDING = 2;
|
|
@@ -22949,6 +23136,7 @@ const styles$r = StyleSheet.create({
|
|
|
22949
23136
|
* ChoiceIcon visualizations but is meant to make the distinctions
|
|
22950
23137
|
* between the states more immediately clear to users.
|
|
22951
23138
|
*/
|
|
23139
|
+
|
|
22952
23140
|
function renderText(checked, correct, crossedOut, strings) {
|
|
22953
23141
|
if (correct) {
|
|
22954
23142
|
// For correct answers, we surface checked _or_ crossedOut state,
|
|
@@ -23300,6 +23488,7 @@ function getInstructionsText(multipleSelect, countChoices, numCorrect, strings)
|
|
|
23300
23488
|
if (multipleSelect) {
|
|
23301
23489
|
// using usesNumCorrect to make sure this logic stays in sync
|
|
23302
23490
|
// with getRadioPublicWidgetOptions logic
|
|
23491
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
23303
23492
|
if (usesNumCorrect(multipleSelect, !!countChoices, numCorrect)) {
|
|
23304
23493
|
return strings.chooseNumAnswers({
|
|
23305
23494
|
numCorrect: String(numCorrect)
|
|
@@ -23344,7 +23533,9 @@ const BaseRadio = function BaseRadio({
|
|
|
23344
23533
|
// the most recently used widget (because, if the user has since
|
|
23345
23534
|
// touched something else, they're probably not trying to keep their
|
|
23346
23535
|
// eye on this widget anymore).
|
|
23347
|
-
if (apiOptions.canScrollPage && isLastUsedWidget && reviewModeRubric &&
|
|
23536
|
+
if (apiOptions.canScrollPage && isLastUsedWidget && reviewModeRubric &&
|
|
23537
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
23538
|
+
!prevReviewModeRubric.current) {
|
|
23348
23539
|
const checkedIndex = choices.findIndex(c => c.checked);
|
|
23349
23540
|
if (checkedIndex >= 0) {
|
|
23350
23541
|
const ref = choiceRefs.current[checkedIndex];
|
|
@@ -23473,7 +23664,9 @@ const BaseRadio = function BaseRadio({
|
|
|
23473
23664
|
});
|
|
23474
23665
|
}
|
|
23475
23666
|
const nextChoice = choices[i + 1];
|
|
23476
|
-
const nextChoiceHighlighted =
|
|
23667
|
+
const nextChoiceHighlighted =
|
|
23668
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
23669
|
+
!!nextChoice && nextChoice.highlighted;
|
|
23477
23670
|
const aphroditeClassName = checked => {
|
|
23478
23671
|
// Whether or not to show correctness borders
|
|
23479
23672
|
// for this choice and the next choice.
|
|
@@ -23637,7 +23830,7 @@ const styles$o = StyleSheet.create({
|
|
|
23637
23830
|
|
|
23638
23831
|
// RenderProps is the return type for radio.jsx#transform
|
|
23639
23832
|
|
|
23640
|
-
|
|
23833
|
+
let Radio$1 = class Radio extends React.Component {
|
|
23641
23834
|
constructor(...args) {
|
|
23642
23835
|
super(...args);
|
|
23643
23836
|
// @ts-expect-error - TS2564 - Property 'focusFunction' has no initializer and is not definitely assigned in the constructor.
|
|
@@ -23834,6 +24027,7 @@ class Radio$1 extends React.Component {
|
|
|
23834
24027
|
// adding hints when editing.
|
|
23835
24028
|
// See: https://github.com/Khan/perseus/blame/e18582b4b69959270b90e237ef1813899711ddfa/src/widgets/radio.js#L169
|
|
23836
24029
|
focus(choiceIndex) {
|
|
24030
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
23837
24031
|
if (this.focusFunction) {
|
|
23838
24032
|
return this.focusFunction(choiceIndex);
|
|
23839
24033
|
}
|
|
@@ -23846,10 +24040,10 @@ class Radio$1 extends React.Component {
|
|
|
23846
24040
|
this.focusFunction = fun;
|
|
23847
24041
|
}
|
|
23848
24042
|
getUserInput() {
|
|
23849
|
-
return Radio
|
|
24043
|
+
return Radio.getUserInputFromProps(this.props);
|
|
23850
24044
|
}
|
|
23851
24045
|
getPromptJSON() {
|
|
23852
|
-
const userInput = Radio
|
|
24046
|
+
const userInput = Radio.getUserInputFromProps(this.props, false);
|
|
23853
24047
|
return getPromptJSON$q(this.props, userInput);
|
|
23854
24048
|
}
|
|
23855
24049
|
render() {
|
|
@@ -23963,7 +24157,7 @@ class Radio$1 extends React.Component {
|
|
|
23963
24157
|
registerFocusFunction: i => this.registerFocusFunction(i)
|
|
23964
24158
|
});
|
|
23965
24159
|
}
|
|
23966
|
-
}
|
|
24160
|
+
};
|
|
23967
24161
|
Radio$1.contextType = PerseusI18nContext;
|
|
23968
24162
|
Radio$1.defaultProps = {
|
|
23969
24163
|
choices: [],
|
|
@@ -23998,6 +24192,7 @@ const _choiceTransform = (widgetOptions, strings, problemNum) => {
|
|
|
23998
24192
|
});
|
|
23999
24193
|
|
|
24000
24194
|
// Place the "None of the above" options last
|
|
24195
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
24001
24196
|
if (noneOfTheAbove) {
|
|
24002
24197
|
newChoices.push(noneOfTheAbove);
|
|
24003
24198
|
}
|
|
@@ -24066,6 +24261,8 @@ var Radio = {
|
|
|
24066
24261
|
};
|
|
24067
24262
|
|
|
24068
24263
|
/* eslint-disable import/no-named-as-default */
|
|
24264
|
+
// As new widgets get added here, please also make sure they get added in
|
|
24265
|
+
// content_internal/perseus_traversal.py so they can be properly translated.
|
|
24069
24266
|
var basicWidgets = [Radio, InputNumber$1, NumericInput$1, Expression$1];
|
|
24070
24267
|
|
|
24071
24268
|
const {
|
|
@@ -24286,7 +24483,6 @@ Categorizer.defaultProps = {
|
|
|
24286
24483
|
values: [],
|
|
24287
24484
|
linterContext: linterContextDefault
|
|
24288
24485
|
};
|
|
24289
|
-
const pageMargin = 16;
|
|
24290
24486
|
|
|
24291
24487
|
// Stylesheets aren't directly testable
|
|
24292
24488
|
/* c8 ignore next */
|
|
@@ -24298,8 +24494,8 @@ const styles$n = StyleSheet.create({
|
|
|
24298
24494
|
},
|
|
24299
24495
|
fullBleedContainer: {
|
|
24300
24496
|
[mediaQueries.mdOrSmaller]: {
|
|
24301
|
-
marginLeft: -
|
|
24302
|
-
marginRight: -
|
|
24497
|
+
marginLeft: -16,
|
|
24498
|
+
marginRight: -16,
|
|
24303
24499
|
overflowX: "auto"
|
|
24304
24500
|
}
|
|
24305
24501
|
},
|
|
@@ -24373,6 +24569,7 @@ const location = () => {
|
|
|
24373
24569
|
* We cache the result to ensure that on subsequent requests we always get
|
|
24374
24570
|
* the first URL that was used to initially render the page.
|
|
24375
24571
|
*/
|
|
24572
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
24376
24573
|
if (!_cachedClientLocation) {
|
|
24377
24574
|
// eslint-disable-next-line no-restricted-syntax
|
|
24378
24575
|
_cachedClientLocation = window.location;
|
|
@@ -24410,6 +24607,7 @@ const getPromptJSON$m = () => {
|
|
|
24410
24607
|
/**
|
|
24411
24608
|
* This widget is for embedding Khan Academy CS programs.
|
|
24412
24609
|
*/
|
|
24610
|
+
|
|
24413
24611
|
const {
|
|
24414
24612
|
updateQueryString: updateQueryString$1
|
|
24415
24613
|
} = Util;
|
|
@@ -24503,6 +24701,7 @@ class CSProgram extends React.Component {
|
|
|
24503
24701
|
}
|
|
24504
24702
|
|
|
24505
24703
|
// Turn array of [{name: "", value: ""}] into object
|
|
24704
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
24506
24705
|
if (this.props.settings) {
|
|
24507
24706
|
const settings = {};
|
|
24508
24707
|
_.each(this.props.settings, function (setting) {
|
|
@@ -24900,7 +25099,7 @@ const styles$k = StyleSheet.create({
|
|
|
24900
25099
|
borderLeftWidth: "5px",
|
|
24901
25100
|
gridTemplateColumns: "1fr",
|
|
24902
25101
|
gridTemplateRows: "1fr",
|
|
24903
|
-
marginLeft: -
|
|
25102
|
+
marginLeft: -23,
|
|
24904
25103
|
minWidth: "100%",
|
|
24905
25104
|
paddingLeft: leftBorderSpacing,
|
|
24906
25105
|
paddingBottom: verticalContentPadding,
|
|
@@ -25489,6 +25688,8 @@ class GradedGroupSet extends React.Component {
|
|
|
25489
25688
|
}));
|
|
25490
25689
|
}
|
|
25491
25690
|
const currentGroup = this.props.gradedGroups[this.state.currentGroup];
|
|
25691
|
+
|
|
25692
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
25492
25693
|
if (!currentGroup) {
|
|
25493
25694
|
return /*#__PURE__*/React.createElement("span", null, "No current group...");
|
|
25494
25695
|
}
|
|
@@ -25650,7 +25851,9 @@ class ButtonGroup extends React.Component {
|
|
|
25650
25851
|
key: "" + i,
|
|
25651
25852
|
className: css(styles$g.buttonStyle, button.value === value && styles$g.selectedStyle),
|
|
25652
25853
|
onClick: () => this.toggleSelect(button.value)
|
|
25653
|
-
},
|
|
25854
|
+
},
|
|
25855
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
25856
|
+
button.content || "" + button.value);
|
|
25654
25857
|
});
|
|
25655
25858
|
const outerStyle = {
|
|
25656
25859
|
display: "inline-block"
|
|
@@ -25907,10 +26110,11 @@ class FunctionGrapher extends React.Component {
|
|
|
25907
26110
|
const model = this.props.model;
|
|
25908
26111
|
const graph = this.props.graph;
|
|
25909
26112
|
const asymptote = this._asymptote();
|
|
26113
|
+
const showAsymptote = (asymptote == null ? void 0 : asymptote.length) > 0;
|
|
25910
26114
|
const dashed = {
|
|
25911
26115
|
strokeDasharray: "- "
|
|
25912
26116
|
};
|
|
25913
|
-
return
|
|
26117
|
+
return showAsymptote && /*#__PURE__*/React.createElement(MovableLine$2, {
|
|
25914
26118
|
onMove: (newCoord, oldCoord) => {
|
|
25915
26119
|
// Calculate and apply displacement
|
|
25916
26120
|
const delta = vector$3.subtract(newCoord, oldCoord);
|
|
@@ -26429,6 +26633,7 @@ const getPromptJSON$e = () => {
|
|
|
26429
26633
|
* It's particularly well suited for embedding our ProcessingJS programs,
|
|
26430
26634
|
* but could also be used for embedding viz's hosted elsewhere.
|
|
26431
26635
|
*/
|
|
26636
|
+
|
|
26432
26637
|
const {
|
|
26433
26638
|
updateQueryString
|
|
26434
26639
|
} = Util;
|
|
@@ -26493,6 +26698,7 @@ class Iframe extends React.Component {
|
|
|
26493
26698
|
let url = this.props.url;
|
|
26494
26699
|
|
|
26495
26700
|
// If the URL doesnt start with http, it must be a program ID
|
|
26701
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
26496
26702
|
if (url && url.length && url.indexOf("http") !== 0) {
|
|
26497
26703
|
url = "https://www.khanacademy.org/computer-programming/program/" + url + "/embedded?buttons=no&embed=yes&editor=no&author=no";
|
|
26498
26704
|
url = updateQueryString(url, "width", this.props.width);
|
|
@@ -26738,6 +26944,7 @@ var Image$1 = {
|
|
|
26738
26944
|
// has a background but no alt text, it is not accessible
|
|
26739
26945
|
accessible: widgetOptions => {
|
|
26740
26946
|
const bgImage = widgetOptions.backgroundImage;
|
|
26947
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
26741
26948
|
return !(bgImage && bgImage.url && !widgetOptions.alt);
|
|
26742
26949
|
},
|
|
26743
26950
|
displayName: "Image",
|
|
@@ -26750,6 +26957,7 @@ const getPromptJSON$c = () => {
|
|
|
26750
26957
|
};
|
|
26751
26958
|
|
|
26752
26959
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
26960
|
+
/* eslint-disable @babel/no-invalid-this, react/no-unsafe */
|
|
26753
26961
|
// @ts-expect-error - TS2339 - Property 'Label' does not exist on type 'typeof Graphie'.
|
|
26754
26962
|
const Label = Graphie.Label;
|
|
26755
26963
|
// @ts-expect-error - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
|
|
@@ -27919,9 +28127,6 @@ function AxisLabels({
|
|
|
27919
28127
|
height,
|
|
27920
28128
|
labelLocation
|
|
27921
28129
|
} = useGraphConfig();
|
|
27922
|
-
const {
|
|
27923
|
-
strings
|
|
27924
|
-
} = i18n;
|
|
27925
28130
|
const graphInfo = {
|
|
27926
28131
|
range,
|
|
27927
28132
|
width,
|
|
@@ -27941,7 +28146,11 @@ function AxisLabels({
|
|
|
27941
28146
|
TeX
|
|
27942
28147
|
} = getDependencies();
|
|
27943
28148
|
return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("span", {
|
|
27944
|
-
|
|
28149
|
+
// Reading the axis labels by themselves is mostly unhelpful
|
|
28150
|
+
// for screen reader users, so we should hide them to avoid
|
|
28151
|
+
// confusion. Instead, the axis labels should be included as
|
|
28152
|
+
// part of the graph description by content authors.
|
|
28153
|
+
"aria-hidden": true,
|
|
27945
28154
|
style: {
|
|
27946
28155
|
position: "absolute",
|
|
27947
28156
|
left: xAxisLabelLocation[X],
|
|
@@ -27950,7 +28159,11 @@ function AxisLabels({
|
|
|
27950
28159
|
transform: xLabelTransform
|
|
27951
28160
|
}
|
|
27952
28161
|
}, /*#__PURE__*/React__default.createElement(TeX, null, replaceOutsideTeX(xAxisLabelText))), /*#__PURE__*/React__default.createElement("span", {
|
|
27953
|
-
|
|
28162
|
+
// Reading the axis labels by themselves is mostly unhelpful
|
|
28163
|
+
// for screen reader users, so we should hide them to avoid
|
|
28164
|
+
// confusion. Instead, the axis labels should be included as
|
|
28165
|
+
// part of the graph description by content authors.
|
|
28166
|
+
"aria-hidden": true,
|
|
27954
28167
|
style: {
|
|
27955
28168
|
position: "absolute",
|
|
27956
28169
|
left: yAxisLabelLocation[X],
|
|
@@ -27986,8 +28199,8 @@ const getLabelPosition = (graphInfo, labelLocation) => {
|
|
|
27986
28199
|
// the labels do not overlap with the axis tick if they are out of the graph bounds.
|
|
27987
28200
|
const xAxisLabelOffset = graphInfo.range[Y][MIN] >= 0 ? [0, fontSize * 3] // Move the label down by 3 font sizes if the y-axis min is positive
|
|
27988
28201
|
: [0, fontSize]; // Move the label down by 1 font size if the y-axis min is negative
|
|
27989
|
-
const yAxisLabelOffset = graphInfo.range[X][MIN] >= 0 ? [-
|
|
27990
|
-
: [-
|
|
28202
|
+
const yAxisLabelOffset = graphInfo.range[X][MIN] >= 0 ? [-14 * 3, -14] // Move the label left by 3 font sizes if the x-axis min is positive
|
|
28203
|
+
: [-14, -14]; // Move the label left by 1 font size if the x-axis min is negative
|
|
27991
28204
|
|
|
27992
28205
|
// Calculate the location of the labels to be halfway between the min and max values of the axes
|
|
27993
28206
|
const xAxisLabelLocation = [(graphInfo.range[X][MIN] + graphInfo.range[X][MAX]) / 2, graphInfo.range[Y][MIN]];
|
|
@@ -28003,7 +28216,7 @@ const getLabelPosition = (graphInfo, labelLocation) => {
|
|
|
28003
28216
|
// place them at the end of the axis, which is the maximum value of the axis.
|
|
28004
28217
|
const xLabelInitial = [graphInfo.range[X][MAX], 0];
|
|
28005
28218
|
const yLabelInitial = [0, graphInfo.range[Y][MAX]];
|
|
28006
|
-
const yLabelOffset = [0, -
|
|
28219
|
+
const yLabelOffset = [0, -14 * 2]; // Move the y-axis label up by 2 font sizes
|
|
28007
28220
|
|
|
28008
28221
|
const xLabel = pointToPixel(xLabelInitial, graphInfo);
|
|
28009
28222
|
const yLabel = vec.add(pointToPixel(yLabelInitial, graphInfo), yLabelOffset);
|
|
@@ -28046,7 +28259,7 @@ const YGridTick = ({
|
|
|
28046
28259
|
|
|
28047
28260
|
// Adjust the y position of the x-axis labels based on
|
|
28048
28261
|
// whether the x-axis is above, within, or below the graph
|
|
28049
|
-
const xAdjustment = range[X][MAX] <= 0 ? tickLabelSize * 1.5 : -
|
|
28262
|
+
const xAdjustment = range[X][MAX] <= 0 ? tickLabelSize * 1.5 : -14 * 1.1;
|
|
28050
28263
|
const xPositionText = xPosition + xAdjustment;
|
|
28051
28264
|
const yPositionText = yPosition + tickLabelSize * 0.25; // Center the text vertically on the tick
|
|
28052
28265
|
|
|
@@ -28105,7 +28318,7 @@ const XGridTick = ({
|
|
|
28105
28318
|
|
|
28106
28319
|
// Adjust the Y position of the x-axis labels based on
|
|
28107
28320
|
// whether the x-axis is above, within, or below the graph
|
|
28108
|
-
const yAdjustment = range[Y][MAX] < 0 ? -
|
|
28321
|
+
const yAdjustment = range[Y][MAX] < 0 ? -14 : tickLabelSize * 1.75;
|
|
28109
28322
|
|
|
28110
28323
|
// Adjust the X position of the x-axis labels based on
|
|
28111
28324
|
// whether the label is positive or negative, in order to
|
|
@@ -28425,6 +28638,7 @@ const styles$e = StyleSheet.create({
|
|
|
28425
28638
|
* (RCSS generates classnames with a randomSuffix, which ensures that any
|
|
28426
28639
|
* two sets of generated classnames will not match.)
|
|
28427
28640
|
*/
|
|
28641
|
+
|
|
28428
28642
|
class InfoTip extends React.Component {
|
|
28429
28643
|
constructor(...args) {
|
|
28430
28644
|
super(...args);
|
|
@@ -29342,6 +29556,7 @@ function getAngleFromPoints(points, i) {
|
|
|
29342
29556
|
const point = points.at(i);
|
|
29343
29557
|
const pt1 = points.at(i - 1);
|
|
29344
29558
|
const pt2 = points[(i + 1) % points.length];
|
|
29559
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
29345
29560
|
if (!point || !pt1 || !pt2) {
|
|
29346
29561
|
return null;
|
|
29347
29562
|
}
|
|
@@ -30261,6 +30476,8 @@ function useDraggable(args) {
|
|
|
30261
30476
|
shiftKey
|
|
30262
30477
|
} = state;
|
|
30263
30478
|
const direction = [yDownDirection[X], -yDownDirection[Y]];
|
|
30479
|
+
|
|
30480
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
30264
30481
|
const span = Math.abs(direction[X]) ? xSpan : ySpan;
|
|
30265
30482
|
let divisions = 50;
|
|
30266
30483
|
if (altKey || metaKey) {
|
|
@@ -31808,6 +32025,7 @@ function initializeGraphState(params) {
|
|
|
31808
32025
|
case "polygon":
|
|
31809
32026
|
return _extends({}, shared, {
|
|
31810
32027
|
type: "polygon",
|
|
32028
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
31811
32029
|
numSides: graph.numSides || 0,
|
|
31812
32030
|
showAngles: Boolean(graph.showAngles),
|
|
31813
32031
|
showSides: Boolean(graph.showSides),
|
|
@@ -31823,6 +32041,7 @@ function initializeGraphState(params) {
|
|
|
31823
32041
|
return _extends({}, shared, {
|
|
31824
32042
|
type: graph.type,
|
|
31825
32043
|
coords: getPointCoords(graph, range, step),
|
|
32044
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
31826
32045
|
numPoints: graph.numPoints || 0,
|
|
31827
32046
|
focusedPointIndex: null,
|
|
31828
32047
|
showRemovePointButton: false,
|
|
@@ -31866,6 +32085,7 @@ function initializeGraphState(params) {
|
|
|
31866
32085
|
}
|
|
31867
32086
|
function getPointCoords(graph, range, step) {
|
|
31868
32087
|
var _graph$coords, _graph$startCoords;
|
|
32088
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
31869
32089
|
const numPoints = graph.numPoints || 1;
|
|
31870
32090
|
let coords = (_graph$coords = graph.coords) == null ? void 0 : _graph$coords.slice();
|
|
31871
32091
|
if (coords) {
|
|
@@ -31964,6 +32184,8 @@ function getPolygonCoords(graph, range, step) {
|
|
|
31964
32184
|
if (startCoords) {
|
|
31965
32185
|
return startCoords;
|
|
31966
32186
|
}
|
|
32187
|
+
|
|
32188
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
31967
32189
|
const n = graph.numSides || 3;
|
|
31968
32190
|
if (n === "unlimited") {
|
|
31969
32191
|
coords = [];
|
|
@@ -32012,6 +32234,8 @@ function getCircleCoords(graph) {
|
|
|
32012
32234
|
radiusPoint: vec.add(graph.center, [graph.radius, 0])
|
|
32013
32235
|
};
|
|
32014
32236
|
}
|
|
32237
|
+
|
|
32238
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
32015
32239
|
if ((_graph$startCoords3 = graph.startCoords) != null && _graph$startCoords3.center && graph.startCoords.radius) {
|
|
32016
32240
|
return {
|
|
32017
32241
|
center: graph.startCoords.center,
|
|
@@ -32278,6 +32502,7 @@ function doMoveLine(state, action) {
|
|
|
32278
32502
|
throw new Error("Please provide index of line to move");
|
|
32279
32503
|
}
|
|
32280
32504
|
const currentLine = state.coords[action.itemIndex];
|
|
32505
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
32281
32506
|
if (!currentLine) {
|
|
32282
32507
|
throw new Error("No line to move");
|
|
32283
32508
|
}
|
|
@@ -33070,6 +33295,7 @@ const LimitedPolygonGraph = statefulProps => {
|
|
|
33070
33295
|
}), points.map((point, i) => {
|
|
33071
33296
|
const pt1 = points.at(i - 1);
|
|
33072
33297
|
const pt2 = points[(i + 1) % points.length];
|
|
33298
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
33073
33299
|
if (!pt1 || !pt2) {
|
|
33074
33300
|
return null;
|
|
33075
33301
|
}
|
|
@@ -34409,7 +34635,9 @@ const MafsGraph = props => {
|
|
|
34409
34635
|
handleKeyboardEvent(event, state, dispatch);
|
|
34410
34636
|
},
|
|
34411
34637
|
"aria-label": fullGraphAriaLabel,
|
|
34412
|
-
"aria-describedby": describedByIds(fullGraphAriaDescription && descriptionId,
|
|
34638
|
+
"aria-describedby": describedByIds(fullGraphAriaDescription && descriptionId,
|
|
34639
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
34640
|
+
interactiveElementsDescription && interactiveElementsDescriptionId, isUnlimitedGraphState(state) && unlimitedGraphKeyboardPromptId, state.type !== "none" && !disableInteraction && instructionsId),
|
|
34413
34641
|
ref: graphRef,
|
|
34414
34642
|
tabIndex: 0,
|
|
34415
34643
|
onFocus: event => {
|
|
@@ -35067,6 +35295,7 @@ class InteractiveGraph extends React.Component {
|
|
|
35067
35295
|
* @param {object} props of an InteractiveGraph instance
|
|
35068
35296
|
*/
|
|
35069
35297
|
static getPointCoords(graph, props) {
|
|
35298
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
35070
35299
|
const numPoints = graph.numPoints || 1;
|
|
35071
35300
|
let coords = graph.coords;
|
|
35072
35301
|
if (coords) {
|
|
@@ -35131,6 +35360,8 @@ class InteractiveGraph extends React.Component {
|
|
|
35131
35360
|
if (coords) {
|
|
35132
35361
|
return coords;
|
|
35133
35362
|
}
|
|
35363
|
+
|
|
35364
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
35134
35365
|
const n = graph.numSides || 3;
|
|
35135
35366
|
if (n === UNLIMITED) {
|
|
35136
35367
|
coords = [];
|
|
@@ -35599,6 +35830,7 @@ function shouldReduceMotion() {
|
|
|
35599
35830
|
return true;
|
|
35600
35831
|
}
|
|
35601
35832
|
const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
35833
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
35602
35834
|
return !mediaQuery || mediaQuery.matches;
|
|
35603
35835
|
}
|
|
35604
35836
|
const MARKER_SIZE = 24;
|
|
@@ -36109,6 +36341,7 @@ class LabelImage extends React.Component {
|
|
|
36109
36341
|
// Compile the user selected answer choices.
|
|
36110
36342
|
const selected = choices.filter((_, index) => selection[index]);
|
|
36111
36343
|
this.handleMarkerChange(index, _extends({}, markers[index], {
|
|
36344
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
36112
36345
|
selected: selected.length ? selected : undefined
|
|
36113
36346
|
}));
|
|
36114
36347
|
}
|
|
@@ -36577,6 +36810,8 @@ class Draggable extends React.Component {
|
|
|
36577
36810
|
if (this.isMouseMoveUpBound) {
|
|
36578
36811
|
this.unbindMouseMoveUp();
|
|
36579
36812
|
}
|
|
36813
|
+
|
|
36814
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
36580
36815
|
if (this.animationFrameRequest) {
|
|
36581
36816
|
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
36582
36817
|
// eslint-disable-next-line no-restricted-syntax
|
|
@@ -36692,7 +36927,13 @@ class Sortable extends React.Component {
|
|
|
36692
36927
|
}
|
|
36693
36928
|
componentDidUpdate() {
|
|
36694
36929
|
// Measure items if their dimensions have been reset
|
|
36695
|
-
if (
|
|
36930
|
+
if (
|
|
36931
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
36932
|
+
this.state.items.length &&
|
|
36933
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
36934
|
+
!this.state.items[0].width &&
|
|
36935
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
36936
|
+
!this.state.items[0].height) {
|
|
36696
36937
|
// Measure on the next frame to allow items size to settle.
|
|
36697
36938
|
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
36698
36939
|
// eslint-disable-next-line no-restricted-syntax
|
|
@@ -36811,6 +37052,7 @@ class Sortable extends React.Component {
|
|
|
36811
37052
|
const item = _.findWhere(this.state.items, {
|
|
36812
37053
|
key: key
|
|
36813
37054
|
});
|
|
37055
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
36814
37056
|
const margin = this.props.margin || 0;
|
|
36815
37057
|
// @ts-expect-error - TS2345 - Argument of type 'SortableItem | undefined' is not assignable to parameter of type 'SortableItem'.
|
|
36816
37058
|
const currentIndex = _.indexOf(items, item);
|
|
@@ -37446,6 +37688,8 @@ class Matrix extends React.Component {
|
|
|
37446
37688
|
// @ts-expect-error - TS2322 - Type '0' is not assignable to type 'null'.
|
|
37447
37689
|
enterTheMatrix = 0;
|
|
37448
37690
|
}
|
|
37691
|
+
|
|
37692
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
37449
37693
|
if (nextPath) {
|
|
37450
37694
|
// Prevent the cursor from jumping again inside the next input
|
|
37451
37695
|
e.preventDefault();
|
|
@@ -37478,6 +37722,7 @@ class Matrix extends React.Component {
|
|
|
37478
37722
|
};
|
|
37479
37723
|
this.onValueChange = (row, column, value, cb) => {
|
|
37480
37724
|
const answers = this.props.answers.map(answer => [...answer]);
|
|
37725
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
37481
37726
|
if (!answers[row]) {
|
|
37482
37727
|
answers[row] = [];
|
|
37483
37728
|
}
|
|
@@ -37565,6 +37810,7 @@ class Matrix extends React.Component {
|
|
|
37565
37810
|
const inputProps = {
|
|
37566
37811
|
className: outside ? "outside" : "inside",
|
|
37567
37812
|
ref: getRefForPath$1(getInputPath$1(row, col)),
|
|
37813
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
37568
37814
|
value: rowVals ? rowVals[col] : null,
|
|
37569
37815
|
style: {
|
|
37570
37816
|
height: INPUT_HEIGHT,
|
|
@@ -38014,7 +38260,7 @@ const bondLength = 30;
|
|
|
38014
38260
|
function polarAdd(origin, angle, length) {
|
|
38015
38261
|
const x = origin[0];
|
|
38016
38262
|
const y = origin[1];
|
|
38017
|
-
return [x + Math.cos(angle * 2 * Math.PI / 360) * length, y + -1
|
|
38263
|
+
return [x + Math.cos(angle * 2 * Math.PI / 360) * length, y + -1 * Math.sin(angle * 2 * Math.PI / 360) * length];
|
|
38018
38264
|
}
|
|
38019
38265
|
|
|
38020
38266
|
/**
|
|
@@ -38298,14 +38544,7 @@ function layout$1(tree, rotationAngle) {
|
|
|
38298
38544
|
return bondLayoutHelper(outputs, atoms, bonds);
|
|
38299
38545
|
}
|
|
38300
38546
|
var MoleculeLayout = {
|
|
38301
|
-
layout: layout$1
|
|
38302
|
-
// The remainder are exported for testing and are not intended for external
|
|
38303
|
-
// use.
|
|
38304
|
-
_atomLayout: atomLayout,
|
|
38305
|
-
_bondLayout: bondLayout,
|
|
38306
|
-
_bondLength: bondLength,
|
|
38307
|
-
_convertTree: convertTree
|
|
38308
|
-
};
|
|
38547
|
+
layout: layout$1};
|
|
38309
38548
|
|
|
38310
38549
|
// Regexp defining characters that are valid SMILES characters that this parser
|
|
38311
38550
|
// can parse. In addition to serving as a sort of validation, this also keeps
|
|
@@ -38892,6 +39131,7 @@ class NumberLine extends React.Component {
|
|
|
38892
39131
|
numDivisions = numDivisions < 0 ? numDivisions * -1 : numDivisions;
|
|
38893
39132
|
|
|
38894
39133
|
// If the number of divisions isn't blank, update the number line
|
|
39134
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
38895
39135
|
if (numDivisions) {
|
|
38896
39136
|
const nextProps = _.extend({}, this.props, {
|
|
38897
39137
|
tickStep: width / numDivisions
|
|
@@ -39182,7 +39422,9 @@ class NumberLine extends React.Component {
|
|
|
39182
39422
|
// eslint-disable-next-line react/no-string-refs
|
|
39183
39423
|
, {
|
|
39184
39424
|
ref: "tick-ctrl",
|
|
39185
|
-
value: this.state.numDivisionsEmpty ? null :
|
|
39425
|
+
value: this.state.numDivisionsEmpty ? null :
|
|
39426
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
39427
|
+
this.props.numDivisions || divisionRange[0],
|
|
39186
39428
|
checkValidity: val => val >= divisionRange[0] && val <= divisionRange[1],
|
|
39187
39429
|
onChange: this.onNumDivisionsChange,
|
|
39188
39430
|
onFocus: this._handleTickCtrlFocus,
|
|
@@ -39886,6 +40128,7 @@ const getPromptJSON$4 = () => {
|
|
|
39886
40128
|
* This is a PhET simulation widget. It is used for rendering simulations
|
|
39887
40129
|
* from https://phet.colorado.edu/.
|
|
39888
40130
|
*/
|
|
40131
|
+
|
|
39889
40132
|
// This renders the PhET sim
|
|
39890
40133
|
class PhetSimulation extends React.Component {
|
|
39891
40134
|
constructor(props) {
|
|
@@ -39962,6 +40205,7 @@ class PhetSimulation extends React.Component {
|
|
|
39962
40205
|
}
|
|
39963
40206
|
async showLocaleWarning(url) {
|
|
39964
40207
|
// Do not show a locale warning on an invalid URL
|
|
40208
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
39965
40209
|
if (!url) {
|
|
39966
40210
|
return false;
|
|
39967
40211
|
}
|
|
@@ -40103,6 +40347,7 @@ class Plotter extends React.Component {
|
|
|
40103
40347
|
this.hairlineRange = void 0;
|
|
40104
40348
|
this.graphie = void 0;
|
|
40105
40349
|
this.state = {
|
|
40350
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
40106
40351
|
values: this.props.starting || [1],
|
|
40107
40352
|
// The measured rendered height of category strings. Used to calculate
|
|
40108
40353
|
// bottom padding of plot, to prevent categories from overlapping the
|
|
@@ -40199,6 +40444,8 @@ class Plotter extends React.Component {
|
|
|
40199
40444
|
// TODO(michaelpolyak): Handle other plot types: Dot, Histogram, Line.
|
|
40200
40445
|
if (isMobile && (isBar || isTiledPlot)) {
|
|
40201
40446
|
const maxCategoryHeight = Math.max(0, ...Object.values(self.state.categoryHeights));
|
|
40447
|
+
|
|
40448
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
40202
40449
|
if (maxCategoryHeight) {
|
|
40203
40450
|
// Account for bottom label position, height.
|
|
40204
40451
|
let offsetY = 25;
|
|
@@ -41283,6 +41530,7 @@ const getPromptJSON = () => {
|
|
|
41283
41530
|
/**
|
|
41284
41531
|
* This is a component that adds a link to the transcript for embedded videos in articles.
|
|
41285
41532
|
*/
|
|
41533
|
+
|
|
41286
41534
|
const IS_URL$1 = /^https?:\/\//;
|
|
41287
41535
|
const getYoutubeId = url => {
|
|
41288
41536
|
const regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
|
|
@@ -41349,6 +41597,7 @@ const styles$3 = StyleSheet.create({
|
|
|
41349
41597
|
/**
|
|
41350
41598
|
* This is a video widget for embedding videos in articles.
|
|
41351
41599
|
*/
|
|
41600
|
+
|
|
41352
41601
|
// Current default is 720p, based on the typical videos we upload currently
|
|
41353
41602
|
const DEFAULT_WIDTH = 1280;
|
|
41354
41603
|
const DEFAULT_HEIGHT = 720;
|
|
@@ -41437,6 +41686,9 @@ var Video$1 = {
|
|
|
41437
41686
|
};
|
|
41438
41687
|
|
|
41439
41688
|
/* eslint-disable import/no-named-as-default */
|
|
41689
|
+
// As new widgets get added here, please also make sure they get added in
|
|
41690
|
+
// content_internal/perseus_traversal.py so they can be properly translated.
|
|
41691
|
+
|
|
41440
41692
|
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, PhetSimulation$1, Plotter$1, PythonProgram$1, Sorter$1, Table$1, Video$1, DeprecatedStandin$1];
|
|
41441
41693
|
|
|
41442
41694
|
/**
|
|
@@ -41451,8 +41703,11 @@ const init = function init() {
|
|
|
41451
41703
|
};
|
|
41452
41704
|
|
|
41453
41705
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
41706
|
+
// version number during the release build.
|
|
41707
|
+
// In dev, you'll never see the version number.
|
|
41708
|
+
|
|
41454
41709
|
const libName = "@khanacademy/perseus";
|
|
41455
|
-
const libVersion = "
|
|
41710
|
+
const libVersion = "59.0.0";
|
|
41456
41711
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
41457
41712
|
|
|
41458
41713
|
const apiVersion = {
|
|
@@ -41515,7 +41770,9 @@ class ArticleRenderer extends React.Component {
|
|
|
41515
41770
|
// Wait for the keypad to mount before getting the height
|
|
41516
41771
|
setTimeout(() => {
|
|
41517
41772
|
const keypadDomNode = keypadElement == null ? void 0 : keypadElement.getDOMNode();
|
|
41518
|
-
const keypadHeight =
|
|
41773
|
+
const keypadHeight =
|
|
41774
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
41775
|
+
keypadDomNode && didFocusInput ? keypadDomNode.getBoundingClientRect().height : 0;
|
|
41519
41776
|
onFocusChange(this._currentFocus, prevFocusPath, keypadHeight, didFocusInput ? focusedInput : null);
|
|
41520
41777
|
}, 0);
|
|
41521
41778
|
}
|
|
@@ -41792,6 +42049,7 @@ class HintsRenderer extends React.Component {
|
|
|
41792
42049
|
let numCallbacks = 1;
|
|
41793
42050
|
const fireCallback = () => {
|
|
41794
42051
|
--numCallbacks;
|
|
42052
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
41795
42053
|
if (callback && numCallbacks === 0) {
|
|
41796
42054
|
callback();
|
|
41797
42055
|
}
|
|
@@ -41804,6 +42062,7 @@ class HintsRenderer extends React.Component {
|
|
|
41804
42062
|
// the state to an unmounted renderer, so...
|
|
41805
42063
|
// If you want to restore state to hints, make sure to
|
|
41806
42064
|
// have the appropriate number of hints visible already.
|
|
42065
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
41807
42066
|
if (hintRenderer) {
|
|
41808
42067
|
++numCallbacks;
|
|
41809
42068
|
// @ts-expect-error - TS2339 - Property 'restoreSerializedState' does not exist on type 'ReactInstance'.
|
|
@@ -41892,6 +42151,7 @@ class HintsRenderer extends React.Component {
|
|
|
41892
42151
|
onClick: evt => {
|
|
41893
42152
|
evt.preventDefault();
|
|
41894
42153
|
evt.stopPropagation();
|
|
42154
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
41895
42155
|
if (getAnotherHint) {
|
|
41896
42156
|
getAnotherHint();
|
|
41897
42157
|
}
|
|
@@ -42116,7 +42376,9 @@ class ServerItemRenderer extends React.Component {
|
|
|
42116
42376
|
setTimeout(() => {
|
|
42117
42377
|
// First, calculate the current keypad height
|
|
42118
42378
|
const keypadDomNode = keypadElement == null ? void 0 : keypadElement.getDOMNode();
|
|
42119
|
-
const keypadHeight =
|
|
42379
|
+
const keypadHeight =
|
|
42380
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
42381
|
+
keypadDomNode && didFocusInput ? keypadDomNode.getBoundingClientRect().height : 0;
|
|
42120
42382
|
|
|
42121
42383
|
// Then call the callback
|
|
42122
42384
|
onFocusChange(this._currentFocus, prevFocus, keypadHeight,
|
|
@@ -42368,6 +42630,7 @@ guess, state) {
|
|
|
42368
42630
|
* from that. We might eventually expose this, but I'd like to be
|
|
42369
42631
|
* more confident in the interface provided first.
|
|
42370
42632
|
*/
|
|
42633
|
+
|
|
42371
42634
|
const noop = function noop() {};
|
|
42372
42635
|
const deepCallbackFor = function deepCallbackFor(contentCallback, widgetCallback, optionsCallback) {
|
|
42373
42636
|
const deepCallback = function deepCallback(widgetInfo, widgetId) {
|
|
@@ -42456,6 +42719,7 @@ const traverse = function traverse(rendererOptions, contentCallback, widgetCallb
|
|
|
42456
42719
|
* This supports widgets that contain renderers, such as the
|
|
42457
42720
|
* group or sequence widgets.
|
|
42458
42721
|
*/
|
|
42722
|
+
|
|
42459
42723
|
const isUpgradedWidgetInfoRenderableBy = function isUpgradedWidgetInfoRenderableBy(widgetInfo, widgetRendererVersion) {
|
|
42460
42724
|
if (widgetRendererVersion == null) {
|
|
42461
42725
|
// If the widget does not exist in this version, this will
|
|
@@ -42509,6 +42773,7 @@ const isItemRenderableByVersion = function isItemRenderableByVersion(itemData, r
|
|
|
42509
42773
|
* or screen, based on the widgets it contains.
|
|
42510
42774
|
*/
|
|
42511
42775
|
|
|
42776
|
+
|
|
42512
42777
|
// Iterate over a single Perseus renderer, mutating `widgets` by appending
|
|
42513
42778
|
// violating widget types discovered in this item.
|
|
42514
42779
|
function traverseRenderer(itemData, widgets) {
|
|
@@ -43019,6 +43284,8 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43019
43284
|
keys(widgets).forEach(widgetID => {
|
|
43020
43285
|
var _options$choices, _categorizer$options, _categorizer$options2, _categorizer$options3, _dropdown$options, _numericInput$options, _inputNumber$options, _expression$options, _gradedGroup$options, _plotter$options, _plotter$options2, _grapher$options, _orderer$options, _sorter$options, _labelImage$options, _numberLine$options, _matrix$options, _matcher$options, _matcher$options2;
|
|
43021
43286
|
const widget = widgets[widgetID];
|
|
43287
|
+
|
|
43288
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43022
43289
|
if (!widget.options) {
|
|
43023
43290
|
return;
|
|
43024
43291
|
}
|
|
@@ -43027,6 +43294,7 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43027
43294
|
const radio = widget;
|
|
43028
43295
|
const options = radio.options;
|
|
43029
43296
|
// Answer is the content of the correct choice
|
|
43297
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43030
43298
|
if (options != null && (_options$choices = options.choices) != null && _options$choices.length) {
|
|
43031
43299
|
for (const choice of options.choices) {
|
|
43032
43300
|
if (choice != null && choice.correct) {
|
|
@@ -43039,7 +43307,11 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43039
43307
|
// Answer is a list of items mapped to their category
|
|
43040
43308
|
// e.g. ['item 1: category 1', 'item 2: category 2']
|
|
43041
43309
|
const categorizer = widget;
|
|
43042
|
-
if (
|
|
43310
|
+
if (
|
|
43311
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43312
|
+
(_categorizer$options = categorizer.options) != null && _categorizer$options.categories && // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43313
|
+
(_categorizer$options2 = categorizer.options) != null && _categorizer$options2.items && // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43314
|
+
(_categorizer$options3 = categorizer.options) != null && _categorizer$options3.values) {
|
|
43043
43315
|
var _categorizer$options4, _categorizer$options5, _categorizer$options6;
|
|
43044
43316
|
const categories = (_categorizer$options4 = categorizer.options) == null ? void 0 : _categorizer$options4.categories;
|
|
43045
43317
|
const items = (_categorizer$options5 = categorizer.options) == null ? void 0 : _categorizer$options5.items;
|
|
@@ -43050,6 +43322,7 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43050
43322
|
case "dropdown":
|
|
43051
43323
|
// Answer is the content of correct dropdown option
|
|
43052
43324
|
const dropdown = widget;
|
|
43325
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43053
43326
|
if ((_dropdown$options = dropdown.options) != null && _dropdown$options.choices) {
|
|
43054
43327
|
for (const choice of dropdown.options.choices) {
|
|
43055
43328
|
if (choice.correct) {
|
|
@@ -43061,6 +43334,7 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43061
43334
|
case "numeric-input":
|
|
43062
43335
|
// Answer is the numeric value cast to a string
|
|
43063
43336
|
const numericInput = widget;
|
|
43337
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43064
43338
|
if ((_numericInput$options = numericInput.options) != null && _numericInput$options.answers) {
|
|
43065
43339
|
for (const ans of numericInput.options.answers) {
|
|
43066
43340
|
if (ans.status === "correct" && ans.value != null) {
|
|
@@ -43072,6 +43346,7 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43072
43346
|
case "input-number":
|
|
43073
43347
|
// Answer is the correct value
|
|
43074
43348
|
const inputNumber = widget;
|
|
43349
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43075
43350
|
if ((_inputNumber$options = inputNumber.options) != null && _inputNumber$options.value) {
|
|
43076
43351
|
answers.push(inputNumber.options.value.toString());
|
|
43077
43352
|
}
|
|
@@ -43080,6 +43355,7 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43080
43355
|
// Answer is a list of potential correct expressions,
|
|
43081
43356
|
// since there can be multiple correct forms of the expression
|
|
43082
43357
|
const expression = widget;
|
|
43358
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43083
43359
|
if ((_expression$options = expression.options) != null && _expression$options.answerForms) {
|
|
43084
43360
|
answers.push(...expression.options.answerForms.map(answer => answer.value));
|
|
43085
43361
|
}
|
|
@@ -43090,6 +43366,7 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43090
43366
|
// call this function to get the nested answers from the
|
|
43091
43367
|
// group's widgets
|
|
43092
43368
|
const gradedGroup = widget;
|
|
43369
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43093
43370
|
if ((_gradedGroup$options = gradedGroup.options) != null && _gradedGroup$options.widgets) {
|
|
43094
43371
|
answers.push(...getAnswersFromWidgets(gradedGroup.options.widgets));
|
|
43095
43372
|
}
|
|
@@ -43099,7 +43376,10 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43099
43376
|
// e.g. '{Soccer: 35, Basketball: 20, Golf: 45, Volleyball: 15,
|
|
43100
43377
|
// Tennis: 30}'
|
|
43101
43378
|
const plotter = widget;
|
|
43102
|
-
if (
|
|
43379
|
+
if (
|
|
43380
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43381
|
+
(_plotter$options = plotter.options) != null && _plotter$options.categories && // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43382
|
+
(_plotter$options2 = plotter.options) != null && _plotter$options2.correct && plotter.options.categories.length === plotter.options.correct.length) {
|
|
43103
43383
|
const {
|
|
43104
43384
|
categories,
|
|
43105
43385
|
correct
|
|
@@ -43125,6 +43405,7 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43125
43405
|
// in the correct order on newlines
|
|
43126
43406
|
// E.g. 'item 1\nitem 2\nitem 3'
|
|
43127
43407
|
const orderer = widget;
|
|
43408
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43128
43409
|
if ((_orderer$options = orderer.options) != null && _orderer$options.correctOptions) {
|
|
43129
43410
|
answers.push(joinOptionContents(orderer.options.correctOptions));
|
|
43130
43411
|
}
|
|
@@ -43134,6 +43415,7 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43134
43415
|
// separated by commas
|
|
43135
43416
|
// E.g. 'item 1, item 2, item 3'
|
|
43136
43417
|
const sorter = widget;
|
|
43418
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43137
43419
|
if ((_sorter$options = sorter.options) != null && _sorter$options.correct) {
|
|
43138
43420
|
answers.push(sorter.options.correct.join(", "));
|
|
43139
43421
|
}
|
|
@@ -43142,6 +43424,7 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43142
43424
|
// Answer is a list of labels, their positions, and their answer
|
|
43143
43425
|
// E.g. '{label: "label 1", position: {x: 0.5, y: 0.5}, answer: "answer 1"}'
|
|
43144
43426
|
const labelImage = widget;
|
|
43427
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43145
43428
|
if ((_labelImage$options = labelImage.options) != null && _labelImage$options.markers) {
|
|
43146
43429
|
answers.push(...labelImage.options.markers.map(m => `{label: "${m.label}", position: {${m.x},${m.y}}, answer: "${m.answers.join(", ")}"}`));
|
|
43147
43430
|
}
|
|
@@ -43158,6 +43441,7 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43158
43441
|
// Answer is a list of rows representing the matrix
|
|
43159
43442
|
// E.g. '[[1, 2], [3, 4]]'
|
|
43160
43443
|
const matrix = widget;
|
|
43444
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43161
43445
|
if ((_matrix$options = matrix.options) != null && _matrix$options.answers) {
|
|
43162
43446
|
answers.push(`[${matrix.options.answers.join("], [")}]`);
|
|
43163
43447
|
}
|
|
@@ -43166,6 +43450,7 @@ function getAnswersFromWidgets(widgets) {
|
|
|
43166
43450
|
// Answer is a table of the left and right items
|
|
43167
43451
|
// E.g. '| Left | Right |\n| --- | --- |\n| left item 1 | right item 1 |\n| left item 2 | right item 2 |'
|
|
43168
43452
|
const matcher = widget;
|
|
43453
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43169
43454
|
if ((_matcher$options = matcher.options) != null && _matcher$options.left && (_matcher$options2 = matcher.options) != null && _matcher$options2.right) {
|
|
43170
43455
|
const {
|
|
43171
43456
|
left,
|
|
@@ -43224,6 +43509,7 @@ function injectWidgets(content, widgets, widgetProps) {
|
|
|
43224
43509
|
if (!content) {
|
|
43225
43510
|
return "";
|
|
43226
43511
|
}
|
|
43512
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43227
43513
|
if (!widgets) {
|
|
43228
43514
|
return content;
|
|
43229
43515
|
}
|
|
@@ -43231,6 +43517,8 @@ function injectWidgets(content, widgets, widgetProps) {
|
|
|
43231
43517
|
keys(widgets).forEach(widgetID => {
|
|
43232
43518
|
var _radio$options, _image$options, _labelImage$options2, _explanation$options, _passage$options, _passage$options2, _group$options, _gradedGroup$options2, _categorizer$options7, _dropdown$options2, _definition$options, _orderer$options2, _sorter$options2, _interactiveGraph$opt, _numberLine$options2, _numberLine$options3, _numberLine$options4, _matrix$options2, _matcher$options3, _matcher$options4;
|
|
43233
43519
|
const widget = widgets[widgetID];
|
|
43520
|
+
|
|
43521
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43234
43522
|
if (!widget.options) {
|
|
43235
43523
|
return;
|
|
43236
43524
|
}
|
|
@@ -43243,6 +43531,7 @@ function injectWidgets(content, widgets, widgetProps) {
|
|
|
43243
43531
|
// 'Option A: choice 1\nOption B: choice 2\nOption C: choice 3'
|
|
43244
43532
|
const radio = widget;
|
|
43245
43533
|
const radioProps = widgetProps == null ? void 0 : widgetProps[widgetID];
|
|
43534
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43246
43535
|
if ((_radio$options = radio.options) != null && (_radio$options = _radio$options.choices) != null && _radio$options.length) {
|
|
43247
43536
|
var _radio$options2;
|
|
43248
43537
|
let radioContext = joinOptionContents(radioProps ? radioProps.choices.map(({
|
|
@@ -43300,6 +43589,7 @@ function injectWidgets(content, widgets, widgetProps) {
|
|
|
43300
43589
|
// '[[☃ Group 1]]' -> 'Nested question\n[[☃ Radio 1]]'
|
|
43301
43590
|
// -> 'Nested question\noption 1\noption 2\noption 3'
|
|
43302
43591
|
const group = widget;
|
|
43592
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43303
43593
|
if ((_group$options = group.options) != null && _group$options.widgets && group.options.content) {
|
|
43304
43594
|
context = context.replace(`[[☃ ${widgetID}]]`, injectWidgets(group.options.content, group.options.widgets));
|
|
43305
43595
|
}
|
|
@@ -43309,9 +43599,11 @@ function injectWidgets(content, widgets, widgetProps) {
|
|
|
43309
43599
|
// '[[☃ Graded Group Set 1]]'
|
|
43310
43600
|
// -> 'Nested question 1\noption 1\noption 2\noption 3\nNested question 2\noption 1\noption 2\noption 3'
|
|
43311
43601
|
const gradedGroup = widget;
|
|
43602
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43312
43603
|
if ((_gradedGroup$options2 = gradedGroup.options) != null && _gradedGroup$options2.gradedGroups) {
|
|
43313
43604
|
const gradedGroups = gradedGroup.options.gradedGroups;
|
|
43314
43605
|
const gradedGroupsContent = gradedGroups.reduce((acc, group) => {
|
|
43606
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43315
43607
|
if (group.widgets && group.content) {
|
|
43316
43608
|
acc += injectWidgets(group.content, group.widgets) + "\n";
|
|
43317
43609
|
}
|
|
@@ -43329,7 +43621,11 @@ function injectWidgets(content, widgets, widgetProps) {
|
|
|
43329
43621
|
// item 2
|
|
43330
43622
|
// '''
|
|
43331
43623
|
const categorizer = widget;
|
|
43332
|
-
if (
|
|
43624
|
+
if (
|
|
43625
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43626
|
+
(_categorizer$options7 = categorizer.options) != null && _categorizer$options7.categories &&
|
|
43627
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43628
|
+
categorizer.options.items) {
|
|
43333
43629
|
const categories = categorizer.options.categories;
|
|
43334
43630
|
const items = categorizer.options.items;
|
|
43335
43631
|
context = context.replace(`[[☃ ${widgetID}]]`, `For each item, select the correct category. Categories: ${categories.join(", ")}.\nItems:\n${items.join("\n")}\n`);
|
|
@@ -43339,6 +43635,7 @@ function injectWidgets(content, widgets, widgetProps) {
|
|
|
43339
43635
|
// Replace dropdown with the dropdown options
|
|
43340
43636
|
// '[[☃ Dropdown 1]]' -> '[option 1 | option 2 | option 3]'
|
|
43341
43637
|
const dropdown = widget;
|
|
43638
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43342
43639
|
if ((_dropdown$options2 = dropdown.options) != null && _dropdown$options2.choices) {
|
|
43343
43640
|
const choices = dropdown.options.choices.map(choice => choice.content);
|
|
43344
43641
|
context = context.replace(`[[☃ ${widgetID}]]`, `[${choices.join(" | ")}]`);
|
|
@@ -43358,6 +43655,7 @@ function injectWidgets(content, widgets, widgetProps) {
|
|
|
43358
43655
|
// Replace orderer with the orderer options
|
|
43359
43656
|
// '[[☃ Orderer 1]]' -> 'option 1\noption 2\noption 3'
|
|
43360
43657
|
const orderer = widget;
|
|
43658
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43361
43659
|
if ((_orderer$options2 = orderer.options) != null && _orderer$options2.options) {
|
|
43362
43660
|
context = context.replace(`[[☃ ${widgetID}]]`, joinOptionContents(orderer.options.options));
|
|
43363
43661
|
}
|
|
@@ -43367,6 +43665,7 @@ function injectWidgets(content, widgets, widgetProps) {
|
|
|
43367
43665
|
// NOTE(chase): These are already in the correct order
|
|
43368
43666
|
// '[[☃ Sorter 1]]' -> '[option 1 | option 2 | option 3]'
|
|
43369
43667
|
const sorter = widget;
|
|
43668
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43370
43669
|
if ((_sorter$options2 = sorter.options) != null && _sorter$options2.correct) {
|
|
43371
43670
|
const choices = sorter.options.correct;
|
|
43372
43671
|
context = context.replace(`[[☃ ${widgetID}]]`, `[${choices.join(" | ")}]`);
|
|
@@ -43405,6 +43704,7 @@ function injectWidgets(content, widgets, widgetProps) {
|
|
|
43405
43704
|
// Replace matcher with a table representing the left and right columns
|
|
43406
43705
|
// '[[☃ Matcher 1]]' -> '| Left Column | Right Column |\n| --- | --- |\n| option 1 | option 2 |\n| option 3 | option 4 |'
|
|
43407
43706
|
const matcher = widget;
|
|
43707
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43408
43708
|
if ((_matcher$options3 = matcher.options) != null && _matcher$options3.left && (_matcher$options4 = matcher.options) != null && _matcher$options4.right) {
|
|
43409
43709
|
const {
|
|
43410
43710
|
left,
|
|
@@ -43447,12 +43747,14 @@ function injectWidgets(content, widgets, widgetProps) {
|
|
|
43447
43747
|
* @returns a stringified list of {widgetId, imageUrl} for imgs that don't have alt text
|
|
43448
43748
|
*/
|
|
43449
43749
|
function getImagesWithoutAltData(perseusRenderer) {
|
|
43750
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43450
43751
|
if (!perseusRenderer.widgets) {
|
|
43451
43752
|
return "";
|
|
43452
43753
|
}
|
|
43453
43754
|
const imgsWithoutAltData = [];
|
|
43454
43755
|
Object.entries(perseusRenderer.widgets).forEach(([widgetId, widget]) => {
|
|
43455
43756
|
var _widget$options$backg;
|
|
43757
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
43456
43758
|
if (!widget.options) {
|
|
43457
43759
|
return;
|
|
43458
43760
|
}
|
|
@@ -43727,6 +44029,7 @@ const EditorJsonify = {
|
|
|
43727
44029
|
/**
|
|
43728
44030
|
* Main entry point
|
|
43729
44031
|
*/
|
|
44032
|
+
|
|
43730
44033
|
const GrapherUtil = {
|
|
43731
44034
|
DEFAULT_GRAPHER_PROPS,
|
|
43732
44035
|
chooseType,
|