@erudit-js/prose 3.0.0-dev.25

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 (355) hide show
  1. package/dist/app/appElement.d.ts +19 -0
  2. package/dist/app/appElement.js +12 -0
  3. package/dist/app/component.d.ts +6 -0
  4. package/dist/app/component.js +6 -0
  5. package/dist/app/composables/anchor.d.ts +16 -0
  6. package/dist/app/composables/anchor.js +89 -0
  7. package/dist/app/composables/appElement.d.ts +4 -0
  8. package/dist/app/composables/appElement.js +16 -0
  9. package/dist/app/composables/context.d.ts +22 -0
  10. package/dist/app/composables/context.js +5 -0
  11. package/dist/app/composables/elementIcon.d.ts +3 -0
  12. package/dist/app/composables/elementIcon.js +5 -0
  13. package/dist/app/composables/formatText.d.ts +1 -0
  14. package/dist/app/composables/formatText.js +5 -0
  15. package/dist/app/composables/language.d.ts +8 -0
  16. package/dist/app/composables/language.js +13 -0
  17. package/dist/app/composables/storage.d.ts +5 -0
  18. package/dist/app/composables/storage.js +23 -0
  19. package/dist/app/default/Inliners.vue +11 -0
  20. package/dist/app/default/Mix.vue +11 -0
  21. package/dist/app/default/Text.vue +21 -0
  22. package/dist/app/icon.d.ts +5 -0
  23. package/dist/app/icon.js +7 -0
  24. package/dist/app/index.d.ts +18 -0
  25. package/dist/app/index.js +18 -0
  26. package/dist/app/language/element.d.ts +10 -0
  27. package/dist/app/language/element.js +12 -0
  28. package/dist/app/language/list/en.d.ts +3 -0
  29. package/dist/app/language/list/en.js +5 -0
  30. package/dist/app/language/list/ru.d.ts +3 -0
  31. package/dist/app/language/list/ru.js +5 -0
  32. package/dist/app/language/prose.d.ts +9 -0
  33. package/dist/app/language/prose.js +4 -0
  34. package/dist/app/shared/Prose.vue +36 -0
  35. package/dist/app/shared/Render.vue +51 -0
  36. package/dist/app/shared/assets/block.svg +3 -0
  37. package/dist/app/shared/assets/check.svg +3 -0
  38. package/dist/app/shared/assets/inliner.svg +3 -0
  39. package/dist/app/shared/assets/plus.svg +3 -0
  40. package/dist/app/shared/assets/share.svg +3 -0
  41. package/dist/app/shared/block/AsideMenu.vue +44 -0
  42. package/dist/app/shared/block/AsideMenuButton.vue +53 -0
  43. package/dist/app/shared/block/AsideMenuCopyLink.vue +40 -0
  44. package/dist/app/shared/block/AsideMenuSeparator.vue +3 -0
  45. package/dist/app/shared/block/Block.vue +270 -0
  46. package/dist/app/shared/inliner/Inliner.vue +11 -0
  47. package/dist/app/shared/invert.d.ts +2 -0
  48. package/dist/app/shared/invert.js +2 -0
  49. package/dist/app/shared/photoswipe/composable.d.ts +9 -0
  50. package/dist/app/shared/photoswipe/composable.js +68 -0
  51. package/dist/app/shared/photoswipe/style.css +26 -0
  52. package/dist/context.d.ts +4 -0
  53. package/dist/context.js +1 -0
  54. package/dist/coreElement.d.ts +10 -0
  55. package/dist/coreElement.js +6 -0
  56. package/dist/elements/accent/Accent.vue +92 -0
  57. package/dist/elements/accent/AccentColumnSection.vue +61 -0
  58. package/dist/elements/accent/AccentRowSections.vue +65 -0
  59. package/dist/elements/accent/app.d.ts +21 -0
  60. package/dist/elements/accent/app.js +16 -0
  61. package/dist/elements/accent/core.d.ts +340 -0
  62. package/dist/elements/accent/core.js +175 -0
  63. package/dist/elements/callout/Callout.vue +88 -0
  64. package/dist/elements/callout/_global.d.ts +15 -0
  65. package/dist/elements/callout/app.d.ts +9 -0
  66. package/dist/elements/callout/app.js +11 -0
  67. package/dist/elements/callout/core.d.ts +80 -0
  68. package/dist/elements/callout/core.js +37 -0
  69. package/dist/elements/callout/icon.svg +3 -0
  70. package/dist/elements/callout/languages/en.d.ts +4 -0
  71. package/dist/elements/callout/languages/en.js +2 -0
  72. package/dist/elements/callout/languages/ru.d.ts +4 -0
  73. package/dist/elements/callout/languages/ru.js +2 -0
  74. package/dist/elements/callout/storage.d.ts +2 -0
  75. package/dist/elements/callout/storage.js +5 -0
  76. package/dist/elements/caption/Caption.vue +47 -0
  77. package/dist/elements/caption/_global.d.ts +26 -0
  78. package/dist/elements/caption/app.d.ts +9 -0
  79. package/dist/elements/caption/app.js +6 -0
  80. package/dist/elements/caption/core.d.ts +114 -0
  81. package/dist/elements/caption/core.js +61 -0
  82. package/dist/elements/details/Details.vue +51 -0
  83. package/dist/elements/details/_global.d.ts +27 -0
  84. package/dist/elements/details/app.d.ts +9 -0
  85. package/dist/elements/details/app.js +11 -0
  86. package/dist/elements/details/core.d.ts +68 -0
  87. package/dist/elements/details/core.js +30 -0
  88. package/dist/elements/details/icon.svg +3 -0
  89. package/dist/elements/details/languages/en.d.ts +4 -0
  90. package/dist/elements/details/languages/en.js +2 -0
  91. package/dist/elements/details/languages/ru.d.ts +4 -0
  92. package/dist/elements/details/languages/ru.js +2 -0
  93. package/dist/elements/diagram/Diagram.vue +364 -0
  94. package/dist/elements/diagram/_global.d.ts +19 -0
  95. package/dist/elements/diagram/app.d.ts +30 -0
  96. package/dist/elements/diagram/app.js +11 -0
  97. package/dist/elements/diagram/core.d.ts +194 -0
  98. package/dist/elements/diagram/core.js +36 -0
  99. package/dist/elements/diagram/icon.svg +3 -0
  100. package/dist/elements/diagram/languages/en.d.ts +4 -0
  101. package/dist/elements/diagram/languages/en.js +2 -0
  102. package/dist/elements/diagram/languages/ru.d.ts +4 -0
  103. package/dist/elements/diagram/languages/ru.js +2 -0
  104. package/dist/elements/emphasis/Emphasis.vue +25 -0
  105. package/dist/elements/emphasis/_global.d.ts +18 -0
  106. package/dist/elements/emphasis/app.d.ts +9 -0
  107. package/dist/elements/emphasis/app.js +6 -0
  108. package/dist/elements/emphasis/core.d.ts +90 -0
  109. package/dist/elements/emphasis/core.js +32 -0
  110. package/dist/elements/flex/Flex.vue +32 -0
  111. package/dist/elements/flex/_global.d.ts +23 -0
  112. package/dist/elements/flex/app.d.ts +9 -0
  113. package/dist/elements/flex/app.js +11 -0
  114. package/dist/elements/flex/core.d.ts +67 -0
  115. package/dist/elements/flex/core.js +28 -0
  116. package/dist/elements/flex/icon.svg +3 -0
  117. package/dist/elements/flex/languages/en.d.ts +4 -0
  118. package/dist/elements/flex/languages/en.js +2 -0
  119. package/dist/elements/flex/languages/ru.d.ts +4 -0
  120. package/dist/elements/flex/languages/ru.js +2 -0
  121. package/dist/elements/gallery/Gallery.vue +56 -0
  122. package/dist/elements/gallery/_global.d.ts +18 -0
  123. package/dist/elements/gallery/app.d.ts +23 -0
  124. package/dist/elements/gallery/app.js +11 -0
  125. package/dist/elements/gallery/core.d.ts +138 -0
  126. package/dist/elements/gallery/core.js +21 -0
  127. package/dist/elements/gallery/icon.svg +3 -0
  128. package/dist/elements/gallery/languages/en.d.ts +4 -0
  129. package/dist/elements/gallery/languages/en.js +2 -0
  130. package/dist/elements/gallery/languages/ru.d.ts +4 -0
  131. package/dist/elements/gallery/languages/ru.js +2 -0
  132. package/dist/elements/heading/Heading.vue +44 -0
  133. package/dist/elements/heading/_global.d.ts +45 -0
  134. package/dist/elements/heading/app.d.ts +9 -0
  135. package/dist/elements/heading/app.js +11 -0
  136. package/dist/elements/heading/core.d.ts +108 -0
  137. package/dist/elements/heading/core.js +52 -0
  138. package/dist/elements/heading/icon.svg +3 -0
  139. package/dist/elements/heading/languages/en.d.ts +4 -0
  140. package/dist/elements/heading/languages/en.js +2 -0
  141. package/dist/elements/heading/languages/ru.d.ts +4 -0
  142. package/dist/elements/heading/languages/ru.js +2 -0
  143. package/dist/elements/horizontalLine/HorizontalLine.vue +6 -0
  144. package/dist/elements/horizontalLine/_global.d.ts +17 -0
  145. package/dist/elements/horizontalLine/app.d.ts +9 -0
  146. package/dist/elements/horizontalLine/app.js +6 -0
  147. package/dist/elements/horizontalLine/core.d.ts +54 -0
  148. package/dist/elements/horizontalLine/core.js +19 -0
  149. package/dist/elements/image/Image.vue +15 -0
  150. package/dist/elements/image/ImageElement.vue +80 -0
  151. package/dist/elements/image/_global.d.ts +18 -0
  152. package/dist/elements/image/app.d.ts +16 -0
  153. package/dist/elements/image/app.js +11 -0
  154. package/dist/elements/image/core.d.ts +136 -0
  155. package/dist/elements/image/core.js +44 -0
  156. package/dist/elements/image/icon.svg +3 -0
  157. package/dist/elements/image/languages/en.d.ts +4 -0
  158. package/dist/elements/image/languages/en.js +2 -0
  159. package/dist/elements/image/languages/ru.d.ts +4 -0
  160. package/dist/elements/image/languages/ru.js +2 -0
  161. package/dist/elements/image/storage.d.ts +6 -0
  162. package/dist/elements/image/storage.js +23 -0
  163. package/dist/elements/lineBreak/LineBreak.vue +3 -0
  164. package/dist/elements/lineBreak/_global.d.ts +18 -0
  165. package/dist/elements/lineBreak/app.d.ts +9 -0
  166. package/dist/elements/lineBreak/app.js +6 -0
  167. package/dist/elements/lineBreak/core.d.ts +54 -0
  168. package/dist/elements/lineBreak/core.js +19 -0
  169. package/dist/elements/link/BlockLink.vue +111 -0
  170. package/dist/elements/link/Link.vue +93 -0
  171. package/dist/elements/link/core.d.ts +13 -0
  172. package/dist/elements/link/core.js +12 -0
  173. package/dist/elements/link/dependency/_global.d.ts +47 -0
  174. package/dist/elements/link/dependency/app.d.ts +16 -0
  175. package/dist/elements/link/dependency/app.js +14 -0
  176. package/dist/elements/link/dependency/core.d.ts +125 -0
  177. package/dist/elements/link/dependency/core.js +51 -0
  178. package/dist/elements/link/dependency/languages/en.d.ts +4 -0
  179. package/dist/elements/link/dependency/languages/en.js +2 -0
  180. package/dist/elements/link/dependency/languages/ru.d.ts +4 -0
  181. package/dist/elements/link/dependency/languages/ru.js +2 -0
  182. package/dist/elements/link/icon.svg +3 -0
  183. package/dist/elements/link/reference/_global.d.ts +49 -0
  184. package/dist/elements/link/reference/app.d.ts +16 -0
  185. package/dist/elements/link/reference/app.js +14 -0
  186. package/dist/elements/link/reference/core.d.ts +120 -0
  187. package/dist/elements/link/reference/core.js +35 -0
  188. package/dist/elements/link/reference/languages/en.d.ts +4 -0
  189. package/dist/elements/link/reference/languages/en.js +2 -0
  190. package/dist/elements/link/reference/languages/ru.d.ts +4 -0
  191. package/dist/elements/link/reference/languages/ru.js +2 -0
  192. package/dist/elements/link/storage.d.ts +34 -0
  193. package/dist/elements/link/storage.js +20 -0
  194. package/dist/elements/list/List.vue +63 -0
  195. package/dist/elements/list/_global.d.ts +50 -0
  196. package/dist/elements/list/app.d.ts +16 -0
  197. package/dist/elements/list/app.js +11 -0
  198. package/dist/elements/list/core.d.ts +169 -0
  199. package/dist/elements/list/core.js +49 -0
  200. package/dist/elements/list/icon.svg +3 -0
  201. package/dist/elements/list/languages/en.d.ts +4 -0
  202. package/dist/elements/list/languages/en.js +2 -0
  203. package/dist/elements/list/languages/ru.d.ts +4 -0
  204. package/dist/elements/list/languages/ru.js +2 -0
  205. package/dist/elements/math/_global.d.ts +72 -0
  206. package/dist/elements/math/_global.ts +3 -0
  207. package/dist/elements/math/app.d.ts +16 -0
  208. package/dist/elements/math/app.js +20 -0
  209. package/dist/elements/math/block.d.ts +75 -0
  210. package/dist/elements/math/block.js +115 -0
  211. package/dist/elements/math/components/BlockMath.vue +30 -0
  212. package/dist/elements/math/components/InlinerMath.vue +65 -0
  213. package/dist/elements/math/components/Katex.vue +89 -0
  214. package/dist/elements/math/components/MathGroup.vue +39 -0
  215. package/dist/elements/math/core.d.ts +66 -0
  216. package/dist/elements/math/core.js +11 -0
  217. package/dist/elements/math/icon.svg +3 -0
  218. package/dist/elements/math/inliner.d.ts +64 -0
  219. package/dist/elements/math/inliner.js +85 -0
  220. package/dist/elements/math/katex.d.ts +8 -0
  221. package/dist/elements/math/katex.js +18 -0
  222. package/dist/elements/math/languages/en.d.ts +4 -0
  223. package/dist/elements/math/languages/en.js +2 -0
  224. package/dist/elements/math/languages/ru.d.ts +4 -0
  225. package/dist/elements/math/languages/ru.js +2 -0
  226. package/dist/elements/math/macros.d.ts +13 -0
  227. package/dist/elements/math/macros.js +12 -0
  228. package/dist/elements/paragraph/Paragraph.vue +27 -0
  229. package/dist/elements/paragraph/_global.d.ts +27 -0
  230. package/dist/elements/paragraph/app.d.ts +9 -0
  231. package/dist/elements/paragraph/app.js +11 -0
  232. package/dist/elements/paragraph/core.d.ts +67 -0
  233. package/dist/elements/paragraph/core.js +29 -0
  234. package/dist/elements/paragraph/icon.svg +4 -0
  235. package/dist/elements/paragraph/languages/en.d.ts +4 -0
  236. package/dist/elements/paragraph/languages/en.js +2 -0
  237. package/dist/elements/paragraph/languages/ru.d.ts +4 -0
  238. package/dist/elements/paragraph/languages/ru.js +2 -0
  239. package/dist/elements/problem/_global.d.ts +112 -0
  240. package/dist/elements/problem/app.d.ts +30 -0
  241. package/dist/elements/problem/app.js +27 -0
  242. package/dist/elements/problem/assets/actions/answer.svg +3 -0
  243. package/dist/elements/problem/assets/actions/check.svg +3 -0
  244. package/dist/elements/problem/assets/actions/generate.svg +3 -0
  245. package/dist/elements/problem/assets/actions/hint.svg +3 -0
  246. package/dist/elements/problem/assets/actions/note.svg +3 -0
  247. package/dist/elements/problem/assets/actions/solution.svg +3 -0
  248. package/dist/elements/problem/assets/attributes/applied.svg +3 -0
  249. package/dist/elements/problem/assets/attributes/inter.svg +3 -0
  250. package/dist/elements/problem/assets/attributes/method.svg +3 -0
  251. package/dist/elements/problem/assets/attributes/pretty.svg +1 -0
  252. package/dist/elements/problem/assets/icon.svg +3 -0
  253. package/dist/elements/problem/components/Problem.vue +22 -0
  254. package/dist/elements/problem/components/ProblemButton.vue +21 -0
  255. package/dist/elements/problem/components/ProblemContainer.vue +9 -0
  256. package/dist/elements/problem/components/ProblemContent.vue +371 -0
  257. package/dist/elements/problem/components/ProblemExpander.vue +7 -0
  258. package/dist/elements/problem/components/ProblemExpanderSection.vue +58 -0
  259. package/dist/elements/problem/components/ProblemHeader.vue +106 -0
  260. package/dist/elements/problem/components/Problems.vue +87 -0
  261. package/dist/elements/problem/components/SubProblem.vue +14 -0
  262. package/dist/elements/problem/components/expanders/Check.vue +151 -0
  263. package/dist/elements/problem/components/expanders/Checks.vue +83 -0
  264. package/dist/elements/problem/components/expanders/DefaultPlusSections.vue +38 -0
  265. package/dist/elements/problem/components/expanders/Hint.vue +26 -0
  266. package/dist/elements/problem/composables/phrase.d.ts +2 -0
  267. package/dist/elements/problem/composables/phrase.js +7 -0
  268. package/dist/elements/problem/composables/problemScript.d.ts +3 -0
  269. package/dist/elements/problem/composables/problemScript.js +11 -0
  270. package/dist/elements/problem/core.d.ts +248 -0
  271. package/dist/elements/problem/core.js +17 -0
  272. package/dist/elements/problem/languages/en.d.ts +3 -0
  273. package/dist/elements/problem/languages/en.js +24 -0
  274. package/dist/elements/problem/languages/ru.d.ts +3 -0
  275. package/dist/elements/problem/languages/ru.js +24 -0
  276. package/dist/elements/problem/phrases.d.ts +16 -0
  277. package/dist/elements/problem/phrases.js +1 -0
  278. package/dist/elements/problem/problem.d.ts +106 -0
  279. package/dist/elements/problem/problem.js +37 -0
  280. package/dist/elements/problem/problemContent.d.ts +439 -0
  281. package/dist/elements/problem/problemContent.js +236 -0
  282. package/dist/elements/problem/problemScript.d.ts +26 -0
  283. package/dist/elements/problem/problemScript.js +79 -0
  284. package/dist/elements/problem/problems.d.ts +212 -0
  285. package/dist/elements/problem/problems.js +74 -0
  286. package/dist/elements/problem/rng.d.ts +18 -0
  287. package/dist/elements/problem/rng.js +76 -0
  288. package/dist/elements/problem/shared.d.ts +28 -0
  289. package/dist/elements/problem/shared.js +42 -0
  290. package/dist/elements/problem/step.d.ts +5 -0
  291. package/dist/elements/problem/step.js +13 -0
  292. package/dist/elements/problem/storage.d.ts +5 -0
  293. package/dist/elements/problem/storage.js +8 -0
  294. package/dist/elements/table/Table.vue +104 -0
  295. package/dist/elements/table/_global.d.ts +36 -0
  296. package/dist/elements/table/app.d.ts +30 -0
  297. package/dist/elements/table/app.js +11 -0
  298. package/dist/elements/table/core.d.ts +324 -0
  299. package/dist/elements/table/core.js +65 -0
  300. package/dist/elements/table/icon.svg +3 -0
  301. package/dist/elements/table/languages/en.d.ts +4 -0
  302. package/dist/elements/table/languages/en.js +2 -0
  303. package/dist/elements/table/languages/ru.d.ts +4 -0
  304. package/dist/elements/table/languages/ru.js +2 -0
  305. package/dist/elements/video/Video.vue +109 -0
  306. package/dist/elements/video/_global.d.ts +18 -0
  307. package/dist/elements/video/app.d.ts +16 -0
  308. package/dist/elements/video/app.js +11 -0
  309. package/dist/elements/video/core.d.ts +128 -0
  310. package/dist/elements/video/core.js +43 -0
  311. package/dist/elements/video/icon.svg +3 -0
  312. package/dist/elements/video/languages/en.d.ts +4 -0
  313. package/dist/elements/video/languages/en.js +2 -0
  314. package/dist/elements/video/languages/ru.d.ts +4 -0
  315. package/dist/elements/video/languages/ru.js +2 -0
  316. package/dist/elements/video/storage.d.ts +2 -0
  317. package/dist/elements/video/storage.js +5 -0
  318. package/dist/include.d.ts +6 -0
  319. package/dist/include.js +42 -0
  320. package/dist/index.d.ts +15 -0
  321. package/dist/index.js +15 -0
  322. package/dist/rawElement.d.ts +6 -0
  323. package/dist/rawElement.js +3 -0
  324. package/dist/resolve.d.ts +20 -0
  325. package/dist/resolve.js +99 -0
  326. package/dist/resolveStep.d.ts +9 -0
  327. package/dist/resolveStep.js +3 -0
  328. package/dist/shared/filePath.d.ts +5 -0
  329. package/dist/shared/filePath.js +11 -0
  330. package/dist/shared/invert.d.ts +1 -0
  331. package/dist/shared/invert.js +1 -0
  332. package/dist/shared/paragraphWrap.d.ts +3 -0
  333. package/dist/shared/paragraphWrap.js +15 -0
  334. package/dist/shared/photoswipe.d.ts +10 -0
  335. package/dist/shared/photoswipe.js +10 -0
  336. package/dist/slugify/index.d.ts +1 -0
  337. package/dist/slugify/index.js +12 -0
  338. package/dist/slugify/languages/en.d.ts +2 -0
  339. package/dist/slugify/languages/en.js +3 -0
  340. package/dist/slugify/languages/ru.d.ts +2 -0
  341. package/dist/slugify/languages/ru.js +38 -0
  342. package/dist/snippet.d.ts +66 -0
  343. package/dist/snippet.js +57 -0
  344. package/dist/tag.d.ts +22 -0
  345. package/dist/tag.js +20 -0
  346. package/dist/title.d.ts +8 -0
  347. package/dist/title.js +6 -0
  348. package/dist/toc.d.ts +34 -0
  349. package/dist/toc.js +52 -0
  350. package/dist/utils/case.d.ts +4 -0
  351. package/dist/utils/case.js +8 -0
  352. package/dist/utils/docs.d.ts +1 -0
  353. package/dist/utils/docs.js +22 -0
  354. package/package.json +48 -0
  355. package/types.d.ts +4 -0
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <div
3
+ class="bg-bg-accent/30 dark:bg-bg-accent/50 border-border/50
4
+ dark:border-border/90 rounded-xl border
5
+ transition-[background,border]"
6
+ >
7
+ <slot></slot>
8
+ </div>
9
+ </template>
@@ -0,0 +1,371 @@
1
+ <script lang="ts" setup>
2
+ import {
3
+ computed,
4
+ onMounted,
5
+ ref,
6
+ shallowRef,
7
+ useTemplateRef,
8
+ watchEffect,
9
+ type Component,
10
+ } from 'vue';
11
+ import { autoUpdate, offset, useFloating } from '@floating-ui/vue';
12
+ import {
13
+ isProseElement,
14
+ resolveRawElement,
15
+ type ProseElement,
16
+ } from '@jsprose/core';
17
+
18
+ import {
19
+ problemAnswer,
20
+ problemCheckSchema,
21
+ problemDescriptionSchema,
22
+ problemHintSchema,
23
+ problemNote,
24
+ problemSolution,
25
+ type CheckFunction,
26
+ type ProblemContentChild,
27
+ } from '../problemContent.js';
28
+ import { useProseContext } from '../../../app/composables/context.js';
29
+ import { useProblemPhrase } from '../composables/phrase.js';
30
+ import type { ProblemAction } from '../shared.js';
31
+ import { useArrayContainsAnchor } from '../../../app/composables/anchor.js';
32
+ import type { ProblemScriptInstance } from '../problemScript.js';
33
+ import type { problemSchema } from '../problem.js';
34
+ import type { subProblemSchema } from '../problems.js';
35
+ import { useElementStorage } from '../../../app/composables/storage.js';
36
+ import type { ProblemScriptStorage } from '../storage.js';
37
+ import { createProblemScriptInstance } from '../composables/problemScript.js';
38
+ import { DEFAULT_SEED, type ProblemSeed } from '../rng.js';
39
+ import plusIcon from '../../../app/shared/assets/plus.svg?raw';
40
+ import Render from '../../../app/shared/Render.vue';
41
+ import Hint from './expanders/Hint.vue';
42
+ import DefaultPlusSections from './expanders/DefaultPlusSections.vue';
43
+ import ProblemButton from './ProblemButton.vue';
44
+ import Checks from './expanders/Checks.vue';
45
+
46
+ const { element, initialElements } = defineProps<{
47
+ element:
48
+ | ProseElement<typeof problemSchema>
49
+ | ProseElement<typeof subProblemSchema>;
50
+ initialElements: ProseElement<ProblemContentChild>[];
51
+ }>();
52
+
53
+ const { EruditIcon, EruditTransition } = useProseContext();
54
+ const phrase = await useProblemPhrase();
55
+
56
+ const actionIcons: Record<ProblemAction, string> = Object.fromEntries(
57
+ Object.entries(
58
+ // @ts-ignore
59
+ import.meta.glob('../assets/actions/*.svg', {
60
+ query: 'raw',
61
+ eager: true,
62
+ import: 'default',
63
+ }),
64
+ ).map(([key, value]) => {
65
+ const name = key.split('/').pop()?.replace('.svg', '') ?? key;
66
+ return [name as any, value as string];
67
+ }),
68
+ );
69
+
70
+ const key = ref(0);
71
+ const elements =
72
+ shallowRef<ProseElement<ProblemContentChild>[]>(initialElements);
73
+
74
+ const description = computed(() => {
75
+ return elements.value.find((element) =>
76
+ isProseElement(element, problemDescriptionSchema),
77
+ )!;
78
+ });
79
+
80
+ const expanderComponents: Record<
81
+ Exclude<ProblemAction, 'generate'>,
82
+ Component
83
+ > = {
84
+ check: Checks,
85
+ hint: Hint,
86
+ answer: DefaultPlusSections,
87
+ solution: DefaultPlusSections,
88
+ note: DefaultPlusSections,
89
+ };
90
+
91
+ const expandableActions = computed(() => {
92
+ type ActionMap<T> =
93
+ T extends Partial<Exclude<Record<ProblemAction, any>, 'generate'>>
94
+ ? T
95
+ : never;
96
+
97
+ const actionMap: ActionMap<{
98
+ hint?: ProseElement<typeof problemHintSchema>[];
99
+ answer?: ProseElement<typeof problemAnswer.schema>;
100
+ solution?: ProseElement<typeof problemSolution.schema>;
101
+ note?: ProseElement<typeof problemNote.schema>;
102
+ check?: {
103
+ checkElements: ProseElement<typeof problemCheckSchema>[];
104
+ checkFunction?: CheckFunction;
105
+ };
106
+ }> = {};
107
+
108
+ const checks = elements.value.filter((element) =>
109
+ isProseElement(element, problemCheckSchema),
110
+ );
111
+ if (checks.length > 0) {
112
+ actionMap.check = {
113
+ checkElements: checks,
114
+ checkFunction: scriptCheck.value,
115
+ };
116
+ }
117
+
118
+ const hints = elements.value.filter((element) =>
119
+ isProseElement(element, problemHintSchema),
120
+ );
121
+ if (hints.length > 0) {
122
+ actionMap.hint = hints;
123
+ }
124
+
125
+ (['answer', 'solution', 'note'] as const).forEach((action) => {
126
+ const actionElements = elements.value.filter((element) => {
127
+ switch (action) {
128
+ case 'answer':
129
+ return isProseElement(element, problemAnswer.schema);
130
+ case 'solution':
131
+ return isProseElement(element, problemSolution.schema);
132
+ case 'note':
133
+ return isProseElement(element, problemNote.schema);
134
+ }
135
+ });
136
+
137
+ if (actionElements.length > 0) {
138
+ actionMap[action] = actionElements[0]! as any;
139
+ }
140
+ });
141
+
142
+ return actionMap;
143
+ });
144
+
145
+ const currentAction = ref<Exclude<ProblemAction, 'generate'>>();
146
+
147
+ const containsAnchorArray = useArrayContainsAnchor(elements.value);
148
+
149
+ watchEffect(() => {
150
+ const anchorIndex = containsAnchorArray.value;
151
+
152
+ if (anchorIndex === undefined) {
153
+ return;
154
+ }
155
+
156
+ const anchorElement = elements.value.at(anchorIndex);
157
+
158
+ switch (true) {
159
+ case isProseElement(anchorElement, problemHintSchema):
160
+ currentAction.value = 'hint';
161
+ break;
162
+ case isProseElement(anchorElement, problemAnswer.schema):
163
+ currentAction.value = 'answer';
164
+ break;
165
+ case isProseElement(anchorElement, problemSolution.schema):
166
+ currentAction.value = 'solution';
167
+ break;
168
+ case isProseElement(anchorElement, problemNote.schema):
169
+ currentAction.value = 'note';
170
+ break;
171
+ }
172
+ });
173
+
174
+ //
175
+ // Problem Script
176
+ //
177
+
178
+ const scriptInstance = shallowRef<ProblemScriptInstance>();
179
+ const scriptStorage = (await useElementStorage(
180
+ element as any,
181
+ )) as ProblemScriptStorage;
182
+ const isGenerator = computed(() => Boolean(scriptInstance.value?.isGenerator));
183
+ const scriptCheck = shallowRef<CheckFunction>();
184
+
185
+ onMounted(async () => {
186
+ scriptInstance.value = await createProblemScriptInstance(
187
+ scriptStorage?.resolvedScriptSrc,
188
+ element.data.scriptUniques,
189
+ );
190
+
191
+ if (scriptInstance.value) {
192
+ const initialGenerateResult =
193
+ scriptInstance.value!.generate(DEFAULT_SEED);
194
+ scriptCheck.value = initialGenerateResult.check;
195
+ }
196
+ });
197
+
198
+ const generateRotation = ref(0);
199
+ const generating = ref(false);
200
+ const seed = ref<ProblemSeed>(DEFAULT_SEED);
201
+ const usingCustomSeed = ref(false);
202
+
203
+ async function doGenerate() {
204
+ if (!scriptInstance.value) {
205
+ return;
206
+ }
207
+
208
+ generateRotation.value += 180;
209
+
210
+ if (generating.value) {
211
+ return;
212
+ }
213
+
214
+ generating.value = true;
215
+
216
+ if (usingCustomSeed.value) {
217
+ usingCustomSeed.value = false;
218
+ } else {
219
+ seed.value = Math.floor(Math.random() * 1000000000) + 1;
220
+ }
221
+
222
+ const generateResult = scriptInstance.value.generate(seed.value);
223
+
224
+ if (generateResult.check) {
225
+ scriptCheck.value = generateResult.check;
226
+ }
227
+
228
+ const rawElements = generateResult.problemContent;
229
+ const proseElements: ProseElement<ProblemContentChild>[] = [];
230
+ for (const rawElement of rawElements) {
231
+ const resolveResult = await resolveRawElement({
232
+ rawElement,
233
+ linkable: false,
234
+ });
235
+ proseElements.push(resolveResult.proseElement as any);
236
+ }
237
+
238
+ elements.value = proseElements;
239
+
240
+ key.value++;
241
+ generating.value = false;
242
+ }
243
+
244
+ //
245
+ // Seed Popup
246
+ //
247
+
248
+ const seedPopupVisible = ref(false);
249
+ const seedReferenceElement = useTemplateRef('seedReference');
250
+ const seedPopupElement = useTemplateRef('seedPopup');
251
+
252
+ const { floatingStyles: seedFloatingStyles } = useFloating(
253
+ seedReferenceElement,
254
+ seedPopupElement,
255
+ {
256
+ whileElementsMounted: autoUpdate,
257
+ placement: 'top',
258
+ },
259
+ );
260
+ </script>
261
+
262
+ <template>
263
+ <div>
264
+ <Suspense suspensible>
265
+ <div class="py-(--proseAsideWidth)" :key>
266
+ <Render
267
+ v-for="child of description.children"
268
+ :element="child"
269
+ />
270
+ </div>
271
+ </Suspense>
272
+
273
+ <div
274
+ v-if="Object.values(expandableActions).some(Boolean) || isGenerator"
275
+ class="gap-small micro:gap-normal flex flex-wrap
276
+ p-(--proseAsideWidth) pt-0"
277
+ >
278
+ <ProblemButton
279
+ v-for="(_, actionKey) in expandableActions"
280
+ :key="actionKey"
281
+ @click="
282
+ currentAction =
283
+ actionKey === currentAction ? undefined : actionKey
284
+ "
285
+ :active="actionKey === currentAction"
286
+ class="flex items-center gap-[7px]"
287
+ >
288
+ <EruditIcon
289
+ :name="actionIcons[actionKey]"
290
+ class="text-[1.3em]"
291
+ />
292
+ <span>{{ phrase[`action_${actionKey}`] }}</span>
293
+ </ProblemButton>
294
+ <div
295
+ v-if="isGenerator"
296
+ ref="seedReference"
297
+ @mouseenter="seedPopupVisible = true"
298
+ @mouseleave="seedPopupVisible = false"
299
+ >
300
+ <ProblemButton
301
+ @touchstart="
302
+ seedPopupVisible = seedPopupVisible ? false : true
303
+ "
304
+ @click="doGenerate"
305
+ class="flex items-center gap-[7px]"
306
+ >
307
+ <EruditIcon
308
+ :name="actionIcons.generate"
309
+ :style="{ transform: `rotate(${generateRotation}deg)` }"
310
+ class="text-[1.3em] transition-[transform]
311
+ backface-hidden"
312
+ />
313
+ <span>{{ phrase.action_generate }}</span>
314
+ </ProblemButton>
315
+ <EruditTransition>
316
+ <div
317
+ v-if="seedPopupVisible"
318
+ ref="seedPopup"
319
+ :style="seedFloatingStyles"
320
+ class="pb-2.5"
321
+ >
322
+ <form
323
+ class="shadow-border text-main-xs flex rounded
324
+ bg-neutral-900 text-white shadow-lg
325
+ dark:bg-neutral-200 dark:text-black"
326
+ @submit.prevent="doGenerate"
327
+ >
328
+ <input
329
+ type="text"
330
+ v-model="seed"
331
+ @input="usingCustomSeed = true"
332
+ :title="phrase.seed_explain"
333
+ @focus="($event as any).target.select()"
334
+ class="max-w-[100px] flex-1 p-[5px] text-center
335
+ outline-none"
336
+ />
337
+ <button
338
+ v-if="seed !== DEFAULT_SEED"
339
+ type="button"
340
+ @click="
341
+ seed = DEFAULT_SEED;
342
+ usingCustomSeed = true;
343
+ doGenerate();
344
+ "
345
+ class="cursor-pointer pr-[3px]"
346
+ >
347
+ <EruditIcon
348
+ :name="plusIcon"
349
+ class="hocus:text-white
350
+ dark:hocus:text-black rotate-45
351
+ text-[1.3em] text-neutral-400
352
+ transition-[color]
353
+ dark:text-neutral-600"
354
+ />
355
+ </button>
356
+ </form>
357
+ </div>
358
+ </EruditTransition>
359
+ </div>
360
+ </div>
361
+
362
+ <Suspense suspensible>
363
+ <component
364
+ v-if="currentAction"
365
+ :key="`${key}-${currentAction}`"
366
+ :is="expanderComponents[currentAction]"
367
+ :value="expandableActions[currentAction]"
368
+ />
369
+ </Suspense>
370
+ </div>
371
+ </template>
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <div>
3
+ <div class="border-border border-t transition-[border]">
4
+ <slot></slot>
5
+ </div>
6
+ </div>
7
+ </template>
@@ -0,0 +1,58 @@
1
+ <script lang="ts" setup>
2
+ import { ref, watchEffect } from 'vue';
3
+ import type { AnySchema, ProseElement } from '@jsprose/core';
4
+
5
+ import plusIcon from '../../../app/shared/assets/plus.svg?raw';
6
+ import { useProseContext } from '../../../app/composables/context.js';
7
+ import { useFormatText } from '../../../app/composables/formatText.js';
8
+ import { useContainsAnchor } from '../../../app/composables/anchor.js';
9
+ import Render from '../../../app/shared/Render.vue';
10
+
11
+ const { element } = defineProps<{
12
+ title: string;
13
+ element: ProseElement<AnySchema>;
14
+ }>();
15
+
16
+ const formatText = useFormatText();
17
+ const { EruditIcon } = useProseContext();
18
+ const opened = ref(false);
19
+ const containsAnchor = useContainsAnchor(element);
20
+
21
+ watchEffect(() => {
22
+ if (containsAnchor.value) {
23
+ opened.value = true;
24
+ }
25
+ });
26
+ </script>
27
+
28
+ <template>
29
+ <div
30
+ @click="opened = !opened"
31
+ class="group border-border text-text-muted relative flex cursor-pointer
32
+ items-center border-t p-(--proseAsideWidth) font-semibold
33
+ transition-[border] first:border-t-0"
34
+ >
35
+ <div class="flex-1">{{ formatText(title) }}</div>
36
+ <button
37
+ class="group-hocus:bg-border/80 text-text-muted shrink-0 rounded
38
+ bg-transparent p-0.5 transition-[background]"
39
+ >
40
+ <EruditIcon
41
+ :name="plusIcon"
42
+ :class="[
43
+ 'micro:text-[26px] text-[22px] transition-[rotate]',
44
+ opened ? 'rotate-45' : '',
45
+ ]"
46
+ />
47
+ </button>
48
+ </div>
49
+ <Suspense>
50
+ <div
51
+ v-if="opened"
52
+ class="border-border border-t border-dashed py-(--proseAsideWidth)
53
+ transition-[border]"
54
+ >
55
+ <Render v-for="child of element.children" :element="child" />
56
+ </div>
57
+ </Suspense>
58
+ </template>
@@ -0,0 +1,106 @@
1
+ <script lang="ts" setup>
2
+ import { useProseContext } from '../../../app/composables/context.js';
3
+ import { useFormatText } from '../../../app/composables/formatText.js';
4
+ import { useProblemPhrase } from '../composables/phrase.js';
5
+ import type { ProblemAttribute, ProblemInfo, ProblemLevel } from '../shared.js';
6
+
7
+ const { info } = defineProps<{
8
+ info: ProblemInfo;
9
+ }>();
10
+
11
+ const { EruditIcon } = useProseContext();
12
+ const formatText = useFormatText();
13
+ const phrase = await useProblemPhrase();
14
+
15
+ const attributeIcons: Record<ProblemAttribute, string> = Object.fromEntries(
16
+ Object.entries(
17
+ // @ts-ignore
18
+ import.meta.glob('../assets/attributes/*.svg', {
19
+ query: 'raw',
20
+ eager: true,
21
+ import: 'default',
22
+ }),
23
+ ).map(([key, value]) => {
24
+ const name = key.split('/').pop()?.replace('.svg', '') ?? key;
25
+ return [name as any, value as string];
26
+ }),
27
+ );
28
+
29
+ const levelEmojies: Record<ProblemLevel, string> = {
30
+ example: '👀',
31
+ easy: '😀',
32
+ medium: '🤔',
33
+ hard: '🤯',
34
+ };
35
+
36
+ const levelColors: Record<ProblemLevel, string> = {
37
+ example: 'light-dark(#1c8baf, #2a9ab8)',
38
+ easy: 'light-dark(#73af00, #79b800)',
39
+ medium: 'light-dark(#db9c00, #ffc01e)',
40
+ hard: 'light-dark(#dc2f51, #ff375f)',
41
+ };
42
+ </script>
43
+
44
+ <template>
45
+ <header
46
+ class="micro:flex-row micro:items-center micro:gap-normal gap-small flex
47
+ flex-col flex-wrap p-(--proseAsideWidth) pb-0"
48
+ >
49
+ <h2
50
+ class="text-text-deep text-main-lg flex-1 font-bold
51
+ transition-[color]"
52
+ >
53
+ {{ formatText(info.title) }}
54
+ </h2>
55
+ <div
56
+ class="micro:[--labelHeight:32px] gap-small micro:justify-start
57
+ micro:flex-row flex flex-row-reverse flex-wrap items-center
58
+ justify-end [--labelHeight:28px]"
59
+ >
60
+ <div
61
+ v-for="attribute of info.attributes.sort()"
62
+ :title="
63
+ typeof attribute === 'string'
64
+ ? phrase[`attribute_explain.${attribute}`]
65
+ : attribute.hint
66
+ "
67
+ class="border-border/60 bg-bg-main text-main-xs text-text-muted
68
+ flex h-(--labelHeight) cursor-help items-center gap-1
69
+ rounded-xl border px-2 shadow
70
+ shadow-[light-dark(#d9d9d9,#3c3c3c)]
71
+ transition-[background,border,color,box-shadow]"
72
+ >
73
+ <EruditIcon
74
+ v-if="typeof attribute === 'string' || attribute.icon"
75
+ :name="
76
+ typeof attribute === 'string'
77
+ ? attributeIcons[attribute]
78
+ : attribute.icon
79
+ "
80
+ class="text-[15px]"
81
+ />
82
+ <span>
83
+ {{
84
+ typeof attribute === 'string'
85
+ ? phrase[`attribute.${attribute}`]
86
+ : attribute.label
87
+ }}
88
+ </span>
89
+ </div>
90
+ <div
91
+ :style="{ '--levelColor': levelColors[info.level] }"
92
+ :title="phrase.level_hint"
93
+ class="text-main-xs flex h-(--labelHeight) cursor-help
94
+ items-center gap-1 rounded-xl border
95
+ border-(--levelColor)/30 bg-(--levelColor)/10 px-2
96
+ font-semibold text-(--levelColor) shadow
97
+ shadow-(color:--levelColor)/25"
98
+ >
99
+ <div class="text-[15px]">
100
+ {{ levelEmojies[info.level] }}
101
+ </div>
102
+ <div>{{ phrase[`level.${info.level}`] }}</div>
103
+ </div>
104
+ </div>
105
+ </header>
106
+ </template>
@@ -0,0 +1,87 @@
1
+ <script setup lang="ts">
2
+ import { ref, watchEffect } from 'vue';
3
+ import {
4
+ isProseElement,
5
+ type BlockSchema,
6
+ type ProseElement,
7
+ } from '@jsprose/core';
8
+
9
+ import { subProblemSchema, type problemsSchema } from '../problems.js';
10
+ import { useFormatText } from '../../../app/composables/formatText.js';
11
+ import { useArrayContainsAnchor } from '../../../app/composables/anchor.js';
12
+ import SubProblem from './SubProblem.vue';
13
+ import Block from '../../../app/shared/block/Block.vue';
14
+ import ProblemContainer from './ProblemContainer.vue';
15
+ import ProblemHeader from './ProblemHeader.vue';
16
+ import Render from '../../../app/shared/Render.vue';
17
+ import ProblemButton from './ProblemButton.vue';
18
+
19
+ const { element } = defineProps<{
20
+ element: ProseElement<typeof problemsSchema>;
21
+ }>();
22
+
23
+ const formatText = useFormatText();
24
+
25
+ const sharedChildren = element.children.filter(
26
+ (child) => !isProseElement(child, subProblemSchema),
27
+ ) as ProseElement<BlockSchema>[];
28
+
29
+ const subProblems = element.children.filter((child) =>
30
+ isProseElement(child, subProblemSchema),
31
+ ) as ProseElement<typeof subProblemSchema>[];
32
+
33
+ const activeSubProblemI = ref(0);
34
+
35
+ function getUnlabeledOrdinal(index: number) {
36
+ let count = 0;
37
+ for (let i = 0; i <= index; i++) {
38
+ if (!subProblems[i].data.label) count++;
39
+ }
40
+ return count;
41
+ }
42
+
43
+ const containsAnchorI = useArrayContainsAnchor(subProblems);
44
+
45
+ watchEffect(() => {
46
+ if (containsAnchorI.value !== undefined) {
47
+ activeSubProblemI.value = containsAnchorI.value;
48
+ }
49
+ });
50
+ </script>
51
+
52
+ <template>
53
+ <Block :element>
54
+ <ProblemContainer>
55
+ <ProblemHeader :info="element.data" />
56
+ <div v-if="sharedChildren.length" class="pt-(--proseAsideWidth)">
57
+ <Render
58
+ v-for="sharedChild of sharedChildren"
59
+ :element="sharedChild"
60
+ />
61
+ </div>
62
+ <div
63
+ class="gap-normal border-border flex flex-wrap border-b
64
+ px-(--proseAsideWidth) py-(--proseAsideWidth)
65
+ transition-[border]"
66
+ >
67
+ <ProblemButton
68
+ v-for="(subProblem, i) of subProblems"
69
+ :active="i === activeSubProblemI"
70
+ @click="activeSubProblemI = i"
71
+ >
72
+ {{
73
+ subProblem.data.label
74
+ ? formatText(subProblem.data.label)
75
+ : getUnlabeledOrdinal(i)
76
+ }}
77
+ </ProblemButton>
78
+ </div>
79
+ <Suspense>
80
+ <SubProblem
81
+ :key="activeSubProblemI"
82
+ :element="subProblems[activeSubProblemI]"
83
+ />
84
+ </Suspense>
85
+ </ProblemContainer>
86
+ </Block>
87
+ </template>
@@ -0,0 +1,14 @@
1
+ <script lang="ts" setup>
2
+ import type { ProseElement } from '@jsprose/core';
3
+
4
+ import type { subProblemSchema } from '../problems.js';
5
+ import ProblemContent from './ProblemContent.vue';
6
+
7
+ const { element } = defineProps<{
8
+ element: ProseElement<typeof subProblemSchema>;
9
+ }>();
10
+ </script>
11
+
12
+ <template>
13
+ <ProblemContent :element :initialElements="element.children" />
14
+ </template>