@gmb/bitmark-parser-generator 1.34.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/dist/browser/bitmark-parser-generator.min.js +1 -1
  2. package/dist/browser/bundle-report.html +2 -2
  3. package/dist/cjs/BitmarkParserGenerator.js +8 -3
  4. package/dist/cjs/BitmarkParserGenerator.js.map +1 -1
  5. package/dist/cjs/ast/Ast.js +1 -0
  6. package/dist/cjs/ast/Ast.js.map +1 -1
  7. package/dist/cjs/ast/BaseBuilder.js +91 -54
  8. package/dist/cjs/ast/BaseBuilder.js.map +1 -1
  9. package/dist/cjs/ast/Builder.js +780 -377
  10. package/dist/cjs/ast/Builder.js.map +1 -1
  11. package/dist/cjs/ast/ResourceBuilder.js +516 -252
  12. package/dist/cjs/ast/ResourceBuilder.js.map +1 -1
  13. package/dist/cjs/ast/rules/NodeValidator.js +61 -22
  14. package/dist/cjs/ast/rules/NodeValidator.js.map +1 -1
  15. package/dist/cjs/ast/writer/StreamWriter.js +13 -0
  16. package/dist/cjs/ast/writer/StreamWriter.js.map +1 -1
  17. package/dist/cjs/ast/writer/StringWriter.js +13 -0
  18. package/dist/cjs/ast/writer/StringWriter.js.map +1 -1
  19. package/dist/cjs/breakscaping/Breakscape.js +122 -95
  20. package/dist/cjs/breakscaping/Breakscape.js.map +1 -1
  21. package/dist/cjs/config/raw/bits.js +24 -5
  22. package/dist/cjs/config/raw/bits.js.map +1 -1
  23. package/dist/cjs/config/raw/properties.js +7 -2
  24. package/dist/cjs/config/raw/properties.js.map +1 -1
  25. package/dist/cjs/generated/build-info.js +1 -1
  26. package/dist/cjs/generated/build-info.js.map +1 -1
  27. package/dist/cjs/generated/parser/bitmark/bitmark-peggy-parser.js +312 -262
  28. package/dist/cjs/generated/parser/bitmark/bitmark-peggy-parser.js.map +1 -1
  29. package/dist/cjs/generator/AstWalkerGenerator.js +4 -1
  30. package/dist/cjs/generator/AstWalkerGenerator.js.map +1 -1
  31. package/dist/cjs/generator/bitmark/BitmarkGenerator.js +977 -336
  32. package/dist/cjs/generator/bitmark/BitmarkGenerator.js.map +1 -1
  33. package/dist/cjs/generator/json/JsonGenerator.js +361 -1964
  34. package/dist/cjs/generator/json/JsonGenerator.js.map +1 -1
  35. package/dist/cjs/generator/text/TextGenerator.js +26 -8
  36. package/dist/cjs/generator/text/TextGenerator.js.map +1 -1
  37. package/dist/cjs/index.js.map +1 -1
  38. package/dist/cjs/model/ast/NodeType.js +64 -42
  39. package/dist/cjs/model/ast/NodeType.js.map +1 -1
  40. package/dist/cjs/model/config/enum/PropertyConfigKey.js +1 -0
  41. package/dist/cjs/model/config/enum/PropertyConfigKey.js.map +1 -1
  42. package/dist/cjs/model/enum/BitType.js +2 -2
  43. package/dist/cjs/model/enum/BitType.js.map +1 -1
  44. package/dist/cjs/model/enum/PropertyFormat.js +3 -1
  45. package/dist/cjs/model/enum/PropertyFormat.js.map +1 -1
  46. package/dist/cjs/model/enum/TextFormat.js +1 -0
  47. package/dist/cjs/model/enum/TextFormat.js.map +1 -1
  48. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserHelper.js +22 -4
  49. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserHelper.js.map +1 -1
  50. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserProcessor.js +93 -88
  51. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserProcessor.js.map +1 -1
  52. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserTypes.js +3 -1
  53. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserTypes.js.map +1 -1
  54. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserValidator.js +10 -32
  55. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserValidator.js.map +1 -1
  56. package/dist/cjs/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js +255 -0
  57. package/dist/cjs/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js.map +1 -0
  58. package/dist/cjs/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js +2 -1
  59. package/dist/cjs/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js.map +1 -1
  60. package/dist/cjs/parser/bitmark/peg/contentProcessors/CardContentProcessor.js +175 -129
  61. package/dist/cjs/parser/bitmark/peg/contentProcessors/CardContentProcessor.js.map +1 -1
  62. package/dist/cjs/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js +8 -2
  63. package/dist/cjs/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js.map +1 -1
  64. package/dist/cjs/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js +61 -0
  65. package/dist/cjs/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js.map +1 -0
  66. package/dist/cjs/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js +11 -5
  67. package/dist/cjs/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js.map +1 -1
  68. package/dist/cjs/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js +21 -17
  69. package/dist/cjs/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js.map +1 -1
  70. package/dist/cjs/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js +50 -0
  71. package/dist/cjs/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js.map +1 -0
  72. package/dist/cjs/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js +2 -15
  73. package/dist/cjs/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js.map +1 -1
  74. package/dist/cjs/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js +2 -4
  75. package/dist/cjs/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js.map +1 -1
  76. package/dist/cjs/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js +4 -1
  77. package/dist/cjs/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js.map +1 -1
  78. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js +2 -4
  79. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js.map +1 -1
  80. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js +5 -5
  81. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js.map +1 -1
  82. package/dist/cjs/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js +5 -6
  83. package/dist/cjs/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js.map +1 -1
  84. package/dist/cjs/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js +23 -7
  85. package/dist/cjs/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js.map +1 -1
  86. package/dist/cjs/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js +5 -5
  87. package/dist/cjs/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js.map +1 -1
  88. package/dist/cjs/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js +3 -2
  89. package/dist/cjs/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js.map +1 -1
  90. package/dist/cjs/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js +19 -8
  91. package/dist/cjs/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js.map +1 -1
  92. package/dist/cjs/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js +4 -6
  93. package/dist/cjs/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js.map +1 -1
  94. package/dist/cjs/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js +4 -5
  95. package/dist/cjs/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js.map +1 -1
  96. package/dist/cjs/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js +14 -5
  97. package/dist/cjs/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js.map +1 -1
  98. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js +37 -21
  99. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js.map +1 -1
  100. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js +3 -2
  101. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js.map +1 -1
  102. package/dist/cjs/parser/json/JsonParser.js +73 -759
  103. package/dist/cjs/parser/json/JsonParser.js.map +1 -1
  104. package/dist/cjs/parser/text/TextParser.js +75 -1
  105. package/dist/cjs/parser/text/TextParser.js.map +1 -1
  106. package/dist/cjs/utils/BitUtils.js +15 -13
  107. package/dist/cjs/utils/BitUtils.js.map +1 -1
  108. package/dist/cjs/utils/StringUtils.js +40 -0
  109. package/dist/cjs/utils/StringUtils.js.map +1 -1
  110. package/dist/esm/BitmarkParserGenerator.js +8 -3
  111. package/dist/esm/BitmarkParserGenerator.js.map +1 -1
  112. package/dist/esm/ast/Ast.js +1 -0
  113. package/dist/esm/ast/Ast.js.map +1 -1
  114. package/dist/esm/ast/BaseBuilder.js +91 -54
  115. package/dist/esm/ast/BaseBuilder.js.map +1 -1
  116. package/dist/esm/ast/Builder.js +780 -377
  117. package/dist/esm/ast/Builder.js.map +1 -1
  118. package/dist/esm/ast/ResourceBuilder.js +516 -252
  119. package/dist/esm/ast/ResourceBuilder.js.map +1 -1
  120. package/dist/esm/ast/rules/NodeValidator.js +61 -22
  121. package/dist/esm/ast/rules/NodeValidator.js.map +1 -1
  122. package/dist/esm/ast/writer/StreamWriter.js +13 -0
  123. package/dist/esm/ast/writer/StreamWriter.js.map +1 -1
  124. package/dist/esm/ast/writer/StringWriter.js +13 -0
  125. package/dist/esm/ast/writer/StringWriter.js.map +1 -1
  126. package/dist/esm/breakscaping/Breakscape.js +122 -95
  127. package/dist/esm/breakscaping/Breakscape.js.map +1 -1
  128. package/dist/esm/config/raw/bits.js +24 -5
  129. package/dist/esm/config/raw/bits.js.map +1 -1
  130. package/dist/esm/config/raw/properties.js +7 -2
  131. package/dist/esm/config/raw/properties.js.map +1 -1
  132. package/dist/esm/generated/build-info.js +1 -1
  133. package/dist/esm/generated/build-info.js.map +1 -1
  134. package/dist/esm/generated/parser/bitmark/bitmark-peggy-parser.js +312 -262
  135. package/dist/esm/generated/parser/bitmark/bitmark-peggy-parser.js.map +1 -1
  136. package/dist/esm/generator/AstWalkerGenerator.js +4 -1
  137. package/dist/esm/generator/AstWalkerGenerator.js.map +1 -1
  138. package/dist/esm/generator/bitmark/BitmarkGenerator.js +977 -336
  139. package/dist/esm/generator/bitmark/BitmarkGenerator.js.map +1 -1
  140. package/dist/esm/generator/json/JsonGenerator.js +361 -1964
  141. package/dist/esm/generator/json/JsonGenerator.js.map +1 -1
  142. package/dist/esm/generator/text/TextGenerator.js +26 -8
  143. package/dist/esm/generator/text/TextGenerator.js.map +1 -1
  144. package/dist/esm/index.js.map +1 -1
  145. package/dist/esm/model/ast/NodeType.js +64 -42
  146. package/dist/esm/model/ast/NodeType.js.map +1 -1
  147. package/dist/esm/model/config/enum/PropertyConfigKey.js +1 -0
  148. package/dist/esm/model/config/enum/PropertyConfigKey.js.map +1 -1
  149. package/dist/esm/model/enum/BitType.js +2 -2
  150. package/dist/esm/model/enum/BitType.js.map +1 -1
  151. package/dist/esm/model/enum/PropertyFormat.js +3 -1
  152. package/dist/esm/model/enum/PropertyFormat.js.map +1 -1
  153. package/dist/esm/model/enum/TextFormat.js +1 -0
  154. package/dist/esm/model/enum/TextFormat.js.map +1 -1
  155. package/dist/esm/parser/bitmark/peg/BitmarkPegParserHelper.js +22 -4
  156. package/dist/esm/parser/bitmark/peg/BitmarkPegParserHelper.js.map +1 -1
  157. package/dist/esm/parser/bitmark/peg/BitmarkPegParserProcessor.js +93 -88
  158. package/dist/esm/parser/bitmark/peg/BitmarkPegParserProcessor.js.map +1 -1
  159. package/dist/esm/parser/bitmark/peg/BitmarkPegParserTypes.js +3 -1
  160. package/dist/esm/parser/bitmark/peg/BitmarkPegParserTypes.js.map +1 -1
  161. package/dist/esm/parser/bitmark/peg/BitmarkPegParserValidator.js +10 -32
  162. package/dist/esm/parser/bitmark/peg/BitmarkPegParserValidator.js.map +1 -1
  163. package/dist/esm/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js +252 -0
  164. package/dist/esm/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js.map +1 -0
  165. package/dist/esm/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js +2 -1
  166. package/dist/esm/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js.map +1 -1
  167. package/dist/esm/parser/bitmark/peg/contentProcessors/CardContentProcessor.js +175 -129
  168. package/dist/esm/parser/bitmark/peg/contentProcessors/CardContentProcessor.js.map +1 -1
  169. package/dist/esm/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js +8 -2
  170. package/dist/esm/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js.map +1 -1
  171. package/dist/esm/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js +58 -0
  172. package/dist/esm/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js.map +1 -0
  173. package/dist/esm/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js +11 -5
  174. package/dist/esm/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js.map +1 -1
  175. package/dist/esm/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js +21 -17
  176. package/dist/esm/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js.map +1 -1
  177. package/dist/esm/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js +47 -0
  178. package/dist/esm/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js.map +1 -0
  179. package/dist/esm/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js +2 -15
  180. package/dist/esm/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js.map +1 -1
  181. package/dist/esm/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js +2 -4
  182. package/dist/esm/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js.map +1 -1
  183. package/dist/esm/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js +4 -1
  184. package/dist/esm/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js.map +1 -1
  185. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js +2 -4
  186. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js.map +1 -1
  187. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js +5 -5
  188. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js.map +1 -1
  189. package/dist/esm/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js +5 -6
  190. package/dist/esm/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js.map +1 -1
  191. package/dist/esm/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js +23 -7
  192. package/dist/esm/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js.map +1 -1
  193. package/dist/esm/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js +5 -5
  194. package/dist/esm/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js.map +1 -1
  195. package/dist/esm/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js +3 -2
  196. package/dist/esm/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js.map +1 -1
  197. package/dist/esm/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js +19 -8
  198. package/dist/esm/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js.map +1 -1
  199. package/dist/esm/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js +4 -6
  200. package/dist/esm/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js.map +1 -1
  201. package/dist/esm/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js +4 -5
  202. package/dist/esm/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js.map +1 -1
  203. package/dist/esm/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js +14 -5
  204. package/dist/esm/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js.map +1 -1
  205. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js +37 -21
  206. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js.map +1 -1
  207. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js +3 -2
  208. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js.map +1 -1
  209. package/dist/esm/parser/json/JsonParser.js +73 -759
  210. package/dist/esm/parser/json/JsonParser.js.map +1 -1
  211. package/dist/esm/parser/text/TextParser.js +75 -1
  212. package/dist/esm/parser/text/TextParser.js.map +1 -1
  213. package/dist/esm/utils/BitUtils.js +15 -13
  214. package/dist/esm/utils/BitUtils.js.map +1 -1
  215. package/dist/esm/utils/StringUtils.js +40 -0
  216. package/dist/esm/utils/StringUtils.js.map +1 -1
  217. package/dist/types/BitmarkParserGenerator.d.ts +8 -0
  218. package/dist/types/BitmarkParserGenerator.d.ts.map +1 -1
  219. package/dist/types/ast/Ast.d.ts.map +1 -1
  220. package/dist/types/ast/BaseBuilder.d.ts +31 -21
  221. package/dist/types/ast/BaseBuilder.d.ts.map +1 -1
  222. package/dist/types/ast/Builder.d.ts +283 -435
  223. package/dist/types/ast/Builder.d.ts.map +1 -1
  224. package/dist/types/ast/ResourceBuilder.d.ts +177 -164
  225. package/dist/types/ast/ResourceBuilder.d.ts.map +1 -1
  226. package/dist/types/ast/rules/NodeValidator.d.ts +3 -2
  227. package/dist/types/ast/rules/NodeValidator.d.ts.map +1 -1
  228. package/dist/types/ast/writer/StreamWriter.d.ts +2 -0
  229. package/dist/types/ast/writer/StreamWriter.d.ts.map +1 -1
  230. package/dist/types/ast/writer/StringWriter.d.ts +2 -0
  231. package/dist/types/ast/writer/StringWriter.d.ts.map +1 -1
  232. package/dist/types/ast/writer/Writer.d.ts +6 -0
  233. package/dist/types/ast/writer/Writer.d.ts.map +1 -1
  234. package/dist/types/breakscaping/Breakscape.d.ts +6 -1
  235. package/dist/types/breakscaping/Breakscape.d.ts.map +1 -1
  236. package/dist/types/config/raw/bits.d.ts.map +1 -1
  237. package/dist/types/config/raw/properties.d.ts.map +1 -1
  238. package/dist/types/generated/parser/bitmark/bitmark-peggy-parser.d.ts.map +1 -1
  239. package/dist/types/generator/AstWalkerGenerator.d.ts.map +1 -1
  240. package/dist/types/generator/bitmark/BitmarkGenerator.d.ts +91 -55
  241. package/dist/types/generator/bitmark/BitmarkGenerator.d.ts.map +1 -1
  242. package/dist/types/generator/json/JsonGenerator.d.ts +96 -108
  243. package/dist/types/generator/json/JsonGenerator.d.ts.map +1 -1
  244. package/dist/types/generator/text/TextGenerator.d.ts +14 -2
  245. package/dist/types/generator/text/TextGenerator.d.ts.map +1 -1
  246. package/dist/types/index.d.ts +2 -2
  247. package/dist/types/index.d.ts.map +1 -1
  248. package/dist/types/model/ast/NodeType.d.ts +122 -84
  249. package/dist/types/model/ast/NodeType.d.ts.map +1 -1
  250. package/dist/types/model/ast/Nodes.d.ts +66 -436
  251. package/dist/types/model/ast/Nodes.d.ts.map +1 -1
  252. package/dist/types/model/ast/TextNodes.d.ts +1 -1
  253. package/dist/types/model/ast/TextNodes.d.ts.map +1 -1
  254. package/dist/types/model/config/enum/ConfigKey.d.ts +2 -0
  255. package/dist/types/model/config/enum/ConfigKey.d.ts.map +1 -1
  256. package/dist/types/model/config/enum/PropertyConfigKey.d.ts +3 -0
  257. package/dist/types/model/config/enum/PropertyConfigKey.d.ts.map +1 -1
  258. package/dist/types/model/enum/BitType.d.ts +4 -4
  259. package/dist/types/model/enum/PropertyFormat.d.ts +4 -2
  260. package/dist/types/model/enum/PropertyFormat.d.ts.map +1 -1
  261. package/dist/types/model/enum/PropertyTag.d.ts +2 -0
  262. package/dist/types/model/enum/PropertyTag.d.ts.map +1 -1
  263. package/dist/types/model/enum/TextFormat.d.ts +2 -0
  264. package/dist/types/model/enum/TextFormat.d.ts.map +1 -1
  265. package/dist/types/model/json/BitJson.d.ts +32 -20
  266. package/dist/types/model/json/BitJson.d.ts.map +1 -1
  267. package/dist/types/model/json/BodyBitJson.d.ts +16 -12
  268. package/dist/types/model/json/BodyBitJson.d.ts.map +1 -1
  269. package/dist/types/model/json/ResourceJson.d.ts +2 -22
  270. package/dist/types/model/json/ResourceJson.d.ts.map +1 -1
  271. package/dist/types/parser/bitmark/peg/BitmarkPegParserHelper.d.ts +4 -2
  272. package/dist/types/parser/bitmark/peg/BitmarkPegParserHelper.d.ts.map +1 -1
  273. package/dist/types/parser/bitmark/peg/BitmarkPegParserProcessor.d.ts +3 -9
  274. package/dist/types/parser/bitmark/peg/BitmarkPegParserProcessor.d.ts.map +1 -1
  275. package/dist/types/parser/bitmark/peg/BitmarkPegParserTypes.d.ts +90 -74
  276. package/dist/types/parser/bitmark/peg/BitmarkPegParserTypes.d.ts.map +1 -1
  277. package/dist/types/parser/bitmark/peg/BitmarkPegParserValidator.d.ts +2 -2
  278. package/dist/types/parser/bitmark/peg/BitmarkPegParserValidator.d.ts.map +1 -1
  279. package/dist/types/parser/bitmark/peg/contentProcessors/BodyContentProcessor.d.ts +37 -0
  280. package/dist/types/parser/bitmark/peg/contentProcessors/BodyContentProcessor.d.ts.map +1 -0
  281. package/dist/types/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.d.ts.map +1 -1
  282. package/dist/types/parser/bitmark/peg/contentProcessors/CardContentProcessor.d.ts +2 -2
  283. package/dist/types/parser/bitmark/peg/contentProcessors/CardContentProcessor.d.ts.map +1 -1
  284. package/dist/types/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.d.ts.map +1 -1
  285. package/dist/types/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.d.ts +15 -0
  286. package/dist/types/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.d.ts.map +1 -0
  287. package/dist/types/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.d.ts.map +1 -1
  288. package/dist/types/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.d.ts.map +1 -1
  289. package/dist/types/parser/bitmark/peg/contentProcessors/FooterContentProcessor.d.ts +16 -0
  290. package/dist/types/parser/bitmark/peg/contentProcessors/FooterContentProcessor.d.ts.map +1 -0
  291. package/dist/types/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.d.ts.map +1 -1
  292. package/dist/types/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.d.ts.map +1 -1
  293. package/dist/types/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.d.ts.map +1 -1
  294. package/dist/types/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.d.ts.map +1 -1
  295. package/dist/types/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.d.ts.map +1 -1
  296. package/dist/types/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.d.ts.map +1 -1
  297. package/dist/types/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.d.ts.map +1 -1
  298. package/dist/types/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.d.ts.map +1 -1
  299. package/dist/types/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.d.ts.map +1 -1
  300. package/dist/types/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.d.ts +2 -2
  301. package/dist/types/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.d.ts.map +1 -1
  302. package/dist/types/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.d.ts.map +1 -1
  303. package/dist/types/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.d.ts.map +1 -1
  304. package/dist/types/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.d.ts +5 -2
  305. package/dist/types/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.d.ts.map +1 -1
  306. package/dist/types/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.d.ts +1 -1
  307. package/dist/types/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.d.ts.map +1 -1
  308. package/dist/types/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.d.ts.map +1 -1
  309. package/dist/types/parser/json/JsonParser.d.ts +9 -72
  310. package/dist/types/parser/json/JsonParser.d.ts.map +1 -1
  311. package/dist/types/parser/text/TextParser.d.ts +16 -1
  312. package/dist/types/parser/text/TextParser.d.ts.map +1 -1
  313. package/dist/types/utils/BitUtils.d.ts +8 -8
  314. package/dist/types/utils/BitUtils.d.ts.map +1 -1
  315. package/dist/types/utils/StringUtils.d.ts +24 -0
  316. package/dist/types/utils/StringUtils.d.ts.map +1 -1
  317. package/package.json +1 -1
@@ -7,22 +7,29 @@ import { ResourceTag } from '../model/enum/ResourceTag';
7
7
  import { TextFormat } from '../model/enum/TextFormat';
8
8
  import { ArrayUtils } from '../utils/ArrayUtils';
9
9
  import { BitUtils } from '../utils/BitUtils';
10
+ import { BooleanUtils } from '../utils/BooleanUtils';
10
11
  import { NumberUtils } from '../utils/NumberUtils';
11
12
  import { ObjectUtils } from '../utils/ObjectUtils';
13
+ import { StringUtils } from '../utils/StringUtils';
12
14
  import { env } from '../utils/env/Env';
13
15
  import { BaseBuilder } from './BaseBuilder';
16
+ import { ResourceBuilder } from './ResourceBuilder';
14
17
  import { NodeValidator } from './rules/NodeValidator';
15
18
  /**
16
19
  * Builder to build bitmark AST node programmatically
17
20
  */
18
21
  class Builder extends BaseBuilder {
22
+ constructor() {
23
+ super(...arguments);
24
+ this.resourceBuilder = new ResourceBuilder();
25
+ }
19
26
  /**
20
27
  * Build bitmark node
21
28
  *
22
29
  * @param data - data for the node
23
30
  * @returns
24
31
  */
25
- bitmark(data) {
32
+ buildBitmark(data) {
26
33
  const { bits, errors } = data;
27
34
  const node = {
28
35
  bits,
@@ -38,49 +45,44 @@ class Builder extends BaseBuilder {
38
45
  * @param data - data for the node
39
46
  * @returns
40
47
  */
41
- bit(data) {
42
- var _a;
43
- const { bitType, bitLevel, textFormat, resourceType, isCommented, id, internalComment, externalId, spaceId, padletId, jupyterId, jupyterExecutionCount, isPublic, aiGenerated, machineTranslated, analyticsTag, feedbackEngine, feedbackType, disableFeedback, releaseVersion, releaseKind, releaseDate, ageRange, lang, language, publisher, publisherName, theme, computerLanguage, target, slug, tag, reductionTag, bubbleTag, levelCEFRp, levelCEFR, levelILR, levelACTFL, icon, iconTag, colorTag, flashcardSet, subtype, bookAlias, coverImage, coverColor, publications, author, subject, date, dateEnd, location, kind, hasMarkAsDone, processHandIn, action, showInIndex, blockId, pageNo, x, y, width, height, index, classification, availableClassifications, allowedBit, tableFixedHeader, tableSearch, tableSort, tablePagination, tablePaginationLimit, tableHeight, tableWhitespaceNoWrap, tableAutoWidth, tableResizableColumns, quizCountItems, quizStrikethroughSolutions, codeLineNumbers, codeMinimap, stripePricingTableId, stripePublishableKey, thumbImage, scormSource, posterImage, focusX, focusY, pointerLeft, pointerTop, listItemIndent, backgroundWallpaper, hasBookNavigation, duration, referenceProperty, deeplink, externalLink, externalLinkText, videoCallLink, vendorUrl, search, bot, list, textReference, isTracked, isInfoOnly, imageFirst, activityType, labelTrue, labelFalse, content2Buy, mailingList, buttonCaption, callToActionUrl, caption, book, quotedPerson, partialAnswer, reasonableNumOfChars, sampleSolution, additionalSolutions, resolved, resolvedDate, resolvedBy, maxCreatedBits, maxDisplayLevel, page, productId, product, productList, productVideo, productVideoList, productFolder, technicalTerm, servings, ratingLevelStart, ratingLevelEnd, ratingLevelSelected, title, subtitle, level, toc, progress, anchor, reference, referenceEnd, isCaseSensitive, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example, imageSource, person, markConfig, extraProperties, imagePlaceholder, resources: _resources, body, footer, markup, parser, } = data;
44
- const bitConfig = Config.getBitConfig(bitType);
45
- // Convert resources into an array
46
- const resources = ArrayUtils.asArray(_resources);
48
+ buildBit(data) {
49
+ var _a, _b, _c, _d, _e, _f, _g, _h;
50
+ const bitConfig = Config.getBitConfig(data.bitType);
51
+ const textFormat = (_a = TextFormat.fromValue(data.textFormat)) !== null && _a !== void 0 ? _a : bitConfig.textFormatDefault;
52
+ // Validate and convert resources, and ensure it is an array
53
+ // const resources = ArrayUtils.asArray(resourcesIn);
47
54
  // Set the card node data
48
- const cardNode = this.cardNode(data);
55
+ const cardNode = this.buildCardNode(data.bitType, textFormat, data);
49
56
  // Add reasonableNumOfChars to the bit only for essay bits (in other cases it will be pushed down the tree)
50
- const reasonableNumOfCharsProperty = Config.isOfBitType(bitType, BitType.essay)
51
- ? this.toAstProperty(PropertyConfigKey.reasonableNumOfChars, reasonableNumOfChars)
57
+ const reasonableNumOfCharsProperty = Config.isOfBitType(data.bitType, BitType.essay)
58
+ ? this.toAstProperty(PropertyConfigKey.reasonableNumOfChars, data.reasonableNumOfChars)
52
59
  : undefined;
60
+ const convertedExample = Object.assign({}, this.toExample(data.__isDefaultExample, data.example));
53
61
  // NOTE: Node order is important and is defined here
54
- const node = Object.assign(Object.assign({ bitType,
55
- bitLevel, textFormat: (_a = TextFormat.fromValue(textFormat)) !== null && _a !== void 0 ? _a : bitConfig.textFormatDefault, resourceType: ResourceTag.fromValue(resourceType), isCommented, id: this.toAstProperty(PropertyConfigKey.id, id), internalComment: this.toAstProperty(PropertyConfigKey.internalComment, internalComment), externalId: this.toAstProperty(PropertyConfigKey.externalId, externalId), spaceId: this.toAstProperty(PropertyConfigKey.spaceId, spaceId), padletId: this.toAstProperty(PropertyConfigKey.padletId, padletId), jupyterId: this.toAstProperty(PropertyConfigKey.jupyterId, jupyterId), jupyterExecutionCount: this.toAstProperty(PropertyConfigKey.jupyterExecutionCount, jupyterExecutionCount), isPublic: this.toAstProperty(PropertyConfigKey.isPublic, isPublic), aiGenerated: this.toAstProperty(PropertyConfigKey.aiGenerated, aiGenerated), machineTranslated: this.toAstProperty(PropertyConfigKey.machineTranslated, machineTranslated), analyticsTag: this.toAstProperty(PropertyConfigKey.analyticsTag, analyticsTag), feedbackEngine: this.toAstProperty(PropertyConfigKey.feedbackEngine, feedbackEngine), feedbackType: this.toAstProperty(PropertyConfigKey.feedbackType, feedbackType), disableFeedback: this.toAstProperty(PropertyConfigKey.disableFeedback, disableFeedback), releaseVersion: this.toAstProperty(PropertyConfigKey.releaseVersion, releaseVersion), releaseKind: this.toAstProperty(PropertyConfigKey.releaseKind, releaseKind), releaseDate: this.toAstProperty(PropertyConfigKey.releaseDate, releaseDate), book, ageRange: this.toAstProperty(PropertyConfigKey.ageRange, ageRange), lang: this.toAstProperty(PropertyConfigKey.lang, lang), language: this.toAstProperty(PropertyConfigKey.language, language), publisher: this.toAstProperty(PropertyConfigKey.publisher, publisher), publisherName: this.toAstProperty(PropertyConfigKey.publisherName, publisherName), theme: this.toAstProperty(PropertyConfigKey.theme, theme), computerLanguage: this.toAstProperty(PropertyConfigKey.computerLanguage, computerLanguage), target: this.toAstProperty(PropertyConfigKey.target, target), slug: this.toAstProperty(PropertyConfigKey.slug, slug), tag: this.toAstProperty(PropertyConfigKey.tag, tag), reductionTag: this.toAstProperty(PropertyConfigKey.reductionTag, reductionTag), bubbleTag: this.toAstProperty(PropertyConfigKey.bubbleTag, bubbleTag), levelCEFRp: this.toAstProperty(PropertyConfigKey.levelCEFRp, levelCEFRp), levelCEFR: this.toAstProperty(PropertyConfigKey.levelCEFR, levelCEFR), levelILR: this.toAstProperty(PropertyConfigKey.levelILR, levelILR), levelACTFL: this.toAstProperty(PropertyConfigKey.levelACTFL, levelACTFL), icon: this.toAstProperty(PropertyConfigKey.icon, icon), iconTag: this.toAstProperty(PropertyConfigKey.iconTag, iconTag), colorTag: this.toAstProperty(PropertyConfigKey.colorTag, colorTag), flashcardSet: this.toAstProperty(PropertyConfigKey.flashcardSet, flashcardSet), subtype: this.toAstProperty(PropertyConfigKey.subtype, subtype), bookAlias: this.toAstProperty(PropertyConfigKey.bookAlias, bookAlias), coverImage: this.toAstProperty(PropertyConfigKey.coverImage, coverImage), coverColor: this.toAstProperty(PropertyConfigKey.coverColor, coverColor), publications: this.toAstProperty(PropertyConfigKey.publications, publications), author: this.toAstProperty(PropertyConfigKey.author, author), subject: this.toAstProperty(PropertyConfigKey.subject, subject), date: this.toAstProperty(PropertyConfigKey.date, date), dateEnd: this.toAstProperty(PropertyConfigKey.dateEnd, dateEnd), location: this.toAstProperty(PropertyConfigKey.location, location), kind: this.toAstProperty(PropertyConfigKey.kind, kind), hasMarkAsDone: this.toAstProperty(PropertyConfigKey.hasMarkAsDone, hasMarkAsDone), processHandIn: this.toAstProperty(PropertyConfigKey.processHandIn, processHandIn), action: this.toAstProperty(PropertyConfigKey.action, action), showInIndex: this.toAstProperty(PropertyConfigKey.showInIndex, showInIndex), blockId: this.toAstProperty(PropertyConfigKey.blockId, blockId), pageNo: this.toAstProperty(PropertyConfigKey.pageNo, pageNo), x: this.toAstProperty(PropertyConfigKey.x, x), y: this.toAstProperty(PropertyConfigKey.y, y), width: this.toAstProperty(PropertyConfigKey.width, width), height: this.toAstProperty(PropertyConfigKey.height, height), index: this.toAstProperty(PropertyConfigKey.index, index), classification: this.toAstProperty(PropertyConfigKey.classification, classification), availableClassifications: this.toAstProperty(PropertyConfigKey.availableClassifications, availableClassifications), allowedBit: this.toAstProperty(PropertyConfigKey.allowedBit, allowedBit), tableFixedHeader: this.toAstProperty(PropertyConfigKey.tableFixedHeader, tableFixedHeader), tableSearch: this.toAstProperty(PropertyConfigKey.tableSearch, tableSearch), tableSort: this.toAstProperty(PropertyConfigKey.tableSort, tableSort), tablePagination: this.toAstProperty(PropertyConfigKey.tablePagination, tablePagination), tablePaginationLimit: this.toAstProperty(PropertyConfigKey.tablePaginationLimit, tablePaginationLimit), tableHeight: this.toAstProperty(PropertyConfigKey.tableHeight, tableHeight), tableWhitespaceNoWrap: this.toAstProperty(PropertyConfigKey.tableWhitespaceNoWrap, tableWhitespaceNoWrap), tableAutoWidth: this.toAstProperty(PropertyConfigKey.tableAutoWidth, tableAutoWidth), tableResizableColumns: this.toAstProperty(PropertyConfigKey.tableResizableColumns, tableResizableColumns), quizCountItems: this.toAstProperty(PropertyConfigKey.quizCountItems, quizCountItems), quizStrikethroughSolutions: this.toAstProperty(PropertyConfigKey.quizStrikethroughSolutions, quizStrikethroughSolutions), codeLineNumbers: this.toAstProperty(PropertyConfigKey.codeLineNumbers, codeLineNumbers), codeMinimap: this.toAstProperty(PropertyConfigKey.codeMinimap, codeMinimap), stripePricingTableId: this.toAstProperty(PropertyConfigKey.stripePricingTableId, stripePricingTableId), stripePublishableKey: this.toAstProperty(PropertyConfigKey.stripePublishableKey, stripePublishableKey), thumbImage: this.toAstProperty(PropertyConfigKey.thumbImage, thumbImage), scormSource: this.toAstProperty(PropertyConfigKey.scormSource, scormSource), posterImage: this.toAstProperty(PropertyConfigKey.posterImage, posterImage), focusX: this.toAstProperty(PropertyConfigKey.focusX, focusX), focusY: this.toAstProperty(PropertyConfigKey.focusY, focusY), pointerLeft: this.toAstProperty(PropertyConfigKey.pointerLeft, pointerLeft), pointerTop: this.toAstProperty(PropertyConfigKey.pointerTop, pointerTop), listItemIndent: this.toAstProperty(PropertyConfigKey.listItemIndent, listItemIndent), backgroundWallpaper: this.toAstProperty(PropertyConfigKey.backgroundWallpaper, backgroundWallpaper), hasBookNavigation: this.toAstProperty(PropertyConfigKey.hasBookNavigation, hasBookNavigation), deeplink: this.toAstProperty(PropertyConfigKey.deeplink, deeplink), externalLink: this.toAstProperty(PropertyConfigKey.externalLink, externalLink), externalLinkText: this.toAstProperty(PropertyConfigKey.externalLinkText, externalLinkText), videoCallLink: this.toAstProperty(PropertyConfigKey.videoCallLink, videoCallLink), vendorUrl: this.toAstProperty(PropertyConfigKey.vendorUrl, vendorUrl), search: this.toAstProperty(PropertyConfigKey.search, search), bot: this.toAstProperty(PropertyConfigKey.bot, bot), duration: this.toAstProperty(PropertyConfigKey.duration, duration), referenceProperty: this.toAstProperty(PropertyConfigKey.property_reference, referenceProperty), list: this.toAstProperty(PropertyConfigKey.list, list), textReference: this.toAstProperty(PropertyConfigKey.textReference, textReference), isTracked: this.toAstProperty(PropertyConfigKey.isTracked, isTracked), isInfoOnly: this.toAstProperty(PropertyConfigKey.isInfoOnly, isInfoOnly), imageFirst: this.toAstProperty(PropertyConfigKey.imageFirst, imageFirst), activityType: this.toAstProperty(PropertyConfigKey.activityType, activityType), labelTrue: this.toAstProperty(PropertyConfigKey.labelTrue, labelTrue), labelFalse: this.toAstProperty(PropertyConfigKey.labelFalse, labelFalse), content2Buy: this.toAstProperty(PropertyConfigKey.content2Buy, content2Buy), mailingList: this.toAstProperty(PropertyConfigKey.mailingList, mailingList), buttonCaption: this.toAstProperty(PropertyConfigKey.buttonCaption, buttonCaption), callToActionUrl: this.toAstProperty(PropertyConfigKey.callToActionUrl, callToActionUrl), caption, quotedPerson: this.toAstProperty(PropertyConfigKey.quotedPerson, quotedPerson), partialAnswer: this.toAstProperty(PropertyConfigKey.partialAnswer, partialAnswer), reasonableNumOfChars: reasonableNumOfCharsProperty, sampleSolution: this.toAstProperty(PropertyConfigKey.property_sampleSolution, sampleSolution), additionalSolutions: this.toAstProperty(PropertyConfigKey.additionalSolutions, additionalSolutions), resolved: this.toAstProperty(PropertyConfigKey.resolved, resolved), resolvedDate: this.toAstProperty(PropertyConfigKey.resolvedDate, resolvedDate), resolvedBy: this.toAstProperty(PropertyConfigKey.resolvedBy, resolvedBy), maxCreatedBits: this.toAstProperty(PropertyConfigKey.maxCreatedBits, maxCreatedBits), maxDisplayLevel: this.toAstProperty(PropertyConfigKey.maxDisplayLevel, maxDisplayLevel), page: this.toAstProperty(PropertyConfigKey.page, page), productId: this.toAstProperty(PropertyConfigKey.productId, productId), product: this.toAstProperty(PropertyConfigKey.product, product), productList: this.toAstProperty(PropertyConfigKey.productList, productList), productVideo: this.toAstProperty(PropertyConfigKey.productVideo, productVideo), productVideoList: this.toAstProperty(PropertyConfigKey.productVideoList, productVideoList), productFolder: this.toAstProperty(PropertyConfigKey.productFolder, productFolder), technicalTerm,
56
- servings,
57
- ratingLevelStart,
58
- ratingLevelEnd, ratingLevelSelected: this.toAstProperty(PropertyConfigKey.ratingLevelSelected, ratingLevelSelected), title,
59
- subtitle, level: NumberUtils.asNumber(level), toc: this.toAstProperty(PropertyConfigKey.toc, toc), progress: this.toAstProperty(PropertyConfigKey.progress, progress), anchor,
60
- reference,
61
- referenceEnd,
62
- markConfig, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
63
- instruction }, this.toExample(isDefaultExample, example)), { imageSource,
64
- person,
65
- imagePlaceholder,
66
- resources,
67
- body,
68
- cardNode,
69
- footer,
70
- markup,
71
- parser,
62
+ const node = Object.assign(Object.assign({ bitType: data.bitType, bitLevel: data.bitLevel, textFormat, resourceType: ResourceTag.fromValue(data.resourceType), isCommented: data.isCommented,
63
+ // Properties
64
+ id: this.toAstProperty(PropertyConfigKey.id, data.id), internalComment: this.toAstProperty(PropertyConfigKey.internalComment, data.internalComment), externalId: this.toAstProperty(PropertyConfigKey.externalId, data.externalId), spaceId: this.toAstProperty(PropertyConfigKey.spaceId, data.spaceId), padletId: this.toAstProperty(PropertyConfigKey.padletId, data.padletId), jupyterId: this.toAstProperty(PropertyConfigKey.jupyterId, data.jupyterId), jupyterExecutionCount: this.toAstProperty(PropertyConfigKey.jupyterExecutionCount, data.jupyterExecutionCount), isPublic: this.toAstProperty(PropertyConfigKey.isPublic, data.isPublic), aiGenerated: this.toAstProperty(PropertyConfigKey.aiGenerated, data.aiGenerated), machineTranslated: this.toAstProperty(PropertyConfigKey.machineTranslated, data.machineTranslated), analyticsTag: this.toAstProperty(PropertyConfigKey.analyticsTag, data.analyticsTag), feedbackEngine: this.toAstProperty(PropertyConfigKey.feedbackEngine, data.feedbackEngine), feedbackType: this.toAstProperty(PropertyConfigKey.feedbackType, data.feedbackType), disableFeedback: this.toAstProperty(PropertyConfigKey.disableFeedback, data.disableFeedback), releaseVersion: this.toAstProperty(PropertyConfigKey.releaseVersion, data.releaseVersion), releaseKind: this.toAstProperty(PropertyConfigKey.releaseKind, data.releaseKind), releaseDate: this.toAstProperty(PropertyConfigKey.releaseDate, data.releaseDate), book: data.book, ageRange: this.toAstProperty(PropertyConfigKey.ageRange, data.ageRange), lang: this.toAstProperty(PropertyConfigKey.lang, data.lang), language: this.toAstProperty(PropertyConfigKey.language, data.language), publisher: this.toAstProperty(PropertyConfigKey.publisher, data.publisher), publisherName: this.toAstProperty(PropertyConfigKey.publisherName, data.publisherName), theme: this.toAstProperty(PropertyConfigKey.theme, data.theme), computerLanguage: this.toAstProperty(PropertyConfigKey.computerLanguage, data.computerLanguage), target: this.toAstProperty(PropertyConfigKey.target, data.target), slug: this.toAstProperty(PropertyConfigKey.slug, data.slug), tag: this.toAstProperty(PropertyConfigKey.tag, data.tag), reductionTag: this.toAstProperty(PropertyConfigKey.reductionTag, data.reductionTag), bubbleTag: this.toAstProperty(PropertyConfigKey.bubbleTag, data.bubbleTag), levelCEFRp: this.toAstProperty(PropertyConfigKey.levelCEFRp, data.levelCEFRp), levelCEFR: this.toAstProperty(PropertyConfigKey.levelCEFR, data.levelCEFR), levelILR: this.toAstProperty(PropertyConfigKey.levelILR, data.levelILR), levelACTFL: this.toAstProperty(PropertyConfigKey.levelACTFL, data.levelACTFL), icon: this.toAstProperty(PropertyConfigKey.icon, data.icon), iconTag: this.toAstProperty(PropertyConfigKey.iconTag, data.iconTag), colorTag: this.toAstProperty(PropertyConfigKey.colorTag, data.colorTag), flashcardSet: this.toAstProperty(PropertyConfigKey.flashcardSet, data.flashcardSet), subtype: this.toAstProperty(PropertyConfigKey.subtype, data.subtype), bookAlias: this.toAstProperty(PropertyConfigKey.bookAlias, data.bookAlias), coverImage: this.toAstProperty(PropertyConfigKey.coverImage, data.coverImage), coverColor: this.toAstProperty(PropertyConfigKey.coverColor, data.coverColor), publications: this.toAstProperty(PropertyConfigKey.publications, data.publications), author: this.toAstProperty(PropertyConfigKey.author, data.author), subject: this.toAstProperty(PropertyConfigKey.subject, data.subject), date: this.toAstProperty(PropertyConfigKey.date, data.date), dateEnd: this.toAstProperty(PropertyConfigKey.dateEnd, data.dateEnd), location: this.toAstProperty(PropertyConfigKey.location, data.location), kind: this.toAstProperty(PropertyConfigKey.kind, data.kind), hasMarkAsDone: this.toAstProperty(PropertyConfigKey.hasMarkAsDone, data.hasMarkAsDone), processHandIn: this.toAstProperty(PropertyConfigKey.processHandIn, data.processHandIn), action: this.toAstProperty(PropertyConfigKey.action, data.action), showInIndex: this.toAstProperty(PropertyConfigKey.showInIndex, data.showInIndex), blockId: this.toAstProperty(PropertyConfigKey.blockId, data.blockId), pageNo: this.toAstProperty(PropertyConfigKey.pageNo, data.pageNo), x: this.toAstProperty(PropertyConfigKey.x, data.x), y: this.toAstProperty(PropertyConfigKey.y, data.y), width: this.toAstProperty(PropertyConfigKey.width, data.width), height: this.toAstProperty(PropertyConfigKey.height, data.height), index: this.toAstProperty(PropertyConfigKey.index, data.index), classification: this.toAstProperty(PropertyConfigKey.classification, data.classification), availableClassifications: this.toAstProperty(PropertyConfigKey.availableClassifications, data.availableClassifications), allowedBit: this.toAstProperty(PropertyConfigKey.allowedBit, data.allowedBit), tableFixedHeader: this.toAstProperty(PropertyConfigKey.tableFixedHeader, data.tableFixedHeader), tableSearch: this.toAstProperty(PropertyConfigKey.tableSearch, data.tableSearch), tableSort: this.toAstProperty(PropertyConfigKey.tableSort, data.tableSort), tablePagination: this.toAstProperty(PropertyConfigKey.tablePagination, data.tablePagination), tablePaginationLimit: this.toAstProperty(PropertyConfigKey.tablePaginationLimit, data.tablePaginationLimit), tableHeight: this.toAstProperty(PropertyConfigKey.tableHeight, data.tableHeight), tableWhitespaceNoWrap: this.toAstProperty(PropertyConfigKey.tableWhitespaceNoWrap, data.tableWhitespaceNoWrap), tableAutoWidth: this.toAstProperty(PropertyConfigKey.tableAutoWidth, data.tableAutoWidth), tableResizableColumns: this.toAstProperty(PropertyConfigKey.tableResizableColumns, data.tableResizableColumns), tableColumnMinWidth: this.toAstProperty(PropertyConfigKey.tableColumnMinWidth, data.tableColumnMinWidth), quizCountItems: this.toAstProperty(PropertyConfigKey.quizCountItems, data.quizCountItems), quizStrikethroughSolutions: this.toAstProperty(PropertyConfigKey.quizStrikethroughSolutions, data.quizStrikethroughSolutions), codeLineNumbers: this.toAstProperty(PropertyConfigKey.codeLineNumbers, data.codeLineNumbers), codeMinimap: this.toAstProperty(PropertyConfigKey.codeMinimap, data.codeMinimap), stripePricingTableId: this.toAstProperty(PropertyConfigKey.stripePricingTableId, data.stripePricingTableId), stripePublishableKey: this.toAstProperty(PropertyConfigKey.stripePublishableKey, data.stripePublishableKey), thumbImage: this.toAstProperty(PropertyConfigKey.thumbImage, data.thumbImage), scormSource: this.toAstProperty(PropertyConfigKey.scormSource, data.scormSource), posterImage: this.toAstProperty(PropertyConfigKey.posterImage, data.posterImage), focusX: this.toAstProperty(PropertyConfigKey.focusX, data.focusX), focusY: this.toAstProperty(PropertyConfigKey.focusY, data.focusY), pointerLeft: this.toAstProperty(PropertyConfigKey.pointerLeft, data.pointerLeft), pointerTop: this.toAstProperty(PropertyConfigKey.pointerTop, data.pointerTop), listItemIndent: this.toAstProperty(PropertyConfigKey.listItemIndent, data.listItemIndent), backgroundWallpaper: this.toAstProperty(PropertyConfigKey.backgroundWallpaper, data.backgroundWallpaper), hasBookNavigation: this.toAstProperty(PropertyConfigKey.hasBookNavigation, data.hasBookNavigation), duration: this.toAstProperty(PropertyConfigKey.duration, data.duration), deeplink: this.toAstProperty(PropertyConfigKey.deeplink, data.deeplink), externalLink: this.toAstProperty(PropertyConfigKey.externalLink, data.externalLink), externalLinkText: this.toAstProperty(PropertyConfigKey.externalLinkText, data.externalLinkText), videoCallLink: this.toAstProperty(PropertyConfigKey.videoCallLink, data.videoCallLink), vendorUrl: this.toAstProperty(PropertyConfigKey.vendorUrl, data.vendorUrl), search: this.toAstProperty(PropertyConfigKey.search, data.search), list: this.toAstProperty(PropertyConfigKey.list, data.list), textReference: this.toAstProperty(PropertyConfigKey.textReference, data.textReference), isTracked: this.toAstProperty(PropertyConfigKey.isTracked, data.isTracked), isInfoOnly: this.toAstProperty(PropertyConfigKey.isInfoOnly, data.isInfoOnly), imageFirst: this.toAstProperty(PropertyConfigKey.imageFirst, data.imageFirst), activityType: this.toAstProperty(PropertyConfigKey.activityType, data.activityType), labelTrue: this.toAstProperty(PropertyConfigKey.labelTrue, data.labelTrue), labelFalse: this.toAstProperty(PropertyConfigKey.labelFalse, data.labelFalse), content2Buy: this.toAstProperty(PropertyConfigKey.content2Buy, data.content2Buy), mailingList: this.toAstProperty(PropertyConfigKey.mailingList, data.mailingList), buttonCaption: this.toAstProperty(PropertyConfigKey.buttonCaption, data.buttonCaption), callToActionUrl: this.toAstProperty(PropertyConfigKey.callToActionUrl, data.callToActionUrl), caption: this.handleJsonText(data.caption), quotedPerson: this.toAstProperty(PropertyConfigKey.quotedPerson, data.quotedPerson), reasonableNumOfChars: reasonableNumOfCharsProperty, resolved: this.toAstProperty(PropertyConfigKey.resolved, data.resolved), resolvedDate: this.toAstProperty(PropertyConfigKey.resolvedDate, data.resolvedDate), resolvedBy: this.toAstProperty(PropertyConfigKey.resolvedBy, data.resolvedBy), maxCreatedBits: this.toAstProperty(PropertyConfigKey.maxCreatedBits, data.maxCreatedBits), maxDisplayLevel: this.toAstProperty(PropertyConfigKey.maxDisplayLevel, data.maxDisplayLevel), page: this.toAstProperty(PropertyConfigKey.page, data.page), productId: this.toAstProperty(PropertyConfigKey.productId, data.productId), product: this.toAstProperty(PropertyConfigKey.product, data.product), productList: this.toAstProperty(PropertyConfigKey.productList, data.productList), productVideo: this.toAstProperty(PropertyConfigKey.productVideo, data.productVideo), productVideoList: this.toAstProperty(PropertyConfigKey.productVideoList, data.productVideoList), productFolder: this.toAstProperty(PropertyConfigKey.productFolder, data.productFolder), technicalTerm: this.buildTechnicalTerm(data.technicalTerm), servings: this.buildServings(data.servings), ratingLevelStart: this.buildRatingLevelStartEnd(data.ratingLevelStart), ratingLevelEnd: this.buildRatingLevelStartEnd(data.ratingLevelEnd), ratingLevelSelected: this.toAstProperty(PropertyConfigKey.ratingLevelSelected, data.ratingLevelSelected), markConfig: this.buildMarkConfigs(data.markConfig), imageSource: this.buildImageSource(data.imageSource), person: this.buildPerson(data.bitType, data.person), bot: this.toAstProperty(PropertyConfigKey.bot, data.bot), referenceProperty: this.toAstProperty(PropertyConfigKey.property_reference, data.referenceProperty),
65
+ // Book data
66
+ title: this.handleJsonText(data.title), subtitle: this.handleJsonText(data.subtitle), level: NumberUtils.asNumber(data.level), toc: this.toAstProperty(PropertyConfigKey.toc, data.toc), progress: this.toAstProperty(PropertyConfigKey.progress, data.progress), anchor: data.anchor, reference: data.reference, referenceEnd: data.referenceEnd,
67
+ // Item, Lead, Hint, Instruction
68
+ item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), pageNumber: this.handleJsonText(data.pageNumber), marginNumber: this.handleJsonText(data.marginNumber), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction), partialAnswer: this.toAstProperty(PropertyConfigKey.partialAnswer, data.partialAnswer), sampleSolution: this.toAstProperty(PropertyConfigKey.property_sampleSolution, data.sampleSolution), additionalSolutions: this.toAstProperty(PropertyConfigKey.additionalSolutions, data.additionalSolutions) }, this.toExample(data.__isDefaultExample, data.example)), {
69
+ // Person
70
+ // Body
71
+ body: this.buildBody(textFormat, data.body), imagePlaceholder: ArrayUtils.asSingle(this.resourceBuilder.resourceFromResourceDataJson(data.bitType, ResourceTag.image, (_b = data.imagePlaceholder) === null || _b === void 0 ? void 0 : _b.image)), resources: ArrayUtils.asArray(this.resourceBuilder.resourceFromResourceJson(data.bitType, data.resources)), cardNode, footer: this.buildFooter(data.footer), markup: data.markup, parser: data.parser,
72
72
  // Must always be last in the AST so key clashes are avoided correctly with other properties
73
- extraProperties: this.parseExtraProperties(extraProperties) });
73
+ extraProperties: this.parseExtraProperties(data.extraProperties),
74
+ // Private properties
75
+ __isDefaultExample: (_c = data.__isDefaultExample) !== null && _c !== void 0 ? _c : false });
74
76
  // Push reasonableNumOfChars down the tree for the interview bit
75
- if (Config.isOfBitType(bitType, BitType.interview)) {
76
- this.pushDownTree(undefined, undefined, cardNode, 'questions', PropertyConfigKey.reasonableNumOfChars, reasonableNumOfChars);
77
+ if (Config.isOfBitType(data.bitType, BitType.interview)) {
78
+ this.pushDownTree(undefined, undefined, cardNode, 'questions', PropertyConfigKey.reasonableNumOfChars, data.reasonableNumOfChars);
77
79
  }
78
80
  // Push isCaseSensitive down the tree for the cloze, match and match-matrix bits
79
- this.pushDownTree(body, [BodyBitType.gap], undefined, undefined, PropertyConfigKey.isCaseSensitive, isCaseSensitive);
80
- this.pushDownTree(undefined, undefined, cardNode, 'pairs', PropertyConfigKey.isCaseSensitive, isCaseSensitive);
81
- this.pushDownTree(undefined, undefined, cardNode, ['matrix', 'cells'], PropertyConfigKey.isCaseSensitive, isCaseSensitive);
82
- // If isDefaultExample is set at the bit level, push the default example down the tree to the relevant nodes
83
- this.pushExampleDownTree(body, cardNode, isDefaultExample, example);
81
+ this.pushDownTree([data.body, ...((_e = (_d = cardNode === null || cardNode === void 0 ? void 0 : cardNode.cardBits) === null || _d === void 0 ? void 0 : _d.map((cardBit) => cardBit.body)) !== null && _e !== void 0 ? _e : [])], [BodyBitType.gap], undefined, 'isCaseSensitive', PropertyConfigKey.isCaseSensitive, (_f = data.isCaseSensitive) !== null && _f !== void 0 ? _f : true);
82
+ this.pushDownTree(undefined, undefined, cardNode, 'pairs', PropertyConfigKey.isCaseSensitive, (_g = data.isCaseSensitive) !== null && _g !== void 0 ? _g : true);
83
+ this.pushDownTree(undefined, undefined, cardNode, ['matrix', 'cells'], PropertyConfigKey.isCaseSensitive, (_h = data.isCaseSensitive) !== null && _h !== void 0 ? _h : true);
84
+ // If __isDefaultExample is set at the bit level, push the default example down the tree to the relevant nodes
85
+ this.pushExampleDownTree(data.body, cardNode, data.__isDefaultExample, convertedExample.example);
84
86
  // Set default values
85
87
  this.setDefaultBitValues(node);
86
88
  // Set the 'isExample' flags
@@ -90,45 +92,88 @@ class Builder extends BaseBuilder {
90
92
  // Remove Unset Optionals
91
93
  ObjectUtils.removeUnwantedProperties(node, {
92
94
  ignoreAllFalse: true,
93
- ignoreEmptyString: ['example'],
95
+ ignoreUndefined: ['example'],
96
+ ignoreEmptyArrays: ['item', 'lead', 'pageNumber', 'marginNumber', 'hint', 'instruction'],
94
97
  });
95
98
  // Validate and correct invalid bits as much as possible
96
99
  return NodeValidator.validateBit(node);
97
100
  }
101
+ /**
102
+ * Build choice[] node
103
+ *
104
+ * @param data - data for the node
105
+ * @returns
106
+ */
107
+ buildChoices(data) {
108
+ if (!Array.isArray(data))
109
+ return undefined;
110
+ const nodes = data.map((d) => this.buildChoice(d)).filter((d) => d != null);
111
+ return nodes.length > 0 ? nodes : undefined;
112
+ }
98
113
  /**
99
114
  * Build choice node
100
115
  *
101
116
  * @param data - data for the node
102
117
  * @returns
103
118
  */
104
- choice(data) {
105
- const { text, isCorrect, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
119
+ buildChoice(data) {
120
+ var _a;
121
+ if (!data)
122
+ return undefined;
106
123
  // NOTE: Node order is important and is defined here
107
- const node = Object.assign({ text, isCorrect: !!isCorrect, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
108
- instruction }, this.toExampleBoolean(isDefaultExample, example));
124
+ const node = Object.assign({ choice: (_a = data.choice) !== null && _a !== void 0 ? _a : '', isCorrect: !!data.isCorrect, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, !!data.isCorrect));
109
125
  // Remove Unset Optionals
110
126
  ObjectUtils.removeUnwantedProperties(node, {
111
127
  ignoreAllFalse: true,
128
+ ignoreEmptyArrays: ['item', 'hint', 'instruction'],
129
+ ignoreUndefined: ['example'],
112
130
  });
113
131
  return node;
114
132
  }
133
+ /**
134
+ * Build response[] node
135
+ *
136
+ * @param data - data for the node
137
+ * @returns
138
+ */
139
+ buildResponses(data) {
140
+ if (!Array.isArray(data))
141
+ return undefined;
142
+ const nodes = data.map((d) => this.buildResponse(d)).filter((d) => d != null);
143
+ return nodes.length > 0 ? nodes : undefined;
144
+ }
115
145
  /**
116
146
  * Build response node
117
147
  *
118
148
  * @param data - data for the node
119
149
  * @returns
120
150
  */
121
- response(data) {
122
- const { text, isCorrect, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
151
+ buildResponse(data) {
152
+ var _a;
153
+ if (!data)
154
+ return undefined;
123
155
  // NOTE: Node order is important and is defined here
124
- const node = Object.assign({ text, isCorrect: !!isCorrect, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
125
- instruction }, this.toExampleBoolean(isDefaultExample, example));
156
+ const node = Object.assign({ response: (_a = data.response) !== null && _a !== void 0 ? _a : '', isCorrect: !!data.isCorrect, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, !!data.isCorrect));
126
157
  // Remove Unset Optionals
127
158
  ObjectUtils.removeUnwantedProperties(node, {
128
159
  ignoreAllFalse: true,
160
+ ignoreEmptyArrays: ['item', 'hint', 'instruction'],
161
+ ignoreUndefined: ['example'],
129
162
  });
130
163
  return node;
131
164
  }
165
+ /**
166
+ * Build bot response[] node
167
+ *
168
+ * @param data - data for the node
169
+ * @returns
170
+ */
171
+ buildBotResponses(data) {
172
+ if (!Array.isArray(data))
173
+ return undefined;
174
+ const nodes = data.map((d) => this.botResponse(d)).filter((d) => d != null);
175
+ return nodes.length > 0 ? nodes : undefined;
176
+ }
132
177
  /**
133
178
  * Build bot response node
134
179
  *
@@ -136,44 +181,79 @@ class Builder extends BaseBuilder {
136
181
  * @returns
137
182
  */
138
183
  botResponse(data) {
139
- const { response, reaction, feedback, item, lead, pageNumber, marginNumber, hint } = data;
184
+ var _a, _b, _c;
185
+ if (!data)
186
+ return undefined;
140
187
  // NOTE: Node order is important and is defined here
141
188
  const node = {
142
- response,
143
- reaction,
144
- feedback,
145
- itemLead: this.itemLead(item, lead, pageNumber, marginNumber),
146
- hint,
189
+ response: (_a = data.response) !== null && _a !== void 0 ? _a : '',
190
+ reaction: (_b = data.reaction) !== null && _b !== void 0 ? _b : '',
191
+ feedback: (_c = data.feedback) !== null && _c !== void 0 ? _c : '',
192
+ item: this.handleJsonText(data.item),
193
+ lead: this.handleJsonText(data.lead),
194
+ hint: this.handleJsonText(data.hint),
147
195
  };
148
196
  // Remove Unset Optionals
149
197
  ObjectUtils.removeUnwantedProperties(node, {
150
198
  ignoreEmptyString: ['response', 'reaction', 'feedback'],
199
+ ignoreAllFalse: true,
200
+ ignoreEmptyArrays: ['item'],
201
+ ignoreUndefined: ['example'],
151
202
  });
152
203
  return node;
153
204
  }
205
+ /**
206
+ * Build quiz[] node
207
+ *
208
+ * @param data - data for the node
209
+ * @returns
210
+ */
211
+ buildQuizzes(data) {
212
+ if (!Array.isArray(data))
213
+ return undefined;
214
+ const nodes = data.map((d) => this.buildQuiz(d)).filter((d) => d != null);
215
+ return nodes.length > 0 ? nodes : undefined;
216
+ }
154
217
  /**
155
218
  * Build quiz node
156
219
  *
157
220
  * @param data - data for the node
158
221
  * @returns
159
222
  */
160
- quiz(data) {
161
- const { choices, responses, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
162
- // Push isDefaultExample down the tree
163
- this.pushExampleDownTreeBoolean(isDefaultExample, example, true, choices);
164
- this.pushExampleDownTreeBoolean(isDefaultExample, example, false, responses);
223
+ buildQuiz(data) {
224
+ if (!data)
225
+ return undefined;
226
+ const convertedExample = Object.assign({}, this.toExample(data.__isDefaultExample, data.__defaultExample));
227
+ let choices;
228
+ let responses;
229
+ if (data.choices) {
230
+ choices = this.buildChoices(data.choices);
231
+ // Push __isDefaultExample down the tree
232
+ this.pushExampleDownTreeBoolean(data.__isDefaultExample, convertedExample.example, true, choices);
233
+ }
234
+ else if (data.responses) {
235
+ responses = this.buildResponses(data.responses);
236
+ // Push __isDefaultExample down the tree
237
+ this.pushExampleDownTreeBoolean(data.__isDefaultExample, convertedExample.example, false, responses);
238
+ }
239
+ else {
240
+ // No choices or responses, not a valid quiz
241
+ return undefined;
242
+ }
165
243
  // NOTE: Node order is important and is defined here
166
244
  const node = {
167
- itemLead: this.itemLead(item, lead, pageNumber, marginNumber),
168
- hint,
169
- instruction,
170
- isExample: isDefaultExample || example != null,
171
- choices,
172
- responses,
245
+ item: this.handleJsonText(data.item),
246
+ lead: this.handleJsonText(data.lead),
247
+ hint: this.handleJsonText(data.hint),
248
+ instruction: this.handleJsonText(data.instruction),
249
+ isExample: !!data.__defaultExample,
250
+ choices: choices,
251
+ responses: responses,
173
252
  };
174
253
  // Remove Unset Optionals
175
254
  ObjectUtils.removeUnwantedProperties(node, {
176
255
  ignoreAllFalse: true,
256
+ ignoreEmptyArrays: ['item', 'hint', 'instruction'],
177
257
  });
178
258
  return node;
179
259
  }
@@ -183,69 +263,126 @@ class Builder extends BaseBuilder {
183
263
  * @param data - data for the node
184
264
  * @returns
185
265
  */
186
- heading(data) {
187
- var _a;
188
- const { forKeys, forValues } = data;
189
- if (forKeys == null)
266
+ buildHeading(data) {
267
+ var _a, _b, _c;
268
+ if (!data)
269
+ return undefined;
270
+ if (data.forKeys == null)
190
271
  return undefined;
191
272
  // NOTE: Node order is important and is defined here
192
273
  const node = {
193
- forKeys: forKeys || Breakscape.EMPTY_STRING,
194
- forValues: (_a = ArrayUtils.asArray(forValues)) !== null && _a !== void 0 ? _a : [],
274
+ forKeys: (_a = data.forKeys) !== null && _a !== void 0 ? _a : '',
275
+ forValues: (_c = (_b = data.forValues) !== null && _b !== void 0 ? _b : data.__forValuesDefault) !== null && _c !== void 0 ? _c : '',
195
276
  };
196
277
  // Remove Unset Optionals
197
- // ObjectUtils.removeUnwantedProperties(node);
278
+ ObjectUtils.removeUnwantedProperties(node, {
279
+ ignoreAllFalse: true,
280
+ ignoreEmptyString: ['forKeys', 'forValues'],
281
+ ignoreEmptyArrays: ['forValues'],
282
+ });
198
283
  return node;
199
284
  }
285
+ /**
286
+ * Build pair[] node
287
+ *
288
+ * @param data - data for the node
289
+ * @returns
290
+ */
291
+ buildPairs(bitType, data) {
292
+ if (!Array.isArray(data))
293
+ return undefined;
294
+ const nodes = data.map((d) => this.buildPair(bitType, d)).filter((d) => d != null);
295
+ return nodes.length > 0 ? nodes : undefined;
296
+ }
200
297
  /**
201
298
  * Build pair node
202
299
  *
203
300
  * @param data - data for the node
204
301
  * @returns
205
302
  */
206
- pair(data) {
207
- const { key, keyAudio, keyImage, values, item, lead, pageNumber, marginNumber, hint, instruction, isCaseSensitive, isDefaultExample, example, } = data;
303
+ buildPair(bitType, data) {
304
+ var _a, _b, _c, _d;
305
+ if (!data)
306
+ return undefined;
307
+ // Set default example
308
+ const defaultExample = Array.isArray(data.__valuesAst) && data.__valuesAst.length > 0 ? data.__valuesAst[0] : null;
309
+ // Process the keyAudio and keyImage resources
310
+ const keyAudio = (_a = ArrayUtils.asSingle(this.resourceBuilder.resourceFromResourceDataJson(bitType, ResourceTag.audio, data.keyAudio))) === null || _a === void 0 ? void 0 : _a.audio;
311
+ const keyImage = (_b = ArrayUtils.asSingle(this.resourceBuilder.resourceFromResourceDataJson(bitType, ResourceTag.image, data.keyImage))) === null || _b === void 0 ? void 0 : _b.image;
208
312
  // NOTE: Node order is important and is defined here
209
- const node = Object.assign(Object.assign({ key,
210
- keyAudio,
211
- keyImage, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
212
- instruction }, this.toExample(isDefaultExample, example)), { isCaseSensitive,
213
- values });
313
+ const node = Object.assign(Object.assign({ key: (_c = data.key) !== null && _c !== void 0 ? _c : '', keyAudio,
314
+ keyImage, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction), isCaseSensitive: data.isCaseSensitive }, this.toExample(data.__isDefaultExample, data.example, defaultExample)), { values: (_d = data.values) !== null && _d !== void 0 ? _d : [], __valuesAst: data.__valuesAst });
214
315
  // Remove Unset Optionals
215
316
  ObjectUtils.removeUnwantedProperties(node, {
216
317
  ignoreAllFalse: true,
318
+ ignoreEmptyArrays: ['item', 'hint', 'instruction', 'values'],
319
+ ignoreUndefined: ['example', 'isCaseSensitive'],
217
320
  });
321
+ // if (node.key) {
322
+ // delete node.keyAudio;
323
+ // delete node.keyImage;
324
+ // }
325
+ // if (node.keyAudio != null) {
326
+ // delete node.key;
327
+ // delete node.keyImage;
328
+ // }
329
+ // if (node.keyImage != null) {
330
+ // delete node.key;
331
+ // delete node.keyAudio;
332
+ // }
218
333
  return node;
219
334
  }
335
+ /**
336
+ * Build matrix[] node
337
+ *
338
+ * @param data - data for the node
339
+ * @returns
340
+ */
341
+ buildMatricies(data) {
342
+ if (!Array.isArray(data))
343
+ return undefined;
344
+ const nodes = data.map((d) => this.buildMatrix(d)).filter((d) => d != null);
345
+ return nodes.length > 0 ? nodes : undefined;
346
+ }
220
347
  /**
221
348
  * Build matrix node
222
349
  *
223
350
  * @param data - data for the node
224
351
  * @returns
225
352
  */
226
- matrix(data) {
227
- const { key, cells, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample } = data;
353
+ buildMatrix(data) {
354
+ var _a, _b, _c;
355
+ if (!data)
356
+ return undefined;
357
+ // const convertedExample = {
358
+ // ...this.toExample(__isDefaultExample, example),
359
+ // };
360
+ // // Push __isDefaultExample down the tree
361
+ // this.pushExampleDownTreeBoolean(__isDefaultExample, convertedExample.example, true, choices);
362
+ // this.pushExampleDownTreeBoolean(__isDefaultExample, convertedExample.example, false, responses);
228
363
  let isExample = false;
229
364
  // Set isExample for matrix based on isExample for cells
230
- for (const c of cells !== null && cells !== void 0 ? cells : []) {
231
- if (isDefaultExample && !c.isExample) {
232
- c.isDefaultExample = true;
365
+ for (const c of (_a = data.cells) !== null && _a !== void 0 ? _a : []) {
366
+ if (data.__isDefaultExample && !c.isExample) {
233
367
  c.isExample = true;
234
368
  }
235
369
  isExample = c.isExample ? true : isExample;
236
370
  }
237
371
  // NOTE: Node order is important and is defined here
238
372
  const node = {
239
- key,
240
- itemLead: this.itemLead(item, lead, pageNumber, marginNumber),
241
- hint,
242
- instruction,
373
+ key: (_b = data.key) !== null && _b !== void 0 ? _b : '',
374
+ item: this.handleJsonText(data.item),
375
+ lead: this.handleJsonText(data.lead),
376
+ hint: this.handleJsonText(data.hint),
377
+ instruction: this.handleJsonText(data.instruction),
243
378
  isExample,
244
- cells,
379
+ cells: ((_c = data.cells) !== null && _c !== void 0 ? _c : []).map((c) => this.buildMatrixCell(c)).filter((c) => c != null),
245
380
  };
246
381
  // Remove Unset Optionals
247
382
  ObjectUtils.removeUnwantedProperties(node, {
248
383
  ignoreAllFalse: true,
384
+ ignoreEmptyArrays: ['hint', 'item', 'cells'],
385
+ ignoreUndefined: ['isCaseSensitive'],
249
386
  });
250
387
  return node;
251
388
  }
@@ -255,15 +392,19 @@ class Builder extends BaseBuilder {
255
392
  * @param data - data for the node
256
393
  * @returns
257
394
  */
258
- matrixCell(data) {
259
- const { values, item, lead, pageNumber, marginNumber, hint, instruction, isCaseSensitive, isDefaultExample, example, } = data;
395
+ buildMatrixCell(data) {
396
+ var _a;
397
+ if (!data)
398
+ return undefined;
399
+ // Set default example
400
+ const defaultExample = Array.isArray(data.__valuesAst) && data.__valuesAst.length > 0 ? data.__valuesAst[0] : null;
260
401
  // NOTE: Node order is important and is defined here
261
- const node = Object.assign({ values, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
262
- instruction,
263
- isCaseSensitive }, this.toExample(isDefaultExample, example));
402
+ const node = Object.assign(Object.assign({ values: (_a = data.values) !== null && _a !== void 0 ? _a : [], item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction), isCaseSensitive: data.isCaseSensitive }, this.toExample(data.__isDefaultExample, data.example, defaultExample)), { __valuesAst: data.__valuesAst });
264
403
  // Remove Unset Optionals
265
404
  ObjectUtils.removeUnwantedProperties(node, {
266
405
  ignoreAllFalse: true,
406
+ ignoreEmptyArrays: ['instruction', 'item', 'values'],
407
+ ignoreUndefined: ['example', 'isCaseSensitive'],
267
408
  });
268
409
  return node;
269
410
  }
@@ -273,12 +414,14 @@ class Builder extends BaseBuilder {
273
414
  * @param data - data for the node
274
415
  * @returns
275
416
  */
276
- table(data) {
277
- const { columns, rows } = data;
417
+ buildTable(dataIn) {
418
+ var _a, _b;
419
+ if (!dataIn)
420
+ return undefined;
278
421
  // NOTE: Node order is important and is defined here
279
422
  const node = {
280
- columns,
281
- rows,
423
+ columns: (_a = dataIn.columns) !== null && _a !== void 0 ? _a : [],
424
+ data: ((_b = dataIn.data) !== null && _b !== void 0 ? _b : []).map((row) => row !== null && row !== void 0 ? row : []),
282
425
  };
283
426
  // Remove Unset Optionals
284
427
  // ObjectUtils.removeUnwantedProperties(node, {
@@ -286,81 +429,235 @@ class Builder extends BaseBuilder {
286
429
  // });
287
430
  return node;
288
431
  }
432
+ /**
433
+ * Build question[] node
434
+ *
435
+ * @param data - data for the node
436
+ * @returns
437
+ */
438
+ buildQuestions(data) {
439
+ if (!Array.isArray(data))
440
+ return undefined;
441
+ const nodes = data.map((d) => this.buildQuestion(d)).filter((d) => d != null);
442
+ return nodes.length > 0 ? nodes : undefined;
443
+ }
289
444
  /**
290
445
  * Build question node
291
446
  *
292
447
  * @param data - data for the node
293
448
  * @returns
294
449
  */
295
- question(data) {
296
- const { question, partialAnswer, item, lead, pageNumber, marginNumber, hint, instruction, reasonableNumOfChars, sampleSolution, additionalSolutions, isDefaultExample, example, } = data;
450
+ buildQuestion(data) {
451
+ var _a, _b, _c, _d, _e;
452
+ if (!data)
453
+ return undefined;
454
+ // Set default example
455
+ const defaultExample = data.__sampleSolutionAst;
297
456
  // NOTE: Node order is important and is defined here
298
- const node = Object.assign(Object.assign({ itemLead: this.itemLead(item, lead, pageNumber, marginNumber), question,
299
- partialAnswer,
300
- hint,
301
- instruction }, this.toExample(isDefaultExample, example)), { reasonableNumOfChars,
302
- sampleSolution,
303
- additionalSolutions });
457
+ const node = Object.assign(Object.assign({ question: (_a = data.question) !== null && _a !== void 0 ? _a : '', partialAnswer: (_b = data.partialAnswer) !== null && _b !== void 0 ? _b : '', sampleSolution: (_c = data.sampleSolution) !== null && _c !== void 0 ? _c : '', additionalSolutions: ((_d = data.additionalSolutions) !== null && _d !== void 0 ? _d : undefined), reasonableNumOfChars: ((_e = data.reasonableNumOfChars) !== null && _e !== void 0 ? _e : undefined), item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, defaultExample)), { __sampleSolutionAst: data.__sampleSolutionAst });
304
458
  // Remove Unset Optionals
305
459
  ObjectUtils.removeUnwantedProperties(node, {
306
- ignoreEmptyString: ['question'],
307
460
  ignoreAllFalse: true,
461
+ ignoreEmptyArrays: ['item', 'hint', 'instruction'],
462
+ ignoreUndefined: ['example'],
463
+ ignoreEmptyString: ['question', 'partialAnswer', 'sampleSolution'],
308
464
  });
309
465
  return node;
310
466
  }
467
+ /**
468
+ * Build ingredient[] node
469
+ *
470
+ * @param data - data for the node
471
+ * @returns
472
+ */
473
+ buildIngredients(data) {
474
+ if (!Array.isArray(data))
475
+ return undefined;
476
+ const nodes = data.map((d) => this.buildIngredient(d)).filter((d) => d != null);
477
+ return nodes.length > 0 ? nodes : undefined;
478
+ }
311
479
  /**
312
480
  * Build ingredient node
313
481
  *
314
482
  * @param data - data for the node
315
483
  * @returns
316
484
  */
317
- ingredient(data) {
318
- const { title, checked, item, quantity, unit, unitAbbr, decimalPlaces, disableCalculation } = data;
485
+ buildIngredient(data) {
486
+ var _a, _b, _c, _d, _e, _f, _g, _h;
487
+ if (!data)
488
+ return undefined;
319
489
  // NOTE: Node order is important and is defined here
320
490
  const node = {
321
- title,
322
- checked: checked !== null && checked !== void 0 ? checked : false,
323
- item,
324
- quantity,
325
- unit,
326
- unitAbbr,
327
- decimalPlaces,
328
- disableCalculation,
491
+ title: (_a = data.title) !== null && _a !== void 0 ? _a : '',
492
+ checked: (_b = data.checked) !== null && _b !== void 0 ? _b : false,
493
+ item: (_c = data.item) !== null && _c !== void 0 ? _c : '',
494
+ quantity: (_d = data.quantity) !== null && _d !== void 0 ? _d : 0,
495
+ unit: (_e = data.unit) !== null && _e !== void 0 ? _e : '',
496
+ unitAbbr: (_f = data.unitAbbr) !== null && _f !== void 0 ? _f : '',
497
+ decimalPlaces: (_g = data.decimalPlaces) !== null && _g !== void 0 ? _g : 1,
498
+ disableCalculation: (_h = data.disableCalculation) !== null && _h !== void 0 ? _h : false,
329
499
  };
330
500
  // Remove Unset Optionals
331
501
  ObjectUtils.removeUnwantedProperties(node, {
332
502
  ignoreAllFalse: true,
503
+ // ignoreAllEmptyArrays: true,
504
+ // ignoreUndefined: ['example'],
505
+ ignoreEmptyString: ['item', 'unit'],
333
506
  });
334
507
  return node;
335
508
  }
336
509
  /**
337
510
  * Build body node
511
+ * - Handles JSON, Bitmark text, and plain text
512
+ * - body: set to either string, TextAst, or JSON
513
+ * - bodyBits: set to array of BodyBitJson (will be validated and merged into body if it is a string)
514
+ * - placeholders: set to placeholders from v2 JSON when body is a v2 JSON string
515
+ * - bodyString: set to the original string if body is a string (only used for card body)
338
516
  *
339
517
  * @param data - data for the node
340
518
  * @returns
341
519
  */
342
- body(data) {
343
- const { bodyParts, bodyJson } = data;
344
- const node = {
345
- bodyParts,
346
- bodyJson,
520
+ buildBody(textFormat, data) {
521
+ if (!data)
522
+ return undefined;
523
+ let body;
524
+ const bodyBits = [];
525
+ const placeholders = data.placeholders;
526
+ const bodyString = data.bodyString;
527
+ // Handle JSON type body
528
+ const handleJsonBody = () => {
529
+ // Attempt to parse a string body as JSON to support the legacy format
530
+ if (typeof data.body === 'string') {
531
+ try {
532
+ body = JSON.parse(data.body);
533
+ }
534
+ catch (e) {
535
+ // Could not parse JSON - set body to null
536
+ body = null;
537
+ }
538
+ }
539
+ else {
540
+ body = data.body;
541
+ }
347
542
  };
348
- return node;
349
- }
350
- /**
351
- * Build bodyPartText node
352
- *
353
- * @param data - data for the node
354
- * @returns
355
- */
356
- bodyText(data) {
357
- const { text } = data;
358
- // NOTE: Node order is important and is defined here
543
+ // Handle Bitmark text type body (both AST v3 and plain text v2)
544
+ const handleBitmarkTextBody = () => {
545
+ var _a;
546
+ let rawBody = data.body;
547
+ let bodyStr;
548
+ const placeholderNodes = {};
549
+ // TODO - process body bits through the correct builders.
550
+ if (StringUtils.isString(data.body)) {
551
+ // Body is a string (legacy bitmark v2, or not bitmark--/++)
552
+ bodyStr = ((_a = data.body) !== null && _a !== void 0 ? _a : '').trim();
553
+ rawBody = [];
554
+ }
555
+ else if (Array.isArray(data.body)) {
556
+ // Body is an array (prosemirror like JSON)
557
+ // Already in the correct format
558
+ }
559
+ else {
560
+ // body is invalid
561
+ rawBody = [];
562
+ }
563
+ if (placeholders) {
564
+ for (const [key, val] of Object.entries(placeholders)) {
565
+ // const bit = this.bodyBitToAst(val);
566
+ // placeholderNodes[key] = bit as BodyBit;
567
+ placeholderNodes[key] = val;
568
+ }
569
+ }
570
+ if (bodyStr) {
571
+ // Breakscape
572
+ bodyStr = Breakscape.breakscape(bodyStr, {
573
+ textFormat: TextFormat.bitmarkMinusMinus, // Treat as bitmark-- for v2 text
574
+ });
575
+ // Convert placeholders {1} to [!1], etc.
576
+ let index = 0;
577
+ const newPlaceholderNodes = [];
578
+ for (const [key, val] of Object.entries(placeholderNodes)) {
579
+ if (bodyStr) {
580
+ const newKey = `[!${index}]`;
581
+ bodyStr = bodyStr.replace(`${key}`, newKey);
582
+ newPlaceholderNodes.push(val);
583
+ index++;
584
+ }
585
+ }
586
+ // Convert the body string to AST
587
+ rawBody = this.textParser.toAst(bodyStr, {
588
+ textFormat: TextFormat.bitmarkMinusMinus, // Treat as bitmark-- for v2 text
589
+ });
590
+ const replaceBitsRecursive = (bodyText) => {
591
+ for (let i = 0, len = bodyText.length; i < len; i++) {
592
+ const bodyPart = bodyText[i];
593
+ if (bodyPart.type === 'bit') {
594
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
595
+ const index = bodyPart.index;
596
+ if (newPlaceholderNodes[index] != null) {
597
+ bodyText[i] = newPlaceholderNodes[index];
598
+ }
599
+ }
600
+ else {
601
+ if (bodyPart.content)
602
+ replaceBitsRecursive(bodyPart.content);
603
+ }
604
+ }
605
+ };
606
+ // Replace the placeholders with the AST
607
+ replaceBitsRecursive(rawBody);
608
+ }
609
+ // Process the body bits to ensure they are valid
610
+ this.textParser.walkBodyBits(rawBody, (parent, index, bodyBit) => {
611
+ // Ensure the body bit is valid
612
+ let parsedBit;
613
+ switch (bodyBit.type) {
614
+ case BodyBitType.gap:
615
+ parsedBit = this.buildGap(bodyBit);
616
+ break;
617
+ case BodyBitType.mark:
618
+ parsedBit = this.buildMark(bodyBit);
619
+ break;
620
+ case BodyBitType.select:
621
+ parsedBit = this.buildSelect(bodyBit);
622
+ break;
623
+ case BodyBitType.highlight:
624
+ parsedBit = this.buildHighlight(bodyBit);
625
+ break;
626
+ default:
627
+ // TODO?? Ensure other parts are valid
628
+ }
629
+ if (parsedBit != undefined) {
630
+ parent[index] = parsedBit;
631
+ bodyBits.push(parsedBit);
632
+ }
633
+ });
634
+ // Set the body
635
+ body = rawBody;
636
+ // Mark the body as text
637
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
638
+ body.__tag = 'text';
639
+ };
640
+ const handlePlainTextBody = () => {
641
+ body = data.body;
642
+ };
643
+ const isBitmarkText = textFormat === TextFormat.bitmarkMinusMinus || textFormat === TextFormat.bitmarkPlusPlus;
644
+ if (textFormat === TextFormat.json) {
645
+ // JSON
646
+ handleJsonBody();
647
+ }
648
+ else if (isBitmarkText) {
649
+ // Bitmark text (either ast or string)
650
+ handleBitmarkTextBody();
651
+ }
652
+ else {
653
+ // Text but not bitmark (plain text)
654
+ handlePlainTextBody();
655
+ }
359
656
  const node = {
360
- type: BodyBitType.text,
361
- data: {
362
- bodyText: text,
363
- },
657
+ body,
658
+ bodyBits,
659
+ bodyString,
660
+ // Placeholders are only ever parsed into AST, never stored directly
364
661
  };
365
662
  return node;
366
663
  }
@@ -370,11 +667,11 @@ class Builder extends BaseBuilder {
370
667
  * @param data - data for the node
371
668
  * @returns
372
669
  */
373
- footerText(data) {
374
- const { text } = data;
375
- // NOTE: Node order is important and is defined here
670
+ buildFooter(data) {
671
+ if (!data)
672
+ return undefined;
376
673
  const node = {
377
- footerText: text,
674
+ footer: this.handleJsonText(data.footer),
378
675
  };
379
676
  return node;
380
677
  }
@@ -384,38 +681,54 @@ class Builder extends BaseBuilder {
384
681
  * @param data - data for the node
385
682
  * @returns
386
683
  */
387
- gap(data) {
388
- const { solutions, item, lead, pageNumber, marginNumber, hint, instruction, isCaseSensitive, isDefaultExample, example, } = data;
389
- // const defaultExample = Array.isArray(solutions) && solutions.length === 1 ? solutions[0] : null;
684
+ buildGap(data) {
685
+ var _a;
686
+ if (!data)
687
+ return undefined;
688
+ // Set default example
689
+ const defaultExample = Array.isArray(data.__solutionsAst) && data.__solutionsAst.length > 0 ? data.__solutionsAst[0] : null;
390
690
  // NOTE: Node order is important and is defined here
391
- const node = {
392
- type: BodyBitType.gap,
393
- data: Object.assign({ solutions, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
394
- instruction,
395
- isCaseSensitive }, this.toExample(isDefaultExample, example)),
396
- };
691
+ const node = Object.assign(Object.assign({ type: BodyBitType.gap, solutions: (_a = data.solutions) !== null && _a !== void 0 ? _a : [], item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction), isCaseSensitive: data.isCaseSensitive }, this.toExample(data.__isDefaultExample, data.example, defaultExample)), { __solutionsAst: data.__solutionsAst });
397
692
  // Remove Unset Optionals
398
693
  ObjectUtils.removeUnwantedProperties(node, {
399
694
  ignoreAllFalse: true,
695
+ ignoreAllEmptyArrays: true,
696
+ ignoreUndefined: ['example', 'isCaseSensitive'],
400
697
  });
401
698
  return node;
402
699
  }
700
+ /**
701
+ * Build mark configs node
702
+ *
703
+ * @param data - data for the node
704
+ * @returns
705
+ */
706
+ buildMarkConfigs(data) {
707
+ if (!Array.isArray(data))
708
+ return undefined;
709
+ const nodes = data.map((d) => this.buildMarkConfig(d)).filter((d) => d != null);
710
+ return nodes.length > 0 ? nodes : undefined;
711
+ }
403
712
  /**
404
713
  * Build mark config node
405
714
  *
406
715
  * @param data - data for the node
407
716
  * @returns
408
717
  */
409
- markConfig(data) {
410
- const { mark, color, emphasis } = data;
718
+ buildMarkConfig(data) {
719
+ var _a, _b, _c;
720
+ if (!data)
721
+ return undefined;
411
722
  // NOTE: Node order is important and is defined here
412
723
  const node = {
413
- mark,
414
- color,
415
- emphasis,
724
+ mark: (_a = data.mark) !== null && _a !== void 0 ? _a : 'unknown',
725
+ color: (_b = data.color) !== null && _b !== void 0 ? _b : '',
726
+ emphasis: (_c = data.emphasis) !== null && _c !== void 0 ? _c : '',
416
727
  };
417
728
  // Remove Unset Optionals
418
- ObjectUtils.removeUnwantedProperties(node);
729
+ ObjectUtils.removeUnwantedProperties(node, {
730
+ ignoreAllEmptyString: true,
731
+ });
419
732
  return node;
420
733
  }
421
734
  /**
@@ -424,17 +737,19 @@ class Builder extends BaseBuilder {
424
737
  * @param data - data for the node
425
738
  * @returns
426
739
  */
427
- mark(data) {
428
- const { solution, mark, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
740
+ buildMark(data) {
741
+ var _a, _b;
742
+ if (!data)
743
+ return undefined;
429
744
  // NOTE: Node order is important and is defined here
430
- const node = {
431
- type: BodyBitType.mark,
432
- data: Object.assign({ solution,
433
- mark, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
434
- instruction }, this.toExample(isDefaultExample, example)),
435
- };
745
+ const node = Object.assign({ type: BodyBitType.mark, solution: (_a = data.solution) !== null && _a !== void 0 ? _a : '', mark: (_b = data.mark) !== null && _b !== void 0 ? _b : '', item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, true));
436
746
  // Remove Unset Optionals
437
- ObjectUtils.removeUnwantedProperties(node);
747
+ ObjectUtils.removeUnwantedProperties(node, {
748
+ ignoreAllFalse: true,
749
+ ignoreAllEmptyArrays: true,
750
+ ignoreUndefined: ['example'],
751
+ ignoreEmptyString: ['solution', 'mark'],
752
+ });
438
753
  return node;
439
754
  }
440
755
  /**
@@ -443,40 +758,49 @@ class Builder extends BaseBuilder {
443
758
  * @param data - data for the node
444
759
  * @returns
445
760
  */
446
- select(data) {
447
- const { options, prefix, postfix, item, lead, pageNumber, marginNumber, hint, instruction } = data;
761
+ buildSelect(data) {
762
+ var _a, _b, _c;
763
+ if (!data)
764
+ return undefined;
448
765
  // NOTE: Node order is important and is defined here
449
- const node = {
450
- type: BodyBitType.select,
451
- data: {
452
- prefix,
453
- options,
454
- postfix,
455
- itemLead: this.itemLead(item, lead, pageNumber, marginNumber),
456
- hint,
457
- instruction,
458
- },
459
- };
766
+ const node = Object.assign(Object.assign({ type: BodyBitType.select, options: (_a = this.buildSelectOptions(data.options)) !== null && _a !== void 0 ? _a : [], prefix: (_b = data.prefix) !== null && _b !== void 0 ? _b : '', postfix: (_c = data.postfix) !== null && _c !== void 0 ? _c : '', item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(false, undefined, undefined)), { __hintString: data.__hintString, __instructionString: data.__instructionString });
460
767
  // Remove Unset Optionals
461
768
  ObjectUtils.removeUnwantedProperties(node, {
462
769
  ignoreAllFalse: true,
770
+ ignoreAllEmptyArrays: true,
771
+ ignoreEmptyString: ['prefix', 'postfix'],
463
772
  });
464
773
  return node;
465
774
  }
775
+ /**
776
+ * Build selectOption[] node
777
+ *
778
+ * @param data - data for the node
779
+ * @returns
780
+ */
781
+ buildSelectOptions(data) {
782
+ if (!Array.isArray(data))
783
+ return undefined;
784
+ const nodes = data.map((d) => this.buildSelectOption(d)).filter((d) => d != null);
785
+ return nodes.length > 0 ? nodes : undefined;
786
+ }
466
787
  /**
467
788
  * Build selectOption node
468
789
  *
469
790
  * @param data - data for the node
470
791
  * @returns
471
792
  */
472
- selectOption(data) {
473
- const { text, isCorrect, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
793
+ buildSelectOption(data) {
794
+ var _a;
795
+ if (!data)
796
+ return undefined;
474
797
  // NOTE: Node order is important and is defined here
475
- const node = Object.assign({ text, isCorrect: !!isCorrect, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
476
- instruction }, this.toExample(isDefaultExample, example));
798
+ const node = Object.assign({ text: (_a = data.text) !== null && _a !== void 0 ? _a : '', isCorrect: !!data.isCorrect, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, !!data.isCorrect));
477
799
  // Remove Unset Optionals
478
800
  ObjectUtils.removeUnwantedProperties(node, {
479
801
  ignoreAllFalse: true,
802
+ ignoreAllEmptyArrays: true,
803
+ ignoreUndefined: ['example'],
480
804
  });
481
805
  return node;
482
806
  }
@@ -486,95 +810,143 @@ class Builder extends BaseBuilder {
486
810
  * @param data - data for the node
487
811
  * @returns
488
812
  */
489
- highlight(data) {
490
- const { texts, prefix, postfix, item, lead, pageNumber, marginNumber, hint, instruction } = data;
813
+ buildHighlight(data) {
814
+ var _a, _b, _c;
815
+ if (!data)
816
+ return undefined;
491
817
  // NOTE: Node order is important and is defined here
492
- const node = {
493
- type: BodyBitType.highlight,
494
- data: {
495
- prefix,
496
- texts,
497
- postfix,
498
- itemLead: this.itemLead(item, lead, pageNumber, marginNumber),
499
- hint,
500
- instruction,
501
- },
502
- };
818
+ const node = Object.assign({ type: BodyBitType.highlight, texts: (_a = this.buildHighlightTexts(data.texts)) !== null && _a !== void 0 ? _a : [], prefix: (_b = data.prefix) !== null && _b !== void 0 ? _b : '', postfix: (_c = data.postfix) !== null && _c !== void 0 ? _c : '', item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(false, undefined, undefined));
503
819
  // Remove Unset Optionals
504
820
  ObjectUtils.removeUnwantedProperties(node, {
505
821
  ignoreAllFalse: true,
822
+ ignoreAllEmptyArrays: true,
823
+ ignoreEmptyString: ['prefix', 'postfix'],
506
824
  });
507
825
  return node;
508
826
  }
827
+ /**
828
+ * Build highlightText[] node
829
+ *
830
+ * @param data - data for the node
831
+ * @returns
832
+ */
833
+ buildHighlightTexts(data) {
834
+ if (!Array.isArray(data))
835
+ return undefined;
836
+ const nodes = data.map((d) => this.buildHighlightText(d)).filter((d) => d != null);
837
+ return nodes.length > 0 ? nodes : undefined;
838
+ }
509
839
  /**
510
840
  * Build highlightText node
511
841
  *
512
842
  * @param data - data for the node
513
843
  * @returns
514
844
  */
515
- highlightText(data) {
516
- const { text, isCorrect, isHighlighted, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example, } = data;
845
+ buildHighlightText(data) {
846
+ var _a;
847
+ if (!data)
848
+ return undefined;
517
849
  // NOTE: Node order is important and is defined here
518
- const node = Object.assign({ text, isCorrect: !!isCorrect, isHighlighted: !!isHighlighted, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
519
- instruction }, this.toExample(isDefaultExample, example));
850
+ const node = Object.assign({ text: (_a = data.text) !== null && _a !== void 0 ? _a : '', isCorrect: !!data.isCorrect, isHighlighted: !!data.isHighlighted, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, !!data.isCorrect));
520
851
  // Remove Unset Optionals
521
852
  ObjectUtils.removeUnwantedProperties(node, {
522
853
  ignoreAllFalse: true,
854
+ ignoreAllEmptyArrays: true,
855
+ ignoreUndefined: ['example'],
523
856
  });
524
857
  return node;
525
858
  }
859
+ /**
860
+ * Build flashcards node
861
+ *
862
+ * @param data - data for the node
863
+ * @returns
864
+ */
865
+ buildFlashcards(data) {
866
+ if (!Array.isArray(data))
867
+ return undefined;
868
+ const nodes = data.map((d) => this.buildFlashcard(d)).filter((d) => d != null);
869
+ return nodes.length > 0 ? nodes : undefined;
870
+ }
526
871
  /**
527
872
  * Build flashcard node
528
873
  *
529
874
  * @param data - data for the node
530
875
  * @returns
531
876
  */
532
- flashcard(data) {
533
- const { question, answer, alternativeAnswers, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example, } = data;
877
+ buildFlashcard(data) {
878
+ if (!data)
879
+ return undefined;
534
880
  // NOTE: Node order is important and is defined here
535
- const node = Object.assign({ question,
536
- answer,
537
- alternativeAnswers, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
538
- instruction }, this.toExampleBoolean(isDefaultExample, example));
881
+ const node = Object.assign({ question: this.handleJsonText(data.question), answer: this.handleJsonText(data.answer), alternativeAnswers: this.handleJsonText(data.alternativeAnswers), item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, true));
539
882
  // Remove Unset Optionals
540
883
  ObjectUtils.removeUnwantedProperties(node, {
541
884
  ignoreAllFalse: true,
885
+ ignoreEmptyArrays: ['question', 'answer', 'alternativeAnswers', 'item', 'hint', 'instruction'],
886
+ ignoreUndefined: ['example'],
542
887
  });
543
888
  return node;
544
889
  }
890
+ /**
891
+ * Build definitionListItem[] node
892
+ *
893
+ * @param data - data for the node
894
+ * @returns
895
+ */
896
+ buildDefinitionList(data) {
897
+ if (!Array.isArray(data))
898
+ return undefined;
899
+ const nodes = data.map((d) => this.buildDefinitionListItem(d)).filter((d) => d != null);
900
+ return nodes.length > 0 ? nodes : undefined;
901
+ }
545
902
  /**
546
903
  * Build definitionListItem node
547
904
  *
548
905
  * @param data - data for the node
549
906
  * @returns
550
907
  */
551
- definitionListItem(data) {
552
- const { term, description, alternativeDefinitions, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example, } = data;
908
+ buildDefinitionListItem(data) {
909
+ if (!data)
910
+ return undefined;
553
911
  // NOTE: Node order is important and is defined here
554
- const node = Object.assign({ term,
555
- description,
556
- alternativeDefinitions, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
557
- instruction }, this.toExampleBoolean(isDefaultExample, example));
912
+ const node = Object.assign({ term: this.handleJsonText(data.term, TextFormat.bitmarkMinusMinus), definition: this.handleJsonText(data.definition), alternativeDefinitions: this.handleJsonText(data.alternativeDefinitions), item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, true));
558
913
  // Remove Unset Optionals
559
914
  ObjectUtils.removeUnwantedProperties(node, {
560
915
  ignoreAllFalse: true,
916
+ ignoreEmptyArrays: ['question', 'answer', 'alternativeDefinitions', 'item', 'hint', 'instruction'],
917
+ ignoreUndefined: ['example'],
561
918
  });
562
919
  return node;
563
920
  }
921
+ /**
922
+ * Build statement[] node
923
+ *
924
+ * @param data - data for the node
925
+ * @returns
926
+ */
927
+ buildStatements(data) {
928
+ if (!Array.isArray(data))
929
+ return undefined;
930
+ const nodes = data.map((d) => this.buildStatement(d)).filter((d) => d != null);
931
+ return nodes.length > 0 ? nodes : undefined;
932
+ }
564
933
  /**
565
934
  * Build statement node
566
935
  *
567
936
  * @param data - data for the node
568
937
  * @returns
569
938
  */
570
- statement(data) {
571
- const { text, isCorrect, item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example } = data;
939
+ buildStatement(data) {
940
+ var _a;
941
+ if (!data)
942
+ return undefined;
572
943
  // NOTE: Node order is important and is defined here
573
- const node = Object.assign({ text, isCorrect: !!isCorrect, itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
574
- instruction }, this.toExampleBoolean(isDefaultExample, example));
944
+ const node = Object.assign({ statement: (_a = data.statement) !== null && _a !== void 0 ? _a : '', isCorrect: !!data.isCorrect, item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example, !!data.isCorrect));
575
945
  // Remove Unset Optionals
576
946
  ObjectUtils.removeUnwantedProperties(node, {
577
947
  ignoreAllFalse: true,
948
+ // ignoreAllEmptyArrays: true,
949
+ ignoreUndefined: ['example'],
578
950
  });
579
951
  return node;
580
952
  }
@@ -584,19 +956,23 @@ class Builder extends BaseBuilder {
584
956
  * @param data - data for the node
585
957
  * @returns
586
958
  */
587
- imageSource(data) {
959
+ buildImageSource(data) {
960
+ if (!data)
961
+ return undefined;
588
962
  const { url, mockupId, size, format, trim } = data;
589
963
  // NOTE: Node order is important and is defined here
590
964
  const node = {
591
- url,
592
- mockupId,
593
- size,
594
- format,
595
- trim,
965
+ url: url !== null && url !== void 0 ? url : '',
966
+ mockupId: mockupId !== null && mockupId !== void 0 ? mockupId : '',
967
+ size: (size !== null && size !== void 0 ? size : null),
968
+ format: (format !== null && format !== void 0 ? format : null),
969
+ trim: (BooleanUtils.isBoolean(trim) ? trim : null),
596
970
  };
597
971
  // Remove Unset Optionals
598
972
  ObjectUtils.removeUnwantedProperties(node, {
599
973
  ignoreFalse: ['trim'],
974
+ ignoreEmptyString: ['url', 'mockupId'],
975
+ ignoreAllUndefined: true,
600
976
  });
601
977
  return node;
602
978
  }
@@ -606,16 +982,23 @@ class Builder extends BaseBuilder {
606
982
  * @param data - data for the node
607
983
  * @returns
608
984
  */
609
- person(data) {
985
+ buildPerson(bitType, data) {
986
+ var _a;
987
+ if (!data)
988
+ return undefined;
610
989
  const { name, title, avatarImage } = data;
990
+ // { name: string; title?: string; avatarImage?: ImageResourceJson }
611
991
  // NOTE: Node order is important and is defined here
612
992
  const node = {
613
- name,
614
- title,
615
- avatarImage,
993
+ name: name !== null && name !== void 0 ? name : '',
994
+ title: (title !== null && title !== void 0 ? title : undefined),
995
+ avatarImage: (_a = ArrayUtils.asSingle(this.resourceBuilder.resourceFromResourceDataJson(bitType, ResourceTag.image, avatarImage))) === null || _a === void 0 ? void 0 : _a.image,
616
996
  };
617
997
  // Remove Unset Optionals
618
- ObjectUtils.removeUnwantedProperties(node);
998
+ ObjectUtils.removeUnwantedProperties(node, {
999
+ ignoreEmptyString: ['name'],
1000
+ ignoreAllUndefined: true,
1001
+ });
619
1002
  return node;
620
1003
  }
621
1004
  /**
@@ -624,15 +1007,20 @@ class Builder extends BaseBuilder {
624
1007
  * @param data - data for the node
625
1008
  * @returns
626
1009
  */
627
- technicalTerm(data) {
1010
+ buildTechnicalTerm(data) {
1011
+ if (!data)
1012
+ return undefined;
628
1013
  const { technicalTerm, lang } = data;
629
1014
  // NOTE: Node order is important and is defined here
630
1015
  const node = {
631
- technicalTerm,
632
- lang,
1016
+ technicalTerm: technicalTerm !== null && technicalTerm !== void 0 ? technicalTerm : '',
1017
+ lang: lang !== null && lang !== void 0 ? lang : '',
633
1018
  };
634
1019
  // Remove Unset Optionals
635
- ObjectUtils.removeUnwantedProperties(node);
1020
+ ObjectUtils.removeUnwantedProperties(node, {
1021
+ ignoreEmptyString: ['technicalTerm'],
1022
+ // ignoreAllUndefined: true,
1023
+ });
636
1024
  return node;
637
1025
  }
638
1026
  /**
@@ -641,19 +1029,24 @@ class Builder extends BaseBuilder {
641
1029
  * @param data - data for the node
642
1030
  * @returns
643
1031
  */
644
- servings(data) {
1032
+ buildServings(data) {
1033
+ if (!data)
1034
+ return undefined;
645
1035
  const { servings, unit, unitAbbr, decimalPlaces, disableCalculation, hint } = data;
646
1036
  // NOTE: Node order is important and is defined here
647
1037
  const node = {
648
- servings,
649
- unit,
650
- unitAbbr,
651
- decimalPlaces,
652
- disableCalculation,
653
- hint,
1038
+ servings: servings !== null && servings !== void 0 ? servings : 0,
1039
+ unit: unit !== null && unit !== void 0 ? unit : '',
1040
+ unitAbbr: unitAbbr !== null && unitAbbr !== void 0 ? unitAbbr : '',
1041
+ decimalPlaces: decimalPlaces !== null && decimalPlaces !== void 0 ? decimalPlaces : 1,
1042
+ disableCalculation: disableCalculation !== null && disableCalculation !== void 0 ? disableCalculation : false,
1043
+ hint: hint !== null && hint !== void 0 ? hint : '',
654
1044
  };
655
1045
  // Remove Unset Optionals
656
- ObjectUtils.removeUnwantedProperties(node);
1046
+ ObjectUtils.removeUnwantedProperties(node, {
1047
+ ignoreEmptyString: ['servings', 'unit'],
1048
+ // ignoreAllUndefined: true,
1049
+ });
657
1050
  return node;
658
1051
  }
659
1052
  /**
@@ -662,15 +1055,20 @@ class Builder extends BaseBuilder {
662
1055
  * @param data - data for the node
663
1056
  * @returns
664
1057
  */
665
- ratingLevelStartEnd(data) {
1058
+ buildRatingLevelStartEnd(data) {
1059
+ if (!data)
1060
+ return undefined;
666
1061
  const { level, label } = data;
667
1062
  // NOTE: Node order is important and is defined here
668
1063
  const node = {
669
- level,
670
- label,
1064
+ level: level !== null && level !== void 0 ? level : 0,
1065
+ label: this.handleJsonText(label),
671
1066
  };
672
1067
  // Remove Unset Optionals
673
- ObjectUtils.removeUnwantedProperties(node);
1068
+ ObjectUtils.removeUnwantedProperties(node, {
1069
+ // ignoreEmptyArrays: ['servings', 'unit'],
1070
+ // ignoreAllUndefined: true,
1071
+ });
674
1072
  return node;
675
1073
  }
676
1074
  /**
@@ -679,15 +1077,22 @@ class Builder extends BaseBuilder {
679
1077
  * @param data - data for the node
680
1078
  * @returns
681
1079
  */
682
- captionDefinition(data) {
683
- const { term, description } = data;
1080
+ buildCaptionDefinition(data) {
1081
+ var _a, _b;
1082
+ if (!data)
1083
+ return undefined;
684
1084
  // NOTE: Node order is important and is defined here
685
1085
  const node = {
686
- term,
687
- description,
1086
+ // term: this.convertJsonTextToAstText(data.term),
1087
+ // description: this.convertJsonTextToAstText(data.description),
1088
+ term: (_a = data.term) !== null && _a !== void 0 ? _a : '',
1089
+ definition: (_b = data.definition) !== null && _b !== void 0 ? _b : '',
688
1090
  };
689
1091
  // Remove Unset Optionals
690
- ObjectUtils.removeUnwantedProperties(node);
1092
+ ObjectUtils.removeUnwantedProperties(node, {
1093
+ ignoreEmptyString: ['term', 'description'],
1094
+ // ignoreAllUndefined: true,
1095
+ });
691
1096
  return node;
692
1097
  }
693
1098
  /**
@@ -696,32 +1101,39 @@ class Builder extends BaseBuilder {
696
1101
  * @param data - data for the node
697
1102
  * @returns
698
1103
  */
699
- captionDefinitionList(data) {
700
- const { columns, definitions } = data;
1104
+ buildCaptionDefinitionList(data) {
1105
+ var _a, _b;
1106
+ if (!data)
1107
+ return undefined;
701
1108
  // NOTE: Node order is important and is defined here
702
1109
  const node = {
703
- columns,
704
- definitions,
1110
+ columns: (_a = data.columns) !== null && _a !== void 0 ? _a : [],
1111
+ definitions: ((_b = data.definitions) !== null && _b !== void 0 ? _b : [])
1112
+ .map((d) => {
1113
+ return this.buildCaptionDefinition({
1114
+ term: d.term,
1115
+ definition: d.definition,
1116
+ });
1117
+ })
1118
+ .filter((d) => d != null),
705
1119
  };
706
1120
  // Remove Unset Optionals
707
- ObjectUtils.removeUnwantedProperties(node);
1121
+ ObjectUtils.removeUnwantedProperties(node, {
1122
+ ignoreAllEmptyArrays: true,
1123
+ });
708
1124
  return node;
709
1125
  }
710
- //
711
- // Private
712
- //
713
- itemLead(item, lead, pageNumber, marginNumber) {
714
- let node;
715
- // NOTE: Node order is important and is defined here
716
- if (item || lead || pageNumber || marginNumber) {
717
- node = {
718
- item,
719
- lead,
720
- pageNumber,
721
- marginNumber,
722
- };
723
- }
724
- return node;
1126
+ /**
1127
+ * Build card bit[] node
1128
+ *
1129
+ * @param data - data for the node
1130
+ * @returns
1131
+ */
1132
+ buildCardBits(textFormat, data) {
1133
+ if (!Array.isArray(data))
1134
+ return undefined;
1135
+ const nodes = data.map((d) => this.buildCardBit(textFormat, d)).filter((d) => d != null);
1136
+ return nodes.length > 0 ? nodes : undefined;
725
1137
  }
726
1138
  /**
727
1139
  * Build card bit node
@@ -729,116 +1141,101 @@ class Builder extends BaseBuilder {
729
1141
  * @param data - data for the node
730
1142
  * @returns
731
1143
  */
732
- cardBit(data) {
733
- const { item, lead, pageNumber, marginNumber, hint, instruction, isDefaultExample, example, extraProperties, body, } = data;
1144
+ buildCardBit(textFormat, data) {
1145
+ var _a;
1146
+ if (!data)
1147
+ return undefined;
734
1148
  // NOTE: Node order is important and is defined here
735
- const node = Object.assign(Object.assign({ itemLead: this.itemLead(item, lead, pageNumber, marginNumber), hint,
736
- instruction }, this.toExample(isDefaultExample, example)), { body,
1149
+ const node = Object.assign(Object.assign({ item: this.handleJsonText(data.item), lead: this.handleJsonText(data.lead), hint: this.handleJsonText(data.hint), instruction: this.handleJsonText(data.instruction) }, this.toExample(data.__isDefaultExample, data.example)), { __isDefaultExample: (_a = data.__isDefaultExample) !== null && _a !== void 0 ? _a : false, body: this.buildBody(textFormat, data.body),
737
1150
  // Must always be last in the AST so key clashes are avoided correctly with other properties
738
- extraProperties: this.parseExtraProperties(extraProperties) });
1151
+ extraProperties: this.parseExtraProperties(data.extraProperties) });
739
1152
  // Remove Unset Optionals
740
1153
  ObjectUtils.removeUnwantedProperties(node, {
741
1154
  ignoreAllFalse: true,
742
- ignoreEmptyString: ['example'],
1155
+ // ignoreEmptyArrays: ['example'],
1156
+ ignoreUndefined: ['example'],
743
1157
  });
744
1158
  // Validate and correct invalid bits as much as possible
745
1159
  return NodeValidator.validateCardBit(node);
746
1160
  }
747
- cardNode(data) {
748
- let node;
749
- const { questions, elements, flashcards, definitions, statement, statements, choices, responses, quizzes, heading, pairs, matrix, table, botResponses, ingredients, captionDefinitionList, cardBits, } = data;
750
- if (questions ||
751
- elements ||
752
- flashcards ||
753
- definitions ||
754
- statement ||
755
- statements ||
756
- choices ||
757
- responses ||
758
- quizzes ||
759
- heading ||
760
- pairs ||
761
- matrix ||
762
- table ||
763
- botResponses ||
764
- ingredients ||
765
- captionDefinitionList ||
766
- cardBits) {
767
- node = {
768
- questions,
769
- elements,
770
- flashcards,
771
- definitions,
772
- statement,
773
- statements,
774
- choices,
775
- responses,
776
- quizzes,
777
- heading,
778
- pairs,
779
- matrix,
780
- table,
781
- botResponses,
782
- ingredients,
783
- captionDefinitionList,
784
- cardBits,
785
- };
786
- // Remove Unset Optionals
787
- ObjectUtils.removeUnwantedProperties(node);
788
- }
789
- return node;
1161
+ //
1162
+ // Private
1163
+ //
1164
+ buildCardNode(bitType, textFormat, data) {
1165
+ const node = {
1166
+ questions: this.buildQuestions(data.questions),
1167
+ elements: data.elements,
1168
+ flashcards: this.buildFlashcards(data.flashcards),
1169
+ definitions: this.buildDefinitionList(data.definitions),
1170
+ statement: this.buildStatement(data.statement),
1171
+ statements: this.buildStatements(data.statements),
1172
+ choices: this.buildChoices(data.choices),
1173
+ responses: this.buildResponses(data.responses),
1174
+ quizzes: this.buildQuizzes(data.quizzes),
1175
+ heading: this.buildHeading(data.heading),
1176
+ pairs: this.buildPairs(bitType, data.pairs),
1177
+ matrix: this.buildMatricies(data.matrix),
1178
+ table: this.buildTable(data.table),
1179
+ botResponses: this.buildBotResponses(data.botResponses),
1180
+ ingredients: this.buildIngredients(data.ingredients),
1181
+ captionDefinitionList: this.buildCaptionDefinitionList(data.captionDefinitionList),
1182
+ cardBits: this.buildCardBits(textFormat, data.cardBits),
1183
+ };
1184
+ // Remove Unset Optionals
1185
+ ObjectUtils.removeUnwantedProperties(node);
1186
+ return Object.keys(node).length > 0 ? node : undefined;
790
1187
  }
791
1188
  /**
792
1189
  * Set examples down the tree
793
1190
  *
794
1191
  * @param body
795
1192
  * @param cardNode
796
- * @param isDefaultExample
1193
+ * @param __isDefaultExample
797
1194
  * @param example
798
1195
  * @returns true if any of the answers has an example, otherwise undefined
799
1196
  */
800
- pushExampleDownTree(body, cardNode, isDefaultExample, example) {
801
- if (isDefaultExample || example) {
1197
+ pushExampleDownTree(body, cardNode, __isDefaultExample, example) {
1198
+ if (__isDefaultExample || example != null) {
802
1199
  if (cardNode) {
803
- this.pushExampleDownTreeString(isDefaultExample, example, cardNode.pairs);
804
- this.pushExampleDownTreeBoolean(isDefaultExample, example, false, cardNode.flashcards);
805
- this.pushExampleDownTreeBoolean(isDefaultExample, example, false, cardNode.definitions);
806
- this.pushExampleDownTreeBoolean(isDefaultExample, example, true, cardNode.choices);
807
- this.pushExampleDownTreeBoolean(isDefaultExample, example, false, cardNode.responses, cardNode.statements, cardNode.statement);
1200
+ this.pushExampleDownTreeString(__isDefaultExample, example, cardNode.pairs);
1201
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, false, cardNode.flashcards);
1202
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, false, cardNode.definitions);
1203
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, true, cardNode.choices);
1204
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, false, cardNode.responses, cardNode.statements, cardNode.statement);
808
1205
  if (cardNode.quizzes) {
809
1206
  for (const quiz of cardNode.quizzes) {
810
- this.pushExampleDownTreeBoolean(isDefaultExample, example, true, quiz.choices);
811
- this.pushExampleDownTreeBoolean(isDefaultExample, example, false, quiz.responses);
1207
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, true, quiz.choices);
1208
+ this.pushExampleDownTreeBoolean(__isDefaultExample, example, false, quiz.responses);
812
1209
  }
813
1210
  }
814
1211
  if (cardNode.matrix) {
815
1212
  for (const m of cardNode.matrix) {
816
- this.pushExampleDownTreeString(isDefaultExample, example, m.cells);
1213
+ this.pushExampleDownTreeString(__isDefaultExample, example, m.cells);
817
1214
  }
818
1215
  }
819
1216
  }
820
1217
  if (body) {
821
- this.pushExampleDownTreeBodyBits(isDefaultExample, example, body);
1218
+ this.pushExampleDownTreeBodyBits(__isDefaultExample, example, body);
822
1219
  }
823
1220
  }
824
1221
  }
825
1222
  /**
826
1223
  * Set examples for boolean nodes
827
1224
  *
828
- * @param isDefaultExample
1225
+ * @param __isDefaultExample
829
1226
  * @param example
830
1227
  * @param onlyCorrect
831
1228
  * @param nodes
832
1229
  * @returns true if any of the answers has an example, otherwise undefined
833
1230
  */
834
- pushExampleDownTreeBoolean(isDefaultExample, example, onlyCorrect, ...nodes) {
835
- if (!isDefaultExample && !example)
1231
+ pushExampleDownTreeBoolean(__isDefaultExample, example, onlyCorrect, ...nodes) {
1232
+ if (!__isDefaultExample && example == null)
836
1233
  return;
837
1234
  if (Array.isArray(nodes)) {
838
1235
  for (const ds of nodes) {
839
1236
  if (ds) {
840
1237
  const exampleNodes = Array.isArray(ds) ? ds : [ds];
841
- BitUtils.fillBooleanExample(exampleNodes, isDefaultExample, example, onlyCorrect);
1238
+ BitUtils.fillBooleanExample(exampleNodes, __isDefaultExample, example, onlyCorrect);
842
1239
  }
843
1240
  }
844
1241
  }
@@ -846,49 +1243,48 @@ class Builder extends BaseBuilder {
846
1243
  /**
847
1244
  * Set examples for string nodes
848
1245
  *
849
- * @param isDefaultExample
1246
+ * @param __isDefaultExample
850
1247
  * @param example
851
1248
  * @param nodes
852
1249
  * @returns true if any of the answers has an example, otherwise undefined
853
1250
  */
854
- pushExampleDownTreeString(isDefaultExample, example, ...nodes) {
855
- if (!isDefaultExample && !example)
1251
+ pushExampleDownTreeString(__isDefaultExample, example, ...nodes) {
1252
+ if (!__isDefaultExample && !example)
856
1253
  return;
857
1254
  if (Array.isArray(nodes)) {
858
1255
  for (const ds of nodes) {
859
1256
  if (ds) {
860
1257
  const exampleNodes = Array.isArray(ds) ? ds : [ds];
861
- BitUtils.fillStringExample(exampleNodes, isDefaultExample, example, false);
1258
+ BitUtils.fillStringExample(exampleNodes, __isDefaultExample, example, false);
862
1259
  }
863
1260
  }
864
1261
  }
865
1262
  }
866
- pushExampleDownTreeBodyBits(isDefaultExample, example, body) {
867
- if (!isDefaultExample && !example)
868
- return;
869
- if (!body || !body.bodyParts || body.bodyParts.length === 0)
1263
+ pushExampleDownTreeBodyBits(__isDefaultExample, example, body) {
1264
+ if (!__isDefaultExample && !example)
870
1265
  return;
871
- for (const part of body.bodyParts) {
1266
+ const bodyBitsJson = this.textParser.extractBodyBits(body === null || body === void 0 ? void 0 : body.body);
1267
+ for (const part of bodyBitsJson) {
872
1268
  if (part) {
873
1269
  switch (part.type) {
874
1270
  case BodyBitType.gap: {
875
1271
  const gap = part;
876
- BitUtils.fillStringExample([gap.data], isDefaultExample, example, false);
1272
+ BitUtils.fillStringExample([gap], __isDefaultExample, example, false);
877
1273
  break;
878
1274
  }
879
1275
  case BodyBitType.mark: {
880
1276
  const mark = part;
881
- BitUtils.fillBooleanExample([mark.data], isDefaultExample, example, false);
1277
+ BitUtils.fillBooleanExample([mark], __isDefaultExample, example, false);
882
1278
  break;
883
1279
  }
884
1280
  case BodyBitType.select: {
885
1281
  const select = part;
886
- BitUtils.fillBooleanExample(select.data.options, isDefaultExample, example, true);
1282
+ BitUtils.fillBooleanExample(select.options, __isDefaultExample, example, true);
887
1283
  break;
888
1284
  }
889
1285
  case BodyBitType.highlight: {
890
1286
  const highlight = part;
891
- BitUtils.fillBooleanExample(highlight.data.texts, isDefaultExample, example, true);
1287
+ BitUtils.fillBooleanExample(highlight.texts, __isDefaultExample, example, true);
892
1288
  break;
893
1289
  }
894
1290
  }
@@ -900,7 +1296,7 @@ class Builder extends BaseBuilder {
900
1296
  *
901
1297
  * This function is not type safe and should be used with care
902
1298
  *
903
- * @param body set if the value should be passed down the body to the body bits
1299
+ * @param body/body[] set if the value should be passed down the body to the body bits / card body bits
904
1300
  * @param bodyBitTypes body bit types to push the value down to
905
1301
  * @param cardNode set if the value should be passed down the card node
906
1302
  * @param path path for the value
@@ -922,14 +1318,22 @@ class Builder extends BaseBuilder {
922
1318
  }
923
1319
  }
924
1320
  // Add value to body bit types if required
925
- if (bodyBitTypes && body && body.bodyParts && body.bodyParts.length > 0) {
926
- for (const part of body.bodyParts) {
927
- if (part) {
928
- if (bodyBitTypes.indexOf(part.type) !== -1) {
929
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
930
- const data = part.data;
931
- if (data[path] == null) {
932
- data[path] = value;
1321
+ if (body) {
1322
+ const bodyArray = (Array.isArray(body) ? body : [body]);
1323
+ for (const b of bodyArray) {
1324
+ if (b && b.body && bodyBitTypes) {
1325
+ const bodyBitsJson = this.textParser.extractBodyBits(b.body);
1326
+ if (bodyBitTypes && bodyBitsJson && bodyBitsJson.length > 0) {
1327
+ for (const part of bodyBitsJson) {
1328
+ if (part) {
1329
+ if (bodyBitTypes.indexOf(part.type) !== -1) {
1330
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1331
+ const data = part;
1332
+ if (data[path] == null) {
1333
+ data[path] = value;
1334
+ }
1335
+ }
1336
+ }
933
1337
  }
934
1338
  }
935
1339
  }
@@ -957,12 +1361,12 @@ class Builder extends BaseBuilder {
957
1361
  * @param bit
958
1362
  */
959
1363
  setIsExampleFlags(bit) {
1364
+ // bit.isExample = false;
960
1365
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
961
- bit.isExample = false;
962
1366
  const checkIsExample = (example) => {
963
1367
  if (!example)
964
1368
  return false;
965
- if (example.isDefaultExample || example.example != undefined) {
1369
+ if ( /*example.__isDefaultExample ||*/example.isExample || example.example != undefined) {
966
1370
  example.isExample = true;
967
1371
  bit.isExample = true;
968
1372
  }
@@ -978,32 +1382,31 @@ class Builder extends BaseBuilder {
978
1382
  };
979
1383
  const { body, cardNode } = bit;
980
1384
  // Body bit level
981
- if (body && body.bodyParts) {
982
- for (const bodyPart of body.bodyParts) {
983
- switch (bodyPart.type) {
984
- case BodyBitType.gap:
985
- case BodyBitType.mark: {
986
- checkIsExample(bodyPart.data);
987
- break;
988
- }
989
- case BodyBitType.select: {
990
- const select = bodyPart;
991
- let hasExample = false;
992
- for (const option of select.data.options) {
993
- hasExample = checkIsExample(option) ? true : hasExample;
994
- }
995
- select.data.isExample = hasExample;
996
- break;
1385
+ const bodyBitsJson = this.textParser.extractBodyBits(body === null || body === void 0 ? void 0 : body.body);
1386
+ for (const bodyPart of bodyBitsJson) {
1387
+ switch (bodyPart.type) {
1388
+ case BodyBitType.gap:
1389
+ case BodyBitType.mark: {
1390
+ checkIsExample(bodyPart);
1391
+ break;
1392
+ }
1393
+ case BodyBitType.select: {
1394
+ const select = bodyPart;
1395
+ let hasExample = false;
1396
+ for (const option of select.options) {
1397
+ hasExample = checkIsExample(option) ? true : hasExample;
997
1398
  }
998
- case BodyBitType.highlight: {
999
- const highlight = bodyPart;
1000
- let hasExample = false;
1001
- for (const text of highlight.data.texts) {
1002
- hasExample = checkIsExample(text) ? true : hasExample;
1003
- }
1004
- highlight.data.isExample = hasExample;
1005
- break;
1399
+ select.isExample = hasExample;
1400
+ break;
1401
+ }
1402
+ case BodyBitType.highlight: {
1403
+ const highlight = bodyPart;
1404
+ let hasExample = false;
1405
+ for (const text of highlight.texts) {
1406
+ hasExample = checkIsExample(text) ? true : hasExample;
1006
1407
  }
1408
+ highlight.isExample = hasExample;
1409
+ break;
1007
1410
  }
1008
1411
  }
1009
1412
  }