@bach.software/vue-dynamic-form 0.1.3 → 0.3.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 (71) hide show
  1. package/README.md +203 -7
  2. package/dist/examples.cjs.js +12 -0
  3. package/dist/examples.cjs.js.map +1 -0
  4. package/dist/examples.es.js +612 -0
  5. package/dist/examples.es.js.map +1 -0
  6. package/dist/src/components/DynamicForm.vue.d.ts +2 -0
  7. package/dist/src/components/DynamicFormItem.vue.d.ts +11 -2
  8. package/dist/src/components/DynamicFormItemArray.vue.d.ts +9 -2
  9. package/dist/src/components/DynamicFormItemChoice.vue.d.ts +9 -2
  10. package/dist/src/components/DynamicFormTemplate.vue.d.ts +72 -21
  11. package/dist/src/components/__tests__/DynamicFormItem.analytics.test.d.ts +1 -0
  12. package/dist/src/components/__tests__/DynamicFormItem.logic.test.d.ts +1 -0
  13. package/dist/src/components/__tests__/DynamicFormItem.test-helpers.d.ts +21 -0
  14. package/dist/src/components/__tests__/DynamicFormItem.validation.test.d.ts +1 -0
  15. package/dist/src/components/__tests__/DynamicFormItemArray.logic.test.d.ts +1 -0
  16. package/dist/src/components/__tests__/DynamicFormItemArray.validation.test.d.ts +1 -0
  17. package/dist/src/components/__tests__/DynamicFormItemChoice.logic.test.d.ts +1 -0
  18. package/dist/src/components/__tests__/DynamicFormItemChoice.validation.test.d.ts +1 -0
  19. package/dist/src/core/__tests__/useValidatePartialForm.test.d.ts +1 -0
  20. package/dist/src/core/__tests__/validation.test.d.ts +1 -0
  21. package/dist/src/core/defineMetadata.d.ts +32 -7
  22. package/dist/src/core/useDynamicForm.d.ts +16 -0
  23. package/dist/src/core/useFieldArrayExtended.d.ts +16 -0
  24. package/dist/src/core/useValidatePartialForm.d.ts +4 -0
  25. package/dist/src/core/validation.d.ts +7 -0
  26. package/dist/src/examples/TestForm.vue.d.ts +13 -0
  27. package/dist/src/examples/TestFormTemplate.vue.d.ts +76 -0
  28. package/dist/src/examples/__tests__/DynamicForm.test.d.ts +1 -0
  29. package/dist/src/examples/__tests__/TestFormTemplate.testcases.d.ts +14 -0
  30. package/dist/src/examples/components/IconButton.vue.d.ts +10 -0
  31. package/dist/src/examples/index.d.ts +3 -0
  32. package/dist/src/index.d.ts +6 -0
  33. package/dist/src/tests/test-setup.d.ts +1 -0
  34. package/dist/src/types/DynamicFormItemProps.d.ts +56 -1
  35. package/dist/src/types/DynamicFormSettings.d.ts +89 -0
  36. package/dist/src/types/FieldMetadata.d.ts +109 -17
  37. package/dist/src/types/InternalFieldMetadata.d.ts +9 -3
  38. package/dist/src/types/KeyValue.d.ts +3 -0
  39. package/dist/src/types/MetadataConfiguration.d.ts +2 -0
  40. package/dist/src/types/ValidationMessage.d.ts +3 -0
  41. package/dist/src/utils/__tests__/checkTreeHasValue.test.d.ts +1 -0
  42. package/dist/src/utils/__tests__/createValidation.test.d.ts +1 -0
  43. package/dist/src/utils/__tests__/mapEachMetadataItem.test.d.ts +16 -0
  44. package/dist/src/utils/__tests__/normalizePath.test.d.ts +1 -0
  45. package/dist/src/utils/__tests__/overridePath.test.d.ts +1 -0
  46. package/dist/src/utils/__tests__/resolveMessage.test.d.ts +1 -0
  47. package/dist/src/utils/__tests__/setInPath.test.d.ts +1 -0
  48. package/dist/src/utils/__tests__/splitValidationFunctions.test.d.ts +1 -0
  49. package/dist/src/utils/camelize.d.ts +5 -0
  50. package/dist/src/utils/checkTreeHasValue.d.ts +9 -0
  51. package/dist/src/utils/createValidation.d.ts +12 -0
  52. package/dist/src/utils/getFieldLabel.d.ts +16 -0
  53. package/dist/src/utils/hashField.d.ts +7 -0
  54. package/dist/src/utils/mapEachMetadataItem.d.ts +10 -0
  55. package/dist/src/utils/normalizePath.d.ts +15 -0
  56. package/dist/src/utils/overridePath.d.ts +19 -0
  57. package/dist/src/utils/resolveMessage.d.ts +17 -0
  58. package/dist/src/utils/setInPath.d.ts +10 -0
  59. package/dist/src/utils/splitValidationFunctions.d.ts +15 -0
  60. package/dist/tsconfig.tsbuildinfo +1 -0
  61. package/dist/useDynamicForm-C6-0mGw4.js +737 -0
  62. package/dist/useDynamicForm-C6-0mGw4.js.map +1 -0
  63. package/dist/useDynamicForm-SHyV1lLH.cjs +6 -0
  64. package/dist/useDynamicForm-SHyV1lLH.cjs.map +1 -0
  65. package/dist/vue-dynamic-form.cjs.js +2 -0
  66. package/dist/vue-dynamic-form.cjs.js.map +1 -0
  67. package/dist/vue-dynamic-form.es.js +13 -178
  68. package/dist/vue-dynamic-form.es.js.map +1 -0
  69. package/package.json +17 -9
  70. package/dist/vue-dynamic-form.umd.js +0 -1
  71. /package/dist/src/components/{DynamicForm.test.d.ts → __tests__/DynamicForm.test.d.ts} +0 -0
package/README.md CHANGED
@@ -1,11 +1,207 @@
1
- # Vue Dynamic Form - Under development (Not ready to use)
1
+ # @bach.software/vue-dynamic-form
2
2
 
3
- A simple yet highly extendable dynamic form system, inspired by the flexibility of XSD and powered by Vee-Validate.
3
+ `@bach.software/vue-dynamic-form` is a schema-driven form library for Vue that extends `vee-validate` with a metadata model for fields, groups, arrays, choices, templates, and XSD-inspired validation rules.
4
4
 
5
- ## Create a new release
5
+ For the manual site and runnable demos, start with [../../docs/index.md](../../docs/index.md).
6
6
 
7
- To create a new release for you PR, follow these steps:
7
+ ## What The Library Solves
8
8
 
9
- 1. Create a new changeset by running `pnpm changeset`.
10
- 2. Create your PR into the main branch.
11
- 3. The release workflow will automatically be triggered.
9
+ The library lets you describe a form as metadata instead of hard-coding the full form tree in templates. The metadata is then rendered by `DynamicForm` and your chosen `DynamicFormTemplate`.
10
+
11
+ This is useful when:
12
+
13
+ - form structure comes from configuration or backend metadata
14
+ - repeated sections and optional groups need to be created dynamically
15
+ - mutually exclusive input branches should be enforced consistently
16
+ - the same logical form must be rendered with different UI templates
17
+
18
+ ## Core Building Blocks
19
+
20
+ ### `DynamicForm`
21
+
22
+ `DynamicForm` is the runtime entry point. It:
23
+
24
+ - accepts metadata and a template component
25
+ - normalizes the metadata tree
26
+ - fills in defaults like `minOccurs`, `maxOccurs`, `type`, `name`, and `path`
27
+ - provides settings to all nested form items
28
+
29
+ ### `DynamicFormTemplate`
30
+
31
+ `DynamicFormTemplate` is the rendering contract between the core engine and your UI layer. Instead of coupling the library to a specific design system, the library exposes slots for:
32
+
33
+ - simple inputs
34
+ - grouped fields
35
+ - array fields
36
+ - choice fields
37
+ - attributes
38
+
39
+ That means the form logic stays in the library, while the visual implementation stays in your app or component library.
40
+
41
+ ### Metadata Tree
42
+
43
+ Each metadata item can represent one of a few structural shapes:
44
+
45
+ - input field: a single value
46
+ - parent/group: `children`
47
+ - choice: `choice`
48
+ - array/repeatable field: `maxOccurs > 1`
49
+ - attribute-bearing field: `attributes`
50
+
51
+ The engine walks the tree recursively and decides per node whether it should render:
52
+
53
+ - as a direct input
54
+ - as a repeatable array
55
+ - as a mutually exclusive choice
56
+ - as a group containing nested children
57
+
58
+ ## How Dynamic Rendering Works
59
+
60
+ At runtime the library derives behavior from metadata.
61
+
62
+ ### Paths
63
+
64
+ Every field gets a normalized path. If you do not provide one, the library derives it from parent path plus field name.
65
+
66
+ Examples:
67
+
68
+ - `person.firstName`
69
+ - `person.contacts[0].email`
70
+ - `invoice.lines[2].price`
71
+
72
+ These paths are used both for rendered `id`s and for `vee-validate` field registration.
73
+
74
+ ### Groups
75
+
76
+ A metadata item with `children` is treated as a parent/group. The group itself may be optional or repeatable, and its children inherit constraints when needed.
77
+
78
+ ### Arrays
79
+
80
+ A field becomes repeatable when `maxOccurs > 1`, unless runtime overrides force different behavior. The array implementation:
81
+
82
+ - manages placeholders and add/remove behavior
83
+ - tracks occurrences independently from validation state
84
+ - applies `minOccurs` and `maxOccurs`
85
+ - allows nested groups and nested arrays inside each occurrence
86
+
87
+ ### Choices
88
+
89
+ A metadata item with `choice` is treated as a mutually exclusive branch selector. The choice engine:
90
+
91
+ - tracks which branch currently has values
92
+ - disables sibling branches when one branch becomes active
93
+ - supports nested choices
94
+ - supports array-based branches
95
+ - calculates per-branch `minOccurs` and `maxOccurs` overrides dynamically
96
+
97
+ This is the part that gives you XSD-like `<choice>` behavior in a Vue form.
98
+
99
+ ## Validation Model
100
+
101
+ The library builds on `vee-validate` rather than replacing it.
102
+
103
+ ### Built-in Rules
104
+
105
+ The core package defines XSD-inspired rules such as:
106
+
107
+ - `xsd_required`
108
+ - `xsd_minOccurs`
109
+ - `xsd_choiceMinOccurs`
110
+ - `xsd_minLength`
111
+ - `xsd_maxLength`
112
+ - `xsd_length`
113
+ - `xsd_pattern`
114
+ - `xsd_minInclusive`
115
+ - `xsd_maxInclusive`
116
+ - `xsd_minExclusive`
117
+ - `xsd_maxExclusive`
118
+ - `xsd_enumeration`
119
+ - `xsd_whiteSpace`
120
+ - `xsd_fractionDigits`
121
+ - `xsd_totalDigits`
122
+
123
+ ### Message Resolution
124
+
125
+ Validation messages can come from:
126
+
127
+ 1. `settings.messages`
128
+ 2. `vee-validate` `configure({ generateMessage })`
129
+ 3. default rule output
130
+
131
+ The message resolver supports both positional placeholders like `{0}` and semantic placeholders like `{min}`, `{length}`, `{digits}`, and `{field}`.
132
+
133
+ ### Custom Validation
134
+
135
+ Metadata can also include custom `vee-validate` validation expressions:
136
+
137
+ - a single function
138
+ - an array of functions
139
+ - a pipe-separated string
140
+ - an object expression
141
+
142
+ The library splits multi-rule expressions into separate validation functions so multiple errors can be collected consistently.
143
+
144
+ ## Template Strategy
145
+
146
+ The recommended workflow is:
147
+
148
+ 1. Use `defineMetadata()` to strongly type your form field types and custom metadata extensions.
149
+ 2. Create one `DynamicFormTemplate` implementation for your design system.
150
+ 3. Pass metadata plus template into `DynamicForm`.
151
+
152
+ This separation is important:
153
+
154
+ - the core package owns behavior
155
+ - your template owns layout and styling
156
+ - your app owns business-specific metadata
157
+
158
+ ## Example
159
+
160
+ ```ts
161
+ import { defineMetadata } from '@bach.software/vue-dynamic-form';
162
+
163
+ const metadata = defineMetadata<
164
+ {
165
+ text: string
166
+ checkbox: boolean
167
+ heading: never
168
+ },
169
+ {
170
+ label?: string
171
+ description?: string
172
+ }
173
+ >();
174
+ ```
175
+
176
+ ```vue
177
+ <script setup lang="ts">
178
+ import { DynamicForm, useDynamicForm } from '@bach.software/vue-dynamic-form';
179
+ import MyFormTemplate from './MyFormTemplate.vue';
180
+
181
+ const { handleSubmit } = useDynamicForm();
182
+
183
+ const formMetadata = [{
184
+ name: 'person',
185
+ type: 'heading',
186
+ children: [
187
+ { name: 'firstName', type: 'text', fieldOptions: { label: 'First name' } },
188
+ { name: 'lastName', type: 'text', fieldOptions: { label: 'Last name' } },
189
+ ],
190
+ }];
191
+ </script>
192
+
193
+ <template>
194
+ <form @submit="handleSubmit(values => console.log(values))">
195
+ <DynamicForm :metadata="formMetadata" :template="MyFormTemplate" />
196
+ </form>
197
+ </template>
198
+ ```
199
+
200
+ ## Recommended Reading Order
201
+
202
+ - Overview and demos: [../../docs/index.md](../../docs/index.md)
203
+ - Getting started: [../../docs/guide/getting-started.md](../../docs/guide/getting-started.md)
204
+ - How the model works: [../../docs/guide/how-it-works.md](../../docs/guide/how-it-works.md)
205
+ - Templates: [../../docs/guide/templates.md](../../docs/guide/templates.md)
206
+ - Validation: [../../docs/guide/validation.md](../../docs/guide/validation.md)
207
+ - Interactive examples: [../../docs/examples/index.md](../../docs/examples/index.md)
@@ -0,0 +1,12 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),b=require("./useDynamicForm-SHyV1lLH.cjs");function y(d,c){return!d||!c||(d=c?.({...d}),d.children=d?.children?.map(s=>y(s,c)),d.choice=d?.choice?.map(s=>y(s,c))),d}const B={key:0,xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor",class:"size-3"},N={key:1,xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24","stroke-width":"1.5",stroke:"currentColor",class:"size-3"},h=e.defineComponent({__name:"IconButton",props:{icon:{},color:{default:"blue"}},emits:["click"],setup(d){return(c,s)=>(e.openBlock(),e.createElementBlock("button",{type:"button",class:e.normalizeClass(["cursor-pointer inline-flex items-center justify-center rounded-full size-5 text-white-800 cursor-pointer",{"bg-blue-200 hover:bg-blue-300":c.color==="blue","bg-red-200 hover:bg-red-300":c.color==="red"}]),onClick:s[0]||(s[0]=g=>c.$emit("click"))},[c.icon==="plus"?(e.openBlock(),e.createElementBlock("svg",B,s[1]||(s[1]=[e.createElementVNode("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M12 4.5v15m7.5-7.5h-15"},null,-1)]))):e.createCommentVNode("",!0),c.icon==="minus"?(e.openBlock(),e.createElementBlock("svg",N,s[2]||(s[2]=[e.createElementVNode("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"M5 12h14"},null,-1)]))):e.createCommentVNode("",!0)],2))}}),V={class:"text-sm whitespace-pre-wrap"},O=["data-testid"],E={class:"grid grid-cols-1 md:grid-cols-2 gap-6"},_={class:"grid grid-cols-1 md:grid-cols-2 gap-6 ms-6"},w={class:"text-sm whitespace-pre-wrap"},S=["data-testid"],$=["for"],D={key:0,class:"-ml-0.5 text-red-500"},T={class:"text-sm whitespace-pre-wrap"},F=["data-testid"],W=["for"],q={key:0,class:"-ml-0.5 text-red-500"},z={class:"flex gap-2 items-center"},I={class:"flex flex-col grow"},R={class:"text-sm whitespace-pre-wrap"},L=["data-testid"],A={key:0,class:"-ml-0.5 text-red-500"},U={class:"grid grid-cols-1 md:grid-cols-2 gap-6 ms-6"},j={class:"text-sm whitespace-pre-wrap"},P=["data-testid"],G={key:0,class:"-ml-0.5 text-red-500"},H={class:"grid grid-cols-1 md:grid-cols-2 gap-6 ms-6"},J={class:"text-sm whitespace-pre-wrap"},Y=["data-testid"],Q=["id","value","disabled","onChange","onBlur"],X=["value"],Z=["id","onUpdate:modelValue","disabled","onBlur"],K=["value"],M=["id","checked","disabled","onChange","onBlur"],ee=["id","onUpdate:modelValue","disabled","onBlur"],te=["id","onUpdate:modelValue","disabled","onBlur"],le=["id","value","disabled","onInput","onBlur"],C=e.defineComponent({__name:"TestFormTemplate",setup(d){const c=b.defineMetadata();return(s,g)=>(e.openBlock(),e.createBlock(b._sfc_main$4,{"metadata-configuration":e.unref(c)},{heading:e.withCtx(({fieldMetadata:t,fieldContext:{errorMessage:l,label:o},disabled:i,canAddItems:n,addItem:a,canRemoveItems:m,removeItem:u,slotProps:r})=>[t.hidden?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["mt-4",{"md:col-span-2":t.fullWidth}])},[o?(e.openBlock(),e.createElementBlock("h3",{key:0,class:e.normalizeClass(["flex text-xl font-bold gap-2 items-center mb-2",{"text-gray-500":t.disabled||i}])},[e.createTextVNode(e.toDisplayString(o)+" ",1),n?(e.openBlock(),e.createBlock(h,{key:0,icon:"plus",tabindex:"-1","data-testid":`${t.path}-add-button`,onClick:a},null,8,["data-testid","onClick"])):e.createCommentVNode("",!0),m?(e.openBlock(),e.createBlock(h,{key:1,icon:"minus",tabindex:"-1",color:"red","data-testid":`${t.path}-remove-button`,onClick:u},null,8,["data-testid","onClick"])):e.createCommentVNode("",!0)],2)):e.createCommentVNode("",!0),e.createElementVNode("pre",V,e.toDisplayString(t.description),1),l.value?(e.openBlock(),e.createElementBlock("span",{key:1,class:"text-red-600 text-sm","data-testid":`${t.path}-error-message`},e.toDisplayString(l.value),9,O)):e.createCommentVNode("",!0),e.createElementVNode("div",E,[e.renderSlot(s.$slots,"default",{level:(r?.level??0)+1})])],2))]),"heading-array":e.withCtx(()=>[e.renderSlot(s.$slots,"default")]),"default-choice":e.withCtx(({fieldMetadata:t,fieldContext:{errorMessage:l,label:o},disabled:i,required:n,slotProps:a})=>[t.hidden?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["flex flex-col gap-2",{"md:col-span-2":t.fullWidth}])},[e.createElementVNode("span",{class:e.normalizeClass(["flex gap-2 items-center",{"text-gray-500":i,"after:content-['*'] after:-ml-0.5 after:text-red-500":n}])},e.toDisplayString(o),3),e.createElementVNode("div",_,[e.renderSlot(s.$slots,"default",{level:(a?.level??0)+1,belowChoiceField:!0})]),e.createElementVNode("pre",w,e.toDisplayString(t.description),1),l.value?(e.openBlock(),e.createElementBlock("span",{key:0,class:"text-red-600 text-sm","data-testid":`${t.path}-error-message`},e.toDisplayString(l.value),9,S)):e.createCommentVNode("",!0)],2))]),"default-array":e.withCtx(({fieldMetadata:t,fieldContext:{errorMessage:l,label:o},disabled:i,required:n,canAddItems:a,addItem:m})=>[t.hidden?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["flex flex-col gap-2",{"md:col-span-2":t.fullWidth}])},[e.createElementVNode("label",{for:`${t.path}[0]`,class:e.normalizeClass([{"text-gray-500":t.disabled||i},"flex gap-2 items-center"])},[e.createTextVNode(e.toDisplayString(o)+" ",1),n?(e.openBlock(),e.createElementBlock("span",D,"*")):e.createCommentVNode("",!0),a?(e.openBlock(),e.createBlock(h,{key:1,icon:"plus",tabindex:"-1","data-testid":`${t.path}-add-button`,onClick:m},null,8,["data-testid","onClick"])):e.createCommentVNode("",!0)],10,$),e.renderSlot(s.$slots,"default",{hideLabel:!0}),e.createElementVNode("pre",T,e.toDisplayString(t.description),1),l.value?(e.openBlock(),e.createElementBlock("span",{key:0,class:"text-red-600 text-sm","data-testid":`${t.path}-error-message`},e.toDisplayString(l.value),9,F)):e.createCommentVNode("",!0)],2))]),default:e.withCtx(({fieldMetadata:t,fieldContext:{errorMessage:l,label:o},disabled:i,required:n,canRemoveItems:a,removeItem:m,slotProps:u})=>[t.hidden?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["flex flex-col gap-2",{"md:col-span-2":t.fullWidth}])},[u?.hideLabel?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("label",{key:0,for:t.path,class:e.normalizeClass({"text-gray-500":t.disabled||i})},[e.createTextVNode(e.toDisplayString(o)+" ",1),n?(e.openBlock(),e.createElementBlock("span",q,"*")):e.createCommentVNode("",!0)],10,W)),e.createElementVNode("div",z,[e.createElementVNode("div",I,[e.renderSlot(s.$slots,"default")]),e.createVNode(h,{class:e.normalizeClass({invisible:!a}),icon:"minus",tabindex:"-1",color:"red","data-testid":`${t.path}-remove-button`,onClick:m},null,8,["class","data-testid","onClick"])]),e.createElementVNode("pre",R,e.toDisplayString(t.description),1),l.value?(e.openBlock(),e.createElementBlock("span",{key:1,class:"text-red-600 text-sm","data-testid":`${t.path}-error-message`},e.toDisplayString(l.value),9,L)):e.createCommentVNode("",!0)],2)),e.renderSlot(s.$slots,"attributes")]),"group-array":e.withCtx(({fieldMetadata:t,fieldContext:{errorMessage:l,label:o},disabled:i,required:n,canAddItems:a,addItem:m,slotProps:u})=>[t.hidden?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[],64)):u?.belowChoiceField?(e.openBlock(),e.createElementBlock("div",{key:1,class:e.normalizeClass({"md:col-span-2":t.fullWidth})},[e.createElementVNode("span",{class:e.normalizeClass(["flex gap-2 items-center mb-2",{"text-gray-500":t.disabled||i}])},[e.createTextVNode(e.toDisplayString(o)+" ",1),n?(e.openBlock(),e.createElementBlock("span",A,"*")):e.createCommentVNode("",!0),a?(e.openBlock(),e.createBlock(h,{key:1,icon:"plus",tabindex:"-1","data-testid":`${t.path}-add-button`,onClick:m},null,8,["data-testid","onClick"])):e.createCommentVNode("",!0)],2),e.createElementVNode("div",U,[e.renderSlot(s.$slots,"default",{level:(u?.level??0)+1})]),e.createElementVNode("pre",j,e.toDisplayString(t.description),1),l.value?(e.openBlock(),e.createElementBlock("span",{key:0,class:"text-red-600 text-sm","data-testid":`${t.path}-error-message`},e.toDisplayString(l.value),9,P)):e.createCommentVNode("",!0)],2)):e.renderSlot(s.$slots,"default",{key:2})]),group:e.withCtx(({fieldMetadata:t,fieldContext:{errorMessage:l,label:o},disabled:i,required:n,canAddItems:a,canRemoveItems:m,addItem:u,removeItem:r,slotProps:p})=>[t.hidden?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass({"md:col-span-2":t.fullWidth})},[p?.hideLabel?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("span",{key:0,class:e.normalizeClass(["flex gap-2 items-center mb-2",{"text-gray-500":t.disabled||i}])},[e.createTextVNode(e.toDisplayString(o)+" ",1),n?(e.openBlock(),e.createElementBlock("span",G,"*")):e.createCommentVNode("",!0),a?(e.openBlock(),e.createBlock(h,{key:1,icon:"plus",tabindex:"-1","data-testid":`${t.path}-add-button`,onClick:u},null,8,["data-testid","onClick"])):e.createCommentVNode("",!0),m?(e.openBlock(),e.createBlock(h,{key:2,icon:"minus",tabindex:"-1","data-testid":`${t.path}-remove-button`,color:"red",onClick:r},null,8,["data-testid","onClick"])):e.createCommentVNode("",!0)],2)),e.createElementVNode("div",H,[e.renderSlot(s.$slots,"default",{level:(p?.level??0)+1})]),e.createElementVNode("pre",J,e.toDisplayString(t.description),1),l.value?(e.openBlock(),e.createElementBlock("span",{key:1,class:"text-red-600 text-sm","data-testid":`${t.path}-error-message`},e.toDisplayString(l.value),9,Y)):e.createCommentVNode("",!0)],2)),e.renderSlot(s.$slots,"attributes")]),"select-input":e.withCtx(({fieldMetadata:t,fieldContext:{value:l,handleBlur:o,handleChange:i},disabled:n})=>[e.createElementVNode("select",{id:t.path,value:l.value,disabled:t.disabled||n,class:"h-9 bg-gray-100 border-gray-200 border rounded px-3 text-sm",onChange:i,onBlur:o},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.options,({key:a,value:m})=>(e.openBlock(),e.createElementBlock("option",{key:a,value:a},e.toDisplayString(m),9,X))),128))],40,Q)]),"selectBoundByVModel-input":e.withCtx(({fieldMetadata:t,fieldContext:{value:l,handleBlur:o},disabled:i})=>[e.withDirectives(e.createElementVNode("select",{id:t.path,"onUpdate:modelValue":n=>l.value=n,disabled:t.disabled||i,class:"h-9 bg-gray-100 border-gray-200 border rounded px-3 text-sm",onBlur:o},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.options,({key:n,value:a})=>(e.openBlock(),e.createElementBlock("option",{key:n,value:n},e.toDisplayString(a),9,K))),128))],40,Z),[[e.vModelSelect,l.value]])]),"checkbox-input":e.withCtx(({fieldMetadata:t,fieldContext:{value:l,handleBlur:o,handleChange:i},disabled:n})=>[e.createElementVNode("input",{id:t.path,checked:l.value,disabled:t.disabled||n,type:"checkbox",class:"h-6 bg-gray-100 border-gray-200 border rounded px-3 text-sm",onChange:a=>i(a.target.checked),onBlur:o},null,40,M)]),"checkboxBoundByVModel-input":e.withCtx(({fieldMetadata:t,fieldContext:{value:l,handleBlur:o},disabled:i})=>[e.withDirectives(e.createElementVNode("input",{id:t.path,"onUpdate:modelValue":n=>l.value=n,disabled:t.disabled||i,type:"checkbox",class:"h-6 bg-gray-100 border-gray-200 border rounded px-3 text-sm",onBlur:o},null,40,ee),[[e.vModelCheckbox,l.value]])]),"textBoundByVModel-input":e.withCtx(({fieldMetadata:t,fieldContext:{value:l,handleBlur:o},disabled:i})=>[e.withDirectives(e.createElementVNode("input",{id:t.path,"onUpdate:modelValue":n=>l.value=n,disabled:t.disabled||i,type:"text",class:"h-9 bg-gray-100 border-gray-200 border rounded px-3 text-sm",onBlur:o},null,40,te),[[e.vModelText,l.value]])]),"default-input":e.withCtx(({fieldMetadata:t,fieldContext:{value:l,handleBlur:o,handleChange:i},disabled:n})=>[e.createElementVNode("input",{id:t.path,value:l.value,disabled:t.disabled||n,type:"text",class:"h-9 bg-gray-100 border-gray-200 border rounded px-3 text-sm",onInput:i,onBlur:o},null,40,le)]),_:3},8,["metadata-configuration"]))}}),oe={class:"flex justify-end gap-2"},ie={key:1,type:"submit",class:"cursor-pointer mt-4 bg-blue-500 text-white px-4 py-2 rounded","data-testid":"submit"},ne={key:0,"data-testid":"errors",class:"col-12 text-red-600"},se=["innerHTML"],re={key:1,"data-testid":"isSubmitted"},ae={key:2,class:"bg-gray-100 p-4 rounded-lg text-sm overflow-auto"},de=e.defineComponent({__name:"TestForm",props:{metadata:{},settings:{},showDebugState:{type:Boolean,default:!1},initialEdit:{type:Boolean,default:!0},hideFieldsWithoutValue:{type:Boolean,default:!1},initialValues:{}},setup(d){const{values:c,handleSubmit:s,errors:g,meta:t}=b.useDynamicForm({initialValues:d.initialValues}),l=e.ref(),o=e.ref(d.initialEdit),i=e.ref(!1),n=e.computed(()=>d.metadata?.map(u=>y(u,r=>(r.computedProps=r.computedProps??[],r.computedProps.push(p=>{o.value||(p.disabled=!0)}),d.hideFieldsWithoutValue&&(r.computedProps.push((p,k)=>{!o.value&&!b.checkTreeHasValue(k.value)&&(p.hidden=!0)}),r.computedProps.push((p,k,x)=>{!o.value&&x.value.length>0&&x.value.every(v=>v.hidden)&&(p.hidden=!0)})),r)))),a=e.computed(()=>({analytics:!0,messages:{required:"{field} is required",minOccurs:"At least {min} items required",choiceMinOccurs:"The following fields need to occur at least {min} time(s): {field}",minLength:"The minimum length of {field} is {length}",maxLength:"The maximum length of {field} is {length}",length:"{field} must be exactly {length} characters",pattern:"{field} does not match the required pattern",minInclusive:"{field} must be at least {min}",maxInclusive:"{field} must be at most {max}",minExclusive:"{field} must be greater than {min}",maxExclusive:"{field} must be less than {max}",enumeration:"{field} must be one of the allowed values",whiteSpace:"{field} contains invalid whitespace (mode: {mode})",fractionDigits:"{field} may have at most {digits} decimal place(s)",totalDigits:"{field} may have at most {digits} significant digit(s)"},...d.settings??{}}));function m(u){s(r=>{i.value=!0,o.value=!1},({errors:r})=>{i.value=!1})(u)}return(u,r)=>(e.openBlock(),e.createElementBlock("form",{onSubmit:e.withModifiers(m,["prevent"])},[e.createElementVNode("div",oe,[o.value?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("button",{key:0,type:"button",class:"cursor-pointer mt-4 bg-blue-500 text-white px-4 py-2 rounded","data-testid":"submit",onClick:r[0]||(r[0]=p=>o.value=!0)}," Edit ")),o.value?(e.openBlock(),e.createElementBlock("button",ie," Submit ")):e.createCommentVNode("",!0),o.value?(e.openBlock(),e.createElementBlock("button",{key:2,type:"button",class:"cursor-pointer mt-4 bg-gray-200 text-black px-4 py-2 rounded","data-testid":"cancel",onClick:r[1]||(r[1]=p=>o.value=!1)}," Cancel ")):e.createCommentVNode("",!0)]),Object.values(e.unref(g)).length?(e.openBlock(),e.createElementBlock("div",ne,[r[3]||(r[3]=e.createTextVNode(" Errors: ",-1)),e.createElementVNode("ul",null,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(g),(p,k)=>(e.openBlock(),e.createElementBlock("li",{key:k},[e.createElementVNode("span",{innerHTML:p},null,8,se)]))),128))])])):e.createCommentVNode("",!0),e.createVNode(b._sfc_main,{template:C,metadata:n.value,settings:a.value,"onUpdate:modelValue":r[2]||(r[2]=p=>l.value=p)},null,8,["metadata","settings"]),i.value?(e.openBlock(),e.createElementBlock("span",re)):e.createCommentVNode("",!0),u.showDebugState?(e.openBlock(),e.createElementBlock("pre",ae,"IsDirty: "+e.toDisplayString(e.unref(t).dirty)+`
2
+ Pending: `+e.toDisplayString(e.unref(t).pending)+`
3
+ Touched: `+e.toDisplayString(e.unref(t).touched)+`
4
+ Valid: `+e.toDisplayString(e.unref(t).valid)+`
5
+ Submitted: `+e.toDisplayString(i.value)+`
6
+
7
+ // form values:
8
+ `+e.toDisplayString(JSON.stringify(e.unref(c),null,2))+`
9
+ `,1)):e.createCommentVNode("",!0)],32))}}),ce=f([{name:"text",type:"text",fieldOptions:{label:"Text Input"},path:"with.custom.structure",restriction:{maxLength:10}}]),ue=f([{fieldOptions:{label:"Array Fields"},type:"heading",children:[{fieldOptions:{label:"Optional field (max 3)"},minOccurs:0,maxOccurs:3},{fieldOptions:{label:"Required field (max 3)"},maxOccurs:3},{fieldOptions:{label:"2 Fields required"},minOccurs:2,maxOccurs:4},{fieldOptions:{label:"Section (2 sections required)"},type:"heading",minOccurs:2,maxOccurs:4,fullWidth:!0,children:[{fieldOptions:{label:"Nested field 1"}},{fieldOptions:{label:"Required Nested field 2"},type:"select",options:[{key:"option1",value:"Option 1"},{key:"option2",value:"Option 2"},{key:"option3",value:"Option 3"}]},{fieldOptions:{label:"Nested field 3"},type:"checkbox"}]}]}]),pe=f([{fieldOptions:{label:"Grouped Fields"},type:"heading",children:[{fieldOptions:{label:"Required group"},type:"group",children:[{fieldOptions:{label:"Required Nested field 1"},fullWidth:!0},{fieldOptions:{label:"Required Nested field 2"},fullWidth:!0}]},{fieldOptions:{label:"Optional group"},type:"group",minOccurs:0,description:`The group is optional, therefore the children will only be required once 1 value is filled in.
10
+
11
+ You can test it by filling in one of the fields.`,children:[{fieldOptions:{label:"Required Nested field 1"},fullWidth:!0},{fieldOptions:{label:"Required Nested field 2"},fullWidth:!0}]}]},{fieldOptions:{label:"Grouped Array Fields"},type:"heading",children:[{fieldOptions:{label:"Required group"},type:"group",maxOccurs:5,fullWidth:!0,children:[{fieldOptions:{label:"Required Nested field 1"}},{fieldOptions:{label:"Required Nested field 2"}}]},{fieldOptions:{label:"Optional group"},type:"group",minOccurs:0,maxOccurs:5,fullWidth:!0,children:[{fieldOptions:{label:"Required Nested field 1"}},{fieldOptions:{label:"Required Nested field 2"}}]}]}]),me=f([{fieldOptions:{label:"Choice Fields (minOccurs 1, maxOccurs 1)"},type:"heading",children:[{fieldOptions:{label:"Simple Choice Field"},fullWidth:!0,description:"In a choice field, only 1 of the fields can be filled in.",choice:[{fieldOptions:{label:"Nested Field 1"}},{fieldOptions:{label:"Nested Field 2"}}]}]},{fieldOptions:{label:"Choice Grouped Fields (minOccurs 1, maxOccurs 3)"},type:"heading",children:[{fieldOptions:{label:"Array Choice Field"},type:"group",maxOccurs:3,fullWidth:!0,description:"In a choice field, only 1 of the fields can be filled in.",choice:[{fieldOptions:{label:"Nested Field 1"},type:"group",children:[{fieldOptions:{label:"Nested Child Field 1"},fullWidth:!0},{fieldOptions:{label:"Nested Child Field 2"},fullWidth:!0}]},{fieldOptions:{label:"Nested Field 2"},type:"group",children:[{fieldOptions:{label:"Nested Child Field 1"},fullWidth:!0},{fieldOptions:{label:"Nested Child Field 2"},fullWidth:!0}]}]}]},{fieldOptions:{label:"Choice Array Fields (minOccurs 1, maxOccurs 3)"},type:"heading",children:[{fieldOptions:{label:"Array Choice Field"},type:"group",maxOccurs:3,fullWidth:!0,description:"In a choice field, only 1 of the fields can be filled in.",choice:[{fieldOptions:{label:"Nested Field 1"},maxOccurs:3},{fieldOptions:{label:"Nested Field 2"},maxOccurs:3}]}]}]),he=f([{fieldOptions:{label:"Personal Info"},type:"heading",name:"person",description:"Only showing the fields that have a value. Click edit to change.",fullWidth:!0,children:[{name:"firstName",fieldOptions:{label:"First Name"}},{name:"lastName",fieldOptions:{label:"Last Name"}},{name:"email",fieldOptions:{label:"Email"}}]},{fieldOptions:{label:"Address"},type:"heading",name:"address",fullWidth:!0,children:[{name:"street",fieldOptions:{label:"Street"},minOccurs:0},{name:"city",fieldOptions:{label:"City"},minOccurs:0},{name:"country",fieldOptions:{label:"Country"},minOccurs:0}]}],void 0,{initialEdit:!1,hideFieldsWithoutValue:!0,initialValues:{person:{firstName:"Jack",lastName:"Smit"}}}),fe=f([{name:"items",type:"text",fieldOptions:{label:"Items"},maxOccurs:3,attributes:[{name:"lang",type:"text",minOccurs:0}]}],{});function f(d,c,s={}){return e.markRaw(e.defineComponent({render:()=>e.h(de,{...s,metadata:d,settings:c,showDebugState:!0})}))}exports.TestFormTemplate=C;exports.arrayTestCase=ue;exports.childFieldsTestCase=he;exports.choiceTestCase=me;exports.createTestCase=f;exports.defaultTestCase=ce;exports.groupTestCase=pe;exports.individualTestCase=fe;
12
+ //# sourceMappingURL=examples.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"examples.cjs.js","sources":["../src/utils/mapEachMetadataItem.ts","../src/examples/components/IconButton.vue","../src/examples/TestFormTemplate.vue","../src/examples/TestForm.vue","../src/examples/__tests__/TestFormTemplate.testcases.ts"],"sourcesContent":["import type { FieldMetadata } from '@/types/FieldMetadata';\n\n/**\n * Recursively walks a `FieldMetadata` tree (visiting `children` and `choice`) and applies\n * `callbackFunc` to every node, returning the transformed tree.\n *\n * The callback receives a shallow clone of each node, so mutations inside the callback do not\n * affect the original metadata. `children` and `choice` on the returned node are replaced with\n * the recursively-mapped results after the callback runs.\n */\nexport function mapEachMetadataItem<\n ExtendedFieldTypes extends string = string,\n ExtendedProperties extends object = object,\n>(\n metadata: FieldMetadata<ExtendedFieldTypes, ExtendedProperties>,\n callbackFunc: (item: FieldMetadata<ExtendedFieldTypes, ExtendedProperties>) => FieldMetadata<ExtendedFieldTypes, ExtendedProperties>,\n): FieldMetadata<ExtendedFieldTypes, ExtendedProperties> {\n if (!metadata || !callbackFunc)\n return metadata;\n\n metadata = callbackFunc?.({ ...metadata });\n metadata.children = metadata?.children?.map(x => mapEachMetadataItem(x, callbackFunc));\n metadata.choice = metadata?.choice?.map(x => mapEachMetadataItem(x, callbackFunc));\n return metadata;\n}\n","<script lang=\"ts\" setup>\ninterface Props {\n icon: 'plus' | 'minus'\n color?: 'blue' | 'red'\n}\ninterface Emits {\n (e: 'click'): void\n}\nconst {\n icon,\n color = 'blue',\n} = defineProps<Props>();\ndefineEmits<Emits>();\n</script>\n\n<template>\n <button\n type=\"button\"\n class=\"cursor-pointer inline-flex items-center justify-center rounded-full size-5 text-white-800 cursor-pointer\"\n :class=\"{\n 'bg-blue-200 hover:bg-blue-300': color === 'blue',\n 'bg-red-200 hover:bg-red-300': color === 'red',\n }\"\n @click=\"$emit('click')\"\n >\n <svg v-if=\"icon === 'plus'\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-3\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" />\n </svg>\n <svg v-if=\"icon === 'minus'\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"size-3\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M5 12h14\" />\n </svg>\n </button>\n</template>\n","<script lang=\"ts\" setup>\nimport type { GetMetadataType } from '@/types/GetMetadataType';\nimport DynamicFormTemplate from '@/components/DynamicFormTemplate.vue';\nimport { defineMetadata } from '@/core/defineMetadata';\nimport IconButton from './components/IconButton.vue';\n\nexport type Metadata = GetMetadataType<typeof metadata>;\n\nconst metadata = defineMetadata<\n {\n text: string\n textBoundByVModel: string\n select: string\n selectBoundByVModel: string\n checkbox: boolean\n checkboxBoundByVModel: boolean\n heading: never\n group: never\n },\n {\n description?: string\n options?: { key: string, value: string }[]\n fullWidth?: boolean\n disabled?: boolean\n hidden?: boolean\n },\n /**\n * Free to decide what attributes you want to pass internally between your templates.\n * You can add any attribute to a <slot /> and then it will be accessible in props.slotProps.\n */\n {\n hideLabel?: boolean\n /** Example on how to keep track of the levels */\n level?: number\n /** Helps identifying that we're below a choice field, so if we're rendering an array we can adjust our layout */\n belowChoiceField?: boolean\n hidden?: boolean\n }\n>();\n</script>\n\n<template>\n <DynamicFormTemplate :metadata-configuration=\"metadata\">\n <template #heading=\"{ fieldMetadata, fieldContext: { errorMessage, label }, disabled, canAddItems, addItem, canRemoveItems, removeItem, slotProps }\">\n <div v-if=\"!fieldMetadata.hidden\" class=\"mt-4\" :class=\"{ 'md:col-span-2': fieldMetadata.fullWidth }\">\n <h3 v-if=\"label\" class=\"flex text-xl font-bold gap-2 items-center mb-2\" :class=\"{ 'text-gray-500': fieldMetadata.disabled || disabled }\">\n {{ label }}\n <IconButton v-if=\"canAddItems\" icon=\"plus\" tabindex=\"-1\" :data-testid=\"`${fieldMetadata.path}-add-button`\" @click=\"addItem\" />\n <IconButton v-if=\"canRemoveItems\" icon=\"minus\" tabindex=\"-1\" color=\"red\" :data-testid=\"`${fieldMetadata.path}-remove-button`\" @click=\"removeItem\" />\n </h3>\n <pre class=\"text-sm whitespace-pre-wrap\">{{ fieldMetadata.description }}</pre>\n <span\n v-if=\"errorMessage.value\"\n class=\"text-red-600 text-sm\"\n :data-testid=\"`${fieldMetadata.path}-error-message`\"\n >{{ errorMessage.value }}</span>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <slot :level=\"(slotProps?.level ?? 0) + 1\" />\n </div>\n </div>\n </template>\n\n <template #heading-array>\n <!-- Don't show any extra elements for the heading -->\n <slot />\n </template>\n\n <template #default-choice=\"{ fieldMetadata, fieldContext: { errorMessage, label }, disabled, required, slotProps }\">\n <div v-if=\"!fieldMetadata.hidden\" class=\"flex flex-col gap-2\" :class=\"{ 'md:col-span-2': fieldMetadata.fullWidth }\">\n <span class=\"flex gap-2 items-center\" :class=\"{ 'text-gray-500': disabled, 'after:content-[\\'*\\'] after:-ml-0.5 after:text-red-500': required }\">\n {{ label }}\n </span>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6 ms-6\">\n <slot :level=\"(slotProps?.level ?? 0) + 1\" :below-choice-field=\"true\" />\n </div>\n <pre class=\"text-sm whitespace-pre-wrap\">{{ fieldMetadata.description }}</pre>\n <span\n v-if=\"errorMessage.value\"\n class=\"text-red-600 text-sm\"\n :data-testid=\"`${fieldMetadata.path}-error-message`\"\n >{{ errorMessage.value }}</span>\n </div>\n </template>\n\n <template #default-array=\"{ fieldMetadata, fieldContext: { errorMessage, label }, disabled, required, canAddItems, addItem }\">\n <div v-if=\"!fieldMetadata.hidden\" class=\"flex flex-col gap-2\" :class=\"{ 'md:col-span-2': fieldMetadata.fullWidth }\">\n <label :for=\"`${fieldMetadata.path}[0]`\" :class=\"{ 'text-gray-500': fieldMetadata.disabled || disabled }\" class=\"flex gap-2 items-center\">\n {{ label }}\n <span v-if=\"required\" class=\"-ml-0.5 text-red-500\">*</span>\n <IconButton v-if=\"canAddItems\" icon=\"plus\" tabindex=\"-1\" :data-testid=\"`${fieldMetadata.path}-add-button`\" @click=\"addItem\" />\n </label>\n <slot :hide-label=\"true\" />\n <pre class=\"text-sm whitespace-pre-wrap\">{{ fieldMetadata.description }}</pre>\n <span\n v-if=\"errorMessage.value\"\n class=\"text-red-600 text-sm\"\n :data-testid=\"`${fieldMetadata.path}-error-message`\"\n >{{ errorMessage.value }}</span>\n </div>\n </template>\n\n <template #default=\"{ fieldMetadata, fieldContext: { errorMessage, label }, disabled, required, canRemoveItems, removeItem, slotProps }\">\n <div v-if=\"!fieldMetadata.hidden\" class=\"flex flex-col gap-2\" :class=\"{ 'md:col-span-2': fieldMetadata.fullWidth }\">\n <label v-if=\"!slotProps?.hideLabel\" :for=\"fieldMetadata.path\" :class=\"{ 'text-gray-500': fieldMetadata.disabled || disabled }\">\n {{ label }}\n <span v-if=\"required\" class=\"-ml-0.5 text-red-500\">*</span>\n </label>\n <div class=\"flex gap-2 items-center\">\n <div class=\"flex flex-col grow\">\n <slot />\n </div>\n <IconButton :class=\"{ invisible: !canRemoveItems }\" icon=\"minus\" tabindex=\"-1\" color=\"red\" :data-testid=\"`${fieldMetadata.path}-remove-button`\" @click=\"removeItem\" />\n </div>\n <pre class=\"text-sm whitespace-pre-wrap\">{{ fieldMetadata.description }}</pre>\n <span\n v-if=\"errorMessage.value\"\n class=\"text-red-600 text-sm\"\n :data-testid=\"`${fieldMetadata.path}-error-message`\"\n >{{ errorMessage.value }}</span>\n </div>\n <slot name=\"attributes\" />\n </template>\n\n <template #group-array=\"{ fieldMetadata, fieldContext: { errorMessage, label }, disabled, required, canAddItems, addItem, slotProps }\">\n <template v-if=\"fieldMetadata.hidden\" />\n <!-- In case we're below a choice field, the first array item is not automatically added, so show a label with buttons -->\n <div v-else-if=\"slotProps?.belowChoiceField\" :class=\"{ 'md:col-span-2': fieldMetadata.fullWidth }\">\n <span class=\"flex gap-2 items-center mb-2\" :class=\"{ 'text-gray-500': fieldMetadata.disabled || disabled }\">\n {{ label }}\n <span v-if=\"required\" class=\"-ml-0.5 text-red-500\">*</span>\n <IconButton v-if=\"canAddItems\" icon=\"plus\" tabindex=\"-1\" :data-testid=\"`${fieldMetadata.path}-add-button`\" @click=\"addItem\" />\n </span>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6 ms-6\">\n <slot :level=\"(slotProps?.level ?? 0) + 1\" />\n </div>\n <pre class=\"text-sm whitespace-pre-wrap\">{{ fieldMetadata.description }}</pre>\n <span\n v-if=\"errorMessage.value\"\n class=\"text-red-600 text-sm\"\n :data-testid=\"`${fieldMetadata.path}-error-message`\"\n >{{ errorMessage.value }}</span>\n </div>\n <!-- In case we show an input directly, show a label and buttons -->\n <slot v-else />\n </template>\n\n <template #group=\"{ fieldMetadata, fieldContext: { errorMessage, label }, disabled, required, canAddItems, canRemoveItems, addItem, removeItem, slotProps }\">\n <!-- In case of a grouped field we render the field differently -->\n <div v-if=\"!fieldMetadata.hidden\" :class=\"{ 'md:col-span-2': fieldMetadata.fullWidth }\">\n <span v-if=\"!slotProps?.hideLabel\" class=\"flex gap-2 items-center mb-2\" :class=\"{ 'text-gray-500': fieldMetadata.disabled || disabled }\">\n {{ label }}\n <span v-if=\"required\" class=\"-ml-0.5 text-red-500\">*</span>\n <IconButton v-if=\"canAddItems\" icon=\"plus\" tabindex=\"-1\" :data-testid=\"`${fieldMetadata.path}-add-button`\" @click=\"addItem\" />\n <IconButton v-if=\"canRemoveItems\" icon=\"minus\" tabindex=\"-1\" :data-testid=\"`${fieldMetadata.path}-remove-button`\" color=\"red\" @click=\"removeItem\" />\n </span>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6 ms-6\">\n <slot :level=\"(slotProps?.level ?? 0) + 1\" />\n </div>\n <pre class=\"text-sm whitespace-pre-wrap\">{{ fieldMetadata.description }}</pre>\n <span\n v-if=\"errorMessage.value\"\n class=\"text-red-600 text-sm\"\n :data-testid=\"`${fieldMetadata.path}-error-message`\"\n >{{ errorMessage.value }}</span>\n </div>\n <slot name=\"attributes\" />\n </template>\n\n <template #select-input=\"{ fieldMetadata, fieldContext: { value, handleBlur, handleChange }, disabled }\">\n <select\n :id=\"fieldMetadata.path\"\n :value=\"value.value\"\n :disabled=\"fieldMetadata.disabled || disabled\"\n class=\"h-9 bg-gray-100 border-gray-200 border rounded px-3 text-sm\"\n @change=\"handleChange\"\n @blur=\"handleBlur\"\n >\n <option v-for=\"{ key: optionKey, value: optionValue } in fieldMetadata.options\" :key=\"optionKey\" :value=\"optionKey\">\n {{ optionValue }}\n </option>\n </select>\n </template>\n\n <template #selectBoundByVModel-input=\"{ fieldMetadata, fieldContext: { value, handleBlur }, disabled }\">\n <select\n :id=\"fieldMetadata.path\"\n v-model=\"value.value\"\n :disabled=\"fieldMetadata.disabled || disabled\"\n class=\"h-9 bg-gray-100 border-gray-200 border rounded px-3 text-sm\"\n @blur=\"handleBlur\"\n >\n <option v-for=\"{ key: optionKey, value: optionValue } in fieldMetadata.options\" :key=\"optionKey\" :value=\"optionKey\">\n {{ optionValue }}\n </option>\n </select>\n </template>\n\n <template #checkbox-input=\"{ fieldMetadata, fieldContext: { value, handleBlur, handleChange }, disabled }\">\n <input\n :id=\"fieldMetadata.path\"\n :checked=\"value.value\"\n :disabled=\"fieldMetadata.disabled || disabled\"\n type=\"checkbox\"\n class=\"h-6 bg-gray-100 border-gray-200 border rounded px-3 text-sm\"\n @change=\"handleChange(($event.target as HTMLInputElement).checked)\"\n @blur=\"handleBlur\"\n >\n </template>\n\n <template #checkboxBoundByVModel-input=\"{ fieldMetadata, fieldContext: { value, handleBlur }, disabled }\">\n <input\n :id=\"fieldMetadata.path\"\n v-model=\"value.value\"\n :disabled=\"fieldMetadata.disabled || disabled\"\n type=\"checkbox\"\n class=\"h-6 bg-gray-100 border-gray-200 border rounded px-3 text-sm\"\n @blur=\"handleBlur\"\n >\n </template>\n\n <template #textBoundByVModel-input=\"{ fieldMetadata, fieldContext: { value, handleBlur }, disabled }\">\n <input\n :id=\"fieldMetadata.path\"\n v-model=\"value.value\"\n :disabled=\"fieldMetadata.disabled || disabled\"\n type=\"text\"\n class=\"h-9 bg-gray-100 border-gray-200 border rounded px-3 text-sm\"\n @blur=\"handleBlur\"\n >\n </template>\n\n <template #default-input=\"{ fieldMetadata, fieldContext: { value, handleBlur, handleChange }, disabled }\">\n <input\n :id=\"fieldMetadata.path\"\n :value=\"value.value\"\n :disabled=\"fieldMetadata.disabled || disabled\"\n type=\"text\"\n class=\"h-9 bg-gray-100 border-gray-200 border rounded px-3 text-sm\"\n @input=\"handleChange\"\n @blur=\"handleBlur\"\n >\n </template>\n </DynamicFormTemplate>\n</template>\n","<script setup lang=\"ts\">\nimport type { GenericObject } from 'vee-validate';\n\nimport type { Metadata } from './TestFormTemplate.vue';\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport { computed, ref } from 'vue';\nimport { checkTreeHasValue } from '@/utils/checkTreeHasValue';\nimport { mapEachMetadataItem } from '@/utils/mapEachMetadataItem';\nimport DynamicForm from '../components/DynamicForm.vue';\nimport { useDynamicForm } from '../core/useDynamicForm';\nimport TestFormTemplate from './TestFormTemplate.vue';\n\nexport interface Props {\n metadata: Metadata[]\n settings?: DynamicFormSettings\n showDebugState?: boolean\n initialEdit?: boolean\n hideFieldsWithoutValue?: boolean\n initialValues?: GenericObject\n}\n\nconst { metadata, settings: _settings, initialEdit = true, hideFieldsWithoutValue = false, showDebugState = false, initialValues } = defineProps<Props>();\n\nconst { values, handleSubmit, errors, meta } = useDynamicForm({\n initialValues,\n});\nconst manualValues = ref();\nconst editMode = ref(initialEdit);\nconst isSubmitted = ref(false);\n\n// Add edit mode functionality to the form. In case we're not in edit mode, disable all items.\nconst metadataWithEdit = computed(() => metadata?.map(x => mapEachMetadataItem(x, (item) => {\n item.computedProps = item.computedProps ?? [];\n\n // Disable all fields when not in edit mode\n item.computedProps.push((thisField) => {\n if (!editMode.value)\n thisField.disabled = true;\n });\n\n if (hideFieldsWithoutValue) {\n // In view mode, hide fields that have no value\n item.computedProps.push((thisField, fieldValue) => {\n if (!editMode.value && !checkTreeHasValue(fieldValue.value))\n thisField.hidden = true;\n });\n\n // In view mode, hide a parent field when all of its children are hidden\n item.computedProps.push((thisField, _fieldValue, childFields) => {\n if (!editMode.value && childFields.value.length > 0 && childFields.value.every(c => c.hidden))\n thisField.hidden = true;\n });\n }\n\n return item;\n})));\n\nconst settings = computed(() => ({\n analytics: true,\n messages: {\n required: '{field} is required',\n minOccurs: 'At least {min} items required',\n choiceMinOccurs: 'The following fields need to occur at least {min} time(s): {field}',\n minLength: 'The minimum length of {field} is {length}',\n maxLength: 'The maximum length of {field} is {length}',\n length: '{field} must be exactly {length} characters',\n pattern: '{field} does not match the required pattern',\n minInclusive: '{field} must be at least {min}',\n maxInclusive: '{field} must be at most {max}',\n minExclusive: '{field} must be greater than {min}',\n maxExclusive: '{field} must be less than {max}',\n enumeration: '{field} must be one of the allowed values',\n whiteSpace: '{field} contains invalid whitespace (mode: {mode})',\n fractionDigits: '{field} may have at most {digits} decimal place(s)',\n totalDigits: '{field} may have at most {digits} significant digit(s)',\n },\n ...(_settings ?? {}),\n}));\n\nfunction submit(e?: Event) {\n handleSubmit(\n (_values) => {\n isSubmitted.value = true;\n editMode.value = false;\n },\n ({ errors: _errors }) => {\n isSubmitted.value = false;\n },\n )(e);\n};\n</script>\n\n<template>\n <form @submit.prevent=\"submit\">\n <div class=\"flex justify-end gap-2\">\n <button v-if=\"!editMode\" type=\"button\" class=\"cursor-pointer mt-4 bg-blue-500 text-white px-4 py-2 rounded\" data-testid=\"submit\" @click=\"editMode = true\">\n Edit\n </button>\n <button v-if=\"editMode\" type=\"submit\" class=\"cursor-pointer mt-4 bg-blue-500 text-white px-4 py-2 rounded\" data-testid=\"submit\">\n Submit\n </button>\n <button v-if=\"editMode\" type=\"button\" class=\"cursor-pointer mt-4 bg-gray-200 text-black px-4 py-2 rounded\" data-testid=\"cancel\" @click=\"editMode = false\">\n Cancel\n </button>\n </div>\n <div v-if=\"Object.values(errors).length\" data-testid=\"errors\" class=\"col-12 text-red-600\">\n Errors:\n <ul>\n <li v-for=\"(error, key) in errors\" :key=\"key\">\n <span v-html=\"error\" />\n </li>\n </ul>\n </div>\n <DynamicForm\n :template=\"TestFormTemplate\"\n :metadata=\"metadataWithEdit\"\n :settings\n @update:model-value=\"manualValues = $event\"\n />\n <span v-if=\"isSubmitted\" data-testid=\"isSubmitted\" />\n <pre v-if=\"showDebugState\" class=\"bg-gray-100 p-4 rounded-lg text-sm overflow-auto\">\nIsDirty: {{ meta.dirty }}\nPending: {{ meta.pending }}\nTouched: {{ meta.touched }}\nValid: {{ meta.valid }}\nSubmitted: {{ isSubmitted }}\n\n// form values:\n{{ JSON.stringify(values, null, 2) }}\n </pre>\n </form>\n</template>\n","import type { GenericObject } from 'vee-validate';\nimport type { Metadata } from '@/examples/TestFormTemplate.vue';\n\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport { defineComponent, h, markRaw } from 'vue';\nimport TestForm from '@/examples/TestForm.vue';\n\nexport const defaultTestCase = createTestCase([{\n name: 'text',\n type: 'text',\n fieldOptions: { label: 'Text Input' },\n path: 'with.custom.structure',\n restriction: { maxLength: 10 },\n}]);\n\nexport const arrayTestCase = createTestCase([{\n fieldOptions: { label: 'Array Fields' },\n type: 'heading',\n children: [\n { fieldOptions: { label: 'Optional field (max 3)' }, minOccurs: 0, maxOccurs: 3 },\n { fieldOptions: { label: 'Required field (max 3)' }, maxOccurs: 3 },\n { fieldOptions: { label: '2 Fields required' }, minOccurs: 2, maxOccurs: 4 },\n { fieldOptions: { label: 'Section (2 sections required)' }, type: 'heading', minOccurs: 2, maxOccurs: 4, fullWidth: true, children: [\n { fieldOptions: { label: 'Nested field 1' } },\n { fieldOptions: { label: 'Required Nested field 2' }, type: 'select', options: [\n { key: 'option1', value: 'Option 1' },\n { key: 'option2', value: 'Option 2' },\n { key: 'option3', value: 'Option 3' },\n ] },\n { fieldOptions: { label: 'Nested field 3' }, type: 'checkbox' },\n ] },\n ],\n}]);\n\nexport const groupTestCase = createTestCase([{\n fieldOptions: { label: 'Grouped Fields' },\n type: 'heading',\n children: [\n { fieldOptions: { label: 'Required group' }, type: 'group', children: [\n { fieldOptions: { label: 'Required Nested field 1' }, fullWidth: true },\n { fieldOptions: { label: 'Required Nested field 2' }, fullWidth: true },\n ] },\n { fieldOptions: { label: 'Optional group' }, type: 'group', minOccurs: 0, description: `The group is optional, therefore the children will only be required once 1 value is filled in.\n \nYou can test it by filling in one of the fields.`, children: [\n { fieldOptions: { label: 'Required Nested field 1' }, fullWidth: true },\n { fieldOptions: { label: 'Required Nested field 2' }, fullWidth: true },\n ] },\n ],\n}, {\n fieldOptions: { label: 'Grouped Array Fields' },\n type: 'heading',\n children: [\n { fieldOptions: { label: 'Required group' }, type: 'group', maxOccurs: 5, fullWidth: true, children: [\n { fieldOptions: { label: 'Required Nested field 1' } },\n { fieldOptions: { label: 'Required Nested field 2' } },\n ] },\n { fieldOptions: { label: 'Optional group' }, type: 'group', minOccurs: 0, maxOccurs: 5, fullWidth: true, children: [\n { fieldOptions: { label: 'Required Nested field 1' } },\n { fieldOptions: { label: 'Required Nested field 2' } },\n ] },\n ],\n}]);\n\nexport const choiceTestCase = createTestCase([\n {\n fieldOptions: { label: 'Choice Fields (minOccurs 1, maxOccurs 1)' },\n type: 'heading',\n children: [\n { fieldOptions: { label: 'Simple Choice Field' }, fullWidth: true, description: `In a choice field, only 1 of the fields can be filled in.`, choice: [\n { fieldOptions: { label: 'Nested Field 1' } },\n { fieldOptions: { label: 'Nested Field 2' } },\n ] },\n ],\n },\n {\n fieldOptions: { label: 'Choice Grouped Fields (minOccurs 1, maxOccurs 3)' },\n type: 'heading',\n children: [\n { fieldOptions: { label: 'Array Choice Field' }, type: 'group', maxOccurs: 3, fullWidth: true, description: `In a choice field, only 1 of the fields can be filled in.`, choice: [\n { fieldOptions: { label: 'Nested Field 1' }, type: 'group', children: [\n { fieldOptions: { label: 'Nested Child Field 1' }, fullWidth: true },\n { fieldOptions: { label: 'Nested Child Field 2' }, fullWidth: true },\n ] },\n { fieldOptions: { label: 'Nested Field 2' }, type: 'group', children: [\n { fieldOptions: { label: 'Nested Child Field 1' }, fullWidth: true },\n { fieldOptions: { label: 'Nested Child Field 2' }, fullWidth: true },\n ] },\n ] },\n ],\n },\n {\n fieldOptions: { label: 'Choice Array Fields (minOccurs 1, maxOccurs 3)' },\n type: 'heading',\n children: [\n { fieldOptions: { label: 'Array Choice Field' }, type: 'group', maxOccurs: 3, fullWidth: true, description: `In a choice field, only 1 of the fields can be filled in.`, choice: [\n { fieldOptions: { label: 'Nested Field 1' }, maxOccurs: 3 },\n { fieldOptions: { label: 'Nested Field 2' }, maxOccurs: 3 },\n ] },\n ],\n },\n]);\n\nexport const childFieldsTestCase = createTestCase([\n {\n fieldOptions: { label: 'Personal Info' },\n type: 'heading',\n name: 'person',\n description: 'Only showing the fields that have a value. Click edit to change.',\n fullWidth: true,\n children: [\n { name: 'firstName', fieldOptions: { label: 'First Name' } },\n { name: 'lastName', fieldOptions: { label: 'Last Name' } },\n { name: 'email', fieldOptions: { label: 'Email' } },\n ],\n },\n {\n fieldOptions: { label: 'Address' },\n type: 'heading',\n name: 'address',\n fullWidth: true,\n children: [\n { name: 'street', fieldOptions: { label: 'Street' }, minOccurs: 0 },\n { name: 'city', fieldOptions: { label: 'City' }, minOccurs: 0 },\n { name: 'country', fieldOptions: { label: 'Country' }, minOccurs: 0 },\n ],\n },\n], undefined, {\n initialEdit: false,\n hideFieldsWithoutValue: true,\n initialValues: {\n person: {\n firstName: 'Jack',\n lastName: 'Smit',\n },\n },\n});\n\nexport const individualTestCase = createTestCase(\n [{\n name: 'items',\n type: 'text',\n fieldOptions: { label: 'Items' },\n maxOccurs: 3,\n attributes: [{ name: 'lang', type: 'text', minOccurs: 0 }],\n }],\n {\n // validateOnValueUpdate: false,\n // validateOnValueUpdateAfterSubmit: false,\n // validateWhenInError: true,\n // validateOnBlur: true,\n },\n);\n\nexport function createTestCase(\n metadata: Metadata[],\n settings?: DynamicFormSettings,\n testCaseConfig: {\n initialEdit?: boolean\n hideFieldsWithoutValue?: boolean\n initialValues?: GenericObject\n } = {},\n) {\n return markRaw(defineComponent({\n render: () => h(TestForm, { ...testCaseConfig, metadata, settings, showDebugState: true }),\n }));\n}\n"],"names":["mapEachMetadataItem","metadata","callbackFunc","x","_createElementBlock","color","$emit","icon","_openBlock","_hoisted_1","_cache","_createElementVNode","_hoisted_2","defineMetadata","_createBlock","DynamicFormTemplate","_unref","fieldMetadata","errorMessage","label","disabled","canAddItems","addItem","canRemoveItems","removeItem","slotProps","_normalizeClass","_createTextVNode","_toDisplayString","IconButton","_hoisted_3","_renderSlot","_ctx","_withCtx","required","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_14","_createVNode","_hoisted_15","_hoisted_16","_Fragment","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","value","handleBlur","handleChange","optionKey","optionValue","_hoisted_26","$event","_hoisted_28","_vModelSelect","_vModelCheckbox","_vModelText","values","handleSubmit","errors","meta","useDynamicForm","__props","manualValues","ref","editMode","isSubmitted","metadataWithEdit","computed","item","thisField","fieldValue","checkTreeHasValue","_fieldValue","childFields","c","settings","submit","e","_values","_errors","_renderList","error","key","DynamicForm","TestFormTemplate","showDebugState","defaultTestCase","createTestCase","arrayTestCase","groupTestCase","choiceTestCase","childFieldsTestCase","individualTestCase","testCaseConfig","markRaw","defineComponent","h","TestForm"],"mappings":"kJAUO,SAASA,EAIdC,EACAC,EACuD,CACvD,MAAI,CAACD,GAAY,CAACC,IAGlBD,EAAWC,IAAe,CAAE,GAAGD,EAAU,EACzCA,EAAS,SAAWA,GAAU,UAAU,OAASD,EAAoBG,EAAGD,CAAY,CAAC,EACrFD,EAAS,OAASA,GAAU,QAAQ,OAASD,EAAoBG,EAAGD,CAAY,CAAC,GAC1ED,CACT,0ZCREG,EAAAA,mBAeS,SAAA,CAdP,KAAK,SACL,wBAAM,2GAA0G,iCAC/DC,EAAAA,QAAK,qCAAkDA,EAAAA,QAAK,KAAA,IAI5G,uBAAOC,EAAAA,MAAK,OAAA,EAAA,GAEFC,EAAAA,OAAI,QAAfC,EAAAA,UAAA,EAAAJ,EAAAA,mBAEM,MAFNK,EAEMC,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAA,CADJC,EAAAA,mBAAkF,OAAA,CAA5E,iBAAe,QAAQ,kBAAgB,QAAQ,EAAE,wBAAA,2CAE9CJ,EAAAA,OAAI,SAAfC,EAAAA,UAAA,EAAAJ,EAAAA,mBAEM,MAFNQ,EAEMF,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAA,CADJC,EAAAA,mBAAoE,OAAA,CAA9D,iBAAe,QAAQ,kBAAgB,QAAQ,EAAE,UAAA,stCCrB7D,MAAMV,EAAWY,EAAAA,eAAA,8BAkCfC,EAAAA,YAwMsBC,EAAAA,YAAA,CAxMA,yBAAwBC,EAAAA,MAAAf,CAAA,GAAQ,CACzC,kBACT,CAeM,CAhBc,cAAAgB,EAAa,aAAA,CAAkB,aAAAC,EAAc,MAAAC,CAAA,EAAS,SAAAC,EAAU,YAAAC,EAAa,QAAAC,EAAS,eAAAC,EAAgB,WAAAC,EAAY,UAAAC,KAAS,CACnIR,EAAc,kDAA1Bb,EAAAA,mBAeM,MAAA,OAf4B,MAAKsB,EAAAA,eAAA,CAAC,OAAM,CAAA,gBAA4BT,EAAc,UAAS,CAAA,CAAA,GACrFE,iBAAVf,EAAAA,mBAIK,KAAA,OAJY,wBAAM,iDAAgD,CAAA,gBAA4Ba,EAAc,UAAYG,EAAQ,CAAA,CAAA,GAChIO,EAAAA,gBAAAC,EAAAA,gBAAAT,CAAK,EAAG,IACX,CAAA,EAAkBE,iBAAlBP,EAAAA,YAA8He,EAAA,OAA/F,KAAK,OAAO,SAAS,KAAM,cAAW,GAAKZ,EAAc,IAAI,cAAgB,QAAOK,CAAA,iEACjGC,iBAAlBT,EAAAA,YAAoJe,EAAA,OAAlH,KAAK,QAAQ,SAAS,KAAK,MAAM,MAAO,cAAW,GAAKZ,EAAc,IAAI,iBAAmB,QAAOO,CAAA,kGAExIb,EAAAA,mBAA8E,MAA9EF,EAA8EmB,EAAAA,gBAAlCX,EAAc,WAAW,EAAA,CAAA,EAE7DC,EAAa,qBADrBd,EAAAA,mBAIgC,OAAA,OAF9B,MAAM,uBACL,cAAW,GAAKa,EAAc,IAAI,gBAAA,EACjCW,EAAAA,gBAAAV,EAAa,KAAK,EAAA,EAAAN,CAAA,+BACtBD,EAAAA,mBAEM,MAFNmB,EAEM,CADJC,aAA6CC,EAAA,OAAA,UAAA,CAAtC,OAAQP,GAAW,OAAK,GAAA,CAAA,YAK1B,0BAET,IAAQ,CAARM,aAAQC,EAAA,OAAA,SAAA,CAAA,GAGC,iBAAcC,EAAAA,QACvB,CAaM,CAdqB,cAAAhB,EAAa,aAAA,CAAkB,aAAAC,EAAc,MAAAC,GAAS,SAAAC,EAAU,SAAAc,EAAU,UAAAT,KAAS,CAClGR,EAAc,kDAA1Bb,EAAAA,mBAaM,MAAA,OAb4B,MAAKsB,EAAAA,eAAA,CAAC,sBAAqB,CAAA,gBAA4BT,EAAc,UAAS,CAAA,CAAA,GAC9GN,EAAAA,mBAEO,OAAA,CAFD,MAAKe,EAAAA,eAAA,CAAC,0BAAyB,CAAA,gBAA4BN,yDAAoEc,EAAQ,CAAA,CAAA,oBACxIf,CAAK,EAAA,CAAA,EAEVR,EAAAA,mBAEM,MAFNwB,EAEM,CADJJ,aAAwEC,EAAA,OAAA,UAAA,CAAjE,OAAQP,GAAW,OAAK,GAAA,EAAa,iBAAoB,EAAA,KAElEd,EAAAA,mBAA8E,MAA9EyB,EAA8ER,EAAAA,gBAAlCX,EAAc,WAAW,EAAA,CAAA,EAE7DC,EAAa,qBADrBd,EAAAA,mBAIgC,OAAA,OAF9B,MAAM,uBACL,cAAW,GAAKa,EAAc,IAAI,gBAAA,EACjCW,EAAAA,gBAAAV,EAAa,KAAK,EAAA,EAAAmB,CAAA,sCAIf,gBAAaJ,EAAAA,QACtB,CAaM,CAdoB,cAAAhB,gBAA+B,aAAAC,EAAc,MAAAC,CAAA,EAAS,SAAAC,EAAU,SAAAc,EAAU,YAAAb,EAAa,QAAAC,KAAO,CAC5GL,EAAc,kDAA1Bb,EAAAA,mBAaM,MAAA,OAb4B,MAAKsB,EAAAA,eAAA,CAAC,sBAAqB,CAAA,gBAA4BT,EAAc,UAAS,CAAA,CAAA,GAC9GN,EAAAA,mBAIQ,QAAA,CAJA,IAAG,GAAKM,EAAc,IAAI,MAAQ,yCAA0BA,EAAc,UAAYG,CAAA,EAAkB,yBAAyB,CAAA,CAAA,GACpIO,EAAAA,gBAAAC,EAAAA,gBAAAT,CAAK,EAAG,IACX,CAAA,EAAYe,iBAAZ9B,EAAAA,mBAA2D,OAA3DkC,EAAmD,GAAC,+BAClCjB,iBAAlBP,EAAAA,YAA8He,EAAA,OAA/F,KAAK,OAAO,SAAS,KAAM,cAAW,GAAKZ,EAAc,IAAI,cAAgB,QAAOK,CAAA,wEAErHS,EAAAA,WAA2BC,EAAA,OAAA,UAAA,CAApB,UAAY,GAAI,EACvBrB,EAAAA,mBAA8E,MAA9E4B,EAA8EX,EAAAA,gBAAlCX,EAAc,WAAW,EAAA,CAAA,EAE7DC,EAAa,qBADrBd,EAAAA,mBAIgC,OAAA,OAF9B,MAAM,uBACL,cAAW,GAAKa,EAAc,IAAI,gBAAA,EACjCW,EAAAA,gBAAAV,EAAa,KAAK,EAAA,EAAAsB,CAAA,sCAIf,kBACT,CAiBM,CAlBc,cAAAvB,EAAa,aAAA,CAAkB,aAAAC,EAAc,MAAAC,CAAA,EAAS,SAAAC,EAAU,SAAAc,EAAU,eAAAX,EAAgB,WAAAC,EAAY,UAAAC,KAAS,CACvHR,EAAc,kDAA1Bb,EAAAA,mBAiBM,MAAA,OAjB4B,MAAKsB,EAAAA,eAAA,CAAC,sBAAqB,CAAA,gBAA4BT,EAAc,UAAS,CAAA,CAAA,GAChGQ,GAAW,qDAAzBrB,EAAAA,mBAGQ,QAAA,OAH6B,IAAKa,EAAc,KAAO,MAAKS,EAAAA,eAAA,CAAA,gBAAqBT,EAAc,UAAYG,EAAQ,CAAA,GACtHO,EAAAA,gBAAAC,EAAAA,gBAAAT,CAAK,EAAG,IACX,CAAA,EAAYe,iBAAZ9B,EAAAA,mBAA2D,OAA3DqC,EAAmD,GAAC,uCAEtD9B,EAAAA,mBAKM,MALN+B,EAKM,CAJJ/B,EAAAA,mBAEM,MAFNgC,EAEM,CADJZ,aAAQC,EAAA,OAAA,SAAA,CAAA,GAEVY,EAAAA,YAAsKf,EAAA,CAAzJ,mCAAqBN,EAAc,EAAI,KAAK,QAAQ,SAAS,KAAK,MAAM,MAAO,cAAW,GAAKN,EAAc,IAAI,iBAAmB,QAAOO,CAAA,8CAE1Jb,EAAAA,mBAA8E,MAA9EkC,EAA8EjB,EAAAA,gBAAlCX,EAAc,WAAW,EAAA,CAAA,EAE7DC,EAAa,qBADrBd,EAAAA,mBAIgC,OAAA,OAF9B,MAAM,uBACL,cAAW,GAAKa,EAAc,IAAI,gBAAA,EACjCW,EAAAA,gBAAAV,EAAa,KAAK,EAAA,EAAA4B,CAAA,oCAExBf,aAA0BC,EAAA,OAAA,YAAA,CAAA,GAGjB,wBACT,CAAwC,CADhB,cAAAf,EAAa,aAAA,CAAkB,aAAAC,EAAc,MAAAC,CAAA,EAAS,SAAAC,EAAU,SAAAc,EAAU,YAAAb,EAAa,QAAAC,EAAS,UAAAG,KAAS,CACjHR,EAAc,sBAA9Bb,EAAAA,mBAAwC2C,EAAAA,SAAA,CAAA,IAAA,CAAA,EAAA,CAAA,EAAA,EAAA,GAExBtB,GAAW,gCAA3BrB,EAAAA,mBAeM,MAAA,OAfwC,MAAKsB,EAAAA,eAAA,CAAA,gBAAqBT,EAAc,UAAS,CAAA,GAC7FN,EAAAA,mBAIO,OAAA,CAJD,wBAAM,+BAA8B,CAAA,gBAA4BM,EAAc,UAAYG,EAAQ,CAAA,CAAA,GACnGO,EAAAA,gBAAAC,EAAAA,gBAAAT,CAAK,EAAG,IACX,CAAA,EAAYe,iBAAZ9B,EAAAA,mBAA2D,OAA3D4C,EAAmD,GAAC,+BAClC3B,iBAAlBP,EAAAA,YAA8He,EAAA,OAA/F,KAAK,OAAO,SAAS,KAAM,cAAW,GAAKZ,EAAc,IAAI,cAAgB,QAAOK,CAAA,qEAErHX,EAAAA,mBAEM,MAFNsC,EAEM,CADJlB,aAA6CC,EAAA,OAAA,UAAA,CAAtC,OAAQP,GAAW,OAAK,GAAA,CAAA,KAEjCd,EAAAA,mBAA8E,MAA9EuC,EAA8EtB,EAAAA,gBAAlCX,EAAc,WAAW,EAAA,CAAA,EAE7DC,EAAa,qBADrBd,EAAAA,mBAIgC,OAAA,OAF9B,MAAM,uBACL,cAAW,GAAKa,EAAc,IAAI,gBAAA,EACjCW,EAAAA,gBAAAV,EAAa,KAAK,EAAA,EAAAiC,CAAA,oCAGxBpB,EAAAA,WAAeC,EAAA,OAAA,UAAA,CAAA,IAAA,CAAA,CAAA,CAAA,GAGN,MAAKC,EAAAA,QAEd,CAgBM,CAlBY,cAAAhB,gBAA+B,aAAAC,EAAc,MAAAC,CAAA,EAAS,SAAAC,EAAU,SAAAc,EAAU,YAAAb,EAAa,eAAAE,EAAgB,QAAAD,EAAS,WAAAE,EAAY,UAAAC,KAAS,CAE3IR,EAAc,kDAA1Bb,EAAAA,mBAgBM,MAAA,OAhB6B,MAAKsB,EAAAA,eAAA,CAAA,gBAAqBT,EAAc,UAAS,CAAA,GACrEQ,GAAW,qDAAxBrB,EAAAA,mBAKO,OAAA,OAL4B,wBAAM,+BAA8B,CAAA,gBAA4Ba,EAAc,UAAYG,EAAQ,CAAA,CAAA,GAChIO,EAAAA,gBAAAC,EAAAA,gBAAAT,CAAK,EAAG,IACX,CAAA,EAAYe,iBAAZ9B,EAAAA,mBAA2D,OAA3DgD,EAAmD,GAAC,+BAClC/B,iBAAlBP,EAAAA,YAA8He,EAAA,OAA/F,KAAK,OAAO,SAAS,KAAM,cAAW,GAAKZ,EAAc,IAAI,cAAgB,QAAOK,CAAA,iEACjGC,iBAAlBT,EAAAA,YAAoJe,EAAA,OAAlH,KAAK,QAAQ,SAAS,KAAM,cAAW,GAAKZ,EAAc,IAAI,iBAAkB,MAAM,MAAO,QAAOO,CAAA,sEAExIb,EAAAA,mBAEM,MAFN0C,EAEM,CADJtB,aAA6CC,EAAA,OAAA,UAAA,CAAtC,OAAQP,GAAW,OAAK,GAAA,CAAA,KAEjCd,EAAAA,mBAA8E,MAA9E2C,EAA8E1B,EAAAA,gBAAlCX,EAAc,WAAW,EAAA,CAAA,EAE7DC,EAAa,qBADrBd,EAAAA,mBAIgC,OAAA,OAF9B,MAAM,uBACL,cAAW,GAAKa,EAAc,IAAI,gBAAA,EACjCW,EAAAA,gBAAAV,EAAa,KAAK,EAAA,EAAAqC,CAAA,oCAExBxB,aAA0BC,EAAA,OAAA,YAAA,CAAA,GAGjB,eAAYC,EAAAA,QACrB,CAWS,CAZgB,cAAAhB,EAAa,aAAA,CAAkB,MAAAuC,EAAO,WAAAC,EAAY,aAAAC,GAAgB,SAAAtC,KAAQ,CACnGT,EAAAA,mBAWS,SAAA,CAVN,GAAIM,EAAc,KAClB,MAAOuC,EAAM,MACb,SAAUvC,EAAc,UAAYG,EACrC,MAAM,8DACL,SAAQsC,EACR,OAAMD,CAAA,IAEPjD,EAAAA,UAAA,EAAA,EAAAJ,EAAAA,mBAES2C,EAAAA,2BAFgD9B,EAAc,QAAO,CAAA,CAAA,IAAxD0C,QAAkBC,oBAAxCxD,EAAAA,mBAES,SAAA,CAFwE,IAAKuD,EAAY,MAAOA,CAAA,oBACpGC,CAAW,EAAA,EAAAC,CAAA,mBAKT,4BAAyB5B,EAAAA,QAClC,CAUS,CAX6B,cAAAhB,gBAA+B,MAAAuC,EAAO,WAAAC,GAAc,SAAArC,KAAQ,kBAClGT,EAAAA,mBAUS,SAAA,CATN,GAAIM,EAAc,KACV,sBAAA6C,GAAAN,EAAM,MAAKM,EACnB,SAAU7C,EAAc,UAAYG,EACrC,MAAM,8DACL,OAAMqC,CAAA,IAEPjD,EAAAA,UAAA,EAAA,EAAAJ,EAAAA,mBAES2C,EAAAA,2BAFgD9B,EAAc,QAAO,CAAA,CAAA,IAAxD0C,QAAkBC,oBAAxCxD,EAAAA,mBAES,SAAA,CAFwE,IAAKuD,EAAY,MAAOA,CAAA,oBACpGC,CAAW,EAAA,EAAAG,CAAA,kBANP,CAAAC,EAAAA,aAAAR,EAAM,KAAK,CAAA,KAWb,iBAAcvB,EAAAA,QACvB,CAQC,CAT0B,cAAAhB,EAAa,aAAA,CAAkB,MAAAuC,EAAO,WAAAC,EAAY,aAAAC,GAAgB,SAAAtC,KAAQ,CACrGT,EAAAA,mBAQC,QAAA,CAPE,GAAIM,EAAc,KAClB,QAASuC,EAAM,MACf,SAAUvC,EAAc,UAAYG,EACrC,KAAK,WACL,MAAM,8DACL,YAAQsC,EAAcI,EAAO,OAA4B,OAAO,EAChE,OAAML,CAAA,eAIA,8BAA2BxB,EAAAA,QACpC,CAOC,CARuC,cAAAhB,gBAA+B,MAAAuC,EAAO,WAAAC,GAAc,SAAArC,KAAQ,kBACpGT,EAAAA,mBAOC,QAAA,CANE,GAAIM,EAAc,KACV,sBAAA6C,GAAAN,EAAM,MAAKM,EACnB,SAAU7C,EAAc,UAAYG,EACrC,KAAK,WACL,MAAM,8DACL,OAAMqC,CAAA,eAJE,CAAAQ,EAAAA,eAAAT,EAAM,KAAK,CAAA,KAQb,0BAAuBvB,EAAAA,QAChC,CAOC,CARmC,cAAAhB,gBAA+B,MAAAuC,EAAO,WAAAC,GAAc,SAAArC,KAAQ,kBAChGT,EAAAA,mBAOC,QAAA,CANE,GAAIM,EAAc,KACV,sBAAA6C,GAAAN,EAAM,MAAKM,EACnB,SAAU7C,EAAc,UAAYG,EACrC,KAAK,OACL,MAAM,8DACL,OAAMqC,CAAA,eAJE,CAAAS,EAAAA,WAAAV,EAAM,KAAK,CAAA,KAQb,gBAAavB,EAAAA,QACtB,CAQC,CATyB,cAAAhB,EAAa,aAAA,CAAkB,MAAAuC,EAAO,WAAAC,EAAY,aAAAC,GAAgB,SAAAtC,KAAQ,CACpGT,EAAAA,mBAQC,QAAA,CAPE,GAAIM,EAAc,KAClB,MAAOuC,EAAM,MACb,SAAUvC,EAAc,UAAYG,EACrC,KAAK,OACL,MAAM,8DACL,QAAOsC,EACP,OAAMD,CAAA,4mBCxNf,KAAM,CAAE,OAAAU,EAAQ,aAAAC,EAAc,OAAAC,EAAQ,KAAAC,CAAA,EAASC,EAAAA,eAAe,CAC5D,cAAYC,EAAA,aAAA,CACb,EACKC,EAAeC,EAAAA,IAAA,EACfC,EAAWD,EAAAA,IAAIF,EAAA,WAAW,EAC1BI,EAAcF,EAAAA,IAAI,EAAK,EAGvBG,EAAmBC,EAAAA,SAAS,IAAMN,EAAA,UAAU,IAAIrE,GAAKH,EAAoBG,EAAI4E,IACjFA,EAAK,cAAgBA,EAAK,eAAiB,CAAA,EAG3CA,EAAK,cAAc,KAAMC,GAAc,CAChCL,EAAS,QACZK,EAAU,SAAW,GACzB,CAAC,EAEGR,EAAA,yBAEFO,EAAK,cAAc,KAAK,CAACC,EAAWC,IAAe,CAC7C,CAACN,EAAS,OAAS,CAACO,EAAAA,kBAAkBD,EAAW,KAAK,IACxDD,EAAU,OAAS,GACvB,CAAC,EAGDD,EAAK,cAAc,KAAK,CAACC,EAAWG,EAAaC,IAAgB,CAC3D,CAACT,EAAS,OAASS,EAAY,MAAM,OAAS,GAAKA,EAAY,MAAM,MAAMC,GAAKA,EAAE,MAAM,IAC1FL,EAAU,OAAS,GACvB,CAAC,GAGID,EACR,CAAC,CAAC,EAEGO,EAAWR,EAAAA,SAAS,KAAO,CAC/B,UAAW,GACX,SAAU,CACR,SAAU,sBACV,UAAW,gCACX,gBAAiB,qEACjB,UAAW,4CACX,UAAW,4CACX,OAAQ,8CACR,QAAS,8CACT,aAAc,iCACd,aAAc,gCACd,aAAc,qCACd,aAAc,kCACd,YAAa,4CACb,WAAY,qDACZ,eAAgB,qDAChB,YAAa,wDAAA,EAEf,GAAIN,EAAA,UAAa,CAAA,CAAC,EAClB,EAEF,SAASe,EAAOC,EAAW,CACzBpB,EACGqB,GAAY,CACXb,EAAY,MAAQ,GACpBD,EAAS,MAAQ,EACnB,EACA,CAAC,CAAE,OAAQe,KAAc,CACvBd,EAAY,MAAQ,EACtB,CAAA,EACAY,CAAC,CACL,6BAIEpF,EAAAA,mBAqCO,OAAA,CArCA,yBAAgBmF,EAAM,CAAA,SAAA,CAAA,CAAA,GAC3B5E,EAAAA,mBAUM,MAVNF,GAUM,CATWkE,EAAA,iDAAfvE,EAAAA,mBAES,SAAA,OAFgB,KAAK,SAAS,MAAM,+DAA+D,cAAY,SAAU,uBAAOuE,EAAA,MAAQ,GAAA,EAAS,QAE1J,GACcA,EAAA,qBAAdvE,qBAES,SAFTQ,GAAgI,UAEhI,+BACc+D,EAAA,qBAAdvE,EAAAA,mBAES,SAAA,OAFe,KAAK,SAAS,MAAM,+DAA+D,cAAY,SAAU,uBAAOuE,EAAA,MAAQ,GAAA,EAAU,UAE1J,iCAES,OAAO,OAAO3D,QAAAqD,CAAA,CAAM,EAAE,QAAjC7D,EAAAA,YAAAJ,EAAAA,mBAOM,MAPN0B,GAOM,+BAPoF,YAExF,EAAA,GAAAnB,EAAAA,mBAIK,KAAA,KAAA,EAHHH,EAAAA,UAAA,EAAA,EAAAJ,EAAAA,mBAEK2C,EAAAA,SAAA,KAAA4C,aAFsB3E,EAAAA,MAAAqD,CAAA,EAAM,CAArBuB,EAAOC,mBAAnBzF,EAAAA,mBAEK,KAAA,CAF+B,IAAAyF,GAAQ,CAC1ClF,EAAAA,mBAAuB,OAAA,CAAjB,UAAQiF,GAAK,KAAA,EAAAzD,EAAA,CAAA,4CAIzBS,EAAAA,YAKEkD,EAAAA,UAAA,CAJC,SAAUC,EACV,SAAUlB,EAAA,MACV,SAAAS,EAAA,MACA,sBAAkB5E,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAoD,GAAEW,EAAA,MAAeX,EAAA,kCAE1Bc,EAAA,OAAZpE,EAAAA,UAAA,EAAAJ,EAAAA,mBAAqD,OAArDgC,EAAqD,+BAC1C4D,EAAAA,gBAAXxF,YAAA,EAAAJ,qBASM,MATNiC,GAAoF,YAC/ET,EAAAA,gBAAGZ,EAAAA,SAAK,KAAK,EAAG;AAAA,6BACbA,QAAAsD,CAAA,EAAK,OAAO,EAAG;AAAA,6BACftD,EAAAA,MAAAsD,CAAA,EAAK,OAAO,EAAG;AAAA,SACpB1C,EAAAA,gBAAGZ,EAAAA,MAAAsD,CAAA,EAAK,KAAK,EAAG;AAAA,aACZ1C,EAAAA,gBAAGgD,EAAA,KAAW,EAAG;AAAA;AAAA;AAAA,oBAGzB,KAAK,UAAU5D,EAAAA,MAAAmD,CAAA,WAAmB;AAAA,MACjC,CAAA,wCC1HS8B,GAAkBC,EAAe,CAAC,CAC7C,KAAM,OACN,KAAM,OACN,aAAc,CAAE,MAAO,YAAA,EACvB,KAAM,wBACN,YAAa,CAAE,UAAW,EAAA,CAC5B,CAAC,CAAC,EAEWC,GAAgBD,EAAe,CAAC,CAC3C,aAAc,CAAE,MAAO,cAAA,EACvB,KAAM,UACN,SAAU,CACR,CAAE,aAAc,CAAE,MAAO,0BAA4B,UAAW,EAAG,UAAW,CAAA,EAC9E,CAAE,aAAc,CAAE,MAAO,wBAAA,EAA4B,UAAW,CAAA,EAChE,CAAE,aAAc,CAAE,MAAO,qBAAuB,UAAW,EAAG,UAAW,CAAA,EACzE,CAAE,aAAc,CAAE,MAAO,iCAAmC,KAAM,UAAW,UAAW,EAAG,UAAW,EAAG,UAAW,GAAM,SAAU,CAClI,CAAE,aAAc,CAAE,MAAO,iBAAiB,EAC1C,CAAE,aAAc,CAAE,MAAO,2BAA6B,KAAM,SAAU,QAAS,CAC7E,CAAE,IAAK,UAAW,MAAO,UAAA,EACzB,CAAE,IAAK,UAAW,MAAO,UAAA,EACzB,CAAE,IAAK,UAAW,MAAO,UAAA,CAAW,CACtC,EACA,CAAE,aAAc,CAAE,MAAO,gBAAA,EAAoB,KAAM,UAAA,CAAW,CAChE,CAAE,CAEN,CAAC,CAAC,EAEWE,GAAgBF,EAAe,CAAC,CAC3C,aAAc,CAAE,MAAO,gBAAA,EACvB,KAAM,UACN,SAAU,CACR,CAAE,aAAc,CAAE,MAAO,kBAAoB,KAAM,QAAS,SAAU,CACpE,CAAE,aAAc,CAAE,MAAO,yBAAA,EAA6B,UAAW,EAAA,EACjE,CAAE,aAAc,CAAE,MAAO,yBAAA,EAA6B,UAAW,EAAA,CAAK,CACxE,EACA,CAAE,aAAc,CAAE,MAAO,gBAAA,EAAoB,KAAM,QAAS,UAAW,EAAG,YAAa;AAAA;AAAA,kDAExC,SAAU,CACvD,CAAE,aAAc,CAAE,MAAO,yBAAA,EAA6B,UAAW,EAAA,EACjE,CAAE,aAAc,CAAE,MAAO,yBAAA,EAA6B,UAAW,EAAA,CAAK,CACxE,CAAE,CAEN,EAAG,CACD,aAAc,CAAE,MAAO,sBAAA,EACvB,KAAM,UACN,SAAU,CACR,CAAE,aAAc,CAAE,MAAO,gBAAA,EAAoB,KAAM,QAAS,UAAW,EAAG,UAAW,GAAM,SAAU,CACnG,CAAE,aAAc,CAAE,MAAO,0BAA0B,EACnD,CAAE,aAAc,CAAE,MAAO,0BAA0B,CAAE,CACvD,EACA,CAAE,aAAc,CAAE,MAAO,kBAAoB,KAAM,QAAS,UAAW,EAAG,UAAW,EAAG,UAAW,GAAM,SAAU,CACjH,CAAE,aAAc,CAAE,MAAO,0BAA0B,EACnD,CAAE,aAAc,CAAE,MAAO,0BAA0B,CAAE,CACvD,CAAE,CAEN,CAAC,CAAC,EAEWG,GAAiBH,EAAe,CAC3C,CACE,aAAc,CAAE,MAAO,0CAAA,EACvB,KAAM,UACN,SAAU,CACR,CAAE,aAAc,CAAE,MAAO,uBAAyB,UAAW,GAAM,YAAa,4DAA6D,OAAQ,CACnJ,CAAE,aAAc,CAAE,MAAO,iBAAiB,EAC1C,CAAE,aAAc,CAAE,MAAO,iBAAiB,CAAE,CAC9C,CAAE,CACJ,EAEF,CACE,aAAc,CAAE,MAAO,kDAAA,EACvB,KAAM,UACN,SAAU,CACR,CAAE,aAAc,CAAE,MAAO,sBAAwB,KAAM,QAAS,UAAW,EAAG,UAAW,GAAM,YAAa,4DAA6D,OAAQ,CAC/K,CAAE,aAAc,CAAE,MAAO,kBAAoB,KAAM,QAAS,SAAU,CACpE,CAAE,aAAc,CAAE,MAAO,sBAAA,EAA0B,UAAW,EAAA,EAC9D,CAAE,aAAc,CAAE,MAAO,sBAAA,EAA0B,UAAW,EAAA,CAAK,CACrE,EACA,CAAE,aAAc,CAAE,MAAO,kBAAoB,KAAM,QAAS,SAAU,CACpE,CAAE,aAAc,CAAE,MAAO,sBAAA,EAA0B,UAAW,EAAA,EAC9D,CAAE,aAAc,CAAE,MAAO,sBAAA,EAA0B,UAAW,EAAA,CAAK,CACrE,CAAE,CACJ,CAAE,CACJ,EAEF,CACE,aAAc,CAAE,MAAO,gDAAA,EACvB,KAAM,UACN,SAAU,CACR,CAAE,aAAc,CAAE,MAAO,sBAAwB,KAAM,QAAS,UAAW,EAAG,UAAW,GAAM,YAAa,4DAA6D,OAAQ,CAC/K,CAAE,aAAc,CAAE,MAAO,gBAAA,EAAoB,UAAW,CAAA,EACxD,CAAE,aAAc,CAAE,MAAO,gBAAA,EAAoB,UAAW,CAAA,CAAE,CAC5D,CAAE,CACJ,CAEJ,CAAC,EAEYI,GAAsBJ,EAAe,CAChD,CACE,aAAc,CAAE,MAAO,eAAA,EACvB,KAAM,UACN,KAAM,SACN,YAAa,mEACb,UAAW,GACX,SAAU,CACR,CAAE,KAAM,YAAa,aAAc,CAAE,MAAO,aAAa,EACzD,CAAE,KAAM,WAAY,aAAc,CAAE,MAAO,YAAY,EACvD,CAAE,KAAM,QAAS,aAAc,CAAE,MAAO,QAAQ,CAAE,CACpD,EAEF,CACE,aAAc,CAAE,MAAO,SAAA,EACvB,KAAM,UACN,KAAM,UACN,UAAW,GACX,SAAU,CACR,CAAE,KAAM,SAAU,aAAc,CAAE,MAAO,QAAA,EAAY,UAAW,CAAA,EAChE,CAAE,KAAM,OAAQ,aAAc,CAAE,MAAO,MAAA,EAAU,UAAW,CAAA,EAC5D,CAAE,KAAM,UAAW,aAAc,CAAE,MAAO,SAAA,EAAa,UAAW,CAAA,CAAE,CACtE,CAEJ,EAAG,OAAW,CACZ,YAAa,GACb,uBAAwB,GACxB,cAAe,CACb,OAAQ,CACN,UAAW,OACX,SAAU,MAAA,CACZ,CAEJ,CAAC,EAEYK,GAAqBL,EAChC,CAAC,CACC,KAAM,QACN,KAAM,OACN,aAAc,CAAE,MAAO,OAAA,EACvB,UAAW,EACX,WAAY,CAAC,CAAE,KAAM,OAAQ,KAAM,OAAQ,UAAW,CAAA,CAAG,CAAA,CAC1D,EACD,CAAA,CAMF,EAEO,SAASA,EACdjG,EACAqF,EACAkB,EAII,CAAA,EACJ,CACA,OAAOC,EAAAA,QAAQC,EAAAA,gBAAgB,CAC7B,OAAQ,IAAMC,IAAEC,GAAU,CAAE,GAAGJ,EAAgB,SAAAvG,EAAU,SAAAqF,EAAU,eAAgB,EAAA,CAAM,CAAA,CAC1F,CAAC,CACJ"}