@bach.software/vue-dynamic-form 0.5.0 → 0.6.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.
- package/dist/examples.cjs.js +6 -6
- package/dist/examples.cjs.js.map +1 -1
- package/dist/examples.es.js +1643 -280
- package/dist/examples.es.js.map +1 -1
- package/dist/mapEachMetadataItem-Cxfn86Z2.cjs +2 -0
- package/dist/mapEachMetadataItem-Cxfn86Z2.cjs.map +1 -0
- package/dist/mapEachMetadataItem-Dvf3R5jd.js +1159 -0
- package/dist/mapEachMetadataItem-Dvf3R5jd.js.map +1 -0
- package/dist/src/components/DynamicFormItemWizard.vue.d.ts +25 -0
- package/dist/src/components/DynamicFormTemplate.vue.d.ts +97 -4
- package/dist/src/components/__tests__/DynamicFormItem.unmount.logic.test.d.ts +1 -0
- package/dist/src/components/__tests__/DynamicFormItemArray.analytics.test.d.ts +1 -0
- package/dist/src/components/__tests__/DynamicFormItemArray.test-helpers.d.ts +9 -0
- package/dist/src/components/__tests__/DynamicFormItemChoice.analytics.test.d.ts +1 -0
- package/dist/src/components/__tests__/DynamicFormItemChoice.test-helpers.d.ts +100 -0
- package/dist/src/components/__tests__/DynamicFormItemWizard.analytics.test.d.ts +1 -0
- package/dist/src/components/__tests__/DynamicFormItemWizard.logic.test.d.ts +1 -0
- package/dist/src/components/__tests__/DynamicFormItemWizard.test-helpers.d.ts +24 -0
- package/dist/src/components/__tests__/DynamicFormItemWizard.validation.test.d.ts +1 -0
- package/dist/src/components/__tests__/DynamicFormTemplate.test.d.ts +1 -0
- package/dist/src/core/validation.d.ts +8 -2
- package/dist/src/examples/KeepValuesOnUnmountTestCase.vue.d.ts +2 -0
- package/dist/src/examples/TestForm.vue.d.ts +1 -0
- package/dist/src/examples/TestFormTemplate.vue.d.ts +48 -13
- package/dist/src/examples/__tests__/TestFormTemplate.testcases.d.ts +2317 -7
- package/dist/src/examples/index.d.ts +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/types/DynamicFormItemProps.d.ts +39 -2
- package/dist/src/types/DynamicFormSettings.d.ts +16 -0
- package/dist/src/types/FieldMetadata.d.ts +123 -1
- package/dist/src/utils/__tests__/deepCloneValue.test.d.ts +1 -0
- package/dist/src/utils/__tests__/mapEachMetadataItem.test.d.ts +1 -1
- package/dist/src/utils/deepCloneValue.d.ts +10 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/vue-dynamic-form.cjs.js +1 -1
- package/dist/vue-dynamic-form.es.js +28 -27
- package/package.json +6 -4
- package/dist/mapEachMetadataItem-B4xJvJDj.js +0 -732
- package/dist/mapEachMetadataItem-B4xJvJDj.js.map +0 -1
- package/dist/mapEachMetadataItem-CDDSsb0c.cjs +0 -6
- package/dist/mapEachMetadataItem-CDDSsb0c.cjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mapEachMetadataItem-CDDSsb0c.cjs","sources":["../src/core/useFieldArrayExtended.ts","../src/types/DynamicFormSettings.ts","../../../node_modules/.pnpm/@vee-validate+rules@4.15.1_vue@3.5.35_typescript@5.9.2_/node_modules/@vee-validate/rules/dist/vee-validate-rules.mjs","../src/utils/checkTreeHasValue.ts","../src/utils/resolveMessage.ts","../src/core/validation.ts","../src/utils/getFieldLabel.ts","../src/utils/createValidation.ts","../src/utils/normalizePath.ts","../src/utils/overridePath.ts","../src/utils/splitValidationFunctions.ts","../src/components/DynamicFormItemArray.vue","../src/components/DynamicFormItemChoice.vue","../src/utils/hashField.ts","../src/components/DynamicFormItem.vue","../src/components/DynamicForm.vue","../src/utils/camelize.ts","../src/components/DynamicFormTemplate.vue","../src/core/defineMetadata.ts","../src/core/useValidatePartialForm.ts","../src/core/useDynamicForm.ts","../src/utils/mapEachMetadataItem.ts"],"sourcesContent":["import type { MaybeRefOrGetter } from 'vue';\nimport { useFieldArray } from 'vee-validate';\nimport { computed } from 'vue';\n\n/**\n * Wraps vee-validate's `useFieldArray`, adding a `values` computed shorthand for\n * `fields.value.map(f => f.value)` so callers don't need to unwrap each keyed field object.\n */\nexport function useFieldArrayExtended(arrayPath: MaybeRefOrGetter<string>) {\n const { fields, ...originalFieldArray } = useFieldArray(arrayPath);\n const values = computed(() => fields.value.map(({ value }) => value));\n\n return {\n fields,\n values,\n ...originalFieldArray,\n };\n}\n","import type { ValidationMessage } from '@/types/ValidationMessage';\n\nexport const dynamicFormSettingsKey = Symbol('dynamicFormSettings');\n\nexport type DynamicFormSettings<\n ExtendedProperties extends object = object,\n> = {\n /**\n * Enables diagnostic data output via concealed DOM elements for reactivity testing\n */\n analytics?: boolean\n\n /**\n * In case of a complex type the value is stored in a value property, i.e. { value: 'the actual value' }\n * Use complexTypeValueProperty to change the property name, for example 'myValue' will result in { myValue: 'the actual value' }\n */\n complexTypeValueProperty?: string\n\n /**\n * When true, validates fields on every value change.\n * When false, only validates on submit.\n *\n * Defaults to true.\n */\n validateOnValueUpdate?: boolean\n\n /**\n * When true, validates fields on every value change after the first submit.\n * When false, listen to the validateOnValueUpdate.\n *\n * Defaults to false.\n */\n validateOnValueUpdateAfterSubmit?: boolean\n\n /**\n * When true, validates fields on blur.\n *\n * Defaults to false.\n */\n validateOnBlur?: boolean\n\n /**\n * When true, validates fields on every value change when the field has an error.\n *\n * Defaults to true (applied by DynamicForm).\n */\n validateWhenInError?: boolean\n\n /**\n * Use this setting to override the default text of the validation messages.\n *\n * Each message accepts either a `string` template or a `(ctx) => string` function.\n *\n * String templates support the following placeholders:\n * - `{field}` — the field label\n * - `{value}` — the current field value\n * - `{0}`, `{1}`, ... — rule params by position (e.g. `{0}` = the limit value)\n * - Named params where supported (e.g. `{min}`, `{max}`)\n *\n * Examples:\n * ```ts\n * required: 'The {field} field is required'\n * minLength: 'The {field} must be at least {0} characters'\n * minLength: (ctx) => `${ctx.field} is too short`\n * ```\n */\n messages?: {\n /** XSD: required. Available placeholders: `{field}` */\n required?: ValidationMessage\n /** XSD: minOccurs. Available placeholders: `{field}`, `{0}` or `{min}` (min number of filled items) */\n minOccurs?: ValidationMessage\n /** XSD: choiceMinOccurs. Available placeholders: `{field}`, `{0}` or `{min}` (min number of filled items) */\n choiceMinOccurs?: ValidationMessage\n /** XSD: minLength. Available placeholders: `{field}`, `{0}` or `{length}` (min length) */\n minLength?: ValidationMessage\n /** XSD: maxLength. Available placeholders: `{field}`, `{0}` or `{length}` (max length) */\n maxLength?: ValidationMessage\n /** XSD: length. Available placeholders: `{field}`, `{0}` or `{length}` (exact length) */\n length?: ValidationMessage\n /** XSD: pattern. Available placeholders: `{field}`, `{0}` or `{pattern}` (regex pattern) */\n pattern?: ValidationMessage\n /** XSD: minInclusive. Available placeholders: `{field}`, `{0}` or `{min}` (min value, inclusive) */\n minInclusive?: ValidationMessage\n /** XSD: maxInclusive. Available placeholders: `{field}`, `{0}` or `{max}` (max value, inclusive) */\n maxInclusive?: ValidationMessage\n /** XSD: minExclusive. Available placeholders: `{field}`, `{0}` or `{min}` (min value, exclusive) */\n minExclusive?: ValidationMessage\n /** XSD: maxExclusive. Available placeholders: `{field}`, `{0}` or `{max}` (max value, exclusive) */\n maxExclusive?: ValidationMessage\n /** XSD: enumeration. Available placeholders: `{field}` */\n enumeration?: ValidationMessage\n /** XSD: whiteSpace. Available placeholders: `{field}`, `{0}` or `{mode}` (preserve | replace | collapse) */\n whiteSpace?: ValidationMessage\n /** XSD: fractionDigits. Available placeholders: `{field}`, `{0}` or `{digits}` (max decimal places) */\n fractionDigits?: ValidationMessage\n /** XSD: totalDigits. Available placeholders: `{field}`, `{0}` or `{digits}` (max total digits) */\n totalDigits?: ValidationMessage\n }\n} & ExtendedProperties;\n","/**\n * vee-validate v4.15.1\n * (c) 2025 Abdelrahman Awad\n * @license MIT\n */\nimport 'vue';\nimport { validate, validateObject } from 'vee-validate';\n\n/* eslint-disable no-misleading-character-class */\n/**\n * Some Alpha Regex helpers.\n * https://github.com/chriso/validator.js/blob/master/src/lib/alpha.js\n */\nconst alpha = {\n en: /^[A-Z]*$/i,\n cs: /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]*$/i,\n da: /^[A-ZÆØÅ]*$/i,\n de: /^[A-ZÄÖÜß]*$/i,\n es: /^[A-ZÁÉÍÑÓÚÜ]*$/i,\n fr: /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]*$/i,\n it: /^[A-Z\\xC0-\\xFF]*$/i,\n lt: /^[A-ZĄČĘĖĮŠŲŪŽ]*$/i,\n nl: /^[A-ZÉËÏÓÖÜ]*$/i,\n hu: /^[A-ZÁÉÍÓÖŐÚÜŰ]*$/i,\n pl: /^[A-ZĄĆĘŚŁŃÓŻŹ]*$/i,\n pt: /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]*$/i,\n ru: /^[А-ЯЁ]*$/i,\n kz: /^[А-ЯЁ\\u04D8\\u04B0\\u0406\\u04A2\\u0492\\u04AE\\u049A\\u04E8\\u04BA]*$/i,\n sk: /^[A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ]*$/i,\n sr: /^[A-ZČĆŽŠĐ]*$/i,\n sv: /^[A-ZÅÄÖ]*$/i,\n tr: /^[A-ZÇĞİıÖŞÜ]*$/i,\n uk: /^[А-ЩЬЮЯЄІЇҐ]*$/i,\n ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]*$/,\n az: /^[A-ZÇƏĞİıÖŞÜ]*$/i,\n ug: /^[A-Zچۋېرتيۇڭوپھسداەىقكلزشغۈبنمژفگخجۆئ]*$/i,\n};\nconst alphaSpaces = {\n en: /^[A-Z\\s]*$/i,\n cs: /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ\\s]*$/i,\n da: /^[A-ZÆØÅ\\s]*$/i,\n de: /^[A-ZÄÖÜß\\s]*$/i,\n es: /^[A-ZÁÉÍÑÓÚÜ\\s]*$/i,\n fr: /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ\\s]*$/i,\n it: /^[A-Z\\xC0-\\xFF\\s]*$/i,\n lt: /^[A-ZĄČĘĖĮŠŲŪŽ\\s]*$/i,\n nl: /^[A-ZÉËÏÓÖÜ\\s]*$/i,\n hu: /^[A-ZÁÉÍÓÖŐÚÜŰ\\s]*$/i,\n pl: /^[A-ZĄĆĘŚŁŃÓŻŹ\\s]*$/i,\n pt: /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ\\s]*$/i,\n ru: /^[А-ЯЁ\\s]*$/i,\n kz: /^[А-ЯЁ\\u04D8\\u04B0\\u0406\\u04A2\\u0492\\u04AE\\u049A\\u04E8\\u04BA\\s]*$/i,\n sk: /^[A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ\\s]*$/i,\n sr: /^[A-ZČĆŽŠĐ\\s]*$/i,\n sv: /^[A-ZÅÄÖ\\s]*$/i,\n tr: /^[A-ZÇĞİıÖŞÜ\\s]*$/i,\n uk: /^[А-ЩЬЮЯЄІЇҐ\\s]*$/i,\n ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ\\s]*$/,\n az: /^[A-ZÇƏĞİıÖŞÜ\\s]*$/i,\n ug: /^[A-Zچۋېرتيۇڭوپھسداەىقكلزشغۈبنمژفگخجۆئ\\s]*$/i,\n};\nconst alphanumeric = {\n en: /^[0-9A-Z]*$/i,\n cs: /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]*$/i,\n da: /^[0-9A-ZÆØÅ]$/i,\n de: /^[0-9A-ZÄÖÜß]*$/i,\n es: /^[0-9A-ZÁÉÍÑÓÚÜ]*$/i,\n fr: /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]*$/i,\n it: /^[0-9A-Z\\xC0-\\xFF]*$/i,\n lt: /^[0-9A-ZĄČĘĖĮŠŲŪŽ]*$/i,\n hu: /^[0-9A-ZÁÉÍÓÖŐÚÜŰ]*$/i,\n nl: /^[0-9A-ZÉËÏÓÖÜ]*$/i,\n pl: /^[0-9A-ZĄĆĘŚŁŃÓŻŹ]*$/i,\n pt: /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]*$/i,\n ru: /^[0-9А-ЯЁ]*$/i,\n kz: /^[0-9А-ЯЁ\\u04D8\\u04B0\\u0406\\u04A2\\u0492\\u04AE\\u049A\\u04E8\\u04BA]*$/i,\n sk: /^[0-9A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ]*$/i,\n sr: /^[0-9A-ZČĆŽŠĐ]*$/i,\n sv: /^[0-9A-ZÅÄÖ]*$/i,\n tr: /^[0-9A-ZÇĞİıÖŞÜ]*$/i,\n uk: /^[0-9А-ЩЬЮЯЄІЇҐ]*$/i,\n ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]*$/,\n az: /^[0-9A-ZÇƏĞİıÖŞÜ]*$/i,\n ug: /^[0-9A-Zچۋېرتيۇڭوپھسداەىقكلزشغۈبنمژفگخجۆئ]*$/i,\n};\nconst alphaDash = {\n en: /^[0-9A-Z_-]*$/i,\n cs: /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ_-]*$/i,\n da: /^[0-9A-ZÆØÅ_-]*$/i,\n de: /^[0-9A-ZÄÖÜß_-]*$/i,\n es: /^[0-9A-ZÁÉÍÑÓÚÜ_-]*$/i,\n fr: /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ_-]*$/i,\n it: /^[0-9A-Z\\xC0-\\xFF_-]*$/i,\n lt: /^[0-9A-ZĄČĘĖĮŠŲŪŽ_-]*$/i,\n nl: /^[0-9A-ZÉËÏÓÖÜ_-]*$/i,\n hu: /^[0-9A-ZÁÉÍÓÖŐÚÜŰ_-]*$/i,\n pl: /^[0-9A-ZĄĆĘŚŁŃÓŻŹ_-]*$/i,\n pt: /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ_-]*$/i,\n ru: /^[0-9А-ЯЁ_-]*$/i,\n kz: /^[0-9А-ЯЁ\\u04D8\\u04B0\\u0406\\u04A2\\u0492\\u04AE\\u049A\\u04E8\\u04BA_-]*$/i,\n sk: /^[0-9A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ_-]*$/i,\n sr: /^[0-9A-ZČĆŽŠĐ_-]*$/i,\n sv: /^[0-9A-ZÅÄÖ_-]*$/i,\n tr: /^[0-9A-ZÇĞİıÖŞÜ_-]*$/i,\n uk: /^[0-9А-ЩЬЮЯЄІЇҐ_-]*$/i,\n ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ_-]*$/,\n az: /^[0-9A-ZÇƏĞİıÖŞÜ_-]*$/i,\n ug: /^[0-9A-Zچۋېرتيۇڭوپھسداەىقكلزشغۈبنمژفگخجۆئ_-]*$/i,\n};\nconst getLocale = (params) => {\n if (!params) {\n return undefined;\n }\n return Array.isArray(params) ? params[0] : params.locale;\n};\n\nfunction getSingleParam(params, paramName) {\n return Array.isArray(params) ? params[0] : params[paramName];\n}\nfunction isEmpty(value) {\n if (value === null || value === undefined || value === '') {\n return true;\n }\n if (Array.isArray(value) && value.length === 0) {\n return true;\n }\n return false;\n}\n\nconst alphaValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const locale = getLocale(params);\n if (Array.isArray(value)) {\n return value.every(val => alphaValidator(val, { locale }));\n }\n const valueAsString = String(value);\n // Match at least one locale.\n if (!locale) {\n return Object.keys(alpha).some(loc => alpha[loc].test(valueAsString));\n }\n return (alpha[locale] || alpha.en).test(valueAsString);\n};\n\nconst alphaDashValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const locale = getLocale(params);\n if (Array.isArray(value)) {\n return value.every(val => alphaDashValidator(val, { locale }));\n }\n const valueAsString = String(value);\n // Match at least one locale.\n if (!locale) {\n return Object.keys(alphaDash).some(loc => alphaDash[loc].test(valueAsString));\n }\n return (alphaDash[locale] || alphaDash.en).test(valueAsString);\n};\n\nconst alphaNumValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const locale = getLocale(params);\n if (Array.isArray(value)) {\n return value.every(val => alphaNumValidator(val, { locale }));\n }\n const valueAsString = String(value);\n // Match at least one locale.\n if (!locale) {\n return Object.keys(alphanumeric).some(loc => alphanumeric[loc].test(valueAsString));\n }\n return (alphanumeric[locale] || alphanumeric.en).test(valueAsString);\n};\n\nconst alphaSpacesValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const locale = getLocale(params);\n if (Array.isArray(value)) {\n return value.every(val => alphaSpacesValidator(val, { locale }));\n }\n const valueAsString = String(value);\n // Match at least one locale.\n if (!locale) {\n return Object.keys(alphaSpaces).some(loc => alphaSpaces[loc].test(valueAsString));\n }\n return (alphaSpaces[locale] || alphaSpaces.en).test(valueAsString);\n};\n\nfunction getParams$1(params) {\n if (Array.isArray(params)) {\n return { min: params[0], max: params[1] };\n }\n return params;\n}\nconst betweenValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const { min, max } = getParams$1(params);\n if (Array.isArray(value)) {\n return value.every(val => betweenValidator(val, { min, max }));\n }\n const valueAsNumber = Number(value);\n return Number(min) <= valueAsNumber && Number(max) >= valueAsNumber;\n};\n\nconst confirmedValidator = (value, params) => {\n const target = getSingleParam(params, 'target');\n return String(value) === String(target);\n};\n\nconst digitsValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const length = getSingleParam(params, 'length');\n if (Array.isArray(value)) {\n return value.every(val => digitsValidator(val, { length }));\n }\n const strVal = String(value);\n return /^[0-9]*$/.test(strVal) && strVal.length === Number(length);\n};\n\nconst validateImage = (file, width, height) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const URL = window.URL || window.webkitURL;\n return new Promise(resolve => {\n const image = new Image();\n image.onerror = () => resolve(false);\n image.onload = () => resolve(image.width === width && image.height === height);\n image.src = URL.createObjectURL(file);\n });\n};\nfunction getParams(params) {\n if (!params) {\n return { width: 0, height: 0 };\n }\n if (Array.isArray(params)) {\n return { width: Number(params[0]), height: Number(params[1]) };\n }\n return {\n width: Number(params.width),\n height: Number(params.height),\n };\n}\nconst dimensionsValidator = (files, params) => {\n if (isEmpty(files)) {\n return true;\n }\n const { width, height } = getParams(params);\n const list = [];\n const fileList = Array.isArray(files) ? files : [files];\n for (let i = 0; i < fileList.length; i++) {\n // if file is not an image, reject.\n if (!/\\.(jpg|svg|jpeg|png|bmp|gif)$/i.test(fileList[i].name)) {\n return Promise.resolve(false);\n }\n list.push(fileList[i]);\n }\n return Promise.all(list.map(file => validateImage(file, width, height))).then(values => {\n return values.every(v => v);\n });\n};\n\n/* eslint-disable no-useless-escape */\n// https://github.com/colinhacks/zod/blob/40e72f9eaf576985f876d1afc2dbc22f73abc1ba/src/types.ts#L595\nconst emailRE = /^(?!\\.)(?!.*\\.\\.)([A-Z0-9_'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i;\nconst emailValidator = (value) => {\n if (isEmpty(value)) {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(val => emailRE.test(String(val)));\n }\n return emailRE.test(String(value));\n};\n\nconst extValidator = (files, extensions) => {\n if (isEmpty(files)) {\n return true;\n }\n const regex = new RegExp(`\\\\.(${extensions.join('|')})$`, 'i');\n if (Array.isArray(files)) {\n return files.every(file => regex.test(file.name));\n }\n return regex.test(files.name);\n};\n\nconst imageValidator = (files) => {\n if (isEmpty(files)) {\n return true;\n }\n const regex = /\\.(jpg|svg|jpeg|png|bmp|gif|webp)$/i;\n if (Array.isArray(files)) {\n return files.every(file => regex.test(file.name));\n }\n return regex.test(files.name);\n};\n\nconst integerValidator = (value) => {\n if (isEmpty(value)) {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(val => /^-?[0-9]+$/.test(String(val)));\n }\n return /^-?[0-9]+$/.test(String(value));\n};\n\nconst isValidator = (value, params) => {\n const other = getSingleParam(params, 'other');\n return value === other;\n};\n\nconst isNotValidator = (value, params) => {\n const other = getSingleParam(params, 'other');\n return value !== other;\n};\n\nconst lengthValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n // Normalize the length value\n const length = getSingleParam(params, 'length');\n if (typeof value === 'number') {\n value = String(value);\n }\n if (!value.length) {\n value = Array.from(value);\n }\n return value.length === Number(length);\n};\n\nconst maxLengthValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const length = getSingleParam(params, 'length');\n if (Array.isArray(value)) {\n return value.every(val => maxLengthValidator(val, { length }));\n }\n return [...String(value)].length <= Number(length);\n};\n\nconst maxValueValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const max = getSingleParam(params, 'max');\n if (Array.isArray(value)) {\n return value.length > 0 && value.every(val => maxValueValidator(val, { max }));\n }\n return Number(value) <= Number(max);\n};\n\nconst ADDED_MIME_RE = /\\+(.+)?/;\nfunction buildRegExp(mime) {\n let strPattern = mime;\n if (ADDED_MIME_RE.test(mime)) {\n strPattern = mime.replace(ADDED_MIME_RE, '(\\\\+$1)?');\n }\n return new RegExp(strPattern.replace('*', '.+'), 'i');\n}\nconst mimesValidator = (files, mimes) => {\n if (isEmpty(files)) {\n return true;\n }\n if (!mimes) {\n mimes = [];\n }\n const patterns = mimes.map(buildRegExp);\n if (Array.isArray(files)) {\n return files.every(file => patterns.some(p => p.test(file.type)));\n }\n return patterns.some(p => p.test(files.type));\n};\n\nconst minValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const length = getSingleParam(params, 'length');\n if (Array.isArray(value)) {\n return value.every(val => minValidator(val, { length }));\n }\n return [...String(value)].length >= Number(length);\n};\n\nconst minValueValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n const min = getSingleParam(params, 'min');\n if (Array.isArray(value)) {\n return value.length > 0 && value.every(val => minValueValidator(val, { min }));\n }\n return Number(value) >= Number(min);\n};\n\nconst oneOfValidator = (value, list) => {\n if (isEmpty(value)) {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(val => oneOfValidator(val, list));\n }\n return Array.from(list).some(item => {\n return item == value;\n });\n};\n\nconst notOneOfValidator = (value, list) => {\n if (isEmpty(value)) {\n return true;\n }\n return !oneOfValidator(value, list);\n};\n\nconst ar = /^[٠١٢٣٤٥٦٧٨٩]+$/;\nconst en = /^[0-9]+$/;\nconst numericValidator = (value) => {\n if (isEmpty(value)) {\n return true;\n }\n const testValue = (val) => {\n const strValue = String(val);\n return en.test(strValue) || ar.test(strValue);\n };\n if (Array.isArray(value)) {\n return value.every(testValue);\n }\n return testValue(value);\n};\n\nconst regexValidator = (value, params) => {\n if (isEmpty(value)) {\n return true;\n }\n let regex = getSingleParam(params, 'regex');\n if (typeof regex === 'string') {\n regex = new RegExp(regex);\n }\n if (Array.isArray(value)) {\n return value.every(val => regexValidator(val, { regex }));\n }\n return regex.test(String(value));\n};\n\nfunction isNullOrUndefined(value) {\n return value === null || value === undefined;\n}\nfunction isEmptyArray(arr) {\n return Array.isArray(arr) && arr.length === 0;\n}\nconst isObject = (obj) => obj !== null && !!obj && typeof obj === 'object' && !Array.isArray(obj);\n\nconst requiredValidator = (value) => {\n if (isNullOrUndefined(value) || isEmptyArray(value) || value === false) {\n return false;\n }\n return !!String(value).trim().length;\n};\n\nconst sizeValidator = (files, params) => {\n if (isEmpty(files)) {\n return true;\n }\n let size = getSingleParam(params, 'size');\n size = Number(size);\n if (isNaN(size)) {\n return false;\n }\n const nSize = size * 1024;\n if (!Array.isArray(files)) {\n return files.size <= nSize;\n }\n for (let i = 0; i < files.length; i++) {\n if (files[i].size > nSize) {\n return false;\n }\n }\n return true;\n};\n\nconst urlValidator = (value, params) => {\n var _a;\n if (isEmpty(value)) {\n return true;\n }\n let pattern = getSingleParam(params, 'pattern');\n if (typeof pattern === 'string') {\n pattern = new RegExp(pattern);\n }\n try {\n new URL(value);\n }\n catch (_b) {\n return false;\n }\n return (_a = pattern === null || pattern === void 0 ? void 0 : pattern.test(value)) !== null && _a !== void 0 ? _a : true;\n};\n\n/**\n * A typed version of Object.keys\n */\nfunction keysOf(record) {\n return Object.keys(record);\n}\n\nfunction toTypedSchema(rawSchema) {\n const schema = {\n __type: 'VVTypedSchema',\n async parse(values) {\n // single field\n if (typeof rawSchema === 'string') {\n const result = await validate(values, rawSchema);\n return {\n errors: [\n {\n errors: result.errors,\n },\n ],\n };\n }\n const result = await validateObject(rawSchema, values);\n return {\n errors: keysOf(result.errors).map(path => {\n var _a;\n const error = {\n path: path,\n errors: ((_a = result.results[path]) === null || _a === void 0 ? void 0 : _a.errors) || [],\n };\n return error;\n }),\n };\n },\n describe(path) {\n if (!path) {\n return getDescriptionFromExpression(rawSchema);\n }\n if (isObject(rawSchema) && path in rawSchema) {\n return getDescriptionFromExpression(rawSchema[path]);\n }\n return {\n required: false,\n exists: false,\n };\n },\n };\n return schema;\n}\nfunction getDescriptionFromExpression(rules) {\n if (typeof rules === 'string') {\n return {\n exists: true,\n required: rules.includes('required'),\n };\n }\n if (isObject(rules)) {\n return {\n exists: true,\n required: !!rules.required,\n };\n }\n return {\n required: false,\n exists: true,\n };\n}\n\nconst all = {\n alpha_dash: alphaDashValidator,\n alpha_num: alphaNumValidator,\n alpha_spaces: alphaSpacesValidator,\n alpha: alphaValidator,\n between: betweenValidator,\n confirmed: confirmedValidator,\n digits: digitsValidator,\n dimensions: dimensionsValidator,\n email: emailValidator,\n ext: extValidator,\n image: imageValidator,\n integer: integerValidator,\n is_not: isNotValidator,\n is: isValidator,\n length: lengthValidator,\n max_value: maxValueValidator,\n max: maxLengthValidator,\n mimes: mimesValidator,\n min_value: minValueValidator,\n min: minValidator,\n not_one_of: notOneOfValidator,\n numeric: numericValidator,\n one_of: oneOfValidator,\n regex: regexValidator,\n required: requiredValidator,\n size: sizeValidator,\n url: urlValidator,\n};\n\nexport { all, alphaValidator as alpha, alphaDashValidator as alpha_dash, alphaNumValidator as alpha_num, alphaSpacesValidator as alpha_spaces, betweenValidator as between, confirmedValidator as confirmed, digitsValidator as digits, dimensionsValidator as dimensions, emailValidator as email, extValidator as ext, imageValidator as image, integerValidator as integer, isValidator as is, isNotValidator as is_not, lengthValidator as length, maxLengthValidator as max, maxValueValidator as max_value, mimesValidator as mimes, minValidator as min, minValueValidator as min_value, notOneOfValidator as not_one_of, numericValidator as numeric, oneOfValidator as one_of, regexValidator as regex, requiredValidator as required, sizeValidator as size, toTypedSchema, urlValidator as url };\n","/**\n * Recursively traverses a data structure to determine if it holds any meaningful data.\n * Returns false only when the entire structure consists of null/undefined values.\n * Particularly useful for validation frameworks to detect populated form fields.\n *\n * @param element Data structure to analyze (supports primitives, objects, arrays)\n * @returns Boolean indicating presence of non-nullish values\n */\nexport function checkTreeHasValue(element: unknown): boolean {\n if (element === null || element === undefined) {\n return false;\n }\n\n if (Array.isArray(element)) {\n return element.some((value: unknown) => checkTreeHasValue(value));\n }\n if (typeof element === 'object') {\n return Object.values(element).some((value: unknown) => checkTreeHasValue(value));\n }\n\n return true;\n}\n","import type { FieldValidationMetaInfo, ValidationMessage } from '@/types/ValidationMessage';\n\n/**\n * Helper function to resolve a validation message, with parameters.\n *\n * All three param styles work:\n * 'Must be at least {0} characters' // positional\n * 'Must be at least {min} characters' // named (object params)\n * 'The {field} value {value} is invalid' // context properties\n *\n * This is exactly how @vee-validate/i18n handles it internally.\n * @param message - The message template or function\n * @param ctx - The vee-validate field validation context\n * @param params - Optional param override. Array for positional `{0}, {1}`, or object for\n * named `{min}, {length}` (also supports positional via numeric keys). Falls back to ctx.rule.params if not provided.\n * @returns The resolved message string\n */\nexport function resolveMessage(message: ValidationMessage, ctx: FieldValidationMetaInfo, params?: unknown[] | Record<string, unknown>): string {\n if (typeof message === 'function')\n return message(ctx);\n return message.replace(/\\{(\\w+)\\}/g, (_, key) => {\n // Named context properties: {field}, {value}\n if (key in ctx)\n return String((ctx as any)[key]);\n // Named or positional from explicit params object: {min}, {length}, {0}\n if (params && !Array.isArray(params) && key in params)\n return String(params[key]);\n // Positional from explicit params array: {0}, {1}\n const index = Number(key);\n if (!Number.isNaN(index)) {\n if (Array.isArray(params) && params[index] !== undefined)\n return String(params[index]);\n return String((ctx.rule?.params as unknown[])?.[index] ?? `{${key}}`);\n }\n // Named from ctx.rule.params object: {min}, {max}\n if (ctx.rule?.params && !Array.isArray(ctx.rule.params))\n return String(ctx.rule.params[key] ?? `{${key}}`);\n return `{${key}}`;\n });\n}\n","import { max, max_value, min, min_value, one_of, regex } from '@vee-validate/rules';\nimport { defineRule } from 'vee-validate';\nimport { checkTreeHasValue } from '@/utils/checkTreeHasValue';\n\nexport { resolveMessage } from '@/utils/resolveMessage';\n\n/** XSD-derived rule names registered globally via vee-validate's `defineRule`. */\nexport type ValidationRule = 'xsd_required'\n | 'xsd_minOccurs'\n | 'xsd_choiceMinOccurs'\n | 'xsd_minLength'\n | 'xsd_maxLength'\n | 'xsd_pattern'\n | 'xsd_minInclusive'\n | 'xsd_maxInclusive'\n | 'xsd_minExclusive'\n | 'xsd_maxExclusive'\n | 'xsd_enumeration'\n | 'xsd_length'\n | 'xsd_whiteSpace'\n | 'xsd_fractionDigits'\n | 'xsd_totalDigits';\n\n// XSD: required — null/undefined/empty string are invalid; false is a valid boolean value\ndefineRule('xsd_required' as ValidationRule, (value: unknown) => value !== null && value !== undefined && value !== '');\n\n// XSD: minOccurs — minimum number of array items that have a value\ndefineRule('xsd_minOccurs' as ValidationRule, (value: unknown, [min]: [number]) => {\n if (!Array.isArray(value))\n return Number(min) <= 0;\n return value.filter(checkTreeHasValue).length >= Number(min);\n});\n\n// XSD: choiceMinOccurs — minimum number of choice items that have a value\ndefineRule('xsd_choiceMinOccurs' as ValidationRule, () => {\n // As we can't actually validate a choice field (it doesn't exist in the vee-validate value tree)\n // we always validate false if this validation is added.\n return false;\n});\n\n// XSD: minLength / maxLength — maps to vee-validate's min/max (string length)\ndefineRule('xsd_minLength' as ValidationRule, min);\ndefineRule('xsd_maxLength' as ValidationRule, max);\n\n// XSD: length — exact string length\ndefineRule('xsd_length' as ValidationRule, (value: unknown, [length]: [number]) => {\n if (value === null || value === undefined || value === '')\n return true;\n return String(value).length === Number(length);\n});\n\n// XSD: pattern — maps to vee-validate's regex\ndefineRule('xsd_pattern' as ValidationRule, regex);\n\n// XSD: minInclusive / maxInclusive (value >= min, value <= max)\ndefineRule('xsd_minInclusive' as ValidationRule, min_value);\ndefineRule('xsd_maxInclusive' as ValidationRule, max_value);\n\n// XSD: minExclusive / maxExclusive (value > min, value < max)\ndefineRule('xsd_minExclusive' as ValidationRule, (value: unknown, [min]: [number]) => {\n if (value === null || value === undefined || value === '')\n return true;\n return Number(value) > Number(min);\n});\ndefineRule('xsd_maxExclusive' as ValidationRule, (value: unknown, [max]: [number]) => {\n if (value === null || value === undefined || value === '')\n return true;\n return Number(value) < Number(max);\n});\n\n// XSD: enumeration — maps to vee-validate's one_of\ndefineRule('xsd_enumeration' as ValidationRule, one_of);\n\n// XSD: whiteSpace — validates the value conforms to the given whitespace mode\n// Modes: 'preserve' (no restriction), 'replace' (no tabs/newlines), 'collapse' (no leading/trailing/multiple spaces)\ndefineRule('xsd_whiteSpace' as ValidationRule, (value: unknown, [mode]: [string]) => {\n if (value === null || value === undefined || value === '')\n return true;\n const str = String(value);\n if (mode === 'replace')\n return !/[\\t\\n\\r]/.test(str);\n if (mode === 'collapse')\n return str === str.trim() && !/\\s{2,}/.test(str);\n return true; // 'preserve' — no restriction\n});\n\n// XSD: fractionDigits — maximum number of decimal places\ndefineRule('xsd_fractionDigits' as ValidationRule, (value: unknown, [digits]: [number]) => {\n if (value === null || value === undefined || value === '')\n return true;\n const decimalIndex = String(value).indexOf('.');\n if (decimalIndex === -1)\n return true;\n return String(value).length - decimalIndex - 1 <= Number(digits);\n});\n\n// XSD: totalDigits — maximum total number of significant digits (excluding sign and decimal point)\ndefineRule('xsd_totalDigits' as ValidationRule, (value: unknown, [digits]: [number]) => {\n if (value === null || value === undefined || value === '')\n return true;\n const significant = String(value).replace(/^-/, '').replace('.', '').replace(/^0+/, '') || '0';\n return significant.length <= Number(digits);\n});\n\n/**\n * Maps each rule to its semantic parameter name, enabling named placeholder\n * interpolation (e.g. `{length}`, `{min}`) alongside positional `{0}` in messages.\n */\nexport const ruleParamNames: Partial<Record<ValidationRule, string>> = {\n xsd_minOccurs: 'min',\n xsd_choiceMinOccurs: 'min',\n xsd_minLength: 'length',\n xsd_maxLength: 'length',\n xsd_length: 'length',\n xsd_pattern: 'pattern',\n xsd_minInclusive: 'min',\n xsd_maxInclusive: 'max',\n xsd_minExclusive: 'min',\n xsd_maxExclusive: 'max',\n xsd_whiteSpace: 'mode',\n xsd_fractionDigits: 'digits',\n xsd_totalDigits: 'digits',\n};\n","import type { FieldValidationMetaInfo } from '@/types/ValidationMessage';\n\n/**\n * Resolves the most user-friendly label for a field validation context.\n *\n * Most components (e.g. DynamicFormItem, DynamicFormItemArray) call `useField`\n * with the field's `fieldOptions`, so vee-validate already sets `ctx.label`\n * and `ctx.field` to a human-readable name. Choice fields are special: they\n * validate at the root path (`''`) and historically registered without any\n * `fieldOptions`, which left vee-validate with the literal placeholder\n * string `{field}`. Normalizing the label here ensures shared helpers like\n * createValidation/splitValidationFunctions always receive a real display name\n * even for those “virtual” fields.\n *\n * Preference order: explicit label → ctx.field → ctx.name → empty string.\n */\nexport function getFieldLabel(ctx: FieldValidationMetaInfo): string {\n return ctx.label ?? ctx.field ?? ctx.name ?? '';\n}\n","import type { ValidationRule } from '@/core/validation';\nimport type { FieldValidationMetaInfo, ValidationMessage } from '@/types/ValidationMessage';\nimport { validate } from 'vee-validate';\nimport { resolveMessage, ruleParamNames } from '@/core/validation';\nimport { getFieldLabel } from '@/utils/getFieldLabel';\n\n/**\n * Creates a validation that uses a globally defined rule in our 'vdf' namespace.\n * When the validation fails we either show the message override from the settings.messages\n * or let the user override the message using the configure.generateMessage\n *\n * @param rule\n * @param param\n * @param customMessage\n */\nexport function createValidation(rule: ValidationRule, param?: unknown, customMessage?: ValidationMessage) {\n // Build params as an object so both positional ({0}) and named ({length}, {min}, ...) placeholders work\n const paramName = ruleParamNames[rule];\n const params: Record<string, unknown> = param !== undefined\n ? { 0: param, ...(paramName ? { [paramName]: param } : {}) }\n : {};\n return async (value: unknown, ctx: FieldValidationMetaInfo) => {\n const fieldName = getFieldLabel(ctx);\n const validateOptions = fieldName ? { name: fieldName } : undefined;\n const normalizedCtx = fieldName && ctx.field !== fieldName\n ? { ...ctx, field: fieldName }\n : ctx;\n\n const result = await validate(\n value,\n param !== undefined ? { [rule]: param } : rule,\n validateOptions,\n );\n if (result.valid)\n return true;\n return customMessage ? resolveMessage(customMessage, normalizedCtx, params) : result.errors[0];\n };\n}\n","/**\n * Helper function that converts a path with bracket notation to a dot notation.\n * When adding an extra path segment, we do this by using the bracket notation, i.e.: person['value'].\n *\n * Vee-validate can't work with this notation, therefore this function fixes those cases.\n *\n * const actualPath = normalizePath(\n * 'this.is[\"added\"].to.my.path.and.more',\n * )\n *\n * console.log(actualPath) // 'this.is.added.to.my.path.and.more'\n *\n * @param path to be normalized\n */\nexport function normalizePath(path: string) {\n return path?.replaceAll(/\\[[`'\"](.*?)[`'\"]\\]/g, '.$1') ?? '';\n}\n","/**\n * Merges two dot-notation paths by replacing leading segments of the base path\n * with segments from the replacement path. Useful for resolving array indices\n * in nested field paths where parent context contains array positions.\n *\n * @example\n * // Given a generic path and an indexed parent path, produce the indexed child path\n * const result = overridePath(\n * 'data.users.contact.email',\n * 'data.users[2]'\n * )\n *\n * console.log(result) // 'data.users[2].contact.email'\n *\n * @param path Base path string to be modified\n * @param overrideWithPath Replacement path that will substitute initial segments\n * @returns Modified path with replaced segments\n */\nexport function overridePath(path: string, overrideWithPath: string | undefined) {\n if (!path || !overrideWithPath)\n return path;\n\n // Split both paths and substitute leading segments from the replacement path\n const parentSegments = overrideWithPath.split('.') ?? [];\n const childSegments = path.split('.') ?? [];\n for (let index = 0; index < parentSegments.length; index++) {\n childSegments[index] = parentSegments[index];\n }\n return childSegments.join('.');\n}\n","import type { GenericValidateFunction, RuleExpression } from 'vee-validate';\nimport type { FieldValidationMetaInfo } from '@/types/ValidationMessage';\nimport { validate } from 'vee-validate';\nimport { getFieldLabel } from '@/utils/getFieldLabel';\n\n/**\n * Splits a vee-validate `RuleExpression` into an array of individual `GenericValidateFunction`s,\n * one per rule. This allows vee-validate to run each rule independently and collect all errors\n * when `bails: false` is configured.\n *\n * Handles all `RuleExpression` formats:\n * - **Function** — returned as-is in a single-element array\n * - **Array** — each element is recursively split\n * - **String** — pipe-separated rules (e.g. `'required|email'`) are split into separate functions,\n * each delegating to vee-validate's `validate()`\n * - **Object** — each key/value pair (e.g. `{ required: true, min: 3 }`) becomes a separate function,\n * each delegating to vee-validate's `validate()`\n */\nexport function splitToValidationFunctions(userRules: RuleExpression<unknown>):\nGenericValidateFunction[] {\n if (!userRules)\n return [];\n if (typeof userRules === 'function')\n return [userRules];\n if (Array.isArray(userRules))\n return userRules.flatMap(splitToValidationFunctions);\n\n if (typeof userRules === 'string') {\n return userRules.split('|').map(rule => async (value: unknown, ctx: FieldValidationMetaInfo) => {\n const fieldName = getFieldLabel(ctx);\n const result = await validate(value, rule, fieldName ? { name: fieldName } : undefined);\n return result.valid ? true : result.errors[0];\n });\n }\n\n // Object format: { required: true, email: true }\n return Object.entries(userRules).map(([key, val]) => async (value: unknown, ctx: FieldValidationMetaInfo) => {\n const fieldName = getFieldLabel(ctx);\n const result = await validate(value, { [key]: val }, fieldName ? { name: fieldName } : undefined);\n return result.valid ? true : result.errors[0];\n });\n}\n","<script\n lang=\"ts\"\n setup\n generic=\"InternalMetadata extends InternalFieldMetadata<FieldMetadata>\"\n>\nimport type { GenericValidateFunction } from 'vee-validate';\nimport type { ComputedRef } from 'vue';\nimport type { LimitedFieldContext } from '@/components/DynamicFormTemplate.vue';\nimport type { DynamicFormItemProps } from '@/types/DynamicFormItemProps';\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport type { FieldMetadata } from '@/types/FieldMetadata';\nimport type { InternalFieldMetadata } from '@/types/InternalFieldMetadata';\nimport { useField, useSubmitCount, useValidateField } from 'vee-validate';\nimport { computed, inject, ref, watch, watchEffect } from 'vue';\nimport DynamicFormItem from '@/components/DynamicFormItem.vue';\nimport { useFieldArrayExtended } from '@/core/useFieldArrayExtended';\nimport { dynamicFormSettingsKey } from '@/types/DynamicFormSettings';\nimport { createValidation } from '@/utils/createValidation';\nimport { normalizePath } from '@/utils/normalizePath';\nimport { overridePath } from '@/utils/overridePath';\nimport { splitToValidationFunctions } from '@/utils/splitValidationFunctions';\n\n// #region Interfaces\nexport interface Emit {\n /** Emitted whenever array values change (item added, removed, or updated); payload is the full array value. */\n (e: 'update:modelValue', value: unknown): void\n /** Bubbled up from child `DynamicFormItem` instances; carries the updated computed field metadata. */\n (e: 'update:computedField', field: InternalFieldMetadata<FieldMetadata>): void\n}\ntype Props = DynamicFormItemProps<InternalMetadata>;\n// #endregion\n\n// #region Props, Emits and inject\nconst props = defineProps<Props>();\nconst emits = defineEmits<Emit>();\nconst settings = inject<ComputedRef<DynamicFormSettings>>(dynamicFormSettingsKey);\n// #endregion\n\n// #region Internal tracking\n// Plain variables (not reactive) to avoid triggering renders when measuring analytics.\n// eslint-disable-next-line prefer-const\nlet _analytics_renderCount = 0;\nlet _analytics_constructValidationCount = 0;\nlet _analytics_fieldChangedCount = 0;\n// #endregion\n\n// #region Computed state\n\n// --- Path ---\n\nconst field = computed(() => {\n _analytics_fieldChangedCount++;\n return props.fieldMetadata;\n});\n\nconst path = computed(() => {\n if (!field.value?.path)\n return '';\n\n return overridePath(field.value.path, props.pathOverride);\n});\n\nconst normalizedPath = computed(() => normalizePath(path.value));\n\n// --- Vee-Validate field array ---\n\nconst validate = useValidateField(normalizedPath);\nconst { remove, push, fields, update, values, replace } = useFieldArrayExtended(normalizedPath);\n\n// --- Occurrence limits ---\n\n// minOccurs determines how many items must exist at minimum.\nconst minOccurs = computed(() =>\n props.minOccursOverride !== undefined\n ? props.minOccursOverride\n : (field.value?.minOccurs ?? 1),\n);\n\n// maxOccurs determines how many items may exist at maximum.\nconst maxOccurs = computed(() =>\n props.maxOccursOverride !== undefined\n ? props.maxOccursOverride\n : (field.value?.maxOccurs ?? 1),\n);\n\nconst disabled = computed(() => maxOccurs.value === 0);\nconst required = computed(() => minOccurs.value >= 1 && !disabled.value);\n\n// Each individual array item is rendered as a single-occurrence field, not another array.\nconst _maxOccursOverride = computed(() =>\n maxOccurs.value === 0 ? 0 : 1,\n);\n\nconst _canAddItems = computed(() => maxOccurs.value > fields.value?.length);\nconst _canRemoveItems = computed(() => {\n // Choice-field children can be removed down to 0.\n if (props.partOfChoiceField)\n return fields.value?.length > 0;\n\n // Or when we choose to not automatically add items\n if (field.value?.autoAddMinOccurs === false)\n return fields.value?.length > 0;\n\n // Otherwise, keep at least minOccurs items and never go below 1.\n return fields.value?.length > minOccurs.value && fields.value?.length > 1;\n});\n\n// --- Validation ---\n\n// Validation is built as a computed (not watchEffect) because there is no circular dependency\n// to break here — the array field does not depend on its own validation value.\nconst combinedValidation = computed<GenericValidateFunction[]>(() => {\n _analytics_constructValidationCount++;\n\n const _validations: GenericValidateFunction[] = [];\n const _messages = settings?.value?.messages;\n\n if (required.value)\n _validations.push(createValidation('xsd_minOccurs', minOccurs.value, _messages?.minOccurs));\n\n if (field.value?.validation)\n _validations.push(...splitToValidationFunctions(field.value?.validation));\n\n return _validations;\n});\n\nconst { label, errors, errorMessage, handleBlur } = useField(normalizedPath, combinedValidation, {\n ...(field.value?.fieldOptions ?? {}),\n validateOnValueUpdate: false, // validation timing is owned by this component\n});\nconst fieldContext: LimitedFieldContext = { label, errors, errorMessage, value: values };\n\n// Delay validation until after the first real value is set — empty placeholder items\n// (added to satisfy minOccurs) should not trigger errors before the user has interacted.\nconst submitCount = useSubmitCount();\nconst firstValueSet = ref(false);\nconst shouldValidateOnValueUpdate = computed(() => {\n if (!firstValueSet.value)\n return;\n\n const validateOnValueUpdateAfterSubmit = settings?.value?.validateOnValueUpdateAfterSubmit === true\n ? (submitCount.value > 0 && settings?.value?.validateOnValueUpdateAfterSubmit)\n : undefined;\n\n const validateWhenInError = settings?.value?.validateWhenInError && fieldContext?.errors.value?.length > 0\n ? true\n : undefined;\n\n // Priority: field-level option → in-error state → after-submit setting → global setting\n return field.value?.fieldOptions?.validateOnValueUpdate\n ?? validateWhenInError\n ?? validateOnValueUpdateAfterSubmit\n ?? settings?.value?.validateOnValueUpdate;\n});\n\n// #endregion\n\n// #region Watchers and lifecycle events\n\nwatch(\n values,\n (v) => {\n if (shouldValidateOnValueUpdate.value) {\n validate();\n }\n emits('update:modelValue', v);\n },\n { immediate: true },\n);\n\n// Auto-add empty placeholder items to satisfy minOccurs.\n// Skipped for choice-field children — the choice manages their count.\n// Skipped when autoAddMinOccurs is explicitly set to false.\nwatchEffect(() => {\n if (props.partOfChoiceField)\n return;\n\n if (field.value?.autoAddMinOccurs === false)\n return;\n\n if (fields.value?.length < 1 || fields.value?.length < minOccurs.value) {\n _addItem();\n }\n});\n\n// #endregion\n\n// #region Methods\n\nfunction _addItem() {\n push(null); // empty placeholder\n emits('update:modelValue', values.value);\n}\n\nfunction _removeItem(index?: number) {\n if (_canRemoveItems.value) {\n remove(index ?? fields.value.length - 1);\n }\n else {\n // Below the allowed minimum — clear the item instead of removing it.\n replace(values.value?.map((x, i) => i === index ? null : x));\n }\n\n emits('update:modelValue', values.value);\n}\n\nfunction guardAndNotifyItemUpdate(value: any, index: number) {\n if (!firstValueSet.value) {\n // Now that a real value exists, enable validation going forward.\n firstValueSet.value = true;\n if (shouldValidateOnValueUpdate.value) {\n validate();\n }\n }\n\n // Workaround: when an array item has attributes, the complexType wrapper may retain\n // attribute values even after the main value is cleared. This causes checkTreeHasValue()\n // to return true and bypasses required validation. Explicitly calling update() with undefined\n // ensures vee-validate clears the entry and required validation can fire correctly.\n if (value === undefined && index >= 0) {\n update(index, undefined);\n }\n\n emits('update:modelValue', values.value);\n};\n\n// #endregion\n</script>\n\n<template>\n <div v-if=\"settings?.analytics\" v-show=\"false\">\n <span :data-testid=\"`${path}-analytics-render-count`\">{{\n ++_analytics_renderCount\n }}</span>\n </div>\n <component\n :is=\"template\"\n :type=\"`${fieldMetadata.type}-array`\"\n :field-metadata\n :field-context\n :slot-props\n :settings\n :required\n :disabled\n :index\n :can-add-items=\"_canAddItems\"\n :can-remove-items=\"_canRemoveItems\"\n :add-item=\"_addItem\"\n :remove-item=\"_removeItem\"\n >\n <template #default=\"slotProps\">\n <DynamicFormItem\n v-for=\"({ key }, arrayIndex) in fields ?? []\"\n :key=\"key\"\n :field-metadata\n :path-override=\"`${path}[${arrayIndex}]`\"\n :index=\"arrayIndex\"\n :template=\"template\"\n :slot-props\n :max-occurs-override=\"_maxOccursOverride\"\n :can-add-items=\"_canAddItems\"\n :can-remove-items=\"_canRemoveItems\"\n :add-item=\"_addItem\"\n :remove-item=\"() => _removeItem(arrayIndex)\"\n part-of-array-field\n is-array-override=\"single\"\n\n @update:model-value=\"guardAndNotifyItemUpdate($event, arrayIndex)\"\n @update:computed-field=\"emits('update:computedField', $event)\"\n @blur=\"handleBlur\"\n />\n </template>\n </component>\n</template>\n","<script\n lang=\"ts\"\n setup\n generic=\"InternalMetadata extends InternalFieldMetadata<FieldMetadata>\"\n>\nimport type { ComputedRef } from 'vue';\nimport type { LimitedFieldContext } from '@/components/DynamicFormTemplate.vue';\nimport type { DynamicFormItemProps } from '@/types/DynamicFormItemProps';\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport type { FieldMetadata } from '@/types/FieldMetadata';\nimport type { InternalFieldMetadata } from '@/types/InternalFieldMetadata';\nimport { useField } from 'vee-validate';\nimport { computed, inject, ref, watch } from 'vue';\nimport DynamicFormItem from '@/components/DynamicFormItem.vue';\nimport { dynamicFormSettingsKey } from '@/types/DynamicFormSettings';\nimport { checkTreeHasValue } from '@/utils/checkTreeHasValue';\nimport { createValidation } from '@/utils/createValidation';\nimport { normalizePath } from '@/utils/normalizePath';\nimport { overridePath } from '@/utils/overridePath';\n\n// #region Interfaces\nexport interface Emit {\n /** Emitted whenever any child option's value changes; payload is the array of all child values in choice-option order. */\n (e: 'update:modelValue', value: unknown): void\n /** Bubbled up from child `DynamicFormItem` instances; carries the updated computed field metadata. */\n (e: 'update:computedField', field: InternalFieldMetadata<FieldMetadata>): void\n}\ntype Props = DynamicFormItemProps<InternalMetadata>;\n\n// Tracks how much of the choice \"budget\" each child is consuming.\ninterface ChildValue {\n value: any\n occurrences: number // how many instances of this child are currently shown\n valuesCount: number // how many of those instances actually have a value\n maxOccurrences: number // the child's own maxOccurs\n}\n// #endregion\n\n// #region Props, Emits and inject\nconst props = defineProps<Props>();\nconst emits = defineEmits<Emit>();\nconst settings = inject<ComputedRef<DynamicFormSettings>>(dynamicFormSettingsKey);\n// #endregion\n\n// #region Internal tracking\n// Plain variables (not reactive) to avoid triggering renders when measuring analytics.\nlet _analytics_updateCallCount = 0;\nlet _analytics_occurrencesCalculatedCount = 0;\n// #endregion\n\n// #region Computed state\n\n// --- Path ---\n\nconst field = computed(() => props.fieldMetadata);\n\n// A choice field itself has no path in the XML/json hierarchy, so we use the nearest ancestor's path\n// for vee-validate registration and for passing down to children as pathOverride.\nconst closestPath = computed(() =>\n overridePath(field.value.path ?? '', props.pathOverride));\n\nconst normalizedPath = computed(() => normalizePath(closestPath.value));\n\n// --- Occurrence limits ---\n\nconst minOccurs = computed(() =>\n props.minOccursOverride !== undefined\n ? props.minOccursOverride\n : (field.value?.minOccurs ?? 1),\n);\n\nconst maxOccurs = computed(() =>\n props.maxOccursOverride !== undefined\n ? props.maxOccursOverride\n : (field.value?.maxOccurs ?? 1),\n);\n\nconst disabled = computed(() => maxOccurs.value === 0);\nconst required = computed(() => minOccurs.value >= 1 && !disabled.value);\n\n// Propagate optional/disabled state to children.\nconst _minOccursOverride = computed(() =>\n minOccurs.value === 0 ? 0 : undefined,\n);\nconst _maxOccursOverride = computed(() =>\n maxOccurs.value === 0 ? 0 : undefined,\n);\n\n// When the choice itself may occur more than once, its children become array fields too.\nconst childrenAreArrays = computed(() => field.value?.maxOccurs > 1 ? 'array' : undefined);\n\n// --- Child value tracking ---\n\n// Each child reports its current value here so we can calculate the shared occurrence budget.\nconst childValues = ref<{ [index: string]: ChildValue }>({});\n\n// Raw child values are emitted upward as-is; occurrence-aware counting happens below.\nconst values = computed(() => Object.values(childValues.value).map(x => x.value));\n\n// --- Single-child shortcut ---\n\n// When a choice field has exactly one option there is no meaningful branching — skip\n// all occurrence math and render that one child directly.\nconst singleChild = computed(() =>\n field.value?.choice?.length === 1 ? field.value?.choice[0] as InternalMetadata : undefined,\n);\n\n// --- Occurrence budget calculation ---\n\n/**\n * For each child, calculates:\n * - how many of the shared choice occurrences it is currently consuming\n * - the resulting min/max occurrence overrides to pass down\n *\n * Background: a choice with maxOccurs=4 and two children each with maxOccurs=2 means\n * every 2 child items count as 1 choice occurrence. Children compete for the shared budget,\n * so the more one child uses, the less the others may use.\n */\nconst occurrences = computed(() => {\n _analytics_occurrencesCalculatedCount++;\n\n const _occurrences: {\n [index: string]: {\n childValuesCount: number\n childOccurrences: number\n childMaxOccurrences: number\n choiceValuesCount: number\n choiceOccurrences: number\n overrideChildMaxOccurrences: number | undefined\n overrideChildMinOccurrences: number | undefined\n }\n } = {};\n\n // Initialise defaults for every child upfront so all indices exist even if no value arrived yet.\n field.value?.choice?.forEach((_, i) => {\n _occurrences[i] = {\n childValuesCount: 0,\n childOccurrences: 0,\n childMaxOccurrences: 1,\n choiceValuesCount: 0,\n choiceOccurrences: 0,\n overrideChildMaxOccurrences: undefined,\n overrideChildMinOccurrences: 0, // children are optional by default inside a choice\n };\n });\n\n const _maxOccurs = maxOccurs.value ?? 1;\n\n // When the whole choice is disabled (maxOccurs=0), disable all children immediately.\n if (_maxOccurs === 0) {\n field.value?.choice?.forEach((_, i) => {\n _occurrences[i].overrideChildMaxOccurrences = 0;\n _occurrences[i].overrideChildMinOccurrences = 0;\n });\n return _occurrences;\n }\n\n // Pass 1: convert each child's raw occurrence count into choice-occurrence units.\n for (const [key, child] of Object.entries(childValues.value ?? {})) {\n // How many choice occurrences does this child consume?\n // e.g. choice.maxOccurs=4, child.maxOccurs=2: every 2 child items = 1 choice occurrence.\n let choiceOccurrences = Math.ceil(child.occurrences / child.maxOccurrences);\n const choiceValuesCount = Math.ceil(child.valuesCount / child.maxOccurrences);\n\n // For a non-array child (totalChildOccurrences=1) the field is always shown, so its\n // \"occupancy\" should be based on whether it actually has a value, not on it being shown.\n const totalChildOccurrences = _maxOccurs * child.maxOccurrences;\n if (totalChildOccurrences === 1) {\n choiceOccurrences = choiceValuesCount;\n }\n\n _occurrences[key] = {\n childValuesCount: child.valuesCount,\n childOccurrences: child.occurrences,\n childMaxOccurrences: child.maxOccurrences,\n choiceOccurrences,\n choiceValuesCount,\n overrideChildMinOccurrences: child.valuesCount === 0 ? 0 : undefined, // optional when empty\n overrideChildMaxOccurrences: undefined, // calculated in pass 2\n };\n }\n\n const totalChoiceOccurrences = Object.values(_occurrences).reduce(\n (acc, value) => acc + value.choiceOccurrences,\n 0,\n );\n\n // Pass 2: for each child, derive how many more items it may add given what the others are using.\n // Because Math.ceil() was used above we work backwards from the combined total to stay accurate.\n Object.values(_occurrences).forEach((value) => {\n const othersChoiceOccurrences = totalChoiceOccurrences - value.choiceOccurrences;\n const othersAsChildOccurrences = othersChoiceOccurrences * value.childMaxOccurrences;\n const totalChildOccurrences = _maxOccurs * value.childMaxOccurrences;\n\n value.overrideChildMaxOccurrences = totalChildOccurrences - othersAsChildOccurrences;\n });\n\n return _occurrences;\n});\n\n// Total number of filled choices (in choice-occurrence units, not raw item counts).\nconst valuesCount = computed(() =>\n Object.values(occurrences.value).reduce(\n (acc, c) => acc + c.choiceValuesCount,\n 0,\n ),\n);\n\n// --- Vee-Validate field context ---\n\n// Only validate when the total filled choices fall below the minimum required.\nconst combinedValidation = computed(() => {\n if (singleChild.value)\n return; // single-child choices are validated by the child itself\n\n if (disabled.value)\n return;\n\n if (valuesCount.value >= minOccurs.value)\n return;\n\n const _messages = settings?.value?.messages;\n return [createValidation('xsd_choiceMinOccurs', minOccurs.value, _messages?.choiceMinOccurs)];\n});\n\n// A choice field has no entry in the vee-validate values tree, so we anchor validation\n// to the nearest parent path instead of a dedicated path. This gives errors a home.\nconst { errors, errorMessage } = useField(normalizedPath, combinedValidation, field.value?.fieldOptions);\nconst fieldContext: LimitedFieldContext = { label: field.value?.fieldOptions?.label, errors, errorMessage, value: values };\n\n// #endregion\n\n// #region Watchers and lifecycle events\n\n// Seed childValues so every child index exists from the start; prevents occurrences\n// from returning undefined for children that haven't emitted an update yet.\nwatch(field, (_field) => {\n if (!_field)\n return;\n\n // Initialize tracking entries for choice children that haven't been set up yet.\n // We skip indices that are already present so that a metadata-reference change\n // (e.g. from a recomputed metadataWithEdit) does not reset values that users have already entered.\n _field.choice?.forEach((child, index) => {\n if (!(index in childValues.value))\n updateChildValue(undefined, index, child.maxOccurs);\n });\n}, { immediate: true });\n\n// #endregion\n\n// #region Methods\n\nfunction updateChildValue(\n value: any,\n childIndex: number | undefined,\n maxOccurrences: number = 1,\n skipCalculations: boolean = false,\n) {\n // Used by singleChild to forward value updates without recalculating the occurrence budget.\n if (skipCalculations) {\n emits('update:modelValue', values.value);\n return;\n }\n\n _analytics_updateCallCount++;\n\n if (childIndex === undefined)\n return;\n\n let calculateValues = Array.isArray(value) ? value : [value];\n\n // For non-array children (totalChildOccurrences=1) an undefined means \"no value\".\n // Filter those out so they don't inflate the occurrence count.\n const _maxOccurs = maxOccurs.value ?? 1;\n const totalChildOccurrences = _maxOccurs * maxOccurrences;\n if (totalChildOccurrences === 1) {\n calculateValues = calculateValues.filter(x => x !== undefined);\n }\n\n const occurrences = calculateValues.length;\n const valuesCount = calculateValues.filter(v => checkTreeHasValue(v)).length;\n\n const childValue = childValues.value[childIndex] ?? ({} as ChildValue);\n childValue.value = value;\n childValue.occurrences = occurrences;\n childValue.valuesCount = valuesCount;\n childValue.maxOccurrences = maxOccurrences;\n\n if (!childValues.value[childIndex]) {\n childValues.value[childIndex] = childValue;\n }\n\n emits('update:modelValue', values.value);\n};\n\n// #endregion\n</script>\n\n<template>\n <component\n :is=\"template\"\n v-slot=\"slotProps\"\n :type=\"`${fieldMetadata.type}-choice`\"\n :field-metadata\n :field-context\n :slot-props\n :settings\n :required\n :index\n :disabled\n :can-add-items\n :can-remove-items\n :add-item\n :remove-item\n >\n <DynamicFormItem\n v-if=\"singleChild\"\n :field-metadata=\"singleChild\"\n :path-override\n :template\n :slot-props\n :min-occurs-override=\"_minOccursOverride\"\n :max-occurs-override=\"_maxOccursOverride\"\n part-of-choice-field\n\n @update:model-value=\"updateChildValue($event, 0, singleChild!.maxOccurs, true)\"\n @update:computed-field=\"emits('update:computedField', $event)\"\n />\n <template v-else>\n <DynamicFormItem\n v-for=\"(child, index) in field.choice\"\n :key=\"child.name\"\n :field-metadata=\"(child as InternalMetadata)\"\n :path-override\n :index\n :template\n :slot-props\n :min-occurs-override=\"occurrences[index]?.overrideChildMinOccurrences\"\n :max-occurs-override=\"occurrences[index]?.overrideChildMaxOccurrences\"\n :is-array-override=\"childrenAreArrays\"\n part-of-choice-field\n\n @update:model-value=\"updateChildValue($event, index, child.maxOccurs)\"\n @update:computed-field=\"emits('update:computedField', $event)\"\n />\n </template>\n </component>\n</template>\n","import type { FieldMetadata } from '@/types/FieldMetadata';\n\n/**\n * Creates a deterministic hash of all mutable field properties (those that computedProps can change).\n * Excludes structural/immutable properties: name, path, children, choice, attributes,\n * fieldOptions, computedProps, maxOccurs, parent, and _hash itself.\n */\nexport function hashField(field: FieldMetadata): string {\n const {\n name: _name,\n path: _path,\n children: _children,\n choice: _choice,\n attributes: _attributes,\n fieldOptions: _fieldOptions,\n computedProps: _computedProps,\n maxOccurs: _maxOccurs,\n _hash: _prevHash,\n parent: _parent,\n isComplexType: _isComplexType,\n computeOnChildValueChange: _computeOnChildValueChange,\n ...mutableProps\n } = field as any;\n\n const sorted = Object.fromEntries(\n Object.entries(mutableProps).sort(([a], [b]) => a.localeCompare(b)),\n );\n return JSON.stringify(sorted);\n}\n","<script\n lang=\"ts\"\n setup\n generic=\"InternalMetadata extends InternalFieldMetadata<FieldMetadata>\"\n>\nimport type { GenericValidateFunction } from 'vee-validate';\nimport type { ComputedRef } from 'vue';\nimport type { FieldContext } from '@/components/DynamicFormTemplate.vue';\nimport type { DynamicFormItemProps } from '@/types/DynamicFormItemProps';\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport type { ComputedPropsFieldOf, FieldMetadata, ReadOnlyFieldOf } from '@/types/FieldMetadata';\nimport type { InternalFieldMetadata } from '@/types/InternalFieldMetadata';\nimport { useField, useSubmitCount } from 'vee-validate';\nimport { computed, inject, onBeforeUnmount, onMounted, ref, watch, watchEffect } from 'vue';\nimport DynamicFormItemArray from '@/components/DynamicFormItemArray.vue';\nimport DynamicFormItemChoice from '@/components/DynamicFormItemChoice.vue';\nimport { dynamicFormSettingsKey } from '@/types/DynamicFormSettings';\nimport { checkTreeHasValue } from '@/utils/checkTreeHasValue';\nimport { createValidation } from '@/utils/createValidation';\nimport { hashField } from '@/utils/hashField';\nimport { normalizePath } from '@/utils/normalizePath';\nimport { overridePath } from '@/utils/overridePath';\nimport { splitToValidationFunctions } from '@/utils/splitValidationFunctions';\n\n// #region Interfaces\nexport interface Emit {\n /** Emitted by leaf input fields whenever their value changes; payload is the new field value. */\n (e: 'update:modelValue', value: unknown): void\n /** Forwarded from vee-validate's `handleBlur`; lets parent array/choice fields trigger validation on blur. */\n (e: 'blur', event?: Event | undefined, shouldValidate?: boolean | undefined): void\n /** Emitted on mount and whenever the field's computed hash changes, so the parent keeps `childFields` in sync. */\n (e: 'update:computedField', field: InternalFieldMetadata<FieldMetadata>): void\n}\ntype Props = DynamicFormItemProps<InternalMetadata>;\n// #endregion\n\n// #region Props, Emits and inject\nconst props = defineProps<Props>();\nconst emits = defineEmits<Emit>();\nconst settings = inject<ComputedRef<DynamicFormSettings>>(dynamicFormSettingsKey);\n// #endregion\n\n// #region Internal tracking\n\n// Plain variables (not reactive) to avoid triggering renders when measuring analytics.\n// eslint-disable-next-line prefer-const\nlet _analytics_renderCount = 0;\nlet _analytics_constructValidationCount = 0;\nlet _analytics_fieldChangedCount = 0;\nlet _analytics_fieldComputeCount = 0;\nlet _analytics_valueChangedCount = 0;\nlet _analytics_notifyValueUpdateCount = 0;\n\n// Detects non-idempotent writes inside computedProps that would cause an infinite recomputation loop.\n// The counter resets after each macrotask, so it only catches computes that happen synchronously.\nconst COMPUTE_LOOP_MAX = 10;\nlet _computeLoopCount = 0;\nlet _computeLoopResetTimer: ReturnType<typeof setTimeout> | undefined;\n\nfunction assertNoComputeLoop(fieldPath: string) {\n _computeLoopCount++;\n\n if (_computeLoopResetTimer == null) {\n _computeLoopResetTimer = setTimeout(() => {\n _computeLoopCount = 0;\n _computeLoopResetTimer = undefined;\n }, 0);\n }\n if (_computeLoopCount > COMPUTE_LOOP_MAX) {\n throw new Error(\n `[DynamicFormItem] Possible infinite loop detected in computedProps for field \"${fieldPath}\". `\n + `computedProps recomputed more than ${COMPUTE_LOOP_MAX} times synchronously. `\n + `Ensure value writes inside computedProps are idempotent (the same input always produces the same output).`,\n );\n }\n}\n\n// #endregion\n\n// #region Computed state\n\n// --- Path ---\n\nconst field = computed(() => {\n _analytics_fieldChangedCount++;\n return props.fieldMetadata;\n});\n\nconst path = computed(() => {\n if (!field.value?.path)\n return '';\n\n return overridePath(field.value.path, props.pathOverride);\n});\n\n// If the field has attributes, it is treated as a complex type: the user-visible value lives\n// at a nested property (e.g. `path['value']`) instead of directly at `path`.\nconst isComplexType = computed(() => field.value?.isComplexType || field.value?.attributes?.length);\n\n// The path vee-validate binds to. For complex types we append the value property key\n// using bracket notation so segment counting by '.' still works correctly.\nconst itemPath = computed(() => {\n let _path = path.value;\n if (isComplexType.value && _path) {\n const complexTypeValueProperty = settings?.value?.complexTypeValueProperty ?? 'value';\n _path = `${_path}['${complexTypeValueProperty}']`;\n }\n return _path;\n});\n\nconst normalizedPath = computed(() => normalizePath(itemPath.value));\n\nconst isArray = computed(() => {\n if (props.isArrayOverride === 'array')\n return true;\n\n if (props.isArrayOverride === 'single')\n return false;\n\n return (field.value?.maxOccurs ?? 1) > 1;\n});\n\n// --- Vee-Validate field context ---\n\n// Initialized empty; populated by the watchEffect below.\n// This indirection breaks a circular dependency:\n// combinedValidation → computedField → value → fieldContext → combinedValidation\nconst combinedValidation = ref<GenericValidateFunction[]>([]);\n\nconst fieldContext = !isArray.value\n ? useField(normalizedPath, combinedValidation, {\n ...(field.value?.fieldOptions ?? {}),\n validateOnValueUpdate: false, // validation timing is owned by this component\n }) as FieldContext\n : { value: ref(undefined) } as FieldContext;\n\nconst value = fieldContext.value;\n\n// Lazily evaluated — only computed when accessed, safe to use on deep field trees.\nfieldContext.hasValue = computed(() => checkTreeHasValue(value.value));\n\n// Apply the global validateOnBlur setting when shouldValidate is not explicitly provided.\nconst originalHandleBlur = fieldContext.handleBlur;\nfieldContext.handleBlur = function (e?: Event | undefined, shouldValidate?: boolean | undefined) {\n shouldValidate = shouldValidate ?? settings?.value?.validateOnBlur;\n originalHandleBlur(e, shouldValidate);\n emits('blur', e, shouldValidate); // lets array fields know when a blur occurred\n};\n\n// Validation is handled in the value watcher; only pass through when explicitly requested.\nconst originalHandleChange = fieldContext.handleChange;\nfieldContext.handleChange = function (e: unknown, shouldValidate?: boolean | undefined) {\n originalHandleChange(e, shouldValidate === true);\n};\n\n// --- Field type flags ---\n\nconst isParent = computed(() => !!field.value?.children?.length);\nconst isChoice = computed(() => !!field.value?.choice?.length);\n// An input is any leaf field — not a repeating array, not a branching choice, not a parent group.\nconst isInput = computed(() => !isArray.value && !isChoice.value && !isParent.value);\n\n// --- Reactive field and dynamic state ---\nconst initialUpdate = ref(true);\n\n/**\n * In case of an object, the useFieldValue() in vee-validate doesn't react on an update of a value of its children.\n * Therefore we keep track of an reactive value, that is updated by the children. That re-triggers reactivity\n */\nconst childValueReactivity = ref(0);\n\n/**\n * Stores the latest computedField of each direct child, keyed by path.\n * Updated when a child emits update:computedField and the hash differs from the stored one.\n * When accessed inside a computedProps function, changes to child computed fields will\n * reactively re-trigger the parent's computedField computation.\n */\nconst childFields = ref<Record<string, ReadOnlyFieldOf<FieldMetadata>>>({});\nconst childFieldsArray = computed(() => Object.values(childFields.value));\n\nconst computedField = computed(() => {\n _analytics_fieldComputeCount++;\n assertNoComputeLoop(path.value);\n\n if (field.value?.computeOnChildValueChange === true) {\n void childValueReactivity.value; // subscribe to child value changes\n }\n\n const _computedField = (field.value?.computedProps ?? []).reduce(\n (field, compute) => {\n // We allow to transform the field metadata reactively based on the current value. In case the value is not\n // called upon in any of the computedProps, it will not be part of the reactivity that triggers a re-compute.\n // The childFieldsArray ref is passed so computedProps can subscribe to children's computed field changes.\n compute(field, value, childFieldsArray);\n return field;\n },\n { ...field.value, path: path.value } as ComputedPropsFieldOf<FieldMetadata>,\n );\n\n // Always restore our calculated path — computedProps may read it but must not override it.\n const _internalMetadata = _computedField as InternalMetadata;\n _internalMetadata.path = path.value;\n _internalMetadata._hash = hashField(_internalMetadata);\n\n return _internalMetadata;\n});\n\n// --- Occurrence limits ---\n\n// minOccurs determines how many times this field must appear at minimum.\nconst minOccurs = computed(() => {\n if (props.minOccursOverride !== undefined)\n return props.minOccursOverride;\n\n // Array items themselves control multiplicity; individual items are always optional.\n if (props.partOfArrayField)\n return 0;\n\n return computedField.value?.minOccurs ?? 1;\n});\n\n// maxOccurs determines how many times this field may appear at maximum.\nconst maxOccurs = computed(() =>\n props.maxOccursOverride !== undefined\n ? props.maxOccursOverride\n : (computedField.value?.maxOccurs ?? 1),\n);\n\nconst disabled = computed(() => maxOccurs.value === 0);\nconst required = computed(() => minOccurs.value >= 1 && !disabled.value);\n\n// When this optional field has no value yet, propagate minOccurs=0 to children so their\n// required validation doesn't fire until the user starts filling in values.\nconst _minOccursOverride = computed(() => {\n // If an ancestor already set the override to 0, keep propagating it.\n if (props.minOccursOverride === 0)\n return props.minOccursOverride;\n\n // Field is required — nothing to override.\n if (minOccurs.value > 0)\n return undefined;\n\n // Field is optional but already has a value — keep children required.\n if (checkTreeHasValue(value.value))\n return undefined;\n\n // Optional field with no value: make all children optional too.\n return 0;\n});\n\n// When maxOccurs=0 (disabled), propagate the disabled state to children.\nconst _maxOccursOverride = computed(() =>\n maxOccurs.value === 0 ? 0 : undefined,\n);\n\nconst _canRemoveItems = computed(() => {\n // Array items with a value can always be removed via the × button to clear them.\n if (props.partOfArrayField && checkTreeHasValue(value.value))\n return true;\n\n return props.canRemoveItems;\n});\n\n// --- Validation helpers ---\n\nconst submitCount = useSubmitCount();\nconst shouldValidateOnValueUpdate = computed(() => {\n // Only check validateOnValueUpdateAfterSubmit when it is explicitly true; otherwise leave\n // the decision to the next check (undefined means \"defer to next rule\").\n const validateOnValueUpdateAfterSubmit = settings?.value?.validateOnValueUpdateAfterSubmit === true\n ? (submitCount.value > 0 && settings?.value?.validateOnValueUpdateAfterSubmit)\n : undefined;\n\n const validateWhenInError = settings?.value?.validateWhenInError && fieldContext?.errors.value?.length > 0\n ? true\n : undefined;\n\n // Priority: field-level option → in-error state → after-submit setting → global setting\n return field.value?.fieldOptions?.validateOnValueUpdate\n ?? validateWhenInError\n ?? validateOnValueUpdateAfterSubmit\n ?? settings?.value?.validateOnValueUpdate;\n});\n\nconst showAttributes = computed(\n () => field.value?.attributes?.length && checkTreeHasValue(value.value),\n);\n\n// #endregion\n\n// #region Watchers and lifecycle events\n\n// Build the validation array reactively so it stays in sync with field metadata and settings.\n// watchEffect (rather than computed) is used here to avoid the circular dependency described\n// at the combinedValidation declaration above.\nwatchEffect(() => {\n _analytics_constructValidationCount++;\n\n const _validations: GenericValidateFunction[] = [];\n const _restriction = field.value.restriction ?? {};\n const _messages = settings?.value?.messages;\n\n if (required.value)\n _validations.push(createValidation('xsd_required', undefined, _messages?.required));\n\n if (_restriction.minLength != null)\n _validations.push(createValidation('xsd_minLength', _restriction.minLength, _messages?.minLength));\n\n if (_restriction.maxLength != null)\n _validations.push(createValidation('xsd_maxLength', _restriction.maxLength, _messages?.maxLength));\n\n if (_restriction.length != null)\n _validations.push(createValidation('xsd_length', _restriction.length, _messages?.length));\n\n if (_restriction.pattern != null)\n _validations.push(createValidation('xsd_pattern', _restriction.pattern, _messages?.pattern));\n\n if (_restriction.minInclusive != null)\n _validations.push(createValidation('xsd_minInclusive', _restriction.minInclusive, _messages?.minInclusive));\n\n if (_restriction.maxInclusive != null)\n _validations.push(createValidation('xsd_maxInclusive', _restriction.maxInclusive, _messages?.maxInclusive));\n\n if (_restriction.minExclusive != null)\n _validations.push(createValidation('xsd_minExclusive', _restriction.minExclusive, _messages?.minExclusive));\n\n if (_restriction.maxExclusive != null)\n _validations.push(createValidation('xsd_maxExclusive', _restriction.maxExclusive, _messages?.maxExclusive));\n\n if (_restriction.enumeration != null)\n _validations.push(createValidation('xsd_enumeration', _restriction.enumeration, _messages?.enumeration));\n\n if (_restriction.whiteSpace != null)\n _validations.push(createValidation('xsd_whiteSpace', _restriction.whiteSpace, _messages?.whiteSpace));\n\n if (_restriction.fractionDigits != null)\n _validations.push(createValidation('xsd_fractionDigits', _restriction.fractionDigits, _messages?.fractionDigits));\n\n if (_restriction.totalDigits != null)\n _validations.push(createValidation('xsd_totalDigits', _restriction.totalDigits, _messages?.totalDigits));\n\n if (field.value?.validation)\n _validations.push(...splitToValidationFunctions(field.value?.validation));\n\n combinedValidation.value = _validations;\n});\n\n// Normalise empty strings to undefined (or null for array items) so the field is cleanly\n// removed from the form values object rather than left as an empty string.\n// flush: 'sync' ensures the value is corrected before any other watchers or computeds read it.\nlet _transforming = false;\nwatch(value, (newValue) => {\n if (_transforming)\n return;\n\n _transforming = true;\n if (newValue === '')\n value.value = props.partOfArrayField ? null : undefined;\n _transforming = false;\n}, {\n flush: 'sync',\n});\n\n// Notify the parent and conditionally trigger validation whenever the value changes.\n// vee-validate does not provide a built-in update event, so we implement it here.\nwatch(\n value,\n (v) => {\n _analytics_valueChangedCount++;\n\n // Only leaf inputs emit; parent/array/choice fields are updated by their children.\n if (!isInput.value)\n return;\n\n // Skip notification on the initial render if there is no value yet.\n if (!initialUpdate.value || v) {\n notifyValueUpdate();\n\n if (shouldValidateOnValueUpdate.value)\n fieldContext?.validate();\n }\n\n initialUpdate.value = false;\n },\n {\n immediate: true,\n },\n);\n\n// Emit the initial computedField after mounting (children mount before parents, so the parent\n// template listener is already in place). Then watch for hash changes to keep the parent in sync.\n// Deferring to onMounted avoids accessing computedField during setup, which would make it a\n// synchronous dep and break the infinite-loop guard test.\nonMounted(() => {\n emits('update:computedField', computedField.value);\n watch(() => computedField.value._hash, (newHash, oldHash) => {\n if (newHash === oldHash)\n return;\n emits('update:computedField', computedField.value);\n });\n});\n\nonBeforeUnmount(() => {\n if (_computeLoopResetTimer != null)\n clearTimeout(_computeLoopResetTimer);\n\n // Array items are cleaned up by useFieldArray's remove() — setting value to undefined here\n // would write back to form.values at the (now-removed) index, causing useFieldArray's sync\n // watcher to detect a mismatch and re-add the entry via initFields().\n if (props.partOfArrayField)\n return;\n\n // Attribute fields are conditionally mounted based on whether the parent has a value.\n // When unmounted, explicitly clear the value so it is removed from the form state.\n if (value.value !== undefined) {\n value.value = undefined;\n notifyValueUpdate();\n }\n});\n\n// #endregion\n\n// #region Methods\n\n/**\n * Called when a direct child (or a DynamicFormItemArray/Choice that wraps a child) emits update:computedField.\n * Only updates childFields when the child's hash has changed, so the parent's computedProps\n * that access childFields are only re-evaluated when something meaningful changed.\n * When childFields is updated, the parent's own computedField may re-run (if it accesses childFields),\n * and the watch above will emit update:computedField upward, notifying the entire ancestor chain.\n */\nfunction onChildComputedFieldUpdate(field: InternalFieldMetadata<FieldMetadata>) {\n if (!field.path)\n return;\n const existing = childFields.value[field.path] as InternalFieldMetadata<FieldMetadata>;\n if (existing?._hash === field._hash)\n return;\n childFields.value[field.path] = field as ReadOnlyFieldOf<FieldMetadata>;\n}\n\nfunction notifyValueUpdate() {\n _analytics_notifyValueUpdateCount++;\n childValueReactivity.value++;\n emits('update:modelValue', value.value);\n};\n\n// Array fields bypass useField and manage their own field array; when their value changes\n// we receive it here and write it directly so the parent can pick it up via its own watcher.\nfunction updateArrayValue(_value: unknown) {\n value.value = _value;\n emits('update:modelValue', value.value);\n};\n\n// #endregion\n</script>\n\n<template>\n <div v-if=\"settings?.analytics\" v-show=\"false\">\n <span :data-testid=\"`${path}-analytics-render-count`\">{{\n ++_analytics_renderCount\n }}</span>\n </div>\n <template v-if=\"isChoice\">\n <DynamicFormItemChoice\n v-bind=\"props\"\n :field-metadata=\"computedField\"\n\n @update:model-value=\"notifyValueUpdate\"\n @update:computed-field=\"onChildComputedFieldUpdate\"\n />\n </template>\n <template v-else-if=\"isArray\">\n <DynamicFormItemArray\n v-bind=\"props\"\n :part-of-choice-field\n :field-metadata=\"computedField\"\n\n @update:model-value=\"updateArrayValue\"\n @update:computed-field=\"onChildComputedFieldUpdate\"\n />\n </template>\n <template v-else>\n <component\n :is=\"template\"\n :type=\"partOfArrayField ? `${computedField.type}-array-item` : computedField.type\"\n :field-metadata=\"computedField\"\n :field-context\n :slot-props\n :settings\n :required\n :disabled\n :index\n :can-add-items\n :can-remove-items=\"_canRemoveItems\"\n :add-item\n :remove-item\n >\n <template #default=\"slotProps\">\n <template v-if=\"isParent\">\n <DynamicFormItem\n v-for=\"(child, index) in computedField.children\"\n :key=\"child.path\"\n :field-metadata=\"(child as InternalMetadata)\"\n :path-override=\"itemPath\"\n :index\n :template\n :slot-props\n :min-occurs-override=\"_minOccursOverride\"\n :max-occurs-override=\"_maxOccursOverride\"\n\n @update:model-value=\"notifyValueUpdate\"\n @update:computed-field=\"onChildComputedFieldUpdate\"\n />\n </template>\n <template v-if=\"!isParent\">\n <component\n :is=\"template\"\n :type=\"`${computedField.type}-input`\"\n :field-metadata=\"computedField\"\n :field-context\n :slot-props\n :settings\n :required\n :disabled\n :index\n :can-add-items\n :can-remove-items=\"_canRemoveItems\"\n :add-item\n :remove-item\n />\n </template>\n </template>\n <template #attributes=\"slotProps\">\n <template v-if=\"showAttributes\">\n <DynamicFormItem\n v-for=\"(attribute, index) in computedField.attributes\"\n :key=\"attribute.path\"\n :field-metadata=\"(attribute as InternalMetadata)\"\n :path-override=\"path\"\n :index\n :template\n :slot-props\n :min-occurs-override=\"_minOccursOverride\"\n :max-occurs-override=\"_maxOccursOverride\"\n\n @update:model-value=\"notifyValueUpdate\"\n @update:computed-field=\"onChildComputedFieldUpdate\"\n />\n </template>\n </template>\n </component>\n </template>\n</template>\n","<script lang=\"ts\" setup generic=\"Metadata extends FieldMetadata\">\nimport type { DefineComponent } from 'vue';\n\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport type { FieldMetadata } from '@/types/FieldMetadata';\nimport type { InternalFieldMetadata } from '@/types/InternalFieldMetadata';\n\nimport { computed, provide } from 'vue';\nimport DynamicFormItem from '@/components/DynamicFormItem.vue';\nimport { dynamicFormSettingsKey } from '@/types/DynamicFormSettings';\n\n// #region Interfaces\nexport interface DynamicFormProps<Metadata extends FieldMetadata> {\n /** One or more field descriptors. Pass an array for multiple top-level fields. */\n metadata: Metadata | Metadata[]\n /** A `DynamicFormTemplate`-based component that exposes the named slots used for rendering. */\n template: DefineComponent<object, object, any>\n /** Overrides for the library defaults; partial — missing keys fall back to built-in defaults. */\n settings?: DynamicFormSettings\n}\n// #endregion\n\n// #region Props and State\ndefineOptions({ name: 'DynamicForm', inheritAttrs: false });\n\nconst { settings: _settings, metadata, template } = defineProps<DynamicFormProps<Metadata>>();\n\nconst settings = computed(() => ({\n validateOnValueUpdate: true,\n validateWhenInError: true,\n ...(_settings ?? {}),\n}));\n\nprovide(dynamicFormSettingsKey, settings);\n\nconst metadataAsArray = computed(() =>\n Array.isArray(metadata) ? metadata : [metadata],\n);\n\nconst metadataWithDefaults = computed(() =>\n metadataAsArray.value?.map((x, index) => correctMetadataAndSetDefaults(x, index)) ?? [],\n);\n\n// DefineComponent doesn't carry slot shape information, so we widen the type here\n// to make the available slots known to child components at the type level.\nconst typedTemplate = computed(\n () =>\n template as DefineComponent<\n object,\n object,\n {\n default?: ((props: object) => any) | undefined\n attributes?: ((props: object) => any) | undefined\n choice?: ((props: object) => any) | undefined\n array?: ((props: object) => any) | undefined\n }\n >,\n);\n// #endregion\n\n// #region Methods\n\n/**\n * Recursively walks the metadata tree and fills in missing defaults (name, path, type, minOccurs,\n * maxOccurs) and links each node to its parent so child components can compute fully-qualified paths.\n */\nfunction correctMetadataAndSetDefaults(\n fieldMetadata: Metadata,\n index?: number,\n parent?: InternalFieldMetadata<Metadata>,\n) {\n if (!fieldMetadata)\n return fieldMetadata;\n\n const fieldName = fieldMetadata.name ?? `field-${index}`;\n const fieldPath = fieldMetadata.path ?? [parent?.path, fieldName].filter(Boolean).join('.');\n const copy: InternalFieldMetadata<Metadata> = {\n name: fieldName,\n path: fieldPath,\n type: 'text',\n minOccurs: 1,\n maxOccurs: 1,\n\n ...fieldMetadata,\n computedProps: [...(fieldMetadata.computedProps ?? [])],\n parent,\n };\n\n copy.children = (fieldMetadata.children ?? []).map((x, index) =>\n correctMetadataAndSetDefaults(x as Metadata, index, copy),\n );\n copy.choice = (fieldMetadata.choice ?? []).map((x, index) =>\n correctMetadataAndSetDefaults(x as Metadata, index, copy),\n );\n copy.attributes = (fieldMetadata.attributes ?? []).map((x, index) =>\n correctMetadataAndSetDefaults(x as Metadata, index, copy),\n );\n\n return copy;\n}\n\n// #endregion\n</script>\n\n<template>\n <DynamicFormItem\n v-for=\"fieldMetadata in metadataWithDefaults\"\n :key=\"fieldMetadata.name\"\n :template=\"typedTemplate\"\n :field-metadata=\"(fieldMetadata as InternalFieldMetadata<FieldMetadata>)\"\n />\n</template>\n","const camelizeRE = /-\\w/g;\n/**\n * Coming from vue source code\n * @private\n */\nexport const camelize: (str: string) => string = cacheStringFunction(\n (str: string): string => {\n return str.replace(camelizeRE, c => c.slice(1).toUpperCase());\n },\n);\n\nfunction cacheStringFunction<T extends (str: string) => string>(fn: T): T {\n const cache: Record<string, string> = Object.create(null);\n return ((str: string) => {\n const hit = cache[str];\n return hit || (cache[str] = fn(str));\n }) as T;\n}\n","<script\n lang=\"ts\"\n setup\n generic=\"TMetadataConfiguration extends MetadataConfiguration\"\n>\nimport type { FieldContext as _FieldContext } from 'vee-validate';\nimport type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';\nimport type { DynamicFormSettings } from '@/types/DynamicFormSettings';\nimport type { ReadOnlyFieldType } from '@/types/FieldMetadata';\nimport type { MetadataConfiguration } from '@/types/MetadataConfiguration';\nimport { computed, useAttrs } from 'vue';\nimport { camelize } from '@/utils/camelize';\n\n// #region Interfaces\n\nexport interface FieldContext<TValue = unknown> extends _FieldContext<TValue> {\n /**\n * Whether this field (or any of its descendants) has a value.\n * Lazily evaluated — only computed when accessed, so safe to use on deep field trees.\n */\n hasValue: ComputedRef<boolean>\n}\n\nexport interface DynamicFormConfigurationProps<\n TMetadataConfiguration extends MetadataConfiguration,\n> {\n /**\n * Use defineMetadata to create a strongly-typed metadata configuration.\n * This metadata configuration can be provided here to type the DynamicFormTemplate component.\n */\n metadataConfiguration: TMetadataConfiguration\n}\n\nexport interface LimitedFieldContext<TValue = unknown> {\n value: ComputedRef<TValue>\n errors: Ref<string[]>\n errorMessage: Ref<string | undefined>\n label?: MaybeRefOrGetter<string | undefined>\n}\n\n/**\n * Props passed to the template component by the library internals.\n * Defined as an interface (rather than actual props) so they don't appear in the\n * public prop signature of the user-facing DynamicFormTemplate component.\n */\nexport interface Attributes<\n TMetadataConfiguration extends MetadataConfiguration,\n> {\n type: TMetadataConfiguration['fieldTypes'][number] | 'default' | 'default-array' | 'default-array-item' | 'default-choice'\n /** The metadata you configured for this field. */\n fieldMetadata: ReadOnlyFieldType<\n TMetadataConfiguration['fieldTypes'][number],\n TMetadataConfiguration['extendedProperties']\n >\n /** Whether the field is required. */\n required: boolean\n /** Whether the field is disabled (maxOccurs = 0). */\n disabled: boolean\n /** The position of this item within its parent, that can be its position in the children or choice collection or its index in an array field. */\n index: number\n /**\n * Whether a new array item can be added.\n * False when the current count has already reached maxOccurs.\n */\n canAddItems: boolean\n /**\n * Whether an array item can be removed.\n * False when the current count has already reached minOccurs.\n */\n canRemoveItems: boolean\n /** Adds a new item to the parent array field. */\n addItem: () => void\n /** Removes this item from the parent array field. */\n removeItem: () => void\n /**\n * The user defined properties that are passed between templates by adding attributes on the <slot /> elements.\n * With these properties you can set values that can be read by components \"living\" further down the tree.\n */\n slotProps: TMetadataConfiguration['slotProperties']\n /**\n * The form settings\n */\n settings: DynamicFormSettings<TMetadataConfiguration['extendedSettingsProperties']>\n}\n\nexport interface ItemAttributes<\n TMetadataConfiguration extends MetadataConfiguration,\n FieldType extends string = string,\n> extends Attributes<TMetadataConfiguration> {\n /**\n * The extended vee-validate field context from useField.\n * Includes a `hasValue` computed that is true when this field or any descendant has a value.\n */\n fieldContext: FieldContext<FieldType extends keyof TMetadataConfiguration['valueTypes']\n ? TMetadataConfiguration['valueTypes'][FieldType]\n : unknown>\n}\n\nexport interface ArrayChoiceAttributes<\n TMetadataConfiguration extends MetadataConfiguration,\n> extends Attributes<TMetadataConfiguration> {\n fieldContext: LimitedFieldContext<unknown[]>\n}\n\ntype Props = DynamicFormConfigurationProps<TMetadataConfiguration>;\ntype SlotProps<FieldType extends string = string> = ItemAttributes<TMetadataConfiguration, FieldType>;\ntype ArrayChoiceSlotProps = ArrayChoiceAttributes<TMetadataConfiguration>;\n\ntype SlotsFromMetadata = {\n // Fallback slot for field types that don't have a dedicated slot.\n default: (props: SlotProps) => any\n} & {\n // Fallback slot for input components that don't have a dedicated slot.\n 'default-input': (props: SlotProps) => any\n} & {\n // Fallback slot for components that are array's but don't have a dedicated slot.\n 'default-array': (props: ArrayChoiceSlotProps) => any\n} & {\n // Fallback slot for components that are array items but don't have a dedicated slot.\n 'default-array-item': (props: SlotProps) => any\n} & {\n // Fallback slot for components that are choice fields but don't have a dedicated slot.\n 'default-choice': (props: ArrayChoiceSlotProps) => any\n} & {\n // One slot per field type defined in the metadata configuration.\n [K in TMetadataConfiguration['fieldTypes'][number]]: (props: SlotProps<K>) => any;\n} & {\n // One input slot per field type (e.g. \"text-input\") for rendering just the inner control.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-input`]: (props: SlotProps<K extends `${infer FieldType}-input` ? FieldType : never>) => any;\n} & {\n // One array slot per field type (e.g. \"text-array\") for defining how to render the type when it is an array.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-array`]: (props: ArrayChoiceSlotProps) => any;\n} & {\n // One array item slot per field type (e.g. \"text-array-item\") for defining how to render the type when it is an array item.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-array-item`]: (props: SlotProps<K extends `${infer FieldType}-input` ? FieldType : never>) => any;\n} & {\n // One choice slot per field type (e.g. \"text-choice\") for defining how to render the type when it is a choice.\n [K in `${TMetadataConfiguration['fieldTypes'][number]}-choice`]: (props: ArrayChoiceSlotProps) => any;\n};\n\n// #endregion\n\n// #region State\ndefineOptions({ name: 'DynamicFormTemplate', inheritAttrs: false });\ndefineProps<Props>();\nconst slots = defineSlots<SlotsFromMetadata>();\n\n// Attributes are passed in as kebab-case HTML attributes by Vue; convert them to camelCase\n// so slot consumers receive consistent camelCase props regardless of how they were bound.\nconst rawAttrs = useAttrs();\nconst attrs = computed(() => {\n const result: Record<string, any> = {};\n for (const [key, value] of Object.entries(rawAttrs)) {\n result[camelize(key)] = value;\n }\n return result as unknown as SlotProps;\n});\n\ntype RegularSlotName = keyof SlotsFromMetadata;\n\n// Resolve which slot to render: prefer a dedicated per-type slot, fall back to\n// 'default-input' for input variants, and finally to 'default' for everything else.\nconst typeWithFallback = computed((): RegularSlotName => {\n const type = attrs.value.type;\n if (type && slots[type as RegularSlotName]) {\n return type as RegularSlotName;\n }\n\n if (type?.endsWith('-input')) {\n return slots['default-input'] ? 'default-input' : 'default';\n }\n if (type?.endsWith('-array')) {\n return slots['default-array'] ? 'default-array' : 'default';\n }\n if (type?.endsWith('-array-item')) {\n return slots['default-array-item'] ? 'default-array-item' : 'default';\n }\n if (type?.endsWith('-choice')) {\n return slots['default-choice'] ? 'default-choice' : 'default';\n }\n return 'default';\n});\n\n// #endregion\n</script>\n\n<template>\n <template v-if=\"attrs.fieldMetadata\">\n <slot v-if=\"attrs.type?.endsWith('-array')\" :name=\"typeWithFallback\" v-bind=\"(attrs as unknown as ArrayChoiceSlotProps)\" />\n <slot v-else-if=\"attrs.type?.endsWith('-choice')\" :name=\"typeWithFallback\" v-bind=\"(attrs as unknown as ArrayChoiceSlotProps)\" />\n <slot v-else :name=\"typeWithFallback\" v-bind=\"attrs\" />\n </template>\n</template>\n","/**\n * Creates a typed metadata configuration for use with `DynamicFormTemplate`.\n *\n * The returned object is a pure type carrier — its runtime values are empty stubs.\n * TypeScript uses it to infer slot names, `fieldContext.value` types, extended field properties,\n * and the shape of `slotProps`. A `default` field type is always injected automatically.\n *\n * @typeParam FieldValueTypes - Map of field type names to their `fieldContext.value` types.\n * Use `never` for display-only types (headings, separators) that hold no value.\n * @typeParam ExtendedFieldProperties - Extra properties merged into every `FieldMetadata` object.\n * @typeParam SlotProperties - Shape of `slotProps` passed from parent slots to child slots.\n * @typeParam ExtendedSettingsProperties - Extra properties merged into `Settings` object.\n * @example\n * const config = defineMetadata<\n * {\n * text: string;\n * checkbox: boolean;\n * age: number;\n * address: { street: string; city: string };\n * heading: never;\n * },\n * {\n * // This will add a label and options property to each field's metadata\n * label?: string;\n * options?: Array<{ key: string; value: string }>;\n * },\n * {\n * // This will add allow you to pass hideLabel and depth through the slots\n * hideLabel?: boolean;\n * depth?: number;\n * },\n * {\n * // This will add a showOptionalOrRequired property to the settings object\n * showOptionalOrRequired?: 'optional' | 'required';\n * }\n * >();\n */\nexport function defineMetadata<\n const FieldValueTypes extends Record<string, any>,\n ExtendedFieldProperties extends object = object,\n SlotProperties extends object = object,\n ExtendedSettingsProperties extends object = object,\n>() {\n type IncludeFields = 'default';\n\n type FieldTypeMetadata\n = | keyof FieldValueTypes\n | IncludeFields;\n\n // Value types are directly from the generic parameter, default is always included and always a string\n type ValueTypeMap = FieldValueTypes & {\n default: string\n };\n\n return {\n fieldTypes: Object.keys({} as FieldValueTypes) as unknown as readonly FieldTypeMetadata[],\n extendedProperties: {} as ExtendedFieldProperties,\n slotProperties: {} as SlotProperties,\n extendedSettingsProperties: {} as ExtendedSettingsProperties,\n valueTypes: {} as ValueTypeMap,\n };\n}\n","import type { FormValidationResult, GenericObject, Path } from 'vee-validate';\nimport type { InjectionKey } from 'vue';\nimport { FormContextKey } from 'vee-validate';\nimport { getCurrentInstance, inject } from 'vue';\n\ntype FormCtx = typeof FormContextKey extends InjectionKey<infer T> ? T : never;\n\nfunction getFormContext(): FormCtx | undefined {\n // When called in the same component as useDynamicForm, inject() looks at the parent's provides\n // and won't find the context that useForm() just provided on the current instance.\n // So we check the current instance's own provides first, then fall back to inject for child-component usage.\n const instance = getCurrentInstance();\n const ownProvides = (instance as any)?.provides as Record<symbol, unknown> | undefined;\n if (ownProvides && (FormContextKey as symbol) in ownProvides)\n return ownProvides[FormContextKey as symbol] as FormCtx;\n\n return inject(FormContextKey);\n}\n\n/**\n * Provides `validateSection` for partial form validation (e.g. wizard steps).\n *\n * Must be called in the same component as `useDynamicForm()` or in a descendant.\n * When called in the same component, it reads the form context from the current instance's\n * own provides rather than via `inject`, because `inject` looks at the *parent's* provides\n * and would miss a `useForm()` call made on the current instance.\n */\nexport function useValidatePartialForm() {\n const form = getFormContext()!;\n\n /**\n * Validates all vee-validate fields whose path equals or starts with `sectionPath`.\n * Matches `sectionPath` itself, `sectionPath.child`, and `sectionPath[0]` — but not\n * unrelated paths that happen to share a prefix string.\n *\n * @param sectionPath - Dot-notated path prefix (e.g. `'address'` or `'steps[0]'`)\n * @returns A `FormValidationResult` shaped identically to vee-validate's `validate()` return value,\n * scoped to the matched fields only.\n */\n async function validateSection(sectionPath: string): Promise<FormValidationResult<GenericObject>> {\n const fieldPaths = form.getAllPathStates()\n .map(state => state.path)\n .filter(path => path === sectionPath\n || path.startsWith(`${sectionPath}.`)\n || path.startsWith(`${sectionPath}[`));\n\n const validationResults = await Promise.all(\n fieldPaths.map(async path => ({\n path,\n result: await form.validateField(path as Path<GenericObject>),\n })),\n );\n\n const results = Object.fromEntries(\n validationResults.map(({ path, result }) => [path, result]),\n ) as FormValidationResult<GenericObject>['results'];\n\n const errors = Object.fromEntries(\n validationResults\n .filter(({ result }) => !result.valid)\n .map(({ path, result }) => [path, result.errors[0] ?? '']),\n ) as FormValidationResult<GenericObject>['errors'];\n\n return {\n valid: validationResults.every(({ result }) => result.valid),\n results,\n errors,\n source: 'fields',\n };\n }\n\n return { validateSection };\n}\n","import type {\n FlattenAndSetPathsType,\n FormContext,\n GenericObject,\n Path,\n PathValue,\n FormOptions as VeeFormOptions,\n} from 'vee-validate';\nimport type { MaybeRef, MaybeRefOrGetter, Ref } from 'vue';\nimport {\n useFieldValue as _useFieldValue,\n useForm,\n} from 'vee-validate';\nimport { useValidatePartialForm } from '@/core/useValidatePartialForm';\n\n/** Options forwarded directly to vee-validate's `useForm()`. */\nexport interface FormOptions<TValues extends GenericObject> {\n initialValues?: VeeFormOptions<TValues>['initialValues']\n initialErrors?: FlattenAndSetPathsType<TValues, string | undefined>\n initialTouched?: FlattenAndSetPathsType<TValues, boolean>\n validateOnMount?: boolean\n keepValuesOnUnmount?: MaybeRef<boolean>\n name?: string\n}\n\n/**\n * Typed wrapper around vee-validate's `useForm()`. Adds:\n * - `useFieldValue(path)` — path-aware field value accessor with full `TValues` type inference,\n * avoiding the need to manually cast `PathValue`.\n * - `validateSection(path)` — validates only the fields registered under the given path prefix,\n * useful for multi-step wizard validation.\n */\nexport function useDynamicForm<TValues extends GenericObject = GenericObject>(opts?: FormOptions<TValues>): FormContext<TValues> & {\n useFieldValue: <TPath extends Path<TValues>>(path?: MaybeRefOrGetter<TPath>) => Ref<PathValue<TValues, TPath>>\n validateSection: ReturnType<typeof useValidatePartialForm>['validateSection']\n} {\n const useFieldValue = <TPath extends Path<TValues>>(path?: MaybeRefOrGetter<TPath>) => {\n return _useFieldValue<PathValue<TValues, TPath>>(path);\n };\n\n const form = useForm<TValues>(opts);\n const { validateSection } = useValidatePartialForm();\n\n return {\n ...form,\n useFieldValue,\n validateSection,\n };\n}\n","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"],"names":["useFieldArrayExtended","arrayPath","fields","originalFieldArray","useFieldArray","values","computed","value","dynamicFormSettingsKey","getSingleParam","params","paramName","isEmpty","maxLengthValidator","length","val","maxValueValidator","max","minValidator","minValueValidator","min","oneOfValidator","list","item","regexValidator","regex","checkTreeHasValue","element","resolveMessage","message","ctx","_","key","index","defineRule","min_value","max_value","one_of","mode","str","digits","decimalIndex","ruleParamNames","getFieldLabel","createValidation","rule","param","customMessage","fieldName","validateOptions","normalizedCtx","result","validate","normalizePath","path","overridePath","overrideWithPath","parentSegments","childSegments","splitToValidationFunctions","userRules","props","__props","emits","__emit","settings","inject","_analytics_renderCount","field","normalizedPath","useValidateField","remove","push","update","replace","minOccurs","maxOccurs","disabled","required","_maxOccursOverride","_canAddItems","_canRemoveItems","combinedValidation","_validations","_messages","label","errors","errorMessage","handleBlur","useField","fieldContext","submitCount","useSubmitCount","firstValueSet","ref","shouldValidateOnValueUpdate","validateOnValueUpdateAfterSubmit","validateWhenInError","watch","v","watchEffect","_addItem","_removeItem","x","i","guardAndNotifyItemUpdate","_unref","_createElementBlock","_hoisted_1","_createElementVNode","_toDisplayString","_isRef","_hoisted_2","_openBlock","_createBlock","_resolveDynamicComponent","_withCtx","slotProps","_Fragment","_renderList","arrayIndex","DynamicFormItem","$event","_cache","closestPath","_minOccursOverride","childrenAreArrays","childValues","singleChild","occurrences","_occurrences","_maxOccurs","child","choiceOccurrences","choiceValuesCount","totalChoiceOccurrences","acc","othersAsChildOccurrences","totalChildOccurrences","valuesCount","c","_field","updateChildValue","childIndex","maxOccurrences","skipCalculations","calculateValues","childValue","hashField","_name","_path","_children","_choice","_attributes","_fieldOptions","_computedProps","_prevHash","_parent","_isComplexType","_computeOnChildValueChange","mutableProps","sorted","a","b","COMPUTE_LOOP_MAX","_computeLoopCount","_computeLoopResetTimer","assertNoComputeLoop","fieldPath","isComplexType","itemPath","complexTypeValueProperty","isArray","originalHandleBlur","e","shouldValidate","originalHandleChange","isParent","isChoice","isInput","initialUpdate","childValueReactivity","childFields","childFieldsArray","computedField","_internalMetadata","compute","showAttributes","_restriction","_transforming","newValue","notifyValueUpdate","onMounted","newHash","oldHash","onBeforeUnmount","onChildComputedFieldUpdate","updateArrayValue","_value","DynamicFormItemChoice","_mergeProps","DynamicFormItemArray","_component_DynamicFormItem","attribute","provide","metadataAsArray","metadataWithDefaults","correctMetadataAndSetDefaults","typedTemplate","fieldMetadata","parent","copy","camelizeRE","camelize","cacheStringFunction","fn","cache","slots","_useSlots","rawAttrs","useAttrs","attrs","typeWithFallback","type","_renderSlot","_ctx","_normalizeProps","defineMetadata","getFormContext","ownProvides","getCurrentInstance","FormContextKey","useValidatePartialForm","form","validateSection","sectionPath","fieldPaths","state","validationResults","results","useDynamicForm","opts","useFieldValue","_useFieldValue","useForm","mapEachMetadataItem","metadata","callbackFunc"],"mappings":"8DAQO,SAASA,GAAsBC,EAAqC,CACzE,KAAM,CAAE,OAAAC,EAAQ,GAAGC,CAAA,EAAuBC,EAAAA,cAAcH,CAAS,EAC3DI,EAASC,WAAS,IAAMJ,EAAO,MAAM,IAAI,CAAC,CAAE,MAAAK,KAAYA,CAAK,CAAC,EAEpE,MAAO,CACL,OAAAL,EACA,OAAAG,EACA,GAAGF,CAAA,CAEP,CCfO,MAAMK,EAAyB,OAAO,qBAAqB,ECFlE;AAAA;AAAA;AAAA;AAAA,IAoHA,SAASC,EAAeC,EAAQC,EAAW,CACvC,OAAO,MAAM,QAAQD,CAAM,EAAIA,EAAO,CAAC,EAAIA,EAAOC,CAAS,CAC/D,CACA,SAASC,EAAQL,EAAO,CAIpB,MAHI,GAAAA,GAAU,MAA+BA,IAAU,IAGnD,MAAM,QAAQA,CAAK,GAAKA,EAAM,SAAW,EAIjD,CAoNA,MAAMM,GAAqB,CAACN,EAAOG,IAAW,CAC1C,GAAIE,EAAQL,CAAK,EACb,MAAO,GAEX,MAAMO,EAASL,EAAeC,EAAQ,QAAQ,EAC9C,OAAI,MAAM,QAAQH,CAAK,EACZA,EAAM,MAAMQ,GAAOF,GAAmBE,EAAK,CAAE,OAAAD,CAAM,CAAE,CAAC,EAE1D,CAAC,GAAG,OAAOP,CAAK,CAAC,EAAE,QAAU,OAAOO,CAAM,CACrD,EAEME,GAAoB,CAACT,EAAOG,IAAW,CACzC,GAAIE,EAAQL,CAAK,EACb,MAAO,GAEX,MAAMU,EAAMR,EAAeC,EAAQ,KAAK,EACxC,OAAI,MAAM,QAAQH,CAAK,EACZA,EAAM,OAAS,GAAKA,EAAM,MAAMQ,GAAOC,GAAkBD,EAAK,CAAE,IAAAE,CAAG,CAAE,CAAC,EAE1E,OAAOV,CAAK,GAAK,OAAOU,CAAG,CACtC,EAwBMC,GAAe,CAACX,EAAOG,IAAW,CACpC,GAAIE,EAAQL,CAAK,EACb,MAAO,GAEX,MAAMO,EAASL,EAAeC,EAAQ,QAAQ,EAC9C,OAAI,MAAM,QAAQH,CAAK,EACZA,EAAM,MAAMQ,GAAOG,GAAaH,EAAK,CAAE,OAAAD,CAAM,CAAE,CAAC,EAEpD,CAAC,GAAG,OAAOP,CAAK,CAAC,EAAE,QAAU,OAAOO,CAAM,CACrD,EAEMK,GAAoB,CAACZ,EAAOG,IAAW,CACzC,GAAIE,EAAQL,CAAK,EACb,MAAO,GAEX,MAAMa,EAAMX,EAAeC,EAAQ,KAAK,EACxC,OAAI,MAAM,QAAQH,CAAK,EACZA,EAAM,OAAS,GAAKA,EAAM,MAAMQ,GAAOI,GAAkBJ,EAAK,CAAE,IAAAK,CAAG,CAAE,CAAC,EAE1E,OAAOb,CAAK,GAAK,OAAOa,CAAG,CACtC,EAEMC,GAAiB,CAACd,EAAOe,IACvBV,EAAQL,CAAK,EACN,GAEP,MAAM,QAAQA,CAAK,EACZA,EAAM,MAAMQ,GAAOM,GAAeN,EAAKO,CAAI,CAAC,EAEhD,MAAM,KAAKA,CAAI,EAAE,KAAKC,GAClBA,GAAQhB,CAClB,EA0BCiB,GAAiB,CAACjB,EAAOG,IAAW,CACtC,GAAIE,EAAQL,CAAK,EACb,MAAO,GAEX,IAAIkB,EAAQhB,EAAeC,EAAQ,OAAO,EAI1C,OAHI,OAAOe,GAAU,WACjBA,EAAQ,IAAI,OAAOA,CAAK,GAExB,MAAM,QAAQlB,CAAK,EACZA,EAAM,MAAMQ,GAAOS,GAAeT,EAAK,CAAE,MAAAU,CAAK,CAAE,CAAC,EAErDA,EAAM,KAAK,OAAOlB,CAAK,CAAC,CACnC,EC5bO,SAASmB,EAAkBC,EAA2B,CAC3D,OAAIA,GAAY,KACP,GAGL,MAAM,QAAQA,CAAO,EAChBA,EAAQ,KAAMpB,GAAmBmB,EAAkBnB,CAAK,CAAC,EAE9D,OAAOoB,GAAY,SACd,OAAO,OAAOA,CAAO,EAAE,KAAMpB,GAAmBmB,EAAkBnB,CAAK,CAAC,EAG1E,EACT,CCJO,SAASqB,GAAeC,EAA4BC,EAA8BpB,EAAsD,CAC7I,OAAI,OAAOmB,GAAY,WACdA,EAAQC,CAAG,EACbD,EAAQ,QAAQ,aAAc,CAACE,EAAGC,IAAQ,CAE/C,GAAIA,KAAOF,EACT,OAAO,OAAQA,EAAYE,CAAG,CAAC,EAEjC,GAAItB,GAAU,CAAC,MAAM,QAAQA,CAAM,GAAKsB,KAAOtB,EAC7C,OAAO,OAAOA,EAAOsB,CAAG,CAAC,EAE3B,MAAMC,EAAQ,OAAOD,CAAG,EACxB,OAAK,OAAO,MAAMC,CAAK,EAMnBH,EAAI,MAAM,QAAU,CAAC,MAAM,QAAQA,EAAI,KAAK,MAAM,EAC7C,OAAOA,EAAI,KAAK,OAAOE,CAAG,GAAK,IAAIA,CAAG,GAAG,EAC3C,IAAIA,CAAG,IAPR,MAAM,QAAQtB,CAAM,GAAKA,EAAOuB,CAAK,IAAM,OACtC,OAAOvB,EAAOuB,CAAK,CAAC,EACtB,OAAQH,EAAI,MAAM,SAAuBG,CAAK,GAAK,IAAID,CAAG,GAAG,CAMxE,CAAC,CACH,CCfAE,EAAAA,WAAW,eAAmC3B,GAAmBA,GAAU,MAA+BA,IAAU,EAAE,EAGtH2B,EAAAA,WAAW,gBAAmC,CAAC3B,EAAgB,CAACa,CAAG,IAC5D,MAAM,QAAQb,CAAK,EAEjBA,EAAM,OAAOmB,CAAiB,EAAE,QAAU,OAAON,CAAG,EADlD,OAAOA,CAAG,GAAK,CAEzB,EAGDc,EAAAA,WAAW,sBAAyC,IAG3C,EACR,EAGDA,EAAAA,WAAW,gBAAmCd,EAAG,EACjDc,EAAAA,WAAW,gBAAmCjB,EAAG,EAGjDiB,EAAAA,WAAW,aAAgC,CAAC3B,EAAgB,CAACO,CAAM,IAC7DP,GAAU,MAA+BA,IAAU,GAC9C,GACF,OAAOA,CAAK,EAAE,SAAW,OAAOO,CAAM,CAC9C,EAGDoB,EAAAA,WAAW,cAAiCT,EAAK,EAGjDS,EAAAA,WAAW,mBAAsCC,EAAS,EAC1DD,EAAAA,WAAW,mBAAsCE,EAAS,EAG1DF,EAAAA,WAAW,mBAAsC,CAAC3B,EAAgB,CAACa,CAAG,IAChEb,GAAU,MAA+BA,IAAU,GAC9C,GACF,OAAOA,CAAK,EAAI,OAAOa,CAAG,CAClC,EACDc,EAAAA,WAAW,mBAAsC,CAAC3B,EAAgB,CAACU,CAAG,IAChEV,GAAU,MAA+BA,IAAU,GAC9C,GACF,OAAOA,CAAK,EAAI,OAAOU,CAAG,CAClC,EAGDiB,EAAAA,WAAW,kBAAqCG,EAAM,EAItDH,EAAAA,WAAW,iBAAoC,CAAC3B,EAAgB,CAAC+B,CAAI,IAAgB,CACnF,GAAI/B,GAAU,MAA+BA,IAAU,GACrD,MAAO,GACT,MAAMgC,EAAM,OAAOhC,CAAK,EACxB,OAAI+B,IAAS,UACJ,CAAC,WAAW,KAAKC,CAAG,EACzBD,IAAS,WACJC,IAAQA,EAAI,KAAA,GAAU,CAAC,SAAS,KAAKA,CAAG,EAC1C,EACT,CAAC,EAGDL,EAAAA,WAAW,qBAAwC,CAAC3B,EAAgB,CAACiC,CAAM,IAAgB,CACzF,GAAIjC,GAAU,MAA+BA,IAAU,GACrD,MAAO,GACT,MAAMkC,EAAe,OAAOlC,CAAK,EAAE,QAAQ,GAAG,EAC9C,OAAIkC,IAAiB,GACZ,GACF,OAAOlC,CAAK,EAAE,OAASkC,EAAe,GAAK,OAAOD,CAAM,CACjE,CAAC,EAGDN,EAAAA,WAAW,kBAAqC,CAAC3B,EAAgB,CAACiC,CAAM,IAClEjC,GAAU,MAA+BA,IAAU,GAC9C,IACW,OAAOA,CAAK,EAAE,QAAQ,KAAM,EAAE,EAAE,QAAQ,IAAK,EAAE,EAAE,QAAQ,MAAO,EAAE,GAAK,KACxE,QAAU,OAAOiC,CAAM,CAC3C,EAMM,MAAME,GAA0D,CACrE,cAAe,MACf,oBAAqB,MACrB,cAAe,SACf,cAAe,SACf,WAAY,SACZ,YAAa,UACb,iBAAkB,MAClB,iBAAkB,MAClB,iBAAkB,MAClB,iBAAkB,MAClB,eAAgB,OAChB,mBAAoB,SACpB,gBAAiB,QACnB,EC1GO,SAASC,GAAcb,EAAsC,CAClE,OAAOA,EAAI,OAASA,EAAI,OAASA,EAAI,MAAQ,EAC/C,CCHO,SAASc,EAAiBC,EAAsBC,EAAiBC,EAAmC,CAEzG,MAAMpC,EAAY+B,GAAeG,CAAI,EAC/BnC,EAAkCoC,IAAU,OAC9C,CAAE,EAAGA,EAAO,GAAInC,EAAY,CAAE,CAACA,CAAS,EAAGmC,CAAA,EAAU,CAAA,CAAC,EACtD,CAAA,EACJ,MAAO,OAAOvC,EAAgBuB,IAAiC,CAC7D,MAAMkB,EAAYL,GAAcb,CAAG,EAC7BmB,EAAkBD,EAAY,CAAE,KAAMA,GAAc,OACpDE,EAAgBF,GAAalB,EAAI,QAAUkB,EAC7C,CAAE,GAAGlB,EAAK,MAAOkB,CAAA,EACjBlB,EAEEqB,EAAS,MAAMC,EAAAA,SACnB7C,EACAuC,IAAU,OAAY,CAAE,CAACD,CAAI,EAAGC,GAAUD,EAC1CI,CAAA,EAEF,OAAIE,EAAO,MACF,GACFJ,EAAgBnB,GAAemB,EAAeG,EAAexC,CAAM,EAAIyC,EAAO,OAAO,CAAC,CAC/F,CACF,CCvBO,SAASE,GAAcC,EAAc,CAC1C,OAAOA,GAAM,WAAW,uBAAwB,KAAK,GAAK,EAC5D,CCEO,SAASC,GAAaD,EAAcE,EAAsC,CAC/E,GAAI,CAACF,GAAQ,CAACE,EACZ,OAAOF,EAGT,MAAMG,EAAiBD,EAAiB,MAAM,GAAG,GAAK,CAAA,EAChDE,EAAgBJ,EAAK,MAAM,GAAG,GAAK,CAAA,EACzC,QAASrB,EAAQ,EAAGA,EAAQwB,EAAe,OAAQxB,IACjDyB,EAAczB,CAAK,EAAIwB,EAAexB,CAAK,EAE7C,OAAOyB,EAAc,KAAK,GAAG,CAC/B,CCXO,SAASC,GAA2BC,EACjB,CACxB,OAAKA,EAED,OAAOA,GAAc,WAChB,CAACA,CAAS,EACf,MAAM,QAAQA,CAAS,EAClBA,EAAU,QAAQD,EAA0B,EAEjD,OAAOC,GAAc,SAChBA,EAAU,MAAM,GAAG,EAAE,IAAIf,GAAQ,MAAOtC,EAAgBuB,IAAiC,CAC9F,MAAMkB,EAAYL,GAAcb,CAAG,EAC7BqB,EAAS,MAAMC,EAAAA,SAAS7C,EAAOsC,EAAMG,EAAY,CAAE,KAAMA,CAAA,EAAc,MAAS,EACtF,OAAOG,EAAO,MAAQ,GAAOA,EAAO,OAAO,CAAC,CAC9C,CAAC,EAII,OAAO,QAAQS,CAAS,EAAE,IAAI,CAAC,CAAC5B,EAAKjB,CAAG,IAAM,MAAOR,EAAgBuB,IAAiC,CAC3G,MAAMkB,EAAYL,GAAcb,CAAG,EAC7BqB,EAAS,MAAMC,EAAAA,SAAS7C,EAAO,CAAE,CAACyB,CAAG,EAAGjB,CAAA,EAAOiC,EAAY,CAAE,KAAMA,CAAA,EAAc,MAAS,EAChG,OAAOG,EAAO,MAAQ,GAAOA,EAAO,OAAO,CAAC,CAC9C,CAAC,EAnBQ,CAAA,CAoBX,yeCRA,MAAMU,EAAQC,EACRC,EAAQC,EACRC,EAAWC,EAAAA,OAAyC1D,CAAsB,EAMhF,IAAI2D,EAAyB,EAS7B,MAAMC,EAAQ9D,EAAAA,SAAS,IAEduD,EAAM,aACd,EAEKP,EAAOhD,EAAAA,SAAS,IACf8D,EAAM,OAAO,KAGXb,GAAaa,EAAM,MAAM,KAAMP,EAAM,YAAY,EAF/C,EAGV,EAEKQ,EAAiB/D,EAAAA,SAAS,IAAM+C,GAAcC,EAAK,KAAK,CAAC,EAIzDF,EAAWkB,EAAAA,iBAAiBD,CAAc,EAC1C,CAAE,OAAAE,EAAQ,KAAAC,EAAM,OAAAtE,EAAQ,OAAAuE,EAAQ,OAAApE,EAAQ,QAAAqE,CAAA,EAAY1E,GAAsBqE,CAAc,EAKxFM,EAAYrE,EAAAA,SAAS,IACzBuD,EAAM,oBAAsB,OACxBA,EAAM,kBACLO,EAAM,OAAO,WAAa,CAAA,EAI3BQ,EAAYtE,EAAAA,SAAS,IACzBuD,EAAM,oBAAsB,OACxBA,EAAM,kBACLO,EAAM,OAAO,WAAa,CAAA,EAG3BS,EAAWvE,EAAAA,SAAS,IAAMsE,EAAU,QAAU,CAAC,EAC/CE,EAAWxE,EAAAA,SAAS,IAAMqE,EAAU,OAAS,GAAK,CAACE,EAAS,KAAK,EAGjEE,EAAqBzE,EAAAA,SAAS,IAClCsE,EAAU,QAAU,EAAI,EAAI,CAAA,EAGxBI,EAAe1E,EAAAA,SAAS,IAAMsE,EAAU,MAAQ1E,EAAO,OAAO,MAAM,EACpE+E,EAAkB3E,EAAAA,SAAS,IAE3BuD,EAAM,mBAINO,EAAM,OAAO,mBAAqB,GAC7BlE,EAAO,OAAO,OAAS,EAGzBA,EAAO,OAAO,OAASyE,EAAU,OAASzE,EAAO,OAAO,OAAS,CACzE,EAMKgF,EAAqB5E,EAAAA,SAAoC,IAAM,CAGnE,MAAM6E,EAA0C,CAAA,EAC1CC,EAAYnB,GAAU,OAAO,SAEnC,OAAIa,EAAS,OACXK,EAAa,KAAKvC,EAAiB,gBAAiB+B,EAAU,MAAOS,GAAW,SAAS,CAAC,EAExFhB,EAAM,OAAO,YACfe,EAAa,KAAK,GAAGxB,GAA2BS,EAAM,OAAO,UAAU,CAAC,EAEnEe,CACT,CAAC,EAEK,CAAE,MAAAE,EAAO,OAAAC,EAAQ,aAAAC,EAAc,WAAAC,GAAeC,EAAAA,SAASpB,EAAgBa,EAAoB,CAC/F,GAAId,EAAM,OAAO,cAAgB,CAAA,EACjC,sBAAuB,EAAA,CACxB,EACKsB,EAAoC,CAAE,MAAAL,EAAO,OAAAC,EAAQ,aAAAC,EAAc,MAAOlF,CAAA,EAI1EsF,EAAcC,EAAAA,eAAA,EACdC,EAAgBC,EAAAA,IAAI,EAAK,EACzBC,EAA8BzF,EAAAA,SAAS,IAAM,CACjD,GAAI,CAACuF,EAAc,MACjB,OAEF,MAAMG,EAAmC/B,GAAU,OAAO,mCAAqC,GAC1F0B,EAAY,MAAQ,GAAK1B,GAAU,OAAO,iCAC3C,OAEEgC,EAAsBhC,GAAU,OAAO,qBAAuByB,GAAc,OAAO,OAAO,OAAS,EACrG,GACA,OAGJ,OAAOtB,EAAM,OAAO,cAAc,uBAC7B6B,GACAD,GACA/B,GAAU,OAAO,qBACxB,CAAC,EAMDiC,EAAAA,MACE7F,EACC8F,GAAM,CACDJ,EAA4B,OAC9B3C,EAAA,EAEFW,EAAM,oBAAqBoC,CAAC,CAC9B,EACA,CAAE,UAAW,EAAA,CAAK,EAMpBC,EAAAA,YAAY,IAAM,CACZvC,EAAM,mBAGNO,EAAM,OAAO,mBAAqB,KAGlClE,EAAO,OAAO,OAAS,GAAKA,EAAO,OAAO,OAASyE,EAAU,QAC/D0B,EAAA,CAEJ,CAAC,EAMD,SAASA,GAAW,CAClB7B,EAAK,IAAI,EACTT,EAAM,oBAAqB1D,EAAO,KAAK,CACzC,CAEA,SAASiG,EAAYrE,EAAgB,CAC/BgD,EAAgB,MAClBV,EAAOtC,GAAS/B,EAAO,MAAM,OAAS,CAAC,EAIvCwE,EAAQrE,EAAO,OAAO,IAAI,CAACkG,EAAGC,IAAMA,IAAMvE,EAAQ,KAAOsE,CAAC,CAAC,EAG7DxC,EAAM,oBAAqB1D,EAAO,KAAK,CACzC,CAEA,SAASoG,EAAyBlG,EAAY0B,EAAe,CACtD4D,EAAc,QAEjBA,EAAc,MAAQ,GAClBE,EAA4B,OAC9B3C,EAAA,GAQA7C,IAAU,QAAa0B,GAAS,GAClCwC,EAAOxC,EAAO,MAAS,EAGzB8B,EAAM,oBAAqB1D,EAAO,KAAK,CACzC,mEAMaqG,QAAAzC,CAAA,GAAU,0CAArB0C,EAAAA,mBAIM,MAAAC,GAAA,CAHJC,EAAAA,mBAES,OAAA,CAFF,iBAAgBvD,EAAA,KAAI,yBAAA,EACzBwD,EAAAA,gBAAAC,QAAA5C,CAAA,EAAwB,EAAAA,EAAA,MAAA,EAAAA,CAAA,EAAA,EAAA6C,EAAA,CAAA,kBAFY,EAAK,CAAA,gCAK7CC,EAAAA,YAAAC,EAAAA,YAqCYC,EAAAA,wBApCLrD,EAAA,QAAQ,EAAA,CACZ,KAAI,GAAKA,EAAA,cAAc,IAAI,SAC3B,iBAAAA,EAAA,cACA,gBAAA4B,EACA,aAAA5B,EAAA,UACA,SAAA4C,EAAAA,MAAAzC,CAAA,EACA,SAAAa,EAAA,MACA,SAAAD,EAAA,MACA,MAAAf,EAAA,MACA,gBAAekB,EAAA,MACf,mBAAkBC,EAAA,MAClB,WAAUoB,EACV,cAAaC,CAAA,GAEH,QAAOc,EAAAA,QAE+BC,GAFpB,EAC3BJ,EAAAA,UAAA,EAAA,EAAAN,EAAAA,mBAmBEW,EAAAA,SAAA,KAAAC,EAAAA,WAlBgCb,QAAAxG,CAAA,GAAM,CAAA,EAAA,CAAA,CAA5B,IAAA8B,CAAA,EAAOwF,mBADnBN,EAAAA,YAmBEO,EAAA,CAjBC,IAAAzF,EACA,iBAAA8B,EAAA,cACA,gBAAa,GAAKR,EAAA,KAAI,IAAIkE,CAAU,IACpC,MAAOA,EACP,SAAU1D,EAAA,SACV,aAAAuD,EACA,sBAAqBtC,EAAA,MACrB,gBAAeC,EAAA,MACf,mBAAkBC,EAAA,MAClB,WAAUoB,EACV,cAAW,IAAQC,EAAYkB,CAAU,EAC1C,sBAAA,GACA,oBAAkB,SAEjB,sBAAkBE,GAAEjB,EAAyBiB,EAAQF,CAAU,EAC/D,yBAAqBG,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAD,GAAE3D,EAAK,uBAAyB2D,CAAM,GAC3D,OAAMhB,EAAAA,MAAAlB,CAAA,CAAA,uwBCtOf,MAAM3B,EAAQC,EACRC,EAAQC,EACRC,EAAWC,EAAAA,OAAyC1D,CAAsB,EAa1E4D,EAAQ9D,EAAAA,SAAS,IAAMuD,EAAM,aAAa,EAI1C+D,EAActH,EAAAA,SAAS,IAC3BiD,GAAaa,EAAM,MAAM,MAAQ,GAAIP,EAAM,YAAY,CAAC,EAEpDQ,EAAiB/D,EAAAA,SAAS,IAAM+C,GAAcuE,EAAY,KAAK,CAAC,EAIhEjD,EAAYrE,EAAAA,SAAS,IACzBuD,EAAM,oBAAsB,OACxBA,EAAM,kBACLO,EAAM,OAAO,WAAa,CAAA,EAG3BQ,EAAYtE,EAAAA,SAAS,IACzBuD,EAAM,oBAAsB,OACxBA,EAAM,kBACLO,EAAM,OAAO,WAAa,CAAA,EAG3BS,EAAWvE,EAAAA,SAAS,IAAMsE,EAAU,QAAU,CAAC,EAC/CE,EAAWxE,EAAAA,SAAS,IAAMqE,EAAU,OAAS,GAAK,CAACE,EAAS,KAAK,EAGjEgD,EAAqBvH,EAAAA,SAAS,IAClCqE,EAAU,QAAU,EAAI,EAAI,MAAA,EAExBI,EAAqBzE,EAAAA,SAAS,IAClCsE,EAAU,QAAU,EAAI,EAAI,MAAA,EAIxBkD,EAAoBxH,EAAAA,SAAS,IAAM8D,EAAM,OAAO,UAAY,EAAI,QAAU,MAAS,EAKnF2D,EAAcjC,EAAAA,IAAqC,EAAE,EAGrDzF,EAASC,EAAAA,SAAS,IAAM,OAAO,OAAOyH,EAAY,KAAK,EAAE,IAAIxB,GAAKA,EAAE,KAAK,CAAC,EAM1EyB,EAAc1H,EAAAA,SAAS,IAC3B8D,EAAM,OAAO,QAAQ,SAAW,EAAIA,EAAM,OAAO,OAAO,CAAC,EAAwB,MAAA,EAc7E6D,EAAc3H,EAAAA,SAAS,IAAM,CAGjC,MAAM4H,EAUF,CAAA,EAGJ9D,EAAM,OAAO,QAAQ,QAAQ,CAACrC,EAAGyE,IAAM,CACrC0B,EAAa1B,CAAC,EAAI,CAChB,iBAAkB,EAClB,iBAAkB,EAClB,oBAAqB,EACrB,kBAAmB,EACnB,kBAAmB,EACnB,4BAA6B,OAC7B,4BAA6B,CAAA,CAEjC,CAAC,EAED,MAAM2B,EAAavD,EAAU,OAAS,EAGtC,GAAIuD,IAAe,EACjB,OAAA/D,EAAM,OAAO,QAAQ,QAAQ,CAACrC,EAAGyE,IAAM,CACrC0B,EAAa1B,CAAC,EAAE,4BAA8B,EAC9C0B,EAAa1B,CAAC,EAAE,4BAA8B,CAChD,CAAC,EACM0B,EAIT,SAAW,CAAClG,EAAKoG,CAAK,IAAK,OAAO,QAAQL,EAAY,OAAS,CAAA,CAAE,EAAG,CAGlE,IAAIM,EAAoB,KAAK,KAAKD,EAAM,YAAcA,EAAM,cAAc,EAC1E,MAAME,EAAoB,KAAK,KAAKF,EAAM,YAAcA,EAAM,cAAc,EAI9CD,EAAaC,EAAM,iBACnB,IAC5BC,EAAoBC,GAGtBJ,EAAalG,CAAG,EAAI,CAClB,iBAAkBoG,EAAM,YACxB,iBAAkBA,EAAM,YACxB,oBAAqBA,EAAM,eAC3B,kBAAAC,EACA,kBAAAC,EACA,4BAA6BF,EAAM,cAAgB,EAAI,EAAI,OAC3D,4BAA6B,MAAA,CAEjC,CAEA,MAAMG,EAAyB,OAAO,OAAOL,CAAY,EAAE,OACzD,CAACM,EAAKjI,IAAUiI,EAAMjI,EAAM,kBAC5B,CAAA,EAKF,cAAO,OAAO2H,CAAY,EAAE,QAAS3H,GAAU,CAE7C,MAAMkI,GAD0BF,EAAyBhI,EAAM,mBACJA,EAAM,oBAC3DmI,EAAwBP,EAAa5H,EAAM,oBAEjDA,EAAM,4BAA8BmI,EAAwBD,CAC9D,CAAC,EAEMP,CACT,CAAC,EAGKS,EAAcrI,EAAAA,SAAS,IAC3B,OAAO,OAAO2H,EAAY,KAAK,EAAE,OAC/B,CAACO,EAAKI,IAAMJ,EAAMI,EAAE,kBACpB,CAAA,CACF,EAMI1D,EAAqB5E,EAAAA,SAAS,IAAM,CAOxC,GANI0H,EAAY,OAGZnD,EAAS,OAGT8D,EAAY,OAAShE,EAAU,MACjC,OAEF,MAAMS,EAAYnB,GAAU,OAAO,SACnC,MAAO,CAACrB,EAAiB,sBAAuB+B,EAAU,MAAOS,GAAW,eAAe,CAAC,CAC9F,CAAC,EAIK,CAAE,OAAAE,EAAQ,aAAAC,CAAA,EAAiBE,EAAAA,SAASpB,EAAgBa,EAAoBd,EAAM,OAAO,YAAY,EACjGsB,EAAoC,CAAE,MAAOtB,EAAM,OAAO,cAAc,MAAO,OAAAkB,EAAQ,aAAAC,EAAc,MAAOlF,CAAA,EAQlH6F,QAAM9B,EAAQyE,GAAW,CAClBA,GAMLA,EAAO,QAAQ,QAAQ,CAACT,EAAOnG,IAAU,CACjCA,KAAS8F,EAAY,OACzBe,EAAiB,OAAW7G,EAAOmG,EAAM,SAAS,CACtD,CAAC,CACH,EAAG,CAAE,UAAW,GAAM,EAMtB,SAASU,EACPvI,EACAwI,EACAC,EAAyB,EACzBC,EAA4B,GAC5B,CAEA,GAAIA,EAAkB,CACpBlF,EAAM,oBAAqB1D,EAAO,KAAK,EACvC,MACF,CAIA,GAAI0I,IAAe,OACjB,OAEF,IAAIG,EAAkB,MAAM,QAAQ3I,CAAK,EAAIA,EAAQ,CAACA,CAAK,GAIxCqE,EAAU,OAAS,GACKoE,IACb,IAC5BE,EAAkBA,EAAgB,OAAO3C,GAAKA,IAAM,MAAS,GAG/D,MAAM0B,EAAciB,EAAgB,OAC9BP,EAAcO,EAAgB,UAAYxH,EAAkByE,CAAC,CAAC,EAAE,OAEhEgD,EAAapB,EAAY,MAAMgB,CAAU,GAAM,CAAA,EACrDI,EAAW,MAAQ5I,EACnB4I,EAAW,YAAclB,EACzBkB,EAAW,YAAcR,EACzBQ,EAAW,eAAiBH,EAEvBjB,EAAY,MAAMgB,CAAU,IAC/BhB,EAAY,MAAMgB,CAAU,EAAII,GAGlCpF,EAAM,oBAAqB1D,EAAO,KAAK,CACzC,eAME4G,EAAAA,YAAAC,EAAAA,YA+CYC,EAAAA,wBA9CLrD,EAAA,QAAQ,EAAA,CAEZ,KAAI,GAAKA,EAAA,cAAc,IAAI,UAC3B,iBAAAA,EAAA,cACA,gBAAA4B,EACA,aAAA5B,EAAA,UACA,SAAA4C,EAAAA,MAAAzC,CAAA,EACA,SAAAa,EAAA,MACA,MAAAhB,EAAA,MACA,SAAAe,EAAA,MACA,gBAAAf,EAAA,YACA,mBAAAA,EAAA,eACA,WAAAA,EAAA,QACA,cAAAA,EAAA,UAAA,GAED,QAAAsD,EAAAA,QAdQC,GAAS,CAeTW,EAAA,qBADRd,EAAAA,YAYEO,EAAA,OAVC,iBAAgBO,EAAA,MAChB,gBAAAlE,EAAA,aACA,SAAAA,EAAA,SACA,aAAAuD,EACA,sBAAqBQ,EAAA,MACrB,sBAAqB9C,EAAA,MACtB,uBAAA,GAEC,qCAAoB+D,EAAiBpB,EAAM,EAAKM,EAAA,MAAa,UAAS,EAAA,GACtE,yBAAqBL,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAD,GAAE3D,EAAK,uBAAyB2D,CAAM,EAAA,mHAG5DT,EAAAA,UAAA,EAAA,EAAAN,EAAAA,mBAeEW,EAAAA,8BAdyBlD,EAAA,MAAM,OAAM,CAA7BgE,EAAOnG,mBADjBiF,EAAAA,YAeEO,EAAA,CAbC,IAAKW,EAAM,KACX,iBAAiBA,EACjB,gBAAAtE,EAAA,aACA,MAAA7B,EACA,SAAA6B,EAAA,SACA,aAAAuD,EACA,sBAAqBY,EAAA,MAAYhG,CAAK,GAAG,4BACzC,sBAAqBgG,EAAA,MAAYhG,CAAK,GAAG,4BACzC,oBAAmB6F,EAAA,MACpB,uBAAA,GAEC,sBAAkBJ,GAAEoB,EAAiBpB,EAAQzF,EAAOmG,EAAM,SAAS,EACnE,yBAAqBT,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAD,GAAE3D,EAAK,uBAAyB2D,CAAM,EAAA,qUCjV7D,SAAS0B,GAAUhF,EAA8B,CACtD,KAAM,CACJ,KAAMiF,EACN,KAAMC,EACN,SAAUC,EACV,OAAQC,EACR,WAAYC,EACZ,aAAcC,EACd,cAAeC,EACf,UAAWxB,EACX,MAAOyB,EACP,OAAQC,EACR,cAAeC,EACf,0BAA2BC,EAC3B,GAAGC,CAAA,EACD5F,EAEE6F,EAAS,OAAO,YACpB,OAAO,QAAQD,CAAY,EAAE,KAAK,CAAC,CAACE,CAAC,EAAG,CAACC,CAAC,IAAMD,EAAE,cAAcC,CAAC,CAAC,CAAA,EAEpE,OAAO,KAAK,UAAUF,CAAM,CAC9B,qCC2BMG,GAAmB,wcAlBzB,MAAMvG,EAAQC,EACRC,EAAQC,EACRC,EAAWC,EAAAA,OAAyC1D,CAAsB,EAOhF,IAAI2D,EAAyB,EAUzBkG,EAAoB,EACpBC,EAEJ,SAASC,EAAoBC,EAAmB,CAS9C,GARAH,IAEIC,GAA0B,OAC5BA,EAAyB,WAAW,IAAM,CACxCD,EAAoB,EACpBC,EAAyB,MAC3B,EAAG,CAAC,GAEFD,EAAoBD,GACtB,MAAM,IAAI,MACR,iFAAiFI,CAAS,yCAClDJ,EAAgB,iIAAA,CAI9D,CAQA,MAAMhG,EAAQ9D,EAAAA,SAAS,IAEduD,EAAM,aACd,EAEKP,EAAOhD,EAAAA,SAAS,IACf8D,EAAM,OAAO,KAGXb,GAAaa,EAAM,MAAM,KAAMP,EAAM,YAAY,EAF/C,EAGV,EAIK4G,EAAgBnK,WAAS,IAAM8D,EAAM,OAAO,eAAiBA,EAAM,OAAO,YAAY,MAAM,EAI5FsG,EAAWpK,EAAAA,SAAS,IAAM,CAC9B,IAAIgJ,EAAQhG,EAAK,MACjB,GAAImH,EAAc,OAASnB,EAAO,CAChC,MAAMqB,EAA2B1G,GAAU,OAAO,0BAA4B,QAC9EqF,EAAQ,GAAGA,CAAK,KAAKqB,CAAwB,IAC/C,CACA,OAAOrB,CACT,CAAC,EAEKjF,EAAiB/D,EAAAA,SAAS,IAAM+C,GAAcqH,EAAS,KAAK,CAAC,EAE7DE,EAAUtK,EAAAA,SAAS,IACnBuD,EAAM,kBAAoB,QACrB,GAELA,EAAM,kBAAoB,SACrB,IAEDO,EAAM,OAAO,WAAa,GAAK,CACxC,EAOKc,EAAqBY,EAAAA,IAA+B,EAAE,EAEtDJ,EAAgBkF,EAAQ,MAK1B,CAAE,MAAO9E,EAAAA,IAAI,MAAS,CAAA,EAJtBL,EAAAA,SAASpB,EAAgBa,EAAoB,CAC7C,GAAId,EAAM,OAAO,cAAgB,CAAA,EACjC,sBAAuB,EAAA,CACxB,EAGG7D,EAAQmF,EAAa,MAG3BA,EAAa,SAAWpF,EAAAA,SAAS,IAAMoB,EAAkBnB,EAAM,KAAK,CAAC,EAGrE,MAAMsK,EAAqBnF,EAAa,WACxCA,EAAa,WAAa,SAAUoF,EAAuBC,EAAsC,CAC/FA,EAAiBA,GAAkB9G,GAAU,OAAO,eACpD4G,EAAmBC,EAAGC,CAAc,EACpChH,EAAM,OAAQ+G,EAAGC,CAAc,CACjC,EAGA,MAAMC,EAAuBtF,EAAa,aAC1CA,EAAa,aAAe,SAAUoF,EAAYC,EAAsC,CACtFC,EAAqBF,EAAGC,IAAmB,EAAI,CACjD,EAIA,MAAME,EAAW3K,EAAAA,SAAS,IAAM,CAAC,CAAC8D,EAAM,OAAO,UAAU,MAAM,EACzD8G,EAAW5K,EAAAA,SAAS,IAAM,CAAC,CAAC8D,EAAM,OAAO,QAAQ,MAAM,EAEvD+G,EAAU7K,EAAAA,SAAS,IAAM,CAACsK,EAAQ,OAAS,CAACM,EAAS,OAAS,CAACD,EAAS,KAAK,EAG7EG,EAAgBtF,EAAAA,IAAI,EAAI,EAMxBuF,EAAuBvF,EAAAA,IAAI,CAAC,EAQ5BwF,EAAcxF,EAAAA,IAAoD,EAAE,EACpEyF,EAAmBjL,EAAAA,SAAS,IAAM,OAAO,OAAOgL,EAAY,KAAK,CAAC,EAElEE,EAAgBlL,EAAAA,SAAS,IAAM,CAEnCiK,EAAoBjH,EAAK,KAAK,EAE1Bc,EAAM,OAAO,4BAA8B,IACxCiH,EAAqB,MAe5B,MAAMI,GAZkBrH,EAAM,OAAO,eAAiB,CAAA,GAAI,OACxD,CAACA,EAAOsH,KAINA,EAAQtH,EAAO7D,EAAOgL,CAAgB,EAC/BnH,GAET,CAAE,GAAGA,EAAM,MAAO,KAAMd,EAAK,KAAA,CAAM,EAKrC,OAAAmI,EAAkB,KAAOnI,EAAK,MAC9BmI,EAAkB,MAAQrC,GAAUqC,CAAiB,EAE9CA,CACT,CAAC,EAKK9G,EAAYrE,EAAAA,SAAS,IACrBuD,EAAM,oBAAsB,OACvBA,EAAM,kBAGXA,EAAM,iBACD,EAEF2H,EAAc,OAAO,WAAa,CAC1C,EAGK5G,EAAYtE,EAAAA,SAAS,IACzBuD,EAAM,oBAAsB,OACxBA,EAAM,kBACL2H,EAAc,OAAO,WAAa,CAAA,EAGnC3G,EAAWvE,EAAAA,SAAS,IAAMsE,EAAU,QAAU,CAAC,EAC/CE,EAAWxE,EAAAA,SAAS,IAAMqE,EAAU,OAAS,GAAK,CAACE,EAAS,KAAK,EAIjEgD,EAAqBvH,EAAAA,SAAS,IAAM,CAExC,GAAIuD,EAAM,oBAAsB,EAC9B,OAAOA,EAAM,kBAGf,GAAI,EAAAc,EAAU,MAAQ,IAIlB,CAAAjD,EAAkBnB,EAAM,KAAK,EAIjC,MAAO,EACT,CAAC,EAGKwE,EAAqBzE,EAAAA,SAAS,IAClCsE,EAAU,QAAU,EAAI,EAAI,MAAA,EAGxBK,EAAkB3E,EAAAA,SAAS,IAE3BuD,EAAM,kBAAoBnC,EAAkBnB,EAAM,KAAK,EAClD,GAEFsD,EAAM,cACd,EAIK8B,EAAcC,EAAAA,eAAA,EACdG,EAA8BzF,EAAAA,SAAS,IAAM,CAGjD,MAAM0F,EAAmC/B,GAAU,OAAO,mCAAqC,GAC1F0B,EAAY,MAAQ,GAAK1B,GAAU,OAAO,iCAC3C,OAEEgC,EAAsBhC,GAAU,OAAO,qBAAuByB,GAAc,OAAO,OAAO,OAAS,EACrG,GACA,OAGJ,OAAOtB,EAAM,OAAO,cAAc,uBAC7B6B,GACAD,GACA/B,GAAU,OAAO,qBACxB,CAAC,EAEK0H,EAAiBrL,EAAAA,SACrB,IAAM8D,EAAM,OAAO,YAAY,QAAU1C,EAAkBnB,EAAM,KAAK,CAAA,EAUxE6F,EAAAA,YAAY,IAAM,CAGhB,MAAMjB,EAA0C,CAAA,EAC1CyG,EAAexH,EAAM,MAAM,aAAe,CAAA,EAC1CgB,EAAYnB,GAAU,OAAO,SAE/Ba,EAAS,OACXK,EAAa,KAAKvC,EAAiB,eAAgB,OAAWwC,GAAW,QAAQ,CAAC,EAEhFwG,EAAa,WAAa,MAC5BzG,EAAa,KAAKvC,EAAiB,gBAAiBgJ,EAAa,UAAWxG,GAAW,SAAS,CAAC,EAE/FwG,EAAa,WAAa,MAC5BzG,EAAa,KAAKvC,EAAiB,gBAAiBgJ,EAAa,UAAWxG,GAAW,SAAS,CAAC,EAE/FwG,EAAa,QAAU,MACzBzG,EAAa,KAAKvC,EAAiB,aAAcgJ,EAAa,OAAQxG,GAAW,MAAM,CAAC,EAEtFwG,EAAa,SAAW,MAC1BzG,EAAa,KAAKvC,EAAiB,cAAegJ,EAAa,QAASxG,GAAW,OAAO,CAAC,EAEzFwG,EAAa,cAAgB,MAC/BzG,EAAa,KAAKvC,EAAiB,mBAAoBgJ,EAAa,aAAcxG,GAAW,YAAY,CAAC,EAExGwG,EAAa,cAAgB,MAC/BzG,EAAa,KAAKvC,EAAiB,mBAAoBgJ,EAAa,aAAcxG,GAAW,YAAY,CAAC,EAExGwG,EAAa,cAAgB,MAC/BzG,EAAa,KAAKvC,EAAiB,mBAAoBgJ,EAAa,aAAcxG,GAAW,YAAY,CAAC,EAExGwG,EAAa,cAAgB,MAC/BzG,EAAa,KAAKvC,EAAiB,mBAAoBgJ,EAAa,aAAcxG,GAAW,YAAY,CAAC,EAExGwG,EAAa,aAAe,MAC9BzG,EAAa,KAAKvC,EAAiB,kBAAmBgJ,EAAa,YAAaxG,GAAW,WAAW,CAAC,EAErGwG,EAAa,YAAc,MAC7BzG,EAAa,KAAKvC,EAAiB,iBAAkBgJ,EAAa,WAAYxG,GAAW,UAAU,CAAC,EAElGwG,EAAa,gBAAkB,MACjCzG,EAAa,KAAKvC,EAAiB,qBAAsBgJ,EAAa,eAAgBxG,GAAW,cAAc,CAAC,EAE9GwG,EAAa,aAAe,MAC9BzG,EAAa,KAAKvC,EAAiB,kBAAmBgJ,EAAa,YAAaxG,GAAW,WAAW,CAAC,EAErGhB,EAAM,OAAO,YACfe,EAAa,KAAK,GAAGxB,GAA2BS,EAAM,OAAO,UAAU,CAAC,EAE1Ec,EAAmB,MAAQC,CAC7B,CAAC,EAKD,IAAI0G,EAAgB,GACpB3F,QAAM3F,EAAQuL,GAAa,CACrBD,IAGJA,EAAgB,GACZC,IAAa,KACfvL,EAAM,MAAQsD,EAAM,iBAAmB,KAAO,QAChDgI,EAAgB,GAClB,EAAG,CACD,MAAO,MAAA,CACR,EAID3F,EAAAA,MACE3F,EACC4F,GAAM,CAIAgF,EAAQ,SAIT,CAACC,EAAc,OAASjF,KAC1B4F,EAAA,EAEIhG,EAA4B,OAC9BL,GAAc,SAAA,GAGlB0F,EAAc,MAAQ,GACxB,EACA,CACE,UAAW,EAAA,CACb,EAOFY,EAAAA,UAAU,IAAM,CACdjI,EAAM,uBAAwByH,EAAc,KAAK,EACjDtF,EAAAA,MAAM,IAAMsF,EAAc,MAAM,MAAO,CAACS,EAASC,IAAY,CACvDD,IAAYC,GAEhBnI,EAAM,uBAAwByH,EAAc,KAAK,CACnD,CAAC,CACH,CAAC,EAEDW,EAAAA,gBAAgB,IAAM,CAChB7B,GAA0B,MAC5B,aAAaA,CAAsB,EAKjC,CAAAzG,EAAM,kBAKNtD,EAAM,QAAU,SAClBA,EAAM,MAAQ,OACdwL,EAAA,EAEJ,CAAC,EAaD,SAASK,EAA2BhI,EAA6C,CAC3E,CAACA,EAAM,MAEMkH,EAAY,MAAMlH,EAAM,IAAI,GAC/B,QAAUA,EAAM,QAE9BkH,EAAY,MAAMlH,EAAM,IAAI,EAAIA,EAClC,CAEA,SAAS2H,GAAoB,CAE3BV,EAAqB,QACrBtH,EAAM,oBAAqBxD,EAAM,KAAK,CACxC,CAIA,SAAS8L,GAAiBC,EAAiB,CACzC/L,EAAM,MAAQ+L,EACdvI,EAAM,oBAAqBxD,EAAM,KAAK,CACxC,2HAMamG,QAAAzC,CAAA,GAAU,0CAArB0C,EAAAA,mBAIM,MAAAC,GAAA,CAHJC,EAAAA,mBAES,OAAA,CAFF,iBAAgBvD,EAAA,KAAI,yBAAA,EACzBwD,EAAAA,gBAAAC,QAAA5C,CAAA,EAAwB,EAAAA,EAAA,MAAA,EAAAA,CAAA,EAAA,EAAA6C,EAAA,CAAA,kBAFY,EAAK,CAAA,+BAK7BkE,EAAA,qBACdhE,cAMEqF,GANFC,EAAAA,WAME,CAAA,IAAA,CAAA,EALQ3I,EAAK,CACZ,iBAAgB2H,EAAA,MAEhB,sBAAoBO,EACpB,yBAAuBK,CAAA,gCAGPxB,EAAA,qBACnB1D,EAAAA,YAOEuF,GAPFD,EAAAA,WAOE,CAAA,IAAA,CAAA,EANQ3I,EAAK,CACZ,uBAAAC,EAAA,kBACA,iBAAgB0H,EAAA,MAEhB,sBAAoBa,GACpB,yBAAuBD,CAAA,wDAI1BnF,EAAAA,YAAAC,EAAAA,YAoEYC,EAAAA,wBAnELrD,EAAA,QAAQ,EAAA,OACZ,KAAMA,mBAAgB,GAAM0H,EAAA,MAAc,IAAI,cAAgBA,EAAA,MAAc,KAC5E,iBAAgBA,EAAA,MAChB,gBAAA9E,EAAAA,MAAAhB,CAAA,EACA,aAAA5B,EAAA,UACA,SAAA4C,EAAAA,MAAAzC,CAAA,EACA,SAAAa,EAAA,MACA,SAAAD,EAAA,MACA,MAAAf,EAAA,MACA,gBAAAA,EAAA,YACA,mBAAkBmB,EAAA,MAClB,WAAAnB,EAAA,QACA,cAAAA,EAAA,UAAA,GAEU,QAAOsD,EAAAA,QAgBLC,GAhBgB,CACX4D,EAAA,OACdhE,EAAAA,UAAA,EAAA,EAAAN,EAAAA,mBAaEW,EAAAA,8BAZyBkE,EAAA,MAAc,SAAQ,CAAvCpD,EAAOnG,oBADjBiF,EAAAA,YAaEwF,EAAA,CAXC,IAAKtE,EAAM,KACX,iBAAiBA,EACjB,gBAAesC,EAAA,MACf,MAAAzI,GACA,SAAA6B,EAAA,SACA,aAAAuD,EACA,sBAAqBQ,EAAA,MACrB,sBAAqB9C,EAAA,MAErB,sBAAoBgH,EACpB,yBAAuBK,CAAA,6JAGXnB,EAAA,mCACfhE,YAAA,EAAAC,EAAAA,YAcEC,0BAbKrD,EAAA,QAAQ,EAAA,OACZ,KAAI,GAAK0H,EAAA,MAAc,IAAI,SAC3B,iBAAgBA,EAAA,MAChB,gBAAA9E,EAAAA,MAAAhB,CAAA,EACA,aAAA2B,EACA,SAAAX,EAAAA,MAAAzC,CAAA,EACA,SAAAa,EAAA,MACA,SAAAD,EAAA,MACA,MAAAf,EAAA,MACA,gBAAAA,EAAA,YACA,mBAAkBmB,EAAA,MAClB,WAAAnB,EAAA,QACA,cAAAA,EAAA,UAAA,yKAII,WAAUsD,EAAAA,QAgBRC,GAhBmB,CACdsE,EAAA,OACd1E,EAAAA,UAAA,EAAA,EAAAN,EAAAA,mBAaEW,EAAAA,8BAZ6BkE,EAAA,MAAc,WAAU,CAA7CmB,EAAW1K,oBADrBiF,EAAAA,YAaEwF,EAAA,CAXC,IAAKC,EAAU,KACf,iBAAiBA,EACjB,gBAAerJ,EAAA,MACf,MAAArB,GACA,SAAA6B,EAAA,SACA,aAAAuD,EACA,sBAAqBQ,EAAA,MACrB,sBAAqB9C,EAAA,MAErB,sBAAoBgH,EACpB,yBAAuBK,CAAA,seCvgBpC,MAAMnI,EAAW3D,EAAAA,SAAS,KAAO,CAC/B,sBAAuB,GACvB,oBAAqB,GACrB,GAAIwD,EAAA,UAAa,CAAA,CAAC,EAClB,EAEF8I,EAAAA,QAAQpM,EAAwByD,CAAQ,EAExC,MAAM4I,EAAkBvM,EAAAA,SAAS,IAC/B,MAAM,QAAQwD,EAAA,QAAQ,EAAIA,EAAA,SAAW,CAACA,EAAA,QAAQ,CAAA,EAG1CgJ,EAAuBxM,EAAAA,SAAS,IACpCuM,EAAgB,OAAO,IAAI,CAACtG,EAAGtE,IAAU8K,EAA8BxG,EAAGtE,CAAK,CAAC,GAAK,CAAA,CAAC,EAKlF+K,EAAgB1M,EAAAA,SACpB,IACEwD,EAAA,QAAA,EAmBJ,SAASiJ,EACPE,EACAhL,EACAiL,EACA,CACA,GAAI,CAACD,EACH,OAAOA,EAET,MAAMjK,EAAYiK,EAAc,MAAQ,SAAShL,CAAK,GAChDuI,EAAYyC,EAAc,MAAQ,CAACC,GAAQ,KAAMlK,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EACpFmK,EAAwC,CAC5C,KAAMnK,EACN,KAAMwH,EACN,KAAM,OACN,UAAW,EACX,UAAW,EAEX,GAAGyC,EACH,cAAe,CAAC,GAAIA,EAAc,eAAiB,CAAA,CAAG,EACtD,OAAAC,CAAA,EAGF,OAAAC,EAAK,UAAYF,EAAc,UAAY,CAAA,GAAI,IAAI,CAAC1G,EAAGtE,IACrD8K,EAA8BxG,EAAetE,EAAOkL,CAAI,CAAA,EAE1DA,EAAK,QAAUF,EAAc,QAAU,CAAA,GAAI,IAAI,CAAC1G,EAAGtE,IACjD8K,EAA8BxG,EAAetE,EAAOkL,CAAI,CAAA,EAE1DA,EAAK,YAAcF,EAAc,YAAc,CAAA,GAAI,IAAI,CAAC1G,EAAGtE,IACzD8K,EAA8BxG,EAAetE,EAAOkL,CAAI,CAAA,EAGnDA,CACT,+BAMExG,EAAAA,mBAKEW,EAAAA,SAAA,KAAAC,EAAAA,WAJwBuF,EAAA,MAAjBG,kBADT/F,EAAAA,YAKEO,EAAA,CAHC,IAAKwF,EAAc,KACnB,SAAUD,EAAA,MACV,iBAAiBC,CAAA,mDC7GhBG,GAAa,OAKNC,GAAoCC,GAC9C/K,GACQA,EAAI,QAAQ6K,GAAYxE,GAAKA,EAAE,MAAM,CAAC,EAAE,aAAa,CAEhE,EAEA,SAAS0E,GAAuDC,EAAU,CACxE,MAAMC,EAAgC,OAAO,OAAO,IAAI,EACxD,OAASjL,GACKiL,EAAMjL,CAAG,IACNiL,EAAMjL,CAAG,EAAIgL,EAAGhL,CAAG,GAEtC,+ICgIA,MAAMkL,EAAQC,EAAAA,SAAA,EAIRC,EAAWC,EAAAA,SAAA,EACXC,EAAQvN,EAAAA,SAAS,IAAM,CAC3B,MAAM6C,EAA8B,CAAA,EACpC,SAAW,CAACnB,EAAKzB,CAAK,IAAK,OAAO,QAAQoN,CAAQ,EAChDxK,EAAOkK,GAASrL,CAAG,CAAC,EAAIzB,EAE1B,OAAO4C,CACT,CAAC,EAMK2K,EAAmBxN,EAAAA,SAAS,IAAuB,CACvD,MAAMyN,EAAOF,EAAM,MAAM,KACzB,OAAIE,GAAQN,EAAMM,CAAuB,EAChCA,EAGLA,GAAM,SAAS,QAAQ,EAClBN,EAAM,eAAe,EAAI,gBAAkB,UAEhDM,GAAM,SAAS,QAAQ,EAClBN,EAAM,eAAe,EAAI,gBAAkB,UAEhDM,GAAM,SAAS,aAAa,EACvBN,EAAM,oBAAoB,EAAI,qBAAuB,UAE1DM,GAAM,SAAS,SAAS,GACnBN,EAAM,gBAAgB,EAAI,iBAE5B,SACT,CAAC,eAMiBI,EAAA,MAAM,6BAAtBlH,EAAAA,mBAIWW,WAAA,CAAA,IAAA,GAAA,CAHGuG,EAAA,MAAM,MAAM,SAAQ,QAAA,EAAhCG,aAA2HC,EAAA,OAAxEH,EAAA,MAAgBI,EAAAA,eAAA1B,EAAAA,WAAA,CAAA,IAAA,CAAA,EAAWqB,EAAA,KAAK,CAAA,CAAA,EAClEA,EAAA,MAAM,MAAM,SAAQ,SAAA,EAArCG,EAAAA,WAAiIC,EAAA,OAAxEH,EAAA,MAAgBI,EAAAA,eAAA1B,EAAAA,WAAA,CAAA,IAAA,CAAA,EAAWqB,EAAA,KAAK,CAAA,CAAA,EACzFG,aAAuDC,EAAA,OAAnCH,EAAA,MAAgBI,EAAAA,eAAA1B,EAAAA,WAAA,CAAA,IAAA,CAAA,EAAUqB,EAAA,KAAK,CAAA,CAAA,CAAA,sCCzJhD,SAASM,IAKZ,CAYF,MAAO,CACL,WAAY,OAAO,KAAK,EAAqB,EAC7C,mBAAoB,CAAA,EACpB,eAAgB,CAAA,EAChB,2BAA4B,CAAA,EAC5B,WAAY,CAAA,CAAC,CAEjB,CCtDA,SAASC,IAAsC,CAK7C,MAAMC,EADWC,EAAAA,mBAAA,GACsB,SACvC,OAAID,GAAgBE,EAAAA,kBAA6BF,EACxCA,EAAYE,EAAAA,cAAwB,EAEtCrK,EAAAA,OAAOqK,EAAAA,cAAc,CAC9B,CAUO,SAASC,IAAyB,CACvC,MAAMC,EAAOL,GAAA,EAWb,eAAeM,EAAgBC,EAAmE,CAChG,MAAMC,EAAaH,EAAK,iBAAA,EACrB,OAAaI,EAAM,IAAI,EACvB,OAAOvL,GAAQA,IAASqL,GACpBrL,EAAK,WAAW,GAAGqL,CAAW,GAAG,GACjCrL,EAAK,WAAW,GAAGqL,CAAW,GAAG,CAAC,EAEnCG,EAAoB,MAAM,QAAQ,IACtCF,EAAW,IAAI,MAAMtL,IAAS,CAC5B,KAAAA,EACA,OAAQ,MAAMmL,EAAK,cAAcnL,CAA2B,CAAA,EAC5D,CAAA,EAGEyL,EAAU,OAAO,YACrBD,EAAkB,IAAI,CAAC,CAAE,KAAAxL,EAAM,OAAAH,KAAa,CAACG,EAAMH,CAAM,CAAC,CAAA,EAGtDmC,EAAS,OAAO,YACpBwJ,EACG,OAAO,CAAC,CAAE,OAAA3L,KAAa,CAACA,EAAO,KAAK,EACpC,IAAI,CAAC,CAAE,KAAAG,EAAM,OAAAH,CAAA,IAAa,CAACG,EAAMH,EAAO,OAAO,CAAC,GAAK,EAAE,CAAC,CAAA,EAG7D,MAAO,CACL,MAAO2L,EAAkB,MAAM,CAAC,CAAE,OAAA3L,CAAA,IAAaA,EAAO,KAAK,EAC3D,QAAA4L,EACA,OAAAzJ,EACA,OAAQ,QAAA,CAEZ,CAEA,MAAO,CAAE,gBAAAoJ,CAAA,CACX,CCxCO,SAASM,GAA8DC,EAG5E,CACA,MAAMC,EAA8C5L,GAC3C6L,EAAAA,cAA0C7L,CAAI,EAGjDmL,EAAOW,EAAAA,QAAiBH,CAAI,EAC5B,CAAE,gBAAAP,CAAA,EAAoBF,GAAA,EAE5B,MAAO,CACL,GAAGC,EACH,cAAAS,EACA,gBAAAR,CAAA,CAEJ,CCtCO,SAASW,GAIdC,EACAC,EACuD,CACvD,MAAI,CAACD,GAAY,CAACC,IAGlBD,EAAWC,IAAe,CAAE,GAAGD,EAAU,EACzCA,EAAS,SAAWA,GAAU,UAAU,OAASD,GAAoB9I,EAAGgJ,CAAY,CAAC,EACrFD,EAAS,OAASA,GAAU,QAAQ,OAASD,GAAoB9I,EAAGgJ,CAAY,CAAC,GAC1ED,CACT","x_google_ignoreList":[2]}
|