@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,3157 @@
1
+ import Input from "./abstract/Input";
2
+ import me from "math-expressions";
3
+ import { deepClone, deepCompare } from "../utils/deepFunctions";
4
+ import {
5
+ convertValueToMathExpression,
6
+ getFromLatex,
7
+ normalizeLatexString,
8
+ roundForDisplay,
9
+ stripLatex,
10
+ vectorOperators,
11
+ } from "../utils/math";
12
+ import CompositeComponent from "./abstract/CompositeComponent";
13
+ import BaseComponent from "./abstract/BaseComponent";
14
+ import {
15
+ returnRoundingAttributeComponentShadowing,
16
+ returnRoundingAttributes,
17
+ returnRoundingStateVariableDefinitions,
18
+ } from "../utils/rounding";
19
+
20
+ export class MatrixInput extends Input {
21
+ constructor(args) {
22
+ super(args);
23
+
24
+ Object.assign(this.actions, {
25
+ updateNumRows: this.updateNumRows.bind(this),
26
+ updateNumColumns: this.updateNumColumns.bind(this),
27
+ });
28
+
29
+ this.externalActions = {};
30
+
31
+ //Complex because the stateValues isn't defined until later
32
+ Object.defineProperty(this.externalActions, "submitAnswer", {
33
+ enumerable: true,
34
+ get: async function () {
35
+ let answerAncestor = await this.stateValues.answerAncestor;
36
+ if (answerAncestor !== null) {
37
+ return {
38
+ componentName: answerAncestor.componentName,
39
+ actionName: "submitAnswer",
40
+ };
41
+ } else {
42
+ return;
43
+ }
44
+ }.bind(this),
45
+ });
46
+ }
47
+
48
+ static componentType = "matrixInput";
49
+
50
+ static variableForPlainMacro = "value";
51
+ static variableForPlainCopy = "value";
52
+
53
+ static processWhenJustUpdatedForNewComponent = true;
54
+
55
+ static renderChildren = true;
56
+
57
+ static createAttributesObject() {
58
+ let attributes = super.createAttributesObject();
59
+
60
+ attributes.numRows = {
61
+ createComponentOfType: "integer",
62
+ createStateVariable: "numRowsPreliminary",
63
+ defaultValue: 1,
64
+ transformNonFiniteTo: 0,
65
+ };
66
+ attributes.numColumns = {
67
+ createComponentOfType: "integer",
68
+ createStateVariable: "numColumnsPreliminary",
69
+ defaultValue: 1,
70
+ transformNonFiniteTo: 0,
71
+ };
72
+
73
+ attributes.showSizeControls = {
74
+ createComponentOfType: "boolean",
75
+ createStateVariable: "showSizeControls",
76
+ defaultValue: true,
77
+ public: true,
78
+ forRenderer: true,
79
+ };
80
+
81
+ attributes.defaultEntry = {
82
+ createComponentOfType: "math",
83
+ createStateVariable: "defaultEntry",
84
+ defaultValue: me.fromAst("\uff3f"),
85
+ };
86
+
87
+ attributes.prefill = {
88
+ createComponentOfType: "math",
89
+ createStateVariable: "prefill",
90
+ defaultValue: me.fromAst("\uff3f"),
91
+ public: true,
92
+ copyComponentAttributesForCreatedComponent: [
93
+ "format",
94
+ "functionSymbols",
95
+ "splitSymbols",
96
+ "parseScientificNotation",
97
+ ],
98
+ };
99
+ attributes.format = {
100
+ createComponentOfType: "text",
101
+ createStateVariable: "format",
102
+ defaultValue: "text",
103
+ public: true,
104
+ };
105
+ attributes.functionSymbols = {
106
+ createComponentOfType: "textList",
107
+ createStateVariable: "functionSymbols",
108
+ defaultValue: ["f", "g"],
109
+ public: true,
110
+ };
111
+ attributes.splitSymbols = {
112
+ createComponentOfType: "boolean",
113
+ createStateVariable: "splitSymbols",
114
+ defaultValue: true,
115
+ public: true,
116
+ };
117
+ attributes.parseScientificNotation = {
118
+ createComponentOfType: "boolean",
119
+ createStateVariable: "parseScientificNotation",
120
+ defaultValue: false,
121
+ public: true,
122
+ };
123
+
124
+ Object.assign(attributes, returnRoundingAttributes());
125
+
126
+ attributes.bindValueTo = {
127
+ createComponentOfType: "math",
128
+ };
129
+ attributes.unionFromU = {
130
+ createComponentOfType: "boolean",
131
+ createStateVariable: "unionFromU",
132
+ defaultValue: false,
133
+ public: true,
134
+ };
135
+ attributes.minComponentWidth = {
136
+ createComponentOfType: "integer",
137
+ createStateVariable: "minComponentWidth",
138
+ defaultValue: 0,
139
+ };
140
+
141
+ return attributes;
142
+ }
143
+
144
+ static returnSugarInstructions() {
145
+ let sugarInstructions = super.returnSugarInstructions();
146
+
147
+ let addMatrixInputGrid = function ({ matchedChildren }) {
148
+ let matrixInputGrid = {
149
+ componentType: "_matrixInputGrid",
150
+ };
151
+
152
+ return {
153
+ success: true,
154
+ newChildren: [matrixInputGrid, ...matchedChildren],
155
+ };
156
+ };
157
+ sugarInstructions.push({
158
+ replacementFunction: addMatrixInputGrid,
159
+ });
160
+ return sugarInstructions;
161
+ }
162
+
163
+ static returnChildGroups() {
164
+ return [
165
+ {
166
+ group: "matrixComponentInputs",
167
+ componentTypes: ["_matrixComponentInput"],
168
+ },
169
+ {
170
+ group: "maths",
171
+ componentTypes: ["math"],
172
+ },
173
+ ];
174
+ }
175
+
176
+ static returnStateVariableDefinitions() {
177
+ let stateVariableDefinitions = super.returnStateVariableDefinitions();
178
+
179
+ Object.assign(
180
+ stateVariableDefinitions,
181
+ returnRoundingStateVariableDefinitions({
182
+ displayDigitsDefault: 10,
183
+ displaySmallAsZeroDefault: 0,
184
+ }),
185
+ );
186
+
187
+ stateVariableDefinitions.valueChanged = {
188
+ public: true,
189
+ hasEssential: true,
190
+ defaultValue: false,
191
+ shadowingInstructions: {
192
+ createComponentOfType: "boolean",
193
+ },
194
+ returnDependencies: () => ({}),
195
+ definition() {
196
+ return { useEssentialOrDefaultValue: { valueChanged: true } };
197
+ },
198
+ inverseDefinition({ desiredStateVariableValues }) {
199
+ return {
200
+ success: true,
201
+ instructions: [
202
+ {
203
+ setEssentialValue: "valueChanged",
204
+ value: Boolean(desiredStateVariableValues.valueChanged),
205
+ },
206
+ ],
207
+ };
208
+ },
209
+ };
210
+
211
+ stateVariableDefinitions.valueOriginal = {
212
+ hasEssential: true,
213
+ shadowVariable: true,
214
+ returnDependencies: () => ({
215
+ mathChild: {
216
+ dependencyType: "child",
217
+ childGroups: ["maths"],
218
+ variableNames: ["value"],
219
+ proceedIfAllChildrenNotMatched: true, // to avoid circular dependency with readyToExpandWhenResolved of matrixInputGrid child
220
+ },
221
+ bindValueTo: {
222
+ dependencyType: "attributeComponent",
223
+ attributeName: "bindValueTo",
224
+ variableNames: ["value"],
225
+ },
226
+ prefill: {
227
+ dependencyType: "stateVariable",
228
+ variableName: "prefill",
229
+ },
230
+ valueChanged: {
231
+ dependencyType: "stateVariable",
232
+ variableName: "valueChanged",
233
+ onlyToSetInInverseDefinition: true,
234
+ },
235
+ immediateValueChanged: {
236
+ dependencyType: "stateVariable",
237
+ variableName: "immediateValueChanged",
238
+ onlyToSetInInverseDefinition: true,
239
+ },
240
+ }),
241
+ set: convertValueToMathExpression,
242
+ definition: function ({ dependencyValues }) {
243
+ if (dependencyValues.mathChild.length > 0) {
244
+ return {
245
+ setValue: {
246
+ valueOriginal: dependencyValues.mathChild[0].stateValues.value,
247
+ },
248
+ };
249
+ } else if (dependencyValues.bindValueTo) {
250
+ return {
251
+ setValue: {
252
+ valueOriginal: dependencyValues.bindValueTo.stateValues.value,
253
+ },
254
+ };
255
+ } else {
256
+ return {
257
+ useEssentialOrDefaultValue: {
258
+ valueOriginal: {
259
+ defaultValue: dependencyValues.prefill,
260
+ },
261
+ },
262
+ };
263
+ }
264
+ },
265
+ inverseDefinition: function ({
266
+ desiredStateVariableValues,
267
+ dependencyValues,
268
+ }) {
269
+ // console.log(`inverse definition of valueOriginal for matrixInput`);
270
+ // console.log(desiredStateVariableValues);
271
+
272
+ let instructions = [
273
+ {
274
+ setDependency: "valueChanged",
275
+ desiredValue: true,
276
+ },
277
+ {
278
+ setDependency: "immediateValueChanged",
279
+ desiredValue: true,
280
+ },
281
+ ];
282
+
283
+ if (dependencyValues.mathChild.length > 0) {
284
+ instructions.push({
285
+ setDependency: "mathChild",
286
+ desiredValue: desiredStateVariableValues.valueOriginal,
287
+ variableIndex: 0,
288
+ childIndex: 0,
289
+ });
290
+ } else if (dependencyValues.bindValueTo) {
291
+ instructions.push({
292
+ setDependency: "bindValueTo",
293
+ desiredValue: desiredStateVariableValues.valueOriginal,
294
+ variableIndex: 0,
295
+ });
296
+ } else {
297
+ // no math child or bindValueTo, so valueOriginal is essential and give it the desired value
298
+ instructions.push({
299
+ setEssentialValue: "valueOriginal",
300
+ value: desiredStateVariableValues.valueOriginal,
301
+ });
302
+ }
303
+ return { success: true, instructions };
304
+ },
305
+ };
306
+
307
+ stateVariableDefinitions.immediateValueChanged = {
308
+ public: true,
309
+ hasEssential: true,
310
+ defaultValue: false,
311
+ shadowingInstructions: {
312
+ createComponentOfType: "boolean",
313
+ },
314
+ returnDependencies: () => ({}),
315
+ definition() {
316
+ return { useEssentialOrDefaultValue: { immediateValueChanged: true } };
317
+ },
318
+ inverseDefinition({ desiredStateVariableValues }) {
319
+ return {
320
+ success: true,
321
+ instructions: [
322
+ {
323
+ setEssentialValue: "immediateValueChanged",
324
+ value: Boolean(desiredStateVariableValues.immediateValueChanged),
325
+ },
326
+ ],
327
+ };
328
+ },
329
+ };
330
+
331
+ stateVariableDefinitions.immediateValueOriginal = {
332
+ hasEssential: true,
333
+ shadowVariable: true,
334
+ returnDependencies: () => ({
335
+ valueOriginal: {
336
+ dependencyType: "stateVariable",
337
+ variableName: "valueOriginal",
338
+ },
339
+ immediateValueChanged: {
340
+ dependencyType: "stateVariable",
341
+ variableName: "immediateValueChanged",
342
+ onlyToSetInInverseDefinition: true,
343
+ },
344
+ }),
345
+ set: convertValueToMathExpression,
346
+ definition: function ({
347
+ dependencyValues,
348
+ changes,
349
+ justUpdatedForNewComponent,
350
+ usedDefault,
351
+ }) {
352
+ // console.log(`definition of immediateValueOriginal`)
353
+ // console.log(dependencyValues)
354
+ // console.log(changes);
355
+ // console.log(dependencyValues.valueOriginal.toString())
356
+
357
+ if (
358
+ changes.valueOriginal &&
359
+ !justUpdatedForNewComponent &&
360
+ !usedDefault.valueOriginal
361
+ ) {
362
+ // only update to valueOriginal when it changes
363
+ // (otherwise, let its essential value change)
364
+ return {
365
+ setValue: {
366
+ immediateValueOriginal: dependencyValues.valueOriginal,
367
+ },
368
+ setEssentialValue: {
369
+ immediateValueOriginal: dependencyValues.valueOriginal,
370
+ },
371
+ };
372
+ } else {
373
+ return {
374
+ useEssentialOrDefaultValue: {
375
+ immediateValueOriginal: {
376
+ defaultValue: dependencyValues.valueOriginal,
377
+ },
378
+ },
379
+ };
380
+ }
381
+ },
382
+ inverseDefinition: function ({
383
+ desiredStateVariableValues,
384
+ initialChange,
385
+ shadowedVariable,
386
+ }) {
387
+ // value is essential; give it the desired value
388
+ let instructions = [
389
+ {
390
+ setEssentialValue: "immediateValueOriginal",
391
+ value: desiredStateVariableValues.immediateValueOriginal,
392
+ },
393
+ {
394
+ setDependency: "immediateValueChanged",
395
+ desiredValue: true,
396
+ },
397
+ ];
398
+
399
+ // if from outside sources, also set value
400
+ if (!(initialChange || shadowedVariable)) {
401
+ instructions.push({
402
+ setDependency: "valueOriginal",
403
+ desiredValue: desiredStateVariableValues.immediateValueOriginal,
404
+ });
405
+ }
406
+
407
+ return {
408
+ success: true,
409
+ instructions,
410
+ };
411
+ },
412
+ };
413
+
414
+ stateVariableDefinitions.haveBoundValue = {
415
+ returnDependencies: () => ({
416
+ mathChild: {
417
+ dependencyType: "child",
418
+ childGroups: ["maths"],
419
+ proceedIfAllChildrenNotMatched: true, // to avoid circular dependency with readyToExpandWhenResolved of matrixInputGrid child
420
+ },
421
+ bindValueTo: {
422
+ dependencyType: "attributeComponent",
423
+ attributeName: "bindValueTo",
424
+ },
425
+ }),
426
+ definition({ dependencyValues }) {
427
+ return {
428
+ setValue: {
429
+ haveBoundValue:
430
+ dependencyValues.mathChild.length > 0 ||
431
+ dependencyValues.bindValueTo !== null,
432
+ },
433
+ };
434
+ },
435
+ };
436
+
437
+ stateVariableDefinitions.numRows = {
438
+ public: true,
439
+ shadowingInstructions: {
440
+ createComponentOfType: "integer",
441
+ },
442
+ forRenderer: true,
443
+ returnDependencies: () => ({
444
+ numRowsPreliminary: {
445
+ dependencyType: "stateVariable",
446
+ variableName: "numRowsPreliminary",
447
+ },
448
+ valueOriginal: {
449
+ dependencyType: "stateVariable",
450
+ variableName: "valueOriginal",
451
+ },
452
+ haveBoundValue: {
453
+ dependencyType: "stateVariable",
454
+ variableName: "haveBoundValue",
455
+ },
456
+ valueChanged: {
457
+ dependencyType: "stateVariable",
458
+ variableName: "valueChanged",
459
+ onlyToSetInInverseDefinition: true,
460
+ },
461
+ immediateValueChanged: {
462
+ dependencyType: "stateVariable",
463
+ variableName: "immediateValueChanged",
464
+ onlyToSetInInverseDefinition: true,
465
+ },
466
+ }),
467
+ definition({ dependencyValues, usedDefault }) {
468
+ let numRows = dependencyValues.numRowsPreliminary;
469
+
470
+ if (usedDefault.numRowsPreliminary || dependencyValues.haveBoundValue) {
471
+ let originalTree = dependencyValues.valueOriginal.tree;
472
+
473
+ numRows = 1;
474
+
475
+ if (Array.isArray(originalTree)) {
476
+ let operator = originalTree[0];
477
+ if (operator === "matrix") {
478
+ numRows = originalTree[1][1];
479
+ } else if (vectorOperators.includes(operator)) {
480
+ numRows = originalTree.length - 1;
481
+ }
482
+ }
483
+ }
484
+
485
+ return { setValue: { numRows } };
486
+ },
487
+ async inverseDefinition({
488
+ desiredStateVariableValues,
489
+ dependencyValues,
490
+ stateValues,
491
+ }) {
492
+ let desiredNumRows = desiredStateVariableValues.numRows;
493
+ if (!Number.isInteger(desiredNumRows)) {
494
+ return { success: false };
495
+ }
496
+ desiredNumRows = Math.max(0, desiredNumRows);
497
+
498
+ let instructions = [
499
+ {
500
+ setDependency: "numRowsPreliminary",
501
+ desiredValue: desiredNumRows,
502
+ },
503
+ { setDependency: "valueChanged", desiredValue: true },
504
+ { setDependency: "immediateValueChanged", desiredValue: true },
505
+ ];
506
+
507
+ if (dependencyValues.haveBoundValue) {
508
+ let originalTree = dependencyValues.valueOriginal.tree;
509
+ let defaultEntryTree = (await stateValues.defaultEntry).tree;
510
+ if (
511
+ (await stateValues.numColumns) === 1 &&
512
+ Array.isArray(originalTree) &&
513
+ vectorOperators.includes(originalTree[0])
514
+ ) {
515
+ // original value was a vector
516
+ // so we keep it a vector
517
+
518
+ let currentNumRows = originalTree.length - 1;
519
+
520
+ if (desiredNumRows < currentNumRows) {
521
+ let newTree = deepClone(originalTree).slice(
522
+ 0,
523
+ desiredNumRows + 1,
524
+ );
525
+ instructions.push({
526
+ setDependency: "valueOriginal",
527
+ desiredValue: me.fromAst(newTree),
528
+ });
529
+ } else if (desiredNumRows > currentNumRows) {
530
+ let newTree = deepClone(originalTree);
531
+ let accumulatedComponents =
532
+ await stateValues.accumulatedComponents;
533
+ for (
534
+ let rowInd = currentNumRows;
535
+ rowInd < desiredNumRows;
536
+ rowInd++
537
+ ) {
538
+ let accumRow = accumulatedComponents[rowInd];
539
+ let accumVal;
540
+ if (accumRow) {
541
+ accumVal = accumRow[0];
542
+ }
543
+ newTree[rowInd + 1] =
544
+ accumVal === undefined ? defaultEntryTree : accumVal;
545
+ }
546
+ instructions.push({
547
+ setDependency: "valueOriginal",
548
+ desiredValue: me.fromAst(newTree),
549
+ });
550
+ }
551
+ } else {
552
+ let valueTree = deepClone((await stateValues.value).tree);
553
+ let previousNumRows = valueTree[1][1];
554
+ valueTree[1][1] = desiredNumRows;
555
+
556
+ if (desiredNumRows !== previousNumRows) {
557
+ if (desiredNumRows < previousNumRows) {
558
+ valueTree[2].length = desiredNumRows + 1;
559
+ } else {
560
+ // add any extra rows
561
+ let numColumns = await stateValues.numColumns;
562
+ let data = valueTree[2];
563
+ let accumulatedComponents =
564
+ await stateValues.accumulatedComponents;
565
+
566
+ for (
567
+ let rowInd = previousNumRows;
568
+ rowInd < desiredNumRows;
569
+ rowInd++
570
+ ) {
571
+ if (!data[rowInd + 1]) {
572
+ data[rowInd + 1] = ["tuple"];
573
+ }
574
+
575
+ let accumRow = accumulatedComponents[rowInd];
576
+ if (!accumRow) {
577
+ accumRow = [];
578
+ }
579
+
580
+ for (let colInd = 0; colInd < numColumns; colInd++) {
581
+ let accumVal = accumRow[colInd];
582
+ data[rowInd + 1][colInd + 1] =
583
+ accumVal === undefined ? defaultEntryTree : accumVal;
584
+ }
585
+ }
586
+ }
587
+
588
+ instructions.push({
589
+ setDependency: "valueOriginal",
590
+ desiredValue: me.fromAst(valueTree),
591
+ });
592
+ }
593
+ }
594
+ }
595
+
596
+ console.log(instructions);
597
+
598
+ return {
599
+ success: true,
600
+ instructions,
601
+ };
602
+ },
603
+ };
604
+
605
+ stateVariableDefinitions.numColumns = {
606
+ public: true,
607
+ shadowingInstructions: {
608
+ createComponentOfType: "integer",
609
+ },
610
+ forRenderer: true,
611
+ returnDependencies: () => ({
612
+ numColumnsPreliminary: {
613
+ dependencyType: "stateVariable",
614
+ variableName: "numColumnsPreliminary",
615
+ },
616
+ valueOriginal: {
617
+ dependencyType: "stateVariable",
618
+ variableName: "valueOriginal",
619
+ },
620
+ haveBoundValue: {
621
+ dependencyType: "stateVariable",
622
+ variableName: "haveBoundValue",
623
+ },
624
+ valueChanged: {
625
+ dependencyType: "stateVariable",
626
+ variableName: "valueChanged",
627
+ onlyToSetInInverseDefinition: true,
628
+ },
629
+ immediateValueChanged: {
630
+ dependencyType: "stateVariable",
631
+ variableName: "immediateValueChanged",
632
+ onlyToSetInInverseDefinition: true,
633
+ },
634
+ }),
635
+ definition({ dependencyValues, usedDefault }) {
636
+ let numColumns = dependencyValues.numColumnsPreliminary;
637
+
638
+ if (
639
+ usedDefault.numColumnsPreliminary ||
640
+ dependencyValues.haveBoundValue
641
+ ) {
642
+ let originalTree = dependencyValues.valueOriginal.tree;
643
+
644
+ numColumns = 1;
645
+
646
+ if (Array.isArray(originalTree)) {
647
+ let operator = originalTree[0];
648
+ if (operator === "matrix") {
649
+ numColumns = originalTree[1][2];
650
+ } else if (
651
+ Array.isArray(originalTree[1]) &&
652
+ vectorOperators.includes(originalTree[1][0]) &&
653
+ ((operator === "^" && originalTree[2] === "T") ||
654
+ operator === "prime")
655
+ ) {
656
+ numColumns = originalTree[1].length - 1;
657
+ }
658
+ }
659
+ }
660
+
661
+ return { setValue: { numColumns } };
662
+ },
663
+ async inverseDefinition({
664
+ desiredStateVariableValues,
665
+ dependencyValues,
666
+ stateValues,
667
+ }) {
668
+ let desiredNumColumns = desiredStateVariableValues.numColumns;
669
+ if (!Number.isInteger(desiredNumColumns)) {
670
+ return { success: false };
671
+ }
672
+ desiredNumColumns = Math.max(0, desiredNumColumns);
673
+
674
+ let instructions = [
675
+ {
676
+ setDependency: "numColumnsPreliminary",
677
+ desiredValue: desiredNumColumns,
678
+ },
679
+ { setDependency: "valueChanged", desiredValue: true },
680
+ { setDependency: "immediateValueChanged", desiredValue: true },
681
+ ];
682
+
683
+ if (dependencyValues.haveBoundValue) {
684
+ let defaultEntryTree = (await stateValues.defaultEntry).tree;
685
+ let originalTree = dependencyValues.valueOriginal.tree;
686
+ let operator = originalTree[0];
687
+
688
+ if (
689
+ Array.isArray(originalTree[1]) &&
690
+ vectorOperators.includes(originalTree[1][0]) &&
691
+ ((operator === "^" && originalTree[2] === "T") ||
692
+ operator === "prime")
693
+ ) {
694
+ // original value was a transpose of a vector
695
+ // so we keep it a transpose of a vector
696
+
697
+ let currentNumColumns = originalTree[1].length - 1;
698
+
699
+ if (desiredNumColumns < currentNumColumns) {
700
+ let newTree = deepClone(originalTree);
701
+ newTree[1] = newTree[1].slice(0, desiredNumColumns + 1);
702
+ instructions.push({
703
+ setDependency: "valueOriginal",
704
+ desiredValue: me.fromAst(newTree),
705
+ });
706
+ } else if (desiredNumColumns > currentNumColumns) {
707
+ let newTree = deepClone(originalTree);
708
+ let accumRow = (await stateValues.accumulatedComponents)[0];
709
+ if (!accumRow) {
710
+ accumRow = [];
711
+ }
712
+
713
+ for (
714
+ let colInd = currentNumColumns;
715
+ colInd < desiredNumColumns;
716
+ colInd++
717
+ ) {
718
+ let accumVal = accumRow[colInd];
719
+ newTree[1][colInd + 1] =
720
+ accumVal === undefined ? defaultEntryTree : accumVal;
721
+ }
722
+ instructions.push({
723
+ setDependency: "valueOriginal",
724
+ desiredValue: me.fromAst(newTree),
725
+ });
726
+ }
727
+ } else {
728
+ let valueTree = deepClone((await stateValues.value).tree);
729
+ let previousNumColumns = valueTree[1][2];
730
+ valueTree[1][2] = desiredNumColumns;
731
+
732
+ if (desiredNumColumns !== previousNumColumns) {
733
+ let numRows = await stateValues.numRows;
734
+ let data = valueTree[2];
735
+
736
+ if (desiredNumColumns < previousNumColumns) {
737
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
738
+ data[rowInd + 1].length = desiredNumColumns + 1;
739
+ }
740
+ } else {
741
+ // add any extra columns
742
+ let accumulatedComponents =
743
+ await stateValues.accumulatedComponents;
744
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
745
+ let accumRow = accumulatedComponents[rowInd];
746
+ if (!accumRow) {
747
+ accumRow = [];
748
+ }
749
+
750
+ for (
751
+ let colInd = previousNumColumns;
752
+ colInd < desiredNumColumns;
753
+ colInd++
754
+ ) {
755
+ let accumVal = accumRow[colInd];
756
+ data[rowInd + 1][colInd + 1] =
757
+ accumVal === undefined ? defaultEntryTree : accumVal;
758
+ }
759
+ }
760
+ }
761
+
762
+ instructions.push({
763
+ setDependency: "valueOriginal",
764
+ desiredValue: me.fromAst(valueTree),
765
+ });
766
+ }
767
+ }
768
+ }
769
+
770
+ return {
771
+ success: true,
772
+ instructions,
773
+ };
774
+ },
775
+ };
776
+
777
+ stateVariableDefinitions.accumulatedComponents = {
778
+ providePreviousValuesInDefinition: true,
779
+ returnDependencies: () => ({
780
+ valueOriginal: {
781
+ dependencyType: "stateVariable",
782
+ variableName: "valueOriginal",
783
+ },
784
+ }),
785
+ definition({ dependencyValues, previousValues }) {
786
+ let accumulatedComponents = [];
787
+ if (previousValues.accumulatedComponents) {
788
+ accumulatedComponents = deepClone(
789
+ previousValues.accumulatedComponents,
790
+ );
791
+ }
792
+ let originalTree = dependencyValues.valueOriginal.tree;
793
+ if (Array.isArray(originalTree)) {
794
+ let operator = originalTree[0];
795
+ if (operator === "matrix") {
796
+ let data = originalTree[2];
797
+
798
+ for (let [rowInd, row] of data.slice(1).entries()) {
799
+ let accumRow = accumulatedComponents[rowInd];
800
+ if (!accumRow) {
801
+ accumRow = accumulatedComponents[rowInd] = [];
802
+ }
803
+ for (let [colInd, comp] of row.slice(1).entries()) {
804
+ accumRow[colInd] = comp;
805
+ }
806
+ }
807
+
808
+ return { setValue: { accumulatedComponents } };
809
+ } else if (vectorOperators.includes(operator)) {
810
+ // treat vector/tuple as first column in matrix
811
+
812
+ for (let [rowInd, comp] of originalTree.slice(1).entries()) {
813
+ let accumRow = accumulatedComponents[rowInd];
814
+ if (!accumRow) {
815
+ accumRow = accumulatedComponents[rowInd] = [];
816
+ }
817
+ accumRow[0] = comp;
818
+ }
819
+
820
+ return { setValue: { accumulatedComponents } };
821
+ } else if (
822
+ Array.isArray(originalTree[1]) &&
823
+ vectorOperators.includes(originalTree[1][0]) &&
824
+ ((operator === "^" && originalTree[2] === "T") ||
825
+ operator === "prime")
826
+ ) {
827
+ // treat transpose of vector/tuple as first row in matrix
828
+
829
+ let accumRow = accumulatedComponents[0];
830
+ if (!accumRow) {
831
+ accumRow = accumulatedComponents[0] = [];
832
+ }
833
+ for (let [colInd, comp] of originalTree[1].slice(1).entries()) {
834
+ accumRow[colInd] = comp;
835
+ }
836
+
837
+ return { setValue: { accumulatedComponents } };
838
+ }
839
+ }
840
+
841
+ let accumRow = accumulatedComponents[0];
842
+ if (!accumRow) {
843
+ accumRow = accumulatedComponents[0] = [];
844
+ }
845
+ accumRow[0] = originalTree;
846
+
847
+ return { setValue: { accumulatedComponents } };
848
+ },
849
+ };
850
+
851
+ stateVariableDefinitions.componentValues = {
852
+ isArray: true,
853
+ entryPrefixes: ["componentValue"],
854
+ numDimensions: 2,
855
+ returnArraySizeDependencies: () => ({
856
+ numRows: {
857
+ dependencyType: "stateVariable",
858
+ variableName: "numRows",
859
+ },
860
+ numColumns: {
861
+ dependencyType: "stateVariable",
862
+ variableName: "numColumns",
863
+ },
864
+ }),
865
+ returnArraySize({ dependencyValues }) {
866
+ return [dependencyValues.numRows, dependencyValues.numColumns];
867
+ },
868
+ returnArrayDependenciesByKey() {
869
+ let globalDependencies = {
870
+ valueOriginal: {
871
+ dependencyType: "stateVariable",
872
+ variableName: "valueOriginal",
873
+ },
874
+ numRows: {
875
+ dependencyType: "stateVariable",
876
+ variableName: "numRows",
877
+ },
878
+ numColumns: {
879
+ dependencyType: "stateVariable",
880
+ variableName: "numColumns",
881
+ },
882
+ accumulatedComponents: {
883
+ dependencyType: "stateVariable",
884
+ variableName: "accumulatedComponents",
885
+ },
886
+ defaultEntry: {
887
+ dependencyType: "stateVariable",
888
+ variableName: "defaultEntry",
889
+ },
890
+ };
891
+
892
+ return { globalDependencies };
893
+ },
894
+ arrayDefinitionByKey({ globalDependencyValues, arrayKeys }) {
895
+ let originalTree = globalDependencyValues.valueOriginal.tree;
896
+ let accumulatedComponents =
897
+ globalDependencyValues.accumulatedComponents;
898
+
899
+ let numRows = globalDependencyValues.numRows;
900
+ let numColumns = globalDependencyValues.numColumns;
901
+
902
+ if (Array.isArray(originalTree)) {
903
+ let operator = originalTree[0];
904
+ if (operator === "matrix") {
905
+ if (
906
+ originalTree[1][1] === numRows &&
907
+ originalTree[1][2] === numColumns
908
+ ) {
909
+ let componentValues = {};
910
+ let originalData = originalTree[2];
911
+
912
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
913
+ for (let colInd = 0; colInd < numColumns; colInd++) {
914
+ let arrayKey = `${rowInd},${colInd}`;
915
+ componentValues[arrayKey] = me.fromAst(
916
+ originalData[rowInd + 1][colInd + 1],
917
+ );
918
+ }
919
+ }
920
+
921
+ return { setValue: { componentValues } };
922
+ }
923
+
924
+ let originalNumRows = originalTree[1][1];
925
+ let originalNumColumns = originalTree[1][2];
926
+
927
+ let componentValues = {};
928
+ let originalData = originalTree[2];
929
+
930
+ let numOverlapRows = Math.min(numRows, originalNumRows);
931
+ let numOverlapColumns = Math.min(numColumns, originalNumColumns);
932
+
933
+ // copy original values from overlap between original size and current size
934
+ for (let rowInd = 0; rowInd < numOverlapRows; rowInd++) {
935
+ for (let colInd = 0; colInd < numOverlapColumns; colInd++) {
936
+ let arrayKey = `${rowInd},${colInd}`;
937
+ componentValues[arrayKey] = me.fromAst(
938
+ originalData[rowInd + 1][colInd + 1],
939
+ );
940
+ }
941
+ }
942
+
943
+ if (numColumns > originalNumColumns) {
944
+ // add any extra columns to existing rows
945
+ for (let rowInd = 0; rowInd < numOverlapRows; rowInd++) {
946
+ let accumRow = accumulatedComponents[rowInd];
947
+ for (
948
+ let colInd = originalNumColumns;
949
+ colInd < numColumns;
950
+ colInd++
951
+ ) {
952
+ let accumVal = accumRow[colInd];
953
+ let arrayKey = `${rowInd},${colInd}`;
954
+ componentValues[arrayKey] = me.fromAst(
955
+ accumVal === undefined
956
+ ? globalDependencyValues.defaultEntry.tree
957
+ : accumVal,
958
+ );
959
+ }
960
+ }
961
+ }
962
+
963
+ if (numRows > originalNumRows) {
964
+ // add any extra rows
965
+ for (let rowInd = originalNumRows; rowInd < numRows; rowInd++) {
966
+ let accumRow = accumulatedComponents[rowInd];
967
+ if (!accumRow) {
968
+ accumRow = [];
969
+ }
970
+ for (let colInd = 0; colInd < numColumns; colInd++) {
971
+ let accumVal = accumRow[colInd];
972
+ let arrayKey = `${rowInd},${colInd}`;
973
+ componentValues[arrayKey] = me.fromAst(
974
+ accumVal === undefined
975
+ ? globalDependencyValues.defaultEntry.tree
976
+ : accumVal,
977
+ );
978
+ }
979
+ }
980
+ }
981
+
982
+ return { setValue: { componentValues } };
983
+ } else if (vectorOperators.includes(operator)) {
984
+ // treat vector/tuple as first column in matrix
985
+
986
+ let operands = originalTree.slice(1);
987
+
988
+ let numRowsFound = operands.length;
989
+
990
+ let componentValues = {};
991
+
992
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
993
+ let minCol = 0;
994
+ if (rowInd < numRowsFound) {
995
+ let arrayKey = `${rowInd},${0}`;
996
+ componentValues[arrayKey] = me.fromAst(operands[rowInd]);
997
+ minCol = 1;
998
+ }
999
+
1000
+ let accumRow = accumulatedComponents[rowInd];
1001
+ if (!accumRow) {
1002
+ accumRow = [];
1003
+ }
1004
+
1005
+ for (let colInd = minCol; colInd < numColumns; colInd++) {
1006
+ let accumVal = accumRow[colInd];
1007
+ let arrayKey = `${rowInd},${colInd}`;
1008
+ componentValues[arrayKey] = me.fromAst(
1009
+ accumVal === undefined
1010
+ ? globalDependencyValues.defaultEntry.tree
1011
+ : accumVal,
1012
+ );
1013
+ }
1014
+ }
1015
+
1016
+ return { setValue: { componentValues } };
1017
+ } else if (
1018
+ Array.isArray(originalTree[1]) &&
1019
+ vectorOperators.includes(originalTree[1][0]) &&
1020
+ ((operator === "^" && originalTree[2] === "T") ||
1021
+ operator === "prime")
1022
+ ) {
1023
+ // treat transpose of vector/tuple as first row in matrix
1024
+
1025
+ let operands = originalTree[1].slice(1, numColumns + 1);
1026
+
1027
+ let accumRow = accumulatedComponents[0];
1028
+ if (!accumRow) {
1029
+ accumRow = [];
1030
+ }
1031
+
1032
+ let componentValues = {};
1033
+
1034
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
1035
+ let accumRow = accumulatedComponents[rowInd];
1036
+ if (!accumRow) {
1037
+ accumRow = [];
1038
+ }
1039
+
1040
+ let minCol = 0;
1041
+ if (rowInd === 0) {
1042
+ for (let colInd = 0; colInd < operands.length; colInd++) {
1043
+ let arrayKey = `${0},${colInd}`;
1044
+ componentValues[arrayKey] = me.fromAst(operands[colInd]);
1045
+ }
1046
+ minCol = operands.length;
1047
+ }
1048
+
1049
+ for (let colInd = minCol; colInd < numColumns; colInd++) {
1050
+ let accumVal = accumRow[colInd];
1051
+ let arrayKey = `${rowInd},${colInd}`;
1052
+ componentValues[arrayKey] = me.fromAst(
1053
+ accumVal === undefined
1054
+ ? globalDependencyValues.defaultEntry.tree
1055
+ : accumVal,
1056
+ );
1057
+ }
1058
+ }
1059
+
1060
+ return { setValue: { componentValues } };
1061
+ }
1062
+ }
1063
+
1064
+ // original value is not a matrix or a vector/tuple
1065
+ // use original value for the upper left matrix entry
1066
+
1067
+ let componentValues = {};
1068
+
1069
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
1070
+ let minCol = 0;
1071
+ if (rowInd === 0) {
1072
+ let arrayKey = `${0},${0}`;
1073
+ componentValues[arrayKey] = me.fromAst(originalTree);
1074
+ minCol = 1;
1075
+ }
1076
+
1077
+ let accumRow = accumulatedComponents[rowInd];
1078
+ if (!accumRow) {
1079
+ accumRow = [];
1080
+ }
1081
+
1082
+ for (let colInd = minCol; colInd < numColumns; colInd++) {
1083
+ let accumVal = accumRow[colInd];
1084
+ let arrayKey = `${rowInd},${colInd}`;
1085
+ componentValues[arrayKey] = me.fromAst(
1086
+ accumVal === undefined
1087
+ ? globalDependencyValues.defaultEntry.tree
1088
+ : accumVal,
1089
+ );
1090
+ }
1091
+ }
1092
+
1093
+ return { setValue: { componentValues } };
1094
+ },
1095
+ inverseArrayDefinitionByKey({
1096
+ desiredStateVariableValues,
1097
+ globalDependencyValues,
1098
+ initialChange,
1099
+ workspace,
1100
+ }) {
1101
+ // merge components from desiredStateVariableValues.componentValues
1102
+ // workspace.valueData,
1103
+ // creating it from valueOriginal if not defined yet
1104
+
1105
+ let numRows = globalDependencyValues.numRows;
1106
+ let numColumns = globalDependencyValues.numColumns;
1107
+
1108
+ let originalIsColumnVector = false;
1109
+ let originalIsRowVector = false;
1110
+ let originalIsMatrix = false;
1111
+
1112
+ let originalTree = globalDependencyValues.valueOriginal.tree;
1113
+ if (Array.isArray(originalTree)) {
1114
+ let operator = originalTree[0];
1115
+ if (vectorOperators.includes(operator)) {
1116
+ originalIsColumnVector = true;
1117
+ } else if (operator === "matrix") {
1118
+ originalIsMatrix = true;
1119
+ } else if (
1120
+ Array.isArray(originalTree[1]) &&
1121
+ vectorOperators.includes(originalTree[1][0]) &&
1122
+ ((operator === "^" && originalTree[2] === "T") ||
1123
+ operator === "prime")
1124
+ ) {
1125
+ originalIsRowVector = true;
1126
+ }
1127
+ }
1128
+
1129
+ let valueData;
1130
+
1131
+ if (workspace.valueData) {
1132
+ valueData = workspace.valueData.map((x) => [...x]);
1133
+ } else {
1134
+ let originalTree = globalDependencyValues.valueOriginal.tree;
1135
+
1136
+ if (originalIsColumnVector) {
1137
+ // valueOriginal is a column vector, which we cut down to size
1138
+ // and/or pad with blanks
1139
+
1140
+ valueData = originalTree.slice(1, 1 + numRows).map((x) => [x]);
1141
+ if (valueData.length < numRows) {
1142
+ // pad first column with blanks
1143
+ for (let rowInd = valueData.length; rowInd < numRows; rowInd++) {
1144
+ valueData.push(["\uff3f"]);
1145
+ }
1146
+ }
1147
+ if (numColumns > 1) {
1148
+ // add additional blank columns
1149
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
1150
+ valueData[rowInd].push(...Array(numColumns - 1).fill("\uff3f"));
1151
+ }
1152
+ }
1153
+ } else if (originalIsRowVector) {
1154
+ // valueOriginal is a row vector, which we cut down to size
1155
+ // and/or pad with blanks
1156
+
1157
+ valueData = [originalTree[1].slice(1, 1 + numColumns)];
1158
+
1159
+ if (valueData[0].length < numColumns) {
1160
+ // pad first row with blanks
1161
+ valueData[0].push(
1162
+ ...Array(numColumns - valueData[0].length).fill("\uff3f"),
1163
+ );
1164
+ }
1165
+
1166
+ if (numRows > 1) {
1167
+ for (let rowInd = 1; rowInd < numRows; rowInd++) {
1168
+ valueData.push(Array(numColumns).fill("\uff3f"));
1169
+ }
1170
+ }
1171
+ } else if (originalIsMatrix) {
1172
+ // valueOriginal is a matrix, which we cut down to size
1173
+ // and/or pad with blanks
1174
+ valueData = originalTree[2]
1175
+ .slice(1, numRows + 1)
1176
+ .map((x) => x.slice(1, numColumns + 1));
1177
+
1178
+ if (valueData[0].length < numColumns) {
1179
+ // pad existing rows with blanks
1180
+ for (let rowInd = 0; rowInd < valueData.length; rowInd++) {
1181
+ valueData[rowInd].push(
1182
+ ...Array(numColumns - valueData[rowInd].length).fill(
1183
+ "\uff3f",
1184
+ ),
1185
+ );
1186
+ }
1187
+ }
1188
+
1189
+ if (valueData.length < numRows) {
1190
+ for (let rowInd = valueData.length; rowInd < numRows; rowInd++) {
1191
+ valueData.push(Array(numColumns).fill("\uff3f"));
1192
+ }
1193
+ }
1194
+ } else {
1195
+ // valueOriginal isn't a vector or matrix, so use as upper left entry
1196
+ valueData = [[originalTree]];
1197
+ if (numColumns > 1) {
1198
+ // pad first row with blanks
1199
+ valueData[0].push(...Array(numColumns - 1).fill("\uff3f"));
1200
+ }
1201
+
1202
+ if (numRows > 1) {
1203
+ for (let rowInd = 1; rowInd < numRows; rowInd++) {
1204
+ valueData.push(Array(numColumns).fill("\uff3f"));
1205
+ }
1206
+ }
1207
+ }
1208
+ }
1209
+
1210
+ for (let arrayKey in desiredStateVariableValues.componentValues) {
1211
+ let [rowInd, colInd] = arrayKey.split(",");
1212
+ valueData[rowInd][colInd] = convertValueToMathExpression(
1213
+ desiredStateVariableValues.componentValues[arrayKey],
1214
+ ).tree;
1215
+ }
1216
+
1217
+ workspace.valueData = valueData;
1218
+
1219
+ if (numColumns === 1 && originalIsColumnVector) {
1220
+ let operator = globalDependencyValues.valueOriginal.tree[0];
1221
+ let desiredValue = me.fromAst([
1222
+ operator,
1223
+ ...valueData.map((x) => x[0]),
1224
+ ]);
1225
+ return {
1226
+ success: true,
1227
+ instructions: [
1228
+ {
1229
+ setDependency: "valueOriginal",
1230
+ desiredValue,
1231
+ treatAsInitialChange: initialChange,
1232
+ },
1233
+ ],
1234
+ };
1235
+ } else if (numRows === 1 && originalIsRowVector) {
1236
+ let originalTree = globalDependencyValues.valueOriginal.tree;
1237
+ let operator = originalTree[0];
1238
+
1239
+ let desiredValue = [originalTree[1][0], ...valueData[0]];
1240
+ if (operator === "^") {
1241
+ desiredValue = me.fromAst(["^", desiredValue, "T"]);
1242
+ } else {
1243
+ desiredValue = me.fromAst(["prime", desiredValue]);
1244
+ }
1245
+
1246
+ return {
1247
+ success: true,
1248
+ instructions: [
1249
+ {
1250
+ setDependency: "valueOriginal",
1251
+ desiredValue,
1252
+ treatAsInitialChange: initialChange,
1253
+ },
1254
+ ],
1255
+ };
1256
+ } else {
1257
+ let desiredValueTree = [
1258
+ "matrix",
1259
+ [
1260
+ "tuple",
1261
+ globalDependencyValues.numRows,
1262
+ globalDependencyValues.numColumns,
1263
+ ],
1264
+ ["tuple", ...valueData.map((x) => ["tuple", ...x])],
1265
+ ];
1266
+
1267
+ return {
1268
+ success: true,
1269
+ instructions: [
1270
+ {
1271
+ setDependency: "valueOriginal",
1272
+ desiredValue: me.fromAst(desiredValueTree),
1273
+ treatAsInitialChange: initialChange,
1274
+ },
1275
+ ],
1276
+ };
1277
+ }
1278
+ },
1279
+ };
1280
+
1281
+ stateVariableDefinitions.componentImmediateValues = {
1282
+ isArray: true,
1283
+ entryPrefixes: ["componentImmediateValue"],
1284
+ numDimensions: 2,
1285
+ returnArraySizeDependencies: () => ({
1286
+ numRows: {
1287
+ dependencyType: "stateVariable",
1288
+ variableName: "numRows",
1289
+ },
1290
+ numColumns: {
1291
+ dependencyType: "stateVariable",
1292
+ variableName: "numColumns",
1293
+ },
1294
+ }),
1295
+ returnArraySize({ dependencyValues }) {
1296
+ return [dependencyValues.numRows, dependencyValues.numColumns];
1297
+ },
1298
+ returnArrayDependenciesByKey() {
1299
+ let globalDependencies = {
1300
+ immediateValueOriginal: {
1301
+ dependencyType: "stateVariable",
1302
+ variableName: "immediateValueOriginal",
1303
+ },
1304
+ numRows: {
1305
+ dependencyType: "stateVariable",
1306
+ variableName: "numRows",
1307
+ },
1308
+ numColumns: {
1309
+ dependencyType: "stateVariable",
1310
+ variableName: "numColumns",
1311
+ },
1312
+ accumulatedComponents: {
1313
+ dependencyType: "stateVariable",
1314
+ variableName: "accumulatedComponents",
1315
+ },
1316
+ defaultEntry: {
1317
+ dependencyType: "stateVariable",
1318
+ variableName: "defaultEntry",
1319
+ },
1320
+ };
1321
+
1322
+ return { globalDependencies };
1323
+ },
1324
+ arrayDefinitionByKey({ globalDependencyValues, arrayKeys }) {
1325
+ let originalTree = globalDependencyValues.immediateValueOriginal.tree;
1326
+ let accumulatedComponents =
1327
+ globalDependencyValues.accumulatedComponents;
1328
+
1329
+ let numRows = globalDependencyValues.numRows;
1330
+ let numColumns = globalDependencyValues.numColumns;
1331
+
1332
+ if (Array.isArray(originalTree)) {
1333
+ let operator = originalTree[0];
1334
+ if (operator === "matrix") {
1335
+ if (
1336
+ originalTree[1][1] === numRows &&
1337
+ originalTree[1][2] === numColumns
1338
+ ) {
1339
+ let componentImmediateValues = {};
1340
+ let originalData = originalTree[2];
1341
+
1342
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
1343
+ for (let colInd = 0; colInd < numColumns; colInd++) {
1344
+ let arrayKey = `${rowInd},${colInd}`;
1345
+ componentImmediateValues[arrayKey] = me.fromAst(
1346
+ originalData[rowInd + 1][colInd + 1],
1347
+ );
1348
+ }
1349
+ }
1350
+
1351
+ return { setValue: { componentImmediateValues } };
1352
+ }
1353
+
1354
+ let originalNumRows = originalTree[1][1];
1355
+ let originalNumColumns = originalTree[1][2];
1356
+
1357
+ let componentImmediateValues = {};
1358
+ let originalData = originalTree[2];
1359
+
1360
+ let numOverlapRows = Math.min(numRows, originalNumRows);
1361
+ let numOverlapColumns = Math.min(numColumns, originalNumColumns);
1362
+
1363
+ // copy original values from overlap between original size and current size
1364
+ for (let rowInd = 0; rowInd < numOverlapRows; rowInd++) {
1365
+ for (let colInd = 0; colInd < numOverlapColumns; colInd++) {
1366
+ let arrayKey = `${rowInd},${colInd}`;
1367
+ componentImmediateValues[arrayKey] = me.fromAst(
1368
+ originalData[rowInd + 1][colInd + 1],
1369
+ );
1370
+ }
1371
+ }
1372
+
1373
+ if (numColumns > originalNumColumns) {
1374
+ // add any extra columns to existing rows
1375
+ for (let rowInd = 0; rowInd < numOverlapRows; rowInd++) {
1376
+ let accumRow = accumulatedComponents[rowInd];
1377
+ for (
1378
+ let colInd = originalNumColumns;
1379
+ colInd < numColumns;
1380
+ colInd++
1381
+ ) {
1382
+ let accumVal = accumRow[colInd];
1383
+ let arrayKey = `${rowInd},${colInd}`;
1384
+ componentImmediateValues[arrayKey] = me.fromAst(
1385
+ accumVal === undefined
1386
+ ? globalDependencyValues.defaultEntry.tree
1387
+ : accumVal,
1388
+ );
1389
+ }
1390
+ }
1391
+ }
1392
+
1393
+ if (numRows > originalNumRows) {
1394
+ // add any extra rows
1395
+ for (let rowInd = originalNumRows; rowInd < numRows; rowInd++) {
1396
+ let accumRow = accumulatedComponents[rowInd];
1397
+ if (!accumRow) {
1398
+ accumRow = [];
1399
+ }
1400
+ for (let colInd = 0; colInd < numColumns; colInd++) {
1401
+ let accumVal = accumRow[colInd];
1402
+ let arrayKey = `${rowInd},${colInd}`;
1403
+ componentImmediateValues[arrayKey] = me.fromAst(
1404
+ accumVal === undefined
1405
+ ? globalDependencyValues.defaultEntry.tree
1406
+ : accumVal,
1407
+ );
1408
+ }
1409
+ }
1410
+ }
1411
+
1412
+ return { setValue: { componentImmediateValues } };
1413
+ } else if (vectorOperators.includes(operator)) {
1414
+ // treat vector/tuple as first column in matrix
1415
+
1416
+ let operands = originalTree.slice(1);
1417
+
1418
+ let numRowsFound = operands.length;
1419
+
1420
+ let componentImmediateValues = {};
1421
+
1422
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
1423
+ let minCol = 0;
1424
+ if (rowInd < numRowsFound) {
1425
+ let arrayKey = `${rowInd},${0}`;
1426
+ componentImmediateValues[arrayKey] = me.fromAst(
1427
+ operands[rowInd],
1428
+ );
1429
+ minCol = 1;
1430
+ }
1431
+
1432
+ let accumRow = accumulatedComponents[rowInd];
1433
+ if (!accumRow) {
1434
+ accumRow = [];
1435
+ }
1436
+
1437
+ for (let colInd = minCol; colInd < numColumns; colInd++) {
1438
+ let accumVal = accumRow[colInd];
1439
+ let arrayKey = `${rowInd},${colInd}`;
1440
+ componentImmediateValues[arrayKey] = me.fromAst(
1441
+ accumVal === undefined
1442
+ ? globalDependencyValues.defaultEntry.tree
1443
+ : accumVal,
1444
+ );
1445
+ }
1446
+ }
1447
+
1448
+ return { setValue: { componentImmediateValues } };
1449
+ } else if (
1450
+ Array.isArray(originalTree[1]) &&
1451
+ vectorOperators.includes(originalTree[1][0]) &&
1452
+ ((operator === "^" && originalTree[2] === "T") ||
1453
+ operator === "prime")
1454
+ ) {
1455
+ // treat transpose of vector/tuple as first row in matrix
1456
+
1457
+ let operands = originalTree[1].slice(1, numColumns + 1);
1458
+
1459
+ let accumRow = accumulatedComponents[0];
1460
+ if (!accumRow) {
1461
+ accumRow = [];
1462
+ }
1463
+
1464
+ let componentImmediateValues = {};
1465
+
1466
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
1467
+ let accumRow = accumulatedComponents[rowInd];
1468
+ if (!accumRow) {
1469
+ accumRow = [];
1470
+ }
1471
+
1472
+ let minCol = 0;
1473
+ if (rowInd === 0) {
1474
+ for (let colInd = 0; colInd < operands.length; colInd++) {
1475
+ let arrayKey = `${0},${colInd}`;
1476
+ componentImmediateValues[arrayKey] = me.fromAst(
1477
+ operands[colInd],
1478
+ );
1479
+ }
1480
+ minCol = operands.length;
1481
+ }
1482
+
1483
+ for (let colInd = minCol; colInd < numColumns; colInd++) {
1484
+ let accumVal = accumRow[colInd];
1485
+ let arrayKey = `${rowInd},${colInd}`;
1486
+ componentImmediateValues[arrayKey] = me.fromAst(
1487
+ accumVal === undefined
1488
+ ? globalDependencyValues.defaultEntry.tree
1489
+ : accumVal,
1490
+ );
1491
+ }
1492
+ }
1493
+
1494
+ return { setValue: { componentImmediateValues } };
1495
+ }
1496
+ }
1497
+
1498
+ // original value is not a matrix or a vector/tuple
1499
+ // use original value for the upper left matrix entry
1500
+
1501
+ let componentImmediateValues = {};
1502
+
1503
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
1504
+ let minCol = 0;
1505
+ if (rowInd === 0) {
1506
+ let arrayKey = `${0},${0}`;
1507
+ componentImmediateValues[arrayKey] = me.fromAst(originalTree);
1508
+ minCol = 1;
1509
+ }
1510
+
1511
+ let accumRow = accumulatedComponents[rowInd];
1512
+ if (!accumRow) {
1513
+ accumRow = [];
1514
+ }
1515
+
1516
+ for (let colInd = minCol; colInd < numColumns; colInd++) {
1517
+ let accumVal = accumRow[colInd];
1518
+ let arrayKey = `${rowInd},${colInd}`;
1519
+ componentImmediateValues[arrayKey] = me.fromAst(
1520
+ accumVal === undefined
1521
+ ? globalDependencyValues.defaultEntry.tree
1522
+ : accumVal,
1523
+ );
1524
+ }
1525
+ }
1526
+
1527
+ return { setValue: { componentImmediateValues } };
1528
+ },
1529
+ inverseArrayDefinitionByKey({
1530
+ desiredStateVariableValues,
1531
+ globalDependencyValues,
1532
+ initialChange,
1533
+ workspace,
1534
+ }) {
1535
+ // merge components from desiredStateVariableValues.componentImmediateValues
1536
+ // workspace.immediateValueData,
1537
+ // creating it from immediateValueOriginal if not defined yet
1538
+
1539
+ let numRows = globalDependencyValues.numRows;
1540
+ let numColumns = globalDependencyValues.numColumns;
1541
+
1542
+ let originalIsColumnVector = false;
1543
+ let originalIsRowVector = false;
1544
+ let originalIsMatrix = false;
1545
+
1546
+ let originalTree = globalDependencyValues.immediateValueOriginal.tree;
1547
+ if (Array.isArray(originalTree)) {
1548
+ let operator = originalTree[0];
1549
+ if (vectorOperators.includes(operator)) {
1550
+ originalIsColumnVector = true;
1551
+ } else if (operator === "matrix") {
1552
+ originalIsMatrix = true;
1553
+ } else if (
1554
+ Array.isArray(originalTree[1]) &&
1555
+ vectorOperators.includes(originalTree[1][0]) &&
1556
+ ((operator === "^" && originalTree[2] === "T") ||
1557
+ operator === "prime")
1558
+ ) {
1559
+ originalIsRowVector = true;
1560
+ }
1561
+ }
1562
+
1563
+ let immediateValueData;
1564
+
1565
+ if (workspace.immediateValueData) {
1566
+ immediateValueData = workspace.immediateValueData.map((x) => [...x]);
1567
+ } else {
1568
+ let originalTree = globalDependencyValues.immediateValueOriginal.tree;
1569
+
1570
+ if (originalIsColumnVector) {
1571
+ // immediateValueOriginal is a column vector, which we cut down to size
1572
+ // and/or pad with blanks
1573
+
1574
+ immediateValueData = originalTree
1575
+ .slice(1, 1 + numRows)
1576
+ .map((x) => [x]);
1577
+ if (immediateValueData.length < numRows) {
1578
+ // pad first column with blanks
1579
+ for (
1580
+ let rowInd = immediateValueData.length;
1581
+ rowInd < numRows;
1582
+ rowInd++
1583
+ ) {
1584
+ immediateValueData.push(["\uff3f"]);
1585
+ }
1586
+ }
1587
+ if (numColumns > 1) {
1588
+ // add additional blank columns
1589
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
1590
+ immediateValueData[rowInd].push(
1591
+ ...Array(numColumns - 1).fill("\uff3f"),
1592
+ );
1593
+ }
1594
+ }
1595
+ } else if (originalIsRowVector) {
1596
+ // immediateValueOriginal is a row vector, which we cut down to size
1597
+ // and/or pad with blanks
1598
+
1599
+ immediateValueData = [originalTree[1].slice(1, 1 + numColumns)];
1600
+
1601
+ if (immediateValueData[0].length < numColumns) {
1602
+ // pad first row with blanks
1603
+ immediateValueData[0].push(
1604
+ ...Array(numColumns - immediateValueData[0].length).fill(
1605
+ "\uff3f",
1606
+ ),
1607
+ );
1608
+ }
1609
+
1610
+ if (numRows > 1) {
1611
+ for (let rowInd = 1; rowInd < numRows; rowInd++) {
1612
+ immediateValueData.push(Array(numColumns).fill("\uff3f"));
1613
+ }
1614
+ }
1615
+ } else if (originalIsMatrix) {
1616
+ // immediateValueOriginal is a matrix, which we cut down to size
1617
+ // and/or pad with blanks
1618
+ immediateValueData = originalTree[2]
1619
+ .slice(1, numRows + 1)
1620
+ .map((x) => x.slice(1, numColumns + 1));
1621
+
1622
+ if (immediateValueData[0].length < numColumns) {
1623
+ // pad existing rows with blanks
1624
+ for (
1625
+ let rowInd = 0;
1626
+ rowInd < immediateValueData.length;
1627
+ rowInd++
1628
+ ) {
1629
+ immediateValueData[rowInd].push(
1630
+ ...Array(numColumns - immediateValueData[rowInd].length).fill(
1631
+ "\uff3f",
1632
+ ),
1633
+ );
1634
+ }
1635
+ }
1636
+
1637
+ if (immediateValueData.length < numRows) {
1638
+ for (
1639
+ let rowInd = immediateValueData.length;
1640
+ rowInd < numRows;
1641
+ rowInd++
1642
+ ) {
1643
+ immediateValueData.push(Array(numColumns).fill("\uff3f"));
1644
+ }
1645
+ }
1646
+ } else {
1647
+ // immediateValueOriginal isn't a vector or matrix, so use as upper left entry
1648
+ immediateValueData = [[originalTree]];
1649
+ if (numColumns > 1) {
1650
+ // pad first row with blanks
1651
+ immediateValueData[0].push(
1652
+ ...Array(numColumns - 1).fill("\uff3f"),
1653
+ );
1654
+ }
1655
+
1656
+ if (numRows > 1) {
1657
+ for (let rowInd = 1; rowInd < numRows; rowInd++) {
1658
+ immediateValueData.push(Array(numColumns).fill("\uff3f"));
1659
+ }
1660
+ }
1661
+ }
1662
+ }
1663
+
1664
+ for (let arrayKey in desiredStateVariableValues.componentImmediateValues) {
1665
+ let [rowInd, colInd] = arrayKey.split(",");
1666
+ immediateValueData[rowInd][colInd] = convertValueToMathExpression(
1667
+ desiredStateVariableValues.componentImmediateValues[arrayKey],
1668
+ ).tree;
1669
+ }
1670
+
1671
+ workspace.immediateValueData = immediateValueData;
1672
+
1673
+ if (numColumns === 1 && originalIsColumnVector) {
1674
+ let operator = globalDependencyValues.immediateValueOriginal.tree[0];
1675
+ let desiredValue = me.fromAst([
1676
+ operator,
1677
+ ...immediateValueData.map((x) => x[0]),
1678
+ ]);
1679
+ return {
1680
+ success: true,
1681
+ instructions: [
1682
+ {
1683
+ setDependency: "immediateValueOriginal",
1684
+ desiredValue,
1685
+ treatAsInitialChange: initialChange,
1686
+ },
1687
+ ],
1688
+ };
1689
+ } else if (numRows === 1 && originalIsRowVector) {
1690
+ let originalTree = globalDependencyValues.immediateValueOriginal.tree;
1691
+ let operator = originalTree[0];
1692
+
1693
+ let desiredValue = [originalTree[1][0], ...immediateValueData[0]];
1694
+ if (operator === "^") {
1695
+ desiredValue = me.fromAst(["^", desiredValue, "T"]);
1696
+ } else {
1697
+ desiredValue = me.fromAst(["prime", desiredValue]);
1698
+ }
1699
+
1700
+ return {
1701
+ success: true,
1702
+ instructions: [
1703
+ {
1704
+ setDependency: "immediateValueOriginal",
1705
+ desiredValue,
1706
+ treatAsInitialChange: initialChange,
1707
+ },
1708
+ ],
1709
+ };
1710
+ } else {
1711
+ let desiredValueTree = [
1712
+ "matrix",
1713
+ [
1714
+ "tuple",
1715
+ globalDependencyValues.numRows,
1716
+ globalDependencyValues.numColumns,
1717
+ ],
1718
+ ["tuple", ...immediateValueData.map((x) => ["tuple", ...x])],
1719
+ ];
1720
+
1721
+ return {
1722
+ success: true,
1723
+ instructions: [
1724
+ {
1725
+ setDependency: "immediateValueOriginal",
1726
+ desiredValue: me.fromAst(desiredValueTree),
1727
+ treatAsInitialChange: initialChange,
1728
+ },
1729
+ ],
1730
+ };
1731
+ }
1732
+ },
1733
+ };
1734
+
1735
+ stateVariableDefinitions.componentValuesForDisplay = {
1736
+ isArray: true,
1737
+ entryPrefixes: ["componentValueForDisplay"],
1738
+ numDimensions: 2,
1739
+ forRenderer: true,
1740
+ returnArraySizeDependencies: () => ({
1741
+ numRows: {
1742
+ dependencyType: "stateVariable",
1743
+ variableName: "numRows",
1744
+ },
1745
+ numColumns: {
1746
+ dependencyType: "stateVariable",
1747
+ variableName: "numColumns",
1748
+ },
1749
+ }),
1750
+ returnArraySize({ dependencyValues }) {
1751
+ return [dependencyValues.numRows, dependencyValues.numColumns];
1752
+ },
1753
+ returnArrayDependenciesByKey({ arrayKeys }) {
1754
+ let globalDependencies = {
1755
+ displayDigits: {
1756
+ dependencyType: "stateVariable",
1757
+ variableName: "displayDigits",
1758
+ },
1759
+ displayDecimals: {
1760
+ dependencyType: "stateVariable",
1761
+ variableName: "displayDecimals",
1762
+ },
1763
+ displaySmallAsZero: {
1764
+ dependencyType: "stateVariable",
1765
+ variableName: "displaySmallAsZero",
1766
+ },
1767
+ };
1768
+
1769
+ let dependenciesByKey = {};
1770
+ for (let arrayKey of arrayKeys) {
1771
+ let [rowInd, colInd] = arrayKey.split(",");
1772
+ let varEnding = Number(rowInd) + 1 + "_" + (Number(colInd) + 1);
1773
+
1774
+ dependenciesByKey[arrayKey] = {
1775
+ componentValue: {
1776
+ dependencyType: "stateVariable",
1777
+ variableName: `componentValue${varEnding}`,
1778
+ },
1779
+ };
1780
+ }
1781
+
1782
+ return { globalDependencies, dependenciesByKey };
1783
+ },
1784
+ arrayDefinitionByKey({
1785
+ globalDependencyValues,
1786
+ dependencyValuesByKey,
1787
+ arrayKeys,
1788
+ }) {
1789
+ let componentValuesForDisplay = {};
1790
+
1791
+ for (let arrayKey of arrayKeys) {
1792
+ // round any decimal numbers to the significant digits
1793
+ // determined by displaydigits or displaydecimals
1794
+ let rounded = roundForDisplay({
1795
+ value: dependencyValuesByKey[arrayKey].componentValue,
1796
+ dependencyValues: globalDependencyValues,
1797
+ });
1798
+
1799
+ componentValuesForDisplay[arrayKey] = rounded;
1800
+ }
1801
+
1802
+ return { setValue: { componentValuesForDisplay } };
1803
+ },
1804
+ };
1805
+
1806
+ stateVariableDefinitions.value = {
1807
+ public: true,
1808
+ shadowingInstructions: {
1809
+ createComponentOfType: "math",
1810
+ addAttributeComponentsShadowingStateVariables:
1811
+ returnRoundingAttributeComponentShadowing(),
1812
+ },
1813
+ returnDependencies: () => ({
1814
+ componentValues: {
1815
+ dependencyType: "stateVariable",
1816
+ variableName: "componentValues",
1817
+ },
1818
+ numRows: {
1819
+ dependencyType: "stateVariable",
1820
+ variableName: "numRows",
1821
+ },
1822
+ numColumns: {
1823
+ dependencyType: "stateVariable",
1824
+ variableName: "numColumns",
1825
+ },
1826
+ // value original is just for inverse definition
1827
+ valueOriginal: {
1828
+ dependencyType: "stateVariable",
1829
+ variableName: "valueOriginal",
1830
+ },
1831
+ }),
1832
+ definition({ dependencyValues }) {
1833
+ let numRows = dependencyValues.numRows;
1834
+ let numColumns = dependencyValues.numColumns;
1835
+
1836
+ let newTree = ["matrix", ["tuple", numRows, numColumns]];
1837
+
1838
+ let data = (newTree[2] = ["tuple"]);
1839
+
1840
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
1841
+ data[rowInd + 1] = ["tuple"];
1842
+
1843
+ for (let colInd = 0; colInd < numColumns; colInd++) {
1844
+ data[rowInd + 1][colInd + 1] =
1845
+ dependencyValues.componentValues[rowInd][colInd].tree;
1846
+ }
1847
+ }
1848
+
1849
+ return { setValue: { value: me.fromAst(newTree) } };
1850
+ },
1851
+ inverseDefinition({ desiredStateVariableValues, dependencyValues }) {
1852
+ let desiredTree = desiredStateVariableValues.value.tree;
1853
+ if (Array.isArray(desiredTree) && desiredTree[0] === "matrix") {
1854
+ if (
1855
+ desiredTree[1][1] === dependencyValues.numRows &&
1856
+ desiredTree[1][2] === dependencyValues.numColumns
1857
+ ) {
1858
+ if (dependencyValues.numColumns === 1) {
1859
+ let originalTree = dependencyValues.valueOriginal.tree;
1860
+ if (Array.isArray(originalTree)) {
1861
+ let operator = originalTree[0];
1862
+ if (vectorOperators.includes(operator)) {
1863
+ // if original value was a vector, then keep it as a vector
1864
+ let desiredValue = me.fromAst([
1865
+ operator,
1866
+ ...desiredTree[2].slice(1).map((x) => x[1]),
1867
+ ]);
1868
+ return {
1869
+ success: true,
1870
+ instructions: [
1871
+ {
1872
+ setDependency: "valueOriginal",
1873
+ desiredValue,
1874
+ },
1875
+ ],
1876
+ };
1877
+ }
1878
+ }
1879
+ } else if (dependencyValues.numRows === 1) {
1880
+ let originalTree = dependencyValues.valueOriginal.tree;
1881
+ if (Array.isArray(originalTree)) {
1882
+ let operator = originalTree[0];
1883
+
1884
+ if (
1885
+ Array.isArray(originalTree[1]) &&
1886
+ vectorOperators.includes(originalTree[1][0]) &&
1887
+ ((operator === "^" && originalTree[2] === "T") ||
1888
+ operator === "prime")
1889
+ ) {
1890
+ // if original value was the transpose of a vector,
1891
+ // then keep it as the transpose of a vector
1892
+ let desiredValue = [
1893
+ originalTree[1][0],
1894
+ ...desiredTree[2][1].slice(1),
1895
+ ];
1896
+ if (operator === "^") {
1897
+ desiredValue = me.fromAst(["^", desiredValue, "T"]);
1898
+ } else {
1899
+ desiredValue = me.fromAst(["prime", desiredValue]);
1900
+ }
1901
+ return {
1902
+ success: true,
1903
+ instructions: [
1904
+ {
1905
+ setDependency: "valueOriginal",
1906
+ desiredValue,
1907
+ },
1908
+ ],
1909
+ };
1910
+ }
1911
+ }
1912
+ }
1913
+ }
1914
+
1915
+ return {
1916
+ success: true,
1917
+ instructions: [
1918
+ {
1919
+ setDependency: "valueOriginal",
1920
+ desiredValue: desiredStateVariableValues.value,
1921
+ },
1922
+ ],
1923
+ };
1924
+ } else {
1925
+ return { success: false };
1926
+ }
1927
+ },
1928
+ };
1929
+
1930
+ stateVariableDefinitions.immediateValue = {
1931
+ public: true,
1932
+ shadowingInstructions: {
1933
+ createComponentOfType: "math",
1934
+ addAttributeComponentsShadowingStateVariables:
1935
+ returnRoundingAttributeComponentShadowing(),
1936
+ },
1937
+ returnDependencies: () => ({
1938
+ componentImmediateValues: {
1939
+ dependencyType: "stateVariable",
1940
+ variableName: "componentImmediateValues",
1941
+ },
1942
+ numRows: {
1943
+ dependencyType: "stateVariable",
1944
+ variableName: "numRows",
1945
+ },
1946
+ numColumns: {
1947
+ dependencyType: "stateVariable",
1948
+ variableName: "numColumns",
1949
+ },
1950
+ // immediateValue original is just for inverse definition
1951
+ immediateValueOriginal: {
1952
+ dependencyType: "stateVariable",
1953
+ variableName: "immediateValueOriginal",
1954
+ },
1955
+ }),
1956
+ definition({ dependencyValues }) {
1957
+ let numRows = dependencyValues.numRows;
1958
+ let numColumns = dependencyValues.numColumns;
1959
+
1960
+ let newTree = ["matrix", ["tuple", numRows, numColumns]];
1961
+
1962
+ let data = (newTree[2] = ["tuple"]);
1963
+
1964
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
1965
+ data[rowInd + 1] = ["tuple"];
1966
+
1967
+ for (let colInd = 0; colInd < numColumns; colInd++) {
1968
+ data[rowInd + 1][colInd + 1] =
1969
+ dependencyValues.componentImmediateValues[rowInd][colInd].tree;
1970
+ }
1971
+ }
1972
+
1973
+ return { setValue: { immediateValue: me.fromAst(newTree) } };
1974
+ },
1975
+ inverseDefinition({ desiredStateVariableValues, dependencyValues }) {
1976
+ let desiredTree = desiredStateVariableValues.immediateValue.tree;
1977
+ if (Array.isArray(desiredTree) && desiredTree[0] === "matrix") {
1978
+ if (
1979
+ desiredTree[1][1] === dependencyValues.numRows &&
1980
+ desiredTree[1][2] === dependencyValues.numColumns
1981
+ ) {
1982
+ if (dependencyValues.numColumns === 1) {
1983
+ let originalTree = dependencyValues.immediateValueOriginal.tree;
1984
+ if (Array.isArray(originalTree)) {
1985
+ let operator = originalTree[0];
1986
+ if (vectorOperators.includes(operator)) {
1987
+ // if original immediateValue was a vector, then keep it as a vector
1988
+ let desiredValue = me.fromAst([
1989
+ operator,
1990
+ ...desiredTree[2].slice(1).map((x) => x[1]),
1991
+ ]);
1992
+ return {
1993
+ success: true,
1994
+ instructions: [
1995
+ {
1996
+ setDependency: "immediateValueOriginal",
1997
+ desiredValue,
1998
+ },
1999
+ ],
2000
+ };
2001
+ }
2002
+ }
2003
+ } else if (dependencyValues.numRows === 1) {
2004
+ let originalTree = dependencyValues.immediateValueOriginal.tree;
2005
+ if (Array.isArray(originalTree)) {
2006
+ let operator = originalTree[0];
2007
+
2008
+ if (
2009
+ Array.isArray(originalTree[1]) &&
2010
+ vectorOperators.includes(originalTree[1][0]) &&
2011
+ ((operator === "^" && originalTree[2] === "T") ||
2012
+ operator === "prime")
2013
+ ) {
2014
+ // if original immediateValue was the transpose of a vector,
2015
+ // then keep it as the transpose of a vector
2016
+ let desiredValue = [
2017
+ originalTree[1][0],
2018
+ ...desiredTree[2][1].slice(1),
2019
+ ];
2020
+ if (operator === "^") {
2021
+ desiredValue = me.fromAst(["^", desiredValue, "T"]);
2022
+ } else {
2023
+ desiredValue = me.fromAst(["prime", desiredValue]);
2024
+ }
2025
+ return {
2026
+ success: true,
2027
+ instructions: [
2028
+ {
2029
+ setDependency: "immediateValueOriginal",
2030
+ desiredValue,
2031
+ },
2032
+ ],
2033
+ };
2034
+ }
2035
+ }
2036
+ }
2037
+ }
2038
+
2039
+ return {
2040
+ success: true,
2041
+ instructions: [
2042
+ {
2043
+ setDependency: "immediateValueOriginal",
2044
+ desiredValue: desiredStateVariableValues.immediateValue,
2045
+ },
2046
+ ],
2047
+ };
2048
+ } else {
2049
+ return { success: false };
2050
+ }
2051
+ },
2052
+ };
2053
+
2054
+ stateVariableDefinitions.valueForDisplay = {
2055
+ forRenderer: true,
2056
+ returnDependencies: () => ({
2057
+ value: {
2058
+ dependencyType: "stateVariable",
2059
+ variableName: "value",
2060
+ },
2061
+ displayDigits: {
2062
+ dependencyType: "stateVariable",
2063
+ variableName: "displayDigits",
2064
+ },
2065
+ displayDecimals: {
2066
+ dependencyType: "stateVariable",
2067
+ variableName: "displayDecimals",
2068
+ },
2069
+ displaySmallAsZero: {
2070
+ dependencyType: "stateVariable",
2071
+ variableName: "displaySmallAsZero",
2072
+ },
2073
+ }),
2074
+ definition: function ({ dependencyValues }) {
2075
+ // round any decimal numbers to the significant digits
2076
+ // determined by displaydigits or displaydecimals
2077
+ let rounded = roundForDisplay({
2078
+ value: dependencyValues.value,
2079
+ dependencyValues,
2080
+ });
2081
+
2082
+ return {
2083
+ setValue: { valueForDisplay: rounded },
2084
+ };
2085
+ },
2086
+ };
2087
+
2088
+ stateVariableDefinitions.componentType = {
2089
+ returnDependencies: () => ({}),
2090
+ definition: () => ({ setValue: { componentType: "matrix" } }),
2091
+ };
2092
+
2093
+ stateVariableDefinitions.childIndicesToRender = {
2094
+ returnDependencies: () => ({
2095
+ numRows: {
2096
+ dependencyType: "stateVariable",
2097
+ variableName: "numRows",
2098
+ },
2099
+ numColumns: {
2100
+ dependencyType: "stateVariable",
2101
+ variableName: "numColumns",
2102
+ },
2103
+ }),
2104
+ definition({ dependencyValues }) {
2105
+ let nChildrenToRender =
2106
+ dependencyValues.numRows * dependencyValues.numColumns;
2107
+
2108
+ return {
2109
+ setValue: {
2110
+ childIndicesToRender: [...Array(nChildrenToRender).keys()],
2111
+ },
2112
+ };
2113
+ },
2114
+ };
2115
+
2116
+ return stateVariableDefinitions;
2117
+ }
2118
+
2119
+ async updateNumRows({
2120
+ numRows,
2121
+ actionId,
2122
+ sourceInformation = {},
2123
+ skipRendererUpdate = false,
2124
+ }) {
2125
+ if (!(await this.stateValues.disabled)) {
2126
+ return await this.coreFunctions.performUpdate({
2127
+ updateInstructions: [
2128
+ {
2129
+ updateType: "updateValue",
2130
+ componentName: this.componentName,
2131
+ stateVariable: "numRows",
2132
+ value: numRows,
2133
+ },
2134
+ ],
2135
+ actionId,
2136
+ sourceInformation,
2137
+ skipRendererUpdate,
2138
+ });
2139
+ } else {
2140
+ this.coreFunctions.resolveAction({ actionId });
2141
+ }
2142
+ }
2143
+
2144
+ async updateNumColumns({
2145
+ numColumns,
2146
+ actionId,
2147
+ sourceInformation = {},
2148
+ skipRendererUpdate = false,
2149
+ }) {
2150
+ if (!(await this.stateValues.disabled)) {
2151
+ return await this.coreFunctions.performUpdate({
2152
+ updateInstructions: [
2153
+ {
2154
+ updateType: "updateValue",
2155
+ componentName: this.componentName,
2156
+ stateVariable: "numColumns",
2157
+ value: numColumns,
2158
+ },
2159
+ ],
2160
+ actionId,
2161
+ sourceInformation,
2162
+ skipRendererUpdate,
2163
+ });
2164
+ } else {
2165
+ this.coreFunctions.resolveAction({ actionId });
2166
+ }
2167
+ }
2168
+
2169
+ static adapters = [
2170
+ {
2171
+ stateVariable: "value",
2172
+ stateVariablesToShadow: Object.keys(
2173
+ returnRoundingStateVariableDefinitions(),
2174
+ ),
2175
+ },
2176
+ ];
2177
+ }
2178
+
2179
+ export class MatrixInputGrid extends CompositeComponent {
2180
+ static componentType = "_matrixInputGrid";
2181
+
2182
+ static stateVariableToEvaluateAfterReplacements = "readyToExpandWhenResolved";
2183
+
2184
+ static returnStateVariableDefinitions() {
2185
+ let stateVariableDefinitions = super.returnStateVariableDefinitions();
2186
+
2187
+ stateVariableDefinitions.numRows = {
2188
+ returnDependencies: () => ({
2189
+ parentNumRows: {
2190
+ dependencyType: "parentStateVariable",
2191
+ parentComponentType: "matrixInput",
2192
+ variableName: "numRows",
2193
+ },
2194
+ }),
2195
+ definition({ dependencyValues }) {
2196
+ return {
2197
+ setValue: { numRows: dependencyValues.parentNumRows },
2198
+ };
2199
+ },
2200
+ };
2201
+
2202
+ stateVariableDefinitions.numColumns = {
2203
+ returnDependencies: () => ({
2204
+ parentNumColumns: {
2205
+ dependencyType: "parentStateVariable",
2206
+ parentComponentType: "matrixInput",
2207
+ variableName: "numColumns",
2208
+ },
2209
+ }),
2210
+ definition({ dependencyValues }) {
2211
+ return {
2212
+ setValue: { numColumns: dependencyValues.parentNumColumns },
2213
+ };
2214
+ },
2215
+ };
2216
+
2217
+ stateVariableDefinitions.readyToExpandWhenResolved = {
2218
+ returnDependencies: () => ({
2219
+ numRows: {
2220
+ dependencyType: "stateVariable",
2221
+ variableName: "numRows",
2222
+ },
2223
+ numColumns: {
2224
+ dependencyType: "stateVariable",
2225
+ variableName: "numColumns",
2226
+ },
2227
+ }),
2228
+ markStale() {
2229
+ return { updateReplacements: true };
2230
+ },
2231
+ definition() {
2232
+ return { setValue: { readyToExpandWhenResolved: true } };
2233
+ },
2234
+ };
2235
+
2236
+ return stateVariableDefinitions;
2237
+ }
2238
+
2239
+ static async createSerializedReplacements({
2240
+ component,
2241
+ componentInfoObjects,
2242
+ flags,
2243
+ workspace,
2244
+ }) {
2245
+ let serializedComponents = [];
2246
+
2247
+ let numRows = await component.stateValues.numRows;
2248
+
2249
+ workspace.previousNumRows = numRows;
2250
+
2251
+ for (let rowInd = 0; rowInd < numRows; rowInd++) {
2252
+ serializedComponents.push({
2253
+ componentType: "_matrixInputRow",
2254
+ state: { rowInd },
2255
+ uniqueIdentifier: rowInd,
2256
+ });
2257
+ }
2258
+
2259
+ return { replacements: serializedComponents };
2260
+ }
2261
+
2262
+ static async calculateReplacementChanges({
2263
+ component,
2264
+ componentChanges,
2265
+ componentInfoObjects,
2266
+ flags,
2267
+ workspace,
2268
+ }) {
2269
+ let replacementChanges = [];
2270
+
2271
+ let previousNumRows = workspace.previousNumRows;
2272
+ let numRows = await component.stateValues.numRows;
2273
+
2274
+ let newReplacementsToWithhold;
2275
+
2276
+ let numReplacementsToAdd = 0;
2277
+
2278
+ // if have fewer replacements than before
2279
+ // mark old replacements as hidden
2280
+ if (numRows < previousNumRows) {
2281
+ newReplacementsToWithhold = component.replacements.length - numRows;
2282
+
2283
+ let replacementInstruction = {
2284
+ changeType: "changeReplacementsToWithhold",
2285
+ replacementsToWithhold: newReplacementsToWithhold,
2286
+ };
2287
+ replacementChanges.push(replacementInstruction);
2288
+ } else if (numRows > previousNumRows) {
2289
+ numReplacementsToAdd = numRows - previousNumRows;
2290
+
2291
+ if (component.replacementsToWithhold > 0) {
2292
+ if (component.replacementsToWithhold >= numReplacementsToAdd) {
2293
+ newReplacementsToWithhold =
2294
+ component.replacementsToWithhold - numReplacementsToAdd;
2295
+ previousNumRows += numReplacementsToAdd;
2296
+ numReplacementsToAdd = 0;
2297
+
2298
+ let replacementInstruction = {
2299
+ changeType: "changeReplacementsToWithhold",
2300
+ replacementsToWithhold: newReplacementsToWithhold,
2301
+ };
2302
+ replacementChanges.push(replacementInstruction);
2303
+ } else {
2304
+ numReplacementsToAdd -= component.replacementsToWithhold;
2305
+ previousNumRows += component.replacementsToWithhold;
2306
+ newReplacementsToWithhold = 0;
2307
+ // don't need to send changedReplacementsToWithold instructions
2308
+ // since will send add instructions,
2309
+ // which will also recalculate replacements in parent
2310
+ }
2311
+ }
2312
+ }
2313
+
2314
+ if (numReplacementsToAdd > 0) {
2315
+ // Need to add more replacement components
2316
+
2317
+ let newSerializedReplacements = [];
2318
+
2319
+ for (let rowInd = previousNumRows; rowInd < numRows; rowInd++) {
2320
+ newSerializedReplacements.push({
2321
+ componentType: "_matrixInputRow",
2322
+ state: { rowInd },
2323
+ uniqueIdentifier: rowInd,
2324
+ });
2325
+ }
2326
+
2327
+ let replacementInstruction = {
2328
+ changeType: "add",
2329
+ changeTopLevelReplacements: true,
2330
+ firstReplacementInd: previousNumRows,
2331
+ serializedReplacements: newSerializedReplacements,
2332
+ replacementsToWithhold: 0,
2333
+ assignNamesOffset: previousNumRows,
2334
+ };
2335
+ replacementChanges.push(replacementInstruction);
2336
+ }
2337
+
2338
+ workspace.previousNumRows = numRows;
2339
+
2340
+ return replacementChanges;
2341
+ }
2342
+ }
2343
+
2344
+ export class MatrixInputRow extends CompositeComponent {
2345
+ static componentType = "_matrixInputRow";
2346
+
2347
+ static stateVariableToEvaluateAfterReplacements = "readyToExpandWhenResolved";
2348
+
2349
+ static returnStateVariableDefinitions() {
2350
+ let stateVariableDefinitions = super.returnStateVariableDefinitions();
2351
+
2352
+ // matrixInputRow should be created as a replacement from matrixInputGrid
2353
+ // and given rowInd in the essential state
2354
+ stateVariableDefinitions.rowInd = {
2355
+ hasEssential: true,
2356
+ defaultValue: null,
2357
+ returnDependencies: () => ({}),
2358
+ definition: () => ({
2359
+ useEssentialOrDefaultValue: { rowInd: true },
2360
+ }),
2361
+ };
2362
+
2363
+ stateVariableDefinitions.numColumns = {
2364
+ returnDependencies: () => ({
2365
+ parentNumColumns: {
2366
+ dependencyType: "parentStateVariable",
2367
+ parentComponentType: "matrixInput",
2368
+ variableName: "numColumns",
2369
+ },
2370
+ }),
2371
+ definition({ dependencyValues }) {
2372
+ return {
2373
+ setValue: { numColumns: dependencyValues.parentNumColumns },
2374
+ };
2375
+ },
2376
+ };
2377
+
2378
+ stateVariableDefinitions.readyToExpandWhenResolved = {
2379
+ returnDependencies: () => ({
2380
+ numColumns: {
2381
+ dependencyType: "stateVariable",
2382
+ variableName: "numColumns",
2383
+ },
2384
+ }),
2385
+ markStale() {
2386
+ return { updateReplacements: true };
2387
+ },
2388
+ definition() {
2389
+ return { setValue: { readyToExpandWhenResolved: true } };
2390
+ },
2391
+ };
2392
+
2393
+ return stateVariableDefinitions;
2394
+ }
2395
+
2396
+ static async createSerializedReplacements({
2397
+ component,
2398
+ componentInfoObjects,
2399
+ flags,
2400
+ workspace,
2401
+ }) {
2402
+ let serializedComponents = [];
2403
+
2404
+ let numColumns = await component.stateValues.numColumns;
2405
+ let rowInd = await component.stateValues.rowInd;
2406
+
2407
+ workspace.previousNumColumns = numColumns;
2408
+
2409
+ for (let colInd = 0; colInd < numColumns; colInd++) {
2410
+ serializedComponents.push({
2411
+ componentType: "_matrixComponentInput",
2412
+ state: {
2413
+ rowInd,
2414
+ colInd,
2415
+ },
2416
+ uniqueIdentifier: colInd,
2417
+ });
2418
+ }
2419
+
2420
+ return { replacements: serializedComponents };
2421
+ }
2422
+
2423
+ static async calculateReplacementChanges({
2424
+ component,
2425
+ componentChanges,
2426
+ componentInfoObjects,
2427
+ flags,
2428
+ workspace,
2429
+ }) {
2430
+ let replacementChanges = [];
2431
+
2432
+ let previousNumColumns = workspace.previousNumColumns;
2433
+ let numColumns = await component.stateValues.numColumns;
2434
+ let rowInd = await component.stateValues.rowInd;
2435
+
2436
+ let newReplacementsToWithhold;
2437
+
2438
+ let numReplacementsToAdd = 0;
2439
+
2440
+ // if have fewer replacements than before
2441
+ // mark old replacements as hidden
2442
+ if (numColumns < previousNumColumns) {
2443
+ newReplacementsToWithhold = component.replacements.length - numColumns;
2444
+
2445
+ let replacementInstruction = {
2446
+ changeType: "changeReplacementsToWithhold",
2447
+ replacementsToWithhold: newReplacementsToWithhold,
2448
+ };
2449
+ replacementChanges.push(replacementInstruction);
2450
+ } else if (numColumns > previousNumColumns) {
2451
+ numReplacementsToAdd = numColumns - previousNumColumns;
2452
+
2453
+ if (component.replacementsToWithhold > 0) {
2454
+ if (component.replacementsToWithhold >= numReplacementsToAdd) {
2455
+ newReplacementsToWithhold =
2456
+ component.replacementsToWithhold - numReplacementsToAdd;
2457
+ previousNumColumns += numReplacementsToAdd;
2458
+ numReplacementsToAdd = 0;
2459
+
2460
+ let replacementInstruction = {
2461
+ changeType: "changeReplacementsToWithhold",
2462
+ replacementsToWithhold: newReplacementsToWithhold,
2463
+ };
2464
+ replacementChanges.push(replacementInstruction);
2465
+ } else {
2466
+ numReplacementsToAdd -= component.replacementsToWithhold;
2467
+ previousNumColumns += component.replacementsToWithhold;
2468
+ newReplacementsToWithhold = 0;
2469
+ // don't need to send changedReplacementsToWithold instructions
2470
+ // since will send add instructions,
2471
+ // which will also recalculate replacements in parent
2472
+ }
2473
+ }
2474
+ }
2475
+
2476
+ if (numReplacementsToAdd > 0) {
2477
+ // Need to add more replacement components
2478
+
2479
+ let newSerializedReplacements = [];
2480
+
2481
+ for (let colInd = previousNumColumns; colInd < numColumns; colInd++) {
2482
+ newSerializedReplacements.push({
2483
+ componentType: "_matrixComponentInput",
2484
+ state: {
2485
+ rowInd,
2486
+ colInd,
2487
+ },
2488
+ uniqueIdentifier: colInd,
2489
+ });
2490
+ }
2491
+
2492
+ let replacementInstruction = {
2493
+ changeType: "add",
2494
+ changeTopLevelReplacements: true,
2495
+ firstReplacementInd: previousNumColumns,
2496
+ serializedReplacements: newSerializedReplacements,
2497
+ replacementsToWithhold: 0,
2498
+ assignNamesOffset: previousNumColumns,
2499
+ };
2500
+ replacementChanges.push(replacementInstruction);
2501
+ }
2502
+
2503
+ workspace.previousNumColumns = numColumns;
2504
+
2505
+ return replacementChanges;
2506
+ }
2507
+ }
2508
+
2509
+ export default class MatrixComponentInput extends BaseComponent {
2510
+ constructor(args) {
2511
+ super(args);
2512
+
2513
+ Object.assign(this.actions, {
2514
+ updateRawValue: this.updateRawValue.bind(this),
2515
+ updateValue: this.updateValue.bind(this),
2516
+ });
2517
+ }
2518
+ static componentType = "_matrixComponentInput";
2519
+ static rendererType = "mathInput";
2520
+
2521
+ static variableForPlainMacro = "value";
2522
+ static variableForPlainCopy = "value";
2523
+
2524
+ static returnStateVariableDefinitions() {
2525
+ let stateVariableDefinitions = super.returnStateVariableDefinitions();
2526
+
2527
+ stateVariableDefinitions.minWidth = {
2528
+ forRenderer: true,
2529
+ returnDependencies: () => ({
2530
+ matrixInputAncestor: {
2531
+ dependencyType: "ancestor",
2532
+ componentType: "matrixInput",
2533
+ variableNames: ["minComponentWidth"],
2534
+ },
2535
+ }),
2536
+ definition({ dependencyValues }) {
2537
+ if (dependencyValues.matrixInputAncestor) {
2538
+ return {
2539
+ setValue: {
2540
+ minWidth:
2541
+ dependencyValues.matrixInputAncestor.stateValues
2542
+ .minComponentWidth,
2543
+ },
2544
+ };
2545
+ } else {
2546
+ return { setValue: { minWidth: 0 } };
2547
+ }
2548
+ },
2549
+ };
2550
+
2551
+ // matrixComponentInput should be created as a replacement from matrixInputRow
2552
+ // and given rowInd and colInd in the essential state
2553
+ stateVariableDefinitions.rowInd = {
2554
+ hasEssential: true,
2555
+ defaultValue: null,
2556
+ returnDependencies: () => ({}),
2557
+ definition: () => ({
2558
+ useEssentialOrDefaultValue: { rowInd: true },
2559
+ }),
2560
+ };
2561
+
2562
+ stateVariableDefinitions.colInd = {
2563
+ hasEssential: true,
2564
+ defaultValue: null,
2565
+ returnDependencies: () => ({}),
2566
+ definition: () => ({
2567
+ useEssentialOrDefaultValue: { colInd: true },
2568
+ }),
2569
+ };
2570
+
2571
+ // don't specify attributes on matrixComponentInput
2572
+ // instead gets these state variables from the parent matrixInput:
2573
+ // format, functionSymbols, splitSymbols, parseScientificNotation
2574
+ // displayDigits, displayDecimals, displaySmallAsZero, unionFromU
2575
+ stateVariableDefinitions.format = {
2576
+ returnDependencies: () => ({
2577
+ parentFormat: {
2578
+ dependencyType: "parentStateVariable",
2579
+ parentComponentType: "matrixInput",
2580
+ variableName: "format",
2581
+ },
2582
+ }),
2583
+ definition({ dependencyValues }) {
2584
+ return { setValue: { format: dependencyValues.parentFormat } };
2585
+ },
2586
+ };
2587
+
2588
+ stateVariableDefinitions.functionSymbols = {
2589
+ returnDependencies: () => ({
2590
+ parentFunctionSymbols: {
2591
+ dependencyType: "parentStateVariable",
2592
+ parentComponentType: "matrixInput",
2593
+ variableName: "functionSymbols",
2594
+ },
2595
+ }),
2596
+ definition({ dependencyValues }) {
2597
+ return {
2598
+ setValue: { functionSymbols: dependencyValues.parentFunctionSymbols },
2599
+ };
2600
+ },
2601
+ };
2602
+
2603
+ stateVariableDefinitions.splitSymbols = {
2604
+ returnDependencies: () => ({
2605
+ parentSplitSymbols: {
2606
+ dependencyType: "parentStateVariable",
2607
+ parentComponentType: "matrixInput",
2608
+ variableName: "splitSymbols",
2609
+ },
2610
+ }),
2611
+ definition({ dependencyValues }) {
2612
+ return {
2613
+ setValue: { splitSymbols: dependencyValues.parentSplitSymbols },
2614
+ };
2615
+ },
2616
+ };
2617
+
2618
+ stateVariableDefinitions.parseScientificNotation = {
2619
+ returnDependencies: () => ({
2620
+ parentParseScientificNotation: {
2621
+ dependencyType: "parentStateVariable",
2622
+ parentComponentType: "matrixInput",
2623
+ variableName: "parseScientificNotation",
2624
+ },
2625
+ }),
2626
+ definition({ dependencyValues }) {
2627
+ return {
2628
+ setValue: {
2629
+ parseScientificNotation:
2630
+ dependencyValues.parentParseScientificNotation,
2631
+ },
2632
+ };
2633
+ },
2634
+ };
2635
+
2636
+ stateVariableDefinitions.displayDigits = {
2637
+ returnDependencies: () => ({
2638
+ parentDisplayDigits: {
2639
+ dependencyType: "parentStateVariable",
2640
+ parentComponentType: "matrixInput",
2641
+ variableName: "displayDigits",
2642
+ },
2643
+ }),
2644
+ definition({ dependencyValues, usedDefault }) {
2645
+ let result = {
2646
+ setValue: { displayDigits: dependencyValues.parentDisplayDigits },
2647
+ };
2648
+
2649
+ if (usedDefault.parentDisplayDigits) {
2650
+ result.markAsUsedDefault = { displayDigits: true };
2651
+ }
2652
+
2653
+ return result;
2654
+ },
2655
+ };
2656
+
2657
+ stateVariableDefinitions.displayDecimals = {
2658
+ returnDependencies: () => ({
2659
+ parentDisplayDecimals: {
2660
+ dependencyType: "parentStateVariable",
2661
+ parentComponentType: "matrixInput",
2662
+ variableName: "displayDecimals",
2663
+ },
2664
+ }),
2665
+ definition({ dependencyValues, usedDefault }) {
2666
+ let result = {
2667
+ setValue: { displayDecimals: dependencyValues.parentDisplayDecimals },
2668
+ };
2669
+
2670
+ if (usedDefault.parentDisplayDecimals) {
2671
+ result.markAsUsedDefault = { displayDecimals: true };
2672
+ }
2673
+
2674
+ return result;
2675
+ },
2676
+ };
2677
+
2678
+ stateVariableDefinitions.displaySmallAsZero = {
2679
+ returnDependencies: () => ({
2680
+ parentDisplaySmallAsZero: {
2681
+ dependencyType: "parentStateVariable",
2682
+ parentComponentType: "matrixInput",
2683
+ variableName: "displaySmallAsZero",
2684
+ },
2685
+ }),
2686
+ definition({ dependencyValues }) {
2687
+ return {
2688
+ setValue: {
2689
+ displaySmallAsZero: dependencyValues.parentDisplaySmallAsZero,
2690
+ },
2691
+ };
2692
+ },
2693
+ };
2694
+
2695
+ stateVariableDefinitions.unionFromU = {
2696
+ returnDependencies: () => ({
2697
+ parentUnionFromU: {
2698
+ dependencyType: "parentStateVariable",
2699
+ parentComponentType: "matrixInput",
2700
+ variableName: "unionFromU",
2701
+ },
2702
+ }),
2703
+ definition({ dependencyValues }) {
2704
+ return { setValue: { unionFromU: dependencyValues.parentUnionFromU } };
2705
+ },
2706
+ };
2707
+
2708
+ // get value from parent matrixInput
2709
+ // using specified rowInd and colInd
2710
+ stateVariableDefinitions.value = {
2711
+ stateVariablesDeterminingDependencies: ["rowInd", "colInd"],
2712
+ returnDependencies: ({ stateValues }) => {
2713
+ let varEnding = "";
2714
+ if (stateValues.rowInd !== null && stateValues.colInd !== null) {
2715
+ varEnding = `${stateValues.rowInd + 1}_${stateValues.colInd + 1}`;
2716
+ }
2717
+ return {
2718
+ parentComponentValue: {
2719
+ dependencyType: "parentStateVariable",
2720
+ parentComponentType: "matrixInput",
2721
+ variableName: `componentValue${varEnding}`,
2722
+ },
2723
+ };
2724
+ },
2725
+ definition: function ({ dependencyValues }) {
2726
+ // in case size of matrix has shrunk so this component is withheld,
2727
+ // check to make sure we are getting a value
2728
+
2729
+ if (dependencyValues.parentComponentValue) {
2730
+ return { setValue: { value: dependencyValues.parentComponentValue } };
2731
+ } else {
2732
+ return { setValue: { value: me.fromAst("\uff3f") } };
2733
+ }
2734
+ },
2735
+ inverseDefinition: function ({
2736
+ desiredStateVariableValues,
2737
+ dependencyValues,
2738
+ }) {
2739
+ let instructions = [
2740
+ {
2741
+ setDependency: "parentComponentValue",
2742
+ desiredValue: desiredStateVariableValues.value,
2743
+ },
2744
+ ];
2745
+
2746
+ return {
2747
+ success: true,
2748
+ instructions,
2749
+ };
2750
+ },
2751
+ };
2752
+
2753
+ stateVariableDefinitions.immediateValue = {
2754
+ stateVariablesDeterminingDependencies: ["rowInd", "colInd"],
2755
+ returnDependencies: ({ stateValues }) => {
2756
+ let varEnding = "";
2757
+ if (stateValues.rowInd !== null && stateValues.colInd !== null) {
2758
+ varEnding = `${stateValues.rowInd + 1}_${stateValues.colInd + 1}`;
2759
+ }
2760
+ return {
2761
+ parentComponentImmediateValue: {
2762
+ dependencyType: "parentStateVariable",
2763
+ parentComponentType: "matrixInput",
2764
+ variableName: `componentImmediateValue${varEnding}`,
2765
+ },
2766
+ };
2767
+ },
2768
+ definition: function ({ dependencyValues }) {
2769
+ return {
2770
+ setValue: {
2771
+ immediateValue: dependencyValues.parentComponentImmediateValue,
2772
+ },
2773
+ };
2774
+ },
2775
+ inverseDefinition: function ({
2776
+ desiredStateVariableValues,
2777
+ initialChange,
2778
+ }) {
2779
+ let instructions = [
2780
+ {
2781
+ setDependency: "parentComponentImmediateValue",
2782
+ desiredValue: desiredStateVariableValues.immediateValue,
2783
+ treatAsInitialChange: initialChange,
2784
+ },
2785
+ ];
2786
+
2787
+ return {
2788
+ success: true,
2789
+ instructions,
2790
+ };
2791
+ },
2792
+ };
2793
+
2794
+ stateVariableDefinitions.valueForDisplay = {
2795
+ forRenderer: true,
2796
+ returnDependencies: () => ({
2797
+ value: {
2798
+ dependencyType: "stateVariable",
2799
+ variableName: "value",
2800
+ },
2801
+ displayDigits: {
2802
+ dependencyType: "stateVariable",
2803
+ variableName: "displayDigits",
2804
+ },
2805
+ displayDecimals: {
2806
+ dependencyType: "stateVariable",
2807
+ variableName: "displayDecimals",
2808
+ },
2809
+ displaySmallAsZero: {
2810
+ dependencyType: "stateVariable",
2811
+ variableName: "displaySmallAsZero",
2812
+ },
2813
+ }),
2814
+ definition: function ({ dependencyValues }) {
2815
+ // round any decimal numbers to the significant digits
2816
+ // determined by displaydigits or displaydecimals
2817
+ let rounded = roundForDisplay({
2818
+ value: dependencyValues.value,
2819
+ dependencyValues,
2820
+ });
2821
+
2822
+ return {
2823
+ setValue: { valueForDisplay: rounded },
2824
+ };
2825
+ },
2826
+ };
2827
+
2828
+ stateVariableDefinitions.text = {
2829
+ public: true,
2830
+ shadowingInstructions: {
2831
+ createComponentOfType: "text",
2832
+ },
2833
+ returnDependencies: () => ({
2834
+ valueForDisplay: {
2835
+ dependencyType: "stateVariable",
2836
+ variableName: "valueForDisplay",
2837
+ },
2838
+ }),
2839
+ definition: function ({ dependencyValues }) {
2840
+ return {
2841
+ setValue: { text: dependencyValues.valueForDisplay.toString() },
2842
+ };
2843
+ },
2844
+ };
2845
+
2846
+ // raw value from renderer
2847
+ stateVariableDefinitions.rawRendererValue = {
2848
+ forRenderer: true,
2849
+ hasEssential: true,
2850
+ shadowVariable: true,
2851
+ defaultValue: "",
2852
+ provideEssentialValuesInDefinition: true,
2853
+ public: true,
2854
+ shadowingInstructions: {
2855
+ createComponentOfType: "text",
2856
+ },
2857
+ additionalStateVariablesDefined: [
2858
+ {
2859
+ variableName: "lastValueForDisplay",
2860
+ hasEssential: true,
2861
+ shadowVariable: true,
2862
+ defaultValue: null,
2863
+ set: convertValueToMathExpression,
2864
+ },
2865
+ ],
2866
+ returnDependencies: () => ({
2867
+ // include immediateValue for inverse definition
2868
+ immediateValue: {
2869
+ dependencyType: "stateVariable",
2870
+ variableName: "immediateValue",
2871
+ },
2872
+ valueForDisplay: {
2873
+ dependencyType: "stateVariable",
2874
+ variableName: "valueForDisplay",
2875
+ },
2876
+ }),
2877
+ definition({ dependencyValues, essentialValues }) {
2878
+ // console.log(`definition of raw value for ${componentName}`)
2879
+ // console.log(dependencyValues, essentialValues)
2880
+
2881
+ // use deepCompare of trees rather than equalsViaSyntax
2882
+ // so even tiny numerical differences that within double precision are detected
2883
+ if (
2884
+ essentialValues.rawRendererValue === undefined ||
2885
+ !deepCompare(
2886
+ essentialValues.lastValueForDisplay.tree,
2887
+ dependencyValues.valueForDisplay.tree,
2888
+ )
2889
+ ) {
2890
+ let rawRendererValue = stripLatex(
2891
+ dependencyValues.valueForDisplay.toLatex(),
2892
+ );
2893
+ if (rawRendererValue === "\uff3f") {
2894
+ rawRendererValue = "";
2895
+ }
2896
+ return {
2897
+ setValue: {
2898
+ rawRendererValue,
2899
+ lastValueForDisplay: dependencyValues.valueForDisplay,
2900
+ },
2901
+ setEssentialValue: {
2902
+ rawRendererValue,
2903
+ lastValueForDisplay: dependencyValues.valueForDisplay,
2904
+ },
2905
+ };
2906
+ } else {
2907
+ return {
2908
+ useEssentialOrDefaultValue: {
2909
+ rawRendererValue: true,
2910
+ lastValueForDisplay: true,
2911
+ },
2912
+ };
2913
+ }
2914
+ },
2915
+ async inverseDefinition({
2916
+ desiredStateVariableValues,
2917
+ stateValues,
2918
+ essentialValues,
2919
+ }) {
2920
+ // console.log(`inverse definition of rawRenderer value for ${componentName}`, desiredStateVariableValues, essentialValues)
2921
+
2922
+ const calculateMathExpressionFromLatex = async (text) => {
2923
+ let expression;
2924
+
2925
+ text = normalizeLatexString(text, {
2926
+ unionFromU: await stateValues.unionFromU,
2927
+ });
2928
+
2929
+ // replace ^25 with ^{2}5, since mathQuill uses standard latex conventions
2930
+ // unlike math-expression's latex parser
2931
+ text = text.replace(/\^(\w)/g, "^{$1}");
2932
+
2933
+ let fromLatex = getFromLatex({
2934
+ functionSymbols: await stateValues.functionSymbols,
2935
+ splitSymbols: await stateValues.splitSymbols,
2936
+ parseScientificNotation: await stateValues.parseScientificNotation,
2937
+ });
2938
+
2939
+ try {
2940
+ expression = fromLatex(text);
2941
+ } catch (e) {
2942
+ // TODO: error on bad text
2943
+ expression = me.fromAst("\uFF3F");
2944
+ }
2945
+ return expression;
2946
+ };
2947
+
2948
+ let instructions = [];
2949
+
2950
+ if (typeof desiredStateVariableValues.rawRendererValue === "string") {
2951
+ let currentValue = essentialValues.rawRendererValue;
2952
+ let desiredValue = desiredStateVariableValues.rawRendererValue;
2953
+
2954
+ if (currentValue !== desiredValue) {
2955
+ instructions.push({
2956
+ setEssentialValue: "rawRendererValue",
2957
+ value: desiredValue,
2958
+ });
2959
+ }
2960
+
2961
+ let currentMath = await calculateMathExpressionFromLatex(
2962
+ currentValue,
2963
+ );
2964
+ let desiredMath = await calculateMathExpressionFromLatex(
2965
+ desiredValue,
2966
+ );
2967
+
2968
+ // use deepCompare of trees rather than equalsViaSyntax
2969
+ // so even tiny numerical differences that within double precision are detected
2970
+ if (!deepCompare(desiredMath.tree, currentMath.tree)) {
2971
+ instructions.push({
2972
+ setDependency: "immediateValue",
2973
+ desiredValue: desiredMath,
2974
+ treatAsInitialChange: true, // so does not change value
2975
+ });
2976
+ }
2977
+ } else {
2978
+ // since desired value was not a string, it must be a math-expression
2979
+ // always update lastValueForDisplay
2980
+ // update rawRendererValue
2981
+ // if desired expression is different from math-expression obtained from current raw value
2982
+ // do not update immediate value
2983
+
2984
+ instructions.push({
2985
+ setEssentialValue: "lastValueForDisplay",
2986
+ value: desiredStateVariableValues.rawRendererValue,
2987
+ });
2988
+
2989
+ let currentMath = await calculateMathExpressionFromLatex(
2990
+ essentialValues.rawRendererValue,
2991
+ );
2992
+
2993
+ // use deepCompare of trees rather than equalsViaSyntax
2994
+ // so even tiny numerical differences that within double precision are detected
2995
+ if (
2996
+ !deepCompare(
2997
+ desiredStateVariableValues.rawRendererValue.tree,
2998
+ currentMath.tree,
2999
+ )
3000
+ ) {
3001
+ let desiredValue = stripLatex(
3002
+ desiredStateVariableValues.rawRendererValue.toLatex(),
3003
+ );
3004
+ if (desiredValue === "\uff3f") {
3005
+ desiredValue = "";
3006
+ }
3007
+ instructions.push({
3008
+ setEssentialValue: "rawRendererValue",
3009
+ value: desiredValue,
3010
+ });
3011
+ }
3012
+ }
3013
+
3014
+ return {
3015
+ success: true,
3016
+ instructions,
3017
+ };
3018
+ },
3019
+ };
3020
+
3021
+ stateVariableDefinitions.componentType = {
3022
+ returnDependencies: () => ({}),
3023
+ definition: () => ({ setValue: { componentType: "math" } }),
3024
+ };
3025
+
3026
+ return stateVariableDefinitions;
3027
+ }
3028
+
3029
+ async updateRawValue({
3030
+ rawRendererValue,
3031
+ actionId,
3032
+ sourceInformation = {},
3033
+ skipRendererUpdate = false,
3034
+ }) {
3035
+ if (!(await this.stateValues.disabled)) {
3036
+ return await this.coreFunctions.performUpdate({
3037
+ updateInstructions: [
3038
+ {
3039
+ updateType: "updateValue",
3040
+ componentName: this.componentName,
3041
+ stateVariable: "rawRendererValue",
3042
+ value: rawRendererValue,
3043
+ },
3044
+ {
3045
+ updateType: "setComponentNeedingUpdateValue",
3046
+ componentName: this.componentName,
3047
+ },
3048
+ ],
3049
+ actionId,
3050
+ sourceInformation,
3051
+ skipRendererUpdate,
3052
+ });
3053
+ } else {
3054
+ this.coreFunctions.resolveAction({ actionId });
3055
+ }
3056
+ }
3057
+
3058
+ async updateValue({
3059
+ actionId,
3060
+ sourceInformation = {},
3061
+ skipRendererUpdate = false,
3062
+ }) {
3063
+ if (!(await this.stateValues.disabled)) {
3064
+ let immediateValue = await this.stateValues.immediateValue;
3065
+
3066
+ if (
3067
+ !deepCompare((await this.stateValues.value).tree, immediateValue.tree)
3068
+ ) {
3069
+ let updateInstructions = [
3070
+ {
3071
+ updateType: "updateValue",
3072
+ componentName: this.componentName,
3073
+ stateVariable: "value",
3074
+ value: immediateValue,
3075
+ },
3076
+ // in case value ended up being a different value than requested
3077
+ // we set immediate value to whatever was the result
3078
+ // (hence the need to execute update first)
3079
+ {
3080
+ updateType: "executeUpdate",
3081
+ },
3082
+ {
3083
+ updateType: "updateValue",
3084
+ componentName: this.componentName,
3085
+ stateVariable: "immediateValue",
3086
+ valueOfStateVariable: "value",
3087
+ },
3088
+ {
3089
+ updateType: "unsetComponentNeedingUpdateValue",
3090
+ },
3091
+ ];
3092
+
3093
+ if (immediateValue.tree !== "\uff3f") {
3094
+ updateInstructions.push({
3095
+ updateType: "updateValue",
3096
+ componentName: this.componentName,
3097
+ stateVariable: "rawRendererValue",
3098
+ valueOfStateVariable: "valueForDisplay",
3099
+ });
3100
+ }
3101
+
3102
+ let event = {
3103
+ verb: "answered",
3104
+ object: {
3105
+ componentName: this.componentName,
3106
+ componentType: this.componentType,
3107
+ },
3108
+ result: {
3109
+ response: immediateValue,
3110
+ responseText: immediateValue.toString(),
3111
+ },
3112
+ };
3113
+
3114
+ let answerAncestor = await this.stateValues.answerAncestor;
3115
+ if (answerAncestor) {
3116
+ event.context = {
3117
+ answerAncestor: answerAncestor.componentName,
3118
+ };
3119
+ }
3120
+
3121
+ await this.coreFunctions.performUpdate({
3122
+ updateInstructions,
3123
+ actionId,
3124
+ sourceInformation,
3125
+ skipRendererUpdate: true,
3126
+ event,
3127
+ });
3128
+
3129
+ return await this.coreFunctions.triggerChainedActions({
3130
+ componentName: this.componentName,
3131
+ actionId,
3132
+ sourceInformation,
3133
+ skipRendererUpdate,
3134
+ });
3135
+ } else {
3136
+ // set raw renderer value to save it to the database,
3137
+ // as it might not have been saved
3138
+ // given that updateRawValue is transient
3139
+ await this.coreFunctions.performUpdate({
3140
+ updateInstructions: [
3141
+ {
3142
+ updateType: "updateValue",
3143
+ componentName: this.componentName,
3144
+ stateVariable: "rawRendererValue",
3145
+ valueOfStateVariable: "rawRendererValue",
3146
+ },
3147
+ ],
3148
+ actionId,
3149
+ sourceInformation,
3150
+ skipRendererUpdate,
3151
+ });
3152
+ }
3153
+ } else {
3154
+ this.coreFunctions.resolveAction({ actionId });
3155
+ }
3156
+ }
3157
+ }