@verbb/plugin-kit-vue 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +132 -0
  4. package/dist/app/PluginKitProvider.d.ts +92 -0
  5. package/dist/app/PluginKitProvider.d.ts.map +1 -0
  6. package/dist/app/PluginKitProvider.js +75 -0
  7. package/dist/app/PluginKitProvider.js.map +1 -0
  8. package/dist/app/configure.d.ts +29 -0
  9. package/dist/app/configure.d.ts.map +1 -0
  10. package/dist/app/configure.js +35 -0
  11. package/dist/app/configure.js.map +1 -0
  12. package/dist/app/index.d.ts +5 -0
  13. package/dist/app/index.d.ts.map +1 -0
  14. package/dist/app/index.js +5 -0
  15. package/dist/app/mountShadowApp.d.ts +6 -0
  16. package/dist/app/mountShadowApp.d.ts.map +1 -0
  17. package/dist/app/mountShadowApp.js +2 -0
  18. package/dist/components/Button.d.ts +208 -0
  19. package/dist/components/Button.d.ts.map +1 -0
  20. package/dist/components/Button.js +71 -0
  21. package/dist/components/Button.js.map +1 -0
  22. package/dist/components/ButtonGroup.d.ts +22 -0
  23. package/dist/components/ButtonGroup.d.ts.map +1 -0
  24. package/dist/components/ButtonGroup.js +19 -0
  25. package/dist/components/ButtonGroup.js.map +1 -0
  26. package/dist/components/Calendar.d.ts +9 -0
  27. package/dist/components/Calendar.d.ts.map +1 -0
  28. package/dist/components/Calendar.js +13 -0
  29. package/dist/components/Calendar.js.map +1 -0
  30. package/dist/components/Checkbox.d.ts +177 -0
  31. package/dist/components/Checkbox.d.ts.map +1 -0
  32. package/dist/components/Checkbox.js +69 -0
  33. package/dist/components/Checkbox.js.map +1 -0
  34. package/dist/components/CheckboxInput.d.ts +210 -0
  35. package/dist/components/CheckboxInput.d.ts.map +1 -0
  36. package/dist/components/CheckboxInput.js +109 -0
  37. package/dist/components/CheckboxInput.js.map +1 -0
  38. package/dist/components/CheckboxSelect.d.ts +9 -0
  39. package/dist/components/CheckboxSelect.d.ts.map +1 -0
  40. package/dist/components/CheckboxSelect.js +13 -0
  41. package/dist/components/CheckboxSelect.js.map +1 -0
  42. package/dist/components/CodeEditor.d.ts +9 -0
  43. package/dist/components/CodeEditor.d.ts.map +1 -0
  44. package/dist/components/CodeEditor.js +13 -0
  45. package/dist/components/CodeEditor.js.map +1 -0
  46. package/dist/components/ColorInput.d.ts +9 -0
  47. package/dist/components/ColorInput.d.ts.map +1 -0
  48. package/dist/components/ColorInput.js +13 -0
  49. package/dist/components/ColorInput.js.map +1 -0
  50. package/dist/components/Combobox.d.ts +9 -0
  51. package/dist/components/Combobox.d.ts.map +1 -0
  52. package/dist/components/Combobox.js +13 -0
  53. package/dist/components/Combobox.js.map +1 -0
  54. package/dist/components/ComboboxInput.d.ts +410 -0
  55. package/dist/components/ComboboxInput.d.ts.map +1 -0
  56. package/dist/components/ComboboxInput.js +174 -0
  57. package/dist/components/ComboboxInput.js.map +1 -0
  58. package/dist/components/CopyButton.d.ts +9 -0
  59. package/dist/components/CopyButton.d.ts.map +1 -0
  60. package/dist/components/CopyButton.js +13 -0
  61. package/dist/components/CopyButton.js.map +1 -0
  62. package/dist/components/DatePicker.d.ts +9 -0
  63. package/dist/components/DatePicker.d.ts.map +1 -0
  64. package/dist/components/DatePicker.js +13 -0
  65. package/dist/components/DatePicker.js.map +1 -0
  66. package/dist/components/Dialog.d.ts +9 -0
  67. package/dist/components/Dialog.d.ts.map +1 -0
  68. package/dist/components/Dialog.js +13 -0
  69. package/dist/components/Dialog.js.map +1 -0
  70. package/dist/components/DropdownMenu.d.ts +29 -0
  71. package/dist/components/DropdownMenu.d.ts.map +1 -0
  72. package/dist/components/DropdownMenu.js +22 -0
  73. package/dist/components/DropdownMenu.js.map +1 -0
  74. package/dist/components/EditableTable.d.ts +9 -0
  75. package/dist/components/EditableTable.d.ts.map +1 -0
  76. package/dist/components/EditableTable.js +13 -0
  77. package/dist/components/EditableTable.js.map +1 -0
  78. package/dist/components/Field.d.ts +9 -0
  79. package/dist/components/Field.d.ts.map +1 -0
  80. package/dist/components/Field.js +13 -0
  81. package/dist/components/Field.js.map +1 -0
  82. package/dist/components/Icon.d.ts +9 -0
  83. package/dist/components/Icon.d.ts.map +1 -0
  84. package/dist/components/Icon.js +13 -0
  85. package/dist/components/Icon.js.map +1 -0
  86. package/dist/components/Input.d.ts +9 -0
  87. package/dist/components/Input.d.ts.map +1 -0
  88. package/dist/components/Input.js +13 -0
  89. package/dist/components/Input.js.map +1 -0
  90. package/dist/components/InputGroup.d.ts +43 -0
  91. package/dist/components/InputGroup.d.ts.map +1 -0
  92. package/dist/components/InputGroup.js +28 -0
  93. package/dist/components/InputGroup.js.map +1 -0
  94. package/dist/components/Lightswitch.d.ts +197 -0
  95. package/dist/components/Lightswitch.d.ts.map +1 -0
  96. package/dist/components/Lightswitch.js +74 -0
  97. package/dist/components/Lightswitch.js.map +1 -0
  98. package/dist/components/Popover.d.ts +9 -0
  99. package/dist/components/Popover.d.ts.map +1 -0
  100. package/dist/components/Popover.js +13 -0
  101. package/dist/components/Popover.js.map +1 -0
  102. package/dist/components/Popup.d.ts +9 -0
  103. package/dist/components/Popup.d.ts.map +1 -0
  104. package/dist/components/Popup.js +13 -0
  105. package/dist/components/Popup.js.map +1 -0
  106. package/dist/components/RadioGroup.d.ts +15 -0
  107. package/dist/components/RadioGroup.d.ts.map +1 -0
  108. package/dist/components/RadioGroup.js +16 -0
  109. package/dist/components/RadioGroup.js.map +1 -0
  110. package/dist/components/RadioGroupInput.d.ts +202 -0
  111. package/dist/components/RadioGroupInput.d.ts.map +1 -0
  112. package/dist/components/RadioGroupInput.js +84 -0
  113. package/dist/components/RadioGroupInput.js.map +1 -0
  114. package/dist/components/ScrollArea.d.ts +9 -0
  115. package/dist/components/ScrollArea.d.ts.map +1 -0
  116. package/dist/components/ScrollArea.js +13 -0
  117. package/dist/components/ScrollArea.js.map +1 -0
  118. package/dist/components/Select.d.ts +22 -0
  119. package/dist/components/Select.d.ts.map +1 -0
  120. package/dist/components/Select.js +19 -0
  121. package/dist/components/Select.js.map +1 -0
  122. package/dist/components/SelectInput.d.ts +311 -0
  123. package/dist/components/SelectInput.d.ts.map +1 -0
  124. package/dist/components/SelectInput.js +127 -0
  125. package/dist/components/SelectInput.js.map +1 -0
  126. package/dist/components/Separator.d.ts +9 -0
  127. package/dist/components/Separator.d.ts.map +1 -0
  128. package/dist/components/Separator.js +13 -0
  129. package/dist/components/Separator.js.map +1 -0
  130. package/dist/components/Spinner.d.ts +94 -0
  131. package/dist/components/Spinner.d.ts.map +1 -0
  132. package/dist/components/Spinner.js +40 -0
  133. package/dist/components/Spinner.js.map +1 -0
  134. package/dist/components/Status.d.ts +9 -0
  135. package/dist/components/Status.d.ts.map +1 -0
  136. package/dist/components/Status.js +13 -0
  137. package/dist/components/Status.js.map +1 -0
  138. package/dist/components/Tabs.d.ts +29 -0
  139. package/dist/components/Tabs.d.ts.map +1 -0
  140. package/dist/components/Tabs.js +22 -0
  141. package/dist/components/Tabs.js.map +1 -0
  142. package/dist/components/Textarea.d.ts +9 -0
  143. package/dist/components/Textarea.d.ts.map +1 -0
  144. package/dist/components/Textarea.js +13 -0
  145. package/dist/components/Textarea.js.map +1 -0
  146. package/dist/components/TimePicker.d.ts +9 -0
  147. package/dist/components/TimePicker.d.ts.map +1 -0
  148. package/dist/components/TimePicker.js +13 -0
  149. package/dist/components/TimePicker.js.map +1 -0
  150. package/dist/components/Tiptap.d.ts +22 -0
  151. package/dist/components/Tiptap.d.ts.map +1 -0
  152. package/dist/components/Tiptap.js +21 -0
  153. package/dist/components/Tiptap.js.map +1 -0
  154. package/dist/components/Toggle.d.ts +9 -0
  155. package/dist/components/Toggle.d.ts.map +1 -0
  156. package/dist/components/Toggle.js +13 -0
  157. package/dist/components/Toggle.js.map +1 -0
  158. package/dist/components/ToggleGroup.d.ts +9 -0
  159. package/dist/components/ToggleGroup.d.ts.map +1 -0
  160. package/dist/components/ToggleGroup.js +13 -0
  161. package/dist/components/ToggleGroup.js.map +1 -0
  162. package/dist/components/Tooltip.d.ts +9 -0
  163. package/dist/components/Tooltip.d.ts.map +1 -0
  164. package/dist/components/Tooltip.js +13 -0
  165. package/dist/components/Tooltip.js.map +1 -0
  166. package/dist/components/index.d.ts +38 -0
  167. package/dist/components/index.d.ts.map +1 -0
  168. package/dist/components/index.js +38 -0
  169. package/dist/createPkComponent.d.ts +17 -0
  170. package/dist/createPkComponent.d.ts.map +1 -0
  171. package/dist/createPkComponent.js +33 -0
  172. package/dist/createPkComponent.js.map +1 -0
  173. package/dist/fault/AppFaultBoundary.d.ts +17 -0
  174. package/dist/fault/AppFaultBoundary.d.ts.map +1 -0
  175. package/dist/fault/AppFaultBoundary.js +31 -0
  176. package/dist/fault/AppFaultBoundary.js.map +1 -0
  177. package/dist/fault/AppFaultProvider.d.ts +116 -0
  178. package/dist/fault/AppFaultProvider.d.ts.map +1 -0
  179. package/dist/fault/AppFaultProvider.js +214 -0
  180. package/dist/fault/AppFaultProvider.js.map +1 -0
  181. package/dist/fault/FaultFallback.d.ts +88 -0
  182. package/dist/fault/FaultFallback.d.ts.map +1 -0
  183. package/dist/fault/FaultFallback.js +91 -0
  184. package/dist/fault/FaultFallback.js.map +1 -0
  185. package/dist/fault/buildSupportBundle.d.ts +3 -0
  186. package/dist/fault/buildSupportBundle.d.ts.map +1 -0
  187. package/dist/fault/buildSupportBundle.js +22 -0
  188. package/dist/fault/buildSupportBundle.js.map +1 -0
  189. package/dist/fault/index.d.ts +8 -0
  190. package/dist/fault/index.d.ts.map +1 -0
  191. package/dist/fault/index.js +7 -0
  192. package/dist/fault/isIgnorableGlobalError.d.ts +3 -0
  193. package/dist/fault/isIgnorableGlobalError.d.ts.map +1 -0
  194. package/dist/fault/isIgnorableGlobalError.js +14 -0
  195. package/dist/fault/isIgnorableGlobalError.js.map +1 -0
  196. package/dist/fault/types.d.ts +18 -0
  197. package/dist/fault/types.d.ts.map +1 -0
  198. package/dist/fault/useUiWatchdog.d.ts +14 -0
  199. package/dist/fault/useUiWatchdog.d.ts.map +1 -0
  200. package/dist/fault/useUiWatchdog.js +37 -0
  201. package/dist/fault/useUiWatchdog.js.map +1 -0
  202. package/dist/forms/Field.d.ts +123 -0
  203. package/dist/forms/Field.d.ts.map +1 -0
  204. package/dist/forms/Field.js +77 -0
  205. package/dist/forms/Field.js.map +1 -0
  206. package/dist/forms/SchemaFormEngine.d.ts +50 -0
  207. package/dist/forms/SchemaFormEngine.d.ts.map +1 -0
  208. package/dist/forms/SchemaFormEngine.js +372 -0
  209. package/dist/forms/SchemaFormEngine.js.map +1 -0
  210. package/dist/forms/SchemaFormFieldNode.d.ts +41 -0
  211. package/dist/forms/SchemaFormFieldNode.d.ts.map +1 -0
  212. package/dist/forms/SchemaFormFieldNode.js +73 -0
  213. package/dist/forms/SchemaFormFieldNode.js.map +1 -0
  214. package/dist/forms/assertSchemaRegistry.d.ts +17 -0
  215. package/dist/forms/assertSchemaRegistry.d.ts.map +1 -0
  216. package/dist/forms/assertSchemaRegistry.js +68 -0
  217. package/dist/forms/assertSchemaRegistry.js.map +1 -0
  218. package/dist/forms/builtin-field-loaders.d.ts +11 -0
  219. package/dist/forms/builtin-field-loaders.d.ts.map +1 -0
  220. package/dist/forms/builtin-field-loaders.js +31 -0
  221. package/dist/forms/builtin-field-loaders.js.map +1 -0
  222. package/dist/forms/components/FieldWrap.d.ts +124 -0
  223. package/dist/forms/components/FieldWrap.d.ts.map +1 -0
  224. package/dist/forms/components/FieldWrap.js +99 -0
  225. package/dist/forms/components/FieldWrap.js.map +1 -0
  226. package/dist/forms/components/ModalTabs.d.ts +147 -0
  227. package/dist/forms/components/ModalTabs.d.ts.map +1 -0
  228. package/dist/forms/components/ModalTabs.js +135 -0
  229. package/dist/forms/components/ModalTabs.js.map +1 -0
  230. package/dist/forms/components/index.d.ts +3 -0
  231. package/dist/forms/components/index.d.ts.map +1 -0
  232. package/dist/forms/components/schemaErrors.d.ts +4 -0
  233. package/dist/forms/components/schemaErrors.d.ts.map +1 -0
  234. package/dist/forms/components/schemaErrors.js +34 -0
  235. package/dist/forms/components/schemaErrors.js.map +1 -0
  236. package/dist/forms/datetime.d.ts +11 -0
  237. package/dist/forms/datetime.d.ts.map +1 -0
  238. package/dist/forms/datetime.js +35 -0
  239. package/dist/forms/datetime.js.map +1 -0
  240. package/dist/forms/engine/context.d.ts +44 -0
  241. package/dist/forms/engine/context.d.ts.map +1 -0
  242. package/dist/forms/engine/context.js +15 -0
  243. package/dist/forms/engine/context.js.map +1 -0
  244. package/dist/forms/fields/CheckboxSelectField.d.ts +29 -0
  245. package/dist/forms/fields/CheckboxSelectField.d.ts.map +1 -0
  246. package/dist/forms/fields/CheckboxSelectField.js +44 -0
  247. package/dist/forms/fields/CheckboxSelectField.js.map +1 -0
  248. package/dist/forms/fields/CodeEditorField.d.ts +29 -0
  249. package/dist/forms/fields/CodeEditorField.d.ts.map +1 -0
  250. package/dist/forms/fields/CodeEditorField.js +46 -0
  251. package/dist/forms/fields/CodeEditorField.js.map +1 -0
  252. package/dist/forms/fields/ColorField.d.ts +29 -0
  253. package/dist/forms/fields/ColorField.d.ts.map +1 -0
  254. package/dist/forms/fields/ColorField.js +42 -0
  255. package/dist/forms/fields/ColorField.js.map +1 -0
  256. package/dist/forms/fields/ComboboxField.d.ts +29 -0
  257. package/dist/forms/fields/ComboboxField.d.ts.map +1 -0
  258. package/dist/forms/fields/ComboboxField.js +47 -0
  259. package/dist/forms/fields/ComboboxField.js.map +1 -0
  260. package/dist/forms/fields/DateTimeField.d.ts +29 -0
  261. package/dist/forms/fields/DateTimeField.d.ts.map +1 -0
  262. package/dist/forms/fields/DateTimeField.js +54 -0
  263. package/dist/forms/fields/DateTimeField.js.map +1 -0
  264. package/dist/forms/fields/GroupField.d.ts +27 -0
  265. package/dist/forms/fields/GroupField.d.ts.map +1 -0
  266. package/dist/forms/fields/GroupField.js +55 -0
  267. package/dist/forms/fields/GroupField.js.map +1 -0
  268. package/dist/forms/fields/LightswitchField.d.ts +29 -0
  269. package/dist/forms/fields/LightswitchField.d.ts.map +1 -0
  270. package/dist/forms/fields/LightswitchField.js +39 -0
  271. package/dist/forms/fields/LightswitchField.js.map +1 -0
  272. package/dist/forms/fields/NumberField.d.ts +29 -0
  273. package/dist/forms/fields/NumberField.d.ts.map +1 -0
  274. package/dist/forms/fields/NumberField.js +44 -0
  275. package/dist/forms/fields/NumberField.js.map +1 -0
  276. package/dist/forms/fields/RadioGroupField.d.ts +29 -0
  277. package/dist/forms/fields/RadioGroupField.d.ts.map +1 -0
  278. package/dist/forms/fields/RadioGroupField.js +55 -0
  279. package/dist/forms/fields/RadioGroupField.js.map +1 -0
  280. package/dist/forms/fields/SelectField.d.ts +29 -0
  281. package/dist/forms/fields/SelectField.d.ts.map +1 -0
  282. package/dist/forms/fields/SelectField.js +58 -0
  283. package/dist/forms/fields/SelectField.js.map +1 -0
  284. package/dist/forms/fields/TextField.d.ts +29 -0
  285. package/dist/forms/fields/TextField.d.ts.map +1 -0
  286. package/dist/forms/fields/TextField.js +43 -0
  287. package/dist/forms/fields/TextField.js.map +1 -0
  288. package/dist/forms/fields/TextareaField.d.ts +29 -0
  289. package/dist/forms/fields/TextareaField.d.ts.map +1 -0
  290. package/dist/forms/fields/TextareaField.js +44 -0
  291. package/dist/forms/fields/TextareaField.js.map +1 -0
  292. package/dist/forms/fields/options.d.ts +13 -0
  293. package/dist/forms/fields/options.d.ts.map +1 -0
  294. package/dist/forms/fields/options.js +29 -0
  295. package/dist/forms/fields/options.js.map +1 -0
  296. package/dist/forms/index.d.ts +13 -0
  297. package/dist/forms/index.d.ts.map +1 -0
  298. package/dist/forms/index.js +12 -0
  299. package/dist/forms/registry.d.ts +10 -0
  300. package/dist/forms/registry.d.ts.map +1 -0
  301. package/dist/forms/registry.js +45 -0
  302. package/dist/forms/registry.js.map +1 -0
  303. package/dist/forms/useEngineField.d.ts +11 -0
  304. package/dist/forms/useEngineField.d.ts.map +1 -0
  305. package/dist/forms/useEngineField.js +34 -0
  306. package/dist/forms/useEngineField.js.map +1 -0
  307. package/dist/forms/utils.d.ts +6 -0
  308. package/dist/forms/utils.d.ts.map +1 -0
  309. package/dist/forms/utils.js +20 -0
  310. package/dist/forms/utils.js.map +1 -0
  311. package/dist/hooks/index.d.ts +2 -0
  312. package/dist/hooks/index.d.ts.map +1 -0
  313. package/dist/hooks/index.js +2 -0
  314. package/dist/hooks/useTranslation.d.ts +4 -0
  315. package/dist/hooks/useTranslation.d.ts.map +1 -0
  316. package/dist/hooks/useTranslation.js +10 -0
  317. package/dist/hooks/useTranslation.js.map +1 -0
  318. package/dist/index.d.ts +3 -0
  319. package/dist/index.d.ts.map +1 -0
  320. package/dist/index.js +42 -0
  321. package/dist/utils/cn.d.ts +4 -0
  322. package/dist/utils/cn.d.ts.map +1 -0
  323. package/dist/utils/cn.js +11 -0
  324. package/dist/utils/cn.js.map +1 -0
  325. package/dist/utils/craftHostBridge.d.ts +17 -0
  326. package/dist/utils/craftHostBridge.d.ts.map +1 -0
  327. package/dist/utils/craftHostBridge.js +29 -0
  328. package/dist/utils/craftHostBridge.js.map +1 -0
  329. package/dist/utils/index.d.ts +9 -0
  330. package/dist/utils/index.d.ts.map +1 -0
  331. package/dist/utils/index.js +8 -0
  332. package/dist/utils/pk-change.d.ts +5 -0
  333. package/dist/utils/pk-change.d.ts.map +1 -0
  334. package/dist/utils/pk-change.js +13 -0
  335. package/dist/utils/pk-change.js.map +1 -0
  336. package/package.json +109 -0
  337. package/style.css +4 -0
  338. package/tailwind-preflight-scope.css +28 -0
  339. package/tailwind-theme.css +245 -0
  340. package/vite-dev.mjs +60 -0
@@ -0,0 +1,372 @@
1
+ import { Separator } from "../components/Separator.js";
2
+ import { SchemaEngineContextKey } from "./engine/context.js";
3
+ import { getFormComponentRegistry } from "./registry.js";
4
+ import { SchemaFormFieldNode } from "./SchemaFormFieldNode.js";
5
+ import { isRecord, normalizeAttrs, readEventValue } from "./utils.js";
6
+ import { defineComponent, h, inject, onBeforeUnmount, onMounted, provide, ref, shallowRef } from "vue";
7
+ import { FormStateStore, buildGroupedMessage, createValidationEngine, evaluateCondition, normalizeSchema } from "@verbb/plugin-kit-forms";
8
+ //#region src/forms/SchemaFormEngine.ts
9
+ var normalizeServerErrors = (rawErrors) => {
10
+ const normalized = {};
11
+ if (!rawErrors) return normalized;
12
+ const appendMessages = (path, messages) => {
13
+ if (!path) return;
14
+ const nextMessages = messages.filter((message) => message !== void 0 && message !== null && message !== "").map((message) => String(message));
15
+ if (!nextMessages.length) return;
16
+ if (!normalized[path]) normalized[path] = [];
17
+ normalized[path].push(...nextMessages);
18
+ };
19
+ const collectErrors = (node, path) => {
20
+ if (Array.isArray(node)) {
21
+ if (node.length === 0) return;
22
+ if (node.every((entry) => typeof entry === "string")) {
23
+ appendMessages(path, node);
24
+ return;
25
+ }
26
+ if (!path) {
27
+ node.forEach((entry) => collectErrors(entry, path));
28
+ return;
29
+ }
30
+ node.forEach((entry, index) => {
31
+ collectErrors(entry, `${path}.${index}`);
32
+ });
33
+ return;
34
+ }
35
+ if (!isRecord(node)) return;
36
+ Object.entries(node).forEach(([key, value]) => {
37
+ collectErrors(value, path ? `${path}.${key}` : key);
38
+ });
39
+ };
40
+ if (Array.isArray(rawErrors)) {
41
+ collectErrors(rawErrors, "");
42
+ return normalized;
43
+ }
44
+ if (isRecord(rawErrors) && "errors" in rawErrors) {
45
+ collectErrors(rawErrors.errors, "");
46
+ return normalized;
47
+ }
48
+ collectErrors(rawErrors, "");
49
+ return normalized;
50
+ };
51
+ var createEngineFieldComponent = (formRef) => defineComponent({
52
+ name: "SchemaEngineField",
53
+ props: { name: {
54
+ type: String,
55
+ required: true
56
+ } },
57
+ setup(props, { slots }) {
58
+ const version = ref(0);
59
+ let unsubscribe;
60
+ onMounted(() => {
61
+ unsubscribe = formRef.value?.store.subscribe(() => {
62
+ version.value += 1;
63
+ });
64
+ });
65
+ onBeforeUnmount(() => {
66
+ unsubscribe?.();
67
+ });
68
+ return () => {
69
+ const form = formRef.value;
70
+ if (!form) return null;
71
+ version.value;
72
+ const fieldApi = {
73
+ state: { value: form.getFieldValue(props.name) },
74
+ handleChange: (valueOrEvent) => {
75
+ form.setFieldValue(props.name, readEventValue(valueOrEvent));
76
+ },
77
+ handleBlur: () => {
78
+ form.store.setTouched(props.name, true);
79
+ },
80
+ errors: form.getErrorMapFields()[props.name] || []
81
+ };
82
+ return slots.default?.(fieldApi);
83
+ };
84
+ }
85
+ });
86
+ var buildConditionData = (form, field, values) => {
87
+ const scopePath = typeof field._scopePath === "string" ? field._scopePath : "";
88
+ const scopedValues = scopePath ? form.getFieldValue(scopePath) : null;
89
+ const scopedObject = isRecord(scopedValues) ? scopedValues : {};
90
+ const conditionContext = form.getConditionContext?.(values, field);
91
+ const normalizedConditionContext = isRecord(conditionContext) ? conditionContext : {};
92
+ const fieldData = isRecord(field._data) ? field._data : {};
93
+ return {
94
+ ...values,
95
+ ...scopedObject,
96
+ ...fieldData,
97
+ ...normalizedConditionContext
98
+ };
99
+ };
100
+ var renderSchemaItem = (schemaItem, index, form) => {
101
+ return h(SchemaItem, {
102
+ key: typeof schemaItem._id === "string" ? schemaItem._id : `schema-item-${index}`,
103
+ field: schemaItem,
104
+ form
105
+ }, { default: () => h(SchemaRenderer, { schema: schemaItem }) });
106
+ };
107
+ var renderFormField = (schema, form) => {
108
+ const { $field, ...props } = schema.$field ? {
109
+ $field: schema.$field,
110
+ ...schema
111
+ } : {
112
+ $field: schema.type,
113
+ ...schema
114
+ };
115
+ return h(SchemaFormFieldNode, {
116
+ fieldType: String($field ?? ""),
117
+ schema,
118
+ field: { ...props },
119
+ form
120
+ }, { default: () => props.children ? h(SchemaRenderer, { schema: props.children }) : null });
121
+ };
122
+ var renderHtmlElement = (schema) => {
123
+ const { $el, children, attrs = {} } = schema;
124
+ const normalizedAttrs = normalizeAttrs(isRecord(attrs) ? attrs : {});
125
+ if (typeof $el !== "string" || !$el) return null;
126
+ if ($el === "hr") return h(Separator, normalizedAttrs);
127
+ return h($el, normalizedAttrs, children ? () => h(SchemaRenderer, { schema: children }) : void 0);
128
+ };
129
+ var renderFormComponent = (schema) => {
130
+ const { $cmp, props = {}, children, ...rest } = schema;
131
+ const Component = getFormComponentRegistry()[$cmp];
132
+ if (!Component) {
133
+ console.warn(`Unknown form component: ${$cmp}`);
134
+ return null;
135
+ }
136
+ const componentProps = {
137
+ ...isRecord(props) ? props : {},
138
+ ...rest
139
+ };
140
+ if (Boolean(Component.usesSchemaNode)) componentProps.schemaNode = schema;
141
+ else if ("schemaNode" in componentProps) delete componentProps.schemaNode;
142
+ return h(Component, componentProps, { default: () => children ? h(SchemaRenderer, { schema: children }) : null });
143
+ };
144
+ var SchemaItem = defineComponent({
145
+ name: "SchemaItem",
146
+ props: {
147
+ field: {
148
+ type: Object,
149
+ required: true
150
+ },
151
+ form: {
152
+ type: Object,
153
+ required: true
154
+ }
155
+ },
156
+ setup(props, { slots }) {
157
+ const shouldShow = ref(true);
158
+ const resolveVisibility = (values) => {
159
+ if (!props.field.if) return true;
160
+ return Boolean(evaluateCondition(props.field.if, buildConditionData(props.form, props.field, values)));
161
+ };
162
+ const update = () => {
163
+ shouldShow.value = resolveVisibility(props.form.store.state.values);
164
+ };
165
+ update();
166
+ onBeforeUnmount(props.form.store.subscribe(update));
167
+ return () => {
168
+ if (!shouldShow.value) return props.field.hideOnIf ? h("div", { style: { display: "none" } }, slots.default?.()) : null;
169
+ return slots.default?.();
170
+ };
171
+ }
172
+ });
173
+ var SchemaRenderer = defineComponent({
174
+ name: "SchemaRenderer",
175
+ props: { schema: {
176
+ type: null,
177
+ required: true
178
+ } },
179
+ setup(props) {
180
+ const form = provideAwareForm();
181
+ return () => {
182
+ const schema = props.schema;
183
+ if (typeof schema === "string") return schema;
184
+ if (Array.isArray(schema)) return schema.map((schemaItem, index) => {
185
+ if (typeof schemaItem === "string") return schemaItem;
186
+ if (!isRecord(schemaItem)) return null;
187
+ return renderSchemaItem(schemaItem, index, form);
188
+ });
189
+ if (schema.$field || schema.$cmp === "Field") return renderFormField(schema, form);
190
+ if (schema.$el) return renderHtmlElement(schema);
191
+ if (schema.$cmp) return renderFormComponent(schema);
192
+ console.warn("Unknown schema item:", schema);
193
+ return null;
194
+ };
195
+ }
196
+ });
197
+ var provideAwareForm = () => {
198
+ const form = inject(SchemaEngineContextKey, null);
199
+ if (!form) throw new Error("SchemaRenderer must be used within SchemaFormEngine.");
200
+ return form;
201
+ };
202
+ var useSchemaFormEngine = ({ schemaIndex = null, defaultValues = {}, errors, onChange, getConditionContext, parentForm, parentPath }) => {
203
+ if (!schemaIndex) throw new Error("SchemaFormEngine requires a compiled schemaIndex.");
204
+ const index = {
205
+ ...schemaIndex,
206
+ schema: normalizeSchema(schemaIndex.schema)
207
+ };
208
+ const store = new FormStateStore(defaultValues);
209
+ const validationEngine = createValidationEngine(index, { conditionDataResolver: getConditionContext });
210
+ const labelMap = /* @__PURE__ */ new Map();
211
+ const nestedForms = /* @__PURE__ */ new Map();
212
+ const formRef = shallowRef(null);
213
+ const Field = createEngineFieldComponent(formRef);
214
+ index.fieldEntries.forEach((entry) => {
215
+ if (entry.path) {
216
+ const label = String(entry.field?.label || entry.field?.name || entry.path);
217
+ labelMap.set(entry.path, label);
218
+ }
219
+ });
220
+ let onSubmitHandler = null;
221
+ let onErrorHandler = null;
222
+ let onSuccessHandler = null;
223
+ let onChangeHandler = onChange ? (value) => {
224
+ if (formRef.value) onChange(value, formRef.value);
225
+ } : null;
226
+ const validateNestedForms = () => {
227
+ const nestedErrors = {};
228
+ nestedForms.forEach((api, path) => {
229
+ const result = api.validate();
230
+ if (result?.fields) Object.entries(result.fields).forEach(([fieldPath, messages]) => {
231
+ const mergedPath = fieldPath ? `${path}.${fieldPath}` : path;
232
+ nestedErrors[mergedPath] = messages;
233
+ });
234
+ });
235
+ return nestedErrors;
236
+ };
237
+ const getGroupedErrorsForPath = (path) => {
238
+ if (!path) return [];
239
+ const currentErrors = store.state.errors || {};
240
+ const rootErrors = currentErrors[path] || [];
241
+ const childKeys = Object.keys(currentErrors).filter((key) => key.startsWith(`${path}.`));
242
+ if (!childKeys.length) return rootErrors;
243
+ const parentLabel = labelMap.get(path);
244
+ const groupedMessages = [];
245
+ childKeys.forEach((key) => {
246
+ const wildcardPath = key.replace(/\.\d+(?=\.|$)/g, ".*");
247
+ const childLabel = labelMap.get(wildcardPath) || key.split(".").slice(-1)[0];
248
+ (currentErrors[key] || []).forEach((message) => {
249
+ if (parentLabel) {
250
+ groupedMessages.push(buildGroupedMessage(String(message), parentLabel, childLabel));
251
+ return;
252
+ }
253
+ groupedMessages.push(String(message));
254
+ });
255
+ });
256
+ return Array.from(new Set([...rootErrors, ...groupedMessages]));
257
+ };
258
+ const handleSubmit = async () => {
259
+ const errorsMap = validationEngine.validate(store.state.values)?.fields || {};
260
+ const nestedErrors = validateNestedForms();
261
+ const mergedErrors = {
262
+ ...errorsMap,
263
+ ...nestedErrors
264
+ };
265
+ if (Object.keys(mergedErrors).length > 0) {
266
+ store.setErrors(mergedErrors);
267
+ onErrorHandler?.(mergedErrors);
268
+ return;
269
+ }
270
+ store.clearErrors();
271
+ await onSubmitHandler?.(store.state.values);
272
+ if (parentForm && parentPath) parentForm.setFieldValue(parentPath, store.state.values);
273
+ onSuccessHandler?.(store.state.values);
274
+ };
275
+ const form = {
276
+ schema: index.schema,
277
+ store,
278
+ index,
279
+ Field,
280
+ getFieldValue: (path) => store.getValue(path),
281
+ setFieldValue: (path, value) => store.setValue(path, value),
282
+ getErrorMapFields: () => store.state.errors || {},
283
+ SchemaRenderer,
284
+ handleSubmit,
285
+ onChange: (handler) => {
286
+ onChangeHandler = handler;
287
+ },
288
+ onSubmit: (handler) => {
289
+ onSubmitHandler = handler;
290
+ },
291
+ onError: (handler) => {
292
+ onErrorHandler = handler;
293
+ },
294
+ onSuccess: (handler) => {
295
+ onSuccessHandler = handler;
296
+ },
297
+ registerNestedForm: (path, api) => {
298
+ nestedForms.set(path, api);
299
+ },
300
+ unregisterNestedForm: (path) => {
301
+ nestedForms.delete(path);
302
+ },
303
+ getGroupedErrorsForPath,
304
+ getConditionContext: (values, field) => getConditionContext?.(values, field) || {}
305
+ };
306
+ formRef.value = form;
307
+ onBeforeUnmount(store.subscribe(() => {
308
+ onChangeHandler?.(store.state.values);
309
+ }));
310
+ const normalized = normalizeServerErrors(errors);
311
+ if (Object.keys(normalized).length) store.setErrors(normalized);
312
+ if (parentForm && parentPath) {
313
+ const nestedApi = {
314
+ path: parentPath,
315
+ validate: () => {
316
+ const result = validationEngine.validate(store.state.values);
317
+ const fieldErrors = result?.fields || {};
318
+ if (Object.keys(fieldErrors).length) store.setErrors(fieldErrors);
319
+ else store.clearErrors();
320
+ return result;
321
+ },
322
+ getValues: () => store.state.values
323
+ };
324
+ parentForm.registerNestedForm(parentPath, nestedApi);
325
+ onBeforeUnmount(() => {
326
+ parentForm.unregisterNestedForm(parentPath);
327
+ });
328
+ }
329
+ return form;
330
+ };
331
+ var SchemaFormEngine = defineComponent({
332
+ name: "SchemaFormEngine",
333
+ props: {
334
+ form: {
335
+ type: Object,
336
+ required: true
337
+ },
338
+ class: {
339
+ type: null,
340
+ default: void 0
341
+ },
342
+ withoutForm: {
343
+ type: Boolean,
344
+ default: false
345
+ }
346
+ },
347
+ setup(props, { expose }) {
348
+ expose(props.form);
349
+ provide(SchemaEngineContextKey, props.form);
350
+ return () => {
351
+ const content = h(SchemaRenderer, { schema: props.form.schema });
352
+ if (props.withoutForm) return h("div", { class: props.class }, content);
353
+ return h("form", {
354
+ class: props.class,
355
+ onSubmit: (event) => {
356
+ event.preventDefault();
357
+ event.stopPropagation();
358
+ props.form.handleSubmit();
359
+ }
360
+ }, [content, h("button", {
361
+ type: "submit",
362
+ tabindex: -1,
363
+ "aria-hidden": "true",
364
+ class: "sr-only"
365
+ })]);
366
+ };
367
+ }
368
+ });
369
+ //#endregion
370
+ export { SchemaFormEngine, useSchemaFormEngine };
371
+
372
+ //# sourceMappingURL=SchemaFormEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaFormEngine.js","names":[],"sources":["../../src/forms/SchemaFormEngine.ts"],"sourcesContent":["import {\n defineComponent,\n h,\n inject,\n onBeforeUnmount,\n onMounted,\n provide,\n ref,\n shallowRef,\n type PropType,\n type VNodeChild,\n} from 'vue';\nimport {\n FormStateStore,\n buildGroupedMessage,\n createValidationEngine,\n evaluateCondition,\n normalizeSchema,\n} from '@verbb/plugin-kit-forms';\nimport type { SchemaIndex, SchemaNode, SchemaRenderable } from '@verbb/plugin-kit-forms';\n\nimport { Separator } from '../components/Separator.js';\nimport { getFormComponentRegistry } from './registry.js';\nimport { SchemaFormFieldNode } from './SchemaFormFieldNode.js';\nimport type {\n FormValues,\n NestedFormApi,\n SchemaFieldApi,\n SchemaFormEngineApi,\n} from './engine/context.js';\nimport { SchemaEngineContextKey } from './engine/context.js';\nimport { isRecord, normalizeAttrs, readEventValue } from './utils.js';\n\ntype SchemaFormEngineErrors = Record<string, unknown> | { errors?: unknown } | unknown[];\n\ntype SchemaFormEngineOptions = {\n schemaIndex: SchemaIndex | null;\n defaultValues?: FormValues;\n errors?: SchemaFormEngineErrors;\n onChange?: (values: Record<string, unknown>, form: SchemaFormEngineApi) => void;\n getConditionContext?: (values: FormValues, field?: SchemaNode) => Record<string, unknown>;\n parentForm?: SchemaFormEngineApi | null;\n parentPath?: string;\n};\n\nconst normalizeServerErrors = (rawErrors: SchemaFormEngineErrors | undefined): Record<string, string[]> => {\n const normalized: Record<string, string[]> = {};\n\n if (!rawErrors) {\n return normalized;\n }\n\n const appendMessages = (path: string, messages: unknown[]) => {\n if (!path) {\n return;\n }\n\n const nextMessages = messages\n .filter((message) => message !== undefined && message !== null && message !== '')\n .map((message) => String(message));\n\n if (!nextMessages.length) {\n return;\n }\n\n if (!normalized[path]) {\n normalized[path] = [];\n }\n\n normalized[path].push(...nextMessages);\n };\n\n const collectErrors = (node: unknown, path: string) => {\n if (Array.isArray(node)) {\n if (node.length === 0) {\n return;\n }\n\n const isMessageArray = node.every((entry) => typeof entry === 'string');\n if (isMessageArray) {\n appendMessages(path, node);\n return;\n }\n\n if (!path) {\n node.forEach((entry) => collectErrors(entry, path));\n return;\n }\n\n node.forEach((entry, index) => {\n collectErrors(entry, `${path}.${index}`);\n });\n return;\n }\n\n if (!isRecord(node)) {\n return;\n }\n\n Object.entries(node).forEach(([key, value]) => {\n const nextPath = path ? `${path}.${key}` : key;\n collectErrors(value, nextPath);\n });\n };\n\n if (Array.isArray(rawErrors)) {\n collectErrors(rawErrors, '');\n return normalized;\n }\n\n if (isRecord(rawErrors) && 'errors' in rawErrors) {\n collectErrors(rawErrors.errors, '');\n return normalized;\n }\n\n collectErrors(rawErrors, '');\n return normalized;\n};\n\nconst createEngineFieldComponent = (formRef: { value: SchemaFormEngineApi | null }) => defineComponent({\n name: 'SchemaEngineField',\n props: {\n name: { type: String, required: true },\n },\n setup(props, { slots }) {\n const version = ref(0);\n let unsubscribe: (() => void) | undefined;\n\n onMounted(() => {\n unsubscribe = formRef.value?.store.subscribe(() => {\n version.value += 1;\n });\n });\n onBeforeUnmount(() => {\n unsubscribe?.();\n });\n\n return () => {\n const form = formRef.value;\n if (!form) {\n return null;\n }\n\n version.value;\n const fieldApi: SchemaFieldApi = {\n state: { value: form.getFieldValue(props.name) },\n handleChange: (valueOrEvent: unknown) => {\n form.setFieldValue(props.name, readEventValue(valueOrEvent));\n },\n handleBlur: () => {\n form.store.setTouched(props.name, true);\n },\n errors: form.getErrorMapFields()[props.name] || [],\n };\n\n return slots.default?.(fieldApi);\n };\n },\n});\n\nconst buildConditionData = (\n form: SchemaFormEngineApi,\n field: SchemaNode,\n values: FormValues,\n): Record<string, unknown> => {\n const scopePath = typeof field._scopePath === 'string' ? field._scopePath : '';\n const scopedValues = scopePath ? form.getFieldValue(scopePath) : null;\n const scopedObject = isRecord(scopedValues) ? scopedValues : {};\n const conditionContext = form.getConditionContext?.(values, field);\n const normalizedConditionContext = isRecord(conditionContext) ? conditionContext : {};\n const fieldData = isRecord(field._data) ? field._data : {};\n\n return {\n ...values,\n ...scopedObject,\n ...fieldData,\n ...normalizedConditionContext,\n };\n};\n\nconst renderSchemaItem = (schemaItem: SchemaNode, index: number, form: SchemaFormEngineApi): VNodeChild => {\n const key = typeof schemaItem._id === 'string' ? schemaItem._id : `schema-item-${index}`;\n\n return h(SchemaItem, { key, field: schemaItem, form }, {\n default: () => h(SchemaRenderer, { schema: schemaItem }),\n });\n};\n\nconst renderFormField = (schema: SchemaNode, form: SchemaFormEngineApi): VNodeChild => {\n const fieldProps = schema.$field ? { $field: schema.$field, ...schema } : { $field: schema.type, ...schema };\n const { $field, ...props } = fieldProps;\n const fieldType = String($field ?? '');\n\n return h(SchemaFormFieldNode, {\n fieldType,\n schema,\n field: { ...props },\n form,\n }, {\n default: () => (props.children ? h(SchemaRenderer, { schema: props.children as SchemaRenderable }) : null),\n });\n};\n\nconst renderHtmlElement = (schema: SchemaNode): VNodeChild => {\n const { $el, children, attrs = {} } = schema;\n const normalizedAttrs = normalizeAttrs(isRecord(attrs) ? attrs : {});\n\n if (typeof $el !== 'string' || !$el) {\n return null;\n }\n\n if ($el === 'hr') {\n return h(Separator, normalizedAttrs);\n }\n\n return h($el, normalizedAttrs, children ? () => h(SchemaRenderer, { schema: children }) : undefined);\n};\n\nconst renderFormComponent = (schema: SchemaNode): VNodeChild => {\n const {\n $cmp, props = {}, children, ...rest\n } = schema;\n const Component = getFormComponentRegistry()[$cmp as string];\n\n if (!Component) {\n console.warn(`Unknown form component: ${$cmp}`);\n return null;\n }\n\n const componentProps = { ...(isRecord(props) ? props : {}), ...rest } as Record<string, unknown>;\n const usesSchemaNode = Boolean(Component.usesSchemaNode);\n\n if (usesSchemaNode) {\n componentProps.schemaNode = schema;\n } else if ('schemaNode' in componentProps) {\n delete componentProps.schemaNode;\n }\n\n return h(Component, componentProps, {\n default: () => (children ? h(SchemaRenderer, { schema: children as SchemaRenderable }) : null),\n });\n};\n\nconst SchemaItem = defineComponent({\n name: 'SchemaItem',\n props: {\n field: { type: Object as PropType<SchemaNode>, required: true },\n form: { type: Object as PropType<SchemaFormEngineApi>, required: true },\n },\n setup(props, { slots }) {\n const shouldShow = ref(true);\n\n const resolveVisibility = (values: FormValues): boolean => {\n if (!props.field.if) {\n return true;\n }\n\n return Boolean(evaluateCondition(props.field.if, buildConditionData(props.form, props.field, values)));\n };\n\n const update = () => {\n shouldShow.value = resolveVisibility(props.form.store.state.values);\n };\n\n update();\n const unsubscribe = props.form.store.subscribe(update);\n onBeforeUnmount(unsubscribe);\n\n return () => {\n if (!shouldShow.value) {\n return props.field.hideOnIf ? h('div', { style: { display: 'none' } }, slots.default?.()) : null;\n }\n\n return slots.default?.();\n };\n },\n});\n\nconst SchemaRenderer = defineComponent({\n name: 'SchemaRenderer',\n props: {\n schema: { type: null as unknown as PropType<SchemaRenderable>, required: true },\n },\n setup(props) {\n const form = provideAwareForm();\n\n return () => {\n const schema = props.schema;\n\n if (typeof schema === 'string') {\n return schema;\n }\n\n if (Array.isArray(schema)) {\n return schema.map((schemaItem, index) => {\n if (typeof schemaItem === 'string') {\n return schemaItem;\n }\n\n if (!isRecord(schemaItem)) {\n return null;\n }\n\n return renderSchemaItem(schemaItem as SchemaNode, index, form);\n });\n }\n\n if (schema.$field || schema.$cmp === 'Field') {\n return renderFormField(schema, form);\n }\n\n if (schema.$el) {\n return renderHtmlElement(schema);\n }\n\n if (schema.$cmp) {\n return renderFormComponent(schema);\n }\n\n console.warn('Unknown schema item:', schema);\n return null;\n };\n },\n});\n\nconst provideAwareForm = (): SchemaFormEngineApi => {\n const form = inject(SchemaEngineContextKey, null);\n if (!form) {\n throw new Error('SchemaRenderer must be used within SchemaFormEngine.');\n }\n return form;\n};\n\nexport const useSchemaFormEngine = ({\n schemaIndex = null,\n defaultValues = {},\n errors,\n onChange,\n getConditionContext,\n parentForm,\n parentPath,\n}: SchemaFormEngineOptions): SchemaFormEngineApi => {\n if (!schemaIndex) {\n throw new Error('SchemaFormEngine requires a compiled schemaIndex.');\n }\n\n const index = {\n ...schemaIndex,\n schema: normalizeSchema(schemaIndex.schema),\n };\n const store = new FormStateStore(defaultValues);\n const validationEngine = createValidationEngine(index, { conditionDataResolver: getConditionContext });\n const labelMap = new Map<string, string>();\n const nestedForms = new Map<string, NestedFormApi>();\n const formRef = shallowRef<SchemaFormEngineApi | null>(null);\n const Field = createEngineFieldComponent(formRef);\n\n index.fieldEntries.forEach((entry) => {\n if (entry.path) {\n const label = String(entry.field?.label || entry.field?.name || entry.path);\n labelMap.set(entry.path, label);\n }\n });\n\n let onSubmitHandler: ((value: FormValues) => Promise<void> | void) | null = null;\n let onErrorHandler: ((errors: Record<string, unknown>) => void) | null = null;\n let onSuccessHandler: ((value: FormValues) => void) | null = null;\n let onChangeHandler: ((value: FormValues) => void) | null = onChange\n ? (value) => {\n if (formRef.value) {\n onChange(value, formRef.value);\n }\n }\n : null;\n\n const validateNestedForms = (): Record<string, string[]> => {\n const nestedErrors: Record<string, string[]> = {};\n\n nestedForms.forEach((api, path) => {\n const result = api.validate();\n if (result?.fields) {\n Object.entries(result.fields).forEach(([fieldPath, messages]) => {\n const mergedPath = fieldPath ? `${path}.${fieldPath}` : path;\n nestedErrors[mergedPath] = messages;\n });\n }\n });\n\n return nestedErrors;\n };\n\n const getGroupedErrorsForPath = (path: string): string[] => {\n if (!path) {\n return [];\n }\n\n const currentErrors = store.state.errors || {};\n const rootErrors = currentErrors[path] || [];\n const childKeys = Object.keys(currentErrors).filter((key) => key.startsWith(`${path}.`));\n\n if (!childKeys.length) {\n return rootErrors;\n }\n\n const parentLabel = labelMap.get(path);\n const groupedMessages: string[] = [];\n\n childKeys.forEach((key) => {\n const wildcardPath = key.replace(/\\.\\d+(?=\\.|$)/g, '.*');\n const childLabel = labelMap.get(wildcardPath) || key.split('.').slice(-1)[0];\n (currentErrors[key] || []).forEach((message) => {\n if (parentLabel) {\n groupedMessages.push(buildGroupedMessage(String(message), parentLabel, childLabel));\n return;\n }\n\n groupedMessages.push(String(message));\n });\n });\n\n return Array.from(new Set([...rootErrors, ...groupedMessages]));\n };\n\n const handleSubmit = async (): Promise<void> => {\n const result = validationEngine.validate(store.state.values);\n const errorsMap = result?.fields || {};\n const nestedErrors = validateNestedForms();\n const mergedErrors = { ...errorsMap, ...nestedErrors };\n\n if (Object.keys(mergedErrors).length > 0) {\n store.setErrors(mergedErrors);\n onErrorHandler?.(mergedErrors);\n return;\n }\n\n store.clearErrors();\n await onSubmitHandler?.(store.state.values);\n\n if (parentForm && parentPath) {\n parentForm.setFieldValue(parentPath, store.state.values);\n }\n\n onSuccessHandler?.(store.state.values);\n };\n\n const form: SchemaFormEngineApi = {\n schema: index.schema,\n store,\n index,\n Field,\n getFieldValue: (path: string) => store.getValue(path),\n setFieldValue: (path: string, value: unknown) => store.setValue(path, value),\n getErrorMapFields: () => store.state.errors || {},\n SchemaRenderer,\n handleSubmit,\n onChange: (handler) => {\n onChangeHandler = handler;\n },\n onSubmit: (handler) => {\n onSubmitHandler = handler;\n },\n onError: (handler) => {\n onErrorHandler = handler;\n },\n onSuccess: (handler) => {\n onSuccessHandler = handler;\n },\n registerNestedForm: (path, api) => {\n nestedForms.set(path, api);\n },\n unregisterNestedForm: (path) => {\n nestedForms.delete(path);\n },\n getGroupedErrorsForPath,\n getConditionContext: (values, field) => getConditionContext?.(values, field) || {},\n };\n\n formRef.value = form;\n\n const unsubscribeChange = store.subscribe(() => {\n onChangeHandler?.(store.state.values);\n });\n onBeforeUnmount(unsubscribeChange);\n\n const normalized = normalizeServerErrors(errors);\n if (Object.keys(normalized).length) {\n store.setErrors(normalized);\n }\n\n if (parentForm && parentPath) {\n const nestedApi: NestedFormApi = {\n path: parentPath,\n validate: () => {\n const result = validationEngine.validate(store.state.values);\n const fieldErrors = result?.fields || {};\n\n if (Object.keys(fieldErrors).length) {\n store.setErrors(fieldErrors);\n } else {\n store.clearErrors();\n }\n\n return result;\n },\n getValues: () => store.state.values,\n };\n\n parentForm.registerNestedForm(parentPath, nestedApi);\n onBeforeUnmount(() => {\n parentForm.unregisterNestedForm(parentPath);\n });\n }\n\n return form;\n};\n\nexport const SchemaFormEngine = defineComponent({\n name: 'SchemaFormEngine',\n props: {\n form: { type: Object as PropType<SchemaFormEngineApi>, required: true },\n class: { type: null as unknown as PropType<unknown>, default: undefined },\n withoutForm: { type: Boolean, default: false },\n },\n setup(props, { expose }) {\n expose(props.form);\n provide(SchemaEngineContextKey, props.form);\n\n return () => {\n const content = h(SchemaRenderer, { schema: props.form.schema });\n\n if (props.withoutForm) {\n return h('div', { class: props.class }, content);\n }\n\n return h(\n 'form',\n {\n class: props.class,\n onSubmit: (event: Event) => {\n event.preventDefault();\n event.stopPropagation();\n void props.form.handleSubmit();\n },\n },\n [\n content,\n h('button', {\n type: 'submit',\n tabindex: -1,\n 'aria-hidden': 'true',\n class: 'sr-only',\n }),\n ],\n );\n };\n },\n});\n"],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { PropType } from 'vue';
2
+ import { SchemaNode } from '@verbb/plugin-kit-forms';
3
+ import { SchemaFormEngineApi } from './engine/context.js';
4
+ export declare const SchemaFormFieldNode: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
5
+ fieldType: {
6
+ type: StringConstructor;
7
+ required: true;
8
+ };
9
+ schema: {
10
+ type: PropType<SchemaNode>;
11
+ required: true;
12
+ };
13
+ field: {
14
+ type: PropType<SchemaNode>;
15
+ required: true;
16
+ };
17
+ form: {
18
+ type: PropType<SchemaFormEngineApi>;
19
+ required: true;
20
+ };
21
+ }>, () => import('vue').VNode<import('vue').RendererNode, import('vue').RendererElement, {
22
+ [key: string]: any;
23
+ }> | null, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
24
+ fieldType: {
25
+ type: StringConstructor;
26
+ required: true;
27
+ };
28
+ schema: {
29
+ type: PropType<SchemaNode>;
30
+ required: true;
31
+ };
32
+ field: {
33
+ type: PropType<SchemaNode>;
34
+ required: true;
35
+ };
36
+ form: {
37
+ type: PropType<SchemaFormEngineApi>;
38
+ required: true;
39
+ };
40
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
41
+ //# sourceMappingURL=SchemaFormFieldNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaFormFieldNode.d.ts","sourceRoot":"","sources":["../../src/forms/SchemaFormFieldNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAMH,KAAK,QAAQ,EAChB,MAAM,KAAK,CAAC;AACb,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,KAAK,EAAE,mBAAmB,EAA4B,MAAM,qBAAqB,CAAC;AAMzF,eAAO,MAAM,mBAAmB;;;;;;cAIE,QAAQ,CAAC,UAAU,CAAC;;;;cACrB,QAAQ,CAAC,UAAU,CAAC;;;;cACrB,QAAQ,CAAC,mBAAmB,CAAC;;;;;;;;;;;cAF3B,QAAQ,CAAC,UAAU,CAAC;;;;cACrB,QAAQ,CAAC,UAAU,CAAC;;;;cACrB,QAAQ,CAAC,mBAAmB,CAAC;;;iGAiE3D,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { cacheLoadedBuiltinFormField, getRegisteredFormField } from "./registry.js";
2
+ import { isBuiltinFormFieldType, loadBuiltinFormField } from "./builtin-field-loaders.js";
3
+ import { defineComponent, h, onMounted, ref, watch } from "vue";
4
+ //#region src/forms/SchemaFormFieldNode.ts
5
+ var SchemaFormFieldNode = defineComponent({
6
+ name: "SchemaFormFieldNode",
7
+ props: {
8
+ fieldType: {
9
+ type: String,
10
+ required: true
11
+ },
12
+ schema: {
13
+ type: Object,
14
+ required: true
15
+ },
16
+ field: {
17
+ type: Object,
18
+ required: true
19
+ },
20
+ form: {
21
+ type: Object,
22
+ required: true
23
+ }
24
+ },
25
+ setup(props, { slots }) {
26
+ const component = ref(getRegisteredFormField(props.fieldType) ?? null);
27
+ const loadFailed = ref(false);
28
+ const loadComponent = async (fieldType) => {
29
+ const registeredField = getRegisteredFormField(fieldType);
30
+ if (registeredField) {
31
+ component.value = registeredField;
32
+ loadFailed.value = false;
33
+ return;
34
+ }
35
+ if (!isBuiltinFormFieldType(fieldType)) {
36
+ console.warn(`Unknown form field type: ${fieldType}`);
37
+ component.value = null;
38
+ loadFailed.value = true;
39
+ return;
40
+ }
41
+ loadFailed.value = false;
42
+ try {
43
+ const loaded = await loadBuiltinFormField(fieldType);
44
+ if (!loaded || fieldType !== props.fieldType) return;
45
+ cacheLoadedBuiltinFormField(fieldType, loaded);
46
+ component.value = loaded;
47
+ } catch (error) {
48
+ if (fieldType !== props.fieldType) return;
49
+ console.error(`Failed to load form field "${fieldType}":`, error);
50
+ component.value = null;
51
+ loadFailed.value = true;
52
+ }
53
+ };
54
+ onMounted(() => {
55
+ loadComponent(props.fieldType);
56
+ });
57
+ watch(() => props.fieldType, (fieldType) => {
58
+ loadComponent(fieldType);
59
+ });
60
+ return () => {
61
+ if (loadFailed.value || !component.value) return null;
62
+ return h(component.value, {
63
+ schema: props.schema,
64
+ field: props.field,
65
+ form: props.form
66
+ }, slots);
67
+ };
68
+ }
69
+ });
70
+ //#endregion
71
+ export { SchemaFormFieldNode };
72
+
73
+ //# sourceMappingURL=SchemaFormFieldNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaFormFieldNode.js","names":[],"sources":["../../src/forms/SchemaFormFieldNode.ts"],"sourcesContent":["import {\n defineComponent,\n h,\n onMounted,\n ref,\n watch,\n type PropType,\n} from 'vue';\nimport type { SchemaNode } from '@verbb/plugin-kit-forms';\n\nimport { isBuiltinFormFieldType, loadBuiltinFormField } from './builtin-field-loaders.js';\nimport type { SchemaFormEngineApi, SchemaFormFieldComponent } from './engine/context.js';\nimport {\n cacheLoadedBuiltinFormField,\n getRegisteredFormField,\n} from './registry.js';\n\nexport const SchemaFormFieldNode = defineComponent({\n name: 'SchemaFormFieldNode',\n props: {\n fieldType: { type: String, required: true },\n schema: { type: Object as PropType<SchemaNode>, required: true },\n field: { type: Object as PropType<SchemaNode>, required: true },\n form: { type: Object as PropType<SchemaFormEngineApi>, required: true },\n },\n setup(props, { slots }) {\n const component = ref<SchemaFormFieldComponent | null>(getRegisteredFormField(props.fieldType) ?? null);\n const loadFailed = ref(false);\n\n const loadComponent = async (fieldType: string): Promise<void> => {\n const registeredField = getRegisteredFormField(fieldType);\n if (registeredField) {\n component.value = registeredField;\n loadFailed.value = false;\n return;\n }\n\n if (!isBuiltinFormFieldType(fieldType)) {\n console.warn(`Unknown form field type: ${fieldType}`);\n component.value = null;\n loadFailed.value = true;\n return;\n }\n\n loadFailed.value = false;\n\n try {\n const loaded = await loadBuiltinFormField(fieldType);\n if (!loaded || fieldType !== props.fieldType) {\n return;\n }\n\n cacheLoadedBuiltinFormField(fieldType, loaded);\n component.value = loaded;\n } catch (error) {\n if (fieldType !== props.fieldType) {\n return;\n }\n\n console.error(`Failed to load form field \"${fieldType}\":`, error);\n component.value = null;\n loadFailed.value = true;\n }\n };\n\n onMounted(() => {\n void loadComponent(props.fieldType);\n });\n watch(() => props.fieldType, (fieldType) => {\n void loadComponent(fieldType);\n });\n\n return () => {\n if (loadFailed.value || !component.value) {\n return null;\n }\n\n return h(\n component.value,\n {\n schema: props.schema,\n field: props.field,\n form: props.form,\n },\n slots,\n );\n };\n },\n});\n"],"mappings":";;;;AAiBA,IAAa,sBAAsB,gBAAgB;CAC/C,MAAM;CACN,OAAO;EACH,WAAW;GAAE,MAAM;GAAQ,UAAU;GAAM;EAC3C,QAAQ;GAAE,MAAM;GAAgC,UAAU;GAAM;EAChE,OAAO;GAAE,MAAM;GAAgC,UAAU;GAAM;EAC/D,MAAM;GAAE,MAAM;GAAyC,UAAU;GAAM;EAC1E;CACD,MAAM,OAAO,EAAE,SAAS;EACpB,MAAM,YAAY,IAAqC,uBAAuB,MAAM,UAAU,IAAI,KAAK;EACvG,MAAM,aAAa,IAAI,MAAM;EAE7B,MAAM,gBAAgB,OAAO,cAAqC;GAC9D,MAAM,kBAAkB,uBAAuB,UAAU;AACzD,OAAI,iBAAiB;AACjB,cAAU,QAAQ;AAClB,eAAW,QAAQ;AACnB;;AAGJ,OAAI,CAAC,uBAAuB,UAAU,EAAE;AACpC,YAAQ,KAAK,4BAA4B,YAAY;AACrD,cAAU,QAAQ;AAClB,eAAW,QAAQ;AACnB;;AAGJ,cAAW,QAAQ;AAEnB,OAAI;IACA,MAAM,SAAS,MAAM,qBAAqB,UAAU;AACpD,QAAI,CAAC,UAAU,cAAc,MAAM,UAC/B;AAGJ,gCAA4B,WAAW,OAAO;AAC9C,cAAU,QAAQ;YACb,OAAO;AACZ,QAAI,cAAc,MAAM,UACpB;AAGJ,YAAQ,MAAM,8BAA8B,UAAU,KAAK,MAAM;AACjE,cAAU,QAAQ;AAClB,eAAW,QAAQ;;;AAI3B,kBAAgB;AACP,iBAAc,MAAM,UAAU;IACrC;AACF,cAAY,MAAM,YAAY,cAAc;AACnC,iBAAc,UAAU;IAC/B;AAEF,eAAa;AACT,OAAI,WAAW,SAAS,CAAC,UAAU,MAC/B,QAAO;AAGX,UAAO,EACH,UAAU,OACV;IACI,QAAQ,MAAM;IACd,OAAO,MAAM;IACb,MAAM,MAAM;IACf,EACD,MACH;;;CAGZ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { SchemaIndex, SchemaRenderable } from '@verbb/plugin-kit-forms';
2
+ export type AssertSchemaRegistryOptions = {
3
+ /** When true, throw on the first missing registry key instead of collecting all. */
4
+ failFast?: boolean;
5
+ };
6
+ export type SchemaRegistryIssue = {
7
+ path: string;
8
+ kind: 'field' | 'component';
9
+ key: string;
10
+ };
11
+ /**
12
+ * Walk a SchemaForm tree and verify every `$field` / `$cmp` key can resolve.
13
+ * Useful in dev/test bootstraps before shipping large CP schemas.
14
+ */
15
+ export declare const assertSchemaRegistry: (schema: SchemaRenderable, options?: AssertSchemaRegistryOptions) => SchemaRegistryIssue[];
16
+ export declare const debugSchemaRegistry: (schemaIndex: SchemaIndex | null | undefined, options?: AssertSchemaRegistryOptions) => SchemaRegistryIssue[];
17
+ //# sourceMappingURL=assertSchemaRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertSchemaRegistry.d.ts","sourceRoot":"","sources":["../../src/forms/assertSchemaRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAc,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAMzF,MAAM,MAAM,2BAA2B,GAAG;IACtC,oFAAoF;IACpF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,WAAW,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAwCF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAC7B,QAAQ,gBAAgB,EACxB,UAAS,2BAAgC,KAC1C,mBAAmB,EA+BrB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC5B,aAAa,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,UAAU,2BAA2B,KACtC,mBAAmB,EAYrB,CAAC"}
@@ -0,0 +1,68 @@
1
+ import { getFormComponentRegistry, getFormFieldRegistry } from "./registry.js";
2
+ import { isBuiltinFormFieldType } from "./builtin-field-loaders.js";
3
+ import { isRecord } from "./utils.js";
4
+ //#region src/forms/assertSchemaRegistry.ts
5
+ var walkSchema = (schema, path, visit) => {
6
+ if (typeof schema === "string") return;
7
+ if (Array.isArray(schema)) {
8
+ schema.forEach((item, index) => {
9
+ if (typeof item === "string" || !isRecord(item)) return;
10
+ const itemPath = `${path}[${index}]`;
11
+ visit(item, itemPath);
12
+ walkSchema(item, itemPath, visit);
13
+ });
14
+ return;
15
+ }
16
+ if (!isRecord(schema)) return;
17
+ const node = schema;
18
+ visit(node, path);
19
+ if (node.children) walkSchema(node.children, `${path}.children`, visit);
20
+ if (node.schema) walkSchema(node.schema, `${path}.schema`, visit);
21
+ };
22
+ /**
23
+ * Walk a SchemaForm tree and verify every `$field` / `$cmp` key can resolve.
24
+ * Useful in dev/test bootstraps before shipping large CP schemas.
25
+ */
26
+ var assertSchemaRegistry = (schema, options = {}) => {
27
+ const { failFast = false } = options;
28
+ const fieldRegistry = getFormFieldRegistry();
29
+ const componentRegistry = getFormComponentRegistry();
30
+ const issues = [];
31
+ walkSchema(schema, "schema", (node, nodePath) => {
32
+ if (node.$field) {
33
+ const key = String(node.$field);
34
+ if (!fieldRegistry[key] && !isBuiltinFormFieldType(key)) {
35
+ const issue = {
36
+ path: nodePath,
37
+ kind: "field",
38
+ key
39
+ };
40
+ issues.push(issue);
41
+ if (failFast) throw new Error(`SchemaForm: unregistered field "${key}" at ${nodePath}`);
42
+ }
43
+ }
44
+ if (node.$cmp) {
45
+ const key = String(node.$cmp);
46
+ if (!componentRegistry[key]) {
47
+ const issue = {
48
+ path: nodePath,
49
+ kind: "component",
50
+ key
51
+ };
52
+ issues.push(issue);
53
+ if (failFast) throw new Error(`SchemaForm: unregistered component "${key}" at ${nodePath}`);
54
+ }
55
+ }
56
+ });
57
+ return issues;
58
+ };
59
+ var debugSchemaRegistry = (schemaIndex, options) => {
60
+ if (!schemaIndex?.schema) return [];
61
+ const issues = assertSchemaRegistry(schemaIndex.schema, options);
62
+ if (issues.length) console.warn("[plugin-kit] SchemaForm registry gaps:", issues);
63
+ return issues;
64
+ };
65
+ //#endregion
66
+ export { assertSchemaRegistry, debugSchemaRegistry };
67
+
68
+ //# sourceMappingURL=assertSchemaRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertSchemaRegistry.js","names":[],"sources":["../../src/forms/assertSchemaRegistry.ts"],"sourcesContent":["import type { SchemaIndex, SchemaNode, SchemaRenderable } from '@verbb/plugin-kit-forms';\n\nimport { isBuiltinFormFieldType } from './builtin-field-loaders.js';\nimport { getFormComponentRegistry, getFormFieldRegistry } from './registry.js';\nimport { isRecord } from './utils.js';\n\nexport type AssertSchemaRegistryOptions = {\n /** When true, throw on the first missing registry key instead of collecting all. */\n failFast?: boolean;\n};\n\nexport type SchemaRegistryIssue = {\n path: string;\n kind: 'field' | 'component';\n key: string;\n};\n\nconst walkSchema = (\n schema: SchemaRenderable,\n path: string,\n visit: (node: SchemaNode, path: string) => void,\n): void => {\n if (typeof schema === 'string') {\n return;\n }\n\n if (Array.isArray(schema)) {\n schema.forEach((item, index) => {\n if (typeof item === 'string' || !isRecord(item)) {\n return;\n }\n\n const itemPath = `${path}[${index}]`;\n visit(item as SchemaNode, itemPath);\n walkSchema(item as SchemaRenderable, itemPath, visit);\n });\n return;\n }\n\n if (!isRecord(schema)) {\n return;\n }\n\n const node = schema as SchemaNode;\n visit(node, path);\n\n if (node.children) {\n walkSchema(node.children as SchemaRenderable, `${path}.children`, visit);\n }\n\n if (node.schema) {\n walkSchema(node.schema as SchemaRenderable, `${path}.schema`, visit);\n }\n};\n\n/**\n * Walk a SchemaForm tree and verify every `$field` / `$cmp` key can resolve.\n * Useful in dev/test bootstraps before shipping large CP schemas.\n */\nexport const assertSchemaRegistry = (\n schema: SchemaRenderable,\n options: AssertSchemaRegistryOptions = {},\n): SchemaRegistryIssue[] => {\n const { failFast = false } = options;\n const fieldRegistry = getFormFieldRegistry();\n const componentRegistry = getFormComponentRegistry();\n const issues: SchemaRegistryIssue[] = [];\n\n walkSchema(schema, 'schema', (node, nodePath) => {\n if (node.$field) {\n const key = String(node.$field);\n if (!fieldRegistry[key] && !isBuiltinFormFieldType(key)) {\n const issue: SchemaRegistryIssue = { path: nodePath, kind: 'field', key };\n issues.push(issue);\n if (failFast) {\n throw new Error(`SchemaForm: unregistered field \"${key}\" at ${nodePath}`);\n }\n }\n }\n\n if (node.$cmp) {\n const key = String(node.$cmp);\n if (!componentRegistry[key]) {\n const issue: SchemaRegistryIssue = { path: nodePath, kind: 'component', key };\n issues.push(issue);\n if (failFast) {\n throw new Error(`SchemaForm: unregistered component \"${key}\" at ${nodePath}`);\n }\n }\n }\n });\n\n return issues;\n};\n\nexport const debugSchemaRegistry = (\n schemaIndex: SchemaIndex | null | undefined,\n options?: AssertSchemaRegistryOptions,\n): SchemaRegistryIssue[] => {\n if (!schemaIndex?.schema) {\n return [];\n }\n\n const issues = assertSchemaRegistry(schemaIndex.schema, options);\n\n if (issues.length) {\n console.warn('[plugin-kit] SchemaForm registry gaps:', issues);\n }\n\n return issues;\n};\n"],"mappings":";;;;AAiBA,IAAM,cACF,QACA,MACA,UACO;AACP,KAAI,OAAO,WAAW,SAClB;AAGJ,KAAI,MAAM,QAAQ,OAAO,EAAE;AACvB,SAAO,SAAS,MAAM,UAAU;AAC5B,OAAI,OAAO,SAAS,YAAY,CAAC,SAAS,KAAK,CAC3C;GAGJ,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM;AAClC,SAAM,MAAoB,SAAS;AACnC,cAAW,MAA0B,UAAU,MAAM;IACvD;AACF;;AAGJ,KAAI,CAAC,SAAS,OAAO,CACjB;CAGJ,MAAM,OAAO;AACb,OAAM,MAAM,KAAK;AAEjB,KAAI,KAAK,SACL,YAAW,KAAK,UAA8B,GAAG,KAAK,YAAY,MAAM;AAG5E,KAAI,KAAK,OACL,YAAW,KAAK,QAA4B,GAAG,KAAK,UAAU,MAAM;;;;;;AAQ5E,IAAa,wBACT,QACA,UAAuC,EAAE,KACjB;CACxB,MAAM,EAAE,WAAW,UAAU;CAC7B,MAAM,gBAAgB,sBAAsB;CAC5C,MAAM,oBAAoB,0BAA0B;CACpD,MAAM,SAAgC,EAAE;AAExC,YAAW,QAAQ,WAAW,MAAM,aAAa;AAC7C,MAAI,KAAK,QAAQ;GACb,MAAM,MAAM,OAAO,KAAK,OAAO;AAC/B,OAAI,CAAC,cAAc,QAAQ,CAAC,uBAAuB,IAAI,EAAE;IACrD,MAAM,QAA6B;KAAE,MAAM;KAAU,MAAM;KAAS;KAAK;AACzE,WAAO,KAAK,MAAM;AAClB,QAAI,SACA,OAAM,IAAI,MAAM,mCAAmC,IAAI,OAAO,WAAW;;;AAKrF,MAAI,KAAK,MAAM;GACX,MAAM,MAAM,OAAO,KAAK,KAAK;AAC7B,OAAI,CAAC,kBAAkB,MAAM;IACzB,MAAM,QAA6B;KAAE,MAAM;KAAU,MAAM;KAAa;KAAK;AAC7E,WAAO,KAAK,MAAM;AAClB,QAAI,SACA,OAAM,IAAI,MAAM,uCAAuC,IAAI,OAAO,WAAW;;;GAI3F;AAEF,QAAO;;AAGX,IAAa,uBACT,aACA,YACwB;AACxB,KAAI,CAAC,aAAa,OACd,QAAO,EAAE;CAGb,MAAM,SAAS,qBAAqB,YAAY,QAAQ,QAAQ;AAEhE,KAAI,OAAO,OACP,SAAQ,KAAK,0CAA0C,OAAO;AAGlE,QAAO"}