@khanacademy/perseus 19.1.4 → 19.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (487) hide show
  1. package/dist/components/graphie.d.ts +9 -1
  2. package/dist/es/index.js +255 -122
  3. package/dist/es/index.js.map +1 -1
  4. package/dist/index.js +261 -126
  5. package/dist/index.js.map +1 -1
  6. package/dist/interactive2/interactive-util.d.ts +1 -1
  7. package/dist/interactive2/movable-point-options.d.ts +5 -4
  8. package/dist/interactive2/movable.d.ts +90 -13
  9. package/dist/interactive2/types.d.ts +6 -0
  10. package/dist/util/graphie.d.ts +5 -0
  11. package/dist/widgets/expression.d.ts +4 -4
  12. package/package.json +11 -8
  13. package/.babelrc.js +0 -8
  14. package/.eslintrc.js +0 -12
  15. package/CHANGELOG.md +0 -1422
  16. package/src/__stories__/article-renderer.stories.tsx +0 -100
  17. package/src/__stories__/hints-renderer.stories.tsx +0 -55
  18. package/src/__stories__/server-item-renderer.stories.tsx +0 -44
  19. package/src/__testdata__/article-renderer.testdata.ts +0 -212
  20. package/src/__testdata__/graphie.testdata.ts +0 -51
  21. package/src/__testdata__/renderer.testdata.ts +0 -274
  22. package/src/__testdata__/server-item-renderer.testdata.ts +0 -171
  23. package/src/__tests__/__snapshots__/perseus-markdown.test.ts.snap +0 -507
  24. package/src/__tests__/__snapshots__/renderer.test.tsx.snap +0 -525
  25. package/src/__tests__/__snapshots__/server-item-renderer.test.tsx.snap +0 -285
  26. package/src/__tests__/a11y.test.ts +0 -303
  27. package/src/__tests__/article-renderer.test.tsx +0 -130
  28. package/src/__tests__/error-boundary.test.tsx +0 -76
  29. package/src/__tests__/extract-perseus-data.test.ts +0 -1027
  30. package/src/__tests__/init.test.ts +0 -10
  31. package/src/__tests__/jipt-paragraphs.test.ts +0 -32
  32. package/src/__tests__/mock-asset-loading-widget.tsx +0 -53
  33. package/src/__tests__/mock-widget.tsx +0 -33
  34. package/src/__tests__/perseus-markdown.test.ts +0 -764
  35. package/src/__tests__/renderability.test.ts +0 -480
  36. package/src/__tests__/renderer-api.test.tsx +0 -302
  37. package/src/__tests__/renderer.test.tsx +0 -1816
  38. package/src/__tests__/server-item-renderer.test.tsx +0 -582
  39. package/src/__tests__/test-items/image-item.ts +0 -24
  40. package/src/__tests__/test-items/input-number-1-item.ts +0 -26
  41. package/src/__tests__/test-items/input-number-2-item.ts +0 -38
  42. package/src/__tests__/test-items/table-item.ts +0 -29
  43. package/src/__tests__/tex-wrangler.test.ts +0 -82
  44. package/src/__tests__/util.test.ts +0 -40
  45. package/src/__tests__/widget-container.test.tsx +0 -126
  46. package/src/__tests__/widgets.test.ts +0 -91
  47. package/src/a11y.ts +0 -45
  48. package/src/all-widgets.ts +0 -9
  49. package/src/article-renderer.tsx +0 -237
  50. package/src/asset-context.ts +0 -30
  51. package/src/basic-widgets.ts +0 -16
  52. package/src/components/__stories__/button-group.stories.tsx +0 -55
  53. package/src/components/__stories__/fixed-to-responsive.stories.tsx +0 -141
  54. package/src/components/__stories__/graph.stories.tsx +0 -28
  55. package/src/components/__stories__/graphie.stories.tsx +0 -33
  56. package/src/components/__stories__/hud.stories.tsx +0 -35
  57. package/src/components/__stories__/icon.stories.tsx +0 -63
  58. package/src/components/__stories__/image-loader.stories.tsx +0 -63
  59. package/src/components/__stories__/info-tip.stories.tsx +0 -31
  60. package/src/components/__stories__/inline-icon.stories.tsx +0 -40
  61. package/src/components/__stories__/input-with-examples.stories.tsx +0 -53
  62. package/src/components/__stories__/lint.stories.tsx +0 -86
  63. package/src/components/__stories__/math-input.stories.tsx +0 -43
  64. package/src/components/__stories__/math-output.stories.tsx +0 -23
  65. package/src/components/__stories__/multi-button-group.stories.tsx +0 -66
  66. package/src/components/__stories__/number-input.stories.tsx +0 -41
  67. package/src/components/__stories__/prop-check-box.stories.tsx +0 -65
  68. package/src/components/__stories__/range-input.stories.tsx +0 -29
  69. package/src/components/__stories__/simple-keypad-input.stories.tsx +0 -27
  70. package/src/components/__stories__/sortable.stories.tsx +0 -77
  71. package/src/components/__stories__/stub-tag-editor.stories.tsx +0 -45
  72. package/src/components/__stories__/svg-image.stories.tsx +0 -74
  73. package/src/components/__stories__/tex.stories.tsx +0 -23
  74. package/src/components/__stories__/text-input.stories.tsx +0 -33
  75. package/src/components/__stories__/text-list-editor.stories.tsx +0 -32
  76. package/src/components/__stories__/tooltip.stories.tsx +0 -52
  77. package/src/components/__stories__/zoomable-tex.stories.tsx +0 -41
  78. package/src/components/__stories__/zoomable.stories.tsx +0 -49
  79. package/src/components/__testdata__/sorter.testdata.ts +0 -19
  80. package/src/components/__tests__/__snapshots__/sortable.test.tsx.snap +0 -163
  81. package/src/components/__tests__/__snapshots__/sorter.test.tsx.snap +0 -265
  82. package/src/components/__tests__/math-input.test.tsx +0 -147
  83. package/src/components/__tests__/number-input.test.tsx +0 -128
  84. package/src/components/__tests__/sortable.test.tsx +0 -269
  85. package/src/components/__tests__/sorter.test.tsx +0 -114
  86. package/src/components/__tests__/zoomable.test.tsx +0 -399
  87. package/src/components/button-group.tsx +0 -130
  88. package/src/components/constants.ts +0 -14
  89. package/src/components/fixed-to-responsive.tsx +0 -169
  90. package/src/components/graph.tsx +0 -444
  91. package/src/components/graphie-classes.ts +0 -153
  92. package/src/components/graphie-movables.ts +0 -338
  93. package/src/components/graphie.tsx +0 -392
  94. package/src/components/highlighting/highlightable-content.tsx +0 -240
  95. package/src/components/highlighting/highlights.ts +0 -207
  96. package/src/components/highlighting/ranges.ts +0 -304
  97. package/src/components/highlighting/types.ts +0 -73
  98. package/src/components/highlighting/ui/highlight-renderer.tsx +0 -172
  99. package/src/components/highlighting/ui/highlight-set-renderer.tsx +0 -185
  100. package/src/components/highlighting/ui/highlight-tooltip.tsx +0 -141
  101. package/src/components/highlighting/ui/highlighting-ui.tsx +0 -143
  102. package/src/components/highlighting/ui/selection-tracker.tsx +0 -186
  103. package/src/components/highlighting/ui/types.ts +0 -21
  104. package/src/components/highlighting/ui/util.ts +0 -165
  105. package/src/components/highlighting/word-indexer.tsx +0 -152
  106. package/src/components/hud.tsx +0 -167
  107. package/src/components/icon.tsx +0 -141
  108. package/src/components/image-loader.tsx +0 -177
  109. package/src/components/info-tip/info-tip.tsx +0 -144
  110. package/src/components/info-tip.tsx +0 -39
  111. package/src/components/inline-icon.tsx +0 -60
  112. package/src/components/input-with-examples.tsx +0 -249
  113. package/src/components/lint.tsx +0 -459
  114. package/src/components/math-input.tsx +0 -474
  115. package/src/components/math-output.tsx +0 -134
  116. package/src/components/multi-button-group.tsx +0 -135
  117. package/src/components/number-input.tsx +0 -249
  118. package/src/components/prop-check-box.tsx +0 -79
  119. package/src/components/range-input.tsx +0 -60
  120. package/src/components/simple-keypad-input.tsx +0 -88
  121. package/src/components/sortable.tsx +0 -958
  122. package/src/components/stub-tag-editor.tsx +0 -53
  123. package/src/components/svg-image.tsx +0 -779
  124. package/src/components/tex.tsx +0 -67
  125. package/src/components/text-input.tsx +0 -129
  126. package/src/components/text-list-editor.tsx +0 -166
  127. package/src/components/tooltip.tsx +0 -410
  128. package/src/components/visibility-observer/__stories__/visibility-observer.stories.tsx +0 -141
  129. package/src/components/visibility-observer/create-visibility-observer.ts +0 -108
  130. package/src/components/visibility-observer/get-scroll-parent.ts +0 -46
  131. package/src/components/visibility-observer/visibility-observer.tsx +0 -124
  132. package/src/components/zoomable-tex.tsx +0 -78
  133. package/src/components/zoomable.tsx +0 -304
  134. package/src/components.ts +0 -15
  135. package/src/definition-context.tsx +0 -59
  136. package/src/dependencies.ts +0 -40
  137. package/src/error-boundary.tsx +0 -70
  138. package/src/extra-widgets.ts +0 -75
  139. package/src/hint-renderer.tsx +0 -151
  140. package/src/hints-renderer.tsx +0 -372
  141. package/src/icon-paths.ts +0 -119
  142. package/src/index.ts +0 -171
  143. package/src/init.ts +0 -56
  144. package/src/interaction-tracker.ts +0 -62
  145. package/src/interactive2/__tests__/movable-mock.ts +0 -43
  146. package/src/interactive2/__tests__/movable-point.test.ts +0 -144
  147. package/src/interactive2/__tests__/movable.test.ts +0 -157
  148. package/src/interactive2/interactive-util.test.ts +0 -93
  149. package/src/interactive2/interactive-util.ts +0 -159
  150. package/src/interactive2/movable-helper-methods.ts +0 -166
  151. package/src/interactive2/movable-line-options.ts +0 -419
  152. package/src/interactive2/movable-line.ts +0 -307
  153. package/src/interactive2/movable-point-options.ts +0 -212
  154. package/src/interactive2/movable-point.tsx +0 -585
  155. package/src/interactive2/movable-polygon-options.ts +0 -389
  156. package/src/interactive2/movable-polygon.ts +0 -360
  157. package/src/interactive2/movable.ts +0 -279
  158. package/src/interactive2/objective_.ts +0 -79
  159. package/src/interactive2/types.ts +0 -2
  160. package/src/interactive2/wrapped-defaults.ts +0 -87
  161. package/src/interactive2/wrapped-ellipse.ts +0 -94
  162. package/src/interactive2/wrapped-line.ts +0 -116
  163. package/src/interactive2/wrapped-path.ts +0 -51
  164. package/src/interactive2.ts +0 -70
  165. package/src/item-version.ts +0 -10
  166. package/src/jipt-paragraphs.ts +0 -49
  167. package/src/jquery.mobile.vmouse.js +0 -545
  168. package/src/loading-context.ts +0 -21
  169. package/src/logging/log.test.ts +0 -39
  170. package/src/logging/log.ts +0 -97
  171. package/src/mixins/__tests__/widget-prop-denylist.test.ts +0 -21
  172. package/src/mixins/changeable.ts +0 -133
  173. package/src/mixins/editor-jsonify.ts +0 -13
  174. package/src/mixins/widget-jsonify-deprecated.ts +0 -23
  175. package/src/mixins/widget-prop-denylist.ts +0 -48
  176. package/src/multi-items/__stories__/multi-renderer.stories.tsx +0 -83
  177. package/src/multi-items/__testdata__/multi-renderer.testdata.ts +0 -172
  178. package/src/multi-items/__tests__/__snapshots__/multi-renderer.test.tsx.snap +0 -1164
  179. package/src/multi-items/__tests__/items.test.ts +0 -240
  180. package/src/multi-items/__tests__/multi-renderer.test.tsx +0 -914
  181. package/src/multi-items/__tests__/prop-type-builders.test.ts +0 -133
  182. package/src/multi-items/__tests__/shapes.test.ts +0 -43
  183. package/src/multi-items/__tests__/trees.test.ts +0 -317
  184. package/src/multi-items/item-types.ts +0 -56
  185. package/src/multi-items/items.ts +0 -176
  186. package/src/multi-items/multi-renderer.tsx +0 -569
  187. package/src/multi-items/prop-type-builders.ts +0 -106
  188. package/src/multi-items/shape-types.ts +0 -52
  189. package/src/multi-items/shapes.ts +0 -52
  190. package/src/multi-items/tree-types.ts +0 -47
  191. package/src/multi-items/trees.ts +0 -360
  192. package/src/multi-items.ts +0 -75
  193. package/src/perseus-api.tsx +0 -188
  194. package/src/perseus-env.ts +0 -27
  195. package/src/perseus-error.ts +0 -17
  196. package/src/perseus-markdown.tsx +0 -405
  197. package/src/perseus-types.ts +0 -1366
  198. package/src/perseus-version.ts +0 -9
  199. package/src/question-paragraph.tsx +0 -34
  200. package/src/renderability.ts +0 -109
  201. package/src/renderer.tsx +0 -2000
  202. package/src/server-item-renderer.tsx +0 -495
  203. package/src/sigfigs.ts +0 -490
  204. package/src/styles/articles.less +0 -749
  205. package/src/styles/constants.ts +0 -94
  206. package/src/styles/global-constants.ts +0 -343
  207. package/src/styles/global-styles.ts +0 -306
  208. package/src/styles/khan-exercise.css +0 -1468
  209. package/src/styles/media-queries.ts +0 -47
  210. package/src/styles/perseus-renderer.less +0 -732
  211. package/src/styles/shared.ts +0 -130
  212. package/src/styles/util.less +0 -47
  213. package/src/styles/variables.boostrap.less +0 -277
  214. package/src/styles/variables.less +0 -56
  215. package/src/styles/variables.shared.less +0 -340
  216. package/src/styles/widgets/categorizer.less +0 -38
  217. package/src/styles/widgets/dropdown.less +0 -3
  218. package/src/styles/widgets/expression.less +0 -65
  219. package/src/styles/widgets/graded-group.less +0 -36
  220. package/src/styles/widgets/grapher.less +0 -12
  221. package/src/styles/widgets/group.less +0 -19
  222. package/src/styles/widgets/image.less +0 -54
  223. package/src/styles/widgets/interactive-graph.less +0 -64
  224. package/src/styles/widgets/label-image.less +0 -57
  225. package/src/styles/widgets/matcher.less +0 -8
  226. package/src/styles/widgets/matrix.less +0 -126
  227. package/src/styles/widgets/measurer.less +0 -20
  228. package/src/styles/widgets/orderer.less +0 -98
  229. package/src/styles/widgets/passage.less +0 -154
  230. package/src/styles/widgets/plotter.less +0 -31
  231. package/src/styles/widgets/radio.less +0 -58
  232. package/src/styles/widgets/reaction-diagram.less +0 -35
  233. package/src/styles/widgets/sequence.less +0 -5
  234. package/src/styles/widgets/sortable.less +0 -113
  235. package/src/styles/widgets/table.less +0 -57
  236. package/src/styles/widgets/unit.less +0 -15
  237. package/src/tex-wrangler.ts +0 -182
  238. package/src/translation-linter.ts +0 -126
  239. package/src/traversal.ts +0 -138
  240. package/src/types.ts +0 -513
  241. package/src/util/a11y.ts +0 -23
  242. package/src/util/answer-types.test.ts +0 -114
  243. package/src/util/answer-types.ts +0 -876
  244. package/src/util/colors.ts +0 -93
  245. package/src/util/drawing-transform.test.ts +0 -67
  246. package/src/util/drawing-transform.ts +0 -102
  247. package/src/util/extract-perseus-data.ts +0 -539
  248. package/src/util/fix-passage-refs.ts +0 -121
  249. package/src/util/geometry.test.ts +0 -75
  250. package/src/util/geometry.ts +0 -312
  251. package/src/util/graph-bounds.ts +0 -23
  252. package/src/util/graph-utils.ts +0 -15
  253. package/src/util/graphie.test.ts +0 -1277
  254. package/src/util/graphie.ts +0 -1566
  255. package/src/util/interactive.ts +0 -4172
  256. package/src/util/interval.ts +0 -4
  257. package/src/util/katex-preprocess.ts +0 -14
  258. package/src/util/math.test.ts +0 -11
  259. package/src/util/math.ts +0 -294
  260. package/src/util/mobile-native-utils.test.ts +0 -22
  261. package/src/util/mobile-native-utils.ts +0 -12
  262. package/src/util/parse-perseus-json.test.ts +0 -10
  263. package/src/util/parse-perseus-json.ts +0 -13
  264. package/src/util/react-render.tsx +0 -27
  265. package/src/util/register-all-widgets-for-testing.ts +0 -13
  266. package/src/util/scroll-utils.ts +0 -155
  267. package/src/util/sizing-utils.ts +0 -46
  268. package/src/util/tex.ts +0 -73
  269. package/src/util/url-utils.ts +0 -34
  270. package/src/util.graphie.test.ts +0 -45
  271. package/src/util.graphie.ts +0 -59
  272. package/src/util.ts +0 -966
  273. package/src/version.ts +0 -10
  274. package/src/widget-container.tsx +0 -199
  275. package/src/widgets/__stories__/categorizer.stories.tsx +0 -14
  276. package/src/widgets/__stories__/cs-program.stories.tsx +0 -14
  277. package/src/widgets/__stories__/definition.stories.tsx +0 -114
  278. package/src/widgets/__stories__/dropdown.stories.tsx +0 -14
  279. package/src/widgets/__stories__/explanation.stories.tsx +0 -18
  280. package/src/widgets/__stories__/expression.stories.tsx +0 -145
  281. package/src/widgets/__stories__/graded-group-set.stories.tsx +0 -31
  282. package/src/widgets/__stories__/graded-group.stories.tsx +0 -31
  283. package/src/widgets/__stories__/grapher.stories.tsx +0 -46
  284. package/src/widgets/__stories__/group.stories.tsx +0 -14
  285. package/src/widgets/__stories__/iframe.stories.tsx +0 -14
  286. package/src/widgets/__stories__/image.stories.tsx +0 -85
  287. package/src/widgets/__stories__/input-number.stories.tsx +0 -101
  288. package/src/widgets/__stories__/interaction.stories.tsx +0 -14
  289. package/src/widgets/__stories__/interactive-graph.stories.tsx +0 -60
  290. package/src/widgets/__stories__/label-image.stories.tsx +0 -130
  291. package/src/widgets/__stories__/matcher.stories.tsx +0 -14
  292. package/src/widgets/__stories__/matrix.stories.tsx +0 -14
  293. package/src/widgets/__stories__/number-line.stories.tsx +0 -14
  294. package/src/widgets/__stories__/numeric-input.stories.tsx +0 -105
  295. package/src/widgets/__stories__/orderer.stories.tsx +0 -18
  296. package/src/widgets/__stories__/passage-ref.stories.tsx +0 -33
  297. package/src/widgets/__stories__/passage.stories.tsx +0 -39
  298. package/src/widgets/__stories__/plotter.stories.tsx +0 -27
  299. package/src/widgets/__stories__/radio.stories.tsx +0 -86
  300. package/src/widgets/__stories__/random-widgets.stories.tsx +0 -59
  301. package/src/widgets/__stories__/sorter.stories.tsx +0 -14
  302. package/src/widgets/__stories__/test-keypad-context-wrapper.tsx +0 -66
  303. package/src/widgets/__stories__/unit.stories.tsx +0 -28
  304. package/src/widgets/__stories__/video-transcript-link.stories.tsx +0 -23
  305. package/src/widgets/__stories__/video.stories.tsx +0 -22
  306. package/src/widgets/__testdata__/base-radio.testdata.ts +0 -21
  307. package/src/widgets/__testdata__/categorizer.testdata.ts +0 -89
  308. package/src/widgets/__testdata__/cs-program.testdata.ts +0 -27
  309. package/src/widgets/__testdata__/dropdown.testdata.ts +0 -71
  310. package/src/widgets/__testdata__/explanation.testdata.ts +0 -85
  311. package/src/widgets/__testdata__/expression.testdata.ts +0 -198
  312. package/src/widgets/__testdata__/graded-group-set.testdata.ts +0 -356
  313. package/src/widgets/__testdata__/graded-group.testdata.ts +0 -77
  314. package/src/widgets/__testdata__/grapher.testdata.ts +0 -374
  315. package/src/widgets/__testdata__/group.testdata.ts +0 -153
  316. package/src/widgets/__testdata__/iframe.testdata.ts +0 -35
  317. package/src/widgets/__testdata__/image.testdata.ts +0 -36
  318. package/src/widgets/__testdata__/input-number.testdata.ts +0 -72
  319. package/src/widgets/__testdata__/interaction.testdata.ts +0 -262
  320. package/src/widgets/__testdata__/interactive-graph-random.testdata.ts +0 -269
  321. package/src/widgets/__testdata__/interactive-graph.testdata.ts +0 -644
  322. package/src/widgets/__testdata__/label-image.testdata.ts +0 -308
  323. package/src/widgets/__testdata__/matcher.testdata.ts +0 -33
  324. package/src/widgets/__testdata__/matrix.testdata.ts +0 -28
  325. package/src/widgets/__testdata__/number-line.testdata.ts +0 -30
  326. package/src/widgets/__testdata__/numeric-input.testdata.ts +0 -265
  327. package/src/widgets/__testdata__/orderer.testdata.ts +0 -123
  328. package/src/widgets/__testdata__/passage-ref.testdata.ts +0 -101
  329. package/src/widgets/__testdata__/passage.testdata.ts +0 -95
  330. package/src/widgets/__testdata__/plotter.testdata.ts +0 -36
  331. package/src/widgets/__testdata__/radio.testdata.ts +0 -324
  332. package/src/widgets/__testdata__/randomizers.ts +0 -51
  333. package/src/widgets/__testdata__/sorter.testdata.ts +0 -19
  334. package/src/widgets/__testdata__/video.testdata.ts +0 -61
  335. package/src/widgets/__tests__/__snapshots__/categorizer.test.ts.snap +0 -940
  336. package/src/widgets/__tests__/__snapshots__/cs-program.test.ts.snap +0 -67
  337. package/src/widgets/__tests__/__snapshots__/definition.test.ts.snap +0 -97
  338. package/src/widgets/__tests__/__snapshots__/dropdown.test.ts.snap +0 -133
  339. package/src/widgets/__tests__/__snapshots__/explanation.test.ts.snap +0 -425
  340. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt.test.ts.snap +0 -729
  341. package/src/widgets/__tests__/__snapshots__/graded-group-set.test.ts.snap +0 -339
  342. package/src/widgets/__tests__/__snapshots__/graded-group.test.ts.snap +0 -801
  343. package/src/widgets/__tests__/__snapshots__/grapher.test.ts.snap +0 -2673
  344. package/src/widgets/__tests__/__snapshots__/group.test.tsx.snap +0 -1211
  345. package/src/widgets/__tests__/__snapshots__/iframe.test.ts.snap +0 -61
  346. package/src/widgets/__tests__/__snapshots__/image.test.ts.snap +0 -378
  347. package/src/widgets/__tests__/__snapshots__/input-number.test.ts.snap +0 -495
  348. package/src/widgets/__tests__/__snapshots__/interaction.test.ts.snap +0 -292
  349. package/src/widgets/__tests__/__snapshots__/interactive-graph.test.ts.snap +0 -2889
  350. package/src/widgets/__tests__/__snapshots__/matcher.test.tsx.snap +0 -883
  351. package/src/widgets/__tests__/__snapshots__/matrix.test.ts.snap +0 -514
  352. package/src/widgets/__tests__/__snapshots__/number-line.test.ts.snap +0 -814
  353. package/src/widgets/__tests__/__snapshots__/numeric-input.test.ts.snap +0 -470
  354. package/src/widgets/__tests__/__snapshots__/orderer.test.ts.snap +0 -243
  355. package/src/widgets/__tests__/__snapshots__/passage-ref.test.ts.snap +0 -434
  356. package/src/widgets/__tests__/__snapshots__/passage.test.tsx.snap +0 -1956
  357. package/src/widgets/__tests__/__snapshots__/plotter.test.tsx.snap +0 -827
  358. package/src/widgets/__tests__/__snapshots__/radio.test.ts.snap +0 -4237
  359. package/src/widgets/__tests__/__snapshots__/unit.test.tsx.snap +0 -20
  360. package/src/widgets/__tests__/__snapshots__/video.test.ts.snap +0 -153
  361. package/src/widgets/__tests__/categorizer.test.ts +0 -203
  362. package/src/widgets/__tests__/cs-program.test.ts +0 -43
  363. package/src/widgets/__tests__/definition.test.ts +0 -136
  364. package/src/widgets/__tests__/dropdown.test.ts +0 -105
  365. package/src/widgets/__tests__/explanation.test.ts +0 -198
  366. package/src/widgets/__tests__/expression-mobile.test.tsx +0 -363
  367. package/src/widgets/__tests__/expression.test.tsx +0 -484
  368. package/src/widgets/__tests__/graded-group-set-jipt.test.ts +0 -30
  369. package/src/widgets/__tests__/graded-group-set.test.ts +0 -288
  370. package/src/widgets/__tests__/graded-group.test.ts +0 -232
  371. package/src/widgets/__tests__/grapher.cypress.ts +0 -576
  372. package/src/widgets/__tests__/grapher.test.ts +0 -33
  373. package/src/widgets/__tests__/group.test.tsx +0 -510
  374. package/src/widgets/__tests__/iframe.test.ts +0 -45
  375. package/src/widgets/__tests__/image.test.ts +0 -62
  376. package/src/widgets/__tests__/input-number.test.ts +0 -354
  377. package/src/widgets/__tests__/interaction.test.ts +0 -31
  378. package/src/widgets/__tests__/interactive-graph.cypress.ts +0 -815
  379. package/src/widgets/__tests__/interactive-graph.test.ts +0 -106
  380. package/src/widgets/__tests__/matcher.test.tsx +0 -176
  381. package/src/widgets/__tests__/matrix.test.ts +0 -82
  382. package/src/widgets/__tests__/number-line.test.ts +0 -79
  383. package/src/widgets/__tests__/numeric-input.test.ts +0 -575
  384. package/src/widgets/__tests__/orderer.test.ts +0 -73
  385. package/src/widgets/__tests__/passage-ref.test.ts +0 -168
  386. package/src/widgets/__tests__/passage.test.tsx +0 -224
  387. package/src/widgets/__tests__/plotter.test.tsx +0 -69
  388. package/src/widgets/__tests__/radio/base-radio.test.tsx +0 -470
  389. package/src/widgets/__tests__/radio/choice-icon.test.tsx +0 -90
  390. package/src/widgets/__tests__/radio/choice.test.tsx +0 -310
  391. package/src/widgets/__tests__/radio/focus-ring.test.tsx +0 -22
  392. package/src/widgets/__tests__/radio/option-status.test.tsx +0 -77
  393. package/src/widgets/__tests__/radio.test.ts +0 -807
  394. package/src/widgets/__tests__/randomizers.test.ts +0 -53
  395. package/src/widgets/__tests__/renderQuestion.tsx +0 -101
  396. package/src/widgets/__tests__/unit.test.tsx +0 -168
  397. package/src/widgets/__tests__/video.test.ts +0 -69
  398. package/src/widgets/categorizer.tsx +0 -344
  399. package/src/widgets/cs-program.tsx +0 -227
  400. package/src/widgets/definition.tsx +0 -121
  401. package/src/widgets/deprecated-standin/__stories__/deprecated-standin.stories.tsx +0 -30
  402. package/src/widgets/deprecated-standin/__tests__/__snapshots__/deprecated-standin.test.ts.snap +0 -70
  403. package/src/widgets/deprecated-standin/__tests__/deprecated-standin.test.ts +0 -93
  404. package/src/widgets/deprecated-standin/index.tsx +0 -58
  405. package/src/widgets/dropdown.tsx +0 -142
  406. package/src/widgets/explanation.tsx +0 -317
  407. package/src/widgets/expression.tsx +0 -707
  408. package/src/widgets/graded-group-answer-bar.tsx +0 -142
  409. package/src/widgets/graded-group-set.tsx +0 -338
  410. package/src/widgets/graded-group.tsx +0 -471
  411. package/src/widgets/grapher/util.tsx +0 -799
  412. package/src/widgets/grapher.tsx +0 -660
  413. package/src/widgets/group.tsx +0 -195
  414. package/src/widgets/iframe.tsx +0 -195
  415. package/src/widgets/image.tsx +0 -312
  416. package/src/widgets/input-number.tsx +0 -412
  417. package/src/widgets/interaction/arrow-picker.tsx +0 -38
  418. package/src/widgets/interaction/color-picker.tsx +0 -69
  419. package/src/widgets/interaction/dash-picker.tsx +0 -45
  420. package/src/widgets/interaction/element-container.tsx +0 -100
  421. package/src/widgets/interaction.tsx +0 -826
  422. package/src/widgets/interactive-graph.tsx +0 -2597
  423. package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +0 -91
  424. package/src/widgets/label-image/__stories__/answer-pill.stories.tsx +0 -62
  425. package/src/widgets/label-image/__stories__/marker.stories.tsx +0 -171
  426. package/src/widgets/label-image/__tests__/answer-pill.test.tsx +0 -75
  427. package/src/widgets/label-image/__tests__/hide-answers-toggle.test.tsx +0 -39
  428. package/src/widgets/label-image/answer-choices.tsx +0 -88
  429. package/src/widgets/label-image/answer-pill.tsx +0 -103
  430. package/src/widgets/label-image/hide-answers-toggle.tsx +0 -40
  431. package/src/widgets/label-image/marker.tsx +0 -268
  432. package/src/widgets/label-image/strings.ts +0 -5
  433. package/src/widgets/label-image/types.ts +0 -27
  434. package/src/widgets/label-image.test.ts +0 -928
  435. package/src/widgets/label-image.tsx +0 -819
  436. package/src/widgets/lights-puzzle.tsx +0 -359
  437. package/src/widgets/matcher.tsx +0 -298
  438. package/src/widgets/matrix.tsx +0 -634
  439. package/src/widgets/measurer.tsx +0 -222
  440. package/src/widgets/molecule/__tests__/layout.test.ts +0 -162
  441. package/src/widgets/molecule/__tests__/parser.test.ts +0 -155
  442. package/src/widgets/molecule/molecule-drawing.ts +0 -173
  443. package/src/widgets/molecule/molecule-layout.ts +0 -362
  444. package/src/widgets/molecule/smiles-parser.ts +0 -296
  445. package/src/widgets/molecule.tsx +0 -172
  446. package/src/widgets/number-line.tsx +0 -862
  447. package/src/widgets/numeric-input.tsx +0 -576
  448. package/src/widgets/orderer.tsx +0 -786
  449. package/src/widgets/passage/__tests__/passage-markdown.test.ts +0 -376
  450. package/src/widgets/passage/passage-markdown.tsx +0 -475
  451. package/src/widgets/passage-ref-target.tsx +0 -76
  452. package/src/widgets/passage-ref.tsx +0 -213
  453. package/src/widgets/passage.tsx +0 -582
  454. package/src/widgets/plotter.tsx +0 -1194
  455. package/src/widgets/radio/__stories__/base-radio.stories.tsx +0 -196
  456. package/src/widgets/radio/__stories__/choice-icon.stories.tsx +0 -166
  457. package/src/widgets/radio/__stories__/choice-none-above.stories.tsx +0 -40
  458. package/src/widgets/radio/__stories__/choice.stories.tsx +0 -137
  459. package/src/widgets/radio/__stories__/focus-ring.stories.tsx +0 -43
  460. package/src/widgets/radio/__stories__/option-status.stories.tsx +0 -103
  461. package/src/widgets/radio/base-radio.tsx +0 -511
  462. package/src/widgets/radio/choice-a11y-text.ts +0 -61
  463. package/src/widgets/radio/choice-icon/choice-icon.tsx +0 -218
  464. package/src/widgets/radio/choice-icon/cross-out-line.tsx +0 -51
  465. package/src/widgets/radio/choice-icon/shared-styles.ts +0 -15
  466. package/src/widgets/radio/choice-none-above.tsx +0 -56
  467. package/src/widgets/radio/choice.jsx.fixture.ts +0 -45
  468. package/src/widgets/radio/choice.tsx +0 -359
  469. package/src/widgets/radio/focus-ring.tsx +0 -57
  470. package/src/widgets/radio/option-status.tsx +0 -98
  471. package/src/widgets/radio/util.test.ts +0 -18
  472. package/src/widgets/radio/util.ts +0 -31
  473. package/src/widgets/radio/widget.tsx +0 -520
  474. package/src/widgets/radio.ts +0 -157
  475. package/src/widgets/reaction-diagram.tsx +0 -144
  476. package/src/widgets/sequence.tsx +0 -142
  477. package/src/widgets/simulator.tsx +0 -829
  478. package/src/widgets/sorter.tsx +0 -155
  479. package/src/widgets/table.tsx +0 -393
  480. package/src/widgets/unit.tsx +0 -374
  481. package/src/widgets/video-transcript-link.test.tsx +0 -213
  482. package/src/widgets/video-transcript-link.tsx +0 -84
  483. package/src/widgets/video.tsx +0 -135
  484. package/src/widgets.ts +0 -489
  485. package/src/zoom.ts +0 -555
  486. package/tsconfig-build.json +0 -26
  487. package/tsconfig-build.tsbuildinfo +0 -1
@@ -1,876 +0,0 @@
1
- /* eslint-disable no-useless-escape */
2
- import * as KAS from "@khanacademy/kas";
3
- import * as i18n from "@khanacademy/wonder-blocks-i18n";
4
- import $ from "jquery";
5
- import _ from "underscore";
6
-
7
- import {Errors} from "../logging/log";
8
- import {PerseusError} from "../perseus-error";
9
-
10
- import KhanMath from "./math";
11
-
12
- const MAXERROR_EPSILON = Math.pow(2, -42);
13
-
14
- type Guess = any;
15
- type Predicate = any;
16
-
17
- // TOOD(kevinb): Figure out how this relates to KEScore in
18
- // perseus-all-package/types.js and see if there's a way to
19
- // unify these types.
20
- type Score = {
21
- empty: boolean;
22
- correct: boolean;
23
- message: string | null | undefined;
24
- suppressAlmostThere?: boolean | null | undefined;
25
- guess: Guess;
26
- // It would be nice if we could ungraded required
27
- ungraded?: boolean;
28
- };
29
-
30
- export const errors = {
31
- APPROXIMATED_PI_ERROR: i18n._(
32
- "Your answer is close, but you may " +
33
- "have approximated pi. Enter your " +
34
- "answer as a multiple of pi, like " +
35
- "<code>12\\ \\text{pi}</code> or " +
36
- "<code>2/3\\ \\text{pi}</code>",
37
- ) as string,
38
- EXTRA_SYMBOLS_ERROR: i18n._(
39
- "We could not understand your " +
40
- "answer. Please check your answer for extra " +
41
- "text or symbols.",
42
- ) as string,
43
- NEEDS_TO_BE_SIMPLFIED_ERROR: i18n._(
44
- "Your answer is almost correct, " + "but it needs to be simplified.",
45
- ) as string,
46
- MISSING_PERCENT_ERROR: i18n._(
47
- "Your answer is almost correct, " +
48
- "but it is missing a " +
49
- "<code>\\%</code> at the end.",
50
- ) as string,
51
- MULTIPLICATION_SIGN_ERROR: i18n._(
52
- "I'm a computer. I only understand " +
53
- "multiplication if you use an asterisk " +
54
- "(*) as the multiplication sign.",
55
- ) as string,
56
- WRONG_CASE_ERROR: i18n._(
57
- "Your answer includes use of a variable with the wrong case.",
58
- ) as string,
59
- WRONG_LETTER_ERROR: i18n._(
60
- "Your answer includes a wrong variable letter.",
61
- ) as string,
62
- } as const;
63
-
64
- /*
65
- * Answer types
66
- *
67
- * Utility for creating answerable questions displayed in exercises
68
- *
69
- * Different answer types produce different kinds of input displays, and do
70
- * different kinds of checking on the solutions.
71
- *
72
- * Each of the objects contain two functions, setup and createValidator.
73
- *
74
- * The setup function takes a solutionarea and solution, and performs setup
75
- * within the solutionarea, and then returns an object which contains:
76
- *
77
- * answer: a function which, when called, will retrieve the current answer from
78
- * the solutionarea, which can then be validated using the validator
79
- * function
80
- * validator: a function returned from the createValidator function (defined
81
- * below)
82
- * solution: the correct answer to the problem
83
- * showGuess: a function which, when given a guess, shows the guess within the
84
- * provided solutionarea
85
- * showGuessCustom: a function which displays parts of a guess that are not
86
- * within the solutionarea; currently only used for custom
87
- * answers
88
- *
89
- * The createValidator function only takes a solution, and it returns a
90
- * function which can be used to validate an answer.
91
- *
92
- * The resulting validator function returns:
93
- * - true: if the answer is fully correct
94
- * - false: if the answer is incorrect
95
- * - "" (the empty string): if no answer has been provided (e.g. the answer box
96
- * is left unfilled)
97
- * - a string: if there is some slight error
98
- *
99
- * In most cases, setup and createValidator don't really need the solution DOM
100
- * element so we have setupFunctional and createValidatorFunctional for them
101
- * which take only $solution.text() and $solution.data(). This makes it easier
102
- * to reuse specific answer types.
103
- *
104
- * TODO(alpert): Think of a less-absurd name for createValidatorFunctional.
105
- *
106
- */
107
-
108
- const KhanAnswerTypes = {
109
- /*
110
- * predicate answer type
111
- *
112
- * performs simple predicate-based checking of a numeric solution, with
113
- * different kinds of number formats
114
- *
115
- * Uses the data-forms option on the solution to choose which number formats
116
- * are acceptable. Available data-forms:
117
- *
118
- * - integer: 3
119
- * - proper: 3/5
120
- * - improper: 5/3
121
- * - pi: 3 pi
122
- * - log: log(5)
123
- * - percent: 15%
124
- * - mixed: 1 1/3
125
- * - decimal: 1.7
126
- *
127
- * The solution should be a predicate of the form:
128
- *
129
- * function(guess, maxError) {
130
- * return abs(guess - 3) < maxError;
131
- * }
132
- *
133
- */
134
- predicate: {
135
- defaultForms: "integer, proper, improper, mixed, decimal",
136
- createValidatorFunctional: function (
137
- predicate: Predicate,
138
- options: any,
139
- ): (arg1: Guess) => Score {
140
- // Extract the options from the given solution object
141
- options = _.extend(
142
- {
143
- simplify: "required",
144
- ratio: false,
145
- forms: KhanAnswerTypes.predicate.defaultForms,
146
- },
147
- options,
148
- );
149
- let acceptableForms;
150
- // this is maintaining backwards compatibility
151
- // TODO(merlob) fix all places that depend on this, then delete
152
- if (!_.isArray(options.forms)) {
153
- acceptableForms = options.forms.split(/\s*,\s*/);
154
- } else {
155
- acceptableForms = options.forms;
156
- }
157
-
158
- // TODO(jack): remove options.inexact in favor of options.maxError
159
- if (options.inexact === undefined) {
160
- // If we aren't allowing inexact, ensure that we don't have a
161
- // large maxError as well.
162
- options.maxError = 0;
163
- }
164
- // Allow a small tolerance on maxError, to avoid numerical
165
- // representation issues (2.3 should be correct for a solution of
166
- // 2.45 with maxError=0.15).
167
- options.maxError = +options.maxError + MAXERROR_EPSILON;
168
-
169
- // If percent is an acceptable form, make sure it's the last one
170
- // in the list so we don't prematurely complain about not having
171
- // a percent sign when the user entered the correct answer in a
172
- // different form (such as a decimal or fraction)
173
- if (_.contains(acceptableForms, "percent")) {
174
- acceptableForms = _.without(acceptableForms, "percent");
175
- acceptableForms.push("percent");
176
- }
177
-
178
- // Take text looking like a fraction, and turn it into a number
179
- const fractionTransformer = function (text) {
180
- text = text
181
- // Replace unicode minus sign with hyphen
182
- .replace(/\u2212/, "-")
183
- // Remove space after +, -
184
- .replace(/([+-])\s+/g, "$1")
185
- // Remove leading/trailing whitespace
186
- .replace(/(^\s*)|(\s*$)/gi, "");
187
-
188
- // Extract numerator and denominator
189
- const match = text.match(/^([+-]?\d+)\s*\/\s*([+-]?\d+)$/);
190
- // Fractions are represented as "-\frac{numerator}{denominator}"
191
- // in Mobile device input instead of "numerator/denominator" as
192
- // in web-browser.
193
- const mobileDeviceMatch = text.match(
194
- /^([+-]?)\\frac\{([+-]?\d+)\}\{([+-]?\d+)\}$/,
195
- );
196
- const parsedInt = parseInt(text, 10);
197
- if (match || mobileDeviceMatch) {
198
- let num;
199
- let denom;
200
- let simplified = true;
201
- if (match) {
202
- num = parseFloat(match[1]);
203
- denom = parseFloat(match[2]);
204
- } else {
205
- num = parseFloat(mobileDeviceMatch[2]);
206
- if (mobileDeviceMatch[1] === "-") {
207
- if (num < 0) {
208
- simplified = false;
209
- }
210
- num = -num;
211
- }
212
- denom = parseFloat(mobileDeviceMatch[3]);
213
- }
214
-
215
- simplified =
216
- simplified &&
217
- denom > 0 &&
218
- (options.ratio || denom !== 1) &&
219
- KhanMath.getGCD(num, denom) === 1;
220
- return [
221
- {
222
- value: num / denom,
223
- exact: simplified,
224
- },
225
- ];
226
- }
227
- if (!isNaN(parsedInt) && "" + parsedInt === text) {
228
- return [
229
- {
230
- value: parsedInt,
231
- exact: true,
232
- },
233
- ];
234
- }
235
-
236
- return [];
237
- };
238
-
239
- /*
240
- * Different forms of numbers
241
- *
242
- * Each function returns a list of objects of the form:
243
- *
244
- * {
245
- * value: numerical value,
246
- * exact: true/false
247
- * }
248
- */
249
- const forms = {
250
- // integer, which is encompassed by decimal
251
- integer: function (text) {
252
- // Compare the decimal form to the decimal form rounded to
253
- // an integer. Only accept if the user actually entered an
254
- // integer.
255
- const decimal = forms.decimal(text);
256
- const rounded = forms.decimal(text, 1);
257
- if (
258
- (decimal[0].value != null &&
259
- decimal[0].value === rounded[0].value) ||
260
- (decimal[1].value != null &&
261
- decimal[1].value === rounded[1].value)
262
- ) {
263
- return decimal;
264
- }
265
- return [];
266
- },
267
-
268
- // A proper fraction
269
- proper: function (text) {
270
- return $.map(fractionTransformer(text), function (o) {
271
- // All fractions that are less than 1
272
- if (Math.abs(o.value) < 1) {
273
- return [o];
274
- }
275
- return [];
276
- });
277
- },
278
-
279
- // an improper fraction
280
- improper: function (text) {
281
- return $.map(fractionTransformer(text), function (o) {
282
- // All fractions that are greater than 1
283
- if (Math.abs(o.value) >= 1) {
284
- return [o];
285
- }
286
- return [];
287
- });
288
- },
289
-
290
- // pi-like numbers
291
- pi: function (text) {
292
- let match;
293
- let possibilities: any[] = [];
294
-
295
- // Replace unicode minus sign with hyphen
296
- text = text.replace(/\u2212/, "-");
297
-
298
- // - pi
299
- // (Note: we also support \pi (for TeX), p, tau (and \tau,
300
- // and t), pau.)
301
- if (
302
- (match = text.match(
303
- /^([+-]?)\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)$/i,
304
- ))
305
- ) {
306
- possibilities = [
307
- {
308
- value: parseFloat(match[1] + "1"),
309
- exact: true,
310
- },
311
- ];
312
-
313
- // 5 / 6 pi
314
- } else if (
315
- (match = text.match(
316
- /^([+-]?\s*\d+\s*(?:\/\s*[+-]?\s*\d+)?)\s*\*?\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)$/i,
317
- ))
318
- ) {
319
- possibilities = fractionTransformer(match[1]);
320
-
321
- // 4 5 / 6 pi
322
- } else if (
323
- (match = text.match(
324
- /^([+-]?)\s*(\d+)\s*([+-]?\d+)\s*\/\s*([+-]?\d+)\s*\*?\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)$/i,
325
- ))
326
- ) {
327
- const sign = parseFloat(match[1] + "1");
328
- const integ = parseFloat(match[2]);
329
- const num = parseFloat(match[3]);
330
- const denom = parseFloat(match[4]);
331
- const simplified =
332
- num < denom && KhanMath.getGCD(num, denom) === 1;
333
-
334
- possibilities = [
335
- {
336
- value: sign * (integ + num / denom),
337
- exact: simplified,
338
- },
339
- ];
340
-
341
- // 5 pi / 6
342
- } else if (
343
- (match = text.match(
344
- /^([+-]?\s*\d+)\s*\*?\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)\s*(?:\/\s*([+-]?\s*\d+))?$/i,
345
- ))
346
- ) {
347
- possibilities = fractionTransformer(
348
- match[1] + "/" + match[3],
349
- );
350
-
351
- // - pi / 4
352
- } else if (
353
- (match = text.match(
354
- /^([+-]?)\s*\*?\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)\s*(?:\/\s*([+-]?\d+))?$/i,
355
- ))
356
- ) {
357
- possibilities = fractionTransformer(
358
- match[1] + "1/" + match[3],
359
- );
360
-
361
- // 0
362
- } else if (text === "0") {
363
- possibilities = [{value: 0, exact: true}];
364
-
365
- // 0.5 pi (fallback)
366
- } else if (
367
- (match = text.match(
368
- /^(.+)\s*\*?\s*(\\?pi|p|\u03c0|\\?tau|t|\u03c4|pau)$/i,
369
- ))
370
- ) {
371
- possibilities = forms.decimal(match[1]);
372
- } else {
373
- possibilities = _.reduce(
374
- KhanAnswerTypes.predicate.defaultForms.split(
375
- /\s*,\s*/,
376
- ),
377
- function (memo, form) {
378
- return memo.concat(forms[form](text));
379
- },
380
- [],
381
- );
382
-
383
- // If the answer is a floating point number that's
384
- // near a multiple of pi, mark is as being possibly
385
- // an approximation of pi. We actually check if
386
- // it's a plausible approximation of pi/12, since
387
- // sometimes the correct answer is like pi/3 or pi/4.
388
- // We also say it's a pi-approximation if it involves
389
- // x/7 (since 22/7 is an approximation of pi.)
390
- // Never mark an integer as being an approximation
391
- // of pi.
392
- let approximatesPi = false;
393
- const number = parseFloat(text);
394
- if (!isNaN(number) && number !== parseInt(text)) {
395
- const piMult = Math.PI / 12;
396
- const roundedNumber =
397
- piMult * Math.round(number / piMult);
398
- if (Math.abs(number - roundedNumber) < 0.01) {
399
- approximatesPi = true;
400
- }
401
- } else if (text.match(/\/\s*7/)) {
402
- approximatesPi = true;
403
- }
404
- if (approximatesPi) {
405
- _.each(possibilities, function (possibility) {
406
- possibility.piApprox = true;
407
- });
408
- }
409
- return possibilities;
410
- }
411
-
412
- let multiplier = Math.PI;
413
- if (text.match(/\\?tau|t|\u03c4/)) {
414
- multiplier = Math.PI * 2;
415
- }
416
-
417
- // We're taking an early stand along side xkcd in the
418
- // inevitable ti vs. pau debate... http://xkcd.com/1292
419
- if (text.match(/pau/)) {
420
- multiplier = Math.PI * 1.5;
421
- }
422
-
423
- $.each(possibilities, function (ix, possibility) {
424
- possibility.value *= multiplier;
425
- });
426
- return possibilities;
427
- },
428
-
429
- // Converts '' to 1 and '-' to -1 so you can write "[___] x"
430
- // and accept sane things
431
- coefficient: function (text) {
432
- let possibilities:
433
- | Array<never>
434
- | Array<{
435
- exact: boolean;
436
- value: number;
437
- }> = [];
438
-
439
- // Replace unicode minus sign with hyphen
440
- text = text.replace(/\u2212/, "-");
441
-
442
- if (text === "") {
443
- possibilities = [{value: 1, exact: true}];
444
- } else if (text === "-") {
445
- possibilities = [{value: -1, exact: true}];
446
- }
447
- return possibilities;
448
- },
449
-
450
- // simple log(c) form
451
- log: function (text) {
452
- let match;
453
- let possibilities = [];
454
-
455
- // Replace unicode minus sign with hyphen
456
- text = text.replace(/\u2212/, "-");
457
- text = text.replace(/[ \(\)]/g, "");
458
-
459
- if ((match = text.match(/^log\s*(\S+)\s*$/i))) {
460
- // @ts-expect-error - TS2322 - Type '{ value: number | undefined; exact: boolean; }[]' is not assignable to type 'never[]'.
461
- possibilities = forms.decimal(match[1]);
462
- } else if (text === "0") {
463
- // @ts-expect-error - TS2322 - Type 'number' is not assignable to type 'never'. | TS2322 - Type 'boolean' is not assignable to type 'never'.
464
- possibilities = [{value: 0, exact: true}];
465
- }
466
- return possibilities;
467
- },
468
-
469
- // Numbers with percent signs
470
- percent: function (text) {
471
- text = $.trim(text);
472
- // store whether or not there is a percent sign
473
- let hasPercentSign = false;
474
-
475
- if (text.indexOf("%") === text.length - 1) {
476
- text = $.trim(text.substring(0, text.length - 1));
477
- hasPercentSign = true;
478
- }
479
-
480
- const transformed = forms.decimal(text);
481
- $.each(transformed, function (ix, t) {
482
- t.exact = hasPercentSign;
483
- // @ts-expect-error - TS2532 - Object is possibly 'undefined'.
484
- t.value = t.value / 100;
485
- });
486
- return transformed;
487
- },
488
-
489
- // Mixed numbers, like 1 3/4
490
- mixed: function (text) {
491
- const match = text
492
- // Replace unicode minus sign with hyphen
493
- .replace(/\u2212/, "-")
494
- // Remove space after +, -
495
- .replace(/([+-])\s+/g, "$1")
496
- // Extract integer, numerator and denominator
497
- .match(/^([+-]?)(\d+)\s+(\d+)\s*\/\s*(\d+)$/);
498
-
499
- if (match) {
500
- const sign = parseFloat(match[1] + "1");
501
- const integ = parseFloat(match[2]);
502
- const num = parseFloat(match[3]);
503
- const denom = parseFloat(match[4]);
504
- const simplified =
505
- num < denom && KhanMath.getGCD(num, denom) === 1;
506
-
507
- return [
508
- {
509
- value: sign * (integ + num / denom),
510
- exact: simplified,
511
- },
512
- ];
513
- }
514
-
515
- return [];
516
- },
517
-
518
- // Decimal numbers -- compare entered text rounded to
519
- // 'precision' Reciprical of the precision against the correct
520
- // answer. We round to 1/1e10 by default, which is healthily
521
- // less than machine epsilon but should be more than any real
522
- // decimal answer would use. (The 'integer' answer type uses
523
- // precision == 1.)
524
- decimal: function (text: string, precision = 1e10) {
525
- const normal = function (text) {
526
- text = $.trim(text);
527
-
528
- const match = text
529
- // Replace unicode minus sign with hyphen
530
- .replace(/\u2212/, "-")
531
- // Remove space after +, -
532
- .replace(/([+-])\s+/g, "$1")
533
- // Extract integer, numerator and denominator. If
534
- // commas or spaces are used, they must be in the
535
- // "correct" places
536
- .match(
537
- /^([+-]?(?:\d{1,3}(?:[, ]?\d{3})*\.?|\d{0,3}(?:[, ]?\d{3})*\.(?:\d{3}[, ]?)*\d{1,3}))$/,
538
- );
539
-
540
- // You can't start a number with `0,`, to prevent us
541
- // interpeting '0.342' as correct for '342'
542
- const badLeadingZero = text.match(/^0[0,]*,/);
543
-
544
- if (match && !badLeadingZero) {
545
- let x = parseFloat(match[1].replace(/[, ]/g, ""));
546
-
547
- if (options.inexact === undefined) {
548
- x = Math.round(x * precision) / precision;
549
- }
550
-
551
- return x;
552
- }
553
- };
554
-
555
- const commas = function (text: string) {
556
- text = text.replace(/([\.,])/g, function (_, c) {
557
- return c === "." ? "," : ".";
558
- });
559
- return normal(text);
560
- };
561
-
562
- return [
563
- {value: normal(text), exact: true},
564
- {value: commas(text), exact: true},
565
- ];
566
- },
567
- } as const;
568
-
569
- // validator function
570
- return function (guess: Guess): Score {
571
- // The fallback variable is used in place of the answer, if no
572
- // answer is provided (i.e. the field is left blank)
573
- const fallback =
574
- options.fallback != null ? "" + options.fallback : "";
575
-
576
- guess = $.trim(guess) || fallback;
577
-
578
- const score: Score = {
579
- empty: guess === "",
580
- correct: false,
581
- message: null as string | null | undefined,
582
- guess: guess,
583
- };
584
-
585
- // iterate over all the acceptable forms, and if one of the
586
- // answers is correct, return true
587
- $.each(acceptableForms, function (i, form) {
588
- const transformed = forms[form](guess);
589
- for (let j = 0, l = transformed.length; j < l; j++) {
590
- const val = transformed[j].value;
591
- const exact = transformed[j].exact;
592
- const piApprox = transformed[j].piApprox;
593
- // If a string was returned, and it exactly matches,
594
- // return true
595
- if (predicate(val, options.maxError)) {
596
- // If the exact correct number was returned,
597
- // return true
598
- if (exact || options.simplify === "optional") {
599
- score.correct = true;
600
- score.message = options.message || null;
601
- // If the answer is correct, don't say it's
602
- // empty. This happens, for example, with the
603
- // coefficient type where guess === "" but is
604
- // interpreted as "1" which is correct.
605
- score.empty = false;
606
- } else if (form === "percent") {
607
- // Otherwise, an error was returned
608
- score.empty = true;
609
- score.message = errors.MISSING_PERCENT_ERROR;
610
- } else {
611
- if (options.simplify !== "enforced") {
612
- score.empty = true;
613
- }
614
- score.message =
615
- errors.NEEDS_TO_BE_SIMPLFIED_ERROR;
616
- }
617
- // The return false below stops the looping of the
618
- // callback since predicate check succeeded.
619
- // No more forms to look to verify the user guess.
620
- return false;
621
- }
622
- if (piApprox && predicate(val, Math.abs(val * 0.001))) {
623
- score.empty = true;
624
- score.message = errors.APPROXIMATED_PI_ERROR;
625
- }
626
- }
627
- });
628
-
629
- if (score.correct === false) {
630
- let interpretedGuess = false;
631
- _.each(forms, function (form) {
632
- const anyAreNaN = _.any(form(guess), function (t) {
633
- return t.value != null && !_.isNaN(t.value);
634
- });
635
-
636
- if (anyAreNaN) {
637
- interpretedGuess = true;
638
- }
639
- });
640
- if (!interpretedGuess) {
641
- score.empty = true;
642
- score.message = errors.EXTRA_SYMBOLS_ERROR;
643
- return score;
644
- }
645
- }
646
-
647
- return score;
648
- };
649
- },
650
- },
651
-
652
- /*
653
- * number answer type
654
- *
655
- * wraps the predicate answer type to performs simple number-based checking
656
- * of a solution
657
- */
658
- number: {
659
- convertToPredicate: function (
660
- correctAnswer: string,
661
- options: any,
662
- ): Predicate {
663
- const correctFloat = parseFloat(correctAnswer);
664
-
665
- return [
666
- function (guess: Predicate, maxError: Predicate) {
667
- return Math.abs(guess - correctFloat) < maxError;
668
- },
669
- $.extend({}, options, {type: "predicate"}),
670
- ];
671
- },
672
- createValidatorFunctional: function (
673
- correctAnswer: string,
674
- options: any,
675
- ): (arg1: Guess) => Score {
676
- return KhanAnswerTypes.predicate.createValidatorFunctional(
677
- // @ts-expect-error - TS2556 - A spread argument must either have a tuple type or be passed to a rest parameter.
678
- ...KhanAnswerTypes.number.convertToPredicate(
679
- correctAnswer,
680
- options,
681
- ),
682
- );
683
- },
684
- },
685
-
686
- /*
687
- * The expression answer type parses a given expression or equation
688
- * and semantically compares it to the solution. In addition, instant
689
- * feedback is provided by rendering the last answer that fully parsed.
690
- *
691
- * Parsing options:
692
- * functions (e.g. data-functions="f g h")
693
- * A space or comma separated list of single-letter variables that
694
- * should be interpreted as functions. Case sensitive. "e" and "i"
695
- * are reserved.
696
- *
697
- * no functions specified: f(x+y) == fx + fy
698
- * with "f" as a function: f(x+y) != fx + fy
699
- *
700
- * Comparison options:
701
- * same-form (e.g. data-same-form)
702
- * If present, the answer must match the solution's structure in
703
- * addition to evaluating the same. Commutativity and excess negation
704
- * are ignored, but all other changes will trigger a rejection. Useful
705
- * for requiring a particular form of an equation, or if the answer
706
- * must be factored.
707
- *
708
- * example question: Factor x^2 + x - 2
709
- * example solution: (x-1)(x+2)
710
- * accepted answers: (x-1)(x+2), (x+2)(x-1), ---(-x-2)(-1+x), etc.
711
- * rejected answers: x^2+x-2, x*x+x-2, x(x+1)-2, (x-1)(x+2)^1, etc.
712
- * rejection message: Your answer is not in the correct form
713
- *
714
- * simplify (e.g. data-simplify)
715
- * If present, the answer must be fully expanded and simplified. Use
716
- * carefully - simplification is hard and there may be bugs, or you
717
- * might not agree on the definition of "simplified" used. You will
718
- * get an error if the provided solution is not itself fully expanded
719
- * and simplified.
720
- *
721
- * example question: Simplify ((n*x^5)^5) / (n^(-2)*x^2)^-3
722
- * example solution: x^31 / n
723
- * accepted answers: x^31 / n, x^31 / n^1, x^31 * n^(-1), etc.
724
- * rejected answers: (x^25 * n^5) / (x^(-6) * n^6), etc.
725
- * rejection message: Your answer is not fully expanded and simplified
726
- *
727
- * Rendering options:
728
- * times (e.g. data-times)
729
- * If present, explicit multiplication (such as between numbers) will
730
- * be rendered with a cross/x symbol (TeX: \times) instead of the usual
731
- * center dot (TeX: \cdot).
732
- *
733
- * normal rendering: 2 * 3^x -> 2 \cdot 3^{x}
734
- * but with "times": 2 * 3^x -> 2 \times 3^{x}
735
- */
736
- expression: {
737
- parseSolution: function (solutionString: string, options: any): any {
738
- let solution = KAS.parse(solutionString, options);
739
- if (!solution.parsed) {
740
- throw new PerseusError(
741
- "The provided solution (" +
742
- solutionString +
743
- ") didn't parse.",
744
- Errors.InvalidInput,
745
- );
746
- } else if (options.simplified && !solution.expr.isSimplified()) {
747
- throw new PerseusError(
748
- "The provided solution (" +
749
- solutionString +
750
- ") isn't fully expanded and simplified.",
751
- Errors.InvalidInput,
752
- );
753
- } else {
754
- solution = solution.expr;
755
- }
756
- return solution;
757
- },
758
-
759
- createValidatorFunctional: function (
760
- solution: any,
761
- options: any,
762
- ): (arg1: Guess) => Score {
763
- return function (guess: Guess): Score {
764
- const score = {
765
- empty: false,
766
- correct: false,
767
- message: null as string | null | undefined,
768
- guess: guess,
769
- // Setting `ungraded` to true indicates that if the
770
- // guess doesn't match any of the solutions, the guess
771
- // shouldn't be marked as incorrect; instead, `message`
772
- // should be shown to the user. This is different from
773
- // setting `empty` to true, since the behavior of `empty`
774
- // is that `message` only will be shown if the guess is
775
- // graded as empty for every solution.
776
- ungraded: false,
777
- } as const;
778
-
779
- // Don't bother parsing an empty input
780
- if (!guess) {
781
- // @ts-expect-error - TS2540 - Cannot assign to 'empty' because it is a read-only property.
782
- score.empty = true;
783
- return score;
784
- }
785
-
786
- const answer = KAS.parse(guess, options);
787
-
788
- // An unsuccessful parse doesn't count as wrong
789
- if (!answer.parsed) {
790
- // @ts-expect-error - TS2540 - Cannot assign to 'empty' because it is a read-only property.
791
- score.empty = true;
792
- return score;
793
- }
794
-
795
- // Solution will need to be parsed again if we're creating
796
- // this from a multiple question type
797
- if (typeof solution === "string") {
798
- solution = KhanAnswerTypes.expression.parseSolution(
799
- solution,
800
- options,
801
- );
802
- }
803
-
804
- const result = KAS.compare(answer.expr, solution, options);
805
-
806
- if (result.equal) {
807
- // Correct answer
808
- // @ts-expect-error - TS2540 - Cannot assign to 'correct' because it is a read-only property.
809
- score.correct = true;
810
- } else if (
811
- result.wrongVariableNames ||
812
- result.wrongVariableCase
813
- ) {
814
- // We don't want to give people an error for getting the
815
- // variable names or the variable case wrong.
816
- // TODO(aasmund): This should ideally have been handled
817
- // under the `result.message` condition, but the
818
- // KAS messages currently aren't translatable.
819
- // @ts-expect-error - TS2540 - Cannot assign to 'ungraded' because it is a read-only property.
820
- score.ungraded = true;
821
- // @ts-expect-error - TS2540 - Cannot assign to 'message' because it is a read-only property.
822
- score.message = result.wrongVariableCase
823
- ? errors.WRONG_CASE_ERROR
824
- : errors.WRONG_LETTER_ERROR;
825
- // Don't tell the use they're "almost there" in this case, that may not be true and isn't helpful.
826
- // @ts-expect-error - TS2339 - Property 'suppressAlmostThere' does not exist on type '{ readonly empty: false; readonly correct: false; readonly message: string | null | undefined; readonly guess: any; readonly ungraded: false; }'.
827
- score.suppressAlmostThere = true;
828
- } else if (result.message) {
829
- // Nearly correct answer
830
- // TODO(aasmund): This message also isn't translatable;
831
- // need to fix that in KAS
832
- // @ts-expect-error - TS2540 - Cannot assign to 'message' because it is a read-only property.
833
- score.message = result.message;
834
- } else {
835
- // Replace x with * and see if it would have been correct
836
- // TODO(aasmund): I think this branch is effectively dead,
837
- // because the replacement will only work in situations
838
- // where the variables are wrong (except if the variable
839
- // is x, in which case the replacement won't work either),
840
- // which is handled by another branch. When we implement a
841
- // more sophisticated variable check, revive this or
842
- // remove it completely if it will never come into play.
843
- const answerX = KAS.parse(
844
- guess.replace(/[xX]/g, "*"),
845
- options,
846
- );
847
- if (answerX.parsed) {
848
- const resultX = KAS.compare(
849
- answerX.expr,
850
- solution,
851
- options,
852
- );
853
- if (resultX.equal) {
854
- // @ts-expect-error - TS2540 - Cannot assign to 'ungraded' because it is a read-only property.
855
- score.ungraded = true;
856
- // @ts-expect-error - TS2540 - Cannot assign to 'message' because it is a read-only property.
857
- score.message = errors.MULTIPLICATION_SIGN_ERROR;
858
- } else if (resultX.message) {
859
- // TODO(aasmund): I18nize `score.message`
860
- // @ts-expect-error - TS2540 - Cannot assign to 'message' because it is a read-only property.
861
- score.message =
862
- resultX.message +
863
- " Also, I'm a computer. I only understand " +
864
- "multiplication if you use an " +
865
- "asterisk (*) as the multiplication " +
866
- "sign.";
867
- }
868
- }
869
- }
870
- return score;
871
- };
872
- },
873
- },
874
- } as const;
875
-
876
- export default KhanAnswerTypes;