@khanacademy/perseus 39.0.1 → 41.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/components/hud.d.ts +4 -0
- package/dist/components/i18n-context.d.ts +4 -0
- package/dist/components/icon.d.ts +28 -27
- package/dist/components/image-loader.d.ts +9 -9
- package/dist/components/inline-icon.d.ts +6 -9
- package/dist/components/lint.d.ts +13 -0
- package/dist/components/math-input.d.ts +2 -2
- package/dist/components/multi-button-group.d.ts +26 -0
- package/dist/components/number-input.d.ts +19 -0
- package/dist/components/range-input.d.ts +3 -0
- package/dist/components/stub-tag-editor.d.ts +2 -2
- package/dist/components/svg-image.d.ts +30 -0
- package/dist/components/tooltip.d.ts +41 -30
- package/dist/es/index.css +6 -0
- package/dist/es/index.js +1502 -2183
- package/dist/es/index.js.map +1 -1
- package/dist/es/strings.js +16 -2
- package/dist/es/strings.js.map +1 -1
- package/dist/icon-paths.d.ts +1 -65
- package/dist/index.css +6 -0
- package/dist/index.d.ts +11 -6
- package/dist/index.js +1509 -2175
- package/dist/index.js.map +1 -1
- package/dist/strings.d.ts +8 -0
- package/dist/strings.js +22 -2
- package/dist/strings.js.map +1 -1
- package/dist/styles/global-styles.d.ts +2 -47
- package/dist/types.d.ts +5 -5
- package/dist/widgets/expression/expression.d.ts +4 -4
- package/dist/widgets/grapher/util.d.ts +0 -4
- package/dist/widgets/interactive-graphs/graphs/angle.d.ts +2 -5
- package/dist/widgets/interactive-graphs/graphs/circle.d.ts +2 -5
- package/dist/widgets/interactive-graphs/graphs/components/movable-point-view.d.ts +1 -11
- package/dist/widgets/interactive-graphs/graphs/components/movable-point.d.ts +2 -1
- package/dist/widgets/interactive-graphs/graphs/components/use-control-point.d.ts +23 -0
- package/dist/widgets/interactive-graphs/graphs/linear-system.d.ts +2 -5
- package/dist/widgets/interactive-graphs/graphs/linear.d.ts +2 -5
- package/dist/widgets/interactive-graphs/graphs/point.d.ts +7 -5
- package/dist/widgets/interactive-graphs/graphs/polygon.d.ts +2 -5
- package/dist/widgets/interactive-graphs/graphs/quadratic.d.ts +2 -4
- package/dist/widgets/interactive-graphs/graphs/ray.d.ts +2 -5
- package/dist/widgets/interactive-graphs/graphs/screenreader-text.d.ts +1 -0
- package/dist/widgets/interactive-graphs/graphs/segment.d.ts +2 -5
- package/dist/widgets/interactive-graphs/graphs/sinusoid.d.ts +2 -5
- package/dist/widgets/interactive-graphs/mafs-graph.d.ts +1 -2
- package/dist/widgets/interactive-graphs/reducer/interactive-graph-action.d.ts +5 -0
- package/dist/widgets/interactive-graphs/types.d.ts +13 -1
- package/dist/widgets/interactive-graphs/utils.d.ts +3 -0
- package/dist/widgets/label-image/label-image.d.ts +2 -2
- package/package.json +10 -9
- package/dist/components/constants.d.ts +0 -7
- package/dist/styles/global-constants.d.ts +0 -342
- package/dist/widgets/interactive-graphs/graphs/index.d.ts +0 -9
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ var wonderBlocksCore = require('@khanacademy/wonder-blocks-core');
|
|
|
9
9
|
var Tooltip$1 = require('@khanacademy/wonder-blocks-tooltip');
|
|
10
10
|
var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
|
|
11
11
|
var aphrodite = require('aphrodite');
|
|
12
|
-
var classNames = require('classnames');
|
|
12
|
+
var classNames$1 = require('classnames');
|
|
13
13
|
var React = require('react');
|
|
14
14
|
var ReactDOM = require('react-dom');
|
|
15
15
|
var _ = require('underscore');
|
|
@@ -67,7 +67,7 @@ function _interopNamespace(e) {
|
|
|
67
67
|
var KAS__namespace = /*#__PURE__*/_interopNamespace(KAS);
|
|
68
68
|
var PerseusLinter__namespace = /*#__PURE__*/_interopNamespace(PerseusLinter);
|
|
69
69
|
var Tooltip__default = /*#__PURE__*/_interopDefaultLegacy(Tooltip$1);
|
|
70
|
-
var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames);
|
|
70
|
+
var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames$1);
|
|
71
71
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
72
72
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
73
73
|
var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
|
|
@@ -367,7 +367,21 @@ const mockStrings = {
|
|
|
367
367
|
simulationLocaleWarning: "Sorry, this simulation isn't available in your language.",
|
|
368
368
|
addPoint: "Add Point",
|
|
369
369
|
removePoint: "Remove Point",
|
|
370
|
-
graphKeyboardPrompt: "Press Shift + Enter to interact with the graph"
|
|
370
|
+
graphKeyboardPrompt: "Press Shift + Enter to interact with the graph",
|
|
371
|
+
srPointAtCoordinates: _ref27 => {
|
|
372
|
+
let {
|
|
373
|
+
x,
|
|
374
|
+
y
|
|
375
|
+
} = _ref27;
|
|
376
|
+
return `Point at ${x} comma ${y}`;
|
|
377
|
+
},
|
|
378
|
+
srInteractiveElements: _ref28 => {
|
|
379
|
+
let {
|
|
380
|
+
elements
|
|
381
|
+
} = _ref28;
|
|
382
|
+
return `Interactive elements: ${elements}`;
|
|
383
|
+
},
|
|
384
|
+
srNoInteractiveElements: "No interactive elements"
|
|
371
385
|
};
|
|
372
386
|
|
|
373
387
|
/**
|
|
@@ -375,11 +389,13 @@ const mockStrings = {
|
|
|
375
389
|
* used inside the Perseus package.
|
|
376
390
|
*
|
|
377
391
|
*/
|
|
378
|
-
|
|
379
|
-
const PerseusI18nContext = /*#__PURE__*/React__namespace.createContext(process.env.NODE_ENV === "test" || process.env.STORYBOOK ? {
|
|
392
|
+
const mockPerseusI18nContext = {
|
|
380
393
|
strings: mockStrings,
|
|
381
394
|
locale: "en"
|
|
382
|
-
}
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
// @ts-expect-error - TS2322 - Type 'Context<{ strings: {}; locale: string; }>' is not assignable to type 'Context<I18nContextType>'.
|
|
398
|
+
const PerseusI18nContext = /*#__PURE__*/React__namespace.createContext(process.env.NODE_ENV === "test" || process.env.STORYBOOK ? mockPerseusI18nContext :
|
|
383
399
|
// We want to return null here, not an empty object, so that we
|
|
384
400
|
// are will throw an error when attempting to access the
|
|
385
401
|
// undefined locale or strings, making it easier to debug.
|
|
@@ -664,7 +680,7 @@ class InnerMathInput extends React__namespace.Component {
|
|
|
664
680
|
closeButtonVisible: true,
|
|
665
681
|
style: styles$E.popoverContent
|
|
666
682
|
}, /*#__PURE__*/React__namespace.createElement(mathInput.DesktopKeypad, _extends({
|
|
667
|
-
onAnalyticsEvent: this.props.
|
|
683
|
+
onAnalyticsEvent: this.props.onAnalyticsEvent,
|
|
668
684
|
extraKeys: this.props.extraKeys,
|
|
669
685
|
onClickKey: this.handleKeypadPress,
|
|
670
686
|
cursorContext: this.state.cursorContext,
|
|
@@ -827,6 +843,9 @@ const getDependencies = () => {
|
|
|
827
843
|
const DependenciesContext = /*#__PURE__*/React__namespace.createContext({
|
|
828
844
|
analytics: {
|
|
829
845
|
onAnalyticsEvent: async () => {}
|
|
846
|
+
},
|
|
847
|
+
useVideo: () => {
|
|
848
|
+
throw new Error("useVideo dependency not provided in Perseus dependencies");
|
|
830
849
|
}
|
|
831
850
|
});
|
|
832
851
|
|
|
@@ -967,7 +986,7 @@ function getTextWidth(text) {
|
|
|
967
986
|
class TextListEditor extends React__namespace.Component {
|
|
968
987
|
static propTypes = {
|
|
969
988
|
options: PropTypes__default["default"].array,
|
|
970
|
-
layout: PropTypes__default["default"].
|
|
989
|
+
layout: PropTypes__default["default"].oneOf(["horizontal", "vertical"]),
|
|
971
990
|
onChange: PropTypes__default["default"].func.isRequired
|
|
972
991
|
};
|
|
973
992
|
static defaultProps = {
|
|
@@ -1085,6 +1104,8 @@ class TextListEditor extends React__namespace.Component {
|
|
|
1085
1104
|
}
|
|
1086
1105
|
}
|
|
1087
1106
|
|
|
1107
|
+
const EMPTY_ARRAY = [];
|
|
1108
|
+
|
|
1088
1109
|
/**
|
|
1089
1110
|
* Stub Tag Editor.
|
|
1090
1111
|
*
|
|
@@ -1098,7 +1119,6 @@ class TextListEditor extends React__namespace.Component {
|
|
|
1098
1119
|
* It also gives a nicer interface for the group metadata editor
|
|
1099
1120
|
* in local demo mode.
|
|
1100
1121
|
*/
|
|
1101
|
-
const EMPTY_ARRAY = [];
|
|
1102
1122
|
class StubTagEditor extends React__namespace.Component {
|
|
1103
1123
|
static propTypes = {
|
|
1104
1124
|
value: PropTypes__default["default"].arrayOf(PropTypes__default["default"].string),
|
|
@@ -2607,9 +2627,7 @@ class Expression extends React__namespace.Component {
|
|
|
2607
2627
|
hasError: this.state.showErrorStyle,
|
|
2608
2628
|
ariaLabel: this.props.ariaLabel || this.context.strings.mathInputBox,
|
|
2609
2629
|
extraKeys: this.props.keypadConfiguration?.extraKeys,
|
|
2610
|
-
|
|
2611
|
-
onAnalyticsEvent: async () => {}
|
|
2612
|
-
}
|
|
2630
|
+
onAnalyticsEvent: this.props.analytics?.onAnalyticsEvent ?? (async () => {})
|
|
2613
2631
|
}))));
|
|
2614
2632
|
}
|
|
2615
2633
|
}
|
|
@@ -3999,12 +4017,12 @@ Zoom.prototype.dispose = function () {
|
|
|
3999
4017
|
const ZoomService = new ZoomServiceClass();
|
|
4000
4018
|
|
|
4001
4019
|
// @baseFontFamily: "Lato", sans-serif;
|
|
4002
|
-
const baseFontFamily
|
|
4020
|
+
const baseFontFamily = "'Lato', sans-serif";
|
|
4003
4021
|
// @boldFontFamily: "Lato-Bold", "Lato", sans-serif;
|
|
4004
4022
|
const boldFontFamily = "'Lato-Bold', 'Lato', sans-serif";
|
|
4005
4023
|
// @kaGreen: #71b307;
|
|
4006
|
-
const kaGreen
|
|
4007
|
-
const white
|
|
4024
|
+
const kaGreen = "#71B307";
|
|
4025
|
+
const white = "#FFFFFF";
|
|
4008
4026
|
const gray97 = "#F6F7F7";
|
|
4009
4027
|
const gray85 = "#D6D8DA";
|
|
4010
4028
|
const gray76 = "#BABEC2";
|
|
@@ -4012,23 +4030,23 @@ const gray68 = "#888D93";
|
|
|
4012
4030
|
const gray17 = "#21242c";
|
|
4013
4031
|
|
|
4014
4032
|
// @pure-sm-min: 568px;
|
|
4015
|
-
const pureSmMin$
|
|
4033
|
+
const pureSmMin$1 = "568px";
|
|
4016
4034
|
// @pure-md-min: 768px;
|
|
4017
|
-
const pureMdMin$
|
|
4035
|
+
const pureMdMin$1 = "768px";
|
|
4018
4036
|
// @pure-lg-min: 1024px;
|
|
4019
|
-
const pureLgMin$
|
|
4037
|
+
const pureLgMin$1 = "1024px";
|
|
4020
4038
|
// @pure-xl-min: 1280px;
|
|
4021
|
-
const pureXlMin$
|
|
4039
|
+
const pureXlMin$1 = "1280px";
|
|
4022
4040
|
// @pure-xs-max: (@pure-sm-min - 1);
|
|
4023
|
-
const pureXsMax$
|
|
4041
|
+
const pureXsMax$1 = "567px";
|
|
4024
4042
|
// @pure-sm-max: (@pure-md-min - 1);
|
|
4025
|
-
const pureSmMax$
|
|
4043
|
+
const pureSmMax$1 = "767px";
|
|
4026
4044
|
// @pure-md-max: (@pure-lg-min - 1);
|
|
4027
|
-
const pureMdMax$
|
|
4045
|
+
const pureMdMax$1 = "1023px";
|
|
4028
4046
|
// @pure-lg-max: (@pure-xl-min - 1);
|
|
4029
|
-
const pureLgMax$
|
|
4047
|
+
const pureLgMax$1 = "1279px";
|
|
4030
4048
|
// @tableBackgroundAccent: #f9f9f9; // for striping
|
|
4031
|
-
const tableBackgroundAccent
|
|
4049
|
+
const tableBackgroundAccent = "#F9F9F9";
|
|
4032
4050
|
// @zIndexAboveScratchpad: @zIndexScratchPad + 1;
|
|
4033
4051
|
const zIndexAboveScratchpad$1 = 2;
|
|
4034
4052
|
// @zIndexInteractiveComponent: @zIndexAboveScratchpad + 1;
|
|
@@ -4056,26 +4074,26 @@ const checkedColor$1 = "#71B307";
|
|
|
4056
4074
|
const articleMaxWidthInPx = 688;
|
|
4057
4075
|
const articleMaxWidthTableInPx = 512;
|
|
4058
4076
|
|
|
4059
|
-
var constants
|
|
4077
|
+
var constants = /*#__PURE__*/Object.freeze({
|
|
4060
4078
|
__proto__: null,
|
|
4061
|
-
baseFontFamily: baseFontFamily
|
|
4079
|
+
baseFontFamily: baseFontFamily,
|
|
4062
4080
|
boldFontFamily: boldFontFamily,
|
|
4063
|
-
kaGreen: kaGreen
|
|
4064
|
-
white: white
|
|
4081
|
+
kaGreen: kaGreen,
|
|
4082
|
+
white: white,
|
|
4065
4083
|
gray97: gray97,
|
|
4066
4084
|
gray85: gray85,
|
|
4067
4085
|
gray76: gray76,
|
|
4068
4086
|
gray68: gray68,
|
|
4069
4087
|
gray17: gray17,
|
|
4070
|
-
pureSmMin: pureSmMin$
|
|
4071
|
-
pureMdMin: pureMdMin$
|
|
4072
|
-
pureLgMin: pureLgMin$
|
|
4073
|
-
pureXlMin: pureXlMin$
|
|
4074
|
-
pureXsMax: pureXsMax$
|
|
4075
|
-
pureSmMax: pureSmMax$
|
|
4076
|
-
pureMdMax: pureMdMax$
|
|
4077
|
-
pureLgMax: pureLgMax$
|
|
4078
|
-
tableBackgroundAccent: tableBackgroundAccent
|
|
4088
|
+
pureSmMin: pureSmMin$1,
|
|
4089
|
+
pureMdMin: pureMdMin$1,
|
|
4090
|
+
pureLgMin: pureLgMin$1,
|
|
4091
|
+
pureXlMin: pureXlMin$1,
|
|
4092
|
+
pureXsMax: pureXsMax$1,
|
|
4093
|
+
pureSmMax: pureSmMax$1,
|
|
4094
|
+
pureMdMax: pureMdMax$1,
|
|
4095
|
+
pureLgMax: pureLgMax$1,
|
|
4096
|
+
tableBackgroundAccent: tableBackgroundAccent,
|
|
4079
4097
|
zIndexAboveScratchpad: zIndexAboveScratchpad$1,
|
|
4080
4098
|
zIndexInteractiveComponent: zIndexInteractiveComponent$1,
|
|
4081
4099
|
phoneMargin: phoneMargin,
|
|
@@ -14942,11 +14960,7 @@ ___default["default"].extend(MovableLine$4.prototype, {
|
|
|
14942
14960
|
* A stripped version of Icon.jsx from webapp. Takes an SVG icon and renders it
|
|
14943
14961
|
* inline like Font Awesome did.
|
|
14944
14962
|
*
|
|
14945
|
-
*
|
|
14946
|
-
* webapp's `icon-paths.js` which is a reference file for all the SVG paths
|
|
14947
|
-
* that we've used. You'll need to copy the object from that file into
|
|
14948
|
-
* whichever file you're using the icon and explicitly pass it in to the
|
|
14949
|
-
* <InlineIcon/> React component.
|
|
14963
|
+
* You can refer to `icon-paths.ts` for all available SVG icons.
|
|
14950
14964
|
*
|
|
14951
14965
|
* We assume that the viewBox is cropped and aligned to (0, 0), but icons can
|
|
14952
14966
|
* be defined differently. At some point we might want to add these attributes
|
|
@@ -14954,13 +14968,14 @@ ___default["default"].extend(MovableLine$4.prototype, {
|
|
|
14954
14968
|
*
|
|
14955
14969
|
* Sample usage:
|
|
14956
14970
|
*
|
|
14957
|
-
*
|
|
14971
|
+
* ```
|
|
14972
|
+
* const editIcon = {
|
|
14958
14973
|
* path: "M41.209 53.753l5.39 0l0 5.39l3.136 0l6.468-6.517-8.477-8.526-6.517 6.517l0 3.136zm33.173-34.937q-.882-.882-1.862.049l-19.6 19.6q-.931.98-.049 1.862t1.862-.049l19.6-19.6q.931-.98.049-1.862zm-38.563 45.668l0-16.121l37.632-37.632 16.17 16.121-37.632 37.632l-16.17 0zm43.022-12.397l0 10.633q-.049 6.713-4.753 11.417t-11.368 4.704l-46.599 0q-6.713 0-11.417-4.753t-4.704-11.368l0-46.599q0-6.664 4.753-11.417t11.368-4.704l46.599 0q3.528 0 6.566 1.372.833.392.98 1.323t-.49 1.617l-2.744 2.744q-.784.784-1.96.441t-2.352-.343l-46.599 0q-3.675 0-6.321 2.646t-2.646 6.321l0 46.599q0 3.675 2.646 6.321t6.321 2.646l46.599 0q3.675 0 6.321-2.646t2.646-6.321l0-7.056q0-.735.49-1.225l3.577-3.577q.833-.833 1.96-.392t1.127 1.617zm7.203-51.646q2.254 0 3.773 1.568l8.526 8.526q1.568 1.568 1.568 3.822t-1.568 3.773l-5.145 5.145-16.121-16.121 5.145-5.145q1.568-1.568 3.822-1.568z",
|
|
14959
14974
|
* width: 100,
|
|
14960
14975
|
* height: 78.912,
|
|
14961
|
-
*
|
|
14962
|
-
*
|
|
14963
|
-
*
|
|
14976
|
+
* };
|
|
14977
|
+
* <InlineIcon {...editIcon} />
|
|
14978
|
+
* ```
|
|
14964
14979
|
*/
|
|
14965
14980
|
const InlineIcon = _ref => {
|
|
14966
14981
|
let {
|
|
@@ -14987,11 +15002,7 @@ const InlineIcon = _ref => {
|
|
|
14987
15002
|
};
|
|
14988
15003
|
|
|
14989
15004
|
/**
|
|
14990
|
-
* Icon paths to be used with `inline-icon.
|
|
14991
|
-
*
|
|
14992
|
-
* These paths are taken directly from webapp's `icon-paths.js`. Unlike the
|
|
14993
|
-
* webapp equivalent, these can be directly required within Perseus files since
|
|
14994
|
-
* this is all bundled together anyway.
|
|
15005
|
+
* Icon paths to be used with `inline-icon.tsx` and `icon.tsx`.
|
|
14995
15006
|
*/
|
|
14996
15007
|
|
|
14997
15008
|
const iconCheck = {
|
|
@@ -14999,77 +15010,26 @@ const iconCheck = {
|
|
|
14999
15010
|
width: 24,
|
|
15000
15011
|
height: 24
|
|
15001
15012
|
};
|
|
15002
|
-
const iconCheckMedium = {
|
|
15003
|
-
path: "M6.072 10.4l6.175-7.058a1 1 0 1 1 1.506 1.317L6.769 12.64a1 1 0 0 1-1.55-.054L2.203 8.604a1 1 0 1 1 1.594-1.208L6.072 10.4z",
|
|
15004
|
-
width: 16,
|
|
15005
|
-
height: 16
|
|
15006
|
-
};
|
|
15007
15013
|
const iconChevronDown = {
|
|
15008
15014
|
path: "M99.669 13.048q0 3.36-2.352 5.712l-41.664 41.664q-2.408 2.408-5.88 2.408t-5.712-2.408l-41.664-41.664q-2.408-2.24-2.408-5.712t2.408-5.88l4.76-4.816q2.52-2.352 5.88-2.352t5.656 2.352l31.136 31.136 31.08-31.136q2.352-2.352 5.712-2.352t5.88 2.352l4.816 4.816q2.352 2.52 2.352 5.88z",
|
|
15009
15015
|
width: 100,
|
|
15010
15016
|
height: 63.034
|
|
15011
15017
|
};
|
|
15012
|
-
const iconChevronRight = {
|
|
15013
|
-
path: "M62.808 49.728q0 3.36-2.352 5.88l-41.72 41.664q-2.352 2.408-5.768 2.408t-5.768-2.408l-4.872-4.76q-2.352-2.52-2.352-5.88t2.352-5.712l31.08-31.136-31.08-31.024q-2.352-2.52-2.352-5.88t2.352-5.712l4.872-4.76q2.296-2.408 5.768-2.408t5.768 2.408l41.72 41.664q2.352 2.296 2.352 5.656z",
|
|
15014
|
-
width: 63.034,
|
|
15015
|
-
height: 100
|
|
15016
|
-
};
|
|
15017
15018
|
const iconCircle = {
|
|
15018
15019
|
path: "M100.035 50.046q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
|
|
15019
15020
|
width: 100,
|
|
15020
15021
|
height: 100
|
|
15021
15022
|
};
|
|
15022
|
-
const iconCircleArrowDown = {
|
|
15023
|
-
path: "M50.046 83.676q1.767 0 2.907-1.14l29.526-29.526q1.197-1.197 1.197-2.907t-1.197-2.964l-5.928-5.928q-1.197-1.14-2.964-1.14t-2.907 1.14l-12.312 12.312l0-32.661q0-1.71-1.254-2.964t-2.907-1.254l-8.322 0q-1.71 0-2.964 1.254t-1.254 2.964l0 32.661l-12.312-12.312q-1.197-1.254-2.907-1.254t-2.907 1.254l-5.928 5.928q-1.197 1.197-1.197 2.964t1.197 2.907l29.469 29.526q1.197 1.14 2.964 1.14zm49.989-33.63q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
|
|
15024
|
-
width: 100,
|
|
15025
|
-
height: 100
|
|
15026
|
-
};
|
|
15027
|
-
const iconCircleArrowUp = {
|
|
15028
|
-
path: "M54.207 83.391q1.653 0 2.907-1.254t1.254-2.907l0-32.718l12.312 12.312q1.254 1.254 2.964 1.254t2.907-1.254l5.928-5.928q1.197-1.197 1.14-2.964 0-1.767-1.14-2.907l-29.526-29.526q-1.197-1.14-2.907-1.14t-2.964 1.14l-29.469 29.526q-1.197 1.254-1.197 2.964t1.197 2.907l5.928 5.928q1.197 1.197 2.907 1.197t2.907-1.197l12.312-12.312l0 32.718q0 1.653 1.254 2.907t2.964 1.254l8.322 0zm45.828-33.345q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
|
|
15029
|
-
width: 100,
|
|
15030
|
-
height: 100
|
|
15031
|
-
};
|
|
15032
15023
|
const iconCircleThin = {
|
|
15033
15024
|
path: "M50.046 8.322q-8.493 0-16.188 3.306-15.561 6.669-22.173 22.23-3.363 7.695-3.363 16.188t3.306 16.188 8.949 13.281q5.586 5.586 13.281 8.892t16.188 3.306 16.188-3.306 13.281-8.892 8.892-13.281 3.306-16.188-3.306-16.188-8.892-13.281-13.281-8.949q-7.695-3.306-16.188-3.306zm0 91.713q-13.623 0-25.137-6.726t-18.183-18.183q-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.726 25.137-6.726 25.137-18.24 18.126q-11.514 6.726-25.08 6.726z",
|
|
15034
15025
|
width: 100,
|
|
15035
15026
|
height: 99.944
|
|
15036
15027
|
};
|
|
15037
|
-
const iconDesktop = {
|
|
15038
|
-
path: "M94.208 52.119l0-43.746q0-.69-.506-1.15t-1.196-.506l-84.088 0q-.69 0-1.196.506t-.506 1.15l0 43.746q0 .69.506 1.196t1.196.506l84.088 0q.69 0 1.196-.506t.506-1.196zm6.716-43.746l0 57.224q0 3.45-2.484 5.934t-5.934 2.484l-28.566 0q0 3.128 2.53 7.774.828 1.61.828 2.622t-1.012 2.07q-1.012 1.012-2.346.966l-26.91 0q-1.38 0-2.392-1.012t-1.012-2.024q0-1.058 1.656-4.14t1.748-6.256l-28.612 0q-3.45 0-5.934-2.484t-2.484-5.934l0-57.224q0-3.45 2.484-5.934t5.934-2.438l84.088 0q3.45 0 5.98 2.438 2.438 2.484 2.438 5.934z",
|
|
15039
|
-
width: 100,
|
|
15040
|
-
height: 86.648
|
|
15041
|
-
};
|
|
15042
|
-
const iconDropdownArrow = {
|
|
15043
|
-
path: "M9 9.8c0 .5.7 1.7 1.5 2.8 1.5 1.9 1.5 1.9 3 0C15.7 9.7 15.4 9 12 9c-1.6 0-3 .4-3 .8z",
|
|
15044
|
-
width: 24,
|
|
15045
|
-
height: 24
|
|
15046
|
-
};
|
|
15047
|
-
const iconExclamationSign = {
|
|
15048
|
-
path: "M58.368 81.225l0-12.369q0-.912-.57-1.539t-1.425-.627l-12.54 0q-.855-.057-1.482.627t-.684 1.539l0 12.369q-.057.855.627 1.482t1.539.684l12.54 0q.855 0 1.425-.627t.57-1.539zm1.026-62.871q0-1.596-2.223-1.71l-14.307 0q-2.109 0-2.223 1.71l1.14 40.47q0 .627.627 1.14t1.539.456l12.084 0q.912-.057 1.539-.513t.684-1.083zm-9.348-18.354q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.726 25.137-6.726 25.137-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669z",
|
|
15049
|
-
width: 100,
|
|
15050
|
-
height: 99.944
|
|
15051
|
-
};
|
|
15052
|
-
// Grabbed from https://github.com/encharm/Font-Awesome-SVG-PNG
|
|
15053
|
-
const iconGear = {
|
|
15054
|
-
path: "M1152 896q0-106-75-181t-181-75-181 75-75 181 75 181 181 75 181-75 75-181zm512-109v222q0 12-8 23t-20 13l-185 28q-19 54-39 91 35 50 107 138 10 12 10 25t-9 23q-27 37-99 108t-94 71q-12 0-26-9l-138-108q-44 23-91 38-16 136-29 186-7 28-36 28h-222q-14 0-24.5-8.5t-11.5-21.5l-28-184q-49-16-90-37l-141 107q-10 9-25 9-14 0-25-11-126-114-165-168-7-10-7-23 0-12 8-23 15-21 51-66.5t54-70.5q-27-50-41-99l-183-27q-13-2-21-12.5t-8-23.5v-222q0-12 8-23t19-13l186-28q14-46 39-92-40-57-107-138-10-12-10-24 0-10 9-23 26-36 98.5-107.5t94.5-71.5q13 0 26 10l138 107q44-23 91-38 16-136 29-186 7-28 36-28h222q14 0 24.5 8.5t11.5 21.5l28 184q49 16 90 37l142-107q9-9 24-9 13 0 25 10 129 119 165 170 7 8 7 22 0 12-8 23-15 21-51 66.5t-54 70.5q26 50 41 98l183 28q13 2 21 12.5t8 23.5z",
|
|
15055
|
-
width: 1792,
|
|
15056
|
-
height: 1792
|
|
15057
|
-
};
|
|
15058
|
-
const iconMobilePhone = {
|
|
15059
|
-
path: "M36.04 89.557q0-2.584-1.836-4.42t-4.42-1.836-4.352 1.836q-1.836 1.836-1.836 4.42t1.836 4.352 4.42 1.836q2.652-.068 4.42-1.836t1.768-4.352zm16.184-12.444l0-54.74q0-1.088-.748-1.768t-1.768-.68l-39.78 0q-1.088 0-1.768.748t-.68 1.7l0 54.74q0 1.02.748 1.768t1.7.68l39.78 0q1.02-.068 1.768-.748t.748-1.7zm-14.892-65.892q0-1.224-1.292-1.292l-12.444 0q-1.224.068-1.224 1.292t1.224 1.224l12.444 0q1.292 0 1.292-1.224zm22.372-1.292l0 79.628q0 3.944-2.992 6.936t-7.004 2.992l-39.78 0q-4.012 0-7.004-2.924-2.924-2.924-2.924-7.004l0-79.628q0-4.012 2.924-6.936t7.004-2.992l39.78 0q4.012-.068 7.004 2.924t2.992 7.004z",
|
|
15060
|
-
width: 60.013,
|
|
15061
|
-
height: 100
|
|
15062
|
-
};
|
|
15063
15028
|
const iconOk = {
|
|
15064
15029
|
path: "M37.964 76.048q-2.576 0-4.368-1.792l-31.864-31.864q-1.792-1.792-1.792-4.368t1.792-4.368l8.736-8.68q1.792-1.792 4.368-1.792t4.312 1.792l18.816 18.872 42-42.056q1.792-1.792 4.368-1.792t4.312 1.792l8.736 8.736q1.792 1.792 1.792 4.368t-1.792 4.312l-55.048 55.048q-1.792 1.792-4.368 1.792z",
|
|
15065
15030
|
width: 100,
|
|
15066
15031
|
height: 76.637
|
|
15067
15032
|
};
|
|
15068
|
-
const iconPlus = {
|
|
15069
|
-
path: "M99.758 43.09l0 13.578q0 2.852-1.984 4.836t-4.836 1.984l-29.45 0l0 29.45q0 2.852-1.984 4.836t-4.836 1.984l-13.578 0q-2.852 0-4.836-1.984t-1.984-4.836l0-29.45l-29.45 0q-2.852 0-4.836-1.984t-1.984-4.836l0-13.578q0-2.852 1.984-4.836t4.836-1.984l29.45 0l0-29.45q0-2.852 1.984-4.836t4.836-1.984l13.578 0q2.852 0 4.836 1.984t1.984 4.836l0 29.45l29.45 0q2.852 0 4.836 1.984t1.984 4.836z",
|
|
15070
|
-
width: 100,
|
|
15071
|
-
height: 100
|
|
15072
|
-
};
|
|
15073
15033
|
const iconRemove = {
|
|
15074
15034
|
path: "M100.464 80.808q0 3.404-2.368 5.772l-11.47 11.544q-2.368 2.368-5.772 2.368t-5.698-2.368l-24.864-24.864-24.864 24.864q-2.368 2.368-5.772 2.368t-5.772-2.368l-11.47-11.544q-2.368-2.368-2.368-5.772t2.368-5.698l24.864-24.864-24.864-24.864q-2.368-2.368-2.368-5.772t2.368-5.772l11.47-11.47q2.368-2.368 5.772-2.368t5.772 2.368l24.864 24.864 24.864-24.864q2.294-2.368 5.698-2.368t5.772 2.368l11.47 11.47q2.368 2.368 2.368 5.772t-2.368 5.772l-24.864 24.864 24.864 24.864q2.368 2.294 2.368 5.698z",
|
|
15075
15035
|
width: 100,
|
|
@@ -15085,53 +15045,17 @@ const iconTryAgain = {
|
|
|
15085
15045
|
width: 23,
|
|
15086
15046
|
height: 23
|
|
15087
15047
|
};
|
|
15088
|
-
const iconTablet = {
|
|
15089
|
-
path: "M45.322 90.706q0-1.86-1.302-3.224-1.364-1.364-3.224-1.364t-3.224 1.364-1.302 3.224q0 1.86 1.364 3.224 1.302 1.364 3.162 1.302 1.86.062 3.224-1.302t1.302-3.224zm27.218-11.346l0-68.014q0-.93-.682-1.612t-1.55-.682l-58.962 0q-.93 0-1.612.682t-.682 1.612l0 68.014q0 .93.682 1.612t1.612.62l58.962 0q.992-.062 1.612-.682t.62-1.55zm9.114-68.014l0 77.066q0 4.65-3.348 7.998t-7.998 3.348l-58.962 0q-4.65 0-7.998-3.348t-3.348-7.998l0-77.066q0-4.65 3.348-7.998t7.998-3.348l58.962 0q4.65 0 7.998 3.348t3.348 7.998z",
|
|
15090
|
-
width: 81.852,
|
|
15091
|
-
height: 100
|
|
15092
|
-
};
|
|
15093
15048
|
const iconTrash = {
|
|
15094
15049
|
path: "M31.293 37.506q2.052 0 2.052 2.109l0 37.506q0 1.995-2.052 2.109l-4.218 0q-.912-.057-1.482-.627t-.57-1.482l0-37.506q0-2.109 2.052-2.109l4.218 0zm18.753 2.109l0 37.506q0 .912-.57 1.482t-1.539.627l-4.161 0q-1.995 0-2.109-2.109l0-37.506q.057-.912.627-1.482t1.482-.627l4.161 0q.969.057 1.539.627t.57 1.482zm14.592-2.109q2.052 0 2.052 2.109l0 37.506q0 1.995-2.052 2.109l-4.161 0q-.969-.057-1.539-.627t-.57-1.482l0-37.506q0-2.109 2.109-2.109l4.161 0zm10.431 49.248l0-61.731l-58.368 0l0 61.731q.057 2.679.969 3.819t1.083 1.14l54.207 0q.171 0 1.14-1.083t.969-3.876zm-43.776-70.11l29.184 0l-3.135-7.581q-.456-.57-1.14-.741l-20.634 0q-.627.114-1.083.741zm-31.293 2.109q0-1.995 2.109-2.109l20.121 0l4.56-10.83q.969-2.394 3.477-4.104 2.565-1.71 5.187-1.71l20.805 0q2.622 0 5.187 1.71t3.477 4.104l4.56 10.83l20.178 0q.912.057 1.482.627t.57 1.482l0 4.161q0 1.995-2.052 2.109l-6.27 0l0 61.731q0 5.415-3.078 9.348t-7.353 3.933l-54.207 0q-4.275 0-7.353-3.819t-3.078-9.177l0-62.016l-6.213 0q-.969 0-1.539-.57t-.57-1.539l0-4.161z",
|
|
15095
15050
|
width: 91.681,
|
|
15096
15051
|
height: 100
|
|
15097
15052
|
};
|
|
15098
|
-
const iconUndo = {
|
|
15099
|
-
path: "M10,6.6C10,7.2,9.8,8,9.3,9.1c0,0,0,0.1-0.1,0.1S9.2,9.3,9.2,9.4c0,0,0,0.1-0.1,0.1C9,9.6,9,9.6,8.9,9.6 c-0.1,0-0.1,0-0.1-0.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1s0-0.1,0-0.1c0-0.3,0-0.5,0-0.7c0-0.4,0-0.7-0.1-1C8.6,7.1,8.5,6.9,8.4,6.7S8.2,6.3,8,6.1C7.8,5.9,7.6,5.8,7.4,5.7S6.9,5.5,6.7,5.5S6.1,5.4,5.8,5.4c-0.3,0-0.6,0-1,0H3.6v1.4c0,0.1,0,0.2-0.1,0.3C3.4,7.1,3.3,7.1,3.2,7.1C3.1,7.1,3,7.1,3,7L0.1,4.1C0,4.1,0,4,0,3.9s0-0.2,0.1-0.3L3,0.8C3,0.7,3.1,0.7,3.2,0.7c0.1,0,0.2,0,0.3,0.1C3.5,0.9,3.6,0.9,3.6,1v1.4h1.2c2.6,0,4.3,0.7,4.9,2.2C9.9,5.2,10,5.8,10,6.6z",
|
|
15100
|
-
width: 10,
|
|
15101
|
-
height: 10
|
|
15102
|
-
};
|
|
15103
15053
|
const iconMinus = {
|
|
15104
15054
|
path: `M8,13 L16,13 C16.5522847,13 17,12.5522847 17,12 C17,11.4477153 16.5522847,11 16,11 L8,11 C7.44771525,11 7,11.4477153 7,12 C7,12.5522847 7.44771525,13 8,13 Z`,
|
|
15105
15055
|
width: 24,
|
|
15106
15056
|
height: 24
|
|
15107
15057
|
};
|
|
15108
15058
|
|
|
15109
|
-
var iconPaths = /*#__PURE__*/Object.freeze({
|
|
15110
|
-
__proto__: null,
|
|
15111
|
-
iconCheck: iconCheck,
|
|
15112
|
-
iconCheckMedium: iconCheckMedium,
|
|
15113
|
-
iconChevronDown: iconChevronDown,
|
|
15114
|
-
iconChevronRight: iconChevronRight,
|
|
15115
|
-
iconCircle: iconCircle,
|
|
15116
|
-
iconCircleArrowDown: iconCircleArrowDown,
|
|
15117
|
-
iconCircleArrowUp: iconCircleArrowUp,
|
|
15118
|
-
iconCircleThin: iconCircleThin,
|
|
15119
|
-
iconDesktop: iconDesktop,
|
|
15120
|
-
iconDropdownArrow: iconDropdownArrow,
|
|
15121
|
-
iconExclamationSign: iconExclamationSign,
|
|
15122
|
-
iconGear: iconGear,
|
|
15123
|
-
iconMobilePhone: iconMobilePhone,
|
|
15124
|
-
iconOk: iconOk,
|
|
15125
|
-
iconPlus: iconPlus,
|
|
15126
|
-
iconRemove: iconRemove,
|
|
15127
|
-
iconStar: iconStar,
|
|
15128
|
-
iconTryAgain: iconTryAgain,
|
|
15129
|
-
iconTablet: iconTablet,
|
|
15130
|
-
iconTrash: iconTrash,
|
|
15131
|
-
iconUndo: iconUndo,
|
|
15132
|
-
iconMinus: iconMinus
|
|
15133
|
-
});
|
|
15134
|
-
|
|
15135
15059
|
/* eslint-disable @babel/no-invalid-this */
|
|
15136
15060
|
const add$1 = {
|
|
15137
15061
|
constrain: function () {
|
|
@@ -17041,6 +16965,15 @@ const Status = {
|
|
|
17041
16965
|
LOADED: "loaded",
|
|
17042
16966
|
FAILED: "failed"
|
|
17043
16967
|
};
|
|
16968
|
+
/**
|
|
16969
|
+
* Component to display an image (or other React components) while the desired
|
|
16970
|
+
* image is loading.
|
|
16971
|
+
*
|
|
16972
|
+
* Derived from
|
|
16973
|
+
* https://github.com/hzdg/react-imageloader/blob/master/src/index.js
|
|
16974
|
+
* to better suit our environment/build tools. Additionally, this one does
|
|
16975
|
+
* not introduce a wrapper element, which makes styling easier.
|
|
16976
|
+
*/
|
|
17044
16977
|
class ImageLoader extends React__namespace.Component {
|
|
17045
16978
|
img;
|
|
17046
16979
|
constructor(props) {
|
|
@@ -18400,7 +18333,7 @@ const styles$C = aphrodite.StyleSheet.create({
|
|
|
18400
18333
|
},
|
|
18401
18334
|
":hover ~ div span[data-lint-inside-table]": {
|
|
18402
18335
|
backgroundColor: warningColor,
|
|
18403
|
-
color: white
|
|
18336
|
+
color: white
|
|
18404
18337
|
}
|
|
18405
18338
|
},
|
|
18406
18339
|
// This is how we position the hover target for inline lint.
|
|
@@ -18436,7 +18369,7 @@ const styles$C = aphrodite.StyleSheet.create({
|
|
|
18436
18369
|
// draw attention to the linty content.
|
|
18437
18370
|
":hover ~ span": {
|
|
18438
18371
|
backgroundColor: warningColor,
|
|
18439
|
-
color: white
|
|
18372
|
+
color: white
|
|
18440
18373
|
}
|
|
18441
18374
|
},
|
|
18442
18375
|
radioWidgetHoverTarget: {
|
|
@@ -18478,7 +18411,7 @@ const styles$C = aphrodite.StyleSheet.create({
|
|
|
18478
18411
|
// draw attention to the linty content.
|
|
18479
18412
|
":hover ~ span": {
|
|
18480
18413
|
backgroundColor: warningColor,
|
|
18481
|
-
color: white
|
|
18414
|
+
color: white
|
|
18482
18415
|
}
|
|
18483
18416
|
},
|
|
18484
18417
|
// This is the class for the lint indicator in the margin.
|
|
@@ -18515,10 +18448,10 @@ const styles$C = aphrodite.StyleSheet.create({
|
|
|
18515
18448
|
// When it is displayed, it goes on top!
|
|
18516
18449
|
zIndex: 1000,
|
|
18517
18450
|
// These styles control what the tooltip looks like
|
|
18518
|
-
color: white
|
|
18451
|
+
color: white,
|
|
18519
18452
|
backgroundColor: gray17,
|
|
18520
18453
|
opacity: 0.9,
|
|
18521
|
-
fontFamily: baseFontFamily
|
|
18454
|
+
fontFamily: baseFontFamily,
|
|
18522
18455
|
fontSize: "12px",
|
|
18523
18456
|
lineHeight: "15px",
|
|
18524
18457
|
width: "320px",
|
|
@@ -19536,7 +19469,7 @@ var preprocessTex = (texCode => texCode
|
|
|
19536
19469
|
|
|
19537
19470
|
const {
|
|
19538
19471
|
interactiveSizes
|
|
19539
|
-
} = constants
|
|
19472
|
+
} = constants;
|
|
19540
19473
|
|
|
19541
19474
|
// Note: these size cutoffs represent content-width cutoffs as specified in
|
|
19542
19475
|
// http://zpl.io/1mVmvU (broken link - we no longer use Zeplin)
|
|
@@ -19569,13 +19502,6 @@ const getInteractiveBoxFromSizeClass = sizeClass => {
|
|
|
19569
19502
|
return [interactiveSizes.defaultBoxSize, interactiveSizes.defaultBoxSize];
|
|
19570
19503
|
};
|
|
19571
19504
|
|
|
19572
|
-
var sizingUtils = /*#__PURE__*/Object.freeze({
|
|
19573
|
-
__proto__: null,
|
|
19574
|
-
containerSizeClass: containerSizeClass,
|
|
19575
|
-
getClassFromWidth: getClassFromWidth,
|
|
19576
|
-
getInteractiveBoxFromSizeClass: getInteractiveBoxFromSizeClass
|
|
19577
|
-
});
|
|
19578
|
-
|
|
19579
19505
|
class WidgetContainer extends React__namespace.Component {
|
|
19580
19506
|
widgetRef = /*#__PURE__*/React__namespace.createRef();
|
|
19581
19507
|
static defaultProps = {
|
|
@@ -21252,7 +21178,7 @@ const Triangle = props => {
|
|
|
21252
21178
|
width: 0,
|
|
21253
21179
|
position: "absolute",
|
|
21254
21180
|
left: props.left,
|
|
21255
|
-
top: props
|
|
21181
|
+
top: props.top,
|
|
21256
21182
|
borderLeft: borderLeft,
|
|
21257
21183
|
borderRight: borderRight,
|
|
21258
21184
|
borderTop: borderTop,
|
|
@@ -21333,6 +21259,47 @@ const HORIZONTAL_ALIGNMNENTS = {
|
|
|
21333
21259
|
arrowLeft: arrowSize => -arrowSize - 2
|
|
21334
21260
|
}
|
|
21335
21261
|
};
|
|
21262
|
+
/**
|
|
21263
|
+
* DEPRECATED! Use Wonder Blocks tooltip instead.
|
|
21264
|
+
*
|
|
21265
|
+
* A generic tooltip library for React.js
|
|
21266
|
+
*
|
|
21267
|
+
* ```
|
|
21268
|
+
* import Tooltip from "./tooltip";
|
|
21269
|
+
* <Tooltip
|
|
21270
|
+
* className="class-for-tooltip-contents"
|
|
21271
|
+
* horizontalPosition={HoriziontalDirection.Left}
|
|
21272
|
+
* horizontalAlign={HoriziontalDirection.Left}
|
|
21273
|
+
* verticalPosition={VerticalDirection.Top}
|
|
21274
|
+
* arrowSize={10} // arrow size in pixels
|
|
21275
|
+
* borderColor="#ccc" // color of the border for the tooltip
|
|
21276
|
+
* show={true} // whether the tooltip should currently be visible
|
|
21277
|
+
* targetContainerStyle={targetContainerStyle}
|
|
21278
|
+
* >
|
|
21279
|
+
* <TargetElementOfTheTooltip />
|
|
21280
|
+
* <TooltipContents1 />
|
|
21281
|
+
* <TooltipContents2 />
|
|
21282
|
+
* </Tooltip>
|
|
21283
|
+
* ```
|
|
21284
|
+
*
|
|
21285
|
+
* To show/hide the tooltip, the parent component should call the
|
|
21286
|
+
* `.show()` and `.hide()` methods of the tooltip when appropriate.
|
|
21287
|
+
* (These are usually set up as handlers of events on the target element.)
|
|
21288
|
+
*
|
|
21289
|
+
* Notes:
|
|
21290
|
+
* `className` should not specify a border; that is handled by `borderColor`
|
|
21291
|
+
* so that the arrow and tooltip match
|
|
21292
|
+
*
|
|
21293
|
+
* ```
|
|
21294
|
+
* __,,--``\\
|
|
21295
|
+
* _,,-''`` \\ ,
|
|
21296
|
+
* '----------_.------'-.___|\__
|
|
21297
|
+
* _.--''`` `)__ )__ @\__
|
|
21298
|
+
* ( .. ''---/___,,E/__,E'------`
|
|
21299
|
+
* `-''`''
|
|
21300
|
+
* Here be dragons.
|
|
21301
|
+
* ```
|
|
21302
|
+
*/
|
|
21336
21303
|
class Tooltip extends React__namespace.Component {
|
|
21337
21304
|
static defaultProps = {
|
|
21338
21305
|
className: "",
|
|
@@ -21560,10 +21527,7 @@ class InputWithExamples extends React__namespace.Component {
|
|
|
21560
21527
|
return "- " + example;
|
|
21561
21528
|
}).join("\n");
|
|
21562
21529
|
const showExamples = this.props.shouldShowExamples && this.state.showExamples;
|
|
21563
|
-
return /*#__PURE__*/React__namespace.createElement(Tooltip
|
|
21564
|
-
// eslint-disable-next-line react/no-string-refs
|
|
21565
|
-
, {
|
|
21566
|
-
ref: "tooltip",
|
|
21530
|
+
return /*#__PURE__*/React__namespace.createElement(Tooltip, {
|
|
21567
21531
|
className: "perseus-formats-tooltip preview-measure",
|
|
21568
21532
|
horizontalPosition: HorizontalDirection.Left,
|
|
21569
21533
|
horizontalAlign: HorizontalDirection.Left,
|
|
@@ -24794,29 +24758,29 @@ var PassageRef$1 = {
|
|
|
24794
24758
|
* });
|
|
24795
24759
|
*/
|
|
24796
24760
|
const {
|
|
24797
|
-
pureXsMax
|
|
24798
|
-
pureSmMin
|
|
24799
|
-
pureSmMax
|
|
24800
|
-
pureMdMin
|
|
24801
|
-
pureMdMax
|
|
24802
|
-
pureLgMin
|
|
24803
|
-
pureLgMax
|
|
24804
|
-
pureXlMin
|
|
24805
|
-
} = constants
|
|
24761
|
+
pureXsMax,
|
|
24762
|
+
pureSmMin,
|
|
24763
|
+
pureSmMax,
|
|
24764
|
+
pureMdMin,
|
|
24765
|
+
pureMdMax,
|
|
24766
|
+
pureLgMin,
|
|
24767
|
+
pureLgMax,
|
|
24768
|
+
pureXlMin
|
|
24769
|
+
} = constants;
|
|
24806
24770
|
var mediaQueries = {
|
|
24807
|
-
xs: `@media screen and (max-width: ${pureXsMax
|
|
24808
|
-
sm: `@media screen and (min-width: ${pureSmMin
|
|
24809
|
-
md: `@media screen and (min-width: ${pureMdMin
|
|
24810
|
-
lg: `@media screen and (min-width: ${pureLgMin
|
|
24811
|
-
xl: `@media screen and (min-width: ${pureXlMin
|
|
24812
|
-
xsOrSmaller: `@media screen and (max-width: ${pureXsMax
|
|
24813
|
-
smOrSmaller: `@media screen and (max-width: ${pureSmMax
|
|
24814
|
-
mdOrSmaller: `@media screen and (max-width: ${pureMdMax
|
|
24815
|
-
lgOrSmaller: `@media screen and (max-width: ${pureLgMax
|
|
24816
|
-
smOrLarger: `@media screen and (min-width: ${pureSmMin
|
|
24817
|
-
mdOrLarger: `@media screen and (min-width: ${pureMdMin
|
|
24818
|
-
lgOrLarger: `@media screen and (min-width: ${pureLgMin
|
|
24819
|
-
xlOrLarger: `@media screen and (min-width: ${pureXlMin
|
|
24771
|
+
xs: `@media screen and (max-width: ${pureXsMax})`,
|
|
24772
|
+
sm: `@media screen and (min-width: ${pureSmMin}) and ` + `(max-width: ${pureSmMax})`,
|
|
24773
|
+
md: `@media screen and (min-width: ${pureMdMin}) and ` + `(max-width: ${pureMdMax})`,
|
|
24774
|
+
lg: `@media screen and (min-width: ${pureLgMin}) and ` + `(max-width: ${pureLgMax})`,
|
|
24775
|
+
xl: `@media screen and (min-width: ${pureXlMin})`,
|
|
24776
|
+
xsOrSmaller: `@media screen and (max-width: ${pureXsMax})`,
|
|
24777
|
+
smOrSmaller: `@media screen and (max-width: ${pureSmMax})`,
|
|
24778
|
+
mdOrSmaller: `@media screen and (max-width: ${pureMdMax})`,
|
|
24779
|
+
lgOrSmaller: `@media screen and (max-width: ${pureLgMax})`,
|
|
24780
|
+
smOrLarger: `@media screen and (min-width: ${pureSmMin})`,
|
|
24781
|
+
mdOrLarger: `@media screen and (min-width: ${pureMdMin})`,
|
|
24782
|
+
lgOrLarger: `@media screen and (min-width: ${pureLgMin})`,
|
|
24783
|
+
xlOrLarger: `@media screen and (min-width: ${pureXlMin})`
|
|
24820
24784
|
};
|
|
24821
24785
|
|
|
24822
24786
|
const {
|
|
@@ -24826,7 +24790,7 @@ const {
|
|
|
24826
24790
|
checkedColor,
|
|
24827
24791
|
circleSize,
|
|
24828
24792
|
radioMarginWidth
|
|
24829
|
-
} = constants
|
|
24793
|
+
} = constants;
|
|
24830
24794
|
var sharedStyles = aphrodite.StyleSheet.create({
|
|
24831
24795
|
perseusInteractive: {
|
|
24832
24796
|
zIndex: zIndexInteractiveComponent,
|
|
@@ -25060,6 +25024,37 @@ const BASE_ICON_SIZE = 10;
|
|
|
25060
25024
|
// If you pass in an object you need to specify an SVG path to
|
|
25061
25025
|
// render along with the width and height of the path (to ensure
|
|
25062
25026
|
// that it gets scaled correctly).
|
|
25027
|
+
/**
|
|
25028
|
+
* An SVG Icon
|
|
25029
|
+
*
|
|
25030
|
+
* This component is designed to take in SVG paths and render icons based upon
|
|
25031
|
+
* them. If you are looking for an icon that we've used before you should look
|
|
25032
|
+
* in `icon-paths.js` which is a reference file for all the SVG paths that
|
|
25033
|
+
* we've used. You'll need to copy the object from that file into whichever
|
|
25034
|
+
* file you're using the icon and explicitly pass it in to the <Icon/> React
|
|
25035
|
+
* component.
|
|
25036
|
+
*
|
|
25037
|
+
* Sample usage:
|
|
25038
|
+
*
|
|
25039
|
+
* ```
|
|
25040
|
+
* const dropdownIcon = `M5,6L0,0L10,0`;
|
|
25041
|
+
* <Icon icon={dropdownIcon} />
|
|
25042
|
+
* ```
|
|
25043
|
+
*
|
|
25044
|
+
* Or:
|
|
25045
|
+
*
|
|
25046
|
+
* ```
|
|
25047
|
+
* const dropdownIcon = {
|
|
25048
|
+
* path: `M5,6L0,0L10,0`,
|
|
25049
|
+
* height: 10,
|
|
25050
|
+
* width: 10,
|
|
25051
|
+
* };
|
|
25052
|
+
* <Icon icon={dropdownIcon} size={20} />
|
|
25053
|
+
* ```
|
|
25054
|
+
*
|
|
25055
|
+
* If you want to add an entirely new icon please read the note inside
|
|
25056
|
+
* the `icon-paths.ts` file.
|
|
25057
|
+
*/
|
|
25063
25058
|
class Icon extends React__namespace.Component {
|
|
25064
25059
|
static defaultProps = {
|
|
25065
25060
|
color: "currentColor"
|
|
@@ -25182,7 +25177,7 @@ function getA11yText(letter, checked, correct, crossedOut, showCorrectness, stri
|
|
|
25182
25177
|
const FocusRing = function (_ref) {
|
|
25183
25178
|
let {
|
|
25184
25179
|
visible = true,
|
|
25185
|
-
color = kaGreen
|
|
25180
|
+
color = kaGreen,
|
|
25186
25181
|
multipleSelect = false,
|
|
25187
25182
|
children
|
|
25188
25183
|
} = _ref;
|
|
@@ -25283,7 +25278,7 @@ function ChoiceInner(props) {
|
|
|
25283
25278
|
} = usePerseusI18n();
|
|
25284
25279
|
const letter = getChoiceLetter(pos, strings);
|
|
25285
25280
|
if (!showCorrectness) {
|
|
25286
|
-
return letter;
|
|
25281
|
+
return /*#__PURE__*/React__namespace.createElement("span", null, letter);
|
|
25287
25282
|
}
|
|
25288
25283
|
if (correct) {
|
|
25289
25284
|
return /*#__PURE__*/React__namespace.createElement(InlineIcon, _extends({}, iconCheck, {
|
|
@@ -25310,7 +25305,7 @@ function getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, cor
|
|
|
25310
25305
|
backgroundColor = "transparent";
|
|
25311
25306
|
} else if (checked) {
|
|
25312
25307
|
const bg = showCorrectness && correct ? wonderBlocksTokens.color.green : wonderBlocksTokens.color.blue;
|
|
25313
|
-
color = white
|
|
25308
|
+
color = white;
|
|
25314
25309
|
backgroundColor = bg;
|
|
25315
25310
|
borderColor = bg;
|
|
25316
25311
|
} else {
|
|
@@ -25353,7 +25348,6 @@ const ChoiceIcon = function (props) {
|
|
|
25353
25348
|
visible: focused || hovered,
|
|
25354
25349
|
multipleSelect: multipleSelect
|
|
25355
25350
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
25356
|
-
// @ts-expect-error - TS2322 - Type '{ backgroundColor: string | null | undefined; borderColor: string; color: string; borderRadius: number; }' is not assignable to type 'Properties<string | number, string & {}>'.
|
|
25357
25351
|
style: dynamicStyles,
|
|
25358
25352
|
"data-testid": "choice-icon__library-choice-icon",
|
|
25359
25353
|
className: aphrodite.css(styles$s.circle, showCorrectness && correct && styles$s.circleCorrect, showCorrectness && !correct && styles$s.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$s.circleIncorrectAnswered)
|
|
@@ -25388,7 +25382,7 @@ const styles$s = aphrodite.StyleSheet.create({
|
|
|
25388
25382
|
borderStyle: "solid",
|
|
25389
25383
|
borderWidth: 2,
|
|
25390
25384
|
// The default icons have letters in them. Style those letters.
|
|
25391
|
-
fontFamily: baseFontFamily
|
|
25385
|
+
fontFamily: baseFontFamily,
|
|
25392
25386
|
// NOTE(emily): We explicitly set the font weight instead of using the
|
|
25393
25387
|
// "bold font family" so that characters which fall back to the default
|
|
25394
25388
|
// font get bolded too.
|
|
@@ -27804,7 +27798,7 @@ const styles$j = aphrodite.StyleSheet.create({
|
|
|
27804
27798
|
gradedGroup: {
|
|
27805
27799
|
borderTop: `1px solid ${gray76}`,
|
|
27806
27800
|
borderBottom: `1px solid ${gray76}`,
|
|
27807
|
-
backgroundColor: tableBackgroundAccent
|
|
27801
|
+
backgroundColor: tableBackgroundAccent,
|
|
27808
27802
|
marginLeft: negativePhoneMargin,
|
|
27809
27803
|
marginRight: negativePhoneMargin,
|
|
27810
27804
|
paddingBottom: phoneMargin,
|
|
@@ -28093,7 +28087,7 @@ const styles$i = aphrodite.StyleSheet.create({
|
|
|
28093
28087
|
container: {
|
|
28094
28088
|
borderTop: `1px solid ${gray76}`,
|
|
28095
28089
|
borderBottom: `1px solid ${gray76}`,
|
|
28096
|
-
backgroundColor: tableBackgroundAccent
|
|
28090
|
+
backgroundColor: tableBackgroundAccent,
|
|
28097
28091
|
marginLeft: negativePhoneMargin,
|
|
28098
28092
|
marginRight: negativePhoneMargin,
|
|
28099
28093
|
paddingBottom: phoneMargin,
|
|
@@ -28698,21 +28692,6 @@ const typeToButton = type => {
|
|
|
28698
28692
|
};
|
|
28699
28693
|
};
|
|
28700
28694
|
|
|
28701
|
-
var util = /*#__PURE__*/Object.freeze({
|
|
28702
|
-
__proto__: null,
|
|
28703
|
-
DEFAULT_BACKGROUND_IMAGE: DEFAULT_BACKGROUND_IMAGE,
|
|
28704
|
-
allTypes: allTypes,
|
|
28705
|
-
functionForType: functionForType,
|
|
28706
|
-
getEquationString: getEquationString,
|
|
28707
|
-
pointsFromNormalized: pointsFromNormalized,
|
|
28708
|
-
maybePointsFromNormalized: maybePointsFromNormalized,
|
|
28709
|
-
defaultPlotProps: defaultPlotProps,
|
|
28710
|
-
chooseType: chooseType,
|
|
28711
|
-
getGridAndSnapSteps: getGridAndSnapSteps,
|
|
28712
|
-
DEFAULT_GRAPHER_PROPS: DEFAULT_GRAPHER_PROPS,
|
|
28713
|
-
typeToButton: typeToButton
|
|
28714
|
-
});
|
|
28715
|
-
|
|
28716
28695
|
function getCoefficientsByType(data) {
|
|
28717
28696
|
if (data.type === "exponential" || data.type === "logarithm") {
|
|
28718
28697
|
const grader = functionForType(data.type);
|
|
@@ -31282,6 +31261,10 @@ const HiddenIcon = () => /*#__PURE__*/React__namespace.createElement("svg", {
|
|
|
31282
31261
|
}, /*#__PURE__*/React__namespace.createElement("path", {
|
|
31283
31262
|
d: "M0 0h24v24H0z"
|
|
31284
31263
|
}))));
|
|
31264
|
+
/**
|
|
31265
|
+
* A "heads-up display" (HUD) indicator that includes a short message (usually
|
|
31266
|
+
* used for linting errors). The indicator can be disabled.
|
|
31267
|
+
*/
|
|
31285
31268
|
const HUD = _ref => {
|
|
31286
31269
|
let {
|
|
31287
31270
|
message,
|
|
@@ -31314,7 +31297,7 @@ const styles$g = aphrodite.StyleSheet.create({
|
|
|
31314
31297
|
fontFamily: boldFontFamily,
|
|
31315
31298
|
fontSize: "15px",
|
|
31316
31299
|
lineHeight: "18px",
|
|
31317
|
-
color: white
|
|
31300
|
+
color: white,
|
|
31318
31301
|
userSelect: "none",
|
|
31319
31302
|
borderWidth: 0 // <button> gives us a border by default
|
|
31320
31303
|
},
|
|
@@ -31495,18 +31478,24 @@ const {
|
|
|
31495
31478
|
const toNumericString = KhanMath.toNumericString;
|
|
31496
31479
|
const getNumericFormat = KhanMath.getNumericFormat;
|
|
31497
31480
|
|
|
31498
|
-
|
|
31481
|
+
/**
|
|
31482
|
+
* An input box that accepts only numeric strings
|
|
31499
31483
|
*
|
|
31500
|
-
* Calls onChange(value, format) for valid numbers.
|
|
31501
|
-
*
|
|
31484
|
+
* Calls `onChange(value, format)` for valid numbers.
|
|
31485
|
+
*
|
|
31486
|
+
* Reverts to the current value `onBlur` or on [ENTER],
|
|
31502
31487
|
* but maintains the format (i.e. 3/2, 1 1/2, 150%)
|
|
31503
|
-
*
|
|
31504
|
-
*
|
|
31505
|
-
*
|
|
31506
|
-
*
|
|
31507
|
-
* If
|
|
31508
|
-
*
|
|
31509
|
-
*
|
|
31488
|
+
*
|
|
31489
|
+
* Accepts empty input and sends it to `onChange` as `null` if no numeric
|
|
31490
|
+
* placeholder is set.
|
|
31491
|
+
*
|
|
31492
|
+
* If given a `checkValidity` function, will turn the background/outline red
|
|
31493
|
+
* when invalid.
|
|
31494
|
+
*
|
|
31495
|
+
* If `useArrowKeys` is set to `true`, up/down arrows will increment/decrement
|
|
31496
|
+
* integers.
|
|
31497
|
+
*
|
|
31498
|
+
* Optionally takes a `size` (`"mini"`, `"small"`,` `"normal"`)
|
|
31510
31499
|
*/
|
|
31511
31500
|
class NumberInput extends React__namespace.Component {
|
|
31512
31501
|
static contextType = PerseusI18nContext;
|
|
@@ -31517,7 +31506,7 @@ class NumberInput extends React__namespace.Component {
|
|
|
31517
31506
|
onChange: PropTypes__default["default"].func.isRequired,
|
|
31518
31507
|
onFormatChange: PropTypes__default["default"].func,
|
|
31519
31508
|
checkValidity: PropTypes__default["default"].func,
|
|
31520
|
-
size: PropTypes__default["default"].
|
|
31509
|
+
size: PropTypes__default["default"].oneOf(["mini", "small", "normal"]),
|
|
31521
31510
|
label: PropTypes__default["default"].oneOf(["put your labels outside your inputs!"])
|
|
31522
31511
|
};
|
|
31523
31512
|
static defaultProps = {
|
|
@@ -31687,8 +31676,8 @@ class NumberInput extends React__namespace.Component {
|
|
|
31687
31676
|
|
|
31688
31677
|
const truth = () => true;
|
|
31689
31678
|
|
|
31690
|
-
|
|
31691
|
-
*
|
|
31679
|
+
/**
|
|
31680
|
+
* A minor abstraction on top of `NumberInput` for ranges
|
|
31692
31681
|
*/
|
|
31693
31682
|
class RangeInput extends React__namespace.Component {
|
|
31694
31683
|
static propTypes = {
|
|
@@ -32388,7 +32377,12 @@ const actions = {
|
|
|
32388
32377
|
},
|
|
32389
32378
|
polygon: {
|
|
32390
32379
|
movePoint,
|
|
32391
|
-
moveAll
|
|
32380
|
+
moveAll,
|
|
32381
|
+
addPoint,
|
|
32382
|
+
removePoint,
|
|
32383
|
+
focusPoint,
|
|
32384
|
+
blurPoint,
|
|
32385
|
+
clickPoint
|
|
32392
32386
|
},
|
|
32393
32387
|
quadratic: {
|
|
32394
32388
|
movePoint
|
|
@@ -32527,11 +32521,341 @@ function reinitialize(params) {
|
|
|
32527
32521
|
};
|
|
32528
32522
|
}
|
|
32529
32523
|
|
|
32524
|
+
/**
|
|
32525
|
+
* Wrapper with Mafs transform styles for SVG elements.
|
|
32526
|
+
* Scales and translates the SVG element to match the Mafs view.
|
|
32527
|
+
* Use if you do not need/want to use the hook in `use-transform.ts`.
|
|
32528
|
+
*/
|
|
32529
|
+
const MafsCssTransformWrapper = _ref => {
|
|
32530
|
+
let {
|
|
32531
|
+
children
|
|
32532
|
+
} = _ref;
|
|
32533
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
32534
|
+
style: {
|
|
32535
|
+
transform: `var(--mafs-view-transform) var(--mafs-user-transform)`
|
|
32536
|
+
}
|
|
32537
|
+
}, children);
|
|
32538
|
+
};
|
|
32539
|
+
|
|
32540
|
+
const TextLabel = _ref => {
|
|
32541
|
+
let {
|
|
32542
|
+
children,
|
|
32543
|
+
...rest
|
|
32544
|
+
} = _ref;
|
|
32545
|
+
return /*#__PURE__*/React__default["default"].createElement(mafs.Text, _extends({
|
|
32546
|
+
size: 16,
|
|
32547
|
+
svgTextProps: {
|
|
32548
|
+
filter: "url(#background)",
|
|
32549
|
+
fontWeight: "bold"
|
|
32550
|
+
}
|
|
32551
|
+
}, rest), children);
|
|
32552
|
+
};
|
|
32553
|
+
const SvgDefs = () => /*#__PURE__*/React__default["default"].createElement("defs", null, /*#__PURE__*/React__default["default"].createElement("filter", {
|
|
32554
|
+
id: "background",
|
|
32555
|
+
x: "-5%",
|
|
32556
|
+
width: "110%",
|
|
32557
|
+
y: "0%",
|
|
32558
|
+
height: "100%"
|
|
32559
|
+
}, /*#__PURE__*/React__default["default"].createElement("feFlood", {
|
|
32560
|
+
floodColor: "#FFF",
|
|
32561
|
+
floodOpacity: "0.64"
|
|
32562
|
+
}), /*#__PURE__*/React__default["default"].createElement("feComposite", {
|
|
32563
|
+
operator: "over",
|
|
32564
|
+
in: "SourceGraphic"
|
|
32565
|
+
})));
|
|
32566
|
+
|
|
32567
|
+
const PolygonAngle = _ref => {
|
|
32568
|
+
let {
|
|
32569
|
+
centerPoint,
|
|
32570
|
+
endPoints,
|
|
32571
|
+
range,
|
|
32572
|
+
polygonLines,
|
|
32573
|
+
showAngles,
|
|
32574
|
+
snapTo
|
|
32575
|
+
} = _ref;
|
|
32576
|
+
const [centerX, centerY] = centerPoint;
|
|
32577
|
+
const areClockwise = clockwise$1([centerPoint, ...endPoints]);
|
|
32578
|
+
const [[startX, startY], [endX, endY]] = areClockwise ? endPoints : endPoints.reverse();
|
|
32579
|
+
const radius = 0.3;
|
|
32580
|
+
const a = mafs.vec.dist(centerPoint, endPoints[0]);
|
|
32581
|
+
const b = mafs.vec.dist(centerPoint, endPoints[1]);
|
|
32582
|
+
const c = mafs.vec.dist(endPoints[0], endPoints[1]);
|
|
32583
|
+
|
|
32584
|
+
// Law of cosines
|
|
32585
|
+
const angle = Math.acos((a ** 2 + b ** 2 - c ** 2) / (2 * a * b));
|
|
32586
|
+
const y1 = centerY + (startY - centerY) / a * radius;
|
|
32587
|
+
const x2 = centerX + (endX - centerX) / b * radius;
|
|
32588
|
+
const x1 = centerX + (startX - centerX) / a * radius;
|
|
32589
|
+
const y2 = centerY + (endY - centerY) / b * radius;
|
|
32590
|
+
|
|
32591
|
+
// Fourth point that would create a rhomboid
|
|
32592
|
+
// Used to calculate the inside of the angle and to create square
|
|
32593
|
+
const [x3, y3] = mafs.vec.add(centerPoint, mafs.vec.add(mafs.vec.sub([x1, y1], centerPoint), mafs.vec.sub([x2, y2], centerPoint)));
|
|
32594
|
+
if (!showAngles) {
|
|
32595
|
+
return isRightPolygonAngle(angle) ? /*#__PURE__*/React__namespace.createElement(RightAngleSquare, {
|
|
32596
|
+
start: [x1, y1],
|
|
32597
|
+
vertex: [x2, y2],
|
|
32598
|
+
end: [x3, y3]
|
|
32599
|
+
}) : null;
|
|
32600
|
+
}
|
|
32601
|
+
|
|
32602
|
+
// Midpoint betwen ends of arc
|
|
32603
|
+
const isOutside = shouldDrawArcOutside([x3, y3], centerPoint, range, polygonLines);
|
|
32604
|
+
const largeArcFlag = isOutside ? 1 : 0;
|
|
32605
|
+
const sweepFlag = isOutside ? 1 : 0;
|
|
32606
|
+
const arc = `M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${x2} ${y2}`;
|
|
32607
|
+
let angleInDegrees = angle * (180 / Math.PI);
|
|
32608
|
+
// If we have triggered "largArcFlag", the angle should be greater than 180
|
|
32609
|
+
if (isOutside) {
|
|
32610
|
+
angleInDegrees = 360 - angleInDegrees;
|
|
32611
|
+
}
|
|
32612
|
+
|
|
32613
|
+
// Only want to show whole numbers when in angles mode
|
|
32614
|
+
const angleLabelNumber = parseFloat(angleInDegrees.toFixed(snapTo === "angles" ? 0 : 1));
|
|
32615
|
+
const angleLabel = Number.isInteger(angleLabelNumber) ? angleLabelNumber : "≈ " + angleLabelNumber;
|
|
32616
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("filter", {
|
|
32617
|
+
id: "background",
|
|
32618
|
+
x: "-5%",
|
|
32619
|
+
width: "110%",
|
|
32620
|
+
y: "0%",
|
|
32621
|
+
height: "100%"
|
|
32622
|
+
}, /*#__PURE__*/React__namespace.createElement("feFlood", {
|
|
32623
|
+
floodColor: "#FFF",
|
|
32624
|
+
floodOpacity: "0.5"
|
|
32625
|
+
}), /*#__PURE__*/React__namespace.createElement("feComposite", {
|
|
32626
|
+
operator: "over",
|
|
32627
|
+
in: "SourceGraphic"
|
|
32628
|
+
}))), !isOutside && isRightAngle(angle) ? /*#__PURE__*/React__namespace.createElement(RightAngleSquare, {
|
|
32629
|
+
start: [x1, y1],
|
|
32630
|
+
vertex: [x2, y2],
|
|
32631
|
+
end: [x3, y3]
|
|
32632
|
+
}) : /*#__PURE__*/React__namespace.createElement(Arc, {
|
|
32633
|
+
arc: arc
|
|
32634
|
+
}), /*#__PURE__*/React__namespace.createElement(TextLabel, {
|
|
32635
|
+
x: x3,
|
|
32636
|
+
y: y3,
|
|
32637
|
+
attach: y3 - centerY > 0 ? "s" : "n",
|
|
32638
|
+
attachDistance: Math.abs(y3 - centerY) < 0.2 || mafs.vec.dist([x3, y3], centerPoint) < 0.3 ? 20 : 10
|
|
32639
|
+
}, angleLabel, "\xB0"));
|
|
32640
|
+
};
|
|
32641
|
+
const Angle = _ref2 => {
|
|
32642
|
+
let {
|
|
32643
|
+
vertex,
|
|
32644
|
+
coords,
|
|
32645
|
+
showAngles,
|
|
32646
|
+
allowReflexAngles,
|
|
32647
|
+
range
|
|
32648
|
+
} = _ref2;
|
|
32649
|
+
// Check if the points are clockwise or not, depending on whether we allow reflex angles
|
|
32650
|
+
const areClockwise = clockwise$1([...coords, vertex]);
|
|
32651
|
+
const shouldReverseCoords = areClockwise && !allowReflexAngles;
|
|
32652
|
+
|
|
32653
|
+
// Reverse the coordinates accordingly to ensure the angle is calculated correctly
|
|
32654
|
+
const clockwiseCoords = shouldReverseCoords ? coords : coords.reverse();
|
|
32655
|
+
|
|
32656
|
+
// Calculate the angles between the two points
|
|
32657
|
+
const startAngle = getAngleFromVertex(clockwiseCoords[0], vertex);
|
|
32658
|
+
const endAngle = getAngleFromVertex(clockwiseCoords[1], vertex);
|
|
32659
|
+
const angle = (startAngle + 360 - endAngle) % 360;
|
|
32660
|
+
|
|
32661
|
+
// Check if the angle is reflexive
|
|
32662
|
+
const isReflexive = angle > 180;
|
|
32663
|
+
|
|
32664
|
+
// Break out the necessary points for the arc calculation
|
|
32665
|
+
const [centerX, centerY] = vertex;
|
|
32666
|
+
const [point1, point2] = clockwiseCoords;
|
|
32667
|
+
const [startX, startY] = point1;
|
|
32668
|
+
const [endX, endY] = point2;
|
|
32669
|
+
const a = mafs.vec.dist(vertex, point1);
|
|
32670
|
+
const b = mafs.vec.dist(vertex, point2);
|
|
32671
|
+
|
|
32672
|
+
// Set the radius of the arc
|
|
32673
|
+
const radius = 2;
|
|
32674
|
+
|
|
32675
|
+
// Calculate the end points of the arc
|
|
32676
|
+
const y1 = centerY + (startY - centerY) / a * radius;
|
|
32677
|
+
const x2 = centerX + (endX - centerX) / b * radius;
|
|
32678
|
+
const x1 = centerX + (startX - centerX) / a * radius;
|
|
32679
|
+
const y2 = centerY + (endY - centerY) / b * radius;
|
|
32680
|
+
|
|
32681
|
+
// Used to calculate the inside of the angle and to create square
|
|
32682
|
+
const [x3, y3] = mafs.vec.add(vertex, mafs.vec.add(mafs.vec.sub([x1, y1], vertex), mafs.vec.sub([x2, y2], vertex)));
|
|
32683
|
+
|
|
32684
|
+
// Determine whether the arc should be drawn outside the angle
|
|
32685
|
+
const isOutside = shouldDrawArcOutside([x3, y3], vertex, range, [[vertex, point1], [vertex, point2]]);
|
|
32686
|
+
|
|
32687
|
+
// Determine the flags for the arc
|
|
32688
|
+
// If the angle is outside OR reflexive, we want to draw a large arc
|
|
32689
|
+
// If the angle is outside AND reflexive, we want to sweep the arc
|
|
32690
|
+
const largeArcFlag = isOutside || isReflexive ? 1 : 0;
|
|
32691
|
+
const sweepFlag = isOutside && isReflexive ? 1 : 0;
|
|
32692
|
+
|
|
32693
|
+
// Create the SVG path for the arc
|
|
32694
|
+
const arc = `M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${x2} ${y2}`;
|
|
32695
|
+
|
|
32696
|
+
// We only ever want to show whole angles
|
|
32697
|
+
const angleLabel = parseFloat(angle.toFixed(0)); // Only want to show whole angles
|
|
32698
|
+
|
|
32699
|
+
// Calculate the text position based on the angle and whether we allow reflex angles
|
|
32700
|
+
// Let's try the angle bisector method to find the midpoint of the arc
|
|
32701
|
+
const [textX, textY] = calculateBisectorPoint(point1, point2, vertex, isReflexive, allowReflexAngles, radius);
|
|
32702
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("filter", {
|
|
32703
|
+
id: "background",
|
|
32704
|
+
x: "-5%",
|
|
32705
|
+
width: "110%",
|
|
32706
|
+
y: "0%",
|
|
32707
|
+
height: "100%"
|
|
32708
|
+
}, /*#__PURE__*/React__namespace.createElement("feFlood", {
|
|
32709
|
+
floodColor: "#FFF",
|
|
32710
|
+
floodOpacity: "0.5"
|
|
32711
|
+
}), /*#__PURE__*/React__namespace.createElement("feComposite", {
|
|
32712
|
+
operator: "over",
|
|
32713
|
+
in: "SourceGraphic"
|
|
32714
|
+
}))), isRightAngle(angle) ? /*#__PURE__*/React__namespace.createElement(RightAngleSquare, {
|
|
32715
|
+
start: [x1, y1],
|
|
32716
|
+
vertex: [x2, y2],
|
|
32717
|
+
end: [x3, y3],
|
|
32718
|
+
className: "arc-right-angle"
|
|
32719
|
+
}) : /*#__PURE__*/React__namespace.createElement(Arc, {
|
|
32720
|
+
arc: arc,
|
|
32721
|
+
className: "angle-arc"
|
|
32722
|
+
}), showAngles && /*#__PURE__*/React__namespace.createElement(TextLabel, {
|
|
32723
|
+
x: textX,
|
|
32724
|
+
y: textY,
|
|
32725
|
+
color: wonderBlocksTokens.color.blue
|
|
32726
|
+
}, angleLabel, "\xB0"));
|
|
32727
|
+
};
|
|
32728
|
+
|
|
32729
|
+
/**
|
|
32730
|
+
* This is broken out into its own component so that it can be used for an early return
|
|
32731
|
+
* (see line 55 or https://github.com/Khan/perseus/blob/84bbd882b11d16871e1b813a0b901f3b903d5479/packages/perseus/src/widgets/interactive-graphs/graphs/components/angle.tsx#L53-L57)
|
|
32732
|
+
*/
|
|
32733
|
+
const RightAngleSquare = _ref3 => {
|
|
32734
|
+
let {
|
|
32735
|
+
start: [x1, y1],
|
|
32736
|
+
vertex: [x2, y2],
|
|
32737
|
+
end: [x3, y3],
|
|
32738
|
+
className
|
|
32739
|
+
} = _ref3;
|
|
32740
|
+
return /*#__PURE__*/React__namespace.createElement(MafsCssTransformWrapper, null, /*#__PURE__*/React__namespace.createElement("path", {
|
|
32741
|
+
d: `M ${x1} ${y1} L ${x3} ${y3} M ${x3} ${y3} L ${x2} ${y2}`,
|
|
32742
|
+
strokeWidth: 0.02,
|
|
32743
|
+
fill: "none",
|
|
32744
|
+
className: className
|
|
32745
|
+
}));
|
|
32746
|
+
};
|
|
32747
|
+
|
|
32748
|
+
// We're conditionally adding the class name here so that we can style the arc differently
|
|
32749
|
+
// based on whether it's an angle or a polygon angle
|
|
32750
|
+
const Arc = _ref4 => {
|
|
32751
|
+
let {
|
|
32752
|
+
arc,
|
|
32753
|
+
className
|
|
32754
|
+
} = _ref4;
|
|
32755
|
+
return /*#__PURE__*/React__namespace.createElement(MafsCssTransformWrapper, null, /*#__PURE__*/React__namespace.createElement("path", {
|
|
32756
|
+
d: arc,
|
|
32757
|
+
strokeWidth: 0.02,
|
|
32758
|
+
fill: "none",
|
|
32759
|
+
className: className
|
|
32760
|
+
}));
|
|
32761
|
+
};
|
|
32762
|
+
const isRightPolygonAngle = angle => Math.abs(angle - Math.PI / 2) < 0.01;
|
|
32763
|
+
const isRightAngle = angle => Math.round(angle) === 90;
|
|
32764
|
+
|
|
32765
|
+
/**
|
|
32766
|
+
* Determines if an angle is an inside (false) or outside (true) angle.
|
|
32767
|
+
* They way, we know to flip the `largeArc` and `sweepArc` flags.
|
|
32768
|
+
* Uses the priciple that a ray from a point inside a polygon will intersect
|
|
32769
|
+
* with an odd number of lines, while a ray from a point outside the polygon
|
|
32770
|
+
* will intersect with an even number of lines.
|
|
32771
|
+
* https://stackoverflow.com/questions/217578/how-can-i-determine-whether-a-2d-point-is-within-a-polygon
|
|
32772
|
+
*/
|
|
32773
|
+
const shouldDrawArcOutside = (midpoint, vertex, range, polygonLines) => {
|
|
32774
|
+
// Create a ray from the midpoint (inside angle) to the edge of the range
|
|
32775
|
+
const rangeIntersectionPoint = getIntersectionOfRayWithBox(midpoint, vertex, range);
|
|
32776
|
+
let lineIntersectionCount = 0;
|
|
32777
|
+
polygonLines.forEach(line => segmentsIntersect([vertex, rangeIntersectionPoint], line) && lineIntersectionCount++);
|
|
32778
|
+
|
|
32779
|
+
// If the number of intersections is even, the angle is inside the polygon
|
|
32780
|
+
return !isEven(lineIntersectionCount);
|
|
32781
|
+
};
|
|
32782
|
+
const isEven = n => n % 2 === 0;
|
|
32783
|
+
|
|
32784
|
+
// This function calculates the bisector point of an angle formed by two points
|
|
32785
|
+
// and a vertex. It is used to position the angle label so that it is always
|
|
32786
|
+
// outside the arc at the exact midpoint of the angle.
|
|
32787
|
+
// Reflex angles make use of polar coordinates to determine the correct direction
|
|
32788
|
+
function calculateBisectorPoint(point1, point2, vertex, isReflex, allowReflex, arcRadius) {
|
|
32789
|
+
const [originX, originY] = vertex;
|
|
32790
|
+
const [x1, y1] = point1;
|
|
32791
|
+
const [x2, y2] = point2;
|
|
32792
|
+
|
|
32793
|
+
// Convert the Cartesian Coordinates to vectors
|
|
32794
|
+
const vectorA = [x1 - originX, y1 - originY];
|
|
32795
|
+
const vectorB = [x2 - originX, y2 - originY];
|
|
32796
|
+
|
|
32797
|
+
// Calculate the average angle of the vectors
|
|
32798
|
+
// so that we can point the bisector in the correct direction using polar coordinates
|
|
32799
|
+
const angleA = Math.atan2(vectorA[1], vectorA[0]);
|
|
32800
|
+
const angleB = Math.atan2(vectorB[1], vectorB[0]);
|
|
32801
|
+
|
|
32802
|
+
// Calculate the average of these two angles
|
|
32803
|
+
let averageAngle = (angleA + angleB) / 2;
|
|
32804
|
+
const angleRadians = Math.abs(angleA - angleB);
|
|
32805
|
+
|
|
32806
|
+
// Adjust the average angle to point in the correct direction
|
|
32807
|
+
// and to account for reflex angles and a bug with 180 degrees
|
|
32808
|
+
// that occurs due to our angleOffsetDegrees option in the graph
|
|
32809
|
+
if (allowReflex) {
|
|
32810
|
+
// If the resulting angles are less than 180 degrees,
|
|
32811
|
+
// or if the user has flipped the points on the interactive element
|
|
32812
|
+
// ensure that we have the correct direction for the reflex angle
|
|
32813
|
+
if (angleRadians <= Math.PI && isReflex || angleB > angleA) {
|
|
32814
|
+
averageAngle += Math.PI; // Add 180 degrees
|
|
32815
|
+
}
|
|
32816
|
+
} else {
|
|
32817
|
+
// If the resulting angles are greater than 180 degrees, adjust
|
|
32818
|
+
// to get the correct angle, as we already know that the angle is not reflexive
|
|
32819
|
+
// This fixes a bug that occurs at 180 degrees due to our angleOffsetDegrees option in the graph
|
|
32820
|
+
if (angleRadians > Math.PI) {
|
|
32821
|
+
averageAngle -= Math.PI; // Subract 180 degrees
|
|
32822
|
+
}
|
|
32823
|
+
}
|
|
32824
|
+
|
|
32825
|
+
// Convert the average angle back to Cartesian coordinates
|
|
32826
|
+
const sum = [Math.cos(averageAngle), Math.sin(averageAngle)];
|
|
32827
|
+
|
|
32828
|
+
// Calculate the magnitude of the sum to normalize it
|
|
32829
|
+
const sumMagnitude = Math.sqrt(sum[0] ** 2 + sum[1] ** 2);
|
|
32830
|
+
const bisectorDirection = [sum[0] / sumMagnitude, sum[1] / sumMagnitude];
|
|
32831
|
+
|
|
32832
|
+
// Calculate the initial distance of the bisector direction from the origin
|
|
32833
|
+
const initialDistance = Math.sqrt(bisectorDirection[0] ** 2 + bisectorDirection[1] ** 2);
|
|
32834
|
+
|
|
32835
|
+
// Determine the minimum radius to ensure that the text is always outside the arc
|
|
32836
|
+
const requiredDistance = arcRadius * 1.75;
|
|
32837
|
+
let radius = requiredDistance / initialDistance;
|
|
32838
|
+
|
|
32839
|
+
// Apply radius only if the initial distance is less than required
|
|
32840
|
+
if (initialDistance >= requiredDistance) {
|
|
32841
|
+
radius = 1; // Use the unit vector as is
|
|
32842
|
+
}
|
|
32843
|
+
|
|
32844
|
+
// Scale the bisector direction by the radius
|
|
32845
|
+
const bisectorPoint = [bisectorDirection[0] * radius, bisectorDirection[1] * radius];
|
|
32846
|
+
|
|
32847
|
+
// Add the vertex to the bisector point to get the final position
|
|
32848
|
+
// to ensure that the angle label moves with the interactive element
|
|
32849
|
+
const scaledBisector = mafs.vec.add(bisectorPoint, vertex);
|
|
32850
|
+
return scaledBisector;
|
|
32851
|
+
}
|
|
32852
|
+
|
|
32530
32853
|
/**
|
|
32531
32854
|
* 44 is touch best practice and AAA compliant for WCAG
|
|
32532
32855
|
* https://www.w3.org/WAI/WCAG21/Understanding/target-size.html
|
|
32533
32856
|
*/
|
|
32534
32857
|
const TARGET_SIZE = 44;
|
|
32858
|
+
const REMOVE_BUTTON_ID = "perseus_mafs_remove_button";
|
|
32535
32859
|
|
|
32536
32860
|
// same as pointsFromNormalized in interactive-graph.tsx
|
|
32537
32861
|
const normalizePoints = (range, step, coordsList, noSnap) => coordsList.map(coords =>
|
|
@@ -32563,6 +32887,9 @@ function bound$1(_ref) {
|
|
|
32563
32887
|
const boundingBox = inset(snapStep, range);
|
|
32564
32888
|
return clampToBox(boundingBox, point);
|
|
32565
32889
|
}
|
|
32890
|
+
function isUnlimitedGraphState(state) {
|
|
32891
|
+
return state.type === "point" && state.numPoints === "unlimited" || state.type === "polygon" && state.numSides === "unlimited";
|
|
32892
|
+
}
|
|
32566
32893
|
|
|
32567
32894
|
var isProduction = process.env.NODE_ENV === 'production';
|
|
32568
32895
|
var prefix = 'Invariant failed';
|
|
@@ -32730,6 +33057,14 @@ function range(min, max) {
|
|
|
32730
33057
|
return result;
|
|
32731
33058
|
}
|
|
32732
33059
|
|
|
33060
|
+
function srFormatNumber(a, locale) {
|
|
33061
|
+
// adding zero here converts negative zero to positive zero.
|
|
33062
|
+
return (0 + a).toLocaleString(locale, {
|
|
33063
|
+
maximumFractionDigits: 3,
|
|
33064
|
+
useGrouping: false // no thousands separators
|
|
33065
|
+
});
|
|
33066
|
+
}
|
|
33067
|
+
|
|
32733
33068
|
// The hitbox size of 48px by 48px is preserved from the legacy interactive
|
|
32734
33069
|
// graph.
|
|
32735
33070
|
const hitboxSizePx = 48;
|
|
@@ -32737,25 +33072,18 @@ const hitboxSizePx = 48;
|
|
|
32737
33072
|
// MovablePointView is a purely presentational component (i.e. it is a pure
|
|
32738
33073
|
// function with no state or effects) that renders the SVG for a movable point
|
|
32739
33074
|
// on an interactive graph.
|
|
32740
|
-
//
|
|
32741
|
-
// It has two modes for managing tabbing / focus: "controlled" (where the caller
|
|
32742
|
-
// manages the display of the focus ring, and the point itself cannot be
|
|
32743
|
-
// focused) and "uncontrolled" (where the point is focusable, and the browser
|
|
32744
|
-
// manages the focus state and styling). For context on why we did this, see
|
|
32745
|
-
// the description of https://github.com/Khan/perseus/pull/1240
|
|
32746
33075
|
const MovablePointView = /*#__PURE__*/React.forwardRef((props, hitboxRef) => {
|
|
32747
33076
|
const {
|
|
32748
33077
|
range,
|
|
32749
33078
|
markings,
|
|
32750
|
-
showTooltips
|
|
32751
|
-
disableKeyboardInteraction
|
|
33079
|
+
showTooltips
|
|
32752
33080
|
} = useGraphConfig();
|
|
32753
33081
|
const {
|
|
32754
33082
|
point,
|
|
32755
33083
|
color = wonderBlocksTokens.color.blue,
|
|
32756
33084
|
dragging,
|
|
32757
|
-
focusBehavior,
|
|
32758
33085
|
cursor,
|
|
33086
|
+
showFocusRing,
|
|
32759
33087
|
onClick = () => {}
|
|
32760
33088
|
} = props;
|
|
32761
33089
|
|
|
@@ -32765,7 +33093,7 @@ const MovablePointView = /*#__PURE__*/React.forwardRef((props, hitboxRef) => {
|
|
|
32765
33093
|
let [_, value] = _ref;
|
|
32766
33094
|
return value === color;
|
|
32767
33095
|
})?.[0] ?? "blue";
|
|
32768
|
-
const pointClasses =
|
|
33096
|
+
const pointClasses = classNames("movable-point", dragging && "movable-point--dragging", showFocusRing && "movable-point--focus");
|
|
32769
33097
|
const [[x, y]] = useTransformVectorsToPixels(point);
|
|
32770
33098
|
const [[xMin, xMax], [yMin, yMax]] = range;
|
|
32771
33099
|
const [[verticalStartX]] = useTransformVectorsToPixels([xMin, 0]);
|
|
@@ -32794,15 +33122,6 @@ const MovablePointView = /*#__PURE__*/React.forwardRef((props, hitboxRef) => {
|
|
|
32794
33122
|
cursor
|
|
32795
33123
|
},
|
|
32796
33124
|
"data-testid": "movable-point",
|
|
32797
|
-
tabIndex: disableKeyboardInteraction ? -1 : tabIndex(focusBehavior),
|
|
32798
|
-
onFocus: event => {
|
|
32799
|
-
const callback = getOnFocusChangeCallback(focusBehavior);
|
|
32800
|
-
callback && callback(event, true);
|
|
32801
|
-
},
|
|
32802
|
-
onBlur: event => {
|
|
32803
|
-
const callback = getOnFocusChangeCallback(focusBehavior);
|
|
32804
|
-
callback && callback(event, false);
|
|
32805
|
-
},
|
|
32806
33125
|
onClick: onClick
|
|
32807
33126
|
}, /*#__PURE__*/React__namespace.createElement("circle", {
|
|
32808
33127
|
className: "movable-point-hitbox",
|
|
@@ -32839,25 +33158,115 @@ const MovablePointView = /*#__PURE__*/React.forwardRef((props, hitboxRef) => {
|
|
|
32839
33158
|
}
|
|
32840
33159
|
}, svgForPoint) : svgForPoint);
|
|
32841
33160
|
});
|
|
32842
|
-
|
|
32843
|
-
|
|
32844
|
-
|
|
33161
|
+
|
|
33162
|
+
// TODO(benchristel): Move this to a more central location if it's reused.
|
|
33163
|
+
// Or install the library.
|
|
33164
|
+
function classNames() {
|
|
33165
|
+
for (var _len = arguments.length, names = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
33166
|
+
names[_key] = arguments[_key];
|
|
32845
33167
|
}
|
|
32846
|
-
return "";
|
|
33168
|
+
return names.filter(Boolean).join(" ");
|
|
32847
33169
|
}
|
|
32848
|
-
|
|
32849
|
-
|
|
32850
|
-
|
|
32851
|
-
|
|
32852
|
-
|
|
33170
|
+
|
|
33171
|
+
function useControlPoint(params) {
|
|
33172
|
+
const {
|
|
33173
|
+
snapStep,
|
|
33174
|
+
disableKeyboardInteraction
|
|
33175
|
+
} = useGraphConfig();
|
|
33176
|
+
const {
|
|
33177
|
+
point,
|
|
33178
|
+
color,
|
|
33179
|
+
cursor,
|
|
33180
|
+
constrain = p => snap(snapStep, p),
|
|
33181
|
+
onMove = noop$1,
|
|
33182
|
+
onClick = noop$1,
|
|
33183
|
+
onFocus = noop$1,
|
|
33184
|
+
onBlur = noop$1,
|
|
33185
|
+
forwardedRef = noop$1
|
|
33186
|
+
} = params;
|
|
33187
|
+
const {
|
|
33188
|
+
strings,
|
|
33189
|
+
locale
|
|
33190
|
+
} = usePerseusI18n();
|
|
33191
|
+
const [focused, setFocused] = React.useState(false);
|
|
33192
|
+
const focusableHandleRef = React.useRef(null);
|
|
33193
|
+
useDraggable({
|
|
33194
|
+
gestureTarget: focusableHandleRef,
|
|
33195
|
+
point,
|
|
33196
|
+
onMove,
|
|
33197
|
+
constrainKeyboardMovement: constrain
|
|
33198
|
+
});
|
|
33199
|
+
const visiblePointRef = React.useRef(null);
|
|
33200
|
+
const {
|
|
33201
|
+
dragging
|
|
33202
|
+
} = useDraggable({
|
|
33203
|
+
gestureTarget: visiblePointRef,
|
|
33204
|
+
point,
|
|
33205
|
+
onMove,
|
|
33206
|
+
constrainKeyboardMovement: constrain
|
|
33207
|
+
});
|
|
33208
|
+
React.useLayoutEffect(() => {
|
|
33209
|
+
setForwardedRef(forwardedRef, focusableHandleRef.current);
|
|
33210
|
+
}, [forwardedRef]);
|
|
33211
|
+
const focusableHandle = /*#__PURE__*/React__namespace.createElement("g", {
|
|
33212
|
+
"data-testid": "movable-point__focusable-handle",
|
|
33213
|
+
className: "movable-point__focusable-handle",
|
|
33214
|
+
tabIndex: disableKeyboardInteraction ? -1 : 0,
|
|
33215
|
+
ref: focusableHandleRef,
|
|
33216
|
+
role: "button",
|
|
33217
|
+
"aria-label": strings.srPointAtCoordinates({
|
|
33218
|
+
x: srFormatNumber(point[X], locale),
|
|
33219
|
+
y: srFormatNumber(point[Y], locale)
|
|
33220
|
+
})
|
|
33221
|
+
// aria-live="assertive" causes the new location of the point to be
|
|
33222
|
+
// announced immediately on move.
|
|
33223
|
+
,
|
|
33224
|
+
"aria-live": "assertive",
|
|
33225
|
+
onFocus: event => {
|
|
33226
|
+
onFocus(event);
|
|
33227
|
+
setFocused(true);
|
|
33228
|
+
},
|
|
33229
|
+
onBlur: event => {
|
|
33230
|
+
onBlur(event);
|
|
33231
|
+
setFocused(false);
|
|
33232
|
+
}
|
|
33233
|
+
});
|
|
33234
|
+
const visiblePoint = /*#__PURE__*/React__namespace.createElement(MovablePointView, {
|
|
33235
|
+
cursor: cursor,
|
|
33236
|
+
onClick: () => {
|
|
33237
|
+
onClick();
|
|
33238
|
+
focusableHandleRef.current?.focus();
|
|
33239
|
+
},
|
|
33240
|
+
point: point,
|
|
33241
|
+
dragging: dragging,
|
|
33242
|
+
color: color,
|
|
33243
|
+
ref: visiblePointRef,
|
|
33244
|
+
showFocusRing: focused
|
|
33245
|
+
});
|
|
33246
|
+
return {
|
|
33247
|
+
focusableHandle,
|
|
33248
|
+
visiblePoint,
|
|
33249
|
+
focusableHandleRef,
|
|
33250
|
+
visiblePointRef
|
|
33251
|
+
};
|
|
32853
33252
|
}
|
|
32854
|
-
|
|
32855
|
-
|
|
32856
|
-
|
|
33253
|
+
|
|
33254
|
+
// TODO(benchristel): move this to a more central place if we want to reuse it.
|
|
33255
|
+
function setForwardedRef(ref, value) {
|
|
33256
|
+
if (typeof ref === "function") {
|
|
33257
|
+
ref(value);
|
|
33258
|
+
} else if (ref !== null) {
|
|
33259
|
+
ref.current = value;
|
|
32857
33260
|
}
|
|
32858
|
-
return () => {};
|
|
32859
33261
|
}
|
|
32860
33262
|
|
|
33263
|
+
// This `noop` const is an optimization. Above, we use the forwardedRef
|
|
33264
|
+
// variable, which defaults to `noop`, in a useEffect deps array. Using `noop`
|
|
33265
|
+
// as the default value instead of `() => {}` ensures that the forwardedRef
|
|
33266
|
+
// variable will have the same value on repeated renders, preventing the
|
|
33267
|
+
// useEffect callback from re-running needlessly.
|
|
33268
|
+
const noop$1 = () => {};
|
|
33269
|
+
|
|
32861
33270
|
const MovableLine = props => {
|
|
32862
33271
|
const {
|
|
32863
33272
|
onMoveLine = () => {},
|
|
@@ -32881,11 +33290,19 @@ const MovableLine = props => {
|
|
|
32881
33290
|
const {
|
|
32882
33291
|
visiblePoint: visiblePoint1,
|
|
32883
33292
|
focusableHandle: focusableHandle1
|
|
32884
|
-
} = useControlPoint(
|
|
33293
|
+
} = useControlPoint({
|
|
33294
|
+
point: start,
|
|
33295
|
+
color,
|
|
33296
|
+
onMove: p => onMovePoint(0, p)
|
|
33297
|
+
});
|
|
32885
33298
|
const {
|
|
32886
33299
|
visiblePoint: visiblePoint2,
|
|
32887
33300
|
focusableHandle: focusableHandle2
|
|
32888
|
-
} = useControlPoint(
|
|
33301
|
+
} = useControlPoint({
|
|
33302
|
+
point: end,
|
|
33303
|
+
color,
|
|
33304
|
+
onMove: p => onMovePoint(1, p)
|
|
33305
|
+
});
|
|
32889
33306
|
const line = /*#__PURE__*/React__namespace.createElement(Line$1, {
|
|
32890
33307
|
start: start,
|
|
32891
33308
|
end: end,
|
|
@@ -32895,51 +33312,6 @@ const MovableLine = props => {
|
|
|
32895
33312
|
});
|
|
32896
33313
|
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, focusableHandle1, line, focusableHandle2, visiblePoint1, visiblePoint2);
|
|
32897
33314
|
};
|
|
32898
|
-
function useControlPoint(point, color, onMovePoint) {
|
|
32899
|
-
const {
|
|
32900
|
-
snapStep,
|
|
32901
|
-
disableKeyboardInteraction
|
|
32902
|
-
} = useGraphConfig();
|
|
32903
|
-
const [focused, setFocused] = React.useState(false);
|
|
32904
|
-
const keyboardHandleRef = React.useRef(null);
|
|
32905
|
-
useDraggable({
|
|
32906
|
-
gestureTarget: keyboardHandleRef,
|
|
32907
|
-
point,
|
|
32908
|
-
onMove: onMovePoint,
|
|
32909
|
-
constrainKeyboardMovement: p => snap(snapStep, p)
|
|
32910
|
-
});
|
|
32911
|
-
const visiblePointRef = React.useRef(null);
|
|
32912
|
-
const {
|
|
32913
|
-
dragging
|
|
32914
|
-
} = useDraggable({
|
|
32915
|
-
gestureTarget: visiblePointRef,
|
|
32916
|
-
point,
|
|
32917
|
-
onMove: onMovePoint,
|
|
32918
|
-
constrainKeyboardMovement: p => snap(snapStep, p)
|
|
32919
|
-
});
|
|
32920
|
-
const focusableHandle = /*#__PURE__*/React__namespace.createElement("g", {
|
|
32921
|
-
"data-testid": "movable-point__focusable-handle",
|
|
32922
|
-
className: "movable-point__focusable-handle",
|
|
32923
|
-
tabIndex: disableKeyboardInteraction ? -1 : 0,
|
|
32924
|
-
ref: keyboardHandleRef,
|
|
32925
|
-
onFocus: () => setFocused(true),
|
|
32926
|
-
onBlur: () => setFocused(false)
|
|
32927
|
-
});
|
|
32928
|
-
const visiblePoint = /*#__PURE__*/React__namespace.createElement(MovablePointView, {
|
|
32929
|
-
point: point,
|
|
32930
|
-
dragging: dragging,
|
|
32931
|
-
color: color,
|
|
32932
|
-
ref: visiblePointRef,
|
|
32933
|
-
focusBehavior: {
|
|
32934
|
-
type: "controlled",
|
|
32935
|
-
showFocusRing: focused
|
|
32936
|
-
}
|
|
32937
|
-
});
|
|
32938
|
-
return {
|
|
32939
|
-
focusableHandle,
|
|
32940
|
-
visiblePoint
|
|
32941
|
-
};
|
|
32942
|
-
}
|
|
32943
33315
|
const defaultStroke = "var(--movable-line-stroke-color)";
|
|
32944
33316
|
const Line$1 = props => {
|
|
32945
33317
|
const {
|
|
@@ -33029,25 +33401,351 @@ function trimRange(range, graphDimensionsInPixels) {
|
|
|
33029
33401
|
return inset([graphUnitsToTrimX, graphUnitsToTrimY], range);
|
|
33030
33402
|
}
|
|
33031
33403
|
|
|
33032
|
-
const
|
|
33404
|
+
const MovablePoint$1 = /*#__PURE__*/React__namespace.forwardRef((props, pointRef) => {
|
|
33033
33405
|
const {
|
|
33034
|
-
|
|
33406
|
+
visiblePoint,
|
|
33407
|
+
focusableHandle
|
|
33408
|
+
} = useControlPoint({
|
|
33409
|
+
...props,
|
|
33410
|
+
forwardedRef: pointRef
|
|
33411
|
+
});
|
|
33412
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, focusableHandle, visiblePoint);
|
|
33413
|
+
});
|
|
33414
|
+
|
|
33415
|
+
function renderAngleGraph(state, dispatch) {
|
|
33416
|
+
return {
|
|
33417
|
+
graph: /*#__PURE__*/React__namespace.createElement(AngleGraph, {
|
|
33418
|
+
graphState: state,
|
|
33419
|
+
dispatch: dispatch
|
|
33420
|
+
}),
|
|
33421
|
+
interactiveElementsDescription: null
|
|
33422
|
+
};
|
|
33423
|
+
}
|
|
33424
|
+
function AngleGraph(props) {
|
|
33425
|
+
const {
|
|
33426
|
+
dispatch,
|
|
33427
|
+
graphState
|
|
33035
33428
|
} = props;
|
|
33036
33429
|
const {
|
|
33037
|
-
|
|
33038
|
-
} =
|
|
33039
|
-
|
|
33040
|
-
|
|
33041
|
-
|
|
33042
|
-
|
|
33043
|
-
|
|
33044
|
-
|
|
33045
|
-
|
|
33046
|
-
|
|
33430
|
+
graphDimensionsInPixels
|
|
33431
|
+
} = useGraphConfig();
|
|
33432
|
+
const {
|
|
33433
|
+
coords,
|
|
33434
|
+
showAngles,
|
|
33435
|
+
range,
|
|
33436
|
+
allowReflexAngles,
|
|
33437
|
+
snapDegrees
|
|
33438
|
+
} = graphState;
|
|
33439
|
+
|
|
33440
|
+
// Break the coords into the two end points and the center point
|
|
33441
|
+
const endPoints = [coords[0], coords[2]];
|
|
33442
|
+
const centerPoint = coords[1];
|
|
33443
|
+
|
|
33444
|
+
// Convert the vectors to pixels for rendering the svg lines
|
|
33445
|
+
const angleLines = [[centerPoint, endPoints[0]], [centerPoint, endPoints[1]]];
|
|
33446
|
+
const linePixelCoords = [useTransformVectorsToPixels(centerPoint, endPoints[0]), useTransformVectorsToPixels(centerPoint, endPoints[1])];
|
|
33447
|
+
|
|
33448
|
+
// Create the SVG lines for the angle
|
|
33449
|
+
const svgLines = linePixelCoords.map((_ref, i) => {
|
|
33450
|
+
let [startPtPx, endPtPx] = _ref;
|
|
33451
|
+
const trimmedRange = trimRange(range, graphDimensionsInPixels);
|
|
33452
|
+
const endExtend = getIntersectionOfRayWithBox(angleLines[i][0], angleLines[i][1], trimmedRange);
|
|
33453
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
33454
|
+
key: `line-${i}`
|
|
33455
|
+
}, /*#__PURE__*/React__namespace.createElement(SVGLine, {
|
|
33456
|
+
start: startPtPx,
|
|
33457
|
+
end: endPtPx,
|
|
33458
|
+
style: {
|
|
33459
|
+
stroke: "var(--movable-line-stroke-color)",
|
|
33460
|
+
strokeWidth: "var(--movable-line-stroke-weight)"
|
|
33461
|
+
}
|
|
33462
|
+
}), /*#__PURE__*/React__namespace.createElement(Vector, {
|
|
33463
|
+
tail: angleLines[i][1],
|
|
33464
|
+
tip: endExtend,
|
|
33465
|
+
color: "var(--movable-line-stroke-color)"
|
|
33466
|
+
}));
|
|
33467
|
+
});
|
|
33468
|
+
|
|
33469
|
+
// Create the angle indicator parameters
|
|
33470
|
+
const angleParams = {
|
|
33471
|
+
vertex: centerPoint,
|
|
33472
|
+
coords: endPoints,
|
|
33473
|
+
allowReflexAngles: allowReflexAngles || false,
|
|
33474
|
+
// Whether to allow reflex angles or not
|
|
33475
|
+
snapDegrees: snapDegrees || 1,
|
|
33476
|
+
// The multiple of degrees to snap to
|
|
33477
|
+
range: range,
|
|
33478
|
+
showAngles: showAngles || false // Whether to show the angle or not
|
|
33479
|
+
};
|
|
33480
|
+
|
|
33481
|
+
// Render the lines, angle, and then movable points
|
|
33482
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, svgLines, /*#__PURE__*/React__namespace.createElement(Angle, angleParams), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
33483
|
+
point: coords[1],
|
|
33484
|
+
constrain: p => p,
|
|
33485
|
+
onMove: destination => dispatch(actions.angle.movePoint(1, destination))
|
|
33486
|
+
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
33487
|
+
point: coords[0],
|
|
33488
|
+
constrain: getAngleSideConstraint(coords[0], coords[1], snapDegrees || 1),
|
|
33489
|
+
onMove: destination => dispatch(actions.angle.movePoint(0, destination))
|
|
33490
|
+
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
33491
|
+
point: coords[2],
|
|
33492
|
+
constrain: getAngleSideConstraint(coords[2], coords[1], snapDegrees || 1),
|
|
33493
|
+
onMove: destination => dispatch(actions.angle.movePoint(2, destination))
|
|
33494
|
+
}));
|
|
33495
|
+
}
|
|
33496
|
+
const positiveX = [1, 0];
|
|
33497
|
+
const negativeX = [-1, 0];
|
|
33498
|
+
const positiveY = [0, 1];
|
|
33499
|
+
const negativeY = [0, -1];
|
|
33500
|
+
function getAngleSideConstraint(sidePoint, vertex, snapDegrees) {
|
|
33501
|
+
const currentAngle = calculateAngleInDegrees(mafs.vec.sub(sidePoint, vertex));
|
|
33502
|
+
|
|
33503
|
+
// Find the rays that start at the current point and point up, down, left
|
|
33504
|
+
// and right.
|
|
33505
|
+
const leftRay = [sidePoint, mafs.vec.add(sidePoint, negativeX)];
|
|
33506
|
+
const rightRay = [sidePoint, mafs.vec.add(sidePoint, positiveX)];
|
|
33507
|
+
const upRay = [sidePoint, mafs.vec.add(sidePoint, positiveY)];
|
|
33508
|
+
const downRay = [sidePoint, mafs.vec.add(sidePoint, negativeY)];
|
|
33509
|
+
|
|
33510
|
+
// find the angles that lie one snap step clockwise and counter-clockwise
|
|
33511
|
+
// from the current angle. These are the angles to which the side can be
|
|
33512
|
+
// moved.
|
|
33513
|
+
const oneStepCounterClockwise = currentAngle + snapDegrees;
|
|
33514
|
+
const oneStepClockwise = currentAngle - snapDegrees;
|
|
33515
|
+
|
|
33516
|
+
// find the rays that start from the vertex and point in the direction of
|
|
33517
|
+
// the angles we just computed.
|
|
33518
|
+
const counterClockwiseRay = [vertex, mafs.vec.add(vertex, polar(1, oneStepCounterClockwise))];
|
|
33519
|
+
const clockwiseRay = [vertex, mafs.vec.add(vertex, polar(1, oneStepClockwise))];
|
|
33520
|
+
|
|
33521
|
+
// find the intersections of those rays with the horizontal and vertical
|
|
33522
|
+
// rays extending from the sidePoint. These intersections are the points to
|
|
33523
|
+
// which sidePoint can move that will result in a rotation of `snapDegrees`.
|
|
33524
|
+
const left = findIntersectionOfRays(leftRay, counterClockwiseRay) ?? findIntersectionOfRays(leftRay, clockwiseRay);
|
|
33525
|
+
const right = findIntersectionOfRays(rightRay, counterClockwiseRay) ?? findIntersectionOfRays(rightRay, clockwiseRay);
|
|
33526
|
+
const up = findIntersectionOfRays(upRay, counterClockwiseRay) ?? findIntersectionOfRays(upRay, clockwiseRay);
|
|
33527
|
+
const down = findIntersectionOfRays(downRay, counterClockwiseRay) ?? findIntersectionOfRays(downRay, clockwiseRay);
|
|
33528
|
+
return {
|
|
33529
|
+
up: up ?? sidePoint,
|
|
33530
|
+
down: down ?? sidePoint,
|
|
33531
|
+
left: left ?? sidePoint,
|
|
33532
|
+
right: right ?? sidePoint
|
|
33533
|
+
};
|
|
33534
|
+
}
|
|
33535
|
+
|
|
33536
|
+
function getGradableGraph(state, initialGraph) {
|
|
33537
|
+
if (!state.hasBeenInteractedWith) {
|
|
33538
|
+
return {
|
|
33539
|
+
...initialGraph
|
|
33540
|
+
};
|
|
33541
|
+
}
|
|
33542
|
+
if (initialGraph.type === "linear-system" && state.type === "linear-system") {
|
|
33543
|
+
return {
|
|
33544
|
+
...initialGraph,
|
|
33545
|
+
coords: state.coords
|
|
33546
|
+
};
|
|
33547
|
+
}
|
|
33548
|
+
if (state.type === "segment" && initialGraph.type === "segment") {
|
|
33549
|
+
return {
|
|
33550
|
+
...initialGraph,
|
|
33551
|
+
coords: state.coords
|
|
33552
|
+
};
|
|
33553
|
+
}
|
|
33554
|
+
if (state.type === "linear" && initialGraph.type === "linear") {
|
|
33555
|
+
return {
|
|
33556
|
+
...initialGraph,
|
|
33557
|
+
coords: state.coords
|
|
33558
|
+
};
|
|
33559
|
+
}
|
|
33560
|
+
if (state.type === "ray" && initialGraph.type === "ray") {
|
|
33561
|
+
return {
|
|
33562
|
+
...initialGraph,
|
|
33563
|
+
coords: state.coords
|
|
33564
|
+
};
|
|
33565
|
+
}
|
|
33566
|
+
if (state.type === "polygon" && initialGraph.type === "polygon") {
|
|
33567
|
+
return {
|
|
33568
|
+
...initialGraph,
|
|
33569
|
+
coords: state.coords
|
|
33570
|
+
};
|
|
33571
|
+
}
|
|
33572
|
+
if (state.type === "point" && initialGraph.type === "point") {
|
|
33573
|
+
return {
|
|
33574
|
+
...initialGraph,
|
|
33575
|
+
coords: state.coords
|
|
33576
|
+
};
|
|
33577
|
+
}
|
|
33578
|
+
if (state.type === "circle" && initialGraph.type === "circle") {
|
|
33579
|
+
return {
|
|
33580
|
+
...initialGraph,
|
|
33581
|
+
center: state.center,
|
|
33582
|
+
radius: getRadius(state)
|
|
33583
|
+
};
|
|
33584
|
+
}
|
|
33585
|
+
if (state.type === "quadratic" && initialGraph.type === "quadratic") {
|
|
33586
|
+
return {
|
|
33587
|
+
...initialGraph,
|
|
33588
|
+
coords: state.coords
|
|
33589
|
+
};
|
|
33590
|
+
}
|
|
33591
|
+
if (state.type === "sinusoid" && initialGraph.type === "sinusoid") {
|
|
33592
|
+
return {
|
|
33593
|
+
...initialGraph,
|
|
33594
|
+
coords: state.coords
|
|
33595
|
+
};
|
|
33596
|
+
}
|
|
33597
|
+
if (state.type === "angle" && initialGraph.type === "angle") {
|
|
33598
|
+
// We're going to reverse the coords for scoring if the angle is clockwise and
|
|
33599
|
+
// we don't allow reflex angles. This is because the angle is largely defined
|
|
33600
|
+
// by the order of the points in the coords array, and we want to maintain
|
|
33601
|
+
// the same angle scoring with the legacy graph (which had a bug).
|
|
33602
|
+
// (LEMS-2190): When we remove the legacy graph, move this logic to the scoring function.
|
|
33603
|
+
const areClockwise = clockwise$1([state.coords[0], state.coords[2], state.coords[1]]);
|
|
33604
|
+
const shouldReverseCoords = areClockwise && !state.allowReflexAngles;
|
|
33605
|
+
const coords = shouldReverseCoords ? state.coords.slice().reverse() : state.coords;
|
|
33606
|
+
return {
|
|
33607
|
+
...initialGraph,
|
|
33608
|
+
coords,
|
|
33609
|
+
allowReflexAngles: state.allowReflexAngles
|
|
33610
|
+
};
|
|
33611
|
+
}
|
|
33612
|
+
if (state.type === "none" && initialGraph.type === "none") {
|
|
33613
|
+
return {
|
|
33614
|
+
type: "none"
|
|
33615
|
+
};
|
|
33616
|
+
}
|
|
33617
|
+
throw new Error("Mafs is not yet implemented for graph type: " + initialGraph.type);
|
|
33618
|
+
}
|
|
33619
|
+
|
|
33620
|
+
/**
|
|
33621
|
+
* determine radius of a circle graph
|
|
33622
|
+
*
|
|
33623
|
+
* @param graph - the graph object containing the circle
|
|
33624
|
+
* @returns the radius of the circle
|
|
33625
|
+
*/
|
|
33626
|
+
function getRadius(graph) {
|
|
33627
|
+
const [centerX, centerY] = graph.center;
|
|
33628
|
+
const [edgeX, edgeY] = graph.radiusPoint;
|
|
33629
|
+
return Math.sqrt(Math.pow(edgeX - centerX, 2) + Math.pow(edgeY - centerY, 2));
|
|
33630
|
+
}
|
|
33631
|
+
|
|
33632
|
+
function renderCircleGraph(state, dispatch) {
|
|
33633
|
+
return {
|
|
33634
|
+
graph: /*#__PURE__*/React__namespace.createElement(CircleGraph, {
|
|
33635
|
+
graphState: state,
|
|
33636
|
+
dispatch: dispatch
|
|
33637
|
+
}),
|
|
33638
|
+
interactiveElementsDescription: null
|
|
33639
|
+
};
|
|
33640
|
+
}
|
|
33641
|
+
function CircleGraph(props) {
|
|
33642
|
+
const {
|
|
33643
|
+
dispatch,
|
|
33644
|
+
graphState
|
|
33645
|
+
} = props;
|
|
33646
|
+
const {
|
|
33647
|
+
center,
|
|
33648
|
+
radiusPoint
|
|
33649
|
+
} = graphState;
|
|
33650
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(MovableCircle, {
|
|
33651
|
+
center: center,
|
|
33652
|
+
radius: getRadius(graphState),
|
|
33653
|
+
onMove: c => dispatch(actions.circle.moveCenter(c))
|
|
33654
|
+
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
33655
|
+
point: radiusPoint,
|
|
33656
|
+
cursor: "ew-resize",
|
|
33657
|
+
onMove: newRadiusPoint => {
|
|
33658
|
+
dispatch(actions.circle.moveRadiusPoint(newRadiusPoint));
|
|
33047
33659
|
}
|
|
33048
|
-
}))
|
|
33049
|
-
}
|
|
33660
|
+
}));
|
|
33661
|
+
}
|
|
33662
|
+
function MovableCircle(props) {
|
|
33663
|
+
const {
|
|
33664
|
+
center,
|
|
33665
|
+
radius,
|
|
33666
|
+
onMove
|
|
33667
|
+
} = props;
|
|
33668
|
+
const {
|
|
33669
|
+
snapStep,
|
|
33670
|
+
disableKeyboardInteraction
|
|
33671
|
+
} = useGraphConfig();
|
|
33672
|
+
const draggableRef = React.useRef(null);
|
|
33673
|
+
const {
|
|
33674
|
+
dragging
|
|
33675
|
+
} = useDraggable({
|
|
33676
|
+
gestureTarget: draggableRef,
|
|
33677
|
+
point: center,
|
|
33678
|
+
onMove,
|
|
33679
|
+
constrainKeyboardMovement: p => snap(snapStep, p)
|
|
33680
|
+
});
|
|
33681
|
+
const [centerPx] = useTransformVectorsToPixels(center);
|
|
33682
|
+
const [radiiPx] = useTransformDimensionsToPixels([radius, radius]);
|
|
33683
|
+
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
33684
|
+
ref: draggableRef,
|
|
33685
|
+
tabIndex: disableKeyboardInteraction ? -1 : 0,
|
|
33686
|
+
className: `movable-circle ${dragging ? "movable-circle--dragging" : ""}`
|
|
33687
|
+
}, /*#__PURE__*/React__namespace.createElement("ellipse", {
|
|
33688
|
+
className: "focus-ring",
|
|
33689
|
+
cx: centerPx[X],
|
|
33690
|
+
cy: centerPx[Y],
|
|
33691
|
+
rx: radiiPx[X] + 3,
|
|
33692
|
+
ry: radiiPx[Y] + 3
|
|
33693
|
+
}), /*#__PURE__*/React__namespace.createElement("ellipse", {
|
|
33694
|
+
className: "circle",
|
|
33695
|
+
cx: centerPx[X],
|
|
33696
|
+
cy: centerPx[Y],
|
|
33697
|
+
rx: radiiPx[X],
|
|
33698
|
+
ry: radiiPx[Y]
|
|
33699
|
+
}), /*#__PURE__*/React__namespace.createElement(DragHandle, {
|
|
33700
|
+
center: center
|
|
33701
|
+
}));
|
|
33702
|
+
}
|
|
33703
|
+
const dragHandleDimensions = [24, 14];
|
|
33704
|
+
const dragHandleDotPositions = crossProduct([-4.4, 0, 4.4], [-2.1, 2.1]);
|
|
33705
|
+
function DragHandle(props) {
|
|
33706
|
+
const {
|
|
33707
|
+
center
|
|
33708
|
+
} = props;
|
|
33709
|
+
const cornerRadius = Math.min(...dragHandleDimensions) / 2;
|
|
33710
|
+
const [centerPx] = useTransformVectorsToPixels(center);
|
|
33711
|
+
const topLeft = mafs.vec.sub(centerPx, mafs.vec.scale(dragHandleDimensions, 0.5));
|
|
33712
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("rect", {
|
|
33713
|
+
className: "movable-circle-handle",
|
|
33714
|
+
x: topLeft[X],
|
|
33715
|
+
y: topLeft[Y],
|
|
33716
|
+
width: dragHandleDimensions[X],
|
|
33717
|
+
height: dragHandleDimensions[Y],
|
|
33718
|
+
rx: cornerRadius,
|
|
33719
|
+
ry: cornerRadius
|
|
33720
|
+
}), dragHandleDotPositions.map(offsetPx => {
|
|
33721
|
+
const [xPx, yPx] = mafs.vec.add(offsetPx, centerPx);
|
|
33722
|
+
return /*#__PURE__*/React__namespace.createElement("circle", {
|
|
33723
|
+
key: `circle-${xPx}-${yPx}`,
|
|
33724
|
+
className: "movable-circle-handle-dot",
|
|
33725
|
+
cx: xPx,
|
|
33726
|
+
cy: yPx
|
|
33727
|
+
});
|
|
33728
|
+
}));
|
|
33729
|
+
}
|
|
33730
|
+
function crossProduct(as, bs) {
|
|
33731
|
+
const result = [];
|
|
33732
|
+
for (const a of as) {
|
|
33733
|
+
for (const b of bs) {
|
|
33734
|
+
result.push([a, b]);
|
|
33735
|
+
}
|
|
33736
|
+
}
|
|
33737
|
+
return result;
|
|
33738
|
+
}
|
|
33050
33739
|
|
|
33740
|
+
function renderLinearGraph(state, dispatch) {
|
|
33741
|
+
return {
|
|
33742
|
+
graph: /*#__PURE__*/React__namespace.createElement(LinearGraph, {
|
|
33743
|
+
graphState: state,
|
|
33744
|
+
dispatch: dispatch
|
|
33745
|
+
}),
|
|
33746
|
+
interactiveElementsDescription: null
|
|
33747
|
+
};
|
|
33748
|
+
}
|
|
33051
33749
|
const LinearGraph = (props, key) => {
|
|
33052
33750
|
const {
|
|
33053
33751
|
dispatch
|
|
@@ -33074,6 +33772,15 @@ const LinearGraph = (props, key) => {
|
|
|
33074
33772
|
});
|
|
33075
33773
|
};
|
|
33076
33774
|
|
|
33775
|
+
function renderLinearSystemGraph(state, dispatch) {
|
|
33776
|
+
return {
|
|
33777
|
+
graph: /*#__PURE__*/React__namespace.createElement(LinearSystemGraph, {
|
|
33778
|
+
graphState: state,
|
|
33779
|
+
dispatch: dispatch
|
|
33780
|
+
}),
|
|
33781
|
+
interactiveElementsDescription: null
|
|
33782
|
+
};
|
|
33783
|
+
}
|
|
33077
33784
|
const LinearSystemGraph = props => {
|
|
33078
33785
|
const {
|
|
33079
33786
|
dispatch
|
|
@@ -33096,412 +33803,125 @@ const LinearSystemGraph = props => {
|
|
|
33096
33803
|
})), ";");
|
|
33097
33804
|
};
|
|
33098
33805
|
|
|
33099
|
-
|
|
33806
|
+
function renderPointGraph(state, dispatch) {
|
|
33807
|
+
return {
|
|
33808
|
+
graph: /*#__PURE__*/React__namespace.createElement(PointGraph, {
|
|
33809
|
+
graphState: state,
|
|
33810
|
+
dispatch: dispatch
|
|
33811
|
+
}),
|
|
33812
|
+
interactiveElementsDescription: /*#__PURE__*/React__namespace.createElement(PointGraphDescription, {
|
|
33813
|
+
state: state
|
|
33814
|
+
})
|
|
33815
|
+
};
|
|
33816
|
+
}
|
|
33817
|
+
function PointGraph(props) {
|
|
33818
|
+
const numPoints = props.graphState.numPoints;
|
|
33819
|
+
if (numPoints === "unlimited") {
|
|
33820
|
+
return UnlimitedPointGraph(props);
|
|
33821
|
+
}
|
|
33822
|
+
return LimitedPointGraph(props);
|
|
33823
|
+
}
|
|
33824
|
+
function LimitedPointGraph(props) {
|
|
33100
33825
|
const {
|
|
33101
33826
|
dispatch
|
|
33102
33827
|
} = props;
|
|
33828
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, props.graphState.coords.map((point, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
33829
|
+
key: i,
|
|
33830
|
+
point: point,
|
|
33831
|
+
onMove: destination => dispatch(actions.pointGraph.movePoint(i, destination))
|
|
33832
|
+
})));
|
|
33833
|
+
}
|
|
33834
|
+
function UnlimitedPointGraph(props) {
|
|
33103
33835
|
const {
|
|
33104
|
-
|
|
33105
|
-
} = props
|
|
33106
|
-
const
|
|
33107
|
-
const
|
|
33108
|
-
|
|
33109
|
-
|
|
33110
|
-
|
|
33111
|
-
|
|
33112
|
-
|
|
33113
|
-
|
|
33114
|
-
|
|
33115
|
-
|
|
33116
|
-
|
|
33836
|
+
dispatch
|
|
33837
|
+
} = props;
|
|
33838
|
+
const graphConfig = useGraphConfig();
|
|
33839
|
+
const {
|
|
33840
|
+
range: [[minX, maxX], [minY, maxY]]
|
|
33841
|
+
} = graphConfig;
|
|
33842
|
+
const width = maxX - minX;
|
|
33843
|
+
const height = maxY - minY;
|
|
33844
|
+
const [[widthPx, heightPx]] = useTransformDimensionsToPixels([width, height]);
|
|
33845
|
+
const [[left, top]] = useTransformVectorsToPixels([minX, maxY]);
|
|
33846
|
+
const itemsRef = React__namespace.useRef([]);
|
|
33847
|
+
React__namespace.useEffect(() => {
|
|
33848
|
+
const focusedIndex = props.graphState.focusedPointIndex;
|
|
33849
|
+
if (focusedIndex != null) {
|
|
33850
|
+
itemsRef.current[focusedIndex]?.focus();
|
|
33117
33851
|
}
|
|
33118
|
-
});
|
|
33119
|
-
|
|
33120
|
-
|
|
33121
|
-
/**
|
|
33122
|
-
* Wrapper with Mafs transform styles for SVG elements.
|
|
33123
|
-
* Scales and translates the SVG element to match the Mafs view.
|
|
33124
|
-
* Use if you do not need/want to use the hook in `use-transform.ts`.
|
|
33125
|
-
*/
|
|
33126
|
-
const MafsCssTransformWrapper = _ref => {
|
|
33127
|
-
let {
|
|
33128
|
-
children
|
|
33129
|
-
} = _ref;
|
|
33130
|
-
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
33852
|
+
}, [props.graphState.focusedPointIndex, itemsRef]);
|
|
33853
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("rect", {
|
|
33131
33854
|
style: {
|
|
33132
|
-
|
|
33855
|
+
fill: "rgba(0,0,0,0)",
|
|
33856
|
+
cursor: "crosshair"
|
|
33857
|
+
},
|
|
33858
|
+
width: widthPx,
|
|
33859
|
+
height: heightPx,
|
|
33860
|
+
x: left,
|
|
33861
|
+
y: top,
|
|
33862
|
+
onClick: event => {
|
|
33863
|
+
const elementRect = event.currentTarget.getBoundingClientRect();
|
|
33864
|
+
const x = event.clientX - elementRect.x;
|
|
33865
|
+
const y = event.clientY - elementRect.y;
|
|
33866
|
+
const graphCoordinates = pixelsToVectors([[x, y]], graphConfig);
|
|
33867
|
+
dispatch(actions.pointGraph.addPoint(graphCoordinates[0]));
|
|
33133
33868
|
}
|
|
33134
|
-
},
|
|
33135
|
-
|
|
33136
|
-
|
|
33137
|
-
|
|
33138
|
-
|
|
33139
|
-
|
|
33140
|
-
|
|
33141
|
-
|
|
33142
|
-
|
|
33143
|
-
|
|
33144
|
-
|
|
33145
|
-
|
|
33146
|
-
fontWeight: "bold"
|
|
33869
|
+
}), props.graphState.coords.map((point, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
33870
|
+
key: i,
|
|
33871
|
+
point: point,
|
|
33872
|
+
onMove: destination => dispatch(actions.pointGraph.movePoint(i, destination)),
|
|
33873
|
+
ref: ref => {
|
|
33874
|
+
itemsRef.current[i] = ref;
|
|
33875
|
+
},
|
|
33876
|
+
onFocus: () => {
|
|
33877
|
+
dispatch(actions.pointGraph.focusPoint(i));
|
|
33878
|
+
},
|
|
33879
|
+
onClick: () => {
|
|
33880
|
+
dispatch(actions.pointGraph.clickPoint(i));
|
|
33147
33881
|
}
|
|
33148
|
-
}
|
|
33149
|
-
}
|
|
33150
|
-
|
|
33151
|
-
id: "background",
|
|
33152
|
-
x: "-5%",
|
|
33153
|
-
width: "110%",
|
|
33154
|
-
y: "0%",
|
|
33155
|
-
height: "100%"
|
|
33156
|
-
}, /*#__PURE__*/React__default["default"].createElement("feFlood", {
|
|
33157
|
-
floodColor: "#FFF",
|
|
33158
|
-
floodOpacity: "0.64"
|
|
33159
|
-
}), /*#__PURE__*/React__default["default"].createElement("feComposite", {
|
|
33160
|
-
operator: "over",
|
|
33161
|
-
in: "SourceGraphic"
|
|
33162
|
-
})));
|
|
33163
|
-
|
|
33164
|
-
const PolygonAngle = _ref => {
|
|
33882
|
+
})));
|
|
33883
|
+
}
|
|
33884
|
+
function PointGraphDescription(_ref) {
|
|
33165
33885
|
let {
|
|
33166
|
-
|
|
33167
|
-
endPoints,
|
|
33168
|
-
range,
|
|
33169
|
-
polygonLines,
|
|
33170
|
-
showAngles,
|
|
33171
|
-
snapTo
|
|
33886
|
+
state
|
|
33172
33887
|
} = _ref;
|
|
33173
|
-
|
|
33174
|
-
|
|
33175
|
-
const
|
|
33176
|
-
|
|
33177
|
-
const a = mafs.vec.dist(centerPoint, endPoints[0]);
|
|
33178
|
-
const b = mafs.vec.dist(centerPoint, endPoints[1]);
|
|
33179
|
-
const c = mafs.vec.dist(endPoints[0], endPoints[1]);
|
|
33180
|
-
|
|
33181
|
-
// Law of cosines
|
|
33182
|
-
const angle = Math.acos((a ** 2 + b ** 2 - c ** 2) / (2 * a * b));
|
|
33183
|
-
const y1 = centerY + (startY - centerY) / a * radius;
|
|
33184
|
-
const x2 = centerX + (endX - centerX) / b * radius;
|
|
33185
|
-
const x1 = centerX + (startX - centerX) / a * radius;
|
|
33186
|
-
const y2 = centerY + (endY - centerY) / b * radius;
|
|
33187
|
-
|
|
33188
|
-
// Fourth point that would create a rhomboid
|
|
33189
|
-
// Used to calculate the inside of the angle and to create square
|
|
33190
|
-
const [x3, y3] = mafs.vec.add(centerPoint, mafs.vec.add(mafs.vec.sub([x1, y1], centerPoint), mafs.vec.sub([x2, y2], centerPoint)));
|
|
33191
|
-
if (!showAngles) {
|
|
33192
|
-
return isRightPolygonAngle(angle) ? /*#__PURE__*/React__namespace.createElement(RightAngleSquare, {
|
|
33193
|
-
start: [x1, y1],
|
|
33194
|
-
vertex: [x2, y2],
|
|
33195
|
-
end: [x3, y3]
|
|
33196
|
-
}) : null;
|
|
33197
|
-
}
|
|
33198
|
-
|
|
33199
|
-
// Midpoint betwen ends of arc
|
|
33200
|
-
const isOutside = shouldDrawArcOutside([x3, y3], centerPoint, range, polygonLines);
|
|
33201
|
-
const largeArcFlag = isOutside ? 1 : 0;
|
|
33202
|
-
const sweepFlag = isOutside ? 1 : 0;
|
|
33203
|
-
const arc = `M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${x2} ${y2}`;
|
|
33204
|
-
let angleInDegrees = angle * (180 / Math.PI);
|
|
33205
|
-
// If we have triggered "largArcFlag", the angle should be greater than 180
|
|
33206
|
-
if (isOutside) {
|
|
33207
|
-
angleInDegrees = 360 - angleInDegrees;
|
|
33208
|
-
}
|
|
33209
|
-
|
|
33210
|
-
// Only want to show whole numbers when in angles mode
|
|
33211
|
-
const angleLabelNumber = parseFloat(angleInDegrees.toFixed(snapTo === "angles" ? 0 : 1));
|
|
33212
|
-
const angleLabel = Number.isInteger(angleLabelNumber) ? angleLabelNumber : "≈ " + angleLabelNumber;
|
|
33213
|
-
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("filter", {
|
|
33214
|
-
id: "background",
|
|
33215
|
-
x: "-5%",
|
|
33216
|
-
width: "110%",
|
|
33217
|
-
y: "0%",
|
|
33218
|
-
height: "100%"
|
|
33219
|
-
}, /*#__PURE__*/React__namespace.createElement("feFlood", {
|
|
33220
|
-
floodColor: "#FFF",
|
|
33221
|
-
floodOpacity: "0.5"
|
|
33222
|
-
}), /*#__PURE__*/React__namespace.createElement("feComposite", {
|
|
33223
|
-
operator: "over",
|
|
33224
|
-
in: "SourceGraphic"
|
|
33225
|
-
}))), !isOutside && isRightAngle(angle) ? /*#__PURE__*/React__namespace.createElement(RightAngleSquare, {
|
|
33226
|
-
start: [x1, y1],
|
|
33227
|
-
vertex: [x2, y2],
|
|
33228
|
-
end: [x3, y3]
|
|
33229
|
-
}) : /*#__PURE__*/React__namespace.createElement(Arc, {
|
|
33230
|
-
arc: arc
|
|
33231
|
-
}), /*#__PURE__*/React__namespace.createElement(TextLabel, {
|
|
33232
|
-
x: x3,
|
|
33233
|
-
y: y3,
|
|
33234
|
-
attach: y3 - centerY > 0 ? "s" : "n",
|
|
33235
|
-
attachDistance: Math.abs(y3 - centerY) < 0.2 || mafs.vec.dist([x3, y3], centerPoint) < 0.3 ? 20 : 10
|
|
33236
|
-
}, angleLabel, "\xB0"));
|
|
33237
|
-
};
|
|
33238
|
-
const Angle = _ref2 => {
|
|
33239
|
-
let {
|
|
33240
|
-
vertex,
|
|
33241
|
-
coords,
|
|
33242
|
-
showAngles,
|
|
33243
|
-
allowReflexAngles,
|
|
33244
|
-
range
|
|
33245
|
-
} = _ref2;
|
|
33246
|
-
// Check if the points are clockwise or not, depending on whether we allow reflex angles
|
|
33247
|
-
const areClockwise = clockwise$1([...coords, vertex]);
|
|
33248
|
-
const shouldReverseCoords = areClockwise && !allowReflexAngles;
|
|
33249
|
-
|
|
33250
|
-
// Reverse the coordinates accordingly to ensure the angle is calculated correctly
|
|
33251
|
-
const clockwiseCoords = shouldReverseCoords ? coords : coords.reverse();
|
|
33252
|
-
|
|
33253
|
-
// Calculate the angles between the two points
|
|
33254
|
-
const startAngle = getAngleFromVertex(clockwiseCoords[0], vertex);
|
|
33255
|
-
const endAngle = getAngleFromVertex(clockwiseCoords[1], vertex);
|
|
33256
|
-
const angle = (startAngle + 360 - endAngle) % 360;
|
|
33257
|
-
|
|
33258
|
-
// Check if the angle is reflexive
|
|
33259
|
-
const isReflexive = angle > 180;
|
|
33260
|
-
|
|
33261
|
-
// Break out the necessary points for the arc calculation
|
|
33262
|
-
const [centerX, centerY] = vertex;
|
|
33263
|
-
const [point1, point2] = clockwiseCoords;
|
|
33264
|
-
const [startX, startY] = point1;
|
|
33265
|
-
const [endX, endY] = point2;
|
|
33266
|
-
const a = mafs.vec.dist(vertex, point1);
|
|
33267
|
-
const b = mafs.vec.dist(vertex, point2);
|
|
33268
|
-
|
|
33269
|
-
// Set the radius of the arc
|
|
33270
|
-
const radius = 2;
|
|
33271
|
-
|
|
33272
|
-
// Calculate the end points of the arc
|
|
33273
|
-
const y1 = centerY + (startY - centerY) / a * radius;
|
|
33274
|
-
const x2 = centerX + (endX - centerX) / b * radius;
|
|
33275
|
-
const x1 = centerX + (startX - centerX) / a * radius;
|
|
33276
|
-
const y2 = centerY + (endY - centerY) / b * radius;
|
|
33277
|
-
|
|
33278
|
-
// Used to calculate the inside of the angle and to create square
|
|
33279
|
-
const [x3, y3] = mafs.vec.add(vertex, mafs.vec.add(mafs.vec.sub([x1, y1], vertex), mafs.vec.sub([x2, y2], vertex)));
|
|
33280
|
-
|
|
33281
|
-
// Determine whether the arc should be drawn outside the angle
|
|
33282
|
-
const isOutside = shouldDrawArcOutside([x3, y3], vertex, range, [[vertex, point1], [vertex, point2]]);
|
|
33283
|
-
|
|
33284
|
-
// Determine the flags for the arc
|
|
33285
|
-
// If the angle is outside OR reflexive, we want to draw a large arc
|
|
33286
|
-
// If the angle is outside AND reflexive, we want to sweep the arc
|
|
33287
|
-
const largeArcFlag = isOutside || isReflexive ? 1 : 0;
|
|
33288
|
-
const sweepFlag = isOutside && isReflexive ? 1 : 0;
|
|
33289
|
-
|
|
33290
|
-
// Create the SVG path for the arc
|
|
33291
|
-
const arc = `M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${x2} ${y2}`;
|
|
33292
|
-
|
|
33293
|
-
// We only ever want to show whole angles
|
|
33294
|
-
const angleLabel = parseFloat(angle.toFixed(0)); // Only want to show whole angles
|
|
33295
|
-
|
|
33296
|
-
// Calculate the text position based on the angle and whether we allow reflex angles
|
|
33297
|
-
// Let's try the angle bisector method to find the midpoint of the arc
|
|
33298
|
-
const [textX, textY] = calculateBisectorPoint(point1, point2, vertex, isReflexive, allowReflexAngles, radius);
|
|
33299
|
-
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("defs", null, /*#__PURE__*/React__namespace.createElement("filter", {
|
|
33300
|
-
id: "background",
|
|
33301
|
-
x: "-5%",
|
|
33302
|
-
width: "110%",
|
|
33303
|
-
y: "0%",
|
|
33304
|
-
height: "100%"
|
|
33305
|
-
}, /*#__PURE__*/React__namespace.createElement("feFlood", {
|
|
33306
|
-
floodColor: "#FFF",
|
|
33307
|
-
floodOpacity: "0.5"
|
|
33308
|
-
}), /*#__PURE__*/React__namespace.createElement("feComposite", {
|
|
33309
|
-
operator: "over",
|
|
33310
|
-
in: "SourceGraphic"
|
|
33311
|
-
}))), isRightAngle(angle) ? /*#__PURE__*/React__namespace.createElement(RightAngleSquare, {
|
|
33312
|
-
start: [x1, y1],
|
|
33313
|
-
vertex: [x2, y2],
|
|
33314
|
-
end: [x3, y3],
|
|
33315
|
-
className: "arc-right-angle"
|
|
33316
|
-
}) : /*#__PURE__*/React__namespace.createElement(Arc, {
|
|
33317
|
-
arc: arc,
|
|
33318
|
-
className: "angle-arc"
|
|
33319
|
-
}), showAngles && /*#__PURE__*/React__namespace.createElement(TextLabel, {
|
|
33320
|
-
x: textX,
|
|
33321
|
-
y: textY,
|
|
33322
|
-
color: wonderBlocksTokens.color.blue
|
|
33323
|
-
}, angleLabel, "\xB0"));
|
|
33324
|
-
};
|
|
33325
|
-
|
|
33326
|
-
/**
|
|
33327
|
-
* This is broken out into its own component so that it can be used for an early return
|
|
33328
|
-
* (see line 55 or https://github.com/Khan/perseus/blob/84bbd882b11d16871e1b813a0b901f3b903d5479/packages/perseus/src/widgets/interactive-graphs/graphs/components/angle.tsx#L53-L57)
|
|
33329
|
-
*/
|
|
33330
|
-
const RightAngleSquare = _ref3 => {
|
|
33331
|
-
let {
|
|
33332
|
-
start: [x1, y1],
|
|
33333
|
-
vertex: [x2, y2],
|
|
33334
|
-
end: [x3, y3],
|
|
33335
|
-
className
|
|
33336
|
-
} = _ref3;
|
|
33337
|
-
return /*#__PURE__*/React__namespace.createElement(MafsCssTransformWrapper, null, /*#__PURE__*/React__namespace.createElement("path", {
|
|
33338
|
-
d: `M ${x1} ${y1} L ${x3} ${y3} M ${x3} ${y3} L ${x2} ${y2}`,
|
|
33339
|
-
strokeWidth: 0.02,
|
|
33340
|
-
fill: "none",
|
|
33341
|
-
className: className
|
|
33342
|
-
}));
|
|
33343
|
-
};
|
|
33344
|
-
|
|
33345
|
-
// We're conditionally adding the class name here so that we can style the arc differently
|
|
33346
|
-
// based on whether it's an angle or a polygon angle
|
|
33347
|
-
const Arc = _ref4 => {
|
|
33348
|
-
let {
|
|
33349
|
-
arc,
|
|
33350
|
-
className
|
|
33351
|
-
} = _ref4;
|
|
33352
|
-
return /*#__PURE__*/React__namespace.createElement(MafsCssTransformWrapper, null, /*#__PURE__*/React__namespace.createElement("path", {
|
|
33353
|
-
d: arc,
|
|
33354
|
-
strokeWidth: 0.02,
|
|
33355
|
-
fill: "none",
|
|
33356
|
-
className: className
|
|
33357
|
-
}));
|
|
33358
|
-
};
|
|
33359
|
-
const isRightPolygonAngle = angle => Math.abs(angle - Math.PI / 2) < 0.01;
|
|
33360
|
-
const isRightAngle = angle => Math.round(angle) === 90;
|
|
33361
|
-
|
|
33362
|
-
/**
|
|
33363
|
-
* Determines if an angle is an inside (false) or outside (true) angle.
|
|
33364
|
-
* They way, we know to flip the `largeArc` and `sweepArc` flags.
|
|
33365
|
-
* Uses the priciple that a ray from a point inside a polygon will intersect
|
|
33366
|
-
* with an odd number of lines, while a ray from a point outside the polygon
|
|
33367
|
-
* will intersect with an even number of lines.
|
|
33368
|
-
* https://stackoverflow.com/questions/217578/how-can-i-determine-whether-a-2d-point-is-within-a-polygon
|
|
33369
|
-
*/
|
|
33370
|
-
const shouldDrawArcOutside = (midpoint, vertex, range, polygonLines) => {
|
|
33371
|
-
// Create a ray from the midpoint (inside angle) to the edge of the range
|
|
33372
|
-
const rangeIntersectionPoint = getIntersectionOfRayWithBox(midpoint, vertex, range);
|
|
33373
|
-
let lineIntersectionCount = 0;
|
|
33374
|
-
polygonLines.forEach(line => segmentsIntersect([vertex, rangeIntersectionPoint], line) && lineIntersectionCount++);
|
|
33375
|
-
|
|
33376
|
-
// If the number of intersections is even, the angle is inside the polygon
|
|
33377
|
-
return !isEven(lineIntersectionCount);
|
|
33378
|
-
};
|
|
33379
|
-
const isEven = n => n % 2 === 0;
|
|
33380
|
-
|
|
33381
|
-
// This function calculates the bisector point of an angle formed by two points
|
|
33382
|
-
// and a vertex. It is used to position the angle label so that it is always
|
|
33383
|
-
// outside the arc at the exact midpoint of the angle.
|
|
33384
|
-
// Reflex angles make use of polar coordinates to determine the correct direction
|
|
33385
|
-
function calculateBisectorPoint(point1, point2, vertex, isReflex, allowReflex, arcRadius) {
|
|
33386
|
-
const [originX, originY] = vertex;
|
|
33387
|
-
const [x1, y1] = point1;
|
|
33388
|
-
const [x2, y2] = point2;
|
|
33389
|
-
|
|
33390
|
-
// Convert the Cartesian Coordinates to vectors
|
|
33391
|
-
const vectorA = [x1 - originX, y1 - originY];
|
|
33392
|
-
const vectorB = [x2 - originX, y2 - originY];
|
|
33393
|
-
|
|
33394
|
-
// Calculate the average angle of the vectors
|
|
33395
|
-
// so that we can point the bisector in the correct direction using polar coordinates
|
|
33396
|
-
const angleA = Math.atan2(vectorA[1], vectorA[0]);
|
|
33397
|
-
const angleB = Math.atan2(vectorB[1], vectorB[0]);
|
|
33398
|
-
|
|
33399
|
-
// Calculate the average of these two angles
|
|
33400
|
-
let averageAngle = (angleA + angleB) / 2;
|
|
33401
|
-
const angleRadians = Math.abs(angleA - angleB);
|
|
33402
|
-
|
|
33403
|
-
// Adjust the average angle to point in the correct direction
|
|
33404
|
-
// and to account for reflex angles and a bug with 180 degrees
|
|
33405
|
-
// that occurs due to our angleOffsetDegrees option in the graph
|
|
33406
|
-
if (allowReflex) {
|
|
33407
|
-
// If the resulting angles are less than 180 degrees,
|
|
33408
|
-
// or if the user has flipped the points on the interactive element
|
|
33409
|
-
// ensure that we have the correct direction for the reflex angle
|
|
33410
|
-
if (angleRadians <= Math.PI && isReflex || angleB > angleA) {
|
|
33411
|
-
averageAngle += Math.PI; // Add 180 degrees
|
|
33412
|
-
}
|
|
33413
|
-
} else {
|
|
33414
|
-
// If the resulting angles are greater than 180 degrees, adjust
|
|
33415
|
-
// to get the correct angle, as we already know that the angle is not reflexive
|
|
33416
|
-
// This fixes a bug that occurs at 180 degrees due to our angleOffsetDegrees option in the graph
|
|
33417
|
-
if (angleRadians > Math.PI) {
|
|
33418
|
-
averageAngle -= Math.PI; // Subract 180 degrees
|
|
33419
|
-
}
|
|
33420
|
-
}
|
|
33421
|
-
|
|
33422
|
-
// Convert the average angle back to Cartesian coordinates
|
|
33423
|
-
const sum = [Math.cos(averageAngle), Math.sin(averageAngle)];
|
|
33424
|
-
|
|
33425
|
-
// Calculate the magnitude of the sum to normalize it
|
|
33426
|
-
const sumMagnitude = Math.sqrt(sum[0] ** 2 + sum[1] ** 2);
|
|
33427
|
-
const bisectorDirection = [sum[0] / sumMagnitude, sum[1] / sumMagnitude];
|
|
33428
|
-
|
|
33429
|
-
// Calculate the initial distance of the bisector direction from the origin
|
|
33430
|
-
const initialDistance = Math.sqrt(bisectorDirection[0] ** 2 + bisectorDirection[1] ** 2);
|
|
33431
|
-
|
|
33432
|
-
// Determine the minimum radius to ensure that the text is always outside the arc
|
|
33433
|
-
const requiredDistance = arcRadius * 1.75;
|
|
33434
|
-
let radius = requiredDistance / initialDistance;
|
|
33435
|
-
|
|
33436
|
-
// Apply radius only if the initial distance is less than required
|
|
33437
|
-
if (initialDistance >= requiredDistance) {
|
|
33438
|
-
radius = 1; // Use the unit vector as is
|
|
33439
|
-
}
|
|
33440
|
-
|
|
33441
|
-
// Scale the bisector direction by the radius
|
|
33442
|
-
const bisectorPoint = [bisectorDirection[0] * radius, bisectorDirection[1] * radius];
|
|
33443
|
-
|
|
33444
|
-
// Add the vertex to the bisector point to get the final position
|
|
33445
|
-
// to ensure that the angle label moves with the interactive element
|
|
33446
|
-
const scaledBisector = mafs.vec.add(bisectorPoint, vertex);
|
|
33447
|
-
return scaledBisector;
|
|
33888
|
+
// PointGraphDescription needs to `usePerseusI18n`, so it has to be a
|
|
33889
|
+
// component rather than a function that simply returns a string.
|
|
33890
|
+
const i18n = usePerseusI18n();
|
|
33891
|
+
return describePointGraph(state, i18n);
|
|
33448
33892
|
}
|
|
33449
33893
|
|
|
33450
|
-
|
|
33894
|
+
// Exported for testing
|
|
33895
|
+
function describePointGraph(state, i18n) {
|
|
33451
33896
|
const {
|
|
33452
|
-
|
|
33453
|
-
|
|
33454
|
-
|
|
33455
|
-
|
|
33456
|
-
|
|
33457
|
-
|
|
33458
|
-
|
|
33459
|
-
|
|
33460
|
-
|
|
33461
|
-
|
|
33462
|
-
|
|
33463
|
-
|
|
33464
|
-
const {
|
|
33465
|
-
dragging
|
|
33466
|
-
} = useDraggable({
|
|
33467
|
-
gestureTarget: elementRef,
|
|
33468
|
-
point,
|
|
33469
|
-
onMove,
|
|
33470
|
-
constrainKeyboardMovement: constrain
|
|
33897
|
+
strings,
|
|
33898
|
+
locale
|
|
33899
|
+
} = i18n;
|
|
33900
|
+
if (state.coords.length === 0) {
|
|
33901
|
+
return strings.srNoInteractiveElements;
|
|
33902
|
+
}
|
|
33903
|
+
const pointDescriptions = state.coords.map(_ref2 => {
|
|
33904
|
+
let [x, y] = _ref2;
|
|
33905
|
+
return strings.srPointAtCoordinates({
|
|
33906
|
+
x: srFormatNumber(x, locale),
|
|
33907
|
+
y: srFormatNumber(y, locale)
|
|
33908
|
+
});
|
|
33471
33909
|
});
|
|
33472
|
-
return
|
|
33473
|
-
|
|
33474
|
-
// Note: This handles the case where pointRef is either a
|
|
33475
|
-
// function or a MutableRefObject. Mostly this is to satisfy
|
|
33476
|
-
// the type system, the function branch seems to be the only
|
|
33477
|
-
// one that occurs
|
|
33478
|
-
if (typeof pointRef === "function") {
|
|
33479
|
-
pointRef(ref);
|
|
33480
|
-
} else if (pointRef !== null) {
|
|
33481
|
-
pointRef.current = ref;
|
|
33482
|
-
}
|
|
33483
|
-
|
|
33484
|
-
// This ref is for the useDraggable and is not passed up the
|
|
33485
|
-
// chain
|
|
33486
|
-
elementRef.current = ref;
|
|
33487
|
-
},
|
|
33488
|
-
point: point,
|
|
33489
|
-
color: color,
|
|
33490
|
-
dragging: dragging,
|
|
33491
|
-
focusBehavior: {
|
|
33492
|
-
type: "uncontrolled",
|
|
33493
|
-
tabIndex: 0,
|
|
33494
|
-
onFocusChange
|
|
33495
|
-
},
|
|
33496
|
-
onClick: () => {
|
|
33497
|
-
onClick && onClick();
|
|
33498
|
-
elementRef.current?.focus();
|
|
33499
|
-
},
|
|
33500
|
-
cursor: cursor
|
|
33910
|
+
return strings.srInteractiveElements({
|
|
33911
|
+
elements: pointDescriptions.join(", ")
|
|
33501
33912
|
});
|
|
33502
|
-
}
|
|
33913
|
+
}
|
|
33503
33914
|
|
|
33504
|
-
|
|
33915
|
+
function renderPolygonGraph(state, dispatch) {
|
|
33916
|
+
return {
|
|
33917
|
+
graph: /*#__PURE__*/React__namespace.createElement(PolygonGraph, {
|
|
33918
|
+
graphState: state,
|
|
33919
|
+
dispatch: dispatch
|
|
33920
|
+
}),
|
|
33921
|
+
interactiveElementsDescription: null
|
|
33922
|
+
};
|
|
33923
|
+
}
|
|
33924
|
+
const LimitedPolygonGraph = props => {
|
|
33505
33925
|
const [hovered, setHovered] = React__namespace.useState(false);
|
|
33506
33926
|
// This is more so required for the re-rendering that occurs when state
|
|
33507
33927
|
// updates; specifically with regard to line weighting and polygon focus.
|
|
@@ -33613,6 +34033,153 @@ const PolygonGraph = props => {
|
|
|
33613
34033
|
}
|
|
33614
34034
|
})));
|
|
33615
34035
|
};
|
|
34036
|
+
|
|
34037
|
+
// TODO(catjohnson): reduce redundancy between LimitedPolygonGraph and UnlimitedPolygonGraph
|
|
34038
|
+
// both components are vary similar, however more implementation is needed to be added before
|
|
34039
|
+
// it is clear what can and can't be shared between components.
|
|
34040
|
+
const UnlimitedPolygonGraph = props => {
|
|
34041
|
+
const [hovered, setHovered] = React__namespace.useState(false);
|
|
34042
|
+
// This is more so required for the re-rendering that occurs when state
|
|
34043
|
+
// updates; specifically with regard to line weighting and polygon focus.
|
|
34044
|
+
const [focusVisible, setFocusVisible] = React__namespace.useState(false);
|
|
34045
|
+
const {
|
|
34046
|
+
dispatch
|
|
34047
|
+
} = props;
|
|
34048
|
+
const {
|
|
34049
|
+
coords,
|
|
34050
|
+
showAngles,
|
|
34051
|
+
showSides,
|
|
34052
|
+
range,
|
|
34053
|
+
snapStep,
|
|
34054
|
+
snapTo = "grid"
|
|
34055
|
+
} = props.graphState;
|
|
34056
|
+
const graphConfig = useGraphConfig();
|
|
34057
|
+
|
|
34058
|
+
// TODO(catjohnson): Explore abstracting this code as it is similar to point.tsx
|
|
34059
|
+
// and hopefully we can cut down ont the unlimited graph redundancy.
|
|
34060
|
+
const {
|
|
34061
|
+
range: [x, y],
|
|
34062
|
+
disableKeyboardInteraction,
|
|
34063
|
+
graphDimensionsInPixels
|
|
34064
|
+
} = graphConfig;
|
|
34065
|
+
const widthPx = graphDimensionsInPixels[0];
|
|
34066
|
+
const heightPx = graphDimensionsInPixels[1];
|
|
34067
|
+
const [[left, top]] = useTransformVectorsToPixels([x[0], y[1]]);
|
|
34068
|
+
const pointRef = React__namespace.useRef([]);
|
|
34069
|
+
|
|
34070
|
+
// TODO(benchristel): can the default set of points be removed here? I don't
|
|
34071
|
+
// think coords can be null.
|
|
34072
|
+
const points = coords ?? [[0, 0]];
|
|
34073
|
+
const polygonRef = React__namespace.useRef(null);
|
|
34074
|
+
const dragReferencePoint = points[0];
|
|
34075
|
+
const constrain = ["angles", "sides"].includes(snapTo) ? p => p : p => snap(snapStep, p);
|
|
34076
|
+
const {
|
|
34077
|
+
dragging
|
|
34078
|
+
} = useDraggable({
|
|
34079
|
+
gestureTarget: polygonRef,
|
|
34080
|
+
point: dragReferencePoint,
|
|
34081
|
+
onMove: newPoint => {
|
|
34082
|
+
const delta = mafs.vec.sub(newPoint, dragReferencePoint);
|
|
34083
|
+
dispatch(actions.polygon.moveAll(delta));
|
|
34084
|
+
},
|
|
34085
|
+
constrainKeyboardMovement: constrain
|
|
34086
|
+
});
|
|
34087
|
+
const lines = getLines(points);
|
|
34088
|
+
React__namespace.useEffect(() => {
|
|
34089
|
+
const focusedIndex = props.graphState.focusedPointIndex;
|
|
34090
|
+
if (focusedIndex != null) {
|
|
34091
|
+
pointRef.current[focusedIndex]?.focus();
|
|
34092
|
+
}
|
|
34093
|
+
}, [props.graphState.focusedPointIndex, pointRef]);
|
|
34094
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("rect", {
|
|
34095
|
+
style: {
|
|
34096
|
+
fill: "rgba(0,0,0,0)",
|
|
34097
|
+
cursor: "crosshair"
|
|
34098
|
+
},
|
|
34099
|
+
width: widthPx,
|
|
34100
|
+
height: heightPx,
|
|
34101
|
+
x: left,
|
|
34102
|
+
y: top,
|
|
34103
|
+
onClick: event => {
|
|
34104
|
+
const elementRect = event.currentTarget.getBoundingClientRect();
|
|
34105
|
+
const x = event.clientX - elementRect.x;
|
|
34106
|
+
const y = event.clientY - elementRect.y;
|
|
34107
|
+
const graphCoordinates = pixelsToVectors([[x, y]], graphConfig);
|
|
34108
|
+
dispatch(actions.polygon.addPoint(graphCoordinates[0]));
|
|
34109
|
+
}
|
|
34110
|
+
}), /*#__PURE__*/React__namespace.createElement(mafs.Polygon, {
|
|
34111
|
+
points: [...points],
|
|
34112
|
+
color: "var(--movable-line-stroke-color)",
|
|
34113
|
+
svgPolygonProps: {
|
|
34114
|
+
strokeWidth: focusVisible ? "var(--movable-line-stroke-weight-active)" : "var(--movable-line-stroke-weight)",
|
|
34115
|
+
style: {
|
|
34116
|
+
fill: "transparent"
|
|
34117
|
+
}
|
|
34118
|
+
}
|
|
34119
|
+
}), props.graphState.coords.map((point, i) => {
|
|
34120
|
+
const pt1 = points.at(i - 1);
|
|
34121
|
+
const pt2 = points[(i + 1) % points.length];
|
|
34122
|
+
if (!pt1 || !pt2) {
|
|
34123
|
+
return null;
|
|
34124
|
+
}
|
|
34125
|
+
return /*#__PURE__*/React__namespace.createElement(PolygonAngle, {
|
|
34126
|
+
key: "angle-" + i,
|
|
34127
|
+
centerPoint: point,
|
|
34128
|
+
endPoints: [pt1, pt2],
|
|
34129
|
+
range: range,
|
|
34130
|
+
polygonLines: lines,
|
|
34131
|
+
showAngles: !!showAngles,
|
|
34132
|
+
snapTo: snapTo
|
|
34133
|
+
});
|
|
34134
|
+
}), showSides && lines.map((_ref2, i) => {
|
|
34135
|
+
let [start, end] = _ref2;
|
|
34136
|
+
const [x, y] = mafs.vec.midpoint(start, end);
|
|
34137
|
+
const length = parseFloat(mafs.vec.dist(start, end).toFixed(snapTo === "sides" ? 0 : 1));
|
|
34138
|
+
return /*#__PURE__*/React__namespace.createElement(TextLabel, {
|
|
34139
|
+
key: "side-" + i,
|
|
34140
|
+
x: x,
|
|
34141
|
+
y: y
|
|
34142
|
+
}, !Number.isInteger(length) && "≈ ", length);
|
|
34143
|
+
}), /*#__PURE__*/React__namespace.createElement(mafs.Polygon, {
|
|
34144
|
+
points: [...points],
|
|
34145
|
+
color: "transparent",
|
|
34146
|
+
svgPolygonProps: {
|
|
34147
|
+
ref: polygonRef,
|
|
34148
|
+
tabIndex: disableKeyboardInteraction ? -1 : 0,
|
|
34149
|
+
strokeWidth: TARGET_SIZE,
|
|
34150
|
+
style: {
|
|
34151
|
+
cursor: dragging ? "grabbing" : "grab",
|
|
34152
|
+
fill: hovered ? "var(--mafs-blue)" : "transparent"
|
|
34153
|
+
},
|
|
34154
|
+
onMouseEnter: () => setHovered(true),
|
|
34155
|
+
onMouseLeave: () => setHovered(false),
|
|
34156
|
+
// Required to remove line weighting when user clicks away
|
|
34157
|
+
// from the focused polygon
|
|
34158
|
+
onKeyDownCapture: () => {
|
|
34159
|
+
setFocusVisible(hasFocusVisible(polygonRef.current));
|
|
34160
|
+
},
|
|
34161
|
+
// Required for lines to darken on focus
|
|
34162
|
+
onFocus: () => setFocusVisible(hasFocusVisible(polygonRef.current)),
|
|
34163
|
+
// Required for line weighting to update on blur. Without this,
|
|
34164
|
+
// the user has to hover over the shape for it to update
|
|
34165
|
+
onBlur: () => setFocusVisible(hasFocusVisible(polygonRef.current)),
|
|
34166
|
+
className: "movable-polygon"
|
|
34167
|
+
}
|
|
34168
|
+
}), props.graphState.coords.map((point, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
34169
|
+
key: i,
|
|
34170
|
+
point: point,
|
|
34171
|
+
onMove: destination => dispatch(actions.pointGraph.movePoint(i, destination)),
|
|
34172
|
+
ref: ref => {
|
|
34173
|
+
pointRef.current[i] = ref;
|
|
34174
|
+
},
|
|
34175
|
+
onFocus: () => {
|
|
34176
|
+
dispatch(actions.pointGraph.focusPoint(i));
|
|
34177
|
+
},
|
|
34178
|
+
onClick: () => {
|
|
34179
|
+
dispatch(actions.pointGraph.clickPoint(i));
|
|
34180
|
+
}
|
|
34181
|
+
})));
|
|
34182
|
+
};
|
|
33616
34183
|
function getLines(points) {
|
|
33617
34184
|
return points.map((point, i) => {
|
|
33618
34185
|
const next = points[(i + 1) % points.length];
|
|
@@ -33630,202 +34197,20 @@ const hasFocusVisible = element => {
|
|
|
33630
34197
|
return matches(":focus");
|
|
33631
34198
|
}
|
|
33632
34199
|
};
|
|
34200
|
+
const PolygonGraph = props => {
|
|
34201
|
+
const numSides = props.graphState.numSides;
|
|
34202
|
+
return numSides === "unlimited" ? UnlimitedPolygonGraph(props) : LimitedPolygonGraph(props);
|
|
34203
|
+
};
|
|
33633
34204
|
|
|
33634
|
-
function
|
|
33635
|
-
|
|
33636
|
-
|
|
33637
|
-
|
|
33638
|
-
|
|
33639
|
-
|
|
33640
|
-
|
|
33641
|
-
|
|
33642
|
-
...initialGraph,
|
|
33643
|
-
coords: state.coords
|
|
33644
|
-
};
|
|
33645
|
-
}
|
|
33646
|
-
if (state.type === "segment" && initialGraph.type === "segment") {
|
|
33647
|
-
return {
|
|
33648
|
-
...initialGraph,
|
|
33649
|
-
coords: state.coords
|
|
33650
|
-
};
|
|
33651
|
-
}
|
|
33652
|
-
if (state.type === "linear" && initialGraph.type === "linear") {
|
|
33653
|
-
return {
|
|
33654
|
-
...initialGraph,
|
|
33655
|
-
coords: state.coords
|
|
33656
|
-
};
|
|
33657
|
-
}
|
|
33658
|
-
if (state.type === "ray" && initialGraph.type === "ray") {
|
|
33659
|
-
return {
|
|
33660
|
-
...initialGraph,
|
|
33661
|
-
coords: state.coords
|
|
33662
|
-
};
|
|
33663
|
-
}
|
|
33664
|
-
if (state.type === "polygon" && initialGraph.type === "polygon") {
|
|
33665
|
-
return {
|
|
33666
|
-
...initialGraph,
|
|
33667
|
-
coords: state.coords
|
|
33668
|
-
};
|
|
33669
|
-
}
|
|
33670
|
-
if (state.type === "point" && initialGraph.type === "point") {
|
|
33671
|
-
return {
|
|
33672
|
-
...initialGraph,
|
|
33673
|
-
coords: state.coords
|
|
33674
|
-
};
|
|
33675
|
-
}
|
|
33676
|
-
if (state.type === "circle" && initialGraph.type === "circle") {
|
|
33677
|
-
return {
|
|
33678
|
-
...initialGraph,
|
|
33679
|
-
center: state.center,
|
|
33680
|
-
radius: getRadius(state)
|
|
33681
|
-
};
|
|
33682
|
-
}
|
|
33683
|
-
if (state.type === "quadratic" && initialGraph.type === "quadratic") {
|
|
33684
|
-
return {
|
|
33685
|
-
...initialGraph,
|
|
33686
|
-
coords: state.coords
|
|
33687
|
-
};
|
|
33688
|
-
}
|
|
33689
|
-
if (state.type === "sinusoid" && initialGraph.type === "sinusoid") {
|
|
33690
|
-
return {
|
|
33691
|
-
...initialGraph,
|
|
33692
|
-
coords: state.coords
|
|
33693
|
-
};
|
|
33694
|
-
}
|
|
33695
|
-
if (state.type === "angle" && initialGraph.type === "angle") {
|
|
33696
|
-
// We're going to reverse the coords for scoring if the angle is clockwise and
|
|
33697
|
-
// we don't allow reflex angles. This is because the angle is largely defined
|
|
33698
|
-
// by the order of the points in the coords array, and we want to maintain
|
|
33699
|
-
// the same angle scoring with the legacy graph (which had a bug).
|
|
33700
|
-
// (LEMS-2190): When we remove the legacy graph, move this logic to the scoring function.
|
|
33701
|
-
const areClockwise = clockwise$1([state.coords[0], state.coords[2], state.coords[1]]);
|
|
33702
|
-
const shouldReverseCoords = areClockwise && !state.allowReflexAngles;
|
|
33703
|
-
const coords = shouldReverseCoords ? state.coords.slice().reverse() : state.coords;
|
|
33704
|
-
return {
|
|
33705
|
-
...initialGraph,
|
|
33706
|
-
coords,
|
|
33707
|
-
allowReflexAngles: state.allowReflexAngles
|
|
33708
|
-
};
|
|
33709
|
-
}
|
|
33710
|
-
if (state.type === "none" && initialGraph.type === "none") {
|
|
33711
|
-
return {
|
|
33712
|
-
type: "none"
|
|
33713
|
-
};
|
|
33714
|
-
}
|
|
33715
|
-
throw new Error("Mafs is not yet implemented for graph type: " + initialGraph.type);
|
|
33716
|
-
}
|
|
33717
|
-
|
|
33718
|
-
/**
|
|
33719
|
-
* determine radius of a circle graph
|
|
33720
|
-
*
|
|
33721
|
-
* @param graph - the graph object containing the circle
|
|
33722
|
-
* @returns the radius of the circle
|
|
33723
|
-
*/
|
|
33724
|
-
function getRadius(graph) {
|
|
33725
|
-
const [centerX, centerY] = graph.center;
|
|
33726
|
-
const [edgeX, edgeY] = graph.radiusPoint;
|
|
33727
|
-
return Math.sqrt(Math.pow(edgeX - centerX, 2) + Math.pow(edgeY - centerY, 2));
|
|
33728
|
-
}
|
|
33729
|
-
|
|
33730
|
-
function CircleGraph(props) {
|
|
33731
|
-
const {
|
|
33732
|
-
dispatch,
|
|
33733
|
-
graphState
|
|
33734
|
-
} = props;
|
|
33735
|
-
const {
|
|
33736
|
-
center,
|
|
33737
|
-
radiusPoint
|
|
33738
|
-
} = graphState;
|
|
33739
|
-
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(MovableCircle, {
|
|
33740
|
-
center: center,
|
|
33741
|
-
radius: getRadius(graphState),
|
|
33742
|
-
onMove: c => dispatch(actions.circle.moveCenter(c))
|
|
33743
|
-
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
33744
|
-
point: radiusPoint,
|
|
33745
|
-
cursor: "ew-resize",
|
|
33746
|
-
onMove: newRadiusPoint => {
|
|
33747
|
-
dispatch(actions.circle.moveRadiusPoint(newRadiusPoint));
|
|
33748
|
-
}
|
|
33749
|
-
}));
|
|
33750
|
-
}
|
|
33751
|
-
function MovableCircle(props) {
|
|
33752
|
-
const {
|
|
33753
|
-
center,
|
|
33754
|
-
radius,
|
|
33755
|
-
onMove
|
|
33756
|
-
} = props;
|
|
33757
|
-
const {
|
|
33758
|
-
snapStep,
|
|
33759
|
-
disableKeyboardInteraction
|
|
33760
|
-
} = useGraphConfig();
|
|
33761
|
-
const draggableRef = React.useRef(null);
|
|
33762
|
-
const {
|
|
33763
|
-
dragging
|
|
33764
|
-
} = useDraggable({
|
|
33765
|
-
gestureTarget: draggableRef,
|
|
33766
|
-
point: center,
|
|
33767
|
-
onMove,
|
|
33768
|
-
constrainKeyboardMovement: p => snap(snapStep, p)
|
|
33769
|
-
});
|
|
33770
|
-
const [centerPx] = useTransformVectorsToPixels(center);
|
|
33771
|
-
const [radiiPx] = useTransformDimensionsToPixels([radius, radius]);
|
|
33772
|
-
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
33773
|
-
ref: draggableRef,
|
|
33774
|
-
tabIndex: disableKeyboardInteraction ? -1 : 0,
|
|
33775
|
-
className: `movable-circle ${dragging ? "movable-circle--dragging" : ""}`
|
|
33776
|
-
}, /*#__PURE__*/React__namespace.createElement("ellipse", {
|
|
33777
|
-
className: "focus-ring",
|
|
33778
|
-
cx: centerPx[X],
|
|
33779
|
-
cy: centerPx[Y],
|
|
33780
|
-
rx: radiiPx[X] + 3,
|
|
33781
|
-
ry: radiiPx[Y] + 3
|
|
33782
|
-
}), /*#__PURE__*/React__namespace.createElement("ellipse", {
|
|
33783
|
-
className: "circle",
|
|
33784
|
-
cx: centerPx[X],
|
|
33785
|
-
cy: centerPx[Y],
|
|
33786
|
-
rx: radiiPx[X],
|
|
33787
|
-
ry: radiiPx[Y]
|
|
33788
|
-
}), /*#__PURE__*/React__namespace.createElement(DragHandle, {
|
|
33789
|
-
center: center
|
|
33790
|
-
}));
|
|
33791
|
-
}
|
|
33792
|
-
const dragHandleDimensions = [24, 14];
|
|
33793
|
-
const dragHandleDotPositions = crossProduct([-4.4, 0, 4.4], [-2.1, 2.1]);
|
|
33794
|
-
function DragHandle(props) {
|
|
33795
|
-
const {
|
|
33796
|
-
center
|
|
33797
|
-
} = props;
|
|
33798
|
-
const cornerRadius = Math.min(...dragHandleDimensions) / 2;
|
|
33799
|
-
const [centerPx] = useTransformVectorsToPixels(center);
|
|
33800
|
-
const topLeft = mafs.vec.sub(centerPx, mafs.vec.scale(dragHandleDimensions, 0.5));
|
|
33801
|
-
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("rect", {
|
|
33802
|
-
className: "movable-circle-handle",
|
|
33803
|
-
x: topLeft[X],
|
|
33804
|
-
y: topLeft[Y],
|
|
33805
|
-
width: dragHandleDimensions[X],
|
|
33806
|
-
height: dragHandleDimensions[Y],
|
|
33807
|
-
rx: cornerRadius,
|
|
33808
|
-
ry: cornerRadius
|
|
33809
|
-
}), dragHandleDotPositions.map(offsetPx => {
|
|
33810
|
-
const [xPx, yPx] = mafs.vec.add(offsetPx, centerPx);
|
|
33811
|
-
return /*#__PURE__*/React__namespace.createElement("circle", {
|
|
33812
|
-
key: `circle-${xPx}-${yPx}`,
|
|
33813
|
-
className: "movable-circle-handle-dot",
|
|
33814
|
-
cx: xPx,
|
|
33815
|
-
cy: yPx
|
|
33816
|
-
});
|
|
33817
|
-
}));
|
|
33818
|
-
}
|
|
33819
|
-
function crossProduct(as, bs) {
|
|
33820
|
-
const result = [];
|
|
33821
|
-
for (const a of as) {
|
|
33822
|
-
for (const b of bs) {
|
|
33823
|
-
result.push([a, b]);
|
|
33824
|
-
}
|
|
33825
|
-
}
|
|
33826
|
-
return result;
|
|
34205
|
+
function renderQuadraticGraph(state, dispatch) {
|
|
34206
|
+
return {
|
|
34207
|
+
graph: /*#__PURE__*/React__namespace.createElement(QuadraticGraph, {
|
|
34208
|
+
graphState: state,
|
|
34209
|
+
dispatch: dispatch
|
|
34210
|
+
}),
|
|
34211
|
+
interactiveElementsDescription: null
|
|
34212
|
+
};
|
|
33827
34213
|
}
|
|
33828
|
-
|
|
33829
34214
|
function QuadraticGraph(props) {
|
|
33830
34215
|
const {
|
|
33831
34216
|
dispatch,
|
|
@@ -33880,6 +34265,74 @@ const getQuadraticCoefficients$1 = coords => {
|
|
|
33880
34265
|
return [a, b, c];
|
|
33881
34266
|
};
|
|
33882
34267
|
|
|
34268
|
+
function renderRayGraph(state, dispatch) {
|
|
34269
|
+
return {
|
|
34270
|
+
graph: /*#__PURE__*/React__namespace.createElement(RayGraph, {
|
|
34271
|
+
graphState: state,
|
|
34272
|
+
dispatch: dispatch
|
|
34273
|
+
}),
|
|
34274
|
+
interactiveElementsDescription: null
|
|
34275
|
+
};
|
|
34276
|
+
}
|
|
34277
|
+
const RayGraph = props => {
|
|
34278
|
+
const {
|
|
34279
|
+
dispatch
|
|
34280
|
+
} = props;
|
|
34281
|
+
const {
|
|
34282
|
+
coords: line
|
|
34283
|
+
} = props.graphState;
|
|
34284
|
+
const handleMoveLine = delta => dispatch(actions.ray.moveRay(delta));
|
|
34285
|
+
const handleMovePoint = (pointIndex, newPoint) => dispatch(actions.ray.movePoint(pointIndex, newPoint));
|
|
34286
|
+
|
|
34287
|
+
// Ray graphs only have one line
|
|
34288
|
+
return /*#__PURE__*/React__namespace.createElement(MovableLine, {
|
|
34289
|
+
points: line,
|
|
34290
|
+
onMoveLine: handleMoveLine,
|
|
34291
|
+
onMovePoint: handleMovePoint,
|
|
34292
|
+
extend: {
|
|
34293
|
+
start: false,
|
|
34294
|
+
end: true
|
|
34295
|
+
}
|
|
34296
|
+
});
|
|
34297
|
+
};
|
|
34298
|
+
|
|
34299
|
+
function renderSegmentGraph(state, dispatch) {
|
|
34300
|
+
return {
|
|
34301
|
+
graph: /*#__PURE__*/React__namespace.createElement(SegmentGraph, {
|
|
34302
|
+
graphState: state,
|
|
34303
|
+
dispatch: dispatch
|
|
34304
|
+
}),
|
|
34305
|
+
interactiveElementsDescription: null
|
|
34306
|
+
};
|
|
34307
|
+
}
|
|
34308
|
+
const SegmentGraph = props => {
|
|
34309
|
+
const {
|
|
34310
|
+
dispatch
|
|
34311
|
+
} = props;
|
|
34312
|
+
const {
|
|
34313
|
+
coords: segments
|
|
34314
|
+
} = props.graphState;
|
|
34315
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, segments?.map((segment, i) => /*#__PURE__*/React__namespace.createElement(MovableLine, {
|
|
34316
|
+
key: i,
|
|
34317
|
+
points: segment,
|
|
34318
|
+
onMoveLine: delta => {
|
|
34319
|
+
dispatch(actions.segment.moveLine(i, delta));
|
|
34320
|
+
},
|
|
34321
|
+
onMovePoint: (endpointIndex, destination) => {
|
|
34322
|
+
dispatch(actions.segment.movePointInFigure(i, endpointIndex, destination));
|
|
34323
|
+
}
|
|
34324
|
+
})));
|
|
34325
|
+
};
|
|
34326
|
+
|
|
34327
|
+
function renderSinusoidGraph(state, dispatch) {
|
|
34328
|
+
return {
|
|
34329
|
+
graph: /*#__PURE__*/React__namespace.createElement(SinusoidGraph, {
|
|
34330
|
+
graphState: state,
|
|
34331
|
+
dispatch: dispatch
|
|
34332
|
+
}),
|
|
34333
|
+
interactiveElementsDescription: null
|
|
34334
|
+
};
|
|
34335
|
+
}
|
|
33883
34336
|
function SinusoidGraph(props) {
|
|
33884
34337
|
const {
|
|
33885
34338
|
dispatch,
|
|
@@ -33955,201 +34408,6 @@ const getSinusoidCoefficients$1 = coords => {
|
|
|
33955
34408
|
};
|
|
33956
34409
|
};
|
|
33957
34410
|
|
|
33958
|
-
function AngleGraph(props) {
|
|
33959
|
-
const {
|
|
33960
|
-
dispatch,
|
|
33961
|
-
graphState
|
|
33962
|
-
} = props;
|
|
33963
|
-
const {
|
|
33964
|
-
graphDimensionsInPixels
|
|
33965
|
-
} = useGraphConfig();
|
|
33966
|
-
const {
|
|
33967
|
-
coords,
|
|
33968
|
-
showAngles,
|
|
33969
|
-
range,
|
|
33970
|
-
allowReflexAngles,
|
|
33971
|
-
snapDegrees
|
|
33972
|
-
} = graphState;
|
|
33973
|
-
|
|
33974
|
-
// Break the coords into the two end points and the center point
|
|
33975
|
-
const endPoints = [coords[0], coords[2]];
|
|
33976
|
-
const centerPoint = coords[1];
|
|
33977
|
-
|
|
33978
|
-
// Convert the vectors to pixels for rendering the svg lines
|
|
33979
|
-
const angleLines = [[centerPoint, endPoints[0]], [centerPoint, endPoints[1]]];
|
|
33980
|
-
const linePixelCoords = [useTransformVectorsToPixels(centerPoint, endPoints[0]), useTransformVectorsToPixels(centerPoint, endPoints[1])];
|
|
33981
|
-
|
|
33982
|
-
// Create the SVG lines for the angle
|
|
33983
|
-
const svgLines = linePixelCoords.map((_ref, i) => {
|
|
33984
|
-
let [startPtPx, endPtPx] = _ref;
|
|
33985
|
-
const trimmedRange = trimRange(range, graphDimensionsInPixels);
|
|
33986
|
-
const endExtend = getIntersectionOfRayWithBox(angleLines[i][0], angleLines[i][1], trimmedRange);
|
|
33987
|
-
return /*#__PURE__*/React__namespace.createElement("g", {
|
|
33988
|
-
key: `line-${i}`
|
|
33989
|
-
}, /*#__PURE__*/React__namespace.createElement(SVGLine, {
|
|
33990
|
-
start: startPtPx,
|
|
33991
|
-
end: endPtPx,
|
|
33992
|
-
style: {
|
|
33993
|
-
stroke: "var(--movable-line-stroke-color)",
|
|
33994
|
-
strokeWidth: "var(--movable-line-stroke-weight)"
|
|
33995
|
-
}
|
|
33996
|
-
}), /*#__PURE__*/React__namespace.createElement(Vector, {
|
|
33997
|
-
tail: angleLines[i][1],
|
|
33998
|
-
tip: endExtend,
|
|
33999
|
-
color: "var(--movable-line-stroke-color)"
|
|
34000
|
-
}));
|
|
34001
|
-
});
|
|
34002
|
-
|
|
34003
|
-
// Create the angle indicator parameters
|
|
34004
|
-
const angleParams = {
|
|
34005
|
-
vertex: centerPoint,
|
|
34006
|
-
coords: endPoints,
|
|
34007
|
-
allowReflexAngles: allowReflexAngles || false,
|
|
34008
|
-
// Whether to allow reflex angles or not
|
|
34009
|
-
snapDegrees: snapDegrees || 1,
|
|
34010
|
-
// The multiple of degrees to snap to
|
|
34011
|
-
range: range,
|
|
34012
|
-
showAngles: showAngles || false // Whether to show the angle or not
|
|
34013
|
-
};
|
|
34014
|
-
|
|
34015
|
-
// Render the lines, angle, and then movable points
|
|
34016
|
-
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, svgLines, /*#__PURE__*/React__namespace.createElement(Angle, angleParams), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
34017
|
-
point: coords[1],
|
|
34018
|
-
constrain: p => p,
|
|
34019
|
-
onMove: destination => dispatch(actions.angle.movePoint(1, destination))
|
|
34020
|
-
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
34021
|
-
point: coords[0],
|
|
34022
|
-
constrain: getAngleSideConstraint(coords[0], coords[1], snapDegrees || 1),
|
|
34023
|
-
onMove: destination => dispatch(actions.angle.movePoint(0, destination))
|
|
34024
|
-
}), /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
34025
|
-
point: coords[2],
|
|
34026
|
-
constrain: getAngleSideConstraint(coords[2], coords[1], snapDegrees || 1),
|
|
34027
|
-
onMove: destination => dispatch(actions.angle.movePoint(2, destination))
|
|
34028
|
-
}));
|
|
34029
|
-
}
|
|
34030
|
-
const positiveX = [1, 0];
|
|
34031
|
-
const negativeX = [-1, 0];
|
|
34032
|
-
const positiveY = [0, 1];
|
|
34033
|
-
const negativeY = [0, -1];
|
|
34034
|
-
function getAngleSideConstraint(sidePoint, vertex, snapDegrees) {
|
|
34035
|
-
const currentAngle = calculateAngleInDegrees(mafs.vec.sub(sidePoint, vertex));
|
|
34036
|
-
|
|
34037
|
-
// Find the rays that start at the current point and point up, down, left
|
|
34038
|
-
// and right.
|
|
34039
|
-
const leftRay = [sidePoint, mafs.vec.add(sidePoint, negativeX)];
|
|
34040
|
-
const rightRay = [sidePoint, mafs.vec.add(sidePoint, positiveX)];
|
|
34041
|
-
const upRay = [sidePoint, mafs.vec.add(sidePoint, positiveY)];
|
|
34042
|
-
const downRay = [sidePoint, mafs.vec.add(sidePoint, negativeY)];
|
|
34043
|
-
|
|
34044
|
-
// find the angles that lie one snap step clockwise and counter-clockwise
|
|
34045
|
-
// from the current angle. These are the angles to which the side can be
|
|
34046
|
-
// moved.
|
|
34047
|
-
const oneStepCounterClockwise = currentAngle + snapDegrees;
|
|
34048
|
-
const oneStepClockwise = currentAngle - snapDegrees;
|
|
34049
|
-
|
|
34050
|
-
// find the rays that start from the vertex and point in the direction of
|
|
34051
|
-
// the angles we just computed.
|
|
34052
|
-
const counterClockwiseRay = [vertex, mafs.vec.add(vertex, polar(1, oneStepCounterClockwise))];
|
|
34053
|
-
const clockwiseRay = [vertex, mafs.vec.add(vertex, polar(1, oneStepClockwise))];
|
|
34054
|
-
|
|
34055
|
-
// find the intersections of those rays with the horizontal and vertical
|
|
34056
|
-
// rays extending from the sidePoint. These intersections are the points to
|
|
34057
|
-
// which sidePoint can move that will result in a rotation of `snapDegrees`.
|
|
34058
|
-
const left = findIntersectionOfRays(leftRay, counterClockwiseRay) ?? findIntersectionOfRays(leftRay, clockwiseRay);
|
|
34059
|
-
const right = findIntersectionOfRays(rightRay, counterClockwiseRay) ?? findIntersectionOfRays(rightRay, clockwiseRay);
|
|
34060
|
-
const up = findIntersectionOfRays(upRay, counterClockwiseRay) ?? findIntersectionOfRays(upRay, clockwiseRay);
|
|
34061
|
-
const down = findIntersectionOfRays(downRay, counterClockwiseRay) ?? findIntersectionOfRays(downRay, clockwiseRay);
|
|
34062
|
-
return {
|
|
34063
|
-
up: up ?? sidePoint,
|
|
34064
|
-
down: down ?? sidePoint,
|
|
34065
|
-
left: left ?? sidePoint,
|
|
34066
|
-
right: right ?? sidePoint
|
|
34067
|
-
};
|
|
34068
|
-
}
|
|
34069
|
-
|
|
34070
|
-
function LimitedPointGraph(props) {
|
|
34071
|
-
const {
|
|
34072
|
-
dispatch
|
|
34073
|
-
} = props;
|
|
34074
|
-
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, props.graphState.coords.map((point, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
34075
|
-
key: i,
|
|
34076
|
-
point: point,
|
|
34077
|
-
onMove: destination => dispatch(actions.pointGraph.movePoint(i, destination))
|
|
34078
|
-
})));
|
|
34079
|
-
}
|
|
34080
|
-
function UnlimitedPointGraph(props) {
|
|
34081
|
-
const {
|
|
34082
|
-
dispatch
|
|
34083
|
-
} = props;
|
|
34084
|
-
const graphState = useGraphConfig();
|
|
34085
|
-
const {
|
|
34086
|
-
range: [[minX, maxX], [minY, maxY]]
|
|
34087
|
-
} = graphState;
|
|
34088
|
-
const width = maxX - minX;
|
|
34089
|
-
const height = maxY - minY;
|
|
34090
|
-
const [[widthPx, heightPx]] = useTransformDimensionsToPixels([width, height]);
|
|
34091
|
-
const [[left, top]] = useTransformVectorsToPixels([minX, maxY]);
|
|
34092
|
-
const itemsRef = React__namespace.useRef([]);
|
|
34093
|
-
React__namespace.useEffect(() => {
|
|
34094
|
-
const focusedIndex = props.graphState.focusedPointIndex;
|
|
34095
|
-
if (focusedIndex != null) {
|
|
34096
|
-
itemsRef.current[focusedIndex]?.focus();
|
|
34097
|
-
}
|
|
34098
|
-
}, [props.graphState.focusedPointIndex, itemsRef]);
|
|
34099
|
-
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement("rect", {
|
|
34100
|
-
style: {
|
|
34101
|
-
fill: "rgba(0,0,0,0)",
|
|
34102
|
-
cursor: "crosshair"
|
|
34103
|
-
},
|
|
34104
|
-
width: widthPx,
|
|
34105
|
-
height: heightPx,
|
|
34106
|
-
x: left,
|
|
34107
|
-
y: top,
|
|
34108
|
-
onClick: event => {
|
|
34109
|
-
const elementRect = event.currentTarget.getBoundingClientRect();
|
|
34110
|
-
const x = event.clientX - elementRect.x;
|
|
34111
|
-
const y = event.clientY - elementRect.y;
|
|
34112
|
-
const graphCoordinates = pixelsToVectors([[x, y]], graphState);
|
|
34113
|
-
dispatch(actions.pointGraph.addPoint(graphCoordinates[0]));
|
|
34114
|
-
}
|
|
34115
|
-
}), props.graphState.coords.map((point, i) => /*#__PURE__*/React__namespace.createElement(MovablePoint$1, {
|
|
34116
|
-
key: i,
|
|
34117
|
-
point: point,
|
|
34118
|
-
onMove: destination => dispatch(actions.pointGraph.movePoint(i, destination)),
|
|
34119
|
-
ref: ref => {
|
|
34120
|
-
itemsRef.current[i] = ref;
|
|
34121
|
-
},
|
|
34122
|
-
onFocusChange: (event, isFocused) => {
|
|
34123
|
-
if (isFocused) {
|
|
34124
|
-
dispatch(actions.pointGraph.focusPoint(i));
|
|
34125
|
-
} else {
|
|
34126
|
-
if (event.relatedTarget?.id === REMOVE_BUTTON_ID) {
|
|
34127
|
-
return;
|
|
34128
|
-
// This is an optimization: If the next target
|
|
34129
|
-
// is a point then don't blur because it casues
|
|
34130
|
-
// the remove button to get taken off the page
|
|
34131
|
-
// and then put back on The new point will
|
|
34132
|
-
// receive focus and set the correct state in
|
|
34133
|
-
// the reducer
|
|
34134
|
-
} else if (event.relatedTarget?.classList.contains("movable-point")) {
|
|
34135
|
-
return;
|
|
34136
|
-
}
|
|
34137
|
-
dispatch(actions.pointGraph.blurPoint());
|
|
34138
|
-
}
|
|
34139
|
-
},
|
|
34140
|
-
onClick: () => {
|
|
34141
|
-
dispatch(actions.pointGraph.clickPoint(i));
|
|
34142
|
-
}
|
|
34143
|
-
})));
|
|
34144
|
-
}
|
|
34145
|
-
function PointGraph(props) {
|
|
34146
|
-
const numPoints = props.graphState.numPoints;
|
|
34147
|
-
if (numPoints === "unlimited") {
|
|
34148
|
-
return UnlimitedPointGraph(props);
|
|
34149
|
-
}
|
|
34150
|
-
return LimitedPointGraph(props);
|
|
34151
|
-
}
|
|
34152
|
-
|
|
34153
34411
|
const protractorImage = "https://ka-perseus-graphie.s3.amazonaws.com/e9d032f2ab8b95979f674fbfa67056442ba1ff6a.png";
|
|
34154
34412
|
|
|
34155
34413
|
// The vector from the center of the protractor to the top left corner of the
|
|
@@ -34297,7 +34555,6 @@ function useDraggablePx(args) {
|
|
|
34297
34555
|
* - Protractor
|
|
34298
34556
|
* - Interactive Graph Elements
|
|
34299
34557
|
*/
|
|
34300
|
-
const REMOVE_BUTTON_ID = "perseus_mafs_remove_button";
|
|
34301
34558
|
const MafsGraph = props => {
|
|
34302
34559
|
const {
|
|
34303
34560
|
state,
|
|
@@ -34314,6 +34571,7 @@ const MafsGraph = props => {
|
|
|
34314
34571
|
const tickStep = props.step;
|
|
34315
34572
|
const uniqueId = React__namespace.useId();
|
|
34316
34573
|
const descriptionId = `interactive-graph-description-${uniqueId}`;
|
|
34574
|
+
const interactiveElementsDescriptionId = `interactive-graph-interactive-elements-description-${uniqueId}`;
|
|
34317
34575
|
const graphRef = React__namespace.useRef(null);
|
|
34318
34576
|
const {
|
|
34319
34577
|
analytics
|
|
@@ -34337,6 +34595,7 @@ const MafsGraph = props => {
|
|
|
34337
34595
|
const {
|
|
34338
34596
|
strings
|
|
34339
34597
|
} = usePerseusI18n();
|
|
34598
|
+
const interactionPrompt = isUnlimitedGraphState(state) && state.showKeyboardInteractionInvitation;
|
|
34340
34599
|
wonderBlocksCore.useOnMountEffect(() => {
|
|
34341
34600
|
analytics.onAnalyticsEvent({
|
|
34342
34601
|
type: "perseus:interactive-graph-widget:rendered",
|
|
@@ -34347,6 +34606,13 @@ const MafsGraph = props => {
|
|
|
34347
34606
|
}
|
|
34348
34607
|
});
|
|
34349
34608
|
});
|
|
34609
|
+
const {
|
|
34610
|
+
graph,
|
|
34611
|
+
interactiveElementsDescription
|
|
34612
|
+
} = renderGraphElements({
|
|
34613
|
+
state,
|
|
34614
|
+
dispatch
|
|
34615
|
+
});
|
|
34350
34616
|
return /*#__PURE__*/React__namespace.createElement(GraphConfigContext.Provider, {
|
|
34351
34617
|
value: {
|
|
34352
34618
|
range: state.range,
|
|
@@ -34378,7 +34644,7 @@ const MafsGraph = props => {
|
|
|
34378
34644
|
handleKeyboardEvent(event, state, dispatch);
|
|
34379
34645
|
},
|
|
34380
34646
|
"aria-label": fullGraphAriaLabel,
|
|
34381
|
-
"aria-describedby": fullGraphAriaDescription
|
|
34647
|
+
"aria-describedby": describedByIds(fullGraphAriaDescription && descriptionId, interactiveElementsDescription && interactiveElementsDescriptionId),
|
|
34382
34648
|
ref: graphRef,
|
|
34383
34649
|
tabIndex: 0,
|
|
34384
34650
|
onFocus: event => {
|
|
@@ -34390,12 +34656,12 @@ const MafsGraph = props => {
|
|
|
34390
34656
|
}, fullGraphAriaDescription && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
34391
34657
|
id: descriptionId,
|
|
34392
34658
|
tabIndex: -1,
|
|
34393
|
-
|
|
34394
|
-
|
|
34395
|
-
|
|
34396
|
-
|
|
34397
|
-
|
|
34398
|
-
},
|
|
34659
|
+
className: "mafs-sr-only"
|
|
34660
|
+
}, fullGraphAriaDescription), interactiveElementsDescription && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
34661
|
+
id: interactiveElementsDescriptionId,
|
|
34662
|
+
tabIndex: -1,
|
|
34663
|
+
className: "mafs-sr-only"
|
|
34664
|
+
}, interactiveElementsDescription), /*#__PURE__*/React__namespace.createElement(LegacyGrid, {
|
|
34399
34665
|
box: props.box,
|
|
34400
34666
|
backgroundImage: props.backgroundImage
|
|
34401
34667
|
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
@@ -34446,10 +34712,7 @@ const MafsGraph = props => {
|
|
|
34446
34712
|
zoom: false,
|
|
34447
34713
|
width: width,
|
|
34448
34714
|
height: height
|
|
34449
|
-
}, /*#__PURE__*/React__namespace.createElement("svg", nestedSVGAttributes, props.showProtractor && /*#__PURE__*/React__namespace.createElement(Protractor, null),
|
|
34450
|
-
state,
|
|
34451
|
-
dispatch
|
|
34452
|
-
}))))), state.type === "point" && state.showKeyboardInteractionInvitation && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
34715
|
+
}, /*#__PURE__*/React__namespace.createElement("svg", nestedSVGAttributes, props.showProtractor && /*#__PURE__*/React__namespace.createElement(Protractor, null), graph)))), interactionPrompt && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
34453
34716
|
style: {
|
|
34454
34717
|
textAlign: "center",
|
|
34455
34718
|
backgroundColor: "white",
|
|
@@ -34466,7 +34729,7 @@ const MafsGraph = props => {
|
|
|
34466
34729
|
state,
|
|
34467
34730
|
dispatch,
|
|
34468
34731
|
width,
|
|
34469
|
-
strings
|
|
34732
|
+
perseusStrings: strings
|
|
34470
34733
|
})));
|
|
34471
34734
|
};
|
|
34472
34735
|
const renderPointGraphControls = props => {
|
|
@@ -34476,7 +34739,7 @@ const renderPointGraphControls = props => {
|
|
|
34476
34739
|
focusedPointIndex
|
|
34477
34740
|
} = props.state;
|
|
34478
34741
|
const {
|
|
34479
|
-
|
|
34742
|
+
perseusStrings
|
|
34480
34743
|
} = props;
|
|
34481
34744
|
const shouldShowRemoveButton = showRemovePointButton && focusedPointIndex !== null;
|
|
34482
34745
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
@@ -34494,7 +34757,7 @@ const renderPointGraphControls = props => {
|
|
|
34494
34757
|
onClick: () => {
|
|
34495
34758
|
props.dispatch(actions.pointGraph.addPoint([0, 0]));
|
|
34496
34759
|
}
|
|
34497
|
-
},
|
|
34760
|
+
}, perseusStrings.addPoint), interactionMode === "mouse" && /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
34498
34761
|
id: REMOVE_BUTTON_ID,
|
|
34499
34762
|
kind: "secondary",
|
|
34500
34763
|
color: "destructive"
|
|
@@ -34507,17 +34770,66 @@ const renderPointGraphControls = props => {
|
|
|
34507
34770
|
marginLeft: "20px",
|
|
34508
34771
|
visibility: shouldShowRemoveButton ? "visible" : "hidden"
|
|
34509
34772
|
},
|
|
34510
|
-
onClick:
|
|
34773
|
+
onClick: _event => {
|
|
34511
34774
|
props.dispatch(actions.pointGraph.removePoint(props.state.focusedPointIndex));
|
|
34512
34775
|
}
|
|
34513
|
-
},
|
|
34776
|
+
}, perseusStrings.removePoint));
|
|
34777
|
+
};
|
|
34778
|
+
|
|
34779
|
+
/**
|
|
34780
|
+
* TODO(catjohnson): The polygon controls will be vastly different from the point controls.
|
|
34781
|
+
* Will be keeping this function as is for the time being, even if it's a copy of the point graph
|
|
34782
|
+
* controls.
|
|
34783
|
+
*/
|
|
34784
|
+
const renderPolygonGraphControls = props => {
|
|
34785
|
+
const {
|
|
34786
|
+
interactionMode,
|
|
34787
|
+
showRemovePointButton,
|
|
34788
|
+
focusedPointIndex
|
|
34789
|
+
} = props.state;
|
|
34790
|
+
const {
|
|
34791
|
+
perseusStrings
|
|
34792
|
+
} = props;
|
|
34793
|
+
const shouldShowRemoveButton = showRemovePointButton && focusedPointIndex !== null;
|
|
34794
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
|
|
34795
|
+
style: {
|
|
34796
|
+
flexDirection: "row",
|
|
34797
|
+
width: props.width
|
|
34798
|
+
}
|
|
34799
|
+
}, interactionMode === "keyboard" && /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
34800
|
+
kind: "secondary",
|
|
34801
|
+
style: {
|
|
34802
|
+
width: "100%",
|
|
34803
|
+
marginLeft: "20px"
|
|
34804
|
+
},
|
|
34805
|
+
tabIndex: 0,
|
|
34806
|
+
onClick: () => {
|
|
34807
|
+
props.dispatch(actions.polygon.addPoint([0, 0]));
|
|
34808
|
+
}
|
|
34809
|
+
}, perseusStrings.addPoint), interactionMode === "mouse" && /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
34810
|
+
id: REMOVE_BUTTON_ID,
|
|
34811
|
+
kind: "secondary",
|
|
34812
|
+
color: "destructive"
|
|
34813
|
+
// This button is meant to be interacted with by the mouse only
|
|
34814
|
+
// Never allow learners to tab to this button
|
|
34815
|
+
,
|
|
34816
|
+
tabIndex: -1,
|
|
34817
|
+
style: {
|
|
34818
|
+
width: "100%",
|
|
34819
|
+
marginLeft: "20px",
|
|
34820
|
+
visibility: shouldShowRemoveButton ? "visible" : "hidden"
|
|
34821
|
+
},
|
|
34822
|
+
onClick: _event => {
|
|
34823
|
+
props.dispatch(actions.polygon.removePoint(props.state.focusedPointIndex));
|
|
34824
|
+
}
|
|
34825
|
+
}, perseusStrings.removePoint));
|
|
34514
34826
|
};
|
|
34515
34827
|
const renderGraphControls = props => {
|
|
34516
34828
|
const {
|
|
34517
34829
|
state,
|
|
34518
34830
|
dispatch,
|
|
34519
34831
|
width,
|
|
34520
|
-
|
|
34832
|
+
perseusStrings
|
|
34521
34833
|
} = props;
|
|
34522
34834
|
const {
|
|
34523
34835
|
type
|
|
@@ -34529,7 +34841,17 @@ const renderGraphControls = props => {
|
|
|
34529
34841
|
state,
|
|
34530
34842
|
dispatch,
|
|
34531
34843
|
width,
|
|
34532
|
-
|
|
34844
|
+
perseusStrings
|
|
34845
|
+
});
|
|
34846
|
+
}
|
|
34847
|
+
return null;
|
|
34848
|
+
case "polygon":
|
|
34849
|
+
if (state.numSides === "unlimited") {
|
|
34850
|
+
return renderPolygonGraphControls({
|
|
34851
|
+
state,
|
|
34852
|
+
dispatch,
|
|
34853
|
+
width,
|
|
34854
|
+
perseusStrings
|
|
34533
34855
|
});
|
|
34534
34856
|
}
|
|
34535
34857
|
return null;
|
|
@@ -34538,21 +34860,28 @@ const renderGraphControls = props => {
|
|
|
34538
34860
|
}
|
|
34539
34861
|
};
|
|
34540
34862
|
function handleFocusEvent(event, state, dispatch) {
|
|
34541
|
-
if (state
|
|
34863
|
+
if (isUnlimitedGraphState(state)) {
|
|
34542
34864
|
if (event.target.classList.contains("mafs-graph") && state.interactionMode === "mouse") {
|
|
34543
34865
|
dispatch(actions.global.changeKeyboardInvitationVisibility(true));
|
|
34544
34866
|
}
|
|
34545
34867
|
}
|
|
34546
34868
|
}
|
|
34547
|
-
function handleBlurEvent(
|
|
34548
|
-
if (state
|
|
34869
|
+
function handleBlurEvent(_event, state, dispatch) {
|
|
34870
|
+
if (isUnlimitedGraphState(state)) {
|
|
34549
34871
|
dispatch(actions.global.changeKeyboardInvitationVisibility(false));
|
|
34550
34872
|
}
|
|
34551
34873
|
}
|
|
34552
34874
|
function handleKeyboardEvent(event, state, dispatch) {
|
|
34553
|
-
if (state
|
|
34875
|
+
if (isUnlimitedGraphState(state)) {
|
|
34554
34876
|
if (event.key === "Backspace") {
|
|
34555
|
-
|
|
34877
|
+
// TODO(benchristel): Checking classList here is a hack to prevent
|
|
34878
|
+
// points from being deleted if the user presses the backspace key
|
|
34879
|
+
// while the whole graph is focused. Instead of doing this, we
|
|
34880
|
+
// should move the keyboard event handler to the movable point
|
|
34881
|
+
// handle element.
|
|
34882
|
+
if (document.activeElement?.classList.contains("movable-point__focusable-handle")) {
|
|
34883
|
+
dispatch(actions.global.deleteIntent());
|
|
34884
|
+
}
|
|
34556
34885
|
|
|
34557
34886
|
// After removing a point blur
|
|
34558
34887
|
// It would be nice if this could focus on the graph but doing so
|
|
@@ -34615,7 +34944,7 @@ const calculateNestedSVGCoords = (range, width, height) => {
|
|
|
34615
34944
|
viewboxY
|
|
34616
34945
|
};
|
|
34617
34946
|
};
|
|
34618
|
-
const
|
|
34947
|
+
const renderGraphElements = props => {
|
|
34619
34948
|
const {
|
|
34620
34949
|
state,
|
|
34621
34950
|
dispatch
|
|
@@ -34625,62 +34954,44 @@ const renderGraph = props => {
|
|
|
34625
34954
|
} = state;
|
|
34626
34955
|
switch (type) {
|
|
34627
34956
|
case "angle":
|
|
34628
|
-
return
|
|
34629
|
-
graphState: state,
|
|
34630
|
-
dispatch: dispatch
|
|
34631
|
-
});
|
|
34957
|
+
return renderAngleGraph(state, dispatch);
|
|
34632
34958
|
case "segment":
|
|
34633
|
-
return
|
|
34634
|
-
graphState: state,
|
|
34635
|
-
dispatch: dispatch
|
|
34636
|
-
});
|
|
34959
|
+
return renderSegmentGraph(state, dispatch);
|
|
34637
34960
|
case "linear-system":
|
|
34638
|
-
return
|
|
34639
|
-
graphState: state,
|
|
34640
|
-
dispatch: dispatch
|
|
34641
|
-
});
|
|
34961
|
+
return renderLinearSystemGraph(state, dispatch);
|
|
34642
34962
|
case "linear":
|
|
34643
|
-
return
|
|
34644
|
-
graphState: state,
|
|
34645
|
-
dispatch: dispatch
|
|
34646
|
-
});
|
|
34963
|
+
return renderLinearGraph(state, dispatch);
|
|
34647
34964
|
case "ray":
|
|
34648
|
-
return
|
|
34649
|
-
graphState: state,
|
|
34650
|
-
dispatch: dispatch
|
|
34651
|
-
});
|
|
34965
|
+
return renderRayGraph(state, dispatch);
|
|
34652
34966
|
case "polygon":
|
|
34653
|
-
return
|
|
34654
|
-
graphState: state,
|
|
34655
|
-
dispatch: dispatch
|
|
34656
|
-
});
|
|
34967
|
+
return renderPolygonGraph(state, dispatch);
|
|
34657
34968
|
case "point":
|
|
34658
|
-
return
|
|
34659
|
-
graphState: state,
|
|
34660
|
-
dispatch: dispatch
|
|
34661
|
-
});
|
|
34969
|
+
return renderPointGraph(state, dispatch);
|
|
34662
34970
|
case "circle":
|
|
34663
|
-
return
|
|
34664
|
-
graphState: state,
|
|
34665
|
-
dispatch: dispatch
|
|
34666
|
-
});
|
|
34971
|
+
return renderCircleGraph(state, dispatch);
|
|
34667
34972
|
case "quadratic":
|
|
34668
|
-
return
|
|
34669
|
-
graphState: state,
|
|
34670
|
-
dispatch: dispatch
|
|
34671
|
-
});
|
|
34973
|
+
return renderQuadraticGraph(state, dispatch);
|
|
34672
34974
|
case "sinusoid":
|
|
34673
|
-
return
|
|
34674
|
-
graphState: state,
|
|
34675
|
-
dispatch: dispatch
|
|
34676
|
-
});
|
|
34975
|
+
return renderSinusoidGraph(state, dispatch);
|
|
34677
34976
|
case "none":
|
|
34678
|
-
return
|
|
34977
|
+
return {
|
|
34978
|
+
graph: null,
|
|
34979
|
+
interactiveElementsDescription: null
|
|
34980
|
+
};
|
|
34679
34981
|
default:
|
|
34680
34982
|
throw new wonderStuffCore.UnreachableCaseError(type);
|
|
34681
34983
|
}
|
|
34682
34984
|
};
|
|
34683
34985
|
|
|
34986
|
+
// Returns a space-separated string like "foo bar" given several optional
|
|
34987
|
+
// string IDs. If all args are falsy, returns undefined.
|
|
34988
|
+
function describedByIds() {
|
|
34989
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
34990
|
+
args[_key] = arguments[_key];
|
|
34991
|
+
}
|
|
34992
|
+
return args.filter(Boolean).join(" ") || undefined;
|
|
34993
|
+
}
|
|
34994
|
+
|
|
34684
34995
|
// Converts the state of a StatefulMafsGraph back to the format used to
|
|
34685
34996
|
// represent graph state in the widget JSON.
|
|
34686
34997
|
//
|
|
@@ -34811,10 +35122,15 @@ function initializeGraphState(params) {
|
|
|
34811
35122
|
return {
|
|
34812
35123
|
...shared,
|
|
34813
35124
|
type: "polygon",
|
|
35125
|
+
numSides: graph.numSides || 0,
|
|
34814
35126
|
showAngles: Boolean(graph.showAngles),
|
|
34815
35127
|
showSides: Boolean(graph.showSides),
|
|
34816
35128
|
coords: getPolygonCoords(graph, range, step),
|
|
34817
|
-
snapTo: graph.snapTo ?? "grid"
|
|
35129
|
+
snapTo: graph.snapTo ?? "grid",
|
|
35130
|
+
focusedPointIndex: null,
|
|
35131
|
+
showRemovePointButton: false,
|
|
35132
|
+
interactionMode: "mouse",
|
|
35133
|
+
showKeyboardInteractionInvitation: false
|
|
34818
35134
|
};
|
|
34819
35135
|
case "point":
|
|
34820
35136
|
return {
|
|
@@ -35108,10 +35424,9 @@ function interactiveGraphReducer(state, action) {
|
|
|
35108
35424
|
}
|
|
35109
35425
|
function doDeleteIntent(state, action) {
|
|
35110
35426
|
// For unlimited point graphs
|
|
35111
|
-
if (state
|
|
35112
|
-
//
|
|
35427
|
+
if (isUnlimitedGraphState(state)) {
|
|
35428
|
+
// Remove the last point that was focused, if any
|
|
35113
35429
|
if (state.focusedPointIndex !== null) {
|
|
35114
|
-
// Remove the focused focus
|
|
35115
35430
|
return doRemovePoint(state, actions.pointGraph.removePoint(state.focusedPointIndex));
|
|
35116
35431
|
}
|
|
35117
35432
|
}
|
|
@@ -35119,6 +35434,7 @@ function doDeleteIntent(state, action) {
|
|
|
35119
35434
|
}
|
|
35120
35435
|
function doFocusPoint(state, action) {
|
|
35121
35436
|
switch (state.type) {
|
|
35437
|
+
case "polygon":
|
|
35122
35438
|
case "point":
|
|
35123
35439
|
return {
|
|
35124
35440
|
...state,
|
|
@@ -35130,6 +35446,7 @@ function doFocusPoint(state, action) {
|
|
|
35130
35446
|
}
|
|
35131
35447
|
function doBlurPoint(state, action) {
|
|
35132
35448
|
switch (state.type) {
|
|
35449
|
+
case "polygon":
|
|
35133
35450
|
case "point":
|
|
35134
35451
|
const nextState = {
|
|
35135
35452
|
...state,
|
|
@@ -35144,10 +35461,7 @@ function doBlurPoint(state, action) {
|
|
|
35144
35461
|
}
|
|
35145
35462
|
}
|
|
35146
35463
|
function doClickPoint(state, action) {
|
|
35147
|
-
if (state
|
|
35148
|
-
return state;
|
|
35149
|
-
}
|
|
35150
|
-
if (state.numPoints === "unlimited") {
|
|
35464
|
+
if (isUnlimitedGraphState(state)) {
|
|
35151
35465
|
return {
|
|
35152
35466
|
...state,
|
|
35153
35467
|
focusedPointIndex: action.index,
|
|
@@ -35157,10 +35471,7 @@ function doClickPoint(state, action) {
|
|
|
35157
35471
|
return state;
|
|
35158
35472
|
}
|
|
35159
35473
|
function doChangeInteractionMode(state, action) {
|
|
35160
|
-
if (state
|
|
35161
|
-
return state;
|
|
35162
|
-
}
|
|
35163
|
-
if (state.numPoints === "unlimited") {
|
|
35474
|
+
if (isUnlimitedGraphState(state)) {
|
|
35164
35475
|
const nextKeyboardInvitation = action.mode === "keyboard" ? false : state.showKeyboardInteractionInvitation;
|
|
35165
35476
|
return {
|
|
35166
35477
|
...state,
|
|
@@ -35171,10 +35482,7 @@ function doChangeInteractionMode(state, action) {
|
|
|
35171
35482
|
return state;
|
|
35172
35483
|
}
|
|
35173
35484
|
function doChangeKeyboardInvitationVisibility(state, action) {
|
|
35174
|
-
if (state
|
|
35175
|
-
return state;
|
|
35176
|
-
}
|
|
35177
|
-
if (state.numPoints === "unlimited") {
|
|
35485
|
+
if (isUnlimitedGraphState(state)) {
|
|
35178
35486
|
return {
|
|
35179
35487
|
...state,
|
|
35180
35488
|
showKeyboardInteractionInvitation: action.shouldShow,
|
|
@@ -35521,7 +35829,7 @@ function doChangeRange(state, action) {
|
|
|
35521
35829
|
};
|
|
35522
35830
|
}
|
|
35523
35831
|
function doAddPoint(state, action) {
|
|
35524
|
-
if (state
|
|
35832
|
+
if (!isUnlimitedGraphState(state)) {
|
|
35525
35833
|
return state;
|
|
35526
35834
|
}
|
|
35527
35835
|
const {
|
|
@@ -35546,7 +35854,7 @@ function doAddPoint(state, action) {
|
|
|
35546
35854
|
};
|
|
35547
35855
|
}
|
|
35548
35856
|
function doRemovePoint(state, action) {
|
|
35549
|
-
if (state
|
|
35857
|
+
if (!isUnlimitedGraphState(state)) {
|
|
35550
35858
|
return state;
|
|
35551
35859
|
}
|
|
35552
35860
|
let nextFocusedPointIndex;
|
|
@@ -37835,9 +38143,6 @@ function shouldUseMafs(mafsFlags, graph) {
|
|
|
37835
38143
|
return Boolean(mafsFlags["point"]);
|
|
37836
38144
|
case "polygon":
|
|
37837
38145
|
if (graph.numSides === UNLIMITED) {
|
|
37838
|
-
// TODO(benchristel): add a feature flag for the "unlimited"
|
|
37839
|
-
// case once we've implemented polygon graphs with unlimited
|
|
37840
|
-
// sides
|
|
37841
38146
|
return Boolean(mafsFlags["unlimited-polygon"]);
|
|
37842
38147
|
}
|
|
37843
38148
|
return Boolean(mafsFlags["polygon"]);
|
|
@@ -37855,976 +38160,15 @@ var InteractiveGraph$1 = {
|
|
|
37855
38160
|
validator: interactiveGraphValidator
|
|
37856
38161
|
};
|
|
37857
38162
|
|
|
37858
|
-
|
|
37859
|
-
const
|
|
37860
|
-
|
|
37861
|
-
const gray = "#999999";
|
|
37862
|
-
const grayLight = "#AAAAAA";
|
|
37863
|
-
const grayLighter = "#DDDDDD";
|
|
37864
|
-
const white = "#FFFFFF";
|
|
37865
|
-
const blue = "#005A88";
|
|
37866
|
-
const blueDark = "#2C3747";
|
|
37867
|
-
const green = "#76A005";
|
|
37868
|
-
const red = "#CF5044";
|
|
37869
|
-
const yellow = "#FFC40D";
|
|
37870
|
-
const orange = "#BF4F04";
|
|
37871
|
-
const pink = "#C3325F";
|
|
37872
|
-
const purple = "#7A43B6";
|
|
37873
|
-
const bodyBackground = "#FFFFFF";
|
|
37874
|
-
const textColor = "#444444";
|
|
37875
|
-
const linkColor = "#005987";
|
|
37876
|
-
const linkColorHover = "#678D00";
|
|
37877
|
-
const sansFontFamily = "'Helvetica Neue',Helvetica,Arial,sans-serif";
|
|
37878
|
-
const serifFontFamily = "Georgia,'Times New Roman',Times,serif";
|
|
37879
|
-
const monoFontFamily = "Monaco,Menlo,Consolas,'Courier New',monospace";
|
|
37880
|
-
const baseFontSize = "14px";
|
|
37881
|
-
const baseFontFamily = "inherit";
|
|
37882
|
-
const baseLineHeight = "20px";
|
|
37883
|
-
const altFontFamily = "Georgia,'Times New Roman',Times,serif";
|
|
37884
|
-
const headingsFontFamily = "inherit";
|
|
37885
|
-
const headingsFontWeight = "bold";
|
|
37886
|
-
const headingsColor = "inherit";
|
|
37887
|
-
const fontSizeLarge = "18px";
|
|
37888
|
-
const fontSizeSmall = "12px";
|
|
37889
|
-
const fontSizeMini = "10.5px";
|
|
37890
|
-
const paddingLarge = "11px 19px";
|
|
37891
|
-
const paddingSmall = "2px 10px";
|
|
37892
|
-
const paddingMini = "0 6px";
|
|
37893
|
-
const baseBorderRadius = "4px";
|
|
37894
|
-
const borderRadiusLarge = "6px";
|
|
37895
|
-
const borderRadiusSmall = "3px";
|
|
37896
|
-
const tableBackground = "#000000";
|
|
37897
|
-
const tableBackgroundAccent = "#F9F9F9";
|
|
37898
|
-
const tableBackgroundHover = "#F5F5F5";
|
|
37899
|
-
const tableBorder = "#DDDDDD";
|
|
37900
|
-
const btnBackground = "#FFFFFF";
|
|
37901
|
-
const btnBackgroundHighlight = "rgb(230, 230, 230)";
|
|
37902
|
-
const btnBorder = "#CCCCCC";
|
|
37903
|
-
const btnPrimaryBackground = "#0088CC";
|
|
37904
|
-
const btnPrimaryBackgroundHighlight = "rgb(0, 68, 204)";
|
|
37905
|
-
const btnInfoBackground = "#5BC0DE";
|
|
37906
|
-
const btnInfoBackgroundHighlight = "#2F96B4";
|
|
37907
|
-
const btnSuccessBackground = "#62C462";
|
|
37908
|
-
const btnSuccessBackgroundHighlight = "#51A351";
|
|
37909
|
-
const btnWarningBackground = "rgb(251, 180, 81)";
|
|
37910
|
-
const btnWarningBackgroundHighlight = "#F89406";
|
|
37911
|
-
const btnDangerBackground = "#EE5F5B";
|
|
37912
|
-
const btnDangerBackgroundHighlight = "#BD362F";
|
|
37913
|
-
const btnInverseBackground = "#444444";
|
|
37914
|
-
const btnInverseBackgroundHighlight = "#222222";
|
|
37915
|
-
const inputBackground = "#FFFFFF";
|
|
37916
|
-
const inputBorder = "#CCCCCC";
|
|
37917
|
-
const inputBorderRadius = "4px";
|
|
37918
|
-
const inputDisabledBackground = "#EEEEEE";
|
|
37919
|
-
const formActionsBackground = "#F5F5F5";
|
|
37920
|
-
const inputHeight = "30px";
|
|
37921
|
-
const dropdownBackground = "#FFFFFF";
|
|
37922
|
-
const dropdownBorder = "rgba(0, 0, 0, 0.2)";
|
|
37923
|
-
const dropdownDividerTop = "#E5E5E5";
|
|
37924
|
-
const dropdownDividerBottom = "#FFFFFF";
|
|
37925
|
-
const dropdownLinkColor = "#333333";
|
|
37926
|
-
const dropdownLinkColorHover = "#FFFFFF";
|
|
37927
|
-
const dropdownLinkColorActive = "#FFFFFF";
|
|
37928
|
-
const dropdownLinkBackgroundActive = "#0088CC";
|
|
37929
|
-
const dropdownLinkBackgroundHover = "#0088CC";
|
|
37930
|
-
const zindexDropdown = 1000;
|
|
37931
|
-
const zindexPopover = 1010;
|
|
37932
|
-
const zindexTooltip = 1030;
|
|
37933
|
-
const zindexFixedNavbar = 1030;
|
|
37934
|
-
const zindexHeader = 1060;
|
|
37935
|
-
const zindexModalBackdrop = 1070;
|
|
37936
|
-
const zindexModal = 1080;
|
|
37937
|
-
const zindexAboveModal = 1090;
|
|
37938
|
-
const iconSpritePath = "../img/glyphicons-halflings.png";
|
|
37939
|
-
const iconWhiteSpritePath = "../img/glyphicons-halflings-white.png";
|
|
37940
|
-
const placeholderText = "#999999";
|
|
37941
|
-
const hrBorder = "#EEEEEE";
|
|
37942
|
-
const horizontalComponentOffset = "180px";
|
|
37943
|
-
const wellBackground = "#F5F5F5";
|
|
37944
|
-
const navbarCollapseWidth = "979px";
|
|
37945
|
-
const navbarCollapseDesktopWidth = "980px";
|
|
37946
|
-
const navbarHeight = "40px";
|
|
37947
|
-
const navbarBackgroundHighlight = "#FFFFFF";
|
|
37948
|
-
const navbarBackground = "rgb(242, 242, 242)";
|
|
37949
|
-
const navbarBorder = "rgb(212, 212, 212)";
|
|
37950
|
-
const navbarText = "#777777";
|
|
37951
|
-
const navbarLinkColor = "#777777";
|
|
37952
|
-
const navbarLinkColorHover = "#333333";
|
|
37953
|
-
const navbarLinkColorActive = "#555555";
|
|
37954
|
-
const navbarLinkBackgroundHover = "#000000";
|
|
37955
|
-
const navbarLinkBackgroundActive = "rgb(230, 230, 230)";
|
|
37956
|
-
const navbarBrandColor = "#777777";
|
|
37957
|
-
const navbarInverseBackground = "#111111";
|
|
37958
|
-
const navbarInverseBackgroundHighlight = "#222222";
|
|
37959
|
-
const navbarInverseBorder = "#252525";
|
|
37960
|
-
const navbarInverseText = "#999999";
|
|
37961
|
-
const navbarInverseLinkColor = "#999999";
|
|
37962
|
-
const navbarInverseLinkColorHover = "#FFFFFF";
|
|
37963
|
-
const navbarInverseLinkColorActive = "#FFFFFF";
|
|
37964
|
-
const navbarInverseLinkBackgroundHover = "#000000";
|
|
37965
|
-
const navbarInverseLinkBackgroundActive = "#111111";
|
|
37966
|
-
const navbarInverseSearchBackground = "rgb(82, 82, 82)";
|
|
37967
|
-
const navbarInverseSearchBackgroundFocus = "#FFFFFF";
|
|
37968
|
-
const navbarInverseSearchBorder = "#111111";
|
|
37969
|
-
const navbarInverseSearchPlaceholderColor = "#CCCCCC";
|
|
37970
|
-
const navbarInverseBrandColor = "#999999";
|
|
37971
|
-
const paginationBackground = "#FFFFFF";
|
|
37972
|
-
const paginationBorder = "#DDDDDD";
|
|
37973
|
-
const paginationActiveBackground = "#F5F5F5";
|
|
37974
|
-
const heroUnitBackground = "#EEEEEE";
|
|
37975
|
-
const heroUnitHeadingColor = "inherit";
|
|
37976
|
-
const heroUnitLeadColor = "inherit";
|
|
37977
|
-
const warningText = "#C09853";
|
|
37978
|
-
const warningBackground = "#FCF8E3";
|
|
37979
|
-
const warningBorder = "rgb(251, 239, 213)";
|
|
37980
|
-
const errorText = "#B94A48";
|
|
37981
|
-
const errorBackground = "#F2DEDE";
|
|
37982
|
-
const errorBorder = "rgb(238, 211, 215)";
|
|
37983
|
-
const successText = "#468847";
|
|
37984
|
-
const successBackground = "#DFF0D8";
|
|
37985
|
-
const successBorder = "rgb(212, 232, 197)";
|
|
37986
|
-
const infoText = "#4A7C17";
|
|
37987
|
-
const infoBackground = "#EDF2DF";
|
|
37988
|
-
const infoBorder = "rgb(228, 232, 197)";
|
|
37989
|
-
const tooltipColor = "#FFFFFF";
|
|
37990
|
-
const tooltipBackground = "#000000";
|
|
37991
|
-
const tooltipArrowWidth = "5px";
|
|
37992
|
-
const tooltipArrowColor = "#000000";
|
|
37993
|
-
const popoverBackground = "#FFFFFF";
|
|
37994
|
-
const popoverArrowWidth = "10px";
|
|
37995
|
-
const popoverArrowColor = "#FFFFFF";
|
|
37996
|
-
const popoverTitleBackground = "rgb(247, 247, 247)";
|
|
37997
|
-
const popoverArrowOuterWidth = "11px";
|
|
37998
|
-
const popoverArrowOuterColor = "rgba(0, 0, 0, 0.25)";
|
|
37999
|
-
const gridColumns = "12";
|
|
38000
|
-
const gridColumnWidth = "60px";
|
|
38001
|
-
const gridGutterWidth = "20px";
|
|
38002
|
-
const gridRowWidth = "940px";
|
|
38003
|
-
const gridColumnWidth1200 = "70px";
|
|
38004
|
-
const gridGutterWidth1200 = "30px";
|
|
38005
|
-
const gridRowWidth1200 = "1170px";
|
|
38006
|
-
const gridColumnWidth768 = "42px";
|
|
38007
|
-
const gridGutterWidth768 = "20px";
|
|
38008
|
-
const gridRowWidth768 = "724px";
|
|
38009
|
-
const fluidGridColumnWidth = "6.382978723404255%";
|
|
38010
|
-
const fluidGridGutterWidth = "2.127659574468085%";
|
|
38011
|
-
const fluidGridColumnWidth1200 = "5.982905982905983%";
|
|
38012
|
-
const fluidGridGutterWidth1200 = "2.564102564102564%";
|
|
38013
|
-
const fluidGridColumnWidth768 = "5.801104972375691%";
|
|
38014
|
-
const fluidGridGutterWidth768 = "2.7624309392265194%";
|
|
38015
|
-
const kaGreen = "#71B307";
|
|
38016
|
-
const kaGreenLight = "#BED47A";
|
|
38017
|
-
const kaBlue = "#314453";
|
|
38018
|
-
const kaBlueLight = "#4D6779";
|
|
38019
|
-
const grayExtraDark = "#111111";
|
|
38020
|
-
const grayExtraLight = "#EEEEEE";
|
|
38021
|
-
const graySuperLight = "#F7F7F7";
|
|
38022
|
-
const whiteDark = "#FDFDFD";
|
|
38023
|
-
const dark = "#21242C";
|
|
38024
|
-
const blueDarkUnsaturated = "#3B414E";
|
|
38025
|
-
const blueDarkSaturated = "#1F3043";
|
|
38026
|
-
const blueLight = "#A9C0D1";
|
|
38027
|
-
const greenLight = "#C6D1AD";
|
|
38028
|
-
const greenDark = "#356700";
|
|
38029
|
-
const yellowGreen = "#9DB63B";
|
|
38030
|
-
const okGreen = "#A7CF5B";
|
|
38031
|
-
const alertRed = "#C42420";
|
|
38032
|
-
const coral = "#EE6666";
|
|
38033
|
-
const grayBlue = "#9AB3B9";
|
|
38034
|
-
const lightPageBackground = "#FDFDFD";
|
|
38035
|
-
const yclaBlue = "#49BAD5";
|
|
38036
|
-
const yclaTeal = "#56D0B3";
|
|
38037
|
-
const yclaTealDark = "#50C1A7";
|
|
38038
|
-
const yclaGreenDark = "#3D9A82";
|
|
38039
|
-
const yclaGreen = "#81C262";
|
|
38040
|
-
const learnstormBlue = "#4898FC";
|
|
38041
|
-
const homepageBlue = "#46A8BF";
|
|
38042
|
-
const backgroundBlue = "#00294A";
|
|
38043
|
-
const teacherSignupBlue = "#335d7d";
|
|
38044
|
-
const homepageGreen = "#2B8E7B";
|
|
38045
|
-
const streakColor = "#F79734";
|
|
38046
|
-
const facebookColor = "#1A60A2";
|
|
38047
|
-
const blueGoogleColor = "#2CAFE2";
|
|
38048
|
-
const redGoogleColor = "#BF4434";
|
|
38049
|
-
const homepageColor = "#2D585E";
|
|
38050
|
-
const lightTextColor = "#898989";
|
|
38051
|
-
const fontSizeTiny = "11px";
|
|
38052
|
-
const fontSizeNormal = "14px";
|
|
38053
|
-
const fontSizeMedium = "16px";
|
|
38054
|
-
const fontSizeExtraLarge = "24px";
|
|
38055
|
-
const fontSizeHuge = "36px";
|
|
38056
|
-
const fontSizeBakana = "48px";
|
|
38057
|
-
const fontSizeBananas = "60px";
|
|
38058
|
-
const fixedWidthFontFamily = "'Helvetica Neue',Helvetica,Arial,sans-serif";
|
|
38059
|
-
const contentPadding = "20px";
|
|
38060
|
-
const primaryButtonBackground = "#89B908";
|
|
38061
|
-
const primaryButtonBorder = "#76A005";
|
|
38062
|
-
const buttonTextColor = "rgb(122, 122, 122)";
|
|
38063
|
-
const buttonBorderRadius = "3px";
|
|
38064
|
-
const basicBorderColor = "#CCCCCC";
|
|
38065
|
-
const minContainerWidth = "1000px";
|
|
38066
|
-
const maxContainerWidth = "1200px";
|
|
38067
|
-
const formHintColor = "#999999";
|
|
38068
|
-
const guidelineExampleText = "#606060";
|
|
38069
|
-
const hoverCardWidth = "450px";
|
|
38070
|
-
const menuHighlightColor = "#96AB4F";
|
|
38071
|
-
const menuHighlightBorderColor = "#76A005";
|
|
38072
|
-
const menuActiveTextColor = "#FFFFFF";
|
|
38073
|
-
const menuInactiveTextColor = "#444444";
|
|
38074
|
-
const menuSubheaderTextColor = "rgb(120, 120, 120)";
|
|
38075
|
-
const menuBorderColor = "#94A170";
|
|
38076
|
-
const unreadBackgroundColor = "#ECEEF4";
|
|
38077
|
-
const menuLineHeight = "18px";
|
|
38078
|
-
const menuSubheaderLineHeight = "17px";
|
|
38079
|
-
const menuSubheaderFontSize = "9px";
|
|
38080
|
-
const notificationBarColor = "#4858A4";
|
|
38081
|
-
const modalBodyTopPadding = "20px";
|
|
38082
|
-
const modalDialogPadding = "15px";
|
|
38083
|
-
const modalSectionPadding = "9px";
|
|
38084
|
-
const mathDomain1 = "#11ACCD";
|
|
38085
|
-
const mathDomain2 = "#63D9EA";
|
|
38086
|
-
const mathDomain3 = "#027d97";
|
|
38087
|
-
const mathDomain4 = "#085566";
|
|
38088
|
-
const partnerContentDomain1 = "#01A995";
|
|
38089
|
-
const partnerContentDomain2 = "#01D1C1";
|
|
38090
|
-
const partnerContentDomain3 = "#208170";
|
|
38091
|
-
const partnerContentDomain4 = "#144F44";
|
|
38092
|
-
const csDomain1 = "#1FAB54";
|
|
38093
|
-
const csDomain2 = "#74CF70";
|
|
38094
|
-
const csDomain3 = "#0D923F";
|
|
38095
|
-
const csDomain4 = "#085E29";
|
|
38096
|
-
const economicsDomain1 = "#E07D10";
|
|
38097
|
-
const economicsDomain2 = "#FFBE26";
|
|
38098
|
-
const economicsDomain3 = "#A75A05";
|
|
38099
|
-
const economicsDomain4 = "#953C02";
|
|
38100
|
-
const collegeCareersMoreDomain1 = "#01A995";
|
|
38101
|
-
const collegeCareersMoreDomain2 = "#01D1C1";
|
|
38102
|
-
const collegeCareersMoreDomain3 = "#208170";
|
|
38103
|
-
const collegeCareersMoreDomain4 = "#144F44";
|
|
38104
|
-
const humanitiesDomain1 = "#E84D39";
|
|
38105
|
-
const humanitiesDomain2 = "#FF8482";
|
|
38106
|
-
const humanitiesDomain3 = "#BE2612";
|
|
38107
|
-
const humanitiesDomain4 = "#8C1C0D";
|
|
38108
|
-
const gtpDomain1 = "#1865F2";
|
|
38109
|
-
const gtpDomain2 = "#1865F2";
|
|
38110
|
-
const gtpDomain3 = "#1865F2";
|
|
38111
|
-
const gtpDomain4 = "#1865F2";
|
|
38112
|
-
const scienceDomain1 = "#CA337C";
|
|
38113
|
-
const scienceDomain2 = "#FF92C6";
|
|
38114
|
-
const scienceDomain3 = "#9E034E";
|
|
38115
|
-
const scienceDomain4 = "#6B0235";
|
|
38116
|
-
const testPrepDomain1 = "#1865F2";
|
|
38117
|
-
const testPrepDomain2 = "#1865F2";
|
|
38118
|
-
const testPrepDomain3 = "#1865F2";
|
|
38119
|
-
const testPrepDomain4 = "#1865F2";
|
|
38120
|
-
const defaultDomain1 = "#1865F2";
|
|
38121
|
-
const defaultDomain2 = "#66afe9";
|
|
38122
|
-
const defaultDomain3 = "#1152b0";
|
|
38123
|
-
const defaultDomain4 = "#0d3d82";
|
|
38124
|
-
const defaultDomainColor = "#314453";
|
|
38125
|
-
const defaultSubjectColor = "#4D6779";
|
|
38126
|
-
const defaultTopicColor = "#6A8DA6";
|
|
38127
|
-
const defaultHoverColor = "#314453";
|
|
38128
|
-
const defaultLinkColor = "#314453";
|
|
38129
|
-
const defaultLinkHoverColor = "#6A8DA6";
|
|
38130
|
-
const scienceDomainColor = "#94424F";
|
|
38131
|
-
const scienceSubjectColor = "#9D4A5A";
|
|
38132
|
-
const scienceTopicColor = "#C55F73";
|
|
38133
|
-
const scienceHoverColor = "#94424F";
|
|
38134
|
-
const scienceLinkColor = "#94424F";
|
|
38135
|
-
const scienceLinkHoverColor = "#C55F73";
|
|
38136
|
-
const humanitiesDomainColor = "#AD3434";
|
|
38137
|
-
const humanitiesSubjectColor = "#C13B31";
|
|
38138
|
-
const humanitiesTopicColor = "#D24A45";
|
|
38139
|
-
const humanitiesHoverColor = "#AD3434";
|
|
38140
|
-
const humanitiesLinkColor = "#AD3434";
|
|
38141
|
-
const humanitiesLinkHoverColor = "#D24A45";
|
|
38142
|
-
const economicsDomainColor = "#B77033";
|
|
38143
|
-
const economicsSubjectColor = "#BF7B34";
|
|
38144
|
-
const economicsTopicColor = "#D1933B";
|
|
38145
|
-
const economicsHoverColor = "#B77033";
|
|
38146
|
-
const economicsLinkColor = "#B77033";
|
|
38147
|
-
const economicsLinkHoverColor = "#D1933B";
|
|
38148
|
-
const csDomainColor = "#437A39";
|
|
38149
|
-
const csSubjectColor = "#53893E";
|
|
38150
|
-
const csTopicColor = "#689B51";
|
|
38151
|
-
const csHoverColor = "#437A39";
|
|
38152
|
-
const csLinkColor = "#437A39";
|
|
38153
|
-
const csLinkHoverColor = "#689B51";
|
|
38154
|
-
const partnerContentDomainColor = "#218270";
|
|
38155
|
-
const partnerContentSubjectColor = "#2C8D7B";
|
|
38156
|
-
const partnerContentTopicColor = "#329A86";
|
|
38157
|
-
const partnerContentHoverColor = "#218270";
|
|
38158
|
-
const partnerContentLinkColor = "#218270";
|
|
38159
|
-
const partnerContentLinkHoverColor = "#329A86";
|
|
38160
|
-
const essayDomainColor = "#0071B3";
|
|
38161
|
-
const mathDomainColor = "#1C758A";
|
|
38162
|
-
const mathSubjectColor = "#46A8BF";
|
|
38163
|
-
const mathTopicColor = "#4FBAD4";
|
|
38164
|
-
const mathHoverColor = "#1C758A";
|
|
38165
|
-
const mathLinkColor = "#1C758A";
|
|
38166
|
-
const mathLinkHoverColor = "#4FBAD4";
|
|
38167
|
-
const testPrepDomainColor = "#644172";
|
|
38168
|
-
const testPrepSubjectColor = "#7E5F8E";
|
|
38169
|
-
const testPrepTopicColor = "#9A72AC";
|
|
38170
|
-
const testPrepHoverColor = "#644172";
|
|
38171
|
-
const testPrepLinkColor = "#644172";
|
|
38172
|
-
const testPrepLinkHoverColor = "#9A72AC";
|
|
38173
|
-
const collegeCareersMoreDomainColor = "#218270";
|
|
38174
|
-
const collegeCareersMoreSubjectColor = "#2C8D7B";
|
|
38175
|
-
const collegeCareersMoreTopicColor = "#329A86";
|
|
38176
|
-
const collegeCareersMoreHoverColor = "#218270";
|
|
38177
|
-
const collegeCareersMoreLinkColor = "#218270";
|
|
38178
|
-
const collegeCareersMoreLinkHoverColor = "#329A86";
|
|
38179
|
-
const colorProficient = "#1C758A";
|
|
38180
|
-
const colorPracticed = "rgb(158, 221, 235)";
|
|
38181
|
-
const colorMastery1 = "rgb(90, 197, 221)";
|
|
38182
|
-
const colorMastery2 = "rgb(42, 174, 203)";
|
|
38183
|
-
const colorMastery3 = "#1C758A";
|
|
38184
|
-
const colorSuggested = "#73982C";
|
|
38185
|
-
const colorReview = "#E35D04";
|
|
38186
|
-
const colorNotStarted = "#CCCCCC";
|
|
38187
|
-
const colorStarted = "#C7E5F7";
|
|
38188
|
-
const colorStruggling = "#C30202";
|
|
38189
|
-
const colorPersonal = "#00809C";
|
|
38190
|
-
const colorPractice = "#96D9FF";
|
|
38191
|
-
const colorEnergyPoints = "#005987";
|
|
38192
|
-
const pureSmMin = "568px";
|
|
38193
|
-
const pureMdMin = "768px";
|
|
38194
|
-
const pureLgMin = "1024px";
|
|
38195
|
-
const pureXlMin = "1200px";
|
|
38196
|
-
const pureXsMax = "567px";
|
|
38197
|
-
const pureSmMax = "767px";
|
|
38198
|
-
const pureMdMax = "1023px";
|
|
38199
|
-
const pureLgMax = "1199px";
|
|
38200
|
-
|
|
38201
|
-
var globalConstants = /*#__PURE__*/Object.freeze({
|
|
38202
|
-
__proto__: null,
|
|
38203
|
-
black: black,
|
|
38204
|
-
grayDarker: grayDarker,
|
|
38205
|
-
grayDark: grayDark,
|
|
38206
|
-
gray: gray,
|
|
38207
|
-
grayLight: grayLight,
|
|
38208
|
-
grayLighter: grayLighter,
|
|
38209
|
-
white: white,
|
|
38210
|
-
blue: blue,
|
|
38211
|
-
blueDark: blueDark,
|
|
38212
|
-
green: green,
|
|
38213
|
-
red: red,
|
|
38214
|
-
yellow: yellow,
|
|
38215
|
-
orange: orange,
|
|
38216
|
-
pink: pink,
|
|
38217
|
-
purple: purple,
|
|
38218
|
-
bodyBackground: bodyBackground,
|
|
38219
|
-
textColor: textColor,
|
|
38220
|
-
linkColor: linkColor,
|
|
38221
|
-
linkColorHover: linkColorHover,
|
|
38222
|
-
sansFontFamily: sansFontFamily,
|
|
38223
|
-
serifFontFamily: serifFontFamily,
|
|
38224
|
-
monoFontFamily: monoFontFamily,
|
|
38225
|
-
baseFontSize: baseFontSize,
|
|
38226
|
-
baseFontFamily: baseFontFamily,
|
|
38227
|
-
baseLineHeight: baseLineHeight,
|
|
38228
|
-
altFontFamily: altFontFamily,
|
|
38229
|
-
headingsFontFamily: headingsFontFamily,
|
|
38230
|
-
headingsFontWeight: headingsFontWeight,
|
|
38231
|
-
headingsColor: headingsColor,
|
|
38232
|
-
fontSizeLarge: fontSizeLarge,
|
|
38233
|
-
fontSizeSmall: fontSizeSmall,
|
|
38234
|
-
fontSizeMini: fontSizeMini,
|
|
38235
|
-
paddingLarge: paddingLarge,
|
|
38236
|
-
paddingSmall: paddingSmall,
|
|
38237
|
-
paddingMini: paddingMini,
|
|
38238
|
-
baseBorderRadius: baseBorderRadius,
|
|
38239
|
-
borderRadiusLarge: borderRadiusLarge,
|
|
38240
|
-
borderRadiusSmall: borderRadiusSmall,
|
|
38241
|
-
tableBackground: tableBackground,
|
|
38242
|
-
tableBackgroundAccent: tableBackgroundAccent,
|
|
38243
|
-
tableBackgroundHover: tableBackgroundHover,
|
|
38244
|
-
tableBorder: tableBorder,
|
|
38245
|
-
btnBackground: btnBackground,
|
|
38246
|
-
btnBackgroundHighlight: btnBackgroundHighlight,
|
|
38247
|
-
btnBorder: btnBorder,
|
|
38248
|
-
btnPrimaryBackground: btnPrimaryBackground,
|
|
38249
|
-
btnPrimaryBackgroundHighlight: btnPrimaryBackgroundHighlight,
|
|
38250
|
-
btnInfoBackground: btnInfoBackground,
|
|
38251
|
-
btnInfoBackgroundHighlight: btnInfoBackgroundHighlight,
|
|
38252
|
-
btnSuccessBackground: btnSuccessBackground,
|
|
38253
|
-
btnSuccessBackgroundHighlight: btnSuccessBackgroundHighlight,
|
|
38254
|
-
btnWarningBackground: btnWarningBackground,
|
|
38255
|
-
btnWarningBackgroundHighlight: btnWarningBackgroundHighlight,
|
|
38256
|
-
btnDangerBackground: btnDangerBackground,
|
|
38257
|
-
btnDangerBackgroundHighlight: btnDangerBackgroundHighlight,
|
|
38258
|
-
btnInverseBackground: btnInverseBackground,
|
|
38259
|
-
btnInverseBackgroundHighlight: btnInverseBackgroundHighlight,
|
|
38260
|
-
inputBackground: inputBackground,
|
|
38261
|
-
inputBorder: inputBorder,
|
|
38262
|
-
inputBorderRadius: inputBorderRadius,
|
|
38263
|
-
inputDisabledBackground: inputDisabledBackground,
|
|
38264
|
-
formActionsBackground: formActionsBackground,
|
|
38265
|
-
inputHeight: inputHeight,
|
|
38266
|
-
dropdownBackground: dropdownBackground,
|
|
38267
|
-
dropdownBorder: dropdownBorder,
|
|
38268
|
-
dropdownDividerTop: dropdownDividerTop,
|
|
38269
|
-
dropdownDividerBottom: dropdownDividerBottom,
|
|
38270
|
-
dropdownLinkColor: dropdownLinkColor,
|
|
38271
|
-
dropdownLinkColorHover: dropdownLinkColorHover,
|
|
38272
|
-
dropdownLinkColorActive: dropdownLinkColorActive,
|
|
38273
|
-
dropdownLinkBackgroundActive: dropdownLinkBackgroundActive,
|
|
38274
|
-
dropdownLinkBackgroundHover: dropdownLinkBackgroundHover,
|
|
38275
|
-
zindexDropdown: zindexDropdown,
|
|
38276
|
-
zindexPopover: zindexPopover,
|
|
38277
|
-
zindexTooltip: zindexTooltip,
|
|
38278
|
-
zindexFixedNavbar: zindexFixedNavbar,
|
|
38279
|
-
zindexHeader: zindexHeader,
|
|
38280
|
-
zindexModalBackdrop: zindexModalBackdrop,
|
|
38281
|
-
zindexModal: zindexModal,
|
|
38282
|
-
zindexAboveModal: zindexAboveModal,
|
|
38283
|
-
iconSpritePath: iconSpritePath,
|
|
38284
|
-
iconWhiteSpritePath: iconWhiteSpritePath,
|
|
38285
|
-
placeholderText: placeholderText,
|
|
38286
|
-
hrBorder: hrBorder,
|
|
38287
|
-
horizontalComponentOffset: horizontalComponentOffset,
|
|
38288
|
-
wellBackground: wellBackground,
|
|
38289
|
-
navbarCollapseWidth: navbarCollapseWidth,
|
|
38290
|
-
navbarCollapseDesktopWidth: navbarCollapseDesktopWidth,
|
|
38291
|
-
navbarHeight: navbarHeight,
|
|
38292
|
-
navbarBackgroundHighlight: navbarBackgroundHighlight,
|
|
38293
|
-
navbarBackground: navbarBackground,
|
|
38294
|
-
navbarBorder: navbarBorder,
|
|
38295
|
-
navbarText: navbarText,
|
|
38296
|
-
navbarLinkColor: navbarLinkColor,
|
|
38297
|
-
navbarLinkColorHover: navbarLinkColorHover,
|
|
38298
|
-
navbarLinkColorActive: navbarLinkColorActive,
|
|
38299
|
-
navbarLinkBackgroundHover: navbarLinkBackgroundHover,
|
|
38300
|
-
navbarLinkBackgroundActive: navbarLinkBackgroundActive,
|
|
38301
|
-
navbarBrandColor: navbarBrandColor,
|
|
38302
|
-
navbarInverseBackground: navbarInverseBackground,
|
|
38303
|
-
navbarInverseBackgroundHighlight: navbarInverseBackgroundHighlight,
|
|
38304
|
-
navbarInverseBorder: navbarInverseBorder,
|
|
38305
|
-
navbarInverseText: navbarInverseText,
|
|
38306
|
-
navbarInverseLinkColor: navbarInverseLinkColor,
|
|
38307
|
-
navbarInverseLinkColorHover: navbarInverseLinkColorHover,
|
|
38308
|
-
navbarInverseLinkColorActive: navbarInverseLinkColorActive,
|
|
38309
|
-
navbarInverseLinkBackgroundHover: navbarInverseLinkBackgroundHover,
|
|
38310
|
-
navbarInverseLinkBackgroundActive: navbarInverseLinkBackgroundActive,
|
|
38311
|
-
navbarInverseSearchBackground: navbarInverseSearchBackground,
|
|
38312
|
-
navbarInverseSearchBackgroundFocus: navbarInverseSearchBackgroundFocus,
|
|
38313
|
-
navbarInverseSearchBorder: navbarInverseSearchBorder,
|
|
38314
|
-
navbarInverseSearchPlaceholderColor: navbarInverseSearchPlaceholderColor,
|
|
38315
|
-
navbarInverseBrandColor: navbarInverseBrandColor,
|
|
38316
|
-
paginationBackground: paginationBackground,
|
|
38317
|
-
paginationBorder: paginationBorder,
|
|
38318
|
-
paginationActiveBackground: paginationActiveBackground,
|
|
38319
|
-
heroUnitBackground: heroUnitBackground,
|
|
38320
|
-
heroUnitHeadingColor: heroUnitHeadingColor,
|
|
38321
|
-
heroUnitLeadColor: heroUnitLeadColor,
|
|
38322
|
-
warningText: warningText,
|
|
38323
|
-
warningBackground: warningBackground,
|
|
38324
|
-
warningBorder: warningBorder,
|
|
38325
|
-
errorText: errorText,
|
|
38326
|
-
errorBackground: errorBackground,
|
|
38327
|
-
errorBorder: errorBorder,
|
|
38328
|
-
successText: successText,
|
|
38329
|
-
successBackground: successBackground,
|
|
38330
|
-
successBorder: successBorder,
|
|
38331
|
-
infoText: infoText,
|
|
38332
|
-
infoBackground: infoBackground,
|
|
38333
|
-
infoBorder: infoBorder,
|
|
38334
|
-
tooltipColor: tooltipColor,
|
|
38335
|
-
tooltipBackground: tooltipBackground,
|
|
38336
|
-
tooltipArrowWidth: tooltipArrowWidth,
|
|
38337
|
-
tooltipArrowColor: tooltipArrowColor,
|
|
38338
|
-
popoverBackground: popoverBackground,
|
|
38339
|
-
popoverArrowWidth: popoverArrowWidth,
|
|
38340
|
-
popoverArrowColor: popoverArrowColor,
|
|
38341
|
-
popoverTitleBackground: popoverTitleBackground,
|
|
38342
|
-
popoverArrowOuterWidth: popoverArrowOuterWidth,
|
|
38343
|
-
popoverArrowOuterColor: popoverArrowOuterColor,
|
|
38344
|
-
gridColumns: gridColumns,
|
|
38345
|
-
gridColumnWidth: gridColumnWidth,
|
|
38346
|
-
gridGutterWidth: gridGutterWidth,
|
|
38347
|
-
gridRowWidth: gridRowWidth,
|
|
38348
|
-
gridColumnWidth1200: gridColumnWidth1200,
|
|
38349
|
-
gridGutterWidth1200: gridGutterWidth1200,
|
|
38350
|
-
gridRowWidth1200: gridRowWidth1200,
|
|
38351
|
-
gridColumnWidth768: gridColumnWidth768,
|
|
38352
|
-
gridGutterWidth768: gridGutterWidth768,
|
|
38353
|
-
gridRowWidth768: gridRowWidth768,
|
|
38354
|
-
fluidGridColumnWidth: fluidGridColumnWidth,
|
|
38355
|
-
fluidGridGutterWidth: fluidGridGutterWidth,
|
|
38356
|
-
fluidGridColumnWidth1200: fluidGridColumnWidth1200,
|
|
38357
|
-
fluidGridGutterWidth1200: fluidGridGutterWidth1200,
|
|
38358
|
-
fluidGridColumnWidth768: fluidGridColumnWidth768,
|
|
38359
|
-
fluidGridGutterWidth768: fluidGridGutterWidth768,
|
|
38360
|
-
kaGreen: kaGreen,
|
|
38361
|
-
kaGreenLight: kaGreenLight,
|
|
38362
|
-
kaBlue: kaBlue,
|
|
38363
|
-
kaBlueLight: kaBlueLight,
|
|
38364
|
-
grayExtraDark: grayExtraDark,
|
|
38365
|
-
grayExtraLight: grayExtraLight,
|
|
38366
|
-
graySuperLight: graySuperLight,
|
|
38367
|
-
whiteDark: whiteDark,
|
|
38368
|
-
dark: dark,
|
|
38369
|
-
blueDarkUnsaturated: blueDarkUnsaturated,
|
|
38370
|
-
blueDarkSaturated: blueDarkSaturated,
|
|
38371
|
-
blueLight: blueLight,
|
|
38372
|
-
greenLight: greenLight,
|
|
38373
|
-
greenDark: greenDark,
|
|
38374
|
-
yellowGreen: yellowGreen,
|
|
38375
|
-
okGreen: okGreen,
|
|
38376
|
-
alertRed: alertRed,
|
|
38377
|
-
coral: coral,
|
|
38378
|
-
grayBlue: grayBlue,
|
|
38379
|
-
lightPageBackground: lightPageBackground,
|
|
38380
|
-
yclaBlue: yclaBlue,
|
|
38381
|
-
yclaTeal: yclaTeal,
|
|
38382
|
-
yclaTealDark: yclaTealDark,
|
|
38383
|
-
yclaGreenDark: yclaGreenDark,
|
|
38384
|
-
yclaGreen: yclaGreen,
|
|
38385
|
-
learnstormBlue: learnstormBlue,
|
|
38386
|
-
homepageBlue: homepageBlue,
|
|
38387
|
-
backgroundBlue: backgroundBlue,
|
|
38388
|
-
teacherSignupBlue: teacherSignupBlue,
|
|
38389
|
-
homepageGreen: homepageGreen,
|
|
38390
|
-
streakColor: streakColor,
|
|
38391
|
-
facebookColor: facebookColor,
|
|
38392
|
-
blueGoogleColor: blueGoogleColor,
|
|
38393
|
-
redGoogleColor: redGoogleColor,
|
|
38394
|
-
homepageColor: homepageColor,
|
|
38395
|
-
lightTextColor: lightTextColor,
|
|
38396
|
-
fontSizeTiny: fontSizeTiny,
|
|
38397
|
-
fontSizeNormal: fontSizeNormal,
|
|
38398
|
-
fontSizeMedium: fontSizeMedium,
|
|
38399
|
-
fontSizeExtraLarge: fontSizeExtraLarge,
|
|
38400
|
-
fontSizeHuge: fontSizeHuge,
|
|
38401
|
-
fontSizeBakana: fontSizeBakana,
|
|
38402
|
-
fontSizeBananas: fontSizeBananas,
|
|
38403
|
-
fixedWidthFontFamily: fixedWidthFontFamily,
|
|
38404
|
-
contentPadding: contentPadding,
|
|
38405
|
-
primaryButtonBackground: primaryButtonBackground,
|
|
38406
|
-
primaryButtonBorder: primaryButtonBorder,
|
|
38407
|
-
buttonTextColor: buttonTextColor,
|
|
38408
|
-
buttonBorderRadius: buttonBorderRadius,
|
|
38409
|
-
basicBorderColor: basicBorderColor,
|
|
38410
|
-
minContainerWidth: minContainerWidth,
|
|
38411
|
-
maxContainerWidth: maxContainerWidth,
|
|
38412
|
-
formHintColor: formHintColor,
|
|
38413
|
-
guidelineExampleText: guidelineExampleText,
|
|
38414
|
-
hoverCardWidth: hoverCardWidth,
|
|
38415
|
-
menuHighlightColor: menuHighlightColor,
|
|
38416
|
-
menuHighlightBorderColor: menuHighlightBorderColor,
|
|
38417
|
-
menuActiveTextColor: menuActiveTextColor,
|
|
38418
|
-
menuInactiveTextColor: menuInactiveTextColor,
|
|
38419
|
-
menuSubheaderTextColor: menuSubheaderTextColor,
|
|
38420
|
-
menuBorderColor: menuBorderColor,
|
|
38421
|
-
unreadBackgroundColor: unreadBackgroundColor,
|
|
38422
|
-
menuLineHeight: menuLineHeight,
|
|
38423
|
-
menuSubheaderLineHeight: menuSubheaderLineHeight,
|
|
38424
|
-
menuSubheaderFontSize: menuSubheaderFontSize,
|
|
38425
|
-
notificationBarColor: notificationBarColor,
|
|
38426
|
-
modalBodyTopPadding: modalBodyTopPadding,
|
|
38427
|
-
modalDialogPadding: modalDialogPadding,
|
|
38428
|
-
modalSectionPadding: modalSectionPadding,
|
|
38429
|
-
mathDomain1: mathDomain1,
|
|
38430
|
-
mathDomain2: mathDomain2,
|
|
38431
|
-
mathDomain3: mathDomain3,
|
|
38432
|
-
mathDomain4: mathDomain4,
|
|
38433
|
-
partnerContentDomain1: partnerContentDomain1,
|
|
38434
|
-
partnerContentDomain2: partnerContentDomain2,
|
|
38435
|
-
partnerContentDomain3: partnerContentDomain3,
|
|
38436
|
-
partnerContentDomain4: partnerContentDomain4,
|
|
38437
|
-
csDomain1: csDomain1,
|
|
38438
|
-
csDomain2: csDomain2,
|
|
38439
|
-
csDomain3: csDomain3,
|
|
38440
|
-
csDomain4: csDomain4,
|
|
38441
|
-
economicsDomain1: economicsDomain1,
|
|
38442
|
-
economicsDomain2: economicsDomain2,
|
|
38443
|
-
economicsDomain3: economicsDomain3,
|
|
38444
|
-
economicsDomain4: economicsDomain4,
|
|
38445
|
-
collegeCareersMoreDomain1: collegeCareersMoreDomain1,
|
|
38446
|
-
collegeCareersMoreDomain2: collegeCareersMoreDomain2,
|
|
38447
|
-
collegeCareersMoreDomain3: collegeCareersMoreDomain3,
|
|
38448
|
-
collegeCareersMoreDomain4: collegeCareersMoreDomain4,
|
|
38449
|
-
humanitiesDomain1: humanitiesDomain1,
|
|
38450
|
-
humanitiesDomain2: humanitiesDomain2,
|
|
38451
|
-
humanitiesDomain3: humanitiesDomain3,
|
|
38452
|
-
humanitiesDomain4: humanitiesDomain4,
|
|
38453
|
-
gtpDomain1: gtpDomain1,
|
|
38454
|
-
gtpDomain2: gtpDomain2,
|
|
38455
|
-
gtpDomain3: gtpDomain3,
|
|
38456
|
-
gtpDomain4: gtpDomain4,
|
|
38457
|
-
scienceDomain1: scienceDomain1,
|
|
38458
|
-
scienceDomain2: scienceDomain2,
|
|
38459
|
-
scienceDomain3: scienceDomain3,
|
|
38460
|
-
scienceDomain4: scienceDomain4,
|
|
38461
|
-
testPrepDomain1: testPrepDomain1,
|
|
38462
|
-
testPrepDomain2: testPrepDomain2,
|
|
38463
|
-
testPrepDomain3: testPrepDomain3,
|
|
38464
|
-
testPrepDomain4: testPrepDomain4,
|
|
38465
|
-
defaultDomain1: defaultDomain1,
|
|
38466
|
-
defaultDomain2: defaultDomain2,
|
|
38467
|
-
defaultDomain3: defaultDomain3,
|
|
38468
|
-
defaultDomain4: defaultDomain4,
|
|
38469
|
-
defaultDomainColor: defaultDomainColor,
|
|
38470
|
-
defaultSubjectColor: defaultSubjectColor,
|
|
38471
|
-
defaultTopicColor: defaultTopicColor,
|
|
38472
|
-
defaultHoverColor: defaultHoverColor,
|
|
38473
|
-
defaultLinkColor: defaultLinkColor,
|
|
38474
|
-
defaultLinkHoverColor: defaultLinkHoverColor,
|
|
38475
|
-
scienceDomainColor: scienceDomainColor,
|
|
38476
|
-
scienceSubjectColor: scienceSubjectColor,
|
|
38477
|
-
scienceTopicColor: scienceTopicColor,
|
|
38478
|
-
scienceHoverColor: scienceHoverColor,
|
|
38479
|
-
scienceLinkColor: scienceLinkColor,
|
|
38480
|
-
scienceLinkHoverColor: scienceLinkHoverColor,
|
|
38481
|
-
humanitiesDomainColor: humanitiesDomainColor,
|
|
38482
|
-
humanitiesSubjectColor: humanitiesSubjectColor,
|
|
38483
|
-
humanitiesTopicColor: humanitiesTopicColor,
|
|
38484
|
-
humanitiesHoverColor: humanitiesHoverColor,
|
|
38485
|
-
humanitiesLinkColor: humanitiesLinkColor,
|
|
38486
|
-
humanitiesLinkHoverColor: humanitiesLinkHoverColor,
|
|
38487
|
-
economicsDomainColor: economicsDomainColor,
|
|
38488
|
-
economicsSubjectColor: economicsSubjectColor,
|
|
38489
|
-
economicsTopicColor: economicsTopicColor,
|
|
38490
|
-
economicsHoverColor: economicsHoverColor,
|
|
38491
|
-
economicsLinkColor: economicsLinkColor,
|
|
38492
|
-
economicsLinkHoverColor: economicsLinkHoverColor,
|
|
38493
|
-
csDomainColor: csDomainColor,
|
|
38494
|
-
csSubjectColor: csSubjectColor,
|
|
38495
|
-
csTopicColor: csTopicColor,
|
|
38496
|
-
csHoverColor: csHoverColor,
|
|
38497
|
-
csLinkColor: csLinkColor,
|
|
38498
|
-
csLinkHoverColor: csLinkHoverColor,
|
|
38499
|
-
partnerContentDomainColor: partnerContentDomainColor,
|
|
38500
|
-
partnerContentSubjectColor: partnerContentSubjectColor,
|
|
38501
|
-
partnerContentTopicColor: partnerContentTopicColor,
|
|
38502
|
-
partnerContentHoverColor: partnerContentHoverColor,
|
|
38503
|
-
partnerContentLinkColor: partnerContentLinkColor,
|
|
38504
|
-
partnerContentLinkHoverColor: partnerContentLinkHoverColor,
|
|
38505
|
-
essayDomainColor: essayDomainColor,
|
|
38506
|
-
mathDomainColor: mathDomainColor,
|
|
38507
|
-
mathSubjectColor: mathSubjectColor,
|
|
38508
|
-
mathTopicColor: mathTopicColor,
|
|
38509
|
-
mathHoverColor: mathHoverColor,
|
|
38510
|
-
mathLinkColor: mathLinkColor,
|
|
38511
|
-
mathLinkHoverColor: mathLinkHoverColor,
|
|
38512
|
-
testPrepDomainColor: testPrepDomainColor,
|
|
38513
|
-
testPrepSubjectColor: testPrepSubjectColor,
|
|
38514
|
-
testPrepTopicColor: testPrepTopicColor,
|
|
38515
|
-
testPrepHoverColor: testPrepHoverColor,
|
|
38516
|
-
testPrepLinkColor: testPrepLinkColor,
|
|
38517
|
-
testPrepLinkHoverColor: testPrepLinkHoverColor,
|
|
38518
|
-
collegeCareersMoreDomainColor: collegeCareersMoreDomainColor,
|
|
38519
|
-
collegeCareersMoreSubjectColor: collegeCareersMoreSubjectColor,
|
|
38520
|
-
collegeCareersMoreTopicColor: collegeCareersMoreTopicColor,
|
|
38521
|
-
collegeCareersMoreHoverColor: collegeCareersMoreHoverColor,
|
|
38522
|
-
collegeCareersMoreLinkColor: collegeCareersMoreLinkColor,
|
|
38523
|
-
collegeCareersMoreLinkHoverColor: collegeCareersMoreLinkHoverColor,
|
|
38524
|
-
colorProficient: colorProficient,
|
|
38525
|
-
colorPracticed: colorPracticed,
|
|
38526
|
-
colorMastery1: colorMastery1,
|
|
38527
|
-
colorMastery2: colorMastery2,
|
|
38528
|
-
colorMastery3: colorMastery3,
|
|
38529
|
-
colorSuggested: colorSuggested,
|
|
38530
|
-
colorReview: colorReview,
|
|
38531
|
-
colorNotStarted: colorNotStarted,
|
|
38532
|
-
colorStarted: colorStarted,
|
|
38533
|
-
colorStruggling: colorStruggling,
|
|
38534
|
-
colorPersonal: colorPersonal,
|
|
38535
|
-
colorPractice: colorPractice,
|
|
38536
|
-
colorEnergyPoints: colorEnergyPoints,
|
|
38537
|
-
pureSmMin: pureSmMin,
|
|
38538
|
-
pureMdMin: pureMdMin,
|
|
38539
|
-
pureLgMin: pureLgMin,
|
|
38540
|
-
pureXlMin: pureXlMin,
|
|
38541
|
-
pureXsMax: pureXsMax,
|
|
38542
|
-
pureSmMax: pureSmMax,
|
|
38543
|
-
pureMdMax: pureMdMax,
|
|
38544
|
-
pureLgMax: pureLgMax
|
|
38545
|
-
});
|
|
38546
|
-
|
|
38547
|
-
const colors = {
|
|
38548
|
-
white: "#FFFFFF",
|
|
38549
|
-
gray98: "#FAFAFA",
|
|
38550
|
-
gray97: "#F6F7F7",
|
|
38551
|
-
gray95: "#F0F1F2",
|
|
38552
|
-
gray90: "#E3E5E6",
|
|
38553
|
-
gray85: "#D6D8DA",
|
|
38554
|
-
gray76: "#BABEC2",
|
|
38555
|
-
gray72: "#999A9D",
|
|
38556
|
-
gray68: "#888D93",
|
|
38557
|
-
gray55: "#707378",
|
|
38558
|
-
gray41: "#626569",
|
|
38559
|
-
gray25: "#3B3E40",
|
|
38560
|
-
gray17: "#21242C",
|
|
38561
|
-
gray10: "#1499af",
|
|
38562
|
-
black: "#000000",
|
|
38563
|
-
// These colors are pulled out from constants.js, which is itself generated
|
|
38564
|
-
// from variables.less. We should probably avoid duplicating these here.
|
|
38565
|
-
alertRed,
|
|
38566
|
-
homepageBlue,
|
|
38567
|
-
kaBlue,
|
|
38568
|
-
kaBlueLight,
|
|
38569
|
-
kaGreen,
|
|
38570
|
-
kaGreenLight,
|
|
38571
|
-
learnstormBlue,
|
|
38572
|
-
backgroundBlue,
|
|
38573
|
-
adminGreen: "#78C008",
|
|
38574
|
-
kaBlueExtraLight: "#39c2db",
|
|
38575
|
-
kaBlueHover: "#0c7f99",
|
|
38576
|
-
kaGreenHover: "#518005",
|
|
38577
|
-
// Domain-agnostic colors related to the study guide experience in the
|
|
38578
|
-
// content library.
|
|
38579
|
-
skyDark: "#001f4d",
|
|
38580
|
-
recommendationGold: "#ffbe26",
|
|
38581
|
-
starAced: "#ff9c39",
|
|
38582
|
-
// We interploate the domain colors into this colors object for
|
|
38583
|
-
// historical reasons, but everyone using domain-specific colors
|
|
38584
|
-
// should switch to using the domainColors() function to look up
|
|
38585
|
-
// colors instead.
|
|
38586
|
-
//
|
|
38587
|
-
// TODO(davidflanagan): remove this line once everything is
|
|
38588
|
-
// working correctly with the domainColors() accessor.
|
|
38589
|
-
// ...domainToColorsMap,
|
|
38590
|
-
// mission: missionColors,
|
|
38591
|
-
|
|
38592
|
-
// Colors for various OAuth providers
|
|
38593
|
-
google: "#C1432f",
|
|
38594
|
-
modernGoogle: "#be2612",
|
|
38595
|
-
modernGoogleHover: "#8c1c0d",
|
|
38596
|
-
facebook: "#4267B2",
|
|
38597
|
-
modernFacebook: "#4267B2",
|
|
38598
|
-
modernFacebookHover: "#00294a",
|
|
38599
|
-
wonderBlocksGold: "#FFB100",
|
|
38600
|
-
wonderBlocksLightBlue: "#37C5FD",
|
|
38601
|
-
// We're using rgba instead of opacity to avoid affecting the focus outline
|
|
38602
|
-
// when we just want to make the color transparent.
|
|
38603
|
-
breadcrumbs: "rgba(255, 255, 255, 0.7)"
|
|
38604
|
-
};
|
|
38605
|
-
const borderRadius = 4;
|
|
38606
|
-
const breadcrumbStyles = {
|
|
38607
|
-
color: colors.breadcrumbs,
|
|
38163
|
+
// TODO: can we use WB typography?
|
|
38164
|
+
const bodyXsmallBold = {
|
|
38165
|
+
// For emphasized metadata, descriptions, etc
|
|
38608
38166
|
fontFamily: "inherit",
|
|
38609
38167
|
fontSize: 15,
|
|
38610
38168
|
fontWeight: "bold",
|
|
38611
|
-
|
|
38612
|
-
lineHeight: "19px",
|
|
38613
|
-
textTransform: "uppercase",
|
|
38614
|
-
// Disable subpixel antialiasing for OSX (improves light on dark text)
|
|
38615
|
-
MozOsxFontSmoothing: "grayscale",
|
|
38616
|
-
WebkitFontSmoothing: "antialiased"
|
|
38617
|
-
};
|
|
38618
|
-
const fonts = {
|
|
38619
|
-
// The body of the page is setup to use 'Helvetica' by default and
|
|
38620
|
-
// 'Lato' if/once it downloads. For your elements to follow this
|
|
38621
|
-
// pattern, all you need is to make the text in your element
|
|
38622
|
-
// inherit from the body using the "inherit" value.
|
|
38623
|
-
regular: "inherit"
|
|
38624
|
-
};
|
|
38625
|
-
const typography = {
|
|
38626
|
-
// For subject names
|
|
38627
|
-
subjectHeadingDesktop: {
|
|
38628
|
-
fontFamily: "inherit",
|
|
38629
|
-
fontSize: 50,
|
|
38630
|
-
fontWeight: "bold",
|
|
38631
|
-
lineHeight: "61px"
|
|
38632
|
-
},
|
|
38633
|
-
subjectHeadingMobile: {
|
|
38634
|
-
fontFamily: "inherit",
|
|
38635
|
-
fontSize: 35,
|
|
38636
|
-
fontWeight: "bold",
|
|
38637
|
-
lineHeight: "37px"
|
|
38638
|
-
},
|
|
38639
|
-
// For the most important thing on the page
|
|
38640
|
-
conceptHeadingDesktop: {
|
|
38641
|
-
fontFamily: "inherit",
|
|
38642
|
-
fontSize: 35,
|
|
38643
|
-
fontWeight: "bold",
|
|
38644
|
-
lineHeight: "37px"
|
|
38645
|
-
},
|
|
38646
|
-
conceptHeadingMobile: {
|
|
38647
|
-
fontFamily: "inherit",
|
|
38648
|
-
fontSize: 23,
|
|
38649
|
-
fontWeight: "bold",
|
|
38650
|
-
lineHeight: "27px"
|
|
38651
|
-
},
|
|
38652
|
-
// For sections or modules
|
|
38653
|
-
subheadingDesktop: {
|
|
38654
|
-
fontFamily: "inherit",
|
|
38655
|
-
fontSize: 23,
|
|
38656
|
-
fontWeight: "bold",
|
|
38657
|
-
lineHeight: "27px"
|
|
38658
|
-
},
|
|
38659
|
-
subheadingMobile: {
|
|
38660
|
-
fontFamily: "inherit",
|
|
38661
|
-
fontSize: 20,
|
|
38662
|
-
fontWeight: "bold",
|
|
38663
|
-
lineHeight: "24px"
|
|
38664
|
-
},
|
|
38665
|
-
smallSubheadingDesktop: {
|
|
38666
|
-
fontFamily: "inherit",
|
|
38667
|
-
fontSize: 20,
|
|
38668
|
-
lineHeight: 1.25
|
|
38669
|
-
},
|
|
38670
|
-
smallSubheadingMobile: {
|
|
38671
|
-
fontFamily: "inherit",
|
|
38672
|
-
fontSize: 15,
|
|
38673
|
-
lineHeight: 1.25
|
|
38674
|
-
},
|
|
38675
|
-
// For callouts
|
|
38676
|
-
smallHeading: {
|
|
38677
|
-
color: colors.gray25,
|
|
38678
|
-
fontFamily: "inherit",
|
|
38679
|
-
fontSize: 17,
|
|
38680
|
-
fontWeight: "bold",
|
|
38681
|
-
lineHeight: "23px"
|
|
38682
|
-
},
|
|
38683
|
-
smallHeadingMobile: {
|
|
38684
|
-
color: colors.gray25,
|
|
38685
|
-
fontFamily: "inherit",
|
|
38686
|
-
fontSize: 15,
|
|
38687
|
-
fontWeight: "bold",
|
|
38688
|
-
lineHeight: "18px"
|
|
38689
|
-
},
|
|
38690
|
-
// Accent headings
|
|
38691
|
-
accentHeading: {
|
|
38692
|
-
color: colors.gray68,
|
|
38693
|
-
fontFamily: "inherit",
|
|
38694
|
-
fontSize: 15,
|
|
38695
|
-
fontWeight: "bold",
|
|
38696
|
-
letterSpacing: 0.8,
|
|
38697
|
-
lineHeight: "19px",
|
|
38698
|
-
textTransform: "uppercase"
|
|
38699
|
-
},
|
|
38700
|
-
bodyLarge: {
|
|
38701
|
-
// For articles with multiple paragraphs
|
|
38702
|
-
fontFamily: fonts.regular,
|
|
38703
|
-
fontSize: 20,
|
|
38704
|
-
lineHeight: "30px"
|
|
38705
|
-
},
|
|
38706
|
-
bodySmall: {
|
|
38707
|
-
// For small blocks of copy
|
|
38708
|
-
fontFamily: fonts.regular,
|
|
38709
|
-
fontSize: 17,
|
|
38710
|
-
fontWeight: "normal",
|
|
38711
|
-
lineHeight: "23px"
|
|
38712
|
-
},
|
|
38713
|
-
bodySmallBold: {
|
|
38714
|
-
// For small blocks of copy
|
|
38715
|
-
fontFamily: fonts.regular,
|
|
38716
|
-
fontSize: 17,
|
|
38717
|
-
fontWeight: "bold",
|
|
38718
|
-
lineHeight: "23px"
|
|
38719
|
-
},
|
|
38720
|
-
bodyXsmall: {
|
|
38721
|
-
// For metadata, descriptions, etc
|
|
38722
|
-
fontFamily: fonts.regular,
|
|
38723
|
-
fontSize: 15,
|
|
38724
|
-
lineHeight: "22px"
|
|
38725
|
-
},
|
|
38726
|
-
bodyXsmallBold: {
|
|
38727
|
-
// For emphasized metadata, descriptions, etc
|
|
38728
|
-
fontFamily: "inherit",
|
|
38729
|
-
fontSize: 15,
|
|
38730
|
-
fontWeight: "bold",
|
|
38731
|
-
lineHeight: "22px"
|
|
38732
|
-
},
|
|
38733
|
-
breadcrumb: breadcrumbStyles,
|
|
38734
|
-
// For in-page tabs, breadcrumbs
|
|
38735
|
-
breadcrumbSmall: {
|
|
38736
|
-
// For in-page tabs and leaf page breadcrumbs
|
|
38737
|
-
...breadcrumbStyles,
|
|
38738
|
-
fontSize: 12,
|
|
38739
|
-
lineHeight: "13px"
|
|
38740
|
-
},
|
|
38741
|
-
labelLarge: {
|
|
38742
|
-
// For chiclets and thumbnail titles
|
|
38743
|
-
fontFamily: "inherit",
|
|
38744
|
-
fontSize: 23,
|
|
38745
|
-
fontWeight: "bold",
|
|
38746
|
-
lineHeight: "27px"
|
|
38747
|
-
},
|
|
38748
|
-
labelMedium: {
|
|
38749
|
-
// For chiclets and thumbnail titles
|
|
38750
|
-
fontFamily: "inherit",
|
|
38751
|
-
fontSize: 15,
|
|
38752
|
-
fontWeight: "bold",
|
|
38753
|
-
lineHeight: "18px"
|
|
38754
|
-
},
|
|
38755
|
-
labelSmall: {
|
|
38756
|
-
// Generally used with labelLarge, for breadcrumbs in thumbnails
|
|
38757
|
-
fontFamily: fonts.regular,
|
|
38758
|
-
fontSize: 12,
|
|
38759
|
-
lineHeight: "14px"
|
|
38760
|
-
},
|
|
38761
|
-
caption: {
|
|
38762
|
-
// For image captions
|
|
38763
|
-
fontFamily: fonts.regular,
|
|
38764
|
-
fontSize: 14,
|
|
38765
|
-
fontStyle: "italic",
|
|
38766
|
-
lineHeight: "17px"
|
|
38767
|
-
},
|
|
38768
|
-
desktopScalingOnMobile: {
|
|
38769
|
-
// For when you need Mobile Safari and friends to stick to desktop
|
|
38770
|
-
// sizes
|
|
38771
|
-
MozTextSizeAdjust: "100%",
|
|
38772
|
-
MsTextSizeAdjust: "100%",
|
|
38773
|
-
WebkitTextSizeAdjust: "100%"
|
|
38774
|
-
},
|
|
38775
|
-
// TODO (josh): This should move to within <ModalHeader>
|
|
38776
|
-
modalSubtitle: {
|
|
38777
|
-
fontSize: 12,
|
|
38778
|
-
lineHeight: 1.65,
|
|
38779
|
-
// NOTE (josh): Font smoothing used here to create a 'medium' weight
|
|
38780
|
-
// font, between normal and bold, on webkit browsers.
|
|
38781
|
-
// This prop is an a11y risk when used on non-bold text, since it
|
|
38782
|
-
// makes text very thin, but it's fine on bold text.
|
|
38783
|
-
WebkitFontSmoothing: "antialiased",
|
|
38784
|
-
fontWeight: "bold"
|
|
38785
|
-
},
|
|
38786
|
-
// HACK(kevinb): temporary wonder blocks styles for header only
|
|
38787
|
-
// TODO(kevinb): use components from wonder-blocks-typography instead
|
|
38788
|
-
wonderBlocksHeader: {
|
|
38789
|
-
paddingLeft: 16,
|
|
38790
|
-
paddingRight: 16,
|
|
38791
|
-
paddingBottom: 24,
|
|
38792
|
-
paddingTop: 34,
|
|
38793
|
-
[mediaQueries.mdOrLarger]: {
|
|
38794
|
-
paddingBottom: 32
|
|
38795
|
-
}
|
|
38796
|
-
},
|
|
38797
|
-
// HACK(kevinb): temporary wonder blocks styles for header only
|
|
38798
|
-
// TODO(kevinb): use components from wonder-blocks-typography instead
|
|
38799
|
-
wonderBlocksTitle: {
|
|
38800
|
-
color: colors.white,
|
|
38801
|
-
fontWeight: 900,
|
|
38802
|
-
// "Black" weight
|
|
38803
|
-
fontSize: 28,
|
|
38804
|
-
lineHeight: "32px",
|
|
38805
|
-
margin: 0,
|
|
38806
|
-
[mediaQueries.mdOrLarger]: {
|
|
38807
|
-
fontSize: 36,
|
|
38808
|
-
lineHeight: "40px"
|
|
38809
|
-
}
|
|
38810
|
-
},
|
|
38811
|
-
// HACK(kevinb): temporary wonder blocks styles for header only
|
|
38812
|
-
// TODO(kevinb): use components from wonder-blocks-typography instead
|
|
38813
|
-
wonderBlocksLabelLarge: {
|
|
38814
|
-
fontSize: 16,
|
|
38815
|
-
lineHeight: "20px",
|
|
38816
|
-
fontWeight: 700 // Bold
|
|
38817
|
-
}
|
|
38169
|
+
lineHeight: "22px"
|
|
38818
38170
|
};
|
|
38819
38171
|
|
|
38820
|
-
var globalStyles = /*#__PURE__*/Object.freeze({
|
|
38821
|
-
__proto__: null,
|
|
38822
|
-
colors: colors,
|
|
38823
|
-
borderRadius: borderRadius,
|
|
38824
|
-
fonts: fonts,
|
|
38825
|
-
typography: typography
|
|
38826
|
-
});
|
|
38827
|
-
|
|
38828
38172
|
const AnswerChoices = props => {
|
|
38829
38173
|
const {
|
|
38830
38174
|
strings
|
|
@@ -39742,7 +39086,7 @@ const styles$a = aphrodite.StyleSheet.create({
|
|
|
39742
39086
|
paddingBottom: 16
|
|
39743
39087
|
},
|
|
39744
39088
|
instructionsCaption: {
|
|
39745
|
-
...
|
|
39089
|
+
...bodyXsmallBold,
|
|
39746
39090
|
paddingBottom: 16
|
|
39747
39091
|
},
|
|
39748
39092
|
instructionsChoices: {
|
|
@@ -43577,9 +42921,9 @@ const makeSafeUrl = (urlString, locale) => {
|
|
|
43577
42921
|
};
|
|
43578
42922
|
const styles$6 = aphrodite.StyleSheet.create({
|
|
43579
42923
|
widgetContainer: {
|
|
43580
|
-
borderRadius:
|
|
42924
|
+
borderRadius: 6,
|
|
43581
42925
|
borderWidth: 1,
|
|
43582
|
-
borderColor:
|
|
42926
|
+
borderColor: "#CCC",
|
|
43583
42927
|
padding: wonderBlocksTokens.spacing.medium_16,
|
|
43584
42928
|
paddingBottom: 0
|
|
43585
42929
|
},
|
|
@@ -44892,7 +44236,7 @@ const VideoTranscriptLink = props => {
|
|
|
44892
44236
|
} = props;
|
|
44893
44237
|
const {
|
|
44894
44238
|
useVideo
|
|
44895
|
-
} =
|
|
44239
|
+
} = useDependencies();
|
|
44896
44240
|
const [id, kind] = IS_URL$1.test(location) ? [getYoutubeId(location), "YOUTUBE_ID"] : [location, "READABLE_ID"];
|
|
44897
44241
|
// The result value conforms to the wonder-blocks-data `Result` type
|
|
44898
44242
|
// which is used by our GraphQL framework.
|
|
@@ -45068,7 +44412,7 @@ const init = function (options) {
|
|
|
45068
44412
|
|
|
45069
44413
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
45070
44414
|
const libName = "@khanacademy/perseus";
|
|
45071
|
-
const libVersion = "
|
|
44415
|
+
const libVersion = "41.0.0";
|
|
45072
44416
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
45073
44417
|
|
|
45074
44418
|
const apiVersion = {
|
|
@@ -45349,7 +44693,7 @@ const styles$3 = aphrodite.StyleSheet.create({
|
|
|
45349
44693
|
},
|
|
45350
44694
|
lastRenderedNewHint: {
|
|
45351
44695
|
marginBottom: 0,
|
|
45352
|
-
borderLeftColor: kaGreen
|
|
44696
|
+
borderLeftColor: kaGreen
|
|
45353
44697
|
}
|
|
45354
44698
|
});
|
|
45355
44699
|
|
|
@@ -45540,7 +44884,7 @@ const styles$2 = aphrodite.StyleSheet.create({
|
|
|
45540
44884
|
fontSize: "100%",
|
|
45541
44885
|
fontFamily: "inherit",
|
|
45542
44886
|
fontWeight: "bold",
|
|
45543
|
-
color: kaGreen
|
|
44887
|
+
color: kaGreen,
|
|
45544
44888
|
padding: 0,
|
|
45545
44889
|
position: "relative"
|
|
45546
44890
|
},
|
|
@@ -45942,28 +45286,6 @@ const ref = /*#__PURE__*/React__namespace.forwardRef((props, ref) => /*#__PURE__
|
|
|
45942
45286
|
}));
|
|
45943
45287
|
}));
|
|
45944
45288
|
|
|
45945
|
-
const devices = {
|
|
45946
|
-
PHONE: "phone",
|
|
45947
|
-
TABLET: "tablet",
|
|
45948
|
-
DESKTOP: "desktop"
|
|
45949
|
-
};
|
|
45950
|
-
|
|
45951
|
-
// How many pixels do we reserve on the right-hand side of a preview
|
|
45952
|
-
// for displaying lint indicators? This space needs to be reserved
|
|
45953
|
-
// in DeviceFramer, but it is actually allocated in PerseusFrame
|
|
45954
|
-
const lintGutterWidth = 36;
|
|
45955
|
-
|
|
45956
|
-
// How wide a border does PerseusFrame draw? We need to allocate enough
|
|
45957
|
-
// space for it in DeviceFramer.
|
|
45958
|
-
const perseusFrameBorderWidth = 1;
|
|
45959
|
-
|
|
45960
|
-
var constants = /*#__PURE__*/Object.freeze({
|
|
45961
|
-
__proto__: null,
|
|
45962
|
-
devices: devices,
|
|
45963
|
-
lintGutterWidth: lintGutterWidth,
|
|
45964
|
-
perseusFrameBorderWidth: perseusFrameBorderWidth
|
|
45965
|
-
});
|
|
45966
|
-
|
|
45967
45289
|
/**
|
|
45968
45290
|
* Traverses a {content, widgets, images} renderer props object,
|
|
45969
45291
|
* such as `itemData.question`
|
|
@@ -48656,6 +47978,18 @@ const EditorJsonify = {
|
|
|
48656
47978
|
}
|
|
48657
47979
|
};
|
|
48658
47980
|
|
|
47981
|
+
/**
|
|
47982
|
+
* Main entry point
|
|
47983
|
+
*/
|
|
47984
|
+
const GrapherUtil = {
|
|
47985
|
+
allTypes,
|
|
47986
|
+
DEFAULT_GRAPHER_PROPS,
|
|
47987
|
+
chooseType,
|
|
47988
|
+
defaultPlotProps,
|
|
47989
|
+
getEquationString,
|
|
47990
|
+
typeToButton
|
|
47991
|
+
};
|
|
47992
|
+
|
|
48659
47993
|
exports.ApiOptions = ApiOptions;
|
|
48660
47994
|
exports.ArticleRenderer = ArticleRenderer;
|
|
48661
47995
|
exports.BaseRadio = BaseRadio;
|
|
@@ -48665,7 +47999,7 @@ exports.ClassNames = ClassNames;
|
|
|
48665
47999
|
exports.Dependencies = dependencies;
|
|
48666
48000
|
exports.EditorJsonify = EditorJsonify;
|
|
48667
48001
|
exports.Expression = Expression;
|
|
48668
|
-
exports.GrapherUtil =
|
|
48002
|
+
exports.GrapherUtil = GrapherUtil;
|
|
48669
48003
|
exports.GrapherWidget = Grapher$1;
|
|
48670
48004
|
exports.HintRenderer = HintRenderer;
|
|
48671
48005
|
exports.HintsRenderer = HintsRenderer;
|
|
@@ -48689,17 +48023,17 @@ exports.QUESTION_WIDGETS = QUESTION_WIDGETS;
|
|
|
48689
48023
|
exports.Radio = Radio;
|
|
48690
48024
|
exports.Renderer = Renderer;
|
|
48691
48025
|
exports.ServerItemRenderer = ref;
|
|
48692
|
-
exports.SizingUtils = sizingUtils;
|
|
48693
48026
|
exports.TableWidget = Table$1;
|
|
48694
48027
|
exports.Util = Util;
|
|
48695
48028
|
exports.WIDGET_PROP_DENYLIST = denylist;
|
|
48696
48029
|
exports.Widgets = widgets$1;
|
|
48697
48030
|
exports.addWidget = addWidget;
|
|
48698
48031
|
exports.apiVersion = apiVersion;
|
|
48032
|
+
exports.bodyXsmallBold = bodyXsmallBold;
|
|
48699
48033
|
exports.buildEmptyItemTreeForShape = buildEmptyItemTreeForShape;
|
|
48700
48034
|
exports.buildMapper = buildMapper;
|
|
48701
48035
|
exports.components = components;
|
|
48702
|
-
exports.
|
|
48036
|
+
exports.containerSizeClass = containerSizeClass;
|
|
48703
48037
|
exports.contentHasWidgetType = contentHasWidgetType;
|
|
48704
48038
|
exports.convertWidgetNameToEnum = convertWidgetNameToEnum;
|
|
48705
48039
|
exports.displaySigFigs = displaySigFigs;
|
|
@@ -48717,6 +48051,7 @@ exports.getCircleCoords = getCircleCoords;
|
|
|
48717
48051
|
exports.getClockwiseAngle = getClockwiseAngle;
|
|
48718
48052
|
exports.getCorrectAnswerForWidgetId = getCorrectAnswerForWidgetId;
|
|
48719
48053
|
exports.getImagesWithoutAltData = getImagesWithoutAltData;
|
|
48054
|
+
exports.getInteractiveBoxFromSizeClass = getInteractiveBoxFromSizeClass;
|
|
48720
48055
|
exports.getLineCoords = getLineCoords;
|
|
48721
48056
|
exports.getLinearSystemCoords = getLinearSystemCoords;
|
|
48722
48057
|
exports.getPointCoords = getPointCoords;
|
|
@@ -48731,9 +48066,8 @@ exports.getWidgetIdsFromContentByType = getWidgetIdsFromContentByType;
|
|
|
48731
48066
|
exports.getWidgetTypeByWidgetId = getWidgetTypeByWidgetId;
|
|
48732
48067
|
exports.getWidgetsFromWidgetMap = getWidgetsFromWidgetMap;
|
|
48733
48068
|
exports.getWidgetsMapFromItemData = getWidgetsMapFromItemData;
|
|
48734
|
-
exports.
|
|
48735
|
-
exports.
|
|
48736
|
-
exports.icons = iconPaths;
|
|
48069
|
+
exports.iconChevronDown = iconChevronDown;
|
|
48070
|
+
exports.iconTrash = iconTrash;
|
|
48737
48071
|
exports.init = init;
|
|
48738
48072
|
exports.injectWidgets = injectWidgets;
|
|
48739
48073
|
exports.interactiveSizes = interactiveSizes$1;
|