@khanacademy/perseus 2.1.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1212) hide show
  1. package/.babelrc.js +1 -1
  2. package/.eslintrc.js +1 -0
  3. package/CHANGELOG.md +22 -0
  4. package/dist/__tests__/mock-asset-loading-widget.d.ts +59 -0
  5. package/dist/__tests__/mock-asset-loading-widget.js.flow +70 -0
  6. package/dist/__tests__/mock-widget.d.ts +30 -0
  7. package/dist/__tests__/mock-widget.js.flow +39 -0
  8. package/dist/__tests__/test-items/image-item.d.ts +14 -0
  9. package/dist/__tests__/test-items/image-item.js.flow +20 -0
  10. package/dist/__tests__/test-items/input-number-1-item.d.ts +9 -0
  11. package/dist/__tests__/test-items/input-number-1-item.js.flow +15 -0
  12. package/dist/__tests__/test-items/input-number-2-item.d.ts +9 -0
  13. package/dist/__tests__/test-items/input-number-2-item.js.flow +15 -0
  14. package/dist/__tests__/test-items/table-item.d.ts +9 -0
  15. package/dist/__tests__/test-items/table-item.js.flow +15 -0
  16. package/dist/a11y.d.ts +5 -0
  17. package/dist/a11y.js.flow +11 -0
  18. package/dist/all-widgets.d.ts +22 -0
  19. package/dist/all-widgets.js.flow +33 -0
  20. package/dist/article-renderer.d.ts +54 -0
  21. package/dist/article-renderer.js.flow +69 -0
  22. package/dist/asset-context.d.ts +14 -0
  23. package/dist/asset-context.js.flow +15 -0
  24. package/dist/basic-widgets.d.ts +22 -0
  25. package/dist/basic-widgets.js.flow +33 -0
  26. package/dist/components/button-group.d.ts +27 -0
  27. package/dist/components/button-group.js.flow +33 -0
  28. package/dist/components/constants.d.ts +7 -0
  29. package/dist/components/constants.js.flow +13 -0
  30. package/dist/components/fixed-to-responsive.d.ts +2 -0
  31. package/dist/components/fixed-to-responsive.js.flow +8 -0
  32. package/dist/components/graph.d.ts +44 -0
  33. package/dist/components/graph.js.flow +52 -0
  34. package/dist/components/graphie-classes.d.ts +13 -0
  35. package/dist/components/graphie-classes.js.flow +19 -0
  36. package/dist/components/graphie-movables.d.ts +16 -0
  37. package/dist/components/graphie-movables.js.flow +22 -0
  38. package/dist/components/graphie.d.ts +44 -0
  39. package/dist/components/graphie.js.flow +56 -0
  40. package/dist/components/highlighting/highlightable-content.d.ts +39 -0
  41. package/dist/components/highlighting/highlightable-content.js.flow +59 -0
  42. package/dist/components/highlighting/highlights.d.ts +30 -0
  43. package/dist/components/highlighting/highlights.js.flow +54 -0
  44. package/dist/components/highlighting/ranges.d.ts +42 -0
  45. package/dist/components/highlighting/ranges.js.flow +60 -0
  46. package/dist/components/highlighting/types.d.ts +64 -0
  47. package/dist/components/highlighting/types.js.flow +70 -0
  48. package/dist/components/highlighting/ui/highlight-renderer.d.ts +34 -0
  49. package/dist/components/highlighting/ui/highlight-renderer.js.flow +45 -0
  50. package/dist/components/highlighting/ui/highlight-set-renderer.d.ts +34 -0
  51. package/dist/components/highlighting/ui/highlight-set-renderer.js.flow +44 -0
  52. package/dist/components/highlighting/ui/highlight-tooltip.d.ts +16 -0
  53. package/dist/components/highlighting/ui/highlight-tooltip.js.flow +24 -0
  54. package/dist/components/highlighting/ui/highlighting-ui.d.ts +19 -0
  55. package/dist/components/highlighting/ui/highlighting-ui.js.flow +30 -0
  56. package/dist/components/highlighting/ui/selection-tracker.d.ts +47 -0
  57. package/dist/components/highlighting/ui/selection-tracker.js.flow +56 -0
  58. package/dist/components/highlighting/ui/types.d.ts +13 -0
  59. package/dist/components/highlighting/ui/types.js.flow +22 -0
  60. package/dist/components/highlighting/ui/util.d.ts +28 -0
  61. package/dist/components/highlighting/ui/util.js.flow +42 -0
  62. package/dist/components/highlighting/word-indexer.d.ts +28 -0
  63. package/dist/components/highlighting/word-indexer.js.flow +21 -0
  64. package/dist/components/hud.d.ts +15 -0
  65. package/dist/components/hud.js.flow +21 -0
  66. package/dist/components/icon.d.ts +56 -0
  67. package/dist/components/icon.js.flow +31 -0
  68. package/dist/components/image-loader.d.ts +52 -0
  69. package/dist/components/image-loader.js.flow +49 -0
  70. package/dist/components/info-tip/info-tip.d.ts +14 -0
  71. package/dist/components/info-tip/info-tip.js.flow +20 -0
  72. package/dist/components/info-tip.d.ts +18 -0
  73. package/dist/components/info-tip.js.flow +18 -0
  74. package/dist/components/inline-icon.d.ts +10 -0
  75. package/dist/components/inline-icon.js.flow +16 -0
  76. package/dist/components/input-with-examples.d.ts +52 -0
  77. package/dist/components/input-with-examples.js.flow +58 -0
  78. package/dist/components/lint.d.ts +23 -0
  79. package/dist/components/lint.js.flow +29 -0
  80. package/dist/components/math-input.d.ts +40 -0
  81. package/dist/components/math-input.js.flow +46 -0
  82. package/dist/components/math-output.d.ts +23 -0
  83. package/dist/components/math-output.js.flow +29 -0
  84. package/dist/components/multi-button-group.d.ts +29 -0
  85. package/dist/components/multi-button-group.js.flow +35 -0
  86. package/dist/components/number-input.d.ts +34 -0
  87. package/dist/components/number-input.js.flow +42 -0
  88. package/dist/components/prop-check-box.d.ts +2 -0
  89. package/dist/components/prop-check-box.js.flow +8 -0
  90. package/dist/components/range-input.d.ts +14 -0
  91. package/dist/components/range-input.js.flow +20 -0
  92. package/dist/components/simple-keypad-input.d.ts +19 -0
  93. package/dist/components/simple-keypad-input.js.flow +16 -0
  94. package/dist/components/sortable.d.ts +68 -0
  95. package/dist/components/sortable.js.flow +78 -0
  96. package/dist/components/stub-tag-editor.d.ts +25 -0
  97. package/dist/components/stub-tag-editor.js.flow +18 -0
  98. package/dist/components/svg-image.d.ts +74 -0
  99. package/dist/components/svg-image.js.flow +83 -0
  100. package/dist/components/tex-buttons.d.ts +20 -0
  101. package/dist/components/tex-buttons.js.flow +26 -0
  102. package/dist/components/tex.d.ts +25 -0
  103. package/dist/components/tex.js.flow +25 -0
  104. package/dist/components/text-input.d.ts +33 -0
  105. package/dist/components/text-input.js.flow +39 -0
  106. package/dist/components/text-list-editor.d.ts +16 -0
  107. package/dist/components/text-list-editor.js.flow +22 -0
  108. package/dist/components/tooltip.d.ts +32 -0
  109. package/dist/components/tooltip.js.flow +38 -0
  110. package/dist/components/visibility-observer/create-visibility-observer.d.ts +34 -0
  111. package/dist/components/visibility-observer/create-visibility-observer.js.flow +23 -0
  112. package/dist/components/visibility-observer/get-scroll-parent.d.ts +1 -0
  113. package/dist/components/visibility-observer/get-scroll-parent.js.flow +7 -0
  114. package/dist/components/visibility-observer/visibility-observer.d.ts +31 -0
  115. package/dist/components/visibility-observer/visibility-observer.js.flow +36 -0
  116. package/dist/components/zoomable-tex.d.ts +18 -0
  117. package/dist/components/zoomable-tex.js.flow +18 -0
  118. package/dist/components/zoomable.d.ts +64 -0
  119. package/dist/components/zoomable.js.flow +70 -0
  120. package/dist/components.d.ts +16 -0
  121. package/dist/components.js.flow +22 -0
  122. package/dist/definition-context.d.ts +21 -0
  123. package/dist/definition-context.js.flow +25 -0
  124. package/dist/dependencies.d.ts +3 -0
  125. package/dist/dependencies.js.flow +9 -0
  126. package/dist/error-boundary.d.ts +13 -0
  127. package/dist/error-boundary.js.flow +21 -0
  128. package/dist/es/index.js +23239 -26937
  129. package/dist/es/index.js.map +1 -1
  130. package/dist/extra-widgets.d.ts +22 -0
  131. package/dist/extra-widgets.js.flow +33 -0
  132. package/dist/hint-renderer.d.ts +23 -0
  133. package/dist/hint-renderer.js.flow +32 -0
  134. package/dist/hints-renderer.d.ts +29 -0
  135. package/dist/hints-renderer.js.flow +41 -0
  136. package/dist/icon-paths.d.ts +117 -0
  137. package/dist/icon-paths.js.flow +123 -0
  138. package/dist/index.d.ts +103 -2
  139. package/dist/index.js +13063 -16571
  140. package/dist/index.js.flow +133 -2
  141. package/dist/index.js.map +1 -1
  142. package/dist/init.d.ts +14 -0
  143. package/dist/init.js.flow +20 -0
  144. package/dist/interaction-tracker.d.ts +23 -0
  145. package/dist/interaction-tracker.js.flow +33 -0
  146. package/dist/interactive2/__tests__/movable-mock.d.ts +5 -0
  147. package/dist/interactive2/__tests__/movable-mock.js.flow +11 -0
  148. package/dist/interactive2/interactive-util.d.ts +31 -0
  149. package/dist/interactive2/interactive-util.js.flow +50 -0
  150. package/dist/interactive2/movable-helper-methods.d.ts +9 -0
  151. package/dist/interactive2/movable-helper-methods.js.flow +15 -0
  152. package/dist/interactive2/movable-line-options.d.ts +34 -0
  153. package/dist/interactive2/movable-line-options.js.flow +44 -0
  154. package/dist/interactive2/movable-line.d.ts +2 -0
  155. package/dist/interactive2/movable-line.js.flow +8 -0
  156. package/dist/interactive2/movable-point-options.d.ts +34 -0
  157. package/dist/interactive2/movable-point-options.js.flow +44 -0
  158. package/dist/interactive2/movable-point.d.ts +2 -0
  159. package/dist/interactive2/movable-point.js.flow +8 -0
  160. package/dist/interactive2/movable-polygon-options.d.ts +40 -0
  161. package/dist/interactive2/movable-polygon-options.js.flow +47 -0
  162. package/dist/interactive2/movable-polygon.d.ts +2 -0
  163. package/dist/interactive2/movable-polygon.js.flow +8 -0
  164. package/dist/interactive2/movable.d.ts +2 -0
  165. package/dist/interactive2/movable.js.flow +8 -0
  166. package/dist/interactive2/objective_.d.ts +13 -0
  167. package/dist/interactive2/objective_.js.flow +25 -0
  168. package/dist/interactive2/types.d.ts +2 -0
  169. package/dist/interactive2/types.js.flow +8 -0
  170. package/dist/interactive2/wrapped-defaults.d.ts +5 -0
  171. package/dist/interactive2/wrapped-defaults.js.flow +11 -0
  172. package/dist/interactive2/wrapped-ellipse.d.ts +3 -0
  173. package/dist/interactive2/wrapped-ellipse.js.flow +14 -0
  174. package/dist/interactive2/wrapped-line.d.ts +3 -0
  175. package/dist/interactive2/wrapped-line.js.flow +14 -0
  176. package/dist/interactive2/wrapped-path.d.ts +3 -0
  177. package/dist/interactive2/wrapped-path.js.flow +13 -0
  178. package/dist/interactive2.d.ts +10 -0
  179. package/dist/interactive2.js.flow +16 -0
  180. package/dist/item-renderer.d.ts +117 -0
  181. package/dist/item-renderer.js.flow +136 -0
  182. package/dist/item-version.d.ts +4 -0
  183. package/dist/item-version.js.flow +11 -0
  184. package/dist/jipt-paragraphs.d.ts +8 -0
  185. package/dist/jipt-paragraphs.js.flow +14 -0
  186. package/dist/keypad-context.d.ts +20 -0
  187. package/dist/keypad-context.js.flow +18 -0
  188. package/dist/loading-context.d.ts +14 -0
  189. package/dist/loading-context.js.flow +12 -0
  190. package/dist/logging/log.d.ts +55 -0
  191. package/dist/logging/log.js.flow +62 -0
  192. package/dist/mixins/changeable.d.ts +30 -0
  193. package/dist/mixins/changeable.js.flow +33 -0
  194. package/dist/mixins/editor-jsonify.d.ts +4 -0
  195. package/dist/mixins/editor-jsonify.js.flow +10 -0
  196. package/dist/mixins/provide-keypad.d.ts +36 -0
  197. package/dist/mixins/provide-keypad.js.flow +33 -0
  198. package/dist/mixins/widget-jsonify-deprecated.d.ts +5 -0
  199. package/dist/mixins/widget-jsonify-deprecated.js.flow +11 -0
  200. package/dist/mixins/widget-prop-denylist.d.ts +14 -0
  201. package/dist/mixins/widget-prop-denylist.js.flow +20 -0
  202. package/dist/multi-items/item-types.d.ts +32 -0
  203. package/dist/multi-items/items.d.ts +53 -0
  204. package/dist/multi-items/items.js.flow +66 -0
  205. package/dist/multi-items/multi-renderer.d.ts +152 -0
  206. package/dist/multi-items/multi-renderer.js.flow +213 -0
  207. package/dist/multi-items/prop-type-builders.d.ts +20 -0
  208. package/dist/multi-items/prop-type-builders.js.flow +22 -0
  209. package/dist/multi-items/shape-types.d.ts +47 -0
  210. package/dist/multi-items/shape-types.js.flow +60 -0
  211. package/dist/multi-items/shapes.d.ts +23 -0
  212. package/dist/multi-items/shapes.js.flow +25 -0
  213. package/dist/multi-items/tree-types.d.ts +34 -0
  214. package/dist/multi-items/tree-types.js.flow +45 -0
  215. package/dist/multi-items/trees.d.ts +146 -0
  216. package/dist/multi-items/trees.js.flow +147 -0
  217. package/dist/multi-items.d.ts +73 -0
  218. package/dist/multi-items.js.flow +36 -0
  219. package/dist/perseus-api.d.ts +128 -0
  220. package/dist/perseus-api.js.flow +139 -0
  221. package/dist/perseus-env.d.ts +3 -0
  222. package/dist/perseus-env.js.flow +6 -0
  223. package/dist/perseus-error.d.ts +11 -0
  224. package/dist/perseus-error.js.flow +16 -0
  225. package/dist/perseus-markdown.d.ts +11 -0
  226. package/dist/perseus-markdown.js.flow +20 -0
  227. package/dist/perseus-types.d.ts +776 -0
  228. package/dist/perseus-types.js.flow +1032 -0
  229. package/dist/question-paragraph.d.ts +11 -0
  230. package/dist/question-paragraph.js.flow +17 -0
  231. package/dist/renderability.d.ts +10 -0
  232. package/dist/renderability.js.flow +19 -0
  233. package/dist/renderer.d.ts +254 -0
  234. package/dist/renderer.js.flow +327 -0
  235. package/dist/server-item-renderer.d.ts +113 -0
  236. package/dist/server-item-renderer.js.flow +136 -0
  237. package/dist/sigfigs.d.ts +32 -0
  238. package/dist/sigfigs.js.flow +41 -0
  239. package/dist/styles/constants.d.ts +56 -0
  240. package/dist/styles/constants.js.flow +62 -0
  241. package/dist/styles/global-constants.d.ts +342 -0
  242. package/dist/styles/global-constants.js.flow +348 -0
  243. package/dist/styles/global-styles.d.ts +47 -0
  244. package/dist/styles/global-styles.js.flow +53 -0
  245. package/dist/styles/media-queries.d.ts +29 -0
  246. package/dist/styles/media-queries.js.flow +35 -0
  247. package/dist/styles/shared.d.ts +3 -0
  248. package/dist/styles/shared.js.flow +9 -0
  249. package/dist/tex-wrangler.d.ts +7 -0
  250. package/dist/tex-wrangler.js.flow +13 -0
  251. package/dist/translation-linter.d.ts +21 -0
  252. package/dist/translation-linter.js.flow +32 -0
  253. package/dist/traversal.d.ts +15 -0
  254. package/dist/traversal.js.flow +26 -0
  255. package/dist/types.d.ts +262 -0
  256. package/dist/types.js.flow +337 -0
  257. package/dist/util/a11y.d.ts +3 -0
  258. package/dist/util/a11y.js.flow +9 -0
  259. package/dist/util/answer-types.d.ts +34 -0
  260. package/dist/util/answer-types.js.flow +49 -0
  261. package/dist/util/colors.d.ts +89 -0
  262. package/dist/util/colors.js.flow +95 -0
  263. package/dist/util/fix-passage-refs.d.ts +2 -0
  264. package/dist/util/fix-passage-refs.js.flow +8 -0
  265. package/dist/util/graph-utils.d.ts +12 -0
  266. package/dist/util/graph-utils.js.flow +9 -0
  267. package/dist/util/graphie.d.ts +2 -0
  268. package/dist/util/graphie.js.flow +8 -0
  269. package/dist/util/interactive.d.ts +9 -0
  270. package/dist/util/interactive.js.flow +9 -0
  271. package/dist/util/katex-preprocess.d.ts +6 -0
  272. package/dist/util/katex-preprocess.js.flow +12 -0
  273. package/dist/util/math.d.ts +28 -0
  274. package/dist/util/math.js.flow +62 -0
  275. package/dist/util/mobile-native-utils.d.ts +7 -0
  276. package/dist/util/mobile-native-utils.js.flow +12 -0
  277. package/dist/util/react-render.d.ts +2 -0
  278. package/dist/util/react-render.js.flow +12 -0
  279. package/dist/util/register-all-widgets-for-testing.d.ts +1 -0
  280. package/dist/util/register-all-widgets-for-testing.js.flow +7 -0
  281. package/dist/util/scroll-utils.d.ts +10 -0
  282. package/dist/util/scroll-utils.js.flow +19 -0
  283. package/dist/util/sizing-utils.d.ts +9 -0
  284. package/dist/util/sizing-utils.js.flow +20 -0
  285. package/dist/util/tex.d.ts +6 -0
  286. package/dist/util/tex.js.flow +17 -0
  287. package/dist/util/url-utils.d.ts +6 -0
  288. package/dist/util/url-utils.js.flow +11 -0
  289. package/dist/util.d.ts +247 -0
  290. package/dist/util.js.flow +320 -0
  291. package/dist/version.d.ts +11 -0
  292. package/dist/version.js.flow +17 -0
  293. package/dist/widget-container.d.ts +27 -0
  294. package/dist/widget-container.js.flow +33 -0
  295. package/dist/widgets/__tests__/renderQuestion.d.ts +13 -0
  296. package/dist/widgets/__tests__/renderQuestion.js.flow +28 -0
  297. package/dist/widgets/categorizer.d.ts +55 -0
  298. package/dist/widgets/categorizer.js.flow +70 -0
  299. package/dist/widgets/cs-program.d.ts +48 -0
  300. package/dist/widgets/cs-program.js.flow +54 -0
  301. package/dist/widgets/definition.d.ts +42 -0
  302. package/dist/widgets/definition.js.flow +57 -0
  303. package/dist/widgets/dropdown.d.ts +51 -0
  304. package/dist/widgets/dropdown.js.flow +63 -0
  305. package/dist/widgets/explanation.d.ts +49 -0
  306. package/dist/widgets/explanation.js.flow +58 -0
  307. package/dist/widgets/expression.d.ts +90 -0
  308. package/dist/widgets/expression.js.flow +115 -0
  309. package/dist/widgets/graded-group-answer-bar.d.ts +13 -0
  310. package/dist/widgets/graded-group-answer-bar.js.flow +24 -0
  311. package/dist/widgets/graded-group-set.d.ts +52 -0
  312. package/dist/widgets/graded-group-set.js.flow +65 -0
  313. package/dist/widgets/graded-group.d.ts +66 -0
  314. package/dist/widgets/graded-group.js.flow +78 -0
  315. package/dist/widgets/grapher/util.d.ts +19 -0
  316. package/dist/widgets/grapher/util.js.flow +38 -0
  317. package/dist/widgets/grapher.d.ts +63 -0
  318. package/dist/widgets/grapher.js.flow +93 -0
  319. package/dist/widgets/group.d.ts +51 -0
  320. package/dist/widgets/group.js.flow +60 -0
  321. package/dist/widgets/iframe.d.ts +52 -0
  322. package/dist/widgets/iframe.js.flow +53 -0
  323. package/dist/widgets/image.d.ts +59 -0
  324. package/dist/widgets/image.js.flow +73 -0
  325. package/dist/widgets/input-number.d.ts +75 -0
  326. package/dist/widgets/input-number.js.flow +94 -0
  327. package/dist/widgets/interaction/arrow-picker.d.ts +12 -0
  328. package/dist/widgets/interaction/arrow-picker.js.flow +21 -0
  329. package/dist/widgets/interaction/color-picker.d.ts +14 -0
  330. package/dist/widgets/interaction/color-picker.js.flow +23 -0
  331. package/dist/widgets/interaction/dash-picker.d.ts +12 -0
  332. package/dist/widgets/interaction/dash-picker.js.flow +21 -0
  333. package/dist/widgets/interaction/element-container.d.ts +21 -0
  334. package/dist/widgets/interaction/element-container.js.flow +33 -0
  335. package/dist/widgets/interaction.d.ts +51 -0
  336. package/dist/widgets/interaction.js.flow +60 -0
  337. package/dist/widgets/interactive-graph.d.ts +180 -0
  338. package/dist/widgets/interactive-graph.js.flow +242 -0
  339. package/dist/widgets/label-image/answer-choices.d.ts +51 -0
  340. package/dist/widgets/label-image/answer-choices.js.flow +55 -0
  341. package/dist/widgets/label-image/marker.d.ts +28 -0
  342. package/dist/widgets/label-image/marker.js.flow +33 -0
  343. package/dist/widgets/label-image/types.d.ts +14 -0
  344. package/dist/widgets/label-image/types.js.flow +23 -0
  345. package/dist/widgets/label-image.d.ts +113 -0
  346. package/dist/widgets/label-image.js.flow +142 -0
  347. package/dist/widgets/lights-puzzle.d.ts +47 -0
  348. package/dist/widgets/lights-puzzle.js.flow +58 -0
  349. package/dist/widgets/matcher.d.ts +82 -0
  350. package/dist/widgets/matcher.js.flow +101 -0
  351. package/dist/widgets/matrix.d.ts +65 -0
  352. package/dist/widgets/matrix.js.flow +80 -0
  353. package/dist/widgets/measurer.d.ts +21 -0
  354. package/dist/widgets/measurer.js.flow +30 -0
  355. package/dist/widgets/molecule/molecule-drawing.d.ts +5 -0
  356. package/dist/widgets/molecule/molecule-drawing.js.flow +11 -0
  357. package/dist/widgets/molecule/molecule-layout.d.ts +82 -0
  358. package/dist/widgets/molecule/molecule-layout.js.flow +96 -0
  359. package/dist/widgets/molecule/smiles-parser.d.ts +19 -0
  360. package/dist/widgets/molecule/smiles-parser.js.flow +26 -0
  361. package/dist/widgets/molecule.d.ts +51 -0
  362. package/dist/widgets/molecule.js.flow +60 -0
  363. package/dist/widgets/number-line.d.ts +90 -0
  364. package/dist/widgets/number-line.js.flow +102 -0
  365. package/dist/widgets/numeric-input.d.ts +80 -0
  366. package/dist/widgets/numeric-input.js.flow +109 -0
  367. package/dist/widgets/orderer.d.ts +69 -0
  368. package/dist/widgets/orderer.js.flow +81 -0
  369. package/dist/widgets/passage/passage-markdown.d.ts +22 -0
  370. package/dist/widgets/passage/passage-markdown.js.flow +33 -0
  371. package/dist/widgets/passage-ref-target.d.ts +41 -0
  372. package/dist/widgets/passage-ref-target.js.flow +52 -0
  373. package/dist/widgets/passage-ref.d.ts +65 -0
  374. package/dist/widgets/passage-ref.js.flow +85 -0
  375. package/dist/widgets/passage.d.ts +125 -0
  376. package/dist/widgets/passage.js.flow +157 -0
  377. package/dist/widgets/plotter.d.ts +68 -0
  378. package/dist/widgets/plotter.js.flow +78 -0
  379. package/dist/widgets/radio/base-radio.d.ts +38 -0
  380. package/dist/widgets/radio/base-radio.js.flow +44 -0
  381. package/dist/widgets/radio/choice-a11y-text.d.ts +2 -0
  382. package/dist/widgets/radio/choice-a11y-text.js.flow +14 -0
  383. package/dist/widgets/radio/choice-icon/choice-icon.d.ts +16 -0
  384. package/dist/widgets/radio/choice-icon/choice-icon.js.flow +22 -0
  385. package/dist/widgets/radio/choice-icon/cross-out-line.d.ts +9 -0
  386. package/dist/widgets/radio/choice-icon/cross-out-line.js.flow +16 -0
  387. package/dist/widgets/radio/choice-icon/shared-styles.d.ts +5 -0
  388. package/dist/widgets/radio/choice-icon/shared-styles.js.flow +11 -0
  389. package/dist/widgets/radio/choice-none-above.d.ts +6 -0
  390. package/dist/widgets/radio/choice-none-above.js.flow +16 -0
  391. package/dist/widgets/radio/choice.d.ts +23 -0
  392. package/dist/widgets/radio/choice.js.flow +32 -0
  393. package/dist/widgets/radio/choice.jsx.fixture.d.ts +1 -0
  394. package/dist/widgets/radio/choice.jsx.fixture.js.flow +7 -0
  395. package/dist/widgets/radio/focus-ring.d.ts +12 -0
  396. package/dist/widgets/radio/focus-ring.js.flow +15 -0
  397. package/dist/widgets/radio/option-status.d.ts +17 -0
  398. package/dist/widgets/radio/option-status.js.flow +16 -0
  399. package/dist/widgets/radio/util.d.ts +6 -0
  400. package/dist/widgets/radio/util.js.flow +12 -0
  401. package/dist/widgets/radio/widget.d.ts +62 -0
  402. package/dist/widgets/radio/widget.js.flow +80 -0
  403. package/dist/widgets/radio.d.ts +22 -0
  404. package/dist/widgets/radio.js.flow +31 -0
  405. package/dist/widgets/reaction-diagram.d.ts +37 -0
  406. package/dist/widgets/reaction-diagram.js.flow +46 -0
  407. package/dist/widgets/sequence.d.ts +79 -0
  408. package/dist/widgets/sequence.js.flow +100 -0
  409. package/dist/widgets/simulator.d.ts +89 -0
  410. package/dist/widgets/simulator.js.flow +106 -0
  411. package/dist/widgets/sorter.d.ts +82 -0
  412. package/dist/widgets/sorter.js.flow +101 -0
  413. package/dist/widgets/table.d.ts +56 -0
  414. package/dist/widgets/table.js.flow +67 -0
  415. package/dist/widgets/transformer.d.ts +94 -0
  416. package/dist/widgets/transformer.js.flow +127 -0
  417. package/dist/widgets/unit.d.ts +77 -0
  418. package/dist/widgets/unit.js.flow +93 -0
  419. package/dist/widgets/video-transcript-link.d.ts +12 -0
  420. package/dist/widgets/video-transcript-link.js.flow +15 -0
  421. package/dist/widgets/video.d.ts +48 -0
  422. package/dist/widgets/video.js.flow +57 -0
  423. package/dist/widgets.d.ts +73 -0
  424. package/dist/widgets.js.flow +108 -0
  425. package/dist/zoom.d.ts +1 -0
  426. package/dist/zoom.js.flow +7 -0
  427. package/package.json +8 -8
  428. package/src/__stories__/hints-renderer.stories.tsx +58 -0
  429. package/src/__stories__/item-renderer.stories.tsx +29 -0
  430. package/src/__stories__/server-item-renderer.stories.tsx +29 -0
  431. package/src/__testdata__/graphie.testdata.ts +51 -0
  432. package/src/__testdata__/item-renderer.testdata.ts +160 -0
  433. package/src/__testdata__/renderer.testdata.ts +122 -0
  434. package/src/__tests__/a11y.test.ts +303 -0
  435. package/src/__tests__/item-renderer.test.tsx +891 -0
  436. package/src/__tests__/jipt-paragraphs.test.ts +32 -0
  437. package/src/__tests__/mock-asset-loading-widget.tsx +56 -0
  438. package/src/__tests__/mock-widget.tsx +33 -0
  439. package/src/__tests__/perseus-markdown.test.ts +764 -0
  440. package/src/__tests__/renderability.test.ts +480 -0
  441. package/src/__tests__/renderer-api.test.tsx +328 -0
  442. package/src/__tests__/renderer.test.tsx +1802 -0
  443. package/src/__tests__/server-item-renderer.test.tsx +518 -0
  444. package/src/__tests__/test-items/image-item.ts +24 -0
  445. package/src/__tests__/test-items/input-number-1-item.ts +26 -0
  446. package/src/__tests__/test-items/input-number-2-item.ts +38 -0
  447. package/src/__tests__/test-items/table-item.ts +29 -0
  448. package/src/__tests__/tex-wrangler.test.ts +82 -0
  449. package/src/__tests__/util.test.ts +40 -0
  450. package/src/a11y.ts +45 -0
  451. package/src/all-widgets.ts +9 -0
  452. package/src/article-renderer.tsx +215 -0
  453. package/src/asset-context.ts +30 -0
  454. package/src/basic-widgets.ts +16 -0
  455. package/src/components/__stories__/button-group.stories.tsx +59 -0
  456. package/src/components/__stories__/fixed-to-responsive.stories.tsx +143 -0
  457. package/src/components/__stories__/graph.stories.tsx +30 -0
  458. package/src/components/__stories__/graphie.stories.tsx +35 -0
  459. package/src/components/__stories__/hud.stories.tsx +39 -0
  460. package/src/components/__stories__/icon.stories.tsx +63 -0
  461. package/src/components/__stories__/image-loader.stories.tsx +62 -0
  462. package/src/components/__stories__/info-tip.stories.tsx +35 -0
  463. package/src/components/__stories__/inline-icon.stories.tsx +44 -0
  464. package/src/components/__stories__/input-with-examples.stories.tsx +57 -0
  465. package/src/components/__stories__/lint.stories.tsx +51 -0
  466. package/src/components/__stories__/math-input.stories.tsx +34 -0
  467. package/src/components/__stories__/math-output.stories.tsx +25 -0
  468. package/src/components/__stories__/multi-button-group.stories.tsx +70 -0
  469. package/src/components/__stories__/number-input.stories.tsx +43 -0
  470. package/src/components/__stories__/prop-check-box.stories.tsx +65 -0
  471. package/src/components/__stories__/range-input.stories.tsx +31 -0
  472. package/src/components/__stories__/simple-keypad-input.stories.tsx +29 -0
  473. package/src/components/__stories__/sortable.stories.tsx +77 -0
  474. package/src/components/__stories__/stub-tag-editor.stories.tsx +49 -0
  475. package/src/components/__stories__/svg-image.stories.tsx +82 -0
  476. package/src/components/__stories__/tex.stories.tsx +25 -0
  477. package/src/components/__stories__/text-buttons.stories.tsx +66 -0
  478. package/src/components/__stories__/text-input.stories.tsx +39 -0
  479. package/src/components/__stories__/text-list-editor.stories.tsx +34 -0
  480. package/src/components/__stories__/zoomable-tex.stories.tsx +39 -0
  481. package/src/components/__stories__/zoomable.stories.tsx +43 -0
  482. package/src/components/__testdata__/sorter.testdata.ts +19 -0
  483. package/src/components/__tests__/number-input.test.tsx +128 -0
  484. package/src/components/__tests__/sortable.test.tsx +234 -0
  485. package/src/components/__tests__/sorter.test.tsx +111 -0
  486. package/src/components/__tests__/zoomable.test.tsx +399 -0
  487. package/src/components/button-group.tsx +130 -0
  488. package/src/components/constants.ts +14 -0
  489. package/src/components/fixed-to-responsive.tsx +165 -0
  490. package/src/components/graph.tsx +421 -0
  491. package/src/components/graphie-classes.ts +153 -0
  492. package/src/components/graphie-movables.ts +338 -0
  493. package/src/components/graphie.tsx +357 -0
  494. package/src/components/highlighting/highlightable-content.tsx +243 -0
  495. package/src/components/highlighting/highlights.ts +207 -0
  496. package/src/components/highlighting/ranges.ts +304 -0
  497. package/src/components/highlighting/types.ts +73 -0
  498. package/src/components/highlighting/ui/highlight-renderer.tsx +175 -0
  499. package/src/components/highlighting/ui/highlight-set-renderer.tsx +188 -0
  500. package/src/components/highlighting/ui/highlight-tooltip.tsx +141 -0
  501. package/src/components/highlighting/ui/highlighting-ui.tsx +153 -0
  502. package/src/components/highlighting/ui/selection-tracker.tsx +189 -0
  503. package/src/components/highlighting/ui/types.ts +21 -0
  504. package/src/components/highlighting/ui/util.ts +165 -0
  505. package/src/components/highlighting/word-indexer.tsx +156 -0
  506. package/src/components/hud.tsx +178 -0
  507. package/src/components/icon.tsx +140 -0
  508. package/src/components/image-loader.tsx +176 -0
  509. package/src/components/info-tip/info-tip.tsx +144 -0
  510. package/src/components/info-tip.tsx +40 -0
  511. package/src/components/inline-icon.tsx +77 -0
  512. package/src/components/input-with-examples.tsx +249 -0
  513. package/src/components/lint.tsx +453 -0
  514. package/src/components/math-input.tsx +299 -0
  515. package/src/components/math-output.tsx +128 -0
  516. package/src/components/multi-button-group.tsx +135 -0
  517. package/src/components/number-input.tsx +250 -0
  518. package/src/components/prop-check-box.tsx +80 -0
  519. package/src/components/range-input.tsx +60 -0
  520. package/src/components/simple-keypad-input.tsx +88 -0
  521. package/src/components/sortable.tsx +914 -0
  522. package/src/components/stub-tag-editor.tsx +53 -0
  523. package/src/components/svg-image.tsx +777 -0
  524. package/src/components/tex-buttons.tsx +321 -0
  525. package/src/components/tex.tsx +67 -0
  526. package/src/components/text-input.tsx +128 -0
  527. package/src/components/text-list-editor.tsx +169 -0
  528. package/src/components/tooltip.tsx +392 -0
  529. package/src/components/visibility-observer/__stories__/visibility-observer.stories.tsx +143 -0
  530. package/src/components/visibility-observer/create-visibility-observer.ts +108 -0
  531. package/src/components/visibility-observer/get-scroll-parent.ts +46 -0
  532. package/src/components/visibility-observer/visibility-observer.tsx +124 -0
  533. package/src/components/zoomable-tex.tsx +78 -0
  534. package/src/components/zoomable.tsx +300 -0
  535. package/src/components.ts +16 -0
  536. package/src/definition-context.tsx +60 -0
  537. package/src/dependencies.ts +21 -0
  538. package/src/error-boundary.tsx +50 -0
  539. package/src/extra-widgets.ts +75 -0
  540. package/src/hint-renderer.tsx +149 -0
  541. package/src/hints-renderer.tsx +377 -0
  542. package/src/icon-paths.ts +119 -0
  543. package/src/index.ts +158 -0
  544. package/src/init.ts +54 -0
  545. package/src/interaction-tracker.ts +61 -0
  546. package/src/interactive2/__tests__/movable-mock.ts +43 -0
  547. package/src/interactive2/__tests__/movable-point.test.ts +145 -0
  548. package/src/interactive2/interactive-util.ts +155 -0
  549. package/src/interactive2/movable-helper-methods.ts +161 -0
  550. package/src/interactive2/movable-line-options.ts +419 -0
  551. package/src/interactive2/movable-line.ts +318 -0
  552. package/src/interactive2/movable-point-options.ts +212 -0
  553. package/src/interactive2/movable-point.tsx +593 -0
  554. package/src/interactive2/movable-polygon-options.ts +390 -0
  555. package/src/interactive2/movable-polygon.ts +368 -0
  556. package/src/interactive2/movable.ts +275 -0
  557. package/src/interactive2/objective_.ts +79 -0
  558. package/src/interactive2/types.ts +2 -0
  559. package/src/interactive2/wrapped-defaults.ts +87 -0
  560. package/src/interactive2/wrapped-ellipse.ts +94 -0
  561. package/src/interactive2/wrapped-line.ts +116 -0
  562. package/src/interactive2/wrapped-path.ts +51 -0
  563. package/src/interactive2.ts +73 -0
  564. package/src/item-renderer.tsx +514 -0
  565. package/src/item-version.ts +10 -0
  566. package/src/jipt-paragraphs.ts +49 -0
  567. package/src/jquery.mobile.vmouse.js +0 -1
  568. package/src/keypad-context.ts +34 -0
  569. package/src/loading-context.ts +21 -0
  570. package/src/logging/log.test.ts +39 -0
  571. package/src/logging/log.ts +97 -0
  572. package/src/mixins/__tests__/widget-prop-denylist.test.ts +21 -0
  573. package/src/mixins/changeable.ts +133 -0
  574. package/src/mixins/editor-jsonify.ts +13 -0
  575. package/src/mixins/provide-keypad.tsx +144 -0
  576. package/src/mixins/widget-jsonify-deprecated.ts +23 -0
  577. package/src/mixins/widget-prop-denylist.ts +48 -0
  578. package/src/multi-items/__stories__/multi-renderer.stories.tsx +87 -0
  579. package/src/multi-items/__testdata__/multi-renderer.testdata.ts +172 -0
  580. package/src/multi-items/__tests__/items.test.ts +250 -0
  581. package/src/multi-items/__tests__/multi-renderer.test.tsx +910 -0
  582. package/src/multi-items/__tests__/prop-type-builders.test.ts +133 -0
  583. package/src/multi-items/__tests__/shapes.test.ts +43 -0
  584. package/src/multi-items/__tests__/trees.test.ts +325 -0
  585. package/src/multi-items/item-types.js.flow +55 -0
  586. package/src/multi-items/item-types.ts +56 -0
  587. package/src/multi-items/items.ts +176 -0
  588. package/src/multi-items/multi-renderer.tsx +564 -0
  589. package/src/multi-items/prop-type-builders.ts +106 -0
  590. package/src/multi-items/shape-types.ts +52 -0
  591. package/src/multi-items/shapes.ts +52 -0
  592. package/src/multi-items/tree-types.ts +47 -0
  593. package/src/multi-items/trees.ts +360 -0
  594. package/src/multi-items.ts +75 -0
  595. package/src/perseus-api.tsx +188 -0
  596. package/src/perseus-env.ts +27 -0
  597. package/src/perseus-error.ts +17 -0
  598. package/src/perseus-markdown.tsx +407 -0
  599. package/src/perseus-types.ts +1474 -0
  600. package/src/question-paragraph.tsx +29 -0
  601. package/src/renderability.ts +109 -0
  602. package/src/renderer.tsx +1992 -0
  603. package/src/server-item-renderer.tsx +465 -0
  604. package/src/sigfigs.ts +490 -0
  605. package/src/styles/constants.ts +94 -0
  606. package/src/styles/global-constants.ts +343 -0
  607. package/src/styles/global-styles.ts +306 -0
  608. package/src/styles/media-queries.ts +47 -0
  609. package/src/styles/shared.ts +130 -0
  610. package/src/tex-wrangler.ts +182 -0
  611. package/src/translation-linter.ts +126 -0
  612. package/src/traversal.ts +138 -0
  613. package/src/types.ts +468 -0
  614. package/src/util/a11y.ts +23 -0
  615. package/src/util/answer-types.test.ts +114 -0
  616. package/src/util/answer-types.ts +876 -0
  617. package/src/util/colors.ts +93 -0
  618. package/src/util/fix-passage-refs.ts +121 -0
  619. package/src/util/graph-utils.ts +15 -0
  620. package/src/util/graphie.ts +1617 -0
  621. package/src/util/interactive.ts +4191 -0
  622. package/src/util/katex-preprocess.ts +14 -0
  623. package/src/util/math.ts +289 -0
  624. package/src/util/mobile-native-utils.test.ts +22 -0
  625. package/src/util/mobile-native-utils.ts +12 -0
  626. package/src/util/react-render.tsx +27 -0
  627. package/src/util/register-all-widgets-for-testing.ts +11 -0
  628. package/src/util/scroll-utils.ts +155 -0
  629. package/src/util/sizing-utils.ts +46 -0
  630. package/src/util/tex.ts +208 -0
  631. package/src/util/url-utils.ts +34 -0
  632. package/src/util.ts +1003 -0
  633. package/src/version.ts +11 -0
  634. package/src/widget-container.tsx +175 -0
  635. package/src/widgets/__stories__/categorizer.stories.tsx +14 -0
  636. package/src/widgets/__stories__/cs-program.stories.tsx +14 -0
  637. package/src/widgets/__stories__/definition.stories.tsx +111 -0
  638. package/src/widgets/__stories__/dropdown.stories.tsx +14 -0
  639. package/src/widgets/__stories__/explanation.stories.tsx +18 -0
  640. package/src/widgets/__stories__/expression.stories.tsx +29 -0
  641. package/src/widgets/__stories__/graded-group-set.stories.tsx +31 -0
  642. package/src/widgets/__stories__/graded-group.stories.tsx +31 -0
  643. package/src/widgets/__stories__/grapher.stories.tsx +60 -0
  644. package/src/widgets/__stories__/group.stories.tsx +14 -0
  645. package/src/widgets/__stories__/iframe.stories.tsx +14 -0
  646. package/src/widgets/__stories__/image.stories.tsx +61 -0
  647. package/src/widgets/__stories__/input-number.stories.tsx +110 -0
  648. package/src/widgets/__stories__/interaction.stories.tsx +14 -0
  649. package/src/widgets/__stories__/interactive-graph.stories.tsx +60 -0
  650. package/src/widgets/__stories__/matcher.stories.tsx +14 -0
  651. package/src/widgets/__stories__/matrix.stories.tsx +14 -0
  652. package/src/widgets/__stories__/number-line.stories.tsx +14 -0
  653. package/src/widgets/__stories__/numeric-input.stories.tsx +107 -0
  654. package/src/widgets/__stories__/on-screen-keypad.stories.tsx +120 -0
  655. package/src/widgets/__stories__/orderer.stories.tsx +14 -0
  656. package/src/widgets/__stories__/passage-ref.stories.tsx +22 -0
  657. package/src/widgets/__stories__/passage.stories.tsx +32 -0
  658. package/src/widgets/__stories__/radio.stories.tsx +88 -0
  659. package/src/widgets/__stories__/sorter.stories.tsx +14 -0
  660. package/src/widgets/__stories__/transformer.stories.tsx +14 -0
  661. package/src/widgets/__stories__/unit.stories.tsx +30 -0
  662. package/src/widgets/__stories__/video-transcript-link.stories.tsx +27 -0
  663. package/src/widgets/__stories__/video.stories.tsx +14 -0
  664. package/src/widgets/__testdata__/base-radio.testdata.ts +21 -0
  665. package/src/widgets/__testdata__/categorizer.testdata.ts +49 -0
  666. package/src/widgets/__testdata__/cs-program.testdata.ts +27 -0
  667. package/src/widgets/__testdata__/dropdown.testdata.ts +33 -0
  668. package/src/widgets/__testdata__/explanation.testdata.ts +55 -0
  669. package/src/widgets/__testdata__/expression.testdata.ts +94 -0
  670. package/src/widgets/__testdata__/graded-group-set.testdata.ts +356 -0
  671. package/src/widgets/__testdata__/graded-group.testdata.ts +77 -0
  672. package/src/widgets/__testdata__/grapher.testdata.ts +374 -0
  673. package/src/widgets/__testdata__/group.testdata.ts +155 -0
  674. package/src/widgets/__testdata__/iframe.testdata.ts +35 -0
  675. package/src/widgets/__testdata__/image.testdata.ts +36 -0
  676. package/src/widgets/__testdata__/input-number.testdata.ts +72 -0
  677. package/src/widgets/__testdata__/interaction.testdata.ts +262 -0
  678. package/src/widgets/__testdata__/interactive-graph.testdata.ts +644 -0
  679. package/src/widgets/__testdata__/matcher.testdata.ts +33 -0
  680. package/src/widgets/__testdata__/matrix.testdata.ts +28 -0
  681. package/src/widgets/__testdata__/number-line.testdata.ts +30 -0
  682. package/src/widgets/__testdata__/numeric-input.testdata.ts +266 -0
  683. package/src/widgets/__testdata__/orderer.testdata.ts +57 -0
  684. package/src/widgets/__testdata__/passage-ref.testdata.ts +101 -0
  685. package/src/widgets/__testdata__/passage.testdata.ts +95 -0
  686. package/src/widgets/__testdata__/radio.testdata.ts +261 -0
  687. package/src/widgets/__testdata__/sorter.testdata.ts +19 -0
  688. package/src/widgets/__testdata__/transformer.testdata.ts +108 -0
  689. package/src/widgets/__testdata__/video.testdata.ts +21 -0
  690. package/src/widgets/__tests__/__snapshots__/input-number.test.ts.snap +497 -0
  691. package/src/widgets/__tests__/__snapshots__/unit.test.tsx.snap +20 -0
  692. package/src/widgets/__tests__/categorizer.test.ts +203 -0
  693. package/src/widgets/__tests__/cs-program.test.ts +43 -0
  694. package/src/widgets/__tests__/definition.test.ts +136 -0
  695. package/src/widgets/__tests__/dropdown.test.ts +105 -0
  696. package/src/widgets/__tests__/explanation.test.ts +198 -0
  697. package/src/widgets/__tests__/expression.test.ts +431 -0
  698. package/src/widgets/__tests__/graded-group-set-jipt.test.ts +30 -0
  699. package/src/widgets/__tests__/graded-group-set.test.ts +288 -0
  700. package/src/widgets/__tests__/graded-group.test.ts +232 -0
  701. package/src/widgets/__tests__/grapher.cypress.ts +576 -0
  702. package/src/widgets/__tests__/grapher.test.ts +33 -0
  703. package/src/widgets/__tests__/group.test.tsx +512 -0
  704. package/src/widgets/__tests__/iframe.test.ts +45 -0
  705. package/src/widgets/__tests__/image.test.ts +62 -0
  706. package/src/widgets/__tests__/input-number.test.ts +354 -0
  707. package/src/widgets/__tests__/interaction.test.ts +31 -0
  708. package/src/widgets/__tests__/interactive-graph.cypress.ts +815 -0
  709. package/src/widgets/__tests__/interactive-graph.test.ts +106 -0
  710. package/src/widgets/__tests__/matcher.test.tsx +152 -0
  711. package/src/widgets/__tests__/matrix.test.ts +82 -0
  712. package/src/widgets/__tests__/number-line.test.ts +79 -0
  713. package/src/widgets/__tests__/numeric-input.test.ts +502 -0
  714. package/src/widgets/__tests__/orderer.test.ts +73 -0
  715. package/src/widgets/__tests__/passage-ref.test.ts +168 -0
  716. package/src/widgets/__tests__/passage.test.tsx +224 -0
  717. package/src/widgets/__tests__/radio/base-radio.test.tsx +470 -0
  718. package/src/widgets/__tests__/radio/choice-icon.test.tsx +90 -0
  719. package/src/widgets/__tests__/radio/choice.test.tsx +310 -0
  720. package/src/widgets/__tests__/radio/focus-ring.test.tsx +23 -0
  721. package/src/widgets/__tests__/radio/option-status.test.tsx +77 -0
  722. package/src/widgets/__tests__/radio.test.ts +807 -0
  723. package/src/widgets/__tests__/renderQuestion.tsx +77 -0
  724. package/src/widgets/__tests__/unit.test.tsx +168 -0
  725. package/src/widgets/__tests__/video.test.ts +53 -0
  726. package/src/widgets/categorizer.tsx +343 -0
  727. package/src/widgets/cs-program.tsx +227 -0
  728. package/src/widgets/definition.tsx +121 -0
  729. package/src/widgets/dropdown.tsx +142 -0
  730. package/src/widgets/explanation.tsx +317 -0
  731. package/src/widgets/expression.tsx +647 -0
  732. package/src/widgets/graded-group-answer-bar.tsx +142 -0
  733. package/src/widgets/graded-group-set.tsx +296 -0
  734. package/src/widgets/graded-group.tsx +466 -0
  735. package/src/widgets/grapher/util.tsx +803 -0
  736. package/src/widgets/grapher.tsx +674 -0
  737. package/src/widgets/group.tsx +196 -0
  738. package/src/widgets/iframe.tsx +195 -0
  739. package/src/widgets/image.tsx +309 -0
  740. package/src/widgets/input-number.tsx +413 -0
  741. package/src/widgets/interaction/arrow-picker.tsx +38 -0
  742. package/src/widgets/interaction/color-picker.tsx +69 -0
  743. package/src/widgets/interaction/dash-picker.tsx +45 -0
  744. package/src/widgets/interaction/element-container.tsx +101 -0
  745. package/src/widgets/interaction.tsx +826 -0
  746. package/src/widgets/interactive-graph.tsx +2921 -0
  747. package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +98 -0
  748. package/src/widgets/label-image/__stories__/marker.stories.tsx +181 -0
  749. package/src/widgets/label-image/answer-choices.tsx +300 -0
  750. package/src/widgets/label-image/marker.tsx +364 -0
  751. package/src/widgets/label-image/types.ts +26 -0
  752. package/src/widgets/label-image.test.ts +840 -0
  753. package/src/widgets/label-image.tsx +849 -0
  754. package/src/widgets/lights-puzzle.tsx +359 -0
  755. package/src/widgets/matcher.tsx +278 -0
  756. package/src/widgets/matrix.tsx +637 -0
  757. package/src/widgets/measurer.tsx +217 -0
  758. package/src/widgets/molecule/__tests__/layout.test.ts +162 -0
  759. package/src/widgets/molecule/__tests__/parser.test.ts +155 -0
  760. package/src/widgets/molecule/molecule-drawing.ts +173 -0
  761. package/src/widgets/molecule/molecule-layout.ts +362 -0
  762. package/src/widgets/molecule/smiles-parser.ts +296 -0
  763. package/src/widgets/molecule.tsx +172 -0
  764. package/src/widgets/number-line.tsx +864 -0
  765. package/src/widgets/numeric-input.tsx +563 -0
  766. package/src/widgets/orderer.tsx +788 -0
  767. package/src/widgets/passage/__tests__/passage-markdown.test.ts +376 -0
  768. package/src/widgets/passage/passage-markdown.tsx +475 -0
  769. package/src/widgets/passage-ref-target.tsx +73 -0
  770. package/src/widgets/passage-ref.tsx +215 -0
  771. package/src/widgets/passage.tsx +584 -0
  772. package/src/widgets/plotter.tsx +1204 -0
  773. package/src/widgets/radio/__stories__/base-radio.stories.tsx +204 -0
  774. package/src/widgets/radio/__stories__/choice-icon.stories.tsx +168 -0
  775. package/src/widgets/radio/__stories__/choice-none-above.stories.tsx +40 -0
  776. package/src/widgets/radio/__stories__/choice.stories.tsx +137 -0
  777. package/src/widgets/radio/__stories__/focus-ring.stories.tsx +43 -0
  778. package/src/widgets/radio/__stories__/option-status.stories.tsx +105 -0
  779. package/src/widgets/radio/base-radio.tsx +509 -0
  780. package/src/widgets/radio/choice-a11y-text.ts +61 -0
  781. package/src/widgets/radio/choice-icon/choice-icon.tsx +217 -0
  782. package/src/widgets/radio/choice-icon/cross-out-line.tsx +53 -0
  783. package/src/widgets/radio/choice-icon/shared-styles.ts +15 -0
  784. package/src/widgets/radio/choice-none-above.tsx +56 -0
  785. package/src/widgets/radio/choice.jsx.fixture.ts +45 -0
  786. package/src/widgets/radio/choice.tsx +358 -0
  787. package/src/widgets/radio/focus-ring.tsx +57 -0
  788. package/src/widgets/radio/option-status.tsx +100 -0
  789. package/src/widgets/radio/util.test.ts +18 -0
  790. package/src/widgets/radio/util.ts +31 -0
  791. package/src/widgets/radio/widget.tsx +521 -0
  792. package/src/widgets/radio.ts +157 -0
  793. package/src/widgets/reaction-diagram.tsx +144 -0
  794. package/src/widgets/sequence.tsx +137 -0
  795. package/src/widgets/simulator.tsx +831 -0
  796. package/src/widgets/sorter.tsx +154 -0
  797. package/src/widgets/table.tsx +393 -0
  798. package/src/widgets/transformer.tsx +2951 -0
  799. package/src/widgets/unit.tsx +374 -0
  800. package/src/widgets/video-transcript-link.test.tsx +213 -0
  801. package/src/widgets/video-transcript-link.tsx +84 -0
  802. package/src/widgets/video.tsx +124 -0
  803. package/src/widgets.ts +444 -0
  804. package/src/zoom.ts +558 -0
  805. package/tsconfig.json +25 -0
  806. package/tsconfig.tsbuildinfo +1 -0
  807. package/src/__stories__/hints-renderer.stories.jsx +0 -60
  808. package/src/__stories__/item-renderer.stories.jsx +0 -27
  809. package/src/__stories__/server-item-renderer.stories.jsx +0 -27
  810. package/src/__testdata__/graphie_testdata.js +0 -53
  811. package/src/__testdata__/item-renderer_testdata.js +0 -161
  812. package/src/__testdata__/renderer_testdata.js +0 -123
  813. package/src/__tests__/a11y_test.jsx +0 -304
  814. package/src/__tests__/item-renderer_test.jsx +0 -892
  815. package/src/__tests__/jipt-paragraphs_test.js +0 -34
  816. package/src/__tests__/mock-asset-loading-widget.jsx +0 -57
  817. package/src/__tests__/mock-widget.jsx +0 -35
  818. package/src/__tests__/perseus-markdown_test.jsx +0 -747
  819. package/src/__tests__/renderability_test.jsx +0 -481
  820. package/src/__tests__/renderer-api_test.jsx +0 -309
  821. package/src/__tests__/renderer_test.jsx +0 -1792
  822. package/src/__tests__/server-item-renderer_test.jsx +0 -516
  823. package/src/__tests__/test-items/image-item.js +0 -25
  824. package/src/__tests__/test-items/input-number-1-item.js +0 -27
  825. package/src/__tests__/test-items/input-number-2-item.js +0 -39
  826. package/src/__tests__/test-items/table-item.js +0 -30
  827. package/src/__tests__/tex-wrangler_test.js +0 -83
  828. package/src/__tests__/util_test.js +0 -41
  829. package/src/a11y.js +0 -46
  830. package/src/all-widgets.js +0 -9
  831. package/src/article-renderer.jsx +0 -214
  832. package/src/asset-context.js +0 -30
  833. package/src/basic-widgets.js +0 -13
  834. package/src/components/__stories__/button-group.stories.jsx +0 -61
  835. package/src/components/__stories__/fixed-to-responsive.stories.jsx +0 -132
  836. package/src/components/__stories__/graph.stories.jsx +0 -27
  837. package/src/components/__stories__/graphie.stories.jsx +0 -32
  838. package/src/components/__stories__/hud.stories.jsx +0 -36
  839. package/src/components/__stories__/icon.stories.jsx +0 -56
  840. package/src/components/__stories__/image-loader.stories.jsx +0 -60
  841. package/src/components/__stories__/info-tip.stories.jsx +0 -33
  842. package/src/components/__stories__/inline-icon.stories.jsx +0 -39
  843. package/src/components/__stories__/input-with-examples.stories.jsx +0 -52
  844. package/src/components/__stories__/lint.stories.jsx +0 -40
  845. package/src/components/__stories__/math-input.stories.jsx +0 -29
  846. package/src/components/__stories__/math-output.stories.jsx +0 -24
  847. package/src/components/__stories__/multi-button-group.stories.jsx +0 -69
  848. package/src/components/__stories__/number-input.stories.jsx +0 -42
  849. package/src/components/__stories__/prop-check-box.stories.jsx +0 -62
  850. package/src/components/__stories__/range-input.stories.jsx +0 -28
  851. package/src/components/__stories__/simple-keypad-input.stories.jsx +0 -28
  852. package/src/components/__stories__/sortable.stories.jsx +0 -73
  853. package/src/components/__stories__/stub-tag-editor.stories.jsx +0 -44
  854. package/src/components/__stories__/svg-image.stories.jsx +0 -71
  855. package/src/components/__stories__/tex.stories.jsx +0 -24
  856. package/src/components/__stories__/text-buttons.stories.jsx +0 -51
  857. package/src/components/__stories__/text-input.stories.jsx +0 -34
  858. package/src/components/__stories__/text-list-editor.stories.jsx +0 -33
  859. package/src/components/__stories__/zoomable-tex.stories.jsx +0 -39
  860. package/src/components/__stories__/zoomable.stories.jsx +0 -40
  861. package/src/components/__testdata__/sorter_testdata.js +0 -20
  862. package/src/components/__tests__/number-input_test.jsx +0 -112
  863. package/src/components/__tests__/sortable_test.jsx +0 -234
  864. package/src/components/__tests__/sorter_test.jsx +0 -111
  865. package/src/components/__tests__/zoomable_test.jsx +0 -388
  866. package/src/components/button-group.jsx +0 -131
  867. package/src/components/constants.js +0 -15
  868. package/src/components/fixed-to-responsive.jsx +0 -165
  869. package/src/components/graph.jsx +0 -413
  870. package/src/components/graphie-classes.jsx +0 -148
  871. package/src/components/graphie-movables.jsx +0 -342
  872. package/src/components/graphie.jsx +0 -353
  873. package/src/components/highlighting/highlightable-content.jsx +0 -245
  874. package/src/components/highlighting/highlights.js +0 -208
  875. package/src/components/highlighting/ranges.js +0 -299
  876. package/src/components/highlighting/types.js +0 -73
  877. package/src/components/highlighting/ui/highlight-renderer.jsx +0 -179
  878. package/src/components/highlighting/ui/highlight-set-renderer.jsx +0 -190
  879. package/src/components/highlighting/ui/highlight-tooltip.jsx +0 -143
  880. package/src/components/highlighting/ui/highlighting-ui.jsx +0 -163
  881. package/src/components/highlighting/ui/selection-tracker.jsx +0 -184
  882. package/src/components/highlighting/ui/types.js +0 -21
  883. package/src/components/highlighting/ui/util.js +0 -166
  884. package/src/components/highlighting/word-indexer.jsx +0 -155
  885. package/src/components/hud.jsx +0 -179
  886. package/src/components/icon.jsx +0 -149
  887. package/src/components/image-loader.jsx +0 -175
  888. package/src/components/info-tip/info-tip.jsx +0 -146
  889. package/src/components/info-tip.jsx +0 -38
  890. package/src/components/inline-icon.jsx +0 -81
  891. package/src/components/input-with-examples.jsx +0 -248
  892. package/src/components/lint.jsx +0 -455
  893. package/src/components/math-input.jsx +0 -293
  894. package/src/components/math-output.jsx +0 -128
  895. package/src/components/multi-button-group.jsx +0 -137
  896. package/src/components/number-input.jsx +0 -253
  897. package/src/components/prop-check-box.jsx +0 -80
  898. package/src/components/range-input.jsx +0 -61
  899. package/src/components/simple-keypad-input.jsx +0 -88
  900. package/src/components/sortable.jsx +0 -872
  901. package/src/components/stub-tag-editor.jsx +0 -54
  902. package/src/components/svg-image.jsx +0 -765
  903. package/src/components/tex-buttons.jsx +0 -320
  904. package/src/components/tex.jsx +0 -70
  905. package/src/components/text-input.jsx +0 -133
  906. package/src/components/text-list-editor.jsx +0 -157
  907. package/src/components/tooltip.jsx +0 -392
  908. package/src/components/visibility-observer/__stories__/visibility-observer.stories.jsx +0 -140
  909. package/src/components/visibility-observer/get-scroll-parent.js +0 -45
  910. package/src/components/visibility-observer/visibility-observer.js +0 -109
  911. package/src/components/visibility-observer/visibility-observer.jsx +0 -123
  912. package/src/components/zoomable-tex.jsx +0 -70
  913. package/src/components/zoomable.jsx +0 -294
  914. package/src/components.js +0 -17
  915. package/src/definition-context.js +0 -59
  916. package/src/dependencies.js +0 -22
  917. package/src/error-boundary.jsx +0 -48
  918. package/src/extra-widgets.js +0 -75
  919. package/src/hint-renderer.jsx +0 -155
  920. package/src/hints-renderer.jsx +0 -367
  921. package/src/icon-paths.js +0 -120
  922. package/src/index.js +0 -159
  923. package/src/init.js +0 -49
  924. package/src/interaction-tracker.js +0 -60
  925. package/src/interactive2/__tests__/movable-mock.js +0 -48
  926. package/src/interactive2/__tests__/movable-point_test.js +0 -146
  927. package/src/interactive2/interactive-util.js +0 -152
  928. package/src/interactive2/movable-helper-methods.js +0 -160
  929. package/src/interactive2/movable-line-options.js +0 -392
  930. package/src/interactive2/movable-line.js +0 -322
  931. package/src/interactive2/movable-point-options.js +0 -190
  932. package/src/interactive2/movable-point.jsx +0 -597
  933. package/src/interactive2/movable-polygon-options.js +0 -351
  934. package/src/interactive2/movable-polygon.js +0 -368
  935. package/src/interactive2/movable.js +0 -273
  936. package/src/interactive2/objective_.js +0 -79
  937. package/src/interactive2/types.js +0 -3
  938. package/src/interactive2/wrapped-defaults.js +0 -86
  939. package/src/interactive2/wrapped-ellipse.js +0 -86
  940. package/src/interactive2/wrapped-line.js +0 -109
  941. package/src/interactive2/wrapped-path.js +0 -47
  942. package/src/interactive2.js +0 -91
  943. package/src/item-renderer.jsx +0 -514
  944. package/src/item-version.js +0 -12
  945. package/src/jipt-paragraphs.js +0 -52
  946. package/src/keypad-context.js +0 -33
  947. package/src/loading-context.js +0 -20
  948. package/src/logging/log.js +0 -107
  949. package/src/logging/log_test.js +0 -41
  950. package/src/mixins/__tests__/widget-prop-denylist_test.js +0 -23
  951. package/src/mixins/changeable.jsx +0 -115
  952. package/src/mixins/editor-jsonify.jsx +0 -13
  953. package/src/mixins/provide-keypad.jsx +0 -131
  954. package/src/mixins/widget-jsonify-deprecated.jsx +0 -23
  955. package/src/mixins/widget-prop-denylist.js +0 -49
  956. package/src/multi-items/__stories__/multi-renderer.stories.js +0 -88
  957. package/src/multi-items/__testdata__/multi-renderer_testdata.js +0 -174
  958. package/src/multi-items/__tests__/items_test.js +0 -245
  959. package/src/multi-items/__tests__/multi-renderer_test.js +0 -903
  960. package/src/multi-items/__tests__/prop-type-builders_test.js +0 -134
  961. package/src/multi-items/__tests__/shapes_test.js +0 -44
  962. package/src/multi-items/__tests__/trees_test.js +0 -316
  963. package/src/multi-items/items.js +0 -176
  964. package/src/multi-items/multi-renderer.jsx +0 -543
  965. package/src/multi-items/prop-type-builders.js +0 -105
  966. package/src/multi-items/shape-types.js +0 -47
  967. package/src/multi-items/shapes.js +0 -53
  968. package/src/multi-items/tree-types.js +0 -42
  969. package/src/multi-items/trees.js +0 -345
  970. package/src/multi-items.js +0 -76
  971. package/src/perseus-api.jsx +0 -221
  972. package/src/perseus-env.js +0 -26
  973. package/src/perseus-error.js +0 -19
  974. package/src/perseus-markdown.jsx +0 -408
  975. package/src/perseus-types.js +0 -1471
  976. package/src/question-paragraph.jsx +0 -30
  977. package/src/renderability.jsx +0 -108
  978. package/src/renderer.jsx +0 -1937
  979. package/src/server-item-renderer.jsx +0 -467
  980. package/src/sigfigs.jsx +0 -492
  981. package/src/styles/constants.js +0 -96
  982. package/src/styles/global-constants.js +0 -344
  983. package/src/styles/global-styles.js +0 -307
  984. package/src/styles/media-queries.js +0 -48
  985. package/src/styles/shared.js +0 -132
  986. package/src/tex-wrangler.js +0 -176
  987. package/src/translation-linter.js +0 -125
  988. package/src/traversal.jsx +0 -141
  989. package/src/types.js +0 -488
  990. package/src/util/a11y.js +0 -24
  991. package/src/util/answer-types.js +0 -861
  992. package/src/util/answer-types_test.js +0 -115
  993. package/src/util/colors.js +0 -94
  994. package/src/util/fix-passage-refs.jsx +0 -122
  995. package/src/util/graph-utils.js +0 -16
  996. package/src/util/graphie.js +0 -1586
  997. package/src/util/interactive.js +0 -4078
  998. package/src/util/katex-preprocess.js +0 -16
  999. package/src/util/math.js +0 -289
  1000. package/src/util/mobile-native-utils.js +0 -14
  1001. package/src/util/mobile-native-utils_test.js +0 -24
  1002. package/src/util/react-render.js +0 -27
  1003. package/src/util/register-all-widgets-for-testing.js +0 -12
  1004. package/src/util/scroll-utils.js +0 -162
  1005. package/src/util/sizing-utils.js +0 -46
  1006. package/src/util/tex.js +0 -203
  1007. package/src/util/url-utils.js +0 -36
  1008. package/src/util.js +0 -984
  1009. package/src/version.js +0 -11
  1010. package/src/widget-container.jsx +0 -178
  1011. package/src/widgets/__stories__/categorizer.stories.jsx +0 -15
  1012. package/src/widgets/__stories__/cs-program.stories.jsx +0 -15
  1013. package/src/widgets/__stories__/definition.stories.jsx +0 -108
  1014. package/src/widgets/__stories__/dropdown.stories.jsx +0 -15
  1015. package/src/widgets/__stories__/explanation.stories.jsx +0 -19
  1016. package/src/widgets/__stories__/expression.stories.jsx +0 -26
  1017. package/src/widgets/__stories__/graded-group-set.stories.jsx +0 -32
  1018. package/src/widgets/__stories__/graded-group.stories.jsx +0 -32
  1019. package/src/widgets/__stories__/grapher.stories.jsx +0 -47
  1020. package/src/widgets/__stories__/group.stories.jsx +0 -15
  1021. package/src/widgets/__stories__/iframe.stories.jsx +0 -15
  1022. package/src/widgets/__stories__/image.stories.jsx +0 -62
  1023. package/src/widgets/__stories__/input-number.stories.jsx +0 -102
  1024. package/src/widgets/__stories__/interaction.stories.jsx +0 -15
  1025. package/src/widgets/__stories__/interactive-graph.stories.jsx +0 -61
  1026. package/src/widgets/__stories__/matcher.stories.jsx +0 -15
  1027. package/src/widgets/__stories__/matrix.stories.jsx +0 -15
  1028. package/src/widgets/__stories__/number-line.stories.jsx +0 -15
  1029. package/src/widgets/__stories__/numeric-input.stories.jsx +0 -106
  1030. package/src/widgets/__stories__/on-screen-keypad.stories.jsx +0 -118
  1031. package/src/widgets/__stories__/orderer.stories.jsx +0 -15
  1032. package/src/widgets/__stories__/passage-ref.stories.jsx +0 -23
  1033. package/src/widgets/__stories__/passage.stories.jsx +0 -27
  1034. package/src/widgets/__stories__/radio.stories.jsx +0 -90
  1035. package/src/widgets/__stories__/sorter.stories.jsx +0 -15
  1036. package/src/widgets/__stories__/transformer.stories.jsx +0 -15
  1037. package/src/widgets/__stories__/unit.stories.jsx +0 -45
  1038. package/src/widgets/__stories__/video-transcript-link.stories.jsx +0 -24
  1039. package/src/widgets/__stories__/video.stories.jsx +0 -15
  1040. package/src/widgets/__testdata__/base-radio_testdata.js +0 -22
  1041. package/src/widgets/__testdata__/categorizer_testdata.js +0 -50
  1042. package/src/widgets/__testdata__/cs-program_testdata.js +0 -28
  1043. package/src/widgets/__testdata__/dropdown_testdata.js +0 -34
  1044. package/src/widgets/__testdata__/explanation_testdata.js +0 -56
  1045. package/src/widgets/__testdata__/expression_testdata.js +0 -95
  1046. package/src/widgets/__testdata__/graded-group-set_testdata.js +0 -358
  1047. package/src/widgets/__testdata__/graded-group_testdata.js +0 -79
  1048. package/src/widgets/__testdata__/grapher_testdata.js +0 -376
  1049. package/src/widgets/__testdata__/group_testdata.js +0 -156
  1050. package/src/widgets/__testdata__/iframe_testdata.js +0 -36
  1051. package/src/widgets/__testdata__/image_testdata.js +0 -38
  1052. package/src/widgets/__testdata__/input-number_testdata.js +0 -73
  1053. package/src/widgets/__testdata__/interaction_testdata.js +0 -264
  1054. package/src/widgets/__testdata__/interactive-graph_testdata.js +0 -646
  1055. package/src/widgets/__testdata__/matcher_testdata.js +0 -34
  1056. package/src/widgets/__testdata__/matrix_testdata.js +0 -29
  1057. package/src/widgets/__testdata__/number-line_testdata.js +0 -31
  1058. package/src/widgets/__testdata__/numeric-input_testdata.js +0 -266
  1059. package/src/widgets/__testdata__/orderer_testdata.js +0 -58
  1060. package/src/widgets/__testdata__/passage-ref_testdata.js +0 -103
  1061. package/src/widgets/__testdata__/passage_testdata.js +0 -96
  1062. package/src/widgets/__testdata__/radio_testdata.js +0 -262
  1063. package/src/widgets/__testdata__/sorter_testdata.js +0 -20
  1064. package/src/widgets/__testdata__/transformer_testdata.js +0 -109
  1065. package/src/widgets/__testdata__/video_testdata.js +0 -22
  1066. package/src/widgets/__tests__/__snapshots__/expression_test.jsx.snap +0 -38
  1067. package/src/widgets/__tests__/__snapshots__/input-number_test.jsx.snap +0 -978
  1068. package/src/widgets/__tests__/categorizer_test.jsx +0 -205
  1069. package/src/widgets/__tests__/cs-program_test.jsx +0 -45
  1070. package/src/widgets/__tests__/definition_test.js +0 -137
  1071. package/src/widgets/__tests__/dropdown_test.jsx +0 -106
  1072. package/src/widgets/__tests__/explanation_test.js +0 -199
  1073. package/src/widgets/__tests__/expression_test.jsx +0 -439
  1074. package/src/widgets/__tests__/graded-group-set-jipt_test.jsx +0 -32
  1075. package/src/widgets/__tests__/graded-group-set_test.jsx +0 -290
  1076. package/src/widgets/__tests__/graded-group_test.jsx +0 -233
  1077. package/src/widgets/__tests__/grapher.cypress.jsx +0 -546
  1078. package/src/widgets/__tests__/grapher_test.jsx +0 -35
  1079. package/src/widgets/__tests__/group_test.jsx +0 -512
  1080. package/src/widgets/__tests__/iframe_test.jsx +0 -47
  1081. package/src/widgets/__tests__/image_test.jsx +0 -65
  1082. package/src/widgets/__tests__/input-number_test.jsx +0 -360
  1083. package/src/widgets/__tests__/interaction_test.jsx +0 -33
  1084. package/src/widgets/__tests__/interactive-graph.cypress.jsx +0 -777
  1085. package/src/widgets/__tests__/interactive-graph_test.jsx +0 -105
  1086. package/src/widgets/__tests__/matcher_test.jsx +0 -157
  1087. package/src/widgets/__tests__/matrix_test.jsx +0 -84
  1088. package/src/widgets/__tests__/number-line_test.jsx +0 -81
  1089. package/src/widgets/__tests__/numeric-input_test.jsx +0 -514
  1090. package/src/widgets/__tests__/orderer_test.jsx +0 -75
  1091. package/src/widgets/__tests__/passage-ref_test.jsx +0 -166
  1092. package/src/widgets/__tests__/passage_test.jsx +0 -212
  1093. package/src/widgets/__tests__/radio/base-radio_test.jsx +0 -443
  1094. package/src/widgets/__tests__/radio/choice-icon_test.jsx +0 -91
  1095. package/src/widgets/__tests__/radio/choice_test.jsx +0 -311
  1096. package/src/widgets/__tests__/radio/focus-ring_test.jsx +0 -23
  1097. package/src/widgets/__tests__/radio/option-status_test.jsx +0 -65
  1098. package/src/widgets/__tests__/radio_test.jsx +0 -810
  1099. package/src/widgets/__tests__/renderQuestion.jsx +0 -66
  1100. package/src/widgets/__tests__/unit_test.jsx +0 -144
  1101. package/src/widgets/__tests__/video_test.jsx +0 -55
  1102. package/src/widgets/categorizer.jsx +0 -343
  1103. package/src/widgets/cs-program.jsx +0 -227
  1104. package/src/widgets/definition.jsx +0 -121
  1105. package/src/widgets/dropdown.jsx +0 -141
  1106. package/src/widgets/explanation.jsx +0 -315
  1107. package/src/widgets/expression.jsx +0 -652
  1108. package/src/widgets/graded-group-answer-bar.jsx +0 -152
  1109. package/src/widgets/graded-group-set.jsx +0 -296
  1110. package/src/widgets/graded-group.jsx +0 -453
  1111. package/src/widgets/grapher/util.jsx +0 -806
  1112. package/src/widgets/grapher.jsx +0 -663
  1113. package/src/widgets/group.jsx +0 -195
  1114. package/src/widgets/iframe.jsx +0 -198
  1115. package/src/widgets/image.jsx +0 -310
  1116. package/src/widgets/input-number.jsx +0 -412
  1117. package/src/widgets/interaction/arrow-picker.jsx +0 -39
  1118. package/src/widgets/interaction/color-picker.jsx +0 -69
  1119. package/src/widgets/interaction/dash-picker.jsx +0 -46
  1120. package/src/widgets/interaction/element-container.jsx +0 -97
  1121. package/src/widgets/interaction.jsx +0 -742
  1122. package/src/widgets/interactive-graph.jsx +0 -2820
  1123. package/src/widgets/label-image/__stories__/answer-choices.stories.jsx +0 -93
  1124. package/src/widgets/label-image/__stories__/marker.stories.jsx +0 -172
  1125. package/src/widgets/label-image/answer-choices.jsx +0 -311
  1126. package/src/widgets/label-image/marker.jsx +0 -365
  1127. package/src/widgets/label-image/types.js +0 -33
  1128. package/src/widgets/label-image.jsx +0 -841
  1129. package/src/widgets/label-image_test.js +0 -840
  1130. package/src/widgets/lights-puzzle.jsx +0 -356
  1131. package/src/widgets/matcher.jsx +0 -274
  1132. package/src/widgets/matrix.jsx +0 -632
  1133. package/src/widgets/measurer.jsx +0 -215
  1134. package/src/widgets/molecule/__tests__/layout_test.jsx +0 -159
  1135. package/src/widgets/molecule/__tests__/parser_test.jsx +0 -142
  1136. package/src/widgets/molecule/molecule-drawing.jsx +0 -175
  1137. package/src/widgets/molecule/molecule-layout.jsx +0 -367
  1138. package/src/widgets/molecule/smiles-parser.jsx +0 -300
  1139. package/src/widgets/molecule.jsx +0 -172
  1140. package/src/widgets/number-line.jsx +0 -858
  1141. package/src/widgets/numeric-input.jsx +0 -553
  1142. package/src/widgets/orderer.jsx +0 -756
  1143. package/src/widgets/passage/__tests__/passage-markdown_test.jsx +0 -373
  1144. package/src/widgets/passage/passage-markdown.jsx +0 -472
  1145. package/src/widgets/passage-ref-target.jsx +0 -73
  1146. package/src/widgets/passage-ref.jsx +0 -214
  1147. package/src/widgets/passage.jsx +0 -576
  1148. package/src/widgets/plotter.jsx +0 -1198
  1149. package/src/widgets/radio/__stories__/base-radio.stories.jsx +0 -189
  1150. package/src/widgets/radio/__stories__/choice-icon.stories.jsx +0 -166
  1151. package/src/widgets/radio/__stories__/choice-none-above.stories.jsx +0 -41
  1152. package/src/widgets/radio/__stories__/choice.stories.jsx +0 -138
  1153. package/src/widgets/radio/__stories__/focus-ring.stories.jsx +0 -44
  1154. package/src/widgets/radio/__stories__/option-status.stories.jsx +0 -104
  1155. package/src/widgets/radio/base-radio.jsx +0 -494
  1156. package/src/widgets/radio/choice-a11y-text.js +0 -62
  1157. package/src/widgets/radio/choice-icon/choice-icon.jsx +0 -214
  1158. package/src/widgets/radio/choice-icon/cross-out-line.jsx +0 -52
  1159. package/src/widgets/radio/choice-icon/shared-styles.js +0 -16
  1160. package/src/widgets/radio/choice-none-above.jsx +0 -63
  1161. package/src/widgets/radio/choice.jsx +0 -382
  1162. package/src/widgets/radio/choice.jsx.fixture.js +0 -46
  1163. package/src/widgets/radio/focus-ring.jsx +0 -58
  1164. package/src/widgets/radio/option-status.jsx +0 -98
  1165. package/src/widgets/radio/util.js +0 -32
  1166. package/src/widgets/radio/util_test.js +0 -19
  1167. package/src/widgets/radio/widget.jsx +0 -515
  1168. package/src/widgets/radio.jsx +0 -155
  1169. package/src/widgets/reaction-diagram.jsx +0 -137
  1170. package/src/widgets/sequence.jsx +0 -143
  1171. package/src/widgets/simulator.jsx +0 -806
  1172. package/src/widgets/sorter.jsx +0 -149
  1173. package/src/widgets/table.jsx +0 -397
  1174. package/src/widgets/transformer.jsx +0 -2876
  1175. package/src/widgets/unit.jsx +0 -372
  1176. package/src/widgets/video-transcript-link.jsx +0 -84
  1177. package/src/widgets/video-transcript-link_test.js +0 -211
  1178. package/src/widgets/video.jsx +0 -126
  1179. package/src/widgets.js +0 -431
  1180. package/src/zoom.js +0 -539
  1181. /package/{src/multi-items/item-types.js → dist/multi-items/item-types.js.flow} +0 -0
  1182. /package/dist/{strings.js → strings} +0 -0
  1183. /package/src/__tests__/__snapshots__/{item-renderer_test.jsx.snap → item-renderer.test.tsx.snap} +0 -0
  1184. /package/src/__tests__/__snapshots__/{perseus-markdown_test.jsx.snap → perseus-markdown.test.ts.snap} +0 -0
  1185. /package/src/__tests__/__snapshots__/{renderer_test.jsx.snap → renderer.test.tsx.snap} +0 -0
  1186. /package/src/__tests__/__snapshots__/{server-item-renderer_test.jsx.snap → server-item-renderer.test.tsx.snap} +0 -0
  1187. /package/src/components/__tests__/__snapshots__/{sortable_test.jsx.snap → sortable.test.tsx.snap} +0 -0
  1188. /package/src/components/__tests__/__snapshots__/{sorter_test.jsx.snap → sorter.test.tsx.snap} +0 -0
  1189. /package/src/multi-items/__tests__/__snapshots__/{multi-renderer_test.js.snap → multi-renderer.test.tsx.snap} +0 -0
  1190. /package/src/widgets/__tests__/__snapshots__/{categorizer_test.jsx.snap → categorizer.test.ts.snap} +0 -0
  1191. /package/src/widgets/__tests__/__snapshots__/{cs-program_test.jsx.snap → cs-program.test.ts.snap} +0 -0
  1192. /package/src/widgets/__tests__/__snapshots__/{definition_test.js.snap → definition.test.ts.snap} +0 -0
  1193. /package/src/widgets/__tests__/__snapshots__/{dropdown_test.jsx.snap → dropdown.test.ts.snap} +0 -0
  1194. /package/src/widgets/__tests__/__snapshots__/{explanation_test.js.snap → explanation.test.ts.snap} +0 -0
  1195. /package/src/widgets/__tests__/__snapshots__/{graded-group-set-jipt_test.jsx.snap → graded-group-set-jipt.test.ts.snap} +0 -0
  1196. /package/src/widgets/__tests__/__snapshots__/{graded-group-set_test.jsx.snap → graded-group-set.test.ts.snap} +0 -0
  1197. /package/src/widgets/__tests__/__snapshots__/{graded-group_test.jsx.snap → graded-group.test.ts.snap} +0 -0
  1198. /package/src/widgets/__tests__/__snapshots__/{grapher_test.jsx.snap → grapher.test.ts.snap} +0 -0
  1199. /package/src/widgets/__tests__/__snapshots__/{group_test.jsx.snap → group.test.tsx.snap} +0 -0
  1200. /package/src/widgets/__tests__/__snapshots__/{iframe_test.jsx.snap → iframe.test.ts.snap} +0 -0
  1201. /package/src/widgets/__tests__/__snapshots__/{image_test.jsx.snap → image.test.ts.snap} +0 -0
  1202. /package/src/widgets/__tests__/__snapshots__/{interaction_test.jsx.snap → interaction.test.ts.snap} +0 -0
  1203. /package/src/widgets/__tests__/__snapshots__/{interactive-graph_test.jsx.snap → interactive-graph.test.ts.snap} +0 -0
  1204. /package/src/widgets/__tests__/__snapshots__/{matcher_test.jsx.snap → matcher.test.tsx.snap} +0 -0
  1205. /package/src/widgets/__tests__/__snapshots__/{matrix_test.jsx.snap → matrix.test.ts.snap} +0 -0
  1206. /package/src/widgets/__tests__/__snapshots__/{number-line_test.jsx.snap → number-line.test.ts.snap} +0 -0
  1207. /package/src/widgets/__tests__/__snapshots__/{numeric-input_test.jsx.snap → numeric-input.test.ts.snap} +0 -0
  1208. /package/src/widgets/__tests__/__snapshots__/{orderer_test.jsx.snap → orderer.test.ts.snap} +0 -0
  1209. /package/src/widgets/__tests__/__snapshots__/{passage-ref_test.jsx.snap → passage-ref.test.ts.snap} +0 -0
  1210. /package/src/widgets/__tests__/__snapshots__/{passage_test.jsx.snap → passage.test.tsx.snap} +0 -0
  1211. /package/src/widgets/__tests__/__snapshots__/{radio_test.jsx.snap → radio.test.ts.snap} +0 -0
  1212. /package/src/widgets/__tests__/__snapshots__/{video_test.jsx.snap → video.test.ts.snap} +0 -0
@@ -0,0 +1,1617 @@
1
+ /* eslint-disable @babel/no-invalid-this */
2
+ import {point as kpoint, vector as kvector} from "@khanacademy/kmath";
3
+ import $ from "jquery";
4
+ // eslint-disable-next-line import/no-extraneous-dependencies
5
+ import Raphael from "raphael";
6
+ import _ from "underscore";
7
+
8
+ // Minify Raphael ourselves because IE8 has a problem with the 1.5.2 minified
9
+ // release
10
+ // http://groups.google.com/group/raphaeljs/browse_thread/thread/c34c75ad8d431544
11
+
12
+ import {Errors, Log} from "../logging/log";
13
+ import {PerseusError} from "../perseus-error";
14
+
15
+ import KhanColors from "./colors";
16
+ import KhanMath from "./math";
17
+ import Tex from "./tex";
18
+
19
+ import type {Coord} from "../interactive2/types";
20
+
21
+ const {processMath} = Tex;
22
+
23
+ /* Convert cartesian coordinates [x, y] to polar coordinates [r,
24
+ * theta], with theta in degrees, or in radians if angleInRadians is
25
+ * specified.
26
+ */
27
+ function cartToPolar(coord: any, angleInRadians: any) {
28
+ const r = Math.sqrt(Math.pow(coord[0], 2) + Math.pow(coord[1], 2));
29
+ let theta = Math.atan2(coord[1], coord[0]);
30
+ // convert angle range from [-pi, pi] to [0, 2pi]
31
+ if (theta < 0) {
32
+ theta += 2 * Math.PI;
33
+ }
34
+ if (!angleInRadians) {
35
+ theta = (theta * 180) / Math.PI;
36
+ }
37
+ return [r, theta];
38
+ }
39
+
40
+ function polar(r: Array<never>, th: number) {
41
+ if (typeof r === "number") {
42
+ r = [r, r];
43
+ }
44
+ th = (th * Math.PI) / 180;
45
+ return [r[0] * Math.cos(th), r[1] * Math.sin(th)];
46
+ }
47
+
48
+ const GraphUtils: any = {
49
+ unscaledSvgPath: function (points) {
50
+ // If this is an empty closed path, return "" instead of "z", which
51
+ // would give an error
52
+ if (points[0] === true) {
53
+ return "";
54
+ }
55
+ return $.map(points, function (point, i) {
56
+ if (point === true) {
57
+ return "z";
58
+ }
59
+ return (i === 0 ? "M" : "L") + point[0] + " " + point[1];
60
+ }).join("");
61
+ },
62
+
63
+ getDistance: function (point1, point2) {
64
+ return kpoint.distanceToPoint(point1, point2);
65
+ },
66
+
67
+ /**
68
+ * Return the difference between two sets of coordinates
69
+ */
70
+ coordDiff: function (startCoord, endCoord) {
71
+ return _.map(endCoord, function (val, i) {
72
+ return endCoord[i] - startCoord[i];
73
+ });
74
+ },
75
+
76
+ /**
77
+ * Round the given coordinates to a given snap value
78
+ * (e.g., nearest 0.2 increment)
79
+ */
80
+ snapCoord: function (coord, snap) {
81
+ return _.map(coord, function (val, i) {
82
+ return KhanMath.roundToNearest(snap[i], val);
83
+ });
84
+ },
85
+
86
+ // Find the angle in degrees between two or three points
87
+ findAngle: function (point1, point2, vertex) {
88
+ if (vertex === undefined) {
89
+ const x = point1[0] - point2[0];
90
+ const y = point1[1] - point2[1];
91
+ if (!x && !y) {
92
+ return 0;
93
+ }
94
+ return (180 + (Math.atan2(-y, -x) * 180) / Math.PI + 360) % 360;
95
+ }
96
+ return (
97
+ GraphUtils.findAngle(point1, vertex) -
98
+ GraphUtils.findAngle(point2, vertex)
99
+ );
100
+ },
101
+
102
+ graphs: {},
103
+ };
104
+
105
+ const Graphie = (GraphUtils.Graphie = function () {});
106
+
107
+ _.extend(Graphie.prototype, {
108
+ cartToPolar: cartToPolar,
109
+ polar: polar,
110
+ });
111
+
112
+ const labelDirections = {
113
+ center: [-0.5, -0.5],
114
+ above: [-0.5, -1.0],
115
+ "above right": [0.0, -1.0],
116
+ right: [0.0, -0.5],
117
+ "below right": [0.0, 0.0],
118
+ below: [-0.5, 0.0],
119
+ "below left": [-1.0, 0.0],
120
+ left: [-1.0, -0.5],
121
+ "above left": [-1.0, -1.0],
122
+ } as const;
123
+
124
+ /**
125
+ * Safari applies some SVG-specific styles to things that are not SVGs, so we
126
+ * need to exclude those styles from things that are not SVGs.
127
+ *
128
+ * To see this behavior in action, open https://codepen.io/anon/pen/zENEoa in
129
+ * Safari.
130
+ *
131
+ * Usage `$.extend({}, someStyles, SVG_SPECIFIC_STYLE_MASK)`
132
+ */
133
+ const SVG_SPECIFIC_STYLE_MASK = {
134
+ "stroke-width": null,
135
+ } as const;
136
+
137
+ GraphUtils.createGraphie = function (el: any) {
138
+ let xScale = 40;
139
+ let yScale = 40;
140
+ let xRange;
141
+ let yRange;
142
+
143
+ $(el).css("position", "relative");
144
+ const raphael = Raphael(el);
145
+
146
+ // For a sometimes-reproducible IE8 bug; doesn't affect SVG browsers at all
147
+ $(el).children("div").css("position", "absolute");
148
+
149
+ // Set up some reasonable defaults
150
+ let currentStyle: any = {
151
+ "stroke-width": 2,
152
+ fill: "none",
153
+ };
154
+
155
+ const scaleVector = function (point: number | Coord) {
156
+ if (typeof point === "number") {
157
+ return scaleVector([point, point]);
158
+ }
159
+
160
+ const x = point[0];
161
+ const y = point[1];
162
+ return [x * xScale, y * yScale];
163
+ };
164
+
165
+ const scalePoint = function scalePoint(point: number | Coord): Coord {
166
+ if (typeof point === "number") {
167
+ return scalePoint([point, point]);
168
+ }
169
+
170
+ const x = point[0];
171
+ const y = point[1];
172
+ return [(x - xRange[0]) * xScale, (yRange[1] - y) * yScale];
173
+ };
174
+
175
+ const unscalePoint = function (point: Array<never>) {
176
+ if (typeof point === "number") {
177
+ return unscalePoint([point, point]);
178
+ }
179
+
180
+ const x = point[0];
181
+ const y = point[1];
182
+ return [x / xScale + xRange[0], yRange[1] - y / yScale];
183
+ };
184
+
185
+ const unscaleVector = function (point: Array<never>) {
186
+ if (typeof point === "number") {
187
+ return unscaleVector([point, point]);
188
+ }
189
+
190
+ return [point[0] / xScale, point[1] / yScale];
191
+ };
192
+
193
+ const setLabelMargins = function (span: any, size: Array<any>) {
194
+ const $span = $(span);
195
+ const direction = $span.data("labelDirection");
196
+ let [width, height] = size;
197
+ // This can happen when a span
198
+ // is invisible but we still want to update the CSS. At worst, we will
199
+ // be off by a few pixels instead of in a different position entirely.
200
+ if (width === 0 && height === 0) {
201
+ [width, height] = [1, 1];
202
+ Log.log("Label size was 0x0 in graphie.js; using 1x1 instead");
203
+ }
204
+ $span.css("visibility", "");
205
+
206
+ if (typeof direction === "number") {
207
+ const x = Math.cos(direction);
208
+ const y = Math.sin(direction);
209
+
210
+ const scale = Math.min(
211
+ width / 2 / Math.abs(x),
212
+ height / 2 / Math.abs(y),
213
+ );
214
+
215
+ $span.css({
216
+ marginLeft: -width / 2 + x * scale,
217
+ marginTop: -height / 2 - y * scale,
218
+ });
219
+ } else {
220
+ const multipliers = labelDirections[direction || "center"];
221
+ $span.css({
222
+ marginLeft: Math.round(width * multipliers[0]),
223
+ marginTop: Math.round(height * multipliers[1]),
224
+ });
225
+ }
226
+ };
227
+
228
+ const svgPath = function (points: any, alreadyScaled) {
229
+ return $.map(points, function (point, i) {
230
+ if (point === true) {
231
+ return "z";
232
+ }
233
+ const scaled = alreadyScaled ? point : scalePoint(point);
234
+ return (
235
+ (i === 0 ? "M" : "L") +
236
+ KhanMath.bound(scaled[0]) +
237
+ " " +
238
+ KhanMath.bound(scaled[1])
239
+ );
240
+ }).join("");
241
+ };
242
+
243
+ const svgParabolaPath = function (a: any, b: any, c: any) {
244
+ const computeParabola = function (x) {
245
+ return (a * x + b) * x + c;
246
+ };
247
+
248
+ // If points are collinear, plot a line instead
249
+ if (a === 0) {
250
+ const points = _.map(xRange, function (x) {
251
+ return [x, computeParabola(x)];
252
+ });
253
+ // @ts-expect-error [FEI-5003] - TS2554 - Expected 2 arguments, but got 1.
254
+ return svgPath(points);
255
+ }
256
+
257
+ // Calculate x coordinates of points on parabola
258
+ const xVertex = -b / (2 * a);
259
+ const distToEdge = Math.max(
260
+ Math.abs(xVertex - xRange[0]),
261
+ Math.abs(xVertex - xRange[1]),
262
+ );
263
+
264
+ // To guarantee that drawn parabola to spans the viewport, use a point
265
+ // on the edge of the graph furtherest from the vertex
266
+ const xPoint = xVertex + distToEdge;
267
+
268
+ // Compute parabola and other point on the curve
269
+ const vertex = [xVertex, computeParabola(xVertex)];
270
+ const point = [xPoint, computeParabola(xPoint)];
271
+
272
+ // Calculate SVG 'control' point, defined by spec
273
+ const control = [vertex[0], vertex[1] - (point[1] - vertex[1])];
274
+
275
+ // Calculate mirror points across parabola's axis of symmetry
276
+ const dx = Math.abs(vertex[0] - point[0]);
277
+ const left = [vertex[0] - dx, point[1]];
278
+ const right = [vertex[0] + dx, point[1]];
279
+
280
+ // Scale and bound
281
+ // @ts-expect-error [FEI-5003] - TS2345 - Argument of type '(point: number | Coord) => Coord' is not assignable to parameter of type 'Iteratee<any[][], any, any[]>'.
282
+ const points = _.map([left, control, right], scalePoint);
283
+ const values = _.map(_.flatten(points), KhanMath.bound);
284
+ return (
285
+ "M" +
286
+ values[0] +
287
+ "," +
288
+ values[1] +
289
+ " Q" +
290
+ values[2] +
291
+ "," +
292
+ values[3] +
293
+ " " +
294
+ values[4] +
295
+ "," +
296
+ values[5]
297
+ );
298
+ };
299
+
300
+ const svgSinusoidPath = function (a, b, c: any, d: any) {
301
+ // Plot a sinusoid of the form: f(x) = a * sin(b * x - c) + d
302
+ const quarterPeriod = Math.abs(Math.PI / (2 * b));
303
+
304
+ const computeSine = function (x: number) {
305
+ return a * Math.sin(b * x - c) + d;
306
+ };
307
+
308
+ const computeDerivative = function (x) {
309
+ return a * b * Math.cos(c - b * x);
310
+ };
311
+
312
+ const coordsForOffset = function (initial: number, i: number) {
313
+ // Return the cubic coordinates (including the two anchor and two
314
+ // control points) for the ith portion of the sinusoid.
315
+ const x0 = initial + quarterPeriod * i;
316
+ const x1 = x0 + quarterPeriod;
317
+
318
+ // Interpolate using derivative technique
319
+ // See: http://stackoverflow.com/questions/13932704/how-to-draw-sine-waves-with-svg-js
320
+ const xCoords = [
321
+ x0,
322
+ (x0 * 2) / 3 + (x1 * 1) / 3,
323
+ (x0 * 1) / 3 + (x1 * 2) / 3,
324
+ x1,
325
+ ];
326
+ const yCoords = [
327
+ computeSine(x0),
328
+ computeSine(x0) + (computeDerivative(x0) * (x1 - x0)) / 3,
329
+ computeSine(x1) - (computeDerivative(x1) * (x1 - x0)) / 3,
330
+ computeSine(x1),
331
+ ];
332
+
333
+ // Zip and scale
334
+ // @ts-expect-error [FEI-5003] - TS2345 - Argument of type '(point: number | Coord) => Coord' is not assignable to parameter of type 'Iteratee<any[][], any, any[]>'.
335
+ return _.map(_.zip(xCoords, yCoords), scalePoint);
336
+ };
337
+
338
+ // How many quarter-periods do we need to span the graph?
339
+ const extent = xRange[1] - xRange[0];
340
+ const numQuarterPeriods = Math.ceil(extent / quarterPeriod) + 1;
341
+
342
+ // Find starting coordinate: first anchor point curve left of xRange[0]
343
+ let initial = c / b;
344
+ const distToEdge = initial - xRange[0];
345
+ initial -= quarterPeriod * Math.ceil(distToEdge / quarterPeriod);
346
+
347
+ // First portion of path is special-case, requiring move-to ('M')
348
+ let coords = coordsForOffset(initial, 0);
349
+ let path =
350
+ "M" +
351
+ coords[0][0] +
352
+ "," +
353
+ coords[0][1] +
354
+ " C" +
355
+ coords[1][0] +
356
+ "," +
357
+ coords[1][1] +
358
+ " " +
359
+ coords[2][0] +
360
+ "," +
361
+ coords[2][1] +
362
+ " " +
363
+ coords[3][0] +
364
+ "," +
365
+ coords[3][1];
366
+ for (let i = 1; i < numQuarterPeriods; i++) {
367
+ coords = coordsForOffset(initial, i);
368
+ path +=
369
+ " C" +
370
+ coords[1][0] +
371
+ "," +
372
+ coords[1][1] +
373
+ " " +
374
+ coords[2][0] +
375
+ "," +
376
+ coords[2][1] +
377
+ " " +
378
+ coords[3][0] +
379
+ "," +
380
+ coords[3][1];
381
+ }
382
+
383
+ return path;
384
+ };
385
+
386
+ // `svgPath` is independent of graphie range, so we export it independently
387
+ GraphUtils.svgPath = svgPath;
388
+
389
+ const processAttributes = function (attrs) {
390
+ const transformers = {
391
+ scale: function (scale) {
392
+ if (typeof scale === "number") {
393
+ scale = [scale, scale];
394
+ }
395
+
396
+ xScale = scale[0];
397
+ yScale = scale[1];
398
+
399
+ // Update the canvas size
400
+ raphael.setSize(
401
+ (xRange[1] - xRange[0]) * xScale,
402
+ (yRange[1] - yRange[0]) * yScale,
403
+ );
404
+ },
405
+
406
+ clipRect: function (pair) {
407
+ const point = pair[0];
408
+ const size = pair[1];
409
+ point[1] += size[1]; // because our coordinates are flipped
410
+
411
+ return {
412
+ "clip-rect": scalePoint(point)
413
+ .concat(scaleVector(size))
414
+ .join(" "),
415
+ };
416
+ },
417
+
418
+ strokeWidth: function (val) {
419
+ return {"stroke-width": parseFloat(val)};
420
+ },
421
+
422
+ rx: function (val) {
423
+ return {rx: scaleVector([val, 0])[0]};
424
+ },
425
+
426
+ ry: function (val) {
427
+ return {ry: scaleVector([0, val])[1]};
428
+ },
429
+
430
+ r: function (val) {
431
+ const scaled = scaleVector([val, val]);
432
+ return {rx: scaled[0], ry: scaled[1]};
433
+ },
434
+ } as const;
435
+
436
+ const processed: Record<string, any> = {};
437
+ $.each(attrs || {}, function (key, value) {
438
+ const transformer = transformers[key];
439
+
440
+ if (typeof transformer === "function") {
441
+ $.extend(processed, transformer(value));
442
+ } else {
443
+ const dasherized = key
444
+ // @ts-expect-error [FEI-5003] - TS2339 - Property 'replace' does not exist on type 'string | number | symbol'.
445
+ .replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2")
446
+ .replace(/([a-z\d])([A-Z])/g, "$1-$2")
447
+ .toLowerCase();
448
+ processed[dasherized] = value;
449
+ }
450
+ });
451
+
452
+ return processed;
453
+ };
454
+
455
+ const addArrowheads = function arrows(path: any) {
456
+ const type = path.constructor.prototype;
457
+
458
+ if (type === Raphael.el) {
459
+ if (
460
+ path.type === "path" &&
461
+ typeof path.arrowheadsDrawn === "undefined"
462
+ ) {
463
+ const w = path.attr("stroke-width");
464
+ const s = 0.6 + 0.4 * w;
465
+ const l = path.getTotalLength();
466
+ const set = raphael.set();
467
+ const head = raphael.path(
468
+ graphie.isMobile
469
+ ? "M-4,4 C-4,4 -0.25,0 -0.25,0 C-0.25,0 -4,-4 -4,-4"
470
+ : "M-3 4 C-2.75 2.5 0 0.25 0.75 0C0 -0.25 -2.75 -2.5 -3 -4",
471
+ );
472
+ const end = path.getPointAtLength(l - 0.4);
473
+ const almostTheEnd = path.getPointAtLength(l - 0.75 * s);
474
+ const angle =
475
+ (Math.atan2(
476
+ end.y - almostTheEnd.y,
477
+ end.x - almostTheEnd.x,
478
+ ) *
479
+ 180) /
480
+ Math.PI;
481
+ const attrs = path.attr();
482
+ delete attrs.path;
483
+
484
+ let subpath = path.getSubpath(0, l - 0.75 * s);
485
+ subpath = raphael.path(subpath).attr(attrs);
486
+ subpath.arrowheadsDrawn = true;
487
+ path.remove();
488
+
489
+ // For some unknown reason 0 doesn't work for the rotation
490
+ // origin so we use a tiny number.
491
+ head.rotate(angle, graphie.isMobile ? 1e-5 : 0.75, 0)
492
+ .scale(s, s, 0.75, 0)
493
+ .translate(almostTheEnd.x, almostTheEnd.y)
494
+ .attr(attrs)
495
+ .attr({
496
+ "stroke-linejoin": "round",
497
+ "stroke-linecap": "round",
498
+ });
499
+
500
+ head.arrowheadsDrawn = true;
501
+ set.push(subpath);
502
+ set.push(head);
503
+ return set;
504
+ }
505
+ } else if (type === Raphael.st) {
506
+ for (let i = 0, l = path.items.length; i < l; i++) {
507
+ arrows(path.items[i]);
508
+ }
509
+ }
510
+ return path;
511
+ };
512
+
513
+ const drawingTools: any = {
514
+ circle: function (center, radius) {
515
+ return raphael.ellipse(
516
+ ...scalePoint(center).concat(scaleVector([radius, radius])),
517
+ );
518
+ },
519
+
520
+ // (x, y) is coordinate of bottom left corner
521
+ rect: function (x, y, width, height) {
522
+ // Raphael needs (x, y) to be coordinate of upper left corner
523
+ const corner = scalePoint([x, y + height]);
524
+ const dims = scaleVector([width, height]);
525
+ const elem = raphael.rect(...corner.concat(dims));
526
+
527
+ if (graphie.isMobile) {
528
+ elem.node.style.shapeRendering = "crispEdges";
529
+ }
530
+
531
+ return elem;
532
+ },
533
+
534
+ ellipse: function (center, radii) {
535
+ return raphael.ellipse(
536
+ ...scalePoint(center).concat(scaleVector(radii)),
537
+ );
538
+ },
539
+
540
+ fixedEllipse: function (
541
+ center: number | Coord,
542
+ // Different type than Coord, this is radiusX, radiusY
543
+ radii: number | [number, number],
544
+ maxScale: number,
545
+ padding: number,
546
+ ) {
547
+ // Scale point and radius
548
+ const scaledPoint = scalePoint(center);
549
+ const scaledRadii = scaleVector(radii);
550
+
551
+ const width = 2 * scaledRadii[0] * maxScale + padding;
552
+ const height = 2 * scaledRadii[1] * maxScale + padding;
553
+
554
+ // Calculate absolute left, top
555
+ const left = scaledPoint[0] - width / 2;
556
+ const top = scaledPoint[1] - height / 2;
557
+
558
+ // Wrap in <div>
559
+ const wrapper = document.createElement("div");
560
+ $(wrapper).css({
561
+ position: "absolute",
562
+ width: width + "px",
563
+ height: height + "px",
564
+ left: left + "px",
565
+ top: top + "px",
566
+ });
567
+ // wrapper.setAttribute("data-graphie-type", "ellipse");
568
+
569
+ // Create Raphael canvas
570
+ const localRaphael = Raphael(wrapper, width, height);
571
+ const visibleShape = localRaphael.ellipse(
572
+ width / 2,
573
+ height / 2,
574
+ scaledRadii[0],
575
+ scaledRadii[1],
576
+ );
577
+
578
+ return {
579
+ wrapper: wrapper,
580
+ visibleShape: visibleShape,
581
+ };
582
+ },
583
+
584
+ arc: function (center, radius, startAngle, endAngle, sector) {
585
+ startAngle = ((startAngle % 360) + 360) % 360;
586
+ endAngle = ((endAngle % 360) + 360) % 360;
587
+
588
+ const cent = scalePoint(center);
589
+ const radii = scaleVector(radius);
590
+ const startVector = polar(radius, startAngle);
591
+ const endVector = polar(radius, endAngle);
592
+
593
+ const startPoint = scalePoint([
594
+ center[0] + startVector[0],
595
+ center[1] + startVector[1],
596
+ ]);
597
+ const endPoint = scalePoint([
598
+ center[0] + endVector[0],
599
+ center[1] + endVector[1],
600
+ ]);
601
+
602
+ const largeAngle =
603
+ (((endAngle - startAngle) % 360) + 360) % 360 > 180;
604
+
605
+ return raphael.path(
606
+ "M" +
607
+ startPoint.join(" ") +
608
+ "A" +
609
+ radii.join(" ") +
610
+ " 0 " + // ellipse rotation
611
+ (largeAngle ? 1 : 0) +
612
+ " 0 " + // sweep flag
613
+ endPoint.join(" ") +
614
+ (sector ? "L" + cent.join(" ") + "z" : ""),
615
+ );
616
+ },
617
+
618
+ path: function (points) {
619
+ // @ts-expect-error [FEI-5003] - TS2554 - Expected 2 arguments, but got 1.
620
+ const p = raphael.path(svgPath(points));
621
+ p.graphiePath = points;
622
+
623
+ return p;
624
+ },
625
+
626
+ fixedPath: function (points, center, createPath) {
627
+ points = _.map(points, scalePoint);
628
+ center = center ? scalePoint(center) : null;
629
+ createPath = createPath || svgPath;
630
+
631
+ const pathLeft = _.min(_.pluck(points, 0));
632
+ const pathRight = _.max(_.pluck(points, 0));
633
+ const pathTop = _.min(_.pluck(points, 1));
634
+ const pathBottom = _.max(_.pluck(points, 1));
635
+
636
+ // Apply padding to line
637
+ const padding = [4, 4];
638
+
639
+ // Calculate and apply additional offset
640
+ const extraOffset = [pathLeft, pathTop];
641
+
642
+ // Apply padding and offset to points
643
+ points = _.map(points, function (point) {
644
+ return kvector.add(
645
+ kvector.subtract(point, extraOffset),
646
+ kvector.scale(padding, 0.5),
647
+ );
648
+ });
649
+
650
+ // Calculate <div> dimensions
651
+ const width = pathRight - pathLeft + padding[0];
652
+ const height = pathBottom - pathTop + padding[1];
653
+ const left = extraOffset[0] - padding[0] / 2;
654
+ const top = extraOffset[1] - padding[1] / 2;
655
+
656
+ // Create <div>
657
+ const wrapper = document.createElement("div");
658
+ $(wrapper).css({
659
+ position: "absolute",
660
+ width: width + "px",
661
+ height: height + "px",
662
+ left: left + "px",
663
+ top: top + "px",
664
+ // If user specified a center, set it
665
+ // NOTE(kevinb): jQuery doesn't like that `transformOrigin `could be `null`
666
+ // so we cast to `any` here.
667
+ transformOrigin: center
668
+ ? width / 2 +
669
+ center[0] +
670
+ "px " +
671
+ (height / 2 + center[1]) +
672
+ "px"
673
+ : null,
674
+ } as any);
675
+
676
+ // Create Raphael canvas
677
+ const localRaphael = Raphael(wrapper, width, height);
678
+
679
+ // Calculate path
680
+ const visibleShape = localRaphael.path(createPath(points));
681
+
682
+ return {
683
+ wrapper: wrapper,
684
+ visibleShape: visibleShape,
685
+ };
686
+ },
687
+
688
+ scaledPath: function (points) {
689
+ const p = raphael.path(svgPath(points, /* alreadyScaled */ true));
690
+ p.graphiePath = points;
691
+ return p;
692
+ },
693
+
694
+ line: function (start, end) {
695
+ const l = this.path([start, end]);
696
+
697
+ if (graphie.isMobile) {
698
+ l.node.style.shapeRendering = "crispEdges";
699
+ }
700
+
701
+ return l;
702
+ },
703
+
704
+ parabola: function (a, b, c) {
705
+ // Plot a parabola of the form: f(x) = (a * x + b) * x + c
706
+ return raphael.path(svgParabolaPath(a, b, c));
707
+ },
708
+
709
+ fixedLine: function (start, end, thickness) {
710
+ // Apply padding to line
711
+ const padding = [thickness, thickness];
712
+
713
+ // Scale points to get values in pixels
714
+ start = scalePoint(start);
715
+ end = scalePoint(end);
716
+
717
+ // Calculate and apply additional offset
718
+ const extraOffset = [
719
+ Math.min(start[0], end[0]),
720
+ Math.min(start[1], end[1]),
721
+ ];
722
+
723
+ // Apply padding and offset to start, end points
724
+ start = kvector.add(
725
+ kvector.subtract(start, extraOffset),
726
+ kvector.scale(padding, 0.5),
727
+ );
728
+ end = kvector.add(
729
+ kvector.subtract(end, extraOffset),
730
+ kvector.scale(padding, 0.5),
731
+ );
732
+
733
+ // Calculate <div> dimensions
734
+ const left = extraOffset[0] - padding[0] / 2;
735
+ const top = extraOffset[1] - padding[1] / 2;
736
+ const width = Math.abs(start[0] - end[0]) + padding[0];
737
+ const height = Math.abs(start[1] - end[1]) + padding[1];
738
+
739
+ // Create <div>
740
+ const wrapper = document.createElement("div");
741
+ $(wrapper).css({
742
+ position: "absolute",
743
+ width: width + "px",
744
+ height: height + "px",
745
+ left: left + "px",
746
+ top: top + "px",
747
+ // Outsiders should feel like the line's 'origin' (i.e., for
748
+ // rotation) is the starting point
749
+ transformOrigin: start[0] + "px " + start[1] + "px",
750
+ });
751
+
752
+ // Create Raphael canvas
753
+ const localRaphael = Raphael(wrapper, width, height);
754
+
755
+ // Calculate path
756
+ const path =
757
+ "M" +
758
+ start[0] +
759
+ " " +
760
+ start[1] +
761
+ " " +
762
+ "L" +
763
+ end[0] +
764
+ " " +
765
+ end[1];
766
+ const visibleShape = localRaphael.path(path);
767
+ visibleShape.graphiePath = [start, end];
768
+
769
+ return {
770
+ wrapper: wrapper,
771
+ visibleShape: visibleShape,
772
+ };
773
+ },
774
+
775
+ sinusoid: function (a, b, c, d) {
776
+ // Plot a sinusoid of the form: f(x) = a * sin(b * x - c) + d
777
+ return raphael.path(svgSinusoidPath(a, b, c, d));
778
+ },
779
+
780
+ grid: function (xr, yr) {
781
+ const step: any = currentStyle.step || [1, 1];
782
+ const set = raphael.set();
783
+
784
+ let x = step[0] * Math.ceil(xr[0] / step[0]);
785
+ for (; x <= xr[1]; x += step[0]) {
786
+ set.push(this.line([x, yr[0]], [x, yr[1]]));
787
+ }
788
+
789
+ let y = step[1] * Math.ceil(yr[0] / step[1]);
790
+ for (; y <= yr[1]; y += step[1]) {
791
+ set.push(this.line([xr[0], y], [xr[1], y]));
792
+ }
793
+
794
+ return set;
795
+ },
796
+
797
+ label: function (point, text, direction, latex) {
798
+ latex = typeof latex === "undefined" || latex;
799
+
800
+ const $span = $("<span>").addClass("graphie-label");
801
+
802
+ const pad = currentStyle["label-distance"];
803
+
804
+ $span
805
+ .css(
806
+ $.extend(
807
+ {},
808
+ {
809
+ position: "absolute",
810
+ padding: (pad != null ? pad : 7) + "px",
811
+ color: "black",
812
+ },
813
+ ),
814
+ )
815
+ .data("labelDirection", direction)
816
+ .appendTo(el);
817
+
818
+ // @ts-expect-error [FEI-5003] - TS2339 - Property 'setPosition' does not exist on type 'JQuery<HTMLElement>'.
819
+ $span.setPosition = function (point) {
820
+ const scaledPoint = scalePoint(point);
821
+ $span.css({
822
+ left: scaledPoint[0],
823
+ top: scaledPoint[1],
824
+ });
825
+ };
826
+
827
+ // @ts-expect-error [FEI-5003] - TS2339 - Property 'setPosition' does not exist on type 'JQuery<HTMLElement>'.
828
+ $span.setPosition(point);
829
+
830
+ const span = $span[0];
831
+
832
+ // @ts-expect-error [FEI-5003] - TS2339 - Property 'processMath' does not exist on type 'JQuery<HTMLElement>'.
833
+ $span.processMath = function (math, force) {
834
+ processMath(span, math, force, function () {
835
+ const width = span.scrollWidth;
836
+ const height = span.scrollHeight;
837
+ setLabelMargins(span, [width, height]);
838
+ });
839
+ };
840
+
841
+ // @ts-expect-error [FEI-5003] - TS2339 - Property 'processText' does not exist on type 'JQuery<HTMLElement>'.
842
+ $span.processText = function (text: any) {
843
+ $span.html(text);
844
+ const width = span.scrollWidth;
845
+ const height = span.scrollHeight;
846
+ setLabelMargins(span, [width, height]);
847
+ };
848
+
849
+ if (latex) {
850
+ // @ts-expect-error [FEI-5003] - TS2339 - Property 'processMath' does not exist on type 'JQuery<HTMLElement>'.
851
+ $span.processMath(text, /* force */ false);
852
+ } else {
853
+ // @ts-expect-error [FEI-5003] - TS2339 - Property 'processText' does not exist on type 'JQuery<HTMLElement>'.
854
+ $span.processText(text);
855
+ }
856
+
857
+ return $span;
858
+ },
859
+
860
+ plotParametric: function (fn, range, shade, fn2) {
861
+ // Note: fn2 should only be set if 'shade' is true, as it denotes
862
+ // the function between which fn should have its area shaded.
863
+ // In general, plotParametric shouldn't be used to shade the area
864
+ // between two arbitrary parametrics functions over an interval,
865
+ // as the method assumes that fn and fn2 are both of the form
866
+ // fn(t) = (t, fn'(t)) for some initial fn'.
867
+ fn2 =
868
+ fn2 ||
869
+ function (t) {
870
+ return [t, 0];
871
+ };
872
+
873
+ // We truncate to 500,000, since anything bigger causes
874
+ // overflow in the firefox svg renderer. This is safe
875
+ // since 500,000 is outside the viewport anyway. We
876
+ // write these functions the way we do to handle undefined.
877
+ const clipper = (xy) => {
878
+ if (Math.abs(xy[1]) > 500000) {
879
+ return [xy[0], Math.min(Math.max(xy[1], -500000), 500000)];
880
+ }
881
+ return xy;
882
+ };
883
+ const clippedFn = (x) => clipper(fn(x));
884
+ const clippedFn2 = (x: number) => clipper(fn2(x));
885
+
886
+ if (!currentStyle.strokeLinejoin) {
887
+ currentStyle.strokeLinejoin = "round";
888
+ }
889
+ if (!currentStyle.strokeLinecap) {
890
+ currentStyle.strokeLinecap = "round";
891
+ }
892
+
893
+ const min = range[0];
894
+ const max = range[1];
895
+ let step = (max - min) / (currentStyle["plot-points"] || 800);
896
+ if (step === 0) {
897
+ step = 1;
898
+ }
899
+
900
+ const paths = raphael.set();
901
+ let points = [];
902
+ let lastDiff = GraphUtils.coordDiff(
903
+ clippedFn(min),
904
+ clippedFn2(min),
905
+ );
906
+
907
+ let lastFlip = min;
908
+ for (let t = min; t <= max; t += step) {
909
+ const top = clippedFn(t);
910
+ const bottom = clippedFn2(t);
911
+ const diff = GraphUtils.coordDiff(top, bottom);
912
+
913
+ // Find points where it flips
914
+ // Create path that sketches area between the two functions
915
+ if (
916
+ // if there is an asymptote here, meaning that the graph
917
+ // switches signs and has a large difference
918
+ (diff[1] < 0 !== lastDiff[1] < 0 &&
919
+ Math.abs(diff[1] - lastDiff[1]) > 2 * yScale) ||
920
+ // or the function is undefined
921
+ isNaN(diff[1])
922
+ ) {
923
+ // split the path at this point, and draw it
924
+ if (shade) {
925
+ // @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'any' is not assignable to parameter of type 'never'.
926
+ points.push(top);
927
+
928
+ // backtrack to draw paired function
929
+ for (let u = t - step; u >= lastFlip; u -= step) {
930
+ // @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'any' is not assignable to parameter of type 'never'.
931
+ points.push(clippedFn2(u));
932
+ }
933
+ lastFlip = t;
934
+ }
935
+ paths.push(this.path(points));
936
+ // restart the path, excluding this point
937
+ points = [];
938
+ if (shade) {
939
+ // @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'any' is not assignable to parameter of type 'never'.
940
+ points.push(top);
941
+ }
942
+ } else {
943
+ // otherwise, just add the point to the path
944
+ // @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'any' is not assignable to parameter of type 'never'.
945
+ points.push(top);
946
+ }
947
+
948
+ lastDiff = diff;
949
+ }
950
+
951
+ if (shade) {
952
+ // backtrack to draw paired function
953
+ for (let u = max - step; u >= lastFlip; u -= step) {
954
+ // @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'any' is not assignable to parameter of type 'never'.
955
+ points.push(clippedFn2(u));
956
+ }
957
+ }
958
+ paths.push(this.path(points));
959
+
960
+ return paths;
961
+ },
962
+
963
+ plotPolar: function (fn, range) {
964
+ const min = range[0];
965
+ const max = range[1];
966
+
967
+ // There is probably a better heuristic for this
968
+ if (!currentStyle["plot-points"]) {
969
+ currentStyle["plot-points"] = 2 * (max - min) * xScale;
970
+ }
971
+
972
+ return this.plotParametric(function (th) {
973
+ return polar(fn(th), (th * 180) / Math.PI);
974
+ }, range);
975
+ },
976
+
977
+ plot: function (fn, range, swapAxes, shade, fn2) {
978
+ const min = range[0];
979
+ const max = range[1];
980
+ if (!currentStyle["plot-points"]) {
981
+ currentStyle["plot-points"] = 2 * (max - min) * xScale;
982
+ }
983
+
984
+ if (swapAxes) {
985
+ if (fn2) {
986
+ // TODO(charlie): support swapped axis area shading
987
+ throw new PerseusError(
988
+ "Can't shade area between functions with swapped axes.",
989
+ Errors.Internal,
990
+ );
991
+ }
992
+ return this.plotParametric(
993
+ function (y) {
994
+ return [fn(y), y];
995
+ },
996
+ range,
997
+ shade,
998
+ );
999
+ }
1000
+ if (fn2) {
1001
+ if (shade) {
1002
+ return this.plotParametric(
1003
+ function (x) {
1004
+ return [x, fn(x)];
1005
+ },
1006
+ range,
1007
+ shade,
1008
+ function (x) {
1009
+ return [x, fn2(x)];
1010
+ },
1011
+ );
1012
+ }
1013
+ throw new PerseusError(
1014
+ "fn2 should only be set when 'shade' is True.",
1015
+ Errors.Internal,
1016
+ );
1017
+ }
1018
+ return this.plotParametric(
1019
+ function (x) {
1020
+ return [x, fn(x)];
1021
+ },
1022
+ range,
1023
+ shade,
1024
+ );
1025
+ },
1026
+
1027
+ /**
1028
+ * Given a piecewise function, return a Raphael set of paths that
1029
+ * can be used to draw the function, e.g. using style().
1030
+ * Calls plotParametric.
1031
+ *
1032
+ * @param {[]} fnArray array of functions which when called
1033
+ * with a parameter i return the value of
1034
+ * the function at i
1035
+ * @param {[]} rangeArray array of ranges over which the
1036
+ * corresponding functions are defined
1037
+ * @return {Raphael set}
1038
+ */
1039
+ plotPiecewise: function (fnArray, rangeArray) {
1040
+ const paths = raphael.set();
1041
+ const self = this;
1042
+ _.times(fnArray.length, function (i) {
1043
+ const fn = fnArray[i];
1044
+ const range = rangeArray[i];
1045
+ const fnPaths = self.plotParametric(function (x) {
1046
+ return [x, fn(x)];
1047
+ }, range);
1048
+ _.each(fnPaths, function (fnPath) {
1049
+ paths.push(fnPath);
1050
+ });
1051
+ });
1052
+
1053
+ return paths;
1054
+ },
1055
+
1056
+ /**
1057
+ * Given an array of coordinates of the form [x, y], create and
1058
+ * return a Raphael set of Raphael circle objects at those
1059
+ * coordinates
1060
+ *
1061
+ * @param {Array of arrays} endpointArray
1062
+ * @return {Raphael set}
1063
+ */
1064
+ plotEndpointCircles: function (endpointArray) {
1065
+ const circles = raphael.set();
1066
+ const self = this;
1067
+
1068
+ _.each(endpointArray, function (coord, i) {
1069
+ circles.push(self.circle(coord, 0.15));
1070
+ });
1071
+
1072
+ return circles;
1073
+ },
1074
+
1075
+ plotAsymptotes: function (fn, range) {
1076
+ const min = range[0];
1077
+ const max = range[1];
1078
+ const step = (max - min) / (currentStyle["plot-points"] || 800);
1079
+
1080
+ const asymptotes = raphael.set();
1081
+ let lastVal = fn(min);
1082
+
1083
+ for (let t = min; t <= max; t += step) {
1084
+ const funcVal = fn(t);
1085
+
1086
+ if (
1087
+ funcVal < 0 !== lastVal < 0 &&
1088
+ Math.abs(funcVal - lastVal) > 2 * yScale
1089
+ ) {
1090
+ asymptotes.push(this.line([t, yScale], [t, -yScale]));
1091
+ }
1092
+
1093
+ lastVal = funcVal;
1094
+ }
1095
+
1096
+ return asymptotes;
1097
+ },
1098
+ };
1099
+
1100
+ const graphie = new Graphie();
1101
+ _.extend(graphie, {
1102
+ raphael: raphael,
1103
+
1104
+ init: function (options) {
1105
+ let scale = options.scale || [40, 40];
1106
+ scale = typeof scale === "number" ? [scale, scale] : scale;
1107
+
1108
+ xScale = scale[0];
1109
+ yScale = scale[1];
1110
+
1111
+ if (options.range == null) {
1112
+ throw new PerseusError(
1113
+ "range should be specified in graph init",
1114
+ Errors.Internal,
1115
+ );
1116
+ }
1117
+
1118
+ xRange = options.range[0];
1119
+ yRange = options.range[1];
1120
+
1121
+ const w = (xRange[1] - xRange[0]) * xScale;
1122
+ const h = (yRange[1] - yRange[0]) * yScale;
1123
+ raphael.setSize(w, h);
1124
+
1125
+ $(el).css({
1126
+ width: w,
1127
+ height: h,
1128
+ });
1129
+
1130
+ this.range = options.range;
1131
+ this.scale = scale;
1132
+ this.dimensions = [w, h];
1133
+ this.xpixels = w;
1134
+ this.ypixels = h;
1135
+
1136
+ this.isMobile = options.isMobile;
1137
+
1138
+ return this;
1139
+ },
1140
+
1141
+ style: function (attrs, fn) {
1142
+ const processed = processAttributes(attrs);
1143
+
1144
+ if (typeof fn === "function") {
1145
+ const oldStyle = currentStyle;
1146
+ currentStyle = $.extend({}, currentStyle, processed);
1147
+ const result = fn.call(graphie);
1148
+ currentStyle = oldStyle;
1149
+ return result;
1150
+ }
1151
+ $.extend(currentStyle, processed);
1152
+ },
1153
+
1154
+ scalePoint: scalePoint,
1155
+ scaleVector: scaleVector,
1156
+
1157
+ unscalePoint: unscalePoint,
1158
+ unscaleVector: unscaleVector,
1159
+
1160
+ // Custom SVG path functions that are dependent on graphie range
1161
+ // `svgPath`, while independent of range, is exported for consistency
1162
+ svgPath: svgPath,
1163
+ svgParabolaPath: svgParabolaPath,
1164
+ svgSinusoidPath: svgSinusoidPath,
1165
+ });
1166
+
1167
+ $.each(drawingTools, function (name) {
1168
+ graphie[name] = function (...args) {
1169
+ const last = args[args.length - 1];
1170
+ const oldStyle = currentStyle;
1171
+ let result;
1172
+
1173
+ // The last argument is probably trying to change the style
1174
+ if (typeof last === "object" && !_.isArray(last)) {
1175
+ currentStyle = {
1176
+ ...currentStyle,
1177
+ ...processAttributes(last),
1178
+ };
1179
+
1180
+ const rest = [].slice.call(args, 0, args.length - 1);
1181
+ result = drawingTools[name](...rest);
1182
+ } else {
1183
+ currentStyle = $.extend({}, currentStyle);
1184
+
1185
+ result = drawingTools[name](...args);
1186
+ }
1187
+
1188
+ // Bad heuristic for recognizing Raphael elements and sets
1189
+ const type = result.constructor.prototype;
1190
+ if (type === Raphael.el || type === Raphael.st) {
1191
+ result.attr(currentStyle);
1192
+
1193
+ if (currentStyle.arrows) {
1194
+ result = addArrowheads(result);
1195
+ }
1196
+ } else if (result instanceof $) {
1197
+ // We assume that if it's not a Raphael element/set, it
1198
+ // does not contain SVG.
1199
+ // @ts-expect-error [FEI-5003] - TS2339 - Property 'css' does not exist on type '{}'.
1200
+ result.css({...currentStyle, ...SVG_SPECIFIC_STYLE_MASK});
1201
+ }
1202
+
1203
+ currentStyle = oldStyle;
1204
+ return result;
1205
+ };
1206
+ });
1207
+
1208
+ // Initializes graphie settings for a graph and draws the basic graph
1209
+ // features (axes, grid, tick marks, and axis labels)
1210
+ // Options expected are:
1211
+ // - range: [[a, b], [c, d]] or [a, b]
1212
+ // - scale: [a, b] or number
1213
+ // - gridOpacity: number (0 - 1)
1214
+ // - gridStep: [a, b] or number (relative to units)
1215
+ // - tickStep: [a, b] or number (relative to grid steps)
1216
+ // - tickLen: [a, b] or number (in pixels)
1217
+ // - labelStep: [a, b] or number (relative to tick steps)
1218
+ // - yLabelFormat: fn to format label string for y-axis
1219
+ // - xLabelFormat: fn to format label string for x-axis
1220
+ // - smartLabelPositioning: true or false to ignore minus sign
1221
+ graphie.graphInit = function (options: any) {
1222
+ options = options || {};
1223
+
1224
+ $.each(options, function (prop, val: any) {
1225
+ // allow options to be specified by a single number for shorthand if
1226
+ // the horizontal and vertical components are the same
1227
+ if (
1228
+ // @ts-expect-error [FEI-5003] - TS2339 - Property 'match' does not exist on type 'string | number | symbol'.
1229
+ !prop.match(/.*Opacity$/) &&
1230
+ prop !== "range" &&
1231
+ typeof val === "number"
1232
+ ) {
1233
+ options[prop] = [val, val];
1234
+ }
1235
+
1236
+ // allow symmetric ranges to be specified by the absolute values
1237
+ if (prop === "range" || prop === "gridRange") {
1238
+ if (val.constructor === Array) {
1239
+ // but don't mandate symmetric ranges
1240
+ if (val[0].constructor !== Array) {
1241
+ options[prop] = [
1242
+ [-val[0], val[0]],
1243
+ [-val[1], val[1]],
1244
+ ];
1245
+ }
1246
+ } else if (typeof val === "number") {
1247
+ options[prop] = [
1248
+ [-val, val],
1249
+ [-val, val],
1250
+ ];
1251
+ }
1252
+ }
1253
+ });
1254
+
1255
+ const range = options.range || [
1256
+ [-10, 10],
1257
+ [-10, 10],
1258
+ ];
1259
+ const gridRange = options.gridRange || options.range;
1260
+ const scale = options.scale || [20, 20];
1261
+ const grid = options.grid != null ? options.grid : true;
1262
+ const gridOpacity = options.gridOpacity || 0.1;
1263
+ const gridStep = options.gridStep || [1, 1];
1264
+ const axes = options.axes != null ? options.axes : true;
1265
+ const axisArrows = options.axisArrows || "";
1266
+ const axisOpacity = options.axisOpacity || 1.0;
1267
+ const axisCenter = options.axisCenter || [
1268
+ Math.min(Math.max(range[0][0], 0), range[0][1]),
1269
+ Math.min(Math.max(range[1][0], 0), range[1][1]),
1270
+ ];
1271
+ const axisLabels =
1272
+ options.axisLabels != null ? options.axisLabels : false;
1273
+ const ticks = options.ticks != null ? options.ticks : true;
1274
+ const tickStep = options.tickStep || [2, 2];
1275
+ const tickLen = options.tickLen || [5, 5];
1276
+ const tickOpacity = options.tickOpacity || 1.0;
1277
+ const labels = options.labels || options.labelStep || false;
1278
+ const labelStep = options.labelStep || [1, 1];
1279
+ const labelOpacity = options.labelOpacity || 1.0;
1280
+ let unityLabels = options.unityLabels || false;
1281
+ const labelFormat =
1282
+ options.labelFormat ||
1283
+ function (a: any) {
1284
+ return a;
1285
+ };
1286
+ let xLabelFormat = options.xLabelFormat || labelFormat;
1287
+ let yLabelFormat = options.yLabelFormat || labelFormat;
1288
+ const smartLabelPositioning =
1289
+ options.smartLabelPositioning != null
1290
+ ? options.smartLabelPositioning
1291
+ : true;
1292
+ const realRange = [
1293
+ [
1294
+ range[0][0] - (range[0][0] > 0 ? 1 : 0),
1295
+ range[0][1] + (range[0][1] < 0 ? 1 : 0),
1296
+ ],
1297
+ [
1298
+ range[1][0] - (range[1][0] > 0 ? 1 : 0),
1299
+ range[1][1] + (range[1][1] < 0 ? 1 : 0),
1300
+ ],
1301
+ ];
1302
+
1303
+ if (!_.isArray(unityLabels)) {
1304
+ unityLabels = [unityLabels, unityLabels];
1305
+ }
1306
+
1307
+ if (smartLabelPositioning) {
1308
+ const minusIgnorer = function (lf: any) {
1309
+ return function (a) {
1310
+ return (lf(a) + "").replace(/-(\d)/g, "\\llap{-}$1");
1311
+ };
1312
+ };
1313
+
1314
+ xLabelFormat = minusIgnorer(xLabelFormat);
1315
+ yLabelFormat = minusIgnorer(yLabelFormat);
1316
+ }
1317
+
1318
+ this.init({
1319
+ range: realRange,
1320
+ scale: scale,
1321
+ isMobile: options.isMobile,
1322
+ });
1323
+
1324
+ // draw grid
1325
+ if (grid) {
1326
+ this.grid(gridRange[0], gridRange[1], {
1327
+ stroke: options.isMobile ? KhanColors.GRAY_C : "#000000",
1328
+ opacity: options.isMobile ? 1 : gridOpacity,
1329
+ step: gridStep,
1330
+ strokeWidth: options.isMobile ? 1 : 2,
1331
+ });
1332
+ }
1333
+
1334
+ // draw axes
1335
+ if (axes) {
1336
+ // this is a slight hack until <-> arrowheads work
1337
+ if (axisArrows === "<->" || axisArrows === true) {
1338
+ this.style(
1339
+ {
1340
+ stroke: options.isMobile
1341
+ ? KhanColors.GRAY_G
1342
+ : "#000000",
1343
+ opacity: options.isMobile ? 1 : axisOpacity,
1344
+ strokeWidth: options.isMobile ? 1 : 2,
1345
+ arrows: "->",
1346
+ },
1347
+ function () {
1348
+ if (range[1][0] < 0 && range[1][1] > 0) {
1349
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1350
+ this.path([
1351
+ axisCenter,
1352
+ [gridRange[0][0], axisCenter[1]],
1353
+ ]);
1354
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1355
+ this.path([
1356
+ axisCenter,
1357
+ [gridRange[0][1], axisCenter[1]],
1358
+ ]);
1359
+ }
1360
+ if (range[0][0] < 0 && range[0][1] > 0) {
1361
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1362
+ this.path([
1363
+ axisCenter,
1364
+ [axisCenter[0], gridRange[1][0]],
1365
+ ]);
1366
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1367
+ this.path([
1368
+ axisCenter,
1369
+ [axisCenter[0], gridRange[1][1]],
1370
+ ]);
1371
+ }
1372
+ },
1373
+ );
1374
+
1375
+ // also, we don't support "<-" arrows yet, but why you
1376
+ // would want that on your graph is beyond me.
1377
+ } else if (axisArrows === "->" || axisArrows === "") {
1378
+ this.style(
1379
+ {
1380
+ stroke: "#000000",
1381
+ opacity: axisOpacity,
1382
+ strokeWidth: 2,
1383
+ arrows: axisArrows,
1384
+ },
1385
+ function () {
1386
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1387
+ this.path([
1388
+ [gridRange[0][0], axisCenter[1]],
1389
+ [gridRange[0][1], axisCenter[1]],
1390
+ ]);
1391
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1392
+ this.path([
1393
+ [axisCenter[0], gridRange[1][0]],
1394
+ [axisCenter[0], gridRange[1][1]],
1395
+ ]);
1396
+ },
1397
+ );
1398
+ }
1399
+
1400
+ if (axisLabels && axisLabels.length === 2) {
1401
+ this.label(
1402
+ [gridRange[0][1], axisCenter[1]],
1403
+ axisLabels[0],
1404
+ "right",
1405
+ );
1406
+ this.label(
1407
+ [axisCenter[0], gridRange[1][1]],
1408
+ axisLabels[1],
1409
+ "above",
1410
+ );
1411
+ }
1412
+ }
1413
+
1414
+ // draw tick marks
1415
+ if (ticks) {
1416
+ const halfWidthTicks = options.isMobile;
1417
+ this.style(
1418
+ {
1419
+ stroke: options.isMobile ? KhanColors.GRAY_G : "#000000",
1420
+ opacity: options.isMobile ? 1 : tickOpacity,
1421
+ strokeWidth: 1,
1422
+ },
1423
+ function () {
1424
+ // horizontal axis
1425
+ let step = gridStep[0] * tickStep[0];
1426
+ let len = tickLen[0] / scale[1];
1427
+ let start = gridRange[0][0];
1428
+ let stop = gridRange[0][1];
1429
+
1430
+ if (range[1][0] < 0 && range[1][1] > 0) {
1431
+ for (
1432
+ let x = step + axisCenter[0];
1433
+ x <= stop;
1434
+ x += step
1435
+ ) {
1436
+ if (x < stop || !axisArrows) {
1437
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1438
+ this.line(
1439
+ [x, -len + axisCenter[1]],
1440
+ [
1441
+ x,
1442
+ halfWidthTicks
1443
+ ? 0
1444
+ : len + axisCenter[1],
1445
+ ],
1446
+ );
1447
+ }
1448
+ }
1449
+
1450
+ for (
1451
+ let x = -step + axisCenter[0];
1452
+ x >= start;
1453
+ x -= step
1454
+ ) {
1455
+ if (x > start || !axisArrows) {
1456
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1457
+ this.line(
1458
+ [x, -len + axisCenter[1]],
1459
+ [
1460
+ x,
1461
+ halfWidthTicks
1462
+ ? 0
1463
+ : len + axisCenter[1],
1464
+ ],
1465
+ );
1466
+ }
1467
+ }
1468
+ }
1469
+
1470
+ // vertical axis
1471
+ step = gridStep[1] * tickStep[1];
1472
+ len = tickLen[1] / scale[0];
1473
+ start = gridRange[1][0];
1474
+ stop = gridRange[1][1];
1475
+
1476
+ if (range[0][0] < 0 && range[0][1] > 0) {
1477
+ for (
1478
+ let y = step + axisCenter[1];
1479
+ y <= stop;
1480
+ y += step
1481
+ ) {
1482
+ if (y < stop || !axisArrows) {
1483
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1484
+ this.line(
1485
+ [-len + axisCenter[0], y],
1486
+ [
1487
+ halfWidthTicks
1488
+ ? 0
1489
+ : len + axisCenter[0],
1490
+ y,
1491
+ ],
1492
+ );
1493
+ }
1494
+ }
1495
+
1496
+ for (
1497
+ let y = -step + axisCenter[1];
1498
+ y >= start;
1499
+ y -= step
1500
+ ) {
1501
+ if (y > start || !axisArrows) {
1502
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1503
+ this.line(
1504
+ [-len + axisCenter[0], y],
1505
+ [
1506
+ halfWidthTicks
1507
+ ? 0
1508
+ : len + axisCenter[0],
1509
+ y,
1510
+ ],
1511
+ );
1512
+ }
1513
+ }
1514
+ }
1515
+ },
1516
+ );
1517
+ }
1518
+
1519
+ // draw axis labels
1520
+ if (labels) {
1521
+ this.style(
1522
+ {
1523
+ stroke: options.isMobile ? KhanColors.GRAY_G : "#000000",
1524
+ opacity: options.isMobile ? 1 : labelOpacity,
1525
+ },
1526
+ function () {
1527
+ // horizontal axis
1528
+ let step = gridStep[0] * tickStep[0] * labelStep[0];
1529
+ let start = gridRange[0][0];
1530
+ let stop = gridRange[0][1];
1531
+ const xAxisPosition = axisCenter[0] < 0 ? "above" : "below";
1532
+ const yAxisPosition = axisCenter[0] < 0 ? "right" : "left";
1533
+ const xShowZero =
1534
+ axisCenter[0] === 0 && axisCenter[1] !== 0;
1535
+ const yShowZero =
1536
+ axisCenter[0] !== 0 && axisCenter[1] === 0;
1537
+ const axisOffCenter =
1538
+ axisCenter[0] !== 0 || axisCenter[1] !== 0;
1539
+ const showUnityX = unityLabels[0] || axisOffCenter;
1540
+ const showUnityY = unityLabels[1] || axisOffCenter;
1541
+
1542
+ // positive x-axis
1543
+ for (
1544
+ let x = (xShowZero ? 0 : step) + axisCenter[0];
1545
+ x <= stop;
1546
+ x += step
1547
+ ) {
1548
+ if (x < stop || !axisArrows) {
1549
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1550
+ this.label(
1551
+ [x, axisCenter[1]],
1552
+ xLabelFormat(x),
1553
+ xAxisPosition,
1554
+ );
1555
+ }
1556
+ }
1557
+
1558
+ // negative x-axis
1559
+ for (
1560
+ let x = -step * (showUnityX ? 1 : 2) + axisCenter[0];
1561
+ x >= start;
1562
+ x -= step
1563
+ ) {
1564
+ if (x > start || !axisArrows) {
1565
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1566
+ this.label(
1567
+ [x, axisCenter[1]],
1568
+ xLabelFormat(x),
1569
+ xAxisPosition,
1570
+ );
1571
+ }
1572
+ }
1573
+
1574
+ step = gridStep[1] * tickStep[1] * labelStep[1];
1575
+ start = gridRange[1][0];
1576
+ stop = gridRange[1][1];
1577
+
1578
+ // positive y-axis
1579
+ for (
1580
+ let y = (yShowZero ? 0 : step) + axisCenter[1];
1581
+ y <= stop;
1582
+ y += step
1583
+ ) {
1584
+ if (y < stop || !axisArrows) {
1585
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1586
+ this.label(
1587
+ [axisCenter[0], y],
1588
+ yLabelFormat(y),
1589
+ yAxisPosition,
1590
+ );
1591
+ }
1592
+ }
1593
+
1594
+ // negative y-axis
1595
+ for (
1596
+ let y = -step * (showUnityY ? 1 : 2) + axisCenter[1];
1597
+ y >= start;
1598
+ y -= step
1599
+ ) {
1600
+ if (y > start || !axisArrows) {
1601
+ // @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
1602
+ this.label(
1603
+ [axisCenter[0], y],
1604
+ yLabelFormat(y),
1605
+ yAxisPosition,
1606
+ );
1607
+ }
1608
+ }
1609
+ },
1610
+ );
1611
+ }
1612
+ };
1613
+
1614
+ return graphie;
1615
+ };
1616
+
1617
+ export default GraphUtils;