@khanacademy/perseus 92.1.0 → 93.0.1

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.
Files changed (59) hide show
  1. package/dist/chunk-rolldown-runtime-DWWV-OC4.js +14 -0
  2. package/dist/components/drag-and-drop/answer-tile/answer-tile.d.ts +2 -1
  3. package/dist/components/drag-and-drop/answer-tile/index.d.ts +0 -1
  4. package/dist/components/drag-and-drop/blank/blank-component.d.ts +2 -1
  5. package/dist/components/drag-and-drop/blank/index.d.ts +0 -1
  6. package/dist/components/drag-and-drop/dnd-action-menu/index.d.ts +1 -1
  7. package/dist/index.css +2 -27
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.js +21515 -118
  10. package/dist/index.js.map +1 -1
  11. package/dist/renderer.d.ts +1 -0
  12. package/dist/server-item-renderer.d.ts +0 -8
  13. package/dist/strings.js +1021 -3
  14. package/dist/strings.js.map +1 -1
  15. package/dist/types.d.ts +1 -1
  16. package/dist/util/graphie-utils.d.ts +4 -2
  17. package/dist/util/{test-utils.d.ts → scoring.testutils.d.ts} +2 -1
  18. package/dist/widgets/image/utils.d.ts +0 -55
  19. package/dist/widgets/interactive-graphs/graph.testutils.d.ts +2 -0
  20. package/dist/widgets/interactive-graphs/graphs/components/movable-line/index.d.ts +0 -1
  21. package/dist/widgets/interactive-graphs/utils.d.ts +0 -2
  22. package/dist/widgets/radio/utils/string-utils.d.ts +0 -47
  23. package/package.json +50 -50
  24. package/dist/chunk-register-all-widgets-for-testing-DhqLyGU0.js +0 -2136
  25. package/dist/chunk-register-all-widgets-for-testing-DhqLyGU0.js.map +0 -1
  26. package/dist/index.css.map +0 -1
  27. package/dist/testing/article-renderer-with-debug-ui.d.ts +0 -17
  28. package/dist/testing/debug-accordion-ui.d.ts +0 -14
  29. package/dist/testing/debug-check-answer-footer.d.ts +0 -20
  30. package/dist/testing/extract-widget-ids-contract-tests.d.ts +0 -10
  31. package/dist/testing/feature-flags-context.d.ts +0 -7
  32. package/dist/testing/feature-flags-util.d.ts +0 -15
  33. package/dist/testing/image-loader-utils.d.ts +0 -9
  34. package/dist/testing/item-flipbook/item-flipbook-model.d.ts +0 -22
  35. package/dist/testing/item-flipbook/item-flipbook-view-model.d.ts +0 -57
  36. package/dist/testing/item-flipbook/item-flipbook-view.d.ts +0 -7
  37. package/dist/testing/item-flipbook/item-flipbook.d.ts +0 -2
  38. package/dist/testing/item-flipbook/safe-parse-perseus-item.d.ts +0 -2
  39. package/dist/testing/item-renderer-hooks.d.ts +0 -45
  40. package/dist/testing/item-renderer-reducer.d.ts +0 -39
  41. package/dist/testing/object-utils.d.ts +0 -1
  42. package/dist/testing/render-question-with-cypress.d.ts +0 -9
  43. package/dist/testing/server-item-renderer-with-debug-ui.d.ts +0 -17
  44. package/dist/testing/split-view.d.ts +0 -13
  45. package/dist/testing/storybook-view-options-context.d.ts +0 -7
  46. package/dist/testing/test-dependencies.d.ts +0 -6
  47. package/dist/testing/test-keypad-context-wrapper.d.ts +0 -10
  48. package/dist/testing/test-mathjax.d.ts +0 -10
  49. package/dist/testing/use-storybook-api-options.d.ts +0 -6
  50. package/dist/testing/user-input-ui.d.ts +0 -7
  51. package/dist/testing/wait.d.ts +0 -27
  52. package/dist/testing.d.ts +0 -5
  53. package/dist/testing.js +0 -68116
  54. package/dist/testing.js.map +0 -1
  55. package/dist/util/scoring.d.ts +0 -2
  56. package/dist/widgets/interactive-graphs/utils/point-labels/point-labels.d.ts +0 -2
  57. package/dist/widgets/mock-widgets/index.d.ts +0 -2
  58. /package/dist/widgets/mock-widgets/{mock-asset-loading-widget.d.ts → mock-asset-loading-widget.testutils.d.ts} +0 -0
  59. /package/dist/widgets/table/{test-util.d.ts → table.testutils.d.ts} +0 -0
@@ -1,2136 +0,0 @@
1
- import * as React from 'react';
2
- import React__default, { useContext, useMemo, forwardRef, useId, useRef, useEffect, useCallback, useImperativeHandle, useState, createContext, useLayoutEffect, createElement } from 'react';
3
- import { KeypadContext } from '@khanacademy/keypad-context';
4
- import { MathInputI18nContext, DesktopKeypad, getCursorContext, CursorContext, getKeyTranslator, createMathField, convertDotToTimesByLocale, mathQuillInstance, KeypadInput, keypadElementPropType } from '@khanacademy/math-input';
5
- import { View, RenderStateRoot, useOnMountEffect, useLatestRef, Text as Text$2 } from '@khanacademy/wonder-blocks-core';
6
- import { Heading, BodyText } from '@khanacademy/wonder-blocks-typography';
7
- import { StyleSheet, css } from 'aphrodite';
8
- import { mockStrings, mapErrorToString } from './strings.js';
9
- import Clickable from '@khanacademy/wonder-blocks-clickable';
10
- import { Popover, PopoverContentCore } from '@khanacademy/wonder-blocks-popover';
11
- import { semanticColor, sizing, border as border$1, color, tokenValue, spacing, font, boxShadow } from '@khanacademy/wonder-blocks-tokens';
12
- import classNames$2 from 'classnames';
13
- import { v4 } from 'uuid';
14
- import PropTypes from 'prop-types';
15
- import * as PerseusLinter from '@khanacademy/perseus-linter';
16
- import { Rule } from '@khanacademy/perseus-linter';
17
- import Tooltip, { TooltipContent } from '@khanacademy/wonder-blocks-tooltip';
18
- import { PerseusError, Errors, isLabeledSVG, getDataUrl, getSvgUrl, getBaseUrl, getRealImageUrl, getImageSizeModern, CoreWidgetRegistry, approximateDeepEqual, pluck, getWidgetIdsFromContentByType, Registry, mapObject, excludeDenylistKeys, applyDefaultsToWidgets, splitPerseusItem, getDefaultAnswerArea, shuffle, usesNumCorrect, isFeatureOn, approximateEqual, lockedFigureColors, lockedFigureFillStyles, GrapherUtil, convertGrapherOptionsToInteractiveGraph, convertGrapherUserInputToInteractiveGraph, convertInteractiveGraphUserInputToGrapher, deepClone, shuffleMatcher, getMatrixSize, makeSafeUrl, SORTER_MAX_HORIZONTAL_CARDS, exceedsCardLimit, shuffleSorter } from '@khanacademy/perseus-core';
19
- import { TextField, TextArea } from '@khanacademy/wonder-blocks-form';
20
- import { KhanAnswerTypes, emptyWidgetsFunctional, scoreWidgetsFunctional, flattenScores, scoreLabelImageMarker } from '@khanacademy/perseus-score';
21
- import * as ReactDOM from 'react-dom';
22
- import ReactDOM__default, { flushSync, createPortal } from 'react-dom';
23
- import _, { debounce as debounce$1 } from 'underscore';
24
- import { CircularSpinner } from '@khanacademy/wonder-blocks-progress-spinner';
25
- import { point, KhanMath, number, vector as vector$3, geometry, angles, coefficients, line } from '@khanacademy/kmath';
26
- import { entries, UnreachableCaseError, isTruthy } from '@khanacademy/wonder-stuff-core';
27
- import $ from 'jquery';
28
- import { ModalDialog, ModalPanel, ModalLauncher, FlexibleDialog } from '@khanacademy/wonder-blocks-modal';
29
- import IconButton from '@khanacademy/wonder-blocks-icon-button';
30
- import closeIcon from '@phosphor-icons/core/bold/x-bold.svg';
31
- import { parseGIF, decompressFrames } from 'gifuct-js';
32
- import { withActionScheduler, useTimeout } from '@khanacademy/wonder-blocks-timing';
33
- import SimpleMarkdown from '@khanacademy/simple-markdown';
34
- import { pureMarkdownRules, traverseContent } from '@khanacademy/pure-markdown';
35
- import dotOutlineIcon from '@phosphor-icons/core/fill/dot-outline-fill.svg';
36
- import warningCircleIcon from '@phosphor-icons/core/fill/warning-circle-fill.svg';
37
- import Banner from '@khanacademy/wonder-blocks-banner';
38
- import { announceMessage } from '@khanacademy/wonder-blocks-announcer';
39
- import caretLeftIcon from '@phosphor-icons/core/regular/caret-left.svg';
40
- import caretRightIcon from '@phosphor-icons/core/regular/caret-right.svg';
41
- import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
42
- import checkIcon from '@phosphor-icons/core/bold/check-bold.svg';
43
- import minusIcon from '@phosphor-icons/core/bold/minus-circle-bold.svg';
44
- import { useDroppable, useDragOperation, useDraggable as useDraggable$1, PointerSensor, DragDropProvider } from '@dnd-kit/react';
45
- import { OptionItem, SingleSelect, MultiSelect, CustomOpener, ActionItem, SeparatorItem, ActionMenu } from '@khanacademy/wonder-blocks-dropdown';
46
- import Button from '@khanacademy/wonder-blocks-button';
47
- import caretDown from '@phosphor-icons/core/regular/caret-down.svg';
48
- import caretUp from '@phosphor-icons/core/regular/caret-up.svg';
49
- import { LabeledField } from '@khanacademy/wonder-blocks-labeled-field';
50
- import warningCircleIcon$1 from '@phosphor-icons/core/regular/warning-circle.svg';
51
- import arrowCounterIcon from '@phosphor-icons/core/bold/arrow-counter-clockwise-bold.svg';
52
- import warningIcon from '@phosphor-icons/core/bold/warning-bold.svg';
53
- import starIcon from '@phosphor-icons/core/fill/star-fill.svg';
54
- import invariant from 'tiny-invariant';
55
- import { vec, Coordinates, Ellipse, Plot as Plot$2, Line as Line$4, Point as Point$2, Polygon, useTransformContext, Text as Text$1, Polyline, Mafs } from 'mafs';
56
- import * as KAS from '@khanacademy/kas';
57
- import { useDrag } from '@use-gesture/react';
58
- import infoIconBold from '@phosphor-icons/core/bold/info-bold.svg';
59
- import pauseIcon from '@phosphor-icons/core/fill/pause-fill.svg';
60
- import playIcon from '@phosphor-icons/core/fill/play-fill.svg';
61
- import Switch from '@khanacademy/wonder-blocks-switch';
62
- import { Popper } from 'react-popper';
63
- import arrowSquareOutIcon from '@phosphor-icons/core/regular/arrow-square-out.svg';
64
- import cornersOutIcon from '@phosphor-icons/core/regular/corners-out.svg';
65
- import xIcon from '@phosphor-icons/core/regular/x.svg';
66
- import checkIcon$1 from '@phosphor-icons/core/regular/check.svg';
67
- import dotsSixVerticalIcon from '@phosphor-icons/core/regular/dots-six-vertical.svg';
68
- import { PointerActivationConstraints, Accessibility } from '@dnd-kit/dom';
69
- import { Strut } from '@khanacademy/wonder-blocks-layout';
70
- import Link from '@khanacademy/wonder-blocks-link';
71
-
72
- var jsxRuntime = {exports: {}};
73
-
74
- var reactJsxRuntime_production_min = {};
75
-
76
- /**
77
- * @license React
78
- * react-jsx-runtime.production.min.js
79
- *
80
- * Copyright (c) Facebook, Inc. and its affiliates.
81
- *
82
- * This source code is licensed under the MIT license found in the
83
- * LICENSE file in the root directory of this source tree.
84
- */
85
-
86
- var hasRequiredReactJsxRuntime_production_min;
87
-
88
- function requireReactJsxRuntime_production_min () {
89
- if (hasRequiredReactJsxRuntime_production_min) return reactJsxRuntime_production_min;
90
- hasRequiredReactJsxRuntime_production_min = 1;
91
- var f=React__default,k=Symbol.for("react.element"),l=Symbol.for("react.fragment"),m=Object.prototype.hasOwnProperty,n=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:true,ref:true,__self:true,__source:true};
92
- function q(c,a,g){var b,d={},e=null,h=null;void 0!==g&&(e=""+g);void 0!==a.key&&(e=""+a.key);void 0!==a.ref&&(h=a.ref);for(b in a)m.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a) void 0===d[b]&&(d[b]=a[b]);return {$$typeof:k,type:c,key:e,ref:h,props:d,_owner:n.current}}reactJsxRuntime_production_min.Fragment=l;reactJsxRuntime_production_min.jsx=q;reactJsxRuntime_production_min.jsxs=q;
93
- return reactJsxRuntime_production_min;
94
- }
95
-
96
- var reactJsxRuntime_development = {};
97
-
98
- /**
99
- * @license React
100
- * react-jsx-runtime.development.js
101
- *
102
- * Copyright (c) Facebook, Inc. and its affiliates.
103
- *
104
- * This source code is licensed under the MIT license found in the
105
- * LICENSE file in the root directory of this source tree.
106
- */
107
-
108
- var hasRequiredReactJsxRuntime_development;
109
-
110
- function requireReactJsxRuntime_development () {
111
- if (hasRequiredReactJsxRuntime_development) return reactJsxRuntime_development;
112
- hasRequiredReactJsxRuntime_development = 1;
113
-
114
- if (process.env.NODE_ENV !== "production") {
115
- (function() {
116
-
117
- var React = React__default;
118
-
119
- // ATTENTION
120
- // When adding new symbols to this file,
121
- // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
122
- // The Symbol used to tag the ReactElement-like types.
123
- var REACT_ELEMENT_TYPE = Symbol.for('react.element');
124
- var REACT_PORTAL_TYPE = Symbol.for('react.portal');
125
- var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
126
- var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');
127
- var REACT_PROFILER_TYPE = Symbol.for('react.profiler');
128
- var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
129
- var REACT_CONTEXT_TYPE = Symbol.for('react.context');
130
- var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
131
- var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
132
- var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
133
- var REACT_MEMO_TYPE = Symbol.for('react.memo');
134
- var REACT_LAZY_TYPE = Symbol.for('react.lazy');
135
- var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');
136
- var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
137
- var FAUX_ITERATOR_SYMBOL = '@@iterator';
138
- function getIteratorFn(maybeIterable) {
139
- if (maybeIterable === null || typeof maybeIterable !== 'object') {
140
- return null;
141
- }
142
-
143
- var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
144
-
145
- if (typeof maybeIterator === 'function') {
146
- return maybeIterator;
147
- }
148
-
149
- return null;
150
- }
151
-
152
- var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
153
-
154
- function error(format) {
155
- {
156
- {
157
- for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
158
- args[_key2 - 1] = arguments[_key2];
159
- }
160
-
161
- printWarning('error', format, args);
162
- }
163
- }
164
- }
165
-
166
- function printWarning(level, format, args) {
167
- // When changing this logic, you might want to also
168
- // update consoleWithStackDev.www.js as well.
169
- {
170
- var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
171
- var stack = ReactDebugCurrentFrame.getStackAddendum();
172
-
173
- if (stack !== '') {
174
- format += '%s';
175
- args = args.concat([stack]);
176
- } // eslint-disable-next-line react-internal/safe-string-coercion
177
-
178
-
179
- var argsWithFormat = args.map(function (item) {
180
- return String(item);
181
- }); // Careful: RN currently depends on this prefix
182
-
183
- argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
184
- // breaks IE9: https://github.com/facebook/react/issues/13610
185
- // eslint-disable-next-line react-internal/no-production-logging
186
-
187
- Function.prototype.apply.call(console[level], console, argsWithFormat);
188
- }
189
- }
190
-
191
- // -----------------------------------------------------------------------------
192
-
193
- var enableScopeAPI = false; // Experimental Create Event Handle API.
194
- var enableCacheElement = false;
195
- var enableTransitionTracing = false; // No known bugs, but needs performance testing
196
-
197
- var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber
198
- // stuff. Intended to enable React core members to more easily debug scheduling
199
- // issues in DEV builds.
200
-
201
- var enableDebugTracing = false; // Track which Fiber(s) schedule render work.
202
-
203
- var REACT_MODULE_REFERENCE;
204
-
205
- {
206
- REACT_MODULE_REFERENCE = Symbol.for('react.module.reference');
207
- }
208
-
209
- function isValidElementType(type) {
210
- if (typeof type === 'string' || typeof type === 'function') {
211
- return true;
212
- } // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).
213
-
214
-
215
- if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || enableDebugTracing || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || enableLegacyHidden || type === REACT_OFFSCREEN_TYPE || enableScopeAPI || enableCacheElement || enableTransitionTracing ) {
216
- return true;
217
- }
218
-
219
- if (typeof type === 'object' && type !== null) {
220
- if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || // This needs to include all possible module reference object
221
- // types supported by any Flight configuration anywhere since
222
- // we don't know which Flight build this will end up being used
223
- // with.
224
- type.$$typeof === REACT_MODULE_REFERENCE || type.getModuleId !== undefined) {
225
- return true;
226
- }
227
- }
228
-
229
- return false;
230
- }
231
-
232
- function getWrappedName(outerType, innerType, wrapperName) {
233
- var displayName = outerType.displayName;
234
-
235
- if (displayName) {
236
- return displayName;
237
- }
238
-
239
- var functionName = innerType.displayName || innerType.name || '';
240
- return functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName;
241
- } // Keep in sync with react-reconciler/getComponentNameFromFiber
242
-
243
-
244
- function getContextName(type) {
245
- return type.displayName || 'Context';
246
- } // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead.
247
-
248
-
249
- function getComponentNameFromType(type) {
250
- if (type == null) {
251
- // Host root, text node or just invalid type.
252
- return null;
253
- }
254
-
255
- {
256
- if (typeof type.tag === 'number') {
257
- error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.');
258
- }
259
- }
260
-
261
- if (typeof type === 'function') {
262
- return type.displayName || type.name || null;
263
- }
264
-
265
- if (typeof type === 'string') {
266
- return type;
267
- }
268
-
269
- switch (type) {
270
- case REACT_FRAGMENT_TYPE:
271
- return 'Fragment';
272
-
273
- case REACT_PORTAL_TYPE:
274
- return 'Portal';
275
-
276
- case REACT_PROFILER_TYPE:
277
- return 'Profiler';
278
-
279
- case REACT_STRICT_MODE_TYPE:
280
- return 'StrictMode';
281
-
282
- case REACT_SUSPENSE_TYPE:
283
- return 'Suspense';
284
-
285
- case REACT_SUSPENSE_LIST_TYPE:
286
- return 'SuspenseList';
287
-
288
- }
289
-
290
- if (typeof type === 'object') {
291
- switch (type.$$typeof) {
292
- case REACT_CONTEXT_TYPE:
293
- var context = type;
294
- return getContextName(context) + '.Consumer';
295
-
296
- case REACT_PROVIDER_TYPE:
297
- var provider = type;
298
- return getContextName(provider._context) + '.Provider';
299
-
300
- case REACT_FORWARD_REF_TYPE:
301
- return getWrappedName(type, type.render, 'ForwardRef');
302
-
303
- case REACT_MEMO_TYPE:
304
- var outerName = type.displayName || null;
305
-
306
- if (outerName !== null) {
307
- return outerName;
308
- }
309
-
310
- return getComponentNameFromType(type.type) || 'Memo';
311
-
312
- case REACT_LAZY_TYPE:
313
- {
314
- var lazyComponent = type;
315
- var payload = lazyComponent._payload;
316
- var init = lazyComponent._init;
317
-
318
- try {
319
- return getComponentNameFromType(init(payload));
320
- } catch (x) {
321
- return null;
322
- }
323
- }
324
-
325
- // eslint-disable-next-line no-fallthrough
326
- }
327
- }
328
-
329
- return null;
330
- }
331
-
332
- var assign = Object.assign;
333
-
334
- // Helpers to patch console.logs to avoid logging during side-effect free
335
- // replaying on render function. This currently only patches the object
336
- // lazily which won't cover if the log function was extracted eagerly.
337
- // We could also eagerly patch the method.
338
- var disabledDepth = 0;
339
- var prevLog;
340
- var prevInfo;
341
- var prevWarn;
342
- var prevError;
343
- var prevGroup;
344
- var prevGroupCollapsed;
345
- var prevGroupEnd;
346
-
347
- function disabledLog() {}
348
-
349
- disabledLog.__reactDisabledLog = true;
350
- function disableLogs() {
351
- {
352
- if (disabledDepth === 0) {
353
- /* eslint-disable react-internal/no-production-logging */
354
- prevLog = console.log;
355
- prevInfo = console.info;
356
- prevWarn = console.warn;
357
- prevError = console.error;
358
- prevGroup = console.group;
359
- prevGroupCollapsed = console.groupCollapsed;
360
- prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099
361
-
362
- var props = {
363
- configurable: true,
364
- enumerable: true,
365
- value: disabledLog,
366
- writable: true
367
- }; // $FlowFixMe Flow thinks console is immutable.
368
-
369
- Object.defineProperties(console, {
370
- info: props,
371
- log: props,
372
- warn: props,
373
- error: props,
374
- group: props,
375
- groupCollapsed: props,
376
- groupEnd: props
377
- });
378
- /* eslint-enable react-internal/no-production-logging */
379
- }
380
-
381
- disabledDepth++;
382
- }
383
- }
384
- function reenableLogs() {
385
- {
386
- disabledDepth--;
387
-
388
- if (disabledDepth === 0) {
389
- /* eslint-disable react-internal/no-production-logging */
390
- var props = {
391
- configurable: true,
392
- enumerable: true,
393
- writable: true
394
- }; // $FlowFixMe Flow thinks console is immutable.
395
-
396
- Object.defineProperties(console, {
397
- log: assign({}, props, {
398
- value: prevLog
399
- }),
400
- info: assign({}, props, {
401
- value: prevInfo
402
- }),
403
- warn: assign({}, props, {
404
- value: prevWarn
405
- }),
406
- error: assign({}, props, {
407
- value: prevError
408
- }),
409
- group: assign({}, props, {
410
- value: prevGroup
411
- }),
412
- groupCollapsed: assign({}, props, {
413
- value: prevGroupCollapsed
414
- }),
415
- groupEnd: assign({}, props, {
416
- value: prevGroupEnd
417
- })
418
- });
419
- /* eslint-enable react-internal/no-production-logging */
420
- }
421
-
422
- if (disabledDepth < 0) {
423
- error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.');
424
- }
425
- }
426
- }
427
-
428
- var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
429
- var prefix;
430
- function describeBuiltInComponentFrame(name, source, ownerFn) {
431
- {
432
- if (prefix === undefined) {
433
- // Extract the VM specific prefix used by each line.
434
- try {
435
- throw Error();
436
- } catch (x) {
437
- var match = x.stack.trim().match(/\n( *(at )?)/);
438
- prefix = match && match[1] || '';
439
- }
440
- } // We use the prefix to ensure our stacks line up with native stack frames.
441
-
442
-
443
- return '\n' + prefix + name;
444
- }
445
- }
446
- var reentry = false;
447
- var componentFrameCache;
448
-
449
- {
450
- var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
451
- componentFrameCache = new PossiblyWeakMap();
452
- }
453
-
454
- function describeNativeComponentFrame(fn, construct) {
455
- // If something asked for a stack inside a fake render, it should get ignored.
456
- if ( !fn || reentry) {
457
- return '';
458
- }
459
-
460
- {
461
- var frame = componentFrameCache.get(fn);
462
-
463
- if (frame !== undefined) {
464
- return frame;
465
- }
466
- }
467
-
468
- var control;
469
- reentry = true;
470
- var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined.
471
-
472
- Error.prepareStackTrace = undefined;
473
- var previousDispatcher;
474
-
475
- {
476
- previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function
477
- // for warnings.
478
-
479
- ReactCurrentDispatcher.current = null;
480
- disableLogs();
481
- }
482
-
483
- try {
484
- // This should throw.
485
- if (construct) {
486
- // Something should be setting the props in the constructor.
487
- var Fake = function () {
488
- throw Error();
489
- }; // $FlowFixMe
490
-
491
-
492
- Object.defineProperty(Fake.prototype, 'props', {
493
- set: function () {
494
- // We use a throwing setter instead of frozen or non-writable props
495
- // because that won't throw in a non-strict mode function.
496
- throw Error();
497
- }
498
- });
499
-
500
- if (typeof Reflect === 'object' && Reflect.construct) {
501
- // We construct a different control for this case to include any extra
502
- // frames added by the construct call.
503
- try {
504
- Reflect.construct(Fake, []);
505
- } catch (x) {
506
- control = x;
507
- }
508
-
509
- Reflect.construct(fn, [], Fake);
510
- } else {
511
- try {
512
- Fake.call();
513
- } catch (x) {
514
- control = x;
515
- }
516
-
517
- fn.call(Fake.prototype);
518
- }
519
- } else {
520
- try {
521
- throw Error();
522
- } catch (x) {
523
- control = x;
524
- }
525
-
526
- fn();
527
- }
528
- } catch (sample) {
529
- // This is inlined manually because closure doesn't do it for us.
530
- if (sample && control && typeof sample.stack === 'string') {
531
- // This extracts the first frame from the sample that isn't also in the control.
532
- // Skipping one frame that we assume is the frame that calls the two.
533
- var sampleLines = sample.stack.split('\n');
534
- var controlLines = control.stack.split('\n');
535
- var s = sampleLines.length - 1;
536
- var c = controlLines.length - 1;
537
-
538
- while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
539
- // We expect at least one stack frame to be shared.
540
- // Typically this will be the root most one. However, stack frames may be
541
- // cut off due to maximum stack limits. In this case, one maybe cut off
542
- // earlier than the other. We assume that the sample is longer or the same
543
- // and there for cut off earlier. So we should find the root most frame in
544
- // the sample somewhere in the control.
545
- c--;
546
- }
547
-
548
- for (; s >= 1 && c >= 0; s--, c--) {
549
- // Next we find the first one that isn't the same which should be the
550
- // frame that called our sample function and the control.
551
- if (sampleLines[s] !== controlLines[c]) {
552
- // In V8, the first line is describing the message but other VMs don't.
553
- // If we're about to return the first line, and the control is also on the same
554
- // line, that's a pretty good indicator that our sample threw at same line as
555
- // the control. I.e. before we entered the sample frame. So we ignore this result.
556
- // This can happen if you passed a class to function component, or non-function.
557
- if (s !== 1 || c !== 1) {
558
- do {
559
- s--;
560
- c--; // We may still have similar intermediate frames from the construct call.
561
- // The next one that isn't the same should be our match though.
562
-
563
- if (c < 0 || sampleLines[s] !== controlLines[c]) {
564
- // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
565
- var _frame = '\n' + sampleLines[s].replace(' at new ', ' at '); // If our component frame is labeled "<anonymous>"
566
- // but we have a user-provided "displayName"
567
- // splice it in to make the stack more readable.
568
-
569
-
570
- if (fn.displayName && _frame.includes('<anonymous>')) {
571
- _frame = _frame.replace('<anonymous>', fn.displayName);
572
- }
573
-
574
- {
575
- if (typeof fn === 'function') {
576
- componentFrameCache.set(fn, _frame);
577
- }
578
- } // Return the line we found.
579
-
580
-
581
- return _frame;
582
- }
583
- } while (s >= 1 && c >= 0);
584
- }
585
-
586
- break;
587
- }
588
- }
589
- }
590
- } finally {
591
- reentry = false;
592
-
593
- {
594
- ReactCurrentDispatcher.current = previousDispatcher;
595
- reenableLogs();
596
- }
597
-
598
- Error.prepareStackTrace = previousPrepareStackTrace;
599
- } // Fallback to just using the name if we couldn't make it throw.
600
-
601
-
602
- var name = fn ? fn.displayName || fn.name : '';
603
- var syntheticFrame = name ? describeBuiltInComponentFrame(name) : '';
604
-
605
- {
606
- if (typeof fn === 'function') {
607
- componentFrameCache.set(fn, syntheticFrame);
608
- }
609
- }
610
-
611
- return syntheticFrame;
612
- }
613
- function describeFunctionComponentFrame(fn, source, ownerFn) {
614
- {
615
- return describeNativeComponentFrame(fn, false);
616
- }
617
- }
618
-
619
- function shouldConstruct(Component) {
620
- var prototype = Component.prototype;
621
- return !!(prototype && prototype.isReactComponent);
622
- }
623
-
624
- function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) {
625
-
626
- if (type == null) {
627
- return '';
628
- }
629
-
630
- if (typeof type === 'function') {
631
- {
632
- return describeNativeComponentFrame(type, shouldConstruct(type));
633
- }
634
- }
635
-
636
- if (typeof type === 'string') {
637
- return describeBuiltInComponentFrame(type);
638
- }
639
-
640
- switch (type) {
641
- case REACT_SUSPENSE_TYPE:
642
- return describeBuiltInComponentFrame('Suspense');
643
-
644
- case REACT_SUSPENSE_LIST_TYPE:
645
- return describeBuiltInComponentFrame('SuspenseList');
646
- }
647
-
648
- if (typeof type === 'object') {
649
- switch (type.$$typeof) {
650
- case REACT_FORWARD_REF_TYPE:
651
- return describeFunctionComponentFrame(type.render);
652
-
653
- case REACT_MEMO_TYPE:
654
- // Memo may contain any component type so we recursively resolve it.
655
- return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);
656
-
657
- case REACT_LAZY_TYPE:
658
- {
659
- var lazyComponent = type;
660
- var payload = lazyComponent._payload;
661
- var init = lazyComponent._init;
662
-
663
- try {
664
- // Lazy may contain any component type so we recursively resolve it.
665
- return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn);
666
- } catch (x) {}
667
- }
668
- }
669
- }
670
-
671
- return '';
672
- }
673
-
674
- var hasOwnProperty = Object.prototype.hasOwnProperty;
675
-
676
- var loggedTypeFailures = {};
677
- var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
678
-
679
- function setCurrentlyValidatingElement(element) {
680
- {
681
- if (element) {
682
- var owner = element._owner;
683
- var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
684
- ReactDebugCurrentFrame.setExtraStackFrame(stack);
685
- } else {
686
- ReactDebugCurrentFrame.setExtraStackFrame(null);
687
- }
688
- }
689
- }
690
-
691
- function checkPropTypes(typeSpecs, values, location, componentName, element) {
692
- {
693
- // $FlowFixMe This is okay but Flow doesn't know it.
694
- var has = Function.call.bind(hasOwnProperty);
695
-
696
- for (var typeSpecName in typeSpecs) {
697
- if (has(typeSpecs, typeSpecName)) {
698
- var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
699
- // fail the render phase where it didn't fail before. So we log it.
700
- // After these have been cleaned up, we'll let them throw.
701
-
702
- try {
703
- // This is intentionally an invariant that gets caught. It's the same
704
- // behavior as without this statement except with a better message.
705
- if (typeof typeSpecs[typeSpecName] !== 'function') {
706
- // eslint-disable-next-line react-internal/prod-error-codes
707
- var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');
708
- err.name = 'Invariant Violation';
709
- throw err;
710
- }
711
-
712
- error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
713
- } catch (ex) {
714
- error$1 = ex;
715
- }
716
-
717
- if (error$1 && !(error$1 instanceof Error)) {
718
- setCurrentlyValidatingElement(element);
719
-
720
- error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1);
721
-
722
- setCurrentlyValidatingElement(null);
723
- }
724
-
725
- if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
726
- // Only monitor this failure once because there tends to be a lot of the
727
- // same error.
728
- loggedTypeFailures[error$1.message] = true;
729
- setCurrentlyValidatingElement(element);
730
-
731
- error('Failed %s type: %s', location, error$1.message);
732
-
733
- setCurrentlyValidatingElement(null);
734
- }
735
- }
736
- }
737
- }
738
- }
739
-
740
- var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare
741
-
742
- function isArray(a) {
743
- return isArrayImpl(a);
744
- }
745
-
746
- /*
747
- * The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol
748
- * and Temporal.* types. See https://github.com/facebook/react/pull/22064.
749
- *
750
- * The functions in this module will throw an easier-to-understand,
751
- * easier-to-debug exception with a clear errors message message explaining the
752
- * problem. (Instead of a confusing exception thrown inside the implementation
753
- * of the `value` object).
754
- */
755
- // $FlowFixMe only called in DEV, so void return is not possible.
756
- function typeName(value) {
757
- {
758
- // toStringTag is needed for namespaced types like Temporal.Instant
759
- var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag;
760
- var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object';
761
- return type;
762
- }
763
- } // $FlowFixMe only called in DEV, so void return is not possible.
764
-
765
-
766
- function willCoercionThrow(value) {
767
- {
768
- try {
769
- testStringCoercion(value);
770
- return false;
771
- } catch (e) {
772
- return true;
773
- }
774
- }
775
- }
776
-
777
- function testStringCoercion(value) {
778
- // If you ended up here by following an exception call stack, here's what's
779
- // happened: you supplied an object or symbol value to React (as a prop, key,
780
- // DOM attribute, CSS property, string ref, etc.) and when React tried to
781
- // coerce it to a string using `'' + value`, an exception was thrown.
782
- //
783
- // The most common types that will cause this exception are `Symbol` instances
784
- // and Temporal objects like `Temporal.Instant`. But any object that has a
785
- // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this
786
- // exception. (Library authors do this to prevent users from using built-in
787
- // numeric operators like `+` or comparison operators like `>=` because custom
788
- // methods are needed to perform accurate arithmetic or comparison.)
789
- //
790
- // To fix the problem, coerce this object or symbol value to a string before
791
- // passing it to React. The most reliable way is usually `String(value)`.
792
- //
793
- // To find which value is throwing, check the browser or debugger console.
794
- // Before this exception was thrown, there should be `console.error` output
795
- // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the
796
- // problem and how that type was used: key, atrribute, input value prop, etc.
797
- // In most cases, this console output also shows the component and its
798
- // ancestor components where the exception happened.
799
- //
800
- // eslint-disable-next-line react-internal/safe-string-coercion
801
- return '' + value;
802
- }
803
- function checkKeyStringCoercion(value) {
804
- {
805
- if (willCoercionThrow(value)) {
806
- error('The provided key is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value));
807
-
808
- return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
809
- }
810
- }
811
- }
812
-
813
- var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
814
- var RESERVED_PROPS = {
815
- key: true,
816
- ref: true,
817
- __self: true,
818
- __source: true
819
- };
820
- var specialPropKeyWarningShown;
821
- var specialPropRefWarningShown;
822
-
823
- function hasValidRef(config) {
824
- {
825
- if (hasOwnProperty.call(config, 'ref')) {
826
- var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
827
-
828
- if (getter && getter.isReactWarning) {
829
- return false;
830
- }
831
- }
832
- }
833
-
834
- return config.ref !== undefined;
835
- }
836
-
837
- function hasValidKey(config) {
838
- {
839
- if (hasOwnProperty.call(config, 'key')) {
840
- var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
841
-
842
- if (getter && getter.isReactWarning) {
843
- return false;
844
- }
845
- }
846
- }
847
-
848
- return config.key !== undefined;
849
- }
850
-
851
- function warnIfStringRefCannotBeAutoConverted(config, self) {
852
- {
853
- if (typeof config.ref === 'string' && ReactCurrentOwner.current && self) ;
854
- }
855
- }
856
-
857
- function defineKeyPropWarningGetter(props, displayName) {
858
- {
859
- var warnAboutAccessingKey = function () {
860
- if (!specialPropKeyWarningShown) {
861
- specialPropKeyWarningShown = true;
862
-
863
- error('%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
864
- }
865
- };
866
-
867
- warnAboutAccessingKey.isReactWarning = true;
868
- Object.defineProperty(props, 'key', {
869
- get: warnAboutAccessingKey,
870
- configurable: true
871
- });
872
- }
873
- }
874
-
875
- function defineRefPropWarningGetter(props, displayName) {
876
- {
877
- var warnAboutAccessingRef = function () {
878
- if (!specialPropRefWarningShown) {
879
- specialPropRefWarningShown = true;
880
-
881
- error('%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
882
- }
883
- };
884
-
885
- warnAboutAccessingRef.isReactWarning = true;
886
- Object.defineProperty(props, 'ref', {
887
- get: warnAboutAccessingRef,
888
- configurable: true
889
- });
890
- }
891
- }
892
- /**
893
- * Factory method to create a new React element. This no longer adheres to
894
- * the class pattern, so do not use new to call it. Also, instanceof check
895
- * will not work. Instead test $$typeof field against Symbol.for('react.element') to check
896
- * if something is a React Element.
897
- *
898
- * @param {*} type
899
- * @param {*} props
900
- * @param {*} key
901
- * @param {string|object} ref
902
- * @param {*} owner
903
- * @param {*} self A *temporary* helper to detect places where `this` is
904
- * different from the `owner` when React.createElement is called, so that we
905
- * can warn. We want to get rid of owner and replace string `ref`s with arrow
906
- * functions, and as long as `this` and owner are the same, there will be no
907
- * change in behavior.
908
- * @param {*} source An annotation object (added by a transpiler or otherwise)
909
- * indicating filename, line number, and/or other information.
910
- * @internal
911
- */
912
-
913
-
914
- var ReactElement = function (type, key, ref, self, source, owner, props) {
915
- var element = {
916
- // This tag allows us to uniquely identify this as a React Element
917
- $$typeof: REACT_ELEMENT_TYPE,
918
- // Built-in properties that belong on the element
919
- type: type,
920
- key: key,
921
- ref: ref,
922
- props: props,
923
- // Record the component responsible for creating this element.
924
- _owner: owner
925
- };
926
-
927
- {
928
- // The validation flag is currently mutative. We put it on
929
- // an external backing store so that we can freeze the whole object.
930
- // This can be replaced with a WeakMap once they are implemented in
931
- // commonly used development environments.
932
- element._store = {}; // To make comparing ReactElements easier for testing purposes, we make
933
- // the validation flag non-enumerable (where possible, which should
934
- // include every environment we run tests in), so the test framework
935
- // ignores it.
936
-
937
- Object.defineProperty(element._store, 'validated', {
938
- configurable: false,
939
- enumerable: false,
940
- writable: true,
941
- value: false
942
- }); // self and source are DEV only properties.
943
-
944
- Object.defineProperty(element, '_self', {
945
- configurable: false,
946
- enumerable: false,
947
- writable: false,
948
- value: self
949
- }); // Two elements created in two different places should be considered
950
- // equal for testing purposes and therefore we hide it from enumeration.
951
-
952
- Object.defineProperty(element, '_source', {
953
- configurable: false,
954
- enumerable: false,
955
- writable: false,
956
- value: source
957
- });
958
-
959
- if (Object.freeze) {
960
- Object.freeze(element.props);
961
- Object.freeze(element);
962
- }
963
- }
964
-
965
- return element;
966
- };
967
- /**
968
- * https://github.com/reactjs/rfcs/pull/107
969
- * @param {*} type
970
- * @param {object} props
971
- * @param {string} key
972
- */
973
-
974
- function jsxDEV(type, config, maybeKey, source, self) {
975
- {
976
- var propName; // Reserved names are extracted
977
-
978
- var props = {};
979
- var key = null;
980
- var ref = null; // Currently, key can be spread in as a prop. This causes a potential
981
- // issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
982
- // or <div key="Hi" {...props} /> ). We want to deprecate key spread,
983
- // but as an intermediary step, we will use jsxDEV for everything except
984
- // <div {...props} key="Hi" />, because we aren't currently able to tell if
985
- // key is explicitly declared to be undefined or not.
986
-
987
- if (maybeKey !== undefined) {
988
- {
989
- checkKeyStringCoercion(maybeKey);
990
- }
991
-
992
- key = '' + maybeKey;
993
- }
994
-
995
- if (hasValidKey(config)) {
996
- {
997
- checkKeyStringCoercion(config.key);
998
- }
999
-
1000
- key = '' + config.key;
1001
- }
1002
-
1003
- if (hasValidRef(config)) {
1004
- ref = config.ref;
1005
- warnIfStringRefCannotBeAutoConverted(config, self);
1006
- } // Remaining properties are added to a new props object
1007
-
1008
-
1009
- for (propName in config) {
1010
- if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
1011
- props[propName] = config[propName];
1012
- }
1013
- } // Resolve default props
1014
-
1015
-
1016
- if (type && type.defaultProps) {
1017
- var defaultProps = type.defaultProps;
1018
-
1019
- for (propName in defaultProps) {
1020
- if (props[propName] === undefined) {
1021
- props[propName] = defaultProps[propName];
1022
- }
1023
- }
1024
- }
1025
-
1026
- if (key || ref) {
1027
- var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;
1028
-
1029
- if (key) {
1030
- defineKeyPropWarningGetter(props, displayName);
1031
- }
1032
-
1033
- if (ref) {
1034
- defineRefPropWarningGetter(props, displayName);
1035
- }
1036
- }
1037
-
1038
- return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
1039
- }
1040
- }
1041
-
1042
- var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
1043
- var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
1044
-
1045
- function setCurrentlyValidatingElement$1(element) {
1046
- {
1047
- if (element) {
1048
- var owner = element._owner;
1049
- var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
1050
- ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
1051
- } else {
1052
- ReactDebugCurrentFrame$1.setExtraStackFrame(null);
1053
- }
1054
- }
1055
- }
1056
-
1057
- var propTypesMisspellWarningShown;
1058
-
1059
- {
1060
- propTypesMisspellWarningShown = false;
1061
- }
1062
- /**
1063
- * Verifies the object is a ReactElement.
1064
- * See https://reactjs.org/docs/react-api.html#isvalidelement
1065
- * @param {?object} object
1066
- * @return {boolean} True if `object` is a ReactElement.
1067
- * @final
1068
- */
1069
-
1070
-
1071
- function isValidElement(object) {
1072
- {
1073
- return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
1074
- }
1075
- }
1076
-
1077
- function getDeclarationErrorAddendum() {
1078
- {
1079
- if (ReactCurrentOwner$1.current) {
1080
- var name = getComponentNameFromType(ReactCurrentOwner$1.current.type);
1081
-
1082
- if (name) {
1083
- return '\n\nCheck the render method of `' + name + '`.';
1084
- }
1085
- }
1086
-
1087
- return '';
1088
- }
1089
- }
1090
-
1091
- function getSourceInfoErrorAddendum(source) {
1092
- {
1093
-
1094
- return '';
1095
- }
1096
- }
1097
- /**
1098
- * Warn if there's no key explicitly set on dynamic arrays of children or
1099
- * object keys are not valid. This allows us to keep track of children between
1100
- * updates.
1101
- */
1102
-
1103
-
1104
- var ownerHasKeyUseWarning = {};
1105
-
1106
- function getCurrentComponentErrorInfo(parentType) {
1107
- {
1108
- var info = getDeclarationErrorAddendum();
1109
-
1110
- if (!info) {
1111
- var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
1112
-
1113
- if (parentName) {
1114
- info = "\n\nCheck the top-level render call using <" + parentName + ">.";
1115
- }
1116
- }
1117
-
1118
- return info;
1119
- }
1120
- }
1121
- /**
1122
- * Warn if the element doesn't have an explicit key assigned to it.
1123
- * This element is in an array. The array could grow and shrink or be
1124
- * reordered. All children that haven't already been validated are required to
1125
- * have a "key" property assigned to it. Error statuses are cached so a warning
1126
- * will only be shown once.
1127
- *
1128
- * @internal
1129
- * @param {ReactElement} element Element that requires a key.
1130
- * @param {*} parentType element's parent's type.
1131
- */
1132
-
1133
-
1134
- function validateExplicitKey(element, parentType) {
1135
- {
1136
- if (!element._store || element._store.validated || element.key != null) {
1137
- return;
1138
- }
1139
-
1140
- element._store.validated = true;
1141
- var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
1142
-
1143
- if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
1144
- return;
1145
- }
1146
-
1147
- ownerHasKeyUseWarning[currentComponentErrorInfo] = true; // Usually the current owner is the offender, but if it accepts children as a
1148
- // property, it may be the creator of the child that's responsible for
1149
- // assigning it a key.
1150
-
1151
- var childOwner = '';
1152
-
1153
- if (element && element._owner && element._owner !== ReactCurrentOwner$1.current) {
1154
- // Give the component that originally created this child.
1155
- childOwner = " It was passed a child from " + getComponentNameFromType(element._owner.type) + ".";
1156
- }
1157
-
1158
- setCurrentlyValidatingElement$1(element);
1159
-
1160
- error('Each child in a list should have a unique "key" prop.' + '%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner);
1161
-
1162
- setCurrentlyValidatingElement$1(null);
1163
- }
1164
- }
1165
- /**
1166
- * Ensure that every element either is passed in a static location, in an
1167
- * array with an explicit keys property defined, or in an object literal
1168
- * with valid key property.
1169
- *
1170
- * @internal
1171
- * @param {ReactNode} node Statically passed child of any type.
1172
- * @param {*} parentType node's parent's type.
1173
- */
1174
-
1175
-
1176
- function validateChildKeys(node, parentType) {
1177
- {
1178
- if (typeof node !== 'object') {
1179
- return;
1180
- }
1181
-
1182
- if (isArray(node)) {
1183
- for (var i = 0; i < node.length; i++) {
1184
- var child = node[i];
1185
-
1186
- if (isValidElement(child)) {
1187
- validateExplicitKey(child, parentType);
1188
- }
1189
- }
1190
- } else if (isValidElement(node)) {
1191
- // This element was passed in a valid location.
1192
- if (node._store) {
1193
- node._store.validated = true;
1194
- }
1195
- } else if (node) {
1196
- var iteratorFn = getIteratorFn(node);
1197
-
1198
- if (typeof iteratorFn === 'function') {
1199
- // Entry iterators used to provide implicit keys,
1200
- // but now we print a separate warning for them later.
1201
- if (iteratorFn !== node.entries) {
1202
- var iterator = iteratorFn.call(node);
1203
- var step;
1204
-
1205
- while (!(step = iterator.next()).done) {
1206
- if (isValidElement(step.value)) {
1207
- validateExplicitKey(step.value, parentType);
1208
- }
1209
- }
1210
- }
1211
- }
1212
- }
1213
- }
1214
- }
1215
- /**
1216
- * Given an element, validate that its props follow the propTypes definition,
1217
- * provided by the type.
1218
- *
1219
- * @param {ReactElement} element
1220
- */
1221
-
1222
-
1223
- function validatePropTypes(element) {
1224
- {
1225
- var type = element.type;
1226
-
1227
- if (type === null || type === undefined || typeof type === 'string') {
1228
- return;
1229
- }
1230
-
1231
- var propTypes;
1232
-
1233
- if (typeof type === 'function') {
1234
- propTypes = type.propTypes;
1235
- } else if (typeof type === 'object' && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.
1236
- // Inner props are checked in the reconciler.
1237
- type.$$typeof === REACT_MEMO_TYPE)) {
1238
- propTypes = type.propTypes;
1239
- } else {
1240
- return;
1241
- }
1242
-
1243
- if (propTypes) {
1244
- // Intentionally inside to avoid triggering lazy initializers:
1245
- var name = getComponentNameFromType(type);
1246
- checkPropTypes(propTypes, element.props, 'prop', name, element);
1247
- } else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {
1248
- propTypesMisspellWarningShown = true; // Intentionally inside to avoid triggering lazy initializers:
1249
-
1250
- var _name = getComponentNameFromType(type);
1251
-
1252
- error('Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', _name || 'Unknown');
1253
- }
1254
-
1255
- if (typeof type.getDefaultProps === 'function' && !type.getDefaultProps.isReactClassApproved) {
1256
- error('getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.');
1257
- }
1258
- }
1259
- }
1260
- /**
1261
- * Given a fragment, validate that it can only be provided with fragment props
1262
- * @param {ReactElement} fragment
1263
- */
1264
-
1265
-
1266
- function validateFragmentProps(fragment) {
1267
- {
1268
- var keys = Object.keys(fragment.props);
1269
-
1270
- for (var i = 0; i < keys.length; i++) {
1271
- var key = keys[i];
1272
-
1273
- if (key !== 'children' && key !== 'key') {
1274
- setCurrentlyValidatingElement$1(fragment);
1275
-
1276
- error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key);
1277
-
1278
- setCurrentlyValidatingElement$1(null);
1279
- break;
1280
- }
1281
- }
1282
-
1283
- if (fragment.ref !== null) {
1284
- setCurrentlyValidatingElement$1(fragment);
1285
-
1286
- error('Invalid attribute `ref` supplied to `React.Fragment`.');
1287
-
1288
- setCurrentlyValidatingElement$1(null);
1289
- }
1290
- }
1291
- }
1292
-
1293
- function jsxWithValidation(type, props, key, isStaticChildren, source, self) {
1294
- {
1295
- var validType = isValidElementType(type); // We warn in this case but don't throw. We expect the element creation to
1296
- // succeed and there will likely be errors in render.
1297
-
1298
- if (!validType) {
1299
- var info = '';
1300
-
1301
- if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
1302
- info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and named imports.";
1303
- }
1304
-
1305
- var sourceInfo = getSourceInfoErrorAddendum();
1306
-
1307
- if (sourceInfo) {
1308
- info += sourceInfo;
1309
- } else {
1310
- info += getDeclarationErrorAddendum();
1311
- }
1312
-
1313
- var typeString;
1314
-
1315
- if (type === null) {
1316
- typeString = 'null';
1317
- } else if (isArray(type)) {
1318
- typeString = 'array';
1319
- } else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
1320
- typeString = "<" + (getComponentNameFromType(type.type) || 'Unknown') + " />";
1321
- info = ' Did you accidentally export a JSX literal instead of a component?';
1322
- } else {
1323
- typeString = typeof type;
1324
- }
1325
-
1326
- error('React.jsx: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', typeString, info);
1327
- }
1328
-
1329
- var element = jsxDEV(type, props, key, source, self); // The result can be nullish if a mock or a custom function is used.
1330
- // TODO: Drop this when these are no longer allowed as the type argument.
1331
-
1332
- if (element == null) {
1333
- return element;
1334
- } // Skip key warning if the type isn't valid since our key validation logic
1335
- // doesn't expect a non-string/function type and can throw confusing errors.
1336
- // We don't want exception behavior to differ between dev and prod.
1337
- // (Rendering will throw with a helpful message and as soon as the type is
1338
- // fixed, the key warnings will appear.)
1339
-
1340
-
1341
- if (validType) {
1342
- var children = props.children;
1343
-
1344
- if (children !== undefined) {
1345
- if (isStaticChildren) {
1346
- if (isArray(children)) {
1347
- for (var i = 0; i < children.length; i++) {
1348
- validateChildKeys(children[i], type);
1349
- }
1350
-
1351
- if (Object.freeze) {
1352
- Object.freeze(children);
1353
- }
1354
- } else {
1355
- error('React.jsx: Static children should always be an array. ' + 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' + 'Use the Babel transform instead.');
1356
- }
1357
- } else {
1358
- validateChildKeys(children, type);
1359
- }
1360
- }
1361
- }
1362
-
1363
- if (type === REACT_FRAGMENT_TYPE) {
1364
- validateFragmentProps(element);
1365
- } else {
1366
- validatePropTypes(element);
1367
- }
1368
-
1369
- return element;
1370
- }
1371
- } // These two functions exist to still get child warnings in dev
1372
- // even with the prod transform. This means that jsxDEV is purely
1373
- // opt-in behavior for better messages but that we won't stop
1374
- // giving you warnings if you use production apis.
1375
-
1376
- function jsxWithValidationStatic(type, props, key) {
1377
- {
1378
- return jsxWithValidation(type, props, key, true);
1379
- }
1380
- }
1381
- function jsxWithValidationDynamic(type, props, key) {
1382
- {
1383
- return jsxWithValidation(type, props, key, false);
1384
- }
1385
- }
1386
-
1387
- var jsx = jsxWithValidationDynamic ; // we may want to special case jsxs internally to take advantage of static children.
1388
- // for now we can ship identical prod functions
1389
-
1390
- var jsxs = jsxWithValidationStatic ;
1391
-
1392
- reactJsxRuntime_development.Fragment = REACT_FRAGMENT_TYPE;
1393
- reactJsxRuntime_development.jsx = jsx;
1394
- reactJsxRuntime_development.jsxs = jsxs;
1395
- })();
1396
- }
1397
- return reactJsxRuntime_development;
1398
- }
1399
-
1400
- var hasRequiredJsxRuntime;
1401
-
1402
- function requireJsxRuntime () {
1403
- if (hasRequiredJsxRuntime) return jsxRuntime.exports;
1404
- hasRequiredJsxRuntime = 1;
1405
-
1406
- if (process.env.NODE_ENV === 'production') {
1407
- jsxRuntime.exports = requireReactJsxRuntime_production_min();
1408
- } else {
1409
- jsxRuntime.exports = requireReactJsxRuntime_development();
1410
- }
1411
- return jsxRuntime.exports;
1412
- }
1413
-
1414
- var jsxRuntimeExports = requireJsxRuntime();
1415
-
1416
- const mockPerseusI18nContext={strings:mockStrings,locale:"en"};const PerseusI18nContext=React.createContext(process.env.NODE_ENV==="test"||process.env.STORYBOOK?mockPerseusI18nContext:null);function PerseusI18nContextProvider({children,strings,locale}){const value=useMemo(()=>({strings,locale}),[strings,locale]);return jsxRuntimeExports.jsx(PerseusI18nContext.Provider,{value:value,children:children})}const usePerseusI18n=()=>useContext(PerseusI18nContext);
1417
-
1418
- var a11y = StyleSheet.create({srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1}});
1419
-
1420
- const debounce=(func,delay)=>{let timer=null;return (...args)=>{if(timer){clearTimeout(timer);}timer=window.setTimeout(()=>{func(...args);},delay);}};
1421
-
1422
- class InnerMathInput extends React.Component{componentDidMount(){this.mathField()?.latex(this.props.value);}componentDidUpdate(prevProps){if(prevProps.ariaRequired!==this.props.ariaRequired){this.updateAriaRequired();}if(prevProps.value!==this.props.value){if(this.state.focused){return}const field=this.mathField();if(!field){return}const current=field.latex();if(this.props.value!==current){field.latex(this.props.value);}}}openKeypad(){if(this.props.buttonsVisible==="never"){return}this.setState({keypadOpen:true});}closeKeypad(){this.setState({keypadOpen:false});}updateAriaRequired(){const textarea=this.__mathFieldWrapperRef?.querySelector("textarea");if(this.props.ariaRequired){textarea?.setAttribute("aria-required","true");}else {textarea?.removeAttribute("aria-required");}}render(){let className=classNames$2({"perseus-math-input":true,"mq-editable-field":true,"mq-math-mode":true});const popoverContentUniqueId=v4().slice(0,8);if(this.props.className){className=className+" "+this.props.className;}return jsxRuntimeExports.jsx(View,{style:[styles$D.outerWrapper,this.state.focused&&styles$D.wrapperFocused],children:jsxRuntimeExports.jsxs("div",{style:{display:"flex",alignItems:"center",padding:1},onClick:e=>{e.stopPropagation();const mathField=this.mathField();if(!mathField){return}this.setState({cursorContext:getCursorContext(mathField)});},children:[jsxRuntimeExports.jsx("span",{className:className,ref:ref=>this.__mathFieldWrapperRef=ref,onFocus:()=>this.focus(),onBlur:()=>this.blur()}),jsxRuntimeExports.jsx(Popover,{opened:this.state.keypadOpen,dismissEnabled:true,rootBoundary:"document","aria-label":this.context.strings.mathInputTitle,"aria-describedby":`popover-content-${popoverContentUniqueId}`,onClose:()=>this.closeKeypad(),content:()=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{size:"large",id:`popover-content-${popoverContentUniqueId}`,style:a11y.srOnly,children:this.context.strings.mathInputDescription}),jsxRuntimeExports.jsx(PopoverContentCore,{style:styles$D.popoverContent,children:jsxRuntimeExports.jsx(DesktopKeypad,{onAnalyticsEvent:this.props.onAnalyticsEvent,extraKeys:this.props.extraKeys,onClickKey:this.handleKeypadPress,cursorContext:this.state.cursorContext,convertDotToTimes:this.props.convertDotToTimes,...this.props.keypadButtonSets??mapButtonSets(this.props?.buttonSets),showDismiss:true})})]}),children:this.props.buttonsVisible==="never"?jsxRuntimeExports.jsx(MathInputIcon,{hovered:false,focused:false,active:false,pressed:false}):jsxRuntimeExports.jsx(Clickable,{"aria-label":this.state.keypadOpen?this.context.strings.closeKeypad:this.context.strings.openKeypad,role:"button",hideDefaultFocusRing:true,onClick:()=>this.state.keypadOpen?this.closeKeypad():this.openKeypad(),children:props=>jsxRuntimeExports.jsx(MathInputIcon,{active:this.state.keypadOpen,...props})})})]})})}constructor(...args){super(...args),this.__mathFieldWrapperRef=null,this.__mathField=null,this.state={focused:false,keypadOpen:this.props.buttonsVisible==="always",cursorContext:CursorContext.NONE},this.insert=value=>{const input=this.mathField();const{locale}=this.context;const customKeyTranslator={...getKeyTranslator(locale,this.context.strings),FRAC:mathQuill=>{const contents=mathQuill.latex();mathQuill.typedText("/");if(mathQuill.latex()===contents){mathQuill.cmd("\\frac");}}};const inputModifier=customKeyTranslator[value];if(inputModifier){inputModifier(input,value);input?.focus();return}if(typeof value==="function"){value(input);}else if(value[0]==="\\"){input?.cmd(value).focus();}else {input?.write(value).focus();}input?.focus();},this.mathField=()=>{if(!this.__mathField&&this.__mathFieldWrapperRef){const{locale}=this.context;this.__mathField=createMathField(this.__mathFieldWrapperRef,locale,this.props.mathInputStrings,baseConfig=>({...baseConfig,handlers:{edit:debounce(mathField=>{let value=mathField.latex();value=value.replace(/<>/g,"\\ne");if(convertDotToTimesByLocale(locale,this.props.convertDotToTimes)){value=value.replace(/\\cdot/g,"\\times");const left=mathField.cursor()[mathQuillInstance.L];if(left&&left.ctrlSeq==="\\cdot "){mathField.controller().backspace();mathField.cmd("\\times");}}else {value=value.replace(/\\times/g,"\\cdot");}if(this.props.value!==value){this.props.onChange(value);}this.setState({cursorContext:getCursorContext(mathField)});},100),enter:()=>{if(this.__mathFieldWrapperRef){this.__mathFieldWrapperRef.dispatchEvent(new Event("submit",{bubbles:true,cancelable:true}));}},upOutOf:mathField=>{mathField.typedText("^");}}}));}this.__mathField?.setAriaLabel(this.props.ariaLabel);this.updateAriaRequired();return this.__mathField},this.focus=()=>{this.mathField()?.focus();this.setState({focused:true});},this.blur=()=>this.setState({focused:false}),this.handleKeypadPress=(key,e)=>{if(key==="DISMISS"){this.closeKeypad();return}const{locale}=this.context;const translator=getKeyTranslator(locale,this.context.strings)[key];const mathField=this.mathField();if(mathField){if(translator){translator(mathField,key);}this.setState({cursorContext:getCursorContext(mathField)});}if(e?.type==="click"){this.focus();}};}}InnerMathInput.contextType=PerseusI18nContext;InnerMathInput.defaultProps={value:"",convertDotToTimes:false};class MathInput extends React.Component{blur(){this.inputRef.current?.blur();}focus(){this.inputRef.current?.focus();}insert(value){this.inputRef.current?.insert(value);}render(){return jsxRuntimeExports.jsx(InnerMathInput,{...this.props,ref:this.inputRef,mathInputStrings:this.context.strings})}constructor(...args){super(...args),this.inputRef=React.createRef();}}MathInput.contextType=MathInputI18nContext;MathInput.defaultProps={ariaLabel:"Math input"};const MathInputIcon=({hovered,focused,pressed,active})=>{let fillColor;switch(true){case focused||pressed||active:fillColor=semanticColor.core.foreground.knockout.default;break;case hovered:fillColor=semanticColor.core.foreground.instructive.strong;break;default:fillColor=semanticColor.core.foreground.neutral.default;break}let dynamicClass;switch(true){case focused||pressed:dynamicClass=styles$D.iconActive;break;case active:dynamicClass=styles$D.iconExpanded;break;case hovered:dynamicClass=styles$D.iconHovered;break;default:dynamicClass=styles$D.iconInactive;}return jsxRuntimeExports.jsx(View,{style:[styles$D.iconContainer,dynamicClass],children:jsxRuntimeExports.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",fill:fillColor,viewBox:"0 0 256 256",children:jsxRuntimeExports.jsx("path",{d:"M112,72a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16h64A8,8,0,0,1,112,72Zm-8,104H80V152a8,8,0,0,0-16,0v24H40a8,8,0,0,0,0,16H64v24a8,8,0,0,0,16,0V192h24a8,8,0,0,0,0-16Zm48,0h64a8,8,0,0,0,0-16H152a8,8,0,0,0,0,16Zm64,16H152a8,8,0,0,0,0,16h64a8,8,0,0,0,0-16Zm-61.66-90.34a8,8,0,0,0,11.32,0L184,83.31l18.34,18.35a8,8,0,0,0,11.32-11.32L195.31,72l18.35-18.34a8,8,0,0,0-11.32-11.32L184,60.69,165.66,42.34a8,8,0,0,0-11.32,11.32L172.69,72,154.34,90.34A8,8,0,0,0,154.34,101.66Z"})})})};const mapButtonSets=buttonSets=>{const keypadButtonSets={};if(!buttonSets){return keypadButtonSets}buttonSets.forEach(buttonSet=>{switch(buttonSet){case "advanced relations":keypadButtonSets.advancedRelations=true;break;case "basic relations":keypadButtonSets.basicRelations=true;break;case "basic+div":keypadButtonSets.divisionKey=true;break;case "logarithms":keypadButtonSets.logarithms=true;break;case "prealgebra":keypadButtonSets.preAlgebra=true;break;case "trig":keypadButtonSets.trigonometry=true;break;case "scientific":keypadButtonSets.scientific=true;break;}});return keypadButtonSets};const inputFocused={borderColor:semanticColor.core.border.instructive.default};const styles$D=StyleSheet.create({iconContainer:{display:"flex",justifyContent:"center",height:"100%",padding:sizing.size_060,borderRadius:border$1.radius.radius_040,borderWidth:border$1.width.medium,borderStyle:"solid"},iconInactive:{borderColor:semanticColor.core.transparent,backgroundColor:semanticColor.core.background.neutral.subtle},iconActive:{borderColor:semanticColor.focus.outer,boxShadow:`inset 0 0 0 ${border$1.width.medium} ${semanticColor.focus.inner}`,backgroundColor:semanticColor.core.background.neutral.default},iconExpanded:{borderColor:semanticColor.core.transparent,backgroundColor:semanticColor.core.background.neutral.default},iconHovered:{borderColor:semanticColor.core.transparent,backgroundColor:semanticColor.core.background.neutral.subtle},outerWrapper:{display:"inline-block",borderStyle:"solid",borderWidth:border$1.width.thin,borderColor:semanticColor.core.border.neutral.default,borderRadius:border$1.radius.radius_040,background:semanticColor.core.background.base.default,":hover":inputFocused},wrapperFocused:inputFocused,popoverContent:{padding:0,paddingBlockEnd:sizing.size_060,maxInlineSize:"initial"}});
1423
-
1424
- let _dependencies=null;const setDependencies=dependencies=>{_dependencies=dependencies;};const getDependencies=()=>{if(_dependencies){return _dependencies}throw new Error(["Perseus has not been provided required dependencies.","setDependencies(dependencies) must be called first.","Make sure Perseus is being imported from javascript/perseus/perseus.js."].join("\n"))};const DependenciesContext=React.createContext({analytics:{onAnalyticsEvent:async()=>{}},generateUrl:()=>{throw new Error("generateUrl dependency not provided in Perseus dependencies")},useVideo:()=>{throw new Error("useVideo dependency not provided in Perseus dependencies")}});const useDependencies=()=>{const deps=React.useContext(DependenciesContext);return deps};
1425
-
1426
- var dependencies = /*#__PURE__*/Object.freeze({
1427
- __proto__: null,
1428
- DependenciesContext: DependenciesContext,
1429
- getDependencies: getDependencies,
1430
- setDependencies: setDependencies,
1431
- useDependencies: useDependencies
1432
- });
1433
-
1434
- const ApiOptions={defaults:{isArticle:false,isMobile:false,isMobileApp:false,editingDisabled:false,onFocusChange:function(){},showAlignmentOptions:false,readOnly:false,baseElements:{Link:props=>{const{children,...rest}=props;return jsxRuntimeExports.jsx("a",{...rest,children:children})}}}};const ClassNames={RENDERER:"perseus-renderer",TWO_COLUMN_RENDERER:"perseus-renderer-two-columns",RESPONSIVE_RENDERER:"perseus-renderer-responsive",INPUT:"perseus-input",FOCUSED:"perseus-focused",MOBILE:"perseus-mobile"};
1435
-
1436
- const getPromptJSON$q=(label,userInput)=>{return {type:"expression",label,userInput:{value:userInput}}};
1437
-
1438
- const englishOperators={arctg:"arctan",cosec:"csc",cossec:"csc",cotg:"cot",ctg:"cot",sen:"sin",tg:"tan"};const anglicizeOperators=tex=>{return tex.replace(/\\operatorname{([a-z]+)}/g,(_,op)=>`\\${englishOperators[op]??op} `)};const normalizeTex=tex=>{return anglicizeOperators(tex)};const defaultOnFocus=()=>{};const defaultOnBlur=()=>{};const KeypadInputWithInterface=React.forwardRef(function KeypadInputWithInterface(props,ref){const keypadInputRef=React.useRef(null);const noopKeypadActivation=_keypadActive=>{};React.useImperativeHandle(ref,()=>({focus:(cb=noopKeypadActivation)=>keypadInputRef.current?.focus(cb),blur:()=>keypadInputRef.current?.blur(),insert:val=>{keypadInputRef.current?.mathField?.pressKey?.(val);}}));return jsxRuntimeExports.jsx(KeypadInput,{ref:keypadInputRef,...props})});const Expression=forwardRef(function Expression(props,ref){const{apiOptions=ApiOptions.defaults,onFocus=defaultOnFocus,onBlur=defaultOnBlur,userInput="",keypadElement,handleUserInput,trackInteraction,widgetId,options:{buttonSets,times,extraKeys,visibleLabel,ariaLabel,buttonsVisible,functions},...rest}=props;const{strings}=usePerseusI18n();const{analytics}=useDependencies();const isRequired=props.isScorable&&!props.reviewMode&&!props.static&&!apiOptions.readOnly;const{setKeypadActive}=React.useContext(KeypadContext);const textareaId=useId();const inputRef=useRef(null);const rootRef=useRef(null);useEffect(()=>{analytics?.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"expression",widgetId}});if(rootRef.current){const isMobile=apiOptions.customKeypad;const selector=isMobile?".mq-textarea > span":"textarea";const inputElement=rootRef.current.querySelector(selector);if(inputElement instanceof HTMLElement){inputElement.setAttribute("id",textareaId);}}},[]);const handleFocus=()=>{analytics?.onAnalyticsEvent({type:"perseus:expression-focused",payload:null});onFocus([]);};const handleBlur=()=>{onBlur([]);};const changeAndTrack=(value,cb)=>{const normalized=normalizeTex(value);handleUserInput(normalized,cb);trackInteraction();};const mobileHandleFocus=()=>{keypadElement?.configure(getKeypadConfiguration(),()=>{if(rootRef.current){handleFocus();}});};const getKeypadConfiguration=useCallback(()=>{return {keypadType:"EXPRESSION",extraKeys:extraKeys,times:times}},[extraKeys,times]);const getFocusTarget=useCallback(()=>{if(!rootRef.current){return null}const isMobile=apiOptions.customKeypad;const selector=isMobile?".mq-textarea > span":"textarea";const element=rootRef.current.querySelector(selector);return element instanceof HTMLElement?element:null},[apiOptions.customKeypad]);useImperativeHandle(ref,()=>({focus:()=>{const targetBefore=getFocusTarget();inputRef.current?.focus?.(setKeypadActive);const targetAfter=getFocusTarget()??targetBefore??(document.activeElement instanceof HTMLElement?document.activeElement:null);if(!targetAfter){return false}if(document.activeElement!==targetAfter){targetAfter.focus();}return document.activeElement===targetAfter},focusInputPath:path=>{inputRef.current?.focus?.(setKeypadActive);},blurInputPath:path=>{if(typeof inputRef.current?.blur==="function"){inputRef.current?.blur();}},insert:keyPressed=>{inputRef.current?.insert?.(keyPressed);},getInputPaths:()=>[[]],getUserInput:()=>{return normalizeTex(userInput)},getKeypadConfiguration,getPromptJSON:()=>{return getPromptJSON$q(visibleLabel,normalizeTex(userInput))},getSerializedState:()=>{return {...rest,value:userInput,keypadConfiguration:getKeypadConfiguration(),times,buttonSets,buttonsVisible,functions}}}));const keypadConfiguration=getKeypadConfiguration();if(apiOptions.customKeypad){return jsxRuntimeExports.jsxs(View,{ref:rootRef,style:styles$C.mobileLabelInputWrapper,children:[!!visibleLabel&&jsxRuntimeExports.jsx(BodyText,{size:"small",htmlFor:textareaId,tag:"label",children:visibleLabel}),jsxRuntimeExports.jsx(KeypadInputWithInterface,{ref:inputRef,ariaLabel:ariaLabel||strings.mathInputBox,ariaRequired:isRequired,value:userInput,keypadElement:keypadElement,onChange:changeAndTrack,onFocus:mobileHandleFocus,onBlur:handleBlur})]})}return jsxRuntimeExports.jsxs(View,{ref:rootRef,style:styles$C.desktopLabelInputWrapper,children:[!!visibleLabel&&jsxRuntimeExports.jsx(BodyText,{size:"small",htmlFor:textareaId,tag:"label",children:visibleLabel}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-expression",children:jsxRuntimeExports.jsx(MathInput,{ref:inputRef,value:userInput,onChange:changeAndTrack,convertDotToTimes:times,buttonSets:buttonSets,onFocus:handleFocus,onBlur:handleBlur,ariaLabel:ariaLabel||strings.mathInputBox,ariaRequired:isRequired,extraKeys:keypadConfiguration.extraKeys,onAnalyticsEvent:analytics?.onAnalyticsEvent??(async()=>{})})})]})});const styles$C=StyleSheet.create({mobileLabelInputWrapper:{paddingBlockStart:"15px",paddingInline:"4px",paddingBlockEnd:"0"},desktopLabelInputWrapper:{marginBlockStart:"5px",marginInline:"5px",marginBlockEnd:"0"}});function getUserInputFromSerializedState$i(serializedState){return normalizeTex(serializedState.value)}function getStartUserInput$i(){return ""}function getOneCorrectAnswerFromRubric$1(rubric){const correctAnswers=(rubric.answerForms||[]).filter(answerForm=>answerForm.considered==="correct");if(correctAnswers.length===0){return}return correctAnswers[0].value}function getCorrectUserInput$9(options){for(const form of options.answerForms){if(form.considered==="correct"){return form.value}}return ""}var Expression$1 = {name:"expression",displayName:"Expression / Equation",widget:Expression,isLintable:true,getOneCorrectAnswerFromRubric: getOneCorrectAnswerFromRubric$1,getStartUserInput: getStartUserInput$i,getCorrectUserInput: getCorrectUserInput$9,getUserInputFromSerializedState: getUserInputFromSerializedState$i};
1439
-
1440
- class SimpleKeypadInput extends React.Component{componentDidMount(){this._isMounted=true;}componentWillUnmount(){this._isMounted=false;}focus(){this.inputRef.current?.focus(this.context.setKeypadActive);}blur(){this.inputRef.current?.blur();}getValue(){return this.props.value}render(){const _this=this;const{keypadElement,onFocus,value,...rest}=_this.props;return jsxRuntimeExports.jsx(KeypadInput,{ref:this.inputRef,keypadElement:keypadElement,onFocus:()=>{if(keypadElement){keypadElement.configure({keypadType:"FRACTION"},()=>{if(_this._isMounted){onFocus?.();}});}else {onFocus?.();}},value:value==null?"":""+value,...rest})}constructor(...args){super(...args),this._isMounted=false,this.inputRef=React.createRef();}}SimpleKeypadInput.contextType=KeypadContext;SimpleKeypadInput.propTypes={keypadElement:keypadElementPropType,onFocus:PropTypes.func,value:PropTypes.oneOfType([PropTypes.string,PropTypes.number])};
1441
-
1442
- const getPromptJSON$p=widgetData=>{return {type:"numeric-input",label:widgetData.options.labelText??"",userInput:{value:widgetData.userInput.currentValue}}};
1443
-
1444
- let lastId=0;function uniqueIdForInput(prefix="input-"){lastId++;return `${prefix}${lastId}`}class TextInput extends React.Component{render(){const{labelText,value,onFocus,onBlur,disabled,placeholder,onKeyDown,style,className}=this.props;const formattedValue=value===null?"":value.toString();const ariaLabel=labelText||undefined;return jsxRuntimeExports.jsx(TextField,{ref:this.inputRef,className:className,style:style,disabled:disabled,id:this.id,value:formattedValue,type:"text","aria-label":ariaLabel,"aria-describedby":this.props["aria-describedby"],"aria-required":this.props["aria-required"],onChange:value=>this.props.onChange(value),placeholder:placeholder,testId:"input-with-examples",onFocus:onFocus,onBlur:onBlur,onKeyDown:onKeyDown,autoCorrect:"off",autoCapitalize:"off",autoComplete:"off"})}constructor(props){super(props),this.inputRef=React.createRef(),this._getInput=()=>{if(!this.inputRef.current){throw new PerseusError("Input ref accessed before set",Errors.Internal)}return this.inputRef.current},this.focus=()=>{this._getInput().focus();},this.blur=()=>{this._getInput().blur();},this.getValue=()=>{return this.inputRef.current?.value},this.getStringValue=()=>{return this.inputRef.current?.value.toString()},this.setSelectionRange=(selectionStart,selectionEnd)=>{this._getInput().setSelectionRange(selectionStart,selectionEnd);},this.getSelectionStart=()=>{return this._getInput().selectionStart},this.getSelectionEnd=()=>{return this._getInput().selectionEnd};if(props.id){this.id=props.id;}else {this.id=uniqueIdForInput();}}}TextInput.defaultProps={value:"",disabled:false};
1445
-
1446
- const defaultContext$1={assetStatuses:{},setAssetStatus:(assetKey,loaded)=>{}};const context=React.createContext(defaultContext$1);
1447
-
1448
- let supportsPassive=false;const nestedMap$2=function(children,func,context){if(Array.isArray(children)){return children.map(function(child){return nestedMap$2(child,func)})}return func.call(context,children)};function inputPathsEqual(a,b){if(a==null||b==null){return a==null===(b==null)}return a.length===b.length&&a.every((item,index)=>{return b[index]===item})}const rWidgetRule=/^\[\[\u2603 (([a-z-]+) ([0-9]+))]]/;const rTypeFromWidgetId=/^([a-z-]+) ([0-9]+)$/;const rWidgetParts=new RegExp(rWidgetRule.source+"$");const snowman="☃";const isBlockWidgetNode=node=>node?.type==="widget"&&!CoreWidgetRegistry.isInlineWidget(node.widgetType);const isParagraphWithBlockWidget=node=>node?.type==="paragraph"&&Array.isArray(node.content)&&node.content.some(isBlockWidgetNode);const inlineWidgetsToExclude=node=>{const widgetsToExclude=["dropdown","explanation","expression"];return node?.type==="widget"&&widgetsToExclude.includes(node.widgetType)};const nodeIsGraphie=node=>{return node.type==="image"&&node.target.startsWith("web+graphie:")};const isContentGraphie=node=>{return Array.isArray(node.content)&&node.content.some(nodeIsGraphie)};const noParagraphForInlineWidget=node=>Array.isArray(node.content)&&node.content.some(inlineWidgetsToExclude);const isWhitespaceOnlyTextNode=node=>node?.type==="text"&&node.content.trim()==="";const trimEdgeWhitespaceNodes=nodes=>{let start=0;let end=nodes.length;while(start<end&&isWhitespaceOnlyTextNode(nodes[start])){start++;}while(end>start&&isWhitespaceOnlyTextNode(nodes[end-1])){end--;}return nodes.slice(start,end)};const mergeInlineNodes=(inlineNodes,blockNodes,referenceNode)=>{const trimmedContentNodes=trimEdgeWhitespaceNodes(inlineNodes);if(trimmedContentNodes.length>0){blockNodes.push({...referenceNode,content:trimmedContentNodes});}};function joinAdjacentTextNodes(ast){if(!Array.isArray(ast)){return ast}const joined=[];for(const node of ast){const lastIndex=joined.length-1;if(node.type==="text"&&joined[lastIndex]?.type==="text"){joined[lastIndex].content+=node.content;}else {joined.push(node);}}return joined}function splitBlockWidgetsFromParagraphs(ast){if(!Array.isArray(ast)){return ast}return ast.flatMap(node=>{if(!isParagraphWithBlockWidget(node)){return node}const blockNodes=[];const inlineNodes=[];node.content.forEach(childNode=>{if(isBlockWidgetNode(childNode)){mergeInlineNodes(inlineNodes,blockNodes,node);blockNodes.push(childNode);inlineNodes.length=0;}else {inlineNodes.push(childNode);}});mergeInlineNodes(inlineNodes,blockNodes,node);return blockNodes})}function firstNumericalParse$1(text){let first;const val=KhanAnswerTypes.predicate.createValidatorFunctional(function(ans){first=ans;return true},{simplify:"optional",inexact:true,forms:"integer, proper, improper, pi, log, mixed, decimal"});val(String(text));return first}function stringArrayOfSize(size){return Array(size).fill("")}function stringArrayOfSize2D(opt){const{rows,columns}=opt;const rowArr=stringArrayOfSize(rows);return rowArr.map(()=>stringArrayOfSize(columns))}function gridDimensionConfig(absTickStep,extent,dimensionConstraint,gridStep){const scale=scaleFromExtent(extent,dimensionConstraint);const stepPx=absTickStep*scale;const unityLabel=stepPx>30;return {scale:scale,tickStep:absTickStep/gridStep,unityLabel:unityLabel}}function getGridStep(range,step,boxSize){return _(2).times(function(i){const scale=scaleFromExtent(range[i],boxSize);const gridStep=gridStepFromTickStep(step[i],scale);return gridStep})}function snapStepFromGridStep(gridStep){return [gridStep[0]/2,gridStep[1]/2]}function gridStepFromTickStep(tickStep,scale){const tickWidth=tickStep*scale;const x=tickStep;const y=Math.pow(10,Math.floor(Math.log(x)/Math.LN10));const leadingDigit=Math.floor(x/y);if(tickWidth<25){return tickStep}if(tickWidth<50){if(leadingDigit===5){return tickStep}return tickStep/2}if(leadingDigit===1){return tickStep/2}if(leadingDigit===2){return tickStep/4}if(leadingDigit===5){return tickStep/5}}function scaleFromExtent(extent,dimensionConstraint){const span=extent[1]-extent[0];const scale=dimensionConstraint/span;return scale}function tickStepFromExtent(extent,dimensionConstraint){const span=extent[1]-extent[0];let tickFactor;if(15<span&&span<=20){tickFactor=23;}else if(span>100||span<5){tickFactor=10;}else {tickFactor=16;}const constraintFactor=dimensionConstraint/500;const desiredNumTicks=tickFactor*constraintFactor;return tickStepFromNumTicks(span,desiredNumTicks)}function tickStepFromNumTicks(span,numTicks){let step=Math.pow(10,Math.floor(Math.log(span/numTicks)/Math.LN10));const err=numTicks/span*step;if(err<=.15){step*=10;}else if(err<=.35){step*=5;}else if(err<=.75){step*=2;}return step}const constrainTickStep=(step,range)=>{const span=range[1]-range[0];const numTicks=span/step;if(numTicks<=10){return step}if(numTicks<=20){return step*2}return tickStepFromNumTicks(span,10)};function constrainedTickStepsFromTickSteps(tickSteps,ranges){return [constrainTickStep(tickSteps[0],ranges[0]),constrainTickStep(tickSteps[1],ranges[1])]}function parseQueryString(query){query=query||window.location.search.substring(1);const urlParams={};const a=/\+/g;const r=/([^&=]+)=?([^&]*)/g;const d=function(s){return decodeURIComponent(s.replace(a," "))};let e;while(e=r.exec(query)){const m=e;urlParams[d(m[1])]=d(m[2]);}return urlParams}function updateQueryString$2(uri,key,value){value=encodeURIComponent(value);const re=new RegExp("([?&])"+key+"=.*?(&|$)","i");const separator=uri.indexOf("?")!==-1?"&":"?";if(uri.match(re)){return uri.replace(re,"$1"+key+"="+value+"$2")}return uri+separator+key+"="+value}function strongEncodeURIComponent(str){return encodeURIComponent(str).replace(/['()!]/g,window.escape).replace(/\*/g,"%2A")}const touchHandlers={pointerDown:false,currentTouchIdentifier:null};function resetTouchHandlers(){Object.assign(touchHandlers,{pointerDown:false,currentTouchIdentifier:null});}function extractPointerLocation(event){let touchOrEvent;if(touchHandlers.pointerDown){if(touchHandlers.currentTouchIdentifier!=null){const len=event.changedTouches?event.changedTouches.length:0;for(let i=0;i<len;i++){if(event.changedTouches[i].identifier===touchHandlers.currentTouchIdentifier){touchOrEvent=event.changedTouches[i];}}}else {touchOrEvent=event;}const isEndish=event.type==="touchend"||event.type==="touchcancel";if(touchOrEvent&&isEndish){touchHandlers.pointerDown=false;touchHandlers.currentTouchIdentifier=null;}}else {touchHandlers.pointerDown=true;if(event.changedTouches){touchOrEvent=event.changedTouches[0];touchHandlers.currentTouchIdentifier=touchOrEvent.identifier;}else {touchOrEvent=event;}}if(touchOrEvent){return {left:touchOrEvent.pageX,top:touchOrEvent.pageY}}}const supportsPassiveEvents=()=>{try{const opts=Object.defineProperty({},"passive",{get:function(){supportsPassive=true;}});window.addEventListener("testPassive",null,opts);window.removeEventListener("testPassive",null,opts);}catch{}return supportsPassive};function captureScratchpadTouchStart$2(e){e.stopPropagation();}function getImageSize(url,callback){const img=new Image;img.onload=function(){if(img.width===0&&img.height===0){document.body?.appendChild(img);_.defer(function(){callback(img.clientWidth,img.clientHeight);document.body?.removeChild(img);});}else {callback(img.width,img.height);}};img.src=getRealImageUrl(url);}function getWordBeforeCursor(textarea){const text=textarea.value;const endPos=textarea.selectionStart-1;const startPos=Math.max(text.lastIndexOf("\n",endPos),text.lastIndexOf(" ",endPos))+1;return {string:text.substring(startPos,endPos+1),pos:{start:startPos,end:endPos}}}function moveCursor(textarea,pos){textarea.selectionStart=pos;textarea.selectionEnd=pos;}const textarea={getWordBeforeCursor,moveCursor};const unescapeMathMode$1=label=>label.startsWith("$")&&label.endsWith("$")?label.slice(1,-1):label;const Util={inputPathsEqual,nestedMap: nestedMap$2,rWidgetRule,rTypeFromWidgetId,rWidgetParts,snowman,splitBlockWidgetsFromParagraphs,firstNumericalParse: firstNumericalParse$1,stringArrayOfSize,stringArrayOfSize2D,gridDimensionConfig,getGridStep,snapStepFromGridStep,scaleFromExtent,tickStepFromExtent,gridStepFromTickStep,tickStepFromNumTicks,constrainedTickStepsFromTickSteps,parseQueryString,updateQueryString: updateQueryString$2,strongEncodeURIComponent,touchHandlers,resetTouchHandlers,extractPointerLocation,supportsPassiveEvents,captureScratchpadTouchStart: captureScratchpadTouchStart$2,getImageSize,getImageSizeModern:getImageSizeModern,getRealImageUrl:getRealImageUrl,isLabeledSVG:isLabeledSVG,getBaseUrl:getBaseUrl,getSvgUrl:getSvgUrl,getDataUrl:getDataUrl,textarea,unescapeMathMode: unescapeMathMode$1,joinAdjacentTextNodes};
1449
-
1450
- const KhanColors={BLUE:color.blue,PINK:"#FF00AF",GREEN:color.green,PURPLE:"#9D38BD",RED:"#DF0030",GRAY:"gray",BLACK:"black",LIGHT_BLUE:"#9AB8ED",LIGHT_ORANGE:"#EDD19B",LIGHT_PINK:"#ED9BD3",LIGHT_GREEN:"#9BEDCE",LIGHT_PURPLE:"#DA9BED",LIGHT_RED:"#ED9AAC",GRAY_C:"#E3E5E6",GRAY_G:"#626569",INTERACTING:color.green,INTERACTIVE:color.green,DYNAMIC:color.blue};const getBackgroundColor=elementToInspect=>{const backgroundColor=window.getComputedStyle(elementToInspect).backgroundColor;if(backgroundColor!=="rgba(0, 0, 0, 0)"&&backgroundColor!=="transparent"){return backgroundColor}const parentElement=elementToInspect.parentElement;if(parentElement?.tagName.toLowerCase()==="html"||!parentElement){return "var(--wb-semanticColor-core-background-base-default)"}return getBackgroundColor(parentElement)};const resolveColorCache=new Map;function resolveColor(color){const cached=resolveColorCache.get(color);if(cached!=null){return cached}if(color[0]==="#"){return parseHexColor(color)}const canvas=document.createElement("canvas");const ctx=canvas.getContext("2d");if(!ctx){return {r:0,g:0,b:0}}ctx.fillStyle=color;ctx.fillRect(0,0,1,1);const[r,g,b]=ctx.getImageData(0,0,1,1).data;const resolved={r,g,b};resolveColorCache.set(color,resolved);return resolved}const lightModeHexForMathColor={[semanticColor.learning.math.foreground.blue]:"#3D7586",[semanticColor.learning.math.foreground.gold]:"#946700",[semanticColor.learning.math.foreground.green]:"#447A53",[semanticColor.learning.math.foreground.gray]:"#5D5F66",[semanticColor.learning.math.foreground.grayH]:"#3B3D45",[semanticColor.learning.math.foreground.grayI]:"#21242C",[semanticColor.learning.math.foreground.purple]:"#594094",[semanticColor.learning.math.foreground.purpleD]:"#8351E8",[semanticColor.learning.math.foreground.pink]:"#B25071",[semanticColor.learning.math.foreground.red]:"#D92916"};function toClosestMathColor(target){const targetRGB=resolveColor(target);let closestRGB={r:0,g:0,b:0};let closestCSSVar=semanticColor.core.foreground.neutral.strong;for(const[cssVar,hex]of Object.entries(lightModeHexForMathColor)){const candidate=resolveColor(hex);if(diffColors(targetRGB,candidate)<diffColors(targetRGB,closestRGB)){closestRGB=candidate;closestCSSVar=cssVar;}}return closestCSSVar}function parseHexColor(hex){const threeDigitMatch=hex.match(/^#([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])?$/);if(threeDigitMatch){return {r:parseInt(threeDigitMatch[1],16)*17,g:parseInt(threeDigitMatch[2],16)*17,b:parseInt(threeDigitMatch[3],16)*17}}const sixDigitMatch=hex.match(/^#([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})?$/);if(sixDigitMatch){return {r:parseInt(sixDigitMatch[1],16),g:parseInt(sixDigitMatch[2],16),b:parseInt(sixDigitMatch[3],16)}}return {r:0,g:0,b:0}}function diffColors(a,b){const redMean=(a.r+b.r)/2;const redWeight=2+redMean/256;const blueWeight=2+(255-redMean)/256;const greenWeight=4;const dr=a.r-b.r;const dg=a.g-b.g;const db=a.b-b.b;return redWeight*dr*dr+greenWeight*dg*dg+blueWeight*db*db}
1451
-
1452
- const Log={log:(message,extra)=>{getDependencies().Log.log(message,extra);},error:(message,kind,extra)=>{getDependencies().Log.error(message,kind,extra);}};
1453
-
1454
- const svgLocalLabelsRegex=/^file\+graphie:/;const hashRegex=/\/([^/]+)$/;function getLocale(){const{JIPT,kaLocale}=getDependencies();return JIPT.useJIPT?"en-pt":kaLocale}function shouldUseLocalizedData(){return getLocale()!=="en"}const splitHashRegex=/\/(?=[^/]+$)/;function getLocalizedDataUrl(url){if(svgLocalLabelsRegex.test(url)){return Util.getDataUrl(url)}const[base,hash]=Util.getBaseUrl(url).split(splitHashRegex);return `${base}/${getLocale()}/${hash}-data.json`}function getUrlHash(url){const match=url.match(hashRegex);if(match==null){throw new PerseusError("not a valid URL",Errors.InvalidInput)}return match&&match[1]}function parseDataFromJSONP(graphieHash,graphieJSONP,errorCallback){const match=graphieJSONP.match(new RegExp(`^(?:svgData|svgOtherData)${graphieHash}\\((.+)\\);$`));const jsonToParse=match?match[1]:graphieJSONP;try{return JSON.parse(jsonToParse)}catch(error){errorCallback(error);return null}}let labelDataCache={};function loadGraphie(url,onDataLoaded){const hash=getUrlHash(url);const entry=labelDataCache[hash];if(entry!=null){if(entry.loaded){const{data,localized}=entry;onDataLoaded(data,localized);}else {entry.dataCallbacks.push(onDataLoaded);}}else {const cacheData={loaded:false,dataCallbacks:[onDataLoaded],localized:shouldUseLocalizedData()};labelDataCache[hash]=cacheData;const retrieveData=async(url,errorCallback)=>{const response=await fetch(url);if(!response?.ok){errorCallback();return}const jsonp=await response.text();const data=parseDataFromJSONP(hash,jsonp,error=>{Log.error("Failed to parse JSONP for svg-image",Errors.Service,{cause:error,loggedMetadata:{dataUrl:Util.getDataUrl(url),jsonp}});});if(!data){return}const newCacheEntry=labelDataCache[hash]={...labelDataCache[hash],loaded:true,data};newCacheEntry.dataCallbacks.forEach(callback=>{callback(newCacheEntry.data,cacheData.localized);});};const dataLoadErrorHandler=(x,status,error)=>{Log.error("Data load failed for svg-image",Errors.Service,{cause:error,loggedMetadata:{dataUrl:Util.getDataUrl(url),status}});};if(shouldUseLocalizedData()){retrieveData(getLocalizedDataUrl(url),()=>{cacheData.localized=false;retrieveData(Util.getDataUrl(url),dataLoadErrorHandler);});}else {retrieveData(Util.getDataUrl(url),dataLoadErrorHandler);}}}
1455
-
1456
- const boldFontFamily="'Lato-Bold', 'Lato', sans-serif";const white="#FFFFFF";const gray76="#BABEC2";const gray68="#888D93";const pureSmMin="568px";const pureMdMin$1="768px";const pureLgMin$1="1024px";const pureXlMin="1280px";const pureXsMax$1="567px";const pureSmMax$1="767px";const pureMdMax$1="1023px";const pureLgMax$1="1279px";const phoneMargin=16;const negativePhoneMargin=-16;const hintBorderWidth=sizing.size_040;const hintPaddingInlineStart=sizing.size_160;const interactiveSizes$1={defaultBoxSize:400,defaultBoxSizeSmall:288};const circleSize$1=24;const radioMarginWidth$1=2;const warningColor="#f86700";const warningColorHover="#df5c00";const warningColorActive="#c75300";const articleMaxWidthInPx=688;const articleMaxWidthTableInPx=512;
1457
-
1458
- var constants = /*#__PURE__*/Object.freeze({
1459
- __proto__: null,
1460
- articleMaxWidthInPx: articleMaxWidthInPx,
1461
- articleMaxWidthTableInPx: articleMaxWidthTableInPx,
1462
- boldFontFamily: boldFontFamily,
1463
- circleSize: circleSize$1,
1464
- gray68: gray68,
1465
- gray76: gray76,
1466
- hintBorderWidth: hintBorderWidth,
1467
- hintPaddingInlineStart: hintPaddingInlineStart,
1468
- interactiveSizes: interactiveSizes$1,
1469
- negativePhoneMargin: negativePhoneMargin,
1470
- phoneMargin: phoneMargin,
1471
- pureLgMax: pureLgMax$1,
1472
- pureLgMin: pureLgMin$1,
1473
- pureMdMax: pureMdMax$1,
1474
- pureMdMin: pureMdMin$1,
1475
- pureSmMax: pureSmMax$1,
1476
- pureSmMin: pureSmMin,
1477
- pureXlMin: pureXlMin,
1478
- pureXsMax: pureXsMax$1,
1479
- radioMarginWidth: radioMarginWidth$1,
1480
- warningColor: warningColor,
1481
- warningColorActive: warningColorActive,
1482
- warningColorHover: warningColorHover,
1483
- white: white
1484
- });
1485
-
1486
- const MIN_VIEWPORT_HEIGHT=480;class FixedToResponsive extends React.Component{componentDidMount(){this._isMounted=true;if(window.innerHeight<MIN_VIEWPORT_HEIGHT){setTimeout(this._cacheViewportSize,800);}else {this._cacheViewportSize();}}componentWillUnmount(){this._isMounted=false;}render(){const aspectRatio=this.props.width/this.props.height;let{width,height}=this.props;if(this.props.constrainHeight&&this.state.viewportHeight){const maxHeight=2/3*this.state.viewportHeight;if(this.props.height>=maxHeight){height=maxHeight;width=maxHeight*aspectRatio;}}const style={maxWidth:width,maxHeight:height,aspectRatio:aspectRatio.toFixed(4)};const className=classNames$2("fixed-to-responsive",this.props.className);const container=jsxRuntimeExports.jsx("div",{className:className,style:style,"data-scale":this.props.scale,children:this.props.children});const shouldFullBleed=this.props.allowFullBleed&&this.state.viewportWidth&&width>=this.state.viewportWidth;if(shouldFullBleed){return jsxRuntimeExports.jsx("div",{style:{marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin},children:container})}return container}constructor(...args){super(...args),this._isMounted=false,this.state={viewportHeight:null,viewportWidth:null},this._cacheViewportSize=()=>{if(this._isMounted){this.setState({viewportHeight:Math.max(MIN_VIEWPORT_HEIGHT,window.innerHeight),viewportWidth:window.innerWidth});}};}}FixedToResponsive.defaultProps={className:"",constrainHeight:false,allowFullBleed:false};
1487
-
1488
- const GifImage=props=>{const{alt,width,height,scale,isPlaying,onLoop,onLoad,gifFrames}=props;const framesRef=React.useRef([]);const canvasRef=React.useRef(null);const hiddenCanvasRef=React.useRef(null);const animationIdRef=React.useRef(null);const currentFrameIndexRef=React.useRef(0);const lastFrameTimeRef=React.useRef(null);const latestPropsRef=React.useRef({isPlaying,onLoop,onLoad});latestPropsRef.current={isPlaying,onLoop,onLoad};const drawPatch=React.useCallback(index=>{const frames=framesRef.current;const hiddenCtx=hiddenCanvasRef.current?.getContext("2d");const displayCtx=canvasRef.current?.getContext("2d");if(!hiddenCtx||!hiddenCanvasRef.current||!displayCtx||!canvasRef.current||frames.length===0){return}const frame=frames[index];const{dims}=frame;if(index>0){const prev=frames[index-1];if(prev.disposalType===2){displayCtx.clearRect(prev.dims.left,prev.dims.top,prev.dims.width,prev.dims.height);}}hiddenCanvasRef.current.width=dims.width;hiddenCanvasRef.current.height=dims.height;const imageData=new ImageData(new Uint8ClampedArray(frame.patch),dims.width,dims.height);hiddenCtx.putImageData(imageData,0,0);displayCtx.drawImage(hiddenCanvasRef.current,dims.left,dims.top);},[]);const drawFrame=React.useCallback((index=0)=>{const frames=framesRef.current;if(frames.length===0||!canvasRef.current||!hiddenCanvasRef.current){return}const targetIndex=Math.min(index,frames.length-1);currentFrameIndexRef.current=targetIndex;const{width:nativeWidth,height:nativeHeight}=frames[0].dims;canvasRef.current.width=nativeWidth;canvasRef.current.height=nativeHeight;for(let i=0;i<=targetIndex;i++){drawPatch(i);}},[drawPatch]);const pause=React.useCallback(()=>{if(animationIdRef.current!==null){cancelAnimationFrame(animationIdRef.current);animationIdRef.current=null;}},[]);const animate=React.useCallback(timestamp=>{const frames=framesRef.current;if(frames.length===0){return}if(lastFrameTimeRef.current===null){lastFrameTimeRef.current=timestamp;drawPatch(currentFrameIndexRef.current);}const frame=frames[currentFrameIndexRef.current];const delay=frame.delay<=0?10:frame.delay;if(timestamp-lastFrameTimeRef.current>=delay){currentFrameIndexRef.current++;if(currentFrameIndexRef.current>=frames.length){currentFrameIndexRef.current=0;animationIdRef.current=null;latestPropsRef.current.onLoop();return}drawPatch(currentFrameIndexRef.current);lastFrameTimeRef.current=lastFrameTimeRef.current+delay;}animationIdRef.current=requestAnimationFrame(animate);},[drawPatch]);const play=React.useCallback(()=>{if(framesRef.current.length===0){return}lastFrameTimeRef.current=null;animationIdRef.current=requestAnimationFrame(animate);},[animate]);const restart=React.useCallback(()=>{pause();drawFrame(0);},[pause,drawFrame]);React.useEffect(()=>{framesRef.current=gifFrames??[];currentFrameIndexRef.current=0;lastFrameTimeRef.current=null;drawFrame(0);latestPropsRef.current.onLoad?.();if(latestPropsRef.current.isPlaying){play();}return ()=>pause()},[gifFrames]);const prevIsPlayingRef=React.useRef(isPlaying);React.useEffect(()=>{const wasPlaying=prevIsPlayingRef.current;prevIsPlayingRef.current=isPlaying;if(isPlaying&&!wasPlaying){play();}if(!isPlaying&&wasPlaying){if(currentFrameIndexRef.current===0){restart();}else {pause();}}},[isPlaying,restart,play,pause,drawFrame]);const setCanvasRef=React.useCallback(canvas=>{canvasRef.current=canvas;if(canvas&&framesRef.current.length>0){drawFrame(0);}},[drawFrame]);const displayHeight=!width&&height?height*scale:undefined;const aspectRatio=width&&height?`${width} / ${height}`:undefined;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("canvas",{"aria-label":alt,role:"img",ref:setCanvasRef,"data-testid":"gif-canvas",style:{width:width?width*scale:undefined,maxInlineSize:"100%",aspectRatio:aspectRatio,height:displayHeight}}),jsxRuntimeExports.jsx("canvas",{"aria-hidden":true,tabIndex:-1,ref:hiddenCanvasRef,"data-testid":"gif-hidden-canvas",style:{display:"none"}})]})};
1489
-
1490
- function getKey$2(eventName,id){return eventName+":"+id}function getEventName$2(key){return key.split(":")[0]}const MovableHelperMethods={_fireEvent:function(listeners,...args){for(const listener of listeners){listener.call(this,...args);}},_applyConstraints:function(current,previous,extraOptions){let skipRemaining=false;return _.reduce(this.state.constraints,(memo,constraint)=>{if(memo===false){return false}if(skipRemaining){return memo}const result=constraint.call(this,memo,previous,{onSkipRemaining:()=>{skipRemaining=true;},...extraOptions});if(result===false){return false}if(point.is(result,2)){return result}if(result===true||result==null){return memo}throw new PerseusError("Constraint returned invalid result: "+result,Errors.Internal)},current,this)},draw:function(){const currState=this.cloneState();MovableHelperMethods._fireEvent.call(this,this.state.draw,currState,this.prevState);this.prevState=currState;},listen:function(eventName,id,func){this._listenerMap=this._listenerMap||{};const key=getKey$2(eventName,id);const index=this._listenerMap[key]=this._listenerMap[key]||this.state[eventName].length;this.state[eventName][index]=func;},unlisten:function(eventName,id){this._listenerMap=this._listenerMap||{};const key=getKey$2(eventName,id);const index=this._listenerMap[key];if(index!==undefined){this.state[eventName].splice(index,1);delete this._listenerMap[key];const keys=Object.keys(this._listenerMap);_.each(keys,function(key){if(getEventName$2(key)===eventName&&this._listenerMap[key]>index){this._listenerMap[key]--;}},this);}}};
1491
-
1492
- let prefixedTransform=null;function computePrefixedTransform(){const el=document.createElement("div");const prefixes=["transform","msTransform","MozTransform","WebkitTransform","OTransform"];let correctPrefix=null;_.each(prefixes,function(prefix){if(typeof el.style[prefix]!=="undefined"){correctPrefix=prefix;}});return correctPrefix}let canUse3dTransform=null;function computeCanUse3dTransform(){const el=document.createElement("div");const prefix=InteractiveUtil.getPrefixedTransform();el.style[prefix]="translateZ(0px)";return !!el.style[prefix]}const FUNCTION_ARRAY_OPTIONS=["add","modify","draw","remove","constraints","onMoveStart","onMove","onMoveEnd","onClick"];const InteractiveUtil={assert:function(isTrue,message){if(!isTrue){throw new PerseusError("Assertion Error"+(message?": "+message:""),Errors.Internal)}},createGettersFor:function(Class,defaults){_.each(Object.keys(defaults),function(key){if(Class.prototype[key]===undefined){Class.prototype[key]=function(){return this.state[key]};}});},addMovableHelperMethodsTo:function(Class){_.each(MovableHelperMethods,function(methodFunc,methodName){if(Class.prototype[methodName]===undefined){Class.prototype[methodName]=methodFunc;}});},arrayify:function(funcOrArray){if(funcOrArray==null){return []}if(Array.isArray(funcOrArray)){return _.filter(_.flatten(funcOrArray),x=>x)}return [funcOrArray]},normalizeOptions:function(options){const result={...options};FUNCTION_ARRAY_OPTIONS.forEach(function(eventName){if(options[eventName]!==undefined){result[eventName]=InteractiveUtil.arrayify(options[eventName]);}});return result},getPrefixedTransform:function(){prefixedTransform=prefixedTransform||computePrefixedTransform();return prefixedTransform},getCanUse3dTransform:function(){if(canUse3dTransform==null){canUse3dTransform=computeCanUse3dTransform();}return canUse3dTransform}};
1493
-
1494
- function _class_private_field_loose_base(receiver, privateKey) {
1495
- if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
1496
- throw new TypeError("attempted to use private field on non-instance");
1497
- }
1498
-
1499
- return receiver;
1500
- }
1501
-
1502
- var id = 0;
1503
-
1504
- function _class_private_field_loose_key(name) {
1505
- return "__private_" + id++ + "_" + name;
1506
- }
1507
-
1508
- /*!
1509
- * Raphael 1.5.2 - JavaScript Vector Library
1510
- *
1511
- * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
1512
- * Licensed under the MIT (http://raphaeljs.com/license.html) license.
1513
- */var Raphael$1 = (function(){var setAttr;if("".trim){setAttr=function(node,att,value){node.setAttribute(att,String(value).trim());};}else {setAttr=function(node,att,value){node.setAttribute(att,String(value));};}function R(){if(R.is(arguments[0],array)){var a=arguments[0],cnv=create[apply](R,a.splice(0,3+R.is(a[0],nu))),res=cnv.set();for(var i=0,ii1=a[length];i<ii1;i++){var j=a[i]||{};elements[has](j.type)&&res[push](cnv[j.type]().attr(j));}return res}return create[apply](R,arguments)}R.version="1.5.2";var separator=/[, ]+/,elements={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},formatrg=/\{(\d+)\}/g,proto="prototype",has="hasOwnProperty",doc=document,win=window,oldRaphael={was:Object[proto][has].call(win,"Raphael"),is:win.Raphael},Paper=function(){this.customAttributes={};},paperproto,appendChild="appendChild",apply="apply",concat="concat",supportsTouch="createTouch"in doc,E="",S=" ",Str=String,split="split",events="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[split](S),touchMap={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},join="join",length="length",lowerCase=Str[proto].toLowerCase,math=Math,mmax=math.max,mmin=math.min,abs=math.abs,pow=math.pow,PI=math.PI,nu="number",string="string",array="array",toString="toString",fillString="fill",objectToString=Object[proto][toString],push="push",ISURL=/^url\(['"]?([^\)]+?)['"]?\)$/i,colourRegExp=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,isnan={"NaN":1,"Infinity":1,"-Infinity":1},bezierrg=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,round=math.round,toFloat=parseFloat,toInt=parseInt,ms=" progid:DXImageTransform.Microsoft",upperCase=Str[proto].toUpperCase,availableAttrs={blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},availableAnimAttrs={along:"along",blur:nu,"clip-rect":"csv",cx:nu,cy:nu,fill:"colour","fill-opacity":nu,"font-size":nu,height:nu,opacity:nu,path:"path",r:nu,rotation:"csv",rx:nu,ry:nu,scale:"csv",stroke:"colour","stroke-opacity":nu,"stroke-width":nu,translation:"csv",width:nu,x:nu,y:nu},rp="replace",animKeyFrames=/^(from|to|\d+%?)$/,commaSpaces=/\s*,\s*/,hsrg={hs:1,rg:1},p2s=/,?([achlmqrstvxz]),?/gi,pathCommand=/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,pathValues=/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,radial_gradient=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,sortByKey=function(a,b){return a.key-b.key};R.type=win.SVGAngle||doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML";if(R.type=="VML"){var d=doc.createElement("div"),b;d.innerHTML='<v:shape adj="1"/>';b=d.firstChild;b.style.behavior="url(#default#VML)";if(!(b&&typeof b.adj=="object")){return R.type=null}d=null;}R.svg=!(R.vml=R.type=="VML");Paper[proto]=R[proto];paperproto=Paper[proto];R._id=0;R._oid=0;R.fn={};R.is=function(o,type){type=lowerCase.call(type);if(type=="finite"){return !isnan[has](+o)}return type=="null"&&o===null||type==typeof o||type=="object"&&o===Object(o)||type=="array"&&Array.isArray&&Array.isArray(o)||objectToString.call(o).slice(8,-1).toLowerCase()==type};R.angle=function(x1,y1,x2,y2,x3,y3){if(x3==null){var x=x1-x2,y=y1-y2;if(!x&&!y){return 0}return ((x<0)*180+math.atan(-y/-x)*180/PI+360)%360}else {return R.angle(x1,y1,x3,y3)-R.angle(x2,y2,x3,y3)}};R.rad=function(deg){return deg%360*PI/180};R.deg=function(rad){return rad*180/PI%360};R.snapTo=function(values,value,tolerance){tolerance=R.is(tolerance,"finite")?tolerance:10;if(R.is(values,array)){var i=values.length;while(i--)if(abs(values[i]-value)<=tolerance){return values[i]}}else {values=+values;var rem=value%values;if(rem<tolerance){return value-rem}if(rem>values-tolerance){return value-rem+values}}return value};function createUUID(){var s=[],i=0;for(;i<32;i++){s[i]=(~~(math.random()*16))[toString](16);}s[12]=4;s[16]=(s[16]&3|8)[toString](16);return "r-"+s[join]("")}R.setWindow=function(newwin){win=newwin;doc=win.document;};var toHex=function(color){if(R.vml){var trim=/^\s+|\s+$/g;var bod;try{var docum=new ActiveXObject("htmlfile");docum.write("<body>");docum.close();bod=docum.body;}catch(e){bod=createPopup().document.body;}var range=bod.createTextRange();toHex=cacher(function(color){try{bod.style.color=Str(color)[rp](trim,E);var value=range.queryCommandValue("ForeColor");value=(value&255)<<16|value&65280|(value&0xff0000)>>>16;return "#"+("000000"+value[toString](16)).slice(-6)}catch(e){return "none"}});}else {var i=doc.createElement("i");i.title="Raphaël Colour Picker";i.style.display="none";doc.body[appendChild](i);toHex=cacher(function(color){i.style.color=color;return doc.defaultView.getComputedStyle(i,E).getPropertyValue("color")});}return toHex(color)},hsbtoString=function(){return "hsb("+[this.h,this.s,this.b]+")"},hsltoString=function(){return "hsl("+[this.h,this.s,this.l]+")"},rgbtoString=function(){return this.hex};R.hsb2rgb=function(h,s,b,o){if(R.is(h,"object")&&"h"in h&&"s"in h&&"b"in h){b=h.b;s=h.s;h=h.h;o=h.o;}return R.hsl2rgb(h,s,b/2,o)};R.hsl2rgb=function(h,s,l,o){if(R.is(h,"object")&&"h"in h&&"s"in h&&"l"in h){l=h.l;s=h.s;h=h.h;}if(h>1||s>1||l>1){h/=360;s/=100;l/=100;}var rgb={},channels=["r","g","b"],t2,t1,t3;if(!s){rgb={r:l,g:l,b:l};}else {if(l<.5){t2=l*(1+s);}else {t2=l+s-l*s;}t1=2*l-t2;for(var i=0;i<3;i++){t3=h+1/3*-(i-1);t3<0&&t3++;t3>1&&t3--;if(t3*6<1){rgb[channels[i]]=t1+(t2-t1)*6*t3;}else if(t3*2<1){rgb[channels[i]]=t2;}else if(t3*3<2){rgb[channels[i]]=t1+(t2-t1)*(2/3-t3)*6;}else {rgb[channels[i]]=t1;}}}rgb.r*=255;rgb.g*=255;rgb.b*=255;rgb.hex="#"+(0x1000000|rgb.b|rgb.g<<8|rgb.r<<16).toString(16).slice(1);R.is(o,"finite")&&(rgb.opacity=o);rgb.toString=rgbtoString;return rgb};R.rgb2hsb=function(red,green,blue){if(green==null&&R.is(red,"object")&&"r"in red&&"g"in red&&"b"in red){blue=red.b;green=red.g;red=red.r;}if(green==null&&R.is(red,string)){var clr=R.getRGB(red);red=clr.r;green=clr.g;blue=clr.b;}if(red>1||green>1||blue>1){red/=255;green/=255;blue/=255;}var max=mmax(red,green,blue),min=mmin(red,green,blue),hue,saturation,brightness=max;if(min==max){return {h:0,s:0,b:max,toString:hsbtoString}}else {var delta=max-min;saturation=delta/max;if(red==max){hue=(green-blue)/delta;}else if(green==max){hue=2+(blue-red)/delta;}else {hue=4+(red-green)/delta;}hue/=6;hue<0&&hue++;hue>1&&hue--;}return {h:hue,s:saturation,b:brightness,toString:hsbtoString}};R.rgb2hsl=function(red,green,blue){if(green==null&&R.is(red,"object")&&"r"in red&&"g"in red&&"b"in red){blue=red.b;green=red.g;red=red.r;}if(green==null&&R.is(red,string)){var clr=R.getRGB(red);red=clr.r;green=clr.g;blue=clr.b;}if(red>1||green>1||blue>1){red/=255;green/=255;blue/=255;}var max=mmax(red,green,blue),min=mmin(red,green,blue),h,s,l=(max+min)/2,hsl;if(min==max){hsl={h:0,s:0,l:l};}else {var delta=max-min;s=l<.5?delta/(max+min):delta/(2-max-min);if(red==max){h=(green-blue)/delta;}else if(green==max){h=2+(blue-red)/delta;}else {h=4+(red-green)/delta;}h/=6;h<0&&h++;h>1&&h--;hsl={h:h,s:s,l:l};}hsl.toString=hsltoString;return hsl};R._path2string=function(){return this.join(",")[rp](p2s,"$1")};function cacher(f,scope,postprocessor){function newf(){var arg=Array[proto].slice.call(arguments,0),args=arg[join]("►"),cache=newf.cache=newf.cache||{},count=newf.count=newf.count||[];if(cache[has](args)){return postprocessor?postprocessor(cache[args]):cache[args]}count[length]>=1e3&&delete cache[count.shift()];count[push](args);cache[args]=f[apply](scope,arg);return postprocessor?postprocessor(cache[args]):cache[args]}return newf}R.getRGB=cacher(function(colour){if(!colour||!!((colour=Str(colour)).indexOf("-")+1)){return {r:-1,g:-1,b:-1,hex:"none",error:1}}if(colour=="none"){return {r:-1,g:-1,b:-1,hex:"none"}}!(hsrg[has](colour.toLowerCase().substring(0,2))||colour.charAt()=="#")&&(colour=toHex(colour));var red,green,blue,opacity,t,values,rgb=colour.match(colourRegExp);if(rgb){if(rgb[2]){blue=toInt(rgb[2].substring(5),16);green=toInt(rgb[2].substring(3,5),16);red=toInt(rgb[2].substring(1,3),16);}if(rgb[3]){blue=toInt((t=rgb[3].charAt(3))+t,16);green=toInt((t=rgb[3].charAt(2))+t,16);red=toInt((t=rgb[3].charAt(1))+t,16);}if(rgb[4]){values=rgb[4][split](commaSpaces);red=toFloat(values[0]);values[0].slice(-1)=="%"&&(red*=2.55);green=toFloat(values[1]);values[1].slice(-1)=="%"&&(green*=2.55);blue=toFloat(values[2]);values[2].slice(-1)=="%"&&(blue*=2.55);rgb[1].toLowerCase().slice(0,4)=="rgba"&&(opacity=toFloat(values[3]));values[3]&&values[3].slice(-1)=="%"&&(opacity/=100);}if(rgb[5]){values=rgb[5][split](commaSpaces);red=toFloat(values[0]);values[0].slice(-1)=="%"&&(red*=2.55);green=toFloat(values[1]);values[1].slice(-1)=="%"&&(green*=2.55);blue=toFloat(values[2]);values[2].slice(-1)=="%"&&(blue*=2.55);(values[0].slice(-3)=="deg"||values[0].slice(-1)=="°")&&(red/=360);rgb[1].toLowerCase().slice(0,4)=="hsba"&&(opacity=toFloat(values[3]));values[3]&&values[3].slice(-1)=="%"&&(opacity/=100);return R.hsb2rgb(red,green,blue,opacity)}if(rgb[6]){values=rgb[6][split](commaSpaces);red=toFloat(values[0]);values[0].slice(-1)=="%"&&(red*=2.55);green=toFloat(values[1]);values[1].slice(-1)=="%"&&(green*=2.55);blue=toFloat(values[2]);values[2].slice(-1)=="%"&&(blue*=2.55);(values[0].slice(-3)=="deg"||values[0].slice(-1)=="°")&&(red/=360);rgb[1].toLowerCase().slice(0,4)=="hsla"&&(opacity=toFloat(values[3]));values[3]&&values[3].slice(-1)=="%"&&(opacity/=100);return R.hsl2rgb(red,green,blue,opacity)}rgb={r:red,g:green,b:blue};rgb.hex="#"+(0x1000000|blue|green<<8|red<<16).toString(16).slice(1);R.is(opacity,"finite")&&(rgb.opacity=opacity);return rgb}return {r:-1,g:-1,b:-1,hex:"none",error:1}},R);R.getColor=function(value){var start=this.getColor.start=this.getColor.start||{h:0,s:1,b:value||.75},rgb=this.hsb2rgb(start.h,start.s,start.b);start.h+=.075;if(start.h>1){start.h=0;start.s-=.2;start.s<=0&&(this.getColor.start={h:0,s:1,b:start.b});}return rgb.hex};R.getColor.reset=function(){delete this.start;};R.parsePathString=cacher(function(pathString){if(!pathString){return null}var paramCounts={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},data=[];if(R.is(pathString,array)&&R.is(pathString[0],array)){data=pathClone(pathString);}if(!data[length]){Str(pathString)[rp](pathCommand,function(a,b,c){var params=[],name=lowerCase.call(b);c[rp](pathValues,function(a,b){b&&params[push](+b);});if(name=="m"&&params[length]>2){data[push]([b][concat](params.splice(0,2)));name="l";b=b=="m"?"l":"L";}while(params[length]>=paramCounts[name]){data[push]([b][concat](params.splice(0,paramCounts[name])));if(!paramCounts[name]){break}}});}data[toString]=R._path2string;return data});R.findDotsAtSegment=function(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t){var t1=1-t,x=pow(t1,3)*p1x+pow(t1,2)*3*t*c1x+t1*3*t*t*c2x+pow(t,3)*p2x,y=pow(t1,3)*p1y+pow(t1,2)*3*t*c1y+t1*3*t*t*c2y+pow(t,3)*p2y,mx=p1x+2*t*(c1x-p1x)+t*t*(c2x-2*c1x+p1x),my=p1y+2*t*(c1y-p1y)+t*t*(c2y-2*c1y+p1y),nx=c1x+2*t*(c2x-c1x)+t*t*(p2x-2*c2x+c1x),ny=c1y+2*t*(c2y-c1y)+t*t*(p2y-2*c2y+c1y),ax=(1-t)*p1x+t*c1x,ay=(1-t)*p1y+t*c1y,cx=(1-t)*c2x+t*p2x,cy=(1-t)*c2y+t*p2y,alpha=90-math.atan((mx-nx)/(my-ny))*180/PI;(mx>nx||my<ny)&&(alpha+=180);return {x:x,y:y,m:{x:mx,y:my},n:{x:nx,y:ny},start:{x:ax,y:ay},end:{x:cx,y:cy},alpha:alpha}};var pathDimensions=cacher(function(path){if(!path){return {x:0,y:0,width:0,height:0}}path=path2curve(path);var x=0,y=0,X=[],Y=[],p;for(var i=0,ii1=path[length];i<ii1;i++){p=path[i];if(p[0]=="M"){x=p[1];y=p[2];X[push](x);Y[push](y);}else {var dim=curveDim(x,y,p[1],p[2],p[3],p[4],p[5],p[6]);X=X[concat](dim.min.x,dim.max.x);Y=Y[concat](dim.min.y,dim.max.y);x=p[5];y=p[6];}}var xmin=mmin[apply](0,X),ymin=mmin[apply](0,Y);return {x:xmin,y:ymin,width:mmax[apply](0,X)-xmin,height:mmax[apply](0,Y)-ymin}}),pathClone=function(pathArray){var res=[];if(!R.is(pathArray,array)||!R.is(pathArray&&pathArray[0],array)){pathArray=R.parsePathString(pathArray);}for(var i=0,ii1=pathArray[length];i<ii1;i++){res[i]=[];for(var j=0,jj=pathArray[i][length];j<jj;j++){res[i][j]=pathArray[i][j];}}res[toString]=R._path2string;return res},pathToRelative=cacher(function(pathArray){if(!R.is(pathArray,array)||!R.is(pathArray&&pathArray[0],array)){pathArray=R.parsePathString(pathArray);}var res=[],x=0,y=0,mx=0,my=0,start=0;if(pathArray[0][0]=="M"){x=pathArray[0][1];y=pathArray[0][2];mx=x;my=y;start++;res[push](["M",x,y]);}for(var i=start,ii1=pathArray[length];i<ii1;i++){var r=res[i]=[],pa=pathArray[i];if(pa[0]!=lowerCase.call(pa[0])){r[0]=lowerCase.call(pa[0]);switch(r[0]){case "a":r[1]=pa[1];r[2]=pa[2];r[3]=pa[3];r[4]=pa[4];r[5]=pa[5];r[6]=+(pa[6]-x).toFixed(3);r[7]=+(pa[7]-y).toFixed(3);break;case "v":r[1]=+(pa[1]-y).toFixed(3);break;case "m":mx=pa[1];my=pa[2];default:for(var j=1,jj=pa[length];j<jj;j++){r[j]=+(pa[j]-(j%2?x:y)).toFixed(3);}}}else {r=res[i]=[];if(pa[0]=="m"){mx=pa[1]+x;my=pa[2]+y;}for(var k=0,kk=pa[length];k<kk;k++){res[i][k]=pa[k];}}var len=res[i][length];switch(res[i][0]){case "z":x=mx;y=my;break;case "h":x+=+res[i][len-1];break;case "v":y+=+res[i][len-1];break;default:x+=+res[i][len-2];y+=+res[i][len-1];}}res[toString]=R._path2string;return res},0,pathClone),pathToAbsolute=cacher(function(pathArray){if(!R.is(pathArray,array)||!R.is(pathArray&&pathArray[0],array)){pathArray=R.parsePathString(pathArray);}var res=[],x=0,y=0,mx=0,my=0,start=0;if(pathArray[0][0]=="M"){x=+pathArray[0][1];y=+pathArray[0][2];mx=x;my=y;start++;res[0]=["M",x,y];}for(var i=start,ii1=pathArray[length];i<ii1;i++){var r=res[i]=[],pa=pathArray[i];if(pa[0]!=upperCase.call(pa[0])){r[0]=upperCase.call(pa[0]);switch(r[0]){case "A":r[1]=pa[1];r[2]=pa[2];r[3]=pa[3];r[4]=pa[4];r[5]=pa[5];r[6]=+(pa[6]+x);r[7]=+(pa[7]+y);break;case "V":r[1]=+pa[1]+y;break;case "H":r[1]=+pa[1]+x;break;case "M":mx=+pa[1]+x;my=+pa[2]+y;default:for(var j=1,jj=pa[length];j<jj;j++){r[j]=+pa[j]+(j%2?x:y);}}}else {for(var k=0,kk=pa[length];k<kk;k++){res[i][k]=pa[k];}}switch(r[0]){case "Z":x=mx;y=my;break;case "H":x=r[1];break;case "V":y=r[1];break;case "M":mx=res[i][res[i][length]-2];my=res[i][res[i][length]-1];default:x=res[i][res[i][length]-2];y=res[i][res[i][length]-1];}}res[toString]=R._path2string;return res},null,pathClone),l2c=function(x1,y1,x2,y2){return [x1,y1,x2,y2,x2,y2]},q2c=function(x1,y1,ax,ay,x2,y2){var _13=1/3,_23=2/3;return [_13*x1+_23*ax,_13*y1+_23*ay,_13*x2+_23*ax,_13*y2+_23*ay,x2,y2]},a2c=function(x1,y1,rx,ry,angle,large_arc_flag,sweep_flag,x2,y2,recursive){var _120=PI*120/180,rad=PI/180*(+angle||0),res=[],xy,rotate=cacher(function(x,y,rad){var X=x*math.cos(rad)-y*math.sin(rad),Y=x*math.sin(rad)+y*math.cos(rad);return {x:X,y:Y}});if(!recursive){xy=rotate(x1,y1,-rad);x1=xy.x;y1=xy.y;xy=rotate(x2,y2,-rad);x2=xy.x;y2=xy.y;var x=(x1-x2)/2,y=(y1-y2)/2;var h=x*x/(rx*rx)+y*y/(ry*ry);if(h>1){h=math.sqrt(h);rx=h*rx;ry=h*ry;}var rx2=rx*rx,ry2=ry*ry,k=(large_arc_flag==sweep_flag?-1:1)*math.sqrt(abs((rx2*ry2-rx2*y*y-ry2*x*x)/(rx2*y*y+ry2*x*x))),cx=k*rx*y/ry+(x1+x2)/2,cy=k*-ry*x/rx+(y1+y2)/2,f1=math.asin(((y1-cy)/ry).toFixed(9)),f2=math.asin(((y2-cy)/ry).toFixed(9));f1=x1<cx?PI-f1:f1;f2=x2<cx?PI-f2:f2;f1<0&&(f1=PI*2+f1);f2<0&&(f2=PI*2+f2);if(sweep_flag&&f1>f2){f1=f1-PI*2;}if(!sweep_flag&&f2>f1){f2=f2-PI*2;}}else {f1=recursive[0];f2=recursive[1];cx=recursive[2];cy=recursive[3];}var df=f2-f1;if(abs(df)>_120){var f2old=f2,x2old=x2,y2old=y2;f2=f1+_120*(sweep_flag&&f2>f1?1:-1);x2=cx+rx*math.cos(f2);y2=cy+ry*math.sin(f2);res=a2c(x2,y2,rx,ry,angle,0,sweep_flag,x2old,y2old,[f2,f2old,cx,cy]);}df=f2-f1;var c1=math.cos(f1),s1=math.sin(f1),c2=math.cos(f2),s2=math.sin(f2),t=math.tan(df/4),hx=4/3*rx*t,hy=4/3*ry*t,m1=[x1,y1],m2=[x1+hx*s1,y1-hy*c1],m3=[x2+hx*s2,y2-hy*c2],m4=[x2,y2];m2[0]=2*m1[0]-m2[0];m2[1]=2*m1[1]-m2[1];if(recursive){return [m2,m3,m4][concat](res)}else {res=[m2,m3,m4][concat](res)[join]()[split](",");var newres=[];for(var i=0,ii1=res[length];i<ii1;i++){newres[i]=i%2?rotate(res[i-1],res[i],rad).y:rotate(res[i],res[i+1],rad).x;}return newres}},findDotAtSegment=function(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t){var t1=1-t;return {x:pow(t1,3)*p1x+pow(t1,2)*3*t*c1x+t1*3*t*t*c2x+pow(t,3)*p2x,y:pow(t1,3)*p1y+pow(t1,2)*3*t*c1y+t1*3*t*t*c2y+pow(t,3)*p2y}},curveDim=cacher(function(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y){var a=c2x-2*c1x+p1x-(p2x-2*c2x+c1x),b=2*(c1x-p1x)-2*(c2x-c1x),c=p1x-c1x,t1=(-b+math.sqrt(b*b-4*a*c))/2/a,t2=(-b-math.sqrt(b*b-4*a*c))/2/a,y=[p1y,p2y],x=[p1x,p2x],dot;abs(t1)>"1e12"&&(t1=.5);abs(t2)>"1e12"&&(t2=.5);if(t1>0&&t1<1){dot=findDotAtSegment(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t1);x[push](dot.x);y[push](dot.y);}if(t2>0&&t2<1){dot=findDotAtSegment(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t2);x[push](dot.x);y[push](dot.y);}a=c2y-2*c1y+p1y-(p2y-2*c2y+c1y);b=2*(c1y-p1y)-2*(c2y-c1y);c=p1y-c1y;t1=(-b+math.sqrt(b*b-4*a*c))/2/a;t2=(-b-math.sqrt(b*b-4*a*c))/2/a;abs(t1)>"1e12"&&(t1=.5);abs(t2)>"1e12"&&(t2=.5);if(t1>0&&t1<1){dot=findDotAtSegment(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t1);x[push](dot.x);y[push](dot.y);}if(t2>0&&t2<1){dot=findDotAtSegment(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t2);x[push](dot.x);y[push](dot.y);}return {min:{x:mmin[apply](0,x),y:mmin[apply](0,y)},max:{x:mmax[apply](0,x),y:mmax[apply](0,y)}}}),path2curve=cacher(function(path,path2){var p=pathToAbsolute(path),p2=path2&&pathToAbsolute(path2),attrs={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},attrs2={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},processPath=function(path,d){var nx,ny;if(!path){return ["C",d.x,d.y,d.x,d.y,d.x,d.y]}!(path[0]in{T:1,Q:1})&&(d.qx=d.qy=null);switch(path[0]){case "M":d.X=path[1];d.Y=path[2];break;case "A":path=["C"][concat](a2c[apply](0,[d.x,d.y][concat](path.slice(1))));break;case "S":nx=d.x+(d.x-(d.bx||d.x));ny=d.y+(d.y-(d.by||d.y));path=["C",nx,ny][concat](path.slice(1));break;case "T":d.qx=d.x+(d.x-(d.qx||d.x));d.qy=d.y+(d.y-(d.qy||d.y));path=["C"][concat](q2c(d.x,d.y,d.qx,d.qy,path[1],path[2]));break;case "Q":d.qx=path[1];d.qy=path[2];path=["C"][concat](q2c(d.x,d.y,path[1],path[2],path[3],path[4]));break;case "L":path=["C"][concat](l2c(d.x,d.y,path[1],path[2]));break;case "H":path=["C"][concat](l2c(d.x,d.y,path[1],d.y));break;case "V":path=["C"][concat](l2c(d.x,d.y,d.x,path[1]));break;case "Z":path=["C"][concat](l2c(d.x,d.y,d.X,d.Y));break}return path},fixArc=function(pp,i){if(pp[i][length]>7){pp[i].shift();var pi=pp[i];while(pi[length]){pp.splice(i++,0,["C"][concat](pi.splice(0,6)));}pp.splice(i,1);ii1=mmax(p[length],p2&&p2[length]||0);}},fixM=function(path1,path2,a1,a2,i){if(path1&&path2&&path1[i][0]=="M"&&path2[i][0]!="M"){path2.splice(i,0,["M",a2.x,a2.y]);a1.bx=0;a1.by=0;a1.x=path1[i][1];a1.y=path1[i][2];ii1=mmax(p[length],p2&&p2[length]||0);}};for(var i=0,ii1=mmax(p[length],p2&&p2[length]||0);i<ii1;i++){p[i]=processPath(p[i],attrs);fixArc(p,i);p2&&(p2[i]=processPath(p2[i],attrs2));p2&&fixArc(p2,i);fixM(p,p2,attrs,attrs2,i);fixM(p2,p,attrs2,attrs,i);var seg=p[i],seg2=p2&&p2[i],seglen=seg[length],seg2len=p2&&seg2[length];attrs.x=seg[seglen-2];attrs.y=seg[seglen-1];attrs.bx=toFloat(seg[seglen-4])||attrs.x;attrs.by=toFloat(seg[seglen-3])||attrs.y;attrs2.bx=p2&&(toFloat(seg2[seg2len-4])||attrs2.x);attrs2.by=p2&&(toFloat(seg2[seg2len-3])||attrs2.y);attrs2.x=p2&&seg2[seg2len-2];attrs2.y=p2&&seg2[seg2len-1];}return p2?[p,p2]:p},null,pathClone),parseDots=cacher(function(gradient){var dots=[];for(var i=0,ii1=gradient[length];i<ii1;i++){var dot={},par=gradient[i].match(/^([^:]*):?([\d\.]*)/);dot.color=R.getRGB(par[1]);if(dot.color.error){return null}dot.color=dot.color.hex;par[2]&&(dot.offset=par[2]+"%");dots[push](dot);}for(i=1,ii1=dots[length]-1;i<ii1;i++){if(!dots[i].offset){var start=toFloat(dots[i-1].offset||0),end=0;for(var j=i+1;j<ii1;j++){if(dots[j].offset){end=dots[j].offset;break}}if(!end){end=100;j=ii1;}end=toFloat(end);var d=(end-start)/(j-i+1);for(;i<j;i++){start+=d;dots[i].offset=start+"%";}}}return dots}),getContainer=function(x,y,w,h){var container;if(R.is(x,string)||R.is(x,"object")){container=R.is(x,string)?doc.getElementById(x):x;if(container.tagName){if(y==null){return {container:container,width:container.style.pixelWidth||container.offsetWidth,height:container.style.pixelHeight||container.offsetHeight}}else {return {container:container,width:y,height:w}}}}else {return {container:1,x:x,y:y,width:w,height:h}}},plugins=function(con,add){var that=this;for(var prop in add){if(add[has](prop)&&!(prop in con)){switch(typeof add[prop]){case "function":(function(f){con[prop]=con===that?f:function(){return f[apply](that,arguments)};})(add[prop]);break;case "object":con[prop]=con[prop]||{};plugins.call(this,con[prop],add[prop]);break;default:con[prop]=add[prop];break}}}},tear=function(el,paper){el==paper.top&&(paper.top=el.prev);el==paper.bottom&&(paper.bottom=el.next);el.next&&(el.next.prev=el.prev);el.prev&&(el.prev.next=el.next);},tofront=function(el,paper){if(paper.top===el){return}tear(el,paper);el.next=null;el.prev=paper.top;paper.top.next=el;paper.top=el;},toback=function(el,paper){if(paper.bottom===el){return}tear(el,paper);el.next=paper.bottom;el.prev=null;paper.bottom.prev=el;paper.bottom=el;},insertafter=function(el,el2,paper){tear(el,paper);el2==paper.top&&(paper.top=el);el2.next&&(el2.next.prev=el);el.next=el2.next;el.prev=el2;el2.next=el;},insertbefore=function(el,el2,paper){tear(el,paper);el2==paper.bottom&&(paper.bottom=el);el2.prev&&(el2.prev.next=el);el.prev=el2.prev;el2.prev=el;el.next=el2;},removed=function(methodname){return function(){throw new Error("Raphaël: you are calling to method “"+methodname+"” of removed object")}};R.pathToRelative=pathToRelative;if(R.svg){paperproto.svgns="http://www.w3.org/2000/svg";paperproto.xlink="http://www.w3.org/1999/xlink";round=function(num){return +num+(~~num===num)*.5};var $=function(el,attr){if(attr){for(var key in attr){if(attr[has](key)){setAttr(el,key,Str(attr[key]));}}}else {el=doc.createElementNS(paperproto.svgns,el);el.style.webkitTapHighlightColor="rgba(0,0,0,0)";return el}};R[toString]=function(){return "Your browser supports SVG.\nYou are running Raphaël "+this.version};var thePath=function(pathString,SVG){var el=$("path");SVG.canvas&&SVG.canvas[appendChild](el);var p=new Element(el,SVG);p.type="path";setFillAndStroke(p,{fill:"none",stroke:"#000",path:pathString});return p};var addGradientFill=function(o,gradient,SVG){var type="linear",fx=.5,fy=.5,s=o.style;gradient=Str(gradient)[rp](radial_gradient,function(all,_fx,_fy){type="radial";if(_fx&&_fy){fx=toFloat(_fx);fy=toFloat(_fy);var dir=(fy>.5)*2-1;pow(fx-.5,2)+pow(fy-.5,2)>.25&&(fy=math.sqrt(.25-pow(fx-.5,2))*dir+.5)&&fy!=.5&&(fy=fy.toFixed(5)-1e-5*dir);}return E});gradient=gradient[split](/\s*\-\s*/);if(type=="linear"){var angle=gradient.shift();angle=-toFloat(angle);if(isNaN(angle)){return null}var vector=[0,0,math.cos(angle*PI/180),math.sin(angle*PI/180)],max=1/(mmax(abs(vector[2]),abs(vector[3]))||1);vector[2]*=max;vector[3]*=max;if(vector[2]<0){vector[0]=-vector[2];vector[2]=0;}if(vector[3]<0){vector[1]=-vector[3];vector[3]=0;}}var dots=parseDots(gradient);if(!dots){return null}var id=o.getAttribute(fillString);id=id.match(/^url\(#(.*)\)$/);id&&SVG.defs.removeChild(doc.getElementById(id[1]));var el=$(type+"Gradient");el.id=createUUID();$(el,type=="radial"?{fx:fx,fy:fy}:{x1:vector[0],y1:vector[1],x2:vector[2],y2:vector[3]});SVG.defs[appendChild](el);for(var i=0,ii1=dots[length];i<ii1;i++){var stop=$("stop");$(stop,{offset:dots[i].offset?dots[i].offset:!i?"0%":"100%","stop-color":dots[i].color||"#fff"});el[appendChild](stop);}$(o,{fill:"url(#"+el.id+")",opacity:1,"fill-opacity":1});s.fill=E;s.opacity=1;s.fillOpacity=1;return 1};var updatePosition=function(o){var bbox=o.getBBox();$(o.pattern,{patternTransform:R.format("translate({0},{1})",bbox.x,bbox.y)});};var setFillAndStroke=function(o,params){var dasharray={"":[0],"none":[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},node=o.node,attrs=o.attrs,rot=o.rotate(),addDashes=function(o,value){value=dasharray[lowerCase.call(value)];if(value){var width=o.attrs["stroke-width"]||"1",butt={round:width,square:width,butt:0}[o.attrs["stroke-linecap"]||params["stroke-linecap"]]||0,dashes=[];var i=value[length];while(i--){dashes[i]=value[i]*width+(i%2?1:-1)*butt;}$(node,{"stroke-dasharray":dashes[join](",")});}};params[has]("rotation")&&(rot=params.rotation);var rotxy=Str(rot)[split](separator);if(!(rotxy.length-1)){rotxy=null;}else {rotxy[1]=+rotxy[1];rotxy[2]=+rotxy[2];}toFloat(rot)&&o.rotate(0,true);for(var att in params){if(params[has](att)){if(!availableAttrs[has](att)){continue}var value=params[att];attrs[att]=value;switch(att){case "blur":o.blur(value);break;case "rotation":o.rotate(value,true);break;case "href":case "title":case "target":var pn=node.parentNode;if(lowerCase.call(pn.tagName)!="a"){var hl=$("a");pn.insertBefore(hl,node);hl[appendChild](node);pn=hl;}if(att=="target"&&value=="blank"){pn.setAttributeNS(o.paper.xlink,"show","new");}else {pn.setAttributeNS(o.paper.xlink,att,value);}break;case "cursor":node.style.cursor=value;break;case "clip-rect":var rect=Str(value)[split](separator);if(rect[length]==4){o.clip&&o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);var el=$("clipPath"),rc=$("rect");el.id=createUUID();$(rc,{x:rect[0],y:rect[1],width:rect[2],height:rect[3]});el[appendChild](rc);o.paper.defs[appendChild](el);$(node,{"clip-path":"url(#"+el.id+")"});o.clip=rc;}if(!value){var clip=doc.getElementById(node.getAttribute("clip-path")[rp](/(^url\(#|\)$)/g,E));clip&&clip.parentNode.removeChild(clip);$(node,{"clip-path":E});delete o.clip;}break;case "path":if(o.type=="path"){$(node,{d:value?attrs.path=pathToAbsolute(value):"M0,0"});}break;case "width":setAttr(node,att,value);if(attrs.fx){att="x";value=attrs.x;}else {break}case "x":if(attrs.fx){value=-attrs.x-(attrs.width||0);}case "rx":if(att=="rx"&&o.type=="rect"){break}case "cx":rotxy&&(att=="x"||att=="cx")&&(rotxy[1]+=value-attrs[att]);setAttr(node,att,value);o.pattern&&updatePosition(o);break;case "height":setAttr(node,att,value);if(attrs.fy){att="y";value=attrs.y;}else {break}case "y":if(attrs.fy){value=-attrs.y-(attrs.height||0);}case "ry":if(att=="ry"&&o.type=="rect"){break}case "cy":rotxy&&(att=="y"||att=="cy")&&(rotxy[2]+=value-attrs[att]);setAttr(node,att,value);o.pattern&&updatePosition(o);break;case "r":if(o.type=="rect"){$(node,{rx:value,ry:value});}else {setAttr(node,att,value);}break;case "src":if(o.type=="image"){node.setAttributeNS(o.paper.xlink,"href",value);}break;case "stroke-width":node.style.strokeWidth=value;setAttr(node,att,value);if(attrs["stroke-dasharray"]){addDashes(o,attrs["stroke-dasharray"]);}break;case "stroke-dasharray":addDashes(o,value);break;case "translation":var xy=Str(value)[split](separator);xy[0]=+xy[0]||0;xy[1]=+xy[1]||0;if(rotxy){rotxy[1]+=xy[0];rotxy[2]+=xy[1];}translate.call(o,xy[0],xy[1]);break;case "scale":xy=Str(value)[split](separator);o.scale(+xy[0]||1,+xy[1]||+xy[0]||1,isNaN(toFloat(xy[2]))?null:+xy[2],isNaN(toFloat(xy[3]))?null:+xy[3]);break;case fillString:var isURL=Str(value).match(ISURL);if(isURL){el=$("pattern");var ig=$("image");el.id=createUUID();$(el,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1});$(ig,{x:0,y:0});ig.setAttributeNS(o.paper.xlink,"href",isURL[1]);el[appendChild](ig);var img=doc.createElement("img");img.style.cssText="position:absolute;left:-9999em;top-9999em";img.onload=function(){$(el,{width:this.offsetWidth,height:this.offsetHeight});$(ig,{width:this.offsetWidth,height:this.offsetHeight});doc.body.removeChild(this);o.paper.safari();};doc.body[appendChild](img);img.src=isURL[1];o.paper.defs[appendChild](el);node.style.fill="url(#"+el.id+")";$(node,{fill:"url(#"+el.id+")"});o.pattern=el;o.pattern&&updatePosition(o);break}var clr=R.getRGB(value);if(!clr.error){delete params.gradient;delete attrs.gradient;!R.is(attrs.opacity,"undefined")&&R.is(params.opacity,"undefined")&&$(node,{opacity:attrs.opacity});!R.is(attrs["fill-opacity"],"undefined")&&R.is(params["fill-opacity"],"undefined")&&$(node,{"fill-opacity":attrs["fill-opacity"]});}else if((({circle:1,ellipse:1})[has](o.type)||Str(value).charAt()!="r")&&addGradientFill(node,value,o.paper)){attrs.gradient=value;attrs.fill="none";break}clr[has]("opacity")&&$(node,{"fill-opacity":clr.opacity>1?clr.opacity/100:clr.opacity});case "stroke":clr=R.getRGB(value);setAttr(node,att,clr.hex);att=="stroke"&&clr[has]("opacity")&&$(node,{"stroke-opacity":clr.opacity>1?clr.opacity/100:clr.opacity});break;case "gradient":(({circle:1,ellipse:1})[has](o.type)||Str(value).charAt()!="r")&&addGradientFill(node,value,o.paper);break;case "opacity":if(attrs.gradient&&!attrs[has]("stroke-opacity")){$(node,{"stroke-opacity":value>1?value/100:value});}case "fill-opacity":if(attrs.gradient){var gradient=doc.getElementById(node.getAttribute(fillString)[rp](/^url\(#|\)$/g,E));if(gradient){var stops=gradient.getElementsByTagName("stop");setAttr(stops[stops[length]-1],"stop-opacity",value);}break}default:att=="font-size"&&(value=toInt(value,10)+"px");var cssrule=att[rp](/(\-.)/g,function(w){return upperCase.call(w.substring(1))});node.style[cssrule]=value;setAttr(node,att,value);break}}}tuneText(o,params);if(rotxy){o.rotate(rotxy.join(S));}else {toFloat(rot)&&o.rotate(rot,true);}};var leading=1.2,tuneText=function(el,params){if(el.type!="text"||!(params[has]("text")||params[has]("font")||params[has]("font-size")||params[has]("x")||params[has]("y"))){return}var a=el.attrs,node=el.node,fontSize=node.firstChild?toInt(doc.defaultView.getComputedStyle(node.firstChild,E).getPropertyValue("font-size"),10):10;if(params[has]("text")){a.text=params.text;while(node.firstChild){node.removeChild(node.firstChild);}var texts=Str(params.text)[split]("\n");for(var i=0,ii1=texts[length];i<ii1;i++)if(texts[i]){var tspan=$("tspan");i&&$(tspan,{dy:fontSize*leading,x:a.x});tspan[appendChild](doc.createTextNode(texts[i]));node[appendChild](tspan);}}else {texts=node.getElementsByTagName("tspan");for(i=0,ii1=texts[length];i<ii1;i++){i&&$(texts[i],{dy:fontSize*leading,x:a.x});}}$(node,{y:a.y});var bb=el.getBBox(),dif=a.y-(bb.y+bb.height/2);dif&&R.is(dif,"finite")&&$(node,{y:a.y+dif});},Element=function(node,svg){this[0]=node;this.id=R._oid++;this.node=node;node.raphael=this;this.paper=svg;this.attrs=this.attrs||{};this.transformations=[];this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};!svg.bottom&&(svg.bottom=this);this.prev=svg.top;svg.top&&(svg.top.next=this);svg.top=this;this.next=null;};var elproto=Element[proto];Element[proto].rotate=function(deg,cx,cy){if(this.removed){return this}if(deg==null){if(this._.rt.cx){return [this._.rt.deg,this._.rt.cx,this._.rt.cy][join](S)}return this._.rt.deg}var bbox=this.getBBox();deg=Str(deg)[split](separator);if(deg[length]-1){cx=toFloat(deg[1]);cy=toFloat(deg[2]);}deg=toFloat(deg[0]);if(cx!=null&&cx!==false){this._.rt.deg=deg;}else {this._.rt.deg+=deg;}cy==null&&(cx=null);this._.rt.cx=cx;this._.rt.cy=cy;cx=cx==null?bbox.x+bbox.width/2:cx;cy=cy==null?bbox.y+bbox.height/2:cy;if(this._.rt.deg){this.transformations[0]=R.format("rotate({0} {1} {2})",this._.rt.deg,cx,cy);this.clip&&$(this.clip,{transform:R.format("rotate({0} {1} {2})",-this._.rt.deg,cx,cy)});}else {this.transformations[0]=E;this.clip&&$(this.clip,{transform:E});}$(this.node,{transform:this.transformations[join](S)});return this};Element[proto].hide=function(){!this.removed&&(this.node.style.display="none");return this};Element[proto].show=function(){!this.removed&&(this.node.style.display="");return this};Element[proto].remove=function(){if(this.removed){return}tear(this,this.paper);this.node.parentNode.removeChild(this.node);for(var i in this){delete this[i];}this.removed=true;};Element[proto].getBBox=function(){if(this.removed){return this}if(this.type=="path"){return pathDimensions(this.attrs.path)}if(this.node.style.display=="none"){this.show();var hide=true;}var bbox={};try{bbox=this.node.getBBox();}catch(e){}finally{bbox=bbox||{};}if(this.type=="text"){bbox={x:bbox.x,y:Infinity,width:0,height:0};for(var i=0,ii1=this.node.getNumberOfChars();i<ii1;i++){var bb=this.node.getExtentOfChar(i);bb.y<bbox.y&&(bbox.y=bb.y);bb.y+bb.height-bbox.y>bbox.height&&(bbox.height=bb.y+bb.height-bbox.y);bb.x+bb.width-bbox.x>bbox.width&&(bbox.width=bb.x+bb.width-bbox.x);}}hide&&this.hide();return bbox};Element[proto].attr=function(name,value){if(this.removed){return this}if(name==null){var res={};for(var i in this.attrs)if(this.attrs[has](i)){res[i]=this.attrs[i];}this._.rt.deg&&(res.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(res.scale=this.scale());res.gradient&&res.fill=="none"&&(res.fill=res.gradient)&&delete res.gradient;return res}if(value==null&&R.is(name,string)){if(name=="translation"){return translate.call(this)}if(name=="rotation"){return this.rotate()}if(name=="scale"){return this.scale()}if(name==fillString&&this.attrs.fill=="none"&&this.attrs.gradient){return this.attrs.gradient}return this.attrs[name]}if(value==null&&R.is(name,array)){var values={};for(var j=0,jj=name.length;j<jj;j++){values[name[j]]=this.attr(name[j]);}return values}if(value!=null){var params={};params[name]=value;}else if(name!=null&&R.is(name,"object")){params=name;}for(var key in this.paper.customAttributes)if(this.paper.customAttributes[has](key)&&params[has](key)&&R.is(this.paper.customAttributes[key],"function")){var par=this.paper.customAttributes[key].apply(this,[][concat](params[key]));this.attrs[key]=params[key];for(var subkey in par)if(par[has](subkey)){params[subkey]=par[subkey];}}setFillAndStroke(this,params);return this};Element[proto].toFront=function(){if(this.removed){return this}this.node.parentNode[appendChild](this.node);var svg=this.paper;svg.top!=this&&tofront(this,svg);return this};Element[proto].toBack=function(){if(this.removed){return this}if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);toback(this,this.paper);this.paper;}return this};Element[proto].insertAfter=function(element){if(this.removed){return this}var node=element.node||element[element.length-1].node;if(node.nextSibling){node.parentNode.insertBefore(this.node,node.nextSibling);}else {node.parentNode[appendChild](this.node);}insertafter(this,element,this.paper);return this};Element[proto].insertBefore=function(element){if(this.removed){return this}var node=element.node||element[0].node;node.parentNode.insertBefore(this.node,node);insertbefore(this,element,this.paper);return this};Element[proto].blur=function(size){var t=this;if(+size!==0){var fltr=$("filter"),blur=$("feGaussianBlur");t.attrs.blur=size;fltr.id=createUUID();$(blur,{stdDeviation:+size||1.5});fltr.appendChild(blur);t.paper.defs.appendChild(fltr);t._blur=fltr;$(t.node,{filter:"url(#"+fltr.id+")"});}else {if(t._blur){t._blur.parentNode.removeChild(t._blur);delete t._blur;delete t.attrs.blur;}t.node.removeAttribute("filter");}};var theCircle=function(svg,x,y,r){var el=$("circle");svg.canvas&&svg.canvas[appendChild](el);var res=new Element(el,svg);res.attrs={cx:x,cy:y,r:r,fill:"none",stroke:"#000"};res.type="circle";$(el,res.attrs);return res},theRect=function(svg,x,y,w,h,r){var el=$("rect");svg.canvas&&svg.canvas[appendChild](el);var res=new Element(el,svg);res.attrs={x:x,y:y,width:w,height:h,r:r||0,rx:r||0,ry:r||0,fill:"none",stroke:"#000"};res.type="rect";$(el,res.attrs);return res},theEllipse=function(svg,x,y,rx,ry){var el=$("ellipse");svg.canvas&&svg.canvas[appendChild](el);var res=new Element(el,svg);res.attrs={cx:x,cy:y,rx:rx,ry:ry,fill:"none",stroke:"#000"};res.type="ellipse";$(el,res.attrs);return res},theImage=function(svg,src,x,y,w,h){var el=$("image");$(el,{x:x,y:y,width:w,height:h,preserveAspectRatio:"none"});el.setAttributeNS(svg.xlink,"href",src);svg.canvas&&svg.canvas[appendChild](el);var res=new Element(el,svg);res.attrs={x:x,y:y,width:w,height:h,src:src};res.type="image";return res},theText=function(svg,x,y,text){var el=$("text");$(el,{x:x,y:y,"text-anchor":"middle"});svg.canvas&&svg.canvas[appendChild](el);var res=new Element(el,svg);res.attrs={x:x,y:y,"text-anchor":"middle",text:text,font:availableAttrs.font,stroke:"none",fill:"#000"};res.type="text";setFillAndStroke(res,res.attrs);return res},setSize=function(width,height){this.width=width||this.width;this.height=height||this.height;setAttr(this.canvas,"width",this.width);setAttr(this.canvas,"height",this.height);return this},create=function(){var con=getContainer[apply](0,arguments),container=con&&con.container,x=con.x,y=con.y,width=con.width,height=con.height;if(!container){throw new Error("SVG container not found.")}var cnvs=$("svg");x=x||0;y=y||0;width=width||512;height=height||342;$(cnvs,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:width,height:height});if(container==1){cnvs.style.cssText="position:absolute;left:"+x+"px;top:"+y+"px";doc.body[appendChild](cnvs);}else {if(container.firstChild){container.insertBefore(cnvs,container.firstChild);}else {container[appendChild](cnvs);}}container=new Paper;container.width=width;container.height=height;container.canvas=cnvs;plugins.call(container,container,R.fn);container.clear();return container};paperproto.clear=function(){var c=this.canvas;while(c.firstChild){c.removeChild(c.firstChild);}this.bottom=this.top=null;(this.desc=$("desc"))[appendChild](doc.createTextNode("Created with Raphaël"));c[appendChild](this.desc);c[appendChild](this.defs=$("defs"));};paperproto.remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var i in this){this[i]=removed(i);}};}if(R.vml){var map={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},bites=/([clmz]),?([^clmz]*)/gi,blurregexp=/ progid:\S+Blur\([^\)]+\)/g,val=/-?[^,\s-]+/g,coordsize=1e3+S+1e3,zoom=10,pathlike={path:1,rect:1},path2vml=function(path){var total=/[ahqstv]/ig,command=pathToAbsolute;Str(path).match(total)&&(command=path2curve);total=/[clmz]/g;if(command==pathToAbsolute&&!Str(path).match(total)){var res=Str(path)[rp](bites,function(all,command,args){var vals=[],isMove=lowerCase.call(command)=="m",res=map[command];args[rp](val,function(value){if(isMove&&vals[length]==2){res+=vals+map[command=="m"?"l":"L"];vals=[];}vals[push](round(value*zoom));});return res+vals});return res}var pa=command(path),p,r;res=[];for(var i=0,ii1=pa[length];i<ii1;i++){p=pa[i];r=lowerCase.call(pa[i][0]);r=="z"&&(r="x");for(var j=1,jj=p[length];j<jj;j++){r+=round(p[j]*zoom)+(j!=jj-1?",":E);}res[push](r);}return res[join](S)};R[toString]=function(){return "Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};thePath=function(pathString,vml){var g=createNode("group");g.style.cssText="position:absolute;left:0;top:0;width:"+vml.width+"px;height:"+vml.height+"px";g.coordsize=vml.coordsize;g.coordorigin=vml.coordorigin;var el=createNode("shape"),ol=el.style;ol.width=vml.width+"px";ol.height=vml.height+"px";el.coordsize=coordsize;el.coordorigin=vml.coordorigin;g[appendChild](el);var p=new Element(el,g,vml),attr={fill:"none",stroke:"#000"};pathString&&(attr.path=pathString);p.type="path";p.path=[];p.Path=E;setFillAndStroke(p,attr);vml.canvas[appendChild](g);return p};setFillAndStroke=function(o,params){o.attrs=o.attrs||{};var node=o.node,a=o.attrs,s=node.style,xy,newpath=(params.x!=a.x||params.y!=a.y||params.width!=a.width||params.height!=a.height||params.r!=a.r)&&o.type=="rect",res=o;for(var par in params)if(params[has](par)){a[par]=params[par];}if(newpath){a.path=rectPath(a.x,a.y,a.width,a.height,a.r);o.X=a.x;o.Y=a.y;o.W=a.width;o.H=a.height;}params.href&&(node.href=params.href);params.title&&(node.title=params.title);params.target&&(node.target=params.target);params.cursor&&(s.cursor=params.cursor);"blur"in params&&o.blur(params.blur);if(params.path&&o.type=="path"||newpath){node.path=path2vml(a.path);}if(params.rotation!=null){o.rotate(params.rotation,true);}if(params.translation){xy=Str(params.translation)[split](separator);translate.call(o,xy[0],xy[1]);if(o._.rt.cx!=null){o._.rt.cx+=+xy[0];o._.rt.cy+=+xy[1];o.setBox(o.attrs,xy[0],xy[1]);}}if(params.scale){xy=Str(params.scale)[split](separator);o.scale(+xy[0]||1,+xy[1]||+xy[0]||1,+xy[2]||null,+xy[3]||null);}if("clip-rect"in params){var rect=Str(params["clip-rect"])[split](separator);if(rect[length]==4){rect[2]=+rect[2]+ +rect[0];rect[3]=+rect[3]+ +rect[1];var div=node.clipRect||doc.createElement("div"),dstyle=div.style,group=node.parentNode;dstyle.clip=R.format("rect({1}px {2}px {3}px {0}px)",rect);if(!node.clipRect){dstyle.position="absolute";dstyle.top=0;dstyle.left=0;dstyle.width=o.paper.width+"px";dstyle.height=o.paper.height+"px";group.parentNode.insertBefore(div,group);div[appendChild](group);node.clipRect=div;}}if(!params["clip-rect"]){node.clipRect&&(node.clipRect.style.clip=E);}}if(o.type=="image"&&params.src){node.src=params.src;}if(o.type=="image"&&params.opacity){node.filterOpacity=ms+".Alpha(opacity="+params.opacity*100+")";s.filter=(node.filterMatrix||E)+(node.filterOpacity||E);}params.font&&(s.font=params.font);params["font-family"]&&(s.fontFamily='"'+params["font-family"][split](",")[0][rp](/^['"]+|['"]+$/g,E)+'"');params["font-size"]&&(s.fontSize=params["font-size"]);params["font-weight"]&&(s.fontWeight=params["font-weight"]);params["font-style"]&&(s.fontStyle=params["font-style"]);if(params.opacity!=null||params["stroke-width"]!=null||params.fill!=null||params.stroke!=null||params["stroke-width"]!=null||params["stroke-opacity"]!=null||params["fill-opacity"]!=null||params["stroke-dasharray"]!=null||params["stroke-miterlimit"]!=null||params["stroke-linejoin"]!=null||params["stroke-linecap"]!=null){node=o.shape||node;var fill=node.getElementsByTagName(fillString)&&node.getElementsByTagName(fillString)[0],newfill=false;!fill&&(newfill=fill=createNode(fillString));if("fill-opacity"in params||"opacity"in params){var opacity=((+a["fill-opacity"]+1||2)-1)*((+a.opacity+1||2)-1)*((+R.getRGB(params.fill).o+1||2)-1);opacity=mmin(mmax(opacity,0),1);fill.opacity=opacity;}params.fill&&(fill.on=true);if(fill.on==null||params.fill=="none"){fill.on=false;}if(fill.on&&params.fill){var isURL=params.fill.match(ISURL);if(isURL){fill.src=isURL[1];fill.type="tile";}else {fill.color=R.getRGB(params.fill).hex;fill.src=E;fill.type="solid";if(R.getRGB(params.fill).error&&(res.type in{circle:1,ellipse:1}||Str(params.fill).charAt()!="r")&&addGradientFill(res,params.fill)){a.fill="none";a.gradient=params.fill;}}}newfill&&node[appendChild](fill);var stroke=node.getElementsByTagName("stroke")&&node.getElementsByTagName("stroke")[0],newstroke=false;!stroke&&(newstroke=stroke=createNode("stroke"));if(params.stroke&&params.stroke!="none"||params["stroke-width"]||params["stroke-opacity"]!=null||params["stroke-dasharray"]||params["stroke-miterlimit"]||params["stroke-linejoin"]||params["stroke-linecap"]){stroke.on=true;}(params.stroke=="none"||stroke.on==null||params.stroke==0||params["stroke-width"]==0)&&(stroke.on=false);var strokeColor=R.getRGB(params.stroke);stroke.on&&params.stroke&&(stroke.color=strokeColor.hex);opacity=((+a["stroke-opacity"]+1||2)-1)*((+a.opacity+1||2)-1)*((+strokeColor.o+1||2)-1);var width=(toFloat(params["stroke-width"])||1)*.75;opacity=mmin(mmax(opacity,0),1);params["stroke-width"]==null&&(width=a["stroke-width"]);params["stroke-width"]&&(stroke.weight=width);width&&width<1&&(opacity*=width)&&(stroke.weight=1);stroke.opacity=opacity;params["stroke-linejoin"]&&(stroke.joinstyle=params["stroke-linejoin"]||"miter");stroke.miterlimit=params["stroke-miterlimit"]||8;params["stroke-linecap"]&&(stroke.endcap=params["stroke-linecap"]=="butt"?"flat":params["stroke-linecap"]=="square"?"square":"round");if(params["stroke-dasharray"]){var dasharray={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};stroke.dashstyle=dasharray[has](params["stroke-dasharray"])?dasharray[params["stroke-dasharray"]]:E;}newstroke&&node[appendChild](stroke);}if(res.type=="text"){s=res.paper.span.style;a.font&&(s.font=a.font);a["font-family"]&&(s.fontFamily=a["font-family"]);a["font-size"]&&(s.fontSize=a["font-size"]);a["font-weight"]&&(s.fontWeight=a["font-weight"]);a["font-style"]&&(s.fontStyle=a["font-style"]);res.node.string&&(res.paper.span.innerHTML=Str(res.node.string)[rp](/</g,"&#60;")[rp](/&/g,"&#38;")[rp](/\n/g,"<br>"));res.W=a.w=res.paper.span.offsetWidth;res.H=a.h=res.paper.span.offsetHeight;res.X=a.x;res.Y=a.y+round(res.H/2);switch(a["text-anchor"]){case "start":res.node.style["v-text-align"]="left";res.bbx=round(res.W/2);break;case "end":res.node.style["v-text-align"]="right";res.bbx=-round(res.W/2);break;default:res.node.style["v-text-align"]="center";break}}};addGradientFill=function(o,gradient){o.attrs=o.attrs||{};o.attrs;var fill,type="linear",fxfy=".5 .5";o.attrs.gradient=gradient;gradient=Str(gradient)[rp](radial_gradient,function(all,fx,fy){type="radial";if(fx&&fy){fx=toFloat(fx);fy=toFloat(fy);pow(fx-.5,2)+pow(fy-.5,2)>.25&&(fy=math.sqrt(.25-pow(fx-.5,2))*((fy>.5)*2-1)+.5);fxfy=fx+S+fy;}return E});gradient=gradient[split](/\s*\-\s*/);if(type=="linear"){var angle=gradient.shift();angle=-toFloat(angle);if(isNaN(angle)){return null}}var dots=parseDots(gradient);if(!dots){return null}o=o.shape||o.node;fill=o.getElementsByTagName(fillString)[0]||createNode(fillString);!fill.parentNode&&o.appendChild(fill);if(dots[length]){fill.on=true;fill.method="none";fill.color=dots[0].color;fill.color2=dots[dots[length]-1].color;var clrs=[];for(var i=0,ii1=dots[length];i<ii1;i++){dots[i].offset&&clrs[push](dots[i].offset+S+dots[i].color);}fill.colors&&(fill.colors.value=clrs[length]?clrs[join]():"0% "+fill.color);if(type=="radial"){fill.type="gradientradial";fill.focus="100%";fill.focussize=fxfy;fill.focusposition=fxfy;}else {fill.type="gradient";fill.angle=(270-angle)%360;}}return 1};Element=function(node,group,vml){this[0]=node;this.id=R._oid++;this.node=node;node.raphael=this;this.X=0;this.Y=0;this.attrs={};this.Group=group;this.paper=vml;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};!vml.bottom&&(vml.bottom=this);this.prev=vml.top;vml.top&&(vml.top.next=this);vml.top=this;this.next=null;};elproto=Element[proto];elproto.rotate=function(deg,cx,cy){if(this.removed){return this}if(deg==null){if(this._.rt.cx){return [this._.rt.deg,this._.rt.cx,this._.rt.cy][join](S)}return this._.rt.deg}deg=Str(deg)[split](separator);if(deg[length]-1){cx=toFloat(deg[1]);cy=toFloat(deg[2]);}deg=toFloat(deg[0]);if(cx!=null){this._.rt.deg=deg;}else {this._.rt.deg+=deg;}cy==null&&(cx=null);this._.rt.cx=cx;this._.rt.cy=cy;this.setBox(this.attrs,cx,cy);this.Group.style.rotation=this._.rt.deg;return this};elproto.setBox=function(params,cx,cy){if(this.removed){return this}var gs=this.Group.style,os=this.shape&&this.shape.style||this.node.style;params=params||{};for(var i in params)if(params[has](i)){this.attrs[i]=params[i];}cx=cx||this._.rt.cx;cy=cy||this._.rt.cy;var attr=this.attrs,x,y,w,h;switch(this.type){case "circle":x=attr.cx-attr.r;y=attr.cy-attr.r;w=h=attr.r*2;break;case "ellipse":x=attr.cx-attr.rx;y=attr.cy-attr.ry;w=attr.rx*2;h=attr.ry*2;break;case "image":x=+attr.x;y=+attr.y;w=attr.width||0;h=attr.height||0;break;case "text":this.textpath.v=["m",round(attr.x),", ",round(attr.y-2),"l",round(attr.x)+1,", ",round(attr.y-2)][join](E);x=attr.x-round(this.W/2);y=attr.y-this.H/2;w=this.W;h=this.H;break;case "rect":case "path":if(!this.attrs.path){x=0;y=0;w=this.paper.width;h=this.paper.height;}else {var dim=pathDimensions(this.attrs.path);x=dim.x;y=dim.y;w=dim.width;h=dim.height;}break;default:x=0;y=0;w=this.paper.width;h=this.paper.height;break}cx=cx==null?x+w/2:cx;cy=cy==null?y+h/2:cy;var left=cx-this.paper.width/2,top=cy-this.paper.height/2,t;gs.left!=(t=left+"px")&&(gs.left=t);gs.top!=(t=top+"px")&&(gs.top=t);this.X=pathlike[has](this.type)?-left:x;this.Y=pathlike[has](this.type)?-top:y;this.W=w;this.H=h;if(pathlike[has](this.type)){os.left!=(t=-left*zoom+"px")&&(os.left=t);os.top!=(t=-top*zoom+"px")&&(os.top=t);}else if(this.type=="text"){os.left!=(t=-left+"px")&&(os.left=t);os.top!=(t=-top+"px")&&(os.top=t);}else {gs.width!=(t=this.paper.width+"px")&&(gs.width=t);gs.height!=(t=this.paper.height+"px")&&(gs.height=t);os.left!=(t=x-left+"px")&&(os.left=t);os.top!=(t=y-top+"px")&&(os.top=t);os.width!=(t=w+"px")&&(os.width=t);os.height!=(t=h+"px")&&(os.height=t);}};elproto.hide=function(){!this.removed&&(this.Group.style.display="none");return this};elproto.show=function(){!this.removed&&(this.Group.style.display="block");return this};elproto.getBBox=function(){if(this.removed){return this}if(pathlike[has](this.type)){return pathDimensions(this.attrs.path)}return {x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H}};elproto.remove=function(){if(this.removed){return}tear(this,this.paper);this.node.parentNode.removeChild(this.node);this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);for(var i in this){delete this[i];}this.removed=true;};elproto.attr=function(name,value){if(this.removed){return this}if(name==null){var res={};for(var i in this.attrs)if(this.attrs[has](i)){res[i]=this.attrs[i];}this._.rt.deg&&(res.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(res.scale=this.scale());res.gradient&&res.fill=="none"&&(res.fill=res.gradient)&&delete res.gradient;return res}if(value==null&&R.is(name,"string")){if(name=="translation"){return translate.call(this)}if(name=="rotation"){return this.rotate()}if(name=="scale"){return this.scale()}if(name==fillString&&this.attrs.fill=="none"&&this.attrs.gradient){return this.attrs.gradient}return this.attrs[name]}if(this.attrs&&value==null&&R.is(name,array)){var ii1,values={};for(i=0,ii1=name[length];i<ii1;i++){values[name[i]]=this.attr(name[i]);}return values}var params;if(value!=null){params={};params[name]=value;}value==null&&R.is(name,"object")&&(params=name);if(params){for(var key in this.paper.customAttributes)if(this.paper.customAttributes[has](key)&&params[has](key)&&R.is(this.paper.customAttributes[key],"function")){var par=this.paper.customAttributes[key].apply(this,[][concat](params[key]));this.attrs[key]=params[key];for(var subkey in par)if(par[has](subkey)){params[subkey]=par[subkey];}}if(params.text&&this.type=="text"){this.node.string=params.text;}setFillAndStroke(this,params);if(params.gradient&&(({circle:1,ellipse:1})[has](this.type)||Str(params.gradient).charAt()!="r")){addGradientFill(this,params.gradient);}(!pathlike[has](this.type)||this._.rt.deg)&&this.setBox(this.attrs);}return this};elproto.toFront=function(){!this.removed&&this.Group.parentNode[appendChild](this.Group);this.paper.top!=this&&tofront(this,this.paper);return this};elproto.toBack=function(){if(this.removed){return this}if(this.Group.parentNode.firstChild!=this.Group){this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);toback(this,this.paper);}return this};elproto.insertAfter=function(element){if(this.removed){return this}if(element.constructor==Set){element=element[element.length-1];}if(element.Group.nextSibling){element.Group.parentNode.insertBefore(this.Group,element.Group.nextSibling);}else {element.Group.parentNode[appendChild](this.Group);}insertafter(this,element,this.paper);return this};elproto.insertBefore=function(element){if(this.removed){return this}if(element.constructor==Set){element=element[0];}element.Group.parentNode.insertBefore(this.Group,element.Group);insertbefore(this,element,this.paper);return this};elproto.blur=function(size){var s=this.node.runtimeStyle,f=s.filter;f=f.replace(blurregexp,E);if(+size!==0){this.attrs.blur=size;s.filter=f+S+ms+".Blur(pixelradius="+(+size||1.5)+")";s.margin=R.format("-{0}px 0 0 -{0}px",round(+size||1.5));}else {s.filter=f;s.margin=0;delete this.attrs.blur;}};theCircle=function(vml,x,y,r){var g=createNode("group"),o=createNode("oval");o.style;g.style.cssText="position:absolute;left:0;top:0;width:"+vml.width+"px;height:"+vml.height+"px";g.coordsize=coordsize;g.coordorigin=vml.coordorigin;g[appendChild](o);var res=new Element(o,g,vml);res.type="circle";setFillAndStroke(res,{stroke:"#000",fill:"none"});res.attrs.cx=x;res.attrs.cy=y;res.attrs.r=r;res.setBox({x:x-r,y:y-r,width:r*2,height:r*2});vml.canvas[appendChild](g);return res};function rectPath(x,y,w,h,r){if(r){return R.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z",x+r,y,w-r*2,r,-r,h-r*2,r*2-w,r*2-h)}else {return R.format("M{0},{1}l{2},0,0,{3},{4},0z",x,y,w,h,-w)}}theRect=function(vml,x,y,w,h,r){var path=rectPath(x,y,w,h,r),res=vml.path(path),a=res.attrs;res.X=a.x=x;res.Y=a.y=y;res.W=a.width=w;res.H=a.height=h;a.r=r;a.path=path;res.type="rect";return res};theEllipse=function(vml,x,y,rx,ry){var g=createNode("group"),o=createNode("oval");o.style;g.style.cssText="position:absolute;left:0;top:0;width:"+vml.width+"px;height:"+vml.height+"px";g.coordsize=coordsize;g.coordorigin=vml.coordorigin;g[appendChild](o);var res=new Element(o,g,vml);res.type="ellipse";setFillAndStroke(res,{stroke:"#000"});res.attrs.cx=x;res.attrs.cy=y;res.attrs.rx=rx;res.attrs.ry=ry;res.setBox({x:x-rx,y:y-ry,width:rx*2,height:ry*2});vml.canvas[appendChild](g);return res};theImage=function(vml,src,x,y,w,h){var g=createNode("group"),o=createNode("image");g.style.cssText="position:absolute;left:0;top:0;width:"+vml.width+"px;height:"+vml.height+"px";g.coordsize=coordsize;g.coordorigin=vml.coordorigin;o.src=src;g[appendChild](o);var res=new Element(o,g,vml);res.type="image";res.attrs.src=src;res.attrs.x=x;res.attrs.y=y;res.attrs.w=w;res.attrs.h=h;res.setBox({x:x,y:y,width:w,height:h});vml.canvas[appendChild](g);return res};theText=function(vml,x,y,text){var g=createNode("group"),el=createNode("shape"),ol=el.style,path=createNode("path");path.style;var o=createNode("textpath");g.style.cssText="position:absolute;left:0;top:0;width:"+vml.width+"px;height:"+vml.height+"px";g.coordsize=coordsize;g.coordorigin=vml.coordorigin;path.v=R.format("m{0},{1}l{2},{1}",round(x*10),round(y*10),round(x*10)+1);path.textpathok=true;ol.width=vml.width;ol.height=vml.height;o.string=Str(text);o.on=true;el[appendChild](o);el[appendChild](path);g[appendChild](el);var res=new Element(o,g,vml);res.shape=el;res.textpath=path;res.type="text";res.attrs.text=text;res.attrs.x=x;res.attrs.y=y;res.attrs.w=1;res.attrs.h=1;setFillAndStroke(res,{font:availableAttrs.font,stroke:"none",fill:"#000"});res.setBox();vml.canvas[appendChild](g);return res};setSize=function(width,height){var cs=this.canvas.style;width==+width&&(width+="px");height==+height&&(height+="px");cs.width=width;cs.height=height;cs.clip="rect(0 "+width+" "+height+" 0)";return this};var createNode;doc.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!doc.namespaces.rvml&&doc.namespaces.add("rvml","urn:schemas-microsoft-com:vml");createNode=function(tagName){return doc.createElement("<rvml:"+tagName+' class="rvml">')};}catch(e){createNode=function(tagName){return doc.createElement("<"+tagName+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')};}create=function(){var con=getContainer[apply](0,arguments),container=con.container,height=con.height,width=con.width,x=con.x,y=con.y;if(!container){throw new Error("VML container not found.")}var res=new Paper,c=res.canvas=doc.createElement("div"),cs=c.style;x=x||0;y=y||0;width=width||512;height=height||342;width==+width&&(width+="px");height==+height&&(height+="px");res.width=1e3;res.height=1e3;res.coordsize=zoom*1e3+S+zoom*1e3;res.coordorigin="0 0";res.span=doc.createElement("span");res.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";c[appendChild](res.span);cs.cssText=R.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",width,height);if(container==1){doc.body[appendChild](c);cs.left=x+"px";cs.top=y+"px";cs.position="absolute";}else {if(container.firstChild){container.insertBefore(c,container.firstChild);}else {container[appendChild](c);}}plugins.call(res,res,R.fn);return res};paperproto.clear=function(){this.canvas.innerHTML=E;this.span=doc.createElement("span");this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";this.canvas[appendChild](this.span);this.bottom=this.top=null;};paperproto.remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var i in this){this[i]=removed(i);}return true};}var version=navigator.userAgent.match(/Version\/(.*?)\s/);if(navigator.vendor=="Apple Computer, Inc."&&(version&&version[1]<4||navigator.platform.slice(0,2)=="iP")){paperproto.safari=function(){var rect=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});win.setTimeout(function(){rect.remove();});};}else {paperproto.safari=function(){};}var preventDefault=function(){this.returnValue=false;},preventTouch=function(){return this.originalEvent.preventDefault()},stopPropagation=function(){this.cancelBubble=true;},stopTouch=function(){return this.originalEvent.stopPropagation()},addEvent=function(){if(doc.addEventListener){return function(obj,type,fn,element){var realName=supportsTouch&&touchMap[type]?touchMap[type]:type;var f=function(e){if(supportsTouch&&touchMap[has](type)){for(var i=0,ii1=e.targetTouches&&e.targetTouches.length;i<ii1;i++){if(e.targetTouches[i].target==obj){var olde=e;e=e.targetTouches[i];e.originalEvent=olde;e.preventDefault=preventTouch;e.stopPropagation=stopTouch;break}}}return fn.call(element,e)};obj.addEventListener(realName,f,false);return function(){obj.removeEventListener(realName,f,false);return true}}}else if(doc.attachEvent){return function(obj,type,fn,element){var f=function(e){e=e||win.event;e.preventDefault=e.preventDefault||preventDefault;e.stopPropagation=e.stopPropagation||stopPropagation;return fn.call(element,e)};obj.attachEvent("on"+type,f);var detacher=function(){obj.detachEvent("on"+type,f);return true};return detacher}}}(),drag=[],dragMove=function(e){var x=e.clientX,y=e.clientY,scrollY=doc.documentElement.scrollTop||doc.body.scrollTop,scrollX=doc.documentElement.scrollLeft||doc.body.scrollLeft,dragi,j=drag.length;while(j--){dragi=drag[j];if(supportsTouch){var i=e.touches.length,touch;while(i--){touch=e.touches[i];if(touch.identifier==dragi.el._drag.id){x=touch.clientX;y=touch.clientY;(e.originalEvent?e.originalEvent:e).preventDefault();break}}}else {e.preventDefault();}x+=scrollX;y+=scrollY;dragi.move&&dragi.move.call(dragi.move_scope||dragi.el,x-dragi.el._drag.x,y-dragi.el._drag.y,x,y,e);}},dragUp=function(e){R.unmousemove(dragMove).unmouseup(dragUp);var i=drag.length,dragi;while(i--){dragi=drag[i];dragi.el._drag={};dragi.end&&dragi.end.call(dragi.end_scope||dragi.start_scope||dragi.move_scope||dragi.el,e);}drag=[];};for(var i=events[length];i--;){(function(eventName){R[eventName]=Element[proto][eventName]=function(fn,scope){if(R.is(fn,"function")){this.events=this.events||[];this.events.push({name:eventName,f:fn,unbind:addEvent(this.shape||this.node||doc,eventName,fn,scope||this)});}return this};R["un"+eventName]=Element[proto]["un"+eventName]=function(fn){var events=this.events,l=events[length];while(l--)if(events[l].name==eventName&&events[l].f==fn){events[l].unbind();events.splice(l,1);!events.length&&delete this.events;return this}return this};})(events[i]);}elproto.hover=function(f_in,f_out,scope_in,scope_out){return this.mouseover(f_in,scope_in).mouseout(f_out,scope_out||scope_in)};elproto.unhover=function(f_in,f_out){return this.unmouseover(f_in).unmouseout(f_out)};elproto.drag=function(onmove,onstart,onend,move_scope,start_scope,end_scope){this._drag={};this.mousedown(function(e){(e.originalEvent||e).preventDefault();var scrollY=doc.documentElement.scrollTop||doc.body.scrollTop,scrollX=doc.documentElement.scrollLeft||doc.body.scrollLeft;this._drag.x=e.clientX+scrollX;this._drag.y=e.clientY+scrollY;this._drag.id=e.identifier;onstart&&onstart.call(start_scope||move_scope||this,e.clientX+scrollX,e.clientY+scrollY,e);!drag.length&&R.mousemove(dragMove).mouseup(dragUp);drag.push({el:this,move:onmove,end:onend,move_scope:move_scope,start_scope:start_scope,end_scope:end_scope});});return this};elproto.undrag=function(onmove,onstart,onend){var i=drag.length;while(i--){drag[i].el==this&&drag[i].move==onmove&&drag[i].end==onend&&drag.splice(i++,1);}!drag.length&&R.unmousemove(dragMove).unmouseup(dragUp);};paperproto.circle=function(x,y,r){return theCircle(this,x||0,y||0,r||0)};paperproto.rect=function(x,y,w,h,r){return theRect(this,x||0,y||0,w||0,h||0,r||0)};paperproto.ellipse=function(x,y,rx,ry){return theEllipse(this,x||0,y||0,rx||0,ry||0)};paperproto.path=function(pathString){pathString&&!R.is(pathString,string)&&!R.is(pathString[0],array)&&(pathString+=E);return thePath(R.format[apply](R,arguments),this)};paperproto.image=function(src,x,y,w,h){return theImage(this,src||"about:blank",x||0,y||0,w||0,h||0)};paperproto.text=function(x,y,text){return theText(this,x||0,y||0,Str(text))};paperproto.set=function(itemsArray){arguments[length]>1&&(itemsArray=Array[proto].splice.call(arguments,0,arguments[length]));return new Set(itemsArray)};paperproto.setSize=setSize;paperproto.top=paperproto.bottom=null;paperproto.raphael=R;function x_y(){return this.x+S+this.y}elproto.resetScale=function(){if(this.removed){return this}this._.sx=1;this._.sy=1;this.attrs.scale="1 1";};elproto.scale=function(x,y,cx,cy){if(this.removed){return this}if(x==null&&y==null){return {x:this._.sx,y:this._.sy,toString:x_y}}y=y||x;!+y&&(y=x);var dx,dy,a=this.attrs;if(x!=0){var bb=this.getBBox(),rcx=bb.x+bb.width/2,rcy=bb.y+bb.height/2,kx=abs(x/this._.sx),ky=abs(y/this._.sy);cx=+cx||cx==0?cx:rcx;cy=+cy||cy==0?cy:rcy;var posx=this._.sx>0,posy=this._.sy>0,dirx=~~(x/abs(x)),diry=~~(y/abs(y)),dkx=kx*dirx,dky=ky*diry,s=this.node.style,ncx=cx+abs(rcx-cx)*dkx*(rcx>cx==posx?1:-1),ncy=cy+abs(rcy-cy)*dky*(rcy>cy==posy?1:-1),fr=x*dirx>y*diry?ky:kx;switch(this.type){case "rect":case "image":var neww=a.width*kx,newh=a.height*ky;this.attr({height:newh,r:a.r*fr,width:neww,x:ncx-neww/2,y:ncy-newh/2});break;case "circle":case "ellipse":this.attr({rx:a.rx*kx,ry:a.ry*ky,r:a.r*fr,cx:ncx,cy:ncy});break;case "text":this.attr({x:ncx,y:ncy});break;case "path":var path=pathToRelative(a.path),skip=true,fx=posx?dkx:kx,fy=posy?dky:ky;for(var i=0,ii1=path[length];i<ii1;i++){var p=path[i],P0=upperCase.call(p[0]);if(P0=="M"&&skip){continue}else {skip=false;}if(P0=="A"){p[path[i][length]-2]*=fx;p[path[i][length]-1]*=fy;p[1]*=kx;p[2]*=ky;p[5]=+(dirx+diry?!!+p[5]:!+p[5]);}else if(P0=="H"){for(var j=1,jj=p[length];j<jj;j++){p[j]*=fx;}}else if(P0=="V"){for(j=1,jj=p[length];j<jj;j++){p[j]*=fy;}}else {for(j=1,jj=p[length];j<jj;j++){p[j]*=j%2?fx:fy;}}}var dim2=pathDimensions(path);dx=ncx-dim2.x-dim2.width/2;dy=ncy-dim2.y-dim2.height/2;path[0][1]+=dx;path[0][2]+=dy;this.attr({path:path});break}if(this.type in{text:1,image:1}&&(dirx!=1||diry!=1)){if(this.transformations){this.transformations[2]="scale("[concat](dirx,",",diry,")");setAttr(this.node,"transform",this.transformations[join](S));dx=dirx==-1?-a.x-(neww||0):a.x;dy=diry==-1?-a.y-(newh||0):a.y;this.attr({x:dx,y:dy});a.fx=dirx-1;a.fy=diry-1;}else {this.node.filterMatrix=ms+".Matrix(M11="[concat](dirx,", M12=0, M21=0, M22=",diry,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");s.filter=(this.node.filterMatrix||E)+(this.node.filterOpacity||E);}}else {if(this.transformations){this.transformations[2]=E;setAttr(this.node,"transform",this.transformations[join](S));a.fx=0;a.fy=0;}else {this.node.filterMatrix=E;s.filter=(this.node.filterMatrix||E)+(this.node.filterOpacity||E);}}a.scale=[x,y,cx,cy][join](S);this._.sx=x;this._.sy=y;}return this};elproto.clone=function(){if(this.removed){return null}var attr=this.attr();delete attr.scale;delete attr.translation;return this.paper[this.type]().attr(attr)};var curveslengths={},getPointAtSegmentLength=function(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,length){if(p1x===c1x&&p1y===c1y&&c2x===p2x&&c2y==p2y){var dx=p2x-p1x,dy=p2y-p1y;var totalLength=Math.sqrt(dx*dx+dy*dy);if(length==null){return totalLength}else {var fract=length/totalLength;return {start:{x:p1x,y:p1y},m:{x:p1x,y:p1y},n:{x:p2x,y:p2y},end:{x:p2x,y:p2y},x:p1x+fract*dx,y:p1y+fract*dy,alpha:90-math.atan(dx/dy)*180/PI}}}var len=0,precision=100,name=[p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y].join(),cache=curveslengths[name],old,dot;!cache&&(curveslengths[name]=cache={data:[]});cache.timer&&clearTimeout(cache.timer);cache.timer=setTimeout(function(){delete curveslengths[name];},2e3);if(length!=null){var total=getPointAtSegmentLength(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y);precision=~~total*10;}for(var i=0;i<precision+1;i++){if(cache.data[length]>i){dot=cache.data[i*precision];}else {dot=R.findDotsAtSegment(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,i/precision);cache.data[i]=dot;}i&&(len+=pow(pow(old.x-dot.x,2)+pow(old.y-dot.y,2),.5));if(length!=null&&len>=length){return dot}old=dot;}if(length==null){return len}},getLengthFactory=function(istotal,subpath){return function(path,length,onlystart){path=path2curve(path);var x,y,p,l,sp="",subpaths={},point,len=0;for(var i=0,ii1=path.length;i<ii1;i++){p=path[i];if(p[0]=="M"){x=+p[1];y=+p[2];}else {l=getPointAtSegmentLength(x,y,p[1],p[2],p[3],p[4],p[5],p[6]);if(len+l>length){if(subpath&&!subpaths.start){point=getPointAtSegmentLength(x,y,p[1],p[2],p[3],p[4],p[5],p[6],length-len);sp+=["C",point.start.x,point.start.y,point.m.x,point.m.y,point.x,point.y];if(onlystart){return sp}subpaths.start=sp;sp=["M",point.x,point.y+"C",point.n.x,point.n.y,point.end.x,point.end.y,p[5],p[6]][join]();len+=l;x=+p[5];y=+p[6];continue}if(!istotal&&!subpath){point=getPointAtSegmentLength(x,y,p[1],p[2],p[3],p[4],p[5],p[6],length-len);return {x:point.x,y:point.y,alpha:point.alpha}}}len+=l;x=+p[5];y=+p[6];}sp+=p;}subpaths.end=sp;point=istotal?len:subpath?subpaths:R.findDotsAtSegment(x,y,p[1],p[2],p[3],p[4],p[5],p[6],1);point.alpha&&(point={x:point.x,y:point.y,alpha:point.alpha});return point}};var getTotalLength=getLengthFactory(1),getPointAtLength=getLengthFactory(),getSubpathsAtLength=getLengthFactory(0,1);elproto.getTotalLength=function(){if(this.type!="path"){return}if(this.node.getTotalLength){return this.node.getTotalLength()}return getTotalLength(this.attrs.path)};elproto.getPointAtLength=function(length){if(this.type!="path"){return}return getPointAtLength(this.attrs.path,length)};elproto.getSubpath=function(from,to){if(this.type!="path"){return}if(abs(this.getTotalLength()-to)<"1e-6"){return getSubpathsAtLength(this.attrs.path,from).end}var a=getSubpathsAtLength(this.attrs.path,to,1);return from?getSubpathsAtLength(a,from).end:a};R.easing_formulas={linear:function(n){return n},"<":function(n){return pow(n,3)},">":function(n){return pow(n-1,3)+1},"<>":function(n){n=n*2;if(n<1){return pow(n,3)/2}n-=2;return (pow(n,3)+2)/2},backIn:function(n){var s=1.70158;return n*n*((s+1)*n-s)},backOut:function(n){n=n-1;var s=1.70158;return n*n*((s+1)*n+s)+1},elastic:function(n){if(n==0||n==1){return n}var p=.3,s=p/4;return pow(2,-10*n)*math.sin((n-s)*(2*PI)/p)+1},bounce:function(n){var s=7.5625,p=2.75,l;if(n<1/p){l=s*n*n;}else {if(n<2/p){n-=1.5/p;l=s*n*n+.75;}else {if(n<2.5/p){n-=2.25/p;l=s*n*n+.9375;}else {n-=2.625/p;l=s*n*n+.984375;}}}return l}};var animationElements=[],animation=function(){var Now=+new Date;for(var l=0;l<animationElements[length];l++){var e=animationElements[l];if(e.stop||e.el.removed){continue}var time=Now-e.start,ms=e.ms,easing=e.easing,from=e.from,diff=e.diff,to=e.to,t=e.t,that=e.el,set={},now;if(time<ms){var pos=easing(time/ms);for(var attr in from)if(from[has](attr)){switch(availableAnimAttrs[attr]){case "along":now=pos*ms*diff[attr];to.back&&(now=to.len-now);var point=getPointAtLength(to[attr],now);that.translate(diff.sx-diff.x||0,diff.sy-diff.y||0);diff.x=point.x;diff.y=point.y;that.translate(point.x-diff.sx,point.y-diff.sy);to.rot&&that.rotate(diff.r+point.alpha,point.x,point.y);break;case nu:now=+from[attr]+pos*ms*diff[attr];break;case "colour":now="rgb("+[upto255(round(from[attr].r+pos*ms*diff[attr].r)),upto255(round(from[attr].g+pos*ms*diff[attr].g)),upto255(round(from[attr].b+pos*ms*diff[attr].b))][join](",")+")";break;case "path":now=[];for(var i=0,ii1=from[attr][length];i<ii1;i++){now[i]=[from[attr][i][0]];for(var j=1,jj=from[attr][i][length];j<jj;j++){now[i][j]=+from[attr][i][j]+pos*ms*diff[attr][i][j];}now[i]=now[i][join](S);}now=now[join](S);break;case "csv":switch(attr){case "translation":var x=pos*ms*diff[attr][0]-t.x,y=pos*ms*diff[attr][1]-t.y;t.x+=x;t.y+=y;now=x+S+y;break;case "rotation":now=+from[attr][0]+pos*ms*diff[attr][0];from[attr][1]&&(now+=","+from[attr][1]+","+from[attr][2]);break;case "scale":now=[+from[attr][0]+pos*ms*diff[attr][0],+from[attr][1]+pos*ms*diff[attr][1],2 in to[attr]?to[attr][2]:E,3 in to[attr]?to[attr][3]:E][join](S);break;case "clip-rect":now=[];i=4;while(i--){now[i]=+from[attr][i]+pos*ms*diff[attr][i];}break}break;default:var from2=[].concat(from[attr]);now=[];i=that.paper.customAttributes[attr].length;while(i--){now[i]=+from2[i]+pos*ms*diff[attr][i];}break}set[attr]=now;}that.attr(set);that._run&&that._run.call(that);}else {if(to.along){point=getPointAtLength(to.along,to.len*!to.back);that.translate(diff.sx-(diff.x||0)+point.x-diff.sx,diff.sy-(diff.y||0)+point.y-diff.sy);to.rot&&that.rotate(diff.r+point.alpha,point.x,point.y);}(t.x||t.y)&&that.translate(-t.x,-t.y);to.scale&&(to.scale+=E);that.attr(to);animationElements.splice(l--,1);}}R.svg&&that&&that.paper&&that.paper.safari();animationElements[length]&&setTimeout(animation);},keyframesRun=function(attr,element,time,prev,prevcallback){var dif=time-prev;element.timeouts.push(setTimeout(function(){R.is(prevcallback,"function")&&prevcallback.call(element);element.animate(attr,dif,attr.easing);},prev));},upto255=function(color){return mmax(mmin(color,255),0)},translate=function(x,y){if(x==null){return {x:this._.tx,y:this._.ty,toString:x_y}}this._.tx+=+x;this._.ty+=+y;switch(this.type){case "circle":case "ellipse":this.attr({cx:+x+this.attrs.cx,cy:+y+this.attrs.cy});break;case "rect":case "image":case "text":this.attr({x:+x+this.attrs.x,y:+y+this.attrs.y});break;case "path":var path=pathToRelative(this.attrs.path);path[0][1]+=+x;path[0][2]+=+y;this.attr({path:path});break}return this};elproto.animateWith=function(element,params,ms,easing,callback){for(var i=0,ii1=animationElements.length;i<ii1;i++){if(animationElements[i].el.id==element.id){params.start=animationElements[i].start;}}return this.animate(params,ms,easing,callback)};elproto.animateAlong=along();elproto.animateAlongBack=along(1);function along(isBack){return function(path,ms,rotate,callback){var params={back:isBack};R.is(rotate,"function")?callback=rotate:params.rot=rotate;path&&path.constructor==Element&&(path=path.attrs.path);path&&(params.along=path);return this.animate(params,ms,callback)}}function CubicBezierAtTime(t,p1x,p1y,p2x,p2y,duration){var cx=3*p1x,bx=3*(p2x-p1x)-cx,ax=1-cx-bx,cy=3*p1y,by=3*(p2y-p1y)-cy,ay=1-cy-by;function sampleCurveX(t){return ((ax*t+bx)*t+cx)*t}function solve(x,epsilon){var t=solveCurveX(x,epsilon);return ((ay*t+by)*t+cy)*t}function solveCurveX(x,epsilon){var t0,t1,t2,x2,d2,i;for(t2=x,i=0;i<8;i++){x2=sampleCurveX(t2)-x;if(abs(x2)<epsilon){return t2}d2=(3*ax*t2+2*bx)*t2+cx;if(abs(d2)<1e-6){break}t2=t2-x2/d2;}t0=0;t1=1;t2=x;if(t2<t0){return t0}if(t2>t1){return t1}while(t0<t1){x2=sampleCurveX(t2);if(abs(x2-x)<epsilon){return t2}if(x>x2){t0=t2;}else {t1=t2;}t2=(t1-t0)/2+t0;}return t2}return solve(t,1/(200*duration))}elproto.onAnimation=function(f){this._run=f||0;return this};elproto.animate=function(params,ms,easing,callback){var element=this;element.timeouts=element.timeouts||[];if(R.is(easing,"function")||!easing){callback=easing||null;}if(element.removed){callback&&callback.call(element);return element}var from={},to={},animateable=false,diff={};for(var attr in params)if(params[has](attr)){if(availableAnimAttrs[has](attr)||element.paper.customAttributes[has](attr)){animateable=true;from[attr]=element.attr(attr);from[attr]==null&&(from[attr]=availableAttrs[attr]);to[attr]=params[attr];switch(availableAnimAttrs[attr]){case "along":var len=getTotalLength(params[attr]);var point=getPointAtLength(params[attr],len*!!params.back);var bb=element.getBBox();diff[attr]=len/ms;diff.tx=bb.x;diff.ty=bb.y;diff.sx=point.x;diff.sy=point.y;to.rot=params.rot;to.back=params.back;to.len=len;params.rot&&(diff.r=toFloat(element.rotate())||0);break;case nu:diff[attr]=(to[attr]-from[attr])/ms;break;case "colour":from[attr]=R.getRGB(from[attr]);var toColour=R.getRGB(to[attr]);diff[attr]={r:(toColour.r-from[attr].r)/ms,g:(toColour.g-from[attr].g)/ms,b:(toColour.b-from[attr].b)/ms};break;case "path":var pathes=path2curve(from[attr],to[attr]);from[attr]=pathes[0];var toPath=pathes[1];diff[attr]=[];for(var i=0,ii1=from[attr][length];i<ii1;i++){diff[attr][i]=[0];for(var j=1,jj=from[attr][i][length];j<jj;j++){diff[attr][i][j]=(toPath[i][j]-from[attr][i][j])/ms;}}break;case "csv":var values=Str(params[attr])[split](separator),from2=Str(from[attr])[split](separator);switch(attr){case "translation":from[attr]=[0,0];diff[attr]=[values[0]/ms,values[1]/ms];break;case "rotation":from[attr]=from2[1]==values[1]&&from2[2]==values[2]?from2:[0,values[1],values[2]];diff[attr]=[(values[0]-from[attr][0])/ms,0,0];break;case "scale":params[attr]=values;from[attr]=Str(from[attr])[split](separator);diff[attr]=[(values[0]-from[attr][0])/ms,(values[1]-from[attr][1])/ms,0,0];break;case "clip-rect":from[attr]=Str(from[attr])[split](separator);diff[attr]=[];i=4;while(i--){diff[attr][i]=(values[i]-from[attr][i])/ms;}break}to[attr]=values;break;default:values=[].concat(params[attr]);from2=[].concat(from[attr]);diff[attr]=[];i=element.paper.customAttributes[attr][length];while(i--){diff[attr][i]=((values[i]||0)-(from2[i]||0))/ms;}break}}}if(!animateable){var attrs=[],lastcall;for(var key in params)if(params[has](key)&&animKeyFrames.test(key)){attr={value:params[key]};key=="from"&&(key=0);key=="to"&&(key=100);attr.key=toInt(key,10);attrs.push(attr);}attrs.sort(sortByKey);if(attrs[0].key){attrs.unshift({key:0,value:element.attrs});}for(i=0,ii1=attrs[length];i<ii1;i++){keyframesRun(attrs[i].value,element,ms/100*attrs[i].key,ms/100*(attrs[i-1]&&attrs[i-1].key||0),attrs[i-1]&&attrs[i-1].value.callback);}lastcall=attrs[attrs[length]-1].value.callback;if(lastcall){element.timeouts.push(setTimeout(function(){lastcall.call(element);},ms));}}else {var easyeasy=R.easing_formulas[easing];if(!easyeasy){easyeasy=Str(easing).match(bezierrg);if(easyeasy&&easyeasy[length]==5){var curve=easyeasy;easyeasy=function(t){return CubicBezierAtTime(t,+curve[1],+curve[2],+curve[3],+curve[4],ms)};}else {easyeasy=function(t){return t};}}animationElements.push({start:params.start||+new Date,ms:ms,easing:easyeasy,from:from,diff:diff,to:to,el:element,t:{x:0,y:0}});R.is(callback,"function")&&(element._ac=setTimeout(function(){callback.call(element);},ms));animationElements[length]==1&&setTimeout(animation);}return this};elproto.stop=function(){for(var i=0;i<animationElements.length;i++){animationElements[i].el.id==this.id&&animationElements.splice(i--,1);}for(i=0,ii=this.timeouts&&this.timeouts.length;i<ii;i++){clearTimeout(this.timeouts[i]);}this.timeouts=[];clearTimeout(this._ac);delete this._ac;return this};elproto.translate=function(x,y){return this.attr({translation:x+" "+y})};elproto[toString]=function(){return "Raphaël’s object"};R.ae=animationElements;var Set=function(items){this.items=[];this[length]=0;this.type="set";if(items){for(var i=0,ii1=items[length];i<ii1;i++){if(items[i]&&(items[i].constructor==Element||items[i].constructor==Set)){this[this.items[length]]=this.items[this.items[length]]=items[i];this[length]++;}}}};Set[proto][push]=function(){var item,len;for(var i=0,ii1=arguments[length];i<ii1;i++){item=arguments[i];if(item&&(item.constructor==Element||item.constructor==Set)){len=this.items[length];this[len]=this.items[len]=item;this[length]++;}}return this};Set[proto].pop=function(){delete this[this[length]--];return this.items.pop()};for(var method in elproto)if(elproto[has](method)){Set[proto][method]=function(methodname){return function(){for(var i=0,ii1=this.items[length];i<ii1;i++){this.items[i][methodname][apply](this.items[i],arguments);}return this}}(method);}Set[proto].attr=function(name,value){if(name&&R.is(name,array)&&R.is(name[0],"object")){for(var j=0,jj=name[length];j<jj;j++){this.items[j].attr(name[j]);}}else {for(var i=0,ii1=this.items[length];i<ii1;i++){this.items[i].attr(name,value);}}return this};Set[proto].animate=function(params,ms,easing,callback){(R.is(easing,"function")||!easing)&&(callback=easing||null);var len=this.items[length],i=len,item,set=this,collector;callback&&(collector=function(){!--len&&callback.call(set);});easing=R.is(easing,string)?easing:collector;item=this.items[--i].animate(params,ms,easing,collector);while(i--){this.items[i]&&!this.items[i].removed&&this.items[i].animateWith(item,params,ms,easing,collector);}return this};Set[proto].insertAfter=function(el){var i=this.items[length];while(i--){this.items[i].insertAfter(el);}return this};Set[proto].getBBox=function(){var x=[],y=[],w=[],h=[];for(var i=this.items[length];i--;){var box=this.items[i].getBBox();x[push](box.x);y[push](box.y);w[push](box.x+box.width);h[push](box.y+box.height);}x=mmin[apply](0,x);y=mmin[apply](0,y);return {x:x,y:y,width:mmax[apply](0,w)-x,height:mmax[apply](0,h)-y}};Set[proto].clone=function(s){s=new Set;for(var i=0,ii1=this.items[length];i<ii1;i++){s[push](this.items[i].clone());}return s};R.registerFont=function(font){if(!font.face){return font}this.fonts=this.fonts||{};var fontcopy={w:font.w,face:{},glyphs:{}},family=font.face["font-family"];for(var prop in font.face)if(font.face[has](prop)){fontcopy.face[prop]=font.face[prop];}if(this.fonts[family]){this.fonts[family][push](fontcopy);}else {this.fonts[family]=[fontcopy];}if(!font.svg){fontcopy.face["units-per-em"]=toInt(font.face["units-per-em"],10);for(var glyph in font.glyphs)if(font.glyphs[has](glyph)){var path=font.glyphs[glyph];fontcopy.glyphs[glyph]={w:path.w,k:{},d:path.d&&"M"+path.d[rp](/[mlcxtrv]/g,function(command){return ({l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"})[command]||"M"})+"z"};if(path.k){for(var k in path.k)if(path[has](k)){fontcopy.glyphs[glyph].k[k]=path.k[k];}}}}return font};paperproto.getFont=function(family,weight,style,stretch){stretch=stretch||"normal";style=style||"normal";weight=+weight||({normal:400,bold:700,lighter:300,bolder:800})[weight]||400;if(!R.fonts){return}var font=R.fonts[family];if(!font){var name=new RegExp("(^|\\s)"+family[rp](/[^\w\d\s+!~.:_-]/g,E)+"(\\s|$)","i");for(var fontName in R.fonts)if(R.fonts[has](fontName)){if(name.test(fontName)){font=R.fonts[fontName];break}}}var thefont;if(font){for(var i=0,ii1=font[length];i<ii1;i++){thefont=font[i];if(thefont.face["font-weight"]==weight&&(thefont.face["font-style"]==style||!thefont.face["font-style"])&&thefont.face["font-stretch"]==stretch){break}}}return thefont};paperproto.print=function(x,y,string,font,size,origin,letter_spacing){origin=origin||"middle";letter_spacing=mmax(mmin(letter_spacing||0,1),-1);var out=this.set(),letters=Str(string)[split](E),shift=0,scale;R.is(font,string)&&(font=this.getFont(font));if(font){scale=(size||16)/font.face["units-per-em"];var bb=font.face.bbox.split(separator),top=+bb[0],height=+bb[1]+(origin=="baseline"?bb[3]-bb[1]+ +font.face.descent:(bb[3]-bb[1])/2);for(var i=0,ii1=letters[length];i<ii1;i++){var prev=i&&font.glyphs[letters[i-1]]||{},curr=font.glyphs[letters[i]];shift+=i?(prev.w||font.w)+(prev.k&&prev.k[letters[i]]||0)+font.w*letter_spacing:0;curr&&curr.d&&out[push](this.path(curr.d).attr({fill:"#000",stroke:"none",translation:[shift,0]}));}out.scale(scale,scale,top,height).translate(x-top,y-height);}return out};R.format=function(token,params){var args=R.is(params,array)?[0][concat](params):arguments;token&&R.is(token,string)&&args[length]-1&&(token=token[rp](formatrg,function(str,i){return args[++i]==null?E:args[i]}));return token||E};R.ninja=function(){oldRaphael.was?win.Raphael=oldRaphael.is:Raphael=undefined;return R};R.el=elproto;R.st=Set[proto];return R})();
1514
-
1515
- class DrawingTransform{constructor(raphael,initialScale,bounds){this.scaleVector=point=>{if(typeof point==="number"){return this.scaleVector([point,point])}const x=point[0];const y=point[1];return [x*this.xScale,y*this.yScale]};this.scalePoint=point=>{if(typeof point==="number"){return this.scalePoint([point,point])}const x=point[0];const y=point[1];return [(x-this.bounds.xMin)*this.xScale,(this.bounds.yMax-y)*this.yScale]};this.unscalePoint=point=>{if(typeof point==="number"){return this.unscalePoint([point,point])}const x=point[0];const y=point[1];return [x/this.xScale+this.bounds.xMin,this.bounds.yMax-y/this.yScale]};this.unscaleVector=point=>{if(typeof point==="number"){return this.unscaleVector([point,point])}return [point[0]/this.xScale,point[1]/this.yScale]};this.setScale=scale=>{if(typeof scale==="number"){scale=[scale,scale];}this.xScale=scale[0];this.yScale=scale[1];this.raphael.setSize(...this.canvasDimensions());};this.canvasDimensions=()=>{return [this.bounds.width()*this.xScale,this.bounds.height()*this.yScale]};this.pixelsPerUnitX=()=>{return this.xScale};this.pixelsPerUnitY=()=>{return this.yScale};this.raphael=raphael;this.bounds=bounds;this.xScale=initialScale[0];this.yScale=initialScale[1];this.setScale(initialScale);}}
1516
-
1517
- class GraphBounds{width(){return this.xMax-this.xMin}height(){return this.yMax-this.yMin}constructor(xRange,yRange){this.xMin=xRange[0];this.xMax=xRange[1];this.yMin=yRange[0];this.yMax=yRange[1];}}
1518
-
1519
- var client = {};
1520
-
1521
- var hasRequiredClient;
1522
-
1523
- function requireClient () {
1524
- if (hasRequiredClient) return client;
1525
- hasRequiredClient = 1;
1526
-
1527
- var m = ReactDOM__default;
1528
- if (process.env.NODE_ENV === 'production') {
1529
- client.createRoot = m.createRoot;
1530
- client.hydrateRoot = m.hydrateRoot;
1531
- } else {
1532
- var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
1533
- client.createRoot = function(c, o) {
1534
- i.usingClientEntryPoint = true;
1535
- try {
1536
- return m.createRoot(c, o);
1537
- } finally {
1538
- i.usingClientEntryPoint = false;
1539
- }
1540
- };
1541
- client.hydrateRoot = function(c, h, o) {
1542
- i.usingClientEntryPoint = true;
1543
- try {
1544
- return m.hydrateRoot(c, h, o);
1545
- } finally {
1546
- i.usingClientEntryPoint = false;
1547
- }
1548
- };
1549
- }
1550
- return client;
1551
- }
1552
-
1553
- var clientExports = requireClient();
1554
-
1555
- const reactRootCache=new WeakMap;function render(element,container){const children=jsxRuntimeExports.jsx(RenderStateRoot,{throwIfNested:false,children:element});let root=reactRootCache.get(container);if(root==null){root=clientExports.createRoot(container);reactRootCache.set(container,root);}root.render(children);}
1556
-
1557
- function findChildOrAdd(elem,className){const child=elem.querySelector("."+className);if(child){return child}const newChild=document.createElement("span");newChild.classList.add(className);elem.appendChild(newChild);return newChild}var Tex$1 = {processMath:async function(elem,text,force,callback){const dataMathFormula=elem.getAttribute("data-math-formula");if(dataMathFormula==null||force){const texHolder=findChildOrAdd(elem,"tex-holder");if(text==null&&dataMathFormula){text=dataMathFormula;}text=text!=null?text+"":"";text=KhanMath.cleanMath(text);elem.setAttribute("data-math-formula",text);const{TeX}=getDependencies();render(React.createElement(TeX,{children:text,onRender:callback}),texHolder);}}};
1558
-
1559
- const{processMath: processMath$1}=Tex$1;function polar$2(r,th){if(typeof r==="number"){r=[r,r];}th=th*Math.PI/180;return [r[0]*Math.cos(th),r[1]*Math.sin(th)]}var _bounds=/*#__PURE__*/_class_private_field_loose_key("_bounds"),_drawingTransform=/*#__PURE__*/_class_private_field_loose_key("_drawingTransform"),_labelElements=/*#__PURE__*/_class_private_field_loose_key("_labelElements"),_resizeObserver=/*#__PURE__*/_class_private_field_loose_key("_resizeObserver");let Graphie$1 = class Graphie{init(options){let scale=options.scale||[40,40];scale=typeof scale==="number"?[scale,scale]:scale;if(options.range==null){throw new PerseusError("range should be specified in graph init",Errors.Internal)}_class_private_field_loose_base(this,_bounds)[_bounds]=new GraphBounds(...options.range);_class_private_field_loose_base(this,_drawingTransform)[_drawingTransform]=new DrawingTransform(this.raphael,scale,this.bounds());const[w,h]=this.drawingTransform().canvasDimensions();$(this.el).css({width:w,height:h});this.range=options.range;this.scale=scale;this.dimensions=[w,h];this.xpixels=w;this.ypixels=h;this.isMobile=options.isMobile??false;return this}graphInit(options){options=options||{};for(const[prop,val]of entries(options)){if(!prop.match(/.*Opacity$/)&&prop!=="range"&&typeof val==="number"){options[prop]=[val,val];}if(prop==="range"||prop==="gridRange"){options[prop]=normalizeRange(options[prop]);}}const range=normalizeRange(options.range||[[-10,10],[-10,10]]);const gridRange=normalizeRange(options.gridRange||range);const scale=options.scale||[20,20];const grid=options.grid!=null?options.grid:true;const gridOpacity=options.gridOpacity||.1;const gridStep=toPair(options.gridStep||[1,1]);const axes=options.axes!=null?options.axes:true;const axisArrows=options.axisArrows||"";const axisOpacity=options.axisOpacity||1;const axisCenter=options.axisCenter||[Math.min(Math.max(range[0][0],0),range[0][1]),Math.min(Math.max(range[1][0],0),range[1][1])];const axisLabels=options.axisLabels!=null?options.axisLabels:false;const ticks=options.ticks!=null?options.ticks:true;const tickStep=options.tickStep||[2,2];const tickLen=options.tickLen||[5,5];const tickOpacity=options.tickOpacity||1;const labels=options.labels||options.labelStep||false;const labelStep=options.labelStep||[1,1];const labelOpacity=options.labelOpacity||1;let unityLabels=options.unityLabels||false;const labelFormat=options.labelFormat||function(a){return a};let xLabelFormat=options.xLabelFormat||labelFormat;let yLabelFormat=options.yLabelFormat||labelFormat;const realRange=[[range[0][0]-(range[0][0]>0?1:0),range[0][1]+(range[0][1]<0?1:0)],[range[1][0]-(range[1][0]>0?1:0),range[1][1]+(range[1][1]<0?1:0)]];if(!Array.isArray(unityLabels)){unityLabels=[unityLabels,unityLabels];}const minusIgnorer=function(lf){return function(a){return (lf(a)+"").replace(/-(\d)/g,"\\llap{-}$1")}};xLabelFormat=minusIgnorer(xLabelFormat);yLabelFormat=minusIgnorer(yLabelFormat);this.init({range:realRange,scale:scale,isMobile:options.isMobile});if(grid){this.grid(gridRange[0],gridRange[1],{stroke:options.isMobile?KhanColors.GRAY_C:"#000000",opacity:options.isMobile?1:gridOpacity,step:gridStep,strokeWidth:options.isMobile?1:2});}if(axes){if(axisArrows==="<->"||axisArrows===true){const thisGraphie=this;this.style({stroke:options.isMobile?KhanColors.GRAY_G:"#000000",opacity:options.isMobile?1:axisOpacity,strokeWidth:options.isMobile?1:2,arrows:"->"},function(){if(range[1][0]<0&&range[1][1]>0){thisGraphie.path([axisCenter,[gridRange[0][0],axisCenter[1]]]);thisGraphie.path([axisCenter,[gridRange[0][1],axisCenter[1]]]);}if(range[0][0]<0&&range[0][1]>0){thisGraphie.path([axisCenter,[axisCenter[0],gridRange[1][0]]]);thisGraphie.path([axisCenter,[axisCenter[0],gridRange[1][1]]]);}});}else if(axisArrows==="->"||axisArrows===""){const thisGraphie=this;this.style({stroke:"#000000",opacity:axisOpacity,strokeWidth:2,arrows:axisArrows},function(){thisGraphie.path([[gridRange[0][0],axisCenter[1]],[gridRange[0][1],axisCenter[1]]]);thisGraphie.path([[axisCenter[0],gridRange[1][0]],[axisCenter[0],gridRange[1][1]]]);});}if(axisLabels&&axisLabels.length===2){this.label([gridRange[0][1],axisCenter[1]],axisLabels[0],"right");this.label([axisCenter[0],gridRange[1][1]],axisLabels[1],"above");}}if(ticks){const halfWidthTicks=options.isMobile;const thisGraphie=this;this.style({stroke:options.isMobile?KhanColors.GRAY_G:"#000000",opacity:options.isMobile?1:tickOpacity,strokeWidth:1},()=>{let step=gridStep[0]*tickStep[0];let len=tickLen[0]/scale[1];let start=gridRange[0][0];let stop=gridRange[0][1];if(range[1][0]<0&&range[1][1]>0){for(let x=step+axisCenter[0];x<=stop;x+=step){if(x<stop||!axisArrows){thisGraphie.line([x,-len+axisCenter[1]],[x,halfWidthTicks?0:len+axisCenter[1]]);}}for(let x=-step+axisCenter[0];x>=start;x-=step){if(x>start||!axisArrows){thisGraphie.line([x,-len+axisCenter[1]],[x,halfWidthTicks?0:len+axisCenter[1]]);}}}step=gridStep[1]*tickStep[1];len=tickLen[1]/scale[0];start=gridRange[1][0];stop=gridRange[1][1];if(range[0][0]<0&&range[0][1]>0){for(let y=step+axisCenter[1];y<=stop;y+=step){if(y<stop||!axisArrows){this.line([-len+axisCenter[0],y],[halfWidthTicks?0:len+axisCenter[0],y]);}}for(let y=-step+axisCenter[1];y>=start;y-=step){if(y>start||!axisArrows){this.line([-len+axisCenter[0],y],[halfWidthTicks?0:len+axisCenter[0],y]);}}}});}if(labels){const thisGraphie=this;this.style({stroke:options.isMobile?KhanColors.GRAY_G:"#000000",opacity:options.isMobile?1:labelOpacity},function(){let step=gridStep[0]*tickStep[0]*labelStep[0];let start=gridRange[0][0];let stop=gridRange[0][1];const xAxisPosition=axisCenter[0]<0?"above":"below";const yAxisPosition=axisCenter[0]<0?"right":"left";const xShowZero=axisCenter[0]===0&&axisCenter[1]!==0;const yShowZero=axisCenter[0]!==0&&axisCenter[1]===0;const axisOffCenter=axisCenter[0]!==0||axisCenter[1]!==0;const showUnityX=unityLabels[0]||axisOffCenter;const showUnityY=unityLabels[1]||axisOffCenter;for(let x=(xShowZero?0:step)+axisCenter[0];x<=stop;x+=step){if(x<stop||!axisArrows){thisGraphie.label([x,axisCenter[1]],xLabelFormat(x),xAxisPosition);}}for(let x=-step*(showUnityX?1:2)+axisCenter[0];x>=start;x-=step){if(x>start||!axisArrows){thisGraphie.label([x,axisCenter[1]],xLabelFormat(x),xAxisPosition);}}step=gridStep[1]*tickStep[1]*labelStep[1];start=gridRange[1][0];stop=gridRange[1][1];for(let y=(yShowZero?0:step)+axisCenter[1];y<=stop;y+=step){if(y<stop||!axisArrows){thisGraphie.label([axisCenter[0],y],yLabelFormat(y),yAxisPosition);}}for(let y=-step*(showUnityY?1:2)+axisCenter[1];y>=start;y-=step){if(y>start||!axisArrows){thisGraphie.label([axisCenter[0],y],yLabelFormat(y),yAxisPosition);}}});}}drawingTransform(){if(_class_private_field_loose_base(this,_drawingTransform)[_drawingTransform]==null){throw new Error("Can't get drawingTransform of an uninitialized Graphie")}return _class_private_field_loose_base(this,_drawingTransform)[_drawingTransform]}bounds(){if(_class_private_field_loose_base(this,_bounds)[_bounds]==null){throw new Error("Can't get bounds of an uninitialized Graphie")}return _class_private_field_loose_base(this,_bounds)[_bounds]}style(attrs,fn){const processed=this.processAttributes(attrs);if(typeof fn==="function"){const oldStyle=this.currentStyle;this.currentStyle={...this.currentStyle,...processed};const result=fn.call(this);this.currentStyle=oldStyle;return result}Object.assign(this.currentStyle,processed);}grid(xr,yr,style){return this.withStyle(style,()=>{const step=this.currentStyle.step||[1,1];const set=this.raphael.set();let x=step[0]*Math.ceil(xr[0]/step[0]);for(;x<=xr[1];x+=step[0]){set.push(this.line([x,yr[0]],[x,yr[1]]));}let y=step[1]*Math.ceil(yr[0]/step[1]);for(;y<=yr[1];y+=step[1]){set.push(this.line([xr[0],y],[xr[1],y]));}return set})}arc(center,radius,startAngle,endAngle,sector,style){return this.withStyle(style,()=>{startAngle=(startAngle%360+360)%360;endAngle=(endAngle%360+360)%360;const cent=this.scalePoint(center);const radii=this.scaleVector(radius);const startVector=polar$2(radius,startAngle);const endVector=polar$2(radius,endAngle);const round=x=>number.round(x,6);const startPoint=this.scalePoint([round(center[0]+startVector[0]),round(center[1]+startVector[1])]);const endPoint=this.scalePoint([round(center[0]+endVector[0]),round(center[1]+endVector[1])]);const largeAngle=((endAngle-startAngle)%360+360)%360>180;return this.raphael.path("M"+startPoint.join(" ")+"A"+radii.join(" ")+" 0 "+(largeAngle?1:0)+" 0 "+endPoint.join(" ")+(sector?"L"+cent.join(" ")+"z":""))})}circle(center,radius,style){return this.withStyle(style,()=>this.raphael.ellipse(...this.scalePoint(center),...this.scaleVector([radius,radius])))}rect(x,y,width,height,style){return this.withStyle(style,()=>{const corner=this.scalePoint([x,y+height]);const dims=this.scaleVector([width,height]);const elem=this.raphael.rect(...corner.concat(dims));if(this.isMobile){elem.node.style.shapeRendering="crispEdges";}return elem})}ellipse(center,radii,style){return this.withStyle(style,()=>this.raphael.ellipse(...this.scalePoint(center).concat(this.scaleVector(radii))))}fixedEllipse(center,radii,maxScale,padding,style){return this.withStyle(style,()=>{const scaledPoint=this.scalePoint(center);const scaledRadii=this.scaleVector(radii);const width=2*scaledRadii[0]*maxScale+padding;const height=2*scaledRadii[1]*maxScale+padding;const left=scaledPoint[0]-width/2;const top=scaledPoint[1]-height/2;const wrapper=document.createElement("div");$(wrapper).css({position:"absolute",width:width+"px",height:height+"px",left:left+"px",top:top+"px"});const localRaphael=Raphael$1(wrapper,width,height);const visibleShape=localRaphael.ellipse(width/2,height/2,scaledRadii[0],scaledRadii[1]);return {wrapper:wrapper,visibleShape:visibleShape}})}unstyledPath(points){const p=this.raphael.path(this.svgPath(points));p.graphiePath=points;return p}path(points,style){return this.withStyle(style,()=>{return this.unstyledPath(points)})}fixedPath(points,center,createPath){points=points.map(this.scalePoint);center=center?this.scalePoint(center):null;createPath=createPath||this.svgPath;const xs=points.map(p=>p[0]);const ys=points.map(p=>p[1]);const pathLeft=Math.min(...xs);const pathRight=Math.max(...xs);const pathTop=Math.min(...ys);const pathBottom=Math.max(...ys);const padding=[4,4];const topLeftOfBoundingBox=[pathLeft,pathTop];points=points.map(function(point){return vector$3.add(vector$3.subtract(point,topLeftOfBoundingBox),vector$3.scale(padding,.5))});const width=pathRight-pathLeft+padding[0];const height=pathBottom-pathTop+padding[1];const left=topLeftOfBoundingBox[0]-padding[0]/2;const top=topLeftOfBoundingBox[1]-padding[1]/2;const wrapper=document.createElement("div");$(wrapper).css({position:"absolute",width:width+"px",height:height+"px",left:left+"px",top:top+"px",transformOrigin:center?width/2+center[0]+"px "+(height/2+center[1])+"px":null});const localRaphael=Raphael$1(wrapper,width,height);const visibleShape=localRaphael.path(createPath(points));return {wrapper:wrapper,visibleShape:visibleShape}}scaledPath(points,style){return this.withStyle(style,()=>{const p=this.raphael.path(this.svgPath(points,true));p.graphiePath=points;return p})}line(start,end,style){return this.withStyle(style,()=>{const l=this.unstyledPath([start,end]);if(this.isMobile){l.node.style.shapeRendering="crispEdges";}return l})}parabola(a,b,c,style){return this.withStyle(style,()=>this.raphael.path(this.svgParabolaPath(a,b,c)))}fixedLine(start,end,thickness){const padding=[thickness,thickness];start=this.scalePoint(start);end=this.scalePoint(end);const extraOffset=[Math.min(start[0],end[0]),Math.min(start[1],end[1])];start=vector$3.add(vector$3.subtract(start,extraOffset),vector$3.scale(padding,.5));end=vector$3.add(vector$3.subtract(end,extraOffset),vector$3.scale(padding,.5));const left=extraOffset[0]-padding[0]/2;const top=extraOffset[1]-padding[1]/2;const width=Math.abs(start[0]-end[0])+padding[0];const height=Math.abs(start[1]-end[1])+padding[1];const wrapper=document.createElement("div");$(wrapper).css({position:"absolute",width:width+"px",height:height+"px",left:left+"px",top:top+"px",transformOrigin:start[0]+"px "+start[1]+"px"});const localRaphael=Raphael$1(wrapper,width,height);const path="M"+start[0]+" "+start[1]+" "+"L"+end[0]+" "+end[1];const visibleShape=localRaphael.path(path);visibleShape.graphiePath=[start,end];return {wrapper:wrapper,visibleShape:visibleShape}}sinusoid(a,b,c,d,style){return this.withStyle(style,()=>this.raphael.path(this.svgSinusoidPath(a,b,c,d)))}plotParametric(fn,range,style){return this.withStyle(style,()=>{const clip=xy=>{if(Math.abs(xy[1])>5e5){return [xy[0],Math.min(Math.max(xy[1],-5e5),5e5)]}return xy};const clippedFn=x=>clip(fn(x));const min=range[0];const max=range[1];let step=(max-min)/(this.currentStyle["plot-points"]||800);if(step===0){step=1;}const paths=this.raphael.set();let points=[];let lastY=clippedFn(min)[1];for(let t=min;t<=max;t+=step){const point=clippedFn(t);const y=point[1];if(y>0!==lastY>0&&Math.abs(y-lastY)>2*this.drawingTransform().pixelsPerUnitY()||isNaN(y)){paths.push(this.unstyledPath(points));points=[];}else {points.push(point);}lastY=y;}paths.push(this.unstyledPath(points));return paths})}plot(fn,range,style){return this.withStyle(style,()=>{const min=range[0];const max=range[1];if(!this.currentStyle["plot-points"]){this.currentStyle["plot-points"]=2*(max-min)*this.drawingTransform().pixelsPerUnitX();}const parametricFn=x=>[x,fn(x)];return this.plotParametric(parametricFn,range)})}withStyle(style,fn){const oldStyle=this.currentStyle;this.currentStyle={...this.currentStyle,...this.processAttributes(style)};const result=this.postprocessDrawingResult(fn());this.currentStyle=oldStyle;return result}postprocessDrawingResult(result){const type=result.constructor.prototype;if(type===Raphael$1.el||type===Raphael$1.st){result.attr(this.currentStyle);if(this.currentStyle.arrows){result=this.addArrowheads(result);}}else if(result instanceof $){result.css({...this.currentStyle,...SVG_SPECIFIC_STYLE_MASK});}return result}addArrowheads(path){const type=path.constructor.prototype;if(type===Raphael$1.el){if(path.type==="path"&&typeof path.arrowheadsDrawn==="undefined"){const w=path.attr("stroke-width");const s=.6+.4*w;const l=path.getTotalLength();const set=this.raphael.set();const head=this.raphael.path(this.isMobile?"M-4,4 C-4,4 -0.25,0 -0.25,0 C-0.25,0 -4,-4 -4,-4":"M-3 4 C-2.75 2.5 0 0.25 0.75 0C0 -0.25 -2.75 -2.5 -3 -4");const end=path.getPointAtLength(l-.4);const almostTheEnd=path.getPointAtLength(l-.75*s);const angle=Math.atan2(end.y-almostTheEnd.y,end.x-almostTheEnd.x)*180/Math.PI;const attrs=path.attr();delete attrs.path;let subpath=path.getSubpath(0,l-.75*s);subpath=this.raphael.path(subpath).attr(attrs);subpath.arrowheadsDrawn=true;path.remove();head.rotate(angle,this.isMobile?1e-5:.75,0).scale(s,s,.75,0).translate(almostTheEnd.x,almostTheEnd.y).attr(attrs).attr({"stroke-linejoin":"round","stroke-linecap":"round"});head.arrowheadsDrawn=true;set.push(subpath);set.push(head);return set}}else if(type===Raphael$1.st){for(let i=0,l=path.items.length;i<l;i++){this.addArrowheads(path.items[i]);}}return path}processAttributes(attrs){const transformers={scale:scale=>{this.drawingTransform().setScale(scale);},clipRect:pair=>{const point=pair[0];const size=pair[1];point[1]+=size[1];return {"clip-rect":this.scalePoint(point).concat(this.scaleVector(size)).join(" ")}},strokeWidth:function(val){return {"stroke-width":parseFloat(val)}},rx:val=>{return {rx:this.scaleVector([val,0])[0]}},ry:val=>{return {ry:this.scaleVector([0,val])[1]}},r:val=>{const scaled=this.scaleVector([val,val]);return {rx:scaled[0],ry:scaled[1]}}};const processed={};Object.entries(attrs||{}).forEach(function([key,value]){const transformer=transformers[key];if(typeof transformer==="function"){Object.assign(processed,transformer(value));}else {const dasherized=String(key).replace(/([A-Z]+)([A-Z][a-z])/g,"$1-$2").replace(/([a-z\d])([A-Z])/g,"$1-$2").toLowerCase();processed[dasherized]=value;}});return processed}addMouseLayer(options){const localOptions={allowScratchpad:false,...options};const mouselayerZIndex=2;this.mouselayer=Raphael$1(this.el,this.xpixels,this.ypixels);$(this.mouselayer.canvas).css("z-index",mouselayerZIndex);if(localOptions.onClick||localOptions.onMouseDown||localOptions.onMouseMove||localOptions.onMouseOver||localOptions.onMouseOut){const canvasClickTarget=this.mouselayer.rect(0,0,this.xpixels,this.ypixels).attr({fill:"transparent",opacity:0});let isClickingCanvas=false;$(this.mouselayer.canvas).on("vmousedown",e=>{if(e.target===canvasClickTarget[0]){if(localOptions.onMouseDown){localOptions.onMouseDown(this.getMouseCoord(e));}isClickingCanvas=true;if(localOptions.onMouseMove){const handler=localOptions.onMouseMove;$(document).on("vmousemove.mouseLayer",e=>{if(isClickingCanvas){e.preventDefault();handler(this.getMouseCoord(e));}});}$(document).on("vmouseup.mouseLayer",e=>{$(document).unbind(".mouseLayer");if(isClickingCanvas&&localOptions.onClick){localOptions.onClick(this.getMouseCoord(e));}isClickingCanvas=false;});}});if(localOptions.onMouseOver){const handler=localOptions.onMouseOver;$(this.mouselayer.canvas).on("vmouseover",e=>{handler(this.getMouseCoord(e));});}if(localOptions.onMouseOut){const handler=localOptions.onMouseOut;$(this.mouselayer.canvas).on("vmouseout",e=>{handler(this.getMouseCoord(e));});}}this._mouselayerWrapper=document.createElement("div");$(this._mouselayerWrapper).css({position:"absolute",left:0,top:0,zIndex:mouselayerZIndex});this._visiblelayerWrapper=document.createElement("div");$(this._visiblelayerWrapper).css({position:"absolute",left:0,top:0});const el=this.el;el.appendChild(this._visiblelayerWrapper);el.appendChild(this._mouselayerWrapper);this.addToMouseLayerWrapper=el=>{this._mouselayerWrapper?.appendChild(el);};this.addToVisibleLayerWrapper=el=>{this._visiblelayerWrapper?.appendChild(el);};}addToMouseLayerWrapper(el){throw new Error("addToMouseLayerWrapper is not ready. Call addMouseLayer() first.")}addToVisibleLayerWrapper(el){throw new Error("addToVisibleLayerWrapper is not ready. Call addMouseLayer() first.")}getMousePx(event){const offset=$(this.el).offset();const mouseX=event.pageX-offset.left;const mouseY=event.pageY-offset.top;return [mouseX,mouseY]}getMouseCoord(event){return this.unscalePoint(this.getMousePx(event))}_ensureResizeObserver(){if(_class_private_field_loose_base(this,_resizeObserver)[_resizeObserver]!=null||typeof ResizeObserver==="undefined"){return}_class_private_field_loose_base(this,_resizeObserver)[_resizeObserver]=new ResizeObserver(()=>{this._recalculateLabels();});_class_private_field_loose_base(this,_resizeObserver)[_resizeObserver].observe(this.el);}_recalculateLabels(){_class_private_field_loose_base(this,_labelElements)[_labelElements].forEach(span=>{const originalSize=$(span).data("originalLabelSize");if(originalSize!=null){setLabelMargins(span,originalSize);}});}cleanup(){_class_private_field_loose_base(this,_resizeObserver)[_resizeObserver]?.disconnect();_class_private_field_loose_base(this,_resizeObserver)[_resizeObserver]=null;_class_private_field_loose_base(this,_labelElements)[_labelElements].clear();}constructor(el){Object.defineProperty(this,_bounds,{writable:true,value:void 0});Object.defineProperty(this,_drawingTransform,{writable:true,value:void 0});Object.defineProperty(this,_labelElements,{writable:true,value:void 0});Object.defineProperty(this,_resizeObserver,{writable:true,value:void 0});_class_private_field_loose_base(this,_labelElements)[_labelElements]=new Set;_class_private_field_loose_base(this,_resizeObserver)[_resizeObserver]=null;this.isMobile=false;this.currentStyle={"stroke-width":2,fill:"none"};this.label=(point,text,direction,arg4,arg5)=>{const style=typeof arg4==="object"?arg4:arg5;const latex=typeof arg4==="boolean"?arg4:true;return this.withStyle(style,()=>{const $span=$("<span>").addClass("graphie-label");const pad=this.currentStyle["label-distance"];$span.css({position:"absolute",padding:(pad!=null?pad:7)+"px",color:semanticColor.core.foreground.neutral.strong}).data("labelDirection",direction).appendTo(this.el);$span.setPosition=point=>{const scaledPoint=this.scalePoint(point);$span.css({left:scaledPoint[0],top:scaledPoint[1]});};$span.setPosition(point);$span.css({"font-size":this.currentStyle["font-size"]});const span=$span[0];_class_private_field_loose_base(this,_labelElements)[_labelElements].add(span);$span.processMath=function(math,force){processMath$1(span,math,force,function(){const width=span.scrollWidth;const height=span.scrollHeight;setLabelMargins(span,[width,height]);});};$span.processText=function(text){$span.html(text);const width=span.scrollWidth;const height=span.scrollHeight;setLabelMargins(span,[width,height]);};if(latex){$span.processMath(text,false);}else {$span.processText(text);}this._ensureResizeObserver();return $span})};this.svgPath=(points,alreadyScaled)=>{return points.map((point,i)=>{if(point===true){return "z"}const scaled=alreadyScaled?point:this.scalePoint(point);return (i===0?"M":"L")+KhanMath.bound(scaled[0])+" "+KhanMath.bound(scaled[1])}).join("")};this.svgParabolaPath=(a,b,c)=>{const computeParabola=function(x){return (a*x+b)*x+c};if(a===0){const points=[[this.bounds().xMin,computeParabola(this.bounds().xMin)],[this.bounds().xMax,computeParabola(this.bounds().xMax)]];return this.svgPath(points)}const xVertex=-b/(2*a);const distToEdge=Math.max(Math.abs(xVertex-this.bounds().xMin),Math.abs(xVertex-this.bounds().xMax));const xPoint=xVertex+distToEdge;const vertex=[xVertex,computeParabola(xVertex)];const point=[xPoint,computeParabola(xPoint)];const control=[vertex[0],vertex[1]-(point[1]-vertex[1])];const dx=Math.abs(vertex[0]-point[0]);const left=[vertex[0]-dx,point[1]];const right=[vertex[0]+dx,point[1]];const points=[left,control,right].map(this.scalePoint);const values=points.flat().map(KhanMath.bound);return "M"+values[0]+","+values[1]+" Q"+values[2]+","+values[3]+" "+values[4]+","+values[5]};this.svgSinusoidPath=(a,b,c,d)=>{const quarterPeriod=Math.abs(Math.PI/(2*b));const computeSine=function(x){return a*Math.sin(b*x-c)+d};const computeDerivative=function(x){return a*b*Math.cos(c-b*x)};const coordsForOffset=(initial,i)=>{const x0=initial+quarterPeriod*i;const x1=x0+quarterPeriod;const xCoords=[x0,x0*2/3+x1*1/3,x0*1/3+x1*2/3,x1];const yCoords=[computeSine(x0),computeSine(x0)+computeDerivative(x0)*(x1-x0)/3,computeSine(x1)-computeDerivative(x1)*(x1-x0)/3,computeSine(x1)];const points=vector$3.zip(xCoords,yCoords);return points.map(this.scalePoint)};const extent=this.bounds().width();const numQuarterPeriods=Math.ceil(extent/quarterPeriod)+1;let initial=c/b;const distToEdge=initial-this.bounds().xMin;initial-=quarterPeriod*Math.ceil(distToEdge/quarterPeriod);let coords=coordsForOffset(initial,0);let path="M"+coords[0][0]+","+coords[0][1]+" C"+coords[1][0]+","+coords[1][1]+" "+coords[2][0]+","+coords[2][1]+" "+coords[3][0]+","+coords[3][1];for(let i=1;i<numQuarterPeriods;i++){coords=coordsForOffset(initial,i);path+=" C"+coords[1][0]+","+coords[1][1]+" "+coords[2][0]+","+coords[2][1]+" "+coords[3][0]+","+coords[3][1];}return path};this.scalePoint=point=>{return this.drawingTransform().scalePoint(point)};this.scaleVector=point=>{return this.drawingTransform().scaleVector(point)};this.unscalePoint=point=>{return this.drawingTransform().unscalePoint(point)};this.unscaleVector=point=>{return this.drawingTransform().unscaleVector(point)};this.el=el;$(el).css("position","relative");this.raphael=Raphael$1(el);$(el).attr("aria-hidden","true");$(el).children("div").css("position","absolute");}};const labelDirections={center:[-0.5,-0.5],above:[-0.5,-1],"above right":[0,-1],right:[0,-0.5],"below right":[0,0],below:[-0.5,0],"below left":[-1,0],left:[-1,-0.5],"above left":[-1,-1]};function normalizeRange(range){function normalizeInterval(magnitude){if(typeof magnitude==="number"){return [-magnitude,magnitude]}else {return magnitude}}function getXAndYRanges(range){if(Array.isArray(range)){return range}else {return [range,range]}}if(range==null){return range}const[xRange,yRange]=getXAndYRanges(range);return [normalizeInterval(xRange),normalizeInterval(yRange)]}function toPair(x){if(Array.isArray(x)){return x}return [x,x]}const SVG_SPECIFIC_STYLE_MASK={"stroke-width":null};const setLabelMargins=function(span,size){if(document.fonts?.status==="loading"){document.fonts.ready.then(()=>applyLabelMargins(span,size));return}applyLabelMargins(span,size);};const applyLabelMargins=function(span,size){const $span=$(span);const direction=$span.data("labelDirection");let[width,height]=size;if(width===0&&height===0){[width,height]=[1,1];Log.log("Label size was 0x0 in graphie.js; using 1x1 instead");}$span.css("visibility","");if(typeof direction==="number"){const x=Math.cos(direction);const y=Math.sin(direction);const scale=Math.min(width/2/Math.abs(x),height/2/Math.abs(y));$span.css({marginLeft:-width/2+x*scale,marginTop:-height/2-y*scale});if($span.data("originalLabelSize")==null){$span.data("originalLabelSize",[width,height]);}}else {const $svgImage=$span.closest(".svg-image");const $graphie=$span.closest(".graphie");const $container=$svgImage.length>0?$svgImage:$graphie;$container.css("line-height","normal");if($span.data("originalLabelSize")==null){height=span.scrollHeight;$span.data("originalLabelSize",[width,height]);}const widthValues=$container.css(["max-width","width"])??{"max-width":"0px"};const expectedWidth=widthValues["max-width"]!=="none"?widthValues["max-width"]:widthValues["width"];let scale=($container.width()??0)/parseInt(expectedWidth.replace(/px$/,""));if(isNaN(scale)){scale=1;}else if(scale===0){scale=1;}let rawPadding;const storedPadding=$span.data("originalPadding");if(storedPadding!=null){rawPadding=storedPadding;}else {const padding=$span.css("padding")??"0px";const currentPadding=padding!=="none"?padding:"0px";rawPadding=parseInt(currentPadding.replace(/px$/,""));$span.data("originalPadding",rawPadding);}let normalizedWidth=width;let normalizedHeight=height;const imageScale=Number($container.attr("data-scale"));const hasValidImageScale=!Number.isNaN(imageScale)&&imageScale>=0;if(hasValidImageScale){scale=scale*imageScale;const totalPadding=2*rawPadding;normalizedWidth=(width-totalPadding)/imageScale+totalPadding;normalizedHeight=(height-totalPadding)/imageScale+totalPadding;}const newPadding=rawPadding*scale;const multipliers=labelDirections[direction||"center"];const styling={marginLeft:normalizedWidth*multipliers[0]*scale,marginTop:normalizedHeight*multipliers[1]*scale,padding:`${newPadding}px`,fontSize:`${scale*100}%`};$span.css(styling);}};const GraphUtils={Graphie: Graphie$1,createGraphie:function(el){return new Graphie$1(el)},unscaledSvgPath:function(points){if(points[0]===true){return ""}return points.map(function(point,i){if(point===true){return "z"}return (i===0?"M":"L")+point[0]+" "+point[1]}).join("")},getDistance:function(point1,point2){return point.distanceToPoint(point1,point2)},findAngleDeprecated:function(point1,point2,vertex){if(vertex===undefined){const x=point1[0]-point2[0];const y=point1[1]-point2[1];if(!x&&!y){return 0}return (180+Math.atan2(-y,-x)*180/Math.PI+360)%360}return GraphUtils.findAngleDeprecated(point1,vertex)-GraphUtils.findAngleDeprecated(point2,vertex)},graphs:{}};
1560
-
1561
- (function($,window1,document1,undefined$1){if(typeof $==="undefined"){return}var dataPropertyName="virtualMouseBindings",touchTargetPropertyName="virtualTouchID",virtualEventNames="vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split(" "),touchEventProps="clientX clientY pageX pageY screenX screenY".split(" "),mouseHookProps=$.event.mouseHooks?$.event.mouseHooks.props:[],mouseEventProps=$.event.props.concat(mouseHookProps),activeDocHandlers={},resetTimerID=0,startX=0,startY=0,didScroll=false,clickBlockList=[],blockMouseTriggers=false,blockTouchTriggers=false,eventCaptureSupported="addEventListener"in document1,$document=$(document1),nextTouchID=1,lastTouchID=0;$.vmouse={moveDistanceThreshold:10,clickDistanceThreshold:10,resetTimerDuration:1500};function getNativeEvent(event){while(event&&typeof event.originalEvent!=="undefined"){event=event.originalEvent;}return event}function createVirtualEvent(event,eventType){var t=event.type,oe,props,ne,prop,ct,touch,i,j,len;event=$.Event(event);event.type=eventType;oe=event.originalEvent;props=$.event.props;if(t.search(/mouse/)>-1){props=mouseEventProps;}if(oe){for(i=props.length,prop;i;){prop=props[--i];event[prop]=oe[prop];}}if(t.search(/mouse(down|up)|click/)>-1&&!event.which){event.which=1;}if(t.search(/^touch/)!==-1){ne=getNativeEvent(oe);t=ne.touches;ct=ne.changedTouches;touch=t&&t.length?t[0]:ct&&ct.length?ct[0]:undefined$1;if(touch){for(j=0,len=touchEventProps.length;j<len;j++){prop=touchEventProps[j];event[prop]=touch[prop];}}}return event}function getVirtualBindingFlags(element){var flags={},b,k;while(element){b=$.data(element,dataPropertyName);for(k in b){if(b[k]){flags[k]=flags.hasVirtualBinding=true;}}element=element.parentNode;}return flags}function getClosestElementWithVirtualBinding(element,eventType){var b;while(element){b=$.data(element,dataPropertyName);if(b&&(!eventType||b[eventType])){return element}element=element.parentNode;}return null}function enableTouchBindings(){blockTouchTriggers=false;}function disableTouchBindings(){blockTouchTriggers=true;}function enableMouseBindings(){lastTouchID=0;clickBlockList.length=0;blockMouseTriggers=false;disableTouchBindings();}function disableMouseBindings(){enableTouchBindings();}function startResetTimer(){clearResetTimer();resetTimerID=setTimeout(function(){resetTimerID=0;enableMouseBindings();},$.vmouse.resetTimerDuration);}function clearResetTimer(){if(resetTimerID){clearTimeout(resetTimerID);resetTimerID=0;}}function triggerVirtualEvent(eventType,event,flags){var ve;if(flags&&flags[eventType]||!flags&&getClosestElementWithVirtualBinding(event.target,eventType)){ve=createVirtualEvent(event,eventType);$(event.target).trigger(ve);}return ve}function mouseEventCallback(event){var touchID=$.data(event.target,touchTargetPropertyName);if(!blockMouseTriggers&&(!lastTouchID||lastTouchID!==touchID)){var ve=triggerVirtualEvent("v"+event.type,event);if(ve){if(ve.isDefaultPrevented()){event.preventDefault();}if(ve.isPropagationStopped()){event.stopPropagation();}if(ve.isImmediatePropagationStopped()){event.stopImmediatePropagation();}}}}function handleTouchStart(event){var touches=getNativeEvent(event).touches,target,flags;if(touches&&touches.length===1){target=event.target;flags=getVirtualBindingFlags(target);if(flags.hasVirtualBinding){lastTouchID=nextTouchID++;$.data(target,touchTargetPropertyName,lastTouchID);clearResetTimer();disableMouseBindings();didScroll=false;var t=getNativeEvent(event).touches[0];startX=t.pageX;startY=t.pageY;triggerVirtualEvent("vmouseover",event,flags);triggerVirtualEvent("vmousedown",event,flags);}}}function handleScroll(event){if(blockTouchTriggers){return}if(!didScroll){triggerVirtualEvent("vmousecancel",event,getVirtualBindingFlags(event.target));}didScroll=true;startResetTimer();}function handleTouchMove(event){if(blockTouchTriggers){return}var t=getNativeEvent(event).touches[0],didCancel=didScroll,moveThreshold=$.vmouse.moveDistanceThreshold,didScroll=didScroll||Math.abs(t.pageX-startX)>moveThreshold||Math.abs(t.pageY-startY)>moveThreshold,flags=getVirtualBindingFlags(event.target);if(didScroll&&!didCancel){triggerVirtualEvent("vmousecancel",event,flags);}triggerVirtualEvent("vmousemove",event,flags);startResetTimer();}function handleTouchEnd(event){if(blockTouchTriggers){return}disableTouchBindings();var flags=getVirtualBindingFlags(event.target),t;triggerVirtualEvent("vmouseup",event,flags);if(!didScroll){var ve=triggerVirtualEvent("vclick",event,flags);if(ve&&ve.isDefaultPrevented()){t=getNativeEvent(event).changedTouches[0];clickBlockList.push({touchID:lastTouchID,x:t.clientX,y:t.clientY});blockMouseTriggers=true;}}triggerVirtualEvent("vmouseout",event,flags);didScroll=false;startResetTimer();}function hasVirtualBindings(ele){var bindings=$.data(ele,dataPropertyName),k;if(bindings){for(k in bindings){if(bindings[k]){return true}}}return false}function dummyMouseHandler(){}function getSpecialEventObject(eventType){var realType=eventType.substr(1);return {setup:function(data,namespace){if(!hasVirtualBindings(this)){$.data(this,dataPropertyName,{});}var bindings=$.data(this,dataPropertyName);bindings[eventType]=true;activeDocHandlers[eventType]=(activeDocHandlers[eventType]||0)+1;if(activeDocHandlers[eventType]===1){$document.bind(realType,mouseEventCallback);}$(this).bind(realType,dummyMouseHandler);if(eventCaptureSupported){activeDocHandlers["touchstart"]=(activeDocHandlers["touchstart"]||0)+1;if(activeDocHandlers["touchstart"]===1){$document.bind("touchstart",handleTouchStart).bind("touchend",handleTouchEnd).bind("touchmove",handleTouchMove).bind("scroll",handleScroll);}}},teardown:function(data,namespace){--activeDocHandlers[eventType];if(!activeDocHandlers[eventType]){$document.unbind(realType,mouseEventCallback);}if(eventCaptureSupported){--activeDocHandlers["touchstart"];if(!activeDocHandlers["touchstart"]){$document.unbind("touchstart",handleTouchStart).unbind("touchmove",handleTouchMove).unbind("touchend",handleTouchEnd).unbind("scroll",handleScroll);}}var $this=$(this),bindings=$.data(this,dataPropertyName);if(bindings){bindings[eventType]=false;}$this.unbind(realType,dummyMouseHandler);if(!hasVirtualBindings(this)){$this.removeData(dataPropertyName);}}}}for(var i=0;i<virtualEventNames.length;i++){$.event.special[virtualEventNames[i]]=getSpecialEventObject(virtualEventNames[i]);}if(eventCaptureSupported){document1.addEventListener("click",function(e){var cnt=clickBlockList.length,target=e.target,x,y,ele,i,o;if(cnt){x=e.clientX;y=e.clientY;threshold=$.vmouse.clickDistanceThreshold;ele=target;while(ele){for(i=0;i<cnt;i++){o=clickBlockList[i];if(ele===target&&Math.abs(o.x-x)<threshold&&Math.abs(o.y-y)<threshold||$.data(ele,touchTargetPropertyName)===o.touchID){e.preventDefault();e.stopPropagation();return}}ele=ele.parentNode;}}},true);}})($,window,document);
1562
-
1563
- const getClipPoint=function(graph,coord,angle){const xExtent=graph.range[0][1]-graph.range[0][0];const yExtent=graph.range[1][1]-graph.range[1][0];const distance=xExtent+yExtent;const angleVec=graph.unscaleVector(vector$3.cartFromPolarDeg(1,angle));const distVec=vector$3.scale(vector$3.normalize(angleVec),distance);const farCoord=vector$3.add(coord,distVec);const scaledAngle=vector$3.polarDegFromCart(angleVec)[1];const clipPoint=graph.constrainToBoundsOnAngle(farCoord,4,scaledAngle*Math.PI/180);return clipPoint};
1564
-
1565
- class WrappedDrawing{transform(transformation){const prefixedTransform=InteractiveUtil.getPrefixedTransform();this.wrapper.style[prefixedTransform]=transformation;}toFront(){const parentNode=this.wrapper.parentNode;if(parentNode){parentNode.appendChild(this.wrapper);}}toBack(){const parentNode=this.wrapper.parentNode;if(parentNode!=null&&parentNode.firstChild!==this.wrapper){parentNode.insertBefore(this.wrapper,parentNode.firstChild);}}remove(){this.visibleShape.remove();this.wrapper.remove();}getMouseTarget(){return this.visibleShape[0]}moveTo(point){const delta=vector$3.subtract(this.graphie.scalePoint(point),this.graphie.scalePoint(this.initialPoint));const do3dTransform=InteractiveUtil.getCanUse3dTransform();const transformation="translateX("+delta[0]+"px) "+"translateY("+delta[1]+"px)"+(do3dTransform?" translateZ(0)":"");this.transform(transformation);}hide(){this.visibleShape.hide();}show(){this.visibleShape.show();}attr(...args){this.visibleShape.attr(...args);}animate(...args){this.visibleShape.animate(...args);}constructor(graphie,initialPoint){this.graphie=graphie;this.initialPoint=initialPoint;}}
1566
-
1567
- const DEFAULT_OPTIONS$2={center:null,createPath:null,mouselayer:false};class WrappedPath extends WrappedDrawing{constructor(graphie,points,options){const initialPoint=graphie.scalePoint(points[0]);super(graphie,initialPoint);options={...DEFAULT_OPTIONS$2,...options};const fixedPath=graphie.fixedPath(points,options.center,options.createPath);this.wrapper=fixedPath.wrapper;this.visibleShape=fixedPath.visibleShape;if(options.mouselayer){this.wrapper.style.touchAction="none";this.graphie.addToMouseLayerWrapper(this.wrapper);}else {this.graphie.addToVisibleLayerWrapper(this.wrapper);}}}
1568
-
1569
- let Arrowhead$1 = class Arrowhead extends WrappedPath{toCoordAtAngle(coord,angle){const clipPoint=this.graphie.scalePoint(getClipPoint(this.graphie,coord,angle));this.transform("translateX("+(clipPoint[0]+Arrowhead.scale*this.center[0])+"px) "+"translateY("+(clipPoint[1]+Arrowhead.scale*this.center[1])+"px) "+"translateZ(0) "+"rotate("+(360-KhanMath.bound(angle))+"deg)");}constructor(graphie,style){const center=[.75,0];const points=[[-3,4],[-2.75,2.5],[0,.25],center,[0,-0.25],[-2.75,-2.5],[-3,-4]].map(point=>{const pv=vector$3.subtract(point,center);const pvScaled=vector$3.scale(pv,Arrowhead.scale);return vector$3.add(center,pvScaled)});const unscaledPoints=points.map(graphie.unscalePoint);super(graphie,unscaledPoints,{center:graphie.unscalePoint(center),createPath:createCubicPath});this.center=center;this.attr(_.extend({"stroke-linejoin":"round","stroke-linecap":"round","stroke-dasharray":""},style));}};Arrowhead$1.scale=1.4;const createCubicPath=function(points){let path="M"+points[0][0]+" "+points[0][1];for(let i=1;i<points.length;i+=3){path+="C"+points[i][0]+" "+points[i][1]+" "+points[i+1][0]+" "+points[i+1][1]+" "+points[i+2][0]+" "+points[i+2][1];}return path};
1570
-
1571
- const DEFAULT_OPTIONS$1={maxScale:1,mouselayer:false,shadow:false,disableMouseEventsOnWrapper:false};const wrappedEllipseShadow=`drop-shadow(0px 0px 2px ${semanticColor.core.foreground.instructive.default})`;class WrappedEllipse extends WrappedDrawing{setShadow(shadow){this.wrapper.style.filter=shadow?wrappedEllipseShadow:"";}constructor(graphie,center,radii,options){super(graphie,center);options=_.extend({},DEFAULT_OPTIONS$1,options);const fixedEllipse=graphie.fixedEllipse(center,radii,options.maxScale,options.padding);this.visibleShape=fixedEllipse.visibleShape;this.wrapper=fixedEllipse.wrapper;this.graphie=graphie;this.initialPoint=center;if(options.interactiveKindForTesting){this.wrapper.setAttribute("data-interactive-kind-for-testing",options.interactiveKindForTesting);}if(options.mouselayer){this.wrapper.style.touchAction="none";this.graphie.addToMouseLayerWrapper(this.wrapper);}else {this.graphie.addToVisibleLayerWrapper(this.wrapper);}this.setShadow(options.shadow);if(options.disableMouseEventsOnWrapper){this.wrapper.style.pointerEvents="none";this.visibleShape.node.style.pointerEvents="auto";}}}
1572
-
1573
- const DEFAULT_OPTIONS={thickness:2,mouselayer:false};class WrappedLine extends WrappedDrawing{getMouseTarget(){return this.wrapper}moveTo(start,end){const scaledStart=this.graphie.scalePoint(start);const scaledEnd=this.graphie.scalePoint(end);const polarDiff=vector$3.polarDegFromCart(vector$3.subtract(scaledEnd,scaledStart));const lineLength=polarDiff[0];const angle=KhanMath.bound(polarDiff[1]);const delta=vector$3.subtract(scaledStart,this.initialPoint);const scale=KhanMath.bound(lineLength/this.initialLength);const do3dTransform=InteractiveUtil.getCanUse3dTransform();const transformation="translateX("+delta[0]+"px) "+"translateY("+delta[1]+"px) "+(do3dTransform?" translateZ(0)":"")+"rotate("+angle+"deg) "+"scaleX("+scale+") scaleY(1)";this.transform(transformation);}constructor(graphie,start,end,options){const initialStart=[graphie.range[0][0],0];const initialEnd=[graphie.range[0][1],0];const initialPoint=graphie.scalePoint(initialStart);super(graphie,initialPoint);options=_.extend({},DEFAULT_OPTIONS,options);const fixedLine=graphie.fixedLine(initialStart,initialEnd,options.thickness);this.wrapper=fixedLine.wrapper;this.visibleShape=fixedLine.visibleShape;if(options.interactiveKindForTesting){this.wrapper.setAttribute("data-interactive-kind-for-testing",options.interactiveKindForTesting);}this.visibleShape.attr(options.normalStyle);this.initialPoint=initialPoint;this.initialLength=point.distanceToPoint(graphie.scalePoint(initialStart),graphie.scalePoint(initialEnd));if(options.mouselayer){this.wrapper.style.touchAction="none";this.graphie.addToMouseLayerWrapper(this.wrapper);}else {this.graphie.addToVisibleLayerWrapper(this.wrapper);}this.moveTo(start,end);}}
1574
-
1575
- const{reverseVector: reverseVector$1}=geometry;function scaledDistanceFromAngle(angle){const a=3.51470560176242*20;const b=.5687298702748785*20;const c=-0.037587715462826674;return (a-b)*Math.exp(c*angle)+b}function scaledPolarRad(radius,radians){return [radius*Math.cos(radians),radius*Math.sin(radians)*-1]}function scaledPolarDeg(radius,degrees){const radians=degrees*Math.PI/180;return scaledPolarRad(radius,radians)}let dragging=false;const InteractiveUtils={bogusShape:{animate:function(){},attr:function(){},remove:function(){}}};_.extend(GraphUtils.Graphie.prototype,{labelAngle:function(options){const graphie=this;_.defaults(options,{point1:[0,0],vertex:[0,0],point3:[0,0],label:null,numArcs:1,showRightAngleMarker:true,pushOut:0,clockwise:false,style:{}});let text=options.text===undefined?"":options.text;const vertex=options.vertex;const sVertex=graphie.scalePoint(vertex);let p1;let p3;if(options.clockwise){p1=options.point1;p3=options.point3;}else {p1=options.point3;p3=options.point1;}const startAngle=GraphUtils.findAngleDeprecated(p1,vertex);const endAngle=GraphUtils.findAngleDeprecated(p3,vertex);const angle=(endAngle+360-startAngle)%360;const halfAngle=(startAngle+angle/2)%360;const sPadding=5*options.pushOut;let sRadius=sPadding+scaledDistanceFromAngle(angle);const temp=[];if(Math.abs(angle-90)<1e-9&&options.showRightAngleMarker){const v1=vector$3.add(sVertex,scaledPolarDeg(sRadius,startAngle));const v2=vector$3.add(sVertex,scaledPolarDeg(sRadius,endAngle));sRadius*=Math.SQRT2;const v3=vector$3.add(sVertex,scaledPolarDeg(sRadius,halfAngle));[v1,v2].forEach(function(v){temp.push(graphie.scaledPath([v,v3],options.style));});}else {for(let i=0;i<options.numArcs;i++){temp.push(graphie.arc(vertex,graphie.unscaleVector(sRadius),startAngle,endAngle,options.style));sRadius+=3;}}if(text){const match=text.match(/\$deg(\d)?/);if(match){const precision=match[1]||1;text=text.replace(match[0],KhanMath.toFixedApprox(angle,precision)+"^{\\circ}");}const sOffset=scaledPolarDeg(sRadius+15,halfAngle);const sPosition=vector$3.add(sVertex,sOffset);const position=graphie.unscalePoint(sPosition);if(options.label){options.label.setPosition(position);options.label.processMath(text,true);}else {graphie.label(position,text,"center",options.style);}}return temp},labelSide:function(options){const graphie=this;_.defaults(options,{point1:[0,0],point2:[0,0],label:null,text:"",numTicks:0,numArrows:0,clockwise:false,style:{}});let p1;let p2;if(options.clockwise){p1=options.point1;p2=options.point2;}else {p1=options.point2;p2=options.point1;}const midpoint=[(p1[0]+p2[0])/2,(p1[1]+p2[1])/2];const sMidpoint=graphie.scalePoint(midpoint);const parallelAngle=Math.atan2(p2[1]-p1[1],p2[0]-p1[0]);const perpendicularAngle=parallelAngle+Math.PI/2;const temp=[];let sCumulativeOffset=0;if(options.numTicks){const n=options.numTicks;const sSpacing=5;const sHeight=5;const style={...options.style,strokeWidth:2};for(let i=0;i<n;i++){const sOffset=sSpacing*(i-(n-1)/2);const sOffsetVector=scaledPolarRad(sOffset,parallelAngle);const sHeightVector=scaledPolarRad(sHeight,perpendicularAngle);const sPath=[vector$3.add(sMidpoint,sOffsetVector,sHeightVector),vector$3.add(sMidpoint,sOffsetVector,reverseVector$1(sHeightVector))];temp.push(graphie.scaledPath(sPath,style));}sCumulativeOffset+=sSpacing*(n-1)+15;}if(options.numArrows){const n=options.numArrows;const start=[p1,p2].sort(function(a,b){if(a[1]===b[1]){return a[0]-b[0]}return a[1]-b[1]})[0];const sStart=graphie.scalePoint(start);const style={...options.style,arrows:"->",strokeWidth:2};const sSpacing=5;for(let i=0;i<n;i++){const sOffset=sCumulativeOffset+sSpacing*i;let sOffsetVector=scaledPolarRad(sOffset,parallelAngle);if(start!==p1){sOffsetVector=reverseVector$1(sOffsetVector);}const sEnd=vector$3.add(sMidpoint,sOffsetVector);temp.push(graphie.scaledPath([sStart,sEnd],style));}}let text=options.text;if(text){const match=text.match(/\$len(\d)?/);if(match){const distance=GraphUtils.getDistance(p1,p2);const precision=match[1]||1;text=text.replace(match[0],KhanMath.toFixedApprox(distance,precision));}const sOffset=20;const sOffsetVector=scaledPolarRad(sOffset,perpendicularAngle);const sPosition=vector$3.add(sMidpoint,sOffsetVector);const position=graphie.unscalePoint(sPosition);if(options.label){options.label.setPosition(position);options.label.processMath(text,true);}else {graphie.label(position,text,"center",options.style);}}return temp},labelVertex:function(options){const graphie=this;_.defaults(options,{point1:null,vertex:[0,0],point3:null,label:null,text:"",clockwise:false,style:{}});if(!options.text){return}const vertex=options.vertex;const sVertex=graphie.scalePoint(vertex);let p1;let p3;if(options.clockwise){p1=options.point1;p3=options.point3;}else {p1=options.point3;p3=options.point1;}let angle=135;let halfAngle;if(p1&&p3){const startAngle=GraphUtils.findAngleDeprecated(p1,vertex);const endAngle=GraphUtils.findAngleDeprecated(p3,vertex);angle=(endAngle+360-startAngle)%360;halfAngle=(startAngle+angle/2+180)%360;}else if(p1){const parallelAngle=GraphUtils.findAngleDeprecated(vertex,p1);halfAngle=parallelAngle+90;}else if(p3){const parallelAngle=GraphUtils.findAngleDeprecated(p3,vertex);halfAngle=parallelAngle+90;}else {halfAngle=135;}const sRadius=10+scaledDistanceFromAngle(360-angle);const sOffsetVector=scaledPolarDeg(sRadius,halfAngle);const sPosition=vector$3.add(sVertex,sOffsetVector);const position=graphie.unscalePoint(sPosition);if(options.label){options.label.setPosition(position);options.label.processMath(options.text,true);}else {graphie.label(position,options.text,"center",options.style);}},addMovablePoint:function(options){const movablePoint=$.extend(true,{graph:this,coord:[0,0],snapX:0,snapY:0,pointSize:4,highlight:false,dragging:false,visible:true,bounded:true,constraints:{fixed:false,constrainX:false,constrainY:false,fixedAngle:{},fixedDistance:{}},lineStarts:[],lineEnds:[],polygonVertices:[],normalStyle:{},highlightStyle:{fill:KhanColors.INTERACTING,stroke:KhanColors.INTERACTING},labelStyle:{color:KhanColors.INTERACTIVE},vertexLabel:"",mouseTarget:null},options);const normalColor=movablePoint.constraints.fixed?KhanColors.DYNAMIC:KhanColors.INTERACTIVE;movablePoint.normalStyle={fill:normalColor,stroke:normalColor,...options.normalStyle};if(options.coordX!==undefined){movablePoint.coord[0]=options.coordX;}if(options.coordY!==undefined){movablePoint.coord[1]=options.coordY;}const graph=movablePoint.graph;const applySnapAndConstraints=function(coord){if(movablePoint.visible&&movablePoint.bounded&&!movablePoint.constraints.fixed){coord=graph.constrainToBounds(coord,10);}let coordX=coord[0];let coordY=coord[1];if(movablePoint.snapX!==0){coordX=Math.round(coordX/movablePoint.snapX)*movablePoint.snapX;}if(movablePoint.snapY!==0){coordY=Math.round(coordY/movablePoint.snapY)*movablePoint.snapY;}if(movablePoint.constraints.fixedDistance.snapPoints){const mouse=graph.scalePoint(coord);let mouseX=mouse[0];let mouseY=mouse[1];const snapRadians=2*Math.PI/movablePoint.constraints.fixedDistance.snapPoints;const radius=movablePoint.constraints.fixedDistance.dist;const centerCoord=movablePoint.constraints.fixedDistance.point;const centerX=(centerCoord[0]-graph.range[0][0])*graph.scale[0];const centerY=(-centerCoord[1]+graph.range[1][1])*graph.scale[1];let mouseXrel=mouseX-centerX;let mouseYrel=-mouseY+centerY;let radians=Math.atan(mouseYrel/mouseXrel);const outsideArcTanRange=mouseXrel<0;if(outsideArcTanRange){radians+=Math.PI;}radians=Math.round(radians/snapRadians)*snapRadians;mouseXrel=radius*Math.cos(radians);mouseYrel=radius*Math.sin(radians);mouseX=mouseXrel+centerX;mouseY=-mouseYrel+centerY;coordX=KhanMath.roundTo(5,mouseX/graph.scale[0]+graph.range[0][0]);coordY=KhanMath.roundTo(5,graph.range[1][1]-mouseY/graph.scale[1]);}const result=movablePoint.applyConstraint([coordX,coordY]);return result};movablePoint.applyConstraint=function(coord,extraConstraints,override){let newCoord=coord.slice();const constraints={};if(override){$.extend(constraints,{fixed:false,constrainX:false,constrainY:false,fixedAngle:{},fixedDistance:{}},extraConstraints);}else {$.extend(constraints,this.constraints,extraConstraints);}if(constraints.constrainX){newCoord=[this.coord[0],coord[1]];}else if(constraints.constrainY){newCoord=[coord[0],this.coord[1]];}else if(typeof constraints.fixedAngle.angle==="number"&&typeof constraints.fixedDistance.dist==="number"){const vertex=constraints.fixedAngle.vertex.coord||constraints.fixedAngle.vertex;const ref=constraints.fixedAngle.ref.coord||constraints.fixedAngle.ref;const distPoint=constraints.fixedDistance.point.coord||constraints.fixedDistance.point;const constrainedAngle=(constraints.fixedAngle.angle+GraphUtils.findAngleDeprecated(ref,vertex))*Math.PI/180;const length=constraints.fixedDistance.dist;newCoord[0]=length*Math.cos(constrainedAngle)+distPoint[0];newCoord[1]=length*Math.sin(constrainedAngle)+distPoint[1];}else if(typeof constraints.fixedAngle.angle==="number"){const vertex=constraints.fixedAngle.vertex.coord||constraints.fixedAngle.vertex;const ref=constraints.fixedAngle.ref.coord||constraints.fixedAngle.ref;const constrainedAngle=(constraints.fixedAngle.angle+GraphUtils.findAngleDeprecated(ref,vertex))*Math.PI/180;const angle=GraphUtils.findAngleDeprecated(coord,vertex)*Math.PI/180;const distance=GraphUtils.getDistance(coord,vertex);let length=distance*Math.cos(constrainedAngle-angle);length=length<1?1:length;newCoord[0]=length*Math.cos(constrainedAngle)+vertex[0];newCoord[1]=length*Math.sin(constrainedAngle)+vertex[1];}else if(typeof constraints.fixedDistance.dist==="number"){const distPoint=constraints.fixedDistance.point.coord||constraints.fixedDistance.point;let angle=GraphUtils.findAngleDeprecated(coord,distPoint);const length=constraints.fixedDistance.dist;angle=angle*Math.PI/180;newCoord[0]=length*Math.cos(angle)+distPoint[0];newCoord[1]=length*Math.sin(angle)+distPoint[1];}else if(constraints.fixed){newCoord=movablePoint.coord;}return newCoord};movablePoint.coord=applySnapAndConstraints(movablePoint.coord);const highlightScale=2;if(movablePoint.visible){graph.style(movablePoint.normalStyle,function(){const radii=[movablePoint.pointSize/graph.scale[0],movablePoint.pointSize/graph.scale[1]];const options={maxScale:highlightScale,padding:2};movablePoint.visibleShape=new WrappedEllipse(graph,movablePoint.coord,radii,options);const{scale,...styleWithoutScale}=movablePoint.normalStyle;movablePoint.visibleShape.attr(styleWithoutScale);movablePoint.visibleShape.toFront();});}movablePoint.normalStyle.scale=1;movablePoint.highlightStyle.scale=highlightScale;if(movablePoint.vertexLabel){movablePoint.labeledVertex=this.label([0,0],"","center",movablePoint.labelStyle);}movablePoint.drawLabel=function(){if(movablePoint.vertexLabel){movablePoint.graph.labelVertex({vertex:movablePoint.coord,label:movablePoint.labeledVertex,text:movablePoint.vertexLabel,style:movablePoint.labelStyle});}};movablePoint.drawLabel();movablePoint.grab=function(offset){offset=offset||[0,0];$(document).on("vmousemove.point vmouseup.point",function(event){event.preventDefault();movablePoint.dragging=true;dragging=true;let coord=vector$3.add(graph.getMouseCoord(event),offset);coord=applySnapAndConstraints(coord);let coordX=coord[0];let coordY=coord[1];let mouseX;let mouseY;if(event.type==="vmousemove"){let doMove=true;if(typeof movablePoint.onMove==="function"){const result=movablePoint.onMove(coordX,coordY);if(result===false){doMove=false;}if(Array.isArray(result)){coordX=result[0];coordY=result[1];}}mouseX=(coordX-graph.range[0][0])*graph.scale[0];mouseY=(-coordY+graph.range[1][1])*graph.scale[1];if(doMove){const point=graph.unscalePoint([mouseX,mouseY]);movablePoint.visibleShape.moveTo(point);movablePoint.mouseTarget.moveTo(point);movablePoint.coord=[coordX,coordY];movablePoint.updateLineEnds();$(movablePoint).trigger("move");}movablePoint.drawLabel();}else if(event.type==="vmouseup"){$(document).unbind(".point");movablePoint.dragging=false;dragging=false;if(typeof movablePoint.onMoveEnd==="function"){const result=movablePoint.onMoveEnd(coordX,coordY);if(Array.isArray(result)){coordX=result[0];coordY=result[1];mouseX=(coordX-graph.range[0][0])*graph.scale[0];mouseY=(-coordY+graph.range[1][1])*graph.scale[1];const point=graph.unscalePoint([mouseX,mouseY]);movablePoint.visibleShape.moveTo(point);movablePoint.mouseTarget.moveTo(point);movablePoint.coord=[coordX,coordY];}}if(!movablePoint.highlight){movablePoint.visibleShape.animate(movablePoint.normalStyle,50);if(movablePoint.onUnhighlight){movablePoint.onUnhighlight();}}}});};if(movablePoint.visible&&!movablePoint.constraints.fixed){if(!movablePoint.mouseTarget){const radii=graph.unscaleVector(16);const options={mouselayer:true,padding:0,disableMouseEventsOnWrapper:true,interactiveKindForTesting:"movable-point"};movablePoint.mouseTarget=new WrappedEllipse(graph,movablePoint.coord,radii,options);movablePoint.mouseTarget.attr({fill:"transparent",opacity:0});}const $mouseTarget=$(movablePoint.mouseTarget.getMouseTarget());$mouseTarget.css("cursor","move");$mouseTarget.on("vmousedown vmouseover vmouseout",function(event){if(event.type==="vmouseover"){movablePoint.highlight=true;if(!dragging){movablePoint.visibleShape.animate(movablePoint.highlightStyle,50);if(movablePoint.onHighlight){movablePoint.onHighlight();}}}else if(event.type==="vmouseout"){movablePoint.highlight=false;if(!movablePoint.dragging&&!dragging){movablePoint.visibleShape.animate(movablePoint.normalStyle,50);if(movablePoint.onUnhighlight){movablePoint.onUnhighlight();}}}else if(event.type==="vmousedown"&&(event.which===1||event.which===0)){event.preventDefault();const startCoord=movablePoint.coord;const startMouseCoord=graph.getMouseCoord(event);const isMouse=!("ontouchstart"in window);const touchOffset=isMouse?[0,0]:vector$3.subtract(startCoord,startMouseCoord);movablePoint.grab(touchOffset);}});}movablePoint.moveTo=function(coordX,coordY,updateLines){const distance=GraphUtils.getDistance(this.graph.scalePoint([coordX,coordY]),this.graph.scalePoint(this.coord));const time=distance*5;const cb=updateLines&&function(coord){movablePoint.coord=coord;movablePoint.updateLineEnds();};this.visibleShape.animateTo([coordX,coordY],time,cb);this.mouseTarget.animateTo([coordX,coordY],time,cb);this.coord=[coordX,coordY];if(typeof this.onMove==="function"){this.onMove(coordX,coordY);}};movablePoint.updateLineEnds=function(){$(this.lineStarts).each(function(){this.coordA=movablePoint.coord;this.transform();});$(this.lineEnds).each(function(){this.coordZ=movablePoint.coord;this.transform();});$(this.polygonVertices).each(function(){this.transform();});};movablePoint.setCoord=function(coord){if(this.visible){this.visibleShape.moveTo(coord);if(this.mouseTarget!=null){this.mouseTarget.moveTo(coord);}}this.coord=coord.slice();};movablePoint.setCoordConstrained=function(coord){this.setCoord(applySnapAndConstraints(coord));};movablePoint.toBack=function(){if(this.visible){if(this.mouseTarget!=null){this.mouseTarget.toBack();}this.visibleShape.toBack();}};movablePoint.toFront=function(){if(this.visible){if(this.mouseTarget!=null){this.mouseTarget.toFront();}this.visibleShape.toFront();}};movablePoint.remove=function(){if(this.visibleShape){this.visibleShape.remove();}if(this.mouseTarget){this.mouseTarget.remove();}if(this.labeledVertex){this.labeledVertex.remove();}};return movablePoint},addMovableLineSegment:function(options){const lineSegment=$.extend({graph:this,coordA:[0,0],coordZ:[1,1],snapX:0,snapY:0,fixed:false,ticks:0,normalStyle:{},highlightStyle:{stroke:tokenValue(semanticColor.core.border.instructive.default),"stroke-width":6},labelStyle:{stroke:KhanColors.INTERACTIVE,color:KhanColors.INTERACTIVE},highlight:false,dragging:false,tick:[],extendLine:false,extendRay:false,constraints:{fixed:false,constrainX:false,constrainY:false},sideLabel:"",vertexLabels:[],numArrows:0,numTicks:0,movePointsWithLine:false},options);const normalColor=lineSegment.fixed?KhanColors.DYNAMIC:KhanColors.INTERACTIVE;lineSegment.normalStyle={"stroke-width":2,stroke:normalColor,...options.normalStyle};lineSegment.arrowStyle={...lineSegment.normalStyle,color:lineSegment.normalStyle.stroke};if(options.pointA!==undefined){lineSegment.coordA=options.pointA.coord;lineSegment.pointA.lineStarts.push(lineSegment);}else if(options.coordA!==undefined){lineSegment.coordA=options.coordA.slice();}if(options.pointZ!==undefined){lineSegment.coordZ=options.pointZ.coord;lineSegment.pointZ.lineEnds.push(lineSegment);}else if(options.coordA!==undefined){lineSegment.coordA=lineSegment.coordA.slice();}const graph=lineSegment.graph;graph.style(lineSegment.normalStyle);for(let i=0;i<lineSegment.ticks;++i){lineSegment.tick[i]=InteractiveUtils.bogusShape;}let path=GraphUtils.unscaledSvgPath([[0,0],[1,0]]);for(let i=0;i<lineSegment.ticks;++i){const tickoffset=.5-(lineSegment.ticks-1+i*2)/graph.scale[0];path+=GraphUtils.unscaledSvgPath([[tickoffset,-7],[tickoffset,7]]);}options={thickness:Math.max(lineSegment.normalStyle["stroke-width"],lineSegment.highlightStyle["stroke-width"])};lineSegment.visibleLine=new WrappedLine(graph,[0,0],[1,0],options);lineSegment.visibleLine.attr(lineSegment.normalStyle);if(!lineSegment.fixed){const options={thickness:30,mouselayer:true,interactiveKindForTesting:"movable-line"};lineSegment.mouseTarget=new WrappedLine(graph,[0,0],[1,0],options);lineSegment.mouseTarget.attr({fill:"transparent",opacity:0});}lineSegment.transform=function(syncToPoints){if(syncToPoints){if(typeof this.pointA==="object"){this.coordA=this.pointA.coord;}if(typeof this.pointZ==="object"){this.coordZ=this.pointZ.coord;}}const getScaledAngle=function(line){const scaledA=line.graph.scalePoint(line.coordA);const scaledZ=line.graph.scalePoint(line.coordZ);return vector$3.polarDegFromCart(vector$3.subtract(scaledZ,scaledA))[1]};const getClipPoint=function(graph,coord,angle){graph=lineSegment.graph;const xExtent=graph.range[0][1]-graph.range[0][0];const yExtent=graph.range[1][1]-graph.range[1][0];const distance=xExtent+yExtent;const angleVec=graph.unscaleVector(vector$3.cartFromPolarDeg(1,angle));const distVec=vector$3.scale(vector$3.normalize(angleVec),distance);const farCoord=vector$3.add(coord,distVec);const scaledAngle=vector$3.polarDegFromCart(angleVec)[1];const clipPoint=graph.constrainToBoundsOnAngle(farCoord,4,scaledAngle*Math.PI/180);return clipPoint};const angle=getScaledAngle(this);let start=this.coordA;let end=this.coordZ;if(this.extendLine){start=getClipPoint(graph,start,360-angle);end=getClipPoint(graph,end,(540-angle)%360);}else if(this.extendRay){end=getClipPoint(graph,start,360-angle);}const elements=[this.visibleLine];if(!this.fixed){elements.push(this.mouseTarget);}elements.forEach(function(element){element.moveTo(start,end);});if(this._arrows==null){this._arrows=[];if(this.extendLine){this._arrows.push(new Arrowhead$1(graph,this.normalStyle));this._arrows.push(new Arrowhead$1(graph,this.normalStyle));}else if(this.extendRay){this._arrows.push(new Arrowhead$1(graph,this.normalStyle));}}const coordForArrow=[this.coordA,this.coordZ];const angleForArrow=[360-angle,(540-angle)%360];this._arrows.forEach(function(arrow,i){arrow.toCoordAtAngle(coordForArrow[i],angleForArrow[i]);});_.invoke(this.temp,"remove");this.temp=[];const isClockwise=this.coordA[0]<this.coordZ[0]||this.coordA[0]===this.coordZ[0]&&this.coordA[1]>this.coordZ[1];if(this.sideLabel){this.temp.push(this.graph.labelSide({point1:this.coordA,point2:this.coordZ,label:this.labeledSide,text:this.sideLabel,numArrows:this.numArrows,numTicks:this.numTicks,clockwise:isClockwise,style:this.labelStyle}));}if(this.vertexLabels.length){this.graph.labelVertex({vertex:this.coordA,point3:this.coordZ,label:this.labeledVertices[0],text:this.vertexLabels[0],clockwise:isClockwise,style:this.labelStyle});this.graph.labelVertex({point1:this.coordA,vertex:this.coordZ,label:this.labeledVertices[1],text:this.vertexLabels[1],clockwise:isClockwise,style:this.labelStyle});}this.temp=this.temp.flat(Infinity);};lineSegment.toBack=function(){if(!lineSegment.fixed){lineSegment.mouseTarget.toBack();}lineSegment.visibleLine.toBack();};lineSegment.toFront=function(){if(!lineSegment.fixed){lineSegment.mouseTarget.toFront();}lineSegment.visibleLine.toFront();};lineSegment.remove=function(){if(!lineSegment.fixed){lineSegment.mouseTarget.remove();}lineSegment.visibleLine.remove();if(lineSegment.labeledSide){lineSegment.labeledSide.remove();}if(lineSegment.labeledVertices){_.invoke(lineSegment.labeledVertices,"remove");}if(lineSegment._arrows){_.invoke(lineSegment._arrows,"remove");}if(lineSegment.temp.length){_.invoke(lineSegment.temp,"remove");}};lineSegment.hide=function(){lineSegment.visibleLine.hide();if(lineSegment.temp.length){_.invoke(lineSegment.temp,"hide");}if(lineSegment._arrows){_.invoke(lineSegment._arrows,"hide");}};lineSegment.show=function(){lineSegment.visibleLine.show();if(lineSegment.temp.length){_.invoke(lineSegment.temp,"show");}if(lineSegment._arrows){_.invoke(lineSegment._arrows,"show");}};if(lineSegment.sideLabel){lineSegment.labeledSide=this.label([0,0],"","center",lineSegment.labelStyle);}if(lineSegment.vertexLabels.length){lineSegment.labeledVertices=lineSegment.vertexLabels.map(label=>{return this.label([0,0],"","center",lineSegment.labelStyle)});}if(!lineSegment.fixed&&!lineSegment.constraints.fixed){const $mouseTarget=$(lineSegment.mouseTarget.getMouseTarget());$mouseTarget.css("cursor","move");$mouseTarget.on("vmousedown vmouseover vmouseout",function(event){if(event.type==="vmouseover"){if(!dragging){lineSegment.highlight=true;lineSegment.visibleLine.animate(lineSegment.highlightStyle,50);lineSegment.arrowStyle={...lineSegment.arrowStyle,color:lineSegment.highlightStyle.stroke,stroke:lineSegment.highlightStyle.stroke};lineSegment.transform();}}else if(event.type==="vmouseout"){lineSegment.highlight=false;if(!lineSegment.dragging){lineSegment.visibleLine.animate(lineSegment.normalStyle,50);lineSegment.arrowStyle={...lineSegment.arrowStyle,color:lineSegment.normalStyle.stroke,stroke:lineSegment.normalStyle.stroke};lineSegment.transform();}}else if(event.type==="vmousedown"&&(event.which===1||event.which===0)){event.preventDefault();let coordX=(event.pageX-$(graph.raphael.canvas.parentNode).offset().left)/graph.scale[0]+graph.range[0][0];let coordY=graph.range[1][1]-(event.pageY-$(graph.raphael.canvas.parentNode).offset().top)/graph.scale[1];if(lineSegment.snapX>0){coordX=Math.round(coordX/lineSegment.snapX)*lineSegment.snapX;}if(lineSegment.snapY>0){coordY=Math.round(coordY/lineSegment.snapY)*lineSegment.snapY;}const mouseOffsetA=[lineSegment.coordA[0]-coordX,lineSegment.coordA[1]-coordY];const mouseOffsetZ=[lineSegment.coordZ[0]-coordX,lineSegment.coordZ[1]-coordY];const offsetLeft=-Math.min(graph.scaleVector(mouseOffsetA)[0],graph.scaleVector(mouseOffsetZ)[0]);const offsetRight=Math.max(graph.scaleVector(mouseOffsetA)[0],graph.scaleVector(mouseOffsetZ)[0]);const offsetTop=Math.max(graph.scaleVector(mouseOffsetA)[1],graph.scaleVector(mouseOffsetZ)[1]);const offsetBottom=-Math.min(graph.scaleVector(mouseOffsetA)[1],graph.scaleVector(mouseOffsetZ)[1]);$(document).on("vmousemove.lineSegment vmouseup.lineSegment",function(event){event.preventDefault();lineSegment.dragging=true;dragging=true;let mouseX=event.pageX-$(graph.raphael.canvas.parentNode).offset().left;let mouseY=event.pageY-$(graph.raphael.canvas.parentNode).offset().top;mouseX=Math.max(offsetLeft+10,Math.min(graph.xpixels-10-offsetRight,mouseX));mouseY=Math.max(offsetTop+10,Math.min(graph.ypixels-10-offsetBottom,mouseY));let coordX=mouseX/graph.scale[0]+graph.range[0][0];let coordY=graph.range[1][1]-mouseY/graph.scale[1];if(lineSegment.snapX>0){coordX=Math.round(coordX/lineSegment.snapX)*lineSegment.snapX;}if(lineSegment.snapY>0){coordY=Math.round(coordY/lineSegment.snapY)*lineSegment.snapY;}if(event.type==="vmousemove"){if(lineSegment.constraints.constrainX){coordX=lineSegment.coordA[0]-mouseOffsetA[0];}if(lineSegment.constraints.constrainY){coordY=lineSegment.coordA[1]-mouseOffsetA[1];}const dX=coordX+mouseOffsetA[0]-lineSegment.coordA[0];const dY=coordY+mouseOffsetA[1]-lineSegment.coordA[1];lineSegment.coordA=[coordX+mouseOffsetA[0],coordY+mouseOffsetA[1]];lineSegment.coordZ=[coordX+mouseOffsetZ[0],coordY+mouseOffsetZ[1]];lineSegment.transform();if(lineSegment.movePointsWithLine){if(typeof lineSegment.pointA==="object"){lineSegment.pointA.setCoord([lineSegment.pointA.coord[0]+dX,lineSegment.pointA.coord[1]+dY]);}if(typeof lineSegment.pointZ==="object"){lineSegment.pointZ.setCoord([lineSegment.pointZ.coord[0]+dX,lineSegment.pointZ.coord[1]+dY]);}}if(typeof lineSegment.onMove==="function"){lineSegment.onMove(dX,dY);}}else if(event.type==="vmouseup"){$(document).unbind(".lineSegment");lineSegment.dragging=false;dragging=false;if(!lineSegment.highlight){lineSegment.visibleLine.animate(lineSegment.normalStyle,50);lineSegment.arrowStyle={...lineSegment.arrowStyle,color:lineSegment.normalStyle.stroke,stroke:lineSegment.normalStyle.stroke};lineSegment.transform();}if(typeof lineSegment.onMoveEnd==="function"){lineSegment.onMoveEnd();}}$(lineSegment).trigger("move");});}});}if(lineSegment.pointA!==undefined){lineSegment.pointA.toFront();}if(lineSegment.pointZ!==undefined){lineSegment.pointZ.toFront();}lineSegment.transform();return lineSegment},constrainToBounds:function(point,padding){const lower=this.unscalePoint([padding,this.ypixels-padding]);const upper=this.unscalePoint([this.xpixels-padding,padding]);const coordX=Math.max(lower[0],Math.min(upper[0],point[0]));const coordY=Math.max(lower[1],Math.min(upper[1],point[1]));return [coordX,coordY]},constrainToBoundsOnAngle:function(point,padding,angle){const lower=this.unscalePoint([padding,this.ypixels-padding]);const upper=this.unscalePoint([this.xpixels-padding,padding]);let result=point.slice();if(result[0]<lower[0]){result=[lower[0],result[1]+(lower[0]-result[0])*Math.tan(angle)];}else if(result[0]>upper[0]){result=[upper[0],result[1]-(result[0]-upper[0])*Math.tan(angle)];}if(result[1]<lower[1]){result=[result[0]+(lower[1]-result[1])/Math.tan(angle),lower[1]];}else if(result[1]>upper[1]){result=[result[0]-(result[1]-upper[1])/Math.tan(angle),upper[1]];}return result},protractor:function(center){return new Protractor$1(this,center)},ruler:function(options){return new Ruler(this,options||{})},addPoints:vector$3.add});function Protractor$1(graph,center){this.set=graph.raphael.set();this.cx=center[0];this.cy=center[1];const pro=this;const r=graph.unscaleVector(180.5)[0];const imgPos=graph.scalePoint([this.cx-r,this.cy+r-graph.unscaleVector(10.5)[1]]);const image=graph.mouselayer.image("https://ka-perseus-graphie.s3.amazonaws.com/e9d032f2ab8b95979f674fbfa67056442ba1ff6a.png",imgPos[0],imgPos[1],360,180);this.set.push(image);image.node.addEventListener("touchstart",function(event){event.preventDefault();},{passive:false});const arrowHelper=function(angle,pixelsFromEdge){const scaledRadius=graph.scaleVector(r);scaledRadius[0]-=16;scaledRadius[1]-=16;const scaledCenter=graph.scalePoint(center);const x=Math.sin((angle+90)*Math.PI/180)*(scaledRadius[0]+pixelsFromEdge)+scaledCenter[0];const y=Math.cos((angle+90)*Math.PI/180)*(scaledRadius[1]+pixelsFromEdge)+scaledCenter[1];return x+","+y};const arrow=graph.raphael.path(" M"+arrowHelper(180,6)+" L"+arrowHelper(180,2)+" L"+arrowHelper(183,10)+" L"+arrowHelper(180,18)+" L"+arrowHelper(180,14)+" A"+(graph.scaleVector(r)[0]+10)+","+(graph.scaleVector(r)[1]+10)+",0,0,1,"+arrowHelper(170,14)+" L"+arrowHelper(170,18)+" L"+arrowHelper(167,10)+" L"+arrowHelper(170,2)+" L"+arrowHelper(170,6)+" A"+(graph.scaleVector(r)[0]+10)+","+(graph.scaleVector(r)[1]+10)+",0,0,0,"+arrowHelper(180,6)+" Z").attr({stroke:null,fill:KhanColors.INTERACTIVE});this.set.push(arrow);this.centerPoint=graph.addMovablePoint({coord:center,visible:false});this.rotateHandle=graph.addMovablePoint({bounded:false,coord:[Math.sin(275*Math.PI/180)*r+this.cx,Math.cos(275*Math.PI/180)*r+this.cy],onMove:function(x,y){const angle=Math.atan2(pro.centerPoint.coord[1]-y,pro.centerPoint.coord[0]-x)*180/Math.PI;pro.rotate(-angle-5,true);}});this.rotateHandle.constraints.fixedDistance.dist=r;this.rotateHandle.constraints.fixedDistance.point=this.centerPoint;this.rotateHandle.visibleShape.remove();this.rotateHandle.mouseTarget.attr({scale:2});let isDragging=false;let isHovering=false;const isHighlight=function(){return isHovering||isDragging};const self=this;const $mouseTarget=$(self.rotateHandle.mouseTarget.getMouseTarget());$mouseTarget.on("vmousedown",function(event){isDragging=true;$mouseTarget.css("cursor","-webkit-grabbing");$mouseTarget.css("cursor","grabbing");arrow.animate({scale:1.5,fill:KhanColors.INTERACTING},50);$(document).on("vmouseup.rotateHandle",function(event){isDragging=false;$mouseTarget.css("cursor","-webkit-grab");$mouseTarget.css("cursor","grab");if(!isHighlight()){arrow.animate({scale:1,fill:KhanColors.INTERACTIVE},50);}$(document).unbind("vmouseup.rotateHandle");});});$mouseTarget.on("vmouseover",function(event){isHovering=true;arrow.animate({scale:1.5,fill:KhanColors.INTERACTING},50);});$mouseTarget.on("vmouseout",function(event){isHovering=false;if(!isHighlight()){arrow.animate({scale:1,fill:KhanColors.INTERACTIVE},50);}});const setNodes=$.map(this.set,function(el){return el.node});this.makeTranslatable=function makeTranslatable(){$(setNodes).css("cursor","move");$mouseTarget.css("cursor","-webkit-grab");$mouseTarget.css("cursor","grab");$(setNodes).on("vmousedown",function(event){event.preventDefault();let startx=event.pageX-$(graph.raphael.canvas.parentNode).offset().left;let starty=event.pageY-$(graph.raphael.canvas.parentNode).offset().top;$(document).on("vmousemove.protractor",function(event){let mouseX=event.pageX-$(graph.raphael.canvas.parentNode).offset().left;let mouseY=event.pageY-$(graph.raphael.canvas.parentNode).offset().top;mouseX=Math.max(10,Math.min(graph.xpixels-10,mouseX));mouseY=Math.max(10,Math.min(graph.ypixels-10,mouseY));const dx=mouseX-startx;const dy=mouseY-starty;$.each(pro.set.items,function(){this.translate(dx,dy);});pro.centerPoint.setCoord([pro.centerPoint.coord[0]+dx/graph.scale[0],pro.centerPoint.coord[1]-dy/graph.scale[1]]);pro.rotateHandle.setCoord([pro.rotateHandle.coord[0]+dx/graph.scale[0],pro.rotateHandle.coord[1]-dy/graph.scale[1]]);startx=mouseX;starty=mouseY;});$(document).one("vmouseup",function(event){$(document).unbind("vmousemove.protractor");});});};this.rotation=0;this.rotate=function(offset,absolute){const center=graph.scalePoint(this.centerPoint.coord);if(absolute){this.rotation=0;}this.set.rotate(this.rotation+offset,center[0],center[1]);this.rotation=this.rotation+offset;return this};this.moveTo=function moveTo(x,y){const start=graph.scalePoint(pro.centerPoint.coord);const end=graph.scalePoint([x,y]);const time=GraphUtils.getDistance(start,end)*2;$({x:start[0],y:start[1]}).animate({x:end[0],y:end[1]},{duration:time,step:function(now,fx){let dx=0;let dy=0;if(fx.prop==="x"){dx=now-graph.scalePoint(pro.centerPoint.coord)[0];}else if(fx.prop==="y"){dy=now-graph.scalePoint(pro.centerPoint.coord)[1];}$.each(pro.set.items,function(){this.translate(dx,dy);});pro.centerPoint.setCoord([pro.centerPoint.coord[0]+dx/graph.scale[0],pro.centerPoint.coord[1]-dy/graph.scale[1]]);pro.rotateHandle.setCoord([pro.rotateHandle.coord[0]+dx/graph.scale[0],pro.rotateHandle.coord[1]-dy/graph.scale[1]]);}});};this.rotateTo=function rotateTo(angle){if(Math.abs(this.rotation-angle)>180){this.rotation+=360;}const time=Math.abs(this.rotation-angle)*5;$({0:this.rotation}).animate({0:angle},{duration:time,step:function(now,fx){pro.rotate(now,true);pro.rotateHandle.setCoord([Math.sin((now+275)*Math.PI/180)*r+pro.centerPoint.coord[0],Math.cos((now+275)*Math.PI/180)*r+pro.centerPoint.coord[1]]);}});};this.remove=function(){this.set.remove();};this.makeTranslatable();return this}function Ruler(graphie,options){_.defaults(options,{center:[0,0],pixelsPerUnit:40,ticksPerUnit:10,units:10,label:"",style:{fill:null,stroke:KhanColors.GRAY}});const light={...options.style,strokeWidth:1};const bold={...options.style,strokeWidth:2};const width=options.units*options.pixelsPerUnit;const height=50;const leftBottom=graphie.unscalePoint(vector$3.subtract(graphie.scalePoint(options.center),vector$3.scale([width,-50],.5)));const graphieUnitsPerUnit=options.pixelsPerUnit/graphie.scale[0];const graphieUnitsHeight=height/graphie.scale[0];const rightTop=vector$3.add(leftBottom,[options.units*graphieUnitsPerUnit,graphieUnitsHeight]);const tickHeight=1;let tickHeightMap;if(options.ticksPerUnit===10){tickHeightMap={10:tickHeight,5:tickHeight*.55,1:tickHeight*.35};}else {const sizes=[1,.6,.45,.3];tickHeightMap={};for(let i=options.ticksPerUnit;i>=1;i/=2){tickHeightMap[i]=tickHeight*(sizes.shift()||.2);}}const tickFrequencies=Object.keys(tickHeightMap).sort(function(a,b){return b-a});function getTickHeight(i){for(let k=0;k<tickFrequencies.length;k++){const key=tickFrequencies[k];if(i%key===0){return tickHeightMap[key]}}return 0}const left=leftBottom[0];const bottom=leftBottom[1];const right=rightTop[0];const top=rightTop[1];const numTicks=options.units*options.ticksPerUnit+1;const set=graphie.raphael.set();const px=1/graphie.scale[0];set.push(graphie.line([left-px,bottom],[right+px,bottom],bold));set.push(graphie.line([left-px,top],[right+px,top],bold));for(let i=0;i<numTicks;i++){const n=i/options.ticksPerUnit;const x=left+n*graphieUnitsPerUnit;const height=getTickHeight(i)*graphieUnitsHeight;const style=i===0||i===numTicks-1?bold:light;set.push(graphie.line([x,bottom],[x,bottom+height],style));if(n%1===0){const coord=graphie.scalePoint([x,top]);let text;let offset;if(n===0){text=options.label;offset=({mm:13,cm:11,m:8,km:11,in:8,ft:8,yd:10,mi:10})[text]||3*text.toString().length;}else {text=n;offset=-3*(n.toString().length+1);}const label=graphie.raphael.text(coord[0]+offset,coord[1]+10,text);label.attr({"font-family":"KaTeX_Main","font-size":"12px",color:"#444"});set.push(label);}}const mouseTarget=graphie.mouselayer.path(graphie.svgPath([leftBottom,[left,top],rightTop,[right,bottom],true]));mouseTarget.attr({fill:"transparent",opacity:0,stroke:"transparent","stroke-width":2});set.push(mouseTarget);mouseTarget.node.addEventListener("touchstart",function(event){event.preventDefault();},{passive:false});const setNodes=$.map(set,function(el){return el.node});$(setNodes).css("cursor","move");$(setNodes).on("vmousedown",function(event){event.preventDefault();let startx=event.pageX-$(graphie.raphael.canvas.parentNode).offset().left;let starty=event.pageY-$(graphie.raphael.canvas.parentNode).offset().top;$(document).on("vmousemove.ruler",function(event){let mouseX=event.pageX-$(graphie.raphael.canvas.parentNode).offset().left;let mouseY=event.pageY-$(graphie.raphael.canvas.parentNode).offset().top;mouseX=Math.max(10,Math.min(graphie.xpixels-10,mouseX));mouseY=Math.max(10,Math.min(graphie.ypixels-10,mouseY));const dx=mouseX-startx;const dy=mouseY-starty;set.translate(dx,dy);leftBottomHandle.setCoord([leftBottomHandle.coord[0]+dx/graphie.scale[0],leftBottomHandle.coord[1]-dy/graphie.scale[1]]);rightBottomHandle.setCoord([rightBottomHandle.coord[0]+dx/graphie.scale[0],rightBottomHandle.coord[1]-dy/graphie.scale[1]]);startx=mouseX;starty=mouseY;});$(document).one("vmouseup",function(event){$(document).unbind("vmousemove.ruler");});});const leftBottomHandle=graphie.addMovablePoint({coord:leftBottom,normalStyle:{fill:KhanColors.INTERACTIVE,"fill-opacity":0,stroke:KhanColors.INTERACTIVE},highlightStyle:{fill:KhanColors.INTERACTING,"fill-opacity":.1,stroke:KhanColors.INTERACTING},pointSize:6,onMove:function(x,y){const dy=rightBottomHandle.coord[1]-y;const dx=rightBottomHandle.coord[0]-x;const angle=Math.atan2(dy,dx)*180/Math.PI;const center=vector$3.scale(vector$3.add([x,y],rightBottomHandle.coord),.5);const scaledCenter=graphie.scalePoint(center);const oldCenter=vector$3.scale(vector$3.add(leftBottomHandle.coord,rightBottomHandle.coord),.5);const scaledOldCenter=graphie.scalePoint(oldCenter);const diff=vector$3.subtract(scaledCenter,scaledOldCenter);set.rotate(-angle,scaledOldCenter[0],scaledOldCenter[1]);set.translate(diff[0],diff[1]);}});const rightBottomHandle=graphie.addMovablePoint({coord:[right,bottom],normalStyle:{fill:KhanColors.INTERACTIVE,"fill-opacity":0,stroke:KhanColors.INTERACTIVE},highlightStyle:{fill:KhanColors.INTERACTING,"fill-opacity":.1,stroke:KhanColors.INTERACTING},pointSize:6,onMove:function(x,y){const dy=y-leftBottomHandle.coord[1];const dx=x-leftBottomHandle.coord[0];const angle=Math.atan2(dy,dx)*180/Math.PI;const center=vector$3.scale(vector$3.add([x,y],leftBottomHandle.coord),.5);const scaledCenter=graphie.scalePoint(center);const oldCenter=vector$3.scale(vector$3.add(leftBottomHandle.coord,rightBottomHandle.coord),.5);const scaledOldCenter=graphie.scalePoint(oldCenter);const diff=vector$3.subtract(scaledCenter,scaledOldCenter);set.rotate(-angle,scaledOldCenter[0],scaledOldCenter[1]);set.translate(diff[0],diff[1]);}});leftBottomHandle.constraints.fixedDistance.dist=width/graphie.scale[0];leftBottomHandle.constraints.fixedDistance.point=rightBottomHandle;rightBottomHandle.constraints.fixedDistance.dist=width/graphie.scale[0];rightBottomHandle.constraints.fixedDistance.point=leftBottomHandle;this.remove=function(){set.remove();leftBottomHandle.remove();rightBottomHandle.remove();};return this}
1576
-
1577
- const nestedMap$1=Util.nestedMap;function GraphieMovable$1(descriptor){_.extend(this,descriptor);}const abstractMethod=function(){throw new PerseusError("Abstract method! Must be implemented by Graphie Movable"+this.constructor.displayName,Errors.NotAllowed)};_.extend(GraphieMovable$1.prototype,{movableProps:[],add:abstractMethod,modify:abstractMethod,remove:abstractMethod,toFront:function(){},componentDidMount:function(){}});const rewriteProps=function(props,childrenArray){return _.extend({},props,{children:_.filter(_.flatten(childrenArray),c=>c)})};const createClass=function(spec){const GraphieClass=function(props){if(!(this instanceof GraphieClass)){throw new PerseusError("Use createElement or JSX with graphie movables",Errors.NotAllowed)}this.props=rewriteProps(props,props.children||[]);return this};spec.displayName=spec.displayName||_.uniqueId("GraphieClass");GraphieClass.displayName=spec.displayName;GraphieClass.prototype=new GraphieMovable$1(spec);GraphieClass.prototype.constructor=GraphieClass;return GraphieClass};const createSimpleClass=function(addFunction){return createClass({displayName:addFunction.name||_.uniqueId("GraphieSimpleClass"),movableProps:["children"],add:function(graphie){this._elements=addFunction(graphie,this.props);this._prevProps=this.props;},modify:function(graphie){if(!approximateDeepEqual(this.props,this._prevProps)){this.remove();this.add(graphie);this._prevProps=this.props;return "reordered"}},remove:function(){nestedMap$1(this._elements,elem=>{if(elem){elem.remove();}});this._elements=null;this._prevProps=null;},toFront:function(){nestedMap$1(this._elements,elem=>{if(elem&&typeof elem.toFront==="function"){elem.toFront();}});}})};var GraphieClasses = {GraphieMovable:GraphieMovable$1,createClass:createClass,createSimpleClass:createSimpleClass};
1578
-
1579
- const normalizeOptions$2=InteractiveUtil.normalizeOptions;const assert$5=InteractiveUtil.assert;const DEFAULT_PROPS$2={cursor:null};const DEFAULT_STATE$2={added:false,isHovering:false,isMouseOver:false,isDragging:false,mouseTarget:null};class Movable{modify(options){this.update({...this._createDefaultState(),...options});}_createDefaultState(){return {id:this.state.id,add:[],modify:[],draw:[],remove:[],onMoveStart:[],onMove:[],onMoveEnd:[],onClick:[],...DEFAULT_PROPS$2}}update(options){const graphie=this.graphie;const prevState=this.cloneState();const state=Object.assign(this.state,normalizeOptions$2(options));if(state.mouseTarget&&!prevState.mouseTarget){let $mouseTarget;if(state.mouseTarget.getMouseTarget){$mouseTarget=$(state.mouseTarget.getMouseTarget());}else {$mouseTarget=$(state.mouseTarget[0]);}const isMouse=!("ontouchstart"in window);if(isMouse){$mouseTarget.on("vmouseover",()=>{state.isMouseOver=true;if(!graphie.isDragging){state.isHovering=true;}if(this.state.added){this.draw();}});$mouseTarget.on("vmouseout",()=>{state.isMouseOver=false;if(!state.isDragging){state.isHovering=false;}if(this.state.added){this.draw();}});}$mouseTarget[0].addEventListener("touchstart",function(event){event.preventDefault();},{passive:false});$mouseTarget.on("vmousedown",e=>{if(e.which!==0&&e.which!==1){return}e.preventDefault();const mouseCoord=graphie.getMouseCoord(e);this.grab(mouseCoord);});}if(state.mouseTarget&&state.cursor!==undefined){let $mouseTarget;if(state.mouseTarget.getMouseTarget){$mouseTarget=$(state.mouseTarget.getMouseTarget());}else {$mouseTarget=$(state.mouseTarget[0]);}$mouseTarget.css("cursor",state.cursor||"");}if(!state.added){this._fireEvent(state.modify,this.cloneState(),{});state.added=true;this.prevState=this.cloneState();}this._fireEvent(state.modify,this.cloneState(),this.prevState);}cloneState(){return {...this.state}}_fireEvent(listeners,...args){if(listeners==null){return}for(const listener of listeners){listener.call(this,...args);}}draw(){const currState=this.cloneState();this._fireEvent(this.state.draw,currState,this.prevState);this.prevState=currState;}grab(coord){assert$5(point.is(coord));const graphie=this.graphie;const state=this.state;state.isHovering=true;state.isDragging=true;graphie.isDragging=true;const startMouseCoord=coord;let prevMouseCoord=startMouseCoord;this._fireEvent(state.onMoveStart,startMouseCoord,startMouseCoord);const moveHandler=e=>{e.preventDefault();const mouseCoord=graphie.getMouseCoord(e);this._fireEvent(state.onMove,mouseCoord,prevMouseCoord);this.draw();prevMouseCoord=mouseCoord;};const upHandler=()=>{$(document).unbind("vmousemove",moveHandler);$(document).unbind("vmouseup",upHandler);if(state.isHovering){this._fireEvent(state.onClick,prevMouseCoord,startMouseCoord);}state.isHovering=this.state.isMouseOver;state.isDragging=false;graphie.isDragging=false;this._fireEvent(state.onMoveEnd,prevMouseCoord,startMouseCoord);this.draw();};$(document).on("vmousemove",moveHandler);$(document).on("vmouseup",upHandler);}_applyConstraints(current,previous,extraOptions){let skipRemaining=false;return (this.state.constraints??[]).reduce((memo,constraint)=>{if(memo===false){return false}if(skipRemaining){return memo}const result=constraint.call(this,memo,previous,{onSkipRemaining:()=>{skipRemaining=true;},...extraOptions});if(result===false){return false}if(point.is(result,2)){return result}if(result===true||result==null){return memo}throw new PerseusError("Constraint returned invalid result: "+result,Errors.Internal)},current)}toBack(){if(this.state.mouseTarget){this.state.mouseTarget.toBack();}}toFront(){if(this.state.mouseTarget){this.state.mouseTarget.toFront();}}listen(eventName,id,func){this._listenerMap=this._listenerMap||{};const key=getKey$1(eventName,id);const index=this._listenerMap[key]=this._listenerMap[key]||this.state[eventName].length;this.state[eventName][index]=func;}unlisten(eventName,id){this._listenerMap=this._listenerMap||{};const key=getKey$1(eventName,id);const index=this._listenerMap[key];if(index!==undefined){this.state[eventName].splice(index,1);delete this._listenerMap[key];const keys=Object.keys(this._listenerMap);keys.forEach(key=>{if(getEventName$1(key)===eventName&&this._listenerMap[key]>index){this._listenerMap[key]--;}});}}remove(){this.state.added=false;this._fireEvent(this.state.remove);if(this.state.mouseTarget){$(this.state.mouseTarget).off();this.state.mouseTarget.remove();this.state.mouseTarget=null;}}cursor(){return this.state.cursor}added(){return this.state.added}isHovering(){return this.state.isHovering}isMouseOver(){return this.state.isMouseOver}isDragging(){return this.state.isDragging}mouseTarget(){return this.state.mouseTarget}constructor(graphie,options){this._listenerMap={};this.graphie=graphie;this.state={id:_.uniqueId("movable")};this.modify({...DEFAULT_STATE$2,...options});}}function getKey$1(eventName,id){return eventName+":"+id}function getEventName$1(key){return key.split(":")[0]}
1580
-
1581
- const getScaledAngle=function(line){const scaledA=line.graphie.scalePoint(line.coord(0));const scaledZ=line.graphie.scalePoint(line.coord(1));return vector$3.polarDegFromCart(vector$3.subtract(scaledZ,scaledA))[1]};const add$1={draw:function(){this.draw();},pointsToFront:function(state){_.invoke(state.points,"toFront");}};add$1.standard=[add$1.draw,add$1.pointsToFront];const modify$1={draw:function(){this.draw();}};modify$1.standard=[modify$1.draw];const draw$1={basic:function(state){const graphie=this.graphie;let start=this.coord(0);let end=this.coord(1);if(!this.state.visibleShape){const options={thickness:10};this.state.visibleShape=new WrappedLine(graphie,start,end,options);this.state.visibleShape.attr(this.normalStyle());this.state.visibleShape.toFront();if(this.mouseTarget()){this.mouseTarget().toFront();}}const angle=getScaledAngle(this);if(state.extendLine){start=getClipPoint(graphie,start,360-angle);end=getClipPoint(graphie,end,(540-angle)%360);}else if(state.extendRay){end=getClipPoint(graphie,end,360-angle);}const elements=[this.state.visibleShape];if(this.mouseTarget()){elements.push(this.mouseTarget());}_.each(elements,function(element){element.moveTo(start,end);});},arrows:function(state){if(this._arrows==null){this._arrows=[];if(state.extendLine){this._arrows.push(new Arrowhead$1(this.graphie,this.normalStyle()));this._arrows.push(new Arrowhead$1(this.graphie,this.normalStyle()));}else if(state.extendRay){this._arrows.push(new Arrowhead$1(this.graphie,this.normalStyle()));}}const angle=getScaledAngle(this);const angleForArrow=[360-angle,(540-angle)%360];_.each(this._arrows,function(arrow,i){arrow.toCoordAtAngle(this.coord(i),angleForArrow[i]);},this);},highlight:function(state,prevState){if(state.isHovering&&!prevState.isHovering){state.visibleShape.animate(state.highlightStyle,50);}else if(!state.isHovering&&prevState.isHovering){state.visibleShape.animate(state.normalStyle,50);}}};draw$1.standard=[draw$1.basic,draw$1.arrows,draw$1.highlight];const remove$1={basic:function(){if(this.state.visibleShape){this.state.visibleShape.remove();}},arrows:function(){if(this._arrows!=null){_.invoke(this._arrows,"remove");}this._arrows=null;}};remove$1.standard=[remove$1.basic,remove$1.arrows];const constraints$1={fixed:function(){return function(){return false}},snap:function(snap){return function(coord,prevCoord){if(snap===null){return true}let delta=vector$3.subtract(coord,prevCoord);snap=snap||this.graphie.snap;delta=point.roundTo(delta,snap);return vector$3.add(prevCoord,delta)}},bound:function(range,snap,paddingPx){if(paddingPx===undefined){if(range===undefined){paddingPx=10;}else {paddingPx=0;}}return function(coord,prevCoord){const graphie=this.graphie;const delta=vector$3.subtract(coord,prevCoord);range=range||graphie.range;if(snap===undefined){snap=graphie.snap;}let absoluteLower=graphie.unscalePoint([paddingPx,graphie.ypixels-paddingPx]);let absoluteUpper=graphie.unscalePoint([graphie.xpixels-paddingPx,paddingPx]);if(snap){absoluteLower=point.ceilTo(absoluteLower,snap);absoluteUpper=point.floorTo(absoluteUpper,snap);}const deltaBounds=this.coords().map(function(coord,i){const max=vector$3.subtract(absoluteUpper,coord);const min=vector$3.subtract(absoluteLower,coord);return [min,max]});const boundedDelta=_.reduce(deltaBounds,function(delta,bound){const lower=bound[0];const upper=bound[1];const deltaX=Math.max(lower[0],Math.min(upper[0],delta[0]));const deltaY=Math.max(lower[1],Math.min(upper[1],delta[1]));return [deltaX,deltaY]},delta);return vector$3.add(prevCoord,boundedDelta)}}};constraints$1.standard=null;const onMove={updatePoints:function(coord,prevCoord){const actualDelta=vector$3.subtract(coord,prevCoord);_.each(this.state.points,function(point){point.setCoord(vector$3.add(point.coord(),actualDelta));});}};onMove.standard=null;var MovableLineOptions = {add:add$1,modify:modify$1,draw:draw$1,remove:remove$1,onMoveStart:{standard:null},constraints:constraints$1,onMove:onMove,onMoveEnd:{standard:null}};
1582
-
1583
- const assert$4=InteractiveUtil.assert;const normalizeOptions$1=InteractiveUtil.normalizeOptions;const DEFAULT_PROPS$1={points:null,static:false,cursor:"move",normalStyle:null,highlightStyle:null,extendLine:false,extendRay:false};const DEFAULT_STATE$1={visibleShape:null,mouseTarget:null};const MovableLine$4=function(graphie,movable,options){assert$4(graphie!=null);assert$4(options!=null);_.extend(this,{graphie:graphie,movable:movable,state:{id:_.uniqueId("movableLine")}});this.modify(_.extend({},DEFAULT_STATE$1,options));};_.extend(MovableLine$4,MovableLineOptions);InteractiveUtil.createGettersFor(MovableLine$4,_.extend({},DEFAULT_PROPS$1,DEFAULT_STATE$1));InteractiveUtil.addMovableHelperMethodsTo(MovableLine$4);_.extend(MovableLine$4.prototype,{cloneState:function(){return _.extend(this.movable.cloneState(),{coords:this.coords()},this.state)},_createDefaultState:function(){return _.extend({id:this.state.id},normalizeOptions$1(pluck(MovableLineOptions,"standard")),DEFAULT_PROPS$1)},modify:function(options){this.update(_.extend(this._createDefaultState(),options));},update:function(options){const self=this;const graphie=this.graphie;const state=self.state=_.extend(self.state,normalizeOptions$1(options));const movableColor=tokenValue(state.static?semanticColor.core.foreground.disabled.strong:semanticColor.core.foreground.instructive.default);state.normalStyle=_.extend({stroke:movableColor,"stroke-width":2},state.normalStyle);state.highlightStyle=_.extend({stroke:movableColor,"stroke-width":3},state.highlightStyle);if(!state.static){if(!state.mouseTarget){const options={thickness:30,mouselayer:true,interactiveKindForTesting:"movable-line"};state.mouseTarget=new WrappedLine(graphie,this.coord(0),this.coord(1),options);state.mouseTarget.attr({fill:"transparent",opacity:0});}}if(state.static&&state.mouseTarget){state.mouseTarget.remove();state.mouseTarget=null;}self.movable.modify(_.extend({},state,{mouseTarget:state.mouseTarget,add:null,modify:null,draw:self.draw.bind(self),remove:null,onMoveStart:function(){self._initialRefCoord=self.coord(0);self._prevRefCoord=self._initialRefCoord;self._totalDelta=[0,0];self._fireEvent(self.state.onMoveStart,self.coord(0),self.coord(0));},onMove:function(mouseCoord,prevMouseCoord){const delta=vector$3.subtract(mouseCoord,prevMouseCoord);self._totalDelta=vector$3.add(self._totalDelta,delta);let refCoord=vector$3.add(self._initialRefCoord,self._totalDelta);refCoord=self._applyConstraints(refCoord,self._prevRefCoord);if(refCoord===false){return}self._fireEvent(self.state.onMove,refCoord,self._prevRefCoord);self._prevRefCoord=refCoord;},onMoveEnd:function(){self._fireEvent(self.state.onMoveEnd,self._prevRefCoord,self._initialRefCoord);}}));if(!state.added){self.prevState={};self._fireEvent(state.add,self.cloneState(),self.prevState);state.added=true;_.invoke(state.points,"listen","onMove",state.id,self.draw.bind(self));self.prevState=self.cloneState();}self._fireEvent(state.modify,self.cloneState(),self.prevState);},coords:function(){return _.invoke(this.state.points,"coord")},point:function(index){return this.state.points[index]},coord:function(index){return this.point(index).coord()},remove:function(){this.state.added=false;this._fireEvent(this.state.remove);if(this.points){_.invoke(this.points,"unlisten","onMove",this.state.id);}if(this.movable){this.movable.remove();}},toBack:function(){this.movable.toBack();if(this.state.visibleShape){this.state.visibleShape.toBack();}},toFront:function(){if(this.state.visibleShape){this.state.visibleShape.toFront();}this.movable.toFront();},isHovering:function(){return this.movable.isHovering()},isDragging:function(){return this.movable.isDragging()},mouseTarget:function(){return this.movable.mouseTarget()}});
1584
-
1585
- const InlineIcon=({path,width,height,style={},title})=>jsxRuntimeExports.jsxs("svg",{role:"img","aria-hidden":!title,style:{verticalAlign:"middle",...style},width:`${width/height}em`,height:"1em",viewBox:`0 0 ${width} ${height}`,children:[!!title&&jsxRuntimeExports.jsx("title",{children:title}),jsxRuntimeExports.jsx("path",{d:path,fill:"currentColor"})]});
1586
-
1587
- const iconCheck={path:`M8.70710678,12.2928932 C8.31658249,11.9023689 7.68341751,11.9023689 7.29289322,12.2928932 C6.90236893,12.6834175 6.90236893,13.3165825 7.29289322,13.7071068 L9.82842712,16.2426407 C10.2207367,16.6349502 10.8574274,16.6328935 11.2471942,16.2380576 L16.7116603,10.7025237 C17.0996535,10.3094846 17.0955629,9.67633279 16.7025237,9.28833966 C16.3094846,8.90034653 15.6763328,8.90443714 15.2883397,9.29747629 L10.5309507,14.1167372 L8.70710678,12.2928932 Z`,width:24,height:24};const iconChevronDown={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",width:100,height:63.034};const iconCircle={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",width:100,height:100};const iconCircleThin={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",width:100,height:99.944};const iconTrash={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",width:91.681,height:100};const iconMinus={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`,width:24,height:24};
1588
-
1589
- const add={constrain:function(){this.constrain();}};add.standard=[add.constrain];const modify={draw:function(){this.draw();}};modify.standard=[modify.draw];const draw={basic:function(state,prevState){const graphie=this.graphie;if(!this.state.visibleShape){const radii=[this.pointSize()/graphie.scale[0],this.pointSize()/graphie.scale[1]];const options={maxScale:Math.max(this.highlightStyle().scale,this.normalStyle().scale),padding:10,shadow:state.shadow};this.state.visibleShape=new WrappedEllipse(graphie,this.coord(),radii,options);this.state.visibleShape.attr(_.omit(this.normalStyle(),"scale"));this.state.visibleShape.toFront();if(this.mouseTarget()){this.mouseTarget().toFront();}}if(state.shadow!==prevState.shadow){this.state.visibleShape.setShadow(state.shadow);}if(state.normalStyle!==prevState.normalStyle&&!_.isEqual(state.normalStyle,prevState.normalStyle)){this.state.visibleShape.attr(this.normalStyle());}this.state.visibleShape.moveTo(this.coord());if(this.mouseTarget()){this.mouseTarget().moveTo(this.coord());}},highlight:function(state,prevState){if(state.isHovering&&!prevState.isHovering){state.visibleShape.animate(this.highlightStyle(),50);}else if(!state.isHovering&&prevState.isHovering){state.visibleShape.animate(this.normalStyle(),50);}}};draw.standard=[draw.basic,draw.highlight];const remove={basic:function(){if(this.state.visibleShape){this.state.visibleShape.remove();this.state.visibleShape=null;}}};remove.standard=remove.basic;const constraints={fixed:function(){return function(){return false}},snap:function(snap){return function(coord){if(snap===null){return true}return point.roundTo(coord,snap||this.graphie.snap)}},bound:function(range,snap,optionalPaddingPx){const paddingPx=(()=>{if(optionalPaddingPx===undefined){if(range===undefined){return 10}else {return 0}}else {return optionalPaddingPx}})();return function(coord,prev,options){const graphie=this.graphie;range=range||graphie.range;if(snap===undefined){snap=graphie.snap;}let lower=graphie.unscalePoint([paddingPx,graphie.ypixels-paddingPx]);let upper=graphie.unscalePoint([graphie.xpixels-paddingPx,paddingPx]);if(snap){lower=point.ceilTo(lower,snap);upper=point.floorTo(upper,snap);}if(!!options&&!!options.onOutOfBounds){if(coord[0]>upper[0]||coord[0]<lower[0]||coord[1]>upper[1]||coord[1]<lower[1]){options.onSkipRemaining();options.onOutOfBounds();}return coord}const coordX=Math.max(lower[0],Math.min(upper[0],coord[0]));const coordY=Math.max(lower[1],Math.min(upper[1],coord[1]));return [coordX,coordY]}}};constraints.standard=null;var MovablePointOptions = {add:add,modify:modify,draw:draw,remove:remove,onMoveStart:{standard:null},constraints:constraints,onMove:{standard:null},onMoveEnd:{standard:null},onClick:{standard:null}};
1590
-
1591
- const assert$3=InteractiveUtil.assert;const normalizeOptions=InteractiveUtil.normalizeOptions;const{processMath}=Tex$1;const DEFAULT_PROPS={coord:[0,0],pointSize:4,static:false,cursor:"move",normalStyle:null,highlightStyle:null,shadow:false,tooltip:false};const DEFAULT_STATE={added:false,hasMoved:false,visibleShape:null,outOfBounds:false,mouseTarget:null,touchOffset:null};const tooltipResetFunctions=[];let MovablePoint$5 = class MovablePoint{modify(options){this.update(_.extend(this._createDefaultState(),options));}_createDefaultState(){return {id:this.state.id,...normalizeOptions(pluck(MovablePointOptions,"standard")),...DEFAULT_PROPS}}cloneState(){return {...this.movable.cloneState(),...this.state}}update(options){const self=this;const graphie=self.graphie;const state=_.extend(self.state,normalizeOptions(options));assert$3(point.is(state.coord));const movableColor=tokenValue(state.static?semanticColor.core.foreground.disabled.strong:semanticColor.core.foreground.instructive.default);state.normalStyle=_.extend({fill:movableColor,stroke:movableColor,scale:1},state.normalStyle);state.highlightStyle=_.extend({fill:movableColor,stroke:movableColor,scale:2},state.highlightStyle);if(!state.static){if(!state.mouseTarget){const center=self.state.coord;const radii=graphie.unscaleVector(24);const options={mouselayer:true,padding:0,interactiveKindForTesting:"movable-point"};state.mouseTarget=new WrappedEllipse(graphie,center,radii,options);state.mouseTarget.attr({fill:"transparent",opacity:0});}}const showTrashTooltip=()=>{this._showTooltip(container=>{render(jsxRuntimeExports.jsx("span",{style:{fontSize:"2em"},children:jsxRuntimeExports.jsx(InlineIcon,{...iconTrash,style:{position:"static",color:movableColor,marginInlineStart:9,marginInlineEnd:9}})}),container);});};let startCoord=state.coord;self.movable.modify(_.extend({},state,{add:null,modify:null,draw:self.draw.bind(self),remove:null,onMoveStart:startMouseCoord=>{state.hasMoved=false;startCoord=state.coord;if(state.touchOffset==null){const isMouse=!("ontouchstart"in window);state.touchOffset=isMouse?[0,0]:vector$3.subtract(startCoord,startMouseCoord);}const svgElem=state.visibleShape.wrapper;if(state.shadow){const filter="none";svgElem.style.filter=filter;}if(state.showHairlines){state.showHairlines(state.coord);}tooltipResetFunctions.forEach(f=>f());if(state.tooltip){if(state.xOnlyTooltip){this._showTooltip(`${state.coord[0]}`);}else {this._showTooltip(`(${state.coord[0]}, ${state.coord[1]})`);}if(state.shadow){const content=svgElem.getElementsByClassName("tooltip-content")[0];const filter=wrappedEllipseShadow;content.style.filter=filter;}}self._fireEvent(state.onMoveStart,startCoord,startCoord);self.draw();},onMove:(mouseCoord,prevMouseCoord)=>{const transformedCoord=vector$3.add(mouseCoord,state.touchOffset);self.moveTo(transformedCoord);if(state.showHairlines){if(!this.state.outOfBounds){state.showHairlines(state.coord);}else {state.hideHairlines();}}if(state.tooltip){if(!this.state.outOfBounds){if(state.xOnlyTooltip){this._showTooltip(`${state.coord[0]}`);}else {this._showTooltip(`(${state.coord[0]}, ${state.coord[1]})`);}}}if(state.onRemove&&this.state.outOfBounds){showTrashTooltip();}},onMoveEnd:()=>{if(self.isHovering()&&!state.hasMoved){self._fireEvent(state.onClick,state.coord,startCoord);}const svgElem=state.visibleShape.wrapper;if(state.shadow){const filter=wrappedEllipseShadow;svgElem.style.filter=filter;}if(state.hideHairlines){state.hideHairlines();}if(state.hasMoved){this._hideTooltip();}else if(state.onRemove){showTrashTooltip();const content=svgElem.getElementsByClassName("tooltip-content")[0];content.style.filter="none";this._tooltip.firstChild.addEventListener("touchstart",e=>{e.stopPropagation();},true);this._tooltip.firstChild.addEventListener("touchend",e=>{state.onRemove();e.stopPropagation();},true);}else if(state.tooltip){this._hideTooltip();}if(state.outOfBounds){state.onRemove();}self._fireEvent(state.onMoveEnd,state.coord,startCoord);state.hasMoved=false;state.touchOffset=null;self.draw();}}));if(!state.added){self.prevState={};self._fireEvent(state.add,self.cloneState(),self.prevState);state.added=true;self.prevState=self.cloneState();}self._fireEvent(state.modify,self.cloneState(),self.prevState);}draw(){const currState=this.cloneState();this._fireEvent(this.state.draw,currState,this.prevState);this.prevState=currState;}constrain(){const result=this._applyConstraints(this.coord(),this.coord());if(point.is(result)){this.setCoord(result);}return result!==false}_fireEvent(listeners,...args){for(const listener of listeners){listener.call(this,...args);}}_applyConstraints(current,previous,extraOptions){let skipRemaining=false;return this.state.constraints.reduce((memo,constraint)=>{if(memo===false){return false}if(skipRemaining){return memo}const result=constraint.call(this,memo,previous,{onSkipRemaining:()=>{skipRemaining=true;},...extraOptions});if(result===false){return false}if(point.is(result,2)){return result}if(result===true||result==null){return memo}throw new PerseusError("Constraint returned invalid result: "+result,Errors.Internal)},current)}_showTooltip(contents){if(!this._tooltip){this._tooltip=document.createElement("div");this._tooltip.className="tooltip-content";this.state.visibleShape.wrapper.className="tooltip";this.state.visibleShape.wrapper.appendChild(this._tooltip);tooltipResetFunctions.push(()=>{if(this.state.added){this._hideTooltip();}});}if(this._tooltip.firstChild){this._tooltip.removeChild(this._tooltip.firstChild);}this.state.visibleShape.wrapper.className="tooltip visible";this._tooltip.appendChild(document.createElement("span"));if(typeof contents==="string"){processMath(this._tooltip.firstChild,contents,false);}else if(typeof contents==="function"){contents(this._tooltip.firstChild);}else {this._tooltip.firstChild.appendChild(contents);}}_hideTooltip(){if(this._tooltip){this.state.visibleShape.wrapper.className="tooltip";}}coord(){return this.state.coord}setCoord(coord){assert$3(point.is(coord,2));this.state.coord=_.clone(coord);this.draw();}setCoordConstrained(coord){assert$3(point.is(coord,2));const result=this._applyConstraints(coord,this.coord());if(result!==false){this.state.coord=_.clone(result);this.draw();}}listen(eventName,id,func){this._listenerMap=this._listenerMap||{};const key=getKey(eventName,id);const index=this._listenerMap[key]=this._listenerMap[key]||this.state[eventName].length;this.state[eventName][index]=func;}unlisten(eventName,id){this._listenerMap=this._listenerMap||{};const key=getKey(eventName,id);const index=this._listenerMap[key];if(index!==undefined){this.state[eventName].splice(index,1);delete this._listenerMap[key];const keys=Object.keys(this._listenerMap);_.each(keys,key=>{if(getEventName(key)===eventName&&this._listenerMap[key]>index){this._listenerMap[key]--;}},this);}}grab(coord){this.state.touchOffset=[0,0];this.movable.grab(coord);this.moveTo(coord);}moveTo(coord){const state=this.state;this.state.outOfBounds=false;const result=this._applyConstraints(coord,state.coord,state.onRemove?{onOutOfBounds:()=>{this.state.outOfBounds=true;},onSkipRemaining:()=>{}}:{onSkipRemaining:()=>{}});if(result===false){return}if(point.is(result)){coord=result;}if(!point.equal(coord,state.coord)){const prevCoord=state.coord;state.coord=coord;state.hasMoved=true;this._fireEvent(state.onMove,state.coord,prevCoord);this.draw();}}remove(){this.state.added=false;this._fireEvent(this.state.remove);if(this.movable){this.movable.remove();}this.state.mouseTarget=null;}pointSize(){return this.state.pointSize}static(){return this.state.static}cursor(){return this.state.cursor}normalStyle(){return this.state.normalStyle}highlightStyle(){return this.state.highlightStyle}shadow(){return this.state.shadow}tooltip(){return this.state.tooltip}added(){return this.state.added}hasMoved(){return this.state.hasMoved}visibleShape(){return this.state.visibleShape}outOfBounds(){return this.state.outOfBounds}mouseTarget(){return this.state.mouseTarget}touchOffset(){return this.state.touchOffset}isHovering(){return this.movable.isHovering()}isDragging(){return this.movable.isDragging()}toBack(){this.movable.toBack();if(this.state.visibleShape){this.state.visibleShape.toBack();}}toFront(){if(this.state.visibleShape){this.state.visibleShape.toFront();}this.movable.toFront();}constructor(graphie,movable,options){this._listenerMap={};this.graphie=graphie;this.movable=movable;this.state={id:_.uniqueId("movablePoint")};this.modify({...DEFAULT_STATE,...options});}};MovablePoint$5.add=MovablePointOptions.add;MovablePoint$5.modify=MovablePointOptions.modify;MovablePoint$5.draw=MovablePointOptions.draw;MovablePoint$5.remove=MovablePointOptions.remove;MovablePoint$5.onMoveStart=MovablePointOptions.onMoveStart;MovablePoint$5.constraints=MovablePointOptions.constraints;MovablePoint$5.onMove=MovablePointOptions.onMove;MovablePoint$5.onMoveEnd=MovablePointOptions.onMoveEnd;MovablePoint$5.onClick=MovablePointOptions.onClick;function getKey(eventName,id){return eventName+":"+id}function getEventName(key){return key.split(":")[0]}
1592
-
1593
- const Interactive2={MovablePoint:MovablePoint$5,addMovablePoint:function(graphie,options){const movable=new Movable(graphie,{});return new MovablePoint$5(graphie,movable,options)},MovableLine:MovableLine$4,addMovableLine:function(graphie,options){const movable=new Movable(graphie,{});return new MovableLine$4(graphie,movable,options)},addMovablePointV2:function(widget,extraProps){const commonStyle={stroke:tokenValue(semanticColor.core.border.knockout.default),"stroke-width":3,fill:tokenValue(semanticColor.core.foreground.instructive.default)};const normalStyle=Object.assign(commonStyle,extraProps.normalStyle);const highlightStyle=Object.assign({...commonStyle,"stroke-width":2,scale:.75},extraProps.highlightStyle);const props=Object.assign({normalStyle:normalStyle,highlightStyle:highlightStyle,shadow:true,tooltip:widget.props.showTooltips,showHairlines:widget.showHairlines,hideHairlines:widget.hideHairlines},{pointSize:7});return Interactive2.addMovablePoint(widget.graphie,Object.assign(extraProps,props))}};
1594
-
1595
- const MovablePoint$4=GraphieClasses.createClass({displayName:"MovablePoint",movableProps:["children"],_getProps:function(){if(!this.props.isMobile||this.props.static){return this.props}const interactiveColor=tokenValue(semanticColor.core.foreground.instructive.default);const commonStyle={stroke:tokenValue(semanticColor.core.foreground.knockout.default),"stroke-width":3,fill:interactiveColor};return Object.assign(this.props,{normalStyle:{...commonStyle,...this.props.mobileStyleOverride||{}},highlightStyle:{...commonStyle,"stroke-width":0,scale:.75,...this.props.mobileStyleOverride||{}},shadow:this.props.shadow??true,tooltip:this.props.showTooltips,pointSize:7})},add:function(graphie){this.point=Interactive2.addMovablePoint(graphie,this._getProps());},modify:function(){this.point.modify(this._getProps());},remove:function(){this.point.remove();},toFront:function(){this.point.toFront();},grab:function(coord){this.point.grab(coord);}});_.extend(MovablePoint$4,Interactive2.MovablePoint);const MovableLine$3=GraphieClasses.createClass({displayName:"MovableLine",movableProps:["children"],add:function(graphie){const points=_.pluck(this.props.children,"point");const props=_.extend({},this.props,{points:points});this.line=Interactive2.addMovableLine(graphie,props);},modify:function(){const points=_.pluck(this.props.children,"point");const props=_.extend({},this.props,{points:points});this.line.modify(props);},remove:function(){this.line.remove();},toFront:function(){this.line.toFront();}});_.extend(MovableLine$3,Interactive2.MovableLine);const Label$1=GraphieClasses.createSimpleClass((graphie,props)=>{let coord=props.coord;if(props.unscaled){coord=graphie.unscalePoint(coord);}let elem;if(getDependencies().JIPT.useJIPT){elem=graphie.label(coord,props.text,props.direction,false,props.style);getDependencies().graphieMovablesJiptLabels.addLabel(elem,props.tex);}else {elem=graphie.label(coord,props.text,props.direction,props.tex,props.style);}return elem});const Line$3=GraphieClasses.createClass({displayName:"Line",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.line=this.graphie.line(props.start,props.end,props.style);},modify:function(){const props=this.props;this.line.remove();this.line=this.graphie.line(props.start,props.end,props.style);},remove:function(){this.line.remove();},toFront:function(){this.line.toFront();}});const Parabola=GraphieClasses.createClass({displayName:"Parabola",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.parabola=this.graphie.parabola(props.a,props.b,props.c,props.style);},modify:function(){const props=this.props;const path=this.graphie.svgParabolaPath(props.a,props.b,props.c);this.parabola.attr(_.extend({},props.style,{path:path}));},remove:function(){this.parabola.remove();},toFront:function(){this.parabola.toFront();}});const Sinusoid=GraphieClasses.createClass({displayName:"Sinusoid",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.sinusoid=this.graphie.sinusoid(props.a,props.b,props.c,props.d,props.style);},modify:function(){const props=this.props;const path=this.graphie.svgSinusoidPath(props.a,props.b,props.c,props.d);this.sinusoid.attr(_.extend({},props.style,{path:path}));},remove:function(){this.sinusoid.remove();},toFront:function(){this.sinusoid.toFront();}});const Plot$1=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.plot(props.fn,props.range,props.style)});const PlotParametric$1=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.plotParametric(props.fn,props.range,props.style)});const Point$1=GraphieClasses.createSimpleClass((graphie,props)=>{const neutralColor=tokenValue(semanticColor.core.foreground.neutral.strong);return graphie.ellipse(props.coord,graphie.unscaleVector([4,4]),{fill:props.color||neutralColor,stroke:props.color||neutralColor})});const Path=GraphieClasses.createClass({displayName:"Path",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.path=this.graphie.path(props.coords,props.style);},modify:function(){const props=this.props;const path=this.graphie.svgPath(props.coords);this.path.attr({path:path});},remove:function(){this.path.remove();},toFront:function(){this.path.toFront();}});const Arc$1=GraphieClasses.createSimpleClass((graphie,props)=>{let center=props.center;let radius=props.radius;if(props.unscaled){center=graphie.unscalePoint(center);radius=graphie.unscaleVector(radius);}return graphie.arc(center,radius,props.startAngle,props.endAngle,props.sector,props.style)});const Circle=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.circle(props.center,props.radius,props.style)});const Rect$1=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.rect(props.x,props.y,props.width,props.height,props.style)});var Movables = {Arc:Arc$1,Circle:Circle,Label:Label$1,Line:Line$3,MovableLine:MovableLine$3,MovablePoint:MovablePoint$4,Parabola:Parabola,Path:Path,Plot:Plot$1,PlotParametric:PlotParametric$1,Point:Point$1,Sinusoid:Sinusoid,Rect:Rect$1};
1596
-
1597
- const GraphieMovable=GraphieClasses.GraphieMovable;const createGraphie=GraphUtils.createGraphie;const{nestedMap}=Util;const{assert: assert$2}=InteractiveUtil;class Graphie extends React.Component{componentDidMount(){this._setupGraphie();this._updateMovables();}shouldComponentUpdate(nextProps){return !_.isEqual(this.props,nextProps)}componentDidUpdate(prevProps){if(this.props.setup!==prevProps.setup){Log.error("<Graphie> was given a new setup function. "+"This is a bad idea; please refactor your code to give "+"the same setup function reference to <Graphie> on "+"every render.",Errors.Internal);}if(!approximateDeepEqual(this.props.options,prevProps.options)||!approximateDeepEqual(this.props.box,prevProps.box)||!approximateDeepEqual(this.props.range,prevProps.range)){this._setupGraphie();}this._updateMovables();}componentWillUnmount(){this._removeMovables();this._graphie.cleanup();}render(){return jsxRuntimeExports.jsx("div",{className:"graphie-container",children:jsxRuntimeExports.jsx("div",{className:"graphie",ref:this.graphieDivRef})})}constructor(...args){super(...args),this.graphieDivRef=React.createRef(),this._graphie=new Graphie$1(document.createElement("div")),this._movables={},this.movables={},this.getGraphie=()=>{return this._graphie},this._range=()=>{const boundsCheckRange=range=>{if(range[0]>=range[1]){return [-10,10]}return range};return [boundsCheckRange(this.props.range[0]),boundsCheckRange(this.props.range[1])]},this._box=()=>{const ensureMinSize=pixelDim=>{return pixelDim>0?pixelDim:340};return [ensureMinSize(this.props.box[0]),ensureMinSize(this.props.box[1])]},this._scale=()=>{const box=this._box();const range=this._range();return box.map((pixelDim,i)=>{const unitDim=range[i][1]-range[i][0];return pixelDim/unitDim})},this._setupGraphie=()=>{this._graphie.cleanup();this._removeMovables();const graphieDiv=this.graphieDivRef.current;if(graphieDiv==null||graphieDiv instanceof Text){throw new Error("No graphie container div found")}graphieDiv.innerHTML="";const graphie=this._graphie=createGraphie(graphieDiv);graphie.init({range:this._range(),scale:this._scale(),isMobile:this.props.isMobile});if(this.props.addMouseLayer){graphie.addMouseLayer({onClick:this.props.onClick,onMouseDown:this.props.onMouseDown,onMouseMove:this.props.onMouseMove});}graphie.snap=this.props.options.snapStep||[1,1];if(this.props.responsive){graphieDiv.style.width="100%";graphieDiv.style.height="100%";graphie.raphael.setSize("100%","100%");}this.props.setup(graphie,_.extend({range:this._range(),scale:this._scale()},this.props.options));},this._removeMovables=()=>{_.invoke(this._movables,"remove");this._movables={};},this._renderMovables=(children,options)=>{const graphie=options.graphie;const oldMovables=options.oldMovables;const newMovables=options.newMovables;const renderChildren=elem=>{_.each(elem.movableProps,prop=>{elem.props[prop]=this._renderMovables(elem.props[prop],options);});};let areMovablesOutOfOrder=false;return nestedMap(children,childDescriptor=>{if(!childDescriptor){options.nextKey++;return childDescriptor}const child=new childDescriptor.type(childDescriptor.props);assert$2(child instanceof GraphieMovable,"All children of a Graphie component must be Graphie "+"movables");const keyProp=childDescriptor.key;const key=keyProp==null?"_no_id_"+options.nextKey:keyProp;options.nextKey++;const ref=childDescriptor.ref;renderChildren(child);const prevMovable=oldMovables[key];if(!prevMovable){child.add(graphie);areMovablesOutOfOrder=true;newMovables[key]=child;}else if(child.constructor===prevMovable.constructor){prevMovable.props=child.props;const modifyResult=prevMovable.modify(graphie);if(modifyResult==="reordered"){areMovablesOutOfOrder=true;}newMovables[key]=prevMovable;}else {if(keyProp==null){Log.error("Replacing a <Graphie> child with a "+"child of a different type. Please add keys "+"to your <Graphie> children",Errors.Internal);}prevMovable.remove();child.add(graphie);areMovablesOutOfOrder=true;newMovables[key]=child;}if(areMovablesOutOfOrder){newMovables[key].toFront();}if(ref){this.movables[ref]=newMovables[key];}return newMovables[key]})},this._updateMovables=()=>{const graphie=this._graphie;const oldMovables=this._movables;const newMovables={};this._movables=newMovables;this.movables={};this._renderMovables(this.props.children,{nextKey:1,graphie:graphie,oldMovables:oldMovables,newMovables:newMovables});_.each(oldMovables,(oldMovable,key)=>{if(!newMovables[key]){oldMovable.remove();}});};}}Graphie.defaultProps={range:[[-10,10],[-10,10]],options:{},responsive:false,addMouseLayer:true};_.extend(Graphie,GraphieClasses);_.extend(Graphie,Movables);
1598
-
1599
- function withDependencies(WrappedComponent){const WithDependenciesComponent=React__default.forwardRef((props,ref)=>{const dependencies=useDependencies();return jsxRuntimeExports.jsx(WrappedComponent,{...props,dependencies:dependencies,ref:ref})});WithDependenciesComponent.displayName=`withDependencies(${WrappedComponent.displayName||WrappedComponent.name||"Component"})`;return WithDependenciesComponent}
1600
-
1601
- const Status={PENDING:"pending",LOADING:"loading",LOADED:"loaded",FAILED:"failed"};class ImageLoader extends React.Component{componentDidMount(){if(this.state.status===Status.LOADING){this.createLoader();}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.src!==nextProps.src){this.setState({status:nextProps.src?Status.LOADING:Status.PENDING});}}componentDidUpdate(prevProps,prevState){if(this.state.status===Status.LOADING&&!this.img){this.createLoader();}if(prevState.status!==this.state.status){this.props.onUpdate(this.state.status);}}componentWillUnmount(){this.destroyLoader();}render(){switch(this.state.status){case Status.LOADED:return this.renderImg();case Status.FAILED:if(this.props.children){return this.props.children}break;default:if(this.props.preloader){return this.props.preloader()}}return null}constructor(props){super(props),this.createLoader=()=>{this.destroyLoader();this.img=new Image;this.img.onload=this.handleLoad;this.img.onerror=this.handleError;this.img.src=this.props.src;},this.destroyLoader=()=>{if(this.img){this.img.onload=null;this.img.onerror=null;this.img=null;}},this.handleLoad=event=>{this.destroyLoader();this.setState({status:Status.LOADED});if(this.props.onLoad){this.props.onLoad(event);}},this.handleError=error=>{this.destroyLoader();this.setState({status:Status.FAILED});if(this.props.onError){this.props.onError(error);}},this.renderImg=()=>{const{src,imgProps}=this.props;const{alt,title,...restImgProps}=imgProps;return jsxRuntimeExports.jsx("img",{alt:alt,title:title,className:"image-loader-img",src:this.props.dependencies.generateUrl({url:src,context:"image_loader:image_url"}),style:{display:"block",...imgProps.style??{width:"100%"}},...restImgProps})};this.state={status:props.src?Status.LOADING:Status.PENDING};}}var ImageLoader$1 = withDependencies(ImageLoader);
1602
-
1603
- function isGif(url){return url.endsWith(".gif")}async function decodeGifFrames(src){const res=await fetch(src);if(!res.ok){return []}const buffer=await res.arrayBuffer();const gif=parseGIF(buffer);return decompressFrames(gif,true)}function isSvg(url){const hasSvgExtension=url.endsWith(".svg");const hasGraphieUrl=isLabeledSVG(url);return hasSvgExtension||hasGraphieUrl}
1604
-
1605
- var styles$B = {"contentWrapper":"perseus_NqTCZY3N","imageContainer":"perseus_Ctn3miye"};
1606
-
1607
- const WB_MODAL_PADDING_TOTAL=64;const ZoomedImageView=props=>{const i18n=usePerseusI18n();const{initialFocusId,onClose,...svgProps}=props;const width=props.width;const height=props.height;const contentScale=props.scale;const imageIsSvg=isSvg(props.src);const scale=imageIsSvg?Math.max(contentScale,2):Math.max(contentScale,1);const maxAvailableWidth=window.innerWidth-WB_MODAL_PADDING_TOTAL;const maxAvailableHeight=window.innerHeight-WB_MODAL_PADDING_TOTAL;const scaleWidth=maxAvailableWidth/(width*scale);const scaleHeight=maxAvailableHeight/(height*scale);const fitRatio=Math.min(scaleWidth,scaleHeight,1);const constrainedDisplayWidth=width*fitRatio*scale;return jsxRuntimeExports.jsx(ModalDialog,{"aria-labelledby":"",style:wbStyles$2.dialog,children:jsxRuntimeExports.jsx(ModalPanel,{closeButtonVisible:false,content:jsxRuntimeExports.jsxs("div",{className:styles$B.contentWrapper,children:[jsxRuntimeExports.jsx("div",{className:styles$B.imageContainer,style:{width:constrainedDisplayWidth},children:jsxRuntimeExports.jsx("div",{className:"framework-perseus",tabIndex:0,id:initialFocusId,children:jsxRuntimeExports.jsx(SvgImage,{...svgProps,allowZoom:false,width:width,height:height,scale:scale})})}),jsxRuntimeExports.jsx(IconButton,{icon:closeIcon,onClick:onClose,"aria-label":i18n.strings.imageResetZoomAriaLabel,kind:"primary",style:wbStyles$2.closeButton})]})})})};const wbStyles$2=StyleSheet.create({dialog:{width:"auto",height:"auto",margin:sizing.size_320,"@media (max-width: 767px)":{margin:0}},closeButton:{position:"absolute",insetBlockStart:border$1.width.medium,insetInlineEnd:border$1.width.medium,opacity:0,":hover":{opacity:1},":focus":{opacity:1}}});
1608
-
1609
- const ZoomImageButton=props=>{const{imgSrc}=props;const i18n=usePerseusI18n();const uniqueId=React.useId().replace(/:/g,"");const zoomedImageUniqueId=`zoomed-image-${uniqueId}`;const handleClick=(event,openModal)=>{const mouseEvent=event;if(mouseEvent.metaKey||mouseEvent.ctrlKey){window.open(imgSrc,"_blank");}else {openModal();}};return jsxRuntimeExports.jsx(ModalLauncher,{initialFocusId:zoomedImageUniqueId,modal:({closeModal})=>jsxRuntimeExports.jsx(ZoomedImageView,{...props,initialFocusId:zoomedImageUniqueId,onClose:closeModal}),children:({openModal})=>jsxRuntimeExports.jsx(Clickable,{"aria-label":i18n.strings.imageZoomAriaLabel,onClick:event=>handleClick(event,openModal),style:{position:"absolute",width:"100%",height:"100%",overflow:"hidden",cursor:"zoom-in"},children:()=>{return jsxRuntimeExports.jsx(React.Fragment,{})}})})};
1610
-
1611
- function isImageProbablyPhotograph(imageUrl){return /\.(jpg|jpeg)$/i.test(imageUrl)}function spinner(){return jsxRuntimeExports.jsx("span",{style:{insetBlockStart:0,insetInlineStart:0,width:"100%",height:"100%",position:"absolute",minInlineSize:"20px",display:"flex",justifyContent:"center",alignContent:"center"},children:jsxRuntimeExports.jsx(CircularSpinner,{size:"medium"})})}class SvgImage extends React.Component{componentDidMount(){this._isMounted=true;if(Util.isLabeledSVG(this.props.src)){this.loadResources();}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.src!==nextProps.src){this._isLoadingGraphie=false;this.setState({imageLoaded:false,dataLoaded:false});}}shouldComponentUpdate(nextProps,nextState){if(!_.isEqual(this.props,nextProps)){return true}const wasLoaded=this.isLoadedInState(this.state);const nextLoaded=this.isLoadedInState(nextState);return wasLoaded!==nextLoaded}componentDidUpdate(prevProps,prevState){const wasLoaded=this.isLoadedInState(prevState);const isLoaded=this.isLoadedInState(this.state);if(Util.isLabeledSVG(this.props.src)&&!this.state.dataLoaded&&!this._isLoadingGraphie){this.loadResources();}if(!wasLoaded&&isLoaded){this.props.setAssetStatus(this.props.src,true);}}componentWillUnmount(){this._isMounted=false;}isLoadedInState(state){return Util.isLabeledSVG(this.props.src)?state.imageLoaded&&state.dataLoaded:state.imageLoaded}loadResources(){this._isLoadingGraphie=true;loadGraphie(this.props.src,(data,localized)=>{this._isLoadingGraphie=false;if(this._isMounted&&data.labels&&data.range){const labelsRendered={};data.labels.forEach(label=>{labelsRendered[label.content]=false;});this.setState({dataLoaded:true,labelDataIsLocalized:localized,labelsRendered,labels:data.labels,range:data.range});}});}sizeProvided(){return this.props.width!=null&&this.props.height!=null}_tryGetPixels(value){value=value||"";if(!value.endsWith("px")){return null}return parseFloat(value)||null}render(){const imageSrc=this.props.src;const imageProps={alt:this.props.alt,title:this.props.title};const width=this.props.width&&this.props.width*this.props.scale;const height=this.props.height&&this.props.height*this.props.scale;const dimensions={width,height};const responsive=this.props.responsive&&!!(width&&height);let extraGraphie;if(this.props.extraGraphie&&this.props.extraGraphie.labels.length){extraGraphie=jsxRuntimeExports.jsx(Graphie,{box:this.props.extraGraphie.box,range:this.props.extraGraphie.range,options:{labels:this.props.extraGraphie.labels},responsive:true,addMouseLayer:false,setup:this.setupGraphie});}if(!Util.isLabeledSVG(imageSrc)){if(responsive){const isGifControlled=this.props.isGifPlaying!==undefined;const imageContent=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[!isGifControlled&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageSrc,imgProps:imageProps,preloader:spinner,onUpdate:this.handleUpdate}),extraGraphie]}),isGifControlled&&jsxRuntimeExports.jsx(GifImage,{alt:this.props.alt,width:this.props.width,height:this.props.height,scale:this.props.scale,isPlaying:!!this.props.isGifPlaying,onLoop:this.props.onGifLoop??(()=>{}),onLoad:()=>{this.onImageLoad();},gifFrames:this.props.gifFrames})]});return jsxRuntimeExports.jsxs(FixedToResponsive,{className:"svg-image",width:width,height:height,constrainHeight:this.props.constrainHeight,allowFullBleed:this.props.allowFullBleed&&isImageProbablyPhotograph(imageSrc),scale:this.props.scale,children:[imageContent,this.props.allowZoom&&jsxRuntimeExports.jsx(ZoomImageButton,{...this.props,imgSrc:imageSrc,width:this.props.width,height:this.props.height})]})}imageProps.style=dimensions;return jsxRuntimeExports.jsx(ImageLoader$1,{src:imageSrc,preloader:spinner,imgProps:imageProps,onUpdate:this.handleUpdate})}const imageUrl=Util.getSvgUrl(imageSrc);let graphie;if(this.isLoadedInState(this.state)){let box;if(this.sizeProvided()){box=[width,height];}else if(this.state.imageDimensions){box=[this.state.imageDimensions[0]*this.props.scale,this.state.imageDimensions[1]*this.props.scale];}else {throw new PerseusError("svg-image has no dimensions",Errors.InvalidInput,{metadata:{src:this.props.src}})}graphie=jsxRuntimeExports.jsx(Graphie,{ref:"graphie",box:box,scale:[40*this.props.scale,40*this.props.scale],range:this.state.range,options:_.pick(this.state,"labels"),responsive:responsive,addMouseLayer:false,setup:this.setupGraphie});}if(responsive){const imageContent=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageUrl,onLoad:this.onImageLoad,onUpdate:this.handleUpdate,preloader:spinner,imgProps:imageProps}),graphie,extraGraphie]});return jsxRuntimeExports.jsxs(FixedToResponsive,{className:"svg-image",width:width,height:height,constrainHeight:this.props.constrainHeight,scale:this.props.scale,children:[imageContent,this.props.allowZoom&&jsxRuntimeExports.jsx(ZoomImageButton,{...this.props,imgSrc:imageUrl,width:this.props.width,height:this.props.height})]})}imageProps.style=dimensions;return jsxRuntimeExports.jsxs("div",{className:"unresponsive-svg-image",style:dimensions,children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageUrl,onLoad:this.onImageLoad,onUpdate:this.handleUpdate,preloader:spinner,imgProps:imageProps}),graphie]})}constructor(props){super(props),this.onImageLoad=()=>{if(this.sizeProvided()){this.setState({imageLoaded:true});}else {Util.getImageSize(this.props.src,(width,height)=>{if(this._isMounted){this.setState({imageLoaded:true,imageDimensions:[width,height]});}});}},this.setupGraphie=(graphie,options)=>{const newLabelsRendered={};_.map(options.labels,labelData=>{const{JIPT}=getDependencies();if(JIPT.useJIPT&&this.state.labelDataIsLocalized){const elem=graphie.label(labelData.coordinates,labelData.content,labelData.alignment,false);getDependencies().svgImageJiptLabels.addLabel(elem,labelData.typesetAsMath);}else if(labelData.coordinates){const styling=this.props.scale!==1?{"font-size":100*this.props.scale+"%"}:null;const label=graphie.label(labelData.coordinates,labelData.content,labelData.alignment,labelData.typesetAsMath,styling);const labelStyle=label[0].style;let labelTop=this._tryGetPixels(labelStyle.top);let labelLeft=this._tryGetPixels(labelStyle.left);if(labelTop===null||labelLeft===null){const labelPosition=label.position();labelTop=labelPosition.top;labelLeft=labelPosition.left;}const svgHeight=(this.props.height||0)*this.props.scale;const svgWidth=(this.props.width||0)*this.props.scale;label.css({top:labelTop/svgHeight*100+"%",left:labelLeft/svgWidth*100+"%"});_.each(labelData.style,(styleValue,styleName)=>{label.css(styleName,styleValue);});if(labelData.style?.color){label.css("color",toClosestMathColor(labelData.style.color));}}newLabelsRendered[labelData.content]=true;});this.setState(prev=>({labelsRendered:{...prev.labelsRendered,...newLabelsRendered}}));},this.handleUpdate=status=>{this.props.onUpdate();if(!Util.isLabeledSVG(this.props.src)&&status==="loaded"){this.setState({imageLoaded:true});}};props.setAssetStatus(props.src,false);this._isMounted=false;this._isLoadingGraphie=false;this.state={imageLoaded:false,imageDimensions:null,dataLoaded:false,labelDataIsLocalized:false,labels:[],labelsRendered:{},range:[[0,0],[0,0]]};}}SvgImage.contextType=PerseusI18nContext;SvgImage.defaultProps={constrainHeight:false,onUpdate:()=>{},responsive:true,src:"",scale:1,setAssetStatus:(src,status)=>{}};
1612
-
1613
- class Tex extends React.Component{render(){const{TeX:BaseTeX}=getDependencies();return jsxRuntimeExports.jsx(BaseTeX,{onRender:this.handleRender,children:this.props.children})}constructor(props){super(props),this.handleRender=()=>{this.setState({rendered:true});this.props.onRender();if(!this._hasRendered){this._hasRendered=true;this.props.setAssetStatus(this.props.children,true);}};this.props.setAssetStatus(this.props.children,false);this.state={rendered:false};this._hasRendered=false;}}Tex.defaultProps={onRender:()=>{},setAssetStatus:(src,status)=>{}};
1614
-
1615
- function getCSSZoomFactor(element){let zoomFactor=1;let currentElement=element;while(currentElement){const computedStyle=window.getComputedStyle(currentElement);const elementZoom=parseFloat(computedStyle.zoom);zoomFactor=isNaN(elementZoom)?zoomFactor:zoomFactor*elementZoom;currentElement=currentElement.parentElement;}return zoomFactor}
1616
-
1617
- const ENTRANCE_TRANSITION_DURATION_MS=300;let assetKeyCounter=0;class Zoomable extends React.Component{componentDidMount(){this._isMounted=true;this.maybeInitializeMeasuring();}componentDidUpdate(){this.maybeInitializeMeasuring();if(this.state.visible){this.markSettledWhenVisible();}}componentWillUnmount(){window.removeEventListener("resize",this.reset);this._observer?.disconnect();this._isMounted=false;}markSettledWhenVisible(){if(this._didLaunchEntranceAnimation){return}const duration=this.props.disableEntranceAnimation?0:ENTRANCE_TRANSITION_DURATION_MS;this.props.schedule.timeout(()=>{this.context.setAssetStatus(this._assetKey,true);},duration);this._didLaunchEntranceAnimation=true;}maybeInitializeMeasuring(){const shouldInitialize=this.props.readyToMeasure&&!this._measuringInitialized;if(this._isMounted&&shouldInitialize){this._measuringInitialized=true;this._node=ReactDOM__default.findDOMNode(this);setTimeout(()=>this.measureAndScaleChildToFit(false),0);if(window.MutationObserver){this._observer=new MutationObserver(mutations=>{if(this._isMounted){for(const mutation of mutations){if(mutation.target!==this._node){this.measureAndScaleChildToFit(this.state.zoomed);break}}}});this._observer.observe(this._node,{childList:true,subtree:true,attributes:true});}window.addEventListener("resize",this.reset);}}measureAndScaleChildToFit(zoomed){if(!this._isMounted){return}let parentNode=this._node;let currentNode=parentNode;while(currentNode&&currentNode.offsetWidth===0){currentNode=currentNode.parentElement?.closest(".perseus-renderer")??null;}if(currentNode){parentNode=currentNode;}const parentBounds={width:parentNode.offsetWidth,height:parentNode.offsetHeight};const childBounds=this.props.computeChildBounds(this._node,parentBounds);const childWidth=childBounds.width+1;const childHeight=childBounds.height+1;const availableWidth=parentBounds.width*getCSSZoomFactor(this._node);if(childWidth>availableWidth){const scale=availableWidth/childWidth;this.setState({scale,zoomed,compactHeight:Math.ceil(scale*childHeight),expandedHeight:childHeight});setTimeout(()=>{if(this._isMounted){this.setState({visible:true});}});}else {this.setState({visible:true});}}render(){const{visible,scale,compactHeight,expandedHeight,zoomed}=this.state;const{animateHeight,disableEntranceAnimation}=this.props;const property=animateHeight?"opacity transform height":"opacity transform";const transitionStyle=visible?{transitionProperty:property,transitionDuration:`${ENTRANCE_TRANSITION_DURATION_MS}ms`,transitionTimingFunction:"ease-out"}:{};const shouldSlide=!disableEntranceAnimation&&!visible;const translateOffset=shouldSlide?" translate(0, 8px)":"";const opacity=shouldSlide?0:1;const scaleString=(scale??1).toString();const transform=zoomed?`scale(1, 1) ${translateOffset}`:`scale(${scaleString}, ${scaleString}) ${translateOffset}`;const style={display:"block",width:"100%",height:zoomed?expandedHeight:compactHeight,transform:transform,transformOrigin:"0 0",opacity:opacity,WebkitTapHighlightColor:"transparent",...transitionStyle};return jsxRuntimeExports.jsx("span",{onClick:this.handleClick,onClickCapture:this.handleClickIfZoomed,onTouchCancelCapture:this.stopPropagationIfZoomed,onTouchEndCapture:this.stopPropagationIfZoomed,onTouchStartCapture:this.stopPropagationIfZoomed,style:style,children:this.props.children})}constructor(props,context){super(props,context),this._didLaunchEntranceAnimation=false,this.state={visible:false,marginBottomPx:0,zoomed:true},this.reset=()=>{if(!this._isMounted){return}if(!this.state.visible){return}this._originalWidth=null;this.setState({visible:false,compactHeight:null,expandedHeight:null,zoomed:true},()=>{this.measureAndScaleChildToFit(false);});},this.stopPropagationIfZoomed=e=>{if(!this.state.zoomed){e.stopPropagation();}},this.handleClickIfZoomed=e=>{if(!this.state.zoomed){e.stopPropagation();this.handleClick();}},this.handleClick=()=>{this.setState({zoomed:!this.state.zoomed});};assetKeyCounter+=1;this._assetKey=`zoomable-${assetKeyCounter}`;context.setAssetStatus(this._assetKey,false);}}Zoomable.contextType=context;Zoomable.defaultProps={animateHeight:false,readyToMeasure:true,disableEntranceAnimation:false,computeChildBounds:parentNode=>{const firstChild=parentNode.firstElementChild;return {width:firstChild.offsetWidth,height:firstChild.offsetHeight}}};var Zoomable$1 = withActionScheduler(Zoomable);
1618
-
1619
- const computeMathBounds=(parentNode,parentBounds)=>{const textElement=parentNode.querySelector(".MathJax");const textElementHeight=Array.from(textElement?.children??[]).reduce((maxHeight,child)=>Math.max(maxHeight,child.offsetHeight),textElement?.offsetHeight??0);const textBounds={width:textElement?.offsetWidth,height:textElementHeight};const hiddenAncestor=parentNode.closest(`[aria-hidden="true"]`);const height=hiddenAncestor?.getBoundingClientRect().width===0?textBounds.height:Math.max(parentBounds.height,textBounds.height);return {width:Math.max(parentBounds.width,textBounds.width),height:height}};class ZoomableTeX extends React.Component{render(){return jsxRuntimeExports.jsx(Zoomable$1,{readyToMeasure:this.state.isRendered,computeChildBounds:computeMathBounds,animateHeight:false,disableEntranceAnimation:true,children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{onRender:this.handleRender,setAssetStatus:setAssetStatus,children:this.props.children})})})}constructor(){super(),this.handleRender=()=>{this.setState({isRendered:true});};this.state={isRendered:false};}}
1620
-
1621
- const defaultContext={activeDefinitionId:null,setActiveDefinitionId:()=>{}};const DefinitionContext=React.createContext(defaultContext);class DefinitionProvider extends React.Component{render(){const{children}=this.props;const{activeDefinitionId}=this.state;const{setActiveDefinitionId}=this;return jsxRuntimeExports.jsx(DefinitionContext.Provider,{value:{activeDefinitionId,setActiveDefinitionId},children:children})}constructor(...args){super(...args),this.state={activeDefinitionId:null},this.setActiveDefinitionId=activeDefinitionId=>{this.setState(prevState=>({activeDefinitionId}));};}}const DefinitionConsumer=DefinitionContext.Consumer;
1622
-
1623
- class ErrorBoundary extends React.Component{componentDidCatch(error,info){this.setState({error:error.toString()});this.props.onError?.(error,info);Log.error("Unhandled Perseus error: "+error.message,Errors.Internal,{cause:error,loggedMetadata:{componentStack:!!info&&"componentStack"in info?info.componentStack:"componentStack not provided",...this.props.metadata}});}render(){if(this.state.error){return jsxRuntimeExports.jsxs("svg",{height:"16",width:"16",viewBox:"0 0 16 16",role:"img",children:[jsxRuntimeExports.jsx("title",{children:"Rendering Error!"}),jsxRuntimeExports.jsx("path",{d:"m8 16c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm0-3c0.55 0 1-0.45 1-1s-0.45-1-1-1-1 0.45-1 1 0.45 1 1 1zm0-9c-0.55 0-1 0.45-1 1v4c0 0.55.45 1 1 1s1-0.45 1-1v-4c0-0.55-0.45-1-1-1z",fill:semanticColor.core.foreground.critical.default,fillRule:"evenodd"})]})}return this.props.children}constructor(props){super(props);this.state={error:""};}}
1624
-
1625
- function _noop(){}class InteractionTracker{constructor(trackApi,widgetType,widgetID,setting){this._track=extraData=>{if(this._tracked&&!this.setting){return}this._tracked=true;this.trackApi({type:this.widgetType,id:this.widgetID,...extraData});};if(!trackApi){this.track=_noop;}else {this._tracked=false;this.trackApi=trackApi;this.widgetType=widgetType;this.widgetID=widgetID;this.setting=setting;this.track=this._track;}}}
1626
-
1627
- const arrayRules={fence:{match:SimpleMarkdown.defaultRules.fence.match,order:1,parse:(capture,state,parse)=>({type:"codeBlock",lang:capture[2]||undefined,content:capture[3]})},paragraph:{match:SimpleMarkdown.defaultRules.paragraph.match,order:2,parse:(capture,state,parse)=>({content:capture[1]})}};const builtArrayParser=SimpleMarkdown.parserFor(arrayRules);const parseToArray=source=>{const paragraphedSource=source.replace(/^\n\s*\n/,"")+"\n\n";return builtArrayParser(paragraphedSource,{inline:false}).map(c=>{return c["content"]})};const joinFromArray=paragraphs=>paragraphs.join("\n\n");var JiptParagraphs = {parseToArray:parseToArray,joinFromArray:joinFromArray};
1628
-
1629
- function LinterLink({message,ruleName,severity,style}){let severityLabel;let severityLabelStyle;if(severity===1){severityLabel="Error";severityLabelStyle=styles$A.publishBlockingError;}else if(severity===2){severityLabel="Warning";severityLabelStyle=styles$A.warning;}else {severityLabel="Recommendation";severityLabelStyle=styles$A.warning;}return jsxRuntimeExports.jsx(Tooltip,{placement:"left",forceAnchorFocusivity:false,variant:"strong",content:jsxRuntimeExports.jsx(TooltipContent,{title:jsxRuntimeExports.jsx(BodyText,{weight:"bold",style:severityLabelStyle,children:severityLabel}),children:message.split("\n\n").map((paragraph,i)=>jsxRuntimeExports.jsx(BodyText,{style:styles$A.tooltipParagraph,children:paragraph},i))}),children:jsxRuntimeExports.jsx(IconButton,{size:"small",kind:"tertiary",actionType:"destructive","aria-label":`${severityLabel}: ${ruleName}`,href:`https://khanacademy.org/r/linter-rules#${ruleName}`,icon:severity===1?warningCircleIcon:dotOutlineIcon,style:style,target:"_blank"})})}const tooltipMaxWidth="min(320px, calc(100vw - 120px))";const styles$A=StyleSheet.create({tooltipParagraph:{maxInlineSize:tooltipMaxWidth,":not(:first-child)":{marginBlockStart:sizing.size_080}},warning:{color:semanticColor.status.warning.foreground},publishBlockingError:{color:semanticColor.status.critical.foreground}});
1630
-
1631
- function Lint({children,inline,message,ruleName,insideTable,blockHighlight,severity}){const linterLinkProps={message,ruleName,severity};if(insideTable){if(inline){return jsxRuntimeExports.jsx("span",{"data-lint-inside-table":"true",children:children})}return jsxRuntimeExports.jsx("div",{"data-lint-inside-table":"true",children:children})}if(blockHighlight){return jsxRuntimeExports.jsxs("span",{className:css(styles$z.lintContainer,styles$z.lintContainerBlock),children:[jsxRuntimeExports.jsx(LinterLink,{...linterLinkProps,style:styles$z.radioWidgetHoverTarget}),jsxRuntimeExports.jsx("span",{children:children})]})}if(inline){return jsxRuntimeExports.jsxs("span",{className:css(styles$z.lintContainer),children:[jsxRuntimeExports.jsx(LinterLink,{...linterLinkProps,style:styles$z.inlineHoverTarget}),jsxRuntimeExports.jsx("span",{children:children})]})}return jsxRuntimeExports.jsxs("div",{className:css(styles$z.lintContainer),children:[jsxRuntimeExports.jsx(LinterLink,{...linterLinkProps,style:styles$z.hoverTarget}),jsxRuntimeExports.jsx("div",{children:children})]})}const highlightBlockContent={":hover ~ div":{outline:`1px solid ${semanticColor.status.warning.foreground}`},":hover ~ div div[data-lint-inside-table]":{outline:`1px solid ${semanticColor.status.warning.foreground}`},":hover ~ div span[data-lint-inside-table]":{backgroundColor:semanticColor.status.warning.background,color:semanticColor.status.warning.foreground}};const highlightInlineContent={":hover ~ span":{backgroundColor:semanticColor.status.warning.background,color:semanticColor.status.warning.foreground}};const styles$z=StyleSheet.create({lintContainer:{position:"relative"},lintContainerBlock:{display:"block"},hoverTarget:{position:"absolute",insetInlineEnd:-60,...highlightBlockContent},inlineHoverTarget:{float:"inline-end",position:"relative",marginInlineEnd:-60,...highlightInlineContent},radioWidgetHoverTarget:{position:"absolute",insetInlineStart:-60}});
1632
-
1633
- const rules={...pureMarkdownRules,columns:{...pureMarkdownRules.columns,react:(node,output,state)=>{return jsxRuntimeExports.jsxs("div",{className:"perseus-two-columns",children:[jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col1,state)})}),jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col2,state)})})]},state.key)}},crowdinId:{...pureMarkdownRules.crowdinId,react:(node,output,state)=>node.id},table:{...pureMarkdownRules.table,react:function(node,output,state){const table=SimpleMarkdown.defaultRules.table.react(node,output,state);if(!state.isMobile){return table}return React.cloneElement(table,{tabIndex:0})}},titledTable:{...pureMarkdownRules.titledTable,react:(node,output,state)=>{let contents;if(!node.table){contents="//invalid table//";}else if(node.table.type==="lint"){if(node.table.content?.type==="table"){contents=rules.lint.react({...node.table,content:{...node,table:node.table.content}},output,{...state,unwrapTitledTableContents:true});}else {contents=rules.lint.react(node.table,output,state);}}else {const tableOutput=SimpleMarkdown.defaultRules.table.react(node.table,output,state);const caption=jsxRuntimeExports.jsx("caption",{className:"perseus-table-title",children:output(node.title,state)},"caption");contents=React.cloneElement(tableOutput,null,[caption,...tableOutput.props.children]);}if(state.unwrapTitledTableContents){return contents}return jsxRuntimeExports.jsx("div",{className:"perseus-titled-table",children:contents},state.key)}},widget:{...pureMarkdownRules.widget,react:(node,output,state)=>{return jsxRuntimeExports.jsx("em",{children:`[Widget: ${node.id}]`},state.key)}},blockMath:{...pureMarkdownRules.blockMath,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},math:{...pureMarkdownRules.math,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},unescapedDollar:{...pureMarkdownRules.unescapedDollar,react:(node,output,state)=>{return "$"}},link:{...pureMarkdownRules.link,react:function(node,output,state){const link=SimpleMarkdown.defaultRules.link.react(node,output,state);const href=link.props.href;let rel=null;const isKAUrl=href?href.match(/https?:\/\/[^/]*khanacademy.org|^\//):false;if(!isKAUrl){rel="noopener noreferrer";}const newProps={...link.props,target:"_blank",href,rel};if(state.baseElements&&state.baseElements.Link){return state.baseElements.Link(newProps)}return React.cloneElement(link,newProps)}},codeBlock:{...pureMarkdownRules.codeBlock,react:(node,output,state)=>{if(node.lang==="alt"){return jsxRuntimeExports.jsx("div",{className:"perseus-markdown-alt perseus-sr-only",children:output(node.content,state)},state.key)}return SimpleMarkdown.defaultRules.codeBlock.react(node,output,state)}},lint:{...pureMarkdownRules.lint,react:(node,output,state)=>{return jsxRuntimeExports.jsx(Lint,{message:node.message,ruleName:node.ruleName,inline:isInline(node.content),blockHighlight:node.blockHighlight,insideTable:node.insideTable,severity:node.severity,children:output(node.content,state)})}}};function isInline(node){if(node?.type==="widget"){return CoreWidgetRegistry.isInlineWidget(node.widgetType)}return !!(node&&node.type&&inlineNodeTypes.hasOwnProperty(node.type))}const inlineNodeTypes={text:true,math:true,unescapedDollar:true,link:true,img:true,strong:true,u:true,em:true,del:true,code:true};const builtParser=SimpleMarkdown.parserFor(rules);const parse=(source,state)=>{const paragraphedSource=source+"\n\n";return builtParser(paragraphedSource,{...state,inline:false})};const inlineParser=(source,state)=>{return builtParser(source,{...state,inline:true})};const getContent=ast=>{if(Array.isArray(ast)){return _.flatten(ast.map(getContent))}if(ast.content&&typeof ast.content==="string"){if(ast.type.toLowerCase().indexOf("code")!==-1){return ["",ast.content,""]}return [ast.content.replace(/\s+/g," ")]}const children=_.chain(ast).values().flatten().filter(object=>object!=null&&_.has(object,"type")).value();if(!children.length){return []}const nestedContent=getContent(children);if(ast.type==="paragraph"&&nestedContent.length){nestedContent[0]=nestedContent[0].replace(/^\s+/,"");const last=nestedContent.length-1;nestedContent[last]=nestedContent[last].replace(/\s+$/,"");}return nestedContent};const characterCount=source=>{const ast=parse(source);const content=getContent(ast).join("");return content.length};var PerseusMarkdown = {characterCount:characterCount,traverseContent:traverseContent,parse:parse,parseInline:inlineParser,reactFor:SimpleMarkdown.reactFor,ruleOutput:SimpleMarkdown.ruleOutput(rules,"react"),basicOutput:SimpleMarkdown.reactFor(SimpleMarkdown.ruleOutput(rules,"react")),sanitizeUrl:SimpleMarkdown.sanitizeUrl};
1634
-
1635
- const QuestionParagraph=props=>{const className=props.className?"deprecated-perseus-container "+props.className:"deprecated-perseus-container";const isJipt=props.translationIndex!=null;if(props.inline&&!props.className&&!isJipt){return props.children}return jsxRuntimeExports.jsx("div",{className:props.inline?props.className??undefined:className,"data-perseus-component-index":isJipt?props.translationIndex:undefined,"data-perseus-paragraph-index":isJipt?props.paragraphIndex:undefined,children:props.children})};
1636
-
1637
- const DEBOUNCE_TIMEOUT=1e3;class TranslationLinter{applyLintErrors(parsedMarkdown,translationLintErrors){if(translationLintErrors.length){const errorText=translationLintErrors.join("\n\n");parsedMarkdown.unshift({content:{type:"text",content:""},insideTable:false,message:errorText,ruleName:"legacy-error",severity:Rule.Severity.ERROR,type:"lint"});}}constructor(){this.previousContent=null;this.runLinter=debounce$1((perseusStr,onLintErrorsGenerated)=>{if(typeof KA==="undefined"){return}if(perseusStr===this.previousContent){return}this.previousContent=perseusStr;if(perseusStr===""){onLintErrorsGenerated([]);return}fetch("/api/internal/translations/lint_poentry?preview=1&lang=en",{headers:{"Content-Type":"application/json"},body:JSON.stringify({msgid:perseusStr,msgstr:perseusStr,format:"perseus_text",filename:""}),method:"POST"}).then(response=>{if(response.status>=400){return {status:"error",message:"Could not run i18n linter."}}return response.json()},rejection=>{return {status:"error",message:"Could not run i18n linter."}}).then(json=>{if(json.status==="error"){onLintErrorsGenerated(["Some part of this text makes it untranslatable. "+"The specific message from the i18n linter was: "+json.message.replace(/\n/g," ")]);}else {onLintErrorsGenerated([]);}});},DEBOUNCE_TIMEOUT);}}
1638
-
1639
- const{interactiveSizes}=constants;const smMax=articleMaxWidthTableInPx;const mdMax=articleMaxWidthInPx;const containerSizeClass={SMALL:"small",MEDIUM:"medium",LARGE:"large",XLARGE:"xlarge"};const getClassFromWidth=width=>{if(!width){return containerSizeClass.MEDIUM}if(width<=smMax){return containerSizeClass.SMALL}if(width<=mdMax){return containerSizeClass.MEDIUM}return containerSizeClass.LARGE};const getInteractiveBoxFromSizeClass=sizeClass=>{if(sizeClass===containerSizeClass.SMALL){return [interactiveSizes.defaultBoxSizeSmall,interactiveSizes.defaultBoxSizeSmall]}return [interactiveSizes.defaultBoxSize,interactiveSizes.defaultBoxSize]};
1640
-
1641
- var preprocessTex = (texCode=>texCode.replace(/\{align[*]?\}/g,"{aligned}").replace(/[\u00a0]/g," "));
1642
-
1643
- function UnsupportedWidgetMessage({widgetType,widgetSubType,widgetId,reason="widget-not-registered"}){const{strings}=usePerseusI18n();const dependencies=useDependencies();useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:unsupported",payload:{widgetType,widgetSubType,widgetId,reason}});});return jsxRuntimeExports.jsx("div",{style:{paddingBlock:sizing.size_080},children:jsxRuntimeExports.jsx(Banner,{text:strings.unsupportedWidget,kind:"info"})})}
1644
-
1645
- function getWidgetTypeByWidgetId(widgetId,widgetMap){const widget=widgetMap[widgetId];return widget?.type??null}function getWidgetSubType(widgetType,widgetOptions){switch(widgetType){case "interactive-graph":const graphOptions=widgetOptions;return graphOptions.graph?.type??null;case "radio":const radioOptions=widgetOptions;return radioOptions.multipleSelect?"multiple-select":"single-select";default:return null}}function getWidgetSubTypeByWidgetId(widgetId,widgetMap){const widget=widgetMap[widgetId];if(!widget){return null}return getWidgetSubType(widget.type,widget.options)}function contentHasWidgetType(type,content,widgetMap){return getWidgetIdsFromContentByType(type,content,widgetMap).length>0}function getWidgetFromWidgetMap(widgetId,widgetMap){return widgetMap[widgetId]??null}function getWidgetsFromWidgetMap(widgetIds,widgetMap){const widgets={};widgetIds.forEach(widgetId=>{const widget=getWidgetFromWidgetMap(widgetId,widgetMap);if(widget){widgets[widgetId]=widget;}});return widgets}
1646
-
1647
- const DEFAULT_TRACKING="";const DEFAULT_LINTABLE=false;const widgets=new Registry("Perseus widget registry");const registerWidget=(type,widget)=>{widgets.set(type,widget);};const registerWidgets=widgetArr=>{widgetArr.forEach(widget=>{registerWidget(widget.name,widget);});};const getWidget=type=>{const widget=widgets.get(type);if(widget==null){return null}return widget.widget};const getWidgetExport=type=>{return widgets.get(type)??null};const getPublicWidgets=()=>{return widgets.entries().reduce((acc,[key,value])=>{if(process.env.STORYBOOK||!value.hidden){acc[key]=value;}return acc},{})};const getAllWidgetTypes=()=>{return widgets.keys()};const supportsStaticMode=type=>{const widgetInfo=widgets.get(type);return widgetInfo&&widgetInfo.getCorrectUserInput!=null};const supportsUngraded=type=>{const widgetInfo=widgets.get(type);return widgetInfo?.supportsUngraded===true};const getTracking=type=>{const widgetExport=widgets.get(type);return widgetExport&&widgetExport.tracking||DEFAULT_TRACKING};const isLintable=type=>{const widgetExports=widgets.get(type);return widgetExports&&widgetExports.isLintable||DEFAULT_LINTABLE};
1648
-
1649
- var widgets$1 = /*#__PURE__*/Object.freeze({
1650
- __proto__: null,
1651
- getAllWidgetTypes: getAllWidgetTypes,
1652
- getPublicWidgets: getPublicWidgets,
1653
- getTracking: getTracking,
1654
- getWidget: getWidget,
1655
- getWidgetExport: getWidgetExport,
1656
- isLintable: isLintable,
1657
- registerWidget: registerWidget,
1658
- registerWidgets: registerWidgets,
1659
- supportsStaticMode: supportsStaticMode,
1660
- supportsUngraded: supportsUngraded
1661
- });
1662
-
1663
- class WidgetContainer extends React.Component{componentDidMount(){if(this.props.widgetProps.apiOptions.isMobile){const containerWidth=ReactDOM__default.findDOMNode(this).offsetWidth;this.setState({sizeClass:getClassFromWidth(containerWidth)});}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.type!==nextProps.type){throw new Error("WidgetContainer can't change widget type; set a different "+"key instead to recreate the container.")}}render(){let className=classNames$2({"perseus-widget-container":true,"perseus-widget__definition":this.props.type==="definition"});const type=this.props.type;const userAgent=navigator.userAgent;let alignment=this.props.widgetProps.alignment;if(alignment==null||alignment==="default"){alignment=CoreWidgetRegistry.getDefaultAlignment(type);}className+=CoreWidgetRegistry.getAlignmentClassName(type,alignment);const subType=getWidgetSubType(type,this.props.widgetProps.options)??"null";const WidgetType=getWidget(type);if(WidgetType==null){return jsxRuntimeExports.jsx("div",{className:"deprecated-perseus-container",children:jsxRuntimeExports.jsx("div",{className:className,children:jsxRuntimeExports.jsx(UnsupportedWidgetMessage,{widgetType:type,widgetSubType:subType,widgetId:this.props.id})})})}const Container=CoreWidgetRegistry.isInlineWidget(type,alignment)?"span":"div";const apiOptions=this.props.widgetProps.apiOptions;const isStatic=this.props.widgetProps.static||apiOptions.readOnly;const staticContainerStyles={position:"relative",overflow:"visible"};const staticOverlayStyles={width:"100%",height:"100%",position:"absolute",top:0,left:0,zIndex:3};const linterContext=isLintable(type)?this.props.widgetProps.linterContext:{...this.props.widgetProps.linterContext,highlightLint:false};return jsxRuntimeExports.jsx(Container,{className:"deprecated-perseus-container",children:jsxRuntimeExports.jsx(Container,{className:className,style:isStatic?staticContainerStyles:{},children:jsxRuntimeExports.jsx(DependenciesContext.Consumer,{children:({analytics})=>jsxRuntimeExports.jsxs(ErrorBoundary,{metadata:{widget_type:type,widget_id:this.props.id},onError:error=>{analytics.onAnalyticsEvent({type:"perseus:widget-rendering-error:ti",payload:{widgetSubType:subType,widgetType:type,widgetId:this.props.id,message:error.message,stack:error.stack??"No stack trace available",userAgent:userAgent}});},children:[jsxRuntimeExports.jsx(WidgetType,{...this.props.widgetProps,linterContext:linterContext,containerSizeClass:this.state.sizeClass,ref:this.widgetRef}),isStatic&&jsxRuntimeExports.jsx("div",{style:staticOverlayStyles})]})})})})}constructor(...args){super(...args),this.widgetRef=React.createRef(),this.state={sizeClass:containerSizeClass.MEDIUM},this.getWidget=()=>{return this.widgetRef.current};}}
1664
-
1665
- const rContainsNonWhitespace=/\S/;const rImageURL=/(web\+graphie|https):\/\/[^\s]*/;const noopOnRender=()=>{};const makeContainerId=id=>"container:"+id;const isIdPathPrefix=function(prefixArray,wholeArray){if(prefixArray===null||wholeArray===null){return prefixArray===wholeArray}return _.every(prefixArray,(elem,i)=>{if(wholeArray!=null){return _.isEqual(elem,wholeArray[i])}})};function isDifferentQuestion(propsA,propsB){function makeItem(props){return splitPerseusItem({question:{content:props.content,widgets:props.widgets,images:{}},hints:[],answerArea:getDefaultAnswerArea()})}return propsA.problemNum!==propsB.problemNum||!_.isEqual(makeItem(propsA),makeItem(propsB))}class Renderer extends React.Component{componentDidMount(){this._isMounted=true;this.handleRender({});this._currentFocus=null;this.props.initializeUserInput?.(this.props.widgets,this.props.problemNum??0);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}UNSAFE_componentWillReceiveProps(nextProps){if(isDifferentQuestion(this.props,nextProps)){this.props.initializeUserInput?.(nextProps.widgets,nextProps.problemNum??0);this.setState(this._getInitialWidgetState(nextProps));}}shouldComponentUpdate(nextProps,nextState){if(this.props.alwaysUpdate){return true}const stateChanged=!_.isEqual(this.state,nextState);const propsChanged=!_.isEqual(this.props,nextProps);return propsChanged||stateChanged}componentDidUpdate(prevProps,prevState){this.handleRender(prevProps);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput&&!_.isEqual(this.props.userInput,prevProps.userInput)){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}componentWillUnmount(){this.widgetIds=[];if(this.translationIndex!=null){getDependencies().rendererTranslationComponents.removeComponentAtIndex(this.translationIndex);}this._isMounted=false;}_isAnswerable(){if(this.props.userInput){return this.emptyWidgets().length===0}return false}_getWidgetIndexById(id){const widgetIndex=this.widgetIds.indexOf(id);if(widgetIndex<0){Log.error("Unable to get widget index in _getWidgetIndexById",Errors.Internal,{loggedMetadata:{widgets:JSON.stringify(this.props.widgets),widgetId:JSON.stringify(id)}});return 0}return widgetIndex}getWidgetProps(widgetId){const apiOptions=this.getApiOptions();const widgetOptions=this.props.widgets[widgetId].options;const widgetInfo=this.state.widgetInfo[widgetId];if(!this._interactionTrackers){this._interactionTrackers={};}let interactionTracker=this._interactionTrackers[widgetId];if(!interactionTracker){interactionTracker=this._interactionTrackers[widgetId]=new InteractionTracker(apiOptions.trackInteraction,widgetInfo&&widgetInfo.type,widgetId,getTracking(widgetInfo&&widgetInfo.type));}return {options:widgetOptions,userInput:this.props.userInput?.[widgetId],widgetId:widgetId,widgetIndex:this._getWidgetIndexById(widgetId),alignment:widgetInfo&&widgetInfo.alignment,static:widgetInfo?.static,graded:widgetInfo?.graded,problemNum:this.props.problemNum,apiOptions:this.getApiOptions(),keypadElement:this.props.keypadElement,showSolutions:this.props.showSolutions,onFocus:_.partial(this._onWidgetFocus,widgetId),onBlur:_.partial(this._onWidgetBlur,widgetId),findWidgets:this.findWidgets,reviewMode:this.props.reviewMode??false,isScorable:this.props.isScorable??false,containerSizeClass:containerSizeClass.MEDIUM,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"widget"),handleUserInput:newUserInput=>{const updatedUserInput={...this.props.userInput,[widgetId]:newUserInput};const emptyWidgetIds=emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,updatedUserInput,this.context.locale);const widgetsEmpty=emptyWidgetIds.length>0;this.props.handleUserInput?.(widgetId,newUserInput,widgetsEmpty);this.props.apiOptions?.interactionCallback?.(updatedUserInput);},trackInteraction:interactionTracker.track}}getSerializedState(){return mapObject(this.props.widgets,(widgetData,widgetId)=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getSerializedState){return excludeDenylistKeys(widget.getSerializedState())}return widgetData.options})}replaceJiptContent(content,paragraphIndex){if(paragraphIndex==null){this.setState({jiptContent:content});}else {const codeFenceRegex=/^\s*(`{3,}|~{3,})\s*(\S+)?\s*\n([\s\S]+?)\s*\1\s*$/;if(codeFenceRegex.test(content));else if(/\S\n\s*\n\S/.test(content)){content="$\\large{\\red{\\text{Please translate each "+"paragraph to a single paragraph.}}}$";}else if(/^\s*$/.test(content)){content="$\\large{\\red{\\text{Translated paragraph is "+"currently empty}}}$";}const allContent=this.getContent(this.props,this.state);const paragraphs=JiptParagraphs.parseToArray(allContent);paragraphs[paragraphIndex]=content;this.setState({jiptContent:JiptParagraphs.joinFromArray(paragraphs)});}}emptyWidgets(){if(!this.props.userInput){throw new Error(`emptyWidgets called without providing userInput to Renderer`)}return emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale)}getUserInputMap(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInputMap called without providing userInput to Renderer`)}return userInput}getPromptJSON(){const{content}=this.props;const widgetJSON={};this.widgetIds.forEach(id=>{const widget=this.getWidgetInstance(id);widgetJSON[id]=widget?.getPromptJSON?.()||{};});return {content,widgets:widgetJSON}}score(){if(!this.props.userInput){throw new Error(`score called without providing userInput to Renderer`)}const scores=scoreWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale);const combinedScore=flattenScores(scores);return combinedScore}render(){const apiOptions=this.getApiOptions();const content=this.getContent(this.props,this.state);this.widgetIds=[];if(this.shouldRenderJiptPlaceholder(this.props,this.state)){if(!this.translationIndex){this.translationIndex=getDependencies().rendererTranslationComponents.addComponent(this);}if(!apiOptions.isArticle){return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{"data-perseus-component-index":this.translationIndex,children:content})})}}this._isTwoColumn=false;let parsedMarkdown=this.props.inline?PerseusMarkdown.parseInline(content,{isJipt:this.translationIndex!=null}):PerseusMarkdown.parse(content,{isJipt:this.translationIndex!=null});parsedMarkdown=Util.splitBlockWidgetsFromParagraphs(parsedMarkdown);if(this.props.linterContext.highlightLint){const fullLinterContext={content:this.props.content,widgets:this.props.widgets,...this.props.linterContext};PerseusLinter.runLinter(parsedMarkdown,fullLinterContext,true);this._translationLinter.applyLintErrors(parsedMarkdown,[...this.state.translationLintErrors,...this.props.legacyPerseusLint||[]]);}const markdownContents=this.outputMarkdown(Util.joinAdjacentTextNodes(parsedMarkdown),{baseElements:apiOptions.baseElements});const className=classNames$2({[ClassNames.RENDERER]:true,[ClassNames.RESPONSIVE_RENDERER]:true,[ClassNames.TWO_COLUMN_RENDERER]:this._isTwoColumn});return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{className:className,children:markdownContents})})}constructor(props){super(props),this._widgetContainers=new Map,this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions}},this._getInitialWidgetState=props=>{const allWidgetInfo=applyDefaultsToWidgets(props.widgets);return {widgetInfo:allWidgetInfo}},this._getDefaultWidgetInfo=widgetId=>{const widgetIdParts=Util.rTypeFromWidgetId.exec(widgetId);if(widgetIdParts==null){return {}}return {type:widgetIdParts[1],graded:true,options:{}}},this._getWidgetInfo=widgetId=>{return this.state.widgetInfo[widgetId]||this._getDefaultWidgetInfo(widgetId)},this.renderWidget=(impliedType,id,state)=>{const widgetInfo=this.state.widgetInfo[id];if(widgetInfo&&widgetInfo.alignment==="full-width"){state.foundFullWidth=true;}if(widgetInfo){const type=widgetInfo&&widgetInfo.type||impliedType;return jsxRuntimeExports.jsx(WidgetContainer,{id:id,ref:node=>{const containerId=makeContainerId(id);if(node!=null){this._widgetContainers.set(containerId,node);}else {this._widgetContainers.delete(containerId);}},type:type,widgetProps:this.getWidgetProps(id)},makeContainerId(id))}return null},this.findInternalWidgets=filterCriterion=>{let filterFunc;if(typeof filterCriterion==="string"){if(filterCriterion.indexOf(" ")!==-1){const widgetId=filterCriterion;filterFunc=(id,widgetInfo,widget)=>id===widgetId;}else {const widgetType=filterCriterion;filterFunc=(id,widgetInfo,widget)=>{return widgetInfo.type===widgetType};}}else {filterFunc=filterCriterion;}const results=this.widgetIds.filter(id=>{const widgetInfo=this._getWidgetInfo(id);const widget=this.getWidgetInstance(id);return filterFunc(id,widgetInfo,widget)}).map(this.getWidgetInstance);return results},this.findWidgets=filterCriterion=>{return [...this.findInternalWidgets(filterCriterion),...this.props.findExternalWidgets(filterCriterion)]},this.getWidgetInstance=id=>{const ref=this._widgetContainers.get(makeContainerId(id));if(!ref){return null}return ref.getWidget()},this._onWidgetFocus=(id,focusPath=[])=>{if(!Array.isArray(focusPath)){throw new PerseusError("widget props.onFocus focusPath must be an Array, "+"but was"+JSON.stringify(focusPath),Errors.Internal)}this._setCurrentFocus([id].concat(focusPath));},this._onWidgetBlur=(id,blurPath)=>{const blurringFocusPath=this._currentFocus;const fullPath=[id].concat(blurPath);if(!_.isEqual(fullPath,blurringFocusPath)){return}_.defer(()=>{if(_.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.getContent=(props,state)=>{return state.jiptContent||props.content},this.shouldRenderJiptPlaceholder=(props,state)=>{return getDependencies().JIPT.useJIPT&&state.jiptContent==null&&props.content.indexOf("crwdns")!==-1},this.outputMarkdown=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;state.paragraphIndex=i;const nodeOut=this.outputMarkdown(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}this._foundTextNodes=false;state.foundFullWidth=false;const output=this.outputNested(ast,state);let className;if(this.translationIndex!=null){className=null;}else {className=classNames$2({"perseus-paragraph-centered":!this._foundTextNodes&&!this.props.inline,"perseus-paragraph-full-width":state.foundFullWidth&&ast.type==="widget"});}return jsxRuntimeExports.jsx(QuestionParagraph,{className:className,translationIndex:this.translationIndex,paragraphIndex:state.paragraphIndex,inline:this.props.inline,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:output})},state.key)},this.outputNested=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;const nodeOut=this.outputNested(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}return this.outputNode(ast,this.outputNested,state)},this.outputNode=(node,nestedOutput,state)=>{const apiOptions=this.getApiOptions();const imagePlaceholder=apiOptions.imagePlaceholder;if(node.type==="paragraph"){const content=nestedOutput(node.content,state);if(isContentGraphie(node)||hasResponsiveImage(node,this.props)){return jsxRuntimeExports.jsx("div",{className:"deprecated-perseus-container",children:content})}if(noParagraphForInlineWidget(node)){return content}return jsxRuntimeExports.jsx("p",{className:"deprecated-perseus-container",children:content},state.key)}if(node.type==="widget"){const widgetPlaceholder=apiOptions.widgetPlaceholder;if(widgetPlaceholder){return widgetPlaceholder}this._foundTextNodes=true;if(this.widgetIds.includes(node.id)){return jsxRuntimeExports.jsx("span",{className:"renderer-widget-error",children:["Widget [[","☃"," ",node.id,"]] already exists."].join("")},state.key)}this.widgetIds.push(node.id);return this.renderWidget(node.widgetType,node.id,state)}if(node.type==="blockMath"){const content=preprocessTex(node.content);const innerStyle={overflowX:"auto",overflowY:"hidden",paddingTop:10,paddingBottom:10,marginTop:-10,marginBottom:-10};if(apiOptions.isMobile){const margin=16;const outerStyle={marginLeft:-16,marginRight:-16};const horizontalPadding={paddingLeft:margin,paddingRight:margin};const mobileInnerStyle={...innerStyle,...styles$y.mobileZoomableParentFix};return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",style:outerStyle,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:{...mobileInnerStyle,...horizontalPadding},children:jsxRuntimeExports.jsx(ZoomableTeX,{children:content})})})},state.key)}return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:innerStyle,children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{setAssetStatus:setAssetStatus,children:content})})})})},state.key)}if(node.type==="math"){const tex=node.content;return jsxRuntimeExports.jsx("span",{style:{whiteSpace:"nowrap"},children:jsxRuntimeExports.jsxs(ErrorBoundary,{children:[jsxRuntimeExports.jsx("span",{}),jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{onRender:this.props.onRender,setAssetStatus:setAssetStatus,children:tex})}),jsxRuntimeExports.jsx("span",{})]})},state.key)}if(node.type==="image"){if(imagePlaceholder){return imagePlaceholder}const responsive=!state.inTable;return jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{allowZoom:true,setAssetStatus:setAssetStatus,src:PerseusMarkdown.sanitizeUrl(node.target),alt:node.alt,title:node.title,responsive:responsive,onUpdate:this.props.onRender,...getImageDimensions(node.target,this.props)})})},state.key)}if(node.type==="columns"){this._isTwoColumn=true;return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)}if(node.type==="text"){if(rContainsNonWhitespace.test(node.content)){this._foundTextNodes=true;}if(imagePlaceholder&&rImageURL.test(node.content)){return imagePlaceholder}return node.content}if(node.type==="table"||node.type==="titledTable"){const output=PerseusMarkdown.ruleOutput(node,nestedOutput,{...state,isMobile:apiOptions.isMobile,inTable:true});if(!apiOptions.isMobile){return output}const outerStyle={marginLeft:-16,marginRight:-16};const innerStyle={paddingLeft:0,paddingRight:0};const mobileInnerStyle={...innerStyle,...styles$y.mobileZoomableParentFix};const wrappedOutput=jsxRuntimeExports.jsx("div",{style:{...mobileInnerStyle,overflowX:"auto"},children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(Zoomable$1,{animateHeight:true,children:output})})});return jsxRuntimeExports.jsx("div",{style:outerStyle,children:wrappedOutput})}return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)},this.handleRender=prevProps=>{const onRender=this.props.onRender;const oldOnRender=prevProps.onRender;if(onRender!==noopOnRender||oldOnRender!==noopOnRender){const node=ReactDOM__default.findDOMNode(this);if(node instanceof Element){node.querySelectorAll("img").forEach(image=>{if(oldOnRender!==noopOnRender){image.removeEventListener("load",oldOnRender);}if(onRender!==noopOnRender){image.addEventListener("load",onRender);}});}}onRender();},this._setCurrentFocus=path=>{const apiOptions=this.getApiOptions();if(!isIdPathPrefix(path,this._currentFocus)){const prevFocus=this._currentFocus;if(prevFocus){this.blurPath(prevFocus);}this._currentFocus=path;apiOptions.onFocusChange(this._currentFocus,prevFocus);}},this.focus=()=>{let id;let focusResult;for(let i=0;i<this.widgetIds.length;i++){const widgetId=this.widgetIds[i];const widget=this.getWidgetInstance(widgetId);const widgetFocusResult=widget?.focus?.();if(widgetFocusResult){id=widgetId;focusResult=widgetFocusResult;break}}if(id){let path;if(typeof focusResult==="object"){path=[id].concat(focusResult.path||[]);Log.error("Renderer received a focus result of type 'object' "+"instead of the expected type 'boolean'",Errors.Internal,{loggedMetadata:{focusResult:JSON.stringify(focusResult)}});}else {path=[id];}this._setCurrentFocus(path);return true}},this.getDOMNodeForPath=path=>{const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget?.getDOMNodeForPath){return widget.getDOMNodeForPath(interWidgetPath)}if(interWidgetPath.length===0){const container=this._widgetContainers.get(makeContainerId(widgetId));if(container){return ReactDOM__default.findDOMNode(container)}return ReactDOM__default.findDOMNode(widget)}},this.getInputPaths=()=>{const inputPaths=[];this.widgetIds.forEach(widgetId=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getInputPaths){const widgetInputPaths=widget.getInputPaths();widgetInputPaths.forEach(inputPath=>{const relativeInputPath=[widgetId].concat(inputPath);inputPaths.push(relativeInputPath);});}});return inputPaths},this.focusPath=path=>{if(_.isEqual(this._currentFocus,path)){return}if(this._currentFocus){this.blurPath(this._currentFocus);}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const focusWidget=this.getWidgetInstance(widgetId);focusWidget?.focusInputPath?.(interWidgetPath);},this.blurPath=path=>{if(!_.isEqual(this._currentFocus,path)){return}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget){const blurWidget=this.getWidgetInstance(widgetId);blurWidget?.blurInputPath?.(interWidgetPath);}},this.blur=()=>{if(this._currentFocus){this.blurPath(this._currentFocus);}},this.getWidgetIds=()=>{return this.widgetIds},this.handletranslationLintErrors=lintErrors=>{if(!this._isMounted){return}this.setState({translationLintErrors:lintErrors});};this._translationLinter=new TranslationLinter;this.state={jiptContent:null,translationLintErrors:[],...this._getInitialWidgetState(props)};}}Renderer.contextType=PerseusI18nContext;Renderer.defaultProps={content:"",widgets:{},images:{},showSolutions:"none",onRender:noopOnRender,findExternalWidgets:()=>[],alwaysUpdate:false,reviewMode:false,isScorable:false,linterContext:PerseusLinter.linterContextDefault};function getImageDimensions(url,{images}){return _.has(images,url)?images[url]:null}function hasResponsiveImage(node,props){if(Array.isArray(node.content)){return node.content.some(child=>hasResponsiveImage(child,props))}return node.type==="image"&&getImageDimensions(node.target,props)!=null}const styles$y={mobileZoomableParentFix:{transform:"translate3d(0,0,0)"}};
1666
-
1667
- const{captureScratchpadTouchStart: captureScratchpadTouchStart$1}=Util;const InputWithExamples=forwardRef(function InputWithExamples({shouldShowExamples=true,onFocus=()=>{},onBlur=()=>{},disabled=false,required=false,linterContext=PerseusLinter.linterContextDefault,className="",...props},ref){const context=React.useContext(PerseusI18nContext);const inputRef=React.useRef(null);const[inputFocused,setInputFocused]=React.useState(false);const id=useId();const ariaId=`aria-for-${id}`;useImperativeHandle(ref,()=>({current:inputRef.current,focus:()=>{if(inputRef.current){inputRef.current.focus();}},blur:()=>{if(inputRef.current){inputRef.current.blur();}}}));const getInputClassName=()=>{let inputClassName=ClassNames.INPUT;if(inputFocused){inputClassName+=" "+ClassNames.FOCUSED;}if(className){inputClassName+=" "+className;}return inputClassName};const handleFocus=()=>{onFocus();setInputFocused(true);};const handleBlur=()=>{onBlur();setInputFocused(false);};const renderInput=()=>{const examplesAria=shouldShowExamples?`${props.examples[0]}
1668
- ${props.examples.slice(1).join(", or\n")}`.replace(/\*/g,"").replace(/\$/g,"").replace(/\\ \\text{pi}/g," pi").replace(/\\ /g," and "):"";const inputProps={id:id,"aria-describedby":shouldShowExamples?ariaId:undefined,"aria-required":required,ref:inputRef,className:getInputClassName(),labelText:props.labelText,value:props.value,onFocus:handleFocus,onBlur:handleBlur,disabled:disabled,style:props.style,onChange:props.onChange,onTouchStart:captureScratchpadTouchStart$1,autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",spellCheck:"false"};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(TextInput,{...inputProps}),jsxRuntimeExports.jsx("span",{id:ariaId,style:{display:"none"},children:examplesAria})]})};const renderTooltipContent=()=>{return jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsx("div",{id:id,className:"input-with-examples-tooltip perseus-in-wb-popover",children:jsxRuntimeExports.jsx(Renderer,{content:examplesContent,linterContext:PerseusLinter.pushContextStack(linterContext,"input-with-examples"),strings:context.strings})})})};const examplesContent=props.examples.length<=2?props.examples.join(" "):props.examples.map((example,index)=>{return index===0&&example.startsWith("**")?`${example}
1669
- `:`- ${example}`}).join("\n");const showExamplesTooltip=shouldShowExamples&&inputFocused;return jsxRuntimeExports.jsx(Tooltip,{content:renderTooltipContent(),opened:showExamplesTooltip,placement:"bottom",children:renderInput()})});
1670
-
1671
- var styles$x = {"inputWithExamples":"perseus_QUlWSKE-","isFocused":"perseus_8i8MUC5K","rightAlign":"perseus_9cRSmuw9","centerAlign":"perseus_L-8sB566","sizeSmall":"perseus_LbMErCm0"};
1672
-
1673
- const styles$w={inputWithExamples:{borderRadius:"0.3rem",borderWidth:"var(--wb-border-width-thin)",direction:"ltr",display:"inline-block",fontFamily:'Symbola, "Times New Roman", serif',fontSize:"1.8rem",height:"3.2rem",lineHeight:"1.8rem",padding:"0.4rem 0.5rem",textAlign:"left",width:"8rem"},isFocused:{borderWidth:"var(--wb-border-width-medium)",padding:"0.4rem"},rightAlign:{textAlign:"right"},centerAlign:{textAlign:"center"},sizeSmall:{width:"4rem"}};
1674
-
1675
- const NumericExampleStrings={integer:(form,strings)=>strings.integerExample,proper:(form,strings)=>form.simplify==="optional"?strings.properExample:strings.simplifiedProperExample,improper:(form,strings)=>form.simplify==="optional"?strings.improperExample:strings.simplifiedImproperExample,mixed:(form,strings)=>strings.mixedExample,decimal:(form,strings)=>strings.decimalExample,percent:(form,strings)=>strings.percentExample,pi:(form,strings)=>strings.piExample};const generateExamples=(answerForms,strings)=>{if(answerForms.length===0){return []}const uniqueForms=getUniqueAnswerForms(answerForms);const examples=uniqueForms.map(form=>{return NumericExampleStrings[form.name](form,strings)});const yourAnswerText=uniqueForms.length>1?strings.yourAnswerCanBe:strings.yourAnswer;return [yourAnswerText].concat(examples)};const shouldShowExamples=answerForms=>{if(answerForms.length===0){return false}const answerFormNames=getUniqueAnswerForms(answerForms).map(form=>form.name);const allFormsAccepted=answerFormNames.length>=Object.keys(NumericExampleStrings).length;return !allFormsAccepted};const getUniqueAnswerForms=function(list){const foundForms=new Set;return list.filter(form=>{if(foundForms.has(form.name)){return false}foundForms.add(form.name);return true})};const unionAnswerForms=function(answerFormsList){const allForms=answerFormsList.flat();const uniqueForms=getUniqueAnswerForms(allForms);const formExampleKeys=Object.keys(NumericExampleStrings);return uniqueForms.sort((a,b)=>{return formExampleKeys.indexOf(a.name)-formExampleKeys.indexOf(b.name)})};function normalizeCorrectAnswerForms(answers){if(answers==null){return []}return unionAnswerForms(answers.filter(answer=>answer.status==="correct").map(answer=>{return (answer.answerForms||[]).map(form=>{return {simplify:answer.simplify,name:form}})}))}function getStartUserInput$h(){return {currentValue:""}}function getUserInputFromSerializedState$h(serializedState){return {currentValue:serializedState.currentValue}}function findPrecision(value){for(let i=0;i<10;i++){if(value===+value.toFixed(i)){return i}}return 10}function findCommonFractions(value){const whole=Math.floor(value);if(value===whole){return}const decimal=value-whole;const precision=findPrecision(decimal);for(let num=1;num<100;num++){for(let denom=2;denom<100;denom++){if(+(num/denom).toFixed(precision)===decimal){return {num:num+whole*denom,denom}}}}}function getCorrectUserInput$8(options){for(const answer of options.answers){if(answer.status==="correct"&&answer.value!=null){if(answer.answerForms?.includes("decimal")){return {currentValue:answer.value.toString()}}if(answer.answerForms?.includes("improper")){const frac=findCommonFractions(answer.value);if(frac){return {currentValue:`${frac.num}/${frac.denom}`}}}if(answer.answerForms?.includes("proper")){const frac=findCommonFractions(answer.value);if(frac){const{num,denom}=frac;if(num>denom){const whole=Math.floor(num/denom);const remainder=num-whole*denom;return {currentValue:`${whole} ${remainder}/${denom}`}}else {return {currentValue:`${num}/${denom}`}}}}return {currentValue:answer.value.toString()}}}return {currentValue:""}}function getOneCorrectAnswerFromRubric(rubric){const correctAnswers=rubric.answers.filter(answer=>answer.status==="correct");const answerStrings=correctAnswers.map(answer=>{const format=answer.answerForms&&answer.answerForms[0]?answer.answerForms[0]:"decimal";let answerString=KhanMath.toNumericString(answer.value,format);if(answer.maxError){answerString+=" ± "+KhanMath.toNumericString(answer.maxError,format);}return answerString});if(answerStrings.length===0){return}return answerStrings[0]}
1676
-
1677
- const NumericInput=forwardRef(function NumericInput(props,ref){const{analytics}=useDependencies();const context=useContext(PerseusI18nContext);const inputRef=useRef(null);const[isFocused,setIsFocused]=useState(false);useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"numeric-input",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({focus(){if(inputRef.current){inputRef.current.focus();setIsFocused(true);}return true},focusInputPath(){if(inputRef.current){inputRef.current.focus();setIsFocused(true);}},blurInputPath(){if(inputRef.current){inputRef.current.blur();setIsFocused(false);}},getInputPaths:()=>[[]],getPromptJSON:()=>getPromptJSON$p(props),getSerializedState(){const{userInput,options,...otherProps}=props;const{labelText,answers,...otherOptions}=options;return {...otherOptions,...otherProps,answerForms:[],labelText:labelText??"",currentValue:userInput.currentValue}}}));const{answers,labelText,size,textAlign}=props.options;const answerForms=normalizeCorrectAnswerForms(answers);const isRequired=props.isScorable&&!props.reviewMode&&!props.static&&!props.apiOptions.readOnly;const handleChange=newValue=>{props.handleUserInput({currentValue:newValue});props.trackInteraction();};const handleFocus=()=>{props.onFocus([]);setIsFocused(true);};const handleBlur=()=>{props.onBlur([]);setIsFocused(false);};const alignmentStyles=textAlign==="center"?styles$w.centerAlign:textAlign==="right"?styles$w.rightAlign:{};const legacyStylesToUse={...styles$w.inputWithExamples,...isFocused?styles$w.isFocused:{},...alignmentStyles,...size==="small"?styles$w.sizeSmall:{}};const classesToUse=[styles$x.inputWithExamples];if(isFocused){classesToUse.push(styles$x.isFocused);}if(textAlign!=="left"){const alignmentClass=textAlign==="center"?styles$x.centerAlign:styles$x.rightAlign;classesToUse.push(alignmentClass);}if(size==="small"){classesToUse.push(styles$x.sizeSmall);}if(props.apiOptions.customKeypad){const alignmentClass=textAlign==="center"?"perseus-input-center-align":textAlign==="right"?"perseus-input-right-align":undefined;return jsxRuntimeExports.jsx("div",{className:alignmentClass,children:jsxRuntimeExports.jsx(SimpleKeypadInput,{ref:inputRef,value:props.userInput.currentValue,keypadElement:props.keypadElement,onChange:handleChange,onFocus:handleFocus,onBlur:handleBlur,ariaRequired:isRequired})})}return jsxRuntimeExports.jsx(InputWithExamples,{ref:inputRef,value:props.userInput.currentValue,onChange:handleChange,labelText:labelText||context.strings.yourAnswerLabel,examples:generateExamples(answerForms,context.strings),shouldShowExamples:shouldShowExamples(answerForms),onFocus:handleFocus,onBlur:handleBlur,id:props.widgetId,disabled:props.apiOptions.readOnly,required:isRequired,style:legacyStylesToUse,className:classesToUse.join(" ")})});var NumericInput$1 = {name:"numeric-input",displayName:"Numeric input",widget:NumericInput,isLintable:true,getCorrectUserInput: getCorrectUserInput$8,getOneCorrectAnswerFromRubric,getStartUserInput: getStartUserInput$h,getUserInputFromSerializedState: getUserInputFromSerializedState$h};
1678
-
1679
- function getUserInputFromSerializedState$g(serializedState){return {currentValue:serializedState.currentValue}}var InputNumber = {name:"input-number",displayName:"Input number (deprecated - use numeric input instead)",hidden:true,widget:NumericInput$1.widget,isLintable:true,getOneCorrectAnswerFromRubric:NumericInput$1.getOneCorrectAnswerFromRubric,getStartUserInput:NumericInput$1.getStartUserInput,getCorrectUserInput:NumericInput$1.getCorrectUserInput,getUserInputFromSerializedState: getUserInputFromSerializedState$g};
1680
-
1681
- const MathRenderingContext=React.createContext({shouldAddAriaLabels:false});
1682
-
1683
- const getPromptJSON$o=(widgetData,userInput)=>{const choices=widgetData.options.choices||[];const options=choices.map(choice=>{const option={value:choice.content,id:choice.id};if(choice.rationale){option.rationale=choice.rationale;}return option});const hasNoneOfTheAbove=choices.some(choice=>choice.isNoneOfTheAbove);return {type:"radio",hasNoneOfTheAbove,options,userInput:{selectedOptions:userInput?.selectedChoiceIds??[]}}};
1684
-
1685
- var styles$v = {"scrollButtonsContainer":"perseus_kjDHiWdD"};
1686
-
1687
- const SCROLL_DISTANCE=100;const scrollInstances=new Map;function ScrollableArea({overflowX,overflowY,children,className,scrollDescription,style,role="group",id:providedId,...additionalProps}){const{strings}=usePerseusI18n();const containerRef=useRef(null);const[isScrollable,setIsScrollable]=useState(false);const[isScrolling,setIsScrolling]=useState(false);const generatedId=React.useId();const id=providedId||generatedId;const scrollableThreshold=React.useMemo(()=>{return window.innerWidth<=767?8:5},[]);const scroll=React.useCallback(direction=>{if(!containerRef.current||isScrolling){return}setIsScrolling(true);const contentIsRtl=getComputedStyle(containerRef.current).direction==="rtl";const scrollNegative=contentIsRtl&&direction==="end"||!contentIsRtl&&direction==="start";const scrollAmount=scrollNegative?-100:SCROLL_DISTANCE;containerRef.current.scrollBy({left:scrollAmount,behavior:"smooth"});setTimeout(()=>{setIsScrolling(false);},150);},[isScrolling]);const updateScrollState=React.useCallback(()=>{if(!containerRef.current){return}const{scrollLeft,scrollWidth,clientWidth}=containerRef.current;const newIsRtl=getComputedStyle(containerRef.current).direction==="rtl";const newIsScrollable=scrollWidth>clientWidth+scrollableThreshold;setIsScrollable(newIsScrollable);let newCanScrollStart;let newCanScrollEnd;if(newIsRtl){newCanScrollStart=scrollLeft<-scrollableThreshold;newCanScrollEnd=Math.abs(scrollLeft)<scrollWidth-clientWidth-scrollableThreshold;}else {newCanScrollStart=scrollLeft>scrollableThreshold;newCanScrollEnd=scrollLeft+clientWidth<scrollWidth-scrollableThreshold;}const scrollState={isScrollable:newIsScrollable,canScrollStart:newCanScrollStart,canScrollEnd:newCanScrollEnd,scroll,scrollDescription:scrollDescription||strings.scrollAnswers};scrollInstances.set(id,scrollState);},[id,scrollableThreshold,scrollDescription,strings.scrollAnswers,scroll]);useEffect(()=>{const container=containerRef.current;if(!container){return}updateScrollState();container.addEventListener("scroll",updateScrollState);window.addEventListener("resize",updateScrollState);return ()=>{container.removeEventListener("scroll",updateScrollState);window.removeEventListener("resize",updateScrollState);scrollInstances.delete(id);}},[children,updateScrollState,id]);const mergeStyle={overflowX:isScrollable&&overflowX==="auto"?"scroll":overflowX,overflowY:isScrollable&&overflowY==="auto"?"scroll":overflowY,scrollbarWidth:"thin",...style};return jsxRuntimeExports.jsx("div",{...additionalProps,id:id,role:role,className:className,style:mergeStyle,ref:containerRef,children:children})}function ScrollControls({target,scrollDescription:overrideDescription}){const{strings}=usePerseusI18n();const[scrollState,setScrollState]=useState(null);useEffect(()=>{if(!target){return}const checkForScrollState=()=>{const state=scrollInstances.get(target);if(state){setScrollState(state);}};checkForScrollState();const interval=setInterval(checkForScrollState,100);return ()=>{clearInterval(interval);}},[target]);if(!scrollState||!scrollState.isScrollable){return null}const description=overrideDescription||scrollState.scrollDescription;return jsxRuntimeExports.jsxs("div",{className:styles$v.scrollButtonsContainer,"aria-live":"polite",role:"group","aria-label":description,children:[jsxRuntimeExports.jsx(IconButton,{icon:caretLeftIcon,actionType:"neutral",kind:"secondary",size:"small",onClick:()=>scrollState.scroll("start"),"aria-label":strings.scrollStart,disabled:!scrollState.canScrollStart}),jsxRuntimeExports.jsx(IconButton,{icon:caretRightIcon,actionType:"neutral",kind:"secondary",size:"small",onClick:()=>scrollState.scroll("end"),"aria-label":strings.scrollEnd,disabled:!scrollState.canScrollEnd}),jsxRuntimeExports.jsx(BodyText,{size:"small",children:description})]})}const ScrollableView=ScrollableArea;ScrollableView.Controls=ScrollControls;
1688
-
1689
- var a11yStyles = {"srOnly":"perseus_BBUb6qxc"};
1690
-
1691
- var styles$u = {"base":"perseus_C4cWo-dY","is-correct":"perseus_vWc7XkhJ","isCorrect":"perseus_vWc7XkhJ","is-wrong":"perseus_yVmsF9sA","isWrong":"perseus_yVmsF9sA","icon":"perseus_brEUCVvd","circle-shape":"perseus_irgRpkgB","circleShape":"perseus_irgRpkgB","square-shape":"perseus_JsUZt48D","squareShape":"perseus_JsUZt48D"};
1692
-
1693
- const Indicator=props=>{const{checked,content,showCorrectness}=props;const indicatorId=useId();const ariaLabelledby=content.labelledBy?`${indicatorId} ${content.labelledBy}`:undefined;const ariaDisabled=showCorrectness?"true":"false";const iconImage=checked&&showCorrectness==="correct"?checkIcon:checked&&showCorrectness==="wrong"?minusIcon:undefined;const icon=iconImage?jsxRuntimeExports.jsx(PhosphorIcon,{"aria-hidden":true,className:styles$u.icon,icon:iconImage}):undefined;const classes=[styles$u.base,styles$u[props.shape+"-shape"]];if(showCorrectness){classes.push(styles$u["is-"+showCorrectness]);}const handleClick=showCorrectness?undefined:event=>{event.stopPropagation();props.updateChecked(!checked);};return jsxRuntimeExports.jsxs("button",{"aria-describedby":content.describedBy,"aria-disabled":ariaDisabled,"aria-pressed":checked,"aria-label":content.screenReader,"aria-labelledby":ariaLabelledby,className:classes.join(" "),id:indicatorId,type:"button",ref:props.buttonRef,onClick:handleClick,children:[icon,jsxRuntimeExports.jsx("span",{children:content.visible})]})};
1694
-
1695
- var styles$t = {"choice":"perseus_hm3uu-sq","is-correct":"perseus_qpU2z5U7","isCorrect":"perseus_qpU2z5U7","is-wrong":"perseus_dUXUrBDI","isWrong":"perseus_dUXUrBDI"};
1696
-
1697
- const Choice=props=>{const showCorrectness=props.showCorrectness;const buttonRef=useRef(null);const indicatorShape=props.isMultiSelect?"square":"circle";const clickHandler=showCorrectness?undefined:()=>{buttonRef.current?.click();};const classes=[styles$t.choice].concat(showCorrectness?[styles$t["is-"+showCorrectness]]:[]).join(" ");return jsxRuntimeExports.jsxs("li",{className:classes,onClick:clickHandler,role:"listitem",children:[jsxRuntimeExports.jsx(Indicator,{buttonRef:buttonRef,checked:props.checked,content:props.indicatorContent,shape:indicatorShape,showCorrectness:showCorrectness,updateChecked:props.updateChecked}),props.children]})};
1698
-
1699
- var styles$s = {"container":"perseus_yewUvpCl","choiceList":"perseus_ejJezW-c","content":"perseus_zAWs4E3G","instructions":"perseus_WyGpYl3q","rationale":"perseus_6vMrWVz0","isCorrect":"perseus_Zv66BVdg","reviewAnswers":"perseus_hJzSXKwq"};
1700
-
1701
- function getChoiceLetter(pos,strings){const lettersString=strings.letters;const letters=lettersString.split(" ");if(pos<letters.length){return letters[pos]}return " "}function hasChoiceData(state){return state!=null&&typeof state==="object"&&"choiceStates"in state&&"choices"in state&&Array.isArray(state.choiceStates)&&Array.isArray(state.choices)}function getUserInputFromSerializedState$f(serializedState){const selectedChoiceIds=[];if(hasChoiceData(serializedState)){const{choiceStates,choices}=serializedState;for(let i=0;i<choiceStates.length;i++){const choiceState=choiceStates[i];const choice=choices[i];if(choiceState?.selected&&choice?.id){selectedChoiceIds.push(choice.id);}}}return {selectedChoiceIds}}function moveNoneOfTheAboveToEnd(choices){let noneOfTheAbove=null;const newChoices=choices.filter((choice,index)=>{if(choice.isNoneOfTheAbove){noneOfTheAbove=choice;return false}return true});if(noneOfTheAbove){newChoices.push(noneOfTheAbove);}return newChoices}function enforceOrdering(choices,strings){const ReversedChoices=[[strings.false,strings.true],[strings.no,strings.yes]];const content=choices.map(c=>c.content);if(ReversedChoices.some(reversed=>_.isEqual(content,reversed))){return [choices[1],choices[0]]}return choices}function choiceTransform(choices,randomize,strings,seed){const choicesWithMetadata=choices.map((choice,i)=>{return {...choice,originalIndex:i,correct:Boolean(choice.correct)}});return moveNoneOfTheAboveToEnd(enforceOrdering(randomize?shuffle(choicesWithMetadata,seed):choicesWithMetadata,strings))}
1702
-
1703
- const getInstructionsText=({multipleSelect,countChoices,numCorrect,strings})=>{if(multipleSelect){if(usesNumCorrect(multipleSelect,!!countChoices,numCorrect)){return strings.chooseNumAnswers({numCorrect:String(numCorrect)})}return strings.chooseAllAnswers}return strings.chooseOneAnswer};
1704
-
1705
- const RadioComponent=({choices,countChoices,multipleSelect=false,numCorrect,onChoiceChange,reviewMode,isRequired=false})=>{const{strings}=usePerseusI18n();const legendId=useId();const containerRef=useRef(null);const[backgroundColor,setBackgroundColor]=useState("transparent");useEffect(()=>{const container=containerRef.current;if(container){setBackgroundColor(getBackgroundColor(container));}},[]);useTimeout(()=>{const container=containerRef.current;if(container){setBackgroundColor(getBackgroundColor(container));}},100);const instructions=getInstructionsText({multipleSelect,countChoices,numCorrect,strings});const choiceListClasses=reviewMode?`${styles$s.choiceList} ${styles$s.reviewAnswers}`:styles$s.choiceList;const cssVariableDeclaration=backgroundColor!=="transparent"?{"--perseus-widget-background-color":backgroundColor}:undefined;const scrollId=useId()+"-scroll";return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs("fieldset",{className:styles$s.container,ref:containerRef,style:cssVariableDeclaration,children:[jsxRuntimeExports.jsxs("legend",{id:legendId,"aria-hidden":"true",className:styles$s.instructions,children:[instructions,isRequired&&jsxRuntimeExports.jsxs("span",{className:a11yStyles.srOnly,children:[" ",strings.required]})]}),jsxRuntimeExports.jsx(ScrollableView,{id:scrollId,overflowX:"auto",children:jsxRuntimeExports.jsx("ul",{"data-widget":"radio","aria-labelledby":legendId,className:choiceListClasses,role:"list",children:jsxRuntimeExports.jsx(ChoiceListItems,{choices:choices,i18nStrings:strings,onChoiceChange:onChoiceChange,reviewMode:reviewMode,multipleSelect:multipleSelect})})})]}),jsxRuntimeExports.jsx(ScrollableView.Controls,{target:scrollId})]})};const ChoiceListItems=props=>{const{choices,i18nStrings,multipleSelect,onChoiceChange,reviewMode}=props;const listId=useId();const items=choices.map((choice,i)=>{const updateChecked=isChecked=>{onChoiceChange(choice.id,isChecked);};const contentId=`${listId}-choice-${i+1}`;const choiceLetter=getChoiceLetter(i,i18nStrings);const srContent=reviewMode&&choice.correct?i18nStrings.choiceCorrect:i18nStrings.choice;const indicatorContent={visible:choiceLetter,screenReader:srContent({letter:choiceLetter}),labelledBy:contentId};const showCorrectness=reviewMode?choice.correct?"correct":"wrong":undefined;const content=choice.isNoneOfTheAbove?i18nStrings.noneOfTheAbove:choice.content;let rationale;if(reviewMode&&choice.hasRationale){const rationaleId=`${contentId}-rationale`;indicatorContent.describedBy=rationaleId;const rationaleClasses=showCorrectness==="correct"?`${styles$s.rationale} ${styles$s.isCorrect}`:styles$s.rationale;rationale=jsxRuntimeExports.jsx("div",{id:rationaleId,className:rationaleClasses,children:choice.rationale});}return jsxRuntimeExports.jsx(Choice,{checked:choice.checked,indicatorContent:indicatorContent,isMultiSelect:multipleSelect,showCorrectness:showCorrectness,updateChecked:updateChecked,children:jsxRuntimeExports.jsxs("div",{className:styles$s.content,children:[jsxRuntimeExports.jsx("div",{id:contentId,children:content}),rationale]})},choice.id)});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:items})};
1706
-
1707
- const getChoiceStates=({choices,showSolutions,choiceStates,reviewMode})=>{if(showSolutions==="all"||reviewMode){return choices.map(choice=>({selected:!!choice.correct}))}if(choiceStates){return choiceStates}return choices.map(()=>({selected:false}))};
1708
-
1709
- const RadioWidget=forwardRef(function RadioWidget(props,ref){const{options}=props;const{multipleSelect=false,countChoices=false}=options;const{showSolutions="none",apiOptions,handleUserInput,trackInteraction,findWidgets,reviewMode,widgetId}=props;const{strings}=usePerseusI18n();const{analytics}=useDependencies();const randomSeed=(props.problemNum??0)+(props.widgetIndex??0);const choices=useMemo(()=>{return [...choiceTransform(options.choices,options.randomize,strings,randomSeed)]},[options.choices,options.randomize,strings,randomSeed]);useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:multipleSelect?"multiple-select":"single-select",widgetType:"radio",widgetId:widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON:()=>{return getPromptJSON$o({...props,options:{...props.options,choices}},props.userInput)},getSerializedState(){const{userInput,static:_1,options,...otherProps}=props;const{randomize,...otherOptions}=options;return {...otherOptions,...otherProps,numCorrect:options.numCorrect??0,choices,hasNoneOfTheAbove:options.hasNoneOfTheAbove??false,choiceStates:choices.map(choice=>{const selected=props.userInput?.selectedChoiceIds.includes(choice?.id)??false;return {selected,highlighted:false,readOnly:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false}})}}}),[choices,props]);const renderContent=(content="")=>{const linterContext={contentType:"radio",highlightLint:false,stack:[]};return jsxRuntimeExports.jsx(MathRenderingContext.Provider,{value:{shouldAddAriaLabels:true},children:jsxRuntimeExports.jsx(Renderer,{apiOptions:apiOptions,content:content,findExternalWidgets:findWidgets,alwaysUpdate:true,linterContext:linterContext,strings:strings},"choiceContentRenderer")})};const handleChoiceChange=(choiceId,newCheckedState)=>{const checkedChoiceIds=[];const choiceStates=choices.map(choice=>{return {selected:props.userInput?.selectedChoiceIds.includes(choice.id)??false,id:choice.id}});const currentSelectedIds=choiceStates.filter(choice=>choice.selected).map(choice=>choice.id);if(newCheckedState&&!multipleSelect){checkedChoiceIds.push(choiceId);}else if(newCheckedState&&multipleSelect){checkedChoiceIds.push(...currentSelectedIds,choiceId);}else {checkedChoiceIds.push(...currentSelectedIds.filter(id=>id!==choiceId));}handleUserInput({selectedChoiceIds:checkedChoiceIds});trackInteraction();announceChoiceChange(checkedChoiceIds.length);};const announceChoiceChange=newCheckedCount=>{let screenReaderMessage="";if(!multipleSelect){screenReaderMessage=newCheckedCount===0?strings.notSelected:"";}else {screenReaderMessage=strings.choicesSelected({num:newCheckedCount});}announceMessage({message:screenReaderMessage});if(multipleSelect){setTimeout(()=>{announceMessage({message:""});},300);}};const buildChoiceProps=choiceStates=>{return choices.map((choice,i)=>{const content=choice.isNoneOfTheAbove&&!choice.content?strings.noneOfTheAbove:choice.content;const{selected=false}=choiceStates[i]??{};return {id:choice.id,content:renderContent(content),checked:selected,correct:!!choice.correct,hasRationale:!!choice.rationale,rationale:renderContent(choice.rationale),isNoneOfTheAbove:!!choice.isNoneOfTheAbove}})};const prepareChoicesProps=()=>{const choiceStates=choices.map(choice=>{return {selected:props.userInput?.selectedChoiceIds.includes(choice.id)??false}});const processedChoiceStates=getChoiceStates({choices,showSolutions,choiceStates,reviewMode});return buildChoiceProps(processedChoiceStates)};const choicesProps=prepareChoicesProps();const numCorrect=options.numCorrect;const isReviewMode=reviewMode||showSolutions==="all";const onChoiceChange=apiOptions.readOnly||isReviewMode?()=>{}:handleChoiceChange;const isRequired=props.isScorable&&!isReviewMode&&!props.static&&!apiOptions.readOnly;return jsxRuntimeExports.jsx(RadioComponent,{reviewMode:isReviewMode,isRequired:isRequired,multipleSelect:multipleSelect,countChoices:countChoices,numCorrect:numCorrect,choices:choicesProps,onChoiceChange:onChoiceChange})});let Radio$1 = class Radio extends React.Component{getSerializedState(){if(!this.radioRef.current){throw new Error("Radio widget is not mounted; getSerializedState is unavailable.")}return this.radioRef.current.getSerializedState()}getPromptJSON(){if(!this.radioRef.current){throw new Error("Radio widget is not mounted; getPromptJSON is unavailable.")}return this.radioRef.current.getPromptJSON()}render(){return jsxRuntimeExports.jsx(RadioWidget,{ref:this.radioRef,...this.props})}constructor(...args){super(...args),this.radioRef=React.createRef();}};
1710
-
1711
- function getStartUserInput$g(){return {selectedChoiceIds:[]}}var Radio = {name:"radio",displayName:"Radio / Multiple choice",widget:Radio$1,getStartUserInput: getStartUserInput$g,isLintable:true,getUserInputFromSerializedState:serializedState=>{return getUserInputFromSerializedState$f(serializedState)}};
1712
-
1713
- var basicWidgets = [Radio,InputNumber,NumericInput$1,Expression$1];
1714
-
1715
- function tileDragId(data){return data.fromBlankId!=null?`placed__${data.fromBlankId}__${data.tileId}`:`bank__${data.tileId}`}function readTileDragData(data){const tileId=data?.tileId;if(typeof tileId!=="string"){return null}const fromBlankId=data?.fromBlankId;return typeof fromBlankId==="string"?{tileId,fromBlankId}:{tileId}}
1716
-
1717
- var styles$r = {"container":"perseus_w5JEPtr3","superSub":"perseus_YYUlZ0FC","superscript":"perseus_zuqfZw15","subscript":"perseus_WBbw9tQT","filled":"perseus_1Uom-GrS","keepsWidth":"perseus_djiO5HzC","dropTarget":"perseus_ZiDXp0R-"};
1718
-
1719
- function BlankComponent(props){const{blankId,displayType,children,minWidth,keepsWidthWhenFilled,className,testId}=props;const{ref,isDropTarget}=useDroppable({id:blankId});const{source}=useDragOperation();const isFilled=React.Children.toArray(children).length>0;const dragged=readTileDragData(source?.data);const isTileDraggingOut=isFilled&&dragged?.fromBlankId===blankId;const showsPlacedTile=isFilled&&!isTileDraggingOut;const minWidthStyle=minWidth!=null?{"--blank-min-inline-size":`${minWidth}px`}:undefined;const slotClasses=classNames$2(styles$r.container,DISPLAY_TYPE_CLASSES[displayType],showsPlacedTile&&styles$r.filled,keepsWidthWhenFilled&&styles$r.keepsWidth,isDropTarget&&styles$r.dropTarget,className);return jsxRuntimeExports.jsx("div",{ref:ref,className:slotClasses,style:minWidthStyle,"data-blank":"true","data-testid":testId,children:children})}const DISPLAY_TYPE_CLASSES={normal:undefined,superscript:classNames$2(styles$r.superSub,styles$r.superscript),subscript:classNames$2(styles$r.superSub,styles$r.subscript)};
1720
-
1721
- const BlankWidget=forwardRef(function BlankWidget(props,ref){useImperativeHandle(ref,()=>({}));return jsxRuntimeExports.jsx(BlankComponent,{blankId:props.widgetId,displayType:props.options.displayType,testId:"blank-widget"})});var Blank = {name:"blank",displayName:"Blank",widget:BlankWidget,isLintable:true,hidden:true};
1722
-
1723
- const{pureXsMax,pureSmMax,pureMdMin,pureMdMax,pureLgMin,pureLgMax}=constants;var mediaQueries = {md:`@media screen and (min-width: ${pureMdMin}) and `+`(max-width: ${pureMdMax})`,xsOrSmaller:`@media screen and (max-width: ${pureXsMax})`,smOrSmaller:`@media screen and (max-width: ${pureSmMax})`,mdOrSmaller:`@media screen and (max-width: ${pureMdMax})`,lgOrSmaller:`@media screen and (max-width: ${pureLgMax})`,lgOrLarger:`@media screen and (min-width: ${pureLgMin})`};
1724
-
1725
- const{circleSize,radioMarginWidth}=constants;var sharedStyles = StyleSheet.create({blankBackground:{backgroundColor:semanticColor.core.background.base.default},perseusSrOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1},responsiveLabel:{[mediaQueries.smOrSmaller]:{fontSize:14,lineHeight:1.3},[mediaQueries.md]:{fontSize:17,lineHeight:1.4},[mediaQueries.lgOrLarger]:{fontSize:20,lineHeight:1.4}},responsiveInput:{display:"inline-block",WebkitAppearance:"none",appearance:"none","::-ms-check":{display:"none"},backgroundColor:semanticColor.core.background.base.default,border:`${border$1.width.medium} solid ${semanticColor.core.background.base.default}`,boxShadow:`0 0px 0px ${border$1.width.medium} ${semanticColor.core.border.neutral.subtle}`,outline:"none",boxSizing:"border-box",flexShrink:0,marginBlockEnd:1,marginInlineStart:1,marginInlineEnd:1,marginBlockStart:1,height:circleSize-2,width:circleSize-2},responsiveRadioInput:{borderRadius:"50%",":checked":{backgroundColor:semanticColor.core.foreground.instructive.default,border:"none",borderRadius:"50%",boxShadow:`inset 0px 0px 0px 2px ${semanticColor.core.background.base.default}, `+`0 0px 0px 2px ${semanticColor.core.foreground.instructive.default}`,marginBlockStart:radioMarginWidth,marginBlockEnd:radioMarginWidth,marginInlineStart:radioMarginWidth,marginInlineEnd:radioMarginWidth,height:circleSize-2*radioMarginWidth,width:circleSize-2*radioMarginWidth}},responsiveRadioInputStatic:{":checked":{backgroundColor:semanticColor.core.foreground.disabled.strong,boxShadow:`inset 0px 0px 0px 2px ${semanticColor.core.background.base.default}, `+`0 0px 0px 2px ${semanticColor.core.foreground.disabled.strong}`}},responsiveRadioInputActive:{backgroundColor:semanticColor.core.background.base.default,border:`${border$1.width.medium} solid ${semanticColor.core.background.base.default}`,borderRadius:"50%",boxShadow:`0 0px 0px 2px ${semanticColor.core.border.neutral.strong}`,marginBlockStart:radioMarginWidth,marginBlockEnd:radioMarginWidth,marginInlineStart:radioMarginWidth,marginInlineEnd:radioMarginWidth,height:circleSize-2*radioMarginWidth,width:circleSize-2*radioMarginWidth,":checked":{backgroundColor:semanticColor.core.background.base.default}},disableTextSelection:{userSelect:"none"}});
1726
-
1727
- const getPromptJSON$n=widgetData=>{return {type:"categorizer",options:{items:widgetData.options.items,categories:widgetData.options.categories},userInput:{itemToCategoryMapping:widgetData.userInput.values}}};
1728
-
1729
- const Categorizer=forwardRef(function Categorizer(props,ref){const{items,categories,randomizeItems}=props.options;const{userInput,problemNum,apiOptions,linterContext,handleUserInput,trackInteraction}=props;const dependencies=useDependencies();const{strings}=usePerseusI18n();const idPrefix=useMemo(()=>_.uniqueId("perseus_radio_"),[]);useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"categorizer",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON:()=>getPromptJSON$n(props),getSerializedState(){const{userInput,options,...rest}=props;return {...options,...rest,values:userInput.values}}}));function _handleUserInput(itemNum,catNum){const values=[...userInput.values];values[itemNum]=catNum;handleUserInput({values});trackInteraction();}let indexedItems=items.map((item,n)=>[item,n]);if(randomizeItems){indexedItems=shuffle(indexedItems,problemNum);}const table=jsxRuntimeExports.jsxs("table",{className:"categorizer-table "+css(styles$q.mobileTable),children:[jsxRuntimeExports.jsx("thead",{children:jsxRuntimeExports.jsxs("tr",{children:[jsxRuntimeExports.jsx("td",{className:css(styles$q.emptyHeaderCell)}),categories.map((category,i)=>{return jsxRuntimeExports.jsx("th",{className:css(styles$q.header),children:jsxRuntimeExports.jsx(Renderer,{content:category,linterContext:linterContext,strings:strings,apiOptions:apiOptions})},i)})]})}),jsxRuntimeExports.jsx("tbody",{children:indexedItems.map(indexedItem=>{const item=indexedItem[0];const itemNum=indexedItem[1];const uniqueId=idPrefix+"_"+itemNum;return jsxRuntimeExports.jsxs("tr",{children:[jsxRuntimeExports.jsx("td",{children:jsxRuntimeExports.jsx(Renderer,{content:item,linterContext:linterContext,strings:strings,apiOptions:apiOptions})}),categories.map((catName,catNum)=>{const selected=userInput.values[itemNum]===catNum;return jsxRuntimeExports.jsx("td",{className:"category "+css(styles$q.cell),children:jsxRuntimeExports.jsxs("div",{role:"button","aria-label":catName,onClick:()=>_handleUserInput(itemNum,catNum),children:[apiOptions.isMobile&&jsxRuntimeExports.jsx("input",{type:"radio",name:uniqueId,className:css(sharedStyles.responsiveInput,sharedStyles.responsiveRadioInput,props.static&&sharedStyles.responsiveRadioInputStatic),checked:selected,onChange:()=>_handleUserInput(itemNum,catNum),onClick:e=>e.stopPropagation()}),!apiOptions.isMobile&&jsxRuntimeExports.jsx("span",{className:css(styles$q.radioSpan,selected&&styles$q.checkedRadioSpan,props.static&&selected&&styles$q.staticCheckedRadioSpan),children:selected?jsxRuntimeExports.jsx(InlineIcon,{...iconCircle}):jsxRuntimeExports.jsx(InlineIcon,{...iconCircleThin})})]})},catNum)})]},itemNum)})})]});const extraClassNames=classNames$2({"categorizer-container":true,"static-mode":props.static});const inlineStyles=apiOptions.isMobile?[styles$q.fullBleedContainer]:[];return jsxRuntimeExports.jsx("div",{className:extraClassNames+" "+css(...inlineStyles),children:table})});const styles$q=StyleSheet.create({mobileTable:{[mediaQueries.smOrSmaller]:{minInlineSize:"auto"}},fullBleedContainer:{[mediaQueries.mdOrSmaller]:{marginInlineStart:-16,marginInlineEnd:-16,overflowX:"auto"}},header:{textAlign:"center",verticalAlign:"bottom"},cell:{textAlign:"center",padding:0,color:semanticColor.core.border.neutral.subtle,verticalAlign:"middle"},emptyHeaderCell:{backgroundColor:"inherit",borderBlockEnd:`${border$1.width.medium} solid ${semanticColor.core.border.neutral.subtle}`},radioSpan:{fontSize:sizing.size_280,paddingInlineEnd:3,cursor:"pointer",":hover":{color:semanticColor.core.foreground.instructive.subtle}},checkedRadioSpan:{color:semanticColor.core.foreground.instructive.default},staticCheckedRadioSpan:{color:semanticColor.core.foreground.disabled.strong}});function getUserInputFromSerializedState$e(serializedState){return {values:serializedState.values}}function getCorrectUserInput$7(options){return {values:options.values}}function getStartUserInput$f(){return {values:[]}}var Categorizer$1 = {name:"categorizer",displayName:"Categorizer",widget:Categorizer,getUserInputFromSerializedState: getUserInputFromSerializedState$e,getCorrectUserInput: getCorrectUserInput$7,getStartUserInput: getStartUserInput$f,isLintable:true};
1730
-
1731
- const isFileProtocol=protocol=>{if(protocol&&protocol.toLowerCase()==="file:"){return true}return false};
1732
-
1733
- let _cachedClientLocation;const location=()=>{if(!_cachedClientLocation){_cachedClientLocation=window.location;}return _cachedClientLocation};const parseUrl=url=>new URL(url,location().origin);const toAbsoluteUrl=url=>parseUrl(url).href;
1734
-
1735
- const getUnsupportedPromptJSON=(widgetType,message="")=>{return {type:widgetType,isSupported:false,message}};
1736
-
1737
- const getPromptJSON$m=()=>{return getUnsupportedPromptJSON("cs-program")};
1738
-
1739
- const{updateQueryString: updateQueryString$1}=Util;function getUrlFromProgramID$1(programID){const{InitialRequestUrl}=getDependencies();const path="/computer-programming/program/"+`${programID}/embedded?embed=yes&author=no`;if(isFileProtocol(InitialRequestUrl.protocol)){return `https://khanacademy.org${path}`}return toAbsoluteUrl(path)}const CSProgram=forwardRef(function CSProgram(props,ref){const{strings,locale}=usePerseusI18n();const{programID,programType,height,settings,showEditor=false,showButtons=false}=props.options;useEffect(()=>{const handleMessageEvent=e=>{let data={};try{data=JSON.parse(e.data);}catch{return}if(data.testsPassed===undefined){return}const status=data.testsPassed?"correct":"incorrect";props.handleUserInput({status:status,message:data.message});};window.addEventListener("message",handleMessageEvent);return ()=>{window.removeEventListener("message",handleMessageEvent);}},[props]);useImperativeHandle(ref,()=>({getPromptJSON:()=>{return getPromptJSON$m()},getSerializedState:()=>{const{userInput,alignment,options,...rest}=props;return {...options,...rest,programType:options.programType||null}}}));if(!programID){return jsxRuntimeExports.jsx("div",{})}let styleContainer=false;let url=getUrlFromProgramID$1(programID);let className;if(showEditor){url+="&editor=yes";className="perseus-scratchpad-editor";}else {url+=`&editor=no&width=${articleMaxWidthInPx}`;className="perseus-scratchpad";if(programType!=="webpage"){styleContainer=true;}}if(showButtons){url+="&buttons=yes";}else {url+="&buttons=no";}if(settings){const settingsObject={};settings.forEach(setting=>{if(setting.name&&setting.value){settingsObject[setting.name]=setting.value;}});url=updateQueryString$1(url,"settings",JSON.stringify(settingsObject));}if(locale){url=updateQueryString$1(url,"lang",locale);}const style={height:showButtons?height+67:height,width:"100%"};const sandboxOptions=["allow-popups","allow-same-origin","allow-scripts","allow-top-navigation"].join(" ");return jsxRuntimeExports.jsx("div",{className:css(styleContainer&&styles$p.container),children:jsxRuntimeExports.jsx("iframe",{title:strings.computerScienceProgram,sandbox:sandboxOptions,src:url,style:style,className:className,allowFullScreen:true})})});const styles$p=StyleSheet.create({container:{margin:"auto"}});function getUserInputFromSerializedState$d(serializedState){return {status:serializedState.status,message:serializedState.message}}function getStartUserInput$e(){return {status:"incomplete",message:null}}var CSProgram$1 = {name:"cs-program",displayName:"CS Program",widget:CSProgram,hidden:true,getStartUserInput: getStartUserInput$e,getUserInputFromSerializedState: getUserInputFromSerializedState$d};
1740
-
1741
- const getPromptJSON$l=widgetData=>{return {type:"definition",definition:widgetData.options.definition,togglePrompt:widgetData.options.togglePrompt}};
1742
-
1743
- var styles$o = {"definition":"perseus_5CDFHduT"};
1744
-
1745
- const styles$n={tooltipBody:{color:"var(--wb-semanticColor-core-foreground-neutral-strong)",fontSize:"var(--wb-font-body-size-medium)",fontWeight:"var(--wb-font-weight-medium)",lineHeight:"var(--wb-font-body-lineHeight-medium)"}};
1746
-
1747
- const Definition=forwardRef(function Definition(props,ref){const{strings}=usePerseusI18n();const dependencies=useDependencies();useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"definition",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON(){return getPromptJSON$l(props)}}));return jsxRuntimeExports.jsx(DefinitionConsumer,{children:({activeDefinitionId,setActiveDefinitionId})=>jsxRuntimeExports.jsx(Popover,{dismissEnabled:true,content:jsxRuntimeExports.jsx(PopoverContentCore,{style:styles$n.tooltipBody,closeButtonVisible:true,children:jsxRuntimeExports.jsx("div",{className:"perseus-in-wb-popover",children:jsxRuntimeExports.jsx(Renderer,{apiOptions:props.apiOptions,content:props.options.definition,strings:strings})})}),opened:activeDefinitionId===props.widgetId,onClose:()=>setActiveDefinitionId(null),placement:"top",children:jsxRuntimeExports.jsx(Clickable,{onClick:()=>{props.trackInteraction();setActiveDefinitionId(props.widgetId);},"aria-label":strings.definitionIdentifier({word:props.options.togglePrompt}),children:()=>jsxRuntimeExports.jsx("span",{className:styles$o.definition,children:props.options.togglePrompt})})})})});var Definition$1 = {name:"definition",displayName:"Definition",widget:Definition};
1748
-
1749
- const getPromptJSON$k=widgetData=>{return {type:"dropdown",options:{items:widgetData.options.choices.map(choice=>choice.content)},userInput:{selectedIndex:widgetData.userInput.value-1}}};
1750
-
1751
- const Dropdown=forwardRef(function Dropdown(props,ref){const{strings}=usePerseusI18n();const dropdownId=useId();const{choices=[],placeholder="",visibleLabel,ariaLabel}=props.options;const{apiOptions=ApiOptions.defaults,userInput={value:0},widgetId,trackInteraction,handleUserInput}=props;const isStatic=props.static??false;const dependencies=useDependencies();const isRequired=props.isScorable&&!props.reviewMode&&!isStatic&&!apiOptions.readOnly;useEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"dropdown",widgetId:widgetId}});},[]);const handleChange=selected=>{trackInteraction();handleUserInput({value:selected});};const rootRef=useRef(null);useImperativeHandle(ref,()=>({focus:()=>{if(apiOptions.readOnly||isStatic){return false}if(!rootRef.current){return false}const button=rootRef.current.querySelector("[role='combobox']");if(!(button instanceof HTMLElement)){return false}if(button instanceof HTMLButtonElement&&button.disabled||button.getAttribute("aria-disabled")==="true"){return false}const previouslyFocused=document.activeElement;button.focus();return document.activeElement===button&&previouslyFocused!==button},getPromptJSON:()=>{return getPromptJSON$k(props)},getSerializedState:()=>{const{userInput,options,...otherProps}=props;const{choices,...otherOptions}=options;return {...otherOptions,...otherProps,choices:choices.map(choice=>choice.content),selected:userInput.value}}}));const children=[jsxRuntimeExports.jsx(OptionItem,{value:"0",disabled:true,label:jsxRuntimeExports.jsx("div",{className:"perseus-in-wb-popover",children:jsxRuntimeExports.jsx(Renderer,{content:placeholder,strings:strings,apiOptions:{flags:apiOptions.flags}})}),labelAsText:placeholder},"placeholder"),...choices.map((choice,i)=>jsxRuntimeExports.jsx(OptionItem,{value:String(i+1),label:jsxRuntimeExports.jsx("div",{className:"perseus-in-wb-popover",children:jsxRuntimeExports.jsx(Renderer,{content:choice.content,strings:strings,apiOptions:{flags:apiOptions.flags}})}),labelAsText:choice.content},String(i+1)))];return jsxRuntimeExports.jsxs(View,{ref:rootRef,onClick:e=>{e.stopPropagation();},onTouchStart:e=>{e.stopPropagation();},children:[visibleLabel&&jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"label",htmlFor:dropdownId,children:visibleLabel}),jsxRuntimeExports.jsx(SingleSelect,{id:dropdownId,placeholder:"",className:"perseus-dropdown",onChange:value=>handleChange(parseInt(value)),selectedValue:String(userInput.value),disabled:Boolean(apiOptions.readOnly||isStatic),"aria-required":isRequired,"aria-label":ariaLabel||visibleLabel||strings.selectAnAnswer,showOpenerLabelAsText:false,children:children})]})});function getUserInputFromSerializedState$c(serializedState){return {value:serializedState.selected}}function getStartUserInput$d(){return {value:0}}function getCorrectUserInput$6(options){return {value:options.choices.findIndex(c=>c.correct)+1}}var Dropdown$1 = {name:"dropdown",displayName:"Drop down",widget:Dropdown,getStartUserInput: getStartUserInput$d,getCorrectUserInput: getCorrectUserInput$6,getUserInputFromSerializedState: getUserInputFromSerializedState$c};
1752
-
1753
- function sharedInitializeUserInput(widgetOptions,problemNum){const startUserInput={};if(!widgetOptions){return startUserInput}Object.entries(widgetOptions).forEach(([id,widgetInfo])=>{const widgetExports=getWidgetExport(widgetInfo.type);if(widgetInfo.static&&widgetExports?.getCorrectUserInput){startUserInput[id]=widgetExports.getCorrectUserInput(widgetInfo.options);}else if(widgetExports?.getStartUserInput){startUserInput[id]=widgetExports.getStartUserInput(widgetInfo.options,problemNum??0);}});return startUserInput}function deriveUserInputFromSerializedState(serializedState,widgetsMap){const restoredUserInput={};Object.entries(serializedState).forEach(([widgetId,props])=>{const widgetType=getWidgetTypeByWidgetId(widgetId,widgetsMap);const widgetExport=getWidgetExport(widgetType);if(widgetExport?.getUserInputFromSerializedState){const restoreResult=widgetExport.getUserInputFromSerializedState(props,widgetsMap[widgetId].options);restoredUserInput[widgetId]=restoreResult;}});return restoredUserInput}function UserInputManager(props){const[userInput,setUserInput]=useState(props.initialUserInput||sharedInitializeUserInput(props.widgets,props.problemNum??0));function handleUserInput(id,nextUserInput,widgetsEmpty){const next={...userInput,[id]:nextUserInput};setUserInput(next);props.handleUserInput?.(next,widgetsEmpty);}function initializeUserInput(widgetOptions,problemNum){setUserInput(props.initialUserInput||sharedInitializeUserInput(widgetOptions,problemNum));}return props.children({userInput,handleUserInput,initializeUserInput})}
1754
-
1755
- const getPromptJSON$j=widgetData=>{return {type:"explanation",showPrompt:widgetData.options.showPrompt,explanation:widgetData.options.explanation}};
1756
-
1757
- var styles$m = {"content":"perseus_HDIlPzEz","contentCollapsed":"perseus_NkFQFgcZ","contentExpanded":"perseus_XhV-9haB","contentWrapper":"perseus_WEJESS6h","transitionCollapsed":"perseus_sbBrAODD","transitionExpanded":"perseus_Wp72j6qk"};
1758
-
1759
- const styles$l={buttonStyleOverrides:{height:"auto",lineHeight:"inherit",marginLeft:"-0.2rem",marginRight:"0.2rem",paddingLeft:"0.2rem"},content:{borderLeft:"0px solid var(--wb-semanticColor-core-border-neutral-subtle)",display:"inline-grid",position:"relative"},contentCollapsed:{gridTemplateColumns:"0fr",gridTemplateRows:"0fr",marginBottom:"0",marginTop:"0",minWidth:"0",paddingBottom:"0",visibility:"hidden"},contentExpanded:{borderLeftWidth:"5px",gridTemplateColumns:"1fr",gridTemplateRows:"1fr",marginBottom:"1.4rem",marginLeft:"-2.3rem",marginTop:"1.4rem",minWidth:"100%",paddingBottom:"1rem",paddingLeft:"2.3rem",visibility:"visible"},contentWrapper:{overflow:"hidden"},labelStyle:{fontSize:"var(--wb-font-heading-size-medium)",lineHeight:"inherit",marginRight:"-0.6rem",textAlign:"left",whiteSpace:"normal"},transitionCollapsed:{transition:"all 0.25s step-end, grid-template-rows 0.25s, margin-top 0.25s, margin-bottom 0.25s, padding-bottom 0.25s"},transitionExpanded:{transition:"grid-template-rows 0.5s, margin-top 0.5s, margin-bottom 0.5s, padding-bottom 0.5s"}};
1760
-
1761
- function mediaQueryIsMatched(mediaQuery){if(typeof window.matchMedia!=="function"){return false}return window.matchMedia(mediaQuery).matches}const Explanation=forwardRef(function Explanation(props,ref){const{strings}=usePerseusI18n();const dependencies=useDependencies();const[expanded,setExpanded]=useState(false);const contentId=useId();const{hidePrompt,showPrompt,explanation,widgets}=props.options;useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"explanation",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON(){return getPromptJSON$j(props)}}));function onClick(){setExpanded(!expanded);props.trackInteraction();}const legacyContentStyling=[styles$l.content,expanded?styles$l.contentExpanded:styles$l.contentCollapsed,mediaQueryIsMatched("(prefers-reduced-motion: no-preference)")&&(expanded?styles$l.transitionExpanded:styles$l.transitionCollapsed)];const contentClasses=[styles$m.content,expanded?styles$m.contentExpanded:styles$m.contentCollapsed,expanded?styles$m.transitionExpanded:styles$m.transitionCollapsed];return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Button,{"aria-expanded":expanded,"aria-controls":contentId,endIcon:expanded?caretUp:caretDown,kind:"tertiary",labelStyle:styles$l.labelStyle,onClick:onClick,size:"small",style:styles$l.buttonStyleOverrides,children:expanded?hidePrompt:showPrompt}),jsxRuntimeExports.jsx(View,{id:contentId,style:legacyContentStyling,className:contentClasses.join(" "),"aria-hidden":!expanded,testId:"content-container",children:jsxRuntimeExports.jsx(View,{className:styles$m.contentWrapper,style:styles$l.contentWrapper,children:jsxRuntimeExports.jsx(UserInputManager,{widgets:widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>{return jsxRuntimeExports.jsx(Renderer,{apiOptions:props.apiOptions,content:explanation,widgets:widgets,linterContext:props.linterContext,strings:strings,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput})}})})})]})});var Explanation$1 = {name:"explanation",displayName:"Explanation",widget:Explanation,isLintable:true};
1762
-
1763
- const FillInTheBlankWidget=forwardRef(function FillInTheBlankWidget(props,ref){useImperativeHandle(ref,()=>({}));if(!isFeatureOn(props,"dnd-widget-fitb")){return null}return jsxRuntimeExports.jsx("div",{"data-testid":"fill-in-the-blank-widget",children:"Fill in the Blank"})});var FillInTheBlank = {name:"fill-in-the-blank",displayName:"Fill in the Blank",widget:FillInTheBlankWidget,isLintable:false,hidden:true};
1764
-
1765
- const FreeResponse=forwardRef(function FreeResponse({options,userInput,handleUserInput,isScorable,reviewMode,static:isStatic,apiOptions},_ref){const{strings}=usePerseusI18n();const isRequired=isScorable&&!reviewMode&&!isStatic&&!apiOptions.readOnly;const{allowUnlimitedCharacters,characterLimit,question,placeholder}=options;const characterCount=userInput.currentValue.replace(/\n/g,"").length;const isOverLimit=!allowUnlimitedCharacters&&characterCount>characterLimit;const characterCountText=allowUnlimitedCharacters?undefined:strings.characterCount({used:characterCount,num:characterLimit});if(characterCountText){announceMessage({message:characterCountText,level:isOverLimit?"assertive":"polite",debounceThreshold:750});}return jsxRuntimeExports.jsx(View,{style:styles$k.container,className:"free-response",children:jsxRuntimeExports.jsx(LabeledField,{label:jsxRuntimeExports.jsx(View,{className:"free-response-question",children:jsxRuntimeExports.jsx(Renderer,{content:question,strings:strings,apiOptions:apiOptions})}),field:jsxRuntimeExports.jsx(TextArea,{"aria-required":isRequired,error:isOverLimit,onChange:newValue=>handleUserInput({currentValue:newValue}),placeholder:placeholder,style:styles$k.textarea,value:userInput.currentValue}),additionalHelperMessage:jsxRuntimeExports.jsxs("p",{className:css(styles$k.characterCountText,isOverLimit?styles$k.overCharacterLimit:undefined),children:[isOverLimit&&jsxRuntimeExports.jsx(PhosphorIcon,{"aria-label":"Error:",icon:warningCircleIcon$1,size:"small",style:styles$k.warningCircleIcon}),characterCountText]})})})});function getStartUserInput$c(){return {currentValue:""}}var FreeResponse$1 = {name:"free-response",accessible:true,displayName:"Free Response (Assessments only)",widget:FreeResponse,hidden:false,getUserInputFromSerializedState:getStartUserInput$c,getStartUserInput: getStartUserInput$c};const styles$k=StyleSheet.create({container:{gap:spacing.xSmall_8},characterCountText:{color:semanticColor.core.foreground.neutral.default,fontSize:font.body.size.small,margin:0},overCharacterLimit:{color:semanticColor.core.foreground.critical.default},textarea:{padding:spacing.medium_16},warningCircleIcon:{marginInlineEnd:spacing.xSmall_8}});
1766
-
1767
- const getPromptJSON$i=(title,rendererJSON,hintRendererJSON)=>{if(!rendererJSON){return {type:"graded-group",title,content:"",widgets:{},hint:hintRendererJSON}}return {...rendererJSON,title,type:"graded-group",hint:hintRendererJSON}};
1768
-
1769
- var styles$j = {"result":"perseus_8dtO1IvS","answerBarContainer":"perseus_TQP1iS6G","answerBar":"perseus_FxBNEIyI","message":"perseus_PHIIz6-3"};
1770
-
1771
- function GradedGroupAnswerBar({apiOptions,answerBarState,invalidMessage,onCheckAnswer,onNextQuestion}){const{strings}=usePerseusI18n();const{keepTrying,check,correctExcited,nextQuestion}=strings;const resultRef=React.useRef(null);const handleCheckAnswer=()=>{flushSync(onCheckAnswer);requestAnimationFrame(()=>resultRef.current?.focus());};const stateInfoMap={correct:{icon:starIcon,iconColor:semanticColor.core.foreground.success.default,text:correctExcited},incorrect:{icon:arrowCounterIcon,iconColor:semanticColor.core.foreground.neutral.subtle,text:keepTrying},invalid:{icon:warningIcon,iconColor:semanticColor.core.border.warning.strong,text:invalidMessage},active:null};const stateInfo=stateInfoMap[answerBarState];const action=answerBarState==="correct"?onNextQuestion&&{label:nextQuestion,onClick:onNextQuestion,disabled:false}:{label:check,onClick:handleCheckAnswer,disabled:apiOptions.readOnly};return jsxRuntimeExports.jsx("div",{className:styles$j.answerBarContainer,children:jsxRuntimeExports.jsxs("div",{className:styles$j.answerBar,children:[jsxRuntimeExports.jsx("span",{className:styles$j.message,children:stateInfo&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PhosphorIcon,{icon:stateInfo.icon,color:stateInfo.iconColor}),jsxRuntimeExports.jsx("output",{ref:resultRef,tabIndex:-1,className:styles$j.result,children:jsxRuntimeExports.jsx(Renderer,{content:stateInfo.text,strings:strings,apiOptions:apiOptions})})]})}),action&&jsxRuntimeExports.jsx(Button,{disabled:action.disabled,onClick:action.onClick,children:action.label})]})})}
1772
-
1773
- var cssModuleStyles = {"hint":"perseus_Tm6z7bco","hintCollapsed":"perseus_BaL4tWtd","hintExpanded":"perseus_Q4V7j8eC","hintWrapper":"perseus_AjlaWAbb"};
1774
-
1775
- const GradedGroup=forwardRef(function GradedGroup(props,ref){const{strings}=usePerseusI18n();const dependencies=useDependencies();const[showHint,setShowHint]=useState(false);const[message,setMessage]=useState("");const[answerBarState,setAnswerBarState]=useState("active");const rendererRef=useRef(null);const hintRendererRef=useRef(null);const hintId=useId();useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group",widgetSubType:"null",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getInputPaths(){return rendererRef.current?.getInputPaths()||[]},getPromptJSON(){const hint=hintRendererRef.current?.getPromptJSON()||{content:props.options.hint?.content||"",widgets:{}};return getPromptJSON$i(props.options.title,rendererRef.current?.getPromptJSON(),hint)},focus(){return !!rendererRef.current?.focus()},focusInputPath(path){rendererRef.current?.focusPath(path);},blurInputPath(path){rendererRef.current?.blurPath(path);}}));function handleAnswerChange(){setMessage("");setAnswerBarState(state=>state==="correct"?state:"active");}function checkAnswer(){const score=rendererRef.current?.score()||{type:"invalid"};const{INVALID_MESSAGE_PREFIX,DEFAULT_INVALID_MESSAGE_1,DEFAULT_INVALID_MESSAGE_2}=strings;const status=score.type==="points"?score.total===score.earned?"correct":"incorrect":"invalid";const message=score.type==="points"?score.message||"":score.message?`${INVALID_MESSAGE_PREFIX} ${mapErrorToString(score.message,strings)}`:`${INVALID_MESSAGE_PREFIX} ${DEFAULT_INVALID_MESSAGE_1}${DEFAULT_INVALID_MESSAGE_2}`;setMessage(message);setAnswerBarState(status);props.trackInteraction({status:status});}const apiOptions=_.extend({},ApiOptions.defaults,props.apiOptions,{onFocusChange:(newFocus,oldFocus)=>{if(oldFocus){props.onBlur(oldFocus);}if(newFocus){props.onFocus(newFocus);}}});const classes=classNames$2("perseus-graded-group",props.inGradedGroupSet?css(styles$i.gradedGroupInSet):css(styles$i.gradedGroup));const isCorrect=answerBarState==="correct";const readOnly=apiOptions.readOnly||isCorrect;const showSolutions=isCorrect?"all":"none";return jsxRuntimeExports.jsxs("div",{className:classes,children:[!!props.options.title&&jsxRuntimeExports.jsx("div",{className:css(styles$i.title),children:props.options.title}),jsxRuntimeExports.jsx(UserInputManager,{widgets:props.options.widgets,handleUserInput:handleAnswerChange,problemNum:props.problemNum??0,children:({userInput,handleUserInput})=>jsxRuntimeExports.jsx(Renderer,{content:props.options.content,widgets:props.options.widgets,images:props.options.images,userInput:userInput,handleUserInput:handleUserInput,problemNum:props.problemNum??0,ref:rendererRef,keypadElement:props.keypadElement,apiOptions:{...apiOptions,readOnly},showSolutions:showSolutions,linterContext:props.linterContext,strings:strings,isScorable:true})}),answerBarState!=="invalid"&&jsxRuntimeExports.jsx("div",{role:"status","aria-live":"polite",children:jsxRuntimeExports.jsx(Renderer,{content:message,strings:strings,apiOptions:apiOptions})}),props.options.answerArea&&apiOptions.renderExtras?.(props.options.answerArea,props.widgetId),props.options.hint?.content&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("button",{"aria-expanded":showHint,"aria-controls":hintId,className:css(styles$i.explainToggle),onClick:()=>setShowHint(!showHint),children:showHint?strings.hideExplanation:strings.explain}),jsxRuntimeExports.jsx("div",{id:hintId,className:classNames$2(cssModuleStyles.hint,showHint?cssModuleStyles.hintExpanded:cssModuleStyles.hintCollapsed),children:jsxRuntimeExports.jsx("div",{className:cssModuleStyles.hintWrapper,children:jsxRuntimeExports.jsx(UserInputManager,{widgets:props.options.hint.widgets,problemNum:props.problemNum??0,children:({userInput,handleUserInput,initializeUserInput})=>{const{content,widgets,images}=props.options.hint;return jsxRuntimeExports.jsx(Renderer,{content:content,widgets:widgets,images:images,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,ref:hintRendererRef,apiOptions:apiOptions,linterContext:props.linterContext,strings:strings,showSolutions:showSolutions})}})})})]}),jsxRuntimeExports.jsx(GradedGroupAnswerBar,{apiOptions:apiOptions,invalidMessage:message,answerBarState:answerBarState,onCheckAnswer:checkAnswer,onNextQuestion:props.onNextQuestion})]})});const styles$i=StyleSheet.create({gradedGroupInSet:{marginInlineStart:0,paddingInlineStart:0},gradedGroup:{borderBlockStart:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,backgroundColor:semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"},explainToggle:{backgroundColor:"unset",fontSize:font.body.size.small,padding:0,border:"none",marginBlockStart:20,color:semanticColor.core.foreground.instructive.default,cursor:"pointer",display:"block",clear:"both"},title:{fontSize:font.heading.size.small,color:semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8}});var GradedGroup$1 = {name:"graded-group",displayName:"Graded group (articles only)",widget:GradedGroup,hidden:false,tracking:"all",isLintable:true};
1776
-
1777
- const getPromptJSON$h=(widgetData,activeGroupJSON)=>{return {type:"graded-group-set",options:{groupCount:widgetData.options.gradedGroups.length,currentGroup:activeGroupJSON}}};
1778
-
1779
- function Indicators(props){function handleKeyDown(e,i){if(e.key==="Enter"||e.key===" "){props.onChangeGroupIndex(i);}}return jsxRuntimeExports.jsx("ul",{role:"list",className:classNames$2(css(styles$h.indicatorContainer),"indicatorContainer"),children:props.gradedGroups.map(({title},i)=>{const isCurrent=i===props.currentGroupIndex;return jsxRuntimeExports.jsx("li",{className:css(styles$h.indicator),children:jsxRuntimeExports.jsx(Clickable,{ref:isCurrent?props.currentPipRef:undefined,role:"button","aria-label":title,"aria-current":isCurrent,style:styles$h.indicatorButton,onClick:()=>props.onChangeGroupIndex(i),onKeyDown:e=>handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(View,{style:[styles$h.indicatorDot,isCurrent&&styles$h.indicatorDotActive,(hovered||focused||pressed)&&styles$h.indicatorDotFocused]})})},i)})})}const GradedGroupSet=forwardRef(function GradedGroupSet(props,ref){const dependencies=useDependencies();const childGroup=useRef(null);const currentPipRef=useRef(null);const[currentGroupIndex,setCurrentGroupIndex]=useState(0);useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group-set",widgetSubType:"null",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getInputPaths(){return childGroup.current?.getInputPaths?.()??[]},getPromptJSON(){invariant(childGroup.current,"GradedGroupSet must have at least one group");return getPromptJSON$h(props,childGroup.current.getPromptJSON())},focus(){return childGroup.current?.focus()??false},focusInputPath(path){childGroup.current?.focusInputPath(path);},blurInputPath(path){childGroup.current?.blurInputPath(path);}}));const{gradedGroups}=props.options;const{JIPT}=getDependencies();if(JIPT.useJIPT&&gradedGroups.length>1){return jsxRuntimeExports.jsx("div",{className:css(styles$h.container),children:gradedGroups.map((gradedGroup,i)=>{return jsxRuntimeExports.jsx(GradedGroup,{...props,problemNum:(props.problemNum??0)+i,options:gradedGroup,inGradedGroupSet:false,linterContext:props.linterContext},i)})})}const currentGroup=gradedGroups[currentGroupIndex];if(currentGroup==null){return jsxRuntimeExports.jsx("span",{children:"No current group..."})}const numGroups=gradedGroups.length;const atEnd=currentGroupIndex>=numGroups-1;const handleNextQuestion=atEnd?undefined:()=>{flushSync(()=>setCurrentGroupIndex(currentGroupIndex+1));currentPipRef.current?.focus();};return jsxRuntimeExports.jsxs("div",{className:css(styles$h.container),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$h.top),children:[jsxRuntimeExports.jsx("div",{className:css(styles$h.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:css(styles$h.spacer)}),jsxRuntimeExports.jsx(Indicators,{currentGroupIndex:currentGroupIndex,gradedGroups:gradedGroups,onChangeGroupIndex:setCurrentGroupIndex,currentPipRef:currentPipRef})]}),jsxRuntimeExports.jsx(GradedGroup,{ref:childGroup,...props,problemNum:(props.problemNum??0)+currentGroupIndex,options:{...currentGroup,title:""},inGradedGroupSet:true,onNextQuestion:handleNextQuestion,linterContext:props.linterContext},currentGroupIndex)]})});var GradedGroupSet$1 = {name:"graded-group-set",displayName:"Graded group set (articles only)",widget:GradedGroupSet,hidden:false,tracking:"all",isLintable:true};const styles$h=StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:font.heading.size.small,color:semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8},indicatorContainer:{display:"flex",flexDirection:"row",listStyleType:"none",margin:"unset",paddingInlineStart:"unset",flexWrap:"wrap"},indicator:{width:24,height:24},indicatorButton:{width:"100%",height:"100%",display:"flex",flexWrap:"wrap",placeContent:"center",cursor:"pointer",":focus":{outline:"none"}},indicatorDot:{boxSizing:"content-box",width:10,height:10,borderRadius:border$1.radius.radius_full,borderWidth:border$1.width.medium,borderColor:semanticColor.core.border.instructive.default,borderStyle:"solid"},indicatorDotFocused:{outlineColor:semanticColor.focus.outer,outlineStyle:"solid",outlineWidth:border$1.width.medium,outlineOffset:border$1.width.medium,boxShadow:`0 0 0 ${border$1.width.medium} ${semanticColor.focus.inner}`},indicatorDotActive:{backgroundColor:semanticColor.core.foreground.instructive.default,borderColor:semanticColor.core.transparent},container:{borderBlockStart:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,backgroundColor:semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"}});
1780
-
1781
- class ButtonGroup extends React.Component{componentWillUnmount(){this.container=null;}focus(){if(this.container){this.container.focus();return true}}toggleSelect(newValue){if(this.props.value!==newValue){this.props.onChange(newValue);}}render(){const value=this.props.value;const buttons=this.props.buttons.map((button,i)=>{return jsxRuntimeExports.jsx("button",{title:button.title,type:"button",disabled:this.props.disabled,className:css(buttonGroupStyles.buttonStyle,button.value===value&&buttonGroupStyles.selectedStyle,button.value===value&&this.props.selectedButtonStyle,this.props.disabled&&buttonGroupStyles.disabledStyle),onClick:()=>this.toggleSelect(button.value),children:button.content},""+i)});const outerStyle={display:"inline-block"};return jsxRuntimeExports.jsx("div",{style:outerStyle,ref:node=>this.container=node,children:buttons})}}ButtonGroup.defaultProps={value:null};const buttonGroupStyles=StyleSheet.create({buttonStyle:{backgroundColor:semanticColor.core.background.base.default,border:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderInlineStart:"0",color:semanticColor.core.foreground.neutral.strong,cursor:"pointer",margin:"0",paddingBlock:"5px",paddingInline:"10px",position:"relative",":first-child":{borderInlineStart:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderStartStartRadius:border$1.radius.radius_040,borderEndStartRadius:border$1.radius.radius_040},":last-child":{borderInlineEnd:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderStartEndRadius:border$1.radius.radius_040,borderEndEndRadius:border$1.radius.radius_040},":hover":{backgroundColor:semanticColor.core.background.instructive.subtle},":focus":{zIndex:2}},selectedStyle:{backgroundColor:semanticColor.core.background.instructive.subtle,boxShadow:`inset 0 calc(-1 * ${border$1.width.thick}) 0 ${semanticColor.core.border.instructive.default}`},disabledStyle:{cursor:"not-allowed",backgroundColor:semanticColor.core.background.disabled.default,color:semanticColor.core.foreground.disabled.strong,":hover":{backgroundColor:semanticColor.core.background.disabled.default}}});
1782
-
1783
- const getPromptJSON$g=widgetData=>{const{userInput}=widgetData;const{type,coords}=userInput;const input={type,coords};if(userInput.type==="logarithm"||userInput.type==="exponential"){input["asymptote"]=userInput.asymptote;}return {type:"grapher",options:{availableTypes:widgetData.options.availableTypes,range:widgetData.options.graph.range,labels:widgetData.options.graph.labels,tickStep:widgetData.options.graph.step,gridStep:widgetData.options.graph.gridStep,snapStep:widgetData.options.graph.snapStep,backgroundImageUrl:widgetData.options.graph.backgroundImage.url},userInput:input}};
1784
-
1785
- const getPromptJSON$f=(props,userInput)=>{return {type:"interactive-graph",options:{graph:getGraphOptionsForProps(props),backgroundImageUrl:props.options.backgroundImage?.url,range:props.options.range,labels:props.options.labels},userInput:getUserInput(userInput)}};const getGraphOptionsForProps=props=>{const type=props.userInput.type;switch(type){case "angle":return {type:props.userInput.type,angleOffsetDegrees:props.userInput.angleOffsetDeg,startCoords:props.userInput.startCoords};case "circle":return {type:props.userInput.type,startParams:{center:props.userInput.startCoords?.center,radius:props.userInput.startCoords?.radius}};case "linear":return {type:props.userInput.type,startCoords:props.userInput.startCoords};case "linear-system":return {type:props.userInput.type,startCoords:props.userInput.startCoords};case "point":return {type:props.userInput.type,numPoints:props.userInput.numPoints,startCoords:props.userInput.startCoords};case "polygon":return {type:props.userInput.type,match:props.userInput.match,numSides:props.userInput.numSides,startCoords:props.userInput.startCoords};case "quadratic":return {type:props.userInput.type,startCoords:props.userInput.startCoords};case "ray":return {type:props.userInput.type,startCoords:props.userInput.startCoords};case "segment":return {type:props.userInput.type,numSegments:props.userInput.numSegments,startCoords:props.userInput.startCoords};case "sinusoid":return {type:props.userInput.type,startCoords:props.userInput.startCoords};case "tangent":return {type:props.userInput.type,startCoords:props.userInput.startCoords};case "none":return {};case "absolute-value":return {type:props.userInput.type,startCoords:props.userInput.startCoords};case "exponential":return {type:props.userInput.type,startCoords:props.userInput.startCoords};case "logarithm":return {type:props.userInput.type,startCoords:props.userInput.startCoords};case "vector":return {type:props.userInput.type,startCoords:props.userInput.startCoords};default:throw new UnreachableCaseError(type)}};const getUserInput=userInput=>{const type=userInput.type;switch(type){case "angle":return {coords:userInput.coords,angleOffsetDegrees:userInput.angleOffsetDeg};case "circle":return {center:userInput.center,radius:userInput.radius};case "linear":return {coords:userInput.coords};case "linear-system":return {coords:userInput.coords};case "point":return {coords:userInput.coords};case "polygon":return {coords:userInput.coords};case "quadratic":return {coords:userInput.coords};case "ray":return {coords:userInput.coords};case "segment":return {coords:userInput.coords};case "sinusoid":return {coords:userInput.coords};case "tangent":return {coords:userInput.coords};case "none":return {};case "absolute-value":return {coords:userInput.coords};case "exponential":return {coords:userInput.coords,asymptote:userInput.asymptote};case "logarithm":return {coords:userInput.coords,asymptote:userInput.asymptote};case "vector":return {coords:userInput.coords};default:throw new UnreachableCaseError(type)}};
1786
-
1787
- function clamp(value,min,max){if(value<min){return min}if(value>max){return max}return value}
1788
-
1789
- function snap(snapStep,point){const[requestedX,requestedY]=point;const[snapX,snapY]=snapStep;return [Math.round(requestedX/snapX)*snapX,Math.round(requestedY/snapY)*snapY]}
1790
-
1791
- const X=0;const Y=1;
1792
-
1793
- const MIN=0;const MAX=1;function size([min,max]){return max-min}function trim(amount,interval){if(amount*2>size(interval)){const middle=average(...interval);return [middle,middle]}return [interval[MIN]+amount,interval[MAX]-amount]}function average(a,b){return (a+b)/2}
1794
-
1795
- function clampToBox(box,point){return [clamp(point[X],...box[X]),clamp(point[Y],...box[Y])]}function inset(amount,box){return [trim(amount[X],box[X]),trim(amount[Y],box[Y])]}function isInBound({range,point}){return point[X]>=range[X][MIN]&&point[X]<=range[X][MAX]&&point[Y]>=range[Y][MIN]&&point[Y]<=range[Y][MAX]}
1796
-
1797
- function lerp(a,b,fraction){return (b-a)*clamp(fraction,0,1)+a}
1798
-
1799
- const segmentsIntersect=([[a,b],[c,d]],[[p,q],[r,s]])=>{const determinant=(c-a)*(s-q)-(r-p)*(d-b);if(determinant===0){return false}else {const lambda=((s-q)*(r-a)+(p-r)*(s-b))/determinant;const gamma=((b-d)*(r-a)+(c-a)*(s-b))/determinant;return 0<lambda&&lambda<1&&0<gamma&&gamma<1}};function findIntersectionOfRays([[a,b],[c,d]],[[p,q],[r,s]]){const determinant=(c-a)*(s-q)-(r-p)*(d-b);if(determinant===0){return undefined}else {const lambda=((s-q)*(r-a)+(p-r)*(s-b))/determinant;const gamma=((b-d)*(r-a)+(c-a)*(s-b))/determinant;if(lambda<=0||gamma>=1){return undefined}const initialPoint=[a,b];const direction=vec.sub([c,d],initialPoint);return vec.add(initialPoint,vec.scale(direction,lambda))}}
1800
-
1801
- function srFormatNumber(a,locale,maximumFractionDigits){const piBasedNumber=getPiMultiple(a);if(piBasedNumber){return piBasedNumber}return (0+a).toLocaleString(locale,{maximumFractionDigits:maximumFractionDigits??3,useGrouping:false})}function getPiMultiple(a){if(Number.isInteger(a)||a===0||a>1e12){return null}const piCoefficient=a/Math.PI;const truncatedCoefficient=parseFloat(piCoefficient.toFixed(12));if(Number.isInteger(truncatedCoefficient)){return truncatedCoefficient+"π"}const acceptableDivisors=[2,3,4,6];for(const divisor of acceptableDivisors){const coefficientNumerator=parseFloat((piCoefficient*divisor).toFixed(12));if(Number.isInteger(coefficientNumerator)){return coefficientNumerator+"π/"+divisor}}return null}
1802
-
1803
- const getIntersectionOfRayWithBox=(initialPoint,throughPoint,box)=>{const[[xMin,xMax],[yMin,yMax]]=box;const[aX,aY]=initialPoint;const[bX,bY]=throughPoint;const yDiff=bY-aY;const xDiff=bX-aX;const slope=yDiff/xDiff;const inverseSlope=1/slope;const xExtreme=xDiff<0?xMin:xMax;const yExtreme=yDiff<0?yMin:yMax;const yAtXExtreme=aY+(xExtreme-aX)*slope;const xAtYExtreme=aX+(yExtreme-aY)*inverseSlope;switch(true){case isBetween(yAtXExtreme,yMin,yMax):return [xExtreme,yAtXExtreme];case isBetween(xAtYExtreme,xMin,xMax):return [xAtYExtreme,yExtreme];default:return [xExtreme,yExtreme]}};function isBetween(x,low,high){return x>=low&&x<=high}function getArrayWithoutDuplicates(array){const returnArray=[];for(const coordPair of array){if(!returnArray.some(([x,y])=>x===coordPair[0]&&y===coordPair[1])){returnArray.push(coordPair);}}return returnArray}function getSlopeStringForLine(line,strings){const slope=(line[1][1]-line[0][1])/(line[1][0]-line[0][0]);if(!Number.isFinite(slope)){return strings.srLinearGraphSlopeVertical}if(slope===0){return strings.srLinearGraphSlopeHorizontal}return slope>0?strings.srLinearGraphSlopeIncreasing:strings.srLinearGraphSlopeDecreasing}function getInterceptStringForLine(line,strings,locale){const slope=(line[1][1]-line[0][1])/(line[1][0]-line[0][0]);const xIntercept=(0-line[0][1])/slope+line[0][0];const yIntercept=line[0][1]-slope*line[0][0];const overlapsXAxis=line[0][1]===0&&line[1][1]===0;const overlapsYAxis=line[0][0]===0&&line[1][0]===0;const hasXIntercept=Number.isFinite(xIntercept)&&!overlapsXAxis;const hasYIntercept=Number.isFinite(yIntercept)&&!overlapsYAxis;if(hasXIntercept&&hasYIntercept){return xIntercept===0&&yIntercept===0?strings.srLinearGraphOriginIntercept:strings.srLinearGraphBothIntercepts({xIntercept:srFormatNumber(xIntercept,locale),yIntercept:srFormatNumber(yIntercept,locale)})}return hasXIntercept?strings.srLinearGraphXOnlyIntercept({xIntercept:srFormatNumber(xIntercept,locale)}):strings.srLinearGraphYOnlyIntercept({yIntercept:srFormatNumber(yIntercept,locale)})}function getQuadraticXIntercepts(a,b,c){if(a===0){if(b===0){return []}return [-c/b]}const discriminant=b*b-4*a*c;if(discriminant<0){return []}const x1=(-b+Math.sqrt(discriminant))/(2*a);const x2=(-b-Math.sqrt(discriminant))/(2*a);if(x1===x2){return [x1]}return [x1,x2]}function getQuadraticVertex(coeffs){const[a,b,c]=coeffs;if(a===0){return undefined}return [-b/(2*a),c-b*b/(4*a)]}function getAngleFromPoints(points,i){if(i<0||i>=points.length||!Number.isInteger(i)){return null}if(points.length<3){return null}const point=points.at(i);const pt1=points.at(i-1);const pt2=points[(i+1)%points.length];if(!point||!pt1||!pt2){return null}const a=vec.dist(point,pt1);const b=vec.dist(point,pt2);const c=vec.dist(pt1,pt2);let lawOfCosinesRadicand=(a**2+b**2-c**2)/(2*a*b);if(lawOfCosinesRadicand<-1||lawOfCosinesRadicand>1){lawOfCosinesRadicand=Math.round(lawOfCosinesRadicand);}const angle=Math.acos(lawOfCosinesRadicand);return angle}function getSideLengthsFromPoints(points,i,isPolygonOpen){if(i<0||i>=points.length||!Number.isInteger(i)){return []}if(points.length<2){return []}const returnArray=[];const point=points[i];const point1Index=i===0?points.length-1:i-1;const point1=points[point1Index];const side1=i!==point1Index?vec.dist(point,point1):null;if(side1&&!(isPolygonOpen&&i===0)){returnArray.push({pointIndex:point1Index,sideLength:side1});}const point2Index=(i+1)%points.length;const point2=points[point2Index];const side2=i!==point2Index&&point2Index!==point1Index?vec.dist(point,point2):null;if(side2&&!(isPolygonOpen&&i===points.length-1)){returnArray.push({pointIndex:point2Index,sideLength:side2});}return returnArray}function getPolygonSideString(sideLength,pointIndex,strings,locale){return Number.isInteger(sideLength)?strings.srPolygonSideLength({pointNum:pointIndex+1,length:`${sideLength}`}):strings.srPolygonSideLengthApprox({pointNum:pointIndex+1,length:srFormatNumber(sideLength,locale,1)})}function calculateScaledRadius(range){const[[xMin,xMax],[yMin,yMax]]=range;const xSpan=xMax-xMin;const ySpan=yMax-yMin;const minSpan=Math.min(xSpan,ySpan);return minSpan*.06}function getAsymptoteGraphKeyboardConstraint(coords,snapStep,pointIndex,isValidPosition){const coordToBeMoved=coords[pointIndex];const movePointWithConstraint=moveFunc=>{let movedCoord=moveFunc(coordToBeMoved);for(let i=0;i<3&&!isValidPosition(movedCoord);i++){movedCoord=moveFunc(movedCoord);}if(!isValidPosition(movedCoord)){return coordToBeMoved}return movedCoord};return {up:movePointWithConstraint(coord=>vec.add(coord,[0,snapStep[1]])),down:movePointWithConstraint(coord=>vec.sub(coord,[0,snapStep[1]])),left:movePointWithConstraint(coord=>vec.sub(coord,[snapStep[0],0])),right:movePointWithConstraint(coord=>vec.add(coord,[snapStep[0],0]))}}function getAsymptoteHandleCoord(orientation,range,asymptote){if(orientation==="horizontal"){const midX=(range[0][0]+range[0][1])/2;return [midX,asymptote]}const midY=(range[1][0]+range[1][1])/2;return [asymptote,midY]}function skipAsymptoteKeyboardOverPoint(proposed,currentAsymptote,coords,handleCoord,snapStep,orientation){const snapped=snap(snapStep,proposed);const moveAxis=orientation==="horizontal"?1:0;const pinAxis=orientation==="horizontal"?0:1;const step=snapStep[moveAxis];const dir=Math.sign(snapped[moveAxis]-currentAsymptote);if(dir===0){return snapped}const pinValue=handleCoord[pinAxis];const isForbidden=v=>coords.some(c=>c[pinAxis]===pinValue&&c[moveAxis]===v);let value=snapped[moveAxis];for(let i=0;i<3&&isForbidden(value);i++){value+=dir*step;}const result=[0,0];result[moveAxis]=value;result[pinAxis]=snapped[pinAxis];return result}const getQuadraticCoefficients$2=coords=>{const p1=coords[0];const p2=coords[1];const p3=coords[2];const denom=(p1[0]-p2[0])*(p1[0]-p3[0])*(p2[0]-p3[0]);if(denom===0){return}const a=(p3[0]*(p2[1]-p1[1])+p2[0]*(p1[1]-p3[1])+p1[0]*(p3[1]-p2[1]))/denom;const b=(p3[0]*p3[0]*(p1[1]-p2[1])+p2[0]*p2[0]*(p3[1]-p1[1])+p1[0]*p1[0]*(p2[1]-p3[1]))/denom;const c=(p2[0]*p3[0]*(p2[0]-p3[0])*p1[1]+p3[0]*p1[0]*(p3[0]-p1[0])*p2[1]+p1[0]*p2[0]*(p1[0]-p2[0])*p3[1])/denom;return [a,b,c]};function getLengthOfSegment(segment){return point.distanceToPoint(...segment)}function getAbsoluteValueCoefficients$1(coords){const p1=coords[0];const p2=coords[1];const denom=p2[X]-p1[X];const num=p2[Y]-p1[Y];let m=Math.abs(num/denom);if(p2[Y]<p1[Y]){m=-m;}return {m,h:p1[X],v:p1[Y]}}
1804
-
1805
- const{getClockwiseAngle: getClockwiseAngle$2}=angles;const{getSinusoidCoefficients: getSinusoidCoefficients$1,getTangentCoefficients: getTangentCoefficients$1,getQuadraticCoefficients: getQuadraticCoefficients$1,getExponentialCoefficients: getExponentialCoefficients$3,getLogarithmCoefficients: getLogarithmCoefficients$3}=coefficients;const{getLineEquation,getLineIntersectionString,magnitude: magnitude$2,vector: vector$2}=geometry;const UNLIMITED="unlimited";function numSteps(range,step){return Math.floor((range[1]-range[0])/step)}const makeInvalidTypeError=(functionName,graphType)=>{return new PerseusError(`${functionName} called but current graph type is not a '${graphType}'`,Errors.NotAllowed,{metadata:{graphType}})};function getLineCoords$1(graph,props){return graph.coords||pointsFromNormalized$1(props,[[.25,.75],[.75,.75]])}function getPointCoords$1(graph,props){const numPoints=graph.numPoints||1;let coords=graph.coords;if(coords){return coords}switch(numPoints){case 1:coords=[graph.coord||[0,0]];break;case 2:coords=[[-5,0],[5,0]];break;case 3:coords=[[-5,0],[0,0],[5,0]];break;case 4:coords=[[-6,0],[-2,0],[2,0],[6,0]];break;case 5:coords=[[-6,0],[-3,0],[0,0],[3,0],[6,0]];break;case 6:coords=[[-5,0],[-3,0],[-1,0],[1,0],[3,0],[5,0]];break;case UNLIMITED:coords=[];break}const range=[[-10,10],[-10,10]];const newCoords=normalizeCoords$1(coords,range);return pointsFromNormalized$1(props,newCoords)}function getLinearSystemCoords$1(graph,props){const defaultCoords=[[[.25,.75],[.75,.75]],[[.25,.25],[.75,.25]]];return graph.coords||defaultCoords.map(coords=>{return pointsFromNormalized$1(props,coords)})}function getPolygonCoords$1(graph,props){if(graph.type!=="polygon"){throw makeInvalidTypeError("toggleShowSides","polygon")}let coords=graph.coords;if(coords){return coords}const n=graph.numSides||3;if(n===UNLIMITED){coords=[];}else {const angle=2*Math.PI/n;const offset=(1/n-1/2)*Math.PI;const radius=graph.snapTo==="sides"?Math.sqrt(3)/3*7:4;coords=_.times(n,function(i){return [radius*Math.cos(i*angle+offset),radius*Math.sin(i*angle+offset)]});}const ranges=[[-10,10],[-10,10]];coords=normalizeCoords$1(coords,ranges);const snapToGrid=graph.snapTo!=="angles"&&graph.snapTo!=="sides";coords=pointsFromNormalized$1(props,coords,!snapToGrid);return coords}function getSegmentCoords$1(graph,props){const coords=graph.coords;if(coords){return coords}const n=graph.numSegments||1;const ys={1:[5],2:[5,-5],3:[5,0,-5],4:[6,2,-2,-6],5:[6,3,0,-3,-6],6:[5,3,1,-1,-3,-5]}[n];const range=[[-10,10],[-10,10]];return ys.map(function(y){let segment=[[-5,y],[5,y]];segment=normalizeCoords$1(segment,range);segment=pointsFromNormalized$1(props,segment);return segment})}function getAngleCoords$1(graph,props){let coords=graph.coords;if(coords){return coords}const snap=graph.snapDegrees||1;let angle=snap;while(angle<20){angle+=snap;}angle=angle*Math.PI/180;const offset=(graph.angleOffsetDeg||0)*Math.PI/180;coords=pointsFromNormalized$1(props,[[.85,.5],[.5,.5]]);const radius=magnitude$2(vector$2(...coords));coords[0]=[coords[1][0]+radius*Math.cos(offset),coords[1][1]+radius*Math.sin(offset)];coords[2]=[coords[1][0]+radius*Math.cos(angle+offset),coords[1][1]+radius*Math.sin(angle+offset)];return coords}function normalizeCoords$1(coordsList,ranges){return coordsList.map(function(coords){return coords.map(function(coord,i){const extent=ranges[i][1]-ranges[i][0];return (coord+ranges[i][1])/extent})})}function pointsFromNormalized$1(props,coordsList,noSnap){return coordsList.map(function(coords){return coords.map(function(coord,i){const range=props.options.range[i];if(noSnap){return range[0]+(range[1]-range[0])*coord}const step=props.options.step[i];const nSteps=numSteps(range,step);const tick=Math.round(coord*nSteps);return range[0]+step*tick})})}function getNoneEquationString(){return ""}function getLinearEquationString(props){const coords=getLineCoords$1(props.userInput,props);if(approximateEqual(coords[0][0],coords[1][0])){return "x = "+coords[0][0].toFixed(3)}const m=(coords[1][1]-coords[0][1])/(coords[1][0]-coords[0][0]);const b=coords[0][1]-m*coords[0][0];if(approximateEqual(m,0)){return "y = "+b.toFixed(3)}return "y = "+m.toFixed(3)+"x + "+b.toFixed(3)}function getCurrentQuadraticCoefficients(props){const coords=props.userInput.coords||defaultQuadraticCoords(props);return getQuadraticCoefficients$1(coords)}function defaultQuadraticCoords(props){const coords=[[.25,.75],[.5,.25],[.75,.75]];return pointsFromNormalized$1(props,coords)}function getQuadraticEquationString(props){const coeffs=getCurrentQuadraticCoefficients(props);return "y = "+coeffs[0].toFixed(3)+"x^2 + "+coeffs[1].toFixed(3)+"x + "+coeffs[2].toFixed(3)}function getCurrentSinusoidCoefficients(props){const coords=props.userInput.coords||defaultSinusoidCoords(props);return getSinusoidCoefficients$1(coords)}function defaultSinusoidCoords(props){const coords=[[.5,.5],[.65,.6]];return pointsFromNormalized$1(props,coords)}function getSinusoidEquationString(props){const coeffs=getCurrentSinusoidCoefficients(props);return "y = "+coeffs[0].toFixed(3)+"sin("+coeffs[1].toFixed(3)+"x - "+coeffs[2].toFixed(3)+") + "+coeffs[3].toFixed(3)}function defaultExponentialCoords(props){const coords=[[.5,.55],[.75,.75]];return pointsFromNormalized$1(props,coords,true)}function getExponentialEquationString(props){const coords=props.userInput.coords||defaultExponentialCoords(props);const asymptote=props.userInput.asymptote??0;const coeffs=getExponentialCoefficients$3(coords,asymptote);if(coeffs==null){return "y = e^x"}return "y = "+coeffs.a.toFixed(3)+"e^("+coeffs.b.toFixed(3)+"x) + "+coeffs.c.toFixed(3)}function defaultLogarithmCoords(props){const coords=[[.55,.55],[.75,.75]];return pointsFromNormalized$1(props,coords,true)}function getLogarithmEquationString(props){const coords=props.userInput.coords||defaultLogarithmCoords(props);const asymptote=props.userInput.asymptote??0;const coeffs=getLogarithmCoefficients$3(coords,asymptote);if(coeffs==null){return "y = ln(x)"}const cStr=coeffs.c===0?"x":coeffs.c<0?"x - "+Math.abs(coeffs.c).toFixed(3):"x + "+coeffs.c.toFixed(3);return "y = "+coeffs.a.toFixed(3)+"ln("+coeffs.b.toFixed(3)+cStr+")"}function getAbsoluteValueEquationString(props){const userInput=props.userInput;if(userInput.type!=="absolute-value"||!userInput.coords){return ""}const{m,h,v}=getAbsoluteValueCoefficients$1(userInput.coords);if(!Number.isFinite(m)){return ""}return "y = "+m.toFixed(3)+"|x - "+h.toFixed(3)+"| + "+v.toFixed(3)}function getCurrentTangentCoefficients(props){const coords=props.userInput.coords||defaultTangentCoords(props);return getTangentCoefficients$1(coords)}function defaultTangentCoords(props){const coords=[[.5,.5],[.75,.75]];return pointsFromNormalized$1(props,coords)}function getTangentEquationString(props){const coeffs=getCurrentTangentCoefficients(props);return "y = "+coeffs[0].toFixed(3)+"tan("+coeffs[1].toFixed(3)+"x - "+coeffs[2].toFixed(3)+") + "+coeffs[3].toFixed(3)}function getCircleEquationString(props){const graph=props.userInput;const center=graph.center||[0,0];const radius=graph.radius||2;return "center ("+center[0]+", "+center[1]+"), radius "+radius}function getLinearSystemEquationString(props){const coords=getLinearSystemCoords$1(props.userInput,props);return "\n"+getLineEquation(coords[0][0],coords[0][1])+"\n"+getLineEquation(coords[1][0],coords[1][1])+"\n"+getLineIntersectionString(coords[0],coords[1])}function getPointEquationString(props){if(props.userInput.type!=="point"){throw makeInvalidTypeError("getPointEquationString","point")}const coords=getPointCoords$1(props.userInput,props);return coords.map(function(coord){return "("+coord[0]+", "+coord[1]+")"}).join(", ")}function getSegmentEquationString(props){if(props.userInput.type!=="segment"){throw makeInvalidTypeError("getSegmentEquationString","segment")}const segments=getSegmentCoords$1(props.userInput,props);return segments.map(function(segment){return "["+segment.map(function(coord){return "("+coord.join(", ")+")"}).join(" ")+"]"}).join(" ")}function getRayEquationString(props){if(props.userInput.type!=="ray"){throw makeInvalidTypeError("createPointForPolygonType","ray")}const coords=getLineCoords$1(props.userInput,props);const a=coords[0];const b=coords[1];let eq=getLinearEquationString(props);if(a[0]>b[0]){eq+=" (for x <= "+a[0].toFixed(3)+")";}else if(a[0]<b[0]){eq+=" (for x >= "+a[0].toFixed(3)+")";}else if(a[1]>b[1]){eq+=" (for y <= "+a[1].toFixed(3)+")";}else {eq+=" (for y >= "+a[1].toFixed(3)+")";}return eq}function getPolygonEquationString(props){if(props.userInput.type!=="polygon"){throw makeInvalidTypeError("getPolygonEquationString","polygon")}const coords=getPolygonCoords$1(props.userInput,props);return coords.map(function(coord){return "("+coord.join(", ")+")"}).join(" ")}function getAngleEquationString(props){if(props.userInput.type!=="angle"){throw makeInvalidTypeError("getAngleEquationString","angle")}const coords=getAngleCoords$1(props.userInput,props);const allowReflexAngles=props.userInput.allowReflexAngles;const angle=getClockwiseAngle$2(coords,allowReflexAngles);return angle.toFixed(0)+"° angle"+" at ("+coords[1].join(", ")+")"}function getVectorEquationString(props){if(props.userInput.type!=="vector"){throw makeInvalidTypeError("getVectorEquationString","vector")}const coords=props.userInput.coords;if(!coords){return ""}const[tail,tip]=coords;const dx=tip[0]-tail[0];const dy=tip[1]-tail[1];return `\u27E8${dx.toFixed(3)}, ${dy.toFixed(3)}\u27E9`}function getEquationString$1(props){const type=props.userInput.type;switch(type){case "none":return getNoneEquationString();case "linear":return getLinearEquationString(props);case "quadratic":return getQuadraticEquationString(props);case "sinusoid":return getSinusoidEquationString(props);case "circle":return getCircleEquationString(props);case "linear-system":return getLinearSystemEquationString(props);case "point":return getPointEquationString(props);case "segment":return getSegmentEquationString(props);case "ray":return getRayEquationString(props);case "polygon":return getPolygonEquationString(props);case "angle":return getAngleEquationString(props);case "absolute-value":return getAbsoluteValueEquationString(props);case "exponential":return getExponentialEquationString(props);case "tangent":return getTangentEquationString(props);case "logarithm":return getLogarithmEquationString(props);case "vector":return getVectorEquationString(props);default:throw new UnreachableCaseError(type)}}
1806
-
1807
- function getCustomPointLabel(pointLabels,index){const label=pointLabels?.[index];return typeof label==="string"&&label!==""?label:undefined}function resolvePointLabel(pointLabels,index){return getCustomPointLabel(pointLabels,index)??`${index+1}`}function buildPointAriaLabel(pointLabels,index,point,strings,locale){const customLabel=getCustomPointLabel(pointLabels,index);if(customLabel===undefined){return undefined}const x=srFormatNumber(point[0],locale);const y=srFormatNumber(point[1],locale);return strings.srPointAtCoordinates({pointLabel:customLabel,x,y})}function usePointAriaLabel(pointLabels){const{strings,locale}=usePerseusI18n();return (index,point)=>buildPointAriaLabel(pointLabels,index,point,strings,locale)}
1808
-
1809
- function srAbsoluteValuePointLabel(state,strings,locale){const x=srFormatNumber(state.x,locale);const y=srFormatNumber(state.y,locale);const{pointLabel}=state;if(state.pointIndex===0){return pointLabel?strings.srAbsoluteValueVertexPointWithLabel({pointLabel,x,y}):strings.srAbsoluteValueVertexPoint({x,y})}const armLabel=pointLabel?strings.srAbsoluteValueArmPointWithLabel({pointLabel,x,y}):strings.srAbsoluteValueArmPoint({x,y});const slopeLabel=strings.srAbsoluteValueSlope({slope:srFormatNumber(state.slope,locale)});return `${armLabel} ${slopeLabel}`}function describeAbsoluteValueGraph(state,i18n){const{strings,locale}=i18n;const{coords}=state;const[vertex,armPoint]=coords;const coeffs=getAbsoluteValueCoefficients$1(coords);const srAbsoluteValueGraph=strings.srAbsoluteValueGraph;const pointLabel=(label,x,y,withLabel,plain)=>label?withLabel({pointLabel:label,x,y}):plain({x,y});const srAbsoluteValueVertexPoint=pointLabel(getCustomPointLabel(state.pointLabels,0),srFormatNumber(vertex[X],locale),srFormatNumber(vertex[Y],locale),strings.srAbsoluteValueVertexPointWithLabel,strings.srAbsoluteValueVertexPoint);const srAbsoluteValueArmPoint=pointLabel(getCustomPointLabel(state.pointLabels,1),srFormatNumber(armPoint[X],locale),srFormatNumber(armPoint[Y],locale),strings.srAbsoluteValueArmPointWithLabel,strings.srAbsoluteValueArmPoint);const srAbsoluteValueDescription=buildAbsoluteValueDescription(coeffs,locale,strings);const srAbsoluteValueSlope=strings.srAbsoluteValueSlope({slope:srFormatNumber(coeffs.m,locale)});return {srAbsoluteValueGraph,srAbsoluteValueVertexPoint,srAbsoluteValueArmPoint,srAbsoluteValueDescription,srAbsoluteValueSlope}}function buildAbsoluteValueDescription(coeffs,locale,strings){const{m,h,v}=coeffs;const atOrigin=h===0&&v===0;const opens=m<0?strings.srAbsoluteValueOpensDown:strings.srAbsoluteValueOpensUp;const vertex=atOrigin?strings.srAbsoluteValueVertexOrigin:strings.srAbsoluteValueVertex({x:srFormatNumber(h,locale),y:srFormatNumber(v,locale)});let xIntercepts="";let yIntercept="";if(!atOrigin){const t=-v/m;if(isFinite(t)&&t>0){xIntercepts=strings.srAbsoluteValueTwoXIntercepts({intercept1:srFormatNumber(h-t,locale),intercept2:srFormatNumber(h+t,locale)});}else if(t===0){xIntercepts=strings.srAbsoluteValueOneXIntercept({intercept:srFormatNumber(h,locale)});}yIntercept=strings.srAbsoluteValueYIntercept({intercept:srFormatNumber(m*Math.abs(h)+v,locale)});}const slope=strings.srAbsoluteValueSlope({slope:srFormatNumber(m,locale)});return [opens,vertex,xIntercepts,yIntercept,slope].filter(Boolean).join(" ")}
1810
-
1811
- const{getClockwiseAngle: getClockwiseAngle$1}=angles;function srAnglePointLabel(state,strings,locale){const x=srFormatNumber(state.x,locale);const y=srFormatNumber(state.y,locale);const customLabel=state.pointLabel;switch(state.pointIndex){case 0:return strings.srAngleEndingSide({pointLabel:customLabel??`${state.pointIndex+1}`,x,y});case 1:return strings.srAngleVertexWithAngleMeasure({pointLabel:customLabel??`${state.pointIndex+1}`,x,y,angleMeasure:srFormatNumber(state.angleMeasure,locale)});default:return strings.srAngleStartingSide({pointLabel:customLabel??`${state.pointIndex+1}`,x,y})}}function describeAngleGraph(state,i18n){const{strings,locale}=i18n;const{coords,allowReflexAngles}=state;const[endingSide,vertex,startingSide]=coords;const angleMeasureValue=getClockwiseAngle$1(coords,allowReflexAngles);const angleMeasure=srFormatNumber(angleMeasureValue,locale);const srAngleGraphAriaLabel=strings.srAngleGraphAriaLabel;const srAngleGraphAriaDescription=strings.srAngleGraphAriaDescription({angleMeasure,vertexX:srFormatNumber(vertex[X],locale),vertexY:srFormatNumber(vertex[Y],locale),startingSideX:srFormatNumber(startingSide[X],locale),startingSideY:srFormatNumber(startingSide[Y],locale),endingSideX:srFormatNumber(endingSide[X],locale),endingSideY:srFormatNumber(endingSide[Y],locale)});const srAngleEndingSide=srAnglePointLabel({pointIndex:0,pointLabel:getCustomPointLabel(state.pointLabels,0),x:endingSide[X],y:endingSide[Y],angleMeasure:angleMeasureValue},strings,locale);const srAngleVertex=srAnglePointLabel({pointIndex:1,pointLabel:getCustomPointLabel(state.pointLabels,1),x:vertex[X],y:vertex[Y],angleMeasure:angleMeasureValue},strings,locale);const srAngleStartingSide=srAnglePointLabel({pointIndex:2,pointLabel:getCustomPointLabel(state.pointLabels,2),x:startingSide[X],y:startingSide[Y],angleMeasure:angleMeasureValue},strings,locale);return {srAngleGraphAriaLabel,srAngleGraphAriaDescription,srAngleStartingSide,srAngleEndingSide,srAngleVertex}}
1812
-
1813
- function getGradableGraph(state,initialGraph){if(!state.hasBeenInteractedWith){return {...initialGraph}}if(initialGraph.type==="linear-system"&&state.type==="linear-system"){return {...initialGraph,coords:state.coords}}if(state.type==="segment"&&initialGraph.type==="segment"){return {...initialGraph,coords:state.coords}}if(state.type==="linear"&&initialGraph.type==="linear"){return {...initialGraph,coords:state.coords}}if(state.type==="ray"&&initialGraph.type==="ray"){return {...initialGraph,coords:state.coords}}if(state.type==="vector"&&initialGraph.type==="vector"){return {...initialGraph,coords:state.coords}}if(state.type==="polygon"&&initialGraph.type==="polygon"){if(state.numSides==="unlimited"&&!state.closedPolygon){return {...initialGraph,coords:null}}return {...initialGraph,coords:state.coords}}if(state.type==="point"&&initialGraph.type==="point"){if(state.numPoints==="unlimited"&&state.coords.length===0){return {...initialGraph,coords:null}}return {...initialGraph,coords:state.coords}}if(state.type==="circle"&&initialGraph.type==="circle"){return {...initialGraph,center:state.center,radius:getRadius(state)}}if(state.type==="quadratic"&&initialGraph.type==="quadratic"){return {...initialGraph,coords:state.coords}}if(state.type==="sinusoid"&&initialGraph.type==="sinusoid"){return {...initialGraph,coords:state.coords}}if(state.type==="exponential"&&initialGraph.type==="exponential"){return {...initialGraph,coords:state.coords,asymptote:state.asymptote}}if(state.type==="logarithm"&&initialGraph.type==="logarithm"){return {...initialGraph,coords:state.coords,asymptote:state.asymptote}}if(state.type==="tangent"&&initialGraph.type==="tangent"){return {...initialGraph,coords:state.coords}}if(state.type==="angle"&&initialGraph.type==="angle"){return {...initialGraph,coords:state.coords,allowReflexAngles:state.allowReflexAngles}}if(state.type==="none"&&initialGraph.type==="none"){return {type:"none"}}if(state.type==="absolute-value"&&initialGraph.type==="absolute-value"){return {...initialGraph,coords:state.coords}}throw new Error("Mafs is not yet implemented for graph type: "+initialGraph.type)}function getRadius(graph){const[centerX,centerY]=graph.center;const[edgeX,edgeY]=graph.radiusPoint;return Math.sqrt(Math.pow(edgeX-centerX,2)+Math.pow(edgeY-centerY,2))}
1814
-
1815
- function srCircleRadiusPointLabel(x,y,centerX,strings,locale,pointLabel){const radiusPointX=srFormatNumber(x,locale);const radiusPointY=srFormatNumber(y,locale);if(x>=centerX){return pointLabel?strings.srCircleRadiusPointRightWithLabel({pointLabel,radiusPointX,radiusPointY}):strings.srCircleRadiusPointRight({radiusPointX,radiusPointY})}return pointLabel?strings.srCircleRadiusPointLeftWithLabel({pointLabel,radiusPointX,radiusPointY}):strings.srCircleRadiusPointLeft({radiusPointX,radiusPointY})}function srCircleCenterLabel(x,y,strings,locale){return strings.srCircleShape({centerX:srFormatNumber(x,locale),centerY:srFormatNumber(y,locale)})}function describeCircleGraph(state,i18n){const{strings,locale}=i18n;const{center,radiusPoint,pointLabels}=state;const radius=getRadius(state);const srCircleGraph=strings.srCircleGraph;const srCircleShape=srCircleCenterLabel(center[0],center[1],strings,locale);const srCircleRadiusPoint=srCircleRadiusPointLabel(radiusPoint[0],radiusPoint[1],center[0],strings,locale,getCustomPointLabel(pointLabels,0));const srCircleRadius=strings.srCircleRadius({radius});const srCircleOuterPoints=strings.srCircleOuterPoints({point1X:srFormatNumber(center[0]+radius,locale),point1Y:srFormatNumber(center[1],locale),point2X:srFormatNumber(center[0],locale),point2Y:srFormatNumber(center[1]+radius,locale),point3X:srFormatNumber(center[0]-radius,locale),point3Y:srFormatNumber(center[1],locale),point4X:srFormatNumber(center[0],locale),point4Y:srFormatNumber(center[1]-radius,locale)});const srCircleInteractiveElement=strings.srInteractiveElements({elements:[srCircleShape,srCircleRadius].join(" ")});return {srCircleGraph,srCircleShape,srCircleRadiusPoint,srCircleRadius,srCircleOuterPoints,srCircleInteractiveElement}}
1816
-
1817
- const{getExponentialCoefficients: getExponentialCoefficients$2}=coefficients;function srExponentialPointLabel(state,strings,locale){const x=srFormatNumber(state.x,locale);const y=srFormatNumber(state.y,locale);const pointLabel=state.pointLabel??`${state.pointIndex+1}`;if(!state.hasCurve){return strings.srPointAtCoordinates({pointLabel,x,y})}return strings.srExponentialPoint({pointLabel,x,y})}function describeExponentialGraph(state,i18n){const{strings,locale}=i18n;const{coords,asymptote}=state;const[point1,point2]=coords;const formattedPoint1={x:srFormatNumber(point1[X],locale),y:srFormatNumber(point1[Y],locale)};const formattedPoint2={x:srFormatNumber(point2[X],locale),y:srFormatNumber(point2[Y],locale)};const asymptoteYFormatted=srFormatNumber(asymptote,locale);const coeffs=getExponentialCoefficients$2(coords,asymptote);const descriptionArgs={point1X:formattedPoint1.x,point1Y:formattedPoint1.y,point2X:formattedPoint2.x,point2Y:formattedPoint2.y,asymptoteY:asymptoteYFormatted};return {srExponentialGraph:strings.srExponentialGraph,srExponentialDescription:buildExponentialDescription(coeffs,descriptionArgs,strings,locale),srExponentialAsymptote:strings.srExponentialAsymptote({asymptoteY:asymptoteYFormatted}),srExponentialPoint1:srExponentialPointLabel({pointIndex:0,pointLabel:getCustomPointLabel(state.pointLabels,0),x:point1[X],y:point1[Y],hasCurve:coeffs!==undefined},strings,locale),srExponentialPoint2:srExponentialPointLabel({pointIndex:1,pointLabel:getCustomPointLabel(state.pointLabels,1),x:point2[X],y:point2[Y],hasCurve:coeffs!==undefined},strings,locale),srExponentialInteractiveElements:strings.srInteractiveElements({elements:strings.srExponentialInteractiveElements(descriptionArgs)})}}function buildExponentialDescription(coeffs,args,strings,locale){if(coeffs===undefined){return strings.srExponentialNoCurve(args)}const{a,b,c}=coeffs;const base=b<0?strings.srExponentialDescriptionLeftPos(args):strings.srExponentialDescriptionRightNeg(args);const position=a>0?strings.srExponentialAboveAsymptote:strings.srExponentialBelowAsymptote;const yIntercept=srFormatNumber(a+c,locale);const ratio=-c/a;const intercepts=ratio>0?strings.srExponentialIntercepts({xIntercept:srFormatNumber(Math.log(ratio)/b,locale),yIntercept}):strings.srExponentialYIntercept({yIntercept});return `${base} ${position} ${intercepts}`}
1818
-
1819
- function srLinearSystemPointLabel(state,strings,locale){const x=srFormatNumber(state.x,locale);const y=srFormatNumber(state.y,locale);const pointLabel=state.pointLabel??`${state.pointIndex+1}`;return strings.srLinearSystemPoint({lineNumber:state.lineIndex+1,pointLabel,x,y})}function describeLinearSystemGraph(state,i18n){const{strings,locale}=i18n;const{coords:lines,pointLabels}=state;const srLinearSystemGraph=strings.srLinearSystemGraph;const lineDescriptions=lines.map((line,i)=>{const[point1,point2]=line;const point1X=srFormatNumber(point1[0],locale);const point1Y=srFormatNumber(point1[1],locale);const point2X=srFormatNumber(point2[0],locale);const point2Y=srFormatNumber(point2[1],locale);return {point1AriaLabel:srLinearSystemPointLabel({lineIndex:i,pointIndex:0,pointLabel:getCustomPointLabel(pointLabels,i*2),x:point1[0],y:point1[1]},strings,locale),point2AriaLabel:srLinearSystemPointLabel({lineIndex:i,pointIndex:1,pointLabel:getCustomPointLabel(pointLabels,i*2+1),x:point2[0],y:point2[1]},strings,locale),grabHandleAriaLabel:strings.srLinearSystemGrabHandle({lineNumber:i+1,point1X,point1Y,point2X,point2Y}),pointsDescription:strings.srLinearSystemPoints({lineNumber:i+1,point1X,point1Y,point2X,point2Y}),interceptDescription:getInterceptStringForLine(line,strings,locale),slopeDescription:getSlopeStringForLine(line,strings)}});const intersectionPoint=geometry.getLineIntersection(lines[0],lines[1]);const intersectionDescription=intersectionPoint?strings.srLinearSystemIntersection({x:srFormatNumber(intersectionPoint[0],locale),y:srFormatNumber(intersectionPoint[1],locale)}):strings.srLinearSystemParallel;const srLinearSystemInteractiveElements=strings.srInteractiveElements({elements:[srLinearSystemGraph,...lineDescriptions.map(line=>line.pointsDescription)].join(" ")});return {srLinearSystemGraph,srLinearSystemInteractiveElements,srIntersectionDescription:intersectionDescription,srLines:lineDescriptions}}
1820
-
1821
- const{getLogarithmCoefficients: getLogarithmCoefficients$2}=coefficients;function srLogarithmPointLabel(state,strings,locale){const x=srFormatNumber(state.x,locale);const y=srFormatNumber(state.y,locale);const pointLabel=state.pointLabel??`${state.pointIndex+1}`;if(!state.hasCurve){return strings.srPointAtCoordinates({pointLabel,x,y})}return strings.srLogarithmPoint({pointLabel,x,y})}function describeLogarithmGraph(state,i18n){const{strings,locale}=i18n;const{coords,asymptote}=state;const[point1,point2]=coords;const formattedPoint1={x:srFormatNumber(point1[X],locale),y:srFormatNumber(point1[Y],locale)};const formattedPoint2={x:srFormatNumber(point2[X],locale),y:srFormatNumber(point2[Y],locale)};const asymptoteXFormatted=srFormatNumber(asymptote,locale);const coeffs=getLogarithmCoefficients$2(coords,asymptote);const descriptionArgs={point1X:formattedPoint1.x,point1Y:formattedPoint1.y,point2X:formattedPoint2.x,point2Y:formattedPoint2.y,asymptoteX:asymptoteXFormatted};return {srLogarithmGraph:strings.srLogarithmGraph,srLogarithmDescription:buildLogarithmDescription(coeffs,descriptionArgs,strings,locale),srLogarithmAsymptote:strings.srLogarithmAsymptote({asymptoteX:asymptoteXFormatted}),srLogarithmPoint1:srLogarithmPointLabel({pointIndex:0,pointLabel:getCustomPointLabel(state.pointLabels,0),x:point1[X],y:point1[Y],hasCurve:coeffs!==undefined},strings,locale),srLogarithmPoint2:srLogarithmPointLabel({pointIndex:1,pointLabel:getCustomPointLabel(state.pointLabels,1),x:point2[X],y:point2[Y],hasCurve:coeffs!==undefined},strings,locale),srLogarithmInteractiveElements:strings.srInteractiveElements({elements:strings.srLogarithmInteractiveElements(descriptionArgs)})}}function buildLogarithmDescription(coeffs,args,strings,locale){if(coeffs===undefined){return strings.srLogarithmNoCurve(args)}const{a,b,c}=coeffs;const base=b>0?a>0?strings.srLogarithmDescriptionRightNeg(args):strings.srLogarithmDescriptionRightPos(args):a>0?strings.srLogarithmDescriptionLeftNeg(args):strings.srLogarithmDescriptionLeftPos(args);const position=b>0?strings.srLogarithmToRightOfAsymptote:strings.srLogarithmToLeftOfAsymptote;const xIntercept=srFormatNumber((1-c)/b,locale);const intercepts=c>0?strings.srLogarithmIntercepts({xIntercept,yIntercept:srFormatNumber(a*Math.log(c),locale)}):strings.srLogarithmXIntercept({xIntercept});return `${base} ${position} ${intercepts}`}
1822
-
1823
- function srPolygonLabel(coords,pointLabels,strings,locale){const pointsString=coords.map(([x,y],i)=>strings.srPointAtCoordinates({pointLabel:resolvePointLabel(pointLabels,i),x:srFormatNumber(x,locale),y:srFormatNumber(y,locale)})).join(" ");const elementsLabel=coords.length===1?strings.srPolygonElementsOne:strings.srPolygonElementsNum({num:coords.length});return `${elementsLabel} ${pointsString}`}function describePolygonGraph(state,i18n,markings){const{strings,locale}=i18n;const{coords,pointLabels}=state;const buildLabel=(index,point)=>buildPointAriaLabel(pointLabels,index,point,strings,locale);const isCoordinatePlane=markings==="axes"||markings==="graph";const hasOnePoint=coords.length===1;const srPolygonGraph=isCoordinatePlane?strings.srPolygonGraphCoordinatePlane:strings.srPolygonGraph;const srPolygonGraphPointsNum=hasOnePoint?strings.srPolygonGraphPointsOne:strings.srPolygonGraphPointsNum({num:coords.length});let srPolygonGraphPoints;if(isCoordinatePlane){const pointsString=coords.map((coord,i)=>buildLabel(i,coord)??strings.srPointAtCoordinates({pointLabel:`${i+1}`,x:srFormatNumber(coord[0],locale),y:srFormatNumber(coord[1],locale)}));srPolygonGraphPoints=pointsString.join(" ");}const srPolygonElementsNum=hasOnePoint?strings.srPolygonElementsOne:strings.srPolygonElementsNum({num:coords.length});const srPolygonInteractiveElements=coords.length>0?strings.srInteractiveElements({elements:[srPolygonElementsNum,srPolygonGraphPoints].join(" ")}):null;return {srPolygonGraph,srPolygonGraphPointsNum,srPolygonGraphPoints,srPolygonElementsNum,srPolygonInteractiveElements}}
1824
-
1825
- function getCoordQuadrant(coord){const[unroundedX,unroundedY]=coord;const x=Number(unroundedX.toFixed(3));const y=Number(unroundedY.toFixed(3));if(x===0&&y===0){return "origin"}if(y===0){return "x-axis"}if(x===0){return "y-axis"}if(x>0&&y>0){return 1}if(x<0&&y>0){return 2}if(x<0&&y<0){return 3}return 4}function getQuadraticVertexString(vertex,strings){const location=getCoordQuadrant(vertex);switch(location){case "origin":return strings.srQuadraticGraphVertexOrigin;case "x-axis":return strings.srQuadraticGraphVertexXAxis;case "y-axis":return strings.srQuadraticGraphVertexYAxis;default:return strings.srQuadraticGraphVertexQuadrant({quadrant:location})}}function getQuadraticPointString(pointLabel,coord,strings,locale){const location=getCoordQuadrant(coord);const[x,y]=coord;switch(location){case "origin":return strings.srQuadraticPointOrigin({pointLabel});case "x-axis":case "y-axis":return strings.srQuadraticPointAxis({pointLabel,x:srFormatNumber(x,locale),y:srFormatNumber(y,locale)});default:return strings.srQuadraticPointQuadrant({pointLabel,quadrant:location,x:srFormatNumber(x,locale),y:srFormatNumber(y,locale)})}}
1826
-
1827
- function srQuadraticPointLabel(state,strings,locale){const pointLabel=state.pointLabel??`${state.pointIndex+1}`;const pointString=getQuadraticPointString(pointLabel,[state.x,state.y],strings,locale);if(state.vertex===undefined){return pointString}return `${pointString} ${getQuadraticVertexString(state.vertex,strings)}`}function describeQuadraticGraph(state,i18n){const{strings,locale}=i18n;const coeffs=getQuadraticCoefficients$2(state.coords);const[a,b,c]=coeffs??[0,0,0];const vertex=getQuadraticVertex([a,b,c]);const xIntercepts=getQuadraticXIntercepts(a,b,c);const srQuadraticGraph=strings.srQuadraticGraph;const srQuadraticFaceUp=strings.srQuadraticFaceUp;const srQuadraticFaceDown=strings.srQuadraticFaceDown;const srQuadraticDirection=a===0?undefined:a>0?srQuadraticFaceUp:srQuadraticFaceDown;const srQuadraticVertex=vertex===undefined?undefined:getQuadraticVertexString(vertex,strings);const srQuadraticXIntercepts=xIntercepts.length===2?strings.srQuadraticTwoXIntercepts({intercept1:srFormatNumber(xIntercepts[0],locale),intercept2:srFormatNumber(xIntercepts[1],locale)}):xIntercepts.length===1?strings.srQuadraticOneXIntercept({intercept:srFormatNumber(xIntercepts[0],locale)}):undefined;const srQuadraticYIntercept=strings.srQuadraticYIntercept({intercept:srFormatNumber(c,locale)});const srQuadraticInteractiveElements=strings.srInteractiveElements({elements:strings.srQuadraticInteractiveElements({point1X:srFormatNumber(state.coords[0][0],locale),point1Y:srFormatNumber(state.coords[0][1],locale),point2X:srFormatNumber(state.coords[1][0],locale),point2Y:srFormatNumber(state.coords[1][1],locale),point3X:srFormatNumber(state.coords[2][0],locale),point3Y:srFormatNumber(state.coords[2][1],locale)})});return {srQuadraticGraph,srQuadraticDirection,srQuadraticVertex,srQuadraticXIntercepts,srQuadraticYIntercept,srQuadraticInteractiveElements}}
1828
-
1829
- function srRayPointLabel(state,strings,locale){const x=srFormatNumber(state.x,locale);const y=srFormatNumber(state.y,locale);const{pointLabel}=state;if(state.pointIndex===0){return pointLabel?strings.srRayEndpointWithLabel({pointLabel,x,y}):strings.srRayEndpoint({x,y})}return pointLabel?strings.srRayTerminalPointWithLabel({pointLabel,x,y}):strings.srRayTerminalPoint({x,y})}function describeRayGraph(state,i18n){const{coords:line}=state;const{strings,locale}=i18n;const srRayGraph=strings.srRayGraph;const srRayPoints=strings.srRayPoints({point1X:srFormatNumber(line[0][0],locale),point1Y:srFormatNumber(line[0][1],locale),point2X:srFormatNumber(line[1][0],locale),point2Y:srFormatNumber(line[1][1],locale)});const srRayEndpoint=srRayPointLabel({pointIndex:0,pointLabel:getCustomPointLabel(state.pointLabels,0),x:line[0][0],y:line[0][1]},strings,locale);const srRayTerminalPoint=srRayPointLabel({pointIndex:1,pointLabel:getCustomPointLabel(state.pointLabels,1),x:line[1][0],y:line[1][1]},strings,locale);const srRayGrabHandle=strings.srRayGrabHandle({point1X:srFormatNumber(line[0][0],locale),point1Y:srFormatNumber(line[0][1],locale),point2X:srFormatNumber(line[1][0],locale),point2Y:srFormatNumber(line[1][1],locale)});const srRayInteractiveElement=strings.srInteractiveElements({elements:[srRayGraph,srRayPoints].join(" ")});return {srRayGraph,srRayPoints,srRayEndpoint,srRayTerminalPoint,srRayGrabHandle,srRayInteractiveElement}}
1830
-
1831
- function srSegmentPointLabel(state,strings,locale){const x=srFormatNumber(state.x,locale);const y=srFormatNumber(state.y,locale);const pointLabel=state.pointLabel??`${state.pointIndex+1}`;return state.totalSegments===1?strings.srSingleSegmentGraphEndpointAriaLabel({pointLabel,x,y}):strings.srMultipleSegmentGraphEndpointAriaLabel({pointLabel,indexOfSegment:state.segmentIndex+1,x,y})}function describeSegmentGraph(state,i18n){const{strings,locale}=i18n;const{coords:segments,pointLabels}=state;const totalSegments=segments.length;const srSegmentGraph=totalSegments>1?strings.srMultipleSegmentGraphAriaLabel({countOfSegments:totalSegments}):strings.srSingleSegmentGraphAriaLabel;const segmentDescriptions=segments.map((segment,i)=>{const[point1,point2]=segment;const point1X=srFormatNumber(point1[X],locale);const point1Y=srFormatNumber(point1[Y],locale);const point2X=srFormatNumber(point2[X],locale);const point2Y=srFormatNumber(point2[Y],locale);return {point1AriaLabel:srSegmentPointLabel({segmentIndex:i,pointIndex:0,pointLabel:getCustomPointLabel(pointLabels,i*2),totalSegments,x:point1[X],y:point1[Y]},strings,locale),point2AriaLabel:srSegmentPointLabel({segmentIndex:i,pointIndex:1,pointLabel:getCustomPointLabel(pointLabels,i*2+1),totalSegments,x:point2[X],y:point2[Y]},strings,locale),grabHandleAriaLabel:strings.srSegmentGrabHandle({point1X,point1Y,point2X,point2Y}),individualAriaLabel:totalSegments===1?strings.srSingleSegmentLabel({point1X,point1Y,point2X,point2Y}):strings.srMultipleSegmentIndividualLabel({point1X,point1Y,point2X,point2Y,indexOfSegment:i+1}),lengthDescription:strings.srSegmentLength({length:srFormatNumber(getLengthOfSegment(segment),locale)})}});const srWholeGraphDescription=segmentDescriptions.map(segment=>segment.individualAriaLabel).join(" ");const srSegmentInteractiveElements=strings.srInteractiveElements({elements:segments.map(([point1,point2],index)=>strings.srMultipleSegmentIndividualLabel({point1X:srFormatNumber(point1[X],locale),point1Y:srFormatNumber(point1[Y],locale),point2X:srFormatNumber(point2[X],locale),point2Y:srFormatNumber(point2[Y],locale),indexOfSegment:index+1})).join(" ")});return {srSegmentGraph,srSegmentInteractiveElements,srWholeGraphDescription,srSegments:segmentDescriptions}}
1832
-
1833
- function srSinusoidPointLabel(state,strings,locale){const x=srFormatNumber(state.x,locale);const y=srFormatNumber(state.y,locale);const{pointLabel}=state;if(state.pointIndex===0){return pointLabel?strings.srSinusoidRootPointWithLabel({pointLabel,x,y}):strings.srSinusoidRootPoint({x,y})}if(state.y===state.otherY){return pointLabel?strings.srSinusoidFlatPointWithLabel({pointLabel,x,y}):strings.srSinusoidFlatPoint({x,y})}if(state.y>state.otherY){return pointLabel?strings.srSinusoidMaxPointWithLabel({pointLabel,x,y}):strings.srSinusoidMaxPoint({x,y})}return pointLabel?strings.srSinusoidMinPointWithLabel({pointLabel,x,y}):strings.srSinusoidMinPoint({x,y})}function describeSinusoidGraph(state,i18n){const{strings,locale}=i18n;const{coords}=state;const[root,peak]=coords;const diffX=Math.abs(peak[X]-root[X]);const diffY=Math.abs(peak[Y]-root[Y]);const srSinusoidGraph=strings.srSinusoidGraph;const srSinusoidDescription=strings.srSinusoidDescription({minValue:srFormatNumber(root[Y]-diffY,locale),maxValue:srFormatNumber(root[Y]+diffY,locale),cycleStart:srFormatNumber(root[X]-2*diffX,locale),cycleEnd:srFormatNumber(root[X]+2*diffX,locale)});const srSinusoidRootPoint=srSinusoidPointLabel({pointIndex:0,pointLabel:getCustomPointLabel(state.pointLabels,0),x:root[X],y:root[Y],otherY:peak[Y]},strings,locale);const srSinusoidPeakPoint=srSinusoidPointLabel({pointIndex:1,pointLabel:getCustomPointLabel(state.pointLabels,1),x:peak[X],y:peak[Y],otherY:root[Y]},strings,locale);const srSinusoidInteractiveElements=strings.srInteractiveElements({elements:strings.srSinusoidInteractiveElements({point1X:srFormatNumber(root[X],locale),point1Y:srFormatNumber(root[Y],locale),point2X:srFormatNumber(peak[X],locale),point2Y:srFormatNumber(peak[Y],locale)})});return {srSinusoidGraph,srSinusoidDescription,srSinusoidRootPoint,srSinusoidPeakPoint,srSinusoidInteractiveElements}}
1834
-
1835
- function srTangentPointLabel(state,strings,locale){const x=srFormatNumber(state.x,locale);const y=srFormatNumber(state.y,locale);const{pointLabel}=state;if(state.pointIndex===0){return pointLabel?strings.srTangentInflectionPointWithLabel({pointLabel,x,y}):strings.srTangentInflectionPoint({x,y})}return pointLabel?strings.srTangentControlPointWithLabel({pointLabel,x,y}):strings.srTangentControlPoint({x,y})}function describeTangentGraph(state,i18n){const{strings,locale}=i18n;const{coords}=state;const[inflection,secondPoint]=coords;const srTangentGraph=strings.srTangentGraph;const srTangentDescription=buildTangentDescription(coords,locale,strings);const srTangentInflectionPoint=srTangentPointLabel({pointIndex:0,pointLabel:getCustomPointLabel(state.pointLabels,0),x:inflection[X],y:inflection[Y]},strings,locale);const srTangentControlPoint=srTangentPointLabel({pointIndex:1,pointLabel:getCustomPointLabel(state.pointLabels,1),x:secondPoint[X],y:secondPoint[Y]},strings,locale);const srTangentInteractiveElements=strings.srInteractiveElements({elements:strings.srTangentInteractiveElements({point1X:srFormatNumber(inflection[X],locale),point1Y:srFormatNumber(inflection[Y],locale),point2X:srFormatNumber(secondPoint[X],locale),point2Y:srFormatNumber(secondPoint[Y],locale)})});return {srTangentGraph,srTangentDescription,srTangentInflectionPoint,srTangentControlPoint,srTangentInteractiveElements}}function buildTangentDescription(coords,locale,strings){const[inflection,control]=coords;const dx=control[X]-inflection[X];const dy=control[Y]-inflection[Y];invariant(dx!==0&&dy!==0,"Tangent requires two control points that differ in both x and y.");const points=strings.srTangentDescriptionPoints({inflectionX:srFormatNumber(inflection[X],locale),inflectionY:srFormatNumber(inflection[Y],locale),controlX:srFormatNumber(control[X],locale),controlY:srFormatNumber(control[Y],locale)});const period=4*Math.abs(dx);const periodFormatted=srFormatNumber(period,locale);const increasing=dx>0===dy>0;const direction=increasing?strings.srTangentIncreasing({period:periodFormatted}):strings.srTangentDecreasing({period:periodFormatted});const halfPeriod=period/2;const asymptotes=strings.srTangentAsymptotes({leftAsymptote:srFormatNumber(inflection[X]-halfPeriod,locale),rightAsymptote:srFormatNumber(inflection[X]+halfPeriod,locale)});return `${points} ${direction} ${asymptotes}`}
1836
-
1837
- function srVectorPointLabel(state,strings,locale){const x=srFormatNumber(state.x,locale);const y=srFormatNumber(state.y,locale);return state.pointIndex===0?strings.srPointAtCoordinates({pointLabel:"1",x,y}):strings.srVectorHeadPoint({x,y})}function describeVectorGraph(state,i18n){const{coords}=state;const[tail,tip]=coords;const{strings,locale}=i18n;const srVectorGraph=strings.srVectorGraph;const srVectorPoints=strings.srVectorPoints({tailX:srFormatNumber(tail[X],locale),tailY:srFormatNumber(tail[Y],locale),headX:srFormatNumber(tip[X],locale),headY:srFormatNumber(tip[Y],locale)});const srVectorHeadPoint=strings.srVectorHeadPoint({x:srFormatNumber(tip[X],locale),y:srFormatNumber(tip[Y],locale)});const srVectorGrabHandle=strings.srVectorGrabHandle({tailX:srFormatNumber(tail[X],locale),tailY:srFormatNumber(tail[Y],locale),headX:srFormatNumber(tip[X],locale),headY:srFormatNumber(tip[Y],locale)});const dx=tip[X]-tail[X];const dy=tip[Y]-tail[Y];const magnitude=Math.sqrt(dx*dx+dy*dy);const directionDegrees=Math.atan2(dy,dx)*180/Math.PI;const normalizedDirection=directionDegrees<0?directionDegrees+360:directionDegrees;const srVectorMagnitudeDirection=strings.srVectorMagnitudeDirection({magnitude:srFormatNumber(magnitude,locale),direction:srFormatNumber(normalizedDirection,locale)});const srVectorDescription=`${srVectorPoints} ${srVectorMagnitudeDirection}`;const srVectorInteractiveElement=strings.srInteractiveElements({elements:[srVectorGraph,srVectorPoints].join(" ")});return {srVectorGraph,srVectorPoints,srVectorDescription,srVectorHeadPoint,srVectorGrabHandle,srVectorInteractiveElement}}
1838
-
1839
- function getAnnouncementText(state,strings,locale){switch(state.type){case "move-point":return strings.srPointAtCoordinates({pointLabel:state.pointLabel,x:srFormatNumber(state.x,locale),y:srFormatNumber(state.y,locale)});case "move-radius-point":return `${srCircleRadiusPointLabel(state.x,state.y,state.centerX,strings,locale,state.pointLabel)} ${strings.srCircleRadius({radius:state.radius})}`;case "move-center":return srCircleCenterLabel(state.x,state.y,strings,locale);case "move-quadratic-point":return srQuadraticPointLabel(state,strings,locale);case "move-vector-point":return srVectorPointLabel(state,strings,locale);case "move-vector-line":return strings.srVectorGrabHandle({tailX:srFormatNumber(state.coords[0][0],locale),tailY:srFormatNumber(state.coords[0][1],locale),headX:srFormatNumber(state.coords[1][0],locale),headY:srFormatNumber(state.coords[1][1],locale)});case "move-segment-point":return srSegmentPointLabel(state,strings,locale);case "move-segment-line":return strings.srSegmentGrabHandle({point1X:srFormatNumber(state.coords[0][0],locale),point1Y:srFormatNumber(state.coords[0][1],locale),point2X:srFormatNumber(state.coords[1][0],locale),point2Y:srFormatNumber(state.coords[1][1],locale)});case "move-linear-system-point":return srLinearSystemPointLabel(state,strings,locale);case "move-linear-system-line":return strings.srLinearSystemGrabHandle({lineNumber:state.lineIndex+1,point1X:srFormatNumber(state.coords[0][0],locale),point1Y:srFormatNumber(state.coords[0][1],locale),point2X:srFormatNumber(state.coords[1][0],locale),point2Y:srFormatNumber(state.coords[1][1],locale)});case "move-ray-point":return srRayPointLabel(state,strings,locale);case "move-ray-line":return strings.srRayGrabHandle(formatLineEndpoints(state.coords,locale));case "move-linear-line":return strings.srLinearGrabHandle(formatLineEndpoints(state.coords,locale));case "move-sinusoid-point":return srSinusoidPointLabel(state,strings,locale);case "move-exponential-point":return srExponentialPointLabel(state,strings,locale);case "move-exponential-asymptote":return strings.srExponentialAsymptote({asymptoteY:srFormatNumber(state.asymptoteY,locale)});case "move-logarithm-point":return srLogarithmPointLabel(state,strings,locale);case "move-logarithm-asymptote":return strings.srLogarithmAsymptote({asymptoteX:srFormatNumber(state.asymptoteX,locale)});case "move-tangent-point":return srTangentPointLabel(state,strings,locale);case "move-absolute-value-point":return srAbsoluteValuePointLabel(state,strings,locale);case "move-angle-point":return srAnglePointLabel(state,strings,locale);case "move-polygon":return srPolygonLabel(state.coords,state.pointLabels,strings,locale);default:throw new UnreachableCaseError(state)}}function formatLineEndpoints(coords,locale){return {point1X:srFormatNumber(coords[0][0],locale),point1Y:srFormatNumber(coords[0][1],locale),point2X:srFormatNumber(coords[1][0],locale),point2Y:srFormatNumber(coords[1][1],locale)}}
1840
-
1841
- function pathBuilder(){return new PathBuilder}class PathBuilder{build(){return this.path.map(scaleCommandBy(this.scaleFactor)).map(commandToString).join("")}move(x,y){this.path.push({action:"M",args:[x,y]});return this}line(x,y){this.path.push({action:"L",args:[x,y]});return this}circularArc(radius,toX,toY,{sweep=false,largeArc=false}={}){this.path.push({action:"A",args:[radius,radius,0,largeArc?1:0,sweep?1:0,toX,toY]});return this}curve(control1X,control1Y,control2X,control2Y,endX,endY){this.path.push({action:"C",args:[control1X,control1Y,control2X,control2Y,endX,endY]});return this}scale(factor){this.scaleFactor*=factor;return this}constructor(){this.path=[];this.scaleFactor=1;}}function commandToString(command){return `${command.action}${command.args.join(" ")}`}function scaleCommandBy(scaleFactor){return command=>{switch(command.action){case "A":return {...command,args:[command.args[0]*scaleFactor,command.args[1]*scaleFactor,command.args[2],command.args[3],command.args[4],command.args[5]*scaleFactor,command.args[6]*scaleFactor]};default:return {...command,args:command.args.map(c=>c*scaleFactor)}}}}
1842
-
1843
- const defaultGraphConfig={range:[[0,1],[0,1]],tickStep:[1,1],gridStep:[1,1],snapStep:[1,1],markings:"none",showTooltips:false,graphDimensionsInPixels:[1,1],width:0,height:0,labels:[],labelLocation:"onAxis",disableKeyboardInteraction:false,interactiveColor:"var(--mafs-blue)",showAxisArrows:{xMin:true,xMax:true,yMin:true,yMax:true},showAxisTicks:{x:true,y:true}};const GraphConfigContext=createContext(defaultGraphConfig);function useGraphConfig(){return React__default.useContext(GraphConfigContext)}
1844
-
1845
- const matrixBuilder=vec.matrixBuilder;function vectorsToPixels(vectors,graphState,translation=[0,0]){const{range,width,height}=graphState;const[[xMin,xMax],[yMin,yMax]]=range;const transformToPx=matrixBuilder().translate(...translation).scale(width/(xMax-xMin),-height/(yMax-yMin)).get();return vectors.map(p=>vec.transform(p,transformToPx))}function dimensionsToPixels(dimens,graphState){const{range,width,height}=graphState;const[[xMin,xMax],[yMin,yMax]]=range;const transformToPx=matrixBuilder().scale(width/(xMax-xMin),height/(yMax-yMin)).get();return dimens.map(d=>vec.transform(d,transformToPx))}function pointToPixel(point,graphState){const[[xMin],[,yMax]]=graphState.range;const[a,b]=[-xMin,-yMax];return vectorsToPixels([point],graphState,[a,b])[0]}const useTransformVectorsToPixels=(...vectors)=>{const graphState=useGraphConfig();return vectorsToPixels(vectors,graphState)};const useTransformDimensionsToPixels=(...dimens)=>{const graphState=useGraphConfig();return dimensionsToPixels(dimens,graphState)};function pixelsToVectors(pixels,graphState){const[[xMin,xMax],[yMin,yMax]]=graphState.range;const{width,height}=graphState;const xSpan=xMax-xMin;const ySpan=yMax-yMin;return pixels.map(pixel=>{const x=pixel[X]/width*xSpan+xMin;const y=yMax-pixel[Y]/height*ySpan;return [x,y]})}
1846
-
1847
- const arrowPath$1=pathBuilder().move(-3,4).curve(-2.75,2.5,0,.25,.75,0).curve(0,-0.25,-2.75,-2.5,-3,-4).scale(1.4).build();function Arrowhead(props){const[point]=useTransformVectorsToPixels(props.tip);return jsxRuntimeExports.jsx("g",{"aria-hidden":true,className:"interactive-graph-arrowhead",transform:`translate(${point[X]} ${point[Y]}) rotate(${props.angle})`,children:jsxRuntimeExports.jsx("g",{transform:"translate(-1.5)",children:jsxRuntimeExports.jsx("path",{d:arrowPath$1,fill:"none",style:{stroke:props.color??"inherit"},strokeLinejoin:"round",strokeLinecap:"round",strokeWidth:`${props.strokeWidth??2}px`})})})}
1848
-
1849
- function AxisArrows(){const{range:[[xMin,xMax],[yMin,yMax]],showAxisArrows}=useGraphConfig();const axisColor="var(--mafs-fg)";return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[!(yMin>0||yMax<0)&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[showAxisArrows.xMin&&jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[xMin,0],angle:180}),showAxisArrows.xMax&&jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[xMax,0],angle:0})]}),!(xMin>0||xMax<0)&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[showAxisArrows.yMin&&jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[0,yMin],angle:90}),showAxisArrows.yMax&&jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[0,yMax],angle:270})]})]})}
1850
-
1851
- const TARGET_SIZE=44;const REMOVE_BUTTON_ID="perseus_mafs_remove_button";const normalizePoints=(range,step,coordsList,noSnap)=>coordsList.map(coords=>coords.map((coord,i)=>{const axisRange=range[i];if(noSnap){return axisRange[MIN]+size(axisRange)*coord}const axisStep=step[i];const nSteps=Math.floor(size(axisRange)/axisStep);const tick=Math.round(coord*nSteps);return axisRange[MIN]+axisStep*tick}));const normalizeCoords=(coordsList,ranges)=>coordsList.map(coords=>coords.map((coord,i)=>{return (coord+ranges[i][1])/size(ranges[i])}));function bound$1({snapStep,range,point}){const boundingBox=inset(snapStep,range);return clampToBox(boundingBox,point)}function boundToEdgeAndSnapToGrid(point,{snapStep,range}){const[snapX,snapY]=snapStep;const[[xMin,xMax],[yMin,yMax]]=range;if(snapX===0&&snapY===0){return [clamp(point[X],xMin,xMax),clamp(point[Y],yMin,yMax)]}const snapped=snap(snapStep,point);return [clamp(snapped[X],Math.ceil(xMin/snapX)*snapX,Math.floor(xMax/snapX)*snapX),clamp(snapped[Y],Math.ceil(yMin/snapY)*snapY,Math.floor(yMax/snapY)*snapY)]}function isUnlimitedGraphState(state){return state.type==="point"&&state.numPoints==="unlimited"||state.type==="polygon"&&state.numSides==="unlimited"}const mathOnlyParser=SimpleMarkdown.parserFor({math:{...pureMarkdownRules.math,order:0},text:{order:1,match:SimpleMarkdown.anyScopeRegex(/^([^$\\{}]+)/),parse:capture=>({content:capture[0]})},specialCharacter:{order:2,match:SimpleMarkdown.anyScopeRegex(/^(\\[\S\s]|\$|\\$|{|})/),parse:capture=>({content:capture[0]})}},{inline:true});function replaceOutsideTeX(mathString){const parsed=mathOnlyParser(mathString);let result="";for(const piece of parsed){piece.type==="math"?result+="$"+piece.content+"$":piece.type==="specialCharacter"?result+=escapeIfUnescaped(piece.content):result+=piece.content;}return `\\text{${result}}`}function escapeIfUnescaped(character){if(character.length===1){return "\\"+character}else {return character}}const getRangeDiff=range=>{const[min,max]=range;return Math.abs(max-min)};const calculateNestedSVGCoords=(range,width,height)=>{let viewboxX=0;const totalXRange=getRangeDiff(range[X]);const gridCellWidth=width/totalXRange;const minX=range[X][MIN];if(minX>0){viewboxX=gridCellWidth*Math.abs(minX);}if(minX<0){viewboxX=-gridCellWidth*Math.abs(minX);}let viewboxY=-height;const totalYRange=getRangeDiff(range[Y]);const gridCellHeight=height/totalYRange;const minY=range[Y][MIN];if(minY>0){viewboxY=-height-gridCellHeight*Math.abs(minY);}if(minY<0){viewboxY=gridCellHeight*Math.abs(minY)-height;}return {viewboxX,viewboxY}};
1852
-
1853
- const fontSize=14;const fontSizeYAxisLabelMultiplier=1.25;const clampLabelPosition=(labelPosition,graphInfo)=>{const x=Math.max(Math.min(labelPosition[X],graphInfo.width+fontSize*1.25),-14*1.5);const y=Math.max(Math.min(labelPosition[Y],graphInfo.height+fontSize*fontSizeYAxisLabelMultiplier),-14*2);return [x,y]};const getLabelTransform=labelLocation=>{const isOnAxis=labelLocation===undefined||labelLocation==="onAxis";const xLabelTransform=isOnAxis?"translate(7px, -50%)":"translate(-50%, -50%)";const yLabelTransform=isOnAxis?"translate(-50%, 0px)":"translate(-50%, 0px) rotate(-90deg)";return {xLabelTransform,yLabelTransform}};const calculateMaxDigitsInRange=(range,tickStep)=>{const maxDigitsInRange=Math.max(String(Math.abs(Math.floor(range[MIN]))).length,String(Math.abs(Math.ceil(range[MAX]))).length);const tickStepSigFigs=countSignificantDecimals(tickStep)+2;return Math.max(maxDigitsInRange,tickStepSigFigs)};const getLabelPosition=(graphInfo,labelLocation,tickStep)=>{if(labelLocation==="alongEdge"){const xAxisLabelOffset=graphInfo.range[Y][MIN]>=0?[0,fontSize*3]:[0,fontSize*1.5];const isRelativelyCloseToZero=graphInfo.range[X][MIN]<0&&Math.abs(graphInfo.range[X][MIN])<(graphInfo.range[X][MAX]-graphInfo.range[X][MIN])*.07;const needsExtraSpacing=graphInfo.range[X][MIN]>=0||isRelativelyCloseToZero;let paddingRequiredForTickLabels=0;if(needsExtraSpacing){const maxDigits=calculateMaxDigitsInRange(graphInfo.range[Y],tickStep[Y]);paddingRequiredForTickLabels=maxDigits*(fontSize*.75)+(graphInfo.range[Y][MIN]<0&&graphInfo.range[X][MIN]<=0?fontSize*.5:0);}const yAxisLabelOffset=[-14*1.25-paddingRequiredForTickLabels,-14];const xAxisLabelLocation=[(graphInfo.range[X][MIN]+graphInfo.range[X][MAX])/2,graphInfo.range[Y][MIN]];const yAxisLabelLocation=[graphInfo.range[X][MIN],(graphInfo.range[Y][MIN]+graphInfo.range[Y][MAX])/2];if(isRelativelyCloseToZero){yAxisLabelLocation[X]=yAxisLabelLocation[X]-graphInfo.range[X][MIN];}const xLabel=vec.add(pointToPixel(xAxisLabelLocation,graphInfo),xAxisLabelOffset);const yLabel=vec.add(pointToPixel(yAxisLabelLocation,graphInfo),yAxisLabelOffset);return [xLabel,yLabel]}const xLabelInitial=[graphInfo.range[X][MAX],0];const yLabelInitial=[0,graphInfo.range[Y][MAX]];const yLabelOffset=[0,-14*2];let xLabel=pointToPixel(xLabelInitial,graphInfo);let yLabel=vec.add(pointToPixel(yLabelInitial,graphInfo),yLabelOffset);xLabel=clampLabelPosition(xLabel,graphInfo);yLabel=clampLabelPosition(yLabel,graphInfo);return [xLabel,yLabel]};const getGraphBottomMargin=(xAxisLabelLocationY,graphHeight,hasXAxisLabel,showsAxisLabels)=>{const baseMargin=30;if(!showsAxisLabels||!hasXAxisLabel){return baseMargin}const xLabelBottomOverflow=Math.max(0,xAxisLabelLocationY+fontSize-graphHeight);return Math.max(baseMargin,xLabelBottomOverflow)};const shouldShowLabel=(currentTick,range,tickStep)=>{let showLabel=true;if(range[X][MIN]<-tickStep&&range[X][MAX]>0&&currentTick===-tickStep){showLabel=false;}return showLabel};function generateTickLocations(tickStep,min,max,otherAxisMin){const ticks=[];const decimalSigFigs=countSignificantDecimals(tickStep);const start=Math.max(min,0);const startOffset=otherAxisMin>=0?0:tickStep;for(let i=start+startOffset;i<max;i+=tickStep){ticks.push(parseFloat(i.toFixed(decimalSigFigs)));}let i=Math.min(max,0)-tickStep;for(i;i>min;i-=tickStep){ticks.push(i);}return ticks}const countSignificantDecimals=number=>{const numStr=number.toString();if(!numStr.includes(".")){return 0}return numStr.split(".")[1].length};function divideByAndShowPi(value){const dividedValue=value/Math.PI;switch(dividedValue){case 1:return "π";case -1:return "-π";case 0:return "0";default:return dividedValue+"π"}}
1854
-
1855
- function AxisLabels({i18n,xAxisLabelLocation,yAxisLabelLocation}){const{labels,labelLocation}=useGraphConfig();const[xAxisLabelText,yAxisLabelText]=labels;const{xLabelTransform,yLabelTransform}=getLabelTransform(labelLocation);const{TeX}=getDependencies();return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("span",{"aria-hidden":true,style:{position:"absolute",left:xAxisLabelLocation[X],top:xAxisLabelLocation[Y],fontSize:fontSize+"px",transform:xLabelTransform},children:jsxRuntimeExports.jsx(TeX,{children:replaceOutsideTeX(xAxisLabelText)})}),jsxRuntimeExports.jsx("span",{"aria-hidden":true,style:{position:"absolute",left:yAxisLabelLocation[X],top:yAxisLabelLocation[Y],fontSize:fontSize+"px",transform:yLabelTransform},children:jsxRuntimeExports.jsx(TeX,{children:replaceOutsideTeX(yAxisLabelText)})})]})}
1856
-
1857
- const tickSize=10;const tickLabelSize=14;const YGridTick=({y,range,tickStep,showPi})=>{let xPointOnAxis=0;if(range[X][MIN]>0){xPointOnAxis=range[X][MIN];}if(range[X][MAX]<0){xPointOnAxis=range[X][MAX];}const pointOnAxis=[xPointOnAxis,y];const[[xPosition,yPosition]]=useTransformVectorsToPixels(pointOnAxis);const x1=xPosition-tickSize/2;const y1=yPosition;const x2=xPosition+tickSize/2;const y2=yPosition;const xAdjustment=range[X][MAX]<=0?tickLabelSize*1.5:-14*1.1;const xPositionText=xPosition+xAdjustment;const yPositionText=yPosition+tickLabelSize*.25;const showLabel=shouldShowLabel(y,range,tickStep);const ySigFigs=countSignificantDecimals(tickStep);const yLabel=showPi?divideByAndShowPi(y):y.toFixed(ySigFigs);return jsxRuntimeExports.jsxs("g",{className:"tick","aria-hidden":true,children:[jsxRuntimeExports.jsx("line",{x1:x1,y1:y1,x2:x2,y2:y2,className:"axis-tick"}),showLabel&&jsxRuntimeExports.jsx("text",{className:"axis-tick-label",style:{fontSize:tickLabelSize},textAnchor:"end",x:xPositionText,y:yPositionText,children:yLabel})]})};const XGridTick=({x,range,tickStep,showPi})=>{let yPointOnAxis=0;if(range[Y][MIN]>0){yPointOnAxis=range[Y][MIN];}if(range[Y][MAX]<0){yPointOnAxis=range[Y][MAX];}const pointOnAxis=[x,yPointOnAxis];const[[xPosition,yPosition]]=useTransformVectorsToPixels(pointOnAxis);const x1=xPosition;const y1=yPosition+tickSize/2;const x2=xPosition;const y2=yPosition-tickSize/2;const yAdjustment=range[Y][MAX]<0?-14:tickLabelSize*1.75;const xAdjustment=x<0?-2:0;const xPositionText=xPosition+xAdjustment;const yPositionText=yPosition+yAdjustment;const xSigFigs=countSignificantDecimals(tickStep);const xLabel=showPi?divideByAndShowPi(x):x.toFixed(xSigFigs);return jsxRuntimeExports.jsxs("g",{className:"tick","aria-hidden":true,children:[jsxRuntimeExports.jsx("line",{x1:x1,y1:y1,x2:x2,y2:y2,className:"axis-tick"}),jsxRuntimeExports.jsx("text",{className:"axis-tick-label",style:{fontSize:tickLabelSize},textAnchor:"middle",x:xPositionText,y:yPositionText,children:xLabel})]})};const AxisTicks=()=>{const{tickStep,range,showAxisTicks}=useGraphConfig();const[[xMin,xMax],[yMin,yMax]]=range;const[xTickStep,yTickStep]=tickStep;const yGridTicks=generateTickLocations(yTickStep,yMin,yMax,xMin);const xGridTicks=generateTickLocations(xTickStep,xMin,xMax,yMin);return jsxRuntimeExports.jsxs("g",{className:"axis-ticks",role:"presentation",children:[showAxisTicks.y&&jsxRuntimeExports.jsx("g",{className:"y-axis-ticks",children:yGridTicks.map(y=>{return jsxRuntimeExports.jsx(YGridTick,{y:y,range:range,tickStep:tickStep[Y],showPi:tickStep[Y]%Math.PI===0},`y-grid-tick-${y}`)})}),showAxisTicks.x&&jsxRuntimeExports.jsx("g",{className:"x-axis-ticks",children:xGridTicks.map(x=>{return jsxRuntimeExports.jsx(XGridTick,{x:x,range:range,tickStep:tickStep[X],showPi:tickStep[X]%Math.PI===0},`x-grid-tick-${x}`)})})]})};
1858
-
1859
- const GraphBorder=({range,width,height,markings})=>{if(markings!=="graph"&&markings!=="grid"){return null}const{viewboxX,viewboxY}=calculateNestedSVGCoords(range,width,height);return jsxRuntimeExports.jsx("rect",{className:"mafs-graph-border","data-testid":"graph-border",x:viewboxX,y:viewboxY,width:width,height:height})};
1860
-
1861
- const gridLineOptions=(props,axisIndex)=>{const lines=props.markings==="axes"?false:props.gridStep[axisIndex];return {axis:false,lines:lines,labels:false}};const axisLineOptions=props=>{return {axis:props.markings==="graph"||props.markings==="axes",lines:false,labels:false}};const Grid=props=>{return props.markings==="none"?null:jsxRuntimeExports.jsx(Coordinates.Cartesian,{xAxis:gridLineOptions(props,X),yAxis:gridLineOptions(props,Y)})};const Axes=props=>{return props.markings==="none"?null:jsxRuntimeExports.jsx(Coordinates.Cartesian,{xAxis:axisLineOptions(props),yAxis:axisLineOptions(props)})};
1862
-
1863
- const VisibleIcon=()=>jsxRuntimeExports.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",className:css(styles$g.icon),children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsx("path",{id:"a",d:"M7.401 10.035c-1.424.748-2.599 1.905-3.544 "+"3.48a1 1 0 0 1-1.714-1.03C4.325 8.849 7.652 7 "+"12 7c4.348 0 7.675 1.848 9.857 5.486a1 1 0 0 "+"1-1.714 1.028c-.945-1.574-2.12-2.73-3.544-"+"3.48a5 5 0 1 1-9.198 0zM12 15a3 3 0 1 0 0-6 3 3 "+"0 0 0 0 6z"})}),jsxRuntimeExports.jsxs("g",{fill:"none",fillRule:"evenodd",children:[jsxRuntimeExports.jsx("path",{fill:"none",d:"M0 0h24v24H0z"}),jsxRuntimeExports.jsx("mask",{id:"b",fill:"#fff",children:jsxRuntimeExports.jsx("use",{href:"#a"})}),jsxRuntimeExports.jsx("use",{fill:"#fff",fillRule:"nonzero",href:"#a"}),jsxRuntimeExports.jsx("g",{fill:"#fff",mask:"url(#b)",children:jsxRuntimeExports.jsx("path",{d:"M0 0h24v24H0z"})})]})]});const HiddenIcon=()=>jsxRuntimeExports.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",className:css(styles$g.icon),children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsx("path",{id:"a",d:"M8.794 7.38C9.791 7.127 10.86 7 12 7c4.348 0 "+"7.675 1.848 9.857 5.486a1 1 0 0 1-1.714 "+"1.028c-.945-1.574-2.12-2.73-3.544-3.48.258."+"604.401 1.268.401 1.966 0 1.02-.305 "+"1.967-.828 2.757l2.535 2.536a1 1 0 0 "+"1-1.414 1.414l-12-12a1 1 0 0 1 "+"1.414-1.414L8.794 7.38zm5.914 5.913a3 3 0 0 "+"0-4.001-4.001l4 4.001zM6.072 8.486l2.976 "+"2.976a3 3 0 0 0 3.49 3.49l1.579 1.58A5 5 0 "+"0 1 7.4 10.035c-1.424.747-2.599 1.904-3.544 "+"3.478a1 1 0 0 1-1.714-1.028c1.049-1.75 "+"2.363-3.085 3.929-4z"})}),jsxRuntimeExports.jsxs("g",{fill:"none",fillRule:"evenodd",children:[jsxRuntimeExports.jsx("path",{fill:"none",d:"M0 0h24v24H0z"}),jsxRuntimeExports.jsx("mask",{id:"b",fill:"#fff",children:jsxRuntimeExports.jsx("use",{href:"#a"})}),jsxRuntimeExports.jsx("use",{fill:"#fff",fillRule:"nonzero",href:"#a"}),jsxRuntimeExports.jsx("g",{fill:"#fff",mask:"url(#b)",children:jsxRuntimeExports.jsx("path",{d:"M0 0h24v24H0z"})})]})]});const HUD=({message,enabled,onClick,fixedPosition=true})=>{let state;let icon;if(enabled){state=styles$g.enabled;icon=jsxRuntimeExports.jsx(VisibleIcon,{});}else {state=styles$g.disabled;icon=jsxRuntimeExports.jsx(HiddenIcon,{});}return jsxRuntimeExports.jsxs("button",{className:css(styles$g.hud,fixedPosition&&styles$g.hudFixedPosition,state),onClick:e=>{onClick();},children:[icon,message]})};const styles$g=StyleSheet.create({hud:{boxSizing:"border-box",height:36,paddingBlock:"9px",paddingInline:"16px",borderRadius:18,fontFamily:boldFontFamily,fontSize:"15px",lineHeight:"18px",color:white,userSelect:"none",borderWidth:0},hudFixedPosition:{insetBlockEnd:20,position:"fixed",insetInlineEnd:20,zIndex:1},icon:{width:24,height:24,marginInlineEnd:8,marginBlockStart:-3,verticalAlign:"middle"},enabled:{backgroundColor:warningColor,":hover":{backgroundColor:warningColorHover},":active":{backgroundColor:warningColorActive}},disabled:{backgroundColor:gray76,":hover":{backgroundColor:"#a1a5a9"},":active":{backgroundColor:gray68}}});
1864
-
1865
- const BASE_ICON_SIZE=10;class Icon extends React.Component{render(){const{color,pathClassName,className,title,style,alt}=this.props;let{icon,size}=this.props;let units="";if(typeof icon==="string"){icon={path:icon,width:BASE_ICON_SIZE,height:BASE_ICON_SIZE};}if(typeof size!=="number"){size=1;units="em";}const height=size;const width=height/icon.height*icon.width;const xMin=0;const yMin=0;const focusable=!!this.props.focusable;return jsxRuntimeExports.jsxs("svg",{role:"img",alt:alt,"aria-label":title,"aria-hidden":title?null:true,className:className,style:style,focusable:focusable.toString(),width:width+units,height:height+units,viewBox:`${xMin} ${yMin} ${icon.width} ${icon.height}`,children:[!!title&&jsxRuntimeExports.jsx("title",{children:title}),jsxRuntimeExports.jsx("path",{className:pathClassName,fill:color,d:icon.path})]})}}Icon.defaultProps={color:"currentColor"};
1866
-
1867
- class MultiButtonGroup extends React.Component{focus(){this.buttonContainerRef.current?.focus();return true}render(){const values=this.props.values||[];const buttons=this.props.buttons.map((button,i)=>{const selected=values.indexOf(button.value)>=0;return jsxRuntimeExports.jsx("button",{title:button.title,type:"button",id:""+i,ref:"button"+i,className:css(buttonGroupStyles.buttonStyle,selected&&buttonGroupStyles.selectedStyle),onClick:()=>this.toggleSelect(button.value),children:button.content||""+button.value},""+i)});const outerStyle={display:"inline-block"};return jsxRuntimeExports.jsx("div",{style:outerStyle,ref:this.buttonContainerRef,children:buttons})}constructor(...args){super(...args),this.buttonContainerRef=React.createRef(),this.toggleSelect=newValue=>{const values=(this.props.values||[]).slice(0);const allowEmpty=this.props.allowEmpty;if(values.indexOf(newValue)>=0&&(values.length>1||allowEmpty)){values.splice(values.indexOf(newValue),1);}else {if(values.indexOf(newValue)<0){values.push(newValue);}}this.props.onChange(values);};}}MultiButtonGroup.defaultProps={values:[],allowEmpty:true};
1868
-
1869
- function isPiMultiple(value){if(Number.isInteger(value)){return false}return value%Math.PI===0||value%(Math.PI/2)===0||value%(Math.PI/3)===0||value%(Math.PI/4)===0||value%(Math.PI/6)===0}
1870
-
1871
- const{firstNumericalParse,captureScratchpadTouchStart}=Util;const toNumericString=KhanMath.toNumericString;const getNumericFormat=KhanMath.getNumericFormat;class NumberInput extends React.Component{componentDidMount(){const value=this.getValue();if(this.props.allowPiTruncation&&value!=null&&value!==0){if(this.state.format!=="pi"&&isPiMultiple(value)){this._setValue(value/Math.PI,"pi");this.setState({format:"pi"});}}}componentDidUpdate(){if(!number.equal(this.getValue(),this.props.value)){this._setValue(this.props.value,this.state.format);}}getValue(){return this.parseInputValue(this._getInput().value)}parseInputValue(value){if(value===""){const placeholder=this.props.placeholder;return _.isFinite(placeholder)?Number(placeholder):null}const result=firstNumericalParse(value);return _.isFinite(result)?result:this.props.value}_checkValidity(value){if(value==null){return true}const val=firstNumericalParse(value);const checkValidity=this.props.checkValidity;return val!=null&&_.isFinite(val)&&checkValidity(val)}_setValue(val,format){this._getInput().value=toNumericString(val,format);}render(){let classes=classNames$2({"number-input":true,"invalid-input":!this._checkValidity(this.props.value),mini:this.props.size==="mini",small:this.props.size==="small",normal:this.props.size==="normal"});if(this.props.className!=null){classes=classes+" "+this.props.className;}const{onFormatChange,checkValidity,useArrowKeys,allowPiTruncation,placeholder,size,...restProps}=this.props;return jsxRuntimeExports.jsx("input",{...restProps,placeholder:placeholder!=null?String(placeholder):undefined,className:classes,type:"text",ref:this.inputRef,onChange:this._handleChange,onFocus:this._handleFocus,onBlur:this._handleBlur,onKeyPress:this._handleBlur,onKeyDown:this._onKeyDown,onTouchStart:captureScratchpadTouchStart,defaultValue:toNumericString(this.props.value,this.state.format),value:undefined})}constructor(...args){super(...args),this.inputRef=React.createRef(),this.state={format:this.props.format??undefined},this._getInput=()=>{if(!this.inputRef.current){throw new PerseusError("Input ref accessed before set",Errors.Internal)}return this.inputRef.current},this.focus=()=>{this._getInput().focus();this._handleFocus();},this.blur=()=>{this._getInput().blur();this._handleBlur();},this._handleChange=e=>{const text=e.target.value;const value=this.parseInputValue(text);if(value==null){return}const format=getNumericFormat(text);this.props.onChange(value);if(format){this.props.onFormatChange?.(value,format);this.setState({format:format});}},this._handleFocus=()=>{if(this.props.onFocus){this.props.onFocus();}},this._handleBlur=e=>{if(e&&e.type==="keypress"&&e.keyCode!==13){return}this._setValue(this.props.value,this.state.format);if(this.props.onBlur){this.props.onBlur();}},this._onKeyDown=e=>{if(!this.props.useArrowKeys||!["ArrowUp","ArrowDown"].includes(e.key)){return}let val=this.getValue();if(val==null||val!==Math.floor(val)){return}if(e.key==="ArrowUp"){val=val+1;}else if(e.key==="ArrowDown"){val=val-1;}if(this._checkValidity(val)){this.props.onChange(val);}};}}NumberInput.defaultProps={value:null,placeholder:null,format:null,checkValidity:()=>true,useArrowKeys:false};
1872
-
1873
- const LegacyGrid=({box,backgroundImage})=>{const{url,width,height}=backgroundImage??{};if(url&&typeof url==="string"){const scale=box[X]/interactiveSizes$1.defaultBoxSize;return jsxRuntimeExports.jsx(View,{style:{position:"absolute",bottom:0,left:0},children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:url,allowZoom:false,width:width,height:height,scale:scale,responsive:false,setAssetStatus:setAssetStatus,alt:""})})})}return null};
1874
-
1875
- function LabelStrokeFilter(){const color=semanticColor.core.border.knockout.default;return jsxRuntimeExports.jsx("svg",{width:"0",height:"0",style:{position:"absolute"},children:jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsxs("filter",{id:"math-stroke",children:[jsxRuntimeExports.jsx("feMorphology",{operator:"dilate",radius:"2",in:"SourceGraphic",result:"expanded"}),jsxRuntimeExports.jsx("feFlood",{floodColor:color,result:"flood"}),jsxRuntimeExports.jsx("feComposite",{in:"flood",in2:"expanded",operator:"in",result:"outline"}),jsxRuntimeExports.jsxs("feMerge",{children:[jsxRuntimeExports.jsx("feMergeNode",{in:"outline"}),jsxRuntimeExports.jsx("feMergeNode",{in:"SourceGraphic"})]})]})})})}
1876
-
1877
- const labelFontSize={small:font.body.size.small,medium:font.body.size.medium,large:font.heading.size.medium};function LockedLabel(props){const{coord,text,color,size}=props;const[x,y]=pointToPixel(coord,useGraphConfig());const{TeX}=getDependencies();return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(LabelStrokeFilter,{}),jsxRuntimeExports.jsx("span",{className:"locked-label",style:{position:"absolute",left:x,top:y,color:lockedFigureColors[color],fontSize:labelFontSize[size],filter:"url(#math-stroke)"},"aria-hidden":true,children:jsxRuntimeExports.jsx(TeX,{children:replaceOutsideTeX(text)})})]})}
1878
-
1879
- function GraphLockedLabelsLayer(props){const{lockedFigures}=props;return lockedFigures.map((figure,i)=>{if(figure.type==="label"){return jsxRuntimeExports.jsx(LockedLabel,{...figure},`label-${i}`)}return jsxRuntimeExports.jsxs(React.Fragment,{children:[figure.labels.map((label,j)=>jsxRuntimeExports.jsx(LockedLabel,{...label},`${i}-label-${j}`)),figure.type==="line"&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[figure.points[0].labels.map((label,k)=>jsxRuntimeExports.jsx(LockedLabel,{...label},`locked-figure-${i}-point-1-label-${k}`)),figure.points[1].labels.map((label,k)=>jsxRuntimeExports.jsx(LockedLabel,{...label},`locked-figure-${i}-point-2-label-${k}`))]})]},i)})}
1880
-
1881
- const strokeWeights={thin:1,medium:2,thick:4};function getDashArrayForWeight(weight){const width=strokeWeights[weight];return `${4*width}, ${3*width}`}function dashedStrokeStyle(isDashed,weight){if(!isDashed){return undefined}return {"--mafs-line-stroke-dash-style":getDashArrayForWeight(weight)}}function clampDomain(domain,graphBounds){const normalizedDomain=[domain[0]===null?-Infinity:domain[0],domain[1]===null?Infinity:domain[1]];if(normalizedDomain[0]>normalizedDomain[1]){return graphBounds}if(normalizedDomain[0]<graphBounds[0]&&normalizedDomain[1]<graphBounds[0]||normalizedDomain[0]>graphBounds[1]&&normalizedDomain[1]>graphBounds[1]){return null}const min=Math.max(normalizedDomain[0],graphBounds[0]);const max=Math.min(normalizedDomain[1],graphBounds[1]);return [min,max]}
1882
-
1883
- const LockedEllipse=props=>{const{center,radius,angle,color,fillStyle,strokeStyle,weight,ariaLabel}=props;const hasAria=!!ariaLabel;return jsxRuntimeExports.jsx("g",{className:"locked-ellipse","aria-label":hasAria?ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",style:dashedStrokeStyle(strokeStyle==="dashed",weight),children:jsxRuntimeExports.jsx(Ellipse,{center:center,radius:radius,angle:angle,fillOpacity:lockedFigureFillStyles[fillStyle],strokeStyle:strokeStyle==="none"?"solid":strokeStyle,color:lockedFigureColors[color],weight:strokeWeights[weight],svgEllipseProps:{style:{fill:fillStyle==="white"?semanticColor.core.background.base.default:lockedFigureColors[color],...strokeStyle==="none"&&{stroke:"none"}}}})})};
1884
-
1885
- const LockedFunction=props=>{const{range}=useGraphConfig();const[equation,setEquation]=useState();const{color,strokeStyle,weight,directionalAxis,domain}=props;const plotProps={color:lockedFigureColors[color],style:strokeStyle,weight:strokeWeights[weight]};const hasAria=!!props.ariaLabel;useEffect(()=>{setEquation(KAS.parse(props.equation).expr);},[props.equation]);if(typeof equation==="undefined"){return null}const clampedDomain=directionalAxis==="x"?clampDomain(domain,range[0]):clampDomain(domain,range[1]);if(clampedDomain===null){return null}return jsxRuntimeExports.jsxs("g",{className:"locked-function","aria-label":hasAria?props.ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",style:dashedStrokeStyle(strokeStyle==="dashed",weight),children:[directionalAxis==="x"&&jsxRuntimeExports.jsx(Plot$2.OfX,{y:x=>equation.eval({x}),domain:clampedDomain,...plotProps}),directionalAxis==="y"&&jsxRuntimeExports.jsx(Plot$2.OfY,{x:y=>equation.eval({y}),domain:clampedDomain,...plotProps})]})};
1886
-
1887
- function SVGLine(props){const{start,end,style,className,testId}=props;return jsxRuntimeExports.jsx("line",{"aria-hidden":true,x1:start[X],y1:start[Y],x2:end[X],y2:end[Y],style:style,className:className,"data-testid":testId})}
1888
-
1889
- const{calculateAngleInDegrees: calculateAngleInDegrees$4}=angles;function Vector(props){const{interactiveColor}=useGraphConfig();const{tail,tip,color=interactiveColor,strokeWidth=2,style,testId}=props;const[tailPx,tipPx]=useTransformVectorsToPixels(tail,tip);const direction=vec.sub(tipPx,tailPx);const angle=calculateAngleInDegrees$4(direction);return jsxRuntimeExports.jsxs("g",{style:{stroke:color,strokeWidth},"data-testid":testId,children:[jsxRuntimeExports.jsx(SVGLine,{start:tailPx,end:tipPx,style:style}),jsxRuntimeExports.jsx(Arrowhead,{angle:angle,tip:tip,color:color,strokeWidth:strokeWidth})]})}
1890
-
1891
- const{calculateAngleInDegrees: calculateAngleInDegrees$3}=angles;const LockedLine=props=>{const{color,lineStyle,kind,points,showPoint1,showPoint2,weight,ariaLabel,range}=props;const[point1,point2]=points;const hasAria=!!ariaLabel;let line;if(kind==="ray"){const extendedPoint=getIntersectionOfRayWithBox(point1.coord,point2.coord,range);line=jsxRuntimeExports.jsx(Vector,{tail:point1.coord,tip:extendedPoint,color:lockedFigureColors[color],strokeWidth:strokeWeights[weight],style:{strokeDasharray:lineStyle==="dashed"?"var(--mafs-line-stroke-dash-style)":undefined}});}else {const LineType=kind==="segment"?Line$4.Segment:Line$4.ThroughPoints;let arrowTip=kind==="segment"?point2.coord:getIntersectionOfRayWithBox(point1.coord,point2.coord,range);const[tailPx,tipPx]=useTransformVectorsToPixels(point2.coord,point1.coord);const direction=vec.sub(tailPx,tipPx);let angle=calculateAngleInDegrees$3(direction);const startArrowHead=kind!=="segment"&&jsxRuntimeExports.jsx(Arrowhead,{angle:angle,tip:arrowTip,color:lockedFigureColors[color],strokeWidth:strokeWeights[weight]});arrowTip=kind==="segment"?point1.coord:getIntersectionOfRayWithBox(point2.coord,point1.coord,range);angle=angle>180?angle-180:angle+180;const endArrowHead=kind!=="segment"&&jsxRuntimeExports.jsx(Arrowhead,{angle:angle,tip:arrowTip,color:lockedFigureColors[color],strokeWidth:strokeWeights[weight]});line=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[startArrowHead,jsxRuntimeExports.jsx(LineType,{point1:point1.coord,point2:point2.coord,color:lockedFigureColors[color],weight:strokeWeights[weight],style:lineStyle}),endArrowHead]});}return jsxRuntimeExports.jsxs("g",{className:kind==="ray"?"locked-ray":"locked-line","aria-label":hasAria?ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",style:dashedStrokeStyle(lineStyle==="dashed",weight),children:[line,showPoint1&&jsxRuntimeExports.jsx(Point$2,{x:point1.coord[X],y:point1.coord[Y],svgCircleProps:{style:{fill:point1.filled?lockedFigureColors[point1.color]:semanticColor.core.background.base.default,stroke:lockedFigureColors[point1.color],strokeWidth:spacing.xxxxSmall_2}}}),showPoint2&&jsxRuntimeExports.jsx(Point$2,{x:point2.coord[X],y:point2.coord[Y],svgCircleProps:{style:{fill:point2.filled?lockedFigureColors[point2.color]:semanticColor.core.background.base.default,stroke:lockedFigureColors[point2.color],strokeWidth:spacing.xxxxSmall_2}}})]})};
1892
-
1893
- const LockedPoint=props=>{const{color,coord,filled,ariaLabel}=props;const[x,y]=coord;const hasAria=!!ariaLabel;return jsxRuntimeExports.jsx("g",{className:"locked-point","aria-label":hasAria?ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",children:jsxRuntimeExports.jsx(Point$2,{x:x,y:y,svgCircleProps:{style:{fill:filled?lockedFigureColors[color]:semanticColor.core.background.base.default,stroke:lockedFigureColors[color],strokeWidth:spacing.xxxxSmall_2}}})})};
1894
-
1895
- const LockedPolygon=props=>{const{points,color,showVertices,fillStyle,strokeStyle,weight}=props;const hasAria=!!props.ariaLabel;return jsxRuntimeExports.jsxs("g",{className:"locked-polygon","aria-label":hasAria?props.ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",style:dashedStrokeStyle(strokeStyle==="dashed",weight),children:[jsxRuntimeExports.jsx(Polygon,{points:[...points],fillOpacity:lockedFigureFillStyles[fillStyle],strokeStyle:strokeStyle==="none"?"solid":strokeStyle,color:lockedFigureColors[color],weight:strokeWeights[weight],svgPolygonProps:{style:{fill:fillStyle==="white"?semanticColor.core.background.base.default:lockedFigureColors[color],...strokeStyle==="none"&&{stroke:"none"}}}}),showVertices&&points.map((point,index)=>jsxRuntimeExports.jsx(Point$2,{x:point[X],y:point[Y],color:lockedFigureColors[color]},`locked-polygon-point-${index}`))]})};
1896
-
1897
- const LockedVector=props=>{const{color,points,weight,ariaLabel}=props;const[tail,tip]=points;const hasAria=!!ariaLabel;return jsxRuntimeExports.jsx("g",{className:"locked-vector","aria-label":hasAria?ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",children:jsxRuntimeExports.jsx(Vector,{tail:tail,tip:tip,color:lockedFigureColors[color],strokeWidth:strokeWeights[weight]})})};
1898
-
1899
- const GraphLockedLayer=props=>{const{lockedFigures}=props;return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:lockedFigures.map((figure,index)=>{switch(figure.type){case "point":return jsxRuntimeExports.jsx(LockedPoint,{...figure},`point-${index}`);case "line":return jsxRuntimeExports.jsx(LockedLine,{range:props.range,...figure},`line-${index}`);case "vector":return jsxRuntimeExports.jsx(LockedVector,{...figure},`vector-${index}`);case "ellipse":return jsxRuntimeExports.jsx(LockedEllipse,{...figure},`ellipse-${index}`);case "polygon":return jsxRuntimeExports.jsx(LockedPolygon,{...figure},`polygon-${index}`);case "function":return jsxRuntimeExports.jsx(LockedFunction,{...figure},`function-${index}`);case "label":return null;default:throw new UnreachableCaseError(figure)}})})};
1900
-
1901
- const actions={global:{deleteIntent,changeInteractionMode,changeKeyboardInvitationVisibility},angle:{movePoint},circle:{moveCenter,moveRadiusPoint},linear:{moveLine:newStart=>moveLine(0,newStart),movePoint:(pointIndex,destination)=>movePointInFigure(0,pointIndex,destination)},linearSystem:{moveLine,movePointInFigure},pointGraph:{movePoint,addPoint,removePoint,focusPoint,blurPoint,clickPoint},polygon:{movePoint,moveAll,addPoint,removePoint,focusPoint,blurPoint,clickPoint,closePolygon,openPolygon},quadratic:{movePoint},ray:{moveRay:newStart=>moveLine(0,newStart),movePoint:(pointIndex,destination)=>movePointInFigure(0,pointIndex,destination)},segment:{movePointInFigure,moveLine},sinusoid:{movePoint},exponential:{movePoint,moveCenter},logarithm:{movePoint,moveCenter},absoluteValue:{movePoint},tangent:{movePoint},vector:{moveTip:destination=>movePointInFigure(0,1,destination),moveVector:newStart=>moveLine(0,newStart)}};const DELETE_INTENT="delete-intent";function deleteIntent(){return {type:DELETE_INTENT}}const MOVE_LINE="move-line";function moveLine(itemIndex,newStart){return {type:MOVE_LINE,itemIndex,newStart}}const ADD_POINT="add-point";function addPoint(location){return {type:ADD_POINT,location}}const REMOVE_POINT="remove-point";function removePoint(index){return {type:REMOVE_POINT,index}}const FOCUS_POINT="focus-point";function focusPoint(index){return {type:FOCUS_POINT,index}}const BLUR_POINT="blur-point";function blurPoint(){return {type:BLUR_POINT}}const CLICK_POINT="click-point";function clickPoint(index){return {type:CLICK_POINT,index}}const CHANGE_INTERACTION_MODE="point-change-interaction-mode";function changeInteractionMode(mode){return {type:CHANGE_INTERACTION_MODE,mode}}const CHANGE_KEYBOARD_INVITATION_VISIBILITY="change-keyboard-interaction-invitation-visibility";function changeKeyboardInvitationVisibility(shouldShow){return {type:CHANGE_KEYBOARD_INVITATION_VISIBILITY,shouldShow}}const CLOSE_POLYGON="close-polygon";function closePolygon(){return {type:CLOSE_POLYGON}}const OPEN_POLYGON="open-polygon";function openPolygon(){return {type:OPEN_POLYGON}}const MOVE_ALL="move-all";function moveAll(newStart){return {type:MOVE_ALL,newStart}}const MOVE_POINT="move-point";function movePoint(index,destination){return {type:MOVE_POINT,index,destination}}const MOVE_POINT_IN_FIGURE="move-point-in-figure";function movePointInFigure(figureIndex,pointIndex,destination){return {type:MOVE_POINT_IN_FIGURE,figureIndex,pointIndex,destination}}const MOVE_CENTER="move-center";function moveCenter(destination){return {type:MOVE_CENTER,destination}}const MOVE_RADIUS_POINT="MOVE_RADIUS_POINT";function moveRadiusPoint(destination){return {type:MOVE_RADIUS_POINT,destination}}const CHANGE_SNAP_STEP="change-snap-step";function changeSnapStep(snapStep){return {type:CHANGE_SNAP_STEP,snapStep}}const CHANGE_RANGE="change-range";function changeRange(range){return {type:CHANGE_RANGE,range}}const REINITIALIZE="reinitialize";function reinitialize(params){return {type:REINITIALIZE,params}}
1902
-
1903
- function ClipToGraphBounds({children,expand}){const{range,graphDimensionsInPixels}=useGraphConfig();const[pixelWidth,pixelHeight]=graphDimensionsInPixels;const{viewboxX,viewboxY}=calculateNestedSVGCoords(range,pixelWidth,pixelHeight);const{top=0,right=0,bottom=0,left=0}=expand??{};const x=viewboxX-left;const y=viewboxY-top;const clipWidth=pixelWidth+left+right;const clipHeight=pixelHeight+top+bottom;return jsxRuntimeExports.jsx("svg",{width:clipWidth,height:clipHeight,viewBox:`${x} ${y} ${clipWidth} ${clipHeight}`,preserveAspectRatio:"xMidYMin",x:x,y:y,children:children})}
1904
-
1905
- function useDraggable(args){const{gestureTarget:target,onMove,onDragStart,onDragEnd,point,constrainKeyboardMovement}=args;const[dragging,setDragging]=React.useState(false);const{xSpan,ySpan}=useSpanContext();const{viewTransform,userTransform}=useTransformContext();const inverseViewTransform=vec.matrixInvert(viewTransform);invariant(inverseViewTransform,"The view transform must be invertible.");const inverseTransform=React.useMemo(()=>getInverseTransform(userTransform),[userTransform]);const pickup=React.useRef([0,0]);const dragStarted=React.useRef(false);useDrag(state=>{const{type,event}=state;const isKeyboard=type.includes("key");if(isKeyboard){invariant(event instanceof KeyboardEvent);event?.stopPropagation();event?.preventDefault();if(type==="keyup"){return}if(typeof constrainKeyboardMovement==="object"){const destination=constrainKeyboardMovement[directionForKey[event.key]];onMove(destination??point);return}const{direction:yDownDirection,altKey,ctrlKey,metaKey,shiftKey}=state;const direction=[yDownDirection[X],-yDownDirection[Y]];const span=Math.abs(direction[X])?xSpan:ySpan;let divisions=50;if(altKey||metaKey){divisions=200;}if(shiftKey&&!ctrlKey){divisions=10;}const min=span/(divisions*2);const tests=range(span/divisions,span/2,span/divisions);for(const dx of tests){const testMovement=vec.scale(direction,dx);const testPoint=constrainKeyboardMovement(vec.transform(vec.add(vec.transform(point,userTransform),testMovement),inverseTransform));if(vec.dist(testPoint,point)>min){onMove(testPoint);break}}}else {const{last,movement:pixelMovement,first}=state;setDragging(!last);if(last&&onDragEnd){onDragEnd();}if(first){pickup.current=vec.transform(point,userTransform);dragStarted.current=false;}if(vec.mag(pixelMovement)===0){return}event?.stopPropagation();event?.preventDefault();if(!dragStarted.current){dragStarted.current=true;onDragStart?.();}const zoomFactor=target.current?getCSSZoomFactor(target.current):1;const unzoomedPixelMovement=vec.scale(pixelMovement,1/zoomFactor);const movement=vec.transform(unzoomedPixelMovement,inverseViewTransform);onMove(vec.transform(vec.add(pickup.current,movement),inverseTransform));}},{target,eventOptions:{passive:false}});return {dragging}}const directionForKey={ArrowLeft:"left",ArrowRight:"right",ArrowUp:"up",ArrowDown:"down"};function getInverseTransform(transform){const invert=vec.matrixInvert(transform);invariant(invert!==null,"Could not invert transform matrix. A parent transformation matrix might be degenerative (mapping 2D space to a line).");return invert}function useSpanContext(){const{range:[[xMin,xMax],[yMin,yMax]]}=useGraphConfig();const xSpan=xMax-xMin;const ySpan=yMax-yMin;return {xSpan,ySpan}}function range(min,max,step=1){const result=[];for(let i=min;i<max-step/2;i+=step){result.push(i);}const computedMax=result[result.length-1]+step;if(Math.abs(max-computedMax)<step/1e-6){result.push(max);}else {result.push(computedMax);}return result}
1906
-
1907
- const HitboxLayerContext=React.createContext(null);
1908
-
1909
- const HANDLE_HITBOX_SIZE_PX=48;function useHitbox(params){const{shape,hitboxRef,layer="handle",cursor,dragging=false,onClick,onHoverChange,testId}=params;const layerEl=useContext(HitboxLayerContext);const graphConfig=useGraphConfig();if(!layerEl){return null}if(shape.kind==="polygon"&&shape.vertices.length<3){return null}return createPortal(jsxRuntimeExports.jsx("div",{ref:hitboxRef,"aria-hidden":true,"data-testid":testId,style:{position:"absolute",touchAction:"none",pointerEvents:"auto",zIndex:layer==="body"?1:2,cursor:dragging?"grabbing":cursor??"grab",...shapeStyle(shape,graphConfig)},onClick:onClick,onPointerEnter:()=>onHoverChange?.(true),onPointerLeave:()=>onHoverChange?.(false)}),layerEl)}function shapeStyle(shape,graphConfig){switch(shape.kind){case "box":{const[x,y]=pointToPixel(shape.center,graphConfig);return {left:x,top:y,width:shape.sizePx,height:shape.sizePx,transform:"translate(-50%, -50%)"}}case "line":{const[sx,sy]=pointToPixel(shape.start,graphConfig);const[ex,ey]=pointToPixel(shape.end,graphConfig);const dx=ex-sx;const dy=ey-sy;const length=Math.hypot(dx,dy);const angleDeg=Math.atan2(dy,dx)*180/Math.PI;return {left:(sx+ex)/2,top:(sy+ey)/2,width:length,height:shape.thicknessPx,transform:`translate(-50%, -50%) rotate(${angleDeg}deg)`}}case "ellipse":{const[cx,cy]=pointToPixel(shape.center,graphConfig);const[[rxPx,ryPx]]=dimensionsToPixels([shape.radius],graphConfig);return {left:cx,top:cy,width:rxPx*2,height:ryPx*2,transform:"translate(-50%, -50%)",borderRadius:"50%"}}case "polygon":{const pts=shape.vertices.map(v=>pointToPixel(v,graphConfig));const xs=pts.map(p=>p[0]);const ys=pts.map(p=>p[1]);const minX=Math.min(...xs);const minY=Math.min(...ys);const maxX=Math.max(...xs);const maxY=Math.max(...ys);const clip=pts.map(([px,py])=>`${px-minX}px ${py-minY}px`).join(", ");return {left:minX,top:minY,width:maxX-minX,height:maxY-minY,clipPath:`polygon(${clip})`}}}}
1910
-
1911
- function Hairlines(props){const{point}=props;const{range}=useGraphConfig();const[[xMin,xMax],[yMin,yMax]]=range;const[[x,y]]=useTransformVectorsToPixels(point);const[[verticalStartX]]=useTransformVectorsToPixels([xMin,0]);const[[verticalEndX]]=useTransformVectorsToPixels([xMax,0]);const[[,horizontalStartY]]=useTransformVectorsToPixels([0,yMin]);const[[,horizontalEndY]]=useTransformVectorsToPixels([0,yMax]);return jsxRuntimeExports.jsxs("g",{"aria-hidden":true,children:[jsxRuntimeExports.jsx("line",{x1:verticalStartX,y1:y,x2:verticalEndX,y2:y,stroke:semanticColor.core.border.instructive.default}),jsxRuntimeExports.jsx("line",{x1:x,y1:horizontalStartY,x2:x,y2:horizontalEndY,stroke:semanticColor.core.border.instructive.default})]})}
1912
-
1913
- const MovablePointView=forwardRef(function MovablePointViewWithRef(props,hitboxRef){const{markings,showTooltips,interactiveColor,snapStep}=useGraphConfig();const{point,dragging,focused,hovered,cursor,showFocusRing,onClick=()=>{}}=props;const pointClasses=classNames$1("movable-point",dragging&&"movable-point--dragging",showFocusRing&&"movable-point--focus",hovered&&"movable-point--hover");const[[x,y]]=useTransformVectorsToPixels(point);const showHairlines=(dragging||focused)&&markings!=="none";const xSigFigs=countSignificantDecimals(snapStep[X]);const ySigFigs=countSignificantDecimals(snapStep[Y]);const xTickLabel=point[X].toFixed(xSigFigs);const yTickLabel=point[Y].toFixed(ySigFigs);const pointTooltipContent=`(${xTickLabel}, ${yTickLabel})`;const svgForPoint=jsxRuntimeExports.jsxs("g",{"aria-hidden":true,ref:hitboxRef,className:pointClasses,style:{"--movable-point-color":interactiveColor,cursor},"data-testid":"movable-point",onClick:onClick,children:[jsxRuntimeExports.jsx("circle",{className:"movable-point-halo",cx:x,cy:y}),jsxRuntimeExports.jsx("circle",{className:"movable-point-ring",cx:x,cy:y}),jsxRuntimeExports.jsx("circle",{className:"movable-point-focus-outline",cx:x,cy:y}),jsxRuntimeExports.jsx("circle",{className:"movable-point-center",cx:x,cy:y,style:{fill:interactiveColor},"data-testid":"movable-point__center"})]});return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[showHairlines&&jsxRuntimeExports.jsx(Hairlines,{point:point}),showTooltips?jsxRuntimeExports.jsx(Tooltip,{autoUpdate:true,opened:true,variant:"strong",content:pointTooltipContent,children:svgForPoint}):svgForPoint]})});function classNames$1(...names){return names.filter(Boolean).join(" ")}
1914
-
1915
- function useControlPoint(params){const{snapStep,disableKeyboardInteraction}=useGraphConfig();const{point,ariaDescribedBy,ariaLabel,constrain=p=>snap(snapStep,p),cursor,forwardedRef=noop$2,sequenceNumber=1,onMove=noop$2,onDragStart=noop$2,onDragEnd=noop$2,onClick=noop$2,onFocus=noop$2,onBlur=noop$2}=params;const{strings,locale}=usePerseusI18n();const[focused,setFocused]=useState(false);const[hovered,setHovered]=useState(false);const focusableHandleRef=useRef(null);useDraggable({gestureTarget:focusableHandleRef,point,onMove,onDragEnd,constrainKeyboardMovement:constrain});const visiblePointRef=useRef(null);const hitboxDivRef=useRef(null);const{dragging}=useDraggable({gestureTarget:hitboxDivRef,point,onMove,onDragStart,onDragEnd,constrainKeyboardMovement:constrain});const focusPoint=()=>{onClick();focusableHandleRef.current?.focus();};const hitbox=useHitbox({shape:{kind:"box",center:point,sizePx:HANDLE_HITBOX_SIZE_PX},hitboxRef:hitboxDivRef,cursor,dragging,onClick:focusPoint,onHoverChange:setHovered,testId:"movable-point__hitbox"});const pointAriaLabel=ariaLabel||strings.srPointAtCoordinates({pointLabel:`${sequenceNumber}`,x:srFormatNumber(point[X],locale),y:srFormatNumber(point[Y],locale)});useLayoutEffect(()=>{setForwardedRef(forwardedRef,focusableHandleRef.current);},[forwardedRef]);useLayoutEffect(()=>{if(dragging&&!focused){focusableHandleRef.current?.focus({preventScroll:true});}},[dragging,focused]);const focusableHandle=jsxRuntimeExports.jsx("g",{"data-testid":"movable-point__focusable-handle",className:"movable-point__focusable-handle",tabIndex:disableKeyboardInteraction?-1:0,ref:focusableHandleRef,role:"button","aria-describedby":ariaDescribedBy,"aria-label":pointAriaLabel,"aria-disabled":disableKeyboardInteraction,onFocus:event=>{onFocus(event);setFocused(true);},onBlur:event=>{onBlur(event);setFocused(false);}});const visiblePoint=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[hitbox,jsxRuntimeExports.jsx(MovablePointView,{cursor:cursor,onClick:focusPoint,point:point,dragging:dragging,focused:focused,hovered:hovered,ref:visiblePointRef,showFocusRing:focused})]});return {focusableHandle,visiblePoint,focusableHandleRef,visiblePointRef}}function setForwardedRef(ref,value){if(typeof ref==="function"){ref(value);}else if(ref!==null){ref.current=value;}}const noop$2=()=>{};
1916
-
1917
- const MovablePoint$3=React.forwardRef(function MovablePointWithRef(props,pointRef){const{visiblePoint,focusableHandle}=useControlPoint({...props,forwardedRef:pointRef});return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[focusableHandle,visiblePoint]})});
1918
-
1919
- function SRDescInSVG(props){const{id,children}=props;return jsxRuntimeExports.jsx("foreignObject",{children:jsxRuntimeExports.jsx("span",{id:id,style:a11y.srOnly,"aria-hidden":true,children:children})})}
1920
-
1921
- function renderAbsoluteValueGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(AbsoluteValueGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:getAbsoluteValueDescription(state,i18n)}}function AbsoluteValueGraph(props){const{dispatch,graphState}=props;const{interactiveColor}=useGraphConfig();const i18n=usePerseusI18n();const id=React.useId();const descriptionId=id+"-description";const slopeDescriptionId=id+"-slope";const{coords,snapStep}=graphState;const coeffRef=React.useRef({m:1,h:0,v:0});const coeffs=getAbsoluteValueCoefficients$1(coords);if(Number.isFinite(coeffs.m)){coeffRef.current=coeffs;}const{m,h,v}=coeffRef.current;const{srAbsoluteValueGraph,srAbsoluteValueVertexPoint,srAbsoluteValueArmPoint,srAbsoluteValueDescription:srDescription,srAbsoluteValueSlope}=describeAbsoluteValueGraph(graphState,i18n);return jsxRuntimeExports.jsxs("g",{"aria-label":srAbsoluteValueGraph,"aria-describedby":descriptionId,children:[jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(Plot$2.OfX,{y:x=>m*Math.abs(x-h)+v,color:interactiveColor,svgPathProps:{"aria-hidden":true}})}),coords.map((coord,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{ariaLabel:i===0?srAbsoluteValueVertexPoint:srAbsoluteValueArmPoint,ariaDescribedBy:i===1?slopeDescriptionId:undefined,point:coord,sequenceNumber:i+1,constrain:getAbsoluteValueKeyboardConstraint(coords,snapStep,i),onMove:destination=>dispatch(actions.absoluteValue.movePoint(i,destination))},"point-"+i)),jsxRuntimeExports.jsx(SRDescInSVG,{id:descriptionId,children:srDescription}),jsxRuntimeExports.jsx(SRDescInSVG,{id:slopeDescriptionId,children:srAbsoluteValueSlope})]})}const getAbsoluteValueKeyboardConstraint=(coords,snapStep,pointIndex)=>{const coordToBeMoved=coords[pointIndex];const otherPoint=coords[1-pointIndex];const moveWithConstraint=moveFunc=>{let movedCoord=moveFunc(coordToBeMoved);if(movedCoord[X]===otherPoint[X]){movedCoord=moveFunc(movedCoord);}return movedCoord};return {up:vec.add(coordToBeMoved,[0,snapStep[Y]]),down:vec.sub(coordToBeMoved,[0,snapStep[Y]]),left:moveWithConstraint(coord=>vec.sub(coord,[snapStep[X],0])),right:moveWithConstraint(coord=>vec.add(coord,[snapStep[X],0]))}};function getAbsoluteValueDescription(state,i18n){const{strings}=i18n;const{coords}=state;const{locale}=i18n;const[p1,p2]=coords;const slope=getAbsoluteValueCoefficients$1(coords).m;return strings.srInteractiveElements({elements:strings.srAbsoluteValueInteractiveElements({point1X:srFormatNumber(p1[X],locale),point1Y:srFormatNumber(p1[Y],locale),point2X:srFormatNumber(p2[X],locale),point2Y:srFormatNumber(p2[Y],locale),slope:srFormatNumber(slope,locale)})})}
1922
-
1923
- const MafsCssTransformWrapper=({children})=>jsxRuntimeExports.jsx("g",{style:{transform:`var(--mafs-view-transform) var(--mafs-user-transform)`},children:children});
1924
-
1925
- const TextLabel=({children,...rest})=>jsxRuntimeExports.jsx(Text$1,{size:16,svgTextProps:{filter:"url(#background)",fontWeight:font.weight.bold},...rest,children:children});const SvgDefs=()=>jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsxs("filter",{id:"background",x:"-5%",width:"110%",y:"0%",height:"100%",children:[jsxRuntimeExports.jsx("feFlood",{floodColor:semanticColor.core.background.base.default,floodOpacity:"0.64"}),jsxRuntimeExports.jsx("feComposite",{operator:"over",in:"SourceGraphic"})]})});
1926
-
1927
- const{clockwise: clockwise$1}=geometry;const{getAngleFromVertex: getAngleFromVertex$1}=angles;const PolygonAngle=({centerPoint,endPoints,showAngles,snapTo,areEndPointsClockwise})=>{const{range}=useGraphConfig();const[centerX,centerY]=centerPoint;const[[startX,startY],[endX,endY]]=areEndPointsClockwise?endPoints:endPoints.reverse();const radius=calculateScaledRadius(range);const a=vec.dist(centerPoint,endPoints[0]);const b=vec.dist(centerPoint,endPoints[1]);const c=vec.dist(endPoints[0],endPoints[1]);let lawOfCosinesRadicand=(a**2+b**2-c**2)/(2*a*b);if(lawOfCosinesRadicand<-1||lawOfCosinesRadicand>1){lawOfCosinesRadicand=Math.round(lawOfCosinesRadicand);}const angle=Math.acos(lawOfCosinesRadicand);const y1=centerY+(startY-centerY)/a*radius;const x2=centerX+(endX-centerX)/b*radius;const x1=centerX+(startX-centerX)/a*radius;const y2=centerY+(endY-centerY)/b*radius;const[x3,y3]=vec.add(centerPoint,vec.add(vec.sub([x1,y1],centerPoint),vec.sub([x2,y2],centerPoint)));if(!showAngles){return isRightPolygonAngle(angle)?jsxRuntimeExports.jsx(RightAngleSquare,{start:[x1,y1],vertex:[x2,y2],end:[x3,y3],nonScalingStroke:true}):null}const isConcave=isConcavePolygonVertex(centerPoint,endPoints);const largeArcFlag=isConcave?1:0;const arc=`M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2}`;let angleInDegrees=angle*(180/Math.PI);if(isConcave){angleInDegrees=360-angleInDegrees;}const angleLabelNumber=parseFloat(angleInDegrees.toFixed(snapTo==="angles"?0:1));const angleLabel=Number.isInteger(angleLabelNumber)?angleLabelNumber:"≈ "+angleLabelNumber;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsxs("filter",{id:"background",x:"-5%",width:"110%",y:"0%",height:"100%",children:[jsxRuntimeExports.jsx("feFlood",{floodColor:semanticColor.core.background.base.default,floodOpacity:"0.5"}),jsxRuntimeExports.jsx("feComposite",{operator:"over",in:"SourceGraphic"})]})}),!isConcave&&isRightPolygonAngle(angle)?jsxRuntimeExports.jsx(RightAngleSquare,{start:[x1,y1],vertex:[x2,y2],end:[x3,y3],nonScalingStroke:true}):jsxRuntimeExports.jsx(Arc,{arc:arc,nonScalingStroke:true}),jsxRuntimeExports.jsxs(TextLabel,{x:x3,y:y3,attach:y3-centerY>0?"s":"n",attachDistance:Math.abs(y3-centerY)<.2||vec.dist([x3,y3],centerPoint)<.3?20:10,children:[angleLabel,"°"]})]})};const Angle=({vertex,coords,showAngles,allowReflexAngles,range})=>{const areClockwise=clockwise$1([...coords,vertex]);const shouldReverseCoords=areClockwise&&!allowReflexAngles;const clockwiseCoords=shouldReverseCoords?coords:coords.reverse();const startAngle=getAngleFromVertex$1(clockwiseCoords[0],vertex);const endAngle=getAngleFromVertex$1(clockwiseCoords[1],vertex);const angle=(startAngle+360-endAngle)%360;const isReflexive=angle>180;const[centerX,centerY]=vertex;const[point1,point2]=clockwiseCoords;const[startX,startY]=point1;const[endX,endY]=point2;const a=vec.dist(vertex,point1);const b=vec.dist(vertex,point2);const radius=2;const y1=centerY+(startY-centerY)/a*radius;const x2=centerX+(endX-centerX)/b*radius;const x1=centerX+(startX-centerX)/a*radius;const y2=centerY+(endY-centerY)/b*radius;const[x3,y3]=vec.add(vertex,vec.add(vec.sub([x1,y1],vertex),vec.sub([x2,y2],vertex)));const isOutside=shouldDrawArcOutside([x3,y3],vertex,range,[[vertex,point1],[vertex,point2]]);const largeArcFlag=isOutside||isReflexive?1:0;const sweepFlag=isOutside&&isReflexive?1:0;const arc=`M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${x2} ${y2}`;const angleLabel=parseFloat(angle.toFixed(0));const[textX,textY]=calculateBisectorPoint(point1,point2,vertex,isReflexive,allowReflexAngles,radius);const{disableKeyboardInteraction}=useGraphConfig();const arcClassName=disableKeyboardInteraction?"angle-arc-static":"angle-arc-interactive";return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsxs("filter",{id:"background",x:"-5%",width:"110%",y:"0%",height:"100%",children:[jsxRuntimeExports.jsx("feFlood",{floodColor:semanticColor.core.background.base.default,floodOpacity:"0.5"}),jsxRuntimeExports.jsx("feComposite",{operator:"over",in:"SourceGraphic"})]})}),isRightAngle(angle)?jsxRuntimeExports.jsx(RightAngleSquare,{start:[x1,y1],vertex:[x2,y2],end:[x3,y3],className:arcClassName}):jsxRuntimeExports.jsx(Arc,{arc:arc,className:arcClassName}),showAngles&&jsxRuntimeExports.jsxs(TextLabel,{x:textX,y:textY,color:semanticColor.core.foreground.instructive.default,children:[angleLabel,"°"]})]})};const RightAngleSquare=({start:[x1,y1],vertex:[x2,y2],end:[x3,y3],className,nonScalingStroke})=>jsxRuntimeExports.jsx(MafsCssTransformWrapper,{children:jsxRuntimeExports.jsx("path",{"aria-hidden":true,d:`M ${x1} ${y1} L ${x3} ${y3} M ${x3} ${y3} L ${x2} ${y2}`,strokeWidth:1,fill:"none",className:className,"data-testid":"angle-indicators__right-angle",vectorEffect:nonScalingStroke?"non-scaling-stroke":"none"})});const Arc=({arc,className,nonScalingStroke})=>{return jsxRuntimeExports.jsx(MafsCssTransformWrapper,{children:jsxRuntimeExports.jsx("path",{"aria-hidden":true,d:arc,strokeWidth:1,fill:"none",className:className,"data-testid":"angle-indicators__arc",vectorEffect:nonScalingStroke?"non-scaling-stroke":"none"})})};const isRightPolygonAngle=angle=>Math.abs(angle-Math.PI/2)<.01;const isRightAngle=angle=>Math.round(angle)===90;const shouldDrawArcOutside=(midpoint,vertex,range,polygonLines)=>{const rangeIntersectionPoint=getIntersectionOfRayWithBox(midpoint,vertex,range);let lineIntersectionCount=0;polygonLines.forEach(line=>segmentsIntersect([vertex,rangeIntersectionPoint],line)&&lineIntersectionCount++);return !isEven(lineIntersectionCount)};const isEven=n=>n%2===0;function isConcavePolygonVertex(centerPoint,clockwiseEndpoints){const v1=vec.sub(clockwiseEndpoints[1],centerPoint);const v2=vec.sub(clockwiseEndpoints[0],centerPoint);const crossProduct=v1[0]*v2[1]-v1[1]*v2[0];return crossProduct>0}function calculateBisectorPoint(point1,point2,vertex,isReflex,allowReflex,arcRadius){const[originX,originY]=vertex;const[x1,y1]=point1;const[x2,y2]=point2;const vectorA=[x1-originX,y1-originY];const vectorB=[x2-originX,y2-originY];const angleA=Math.atan2(vectorA[1],vectorA[0]);const angleB=Math.atan2(vectorB[1],vectorB[0]);let averageAngle=(angleA+angleB)/2;const angleRadians=Math.abs(angleA-angleB);if(allowReflex){if(angleRadians<=Math.PI&&isReflex||angleB>angleA){averageAngle+=Math.PI;}}else {if(angleRadians>Math.PI){averageAngle-=Math.PI;}}const sum=[Math.cos(averageAngle),Math.sin(averageAngle)];const sumMagnitude=Math.sqrt(sum[0]**2+sum[1]**2);const bisectorDirection=[sum[0]/sumMagnitude,sum[1]/sumMagnitude];const initialDistance=Math.sqrt(bisectorDirection[0]**2+bisectorDirection[1]**2);const requiredDistance=arcRadius*1.75;let radius=requiredDistance/initialDistance;if(initialDistance>=requiredDistance){radius=1;}const bisectorPoint=[bisectorDirection[0]*radius,bisectorDirection[1]*radius];const scaledBisector=vec.add(bisectorPoint,vertex);return scaledBisector}
1928
-
1929
- const getMovableLineKeyboardConstraint=(line,snapStep,pointIndex)=>{const coordToBeMoved=line[pointIndex];const otherPoint=line[1-pointIndex];const movePointWithConstraint=moveFunc=>{let movedCoord=moveFunc(coordToBeMoved);if(vec.dist(movedCoord,otherPoint)===0){movedCoord=moveFunc(movedCoord);}return movedCoord};return {up:movePointWithConstraint(coord=>vec.add(coord,[0,snapStep[1]])),down:movePointWithConstraint(coord=>vec.sub(coord,[0,snapStep[1]])),left:movePointWithConstraint(coord=>vec.sub(coord,[snapStep[0],0])),right:movePointWithConstraint(coord=>vec.add(coord,[snapStep[0],0]))}};const GRAPH_EDGE_INSET_PX=4;function trimRange(range,graphDimensionsInPixels){const[xRange,yRange]=range;const[pixelsWide,pixelsTall]=graphDimensionsInPixels;const graphUnitsPerPixelX=size(xRange)/pixelsWide;const graphUnitsPerPixelY=size(yRange)/pixelsTall;const graphUnitsToTrimX=GRAPH_EDGE_INSET_PX*graphUnitsPerPixelX;const graphUnitsToTrimY=GRAPH_EDGE_INSET_PX*graphUnitsPerPixelY;return inset([graphUnitsToTrimX,graphUnitsToTrimY],range)}function insetTipAlongRay(tail,tip,range,graphDimensionsInPixels){const dx=tip[0]-tail[0];const dy=tip[1]-tail[1];const[pixelsWide,pixelsTall]=graphDimensionsInPixels;const pxPerUnitX=pixelsWide/size(range[0]);const pxPerUnitY=pixelsTall/size(range[1]);const lenPx=Math.hypot(dx*pxPerUnitX,dy*pxPerUnitY);if(lenPx===0){return tip}const scale=GRAPH_EDGE_INSET_PX/lenPx;return [tip[0]-dx*scale,tip[1]-dy*scale]}
1930
-
1931
- const Line$2=props=>{const{start,end,ariaLabel,ariaDescribedBy,extend,onMove}=props;const[startPtPx,endPtPx]=useTransformVectorsToPixels(start,end);const{range,graphDimensionsInPixels,snapStep,disableKeyboardInteraction,interactiveColor}=useGraphConfig();const computeExtensionTip=(tail,source)=>insetTipAlongRay(tail,getIntersectionOfRayWithBox(source,tail,range),range,graphDimensionsInPixels);const startExtend=extend?.start?computeExtensionTip(start,end):undefined;const endExtend=extend?.end?computeExtensionTip(end,start):undefined;const line=useRef(null);const lineHitboxRef=useRef(null);const[hovered,setHovered]=useState(false);useDraggable({gestureTarget:line,point:start,onMove,constrainKeyboardMovement:p=>snap(snapStep,p)});const{dragging}=useDraggable({gestureTarget:lineHitboxRef,point:start,onMove,constrainKeyboardMovement:p=>snap(snapStep,p)});const lineHitbox=useHitbox({shape:{kind:"line",start,end,thicknessPx:TARGET_SIZE},hitboxRef:lineHitboxRef,layer:"body",dragging,onHoverChange:setHovered,testId:"movable-line__hitbox"});return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[lineHitbox,jsxRuntimeExports.jsxs("g",{ref:line,tabIndex:disableKeyboardInteraction?-1:0,"aria-label":ariaLabel,"aria-describedby":ariaDescribedBy,"aria-disabled":disableKeyboardInteraction,className:hovered?"movable-line movable-line--hover":"movable-line","data-testid":"movable-line",style:{cursor:dragging?"grabbing":"grab"},role:"button",children:[jsxRuntimeExports.jsx(SVGLine,{start:startPtPx,end:endPtPx,className:"movable-line-focus-outline",style:{}}),jsxRuntimeExports.jsx(SVGLine,{start:startPtPx,end:endPtPx,className:"movable-line-focus-outline-gap",style:{}}),jsxRuntimeExports.jsx(SVGLine,{start:startPtPx,end:endPtPx,style:{stroke:interactiveColor,strokeWidth:"var(--movable-line-stroke-weight)"},className:dragging?"movable-dragging":"",testId:"movable-line__line"})]}),startExtend&&jsxRuntimeExports.jsx(Vector,{tail:start,tip:startExtend,testId:"movable-line__vector"}),endExtend&&jsxRuntimeExports.jsx(Vector,{tail:end,tip:endExtend,testId:"movable-line__vector"})]})};
1932
-
1933
- const MovableLine$2=props=>{const{points:[start,end],ariaLabels,ariaDescribedBy,extend,onMoveLine=()=>{},onMovePoint=()=>{}}=props;const{snapStep}=useGraphConfig();const{visiblePoint:visiblePoint1,focusableHandle:focusableHandle1}=useControlPoint({ariaLabel:ariaLabels?.point1AriaLabel,ariaDescribedBy:ariaDescribedBy,point:start,sequenceNumber:1,onMove:p=>{onMovePoint(0,p);},constrain:getMovableLineKeyboardConstraint([start,end],snapStep,0)});const{visiblePoint:visiblePoint2,focusableHandle:focusableHandle2}=useControlPoint({ariaLabel:ariaLabels?.point2AriaLabel,ariaDescribedBy:ariaDescribedBy,point:end,sequenceNumber:2,onMove:p=>{onMovePoint(1,p);},constrain:getMovableLineKeyboardConstraint([start,end],snapStep,1)});const line=jsxRuntimeExports.jsx(Line$2,{ariaLabel:ariaLabels?.grabHandleAriaLabel,ariaDescribedBy:ariaDescribedBy,start:start,end:end,extend:extend,onMove:newStart=>{onMoveLine(newStart);}});return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[focusableHandle1,line,focusableHandle2,visiblePoint1,visiblePoint2]})};
1934
-
1935
- const{calculateAngleInDegrees: calculateAngleInDegrees$2,polar: polar$1}=angles;function renderAngleGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(AngleGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:getAngleGraphDescription(state,i18n)}}function AngleGraph(props){const{dispatch,graphState}=props;const{graphDimensionsInPixels,interactiveColor}=useGraphConfig();const i18n=usePerseusI18n();const id=React.useId();const descriptionId=id+"-description";const{coords,showAngles,range,allowReflexAngles,snapDegrees}=graphState;const endPoints=[coords[0],coords[2]];const centerPoint=coords[1];const angleLines=[[centerPoint,endPoints[0]],[centerPoint,endPoints[1]]];const linePixelCoords=[useTransformVectorsToPixels(centerPoint,endPoints[0]),useTransformVectorsToPixels(centerPoint,endPoints[1])];const svgLines=linePixelCoords.map(([startPtPx,endPtPx],i)=>{const trimmedRange=trimRange(range,graphDimensionsInPixels);const endExtend=getIntersectionOfRayWithBox(angleLines[i][0],angleLines[i][1],trimmedRange);return jsxRuntimeExports.jsxs("g",{children:[jsxRuntimeExports.jsx(SVGLine,{start:startPtPx,end:endPtPx,style:{stroke:interactiveColor,strokeWidth:"var(--movable-line-stroke-weight)"},testId:"angle-graph__line"}),jsxRuntimeExports.jsx(Vector,{tail:angleLines[i][1],tip:endExtend,testId:"angle-graph__vector"})]},`line-${i}`)});const angleParams={vertex:centerPoint,coords:endPoints,allowReflexAngles:allowReflexAngles||false,snapDegrees:snapDegrees||1,range:range,showAngles:showAngles||false};const{srAngleGraphAriaLabel,srAngleGraphAriaDescription,srAngleStartingSide,srAngleEndingSide,srAngleVertex}=describeAngleGraph(graphState,i18n);return jsxRuntimeExports.jsxs("g",{"aria-label":srAngleGraphAriaLabel,"aria-describedby":descriptionId,children:[svgLines,jsxRuntimeExports.jsx(Angle,{...angleParams}),jsxRuntimeExports.jsx(MovablePoint$3,{point:coords[1],sequenceNumber:1,constrain:p=>p,onMove:destination=>dispatch(actions.angle.movePoint(1,destination)),ariaLabel:srAngleVertex}),jsxRuntimeExports.jsx(MovablePoint$3,{point:coords[0],sequenceNumber:2,constrain:getAngleSideConstraint(coords[0],coords[1],snapDegrees||1),onMove:destination=>dispatch(actions.angle.movePoint(0,destination)),ariaLabel:srAngleEndingSide}),jsxRuntimeExports.jsx(MovablePoint$3,{point:coords[2],sequenceNumber:3,constrain:getAngleSideConstraint(coords[2],coords[1],snapDegrees||1),onMove:destination=>dispatch(actions.angle.movePoint(2,destination)),ariaLabel:srAngleStartingSide}),jsxRuntimeExports.jsx(SRDescInSVG,{id:descriptionId,children:srAngleGraphAriaDescription})]})}function getAngleGraphDescription(state,i18n){const{strings,locale}=i18n;const{coords}=state;return strings.srInteractiveElements({elements:strings.srAngleInteractiveElements({vertexX:srFormatNumber(coords[1][X],locale),vertexY:srFormatNumber(coords[1][Y],locale),startingSideX:srFormatNumber(coords[2][X],locale),startingSideY:srFormatNumber(coords[2][Y],locale),endingSideX:srFormatNumber(coords[0][X],locale),endingSideY:srFormatNumber(coords[0][Y],locale)})})}const positiveX=[1,0];const negativeX=[-1,0];const positiveY=[0,1];const negativeY=[0,-1];function getAngleSideConstraint(sidePoint,vertex,snapDegrees){const currentAngle=calculateAngleInDegrees$2(vec.sub(sidePoint,vertex));const leftRay=[sidePoint,vec.add(sidePoint,negativeX)];const rightRay=[sidePoint,vec.add(sidePoint,positiveX)];const upRay=[sidePoint,vec.add(sidePoint,positiveY)];const downRay=[sidePoint,vec.add(sidePoint,negativeY)];const oneStepCounterClockwise=currentAngle+snapDegrees;const oneStepClockwise=currentAngle-snapDegrees;const counterClockwiseRay=[vertex,vec.add(vertex,polar$1(1,oneStepCounterClockwise))];const clockwiseRay=[vertex,vec.add(vertex,polar$1(1,oneStepClockwise))];const left=findIntersectionOfRays(leftRay,counterClockwiseRay)??findIntersectionOfRays(leftRay,clockwiseRay);const right=findIntersectionOfRays(rightRay,counterClockwiseRay)??findIntersectionOfRays(rightRay,clockwiseRay);const up=findIntersectionOfRays(upRay,counterClockwiseRay)??findIntersectionOfRays(upRay,clockwiseRay);const down=findIntersectionOfRays(downRay,counterClockwiseRay)??findIntersectionOfRays(downRay,clockwiseRay);return {up:up??sidePoint,down:down??sidePoint,left:left??sidePoint,right:right??sidePoint}}
1936
-
1937
- function renderCircleGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(CircleGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeCircleGraph(state,i18n).srCircleInteractiveElement}}function CircleGraph(props){const{dispatch,graphState}=props;const{center,radiusPoint,snapStep}=graphState;const{strings,locale}=usePerseusI18n();const radius=getRadius(graphState);const id=React.useId();const circleId=id+"-circle";const radiusId=id+"-radius";const outerPointsId=id+"-outer-points";const{srCircleGraph,srCircleShape,srCircleRadiusPoint,srCircleRadius,srCircleOuterPoints}=describeCircleGraph(graphState,{strings,locale});return jsxRuntimeExports.jsxs("g",{"aria-label":srCircleGraph,"aria-describedby":`${circleId} ${radiusId} ${outerPointsId}`,children:[jsxRuntimeExports.jsx(MovableCircle,{id:circleId,ariaLabel:srCircleShape,ariaDescribedBy:`${radiusId} ${outerPointsId}`,center:center,radius:radius,onMove:c=>{dispatch(actions.circle.moveCenter(c));}}),jsxRuntimeExports.jsx(MovablePoint$3,{ariaLabel:`${srCircleRadiusPoint} ${srCircleRadius}`,ariaDescribedBy:`${outerPointsId}`,point:radiusPoint,sequenceNumber:1,cursor:"ew-resize",onMove:newRadiusPoint=>{dispatch(actions.circle.moveRadiusPoint(newRadiusPoint));},constrain:getCircleKeyboardConstraint(center,radiusPoint,snapStep)}),jsxRuntimeExports.jsx(SRDescInSVG,{id:radiusId,children:srCircleRadius}),jsxRuntimeExports.jsx(SRDescInSVG,{id:outerPointsId,children:srCircleOuterPoints})]})}function MovableCircle(props){const{id,ariaLabel,ariaDescribedBy,center,radius,onMove}=props;const{snapStep,disableKeyboardInteraction,interactiveColor}=useGraphConfig();const[focused,setFocused]=React.useState(false);const[hovered,setHovered]=React.useState(false);const focusableHandleRef=useRef(null);const visibleGroupRef=useRef(null);const circleHitboxRef=useRef(null);useDraggable({gestureTarget:focusableHandleRef,point:center,onMove,constrainKeyboardMovement:p=>snap(snapStep,p)});const{dragging}=useDraggable({gestureTarget:circleHitboxRef,point:center,onMove,constrainKeyboardMovement:p=>snap(snapStep,p)});const circleHitbox=useHitbox({shape:{kind:"ellipse",center,radius:[radius,radius]},hitboxRef:circleHitboxRef,layer:"body",dragging,onHoverChange:setHovered,testId:"movable-circle__hitbox"});React.useLayoutEffect(()=>{if(dragging&&!focused){focusableHandleRef.current?.focus();}},[dragging,focused]);const[centerPx]=useTransformVectorsToPixels(center);const[radiiPx]=useTransformDimensionsToPixels([radius,radius]);return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[circleHitbox,jsxRuntimeExports.jsx("g",{ref:focusableHandleRef,className:"movable-circle-focusable-handle",tabIndex:disableKeyboardInteraction?-1:0,role:"button","aria-label":ariaLabel,"aria-describedby":ariaDescribedBy,"aria-disabled":disableKeyboardInteraction,onFocus:()=>setFocused(true),onBlur:()=>setFocused(false)}),jsxRuntimeExports.jsxs("g",{"aria-hidden":true,ref:visibleGroupRef,className:`movable-circle${dragging?" movable-circle--dragging":""}${hovered?" movable-circle--hover":""}`,children:[jsxRuntimeExports.jsxs(ClipToGraphBounds,{children:[jsxRuntimeExports.jsx("ellipse",{className:"focus-ring",cx:centerPx[X],cy:centerPx[Y],rx:radiiPx[X]+3,ry:radiiPx[Y]+3}),jsxRuntimeExports.jsx("ellipse",{id:id,className:"circle",cx:centerPx[X],cy:centerPx[Y],rx:radiiPx[X],ry:radiiPx[Y],stroke:interactiveColor,"data-testid":"movable-circle__circle"})]}),jsxRuntimeExports.jsx(DragHandle,{center:center,dragging:dragging,focused:focused})]})]})}const dragHandleDimensions=[24,14];const dragHandleDotPositions=crossProduct([-4.4,0,4.4],[-2.1,2.1]);function DragHandle(props){const{center,dragging,focused}=props;const[centerPx]=useTransformVectorsToPixels(center);const{markings,interactiveColor}=useGraphConfig();const cornerRadius=Math.min(...dragHandleDimensions)/2;const topLeft=vec.sub(centerPx,vec.scale(dragHandleDimensions,.5));const showHairlines=(dragging||focused)&&markings!=="none";return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[showHairlines&&jsxRuntimeExports.jsx(Hairlines,{point:center}),jsxRuntimeExports.jsx("rect",{className:"movable-circle-handle",x:topLeft[X],y:topLeft[Y],width:dragHandleDimensions[X],height:dragHandleDimensions[Y],rx:cornerRadius,ry:cornerRadius,fill:interactiveColor,"data-testid":"movable-circle__handle"}),dragHandleDotPositions.map(offsetPx=>{const[xPx,yPx]=vec.add(offsetPx,centerPx);return jsxRuntimeExports.jsx("circle",{className:"movable-circle-handle-dot",cx:xPx,cy:yPx},`circle-${xPx}-${yPx}`)})]})}function crossProduct(as,bs){const result=[];for(const a of as){for(const b of bs){result.push([a,b]);}}return result}const getCircleKeyboardConstraint=(center,radiusPoint,snapStep)=>{const movePointWithConstraint=moveFunc=>{let movedCoord=moveFunc(radiusPoint);if(vec.dist(movedCoord,center)===0){movedCoord=moveFunc(movedCoord);}return movedCoord};return {up:movePointWithConstraint(coord=>vec.add(coord,[0,snapStep[1]])),down:movePointWithConstraint(coord=>vec.sub(coord,[0,snapStep[1]])),left:movePointWithConstraint(coord=>vec.sub(coord,[snapStep[0],0])),right:movePointWithConstraint(coord=>vec.add(coord,[snapStep[0],0]))}};
1938
-
1939
- function getMovablePointLabels(state){if(!state.showPointLabels){return []}const{pointLabels}=state;switch(state.type){case "point":case "polygon":case "sinusoid":case "linear":case "ray":case "absolute-value":case "exponential":case "logarithm":case "tangent":case "quadratic":return collect(state.coords,pointLabels);case "angle":return collect(state.coords,pointLabels);case "circle":{const text=pointLabels?.[0];if(text==null||text===""){return []}return [{key:"0",coord:state.radiusPoint,text}]}case "linear-system":case "segment":{const flatCoords=state.coords.flatMap(pair=>[pair[0],pair[1]]);return collect(flatCoords,pointLabels)}case "vector":case "none":return []}}function collect(coords,labels){const out=[];for(let i=0;i<coords.length;i++){const text=labels?.[i];if(text==null||text===""){continue}out.push({key:String(i),coord:coords[i],text});}return out}const ATTACH_BY_QUADRANT={n:{e:"ne",w:"nw"},s:{e:"se",w:"sw"}};const EDGE_FLIP_FRACTION=.15;function getLabelAttach(coord,range){const[xMin,xMax]=range[0];const[yMin,yMax]=range[1];const xMid=(xMin+xMax)/2;const yMid=(yMin+yMax)/2;const xSpan=xMax-xMin;const ySpan=yMax-yMin;let vertical=coord[1]>=yMid?"n":"s";let horizontal=coord[0]>=xMid?"e":"w";if(vertical==="n"&&(yMax-coord[1])/ySpan<EDGE_FLIP_FRACTION){vertical="s";}else if(vertical==="s"&&(coord[1]-yMin)/ySpan<EDGE_FLIP_FRACTION){vertical="n";}if(horizontal==="e"&&(xMax-coord[0])/xSpan<EDGE_FLIP_FRACTION){horizontal="w";}else if(horizontal==="w"&&(coord[0]-xMin)/xSpan<EDGE_FLIP_FRACTION){horizontal="e";}return ATTACH_BY_QUADRANT[vertical][horizontal]}
1940
-
1941
- function MovablePointLabelsLayer({state}){const labeledPoints=getMovablePointLabels(state);if(labeledPoints.length===0){return null}return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(LabelStrokeFilter,{}),labeledPoints.map(label=>jsxRuntimeExports.jsx(MovablePointLabelView,{label:label,range:state.range},label.key))]})}function MovablePointLabelView({label,range}){const graphConfig=useGraphConfig();const[x,y]=pointToPixel(label.coord,graphConfig);const attach=getLabelAttach(label.coord,range);return jsxRuntimeExports.jsx("span",{className:"movable-point-label","data-testid":"movable-point__visible-label","aria-hidden":true,style:{position:"absolute",left:x,top:y,transform:translateOutward(attach),color:semanticColor.core.foreground.neutral.default,fontFamily:'Symbola, "Times New Roman", serif',fontSize:font.heading.size.medium,fontWeight:font.weight.black,whiteSpace:"nowrap",pointerEvents:"none",filter:"url(#math-stroke)"},children:label.text})}const LABEL_PADDING_PX=12;function translateOutward(attach){const p=LABEL_PADDING_PX;switch(attach){case "n":return `translate(-50%, calc(-100% - ${p}px))`;case "ne":return `translate(${p}px, calc(-100% - ${p}px))`;case "e":return `translate(${p}px, -50%)`;case "se":return `translate(${p}px, ${p}px)`;case "s":return `translate(-50%, ${p}px)`;case "sw":return `translate(calc(-100% - ${p}px), ${p}px)`;case "w":return `translate(calc(-100% - ${p}px), -50%)`;case "nw":return `translate(calc(-100% - ${p}px), calc(-100% - ${p}px))`}}
1942
-
1943
- function DashedAsymptoteLine(props){const{start,end,color,className,testId}=props;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(SVGLine,{start:start,end:end,style:{stroke:semanticColor.core.background.base.default,strokeWidth:"var(--movable-asymptote-stroke-weight)",strokeLinecap:"round"},className:className}),jsxRuntimeExports.jsx(SVGLine,{start:start,end:end,style:{stroke:color,strokeWidth:"var(--movable-asymptote-stroke-weight)",strokeDasharray:"var(--movable-asymptote-dash-length) var(--movable-asymptote-dash-gap)",strokeLinecap:"round"},className:className,testId:testId})]})}
1944
-
1945
- const ACTIVE_MAJOR=22;const ACTIVE_MINOR=12;const INACTIVE_MAJOR=16;const INACTIVE_MINOR=6;const RING_PAD=2;const HALO_PAD=3;const FOCUS_RING_PAD=2;const GRIP_DOT_MAJOR_OFFSETS=[-3,0,3];const GRIP_DOT_MINOR_OFFSETS=[-2,2];function MovablePillHandle(props){const{center,active,focused,rotation=0}=props;const[cx,cy]=center;const{interactiveColor}=useGraphConfig();const majorSize=active?ACTIVE_MAJOR:INACTIVE_MAJOR;const minorSize=active?ACTIVE_MINOR:INACTIVE_MINOR;const pillW=majorSize;const pillH=minorSize;const pillRadius=pillH/2;const haloW=pillW+(RING_PAD+HALO_PAD)*2;const haloH=pillH+(RING_PAD+HALO_PAD)*2;const haloRadius=haloH/2;const ringW=pillW+RING_PAD*2;const ringH=pillH+RING_PAD*2;const ringRadius=ringH/2;const focusRingW=haloW+FOCUS_RING_PAD*2;const focusRingH=haloH+FOCUS_RING_PAD*2;const focusRingRadius=focusRingH/2;return jsxRuntimeExports.jsxs("g",{className:"movable-pill-handle-group","aria-hidden":true,style:{pointerEvents:"none"},transform:`translate(${cx} ${cy}) rotate(${rotation})`,"data-testid":"movable-pill-handle",children:[focused&&jsxRuntimeExports.jsx("rect",{className:"movable-pill-handle-focus-ring","data-testid":"movable-pill-handle-focus-ring",x:-focusRingW/2,y:-focusRingH/2,width:focusRingW,height:focusRingH,rx:focusRingRadius,ry:focusRingRadius,stroke:interactiveColor}),jsxRuntimeExports.jsx("rect",{className:"movable-pill-handle-halo",x:-haloW/2,y:-haloH/2,width:haloW,height:haloH,rx:haloRadius,ry:haloRadius,fill:interactiveColor}),jsxRuntimeExports.jsx("rect",{className:"movable-pill-handle-ring",x:-ringW/2,y:-ringH/2,width:ringW,height:ringH,rx:ringRadius,ry:ringRadius}),jsxRuntimeExports.jsx("rect",{className:"movable-pill-handle","data-testid":"movable-pill-handle-pill",x:-pillW/2,y:-pillH/2,width:pillW,height:pillH,rx:pillRadius,ry:pillRadius,fill:interactiveColor}),active&&GRIP_DOT_MINOR_OFFSETS.map(dy=>GRIP_DOT_MAJOR_OFFSETS.map(dx=>jsxRuntimeExports.jsx("circle",{className:"movable-pill-handle-dot","data-testid":"movable-pill-handle-dot",cx:dx,cy:dy},`${dx},${dy}`)))]})}
1946
-
1947
- function MovableAsymptote(props){const{start,end,mid,point,onMove,constrainKeyboardMovement,orientation,ariaLabel,children}=props;const{interactiveColor,disableKeyboardInteraction}=useGraphConfig();const[focused,setFocused]=React.useState(false);const[hovered,setHovered]=React.useState(false);const groupRef=React.useRef(null);const asymptoteHitboxRef=React.useRef(null);useDraggable({gestureTarget:groupRef,point,onMove,constrainKeyboardMovement:constrainKeyboardMovement??(p=>p)});const{dragging}=useDraggable({gestureTarget:asymptoteHitboxRef,point,onMove,constrainKeyboardMovement:constrainKeyboardMovement??(p=>p)});const asymptoteHitbox=useHitbox({shape:{kind:"box",center:point,sizePx:HANDLE_HITBOX_SIZE_PX},hitboxRef:asymptoteHitboxRef,layer:"handle",dragging,onHoverChange:setHovered,testId:"movable-asymptote__hitbox"});React.useLayoutEffect(()=>{if(dragging&&!focused){groupRef.current?.focus({preventScroll:true});}},[dragging,focused]);return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[asymptoteHitbox,jsxRuntimeExports.jsxs("g",{ref:groupRef,tabIndex:disableKeyboardInteraction?-1:0,"aria-disabled":disableKeyboardInteraction,"aria-label":ariaLabel,className:hovered?"movable-line movable-line--hover":"movable-line",style:{cursor:dragging?"grabbing":"grab"},role:"button","data-testid":"movable-asymptote",onFocus:()=>setFocused(true),onBlur:()=>setFocused(false),onMouseEnter:()=>setHovered(true),onMouseLeave:()=>setHovered(false),children:[jsxRuntimeExports.jsx(SVGLine,{start:start,end:end,style:{stroke:"transparent",strokeWidth:TARGET_SIZE}}),jsxRuntimeExports.jsx(DashedAsymptoteLine,{start:start,end:end,color:interactiveColor,className:dragging?"movable-dragging":"",testId:"movable-asymptote__line"}),children,jsxRuntimeExports.jsx(MovablePillHandle,{center:mid,rotation:orientation==="vertical"?90:0,active:dragging||focused||hovered,focused:focused})]})]})}
1948
-
1949
- const{getExponentialCoefficients: getExponentialCoefficients$1}=coefficients;function renderExponentialGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(ExponentialGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeExponentialGraph(state,i18n).srExponentialInteractiveElements}}function ExponentialGraph(props){const{dispatch,graphState}=props;const{interactiveColor,range}=useGraphConfig();const i18n=usePerseusI18n();const id=React.useId();const descriptionId=id+"-description";const{coords,asymptote,snapStep}=graphState;const coeffs=getExponentialCoefficients$1(coords,asymptote);const asymptoteY=asymptote;const yMin=range[1][0];const yMax=range[1][1];const yPadding=(yMax-yMin)*4;const{srExponentialGraph,srExponentialDescription,srExponentialPoint1,srExponentialPoint2,srExponentialAsymptote}=describeExponentialGraph(graphState,i18n);const asymptoteLeft=[range[0][0],asymptoteY];const asymptoteRight=[range[0][1],asymptoteY];const handleCoord=getAsymptoteHandleCoord("horizontal",range,asymptote);const[leftPx,rightPx,midPx]=useTransformVectorsToPixels(asymptoteLeft,asymptoteRight,handleCoord);return jsxRuntimeExports.jsxs("g",{"aria-label":srExponentialGraph,"aria-describedby":descriptionId,children:[jsxRuntimeExports.jsx(MovableAsymptote,{start:leftPx,end:rightPx,mid:midPx,point:handleCoord,onMove:newPoint=>dispatch(actions.exponential.moveCenter(newPoint)),constrainKeyboardMovement:p=>skipAsymptoteKeyboardOverPoint(p,asymptote,coords,handleCoord,snapStep,"horizontal"),orientation:"horizontal",ariaLabel:srExponentialAsymptote,children:coeffs!==undefined&&jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(Plot$2.OfX,{y:x=>{const y=computeExponential(x,coeffs);if(y<yMin-yPadding||y>yMax+yPadding){return NaN}return y},color:interactiveColor,svgPathProps:{"aria-hidden":true,style:{pointerEvents:"none"}}})})}),coords.map((coord,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{ariaLabel:i===0?srExponentialPoint1:srExponentialPoint2,point:coord,sequenceNumber:i+1,constrain:getExponentialKeyboardConstraint(coords,asymptote,snapStep,i,range),onMove:destination=>dispatch(actions.exponential.movePoint(i,destination))},"point-"+i)),jsxRuntimeExports.jsx(SRDescInSVG,{id:descriptionId,children:srExponentialDescription})]})}const getExponentialKeyboardConstraint=(coords,asymptote,snapStep,pointIndex,range)=>{const otherPoint=coords[1-pointIndex];const handleCoord=getAsymptoteHandleCoord("horizontal",range,asymptote);return getAsymptoteGraphKeyboardConstraint(coords,snapStep,pointIndex,coord=>{const clamped=boundToEdgeAndSnapToGrid(coord,{snapStep,range});const clampedX=clamped[X];const clampedY=clamped[Y];if(coord[X]===otherPoint[X]||clampedX===otherPoint[X]){return false}if(clampedX===handleCoord[X]&&clampedY===handleCoord[Y]){return false}return true})};const computeExponential=function(x,coefficients){const{a,b,c}=coefficients;return a*Math.exp(b*x)+c};
1950
-
1951
- function describeLinearGraph(state,i18n){const{coords:line}=state;const{strings,locale}=i18n;const srLinearGraph=strings.srLinearGraph;const srLinearGraphPoints=strings.srLinearGraphPoints({point1X:srFormatNumber(line[0][0],locale),point1Y:srFormatNumber(line[0][1],locale),point2X:srFormatNumber(line[1][0],locale),point2Y:srFormatNumber(line[1][1],locale)});const srLinearGrabHandle=strings.srLinearGrabHandle({point1X:srFormatNumber(line[0][0],locale),point1Y:srFormatNumber(line[0][1],locale),point2X:srFormatNumber(line[1][0],locale),point2Y:srFormatNumber(line[1][1],locale)});const slopeString=getSlopeStringForLine(line,strings);const interceptString=getInterceptStringForLine(line,strings,locale);const srLinearInteractiveElement=strings.srInteractiveElements({elements:[srLinearGraph,srLinearGraphPoints].join(" ")});return {srLinearGraph,srLinearGraphPoints,srLinearGrabHandle,slopeString,interceptString,srLinearInteractiveElement}}
1952
-
1953
- function renderLinearGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(LinearGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeLinearGraph(state,i18n).srLinearInteractiveElement}}const LinearGraph=(props,key)=>{const{dispatch}=props;const{coords:line,pointLabels}=props.graphState;const{strings,locale}=usePerseusI18n();const buildLabel=usePointAriaLabel(pointLabels);const id=React.useId();const pointsDescriptionId=id+"-points";const interceptDescriptionId=id+"-intercept";const slopeDescriptionId=id+"-slope";const{srLinearGraph,srLinearGraphPoints,srLinearGrabHandle,slopeString,interceptString}=describeLinearGraph(props.graphState,{strings,locale});return jsxRuntimeExports.jsxs("g",{"aria-label":srLinearGraph,"aria-describedby":`${pointsDescriptionId} ${interceptDescriptionId} ${slopeDescriptionId}`,children:[jsxRuntimeExports.jsx(MovableLine$2,{ariaLabels:{grabHandleAriaLabel:srLinearGrabHandle,point1AriaLabel:buildLabel(0,line[0]),point2AriaLabel:buildLabel(1,line[1])},ariaDescribedBy:`${interceptDescriptionId} ${slopeDescriptionId}`,points:line,onMoveLine:newStart=>{dispatch(actions.linear.moveLine(newStart));},extend:{start:true,end:true},onMovePoint:(endpointIndex,destination)=>dispatch(actions.linear.movePoint(endpointIndex,destination))},0),jsxRuntimeExports.jsx(SRDescInSVG,{id:pointsDescriptionId,children:srLinearGraphPoints}),jsxRuntimeExports.jsx(SRDescInSVG,{id:interceptDescriptionId,children:interceptString}),jsxRuntimeExports.jsx(SRDescInSVG,{id:slopeDescriptionId,children:slopeString})]})};
1954
-
1955
- function renderLinearSystemGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(LinearSystemGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeLinearSystemGraph(state,i18n).srLinearSystemInteractiveElements}}const LinearSystemGraph=props=>{const{dispatch}=props;const{coords:lines}=props.graphState;const i18n=usePerseusI18n();const id=React.useId();const intersectionId=`${id}-intersection`;const{srLinearSystemGraph,srIntersectionDescription,srLines}=describeLinearSystemGraph(props.graphState,i18n);const lineIds=lines.map((_,i)=>({pointsDescriptionId:`${id}-line${i+1}-points`,interceptDescriptionId:`${id}-line${i+1}-intercept`,slopeDescriptionId:`${id}-line${i+1}-slope`}));const individualLineDescriptions=lineIds.map(({pointsDescriptionId,interceptDescriptionId,slopeDescriptionId})=>`${pointsDescriptionId} ${interceptDescriptionId} ${slopeDescriptionId}`).join(" ");return jsxRuntimeExports.jsxs("g",{"aria-label":srLinearSystemGraph,"aria-describedby":`${individualLineDescriptions} ${intersectionId}`,children:[lines?.map((line,i)=>jsxRuntimeExports.jsx(MovableLine$2,{points:line,ariaLabels:{point1AriaLabel:srLines[i].point1AriaLabel,point2AriaLabel:srLines[i].point2AriaLabel,grabHandleAriaLabel:srLines[i].grabHandleAriaLabel},ariaDescribedBy:`${lineIds[i].interceptDescriptionId} ${lineIds[i].slopeDescriptionId} ${intersectionId}`,onMoveLine:newStart=>{dispatch(actions.linearSystem.moveLine(i,newStart));},extend:{start:true,end:true},onMovePoint:(endpointIndex,destination)=>dispatch(actions.linearSystem.movePointInFigure(i,endpointIndex,destination))},i)),lineIds.map(({pointsDescriptionId,interceptDescriptionId,slopeDescriptionId},i)=>jsxRuntimeExports.jsxs("span",{children:[jsxRuntimeExports.jsx(SRDescInSVG,{id:pointsDescriptionId,children:srLines[i].pointsDescription}),jsxRuntimeExports.jsx(SRDescInSVG,{id:interceptDescriptionId,children:srLines[i].interceptDescription}),jsxRuntimeExports.jsx(SRDescInSVG,{id:slopeDescriptionId,children:srLines[i].slopeDescription})]},`line-descriptions-${i}`)),jsxRuntimeExports.jsx(SRDescInSVG,{id:intersectionId,children:srIntersectionDescription})]})};
1956
-
1957
- const{getLogarithmCoefficients: getLogarithmCoefficients$1}=coefficients;function renderLogarithmGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(LogarithmGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeLogarithmGraph(state,i18n).srLogarithmInteractiveElements}}function LogarithmGraph(props){const{dispatch,graphState}=props;const{interactiveColor,range}=useGraphConfig();const i18n=usePerseusI18n();const id=React.useId();const descriptionId=id+"-description";const{coords,asymptote,snapStep}=graphState;const coeffs=getLogarithmCoefficients$1(coords,asymptote);const asymptoteX=asymptote;const xMin=range[0][0];const xMax=range[0][1];const yMin=range[1][0];const yMax=range[1][1];const{srLogarithmGraph,srLogarithmDescription,srLogarithmPoint1,srLogarithmPoint2,srLogarithmAsymptote}=describeLogarithmGraph(graphState,i18n);const asymptoteBottom=[asymptoteX,yMin];const asymptoteTop=[asymptoteX,yMax];const handleCoord=getAsymptoteHandleCoord("vertical",range,asymptote);const[bottomPx,topPx,midPx]=useTransformVectorsToPixels(asymptoteBottom,asymptoteTop,handleCoord);return jsxRuntimeExports.jsxs("g",{"aria-label":srLogarithmGraph,"aria-describedby":descriptionId,children:[jsxRuntimeExports.jsx(MovableAsymptote,{start:bottomPx,end:topPx,mid:midPx,point:handleCoord,onMove:newPoint=>dispatch(actions.logarithm.moveCenter(newPoint)),constrainKeyboardMovement:p=>skipAsymptoteKeyboardOverPoint(p,asymptote,coords,handleCoord,snapStep,"vertical"),orientation:"vertical",ariaLabel:srLogarithmAsymptote,children:coeffs!==undefined&&renderLogarithmCurve({coeffs,coords,asymptoteX,xMin,xMax,yMin,yMax,interactiveColor})}),coords.map((coord,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{ariaLabel:i===0?srLogarithmPoint1:srLogarithmPoint2,point:coord,sequenceNumber:i+1,constrain:getLogarithmKeyboardConstraint(coords,asymptote,snapStep,i,range),onMove:destination=>dispatch(actions.logarithm.movePoint(i,destination))},"point-"+i)),jsxRuntimeExports.jsx(SRDescInSVG,{id:descriptionId,children:srLogarithmDescription})]})}const getLogarithmKeyboardConstraint=(coords,asymptote,snapStep,pointIndex,range)=>{const otherPoint=coords[1-pointIndex];const handleCoord=getAsymptoteHandleCoord("vertical",range,asymptote);return getAsymptoteGraphKeyboardConstraint(coords,snapStep,pointIndex,coord=>{const clamped=boundToEdgeAndSnapToGrid(coord,{snapStep,range});const clampedX=clamped[X];const clampedY=clamped[Y];if(coord[X]===otherPoint[X]||clampedX===otherPoint[X]){return false}if(coord[Y]===otherPoint[Y]||clampedY===otherPoint[Y]){return false}if(clampedX===handleCoord[X]&&clampedY===handleCoord[Y]){return false}return true})};const computeLogarithm=function(coefficients,x){const{a,b,c}=coefficients;const arg=b*x+c;if(arg<=0){return NaN}return a*Math.log(arg)};function renderLogarithmCurve({coeffs,coords,asymptoteX,xMin,xMax,yMin,yMax,interactiveColor}){const offScreenMargin=2;const{a,b,c}=coeffs;const targetY=a>0?yMin-offScreenMargin:yMax+offScreenMargin;const computedX=(Math.exp(targetY/a)-c)/b;const computedOffset=Math.abs(computedX-asymptoteX);const domainOffset=isFinite(computedOffset)&&computedOffset>0?computedOffset:1e-8;const pointsRightOfAsymptote=coords[0][X]>asymptoteX;return jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(Plot$2.OfX,{y:x=>computeLogarithm(coeffs,x),color:interactiveColor,svgPathProps:{"aria-hidden":true,style:{pointerEvents:"none"}},domain:pointsRightOfAsymptote?[asymptoteX+domainOffset,xMax]:[xMin,asymptoteX-domainOffset]})})}
1958
-
1959
- function describePointGraph(state,i18n){const{strings,locale}=i18n;if(state.coords.length===0){return strings.srNoInteractiveElements}const pointDescriptions=state.coords.map((point,index)=>buildPointAriaLabel(state.pointLabels,index,point,strings,locale)??strings.srPointAtCoordinates({pointLabel:`${index+1}`,x:srFormatNumber(point[0],locale),y:srFormatNumber(point[1],locale)}));return strings.srInteractiveElements({elements:pointDescriptions.join(" ")})}
1960
-
1961
- function renderPointGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(PointGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describePointGraph(state,i18n)}}function PointGraph(props){const{numPoints}=props.graphState;const graphConfig=useGraphConfig();const pointsRef=React.useRef([]);const{range:[x,y]}=graphConfig;const[[left,top]]=useTransformVectorsToPixels([x[0],y[1]]);React.useEffect(()=>{const focusedIndex=props.graphState.focusedPointIndex;if(focusedIndex!=null){pointsRef.current[focusedIndex]?.focus();}},[props.graphState.focusedPointIndex,props.graphState.coords.length,pointsRef]);const statefulProps={...props,graphConfig,pointsRef,top,left};if(numPoints==="unlimited"){return jsxRuntimeExports.jsx(UnlimitedPointGraph,{...statefulProps})}return jsxRuntimeExports.jsx(LimitedPointGraph,{...statefulProps})}function LimitedPointGraph(statefulProps){const{dispatch}=statefulProps;const{coords,pointLabels}=statefulProps.graphState;const buildLabel=usePointAriaLabel(pointLabels);return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:coords.map((point,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{point:point,sequenceNumber:i+1,ariaLabel:buildLabel(i,point),onMove:destination=>dispatch(actions.pointGraph.movePoint(i,destination))},i))})}function UnlimitedPointGraph(statefulProps){const{dispatch,graphConfig,pointsRef,top,left}=statefulProps;const{coords,pointLabels}=statefulProps.graphState;const buildLabel=usePointAriaLabel(pointLabels);const[isCurrentlyDragging,setIsCurrentlyDragging]=React.useState(false);const dragEndCallbackTimer=useTimeout(()=>setIsCurrentlyDragging(false),400);const{graphDimensionsInPixels}=graphConfig;const widthPx=graphDimensionsInPixels[0];const heightPx=graphDimensionsInPixels[1];return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("rect",{"data-testid":"unlimited-point-graph-add-target",style:{fill:"none",pointerEvents:"all",cursor:"crosshair"},width:widthPx,height:heightPx,x:left,y:top,onClick:event=>{if(isCurrentlyDragging){return}const elementRect=event.currentTarget.getBoundingClientRect();const zoomFactor=getCSSZoomFactor(event.currentTarget);const x=(event.clientX-elementRect.x)/zoomFactor;const y=(event.clientY-elementRect.y)/zoomFactor;const graphCoordinates=pixelsToVectors([[x,y]],graphConfig);dispatch(actions.pointGraph.addPoint(graphCoordinates[0]));}}),coords.map((point,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{point:point,sequenceNumber:i+1,ariaLabel:buildLabel(i,point),onDragStart:()=>{dragEndCallbackTimer.clear();setIsCurrentlyDragging(true);},onMove:destination=>{dispatch(actions.pointGraph.movePoint(i,destination));},onDragEnd:()=>{dragEndCallbackTimer.set();},ref:ref=>{pointsRef.current[i]=ref;},onFocus:()=>{dispatch(actions.pointGraph.focusPoint(i));},onClick:()=>{dispatch(actions.pointGraph.clickPoint(i));}},i))]})}
1962
-
1963
- const{magnitude: magnitude$1,vector: vector$1}=geometry;function initializeGraphState(params){const{graph,step,snapStep,range}=params;const shared={hasBeenInteractedWith:false,range,snapStep,pointLabels:"pointLabels"in graph?graph.pointLabels:undefined,showPointLabels:"showPointLabels"in graph?Boolean(graph.showPointLabels):undefined};switch(graph.type){case "segment":return {...shared,type:"segment",coords:getSegmentCoords(graph,range,step)};case "linear":return {...shared,type:graph.type,coords:getLineCoords(graph,range,step)};case "ray":return {...shared,type:graph.type,coords:getLineCoords(graph,range,step)};case "linear-system":return {...shared,type:graph.type,coords:getLinearSystemCoords(graph,range,step)};case "polygon":return {...shared,type:"polygon",numSides:graph.numSides||0,showAngles:Boolean(graph.showAngles),showSides:Boolean(graph.showSides),coords:getPolygonCoords(graph,range,step),snapTo:graph.snapTo??"grid",focusedPointIndex:null,showRemovePointButton:false,interactionMode:"mouse",showKeyboardInteractionInvitation:false,closedPolygon:false};case "point":return {...shared,type:graph.type,coords:getPointCoords(graph,range,step),numPoints:graph.numPoints||0,focusedPointIndex:null,showRemovePointButton:false,interactionMode:"mouse",showKeyboardInteractionInvitation:false};case "circle":return {...shared,type:graph.type,...getCircleCoords(graph)};case "quadratic":return {...shared,type:graph.type,coords:getQuadraticCoords(graph,range,step)};case "sinusoid":return {...shared,type:graph.type,coords:getSinusoidCoords(graph,range,step)};case "exponential":return {...shared,type:graph.type,...getExponentialCoords(graph,range,step)};case "angle":return {...shared,type:graph.type,showAngles:Boolean(graph.showAngles),coords:getAngleCoords({graph,range,step}),angleOffsetDeg:graph.angleOffsetDeg??0,allowReflexAngles:Boolean(graph.allowReflexAngles),snapDegrees:Number(graph.snapDegrees)};case "none":return {...shared,type:"none"};case "absolute-value":return {...shared,type:graph.type,coords:getAbsoluteValueCoords(graph,range,step)};case "tangent":return {...shared,type:graph.type,coords:getTangentCoords(graph,range,step)};case "logarithm":return {...shared,type:graph.type,...getLogarithmCoords(graph,range,step)};case "vector":return {...shared,type:graph.type,coords:getVectorCoords(graph,range,step)};default:throw new UnreachableCaseError(graph)}}function getPointCoords(graph,range,step){const numPoints=graph.numPoints||1;let coords=graph.coords?.slice();if(coords){return coords}const startCoords=graph.startCoords?.slice();if(startCoords){return startCoords}switch(numPoints){case 1:coords=[graph.coord||[0,0]];break;case 2:coords=[[-5,0],[5,0]];break;case 3:coords=[[-5,0],[0,0],[5,0]];break;case 4:coords=[[-6,0],[-2,0],[2,0],[6,0]];break;case 5:coords=[[-6,0],[-3,0],[0,0],[3,0],[6,0]];break;case 6:coords=[[-5,0],[-3,0],[-1,0],[1,0],[3,0],[5,0]];break;default:coords=[];break}const newCoords=normalizeCoords(coords,[[-10,10],[-10,10]]);return normalizePoints(range,step,newCoords)}function getSegmentCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}const ys=n=>{switch(n){case 2:return [5,-5];case 3:return [5,0,-5];case 4:return [6,2,-2,-6];case 5:return [6,3,0,-3,-6];case 6:return [5,3,1,-1,-3,-5];default:return [5]}};const defaultRange=[[-10,10],[-10,10]];return ys(graph.numSegments).map(y=>{let endpoints=[[-5,y],[5,y]];endpoints=normalizeCoords(endpoints,defaultRange);endpoints=normalizePoints(range,step,endpoints);return endpoints})}const defaultLinearCoords=[[[.25,.75],[.75,.75]],[[.25,.25],[.75,.25]]];function getLineCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}return normalizePoints(range,step,defaultLinearCoords[0])}function getVectorCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}return normalizePoints(range,step,[[.6,.6],[.85,.85]])}function getLinearSystemCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}return defaultLinearCoords.map(points=>normalizePoints(range,step,points))}function getPolygonCoords(graph,range,step){let coords=graph.coords?.slice();if(coords){return coords}const startCoords=graph.startCoords?.slice();if(startCoords){return startCoords}const n=graph.numSides||3;if(n==="unlimited"){coords=[];}else {const angle=2*Math.PI/n;const offset=(1/n-1/2)*Math.PI;const radius=graph.snapTo==="sides"?Math.sqrt(3)/3*7:4;coords=[...Array(n).keys()].map(i=>[radius*Math.cos(i*angle+offset),radius*Math.sin(i*angle+offset)]);}coords=normalizeCoords(coords,[[-10,10],[-10,10]]);const snapToGrid=!["angles","sides"].includes(graph.snapTo||"");coords=normalizePoints(range,step,coords,!snapToGrid);return coords}function getSinusoidCoords(graph,range,step){if(graph.coords){return [graph.coords[0],graph.coords[1]]}if(graph.startCoords){return [graph.startCoords[0],graph.startCoords[1]]}let coords=[[.5,.5],[.65,.6]];coords=normalizePoints(range,step,coords,true);return coords}function getAbsoluteValueCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}const defaultCoords=[[.5,.5],[.75,.75]];return normalizePoints(range,step,defaultCoords,true)}function getTangentCoords(graph,range,step){if(graph.coords){return [graph.coords[0],graph.coords[1]]}if(graph.startCoords){return [graph.startCoords[0],graph.startCoords[1]]}let coords=[[.5,.5],[.75,.75]];coords=normalizePoints(range,step,coords,true);return coords}function getQuadraticCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}const defaultCoords=[[.25,.75],[.5,.25],[.75,.75]];return normalizePoints(range,step,defaultCoords,true)}function getCircleCoords(graph){if(graph.center!=null&&graph.radius!=null){return {center:graph.center,radiusPoint:vec.add(graph.center,[graph.radius,0])}}if(graph.startCoords?.center&&graph.startCoords.radius){return {center:graph.startCoords.center,radiusPoint:vec.add(graph.startCoords.center,[graph.startCoords.radius,0])}}return {center:[0,0],radiusPoint:[2,0]}}function getExponentialCoords(graph,range,step){if(graph.coords&&graph.asymptote!=null){return {coords:[graph.coords[0],graph.coords[1]],asymptote:graph.asymptote}}let defaultCoords=[[.5,.6],[.75,.75]];defaultCoords=normalizePoints(range,step,defaultCoords,true);const coords=graph.startCoords?graph.startCoords.coords:defaultCoords;const asymptote=graph.startCoords?graph.startCoords.asymptote:0;return {coords,asymptote}}function getLogarithmCoords(graph,range,step){if(graph.coords&&graph.asymptote!=null){return {coords:[graph.coords[0],graph.coords[1]],asymptote:graph.asymptote}}let defaultCoords=[[.6,.55],[.75,.75]];defaultCoords=normalizePoints(range,step,defaultCoords,true);const coords=graph.startCoords?graph.startCoords.coords:defaultCoords;const asymptote=graph.startCoords?graph.startCoords.asymptote:0;return {coords,asymptote}}const getAngleCoords=params=>{const{graph,range,step}=params;if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}const{snapDegrees,angleOffsetDeg}=graph;const snap=snapDegrees||1;let angle=snap;while(angle<20){angle+=snap;}angle=angle*Math.PI/180;const offset=(angleOffsetDeg||0)*Math.PI/180;let defaultCoords=[[.85,.5],[.5,.5]];defaultCoords=normalizePoints(range,step,defaultCoords,true);const radius=magnitude$1(vector$1(...defaultCoords));const coords=[...defaultCoords,[0,0]];coords[0]=[coords[1][0]+radius*Math.cos(offset),coords[1][1]+radius*Math.sin(offset)];coords[2]=[coords[1][0]+radius*Math.cos(angle+offset),coords[1][1]+radius*Math.sin(angle+offset)];return coords};
1964
-
1965
- const{getAngleFromVertex,getClockwiseAngle,polar}=angles;const{angleMeasures,ccw,lawOfCosines,magnitude,polygonSidesIntersect,reverseVector,sign,vector}=geometry;const{getAbsoluteValueCoefficients,getLogarithmCoefficients,getExponentialCoefficients,getQuadraticCoefficients}=coefficients;const minDistanceBetweenAngleVertexAndSidePoint=2;function interactiveGraphReducer(state,action){switch(action.type){case REINITIALIZE:return initializeGraphState(action.params);case MOVE_POINT_IN_FIGURE:return doMovePointInFigure(state,action);case MOVE_LINE:return doMoveLine(state,action);case MOVE_ALL:return doMoveAll(state,action);case MOVE_POINT:return doMovePoint(state,action);case MOVE_CENTER:return doMoveCenter(state,action);case MOVE_RADIUS_POINT:return doMoveRadiusPoint(state,action);case CHANGE_SNAP_STEP:return doChangeSnapStep(state,action);case CHANGE_RANGE:return doChangeRange(state,action);case ADD_POINT:return doAddPoint(state,action);case REMOVE_POINT:return doRemovePoint(state,action);case FOCUS_POINT:return doFocusPoint(state,action);case BLUR_POINT:return doBlurPoint(state);case DELETE_INTENT:return doDeleteIntent(state);case CLICK_POINT:return doClickPoint(state,action);case CLOSE_POLYGON:return doClosePolygon(state);case OPEN_POLYGON:return doOpenPolygon(state);case CHANGE_INTERACTION_MODE:return doChangeInteractionMode(state,action);case CHANGE_KEYBOARD_INVITATION_VISIBILITY:return doChangeKeyboardInvitationVisibility(state,action);default:throw new UnreachableCaseError(action)}}function doDeleteIntent(state,action){if(isUnlimitedGraphState(state)){if(state.focusedPointIndex!==null){return doRemovePoint(state,actions.pointGraph.removePoint(state.focusedPointIndex))}}return state}function doFocusPoint(state,action){switch(state.type){case "polygon":case "point":return {...state,focusedPointIndex:action.index};default:return state}}function doBlurPoint(state,action){switch(state.type){case "polygon":case "point":const nextState={...state,showRemovePointButton:false};if(state.interactionMode==="mouse"){nextState.focusedPointIndex=null;}return nextState;default:return state}}function doClickPoint(state,action){if(isUnlimitedGraphState(state)){return {...state,focusedPointIndex:action.index,showRemovePointButton:true}}return state}function doClosePolygon(state){if(isUnlimitedGraphState(state)&&state.type==="polygon"){const noDupedPoints=getArrayWithoutDuplicates(state.coords);return {...state,coords:noDupedPoints,closedPolygon:true}}return state}function doOpenPolygon(state){if(isUnlimitedGraphState(state)&&state.type==="polygon"){return {...state,closedPolygon:false}}return state}function doChangeInteractionMode(state,action){if(isUnlimitedGraphState(state)){const nextKeyboardInvitation=action.mode==="keyboard"?false:state.showKeyboardInteractionInvitation;return {...state,interactionMode:action.mode,showKeyboardInteractionInvitation:nextKeyboardInvitation}}return state}function doChangeKeyboardInvitationVisibility(state,action){if(isUnlimitedGraphState(state)){return {...state,showKeyboardInteractionInvitation:action.shouldShow,hasBeenInteractedWith:true}}return state}function doMovePointInFigure(state,action){switch(state.type){case "segment":case "linear-system":{const newValue=boundToEdgeAndSnapToGrid(action.destination,state);const newCoords=updateAtIndex({array:state.coords,index:action.figureIndex,update:tuple=>setAtIndex({array:tuple,index:action.pointIndex,newValue})});const coordsToCheck=newCoords[action.figureIndex];if(coordsOverlap(coordsToCheck)){return state}const sharedAnnouncement={pointIndex:action.pointIndex,pointLabel:getCustomPointLabel(state.pointLabels,action.figureIndex*2+action.pointIndex),x:newValue[X],y:newValue[Y]};const stateAnnouncement=state.type==="segment"?{type:"move-segment-point",segmentIndex:action.figureIndex,totalSegments:state.coords.length,...sharedAnnouncement}:{type:"move-linear-system-point",lineIndex:action.figureIndex,...sharedAnnouncement};return {...state,hasBeenInteractedWith:true,coords:newCoords,stateAnnouncement}}case "ray":case "linear":case "vector":{const newValue=boundToEdgeAndSnapToGrid(action.destination,state);const newCoords=setAtIndex({array:state.coords,index:action.pointIndex,newValue});if(coordsOverlap(newCoords)){return state}let stateAnnouncement;if(state.type==="ray"){stateAnnouncement={type:"move-ray-point",pointIndex:action.pointIndex,pointLabel:getCustomPointLabel(state.pointLabels,action.pointIndex),x:newValue[X],y:newValue[Y]};}else if(state.type==="vector"){stateAnnouncement={type:"move-vector-point",pointIndex:action.pointIndex,x:newValue[X],y:newValue[Y]};}else {stateAnnouncement={type:"move-point",pointLabel:resolvePointLabel(state.pointLabels,action.pointIndex),x:newValue[X],y:newValue[Y]};}return {...state,hasBeenInteractedWith:true,coords:newCoords,stateAnnouncement}}case "circle":throw new Error(`Don't use movePointInFigure for circle graphs. Use moveCenter or moveRadiusPoint.`);case "angle":case "none":case "point":case "polygon":case "quadratic":case "sinusoid":case "absolute-value":case "tangent":case "exponential":case "logarithm":throw new Error(`Don't use movePointInFigure for ${state.type} graphs. Use movePoint instead!`);default:throw new UnreachableCaseError(state)}}function doMoveLine(state,action){const{snapStep,range}=state;const{newStart}=action;switch(state.type){case "segment":case "linear-system":{if(action.itemIndex===undefined){throw new Error("Please provide index of line to move")}const currentLine=state.coords[action.itemIndex];const constrainedLine=constrainShapePreservingMove(currentLine,newStart,{snapStep,range});const newCoords=setAtIndex({array:state.coords,index:action.itemIndex,newValue:constrainedLine});const stateAnnouncement=state.type==="segment"?{type:"move-segment-line",coords:constrainedLine}:{type:"move-linear-system-line",lineIndex:action.itemIndex,coords:constrainedLine};return {...state,type:state.type,hasBeenInteractedWith:true,coords:newCoords,stateAnnouncement}}case "ray":case "linear":case "vector":{const constrainedLine=constrainShapePreservingMove(state.coords,newStart,{snapStep,range});let type;if(state.type==="ray"){type="move-ray-line";}else if(state.type==="vector"){type="move-vector-line";}else {type="move-linear-line";}const stateAnnouncement={type,coords:constrainedLine};return {...state,type:state.type,hasBeenInteractedWith:true,coords:constrainedLine,stateAnnouncement}}default:return state}}function doMoveAll(state,action){const{snapStep,range}=state;const{newStart}=action;switch(state.type){case "polygon":{const useGridSnap=state.snapTo!=="sides"&&state.snapTo!=="angles";const desiredDelta=vec.sub(newStart,state.coords[0]);const change=getChange(state.coords,desiredDelta,{snapStep:useGridSnap?snapStep:[0,0],range});const newCoords=state.coords.map(point=>useGridSnap?snap(snapStep,vec.add(point,change)):vec.add(point,change));return {...state,hasBeenInteractedWith:true,coords:newCoords,stateAnnouncement:{type:"move-polygon",coords:newCoords,pointLabels:state.pointLabels}}}default:return state}}function doMovePoint(state,action){switch(state.type){case "angle":const newState=(()=>{if(action.index===1){const updatedCoords=boundAndSnapAngleVertex(state,action);return {...state,hasBeenInteractedWith:true,coords:updatedCoords}}return {...state,hasBeenInteractedWith:true,coords:setAtIndex({array:state.coords,index:action.index,newValue:boundAndSnapAngleEndPoints(action.destination,state,action.index)})}})();if(angleSidePointsTooCloseToVertex(newState)){return state}return {...newState,stateAnnouncement:{type:"move-angle-point",pointIndex:action.index,pointLabel:getCustomPointLabel(state.pointLabels,action.index),x:newState.coords[action.index][X],y:newState.coords[action.index][Y],angleMeasure:getClockwiseAngle(newState.coords,newState.allowReflexAngles??false)}};case "polygon":let newValue;if(state.snapTo==="sides"){newValue=boundAndSnapToSides(action.destination,state,action.index);}else if(state.snapTo==="angles"){newValue=boundAndSnapToPolygonAngle(action.destination,state,action.index);}else {newValue=boundToEdgeAndSnapToGrid(action.destination,state);}const newCoords=setAtIndex({array:state.coords,index:action.index,newValue:newValue});const polygonSidesCanIntersect=state.numSides==="unlimited"&&!state.closedPolygon;if(!polygonSidesCanIntersect&&polygonSidesIntersect(newCoords)){return state}return {...state,hasBeenInteractedWith:true,coords:newCoords,stateAnnouncement:{type:"move-point",pointLabel:resolvePointLabel(state.pointLabels,action.index),x:newValue[X],y:newValue[Y]}};case "point":{const newCoord=boundToEdgeAndSnapToGrid(action.destination,state);return {...state,hasBeenInteractedWith:true,focusedPointIndex:action.index,coords:setAtIndex({array:state.coords,index:action.index,newValue:newCoord}),stateAnnouncement:{type:"move-point",pointLabel:resolvePointLabel(state.pointLabels,action.index),x:newCoord[X],y:newCoord[Y]}}}case "sinusoid":{const destination=action.destination;const boundDestination=boundToEdgeAndSnapToGrid(destination,state);const newCoords=[...state.coords];newCoords[action.index]=boundDestination;if(newCoords[0][X]===newCoords[1][X]){return state}return {...state,hasBeenInteractedWith:true,coords:setAtIndex({array:state.coords,index:action.index,newValue:boundDestination}),stateAnnouncement:{type:"move-sinusoid-point",pointIndex:action.index,pointLabel:getCustomPointLabel(state.pointLabels,action.index),x:newCoords[action.index][X],y:newCoords[action.index][Y],otherY:newCoords[1-action.index][Y]}}}case "exponential":{const boundDestination=boundToEdgeAndSnapToGrid(action.destination,state);const newCoords=[...state.coords];newCoords[action.index]=boundDestination;if(newCoords[0][X]===newCoords[1][X]){return state}const expHandle=getAsymptoteHandleCoord("horizontal",state.range,state.asymptote);if(boundDestination[X]===expHandle[X]&&boundDestination[Y]===expHandle[Y]){return state}return {...state,hasBeenInteractedWith:true,coords:setAtIndex({array:state.coords,index:action.index,newValue:boundDestination}),stateAnnouncement:{type:"move-exponential-point",pointIndex:action.index,pointLabel:getCustomPointLabel(state.pointLabels,action.index),x:boundDestination[X],y:boundDestination[Y],hasCurve:getExponentialCoefficients(newCoords,state.asymptote)!==undefined}}}case "logarithm":{const boundDestination=boundToEdgeAndSnapToGrid(action.destination,state);const newCoords=[...state.coords];newCoords[action.index]=boundDestination;if(newCoords[0][X]===newCoords[1][X]){return state}if(newCoords[0][Y]===newCoords[1][Y]){return state}const logHandle=getAsymptoteHandleCoord("vertical",state.range,state.asymptote);if(boundDestination[X]===logHandle[X]&&boundDestination[Y]===logHandle[Y]){return state}return {...state,hasBeenInteractedWith:true,coords:setAtIndex({array:state.coords,index:action.index,newValue:boundDestination}),stateAnnouncement:{type:"move-logarithm-point",pointIndex:action.index,pointLabel:getCustomPointLabel(state.pointLabels,action.index),x:boundDestination[X],y:boundDestination[Y],hasCurve:getLogarithmCoefficients(newCoords,state.asymptote)!==undefined}}}case "absolute-value":{const boundDestination=boundToEdgeAndSnapToGrid(action.destination,state);const newCoords=[...state.coords];newCoords[action.index]=boundDestination;if(newCoords[0][X]===newCoords[1][X]){return state}return {...state,hasBeenInteractedWith:true,coords:setAtIndex({array:state.coords,index:action.index,newValue:boundDestination}),stateAnnouncement:{type:"move-absolute-value-point",pointIndex:action.index,pointLabel:getCustomPointLabel(state.pointLabels,action.index),x:boundDestination[X],y:boundDestination[Y],slope:getAbsoluteValueCoefficients(newCoords)[0]}}}case "tangent":{const boundDestination=boundToEdgeAndSnapToGrid(action.destination,state);const newCoords=[...state.coords];newCoords[action.index]=boundDestination;if(newCoords[0][X]===newCoords[1][X]||newCoords[0][Y]===newCoords[1][Y]){return state}return {...state,hasBeenInteractedWith:true,coords:setAtIndex({array:state.coords,index:action.index,newValue:boundDestination}),stateAnnouncement:{type:"move-tangent-point",pointIndex:action.index,pointLabel:getCustomPointLabel(state.pointLabels,action.index),x:boundDestination[X],y:boundDestination[Y]}}}case "quadratic":{const newCoords=[...state.coords];const boundDestination=boundToEdgeAndSnapToGrid(action.destination,state);newCoords[action.index]=boundDestination;const QuadraticCoefficients=getQuadraticCoefficients(newCoords);if(QuadraticCoefficients===undefined){return state}const vertex=getQuadraticVertex(QuadraticCoefficients);return {...state,hasBeenInteractedWith:true,coords:setAtIndex({array:state.coords,index:action.index,newValue:boundDestination}),stateAnnouncement:{type:"move-quadratic-point",pointIndex:action.index,pointLabel:getCustomPointLabel(state.pointLabels,action.index),x:boundDestination[X],y:boundDestination[Y],vertex}}}default:throw new Error("The movePoint action is only for point, quadratic, and polygon graphs")}}function doMoveCenter(state,action){switch(state.type){case "circle":{const constrainedCenter=boundToEdgeAndSnapToGrid(action.destination,state);const newRadiusPoint=[...vec.add(state.radiusPoint,vec.sub(constrainedCenter,state.center))];const[xMin,xMax]=state.range[X];const[radX]=newRadiusPoint;if(radX<xMin||radX>xMax){const xJumpDist=(radX-constrainedCenter[X])*2;const possibleNewX=radX-xJumpDist;if(possibleNewX>=xMin&&possibleNewX<=xMax){newRadiusPoint[X]=possibleNewX;}else {return state}}return {...state,hasBeenInteractedWith:true,center:constrainedCenter,radiusPoint:newRadiusPoint,stateAnnouncement:{type:"move-center",x:constrainedCenter[X],y:constrainedCenter[Y]}}}case "exponential":{const newY=boundAndSnapToGrid(action.destination,state)[Y];if(newY===state.asymptote){return state}const expFutureHandle=getAsymptoteHandleCoord("horizontal",state.range,newY);if(state.coords.some(c=>c[X]===expFutureHandle[X]&&c[Y]===expFutureHandle[Y])){return state}return {...state,hasBeenInteractedWith:true,asymptote:newY,stateAnnouncement:{type:"move-exponential-asymptote",asymptoteY:newY}}}case "logarithm":{const newX=boundAndSnapToGrid(action.destination,state)[X];if(newX===state.asymptote){return state}const logFutureHandle=getAsymptoteHandleCoord("vertical",state.range,newX);if(state.coords.some(c=>c[X]===logFutureHandle[X]&&c[Y]===logFutureHandle[Y])){return state}return {...state,hasBeenInteractedWith:true,asymptote:newX,stateAnnouncement:{type:"move-logarithm-asymptote",asymptoteX:newX}}}default:throw new Error("The doMoveCenter action is only for circle, exponential, or logarithm graphs")}}function doMoveRadiusPoint(state,action){switch(state.type){case "circle":{const nextRadiusPoint=boundToEdgeAndSnapToGrid([action.destination[X],state.center[1]],state);if(vector$3.equal(nextRadiusPoint,state.center)){return state}return {...state,hasBeenInteractedWith:true,radiusPoint:nextRadiusPoint,stateAnnouncement:{type:"move-radius-point",x:nextRadiusPoint[X],y:nextRadiusPoint[Y],centerX:state.center[X],radius:vec.dist(state.center,nextRadiusPoint),pointLabel:getCustomPointLabel(state.pointLabels,0)}}}default:throw new Error("The doMoveRadiusPoint action is only for circle graphs")}}function doChangeSnapStep(state,action){if(_.isEqual(state.snapStep,action.snapStep)){return state}return {...state,snapStep:action.snapStep}}function doChangeRange(state,action){if(_.isEqual(state.range,action.range)){return state}return {...state,range:action.range}}function doAddPoint(state,action){if(!isUnlimitedGraphState(state)){return state}const{snapStep}=state;const snappedPoint=snap(snapStep,action.location);for(const point of state.coords){if(point[X]===snappedPoint[X]&&point[Y]===snappedPoint[Y]){return state}}const newCoords=[...state.coords,snappedPoint];return {...state,hasBeenInteractedWith:true,coords:newCoords,showRemovePointButton:true,focusedPointIndex:newCoords.length-1}}function doRemovePoint(state,action){if(!isUnlimitedGraphState(state)){return state}const nextFocusedPointIndex=state.coords.length>1?state.coords.length-2:null;return {...state,coords:state.coords.filter((_,i)=>i!==action.index),focusedPointIndex:nextFocusedPointIndex,showRemovePointButton:nextFocusedPointIndex!==null?true:false}}const getDeltaVertex=(maxMoves,minMoves,delta)=>{const[deltaX,deltaY]=delta;const maxXMove=Math.min(...maxMoves.map(move=>move[X]));const maxYMove=Math.min(...maxMoves.map(move=>move[Y]));const minXMove=Math.max(...minMoves.map(move=>move[X]));const minYMove=Math.max(...minMoves.map(move=>move[Y]));const dx=clamp(deltaX,minXMove,maxXMove);const dy=clamp(deltaY,minYMove,maxYMove);return [dx,dy]};const getChange=(coords,delta,constraintOpts)=>{const maxMoves=coords.map(point=>maxMove({...constraintOpts,point}));const minMoves=coords.map(point=>minMove({...constraintOpts,point}));const[dx,dy]=getDeltaVertex(maxMoves,minMoves,delta);return [dx,dy]};const constrainShapePreservingMove=(currentLine,newStart,constraintOpts)=>{const desiredDelta=vec.sub(newStart,currentLine[0]);const change=getChange(currentLine,desiredDelta,constraintOpts);const{snapStep}=constraintOpts;return [snap(snapStep,vec.add(currentLine[0],change)),snap(snapStep,vec.add(currentLine[1],change))]};function leq(a,b){return a<b||approximateEqual(a,b)}function boundAndSnapToGrid(point,{snapStep,range}){return snap(snapStep,bound$1({snapStep,range,point}))}function boundAndSnapAngleVertex({range,coords,snapStep},{destination}){const coordsCopy=[...coords];const startingVertex=coordsCopy[1];const insetAmount=vec.add(snapStep,[minDistanceBetweenAngleVertexAndSidePoint,minDistanceBetweenAngleVertexAndSidePoint]);const newVertex=clampToBox(inset(insetAmount,range),snap(snapStep,destination));const delta=vec.add(newVertex,reverseVector(startingVertex));const newPoints={};for(const i of [0,2]){const oldPoint=coordsCopy[i];let newPoint=vec.add(oldPoint,delta);let angle=getAngleFromVertex(newVertex,newPoint);angle*=Math.PI/180;newPoint=constrainToBoundsOnAngle(newPoint,angle,range,snapStep);newPoints[i]=newPoint;}newPoints[1]=newVertex;Object.entries(newPoints).forEach(([i,newPoint])=>{coordsCopy[i]=newPoint;});return coordsCopy}function tooClose(point1,point2,range){const safeDistance=2;const distance=vec.dist(point1,point2);return distance<safeDistance}function constrainToBoundsOnAngle(point,angle,range,snapStep){const lower=[range[0][0]+snapStep[0],range[1][0]+snapStep[0]];const upper=[range[0][1]-snapStep[1],range[1][1]-snapStep[1]];let result=point;if(result[0]<lower[0]){result=[lower[0],result[1]+(lower[0]-result[0])*Math.tan(angle)];}else if(result[0]>upper[0]){result=[upper[0],result[1]-(result[0]-upper[0])*Math.tan(angle)];}if(result[1]<lower[1]){result=[result[0]+(lower[1]-result[1])/Math.tan(angle),lower[1]];}else if(result[1]>upper[1]){result=[result[0]-(result[1]-upper[1])/Math.tan(angle),upper[1]];}return result}function boundAndSnapAngleEndPoints(destinationPoint,{range,coords,snapDegrees,angleOffsetDeg,snapStep},index){const snap=snapDegrees||1;const offsetDegrees=angleOffsetDeg||0;const coordsCopy=[...coords];const angleRange=[[range[0][0]+snapStep[0],range[0][1]-snapStep[0]],[range[1][0]+snapStep[1],range[1][1]-snapStep[1]]];const boundPoint=bound$1({snapStep:[0,0],range:angleRange,point:destinationPoint});coordsCopy[index]=boundPoint;const vertex=coords[1];let angle=getAngleFromVertex(coordsCopy[index],vertex);angle=Math.round((angle-offsetDegrees)/snap)*snap+offsetDegrees;const minDistance=minDistanceBetweenAngleVertexAndSidePoint+.01;const distance=Math.max(vec.dist(coordsCopy[index],vertex),minDistance);const snappedValue=vec.add(vertex,polar(distance,angle));return snappedValue}function angleSidePointsTooCloseToVertex(state){return tooClose(state.coords[0],state.coords[1],state.range)||tooClose(state.coords[2],state.coords[1],state.range)}function boundAndSnapToPolygonAngle(destinationPoint,{range,coords},index){const startingPoint=coords[index];return calculateAngleSnap(destinationPoint,range,coords,index,startingPoint)}function calculateAngleSnap(destinationPoint,range,coords,index,startingPoint){const coordsCopy=[...coords];coordsCopy[index]=bound$1({snapStep:[0,0],range,point:destinationPoint});const angles=angleMeasures(coordsCopy).map(angle=>angle*180/Math.PI);const rel=j=>{return (index+j+coordsCopy.length)%coordsCopy.length};_.each([-1,1],function(j){angles[rel(j)]=Math.round(angles[rel(j)]);});const getAngle=function(a,vertex,b){const angle=getClockwiseAngle([coordsCopy[rel(a)],coordsCopy[rel(vertex)],coordsCopy[rel(b)]]);return angle};const innerAngles=[angles[rel(-1)]-getAngle(-2,-1,1),angles[rel(1)]-getAngle(-1,1,2)];innerAngles[2]=180-(innerAngles[0]+innerAngles[1]);if(innerAngles.some(function(angle){return leq(angle,1)})){return startingPoint}const knownSide=magnitude(vector(coordsCopy[rel(-1)],coordsCopy[rel(1)]));const onLeft=sign(ccw(coordsCopy[rel(-1)],coordsCopy[rel(1)],coordsCopy[index]))===1;const side=Math.sin(innerAngles[1]*Math.PI/180)/Math.sin(innerAngles[2]*Math.PI/180)*knownSide;const outerAngle=getAngleFromVertex(coordsCopy[rel(1)],coordsCopy[rel(-1)]);const offset=polar(side,outerAngle+(onLeft?1:-1)*innerAngles[0]);return vector$3.add(coordsCopy[rel(-1)],offset)}function boundAndSnapToSides(destinationPoint,{range,coords},index){const startingPoint=coords[index];return calculateSideSnap(destinationPoint,range,coords,index,startingPoint)}function calculateSideSnap(destinationPoint,range,coords,index,startingPoint){const boundedDestinationPoint=bound$1({snapStep:[0,0],range,point:destinationPoint});const rel=j=>{return (index+j+coords.length)%coords.length};const sides=[[coords[rel(-1)],boundedDestinationPoint],[boundedDestinationPoint,coords[rel(1)]],[coords[rel(-1)],coords[rel(1)]]].map(function(coords){return magnitude(vector(...coords))});_.each([0,1],function(j){sides[j]=Math.round(sides[j]);});if(leq(sides[1]+sides[2],sides[0])||leq(sides[0]+sides[2],sides[1])||leq(sides[0]+sides[1],sides[2])){return startingPoint}const innerAngle=lawOfCosines(sides[0],sides[2],sides[1]);const outerAngle=getAngleFromVertex(coords[rel(1)],coords[rel(-1)]);const onLeft=sign(ccw(coords[rel(-1)],coords[rel(1)],boundedDestinationPoint))===1;const offset=polar(sides[0],outerAngle+(onLeft?1:-1)*innerAngle);return vector$3.add(coords[rel(-1)],offset)}function maxMove({snapStep,range,point}){const topRight=boundToEdgeAndSnapToGrid([Infinity,Infinity],{snapStep,range});return vec.sub(topRight,point)}function minMove({snapStep,range,point}){const bottomLeft=boundToEdgeAndSnapToGrid([-Infinity,-Infinity],{snapStep,range});return vec.sub(bottomLeft,point)}const coordsOverlap=coords=>coords.some((coord,i)=>coords.some((c,j)=>i!==j&&vector$3.equal(coord,c)));function updateAtIndex(args){const{array,index,update}=args;const newValue=update(array[index]);return setAtIndex({array,index,newValue})}function setAtIndex(args){const{array,index,newValue}=args;const copy=[...array];copy[index]=newValue;return copy}
1966
-
1967
- const{clockwise}=geometry;const{convertRadiansToDegrees}=angles;function renderPolygonGraph(state,dispatch,i18n,markings){return {graph:jsxRuntimeExports.jsx(PolygonGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describePolygonGraph(state,i18n,markings).srPolygonInteractiveElements}}const PolygonGraph=props=>{const{dispatch}=props;const{numSides,coords,snapStep,snapTo="grid"}=props.graphState;const graphConfig=useGraphConfig();const polygonRef=React.useRef(null);const polygonHitboxRef=React.useRef(null);const pointsRef=React.useRef([]);const lastMoveTimeRef=React.useRef(0);const{range:[x,y]}=graphConfig;const[[left,top]]=useTransformVectorsToPixels([x[0],y[1]]);const dragReferencePoint=coords[0];const constrain=getKeyboardMovementConstraintForPolygon(snapStep,snapTo);const moveAll=newStart=>{dispatch(actions.polygon.moveAll(newStart));};useDraggable({gestureTarget:polygonRef,point:dragReferencePoint,onMove:moveAll,constrainKeyboardMovement:constrain});const{dragging}=useDraggable({gestureTarget:polygonHitboxRef,point:dragReferencePoint,onMove:moveAll,constrainKeyboardMovement:constrain});const[hovered,setHovered]=React.useState(false);const[focusVisible,setFocusVisible]=React.useState(false);const polygonHitbox=useHitbox({shape:{kind:"polygon",vertices:coords},hitboxRef:polygonHitboxRef,layer:"body",dragging,onHoverChange:setHovered,testId:"movable-polygon__hitbox"});React.useEffect(()=>{const focusedIndex=props.graphState.focusedPointIndex;if(focusedIndex!=null){pointsRef.current[focusedIndex]?.focus();}},[props.graphState.focusedPointIndex,props.graphState.coords.length,pointsRef]);React.useEffect(()=>{if(numSides==="unlimited"&&props.graphState.coords.length>2){dispatch(actions.polygon.closePolygon());}},[]);const statefulProps={...props,graphConfig,polygonRef,pointsRef,lastMoveTimeRef,left,top,dragging,points:coords,hovered,setHovered,focusVisible,setFocusVisible};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[polygonHitbox,numSides==="unlimited"?jsxRuntimeExports.jsx(UnlimitedPolygonGraph,{...statefulProps}):jsxRuntimeExports.jsx(LimitedPolygonGraph,{...statefulProps})]})};const LimitedPolygonGraph=statefulProps=>{const{dispatch,hovered,setHovered,focusVisible,setFocusVisible,graphConfig,polygonRef,lastMoveTimeRef,dragging,points}=statefulProps;const{showAngles,showSides,range,snapTo="grid",snapStep,pointLabels}=statefulProps.graphState;const{disableKeyboardInteraction,interactiveColor}=graphConfig;const{strings,locale}=usePerseusI18n();const buildLabel=usePointAriaLabel(pointLabels);const id=React.useId();const lines=getLines(points);const polygonPointsNumId=id+"-points-num";const polygonPointsId=id+"-points";const{srPolygonGraph,srPolygonGraphPointsNum,srPolygonGraphPoints,srPolygonElementsNum}=describePolygonGraph(statefulProps.graphState,{strings,locale},statefulProps.graphConfig.markings);return jsxRuntimeExports.jsxs("g",{"aria-label":srPolygonGraph,"aria-describedby":`${polygonPointsNumId} ${polygonPointsId}`,children:[jsxRuntimeExports.jsx(Polygon,{points:[...points],color:interactiveColor,svgPolygonProps:{strokeWidth:focusVisible?"var(--movable-line-stroke-weight-active)":"var(--movable-line-stroke-weight)",style:{fill:"transparent"},"aria-hidden":true}}),points.map((point,i)=>{const pt1=points.at(i-1);const pt2=points[(i+1)%points.length];if(!pt1||!pt2){return null}return jsxRuntimeExports.jsx(PolygonAngle,{centerPoint:point,endPoints:[pt1,pt2],areEndPointsClockwise:clockwise(points),showAngles:!!showAngles,snapTo:snapTo},"angle-"+i)}),showSides&&lines.map(([start,end],i)=>{const[x,y]=line.midpoint([start,end]);const length=vec.dist(start,end);const isApprox=!Number.isInteger(length);return jsxRuntimeExports.jsx(TextLabel,{x:x,y:y,children:isApprox?`≈ ${length.toFixed(snapTo==="sides"?0:1)}`:length},"side-"+i)}),jsxRuntimeExports.jsx(Polygon,{points:[...points],color:"transparent",svgPolygonProps:{ref:polygonRef,tabIndex:disableKeyboardInteraction?-1:0,strokeWidth:TARGET_SIZE,style:{cursor:dragging?"grabbing":"grab",fill:hovered?"var(--mafs-blue)":"transparent"},onMouseEnter:()=>setHovered(true),onMouseLeave:()=>setHovered(false),onKeyDownCapture:()=>{setFocusVisible(hasFocusVisible(polygonRef.current));},onFocus:()=>{setFocusVisible(hasFocusVisible(polygonRef.current));},onBlur:()=>setFocusVisible(hasFocusVisible(polygonRef.current)),className:"movable-polygon",role:"button","aria-label":srPolygonGraphPoints?`${srPolygonElementsNum} ${srPolygonGraphPoints}`:srPolygonElementsNum,"aria-disabled":disableKeyboardInteraction}}),points.map((point,i)=>{const angleId=`${id}-angle-${i}`;const side1Id=`${id}-point-${i}-side-1`;const side2Id=`${id}-point-${i}-side-2`;const angle=getAngleFromPoints(points,i);const angleDegree=angle?convertRadiansToDegrees(angle):null;const sidesArray=getSideLengthsFromPoints(points,i);const{pointIndex:point1Index,sideLength:side1Length}=sidesArray[0];const{pointIndex:point2Index,sideLength:side2Length}=sidesArray[1];return jsxRuntimeExports.jsxs("g",{children:[jsxRuntimeExports.jsx(MovablePoint$3,{ariaDescribedBy:`${angleId} ${side1Id} ${side2Id}`,ariaLabel:buildLabel(i,point),constrain:getKeyboardMovementConstraintForPoint(points,i,range,snapStep,snapTo),point:point,sequenceNumber:i+1,onMove:destination=>{const now=Date.now();const targetFPS=40;const moveThresholdTime=1e3/targetFPS;if(now-lastMoveTimeRef.current>moveThresholdTime){dispatch(actions.polygon.movePoint(i,destination));lastMoveTimeRef.current=now;}}}),angleDegree&&jsxRuntimeExports.jsx(SRDescInSVG,{id:angleId,children:Number.isInteger(angleDegree)?strings.srPolygonPointAngle({angle:angleDegree}):strings.srPolygonPointAngleApprox({angle:srFormatNumber(angleDegree,locale,1)})}),jsxRuntimeExports.jsx(SRDescInSVG,{id:side1Id,children:getPolygonSideString(side1Length,point1Index,strings,locale)}),jsxRuntimeExports.jsx(SRDescInSVG,{id:side2Id,children:getPolygonSideString(side2Length,point2Index,strings,locale)})]},"point-"+i)}),jsxRuntimeExports.jsx(SRDescInSVG,{id:polygonPointsNumId,children:srPolygonGraphPointsNum}),srPolygonGraphPoints&&jsxRuntimeExports.jsx(SRDescInSVG,{id:polygonPointsId,children:srPolygonGraphPoints})]})};const UnlimitedPolygonGraph=statefulProps=>{const{dispatch,graphConfig,left,top,pointsRef,points}=statefulProps;const{coords,closedPolygon,pointLabels}=statefulProps.graphState;const{strings,locale}=usePerseusI18n();const buildLabel=usePointAriaLabel(pointLabels);const{interactiveColor}=useGraphConfig();const[isCurrentlyDragging,setIsCurrentlyDragging]=useState(false);const dragEndCallbackTimer=useTimeout(()=>setIsCurrentlyDragging(false),400);const id=React.useId();const polygonPointsNumId=id+"-points-num";const polygonPointsId=id+"-points";if(closedPolygon){const closedPolygonProps={...statefulProps,numSides:coords.length};return jsxRuntimeExports.jsx(LimitedPolygonGraph,{...closedPolygonProps})}const{graphDimensionsInPixels}=graphConfig;const widthPx=graphDimensionsInPixels[0];const heightPx=graphDimensionsInPixels[1];const emptyGraph=coords.length===0;const{srPolygonGraph,srPolygonGraphPointsNum,srPolygonGraphPoints}=describePolygonGraph(statefulProps.graphState,{strings,locale},statefulProps.graphConfig.markings);return jsxRuntimeExports.jsxs("g",{"aria-label":emptyGraph?strings.srUnlimitedPolygonEmpty:srPolygonGraph,"aria-describedby":`${polygonPointsNumId} ${polygonPointsId}`,children:[jsxRuntimeExports.jsx(Polyline,{points:[...points],color:interactiveColor,svgPolylineProps:{strokeWidth:"var(--movable-line-stroke-weight)",style:{fill:"transparent"},"aria-hidden":true}}),jsxRuntimeExports.jsx("rect",{"aria-hidden":true,style:{fill:"none",pointerEvents:"all",cursor:"crosshair"},width:widthPx,height:heightPx,x:left,y:top,onClick:event=>{if(isCurrentlyDragging){return}const elementRect=event.currentTarget.getBoundingClientRect();const zoomFactor=getCSSZoomFactor(event.currentTarget);const x=(event.clientX-elementRect.x)/zoomFactor;const y=(event.clientY-elementRect.y)/zoomFactor;const graphCoordinates=pixelsToVectors([[x,y]],graphConfig);dispatch(actions.polygon.addPoint(graphCoordinates[0]));}}),coords.map((point,i)=>{const angleId=`${id}-angle-${i}`;let sideIds="";const hasAngle=i>0&&i<coords.length-1;const angle=hasAngle?getAngleFromPoints(points,i):null;const angleDegree=angle?convertRadiansToDegrees(angle):null;const sidesArray=getSideLengthsFromPoints(points,i,true);for(let sideIndex=0;sideIndex<sidesArray.length;sideIndex++){sideIds+=`${id}-point-${i}-side-${sideIndex} `;}return jsxRuntimeExports.jsxs("g",{children:[jsxRuntimeExports.jsx(MovablePoint$3,{ariaDescribedBy:`${angleId} ${sideIds}`,ariaLabel:buildLabel(i,point),point:point,sequenceNumber:i+1,onDragStart:()=>{dragEndCallbackTimer.clear();setIsCurrentlyDragging(true);},onMove:destination=>{dispatch(actions.polygon.movePoint(i,destination));},onDragEnd:()=>{dragEndCallbackTimer.set();},ref:ref=>{pointsRef.current[i]=ref;},onFocus:()=>{dispatch(actions.polygon.focusPoint(i));},onClick:()=>{if(i===0&&getArrayWithoutDuplicates(coords).length>=3){dispatch(actions.polygon.closePolygon());}dispatch(actions.polygon.clickPoint(i));}}),angleDegree&&jsxRuntimeExports.jsx(SRDescInSVG,{id:angleId,children:Number.isInteger(angleDegree)?strings.srPolygonPointAngle({angle:angleDegree}):strings.srPolygonPointAngleApprox({angle:srFormatNumber(angleDegree,locale,1)})}),sidesArray.map(({pointIndex,sideLength},j)=>jsxRuntimeExports.jsx(SRDescInSVG,{id:`${id}-point-${i}-side-${j}`,children:getPolygonSideString(sideLength,pointIndex,strings,locale)},`${id}-point-${i}-side-${j}`))]},"point-"+i)}),coords.length>0&&jsxRuntimeExports.jsx(SRDescInSVG,{id:polygonPointsNumId,children:srPolygonGraphPointsNum}),srPolygonGraphPoints&&jsxRuntimeExports.jsx(SRDescInSVG,{id:polygonPointsId,children:srPolygonGraphPoints})]})};function getLines(points){return points.map((point,i)=>{const next=points[(i+1)%points.length];return [point,next]})}const hasFocusVisible=element=>{const matches=selector=>element?.matches(selector)??false;try{return matches(":focus-visible")}catch{return matches(":focus")}};function getKeyboardMovementConstraintForPoint(points,index,range,snapStep,snapTo){switch(snapTo){case "grid":return p=>snap(snapStep,p);case "sides":return getSideSnapConstraint(points,index,range);case "angles":return getAngleSnapConstraint(points,index,range);default:throw new UnreachableCaseError(snapTo)}}function getKeyboardMovementConstraintForPolygon(snapStep,snapTo){switch(snapTo){case "grid":return p=>snap(snapStep,p);case "sides":case "angles":return p=>p;default:throw new UnreachableCaseError(snapTo)}}function getSideSnapConstraint(points,index,range){const newPoints=[...points];const pointToBeMoved=newPoints[index];const movePointWithConstraint=moveFunc=>{let destinationAttempt=moveFunc(pointToBeMoved);let newPoint=pointToBeMoved;while(newPoint[0]===pointToBeMoved[0]&&newPoint[1]===pointToBeMoved[1]&&isInBound({range,point:destinationAttempt})){newPoint=calculateSideSnap(destinationAttempt,range,newPoints,index,pointToBeMoved);destinationAttempt=moveFunc(destinationAttempt);}return newPoint};return {up:movePointWithConstraint(coord=>vec.add(coord,[0,1])),down:movePointWithConstraint(coord=>vec.sub(coord,[0,1])),left:movePointWithConstraint(coord=>vec.sub(coord,[1,0])),right:movePointWithConstraint(coord=>vec.add(coord,[1,0]))}}function getAngleSnapConstraint(points,index,range){const newPoints=[...points];const pointToBeMoved=newPoints[index];const movePointWithConstraint=moveFunc=>{let destinationAttempt=bound$1({snapStep:[0,0],range,point:moveFunc(pointToBeMoved)});let newPoint=pointToBeMoved;while(newPoint[0]===pointToBeMoved[0]&&newPoint[1]===pointToBeMoved[1]&&isInBound({range,point:destinationAttempt})){newPoint=calculateAngleSnap(destinationAttempt,range,newPoints,index,pointToBeMoved);destinationAttempt=moveFunc(destinationAttempt);}return newPoint};return {up:movePointWithConstraint(coord=>vec.add(coord,[0,.1])),down:movePointWithConstraint(coord=>vec.sub(coord,[0,.1])),left:movePointWithConstraint(coord=>vec.sub(coord,[.1,0])),right:movePointWithConstraint(coord=>vec.add(coord,[.1,0]))}}
1968
-
1969
- function renderQuadraticGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(QuadraticGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeQuadraticGraph(state,i18n).srQuadraticInteractiveElements}}function QuadraticGraph(props){const{dispatch,graphState}=props;const{coords,pointLabels,snapStep}=graphState;const{interactiveColor}=useGraphConfig();const{strings,locale}=usePerseusI18n();const id=React.useId();const quadraticDirectionId=id+"-direction";const quadraticVertexId=id+"-vertex";const quadraticInterceptsId=id+"-intercepts";const coeffRef=React.useRef([0,0,0]);const coeffs=getQuadraticCoefficients$2(coords);if(coeffs!==undefined){coeffRef.current=coeffs;}const[a,b,c]=coeffRef.current;const y=x=>(a*x+b)*x+c;const{srQuadraticGraph,srQuadraticDirection,srQuadraticVertex,srQuadraticXIntercepts,srQuadraticYIntercept}=describeQuadraticGraph(graphState,{strings,locale});return jsxRuntimeExports.jsxs("g",{"aria-label":srQuadraticGraph,"aria-describedby":`${quadraticDirectionId} ${quadraticVertexId} ${quadraticInterceptsId}`,children:[jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(Plot$2.OfX,{y:y,color:interactiveColor,svgPathProps:{"aria-hidden":true}})}),coords.map((coord,i)=>{const srQuadraticPoint=getQuadraticPointString(resolvePointLabel(pointLabels,i),coord,strings,locale);const srVertex=srQuadraticVertex?` ${srQuadraticVertex}`:"";return jsxRuntimeExports.jsx(MovablePoint$3,{ariaLabel:`${srQuadraticPoint}${srVertex}`,point:coord,sequenceNumber:i+1,constrain:getQuadraticKeyboardConstraint(coords,snapStep,i),onMove:destination=>dispatch(actions.quadratic.movePoint(i,destination))},"point-"+i)}),srQuadraticDirection&&jsxRuntimeExports.jsx(SRDescInSVG,{id:quadraticDirectionId,children:srQuadraticDirection}),srQuadraticVertex&&jsxRuntimeExports.jsx(SRDescInSVG,{id:quadraticVertexId,children:srQuadraticVertex}),jsxRuntimeExports.jsx(SRDescInSVG,{id:quadraticInterceptsId,children:srQuadraticXIntercepts?`${srQuadraticXIntercepts} ${srQuadraticYIntercept}`:`${srQuadraticYIntercept}`})]})}const getQuadraticKeyboardConstraint=(coords,snapStep,pointMoved)=>{const newCoords=[coords[0],coords[1],coords[2]];const coordToBeMoved=newCoords[pointMoved];const movePointWithConstraint=moveFunc=>{let movedCoord=moveFunc(coordToBeMoved);newCoords[pointMoved]=movedCoord;if(areCoordsValid(newCoords)){return movedCoord}movedCoord=moveFunc(movedCoord);newCoords[pointMoved]=movedCoord;if(areCoordsValid(newCoords)){return movedCoord}return moveFunc(movedCoord)};return {up:vec.add(coordToBeMoved,[0,snapStep[1]]),down:vec.sub(coordToBeMoved,[0,snapStep[1]]),left:movePointWithConstraint(coord=>vec.sub(coord,[snapStep[0],0])),right:movePointWithConstraint(coord=>vec.add(coord,[snapStep[0],0]))}};const areCoordsValid=coords=>{const p1=coords[0];const p2=coords[1];const p3=coords[2];if(p1[0]===p2[0]||p2[0]===p3[0]||p1[0]===p3[0]){return false}return true};
1970
-
1971
- function renderRayGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(RayGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeRayGraph(state,i18n).srRayInteractiveElement}}const RayGraph=props=>{const{dispatch}=props;const{coords:line}=props.graphState;const handleMoveLine=newStart=>dispatch(actions.ray.moveRay(newStart));const handleMovePoint=(pointIndex,newPoint)=>dispatch(actions.ray.movePoint(pointIndex,newPoint));const{strings,locale}=usePerseusI18n();const id=React.useId();const pointsDescriptionId=id+"-points";const{srRayGraph,srRayPoints,srRayEndpoint,srRayTerminalPoint,srRayGrabHandle}=describeRayGraph(props.graphState,{strings,locale});return jsxRuntimeExports.jsxs("g",{"aria-label":srRayGraph,"aria-describedby":pointsDescriptionId,children:[jsxRuntimeExports.jsx(MovableLine$2,{points:line,ariaLabels:{point1AriaLabel:srRayEndpoint,point2AriaLabel:srRayTerminalPoint,grabHandleAriaLabel:srRayGrabHandle},onMoveLine:handleMoveLine,onMovePoint:handleMovePoint,extend:{start:false,end:true}}),jsxRuntimeExports.jsx(SRDescInSVG,{id:pointsDescriptionId,children:srRayPoints})]})};
1972
-
1973
- function renderSegmentGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(SegmentGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeSegmentGraph(state,i18n).srSegmentInteractiveElements}}const SegmentGraph=({dispatch,graphState})=>{const{coords:segments}=graphState;const i18n=usePerseusI18n();const segmentUniqueId=React.useId();const lengthDescriptionId=segmentUniqueId+"-length";const wholeGraphDescriptionId=segmentUniqueId+"-whole-graph";const{srSegmentGraph,srWholeGraphDescription,srSegments}=describeSegmentGraph(graphState,i18n);return jsxRuntimeExports.jsxs("g",{"aria-label":srSegmentGraph,"aria-describedby":`${wholeGraphDescriptionId} ${segments.length===1&&lengthDescriptionId}`,children:[segments?.map((segment,i)=>jsxRuntimeExports.jsxs("g",{"aria-label":segments.length===1?undefined:srSegments[i].individualAriaLabel,"aria-describedby":segments.length===1?undefined:lengthDescriptionId,children:[jsxRuntimeExports.jsx(MovableLine$2,{points:segment,onMoveLine:newStart=>{dispatch(actions.segment.moveLine(i,newStart));},onMovePoint:(endpointIndex,destination)=>{dispatch(actions.segment.movePointInFigure(i,endpointIndex,destination));},ariaLabels:{point1AriaLabel:srSegments[i].point1AriaLabel,point2AriaLabel:srSegments[i].point2AriaLabel,grabHandleAriaLabel:srSegments[i].grabHandleAriaLabel}},i),jsxRuntimeExports.jsx(SRDescInSVG,{id:lengthDescriptionId,children:srSegments[i].lengthDescription})]},`${segmentUniqueId}-${i}`)),jsxRuntimeExports.jsx(SRDescInSVG,{id:wholeGraphDescriptionId,children:srWholeGraphDescription})]})};
1974
-
1975
- function renderSinusoidGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(SinusoidGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeSinusoidGraph(state,i18n).srSinusoidInteractiveElements}}function SinusoidGraph(props){const{dispatch,graphState}=props;const{interactiveColor}=useGraphConfig();const i18n=usePerseusI18n();const id=React.useId();const descriptionId=id+"-description";const{coords,snapStep}=graphState;const coeffRef=React.useRef({amplitude:1,angularFrequency:1,phase:1,verticalOffset:0});const coeffs=getSinusoidCoefficients(coords);if(coeffs!==undefined){coeffRef.current=coeffs;}const{srSinusoidGraph,srSinusoidDescription,srSinusoidRootPoint,srSinusoidPeakPoint}=describeSinusoidGraph(graphState,i18n);return jsxRuntimeExports.jsxs("g",{"aria-label":srSinusoidGraph,"aria-describedby":descriptionId,children:[jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(Plot$2.OfX,{y:x=>computeSine(x,coeffRef.current),color:interactiveColor,svgPathProps:{"aria-hidden":true}})}),coords.map((coord,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{ariaLabel:i===0?srSinusoidRootPoint:srSinusoidPeakPoint,point:coord,sequenceNumber:i+1,constrain:getSinusoidKeyboardConstraint(coords,snapStep,i),onMove:destination=>dispatch(actions.sinusoid.movePoint(i,destination))},"point-"+i)),jsxRuntimeExports.jsx(SRDescInSVG,{id:descriptionId,children:srSinusoidDescription})]})}const getSinusoidKeyboardConstraint=(coords,snapStep,pointIndex)=>{const coordToBeMoved=coords[pointIndex];const otherPoint=coords[1-pointIndex];const movePointWithConstraint=moveFunc=>{let movedCoord=moveFunc(coordToBeMoved);if(movedCoord[X]===otherPoint[X]){movedCoord=moveFunc(movedCoord);}return movedCoord};return {up:movePointWithConstraint(coord=>vec.add(coord,[0,snapStep[1]])),down:movePointWithConstraint(coord=>vec.sub(coord,[0,snapStep[1]])),left:movePointWithConstraint(coord=>vec.sub(coord,[snapStep[0],0])),right:movePointWithConstraint(coord=>vec.add(coord,[snapStep[0],0]))}};const computeSine=function(x,sinusoidCoefficients){const{amplitude:a,angularFrequency:b,phase:c,verticalOffset:d}=sinusoidCoefficients;return a*Math.sin(b*x-c)+d};const getSinusoidCoefficients=coords=>{const p1=coords[0];const p2=coords[1];if(p2[X]===p1[X]){return}const amplitude=p2[Y]-p1[Y];const angularFrequency=Math.PI/(2*(p2[X]-p1[X]));const phase=p1[X]*angularFrequency;const verticalOffset=p1[Y];return {amplitude,angularFrequency,phase,verticalOffset}};
1976
-
1977
- function renderTangentGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(TangentGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeTangentGraph(state,i18n).srTangentInteractiveElements}}function TangentGraph(props){const{dispatch,graphState}=props;const{interactiveColor,range}=useGraphConfig();const i18n=usePerseusI18n();const id=React.useId();const descriptionId=id+"-description";const{coords,snapStep}=graphState;const coeffs=getTangentCoefficients(coords);invariant(coeffs!==undefined&&coeffs.amplitude!==0,"Tangent requires two control points that differ in both x and y.");const xRange=[range[0][0],range[0][1]];const yRange=[range[1][0],range[1][1]];const asymptotes=getAsymptotePositions(coeffs,xRange);const segments=getPlotSegments(asymptotes,xRange);const{srTangentGraph,srTangentDescription,srTangentInflectionPoint,srTangentControlPoint}=describeTangentGraph(graphState,i18n);return jsxRuntimeExports.jsxs("g",{"aria-label":srTangentGraph,"aria-describedby":descriptionId,children:[jsxRuntimeExports.jsx(TangentAsymptotes,{asymptotes:asymptotes,yRange:yRange,color:interactiveColor}),jsxRuntimeExports.jsx(ClipToGraphBounds,{children:segments.map(([segStart,segEnd],i)=>jsxRuntimeExports.jsx(Plot$2.OfX,{y:x=>computeTangent(x,coeffs),domain:[segStart,segEnd],color:interactiveColor,svgPathProps:{"aria-hidden":true}},`tangent-segment-${i}`))}),coords.map((coord,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{ariaLabel:i===0?srTangentInflectionPoint:srTangentControlPoint,point:coord,sequenceNumber:i+1,constrain:getTangentKeyboardConstraint(coords,snapStep,i),onMove:destination=>dispatch(actions.tangent.movePoint(i,destination))},"point-"+i)),jsxRuntimeExports.jsx(SRDescInSVG,{id:descriptionId,children:srTangentDescription})]})}const getTangentKeyboardConstraint=(coords,snapStep,pointIndex)=>{const coordToBeMoved=coords[pointIndex];const otherPoint=coords[1-pointIndex];const movePointWithConstraint=moveFunc=>{let movedCoord=moveFunc(coordToBeMoved);if(movedCoord[X]===otherPoint[X]||movedCoord[Y]===otherPoint[Y]){movedCoord=moveFunc(movedCoord);}return movedCoord};return {up:movePointWithConstraint(coord=>vec.add(coord,[0,snapStep[1]])),down:movePointWithConstraint(coord=>vec.sub(coord,[0,snapStep[1]])),left:movePointWithConstraint(coord=>vec.sub(coord,[snapStep[0],0])),right:movePointWithConstraint(coord=>vec.add(coord,[snapStep[0],0]))}};const computeTangent=function(x,tangentCoefficients){const{amplitude:a,angularFrequency:b,phase:c,verticalOffset:d}=tangentCoefficients;const arg=b*x-c;const normalized=(arg-Math.PI/2)/Math.PI%1;const distToAsymptote=Math.abs(normalized>.5?normalized-1:normalized<-0.5?normalized+1:normalized);if(distToAsymptote<.001){return NaN}return a*Math.tan(arg)+d};const getTangentCoefficients=coords=>{const p1=coords[0];const p2=coords[1];if(p2[X]===p1[X]){return}const amplitude=p2[Y]-p1[Y];const angularFrequency=Math.PI/(4*(p2[X]-p1[X]));const phase=p1[X]*angularFrequency;const verticalOffset=p1[Y];return {amplitude,angularFrequency,phase,verticalOffset}};function getAsymptotePositions(coeffs,xRange){const{angularFrequency:b,phase:c}=coeffs;if(b===0){return []}const period=Math.PI/Math.abs(b);const referenceAsymptote=(c+Math.PI/2)/b;const asymptotes=[];let x=referenceAsymptote;while(x>xRange[0]-period){if(x>xRange[0]&&x<xRange[1]){asymptotes.push(x);}x-=period;}x=referenceAsymptote+period;while(x<xRange[1]+period){if(x>xRange[0]&&x<xRange[1]){asymptotes.push(x);}x+=period;}return asymptotes.sort((a,b)=>a-b)}function getPlotSegments(asymptotes,xRange){const eps=.01;const segments=[];let start=xRange[0];for(const asymptote of asymptotes){segments.push([start,asymptote-eps]);start=asymptote+eps;}segments.push([start,xRange[1]]);return segments}function TangentAsymptotes(props){const{asymptotes,yRange,color}=props;const endpoints=asymptotes.flatMap(x=>[[x,yRange[0]],[x,yRange[1]]]);const pixels=useTransformVectorsToPixels(...endpoints);return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:asymptotes.map((x,i)=>jsxRuntimeExports.jsx(DashedAsymptoteLine,{start:pixels[i*2],end:pixels[i*2+1],color:color,testId:"tangent-asymptote__line"},`asymptote-${x}`))})}
1978
-
1979
- const ARROW_SCALE=1.5;const arrowPath=pathBuilder().move(-5,5).line(0,0).line(-5,-5).scale(ARROW_SCALE).build();function buildRoundedTriangle(tipX,tipY,armX,armY,backX,backY,backR,tipR){return pathBuilder().move(tipX,tipY).line(armX,armY).circularArc(backR,backX,backY,{sweep:true}).line(backX,-5).circularArc(backR,armX,-7.8,{sweep:true}).line(tipX,-2.8).circularArc(tipR,tipX,tipY,{sweep:true}).scale(ARROW_SCALE).build()}const arrowPathHalo=buildRoundedTriangle(2.8,2.8,-2.2,7.8,-9,5,4,4);const chevronPathAttrs={d:arrowPath,fill:"none",strokeLinejoin:"round",strokeLinecap:"round"};const MovableArrowheadView=forwardRef(function MovableArrowheadViewWithRef(props,hitboxRef){const{showTooltips,interactiveColor,snapStep}=useGraphConfig();const{point,angle,dragging,hovered,cursor,showFocusRing,onClick=()=>{}}=props;const classes=classNames("movable-arrowhead",dragging&&"movable-arrowhead--dragging",showFocusRing&&"movable-arrowhead--focus",hovered&&"movable-arrowhead--hover");const[[x,y]]=useTransformVectorsToPixels(point);const xSigFigs=countSignificantDecimals(snapStep[X]);const ySigFigs=countSignificantDecimals(snapStep[Y]);const xTickLabel=point[X].toFixed(xSigFigs);const yTickLabel=point[Y].toFixed(ySigFigs);const tooltipContent=`(${xTickLabel}, ${yTickLabel})`;const svgForArrowhead=jsxRuntimeExports.jsx("g",{"aria-hidden":true,ref:hitboxRef,className:classes,style:{"--movable-arrowhead-color":interactiveColor,cursor},"data-testid":"movable-arrowhead",onClick:onClick,children:jsxRuntimeExports.jsxs("g",{transform:`translate(${x} ${y}) rotate(${angle})`,children:[jsxRuntimeExports.jsx("path",{d:arrowPathHalo,className:"movable-arrowhead-halo"}),jsxRuntimeExports.jsx("path",{...chevronPathAttrs,className:"movable-arrowhead-ring"}),jsxRuntimeExports.jsx("path",{...chevronPathAttrs,className:"movable-arrowhead-center"})]})});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:showTooltips?jsxRuntimeExports.jsx(Tooltip,{autoUpdate:true,opened:true,content:tooltipContent,variant:"strong",children:svgForArrowhead}):svgForArrowhead})});function classNames(...names){return names.filter(Boolean).join(" ")}
1980
-
1981
- function useControlArrowhead(params){const{snapStep,disableKeyboardInteraction}=useGraphConfig();const{point,angle,ariaDescribedBy,ariaLabel,constrain=p=>snap(snapStep,p),sequenceNumber=1,onMove=noop$1,onDragEnd=noop$1}=params;const{strings,locale}=usePerseusI18n();const[focused,setFocused]=useState(false);const[hovered,setHovered]=useState(false);const focusableHandleRef=useRef(null);useDraggable({gestureTarget:focusableHandleRef,point,onMove,onDragEnd,constrainKeyboardMovement:constrain});const visibleRef=useRef(null);const arrowheadHitboxRef=useRef(null);const{dragging}=useDraggable({gestureTarget:arrowheadHitboxRef,point,onMove,onDragEnd,constrainKeyboardMovement:constrain});const hitbox=useHitbox({shape:{kind:"box",center:point,sizePx:HANDLE_HITBOX_SIZE_PX},hitboxRef:arrowheadHitboxRef,dragging,onClick:()=>focusableHandleRef.current?.focus(),onHoverChange:setHovered,testId:"movable-arrowhead__hitbox"});const pointAriaLabel=ariaLabel||strings.srPointAtCoordinates({pointLabel:`${sequenceNumber}`,x:srFormatNumber(point[X],locale),y:srFormatNumber(point[Y],locale)});useLayoutEffect(()=>{if(dragging&&!focused){focusableHandleRef.current?.focus();}},[dragging,focused]);const focusableHandle=jsxRuntimeExports.jsx("g",{"data-testid":"movable-arrowhead__focusable-handle",className:"movable-point__focusable-handle",tabIndex:disableKeyboardInteraction?-1:0,ref:focusableHandleRef,role:"button","aria-describedby":ariaDescribedBy,"aria-label":pointAriaLabel,"aria-disabled":disableKeyboardInteraction,onFocus:()=>setFocused(true),onBlur:()=>setFocused(false)});const visibleArrowhead=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[hitbox,jsxRuntimeExports.jsx(MovableArrowheadView,{point:point,angle:angle,dragging:dragging,focused:focused,hovered:hovered,ref:visibleRef,showFocusRing:focused,onClick:()=>{focusableHandleRef.current?.focus();}})]});return {focusableHandle,visibleArrowhead,dragging,focused}}const noop$1=()=>{};
1982
-
1983
- const{calculateAngleInDegrees: calculateAngleInDegrees$1}=angles;const LINE_PULLBACK_PX=4;function renderVectorGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(VectorGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeVectorGraph(state,i18n).srVectorInteractiveElement}}const VectorGraph=props=>{const{dispatch}=props;const{coords}=props.graphState;const[tail,tip]=coords;const{strings,locale}=usePerseusI18n();const{markings}=useGraphConfig();const id=React.useId();const pointsDescriptionId=id+"-points";const{srVectorGraph,srVectorDescription,srVectorHeadPoint,srVectorGrabHandle}=describeVectorGraph(props.graphState,{strings,locale});const tipArrowhead=useTipArrowhead({tail,tip,ariaLabel:srVectorHeadPoint,ariaDescribedBy:pointsDescriptionId,onMove:destination=>dispatch(actions.vector.moveTip(destination))});const showHairlines=(tipArrowhead.dragging||tipArrowhead.focused)&&markings!=="none";return jsxRuntimeExports.jsxs("g",{"aria-label":srVectorGraph,"aria-describedby":pointsDescriptionId,children:[showHairlines&&jsxRuntimeExports.jsx(Hairlines,{point:tip}),jsxRuntimeExports.jsx(VectorBody,{tail:tail,tip:tip,ariaLabel:srVectorGrabHandle,ariaDescribedBy:pointsDescriptionId,onMove:newStart=>dispatch(actions.vector.moveVector(newStart))}),tipArrowhead.focusableHandle,tipArrowhead.visibleArrowhead,jsxRuntimeExports.jsx(SRDescInSVG,{id:pointsDescriptionId,children:srVectorDescription})]})};const VectorBody=props=>{const{tail,tip,ariaLabel,ariaDescribedBy,onMove}=props;const{snapStep,disableKeyboardInteraction,interactiveColor}=useGraphConfig();const[hovered,setHovered]=useState(false);const[focused,setFocused]=useState(false);const[tailPx,tipPx]=useTransformVectorsToPixels(tail,tip);const bodyRef=useRef(null);const vectorHitboxRef=useRef(null);useDraggable({gestureTarget:bodyRef,point:tail,onMove,constrainKeyboardMovement:p=>snap(snapStep,p)});const{dragging}=useDraggable({gestureTarget:vectorHitboxRef,point:tail,onMove,onDragEnd:()=>{bodyRef.current?.blur();},constrainKeyboardMovement:p=>snap(snapStep,p)});const vectorHitbox=useHitbox({shape:{kind:"line",start:tail,end:tip,thicknessPx:TARGET_SIZE},hitboxRef:vectorHitboxRef,layer:"body",dragging,onHoverChange:setHovered,testId:"movable-vector__hitbox"});const direction=vec.sub(tipPx,tailPx);const dirMag=vec.mag(direction);const angleDeg=calculateAngleInDegrees$1(direction);const lineEndPx=dirMag>0?[tipPx[X]-direction[X]/dirMag*LINE_PULLBACK_PX,tipPx[Y]-direction[Y]/dirMag*LINE_PULLBACK_PX]:tipPx;const handleT=1/2;const handlePx=[tailPx[X]+(tipPx[X]-tailPx[X])*handleT,tailPx[Y]+(tipPx[Y]-tailPx[Y])*handleT];const active=hovered||dragging||focused;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[vectorHitbox,jsxRuntimeExports.jsxs("g",{ref:bodyRef,tabIndex:disableKeyboardInteraction?-1:0,"aria-label":ariaLabel,"aria-describedby":ariaDescribedBy,"aria-disabled":disableKeyboardInteraction,className:hovered?"movable-line movable-line--hover":"movable-line","data-testid":"movable-vector",style:{cursor:dragging?"grabbing":"grab"},role:"button",onFocus:()=>setFocused(true),onBlur:()=>setFocused(false),children:[jsxRuntimeExports.jsx(SVGLine,{start:tailPx,end:lineEndPx,className:`movable-vector-line ${active?"movable-dragging":""}`,style:{stroke:interactiveColor,strokeWidth:sizing.size_020},testId:"movable-vector__line"}),active&&jsxRuntimeExports.jsx(MovablePillHandle,{center:handlePx,rotation:angleDeg,active:active,focused:focused})]})]})};function useTipArrowhead(params){const{tail,tip,ariaLabel,ariaDescribedBy,onMove}=params;const{snapStep}=useGraphConfig();const[tailPx,tipPx]=useTransformVectorsToPixels(tail,tip);const direction=vec.sub(tipPx,tailPx);const angleDeg=calculateAngleInDegrees$1(direction);return useControlArrowhead({ariaLabel,ariaDescribedBy,point:tip,angle:angleDeg,sequenceNumber:1,onMove,constrain:getVectorTipKeyboardConstraint(tail,tip,snapStep)})}const getVectorTipKeyboardConstraint=(tail,tip,snapStep)=>{const moveWithConstraint=moveFunc=>{let moved=moveFunc(tip);if(vec.dist(moved,tail)===0){moved=moveFunc(moved);}return moved};return {up:moveWithConstraint(coord=>vec.add(coord,[0,snapStep[Y]])),down:moveWithConstraint(coord=>vec.sub(coord,[0,snapStep[Y]])),left:moveWithConstraint(coord=>vec.sub(coord,[snapStep[X],0])),right:moveWithConstraint(coord=>vec.add(coord,[snapStep[X],0]))}};
1984
-
1985
- const{calculateAngleInDegrees,convertDegreesToRadians}=angles;const protractorImage="https://cdn.kastatic.org/images/perseus/protractor.svg";const centerToTopLeft=[-195,-190];const centerToRotationHandle=[-201,-15];function Protractor(){const staticUrl=getDependencies().staticUrl;const{range,snapStep}=useGraphConfig();const[[xMin,xMax],[yMin,yMax]]=range;const initialCenter=[lerp(xMin,xMax,.5),lerp(yMin,yMax,.25)];const[center,setCenter]=useState(initialCenter);const[rotationHandleOffset,setRotationHandleOffset]=useState(centerToRotationHandle);const draggableRef=useRef(null);const{dragging}=useDraggable({gestureTarget:draggableRef,onMove:point=>setCenter(bound$1({snapStep,range,point})),point:center,constrainKeyboardMovement:point=>bound$1({snapStep,range,point})});const rotationHandleRef=useRef(null);useDraggablePx({gestureTarget:rotationHandleRef,onMove:setRotationHandleOffset,point:rotationHandleOffset,constrain:constrainToCircle});const[centerPx]=useTransformVectorsToPixels(center);const topLeftPx=vec.add(centerPx,centerToTopLeft);const angle=calculateAngleInDegrees(rotationHandleOffset)-calculateAngleInDegrees(centerToRotationHandle);return jsxRuntimeExports.jsxs("g",{ref:draggableRef,transform:`translate(${topLeftPx[X]}, ${topLeftPx[Y]}), rotate(${angle})`,style:{transformOrigin:`${-centerToTopLeft[X]}px ${-centerToTopLeft[Y]}px`,cursor:dragging?"grabbing":"grab"},children:[jsxRuntimeExports.jsx("image",{href:staticUrl(protractorImage)}),jsxRuntimeExports.jsx("g",{transform:`translate(5, ${-centerToTopLeft[1]})`,ref:rotationHandleRef,children:jsxRuntimeExports.jsx(RotationArrow,{})})]})}function RotationArrow(){const radius=175;const angleDeg=10;const angleRad=convertDegreesToRadians(angleDeg);const endX=radius*(1-Math.cos(angleRad));const endY=radius*-Math.sin(angleRad);const rotationArrow=pathBuilder().move(0,0).circularArc(radius,endX,endY,{sweep:true}).build();const arrowhead=pathBuilder().move(-8,0).line(0,10).line(8,0).build();const targetRadius=TARGET_SIZE/2;return jsxRuntimeExports.jsxs("g",{className:"protractor-rotation-handle",children:[jsxRuntimeExports.jsx("path",{className:"protractor-rotation-handle-arrow-arc",d:rotationArrow}),jsxRuntimeExports.jsx("path",{className:"protractor-rotation-handle-arrowhead",d:arrowhead}),jsxRuntimeExports.jsx("path",{className:"protractor-rotation-handle-arrowhead",d:arrowhead,transform:`translate(${endX}, ${endY}), rotate(${180+angleDeg})`}),jsxRuntimeExports.jsx("ellipse",{cx:"0px",cy:"-15px",rx:targetRadius,ry:targetRadius,fill:"none"})]})}const protractorRadius=vec.mag(centerToRotationHandle);function constrainToCircle(edgePoint){return vec.withMag(edgePoint,protractorRadius)}function useDraggablePx(args){const{gestureTarget:target,onMove,point,constrain=p=>p}=args;const pickupPx=React.useRef([0,0]);useDrag(state=>{const{event,first,movement:pixelMovement}=state;event?.stopPropagation();if(first){pickupPx.current=point;}if(vec.mag(pixelMovement)===0){return}onMove?.(constrain(vec.add(pickupPx.current,pixelMovement)));},{target,eventOptions:{passive:false}});}
1986
-
1987
- function getLockedFigureClipRuns(lockedFigures){const runs=[];for(const figure of lockedFigures){if(figure.type==="label"){continue}const clipped=figure.type!=="point";const lastRun=runs[runs.length-1];if(lastRun?.clipped===clipped){lastRun.figures.push(figure);}else {runs.push({clipped,figures:[figure]});}}return runs}function handleFocusEvent(event,state,dispatch){if(isUnlimitedGraphState(state)){if(event.target.classList.contains("mafs-graph")&&state.interactionMode==="mouse"&&hasFocusVisible(event.target)){dispatch(actions.global.changeKeyboardInvitationVisibility(true));}}}function handleBlurEvent(_event,state,dispatch){if(isUnlimitedGraphState(state)){dispatch(actions.global.changeKeyboardInvitationVisibility(false));}}function handleKeyboardEvent(event,state,dispatch){if(isUnlimitedGraphState(state)){if(event.key==="Backspace"||event.key==="Delete"){if(document.activeElement?.classList.contains("movable-point__focusable-handle")){if(state.type==="point"||state.type==="polygon"&&!state.closedPolygon){dispatch(actions.global.deleteIntent());}}document.activeElement.blur();}else if(event.shiftKey&&event.key==="Enter"){dispatch(actions.global.changeInteractionMode("keyboard"));}else if(state.interactionMode==="keyboard"&&event.key==="a"){dispatch(actions.pointGraph.addPoint([0,0]));}}}function describedByIds(...args){return args.filter(Boolean).join(" ")||undefined}
1988
-
1989
- const GRAPH_LEFT_MARGIN=20;const MafsGraph=props=>{const{state,dispatch,labels,labelLocation,readOnly,fullGraphAriaLabel,fullGraphAriaDescription,widgetId,ungradedDescriptionId,isRequired}=props;const{type}=state;const[width,height]=props.box;const tickStep=props.step;const uniqueId=React.useId();const descriptionId=`interactive-graph-description-${uniqueId}`;const interactiveElementsDescriptionId=`interactive-graph-interactive-elements-description-${uniqueId}`;const unlimitedGraphKeyboardPromptId=`unlimited-graph-keyboard-prompt-${uniqueId}`;const instructionsId=`instructions-${uniqueId}`;const graphRef=React.useRef(null);const[hitboxLayerEl,setHitboxLayerEl]=React.useState(null);const{analytics}=useDependencies();const i18n=usePerseusI18n();const{strings}=i18n;const interactionPrompt=isUnlimitedGraphState(state)&&state.showKeyboardInteractionInvitation;useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:type,widgetType:"interactive-graph",widgetId:widgetId}});});const{graph,interactiveElementsDescription}=renderGraphElements({state,dispatch,i18n,markings:props.markings});const disableInteraction=readOnly||!!props.static;const graphInfo={range:state.range,width,height};const[xAxisLabelLocation,yAxisLabelLocation]=getLabelPosition(graphInfo,labelLocation,tickStep);const needsExtraMargin=labelLocation==="alongEdge"&&yAxisLabelLocation[0]<-14*fontSizeYAxisLabelMultiplier;const marginLabelDiff=GRAPH_LEFT_MARGIN-fontSize*fontSizeYAxisLabelMultiplier;const marginWithExtraOffset=-1*(yAxisLabelLocation[X]-marginLabelDiff);const showsAxisLabels=props.markings==="graph"||props.markings==="axes";const hasXAxisLabel=!!(labels[0]&&labels[0].trim());const graphMarginBottom=getGraphBottomMargin(xAxisLabelLocation[Y],height,hasXAxisLabel,showsAxisLabels);const[[xMin,xMax],[yMin,yMax]]=state.range;const halfStroke=1;const axisClipExpand={left:xMin===0?halfStroke:0,right:xMax===0?halfStroke:0,bottom:yMin===0?halfStroke:0,top:yMax===0?halfStroke:0};const lockedFigureRuns=getLockedFigureClipRuns(props.lockedFigures);return jsxRuntimeExports.jsx(GraphConfigContext.Provider,{value:{range:state.range,snapStep:state.snapStep,markings:props.markings,tickStep:tickStep,gridStep:props.gridStep,showTooltips:!!props.showTooltips,showAxisArrows:props.showAxisArrows,showAxisTicks:props.showAxisTicks,graphDimensionsInPixels:props.box,width,height,labels,labelLocation,disableKeyboardInteraction:disableInteraction,interactiveColor:disableInteraction?"var(--static-gray)":"var(--mafs-blue)"},children:jsxRuntimeExports.jsxs(View,{className:"mafs-graph-container",children:[jsxRuntimeExports.jsxs(View,{className:"mafs-graph",role:"figure",style:{position:"relative",paddingBlockStart:"25px",paddingInlineEnd:"25px",paddingBlockEnd:"0",paddingInlineStart:"0",boxSizing:"content-box",marginInlineStart:needsExtraMargin?`${marginWithExtraOffset}px`:`${GRAPH_LEFT_MARGIN}px`,marginBlockEnd:graphMarginBottom,pointerEvents:props.static?"none":"auto",userSelect:"none",width,height},onKeyUp:event=>{handleKeyboardEvent(event,state,dispatch);},"aria-label":fullGraphAriaLabel,"aria-describedby":describedByIds(ungradedDescriptionId,state.type!=="none"&&!disableInteraction&&instructionsId,fullGraphAriaDescription&&descriptionId,interactiveElementsDescription&&interactiveElementsDescriptionId,isUnlimitedGraphState(state)&&unlimitedGraphKeyboardPromptId),ref:graphRef,tabIndex:0,onFocus:event=>{handleFocusEvent(event,state,dispatch);},onBlur:event=>{handleBlurEvent(event,state,dispatch);},children:[state.type!=="none"&&jsxRuntimeExports.jsxs(View,{id:instructionsId,tabIndex:-1,className:"mafs-sr-only",children:[isUnlimitedGraphState(state)?strings.srUnlimitedGraphInstructions:strings.srGraphInstructions,isRequired&&` ${strings.required}`]}),fullGraphAriaDescription&&jsxRuntimeExports.jsx(View,{id:descriptionId,tabIndex:-1,className:"mafs-sr-only",children:fullGraphAriaDescription}),interactiveElementsDescription&&jsxRuntimeExports.jsx(View,{id:interactiveElementsDescriptionId,tabIndex:-1,className:"mafs-sr-only",children:interactiveElementsDescription}),jsxRuntimeExports.jsx(LegacyGrid,{box:props.box,backgroundImage:props.backgroundImage}),jsxRuntimeExports.jsxs(View,{style:{position:"absolute",bottom:0,left:0},children:[(props.markings==="graph"||props.markings==="axes")&&jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:jsxRuntimeExports.jsx(AxisLabels,{i18n:i18n,xAxisLabelLocation:xAxisLabelLocation,yAxisLabelLocation:yAxisLabelLocation})}),jsxRuntimeExports.jsx(View,{"aria-hidden":props.lockedFigures.length===0,children:jsxRuntimeExports.jsxs(Mafs,{preserveAspectRatio:false,viewBox:{x:state.range[X],y:state.range[Y],padding:0},pan:false,zoom:false,width:width,height:height,children:[jsxRuntimeExports.jsx(SvgDefs,{}),jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(Grid,{gridStep:props.gridStep,range:state.range,containerSizeClass:props.containerSizeClass,markings:props.markings,width:width,height:height})}),jsxRuntimeExports.jsx(GraphBorder,{range:state.range,width:width,height:height,markings:props.markings}),showsAxisLabels&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ClipToGraphBounds,{expand:axisClipExpand,children:jsxRuntimeExports.jsx(Axes,{gridStep:props.gridStep,range:state.range,containerSizeClass:props.containerSizeClass,markings:props.markings,width:width,height:height})}),jsxRuntimeExports.jsx(AxisTicks,{}),jsxRuntimeExports.jsx(AxisArrows,{})]}),lockedFigureRuns.map((run,index)=>run.clipped?jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(GraphLockedLayer,{lockedFigures:run.figures,range:state.range})},`locked-figure-run-${index}`):jsxRuntimeExports.jsx(GraphLockedLayer,{lockedFigures:run.figures,range:state.range},`locked-figure-run-${index}`))]})}),jsxRuntimeExports.jsx(GraphLockedLabelsLayer,{lockedFigures:props.lockedFigures}),!props.static&&jsxRuntimeExports.jsx(MovablePointLabelsLayer,{state:state}),jsxRuntimeExports.jsxs(HitboxLayerContext.Provider,{value:hitboxLayerEl,children:[jsxRuntimeExports.jsx(View,{style:{position:"absolute"},children:jsxRuntimeExports.jsxs(Mafs,{preserveAspectRatio:false,viewBox:{x:state.range[X],y:state.range[Y],padding:0},pan:false,zoom:false,width:width,height:height,children:[props.showProtractor&&jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(Protractor,{})}),graph]})}),jsxRuntimeExports.jsx("div",{ref:setHitboxLayerEl,className:"interactive-graph-hitbox-layer",style:{position:"absolute",top:0,left:0,width,height,pointerEvents:"none"}})]})]}),interactionPrompt&&jsxRuntimeExports.jsx(View,{style:{display:interactionPrompt?undefined:"hidden",textAlign:"center",backgroundColor:semanticColor.core.background.base.default,border:`1px solid ${semanticColor.core.border.neutral.subtle}`,paddingBlock:"16px",paddingInline:"0",boxShadow:boxShadow.mid,insetBlockStart:"50%",transform:"translateY(-50%)"},children:jsxRuntimeExports.jsx(BodyText,{id:unlimitedGraphKeyboardPromptId,children:strings.graphKeyboardPrompt})})]}),renderGraphControls({state,dispatch,width,perseusStrings:strings})]})})};const renderPointGraphControls=props=>{const{interactionMode,showRemovePointButton,focusedPointIndex}=props.state;const{perseusStrings}=props;const shouldShowRemoveButton=showRemovePointButton&&focusedPointIndex!==null;return jsxRuntimeExports.jsxs(View,{style:{flexDirection:"row",width:props.width},children:[interactionMode==="keyboard"&&jsxRuntimeExports.jsx(Button,{kind:"secondary",style:{width:"100%",marginInlineStart:"20px"},tabIndex:0,onClick:()=>{props.dispatch(actions.pointGraph.addPoint([0,0]));},children:perseusStrings.addPoint}),interactionMode==="mouse"&&jsxRuntimeExports.jsx(Button,{id:REMOVE_BUTTON_ID,kind:"secondary",actionType:"destructive",tabIndex:-1,style:{width:"100%",marginInlineStart:"20px",visibility:shouldShowRemoveButton?"visible":"hidden"},onClick:_event=>{props.dispatch(actions.pointGraph.removePoint(props.state.focusedPointIndex));},children:perseusStrings.removePoint})]})};const renderPolygonGraphControls=props=>{const{interactionMode,showRemovePointButton,focusedPointIndex,closedPolygon,coords}=props.state;const{perseusStrings}=props;const shouldShowRemoveButton=showRemovePointButton&&focusedPointIndex!==null;const disableCloseButton=getArrayWithoutDuplicates(coords).length<3;const polygonButton=closedPolygon?jsxRuntimeExports.jsx(Button,{kind:"secondary",style:{width:"100%",marginInlineStart:"20px"},tabIndex:0,onClick:()=>{props.dispatch(actions.polygon.openPolygon());},children:perseusStrings.openPolygon}):jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:disableCloseButton,style:{width:"100%",marginInlineStart:"20px"},tabIndex:disableCloseButton?-1:0,onClick:()=>{props.dispatch(actions.polygon.closePolygon());},children:perseusStrings.closePolygon});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:jsxRuntimeExports.jsxs(View,{style:{flexDirection:"row",width:props.width},children:[interactionMode==="keyboard"&&jsxRuntimeExports.jsx(Button,{kind:"secondary",style:{width:"100%",marginInlineStart:"20px"},disabled:closedPolygon,tabIndex:closedPolygon?-1:0,onClick:()=>{props.dispatch(actions.polygon.addPoint([0,0]));},children:perseusStrings.addPoint}),interactionMode==="mouse"&&jsxRuntimeExports.jsx(Button,{id:REMOVE_BUTTON_ID,kind:"secondary",actionType:"destructive",disabled:closedPolygon||!shouldShowRemoveButton,tabIndex:-1,style:{width:"100%",marginInlineStart:"20px"},onClick:_event=>{props.dispatch(actions.polygon.removePoint(props.state.focusedPointIndex));},children:perseusStrings.removePoint}),polygonButton]})})};const renderGraphControls=props=>{const{state,dispatch,width,perseusStrings}=props;const{type}=state;switch(type){case "point":if(state.numPoints==="unlimited"){return renderPointGraphControls({state,dispatch,width,perseusStrings})}return null;case "polygon":if(state.numSides==="unlimited"){return renderPolygonGraphControls({state,dispatch,width,perseusStrings})}return null;default:return null}};const renderGraphElements=props=>{const{state,dispatch,i18n,markings}=props;const{type}=state;switch(type){case "angle":return renderAngleGraph(state,dispatch,i18n);case "segment":return renderSegmentGraph(state,dispatch,i18n);case "linear-system":return renderLinearSystemGraph(state,dispatch,i18n);case "linear":return renderLinearGraph(state,dispatch,i18n);case "ray":return renderRayGraph(state,dispatch,i18n);case "polygon":return renderPolygonGraph(state,dispatch,i18n,markings);case "point":return renderPointGraph(state,dispatch,i18n);case "circle":return renderCircleGraph(state,dispatch,i18n);case "quadratic":return renderQuadraticGraph(state,dispatch,i18n);case "sinusoid":return renderSinusoidGraph(state,dispatch,i18n);case "exponential":return renderExponentialGraph(state,dispatch,i18n);case "none":return {graph:null,interactiveElementsDescription:null};case "absolute-value":return renderAbsoluteValueGraph(state,dispatch,i18n);case "tangent":return renderTangentGraph(state,dispatch,i18n);case "logarithm":return renderLogarithmGraph(state,dispatch,i18n);case "vector":return renderVectorGraph(state,dispatch,i18n);default:throw new UnreachableCaseError(type)}};
1990
-
1991
- function mafsStateToInteractiveGraph(state,originalGraph){switch(state.type){case "angle":invariant(originalGraph.type==="angle");return {...originalGraph,coords:state.coords};case "quadratic":invariant(originalGraph.type==="quadratic");return {...originalGraph,coords:state.coords};case "circle":invariant(originalGraph.type==="circle");return {...originalGraph,center:state.center,radius:getRadius(state)};case "linear":invariant(originalGraph.type==="linear");return {...originalGraph,coords:state.coords};case "ray":invariant(originalGraph.type==="ray");return {...originalGraph,coords:state.coords};case "sinusoid":invariant(originalGraph.type==="sinusoid");return {...originalGraph,coords:state.coords};case "segment":invariant(originalGraph.type==="segment");return {...originalGraph,coords:state.coords};case "linear-system":invariant(originalGraph.type==="linear-system");return {...originalGraph,coords:state.coords};case "polygon":invariant(originalGraph.type==="polygon");return {...originalGraph,coords:state.coords};case "point":invariant(originalGraph.type==="point");return {...originalGraph,coords:state.coords};case "exponential":invariant(originalGraph.type==="exponential");return {...originalGraph,coords:state.coords,asymptote:state.asymptote};case "none":invariant(originalGraph.type==="none");return {...originalGraph};case "absolute-value":invariant(originalGraph.type==="absolute-value");return {...originalGraph,coords:state.coords};case "tangent":invariant(originalGraph.type==="tangent");return {...originalGraph,coords:state.coords};case "logarithm":invariant(originalGraph.type==="logarithm");return {...originalGraph,coords:state.coords,asymptote:state.asymptote};case "vector":invariant(originalGraph.type==="vector");return {...originalGraph,coords:state.coords};default:throw new UnreachableCaseError(state)}}
1992
-
1993
- function useReinitializeOnGraphChange(props,dispatch){const{graph}=props;const numSegments=graph.type==="segment"?graph.numSegments:null;const numPoints=graph.type==="point"?graph.numPoints:null;const numSides=graph.type==="polygon"?graph.numSides:null;const snapTo=graph.type==="polygon"?graph.snapTo:null;const showAngles=graph.type==="polygon"||graph.type==="angle"?graph.showAngles:null;const allowReflexAngles=graph.type==="angle"?graph.allowReflexAngles:null;const showSides=graph.type==="polygon"?graph.showSides:null;const startCoords="startCoords"in graph?graph.startCoords:undefined;const pointLabels="pointLabels"in graph?graph.pointLabels:undefined;const showPointLabels="showPointLabels"in graph?graph.showPointLabels:undefined;const pointLabelsKey=pointLabels&&JSON.stringify(pointLabels);const startCoordsKey=startCoords&&JSON.stringify(startCoords);const originalPropsRef=useRef(props);const latestPropsRef=useLatestRef(props);useEffect(()=>{if(latestPropsRef.current!==originalPropsRef.current){dispatch(reinitialize(latestPropsRef.current));}},[dispatch,graph.type,numPoints,numSegments,numSides,snapTo,showAngles,showSides,latestPropsRef,startCoordsKey,allowReflexAngles,pointLabelsKey,showPointLabels]);}
1994
-
1995
- const StatefulMafsGraph=React.forwardRef(function StatefulMafsGraphWithRef(props,ref){const{onChange,graph}=props;const{strings,locale}=usePerseusI18n();const[state,dispatch]=React.useReducer(interactiveGraphReducer,props,initializeGraphState);useImperativeHandle(ref,()=>({getUserInput:()=>getGradableGraph(state,graph)}));const prevState=useRef(state);useEffect(()=>{if(prevState.current!==state){onChange(mafsStateToInteractiveGraph(state,graph));}prevState.current=state;},[onChange,state,graph]);useEffect(()=>{if(!state.stateAnnouncement){return}announceMessage({message:getAnnouncementText(state.stateAnnouncement,strings,locale)});},[state.stateAnnouncement,strings,locale]);const[xSnap,ySnap]=props.snapStep;useEffect(()=>{dispatch(changeSnapStep([xSnap,ySnap]));},[dispatch,xSnap,ySnap]);const[[xMinRange,xMaxRange],[yMinRange,yMaxRange]]=props.range;useEffect(()=>{dispatch(changeRange([[xMinRange,xMaxRange],[yMinRange,yMaxRange]]));},[dispatch,xMinRange,xMaxRange,yMinRange,yMaxRange]);useReinitializeOnGraphChange(props,dispatch);if(props.static&&props.correct&&props.graded!==false){return jsxRuntimeExports.jsx(MafsGraph,{...props,state:initializeGraphState({...props,graph:props.correct}),dispatch:dispatch})}return jsxRuntimeExports.jsx(MafsGraph,{...props,state:state,dispatch:dispatch})});
1996
-
1997
- class InteractiveGraph extends React.Component{static getEquationString(props){return getEquationString$1(props)}getUserInput(){if(this.mafsRef.current?.getUserInput){return this.mafsRef.current.getUserInput()}throw new PerseusError("Cannot getUserInput from a graph that has never rendered",Errors.NotAllowed)}getPromptJSON(){return getPromptJSON$f(this.props,this.getUserInput())}getSerializedState(){const{userInput,options,...rest}=this.props;return {...options,...rest,graph:userInput}}render(){const options=this.props.options;const box=getInteractiveBoxFromSizeClass(this.props.containerSizeClass);const gridStep=options.gridStep||Util.getGridStep(options.range,options.step,box[0]);const snapStep=options.snapStep||Util.snapStepFromGridStep(gridStep);const mafsProps={...options,static:this.props.static,containerSizeClass:this.props.containerSizeClass,graph:this.props.userInput,onChange:()=>this.props.handleUserInput(this.mafsRef.current?.getUserInput())};const showUngradedText=this.props.graded===false&&options.graph.type!=="none";const ungradedDescriptionId=`interactive-graph-ungraded-description-${this.props.widgetId?.replace(/\s+/g,"-")}`;const isRequired=this.props.isScorable&&this.props.graded!==false&&!this.props.reviewMode&&!this.props.static&&!this.props.apiOptions?.readOnly;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[showUngradedText&&jsxRuntimeExports.jsx("p",{id:ungradedDescriptionId,children:this.context.strings.ungradedInteractiveGraph}),jsxRuntimeExports.jsx(StatefulMafsGraph,{...mafsProps,ref:this.mafsRef,gridStep:gridStep,snapStep:snapStep,box:box,showTooltips:!!options.showTooltips,readOnly:this.props.apiOptions?.readOnly,widgetId:this.props.widgetId,graded:this.props.graded,ungradedDescriptionId:showUngradedText?ungradedDescriptionId:undefined,isRequired:isRequired})]})}constructor(...args){super(...args),this.mafsRef=React.createRef();}}InteractiveGraph.contextType=PerseusI18nContext;function getUserInputFromSerializedState$b(serializedState){return serializedState.graph}function getStartUserInput$b(options){return options.graph}function getCorrectUserInput$5(options){return options.correct}var InteractiveGraph$1 = {name:"interactive-graph",displayName:"Interactive graph",widget:InteractiveGraph,getStartUserInput: getStartUserInput$b,getCorrectUserInput: getCorrectUserInput$5,getUserInputFromSerializedState: getUserInputFromSerializedState$b,supportsUngraded:true};
1998
-
1999
- const paths={linear:"M8 42L42 8",quadratic:"M8 8Q25 72 42 8",sinusoid:"M8 25C11.1 13 13.4 13 16.5 25C19.6 37 21.9 37 25 25C28.1 13 30.4 13 33.5 25C36.6 37 38.9 37 42 25",tangent:"M8 42L8.2 38.6L8.5 35.2L9.1 31.8L10.4 28.4L13.7 25L16.9 21.6L18.3 18.2L18.8 14.8L19.1 11.4L19.3 8M19.3 42L19.5 38.6L19.8 35.2L20.4 31.8L21.7 28.4L25 25L28.3 21.6L29.6 18.2L30.2 14.8L30.5 11.4L30.7 8M30.7 42L30.9 38.6L31.2 35.2L31.7 31.8L33.1 28.4L36.3 25L39.6 21.6L40.9 18.2L41.5 14.8L41.8 11.4L42 8",exponential:"M8 42L10.6 41.8L13.2 41.5L15.8 41.1L18.5 40.5L21.1 39.8L23.7 38.7L26.3 37.3L28.9 35.4L31.5 32.7L34.2 29.1L36.8 24.1L39.4 17.3L42 8",logarithm:"M8 42L10.6 29.7L13.2 24.5L15.8 21.2L18.5 18.7L21.1 16.7L23.7 15.1L26.3 13.7L28.9 12.5L31.5 11.4L34.2 10.4L36.8 9.5L39.4 8.7L42 8",absolute_value:"M10 8L25 42L40 8"};function FunctionTypeIcon({type,label}){return jsxRuntimeExports.jsx("svg",{width:50,height:50,viewBox:"0 0 50 50",role:"img","aria-label":label,focusable:"false",children:jsxRuntimeExports.jsx("path",{d:paths[type],fill:"none",stroke:semanticColor.core.foreground.instructive.default,strokeWidth:3,strokeLinecap:"round",strokeLinejoin:"round"})})}
2000
-
2001
- const movableTypeToComponent={PLOT:Graphie.Plot,PARABOLA:Graphie.Parabola,SINUSOID:Graphie.Sinusoid};const DEFAULT_BACKGROUND_IMAGE={url:null};const getEquationString=plot=>{if(plot.type&&plot.coords){const handler=GrapherUtil.functionForType(plot.type);const result=handler.getEquationString(plot.coords,plot.asymptote);return result||""}return ""};const pointsFromNormalized=(coordsList,range,step,snapStep)=>{const numSteps=function(range,step){return Math.floor((range[1]-range[0])/step)};return coordsList.map(coords=>{const unsnappedPoint=coords.map((coord,i)=>{const currRange=range[i];const currStep=step[i];const nSteps=numSteps(currRange,currStep);const tick=Math.round(coord*nSteps);return currRange[0]+currStep*tick});return point.roundTo(unsnappedPoint,snapStep)})};const maybePointsFromNormalized=(coordsList,range,step,snapStep)=>{if(coordsList){return pointsFromNormalized(coordsList,range,step,snapStep)}return coordsList};const defaultPlotProps=(type,graph)=>{const model=GrapherUtil.functionForType(type);const defaultAsymptote="defaultAsymptote"in model?model.defaultAsymptote:null;const gridStep=[1,1];const snapStep=Util.snapStepFromGridStep(gridStep);return {type,asymptote:maybePointsFromNormalized(defaultAsymptote,graph.range,graph.step,snapStep),coords:null}};const chooseType=_.first;const getGridAndSnapSteps=(options,boxSize)=>{const gridStep=options.gridStep||Util.getGridStep(options.range,options.step,boxSize);const snapStep=options.snapStep||Util.snapStepFromGridStep(gridStep);return {gridStep:gridStep,snapStep:snapStep}};const defaultGraph={labels:["x","y"],range:[[-10,10],[-10,10]],step:[1,1],backgroundImage:DEFAULT_BACKGROUND_IMAGE,markings:"graph",rulerLabel:"",rulerTicks:10,valid:true,showTooltips:false};const defaultPlot=defaultPlotProps("linear",defaultGraph);const DEFAULT_GRAPHER_PROPS={graph:defaultGraph,plot:defaultPlot,availableTypes:[defaultPlot.type]};const typeToButton=type=>{const capitalized=type.charAt(0).toUpperCase()+type.substring(1);return {value:type,title:capitalized,content:jsxRuntimeExports.jsx(FunctionTypeIcon,{type:type,label:capitalized})}};
2002
-
2003
- const MovablePoint$2=Graphie.MovablePoint;const MovableLine$1=Graphie.MovableLine;function isFlipped(newCoord,oldCoord,line){const CCW=(a,b,c)=>{return (b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1])};return CCW(line[0],line[1],oldCoord)>0!==CCW(line[0],line[1],newCoord)>0}const typeSelectorStyle={padding:"5px 5px"};class FunctionGrapher extends React.Component{render(){const pointForCoord=(coord,i)=>{return jsxRuntimeExports.jsx(MovablePoint$2,{coord:coord,static:this.props.static,constraints:[Interactive2.MovablePoint.constraints.bound(),Interactive2.MovablePoint.constraints.snap(),coord=>{const isFunction=this._coords().every((otherCoord,j)=>{return i===j||!otherCoord||!number.equal(coord[0],otherCoord[0])});if(!isFunction){return false}if(this.props.model&&this.props.model.extraCoordConstraint){const extraConstraint=this.props.model.extraCoordConstraint;const proposedCoords=deepClone(this._coords());const oldCoord=deepClone(proposedCoords[i]);proposedCoords[i]=coord;return extraConstraint(coord,oldCoord,proposedCoords,this._asymptote(),this.props.graph)}return isFunction}],onMove:(newCoord,oldCoord)=>{let coords;const asymptote=this._asymptote();if(asymptote&&this.props.model.allowReflectOverAsymptote&&isFlipped(newCoord,oldCoord,asymptote)){coords=this._coords().map(coord=>{return point.reflectOverLine(coord,asymptote)});}else {coords=deepClone(this._coords());}coords[i]=newCoord;this.props.onChange({coords:coords});},showHairlines:this.props.showHairlines,hideHairlines:this.props.hideHairlines,showTooltips:this.props.showTooltips,isMobile:this.props.isMobile},i)};const points=this._coords().map(pointForCoord);const box=this.props.graph.box;const imageDescription=this.props.graph.backgroundImage;let image=null;if(imageDescription.url){const scale=box[0]/interactiveSizes$1.defaultBoxSize;image=jsxRuntimeExports.jsx(SvgImage,{src:imageDescription.url,allowZoom:false,width:imageDescription.width,height:imageDescription.height,scale:scale});}return jsxRuntimeExports.jsx("div",{className:"perseus-widget "+"perseus-widget-grapher",style:{width:box[0],height:box[1],boxSizing:"initial"},children:jsxRuntimeExports.jsxs("div",{className:"graphie-container blank-background",style:{width:box[0],height:box[1]},children:[image,jsxRuntimeExports.jsxs(Graphie,{...this.props.graph,children:[this.props.model&&this.renderPlot(),this.props.model&&this.renderAsymptote(),this.props.model&&points]})]})})}constructor(...args){super(...args),this._coords=()=>{const props=this.props;const graph=props.graph;const defaultModelCoords=props.model&&maybePointsFromNormalized(props.model.defaultCoords,graph.range,graph.step,graph.snapStep);return props.coords||defaultModelCoords||null},this._asymptote=()=>{return this.props.asymptote},this.renderPlot=()=>{const model=this.props.model;const xRange=this.props.graph.range[0];const style={stroke:tokenValue(this.props.static?semanticColor.core.foreground.disabled.strong:semanticColor.core.foreground.instructive.default),...this.props.isMobile?{"stroke-width":3}:{}};const coeffs=model.getCoefficients(this._coords(),this._asymptote());if(!coeffs){return}const functionProps=model.getPropsForCoeffs(coeffs,xRange);const Movable=movableTypeToComponent[model.movable];return createElement(Movable,{...functionProps,key:this.props.model.url,range:xRange,style:style})},this.renderAsymptote=()=>{const model=this.props.model;const graph=this.props.graph;const asymptote=this._asymptote();const showAsymptote=asymptote?.length>0;const dashed={"stroke-dasharray":"- "};return showAsymptote&&jsxRuntimeExports.jsx(MovableLine$1,{static:this.props.static,onMove:(newCoord,oldCoord)=>{const delta=vector$3.subtract(newCoord,oldCoord);const newAsymptote=this._asymptote().map(coord=>vector$3.add(coord,delta));this.props.onChange({asymptote:newAsymptote});},constraints:[Interactive2.MovableLine.constraints.bound(),Interactive2.MovableLine.constraints.snap(),(newCoord,oldCoord)=>{const delta=vector$3.subtract(newCoord,oldCoord);const proposedAsymptote=this._asymptote().map(coord=>vector$3.add(coord,delta));if(model.extraAsymptoteConstraint){return model.extraAsymptoteConstraint(newCoord,oldCoord,this._coords(),proposedAsymptote,graph)}return true}],normalStyle:dashed,highlightStyle:dashed,children:asymptote.map((coord,i)=>jsxRuntimeExports.jsx(MovablePoint$2,{coord:coord,static:true,draw:null,extendLine:true,showHairlines:this.props.showHairlines,hideHairlines:this.props.hideHairlines,showTooltips:this.props.showTooltips,isMobile:this.props.isMobile},`asymptoteCoord-${i}`))})};}}FunctionGrapher.defaultProps={graph:{range:[[-10,10],[-10,10]],step:[1,1]},coords:null,asymptote:null,isMobile:false};class Grapher extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"grapher",widgetSubType:"null",widgetId:this.props.widgetId}});}_getGridConfig(options){return options.step.map((step,i)=>{return Util.gridDimensionConfig(step,options.range[i],options.box[i],options.gridStep[i])})}_calculateMobileTickStep(gridStep,step,ranges){const tickStep=Util.constrainedTickStepsFromTickSteps(step,ranges);tickStep[0]=tickStep[0]/gridStep[0];tickStep[1]=tickStep[1]/gridStep[1];return tickStep}getPromptJSON(){return getPromptJSON$g(this.props)}getSerializedState(){const{alignment,options,userInput}=this.props;return {static:this.props.static,alignment,availableTypes:options.availableTypes,graph:options.graph,plot:userInput}}getAvailableTypes(){const{correct,availableTypes}=this.props.options;if(this.props.static){invariant(correct,"static widgets must have a correct answer");return [correct.type]}return availableTypes}renderLegacyGrapher(){const availableTypes=this.getAvailableTypes();const type=this.props.userInput.type;const coords=this.props.userInput.coords;const asymptote="asymptote"in this.props.userInput?this.props.userInput.asymptote:undefined;const typeSelector=jsxRuntimeExports.jsx("div",{style:typeSelectorStyle,children:jsxRuntimeExports.jsx(ButtonGroup,{value:type,buttons:availableTypes.map(typeToButton),onChange:this.handleActiveTypeChange})});const box=getInteractiveBoxFromSizeClass(this.props.containerSizeClass);const{graph}=this.props.options;const options={...graph,...getGridAndSnapSteps(graph,box[0]),gridConfig:this._getGridConfig({...graph,box:box,...getGridAndSnapSteps(graph,box[0])})};const grapherProps={graph:{box:box,range:options.range,step:options.step,snapStep:options.snapStep,backgroundImage:options.backgroundImage,options:options,setup:this._setupGraphie},onChange:this.handlePlotChanges,model:type&&GrapherUtil.functionForType(type),coords:coords,asymptote:asymptote,static:this.props.static,isMobile:this.props.apiOptions.isMobile,showTooltips:graph.showTooltips,showHairlines:this.showHairlines,hideHairlines:this.hideHairlines};return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(FunctionGrapher,{...grapherProps}),availableTypes.length>1&&typeSelector]})}render(){const{options,...universalProps}=this.props;const interactiveGraphOptions=convertGrapherOptionsToInteractiveGraph(options);if(interactiveGraphOptions==null){return this.renderLegacyGrapher()}const interactiveGraphUserInput=convertGrapherUserInputToInteractiveGraph(this.props.userInput);return jsxRuntimeExports.jsx(InteractiveGraph$1.widget,{...universalProps,options:interactiveGraphOptions,userInput:interactiveGraphUserInput,handleUserInput:interactiveGraphUserInput=>this.props.handleUserInput(convertInteractiveGraphUserInputToGrapher(interactiveGraphUserInput))})}constructor(...args){super(...args),this.handlePlotChanges=newPlot=>{const plot={...this.props.userInput,...newPlot};this.props.handleUserInput(plot);this.props.trackInteraction();},this.handleActiveTypeChange=newType=>{const{graph}=this.props.options;const plot={...this.props.userInput,...defaultPlotProps(newType,graph)};this.props.handleUserInput(plot);},this._setupGraphie=(graphie,options)=>{const isMobile=this.props.apiOptions.isMobile;if(options.markings==="graph"){graphie.graphInit({range:options.range,scale:options.gridConfig.map(e=>e.scale),axisArrows:"<->",labelFormat:function(s){return "\\small{"+s+"}"},gridStep:options.gridStep,snapStep:options.snapStep,tickStep:isMobile?this._calculateMobileTickStep(options.gridStep,options.step,options.range):options.gridConfig.map(e=>e.tickStep),labelStep:1,unityLabels:options.gridConfig.map(e=>e.unityLabel),isMobile:isMobile});graphie.label([0,options.range[1][1]],options.labels[1],isMobile?"below right":"above");graphie.label([options.range[0][1],0],options.labels[0],isMobile?"above left":"right");}else if(options.markings==="grid"){graphie.graphInit({range:options.range,scale:options.gridConfig.map(e=>e.scale),gridStep:options.gridStep,axes:false,ticks:false,labels:false,isMobile:isMobile});}else if(options.markings==="none"){graphie.init({range:options.range,scale:options.gridConfig.map(e=>e.scale)});}const hairlineStyle={normalStyle:{strokeWidth:1}};this.horizHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.horizHairline.attr({stroke:tokenValue(semanticColor.core.border.instructive.default)});this.horizHairline.hide();this.vertHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.vertHairline.attr({stroke:tokenValue(semanticColor.core.border.instructive.default)});this.vertHairline.hide();},this.showHairlines=point=>{const{graph}=this.props.options;this.horizHairline.moveTo([graph.range[0][0],point[1]],[graph.range[0][1],point[1]]);this.horizHairline.show();this.vertHairline.moveTo([point[0],graph.range[1][0]],[point[0],graph.range[1][1]]);this.vertHairline.show();},this.hideHairlines=()=>{this.horizHairline.hide();this.vertHairline.hide();};}}function getUserInputFromSerializedState$a(serializedState){return serializedState.plot}function getStartUserInput$a(options){if(options.availableTypes.length===1){const graph=options.graph;const type=chooseType(options.availableTypes);if(type){return defaultPlotProps(type,graph)}}return DEFAULT_GRAPHER_PROPS.plot}function getCorrectUserInput$4(options){invariant(options.correct,"getCorrectUserInput should only be called for static widgets");return options.correct}const WrappedGrapher=withDependencies(Grapher);var Grapher$1 = {name:"grapher",displayName:"Grapher",hidden:true,widget:WrappedGrapher,getUserInputFromSerializedState: getUserInputFromSerializedState$a,getStartUserInput: getStartUserInput$a,getCorrectUserInput: getCorrectUserInput$4};
2004
-
2005
- const getPromptJSON$e=rendererJSON=>{if(!rendererJSON){return {type:"group",content:"",widgets:{}}}return {...rendererJSON,type:"group"}};
2006
-
2007
- class Group extends React.Component{componentDidMount(){this.forceUpdate();}getPromptJSON(){return getPromptJSON$e(this.rendererRef?.getPromptJSON())}getInputPaths(){return this.rendererRef?.getInputPaths()??[]}focus(){return this.rendererRef?.focus()??false}render(){const apiOptions={...ApiOptions.defaults,...this.props.apiOptions,onFocusChange:(newFocus,oldFocus)=>{if(oldFocus){this.props.onBlur(oldFocus);}if(newFocus){this.props.onFocus(newFocus);}}};return jsxRuntimeExports.jsx("div",{className:classNames$2({"perseus-group":true}),children:jsxRuntimeExports.jsx(Renderer,{userInput:this.props.userInput,handleUserInput:(widgetId,userInput)=>{this.props.handleUserInput({...this.props.userInput,[widgetId]:userInput});},content:this.props.options.content,widgets:this.props.options.widgets,images:this.props.options.images,ref:ref=>this.rendererRef=ref,apiOptions:apiOptions,findExternalWidgets:this.props.findWidgets,reviewMode:this.props.reviewMode,showSolutions:this.props.showSolutions,linterContext:this.props.linterContext,strings:this.context.strings})})}constructor(...args){super(...args),this.getSerializedState=()=>{return this.rendererRef?.getSerializedState()},this.focusInputPath=path=>{this.rendererRef?.focusPath(path);},this.blurInputPath=path=>{this.rendererRef?.blurPath(path);};}}Group.contextType=PerseusI18nContext;function getStartUserInput$9(options,problemNum){return sharedInitializeUserInput(options.widgets,problemNum)}function getUserInputFromSerializedState$9(serializedState,widgetOptions){return deriveUserInputFromSerializedState(serializedState,widgetOptions.widgets)}var Group$1 = {name:"group",displayName:"Group (SAT only)",widget:Group,hidden:true,isLintable:true,getStartUserInput: getStartUserInput$9,getUserInputFromSerializedState: getUserInputFromSerializedState$9};
2008
-
2009
- const getPromptJSON$d=()=>{return getUnsupportedPromptJSON("iframe")};
2010
-
2011
- const{updateQueryString}=Util;const Iframe=forwardRef(function Iframe(props,ref){const{strings,locale}=usePerseusI18n();const{InitialRequestUrl}=getDependencies();const{allowFullScreen}=props.options;useEffect(()=>{function handleMessageEvent(e){let data={};try{data=JSON.parse(e.data);}catch{return}if(data.testsPassed===undefined){return}props.handleUserInput({status:data.testsPassed?"correct":"incorrect",message:data.message});}window.addEventListener("message",handleMessageEvent);return ()=>{window.removeEventListener("message",handleMessageEvent);}},[props]);useImperativeHandle(ref,()=>({getPromptJSON(){return getPromptJSON$d()},getSerializedState(){const{userInput,alignment,options,...rest}=props;const defaults={allowTopNavigation:false};return {...defaults,...options,...rest}}}));const style=getIframeStyle(props.options);const url=getIframeUrl(props.options,locale,InitialRequestUrl.origin);return jsxRuntimeExports.jsx("iframe",{title:strings.embeddedContent,sandbox:"allow-same-origin allow-scripts allow-top-navigation",style:style,src:url,allowFullScreen:allowFullScreen})});function getIframeUrl(options,locale,origin){let url=options.url;if(url&&url.length&&url.indexOf("http")!==0){url="https://www.khanacademy.org/computer-programming/program/"+url+"/embedded?buttons=no&embed=yes&editor=no&author=no";url=updateQueryString(url,"width",`${options.width}`);url=updateQueryString(url,"height",`${options.height}`);url=updateQueryString(url,"origin",origin);}if(locale&&url?.includes("khanacademy.org")){url=updateQueryString(url,"lang",locale);}if(options.settings){const settings={};options.settings.forEach(setting=>{if(setting.name&&setting.value){settings[setting.name]=setting.value;}});url=updateQueryString(url,"settings",JSON.stringify(settings));}return url}function getIframeStyle(options){return {width:toCssSize(String(options.width)),height:toCssSize(String(options.height))}}function toCssSize(value){if(value.endsWith("%")||value.endsWith("px")){return value}return `${value}px`}function getUserInputFromSerializedState$8(serializedState){return {status:serializedState.status,message:serializedState.message}}function getStartUserInput$8(){return {status:"incomplete",message:null}}var Iframe$1 = {name:"iframe",displayName:"Iframe (deprecated)",widget:Iframe,hidden:true,getStartUserInput: getStartUserInput$8,getUserInputFromSerializedState: getUserInputFromSerializedState$8};
2012
-
2013
- const getPromptJSON$c=widgetData=>{return {type:"image",options:{altText:widgetData.options.alt,title:widgetData.options.title,caption:widgetData.options.caption,imageUrl:widgetData.options.backgroundImage.url}}};
2014
-
2015
- var styles$f = {"titleContainer":"perseus_aAJy9Er3","infoAreaContainer":"perseus_a7ZnxMAZ","modalContainer":"perseus_-p2ghr1-","modalTitleContainer":"perseus_YxnjOOa7","modalPanelContainer":"perseus_ryDvI8uD","modalImageContainer":"perseus_yCoMyk8e","modalDescriptionContainer":"perseus_femvuTvR","modalCaptionContainer":"perseus_y4DO7MoR","spacerHorizontal":"perseus_fBhKbquh","spacerVertical":"perseus_9XgZ2QXH"};
2016
-
2017
- function ExploreImageButton({hasCaption,onClick}){const context=React.useContext(PerseusI18nContext);if(!hasCaption){return jsxRuntimeExports.jsx(Button,{"aria-label":context.strings.imageExploreButtonAriaLabel,kind:"secondary",startIcon:infoIconBold,onClick:onClick,children:context.strings.imageExploreButton})}return jsxRuntimeExports.jsx(IconButton,{"aria-label":context.strings.imageExploreButtonAriaLabel,icon:infoIconBold,kind:"secondary",onClick:onClick,style:{flexShrink:0}})}
2018
-
2019
- const GifControlsButton=({isPlaying,onToggle})=>{const strings=usePerseusI18n().strings;return jsxRuntimeExports.jsx(Button,{"aria-label":isPlaying?strings.gifPauseButtonLabel:strings.gifPlayButtonLabel,kind:"secondary",startIcon:isPlaying?pauseIcon:playIcon,onClick:onToggle,style:{width:"fit-content"},children:isPlaying?strings.gifPauseButtonLabel:strings.gifPlayButtonLabel})};
2020
-
2021
- const MODAL_HEIGHT=568;function ExploreImageModalContent({options,linterContext,apiOptions,captionId,longDescId}){const{backgroundImage,scale:contentScale,caption,alt,longDescription,box,labels,range}=options;const[isGifPlaying,setIsGifPlaying]=React.useState(false);const[gifFrames,setGifFrames]=React.useState(null);const[imageIsGif,setImageIsGif]=React.useState(false);const context$1=React.useContext(PerseusI18nContext);React.useEffect(()=>{setIsGifPlaying(false);setGifFrames(null);const url=backgroundImage.url;if(!url||!isGif(url)){setImageIsGif(false);return}setImageIsGif(true);let mounted=true;decodeGifFrames(url).then(frames=>{if(mounted){setGifFrames(frames);}});return ()=>{mounted=false;}},[backgroundImage.url]);if(!backgroundImage.url){return null}const imageIsSvg=isSvg(backgroundImage.url);const isAnimatedGif=imageIsGif&&gifFrames!=null&&gifFrames.length>1;let scale=1;if(backgroundImage.width&&backgroundImage.height){scale=imageIsSvg?Math.max(contentScale,2):Math.max(contentScale,1);}let height=backgroundImage.height;let width=backgroundImage.width;if(backgroundImage.height&&backgroundImage.width){width=backgroundImage.width;height=backgroundImage.height;const maxScale=MODAL_HEIGHT/backgroundImage.height;scale=Math.min(scale,maxScale);}return jsxRuntimeExports.jsxs("div",{className:styles$f.modalPanelContainer,children:[jsxRuntimeExports.jsx("div",{className:styles$f.modalImageContainer,children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:backgroundImage.url,allowZoom:false,alt:caption===alt?"":alt,width:width,height:height,scale:scale,extraGraphie:{box:box,range:range,labels:labels??[]},constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,setAssetStatus:setAssetStatus,isGifPlaying:imageIsGif?isGifPlaying:undefined,onGifLoop:imageIsGif?()=>setIsGifPlaying(false):undefined,gifFrames:imageIsGif?gifFrames??undefined:undefined})})}),jsxRuntimeExports.jsxs("div",{className:`perseus-image-modal-description ${styles$f.modalDescriptionContainer}`,children:[isAnimatedGif&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(GifControlsButton,{isPlaying:isGifPlaying,onToggle:()=>setIsGifPlaying(!isGifPlaying)}),jsxRuntimeExports.jsx("div",{className:styles$f.spacerVertical})]}),caption&&jsxRuntimeExports.jsx("div",{id:captionId,className:styles$f.modalCaptionContainer,children:jsxRuntimeExports.jsx(Renderer,{content:caption,apiOptions:apiOptions,linterContext:linterContext,strings:context$1.strings})}),jsxRuntimeExports.jsx(Heading,{size:"large",tag:"h2",style:wbStyles$1.descriptionHeading,children:context$1.strings.imageDescriptionLabel}),jsxRuntimeExports.jsx("div",{id:longDescId,children:jsxRuntimeExports.jsx(Renderer,{content:longDescription,apiOptions:apiOptions,linterContext:linterContext,strings:context$1.strings})})]})]})}const wbStyles$1={descriptionHeading:{marginBlockEnd:sizing.size_160}};
2022
-
2023
- const ExploreImageModal=props=>{const context=React__default.useContext(PerseusI18nContext);const uniqueId=React__default.useId();const captionId=`${uniqueId}-caption`;const longDescId=`${uniqueId}-long-desc`;const{analytics}=useDependencies();React__default.useEffect(()=>{const openedAt=Date.now();return ()=>{analytics.onAnalyticsEvent({type:"perseus:image:explore-modal-closed:ti",payload:{widgetSubType:"null",widgetId:props.widgetId,durationMs:Date.now()-openedAt}});}},[]);const titleText=props.options.title||context.strings.imageAlternativeTitle;const title=jsxRuntimeExports.jsx("h1",{className:`perseus-image-modal-title ${styles$f.modalTitleContainer}`,children:jsxRuntimeExports.jsx(Renderer,{content:titleText,apiOptions:props.apiOptions,linterContext:props.linterContext,strings:context.strings})});return jsxRuntimeExports.jsx("div",{className:`framework-perseus ${styles$f.modalContainer}`,children:jsxRuntimeExports.jsx(FlexibleDialog,{title:title,content:jsxRuntimeExports.jsx(ExploreImageModalContent,{...props,captionId:captionId,longDescId:longDescId}),"aria-describedby":props.options.caption?`${captionId} ${longDescId}`:longDescId,styles:{root:wbStyles.root}})})};const wbStyles={root:{borderRadius:sizing.size_120,maxWidth:"100%"}};
2024
-
2025
- const GifControlsIcon=({isPlaying,onToggle})=>{const strings=usePerseusI18n().strings;return jsxRuntimeExports.jsx(IconButton,{icon:isPlaying?pauseIcon:playIcon,kind:"secondary","aria-label":isPlaying?strings.gifPauseButtonLabel:strings.gifPlayButtonLabel,onClick:onToggle,style:{flexShrink:0}})};
2026
-
2027
- const ImageInfoArea=props=>{const{options,apiOptions,linterContext,isGifPlaying,setIsGifPlaying,isAnimatedGif,widgetId}=props;const{backgroundImage,caption,longDescription}=options;const context=React.useContext(PerseusI18nContext);const{analytics}=useDependencies();if(!backgroundImage.url){return null}return jsxRuntimeExports.jsxs("div",{className:styles$f.infoAreaContainer,children:[isAnimatedGif&&jsxRuntimeExports.jsx(GifControlsIcon,{isPlaying:isGifPlaying,onToggle:()=>setIsGifPlaying(!isGifPlaying)}),isAnimatedGif&&longDescription&&jsxRuntimeExports.jsx("div",{className:styles$f.spacerHorizontal}),longDescription&&jsxRuntimeExports.jsx(ModalLauncher,{modal:jsxRuntimeExports.jsx(ExploreImageModal,{...props}),children:({openModal})=>jsxRuntimeExports.jsx(ExploreImageButton,{hasCaption:!!caption,onClick:()=>{analytics.onAnalyticsEvent({type:"perseus:image:explore-modal-opened:ti",payload:{widgetSubType:"null",widgetId}});openModal();}})}),caption&&jsxRuntimeExports.jsx("figcaption",{className:"perseus-image-caption",children:jsxRuntimeExports.jsx(Renderer,{content:caption,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})})]})};
2028
-
2029
- const ImageWidget=forwardRef(function ImageWidget(props,ref){const{apiOptions,linterContext,trackInteraction,widgetId}=props;const{alt,backgroundImage,box,caption,longDescription,decorative,labels,range,title}=props.options;const context$1=React__default.useContext(PerseusI18nContext);const{analytics}=useDependencies();const[isGifPlaying,setIsGifPlaying]=React__default.useState(false);const[gifFrames,setGifFrames]=React__default.useState(null);const[imageIsGif,setImageGif]=React__default.useState(false);useImperativeHandle(ref,()=>({getPromptJSON:()=>getPromptJSON$c(props)}));useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"image",widgetId:widgetId}});});React__default.useEffect(()=>{setIsGifPlaying(false);setGifFrames(null);const url=backgroundImage.url;if(!url||!isGif(url)){setImageGif(false);return}setImageGif(true);let mounted=true;decodeGifFrames(url).then(frames=>{if(mounted){setGifFrames(frames);}});return ()=>{mounted=false;}},[backgroundImage.url]);if(!backgroundImage.url){return null}const isAnimatedGif=imageIsGif&&gifFrames!=null&&gifFrames.length>1;let scale=props.options.scale;if(scale<=0||scale===Infinity||scale===-Infinity){scale=1;}const svgImage=jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:backgroundImage.url,apiOptions:apiOptions,width:backgroundImage.width,height:backgroundImage.height,scale:scale,extraGraphie:{box:box,range:range,labels:labels},trackInteraction:trackInteraction,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,allowZoom:!decorative&&!imageIsGif,alt:decorative||caption===alt?"":alt,setAssetStatus:setAssetStatus,isGifPlaying:imageIsGif?isGifPlaying:undefined,onGifLoop:imageIsGif?()=>setIsGifPlaying(false):undefined,gifFrames:imageIsGif?gifFrames??undefined:undefined})});const maxWidth=backgroundImage.width?backgroundImage.width*scale:undefined;const width=maxWidth?undefined:"fit-content";if(decorative){return jsxRuntimeExports.jsx("figure",{className:"perseus-image-widget",style:{maxInlineSize:maxWidth,width:width},children:svgImage})}return jsxRuntimeExports.jsxs("figure",{className:"perseus-image-widget",style:{maxInlineSize:maxWidth,width:width},children:[title&&jsxRuntimeExports.jsx("div",{className:`perseus-image-title ${styles$f.titleContainer}`,children:jsxRuntimeExports.jsx(Renderer,{content:title,apiOptions:apiOptions,linterContext:linterContext,strings:context$1.strings})}),svgImage,(isAnimatedGif||caption||longDescription)&&jsxRuntimeExports.jsx(ImageInfoArea,{isGifPlaying:isGifPlaying,setIsGifPlaying:setIsGifPlaying,isAnimatedGif:isAnimatedGif,options:props.options,apiOptions:apiOptions,linterContext:linterContext,widgetId:widgetId})]})});var Image$1 = {name:"image",displayName:"Image",widget:ImageWidget,isLintable:true};
2030
-
2031
- const getPromptJSON$b=()=>{return getUnsupportedPromptJSON("interaction")};
2032
-
2033
- const Label=Graphie.Label;const Line$1=Graphie.Line;const MovablePoint$1=Graphie.MovablePoint;const MovableLine=Graphie.MovableLine;const Plot=Graphie.Plot;const PlotParametric=Graphie.PlotParametric;const Point=Graphie.Point;const Rect=Graphie.Rect;const{unescapeMathMode}=Util;function KAShashFunc(expr,options){let result=expr+"||";const functions=options?.functions;const functionsLength=functions?functions.length:0;for(let i=0;i<functionsLength;i++){result+=functions[i]+"|";}return result}const _parseCache=Object.create(null);function KASparse(expr){const hash=KAShashFunc(expr);let cached=_parseCache[hash];if(cached){return cached}cached=KAS.parse(expr);_parseCache[hash]=cached;return cached}const _compileCache=Object.create(null);function KAScompile(expr,options){const hash=KAShashFunc(expr,options);let cached=_compileCache[hash];if(cached){return cached}const parsed=KAS.parse(expr,options).expr;cached=parsed?parsed.compile():function(){return 0};_compileCache[hash]=cached;return cached}class Interaction extends React.Component{UNSAFE_componentWillReceiveProps(nextProps){if(!_.isEqual(this.props.options.elements,nextProps.options.elements)){this.setState({variables:_getInitialVariables(nextProps.options.elements),functions:_getInitialFunctions(nextProps.options.elements)});}}getPromptJSON(){return getPromptJSON$b()}render(){const range=this.props.options.graph.range;let labels=this.props.options.graph.labels;if(this.props.options.graph.markings==="graph"){labels=this.props.options.graph.labels.map(label=>label.startsWith("$")&&label.endsWith("$")?label.slice(1,-1):label);}return jsxRuntimeExports.jsxs(Graphie,{box:this.props.options.graph.box,range:this.props.options.graph.range,options:this.props.options.graph,setup:this._setupGraphie,children:[this.props.options.graph.markings==="graph"&&jsxRuntimeExports.jsx(Label,{coord:[0,range[1][1]],text:labels[1],direction:"above"}),this.props.options.graph.markings==="graph"&&jsxRuntimeExports.jsx(Label,{coord:[range[0][1],0],text:labels[0],direction:"right"}),this.props.options.elements.map((element,n)=>{if(element.type==="point"){return jsxRuntimeExports.jsx(Point,{coord:[this._eval(element.options.coordX),this._eval(element.options.coordY)],color:element.options.color},element.key)}if(element.type==="line"){const start=[this._eval(element.options.startX),this._eval(element.options.startY)];const end=[this._eval(element.options.endX),this._eval(element.options.endY)];return jsxRuntimeExports.jsx(Line$1,{start:start,end:end,style:{stroke:element.options.color,strokeWidth:element.options.strokeWidth,strokeDasharray:element.options.strokeDasharray,arrows:element.options.arrows}},element.key)}if(element.type==="movable-point"){const constraints=[coord=>{const coordX=Math.max(this._eval(element.options.constraintXMin),Math.min(this._eval(element.options.constraintXMax),coord[0]));const coordY=Math.max(this._eval(element.options.constraintYMin),Math.min(this._eval(element.options.constraintYMax),coord[1]));return [coordX,coordY]}];if(element.options.constraint==="snap"){constraints.push(MovablePoint$1.constraints.snap(element.options.snap));}else if(element.options.constraint==="x"){constraints.push(coord=>{return [this._eval(element.options.constraintFn,{y:coord[1]}),coord[1]]});}else if(element.options.constraint==="y"){constraints.push(coord=>{return [coord[0],this._eval(element.options.constraintFn,{x:coord[0]})]});}return jsxRuntimeExports.jsx(MovablePoint$1,{coord:[this.state.variables["x_"+element.options.varSubscript],this.state.variables["y_"+element.options.varSubscript]],constraints:constraints,foo_x:element.options.constraint,foo_y:element.options.constraintFn,foo_z:element.options.snap,onMove:_.partial(this._updatePointLocation,element.options.varSubscript)},element.key)}if(element.type==="movable-line"){const constraints=[coord=>{const coordX=Math.max(this._eval(element.options.constraintXMin),Math.min(this._eval(element.options.constraintXMax),coord[0]));const coordY=Math.max(this._eval(element.options.constraintYMin),Math.min(this._eval(element.options.constraintYMax),coord[1]));return [coordX,coordY]}];if(element.options.constraint==="snap"){constraints.push(MovablePoint$1.constraints.snap(element.options.snap));}else if(element.options.constraint==="x"){constraints.push(coord=>{return [this._eval(element.options.constraintFn,{y:coord[1]}),coord[1]]});}else if(element.options.constraint==="y"){constraints.push(coord=>{return [coord[0],this._eval(element.options.constraintFn,{x:coord[0]})]});}const start=[this.state.variables["x_"+element.options.startSubscript],this.state.variables["y_"+element.options.startSubscript]];const end=[this.state.variables["x_"+element.options.endSubscript],this.state.variables["y_"+element.options.endSubscript]];return jsxRuntimeExports.jsxs(MovableLine,{constraints:constraints,onMove:this._updateLineLocation.bind(this,element.options),foo_x:element.options.constraint,foo_y:element.options.constraintFn,foo_z:element.options.snap,children:[jsxRuntimeExports.jsx(MovablePoint$1,{coord:start,static:true,normalStyle:{stroke:"none",fill:"none"}}),jsxRuntimeExports.jsx(MovablePoint$1,{coord:end,static:true,normalStyle:{stroke:"none",fill:"none"}})]},element.key)}if(element.type==="function"){const fn=x=>{return this._eval(element.options.value,{x:x})};const vars=this._extractVars(KASparse(element.options.value).expr).filter(v=>v!=="x");const varValues=Object.fromEntries(vars.map(v=>[v,this.state.variables[v]]));const range=[this._eval(element.options.rangeMin,this.state.variables),this._eval(element.options.rangeMax,this.state.variables)];return jsxRuntimeExports.jsx(Plot,{fn:fn,foo_fn:element.options.value,foo_varvalues:varValues,range:range,style:{stroke:element.options.color,strokeWidth:element.options.strokeWidth,strokeDasharray:element.options.strokeDasharray,plotPoints:100}},element.key)}if(element.type==="parametric"){const fn=t=>{return [this._eval(element.options.x,{t:t}),this._eval(element.options.y,{t:t})]};const vars=this._extractVars(KASparse(element.options.x).expr).concat(this._extractVars(KASparse(element.options.y).expr)).filter(v=>v!=="t");const varValues=Object.fromEntries(vars.map(v=>[v,this.state.variables[v]]));const range=[this._eval(element.options.rangeMin,this.state.variables),this._eval(element.options.rangeMax,this.state.variables)];return jsxRuntimeExports.jsx(PlotParametric,{fn:fn,foo_fnx:element.options.x,foo_fny:element.options.y,foo_varvalues:varValues,range:range,style:{stroke:element.options.color,strokeWidth:element.options.strokeWidth,strokeDasharray:element.options.strokeDasharray,plotPoints:100}},element.key)}if(element.type==="label"){const coord=[this._eval(element.options.coordX),this._eval(element.options.coordY)];return jsxRuntimeExports.jsx(Label,{coord:coord,text:unescapeMathMode(element.options.label),style:{color:element.options.color}},n+1)}if(element.type==="rectangle"){return jsxRuntimeExports.jsx(Rect,{x:this._eval(element.options.coordX),y:this._eval(element.options.coordY),width:Math.max(this._eval(element.options.width),0),height:Math.max(this._eval(element.options.height),0),style:{stroke:"none",fill:element.options.color}},n+1)}})]})}constructor(...args){super(...args),this.isWidget=true,this.state={variables:_getInitialVariables(this.props.options.elements),functions:_getInitialFunctions(this.props.options.elements)},this._setupGraphie=(graphie,options)=>{graphie.graphInit({...options,grid:["graph","grid"].includes(this.props.options.graph.markings),axes:["graph"].includes(this.props.options.graph.markings),ticks:["graph"].includes(this.props.options.graph.markings),labels:["graph"].includes(this.props.options.graph.markings),labelFormat:function(s){return "\\small{"+s+"}"},axisArrows:"<->",unityLabels:false});},this._updatePointLocation=(subscript,coord)=>{const variables={...this.state.variables};variables["x_"+subscript]=coord[0];variables["y_"+subscript]=coord[1];this.setState({variables:variables});this.props.trackInteraction();},this._updateLineLocation=(options,startCoord)=>{const xDiff=this._eval("("+options.endX+")-("+options.startX+")");const yDiff=this._eval("("+options.endY+")-("+options.startY+")");const endCoord=vector$3.add(startCoord,[xDiff,yDiff]);const variables={...this.state.variables};variables["x_"+options.startSubscript]=startCoord[0];variables["y_"+options.startSubscript]=startCoord[1];variables["x_"+options.endSubscript]=endCoord[0];variables["y_"+options.endSubscript]=endCoord[1];this.setState({variables:variables});this.props.trackInteraction();},this._eval=(expression,variables)=>{const func=KAScompile(expression,{functions:this.state.functions});const compiledVars={...this.state.variables,...variables};Object.keys(compiledVars).forEach(name=>{if(typeof compiledVars[name]==="string"){const func=KAScompile(compiledVars[name],{functions:this.state.functions});compiledVars[name]=function(x){return func({...compiledVars,x})};}});return func(compiledVars)||0},this._extractVars=expr=>{if(expr==null){return []}let vars=[];expr.args().forEach(arg=>{if(arg&&arg.constructor.name==="Expr"){vars=vars.concat(this._extractVars(arg));}});if(expr.name()==="Var"){vars.push(expr.prettyPrint());}return vars};}}const _getInitialVariables=elements=>{const variables={};elements.filter(element=>element.type==="movable-point").forEach(element=>{const subscript=element.options.varSubscript;const startXExpr=KASparse(element.options.startX||"0").expr;const startYExpr=KASparse(element.options.startY||"0").expr;let startX=0;let startY=0;if(startXExpr){startX=startXExpr.eval({})||0;}if(startYExpr){startY=startYExpr.eval({})||0;}variables["x_"+subscript]=startX;variables["y_"+subscript]=startY;});elements.filter(element=>element.type==="movable-line").forEach(element=>{const startSubscript=element.options.startSubscript;const endSubscript=element.options.endSubscript;const startXExpr=KASparse(element.options.startX||"0").expr;const startYExpr=KASparse(element.options.startY||"0").expr;const endXExpr=KASparse(element.options.endX||"0").expr;const endYExpr=KASparse(element.options.endY||"0").expr;let startX=0;let startY=0;let endX=0;let endY=0;if(startXExpr){startX=startXExpr.eval({})||0;}if(startYExpr){startY=startYExpr.eval({})||0;}if(endXExpr){endX=endXExpr.eval({})||0;}if(endYExpr){endY=endYExpr.eval({})||0;}variables["x_"+startSubscript]=startX;variables["y_"+startSubscript]=startY;variables["x_"+endSubscript]=endX;variables["y_"+endSubscript]=endY;});elements.filter(element=>element.type==="function").forEach(element=>{variables[element.options.funcName]=element.options.value;});return variables};const _getInitialFunctions=elements=>{return elements.filter(element=>element.type==="function").map(element=>element.options.funcName)};var Interactive = {name:"interaction",displayName:"Interaction",widget:Interaction,hidden:true};
2034
-
2035
- const bodyXsmallBold={fontFamily:"inherit",fontSize:15,fontWeight:"bold",lineHeight:"22px"};
2036
-
2037
- const getPromptJSON$a=widgetData=>{const propMarkers=widgetData.options.markers.map(marker=>{const userInputMarker={label:marker.label};if(marker.answers?.length){userInputMarker.answers=marker.answers;}return userInputMarker});const inputMarkers=widgetData.userInput.markers.map(marker=>{return {label:marker.label,selected:marker.selected}});return {type:"label-image",options:{choices:widgetData.options.choices,imageUrl:widgetData.options.imageUrl,imageAlt:widgetData.options.imageAlt,markers:propMarkers},userInput:{markers:inputMarkers}}};
2038
-
2039
- const AnswerChoices=props=>{const{strings}=usePerseusI18n();const onAnswerChange=selected=>{const{choices,onChange}=props;onChange(choices.map(choice=>selected.includes(choice.content)));};const AnswerItems=choices=>choices.map(({content})=>jsxRuntimeExports.jsx(OptionItem,{value:content,label:jsxRuntimeExports.jsx(Renderer,{content:content,strings:strings,inline:true})},content));const selectedValues=props.choices.filter(choice=>choice.checked).map(choice=>choice.content);const{opener,onToggle,disabled}=props;const args={style:{zIndex:"unset"},children:AnswerItems(props.choices),opener,onToggle,disabled,"aria-required":props["aria-required"]};return props.multipleSelect?jsxRuntimeExports.jsx(MultiSelect,{...args,selectedValues:selectedValues,onChange:selected=>onAnswerChange(selected)}):jsxRuntimeExports.jsx(SingleSelect,{...args,selectedValue:selectedValues[0],onChange:selected=>onAnswerChange([selected]),placeholder:props.choices[0].content})};
2040
-
2041
- const HideAnswersToggle=props=>{const switchId=useId();const labelId=useId();const{strings}=usePerseusI18n();return jsxRuntimeExports.jsxs(View,{style:styles$e.switchWrapper,children:[jsxRuntimeExports.jsx(Switch,{id:switchId,checked:props.areAnswersHidden,onChange:props.onChange,"aria-labelledby":labelId}),jsxRuntimeExports.jsx(BodyText,{id:labelId,htmlFor:switchId,tag:"label",children:strings.hideAnswersToggleLabel})]})};const styles$e=StyleSheet.create({switchWrapper:{display:"flex",flexDirection:"row",flexWrap:"wrap-reverse",alignItems:"center",gap:"0.5em",marginBlockStart:"1em"}});
2042
-
2043
- const Pill=React.forwardRef(function Pill({id,children,onClick,style},ref){if(onClick){return jsxRuntimeExports.jsx(Clickable,{id:id,onClick:onClick,style:[styles$d.pill,styles$d.clickable,style],ref:ref,children:()=>children})}return jsxRuntimeExports.jsx(View,{id:id,style:[styles$d.pill,style],ref:ref,children:children})});const styles$d=StyleSheet.create({pill:{display:"inline-flex",width:"fit-content",alignItems:"center",justifyContent:"center",paddingInline:sizing.size_120,paddingBlock:sizing.size_060,borderRadius:border$1.radius.radius_240,color:semanticColor.core.foreground.knockout.default,backgroundColor:semanticColor.core.background.instructive.strong},clickable:{outline:"none",":hover":{outline:`${border$1.width.medium} solid ${semanticColor.core.border.instructive.default}`,outlineOffset:sizing.size_020},":active":{backgroundColor:semanticColor.action.primary.progressive.press.background,outline:`${border$1.width.medium} solid ${semanticColor.core.border.instructive.strong}`,outlineOffset:sizing.size_020},":focus-visible":{boxShadow:`0 0 0 ${border$1.width.medium} ${semanticColor.focus.inner}`,outline:`${border$1.width.medium} solid ${semanticColor.focus.outer}`,outlineOffset:border$1.width.medium}}});
2044
-
2045
- const BringToFront={boxShadow:`0 8px 8px ${semanticColor.core.border.neutral.default}`,zIndex:1e3};const AnswerPill=props=>{const{selectedAnswers,showCorrectness,markerRef,side,onClick,style,focused,hovered}=props;const pillId=useId();const{strings}=usePerseusI18n();const answerString=selectedAnswers.length>1?strings.answers({num:selectedAnswers.length}):selectedAnswers[0];const correct=showCorrectness==="correct";const incorrect=showCorrectness==="incorrect";return jsxRuntimeExports.jsx(Popper,{placement:side,referenceElement:markerRef,modifiers:[{name:"preventOverflow",options:{rootBoundary:"viewport"}}],children:({ref,style:popperStyle})=>jsxRuntimeExports.jsx(Pill,{id:pillId,onClick:correct?undefined:onClick,ref:ref,style:[style,popperStyle,correct&&styles$c.correct,incorrect&&styles$c.incorrect,(focused||hovered)&&BringToFront],children:jsxRuntimeExports.jsx(Renderer,{content:answerString,strings:strings,inline:true})})})};const styles$c=StyleSheet.create({correct:{backgroundColor:semanticColor.core.background.success.strong},incorrect:{backgroundColor:semanticColor.core.background.neutral.default}});
2046
-
2047
- function shouldReduceMotion(){if(typeof window.matchMedia!=="function"){return true}const mediaQuery=window.matchMedia("(prefers-reduced-motion: reduce)");return !mediaQuery||mediaQuery.matches}const MARKER_SIZE=24;class Marker extends React.Component{componentDidMount(){this._mounted=true;}componentWillUnmount(){this._mounted=false;}renderIcon(){const{selected,showCorrectness,showSelected,showPulsate}=this.props;const isOpen=showSelected;const selectedAnswers=selected;let iconStyles;const iconNull={path:"",height:1,width:1};let args={size:MARKER_SIZE,color:semanticColor.core.foreground.knockout.default,icon:iconNull};if(showCorrectness){iconStyles=[styles$b.markerGraded,showCorrectness==="correct"?styles$b.markerCorrect:styles$b.markerIncorrect,isOpen&&styles$b.markerSelected];args={...args,icon:showCorrectness==="correct"?iconCheck:iconMinus};}else if(selectedAnswers&&selectedAnswers.length>0){iconStyles=[styles$b.markerFilled,isOpen&&styles$b.markerSelected];}else if(isOpen){iconStyles=[styles$b.markerSelected];args={...args,icon:iconChevronDown,size:8};}else if(showPulsate){iconStyles=[styles$b.markerPulsateBase,this._mounted&&shouldReduceMotion()?showPulsate&&styles$b.markerUnfilledPulsateOnce:showPulsate&&styles$b.markerUnfilledPulsateInfinite];}return jsxRuntimeExports.jsx(View,{style:[styles$b.markerIcon,iconStyles],ref:node=>this._icon=node,children:jsxRuntimeExports.jsx(Icon,{...args})})}render(){const{showCorrectness,selected,showAnswer,answerSide,answerStyles,hovered,focused}=this.props;const markerDisabled=showCorrectness==="correct";const active=hovered||focused;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(View,{style:[styles$b.marker,active&&!markerDisabled&&styles$b.markerActive],children:this.renderIcon()}),!!selected&&showAnswer&&jsxRuntimeExports.jsx(AnswerPill,{selectedAnswers:selected,showCorrectness:showCorrectness,side:answerSide,style:answerStyles,markerRef:this._icon??undefined,hovered:hovered,focused:focused})]})}constructor(...args){super(...args),this._mounted=false;}}Marker.defaultProps={selected:[]};const styles$b=StyleSheet.create({marker:{position:"absolute",backgroundColor:semanticColor.core.background.base.default,borderRadius:MARKER_SIZE,width:MARKER_SIZE,height:MARKER_SIZE,marginLeft:MARKER_SIZE/-2,marginTop:MARKER_SIZE/-2,boxShadow:boxShadow.mid},markerIcon:{display:"flex",alignItems:"center",justifyContent:"center",boxSizing:"border-box",width:MARKER_SIZE,height:MARKER_SIZE,border:`${border$1.width.medium} solid ${semanticColor.core.border.neutral.default}`,borderRadius:MARKER_SIZE},markerPulsateBase:{animationName:{"0%":{transform:"scale(1)",backgroundColor:semanticColor.core.background.instructive.default},"100%":{transform:"scale(1.3)",backgroundColor:semanticColor.core.background.instructive.default}},animationDirection:"alternate",animationDuration:"0.8s",animationTimingFunction:"ease-in",transformOrigin:"50% 50%",animationIterationCount:"0"},markerUnfilledPulsateInfinite:{animationIterationCount:"infinite"},markerUnfilledPulsateOnce:{animationIterationCount:"2"},markerActive:{outline:`${border$1.width.medium} solid ${semanticColor.core.border.instructive.default}`,outlineOffset:2},markerSelected:{boxShadow:boxShadow.mid,border:`solid ${border$1.width.thick} ${semanticColor.core.border.knockout.default}`,backgroundColor:semanticColor.core.background.instructive.default,borderRadius:MARKER_SIZE,transform:"rotate(180deg)"},markerFilled:{backgroundColor:semanticColor.core.background.instructive.subtle,border:`${border$1.width.thick} solid ${semanticColor.core.border.instructive.default}`},markerGraded:{width:MARKER_SIZE,height:MARKER_SIZE,justifyContent:"center",alignItems:"center",border:`${border$1.width.medium} solid ${semanticColor.core.border.knockout.default}`},markerCorrect:{background:semanticColor.core.background.success.strong},markerIncorrect:{background:semanticColor.core.background.neutral.default}});
2048
-
2049
- function isAnswerful(marker){return marker.answers!=null}function getComputedSelectedState(marker,userInputMarker,reviewMode,showSolutions){const shouldShowFeedback=showSolutions==="all"||reviewMode;if(!shouldShowFeedback){return userInputMarker}if(isAnswerful(marker)){return {...userInputMarker,selected:marker.answers}}else {return {...userInputMarker,selected:undefined}}}class LabelImage extends React.Component{static pointInTriangle(p,a,b,c){const sign=(p1,p2,p3)=>(p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y);const b1=sign(p,a,b)<0;const b2=sign(p,b,c)<0;const b3=sign(p,c,a)<0;return b1===b2&&b2===b3}static imageSideForMarkerPosition(x,y,preferredDirection){if(preferredDirection&&preferredDirection!=="NONE"){if(preferredDirection==="LEFT"&&x>20){return "right"}else if(preferredDirection==="RIGHT"&&x<80){return "left"}else if(preferredDirection==="UP"&&y>20){return "bottom"}else if(preferredDirection==="DOWN"&&y<80){return "top"}}if(x<20){return "left"}if(x>80){return "right"}const tl={x:20,y:0};const tr={x:80,y:0};const br={x:80,y:100};const bl={x:20,y:100};const cp={x:50,y:50};const sides=["top","right","bottom","left"];const triangles={top:[tl,tr,cp],right:[cp,tr,br],bottom:[bl,cp,br],left:[tl,cp,bl]};const p={x,y};for(const side of sides){const corners=triangles[side];if(LabelImage.pointInTriangle(p,...corners)){return side}}return "center"}static navigateToMarkerIndex(navigateDirection,markers,thisIndex){const thisMarker=markers[thisIndex];const sortedMarkers=markers.map((otherMarker,index)=>{const x=otherMarker.x-thisMarker.x;const y=otherMarker.y-thisMarker.y;const dist=Math.sqrt(x**2+y**2);return {index,dist,dir:{x:dist!==0?x/dist:0,y:dist!==0?y/dist:0}}}).filter(marker=>{if(marker.index===thisIndex){return false}return markers[marker.index].showCorrectness!=="correct"}).sort((a,b)=>{const distA=Math.round(a.dist*(navigateDirection.x*a.dir.x+navigateDirection.y*a.dir.y));const distB=Math.round(b.dist*(navigateDirection.x*b.dir.x+navigateDirection.y*b.dir.y));let dirA;let dirB;if(navigateDirection.x>0){dirA=a.dir.x>0&&distA!==0;dirB=b.dir.x>0&&distB!==0;}else if(navigateDirection.x<0){dirA=a.dir.x<0&&distA!==0;dirB=b.dir.x<0&&distB!==0;}else if(navigateDirection.y>0){dirA=a.dir.y>0&&distA!==0;dirB=b.dir.y>0&&distB!==0;}else if(navigateDirection.y<0){dirA=a.dir.y<0&&distA!==0;dirB=b.dir.y<0&&distB!==0;}if(dirA!==dirB){if(dirA){return -1}return 1}return distA-distB});return sortedMarkers.length>0?sortedMarkers[0].index:thisIndex}componentDidMount(){this.props.analytics?.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"label-image",widgetId:this.props.widgetId}});this._mounted=true;}componentWillUnmount(){this._mounted=false;}getPromptJSON(){return getPromptJSON$a(this.props)}handleMarkerChange(index,marker){const{userInput,handleUserInput}=this.props;const updatedUserInput=[...userInput.markers.slice(0,index),{label:marker.label,selected:marker.selected},...userInput.markers.slice(index+1)];handleUserInput({markers:updatedUserInput});}activateMarker(index,opened){this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:marker-interacted-with",payload:null});this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:marker-interacted-with:ti",payload:null});const{activeMarkerIndex}=this.state;if(activeMarkerIndex!==index&&opened){this.setState({activeMarkerIndex:index,markersInteracted:true});}else {this.setState({activeMarkerIndex:-1});}}handleMarkerKeyDown(index,e){const{markers}=this.props.options;if(markers.length<2){return}const directions={ArrowUp:{x:0,y:-1},ArrowRight:{x:1,y:0},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0}};if(!(e.key in directions)){return}const navigateDirection=directions[e.key];e.preventDefault();const marker=this._markers[LabelImage.navigateToMarkerIndex(navigateDirection,markers,index)];if(marker){ReactDOM.findDOMNode(marker).focus();}}handleAnswerChoicesChangeForMarker(index,selection){const{choices,markers}=this.props.options;const selected=choices.filter((_,index)=>selection[index]);this.handleMarkerChange(index,{...markers[index],selected:selected.length>0?selected:undefined});}renderMarkers(){const{userInput,options}=this.props;const{choices,imageWidth,imageHeight,markers,multipleAnswers,preferredPopoverDirection}=options;const{markersInteracted,activeMarkerIndex}=this.state;const isNarrowPage=this._mounted&&window.matchMedia(mediaQueries.xsOrSmaller.replace("@media ","")).matches;const isWideImage=imageWidth/2>imageHeight;return markers.map((marker,index)=>{const userInputMarker=userInput.markers[index];let side;let markerPosition;if(isNarrowPage||isWideImage){side=marker.y>50?"top":"bottom";markerPosition=marker.y>50?"bottom":"top";}else {markerPosition=LabelImage.imageSideForMarkerPosition(marker.x,marker.y,preferredPopoverDirection);if(markerPosition==="center"){markerPosition="bottom";}side=({left:"right",top:"bottom",right:"left",bottom:"top"})[markerPosition];}const computedSelectedState=getComputedSelectedState(marker,userInputMarker,this.props.reviewMode,this.props.showSolutions);let score;if(isAnswerful(marker)){score=scoreLabelImageMarker(computedSelectedState.selected,marker.answers);}else {score={hasAnswers:false,isCorrect:false};}const shouldShowFeedback=this.props.showSolutions==="all"||this.props.reviewMode;const showCorrectness=shouldShowFeedback&&score.isCorrect?"correct":marker.showCorrectness;const disabled=shouldShowFeedback;const isRequired=this.props.isScorable&&!disabled&&!this.props.static&&!this.props.apiOptions.readOnly;const isActiveAnswerChoice=activeMarkerIndex===index;const showAnswerChoice=computedSelectedState.selected&&!this.state.hideAnswers&&!isActiveAnswerChoice;const adjustPillDistance={[`margin${markerPosition.charAt(0).toUpperCase()+markerPosition.slice(1)}`]:10};return jsxRuntimeExports.jsx(View,{style:{position:"absolute",left:`${marker.x}%`,top:`${marker.y}%`,zIndex:"unset"},children:jsxRuntimeExports.jsx(AnswerChoices,{choices:choices.map(choice=>({content:choice,checked:computedSelectedState.selected?computedSelectedState.selected.includes(choice):false})),multipleSelect:multipleAnswers,onChange:selection=>{this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:choiced-interacted-with",payload:null});this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:choiced-interacted-with:ti",payload:null});this.handleAnswerChoicesChangeForMarker(index,selection);},onToggle:opened=>this.activateMarker(index,opened),disabled:disabled,"aria-required":isRequired,opener:({opened})=>jsxRuntimeExports.jsx(Clickable,{role:"button","aria-expanded":opened,"aria-label":showCorrectness==="correct"?this.context.strings.correctExcited:marker.label,children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(Marker,{showCorrectness:showCorrectness,showSelected:opened,showPulsate:!markersInteracted,ref:node=>this._markers[index]=node,showAnswer:showAnswerChoice,answerSide:side,answerStyles:adjustPillDistance,focused:focused||pressed,hovered:hovered,selected:computedSelectedState.selected})},`marker-${marker.x}.${marker.y}`)},`answers-${marker.x}.${marker.y}`)},index)})}renderInstructions(){const{apiOptions:{isMobile}}=this.props;const{choices,multipleAnswers,hideChoicesFromInstructions:hideChoices}=this.props.options;const{strings}=this.context;const promptString=isMobile?multipleAnswers?strings.tapMultiple:strings.tapSingle:multipleAnswers?strings.clickMultiple:strings.clickSingle;const choicesString=strings.choices;return jsxRuntimeExports.jsxs("div",{className:classNames$2("perseus-label-image-widget-instructions",css(styles$a.instructions)),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$a.instructionsCaption),children:[promptString," ",!hideChoices&&choicesString]}),!hideChoices&&jsxRuntimeExports.jsx("div",{className:css(styles$a.instructionsChoices),children:choices.map((choice,index)=>jsxRuntimeExports.jsx("div",{className:css(styles$a.instructionsChoice),children:jsxRuntimeExports.jsx(Renderer,{content:choice,strings:strings,apiOptions:this.props.apiOptions})},index))})]})}getSerializedState(){const{userInput,options,...restOfProps}=this.props;const{markers,...restOfOptions}=options;return {...restOfOptions,...restOfProps,markers:markers.map((marker,index)=>({...marker,selected:userInput.markers[index].selected}))}}render(){const{imageAlt,imageUrl,imageWidth,imageHeight}=this.props.options;const{activeMarkerIndex}=this.state;return jsxRuntimeExports.jsxs("div",{children:[this.renderInstructions(),jsxRuntimeExports.jsxs("div",{className:css(styles$a.markersCanvas),style:{maxInlineSize:imageWidth,maxBlockSize:imageHeight},children:[jsxRuntimeExports.jsx("div",{className:css(styles$a.imageContainer,activeMarkerIndex!==-1&&styles$a.imageInteractionDisabled),children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{alt:imageAlt,src:imageUrl,width:imageWidth,height:imageHeight,setAssetStatus:setAssetStatus,allowZoom:true})})}),this.renderMarkers()]}),jsxRuntimeExports.jsx(HideAnswersToggle,{areAnswersHidden:this.state.hideAnswers,onChange:hideAnswers=>{this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:toggle-answers-hidden",payload:null});this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:toggle-answers-hidden:ti",payload:null});this.setState({hideAnswers});}})]})}constructor(props){super(props),this._mounted=false;this._markers=[];this.state={activeMarkerIndex:-1,markersInteracted:false,hideAnswers:false};}}LabelImage.contextType=PerseusI18nContext;const LabelImageWithDependencies=React.forwardRef((props,ref)=>{const deps=useDependencies();return jsxRuntimeExports.jsx(LabelImage,{ref:ref,analytics:deps.analytics,...props})});function getStartUserInput$7(options){return {markers:options.markers.map(m=>({label:m.label}))}}function getUserInputFromSerializedState$7(serializedState){return {markers:serializedState.markers.map(m=>({label:m.label,selected:m.selected}))}}function getCorrectUserInput$3(options){return {markers:options.markers.map(marker=>({label:marker.label,selected:marker.answers}))}}var LabelImage$1 = {name:"label-image",displayName:"Label Image",widget:LabelImageWithDependencies,isLintable:true,getStartUserInput: getStartUserInput$7,getCorrectUserInput: getCorrectUserInput$3,getUserInputFromSerializedState: getUserInputFromSerializedState$7};const styles$a=StyleSheet.create({instructions:{paddingBlockEnd:16},instructionsCaption:{...bodyXsmallBold,paddingBlockEnd:16},instructionsChoices:{display:"flex",flexWrap:"wrap",marginBlock:"-8px",marginInline:"0"},instructionsChoice:{display:"flex",alignItems:"center",marginBlock:"8px",marginInline:"0",":not(:last-child)":{"::after":{content:"''",display:"inline-block",position:"relative",width:2,height:2,marginInlineStart:5,marginInlineEnd:5,background:semanticColor.core.border.neutral.default,borderRadius:border$1.radius.radius_full}}},markersCanvas:{position:"relative"},imageContainer:{display:"flex"},imageInteractionDisabled:{pointerEvents:"none"}});
2050
-
2051
- const addOffsetParentScroll=($el,position)=>{const $offsetParent=$el.offsetParent();return {top:position.top+$offsetParent.scrollTop(),left:position.left+$offsetParent.scrollLeft()}};class Placeholder extends React.Component{render(){const{layout}=this.props;const className=css(styles$9.card,styles$9.placeholder,layout==="horizontal"&&styles$9.horizontalCard);const style={width:this.props.width,height:this.props.height};if(this.props.margin!=null){style.margin=this.props.margin;}return jsxRuntimeExports.jsx("li",{className:className,style:style})}}class Draggable extends React.Component{componentDidMount(){this._mounted=true;this.isMouseMoveUpBound=false;document.addEventListener("touchmove",this.onMouseMove,Util.supportsPassiveEvents()?{passive:false}:false);}componentDidUpdate(prevProps){if(this.props.state===prevProps.state){return}if(this.props.state==="animating"&&this.props.endPosition){const current=this.getCurrentPosition();const duration=15*Math.sqrt(Math.sqrt(Math.pow(this.props.endPosition.left-current.left,2)+Math.pow(this.props.endPosition.top-current.top,2)));$(ReactDOM__default.findDOMNode(this)).animate(this.props.endPosition,{duration:Math.max(duration,1),complete:this.props.onAnimationEnd});}else if(this.props.state==="static"){$(ReactDOM__default.findDOMNode(this)).finish();}}componentWillUnmount(){this._mounted=false;if(this.isMouseMoveUpBound){this.unbindMouseMoveUp();}if(this.animationFrameRequest){cancelAnimationFrame(this.animationFrameRequest);}document.removeEventListener("touchmove",this.onMouseMove);}render(){const{includePadding,layout,state:type}=this.props;let className=css(styles$9.card,styles$9.draggable,layout==="horizontal"&&styles$9.horizontalCard,layout==="vertical"&&styles$9.verticalCard,type==="dragging"&&styles$9.dragging,type==="disabled"&&styles$9.disabled,!includePadding&&styles$9.unpaddedCard)+" "+"perseus-sortable-draggable";if(!includePadding){className+=" perseus-sortable-draggable-unpadded";}const style={position:"static"};if(this.props.state==="dragging"||this.props.state==="animating"){Object.assign(style,{position:"absolute"},this.getCurrentPosition());}if(this.props.width){style.width=this.props.width+1;}if(this.props.height){style.height=this.props.height;}if(this.props.margin!=null){style.margin=this.props.margin;}return jsxRuntimeExports.jsx("li",{className:className,style:style,onMouseDown:this.onMouseDown,onTouchStart:this.onMouseDown,onTouchMove:this.onMouseMove,onTouchEnd:this.onMouseUp,onTouchCancel:this.onMouseUp,children:jsxRuntimeExports.jsx(Renderer,{content:this.props.content,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"draggable"),onRender:this.props.onRender,strings:this.context.strings,apiOptions:this.props.apiOptions})})}constructor(...args){super(...args),this.animationFrameRequest=null,this.state={startPosition:{left:0,top:0},startMouse:{left:0,top:0},mouse:{left:0,top:0},dragging:false},this.getCurrentPosition=()=>{return {left:this.state.startPosition.left+this.state.mouse.left-this.state.startMouse.left,top:this.state.startPosition.top+this.state.mouse.top-this.state.startMouse.top}},this.bindMouseMoveUp=()=>{this.isMouseMoveUpBound=true;$(document).on("mousemove",this.onMouseMove);$(document).on("mouseup",this.onMouseUp);},this.unbindMouseMoveUp=()=>{this.isMouseMoveUpBound=false;$(document).off("mousemove",this.onMouseMove);$(document).off("mouseup",this.onMouseUp);},this.onMouseDown=event=>{if(this.props.state!=="static"){return}if(!(event.button===0||event.touches!=null&&event.touches.length===1)){return}event.preventDefault();const loc=Util.extractPointerLocation(event);this.animationFrameRequest=requestAnimationFrame(()=>{const $el=$(ReactDOM__default.findDOMNode(this));const position=$el.position();const startPosition=addOffsetParentScroll($el,position);if(loc&&this._mounted){this.setState({startPosition,startMouse:loc,mouse:loc,dragging:true},function(){this.bindMouseMoveUp();this.props.onMouseDown();});}});},this.onMouseMove=event=>{const notDragging=this.props.state!=="dragging"||!this.state.dragging;if(notDragging){return}event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.animationFrameRequest=requestAnimationFrame(()=>{this.setState({mouse:loc},this.props.onMouseMove);});}},this.onMouseUp=event=>{const notDragging=this.props.state!=="dragging"||!this.state.dragging;if(notDragging){return}event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.setState({dragging:false});this.unbindMouseMoveUp();this.props.onMouseUp();}};}}Draggable.contextType=PerseusI18nContext;Draggable.defaultProps={includePadding:true,type:"static",linterContext:PerseusLinter.linterContextDefault};class Sortable extends React.Component{static itemsFromProps(props){const state=props.disabled?"disabled":"static";return props.options.map((option,i)=>{return {option:option,key:i,state,width:0,height:0}})}static clearItemMeasurements(items){return items.map(item=>{return {...item,width:0,height:0}})}componentDidMount(){document.fonts?.addEventListener("loadingdone",this.remeasureItems);}UNSAFE_componentWillReceiveProps(nextProps){const prevProps=this.props;if(!_.isEqual(nextProps.options,prevProps.options)){this.setState({items:Sortable.itemsFromProps(nextProps)});}else if(nextProps.layout!==prevProps.layout||nextProps.padding!==prevProps.padding||nextProps.disabled!==prevProps.disabled||!_.isEqual(nextProps.constraints,prevProps.constraints)){this.setState({items:Sortable.clearItemMeasurements(this.state.items)});}}componentDidUpdate(){if(this.state.items.length&&!this.state.items[0].width&&!this.state.items[0].height){setTimeout(()=>{this.measureItems();},0);}}componentWillUnmount(){this.isUnmounted=true;document.fonts?.removeEventListener("loadingdone",this.remeasureItems);}measureItems(){let items=[...this.state.items];const $items=items.map(item=>{return $(ReactDOM__default.findDOMNode(this.refs[item.key]))});const widths=_.invoke($items,"outerWidth");const heights=_.invoke($items,"outerHeight");const{constraints,layout}=this.props;let syncWidth=null;if(constraints?.width){syncWidth=Math.max(...widths,constraints.width);}else if(layout==="vertical"){syncWidth=Math.max(...widths);}let syncHeight=null;if(constraints?.height){syncHeight=Math.max(...heights,constraints.height);}else if(layout==="horizontal"){syncHeight=Math.max(...heights);}items=items.map(function(item,i){item.width=syncWidth||widths[i];item.height=syncHeight||heights[i];return item});this.setState({items},()=>{this.props.onMeasure?.({widths:widths,heights:heights});});}onMouseDown(key){const items=this.state.items.map(function(item){if(item.key===key){item.state="dragging";}return item});this.setState({items:items});}moveOptionToIndex(option,index){const{items}=this.state;if(index<0||index>items.length){throw new Error(`index ${index} out of bounds`)}const nextItems=[...items];const item=items.filter(item=>{return item.option===option})[0];if(item==null){throw new Error(`option ${option} not found`)}const currentIndex=items.findIndex(i=>{return i.key===item.key});nextItems.splice(currentIndex,1);nextItems.splice(index,0,item);this.setState({items:nextItems},()=>{this.props.onChange?.({});});}onMouseMove(key){const $draggable=$(ReactDOM__default.findDOMNode(this.refs[key]));const $sortable=$(ReactDOM__default.findDOMNode(this));const items=[...this.state.items];const item=this.state.items.find(item=>item.key===key);const margin=this.props.margin||0;const currentIndex=items.indexOf(item);let newIndex=0;items.splice(currentIndex,1);if(this.props.layout==="horizontal"){const midWidth=$draggable.offset().left-$sortable.offset().left;let sumWidth=0;let cardWidth;items.forEach(function(item){cardWidth=item.width;if(midWidth>sumWidth+cardWidth/2){newIndex+=1;}sumWidth+=cardWidth+margin;});}else {const midHeight=$draggable.offset().top-$sortable.offset().top;let sumHeight=0;let cardHeight;items.forEach(function(item){cardHeight=item.height;if(midHeight>sumHeight+cardHeight/2){newIndex+=1;}sumHeight+=cardHeight+margin;});}if(newIndex!==currentIndex){items.splice(newIndex,0,item);this.setState({items:items});}}onMouseUp(key){const nextAnimationFrame=requestAnimationFrame(()=>{const items=this.state.items.map(item=>{if(item.key===key){item.state="animating";const $placeholder=$(ReactDOM__default.findDOMNode(this.refs["placeholder_"+key]));const position=$placeholder.position();const endPosition=addOffsetParentScroll($placeholder,position);item.endPosition=endPosition;}return item},this);this.setState({items:items},()=>{this.props.onChange?.({});});});this.animationFrameRequest=nextAnimationFrame;}onAnimationEnd(key){const items=this.state.items.map(function(item){if(item.key===key){item.state="static";}return item});this.setState({items:items});}getOptions(){return this.state.items.map(item=>item.option)}render(){if(this.props.waitForTexRendererToLoad&&!this.state.texRendererLoaded){const{TeX}=getDependencies();return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(CircularSpinner,{}),jsxRuntimeExports.jsx("div",{style:{display:"none"},children:jsxRuntimeExports.jsx(TeX,{onRender:()=>this.setState({texRendererLoaded:true}),children:"1"})})]})}const cards=[];const{layout}=this.props;const className=css(styles$9.sortable)+" perseus-sortable";const syncWidth=this.props.constraints?.width||layout==="vertical";const syncHeight=this.props.constraints?.height||layout==="horizontal";this.state.items.forEach((item,i,items)=>{const isLast=i===items.length-1;const isStatic=item.state==="static"||item.state==="disabled";let margin;if(this.props.layout==="horizontal"){margin="0 "+this.props.margin+"px 0 0";}else if(this.props.layout==="vertical"){margin="0 0 "+this.props.margin+"px 0";}cards.push(jsxRuntimeExports.jsx(Draggable,{apiOptions:this.props.apiOptions,content:item.option,state:item.state,ref:item.key,width:syncWidth?item.width:undefined,height:syncHeight?item.height:undefined,layout:layout,includePadding:this.props.padding,margin:isLast&&isStatic?0:margin,endPosition:item.endPosition,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"sortable"),onRender:this.remeasureItems,onMouseDown:()=>this.onMouseDown(item.key),onMouseMove:()=>this.onMouseMove(item.key),onMouseUp:()=>this.onMouseUp(item.key),onTouchMove:()=>this.onMouseMove(item.key),onTouchEnd:()=>this.onMouseUp(item.key),onTouchCancel:()=>this.onMouseUp(item.key),onAnimationEnd:()=>this.onAnimationEnd(item.key)},item.key));if(item.state==="dragging"||item.state==="animating"){cards.push(jsxRuntimeExports.jsx(Placeholder,{ref:"placeholder_"+item.key,width:item.width,height:item.height,layout:layout,margin:isLast?0:margin},"placeholder_"+item.key));}});return jsxRuntimeExports.jsx("ul",{className:className,children:cards})}constructor(props){super(props),this.isUnmounted=false,this.remeasureItems=_.debounce(()=>{if(this.isUnmounted){return}this.setState({items:Sortable.clearItemMeasurements(this.state.items)});},20);this.state={items:Sortable.itemsFromProps(this.props),texRendererLoaded:false};}}Sortable.defaultProps={layout:"horizontal",padding:true,disabled:false,constraints:{},onMeasure:function(){},margin:5,onChange:function(){},linterContext:PerseusLinter.linterContextDefault,waitForTexRendererToLoad:true};const styles$9=StyleSheet.create({sortable:{boxSizing:"border-box",float:"inline-start",padding:0,margin:0},card:{boxSizing:"border-box",background:semanticColor.core.background.base.default,border:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderRadius:border$1.radius.radius_040,cursor:"pointer",minInlineSize:25,minBlockSize:44,padding:10,listStyleType:"none",userSelect:"none",touchAction:"none"},placeholder:{background:semanticColor.core.background.neutral.subtle,border:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`},draggable:{textAlign:"center"},horizontalCard:{float:"inline-start",cursor:"ew-resize"},verticalCard:{maxInlineSize:"100%",cursor:"ns-resize"},unpaddedCard:{padding:0},dragging:{background:semanticColor.core.background.instructive.subtle,border:`${border$1.width.thin} solid ${semanticColor.core.border.instructive.default}`,opacity:.8},disabled:{backgroundColor:"inherit",border:`${border$1.width.thin} solid ${semanticColor.core.border.disabled.subtle}`,cursor:"default"}});
2052
-
2053
- const getPromptJSON$9=widgetData=>{const{userInput,options}=widgetData;return {type:"matcher",options:{labels:options.labels,left:options.left,right:options.right,orderMatters:options.orderMatters},userInput:{left:userInput.left,right:userInput.right}}};
2054
-
2055
- const HACKY_CSS_CLASSNAME="perseus-widget-matcher";const Matcher=forwardRef(function Matcher(props,ref){const{strings}=usePerseusI18n();const dependencies=useDependencies();const leftSortable=useRef(null);const rightSortable=useRef(null);const[leftHeight,setLeftHeight]=useState(0);const[rightHeight,setRightHeight]=useState(0);const[texRendererLoaded,setTexRendererLoaded]=useState(false);useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"matcher",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON:()=>getPromptJSON$9(props),moveLeftOptionToIndex:(option,index)=>{leftSortable.current?.moveOptionToIndex(option,index);},moveRightOptionToIndex:(option,index)=>{rightSortable.current?.moveOptionToIndex(option,index);}}));function getUserInputFromSortable(){if(!texRendererLoaded){return {left:[],right:[]}}return {left:leftSortable.current?.getOptions()??[],right:rightSortable.current?.getOptions()??[]}}function changeAndTrack(){props.handleUserInput(getUserInputFromSortable());props.trackInteraction();}if(!texRendererLoaded){const{TeX}=getDependencies();return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(CircularSpinner,{}),jsxRuntimeExports.jsx("div",{style:{display:"none"},children:jsxRuntimeExports.jsx(TeX,{onRender:()=>setTexRendererLoaded(true),children:"1"})})]})}const{labels,padding,orderMatters}=props.options;const showLabels=labels.some(isTruthy);const constraints={height:Math.max(leftHeight,rightHeight)};const cellMarginPx=props.apiOptions.isMobile?8:5;return jsxRuntimeExports.jsx("table",{className:css(styles$8.widget)+" "+HACKY_CSS_CLASSNAME,children:jsxRuntimeExports.jsxs("tbody",{children:[showLabels&&jsxRuntimeExports.jsxs("tr",{className:css(styles$8.row),children:[jsxRuntimeExports.jsx("th",{className:css(styles$8.column,styles$8.columnLabel),children:jsxRuntimeExports.jsx(Renderer,{content:labels[0]||"...",linterContext:props.linterContext,strings:strings,apiOptions:props.apiOptions})}),jsxRuntimeExports.jsx("th",{className:css(styles$8.column,styles$8.columnRight,styles$8.columnLabel),children:jsxRuntimeExports.jsx(Renderer,{content:labels[1]||"...",linterContext:props.linterContext,strings:strings,apiOptions:props.apiOptions})})]}),jsxRuntimeExports.jsxs("tr",{className:css(styles$8.row),children:[jsxRuntimeExports.jsx("td",{className:css(styles$8.column),children:jsxRuntimeExports.jsx(Sortable,{apiOptions:props.apiOptions,options:props.userInput.left,layout:"vertical",padding:padding,disabled:!orderMatters,constraints:constraints,onMeasure:dimensions=>setLeftHeight(Math.max(...dimensions.heights)),onChange:changeAndTrack,margin:cellMarginPx,linterContext:props.linterContext,ref:leftSortable})}),jsxRuntimeExports.jsx("td",{className:css(styles$8.column,styles$8.columnRight),children:jsxRuntimeExports.jsx(Sortable,{apiOptions:props.apiOptions,options:props.userInput.right,layout:"vertical",padding:padding,constraints:constraints,onMeasure:dimensions=>setRightHeight(Math.max(...dimensions.heights)),onChange:changeAndTrack,margin:cellMarginPx,linterContext:props.linterContext,ref:rightSortable})})]})]})})});function getStartUserInput$6(options,problemNum){const shuffled=shuffleMatcher(options,problemNum);return shuffled}function getUserInputFromSerializedState$6(serializedState){return {left:serializedState.left,right:serializedState.right}}var Matcher$1 = {name:"matcher",displayName:"Matcher (two column)",hidden:true,widget:Matcher,isLintable:true,getStartUserInput: getStartUserInput$6,getUserInputFromSerializedState: getUserInputFromSerializedState$6};const padding=5;const border=`var(--wb-border-width-thin) solid var(--wb-semanticColor-core-border-neutral-strong)`;const styles$8=StyleSheet.create({widget:{paddingBlockStart:padding,maxInlineSize:"100%",minInlineSize:"auto"},row:{border:0},column:{padding:0,border:0},columnRight:{borderInlineStart:border},columnLabel:{fontWeight:"inherit",borderBlockEnd:border,padding:`0 ${padding}px ${padding}px ${padding}px`,textAlign:"center"}});
2056
-
2057
- const getPromptJSON$8=widgetData=>{return {type:"matrix",options:{height:widgetData.options.matrixBoardSize[0],width:widgetData.options.matrixBoardSize[1]},userInput:{answerRows:widgetData.userInput.answers}}};
2058
-
2059
- const{assert: assert$1}=InteractiveUtil;const NORMAL_DIMENSIONS={INPUT_MARGIN:3,INPUT_HEIGHT:30,INPUT_WIDTH:40};const KEYPAD_INPUT_DIMENSIONS={INPUT_MARGIN:4,INPUT_HEIGHT:36,INPUT_WIDTH:64};function getInputPath$1(row,column){return [""+row,""+column]}const getDefaultPath$1=function(){return getInputPath$1(0,0)};const getRowFromPath$1=function(path){assert$1(Array.isArray(path)&&path.length===2);return +path[0]};const getColumnFromPath$1=function(path){assert$1(Array.isArray(path)&&path.length===2);return +path[1]};const getRefForPath$1=function(path){const row=getRowFromPath$1(path);const column=getColumnFromPath$1(path);return "answer"+row+","+column};class Matrix extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"matrix",widgetSubType:"null",widgetId:this.props.widgetId}});this.cursorPosition=[0,0];}getDOMNodeForPath(path){const inputID=getRefForPath$1(path);return ReactDOM__default.findDOMNode(this.refs[inputID])}getPromptJSON(){return getPromptJSON$8(this.props)}getSerializedState(){const{alignment,options,userInput}=this.props;return {static:this.props.static,alignment,matrixBoardSize:options.matrixBoardSize,prefix:options.prefix,suffix:options.suffix,answers:userInput.answers,cursorPosition:this.state.cursorPosition}}render(){let dimensions;if(this.props.apiOptions.customKeypad){dimensions=KEYPAD_INPUT_DIMENSIONS;}else {dimensions=NORMAL_DIMENSIONS;}const{INPUT_MARGIN,INPUT_HEIGHT,INPUT_WIDTH}=dimensions;const matrixSize=getMatrixSize(this.props.userInput.answers);const maxRows=this.props.options.matrixBoardSize[0];const maxCols=this.props.options.matrixBoardSize[1];const cursorRow=this.state.cursorPosition[0];const cursorCol=this.state.cursorPosition[1];const highlightedRow=Math.max(cursorRow,matrixSize[0]-1);const highlightedCol=Math.max(cursorCol,matrixSize[1]-1);const bracketHeight=(highlightedRow+1)*(INPUT_HEIGHT+2*INPUT_MARGIN);const bracketOffset=(highlightedCol+1)*(INPUT_WIDTH+2*INPUT_MARGIN);const className=classNames$2({"perseus-matrix":true,"static-mode":this.props.static});return jsxRuntimeExports.jsxs("div",{className:className,children:[this.props.options.prefix&&jsxRuntimeExports.jsx("div",{className:"matrix-prefix",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.options.prefix,linterContext:this.props.linterContext,strings:this.context.strings,apiOptions:this.props.apiOptions})}),jsxRuntimeExports.jsxs("div",{className:"matrix-input",children:[jsxRuntimeExports.jsx("div",{className:"matrix-bracket bracket-left",style:{height:bracketHeight}}),jsxRuntimeExports.jsx("div",{className:"matrix-bracket bracket-right",style:{height:bracketHeight,left:bracketOffset}}),_(maxRows).times(row=>{const rowVals=this.props.userInput.answers[row];return jsxRuntimeExports.jsx("div",{className:"matrix-row",children:_(maxCols).times(col=>{const outside=row>highlightedRow||col>highlightedCol;const inputProps={className:outside?"outside":"inside",ref:getRefForPath$1(getInputPath$1(row,col)),value:rowVals?rowVals[col]:null,style:{height:INPUT_HEIGHT,width:INPUT_WIDTH,margin:INPUT_MARGIN},disabled:this.props.apiOptions.readOnly||this.props.apiOptions.editingDisabled,onFocus:()=>{this.cursorPosition=[row,col];this.setState({cursorPosition:[row,col]});this._handleFocus(row,col);},onBlur:()=>{if(row===this.cursorPosition[0]&&col===this.cursorPosition[1]){this.setState({cursorPosition:[0,0]});}this._handleBlur(row,col);},onKeyDown:e=>{this.handleKeyDown(row,col,e);},onChange:(value,cb)=>{this.onValueChange(row,col,value,cb);}};let MatrixInput;if(this.props.apiOptions.customKeypad){const style={margin:INPUT_MARGIN,minWidth:INPUT_WIDTH,minHeight:INPUT_HEIGHT,boxSizing:"border-box",borderWidth:outside?border$1.width.thin:border$1.width.medium};MatrixInput=jsxRuntimeExports.jsx(SimpleKeypadInput,{...inputProps,style:style,scrollable:true,keypadElement:this.props.keypadElement});}else {const updatedProps={...inputProps,style:StyleSheet.create({input:{...inputProps.style,display:"inline-block",padding:0,borderWidth:outside?border$1.width.thin:border$1.width.medium}}).input};MatrixInput=jsxRuntimeExports.jsx(TextInput,{...updatedProps});}return jsxRuntimeExports.jsx("span",{className:"matrix-input-field",children:MatrixInput},col)})},row)})]}),this.props.options.suffix&&jsxRuntimeExports.jsx("div",{className:"matrix-suffix",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.options.suffix,linterContext:this.props.linterContext,strings:this.context.strings,apiOptions:this.props.apiOptions})})]})}constructor(...args){super(...args),this.state={cursorPosition:[0,0]},this.getInputPaths=()=>{const inputPaths=[];const maxRows=this.props.options.matrixBoardSize[0];const maxCols=this.props.options.matrixBoardSize[1];for(let row=0;row<maxRows;row++){for(let col=0;col<maxCols;col++){const inputPath=getInputPath$1(row,col);inputPaths.push(inputPath);}}return inputPaths},this._handleFocus=(row,col)=>{this.props.onFocus(getInputPath$1(row,col));},this._handleBlur=(row,col)=>{this.props.onBlur(getInputPath$1(row,col));},this.focus=()=>{this.focusInputPath(getDefaultPath$1());return true},this.focusInputPath=path=>{const inputID=getRefForPath$1(path);this.refs[inputID].focus();},this.blurInputPath=path=>{if(path.length===0){path=getDefaultPath$1();}const inputID=getRefForPath$1(path);this.refs[inputID].blur();},this.handleKeyDown=(row,col,e)=>{const maxRow=this.props.options.matrixBoardSize[0];const maxCol=this.props.options.matrixBoardSize[1];const curInput=this.refs[getRefForPath$1(getInputPath$1(row,col))];const curValueString=curInput.getStringValue();const cursorStartPosition=curInput.getSelectionStart();const cursorEndPosition=curInput.getSelectionEnd();let nextPath=null;if(e.key==="ArrowUp"&&row>0){nextPath=getInputPath$1(row-1,col);}else if(e.key==="ArrowDown"&&row+1<maxRow){nextPath=getInputPath$1(row+1,col);}else if(e.key==="ArrowLeft"&&col>0){if(cursorStartPosition===0&&cursorEndPosition===0){nextPath=getInputPath$1(row,col-1);}}else if(e.key==="ArrowRight"&&col+1<maxCol){if(cursorStartPosition===curValueString.length){nextPath=getInputPath$1(row,col+1);}}if(nextPath){e.preventDefault();const input=this.refs[getRefForPath$1(nextPath)];const inputValString=input.getStringValue();const valueLength=inputValString.length*2;input.focus();if(e.key==="ArrowRight"){input.setSelectionRange(0,0);}else {input.setSelectionRange(valueLength,valueLength);}}},this.onValueChange=(row,column,value,cb)=>{const answers=this.props.userInput.answers.map(answer=>[...answer]);if(!answers[row]){answers[row]=[];}answers[row][column]=value;this.props.handleUserInput({answers},cb);this.props.trackInteraction();};}}Matrix.contextType=PerseusI18nContext;function getStartUserInput$5(){return {answers:[[]]}}function getCorrectUserInput$2(options){return {answers:options.answers.map(row=>row.map(num=>String(num)))}}function getUserInputFromSerializedState$5(serializedState){return {answers:serializedState.answers}}const WrappedMatrix=withDependencies(Matrix);var Matrix$1 = {name:"matrix",displayName:"Matrix",hidden:true,widget:WrappedMatrix,isLintable:true,getStartUserInput: getStartUserInput$5,getCorrectUserInput: getCorrectUserInput$2,getUserInputFromSerializedState: getUserInputFromSerializedState$5};
2060
-
2061
- const getPromptJSON$7=()=>{return getUnsupportedPromptJSON("measurer")};
2062
-
2063
- class Measurer extends React.Component{componentDidMount(){this.setupGraphie();}componentDidUpdate(prevProps){const propsAffectingGraphie=["box","showProtractor","showRuler","rulerLabel","rulerTicks","rulerPixels","rulerLength"];const shouldSetupGraphie=propsAffectingGraphie.some(prop=>prevProps.options[prop]!==this.props.options[prop]);if(shouldSetupGraphie){this.setupGraphie();}}setupGraphie(){const graphieDiv=this.graphieDivRef.current;if(graphieDiv==null){throw new Error("No graphie container div found")}graphieDiv.innerHTML="";const graphie=GraphUtils.createGraphie(graphieDiv);const scale=[40,40];const range=[[0,this.props.options.box[0]/scale[0]],[0,this.props.options.box[1]/scale[1]]];graphie.init({range:range,scale:scale});graphie.addMouseLayer({allowScratchpad:true});if(this.protractor){this.protractor.remove();}if(this.props.options.showProtractor){this.protractor=graphie.protractor([7.5,.5]);}if(this.ruler){this.ruler.remove();}if(this.props.options.showRuler){this.ruler=graphie.ruler({center:[(range[0][0]+range[0][1])/2,(range[1][0]+range[1][1])/2],label:this.props.options.rulerLabel,pixelsPerUnit:this.props.options.rulerPixels,ticksPerUnit:this.props.options.rulerTicks,units:this.props.options.rulerLength});}}getPromptJSON(){return getPromptJSON$7()}render(){const{image}=this.props.options;return jsxRuntimeExports.jsxs("div",{className:"perseus-widget perseus-widget-measurer "+"graphie-container blank-background",style:{width:this.props.options.box[0],height:this.props.options.box[1]},children:[image.url&&jsxRuntimeExports.jsx("div",{style:{position:"relative",top:image.top??0,left:image.left??0},children:jsxRuntimeExports.jsx(SvgImage,{src:image.url,allowZoom:false})}),jsxRuntimeExports.jsx("div",{className:"graphie",ref:this.graphieDivRef})]})}constructor(...args){super(...args),this.isWidget=true,this.graphieDivRef=React.createRef();}}var Measurer$1 = {name:"measurer",displayName:"Measurer",hidden:true,widget:Measurer};
2064
-
2065
- const getPromptJSON$6=widgetData=>{const{userInput}=widgetData;return {type:"number-line",options:{range:widgetData.options.range,snapDivisions:widgetData.options.snapDivisions},userInput:{numLinePosition:userInput.numLinePosition,numDivisions:userInput.numDivisions,rel:userInput.rel}}};
2066
-
2067
- const MovablePoint=Graphie.MovablePoint;const Line=Graphie.Line;const{assert}=InteractiveUtil;const bound=(x,gt,lt)=>Math.min(Math.max(x,gt),lt);const EN_DASH="–";const horizontalPadding=30;const MOBILE_BOX_WIDTH=288;const DESKTOP_BOX_WIDTH=460;function getNumberLineWidthPx(isMobile){return (isMobile?MOBILE_BOX_WIDTH:DESKTOP_BOX_WIDTH)-horizontalPadding*2}const reverseRel={eq:"eq",ge:"le",gt:"lt",le:"ge",lt:"gt"};const toggleStrictRel={eq:"eq",ge:"gt",gt:"ge",le:"lt",lt:"le"};function formatImproper(n,d){if(d===1){return ""+n}return `\\dfrac{${n}}{${d}}`}function formatMixed(n,d){if(n<0){return "-"+formatMixed(-n,d)}const w=Math.floor(n/d);if(w===0){return formatImproper(n,d)}if(n-w*d===0){return ""+w}return w+formatImproper(n-w*d,d)}function formatNonReduced(n,d,base){const factor=Math.floor(base/d);return formatImproper(n*factor,base)}const _label=(graphie,labelStyle,pos,value,base)=>{value=value||pos;if(labelStyle==="decimal"){return graphie.label([pos,-0.53],Math.round(value*100)/100,"center")}if(labelStyle==="improper"){const frac=KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatImproper(frac[0],frac[1]),"below")}if(labelStyle==="mixed"){const frac=KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatMixed(frac[0],frac[1]),"below")}if(labelStyle==="non-reduced"){const frac=KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatNonReduced(frac[0],frac[1],base),"below")}};const TickMarks=Graphie.createSimpleClass((graphie,props)=>{if(!Number.isFinite(props.tickStep)||props.tickStep<=0){return []}const results=[];const{range,labelRange,labelStyle,labelTicks,tickStep,numDivisions}=props;const leftLabel=labelRange[0]==null?range[0]:labelRange[0];const rightLabel=labelRange[1]==null?range[1]:labelRange[1];let base;if(labelStyle==="non-reduced"){const fractions=[leftLabel,rightLabel];for(let i=0;i<=numDivisions;i++){const x=range[0]+i*tickStep;fractions.push(x);}const getDenom=x=>number.toFraction(x)[1];const denoms=fractions.map(getDenom);base=denoms.reduce((x,y)=>KhanMath.getLCM(x,y));}else {base=undefined;}const highlightedLineStyle={stroke:tokenValue(semanticColor.core.foreground.instructive.default),strokeWidth:3.5};const highlightedTextStyle={color:tokenValue(semanticColor.core.foreground.instructive.default)};const initialTicks=[...Array(Math.round(numDivisions)).keys()].map(index=>range[0]+index*tickStep);const byNumericAscending=(a,b)=>a-b;const allTicks=[...new Set([...initialTicks,leftLabel,rightLabel,...range])].sort(byNumericAscending);allTicks.forEach(tick=>{const tickIsHighlighted=tick===leftLabel||tick===rightLabel;const lineStyle=tickIsHighlighted?highlightedLineStyle:null;const textStyle=tickIsHighlighted?highlightedTextStyle:null;graphie.style(lineStyle,()=>{results.push(graphie.line([tick,-0.2],[tick,.2]));});if(labelTicks||tickIsHighlighted){graphie.style(textStyle,()=>{results.push(_label(graphie,labelStyle,tick,tick,base));});}});return results});function isValid(props){const{range,divisionRange,snapDivisions}=props.options;let initialX=props.userInput?.numLinePosition;initialX=initialX==null?range[0]:initialX;return range[0]<range[1]&&number.sign(initialX-range[0])>=0&&number.sign(initialX-range[1])<=0&&divisionRange[0]<divisionRange[1]&&0<props.userInput?.numDivisions&&0<snapDivisions}const NumberLine=forwardRef(function NumberLine(props,ref){const{strings}=usePerseusI18n();const dependencies=useDependencies();const propsRef=useLatestRef(props);const[numDivisionsEmpty,setNumDivisionsEmpty]=useState(false);const tickStep=getTickStep(props.options.range,props.userInput.numDivisions);const graphieRef=useRef(null);const tickCtrlRef=useRef(null);useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"number-line",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({focus:()=>{if(props.options.isTickCtrl){tickCtrlRef.current?.focus();return true}return false},focusInputPath:path=>{if(path?.length===1){tickCtrlRef.current?.focus();}},blurInputPath:path=>{if(path?.length===1){tickCtrlRef.current?.blur();}},getInputPaths:()=>{if(props.options.isTickCtrl){return [["tick-ctrl"]]}return []},getDOMNodeForPath:inputPath=>{if(inputPath?.length===1){return ReactDOM__default.findDOMNode(tickCtrlRef.current)}return null},getSerializedState:()=>({alignment:props.alignment,static:props.static,range:props.options.range,labelRange:props.options.labelRange,labelStyle:props.options.labelStyle,labelTicks:props.options.labelTicks,divisionRange:props.options.divisionRange,snapDivisions:props.options.snapDivisions,isInequality:props.options.isInequality,showTooltips:props.options.showTooltips,isTickCtrl:props.options.isTickCtrl,numDivisions:props.userInput.numDivisions,numLinePosition:props.userInput.numLinePosition,rel:"ge"}),getPromptJSON(){return getPromptJSON$6(props)},movePosition}));const setupGraphie=useCallback((graphie,options)=>{const latestProps=propsRef.current;if(!isValid(latestProps)){return}const widthInPixels=getNumberLineWidthPx(latestProps.apiOptions.isMobile);const range=options.range;const scale=(range[1]-range[0])/widthInPixels;const buffer=horizontalPadding*scale;const left=range[0]-buffer;const right=range[1]+buffer;const{labelStyle}=latestProps.options;const hasFractionalLabels=labelStyle==="improper"||labelStyle==="mixed"||labelStyle==="non-reduced";const bottom=hasFractionalLabels?-1.5:-1;const top=1;graphie.init({range:[[left,right],[bottom,top]],scale:[1/scale,40],isMobile:latestProps.apiOptions.isMobile});const center=(range[0]+range[1])/2;graphie.line([center,0],[right,0],{arrows:"->"});graphie.line([center,0],[left,0],{arrows:"->"});},[propsRef]);function snapNumLinePosition(tickStep,numLinePosition){const{range,snapDivisions}=props.options;const left=range[0];const right=range[1];const snapX=tickStep/snapDivisions;let x=bound(numLinePosition,left,right);x=left+number.roundTo(x-left,snapX);assert(Number.isFinite(x));return x}function onNumDivisionsChange(numDivisions,cb){numDivisions=Math.round(numDivisions);numDivisions=numDivisions<0?numDivisions*-1:numDivisions;if(numDivisions){const newTickStep=getTickStep(props.options.range,numDivisions);const newNumLinePosition=snapNumLinePosition(newTickStep,props.userInput.numLinePosition);setNumDivisionsEmpty(false);props.handleUserInput({...props.userInput,numDivisions:numDivisions,numLinePosition:newNumLinePosition},cb);}else {setNumDivisionsEmpty(true);cb?.();}}function handleTickCtrlFocus(){props.onFocus(["tick-ctrl"]);}function handleTickCtrlBlur(){props.onBlur(["tick-ctrl"]);}function movePosition(targetPosition){props.handleUserInput({...props.userInput,numLinePosition:targetPosition});props.trackInteraction();}function handleReverse(){const newRel=reverseRel[props.userInput.rel];props.handleUserInput({...props.userInput,rel:newRel});}function handleToggleStrict(){const newRel=toggleStrictRel[props.userInput.rel];props.handleUserInput({...props.userInput,rel:newRel});}function renderNumberLinePoint(){const isOpen=["lt","gt"].includes(props.userInput.rel);const interactiveColor=tokenValue(semanticColor.core.foreground.instructive.default);const staticColor=tokenValue(semanticColor.core.foreground.disabled.strong);const knockoutColor=tokenValue(semanticColor.core.border.knockout.default);const hollowFill=tokenValue(semanticColor.core.foreground.knockout.default);const pointColor=props.static?staticColor:interactiveColor;const normalStyle={fill:isOpen?hollowFill:pointColor,stroke:isOpen?pointColor:knockoutColor,"stroke-width":isOpen?3:1};const highlightStyle={fill:isOpen?hollowFill:interactiveColor,"stroke-width":isOpen?3:1};const mobileDotStyle=props.options.isInequality&&isOpen?{fill:hollowFill,stroke:pointColor,"stroke-width":3}:{};return jsxRuntimeExports.jsx(MovablePoint,{ref:"numberLinePoint",pointSize:6,coord:[props.userInput.numLinePosition,0],constraints:[(coord,prevCoord)=>{return [coord[0],prevCoord[1]]},(coord,prevCoord)=>{const x=snapNumLinePosition(tickStep,coord[0]);return [x,coord[1]]}],shadow:!!props.apiOptions.isMobile&&!isOpen,normalStyle:normalStyle,highlightStyle:highlightStyle,onMove:coord=>{movePosition(coord[0]);},isMobile:props.apiOptions.isMobile,mobileStyleOverride:mobileDotStyle,showTooltips:props.options.showTooltips??false,xOnlyTooltip:true})}function getInequalityEndpoint(){const isGreater=["ge","gt"].includes(props.userInput.rel);const widthInPixels=getNumberLineWidthPx(props.apiOptions.isMobile);const range=props.options.range;const scale=(range[1]-range[0])/widthInPixels;const buffer=horizontalPadding*scale;const left=range[0]-buffer;const right=range[1]+buffer;const end=isGreater?[right,0]:[left,0];return end}function renderInequality(){if(props.options.isInequality){const end=getInequalityEndpoint();const style={arrows:"->",stroke:tokenValue(semanticColor.core.foreground.instructive.default),strokeWidth:3.5};return jsxRuntimeExports.jsx(Line,{start:[props.userInput.numLinePosition,0],end:end,style:style})}return null}function renderGraphie(){const range=props.options.range;return jsxRuntimeExports.jsxs(Graphie,{ref:graphieRef,box:[props.apiOptions.isMobile?MOBILE_BOX_WIDTH:DESKTOP_BOX_WIDTH,80],options:{range,isTickCtrl:props.options.isTickCtrl},onMouseDown:coord=>{const point=graphieRef.current?.movables.numberLinePoint;point?.grab(coord);},setup:setupGraphie,isMobile:props.apiOptions.isMobile,children:[jsxRuntimeExports.jsx(TickMarks,{range:props.options.range,labelTicks:props.options.labelTicks,labelStyle:props.options.labelStyle,labelRange:props.options.labelRange,tickStep:tickStep,numDivisions:props.userInput.numDivisions,isMobile:props.apiOptions.isMobile}),renderInequality(),renderNumberLinePoint()]},props.options.labelStyle)}const{divisionRange,isTickCtrl,isInequality}=props.options;const divRangeString=divisionRange[0]+EN_DASH+divisionRange[1];const invalidNumDivisions=props.userInput?.numDivisions<divisionRange[0]||props.userInput?.numDivisions>divisionRange[1];const inequalityControls=jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("input",{type:"button",className:"simple-button",value:strings.switchDirection,onClick:handleReverse}),jsxRuntimeExports.jsx("input",{type:"button",className:"simple-button",value:["le","ge"].includes(props.userInput?.rel)?strings.circleOpen:strings.circleFilled,onClick:handleToggleStrict})]});let tickCtrl;if(isTickCtrl){const Input=props.apiOptions.customKeypad?SimpleKeypadInput:NumberInput;tickCtrl=jsxRuntimeExports.jsxs("label",{children:[strings.numDivisions," ",jsxRuntimeExports.jsx(Input,{ref:tickCtrlRef,value:numDivisionsEmpty?null:props.userInput?.numDivisions||divisionRange[0],checkValidity:val=>val>=divisionRange[0]&&val<=divisionRange[1],onChange:onNumDivisionsChange,onFocus:handleTickCtrlFocus,onBlur:handleTickCtrlBlur,useArrowKeys:true,keypadElement:props.keypadElement})]});}return jsxRuntimeExports.jsxs("div",{className:"perseus-widget "+"perseus-widget-interactive-number-line",children:[tickCtrl,!isValid(props)?jsxRuntimeExports.jsx("div",{className:"perseus-error",children:"Invalid number line configuration."}):isTickCtrl&&invalidNumDivisions?jsxRuntimeExports.jsx("div",{className:"perseus-error",children:strings.divisions({divRangeString:divRangeString})}):renderGraphie(),!props.static&&isInequality&&inequalityControls]})});function getUserInputFromSerializedState$4(serializedState){return {numDivisions:serializedState.numDivisions,numLinePosition:serializedState.numLinePosition,rel:"eq"}}function getStartNumDivisions(options){const width=options.range[1]-options.range[0];let numDivisions;if(options.numDivisions!=null){numDivisions=options.numDivisions;}else if(options.tickStep!=null){numDivisions=width/options.tickStep;}else {numDivisions=undefined;}return numDivisions}function getTickStep(range,numDivisions){const[min,max]=range;const width=max-min;return width/numDivisions}function getCorrectUserInput$1(options){const numLinePosition=options.correctX!=null?options.correctX:options.range[0];return {numDivisions:getStartNumDivisions(options),numLinePosition,rel:options.isInequality&&options.correctRel||"eq"}}function getStartUserInput$4(options){const numLinePosition=options.initialX!=null?options.initialX:options.range[0];return {numDivisions:getStartNumDivisions(options),numLinePosition,rel:options.isInequality?"ge":"eq"}}var NumberLine$1 = {name:"number-line",displayName:"Number line",widget:NumberLine,getCorrectUserInput: getCorrectUserInput$1,getStartUserInput: getStartUserInput$4,getUserInputFromSerializedState: getUserInputFromSerializedState$4};
2068
-
2069
- const getPromptJSON$5=widgetData=>{return {type:"orderer",options:{options:widgetData.options.options.map(option=>option.content)},userInput:{values:widgetData.userInput.current}}};
2070
-
2071
- const noop=()=>{};class PlaceholderCard extends React.Component{render(){return jsxRuntimeExports.jsx("div",{className:"card-wrap",style:{width:this.props.width},children:jsxRuntimeExports.jsx("div",{className:"card placeholder",style:{height:this.props.width}})})}}class DragHintCard extends React.Component{render(){return jsxRuntimeExports.jsx("div",{className:"card-wrap",children:jsxRuntimeExports.jsx("div",{className:"card drag-hint"})})}}class Card extends React.Component{componentDidMount(){this.mouseMoveUpBound=false;document.addEventListener("touchmove",this.onMouseMove,Util.supportsPassiveEvents()?{passive:false}:false);}shouldComponentUpdate(nextProps,nextState){return this.props.floating||nextProps.floating||this.props.content!==nextProps.content||this.props.fakeRef!==nextProps.fakeRef}componentDidUpdate(prevProps,prevState){if(this.props.animating&&!prevProps.animating&&this.props.animateTo&&this.props.startOffset){const ms=15*Math.sqrt(Math.sqrt(Math.pow(this.props.animateTo.left-this.props.startOffset.left,2)+Math.pow(this.props.animateTo.top-this.props.startOffset.top,2)));$(ReactDOM__default.findDOMNode(this)).animate(this.props.animateTo,Math.max(ms,1),this.props.onAnimationEnd);}}componentWillUnmount(){if(this.mouseMoveUpBound){this.unbindMouseMoveUp();Util.resetTouchHandlers();}document.removeEventListener("touchmove",this.onMouseMove);}render(){let style={};if(this.props.floating){style={position:"absolute",left:this.props.startOffset?.left,top:this.props.startOffset?.top};}if(this.props.width){style.width=this.props.width;}const className=["card"];if(this.props.stack){className.push("stack");}if(this.props.floating&&!this.props.animating&&this.props.mouse&&this.props.startMouse){className.push("dragging");style.left+=this.props.mouse.left-this.props.startMouse.left;style.top+=this.props.mouse.top-this.props.startMouse.top;const hasNotMoved=this.props.mouse.left===this.props.startMouse.left&&this.props.mouse.top===this.props.startMouse.top;if(this.props.removing&&hasNotMoved){className.push("removing");}}const rendererProps={content:this.props.content};const onMouseDown=this.props.animating?noop:this.onMouseDown;return jsxRuntimeExports.jsx("div",{className:"card-wrap",style:style,onMouseDown:onMouseDown,onTouchStart:onMouseDown,onTouchEnd:this.onMouseUp,onTouchCancel:this.onMouseUp,children:jsxRuntimeExports.jsx("div",{className:className.join(" "),children:jsxRuntimeExports.jsx(Renderer,{...rendererProps,linterContext:this.props.linterContext,strings:this.context.strings,apiOptions:this.props.apiOptions})})})}constructor(...args){super(...args),this.state={dragging:false},this.bindMouseMoveUp=()=>{this.mouseMoveUpBound=true;$(document).on("mousemove",this.onMouseMove);$(document).on("mouseup",this.onMouseUp);},this.unbindMouseMoveUp=()=>{this.mouseMoveUpBound=false;$(document).off("mousemove",this.onMouseMove);$(document).off("mouseup",this.onMouseUp);},this.onMouseDown=event=>{event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.setState({dragging:true});this.bindMouseMoveUp();this.props.onMouseDown?.(loc,this);}},this.onMouseMove=event=>{if(!this.state.dragging){return}event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.props.onMouseMove?.(loc);}},this.onMouseUp=event=>{event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.setState({dragging:false});this.unbindMouseMoveUp();this.props.onMouseUp?.(loc);}};}}Card.contextType=PerseusI18nContext;Card.defaultProps={stack:false,removing:false,animating:false};class Orderer extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"orderer",widgetSubType:"null",widgetId:this.props.widgetId}});}getPromptJSON(){return getPromptJSON$5(this.props)}getSerializedState(){const{alignment,options,userInput}=this.props;return {alignment,static:this.props.static,options:options.options,current:userInput.current.map(e=>({content:e})),height:options.height,layout:options.layout,otherOptions:"otherOptions"in options?options.otherOptions:undefined,correctOptions:"correctOptions"in options?options.correctOptions:undefined}}render(){const dragging=this.state.dragging&&jsxRuntimeExports.jsx(Card,{ref:"dragging",apiOptions:this.props.apiOptions,floating:true,content:this.state.dragContent,startOffset:this.state.offsetPos,startMouse:this.state.grabPos,mouse:this.state.mousePos,width:this.state.dragWidth,removing:this.state.dragSource==="current",onMouseUp:this.onRelease,onMouseMove:this.onMouseMove,linterContext:this.props.linterContext},this.state.dragKey||"draggingCard");const animating=this.state.animating&&jsxRuntimeExports.jsx(Card,{apiOptions:this.props.apiOptions,floating:true,animating:true,content:this.state.dragContent,startOffset:this.state.offsetPos,width:this.state.dragWidth,animateTo:this.state.animateTo,onAnimationEnd:this.state.onAnimationEnd,linterContext:this.props.linterContext},this.state.dragKey||"draggingCard");const sortableCards=this.props.userInput.current.map((opt,i)=>{return jsxRuntimeExports.jsx(Card,{ref:"sortable"+i,apiOptions:this.props.apiOptions,fakeRef:"sortable"+i,floating:false,content:opt,linterContext:this.props.linterContext,onMouseDown:this.state.animating?noop:this.onClick.bind(null,"current",i)},`sortableCard${i}`)});if(this.state.placeholderIndex!=null){const placeholder=jsxRuntimeExports.jsx(PlaceholderCard,{ref:"placeholder",width:this.state.dragWidth,height:this.state.dragHeight},"placeholder");sortableCards.splice(this.state.placeholderIndex,0,placeholder);}const anySortableCards=sortableCards.length>0;sortableCards.push(dragging,animating);const sortable=jsxRuntimeExports.jsxs("div",{className:"perseus-clearfix draggable-box",children:[!anySortableCards&&jsxRuntimeExports.jsx(DragHintCard,{}),jsxRuntimeExports.jsx("div",{ref:"dragList",children:sortableCards})]});const bank=jsxRuntimeExports.jsx("div",{ref:"bank",className:"bank perseus-clearfix",children:this.props.options.options.map((opt,i)=>{return jsxRuntimeExports.jsx(Card,{ref:"bank"+i,apiOptions:this.props.apiOptions,floating:false,content:opt.content,stack:true,linterContext:this.props.linterContext,onMouseDown:this.state.animating?noop:this.onClick.bind(null,"bank",i),onMouseMove:this.onMouseMove,onMouseUp:this.onRelease},i)})});return jsxRuntimeExports.jsxs("div",{className:"draggy-boxy-thing orderer "+"height-"+this.props.options.height+" "+"layout-"+this.props.options.layout+" "+"blank-background "+"perseus-clearfix ",ref:"orderer",children:[bank,sortable]})}constructor(...args){super(...args),this.state={dragging:false,dragSource:null,placeholderIndex:null,dragKey:null,animating:false,dragContent:null,dragWidth:null,dragHeight:null,offsetPos:null,animateTo:null,grabPos:null},this.onClick=(type,index,loc,draggable)=>{const $draggable=$(ReactDOM__default.findDOMNode(draggable));const list=this.props.userInput.current.slice();let content;let placeholderIndex=null;if(type==="current"){list.splice(index,1);content=this.props.userInput.current[index];placeholderIndex=index;}else {content=this.props.options.options[index].content;}this.props.handleUserInput({current:list});this.setState({dragging:true,dragSource:type,placeholderIndex:placeholderIndex,dragContent:content,dragWidth:$draggable.width(),dragHeight:$draggable.height(),grabPos:loc,mousePos:loc,offsetPos:$draggable.position()});},this.onRelease=loc=>{const draggable=this.refs.dragging;if(draggable==null){return}const inCardBank=this.isCardInBank(draggable);const index=this.state.placeholderIndex||0;const onAnimationEnd=()=>{const list=this.props.userInput.current.slice();if(!inCardBank){const cardContent=this.state.dragContent;if(typeof cardContent==="string"){const newCard={content:cardContent,key:_.uniqueId("perseus_draggable_card_"),width:this.state.dragWidth};list.splice(index,0,newCard.content);}}this.props.handleUserInput({current:list});this.setState({dragging:false,dragSource:null,placeholderIndex:null,animating:false});this.props.trackInteraction();};const offset=$(ReactDOM__default.findDOMNode(draggable)).position();let finalOffset=null;if(inCardBank){this.props.options.options.forEach((opt,i)=>{if(opt.content===this.state.dragContent){const card=ReactDOM__default.findDOMNode(this.refs["bank"+i]);finalOffset=$(card).position();}});}else if(this.refs.placeholder!=null){finalOffset=$(ReactDOM__default.findDOMNode(this.refs.placeholder)).position();}if(finalOffset==null){onAnimationEnd();}else {this.setState({offsetPos:offset,animateTo:finalOffset,onAnimationEnd:onAnimationEnd,animating:true,dragging:false});}},this.onMouseMove=loc=>{const draggable=this.refs.dragging;if(draggable==null){return}let index;if(this.isCardInBank(draggable)){index=null;}else {index=this.findCorrectIndex(draggable,this.props.userInput.current);}this.setState({mousePos:loc,placeholderIndex:index});},this.findCorrectIndex=(draggable,list)=>{const isHorizontal=this.props.options.layout==="horizontal";const $dragList=$(ReactDOM__default.findDOMNode(this.refs.dragList));const leftEdge=$dragList.offset().left;const topEdge=$dragList.offset().top;const midWidth=$(ReactDOM__default.findDOMNode(draggable)).offset().left-leftEdge;const midHeight=$(ReactDOM__default.findDOMNode(draggable)).offset().top-topEdge;let index=0;let sumWidth=0;let sumHeight=0;if(isHorizontal){list.forEach((opt,i)=>{const card=ReactDOM__default.findDOMNode(this.refs["sortable"+i]);const outerWidth=$(card).outerWidth(true);if(midWidth>sumWidth+outerWidth/2){index+=1;}sumWidth+=outerWidth;});}else {list.forEach((_,i)=>{const card=ReactDOM__default.findDOMNode(this.refs["sortable"+i]);const outerHeight=$(card).outerHeight(true);if(midHeight>sumHeight+outerHeight/2){index+=1;}sumHeight+=outerHeight;});}return index},this.isCardInBank=draggable=>{if(draggable==null){return false}const isHorizontal=this.props.options.layout==="horizontal";const $draggable=$(ReactDOM__default.findDOMNode(draggable));const $bank=$(ReactDOM__default.findDOMNode(this.refs.bank));const draggableOffset=$draggable.offset();const bankOffset=$bank.offset();const draggableHeight=$draggable.outerHeight(true);const bankHeight=$bank.outerHeight(true);const bankWidth=$bank.outerWidth(true);const draggableWidth=$draggable.outerWidth(true);if(isHorizontal){return draggableOffset.top+draggableHeight/2<bankOffset.top+bankHeight}return draggableOffset.left+draggableWidth/2<bankOffset.left+bankWidth},this.setListValues=values=>{this.props.handleUserInput({current:values});};}}function getUserInputFromSerializedState$3(serializedState){return {current:serializedState.current.map(e=>e.content)}}function getStartUserInput$3(){return {current:[]}}const WrappedOrderer=withDependencies(Orderer);var Orderer$1 = {name:"orderer",displayName:"Orderer",hidden:true,widget:WrappedOrderer,isLintable:true,getStartUserInput: getStartUserInput$3,getUserInputFromSerializedState: getUserInputFromSerializedState$3};
2072
-
2073
- const getPromptJSON$4=()=>{return getUnsupportedPromptJSON("phet-simulation")};
2074
-
2075
- const isFullscreenApiSupported=()=>{if(typeof document==="undefined"){return false}const doc=document;return Boolean(doc.fullscreenEnabled||doc.webkitFullscreenEnabled)};const MOBILE_APP_BOTTOM_BAR_HEIGHT=66;class PhetSimulation extends React.Component{async componentDidMount(){await this.updateSimState(this.props.options.url);}async componentDidUpdate(prevProps){if(prevProps.options.url!==this.props.options.url){await this.updateSimState(this.props.options.url);}}getLocale(){switch(this.context.locale){case "pt-pt":return "pt";case "zh-hans":return "zh_CN";case "zh-hant":return "zh_TW";case "fa-af":return "fa_DA";default:return this.context.locale}}getPromptJSON(){return getPromptJSON$4()}async updateSimState(urlString){const url=makeSafeUrl(urlString,this.getLocale(),"https://phet.colorado.edu");if(url===null){this.displayLoadFailure();return}const response=await fetch(url);if(!response.ok){this.displayLoadFailure();return}const showLocaleWarning=await this.showLocaleWarning(url);this.setState({url:url,banner:showLocaleWarning?{message:this.context.strings.simulationLocaleWarning,kind:"warning"}:null});}async showLocaleWarning(url){if(!url){return false}const phetRegex=/https:\/\/phet\.colorado\.edu\/sims\/html\/([a-zA-Z0-9-]+)\/.*/g;const match=phetRegex.exec(url.toString());if(match===null){return false}const simName=match[1];const response=await fetch(`https://phet.colorado.edu/sims/html/${simName}/latest/string-map.json`);if(!response.ok){return false}let responseJson;try{responseJson=await response.json();}catch{return false}const locales=Object.keys(responseJson);const baseLocale=this.getLocale().split("_")[0];for(const l of locales){if(baseLocale===l.split("_")[0]){return false}}return true}renderCornerButton(url,isMobileApp){if(isMobileApp||isFullscreenApiSupported()){return jsxRuntimeExports.jsx(IconButton,{icon:cornersOutIcon,onClick:isMobileApp?this.toggleFullScreen:this.requestIframeFullscreen,kind:"secondary",actionType:"neutral","aria-label":this.context.strings.fullscreen,style:styles$7.cornerButton})}return jsxRuntimeExports.jsx(IconButton,{icon:arrowSquareOutIcon,href:url.toString(),target:"_blank",kind:"secondary",actionType:"neutral","aria-label":this.context.strings.openInNewTab,style:styles$7.cornerButton})}render(){const{isFullScreen,banner,url}=this.state;const{isMobileApp}=this.props.apiOptions;const isMobileAppFullscreen=isFullScreen&&isMobileApp;const containerStyle=isMobileAppFullscreen?{...styles$7.appFullScreenWidgetContainer}:styles$7.widgetContainer;const iframeContainerStyle=isMobileAppFullscreen?styles$7.appFullScreenIframeContainer:styles$7.iframeContainer;const sandboxProperties="allow-same-origin allow-scripts";return jsxRuntimeExports.jsxs(View,{style:containerStyle,children:[banner!==null&&jsxRuntimeExports.jsx(View,{style:{marginBlockEnd:phoneMargin},children:jsxRuntimeExports.jsx(Banner,{kind:banner.kind,text:banner.message})}),isMobileAppFullscreen&&jsxRuntimeExports.jsx(View,{style:styles$7.closeButtonContainer,children:jsxRuntimeExports.jsx(IconButton,{icon:xIcon,onClick:this.toggleFullScreen,kind:"secondary",actionType:"neutral","aria-label":this.context.strings.exitFullscreen})}),jsxRuntimeExports.jsx(View,{style:iframeContainerStyle,children:jsxRuntimeExports.jsx("iframe",{ref:this.iframeRef,title:this.props.options.description,sandbox:sandboxProperties,className:css(styles$7.iframeResponsive),src:url?.toString(),allow:"fullscreen"})}),url!==null&&!isMobileAppFullscreen&&this.renderCornerButton(url,isMobileApp)]})}constructor(...args){super(...args),this.iframeRef=React.createRef(),this.isWidget=true,this.state={url:null,banner:null,isFullScreen:false},this.displayLoadFailure=()=>{this.setState({url:null,banner:{message:this.context.strings.simulationLoadFail,kind:"critical"}});},this.toggleFullScreen=()=>{this.setState(prevState=>({isFullScreen:!prevState.isFullScreen}));},this.requestIframeFullscreen=()=>{const iframe=this.iframeRef.current;if(!iframe){return}if(typeof iframe.requestFullscreen==="function"){iframe.requestFullscreen().catch(()=>{});}else {iframe.webkitRequestFullscreen?.();}};}}PhetSimulation.contextType=PerseusI18nContext;const styles$7=StyleSheet.create({widgetContainer:{borderRadius:border$1.radius.radius_080,borderWidth:border$1.width.thin,borderColor:semanticColor.core.border.neutral.subtle,padding:sizing.size_160,paddingBlockEnd:0},cornerButton:{marginBlockStart:5,marginBlockEnd:5,alignSelf:"flex-end"},iframeContainer:{position:"relative",overflow:"hidden",width:"100%",paddingBlockStart:"56.25%"},iframeResponsive:{borderWidth:border$1.width.none,position:"absolute",insetBlockStart:0,insetInlineStart:0,insetBlockEnd:0,insetInlineEnd:0,width:"100%",height:"100%"},appFullScreenWidgetContainer:{position:"fixed",insetBlockStart:0,insetInlineStart:0,insetInlineEnd:0,insetBlockEnd:MOBILE_APP_BOTTOM_BAR_HEIGHT,width:"100%",height:"auto",zIndex:1e3,backgroundColor:semanticColor.core.background.base.default,display:"flex",flexDirection:"column"},appFullScreenIframeContainer:{position:"relative",overflow:"hidden",width:"100%",flex:1},closeButtonContainer:{position:"absolute",insetBlockStart:sizing.size_080,insetInlineEnd:sizing.size_080,zIndex:1001}});var PhetSimulation$1 = {name:"phet-simulation",displayName:"PhET Simulation",widget:PhetSimulation,isLintable:true};
2076
-
2077
- const getPromptJSON$3=()=>{return getUnsupportedPromptJSON("plotter")};
2078
-
2079
- class Plotter extends React.Component{componentDidMount(){this._isMounted=true;this.setupGraphie(this.props.userInput);this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"plotter",widgetSubType:"null",widgetId:this.props.widgetId}});}UNSAFE_componentWillReceiveProps(nextProps){const optionsKeys=["type","labels","categories","scaleY","maxY","snapsPerLine","picUrl","labelInterval"];const options=this.props.options;const nextOptions=nextProps.options;this.shouldSetupGraphie=this.props.static!==nextProps.static||optionsKeys.some(key=>!_.isEqual(options[key],nextOptions[key]));if(!_.isEqual(options.starting,nextOptions.starting)&&!_.isEqual(this.props.userInput,nextOptions.starting)){this.shouldSetupGraphie=true;this.props.handleUserInput(nextOptions.starting);}}componentDidUpdate(prevProps,prevState){this.shouldSetupGraphie=this.shouldSetupGraphie||!_.isEqual(this.state.categoryHeights,prevState.categoryHeights);if(this.shouldSetupGraphie){this.setupGraphie(prevProps.userInput);}}componentWillUnmount(){this._isMounted=false;}setupGraphie(prevValues){const self=this;self.shouldSetupGraphie=false;this.graphieDiv.current.innerHTML="";const graphie=GraphUtils.createGraphie(this.graphieDiv.current);self.graphie=graphie;self.graphie.pics=[];self.graphie.dotTicks=[];const isBar=self.props.options.type==="bar";const isLine=self.props.options.type==="line";const isPic=self.props.options.type==="pic";const isHistogram=self.props.options.type==="histogram";const isDotplot=self.props.options.type==="dotplot";const isTiledPlot=isPic||isDotplot;const config={};const c=config;const isMobile=this.props.apiOptions.isMobile;c.graph={lines:[],bars:[],points:[],dividers:[]};c.scaleY=self.props.options.scaleY;c.dimX=self.props.options.categories.length;const plotDimensions=isMobile?[288,336]:self.props.options.plotDimensions;if(isLine){c.dimX+=isMobile?-0.2:1;}else if(isHistogram){c.barPad=0;c.barWidth=1;}else if(isBar){c.barPad=isMobile?.08:.15;c.barWidth=1-2*c.barPad;c.dimX+=(isMobile?-2:2)*c.barPad;}else if(isTiledPlot){c.picBoxHeight=self.props.options.picBoxHeight;c.picBoxWidthPx=plotDimensions[0]/self.props.options.categories.length;const picPadAllWidth=plotDimensions[0]-c.dimX*c.picBoxWidthPx;c.picPad=picPadAllWidth/(2*c.dimX+2);const picFullWidth=c.picBoxWidthPx+2*c.picPad;c.picPad=c.picPad/picFullWidth;c.picBoxWidth=c.picBoxWidthPx/picFullWidth;c.dimX+=2*c.picPad;}if(isDotplot){c.picBoxHeight=this.DOT_PLOT_POINT_SIZE()*2+this.DOT_PLOT_POINT_PADDING();}c.dimY=Math.ceil(self.props.options.maxY/c.scaleY)*c.scaleY;let padX=25;if((isBar||isLine)&&isMobile){padX=self.props.options.labels[1].length!==0?17:11;}if(isDotplot){padX/=2;}if(isMobile&&isTiledPlot&&self.props.options.labels[1].length===0){padX=0;}let padTop=25;let padBottom=25*3;if(isMobile&&(isBar||isTiledPlot)){const maxCategoryHeight=Math.max(0,...Object.values(self.state.categoryHeights));if(maxCategoryHeight){let offsetY=25;if(isTiledPlot){offsetY+=10;}padBottom=offsetY+maxCategoryHeight;}}if(isMobile){c.scale=[(plotDimensions[0]-padX*4)/c.dimX,(plotDimensions[1]-(padTop+padBottom))/c.dimY];}else {c.scale=[c.dimX,c.dimY].map(function(dim,i){return plotDimensions[i]/dim});}if(isTiledPlot){c.scale[1]=c.picBoxHeight/c.scaleY;}padX/=c.scale[0];padTop/=c.scale[1];padBottom/=c.scale[1];graphie.init({range:[[-3*padX,c.dimX+padX],[-padBottom,c.dimY+padTop]],scale:c.scale,isMobile:this.props.apiOptions.isMobile});graphie.addMouseLayer({allowScratchpad:true});if(!isTiledPlot){const initialY=isMobile?c.scaleY:0;for(let y=initialY;y<=c.dimY;y+=c.scaleY){graphie.label([0,y],KhanMath.roundToApprox(y,2),"left",true);graphie.style({stroke:tokenValue(semanticColor.core.border.neutral.default),strokeWidth:1,opacity:1},function(){graphie.line([0,y],[c.dimX,y]);});}}if((isBar||isLine)&&isMobile&&!this.props.static){self.graphie.dragPrompt=graphie.label([c.dimX/2,c.dimY/2],this.context.strings.dragHandles,"center",false).css("font-weight",font.weight.bold).css("color",tokenValue(semanticColor.core.foreground.neutral.strong)).css("display","none");}self.setupCategories(config);if(isTiledPlot&&isMobile){self.graphie.dotPrompt=graphie.label([c.dimX/2,c.dimY/2],this.context.strings.tapAddPoints,"center",false).css("font-weight",font.weight.bold).css("color",semanticColor.core.foreground.neutral.strong).css("display","none");}if(isTiledPlot){self.drawPicHeights(self.props.userInput,prevValues);}graphie.style({stroke:tokenValue(semanticColor.core.border.neutral.strong),strokeWidth:2,opacity:1},function(){if(isTiledPlot){if(isDotplot){graphie.line([isMobile?0:.5,0],[c.dimX-(isMobile?0:.5),0]);}else {graphie.line([0,0],[c.dimX,0]);if(self.props.options.labels[1].length!==0||!isMobile){graphie.line([0,0],[0,c.dimY]);}}}else {graphie.line([isMobile?-padX*3:0,0],[c.dimX+(isMobile?padX:0),0]);if(!((isBar||isLine)&&isMobile)){graphie.line([0,0],[0,c.dimY]);}}});graphie.label([c.dimX/2,isMobile?-padBottom:-35/c.scale[1]],self.props.options.labels[0],isMobile?"above":"below",false).css("color",tokenValue(semanticColor.core.foreground.neutral.strong)).css("font-weight",font.weight.bold);graphie.label([(isMobile?-35:-60)/c.scale[0],c.dimY/2],self.props.options.labels[1],"center",false).css("color",tokenValue(semanticColor.core.foreground.neutral.strong)).css("font-weight",font.weight.bold).addClass("rotate");if(this.props.apiOptions.isMobile){this.horizHairline=new WrappedLine(this.graphie,[0,0],[0,0],{normalStyle:{strokeWidth:1}});this.horizHairline.attr({stroke:tokenValue(semanticColor.core.border.instructive.default)});this.horizHairline.hide();this.hairlineRange=[[0,c.dimX],[0,c.dimY]];}}_testInsertUserInput(userInput){this.props.handleUserInput(userInput);}drawPicHeights(values,prevValues){const self=this;const graphie=self.graphie;const pics=graphie.pics;const isMobile=this.props.apiOptions.isMobile;if(isMobile){const shouldDisplay=values.every(v=>v===0);graphie.dotPrompt[0].style.display=shouldDisplay?"inline":"none";}_.each(pics,function(ps,i){_.each(ps,function(pic,j){const y=(j+1)*self.props.options.scaleY;const show=y<=values[i];if(self.props.options.type==="dotplot"){const wasShown=y<=prevValues[i];const wasJustShown=show&&!wasShown;if(wasJustShown){pic.animate({"stroke-width":8},75,()=>pic.animate({"stroke-width":2},75));}}pic[0].style.display=show?"inline":"none";graphie.dotTicks[i][j][0].style.display=show||!isMobile?"none":"inline";});});}getPromptJSON(){return getPromptJSON$3()}getSerializedState(){const{alignment,options,userInput}=this.props;return {alignment,static:this.props.static,scaleY:options.scaleY,maxY:options.maxY,snapsPerLine:options.snapsPerLine,starting:options.starting,type:options.type,labels:options.labels,categories:options.categories,picSize:options.picSize,picBoxHeight:options.picBoxHeight,plotDimensions:options.plotDimensions,labelInterval:options.labelInterval,picUrl:options.picUrl,values:userInput,correct:"correct"in options?options.correct:undefined}}render(){const paddingForBottomLabel=75;const style={marginBottom:this.props.options.labels[0]?paddingForBottomLabel:0};return jsxRuntimeExports.jsx("div",{className:"perseus-widget-plotter graphie",ref:this.graphieDiv,style:style})}constructor(...args){super(...args),this._isMounted=false,this.graphieDiv=React.createRef(),this.state={categoryHeights:{}},this.DOT_PLOT_POINT_SIZE=()=>{return this.props.apiOptions.isMobile?6:4},this.DOT_PLOT_POINT_PADDING=()=>{return 8},this.DOT_TICK_POINT_SIZE=()=>{return 2},this.showHairlines=point=>{if(this.props.apiOptions.isMobile){this.horizHairline.moveTo([this.hairlineRange[0][0],point[1]],[this.hairlineRange[0][1],point[1]]);this.horizHairline.show();}},this.hideHairlines=()=>{if(this.props.apiOptions.isMobile){this.horizHairline.hide();}},this.labelCategory=(x,category)=>{const isMobile=this.props.apiOptions.isMobile;const graphie=this.graphie;category=category+"";let isTeX=false;const mathyCategory=category.match(/^\$(.*)\$$/);if(mathyCategory){category=mathyCategory[1];isTeX=true;}const translateX=5;const rotationDeg=45;const rotationRad=rotationDeg*(Math.PI/180);const labelRotation=`translateX(-50%) translateX(${translateX}px) `+`translateY(-50%) rotate(-${rotationDeg}deg)`;const shouldRotate=isMobile&&!mathyCategory;return new Promise(resolve=>{graphie.style({color:tokenValue(semanticColor.core.foreground.neutral.strong),transform:shouldRotate?labelRotation:"none",transformOrigin:"100%"},()=>{const $span=graphie.label([x,isMobile?-0.5:0],category,"below",isTeX);const height=14+(shouldRotate?Math.round($span.height()*Math.cos(rotationRad)+($span.width()+translateX)*Math.sin(rotationRad)):$span.height());resolve({category,height});});})},this.setupCategories=config=>{const self=this;const c=config;const graphie=self.graphie;const isMobile=this.props.apiOptions.isMobile;const categoryHeightPromises=[];if(self.props.options.type==="histogram"){_.times(self.props.options.categories.length-1,function(i){self.setupBar({index:i,startHeight:self.props.userInput[i],config:config,isHistogram:true});});_.each(self.props.options.categories,function(category,i){const x=.5+i*c.barWidth;categoryHeightPromises.push(self.labelCategory(x,category));const tickHeight=6/c.scale[1];graphie.style({stroke:tokenValue(semanticColor.core.border.neutral.strong),strokeWidth:2,opacity:1},function(){graphie.line([x,-tickHeight],[x,0]);});});}else {_.each(self.props.options.categories,function(category,i){const startHeight=self.props.userInput[i];let x;if(self.props.options.type==="bar"){x=self.setupBar({index:i,startHeight:startHeight,config:config,isHistogram:false});}else if(self.props.options.type==="line"){x=self.setupLine(i,startHeight,config);}else if(self.props.options.type==="pic"){x=self.setupPic(i,config);}else if(self.props.options.type==="dotplot"){x=self.setupDotplot(i,config);}let tickStart=0;let tickEnd=-6/c.scale[1];if(self.props.options.type==="dotplot"&&!isMobile){tickStart=-tickEnd;}if(self.props.options.type==="dotplot"){if(i%self.props.options.labelInterval===0||i===self.props.options.categories.length-1){categoryHeightPromises.push(self.labelCategory(x,category));tickStart*=1.5;tickEnd*=1.5;}}else {categoryHeightPromises.push(self.labelCategory(x,category));}graphie.style({stroke:tokenValue(semanticColor.core.border.neutral.strong),strokeWidth:2,opacity:1},function(){graphie.line([x,tickStart],[x,tickEnd]);});});}Promise.all(categoryHeightPromises).then(measurements=>{if(self._isMounted){const categoryHeights={};measurements.forEach(({category,height})=>categoryHeights[category]=height);self.setState({categoryHeights});}});},this._clampValue=(v,min,max)=>{return Math.max(Math.min(v,max),min)},this._maybeShowDragPrompt=()=>{if(this.graphie.dragPrompt!=null){this.graphie.dragPrompt[0].style.display="inline";}},this._maybeHideDragPrompt=()=>{if(this.graphie.dragPrompt!=null){this.graphie.dragPrompt[0].style.display="none";}},this.setupBar=args=>{const isMobile=this.props.apiOptions.isMobile;const i=args.index;const startHeight=args.startHeight;const config=args.config;const isHistogram=args.isHistogram;const self=this;const graphie=self.graphie;const barHalfWidth=config.barWidth/2;let x;if(isHistogram){x=.5+i*config.barWidth+barHalfWidth;}else {x=(isMobile?barHalfWidth:.5+config.barPad)+i;}const scaleBar=function(i,height){const center=graphie.scalePoint(0);config.graph.bars[i].scale(1,Math.max(isMobile?.2:.01,height/config.scaleY),center[0],center[1]);if(isHistogram){const leftDivider=config.graph.dividers[i-1];const rightDivider=config.graph.dividers[i];if(leftDivider){const divHeight=Math.min(self.props.userInput[i-1],height);leftDivider.scale(1,Math.max(.01,divHeight/config.scaleY),center[0],center[1]);}if(rightDivider){const divHeight=Math.min(self.props.userInput[i+1],height);rightDivider.scale(1,Math.max(.01,divHeight/config.scaleY),center[0],center[1]);}}};graphie.style({stroke:"none",fill:tokenValue(semanticColor.core.foreground.instructive.subtle),opacity:1},function(){config.graph.bars[i]=graphie.path([[x-barHalfWidth,0],[x-barHalfWidth,config.scaleY],[x+barHalfWidth,config.scaleY],[x+barHalfWidth,0],[x-barHalfWidth,0]]);});if(isHistogram){if(i>0){graphie.style({stroke:tokenValue(semanticColor.core.border.knockout.default),strokeWidth:1},function(){config.graph.dividers.push(graphie.path([[x-barHalfWidth,0],[x-barHalfWidth,config.scaleY]]));});}}if(isMobile){const snap=config.scaleY/self.props.options.snapsPerLine;config.graph.lines[i]=Interactive2.addMovablePointV2(this,{coord:[x,startHeight],constraints:[(coord,prev,options)=>{return [x,this._clampValue(Math.round(coord[1]/snap)*snap,0,config.dimY)]}],onMove:function(){const y=config.graph.lines[i].coord()[1];const values=[...self.props.userInput];values[i]=y;self.changeAndTrack(values);self._maybeHideDragPrompt();scaleBar(i,y);}});config.graph.lines[i].state.visibleShape.wrapper.style.zIndex="1";self._maybeShowDragPrompt();}else {config.graph.lines[i]=graphie.addMovableLineSegment({coordA:[x-barHalfWidth,startHeight],coordZ:[x+barHalfWidth,startHeight],snapY:config.scaleY/self.props.options.snapsPerLine,constraints:{constrainX:true},normalStyle:{stroke:tokenValue(semanticColor.core.foreground.instructive.default),"stroke-width":this.props.static?0:4}});config.graph.lines[i].onMove=function(dx,dy){let y=this.coordA[1];if(y<0||y>config.dimY){y=Math.min(Math.max(y,0),config.dimY);this.coordA[1]=this.coordZ[1]=y;this.transform();}const values=[...self.props.userInput];values[i]=y;self.changeAndTrack(values);scaleBar(i,y);};}scaleBar(i,startHeight);return x},this.setupLine=(i,startHeight,config)=>{const isMobile=this.props.apiOptions.isMobile;const self=this;const c=config;const graphie=self.graphie;const x=i+(isMobile?.4:1);const snap=config.scaleY/self.props.options.snapsPerLine;c.graph.points[i]=Interactive2.addMovablePointV2(this,{coord:[x,startHeight],constraints:[coord=>{return [x,this._clampValue(Math.round(coord[1]/snap)*snap,0,config.dimY)]}],onMove:function(){const y=c.graph.points[i].coord()[1];const values=[...self.props.userInput];values[i]=y;self.changeAndTrack(values);self._maybeHideDragPrompt();}});self._maybeShowDragPrompt();if(i>0){c.graph.lines[i]=Interactive2.addMovableLine(graphie,{points:[c.graph.points[i-1],c.graph.points[i]],constraints:Interactive2.MovablePoint.constraints.fixed(),normalStyle:{stroke:tokenValue(semanticColor.core.border.instructive.default),"stroke-width":2},highlightStyle:{stroke:tokenValue(semanticColor.core.border.instructive.default),"stroke-width":2}});}return x},this.setupDotplot=(i,config)=>{const graphie=this.graphie;const isMobile=this.props.apiOptions.isMobile;return this.setupTiledPlot(i,isMobile?.5:1,config,(x,y)=>{return graphie.ellipse([x,y],[this.DOT_PLOT_POINT_SIZE()/graphie.scale[0],this.DOT_PLOT_POINT_SIZE()/graphie.scale[1]],{fill:tokenValue(semanticColor.core.foreground.instructive.default),stroke:tokenValue(semanticColor.core.foreground.instructive.default)})})},this.setupPic=(i,config)=>{const graphie=this.graphie;return this.setupTiledPlot(i,0,config,(x,y)=>{const scaledCenter=graphie.scalePoint([x,y]);const size=this.props.options.picSize;return graphie.raphael.image(this.props.options.picUrl,scaledCenter[0]-size/2,scaledCenter[1]-size/2,size,size)})},this.setupTiledPlot=(i,bottomMargin,config,createImage)=>{const self=this;const c=config;const graphie=self.graphie;const pics=graphie.pics;const dotTicks=graphie.dotTicks;const x=i+.5+c.picPad;graphie.mouselayer.canvas.style.touchAction="none";pics[i]=[];dotTicks[i]=[];const n=Math.round(c.dimY/c.scaleY)+1;_(n).times(function(j){j-=1;const midY=(j+.5)*c.scaleY;const leftX=x-c.picBoxWidth/2;const topY=midY+.5*c.scaleY;const coord=graphie.scalePoint([leftX,topY+bottomMargin]);const mouseRect=graphie.mouselayer.rect(coord[0],coord[1],c.picBoxWidthPx,c.picBoxHeight);$(mouseRect[0]).css({fill:"transparent",opacity:0,cursor:"pointer"}).on("vmousedown",function(e){e.preventDefault();self.whichPicClicked=i;self.setPicHeight(i,topY);$(document).on("vmouseup.plotTile",function(e){$(document).unbind(".plotTile");});$(document).on("vmousemove.plotTile",function(e){e.preventDefault();const yCoord=graphie.getMouseCoord(e)[1];const adjustedCoord=Math.floor(yCoord-bottomMargin);const newJ=Math.max(-1,Math.floor(adjustedCoord/c.scaleY));const newMidY=(newJ+.5)*c.scaleY;const newTopY=Math.min(newMidY+.5*c.scaleY,c.dimY);self.setPicHeight(self.whichPicClicked,newTopY);});});if(j<0){return}pics[i][j]=createImage(x,midY+bottomMargin);dotTicks[i][j]=graphie.ellipse([x,midY+bottomMargin],[self.DOT_TICK_POINT_SIZE()/graphie.scale[0],self.DOT_TICK_POINT_SIZE()/graphie.scale[1]],{fill:tokenValue(semanticColor.core.border.neutral.subtle),stroke:tokenValue(semanticColor.core.border.neutral.subtle)});});return x},this.setPicHeight=(i,y)=>{const values=[...this.props.userInput];values[i]=y;this.drawPicHeights(values,this.props.userInput);this.changeAndTrack(values);},this.changeAndTrack=userInput=>{this.props.handleUserInput(userInput);this.props.trackInteraction();};}}Plotter.contextType=PerseusI18nContext;function getStartUserInput$2(options){return options.starting}function getCorrectUserInput(options){return options.correct}function getUserInputFromSerializedState$2(serializedState){return serializedState.values}const WrappedPlotter=withDependencies(Plotter);var Plotter$1 = {name:"plotter",displayName:"Plotter",hidden:true,widget:WrappedPlotter,getCorrectUserInput,getStartUserInput: getStartUserInput$2,getUserInputFromSerializedState: getUserInputFromSerializedState$2};
2080
-
2081
- const getPromptJSON$2=()=>{return getUnsupportedPromptJSON("python-program")};
2082
-
2083
- function getUrlFromProgramID(programID){return `/python-program/${programID}/embedded`}const PythonProgram=forwardRef(function PythonProgram(props,ref){const{strings,locale}=usePerseusI18n();const dependencies=useDependencies();const{programID,height}=props.options;useImperativeHandle(ref,()=>({getPromptJSON:()=>{return getPromptJSON$2()}}));const url=dependencies.generateUrl({url:getUrlFromProgramID(programID),context:"python_program:program_url",kaLocale:locale});const iframeStyle={height,width:"100%"};const sandboxOptions=["allow-popups","allow-same-origin","allow-scripts","allow-top-navigation"].join(" ");return jsxRuntimeExports.jsx(View,{style:styles$6.container,children:jsxRuntimeExports.jsx("iframe",{title:strings.pythonProgram,sandbox:sandboxOptions,src:url,style:iframeStyle,allowFullScreen:true})})});const styles$6=StyleSheet.create({container:{margin:"auto",width:"100%"}});var PythonProgram$1 = {name:"python-program",displayName:"Python Program",widget:PythonProgram};
2084
-
2085
- const tempDndStrings={moveTo:"Move to",clear:"Clear",moveToTarget:({target})=>`Move to ${target}`,clearTarget:({target})=>`Clear from ${target}`,actionsMenu:"Actions menu",menuRemaining:({num})=>`${num} remaining.`,choices:"Choices",blankLabel:({num})=>`Blank ${num}`,movedToTarget:({tile,target})=>`${tile} moved to ${target}.`,returnedToChoices:({tile})=>`${tile} returned to Choices.`};
2086
-
2087
- var styles$5 = {"opener":"perseus_9tV0b4Tg","menuHeader":"perseus_BmGXIgIP"};
2088
-
2089
- function assignRef(ref,value){if(typeof ref==="function"){ref(value);}else if(ref){ref.current=value;}}const MergedRefOpener=React.forwardRef(function MergedRefOpener({openerRef,...rest},injectedRef){const mergedRef=React.useCallback(node=>{assignRef(injectedRef,node);assignRef(openerRef,node);},[injectedRef,openerRef]);return jsxRuntimeExports.jsx(CustomOpener,{ref:mergedRef,...rest})});
2090
-
2091
- const DndActionMenu=React.forwardRef(function DndActionMenu(props,ref){const{tileLabel,remainingUses,moveTargets,onMove,clearFromLabel,onClear}=props;const descriptionId=useId();const description=remainingUses!=null?`${tempDndStrings.menuRemaining({num:remainingUses})} ${tempDndStrings.actionsMenu}`:tempDndStrings.actionsMenu;const menuItems=[];if(moveTargets.length>0){menuItems.push(jsxRuntimeExports.jsx("span",{"aria-hidden":"true",className:styles$5.menuHeader,children:jsxRuntimeExports.jsx("span",{"aria-hidden":"true",onClick:event=>event.stopPropagation(),children:tempDndStrings.moveTo})},"header"),...moveTargets.map(target=>jsxRuntimeExports.jsx(ActionItem,{label:target.label,"aria-label":tempDndStrings.moveToTarget({target:target.label}),onClick:()=>onMove(target.id),style:menuItemStyle},target.id)));}if(clearFromLabel!=null&&onClear!=null){if(menuItems.length>0){menuItems.push(jsxRuntimeExports.jsx(SeparatorItem,{},"separator"));}menuItems.push(jsxRuntimeExports.jsx(ActionItem,{label:tempDndStrings.clear,"aria-label":tempDndStrings.clearTarget({target:clearFromLabel}),onClick:onClear,style:menuItemStyle},"clear"));}const isDisabled=menuItems.length===0;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("span",{id:descriptionId,"aria-hidden":"true",className:a11yStyles.srOnly,children:description}),jsxRuntimeExports.jsx(ActionMenu,{menuText:tileLabel,disabled:isDisabled,alignment:"auto-start",dropdownStyle:{minInlineSize:"16rem"},opener:()=>jsxRuntimeExports.jsx(MergedRefOpener,{openerRef:ref,disabled:isDisabled,"aria-label":tileLabel,"aria-describedby":descriptionId,className:styles$5.opener,children:jsxRuntimeExports.jsx(PhosphorIcon,{icon:dotsSixVerticalIcon,size:"medium"})}),children:menuItems})]})});const menuItemStyle={minBlockSize:sizing.size_480};
2092
-
2093
- var styles$4 = {"tile":"perseus_qpv2o-UT","correct":"perseus_0XFKY082","incorrect":"perseus_ghbQ7P76","unused":"perseus_Dm74piVQ","draggable":"perseus_eEmqTX3y","dragging":"perseus_zW04-Nzj","hidesMenuAtRest":"perseus_6zUIp9cw","startContainer":"perseus_7QEk5x84","content":"perseus_Rs5O8PGP","fillsBlank":"perseus_lgaXSA9e","compact":"perseus_K7FBWZPW"};
2094
-
2095
- function AnswerTile(props){const{content,label,scoring,moveTargets,onMove,clearFromLabel,onClear,remainingUses,menuRef,tileId,fromBlankId,hidesMenuAtRest,fillsBlank,onContentRender,imageHeight,compact}=props;const{strings}=usePerseusI18n();const isDraggable=scoring==null;const dragData={tileId,fromBlankId};const{ref:dragRef,isDragging}=useDraggable$1({id:tileDragId(dragData),data:dragData,disabled:!isDraggable});const isEmpty=content.trim()==="";const tileClasses=classNames$2(styles$4.tile,scoring!=null&&styles$4[scoring],isDraggable&&styles$4.draggable,isDragging&&styles$4.dragging,hidesMenuAtRest&&styles$4.hidesMenuAtRest,fillsBlank&&styles$4.fillsBlank,compact&&styles$4.compact);const renderTileStart=()=>{if(scoring==="unused"){return null}if(scoring!=null){return jsxRuntimeExports.jsx("div",{className:styles$4.startContainer,children:jsxRuntimeExports.jsx(PhosphorIcon,{"aria-hidden":"true",icon:scoredIcons[scoring],size:"medium"})})}return jsxRuntimeExports.jsx("div",{className:styles$4.startContainer,children:jsxRuntimeExports.jsx(DndActionMenu,{ref:menuRef,tileLabel:label,moveTargets:moveTargets,onMove:onMove,clearFromLabel:clearFromLabel,onClear:onClear,remainingUses:remainingUses})})};const renderTileContent=()=>{if(isEmpty){return jsxRuntimeExports.jsx("span",{className:a11yStyles.srOnly,children:label})}return jsxRuntimeExports.jsx(Renderer,{content:content,strings:strings,onRender:onContentRender})};const imageHeightStyle=imageHeight!=null?{"--answer-tile-image-height":`${imageHeight}px`}:undefined;return jsxRuntimeExports.jsxs("div",{className:tileClasses,style:imageHeightStyle,ref:dragRef,children:[renderTileStart(),jsxRuntimeExports.jsx("div",{className:styles$4.content,children:renderTileContent()})]})}const scoredIcons={correct:checkIcon$1,incorrect:xIcon};
2096
-
2097
- var styles$3 = {"choiceBank":"perseus_T-Hn60VH","label":"perseus_ZE00ms-U","list":"perseus_uWmQkOPl","item":"perseus_a-OxCEVO"};
2098
-
2099
- const CHOICE_BANK_DROP_ID="choice-bank";function ChoiceBank({children,label}){const labelId=useId();const{ref}=useDroppable({id:CHOICE_BANK_DROP_ID});return jsxRuntimeExports.jsxs("div",{ref:ref,className:styles$3.choiceBank,children:[jsxRuntimeExports.jsx("span",{id:labelId,className:styles$3.label,children:label}),jsxRuntimeExports.jsx("ul",{className:styles$3.list,"aria-labelledby":labelId,children:React.Children.map(children,tile=>jsxRuntimeExports.jsx("li",{className:styles$3.item,children:tile}))})]})}
2100
-
2101
- function activationConstraints(event,source){const{pointerType,target}=event;if(pointerType==="touch"){return [new PointerActivationConstraints.Delay({value:250,tolerance:5})]}if(target instanceof Element&&target.closest("button")!=null){return [new PointerActivationConstraints.Distance({value:5})]}return [new PointerActivationConstraints.Delay({value:200,tolerance:10}),new PointerActivationConstraints.Distance({value:5})]}function preventActivation(event){const{target}=event;if(!(target instanceof Element)){return false}if(target.closest("button")!=null){return false}return target.closest("a, input, textarea, select, [contenteditable=true]")!=null}const SENSORS=[PointerSensor.configure({activationConstraints,preventActivation})];function withoutAccessibilityPlugin(defaultPlugins){return defaultPlugins.filter(plugin=>plugin!==Accessibility)}const PerseusDndProvider=props=>{return jsxRuntimeExports.jsx(DragDropProvider,{sensors:SENSORS,plugins:withoutAccessibilityPlugin,onDragEnd:props.onDragEnd,children:props.children})};
2102
-
2103
- function countPlacements(placements,tileId){return Object.values(placements).filter(placed=>placed===tileId).length}function placeTile(placements,move,targetBlankId,tileUsage){const next={...placements};if(move.fromBlankId!=null){delete next[move.fromBlankId];}{for(const[blankId,placedTileId]of Object.entries(next)){if(placedTileId===move.tileId){delete next[blankId];}}}next[targetBlankId]=move.tileId;return next}function clearBlank(placements,blankId){if(!(blankId in placements)){return placements}const{[blankId]:_cleared,...rest}=placements;return rest}function remainingUses(placements,tileId,tileUsage,maxUsesPerTile){const used=countPlacements(placements,tileId);return used>0?0:1}function isTileInBank(placements,tileId,tileUsage,maxUsesPerTile){const remaining=remainingUses(placements,tileId);return remaining==null||remaining>0}
2104
-
2105
- function useTileMoveActions(options){const{placements,onPlacementsChange,getTileLabel,getBlankLabel,blankIds}=options;const bankMenuRef=React.useRef(null);const placedMenuRefs=React.useRef(new Map);const pendingMenuFocus=React.useRef(null);React.useEffect(()=>{const pending=pendingMenuFocus.current;if(pending==null){return}pendingMenuFocus.current=null;const fallback=pending.fallbackBlankId!=null?placedMenuRefs.current.get(pending.fallbackBlankId):undefined;(bankMenuRef.current??fallback)?.focus();},[placements]);const applyMove=(move,targetBlankId)=>{pendingMenuFocus.current=null;if(move.fromBlankId==null&&placements[targetBlankId]===move.tileId){return false}const evictedTileId=placements[targetBlankId];onPlacementsChange(placeTile(placements,move,targetBlankId));let message=tempDndStrings.movedToTarget({tile:getTileLabel(move.tileId),target:getBlankLabel(targetBlankId)});if(evictedTileId!=null&&evictedTileId!==move.tileId){message+=` ${tempDndStrings.returnedToChoices({tile:getTileLabel(evictedTileId)})}`;}announceMessage({message});return true};const applyClear=blankId=>{pendingMenuFocus.current=null;const tileId=placements[blankId];if(tileId==null){return false}onPlacementsChange(clearBlank(placements,blankId));announceMessage({message:tempDndStrings.returnedToChoices({tile:getTileLabel(tileId)})});return true};const handleMove=(move,targetBlankId)=>{if(applyMove(move,targetBlankId)){pendingMenuFocus.current={fallbackBlankId:targetBlankId};}};const handleClear=blankId=>{if(applyClear(blankId)){pendingMenuFocus.current={fallbackBlankId:null};}};const handleDragEnd=({operation,canceled})=>{const{source,target}=operation;if(canceled||!source||!target){return}const move=readTileDragData(source.data);if(move==null){return}const targetId=String(target.id);if(targetId===move.fromBlankId){return}if(targetId===CHOICE_BANK_DROP_ID){if(move.fromBlankId!=null){applyClear(move.fromBlankId);}}else if(blankIds.includes(targetId)){applyMove(move,targetId);}};const firstBankMenuRef=React.useCallback(button=>{bankMenuRef.current=button;},[]);const placedMenuRefCallbacks=React.useRef(new Map);const placedMenuRef=blankId=>{let callback=placedMenuRefCallbacks.current.get(blankId);if(callback==null){callback=button=>{if(button==null){placedMenuRefs.current.delete(blankId);}else {placedMenuRefs.current.set(blankId,button);}};placedMenuRefCallbacks.current.set(blankId,callback);}return callback};return {handleMove,handleClear,handleDragEnd,firstBankMenuRef,placedMenuRef}}
2106
-
2107
- const getPromptJSON$1=userInput=>{return {type:"sorter",userInput:{values:userInput.options,changed:userInput.changed}}};
2108
-
2109
- var styles$2 = {"sorter":"perseus_IyYPOMNa","blanks":"perseus_vF53xt7t","vertical":"perseus_KNzioeRt","blankItem":"perseus_wKwQ18jE","blank":"perseus_J2S157eK"};
2110
-
2111
- function getBlankId(index){return `blank-${index}`}function getTileId(index){return `tile-${index}`}function placementsFromOrder(order){const placements={};order.forEach((_,index)=>{placements[getBlankId(index)]=getTileId(index);});return placements}const Sorter$3=forwardRef(function Sorter(props,ref){const{options,userInput,widgetId,handleUserInput,trackInteraction}=props;const dependencies=useDependencies();const[bankOrder]=useState(()=>userInput.options);const[placements,setPlacements]=useState(()=>userInput.changed?placementsFromOrder(userInput.options):{});useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"sorter",widgetId:widgetId}});});const blankIds=options.correct.map((_,index)=>getBlankId(index));const layout=options.correct.length>SORTER_MAX_HORIZONTAL_CARDS?"vertical":options.layout;const tileIds=bankOrder.map((_,index)=>getTileId(index));function getTileContent(tileId){return bankOrder[tileIds.indexOf(tileId)]}function getTileLabel(tileId){return getTileContent(tileId)}function getBlankLabel(blankId){return tempDndStrings.blankLabel({num:blankIds.indexOf(blankId)+1})}function onPlacementsChange(next){setPlacements(next);const isComplete=blankIds.every(blankId=>next[blankId]!=null);if(isComplete){handleUserInput({options:blankIds.map(blankId=>getTileContent(next[blankId])),changed:true});}else if(userInput.changed){handleUserInput({options:userInput.options,changed:false});}trackInteraction();}const{handleMove,handleClear,handleDragEnd,firstBankMenuRef,placedMenuRef}=useTileMoveActions({blankIds,placements,onPlacementsChange,getBlankLabel,getTileLabel});useImperativeHandle(ref,()=>({getPromptJSON(){return getPromptJSON$1(props.userInput)},getSerializedState(){const{userInput,options,...rest}=props;return {...rest,...options,changed:userInput.changed,options:userInput.options}}}));function getMoveTargets(fromBlankId){return blankIds.filter(blankId=>blankId!==fromBlankId).map(blankId=>({id:blankId,label:getBlankLabel(blankId)}))}if(exceedsCardLimit(options.correct)){return jsxRuntimeExports.jsx(UnsupportedWidgetMessage,{widgetType:"sorter",widgetSubType:"null",widgetId:widgetId,reason:"exceeds-card-limit"})}const bankTiles=tileIds.filter(tileId=>isTileInBank(placements,tileId));return jsxRuntimeExports.jsx(PerseusDndProvider,{onDragEnd:handleDragEnd,children:jsxRuntimeExports.jsxs("div",{className:styles$2.sorter,children:[jsxRuntimeExports.jsx("ol",{className:classNames$2(styles$2.blanks,layout==="vertical"&&styles$2.vertical),children:blankIds.map(blankId=>{const tileId=placements[blankId];return jsxRuntimeExports.jsx("li",{className:styles$2.blankItem,children:jsxRuntimeExports.jsx(BlankComponent,{blankId:blankId,displayType:"normal",className:styles$2.blank,children:tileId!=null&&jsxRuntimeExports.jsx(AnswerTile,{tileId:tileId,fromBlankId:blankId,content:getTileContent(tileId),label:getTileLabel(tileId),moveTargets:getMoveTargets(blankId),onMove:targetId=>handleMove({tileId,fromBlankId:blankId},targetId),clearFromLabel:getBlankLabel(blankId),onClear:()=>handleClear(blankId),menuRef:placedMenuRef(blankId),fillsBlank:true})})},blankId)})}),jsxRuntimeExports.jsx(ChoiceBank,{label:tempDndStrings.choices,children:bankTiles.map((tileId,index)=>jsxRuntimeExports.jsx(AnswerTile,{tileId:tileId,content:getTileContent(tileId),label:getTileLabel(tileId),moveTargets:getMoveTargets(),onMove:targetId=>handleMove({tileId},targetId),menuRef:index===0?firstBankMenuRef:undefined},tileId))})]})})});
2112
-
2113
- const Sorter$2=forwardRef(function Sorter(props,ref){const dependencies=useDependencies();const sortable=useRef(null);const{options,userInput,widgetId,linterContext,apiOptions}=props;const{correct,padding}=options;const layout=correct.length>SORTER_MAX_HORIZONTAL_CARDS?"vertical":options.layout;useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"sorter",widgetId:widgetId}});});useImperativeHandle(ref,()=>({moveOptionToIndex:(option,index)=>{sortable.current?.moveOptionToIndex(option,index);},getPromptJSON:()=>getPromptJSON$1(props.userInput),getSerializedState:()=>{const{userInput,options,...rest}=props;return {...rest,...options,changed:userInput.changed,options:userInput.options}}}));function handleChange(){props.handleUserInput({options:sortable.current?.getOptions()??[],changed:true});props.trackInteraction();}if(exceedsCardLimit(options.correct)){return jsxRuntimeExports.jsx(UnsupportedWidgetMessage,{widgetType:"sorter",widgetSubType:"null",widgetId:widgetId,reason:"exceeds-card-limit"})}return jsxRuntimeExports.jsx("div",{className:"perseus-clearfix",children:jsxRuntimeExports.jsx(Sortable,{apiOptions:apiOptions,options:userInput.options,layout:layout,margin:apiOptions.isMobile?8:5,padding:padding,onChange:handleChange,linterContext:linterContext,ref:sortable})})});
2114
-
2115
- const Sorter$1=forwardRef(function Sorter(props,ref){if(isFeatureOn(props,"dnd-widget-sorter")){return jsxRuntimeExports.jsx(Sorter$3,{...props,ref:ref})}return jsxRuntimeExports.jsx(Sorter$2,{...props,ref:ref})});
2116
-
2117
- function getStartUserInput$1(options,problemNum){const shuffled=shuffleSorter(options,problemNum);return {options:shuffled,changed:false}}function getUserInputFromSerializedState$1(serializedState){return {changed:serializedState.changed,options:serializedState.options}}var Sorter = {name:"sorter",displayName:"Sorter",widget:Sorter$1,isLintable:true,getStartUserInput: getStartUserInput$1,getUserInputFromSerializedState: getUserInputFromSerializedState$1};
2118
-
2119
- function getInputPath(row,column){return [""+row,""+column]}function getDefaultPath(){return getInputPath(0,0)}function getRowFromPath(path){invariant(Array.isArray(path)&&path.length===2,"path should be a (row, colum) pair");return +path[0]}function getColumnFromPath(path){invariant(Array.isArray(path)&&path.length===2,"path should be a (row, colum) pair");return +path[1]}function getRefForPath(path){const row=getRowFromPath(path);const column=getColumnFromPath(path);return "answer"+row+","+column}const Table=forwardRef(function Table(props,ref){const{strings}=usePerseusI18n();const cellRefs=useRef({});useImperativeHandle(ref,()=>({focus(){getCellForPath(getDefaultPath())?.focus();return true},focusInputPath(path){getCellForPath(path)?.focus();},blurInputPath(path){getCellForPath(path)?.blur();},getDOMNodeForPath(path){const cell=getCellForPath(path);if(cell instanceof HTMLInputElement){return cell}return ReactDOM__default.findDOMNode(cell??null)},getInputPaths:()=>props.userInput.flatMap((rowArr,r)=>rowArr.map((_,c)=>getInputPath(r,c))),getSerializedState(){const{userInput,editableHeaders,options,...rest}=props;return {...options,...rest,answers:userInput}}}));function getCellForPath(path){return cellRefs.current[getRefForPath(path)]}function handleValueChange(row,column,eventOrValue){const answers=deepClone(props.userInput);answers[row][column]=eventOrValue.target?eventOrValue.target.value:eventOrValue;props.handleUserInput(answers);props.trackInteraction();}function handleHeaderChange(index,e){const headers=[...props.options.headers];headers[index]=e.content;props.onChange({headers});}let InputComponent;let inputStyle;const extraInputProps={};if(props.apiOptions.customKeypad){InputComponent=SimpleKeypadInput;inputStyle={width:80};extraInputProps.keypadElement=props.keypadElement;}else {InputComponent="input";inputStyle={};}const headerRow=jsxRuntimeExports.jsx("tr",{children:props.options.headers.map((header,i)=>{if(props.editableHeaders){return jsxRuntimeExports.jsx("th",{children:jsxRuntimeExports.jsx(props.Editor,{apiOptions:props.apiOptions,content:header,widgetEnabled:false,onChange:e=>handleHeaderChange(i,e)})},i)}return jsxRuntimeExports.jsx("th",{children:jsxRuntimeExports.jsx(Renderer,{content:header,linterContext:props.linterContext,strings:strings,apiOptions:props.apiOptions})},i)})});const tableRows=props.userInput.map((rowCells,r)=>jsxRuntimeExports.jsx("tr",{children:rowCells.map((answer,c)=>jsxRuntimeExports.jsx("td",{children:jsxRuntimeExports.jsx(InputComponent,{ref:cell=>{const refId=getRefForPath(getInputPath(r,c));cellRefs.current[refId]=cell??undefined;},type:"text",value:answer,disabled:props.apiOptions.readOnly,onFocus:()=>props.onFocus(getInputPath(r,c)),onBlur:()=>props.onBlur(getInputPath(r,c)),onChange:e=>handleValueChange(r,c,e),style:inputStyle,...extraInputProps})},c))},r));return jsxRuntimeExports.jsxs("table",{className:"perseus-widget-table-of-values non-markdown",children:[jsxRuntimeExports.jsx("thead",{children:headerRow}),jsxRuntimeExports.jsx("tbody",{children:tableRows})]})});function getStartUserInput(options){const rows=options.rows;const columns=options.columns;return Util.stringArrayOfSize2D({rows,columns})}function getUserInputFromSerializedState(serializedState){return serializedState.answers}var Table$1 = {name:"table",displayName:"Table (deprecated - use markdown table instead)",widget:Table,hidden:true,isLintable:true,getStartUserInput,getUserInputFromSerializedState};
2120
-
2121
- const getPromptJSON=()=>{return getUnsupportedPromptJSON("video")};
2122
-
2123
- const IS_URL$1=/^https?:\/\//;const getYoutubeId=url=>{const regExp=/^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;const match=url.match(regExp);if(match&&match[7].length===11){return match[7]}return "videoNotFound"};const VideoTranscriptLink=props=>{const{location}=props;const{useVideo}=useDependencies();const[id,kind]=IS_URL$1.test(location)?[getYoutubeId(location),"YOUTUBE_ID"]:[location,"READABLE_ID"];const result=useVideo(id,kind);const{strings}=usePerseusI18n();switch(result.status){case "loading":return jsxRuntimeExports.jsx(View,{children:strings.loading});case "success":{const video=result.data?.video;return jsxRuntimeExports.jsxs(View,{style:styles$1.transcriptLink,children:[jsxRuntimeExports.jsx(Text$2,{children:video?.title}),jsxRuntimeExports.jsx(Strut,{size:10}),jsxRuntimeExports.jsx(Link,{href:"/transcript/"+(video?.contentId||"videoNotFound"),target:"_blank",className:"visited-no-recolor",children:strings.videoTranscript})]})}case "error":return jsxRuntimeExports.jsx(View,{children:strings.somethingWrong});case "aborted":return jsxRuntimeExports.jsx(View,{children:strings.somethingWrong});default:return jsxRuntimeExports.jsx(View,{children:strings.somethingWrong})}};const styles$1=StyleSheet.create({transcriptLink:{flexDirection:"row",width:"100%",justifyContent:"center"}});
2124
-
2125
- var styles = {"perseusVideoWidget":"perseus_gxXDcWBe","perseusVideoFixedToResponsive":"perseus_5hjlD7xq"};
2126
-
2127
- const DEFAULT_WIDTH=1280;const DEFAULT_HEIGHT=720;const KA_EMBED="{host}/embed_video?slug={slug}"+"&internal_video_only=1";const IS_URL=/^https?:\/\//;const IS_KA_SITE=/(khanacademy\.org|localhost)/;const IS_VIMEO=/(vimeo\.com)/;class Video extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"video",widgetId:this.props.widgetId}});}getPromptJSON(){return getPromptJSON()}render(){const{InitialRequestUrl}=getDependencies();const{location}=this.props.options;if(!location){return jsxRuntimeExports.jsx("div",{})}let url;if(IS_URL.test(location)){url=location;if(IS_VIMEO.test(url)){if(url.indexOf("?")===-1){url+="?dnt=1";}else {url+="&dnt=1";}}}else {url=KA_EMBED.replace("{slug}",location);let embedHostname="https://www.khanacademy.org";if(IS_KA_SITE.test(InitialRequestUrl.host)){embedHostname=InitialRequestUrl.origin;}url=url.replace("{host}",embedHostname);}url=this.props.dependencies.generateUrl({url,context:"video:video_url",kaLocale:this.context.locale});return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(FixedToResponsive,{className:styles.perseusVideoFixedToResponsive,width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,children:jsxRuntimeExports.jsx("iframe",{title:this.context.strings.videoWrapper,className:styles.perseusVideoWidget,sandbox:"allow-same-origin allow-scripts",width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,src:url,allowFullScreen:true,allow:"autoplay"})},location),jsxRuntimeExports.jsx(VideoTranscriptLink,{location:location})]})}constructor(...args){super(...args),this.isWidget=true;}}Video.contextType=PerseusI18nContext;const WrappedVideo=withDependencies(Video);var Video$1 = {name:"video",displayName:"Video",widget:WrappedVideo};
2128
-
2129
- var extraWidgets = [Blank,CSProgram$1,Categorizer$1,Definition$1,Dropdown$1,Explanation$1,FillInTheBlank,FreeResponse$1,GradedGroup$1,GradedGroupSet$1,Grapher$1,Group$1,Iframe$1,Image$1,Interactive,InteractiveGraph$1,LabelImage$1,Matcher$1,Matrix$1,Measurer$1,NumberLine$1,Orderer$1,PhetSimulation$1,Plotter$1,PythonProgram$1,Sorter,Table$1,Video$1];
2130
-
2131
- var allWidgets = [...basicWidgets,...extraWidgets];
2132
-
2133
- const registerAllWidgetsForTesting=()=>{registerWidgets(allWidgets);};
2134
-
2135
- export { MathRenderingContext as $, ApiOptions as A, ButtonGroup as B, ClassNames as C, DependenciesContext as D, Expression as E, Categorizer$1 as F, Graphie as G, HUD as H, Icon as I, JiptParagraphs as J, InteractiveGraph$1 as K, Matrix$1 as L, MathInput as M, NumberInput as N, Table$1 as O, PerseusI18nContext as P, Plotter$1 as Q, Renderer as R, SvgImage as S, TextInput as T, UserInputManager as U, Grapher$1 as V, iconChevronDown as W, iconTrash as X, bodyXsmallBold as Y, dependencies as Z, Log as _, InlineIcon as a, interactiveSizes$1 as a0, PerseusI18nContextProvider as a1, usePerseusI18n as a2, KhanColors as a3, preprocessTex as a4, registerAllWidgetsForTesting as a5, containerSizeClass as a6, getInteractiveBoxFromSizeClass as a7, mathOnlyParser as a8, getWidgetSubTypeByWidgetId as a9, contentHasWidgetType as aa, getWidgetFromWidgetMap as ab, getWidgetsFromWidgetMap as ac, getAbsoluteValueCoords as ad, getCircleCoords as ae, getExponentialCoords as af, getLogarithmCoords as ag, getLineCoords as ah, getLinearSystemCoords as ai, getPointCoords as aj, getPolygonCoords as ak, getSegmentCoords as al, getSinusoidCoords as am, getTangentCoords as an, getVectorCoords as ao, getQuadraticCoords as ap, getAngleCoords as aq, deriveUserInputFromSerializedState as ar, parseDataFromJSONP as as, MultiButtonGroup as b, basicWidgets as c, Util as d, extraWidgets as e, hintBorderWidth as f, getDependencies as g, hintPaddingInlineStart as h, context as i, jsxRuntimeExports as j, getWidgetTypeByWidgetId as k, getWidgetExport as l, mediaQueries as m, PerseusMarkdown as n, getEquationString as o, defaultPlotProps as p, chooseType as q, registerWidgets as r, sharedStyles as s, typeToButton as t, DEFAULT_GRAPHER_PROPS as u, allWidgets as v, widgets$1 as w, InputNumber as x, NumericInput$1 as y, Radio as z };
2136
- //# sourceMappingURL=chunk-register-all-widgets-for-testing-DhqLyGU0.js.map