diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index 6f9ff9c54e..fb342746f6 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -43,7 +43,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} projectToken: ${{ secrets.CHROMATIC_APP_CODE }} autoAcceptChanges: "main" - onlyStoryFiles: "**/*regression.stories.tsx" + onlyStoryFiles: "**/*-regression.stories.tsx" # NOTE: We cannot enable `onlyChanged` because it is # incompatible with `onlyStoryFiles` which we use above. # onlyChanged: true # Enable TurboSnap! diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index f4b81fb8b7..925f19a4ae 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -41,6 +41,16 @@ const preview: Preview = { // These parameters apply to all stories, both inside and outside the fixture // framework. parameters: { + // Disables Chromatic's snapshotting on a global level + // We disable snapshotting globally because we have enabled + // turbosnaps for `-regression.stories.tsx` files. If we have + // snapshots enabled globally, we pay for turbosnaps even for + // skipped stories/tests (which is all of them). + // We then enable snapshots for `-regression.stories.tsx` files in + // each of those files (unfortunately, this is how we have to do + // it). + chromatic: {disableSnapshot: true}, + options: { storySort: { order: ["Perseus", "PerseusEditor", "Math-Input", "*"], diff --git a/config/test/custom-matchers.ts b/config/test/custom-matchers.ts index afddd66c24..4f2eab260b 100644 --- a/config/test/custom-matchers.ts +++ b/config/test/custom-matchers.ts @@ -1,6 +1,6 @@ // Ok here we are -import type {PerseusScore} from "../../packages/perseus/src/types"; +import type {PerseusScore} from "../../packages/perseus-score/src/validation.types"; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace diff --git a/dev/CHANGELOG.md b/dev/CHANGELOG.md index d28a288b24..f3789a19e7 100644 --- a/dev/CHANGELOG.md +++ b/dev/CHANGELOG.md @@ -1,5 +1,22 @@ # @khanacademy/perseus-dev-ui +## 5.1.1 + +### Patch Changes + +- [#2101](https://github.com/Khan/perseus/pull/2101) [`9cabe689a`](https://github.com/Khan/perseus/commit/9cabe689a7aa143f95adf4556bf5c10d654a66ae) Thanks [@handeyeco](https://github.com/handeyeco)! - Move scorers and validators to `perseus-score` + +* [#2109](https://github.com/Khan/perseus/pull/2109) [`41ffd4a71`](https://github.com/Khan/perseus/commit/41ffd4a71673399657d7024c206af4fa4e0be267) Thanks [@dependabot](https://github.com/apps/dependabot)! - Updating our wonder-blocks packages with the latest versions. + +* Updated dependencies [[`9cabe689a`](https://github.com/Khan/perseus/commit/9cabe689a7aa143f95adf4556bf5c10d654a66ae), [`41ffd4a71`](https://github.com/Khan/perseus/commit/41ffd4a71673399657d7024c206af4fa4e0be267)]: + - @khanacademy/kmath@0.3.0 + - @khanacademy/perseus-core@3.2.0 + - @khanacademy/math-input@22.2.1 + - @khanacademy/kas@0.4.11 + - @khanacademy/perseus-linter@1.2.13 + - @khanacademy/pure-markdown@0.3.22 + - @khanacademy/simple-markdown@0.13.15 + ## 5.1.0 ### Minor Changes diff --git a/dev/flipbook.tsx b/dev/flipbook.tsx index b6cf09fb3c..1944dffebf 100644 --- a/dev/flipbook.tsx +++ b/dev/flipbook.tsx @@ -39,13 +39,15 @@ import { } from "./flipbook-model"; import {Header} from "./header"; -import type {APIOptions, PerseusScore} from "../packages/perseus/src"; +import type {APIOptions} from "../packages/perseus/src"; import type { InteractiveGraphWidget, PerseusRenderer, PerseusWidget, } from "../packages/perseus-core/src/data-schema"; +import type {PerseusScore} from "../packages/perseus-score/src/validation.types"; import type {PropsFor} from "@khanacademy/wonder-blocks-core"; + import "../packages/perseus/src/styles/perseus-renderer.less"; const exampleCommands = ` diff --git a/dev/package.json b/dev/package.json index 854b4bdaee..5474f3cea3 100644 --- a/dev/package.json +++ b/dev/package.json @@ -3,7 +3,7 @@ "description": "Perseus dev UI", "author": "Khan Academy", "license": "MIT", - "version": "5.1.0", + "version": "5.1.1", "private": true, "repository": { "type": "git", @@ -14,22 +14,22 @@ "dev": "vite" }, "dependencies": { - "@khanacademy/kas": "^0.4.10", - "@khanacademy/kmath": "^0.2.0", - "@khanacademy/math-input": "^22.2.0", - "@khanacademy/perseus-core": "3.1.0", - "@khanacademy/perseus-linter": "^1.2.12", - "@khanacademy/pure-markdown": "^0.3.21", - "@khanacademy/simple-markdown": "^0.13.14", - "@khanacademy/wonder-blocks-banner": "4.0.3", - "@khanacademy/wonder-blocks-icon": "5.0.3", - "@khanacademy/wonder-blocks-icon-button": "6.0.3", - "@khanacademy/wonder-blocks-link": "7.0.3", - "@khanacademy/wonder-blocks-search-field": "4.0.1", - "@khanacademy/wonder-blocks-timing": "6.0.0", - "@khanacademy/wonder-blocks-tokens": "3.0.0", - "@khanacademy/wonder-blocks-toolbar": "5.0.3", - "@khanacademy/wonder-blocks-tooltip": "4.0.1", + "@khanacademy/kas": "^0.4.11", + "@khanacademy/kmath": "^0.3.0", + "@khanacademy/math-input": "^22.2.1", + "@khanacademy/perseus-core": "3.2.0", + "@khanacademy/perseus-linter": "^1.2.13", + "@khanacademy/pure-markdown": "^0.3.22", + "@khanacademy/simple-markdown": "^0.13.15", + "@khanacademy/wonder-blocks-banner": "4.0.5", + "@khanacademy/wonder-blocks-icon": "5.0.5", + "@khanacademy/wonder-blocks-icon-button": "6.0.5", + "@khanacademy/wonder-blocks-link": "7.0.5", + "@khanacademy/wonder-blocks-search-field": "4.0.5", + "@khanacademy/wonder-blocks-timing": "6.0.1", + "@khanacademy/wonder-blocks-tokens": "3.0.1", + "@khanacademy/wonder-blocks-toolbar": "5.0.5", + "@khanacademy/wonder-blocks-tooltip": "4.0.3", "@khanacademy/wonder-stuff-core": "1.5.4", "@phosphor-icons/core": "^2.0.2" }, diff --git a/package.json b/package.json index c8378cc1c2..14805440b2 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,8 @@ "@khanacademy/eslint-config": "^5.0.1", "@khanacademy/eslint-plugin": "^3.1.1", "@khanacademy/mathjax-renderer": "^2.1.1", - "@khanacademy/wonder-blocks-button": "7.0.3", - "@khanacademy/wonder-blocks-layout": "3.0.3", + "@khanacademy/wonder-blocks-button": "7.0.5", + "@khanacademy/wonder-blocks-layout": "3.0.5", "@khanacademy/wonder-blocks-spacing": "^4.0.1", "@popperjs/core": "^2.10.2", "@rollup/plugin-alias": "^3.1.9", diff --git a/packages/kas/CHANGELOG.md b/packages/kas/CHANGELOG.md index 98136c8f53..28be3b48de 100644 --- a/packages/kas/CHANGELOG.md +++ b/packages/kas/CHANGELOG.md @@ -1,5 +1,12 @@ # @khanacademy/kas +## 0.4.11 + +### Patch Changes + +- Updated dependencies [[`9cabe689a`](https://github.com/Khan/perseus/commit/9cabe689a7aa143f95adf4556bf5c10d654a66ae)]: + - @khanacademy/perseus-core@3.2.0 + ## 0.4.10 ### Patch Changes diff --git a/packages/kas/package.json b/packages/kas/package.json index bbf0bce3bb..72af2aa704 100644 --- a/packages/kas/package.json +++ b/packages/kas/package.json @@ -3,7 +3,7 @@ "description": "A lightweight JavaScript CAS for comparing expressions and equations.", "author": "Khan Academy", "license": "MIT", - "version": "0.4.10", + "version": "0.4.11", "publishConfig": { "access": "public" }, @@ -27,7 +27,7 @@ "test": "bash -c 'yarn --silent --cwd \"../..\" test ${@:0} $($([[ ${@: -1} = -* ]] || [[ ${@: -1} = bash ]]) && echo $PWD)'" }, "dependencies": { - "@khanacademy/perseus-core": "3.1.0" + "@khanacademy/perseus-core": "3.2.0" }, "devDependencies": { "jison": "0.4.15", diff --git a/packages/keypad-context/CHANGELOG.md b/packages/keypad-context/CHANGELOG.md index ce69e2b0d1..2a476fd5a1 100644 --- a/packages/keypad-context/CHANGELOG.md +++ b/packages/keypad-context/CHANGELOG.md @@ -1,5 +1,12 @@ # @khanacademy/keypad-context +## 1.0.14 + +### Patch Changes + +- Updated dependencies [[`9cabe689a`](https://github.com/Khan/perseus/commit/9cabe689a7aa143f95adf4556bf5c10d654a66ae)]: + - @khanacademy/perseus-core@3.2.0 + ## 1.0.13 ### Patch Changes diff --git a/packages/keypad-context/package.json b/packages/keypad-context/package.json index 2f06c7e2cb..df8d228ff2 100644 --- a/packages/keypad-context/package.json +++ b/packages/keypad-context/package.json @@ -3,7 +3,7 @@ "description": "Perseus keypad context", "author": "Khan Academy", "license": "MIT", - "version": "1.0.13", + "version": "1.0.14", "publishConfig": { "access": "public" }, @@ -26,7 +26,7 @@ "test": "bash -c 'yarn --silent --cwd \"../..\" test ${@:0} $($([[ ${@: -1} = -* ]] || [[ ${@: -1} = bash ]]) && echo $PWD)'" }, "dependencies": { - "@khanacademy/perseus-core": "3.1.0" + "@khanacademy/perseus-core": "3.2.0" }, "devDependencies": { "react": "^18.2.0" diff --git a/packages/kmath/CHANGELOG.md b/packages/kmath/CHANGELOG.md index d4e8896519..ee88dce1fd 100644 --- a/packages/kmath/CHANGELOG.md +++ b/packages/kmath/CHANGELOG.md @@ -1,5 +1,16 @@ # @khanacademy/kmath +## 0.3.0 + +### Minor Changes + +- [#2101](https://github.com/Khan/perseus/pull/2101) [`9cabe689a`](https://github.com/Khan/perseus/commit/9cabe689a7aa143f95adf4556bf5c10d654a66ae) Thanks [@handeyeco](https://github.com/handeyeco)! - Move scorers and validators to `perseus-score` + +### Patch Changes + +- Updated dependencies [[`9cabe689a`](https://github.com/Khan/perseus/commit/9cabe689a7aa143f95adf4556bf5c10d654a66ae)]: + - @khanacademy/perseus-core@3.2.0 + ## 0.2.0 ### Minor Changes diff --git a/packages/kmath/package.json b/packages/kmath/package.json index e679294f02..effae8860b 100644 --- a/packages/kmath/package.json +++ b/packages/kmath/package.json @@ -3,7 +3,7 @@ "description": "Khan Academy's Javascript Numeric Math Utilities", "author": "Khan Academy", "license": "MIT", - "version": "0.2.0", + "version": "0.3.0", "publishConfig": { "access": "public" }, @@ -25,7 +25,7 @@ "test": "bash -c 'yarn --silent --cwd \"../..\" test ${@:0} $($([[ ${@: -1} = -* ]] || [[ ${@: -1} = bash ]]) && echo $PWD)'" }, "dependencies": { - "@khanacademy/perseus-core": "3.1.0" + "@khanacademy/perseus-core": "3.2.0" }, "devDependencies": { "perseus-build-settings": "^0.4.3", diff --git a/packages/perseus/src/widgets/interactive-graphs/math/angles.test.ts b/packages/kmath/src/angles.test.ts similarity index 100% rename from packages/perseus/src/widgets/interactive-graphs/math/angles.test.ts rename to packages/kmath/src/angles.test.ts diff --git a/packages/perseus/src/widgets/interactive-graphs/math/angles.ts b/packages/kmath/src/angles.ts similarity index 86% rename from packages/perseus/src/widgets/interactive-graphs/math/angles.ts rename to packages/kmath/src/angles.ts index c2d20bd4e8..ec4b55b294 100644 --- a/packages/perseus/src/widgets/interactive-graphs/math/angles.ts +++ b/packages/kmath/src/angles.ts @@ -1,9 +1,8 @@ -import {clockwise} from "../../../util/geometry"; +// This file contains helper functions for working with angles. -import type {Coord} from "@khanacademy/perseus"; -import type {vec} from "mafs"; +import {clockwise} from "./geometry"; -// This file contains helper functions for working with angles. +import type {Coord} from "@khanacademy/perseus-core"; export function convertDegreesToRadians(degrees: number): number { return (degrees / 180) * Math.PI; @@ -11,12 +10,12 @@ export function convertDegreesToRadians(degrees: number): number { // Returns a value between -180 and 180, inclusive. The angle is measured // between the positive x-axis and the given vector. -export function calculateAngleInDegrees([x, y]: vec.Vector2): number { +export function calculateAngleInDegrees([x, y]: Coord): number { return (Math.atan2(y, x) * 180) / Math.PI; } // Converts polar coordinates to cartesian. The th(eta) parameter is in degrees. -export function polar(r: number | vec.Vector2, th: number): vec.Vector2 { +export function polar(r: number | Coord, th: number): Coord { if (typeof r === "number") { r = [r, r]; } @@ -26,10 +25,7 @@ export function polar(r: number | vec.Vector2, th: number): vec.Vector2 { // This function calculates the angle between two points and an optional vertex. // If the vertex is not provided, the angle is measured between the two points. // This does not account for reflex angles or clockwise position. -export const getAngleFromVertex = ( - point: vec.Vector2, - vertex: vec.Vector2, -): number => { +export const getAngleFromVertex = (point: Coord, vertex: Coord): number => { const x = point[0] - vertex[0]; const y = point[1] - vertex[1]; if (!x && !y) { diff --git a/packages/kmath/src/coefficients.ts b/packages/kmath/src/coefficients.ts new file mode 100644 index 0000000000..c33c9ba9b2 --- /dev/null +++ b/packages/kmath/src/coefficients.ts @@ -0,0 +1,62 @@ +import type {SineCoefficient} from "./geometry"; +import type {Coord} from "@khanacademy/perseus-core"; + +export type NamedSineCoefficient = { + amplitude: number; + angularFrequency: number; + phase: number; + verticalOffset: number; +}; + +// TODO: there's another, very similar getSinusoidCoefficients function +// they should probably be merged +export function getSinusoidCoefficients( + coords: ReadonlyArray, +): SineCoefficient { + // It's assumed that p1 is the root and p2 is the first peak + const p1 = coords[0]; + const p2 = coords[1]; + + // Resulting coefficients are canonical for this sine curve + const amplitude = p2[1] - p1[1]; + const angularFrequency = Math.PI / (2 * (p2[0] - p1[0])); + const phase = p1[0] * angularFrequency; + const verticalOffset = p1[1]; + + return [amplitude, angularFrequency, phase, verticalOffset]; +} + +export type QuadraticCoefficient = [number, number, number]; + +// TODO: there's another, very similar getQuadraticCoefficients function +// they should probably be merged +export function getQuadraticCoefficients( + coords: ReadonlyArray, +): QuadraticCoefficient { + 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) { + // Many of the callers assume that the return value is always defined. + // @ts-expect-error - TS2322 - Type 'undefined' is not assignable to type 'QuadraticCoefficient'. + 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]; +} diff --git a/packages/perseus/src/util/geometry.test.ts b/packages/kmath/src/geometry.test.ts similarity index 100% rename from packages/perseus/src/util/geometry.test.ts rename to packages/kmath/src/geometry.test.ts diff --git a/packages/perseus/src/util/geometry.ts b/packages/kmath/src/geometry.ts similarity index 96% rename from packages/perseus/src/util/geometry.ts rename to packages/kmath/src/geometry.ts index ab7eacc0fe..3ded900a65 100644 --- a/packages/perseus/src/util/geometry.ts +++ b/packages/kmath/src/geometry.ts @@ -2,14 +2,16 @@ * A collection of geomtry-related utility functions */ -import {number as knumber, point as kpoint, sum} from "@khanacademy/kmath"; +import { + approximateDeepEqual, + approximateEqual, + type Coord, +} from "@khanacademy/perseus-core"; import _ from "underscore"; -import Util from "../util"; - -import type {Coord, Line} from "../interactive2/types"; +import {number as knumber, point as kpoint, sum} from "@khanacademy/kmath"; -const {eq, deepEq} = Util; +type Line = [Coord, Coord]; // This should really be a readonly tuple of [number, number] export type Range = [number, number]; @@ -21,12 +23,9 @@ export type SineCoefficient = [ number, // verticalOffset ]; -// a, b, c -export type QuadraticCoefficient = [number, number, number]; - // Given a number, return whether it is positive (1), negative (-1), or zero (0) export function sign(val: number): 0 | 1 | -1 { - if (eq(val, 0)) { + if (approximateEqual(val, 0)) { return 0; } return val > 0 ? 1 : -1; @@ -39,7 +38,7 @@ export function ccw(a: Coord, b: Coord, c: Coord): number { } export function collinear(a: Coord, b: Coord, c: Coord): boolean { - return eq(ccw(a, b, c), 0); + return approximateEqual(ccw(a, b, c), 0); } // Given rect bounding points A and B, whether point C is inside the rect @@ -229,7 +228,7 @@ export function similar( // @ts-expect-error - TS4104 - The type 'readonly number[]' is 'readonly' and cannot be assigned to the mutable type 'number[]'. sides = rotate(sides, i); - if (deepEq(angles1, angles)) { + if (approximateDeepEqual(angles1, angles)) { const sidePairs = _.zip(sides1, sides); const factors = _.map(sidePairs, function (pair) { @@ -237,7 +236,7 @@ export function similar( }); const same = _.all(factors, function (factor) { - return eq(factors[0], factor); + return approximateEqual(factors[0], factor); }); const congruentEnough = _.all(sidePairs, function (pair) { @@ -304,7 +303,7 @@ export function rotate( } export function getLineEquation(first: Coord, second: Coord): string { - if (eq(first[0], second[0])) { + if (approximateEqual(first[0], second[0])) { return "x = " + first[0].toFixed(3); } const m = (second[1] - first[1]) / (second[0] - first[0]); diff --git a/packages/kmath/src/index.ts b/packages/kmath/src/index.ts index cbeb7d8403..284f4eb02e 100644 --- a/packages/kmath/src/index.ts +++ b/packages/kmath/src/index.ts @@ -5,5 +5,13 @@ export * as vector from "./vector"; export * as point from "./point"; export * as line from "./line"; export * as ray from "./ray"; +export * as angles from "./angles"; +export * as geometry from "./geometry"; +export * as coefficients from "./coefficients"; export {default as KhanMath, sum} from "./math"; + +export type {Range, SineCoefficient} from "./geometry"; +export type {NamedSineCoefficient, QuadraticCoefficient} from "./coefficients"; + +export type * from "./types"; diff --git a/packages/kmath/src/types.ts b/packages/kmath/src/types.ts new file mode 100644 index 0000000000..7c24a6dd7b --- /dev/null +++ b/packages/kmath/src/types.ts @@ -0,0 +1,3 @@ +import type {Coord} from "@khanacademy/perseus-core"; + +export type QuadraticCoords = [Coord, Coord, Coord]; diff --git a/packages/math-input/CHANGELOG.md b/packages/math-input/CHANGELOG.md index 57006885dc..8961176c42 100644 --- a/packages/math-input/CHANGELOG.md +++ b/packages/math-input/CHANGELOG.md @@ -1,5 +1,17 @@ # @khanacademy/math-input +## 22.2.1 + +### Patch Changes + +- [#2101](https://github.com/Khan/perseus/pull/2101) [`9cabe689a`](https://github.com/Khan/perseus/commit/9cabe689a7aa143f95adf4556bf5c10d654a66ae) Thanks [@handeyeco](https://github.com/handeyeco)! - Move scorers and validators to `perseus-score` + +* [#2109](https://github.com/Khan/perseus/pull/2109) [`41ffd4a71`](https://github.com/Khan/perseus/commit/41ffd4a71673399657d7024c206af4fa4e0be267) Thanks [@dependabot](https://github.com/apps/dependabot)! - Updating our wonder-blocks packages with the latest versions. + +* Updated dependencies [[`9cabe689a`](https://github.com/Khan/perseus/commit/9cabe689a7aa143f95adf4556bf5c10d654a66ae)]: + - @khanacademy/perseus-core@3.2.0 + - @khanacademy/keypad-context@1.0.14 + ## 22.2.0 ### Minor Changes diff --git a/packages/math-input/package.json b/packages/math-input/package.json index 7d880032df..d212e52a37 100644 --- a/packages/math-input/package.json +++ b/packages/math-input/package.json @@ -3,7 +3,7 @@ "description": "Khan Academy's new expression editor for the mobile web.", "author": "Khan Academy", "license": "MIT", - "version": "22.2.0", + "version": "22.2.1", "publishConfig": { "access": "public" }, @@ -40,17 +40,17 @@ "prepublishOnly": "../../utils/package-pre-publish-check.sh" }, "dependencies": { - "@khanacademy/keypad-context": "^1.0.13", - "@khanacademy/perseus-core": "3.1.0", + "@khanacademy/keypad-context": "^1.0.14", + "@khanacademy/perseus-core": "3.2.0", "mathquill": "https://github.com/Khan/mathquill/releases/download/v1.0.0/mathquill-v1.0.0.tgz" }, "devDependencies": { "@khanacademy/mathjax-renderer": "^2.1.1", - "@khanacademy/wonder-blocks-clickable": "5.0.3", - "@khanacademy/wonder-blocks-core": "11.0.0", - "@khanacademy/wonder-blocks-popover": "5.0.1", - "@khanacademy/wonder-blocks-timing": "6.0.0", - "@khanacademy/wonder-blocks-tokens": "3.0.0", + "@khanacademy/wonder-blocks-clickable": "5.0.5", + "@khanacademy/wonder-blocks-core": "11.1.0", + "@khanacademy/wonder-blocks-popover": "5.0.3", + "@khanacademy/wonder-blocks-timing": "6.0.1", + "@khanacademy/wonder-blocks-tokens": "3.0.1", "@khanacademy/wonder-stuff-core": "1.5.4", "@phosphor-icons/core": "^2.0.2", "aphrodite": "^1.2.5", @@ -64,11 +64,11 @@ }, "peerDependencies": { "@khanacademy/mathjax-renderer": "^2.1.1", - "@khanacademy/wonder-blocks-clickable": "5.0.3", - "@khanacademy/wonder-blocks-core": "11.0.0", - "@khanacademy/wonder-blocks-popover": "5.0.1", - "@khanacademy/wonder-blocks-timing": "6.0.0", - "@khanacademy/wonder-blocks-tokens": "3.0.0", + "@khanacademy/wonder-blocks-clickable": "5.0.5", + "@khanacademy/wonder-blocks-core": "11.1.0", + "@khanacademy/wonder-blocks-popover": "5.0.3", + "@khanacademy/wonder-blocks-timing": "6.0.1", + "@khanacademy/wonder-blocks-tokens": "3.0.1", "@khanacademy/wonder-stuff-core": "1.5.4", "@phosphor-icons/core": "^2.0.2", "aphrodite": "^1.2.5", diff --git a/packages/math-input/src/components/key-handlers/key-translator.ts b/packages/math-input/src/components/key-handlers/key-translator.ts index ced26e7254..6d5b8347bf 100644 --- a/packages/math-input/src/components/key-handlers/key-translator.ts +++ b/packages/math-input/src/components/key-handlers/key-translator.ts @@ -1,5 +1,6 @@ +import {getDecimalSeparator} from "@khanacademy/perseus-core"; + import {MathFieldActionType} from "../../types"; -import {getDecimalSeparator} from "../../utils"; import {mathQuillInstance} from "../input/mathquill-instance"; import handleArrow from "./handle-arrow"; diff --git a/packages/math-input/src/components/keypad/button-assets.tsx b/packages/math-input/src/components/keypad/button-assets.tsx index 732efcd596..5803f6ceca 100644 --- a/packages/math-input/src/components/keypad/button-assets.tsx +++ b/packages/math-input/src/components/keypad/button-assets.tsx @@ -10,9 +10,9 @@ asset. In the future it would be great if these were included from files so that no copying and pasting is necessary. */ +import {getDecimalSeparator} from "@khanacademy/perseus-core"; import * as React from "react"; -import {DecimalSeparator, getDecimalSeparator} from "../../utils"; import {useMathInputI18n} from "../i18n-context"; import type Key from "../../data/keys"; @@ -176,10 +176,7 @@ export default function ButtonAsset({id}: Props): React.ReactNode { case "PERIOD": // Different locales use different symbols for the decimal separator // (, vs .) - if ( - id === "DECIMAL" && - getDecimalSeparator(locale) === DecimalSeparator.COMMA - ) { + if (id === "DECIMAL" && getDecimalSeparator(locale) !== ".") { // comma decimal separator return ( { - let separator: string = DecimalSeparator.PERIOD; - - switch (locale) { - // TODO(somewhatabstract): Remove this when Chrome supports the `ka` - // locale properly. - // https://github.com/formatjs/formatjs/issues/1526#issuecomment-559891201 - // - // Supported locales in Chrome: - // https://source.chromium.org/chromium/chromium/src/+/master:third_party/icu/scripts/chrome_ui_languages.list - case "ka": - separator = ","; - break; - - default: - const numberWithDecimalSeparator = 1.1; - // TODO(FEI-3647): Update to use .formatToParts() once we no longer have to - // support Safari 12. - const match = new Intl.NumberFormat(locale) - .format(numberWithDecimalSeparator) - // 0x661 is ARABIC-INDIC DIGIT ONE - // 0x6F1 is EXTENDED ARABIC-INDIC DIGIT ONE - .match(/[^\d\u0661\u06F1]/); - separator = match?.[0] ?? "."; - } - - return separator === "," ? DecimalSeparator.COMMA : DecimalSeparator.PERIOD; -}; - const CDOT_ONLY = [ "az", "cs", diff --git a/packages/perseus-core/CHANGELOG.md b/packages/perseus-core/CHANGELOG.md index b0b569715c..1cdb0c25a3 100644 --- a/packages/perseus-core/CHANGELOG.md +++ b/packages/perseus-core/CHANGELOG.md @@ -1,5 +1,11 @@ # @khanacademy/perseus-core +## 3.2.0 + +### Minor Changes + +- [#2101](https://github.com/Khan/perseus/pull/2101) [`9cabe689a`](https://github.com/Khan/perseus/commit/9cabe689a7aa143f95adf4556bf5c10d654a66ae) Thanks [@handeyeco](https://github.com/handeyeco)! - Move scorers and validators to `perseus-score` + ## 3.1.0 ### Minor Changes diff --git a/packages/perseus-core/package.json b/packages/perseus-core/package.json index ec4d9a1d67..00c61a8ceb 100644 --- a/packages/perseus-core/package.json +++ b/packages/perseus-core/package.json @@ -3,7 +3,7 @@ "description": "Shared Perseus infrastructure", "author": "Khan Academy", "license": "MIT", - "version": "3.1.0", + "version": "3.2.0", "publishConfig": { "access": "public" }, diff --git a/packages/perseus-core/src/index.ts b/packages/perseus-core/src/index.ts index c34af77712..df95a6a770 100644 --- a/packages/perseus-core/src/index.ts +++ b/packages/perseus-core/src/index.ts @@ -3,11 +3,21 @@ export type { KEScore, KeypadContextRendererInterface, RendererInterface, + MarkerType, + InteractiveMarkerType, + Relationship, } from "./types"; export type {ErrorKind} from "./error/errors"; +export type {FunctionTypeMappingKeys} from "./utils/grapher-util"; +export type {Coords} from "./utils/grapher-types"; // Careful, `version.ts` uses this function so it _must_ be imported above it export {addLibraryVersionToPerseusDebug} from "./utils/add-library-version-to-perseus-debug"; +export {default as getMatrixSize} from "./utils/get-matrix-size"; +export {default as getDecimalSeparator} from "./utils/get-decimal-separator"; +export {approximateEqual, approximateDeepEqual} from "./utils/equality"; +export {default as deepClone} from "./utils/deep-clone"; +export * as GrapherUtil from "./utils/grapher-util"; export {libVersion} from "./version"; diff --git a/packages/perseus-core/src/types.ts b/packages/perseus-core/src/types.ts index 2e71b875bd..0369c2b9a5 100644 --- a/packages/perseus-core/src/types.ts +++ b/packages/perseus-core/src/types.ts @@ -27,3 +27,27 @@ export type KEScore = { guess: any; state: any; }; + +// Base marker, with the props that are set by the editor. +export type MarkerType = { + // The list of correct answers expected for the marker. + answers: ReadonlyArray; + // The marker title or description. + label: string; + // The marker coordinates on the question image as percent of image size. + x: number; + y: number; +}; + +// Additional props that are set when user interacts with the marker. +export type InteractiveMarkerType = MarkerType & { + // The user selected list of answers, used to grade the question. + selected?: ReadonlyArray; + // Reveal the correctness state of the user selected answers for the marker. + showCorrectness?: "correct" | "incorrect"; + focused?: boolean; +}; + +// Used for NumberLine +// TODO: can this be merged with PerseusNumberLineWidgetOptions.correctRel? +export type Relationship = "lt" | "gt" | "le" | "ge"; diff --git a/packages/perseus-core/src/utils/deep-clone.test.ts b/packages/perseus-core/src/utils/deep-clone.test.ts new file mode 100644 index 0000000000..682349af3f --- /dev/null +++ b/packages/perseus-core/src/utils/deep-clone.test.ts @@ -0,0 +1,25 @@ +import deepClone from "./deep-clone"; + +describe("deepClone", () => { + it("does nothing to a primitive", () => { + expect(deepClone(3)).toBe(3); + }); + + it("copies an array", () => { + const input = [1, 2, 3]; + + const result = deepClone(input); + + expect(result).toEqual(input); + expect(result).not.toBe(input); + }); + + it("recursively clones array elements", () => { + const input = [[1]]; + + const result = deepClone(input); + + expect(result).toEqual(input); + expect(result[0]).not.toBe(input[0]); + }); +}); diff --git a/packages/perseus-core/src/utils/deep-clone.ts b/packages/perseus-core/src/utils/deep-clone.ts new file mode 100644 index 0000000000..941a89e95a --- /dev/null +++ b/packages/perseus-core/src/utils/deep-clone.ts @@ -0,0 +1,18 @@ +// TODO(benchristel): in the future, we may want to make deepClone work for +// Record as well. Currently, it only does arrays. +type Cloneable = + | null + | undefined + | boolean + | string + | number + | Cloneable[] + | readonly Cloneable[]; +function deepClone(obj: T): T { + if (Array.isArray(obj)) { + return obj.map(deepClone) as T; + } + return obj; +} + +export default deepClone; diff --git a/packages/perseus-core/src/utils/equality.ts b/packages/perseus-core/src/utils/equality.ts new file mode 100644 index 0000000000..9d2bf59e46 --- /dev/null +++ b/packages/perseus-core/src/utils/equality.ts @@ -0,0 +1,55 @@ +import _ from "underscore"; + +/** + * APPROXIMATE equality on numbers and primitives. + */ +export function approximateEqual(x: T, y: T): boolean { + if (typeof x === "number" && typeof y === "number") { + return Math.abs(x - y) < 1e-9; + } + return x === y; +} + +/** + * Deep APPROXIMATE equality on primitives, numbers, arrays, and objects. + * Recursive. + */ +export function approximateDeepEqual(x: T, y: T): boolean { + if (Array.isArray(x) && Array.isArray(y)) { + if (x.length !== y.length) { + return false; + } + for (let i = 0; i < x.length; i++) { + if (!approximateDeepEqual(x[i], y[i])) { + return false; + } + } + return true; + } + if (Array.isArray(x) || Array.isArray(y)) { + return false; + } + if (typeof x === "function" && typeof y === "function") { + return approximateEqual(x, y); + } + if (typeof x === "function" || typeof y === "function") { + return false; + } + if (typeof x === "object" && typeof y === "object" && !!x && !!y) { + return ( + x === y || + (_.all(x, function (v, k) { + // @ts-expect-error - TS2536 - Type 'CollectionKey' cannot be used to index type 'T'. + return approximateDeepEqual(y[k], v); + }) && + _.all(y, function (v, k) { + // @ts-expect-error - TS2536 - Type 'CollectionKey' cannot be used to index type 'T'. + return approximateDeepEqual(x[k], v); + })) + ); + } + if ((typeof x === "object" && !!x) || (typeof y === "object" && !!y)) { + return false; + } + return approximateEqual(x, y); +} diff --git a/packages/perseus/src/widgets/expression/get-decimal-separator.ts b/packages/perseus-core/src/utils/get-decimal-separator.ts similarity index 100% rename from packages/perseus/src/widgets/expression/get-decimal-separator.ts rename to packages/perseus-core/src/utils/get-decimal-separator.ts diff --git a/packages/perseus-core/src/utils/get-matrix-size.ts b/packages/perseus-core/src/utils/get-matrix-size.ts new file mode 100644 index 0000000000..1388852973 --- /dev/null +++ b/packages/perseus-core/src/utils/get-matrix-size.ts @@ -0,0 +1,27 @@ +import _ from "underscore"; + +function getMatrixSize(matrix: ReadonlyArray>) { + const matrixSize = [1, 1]; + + // We need to find the widest row and tallest column to get the correct + // matrix size. + _(matrix).each((matrixRow, row) => { + let rowWidth = 0; + _(matrixRow).each((matrixCol, col) => { + if (matrixCol != null && matrixCol.toString().length) { + rowWidth = col + 1; + } + }); + + // Matrix width: + matrixSize[1] = Math.max(matrixSize[1], rowWidth); + + // Matrix height: + if (rowWidth > 0) { + matrixSize[0] = Math.max(matrixSize[0], row + 1); + } + }); + return matrixSize; +} + +export default getMatrixSize; diff --git a/packages/perseus/src/widgets/grapher/grapher-types.ts b/packages/perseus-core/src/utils/grapher-types.ts similarity index 97% rename from packages/perseus/src/widgets/grapher/grapher-types.ts rename to packages/perseus-core/src/utils/grapher-types.ts index c004902cbb..232f91831d 100644 --- a/packages/perseus/src/widgets/grapher/grapher-types.ts +++ b/packages/perseus-core/src/utils/grapher-types.ts @@ -1,4 +1,4 @@ -import type {Coord} from "@khanacademy/perseus"; +import type {Coord} from "../data-schema"; export type Coords = [Coord, Coord]; diff --git a/packages/perseus-core/src/utils/grapher-util.ts b/packages/perseus-core/src/utils/grapher-util.ts new file mode 100644 index 0000000000..072b9d8f58 --- /dev/null +++ b/packages/perseus-core/src/utils/grapher-util.ts @@ -0,0 +1,646 @@ +import _ from "underscore"; + +import {approximateDeepEqual} from "./equality"; + +import type { + LinearType, + QuadraticType, + SinusoidType, + TangentType, + ExponentialType, + LogarithmType, + AbsoluteValueType, + Coords, +} from "./grapher-types"; +import type {Coord} from "../data-schema"; + +export const MOVABLES = { + PLOT: "PLOT", + PARABOLA: "PARABOLA", + SINUSOID: "SINUSOID", +}; + +// TODO(charlie): These really need to go into a utility file as they're being +// used by both interactive-graph and now grapher. +function canonicalSineCoefficients(coeffs: any) { + // For a curve of the form f(x) = a * Sin(b * x - c) + d, + // this function ensures that a, b > 0, and c is its + // smallest possible positive value. + let amplitude = coeffs[0]; + let angularFrequency = coeffs[1]; + let phase = coeffs[2]; + const verticalOffset = coeffs[3]; + + // Guarantee a > 0 + if (amplitude < 0) { + amplitude *= -1; + angularFrequency *= -1; + phase *= -1; + } + + const period = 2 * Math.PI; + // Guarantee b > 0 + if (angularFrequency < 0) { + angularFrequency *= -1; + phase *= -1; + phase += period / 2; + } + + // Guarantee c is smallest possible positive value + while (phase > 0) { + phase -= period; + } + while (phase < 0) { + phase += period; + } + + return [amplitude, angularFrequency, phase, verticalOffset]; +} + +function canonicalTangentCoefficients(coeffs: any) { + // For a curve of the form f(x) = a * Tan(b * x - c) + d, + // this function ensures that a, b > 0, and c is its + // smallest possible positive value. + let amplitude = coeffs[0]; + let angularFrequency = coeffs[1]; + let phase = coeffs[2]; + const verticalOffset = coeffs[3]; + + // Guarantee a > 0 + if (amplitude < 0) { + amplitude *= -1; + angularFrequency *= -1; + phase *= -1; + } + + const period = Math.PI; + // Guarantee b > 0 + if (angularFrequency < 0) { + angularFrequency *= -1; + phase *= -1; + phase += period / 2; + } + + // Guarantee c is smallest possible positive value + while (phase > 0) { + phase -= period; + } + while (phase < 0) { + phase += period; + } + + return [amplitude, angularFrequency, phase, verticalOffset]; +} + +const PlotDefaults = { + areEqual: function ( + coeffs1: ReadonlyArray, + coeffs2: ReadonlyArray, + ): boolean { + return approximateDeepEqual(coeffs1, coeffs2); + }, + movable: MOVABLES.PLOT, + getPropsForCoeffs: function (coeffs: ReadonlyArray): {fn: any} { + return { + // @ts-expect-error - TS2339 - Property 'getFunctionForCoeffs' does not exist on type '{ readonly areEqual: (coeffs1: any, coeffs2: any) => boolean; readonly Movable: any; readonly getPropsForCoeffs: (coeffs: any) => any; }'. + fn: _.partial(this.getFunctionForCoeffs, coeffs), + }; + }, +} as const; + +const Linear: LinearType = _.extend({}, PlotDefaults, { + url: "https://ka-perseus-graphie.s3.amazonaws.com/67aaf581e6d9ef9038c10558a1f70ac21c11c9f8.png", + + defaultCoords: [ + [0.25, 0.75], + [0.75, 0.75], + ], + + getCoefficients: function ( + coords: Coords, + ): ReadonlyArray | undefined { + const p1 = coords[0]; + const p2 = coords[1]; + + const denom = p2[0] - p1[0]; + const num = p2[1] - p1[1]; + + if (denom === 0) { + return; + } + + const m = num / denom; + const b = p2[1] - m * p2[0]; + return [m, b]; + }, + + getFunctionForCoeffs: function (coeffs: ReadonlyArray, x: number) { + const m = coeffs[0]; + const b = coeffs[1]; + return m * x + b; + }, + + getEquationString: function (coords: Coords) { + const coeffs: ReadonlyArray = this.getCoefficients(coords); + const m: number = coeffs[0]; + const b: number = coeffs[1]; + return "y = " + m.toFixed(3) + "x + " + b.toFixed(3); + }, +}); + +const Quadratic: QuadraticType = _.extend({}, PlotDefaults, { + url: "https://ka-perseus-graphie.s3.amazonaws.com/e23d36e6fc29ee37174e92c9daba2a66677128ab.png", + + defaultCoords: [ + [0.5, 0.5], + [0.75, 0.75], + ], + movable: MOVABLES.PARABOLA, + + getCoefficients: function (coords: Coords): ReadonlyArray { + const p1 = coords[0]; + const p2 = coords[1]; + + // Parabola with vertex (h, k) has form: y = a * (h - k)^2 + k + const h = p1[0]; + const k = p1[1]; + + // Use these to calculate familiar a, b, c + const a = (p2[1] - k) / ((p2[0] - h) * (p2[0] - h)); + const b = -2 * h * a; + const c = a * h * h + k; + + return [a, b, c]; + }, + + getFunctionForCoeffs: function ( + coeffs: ReadonlyArray, + x: number, + ): number { + const a = coeffs[0]; + const b = coeffs[1]; + const c = coeffs[2]; + return (a * x + b) * x + c; + }, + + getPropsForCoeffs: function (coeffs: ReadonlyArray): { + a: number; + b: number; + c: number; + } { + return { + a: coeffs[0], + b: coeffs[1], + c: coeffs[2], + }; + }, + + getEquationString: function (coords: Coords) { + const coeffs = this.getCoefficients(coords); + const a = coeffs[0]; + const b = coeffs[1]; + const c = coeffs[2]; + return ( + "y = " + + a.toFixed(3) + + "x^2 + " + + b.toFixed(3) + + "x + " + + c.toFixed(3) + ); + }, +}); + +const Sinusoid: SinusoidType = _.extend({}, PlotDefaults, { + url: "https://ka-perseus-graphie.s3.amazonaws.com/3d68e7718498475f53b206c2ab285626baf8857e.png", + + defaultCoords: [ + [0.5, 0.5], + [0.6, 0.6], + ], + movable: MOVABLES.SINUSOID, + + getCoefficients: function (coords: Coords) { + const p1 = coords[0]; + const p2 = coords[1]; + + const a = p2[1] - p1[1]; + const b = Math.PI / (2 * (p2[0] - p1[0])); + const c = p1[0] * b; + const d = p1[1]; + + return [a, b, c, d]; + }, + + getFunctionForCoeffs: function (coeffs: ReadonlyArray, x: number) { + const a = coeffs[0]; + const b = coeffs[1]; + const c = coeffs[2]; + const d = coeffs[3]; + return a * Math.sin(b * x - c) + d; + }, + + getPropsForCoeffs: function (coeffs: ReadonlyArray) { + return { + a: coeffs[0], + b: coeffs[1], + c: coeffs[2], + d: coeffs[3], + }; + }, + + getEquationString: function (coords: Coords) { + const coeffs = this.getCoefficients(coords); + const a = coeffs[0]; + const b = coeffs[1]; + const c = coeffs[2]; + const d = coeffs[3]; + return ( + "y = " + + a.toFixed(3) + + " sin(" + + b.toFixed(3) + + "x - " + + c.toFixed(3) + + ") + " + + d.toFixed(3) + ); + }, + + areEqual: function ( + coeffs1: ReadonlyArray, + coeffs2: ReadonlyArray, + ) { + return approximateDeepEqual( + canonicalSineCoefficients(coeffs1), + canonicalSineCoefficients(coeffs2), + ); + }, +}); + +const Tangent: TangentType = _.extend({}, PlotDefaults, { + url: "https://ka-perseus-graphie.s3.amazonaws.com/7db80d23c35214f98659fe1cf0765811c1bbfbba.png", + + defaultCoords: [ + [0.5, 0.5], + [0.75, 0.75], + ], + + getCoefficients: function (coords: Coords) { + const p1 = coords[0]; + const p2 = coords[1]; + + const a = p2[1] - p1[1]; + const b = Math.PI / (4 * (p2[0] - p1[0])); + const c = p1[0] * b; + const d = p1[1]; + + return [a, b, c, d]; + }, + + getFunctionForCoeffs: function (coeffs: ReadonlyArray, x: number) { + const a = coeffs[0]; + const b = coeffs[1]; + const c = coeffs[2]; + const d = coeffs[3]; + return a * Math.tan(b * x - c) + d; + }, + + getEquationString: function (coords: Coords) { + const coeffs = this.getCoefficients(coords); + const a = coeffs[0]; + const b = coeffs[1]; + const c = coeffs[2]; + const d = coeffs[3]; + return ( + "y = " + + a.toFixed(3) + + " sin(" + + b.toFixed(3) + + "x - " + + c.toFixed(3) + + ") + " + + d.toFixed(3) + ); + }, + + areEqual: function ( + coeffs1: ReadonlyArray, + coeffs2: ReadonlyArray, + ) { + return approximateDeepEqual( + canonicalTangentCoefficients(coeffs1), + canonicalTangentCoefficients(coeffs2), + ); + }, +}); + +const Exponential: ExponentialType = _.extend({}, PlotDefaults, { + url: "https://ka-perseus-graphie.s3.amazonaws.com/9cbfad55525e3ce755a31a631b074670a5dad611.png", + + defaultCoords: [ + [0.5, 0.55], + [0.75, 0.75], + ], + + defaultAsymptote: [ + [0, 0.5], + [1.0, 0.5], + ], + + /** + * Add extra constraints for movement of the points or asymptote (below): + * newCoord: [x, y] + * The end position of the point or asymptote endpoint + * oldCoord: [x, y] + * The old position of the point or asymptote endpoint + * coords: + * An array of coordinates representing the proposed end configuration + * of the plot coordinates. + * asymptote: + * An array of coordinates representing the proposed end configuration + * of the asymptote. + * + * Return: either a coordinate (to be used as the resulting coordinate of + * the move) or a boolean, where `true` uses newCoord as the resulting + * coordinate, and `false` uses oldCoord as the resulting coordinate. + */ + extraCoordConstraint: function ( + newCoord: Coord, + oldCoord: Coord, + coords: Coords, + asymptote: Coords, + graph, + ) { + const y: number = asymptote[0][1]; + return _.all(coords, (coord) => coord[1] !== y); + }, + + extraAsymptoteConstraint: function ( + newCoord: Coord, + oldCoord: Coord, + coords: Coords, + asymptote: Coords, + graph, + ): Coord { + const y = newCoord[1]; + const isValid = + _.all(coords, (coord) => coord[1] > y) || + _.all(coords, (coord) => coord[1] < y); + + if (isValid) { + return [oldCoord[0], y]; + } + // Snap the asymptote as close as possible, i.e., if the user moves + // the mouse really quickly into an invalid region + const oldY = oldCoord[1]; + const wasBelow = _.all(coords, (coord) => coord[1] > oldY); + if (wasBelow) { + const bottomMost = _.min(_.map(coords, (coord) => coord[1])); + return [oldCoord[0], bottomMost - graph.snapStep[1]]; + } + const topMost = _.max(_.map(coords, (coord) => coord[1])); + return [oldCoord[0], topMost + graph.snapStep[1]]; + }, + + allowReflectOverAsymptote: true, + + getCoefficients: function ( + coords: Coords, + asymptote: Coords, + ): ReadonlyArray { + const p1 = coords[0]; + const p2 = coords[1]; + + const c = asymptote[0][1]; + const b = Math.log((p1[1] - c) / (p2[1] - c)) / (p1[0] - p2[0]); + const a = (p1[1] - c) / Math.exp(b * p1[0]); + return [a, b, c]; + }, + + getFunctionForCoeffs: function ( + coeffs: ReadonlyArray, + x: number, + ): number { + const a = coeffs[0]; + const b = coeffs[1]; + const c = coeffs[2]; + return a * Math.exp(b * x) + c; + }, + + getEquationString: function (coords: Coords, asymptote: Coords) { + if (!asymptote) { + return null; + } + const coeffs = this.getCoefficients(coords, asymptote); + const a = coeffs[0]; + const b = coeffs[1]; + const c = coeffs[2]; + return ( + "y = " + + a.toFixed(3) + + "e^(" + + b.toFixed(3) + + "x) + " + + c.toFixed(3) + ); + }, +}); + +const Logarithm: LogarithmType = _.extend({}, PlotDefaults, { + url: "https://ka-perseus-graphie.s3.amazonaws.com/f6491e99d34af34d924bfe0231728ad912068dc3.png", + + defaultCoords: [ + [0.55, 0.5], + [0.75, 0.75], + ], + + defaultAsymptote: [ + [0.5, 0], + [0.5, 1.0], + ], + + extraCoordConstraint: function ( + newCoord: Coord, + oldCoord: Coord, + coords: Coord, + asymptote: Coords, + graph, + ) { + const x = asymptote[0][0]; + return ( + _.all(coords, (coord) => coord[0] !== x) && + coords[0][1] !== coords[1][1] + ); + }, + + extraAsymptoteConstraint: function ( + newCoord: Coord, + oldCoord: Coord, + coords: Coords, + asymptote: Coords, + graph, + ): ReadonlyArray { + const x = newCoord[0]; + const isValid = + _.all(coords, (coord) => coord[0] > x) || + _.all(coords, (coord) => coord[0] < x); + + if (isValid) { + return [x, oldCoord[1]]; + } + // Snap the asymptote as close as possible, i.e., if the user moves + // the mouse really quickly into an invalid region + const oldX = oldCoord[0]; + const wasLeft = _.all(coords, (coord) => coord[0] > oldX); + if (wasLeft) { + const leftMost = _.min(_.map(coords, (coord) => coord[0])); + return [leftMost - graph.snapStep[0], oldCoord[1]]; + } + const rightMost = _.max(_.map(coords, (coord) => coord[0])); + return [rightMost + graph.snapStep[0], oldCoord[1]]; + }, + + allowReflectOverAsymptote: true, + + getCoefficients: function ( + coords: Coords, + asymptote: Coords, + ): ReadonlyArray | undefined { + // It's easiest to calculate the logarithm's coefficients by thinking + // about it as the inverse of the exponential, so we flip x and y and + // perform some algebra on the coefficients. This also unifies the + // logic between the two 'models'. + const flip = (coord: Coord): Coord => [coord[1], coord[0]]; + const inverseCoeffs = Exponential.getCoefficients( + _.map(coords, flip) as Coords, + _.map(asymptote, flip) as Coords, + ); + if (inverseCoeffs) { + const c = -inverseCoeffs[2] / inverseCoeffs[0]; + const b = 1 / inverseCoeffs[0]; + const a = 1 / inverseCoeffs[1]; + return [a, b, c]; + } + }, + + getFunctionForCoeffs: function ( + coeffs: ReadonlyArray, + x: number, + asymptote: Coords, + ) { + const a = coeffs[0]; + const b = coeffs[1]; + const c = coeffs[2]; + return a * Math.log(b * x + c); + }, + + getEquationString: function (coords: Coords, asymptote: Coords) { + if (!asymptote) { + return null; + } + const coeffs: ReadonlyArray = this.getCoefficients( + coords, + asymptote, + ); + const a = coeffs[0]; + const b = coeffs[1]; + const c = coeffs[2]; + return ( + "y = ln(" + + a.toFixed(3) + + "x + " + + b.toFixed(3) + + ") + " + + c.toFixed(3) + ); + }, +}); + +const AbsoluteValue: AbsoluteValueType = _.extend({}, PlotDefaults, { + url: "https://ka-perseus-graphie.s3.amazonaws.com/8256a630175a0cb1d11de223d6de0266daf98721.png", + + defaultCoords: [ + [0.5, 0.5], + [0.75, 0.75], + ], + + getCoefficients: function ( + coords: Coords, + ): ReadonlyArray | undefined { + const p1 = coords[0]; + const p2 = coords[1]; + + const denom = p2[0] - p1[0]; + const num = p2[1] - p1[1]; + + if (denom === 0) { + return; + } + + let m = Math.abs(num / denom); + if (p2[1] < p1[1]) { + m *= -1; + } + const horizontalOffset = p1[0]; + const verticalOffset = p1[1]; + + return [m, horizontalOffset, verticalOffset]; + }, + + getFunctionForCoeffs: function (coeffs: ReadonlyArray, x: number) { + const m = coeffs[0]; + const horizontalOffset = coeffs[1]; + const verticalOffset = coeffs[2]; + return m * Math.abs(x - horizontalOffset) + verticalOffset; + }, + + getEquationString: function (coords: Coords) { + const coeffs: ReadonlyArray = this.getCoefficients(coords); + const m = coeffs[0]; + const horizontalOffset = coeffs[1]; + const verticalOffset = coeffs[2]; + return ( + "y = " + + m.toFixed(3) + + "| x - " + + horizontalOffset.toFixed(3) + + "| + " + + verticalOffset.toFixed(3) + ); + }, +}); + +/* Utility functions for dealing with graphing interfaces. */ +const functionTypeMapping = { + linear: Linear, + quadratic: Quadratic, + sinusoid: Sinusoid, + tangent: Tangent, + exponential: Exponential, + logarithm: Logarithm, + absolute_value: AbsoluteValue, +} as const; + +export const allTypes: any = _.keys(functionTypeMapping); + +export type FunctionTypeMappingKeys = keyof typeof functionTypeMapping; + +type ConditionalGraderType = + // prettier-ignore + T extends "linear" ? LinearType + : T extends "quadratic" ? QuadraticType + : T extends "sinusoid" ? SinusoidType + : T extends "tangent" ? TangentType + : T extends "exponential" ? ExponentialType + : T extends "logarithm" ? LogarithmType + : T extends "absolute_value" ? AbsoluteValueType + : never; + +export function functionForType( + type: T, +): ConditionalGraderType { + // @ts-expect-error: TypeScript doesn't know how to use deal with generics + // and conditional types in this way. + return functionTypeMapping[type]; +} diff --git a/packages/perseus-editor/CHANGELOG.md b/packages/perseus-editor/CHANGELOG.md index d13f5b558e..4f05ea785d 100644 --- a/packages/perseus-editor/CHANGELOG.md +++ b/packages/perseus-editor/CHANGELOG.md @@ -1,5 +1,32 @@ # @khanacademy/perseus-editor +## 17.3.2 + +### Patch Changes + +- Updated dependencies [[`cb15921b8`](https://github.com/Khan/perseus/commit/cb15921b8bdfd850c40610b4df5c9919a668a2a1)]: + - @khanacademy/perseus@51.0.1 + +## 17.3.1 + +### Patch Changes + +- [#2101](https://github.com/Khan/perseus/pull/2101) [`9cabe689a`](https://github.com/Khan/perseus/commit/9cabe689a7aa143f95adf4556bf5c10d654a66ae) Thanks [@handeyeco](https://github.com/handeyeco)! - Move scorers and validators to `perseus-score` + +* [#2126](https://github.com/Khan/perseus/pull/2126) [`518b005f2`](https://github.com/Khan/perseus/commit/518b005f2b0b9a173dec6526a7b5c808062fe144) Thanks [@benchristel](https://github.com/benchristel)! - Fix a React warning about non-unique component keys in the exercise editor. + +- [#2109](https://github.com/Khan/perseus/pull/2109) [`41ffd4a71`](https://github.com/Khan/perseus/commit/41ffd4a71673399657d7024c206af4fa4e0be267) Thanks [@dependabot](https://github.com/apps/dependabot)! - Updating our wonder-blocks packages with the latest versions. + +- Updated dependencies [[`165305e11`](https://github.com/Khan/perseus/commit/165305e11c5ba196e1a2a9c4fd814d387d34dc55), [`6f2813cfc`](https://github.com/Khan/perseus/commit/6f2813cfcb6bce063d8f0f8f66219ce0123aac66), [`faccc2d59`](https://github.com/Khan/perseus/commit/faccc2d5959a4a7051720f7a3dfe4a4875b6ace9), [`9cabe689a`](https://github.com/Khan/perseus/commit/9cabe689a7aa143f95adf4556bf5c10d654a66ae), [`d96821e08`](https://github.com/Khan/perseus/commit/d96821e08b3f80eb0a277882f4a8a40330b27adc), [`0f8d11c0b`](https://github.com/Khan/perseus/commit/0f8d11c0b8c00a10eb49f2d84b664803c5c83f3f), [`41ffd4a71`](https://github.com/Khan/perseus/commit/41ffd4a71673399657d7024c206af4fa4e0be267)]: + - @khanacademy/perseus@51.0.0 + - @khanacademy/kmath@0.3.0 + - @khanacademy/perseus-core@3.2.0 + - @khanacademy/perseus-score@1.1.0 + - @khanacademy/math-input@22.2.1 + - @khanacademy/kas@0.4.11 + - @khanacademy/keypad-context@1.0.14 + - @khanacademy/pure-markdown@0.3.22 + ## 17.3.0 ### Minor Changes diff --git a/packages/perseus-editor/package.json b/packages/perseus-editor/package.json index 5206ee39fc..3d09bac212 100644 --- a/packages/perseus-editor/package.json +++ b/packages/perseus-editor/package.json @@ -3,7 +3,7 @@ "description": "Perseus editors", "author": "Khan Academy", "license": "MIT", - "version": "17.3.0", + "version": "17.3.2", "publishConfig": { "access": "public" }, @@ -35,32 +35,33 @@ "test": "bash -c 'yarn --silent --cwd \"../..\" test ${@:0} $($([[ ${@: -1} = -* ]] || [[ ${@: -1} = bash ]]) && echo $PWD)'" }, "dependencies": { - "@khanacademy/kas": "^0.4.10", - "@khanacademy/keypad-context": "^1.0.13", - "@khanacademy/kmath": "^0.2.0", - "@khanacademy/math-input": "^22.2.0", - "@khanacademy/perseus": "^50.1.0", - "@khanacademy/perseus-core": "3.1.0", - "@khanacademy/pure-markdown": "^0.3.21", + "@khanacademy/kas": "^0.4.11", + "@khanacademy/keypad-context": "^1.0.14", + "@khanacademy/kmath": "^0.3.0", + "@khanacademy/math-input": "^22.2.1", + "@khanacademy/perseus": "^51.0.1", + "@khanacademy/perseus-core": "3.2.0", + "@khanacademy/perseus-score": "^1.1.0", + "@khanacademy/pure-markdown": "^0.3.22", "mafs": "^0.19.0" }, "devDependencies": { - "@khanacademy/perseus-linter": "^1.2.12", - "@khanacademy/wonder-blocks-accordion": "3.0.1", - "@khanacademy/wonder-blocks-banner": "4.0.3", - "@khanacademy/wonder-blocks-button": "7.0.3", - "@khanacademy/wonder-blocks-clickable": "5.0.3", - "@khanacademy/wonder-blocks-core": "11.0.0", - "@khanacademy/wonder-blocks-dropdown": "7.0.1", - "@khanacademy/wonder-blocks-form": "6.0.1", - "@khanacademy/wonder-blocks-icon": "5.0.3", - "@khanacademy/wonder-blocks-icon-button": "6.0.3", - "@khanacademy/wonder-blocks-pill": "3.0.3", - "@khanacademy/wonder-blocks-switch": "3.0.1", - "@khanacademy/wonder-blocks-timing": "6.0.0", - "@khanacademy/wonder-blocks-tokens": "3.0.0", - "@khanacademy/wonder-blocks-tooltip": "4.0.1", - "@khanacademy/wonder-blocks-typography": "3.0.3", + "@khanacademy/perseus-linter": "^1.2.13", + "@khanacademy/wonder-blocks-accordion": "3.0.3", + "@khanacademy/wonder-blocks-banner": "4.0.5", + "@khanacademy/wonder-blocks-button": "7.0.5", + "@khanacademy/wonder-blocks-clickable": "5.0.5", + "@khanacademy/wonder-blocks-core": "11.1.0", + "@khanacademy/wonder-blocks-dropdown": "7.0.5", + "@khanacademy/wonder-blocks-form": "6.0.5", + "@khanacademy/wonder-blocks-icon": "5.0.5", + "@khanacademy/wonder-blocks-icon-button": "6.0.5", + "@khanacademy/wonder-blocks-pill": "3.0.5", + "@khanacademy/wonder-blocks-switch": "3.0.3", + "@khanacademy/wonder-blocks-timing": "6.0.1", + "@khanacademy/wonder-blocks-tokens": "3.0.1", + "@khanacademy/wonder-blocks-tooltip": "4.0.3", + "@khanacademy/wonder-blocks-typography": "3.0.5", "@khanacademy/wonder-stuff-core": "1.5.4", "@phosphor-icons/core": "^2.0.2", "aphrodite": "^1.2.5", @@ -74,21 +75,21 @@ "underscore": "^1.4.4" }, "peerDependencies": { - "@khanacademy/wonder-blocks-accordion": "3.0.1", - "@khanacademy/wonder-blocks-banner": "4.0.3", - "@khanacademy/wonder-blocks-button": "7.0.3", - "@khanacademy/wonder-blocks-clickable": "5.0.3", - "@khanacademy/wonder-blocks-core": "11.0.0", - "@khanacademy/wonder-blocks-dropdown": "7.0.1", - "@khanacademy/wonder-blocks-form": "6.0.1", - "@khanacademy/wonder-blocks-icon": "5.0.3", - "@khanacademy/wonder-blocks-icon-button": "6.0.3", - "@khanacademy/wonder-blocks-pill": "3.0.3", - "@khanacademy/wonder-blocks-switch": "3.0.1", - "@khanacademy/wonder-blocks-timing": "6.0.0", - "@khanacademy/wonder-blocks-tokens": "3.0.0", - "@khanacademy/wonder-blocks-tooltip": "4.0.1", - "@khanacademy/wonder-blocks-typography": "3.0.3", + "@khanacademy/wonder-blocks-accordion": "3.0.3", + "@khanacademy/wonder-blocks-banner": "4.0.5", + "@khanacademy/wonder-blocks-button": "7.0.5", + "@khanacademy/wonder-blocks-clickable": "5.0.5", + "@khanacademy/wonder-blocks-core": "11.1.0", + "@khanacademy/wonder-blocks-dropdown": "7.0.5", + "@khanacademy/wonder-blocks-form": "6.0.5", + "@khanacademy/wonder-blocks-icon": "5.0.5", + "@khanacademy/wonder-blocks-icon-button": "6.0.5", + "@khanacademy/wonder-blocks-pill": "3.0.5", + "@khanacademy/wonder-blocks-switch": "3.0.3", + "@khanacademy/wonder-blocks-timing": "6.0.1", + "@khanacademy/wonder-blocks-tokens": "3.0.1", + "@khanacademy/wonder-blocks-tooltip": "4.0.3", + "@khanacademy/wonder-blocks-typography": "3.0.5", "@khanacademy/wonder-stuff-core": "1.5.4", "@phosphor-icons/core": "^2.0.2", "aphrodite": "^1.2.5", diff --git a/packages/perseus-editor/src/__tests__/editor.test.tsx b/packages/perseus-editor/src/__tests__/editor.test.tsx index 2eb2fc1413..35b7f392f6 100644 --- a/packages/perseus-editor/src/__tests__/editor.test.tsx +++ b/packages/perseus-editor/src/__tests__/editor.test.tsx @@ -143,4 +143,26 @@ describe("Editor", () => { undefined, ); }); + + it("should not log a warning given a widget with an undefined key", () => { + const consoleErrorSpy = jest.spyOn(console, "error"); + + render( + , + ); + + expect(consoleErrorSpy).not.toHaveBeenCalled(); + }); }); diff --git a/packages/perseus-editor/src/components/graph-settings.tsx b/packages/perseus-editor/src/components/graph-settings.tsx index 4ae48751f5..4f551f628e 100644 --- a/packages/perseus-editor/src/components/graph-settings.tsx +++ b/packages/perseus-editor/src/components/graph-settings.tsx @@ -15,8 +15,7 @@ import * as React from "react"; import ReactDOM from "react-dom"; import _ from "underscore"; -import type {Coords} from "@khanacademy/perseus"; -import type {MarkingsType} from "@khanacademy/perseus-core"; +import type {Coords, MarkingsType} from "@khanacademy/perseus-core"; const {ButtonGroup, InfoTip, RangeInput} = components; diff --git a/packages/perseus-editor/src/editor.tsx b/packages/perseus-editor/src/editor.tsx index 13a66f2a17..99a357b3c3 100644 --- a/packages/perseus-editor/src/editor.tsx +++ b/packages/perseus-editor/src/editor.tsx @@ -250,6 +250,11 @@ class Editor extends React.Component { } return ( { onRemove={this._handleWidgetEditorRemove.bind(this, id)} apiOptions={this.props.apiOptions} widgetIsOpen={this.props.widgetIsOpen} - {...this.props.widgets[id]} /> ); } diff --git a/packages/perseus-editor/src/widgets/grapher-editor.tsx b/packages/perseus-editor/src/widgets/grapher-editor.tsx index f2056e96f5..9b2d1631bb 100644 --- a/packages/perseus-editor/src/widgets/grapher-editor.tsx +++ b/packages/perseus-editor/src/widgets/grapher-editor.tsx @@ -7,6 +7,7 @@ import { containerSizeClass, getInteractiveBoxFromSizeClass, } from "@khanacademy/perseus"; +import {GrapherUtil as CoreGrapherUtil} from "@khanacademy/perseus-core"; import * as React from "react"; import _ from "underscore"; @@ -16,7 +17,6 @@ const {InfoTip, MultiButtonGroup} = components; const Grapher = GrapherWidget.widget; const { DEFAULT_GRAPHER_PROPS, - allTypes, chooseType, defaultPlotProps, getEquationString, @@ -141,7 +141,7 @@ class GrapherEditor extends React.Component { diff --git a/packages/perseus-editor/src/widgets/input-number-editor.tsx b/packages/perseus-editor/src/widgets/input-number-editor.tsx index af93315324..9095e7f2e7 100644 --- a/packages/perseus-editor/src/widgets/input-number-editor.tsx +++ b/packages/perseus-editor/src/widgets/input-number-editor.tsx @@ -1,4 +1,5 @@ import {components, PerseusI18nContext, Util} from "@khanacademy/perseus"; +import {inputNumberAnswerTypes} from "@khanacademy/perseus-score"; import * as React from "react"; import _ from "underscore"; @@ -9,41 +10,6 @@ import type {PerseusInputNumberWidgetOptions} from "@khanacademy/perseus-core"; const {InfoTip} = components; -const answerTypes = { - number: { - name: "Numbers", - forms: "integer, decimal, proper, improper, mixed", - }, - decimal: { - name: "Decimals", - forms: "decimal", - }, - integer: { - name: "Integers", - forms: "integer", - }, - rational: { - name: "Fractions and mixed numbers", - forms: "integer, proper, improper, mixed", - }, - improper: { - name: "Improper numbers (no mixed)", - forms: "integer, proper, improper", - }, - mixed: { - name: "Mixed numbers (no improper)", - forms: "integer, proper, mixed", - }, - percent: { - name: "Numbers or percents", - forms: "integer, decimal, proper, improper, mixed, percent", - }, - pi: { - name: "Numbers with pi", - forms: "pi", - }, -} as const; - type Props = { value: number; simplify: PerseusInputNumberWidgetOptions["simplify"]; @@ -121,7 +87,7 @@ class InputNumberEditor extends React.Component { render(): React.ReactNode { const answerTypeOptions = _.map( - answerTypes, + inputNumberAnswerTypes, function (v, k) { return ( ( for (const [prop, propParser] of Object.entries(schema)) { const result = propParser(rawValue[prop], ctx.forSubtree(prop)); if (isSuccess(result)) { - ret[prop] = result.value; + if (result.value !== undefined || prop in rawValue) { + ret[prop] = result.value; + } } else { mismatches.push(...result.detail); } diff --git a/packages/perseus/src/util/parse-perseus-json/regression-tests/__snapshots__/parse-perseus-json-snapshot.test.ts.snap b/packages/perseus/src/util/parse-perseus-json/regression-tests/__snapshots__/parse-perseus-json-snapshot.test.ts.snap index d0cc4ff18d..48cd27db6f 100644 --- a/packages/perseus/src/util/parse-perseus-json/regression-tests/__snapshots__/parse-perseus-json-snapshot.test.ts.snap +++ b/packages/perseus/src/util/parse-perseus-json/regression-tests/__snapshots__/parse-perseus-json-snapshot.test.ts.snap @@ -2,7 +2,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/categorizer-missing-randomizeItems.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -16,18 +15,14 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/categorizer-missing- [[☃ categorizer 1]]", "images": {}, - "metadata": undefined, "widgets": { "categorizer 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "categories": [ "Non-renewable Energy Sources", "Renewable Energy Sources", ], - "highlightLint": undefined, "items": [ "Coal", "Wind", @@ -37,7 +32,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/categorizer-missing- "Petroleum", "Solar", ], - "linterContext": undefined, "randomizeItems": false, "static": false, "values": [ @@ -50,7 +44,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/categorizer-missing- 1, ], }, - "static": undefined, "type": "categorizer", "version": { "major": 0, @@ -64,7 +57,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/categorizer-missing- exports[`parseAndTypecheckPerseusItem correctly parses data/categorizer-missing-static.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -78,30 +70,24 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/categorizer-missing- [[☃ categorizer 1]]", "images": {}, - "metadata": undefined, "widgets": { "categorizer 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "categories": [ "one", "two", "three", ], - "highlightLint": undefined, "items": [ "this", "that", "other", ], - "linterContext": undefined, "randomizeItems": true, "static": false, "values": [], }, - "static": undefined, "type": "categorizer", "version": { "major": 0, @@ -115,7 +101,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/categorizer-missing- exports[`parseAndTypecheckPerseusItem correctly parses data/categorizer-with-null-value.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -133,19 +118,16 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/categorizer-with-nul [[☃ categorizer 1]]", "images": {}, - "metadata": undefined, "widgets": { "categorizer 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "categories": [ "Transparent", "Translucent", "Opaque", ], - "highlightLint": undefined, "items": [ "Water", "Clean glass", @@ -185,7 +167,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/categorizer-with-nul exports[`parseAndTypecheckPerseusItem correctly parses data/cs-program-missing-static.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "periodicTable": false, @@ -209,16 +190,13 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/cs-program-missing-s "width": 300, }, }, - "metadata": undefined, "widgets": { "cs-program 1": { "alignment": "block", "graded": true, - "key": undefined, "options": { "height": 400, "programID": "5900231381221376", - "programType": undefined, "settings": [ { "name": "", @@ -230,7 +208,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/cs-program-missing-s "static": false, "width": 400, }, - "static": undefined, "type": "cs-program", "version": { "major": 0, @@ -240,12 +217,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/cs-program-missing-s "numeric-input 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { - "answerForms": undefined, "maxError": 0.05, "message": "", "simplify": "required", @@ -256,11 +230,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/cs-program-missing-s ], "coefficient": false, "labelText": "", - "rightAlign": undefined, "size": "normal", "static": false, }, - "static": undefined, "type": "numeric-input", "version": { "major": 0, @@ -274,32 +246,24 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/cs-program-missing-s exports[`parseAndTypecheckPerseusItem correctly parses data/cs-program-with-null-width.json 1`] = ` { - "answer": undefined, "answerArea": {}, "hints": [], - "itemDataVersion": undefined, "question": { "content": "[[☃ cs-program 1]]", "images": {}, - "metadata": undefined, "widgets": { "cs-program 1": { "alignment": "block", - "graded": undefined, - "key": undefined, "options": { "height": 250, "programID": "4545417404481536", - "programType": undefined, "settings": [], "showButtons": true, "showEditor": true, "static": false, "width": null, }, - "static": undefined, "type": "cs-program", - "version": undefined, }, }, }, @@ -308,7 +272,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/cs-program-with-null exports[`parseAndTypecheckPerseusItem correctly parses data/definition-missing-static.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -330,19 +293,16 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/definition-missing-s ", "images": {}, - "metadata": undefined, "widgets": { "categorizer 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "categories": [ "Increases", "Decreases", "Stays constant", ], - "highlightLint": undefined, "items": [ "Speed", "Acceleration", @@ -368,15 +328,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/definition-missing-s }, }, "definition 1": { - "alignment": undefined, - "graded": undefined, - "key": undefined, "options": { "definition": "", "static": false, "togglePrompt": "", }, - "static": undefined, "type": "definition", "version": { "major": 0, @@ -390,7 +346,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/definition-missing-s exports[`parseAndTypecheckPerseusItem correctly parses data/dropdown-missing-placeholder.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -400,19 +355,14 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/dropdown-missing-pla This is true whether the number is positive, negative, or $0$.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "$(x-x)=0$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], - "itemDataVersion": undefined, "question": { "content": "**Compare the two values using the number line below.** @@ -425,14 +375,10 @@ $\\qquad(x-x)$ [[☃ dropdown 1]] $0$ "width": 460, }, }, - "metadata": undefined, "widgets": { "dropdown 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "ariaLabel": undefined, "choices": [ { "content": ">", @@ -449,11 +395,8 @@ $\\qquad(x-x)$ [[☃ dropdown 1]] $0$ ], "placeholder": "", "static": false, - "visibleLabel": undefined, }, - "static": undefined, "type": "dropdown", - "version": undefined, }, }, }, @@ -462,7 +405,6 @@ $\\qquad(x-x)$ [[☃ dropdown 1]] $0$ exports[`parseAndTypecheckPerseusItem correctly parses data/dropdown-missing-version.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -470,23 +412,16 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/dropdown-missing-ver { "content": "While the Articles of Confederation did not provide for a federal executive, delegates to the Continental Congress did elect a president.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], - "itemDataVersion": undefined, "question": { "content": "**Under the Articles of Confederation[[☃ dropdown 1]] chose the president of the United States.** ", "images": {}, - "metadata": undefined, "widgets": { "dropdown 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "ariaLabel": undefined, "choices": [ { "content": "state legislatures", @@ -503,11 +438,8 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/dropdown-missing-ver ], "placeholder": "", "static": false, - "visibleLabel": undefined, }, - "static": undefined, "type": "dropdown", - "version": undefined, }, }, }, @@ -516,7 +448,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/dropdown-missing-ver exports[`parseAndTypecheckPerseusItem correctly parses data/explanation-missing-widgets-map.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "periodicTable": false, @@ -525,8 +456,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/explanation-missing- { "content": "What times $a$ gives us $b$?", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -534,20 +463,14 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/explanation-missing- > $b=\\blue{0.25}a$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "The *constant of proportionality* $(r)$ in the equation $b=ra$ is $\\blue{0.25}$.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": { "explanation 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "explanation": "Let's check the values of $a$ and $b$ given in the table above.", "hidePrompt": "Okay, I'm convinced.", @@ -555,7 +478,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/explanation-missing- "static": false, "widgets": {}, }, - "static": undefined, "type": "explanation", "version": { "major": 0, @@ -582,17 +504,12 @@ $32$ | $8$ $r = $ [[☃ numeric-input 1]] ", "images": {}, - "metadata": undefined, "widgets": { "numeric-input 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { - "answerForms": undefined, "maxError": null, "message": "", "simplify": "required", @@ -603,11 +520,9 @@ $r = $ [[☃ numeric-input 1]] ", ], "coefficient": false, "labelText": "", - "rightAlign": undefined, "size": "normal", "static": false, }, - "static": undefined, "type": "numeric-input", "version": { "major": 0, @@ -621,7 +536,6 @@ $r = $ [[☃ numeric-input 1]] ", exports[`parseAndTypecheckPerseusItem correctly parses data/expression-answerForm-missing-form.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -641,12 +555,10 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/expression-answerFor [[☃ expression 1]]", "images": {}, - "metadata": undefined, "widgets": { "expression 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -657,19 +569,16 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/expression-answerFor "value": "j<14", }, ], - "ariaLabel": undefined, "buttonSets": [ "basic", "basic relations", "advanced relations", ], - "buttonsVisible": undefined, "functions": [ "f", "g", ], "times": false, - "visibleLabel": undefined, }, "static": false, "type": "expression", @@ -685,12 +594,10 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/expression-answerFor exports[`parseAndTypecheckPerseusItem correctly parses data/expression-missing-buttonSets.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, "hints": [], - "itemDataVersion": undefined, "question": { "content": " $ax + by = c$ @@ -703,12 +610,9 @@ $y=$ [[☃ expression 1]]", "width": 291, }, }, - "metadata": undefined, "widgets": { "expression 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -734,7 +638,6 @@ $y=$ [[☃ expression 1]]", "times": false, "visibleLabel": undefined, }, - "static": undefined, "type": "expression", "version": { "major": 1, @@ -748,7 +651,6 @@ $y=$ [[☃ expression 1]]", exports[`parseAndTypecheckPerseusItem correctly parses data/expression-option-missing-value.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "periodicTable": false, @@ -765,28 +667,22 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/expression-option-mi [[☃ expression 1]]", "images": {}, - "metadata": undefined, "widgets": { "expression 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "answerForms": [], - "ariaLabel": undefined, "buttonSets": [ "basic", ], - "buttonsVisible": undefined, "functions": [ "f", "g", "h", ], "times": false, - "visibleLabel": undefined, }, - "static": undefined, "type": "expression", "version": { "major": 1, @@ -800,7 +696,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/expression-option-mi exports[`parseAndTypecheckPerseusItem correctly parses data/expression-with-null-answer-key.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -815,8 +710,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/expression-with-null "width": 288, }, }, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -826,8 +719,6 @@ $2 \\purple{b} = 6$ $\\purple{b} = 3$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -837,8 +728,6 @@ $3\\pink{\\varphi} = \\pi$ $\\pink{\\varphi} = \\dfrac{\\pi}{3}$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -846,8 +735,6 @@ $\\pink{\\varphi} = \\dfrac{\\pi}{3}$", $\\blue\\theta = \\dfrac{\\pi}{6}$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -862,8 +749,6 @@ $\\begin{align} \\red{a}^2+ \\purple{b}^2 &= 6^2 \\\\ ($\\red{a}$ is positive because it's a length.)", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -871,8 +756,6 @@ $\\begin{align} \\red{a}^2+ \\purple{b}^2 &= 6^2 \\\\ $\\begin{align}\\sin (\\blue{\\theta})&=\\dfrac{3}{6}\\\\ &= \\frac{1}{2}\\end{align}$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -890,8 +773,6 @@ $\\begin{align}\\sin (\\blue{\\theta})&=\\dfrac{3}{6}\\\\ &= \\frac{1}{2}\\end{a - $\\sin (\\blue{\\theta}) =\\dfrac{1}{2}$ ", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -921,12 +802,9 @@ $\\qquad$![](https://ka-perseus-graphie.s3.amazonaws.com/bee05e004428ab4fb0d8af9 "width": 288, }, }, - "metadata": undefined, "widgets": { "expression 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -937,21 +815,17 @@ $\\qquad$![](https://ka-perseus-graphie.s3.amazonaws.com/bee05e004428ab4fb0d8af9 "value": "sqrt(3)*3", }, ], - "ariaLabel": undefined, "buttonSets": [ "basic", "prealgebra", ], - "buttonsVisible": undefined, "functions": [ "f", "g", "h", ], "times": false, - "visibleLabel": undefined, }, - "static": undefined, "type": "expression", "version": { "major": 1, @@ -959,9 +833,7 @@ $\\qquad$![](https://ka-perseus-graphie.s3.amazonaws.com/bee05e004428ab4fb0d8af9 }, }, "expression 2": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -972,21 +844,17 @@ $\\qquad$![](https://ka-perseus-graphie.s3.amazonaws.com/bee05e004428ab4fb0d8af9 "value": "3", }, ], - "ariaLabel": undefined, "buttonSets": [ "basic", "prealgebra", ], - "buttonsVisible": undefined, "functions": [ "f", "g", "h", ], "times": false, - "visibleLabel": undefined, }, - "static": undefined, "type": "expression", "version": { "major": 1, @@ -994,9 +862,7 @@ $\\qquad$![](https://ka-perseus-graphie.s3.amazonaws.com/bee05e004428ab4fb0d8af9 }, }, "expression 3": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -1007,21 +873,17 @@ $\\qquad$![](https://ka-perseus-graphie.s3.amazonaws.com/bee05e004428ab4fb0d8af9 "value": "pi/6", }, ], - "ariaLabel": undefined, "buttonSets": [ "basic", "prealgebra", ], - "buttonsVisible": undefined, "functions": [ "f", "g", "h", ], "times": false, - "visibleLabel": undefined, }, - "static": undefined, "type": "expression", "version": { "major": 1, @@ -1029,9 +891,7 @@ $\\qquad$![](https://ka-perseus-graphie.s3.amazonaws.com/bee05e004428ab4fb0d8af9 }, }, "expression 4": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -1049,21 +909,17 @@ $\\qquad$![](https://ka-perseus-graphie.s3.amazonaws.com/bee05e004428ab4fb0d8af9 "value": "1/2", }, ], - "ariaLabel": undefined, "buttonSets": [ "basic", "prealgebra", ], - "buttonsVisible": undefined, "functions": [ "f", "g", "h", ], "times": false, - "visibleLabel": undefined, }, - "static": undefined, "type": "expression", "version": { "major": 1, @@ -1077,7 +933,6 @@ $\\qquad$![](https://ka-perseus-graphie.s3.amazonaws.com/bee05e004428ab4fb0d8af9 exports[`parseAndTypecheckPerseusItem correctly parses data/graded-group-with-false-hint.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -1095,13 +950,11 @@ To find entry $(i,j)$ of the resulting product matrix, we calculate the vector * ", "images": {}, - "metadata": undefined, "replace": false, "widgets": { "explanation 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": "In general, vector dot product is an operation that takes two vectors of equal dimensions and returns a single real number. @@ -1152,13 +1005,11 @@ The other entries of $\\text{H}$ can be found similarly. "width": 160, }, }, - "metadata": undefined, "replace": false, "widgets": { "graded-group 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "content": "**What is the appropriate calculation of $\\textbf{H}_{2,1}$?** @@ -1168,44 +1019,30 @@ The other entries of $\\text{H}$ can be found similarly. "hasHint": false, "hint": null, "images": {}, - "immutableWidgets": undefined, "title": "", - "widgetEnabled": undefined, "widgets": { "radio 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "$1 \\cdot 4 + 3\\cdot 0 = 4$", "correct": true, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "$4 \\cdot 4 + 3\\cdot 3= 25$", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "$1 \\cdot 3 + 4\\cdot -1 = -1$", - "correct": undefined, "isNoneOfTheAbove": false, - "widgets": undefined, }, ], - "countChoices": undefined, "deselectEnabled": false, "displayCount": null, "hasNoneOfTheAbove": false, "multipleSelect": false, - "noneOfTheAbove": undefined, "onePerLine": true, "randomize": true, }, @@ -1234,7 +1071,6 @@ After calculating all the remaining entries of $\\text{H}$, we get the following $ \\text{H}=\\left[\\begin{array}{rr}4 & -1 \\\\ 4 & 0\\end{array}\\right]$ ", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -1251,12 +1087,10 @@ $ \\text{H}=\\left[\\begin{array}{rr}4 & -1 \\\\ 4 & 0\\end{array}\\right]$ ", [[☃ matrix 1]] ", "images": {}, - "metadata": undefined, "widgets": { "matrix 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "answers": [ [ @@ -1294,7 +1128,6 @@ $ \\text{H}=\\left[\\begin{array}{rr}4 & -1 \\\\ 4 & 0\\end{array}\\right]$ ", exports[`parseAndTypecheckPerseusItem correctly parses data/grapher-with-null-coords.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -1308,12 +1141,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/grapher-with-null-co ", "images": {}, - "metadata": undefined, "widgets": { "grapher 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "availableTypes": [ "linear", @@ -1331,10 +1161,7 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/grapher-with-null-co }, "graph": { "backgroundImage": { - "bottom": undefined, "height": 0, - "left": undefined, - "scale": undefined, "url": null, "width": 0, }, @@ -1370,7 +1197,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/grapher-with-null-co "rulerTicks": 10, "showProtractor": false, "showRuler": false, - "showTooltips": undefined, "snapStep": [ 1, 1, @@ -1382,7 +1208,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/grapher-with-null-co "valid": true, }, }, - "static": undefined, "type": "grapher", "version": { "major": 0, @@ -1396,7 +1221,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/grapher-with-null-co exports[`parseAndTypecheckPerseusItem correctly parses data/hint-missing-images.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -1422,13 +1246,11 @@ If you haven't practiced [Systems of equations with elimination](/e/systems_of_e For more practice, go to [Systems of equations with elimination challenge](/e/systems_of_equations_with_elimination?getready=post).", "images": {}, - "metadata": undefined, "replace": false, "widgets": { "graded-group-set 2": { "alignment": "default", "graded": true, - "key": undefined, "options": { "gradedGroups": [ { @@ -1443,7 +1265,6 @@ $\\begin{align} $x=$ [[☃ numeric-input 1]] $y=$ [[☃ numeric-input 2]]", - "hasHint": undefined, "hint": { "content": "Let's solve the system by using the *elimination method.* In order to eliminate one of the variables, we need to manipulate the equations so that variable has coefficients of the same size but opposite signs in each equation. @@ -1477,7 +1298,6 @@ $\\begin{align} &y=-\\dfrac{1}{3} \\end{align}$", "images": {}, - "metadata": undefined, "widgets": {}, }, "images": {}, @@ -1488,12 +1308,9 @@ $\\begin{align} "numeric-input 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { - "answerForms": undefined, "maxError": null, "message": "", "simplify": "required", @@ -1519,9 +1336,7 @@ $\\begin{align} "numeric-input 2": { "alignment": "default", "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { "answerForms": [ @@ -1564,7 +1379,6 @@ $\\begin{align} $x=$ [[☃ numeric-input 1]] $y=$ [[☃ numeric-input 2]]", - "hasHint": undefined, "hint": { "content": "Let's solve the system by using the *elimination method.* In order to eliminate one of the variables, we need to manipulate the equations so that variable has coefficients of the same size but opposite signs in each equation. @@ -1595,7 +1409,6 @@ $\\begin{align} {72x}-\\maroonD{40y} &= -440 \\\\\\\\ When we solve the resulting equation we obtain that $x = -5$. Then, we can substitute this into one of the original equations and solve for $y$ to obtain $y=2$.", "images": {}, - "metadata": undefined, "widgets": {}, }, "images": {}, @@ -1606,12 +1419,9 @@ When we solve the resulting equation we obtain that $x = -5$. Then, we can subst "numeric-input 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { - "answerForms": undefined, "maxError": null, "message": "", "simplify": "required", @@ -1637,12 +1447,9 @@ When we solve the resulting equation we obtain that $x = -5$. Then, we can subst "numeric-input 2": { "alignment": "default", "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { - "answerForms": undefined, "maxError": null, "message": "", "simplify": "required", @@ -1683,7 +1490,6 @@ When we solve the resulting equation we obtain that $x = -5$. Then, we can subst It is possible to solve any system of linear equations using the substitution method as long as you're comfortable working with fractions in your equations.", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -1699,7 +1505,6 @@ Our strategic supplement version of algebra 1 is for students who are getting cl In case you would like a fuller experience, here is a taste of a skill you can learn in our full algebra 1 course.", "images": {}, - "metadata": undefined, "widgets": {}, }, } @@ -1707,7 +1512,6 @@ In case you would like a fuller experience, here is a taste of a skill you can l exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-allowFullScreen.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -1717,21 +1521,12 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-allow [[☃ image 1]]", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": { "image 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "alt": undefined, "backgroundImage": { - "bottom": undefined, "height": 215, - "left": undefined, - "scale": undefined, - "top": undefined, "url": "https://s3.amazonaws.com/ka-cs-algorithms/hanoi_exercise_step2_1.png", "width": 304, }, @@ -1739,7 +1534,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-allow 304, 215, ], - "caption": undefined, "labels": [], "range": [ [ @@ -1751,10 +1545,7 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-allow 10, ], ], - "static": undefined, - "title": undefined, }, - "static": undefined, "type": "image", "version": { "major": 0, @@ -1773,15 +1564,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-allow [[☃ iframe 1]]", "images": {}, - "metadata": undefined, "widgets": { "iframe 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "allowFullScreen": false, - "allowTopNavigation": undefined, "height": "400", "settings": [ { @@ -1805,7 +1592,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-allow "url": "4772835774169088", "width": 400, }, - "static": undefined, "type": "iframe", "version": { "major": 0, @@ -1819,31 +1605,22 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-allow exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-settings.json 1`] = ` { - "answer": undefined, "answerArea": {}, "hints": [], - "itemDataVersion": undefined, "question": { "content": "[[☃ iframe 1]]", "images": {}, - "metadata": undefined, "widgets": { "iframe 1": { "alignment": "block", - "graded": undefined, - "key": undefined, "options": { "allowFullScreen": false, - "allowTopNavigation": undefined, "height": "550px", - "settings": undefined, "static": false, "url": "https://learnstorm.typeform.com/to/fnQ2tw?", "width": "100%", }, - "static": undefined, "type": "iframe", - "version": undefined, }, }, }, @@ -1852,7 +1629,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-setti exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-static.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "periodicTable": false, @@ -1863,16 +1639,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-stati [[☃ iframe 1]]", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": { "iframe 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "allowFullScreen": true, - "allowTopNavigation": undefined, "height": "235", "settings": [ { @@ -1884,7 +1655,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-stati "url": "https://www.youtube.com/embed/qYD5iwhLzm8?enablejsapi=1&wmode=transparent&modestbranding=1&rel=0&frameborder='0'", "width": "425", }, - "static": undefined, "type": "iframe", "version": { "major": 0, @@ -1901,7 +1671,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-stati "question": { "content": "This is a question.", "images": {}, - "metadata": undefined, "widgets": {}, }, } @@ -1909,7 +1678,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/iframe-missing-stati exports[`parseAndTypecheckPerseusItem correctly parses data/input-number-with-boolean-value.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -1921,8 +1689,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/input-number-with-bo \\red{- 3|x - 5|}& && \\red{- 3|x - 5|} \\\\ \\\\ & -3 &=& 1|x - 5| + 7 \\end{eqnarray} $", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -1932,8 +1698,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/input-number-with-bo \\red{- 7} && &\\red{- 7} \\\\ \\\\ -10 &=& 1|x - 5| \\end{eqnarray} $", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -1941,15 +1705,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/input-number-with-bo $\\qquad -10 = |x - 5| $", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "The absolute value cannot be negative. Therefore, there is no solution.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -1964,23 +1724,17 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/input-number-with-bo [[☃ radio 1]]", "images": {}, - "metadata": undefined, "widgets": { "input-number 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerType": "number", - "customKeypad": undefined, "inexact": false, "maxError": 0.1, - "rightAlign": undefined, "simplify": "required", "size": "small", "value": 0, }, - "static": undefined, "type": "input-number", "version": { "major": 0, @@ -1988,20 +1742,15 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/input-number-with-bo }, }, "input-number 2": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerType": "number", - "customKeypad": undefined, "inexact": false, "maxError": 0.1, - "rightAlign": undefined, "simplify": "required", "size": "small", "value": "true", }, - "static": undefined, "type": "input-number", "version": { "major": 0, @@ -2009,50 +1758,36 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/input-number-with-bo }, }, "radio 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "choices": [ { "clue": "Absolute values cannot be negative.", "content": "$-5$", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { "clue": "Check your signs.", "content": " $5$", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { "clue": "You might have made a sign error.", "content": " $15$", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "There are no solutions.", "correct": true, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], - "countChoices": undefined, "deselectEnabled": false, "displayCount": null, - "hasNoneOfTheAbove": undefined, "multipleSelect": false, "noneOfTheAbove": false, "onePerLine": true, "randomize": false, }, - "static": undefined, "type": "radio", "version": { "major": 0, @@ -2066,7 +1801,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/input-number-with-bo exports[`parseAndTypecheckPerseusItem correctly parses data/interaction-element-missing-constraints.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -2078,12 +1812,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interaction-element- "question": { "content": "[[☃ interaction 1]]", "images": {}, - "metadata": undefined, "widgets": { "interaction 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "elements": [ { @@ -2207,12 +1938,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interaction-element- "graph": { "backgroundImage": { "bottom": 0, - "height": undefined, "left": 0, "scale": 1, - "top": undefined, "url": null, - "width": undefined, }, "box": [ 400, @@ -2257,7 +1985,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interaction-element- }, "static": false, }, - "static": undefined, "type": "interaction", "version": { "major": 0, @@ -2271,10 +1998,8 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interaction-element- exports[`parseAndTypecheckPerseusItem correctly parses data/interaction-element-missing-key.json 1`] = ` { - "answer": undefined, "answerArea": {}, "hints": [], - "itemDataVersion": undefined, "question": { "content": "# Functions introduction @@ -2311,12 +2036,9 @@ Next, we'll look at some other representations of functions!", "width": 400, }, }, - "metadata": undefined, "widgets": { "interaction 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "elements": [ { @@ -2348,12 +2070,9 @@ Next, we'll look at some other representations of functions!", "graph": { "backgroundImage": { "bottom": 0, - "height": undefined, "left": 0, "scale": 1, - "top": undefined, "url": null, - "width": undefined, }, "box": [ 400, @@ -2402,7 +2121,6 @@ Next, we'll look at some other representations of functions!", }, "static": false, }, - "static": undefined, "type": "interaction", "version": { "major": 0, @@ -2410,9 +2128,7 @@ Next, we'll look at some other representations of functions!", }, }, "interaction 2": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "elements": [ { @@ -2444,12 +2160,9 @@ Next, we'll look at some other representations of functions!", "graph": { "backgroundImage": { "bottom": 0, - "height": undefined, "left": 0, "scale": 1, - "top": undefined, "url": null, - "width": undefined, }, "box": [ 400, @@ -2498,7 +2211,6 @@ Next, we'll look at some other representations of functions!", }, "static": false, }, - "static": undefined, "type": "interaction", "version": { "major": 0, @@ -2506,9 +2218,7 @@ Next, we'll look at some other representations of functions!", }, }, "interaction 3": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "elements": [ { @@ -2540,12 +2250,9 @@ Next, we'll look at some other representations of functions!", "graph": { "backgroundImage": { "bottom": 0, - "height": undefined, "left": 0, "scale": 1, - "top": undefined, "url": null, - "width": undefined, }, "box": [ 400, @@ -2594,7 +2301,6 @@ Next, we'll look at some other representations of functions!", }, "static": false, }, - "static": undefined, "type": "interaction", "version": { "major": 0, @@ -2602,9 +2308,7 @@ Next, we'll look at some other representations of functions!", }, }, "interaction 4": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "elements": [ { @@ -2636,12 +2340,9 @@ Next, we'll look at some other representations of functions!", "graph": { "backgroundImage": { "bottom": 0, - "height": undefined, "left": 0, "scale": 1, - "top": undefined, "url": null, - "width": undefined, }, "box": [ 400, @@ -2690,7 +2391,6 @@ Next, we'll look at some other representations of functions!", }, "static": false, }, - "static": undefined, "type": "interaction", "version": { "major": 0, @@ -2698,9 +2398,7 @@ Next, we'll look at some other representations of functions!", }, }, "interaction 5": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "elements": [ { @@ -2732,12 +2430,9 @@ Next, we'll look at some other representations of functions!", "graph": { "backgroundImage": { "bottom": 0, - "height": undefined, "left": 0, "scale": 1, - "top": undefined, "url": null, - "width": undefined, }, "box": [ 400, @@ -2786,7 +2481,6 @@ Next, we'll look at some other representations of functions!", }, "static": false, }, - "static": undefined, "type": "interaction", "version": { "major": 0, @@ -2800,7 +2494,6 @@ Next, we'll look at some other representations of functions!", exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-backgroundImage-with-empty-string-coordinates.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "periodicTable": false, @@ -2815,8 +2508,6 @@ $\\qquad d=\\blue 6+5\\\\~~~~~~~~~~=\\red{11}.$ So we place one point at $(\\blue 6,\\red{11})$.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -2826,8 +2517,6 @@ $\\qquad d=\\blue{10}+5=\\red{15}$. So the second point is at $(\\blue{10},\\red{15})$.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -2840,8 +2529,6 @@ So the second point is at $(\\blue{10},\\red{15})$.", "width": 425, }, }, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -2869,24 +2556,20 @@ $3$ | $8$ [[☃ interactive-graph 1]]", "images": {}, - "metadata": undefined, "widgets": { "interactive-graph 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { "bottom": 0, "height": 0, "left": 0, "scale": 1, - "top": undefined, "url": null, "width": 0, }, "correct": { - "coord": undefined, "coords": [ [ 6, @@ -2898,16 +2581,10 @@ $3$ | $8$ ], ], "numPoints": 2, - "startCoords": undefined, "type": "point", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, "numPoints": 2, - "startCoords": undefined, "type": "point", }, "gridStep": [ @@ -2918,7 +2595,6 @@ $3$ | $8$ "w", "d", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -2934,7 +2610,6 @@ $3$ | $8$ "rulerTicks": 10, "showProtractor": false, "showRuler": false, - "showTooltips": undefined, "snapStep": [ 0.5, 0.5, @@ -2944,7 +2619,6 @@ $3$ | $8$ 1, ], }, - "static": undefined, "type": "interactive-graph", "version": { "major": 0, @@ -2958,10 +2632,8 @@ $3$ | $8$ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-locked-line-missing-showPoint1.json 1`] = ` { - "answer": undefined, "answerArea": {}, "hints": [], - "itemDataVersion": undefined, "question": { "content": "Custom Axis Labels: [[☃ interactive-graph 1]] @@ -2988,24 +2660,15 @@ Locked figures: [[☃ interactive-graph 8]] ", "images": {}, - "metadata": undefined, "widgets": { "interactive-graph 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, "coords": [ [ [ @@ -3069,16 +2732,10 @@ Locked figures: ], ], "numSegments": 6, - "startCoords": undefined, "type": "segment", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, "numSegments": 6, - "startCoords": undefined, "type": "segment", }, "gridStep": [ @@ -3089,7 +2746,6 @@ Locked figures: "\\text{Re}", "\\text{Im}", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -3101,10 +2757,7 @@ Locked figures: 10, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, "showTooltips": false, "snapStep": [ 0.5, @@ -3125,19 +2778,11 @@ Locked figures: "interactive-graph 2": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, "coords": [ [ [ @@ -3150,17 +2795,9 @@ Locked figures: ], ], ], - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, "gridStep": [ @@ -3171,7 +2808,6 @@ Locked figures: "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -3183,10 +2819,7 @@ Locked figures: 100, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, "showTooltips": false, "snapStep": [ 0.5, @@ -3207,31 +2840,16 @@ Locked figures: "interactive-graph 3": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, "height": 0, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, "width": 0, }, "correct": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, "gridStep": [ @@ -3242,7 +2860,6 @@ Locked figures: "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -3254,10 +2871,7 @@ Locked figures: 10, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, "showTooltips": false, "snapStep": [ 2.5, @@ -3278,31 +2892,14 @@ Locked figures: "interactive-graph 4": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, "gridStep": [ @@ -3313,7 +2910,6 @@ Locked figures: "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -3325,10 +2921,7 @@ Locked figures: 3, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, "showTooltips": false, "snapStep": [ 0.25, @@ -3349,31 +2942,14 @@ Locked figures: "interactive-graph 5": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, "gridStep": [ @@ -3384,7 +2960,6 @@ Locked figures: "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -3396,10 +2971,7 @@ Locked figures: 10, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, "showTooltips": false, "snapStep": [ 1, @@ -3420,31 +2992,14 @@ Locked figures: "interactive-graph 6": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, "gridStep": [ @@ -3455,7 +3010,6 @@ Locked figures: "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -3467,10 +3021,7 @@ Locked figures: 5, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, "showTooltips": false, "snapStep": [ 0.25, @@ -3491,31 +3042,14 @@ Locked figures: "interactive-graph 7": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, "gridStep": [ @@ -3526,7 +3060,6 @@ Locked figures: "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -3538,10 +3071,7 @@ Locked figures: 5, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, "showTooltips": false, "snapStep": [ 1, @@ -3562,19 +3092,11 @@ Locked figures: "interactive-graph 8": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, "coords": [ [ [ @@ -3589,7 +3111,6 @@ Locked figures: ], "hasBeenInteractedWith": true, "markings": "graph", - "numSegments": undefined, "range": [ [ -10, @@ -3604,16 +3125,9 @@ Locked figures: 0.5, 0.5, ], - "startCoords": undefined, "type": "segment", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, - "numSegments": undefined, - "startCoords": undefined, "type": "segment", }, "gridStep": [ @@ -3626,54 +3140,44 @@ Locked figures: ], "lockedFigures": [ { - "ariaLabel": undefined, "color": "green", "coord": [ -1, 5, ], "filled": true, - "labels": undefined, "type": "point", }, { - "ariaLabel": undefined, "color": "grayH", "coord": [ 1, 5, ], "filled": false, - "labels": undefined, "type": "point", }, { - "ariaLabel": undefined, "color": "grayH", "kind": "line", - "labels": undefined, "lineStyle": "solid", "points": [ { - "ariaLabel": undefined, "color": "grayH", "coord": [ 0, 1, ], "filled": true, - "labels": undefined, "type": "point", }, { - "ariaLabel": undefined, "color": "grayH", "coord": [ 5, 2, ], "filled": true, - "labels": undefined, "type": "point", }, ], @@ -3684,32 +3188,26 @@ Locked figures: "type": "line", }, { - "ariaLabel": undefined, "color": "grayH", "kind": "line", - "labels": undefined, "lineStyle": "dashed", "points": [ { - "ariaLabel": undefined, "color": "grayH", "coord": [ 0, 0, ], "filled": true, - "labels": undefined, "type": "point", }, { - "ariaLabel": undefined, "color": "grayH", "coord": [ 5, 1, ], "filled": false, - "labels": undefined, "type": "point", }, ], @@ -3720,32 +3218,26 @@ Locked figures: "type": "line", }, { - "ariaLabel": undefined, "color": "pink", "kind": "ray", - "labels": undefined, "lineStyle": "solid", "points": [ { - "ariaLabel": undefined, "color": "pink", "coord": [ 0, -1, ], "filled": true, - "labels": undefined, "type": "point", }, { - "ariaLabel": undefined, "color": "pink", "coord": [ 5, 0, ], "filled": true, - "labels": undefined, "type": "point", }, ], @@ -3756,32 +3248,26 @@ Locked figures: "type": "line", }, { - "ariaLabel": undefined, "color": "pink", "kind": "ray", - "labels": undefined, "lineStyle": "dashed", "points": [ { - "ariaLabel": undefined, "color": "purple", "coord": [ 0, -2, ], "filled": true, - "labels": undefined, "type": "point", }, { - "ariaLabel": undefined, "color": "pink", "coord": [ 5, -1, ], "filled": false, - "labels": undefined, "type": "point", }, ], @@ -3792,32 +3278,26 @@ Locked figures: "type": "line", }, { - "ariaLabel": undefined, "color": "red", "kind": "segment", - "labels": undefined, "lineStyle": "solid", "points": [ { - "ariaLabel": undefined, "color": "red", "coord": [ 0, -3, ], "filled": true, - "labels": undefined, "type": "point", }, { - "ariaLabel": undefined, "color": "red", "coord": [ 5, -2, ], "filled": true, - "labels": undefined, "type": "point", }, ], @@ -3828,32 +3308,26 @@ Locked figures: "type": "line", }, { - "ariaLabel": undefined, "color": "red", "kind": "segment", - "labels": undefined, "lineStyle": "dashed", "points": [ { - "ariaLabel": undefined, "color": "green", "coord": [ 0, -4, ], "filled": true, - "labels": undefined, "type": "point", }, { - "ariaLabel": undefined, "color": "red", "coord": [ 5, -3, ], "filled": false, - "labels": undefined, "type": "point", }, ], @@ -3885,10 +3359,7 @@ Locked figures: 10, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, "showTooltips": false, "snapStep": [ 0.5, @@ -3913,7 +3384,6 @@ Locked figures: exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-missing-graph.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -3929,7 +3399,6 @@ Let's remember what magnetic dip means. It is the angle that the magnetic field *Tip: The **dip** angle is **positive** when the magnetic field **dips**!*", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -3942,21 +3411,15 @@ Here, the dip angle is **positive**, so the magnetic field is **below** the hori As we can see the direction of the vertical component is downwards $(\\downarrow)$, now let's find the magnitude.", "images": {}, - "metadata": undefined, "replace": false, "widgets": { "image 1": { "alignment": "block", "graded": true, - "key": undefined, "options": { "alt": "", "backgroundImage": { - "bottom": undefined, "height": 151, - "left": undefined, - "scale": undefined, - "top": undefined, "url": "https://ka-perseus-images.s3.amazonaws.com/d36824c27f73d6263d9a1c548ead1fdac535243e.svg", "width": 255, }, @@ -3998,13 +3461,11 @@ $\\begin{align} [[☃ explanation 1]]", "images": {}, - "metadata": undefined, "replace": false, "widgets": { "explanation 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": "We can move $\\purpleD {B_V}$ to the right in the diagram to get the right angle triangle as shown below. @@ -4023,15 +3484,10 @@ $\\begin{align} "image 1": { "alignment": "block", "graded": true, - "key": undefined, "options": { "alt": "", "backgroundImage": { - "bottom": undefined, "height": 156, - "left": undefined, - "scale": undefined, - "top": undefined, "url": "https://ka-perseus-images.s3.amazonaws.com/d3b512adb0f11756344a3838f91aa35eda75439b.svg", "width": 255, }, @@ -4062,36 +3518,21 @@ $\\begin{align} }, }, "interactive-graph 1": { - "alignment": undefined, - "graded": undefined, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, "coords": null, - "startCoords": undefined, "type": "linear", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { "type": "linear", }, - "gridStep": undefined, "labels": [ "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -4108,14 +3549,12 @@ $\\begin{align} "showProtractor": false, "showRuler": false, "showTooltips": false, - "snapStep": undefined, "step": [ 1, 1, ], "valid": true, }, - "static": undefined, "type": "interactive-graph", "version": { "major": 0, @@ -4139,7 +3578,6 @@ $\\begin{align} $B_E\\ \\sin{45\\degree}\\downarrow$ ", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -4161,55 +3599,39 @@ $B_E\\ \\sin{45\\degree}\\downarrow$ "width": 352, }, }, - "metadata": undefined, "widgets": { "radio 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "$B_E\\ \\cos{45\\degree} \\uparrow$", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "$B_E\\ \\cos{45\\degree} \\downarrow$", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "$B_E\\ \\sin{45\\degree} \\downarrow$", "correct": true, "isNoneOfTheAbove": false, - "widgets": undefined, }, { - "clue": undefined, "content": "$B_E\\ \\sin{45\\degree}\\uparrow$", "correct": false, "isNoneOfTheAbove": false, - "widgets": undefined, }, { - "clue": undefined, "content": "$B_E\\ \\tan {45\\degree} \\uparrow$", "correct": false, "isNoneOfTheAbove": false, - "widgets": undefined, }, { - "clue": undefined, "content": "$B_E\\ \\tan {45\\degree} \\downarrow$", "correct": false, "isNoneOfTheAbove": false, - "widgets": undefined, }, ], "countChoices": false, @@ -4217,8 +3639,6 @@ $B_E\\ \\sin{45\\degree}\\downarrow$ "displayCount": null, "hasNoneOfTheAbove": false, "multipleSelect": false, - "noneOfTheAbove": undefined, - "onePerLine": undefined, "randomize": false, }, "static": false, @@ -4235,7 +3655,6 @@ $B_E\\ \\sin{45\\degree}\\downarrow$ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-missing-gridStep.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -4255,43 +3674,26 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-mi ", "images": {}, - "metadata": undefined, "replace": false, "widgets": { "interactive-graph 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, "coords": null, - "startCoords": undefined, "type": "linear", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, - "startCoords": undefined, "type": "linear", }, - "gridStep": undefined, "labels": [ "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -4303,12 +3705,8 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-mi 10, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, "showTooltips": false, - "snapStep": undefined, "step": [ 1, 1, @@ -4335,24 +3733,15 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-mi [[☃ interactive-graph 2]]", "images": {}, - "metadata": undefined, "widgets": { "interactive-graph 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, "coords": [ [ -3, @@ -4378,23 +3767,15 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-mi 0.5, 0.5, ], - "startCoords": undefined, "type": "linear", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, - "startCoords": undefined, "type": "linear", }, - "gridStep": undefined, "labels": [ "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -4406,12 +3787,8 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-mi 10, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, "showTooltips": false, - "snapStep": undefined, "step": [ 1, 1, @@ -4427,19 +3804,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-mi "interactive-graph 2": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, "coords": [ [ -3, @@ -4465,23 +3834,15 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-mi 0.5, 0.5, ], - "startCoords": undefined, "type": "linear", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, - "startCoords": undefined, "type": "linear", }, - "gridStep": undefined, "labels": [ "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -4493,12 +3854,8 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-mi 10, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, "showTooltips": false, - "snapStep": undefined, "step": [ 1, 1, @@ -4518,7 +3875,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-mi exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-missing-labels.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -4530,8 +3886,6 @@ $R$ $(1,-3)$ is transformed into $R'$ $(4,4)$. ![](https://ka-perseus-graphie.s3.amazonaws.com/0450d707e93ac22809e8e4063f74b98bf35d079e.png)", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -4540,8 +3894,6 @@ $R$ $(1,-3)$ is transformed into $R'$ $(4,4)$. $G$ $(-3,-3)$ is transformed into $G'$ $(0,4)$. $A$ $(1,0)$ is transformed into $A'$ $(4,7)$. ", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -4550,35 +3902,27 @@ $A$ $(1,0)$ is transformed into $A'$ $(4,7)$. ", ![](https://ka-perseus-graphie.s3.amazonaws.com/dcbfde322f50640db9f40bf4b79824ad9014d8db.png) ", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], - "itemDataVersion": undefined, "question": { "content": "**Arrange the vertices of the movable triangle to construct the image of $\\triangle GAR$ after a translation by $\\langle3,7\\rangle$.** [[☃ interactive-graph 1]]", "images": {}, - "metadata": undefined, "widgets": { "interactive-graph 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "backgroundImage": { "bottom": 0, "height": 425, "left": 0, "scale": 1, - "top": undefined, "url": "https://ka-perseus-graphie.s3.amazonaws.com/31eb6c4f83e061ca7e28bb4382469cb4d682f7b4.png", "width": 425, }, "correct": { - "coord": undefined, "coords": [ [ 4, @@ -4593,29 +3937,13 @@ $A$ $(1,0)$ is transformed into $A'$ $(4,7)$. ", 4, ], ], - "match": undefined, "numSides": 3, - "showAngles": undefined, - "showSides": undefined, - "snapTo": undefined, - "startCoords": undefined, "type": "polygon", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "match": undefined, "numSides": 3, - "showAngles": undefined, - "showSides": undefined, - "snapTo": undefined, - "startCoords": undefined, "type": "polygon", }, - "gridStep": undefined, - "labels": undefined, - "lockedFigures": undefined, "markings": "none", "range": [ [ @@ -4627,20 +3955,13 @@ $A$ $(1,0)$ is transformed into $A'$ $(4,7)$. ", 10, ], ], - "rulerLabel": undefined, - "rulerTicks": undefined, "showProtractor": false, - "showRuler": undefined, - "showTooltips": undefined, - "snapStep": undefined, "step": [ 1, 1, ], }, - "static": undefined, "type": "interactive-graph", - "version": undefined, }, }, }, @@ -4649,7 +3970,6 @@ $A$ $(1,0)$ is transformed into $A'$ $(4,7)$. ", exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-polygon-with-exact-match.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -4664,8 +3984,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-po "width": 425, }, }, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -4680,8 +3998,6 @@ Plotting the remaining vertices at $(8,7)$ and $(5,3)$ gives the rhombus sides o "width": 425, }, }, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -4695,8 +4011,6 @@ We end up with a rhombus that looks like this: "width": 425, }, }, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -4713,24 +4027,17 @@ Draw the rhombus in the first quadrant. [[☃ interactive-graph 1]]", "images": {}, - "metadata": undefined, "widgets": { "interactive-graph 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "backgroundImage": { "bottom": 0, - "height": undefined, "left": 0, "scale": 1, - "top": undefined, "url": null, - "width": undefined, }, "correct": { - "coord": undefined, "coords": [ [ 3, @@ -4751,22 +4058,14 @@ Draw the rhombus in the first quadrant. ], "match": "exact", "numSides": "unlimited", - "showAngles": undefined, "showSides": true, "snapTo": "grid", - "startCoords": undefined, "type": "polygon", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "match": undefined, "numSides": "unlimited", - "showAngles": undefined, "showSides": true, "snapTo": "grid", - "startCoords": undefined, "type": "polygon", }, "gridStep": [ @@ -4777,7 +4076,6 @@ Draw the rhombus in the first quadrant. "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -4793,7 +4091,6 @@ Draw the rhombus in the first quadrant. "rulerTicks": 10, "showProtractor": false, "showRuler": false, - "showTooltips": undefined, "snapStep": [ 1, 1, @@ -4803,7 +4100,6 @@ Draw the rhombus in the first quadrant. 1, ], }, - "static": undefined, "type": "interactive-graph", "version": { "major": 0, @@ -4817,7 +4113,6 @@ Draw the rhombus in the first quadrant. exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-with-string-backgroundImage-left.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -4840,24 +4135,20 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-wi **How far along will Ally be in the race when she reaches her family?** [[☃ radio 1]]", "images": {}, - "metadata": undefined, "widgets": { "interactive-graph 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "backgroundImage": { "bottom": 4, "height": 0, "left": 0, "scale": 1, - "top": undefined, "url": "", "width": 0, }, "correct": { - "coord": undefined, "coords": [ [ 4, @@ -4873,16 +4164,10 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-wi ], ], "numPoints": 3, - "startCoords": undefined, "type": "point", }, - "fullGraphAriaDescription": undefined, - "fullGraphLabel": undefined, "graph": { - "coord": undefined, - "coords": undefined, "numPoints": 3, - "startCoords": undefined, "type": "point", }, "gridStep": [ @@ -4893,7 +4178,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-wi "x", "y", ], - "lockedFigures": undefined, "markings": "graph", "range": [ [ @@ -4929,29 +4213,18 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-wi "radio 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "Less than halfway through the race", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "Halfway through the race", "correct": true, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "More than halfway through the race", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], "countChoices": false, @@ -4959,8 +4232,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-wi "displayCount": null, "hasNoneOfTheAbove": false, "multipleSelect": false, - "noneOfTheAbove": undefined, - "onePerLine": undefined, "randomize": false, }, "static": false, @@ -4977,7 +4248,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/interactive-graph-wi exports[`parseAndTypecheckPerseusItem correctly parses data/label-image-missing-static.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -4995,14 +4265,12 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/label-image-missing- Non-renewable source can be exhausted with continuous use", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, { "content": "Wind and solar energy are renewable, while oil and coal are non-renewable fossil fuels.", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -5017,18 +4285,15 @@ Non-renewable source can be exhausted with continuous use", [[☃ categorizer 1]] ", "images": {}, - "metadata": undefined, "widgets": { "categorizer 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "categories": [ "Renewable", "Non-renewable", ], - "highlightLint": undefined, "items": [ "Wind", "Oil", @@ -5058,11 +4323,7 @@ Non-renewable source can be exhausted with continuous use", }, }, "dropdown 1": { - "alignment": undefined, - "graded": undefined, - "key": undefined, "options": { - "ariaLabel": undefined, "choices": [ { "content": "", @@ -5071,9 +4332,7 @@ Non-renewable source can be exhausted with continuous use", ], "placeholder": "", "static": false, - "visibleLabel": undefined, }, - "static": undefined, "type": "dropdown", "version": { "major": 0, @@ -5081,9 +4340,6 @@ Non-renewable source can be exhausted with continuous use", }, }, "label-image 1": { - "alignment": undefined, - "graded": undefined, - "key": undefined, "options": { "choices": [], "hideChoicesFromInstructions": false, @@ -5095,7 +4351,6 @@ Non-renewable source can be exhausted with continuous use", "multipleAnswers": false, "static": false, }, - "static": undefined, "type": "label-image", "version": { "major": 0, @@ -5103,9 +4358,6 @@ Non-renewable source can be exhausted with continuous use", }, }, "matcher 1": { - "alignment": undefined, - "graded": undefined, - "key": undefined, "options": { "labels": [ "test", @@ -5124,7 +4376,6 @@ Non-renewable source can be exhausted with continuous use", "$3$", ], }, - "static": undefined, "type": "matcher", "version": { "major": 0, @@ -5132,9 +4383,6 @@ Non-renewable source can be exhausted with continuous use", }, }, "sorter 1": { - "alignment": undefined, - "graded": undefined, - "key": undefined, "options": { "correct": [ "$x$", @@ -5144,7 +4392,6 @@ Non-renewable source can be exhausted with continuous use", "layout": "horizontal", "padding": true, }, - "static": undefined, "type": "sorter", "version": { "major": 0, @@ -5158,23 +4405,18 @@ Non-renewable source can be exhausted with continuous use", exports[`parseAndTypecheckPerseusItem correctly parses data/lights-puzzle.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, "hints": [], - "itemDataVersion": undefined, "question": { "content": "**Light up all the squares by clicking on them.** When you click on a square, it will turn on (if it's off), or off (if it's on), as will each of the squares next to it. [[☃ lights-puzzle 1]]", "images": {}, - "metadata": undefined, "widgets": { "lights-puzzle 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "gradeIncompleteAsWrong": false, "startCells": [ @@ -5195,9 +4437,7 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/lights-puzzle.json 1 ], ], }, - "static": undefined, "type": "deprecated-standin", - "version": undefined, }, }, }, @@ -5206,7 +4446,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/lights-puzzle.json 1 exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-missing-version.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -5216,8 +4455,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-missing-versi $ \\textbf A^{-1} = \\frac{1}{det(\\textbf A)}adj(\\textbf A) $", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -5227,8 +4464,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-missing-versi $ \\left[\\begin{array}{rrr}\\left|\\begin{array}{rr}1 & 1 \\\\ 1 & 1\\end{array}\\right| & \\left|\\begin{array}{rr}0 & 1 \\\\ 1 & 1\\end{array}\\right| & \\left|\\begin{array}{rr}0 & 1 \\\\ 1 & 1\\end{array}\\right| \\\\ \\left|\\begin{array}{rr}0 & 1 \\\\ 1 & 1\\end{array}\\right| & \\left|\\begin{array}{rr}2 & 1 \\\\ 1 & 1\\end{array}\\right| & \\left|\\begin{array}{rr}2 & 0 \\\\ 1 & 1\\end{array}\\right| \\\\ \\left|\\begin{array}{rr}0 & 1 \\\\ 1 & 1\\end{array}\\right| & \\left|\\begin{array}{rr}2 & 1 \\\\ 0 & 1\\end{array}\\right| & \\left|\\begin{array}{rr}2 & 0 \\\\ 0 & 1\\end{array}\\right|\\end{array}\\right] = \\left[\\begin{array}{rrr}0 & -1 & -1 \\\\ -1 & 1 & 2 \\\\ -1 & 2 & 2\\end{array}\\right] $", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -5238,8 +4473,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-missing-versi $ \\left[\\begin{array}{rrr}0 & 1 & -1 \\\\ 1 & 1 & -2 \\\\ -1 & -2 & 2\\end{array}\\right] $", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -5247,8 +4480,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-missing-versi $ adj(\\textbf A) = \\left[\\begin{array}{rrr}0 & 1 & -1 \\\\ 1 & 1 & -2 \\\\ -1 & -2 & 2\\end{array}\\right]^T = \\left[\\begin{array}{rrr}\\color{\\#6495ED}{0} & \\color{\\#6495ED}{1} & \\color{\\#6495ED}{-1} \\\\ \\color{\\#6495ED}{1} & \\color{\\#6495ED}{1} & \\color{\\#6495ED}{-2} \\\\ \\color{\\#6495ED}{-1} & \\color{\\#6495ED}{-2} & \\color{\\#6495ED}{2}\\end{array}\\right] $", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -5258,8 +4489,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-missing-versi $ det(\\textbf A) = \\left|\\begin{array}{rrr}2 & 0 & 1 \\\\ 0 & 1 & 1 \\\\ 1 & 1 & 1\\end{array}\\right|= \\color{\\#DF0030}{-1} $", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -5269,19 +4498,14 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-missing-versi $ \\textbf A^{-1} = \\frac{1}{\\color{\\#DF0030}{-1}} \\left[\\begin{array}{rrr}\\color{\\#6495ED}{0} & \\color{\\#6495ED}{1} & \\color{\\#6495ED}{-1} \\\\ \\color{\\#6495ED}{1} & \\color{\\#6495ED}{1} & \\color{\\#6495ED}{-2} \\\\ \\color{\\#6495ED}{-1} & \\color{\\#6495ED}{-2} & \\color{\\#6495ED}{2}\\end{array}\\right] $", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "$ = \\left[\\begin{array}{rrr}0 & -1 & 1 \\\\ -1 & -1 & 2 \\\\ 1 & 2 & -2\\end{array}\\right]$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], - "itemDataVersion": undefined, "question": { "content": "$\\textbf A = \\left[\\begin{array}{rrr}2 & 0 & 1 \\\\ 0 & 1 & 1 \\\\ 1 & 1 & 1\\end{array}\\right]$ @@ -5289,12 +4513,8 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-missing-versi [[☃ matrix 1]]", "images": {}, - "metadata": undefined, "widgets": { "matrix 1": { - "alignment": undefined, - "graded": undefined, - "key": undefined, "options": { "answers": [ [ @@ -5313,18 +4533,12 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-missing-versi -2, ], ], - "cursorPosition": undefined, "matrixBoardSize": [ 3, 3, ], - "prefix": undefined, - "static": undefined, - "suffix": undefined, }, - "static": undefined, "type": "matrix", - "version": undefined, }, }, }, @@ -5333,7 +4547,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-missing-versi exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-with-nulls-in-answer.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -5351,12 +4564,10 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-with-nulls-in [[☃ matrix 1]]", "images": {}, - "metadata": undefined, "widgets": { "matrix 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "answers": [ [ @@ -5401,7 +4612,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-with-nulls-in exports[`parseAndTypecheckPerseusItem correctly parses data/matrix-with-string-answer-element.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": true, "chi2Table": false, @@ -5422,13 +4632,11 @@ $x_1\\cdot\\vec{v_1}+x_2\\cdot\\vec{v_2}+...+x_n\\cdot\\vec{v_n}$ [[☃ explanation 1]]", "images": {}, - "metadata": undefined, "replace": false, "widgets": { "explanation 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": "We learned that for 2-dimensional matrices, the first column is the image of the unit vector $\\left[\\begin{array}{c}1\\\\\\\\0\\end{array}\\right]$ and the second column is the image of the unit vector $\\left[\\begin{array}{c}0\\\\\\\\1\\end{array}\\right]$. @@ -5559,7 +4767,6 @@ $x_1\\cdot\\left[\\begin{array}{c}1\\\\\\\\0\\\\\\\\0\\\\\\\\0\\end{array}\\righ \\end{array}\\right] \\end{align}$", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -5592,7 +4799,6 @@ $\\left[\\begin{array}{c} -5 \\end{array}\\right]$", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -5626,12 +4832,10 @@ $\\left[\\begin{array}{c} [[☃ matrix 1]]", "images": {}, - "metadata": undefined, "widgets": { "matrix 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "answers": [ [ @@ -5673,7 +4877,6 @@ $\\left[\\begin{array}{c} exports[`parseAndTypecheckPerseusItem correctly parses data/measurer-missing-image.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -5681,37 +4884,26 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/measurer-missing-ima { "content": "crwdns2931741:0crwdne2931741:0", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "crwdns2931695:0crwdne2931695:0", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "crwdns2931679:0crwdne2931679:0", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], - "itemDataVersion": undefined, "question": { "content": "crwdns3125767:0crwdne3125767:0", "images": {}, - "metadata": undefined, "widgets": { "dropdown 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "ariaLabel": undefined, "choices": [ { "content": "crwdns2301760:0crwdne2301760:0", @@ -5744,16 +4936,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/measurer-missing-ima ], "placeholder": "", "static": false, - "visibleLabel": undefined, }, - "static": undefined, "type": "dropdown", - "version": undefined, }, "measurer 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "box": [ 480, @@ -5775,9 +4962,7 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/measurer-missing-ima "showRuler": false, "static": false, }, - "static": undefined, "type": "measurer", - "version": undefined, }, }, }, @@ -5786,7 +4971,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/measurer-missing-ima exports[`parseAndTypecheckPerseusItem correctly parses data/measurer-missing-static.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -5800,26 +4984,15 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/measurer-missing-sta ", "images": {}, - "metadata": undefined, "widgets": { "measurer 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "box": [ 480, 480, ], - "image": { - "bottom": undefined, - "height": undefined, - "left": undefined, - "scale": undefined, - "top": undefined, - "url": undefined, - "width": undefined, - }, + "image": {}, "rulerLabel": "", "rulerLength": 10, "rulerPixels": 40, @@ -5828,7 +5001,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/measurer-missing-sta "showRuler": true, "static": false, }, - "static": undefined, "type": "measurer", "version": { "major": 1, @@ -5842,7 +5014,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/measurer-missing-sta exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-missing-snapDivisions.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -5869,7 +5040,6 @@ This amount must be *greater than or equal to* $\\purpleC{13.50}$, so the inequa $\\blueD{3}+\\greenD{1.2c}\\maroonD{\\geq}\\purpleC{13.50}$", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -5888,7 +5058,6 @@ c &≥ 8.75 Janie must do $8.75$ or more chores to have enough money to purchase the CD.", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -5899,7 +5068,6 @@ The solution includes the point $c=8.75$, so we *fill in* the circle at $8.75$. Because the solution to the inequality says that $c\\geq 8.75$, this means that solutions are numbers to the *right* of $8.75$.", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -5917,13 +5085,11 @@ The graph of the solution of the inequality, $c ≥ 8.75$, looks like this: "width": 460, }, }, - "metadata": undefined, "replace": false, "widgets": { "number-line 3": { "alignment": "default", "graded": true, - "key": undefined, "options": { "correctRel": "ge", "correctX": 8.75, @@ -5945,7 +5111,6 @@ The graph of the solution of the inequality, $c ≥ 8.75$, looks like this: 5, 10, ], - "showTooltip": undefined, "showTooltips": false, "snapDivisions": 2, "static": false, @@ -5993,12 +5158,10 @@ The graph of the solution of the inequality, $c ≥ 8.75$, looks like this: "width": 460, }, }, - "metadata": undefined, "widgets": { "expression 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -6009,20 +5172,17 @@ The graph of the solution of the inequality, $c ≥ 8.75$, looks like this: "value": "1.2c+3\\ge13.5", }, ], - "ariaLabel": undefined, "buttonSets": [ "basic", "basic relations", "advanced relations", ], - "buttonsVisible": undefined, "functions": [ "f", "g", "h", ], "times": false, - "visibleLabel": undefined, }, "static": false, "type": "expression", @@ -6034,7 +5194,6 @@ The graph of the solution of the inequality, $c ≥ 8.75$, looks like this: "number-line 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "correctRel": "ge", "correctX": 8.75, @@ -6056,7 +5215,6 @@ The graph of the solution of the inequality, $c ≥ 8.75$, looks like this: 5, 10, ], - "showTooltip": undefined, "showTooltips": false, "snapDivisions": 2, "static": false, @@ -6076,7 +5234,6 @@ The graph of the solution of the inequality, $c ≥ 8.75$, looks like this: exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-missing-static.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -6090,12 +5247,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-missing- ", "images": {}, - "metadata": undefined, "widgets": { "number-line 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "correctRel": "eq", "correctX": 0.5, @@ -6117,12 +5271,10 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-missing- 0, 1, ], - "showTooltip": undefined, "snapDivisions": 1, "static": false, "tickStep": null, }, - "static": undefined, "type": "number-line", "version": { "major": 0, @@ -6136,7 +5288,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-missing- exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-with-empty-strings-in-label-range.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -6154,15 +5305,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-with-emp "width": 460, }, }, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "On the number line, numbers to the left are less than numbers to the right.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { @@ -6175,8 +5322,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-with-emp "width": 460, }, }, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -6192,12 +5337,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-with-emp ", "images": {}, - "metadata": undefined, "widgets": { "number-line 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "correctRel": "eq", "correctX": -0.375, @@ -6218,12 +5360,10 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-with-emp -1, 1, ], - "showTooltip": undefined, "snapDivisions": 2, "static": false, "tickStep": null, }, - "static": undefined, "type": "number-line", "version": { "major": 0, @@ -6231,43 +5371,29 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-with-emp }, }, "radio 2": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": " $\\,-1\\,\\,\\,<\\,-10$", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": " $-10\\,\\,\\,<\\,\\,\\,1$", "correct": true, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": " $\\,\\,\\,\\,\\,10\\,\\,\\,< \\,-1$", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], - "countChoices": undefined, "deselectEnabled": false, "displayCount": null, - "hasNoneOfTheAbove": undefined, "multipleSelect": true, "noneOfTheAbove": false, "onePerLine": true, "randomize": true, }, - "static": undefined, "type": "radio", "version": { "major": 0, @@ -6281,7 +5407,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-with-emp exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-with-null-correctX.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -6292,22 +5417,16 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/number-line-with-nul $=(31-31) -8$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "$ =0-8$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "$=-8$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -6320,12 +5439,9 @@ $=(31-31) -8$", [[☃ numeric-input 1]]", "images": {}, - "metadata": undefined, "widgets": { "number-line 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "correctRel": "eq", "correctX": null, @@ -6334,7 +5450,6 @@ $=(31-31) -8$", 12, ], "initialX": null, - "isTickCtrl": undefined, "labelRange": [ null, null, @@ -6346,12 +5461,10 @@ $=(31-31) -8$", 0, 10, ], - "showTooltip": undefined, "snapDivisions": 2, "static": false, "tickStep": null, }, - "static": undefined, "type": "number-line", "version": { "major": 0, @@ -6359,14 +5472,10 @@ $=(31-31) -8$", }, }, "numeric-input 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { - "answerForms": undefined, "maxError": null, "message": "", "simplify": "required", @@ -6376,12 +5485,9 @@ $=(31-31) -8$", }, ], "coefficient": false, - "labelText": undefined, - "rightAlign": undefined, "size": "normal", "static": false, }, - "static": undefined, "type": "numeric-input", "version": { "major": 0, @@ -6395,7 +5501,6 @@ $=(31-31) -8$", exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-answer-with-null-value.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -6409,14 +5514,10 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-answer [[☃ numeric-input 1]]", "images": {}, - "metadata": undefined, "widgets": { "numeric-input 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { "answerForms": [], @@ -6429,12 +5530,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-answer }, ], "coefficient": false, - "labelText": undefined, - "rightAlign": undefined, "size": "normal", "static": false, }, - "static": undefined, "type": "numeric-input", "version": { "major": 0, @@ -6448,7 +5546,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-answer exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-answer-with-simplify-true.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -6456,15 +5553,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-answer { "content": "$= \\dfrac{9 \\times 1}{2 \\times 4}$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "$= \\dfrac{9}{8}$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -6477,17 +5570,13 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-answer [[☃ numeric-input 1]]", "images": {}, - "metadata": undefined, "widgets": { "numeric-input 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { - "answerForms": undefined, "maxError": 0, "message": "", "simplify": "true", @@ -6498,11 +5587,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-answer ], "coefficient": false, "labelText": "", - "rightAlign": undefined, "size": "normal", "static": false, }, - "static": undefined, "type": "numeric-input", "version": { "major": 0, @@ -6516,7 +5603,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-answer exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-answer-without-value.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -6534,7 +5620,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-answer Let's perform this multiplication to find the answer.", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -6543,7 +5628,6 @@ Let's perform this multiplication to find the answer.", $\\dfrac{2}{3}\\times \\dfrac{2}{3}\\times\\dfrac{2}{3}=\\boxed{\\dfrac{8}{27}}$.", "images": {}, - "metadata": undefined, "replace": false, "widgets": {}, }, @@ -6555,12 +5639,10 @@ $\\dfrac{2}{3}\\times \\dfrac{2}{3}\\times\\dfrac{2}{3}=\\boxed{\\dfrac{8}{27}}$ "question": { "content": "$\\bigg(\\dfrac{2}{3} \\bigg)^3 =$ [[☃ expression 1]]", "images": {}, - "metadata": undefined, "widgets": { "expression 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -6587,11 +5669,9 @@ $\\dfrac{2}{3}\\times \\dfrac{2}{3}\\times\\dfrac{2}{3}=\\boxed{\\dfrac{8}{27}}$ "value": "\\frac{8}{27}", }, ], - "ariaLabel": undefined, "buttonSets": [ "basic", ], - "buttonsVisible": undefined, "functions": [ "f", "g", @@ -6599,7 +5679,6 @@ $\\dfrac{2}{3}\\times \\dfrac{2}{3}\\times\\dfrac{2}{3}=\\boxed{\\dfrac{8}{27}}$ ], "static": false, "times": false, - "visibleLabel": undefined, }, "static": false, "type": "expression", @@ -6611,9 +5690,7 @@ $\\dfrac{2}{3}\\times \\dfrac{2}{3}\\times\\dfrac{2}{3}=\\boxed{\\dfrac{8}{27}}$ "numeric-input 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { "answerForms": [ @@ -6625,7 +5702,6 @@ $\\dfrac{2}{3}\\times \\dfrac{2}{3}\\times\\dfrac{2}{3}=\\boxed{\\dfrac{8}{27}}$ "simplify": "required", "status": "correct", "strict": false, - "value": undefined, }, ], "coefficient": false, @@ -6649,7 +5725,6 @@ $\\dfrac{2}{3}\\times \\dfrac{2}{3}\\times\\dfrac{2}{3}=\\boxed{\\dfrac{8}{27}}$ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missing-coefficient.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -6667,14 +5742,10 @@ What is the radius of the mattress when it is rolled up into a cylinder. [[☃ numeric-input 1]] ", "images": {}, - "metadata": undefined, "widgets": { "numeric-input 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { "answerForms": [], @@ -6687,12 +5758,9 @@ What is the radius of the mattress when it is rolled up into a cylinder. }, ], "coefficient": false, - "labelText": undefined, - "rightAlign": undefined, "size": "normal", "static": false, }, - "static": undefined, "type": "numeric-input", "version": { "major": 0, @@ -6706,7 +5774,6 @@ What is the radius of the mattress when it is rolled up into a cylinder. exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missing-labelText.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -6714,13 +5781,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missin { "content": "Heart rate is measured in beats per minute: $\\dfrac{beats}{minutes}$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": { "expression 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -6743,7 +5806,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missin "times": false, "visibleLabel": undefined, }, - "static": undefined, "type": "expression", "version": { "major": 1, @@ -6751,20 +5813,15 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missin }, }, "input-number 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerType": "number", - "customKeypad": undefined, "inexact": false, "maxError": 0.1, - "rightAlign": undefined, "simplify": "required", "size": "normal", "value": 0, }, - "static": undefined, "type": "input-number", "version": { "major": 0, @@ -6772,9 +5829,7 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missin }, }, "passage 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "footnotes": "", "passageText": "", @@ -6782,7 +5837,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missin "showLineNumbers": true, "static": false, }, - "static": undefined, "type": "passage", "version": { "major": 0, @@ -6796,13 +5850,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missin ", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": { "expression 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -6825,7 +5875,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missin "times": false, "visibleLabel": undefined, }, - "static": undefined, "type": "expression", "version": { "major": 1, @@ -6833,17 +5882,10 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missin }, }, "image 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "alt": undefined, "backgroundImage": { - "bottom": undefined, "height": 0, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, "width": 0, }, @@ -6863,10 +5905,8 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missin 10, ], ], - "static": undefined, "title": "", }, - "static": undefined, "type": "image", "version": { "major": 0, @@ -6885,36 +5925,26 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-missin "width": 342, }, }, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "From the previous calculation, we get 96 beats per minute as Lance's active heart rate.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "To find the difference between the active and resting heart rate, subtract the resting heart rate from the active heart rate. The next hint shows this.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "$96$ $bpm$ $-$ $32$ $bpm$ $=$ $64$ $bpm$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "The difference between Lance Armstrong's active and resting heart rate is $64$ $bpm$. ", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -6940,12 +5970,9 @@ Heart rate is described as the number of heart beats per minute. The normal hum "width": 478, }, }, - "metadata": undefined, "widgets": { "expression 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -6968,7 +5995,6 @@ Heart rate is described as the number of heart beats per minute. The normal hum "times": false, "visibleLabel": undefined, }, - "static": undefined, "type": "expression", "version": { "major": 1, @@ -6976,14 +6002,10 @@ Heart rate is described as the number of heart beats per minute. The normal hum }, }, "numeric-input 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { - "answerForms": undefined, "maxError": null, "message": "", "simplify": "required", @@ -6993,12 +6015,9 @@ Heart rate is described as the number of heart beats per minute. The normal hum }, ], "coefficient": false, - "labelText": undefined, - "rightAlign": undefined, "size": "normal", "static": false, }, - "static": undefined, "type": "numeric-input", "version": { "major": 0, @@ -7006,9 +6025,7 @@ Heart rate is described as the number of heart beats per minute. The normal hum }, }, "sequence 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "json": [ { @@ -7018,7 +6035,6 @@ Heart rate is described as the number of heart beats per minute. The normal hum }, ], }, - "static": undefined, "type": "deprecated-standin", "version": { "major": 0, @@ -7032,7 +6048,6 @@ Heart rate is described as the number of heart beats per minute. The normal hum exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-with-simplify-false.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -7058,17 +6073,13 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-with-s "width": 285, }, }, - "metadata": undefined, "widgets": { "numeric-input 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { - "answerForms": undefined, "maxError": 0, "message": "", "simplify": "false", @@ -7098,7 +6109,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/numeric-input-with-s exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-option-missing-images.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -7115,13 +6125,11 @@ To **decompose** a number, we break it into smaller parts. A **unit fraction** is a fraction with a numerator of $1$. [[☃ explanation 2]]", "images": {}, - "metadata": undefined, "replace": false, "widgets": { "explanation 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": "We can decompose $54$ into $50+4$.", "hidePrompt": "Okay, got it", @@ -7139,7 +6147,6 @@ A **unit fraction** is a fraction with a numerator of $1$. [[☃ explanation 2]] "explanation 2": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": "$\\dfrac15$ is a unit fraction because the numerator (top number) is $1$.", "hidePrompt": "Okay, got it", @@ -7175,13 +6182,11 @@ Let's decompose $\\dfrac59$ into unit fractions. "width": 400, }, }, - "metadata": undefined, "replace": false, "widgets": { "explanation 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": " @@ -7203,76 +6208,61 @@ $\\dfrac59$ can be broken up into $\\dfrac19+\\dfrac19+\\dfrac19+\\dfrac19+\\dfr "graded-group 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "content": "**Drag the cards to create an expression that is equivalent to $\\dfrac59$.** [[☃ orderer 1]]", - "hasHint": undefined, - "hint": undefined, "images": {}, - "immutableWidgets": undefined, "title": "", - "widgetEnabled": undefined, "widgets": { "orderer 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "correctOptions": [ { "content": "$\\dfrac19$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$+$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$\\dfrac19$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$+$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$\\dfrac19$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$+$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$\\dfrac19$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$+$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$\\dfrac19$", "images": {}, - "metadata": undefined, "widgets": {}, }, ], @@ -7282,13 +6272,11 @@ $\\dfrac59$ can be broken up into $\\dfrac19+\\dfrac19+\\dfrac19+\\dfrac19+\\dfr { "content": "$\\dfrac19$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$+$", "images": {}, - "metadata": undefined, "widgets": {}, }, ], @@ -7332,13 +6320,11 @@ How can we decompose $\\dfrac38$? "width": 96, }, }, - "metadata": undefined, "replace": false, "widgets": { "explanation 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": "$\\dfrac18+\\dfrac18+\\dfrac18$ @@ -7358,7 +6344,6 @@ How can we decompose $\\dfrac38$? "graded-group 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "content": "**Write an expression decomposing $\\dfrac38$ into unit fractions.** @@ -7367,17 +6352,12 @@ How can we decompose $\\dfrac38$? [[☃ expression 1]] ", - "hasHint": undefined, - "hint": undefined, "images": {}, - "immutableWidgets": undefined, "title": "", - "widgetEnabled": undefined, "widgets": { "expression 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -7388,18 +6368,15 @@ How can we decompose $\\dfrac38$? "value": "\\frac{1}{8}+\\frac{1}{8}+\\frac{1}{8}", }, ], - "ariaLabel": undefined, "buttonSets": [ "basic", ], - "buttonsVisible": undefined, "functions": [ "f", "g", "h", ], "times": true, - "visibleLabel": undefined, }, "static": false, "type": "expression", @@ -7435,13 +6412,11 @@ How can we decompose $\\dfrac64$? "width": 410, }, }, - "metadata": undefined, "replace": false, "widgets": { "explanation 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": "$\\dfrac14+\\dfrac14+\\dfrac14+\\dfrac14+\\dfrac14+\\dfrac14$", "hidePrompt": "Hide solution", @@ -7459,90 +6434,73 @@ How can we decompose $\\dfrac64$? "graded-group 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "content": "**Drag the cards to create an expression that is equivalent to $\\dfrac64$.** [[☃ orderer 1]] ", - "hasHint": undefined, - "hint": undefined, "images": {}, - "immutableWidgets": undefined, "title": "", - "widgetEnabled": undefined, "widgets": { "orderer 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "correctOptions": [ { "content": "$\\dfrac14$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$+$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$\\dfrac14$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$+$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$\\dfrac14$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$+$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$\\dfrac14$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$+$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$\\dfrac14$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$+$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$\\dfrac14$", "images": {}, - "metadata": undefined, "widgets": {}, }, ], @@ -7552,13 +6510,11 @@ How can we decompose $\\dfrac64$? { "content": "$\\dfrac14$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$+$", "images": {}, - "metadata": undefined, "widgets": {}, }, ], @@ -7613,13 +6569,11 @@ How can we decompose $\\dfrac64$? [[☃ explanation 4]]", "images": {}, - "metadata": undefined, "replace": false, "widgets": { "explanation 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": "$\\dfrac29=\\dfrac19+\\dfrac19$", "hidePrompt": "Hide solution", @@ -7637,7 +6591,6 @@ How can we decompose $\\dfrac64$? "explanation 2": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": "$\\dfrac13+\\dfrac13+\\dfrac13+\\dfrac13+\\dfrac13$", "hidePrompt": "Hide solution", @@ -7655,7 +6608,6 @@ How can we decompose $\\dfrac64$? "explanation 3": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": "$\\dfrac16+\\dfrac16+\\dfrac16+\\dfrac16+\\dfrac16=\\dfrac56$ ", @@ -7674,7 +6626,6 @@ How can we decompose $\\dfrac64$? "explanation 4": { "alignment": "default", "graded": true, - "key": undefined, "options": { "explanation": " @@ -7698,54 +6649,38 @@ $\\dfrac23$ | $\\dfrac13+\\dfrac13$", "graded-group 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "content": "**Which shows $\\dfrac29$ decomposed into unit fractions?** [[☃ radio 1]] ", - "hasHint": undefined, - "hint": undefined, "images": {}, - "immutableWidgets": undefined, "title": "", - "widgetEnabled": undefined, "widgets": { "radio 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "$\\dfrac19+\\dfrac19$", "correct": true, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "$\\dfrac12+\\dfrac12+\\dfrac12+\\dfrac12+\\dfrac12+\\dfrac12+\\dfrac12+\\dfrac12+\\dfrac12$", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "$\\dfrac19+\\dfrac29$", "correct": false, "isNoneOfTheAbove": false, - "widgets": undefined, }, ], - "countChoices": undefined, "deselectEnabled": false, "displayCount": null, "hasNoneOfTheAbove": false, "multipleSelect": false, - "noneOfTheAbove": undefined, "onePerLine": true, "randomize": false, }, @@ -7768,7 +6703,6 @@ $\\dfrac23$ | $\\dfrac13+\\dfrac13$", "graded-group 2": { "alignment": "default", "graded": true, - "key": undefined, "options": { "content": "**Write an expression showing $\\dfrac53$ decomposed into unit fractions.** @@ -7777,17 +6711,12 @@ $\\dfrac23$ | $\\dfrac13+\\dfrac13$", ", - "hasHint": undefined, - "hint": undefined, "images": {}, - "immutableWidgets": undefined, "title": "", - "widgetEnabled": undefined, "widgets": { "expression 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "answerForms": [ { @@ -7798,18 +6727,15 @@ $\\dfrac23$ | $\\dfrac13+\\dfrac13$", "value": "\\frac{1}{3}+\\frac{1}{3}+\\frac{1}{3}+\\frac{1}{3}+\\frac{1}{3}", }, ], - "ariaLabel": undefined, "buttonSets": [ "basic", ], - "buttonsVisible": undefined, "functions": [ "f", "g", "h", ], "times": false, - "visibleLabel": undefined, }, "static": false, "type": "expression", @@ -7830,7 +6756,6 @@ $\\dfrac23$ | $\\dfrac13+\\dfrac13$", "graded-group 3": { "alignment": "default", "graded": true, - "key": undefined, "options": { "content": "**What fraction is equal to $\\dfrac16+\\dfrac16+\\dfrac16+\\dfrac16+\\dfrac16$?** @@ -7839,19 +6764,13 @@ $\\dfrac23$ | $\\dfrac13+\\dfrac13$", ", - "hasHint": undefined, - "hint": undefined, "images": {}, - "immutableWidgets": undefined, "title": "", - "widgetEnabled": undefined, "widgets": { "numeric-input 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { - "answerForms": undefined, "answers": [ { "answerForms": [ @@ -7868,7 +6787,6 @@ $\\dfrac23$ | $\\dfrac13+\\dfrac13$", ], "coefficient": false, "labelText": "", - "rightAlign": undefined, "size": "normal", "static": false, }, @@ -7891,7 +6809,6 @@ $\\dfrac23$ | $\\dfrac13+\\dfrac13$", "graded-group 4": { "alignment": "default", "graded": true, - "key": undefined, "options": { "content": "**Match each fraction to its equivalent expression.** @@ -7900,17 +6817,12 @@ $\\dfrac23$ | $\\dfrac13+\\dfrac13$", ", - "hasHint": undefined, - "hint": undefined, "images": {}, - "immutableWidgets": undefined, "title": "", - "widgetEnabled": undefined, "widgets": { "matcher 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "labels": [ "Fraction", @@ -7955,7 +6867,6 @@ $\\dfrac23$ | $\\dfrac13+\\dfrac13$", "question": { "content": "", "images": {}, - "metadata": undefined, "widgets": {}, }, } @@ -7963,7 +6874,6 @@ $\\dfrac23$ | $\\dfrac13+\\dfrac13$", exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-option-missing-widgets.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -7972,19 +6882,14 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-option-missi "content": "Extinction is a natural process, and the rate of extinction can be determined by studying changes in biodiversity during the history of life on Earth. ", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": { "orderer 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "correctOptions": [ { "content": "$x$", "images": {}, - "metadata": undefined, "widgets": {}, }, ], @@ -7994,13 +6899,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-option-missi { "content": "$x$", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "$y$", "images": {}, - "metadata": undefined, "widgets": {}, }, ], @@ -8008,12 +6911,10 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-option-missi { "content": "$y$", "images": {}, - "metadata": undefined, "widgets": {}, }, ], }, - "static": undefined, "type": "orderer", "version": { "major": 0, @@ -8025,8 +6926,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-option-missi { "content": "Humans are causing a current sixth mass extinction event, but are not the only reason species go extinct.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -8046,53 +6945,35 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-option-missi "width": 396, }, }, - "metadata": undefined, "widgets": { "radio 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "a. the rate of extinction that balances the rate of speciation", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "b. the average rate at which extinctions have occurred naturally in the geologic past, without human involvement", "correct": true, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "c. the rate of extinction that is currently occurring in protected areas like national parks and marine sanctuaries", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "d. the rate of extinction that can be determined by using Geiger counters and detecting radiation", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], - "countChoices": undefined, "deselectEnabled": false, "displayCount": null, - "hasNoneOfTheAbove": undefined, "multipleSelect": false, "noneOfTheAbove": false, "onePerLine": true, "randomize": false, }, - "static": undefined, "type": "radio", "version": { "major": 0, @@ -8106,7 +6987,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-option-missi exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-with-invalid-height.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -8114,12 +6994,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-with-invalid { "content": "The doric is the oldest and simplest order, the Corinthian is the latest and most complex.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], - "itemDataVersion": undefined, "question": { "content": "Here is a doric, ionic and corinthian capital. Put these in the chronological order of their development. [[☃ orderer 1]] @@ -8132,30 +7009,23 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-with-invalid ", "images": {}, - "metadata": undefined, "widgets": { "orderer 1": { - "alignment": undefined, - "graded": undefined, - "key": undefined, "options": { "correctOptions": [ { "content": "![](https://ka-perseus-images.s3.amazonaws.com/a9387c1491bb743a0c76d2ab74c4dd145c964c7b.jpeg)", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "![](https://ka-perseus-images.s3.amazonaws.com/45ff66c9387dcb419651883677cfb11fbbf8e075.jpeg)", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "![](https://ka-perseus-images.s3.amazonaws.com/54ea9b0cf1a57bf2879772ea81f656264605d75e.jpeg)", "images": {}, - "metadata": undefined, "widgets": {}, }, ], @@ -8165,27 +7035,22 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-with-invalid { "content": "![](https://ka-perseus-images.s3.amazonaws.com/45ff66c9387dcb419651883677cfb11fbbf8e075.jpeg)", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "![](https://ka-perseus-images.s3.amazonaws.com/54ea9b0cf1a57bf2879772ea81f656264605d75e.jpeg)", "images": {}, - "metadata": undefined, "widgets": {}, }, { "content": "![](https://ka-perseus-images.s3.amazonaws.com/a9387c1491bb743a0c76d2ab74c4dd145c964c7b.jpeg)", "images": {}, - "metadata": undefined, "widgets": {}, }, ], "otherOptions": [], }, - "static": undefined, "type": "orderer", - "version": undefined, }, }, }, @@ -8194,7 +7059,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-with-invalid exports[`parseAndTypecheckPerseusItem correctly parses data/orderer-with-undefined-options.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -8225,20 +7089,14 @@ A free body diagram of the **box** is shown below. "width": 400, }, }, - "metadata": undefined, "widgets": { "image 1": { "alignment": "block", "graded": true, - "key": undefined, "options": { "alt": "A woman places a box on a shelf and pushes it to the left, sliding it further onto the shelf.", "backgroundImage": { - "bottom": undefined, "height": 263, - "left": undefined, - "scale": undefined, - "top": undefined, "url": "https://cdn.kastatic.org/ka-content-images/89e2cabd1261ec9119c501bd6c9c0f541e09ab2f.png", "width": 400, }, @@ -8271,15 +7129,10 @@ A free body diagram of the **box** is shown below. "image 2": { "alignment": "block", "graded": true, - "key": undefined, "options": { "alt": "A model shows a square with four arrows pointing out of it. An arrow points down and is labelled F g. Another arrow points up and is labelled F N. Another arrow points left and is labelled F a. Another arrow points right and is labelled F f.", "backgroundImage": { - "bottom": undefined, "height": 306, - "left": undefined, - "scale": undefined, - "top": undefined, "url": "https://cdn.kastatic.org/ka-content-images/48c2597aa0e5a7ac27771cfc2e7c955c7cb14881.svg", "width": 300, }, @@ -8310,15 +7163,11 @@ A free body diagram of the **box** is shown below. }, }, "orderer 1": { - "alignment": undefined, - "graded": undefined, - "key": undefined, "options": { "correctOptions": [ { "content": "$x$", "images": {}, - "metadata": undefined, "widgets": {}, }, ], @@ -8329,12 +7178,10 @@ A free body diagram of the **box** is shown below. { "content": "$y$", "images": {}, - "metadata": undefined, "widgets": {}, }, ], }, - "static": undefined, "type": "orderer", "version": { "major": 0, @@ -8344,36 +7191,29 @@ A free body diagram of the **box** is shown below. "radio 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "choices": [ { "clue": "$F_\\text{N}$ results from the box interacting with the shelf.", "content": "normal force $(F_\\text{N})$", "correct": true, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { "clue": "$F_\\text{g}$ results from the box interacting with Earth.", "content": "gravitational force $(F_\\text{g})$", "correct": true, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { "clue": "$F_\\text{a}$ results from the box interacting with the woman's hand.", "content": "applied force $(F_\\text{a})$", "correct": true, "isNoneOfTheAbove": false, - "widgets": undefined, }, { "clue": "$F_\\text{f}$ results from the box interacting with the shelf.", "content": "frictional force $(F_\\text{f})$", "correct": true, "isNoneOfTheAbove": false, - "widgets": undefined, }, ], "countChoices": false, @@ -8381,8 +7221,6 @@ A free body diagram of the **box** is shown below. "displayCount": null, "hasNoneOfTheAbove": false, "multipleSelect": true, - "noneOfTheAbove": undefined, - "onePerLine": undefined, "randomize": true, }, "static": false, @@ -8395,7 +7233,6 @@ A free body diagram of the **box** is shown below. "sorter 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "correct": [ "$x$", @@ -8419,7 +7256,6 @@ A free body diagram of the **box** is shown below. exports[`parseAndTypecheckPerseusItem correctly parses data/passage-missing-footnotes-and-title.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -8435,12 +7271,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/passage-missing-foot [[☃ passage-ref 1]]", "images": {}, - "metadata": undefined, "widgets": { "passage 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "footnotes": "", "passageText": "a", @@ -8448,7 +7281,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/passage-missing-foot "showLineNumbers": true, "static": false, }, - "static": undefined, "type": "passage", "version": { "major": 0, @@ -8456,15 +7288,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/passage-missing-foot }, }, "passage-ref 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "passageNumber": 1, "referenceNumber": 1, - "summaryText": undefined, }, - "static": undefined, "type": "passage-ref", "version": { "major": 0, @@ -8478,7 +7306,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/passage-missing-foot exports[`parseAndTypecheckPerseusItem correctly parses data/passage-ref-missing-summaryText.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -8486,22 +7313,16 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/passage-ref-missing- { "content": "Anybody likely to need armor would certainly want to be wearing it. Armor was worn for sport, battle, civil defense, ceremony, and in some cases for hunting. This example—commissioned in 1591 by Sophie of Brandenburg as a Christmas gift for her husband, Christian I (reigned 1586–91)—is one of a set of twelve matching armors for the courtly sport of foot combat.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "Many medieval European cities, such as London, Paris, Frankfurt, Vienna, and Milan, actually required their citizens to own armor and weapons so that they would be able to defend the city in times of war.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "The answer is: All of the above. ", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -8519,20 +7340,12 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( ", "images": {}, - "metadata": undefined, "widgets": { "image 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "alt": undefined, "backgroundImage": { - "bottom": undefined, "height": 571, - "left": undefined, - "scale": undefined, - "top": undefined, "url": "https://ka-perseus-images.s3.amazonaws.com/3d84aeb69c515789bba289f5118b1d6e2b796ca1.jpg", "width": 357, }, @@ -8552,11 +7365,9 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( 10, ], ], - "static": undefined, "title": " ", }, - "static": undefined, "type": "image", "version": { "major": 0, @@ -8564,17 +7375,10 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( }, }, "image 2": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { - "alt": undefined, "backgroundImage": { - "bottom": undefined, "height": 0, - "left": undefined, - "scale": undefined, - "top": undefined, "url": null, "width": 0, }, @@ -8594,10 +7398,8 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( 10, ], ], - "static": undefined, "title": "", }, - "static": undefined, "type": "image", "version": { "major": 0, @@ -8605,9 +7407,7 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( }, }, "passage 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "footnotes": "", "passageText": "", @@ -8615,7 +7415,6 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( "showLineNumbers": true, "static": false, }, - "static": undefined, "type": "passage", "version": { "major": 0, @@ -8623,15 +7422,11 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( }, }, "passage-ref 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "passageNumber": 1, "referenceNumber": 1, - "summaryText": undefined, }, - "static": undefined, "type": "passage-ref", "version": { "major": 0, @@ -8639,50 +7434,33 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( }, }, "radio 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "Members of the high nobility and the wealthiest of the knightly class", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "Soldiers, members of the civilian militia, and mercenaries", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "Horses and dogs", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { "clue": "Armor (of different styles and quality) was worn by almost all levels of society: high nobility (emperors, dukes, and counts), knights, mercenaries, citizens, peasants, and even young boys. Horses and dogs could also be protected with armor. Price varied considerably based on materials, quality, and decoration.", "content": "All of the above", "correct": true, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], - "countChoices": undefined, - "deselectEnabled": undefined, "displayCount": null, - "hasNoneOfTheAbove": undefined, "multipleSelect": false, "noneOfTheAbove": false, "onePerLine": true, "randomize": false, }, - "static": undefined, "type": "radio", "version": { "major": 0, @@ -8690,36 +7468,22 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( }, }, "radio 2": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], - "countChoices": undefined, - "deselectEnabled": undefined, "displayCount": null, - "hasNoneOfTheAbove": undefined, "multipleSelect": false, "noneOfTheAbove": false, "onePerLine": true, "randomize": false, }, - "static": undefined, "type": "radio", "version": { "major": 0, @@ -8727,9 +7491,7 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( }, }, "table 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answers": [ [ @@ -8751,7 +7513,6 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( ], "rows": 4, }, - "static": undefined, "type": "table", "version": { "major": 0, @@ -8765,7 +7526,6 @@ Anton Peffenhauser, *Foot-Combat Armor of Prince-Elector Christian I of Saxony ( exports[`parseAndTypecheckPerseusItem correctly parses data/plotter-missing-scaleY-and-snapsPerLine.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -8782,15 +7542,11 @@ $$ $\\green5 - \\red3= \\purple{2}$", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "Michaela gjorde $\\purple{2}$ korgar mer än William. ", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -8817,23 +7573,17 @@ $\\green5 - \\red3= \\purple{2}$", "width": 474, }, }, - "metadata": undefined, "widgets": { "input-number 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "answerType": "number", - "customKeypad": undefined, "inexact": false, "maxError": 0.1, - "rightAlign": undefined, "simplify": "required", "size": "normal", "value": 2, }, - "static": undefined, "type": "input-number", "version": { "major": 0, @@ -8841,9 +7591,6 @@ $\\green5 - \\red3= \\purple{2}$", }, }, "plotter 1": { - "alignment": undefined, - "graded": undefined, - "key": undefined, "options": { "categories": [ "Calista", @@ -8857,14 +7604,11 @@ $\\green5 - \\red3= \\purple{2}$", 1, 1, ], - "labelInterval": undefined, "labels": [ "Child", "Baskets", ], "maxY": 5, - "picBoxHeight": undefined, - "picSize": undefined, "picUrl": "http://i.imgur.com/B8mGnxB.png", "plotDimensions": [ 380, @@ -8880,9 +7624,7 @@ $\\green5 - \\red3= \\purple{2}$", ], "type": "pic", }, - "static": undefined, "type": "plotter", - "version": undefined, }, }, }, @@ -8891,7 +7633,6 @@ $\\green5 - \\red3= \\purple{2}$", exports[`parseAndTypecheckPerseusItem correctly parses data/plotter-with-undefined-plotDimensions.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -8899,13 +7640,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/plotter-with-undefin { "content": "If there is a 60° angle to the ground, this gives us a 30-60-90 triangle. ", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": { "plotter 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "categories": [ "", @@ -8919,9 +7656,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/plotter-with-undefin "", ], "maxY": 10, - "picBoxHeight": undefined, - "picSize": undefined, - "picUrl": undefined, "plotDimensions": [ 380, 300, @@ -8933,7 +7667,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/plotter-with-undefin ], "type": "bar", }, - "static": undefined, "type": "plotter", "version": { "major": 0, @@ -8945,15 +7678,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/plotter-with-undefin { "content": "In this case, the horizontal component of force should be equal to the cos θ multiplied by the force of tension. ", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, { "content": "Since we know θ=60, and T=30N, we can solve: 30cos60 = 15 N.", "images": {}, - "metadata": undefined, - "replace": undefined, "widgets": {}, }, ], @@ -8968,53 +7697,33 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/plotter-with-undefin ", "images": {}, - "metadata": undefined, "widgets": { "radio 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "15 N", "correct": true, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "30 N", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "60 N", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "180 N", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], - "countChoices": undefined, "deselectEnabled": false, "displayCount": null, - "hasNoneOfTheAbove": undefined, "multipleSelect": false, "noneOfTheAbove": false, "onePerLine": true, "randomize": true, }, - "static": undefined, "type": "radio", "version": { "major": 0, @@ -9028,14 +7737,11 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/plotter-with-undefin exports[`parseAndTypecheckPerseusItem correctly parses data/question-missing-content.json 1`] = ` { - "answer": undefined, "answerArea": {}, "hints": [], - "itemDataVersion": undefined, "question": { "content": "", "images": {}, - "metadata": undefined, "widgets": {}, }, } @@ -9043,7 +7749,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/question-missing-con exports[`parseAndTypecheckPerseusItem correctly parses data/radio-choice-missing-content.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -9063,64 +7768,39 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/radio-choice-missing [[☃ group 4]]", "images": {}, - "metadata": undefined, "widgets": { "group 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "content": " [[☃ radio 1]]", "images": {}, - "metadata": undefined, "widgets": { "radio 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], - "countChoices": undefined, "deselectEnabled": false, "displayCount": null, - "hasNoneOfTheAbove": undefined, "multipleSelect": false, "noneOfTheAbove": false, "onePerLine": true, "randomize": false, }, - "static": undefined, "type": "radio", "version": { "major": 0, @@ -9129,7 +7809,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/radio-choice-missing }, }, }, - "static": undefined, "type": "group", "version": { "major": 0, @@ -9137,61 +7816,37 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/radio-choice-missing }, }, "group 2": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "content": " [[☃ radio 1]]", "images": {}, - "metadata": undefined, "widgets": { "radio 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], - "countChoices": undefined, "deselectEnabled": false, "displayCount": null, - "hasNoneOfTheAbove": undefined, "multipleSelect": false, "noneOfTheAbove": false, "onePerLine": true, "randomize": false, }, - "static": undefined, "type": "radio", "version": { "major": 0, @@ -9200,7 +7855,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/radio-choice-missing }, }, }, - "static": undefined, "type": "group", "version": { "major": 0, @@ -9208,61 +7862,37 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/radio-choice-missing }, }, "group 3": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "content": " [[☃ radio 1]]", "images": {}, - "metadata": undefined, "widgets": { "radio 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], - "countChoices": undefined, "deselectEnabled": false, "displayCount": null, - "hasNoneOfTheAbove": undefined, "multipleSelect": false, "noneOfTheAbove": false, "onePerLine": true, "randomize": false, }, - "static": undefined, "type": "radio", "version": { "major": 0, @@ -9271,7 +7901,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/radio-choice-missing }, }, }, - "static": undefined, "type": "group", "version": { "major": 0, @@ -9279,61 +7908,37 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/radio-choice-missing }, }, "group 4": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "content": " [[☃ radio 1]]", "images": {}, - "metadata": undefined, "widgets": { "radio 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "", - "correct": undefined, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], - "countChoices": undefined, "deselectEnabled": false, "displayCount": null, - "hasNoneOfTheAbove": undefined, "multipleSelect": false, "noneOfTheAbove": false, "onePerLine": true, "randomize": false, }, - "static": undefined, "type": "radio", "version": { "major": 0, @@ -9342,7 +7947,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/radio-choice-missing }, }, }, - "static": undefined, "type": "group", "version": { "major": 0, @@ -9356,7 +7960,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/radio-choice-missing exports[`parseAndTypecheckPerseusItem correctly parses data/radio-missing-noneOfTheAbove.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, "chi2Table": false, @@ -9380,27 +7983,19 @@ B &= \\{x: x \\text{ is a square in the plane P} \\} [[☃ radio 1]] ", "images": {}, - "metadata": undefined, "widgets": { "radio 1": { "alignment": "default", "graded": true, - "key": undefined, "options": { "choices": [ { - "clue": undefined, "content": "Yes", "correct": false, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, { - "clue": undefined, "content": "No", "correct": true, - "isNoneOfTheAbove": undefined, - "widgets": undefined, }, ], "countChoices": false, @@ -9408,8 +8003,6 @@ B &= \\{x: x \\text{ is a square in the plane P} \\} "displayCount": null, "hasNoneOfTheAbove": false, "multipleSelect": false, - "noneOfTheAbove": undefined, - "onePerLine": undefined, "randomize": false, }, "static": false, @@ -9426,7 +8019,6 @@ B &= \\{x: x \\text{ is a square in the plane P} \\} exports[`parseAndTypecheckPerseusItem correctly parses data/simulator-widget.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -9440,12 +8032,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/simulator-widget.jso ", "images": {}, - "metadata": undefined, "widgets": { "simulator 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "numTrials": 100, "proportionLabel": "Underlying proportion", @@ -9453,7 +8042,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/simulator-widget.jso "xAxisLabel": "Proportion (%)", "yAxisLabel": "Number of times seen", }, - "static": undefined, "type": "deprecated-standin", "version": { "major": 0, @@ -9461,9 +8049,7 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/simulator-widget.jso }, }, "sorter 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "correct": [ "$x$", @@ -9473,7 +8059,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/simulator-widget.jso "layout": "horizontal", "padding": true, }, - "static": undefined, "type": "sorter", "version": { "major": 0, @@ -9487,7 +8072,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/simulator-widget.jso exports[`parseAndTypecheckPerseusItem correctly parses data/transformer-widget.json 1`] = ` { - "answer": undefined, "answerArea": { "calculator": false, }, @@ -9501,12 +8085,9 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/transformer-widget.j ", "images": {}, - "metadata": undefined, "widgets": { "transformer 1": { - "alignment": undefined, "graded": true, - "key": undefined, "options": { "correct": { "shape": { @@ -9641,7 +8222,6 @@ exports[`parseAndTypecheckPerseusItem correctly parses data/transformer-widget.j }, "version": 1.2, }, - "static": undefined, "type": "deprecated-standin", "version": { "major": 0, diff --git a/packages/perseus/src/util/scoring.ts b/packages/perseus/src/util/scoring.ts index b66af9c8f8..2c55b4c2d0 100644 --- a/packages/perseus/src/util/scoring.ts +++ b/packages/perseus/src/util/scoring.ts @@ -1,8 +1,7 @@ import {Errors, PerseusError} from "@khanacademy/perseus-core"; -import type {PerseusScore} from "../types"; -import type {UserInputArray} from "../validation.types"; import type {KEScore} from "@khanacademy/perseus-core"; +import type {PerseusScore, UserInputArray} from "@khanacademy/perseus-score"; const noScore: PerseusScore = { type: "points", diff --git a/packages/perseus/src/util/test-utils.ts b/packages/perseus/src/util/test-utils.ts index be236562c8..342ff61176 100644 --- a/packages/perseus/src/util/test-utils.ts +++ b/packages/perseus/src/util/test-utils.ts @@ -1,8 +1,6 @@ import {scorePerseusItem} from "../renderer-util"; import {mockStrings} from "../strings"; -import type {PerseusScore} from "../types"; -import type {UserInputMap} from "../validation.types"; import type { CategorizerWidget, ExpressionWidget, @@ -12,6 +10,7 @@ import type { PerseusRenderer, RadioWidget, } from "@khanacademy/perseus-core"; +import type {PerseusScore, UserInputMap} from "@khanacademy/perseus-score"; export const genericPerseusItemData: PerseusItem = { question: { diff --git a/packages/perseus/src/widget-ai-utils/categorizer/categorizer-ai-utils.test.ts b/packages/perseus/src/widget-ai-utils/categorizer/categorizer-ai-utils.test.ts index dd9521f9e6..6aa9cdff5a 100644 --- a/packages/perseus/src/widget-ai-utils/categorizer/categorizer-ai-utils.test.ts +++ b/packages/perseus/src/widget-ai-utils/categorizer/categorizer-ai-utils.test.ts @@ -7,8 +7,8 @@ import {renderQuestion} from "../../widgets/__testutils__/renderQuestion"; import {getPromptJSON} from "./categorizer-ai-utils"; -import type {PerseusCategorizerUserInput} from "../../validation.types"; import type {PerseusRenderer} from "@khanacademy/perseus-core"; +import type {PerseusCategorizerUserInput} from "@khanacademy/perseus-score"; import type {UserEvent} from "@testing-library/user-event"; const randomizedQuestion: PerseusRenderer = { diff --git a/packages/perseus/src/widget-ai-utils/categorizer/categorizer-ai-utils.ts b/packages/perseus/src/widget-ai-utils/categorizer/categorizer-ai-utils.ts index 0d69e5102c..51227a6ba6 100644 --- a/packages/perseus/src/widget-ai-utils/categorizer/categorizer-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/categorizer/categorizer-ai-utils.ts @@ -1,5 +1,5 @@ -import type {PerseusCategorizerUserInput} from "../../validation.types"; import type categorizer from "../../widgets/categorizer/categorizer"; +import type {PerseusCategorizerUserInput} from "@khanacademy/perseus-score"; import type React from "react"; export type CategorizerPromptJSON = { diff --git a/packages/perseus/src/widget-ai-utils/dropdown/dropdown-ai-utils.test.ts b/packages/perseus/src/widget-ai-utils/dropdown/dropdown-ai-utils.test.ts index 79a49dc0bc..e9267f58da 100644 --- a/packages/perseus/src/widget-ai-utils/dropdown/dropdown-ai-utils.test.ts +++ b/packages/perseus/src/widget-ai-utils/dropdown/dropdown-ai-utils.test.ts @@ -5,8 +5,8 @@ import {renderQuestion} from "../../widgets/__testutils__/renderQuestion"; import {getPromptJSON} from "./dropdown-ai-utils"; -import type {PerseusDropdownUserInput} from "../../validation.types"; import type {PerseusRenderer} from "@khanacademy/perseus-core"; +import type {PerseusDropdownUserInput} from "@khanacademy/perseus-score"; import type {UserEvent} from "@testing-library/user-event"; const question1: PerseusRenderer = { diff --git a/packages/perseus/src/widget-ai-utils/dropdown/dropdown-ai-utils.ts b/packages/perseus/src/widget-ai-utils/dropdown/dropdown-ai-utils.ts index 501ac1fb83..cdfd76f813 100644 --- a/packages/perseus/src/widget-ai-utils/dropdown/dropdown-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/dropdown/dropdown-ai-utils.ts @@ -1,5 +1,5 @@ -import type {PerseusDropdownUserInput} from "../../validation.types"; import type dropdown from "../../widgets/dropdown/dropdown"; +import type {PerseusDropdownUserInput} from "@khanacademy/perseus-score"; import type React from "react"; export type DropdownPromptJSON = { diff --git a/packages/perseus/src/widget-ai-utils/expression/expression-ai-utils.ts b/packages/perseus/src/widget-ai-utils/expression/expression-ai-utils.ts index b1d1171707..20fc757091 100644 --- a/packages/perseus/src/widget-ai-utils/expression/expression-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/expression/expression-ai-utils.ts @@ -1,5 +1,5 @@ -import type {PerseusExpressionUserInput} from "../../validation.types"; import type expression from "../../widgets/expression/expression"; +import type {PerseusExpressionUserInput} from "@khanacademy/perseus-score"; import type React from "react"; export type ExpressionPromptJSON = { diff --git a/packages/perseus/src/widget-ai-utils/grapher/grapher-ai-utils.ts b/packages/perseus/src/widget-ai-utils/grapher/grapher-ai-utils.ts index 1fde7b63b2..4b95040057 100644 --- a/packages/perseus/src/widget-ai-utils/grapher/grapher-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/grapher/grapher-ai-utils.ts @@ -1,6 +1,6 @@ -import type {PerseusGrapherUserInput} from "../../validation.types"; import type grapher from "../../widgets/grapher/grapher"; import type {GrapherAnswerTypes} from "@khanacademy/perseus-core"; +import type {PerseusGrapherUserInput} from "@khanacademy/perseus-score"; import type React from "react"; export type GrapherPromptJSON = { diff --git a/packages/perseus/src/widget-ai-utils/input-number/input-number-ai-utils.test.ts b/packages/perseus/src/widget-ai-utils/input-number/input-number-ai-utils.test.ts index fae736a7fd..4948b8ef7b 100644 --- a/packages/perseus/src/widget-ai-utils/input-number/input-number-ai-utils.test.ts +++ b/packages/perseus/src/widget-ai-utils/input-number/input-number-ai-utils.test.ts @@ -5,11 +5,11 @@ import {renderQuestion} from "../../widgets/__testutils__/renderQuestion"; import {getPromptJSON} from "./input-number-ai-utils"; -import type {PerseusInputNumberUserInput} from "../../validation.types"; import type { InputNumberWidget, PerseusRenderer, } from "@khanacademy/perseus-core"; +import type {PerseusInputNumberUserInput} from "@khanacademy/perseus-score"; import type {UserEvent} from "@testing-library/user-event"; const question: PerseusRenderer = { diff --git a/packages/perseus/src/widget-ai-utils/input-number/input-number-ai-utils.ts b/packages/perseus/src/widget-ai-utils/input-number/input-number-ai-utils.ts index 5b21df604c..8a62685233 100644 --- a/packages/perseus/src/widget-ai-utils/input-number/input-number-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/input-number/input-number-ai-utils.ts @@ -1,5 +1,5 @@ -import type {PerseusInputNumberUserInput} from "../../validation.types"; import type inputNumber from "../../widgets/input-number/input-number"; +import type {PerseusInputNumberUserInput} from "@khanacademy/perseus-score"; import type React from "react"; export type InputNumberPromptJSON = { diff --git a/packages/perseus/src/widget-ai-utils/label-image/label-image-ai-utils.ts b/packages/perseus/src/widget-ai-utils/label-image/label-image-ai-utils.ts index fc7a56f546..91532bd2e9 100644 --- a/packages/perseus/src/widget-ai-utils/label-image/label-image-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/label-image/label-image-ai-utils.ts @@ -1,5 +1,5 @@ -import type {PerseusLabelImageUserInput} from "../../validation.types"; import type labelImage from "../../widgets/label-image/label-image"; +import type {PerseusLabelImageUserInput} from "@khanacademy/perseus-score"; import type React from "react"; type BaseMarker = { diff --git a/packages/perseus/src/widget-ai-utils/matcher/matcher-ai-utils.test.tsx b/packages/perseus/src/widget-ai-utils/matcher/matcher-ai-utils.test.tsx index 95ba6e1736..82033cff9b 100644 --- a/packages/perseus/src/widget-ai-utils/matcher/matcher-ai-utils.test.tsx +++ b/packages/perseus/src/widget-ai-utils/matcher/matcher-ai-utils.test.tsx @@ -7,8 +7,8 @@ import {renderQuestion} from "../../widgets/__testutils__/renderQuestion"; import {getPromptJSON} from "./matcher-ai-utils"; -import type {PerseusMatcherUserInput} from "../../validation.types"; import type {PerseusRenderer} from "@khanacademy/perseus-core"; +import type {PerseusMatcherUserInput} from "@khanacademy/perseus-score"; const question1: PerseusRenderer = { content: diff --git a/packages/perseus/src/widget-ai-utils/matcher/matcher-ai-utils.ts b/packages/perseus/src/widget-ai-utils/matcher/matcher-ai-utils.ts index 75fef76d7e..bc274e9945 100644 --- a/packages/perseus/src/widget-ai-utils/matcher/matcher-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/matcher/matcher-ai-utils.ts @@ -1,5 +1,5 @@ -import type {PerseusMatcherUserInput} from "../../validation.types"; import type matcher from "../../widgets/matcher/matcher"; +import type {PerseusMatcherUserInput} from "@khanacademy/perseus-score"; import type React from "react"; export type MatcherPromptJSON = { diff --git a/packages/perseus/src/widget-ai-utils/matrix/matrix-ai-utils.ts b/packages/perseus/src/widget-ai-utils/matrix/matrix-ai-utils.ts index 4e3cc1bb48..b6409dece3 100644 --- a/packages/perseus/src/widget-ai-utils/matrix/matrix-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/matrix/matrix-ai-utils.ts @@ -1,5 +1,5 @@ -import type {PerseusMatrixUserInput} from "../../validation.types"; import type matrix from "../../widgets/matrix/matrix"; +import type {PerseusMatrixUserInput} from "@khanacademy/perseus-score"; import type React from "react"; export type MatrixPromptJSON = { diff --git a/packages/perseus/src/widget-ai-utils/number-line/number-line-ai-utils.ts b/packages/perseus/src/widget-ai-utils/number-line/number-line-ai-utils.ts index 79ccf57fd3..5d8f4ee522 100644 --- a/packages/perseus/src/widget-ai-utils/number-line/number-line-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/number-line/number-line-ai-utils.ts @@ -1,5 +1,5 @@ -import type {PerseusNumberLineUserInput} from "../../validation.types"; import type numberLine from "../../widgets/number-line/number-line"; +import type {PerseusNumberLineUserInput} from "@khanacademy/perseus-score"; import type React from "react"; export type NumberLinePromptJSON = { diff --git a/packages/perseus/src/widget-ai-utils/numeric-input/prompt-utils.test.ts b/packages/perseus/src/widget-ai-utils/numeric-input/prompt-utils.test.ts index 87522e6064..bea3f8f823 100644 --- a/packages/perseus/src/widget-ai-utils/numeric-input/prompt-utils.test.ts +++ b/packages/perseus/src/widget-ai-utils/numeric-input/prompt-utils.test.ts @@ -1,6 +1,6 @@ import {getPromptJSON} from "./prompt-utils"; -import type {PerseusNumericInputUserInput} from "../../validation.types"; +import type {PerseusNumericInputUserInput} from "@khanacademy/perseus-score"; describe("NumericInput getPromptJSON", () => { it("it returns JSON with the expected format and fields", () => { diff --git a/packages/perseus/src/widget-ai-utils/numeric-input/prompt-utils.ts b/packages/perseus/src/widget-ai-utils/numeric-input/prompt-utils.ts index 7472abc80c..974d14d3df 100644 --- a/packages/perseus/src/widget-ai-utils/numeric-input/prompt-utils.ts +++ b/packages/perseus/src/widget-ai-utils/numeric-input/prompt-utils.ts @@ -1,5 +1,5 @@ -import type {PerseusNumericInputUserInput} from "../../validation.types"; import type numericInput from "../../widgets/numeric-input/numeric-input"; +import type {PerseusNumericInputUserInput} from "@khanacademy/perseus-score"; import type React from "react"; export type NumericInputPromptJSON = { diff --git a/packages/perseus/src/widget-ai-utils/orderer/orderer-ai-utils.ts b/packages/perseus/src/widget-ai-utils/orderer/orderer-ai-utils.ts index e4ab89d1a5..43f7890042 100644 --- a/packages/perseus/src/widget-ai-utils/orderer/orderer-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/orderer/orderer-ai-utils.ts @@ -1,5 +1,5 @@ -import type {PerseusOrdererUserInput} from "../../validation.types"; import type orderer from "../../widgets/orderer/orderer"; +import type {PerseusOrdererUserInput} from "@khanacademy/perseus-score"; import type React from "react"; export type OrdererPromptJSON = { diff --git a/packages/perseus/src/widget-ai-utils/radio/radio-ai-utils.test.ts b/packages/perseus/src/widget-ai-utils/radio/radio-ai-utils.test.ts index 02f5750327..1b879bc946 100644 --- a/packages/perseus/src/widget-ai-utils/radio/radio-ai-utils.test.ts +++ b/packages/perseus/src/widget-ai-utils/radio/radio-ai-utils.test.ts @@ -7,8 +7,8 @@ import {renderQuestion} from "../../widgets/__testutils__/renderQuestion"; import {getPromptJSON} from "./radio-ai-utils"; -import type {PerseusRadioUserInput} from "../../validation.types"; import type {PerseusRenderer, RadioWidget} from "@khanacademy/perseus-core"; +import type {PerseusRadioUserInput} from "@khanacademy/perseus-score"; import type {UserEvent} from "@testing-library/user-event"; const shuffledQuestion: PerseusRenderer = { diff --git a/packages/perseus/src/widget-ai-utils/radio/radio-ai-utils.ts b/packages/perseus/src/widget-ai-utils/radio/radio-ai-utils.ts index 611685112c..b0eaa1f020 100644 --- a/packages/perseus/src/widget-ai-utils/radio/radio-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/radio/radio-ai-utils.ts @@ -1,5 +1,5 @@ -import type {PerseusRadioUserInput} from "../../validation.types"; import type radio from "../../widgets/radio/radio"; +import type {PerseusRadioUserInput} from "@khanacademy/perseus-score"; import type React from "react"; export type BasicOption = { diff --git a/packages/perseus/src/widget-ai-utils/sorter/sorter-ai-utils.test.ts b/packages/perseus/src/widget-ai-utils/sorter/sorter-ai-utils.test.ts index 6d8fa17169..67744c008e 100644 --- a/packages/perseus/src/widget-ai-utils/sorter/sorter-ai-utils.test.ts +++ b/packages/perseus/src/widget-ai-utils/sorter/sorter-ai-utils.test.ts @@ -1,6 +1,6 @@ import {getPromptJSON} from "./sorter-ai-utils"; -import type {PerseusSorterUserInput} from "../../validation.types"; +import type {PerseusSorterUserInput} from "@khanacademy/perseus-score"; describe("Sorter AI utils", () => { it("it returns JSON with the expected format and fields", () => { diff --git a/packages/perseus/src/widget-ai-utils/sorter/sorter-ai-utils.ts b/packages/perseus/src/widget-ai-utils/sorter/sorter-ai-utils.ts index 6fdd1670c0..05cbb5d96a 100644 --- a/packages/perseus/src/widget-ai-utils/sorter/sorter-ai-utils.ts +++ b/packages/perseus/src/widget-ai-utils/sorter/sorter-ai-utils.ts @@ -1,4 +1,4 @@ -import type {PerseusSorterUserInput} from "../../validation.types"; +import type {PerseusSorterUserInput} from "@khanacademy/perseus-score"; export type SorterPromptJSON = { type: "sorter"; diff --git a/packages/perseus/src/widgets/__shared__/score-noop.ts b/packages/perseus/src/widgets/__shared__/score-noop.ts index 1fe77e1dab..6896b95418 100644 --- a/packages/perseus/src/widgets/__shared__/score-noop.ts +++ b/packages/perseus/src/widgets/__shared__/score-noop.ts @@ -1,4 +1,4 @@ -import type {PerseusScore} from "../../types"; +import type {PerseusScore} from "@khanacademy/perseus-score"; /** * Several widgets don't have "right"/"wrong" scoring logic, diff --git a/packages/perseus/src/widgets/categorizer/categorizer.test.ts b/packages/perseus/src/widgets/categorizer/categorizer.test.ts index faffac1441..d2dcdeb02a 100644 --- a/packages/perseus/src/widgets/categorizer/categorizer.test.ts +++ b/packages/perseus/src/widgets/categorizer/categorizer.test.ts @@ -70,7 +70,7 @@ describe("categorizer widget", () => { // Assert expect(score).toMatchInlineSnapshot(` { - "message": "Make sure you select something for every row.", + "message": "INVALID_SELECTION_ERROR", "type": "invalid", } `); @@ -94,7 +94,7 @@ describe("categorizer widget", () => { // assert expect(score).toMatchInlineSnapshot(` { - "message": "Make sure you select something for every row.", + "message": "INVALID_SELECTION_ERROR", "type": "invalid", } `); diff --git a/packages/perseus/src/widgets/categorizer/categorizer.tsx b/packages/perseus/src/widgets/categorizer/categorizer.tsx index 62e5f62480..d982b294df 100644 --- a/packages/perseus/src/widgets/categorizer/categorizer.tsx +++ b/packages/perseus/src/widgets/categorizer/categorizer.tsx @@ -1,5 +1,9 @@ /* eslint-disable @khanacademy/ts-no-error-suppressions */ import {linterContextDefault} from "@khanacademy/perseus-linter"; +import { + scoreCategorizer, + validateCategorizer, +} from "@khanacademy/perseus-score"; import {StyleSheet, css} from "aphrodite"; import classNames from "classnames"; import * as React from "react"; @@ -17,16 +21,14 @@ import Util from "../../util"; import {getPromptJSON as _getPromptJSON} from "../../widget-ai-utils/categorizer/categorizer-ai-utils"; import getCategorizerPublicWidgetOptions from "./categorizer.util"; -import scoreCategorizer from "./score-categorizer"; -import validateCategorizer from "./validate-categorizer"; import type {Widget, WidgetExports, WidgetProps} from "../../types"; +import type {CategorizerPromptJSON} from "../../widget-ai-utils/categorizer/categorizer-ai-utils"; +import type {PerseusCategorizerWidgetOptions} from "@khanacademy/perseus-core"; import type { PerseusCategorizerScoringData, PerseusCategorizerUserInput, -} from "../../validation.types"; -import type {CategorizerPromptJSON} from "../../widget-ai-utils/categorizer/categorizer-ai-utils"; -import type {PerseusCategorizerWidgetOptions} from "@khanacademy/perseus-core"; +} from "@khanacademy/perseus-score"; type Props = WidgetProps & { values: ReadonlyArray; diff --git a/packages/perseus/src/widgets/cs-program/cs-program.test.ts b/packages/perseus/src/widgets/cs-program/cs-program.test.ts index 89f9ab8699..7a47a73ece 100644 --- a/packages/perseus/src/widgets/cs-program/cs-program.test.ts +++ b/packages/perseus/src/widgets/cs-program/cs-program.test.ts @@ -4,7 +4,7 @@ import {renderQuestion} from "../__testutils__/renderQuestion"; import {question1} from "./cs-program.testdata"; -import type {PerseusCSProgramUserInput} from "../../validation.types"; +import type {PerseusCSProgramUserInput} from "@khanacademy/perseus-score"; describe("cs-program widget", () => { beforeEach(() => { diff --git a/packages/perseus/src/widgets/cs-program/cs-program.tsx b/packages/perseus/src/widgets/cs-program/cs-program.tsx index ce374996bf..e652ed6e5f 100644 --- a/packages/perseus/src/widgets/cs-program/cs-program.tsx +++ b/packages/perseus/src/widgets/cs-program/cs-program.tsx @@ -2,6 +2,7 @@ * This widget is for embedding Khan Academy CS programs. */ +import {scoreCSProgram} from "@khanacademy/perseus-score"; import {StyleSheet, css} from "aphrodite"; import $ from "jquery"; import * as React from "react"; @@ -15,12 +16,10 @@ import {isFileProtocol} from "../../util/mobile-native-utils"; import {toAbsoluteUrl} from "../../util/url-utils"; import {getPromptJSON as _getPromptJSON} from "../../widget-ai-utils/cs-program/cs-program-ai-utils"; -import scoreCSProgram from "./score-cs-program"; - import type {Widget, WidgetExports, WidgetProps} from "../../types"; -import type {PerseusCSProgramUserInput} from "../../validation.types"; import type {UnsupportedWidgetPromptJSON} from "../../widget-ai-utils/unsupported-widget"; import type {PerseusCSProgramWidgetOptions} from "@khanacademy/perseus-core"; +import type {PerseusCSProgramUserInput} from "@khanacademy/perseus-score"; const {updateQueryString} = Util; diff --git a/packages/perseus/src/widgets/dropdown/dropdown.tsx b/packages/perseus/src/widgets/dropdown/dropdown.tsx index 8e07616d95..5e0204111a 100644 --- a/packages/perseus/src/widgets/dropdown/dropdown.tsx +++ b/packages/perseus/src/widgets/dropdown/dropdown.tsx @@ -1,3 +1,4 @@ +import {scoreDropdown, validateDropdown} from "@khanacademy/perseus-score"; import {Id, View} from "@khanacademy/wonder-blocks-core"; import {SingleSelect, OptionItem} from "@khanacademy/wonder-blocks-dropdown"; import {LabelLarge} from "@khanacademy/wonder-blocks-typography"; @@ -9,16 +10,13 @@ import {ApiOptions} from "../../perseus-api"; import Renderer from "../../renderer"; import {getPromptJSON as _getPromptJSON} from "../../widget-ai-utils/dropdown/dropdown-ai-utils"; -import scoreDropdown from "./score-dropdown"; -import validateDropdown from "./validate-dropdown"; - import type {Widget, WidgetExports, WidgetProps} from "../../types"; +import type {DropdownPromptJSON} from "../../widget-ai-utils/dropdown/dropdown-ai-utils"; +import type {PerseusDropdownWidgetOptions} from "@khanacademy/perseus-core"; import type { PerseusDropdownScoringData, PerseusDropdownUserInput, -} from "../../validation.types"; -import type {DropdownPromptJSON} from "../../widget-ai-utils/dropdown/dropdown-ai-utils"; -import type {PerseusDropdownWidgetOptions} from "@khanacademy/perseus-core"; +} from "@khanacademy/perseus-score"; type Props = WidgetProps & { selected: number; diff --git a/packages/perseus/src/widgets/explanation/__snapshots__/explanation.test.ts.snap b/packages/perseus/src/widgets/explanation/__snapshots__/explanation.test.ts.snap index 3383f7cfa0..e96e0672b6 100644 --- a/packages/perseus/src/widgets/explanation/__snapshots__/explanation.test.ts.snap +++ b/packages/perseus/src/widgets/explanation/__snapshots__/explanation.test.ts.snap @@ -21,12 +21,12 @@ exports[`Explanation should snapshot when expanded: expanded 1`] = ` aria-controls=":r1:" aria-disabled="false" aria-expanded="true" - class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1hl5pu8-o_O-small_14crccx-o_O-inlineStyles_1s8anjv" + class="button_vr44p2-o_O-shared_lwskrm-o_O-default_qjb97o-o_O-small_14crccx-o_O-inlineStyles_1s8anjv" role="button" type="button" > Hide explanation! @@ -94,12 +94,12 @@ exports[`Explanation should snapshot: initial render 1`] = ` aria-controls=":r0:" aria-disabled="false" aria-expanded="false" - class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1hl5pu8-o_O-small_14crccx-o_O-inlineStyles_1s8anjv" + class="button_vr44p2-o_O-shared_lwskrm-o_O-default_qjb97o-o_O-small_14crccx-o_O-inlineStyles_1s8anjv" role="button" type="button" > Explanation diff --git a/packages/perseus/src/widgets/expression/expression.tsx b/packages/perseus/src/widgets/expression/expression.tsx index a67c005b80..31f1beafe1 100644 --- a/packages/perseus/src/widgets/expression/expression.tsx +++ b/packages/perseus/src/widgets/expression/expression.tsx @@ -1,6 +1,11 @@ import * as KAS from "@khanacademy/kas"; import {KeyArray, KeypadInput, KeypadType} from "@khanacademy/math-input"; +import { + getDecimalSeparator, + type PerseusExpressionWidgetOptions, +} from "@khanacademy/perseus-core"; import {linterContextDefault} from "@khanacademy/perseus-linter"; +import {scoreExpression, validateExpression} from "@khanacademy/perseus-score"; import {View} from "@khanacademy/wonder-blocks-core"; import Tooltip from "@khanacademy/wonder-blocks-tooltip"; import {LabelSmall} from "@khanacademy/wonder-blocks-typography"; @@ -18,19 +23,14 @@ import {ApiOptions, ClassNames as ApiClassNames} from "../../perseus-api"; import a11y from "../../util/a11y"; import {getPromptJSON as _getPromptJSON} from "../../widget-ai-utils/expression/expression-ai-utils"; -import getDecimalSeparator from "./get-decimal-separator"; -import scoreExpression from "./score-expression"; -import validateExpression from "./validate-expression"; - import type {DependenciesContext} from "../../dependencies"; -import type {FocusPath, Widget, WidgetExports, WidgetProps} from "../../types"; +import type {WidgetProps, Widget, FocusPath, WidgetExports} from "../../types"; +import type {ExpressionPromptJSON} from "../../widget-ai-utils/expression/expression-ai-utils"; +import type {Keys as Key, KeypadConfiguration} from "@khanacademy/math-input"; import type { PerseusExpressionScoringData, PerseusExpressionUserInput, -} from "../../validation.types"; -import type {ExpressionPromptJSON} from "../../widget-ai-utils/expression/expression-ai-utils"; -import type {Keys as Key, KeypadConfiguration} from "@khanacademy/math-input"; -import type {PerseusExpressionWidgetOptions} from "@khanacademy/perseus-core"; +} from "@khanacademy/perseus-score"; import type {PropsFor} from "@khanacademy/wonder-blocks-core"; type InputPath = ReadonlyArray; diff --git a/packages/perseus/src/widgets/graded-group-set/__snapshots__/graded-group-set-jipt.test.ts.snap b/packages/perseus/src/widgets/graded-group-set/__snapshots__/graded-group-set-jipt.test.ts.snap index 6d4b738751..fcf253b7dd 100644 --- a/packages/perseus/src/widgets/graded-group-set/__snapshots__/graded-group-set-jipt.test.ts.snap +++ b/packages/perseus/src/widgets/graded-group-set/__snapshots__/graded-group-set-jipt.test.ts.snap @@ -251,12 +251,12 @@ exports[`graded-group-set should render all graded groups 1`] = ` />