@khanacademy/perseus 19.1.5 → 19.1.7

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 (489) hide show
  1. package/dist/components/graph.d.ts +0 -1
  2. package/dist/components/graphie.d.ts +0 -1
  3. package/dist/es/index.js +319 -212
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.js +338 -222
  6. package/dist/index.js.map +1 -1
  7. package/dist/interactive2/movable-point.d.ts +195 -1
  8. package/dist/interactive2/movable.d.ts +1 -1
  9. package/dist/interactive2/types.d.ts +4 -2
  10. package/dist/interactive2.d.ts +2 -1
  11. package/dist/server-item-renderer.d.ts +2 -2
  12. package/dist/util/graphie.d.ts +12 -2
  13. package/dist/widgets/expression.d.ts +6 -6
  14. package/package.json +11 -8
  15. package/.babelrc.js +0 -8
  16. package/.eslintrc.js +0 -12
  17. package/CHANGELOG.md +0 -1432
  18. package/src/__stories__/article-renderer.stories.tsx +0 -100
  19. package/src/__stories__/hints-renderer.stories.tsx +0 -55
  20. package/src/__stories__/server-item-renderer.stories.tsx +0 -44
  21. package/src/__testdata__/article-renderer.testdata.ts +0 -212
  22. package/src/__testdata__/graphie.testdata.ts +0 -51
  23. package/src/__testdata__/renderer.testdata.ts +0 -274
  24. package/src/__testdata__/server-item-renderer.testdata.ts +0 -171
  25. package/src/__tests__/__snapshots__/perseus-markdown.test.ts.snap +0 -507
  26. package/src/__tests__/__snapshots__/renderer.test.tsx.snap +0 -525
  27. package/src/__tests__/__snapshots__/server-item-renderer.test.tsx.snap +0 -285
  28. package/src/__tests__/a11y.test.ts +0 -303
  29. package/src/__tests__/article-renderer.test.tsx +0 -130
  30. package/src/__tests__/error-boundary.test.tsx +0 -76
  31. package/src/__tests__/extract-perseus-data.test.ts +0 -1027
  32. package/src/__tests__/init.test.ts +0 -10
  33. package/src/__tests__/jipt-paragraphs.test.ts +0 -32
  34. package/src/__tests__/mock-asset-loading-widget.tsx +0 -53
  35. package/src/__tests__/mock-widget.tsx +0 -33
  36. package/src/__tests__/perseus-markdown.test.ts +0 -764
  37. package/src/__tests__/renderability.test.ts +0 -480
  38. package/src/__tests__/renderer-api.test.tsx +0 -302
  39. package/src/__tests__/renderer.test.tsx +0 -1816
  40. package/src/__tests__/server-item-renderer.test.tsx +0 -582
  41. package/src/__tests__/test-items/image-item.ts +0 -24
  42. package/src/__tests__/test-items/input-number-1-item.ts +0 -26
  43. package/src/__tests__/test-items/input-number-2-item.ts +0 -38
  44. package/src/__tests__/test-items/table-item.ts +0 -29
  45. package/src/__tests__/tex-wrangler.test.ts +0 -82
  46. package/src/__tests__/util.test.ts +0 -40
  47. package/src/__tests__/widget-container.test.tsx +0 -126
  48. package/src/__tests__/widgets.test.ts +0 -91
  49. package/src/a11y.ts +0 -45
  50. package/src/all-widgets.ts +0 -9
  51. package/src/article-renderer.tsx +0 -237
  52. package/src/asset-context.ts +0 -30
  53. package/src/basic-widgets.ts +0 -16
  54. package/src/components/__stories__/button-group.stories.tsx +0 -55
  55. package/src/components/__stories__/fixed-to-responsive.stories.tsx +0 -141
  56. package/src/components/__stories__/graph.stories.tsx +0 -28
  57. package/src/components/__stories__/graphie.stories.tsx +0 -33
  58. package/src/components/__stories__/hud.stories.tsx +0 -35
  59. package/src/components/__stories__/icon.stories.tsx +0 -63
  60. package/src/components/__stories__/image-loader.stories.tsx +0 -63
  61. package/src/components/__stories__/info-tip.stories.tsx +0 -31
  62. package/src/components/__stories__/inline-icon.stories.tsx +0 -40
  63. package/src/components/__stories__/input-with-examples.stories.tsx +0 -53
  64. package/src/components/__stories__/lint.stories.tsx +0 -86
  65. package/src/components/__stories__/math-input.stories.tsx +0 -43
  66. package/src/components/__stories__/math-output.stories.tsx +0 -23
  67. package/src/components/__stories__/multi-button-group.stories.tsx +0 -66
  68. package/src/components/__stories__/number-input.stories.tsx +0 -41
  69. package/src/components/__stories__/prop-check-box.stories.tsx +0 -65
  70. package/src/components/__stories__/range-input.stories.tsx +0 -29
  71. package/src/components/__stories__/simple-keypad-input.stories.tsx +0 -27
  72. package/src/components/__stories__/sortable.stories.tsx +0 -77
  73. package/src/components/__stories__/stub-tag-editor.stories.tsx +0 -45
  74. package/src/components/__stories__/svg-image.stories.tsx +0 -74
  75. package/src/components/__stories__/tex.stories.tsx +0 -23
  76. package/src/components/__stories__/text-input.stories.tsx +0 -33
  77. package/src/components/__stories__/text-list-editor.stories.tsx +0 -32
  78. package/src/components/__stories__/tooltip.stories.tsx +0 -52
  79. package/src/components/__stories__/zoomable-tex.stories.tsx +0 -41
  80. package/src/components/__stories__/zoomable.stories.tsx +0 -49
  81. package/src/components/__testdata__/sorter.testdata.ts +0 -19
  82. package/src/components/__tests__/__snapshots__/sortable.test.tsx.snap +0 -163
  83. package/src/components/__tests__/__snapshots__/sorter.test.tsx.snap +0 -265
  84. package/src/components/__tests__/math-input.test.tsx +0 -147
  85. package/src/components/__tests__/number-input.test.tsx +0 -128
  86. package/src/components/__tests__/sortable.test.tsx +0 -269
  87. package/src/components/__tests__/sorter.test.tsx +0 -114
  88. package/src/components/__tests__/zoomable.test.tsx +0 -399
  89. package/src/components/button-group.tsx +0 -130
  90. package/src/components/constants.ts +0 -14
  91. package/src/components/fixed-to-responsive.tsx +0 -169
  92. package/src/components/graph.tsx +0 -444
  93. package/src/components/graphie-classes.ts +0 -153
  94. package/src/components/graphie-movables.ts +0 -338
  95. package/src/components/graphie.tsx +0 -400
  96. package/src/components/highlighting/highlightable-content.tsx +0 -240
  97. package/src/components/highlighting/highlights.ts +0 -207
  98. package/src/components/highlighting/ranges.ts +0 -304
  99. package/src/components/highlighting/types.ts +0 -73
  100. package/src/components/highlighting/ui/highlight-renderer.tsx +0 -172
  101. package/src/components/highlighting/ui/highlight-set-renderer.tsx +0 -185
  102. package/src/components/highlighting/ui/highlight-tooltip.tsx +0 -141
  103. package/src/components/highlighting/ui/highlighting-ui.tsx +0 -143
  104. package/src/components/highlighting/ui/selection-tracker.tsx +0 -186
  105. package/src/components/highlighting/ui/types.ts +0 -21
  106. package/src/components/highlighting/ui/util.ts +0 -165
  107. package/src/components/highlighting/word-indexer.tsx +0 -152
  108. package/src/components/hud.tsx +0 -167
  109. package/src/components/icon.tsx +0 -141
  110. package/src/components/image-loader.tsx +0 -177
  111. package/src/components/info-tip/info-tip.tsx +0 -144
  112. package/src/components/info-tip.tsx +0 -39
  113. package/src/components/inline-icon.tsx +0 -60
  114. package/src/components/input-with-examples.tsx +0 -249
  115. package/src/components/lint.tsx +0 -459
  116. package/src/components/math-input.tsx +0 -474
  117. package/src/components/math-output.tsx +0 -134
  118. package/src/components/multi-button-group.tsx +0 -135
  119. package/src/components/number-input.tsx +0 -249
  120. package/src/components/prop-check-box.tsx +0 -79
  121. package/src/components/range-input.tsx +0 -60
  122. package/src/components/simple-keypad-input.tsx +0 -88
  123. package/src/components/sortable.tsx +0 -958
  124. package/src/components/stub-tag-editor.tsx +0 -53
  125. package/src/components/svg-image.tsx +0 -779
  126. package/src/components/tex.tsx +0 -67
  127. package/src/components/text-input.tsx +0 -129
  128. package/src/components/text-list-editor.tsx +0 -166
  129. package/src/components/tooltip.tsx +0 -410
  130. package/src/components/visibility-observer/__stories__/visibility-observer.stories.tsx +0 -141
  131. package/src/components/visibility-observer/create-visibility-observer.ts +0 -108
  132. package/src/components/visibility-observer/get-scroll-parent.ts +0 -46
  133. package/src/components/visibility-observer/visibility-observer.tsx +0 -124
  134. package/src/components/zoomable-tex.tsx +0 -78
  135. package/src/components/zoomable.tsx +0 -304
  136. package/src/components.ts +0 -15
  137. package/src/definition-context.tsx +0 -59
  138. package/src/dependencies.ts +0 -40
  139. package/src/error-boundary.tsx +0 -70
  140. package/src/extra-widgets.ts +0 -75
  141. package/src/hint-renderer.tsx +0 -151
  142. package/src/hints-renderer.tsx +0 -372
  143. package/src/icon-paths.ts +0 -119
  144. package/src/index.ts +0 -171
  145. package/src/init.ts +0 -56
  146. package/src/interaction-tracker.ts +0 -62
  147. package/src/interactive2/__tests__/movable-mock.ts +0 -55
  148. package/src/interactive2/__tests__/movable-point.test.ts +0 -144
  149. package/src/interactive2/interactive-util.test.ts +0 -93
  150. package/src/interactive2/interactive-util.ts +0 -159
  151. package/src/interactive2/movable-helper-methods.ts +0 -166
  152. package/src/interactive2/movable-line-options.ts +0 -419
  153. package/src/interactive2/movable-line.ts +0 -307
  154. package/src/interactive2/movable-point-options.ts +0 -224
  155. package/src/interactive2/movable-point.tsx +0 -585
  156. package/src/interactive2/movable-polygon-options.ts +0 -389
  157. package/src/interactive2/movable-polygon.ts +0 -360
  158. package/src/interactive2/movable.test.ts +0 -249
  159. package/src/interactive2/movable.ts +0 -437
  160. package/src/interactive2/objective_.ts +0 -79
  161. package/src/interactive2/types.ts +0 -17
  162. package/src/interactive2/wrapped-defaults.ts +0 -87
  163. package/src/interactive2/wrapped-ellipse.ts +0 -94
  164. package/src/interactive2/wrapped-line.ts +0 -116
  165. package/src/interactive2/wrapped-path.ts +0 -51
  166. package/src/interactive2.ts +0 -70
  167. package/src/item-version.ts +0 -10
  168. package/src/jipt-paragraphs.ts +0 -49
  169. package/src/jquery.mobile.vmouse.js +0 -545
  170. package/src/loading-context.ts +0 -21
  171. package/src/logging/log.test.ts +0 -39
  172. package/src/logging/log.ts +0 -97
  173. package/src/mixins/__tests__/widget-prop-denylist.test.ts +0 -21
  174. package/src/mixins/changeable.ts +0 -133
  175. package/src/mixins/editor-jsonify.ts +0 -13
  176. package/src/mixins/widget-jsonify-deprecated.ts +0 -23
  177. package/src/mixins/widget-prop-denylist.ts +0 -48
  178. package/src/multi-items/__stories__/multi-renderer.stories.tsx +0 -83
  179. package/src/multi-items/__testdata__/multi-renderer.testdata.ts +0 -172
  180. package/src/multi-items/__tests__/__snapshots__/multi-renderer.test.tsx.snap +0 -1164
  181. package/src/multi-items/__tests__/items.test.ts +0 -240
  182. package/src/multi-items/__tests__/multi-renderer.test.tsx +0 -914
  183. package/src/multi-items/__tests__/prop-type-builders.test.ts +0 -133
  184. package/src/multi-items/__tests__/shapes.test.ts +0 -43
  185. package/src/multi-items/__tests__/trees.test.ts +0 -317
  186. package/src/multi-items/item-types.ts +0 -56
  187. package/src/multi-items/items.ts +0 -176
  188. package/src/multi-items/multi-renderer.tsx +0 -569
  189. package/src/multi-items/prop-type-builders.ts +0 -106
  190. package/src/multi-items/shape-types.ts +0 -52
  191. package/src/multi-items/shapes.ts +0 -52
  192. package/src/multi-items/tree-types.ts +0 -47
  193. package/src/multi-items/trees.ts +0 -360
  194. package/src/multi-items.ts +0 -75
  195. package/src/perseus-api.tsx +0 -188
  196. package/src/perseus-env.ts +0 -27
  197. package/src/perseus-error.ts +0 -17
  198. package/src/perseus-markdown.tsx +0 -405
  199. package/src/perseus-types.ts +0 -1366
  200. package/src/perseus-version.ts +0 -9
  201. package/src/question-paragraph.tsx +0 -34
  202. package/src/renderability.ts +0 -109
  203. package/src/renderer.tsx +0 -2000
  204. package/src/server-item-renderer.tsx +0 -495
  205. package/src/sigfigs.ts +0 -490
  206. package/src/styles/articles.less +0 -749
  207. package/src/styles/constants.ts +0 -94
  208. package/src/styles/global-constants.ts +0 -343
  209. package/src/styles/global-styles.ts +0 -306
  210. package/src/styles/khan-exercise.css +0 -1468
  211. package/src/styles/media-queries.ts +0 -47
  212. package/src/styles/perseus-renderer.less +0 -732
  213. package/src/styles/shared.ts +0 -130
  214. package/src/styles/util.less +0 -47
  215. package/src/styles/variables.boostrap.less +0 -277
  216. package/src/styles/variables.less +0 -56
  217. package/src/styles/variables.shared.less +0 -340
  218. package/src/styles/widgets/categorizer.less +0 -38
  219. package/src/styles/widgets/dropdown.less +0 -3
  220. package/src/styles/widgets/expression.less +0 -65
  221. package/src/styles/widgets/graded-group.less +0 -36
  222. package/src/styles/widgets/grapher.less +0 -12
  223. package/src/styles/widgets/group.less +0 -19
  224. package/src/styles/widgets/image.less +0 -54
  225. package/src/styles/widgets/interactive-graph.less +0 -64
  226. package/src/styles/widgets/label-image.less +0 -57
  227. package/src/styles/widgets/matcher.less +0 -8
  228. package/src/styles/widgets/matrix.less +0 -126
  229. package/src/styles/widgets/measurer.less +0 -20
  230. package/src/styles/widgets/orderer.less +0 -98
  231. package/src/styles/widgets/passage.less +0 -154
  232. package/src/styles/widgets/plotter.less +0 -31
  233. package/src/styles/widgets/radio.less +0 -58
  234. package/src/styles/widgets/reaction-diagram.less +0 -35
  235. package/src/styles/widgets/sequence.less +0 -5
  236. package/src/styles/widgets/sortable.less +0 -113
  237. package/src/styles/widgets/table.less +0 -57
  238. package/src/styles/widgets/unit.less +0 -15
  239. package/src/tex-wrangler.ts +0 -182
  240. package/src/translation-linter.ts +0 -126
  241. package/src/traversal.ts +0 -138
  242. package/src/types.ts +0 -513
  243. package/src/util/a11y.ts +0 -23
  244. package/src/util/answer-types.test.ts +0 -114
  245. package/src/util/answer-types.ts +0 -876
  246. package/src/util/colors.ts +0 -93
  247. package/src/util/drawing-transform.test.ts +0 -67
  248. package/src/util/drawing-transform.ts +0 -102
  249. package/src/util/extract-perseus-data.ts +0 -539
  250. package/src/util/fix-passage-refs.ts +0 -121
  251. package/src/util/geometry.test.ts +0 -75
  252. package/src/util/geometry.ts +0 -312
  253. package/src/util/graph-bounds.ts +0 -23
  254. package/src/util/graph-utils.ts +0 -15
  255. package/src/util/graphie.test.ts +0 -1277
  256. package/src/util/graphie.ts +0 -1576
  257. package/src/util/interactive.ts +0 -4174
  258. package/src/util/interval.ts +0 -4
  259. package/src/util/katex-preprocess.ts +0 -14
  260. package/src/util/math.test.ts +0 -11
  261. package/src/util/math.ts +0 -294
  262. package/src/util/mobile-native-utils.test.ts +0 -22
  263. package/src/util/mobile-native-utils.ts +0 -12
  264. package/src/util/parse-perseus-json.test.ts +0 -10
  265. package/src/util/parse-perseus-json.ts +0 -13
  266. package/src/util/react-render.tsx +0 -27
  267. package/src/util/register-all-widgets-for-testing.ts +0 -13
  268. package/src/util/scroll-utils.ts +0 -155
  269. package/src/util/sizing-utils.ts +0 -46
  270. package/src/util/tex.ts +0 -73
  271. package/src/util/url-utils.ts +0 -34
  272. package/src/util.graphie.test.ts +0 -45
  273. package/src/util.graphie.ts +0 -59
  274. package/src/util.ts +0 -966
  275. package/src/version.ts +0 -10
  276. package/src/widget-container.tsx +0 -199
  277. package/src/widgets/__stories__/categorizer.stories.tsx +0 -14
  278. package/src/widgets/__stories__/cs-program.stories.tsx +0 -14
  279. package/src/widgets/__stories__/definition.stories.tsx +0 -114
  280. package/src/widgets/__stories__/dropdown.stories.tsx +0 -14
  281. package/src/widgets/__stories__/explanation.stories.tsx +0 -18
  282. package/src/widgets/__stories__/expression.stories.tsx +0 -145
  283. package/src/widgets/__stories__/graded-group-set.stories.tsx +0 -31
  284. package/src/widgets/__stories__/graded-group.stories.tsx +0 -31
  285. package/src/widgets/__stories__/grapher.stories.tsx +0 -46
  286. package/src/widgets/__stories__/group.stories.tsx +0 -14
  287. package/src/widgets/__stories__/iframe.stories.tsx +0 -14
  288. package/src/widgets/__stories__/image.stories.tsx +0 -85
  289. package/src/widgets/__stories__/input-number.stories.tsx +0 -101
  290. package/src/widgets/__stories__/interaction.stories.tsx +0 -14
  291. package/src/widgets/__stories__/interactive-graph.stories.tsx +0 -60
  292. package/src/widgets/__stories__/label-image.stories.tsx +0 -130
  293. package/src/widgets/__stories__/matcher.stories.tsx +0 -14
  294. package/src/widgets/__stories__/matrix.stories.tsx +0 -14
  295. package/src/widgets/__stories__/number-line.stories.tsx +0 -14
  296. package/src/widgets/__stories__/numeric-input.stories.tsx +0 -105
  297. package/src/widgets/__stories__/orderer.stories.tsx +0 -18
  298. package/src/widgets/__stories__/passage-ref.stories.tsx +0 -33
  299. package/src/widgets/__stories__/passage.stories.tsx +0 -39
  300. package/src/widgets/__stories__/plotter.stories.tsx +0 -27
  301. package/src/widgets/__stories__/radio.stories.tsx +0 -86
  302. package/src/widgets/__stories__/random-widgets.stories.tsx +0 -59
  303. package/src/widgets/__stories__/sorter.stories.tsx +0 -14
  304. package/src/widgets/__stories__/test-keypad-context-wrapper.tsx +0 -66
  305. package/src/widgets/__stories__/unit.stories.tsx +0 -28
  306. package/src/widgets/__stories__/video-transcript-link.stories.tsx +0 -23
  307. package/src/widgets/__stories__/video.stories.tsx +0 -22
  308. package/src/widgets/__testdata__/base-radio.testdata.ts +0 -21
  309. package/src/widgets/__testdata__/categorizer.testdata.ts +0 -89
  310. package/src/widgets/__testdata__/cs-program.testdata.ts +0 -27
  311. package/src/widgets/__testdata__/dropdown.testdata.ts +0 -71
  312. package/src/widgets/__testdata__/explanation.testdata.ts +0 -85
  313. package/src/widgets/__testdata__/expression.testdata.ts +0 -198
  314. package/src/widgets/__testdata__/graded-group-set.testdata.ts +0 -356
  315. package/src/widgets/__testdata__/graded-group.testdata.ts +0 -77
  316. package/src/widgets/__testdata__/grapher.testdata.ts +0 -374
  317. package/src/widgets/__testdata__/group.testdata.ts +0 -153
  318. package/src/widgets/__testdata__/iframe.testdata.ts +0 -35
  319. package/src/widgets/__testdata__/image.testdata.ts +0 -36
  320. package/src/widgets/__testdata__/input-number.testdata.ts +0 -72
  321. package/src/widgets/__testdata__/interaction.testdata.ts +0 -262
  322. package/src/widgets/__testdata__/interactive-graph-random.testdata.ts +0 -269
  323. package/src/widgets/__testdata__/interactive-graph.testdata.ts +0 -644
  324. package/src/widgets/__testdata__/label-image.testdata.ts +0 -308
  325. package/src/widgets/__testdata__/matcher.testdata.ts +0 -33
  326. package/src/widgets/__testdata__/matrix.testdata.ts +0 -28
  327. package/src/widgets/__testdata__/number-line.testdata.ts +0 -30
  328. package/src/widgets/__testdata__/numeric-input.testdata.ts +0 -265
  329. package/src/widgets/__testdata__/orderer.testdata.ts +0 -123
  330. package/src/widgets/__testdata__/passage-ref.testdata.ts +0 -101
  331. package/src/widgets/__testdata__/passage.testdata.ts +0 -95
  332. package/src/widgets/__testdata__/plotter.testdata.ts +0 -36
  333. package/src/widgets/__testdata__/radio.testdata.ts +0 -324
  334. package/src/widgets/__testdata__/randomizers.ts +0 -51
  335. package/src/widgets/__testdata__/sorter.testdata.ts +0 -19
  336. package/src/widgets/__testdata__/video.testdata.ts +0 -61
  337. package/src/widgets/__tests__/__snapshots__/categorizer.test.ts.snap +0 -940
  338. package/src/widgets/__tests__/__snapshots__/cs-program.test.ts.snap +0 -67
  339. package/src/widgets/__tests__/__snapshots__/definition.test.ts.snap +0 -97
  340. package/src/widgets/__tests__/__snapshots__/dropdown.test.ts.snap +0 -133
  341. package/src/widgets/__tests__/__snapshots__/explanation.test.ts.snap +0 -425
  342. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt.test.ts.snap +0 -729
  343. package/src/widgets/__tests__/__snapshots__/graded-group-set.test.ts.snap +0 -339
  344. package/src/widgets/__tests__/__snapshots__/graded-group.test.ts.snap +0 -801
  345. package/src/widgets/__tests__/__snapshots__/grapher.test.ts.snap +0 -2673
  346. package/src/widgets/__tests__/__snapshots__/group.test.tsx.snap +0 -1211
  347. package/src/widgets/__tests__/__snapshots__/iframe.test.ts.snap +0 -61
  348. package/src/widgets/__tests__/__snapshots__/image.test.ts.snap +0 -378
  349. package/src/widgets/__tests__/__snapshots__/input-number.test.ts.snap +0 -495
  350. package/src/widgets/__tests__/__snapshots__/interaction.test.ts.snap +0 -292
  351. package/src/widgets/__tests__/__snapshots__/interactive-graph.test.ts.snap +0 -2889
  352. package/src/widgets/__tests__/__snapshots__/matcher.test.tsx.snap +0 -883
  353. package/src/widgets/__tests__/__snapshots__/matrix.test.ts.snap +0 -514
  354. package/src/widgets/__tests__/__snapshots__/number-line.test.ts.snap +0 -814
  355. package/src/widgets/__tests__/__snapshots__/numeric-input.test.ts.snap +0 -470
  356. package/src/widgets/__tests__/__snapshots__/orderer.test.ts.snap +0 -243
  357. package/src/widgets/__tests__/__snapshots__/passage-ref.test.ts.snap +0 -434
  358. package/src/widgets/__tests__/__snapshots__/passage.test.tsx.snap +0 -1956
  359. package/src/widgets/__tests__/__snapshots__/plotter.test.tsx.snap +0 -827
  360. package/src/widgets/__tests__/__snapshots__/radio.test.ts.snap +0 -4237
  361. package/src/widgets/__tests__/__snapshots__/unit.test.tsx.snap +0 -20
  362. package/src/widgets/__tests__/__snapshots__/video.test.ts.snap +0 -153
  363. package/src/widgets/__tests__/categorizer.test.ts +0 -203
  364. package/src/widgets/__tests__/cs-program.test.ts +0 -43
  365. package/src/widgets/__tests__/definition.test.ts +0 -136
  366. package/src/widgets/__tests__/dropdown.test.ts +0 -105
  367. package/src/widgets/__tests__/explanation.test.ts +0 -198
  368. package/src/widgets/__tests__/expression-mobile.test.tsx +0 -363
  369. package/src/widgets/__tests__/expression.test.tsx +0 -484
  370. package/src/widgets/__tests__/graded-group-set-jipt.test.ts +0 -30
  371. package/src/widgets/__tests__/graded-group-set.test.ts +0 -288
  372. package/src/widgets/__tests__/graded-group.test.ts +0 -232
  373. package/src/widgets/__tests__/grapher.cypress.ts +0 -576
  374. package/src/widgets/__tests__/grapher.test.ts +0 -33
  375. package/src/widgets/__tests__/group.test.tsx +0 -510
  376. package/src/widgets/__tests__/iframe.test.ts +0 -45
  377. package/src/widgets/__tests__/image.test.ts +0 -62
  378. package/src/widgets/__tests__/input-number.test.ts +0 -354
  379. package/src/widgets/__tests__/interaction.test.ts +0 -31
  380. package/src/widgets/__tests__/interactive-graph.cypress.ts +0 -815
  381. package/src/widgets/__tests__/interactive-graph.test.ts +0 -106
  382. package/src/widgets/__tests__/matcher.test.tsx +0 -176
  383. package/src/widgets/__tests__/matrix.test.ts +0 -82
  384. package/src/widgets/__tests__/number-line.test.ts +0 -79
  385. package/src/widgets/__tests__/numeric-input.test.ts +0 -575
  386. package/src/widgets/__tests__/orderer.test.ts +0 -73
  387. package/src/widgets/__tests__/passage-ref.test.ts +0 -168
  388. package/src/widgets/__tests__/passage.test.tsx +0 -224
  389. package/src/widgets/__tests__/plotter.test.tsx +0 -69
  390. package/src/widgets/__tests__/radio/base-radio.test.tsx +0 -470
  391. package/src/widgets/__tests__/radio/choice-icon.test.tsx +0 -90
  392. package/src/widgets/__tests__/radio/choice.test.tsx +0 -310
  393. package/src/widgets/__tests__/radio/focus-ring.test.tsx +0 -22
  394. package/src/widgets/__tests__/radio/option-status.test.tsx +0 -77
  395. package/src/widgets/__tests__/radio.test.ts +0 -807
  396. package/src/widgets/__tests__/randomizers.test.ts +0 -53
  397. package/src/widgets/__tests__/renderQuestion.tsx +0 -101
  398. package/src/widgets/__tests__/unit.test.tsx +0 -168
  399. package/src/widgets/__tests__/video.test.ts +0 -69
  400. package/src/widgets/categorizer.tsx +0 -344
  401. package/src/widgets/cs-program.tsx +0 -227
  402. package/src/widgets/definition.tsx +0 -121
  403. package/src/widgets/deprecated-standin/__stories__/deprecated-standin.stories.tsx +0 -30
  404. package/src/widgets/deprecated-standin/__tests__/__snapshots__/deprecated-standin.test.ts.snap +0 -70
  405. package/src/widgets/deprecated-standin/__tests__/deprecated-standin.test.ts +0 -93
  406. package/src/widgets/deprecated-standin/index.tsx +0 -58
  407. package/src/widgets/dropdown.tsx +0 -142
  408. package/src/widgets/explanation.tsx +0 -317
  409. package/src/widgets/expression.tsx +0 -707
  410. package/src/widgets/graded-group-answer-bar.tsx +0 -142
  411. package/src/widgets/graded-group-set.tsx +0 -338
  412. package/src/widgets/graded-group.tsx +0 -471
  413. package/src/widgets/grapher/util.tsx +0 -799
  414. package/src/widgets/grapher.tsx +0 -660
  415. package/src/widgets/group.tsx +0 -195
  416. package/src/widgets/iframe.tsx +0 -195
  417. package/src/widgets/image.tsx +0 -312
  418. package/src/widgets/input-number.tsx +0 -412
  419. package/src/widgets/interaction/arrow-picker.tsx +0 -38
  420. package/src/widgets/interaction/color-picker.tsx +0 -69
  421. package/src/widgets/interaction/dash-picker.tsx +0 -45
  422. package/src/widgets/interaction/element-container.tsx +0 -100
  423. package/src/widgets/interaction.tsx +0 -826
  424. package/src/widgets/interactive-graph.tsx +0 -2597
  425. package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +0 -91
  426. package/src/widgets/label-image/__stories__/answer-pill.stories.tsx +0 -62
  427. package/src/widgets/label-image/__stories__/marker.stories.tsx +0 -171
  428. package/src/widgets/label-image/__tests__/answer-pill.test.tsx +0 -75
  429. package/src/widgets/label-image/__tests__/hide-answers-toggle.test.tsx +0 -39
  430. package/src/widgets/label-image/answer-choices.tsx +0 -88
  431. package/src/widgets/label-image/answer-pill.tsx +0 -103
  432. package/src/widgets/label-image/hide-answers-toggle.tsx +0 -40
  433. package/src/widgets/label-image/marker.tsx +0 -268
  434. package/src/widgets/label-image/strings.ts +0 -5
  435. package/src/widgets/label-image/types.ts +0 -27
  436. package/src/widgets/label-image.test.ts +0 -928
  437. package/src/widgets/label-image.tsx +0 -819
  438. package/src/widgets/lights-puzzle.tsx +0 -359
  439. package/src/widgets/matcher.tsx +0 -298
  440. package/src/widgets/matrix.tsx +0 -634
  441. package/src/widgets/measurer.tsx +0 -222
  442. package/src/widgets/molecule/__tests__/layout.test.ts +0 -162
  443. package/src/widgets/molecule/__tests__/parser.test.ts +0 -155
  444. package/src/widgets/molecule/molecule-drawing.ts +0 -173
  445. package/src/widgets/molecule/molecule-layout.ts +0 -362
  446. package/src/widgets/molecule/smiles-parser.ts +0 -296
  447. package/src/widgets/molecule.tsx +0 -172
  448. package/src/widgets/number-line.tsx +0 -862
  449. package/src/widgets/numeric-input.tsx +0 -576
  450. package/src/widgets/orderer.tsx +0 -786
  451. package/src/widgets/passage/__tests__/passage-markdown.test.ts +0 -376
  452. package/src/widgets/passage/passage-markdown.tsx +0 -475
  453. package/src/widgets/passage-ref-target.tsx +0 -76
  454. package/src/widgets/passage-ref.tsx +0 -213
  455. package/src/widgets/passage.tsx +0 -582
  456. package/src/widgets/plotter.tsx +0 -1194
  457. package/src/widgets/radio/__stories__/base-radio.stories.tsx +0 -196
  458. package/src/widgets/radio/__stories__/choice-icon.stories.tsx +0 -166
  459. package/src/widgets/radio/__stories__/choice-none-above.stories.tsx +0 -40
  460. package/src/widgets/radio/__stories__/choice.stories.tsx +0 -137
  461. package/src/widgets/radio/__stories__/focus-ring.stories.tsx +0 -43
  462. package/src/widgets/radio/__stories__/option-status.stories.tsx +0 -103
  463. package/src/widgets/radio/base-radio.tsx +0 -511
  464. package/src/widgets/radio/choice-a11y-text.ts +0 -61
  465. package/src/widgets/radio/choice-icon/choice-icon.tsx +0 -218
  466. package/src/widgets/radio/choice-icon/cross-out-line.tsx +0 -51
  467. package/src/widgets/radio/choice-icon/shared-styles.ts +0 -15
  468. package/src/widgets/radio/choice-none-above.tsx +0 -56
  469. package/src/widgets/radio/choice.jsx.fixture.ts +0 -45
  470. package/src/widgets/radio/choice.tsx +0 -359
  471. package/src/widgets/radio/focus-ring.tsx +0 -57
  472. package/src/widgets/radio/option-status.tsx +0 -98
  473. package/src/widgets/radio/util.test.ts +0 -18
  474. package/src/widgets/radio/util.ts +0 -31
  475. package/src/widgets/radio/widget.tsx +0 -520
  476. package/src/widgets/radio.ts +0 -157
  477. package/src/widgets/reaction-diagram.tsx +0 -144
  478. package/src/widgets/sequence.tsx +0 -142
  479. package/src/widgets/simulator.tsx +0 -829
  480. package/src/widgets/sorter.tsx +0 -155
  481. package/src/widgets/table.tsx +0 -393
  482. package/src/widgets/unit.tsx +0 -374
  483. package/src/widgets/video-transcript-link.test.tsx +0 -213
  484. package/src/widgets/video-transcript-link.tsx +0 -84
  485. package/src/widgets/video.tsx +0 -135
  486. package/src/widgets.ts +0 -489
  487. package/src/zoom.ts +0 -555
  488. package/tsconfig-build.json +0 -26
  489. 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;