@khanacademy/perseus 18.0.1 → 19.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/es/index.css +209 -128
  3. package/dist/es/index.js +1026 -3516
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.css +209 -128
  6. package/dist/index.d.ts +3 -3
  7. package/dist/index.js +917 -3409
  8. package/dist/index.js.map +1 -1
  9. package/dist/mixins/changeable.d.ts +1 -1
  10. package/dist/perseus-api.d.ts +1 -0
  11. package/dist/perseus-types.d.ts +2 -109
  12. package/dist/renderer.d.ts +2 -4
  13. package/dist/server-item-renderer.d.ts +1 -0
  14. package/dist/strings.js +0 -29
  15. package/dist/types.d.ts +4 -4
  16. package/dist/util/geometry.d.ts +2 -0
  17. package/dist/util/graphie.d.ts +107 -1
  18. package/dist/util/math.d.ts +2 -0
  19. package/dist/util/parse-perseus-json.d.ts +3 -3
  20. package/dist/widgets/expression.d.ts +8 -2
  21. package/dist/widgets/label-image.d.ts +2 -0
  22. package/dist/widgets.d.ts +1 -1
  23. package/package.json +3 -4
  24. package/src/__testdata__/renderer.testdata.ts +152 -0
  25. package/src/__tests__/renderer.test.tsx +17 -0
  26. package/src/__tests__/widgets.test.ts +0 -1
  27. package/src/components/math-input.tsx +4 -6
  28. package/src/extra-widgets.ts +0 -2
  29. package/src/index.ts +8 -4
  30. package/src/mixins/changeable.ts +1 -1
  31. package/src/perseus-types.ts +1 -154
  32. package/src/renderer.tsx +14 -8
  33. package/src/styles/perseus-renderer.less +0 -1
  34. package/src/types.ts +9 -5
  35. package/src/util/geometry.test.ts +75 -0
  36. package/src/util/geometry.ts +19 -0
  37. package/src/util/graphie.test.ts +1291 -0
  38. package/src/util/graphie.ts +832 -784
  39. package/src/util/interactive.ts +23 -51
  40. package/src/util/math.test.ts +11 -0
  41. package/src/util/math.ts +8 -0
  42. package/src/util/parse-perseus-json.test.ts +3 -3
  43. package/src/util/parse-perseus-json.ts +4 -4
  44. package/src/util/register-all-widgets-for-testing.ts +1 -3
  45. package/src/widgets/__tests__/__snapshots__/input-number.test.ts.snap +4 -2
  46. package/src/widgets/__tests__/__snapshots__/numeric-input.test.ts.snap +4 -2
  47. package/src/widgets/__tests__/expression-mobile.test.tsx +8 -5
  48. package/src/widgets/__tests__/renderQuestion.tsx +11 -3
  49. package/src/widgets/expression.tsx +1 -23
  50. package/src/widgets/label-image.tsx +0 -1
  51. package/src/widgets.ts +1 -9
  52. package/tsconfig-build.tsbuildinfo +1 -1
  53. package/dist/widgets/transformer.d.ts +0 -94
  54. package/src/styles/widgets/transformer.less +0 -29
  55. package/src/widgets/__stories__/transformer.stories.tsx +0 -14
  56. package/src/widgets/__testdata__/transformer.testdata.ts +0 -107
  57. package/src/widgets/transformer.tsx +0 -2936
@@ -26,5 +26,5 @@ export declare const propTypes: {
26
26
  export type ChangeableProps = {
27
27
  onChange: (values: {
28
28
  [key: string]: any;
29
- }, callback?: () => unknown | null | undefined, silent?: boolean) => unknown;
29
+ }, callback?: (() => unknown) | null | undefined, silent?: boolean) => unknown;
30
30
  };
@@ -93,6 +93,7 @@ export declare const ApiOptions: {
93
93
  inModal?: boolean | undefined;
94
94
  crossOutEnabled?: boolean | undefined;
95
95
  editorChangeDelay?: number | undefined;
96
+ onWidgetStartProps?: ((widgets: import("./types").PerseusWidgetMap) => import("./types").PerseusWidgetMap) | undefined;
96
97
  }> & {
97
98
  GroupMetadataEditor: NonNullable<React.ComponentType<any> | undefined>;
98
99
  baseElements: {
@@ -70,7 +70,6 @@ export type SequenceWidget = Widget<'sequence', PerseusSequenceWidgetOptions>;
70
70
  export type SimulatorWidget = Widget<'simulator', PerseusSimulatorWidgetOptions>;
71
71
  export type SorterWidget = Widget<'sorter', PerseusSorterWidgetOptions>;
72
72
  export type TableWidget = Widget<'table', PerseusTableWidgetOptions>;
73
- export type TransformerWidget = Widget<'transformer', PerseusTransformerWidgetOptions>;
74
73
  export type ExampleGraphieWidget = Widget<'example-graphie-widget', PerseusExampleGraphieWidgetOptions>;
75
74
  export type ExampleWidget = Widget<'example-widget', PerseusExampleWidgetOptions>;
76
75
  export type InputNumberWidget = Widget<'input-number', PerseusInputNumberWidgetOptions>;
@@ -82,7 +81,7 @@ export type SimpleMarkdownTesterWidget = Widget<'simple-markdown-tester', Perseu
82
81
  export type UnitInputWidget = Widget<'unit-input', PerseusUnitInputWidgetOptions>;
83
82
  export type VideoWidget = Widget<'video', PerseusVideoWidgetOptions>;
84
83
  export type AutoCorrectWidget = Widget<'deprecated-standin', PerseusWidgetOptions>;
85
- export type PerseusWidget = CategorizerWidget | CSProgramWidget | DefinitionWidget | DropdownWidget | ExampleGraphieWidget | ExampleWidget | ExplanationWidget | ExpressionWidget | GradedGroupSetWidget | GradedGroupWidget | GrapherWidget | GroupWidget | IFrameWidget | ImageWidget | InputNumberWidget | InteractionWidget | InteractiveGraphWidget | LabelImageWidget | LightsPuzzleWidget | MatcherWidget | MatrixWidget | MeasurerWidget | MoleculeRendererWidget | NumberLineWidget | NumericInputWidget | OrdererWidget | PassageRefWidget | PassageWidget | PlotterWidget | RadioWidget | ReactionDiagramWidget | RefTargetWidget | SequenceWidget | SimpleMarkdownTesterWidget | SimulatorWidget | SorterWidget | TableWidget | TransformerWidget | UnitInputWidget | VideoWidget | AutoCorrectWidget;
84
+ export type PerseusWidget = CategorizerWidget | CSProgramWidget | DefinitionWidget | DropdownWidget | ExampleGraphieWidget | ExampleWidget | ExplanationWidget | ExpressionWidget | GradedGroupSetWidget | GradedGroupWidget | GrapherWidget | GroupWidget | IFrameWidget | ImageWidget | InputNumberWidget | InteractionWidget | InteractiveGraphWidget | LabelImageWidget | LightsPuzzleWidget | MatcherWidget | MatrixWidget | MeasurerWidget | MoleculeRendererWidget | NumberLineWidget | NumericInputWidget | OrdererWidget | PassageRefWidget | PassageWidget | PlotterWidget | RadioWidget | ReactionDiagramWidget | RefTargetWidget | SequenceWidget | SimpleMarkdownTesterWidget | SimulatorWidget | SorterWidget | TableWidget | UnitInputWidget | VideoWidget | AutoCorrectWidget;
86
85
  export type PerseusImageBackground = {
87
86
  url: string | null | undefined;
88
87
  width?: number;
@@ -468,85 +467,6 @@ export type PerseusTableWidgetOptions = {
468
467
  columns: number;
469
468
  answers: ReadonlyArray<ReadonlyArray<string>>;
470
469
  };
471
- export type PerseusTransformerWidgetOptions = {
472
- correct: {
473
- shape: {
474
- type: ReadonlyArray<"polygon-5" | "polygon-3" | "polygon-4" | "lineSegment" | "polygon-6" | "angle" | "line" | "circle">;
475
- coords: ReadonlyArray<Coord>;
476
- options?: ReadonlyArray<{
477
- reflex?: boolean;
478
- }>;
479
- };
480
- transformations: ReadonlyArray<PerseusTransformerTransformation>;
481
- };
482
- drawSolutionShape: boolean;
483
- gradeEmpty: boolean;
484
- graph: {
485
- backgroundImage: {
486
- bottom?: number;
487
- height?: number;
488
- left?: number;
489
- scale?: number;
490
- url?: string;
491
- width?: number;
492
- };
493
- gridStep?: [number, number];
494
- labels?: ["x", "y"];
495
- markings: "none" | "graph" | "grid";
496
- range: [[number, number], [number, number]];
497
- rulerLabel?: string;
498
- rulerTicks?: number;
499
- showProtractor: boolean;
500
- showRuler?: boolean;
501
- snapStep?: [number, number];
502
- step: [number, number];
503
- };
504
- graphMode: "dynamic" | "interactive" | "static";
505
- listMode: "interactive" | "dynamic" | "static";
506
- starting: {
507
- shape: {
508
- type: ReadonlyArray<"polygon-5" | "polygon-3" | "polygon-4" | "lineSegment" | "polygon-6">;
509
- coords: ReadonlyArray<Coord>;
510
- options?: ReadonlyArray<Empty>;
511
- } | {
512
- type: "polygon-3";
513
- coords: [Coord, Coord, Coord];
514
- } | {
515
- type: [
516
- "polygon-3" | "lineSegment" | "polygon-4" | "polygon-5" | "polygon-6" | "line" | "circle"
517
- ];
518
- coords: ReadonlyArray<Coord>;
519
- options: [Empty];
520
- } | {
521
- type: ["polygon-3"];
522
- coords: [Coord, Coord, Coord];
523
- options?: [Empty];
524
- } | {
525
- type: ["angle"];
526
- coords: [Coord, Coord, Coord];
527
- options: [
528
- {
529
- reflex: boolean;
530
- }
531
- ];
532
- } | {
533
- type: ["line" | "lineSegment"];
534
- coords: [Coord, Coord];
535
- options?: [Empty];
536
- } | {
537
- type: "polygon";
538
- coords: ReadonlyArray<Coord>;
539
- };
540
- transformations: ReadonlyArray<PerseusTransformerTransformation>;
541
- };
542
- tools: {
543
- dilation: DilationTool;
544
- reflection: ReflectionTool;
545
- rotation: RotationTool;
546
- translation: TranslationTool;
547
- };
548
- version: number;
549
- };
550
470
  export type DilationTransformation = {
551
471
  type: "dilation";
552
472
  center: Coord;
@@ -575,33 +495,6 @@ export type TranslationTransformation = {
575
495
  vector: Coord;
576
496
  contraints: Empty;
577
497
  };
578
- export type PerseusTransformerTransformation = DilationTransformation | ReflectionTransformation | RotationTransformation | TranslationTransformation;
579
- type DilationTool = {
580
- constraints: PerseusTransformerToolConstraints;
581
- coord: Coord;
582
- enabled: boolean;
583
- required?: boolean;
584
- };
585
- type ReflectionTool = {
586
- constraints: PerseusTransformerToolConstraints;
587
- coords: [Coord, Coord];
588
- enabled: boolean;
589
- required?: boolean;
590
- };
591
- type RotationTool = {
592
- constraints: PerseusTransformerToolConstraints;
593
- coord: Coord;
594
- enabled: boolean;
595
- required?: boolean;
596
- };
597
- type TranslationTool = {
598
- constraints: Empty;
599
- enabled: boolean;
600
- required?: boolean;
601
- };
602
- export type PerseusTransformerToolConstraints = {
603
- fixed: boolean;
604
- };
605
498
  export type PerseusInteractionWidgetOptions = {
606
499
  graph: PerseusInteractionGraph;
607
500
  elements: ReadonlyArray<PerseusInteractionElement>;
@@ -774,5 +667,5 @@ export type PerseusPassageRefTargetWidgetOptions = any;
774
667
  export type PerseusReactionDiagramWidgetOptions = any;
775
668
  export type PerseusSimpleMarkdownTesterWidgetOptions = any;
776
669
  export type PerseusUnitInputWidgetOptions = any;
777
- export type PerseusWidgetOptions = PerseusCategorizerWidgetOptions | PerseusCSProgramWidgetOptions | PerseusDefinitionWidgetOptions | PerseusDropdownWidgetOptions | PerseusExampleGraphieWidgetOptions | PerseusExampleWidgetOptions | PerseusExplanationWidgetOptions | PerseusExpressionWidgetOptions | PerseusGradedGroupSetWidgetOptions | PerseusGradedGroupWidgetOptions | PerseusIFrameWidgetOptions | PerseusImageWidgetOptions | PerseusInputNumberWidgetOptions | PerseusInteractionWidgetOptions | PerseusInteractiveGraphWidgetOptions | PerseusLabelImageWidgetOptions | PerseusLightsPuzzleWidgetOptions | PerseusMatcherWidgetOptions | PerseusMatrixWidgetOptions | PerseusMeasurerWidgetOptions | PerseusMoleculeRendererWidgetOptions | PerseusNumberLineWidgetOptions | PerseusNumericInputWidgetOptions | PerseusOrdererWidgetOptions | PerseusPassageRefTargetWidgetOptions | PerseusPassageRefWidgetOptions | PerseusPassageWidgetOptions | PerseusPlotterWidgetOptions | PerseusRadioWidgetOptions | PerseusReactionDiagramWidgetOptions | PerseusSequenceWidgetOptions | PerseusSimpleMarkdownTesterWidgetOptions | PerseusSimulatorWidgetOptions | PerseusSorterWidgetOptions | PerseusTableWidgetOptions | PerseusTransformerWidgetOptions | PerseusUnitInputWidgetOptions | PerseusVideoWidgetOptions;
670
+ export type PerseusWidgetOptions = PerseusCategorizerWidgetOptions | PerseusCSProgramWidgetOptions | PerseusDefinitionWidgetOptions | PerseusDropdownWidgetOptions | PerseusExampleGraphieWidgetOptions | PerseusExampleWidgetOptions | PerseusExplanationWidgetOptions | PerseusExpressionWidgetOptions | PerseusGradedGroupSetWidgetOptions | PerseusGradedGroupWidgetOptions | PerseusIFrameWidgetOptions | PerseusImageWidgetOptions | PerseusInputNumberWidgetOptions | PerseusInteractionWidgetOptions | PerseusInteractiveGraphWidgetOptions | PerseusLabelImageWidgetOptions | PerseusLightsPuzzleWidgetOptions | PerseusMatcherWidgetOptions | PerseusMatrixWidgetOptions | PerseusMeasurerWidgetOptions | PerseusMoleculeRendererWidgetOptions | PerseusNumberLineWidgetOptions | PerseusNumericInputWidgetOptions | PerseusOrdererWidgetOptions | PerseusPassageRefTargetWidgetOptions | PerseusPassageRefWidgetOptions | PerseusPassageWidgetOptions | PerseusPlotterWidgetOptions | PerseusRadioWidgetOptions | PerseusReactionDiagramWidgetOptions | PerseusSequenceWidgetOptions | PerseusSimpleMarkdownTesterWidgetOptions | PerseusSimulatorWidgetOptions | PerseusSorterWidgetOptions | PerseusTableWidgetOptions | PerseusUnitInputWidgetOptions | PerseusVideoWidgetOptions;
778
671
  export {};
@@ -4,7 +4,7 @@ import TranslationLinter from "./translation-linter";
4
4
  import WidgetContainer from "./widget-container";
5
5
  import type { DependenciesContext } from "./dependencies";
6
6
  import type { PerseusRenderer, PerseusWidget, PerseusWidgetOptions } from "./perseus-types";
7
- import type { APIOptions, APIOptionsWithDefaults, FilterCriterion, FocusPath, PerseusScore, WidgetProps } from "./types";
7
+ import type { APIOptions, APIOptionsWithDefaults, FilterCriterion, FocusPath, PerseusScore, PerseusWidgetMap, WidgetProps } from "./types";
8
8
  import type { LinterContextProps } from "@khanacademy/perseus-linter";
9
9
  import "./styles/perseus-renderer.less";
10
10
  type WidgetState = {
@@ -117,9 +117,7 @@ declare class Renderer extends React.Component<Props, State> {
117
117
  _getAllWidgetsInfo: (props: Props) => {
118
118
  [key: string]: PerseusWidget;
119
119
  };
120
- _getAllWidgetsStartProps: (allWidgetInfo: {
121
- [key: string]: PerseusWidget;
122
- }, props: Props) => any;
120
+ _getAllWidgetsStartProps: (allWidgetInfo: PerseusWidgetMap, props: Props) => PerseusWidgetMap;
123
121
  _getDefaultWidgetInfo: (widgetId: string) => any;
124
122
  _getWidgetInfo: (widgetId: string) => PerseusWidget;
125
123
  renderWidget: (impliedType: string, id: string, state: WidgetState) => null | React.ReactNode;
@@ -136,6 +136,7 @@ declare const ref: React.ForwardRefExoticComponent<Omit<Pick<OwnProps & HOCProps
136
136
  inModal?: boolean | undefined;
137
137
  crossOutEnabled?: boolean | undefined;
138
138
  editorChangeDelay?: number | undefined;
139
+ onWidgetStartProps?: ((widgets: import("./types").PerseusWidgetMap) => import("./types").PerseusWidgetMap) | undefined;
139
140
  }> | undefined;
140
141
  onRendered?: ((isRendered: boolean) => void) | undefined;
141
142
  } & {}, "onRendered"> & React.RefAttributes<ServerItemRenderer>>;
package/dist/strings.js CHANGED
@@ -31,7 +31,6 @@ module.exports = [
31
31
  i18n._("a multiple of pi, like $12\\ \\text{pi}$ or $2/3\\ \\text{pi}$", {}),
32
32
  i18n._("a percent, like $12.34\\%$", {}),
33
33
  i18n._("Add highlight", {}),
34
- i18n._("Add transformations below:", {}),
35
34
  i18n._("an *exact* decimal, like $0.75$", {}),
36
35
  i18n._("an *improper* fraction, like $10/7$ or $14/8$", {}),
37
36
  i18n._("an integer, like $6$", {}),
@@ -55,12 +54,6 @@ module.exports = [
55
54
  i18n._("Correct (selected)", {}),
56
55
  i18n._("Correct!", {}),
57
56
  i18n._("Current", {}),
58
- // I18N: As in the command, "Dilate the polygon"
59
- i18n._("Dilate", {}),
60
- i18n._("dilation", {}),
61
- i18n._("Dilation", {}),
62
- i18n.$_("Dilation about %(point)s by %(scale)s", {}),
63
- i18n.$_("Dilation of scale %(scale)s about %(point)s", {}),
64
57
  i18n._("Drag handles to make graph", {}),
65
58
  i18n._("End of reading passage.", {}),
66
59
  i18n._("entered in an invalid answer.", {}),
@@ -93,7 +86,6 @@ module.exports = [
93
86
  i18n._("Next question", {}),
94
87
  i18n._("No", {}),
95
88
  i18n._("None of the above", {}),
96
- i18n._("Note: For this question, the shape will not move.", {}),
97
89
  i18n._("Number of divisions:", {}),
98
90
  i18n._("Number of trials:", {}),
99
91
  i18n._("Oops!", {}),
@@ -102,19 +94,7 @@ module.exports = [
102
94
  i18n._("Please choose the correct number of answers.", {}),
103
95
  i18n.$_("Please make sure the number of divisions is in the range %(divRangeString)s.", {}),
104
96
  i18n._("Reaction arrow pointing to the right.", {}),
105
- // I18N: As in the command, "Reflect the polygon"
106
- i18n._("Reflect", {}),
107
- i18n._("reflection", {}),
108
- i18n._("Reflection", {}),
109
- i18n.$_("Reflection over the line from %(point1)s to %(point2)s", {}),
110
97
  i18n._("Remove highlight", {}),
111
- // I18N: As in the command, "Rotate the polygon"
112
- i18n._("Rotate", {}),
113
- i18n._("rotation", {}),
114
- i18n._("Rotation", {}),
115
- // I18N: %(point)s must come before %(degrees)s in this phrase
116
- i18n.$_("Rotation about %(point)s by %(degrees)s", {}),
117
- i18n.$_("Rotation by %(degrees)s about %(point)s", {}),
118
98
  i18n._("Run simulation", {}),
119
99
  i18n._("Sample size:", {}),
120
100
  i18n._("See video transcript", {}),
@@ -131,16 +111,8 @@ module.exports = [
131
111
  i18n._("This controls the proportion or percentage that will be used in your simulation.", {}),
132
112
  i18n._("This controls the sample size that will be used in your simulation. For example, if you set this to 100, then for each trial, responses from 100 participants will be simulated.", {}),
133
113
  i18n._("This is the number of trials used in the simulation. For example, if set to 50, then the survey will be conducted 50 times.", {}),
134
- // I18N: As in the command, "Translate the polygon"
135
- i18n._("Translate", {}),
136
- i18n._("translation", {}),
137
- i18n._("Translation", {}),
138
- // I18N: As in the command, "Translation by <3, 1>"
139
- i18n.$_("Translation by %(vector)s", {}),
140
114
  i18n._("True", {}),
141
115
  i18n._("Try again", {}),
142
- i18n._("Undo", {}),
143
- i18n._("Use the interactive graph to define a correct transformation.", {}),
144
116
  i18n._("Value", {}),
145
117
  i18n._("We could not understand your answer. Please check your answer for extra text or symbols.", {}),
146
118
  i18n._("We couldn't grade your answer.", {}),
@@ -152,5 +124,4 @@ module.exports = [
152
124
  i18n._("Your answer is almost correct, but it needs to be simplified.", {}),
153
125
  i18n._("Your answer is close, but you may have approximated pi. Enter your answer as a multiple of pi, like <code>12\\ \\text{pi}</code> or <code>2/3\\ \\text{pi}</code>", {}),
154
126
  i18n._("Your answer:", {}),
155
- i18n._("Your transformation must use a %(type)s.", {}),
156
127
  ];
package/dist/types.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type { SerializedHighlightSet } from "./components/highlighting/types";
2
1
  import type { ILogger } from "./logging/log";
3
2
  import type { Item } from "./multi-items/item-types";
4
3
  import type { PerseusAnswerArea, PerseusRenderer, PerseusWidget } from "./perseus-types";
@@ -65,9 +64,6 @@ export type ChangeHandler = (arg1: {
65
64
  choiceStates?: ReadonlyArray<ChoiceState>;
66
65
  currentValue?: string;
67
66
  selected?: number;
68
- tools?: ReadonlyArray<any>;
69
- transformations?: ReadonlyArray<any>;
70
- highlights?: SerializedHighlightSet;
71
67
  plot?: any;
72
68
  }, callback?: () => unknown | null | undefined, silent?: boolean) => unknown;
73
69
  export type ImageUploader = (file: string, callback: (url: string) => unknown) => unknown;
@@ -107,6 +103,7 @@ export type APIOptions = Readonly<{
107
103
  inModal?: boolean;
108
104
  crossOutEnabled?: boolean;
109
105
  editorChangeDelay?: number;
106
+ onWidgetStartProps?: (widgets: PerseusWidgetMap) => PerseusWidgetMap;
110
107
  }>;
111
108
  type TeXProps = {
112
109
  children: string;
@@ -246,6 +243,9 @@ export type WidgetExports<T extends React.ComponentType<any> = React.ComponentTy
246
243
  };
247
244
  widget: T;
248
245
  }>;
246
+ export type PerseusWidgetMap = {
247
+ [key: string]: PerseusWidget;
248
+ };
249
249
  export type FilterCriterion = string | ((id: string, widgetInfo: PerseusWidget, widget?: Widget | null | undefined) => boolean);
250
250
  export type WidgetProps<RenderProps, Rubric, TrackingExtraArgs = Empty> = RenderProps & {
251
251
  widgetId: string;
@@ -15,6 +15,8 @@ export declare function ccw(a: Coord, b: Coord, c: Coord): number;
15
15
  export declare function collinear(a: Coord, b: Coord, c: Coord): boolean;
16
16
  export declare function intersects(ab: Line, cd: Line): boolean;
17
17
  export declare function vector(a: any, b: any): number[];
18
+ export declare function reverseVector(vector: Coord): Coord;
19
+ export declare function clockwise(points: Coord[]): boolean;
18
20
  export declare function magnitude(v: ReadonlyArray<Coord>): number;
19
21
  export declare function angleMeasures(coords: ReadonlyArray<Coord>): ReadonlyArray<number>;
20
22
  export declare function similar(coords1: ReadonlyArray<Coord>, coords2: ReadonlyArray<Coord>, tolerance: number): boolean;
@@ -1,4 +1,110 @@
1
+ import type { Interval } from "./interval";
1
2
  import type { Coord } from "../interactive2/types";
2
- export declare function polar(r: number | Coord, th: number): number[];
3
+ export declare function polar(r: number | Coord, th: number): Coord;
4
+ interface RaphaelElement {
5
+ type: string;
6
+ attrs: Record<string, any>;
7
+ node: {
8
+ style: {
9
+ shapeRendering: "crispEdges" | "geometricPrecision";
10
+ };
11
+ };
12
+ }
13
+ type PositionedShape = {
14
+ wrapper: HTMLDivElement;
15
+ visibleShape: RaphaelElement;
16
+ };
17
+ export type StyleParams = {
18
+ fill?: string;
19
+ labelDistance?: number;
20
+ opacity?: number;
21
+ step?: Coord;
22
+ stroke?: string;
23
+ strokeWidth?: number;
24
+ };
25
+ type LabelPosition = "center" | "above" | "below" | "right" | "left" | "above right" | "above left" | "below right" | "below left";
26
+ interface LabelMethod {
27
+ (point: Coord, text: string, position: LabelPosition): any;
28
+ (point: Coord, text: string, position: LabelPosition, renderTex: boolean): any;
29
+ (point: Coord, text: string, position: LabelPosition, style: StyleParams): any;
30
+ (point: Coord, text: string, position: LabelPosition, renderTex: boolean, style: StyleParams): any;
31
+ }
32
+ export declare class Graphie {
33
+ #private;
34
+ el: HTMLElement;
35
+ raphael?: any;
36
+ isMobile: boolean;
37
+ currentStyle: any;
38
+ range?: [Interval, Interval];
39
+ scale?: Coord;
40
+ dimensions?: Coord;
41
+ xpixels?: number;
42
+ ypixels?: number;
43
+ constructor(el: HTMLElement);
44
+ init(options: {
45
+ range?: [Interval, Interval];
46
+ scale?: number | Coord;
47
+ isMobile?: boolean;
48
+ }): this;
49
+ graphInit(options: {
50
+ range?: [Interval, Interval] | Coord;
51
+ grid?: boolean;
52
+ gridRange?: [Interval, Interval] | Coord;
53
+ scale: Coord | number;
54
+ axes?: true;
55
+ axisArrows?: "<->" | "->" | true | "";
56
+ axisOpacity?: number;
57
+ axisCenter?: Coord;
58
+ axisLabels?: [string, string] | false;
59
+ gridOpacity?: number;
60
+ gridStep?: Coord | number;
61
+ ticks?: boolean;
62
+ tickStep?: Coord | number;
63
+ tickLen?: Coord | number;
64
+ tickOpacity?: number;
65
+ labels?: boolean;
66
+ labelStep?: number;
67
+ labelOpacity?: number;
68
+ labelFormat?: (a: number) => string;
69
+ yLabelFormat?: (y: number) => string;
70
+ xLabelFormat?: (x: number) => string;
71
+ unityLabels?: boolean | [boolean, boolean];
72
+ isMobile?: boolean;
73
+ }): void;
74
+ private drawingTransform;
75
+ private bounds;
76
+ style(attrs: any, fn: any): any;
77
+ grid(xr: Interval, yr: Interval, style?: StyleParams): unknown;
78
+ arc(center: Coord, radius: Coord, startAngle: number, endAngle: number, sector: boolean, style?: StyleParams): RaphaelElement;
79
+ circle(center: Coord, radius: number, style?: StyleParams): any;
80
+ rect(x: any, y: any, width: any, height: any, style?: StyleParams): any;
81
+ ellipse(center: any, radii: any, style?: StyleParams): any;
82
+ fixedEllipse(center: number | Coord, radii: number | [number, number], maxScale: number, padding: number, style?: StyleParams): PositionedShape;
83
+ private unstyledPath;
84
+ path(points: Coord[], style?: StyleParams): RaphaelElement;
85
+ fixedPath(points: Coord[], center: Coord | null, createPath: (scaledPoints: Coord[]) => string): PositionedShape;
86
+ scaledPath(points: Coord[], style?: StyleParams): RaphaelElement;
87
+ line(start: Coord, end: Coord, style?: StyleParams): RaphaelElement;
88
+ parabola(a: number, b: number, c: number, style?: StyleParams): RaphaelElement;
89
+ fixedLine(start: Coord, end: Coord, thickness: number): PositionedShape;
90
+ sinusoid(a: number, b: number, c: number, d: number, style?: StyleParams): RaphaelElement;
91
+ label: LabelMethod;
92
+ plotParametric(fn: (t: number) => Coord, range: Interval, style?: StyleParams): RaphaelElement;
93
+ plot(fn: (x: number) => number, range: Interval, style?: StyleParams): RaphaelElement;
94
+ svgPath: (points: (Coord | true)[], alreadyScaled?: boolean) => string;
95
+ svgParabolaPath: (a: any, b: any, c: any) => string;
96
+ svgSinusoidPath: (a: number, b: number, c: number, d: number) => string;
97
+ private withStyle;
98
+ private postprocessDrawingResult;
99
+ private addArrowheads;
100
+ scalePoint: (point: number | Coord) => Coord;
101
+ scaleVector: (point: number | Coord) => any;
102
+ unscalePoint: (point: Coord) => any;
103
+ unscaleVector: (point: Coord) => any;
104
+ private processAttributes;
105
+ }
106
+ type RangeSpecifier = [Interval, Interval] | Coord | number;
107
+ export declare function normalizeRange(range: RangeSpecifier): [Interval, Interval];
108
+ export declare function normalizeRange(range: RangeSpecifier | undefined): [Interval, Interval] | undefined;
3
109
  declare const GraphUtils: any;
4
110
  export default GraphUtils;
@@ -25,4 +25,6 @@ declare const KhanMath: {
25
25
  readonly getNumericFormat: (text: string) => MathFormat | null | undefined;
26
26
  readonly toNumericString: (number: number, format?: MathFormat) => string;
27
27
  };
28
+ export declare function sum(array: number[]): number;
29
+ export declare function add(a: number, b: number): number;
28
30
  export default KhanMath;
@@ -1,10 +1,10 @@
1
1
  import type { PerseusItem } from "../perseus-types";
2
2
  /**
3
- * Helper to parse Perseus JSON
3
+ * Helper to parse PerseusItem JSON
4
4
  * Why not just use JSON.parse? We want:
5
5
  * - To make sure types are correct
6
6
  * - To give us a central place to validate/transform output if needed
7
- * @param {string} input - the stringified Perseus JSON
7
+ * @param {string} json - the stringified PerseusItem JSON
8
8
  * @returns {PerseusItem} the parsed PerseusItem object
9
9
  */
10
- export default function parsePerseusJSON(input: string): PerseusItem;
10
+ export declare function parsePerseusItem(json: string): PerseusItem;
@@ -121,6 +121,7 @@ declare const _default: Readonly<{
121
121
  inModal?: boolean | undefined;
122
122
  crossOutEnabled?: boolean | undefined;
123
123
  editorChangeDelay?: number | undefined;
124
+ onWidgetStartProps?: ((widgets: import("../types").PerseusWidgetMap) => import("../types").PerseusWidgetMap) | undefined;
124
125
  }> & {
125
126
  GroupMetadataEditor: NonNullable<React.ComponentType<any> | undefined>;
126
127
  baseElements: {
@@ -184,6 +185,7 @@ declare const _default: Readonly<{
184
185
  inModal?: boolean | undefined;
185
186
  crossOutEnabled?: boolean | undefined;
186
187
  editorChangeDelay?: number | undefined;
188
+ onWidgetStartProps?: ((widgets: import("../types").PerseusWidgetMap) => import("../types").PerseusWidgetMap) | undefined;
187
189
  }> & {
188
190
  GroupMetadataEditor: NonNullable<React.ComponentType<any> | undefined>;
189
191
  baseElements: {
@@ -210,7 +212,7 @@ declare const _default: Readonly<{
210
212
  onFocus: (blurPath: import("../types").FocusPath) => void;
211
213
  times: boolean;
212
214
  value: string;
213
- }, "static" | "trackInteraction" | "onChange" | "analytics" | "problemNum" | "questionCompleted" | "keypadElement" | "alignment" | "buttonsVisible" | "containerSizeClass" | "widgetId" | "findWidgets" | "keypadConfiguration" | "reviewModeRubric" | "isLastUsedWidget"> & {
215
+ }, "trackInteraction" | "onChange" | "static" | "analytics" | "problemNum" | "questionCompleted" | "keypadElement" | "alignment" | "buttonsVisible" | "containerSizeClass" | "widgetId" | "findWidgets" | "keypadConfiguration" | "reviewModeRubric" | "isLastUsedWidget"> & {
214
216
  value?: string | undefined;
215
217
  onFocus?: ((blurPath: import("../types").FocusPath) => void) | undefined;
216
218
  onBlur?: ((blurPath: import("../types").FocusPath) => void) | undefined;
@@ -247,6 +249,7 @@ declare const _default: Readonly<{
247
249
  inModal?: boolean | undefined;
248
250
  crossOutEnabled?: boolean | undefined;
249
251
  editorChangeDelay?: number | undefined;
252
+ onWidgetStartProps?: ((widgets: import("../types").PerseusWidgetMap) => import("../types").PerseusWidgetMap) | undefined;
250
253
  }> & {
251
254
  GroupMetadataEditor: NonNullable<React.ComponentType<any> | undefined>;
252
255
  baseElements: {
@@ -321,6 +324,7 @@ declare const _default: Readonly<{
321
324
  inModal?: boolean | undefined;
322
325
  crossOutEnabled?: boolean | undefined;
323
326
  editorChangeDelay?: number | undefined;
327
+ onWidgetStartProps?: ((widgets: import("../types").PerseusWidgetMap) => import("../types").PerseusWidgetMap) | undefined;
324
328
  }> & {
325
329
  GroupMetadataEditor: NonNullable<React.ComponentType<any> | undefined>;
326
330
  baseElements: {
@@ -384,6 +388,7 @@ declare const _default: Readonly<{
384
388
  inModal?: boolean | undefined;
385
389
  crossOutEnabled?: boolean | undefined;
386
390
  editorChangeDelay?: number | undefined;
391
+ onWidgetStartProps?: ((widgets: import("../types").PerseusWidgetMap) => import("../types").PerseusWidgetMap) | undefined;
387
392
  }> & {
388
393
  GroupMetadataEditor: NonNullable<React.ComponentType<any> | undefined>;
389
394
  baseElements: {
@@ -410,7 +415,7 @@ declare const _default: Readonly<{
410
415
  onFocus: (blurPath: import("../types").FocusPath) => void;
411
416
  times: boolean;
412
417
  value: string;
413
- }, "static" | "trackInteraction" | "onChange" | "analytics" | "problemNum" | "questionCompleted" | "keypadElement" | "alignment" | "buttonsVisible" | "containerSizeClass" | "widgetId" | "findWidgets" | "keypadConfiguration" | "reviewModeRubric" | "isLastUsedWidget"> & {
418
+ }, "trackInteraction" | "onChange" | "static" | "analytics" | "problemNum" | "questionCompleted" | "keypadElement" | "alignment" | "buttonsVisible" | "containerSizeClass" | "widgetId" | "findWidgets" | "keypadConfiguration" | "reviewModeRubric" | "isLastUsedWidget"> & {
414
419
  value?: string | undefined;
415
420
  onFocus?: ((blurPath: import("../types").FocusPath) => void) | undefined;
416
421
  onBlur?: ((blurPath: import("../types").FocusPath) => void) | undefined;
@@ -447,6 +452,7 @@ declare const _default: Readonly<{
447
452
  inModal?: boolean | undefined;
448
453
  crossOutEnabled?: boolean | undefined;
449
454
  editorChangeDelay?: number | undefined;
455
+ onWidgetStartProps?: ((widgets: import("../types").PerseusWidgetMap) => import("../types").PerseusWidgetMap) | undefined;
450
456
  }> & {
451
457
  GroupMetadataEditor: NonNullable<React.ComponentType<any> | undefined>;
452
458
  baseElements: {
@@ -120,6 +120,7 @@ declare const _default: Readonly<{
120
120
  inModal?: boolean | undefined;
121
121
  crossOutEnabled?: boolean | undefined;
122
122
  editorChangeDelay?: number | undefined;
123
+ onWidgetStartProps?: ((widgets: import("../types").PerseusWidgetMap) => import("../types").PerseusWidgetMap) | undefined;
123
124
  }>;
124
125
  choices: readonly string[];
125
126
  imageAlt: string;
@@ -179,6 +180,7 @@ declare const _default: Readonly<{
179
180
  inModal?: boolean | undefined;
180
181
  crossOutEnabled?: boolean | undefined;
181
182
  editorChangeDelay?: number | undefined;
183
+ onWidgetStartProps?: ((widgets: import("../types").PerseusWidgetMap) => import("../types").PerseusWidgetMap) | undefined;
182
184
  }>;
183
185
  choices: readonly string[];
184
186
  imageAlt: string;
package/dist/widgets.d.ts CHANGED
@@ -9,7 +9,7 @@ export declare const registerWidgets: (widgets: ReadonlyArray<WidgetExports>) =>
9
9
  * @param name - the widget that you are trying to replace
10
10
  * @param replacementName - the name of the widget that takes its place
11
11
  *
12
- * e.g. replaceWidget("transformer", "always-correct") will make it so the
12
+ * e.g. replaceWidget("transformer", "deprecated-standin") will make it so the
13
13
  * transformer widget is replaced by the always correct widget
14
14
  */
15
15
  export declare const replaceWidget: (name: string, replacementName: string) => void;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Core Perseus API (includes renderers and widgets)",
4
4
  "author": "Khan Academy",
5
5
  "license": "MIT",
6
- "version": "18.0.1",
6
+ "version": "19.1.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -23,8 +23,8 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@khanacademy/kas": "^0.3.7",
26
- "@khanacademy/kmath": "^0.1.8",
27
- "@khanacademy/math-input": "^16.5.1",
26
+ "@khanacademy/kmath": "^0.1.9",
27
+ "@khanacademy/math-input": "^17.0.0",
28
28
  "@khanacademy/perseus-core": "1.4.1",
29
29
  "@khanacademy/perseus-linter": "^0.3.10",
30
30
  "@khanacademy/pure-markdown": "^0.2.13",
@@ -63,7 +63,6 @@
63
63
  "jquery": "^2.1.1",
64
64
  "katex": "^0.11.1",
65
65
  "lodash.debounce": "^4.0.8",
66
- "mathquill": "git+https://git@github.com/Khan/mathquill.git#48410e80d760bbd5105544d4a4ab459a28dc2cbc",
67
66
  "perseus-build-settings": "^0.3.0",
68
67
  "prop-types": "^15.6.1",
69
68
  "react": "16.14.0",