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