@doenet/doenetml 0.6.0-alpha1

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 (549) hide show
  1. package/.prettierrc +3 -0
  2. package/LICENSE +661 -0
  3. package/README.md +146 -0
  4. package/cypress/e2e/ActivityViewer/activityVariants.cy.js +1770 -0
  5. package/cypress/e2e/ActivityViewer/compiledActivity.cy.js +83 -0
  6. package/cypress/e2e/ActivityViewer/relationshipsAmongPages.cy.js +697 -0
  7. package/cypress/e2e/answerValidation/errorinnumbers.cy.js +2125 -0
  8. package/cypress/e2e/answerValidation/factoring.cy.js +1945 -0
  9. package/cypress/e2e/answerValidation/factoringOldAlgorithm.cy.js +892 -0
  10. package/cypress/e2e/answerValidation/functionanswers.cy.js +314 -0
  11. package/cypress/e2e/answerValidation/matchingpatterns.cy.js +287 -0
  12. package/cypress/e2e/answerValidation/matchpartial.cy.js +6711 -0
  13. package/cypress/e2e/answerValidation/pointlocation.cy.js +3989 -0
  14. package/cypress/e2e/answerValidation/symbolicequality.cy.js +1893 -0
  15. package/cypress/e2e/answerValidation/videoProgress.cy.js +210 -0
  16. package/cypress/e2e/assignNames/basiccopy.cy.js +2376 -0
  17. package/cypress/e2e/assignNames/collections.cy.js +9247 -0
  18. package/cypress/e2e/assignNames/selects.cy.js +105 -0
  19. package/cypress/e2e/assignNames/sequences.cy.js +1964 -0
  20. package/cypress/e2e/baseComponent/basecomponentproperties.cy.js +999 -0
  21. package/cypress/e2e/baseComponent/doenetMLtext.cy.js +427 -0
  22. package/cypress/e2e/chemistry/atom.cy.js +201 -0
  23. package/cypress/e2e/chemistry/ion.cy.js +608 -0
  24. package/cypress/e2e/chemistry/ioniccompound.cy.js +133 -0
  25. package/cypress/e2e/dynamicalsystem/cobwebpolyline.cy.js +2653 -0
  26. package/cypress/e2e/dynamicalsystem/equilibriumcurve.cy.js +311 -0
  27. package/cypress/e2e/dynamicalsystem/equilibriumline.cy.js +279 -0
  28. package/cypress/e2e/dynamicalsystem/equilibriumpoint.cy.js +283 -0
  29. package/cypress/e2e/dynamicalsystem/odesystem.cy.js +1834 -0
  30. package/cypress/e2e/equality/mathexpressions.cy.js +948 -0
  31. package/cypress/e2e/graphing/graphreferences.cy.js +978 -0
  32. package/cypress/e2e/graphing/graphreferences2.cy.js +615 -0
  33. package/cypress/e2e/linearAlgebra/eigenDecomposition.cy.js +401 -0
  34. package/cypress/e2e/tagSpecific/angle.cy.js +3898 -0
  35. package/cypress/e2e/tagSpecific/animatefromsequence.cy.js +2306 -0
  36. package/cypress/e2e/tagSpecific/answer.cy.js +31647 -0
  37. package/cypress/e2e/tagSpecific/bestfitline.cy.js +612 -0
  38. package/cypress/e2e/tagSpecific/blockquote.cy.js +30 -0
  39. package/cypress/e2e/tagSpecific/boolean.cy.js +742 -0
  40. package/cypress/e2e/tagSpecific/booleaninput.cy.js +1283 -0
  41. package/cypress/e2e/tagSpecific/booleanlist.cy.js +588 -0
  42. package/cypress/e2e/tagSpecific/booleanoperators.cy.js +596 -0
  43. package/cypress/e2e/tagSpecific/booleanoperatorsonmath.cy.js +498 -0
  44. package/cypress/e2e/tagSpecific/callaction.cy.js +2835 -0
  45. package/cypress/e2e/tagSpecific/choiceinput.cy.js +3205 -0
  46. package/cypress/e2e/tagSpecific/circle.cy.js +22036 -0
  47. package/cypress/e2e/tagSpecific/codeeditor.cy.js +1995 -0
  48. package/cypress/e2e/tagSpecific/collect.cy.js +5035 -0
  49. package/cypress/e2e/tagSpecific/componentsize.cy.js +502 -0
  50. package/cypress/e2e/tagSpecific/conditionalcontent.cy.js +3495 -0
  51. package/cypress/e2e/tagSpecific/contentBrowser.cy.js +335 -0
  52. package/cypress/e2e/tagSpecific/contentpicker.cy.js +261 -0
  53. package/cypress/e2e/tagSpecific/copy.cy.js +12627 -0
  54. package/cypress/e2e/tagSpecific/copy2.cy.js +5698 -0
  55. package/cypress/e2e/tagSpecific/curve.bezier.cy.js +12440 -0
  56. package/cypress/e2e/tagSpecific/curve.cy.js +1716 -0
  57. package/cypress/e2e/tagSpecific/curve.function.cy.js +1471 -0
  58. package/cypress/e2e/tagSpecific/curve.parametrized.cy.js +920 -0
  59. package/cypress/e2e/tagSpecific/document.cy.js +234 -0
  60. package/cypress/e2e/tagSpecific/endpoint.cy.js +197 -0
  61. package/cypress/e2e/tagSpecific/evaluate.cy.js +8895 -0
  62. package/cypress/e2e/tagSpecific/extract.cy.js +2282 -0
  63. package/cypress/e2e/tagSpecific/feedback.cy.js +2941 -0
  64. package/cypress/e2e/tagSpecific/function.cy.js +9450 -0
  65. package/cypress/e2e/tagSpecific/functioniterates.cy.js +1178 -0
  66. package/cypress/e2e/tagSpecific/functionoperators.cy.js +4047 -0
  67. package/cypress/e2e/tagSpecific/graph.cy.js +2491 -0
  68. package/cypress/e2e/tagSpecific/group.cy.js +683 -0
  69. package/cypress/e2e/tagSpecific/hint.cy.js +204 -0
  70. package/cypress/e2e/tagSpecific/image.cy.js +770 -0
  71. package/cypress/e2e/tagSpecific/integer.cy.js +206 -0
  72. package/cypress/e2e/tagSpecific/label.cy.js +800 -0
  73. package/cypress/e2e/tagSpecific/legend.cy.js +1001 -0
  74. package/cypress/e2e/tagSpecific/line.cy.js +12167 -0
  75. package/cypress/e2e/tagSpecific/linesegment.cy.js +4749 -0
  76. package/cypress/e2e/tagSpecific/lorem.cy.js +289 -0
  77. package/cypress/e2e/tagSpecific/map.cy.js +4476 -0
  78. package/cypress/e2e/tagSpecific/matchespattern.cy.js +693 -0
  79. package/cypress/e2e/tagSpecific/math.cy.js +10990 -0
  80. package/cypress/e2e/tagSpecific/mathdisplay.cy.js +2689 -0
  81. package/cypress/e2e/tagSpecific/mathinput.cy.js +15628 -0
  82. package/cypress/e2e/tagSpecific/mathinputgraph.cy.js +566 -0
  83. package/cypress/e2e/tagSpecific/mathlist.cy.js +4073 -0
  84. package/cypress/e2e/tagSpecific/mathoperators.cy.js +13851 -0
  85. package/cypress/e2e/tagSpecific/matrix.cy.js +8825 -0
  86. package/cypress/e2e/tagSpecific/matrixinput.cy.js +16277 -0
  87. package/cypress/e2e/tagSpecific/module.cy.js +1771 -0
  88. package/cypress/e2e/tagSpecific/number.cy.js +2221 -0
  89. package/cypress/e2e/tagSpecific/numberlist.cy.js +1285 -0
  90. package/cypress/e2e/tagSpecific/p.cy.js +72 -0
  91. package/cypress/e2e/tagSpecific/paginator.cy.js +2983 -0
  92. package/cypress/e2e/tagSpecific/parabola.cy.js +14331 -0
  93. package/cypress/e2e/tagSpecific/paragraphmarkup.cy.js +104 -0
  94. package/cypress/e2e/tagSpecific/periodicset.cy.js +1439 -0
  95. package/cypress/e2e/tagSpecific/piecewisefunction.cy.js +1055 -0
  96. package/cypress/e2e/tagSpecific/pluralize.cy.js +274 -0
  97. package/cypress/e2e/tagSpecific/point.cy.js +8895 -0
  98. package/cypress/e2e/tagSpecific/point2.cy.js +10259 -0
  99. package/cypress/e2e/tagSpecific/polygon.cy.js +5039 -0
  100. package/cypress/e2e/tagSpecific/polyline.cy.js +4704 -0
  101. package/cypress/e2e/tagSpecific/problem.cy.js +2768 -0
  102. package/cypress/e2e/tagSpecific/ray.cy.js +10770 -0
  103. package/cypress/e2e/tagSpecific/rectangle.cy.js +2143 -0
  104. package/cypress/e2e/tagSpecific/ref.cy.js +420 -0
  105. package/cypress/e2e/tagSpecific/regularPolygon.cy.js +1006 -0
  106. package/cypress/e2e/tagSpecific/regularPolygon2.cy.js +100 -0
  107. package/cypress/e2e/tagSpecific/regularPolygon3.cy.js +777 -0
  108. package/cypress/e2e/tagSpecific/samplerandomnumbers.cy.js +3619 -0
  109. package/cypress/e2e/tagSpecific/sectioning.cy.js +3530 -0
  110. package/cypress/e2e/tagSpecific/select.cy.js +5376 -0
  111. package/cypress/e2e/tagSpecific/selectfromsequence.cy.js +3846 -0
  112. package/cypress/e2e/tagSpecific/selectrandomnumbers.cy.js +2914 -0
  113. package/cypress/e2e/tagSpecific/sequence.cy.js +2093 -0
  114. package/cypress/e2e/tagSpecific/shuffle.cy.js +490 -0
  115. package/cypress/e2e/tagSpecific/sidebyside.cy.js +8057 -0
  116. package/cypress/e2e/tagSpecific/singlecharactercomponents.cy.js +72 -0
  117. package/cypress/e2e/tagSpecific/slider.cy.js +914 -0
  118. package/cypress/e2e/tagSpecific/solution.cy.js +109 -0
  119. package/cypress/e2e/tagSpecific/solveequations.cy.js +1026 -0
  120. package/cypress/e2e/tagSpecific/sort.cy.js +1685 -0
  121. package/cypress/e2e/tagSpecific/spreadsheet.cy.js +5971 -0
  122. package/cypress/e2e/tagSpecific/subsetofreals.cy.js +2725 -0
  123. package/cypress/e2e/tagSpecific/substitute.cy.js +2646 -0
  124. package/cypress/e2e/tagSpecific/tabular.cy.js +36 -0
  125. package/cypress/e2e/tagSpecific/text.cy.js +975 -0
  126. package/cypress/e2e/tagSpecific/textinput.cy.js +2177 -0
  127. package/cypress/e2e/tagSpecific/textlist.cy.js +369 -0
  128. package/cypress/e2e/tagSpecific/triangle.cy.js +1936 -0
  129. package/cypress/e2e/tagSpecific/triggerset.cy.js +2023 -0
  130. package/cypress/e2e/tagSpecific/updatevalue.cy.js +3288 -0
  131. package/cypress/e2e/tagSpecific/vector.cy.js +20183 -0
  132. package/cypress/e2e/tagSpecific/video.cy.js +612 -0
  133. package/cypress/e2e/tagSpecific/when.cy.js +202 -0
  134. package/cypress/e2e/variants/specifysinglevariant.cy.js +6726 -0
  135. package/cypress/e2e/variants/uniquevariants.cy.js +4846 -0
  136. package/cypress/fixtures/example.json +5 -0
  137. package/cypress/support/commands.js +32 -0
  138. package/cypress/support/e2e.js +31 -0
  139. package/cypress.config.js +18 -0
  140. package/docs/codeSnippet.jsx +11 -0
  141. package/docs/index.html +133 -0
  142. package/docs/index.jsx +138 -0
  143. package/docs/prism.css +3 -0
  144. package/index.html +14 -0
  145. package/index.js +21 -0
  146. package/media/answer_example.png +0 -0
  147. package/media/graph_example.png +0 -0
  148. package/media/graph_markup_example.png +0 -0
  149. package/package.json +83 -0
  150. package/public/favicon.ico +0 -0
  151. package/public/fonts/files/open-sans-v18-latin-700.woff +0 -0
  152. package/public/fonts/files/open-sans-v18-latin-700.woff2 +0 -0
  153. package/public/fonts/files/open-sans-v18-latin-700italic.woff +0 -0
  154. package/public/fonts/files/open-sans-v18-latin-700italic.woff2 +0 -0
  155. package/public/fonts/files/open-sans-v18-latin-italic.woff +0 -0
  156. package/public/fonts/files/open-sans-v18-latin-italic.woff2 +0 -0
  157. package/public/fonts/files/open-sans-v18-latin-light-italic.woff +0 -0
  158. package/public/fonts/files/open-sans-v18-latin-light-italic.woff2 +0 -0
  159. package/public/fonts/files/open-sans-v18-latin-light.woff +0 -0
  160. package/public/fonts/files/open-sans-v18-latin-light.woff2 +0 -0
  161. package/public/fonts/files/open-sans-v18-latin-regular.woff +0 -0
  162. package/public/fonts/files/open-sans-v18-latin-regular.woff2 +0 -0
  163. package/src/Core/ComponentTypes.js +426 -0
  164. package/src/Core/Core.js +11852 -0
  165. package/src/Core/CoreWorker.js +127 -0
  166. package/src/Core/Dependencies.js +8226 -0
  167. package/src/Core/Numerics.js +473 -0
  168. package/src/Core/ParameterStack.js +36 -0
  169. package/src/Core/ReadOnlyProxyHandler.js +41 -0
  170. package/src/Core/StateProxyHandler.js +88 -0
  171. package/src/Core/components/Aliases.js +67 -0
  172. package/src/Core/components/Angle.js +758 -0
  173. package/src/Core/components/AnimateFromSequence.js +922 -0
  174. package/src/Core/components/Answer.js +2087 -0
  175. package/src/Core/components/AsList.js +83 -0
  176. package/src/Core/components/AttractTo.js +245 -0
  177. package/src/Core/components/AttractToAngles.js +262 -0
  178. package/src/Core/components/AttractToConstraint.js +104 -0
  179. package/src/Core/components/AttractToGrid.js +315 -0
  180. package/src/Core/components/Award.js +906 -0
  181. package/src/Core/components/BestFitLine.js +318 -0
  182. package/src/Core/components/BezierControls.js +719 -0
  183. package/src/Core/components/BlockQuote.js +35 -0
  184. package/src/Core/components/Boolean.js +500 -0
  185. package/src/Core/components/BooleanInput.js +330 -0
  186. package/src/Core/components/BooleanList.js +396 -0
  187. package/src/Core/components/BooleanOperators.js +35 -0
  188. package/src/Core/components/BooleanOperatorsOfMath.js +148 -0
  189. package/src/Core/components/CallAction.js +261 -0
  190. package/src/Core/components/Caption.js +73 -0
  191. package/src/Core/components/Case.js +56 -0
  192. package/src/Core/components/Cell.js +439 -0
  193. package/src/Core/components/CellBlock.js +64 -0
  194. package/src/Core/components/Chart.js +795 -0
  195. package/src/Core/components/Choice.js +266 -0
  196. package/src/Core/components/ChoiceInput.js +1407 -0
  197. package/src/Core/components/Circle.js +2884 -0
  198. package/src/Core/components/CodeEditor.js +647 -0
  199. package/src/Core/components/CodeViewer.js +294 -0
  200. package/src/Core/components/CollaborateGroupSetup.js +46 -0
  201. package/src/Core/components/CollaborateGroups.js +119 -0
  202. package/src/Core/components/Collect.js +850 -0
  203. package/src/Core/components/Column.js +608 -0
  204. package/src/Core/components/ConditionalContent.js +468 -0
  205. package/src/Core/components/ConsiderAsResponses.js +49 -0
  206. package/src/Core/components/ConstrainTo.js +161 -0
  207. package/src/Core/components/ConstrainToAngles.js +244 -0
  208. package/src/Core/components/ConstrainToGraph.js +142 -0
  209. package/src/Core/components/ConstrainToGrid.js +175 -0
  210. package/src/Core/components/ConstraintUnion.js +119 -0
  211. package/src/Core/components/Constraints.js +497 -0
  212. package/src/Core/components/ContentBrowser.js +441 -0
  213. package/src/Core/components/ContentPicker.js +263 -0
  214. package/src/Core/components/ControlVectors.js +25 -0
  215. package/src/Core/components/Coords.js +63 -0
  216. package/src/Core/components/Copy.js +3412 -0
  217. package/src/Core/components/Curve.js +4130 -0
  218. package/src/Core/components/CustomAttribute.js +175 -0
  219. package/src/Core/components/DataFrame.js +357 -0
  220. package/src/Core/components/DiscreteSimulationResultList.js +342 -0
  221. package/src/Core/components/DiscreteSimulationResultPolyline.js +581 -0
  222. package/src/Core/components/Divisions.js +55 -0
  223. package/src/Core/components/Document.js +888 -0
  224. package/src/Core/components/Embed.js +65 -0
  225. package/src/Core/components/Endpoint.js +62 -0
  226. package/src/Core/components/Evaluate.js +321 -0
  227. package/src/Core/components/Extract.js +656 -0
  228. package/src/Core/components/Extrema.js +556 -0
  229. package/src/Core/components/Feedback.js +200 -0
  230. package/src/Core/components/FeedbackDefinitions.js +97 -0
  231. package/src/Core/components/Figure.js +148 -0
  232. package/src/Core/components/Footnote.js +73 -0
  233. package/src/Core/components/Function.js +5344 -0
  234. package/src/Core/components/FunctionIterates.js +306 -0
  235. package/src/Core/components/FunctionOperators.js +702 -0
  236. package/src/Core/components/Graph.js +1679 -0
  237. package/src/Core/components/Group.js +7 -0
  238. package/src/Core/components/HasSameFactoring.js +407 -0
  239. package/src/Core/components/Hint.js +241 -0
  240. package/src/Core/components/Image.js +524 -0
  241. package/src/Core/components/Indexing.js +79 -0
  242. package/src/Core/components/IntComma.js +64 -0
  243. package/src/Core/components/Integer.js +81 -0
  244. package/src/Core/components/Intersection.js +328 -0
  245. package/src/Core/components/Interval.js +29 -0
  246. package/src/Core/components/Label.js +492 -0
  247. package/src/Core/components/Latex.js +104 -0
  248. package/src/Core/components/Legend.js +329 -0
  249. package/src/Core/components/Line.js +2040 -0
  250. package/src/Core/components/LineSegment.js +882 -0
  251. package/src/Core/components/Lists.js +180 -0
  252. package/src/Core/components/Lorem.js +249 -0
  253. package/src/Core/components/MMeMen.js +377 -0
  254. package/src/Core/components/Map.js +873 -0
  255. package/src/Core/components/Markers.js +101 -0
  256. package/src/Core/components/MatchesPattern.js +339 -0
  257. package/src/Core/components/Math.js +2552 -0
  258. package/src/Core/components/MathInput.js +948 -0
  259. package/src/Core/components/MathList.js +828 -0
  260. package/src/Core/components/MathOperators.js +1286 -0
  261. package/src/Core/components/Matrix.js +497 -0
  262. package/src/Core/components/MatrixInput.js +3157 -0
  263. package/src/Core/components/MdMdnMrow.js +394 -0
  264. package/src/Core/components/Module.js +16 -0
  265. package/src/Core/components/Number.js +1031 -0
  266. package/src/Core/components/NumberList.js +550 -0
  267. package/src/Core/components/Option.js +24 -0
  268. package/src/Core/components/P.js +71 -0
  269. package/src/Core/components/Paginator.js +338 -0
  270. package/src/Core/components/Panel.js +126 -0
  271. package/src/Core/components/Parabola.js +1561 -0
  272. package/src/Core/components/ParagraphMarkup.js +59 -0
  273. package/src/Core/components/Pegboard.js +43 -0
  274. package/src/Core/components/PeriodicSet.js +291 -0
  275. package/src/Core/components/PiecewiseFunction.js +832 -0
  276. package/src/Core/components/Pluralize.js +198 -0
  277. package/src/Core/components/Point.js +1295 -0
  278. package/src/Core/components/Polygon.js +408 -0
  279. package/src/Core/components/Polyline.js +841 -0
  280. package/src/Core/components/RandomizedTextList.js +225 -0
  281. package/src/Core/components/Ray.js +1737 -0
  282. package/src/Core/components/Rectangle.js +1535 -0
  283. package/src/Core/components/Ref.js +350 -0
  284. package/src/Core/components/RegionBetweenCurveXAxis.js +124 -0
  285. package/src/Core/components/RegionHalfPlane.js +107 -0
  286. package/src/Core/components/RegularPolygon.js +2118 -0
  287. package/src/Core/components/RenderDoenetML.js +181 -0
  288. package/src/Core/components/Row.js +780 -0
  289. package/src/Core/components/SampleRandomNumbers.js +653 -0
  290. package/src/Core/components/Sectioning.js +303 -0
  291. package/src/Core/components/Select.js +947 -0
  292. package/src/Core/components/SelectFromSequence.js +1242 -0
  293. package/src/Core/components/SelectRandomNumbers.js +225 -0
  294. package/src/Core/components/Sequence.js +444 -0
  295. package/src/Core/components/Setup.js +53 -0
  296. package/src/Core/components/Shuffle.js +470 -0
  297. package/src/Core/components/SideBySide.js +2130 -0
  298. package/src/Core/components/SingleCharacterComponents.js +41 -0
  299. package/src/Core/components/Slider.js +819 -0
  300. package/src/Core/components/SolutionContainer.js +67 -0
  301. package/src/Core/components/Solutions.js +334 -0
  302. package/src/Core/components/SolveEquations.js +568 -0
  303. package/src/Core/components/Sort.js +398 -0
  304. package/src/Core/components/Sources.js +108 -0
  305. package/src/Core/components/Split.js +205 -0
  306. package/src/Core/components/Spreadsheet.js +1507 -0
  307. package/src/Core/components/StyleDefinitions.js +111 -0
  308. package/src/Core/components/SubsetOfReals.js +348 -0
  309. package/src/Core/components/SubsetOfRealsInput.js +1474 -0
  310. package/src/Core/components/Substitute.js +496 -0
  311. package/src/Core/components/SummaryStatistics.js +652 -0
  312. package/src/Core/components/Table.js +145 -0
  313. package/src/Core/components/Tabular.js +384 -0
  314. package/src/Core/components/Template.js +360 -0
  315. package/src/Core/components/Text.js +341 -0
  316. package/src/Core/components/TextInput.js +566 -0
  317. package/src/Core/components/TextList.js +442 -0
  318. package/src/Core/components/TextListFromString.js +137 -0
  319. package/src/Core/components/TextOperatorsOfMath.js +21 -0
  320. package/src/Core/components/Triangle.js +280 -0
  321. package/src/Core/components/TriggerSet.js +189 -0
  322. package/src/Core/components/TupleList.js +43 -0
  323. package/src/Core/components/UpdateValue.js +435 -0
  324. package/src/Core/components/VariantControl.js +36 -0
  325. package/src/Core/components/Vector.js +2478 -0
  326. package/src/Core/components/Verbatim.js +125 -0
  327. package/src/Core/components/Video.js +673 -0
  328. package/src/Core/components/When.js +198 -0
  329. package/src/Core/components/abstract/AngleListComponent.js +140 -0
  330. package/src/Core/components/abstract/BaseComponent.js +1496 -0
  331. package/src/Core/components/abstract/BlockComponent.js +5 -0
  332. package/src/Core/components/abstract/BooleanBaseOperator.js +88 -0
  333. package/src/Core/components/abstract/BooleanBaseOperatorOfMath.js +100 -0
  334. package/src/Core/components/abstract/BooleanBaseOperatorOneInput.js +44 -0
  335. package/src/Core/components/abstract/ComponentSize.js +789 -0
  336. package/src/Core/components/abstract/ComponentWithSelectableType.js +537 -0
  337. package/src/Core/components/abstract/CompositeComponent.js +142 -0
  338. package/src/Core/components/abstract/ConstraintComponent.js +19 -0
  339. package/src/Core/components/abstract/FunctionBaseOperator.js +680 -0
  340. package/src/Core/components/abstract/GraphicalComponent.js +56 -0
  341. package/src/Core/components/abstract/InlineComponent.js +5 -0
  342. package/src/Core/components/abstract/InlineRenderInlineChildren.js +63 -0
  343. package/src/Core/components/abstract/Input.js +192 -0
  344. package/src/Core/components/abstract/IntervalListComponent.js +218 -0
  345. package/src/Core/components/abstract/LineListComponent.js +114 -0
  346. package/src/Core/components/abstract/MathBaseOperator.js +631 -0
  347. package/src/Core/components/abstract/MathBaseOperatorOneInput.js +112 -0
  348. package/src/Core/components/abstract/PointListComponent.js +238 -0
  349. package/src/Core/components/abstract/SectioningComponent.js +1262 -0
  350. package/src/Core/components/abstract/SingleCharacterInline.js +23 -0
  351. package/src/Core/components/abstract/TextBaseOperatorOfMath.js +47 -0
  352. package/src/Core/components/abstract/TextOrInline.js +66 -0
  353. package/src/Core/components/abstract/VariableName.js +31 -0
  354. package/src/Core/components/abstract/VariableNameList.js +83 -0
  355. package/src/Core/components/abstract/VectorListComponent.js +235 -0
  356. package/src/Core/components/chemistry/Atom.js +910 -0
  357. package/src/Core/components/chemistry/ElectronConfiguration.js +36 -0
  358. package/src/Core/components/chemistry/Ion.js +684 -0
  359. package/src/Core/components/chemistry/IonicCompound.js +189 -0
  360. package/src/Core/components/chemistry/OrbitalDiagram.js +175 -0
  361. package/src/Core/components/chemistry/OrbitalDiagramInput.js +753 -0
  362. package/src/Core/components/chemistry/index.js +6 -0
  363. package/src/Core/components/commonsugar/breakstrings.js +627 -0
  364. package/src/Core/components/commonsugar/lists.js +177 -0
  365. package/src/Core/components/dynamicalSystems/CobwebPolyline.js +913 -0
  366. package/src/Core/components/dynamicalSystems/EquilibriumCurve.js +95 -0
  367. package/src/Core/components/dynamicalSystems/EquilibriumLine.js +93 -0
  368. package/src/Core/components/dynamicalSystems/EquilibriumPoint.js +93 -0
  369. package/src/Core/components/dynamicalSystems/ODESystem.js +943 -0
  370. package/src/Core/components/dynamicalSystems/index.js +5 -0
  371. package/src/Core/components/linearAlgebra/EigenDecomposition.js +294 -0
  372. package/src/Core/utils/array.js +30 -0
  373. package/src/Core/utils/booleanLogic.js +965 -0
  374. package/src/Core/utils/checkEquality.js +818 -0
  375. package/src/Core/utils/cid.js +29 -0
  376. package/src/Core/utils/componentInfoObjects.js +100 -0
  377. package/src/Core/utils/constraints.js +23 -0
  378. package/src/Core/utils/copy.js +572 -0
  379. package/src/Core/utils/deepFunctions.js +173 -0
  380. package/src/Core/utils/descendants.js +252 -0
  381. package/src/Core/utils/enumeration.js +234 -0
  382. package/src/Core/utils/feedback.js +84 -0
  383. package/src/Core/utils/function.js +1343 -0
  384. package/src/Core/utils/graphical.js +196 -0
  385. package/src/Core/utils/label.js +396 -0
  386. package/src/Core/utils/math.js +1056 -0
  387. package/src/Core/utils/naming.js +45 -0
  388. package/src/Core/utils/periodicSetEquality.js +403 -0
  389. package/src/Core/utils/randomNumbers.js +70 -0
  390. package/src/Core/utils/retrieveMedia.js +98 -0
  391. package/src/Core/utils/retrieveTextFile.js +140 -0
  392. package/src/Core/utils/returnAllPossibleVariants.js +73 -0
  393. package/src/Core/utils/rounding.js +316 -0
  394. package/src/Core/utils/sequence.js +754 -0
  395. package/src/Core/utils/serializedStateProcessing.js +4049 -0
  396. package/src/Core/utils/size.js +22 -0
  397. package/src/Core/utils/stateVariables.js +138 -0
  398. package/src/Core/utils/style.js +535 -0
  399. package/src/Core/utils/subset-of-reals.js +796 -0
  400. package/src/Core/utils/table.js +41 -0
  401. package/src/Core/utils/text.js +16 -0
  402. package/src/Core/utils/triggering.js +167 -0
  403. package/src/Core/utils/variants.js +477 -0
  404. package/src/DoenetML.css +308 -0
  405. package/src/DoenetML.jsx +201 -0
  406. package/src/Parser/doenet.grammar +90 -0
  407. package/src/Parser/doenet.js +33 -0
  408. package/src/Parser/doenet.terms.js +20 -0
  409. package/src/Parser/parser.js +266 -0
  410. package/src/Parser/tokens.js +129 -0
  411. package/src/Tools/CodeMirror.jsx +440 -0
  412. package/src/Tools/DarkmodeController.jsx +21 -0
  413. package/src/Tools/Footers/MathInputSelector.jsx +34 -0
  414. package/src/Tools/Footers/VirtualKeyboard.jsx +751 -0
  415. package/src/Tools/cypressTest/CypressTest.jsx +341 -0
  416. package/src/Tools/cypressTest/index.html +102 -0
  417. package/src/Tools/cypressTest/index.jsx +40 -0
  418. package/src/Viewer/ActivityViewer.jsx +1461 -0
  419. package/src/Viewer/PageViewer.jsx +1329 -0
  420. package/src/Viewer/renderers/alert.jsx +17 -0
  421. package/src/Viewer/renderers/angle.jsx +209 -0
  422. package/src/Viewer/renderers/answer.jsx +206 -0
  423. package/src/Viewer/renderers/asList.jsx +25 -0
  424. package/src/Viewer/renderers/blockQuote.jsx +41 -0
  425. package/src/Viewer/renderers/boolean.jsx +17 -0
  426. package/src/Viewer/renderers/booleanInput.css +105 -0
  427. package/src/Viewer/renderers/booleanInput.jsx +636 -0
  428. package/src/Viewer/renderers/button.jsx +369 -0
  429. package/src/Viewer/renderers/c.jsx +17 -0
  430. package/src/Viewer/renderers/callAction.jsx +18 -0
  431. package/src/Viewer/renderers/cell.jsx +59 -0
  432. package/src/Viewer/renderers/chart.jsx +83 -0
  433. package/src/Viewer/renderers/choiceInput.css +223 -0
  434. package/src/Viewer/renderers/choiceInput.jsx +535 -0
  435. package/src/Viewer/renderers/circle.jsx +990 -0
  436. package/src/Viewer/renderers/cobwebPolyline.jsx +442 -0
  437. package/src/Viewer/renderers/codeEditor.jsx +248 -0
  438. package/src/Viewer/renderers/codeViewer.jsx +105 -0
  439. package/src/Viewer/renderers/containerBlock.jsx +41 -0
  440. package/src/Viewer/renderers/containerInline.jsx +17 -0
  441. package/src/Viewer/renderers/contentBrowser.jsx +159 -0
  442. package/src/Viewer/renderers/contentPicker.jsx +160 -0
  443. package/src/Viewer/renderers/curve.jsx +1072 -0
  444. package/src/Viewer/renderers/ellipsis.jsx +17 -0
  445. package/src/Viewer/renderers/em.jsx +17 -0
  446. package/src/Viewer/renderers/embed.jsx +110 -0
  447. package/src/Viewer/renderers/feedback.jsx +74 -0
  448. package/src/Viewer/renderers/figure.jsx +131 -0
  449. package/src/Viewer/renderers/footnote.jsx +52 -0
  450. package/src/Viewer/renderers/graph.jsx +925 -0
  451. package/src/Viewer/renderers/hint.jsx +142 -0
  452. package/src/Viewer/renderers/image.jsx +581 -0
  453. package/src/Viewer/renderers/jsxgraph-distrib/jsxgraphcore.mjs +2 -0
  454. package/src/Viewer/renderers/jsxgraph-distrib/jsxgraphcore.mjs.map +1 -0
  455. package/src/Viewer/renderers/label.jsx +470 -0
  456. package/src/Viewer/renderers/legend.jsx +306 -0
  457. package/src/Viewer/renderers/line.jsx +511 -0
  458. package/src/Viewer/renderers/lineSegment.jsx +754 -0
  459. package/src/Viewer/renderers/list.jsx +111 -0
  460. package/src/Viewer/renderers/lq.jsx +12 -0
  461. package/src/Viewer/renderers/lsq.jsx +12 -0
  462. package/src/Viewer/renderers/math.jsx +582 -0
  463. package/src/Viewer/renderers/mathInput.css +10 -0
  464. package/src/Viewer/renderers/mathInput.jsx +425 -0
  465. package/src/Viewer/renderers/mathInputog.jsx +534 -0
  466. package/src/Viewer/renderers/mathList.jsx +39 -0
  467. package/src/Viewer/renderers/matrixInput.jsx +317 -0
  468. package/src/Viewer/renderers/mdash.jsx +12 -0
  469. package/src/Viewer/renderers/nbsp.jsx +12 -0
  470. package/src/Viewer/renderers/ndash.jsx +12 -0
  471. package/src/Viewer/renderers/number.jsx +454 -0
  472. package/src/Viewer/renderers/numberList.jsx +35 -0
  473. package/src/Viewer/renderers/orbitalDiagram.jsx +247 -0
  474. package/src/Viewer/renderers/orbitalDiagramInput.jsx +450 -0
  475. package/src/Viewer/renderers/p.jsx +38 -0
  476. package/src/Viewer/renderers/paginatorControls.jsx +41 -0
  477. package/src/Viewer/renderers/pegboard.jsx +239 -0
  478. package/src/Viewer/renderers/point.jsx +649 -0
  479. package/src/Viewer/renderers/polygon.jsx +612 -0
  480. package/src/Viewer/renderers/polyline.jsx +608 -0
  481. package/src/Viewer/renderers/pre.jsx +34 -0
  482. package/src/Viewer/renderers/q.jsx +17 -0
  483. package/src/Viewer/renderers/ray.jsx +410 -0
  484. package/src/Viewer/renderers/ref.jsx +149 -0
  485. package/src/Viewer/renderers/regionBetweenCurveXAxis.jsx +182 -0
  486. package/src/Viewer/renderers/renderDoenetML.jsx +56 -0
  487. package/src/Viewer/renderers/row.jsx +31 -0
  488. package/src/Viewer/renderers/rq.jsx +12 -0
  489. package/src/Viewer/renderers/rsq.jsx +12 -0
  490. package/src/Viewer/renderers/section.jsx +427 -0
  491. package/src/Viewer/renderers/sideBySide.jsx +80 -0
  492. package/src/Viewer/renderers/slider.jsx +800 -0
  493. package/src/Viewer/renderers/solution.jsx +134 -0
  494. package/src/Viewer/renderers/spreadsheet.jsx +83 -0
  495. package/src/Viewer/renderers/sq.jsx +17 -0
  496. package/src/Viewer/renderers/styles/global.css +14 -0
  497. package/src/Viewer/renderers/subsetOfRealsInput.jsx +392 -0
  498. package/src/Viewer/renderers/summaryStatistics.jsx +83 -0
  499. package/src/Viewer/renderers/table.jsx +78 -0
  500. package/src/Viewer/renderers/tabular.jsx +58 -0
  501. package/src/Viewer/renderers/tag.jsx +26 -0
  502. package/src/Viewer/renderers/text.jsx +439 -0
  503. package/src/Viewer/renderers/textInput.jsx +774 -0
  504. package/src/Viewer/renderers/textList.jsx +30 -0
  505. package/src/Viewer/renderers/triggerSet.jsx +52 -0
  506. package/src/Viewer/renderers/updateValue.jsx +30 -0
  507. package/src/Viewer/renderers/utils/css.js +13 -0
  508. package/src/Viewer/renderers/utils/graph.js +159 -0
  509. package/src/Viewer/renderers/utils/offGraphIndicators.js +91 -0
  510. package/src/Viewer/renderers/vector.jsx +678 -0
  511. package/src/Viewer/renderers/video.jsx +494 -0
  512. package/src/Viewer/useDoenetRenderer.jsx +128 -0
  513. package/src/main.jsx +16 -0
  514. package/src/media/fonts/files/open-sans-v18-latin-700.woff +0 -0
  515. package/src/media/fonts/files/open-sans-v18-latin-700.woff2 +0 -0
  516. package/src/media/fonts/files/open-sans-v18-latin-700italic.woff +0 -0
  517. package/src/media/fonts/files/open-sans-v18-latin-700italic.woff2 +0 -0
  518. package/src/media/fonts/files/open-sans-v18-latin-italic.woff +0 -0
  519. package/src/media/fonts/files/open-sans-v18-latin-italic.woff2 +0 -0
  520. package/src/media/fonts/files/open-sans-v18-latin-light-italic.woff +0 -0
  521. package/src/media/fonts/files/open-sans-v18-latin-light-italic.woff2 +0 -0
  522. package/src/media/fonts/files/open-sans-v18-latin-light.woff +0 -0
  523. package/src/media/fonts/files/open-sans-v18-latin-light.woff2 +0 -0
  524. package/src/media/fonts/files/open-sans-v18-latin-regular.woff +0 -0
  525. package/src/media/fonts/files/open-sans-v18-latin-regular.woff2 +0 -0
  526. package/src/test/testCode.doenet +26 -0
  527. package/src/test/testViewer.jsx +158 -0
  528. package/src/uiComponents/ActionButton.jsx +157 -0
  529. package/src/uiComponents/ActionButtonGroup.jsx +93 -0
  530. package/src/uiComponents/Button.jsx +160 -0
  531. package/src/uiComponents/ButtonGroup.jsx +56 -0
  532. package/src/uiComponents/ToggleButton.jsx +194 -0
  533. package/src/uiComponents/ToggleButtonGroup.jsx +77 -0
  534. package/src/utils/activityUtils.js +713 -0
  535. package/src/utils/array.js +17 -0
  536. package/src/utils/cid.js +34 -0
  537. package/src/utils/componentInfoObjects.js +89 -0
  538. package/src/utils/deepFunctions.js +165 -0
  539. package/src/utils/enumeration.js +226 -0
  540. package/src/utils/math.js +624 -0
  541. package/src/utils/naming.js +44 -0
  542. package/src/utils/retrieveTextFile.js +156 -0
  543. package/src/utils/returnAllPossibleVariants.js +81 -0
  544. package/src/utils/sequence.js +715 -0
  545. package/src/utils/serialize.js +29 -0
  546. package/src/utils/serializedStateProcessing.js +2587 -0
  547. package/src/utils/subset-of-reals.js +783 -0
  548. package/src/utils/url.js +19 -0
  549. package/vite.config.js +14 -0
@@ -0,0 +1,2087 @@
1
+ import InlineComponent from "./abstract/InlineComponent";
2
+ import { deepCompare } from "../utils/deepFunctions";
3
+ import { renameStateVariable } from "../utils/stateVariables";
4
+ import {
5
+ serializedComponentsReplacer,
6
+ serializedComponentsReviver,
7
+ } from "../utils/serializedStateProcessing";
8
+ import sha1 from "crypto-js/sha1";
9
+ import Base64 from "crypto-js/enc-base64";
10
+ import stringify from "json-stringify-deterministic";
11
+ import me from "math-expressions";
12
+
13
+ export default class Answer extends InlineComponent {
14
+ constructor(args) {
15
+ super(args);
16
+
17
+ Object.assign(this.actions, {
18
+ submitAnswer: this.submitAnswer.bind(this),
19
+ });
20
+ }
21
+ static componentType = "answer";
22
+
23
+ static renderChildren = true;
24
+
25
+ static variableForPlainMacro = "submittedResponses";
26
+ static variableForPlainCopy = "submittedResponses";
27
+
28
+ static includeBlankStringChildren = true;
29
+ static removeBlankStringChildrenPostSugar = true;
30
+
31
+ static processWhenJustUpdatedForNewComponent = true;
32
+
33
+ static createAttributesObject() {
34
+ let attributes = super.createAttributesObject();
35
+ attributes.weight = {
36
+ createComponentOfType: "number",
37
+ createStateVariable: "weight",
38
+ defaultValue: 1,
39
+ public: true,
40
+ };
41
+ attributes.handGraded = {
42
+ createPrimitiveOfType: "boolean",
43
+ createStateVariable: "handGraded",
44
+ defaultValue: false,
45
+ public: true,
46
+ };
47
+ attributes.inline = {
48
+ createComponentOfType: "boolean",
49
+ createStateVariable: "inline",
50
+ defaultValue: false,
51
+ public: true,
52
+ };
53
+ attributes.symbolicEquality = {
54
+ createComponentOfType: "boolean",
55
+ createStateVariable: "symbolicEquality",
56
+ defaultValue: false,
57
+ public: true,
58
+ };
59
+ attributes.matchPartial = {
60
+ createComponentOfType: "boolean",
61
+ createStateVariable: "matchPartial",
62
+ defaultValue: false,
63
+ public: true,
64
+ };
65
+ attributes.forceFullCheckworkButton = {
66
+ createComponentOfType: "boolean",
67
+ createStateVariable: "forceFullCheckworkButton",
68
+ defaultValue: false,
69
+ public: true,
70
+ };
71
+ attributes.simplifyOnCompare = {
72
+ createComponentOfType: "text",
73
+ createStateVariable: "simplifyOnCompare",
74
+ defaultValue: "none",
75
+ toLowerCase: true,
76
+ valueTransformations: { "": "full", true: "full", false: "none" },
77
+ validValues: ["none", "full", "numbers", "numberspreserveorder"],
78
+ public: true,
79
+ };
80
+ attributes.expandOnCompare = {
81
+ createComponentOfType: "boolean",
82
+ createStateVariable: "expandOnCompare",
83
+ defaultValue: false,
84
+ public: true,
85
+ };
86
+ attributes.unorderedCompare = {
87
+ createComponentOfType: "boolean",
88
+ createStateVariable: "unorderedCompare",
89
+ defaultValue: false,
90
+ public: true,
91
+ };
92
+ attributes.matchByExactPositions = {
93
+ createComponentOfType: "boolean",
94
+ createStateVariable: "matchByExactPositions",
95
+ defaultValue: false,
96
+ public: true,
97
+ };
98
+ attributes.numAwardsCredited = {
99
+ createComponentOfType: "integer",
100
+ createStateVariable: "numAwardsCredited",
101
+ defaultValue: 1,
102
+ public: true,
103
+ };
104
+ attributes.maxNumAttempts = {
105
+ createComponentOfType: "integer",
106
+ createStateVariable: "maxNumAttempts",
107
+ defaultValue: Infinity,
108
+ public: true,
109
+ };
110
+ attributes.allowedErrorInNumbers = {
111
+ createComponentOfType: "number",
112
+ createStateVariable: "allowedErrorInNumbers",
113
+ defaultValue: 0,
114
+ public: true,
115
+ };
116
+ attributes.includeErrorInNumberExponents = {
117
+ createComponentOfType: "boolean",
118
+ createStateVariable: "includeErrorInNumberExponents",
119
+ defaultValue: false,
120
+ public: true,
121
+ };
122
+ attributes.allowedErrorIsAbsolute = {
123
+ createComponentOfType: "boolean",
124
+ createStateVariable: "allowedErrorIsAbsolute",
125
+ defaultValue: false,
126
+ public: true,
127
+ };
128
+ attributes.numSignErrorsMatched = {
129
+ createComponentOfType: "number",
130
+ createStateVariable: "numSignErrorsMatched",
131
+ defaultValue: 0,
132
+ public: true,
133
+ };
134
+ attributes.numPeriodicSetMatchesRequired = {
135
+ createComponentOfType: "integer",
136
+ createStateVariable: "numPeriodicSetMatchesRequired",
137
+ defaultValue: 3,
138
+ public: true,
139
+ };
140
+ attributes.caseInsensitiveMatch = {
141
+ createComponentOfType: "boolean",
142
+ createStateVariable: "caseInsensitiveMatch",
143
+ defaultValue: false,
144
+ public: true,
145
+ };
146
+ attributes.matchBlanks = {
147
+ createComponentOfType: "boolean",
148
+ createStateVariable: "matchBlanks",
149
+ defaultValue: false,
150
+ public: true,
151
+ };
152
+ attributes.showCorrectness = {
153
+ createComponentOfType: "boolean",
154
+ createStateVariable: "showCorrectnessPreliminary",
155
+ defaultValue: null,
156
+ };
157
+ attributes.type = {
158
+ createPrimitiveOfType: "string",
159
+ };
160
+
161
+ attributes.disableAfterCorrect = {
162
+ createComponentOfType: "boolean",
163
+ createStateVariable: "disableAfterCorrect",
164
+ defaultValue: false,
165
+ public: true,
166
+ };
167
+
168
+ attributes.submitLabel = {
169
+ createComponentOfType: "text",
170
+ createStateVariable: "submitLabel",
171
+ defaultValue: "Check Work",
172
+ public: true,
173
+ forRenderer: true,
174
+ };
175
+
176
+ attributes.submitLabelNoCorrectness = {
177
+ createComponentOfType: "text",
178
+ createStateVariable: "submitLabelNoCorrectness",
179
+ defaultValue: "Submit Response",
180
+ public: true,
181
+ forRenderer: true,
182
+ };
183
+
184
+ attributes.selectMultiple = {
185
+ createComponentOfType: "boolean",
186
+ createStateVariable: "selectMultiple",
187
+ defaultValue: false,
188
+ public: true,
189
+ };
190
+ attributes.shuffleOrder = {
191
+ createPrimitiveOfType: "boolean",
192
+ createStateVariable: "shuffleOrder",
193
+ defaultValue: false,
194
+ public: true,
195
+ };
196
+
197
+ attributes.splitSymbols = {
198
+ createComponentOfType: "boolean",
199
+ createStateVariable: "splitSymbols",
200
+ defaultValue: true,
201
+ public: true,
202
+ };
203
+
204
+ attributes.parseScientificNotation = {
205
+ createComponentOfType: "boolean",
206
+ createStateVariable: "parseScientificNotation",
207
+ defaultValue: false,
208
+ public: true,
209
+ };
210
+
211
+ attributes.expanded = {
212
+ createComponentOfType: "boolean",
213
+ createStateVariable: "expanded",
214
+ defaultValue: false,
215
+ public: true,
216
+ };
217
+
218
+ attributes.displayDigitsForResponses = {
219
+ createComponentOfType: "integer",
220
+ createStateVariable: "displayDigitsForResponses",
221
+ defaultValue: 10,
222
+ public: true,
223
+ };
224
+
225
+ attributes.displayDigitsForCreditAchieved = {
226
+ createComponentOfType: "integer",
227
+ createStateVariable: "displayDigitsForCreditAchieved",
228
+ defaultValue: 3,
229
+ public: true,
230
+ };
231
+
232
+ // temporary attribute until fix toast
233
+ attributes.suppressToast = {
234
+ createComponentOfType: "boolean",
235
+ createStateVariable: "suppressToast",
236
+ defaultValue: false,
237
+ };
238
+
239
+ return attributes;
240
+ }
241
+
242
+ static returnSugarInstructions() {
243
+ let sugarInstructions = super.returnSugarInstructions();
244
+
245
+ let addAwardAndPossiblyInput = function ({
246
+ matchedChildren,
247
+ componentAttributes,
248
+ componentInfoObjects,
249
+ }) {
250
+ // if chidren are strings and macros
251
+ // wrap with award and type
252
+
253
+ function checkForResponseDescendant(components) {
254
+ for (let component of components) {
255
+ if (
256
+ component?.attributes?.isResponse &&
257
+ component.attributes.isResponse.primitive !== false
258
+ ) {
259
+ // idea: catch either isResponse = true or isResponse.primitive=true
260
+ return true;
261
+ } else if (
262
+ component.children &&
263
+ checkForResponseDescendant(component.children)
264
+ ) {
265
+ return true;
266
+ }
267
+ }
268
+ return false;
269
+ }
270
+
271
+ function addResponsesToCompositeDescendants(components) {
272
+ for (let component of components) {
273
+ if (
274
+ componentInfoObjects.isInheritedComponentType({
275
+ inheritedComponentType: component.componentType,
276
+ baseComponentType: "_composite",
277
+ })
278
+ ) {
279
+ if (!component.attributes) {
280
+ component.attributes = {};
281
+ }
282
+ // Note we don't add the attribute as {primitive: true}
283
+ // because the composite don't have the attribute isResponse
284
+ // but pass it on to their replacements
285
+ component.attributes.isResponse = true;
286
+ } else if (component.children) {
287
+ addResponsesToCompositeDescendants(component.children);
288
+ }
289
+ }
290
+ }
291
+
292
+ let componentIsSpecifiedType =
293
+ componentInfoObjects.componentIsSpecifiedType;
294
+
295
+ let foundMath = false,
296
+ foundText = false,
297
+ foundBoolean = false;
298
+ let nChoicesFound = 0;
299
+ let definitelyDoNotAddInput = false,
300
+ mayNeedInput = false;
301
+ let foundResponse = false;
302
+ let foundAward = false;
303
+
304
+ let childIsWrappable = [];
305
+ for (let child of matchedChildren) {
306
+ if (typeof child !== "object") {
307
+ childIsWrappable.push(true);
308
+ if (child.trim()) {
309
+ mayNeedInput = true;
310
+ }
311
+ } else if (
312
+ componentIsSpecifiedType(child, "math") ||
313
+ componentIsSpecifiedType(child, "number") ||
314
+ componentIsSpecifiedType(child, "mathList") ||
315
+ componentIsSpecifiedType(child, "numberList")
316
+ ) {
317
+ childIsWrappable.push(true);
318
+ mayNeedInput = true;
319
+ foundMath = true;
320
+ } else if (
321
+ componentIsSpecifiedType(child, "text") ||
322
+ componentIsSpecifiedType(child, "textList")
323
+ ) {
324
+ childIsWrappable.push(true);
325
+ foundText = true;
326
+ mayNeedInput = true;
327
+ } else if (componentIsSpecifiedType(child, "boolean")) {
328
+ childIsWrappable.push(true);
329
+ foundBoolean = true;
330
+ mayNeedInput = true;
331
+ } else if (componentIsSpecifiedType(child, "booleanList")) {
332
+ // TODO: what should we do with a booleanList,
333
+ // as don't have a booleanList input?
334
+ childIsWrappable.push(true);
335
+ foundBoolean = true;
336
+ } else if (componentIsSpecifiedType(child, "choice")) {
337
+ childIsWrappable.push(true);
338
+ nChoicesFound++;
339
+ } else if (componentIsSpecifiedType(child, "award")) {
340
+ foundAward = true;
341
+ childIsWrappable.push(false);
342
+ if (child.attributes?.sourcesAreResponses) {
343
+ foundResponse = true;
344
+ }
345
+ if (child.children?.length > 0) {
346
+ for (let grandChild of child.children) {
347
+ if (typeof grandChild !== "object") {
348
+ if (grandChild.trim()) {
349
+ mayNeedInput = true;
350
+ }
351
+ } else if (componentIsSpecifiedType(grandChild, "when")) {
352
+ // have to test for when before boolean, sincd when is derived from boolean!
353
+ } else if (
354
+ componentIsSpecifiedType(grandChild, "math") ||
355
+ componentIsSpecifiedType(grandChild, "number") ||
356
+ componentIsSpecifiedType(grandChild, "mathList") ||
357
+ componentIsSpecifiedType(grandChild, "numberList")
358
+ ) {
359
+ foundMath = true;
360
+ mayNeedInput = true;
361
+ } else if (
362
+ componentIsSpecifiedType(grandChild, "text") ||
363
+ componentIsSpecifiedType(grandChild, "textList")
364
+ ) {
365
+ foundText = true;
366
+ mayNeedInput = true;
367
+ } else if (componentIsSpecifiedType(grandChild, "boolean")) {
368
+ foundBoolean = true;
369
+ mayNeedInput = true;
370
+ } else if (componentIsSpecifiedType(grandChild, "booleanList")) {
371
+ // TODO: what should we do with a booleanList,
372
+ // as don't have a booleanList input?
373
+ foundBoolean = true;
374
+ } else if (
375
+ componentInfoObjects.isInheritedComponentType({
376
+ inheritedComponentType: grandChild.componentType,
377
+ baseComponentType: "_composite",
378
+ }) &&
379
+ !grandChild.attributes?.createComponentOfType?.primitive
380
+ ) {
381
+ mayNeedInput = true;
382
+ } else if (
383
+ componentIsSpecifiedType(grandChild, "orbitalDiagram")
384
+ ) {
385
+ // Note: should add componentTypes as create more comparable types in award
386
+ } else {
387
+ // could be a component that could adapt into a math/text/boolean
388
+ mayNeedInput = true;
389
+ }
390
+ }
391
+ } else {
392
+ // if copied in award, it won't have children
393
+ mayNeedInput = true;
394
+ }
395
+ } else if (componentIsSpecifiedType(child, "mathInput")) {
396
+ childIsWrappable.push(false);
397
+ foundMath = true;
398
+ definitelyDoNotAddInput = true;
399
+ } else if (componentIsSpecifiedType(child, "textInput")) {
400
+ childIsWrappable.push(false);
401
+ foundText = true;
402
+ definitelyDoNotAddInput = true;
403
+ } else if (componentIsSpecifiedType(child, "_input")) {
404
+ childIsWrappable.push(false);
405
+ definitelyDoNotAddInput = true;
406
+ } else if (componentIsSpecifiedType(child, "considerAsResponses")) {
407
+ childIsWrappable.push(false);
408
+ definitelyDoNotAddInput = true;
409
+ } else if (
410
+ componentInfoObjects.isInheritedComponentType({
411
+ inheritedComponentType: child.componentType,
412
+ baseComponentType: "_composite",
413
+ }) &&
414
+ !child.attributes?.createComponentOfType?.primitive
415
+ ) {
416
+ // have a composite without specified componentType
417
+ childIsWrappable.push(true);
418
+ mayNeedInput = true;
419
+ } else {
420
+ // wrap anything else as it isn't matched by a child group?
421
+ childIsWrappable.push(true);
422
+ mayNeedInput = true;
423
+ }
424
+ }
425
+
426
+ if (definitelyDoNotAddInput) {
427
+ foundResponse = true;
428
+ }
429
+
430
+ if (nChoicesFound > 0) {
431
+ // remove blank string children
432
+ matchedChildren = matchedChildren.filter(
433
+ (x) => typeof x !== "string" || x.trim() !== "",
434
+ );
435
+ if (matchedChildren.length !== nChoicesFound) {
436
+ return { success: false };
437
+ } else {
438
+ // wrap all choices in a choiceinput
439
+ let choiceinput = {
440
+ componentType: "choiceInput",
441
+ children: matchedChildren,
442
+ };
443
+ if (componentAttributes.shuffleOrder) {
444
+ choiceinput.attributes = { shuffleOrder: { primitive: true } };
445
+ }
446
+ return {
447
+ success: true,
448
+ newChildren: [choiceinput],
449
+ };
450
+ }
451
+ }
452
+
453
+ if (componentAttributes.handGraded && !foundAward) {
454
+ mayNeedInput = true;
455
+ }
456
+
457
+ if (!mayNeedInput && !foundResponse) {
458
+ // recurse to all descendants of awards to see if have a response
459
+ for (let child of matchedChildren) {
460
+ if (componentIsSpecifiedType(child, "award")) {
461
+ if (child.children?.length > 0) {
462
+ if (checkForResponseDescendant(child.children)) {
463
+ foundResponse = true;
464
+ break;
465
+ }
466
+ }
467
+ }
468
+ }
469
+
470
+ if (!foundResponse) {
471
+ // definitely have a case where there is not a response
472
+ // look inside each award and add isResponse to any composites
473
+ for (let child of matchedChildren) {
474
+ if (componentIsSpecifiedType(child, "award")) {
475
+ if (child.children?.length > 0) {
476
+ addResponsesToCompositeDescendants(child.children);
477
+ }
478
+ }
479
+ }
480
+ }
481
+ }
482
+
483
+ let childrenToWrap = [],
484
+ childrenToNotWrapBegin = [],
485
+ childrenToNotWrapEnd = [];
486
+
487
+ if (childIsWrappable.filter((x) => !x).length === 0) {
488
+ childrenToWrap = matchedChildren;
489
+ } else {
490
+ if (!childIsWrappable[0]) {
491
+ // started with non-wrappable, find first wrappable child
492
+ let firstNonLabelInd = childIsWrappable.indexOf(true);
493
+ if (firstNonLabelInd !== -1) {
494
+ childrenToNotWrapBegin = matchedChildren.slice(0, firstNonLabelInd);
495
+ matchedChildren = matchedChildren.slice(firstNonLabelInd);
496
+ childIsWrappable = childIsWrappable.slice(firstNonLabelInd);
497
+ }
498
+ }
499
+
500
+ // now we don't have non-wrappable at the beginning
501
+ // find first non-wrappable ind
502
+ let firstLabelInd = childIsWrappable.indexOf(false);
503
+ if (firstLabelInd === -1) {
504
+ childrenToWrap = matchedChildren;
505
+ } else {
506
+ childrenToWrap = matchedChildren.slice(0, firstLabelInd);
507
+ childrenToNotWrapEnd = matchedChildren.slice(firstLabelInd);
508
+ }
509
+ }
510
+
511
+ // remove any blank string children from beginning or end of children to wrap
512
+ while (
513
+ typeof childrenToWrap[0] === "string" &&
514
+ childrenToWrap[0].trim() === ""
515
+ ) {
516
+ childrenToWrap = childrenToWrap.slice(1);
517
+ }
518
+ let nWrap = childrenToWrap.length;
519
+ while (
520
+ typeof childrenToWrap[nWrap - 1] === "string" &&
521
+ childrenToWrap[nWrap - 1].trim() === ""
522
+ ) {
523
+ childrenToWrap = childrenToWrap.slice(0, nWrap - 1);
524
+ nWrap = childrenToWrap.length;
525
+ }
526
+
527
+ let newChildren;
528
+ let type;
529
+ if (componentAttributes.type) {
530
+ type = componentAttributes.type;
531
+ if (!["math", "text", "boolean"].includes(type)) {
532
+ console.warn(`Invalid type ${type}`);
533
+ type = "math";
534
+ }
535
+ } else {
536
+ if (foundMath) {
537
+ type = "math";
538
+ } else if (foundText) {
539
+ type = "text";
540
+ } else if (foundBoolean) {
541
+ // TODO: if have multiple booleans,
542
+ // it doesn't make sense to wrap in one big boolean.
543
+ // What is a better solution?
544
+ type = "boolean";
545
+ } else {
546
+ type = "math";
547
+ }
548
+ }
549
+
550
+ if (childrenToWrap.length === 0) {
551
+ newChildren = [...childrenToNotWrapBegin, ...childrenToNotWrapEnd];
552
+ } else {
553
+ // if have one child and it has a specified componentType
554
+ // then no need to wrap with componentType
555
+
556
+ let needToWrapWithComponentType =
557
+ childrenToWrap.length > 1 ||
558
+ (componentInfoObjects.isInheritedComponentType({
559
+ inheritedComponentType: childrenToWrap[0].componentType,
560
+ baseComponentType: "_composite",
561
+ }) &&
562
+ !childrenToWrap[0].props?.componentType);
563
+
564
+ let awardChildren;
565
+ if (needToWrapWithComponentType) {
566
+ awardChildren = [
567
+ {
568
+ componentType: type,
569
+ children: childrenToWrap,
570
+ },
571
+ ];
572
+ } else {
573
+ awardChildren = childrenToWrap;
574
+ }
575
+ newChildren = [
576
+ ...childrenToNotWrapBegin,
577
+ {
578
+ componentType: "award",
579
+ children: awardChildren,
580
+ },
581
+ ...childrenToNotWrapEnd,
582
+ ];
583
+ }
584
+
585
+ if (mayNeedInput && !definitelyDoNotAddInput) {
586
+ let inputType = type + "Input";
587
+
588
+ newChildren = [{ componentType: inputType }, ...newChildren];
589
+ }
590
+
591
+ return {
592
+ success: true,
593
+ newChildren: newChildren,
594
+ };
595
+ };
596
+
597
+ sugarInstructions.push({
598
+ replacementFunction: addAwardAndPossiblyInput,
599
+ });
600
+
601
+ return sugarInstructions;
602
+ }
603
+
604
+ static returnChildGroups() {
605
+ return [
606
+ {
607
+ group: "awards",
608
+ componentTypes: ["award"],
609
+ },
610
+ {
611
+ group: "inputs",
612
+ componentTypes: ["_input"],
613
+ },
614
+ {
615
+ group: "responses",
616
+ componentTypes: ["considerAsResponses"],
617
+ },
618
+ ];
619
+ }
620
+
621
+ static returnStateVariableDefinitions() {
622
+ let stateVariableDefinitions = super.returnStateVariableDefinitions();
623
+
624
+ // rename disabled to disabledOriginal
625
+ renameStateVariable({
626
+ stateVariableDefinitions,
627
+ oldName: "disabled",
628
+ newName: "disabledOriginal",
629
+ });
630
+
631
+ stateVariableDefinitions.showCorrectness = {
632
+ forRenderer: true,
633
+ returnDependencies: () => ({
634
+ showCorrectnessPreliminary: {
635
+ dependencyType: "stateVariable",
636
+ variableName: "showCorrectnessPreliminary",
637
+ },
638
+ showCorrectnessFlag: {
639
+ dependencyType: "flag",
640
+ flagName: "showCorrectness",
641
+ },
642
+ handGraded: {
643
+ dependencyType: "stateVariable",
644
+ variableName: "handGraded",
645
+ },
646
+ }),
647
+ definition({ dependencyValues, usedDefault }) {
648
+ let showCorrectness;
649
+ if (!usedDefault.showCorrectnessPreliminary) {
650
+ showCorrectness = dependencyValues.showCorrectnessPreliminary;
651
+ } else {
652
+ showCorrectness =
653
+ dependencyValues.showCorrectnessFlag !== false &&
654
+ !dependencyValues.handGraded;
655
+ }
656
+ return { setValue: { showCorrectness } };
657
+ },
658
+ };
659
+
660
+ stateVariableDefinitions.haveAwardThatRequiresInput = {
661
+ returnDependencies: () => ({
662
+ awardChildren: {
663
+ dependencyType: "child",
664
+ childGroups: ["awards"],
665
+ variableNames: ["requireInputInAnswer"],
666
+ },
667
+ }),
668
+ definition({ dependencyValues }) {
669
+ return {
670
+ setValue: {
671
+ haveAwardThatRequiresInput: dependencyValues.awardChildren.some(
672
+ (x) => x.stateValues.requireInputInAnswer,
673
+ ),
674
+ },
675
+ };
676
+ },
677
+ };
678
+
679
+ stateVariableDefinitions.allInputChildrenIncludingSugared = {
680
+ returnDependencies: () => ({
681
+ allInputChildrenIncludingSugared: {
682
+ dependencyType: "child",
683
+ childGroups: ["inputs"],
684
+ },
685
+ }),
686
+ definition({ dependencyValues }) {
687
+ return {
688
+ setValue: {
689
+ allInputChildrenIncludingSugared:
690
+ dependencyValues.allInputChildrenIncludingSugared,
691
+ },
692
+ };
693
+ },
694
+ };
695
+
696
+ stateVariableDefinitions.inputChildren = {
697
+ stateVariablesDeterminingDependencies: [
698
+ "allInputChildrenIncludingSugared",
699
+ ],
700
+ additionalStateVariablesDefined: [
701
+ "inputChildIndices",
702
+ "skippedFirstInput",
703
+ ],
704
+ forRenderer: true,
705
+ returnDependencies({ stateValues }) {
706
+ let dependencies = {
707
+ allInputChildrenIncludingSugared: {
708
+ dependencyType: "stateVariable",
709
+ variableName: "allInputChildrenIncludingSugared",
710
+ },
711
+ haveAwardThatRequiresInput: {
712
+ dependencyType: "stateVariable",
713
+ variableName: "haveAwardThatRequiresInput",
714
+ },
715
+ handGraded: {
716
+ dependencyType: "stateVariable",
717
+ variableName: "handGraded",
718
+ },
719
+ };
720
+
721
+ if (stateValues.allInputChildrenIncludingSugared.length > 0) {
722
+ dependencies.firstInputFromSugar = {
723
+ dependencyType: "doenetAttribute",
724
+ componentName:
725
+ stateValues.allInputChildrenIncludingSugared[0].componentName,
726
+ attributeName: "createdFromSugar",
727
+ };
728
+ }
729
+
730
+ return dependencies;
731
+ },
732
+ definition({ dependencyValues }) {
733
+ // if have award the requires input,
734
+ // use the input child from sugar if none other exists
735
+ // but if first input is choiceInput, use that anyway
736
+
737
+ let inputChildren = [
738
+ ...dependencyValues.allInputChildrenIncludingSugared,
739
+ ];
740
+ let inputChildIndices = [
741
+ ...dependencyValues.allInputChildrenIncludingSugared.keys(),
742
+ ];
743
+ let skippedFirstInput = false;
744
+
745
+ let skipFirstSugaredInput =
746
+ inputChildren[0]?.componentType !== "choiceInput" &&
747
+ (!(
748
+ dependencyValues.haveAwardThatRequiresInput ||
749
+ dependencyValues.handGraded
750
+ ) ||
751
+ dependencyValues.allInputChildrenIncludingSugared.length > 1);
752
+
753
+ if (skipFirstSugaredInput && dependencyValues.firstInputFromSugar) {
754
+ skippedFirstInput = true;
755
+ inputChildren = inputChildren.slice(1);
756
+ inputChildIndices = inputChildIndices.slice(1);
757
+ }
758
+
759
+ return {
760
+ setValue: { inputChildren, inputChildIndices, skippedFirstInput },
761
+ };
762
+ },
763
+ };
764
+
765
+ stateVariableDefinitions.inputChildrenWithValues = {
766
+ stateVariablesDeterminingDependencies: ["inputChildIndices"],
767
+ forRenderer: true,
768
+ returnDependencies: ({ stateValues }) => ({
769
+ inputChildren: {
770
+ dependencyType: "child",
771
+ childGroups: ["inputs"],
772
+ variableNames: [
773
+ "valueToRecordOnSubmit",
774
+ "valueRecordedAtSubmit",
775
+ "value",
776
+ ],
777
+ childIndices: stateValues.inputChildIndices,
778
+ variablesOptional: true,
779
+ },
780
+ }),
781
+ definition: function ({ dependencyValues }) {
782
+ return {
783
+ setValue: { inputChildrenWithValues: dependencyValues.inputChildren },
784
+ };
785
+ },
786
+ };
787
+
788
+ // for award children to find the one input child
789
+ stateVariableDefinitions.inputChildWithValues = {
790
+ returnDependencies: () => ({
791
+ inputChildrenWithValues: {
792
+ dependencyType: "stateVariable",
793
+ variableName: "inputChildrenWithValues",
794
+ },
795
+ }),
796
+ definition({ dependencyValues }) {
797
+ let inputChildWithValues = null;
798
+ if (dependencyValues.inputChildrenWithValues.length === 1) {
799
+ inputChildWithValues = dependencyValues.inputChildrenWithValues[0];
800
+ }
801
+ return { setValue: { inputChildWithValues } };
802
+ },
803
+ };
804
+
805
+ stateVariableDefinitions.awardInputResponseChildren = {
806
+ returnDependencies: () => ({
807
+ awardInputResponseChildren: {
808
+ dependencyType: "child",
809
+ childGroups: ["awards", "inputs", "responses"],
810
+ },
811
+ skippedFirstInput: {
812
+ dependencyType: "stateVariable",
813
+ variableName: "skippedFirstInput",
814
+ },
815
+ }),
816
+ definition({ dependencyValues }) {
817
+ let awardInputResponseChildren = [
818
+ ...dependencyValues.awardInputResponseChildren,
819
+ ];
820
+ if (dependencyValues.skippedFirstInput) {
821
+ awardInputResponseChildren = awardInputResponseChildren.slice(1);
822
+ }
823
+ return {
824
+ setValue: { awardInputResponseChildren },
825
+ };
826
+ },
827
+ };
828
+
829
+ stateVariableDefinitions.numResponses = {
830
+ public: true,
831
+ shadowingInstructions: {
832
+ createComponentOfType: "number",
833
+ },
834
+ stateVariablesDeterminingDependencies: ["awardInputResponseChildren"],
835
+ returnDependencies({ stateValues, componentInfoObjects }) {
836
+ let dependencies = {
837
+ childTypes: {
838
+ dependencyType: "value",
839
+ value: stateValues.awardInputResponseChildren.map(
840
+ (x) => x.componentType,
841
+ ),
842
+ },
843
+ };
844
+
845
+ for (let [
846
+ ind,
847
+ child,
848
+ ] of stateValues.awardInputResponseChildren.entries()) {
849
+ if (
850
+ componentInfoObjects.isInheritedComponentType({
851
+ inheritedComponentType: child.componentType,
852
+ baseComponentType: "award",
853
+ })
854
+ ) {
855
+ dependencies["child" + ind] = {
856
+ dependencyType: "descendant",
857
+ ancestorName: child.componentName,
858
+ componentTypes: ["_base"],
859
+ variableNames: ["isResponse", "numValues"],
860
+ variablesOptional: true,
861
+ recurseToMatchedChildren: true,
862
+ includeNonActiveChildren: true,
863
+ skipOverAdapters: true,
864
+ };
865
+ } else if (
866
+ componentInfoObjects.isInheritedComponentType({
867
+ inheritedComponentType: child.componentType,
868
+ baseComponentType: "_input",
869
+ })
870
+ ) {
871
+ dependencies["childNValues" + ind] = {
872
+ dependencyType: "stateVariable",
873
+ componentName: child.componentName,
874
+ variableName: "numValues",
875
+ variablesOptional: true,
876
+ };
877
+ } else {
878
+ // considerAsResponses
879
+ dependencies["child" + ind] = {
880
+ dependencyType: "stateVariable",
881
+ componentName: child.componentName,
882
+ variableName: "childrenWithNValues",
883
+ };
884
+ }
885
+ }
886
+
887
+ return dependencies;
888
+ },
889
+ definition({ dependencyValues, componentInfoObjects }) {
890
+ let numResponses = 0;
891
+
892
+ for (let [ind, childType] of dependencyValues.childTypes.entries()) {
893
+ if (
894
+ componentInfoObjects.isInheritedComponentType({
895
+ inheritedComponentType: childType,
896
+ baseComponentType: "award",
897
+ })
898
+ ) {
899
+ for (let descendant of dependencyValues["child" + ind]) {
900
+ if (
901
+ !descendant.stateValues.isResponse ||
902
+ componentInfoObjects.isInheritedComponentType({
903
+ inheritedComponentType: descendant.componentType,
904
+ baseComponentType: "_composite",
905
+ })
906
+ ) {
907
+ continue;
908
+ }
909
+
910
+ if (descendant.stateValues.numValues === undefined) {
911
+ numResponses += 1;
912
+ } else {
913
+ numResponses += descendant.stateValues.numValues;
914
+ }
915
+ }
916
+ } else if (
917
+ componentInfoObjects.isInheritedComponentType({
918
+ inheritedComponentType: childType,
919
+ baseComponentType: "_input",
920
+ })
921
+ ) {
922
+ let numValues = dependencyValues["childNValues" + ind];
923
+ if (numValues === undefined) {
924
+ numResponses += 1;
925
+ } else {
926
+ numResponses += numValues;
927
+ }
928
+ } else {
929
+ // considerAsResponses
930
+
931
+ for (let child of dependencyValues["child" + ind]) {
932
+ if (child.stateValues.numValues === undefined) {
933
+ numResponses += 1;
934
+ } else {
935
+ numResponses += child.stateValues.numValues;
936
+ }
937
+ }
938
+ }
939
+ }
940
+
941
+ return { setValue: { numResponses } };
942
+ },
943
+ };
944
+
945
+ stateVariableDefinitions.currentResponses = {
946
+ public: true,
947
+ shadowingInstructions: {
948
+ hasVariableComponentType: true,
949
+ addAttributeComponentsShadowingStateVariables: {
950
+ displayDigits: {
951
+ stateVariableToShadow: "displayDigitsForResponses",
952
+ },
953
+ },
954
+ },
955
+ isArray: true,
956
+ entryPrefixes: ["currentResponse"],
957
+ stateVariablesDeterminingDependencies: ["awardInputResponseChildren"],
958
+ returnArraySizeDependencies: () => ({
959
+ numResponses: {
960
+ dependencyType: "stateVariable",
961
+ variableName: "numResponses",
962
+ },
963
+ }),
964
+ returnArraySize({ dependencyValues }) {
965
+ return [dependencyValues.numResponses];
966
+ },
967
+ returnArrayDependenciesByKey({ stateValues, componentInfoObjects }) {
968
+ let globalDependencies = {
969
+ childTypes: {
970
+ dependencyType: "value",
971
+ value: stateValues.awardInputResponseChildren.map(
972
+ (x) => x.componentType,
973
+ ),
974
+ },
975
+ };
976
+
977
+ for (let [
978
+ ind,
979
+ child,
980
+ ] of stateValues.awardInputResponseChildren.entries()) {
981
+ if (
982
+ componentInfoObjects.isInheritedComponentType({
983
+ inheritedComponentType: child.componentType,
984
+ baseComponentType: "award",
985
+ })
986
+ ) {
987
+ globalDependencies["child" + ind] = {
988
+ dependencyType: "descendant",
989
+ ancestorName: child.componentName,
990
+ componentTypes: ["_base"],
991
+ variableNames: [
992
+ "isResponse",
993
+ "value",
994
+ "values",
995
+ "formula",
996
+ "componentType",
997
+ ],
998
+ variablesOptional: true,
999
+ recurseToMatchedChildren: true,
1000
+ includeAttributeChildren: true,
1001
+ includeNonActiveChildren: true,
1002
+ skipOverAdapters: true,
1003
+ };
1004
+ } else if (
1005
+ componentInfoObjects.isInheritedComponentType({
1006
+ inheritedComponentType: child.componentType,
1007
+ baseComponentType: "_input",
1008
+ })
1009
+ ) {
1010
+ globalDependencies["childValue" + ind] = {
1011
+ dependencyType: "stateVariable",
1012
+ componentName: child.componentName,
1013
+ variableName: "value",
1014
+ variablesOptional: true,
1015
+ };
1016
+ globalDependencies["childValues" + ind] = {
1017
+ dependencyType: "stateVariable",
1018
+ componentName: child.componentName,
1019
+ variableName: "values",
1020
+ variablesOptional: true,
1021
+ };
1022
+ globalDependencies["childComponentType" + ind] = {
1023
+ dependencyType: "stateVariable",
1024
+ componentName: child.componentName,
1025
+ variableName: "componentType",
1026
+ variablesOptional: true,
1027
+ };
1028
+ } else {
1029
+ // considerAsResponses
1030
+ globalDependencies["child" + ind] = {
1031
+ dependencyType: "stateVariable",
1032
+ componentName: child.componentName,
1033
+ variableName: "childrenAsResponses",
1034
+ };
1035
+ }
1036
+ }
1037
+
1038
+ return { globalDependencies };
1039
+ },
1040
+ arrayDefinitionByKey({ globalDependencyValues, componentInfoObjects }) {
1041
+ let currentResponses = [];
1042
+ let componentType = [];
1043
+
1044
+ let responseComponents = [];
1045
+
1046
+ for (let [
1047
+ ind,
1048
+ childType,
1049
+ ] of globalDependencyValues.childTypes.entries()) {
1050
+ if (
1051
+ componentInfoObjects.isInheritedComponentType({
1052
+ inheritedComponentType: childType,
1053
+ baseComponentType: "award",
1054
+ })
1055
+ ) {
1056
+ for (let descendant of globalDependencyValues["child" + ind]) {
1057
+ if (
1058
+ !descendant.stateValues.isResponse ||
1059
+ componentInfoObjects.isInheritedComponentType({
1060
+ inheritedComponentType: descendant.componentType,
1061
+ baseComponentType: "_composite",
1062
+ })
1063
+ ) {
1064
+ continue;
1065
+ }
1066
+
1067
+ responseComponents.push(descendant);
1068
+ }
1069
+ } else if (
1070
+ componentInfoObjects.isInheritedComponentType({
1071
+ inheritedComponentType: childType,
1072
+ baseComponentType: "_input",
1073
+ })
1074
+ ) {
1075
+ // reconstruct child in same way as for other components
1076
+ let child = {
1077
+ componentType: childType,
1078
+ stateValues: {
1079
+ value: globalDependencyValues["childValue" + ind],
1080
+ values: globalDependencyValues["childValues" + ind],
1081
+ componentType:
1082
+ globalDependencyValues["childComponentType" + ind],
1083
+ },
1084
+ };
1085
+
1086
+ responseComponents.push(child);
1087
+ } else {
1088
+ // considerAsResponses
1089
+ responseComponents.push(...globalDependencyValues["child" + ind]);
1090
+ }
1091
+ }
1092
+
1093
+ for (let component of responseComponents) {
1094
+ let ct = component.stateValues.componentType;
1095
+ if (!ct) {
1096
+ ct = component.componentType;
1097
+ }
1098
+
1099
+ if (ct === "mathList") {
1100
+ ct = "math";
1101
+ } else if (ct === "numberList") {
1102
+ ct = "number";
1103
+ } else if (ct === "textList") {
1104
+ ct = "text";
1105
+ } else if (ct === "booleanList") {
1106
+ ct = "boolean";
1107
+ }
1108
+
1109
+ if (Array.isArray(component.stateValues.values)) {
1110
+ currentResponses.push(...component.stateValues.values);
1111
+ componentType.push(
1112
+ ...Array(component.stateValues.values.length).fill(ct),
1113
+ );
1114
+ } else if (component.stateValues.value !== undefined) {
1115
+ currentResponses.push(component.stateValues.value);
1116
+ componentType.push(ct);
1117
+ } else if (component.stateValues.formula instanceof me.class) {
1118
+ currentResponses.push(component.stateValues.formula);
1119
+ componentType.push("math");
1120
+ } else {
1121
+ currentResponses.push("");
1122
+ componentType.push("text");
1123
+ }
1124
+ }
1125
+
1126
+ return {
1127
+ setValue: { currentResponses },
1128
+ setCreateComponentOfType: { currentResponses: componentType },
1129
+ };
1130
+ },
1131
+ };
1132
+
1133
+ stateVariableDefinitions.currentResponse = {
1134
+ isAlias: true,
1135
+ targetVariableName: "currentResponse1",
1136
+ };
1137
+
1138
+ stateVariableDefinitions.numSubmittedResponses = {
1139
+ public: true,
1140
+ shadowingInstructions: {
1141
+ createComponentOfType: "number",
1142
+ },
1143
+ hasEssential: true,
1144
+ defaultValue: 0,
1145
+ returnDependencies: () => ({}),
1146
+ definition: () => ({
1147
+ useEssentialOrDefaultValue: {
1148
+ numSubmittedResponses: true,
1149
+ },
1150
+ }),
1151
+ inverseDefinition({ desiredStateVariableValues }) {
1152
+ return {
1153
+ success: true,
1154
+ instructions: [
1155
+ {
1156
+ setEssentialValue: "numSubmittedResponses",
1157
+ value: desiredStateVariableValues.numSubmittedResponses,
1158
+ },
1159
+ ],
1160
+ };
1161
+ },
1162
+ };
1163
+
1164
+ stateVariableDefinitions.submittedResponsesComponentType = {
1165
+ hasEssential: true,
1166
+ defaultValue: null,
1167
+ returnDependencies: () => ({}),
1168
+ definition: () => ({
1169
+ useEssentialOrDefaultValue: {
1170
+ submittedResponsesComponentType: true,
1171
+ },
1172
+ }),
1173
+ inverseDefinition: function ({ desiredStateVariableValues }) {
1174
+ if (desiredStateVariableValues.submittedResponsesComponentType) {
1175
+ return {
1176
+ success: true,
1177
+ instructions: [
1178
+ {
1179
+ setEssentialValue: "submittedResponsesComponentType",
1180
+ value: [
1181
+ ...desiredStateVariableValues.submittedResponsesComponentType,
1182
+ ],
1183
+ },
1184
+ ],
1185
+ };
1186
+ } else {
1187
+ return {
1188
+ success: true,
1189
+ instructions: [
1190
+ {
1191
+ setEssentialValue: "submittedResponsesComponentType",
1192
+ value: [],
1193
+ },
1194
+ ],
1195
+ };
1196
+ }
1197
+ },
1198
+ };
1199
+
1200
+ stateVariableDefinitions.submittedResponses = {
1201
+ public: true,
1202
+ shadowingInstructions: {
1203
+ hasVariableComponentType: true,
1204
+ addAttributeComponentsShadowingStateVariables: {
1205
+ displayDigits: {
1206
+ stateVariableToShadow: "displayDigitsForResponses",
1207
+ },
1208
+ },
1209
+ },
1210
+ isArray: true,
1211
+ entryPrefixes: ["submittedResponse"],
1212
+ defaultValueByArrayKey: () => "\uFF3F",
1213
+ hasEssential: true,
1214
+ inverseShadowToSetEntireArray: true,
1215
+ doNotCombineInverseArrayInstructions: true,
1216
+ returnArraySizeDependencies: () => ({
1217
+ numSubmittedResponses: {
1218
+ dependencyType: "stateVariable",
1219
+ variableName: "numSubmittedResponses",
1220
+ },
1221
+ }),
1222
+ returnArraySize({ dependencyValues }) {
1223
+ return [dependencyValues.numSubmittedResponses];
1224
+ },
1225
+ returnArrayDependenciesByKey() {
1226
+ let globalDependencies = {
1227
+ submittedResponsesComponentType: {
1228
+ dependencyType: "stateVariable",
1229
+ variableName: "submittedResponsesComponentType",
1230
+ },
1231
+ numSubmittedResponses: {
1232
+ dependencyType: "stateVariable",
1233
+ variableName: "numSubmittedResponses",
1234
+ },
1235
+ };
1236
+ return { globalDependencies };
1237
+ },
1238
+ arrayDefinitionByKey({ globalDependencyValues }) {
1239
+ let componentType = [];
1240
+
1241
+ if (globalDependencyValues.submittedResponsesComponentType) {
1242
+ componentType.push(
1243
+ ...globalDependencyValues.submittedResponsesComponentType.slice(
1244
+ 0,
1245
+ globalDependencyValues.numSubmittedResponses,
1246
+ ),
1247
+ );
1248
+ }
1249
+
1250
+ let essentialSubmittedResponses = {};
1251
+
1252
+ for (
1253
+ let ind = 0;
1254
+ ind < globalDependencyValues.numSubmittedResponses;
1255
+ ind++
1256
+ ) {
1257
+ // this function doesn't change the values once they set for the first time
1258
+ // (The values will just be changed using the inverse function)
1259
+ essentialSubmittedResponses[ind] = true;
1260
+
1261
+ if (!componentType[ind]) {
1262
+ componentType[ind] = "math";
1263
+ }
1264
+ }
1265
+
1266
+ return {
1267
+ useEssentialOrDefaultValue: {
1268
+ submittedResponses: essentialSubmittedResponses,
1269
+ },
1270
+ setCreateComponentOfType: { submittedResponses: componentType },
1271
+ };
1272
+ },
1273
+ inverseArrayDefinitionByKey: function ({
1274
+ desiredStateVariableValues,
1275
+ initialChange,
1276
+ }) {
1277
+ if (!initialChange) {
1278
+ return { success: false };
1279
+ }
1280
+
1281
+ return {
1282
+ success: true,
1283
+ instructions: [
1284
+ {
1285
+ setDependency: "numSubmittedResponses",
1286
+ desiredValue:
1287
+ desiredStateVariableValues.submittedResponses.length,
1288
+ },
1289
+ {
1290
+ setEssentialValue: "submittedResponses",
1291
+ value: [...desiredStateVariableValues.submittedResponses],
1292
+ },
1293
+ ],
1294
+ };
1295
+ },
1296
+ };
1297
+
1298
+ stateVariableDefinitions.submittedResponse = {
1299
+ isAlias: true,
1300
+ targetVariableName: "submittedResponse1",
1301
+ };
1302
+
1303
+ stateVariableDefinitions.suppressCheckwork = {
1304
+ forRenderer: true,
1305
+ returnDependencies: () => ({
1306
+ autoSubmit: {
1307
+ dependencyType: "flag",
1308
+ flagName: "autoSubmit",
1309
+ },
1310
+ }),
1311
+ definition({ dependencyValues }) {
1312
+ return { setValue: { suppressCheckwork: dependencyValues.autoSubmit } };
1313
+ },
1314
+ };
1315
+
1316
+ stateVariableDefinitions.delegateCheckWork = {
1317
+ additionalStateVariablesDefined: [
1318
+ "delegateCheckWorkToInput",
1319
+ "delegateCheckWorkToAncestor",
1320
+ ],
1321
+ forRenderer: true,
1322
+ returnDependencies: () => ({
1323
+ inputChildren: {
1324
+ dependencyType: "stateVariable",
1325
+ variableName: "inputChildren",
1326
+ },
1327
+ forceFullCheckworkButton: {
1328
+ dependencyType: "stateVariable",
1329
+ variableName: "forceFullCheckworkButton",
1330
+ },
1331
+ sectionAncestor: {
1332
+ dependencyType: "ancestor",
1333
+ componentType: "_sectioningComponent",
1334
+ variableNames: ["suppressAnswerSubmitButtons"],
1335
+ },
1336
+ documentAncestor: {
1337
+ dependencyType: "ancestor",
1338
+ componentType: "document",
1339
+ variableNames: ["suppressAnswerSubmitButtons"],
1340
+ },
1341
+ }),
1342
+ definition: function ({ dependencyValues }) {
1343
+ let delegateCheckWorkToAncestor = false;
1344
+ let delegateCheckWorkToInput = false;
1345
+ let delegateCheckWork = false;
1346
+
1347
+ if (
1348
+ dependencyValues.documentAncestor.stateValues
1349
+ .suppressAnswerSubmitButtons
1350
+ ) {
1351
+ delegateCheckWorkToAncestor = delegateCheckWork = true;
1352
+ } else if (
1353
+ dependencyValues.sectionAncestor?.stateValues
1354
+ .suppressAnswerSubmitButtons
1355
+ ) {
1356
+ delegateCheckWorkToAncestor = delegateCheckWork = true;
1357
+ } else if (
1358
+ dependencyValues.inputChildren.length === 1 &&
1359
+ !dependencyValues.forceFullCheckworkButton
1360
+ ) {
1361
+ delegateCheckWorkToInput = delegateCheckWork = true;
1362
+ }
1363
+ return {
1364
+ setValue: {
1365
+ delegateCheckWork,
1366
+ delegateCheckWorkToAncestor,
1367
+ delegateCheckWorkToInput,
1368
+ },
1369
+ };
1370
+ },
1371
+ };
1372
+
1373
+ stateVariableDefinitions.creditAchievedIfSubmit = {
1374
+ additionalStateVariablesDefined: [
1375
+ "awardsUsedIfSubmit",
1376
+ "awardChildren",
1377
+ "inputUsedIfSubmit",
1378
+ ],
1379
+ stateVariablesDeterminingDependencies: ["inputChildIndices"],
1380
+ returnDependencies: ({ stateValues }) => ({
1381
+ awardChildren: {
1382
+ dependencyType: "child",
1383
+ childGroups: ["awards"],
1384
+ variableNames: [
1385
+ "credit",
1386
+ "creditAchievedIfSubmit",
1387
+ "fractionSatisfiedIfSubmit",
1388
+ ],
1389
+ },
1390
+ inputChildren: {
1391
+ dependencyType: "child",
1392
+ childGroups: ["inputs"],
1393
+ variableNames: ["creditAchievedIfSubmit", "value"], // include value so inputs always make dependency values change
1394
+ childIndices: stateValues.inputChildIndices,
1395
+ variablesOptional: true,
1396
+ },
1397
+ numAwardsCredited: {
1398
+ dependencyType: "stateVariable",
1399
+ variableName: "numAwardsCredited",
1400
+ },
1401
+ }),
1402
+ definition: function ({ dependencyValues }) {
1403
+ let creditAchieved = 0;
1404
+
1405
+ let n = dependencyValues.numAwardsCredited;
1406
+ let awardsUsed = Array(n).fill(null);
1407
+ let inputUsed = null;
1408
+
1409
+ if (dependencyValues.awardChildren.length === 0) {
1410
+ if (dependencyValues.inputChildren.length === 1) {
1411
+ let inputCredit =
1412
+ dependencyValues.inputChildren[0].stateValues
1413
+ .creditAchievedIfSubmit;
1414
+ // if input has a state variable creditAchievedIfSubmit
1415
+ // that is a non-negative number, use that value
1416
+ if (inputCredit >= 0) {
1417
+ creditAchieved = inputCredit;
1418
+ inputUsed = dependencyValues.inputChildren[0].componentName;
1419
+ }
1420
+ }
1421
+ } else {
1422
+ // awardsUsed will be component names of first awards
1423
+ // (up to numAwardsCredited)
1424
+ // that give the maximum credit (which will be creditAchieved)
1425
+ // Always process awards if haven't matched an award in case want to
1426
+ // use an award with credit=0 to trigger feedback
1427
+ let awardCredits = Array(n).fill(null);
1428
+ let minimumFromAwardCredits = 0;
1429
+ for (let child of dependencyValues.awardChildren) {
1430
+ let creditFromChild = child.stateValues.creditAchievedIfSubmit;
1431
+ if (
1432
+ creditFromChild > minimumFromAwardCredits ||
1433
+ awardsUsed[n - 1] === null
1434
+ ) {
1435
+ if (child.stateValues.fractionSatisfiedIfSubmit > 0) {
1436
+ if (awardsUsed[0] === null) {
1437
+ awardsUsed[0] = child.componentName;
1438
+ awardCredits[0] = creditFromChild;
1439
+ minimumFromAwardCredits = Math.min(...awardCredits);
1440
+ } else {
1441
+ for (let [ind, credit] of awardCredits.entries()) {
1442
+ if (creditFromChild > credit || credit === null) {
1443
+ awardsUsed.splice(ind, 0, child.componentName);
1444
+ awardsUsed = awardsUsed.slice(0, n);
1445
+ awardCredits.splice(ind, 0, creditFromChild);
1446
+ awardCredits = awardCredits.slice(0, n);
1447
+ minimumFromAwardCredits = Math.min(...awardCredits);
1448
+ break;
1449
+ }
1450
+ }
1451
+ }
1452
+ }
1453
+ }
1454
+ }
1455
+
1456
+ creditAchieved = Math.min(
1457
+ 1,
1458
+ awardCredits.reduce((a, c) => a + c, 0),
1459
+ );
1460
+ }
1461
+ return {
1462
+ setValue: {
1463
+ creditAchievedIfSubmit: creditAchieved,
1464
+ awardsUsedIfSubmit: awardsUsed,
1465
+ awardChildren: dependencyValues.awardChildren,
1466
+ inputUsedIfSubmit: inputUsed,
1467
+ },
1468
+ };
1469
+ },
1470
+ };
1471
+
1472
+ stateVariableDefinitions.displayDecimalsForCreditAchieved = {
1473
+ returnDependencies: () => ({}),
1474
+ definition: () => ({
1475
+ setValue: { displayDecimalsForCreditAchieved: -Infinity },
1476
+ }),
1477
+ };
1478
+
1479
+ stateVariableDefinitions.creditAchieved = {
1480
+ defaultValue: 0,
1481
+ public: true,
1482
+ shadowingInstructions: {
1483
+ createComponentOfType: "number",
1484
+ addAttributeComponentsShadowingStateVariables: {
1485
+ displayDigits: {
1486
+ stateVariableToShadow: "displayDigitsForCreditAchieved",
1487
+ },
1488
+ displayDecimals: {
1489
+ stateVariableToShadow: "displayDecimalsForCreditAchieved",
1490
+ },
1491
+ },
1492
+ },
1493
+ forRenderer: true,
1494
+ hasEssential: true,
1495
+ returnDependencies: () => ({}),
1496
+ definition: () => ({
1497
+ useEssentialOrDefaultValue: {
1498
+ creditAchieved: true,
1499
+ },
1500
+ }),
1501
+ inverseDefinition: function ({ desiredStateVariableValues }) {
1502
+ return {
1503
+ success: true,
1504
+ instructions: [
1505
+ {
1506
+ setEssentialValue: "creditAchieved",
1507
+ value: desiredStateVariableValues.creditAchieved,
1508
+ },
1509
+ ],
1510
+ };
1511
+ },
1512
+ };
1513
+
1514
+ stateVariableDefinitions.responseHasBeenSubmitted = {
1515
+ public: true,
1516
+ shadowingInstructions: {
1517
+ createComponentOfType: "boolean",
1518
+ },
1519
+ defaultValue: false,
1520
+ hasEssential: true,
1521
+ returnDependencies: () => ({}),
1522
+ definition: () => ({
1523
+ useEssentialOrDefaultValue: {
1524
+ responseHasBeenSubmitted: true,
1525
+ },
1526
+ }),
1527
+ inverseDefinition: function ({ desiredStateVariableValues }) {
1528
+ return {
1529
+ success: true,
1530
+ instructions: [
1531
+ {
1532
+ setEssentialValue: "responseHasBeenSubmitted",
1533
+ value: desiredStateVariableValues.responseHasBeenSubmitted,
1534
+ },
1535
+ ],
1536
+ };
1537
+ },
1538
+ };
1539
+
1540
+ stateVariableDefinitions.autoSubmit = {
1541
+ returnDependencies: () => ({
1542
+ autoSubmit: {
1543
+ dependencyType: "flag",
1544
+ flagName: "autoSubmit",
1545
+ },
1546
+ }),
1547
+ definition({ dependencyValues }) {
1548
+ return {
1549
+ setValue: { autoSubmit: Boolean(dependencyValues.autoSubmit) },
1550
+ };
1551
+ },
1552
+ };
1553
+
1554
+ stateVariableDefinitions.creditAchievedDependencies = {
1555
+ shadowVariable: true,
1556
+ stateVariablesDeterminingDependencies: ["autoSubmit"],
1557
+ returnDependencies: ({ stateValues }) => ({
1558
+ currentCreditAchievedDependencies: {
1559
+ dependencyType: "recursiveDependencyValues",
1560
+ variableNames: ["creditAchievedIfSubmit"],
1561
+ includeImmediateValueWithValue: !stateValues.autoSubmit,
1562
+ includeRawValueWithImmediateValue: !stateValues.autoSubmit,
1563
+ includeOnlyEssentialValues: true,
1564
+ },
1565
+ }),
1566
+ definition({ dependencyValues }) {
1567
+ // Use stringify from json-stringify-deterministic
1568
+ // so that the string will be the same
1569
+ // even if the object was built in a different order
1570
+ // (as can happen when reloading from a database)
1571
+
1572
+ let stringified = stringify(
1573
+ dependencyValues.currentCreditAchievedDependencies,
1574
+ { replacer: serializedComponentsReplacer },
1575
+ );
1576
+ return {
1577
+ setValue: {
1578
+ creditAchievedDependencies: Base64.stringify(sha1(stringified)),
1579
+ },
1580
+ };
1581
+ },
1582
+ markStale: () => ({ answerCreditPotentiallyChanged: true }),
1583
+ };
1584
+
1585
+ stateVariableDefinitions.creditAchievedDependenciesAtSubmit = {
1586
+ defaultValue: null,
1587
+ hasEssential: true,
1588
+ returnDependencies: () => ({}),
1589
+ definition: () => ({
1590
+ useEssentialOrDefaultValue: {
1591
+ creditAchievedDependenciesAtSubmit: true,
1592
+ },
1593
+ }),
1594
+ inverseDefinition: function ({ desiredStateVariableValues }) {
1595
+ return {
1596
+ success: true,
1597
+ instructions: [
1598
+ {
1599
+ setEssentialValue: "creditAchievedDependenciesAtSubmit",
1600
+ value:
1601
+ desiredStateVariableValues.creditAchievedDependenciesAtSubmit,
1602
+ },
1603
+ ],
1604
+ };
1605
+ },
1606
+ };
1607
+
1608
+ stateVariableDefinitions.justSubmitted = {
1609
+ public: true,
1610
+ shadowingInstructions: {
1611
+ createComponentOfType: "boolean",
1612
+ },
1613
+ forRenderer: true,
1614
+ defaultValue: false,
1615
+ hasEssential: true,
1616
+ shadowVariable: true,
1617
+ returnDependencies: () => ({
1618
+ currentCreditAchievedDependencies: {
1619
+ dependencyType: "stateVariable",
1620
+ variableName: "creditAchievedDependencies",
1621
+ },
1622
+ creditAchievedDependenciesAtSubmit: {
1623
+ dependencyType: "stateVariable",
1624
+ variableName: "creditAchievedDependenciesAtSubmit",
1625
+ },
1626
+ disableAfterCorrect: {
1627
+ dependencyType: "stateVariable",
1628
+ variableName: "disableAfterCorrect",
1629
+ },
1630
+ hasBeenCorrect: {
1631
+ dependencyType: "stateVariable",
1632
+ variableName: "hasBeenCorrect",
1633
+ },
1634
+ }),
1635
+ definition: function ({
1636
+ dependencyValues,
1637
+ justUpdatedForNewComponent,
1638
+ componentName,
1639
+ }) {
1640
+ if (
1641
+ dependencyValues.disableAfterCorrect &&
1642
+ dependencyValues.hasBeenCorrect
1643
+ ) {
1644
+ return {
1645
+ setValue: { justSubmitted: true },
1646
+ };
1647
+ }
1648
+
1649
+ let foundChange =
1650
+ dependencyValues.creditAchievedDependenciesAtSubmit !==
1651
+ dependencyValues.currentCreditAchievedDependencies;
1652
+
1653
+ if (foundChange && !justUpdatedForNewComponent) {
1654
+ return {
1655
+ setValue: { justSubmitted: false },
1656
+ setEssentialValue: { justSubmitted: false },
1657
+ };
1658
+ } else {
1659
+ return {
1660
+ useEssentialOrDefaultValue: { justSubmitted: true },
1661
+ };
1662
+ }
1663
+ },
1664
+ inverseDefinition({ desiredStateVariableValues, componentName }) {
1665
+ return {
1666
+ success: true,
1667
+ instructions: [
1668
+ {
1669
+ setEssentialValue: "justSubmitted",
1670
+ value: desiredStateVariableValues.justSubmitted,
1671
+ },
1672
+ ],
1673
+ };
1674
+ },
1675
+ };
1676
+
1677
+ stateVariableDefinitions.allFeedbacks = {
1678
+ returnDependencies: () => ({
1679
+ awardChildren: {
1680
+ dependencyType: "child",
1681
+ childGroups: ["awards"],
1682
+ variableNames: ["feedbacks"],
1683
+ },
1684
+ feedbackComponents: {
1685
+ dependencyType: "descendant",
1686
+ componentTypes: ["_input"],
1687
+ variableNames: ["feedbacks"],
1688
+ variablesOptional: true,
1689
+ },
1690
+ }),
1691
+ definition: function ({ dependencyValues }) {
1692
+ let feedbacks = [];
1693
+
1694
+ for (let award of dependencyValues.awardChildren) {
1695
+ feedbacks.push(...award.stateValues.feedbacks);
1696
+ }
1697
+ for (let feedbackComponent of dependencyValues.feedbackComponents) {
1698
+ if (Array.isArray(feedbackComponent.stateValues.feedbacks)) {
1699
+ feedbacks.push(...feedbackComponent.stateValues.feedbacks);
1700
+ }
1701
+ }
1702
+ return {
1703
+ setValue: {
1704
+ allFeedbacks: feedbacks,
1705
+ },
1706
+ };
1707
+ },
1708
+ };
1709
+
1710
+ stateVariableDefinitions.numFeedbacks = {
1711
+ public: true,
1712
+ shadowingInstructions: {
1713
+ createComponentOfType: "number",
1714
+ },
1715
+ returnDependencies: () => ({
1716
+ allFeedbacks: {
1717
+ dependencyType: "stateVariable",
1718
+ variableName: "allFeedbacks",
1719
+ },
1720
+ }),
1721
+ definition({ dependencyValues }) {
1722
+ return {
1723
+ setValue: { numFeedbacks: dependencyValues.allFeedbacks.length },
1724
+ checkForActualChange: { numFeedbacks: true },
1725
+ };
1726
+ },
1727
+ };
1728
+
1729
+ stateVariableDefinitions.feedbacks = {
1730
+ public: true,
1731
+ shadowingInstructions: {
1732
+ createComponentOfType: "feedback",
1733
+ },
1734
+ isArray: true,
1735
+ entryPrefixes: ["feedback"],
1736
+ returnArraySizeDependencies: () => ({
1737
+ numFeedbacks: {
1738
+ dependencyType: "stateVariable",
1739
+ variableName: "numFeedbacks",
1740
+ },
1741
+ }),
1742
+ returnArraySize({ dependencyValues }) {
1743
+ return [dependencyValues.numFeedbacks];
1744
+ },
1745
+ returnArrayDependenciesByKey() {
1746
+ let globalDependencies = {
1747
+ allFeedbacks: {
1748
+ dependencyType: "stateVariable",
1749
+ variableName: "allFeedbacks",
1750
+ },
1751
+ };
1752
+
1753
+ return { globalDependencies };
1754
+ },
1755
+ arrayDefinitionByKey({ globalDependencyValues }) {
1756
+ // console.log(`array definition by key of function feedbacks`)
1757
+ // console.log(globalDependencyValues)
1758
+
1759
+ let feedbacks = {};
1760
+
1761
+ for (
1762
+ let arrayKey = 0;
1763
+ arrayKey < globalDependencyValues.__array_size;
1764
+ arrayKey++
1765
+ ) {
1766
+ feedbacks[arrayKey] = globalDependencyValues.allFeedbacks[arrayKey];
1767
+ }
1768
+
1769
+ return { setValue: { feedbacks } };
1770
+ },
1771
+ };
1772
+
1773
+ stateVariableDefinitions.numSubmissions = {
1774
+ public: true,
1775
+ shadowingInstructions: {
1776
+ createComponentOfType: "integer",
1777
+ },
1778
+ defaultValue: 0,
1779
+ hasEssential: true,
1780
+ returnDependencies: () => ({}),
1781
+ definition: () => ({
1782
+ useEssentialOrDefaultValue: {
1783
+ numSubmissions: true,
1784
+ },
1785
+ }),
1786
+ inverseDefinition: ({ desiredStateVariableValues }) => ({
1787
+ success: true,
1788
+ instructions: [
1789
+ {
1790
+ setEssentialValue: "numSubmissions",
1791
+ value: desiredStateVariableValues.numSubmissions,
1792
+ },
1793
+ ],
1794
+ }),
1795
+ };
1796
+
1797
+ stateVariableDefinitions.numAttemptsLeft = {
1798
+ public: true,
1799
+ shadowingInstructions: {
1800
+ createComponentOfType: "integer",
1801
+ },
1802
+ forRenderer: true,
1803
+ returnDependencies: () => ({
1804
+ numSubmissions: {
1805
+ dependencyType: "stateVariable",
1806
+ variableName: "numSubmissions",
1807
+ },
1808
+ maxNumAttempts: {
1809
+ dependencyType: "stateVariable",
1810
+ variableName: "maxNumAttempts",
1811
+ },
1812
+ }),
1813
+ definition({ dependencyValues }) {
1814
+ return {
1815
+ setValue: {
1816
+ numAttemptsLeft:
1817
+ dependencyValues.maxNumAttempts - dependencyValues.numSubmissions,
1818
+ },
1819
+ };
1820
+ },
1821
+ };
1822
+
1823
+ stateVariableDefinitions.hasBeenCorrect = {
1824
+ defaultValue: false,
1825
+ hasEssential: true,
1826
+ shadowVariable: true,
1827
+ returnDependencies: () => ({
1828
+ creditAchieved: {
1829
+ dependencyType: "stateVariable",
1830
+ variableName: "creditAchieved",
1831
+ },
1832
+ }),
1833
+ definition({ dependencyValues }) {
1834
+ if (dependencyValues.creditAchieved === 1) {
1835
+ return {
1836
+ setValue: { hasBeenCorrect: true },
1837
+ setEssentialValue: { hasBeenCorrect: true },
1838
+ };
1839
+ }
1840
+
1841
+ return {
1842
+ useEssentialOrDefaultValue: {
1843
+ hasBeenCorrect: true,
1844
+ },
1845
+ };
1846
+ },
1847
+ };
1848
+
1849
+ stateVariableDefinitions.disabled = {
1850
+ public: true,
1851
+ shadowingInstructions: {
1852
+ createComponentOfType: "boolean",
1853
+ },
1854
+ forRenderer: true,
1855
+ stateVariablesDeterminingDependencies: ["disableAfterCorrect"],
1856
+ returnDependencies({ stateValues }) {
1857
+ let dependencies = {
1858
+ disabledOriginal: {
1859
+ dependencyType: "stateVariable",
1860
+ variableName: "disabledOriginal",
1861
+ },
1862
+ numAttemptsLeft: {
1863
+ dependencyType: "stateVariable",
1864
+ variableName: "numAttemptsLeft",
1865
+ },
1866
+ disableAfterCorrect: {
1867
+ dependencyType: "stateVariable",
1868
+ variableName: "disableAfterCorrect",
1869
+ },
1870
+ };
1871
+
1872
+ if (stateValues.disableAfterCorrect) {
1873
+ dependencies.hasBeenCorrect = {
1874
+ dependencyType: "stateVariable",
1875
+ variableName: "hasBeenCorrect",
1876
+ };
1877
+ }
1878
+
1879
+ return dependencies;
1880
+ },
1881
+ definition({ dependencyValues }) {
1882
+ let disabled =
1883
+ dependencyValues.disabledOriginal ||
1884
+ dependencyValues.numAttemptsLeft < 1 ||
1885
+ (dependencyValues.disableAfterCorrect &&
1886
+ dependencyValues.hasBeenCorrect);
1887
+
1888
+ return { setValue: { disabled } };
1889
+ },
1890
+ };
1891
+
1892
+ stateVariableDefinitions.inItemNumber = {
1893
+ returnDependencies: () => ({
1894
+ documentAncestor: {
1895
+ dependencyType: "ancestor",
1896
+ componentType: "document",
1897
+ variableNames: ["itemNumberByAnswerName"],
1898
+ },
1899
+ }),
1900
+ definition({ dependencyValues, componentName }) {
1901
+ return {
1902
+ setValue: {
1903
+ inItemNumber:
1904
+ dependencyValues.documentAncestor.stateValues
1905
+ .itemNumberByAnswerName[componentName],
1906
+ },
1907
+ };
1908
+ },
1909
+ };
1910
+
1911
+ return stateVariableDefinitions;
1912
+ }
1913
+
1914
+ async submitAnswer({
1915
+ actionId,
1916
+ sourceInformation = {},
1917
+ skipRendererUpdate = false,
1918
+ }) {
1919
+ let numAttemptsLeft = await this.stateValues.numAttemptsLeft;
1920
+ if (numAttemptsLeft < 1) {
1921
+ console.warn(
1922
+ `Cannot submit answer for ${this.componentName} as number of attempts left is ${numAttemptsLeft}`,
1923
+ );
1924
+ return;
1925
+ }
1926
+
1927
+ let creditAchieved = await this.stateValues.creditAchievedIfSubmit;
1928
+ if (await this.stateValues.handGraded) {
1929
+ creditAchieved = 0;
1930
+ }
1931
+ let awardsUsed = await this.stateValues.awardsUsedIfSubmit;
1932
+ let inputUsed = await this.stateValues.inputUsedIfSubmit;
1933
+
1934
+ // request to update credit
1935
+ let instructions = [
1936
+ {
1937
+ updateType: "updateValue",
1938
+ componentName: this.componentName,
1939
+ stateVariable: "creditAchieved",
1940
+ value: creditAchieved,
1941
+ },
1942
+ {
1943
+ updateType: "updateValue",
1944
+ componentName: this.componentName,
1945
+ stateVariable: "responseHasBeenSubmitted",
1946
+ value: true,
1947
+ },
1948
+ ];
1949
+
1950
+ let inputChildrenWithValues = await this.stateValues
1951
+ .inputChildrenWithValues;
1952
+
1953
+ if (inputChildrenWithValues.length === 1) {
1954
+ // if have a single input descendant,
1955
+ // then will record the current value
1956
+
1957
+ let inputChild = inputChildrenWithValues[0];
1958
+
1959
+ if (
1960
+ inputUsed === inputChild.componentName &&
1961
+ "valueToRecordOnSubmit" in inputChild.stateValues &&
1962
+ "valueRecordedAtSubmit" in inputChild.stateValues
1963
+ ) {
1964
+ instructions.push({
1965
+ updateType: "updateValue",
1966
+ componentName: inputChild.componentName,
1967
+ stateVariable: "valueRecordedAtSubmit",
1968
+ value: inputChild.stateValues.valueToRecordOnSubmit,
1969
+ });
1970
+ }
1971
+ }
1972
+
1973
+ // add submitted responses to instruction for answer
1974
+ let currentResponses = await this.stateValues.currentResponses;
1975
+ // let currentResponses = await this.state.currentResponses.value;
1976
+
1977
+ instructions.push({
1978
+ updateType: "updateValue",
1979
+ componentName: this.componentName,
1980
+ stateVariable: "submittedResponses",
1981
+ value: currentResponses,
1982
+ });
1983
+
1984
+ instructions.push({
1985
+ updateType: "updateValue",
1986
+ componentName: this.componentName,
1987
+ stateVariable: "submittedResponsesComponentType",
1988
+ value:
1989
+ this.state.currentResponses.shadowingInstructions.createComponentOfType,
1990
+ });
1991
+
1992
+ instructions.push({
1993
+ updateType: "updateValue",
1994
+ componentName: this.componentName,
1995
+ stateVariable: "justSubmitted",
1996
+ value: true,
1997
+ });
1998
+
1999
+ instructions.push({
2000
+ updateType: "updateValue",
2001
+ componentName: this.componentName,
2002
+ stateVariable: "creditAchievedDependenciesAtSubmit",
2003
+ value: await this.stateValues.creditAchievedDependencies,
2004
+ });
2005
+
2006
+ instructions.push({
2007
+ updateType: "updateValue",
2008
+ componentName: this.componentName,
2009
+ stateVariable: "numSubmissions",
2010
+ value: (await this.stateValues.numSubmissions) + 1,
2011
+ });
2012
+
2013
+ for (let child of await this.stateValues.awardChildren) {
2014
+ let awarded = awardsUsed.includes(child.componentName);
2015
+ instructions.push({
2016
+ updateType: "updateValue",
2017
+ componentName: child.componentName,
2018
+ stateVariable: "awarded",
2019
+ value: awarded,
2020
+ });
2021
+ instructions.push({
2022
+ updateType: "updateValue",
2023
+ componentName: child.componentName,
2024
+ stateVariable: "creditAchieved",
2025
+ value: child.stateValues.creditAchievedIfSubmit,
2026
+ });
2027
+ instructions.push({
2028
+ updateType: "updateValue",
2029
+ componentName: child.componentName,
2030
+ stateVariable: "fractionSatisfied",
2031
+ value: child.stateValues.fractionSatisfiedIfSubmit,
2032
+ });
2033
+ }
2034
+
2035
+ let responseText = [];
2036
+ for (let response of currentResponses) {
2037
+ if (response.toString) {
2038
+ try {
2039
+ responseText.push(response.toString());
2040
+ } catch (e) {
2041
+ responseText.push("\uff3f");
2042
+ }
2043
+ } else {
2044
+ responseText.push(response);
2045
+ }
2046
+ }
2047
+
2048
+ instructions.push({
2049
+ updateType: "recordItemSubmission",
2050
+ itemNumber: await this.stateValues.inItemNumber,
2051
+ submittedComponent: this.componentName,
2052
+ response: currentResponses,
2053
+ responseText,
2054
+ creditAchieved,
2055
+ });
2056
+
2057
+ // console.log(`submit instructions`)
2058
+ // console.log(instructions);
2059
+
2060
+ await this.coreFunctions.performUpdate({
2061
+ updateInstructions: instructions,
2062
+ actionId,
2063
+ sourceInformation,
2064
+ skipRendererUpdate: true,
2065
+ event: {
2066
+ verb: "submitted",
2067
+ object: {
2068
+ componentName: this.componentName,
2069
+ componentType: this.componentType,
2070
+ },
2071
+ result: {
2072
+ response: currentResponses,
2073
+ responseText,
2074
+ creditAchieved,
2075
+ },
2076
+ },
2077
+ suppressToast: await this.stateValues.suppressToast, // temporary
2078
+ });
2079
+
2080
+ return await this.coreFunctions.triggerChainedActions({
2081
+ componentName: this.componentName,
2082
+ actionId,
2083
+ sourceInformation,
2084
+ skipRendererUpdate,
2085
+ });
2086
+ }
2087
+ }