@formio/js 5.1.0-dev.6152.95f2394 → 5.1.0-dev.6155.76252ef

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/formio.builder.css +1 -0
  2. package/dist/formio.builder.min.css +1 -1
  3. package/dist/formio.form.css +1 -0
  4. package/dist/formio.form.js +9 -9
  5. package/dist/formio.form.min.css +1 -1
  6. package/dist/formio.form.min.js +1 -1
  7. package/dist/formio.full.css +1 -0
  8. package/dist/formio.full.js +11 -11
  9. package/dist/formio.full.min.css +1 -1
  10. package/dist/formio.full.min.js +1 -1
  11. package/dist/formio.js +4 -4
  12. package/dist/formio.min.js +1 -1
  13. package/dist/formio.utils.js +5 -5
  14. package/dist/formio.utils.min.js +1 -1
  15. package/lib/cjs/PDFBuilder.d.ts +1 -0
  16. package/lib/cjs/PDFBuilder.js +8 -8
  17. package/lib/cjs/WebformBuilder.d.ts +1 -1
  18. package/lib/cjs/WebformBuilder.js +36 -11
  19. package/lib/cjs/components/button/Button.d.ts +1 -1
  20. package/lib/cjs/components/button/Button.js +4 -4
  21. package/lib/cjs/components/radio/Radio.d.ts +8 -0
  22. package/lib/cjs/components/radio/Radio.js +15 -5
  23. package/lib/cjs/components/select/Select.d.ts +1 -0
  24. package/lib/cjs/components/select/Select.js +18 -2
  25. package/lib/cjs/components/selectboxes/SelectBoxes.d.ts +6 -0
  26. package/lib/cjs/translations/en.d.ts +1 -0
  27. package/lib/cjs/translations/en.js +1 -1
  28. package/lib/cjs/utils/utils.js +14 -3
  29. package/lib/mjs/PDFBuilder.d.ts +1 -0
  30. package/lib/mjs/PDFBuilder.js +8 -8
  31. package/lib/mjs/WebformBuilder.d.ts +1 -1
  32. package/lib/mjs/WebformBuilder.js +36 -12
  33. package/lib/mjs/components/button/Button.d.ts +1 -1
  34. package/lib/mjs/components/button/Button.js +1 -1
  35. package/lib/mjs/components/radio/Radio.d.ts +8 -0
  36. package/lib/mjs/components/radio/Radio.js +15 -5
  37. package/lib/mjs/components/select/Select.d.ts +1 -0
  38. package/lib/mjs/components/select/Select.js +18 -2
  39. package/lib/mjs/components/selectboxes/SelectBoxes.d.ts +6 -0
  40. package/lib/mjs/translations/en.d.ts +1 -0
  41. package/lib/mjs/translations/en.js +1 -0
  42. package/lib/mjs/utils/utils.js +14 -2
  43. package/package.json +2 -2
@@ -850,7 +850,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
850
850
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
851
851
 
852
852
  "use strict";
853
- eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.validateRequiredInfo = exports.validateRequiredSync = exports.validateRequired = exports.shouldValidate = void 0;\nconst error_1 = __webpack_require__(/*! ../../../error */ \"./node_modules/@formio/core/lib/error/index.js\");\nconst util_1 = __webpack_require__(/*! ../util */ \"./node_modules/@formio/core/lib/process/validation/util.js\");\nconst formUtil_1 = __webpack_require__(/*! ../../../utils/formUtil */ \"./node_modules/@formio/core/lib/utils/formUtil/index.js\");\nconst isAddressComponent = (component) => {\n return component.type === 'address';\n};\nconst isDayComponent = (component) => {\n return component.type === 'day';\n};\nconst isAddressComponentDataObject = (value) => {\n return (value !== null &&\n typeof value === 'object' &&\n value.mode &&\n value.address &&\n typeof value.address === 'object');\n};\n// Checkboxes and selectboxes consider false to be falsy, whereas other components with\n// settable values (e.g. radio, select, datamap, container, etc.) consider it truthy\nconst isComponentThatCannotHaveFalseValue = (component) => {\n return component.type === 'checkbox' || component.type === 'selectboxes';\n};\nconst valueIsPresent = (value, considerFalseTruthy, isNestedDatatype) => {\n // Evaluate for 3 out of 6 falsy values (\"\", null, undefined), don't check for 0\n // and only check for false under certain conditions\n if (value === null ||\n value === undefined ||\n value === '' ||\n (!considerFalseTruthy && value === false)) {\n return false;\n }\n // Evaluate for empty object\n else if ((0, util_1.isEmptyObject)(value)) {\n return false;\n }\n // Evaluate for empty array\n else if (Array.isArray(value) && value.length === 0) {\n return false;\n }\n // Check for moment.js object or Date object\n else if (typeof value === 'object' &&\n (value._isAMomentObject === true || value instanceof Date)) {\n return true;\n }\n // Recursively evaluate\n else if (typeof value === 'object' && !isNestedDatatype) {\n return Object.values(value).some((val) => valueIsPresent(val, considerFalseTruthy, isNestedDatatype));\n }\n // If value is an array, check it's children have value\n else if (Array.isArray(value) && value.length) {\n return (0, util_1.doesArrayDataHaveValue)(value);\n }\n return true;\n};\nconst shouldValidate = (context) => {\n var _a, _b;\n const { component } = context;\n return !!((_a = component.scope) === null || _a === void 0 ? void 0 : _a.required) || !!((_b = component.validate) === null || _b === void 0 ? void 0 : _b.required);\n};\nexports.shouldValidate = shouldValidate;\nconst validateRequired = (context) => __awaiter(void 0, void 0, void 0, function* () {\n return (0, exports.validateRequiredSync)(context);\n});\nexports.validateRequired = validateRequired;\nconst validateRequiredSync = (context) => {\n const error = new error_1.FieldError('required', Object.assign(Object.assign({}, context), { setting: true }));\n const { component, value } = context;\n if (!(0, exports.shouldValidate)(context)) {\n return null;\n }\n if (isAddressComponent(component) && isAddressComponentDataObject(value)) {\n return (0, util_1.isEmptyObject)(value.address)\n ? error\n : Object.entries(value.address)\n .filter(([key]) => !['address2'].includes(key))\n .every(([, val]) => !!val)\n ? null\n : error;\n }\n else if (isDayComponent(component) && value === '00/00/0000') {\n return error;\n }\n else if (isComponentThatCannotHaveFalseValue(component)) {\n return !valueIsPresent(value, false, (0, formUtil_1.isComponentNestedDataType)(component)) ? error : null;\n }\n return !valueIsPresent(value, true, (0, formUtil_1.isComponentNestedDataType)(component)) ? error : null;\n};\nexports.validateRequiredSync = validateRequiredSync;\nexports.validateRequiredInfo = {\n name: 'validateRequired',\n process: exports.validateRequired,\n processSync: exports.validateRequiredSync,\n shouldProcess: exports.shouldValidate,\n};\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/process/validation/rules/validateRequired.js?");
853
+ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.validateRequiredInfo = exports.validateRequiredSync = exports.validateRequired = exports.shouldValidate = void 0;\nconst error_1 = __webpack_require__(/*! ../../../error */ \"./node_modules/@formio/core/lib/error/index.js\");\nconst util_1 = __webpack_require__(/*! ../util */ \"./node_modules/@formio/core/lib/process/validation/util.js\");\nconst formUtil_1 = __webpack_require__(/*! ../../../utils/formUtil */ \"./node_modules/@formio/core/lib/utils/formUtil/index.js\");\nconst isAddressComponent = (component) => {\n return component.type === 'address';\n};\nconst isDayComponent = (component) => {\n return component.type === 'day';\n};\nconst isAddressComponentDataObject = (value) => {\n return (value !== null &&\n typeof value === 'object' &&\n value.mode &&\n value.address &&\n typeof value.address === 'object');\n};\n// Checkboxes and selectboxes consider false to be falsy, whereas other components with\n// settable values (e.g. radio, select, datamap, container, etc.) consider it truthy\nconst isComponentThatCannotHaveFalseValue = (component) => {\n return component.type === 'checkbox' || component.type === 'selectboxes';\n};\nconst valueIsPresent = (value, considerFalseTruthy, isNestedDatatype) => {\n // Evaluate for 3 out of 6 falsy values (\"\", null, undefined), don't check for 0\n // and only check for false under certain conditions\n if (value === null ||\n value === undefined ||\n value === '' ||\n (!considerFalseTruthy && value === false)) {\n return false;\n }\n // Evaluate for empty object\n else if ((0, util_1.isEmptyObject)(value)) {\n return false;\n }\n // Evaluate for empty array\n else if (Array.isArray(value) && value.length === 0) {\n return false;\n }\n // Check for moment.js object or Date object\n else if (typeof value === 'object' &&\n (value._isAMomentObject === true || value instanceof Date)) {\n return true;\n }\n // Recursively evaluate\n else if (typeof value === 'object' && !isNestedDatatype) {\n return Object.values(value).some((val) => valueIsPresent(val, considerFalseTruthy, isNestedDatatype));\n }\n // If value is an array, check it's children have value\n else if (Array.isArray(value) && value.length) {\n return (0, util_1.doesArrayDataHaveValue)(value);\n }\n return true;\n};\nconst shouldValidate = (context) => {\n var _a, _b;\n const { component } = context;\n return !!((_a = component.scope) === null || _a === void 0 ? void 0 : _a.required) || !!((_b = component.validate) === null || _b === void 0 ? void 0 : _b.required);\n};\nexports.shouldValidate = shouldValidate;\nconst validateRequired = (context) => __awaiter(void 0, void 0, void 0, function* () {\n return (0, exports.validateRequiredSync)(context);\n});\nexports.validateRequired = validateRequired;\nconst validateRequiredSync = (context) => {\n const error = new error_1.FieldError('required', Object.assign(Object.assign({}, context), { setting: true }));\n const { component, value } = context;\n if (!(0, exports.shouldValidate)(context)) {\n return null;\n }\n if (isAddressComponent(component) && isAddressComponentDataObject(value)) {\n return (0, util_1.isEmptyObject)(value.address)\n ? error\n : Object.entries(value.address)\n .filter(([key]) => !['address2', 'name'].includes(key))\n .every(([, val]) => !!val)\n ? null\n : error;\n }\n else if (isDayComponent(component) && value === '00/00/0000') {\n return error;\n }\n else if (isComponentThatCannotHaveFalseValue(component)) {\n return !valueIsPresent(value, false, (0, formUtil_1.isComponentNestedDataType)(component)) ? error : null;\n }\n return !valueIsPresent(value, true, (0, formUtil_1.isComponentNestedDataType)(component)) ? error : null;\n};\nexports.validateRequiredSync = validateRequiredSync;\nexports.validateRequiredInfo = {\n name: 'validateRequired',\n process: exports.validateRequired,\n processSync: exports.validateRequiredSync,\n shouldProcess: exports.shouldValidate,\n};\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/process/validation/rules/validateRequired.js?");
854
854
 
855
855
  /***/ }),
856
856
 
@@ -1620,7 +1620,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
1620
1620
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1621
1621
 
1622
1622
  "use strict";
1623
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.eachComponentData = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst index_1 = __webpack_require__(/*! ./index */ \"./node_modules/@formio/core/lib/utils/formUtil/index.js\");\nconst eachComponent_1 = __webpack_require__(/*! ./eachComponent */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponent.js\");\n/**\n * Iterates through each component as well as its data, and triggers a callback for every component along\n * with the contextual data for that component in addition to the absolute path for that component.\n * @param components - The array of JSON components to iterate through.\n * @param data - The contextual data object for the components.\n * @param fn - The callback function to trigger for each component following the signature (component, data, row, path, components, index, parent).\n * @param parent - The parent component.\n * @param includeAll\n * @returns\n */\nconst eachComponentData = (components, data, fn, includeAll = false, local = false, parent, parentPaths) => {\n if (!components) {\n return;\n }\n return (0, eachComponent_1.eachComponent)(components, (component, compPath, componentComponents, compParent, compPaths) => {\n const row = (0, index_1.getContextualRowData)(component, data, compPaths, local);\n if (fn(component, data, row, (compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataPath) || '', componentComponents, compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataIndex, compParent, compPaths) === true) {\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n if ((0, index_1.isComponentNestedDataType)(component)) {\n const value = (0, lodash_1.get)(data, local ? (compPaths === null || compPaths === void 0 ? void 0 : compPaths.localDataPath) || '' : (compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataPath) || '');\n if ((0, index_1.getModelType)(component) === 'nestedArray' ||\n (0, index_1.getModelType)(component) === 'nestedDataArray') {\n if (Array.isArray(value) && value.length) {\n for (let i = 0; i < value.length; i++) {\n if (compPaths) {\n compPaths.dataIndex = i;\n }\n (0, exports.eachComponentData)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n }\n else if (includeAll || (0, lodash_1.isUndefined)(value)) {\n (0, exports.eachComponentData)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n else {\n if (!includeAll && !(0, index_1.shouldProcessComponent)(component, row, value)) {\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n (0, exports.eachComponentData)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n else if (!component.type || (0, index_1.getModelType)(component) === 'none') {\n const info = (0, index_1.componentInfo)(component);\n if (info.hasColumns) {\n component.columns.forEach((column) => (0, exports.eachComponentData)(column.components, data, fn, includeAll, local, component, compPaths));\n }\n else if (info.hasRows) {\n component.rows.forEach((row) => {\n if (Array.isArray(row)) {\n row.forEach((row) => (0, exports.eachComponentData)(row.components, data, fn, includeAll, local, component, compPaths));\n }\n });\n }\n else if (info.hasComps) {\n (0, exports.eachComponentData)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n (0, index_1.resetComponentScope)(component);\n return false;\n }, true, parentPaths, parent);\n};\nexports.eachComponentData = eachComponentData;\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/utils/formUtil/eachComponentData.js?");
1623
+ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.eachComponentData = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst index_1 = __webpack_require__(/*! ./index */ \"./node_modules/@formio/core/lib/utils/formUtil/index.js\");\nconst eachComponent_1 = __webpack_require__(/*! ./eachComponent */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponent.js\");\n/**\n * Iterates through each component as well as its data, and triggers a callback for every component along\n * with the contextual data for that component in addition to the absolute path for that component.\n * @param components - The array of JSON components to iterate through.\n * @param data - The contextual data object for the components.\n * @param fn - The callback function to trigger for each component following the signature (component, data, row, path, components, index, parent).\n * @param parent - The parent component.\n * @param includeAll\n * @returns\n */\nconst eachComponentData = (components, data, fn, includeAll = false, local = false, parent, parentPaths) => {\n if (!components) {\n return;\n }\n return (0, eachComponent_1.eachComponent)(components, (component, compPath, componentComponents, compParent, compPaths) => {\n const row = (0, index_1.getContextualRowData)(component, data, compPaths, local);\n if (fn(component, data, row, (component.modelType === 'none' ? compPaths === null || compPaths === void 0 ? void 0 : compPaths.fullPath : compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataPath) || '', componentComponents, compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataIndex, compParent, compPaths) === true) {\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n if ((0, index_1.isComponentNestedDataType)(component)) {\n const value = (0, lodash_1.get)(data, local ? (compPaths === null || compPaths === void 0 ? void 0 : compPaths.localDataPath) || '' : (compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataPath) || '');\n if ((0, index_1.getModelType)(component) === 'nestedArray' ||\n (0, index_1.getModelType)(component) === 'nestedDataArray') {\n if (Array.isArray(value) && value.length) {\n for (let i = 0; i < value.length; i++) {\n if (compPaths) {\n compPaths.dataIndex = i;\n }\n (0, exports.eachComponentData)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n }\n else if (includeAll || (0, lodash_1.isUndefined)(value)) {\n (0, exports.eachComponentData)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n else {\n if (!includeAll && !(0, index_1.shouldProcessComponent)(component, row, value)) {\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n (0, exports.eachComponentData)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n else if (!component.type || (0, index_1.getModelType)(component) === 'none') {\n const info = (0, index_1.componentInfo)(component);\n if (info.hasColumns) {\n component.columns.forEach((column) => (0, exports.eachComponentData)(column.components, data, fn, includeAll, local, component, compPaths));\n }\n else if (info.hasRows) {\n component.rows.forEach((row) => {\n if (Array.isArray(row)) {\n row.forEach((row) => (0, exports.eachComponentData)(row.components, data, fn, includeAll, local, component, compPaths));\n }\n });\n }\n else if (info.hasComps) {\n (0, exports.eachComponentData)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n (0, index_1.resetComponentScope)(component);\n return false;\n }, true, parentPaths, parent);\n};\nexports.eachComponentData = eachComponentData;\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/utils/formUtil/eachComponentData.js?");
1624
1624
 
1625
1625
  /***/ }),
1626
1626
 
@@ -1631,7 +1631,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
1631
1631
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1632
1632
 
1633
1633
  "use strict";
1634
- eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.eachComponentDataAsync = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst index_1 = __webpack_require__(/*! ./index */ \"./node_modules/@formio/core/lib/utils/formUtil/index.js\");\nconst eachComponentAsync_1 = __webpack_require__(/*! ./eachComponentAsync */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponentAsync.js\");\n// Async each component data.\nconst eachComponentDataAsync = (components_1, data_1, fn_1, ...args_1) => __awaiter(void 0, [components_1, data_1, fn_1, ...args_1], void 0, function* (components, data, fn, includeAll = false, local = false, parent, parentPaths) {\n if (!components) {\n return;\n }\n return yield (0, eachComponentAsync_1.eachComponentAsync)(components, (component, compPath, componentComponents, compParent, compPaths) => __awaiter(void 0, void 0, void 0, function* () {\n const row = (0, index_1.getContextualRowData)(component, data, compPaths, local);\n if ((yield fn(component, data, row, (compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataPath) || '', componentComponents, compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataIndex, compParent)) === true) {\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n if ((0, index_1.isComponentNestedDataType)(component)) {\n const value = (0, lodash_1.get)(data, local ? (compPaths === null || compPaths === void 0 ? void 0 : compPaths.localDataPath) || '' : (compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataPath) || '');\n if ((0, index_1.getModelType)(component) === 'nestedArray' ||\n (0, index_1.getModelType)(component) === 'nestedDataArray') {\n if (Array.isArray(value) && value.length) {\n for (let i = 0; i < value.length; i++) {\n if (compPaths) {\n compPaths.dataIndex = i;\n }\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n }\n else if (includeAll) {\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n else {\n if (!includeAll && !(0, index_1.shouldProcessComponent)(component, row, value)) {\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n else if (!component.type || (0, index_1.getModelType)(component) === 'none') {\n const info = (0, index_1.componentInfo)(component);\n if (info.hasColumns) {\n const columnsComponent = component;\n for (const column of columnsComponent.columns) {\n yield (0, exports.eachComponentDataAsync)(column.components, data, fn, includeAll, local, component, compPaths);\n }\n }\n else if (info.hasRows) {\n const rowsComponent = component;\n for (const rowArray of rowsComponent.rows) {\n if (Array.isArray(rowArray)) {\n for (const row of rowArray) {\n yield (0, exports.eachComponentDataAsync)(row.components, data, fn, includeAll, local, component, compPaths);\n }\n }\n }\n }\n else if (info.hasComps) {\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n (0, index_1.resetComponentScope)(component);\n return false;\n }), true, parentPaths, parent);\n});\nexports.eachComponentDataAsync = eachComponentDataAsync;\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/utils/formUtil/eachComponentDataAsync.js?");
1634
+ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.eachComponentDataAsync = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst index_1 = __webpack_require__(/*! ./index */ \"./node_modules/@formio/core/lib/utils/formUtil/index.js\");\nconst eachComponentAsync_1 = __webpack_require__(/*! ./eachComponentAsync */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponentAsync.js\");\n// Async each component data.\nconst eachComponentDataAsync = (components_1, data_1, fn_1, ...args_1) => __awaiter(void 0, [components_1, data_1, fn_1, ...args_1], void 0, function* (components, data, fn, includeAll = false, local = false, parent, parentPaths) {\n if (!components) {\n return;\n }\n return yield (0, eachComponentAsync_1.eachComponentAsync)(components, (component, compPath, componentComponents, compParent, compPaths) => __awaiter(void 0, void 0, void 0, function* () {\n const row = (0, index_1.getContextualRowData)(component, data, compPaths, local);\n if ((yield fn(component, data, row, (component.modelType === 'none' ? compPaths === null || compPaths === void 0 ? void 0 : compPaths.fullPath : compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataPath) || '', componentComponents, compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataIndex, compParent)) === true) {\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n if ((0, index_1.isComponentNestedDataType)(component)) {\n const value = (0, lodash_1.get)(data, local ? (compPaths === null || compPaths === void 0 ? void 0 : compPaths.localDataPath) || '' : (compPaths === null || compPaths === void 0 ? void 0 : compPaths.dataPath) || '');\n if ((0, index_1.getModelType)(component) === 'nestedArray' ||\n (0, index_1.getModelType)(component) === 'nestedDataArray') {\n if (Array.isArray(value) && value.length) {\n for (let i = 0; i < value.length; i++) {\n if (compPaths) {\n compPaths.dataIndex = i;\n }\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n }\n else if (includeAll) {\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n else {\n if (!includeAll && !(0, index_1.shouldProcessComponent)(component, row, value)) {\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n else if (!component.type || (0, index_1.getModelType)(component) === 'none') {\n const info = (0, index_1.componentInfo)(component);\n if (info.hasColumns) {\n const columnsComponent = component;\n for (const column of columnsComponent.columns) {\n yield (0, exports.eachComponentDataAsync)(column.components, data, fn, includeAll, local, component, compPaths);\n }\n }\n else if (info.hasRows) {\n const rowsComponent = component;\n for (const rowArray of rowsComponent.rows) {\n if (Array.isArray(rowArray)) {\n for (const row of rowArray) {\n yield (0, exports.eachComponentDataAsync)(row.components, data, fn, includeAll, local, component, compPaths);\n }\n }\n }\n }\n else if (info.hasComps) {\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, includeAll, local, component, compPaths);\n }\n (0, index_1.resetComponentScope)(component);\n return true;\n }\n (0, index_1.resetComponentScope)(component);\n return false;\n }), true, parentPaths, parent);\n});\nexports.eachComponentDataAsync = eachComponentDataAsync;\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/utils/formUtil/eachComponentDataAsync.js?");
1635
1635
 
1636
1636
  /***/ }),
1637
1637
 
@@ -1642,7 +1642,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
1642
1642
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1643
1643
 
1644
1644
  "use strict";
1645
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.eachComponentDataAsync = exports.eachComponentAsync = exports.eachComponentData = exports.eachComponent = exports.normalizeContext = exports.getComponentErrorField = exports.compareSelectResourceWithObjectTypeValues = exports.isSelectResourceWithObjectValue = exports.getItemTemplateKeys = exports.isComponentDataEmpty = exports.getEmptyValue = exports.findComponent = exports.applyFormChanges = exports.generateFormChange = exports.getStrings = exports.getValue = exports.escapeRegExCharacters = exports.formatAsCurrency = exports.parseFloatExt = exports.hasCondition = exports.removeComponent = exports.findComponents = exports.searchComponents = exports.getComponent = exports.matchComponent = exports.isLayoutComponent = exports.getComponentValue = exports.getComponentData = exports.componentInfo = exports.shouldProcessComponent = exports.getComponentLocalData = exports.getContextualRowData = exports.getContextualRowPath = exports.getComponentKey = exports.getComponentFromPath = exports.getBestMatch = exports.componentMatches = exports.getStringFromComponentPath = exports.getComponentPaths = exports.componentPath = exports.resetComponentScope = exports.setComponentScope = exports.isComponentNestedDataType = exports.getModelType = exports.MODEL_TYPES_OF_KNOWN_COMPONENTS = exports.uniqueName = exports.guid = exports.flattenComponents = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst fast_json_patch_1 = __webpack_require__(/*! fast-json-patch */ \"./node_modules/fast-json-patch/index.mjs\");\nconst types_1 = __webpack_require__(/*! ../../types */ \"./node_modules/@formio/core/lib/types/index.js\");\nconst Evaluator_1 = __webpack_require__(/*! ../Evaluator */ \"./node_modules/@formio/core/lib/utils/Evaluator.js\");\nconst eachComponent_1 = __webpack_require__(/*! ./eachComponent */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponent.js\");\nObject.defineProperty(exports, \"eachComponent\", ({ enumerable: true, get: function () { return eachComponent_1.eachComponent; } }));\nconst eachComponentData_1 = __webpack_require__(/*! ./eachComponentData */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponentData.js\");\nObject.defineProperty(exports, \"eachComponentData\", ({ enumerable: true, get: function () { return eachComponentData_1.eachComponentData; } }));\nconst eachComponentAsync_1 = __webpack_require__(/*! ./eachComponentAsync */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponentAsync.js\");\nObject.defineProperty(exports, \"eachComponentAsync\", ({ enumerable: true, get: function () { return eachComponentAsync_1.eachComponentAsync; } }));\nconst eachComponentDataAsync_1 = __webpack_require__(/*! ./eachComponentDataAsync */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponentDataAsync.js\");\nObject.defineProperty(exports, \"eachComponentDataAsync\", ({ enumerable: true, get: function () { return eachComponentDataAsync_1.eachComponentDataAsync; } }));\n/**\n * Flatten the form components for data manipulation.\n *\n * @param {Object} components\n * The components to iterate.\n * @param {Boolean} includeAll\n * Whether or not to include layout components.\n *\n * @returns {Object}\n * The flattened components map.\n */\nfunction flattenComponents(components, includeAll = false) {\n const flattened = {};\n (0, eachComponent_1.eachComponent)(components, (component, path) => {\n flattened[path] = component;\n }, includeAll);\n return flattened;\n}\nexports.flattenComponents = flattenComponents;\nfunction guid() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\nexports.guid = guid;\n/**\n * Make a filename guaranteed to be unique.\n * @param name\n * @param template\n * @param evalContext\n * @returns {string}\n */\nfunction uniqueName(name, template, evalContext) {\n template = template || '{{fileName}}-{{guid}}';\n //include guid in template anyway, to prevent overwriting issue if filename matches existing file\n if (!template.includes('{{guid}}')) {\n template = `${template}-{{guid}}`;\n }\n const parts = name.split('.');\n let fileName = parts.slice(0, parts.length - 1).join('.');\n const extension = parts.length > 1 ? `.${(0, lodash_1.last)(parts)}` : '';\n //allow only 100 characters from original name to avoid issues with filename length restrictions\n fileName = fileName.substr(0, 100);\n evalContext = Object.assign(evalContext || {}, {\n fileName,\n guid: guid(),\n });\n //only letters, numbers, dots, dashes, underscores and spaces are allowed. Anything else will be replaced with dash\n const uniqueName = `${Evaluator_1.Evaluator.interpolate(template, evalContext)}${extension}`.replace(/[^0-9a-zA-Z.\\-_ ]/g, '-');\n return uniqueName;\n}\nexports.uniqueName = uniqueName;\n/**\n * Defines model types for known components.\n * For now, these will be the only model types supported by the @formio/core library.\n *\n * nestedArray: for components that store their data as an array and have nested components.\n * nestedDataArray: for components that store their data as an array and have nested components, but keeps the value of nested components inside 'data' property.\n * array: for components that store their data as an array.\n * dataObject: for components that store their data in a nested { data: {} } object.\n * object: for components that store their data in an object.\n * map: for components that store their data in a map.\n * content: for components that do not store data.\n * string: for components that store their data as a string.\n * number: for components that store their data as a number.\n * boolean: for components that store their data as a boolean.\n * none: for components that do not store data and should not be included in the submission.\n * any: for components that can store any type of data.\n *\n */\nexports.MODEL_TYPES_OF_KNOWN_COMPONENTS = {\n nestedArray: ['datagrid', 'editgrid', 'datatable', 'dynamicWizard'],\n nestedDataArray: ['tagpad'],\n dataObject: ['form'],\n object: ['container', 'address'],\n map: ['datamap'],\n content: ['htmlelement', 'content'],\n string: [\n 'textfield',\n 'password',\n 'email',\n 'url',\n 'phoneNumber',\n 'day',\n 'datetime',\n 'time',\n 'signature',\n ],\n number: ['number', 'currency'],\n boolean: ['checkbox', 'radio'],\n none: ['table', 'well', 'columns', 'fieldset', 'panel', 'tabs'],\n any: [\n 'survey',\n 'captcha',\n 'textarea',\n 'selectboxes',\n 'tags',\n 'select',\n 'hidden',\n 'button',\n 'datasource',\n 'sketchpad',\n 'reviewpage',\n 'file',\n ],\n};\nfunction getModelType(component) {\n // If the component JSON asserts a model type, use that.\n if (component.modelType) {\n return component.modelType;\n }\n let modelType = 'any';\n // Otherwise, check for known component types.\n for (const type of Object.keys(exports.MODEL_TYPES_OF_KNOWN_COMPONENTS)) {\n if (exports.MODEL_TYPES_OF_KNOWN_COMPONENTS[type].includes(component.type)) {\n modelType = type;\n break;\n }\n }\n // Otherwise check for components that assert no value.\n if (modelType === 'any' && component.input === false) {\n modelType = 'none';\n }\n // To speed up performance of getModelType, we will set the modelType on the component as a non-enumerable property.\n Object.defineProperty(component, 'modelType', {\n enumerable: false,\n writable: true,\n value: modelType,\n });\n // Otherwise default to any.\n return modelType;\n}\nexports.getModelType = getModelType;\nfunction isComponentNestedDataType(component) {\n return (component.tree ||\n getModelType(component) === 'nestedArray' ||\n getModelType(component) === 'nestedDataArray' ||\n getModelType(component) === 'dataObject' ||\n getModelType(component) === 'object' ||\n getModelType(component) === 'map');\n}\nexports.isComponentNestedDataType = isComponentNestedDataType;\nfunction setComponentScope(component, name, value) {\n if (!component) {\n return;\n }\n if (!component.scope) {\n Object.defineProperty(component, 'scope', {\n enumerable: false,\n configurable: true,\n writable: true,\n value: {},\n });\n }\n Object.defineProperty(component.scope, name, {\n enumerable: false,\n writable: false,\n configurable: true,\n value,\n });\n}\nexports.setComponentScope = setComponentScope;\nfunction resetComponentScope(component) {\n if (component.scope) {\n delete component.scope;\n }\n}\nexports.resetComponentScope = resetComponentScope;\n/**\n * Return the component path provided the type of the component path.\n * @param component - The component JSON.\n * @param type - The type of path to return.\n * @returns\n */\nfunction componentPath(component, parent, parentPaths, type) {\n if (!component) {\n return '';\n }\n if (component.component) {\n component = component.component;\n }\n const compModel = getModelType(component);\n // Relative paths are only referenced from the current form.\n const relative = type === types_1.ComponentPath.localPath ||\n type === types_1.ComponentPath.fullLocalPath ||\n type === types_1.ComponentPath.localDataPath;\n // Full paths include all layout component ids in the path.\n const fullPath = type === types_1.ComponentPath.fullPath || type === types_1.ComponentPath.fullLocalPath;\n // See if this is a data path.\n const dataPath = type === types_1.ComponentPath.dataPath || type === types_1.ComponentPath.localDataPath;\n // Determine if this component should include its key.\n const includeKey = fullPath || (!!component.type && compModel !== 'none' && compModel !== 'content');\n // The key is provided if the component can have data or if we are fetching the full path.\n const key = includeKey ? getComponentKey(component) : '';\n if (!parent) {\n // Return the key if there is no parent.\n return key;\n }\n // Get the parent model type.\n const parentModel = getModelType(parent);\n // If there is a parent, then we only return the key if the parent is a nested form and it is a relative path.\n if (relative && parentModel === 'dataObject') {\n return key;\n }\n // Return the parent path.\n let parentPath = (parentPaths === null || parentPaths === void 0 ? void 0 : parentPaths.hasOwnProperty(type)) ? parentPaths[type] || '' : '';\n // For data paths (where we wish to get the path to the data), we need to ensure we append the parent\n // paths to the end of the path so that any component within this component properly references their data.\n if (dataPath && parentPath) {\n if (parentModel === 'nestedArray' || parentModel === 'nestedDataArray') {\n parentPath += `[${(parentPaths === null || parentPaths === void 0 ? void 0 : parentPaths.dataIndex) || 0}]`;\n }\n if (parentModel === 'dataObject' || parentModel === 'nestedDataArray') {\n parentPath += '.data';\n }\n }\n // Return the parent path with its relative component path (if applicable).\n return parentPath ? (key ? `${parentPath}.${key}` : parentPath) : key;\n}\nexports.componentPath = componentPath;\n/**\n * This method determines a components paths provided the component JSON, the parent and the parent paths.\n * @param component\n * @param parent\n * @param parentPaths\n * @returns\n */\nfunction getComponentPaths(component, parent, parentPaths) {\n return {\n path: componentPath(component, parent, parentPaths, types_1.ComponentPath.path),\n fullPath: componentPath(component, parent, parentPaths, types_1.ComponentPath.fullPath),\n localPath: componentPath(component, parent, parentPaths, types_1.ComponentPath.localPath),\n fullLocalPath: componentPath(component, parent, parentPaths, types_1.ComponentPath.fullLocalPath),\n dataPath: componentPath(component, parent, parentPaths, types_1.ComponentPath.dataPath),\n localDataPath: componentPath(component, parent, parentPaths, types_1.ComponentPath.localDataPath),\n dataIndex: parentPaths === null || parentPaths === void 0 ? void 0 : parentPaths.dataIndex,\n };\n}\nexports.getComponentPaths = getComponentPaths;\nfunction getStringFromComponentPath(path) {\n if (!(0, lodash_1.isArray)(path)) {\n return path;\n }\n let strPath = '';\n path.forEach((part, i) => {\n if ((0, lodash_1.isNumber)(part)) {\n strPath += `[${part}]`;\n }\n else {\n strPath += i === 0 ? part : `.${part}`;\n }\n });\n return strPath;\n}\nexports.getStringFromComponentPath = getStringFromComponentPath;\n/**\n * Determines if a component has a match at any of the path types.\n * @param component {Component} - The component JSON to check for matches.\n * @param paths {ComponentPaths} - The current component paths object.\n * @param path {string} - Either the \"form\" or \"data\" path to see if a match occurs.\n * @param dataIndex {number | undefined} - The data index for the current component to match.\n * @param matches {Record<string, ComponentMatch | undefined>} - The current matches object.\n * @param addMatch {(type: ComponentPath | 'key', match: ComponentMatch) => ComponentMatch} - A callback function to allow modules to decorate the match object.\n */\nfunction componentMatches(component, paths, path, dataIndex, matches = {\n path: undefined,\n fullPath: undefined,\n localPath: undefined,\n dataPath: undefined,\n localDataPath: undefined,\n fullLocalPath: undefined,\n key: undefined,\n}, addMatch = (type, match) => {\n return match;\n}) {\n let dataProperty = '';\n if (component.type === 'selectboxes') {\n const valuePath = new RegExp(`(\\\\.${(0, lodash_1.escapeRegExp)(component.key)})(\\\\.[^\\\\.]+)$`);\n const pathMatches = path.match(valuePath);\n if ((pathMatches === null || pathMatches === void 0 ? void 0 : pathMatches.length) === 3) {\n dataProperty = pathMatches[2];\n path = path.replace(valuePath, '$1');\n }\n }\n // Get the current model type.\n const modelType = getModelType(component);\n const dataModel = modelType !== 'none' && modelType !== 'content';\n [\n types_1.ComponentPath.path,\n types_1.ComponentPath.fullPath,\n types_1.ComponentPath.localPath,\n types_1.ComponentPath.fullLocalPath,\n types_1.ComponentPath.dataPath,\n types_1.ComponentPath.localDataPath,\n ].forEach((type) => {\n const dataPath = type === types_1.ComponentPath.dataPath || type === types_1.ComponentPath.localDataPath;\n if (paths[type] === path) {\n const currentMatch = matches[type];\n const currentModelType = (currentMatch === null || currentMatch === void 0 ? void 0 : currentMatch.component)\n ? getModelType(currentMatch.component)\n : 'none';\n const currentDataModel = currentModelType !== 'none' && currentModelType !== 'content';\n if (!currentMatch ||\n (dataPath && dataModel && currentDataModel) || // Replace the current match if this is a dataPath and both are dataModels.\n (!dataPath && dataIndex === paths.dataIndex) // Replace the current match if this is not a dataPath and the indexes are the same.\n ) {\n if (dataPath) {\n const dataPaths = {\n dataPath: paths.dataPath || '',\n localDataPath: paths.localDataPath || '',\n };\n if (dataProperty) {\n dataPaths.dataPath += dataProperty;\n dataPaths.localDataPath += dataProperty;\n }\n matches[type] = addMatch(type, {\n component,\n paths: Object.assign(Object.assign({}, paths), dataPaths),\n });\n }\n else {\n matches[type] = addMatch(type, { component, paths });\n }\n }\n }\n });\n if (!matches.key && component.key === path) {\n matches.key = addMatch('key', { component, paths });\n }\n}\nexports.componentMatches = componentMatches;\nfunction getBestMatch(matches) {\n if (matches.dataPath) {\n return matches.dataPath;\n }\n if (matches.localDataPath) {\n return matches.localDataPath;\n }\n if (matches.fullPath) {\n return matches.fullPath;\n }\n if (matches.path) {\n return matches.path;\n }\n if (matches.fullLocalPath) {\n return matches.fullLocalPath;\n }\n if (matches.localPath) {\n return matches.localPath;\n }\n if (matches.key) {\n return matches.key;\n }\n return undefined;\n}\nexports.getBestMatch = getBestMatch;\n/**\n * This method performs a fuzzy search for a component within a form provided a number of different\n * paths to search.\n */\nfunction getComponentFromPath(components, path, data, dataIndex, includeAll = false) {\n const matches = {\n path: undefined,\n fullPath: undefined,\n localPath: undefined,\n fullLocalPath: undefined,\n dataPath: undefined,\n localDataPath: undefined,\n key: undefined,\n };\n if (data) {\n (0, eachComponentData_1.eachComponentData)(components, data, (component, data, row, compPath, comps, index, parent, paths) => {\n componentMatches(component, paths || {}, path, dataIndex, matches);\n }, includeAll);\n }\n else {\n (0, eachComponent_1.eachComponent)(components, (component, compPath, componentComponents, compParent, paths) => {\n componentMatches(component, paths || {}, path, dataIndex, matches);\n }, includeAll);\n }\n return getBestMatch(matches);\n}\nexports.getComponentFromPath = getComponentFromPath;\n/**\n * Provided a component, this will return the \"data\" key for that component in the contextual data\n * object.\n *\n * @param component\n * @returns\n */\nfunction getComponentKey(component) {\n if (!component) {\n return '';\n }\n if (component.type === 'checkbox' &&\n component.inputType === 'radio' &&\n component.name) {\n return component.name;\n }\n return component.key;\n}\nexports.getComponentKey = getComponentKey;\nfunction getContextualRowPath(component, paths, local) {\n if (!paths) {\n return '';\n }\n const dataPath = local ? paths.localDataPath : paths.dataPath;\n return (dataPath === null || dataPath === void 0 ? void 0 : dataPath.replace(new RegExp(`.?${(0, lodash_1.escapeRegExp)(getComponentKey(component))}$`), '')) || '';\n}\nexports.getContextualRowPath = getContextualRowPath;\nfunction getContextualRowData(component, data, paths, local) {\n const rowPath = getContextualRowPath(component, paths, local);\n return rowPath ? (0, lodash_1.get)(data, rowPath, null) : data;\n}\nexports.getContextualRowData = getContextualRowData;\nfunction getComponentLocalData(paths, data, local) {\n var _a;\n if (local) {\n return data;\n }\n const parentPath = ((_a = paths.dataPath) === null || _a === void 0 ? void 0 : _a.replace(new RegExp(`.?${(0, lodash_1.escapeRegExp)(paths.localDataPath)}$`), '')) || '';\n return parentPath ? (0, lodash_1.get)(data, parentPath, null) : data;\n}\nexports.getComponentLocalData = getComponentLocalData;\nfunction shouldProcessComponent(comp, row, value) {\n var _a;\n if (getModelType(comp) === 'dataObject') {\n const noReferenceAttached = (value === null || value === void 0 ? void 0 : value._id) ? (0, lodash_1.isEmpty)(value.data) && !(0, lodash_1.has)(value, 'form') : false;\n const shouldBeCleared = (!comp.hasOwnProperty('clearOnHide') || comp.clearOnHide) &&\n (comp.hidden || ((_a = comp.scope) === null || _a === void 0 ? void 0 : _a.conditionallyHidden));\n const shouldSkipProcessingNestedFormData = noReferenceAttached || shouldBeCleared;\n if (shouldSkipProcessingNestedFormData) {\n return false;\n }\n }\n return true;\n}\nexports.shouldProcessComponent = shouldProcessComponent;\nfunction componentInfo(component) {\n const hasColumns = component.columns && Array.isArray(component.columns);\n const hasRows = component.rows && Array.isArray(component.rows);\n const hasComps = component.components && Array.isArray(component.components);\n const isContent = getModelType(component) === 'content';\n const isLayout = getModelType(component) === 'none';\n const isInput = !component.hasOwnProperty('input') || !!component.input;\n return {\n hasColumns,\n hasRows,\n hasComps,\n layout: hasColumns || hasRows || (hasComps && !isInput) || isLayout || isContent,\n iterable: hasColumns || hasRows || hasComps || isContent,\n };\n}\nexports.componentInfo = componentInfo;\n// Provided components, data, and a key, this will return the components data.\nfunction getComponentData(components, data, path) {\n const compData = { component: null, data: null };\n (0, eachComponentData_1.eachComponentData)(components, data, (component, data, row, compPath) => {\n if (compPath === path) {\n compData.component = component;\n compData.data = row;\n return true;\n }\n });\n return compData;\n}\nexports.getComponentData = getComponentData;\nfunction getComponentValue(form, data, path, dataIndex, local) {\n var _a, _b;\n const match = getComponentFromPath((form === null || form === void 0 ? void 0 : form.components) || [], path, data, dataIndex);\n if (!match) {\n // Fall back to get the value from the data object.\n return (0, lodash_1.get)(data, path, undefined);\n }\n if (local) {\n return ((_a = match === null || match === void 0 ? void 0 : match.paths) === null || _a === void 0 ? void 0 : _a.localDataPath) ? (0, lodash_1.get)(data, match.paths.localDataPath, undefined) : null;\n }\n return ((_b = match === null || match === void 0 ? void 0 : match.paths) === null || _b === void 0 ? void 0 : _b.dataPath) ? (0, lodash_1.get)(data, match.paths.dataPath, undefined) : null;\n}\nexports.getComponentValue = getComponentValue;\n/**\n * Determine if a component is a layout component or not.\n *\n * @param {Object} component\n * The component to check.\n *\n * @returns {Boolean}\n * Whether or not the component is a layout component.\n */\nfunction isLayoutComponent(component) {\n return Boolean((component.columns &&\n Array.isArray(component.columns)) ||\n (component.rows && Array.isArray(component.rows)) ||\n (component.components &&\n Array.isArray(component.components)));\n}\nexports.isLayoutComponent = isLayoutComponent;\n/**\n * Matches if a component matches the query.\n *\n * @param component\n * @param query\n * @return {boolean}\n */\nfunction matchComponent(component, query, paths) {\n if ((0, lodash_1.isString)(query)) {\n return component.key === query || (paths === null || paths === void 0 ? void 0 : paths.localPath) === query || (paths === null || paths === void 0 ? void 0 : paths.path) === query;\n }\n else {\n let matches = false;\n (0, lodash_1.forOwn)(query, (value, key) => {\n matches = (0, lodash_1.get)(component, key) === value;\n if (!matches) {\n return false;\n }\n });\n return matches;\n }\n}\nexports.matchComponent = matchComponent;\n/**\n * Get a component by its path.\n *\n * @param {Object} components - The components to iterate.\n * @param {String|Object} path - The key of the component to get, or a query of the component to search.\n * @param {boolean} includeAll - Whether or not to include layout components.\n * @returns {Component} - The component that matches the given key, or undefined if not found.\n */\nfunction getComponent(components, path, includeAll = true, dataIndex) {\n var _a;\n return (_a = getComponentFromPath(components, path, undefined, dataIndex, includeAll)) === null || _a === void 0 ? void 0 : _a.component;\n}\nexports.getComponent = getComponent;\n/**\n * Finds a component provided a query of properties of that component.\n *\n * @param components\n * @param query\n * @return {*}\n */\nfunction searchComponents(components, query) {\n const results = [];\n (0, eachComponent_1.eachComponent)(components, (component, compPath, components, parent, compPaths) => {\n if (matchComponent(component, query, compPaths)) {\n results.push(component);\n }\n }, true);\n return results;\n}\nexports.searchComponents = searchComponents;\n/**\n * Deprecated version of findComponents. Renamed to searchComponents.\n * @param {import('@formio/core').Component[]} components - The components to find components within.\n * @param {object} query - The query to use when searching for the components.\n * @returns {import('@formio/core').Component[]} - The result of the component that is found.\n */\nfunction findComponents(components, query) {\n console.warn('formio.js/utils findComponents is deprecated. Use searchComponents instead.');\n return searchComponents(components, query);\n}\nexports.findComponents = findComponents;\n/**\n * Remove a component by path.\n *\n * @param components\n * @param path\n */\nfunction removeComponent(components, path) {\n // @ts-expect-error - I'm not sure why we're using `pop` here if it's a string\n const index = path.pop();\n if (path.length !== 0) {\n components = (0, lodash_1.get)(components, path);\n }\n components.splice(index, 1);\n}\nexports.removeComponent = removeComponent;\n/**\n * Returns if this component has a conditional statement.\n *\n * @param component - The component JSON schema.\n *\n * @returns {boolean} - TRUE - This component has a conditional, FALSE - No conditional provided.\n */\nfunction hasCondition(component) {\n return Boolean(component.customConditional ||\n (component.conditional &&\n (component.conditional.when ||\n component.conditional.json ||\n (component.conditional.conjunction &&\n ((0, lodash_1.isBoolean)(component.conditional.show) ||\n component.conditional.show) &&\n !(0, lodash_1.isEmpty)(component.conditional.conditions)))));\n}\nexports.hasCondition = hasCondition;\n/**\n * Extension of standard #parseFloat(value) function, that also clears input string.\n *\n * @param {any} value\n * The value to parse.\n *\n * @returns {Number}\n * Parsed value.\n */\nfunction parseFloatExt(value) {\n return parseFloat((0, lodash_1.isString)(value) ? value.replace(/[^\\de.+-]/gi, '') : value);\n}\nexports.parseFloatExt = parseFloatExt;\n/**\n * Formats provided value in way how Currency component uses it.\n *\n * @param {any} value\n * The value to format.\n *\n * @returns {String}\n * Value formatted for Currency component.\n */\nfunction formatAsCurrency(value) {\n const parsedValue = parseFloatExt(value);\n if (isNaN(parsedValue)) {\n return '';\n }\n const parts = (0, lodash_1.round)(parsedValue, 2).toString().split('.');\n parts[0] = (0, lodash_1.chunk)(Array.from(parts[0]).reverse(), 3)\n .reverse()\n .map((part) => part.reverse().join(''))\n .join(',');\n parts[1] = (0, lodash_1.pad)(parts[1], 2, '0');\n return parts.join('.');\n}\nexports.formatAsCurrency = formatAsCurrency;\n/**\n * Escapes RegEx characters in provided String value.\n *\n * @param {String} value\n * String for escaping RegEx characters.\n * @returns {string}\n * String with escaped RegEx characters.\n */\nfunction escapeRegExCharacters(value) {\n return value.replace(/[-[\\]/{}()*+?.\\\\^$|]/g, '\\\\$&');\n}\nexports.escapeRegExCharacters = escapeRegExCharacters;\n/**\n * Get the value for a component key, in the given submission.\n *\n * @param {Object} submission\n * A submission object to search.\n * @param {String} key\n * A for components API key to search for.\n */\nfunction getValue(submission, key) {\n const search = (data) => {\n if ((0, lodash_1.isPlainObject)(data)) {\n if ((0, lodash_1.has)(data, key)) {\n return (0, lodash_1.get)(data, key);\n }\n let value = null;\n (0, lodash_1.forOwn)(data, (prop) => {\n const result = search(prop);\n if (!(0, lodash_1.isNil)(result)) {\n value = result;\n return false;\n }\n });\n return value;\n }\n else {\n return null;\n }\n };\n return search(submission.data);\n}\nexports.getValue = getValue;\n/**\n * Iterate over all components in a form and get string values for translation.\n * @param form\n */\nfunction getStrings(form) {\n const properties = [\n 'label',\n 'title',\n 'legend',\n 'tooltip',\n 'description',\n 'placeholder',\n 'prefix',\n 'suffix',\n 'errorLabel',\n 'content',\n 'html',\n ];\n const strings = [];\n (0, eachComponent_1.eachComponent)(form.components, (component) => {\n properties.forEach((property) => {\n if (component.hasOwnProperty(property) && component[property]) {\n strings.push({\n key: component.key,\n type: component.type,\n property,\n string: component[property],\n });\n }\n });\n if ((!component.dataSrc || component.dataSrc === 'values') &&\n component.hasOwnProperty('values') &&\n Array.isArray(component.values) &&\n component.values.length) {\n component.values.forEach((value, index) => {\n strings.push({\n key: component.key,\n property: `value[${index}].label`,\n string: component.values[index].label,\n });\n });\n }\n // Hard coded values from Day component\n if (component.type === 'day') {\n [\n 'day',\n 'month',\n 'year',\n 'Day',\n 'Month',\n 'Year',\n 'january',\n 'february',\n 'march',\n 'april',\n 'may',\n 'june',\n 'july',\n 'august',\n 'september',\n 'october',\n 'november',\n 'december',\n ].forEach((string) => {\n strings.push({\n key: component.key,\n property: 'day',\n string,\n });\n });\n if (component.fields.day.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.day.placeholder',\n string: component.fields.day.placeholder,\n });\n }\n if (component.fields.month.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.month.placeholder',\n string: component.fields.month.placeholder,\n });\n }\n if (component.fields.year.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.year.placeholder',\n string: component.fields.year.placeholder,\n });\n }\n }\n if (component.type === 'editgrid') {\n const string = component.addAnother || 'Add Another';\n if (component.addAnother) {\n strings.push({\n key: component.key,\n property: 'addAnother',\n string,\n });\n }\n }\n if (component.type === 'select') {\n ['loading...', 'Type to search'].forEach((string) => {\n strings.push({\n key: component.key,\n property: 'select',\n string,\n });\n });\n }\n }, true);\n return strings;\n}\nexports.getStrings = getStrings;\n// ?????????????????????????\n// questionable section\nfunction generateFormChange(type, data) {\n let change;\n switch (type) {\n case 'add':\n change = {\n op: 'add',\n key: data.component.key,\n container: data.parent.key, // Parent component\n path: data.path, // Path to container within parent component.\n index: data.index, // Index of component in parent container.\n component: data.component,\n };\n break;\n case 'edit':\n change = {\n op: 'edit',\n key: data.originalComponent.key,\n patches: (0, fast_json_patch_1.compare)(data.originalComponent, data.component),\n };\n // Don't save if nothing changed.\n if (!change.patches.length) {\n change = null;\n }\n break;\n case 'remove':\n change = {\n op: 'remove',\n key: data.component.key,\n };\n break;\n }\n return change;\n}\nexports.generateFormChange = generateFormChange;\nfunction applyFormChanges(form, changes) {\n const failed = [];\n changes.forEach(function (change) {\n let found = false;\n switch (change.op) {\n case 'add': {\n let newComponent = change.component;\n // Find the container to set the component in.\n findComponent(form.components, change.container, null, function (parent) {\n if (!change.container) {\n parent = form;\n }\n // A move will first run an add so remove any existing components with matching key before inserting.\n findComponent(form.components, change.key, null, function (component, path) {\n // If found, use the existing component. (If someone else edited it, the changes would be here)\n newComponent = component;\n removeComponent(form.components, path);\n });\n found = true;\n const container = (0, lodash_1.get)(parent, change.path);\n container.splice(change.index, 0, newComponent);\n });\n break;\n }\n case 'remove':\n findComponent(form.components, change.key, null, function (component, path) {\n found = true;\n const oldComponent = (0, lodash_1.get)(form.components, path);\n if (oldComponent.key !== component.key) {\n path.pop();\n }\n removeComponent(form.components, path);\n });\n break;\n case 'edit':\n findComponent(form.components, change.key, null, function (component, path) {\n found = true;\n try {\n const oldComponent = (0, lodash_1.get)(form.components, path);\n const newComponent = (0, fast_json_patch_1.applyPatch)(component, change.patches).newDocument;\n if (oldComponent.key !== newComponent.key) {\n path.pop();\n }\n (0, lodash_1.set)(form.components, path, newComponent);\n }\n catch (ignoreErr) {\n failed.push(change);\n }\n });\n break;\n case 'move':\n break;\n }\n if (!found) {\n failed.push(change);\n }\n });\n return {\n form,\n failed,\n };\n}\nexports.applyFormChanges = applyFormChanges;\n/**\n * This function will find a component in a form and return the component AND THE PATH to the component in the form.\n * Path to the component is stored as an array of nested components and their indexes.The Path is being filled recursively\n * when you iterating through the nested structure.\n * If the component is not found the callback won't be called and function won't return anything.\n *\n * @param components\n * @param key\n * @param fn\n * @param path\n * @returns {*}\n */\nfunction findComponent(components, key, path, fn) {\n if (!components)\n return;\n path = path || [];\n if (!key) {\n return fn(components);\n }\n components.forEach(function (component, index) {\n const newPath = path.slice();\n // Add an index of the component it iterates through in nested structure\n newPath.push(index);\n if (!component)\n return;\n if (component.hasOwnProperty('columns') && Array.isArray(component.columns)) {\n newPath.push('columns');\n component.columns.forEach(function (column, index) {\n const colPath = newPath.slice();\n colPath.push(index);\n colPath.push('components');\n findComponent(column.components, key, colPath, fn);\n });\n }\n if (component.hasOwnProperty('rows') && Array.isArray(component.rows)) {\n newPath.push('rows');\n component.rows.forEach(function (row, index) {\n const rowPath = newPath.slice();\n rowPath.push(index);\n row.forEach(function (column, index) {\n const colPath = rowPath.slice();\n colPath.push(index);\n colPath.push('components');\n findComponent(column.components, key, colPath, fn);\n });\n });\n }\n if (component.hasOwnProperty('components') && Array.isArray(component.components)) {\n newPath.push('components');\n findComponent(component.components, key, newPath, fn);\n }\n if (component.key === key) {\n //Final callback if the component is found\n fn(component, newPath, components);\n }\n });\n}\nexports.findComponent = findComponent;\nconst isCheckboxComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'checkbox';\nconst isDataGridComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'datagrid';\nconst isEditGridComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'editgrid';\nconst isAddressComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'address';\nconst isDataTableComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'datatable';\nconst hasChildComponents = (component) => (component === null || component === void 0 ? void 0 : component.components) != null;\nconst isDateTimeComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'datetime';\nconst isSelectBoxesComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'selectboxes';\nconst isTextAreaComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'textarea';\nconst isTextFieldComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'textfield';\nfunction getEmptyValue(component) {\n switch (component.type) {\n case 'textarea':\n case 'textfield':\n case 'time':\n case 'datetime':\n case 'day':\n return '';\n case 'datagrid':\n case 'editgrid':\n return [];\n default:\n return null;\n }\n}\nexports.getEmptyValue = getEmptyValue;\nconst replaceBlanks = (value) => {\n const nbsp = '<p>&nbsp;</p>';\n const br = '<p><br></p>';\n const brNbsp = '<p><br>&nbsp;</p>';\n const regExp = new RegExp(`^${nbsp}|${nbsp}$|^${br}|${br}$|^${brNbsp}|${brNbsp}$`, 'g');\n return typeof value === 'string' ? value.replace(regExp, '').trim() : value;\n};\nfunction trimBlanks(value) {\n if (!value) {\n return value;\n }\n if (Array.isArray(value)) {\n value = value.map((val) => replaceBlanks(val));\n }\n else {\n value = replaceBlanks(value);\n }\n return value;\n}\nfunction isValueEmpty(component, value) {\n const compValueIsEmptyArray = (0, lodash_1.isArray)(value) && value.length === 1 ? (0, lodash_1.isEqual)(value[0], getEmptyValue(component)) : false;\n return (value == null || value === '' || ((0, lodash_1.isArray)(value) && value.length === 0) || compValueIsEmptyArray);\n}\nfunction isComponentDataEmpty(component, data, path, valueCond) {\n var _a;\n const value = (0, lodash_1.isNil)(valueCond) ? (0, lodash_1.get)(data, path) : valueCond;\n const addressIgnoreProperties = ['mode', 'address'];\n if (isCheckboxComponent(component)) {\n return isValueEmpty(component, value) || value === false;\n }\n else if (isAddressComponent(component)) {\n if (Object.keys(value).length === 0) {\n return true;\n }\n return !Object.values((0, lodash_1.omit)(value, addressIgnoreProperties)).some(Boolean);\n }\n else if (isDataGridComponent(component) ||\n isEditGridComponent(component) ||\n isDataTableComponent(component) ||\n hasChildComponents(component)) {\n if ((_a = component.components) === null || _a === void 0 ? void 0 : _a.length) {\n let childrenEmpty = true;\n // wrap component in an array to let eachComponentData handle introspection to child components (e.g. this will be different\n // for data grids versus nested forms, etc.)\n (0, eachComponentData_1.eachComponentData)([component], data, (thisComponent, data, row, path) => {\n if (component.key === thisComponent.key)\n return;\n if (!isComponentDataEmpty(thisComponent, data, path)) {\n childrenEmpty = false;\n }\n });\n return isValueEmpty(component, value) || childrenEmpty;\n }\n return isValueEmpty(component, value);\n }\n else if (isDateTimeComponent(component)) {\n return isValueEmpty(component, value) || value.toString() === 'Invalid date';\n }\n else if (isSelectBoxesComponent(component)) {\n let selectBoxEmpty = true;\n for (const key in value) {\n if (value[key]) {\n selectBoxEmpty = false;\n break;\n }\n }\n return isValueEmpty(component, value) || selectBoxEmpty;\n }\n else if (isTextAreaComponent(component)) {\n const isPlain = !component.wysiwyg && !component.editor;\n return isPlain\n ? typeof value === 'string'\n ? isValueEmpty(component, value.trim())\n : isValueEmpty(component, value)\n : isValueEmpty(component, trimBlanks(value));\n }\n else if (isTextFieldComponent(component)) {\n if (component.allowMultipleMasks && !!component.inputMasks && !!component.inputMasks.length) {\n return (isValueEmpty(component, value) ||\n (component.multiple ? value.length === 0 : !value.maskName || !value.value));\n }\n return isValueEmpty(component, value === null || value === void 0 ? void 0 : value.toString().trim());\n }\n return isValueEmpty(component, value);\n}\nexports.isComponentDataEmpty = isComponentDataEmpty;\n/**\n * Returns the template keys inside the template code.\n * @param {string} template - The template to get the keys from.\n * @returns {Array<string>} - The keys inside the template.\n */\nfunction getItemTemplateKeys(template) {\n const templateKeys = [];\n if (!template) {\n return templateKeys;\n }\n const keys = template.match(/({{\\s*(.*?)\\s*}})/g);\n if (keys) {\n keys.forEach((key) => {\n const propKey = key.match(/{{\\s*item\\.(.*?)\\s*}}/);\n if (propKey && propKey.length > 1) {\n templateKeys.push(propKey[1]);\n }\n });\n }\n return templateKeys;\n}\nexports.getItemTemplateKeys = getItemTemplateKeys;\n/**\n * Returns if the component is a select resource with an object for its value.\n * @param {Component} comp - The component to check.\n * @returns {boolean} - TRUE if the component is a select resource with an object for its value; FALSE otherwise.\n */\nfunction isSelectResourceWithObjectValue(comp = {}) {\n const { reference, dataSrc, valueProperty } = comp;\n return reference || (dataSrc === 'resource' && (!valueProperty || valueProperty === 'data'));\n}\nexports.isSelectResourceWithObjectValue = isSelectResourceWithObjectValue;\n/**\n * Compares real select resource value with expected value in condition.\n * @param {any} value - current value of selectcomponent.\n * @param {any} comparedValue - expocted value of select component.\n * @param {SelectComponent} conditionComponent - select component on which the condtion is based.\n * @returns {boolean} - TRUE if the select component current value is equal to the expected value; FALSE otherwise.\n */\nfunction compareSelectResourceWithObjectTypeValues(value, comparedValue, conditionComponent) {\n if (!value || !(0, lodash_1.isPlainObject)(value)) {\n return false;\n }\n const { template, valueProperty } = conditionComponent;\n if (valueProperty === 'data') {\n value = { data: value };\n comparedValue = { data: comparedValue };\n }\n return (0, lodash_1.every)(getItemTemplateKeys(template) || [], (k) => (0, lodash_1.isEqual)((0, lodash_1.get)(value, k), (0, lodash_1.get)(comparedValue, k)));\n}\nexports.compareSelectResourceWithObjectTypeValues = compareSelectResourceWithObjectTypeValues;\nfunction getComponentErrorField(component, context) {\n const toInterpolate = component.errorLabel || component.label || component.placeholder || component.key;\n return Evaluator_1.Evaluator.interpolate(toInterpolate, context);\n}\nexports.getComponentErrorField = getComponentErrorField;\n/**\n * Normalize a context object so that it contains the correct paths and data, and so it can pass into and out of a sandbox for evaluation\n * @param context\n * @returns\n */\nfunction normalizeContext(context) {\n const { data, paths, local, path, form, submission, row, component, instance, value } = context;\n return {\n path: paths ? paths.localDataPath : path,\n data: paths ? getComponentLocalData(paths, data, local) : data,\n form,\n submission,\n row,\n component,\n instance,\n value,\n input: value,\n };\n}\nexports.normalizeContext = normalizeContext;\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/utils/formUtil/index.js?");
1645
+ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.eachComponentDataAsync = exports.eachComponentAsync = exports.eachComponentData = exports.eachComponent = exports.normalizeContext = exports.getComponentErrorField = exports.compareSelectResourceWithObjectTypeValues = exports.isSelectResourceWithObjectValue = exports.getItemTemplateKeys = exports.isComponentDataEmpty = exports.getEmptyValue = exports.findComponent = exports.applyFormChanges = exports.generateFormChange = exports.getStrings = exports.getValue = exports.escapeRegExCharacters = exports.formatAsCurrency = exports.parseFloatExt = exports.hasCondition = exports.removeComponent = exports.findComponents = exports.searchComponents = exports.getComponent = exports.matchComponent = exports.isLayoutComponent = exports.getComponentValue = exports.getComponentData = exports.componentInfo = exports.shouldProcessComponent = exports.getComponentLocalData = exports.getContextualRowData = exports.getContextualRowPath = exports.getComponentKey = exports.getComponentFromPath = exports.getBestMatch = exports.componentMatches = exports.getStringFromComponentPath = exports.getComponentPaths = exports.componentPath = exports.resetComponentScope = exports.setComponentScope = exports.isComponentNestedDataType = exports.getModelType = exports.MODEL_TYPES_OF_KNOWN_COMPONENTS = exports.uniqueName = exports.guid = exports.flattenComponents = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst fast_json_patch_1 = __webpack_require__(/*! fast-json-patch */ \"./node_modules/fast-json-patch/index.mjs\");\nconst types_1 = __webpack_require__(/*! ../../types */ \"./node_modules/@formio/core/lib/types/index.js\");\nconst Evaluator_1 = __webpack_require__(/*! ../Evaluator */ \"./node_modules/@formio/core/lib/utils/Evaluator.js\");\nconst eachComponent_1 = __webpack_require__(/*! ./eachComponent */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponent.js\");\nObject.defineProperty(exports, \"eachComponent\", ({ enumerable: true, get: function () { return eachComponent_1.eachComponent; } }));\nconst eachComponentData_1 = __webpack_require__(/*! ./eachComponentData */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponentData.js\");\nObject.defineProperty(exports, \"eachComponentData\", ({ enumerable: true, get: function () { return eachComponentData_1.eachComponentData; } }));\nconst eachComponentAsync_1 = __webpack_require__(/*! ./eachComponentAsync */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponentAsync.js\");\nObject.defineProperty(exports, \"eachComponentAsync\", ({ enumerable: true, get: function () { return eachComponentAsync_1.eachComponentAsync; } }));\nconst eachComponentDataAsync_1 = __webpack_require__(/*! ./eachComponentDataAsync */ \"./node_modules/@formio/core/lib/utils/formUtil/eachComponentDataAsync.js\");\nObject.defineProperty(exports, \"eachComponentDataAsync\", ({ enumerable: true, get: function () { return eachComponentDataAsync_1.eachComponentDataAsync; } }));\n/**\n * Flatten the form components for data manipulation.\n *\n * @param {Object} components\n * The components to iterate.\n * @param {Boolean} includeAll\n * Whether or not to include layout components.\n *\n * @returns {Object}\n * The flattened components map.\n */\nfunction flattenComponents(components, includeAll = false) {\n const flattened = {};\n (0, eachComponent_1.eachComponent)(components, (component, path) => {\n flattened[path] = component;\n }, includeAll);\n return flattened;\n}\nexports.flattenComponents = flattenComponents;\nfunction guid() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\nexports.guid = guid;\n/**\n * Make a filename guaranteed to be unique.\n * @param name\n * @param template\n * @param evalContext\n * @returns {string}\n */\nfunction uniqueName(name, template, evalContext) {\n template = template || '{{fileName}}-{{guid}}';\n //include guid in template anyway, to prevent overwriting issue if filename matches existing file\n if (!template.includes('{{guid}}')) {\n template = `${template}-{{guid}}`;\n }\n const parts = name.split('.');\n let fileName = parts.slice(0, parts.length - 1).join('.');\n const extension = parts.length > 1 ? `.${(0, lodash_1.last)(parts)}` : '';\n //allow only 100 characters from original name to avoid issues with filename length restrictions\n fileName = fileName.substr(0, 100);\n evalContext = Object.assign(evalContext || {}, {\n fileName,\n guid: guid(),\n });\n //only letters, numbers, dots, dashes, underscores and spaces are allowed. Anything else will be replaced with dash\n const uniqueName = `${Evaluator_1.Evaluator.interpolate(template, evalContext)}${extension}`.replace(/[^0-9a-zA-Z.\\-_ ]/g, '-');\n return uniqueName;\n}\nexports.uniqueName = uniqueName;\n/**\n * Defines model types for known components.\n * For now, these will be the only model types supported by the @formio/core library.\n *\n * nestedArray: for components that store their data as an array and have nested components.\n * nestedDataArray: for components that store their data as an array and have nested components, but keeps the value of nested components inside 'data' property.\n * array: for components that store their data as an array.\n * dataObject: for components that store their data in a nested { data: {} } object.\n * object: for components that store their data in an object.\n * map: for components that store their data in a map.\n * content: for components that do not store data.\n * string: for components that store their data as a string.\n * number: for components that store their data as a number.\n * boolean: for components that store their data as a boolean.\n * none: for components that do not store data and should not be included in the submission.\n * any: for components that can store any type of data.\n *\n */\nexports.MODEL_TYPES_OF_KNOWN_COMPONENTS = {\n nestedArray: ['datagrid', 'editgrid', 'datatable', 'dynamicWizard'],\n nestedDataArray: ['tagpad'],\n dataObject: ['form'],\n object: ['container', 'address'],\n map: ['datamap'],\n content: ['htmlelement', 'content'],\n string: [\n 'textfield',\n 'password',\n 'email',\n 'url',\n 'phoneNumber',\n 'day',\n 'datetime',\n 'time',\n 'signature',\n ],\n number: ['number', 'currency'],\n boolean: ['checkbox', 'radio'],\n none: ['table', 'well', 'columns', 'fieldset', 'panel', 'tabs'],\n any: [\n 'survey',\n 'captcha',\n 'textarea',\n 'selectboxes',\n 'tags',\n 'select',\n 'hidden',\n 'button',\n 'datasource',\n 'sketchpad',\n 'reviewpage',\n 'file',\n ],\n};\nfunction getModelType(component) {\n // If the component JSON asserts a model type, use that.\n if (component.modelType) {\n return component.modelType;\n }\n let modelType = 'any';\n // Otherwise, check for known component types.\n for (const type of Object.keys(exports.MODEL_TYPES_OF_KNOWN_COMPONENTS)) {\n if (exports.MODEL_TYPES_OF_KNOWN_COMPONENTS[type].includes(component.type)) {\n modelType = type;\n break;\n }\n }\n // Otherwise check for components that assert no value.\n if (modelType === 'any' &&\n (component.input === false ||\n (component.components && !component.input))) {\n modelType = 'none';\n }\n // To speed up performance of getModelType, we will set the modelType on the component as a non-enumerable property.\n Object.defineProperty(component, 'modelType', {\n enumerable: false,\n writable: true,\n value: modelType,\n });\n // Otherwise default to any.\n return modelType;\n}\nexports.getModelType = getModelType;\nfunction isComponentNestedDataType(component) {\n return (component.tree ||\n getModelType(component) === 'nestedArray' ||\n getModelType(component) === 'nestedDataArray' ||\n getModelType(component) === 'dataObject' ||\n getModelType(component) === 'object' ||\n getModelType(component) === 'map');\n}\nexports.isComponentNestedDataType = isComponentNestedDataType;\nfunction setComponentScope(component, name, value) {\n if (!component) {\n return;\n }\n if (!component.scope) {\n Object.defineProperty(component, 'scope', {\n enumerable: false,\n configurable: true,\n writable: true,\n value: {},\n });\n }\n Object.defineProperty(component.scope, name, {\n enumerable: false,\n writable: false,\n configurable: true,\n value,\n });\n}\nexports.setComponentScope = setComponentScope;\nfunction resetComponentScope(component) {\n if (component.scope) {\n delete component.scope;\n }\n}\nexports.resetComponentScope = resetComponentScope;\n/**\n * Return the component path provided the type of the component path.\n * @param component - The component JSON.\n * @param type - The type of path to return.\n * @returns\n */\nfunction componentPath(component, parent, parentPaths, type) {\n if (!component) {\n return '';\n }\n if (component.component) {\n component = component.component;\n }\n const compModel = getModelType(component);\n // Relative paths are only referenced from the current form.\n const relative = type === types_1.ComponentPath.localPath ||\n type === types_1.ComponentPath.fullLocalPath ||\n type === types_1.ComponentPath.localDataPath;\n // Full paths include all layout component ids in the path.\n const fullPath = type === types_1.ComponentPath.fullPath || type === types_1.ComponentPath.fullLocalPath;\n // See if this is a data path.\n const dataPath = type === types_1.ComponentPath.dataPath || type === types_1.ComponentPath.localDataPath;\n // Determine if this component should include its key.\n const includeKey = fullPath || (!!component.type && compModel !== 'none');\n // The key is provided if the component can have data or if we are fetching the full path.\n const key = includeKey ? getComponentKey(component) : '';\n if (!parent) {\n // Return the key if there is no parent.\n return key;\n }\n // Get the parent model type.\n const parentModel = getModelType(parent);\n // If there is a parent, then we only return the key if the parent is a nested form and it is a relative path.\n if (relative && parentModel === 'dataObject') {\n return key;\n }\n // Return the parent path.\n let parentPath = (parentPaths === null || parentPaths === void 0 ? void 0 : parentPaths.hasOwnProperty(type)) ? parentPaths[type] || '' : '';\n // For data paths (where we wish to get the path to the data), we need to ensure we append the parent\n // paths to the end of the path so that any component within this component properly references their data.\n if (dataPath && parentPath) {\n if (parentModel === 'nestedArray' || parentModel === 'nestedDataArray') {\n parentPath += `[${(parentPaths === null || parentPaths === void 0 ? void 0 : parentPaths.dataIndex) || 0}]`;\n }\n if (parentModel === 'dataObject' || parentModel === 'nestedDataArray') {\n parentPath += '.data';\n }\n }\n // Return the parent path with its relative component path (if applicable).\n return parentPath ? (key ? `${parentPath}.${key}` : parentPath) : key;\n}\nexports.componentPath = componentPath;\n/**\n * This method determines a components paths provided the component JSON, the parent and the parent paths.\n * @param component\n * @param parent\n * @param parentPaths\n * @returns\n */\nfunction getComponentPaths(component, parent, parentPaths) {\n return {\n path: componentPath(component, parent, parentPaths, types_1.ComponentPath.path),\n fullPath: componentPath(component, parent, parentPaths, types_1.ComponentPath.fullPath),\n localPath: componentPath(component, parent, parentPaths, types_1.ComponentPath.localPath),\n fullLocalPath: componentPath(component, parent, parentPaths, types_1.ComponentPath.fullLocalPath),\n dataPath: componentPath(component, parent, parentPaths, types_1.ComponentPath.dataPath),\n localDataPath: componentPath(component, parent, parentPaths, types_1.ComponentPath.localDataPath),\n dataIndex: parentPaths === null || parentPaths === void 0 ? void 0 : parentPaths.dataIndex,\n };\n}\nexports.getComponentPaths = getComponentPaths;\nfunction getStringFromComponentPath(path) {\n if (!(0, lodash_1.isArray)(path)) {\n return path;\n }\n let strPath = '';\n path.forEach((part, i) => {\n if ((0, lodash_1.isNumber)(part)) {\n strPath += `[${part}]`;\n }\n else {\n strPath += i === 0 ? part : `.${part}`;\n }\n });\n return strPath;\n}\nexports.getStringFromComponentPath = getStringFromComponentPath;\n/**\n * Determines if a component has a match at any of the path types.\n * @param component {Component} - The component JSON to check for matches.\n * @param paths {ComponentPaths} - The current component paths object.\n * @param path {string} - Either the \"form\" or \"data\" path to see if a match occurs.\n * @param dataIndex {number | undefined} - The data index for the current component to match.\n * @param matches {Record<string, ComponentMatch | undefined>} - The current matches object.\n * @param addMatch {(type: ComponentPath | 'key', match: ComponentMatch) => ComponentMatch} - A callback function to allow modules to decorate the match object.\n */\nfunction componentMatches(component, paths, path, dataIndex, matches = {\n path: undefined,\n fullPath: undefined,\n localPath: undefined,\n dataPath: undefined,\n localDataPath: undefined,\n fullLocalPath: undefined,\n key: undefined,\n}, addMatch = (type, match) => {\n return match;\n}) {\n let dataProperty = '';\n if (component.type === 'selectboxes') {\n const valuePath = new RegExp(`(\\\\.${(0, lodash_1.escapeRegExp)(component.key)})(\\\\.[^\\\\.]+)$`);\n const pathMatches = path.match(valuePath);\n if ((pathMatches === null || pathMatches === void 0 ? void 0 : pathMatches.length) === 3) {\n dataProperty = pathMatches[2];\n path = path.replace(valuePath, '$1');\n }\n }\n // Get the current model type.\n const modelType = getModelType(component);\n const dataModel = modelType !== 'none' && modelType !== 'content';\n [\n types_1.ComponentPath.path,\n types_1.ComponentPath.fullPath,\n types_1.ComponentPath.localPath,\n types_1.ComponentPath.fullLocalPath,\n types_1.ComponentPath.dataPath,\n types_1.ComponentPath.localDataPath,\n ].forEach((type) => {\n const dataPath = type === types_1.ComponentPath.dataPath || type === types_1.ComponentPath.localDataPath;\n if (paths[type] === path) {\n const currentMatch = matches[type];\n const currentModelType = (currentMatch === null || currentMatch === void 0 ? void 0 : currentMatch.component)\n ? getModelType(currentMatch.component)\n : 'none';\n const currentDataModel = currentModelType !== 'none' && currentModelType !== 'content';\n if (!currentMatch ||\n (dataPath && dataModel && currentDataModel) || // Replace the current match if this is a dataPath and both are dataModels.\n (!dataPath && !(0, lodash_1.isNil)(paths.dataIndex) && dataIndex === paths.dataIndex) // Replace the current match if this is not a dataPath and the indexes are the same.\n ) {\n if (dataPath) {\n const dataPaths = {\n dataPath: paths.dataPath || '',\n localDataPath: paths.localDataPath || '',\n };\n if (dataProperty) {\n dataPaths.dataPath += dataProperty;\n dataPaths.localDataPath += dataProperty;\n }\n matches[type] = addMatch(type, {\n component,\n paths: Object.assign(Object.assign({}, paths), dataPaths),\n });\n }\n else {\n matches[type] = addMatch(type, { component, paths });\n }\n }\n }\n });\n if (!matches.key && component.key === path) {\n matches.key = addMatch('key', { component, paths });\n }\n}\nexports.componentMatches = componentMatches;\nfunction getBestMatch(matches) {\n if (matches.dataPath) {\n return matches.dataPath;\n }\n if (matches.localDataPath) {\n return matches.localDataPath;\n }\n if (matches.fullPath) {\n return matches.fullPath;\n }\n if (matches.path) {\n return matches.path;\n }\n if (matches.fullLocalPath) {\n return matches.fullLocalPath;\n }\n if (matches.localPath) {\n return matches.localPath;\n }\n if (matches.key) {\n return matches.key;\n }\n return undefined;\n}\nexports.getBestMatch = getBestMatch;\n/**\n * This method performs a fuzzy search for a component within a form provided a number of different\n * paths to search.\n */\nfunction getComponentFromPath(components, path, data, dataIndex, includeAll = false) {\n const matches = {\n path: undefined,\n fullPath: undefined,\n localPath: undefined,\n fullLocalPath: undefined,\n dataPath: undefined,\n localDataPath: undefined,\n key: undefined,\n };\n if (data) {\n (0, eachComponentData_1.eachComponentData)(components, data, (component, data, row, compPath, comps, index, parent, paths) => {\n componentMatches(component, paths || {}, path, dataIndex, matches);\n }, includeAll);\n }\n else {\n (0, eachComponent_1.eachComponent)(components, (component, compPath, componentComponents, compParent, paths) => {\n componentMatches(component, paths || {}, path, dataIndex, matches);\n }, includeAll);\n }\n return getBestMatch(matches);\n}\nexports.getComponentFromPath = getComponentFromPath;\n/**\n * Provided a component, this will return the \"data\" key for that component in the contextual data\n * object.\n *\n * @param component\n * @returns\n */\nfunction getComponentKey(component) {\n if (!component) {\n return '';\n }\n if (component.type === 'checkbox' &&\n component.inputType === 'radio' &&\n component.name) {\n return component.name;\n }\n return component.key;\n}\nexports.getComponentKey = getComponentKey;\nfunction getContextualRowPath(component, paths, local) {\n if (!paths) {\n return '';\n }\n const dataPath = local ? paths.localDataPath : paths.dataPath;\n return (dataPath === null || dataPath === void 0 ? void 0 : dataPath.replace(new RegExp(`.?${(0, lodash_1.escapeRegExp)(getComponentKey(component))}$`), '')) || '';\n}\nexports.getContextualRowPath = getContextualRowPath;\nfunction getContextualRowData(component, data, paths, local) {\n const rowPath = getContextualRowPath(component, paths, local);\n return rowPath ? (0, lodash_1.get)(data, rowPath, null) : data;\n}\nexports.getContextualRowData = getContextualRowData;\nfunction getComponentLocalData(paths, data, local) {\n var _a;\n if (local) {\n return data;\n }\n const parentPath = ((_a = paths.dataPath) === null || _a === void 0 ? void 0 : _a.replace(new RegExp(`.?${(0, lodash_1.escapeRegExp)(paths.localDataPath)}$`), '')) || '';\n return parentPath ? (0, lodash_1.get)(data, parentPath, null) : data;\n}\nexports.getComponentLocalData = getComponentLocalData;\nfunction shouldProcessComponent(comp, row, value) {\n var _a;\n if (getModelType(comp) === 'dataObject') {\n const noReferenceAttached = (value === null || value === void 0 ? void 0 : value._id) ? (0, lodash_1.isEmpty)(value.data) && !(0, lodash_1.has)(value, 'form') : false;\n const shouldBeCleared = (!comp.hasOwnProperty('clearOnHide') || comp.clearOnHide) &&\n (comp.hidden || ((_a = comp.scope) === null || _a === void 0 ? void 0 : _a.conditionallyHidden));\n const shouldSkipProcessingNestedFormData = noReferenceAttached || (shouldBeCleared && !comp.validateWhenHidden);\n if (shouldSkipProcessingNestedFormData) {\n return false;\n }\n }\n return true;\n}\nexports.shouldProcessComponent = shouldProcessComponent;\nfunction componentInfo(component) {\n const hasColumns = component.columns && Array.isArray(component.columns);\n const hasRows = component.rows && Array.isArray(component.rows);\n const hasComps = component.components && Array.isArray(component.components);\n const isContent = getModelType(component) === 'content';\n const isLayout = getModelType(component) === 'none';\n const isInput = (!component.hasOwnProperty('input') && !component.components) || !!component.input;\n return {\n hasColumns,\n hasRows,\n hasComps,\n layout: hasColumns || hasRows || (hasComps && !isInput) || isLayout || isContent,\n iterable: hasColumns || hasRows || hasComps || isContent,\n };\n}\nexports.componentInfo = componentInfo;\n// Provided components, data, and a key, this will return the components data.\nfunction getComponentData(components, data, path) {\n const compData = { component: null, data: null };\n (0, eachComponentData_1.eachComponentData)(components, data, (component, data, row, compPath) => {\n if (compPath === path) {\n compData.component = component;\n compData.data = row;\n return true;\n }\n });\n return compData;\n}\nexports.getComponentData = getComponentData;\nfunction getComponentValue(form, data, path, dataIndex, local) {\n var _a, _b;\n const match = getComponentFromPath((form === null || form === void 0 ? void 0 : form.components) || [], path, data, dataIndex);\n if (!match) {\n // Fall back to get the value from the data object.\n return (0, lodash_1.get)(data, path, undefined);\n }\n if (local) {\n return ((_a = match === null || match === void 0 ? void 0 : match.paths) === null || _a === void 0 ? void 0 : _a.localDataPath) ? (0, lodash_1.get)(data, match.paths.localDataPath, undefined) : null;\n }\n return ((_b = match === null || match === void 0 ? void 0 : match.paths) === null || _b === void 0 ? void 0 : _b.dataPath) ? (0, lodash_1.get)(data, match.paths.dataPath, undefined) : null;\n}\nexports.getComponentValue = getComponentValue;\n/**\n * Determine if a component is a layout component or not.\n *\n * @param {Object} component\n * The component to check.\n *\n * @returns {Boolean}\n * Whether or not the component is a layout component.\n */\nfunction isLayoutComponent(component) {\n return Boolean((component.columns &&\n Array.isArray(component.columns)) ||\n (component.rows && Array.isArray(component.rows)) ||\n (component.components &&\n Array.isArray(component.components)));\n}\nexports.isLayoutComponent = isLayoutComponent;\n/**\n * Matches if a component matches the query.\n *\n * @param component\n * @param query\n * @return {boolean}\n */\nfunction matchComponent(component, query, paths) {\n if ((0, lodash_1.isString)(query)) {\n return component.key === query || (paths === null || paths === void 0 ? void 0 : paths.localPath) === query || (paths === null || paths === void 0 ? void 0 : paths.path) === query;\n }\n else {\n let matches = false;\n (0, lodash_1.forOwn)(query, (value, key) => {\n matches = (0, lodash_1.get)(component, key) === value;\n if (!matches) {\n return false;\n }\n });\n return matches;\n }\n}\nexports.matchComponent = matchComponent;\n/**\n * Get a component by its path.\n *\n * @param {Object} components - The components to iterate.\n * @param {String|Object} path - The key of the component to get, or a query of the component to search.\n * @param {boolean} includeAll - Whether or not to include layout components.\n * @returns {Component} - The component that matches the given key, or undefined if not found.\n */\nfunction getComponent(components, path, includeAll = true, dataIndex) {\n var _a;\n return (_a = getComponentFromPath(components, path, undefined, dataIndex, includeAll)) === null || _a === void 0 ? void 0 : _a.component;\n}\nexports.getComponent = getComponent;\n/**\n * Finds a component provided a query of properties of that component.\n *\n * @param components\n * @param query\n * @return {*}\n */\nfunction searchComponents(components, query) {\n const results = [];\n (0, eachComponent_1.eachComponent)(components, (component, compPath, components, parent, compPaths) => {\n if (matchComponent(component, query, compPaths)) {\n results.push(component);\n }\n }, true);\n return results;\n}\nexports.searchComponents = searchComponents;\n/**\n * Deprecated version of findComponents. Renamed to searchComponents.\n * @param {import('@formio/core').Component[]} components - The components to find components within.\n * @param {object} query - The query to use when searching for the components.\n * @returns {import('@formio/core').Component[]} - The result of the component that is found.\n */\nfunction findComponents(components, query) {\n console.warn('formio.js/utils findComponents is deprecated. Use searchComponents instead.');\n return searchComponents(components, query);\n}\nexports.findComponents = findComponents;\n/**\n * Remove a component by path.\n *\n * @param components\n * @param path\n */\nfunction removeComponent(components, path) {\n // @ts-expect-error - I'm not sure why we're using `pop` here if it's a string\n const index = path.pop();\n if (path.length !== 0) {\n components = (0, lodash_1.get)(components, path);\n }\n components.splice(index, 1);\n}\nexports.removeComponent = removeComponent;\n/**\n * Returns if this component has a conditional statement.\n *\n * @param component - The component JSON schema.\n *\n * @returns {boolean} - TRUE - This component has a conditional, FALSE - No conditional provided.\n */\nfunction hasCondition(component) {\n return Boolean(component.customConditional ||\n (component.conditional &&\n (component.conditional.when ||\n component.conditional.json ||\n (component.conditional.conjunction &&\n ((0, lodash_1.isBoolean)(component.conditional.show) ||\n component.conditional.show) &&\n !(0, lodash_1.isEmpty)(component.conditional.conditions)))));\n}\nexports.hasCondition = hasCondition;\n/**\n * Extension of standard #parseFloat(value) function, that also clears input string.\n *\n * @param {any} value\n * The value to parse.\n *\n * @returns {Number}\n * Parsed value.\n */\nfunction parseFloatExt(value) {\n return parseFloat((0, lodash_1.isString)(value) ? value.replace(/[^\\de.+-]/gi, '') : value);\n}\nexports.parseFloatExt = parseFloatExt;\n/**\n * Formats provided value in way how Currency component uses it.\n *\n * @param {any} value\n * The value to format.\n *\n * @returns {String}\n * Value formatted for Currency component.\n */\nfunction formatAsCurrency(value) {\n const parsedValue = parseFloatExt(value);\n if (isNaN(parsedValue)) {\n return '';\n }\n const parts = (0, lodash_1.round)(parsedValue, 2).toString().split('.');\n parts[0] = (0, lodash_1.chunk)(Array.from(parts[0]).reverse(), 3)\n .reverse()\n .map((part) => part.reverse().join(''))\n .join(',');\n parts[1] = (0, lodash_1.pad)(parts[1], 2, '0');\n return parts.join('.');\n}\nexports.formatAsCurrency = formatAsCurrency;\n/**\n * Escapes RegEx characters in provided String value.\n *\n * @param {String} value\n * String for escaping RegEx characters.\n * @returns {string}\n * String with escaped RegEx characters.\n */\nfunction escapeRegExCharacters(value) {\n return value.replace(/[-[\\]/{}()*+?.\\\\^$|]/g, '\\\\$&');\n}\nexports.escapeRegExCharacters = escapeRegExCharacters;\n/**\n * Get the value for a component key, in the given submission.\n *\n * @param {Object} submission\n * A submission object to search.\n * @param {String} key\n * A for components API key to search for.\n */\nfunction getValue(submission, key) {\n const search = (data) => {\n if ((0, lodash_1.isPlainObject)(data)) {\n if ((0, lodash_1.has)(data, key)) {\n return (0, lodash_1.get)(data, key);\n }\n let value = null;\n (0, lodash_1.forOwn)(data, (prop) => {\n const result = search(prop);\n if (!(0, lodash_1.isNil)(result)) {\n value = result;\n return false;\n }\n });\n return value;\n }\n else {\n return null;\n }\n };\n return search(submission.data);\n}\nexports.getValue = getValue;\n/**\n * Iterate over all components in a form and get string values for translation.\n * @param form\n */\nfunction getStrings(form) {\n const properties = [\n 'label',\n 'title',\n 'legend',\n 'tooltip',\n 'description',\n 'placeholder',\n 'prefix',\n 'suffix',\n 'errorLabel',\n 'content',\n 'html',\n ];\n const strings = [];\n (0, eachComponent_1.eachComponent)(form.components, (component) => {\n properties.forEach((property) => {\n if (component.hasOwnProperty(property) && component[property]) {\n strings.push({\n key: component.key,\n type: component.type,\n property,\n string: component[property],\n });\n }\n });\n if ((!component.dataSrc || component.dataSrc === 'values') &&\n component.hasOwnProperty('values') &&\n Array.isArray(component.values) &&\n component.values.length) {\n component.values.forEach((value, index) => {\n strings.push({\n key: component.key,\n property: `value[${index}].label`,\n string: component.values[index].label,\n });\n });\n }\n // Hard coded values from Day component\n if (component.type === 'day') {\n [\n 'day',\n 'month',\n 'year',\n 'Day',\n 'Month',\n 'Year',\n 'january',\n 'february',\n 'march',\n 'april',\n 'may',\n 'june',\n 'july',\n 'august',\n 'september',\n 'october',\n 'november',\n 'december',\n ].forEach((string) => {\n strings.push({\n key: component.key,\n property: 'day',\n string,\n });\n });\n if (component.fields.day.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.day.placeholder',\n string: component.fields.day.placeholder,\n });\n }\n if (component.fields.month.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.month.placeholder',\n string: component.fields.month.placeholder,\n });\n }\n if (component.fields.year.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.year.placeholder',\n string: component.fields.year.placeholder,\n });\n }\n }\n if (component.type === 'editgrid') {\n const string = component.addAnother || 'Add Another';\n if (component.addAnother) {\n strings.push({\n key: component.key,\n property: 'addAnother',\n string,\n });\n }\n }\n if (component.type === 'select') {\n ['loading...', 'Type to search'].forEach((string) => {\n strings.push({\n key: component.key,\n property: 'select',\n string,\n });\n });\n }\n }, true);\n return strings;\n}\nexports.getStrings = getStrings;\n// ?????????????????????????\n// questionable section\nfunction generateFormChange(type, data) {\n let change;\n switch (type) {\n case 'add':\n change = {\n op: 'add',\n key: data.component.key,\n container: data.parent.key, // Parent component\n path: data.path, // Path to container within parent component.\n index: data.index, // Index of component in parent container.\n component: data.component,\n };\n break;\n case 'edit':\n change = {\n op: 'edit',\n key: data.originalComponent.key,\n patches: (0, fast_json_patch_1.compare)(data.originalComponent, data.component),\n };\n // Don't save if nothing changed.\n if (!change.patches.length) {\n change = null;\n }\n break;\n case 'remove':\n change = {\n op: 'remove',\n key: data.component.key,\n };\n break;\n }\n return change;\n}\nexports.generateFormChange = generateFormChange;\nfunction applyFormChanges(form, changes) {\n const failed = [];\n changes.forEach(function (change) {\n let found = false;\n switch (change.op) {\n case 'add': {\n let newComponent = change.component;\n // Find the container to set the component in.\n findComponent(form.components, change.container, null, function (parent) {\n if (!change.container) {\n parent = form;\n }\n // A move will first run an add so remove any existing components with matching key before inserting.\n findComponent(form.components, change.key, null, function (component, path) {\n // If found, use the existing component. (If someone else edited it, the changes would be here)\n newComponent = component;\n removeComponent(form.components, path);\n });\n found = true;\n const container = (0, lodash_1.get)(parent, change.path);\n container.splice(change.index, 0, newComponent);\n });\n break;\n }\n case 'remove':\n findComponent(form.components, change.key, null, function (component, path) {\n found = true;\n const oldComponent = (0, lodash_1.get)(form.components, path);\n if (oldComponent.key !== component.key) {\n path.pop();\n }\n removeComponent(form.components, path);\n });\n break;\n case 'edit':\n findComponent(form.components, change.key, null, function (component, path) {\n found = true;\n try {\n const oldComponent = (0, lodash_1.get)(form.components, path);\n const newComponent = (0, fast_json_patch_1.applyPatch)(component, change.patches).newDocument;\n if (oldComponent.key !== newComponent.key) {\n path.pop();\n }\n (0, lodash_1.set)(form.components, path, newComponent);\n }\n catch (ignoreErr) {\n failed.push(change);\n }\n });\n break;\n case 'move':\n break;\n }\n if (!found) {\n failed.push(change);\n }\n });\n return {\n form,\n failed,\n };\n}\nexports.applyFormChanges = applyFormChanges;\n/**\n * This function will find a component in a form and return the component AND THE PATH to the component in the form.\n * Path to the component is stored as an array of nested components and their indexes.The Path is being filled recursively\n * when you iterating through the nested structure.\n * If the component is not found the callback won't be called and function won't return anything.\n *\n * @param components\n * @param key\n * @param fn\n * @param path\n * @returns {*}\n */\nfunction findComponent(components, key, path, fn) {\n if (!components)\n return;\n path = path || [];\n if (!key) {\n return fn(components);\n }\n components.forEach(function (component, index) {\n const newPath = path.slice();\n // Add an index of the component it iterates through in nested structure\n newPath.push(index);\n if (!component)\n return;\n if (component.hasOwnProperty('columns') && Array.isArray(component.columns)) {\n newPath.push('columns');\n component.columns.forEach(function (column, index) {\n const colPath = newPath.slice();\n colPath.push(index);\n colPath.push('components');\n findComponent(column.components, key, colPath, fn);\n });\n }\n if (component.hasOwnProperty('rows') && Array.isArray(component.rows)) {\n newPath.push('rows');\n component.rows.forEach(function (row, index) {\n const rowPath = newPath.slice();\n rowPath.push(index);\n row.forEach(function (column, index) {\n const colPath = rowPath.slice();\n colPath.push(index);\n colPath.push('components');\n findComponent(column.components, key, colPath, fn);\n });\n });\n }\n if (component.hasOwnProperty('components') && Array.isArray(component.components)) {\n newPath.push('components');\n findComponent(component.components, key, newPath, fn);\n }\n if (component.key === key) {\n //Final callback if the component is found\n fn(component, newPath, components);\n }\n });\n}\nexports.findComponent = findComponent;\nconst isCheckboxComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'checkbox';\nconst isDataGridComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'datagrid';\nconst isEditGridComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'editgrid';\nconst isAddressComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'address';\nconst isDataTableComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'datatable';\nconst hasChildComponents = (component) => (component === null || component === void 0 ? void 0 : component.components) != null;\nconst isDateTimeComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'datetime';\nconst isSelectBoxesComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'selectboxes';\nconst isTextAreaComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'textarea';\nconst isTextFieldComponent = (component) => (component === null || component === void 0 ? void 0 : component.type) === 'textfield';\nfunction getEmptyValue(component) {\n switch (component.type) {\n case 'textarea':\n case 'textfield':\n case 'time':\n case 'datetime':\n case 'day':\n return '';\n case 'datagrid':\n case 'editgrid':\n return [];\n default:\n return null;\n }\n}\nexports.getEmptyValue = getEmptyValue;\nconst replaceBlanks = (value) => {\n const nbsp = '<p>&nbsp;</p>';\n const br = '<p><br></p>';\n const brNbsp = '<p><br>&nbsp;</p>';\n const regExp = new RegExp(`^${nbsp}|${nbsp}$|^${br}|${br}$|^${brNbsp}|${brNbsp}$`, 'g');\n return typeof value === 'string' ? value.replace(regExp, '').trim() : value;\n};\nfunction trimBlanks(value) {\n if (!value) {\n return value;\n }\n if (Array.isArray(value)) {\n value = value.map((val) => replaceBlanks(val));\n }\n else {\n value = replaceBlanks(value);\n }\n return value;\n}\nfunction isValueEmpty(component, value) {\n const compValueIsEmptyArray = (0, lodash_1.isArray)(value) && value.length === 1 ? (0, lodash_1.isEqual)(value[0], getEmptyValue(component)) : false;\n return (value == null || value === '' || ((0, lodash_1.isArray)(value) && value.length === 0) || compValueIsEmptyArray);\n}\nfunction isComponentDataEmpty(component, data, path, valueCond) {\n var _a;\n const value = (0, lodash_1.isNil)(valueCond) ? (0, lodash_1.get)(data, path) : valueCond;\n const addressIgnoreProperties = ['mode', 'address'];\n if (isCheckboxComponent(component)) {\n return isValueEmpty(component, value) || value === false;\n }\n else if (isAddressComponent(component)) {\n if (Object.keys(value).length === 0) {\n return true;\n }\n return !Object.values((0, lodash_1.omit)(value, addressIgnoreProperties)).some(Boolean);\n }\n else if (isDataGridComponent(component) ||\n isEditGridComponent(component) ||\n isDataTableComponent(component) ||\n hasChildComponents(component)) {\n if ((_a = component.components) === null || _a === void 0 ? void 0 : _a.length) {\n let childrenEmpty = true;\n // wrap component in an array to let eachComponentData handle introspection to child components (e.g. this will be different\n // for data grids versus nested forms, etc.)\n (0, eachComponentData_1.eachComponentData)([component], data, (thisComponent, data, row, path) => {\n if (component.key === thisComponent.key)\n return;\n if (!isComponentDataEmpty(thisComponent, data, path)) {\n childrenEmpty = false;\n }\n });\n return isValueEmpty(component, value) || childrenEmpty;\n }\n return isValueEmpty(component, value);\n }\n else if (isDateTimeComponent(component)) {\n return isValueEmpty(component, value) || value.toString() === 'Invalid date';\n }\n else if (isSelectBoxesComponent(component)) {\n let selectBoxEmpty = true;\n for (const key in value) {\n if (value[key]) {\n selectBoxEmpty = false;\n break;\n }\n }\n return isValueEmpty(component, value) || selectBoxEmpty;\n }\n else if (isTextAreaComponent(component)) {\n const isPlain = !component.wysiwyg && !component.editor;\n return isPlain\n ? typeof value === 'string'\n ? isValueEmpty(component, value.trim())\n : isValueEmpty(component, value)\n : isValueEmpty(component, trimBlanks(value));\n }\n else if (isTextFieldComponent(component)) {\n if (component.allowMultipleMasks && !!component.inputMasks && !!component.inputMasks.length) {\n return (isValueEmpty(component, value) ||\n (component.multiple ? value.length === 0 : !value.maskName || !value.value));\n }\n return isValueEmpty(component, value === null || value === void 0 ? void 0 : value.toString().trim());\n }\n return isValueEmpty(component, value);\n}\nexports.isComponentDataEmpty = isComponentDataEmpty;\n/**\n * Returns the template keys inside the template code.\n * @param {string} template - The template to get the keys from.\n * @returns {Array<string>} - The keys inside the template.\n */\nfunction getItemTemplateKeys(template) {\n const templateKeys = [];\n if (!template) {\n return templateKeys;\n }\n const keys = template.match(/({{\\s*(.*?)\\s*}})/g);\n if (keys) {\n keys.forEach((key) => {\n const propKey = key.match(/{{\\s*item\\.(.*?)\\s*}}/);\n if (propKey && propKey.length > 1) {\n templateKeys.push(propKey[1]);\n }\n });\n }\n return templateKeys;\n}\nexports.getItemTemplateKeys = getItemTemplateKeys;\n/**\n * Returns if the component is a select resource with an object for its value.\n * @param {Component} comp - The component to check.\n * @returns {boolean} - TRUE if the component is a select resource with an object for its value; FALSE otherwise.\n */\nfunction isSelectResourceWithObjectValue(comp = {}) {\n const { reference, dataSrc, valueProperty } = comp;\n return reference || (dataSrc === 'resource' && (!valueProperty || valueProperty === 'data'));\n}\nexports.isSelectResourceWithObjectValue = isSelectResourceWithObjectValue;\n/**\n * Compares real select resource value with expected value in condition.\n * @param {any} value - current value of selectcomponent.\n * @param {any} comparedValue - expocted value of select component.\n * @param {SelectComponent} conditionComponent - select component on which the condtion is based.\n * @returns {boolean} - TRUE if the select component current value is equal to the expected value; FALSE otherwise.\n */\nfunction compareSelectResourceWithObjectTypeValues(value, comparedValue, conditionComponent) {\n if (!value || !(0, lodash_1.isPlainObject)(value)) {\n return false;\n }\n const { template, valueProperty } = conditionComponent;\n if (valueProperty === 'data') {\n value = { data: value };\n comparedValue = { data: comparedValue };\n }\n return (0, lodash_1.every)(getItemTemplateKeys(template) || [], (k) => (0, lodash_1.isEqual)((0, lodash_1.get)(value, k), (0, lodash_1.get)(comparedValue, k)));\n}\nexports.compareSelectResourceWithObjectTypeValues = compareSelectResourceWithObjectTypeValues;\nfunction getComponentErrorField(component, context) {\n const toInterpolate = component.errorLabel || component.label || component.placeholder || component.key;\n return Evaluator_1.Evaluator.interpolate(toInterpolate, context);\n}\nexports.getComponentErrorField = getComponentErrorField;\n/**\n * Normalize a context object so that it contains the correct paths and data, and so it can pass into and out of a sandbox for evaluation\n * @param context\n * @returns\n */\nfunction normalizeContext(context) {\n const { data, paths, local, path, form, submission, row, component, instance, value } = context;\n return {\n path: paths ? paths.localDataPath : path,\n data: paths ? getComponentLocalData(paths, data, local) : data,\n form,\n submission,\n row,\n component,\n instance,\n value,\n input: value,\n };\n}\nexports.normalizeContext = normalizeContext;\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/utils/formUtil/index.js?");
1646
1646
 
1647
1647
  /***/ }),
1648
1648
 
@@ -5084,7 +5084,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
5084
5084
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
5085
5085
 
5086
5086
  "use strict";
5087
- eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Field_1 = __importDefault(__webpack_require__(/*! ../_classes/field/Field */ \"./lib/cjs/components/_classes/field/Field.js\"));\nconst Input_1 = __importDefault(__webpack_require__(/*! ../_classes/input/Input */ \"./lib/cjs/components/_classes/input/Input.js\"));\nconst formUtils_1 = __webpack_require__(/*! ../../utils/formUtils */ \"./lib/cjs/utils/formUtils.js\");\nclass ButtonComponent extends Field_1.default {\n static schema(...extend) {\n return Input_1.default.schema({\n type: 'button',\n label: 'Submit',\n key: 'submit',\n size: 'md',\n leftIcon: '',\n rightIcon: '',\n block: false,\n action: 'submit',\n persistent: false,\n disableOnInvalid: false,\n theme: 'primary',\n dataGridLabel: true\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Button',\n group: 'basic',\n icon: 'stop',\n documentation: '/userguide/form-building/form-components#button',\n weight: 110,\n schema: ButtonComponent.schema()\n };\n }\n static savedValueTypes(schema) {\n return (0, formUtils_1.getComponentSavedTypes)(schema) || [formUtils_1.componentValueTypes.boolean];\n }\n constructor(component, options, data) {\n super(component, options, data);\n this.filesUploading = 0;\n }\n get defaultSchema() {\n return ButtonComponent.schema();\n }\n get inputInfo() {\n const info = super.elementInfo();\n info.type = 'button';\n info.attr.type = (['submit', 'saveState'].includes(this.component.action)) ? 'submit' : 'button';\n this.component.theme = this.component.theme || 'default';\n info.attr.class = `btn btn-${this.component.theme}`;\n if (this.component.size) {\n info.attr.class += ` btn-${this.component.size}`;\n }\n if (this.component.block) {\n info.attr.class += ' btn-block';\n }\n if (this.component.customClass) {\n info.attr.class += ` ${this.component.customClass}`;\n }\n info.content = this.t(this.component.label, { _userInput: true });\n return info;\n }\n get labelInfo() {\n return {\n hidden: true\n };\n }\n set loading(loading) {\n this.setLoading(this.refs.button, loading);\n }\n get skipInEmail() {\n return true;\n }\n // No label needed for buttons.\n createLabel() { }\n createInput(container) {\n this.refs.button = super.createInput(container);\n return this.refs.button;\n }\n get emptyValue() {\n return false;\n }\n getValue() {\n return this.dataValue;\n }\n get clicked() {\n return this.dataValue;\n }\n get defaultValue() {\n return false;\n }\n get className() {\n let className = super.className;\n className += ` ${this.transform('class', 'form-group')}`;\n return className;\n }\n get oauthConfig() {\n if (lodash_1.default.has(this, 'root.form.config.oauth') && this.component.oauthProvider) {\n return this.root.form.config.oauth[this.component.oauthProvider];\n }\n // Legacy oauth location.\n if (this.component.oauth) {\n return this.component.oauth;\n }\n return false;\n }\n render() {\n if (this.viewOnly || this.options.hideButtons) {\n this._visible = false;\n }\n return super.render(this.renderTemplate('button', {\n component: this.component,\n input: this.inputInfo,\n }));\n }\n attachButton() {\n this.addShortcut(this.refs.button);\n let onChange = null;\n let onError = null;\n if (this.component.action === 'submit') {\n this.on('submitButton', () => {\n this.disabled = true;\n }, true);\n this.on('cancelSubmit', () => {\n this.disabled = false;\n }, true);\n this.on('submitDone', (message) => {\n const resultMessage = lodash_1.default.isString(message) ? message : this.t('complete');\n this.loading = false;\n this.disabled = false;\n this.addClass(this.refs.button, 'btn-success submit-success');\n this.removeClass(this.refs.button, 'btn-danger submit-fail');\n this.addClass(this.refs.buttonMessageContainer, 'has-success');\n this.removeClass(this.refs.buttonMessageContainer, 'has-error');\n this.setContent(this.refs.buttonMessage, resultMessage);\n }, true);\n this.on('submitError', (message) => {\n const resultMessage = lodash_1.default.isString(message) ? this.t(message) : this.t(this.errorMessage('submitError'));\n this.loading = false;\n this.disabled = false;\n this.hasError = true;\n this.removeClass(this.refs.button, 'btn-success submit-success');\n this.addClass(this.refs.button, 'btn-danger submit-fail');\n this.removeClass(this.refs.buttonMessageContainer, 'has-success');\n this.addClass(this.refs.buttonMessageContainer, 'has-error');\n this.setContent(this.refs.buttonMessage, resultMessage);\n }, true);\n this.on('fileUploadingStart', () => {\n this.filesUploading++;\n this.disabled = true;\n this.setDisabled(this.refs.button, this.disabled);\n }, true);\n this.on('fileUploadingEnd', () => {\n this.filesUploading--;\n this.disabled = this.shouldDisabled ? true : false;\n this.setDisabled(this.refs.button, this.disabled);\n }, true);\n onChange = (value, isValid) => {\n this.removeClass(this.refs.button, 'btn-success submit-success');\n if (isValid) {\n this.removeClass(this.refs.button, 'btn-danger submit-fail');\n if (this.hasError) {\n this.hasError = false;\n this.setContent(this.refs.buttonMessage, '');\n this.removeClass(this.refs.buttonMessageContainer, 'has-success');\n this.removeClass(this.refs.buttonMessageContainer, 'has-error');\n }\n }\n };\n onError = () => {\n this.hasError = true;\n this.removeClass(this.refs.button, 'btn-success submit-success');\n this.addClass(this.refs.button, 'btn-danger submit-fail');\n this.removeClass(this.refs.buttonMessageContainer, 'has-success');\n this.addClass(this.refs.buttonMessageContainer, 'has-error');\n this.setContent(this.refs.buttonMessage, this.t(this.errorMessage('submitError')));\n };\n }\n if (this.component.action === 'url') {\n this.on('requestButton', () => {\n this.disabled = true;\n }, true);\n this.on('requestDone', () => {\n this.loading = false;\n this.disabled = false;\n }, true);\n }\n this.on('change', (value, flags) => {\n let isValid = value.isValid;\n const isSilent = flags && flags.silent;\n //check root validity only if disableOnInvalid is set and when it is not possible to make submission because of validation errors\n if (flags && flags.noValidate && (this.component.disableOnInvalid || this.hasError)) {\n isValid = flags.rootValidity || (this.root ? (this.root.validate(this.root.data, { dirty: false, silentCheck: true }).length === 0) : true);\n flags.rootValidity = isValid;\n }\n this.isDisabledOnInvalid = this.component.disableOnInvalid && (isSilent || !isValid);\n this.disabled = this.shouldDisabled;\n this.setDisabled(this.refs.button, this.disabled);\n if (onChange) {\n onChange(value, isValid);\n }\n }, true);\n this.on('error', () => {\n this.loading = false;\n this.disabled = false;\n if (onError) {\n onError();\n }\n }, true);\n if (this.component.saveOnEnter) {\n this.root.addEventListener(this.root.element, 'keyup', (event) => {\n if (event.keyCode === 13) {\n this.onClick.call(this, event);\n }\n });\n }\n this.addEventListener(this.refs.button, 'click', this.onClick.bind(this));\n this.addEventListener(this.refs.buttonMessageContainer, 'click', () => {\n if (this.refs.buttonMessageContainer.classList.contains('has-error')) {\n if (this.root && this.root.alert) {\n this.scrollIntoView(this.root.alert);\n }\n }\n });\n this.disabled = this.shouldDisabled;\n this.setDisabled(this.refs.button, this.disabled);\n /**\n * Get url parameter by name\n * @param {string} name - The url parameter\n * @returns {string} - The url parameter value\n */\n function getUrlParameter(name) {\n name = name.replace(/[[]/, '\\\\[').replace(/[\\]]/, '\\\\]');\n const regex = new RegExp(`[\\\\?&]${name}=([^&#]*)`);\n const results = regex.exec(location.search);\n if (!results) {\n return results;\n }\n return decodeURIComponent(results[1].replace(/\\+/g, ' '));\n }\n // If this is an OpenID Provider initiated login, perform the click event immediately\n if ((this.component.action === 'oauth') && this.oauthConfig && !this.oauthConfig.error) {\n const iss = getUrlParameter('iss');\n if (iss && (this.oauthConfig.authURI.indexOf(iss) === 0)) {\n this.openOauth(this.oauthConfig);\n }\n }\n }\n get shouldDisabled() {\n return super.shouldDisabled || this.filesUploading > 0 || this.isDisabledOnInvalid;\n }\n attach(element) {\n this.loadRefs(element, {\n button: 'single',\n buttonMessageContainer: 'single',\n buttonMessage: 'single'\n });\n const superAttach = super.attach(element);\n this.attachButton();\n return superAttach;\n }\n /* eslint-enable max-statements */\n detach(element) {\n if (element && this.refs.button) {\n this.removeShortcut(this.refs.button);\n }\n super.detach();\n }\n onClick(event) {\n this.triggerCaptcha();\n // Don't click if disabled or in builder mode.\n if (this.disabled || this.options.attachMode === 'builder') {\n return;\n }\n this.dataValue = true;\n if (this.component.action !== 'submit' && this.component.showValidations) {\n this.emit('checkValidity', this.data);\n }\n switch (this.component.action) {\n case 'saveState':\n case 'submit':\n event.preventDefault();\n event.stopPropagation();\n this.loading = true;\n this.emit('submitButton', {\n noValidate: this.component.state === 'draft',\n state: this.component.state || 'submitted',\n component: this.component,\n instance: this\n });\n break;\n case 'event':\n this.emit(this.interpolate(this.component.event), this.data);\n this.events.emit(this.interpolate(this.component.event), this.data);\n this.emit('customEvent', {\n type: this.interpolate(this.component.event),\n component: this.component,\n data: this.data,\n event: event\n });\n break;\n case 'custom': {\n // Get the FormioForm at the root of this component's tree\n const form = this.getRoot();\n const flattened = {};\n const components = {};\n (0, formUtils_1.eachComponent)(form.components, (componentWrapper, path) => {\n const component = componentWrapper.component || componentWrapper;\n flattened[path] = component;\n components[component.key] = component;\n }, true);\n this.evaluate(this.component.custom, {\n form,\n flattened,\n components\n });\n this.triggerChange();\n break;\n }\n case 'url':\n this.loading = true;\n this.emit('requestButton', {\n component: this.component,\n instance: this\n });\n this.emit('requestUrl', {\n url: this.interpolate(this.component.url),\n headers: this.component.headers\n });\n break;\n case 'reset':\n this.emit('resetForm');\n break;\n case 'delete':\n this.emit('deleteSubmission');\n break;\n case 'oauth':\n if (this.root === this) {\n console.warn(this.t('noOAuthBtn'));\n return;\n }\n // Display Alert if OAuth config is missing\n if (!this.oauthConfig) {\n this.root.setAlert('danger', this.t('noOAuthConfiguration'));\n break;\n }\n // Display Alert if oAuth has an error is missing\n if (this.oauthConfig.error) {\n this.root.setAlert('danger', `${this.t('oAuthErrorsTitle')} ${this.t(this.oauthConfig.error)}`);\n break;\n }\n this.openOauth(this.oauthConfig);\n break;\n }\n }\n openOauth(settings) {\n if (!this.root.formio) {\n console.warn(this.t('noOAuthFormUrl'));\n return;\n }\n /*eslint-disable camelcase */\n let params = {\n response_type: 'code',\n client_id: settings.clientId,\n redirect_uri: (settings.redirectURI && this.interpolate(settings.redirectURI)) || window.location.origin || `${window.location.protocol}//${window.location.host}`,\n scope: settings.scope\n };\n if (settings.state) {\n params.state = settings.state;\n }\n else if (settings.code_challenge) {\n params.code_challenge = settings.code_challenge;\n params.code_challenge_method = 'S256';\n }\n /*eslint-enable camelcase */\n // Needs for the correct redirection URI for the OpenID\n const originalRedirectUri = params.redirect_uri;\n // Make display optional.\n if (settings.display) {\n params.display = settings.display;\n }\n params = Object.keys(params).map(key => {\n return `${key}=${encodeURIComponent(params[key])}`;\n }).join('&');\n const separator = settings.authURI.indexOf('?') !== -1 ? '&' : '?';\n const url = `${settings.authURI}${separator}${params}`;\n const popup = window.open(url, settings.provider, 'width=1020,height=618');\n const interval = setInterval(() => {\n try {\n const popupHost = popup.location.host;\n const currentHost = window.location.host;\n if (popup && !popup.closed && popupHost === currentHost) {\n popup.close();\n const params = popup.location.search.substr(1).split('&').reduce((params, param) => {\n const split = param.split('=');\n params[split[0]] = split[1];\n return params;\n }, {});\n if (params.error) {\n alert(params.error_description || params.error);\n this.root.setAlert('danger', params.error_description || params.error);\n return;\n }\n // TODO: check for error response here\n if (settings.state !== params.state) {\n this.root.setAlert('danger', this.t('oAuthStateError'));\n return;\n }\n // Depending on where the settings came from, submit to either the submission endpoint (old) or oauth endpoint (new).\n let requestPromise = Promise.resolve();\n if (lodash_1.default.has(this, 'root.form.config.oauth') && this.root.form.config.oauth[this.component.oauthProvider]) {\n params.provider = settings.provider;\n params.redirectURI = originalRedirectUri;\n // Needs for the exclude oAuth Actions that not related to this button\n params.triggeredBy = this.oauthComponentPath;\n requestPromise = this.root.formio.makeRequest('oauth', `${this.root.formio.projectUrl}/oauth2`, 'POST', params);\n }\n else {\n const submission = { data: {}, oauth: {} };\n submission.oauth[settings.provider] = params;\n submission.oauth[settings.provider].redirectURI = originalRedirectUri;\n if (settings.logoutURI) {\n this.root.formio.oauthLogoutURI(settings.logoutURI);\n }\n // Needs for the exclude oAuth Actions that not related to this button\n submission.oauth[settings.provider].triggeredBy = this.oauthComponentPath;\n requestPromise = this.root.formio.saveSubmission(submission);\n }\n requestPromise.then((result) => {\n this.root.onSubmit(result, true);\n })\n .catch((err) => {\n this.root.onSubmissionError(err);\n });\n }\n }\n catch (error) {\n if (error.name !== 'SecurityError' && (error.name !== 'Error' || error.message !== 'Permission denied')) {\n this.root.setAlert('danger', this.t(`${error.message || error}`));\n }\n }\n if (!popup || popup.closed || popup.closed === undefined) {\n clearInterval(interval);\n }\n }, 100);\n }\n get oauthComponentPath() {\n const pathArray = (0, formUtils_1.getArrayFromComponentPath)(this.path);\n return lodash_1.default.chain(pathArray).filter(pathPart => !lodash_1.default.isNumber(pathPart)).join('.').value();\n }\n focus() {\n if (this.refs.button) {\n this.refs.button.focus();\n }\n }\n triggerCaptcha() {\n if (!this.root) {\n return;\n }\n let captchaComponent;\n this.root.everyComponent((component) => {\n if (/^(re)?captcha$/.test(component.component.type) &&\n component.component.eventType === 'buttonClick' &&\n component.component.buttonKey === this.component.key) {\n captchaComponent = component;\n }\n });\n if (captchaComponent) {\n captchaComponent.verify(`${this.component.key}Click`);\n }\n }\n}\nexports[\"default\"] = ButtonComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/button/Button.js?");
5087
+ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Field_1 = __importDefault(__webpack_require__(/*! ../_classes/field/Field */ \"./lib/cjs/components/_classes/field/Field.js\"));\nconst Input_1 = __importDefault(__webpack_require__(/*! ../_classes/input/Input */ \"./lib/cjs/components/_classes/input/Input.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils */ \"./lib/cjs/utils/index.js\");\nclass ButtonComponent extends Field_1.default {\n static schema(...extend) {\n return Input_1.default.schema({\n type: 'button',\n label: 'Submit',\n key: 'submit',\n size: 'md',\n leftIcon: '',\n rightIcon: '',\n block: false,\n action: 'submit',\n persistent: false,\n disableOnInvalid: false,\n theme: 'primary',\n dataGridLabel: true\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Button',\n group: 'basic',\n icon: 'stop',\n documentation: '/userguide/form-building/form-components#button',\n weight: 110,\n schema: ButtonComponent.schema()\n };\n }\n static savedValueTypes(schema) {\n return (0, utils_1.getComponentSavedTypes)(schema) || [utils_1.componentValueTypes.boolean];\n }\n constructor(component, options, data) {\n super(component, options, data);\n this.filesUploading = 0;\n }\n get defaultSchema() {\n return ButtonComponent.schema();\n }\n get inputInfo() {\n const info = super.elementInfo();\n info.type = 'button';\n info.attr.type = (['submit', 'saveState'].includes(this.component.action)) ? 'submit' : 'button';\n this.component.theme = this.component.theme || 'default';\n info.attr.class = `btn btn-${this.component.theme}`;\n if (this.component.size) {\n info.attr.class += ` btn-${this.component.size}`;\n }\n if (this.component.block) {\n info.attr.class += ' btn-block';\n }\n if (this.component.customClass) {\n info.attr.class += ` ${this.component.customClass}`;\n }\n info.content = this.t(this.component.label, { _userInput: true });\n return info;\n }\n get labelInfo() {\n return {\n hidden: true\n };\n }\n set loading(loading) {\n this.setLoading(this.refs.button, loading);\n }\n get skipInEmail() {\n return true;\n }\n // No label needed for buttons.\n createLabel() { }\n createInput(container) {\n this.refs.button = super.createInput(container);\n return this.refs.button;\n }\n get emptyValue() {\n return false;\n }\n getValue() {\n return this.dataValue;\n }\n get clicked() {\n return this.dataValue;\n }\n get defaultValue() {\n return false;\n }\n get className() {\n let className = super.className;\n className += ` ${this.transform('class', 'form-group')}`;\n return className;\n }\n get oauthConfig() {\n if (lodash_1.default.has(this, 'root.form.config.oauth') && this.component.oauthProvider) {\n return this.root.form.config.oauth[this.component.oauthProvider];\n }\n // Legacy oauth location.\n if (this.component.oauth) {\n return this.component.oauth;\n }\n return false;\n }\n render() {\n if (this.viewOnly || this.options.hideButtons) {\n this._visible = false;\n }\n return super.render(this.renderTemplate('button', {\n component: this.component,\n input: this.inputInfo,\n }));\n }\n attachButton() {\n this.addShortcut(this.refs.button);\n let onChange = null;\n let onError = null;\n if (this.component.action === 'submit') {\n this.on('submitButton', () => {\n this.disabled = true;\n }, true);\n this.on('cancelSubmit', () => {\n this.disabled = false;\n }, true);\n this.on('submitDone', (message) => {\n const resultMessage = lodash_1.default.isString(message) ? message : this.t('complete');\n this.loading = false;\n this.disabled = false;\n this.addClass(this.refs.button, 'btn-success submit-success');\n this.removeClass(this.refs.button, 'btn-danger submit-fail');\n this.addClass(this.refs.buttonMessageContainer, 'has-success');\n this.removeClass(this.refs.buttonMessageContainer, 'has-error');\n this.setContent(this.refs.buttonMessage, resultMessage);\n }, true);\n this.on('submitError', (message) => {\n const resultMessage = lodash_1.default.isString(message) ? this.t(message) : this.t(this.errorMessage('submitError'));\n this.loading = false;\n this.disabled = false;\n this.hasError = true;\n this.removeClass(this.refs.button, 'btn-success submit-success');\n this.addClass(this.refs.button, 'btn-danger submit-fail');\n this.removeClass(this.refs.buttonMessageContainer, 'has-success');\n this.addClass(this.refs.buttonMessageContainer, 'has-error');\n this.setContent(this.refs.buttonMessage, resultMessage);\n }, true);\n this.on('fileUploadingStart', () => {\n this.filesUploading++;\n this.disabled = true;\n this.setDisabled(this.refs.button, this.disabled);\n }, true);\n this.on('fileUploadingEnd', () => {\n this.filesUploading--;\n this.disabled = this.shouldDisabled ? true : false;\n this.setDisabled(this.refs.button, this.disabled);\n }, true);\n onChange = (value, isValid) => {\n this.removeClass(this.refs.button, 'btn-success submit-success');\n if (isValid) {\n this.removeClass(this.refs.button, 'btn-danger submit-fail');\n if (this.hasError) {\n this.hasError = false;\n this.setContent(this.refs.buttonMessage, '');\n this.removeClass(this.refs.buttonMessageContainer, 'has-success');\n this.removeClass(this.refs.buttonMessageContainer, 'has-error');\n }\n }\n };\n onError = () => {\n this.hasError = true;\n this.removeClass(this.refs.button, 'btn-success submit-success');\n this.addClass(this.refs.button, 'btn-danger submit-fail');\n this.removeClass(this.refs.buttonMessageContainer, 'has-success');\n this.addClass(this.refs.buttonMessageContainer, 'has-error');\n this.setContent(this.refs.buttonMessage, this.t(this.errorMessage('submitError')));\n };\n }\n if (this.component.action === 'url') {\n this.on('requestButton', () => {\n this.disabled = true;\n }, true);\n this.on('requestDone', () => {\n this.loading = false;\n this.disabled = false;\n }, true);\n }\n this.on('change', (value, flags) => {\n let isValid = value.isValid;\n const isSilent = flags && flags.silent;\n //check root validity only if disableOnInvalid is set and when it is not possible to make submission because of validation errors\n if (flags && flags.noValidate && (this.component.disableOnInvalid || this.hasError)) {\n isValid = flags.rootValidity || (this.root ? (this.root.validate(this.root.data, { dirty: false, silentCheck: true }).length === 0) : true);\n flags.rootValidity = isValid;\n }\n this.isDisabledOnInvalid = this.component.disableOnInvalid && (isSilent || !isValid);\n this.disabled = this.shouldDisabled;\n this.setDisabled(this.refs.button, this.disabled);\n if (onChange) {\n onChange(value, isValid);\n }\n }, true);\n this.on('error', () => {\n this.loading = false;\n this.disabled = false;\n if (onError) {\n onError();\n }\n }, true);\n if (this.component.saveOnEnter) {\n this.root.addEventListener(this.root.element, 'keyup', (event) => {\n if (event.keyCode === 13) {\n this.onClick.call(this, event);\n }\n });\n }\n this.addEventListener(this.refs.button, 'click', this.onClick.bind(this));\n this.addEventListener(this.refs.buttonMessageContainer, 'click', () => {\n if (this.refs.buttonMessageContainer.classList.contains('has-error')) {\n if (this.root && this.root.alert) {\n this.scrollIntoView(this.root.alert);\n }\n }\n });\n this.disabled = this.shouldDisabled;\n this.setDisabled(this.refs.button, this.disabled);\n /**\n * Get url parameter by name\n * @param {string} name - The url parameter\n * @returns {string} - The url parameter value\n */\n function getUrlParameter(name) {\n name = name.replace(/[[]/, '\\\\[').replace(/[\\]]/, '\\\\]');\n const regex = new RegExp(`[\\\\?&]${name}=([^&#]*)`);\n const results = regex.exec(location.search);\n if (!results) {\n return results;\n }\n return decodeURIComponent(results[1].replace(/\\+/g, ' '));\n }\n // If this is an OpenID Provider initiated login, perform the click event immediately\n if ((this.component.action === 'oauth') && this.oauthConfig && !this.oauthConfig.error) {\n const iss = getUrlParameter('iss');\n if (iss && (this.oauthConfig.authURI.indexOf(iss) === 0)) {\n this.openOauth(this.oauthConfig);\n }\n }\n }\n get shouldDisabled() {\n return super.shouldDisabled || this.filesUploading > 0 || this.isDisabledOnInvalid;\n }\n attach(element) {\n this.loadRefs(element, {\n button: 'single',\n buttonMessageContainer: 'single',\n buttonMessage: 'single'\n });\n const superAttach = super.attach(element);\n this.attachButton();\n return superAttach;\n }\n /* eslint-enable max-statements */\n detach(element) {\n if (element && this.refs.button) {\n this.removeShortcut(this.refs.button);\n }\n super.detach();\n }\n onClick(event) {\n this.triggerCaptcha();\n // Don't click if disabled or in builder mode.\n if (this.disabled || this.options.attachMode === 'builder') {\n return;\n }\n this.dataValue = true;\n if (this.component.action !== 'submit' && this.component.showValidations) {\n this.emit('checkValidity', this.data);\n }\n switch (this.component.action) {\n case 'saveState':\n case 'submit':\n event.preventDefault();\n event.stopPropagation();\n this.loading = true;\n this.emit('submitButton', {\n noValidate: this.component.state === 'draft',\n state: this.component.state || 'submitted',\n component: this.component,\n instance: this\n });\n break;\n case 'event':\n this.emit(this.interpolate(this.component.event), this.data);\n this.events.emit(this.interpolate(this.component.event), this.data);\n this.emit('customEvent', {\n type: this.interpolate(this.component.event),\n component: this.component,\n data: this.data,\n event: event\n });\n break;\n case 'custom': {\n // Get the FormioForm at the root of this component's tree\n const form = this.getRoot();\n const flattened = {};\n const components = {};\n (0, utils_1.eachComponent)(form.components, (componentWrapper, path) => {\n const component = componentWrapper.component || componentWrapper;\n flattened[path] = component;\n components[component.key] = component;\n }, true);\n this.evaluate(this.component.custom, {\n form,\n flattened,\n components\n });\n this.triggerChange();\n break;\n }\n case 'url':\n this.loading = true;\n this.emit('requestButton', {\n component: this.component,\n instance: this\n });\n this.emit('requestUrl', {\n url: this.interpolate(this.component.url),\n headers: this.component.headers\n });\n break;\n case 'reset':\n this.emit('resetForm');\n break;\n case 'delete':\n this.emit('deleteSubmission');\n break;\n case 'oauth':\n if (this.root === this) {\n console.warn(this.t('noOAuthBtn'));\n return;\n }\n // Display Alert if OAuth config is missing\n if (!this.oauthConfig) {\n this.root.setAlert('danger', this.t('noOAuthConfiguration'));\n break;\n }\n // Display Alert if oAuth has an error is missing\n if (this.oauthConfig.error) {\n this.root.setAlert('danger', `${this.t('oAuthErrorsTitle')} ${this.t(this.oauthConfig.error)}`);\n break;\n }\n this.openOauth(this.oauthConfig);\n break;\n }\n }\n openOauth(settings) {\n if (!this.root.formio) {\n console.warn(this.t('noOAuthFormUrl'));\n return;\n }\n /*eslint-disable camelcase */\n let params = {\n response_type: 'code',\n client_id: settings.clientId,\n redirect_uri: (settings.redirectURI && this.interpolate(settings.redirectURI)) || window.location.origin || `${window.location.protocol}//${window.location.host}`,\n scope: settings.scope\n };\n if (settings.state) {\n params.state = settings.state;\n }\n else if (settings.code_challenge) {\n params.code_challenge = settings.code_challenge;\n params.code_challenge_method = 'S256';\n }\n /*eslint-enable camelcase */\n // Needs for the correct redirection URI for the OpenID\n const originalRedirectUri = params.redirect_uri;\n // Make display optional.\n if (settings.display) {\n params.display = settings.display;\n }\n params = Object.keys(params).map(key => {\n return `${key}=${encodeURIComponent(params[key])}`;\n }).join('&');\n const separator = settings.authURI.indexOf('?') !== -1 ? '&' : '?';\n const url = `${settings.authURI}${separator}${params}`;\n const popup = window.open(url, settings.provider, 'width=1020,height=618');\n const interval = setInterval(() => {\n try {\n const popupHost = popup.location.host;\n const currentHost = window.location.host;\n if (popup && !popup.closed && popupHost === currentHost) {\n popup.close();\n const params = popup.location.search.substr(1).split('&').reduce((params, param) => {\n const split = param.split('=');\n params[split[0]] = split[1];\n return params;\n }, {});\n if (params.error) {\n alert(params.error_description || params.error);\n this.root.setAlert('danger', params.error_description || params.error);\n return;\n }\n // TODO: check for error response here\n if (settings.state !== params.state) {\n this.root.setAlert('danger', this.t('oAuthStateError'));\n return;\n }\n // Depending on where the settings came from, submit to either the submission endpoint (old) or oauth endpoint (new).\n let requestPromise = Promise.resolve();\n if (lodash_1.default.has(this, 'root.form.config.oauth') && this.root.form.config.oauth[this.component.oauthProvider]) {\n params.provider = settings.provider;\n params.redirectURI = originalRedirectUri;\n // Needs for the exclude oAuth Actions that not related to this button\n params.triggeredBy = this.oauthComponentPath;\n requestPromise = this.root.formio.makeRequest('oauth', `${this.root.formio.projectUrl}/oauth2`, 'POST', params);\n }\n else {\n const submission = { data: {}, oauth: {} };\n submission.oauth[settings.provider] = params;\n submission.oauth[settings.provider].redirectURI = originalRedirectUri;\n if (settings.logoutURI) {\n this.root.formio.oauthLogoutURI(settings.logoutURI);\n }\n // Needs for the exclude oAuth Actions that not related to this button\n submission.oauth[settings.provider].triggeredBy = this.oauthComponentPath;\n requestPromise = this.root.formio.saveSubmission(submission);\n }\n requestPromise.then((result) => {\n this.root.onSubmit(result, true);\n })\n .catch((err) => {\n this.root.onSubmissionError(err);\n });\n }\n }\n catch (error) {\n if (error.name !== 'SecurityError' && (error.name !== 'Error' || error.message !== 'Permission denied')) {\n this.root.setAlert('danger', this.t(`${error.message || error}`));\n }\n }\n if (!popup || popup.closed || popup.closed === undefined) {\n clearInterval(interval);\n }\n }, 100);\n }\n get oauthComponentPath() {\n const pathArray = (0, utils_1.getArrayFromComponentPath)(this.path);\n return lodash_1.default.chain(pathArray).filter(pathPart => !lodash_1.default.isNumber(pathPart)).join('.').value();\n }\n focus() {\n if (this.refs.button) {\n this.refs.button.focus();\n }\n }\n triggerCaptcha() {\n if (!this.root) {\n return;\n }\n let captchaComponent;\n this.root.everyComponent((component) => {\n if (/^(re)?captcha$/.test(component.component.type) &&\n component.component.eventType === 'buttonClick' &&\n component.component.buttonKey === this.component.key) {\n captchaComponent = component;\n }\n });\n if (captchaComponent) {\n captchaComponent.verify(`${this.component.key}Click`);\n }\n }\n}\nexports[\"default\"] = ButtonComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/button/Button.js?");
5088
5088
 
5089
5089
  /***/ }),
5090
5090
 
@@ -5326,7 +5326,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
5326
5326
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
5327
5327
 
5328
5328
  "use strict";
5329
- eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst ListComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/list/ListComponent */ \"./lib/cjs/components/_classes/list/ListComponent.js\"));\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst utils_1 = __webpack_require__(/*! ../../utils */ \"./lib/cjs/utils/index.js\");\nclass RadioComponent extends ListComponent_1.default {\n static schema(...extend) {\n return ListComponent_1.default.schema({\n type: 'radio',\n inputType: 'radio',\n label: 'Radio',\n key: 'radio',\n values: [{ label: '', value: '' }],\n data: {\n url: '',\n },\n fieldSet: false\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Radio',\n group: 'basic',\n icon: 'dot-circle-o',\n weight: 80,\n documentation: '/userguide/form-building/form-components#radio',\n schema: RadioComponent.schema()\n };\n }\n static get conditionOperatorsSettings() {\n return Object.assign(Object.assign({}, super.conditionOperatorsSettings), { valueComponent(classComp) {\n const isValuesSrc = !classComp.dataSrc || classComp.dataSrc === 'values';\n return isValuesSrc\n ? {\n type: 'select',\n dataSrc: 'custom',\n valueProperty: 'value',\n dataType: classComp.dataType || '',\n data: {\n custom: `values = ${classComp && classComp.values ? JSON.stringify(classComp.values) : []}`,\n }\n }\n : Object.assign(Object.assign({}, classComp), { type: 'select' });\n } });\n }\n static get serverConditionSettings() {\n return RadioComponent.conditionOperatorsSettings;\n }\n static savedValueTypes(schema) {\n const { boolean, string, number, object, array } = utils_1.componentValueTypes;\n const { dataType } = schema;\n const types = (0, utils_1.getComponentSavedTypes)(schema);\n if (types) {\n return types;\n }\n if (dataType === 'object') {\n return [object, array];\n }\n if (utils_1.componentValueTypes[dataType]) {\n return [utils_1.componentValueTypes[dataType]];\n }\n return [boolean, string, number, object, array];\n }\n constructor(component, options, data) {\n super(component, options, data);\n this.previousValue = this.dataValue || null;\n }\n get defaultSchema() {\n return RadioComponent.schema();\n }\n get defaultValue() {\n let defaultValue = super.defaultValue;\n if (!defaultValue && this.component.defaultValue === false) {\n defaultValue = this.component.defaultValue;\n }\n return defaultValue;\n }\n resetValue() {\n this.unset();\n this.setValue(this.emptyValue, {\n noUpdateEvent: true,\n noValidate: true,\n resetValue: true\n });\n }\n get inputInfo() {\n var _a;\n const info = super.elementInfo();\n info.type = 'input';\n info.changeEvent = 'click';\n info.attr.class = 'form-check-input';\n info.attr.name = info.attr.name += `[${(_a = this.root) === null || _a === void 0 ? void 0 : _a.id}-${this.id}]`;\n return info;\n }\n get emptyValue() {\n return '';\n }\n get isRadio() {\n return this.component.inputType === 'radio';\n }\n get optionSelectedClass() {\n return 'radio-selected';\n }\n get listData() {\n const listData = lodash_1.default.get(this.root, 'submission.metadata.listData', {});\n return lodash_1.default.get(listData, this.path);\n }\n get selectMetadata() {\n return super.selectData;\n }\n get selectData() {\n return this.selectMetadata || this.component.selectData;\n }\n init() {\n super.init();\n this.templateData = {};\n // Trigger an update.//\n let updateArgs = [];\n const triggerUpdate = lodash_1.default.debounce((...args) => {\n updateArgs = [];\n return this.updateItems.apply(this, args);\n }, 100);\n this.triggerUpdate = (...args) => {\n // Make sure we always resolve the previous promise before reassign it\n if (typeof this.itemsLoadedResolve === 'function') {\n this.itemsLoadedResolve();\n }\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n if (args.length) {\n updateArgs = args;\n }\n return triggerUpdate(...updateArgs);\n };\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n this.optionsLoaded = !this.component.dataSrc || this.component.dataSrc === 'values';\n this.loadedOptions = [];\n if (!this.visible) {\n this.itemsLoadedResolve();\n }\n // Get the template keys for this radio component.\n this.getTemplateKeys();\n }\n beforeSubmit() {\n return new Promise(res => {\n this.dataReady.then(() => res(true));\n });\n }\n render() {\n if (!this.optionsLoaded) {\n return super.render(this.renderTemplate('loader'));\n }\n return super.render(this.renderTemplate('radio', {\n input: this.inputInfo,\n inline: this.component.inline,\n values: this.component.dataSrc === 'values' ? this.component.values : this.loadedOptions,\n value: this.dataValue,\n row: this.row,\n }));\n }\n attach(element) {\n this.loadRefs(element, { input: 'multiple', wrapper: 'multiple' });\n this.refs.input.forEach((input, index) => {\n this.addEventListener(input, this.inputInfo.changeEvent, () => {\n this.updateValue(null, {\n modified: true,\n });\n });\n if (this.component.values[index]) {\n this.addShortcut(input, this.component.values[index].shortcut);\n }\n if (this.isRadio) {\n let dataValue = this.dataValue;\n if (!lodash_1.default.isString(this.dataValue)) {\n dataValue = lodash_1.default.toString(this.dataValue);\n }\n if (this.isSelectURL && lodash_1.default.isObject(this.loadedOptions[index].value)) {\n const optionValue = this.component.dataType === 'string' ? JSON.stringify(this.loadedOptions[index].value) : this.loadedOptions[index].value;\n input.checked = lodash_1.default.isEqual(optionValue, this.dataValue);\n }\n else {\n input.checked = (dataValue === input.value && (input.value || this.component.dataSrc !== 'url'));\n }\n this.addEventListener(input, 'keyup', (event) => {\n if (event.key === ' ' && dataValue === input.value) {\n event.preventDefault();\n this.updateValue(null, {\n modified: true,\n });\n }\n });\n }\n });\n this.triggerUpdate();\n this.setSelectedClasses();\n return super.attach(element);\n }\n detach(element) {\n if (element && this.refs.input) {\n this.refs.input.forEach((input, index) => {\n if (this.component.values[index]) {\n this.removeShortcut(input, this.component.values[index].shortcut);\n }\n });\n }\n super.detach();\n }\n getValue() {\n if (this.viewOnly || !this.refs.input || !this.refs.input.length) {\n return this.dataValue;\n }\n // If the input type of the component is checkbox the value should be determined by the checkboxes checked property\n let value = this.component.inputType === 'checkbox' ? '' : this.dataValue;\n this.refs.input.forEach((input, index) => {\n if (input.checked) {\n value = (this.isSelectURL && lodash_1.default.isObject(this.loadedOptions[index].value)) ?\n this.loadedOptions[index].value :\n input.value;\n }\n });\n return value;\n }\n validateValueProperty() {\n if (this.component.dataSrc === 'values') {\n return true;\n }\n return !lodash_1.default.some(this.refs.wrapper, (wrapper, index) => this.refs.input[index].checked && this.loadedOptions[index].invalid);\n }\n validateValueAvailability(setting, value) {\n if (!(0, utils_1.boolValue)(setting) || !value) {\n return true;\n }\n const values = this.component.dataSrc === 'values' ? this.component.values : this.loadedOptions;\n if (values) {\n return values.findIndex(({ value: optionValue }) => this.normalizeValue(optionValue) === value) !== -1;\n }\n return false;\n }\n getValueAsString(value, options = {}) {\n if (lodash_1.default.isObject(value)) {\n value = JSON.stringify(value);\n }\n else if (!lodash_1.default.isString(value)) {\n value = lodash_1.default.toString(value);\n }\n const shouldUseSelectData = (options.modalPreview || this.inDataTable)\n && this.component.dataSrc === 'url' && (this.loadedOptions.length || this.selectData);\n if (this.component.dataSrc !== 'values' && !shouldUseSelectData) {\n return value;\n }\n const values = shouldUseSelectData ? this.loadedOptions : this.component.values;\n const option = !(values === null || values === void 0 ? void 0 : values.length) && shouldUseSelectData ? {\n label: this.itemTemplate(this.selectData),\n } : lodash_1.default.find(values, (v) => v.value === value);\n if (!value) {\n return lodash_1.default.get(option, 'label', '');\n }\n return lodash_1.default.get(option, 'label', '');\n }\n setValueAt(index, value) {\n if (this.refs.input && this.refs.input[index] && value !== null && value !== undefined) {\n const inputValue = this.refs.input[index].value;\n this.refs.input[index].checked = (inputValue === value.toString());\n }\n }\n get shouldLoad() {\n // do not load options if the value is empty in readOnly and we have options available in metadata\n if (this.options.readOnly && this.isEmpty() && this.listData) {\n return false;\n }\n return super.shouldLoad;\n }\n loadItems(url, search, headers, options, method, body) {\n if (this.optionsLoaded) {\n this.itemsLoadedResolve();\n return;\n }\n if (!this.shouldLoad && this.listData) {\n this.loadItemsFromMetadata();\n this.itemsLoadedResolve();\n this.optionsLoaded = true;\n return;\n }\n // Ensure we have a method and remove any body if method is get\n method = method || 'GET';\n if (method.toUpperCase() === 'GET') {\n body = null;\n }\n const limit = this.component.limit || 100;\n const skip = this.isScrollLoading ? this.selectOptions.length : 0;\n // Allow for url interpolation.\n url = this.sanitize(this.interpolate(url, {\n formioBase: Formio_1.Formio.getBaseUrl(),\n search,\n limit,\n skip,\n page: Math.abs(Math.floor(skip / limit))\n }), this.shouldSanitizeValue);\n // Set ignoreCache if it is\n options.ignoreCache = this.component.ignoreCache;\n // Make the request.\n options.header = headers;\n this.loading = true;\n Formio_1.Formio.makeRequest(this.options.formio, 'select', url, method, body, options)\n .then((response) => {\n this.loading = false;\n this.setItems(response);\n })\n .catch((err) => {\n this.handleLoadingError(err);\n })\n .finally(() => {\n this.optionsLoaded = true;\n this.redraw();\n });\n }\n loadItemsFromMetadata() {\n this.listData.forEach((item, i) => {\n this.loadedOptions[i] = {\n label: this.itemTemplate(item)\n };\n if (lodash_1.default.isEqual(item, this.selectData || lodash_1.default.pick(this.dataValue, lodash_1.default.keys(item)))) {\n this.loadedOptions[i].value = this.dataValue;\n }\n });\n this.optionsLoaded = true;\n this.redraw();\n }\n setItems(items) {\n const listData = [];\n items === null || items === void 0 ? void 0 : items.forEach((item, i) => {\n const valueAtProperty = lodash_1.default.get(item, this.component.valueProperty);\n this.loadedOptions[i] = {\n value: this.component.valueProperty ? valueAtProperty : item,\n label: this.component.valueProperty ? this.itemTemplate(item, valueAtProperty) : this.itemTemplate(item, item, i)\n };\n listData.push(this.templateData[this.component.valueProperty ? valueAtProperty : i]);\n const value = this.loadedOptions[i].value;\n if (!this.isRadio && (lodash_1.default.isObject(value) || lodash_1.default.isBoolean(value) || lodash_1.default.isUndefined(value))) {\n this.loadedOptions[i].invalid = true;\n }\n });\n if (this.isSelectURL) {\n const submission = this.root.submission;\n if (!submission.metadata) {\n submission.metadata = {};\n }\n if (!submission.metadata.listData) {\n submission.metadata.listData = {};\n }\n lodash_1.default.set(submission.metadata.listData, this.path, listData);\n }\n this.itemsLoadedResolve();\n }\n setSelectedClasses() {\n if (this.refs.wrapper) {\n //add/remove selected option class\n const value = this.dataValue;\n this.refs.wrapper.forEach((wrapper, index) => {\n const input = this.refs.input[index];\n const checked = (value === undefined || value === null) ? false : (input.type === 'checkbox') ? value[input.value] || input.checked : (input.value.toString() === value.toString());\n if (checked) {\n //add class to container when selected\n this.addClass(wrapper, this.optionSelectedClass);\n //change \"checked\" attribute\n input.setAttribute('checked', 'true');\n }\n else {\n this.removeClass(wrapper, this.optionSelectedClass);\n input.removeAttribute('checked');\n }\n });\n }\n }\n updateValue(value, flags) {\n const changed = super.updateValue(value, flags);\n if (changed) {\n this.setSelectedClasses();\n }\n if (!flags || !flags.modified || !this.isRadio) {\n if (changed) {\n this.previousValue = this.dataValue;\n }\n return changed;\n }\n // If they clicked on the radio that is currently selected, it needs to reset the value.\n this.currentValue = this.dataValue;\n const shouldResetValue = flags && flags.modified && !flags.noUpdateEvent && this.previousValue === this.currentValue;\n if (shouldResetValue) {\n this.resetValue();\n this.triggerChange(flags);\n this.setSelectedClasses();\n }\n this.previousValue = this.dataValue;\n return changed;\n }\n /**\n * Normalize values coming into updateValue. For example, depending on the configuration, string value `\"true\"` will be normalized to boolean `true`.\n * @param {*} value - The value to normalize\n * @returns {*} - Returns the normalized value\n */\n normalizeValue(value) {\n const dataType = this.component.dataType || 'auto';\n if (value === this.emptyValue) {\n return value;\n }\n switch (dataType) {\n case 'auto':\n if (!isNaN(parseFloat(value)) && isFinite(value) && lodash_1.default.toString(value) === Number(value).toString()) {\n value = +value;\n }\n if (value === 'true') {\n value = true;\n }\n if (value === 'false') {\n value = false;\n }\n break;\n case 'number':\n value = +value;\n break;\n case 'string':\n if (typeof value === 'object') {\n value = JSON.stringify(value);\n }\n else {\n value = String(value);\n }\n break;\n case 'boolean':\n value = !(!value || value.toString() === 'false');\n break;\n }\n if (this.isSelectURL && this.templateData && this.templateData[value]) {\n const submission = this.root.submission;\n if (!submission.metadata.selectData) {\n submission.metadata.selectData = {};\n }\n lodash_1.default.set(submission.metadata.selectData, this.path, this.templateData[value]);\n }\n return super.normalizeValue(value);\n }\n}\nexports[\"default\"] = RadioComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/radio/Radio.js?");
5329
+ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst ListComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/list/ListComponent */ \"./lib/cjs/components/_classes/list/ListComponent.js\"));\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst utils_1 = __webpack_require__(/*! ../../utils */ \"./lib/cjs/utils/index.js\");\nclass RadioComponent extends ListComponent_1.default {\n static schema(...extend) {\n return ListComponent_1.default.schema({\n type: 'radio',\n inputType: 'radio',\n label: 'Radio',\n key: 'radio',\n values: [{ label: '', value: '' }],\n data: {\n url: '',\n },\n fieldSet: false\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Radio',\n group: 'basic',\n icon: 'dot-circle-o',\n weight: 80,\n documentation: '/userguide/form-building/form-components#radio',\n schema: RadioComponent.schema()\n };\n }\n static get conditionOperatorsSettings() {\n return Object.assign(Object.assign({}, super.conditionOperatorsSettings), { valueComponent(classComp) {\n const isValuesSrc = !classComp.dataSrc || classComp.dataSrc === 'values';\n return isValuesSrc\n ? {\n type: 'select',\n dataSrc: 'custom',\n valueProperty: 'value',\n dataType: classComp.dataType || '',\n data: {\n custom: `values = ${classComp && classComp.values ? JSON.stringify(classComp.values) : []}`,\n }\n }\n : Object.assign(Object.assign({}, classComp), { type: 'select' });\n } });\n }\n static get serverConditionSettings() {\n return RadioComponent.conditionOperatorsSettings;\n }\n static savedValueTypes(schema) {\n const { boolean, string, number, object, array } = utils_1.componentValueTypes;\n const { dataType } = schema;\n const types = (0, utils_1.getComponentSavedTypes)(schema);\n if (types) {\n return types;\n }\n if (dataType === 'object') {\n return [object, array];\n }\n if (utils_1.componentValueTypes[dataType]) {\n return [utils_1.componentValueTypes[dataType]];\n }\n return [boolean, string, number, object, array];\n }\n constructor(component, options, data) {\n super(component, options, data);\n this.previousValue = this.dataValue || null;\n }\n get defaultSchema() {\n return RadioComponent.schema();\n }\n get defaultValue() {\n let defaultValue = super.defaultValue;\n if (!defaultValue && this.component.defaultValue === false) {\n defaultValue = this.component.defaultValue;\n }\n return defaultValue;\n }\n resetValue() {\n this.unset();\n this.setValue(this.emptyValue, {\n noUpdateEvent: true,\n noValidate: true,\n resetValue: true\n });\n }\n get inputInfo() {\n var _a;\n const info = super.elementInfo();\n info.type = 'input';\n info.changeEvent = 'click';\n info.attr.class = 'form-check-input';\n info.attr.name = info.attr.name += `[${(_a = this.root) === null || _a === void 0 ? void 0 : _a.id}-${this.id}]`;\n return info;\n }\n get emptyValue() {\n return '';\n }\n get isRadio() {\n return this.component.inputType === 'radio';\n }\n get optionSelectedClass() {\n return 'radio-selected';\n }\n get listData() {\n const listData = lodash_1.default.get(this.root, 'submission.metadata.listData', {});\n return lodash_1.default.get(listData, this.path);\n }\n get selectMetadata() {\n return super.selectData;\n }\n get selectData() {\n return this.selectMetadata || this.component.selectData;\n }\n init() {\n super.init();\n this.templateData = {};\n // Trigger an update.//\n let updateArgs = [];\n const triggerUpdate = lodash_1.default.debounce((...args) => {\n updateArgs = [];\n return this.updateItems.apply(this, args);\n }, 100);\n this.triggerUpdate = (...args) => {\n // Make sure we always resolve the previous promise before reassign it\n if (typeof this.itemsLoadedResolve === 'function') {\n this.itemsLoadedResolve();\n }\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n if (args.length) {\n updateArgs = args;\n }\n return triggerUpdate(...updateArgs);\n };\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n this.optionsLoaded = !this.component.dataSrc || this.component.dataSrc === 'values';\n this.loadedOptions = [];\n if (!this.visible) {\n this.itemsLoadedResolve();\n }\n // Get the template keys for this radio component.\n this.getTemplateKeys();\n }\n beforeSubmit() {\n return new Promise(res => {\n this.dataReady.then(() => res(true));\n });\n }\n convertValues(values) {\n if (this.options.renderMode === 'html' && this.type === 'radio') {\n return values.map(x => (Object.assign(Object.assign({}, x), { value: this.convertByDataType(x.value) })));\n }\n return values;\n }\n render() {\n if (!this.optionsLoaded) {\n return super.render(this.renderTemplate('loader'));\n }\n return super.render(this.renderTemplate('radio', {\n input: this.inputInfo,\n inline: this.component.inline,\n values: this.component.dataSrc === 'values' ? this.convertValues(this.component.values) : this.loadedOptions,\n value: this.dataValue,\n row: this.row,\n }));\n }\n attach(element) {\n this.loadRefs(element, { input: 'multiple', wrapper: 'multiple' });\n this.refs.input.forEach((input, index) => {\n this.addEventListener(input, this.inputInfo.changeEvent, () => {\n this.updateValue(null, {\n modified: true,\n });\n });\n if (this.component.values[index]) {\n this.addShortcut(input, this.component.values[index].shortcut);\n }\n if (this.isRadio) {\n let dataValue = this.dataValue;\n if (!lodash_1.default.isString(this.dataValue)) {\n dataValue = lodash_1.default.toString(this.dataValue);\n }\n if (this.isSelectURL && lodash_1.default.isObject(this.loadedOptions[index].value)) {\n const optionValue = this.component.dataType === 'string' ? JSON.stringify(this.loadedOptions[index].value) : this.loadedOptions[index].value;\n input.checked = lodash_1.default.isEqual(optionValue, this.dataValue);\n }\n else {\n input.checked = (dataValue === input.value && (input.value || this.component.dataSrc !== 'url'));\n }\n this.addEventListener(input, 'keyup', (event) => {\n if (event.key === ' ' && dataValue === input.value) {\n event.preventDefault();\n this.updateValue(null, {\n modified: true,\n });\n }\n });\n }\n });\n this.triggerUpdate();\n this.setSelectedClasses();\n return super.attach(element);\n }\n detach(element) {\n if (element && this.refs.input) {\n this.refs.input.forEach((input, index) => {\n if (this.component.values[index]) {\n this.removeShortcut(input, this.component.values[index].shortcut);\n }\n });\n }\n super.detach();\n }\n getValue() {\n if (this.viewOnly || !this.refs.input || !this.refs.input.length) {\n return this.dataValue;\n }\n // If the input type of the component is checkbox the value should be determined by the checkboxes checked property\n let value = this.component.inputType === 'checkbox' ? '' : this.dataValue;\n this.refs.input.forEach((input, index) => {\n if (input.checked) {\n value = (this.isSelectURL && lodash_1.default.isObject(this.loadedOptions[index].value)) ?\n this.loadedOptions[index].value :\n input.value;\n }\n });\n return value;\n }\n validateValueProperty() {\n if (this.component.dataSrc === 'values') {\n return true;\n }\n return !lodash_1.default.some(this.refs.wrapper, (wrapper, index) => this.refs.input[index].checked && this.loadedOptions[index].invalid);\n }\n validateValueAvailability(setting, value) {\n if (!(0, utils_1.boolValue)(setting) || !value) {\n return true;\n }\n const values = this.component.dataSrc === 'values' ? this.component.values : this.loadedOptions;\n if (values) {\n return values.findIndex(({ value: optionValue }) => this.normalizeValue(optionValue) === value) !== -1;\n }\n return false;\n }\n getValueAsString(value, options = {}) {\n if (lodash_1.default.isObject(value)) {\n value = JSON.stringify(value);\n }\n else if (!lodash_1.default.isString(value)) {\n value = lodash_1.default.toString(value);\n }\n const shouldUseSelectData = (options.modalPreview || this.inDataTable)\n && this.component.dataSrc === 'url' && (this.loadedOptions.length || this.selectData);\n if (this.component.dataSrc !== 'values' && !shouldUseSelectData) {\n return value;\n }\n const values = shouldUseSelectData ? this.loadedOptions : this.component.values;\n const option = !(values === null || values === void 0 ? void 0 : values.length) && shouldUseSelectData ? {\n label: this.itemTemplate(this.selectData),\n } : lodash_1.default.find(values, (v) => v.value === value);\n if (!value) {\n return lodash_1.default.get(option, 'label', '');\n }\n return lodash_1.default.get(option, 'label', '');\n }\n setValueAt(index, value) {\n if (this.refs.input && this.refs.input[index] && value !== null && value !== undefined) {\n const inputValue = this.refs.input[index].value;\n this.refs.input[index].checked = (inputValue === value.toString());\n }\n }\n get shouldLoad() {\n // do not load options if the value is empty in readOnly and we have options available in metadata\n if (this.options.readOnly && this.isEmpty() && this.listData) {\n return false;\n }\n return super.shouldLoad;\n }\n loadItems(url, search, headers, options, method, body) {\n if (this.optionsLoaded) {\n this.itemsLoadedResolve();\n return;\n }\n if (!this.shouldLoad && this.listData) {\n this.loadItemsFromMetadata();\n this.itemsLoadedResolve();\n this.optionsLoaded = true;\n return;\n }\n // Ensure we have a method and remove any body if method is get\n method = method || 'GET';\n if (method.toUpperCase() === 'GET') {\n body = null;\n }\n const limit = this.component.limit || 100;\n const skip = this.isScrollLoading ? this.selectOptions.length : 0;\n // Allow for url interpolation.\n url = this.sanitize(this.interpolate(url, {\n formioBase: Formio_1.Formio.getBaseUrl(),\n search,\n limit,\n skip,\n page: Math.abs(Math.floor(skip / limit))\n }), this.shouldSanitizeValue);\n // Set ignoreCache if it is\n options.ignoreCache = this.component.ignoreCache;\n // Make the request.\n options.header = headers;\n this.loading = true;\n Formio_1.Formio.makeRequest(this.options.formio, 'select', url, method, body, options)\n .then((response) => {\n this.loading = false;\n this.setItems(response);\n })\n .catch((err) => {\n this.handleLoadingError(err);\n })\n .finally(() => {\n this.optionsLoaded = true;\n this.redraw();\n });\n }\n loadItemsFromMetadata() {\n this.listData.forEach((item, i) => {\n this.loadedOptions[i] = {\n label: this.itemTemplate(item)\n };\n if (lodash_1.default.isEqual(item, this.selectData || lodash_1.default.pick(this.dataValue, lodash_1.default.keys(item)))) {\n this.loadedOptions[i].value = this.dataValue;\n }\n });\n this.optionsLoaded = true;\n this.redraw();\n }\n setItems(items) {\n const listData = [];\n items === null || items === void 0 ? void 0 : items.forEach((item, i) => {\n const valueAtProperty = lodash_1.default.get(item, this.component.valueProperty);\n this.loadedOptions[i] = {\n value: this.component.valueProperty ? valueAtProperty : item,\n label: this.component.valueProperty ? this.itemTemplate(item, valueAtProperty) : this.itemTemplate(item, item, i)\n };\n listData.push(this.templateData[this.component.valueProperty ? valueAtProperty : i]);\n const value = this.loadedOptions[i].value;\n if (!this.isRadio && (lodash_1.default.isObject(value) || lodash_1.default.isBoolean(value) || lodash_1.default.isUndefined(value))) {\n this.loadedOptions[i].invalid = true;\n }\n });\n if (this.isSelectURL) {\n const submission = this.root.submission;\n if (!submission.metadata) {\n submission.metadata = {};\n }\n if (!submission.metadata.listData) {\n submission.metadata.listData = {};\n }\n lodash_1.default.set(submission.metadata.listData, this.path, listData);\n }\n this.itemsLoadedResolve();\n }\n setSelectedClasses() {\n if (this.refs.wrapper) {\n //add/remove selected option class\n const value = this.dataValue;\n this.refs.wrapper.forEach((wrapper, index) => {\n const input = this.refs.input[index];\n const checked = (value === undefined || value === null) ? false : (input.type === 'checkbox') ? value[input.value] || input.checked : (input.value.toString() === value.toString());\n if (checked) {\n //add class to container when selected\n this.addClass(wrapper, this.optionSelectedClass);\n //change \"checked\" attribute\n input.setAttribute('checked', 'true');\n }\n else {\n this.removeClass(wrapper, this.optionSelectedClass);\n input.removeAttribute('checked');\n }\n });\n }\n }\n updateValue(value, flags) {\n const changed = super.updateValue(value, flags);\n if (changed) {\n this.setSelectedClasses();\n }\n if (!flags || !flags.modified || !this.isRadio) {\n if (changed) {\n this.previousValue = this.dataValue;\n }\n return changed;\n }\n // If they clicked on the radio that is currently selected, it needs to reset the value.\n this.currentValue = this.dataValue;\n const shouldResetValue = flags && flags.modified && !flags.noUpdateEvent && this.previousValue === this.currentValue;\n if (shouldResetValue) {\n this.resetValue();\n this.triggerChange(flags);\n this.setSelectedClasses();\n }\n this.previousValue = this.dataValue;\n return changed;\n }\n /**\n * Normalize values coming into updateValue. For example, depending on the configuration, string value `\"true\"` will be normalized to boolean `true`.\n * @param {*} value - The value to normalize\n * @returns {*} - Returns the normalized value\n */\n convertByDataType(value) {\n const dataType = this.component.dataType || 'auto';\n if (value === this.emptyValue) {\n return value;\n }\n switch (dataType) {\n case 'auto':\n if (!isNaN(parseFloat(value)) && isFinite(value) && lodash_1.default.toString(value) === Number(value).toString()) {\n value = +value;\n }\n if (value === 'true') {\n value = true;\n }\n if (value === 'false') {\n value = false;\n }\n break;\n case 'number':\n value = +value;\n break;\n case 'string':\n if (typeof value === 'object') {\n value = JSON.stringify(value);\n }\n else {\n value = String(value);\n }\n break;\n case 'boolean':\n value = !(!value || value.toString() === 'false');\n break;\n }\n return value;\n }\n normalizeValue(value) {\n const valueConverted = this.convertByDataType(value);\n if (this.isSelectURL && this.templateData && this.templateData[valueConverted]) {\n const submission = this.root.submission;\n if (!submission.metadata.selectData) {\n submission.metadata.selectData = {};\n }\n lodash_1.default.set(submission.metadata.selectData, this.path, this.templateData[valueConverted]);\n }\n return super.normalizeValue(valueConverted);\n }\n}\nexports[\"default\"] = RadioComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/radio/Radio.js?");
5330
5330
 
5331
5331
  /***/ }),
5332
5332
 
@@ -5348,7 +5348,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
5348
5348
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
5349
5349
 
5350
5350
  "use strict";
5351
- eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst ListComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/list/ListComponent */ \"./lib/cjs/components/_classes/list/ListComponent.js\"));\nconst Form_1 = __importDefault(__webpack_require__(/*! ../../Form */ \"./lib/cjs/Form.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils */ \"./lib/cjs/utils/index.js\");\nconst ChoicesWrapper_1 = __importDefault(__webpack_require__(/*! ../../utils/ChoicesWrapper */ \"./lib/cjs/utils/ChoicesWrapper.js\"));\nclass SelectComponent extends ListComponent_1.default {\n static schema(...extend) {\n return ListComponent_1.default.schema({\n type: 'select',\n label: 'Select',\n key: 'select',\n idPath: 'id',\n data: {\n values: [{ label: '', value: '' }],\n json: '',\n url: '',\n resource: '',\n custom: ''\n },\n clearOnRefresh: false,\n limit: 100,\n valueProperty: '',\n lazyLoad: true,\n filter: '',\n searchEnabled: true,\n searchDebounce: 0.3,\n searchField: '',\n minSearch: 0,\n readOnlyValue: false,\n selectFields: '',\n selectThreshold: 0.3,\n uniqueOptions: false,\n tableView: true,\n fuseOptions: {\n include: 'score',\n threshold: 0.3,\n },\n indexeddb: {\n filter: {}\n },\n customOptions: {},\n useExactSearch: false,\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Select',\n group: 'basic',\n icon: 'th-list',\n weight: 70,\n documentation: '/userguide/form-building/form-components#select',\n schema: SelectComponent.schema()\n };\n }\n static get serverConditionSettings() {\n return SelectComponent.conditionOperatorsSettings;\n }\n static get conditionOperatorsSettings() {\n const numberType = () => ({ type: 'number' });\n return Object.assign(Object.assign({}, super.conditionOperatorsSettings), { valueComponent(classComp) {\n const valueComp = Object.assign(Object.assign({}, classComp), { type: 'select' });\n if ((0, utils_1.isSelectResourceWithObjectValue)(classComp)) {\n valueComp.reference = false;\n valueComp.onSetItems = `\n var templateKeys = utils.getItemTemplateKeys(component.template) || [];\n items = _.map(items || [], i => {\n var item = {};\n _.each(templateKeys, k => _.set(item, k, _.get(i, k)));\n return item;\n })\n `;\n }\n return valueComp;\n }, dataTypeOperators: {\n number: ['lessThan', 'greaterThan', 'lessThanOrEqual', 'greaterThanOrEqual'],\n }, dataTypeValueComponents: {\n number: {\n lessThan: numberType,\n greaterThan: numberType,\n lessThanOrEqual: numberType,\n greaterThanOrEqual: numberType,\n },\n } });\n }\n static savedValueTypes(schema) {\n const { boolean, string, number, object, array } = utils_1.componentValueTypes;\n const { dataType, reference } = schema;\n const types = (0, utils_1.getComponentSavedTypes)(schema);\n if (types) {\n return types;\n }\n if (reference) {\n return [object];\n }\n if (dataType === 'object') {\n return [object, array];\n }\n if (utils_1.componentValueTypes[dataType]) {\n return [utils_1.componentValueTypes[dataType]];\n }\n return [boolean, string, number, object, array];\n }\n init() {\n super.init();\n this.templateData = {};\n // Trigger an update.\n let updateArgs = [];\n const triggerUpdate = lodash_1.default.debounce((...args) => {\n updateArgs = [];\n return this.updateItems.apply(this, args);\n }, 100);\n this.triggerUpdate = (...args) => {\n // Make sure we always resolve the previous promise before reassign it\n if (typeof this.itemsLoadedResolve === 'function') {\n this.itemsLoadedResolve();\n }\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n if (args.length) {\n updateArgs = args;\n }\n return triggerUpdate(...updateArgs);\n };\n // Keep track of the select options.\n this.selectOptions = [];\n if (this.itemsFromUrl) {\n this.isFromSearch = false;\n this.searchServerCount = null;\n this.defaultServerCount = null;\n this.isScrollLoading = false;\n this.searchDownloadedResources = [];\n this.defaultDownloadedResources = [];\n }\n // If this component has been activated.//\n this.activated = false;\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n this.shouldPositionDropdown = this.hasDataGridAncestor();\n if (this.isHtmlRenderMode()) {\n this.activate();\n }\n // Get the template keys for this select component.\n this.getTemplateKeys();\n }\n get defaultSchema() {\n return SelectComponent.schema();\n }\n get emptyValue() {\n if (this.component.multiple) {\n return [];\n }\n // if select has JSON data source type, we are defining if empty value would be an object or a string by checking JSON's first item\n if (this.component.dataSrc === 'json' && this.component.data.json) {\n const firstItem = this.component.data.json[0];\n let firstValue;\n if (this.valueProperty) {\n firstValue = lodash_1.default.get(firstItem, this.valueProperty);\n }\n else {\n firstValue = firstItem;\n }\n if (firstValue && typeof firstValue === 'string') {\n return '';\n }\n else {\n return {};\n }\n }\n if (this.valueProperty) {\n return '';\n }\n return {};\n }\n get valueProperty() {\n if (this.component.valueProperty) {\n return this.component.valueProperty;\n }\n // Force values datasource to use values without actually setting it on the component settings.\n if (this.component.dataSrc === 'values') {\n return 'value';\n }\n return '';\n }\n get inputInfo() {\n const info = super.elementInfo();\n info.type = 'select';\n info.changeEvent = 'change';\n return info;\n }\n get isSelectResource() {\n return this.component.dataSrc === 'resource';\n }\n get itemsFromUrl() {\n return this.isSelectResource || this.isSelectURL;\n }\n get isInfiniteScrollProvided() {\n return this.itemsFromUrl;\n }\n get shouldDisabled() {\n return super.shouldDisabled || this.parentDisabled;\n }\n get shouldInitialLoad() {\n if (this.component.widget === 'html5' &&\n this.isEntireObjectDisplay() &&\n this.component.searchField &&\n this.dataValue) {\n return false;\n }\n return super.shouldLoad;\n }\n get selectMetadata() {\n return super.selectData;\n }\n get selectData() {\n return this.selectMetadata || this.component.selectData;\n }\n isEntireObjectDisplay() {\n return this.component.dataSrc === 'resource' && this.valueProperty === 'data';\n }\n selectValueAndLabel(data) {\n const value = this.getOptionValue((this.isEntireObjectDisplay() && !this.itemValue(data)) ? data : this.itemValue(data));\n return {\n value,\n label: this.itemTemplate((this.isEntireObjectDisplay() && !lodash_1.default.isObject(data.data)) ? { data: data } : data, value)\n };\n }\n itemTemplate(data, value) {\n if (!lodash_1.default.isNumber(data) && lodash_1.default.isEmpty(data)) {\n return '';\n }\n // If they wish to show the value in read only mode, then just return the itemValue here.\n if (this.options.readOnly && this.component.readOnlyValue) {\n return this.itemValue(data);\n }\n // Perform a fast interpretation if we should not use the template.\n if (data && !this.component.template) {\n const itemLabel = data.label || data;\n const value = (typeof itemLabel === 'string') ? this.t(itemLabel, { _userInput: true }) : itemLabel;\n return this.sanitize(value, this.shouldSanitizeValue);\n }\n // Inside DataTable component won't have dataValue set\n const shouldUseSelectData = (this.component.multiple && lodash_1.default.isArray(this.dataValue)\n ? this.dataValue.find((val) => this.normalizeSingleValue(value) === val)\n : (this.dataValue === this.normalizeSingleValue(value))) || this.inDataTable;\n if (shouldUseSelectData) {\n const selectData = this.selectData;\n if (selectData) {\n const templateValue = this.component.reference && (value === null || value === void 0 ? void 0 : value._id) ? value._id.toString() : value;\n if (!this.templateData || !this.templateData[templateValue]) {\n this.getOptionTemplate(data, value);\n }\n if (this.component.multiple) {\n if (selectData[templateValue]) {\n data = selectData[templateValue];\n }\n }\n else {\n data = selectData;\n }\n }\n }\n if (typeof data === 'string' || typeof data === 'number') {\n return this.sanitize(this.t(data, { _userInput: true }), this.shouldSanitizeValue);\n }\n if (Array.isArray(data)) {\n return data.map((val) => {\n if (typeof val === 'string' || typeof val === 'number') {\n return this.sanitize(this.t(val, { _userInput: true }), this.shouldSanitizeValue);\n }\n return val;\n });\n }\n if (data.data) {\n // checking additional fields in the template for the selected Entire Object option\n const hasNestedFields = /item\\.data\\.\\w*/g.test(this.component.template);\n data.data = this.isEntireObjectDisplay() && lodash_1.default.isObject(data.data) && !hasNestedFields\n ? JSON.stringify(data.data)\n : data.data;\n }\n return super.itemTemplate(data, value);\n }\n /**\n * Adds an option to the select dropdown.\n * @param {*} value - The value of the new option.\n * @param {string} label - The label of the new option.\n * @param {object} [attrs] - Additional value attributes. Defaults to {}.\n * @param {string} [id] - An id. Defaults to a random string.\n */\n addOption(value, label, attrs = {}, id = (0, utils_1.getRandomComponentId)()) {\n if (lodash_1.default.isNil(label))\n return;\n const idPath = this.component.idPath\n ? this.component.idPath.split('.').reduceRight((obj, key) => ({ [key]: obj }), id)\n : {};\n const option = Object.assign({ value: this.getOptionValue(value), label }, idPath);\n const skipOption = this.component.uniqueOptions\n ? !!this.selectOptions.find((selectOption) => lodash_1.default.isEqual(selectOption.value, option.value))\n : false;\n if (skipOption) {\n return;\n }\n if (value) {\n this.selectOptions.push(option);\n }\n if (this.refs.selectContainer && (this.component.widget === 'html5')) {\n // Replace an empty Object value to an empty String.\n if (option.value && lodash_1.default.isObject(option.value) && lodash_1.default.isEmpty(option.value)) {\n option.value = '';\n }\n // Add element to option so we can reference it later.\n const div = document.createElement('div');\n div.innerHTML = this.sanitize(this.renderTemplate('selectOption', {\n selected: lodash_1.default.isEqual(this.getOptionValue(this.dataValue), option.value),\n option,\n attrs,\n id,\n useId: (this.valueProperty === '' || this.isEntireObjectDisplay()) && lodash_1.default.isObject(value) && id,\n }), this.shouldSanitizeValue).trim();\n option.element = div.firstChild;\n this.refs.selectContainer.appendChild(option.element);\n }\n }\n addValueOptions(items) {\n items = items || [];\n let added = false;\n let data = this.dataValue;\n // preset submission value with value property before request.\n if (this.options.pdf && !items.length && this.component.dataSrc === 'url' && this.valueProperty) {\n data = Array.isArray(data)\n ? data.map(item => lodash_1.default.set({}, this.valueProperty, item))\n : lodash_1.default.set({}, this.valueProperty, data);\n }\n if (!this.selectOptions.length) {\n // Add the currently selected choices if they don't already exist.\n const currentChoices = Array.isArray(data) && this.component.multiple ? data : [data];\n added = this.addCurrentChoices(currentChoices, items);\n if (!added && !this.component.multiple) {\n this.addPlaceholder();\n }\n }\n return added;\n }\n disableInfiniteScroll() {\n if (!this.downloadedResources) {\n return;\n }\n this.downloadedResources.serverCount = this.downloadedResources.length;\n this.serverCount = this.downloadedResources.length;\n }\n /* eslint-disable max-statements */\n setItems(items, fromSearch) {\n var _a, _b;\n this.selectItems = items;\n // If the items is a string, then parse as JSON.\n if (typeof items == 'string') {\n try {\n items = JSON.parse(items);\n }\n catch (err) {\n console.warn(err.message);\n items = [];\n }\n }\n // Allow js processing (needed for form builder)\n if (this.component.onSetItems) {\n const newItems = typeof this.component.onSetItems === 'function'\n ? this.component.onSetItems(this, items)\n : this.evaluate(this.component.onSetItems, { items: items }, 'items');\n if (newItems) {\n items = newItems;\n }\n }\n if (!this.choices && this.refs.selectContainer) {\n this.empty(this.refs.selectContainer);\n }\n // If they provided select values, then we need to get them instead.\n if (this.component.selectValues) {\n items = lodash_1.default.get(items, this.component.selectValues, items) || [];\n }\n let areItemsEqual;\n if (this.itemsFromUrl) {\n areItemsEqual = this.isSelectURL ? lodash_1.default.isEqual(items, this.downloadedResources) : false;\n const areItemsEnded = this.component.limit > items.length;\n const areItemsDownloaded = areItemsEqual\n && this.downloadedResources\n && this.downloadedResources.length === items.length;\n if (areItemsEnded) {\n this.disableInfiniteScroll();\n }\n else if (areItemsDownloaded) {\n this.selectOptions = [];\n }\n else {\n this.serverCount = items.serverCount;\n }\n }\n if (this.isScrollLoading && items) {\n if (!areItemsEqual) {\n this.downloadedResources = this.downloadedResources\n ? this.downloadedResources.concat(items)\n : items;\n }\n this.downloadedResources.serverCount = items.serverCount || this.downloadedResources.serverCount;\n }\n else {\n this.downloadedResources = items || [];\n this.selectOptions = [];\n // If there is new select option with same id as already selected, set the new one\n if (!lodash_1.default.isEmpty(this.dataValue) && this.component.idPath) {\n const selectedOptionId = lodash_1.default.get(this.dataValue, this.component.idPath, null);\n const newOptionWithSameId = !lodash_1.default.isNil(selectedOptionId) && items.find(item => {\n const itemId = lodash_1.default.get(item, this.component.idPath);\n return itemId === selectedOptionId;\n });\n if (newOptionWithSameId) {\n this.setValue(newOptionWithSameId);\n }\n }\n }\n // Add the value options.\n if (!fromSearch) {\n this.addValueOptions(items);\n }\n if (this.component.widget === 'html5' && !this.component.placeholder) {\n this.addOption(null, '');\n }\n // Iterate through each of the items.\n lodash_1.default.each(items, (item, index) => {\n // preventing references of the components inside the form to the parent form when building forms\n if (this.root && this.root.options.editForm && this.root.options.editForm._id && this.root.options.editForm._id === item._id)\n return;\n const itemValueAndLabel = this.selectValueAndLabel(item);\n this.addOption(itemValueAndLabel.value, itemValueAndLabel.label, {}, lodash_1.default.get(item, this.component.idPath, String(index)));\n });\n if (this.choices) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true);\n }\n else if (this.loading) {\n // Re-attach select input.\n // this.appendTo(this.refs.input[0], this.selectContainer);\n }\n // We are no longer loading.\n this.isScrollLoading = false;\n this.loading = false;\n const searching = fromSearch && ((_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.input) === null || _b === void 0 ? void 0 : _b.isFocussed);\n if (!searching) {\n // If a value is provided, then select it.\n if (!this.isEmpty() || this.isRemoveButtonPressed) {\n this.setValue(this.dataValue, {\n noUpdateEvent: true\n });\n }\n else if (this.shouldAddDefaultValue && !this.options.readOnly) {\n // If a default value is provided then select it.\n const defaultValue = this.defaultValue;\n if (!this.isEmpty(defaultValue)) {\n this.setValue(defaultValue);\n }\n }\n }\n // Say we are done loading the items.\n this.itemsLoadedResolve();\n }\n getSingleItemValueForHTMLMode(data) {\n var _a;\n const option = (_a = this.selectOptions) === null || _a === void 0 ? void 0 : _a.find(({ value }) => lodash_1.default.isEqual(value, data));\n if (option) {\n return option.label || data;\n }\n return data;\n }\n itemValueForHTMLMode(value) {\n if (!this.isHtmlRenderMode()) {\n return super.itemValueForHTMLMode(value);\n }\n if (Array.isArray(value)) {\n const values = value.map(item => Array.isArray(item)\n ? this.itemValueForHTMLMode(item)\n : this.getSingleItemValueForHTMLMode(item));\n return values.join(', ');\n }\n return this.getSingleItemValueForHTMLMode(value);\n }\n /* eslint-enable max-statements */\n get defaultValue() {\n let defaultValue = super.defaultValue;\n if (!defaultValue && (this.component.defaultValue === false || this.component.defaultValue === 0)) {\n defaultValue = this.component.defaultValue;\n }\n return defaultValue;\n }\n get loadingError() {\n return !this.component.refreshOn && !this.component.refreshOnBlur && this.networkError;\n }\n loadItems(url, search, headers, options, method, body) {\n options = options || {};\n // See if we should load items or not.\n if (!this.shouldLoad || (!this.itemsFromUrl && this.options.readOnly)) {\n this.isScrollLoading = false;\n this.loading = false;\n this.itemsLoadedResolve();\n return;\n }\n // See if they have not met the minimum search requirements.\n const minSearch = parseInt(this.component.minSearch, 10);\n if (this.component.searchField &&\n (minSearch > 0) &&\n (!search || (search.length < minSearch))) {\n // Set empty items.\n return this.setItems([]);\n }\n // Ensure we have a method and remove any body if method is get\n method = method || 'GET';\n if (method.toUpperCase() === 'GET') {\n body = null;\n }\n const limit = this.component.limit || 100;\n const skip = this.isScrollLoading ? this.selectOptions.length : 0;\n const query = this.component.disableLimit ? {} : {\n limit,\n skip,\n };\n // Allow for url interpolation.\n url = this.sanitize(this.interpolate(url, {\n formioBase: Formio_1.Formio.getBaseUrl(),\n search,\n limit,\n skip,\n page: Math.abs(Math.floor(skip / limit))\n }), this.shouldSanitizeValue);\n // Add search capability.\n if (this.component.searchField && search) {\n const searchValue = Array.isArray(search)\n ? search.join(',')\n : typeof search === 'object'\n ? JSON.stringify(search)\n : search;\n query[this.component.searchField] = this.component.searchField.endsWith('__regex')\n ? lodash_1.default.escapeRegExp(searchValue)\n : searchValue;\n }\n // If they wish to return only some fields.\n if (this.component.selectFields) {\n query.select = this.component.selectFields;\n }\n // Add sort capability\n if (this.component.sort) {\n query.sort = this.component.sort;\n }\n if (!lodash_1.default.isEmpty(query)) {\n // Add the query string.\n url += (!url.includes('?') ? '?' : '&') + Formio_1.Formio.serialize(query, (item) => this.interpolate(item));\n }\n // Add filter capability\n if (this.component.filter) {\n url += (!url.includes('?') ? '?' : '&') + this.interpolate(this.component.filter);\n }\n // Set ignoreCache if it is\n options.ignoreCache = this.component.ignoreCache;\n // Make the request.\n options.header = headers;\n this.loading = true;\n Formio_1.Formio.makeRequest(this.options.formio, 'select', url, method, body, options)\n .then((response) => {\n this.loading = false;\n this.setItems(response, !!search);\n })\n .catch((err) => {\n if (this.itemsFromUrl) {\n this.setItems([]);\n this.disableInfiniteScroll();\n }\n this.isScrollLoading = false;\n this.handleLoadingError(err);\n });\n }\n handleLoadingError(err) {\n this.loading = false;\n if (err.networkError) {\n this.networkError = true;\n }\n this.itemsLoadedResolve();\n this.emit('componentError', {\n component: this.component,\n message: err.toString(),\n });\n console.warn(this.t('loadResourcesError', { componentKey: this.key }));\n }\n /**\n * Get the request headers for this select dropdown.\n * @returns {*} - Returns the request headers for this select dropdown.\n */\n get requestHeaders() {\n // Create the headers object.\n const headers = new Formio_1.Formio.Headers();\n // Add custom headers to the url.\n if (this.component.data && this.component.data.headers) {\n try {\n lodash_1.default.each(this.component.data.headers, (header) => {\n if (header.key) {\n headers.set(header.key, this.interpolate(header.value));\n }\n });\n }\n catch (err) {\n console.warn(err.message);\n }\n }\n return headers;\n }\n getCustomItems() {\n const customItems = this.evaluate(this.component.data.custom, {\n values: []\n }, 'values');\n this.asyncValues = (0, utils_1.isPromise)(customItems);\n return customItems;\n }\n asyncCustomValues() {\n if (!lodash_1.default.isBoolean(this.asyncValues)) {\n this.getCustomItems();\n }\n return this.asyncValues;\n }\n updateCustomItems(forceUpdate) {\n if (this.asyncCustomValues()) {\n if (!forceUpdate && !this.active) {\n this.itemsLoadedResolve();\n return;\n }\n this.loading = true;\n this.getCustomItems()\n .then(items => {\n this.loading = false;\n this.setItems(items || []);\n })\n .catch(err => {\n this.handleLoadingError(err);\n });\n }\n else {\n this.setItems(this.getCustomItems() || []);\n }\n }\n isEmpty(value = this.dataValue) {\n return super.isEmpty(value) || value === undefined;\n }\n refresh(value, { instance }) {\n if (this.component.clearOnRefresh && (instance && !instance.pristine)) {\n this.setValue(this.emptyValue);\n }\n this.updateItems(null, true);\n }\n get additionalResourcesAvailable() {\n return lodash_1.default.isNil(this.serverCount) || (this.serverCount > this.downloadedResources.length);\n }\n get serverCount() {\n if (this.isFromSearch) {\n return this.searchServerCount;\n }\n return this.defaultServerCount;\n }\n set serverCount(value) {\n if (this.isFromSearch) {\n this.searchServerCount = value;\n }\n else {\n this.defaultServerCount = value;\n }\n }\n get downloadedResources() {\n if (this.isFromSearch) {\n return this.searchDownloadedResources;\n }\n return this.defaultDownloadedResources;\n }\n set downloadedResources(value) {\n if (this.isFromSearch) {\n this.searchDownloadedResources = value;\n }\n else {\n this.defaultDownloadedResources = value;\n }\n }\n addPlaceholder() {\n if (!this.component.placeholder) {\n return;\n }\n this.addOption('', this.component.placeholder, { placeholder: true });\n }\n /**\n * Activate this select control.\n */\n activate() {\n if (this.loading || !this.active) {\n this.setLoadingItem();\n }\n if (this.active) {\n return;\n }\n this.activated = true;\n this.triggerUpdate();\n }\n setLoadingItem(addToCurrentList = false) {\n if (this.choices) {\n if (addToCurrentList) {\n this.choices.setChoices([{\n value: `${this.id}-loading`,\n label: 'Loading...',\n disabled: true,\n }], 'value', 'label');\n }\n else {\n this.choices.setChoices([{\n value: '',\n label: `<i class=\"${this.iconClass('refresh')}\" style=\"font-size:1.3em;\"></i>`,\n disabled: true,\n }], 'value', 'label', true);\n }\n }\n else if (this.component.dataSrc === 'url' || this.component.dataSrc === 'resource') {\n this.addOption('', `${this.t('loading')}...`);\n }\n }\n get active() {\n return !this.component.lazyLoad || this.activated;\n }\n render() {\n const info = this.inputInfo;\n info.attr = info.attr || {};\n info.multiple = this.component.multiple;\n return super.render(this.wrapElement(this.renderTemplate('select', {\n input: info,\n selectOptions: '',\n index: null,\n })));\n }\n wrapElement(element) {\n return this.component.addResource && !this.options.readOnly\n ? (this.renderTemplate('resourceAdd', {\n element\n }))\n : element;\n }\n choicesOptions() {\n const useSearch = this.component.hasOwnProperty('searchEnabled') ? this.component.searchEnabled : true;\n const placeholderValue = this.t(this.component.placeholder, { _userInput: true });\n let customOptions = this.component.customOptions || {};\n if (typeof customOptions == 'string') {\n try {\n customOptions = JSON.parse(customOptions);\n }\n catch (err) {\n console.warn(err.message);\n customOptions = {};\n }\n }\n const commonFuseOptions = {\n maxPatternLength: 1000,\n distance: 1000,\n };\n return Object.assign({ removeItemButton: this.component.disabled ? false : lodash_1.default.get(this.component, 'removeItemButton', true), itemSelectText: '', classNames: {\n containerOuter: ['choices', 'form-group', 'formio-choices'],\n containerInner: this.transform('class', 'form-control ui fluid selection dropdown').split(' '),\n }, addItemText: false, allowHTML: true, placeholder: !!this.component.placeholder, placeholderValue: placeholderValue, noResultsText: this.t('noResultsFound'), noChoicesText: this.t('noChoices'), searchPlaceholderValue: this.t('typeToSearch'), shouldSort: false, position: (this.component.dropdown || 'auto'), searchEnabled: useSearch, searchChoices: !this.component.searchField, searchFields: lodash_1.default.get(this, 'component.searchFields', ['label']), shadowRoot: this.root ? this.root.shadowRoot : null, fuseOptions: this.component.useExactSearch\n ? Object.assign({ tokenize: true, matchAllTokens: true }, commonFuseOptions) : Object.assign({}, lodash_1.default.get(this, 'component.fuseOptions', {}), Object.assign({ include: 'score', threshold: lodash_1.default.get(this, 'component.selectThreshold', 0.3) }, commonFuseOptions)), valueComparer: lodash_1.default.isEqual, resetScrollPosition: false, duplicateItemsAllowed: false }, customOptions);\n }\n /* eslint-disable max-statements */\n attach(element) {\n var _a, _b, _c;\n const superAttach = super.attach(element);\n this.loadRefs(element, {\n selectContainer: 'single',\n addResource: 'single',\n autocompleteInput: 'single'\n });\n //enable autocomplete for select\n const autocompleteInput = this.refs.autocompleteInput;\n if (autocompleteInput) {\n this.addEventListener(autocompleteInput, 'change', (event) => {\n this.setValue(event.target.value);\n });\n }\n const input = this.refs.selectContainer;\n if (!input) {\n return;\n }\n this.addEventListener(input, this.inputInfo.changeEvent, () => this.updateValue(null, {\n modified: true\n }));\n this.attachRefreshOnBlur();\n if (this.component.widget === 'html5') {\n this.addFocusBlurEvents(input);\n this.triggerUpdate(null, true);\n if (this.visible) {\n this.setItems(this.selectItems || []);\n }\n this.focusableElement = input;\n if (this.component.dataSrc === 'custom') {\n this.addEventListener(input, 'focus', () => this.updateCustomItems());\n }\n this.addEventListener(input, 'keydown', (event) => {\n const { key } = event;\n if (['Backspace', 'Delete'].includes(key)) {\n this.setValue(this.emptyValue);\n }\n });\n return;\n }\n const tabIndex = input.tabIndex;\n this.addPlaceholder();\n if (this.i18next) {\n input.setAttribute('dir', this.i18next.dir());\n }\n if ((_c = (_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.containerOuter) === null || _b === void 0 ? void 0 : _b.element) === null || _c === void 0 ? void 0 : _c.parentNode) {\n this.choices.destroy();\n }\n const choicesOptions = this.choicesOptions();\n if (ChoicesWrapper_1.default) {\n this.choices = new ChoicesWrapper_1.default(input, choicesOptions);\n if (this.selectOptions && this.selectOptions.length) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true);\n }\n if (this.component.multiple) {\n this.focusableElement = this.choices.input.element;\n }\n else {\n this.focusableElement = this.choices.containerInner.element;\n this.choices.containerOuter.element.setAttribute('tabIndex', '-1');\n this.addEventListener(this.choices.containerOuter.element, 'focus', () => this.focusableElement.focus());\n }\n this.addFocusBlurEvents(this.choices.input.element);\n if (this.itemsFromUrl && !this.component.noRefreshOnScroll) {\n this.scrollList = this.choices.choiceList.element;\n this.addEventListener(this.scrollList, 'scroll', () => this.onScroll());\n }\n if (choicesOptions.removeItemButton) {\n this.addEventListener(input, 'removeItem', () => {\n this.isRemoveButtonPressed = true;\n });\n }\n }\n if (window && this.choices && this.shouldPositionDropdown) {\n this.addEventListener(window.document, 'scroll', () => {\n this.positionDropdown(true);\n }, false, true);\n }\n this.focusableElement.setAttribute('tabIndex', tabIndex);\n // If a search field is provided, then add an event listener to update items on search.\n if (this.component.searchField) {\n // Make sure to clear the search when no value is provided.\n if (this.choices && this.choices.input && this.choices.input.element) {\n this.addEventListener(this.choices.input.element, 'input', (event) => {\n this.isFromSearch = !!event.target.value;\n if (!event.target.value) {\n this.triggerUpdate();\n }\n else {\n this.serverCount = null;\n this.downloadedResources = [];\n }\n });\n }\n this.addEventListener(input, 'choice', () => {\n if (this.component.multiple && this.component.dataSrc === 'resource' && this.isFromSearch) {\n this.triggerUpdate();\n }\n this.isFromSearch = false;\n });\n // avoid spamming the resource/url endpoint when we have server side filtering enabled.\n const debounceTimeout = this.component.searchField && (this.isSelectResource || this.isSelectURL) ?\n (this.component.searchDebounce === 0 ? 0 : this.component.searchDebounce || this.defaultSchema.searchDebounce) * 1000\n : 0;\n const updateComponent = (evt) => {\n this.triggerUpdate(evt.detail.value);\n };\n this.addEventListener(input, 'search', lodash_1.default.debounce((e) => {\n updateComponent(e);\n this.positionDropdown();\n }, debounceTimeout));\n this.addEventListener(input, 'stopSearch', () => this.triggerUpdate());\n this.addEventListener(input, 'hideDropdown', () => {\n if (this.choices && this.choices.input && this.choices.input.element) {\n this.choices.input.element.value = '';\n }\n this.updateItems(null, true);\n });\n }\n this.addEventListener(input, 'showDropdown', () => {\n this.update();\n this.positionDropdown();\n });\n if (this.shouldPositionDropdown) {\n this.addEventListener(input, 'highlightChoice', () => {\n this.positionDropdown();\n });\n }\n // Add value options.\n this.addValueOptions();\n this.setChoicesValue(this.dataValue);\n if (this.isSelectResource && this.refs.addResource) {\n this.addEventListener(this.refs.addResource, 'click', (event) => {\n event.preventDefault();\n const formioForm = this.ce('div');\n const dialog = this.createModal(formioForm);\n const projectUrl = lodash_1.default.get(this.root, 'formio.projectUrl', Formio_1.Formio.getProjectUrl());\n const formUrl = `${projectUrl}/form/${this.component.data.resource}`;\n new Form_1.default(formioForm, formUrl, {}).ready\n .then((form) => {\n form.on('submit', (submission) => {\n // If valueProperty is set, replace the submission with the corresponding value\n let value = this.valueProperty ? lodash_1.default.get(submission, this.valueProperty) : submission;\n if (this.component.multiple) {\n value = [...this.dataValue, value];\n }\n this.setValue(value);\n this.triggerUpdate();\n dialog.close();\n });\n });\n });\n }\n // Force the disabled state with getters and setters.\n this.disabled = this.shouldDisabled;\n this.triggerUpdate();\n return superAttach;\n }\n setDropdownPosition() {\n var _a, _b, _c, _d;\n const dropdown = (_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.dropdown) === null || _b === void 0 ? void 0 : _b.element;\n const container = (_d = (_c = this.choices) === null || _c === void 0 ? void 0 : _c.containerOuter) === null || _d === void 0 ? void 0 : _d.element;\n if (!dropdown || !container) {\n return;\n }\n const containerPosition = container.getBoundingClientRect();\n const isFlipped = container.classList.contains('is-flipped');\n lodash_1.default.assign(dropdown.style, {\n top: `${isFlipped ? containerPosition.top - dropdown.offsetHeight : containerPosition.top + containerPosition.height}px`,\n left: `${containerPosition.left}px`,\n width: `${containerPosition.width}px`,\n position: 'fixed',\n bottom: 'unset',\n right: 'unset',\n });\n }\n hasDataGridAncestor(comp) {\n comp = comp || this;\n if (comp.inDataGrid || comp.type === 'datagrid') {\n return true;\n }\n else if (comp.parent) {\n return this.hasDataGridAncestor(comp.parent);\n }\n else {\n return false;\n }\n }\n positionDropdown(scroll) {\n var _a;\n if (!this.shouldPositionDropdown || !this.choices || (!((_a = this.choices.dropdown) === null || _a === void 0 ? void 0 : _a.isActive) && scroll)) {\n return;\n }\n this.setDropdownPosition();\n this.itemsLoaded.then(() => {\n this.setDropdownPosition();\n });\n }\n get isLoadingAvailable() {\n return !this.isScrollLoading && this.additionalResourcesAvailable;\n }\n onScroll() {\n if (this.isLoadingAvailable) {\n this.isScrollLoading = true;\n this.setLoadingItem(true);\n this.triggerUpdate(this.choices.input.element.value);\n }\n }\n attachRefreshOnBlur() {\n if (this.component.refreshOnBlur) {\n this.on('blur', (instance) => {\n this.checkRefreshOn([{ instance, value: instance.dataValue }], { fromBlur: true });\n });\n }\n }\n /* eslint-enable max-statements */\n update() {\n if (this.component.dataSrc === 'custom') {\n this.updateCustomItems();\n }\n // Activate the control.\n this.activate();\n }\n set disabled(disabled) {\n super.disabled = disabled;\n if (!this.choices) {\n return;\n }\n if (disabled) {\n this.setDisabled(this.choices.containerInner.element, true);\n this.focusableElement.removeAttribute('tabIndex');\n this.choices.disable();\n }\n else {\n this.setDisabled(this.choices.containerInner.element, false);\n this.focusableElement.setAttribute('tabIndex', this.component.tabindex || 0);\n this.choices.enable();\n }\n }\n get disabled() {\n return super.disabled;\n }\n set visible(value) {\n // If we go from hidden to visible, trigger a refresh.\n if (value && (!this._visible !== !value)) {\n this.triggerUpdate();\n }\n super.visible = value;\n }\n get visible() {\n return super.visible;\n }\n addCurrentChoices(values, items, keyValue) {\n if (!values) {\n return false;\n }\n const notFoundValuesToAdd = [];\n const added = values.reduce((defaultAdded, value) => {\n if (!value || lodash_1.default.isEmpty(value)) {\n return defaultAdded;\n }\n let found = false;\n // Make sure that `items` and `this.selectOptions` points\n // to the same reference. Because `this.selectOptions` is\n // internal property and all items are populated by\n // `this.addOption` method, we assume that items has\n // 'label' and 'value' properties. This assumption allows\n // us to read correct value from the item.\n const isSelectOptions = items === this.selectOptions;\n if (items && items.length) {\n lodash_1.default.each(items, (choice) => {\n if (choice._id && value._id && (choice._id === value._id)) {\n found = true;\n return false;\n }\n const itemValue = keyValue ? choice.value : this.itemValue(choice, isSelectOptions);\n found |= lodash_1.default.isEqual(itemValue, value);\n return found ? false : true;\n });\n }\n // Add the default option if no item is found.\n if (!found) {\n notFoundValuesToAdd.push(this.selectValueAndLabel(value));\n return true;\n }\n return found || defaultAdded;\n }, false);\n if (notFoundValuesToAdd.length) {\n if (this.choices) {\n this.choices.setChoices(notFoundValuesToAdd, 'value', 'label');\n }\n notFoundValuesToAdd.map(notFoundValue => {\n this.addOption(notFoundValue.value, notFoundValue.label);\n });\n }\n return added;\n }\n getValueAsString(data, options) {\n return (this.component.multiple && Array.isArray(data))\n ? data.map((v) => this.asString(v, options)).join(', ')\n : this.asString(data, options);\n }\n getValue() {\n // If the widget isn't active.\n if (this.viewOnly || this.loading\n || (!this.component.lazyLoad && !this.selectOptions.length)\n || !this.element) {\n return this.dataValue;\n }\n let value = this.emptyValue;\n if (this.choices) {\n value = this.choices.getValue(true);\n // Make sure we don't get the placeholder\n if (!this.component.multiple &&\n this.component.placeholder &&\n (value === this.t(this.component.placeholder, { _userInput: true }))) {\n value = this.emptyValue;\n }\n }\n else if (this.refs.selectContainer) {\n value = this.refs.selectContainer.value;\n if (this.valueProperty === '' || this.isEntireObjectDisplay()) {\n if (value === '') {\n return {};\n }\n const option = this.selectOptions[value] ||\n this.selectOptions.find(option => option.id === value);\n if (option && lodash_1.default.isObject(option.value)) {\n value = option.value;\n }\n }\n }\n else {\n value = this.dataValue;\n }\n // Choices will return undefined if nothing is selected. We really want '' to be empty.\n if (value === undefined || value === null) {\n value = '';\n }\n return value;\n }\n redraw() {\n const done = super.redraw();\n this.triggerUpdate();\n return done;\n }\n normalizeSingleValue(value) {\n if (lodash_1.default.isNil(value)) {\n return;\n }\n const valueIsObject = lodash_1.default.isObject(value);\n //check if value equals to default emptyValue\n if (valueIsObject && Object.keys(value).length === 0) {\n return value;\n }\n const dataType = this.component.dataType || 'auto';\n const normalize = {\n value,\n number() {\n const numberValue = Number(this.value);\n const isEquivalent = value.toString() === numberValue.toString();\n if (!Number.isNaN(numberValue) && Number.isFinite(numberValue) && value !== '' && isEquivalent) {\n this.value = numberValue;\n }\n return this;\n },\n boolean() {\n if (lodash_1.default.isString(this.value)\n && (this.value.toLowerCase() === 'true'\n || this.value.toLowerCase() === 'false')) {\n this.value = (this.value.toLowerCase() === 'true');\n }\n return this;\n },\n string() {\n this.value = String(this.value);\n return this;\n },\n object() {\n return this;\n },\n auto() {\n if (lodash_1.default.isObject(this.value)) {\n this.value = this.object().value;\n }\n else {\n this.value = this.string().number().boolean().value;\n }\n return this;\n }\n };\n try {\n return normalize[dataType]().value;\n }\n catch (err) {\n console.warn(this.t('failedToNormalize'), err);\n return value;\n }\n }\n /**\n * Normalize values coming into updateValue. For example, depending on the configuration, string value `\"true\"` will be normalized to boolean `true`.\n * @param {*} value - The value to normalize\n * @returns {*} - Returns the normalized value\n */\n normalizeValue(value) {\n if (this.component.multiple && Array.isArray(value)) {\n return value.map((singleValue) => this.normalizeSingleValue(singleValue));\n }\n return super.normalizeValue(this.normalizeSingleValue(value));\n }\n setMetadata(value, flags = {}) {\n var _a, _b;\n if (lodash_1.default.isNil(value)) {\n return;\n }\n const valueIsObject = lodash_1.default.isObject(value);\n //check if value equals to default emptyValue\n if (valueIsObject && Object.keys(value).length === 0) {\n return value;\n }\n // Check to see if we need to save off the template data into our metadata.\n const templateValue = this.component.reference && (value === null || value === void 0 ? void 0 : value._id) ? value._id.toString() : value;\n const shouldSaveData = (!valueIsObject || this.component.reference) && !this.inDataTable;\n if (!lodash_1.default.isNil(templateValue) && shouldSaveData && this.templateData && this.templateData[templateValue] && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submission)) {\n const submission = this.root.submission;\n if (!submission.metadata) {\n submission.metadata = {};\n }\n if (!submission.metadata.selectData) {\n submission.metadata.selectData = {};\n }\n let templateData = this.templateData[templateValue];\n if (this.component.multiple) {\n templateData = {};\n const dataValue = this.dataValue;\n if (dataValue && lodash_1.default.isArray(dataValue) && dataValue.length) {\n dataValue.forEach((dataValueItem) => {\n const dataValueItemValue = this.component.reference ? dataValueItem._id.toString() : dataValueItem;\n templateData[dataValueItemValue] = this.templateData[dataValueItemValue];\n });\n }\n templateData[value] = this.templateData[value];\n }\n lodash_1.default.set(submission.metadata.selectData, this.path, templateData);\n }\n if (flags.resetValue && ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submission) && !this.options.readOnly) {\n const submission = this.root.submission;\n if (!submission.metadata) {\n submission.metadata = {};\n }\n submission.metadata.selectData = {};\n }\n }\n updateValue(value, flags) {\n const changed = super.updateValue(value, flags);\n if (changed || !this.selectMetadata || flags.resetValue) {\n if (this.component.multiple && Array.isArray(this.dataValue)) {\n this.dataValue.forEach(singleValue => this.setMetadata(singleValue, flags));\n }\n else {\n this.setMetadata(this.dataValue, flags);\n }\n }\n return changed;\n }\n undoValueTyping(value) {\n let untypedValue = value;\n if (this.component.multiple && Array.isArray(value)) {\n untypedValue = value.map(v => {\n if (typeof v === 'boolean' || typeof v === 'number') {\n return v.toString();\n }\n return v;\n });\n }\n else {\n if (typeof value === 'boolean' || typeof value === 'number') {\n untypedValue = value.toString();\n }\n }\n return untypedValue;\n }\n setValue(value, flags = {}) {\n const previousValue = this.dataValue;\n const changed = this.updateValue(value, flags);\n if (this.component.widget === 'html5' && (lodash_1.default.isEqual(value, previousValue) || lodash_1.default.isEqual(previousValue, {}) && lodash_1.default.isEqual(flags, {})) && !flags.fromSubmission) {\n return false;\n }\n value = this.dataValue;\n const hasPreviousValue = !this.isEmpty(previousValue);\n const hasValue = !this.isEmpty(value);\n // Undo typing when searching to set the value.\n value = this.undoValueTyping(value);\n if (this.isHtmlRenderMode() && flags && flags.fromSubmission && changed) {\n this.itemsLoaded.then(() => {\n this.redraw();\n });\n return changed;\n }\n // Do not set the value if we are loading... that will happen after it is done.\n if (this.loading) {\n return changed;\n }\n // Determine if we need to perform an initial lazyLoad api call if searchField is provided.\n if (this.isInitApiCallNeeded(hasValue)) {\n this.loading = true;\n this.lazyLoadInit = true;\n const searchProperty = this.component.searchField || this.component.valueProperty;\n this.triggerUpdate(lodash_1.default.get(value.data || value, searchProperty, value), true);\n return changed;\n }\n // Add the value options.\n this.itemsLoaded.then(() => {\n this.addValueOptions();\n this.setChoicesValue(value, hasPreviousValue, flags);\n });\n return changed;\n }\n isInitApiCallNeeded(hasValue) {\n return this.component.lazyLoad &&\n !this.lazyLoadInit &&\n !this.active &&\n !this.selectOptions.length &&\n hasValue &&\n this.shouldInitialLoad &&\n this.visible && (this.component.searchField || this.component.valueProperty);\n }\n setChoicesValue(value, hasPreviousValue, flags = {}) {\n const hasValue = !this.isEmpty(value) || flags.fromSubmission;\n hasPreviousValue = (hasPreviousValue === undefined) ? true : hasPreviousValue;\n if (this.choices) {\n // Now set the value.\n if (hasValue) {\n this.choices.removeActiveItems();\n // Add the currently selected choices if they don't already exist.\n const currentChoices = Array.isArray(value) && this.component.multiple ? value : [value];\n if (!this.addCurrentChoices(currentChoices, this.selectOptions, true)) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true);\n }\n this.choices.setChoiceByValue(currentChoices);\n }\n else if (hasPreviousValue || flags.resetValue) {\n this.choices.removeActiveItems();\n }\n }\n else {\n if (hasValue) {\n const values = Array.isArray(value) ? value : [value];\n if (!lodash_1.default.isEqual(this.dataValue, this.defaultValue) && this.selectOptions.length < 2\n || (this.selectData && flags.fromSubmission)) {\n const { value, label } = this.selectValueAndLabel(this.dataValue);\n this.addOption(value, label);\n }\n lodash_1.default.each(this.selectOptions, (selectOption) => {\n lodash_1.default.each(values, (val) => {\n if (selectOption.value === '') {\n selectOption.value = {};\n }\n if (lodash_1.default.isEqual(val, selectOption.value) && selectOption.element) {\n selectOption.element.selected = true;\n selectOption.element.setAttribute('selected', 'selected');\n return false;\n }\n });\n });\n }\n else {\n lodash_1.default.each(this.selectOptions, (selectOption) => {\n if (selectOption.element) {\n selectOption.element.selected = false;\n selectOption.element.removeAttribute('selected');\n }\n });\n }\n }\n }\n validateValueAvailability(setting, value) {\n if (!(0, utils_1.boolValue)(setting) || !value) {\n return true;\n }\n const values = this.getOptionsValues();\n if (values) {\n if (lodash_1.default.isObject(value)) {\n const compareComplexValues = (optionValue) => {\n const normalizedOptionValue = this.normalizeSingleValue(optionValue);\n if (!lodash_1.default.isObject(normalizedOptionValue)) {\n return false;\n }\n try {\n return (JSON.stringify(normalizedOptionValue) === JSON.stringify(value));\n }\n catch (err) {\n console.warn.error(this.t('failedToCompareItems'), err);\n return false;\n }\n };\n return values.findIndex((optionValue) => compareComplexValues(optionValue)) !== -1;\n }\n return values.findIndex((optionValue) => this.normalizeSingleValue(optionValue) === value) !== -1;\n }\n return false;\n }\n /**\n * Performs required transformations on the initial value to use in selectOptions\n * @param {*} value - The value to transform.\n * @returns {*} - Returns the options value.\n */\n getOptionValue(value) {\n return lodash_1.default.isObject(value) && this.isEntireObjectDisplay()\n ? this.normalizeSingleValue(value)\n : lodash_1.default.isObject(value) && (this.valueProperty || this.component.key !== 'resource')\n ? value\n : lodash_1.default.isObject(value) && !this.valueProperty\n ? this.interpolate(this.component.template, { item: value }).replace(/<\\/?[^>]+(>|$)/g, '')\n : lodash_1.default.isNull(value)\n ? this.emptyValue\n : String(this.normalizeSingleValue(value));\n }\n /**\n * If component has static values (values, json) or custom values, returns an array of them\n * @returns {Array<*>|undefined} - Returns an array of the static or custom values.\n */\n getOptionsValues() {\n let rawItems = [];\n switch (this.component.dataSrc) {\n case 'values':\n rawItems = this.component.data.values;\n break;\n case 'json':\n rawItems = this.component.data.json;\n break;\n case 'custom':\n rawItems = this.getCustomItems();\n break;\n case 'url':\n rawItems = this.selectItems;\n break;\n }\n if (typeof rawItems === 'string') {\n try {\n rawItems = JSON.parse(rawItems);\n }\n catch (err) {\n console.warn(err.message);\n rawItems = [];\n }\n }\n if (!Array.isArray(rawItems)) {\n return;\n }\n return rawItems.map((item) => this.getOptionValue(this.itemValue(item)));\n }\n /**\n * Deletes the value of the component.\n */\n deleteValue() {\n this.setValue('', {\n noUpdateEvent: true\n });\n this.unset();\n }\n /**\n * Check if a component is eligible for multiple validation\n * @returns {boolean} - Returns FALSE for select components.\n */\n validateMultiple() {\n // Select component will contain one input when flagged as multiple.\n return false;\n }\n /**\n * Output this select dropdown as a string value.\n * @returns {*}\n */\n isBooleanOrNumber(value) {\n return typeof value === 'number' || typeof value === 'boolean';\n }\n getNormalizedValues() {\n if (!this.component || !this.component.data || !this.component.data.values) {\n return;\n }\n return this.component.data.values.map(value => ({ label: value.label, value: String(this.normalizeSingleValue(value.value)) }));\n }\n asString(value, options = {}) {\n var _a;\n value = value !== null && value !== void 0 ? value : this.getValue();\n if (options.modalPreview || this.inDataTable || options.email) {\n if (this.inDataTable) {\n value = this.undoValueTyping(value);\n }\n const templateValue = (this.isEntireObjectDisplay() && !lodash_1.default.isObject(value.data)) ? { data: value } : value;\n const template = this.itemTemplate(templateValue, value, options);\n return template;\n }\n //need to convert values to strings to be able to compare values with available options that are strings\n const convertToString = (data, valueProperty) => {\n if (valueProperty) {\n if (Array.isArray(data)) {\n data.forEach((item) => item[valueProperty] = item[valueProperty].toString());\n }\n else if (lodash_1.default.isObject(data)) {\n data[valueProperty] = data[valueProperty].toString();\n }\n return data;\n }\n if (this.isBooleanOrNumber(data)) {\n data = data.toString();\n }\n if (Array.isArray(data) && data.some(item => this.isBooleanOrNumber(item))) {\n data = data.map(item => this.isBooleanOrNumber(item) ? item.toString() : item);\n }\n return data;\n };\n value = convertToString(value);\n if (['values', 'custom'].includes(this.component.dataSrc) && !this.asyncCustomValues()) {\n const { items, valueProperty, } = this.component.dataSrc === 'values'\n ? {\n items: convertToString(this.getNormalizedValues(), 'value'),\n valueProperty: 'value',\n }\n : {\n items: convertToString(this.getCustomItems(), this.valueProperty),\n valueProperty: this.valueProperty,\n };\n const getFromValues = () => {\n const initialValue = lodash_1.default.find(items, [valueProperty, value]);\n const values = this.defaultSchema.data.values || [];\n return lodash_1.default.isEqual(initialValue, values[0]) ? '-' : initialValue;\n };\n value = (this.component.multiple && Array.isArray(value))\n ? lodash_1.default.filter(items, (item) => value.includes(item.value))\n : (valueProperty && items)\n ? (_a = getFromValues()) !== null && _a !== void 0 ? _a : { value, label: value }\n : value;\n }\n if (lodash_1.default.isString(value)) {\n return value;\n }\n const getTemplateValue = (v) => {\n const itemTemplate = this.itemTemplate(v);\n return options.csv && itemTemplate\n ? (0, utils_1.removeHTML)(itemTemplate)\n : itemTemplate;\n };\n if (Array.isArray(value)) {\n const items = [];\n value.forEach(item => items.push(getTemplateValue(item)));\n if (this.component.dataSrc === 'resource' && items.length > 0) {\n return items.join(', ');\n }\n else if (items.length > 0) {\n return items.join('<br />');\n }\n else {\n return '-';\n }\n }\n if (this.isEntireObjectDisplay() && lodash_1.default.isObject(value)) {\n return JSON.stringify(value);\n }\n return !lodash_1.default.isNil(value)\n ? getTemplateValue(value)\n : '-';\n }\n detach() {\n var _a, _b;\n this.off('blur');\n if (this.choices) {\n if ((_b = (_a = this.choices.containerOuter) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.parentNode) {\n this.choices.destroy();\n }\n this.choices = null;\n }\n super.detach();\n }\n focus() {\n super.focus.call(this);\n if (this.focusableElement) {\n this.focusableElement.focus();\n }\n }\n setErrorClasses(elements, dirty, hasError, hasMessages, element = this.element) {\n super.setErrorClasses(elements, dirty, hasError, hasMessages, element);\n if (this.choices) {\n super.setErrorClasses([this.choices.containerInner.element], dirty, hasError, hasMessages, element);\n }\n else {\n super.setErrorClasses([this.refs.selectContainer], dirty, hasError, hasMessages, element);\n }\n }\n}\nexports[\"default\"] = SelectComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/select/Select.js?");
5351
+ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst Formio_1 = __webpack_require__(/*! ../../Formio */ \"./lib/cjs/Formio.js\");\nconst ListComponent_1 = __importDefault(__webpack_require__(/*! ../_classes/list/ListComponent */ \"./lib/cjs/components/_classes/list/ListComponent.js\"));\nconst Form_1 = __importDefault(__webpack_require__(/*! ../../Form */ \"./lib/cjs/Form.js\"));\nconst utils_1 = __webpack_require__(/*! ../../utils */ \"./lib/cjs/utils/index.js\");\nconst ChoicesWrapper_1 = __importDefault(__webpack_require__(/*! ../../utils/ChoicesWrapper */ \"./lib/cjs/utils/ChoicesWrapper.js\"));\nclass SelectComponent extends ListComponent_1.default {\n static schema(...extend) {\n return ListComponent_1.default.schema({\n type: 'select',\n label: 'Select',\n key: 'select',\n idPath: 'id',\n data: {\n values: [{ label: '', value: '' }],\n json: '',\n url: '',\n resource: '',\n custom: ''\n },\n clearOnRefresh: false,\n limit: 100,\n valueProperty: '',\n lazyLoad: true,\n filter: '',\n searchEnabled: true,\n searchDebounce: 0.3,\n searchField: '',\n minSearch: 0,\n readOnlyValue: false,\n selectFields: '',\n selectThreshold: 0.3,\n uniqueOptions: false,\n tableView: true,\n fuseOptions: {\n include: 'score',\n threshold: 0.3,\n },\n indexeddb: {\n filter: {}\n },\n customOptions: {},\n useExactSearch: false,\n }, ...extend);\n }\n static get builderInfo() {\n return {\n title: 'Select',\n group: 'basic',\n icon: 'th-list',\n weight: 70,\n documentation: '/userguide/form-building/form-components#select',\n schema: SelectComponent.schema()\n };\n }\n static get serverConditionSettings() {\n return SelectComponent.conditionOperatorsSettings;\n }\n static get conditionOperatorsSettings() {\n const numberType = () => ({ type: 'number' });\n return Object.assign(Object.assign({}, super.conditionOperatorsSettings), { valueComponent(classComp) {\n const valueComp = Object.assign(Object.assign({}, classComp), { type: 'select' });\n if ((0, utils_1.isSelectResourceWithObjectValue)(classComp)) {\n valueComp.reference = false;\n valueComp.onSetItems = `\n var templateKeys = utils.getItemTemplateKeys(component.template) || [];\n items = _.map(items || [], i => {\n var item = {};\n _.each(templateKeys, k => _.set(item, k, _.get(i, k)));\n return item;\n })\n `;\n }\n return valueComp;\n }, dataTypeOperators: {\n number: ['lessThan', 'greaterThan', 'lessThanOrEqual', 'greaterThanOrEqual'],\n }, dataTypeValueComponents: {\n number: {\n lessThan: numberType,\n greaterThan: numberType,\n lessThanOrEqual: numberType,\n greaterThanOrEqual: numberType,\n },\n } });\n }\n static savedValueTypes(schema) {\n const { boolean, string, number, object, array } = utils_1.componentValueTypes;\n const { dataType, reference } = schema;\n const types = (0, utils_1.getComponentSavedTypes)(schema);\n if (types) {\n return types;\n }\n if (reference) {\n return [object];\n }\n if (dataType === 'object') {\n return [object, array];\n }\n if (utils_1.componentValueTypes[dataType]) {\n return [utils_1.componentValueTypes[dataType]];\n }\n return [boolean, string, number, object, array];\n }\n init() {\n super.init();\n this.templateData = {};\n // Trigger an update.\n let updateArgs = [];\n const triggerUpdate = lodash_1.default.debounce((...args) => {\n updateArgs = [];\n return this.updateItems.apply(this, args);\n }, 100);\n this.triggerUpdate = (...args) => {\n // Make sure we always resolve the previous promise before reassign it\n if (typeof this.itemsLoadedResolve === 'function') {\n this.itemsLoadedResolve();\n }\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n if (args.length) {\n updateArgs = args;\n }\n return triggerUpdate(...updateArgs);\n };\n // Keep track of the select options.\n this.selectOptions = [];\n if (this.itemsFromUrl) {\n this.isFromSearch = false;\n this.searchServerCount = null;\n this.defaultServerCount = null;\n this.isScrollLoading = false;\n this.searchDownloadedResources = [];\n this.defaultDownloadedResources = [];\n }\n // If this component has been activated.//\n this.activated = false;\n this.itemsLoaded = new Promise((resolve) => {\n this.itemsLoadedResolve = resolve;\n });\n this.shouldPositionDropdown = this.hasDataGridAncestor();\n if (this.isHtmlRenderMode()) {\n this.activate();\n }\n // Get the template keys for this select component.\n this.getTemplateKeys();\n }\n get defaultSchema() {\n return SelectComponent.schema();\n }\n get emptyValue() {\n if (this.component.multiple) {\n return [];\n }\n // if select has JSON data source type, we are defining if empty value would be an object or a string by checking JSON's first item\n if (this.component.dataSrc === 'json' && this.component.data.json) {\n const firstItem = this.component.data.json[0];\n let firstValue;\n if (this.valueProperty) {\n firstValue = lodash_1.default.get(firstItem, this.valueProperty);\n }\n else {\n firstValue = firstItem;\n }\n if (firstValue && typeof firstValue === 'string') {\n return '';\n }\n else {\n return {};\n }\n }\n if (this.valueProperty) {\n return '';\n }\n return {};\n }\n get valueProperty() {\n if (this.component.valueProperty) {\n return this.component.valueProperty;\n }\n // Force values datasource to use values without actually setting it on the component settings.\n if (this.component.dataSrc === 'values') {\n return 'value';\n }\n return '';\n }\n get inputInfo() {\n const info = super.elementInfo();\n info.type = 'select';\n info.changeEvent = 'change';\n return info;\n }\n get isSelectResource() {\n return this.component.dataSrc === 'resource';\n }\n get itemsFromUrl() {\n return this.isSelectResource || this.isSelectURL;\n }\n get isInfiniteScrollProvided() {\n return this.itemsFromUrl;\n }\n get shouldDisabled() {\n return super.shouldDisabled || this.parentDisabled;\n }\n get shouldInitialLoad() {\n if (this.component.widget === 'html5' &&\n this.isEntireObjectDisplay() &&\n this.component.searchField &&\n this.dataValue) {\n return false;\n }\n return super.shouldLoad;\n }\n get selectMetadata() {\n return super.selectData;\n }\n get selectData() {\n return this.selectMetadata || this.component.selectData;\n }\n isEntireObjectDisplay() {\n return this.component.dataSrc === 'resource' && this.valueProperty === 'data';\n }\n selectValueAndLabel(data) {\n const value = this.getOptionValue((this.isEntireObjectDisplay() && !this.itemValue(data)) ? data : this.itemValue(data));\n return {\n value,\n label: this.itemTemplate((this.isEntireObjectDisplay() && !lodash_1.default.isObject(data.data)) ? { data: data } : data, value)\n };\n }\n itemTemplate(data, value) {\n if (!lodash_1.default.isNumber(data) && lodash_1.default.isEmpty(data)) {\n return '';\n }\n // If they wish to show the value in read only mode, then just return the itemValue here.\n if (this.options.readOnly && this.component.readOnlyValue) {\n return this.itemValue(data);\n }\n // Perform a fast interpretation if we should not use the template.\n if (data && !this.component.template) {\n const itemLabel = data.label || data;\n const value = (typeof itemLabel === 'string') ? this.t(itemLabel, { _userInput: true }) : itemLabel;\n return this.sanitize(value, this.shouldSanitizeValue);\n }\n // Inside DataTable component won't have dataValue set\n const shouldUseSelectData = (this.component.multiple && lodash_1.default.isArray(this.dataValue)\n ? this.dataValue.find((val) => this.normalizeSingleValue(value) === val)\n : (this.dataValue === this.normalizeSingleValue(value))) || this.inDataTable;\n if (shouldUseSelectData) {\n const selectData = this.selectData;\n if (selectData) {\n const templateValue = this.component.reference && (value === null || value === void 0 ? void 0 : value._id) ? value._id.toString() : value;\n if (!this.templateData || !this.templateData[templateValue]) {\n this.getOptionTemplate(data, value);\n }\n if (this.component.multiple) {\n if (selectData[templateValue]) {\n data = selectData[templateValue];\n }\n }\n else {\n data = selectData;\n }\n }\n }\n if (typeof data === 'string' || typeof data === 'number') {\n return this.sanitize(this.t(data, { _userInput: true }), this.shouldSanitizeValue);\n }\n if (Array.isArray(data)) {\n return data.map((val) => {\n if (typeof val === 'string' || typeof val === 'number') {\n return this.sanitize(this.t(val, { _userInput: true }), this.shouldSanitizeValue);\n }\n return val;\n });\n }\n if (data.data) {\n // checking additional fields in the template for the selected Entire Object option\n const hasNestedFields = /item\\.data\\.\\w*/g.test(this.component.template);\n data.data = this.isEntireObjectDisplay() && lodash_1.default.isObject(data.data) && !hasNestedFields\n ? JSON.stringify(data.data)\n : data.data;\n }\n return super.itemTemplate(data, value);\n }\n /**\n * Adds an option to the select dropdown.\n * @param {*} value - The value of the new option.\n * @param {string} label - The label of the new option.\n * @param {object} [attrs] - Additional value attributes. Defaults to {}.\n * @param {string} [id] - An id. Defaults to a random string.\n */\n addOption(value, label, attrs = {}, id = (0, utils_1.getRandomComponentId)()) {\n if (lodash_1.default.isNil(label))\n return;\n const idPath = this.component.idPath\n ? this.component.idPath.split('.').reduceRight((obj, key) => ({ [key]: obj }), id)\n : {};\n const option = Object.assign({ value: this.getOptionValue(value), label }, idPath);\n const skipOption = this.component.uniqueOptions\n ? !!this.selectOptions.find((selectOption) => lodash_1.default.isEqual(selectOption.value, option.value))\n : false;\n if (skipOption) {\n return;\n }\n if (value) {\n this.selectOptions.push(option);\n }\n if (this.refs.selectContainer && (this.component.widget === 'html5')) {\n // Replace an empty Object value to an empty String.\n if (option.value && lodash_1.default.isObject(option.value) && lodash_1.default.isEmpty(option.value)) {\n option.value = '';\n }\n // Add element to option so we can reference it later.\n const div = document.createElement('div');\n div.innerHTML = this.sanitize(this.renderTemplate('selectOption', {\n selected: lodash_1.default.isEqual(this.getOptionValue(this.dataValue), option.value),\n option,\n attrs,\n id,\n useId: (this.valueProperty === '' || this.isEntireObjectDisplay()) && lodash_1.default.isObject(value) && id,\n }), this.shouldSanitizeValue).trim();\n option.element = div.firstChild;\n this.refs.selectContainer.appendChild(option.element);\n }\n }\n addValueOptions(items) {\n items = items || [];\n let added = false;\n let data = this.dataValue;\n // preset submission value with value property before request.\n if (this.options.pdf && !items.length && this.component.dataSrc === 'url' && this.valueProperty) {\n data = Array.isArray(data)\n ? data.map(item => lodash_1.default.set({}, this.valueProperty, item))\n : lodash_1.default.set({}, this.valueProperty, data);\n }\n if (!this.selectOptions.length) {\n // Add the currently selected choices if they don't already exist.\n const currentChoices = Array.isArray(data) && this.component.multiple ? data : [data];\n added = this.addCurrentChoices(currentChoices, items);\n if (!added && !this.component.multiple) {\n this.addPlaceholder();\n }\n }\n return added;\n }\n disableInfiniteScroll() {\n if (!this.downloadedResources) {\n return;\n }\n this.downloadedResources.serverCount = this.downloadedResources.length;\n this.serverCount = this.downloadedResources.length;\n }\n shouldResetChoicesItems(items) {\n if (this.choices._store.choices.length !== items.length) {\n return true;\n }\n for (let item of items) {\n const choicesItem = this.choices._store.choices.find((i) => i.label === item.label);\n if (!choicesItem) {\n return true;\n }\n }\n return false;\n }\n /* eslint-disable max-statements */\n setItems(items, fromSearch) {\n var _a, _b;\n this.selectItems = items;\n // If the items is a string, then parse as JSON.\n if (typeof items == 'string') {\n try {\n items = JSON.parse(items);\n }\n catch (err) {\n console.warn(err.message);\n items = [];\n }\n }\n // Allow js processing (needed for form builder)\n if (this.component.onSetItems) {\n const newItems = typeof this.component.onSetItems === 'function'\n ? this.component.onSetItems(this, items)\n : this.evaluate(this.component.onSetItems, { items: items }, 'items');\n if (newItems) {\n items = newItems;\n }\n }\n if (!this.choices && this.refs.selectContainer) {\n this.empty(this.refs.selectContainer);\n }\n // If they provided select values, then we need to get them instead.\n if (this.component.selectValues) {\n items = lodash_1.default.get(items, this.component.selectValues, items) || [];\n }\n let areItemsEqual;\n if (this.itemsFromUrl) {\n areItemsEqual = this.isSelectURL ? lodash_1.default.isEqual(items, this.downloadedResources) : false;\n const areItemsEnded = this.component.limit > items.length;\n const areItemsDownloaded = areItemsEqual\n && this.downloadedResources\n && this.downloadedResources.length === items.length;\n if (areItemsEnded) {\n this.disableInfiniteScroll();\n }\n else if (areItemsDownloaded) {\n this.selectOptions = [];\n }\n else {\n this.serverCount = items.serverCount;\n }\n }\n if (this.isScrollLoading && items) {\n if (!areItemsEqual) {\n this.downloadedResources = this.downloadedResources\n ? this.downloadedResources.concat(items)\n : items;\n }\n this.downloadedResources.serverCount = items.serverCount || this.downloadedResources.serverCount;\n }\n else {\n this.downloadedResources = items || [];\n this.selectOptions = [];\n // If there is new select option with same id as already selected, set the new one\n if (!lodash_1.default.isEmpty(this.dataValue) && this.component.idPath) {\n const selectedOptionId = lodash_1.default.get(this.dataValue, this.component.idPath, null);\n const newOptionWithSameId = !lodash_1.default.isNil(selectedOptionId) && items.find(item => {\n const itemId = lodash_1.default.get(item, this.component.idPath);\n return itemId === selectedOptionId;\n });\n if (newOptionWithSameId) {\n this.setValue(newOptionWithSameId);\n }\n }\n }\n // Add the value options.\n if (!fromSearch) {\n this.addValueOptions(items);\n }\n if (this.component.widget === 'html5' && !this.component.placeholder) {\n this.addOption(null, '');\n }\n // Iterate through each of the items.\n lodash_1.default.each(items, (item, index) => {\n // preventing references of the components inside the form to the parent form when building forms\n if (this.root && this.root.options.editForm && this.root.options.editForm._id && this.root.options.editForm._id === item._id)\n return;\n const itemValueAndLabel = this.selectValueAndLabel(item);\n this.addOption(itemValueAndLabel.value, itemValueAndLabel.label, {}, lodash_1.default.get(item, this.component.idPath, String(index)));\n });\n if (this.choices) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true, true, !fromSearch && this.shouldResetChoicesItems(this.selectOptions));\n }\n else if (this.loading) {\n // Re-attach select input.\n // this.appendTo(this.refs.input[0], this.selectContainer);\n }\n // We are no longer loading.\n this.isScrollLoading = false;\n this.loading = false;\n const searching = fromSearch && ((_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.input) === null || _b === void 0 ? void 0 : _b.isFocussed);\n if (!searching) {\n // If a value is provided, then select it.\n if (!this.isEmpty() || this.isRemoveButtonPressed) {\n this.setValue(this.dataValue, {\n noUpdateEvent: true\n });\n }\n else if (this.shouldAddDefaultValue && !this.options.readOnly) {\n // If a default value is provided then select it.\n const defaultValue = this.defaultValue;\n if (!this.isEmpty(defaultValue)) {\n this.setValue(defaultValue);\n }\n }\n }\n // Say we are done loading the items.\n this.itemsLoadedResolve();\n }\n getSingleItemValueForHTMLMode(data) {\n var _a;\n const option = (_a = this.selectOptions) === null || _a === void 0 ? void 0 : _a.find(({ value }) => lodash_1.default.isEqual(value, data));\n if (option) {\n return option.label || data;\n }\n return data;\n }\n itemValueForHTMLMode(value) {\n if (!this.isHtmlRenderMode()) {\n return super.itemValueForHTMLMode(value);\n }\n if (Array.isArray(value)) {\n const values = value.map(item => Array.isArray(item)\n ? this.itemValueForHTMLMode(item)\n : this.getSingleItemValueForHTMLMode(item));\n return values.join(', ');\n }\n return this.getSingleItemValueForHTMLMode(value);\n }\n /* eslint-enable max-statements */\n get defaultValue() {\n let defaultValue = super.defaultValue;\n if (!defaultValue && (this.component.defaultValue === false || this.component.defaultValue === 0)) {\n defaultValue = this.component.defaultValue;\n }\n return defaultValue;\n }\n get loadingError() {\n return !this.component.refreshOn && !this.component.refreshOnBlur && this.networkError;\n }\n loadItems(url, search, headers, options, method, body) {\n options = options || {};\n // See if we should load items or not.\n if (!this.shouldLoad || (!this.itemsFromUrl && this.options.readOnly)) {\n this.isScrollLoading = false;\n this.loading = false;\n this.itemsLoadedResolve();\n return;\n }\n // See if they have not met the minimum search requirements.\n const minSearch = parseInt(this.component.minSearch, 10);\n if (this.component.searchField &&\n (minSearch > 0) &&\n (!search || (search.length < minSearch))) {\n // Set empty items.\n return this.setItems([]);\n }\n // Ensure we have a method and remove any body if method is get\n method = method || 'GET';\n if (method.toUpperCase() === 'GET') {\n body = null;\n }\n const limit = this.component.limit || 100;\n const skip = this.isScrollLoading ? this.selectOptions.length : 0;\n const query = this.component.disableLimit ? {} : {\n limit,\n skip,\n };\n // Allow for url interpolation.\n url = this.sanitize(this.interpolate(url, {\n formioBase: Formio_1.Formio.getBaseUrl(),\n search,\n limit,\n skip,\n page: Math.abs(Math.floor(skip / limit))\n }), this.shouldSanitizeValue);\n // Add search capability.\n if (this.component.searchField && search) {\n const searchValue = Array.isArray(search)\n ? search.join(',')\n : typeof search === 'object'\n ? JSON.stringify(search)\n : search;\n query[this.component.searchField] = this.component.searchField.endsWith('__regex')\n ? lodash_1.default.escapeRegExp(searchValue)\n : searchValue;\n }\n // If they wish to return only some fields.\n if (this.component.selectFields) {\n query.select = this.component.selectFields;\n }\n // Add sort capability\n if (this.component.sort) {\n query.sort = this.component.sort;\n }\n if (!lodash_1.default.isEmpty(query)) {\n // Add the query string.\n url += (!url.includes('?') ? '?' : '&') + Formio_1.Formio.serialize(query, (item) => this.interpolate(item));\n }\n // Add filter capability\n if (this.component.filter) {\n url += (!url.includes('?') ? '?' : '&') + this.interpolate(this.component.filter);\n }\n // Set ignoreCache if it is\n options.ignoreCache = this.component.ignoreCache;\n // Make the request.\n options.header = headers;\n this.loading = true;\n Formio_1.Formio.makeRequest(this.options.formio, 'select', url, method, body, options)\n .then((response) => {\n this.loading = false;\n this.setItems(response, !!search);\n })\n .catch((err) => {\n if (this.itemsFromUrl) {\n this.setItems([]);\n this.disableInfiniteScroll();\n }\n this.isScrollLoading = false;\n this.handleLoadingError(err);\n });\n }\n handleLoadingError(err) {\n this.loading = false;\n if (err.networkError) {\n this.networkError = true;\n }\n this.itemsLoadedResolve();\n this.emit('componentError', {\n component: this.component,\n message: err.toString(),\n });\n console.warn(this.t('loadResourcesError', { componentKey: this.key }));\n }\n /**\n * Get the request headers for this select dropdown.\n * @returns {*} - Returns the request headers for this select dropdown.\n */\n get requestHeaders() {\n // Create the headers object.\n const headers = new Formio_1.Formio.Headers();\n // Add custom headers to the url.\n if (this.component.data && this.component.data.headers) {\n try {\n lodash_1.default.each(this.component.data.headers, (header) => {\n if (header.key) {\n headers.set(header.key, this.interpolate(header.value));\n }\n });\n }\n catch (err) {\n console.warn(err.message);\n }\n }\n return headers;\n }\n getCustomItems() {\n const customItems = this.evaluate(this.component.data.custom, {\n values: []\n }, 'values');\n this.asyncValues = (0, utils_1.isPromise)(customItems);\n return customItems;\n }\n asyncCustomValues() {\n if (!lodash_1.default.isBoolean(this.asyncValues)) {\n this.getCustomItems();\n }\n return this.asyncValues;\n }\n updateCustomItems(forceUpdate) {\n if (this.asyncCustomValues()) {\n if (!forceUpdate && !this.active) {\n this.itemsLoadedResolve();\n return;\n }\n this.loading = true;\n this.getCustomItems()\n .then(items => {\n this.loading = false;\n this.setItems(items || []);\n })\n .catch(err => {\n this.handleLoadingError(err);\n });\n }\n else {\n this.setItems(this.getCustomItems() || []);\n }\n }\n isEmpty(value = this.dataValue) {\n return super.isEmpty(value) || value === undefined;\n }\n refresh(value, { instance }) {\n if (this.component.clearOnRefresh && (instance && !instance.pristine)) {\n this.setValue(this.emptyValue);\n }\n this.updateItems(null, true);\n }\n get additionalResourcesAvailable() {\n return lodash_1.default.isNil(this.serverCount) || (this.serverCount > this.downloadedResources.length);\n }\n get serverCount() {\n if (this.isFromSearch) {\n return this.searchServerCount;\n }\n return this.defaultServerCount;\n }\n set serverCount(value) {\n if (this.isFromSearch) {\n this.searchServerCount = value;\n }\n else {\n this.defaultServerCount = value;\n }\n }\n get downloadedResources() {\n if (this.isFromSearch) {\n return this.searchDownloadedResources;\n }\n return this.defaultDownloadedResources;\n }\n set downloadedResources(value) {\n if (this.isFromSearch) {\n this.searchDownloadedResources = value;\n }\n else {\n this.defaultDownloadedResources = value;\n }\n }\n addPlaceholder() {\n if (!this.component.placeholder) {\n return;\n }\n this.addOption('', this.component.placeholder, { placeholder: true });\n }\n /**\n * Activate this select control.\n */\n activate() {\n if (this.loading || !this.active) {\n this.setLoadingItem();\n }\n if (this.active) {\n return;\n }\n this.activated = true;\n this.triggerUpdate();\n }\n setLoadingItem(addToCurrentList = false) {\n if (this.choices) {\n if (addToCurrentList) {\n this.choices.setChoices([{\n value: `${this.id}-loading`,\n label: 'Loading...',\n disabled: true,\n }], 'value', 'label');\n }\n else {\n this.choices.setChoices([{\n value: '',\n label: `<i class=\"${this.iconClass('refresh')}\" style=\"font-size:1.3em;\"></i>`,\n disabled: true,\n }], 'value', 'label', true);\n }\n }\n else if (this.component.dataSrc === 'url' || this.component.dataSrc === 'resource') {\n this.addOption('', `${this.t('loading')}...`);\n }\n }\n get active() {\n return !this.component.lazyLoad || this.activated;\n }\n render() {\n const info = this.inputInfo;\n info.attr = info.attr || {};\n info.multiple = this.component.multiple;\n return super.render(this.wrapElement(this.renderTemplate('select', {\n input: info,\n selectOptions: '',\n index: null,\n })));\n }\n wrapElement(element) {\n return this.component.addResource && !this.options.readOnly\n ? (this.renderTemplate('resourceAdd', {\n element\n }))\n : element;\n }\n choicesOptions() {\n const useSearch = this.component.hasOwnProperty('searchEnabled') ? this.component.searchEnabled : true;\n const placeholderValue = this.t(this.component.placeholder, { _userInput: true });\n let customOptions = this.component.customOptions || {};\n if (typeof customOptions == 'string') {\n try {\n customOptions = JSON.parse(customOptions);\n }\n catch (err) {\n console.warn(err.message);\n customOptions = {};\n }\n }\n const commonFuseOptions = {\n maxPatternLength: 1000,\n distance: 1000,\n };\n return Object.assign({ removeItemButton: this.component.disabled ? false : lodash_1.default.get(this.component, 'removeItemButton', true), itemSelectText: '', classNames: {\n containerOuter: ['choices', 'form-group', 'formio-choices'],\n containerInner: this.transform('class', 'form-control ui fluid selection dropdown').split(' '),\n }, addItemText: false, allowHTML: true, placeholder: !!this.component.placeholder, placeholderValue: placeholderValue, noResultsText: this.t('noResultsFound'), noChoicesText: this.t('noChoices'), searchPlaceholderValue: this.t('typeToSearch'), shouldSort: false, position: (this.component.dropdown || 'auto'), searchEnabled: useSearch, searchChoices: !this.component.searchField, searchFields: lodash_1.default.get(this, 'component.searchFields', ['label']), shadowRoot: this.root ? this.root.shadowRoot : null, fuseOptions: this.component.useExactSearch\n ? Object.assign({ tokenize: true, matchAllTokens: true }, commonFuseOptions) : Object.assign({}, lodash_1.default.get(this, 'component.fuseOptions', {}), Object.assign({ include: 'score', threshold: lodash_1.default.get(this, 'component.selectThreshold', 0.3) }, commonFuseOptions)), valueComparer: lodash_1.default.isEqual, resetScrollPosition: false, duplicateItemsAllowed: false }, customOptions);\n }\n /* eslint-disable max-statements */\n attach(element) {\n var _a, _b, _c;\n const superAttach = super.attach(element);\n this.loadRefs(element, {\n selectContainer: 'single',\n addResource: 'single',\n autocompleteInput: 'single'\n });\n //enable autocomplete for select\n const autocompleteInput = this.refs.autocompleteInput;\n if (autocompleteInput) {\n this.addEventListener(autocompleteInput, 'change', (event) => {\n this.setValue(event.target.value);\n });\n }\n const input = this.refs.selectContainer;\n if (!input) {\n return;\n }\n this.addEventListener(input, this.inputInfo.changeEvent, () => this.updateValue(null, {\n modified: true\n }));\n this.attachRefreshOnBlur();\n if (this.component.widget === 'html5') {\n this.addFocusBlurEvents(input);\n this.triggerUpdate(null, true);\n if (this.visible) {\n this.setItems(this.selectItems || []);\n }\n this.focusableElement = input;\n if (this.component.dataSrc === 'custom') {\n this.addEventListener(input, 'focus', () => this.updateCustomItems());\n }\n this.addEventListener(input, 'keydown', (event) => {\n const { key } = event;\n if (['Backspace', 'Delete'].includes(key)) {\n this.setValue(this.emptyValue);\n }\n });\n return;\n }\n const tabIndex = input.tabIndex;\n this.addPlaceholder();\n if (this.i18next) {\n input.setAttribute('dir', this.i18next.dir());\n }\n if ((_c = (_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.containerOuter) === null || _b === void 0 ? void 0 : _b.element) === null || _c === void 0 ? void 0 : _c.parentNode) {\n this.choices.destroy();\n }\n const choicesOptions = this.choicesOptions();\n if (ChoicesWrapper_1.default) {\n this.choices = new ChoicesWrapper_1.default(input, choicesOptions);\n if (this.selectOptions && this.selectOptions.length) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true);\n }\n if (this.component.multiple) {\n this.focusableElement = this.choices.input.element;\n }\n else {\n this.focusableElement = this.choices.containerInner.element;\n this.choices.containerOuter.element.setAttribute('tabIndex', '-1');\n this.addEventListener(this.choices.containerOuter.element, 'focus', () => this.focusableElement.focus());\n }\n this.addFocusBlurEvents(this.choices.input.element);\n if (this.itemsFromUrl && !this.component.noRefreshOnScroll) {\n this.scrollList = this.choices.choiceList.element;\n this.addEventListener(this.scrollList, 'scroll', () => this.onScroll());\n }\n if (choicesOptions.removeItemButton) {\n this.addEventListener(input, 'removeItem', () => {\n this.isRemoveButtonPressed = true;\n });\n }\n }\n if (window && this.choices && this.shouldPositionDropdown) {\n this.addEventListener(window.document, 'scroll', () => {\n this.positionDropdown(true);\n }, false, true);\n }\n this.focusableElement.setAttribute('tabIndex', tabIndex);\n // If a search field is provided, then add an event listener to update items on search.\n if (this.component.searchField) {\n // Make sure to clear the search when no value is provided.\n if (this.choices && this.choices.input && this.choices.input.element) {\n this.addEventListener(this.choices.input.element, 'input', (event) => {\n this.isFromSearch = !!event.target.value;\n if (!event.target.value) {\n this.triggerUpdate();\n }\n else {\n this.serverCount = null;\n this.downloadedResources = [];\n }\n });\n }\n this.addEventListener(input, 'choice', () => {\n if (this.component.multiple && this.component.dataSrc === 'resource' && this.isFromSearch) {\n this.triggerUpdate();\n }\n this.isFromSearch = false;\n });\n // avoid spamming the resource/url endpoint when we have server side filtering enabled.\n const debounceTimeout = this.component.searchField && (this.isSelectResource || this.isSelectURL) ?\n (this.component.searchDebounce === 0 ? 0 : this.component.searchDebounce || this.defaultSchema.searchDebounce) * 1000\n : 0;\n const updateComponent = (evt) => {\n this.triggerUpdate(evt.detail.value);\n };\n this.addEventListener(input, 'search', lodash_1.default.debounce((e) => {\n updateComponent(e);\n this.positionDropdown();\n }, debounceTimeout));\n this.addEventListener(input, 'stopSearch', () => this.triggerUpdate());\n this.addEventListener(input, 'hideDropdown', () => {\n if (this.choices && this.choices.input && this.choices.input.element) {\n this.choices.input.element.value = '';\n }\n this.updateItems(null, true);\n });\n }\n this.addEventListener(input, 'showDropdown', () => {\n this.update();\n this.positionDropdown();\n });\n if (this.shouldPositionDropdown) {\n this.addEventListener(input, 'highlightChoice', () => {\n this.positionDropdown();\n });\n }\n // Add value options.\n const value = this.undoValueTyping(this.dataValue);\n this.addValueOptions();\n this.setChoicesValue(value);\n if (this.isSelectResource && this.refs.addResource) {\n this.addEventListener(this.refs.addResource, 'click', (event) => {\n event.preventDefault();\n const formioForm = this.ce('div');\n const dialog = this.createModal(formioForm);\n const projectUrl = lodash_1.default.get(this.root, 'formio.projectUrl', Formio_1.Formio.getProjectUrl());\n const formUrl = `${projectUrl}/form/${this.component.data.resource}`;\n new Form_1.default(formioForm, formUrl, {}).ready\n .then((form) => {\n form.on('submit', (submission) => {\n // If valueProperty is set, replace the submission with the corresponding value\n let value = this.valueProperty ? lodash_1.default.get(submission, this.valueProperty) : submission;\n if (this.component.multiple) {\n value = [...this.dataValue, value];\n }\n this.setValue(value);\n this.triggerUpdate();\n dialog.close();\n });\n });\n });\n }\n // Force the disabled state with getters and setters.\n this.disabled = this.shouldDisabled;\n this.triggerUpdate();\n return superAttach;\n }\n setDropdownPosition() {\n var _a, _b, _c, _d;\n const dropdown = (_b = (_a = this.choices) === null || _a === void 0 ? void 0 : _a.dropdown) === null || _b === void 0 ? void 0 : _b.element;\n const container = (_d = (_c = this.choices) === null || _c === void 0 ? void 0 : _c.containerOuter) === null || _d === void 0 ? void 0 : _d.element;\n if (!dropdown || !container) {\n return;\n }\n const containerPosition = container.getBoundingClientRect();\n const isFlipped = container.classList.contains('is-flipped');\n lodash_1.default.assign(dropdown.style, {\n top: `${isFlipped ? containerPosition.top - dropdown.offsetHeight : containerPosition.top + containerPosition.height}px`,\n left: `${containerPosition.left}px`,\n width: `${containerPosition.width}px`,\n position: 'fixed',\n bottom: 'unset',\n right: 'unset',\n });\n }\n hasDataGridAncestor(comp) {\n comp = comp || this;\n if (comp.inDataGrid || comp.type === 'datagrid') {\n return true;\n }\n else if (comp.parent) {\n return this.hasDataGridAncestor(comp.parent);\n }\n else {\n return false;\n }\n }\n positionDropdown(scroll) {\n var _a;\n if (!this.shouldPositionDropdown || !this.choices || (!((_a = this.choices.dropdown) === null || _a === void 0 ? void 0 : _a.isActive) && scroll)) {\n return;\n }\n this.setDropdownPosition();\n this.itemsLoaded.then(() => {\n this.setDropdownPosition();\n });\n }\n get isLoadingAvailable() {\n return !this.isScrollLoading && this.additionalResourcesAvailable;\n }\n onScroll() {\n if (this.isLoadingAvailable) {\n this.isScrollLoading = true;\n this.setLoadingItem(true);\n this.triggerUpdate(this.choices.input.element.value);\n }\n }\n attachRefreshOnBlur() {\n if (this.component.refreshOnBlur) {\n this.on('blur', (instance) => {\n this.checkRefreshOn([{ instance, value: instance.dataValue }], { fromBlur: true });\n });\n }\n }\n /* eslint-enable max-statements */\n update() {\n if (this.component.dataSrc === 'custom') {\n this.updateCustomItems();\n }\n // Activate the control.\n this.activate();\n }\n set disabled(disabled) {\n super.disabled = disabled;\n if (!this.choices) {\n return;\n }\n if (disabled) {\n this.setDisabled(this.choices.containerInner.element, true);\n this.focusableElement.removeAttribute('tabIndex');\n this.choices.disable();\n }\n else {\n this.setDisabled(this.choices.containerInner.element, false);\n this.focusableElement.setAttribute('tabIndex', this.component.tabindex || 0);\n this.choices.enable();\n }\n }\n get disabled() {\n return super.disabled;\n }\n set visible(value) {\n // If we go from hidden to visible, trigger a refresh.\n if (value && (!this._visible !== !value)) {\n this.triggerUpdate();\n }\n super.visible = value;\n }\n get visible() {\n return super.visible;\n }\n addCurrentChoices(values, items, keyValue) {\n if (!values) {\n return false;\n }\n const notFoundValuesToAdd = [];\n const added = values.reduce((defaultAdded, value) => {\n if (!value || lodash_1.default.isEmpty(value)) {\n return defaultAdded;\n }\n let found = false;\n // Make sure that `items` and `this.selectOptions` points\n // to the same reference. Because `this.selectOptions` is\n // internal property and all items are populated by\n // `this.addOption` method, we assume that items has\n // 'label' and 'value' properties. This assumption allows\n // us to read correct value from the item.\n const isSelectOptions = items === this.selectOptions;\n if (items && items.length) {\n lodash_1.default.each(items, (choice) => {\n if (choice._id && value._id && (choice._id === value._id)) {\n found = true;\n return false;\n }\n const itemValue = keyValue ? choice.value : this.itemValue(choice, isSelectOptions);\n found |= lodash_1.default.isEqual(itemValue, value);\n return found ? false : true;\n });\n }\n // Add the default option if no item is found.\n if (!found) {\n notFoundValuesToAdd.push(this.selectValueAndLabel(value));\n return true;\n }\n return found || defaultAdded;\n }, false);\n if (notFoundValuesToAdd.length) {\n if (this.choices) {\n this.choices.setChoices(notFoundValuesToAdd, 'value', 'label');\n }\n notFoundValuesToAdd.map(notFoundValue => {\n this.addOption(notFoundValue.value, notFoundValue.label);\n });\n }\n return added;\n }\n getValueAsString(data, options) {\n return (this.component.multiple && Array.isArray(data))\n ? data.map((v) => this.asString(v, options)).join(', ')\n : this.asString(data, options);\n }\n getValue() {\n // If the widget isn't active.\n if (this.viewOnly || this.loading\n || (!this.component.lazyLoad && !this.selectOptions.length)\n || !this.element) {\n return this.dataValue;\n }\n let value = this.emptyValue;\n if (this.choices) {\n value = this.choices.getValue(true);\n // Make sure we don't get the placeholder\n if (!this.component.multiple &&\n this.component.placeholder &&\n (value === this.t(this.component.placeholder, { _userInput: true }))) {\n value = this.emptyValue;\n }\n }\n else if (this.refs.selectContainer) {\n value = this.refs.selectContainer.value;\n if (this.valueProperty === '' || this.isEntireObjectDisplay()) {\n if (value === '') {\n return {};\n }\n const option = this.selectOptions[value] ||\n this.selectOptions.find(option => option.id === value);\n if (option && lodash_1.default.isObject(option.value)) {\n value = option.value;\n }\n }\n }\n else {\n value = this.dataValue;\n }\n // Choices will return undefined if nothing is selected. We really want '' to be empty.\n if (value === undefined || value === null) {\n value = '';\n }\n return value;\n }\n redraw() {\n const done = super.redraw();\n this.triggerUpdate();\n return done;\n }\n normalizeSingleValue(value) {\n if (lodash_1.default.isNil(value)) {\n return;\n }\n const valueIsObject = lodash_1.default.isObject(value);\n //check if value equals to default emptyValue\n if (valueIsObject && Object.keys(value).length === 0) {\n return value;\n }\n const dataType = this.component.dataType || 'auto';\n const normalize = {\n value,\n number() {\n const numberValue = Number(this.value);\n const isEquivalent = value.toString() === numberValue.toString();\n if (!Number.isNaN(numberValue) && Number.isFinite(numberValue) && value !== '' && isEquivalent) {\n this.value = numberValue;\n }\n return this;\n },\n boolean() {\n if (lodash_1.default.isString(this.value)\n && (this.value.toLowerCase() === 'true'\n || this.value.toLowerCase() === 'false')) {\n this.value = (this.value.toLowerCase() === 'true');\n }\n return this;\n },\n string() {\n this.value = String(this.value);\n return this;\n },\n object() {\n return this;\n },\n auto() {\n if (lodash_1.default.isObject(this.value)) {\n this.value = this.object().value;\n }\n else {\n this.value = this.string().number().boolean().value;\n }\n return this;\n }\n };\n try {\n return normalize[dataType]().value;\n }\n catch (err) {\n console.warn(this.t('failedToNormalize'), err);\n return value;\n }\n }\n /**\n * Normalize values coming into updateValue. For example, depending on the configuration, string value `\"true\"` will be normalized to boolean `true`.\n * @param {*} value - The value to normalize\n * @returns {*} - Returns the normalized value\n */\n normalizeValue(value) {\n if (this.component.multiple && Array.isArray(value)) {\n return value.map((singleValue) => this.normalizeSingleValue(singleValue));\n }\n return super.normalizeValue(this.normalizeSingleValue(value));\n }\n setMetadata(value, flags = {}) {\n var _a, _b;\n if (lodash_1.default.isNil(value)) {\n return;\n }\n const valueIsObject = lodash_1.default.isObject(value);\n //check if value equals to default emptyValue\n if (valueIsObject && Object.keys(value).length === 0) {\n return value;\n }\n // Check to see if we need to save off the template data into our metadata.\n const templateValue = this.component.reference && (value === null || value === void 0 ? void 0 : value._id) ? value._id.toString() : value;\n const shouldSaveData = (!valueIsObject || this.component.reference) && !this.inDataTable;\n if (!lodash_1.default.isNil(templateValue) && shouldSaveData && this.templateData && this.templateData[templateValue] && ((_a = this.root) === null || _a === void 0 ? void 0 : _a.submission)) {\n const submission = this.root.submission;\n if (!submission.metadata) {\n submission.metadata = {};\n }\n if (!submission.metadata.selectData) {\n submission.metadata.selectData = {};\n }\n let templateData = this.templateData[templateValue];\n if (this.component.multiple) {\n templateData = {};\n const dataValue = this.dataValue;\n if (dataValue && lodash_1.default.isArray(dataValue) && dataValue.length) {\n dataValue.forEach((dataValueItem) => {\n const dataValueItemValue = this.component.reference ? dataValueItem._id.toString() : dataValueItem;\n templateData[dataValueItemValue] = this.templateData[dataValueItemValue];\n });\n }\n templateData[value] = this.templateData[value];\n }\n lodash_1.default.set(submission.metadata.selectData, this.path, templateData);\n }\n if (flags.resetValue && ((_b = this.root) === null || _b === void 0 ? void 0 : _b.submission) && !this.options.readOnly) {\n const submission = this.root.submission;\n if (!submission.metadata) {\n submission.metadata = {};\n }\n submission.metadata.selectData = {};\n }\n }\n updateValue(value, flags) {\n const changed = super.updateValue(value, flags);\n if (changed || !this.selectMetadata || flags.resetValue) {\n if (this.component.multiple && Array.isArray(this.dataValue)) {\n this.dataValue.forEach(singleValue => this.setMetadata(singleValue, flags));\n }\n else {\n this.setMetadata(this.dataValue, flags);\n }\n }\n return changed;\n }\n undoValueTyping(value) {\n let untypedValue = value;\n if (this.component.multiple && Array.isArray(value)) {\n untypedValue = value.map(v => {\n if (typeof v === 'boolean' || typeof v === 'number') {\n return v.toString();\n }\n return v;\n });\n }\n else {\n if (typeof value === 'boolean' || typeof value === 'number') {\n untypedValue = value.toString();\n }\n }\n return untypedValue;\n }\n setValue(value, flags = {}) {\n const previousValue = this.dataValue;\n const changed = this.updateValue(value, flags);\n if (this.component.widget === 'html5' && (lodash_1.default.isEqual(value, previousValue) || lodash_1.default.isEqual(previousValue, {}) && lodash_1.default.isEqual(flags, {})) && !flags.fromSubmission) {\n return false;\n }\n value = this.dataValue;\n const hasPreviousValue = !this.isEmpty(previousValue);\n const hasValue = !this.isEmpty(value);\n // Undo typing when searching to set the value.\n value = this.undoValueTyping(value);\n if (this.isHtmlRenderMode() && flags && flags.fromSubmission && changed) {\n this.itemsLoaded.then(() => {\n this.redraw();\n });\n return changed;\n }\n // Do not set the value if we are loading... that will happen after it is done.\n if (this.loading) {\n return changed;\n }\n // Determine if we need to perform an initial lazyLoad api call if searchField is provided.\n if (this.isInitApiCallNeeded(hasValue)) {\n this.loading = true;\n this.lazyLoadInit = true;\n const searchProperty = this.component.searchField || this.component.valueProperty;\n this.triggerUpdate(lodash_1.default.get(value.data || value, searchProperty, value), true);\n this.itemsLoaded.then(() => {\n this.setChoicesValue(value, hasPreviousValue, flags);\n });\n return changed;\n }\n // Add the value options.\n this.itemsLoaded.then(() => {\n this.addValueOptions();\n this.setChoicesValue(value, hasPreviousValue, flags);\n });\n return changed;\n }\n isInitApiCallNeeded(hasValue) {\n return this.component.lazyLoad &&\n !this.lazyLoadInit &&\n !this.active &&\n !this.selectOptions.length &&\n hasValue &&\n this.shouldInitialLoad &&\n this.visible && (this.component.searchField || this.component.valueProperty);\n }\n setChoicesValue(value, hasPreviousValue, flags = {}) {\n const hasValue = !this.isEmpty(value) || flags.fromSubmission;\n hasPreviousValue = (hasPreviousValue === undefined) ? true : hasPreviousValue;\n if (this.choices) {\n // Now set the value.\n if (hasValue) {\n this.choices.removeActiveItems();\n // Add the currently selected choices if they don't already exist.\n const currentChoices = Array.isArray(value) && this.component.multiple ? value : [value];\n if (!this.addCurrentChoices(currentChoices, this.selectOptions, true)) {\n this.choices.setChoices(this.selectOptions, 'value', 'label', true);\n }\n this.choices.setChoiceByValue(currentChoices);\n }\n else if (hasPreviousValue || flags.resetValue) {\n this.choices.removeActiveItems();\n }\n }\n else {\n if (hasValue) {\n const values = Array.isArray(value) ? value : [value];\n if (!lodash_1.default.isEqual(this.dataValue, this.defaultValue) && this.selectOptions.length < 2\n || (this.selectData && flags.fromSubmission)) {\n const { value, label } = this.selectValueAndLabel(this.dataValue);\n this.addOption(value, label);\n }\n lodash_1.default.each(this.selectOptions, (selectOption) => {\n lodash_1.default.each(values, (val) => {\n if (selectOption.value === '') {\n selectOption.value = {};\n }\n if (lodash_1.default.isEqual(val, selectOption.value) && selectOption.element) {\n selectOption.element.selected = true;\n selectOption.element.setAttribute('selected', 'selected');\n return false;\n }\n });\n });\n }\n else {\n lodash_1.default.each(this.selectOptions, (selectOption) => {\n if (selectOption.element) {\n selectOption.element.selected = false;\n selectOption.element.removeAttribute('selected');\n }\n });\n }\n }\n }\n validateValueAvailability(setting, value) {\n if (!(0, utils_1.boolValue)(setting) || !value) {\n return true;\n }\n const values = this.getOptionsValues();\n if (values) {\n if (lodash_1.default.isObject(value)) {\n const compareComplexValues = (optionValue) => {\n const normalizedOptionValue = this.normalizeSingleValue(optionValue);\n if (!lodash_1.default.isObject(normalizedOptionValue)) {\n return false;\n }\n try {\n return (JSON.stringify(normalizedOptionValue) === JSON.stringify(value));\n }\n catch (err) {\n console.warn.error(this.t('failedToCompareItems'), err);\n return false;\n }\n };\n return values.findIndex((optionValue) => compareComplexValues(optionValue)) !== -1;\n }\n return values.findIndex((optionValue) => this.normalizeSingleValue(optionValue) === value) !== -1;\n }\n return false;\n }\n /**\n * Performs required transformations on the initial value to use in selectOptions\n * @param {*} value - The value to transform.\n * @returns {*} - Returns the options value.\n */\n getOptionValue(value) {\n return lodash_1.default.isObject(value) && this.isEntireObjectDisplay()\n ? this.normalizeSingleValue(value)\n : lodash_1.default.isObject(value) && (this.valueProperty || this.component.key !== 'resource')\n ? value\n : lodash_1.default.isObject(value) && !this.valueProperty\n ? this.interpolate(this.component.template, { item: value }).replace(/<\\/?[^>]+(>|$)/g, '')\n : lodash_1.default.isNull(value)\n ? this.emptyValue\n : String(this.normalizeSingleValue(value));\n }\n /**\n * If component has static values (values, json) or custom values, returns an array of them\n * @returns {Array<*>|undefined} - Returns an array of the static or custom values.\n */\n getOptionsValues() {\n let rawItems = [];\n switch (this.component.dataSrc) {\n case 'values':\n rawItems = this.component.data.values;\n break;\n case 'json':\n rawItems = this.component.data.json;\n break;\n case 'custom':\n rawItems = this.getCustomItems();\n break;\n case 'url':\n rawItems = this.selectItems;\n break;\n }\n if (typeof rawItems === 'string') {\n try {\n rawItems = JSON.parse(rawItems);\n }\n catch (err) {\n console.warn(err.message);\n rawItems = [];\n }\n }\n if (!Array.isArray(rawItems)) {\n return;\n }\n return rawItems.map((item) => this.getOptionValue(this.itemValue(item)));\n }\n /**\n * Deletes the value of the component.\n */\n deleteValue() {\n this.setValue('', {\n noUpdateEvent: true\n });\n this.unset();\n }\n /**\n * Check if a component is eligible for multiple validation\n * @returns {boolean} - Returns FALSE for select components.\n */\n validateMultiple() {\n // Select component will contain one input when flagged as multiple.\n return false;\n }\n /**\n * Output this select dropdown as a string value.\n * @returns {*}\n */\n isBooleanOrNumber(value) {\n return typeof value === 'number' || typeof value === 'boolean';\n }\n getNormalizedValues() {\n if (!this.component || !this.component.data || !this.component.data.values) {\n return;\n }\n return this.component.data.values.map(value => ({ label: value.label, value: String(this.normalizeSingleValue(value.value)) }));\n }\n asString(value, options = {}) {\n var _a;\n value = value !== null && value !== void 0 ? value : this.getValue();\n if (options.modalPreview || this.inDataTable || options.email) {\n if (this.inDataTable) {\n value = this.undoValueTyping(value);\n }\n const templateValue = (this.isEntireObjectDisplay() && !lodash_1.default.isObject(value.data)) ? { data: value } : value;\n const template = this.itemTemplate(templateValue, value, options);\n return template;\n }\n //need to convert values to strings to be able to compare values with available options that are strings\n const convertToString = (data, valueProperty) => {\n if (valueProperty) {\n if (Array.isArray(data)) {\n data.forEach((item) => item[valueProperty] = item[valueProperty].toString());\n }\n else if (lodash_1.default.isObject(data)) {\n data[valueProperty] = data[valueProperty].toString();\n }\n return data;\n }\n if (this.isBooleanOrNumber(data)) {\n data = data.toString();\n }\n if (Array.isArray(data) && data.some(item => this.isBooleanOrNumber(item))) {\n data = data.map(item => this.isBooleanOrNumber(item) ? item.toString() : item);\n }\n return data;\n };\n value = convertToString(value);\n if (['values', 'custom'].includes(this.component.dataSrc) && !this.asyncCustomValues()) {\n const { items, valueProperty, } = this.component.dataSrc === 'values'\n ? {\n items: convertToString(this.getNormalizedValues(), 'value'),\n valueProperty: 'value',\n }\n : {\n items: convertToString(this.getCustomItems(), this.valueProperty),\n valueProperty: this.valueProperty,\n };\n const getFromValues = () => {\n const initialValue = lodash_1.default.find(items, [valueProperty, value]);\n const values = this.defaultSchema.data.values || [];\n return lodash_1.default.isEqual(initialValue, values[0]) ? '-' : initialValue;\n };\n value = (this.component.multiple && Array.isArray(value))\n ? lodash_1.default.filter(items, (item) => value.includes(item.value))\n : (valueProperty && items)\n ? (_a = getFromValues()) !== null && _a !== void 0 ? _a : { value, label: value }\n : value;\n }\n if (lodash_1.default.isString(value)) {\n return value;\n }\n const getTemplateValue = (v) => {\n const itemTemplate = this.itemTemplate(v);\n return options.csv && itemTemplate\n ? (0, utils_1.removeHTML)(itemTemplate)\n : itemTemplate;\n };\n if (Array.isArray(value)) {\n const items = [];\n value.forEach(item => items.push(getTemplateValue(item)));\n if (this.component.dataSrc === 'resource' && items.length > 0) {\n return items.join(', ');\n }\n else if (items.length > 0) {\n return items.join('<br />');\n }\n else {\n return '-';\n }\n }\n if (this.isEntireObjectDisplay() && lodash_1.default.isObject(value)) {\n return JSON.stringify(value);\n }\n return !lodash_1.default.isNil(value)\n ? getTemplateValue(value)\n : '-';\n }\n detach() {\n var _a, _b;\n this.off('blur');\n if (this.choices) {\n if ((_b = (_a = this.choices.containerOuter) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.parentNode) {\n this.choices.destroy();\n }\n this.choices = null;\n }\n super.detach();\n }\n focus() {\n super.focus.call(this);\n if (this.focusableElement) {\n this.focusableElement.focus();\n }\n }\n setErrorClasses(elements, dirty, hasError, hasMessages, element = this.element) {\n super.setErrorClasses(elements, dirty, hasError, hasMessages, element);\n if (this.choices) {\n super.setErrorClasses([this.choices.containerInner.element], dirty, hasError, hasMessages, element);\n }\n else {\n super.setErrorClasses([this.refs.selectContainer], dirty, hasError, hasMessages, element);\n }\n }\n}\nexports[\"default\"] = SelectComponent;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/components/select/Select.js?");
5352
5352
 
5353
5353
  /***/ }),
5354
5354
 
@@ -5799,7 +5799,7 @@ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {
5799
5799
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
5800
5800
 
5801
5801
  "use strict";
5802
- eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nvar _a;\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst bootstrap_1 = __importDefault(__webpack_require__(/*! @formio/bootstrap */ \"./node_modules/@formio/bootstrap/lib/cjs/bootstrap5.js\"));\nexports[\"default\"] = Object.assign(Object.assign({}, (((_a = bootstrap_1.default === null || bootstrap_1.default === void 0 ? void 0 : bootstrap_1.default.translations) === null || _a === void 0 ? void 0 : _a.en) || {})), { unsavedRowsError: 'Please save all rows before proceeding.', invalidRowsError: 'Please correct invalid rows before proceeding.', invalidRowError: 'Invalid row. Please correct it or delete.', invalidOption: '{{field}} is an invalid value.', invalidDay: '{{field}} is not a valid day.', complete: 'Submission Complete', error: 'Please fix the following errors before submitting.', errorListHotkey: 'Press Ctrl + Alt + X to go back to the error list.', errorsListNavigationMessage: 'Click to navigate to the field with following error.', submitError: 'Please check the form and correct all errors before submitting.', required: '{{field}} is required', unique: '{{field}} must be unique', array: '{{field}} must be an array', array_nonempty: '{{field}} must be a non-empty array', nonarray: '{{field}} must not be an array', select: '{{field}} contains an invalid selection', pattern: '{{field}} does not match the pattern {{pattern}}', minLength: '{{field}} must have at least {{length}} characters.', maxLength: '{{field}} must have no more than {{length}} characters.', minWords: '{{field}} must have at least {{length}} words.', maxWords: '{{field}} must have no more than {{length}} words.', min: '{{field}} cannot be less than {{min}}.', max: '{{field}} cannot be greater than {{max}}.', maxDate: '{{field}} should not contain date after {{maxDate}}', minDate: '{{field}} should not contain date before {{minDate}}', maxYear: '{{field}} should not contain year greater than {{maxYear}}', minYear: '{{field}} should not contain year less than {{minYear}}', minSelectedCount: 'You must select at least {{minCount}} items', maxSelectedCount: 'You may only select up to {{maxCount}} items', invalid_email: '{{field}} must be a valid email.', invalid_url: '{{field}} must be a valid url.', invalid_regex: '{{field}} does not match the pattern {{regex}}.', invalid_date: '{{field}} is not a valid date.', invalid_day: '{{field}} is not a valid day.', invalidValueProperty: 'Invalid Value Property', mask: '{{field}} does not match the mask.', valueIsNotAvailable: '{{ field }} is an invalid value.', stripe: '{{stripe}}', month: 'Month', day: 'Day', year: 'Year', january: 'January', february: 'February', march: 'March', april: 'April', may: 'May', june: 'June', july: 'July', august: 'August', september: 'September', october: 'October', november: 'November', december: 'December', next: 'Next', previous: 'Previous', cancel: 'Cancel', submit: 'Submit Form', confirmCancel: 'Are you sure you want to cancel?', saveDraftInstanceError: 'Cannot save draft because there is no formio instance.', saveDraftAuthError: 'Cannot save draft unless a user is authenticated.', restoreDraftInstanceError: 'Cannot restore draft because there is no formio instance.', saveDraftError: 'Unable to save draft.', restoreDraftError: 'Unable to restore draft.', time: 'Invalid time', cancelButtonAriaLabel: 'Cancel button. Click to reset the form', previousButtonAriaLabel: 'Previous button. Click to go back to the previous tab', nextButtonAriaLabel: 'Next button. Click to go to the next tab', submitButtonAriaLabel: 'Submit Form button. Click to submit the form', reCaptchaTokenValidationError: 'ReCAPTCHA: Token validation error', reCaptchaTokenNotSpecifiedError: 'ReCAPTCHA: Token is not specified in submission', apiKey: 'API Key is not unique: {{key}}', typeRemaining: '{{ remaining }} {{ type }} remaining.', typeCount: '{{ count }} {{ type }}', requiredDayField: '{{ field }} is required', requiredDayEmpty: '{{ field }} is required', requiredMonthField: '{{ field }} is required', requiredYearField: '{{ field }} is required', formNotReady: 'Form not ready. Use form.ready promise', noFormElement: 'No DOM element for form.', notUniqueKey: 'API Key is not unique', newFormSchema: 'Form schema is for a newer version, please upgrade your renderer. Some functionality may not work.', missingUrl: 'Missing URL argument', urlNotAttachedToBtn: 'You should add a URL to this button.', loadingProjectSettingsError: 'Could not load project settings', sessionStorageSupportError: 'Session storage is not supported in this browser.', builderUniqueError: `You cannot add more than one {{componentKeyOrTitle}} component to one page.`, pageNotFound: 'Page not found', noDragInfoError: 'There is no Drag Info available for either dragged or sibling element', addonSupportTypeError: 'Addon {{label}} does not support component of type {{type}}', setPathError: 'Should not be setting the path of a component.', calculatedPathDeprecation: 'component.calculatedPath was deprecated, use component.path instead.', unknownTemplate: 'Unknown template: {{name}}', unknownComponent: 'Unknown component: {{type}}', renderTemplateFunctionDeprecation: `Form.io 'render' template function is deprecated.\n If you need to render template (template A) inside of another template (template B),\n pass pre-compiled template A (use this.renderTemplate('template_A_name') as template context variable for template B`, whenReadyDeprecation: 'The whenReady() method has been deprecated. Please use the dataReady property instead.', loadResourcesError: 'Unable to load resources for {{componentKey}}', noSelectDataConfiguration: 'Select component {{componentKey}} does not have data configuration.', indexedDBSupportError: \"Your browser doesn't support current version of indexedDB\", caretPositionSavingError: 'An error occurred while trying to save caret position', iteratableRowsError: 'Getter #iteratableRows() is not implemented', checkRowDeprecation: 'Deprecation Warning: checkRow method has been replaced with processRow', noOAuthBtn: 'You must add the OAuth button to a form for it to function properly', noOAuthConfiguration: 'OAuth not configured. You must configure oauth for your project before it will work.', oAuthErrorsTitle: 'The Following Error Has Occured', noOAuthFormUrl: 'You must attach a Form API url to your form in order to use OAuth buttons.', oAuthStateError: 'OAuth state does not match. Please try logging in again.', componentInvalidRowValidation: 'Invalid row validation for {{componentKey}}', videoPlayerNotFound: 'Video player not found in template.', synchronizationFailed: 'Synchronization is failed', fileWithDuplicatedNameInProgress: 'File with the same name is already being uploaded', fileWithDuplicatedNameLoaded: 'File with the same name is already uploaded', nestedForm: 'Nested form', noDataProvided: 'No data provided', subformSubmissionLoadingError: 'Unable to load subform submission {{submissionId}}:', noDelimiterSet: 'In order for thousands separator to work properly, you must set the delimiter to true in the component json', noSiteKey: 'There is no Site Key specified in settings in form JSON', failedToNormalize: 'Failed to normalize value', failedToCompareItems: 'Error while comparing items', editorFocusError: 'An editor did not initialize properly when trying to focus:', quillImageUploadFailed: 'Quill image upload failed', noFilesSelected: 'No files selected', needConfigurationForQuill: 'The WYSIWYG settings are configured for CKEditor. For this renderer, you will need to use configurations for the Quill Editor. See https://quilljs.com/docs/configuration for more information.', waitPdfConverting: 'Converting PDF. Please wait.', uploading: 'Uploading', pasteBelow: 'Paste below', copy: 'Copy', move: 'Move', edit: 'Edit', editJson: 'Edit JSON', remove: 'Remove', clickToSetValue: 'Click to set value', words: 'words', characters: 'characters', addAnother: 'Add Another', yes: 'Yes', no: 'No', wantToClearData: 'Do you want to clear data?', yesDelete: 'Yes, delete it', waitFileProcessing: 'Processing file. Please wait...', wrongFileType: 'File is the wrong type; it must be {{ pattern }}', fileTooSmall: 'File is too small; it must be at least {{ size }}', fileTooBig: 'File is too big; it must be at most {{ size }}', noFileService: 'File Service not provided.', fileProcessingFailed: 'File processing has been failed.', readyForUpload: 'Ready to be uploaded into storage', readyForRemovingFromStorage: 'Ready to be removed from storage', preparingFileToRemove: 'Preparing file to remove', succefullyRemoved: 'Succefully removed', succefullyUploaded: 'Succefully uploaded', maxSelectItems: 'You may only select up to {{maxCount}} items', minSelectItems: 'You must select at least {{minCount}} items', clickToSign: 'Click to Sign', surveyQuestion: 'Question', surveyQuestionValue: 'Value', success: 'Success', noResultsFound: 'No results found', noChoices: 'No choices to choose from', typeToSearch: 'Type to search', loading: 'Loading' });\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/translations/en.js?");
5802
+ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nvar _a;\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst bootstrap_1 = __importDefault(__webpack_require__(/*! @formio/bootstrap */ \"./node_modules/@formio/bootstrap/lib/cjs/bootstrap5.js\"));\nexports[\"default\"] = Object.assign(Object.assign({}, (((_a = bootstrap_1.default === null || bootstrap_1.default === void 0 ? void 0 : bootstrap_1.default.translations) === null || _a === void 0 ? void 0 : _a.en) || {})), { unsavedRowsError: 'Please save all rows before proceeding.', invalidRowsError: 'Please correct invalid rows before proceeding.', invalidRowError: 'Invalid row. Please correct it or delete.', invalidOption: '{{field}} is an invalid value.', invalidDay: '{{field}} is not a valid day.', complete: 'Submission Complete', error: 'Please fix the following errors before submitting.', errorListHotkey: 'Press Ctrl + Alt + X to go back to the error list.', errorsListNavigationMessage: 'Click to navigate to the field with following error.', submitError: 'Please check the form and correct all errors before submitting.', required: '{{field}} is required', unique: '{{field}} must be unique', array: '{{field}} must be an array', array_nonempty: '{{field}} must be a non-empty array', nonarray: '{{field}} must not be an array', select: '{{field}} contains an invalid selection', pattern: '{{field}} does not match the pattern {{pattern}}', minLength: '{{field}} must have at least {{length}} characters.', maxLength: '{{field}} must have no more than {{length}} characters.', minWords: '{{field}} must have at least {{length}} words.', maxWords: '{{field}} must have no more than {{length}} words.', min: '{{field}} cannot be less than {{min}}.', max: '{{field}} cannot be greater than {{max}}.', maxDate: '{{field}} should not contain date after {{maxDate}}', minDate: '{{field}} should not contain date before {{minDate}}', maxYear: '{{field}} should not contain year greater than {{maxYear}}', minYear: '{{field}} should not contain year less than {{minYear}}', minSelectedCount: 'You must select at least {{minCount}} items', maxSelectedCount: 'You may only select up to {{maxCount}} items', invalid_email: '{{field}} must be a valid email.', invalid_url: '{{field}} must be a valid url.', invalid_regex: '{{field}} does not match the pattern {{regex}}.', invalid_date: '{{field}} is not a valid date.', invalid_day: '{{field}} is not a valid day.', invalidValueProperty: 'Invalid Value Property', mask: '{{field}} does not match the mask.', valueIsNotAvailable: '{{ field }} is an invalid value.', stripe: '{{stripe}}', month: 'Month', day: 'Day', year: 'Year', january: 'January', february: 'February', march: 'March', april: 'April', may: 'May', june: 'June', july: 'July', august: 'August', september: 'September', october: 'October', november: 'November', december: 'December', next: 'Next', previous: 'Previous', cancel: 'Cancel', submit: 'Submit Form', confirmCancel: 'Are you sure you want to cancel?', saveDraftInstanceError: 'Cannot save draft because there is no formio instance.', saveDraftAuthError: 'Cannot save draft unless a user is authenticated.', restoreDraftInstanceError: 'Cannot restore draft because there is no formio instance.', saveDraftError: 'Unable to save draft.', restoreDraftError: 'Unable to restore draft.', time: 'Invalid time', cancelButtonAriaLabel: 'Cancel button. Click to reset the form', previousButtonAriaLabel: 'Previous button. Click to go back to the previous tab', nextButtonAriaLabel: 'Next button. Click to go to the next tab', submitButtonAriaLabel: 'Submit Form button. Click to submit the form', reCaptchaTokenValidationError: 'ReCAPTCHA: Token validation error', reCaptchaTokenNotSpecifiedError: 'ReCAPTCHA: Token is not specified in submission', apiKey: 'API Key is not unique: {{key}}', apiKeyNotValid: 'API Key is not valid: {{key}}', typeRemaining: '{{ remaining }} {{ type }} remaining.', typeCount: '{{ count }} {{ type }}', requiredDayField: '{{ field }} is required', requiredDayEmpty: '{{ field }} is required', requiredMonthField: '{{ field }} is required', requiredYearField: '{{ field }} is required', formNotReady: 'Form not ready. Use form.ready promise', noFormElement: 'No DOM element for form.', notUniqueKey: 'API Key is not unique', newFormSchema: 'Form schema is for a newer version, please upgrade your renderer. Some functionality may not work.', missingUrl: 'Missing URL argument', urlNotAttachedToBtn: 'You should add a URL to this button.', loadingProjectSettingsError: 'Could not load project settings', sessionStorageSupportError: 'Session storage is not supported in this browser.', builderUniqueError: `You cannot add more than one {{componentKeyOrTitle}} component to one page.`, pageNotFound: 'Page not found', noDragInfoError: 'There is no Drag Info available for either dragged or sibling element', addonSupportTypeError: 'Addon {{label}} does not support component of type {{type}}', setPathError: 'Should not be setting the path of a component.', calculatedPathDeprecation: 'component.calculatedPath was deprecated, use component.path instead.', unknownTemplate: 'Unknown template: {{name}}', unknownComponent: 'Unknown component: {{type}}', renderTemplateFunctionDeprecation: `Form.io 'render' template function is deprecated.\n If you need to render template (template A) inside of another template (template B),\n pass pre-compiled template A (use this.renderTemplate('template_A_name') as template context variable for template B`, whenReadyDeprecation: 'The whenReady() method has been deprecated. Please use the dataReady property instead.', loadResourcesError: 'Unable to load resources for {{componentKey}}', noSelectDataConfiguration: 'Select component {{componentKey}} does not have data configuration.', indexedDBSupportError: \"Your browser doesn't support current version of indexedDB\", caretPositionSavingError: 'An error occurred while trying to save caret position', iteratableRowsError: 'Getter #iteratableRows() is not implemented', checkRowDeprecation: 'Deprecation Warning: checkRow method has been replaced with processRow', noOAuthBtn: 'You must add the OAuth button to a form for it to function properly', noOAuthConfiguration: 'OAuth not configured. You must configure oauth for your project before it will work.', oAuthErrorsTitle: 'The Following Error Has Occured', noOAuthFormUrl: 'You must attach a Form API url to your form in order to use OAuth buttons.', oAuthStateError: 'OAuth state does not match. Please try logging in again.', componentInvalidRowValidation: 'Invalid row validation for {{componentKey}}', videoPlayerNotFound: 'Video player not found in template.', synchronizationFailed: 'Synchronization is failed', fileWithDuplicatedNameInProgress: 'File with the same name is already being uploaded', fileWithDuplicatedNameLoaded: 'File with the same name is already uploaded', nestedForm: 'Nested form', noDataProvided: 'No data provided', subformSubmissionLoadingError: 'Unable to load subform submission {{submissionId}}:', noDelimiterSet: 'In order for thousands separator to work properly, you must set the delimiter to true in the component json', noSiteKey: 'There is no Site Key specified in settings in form JSON', failedToNormalize: 'Failed to normalize value', failedToCompareItems: 'Error while comparing items', editorFocusError: 'An editor did not initialize properly when trying to focus:', quillImageUploadFailed: 'Quill image upload failed', noFilesSelected: 'No files selected', needConfigurationForQuill: 'The WYSIWYG settings are configured for CKEditor. For this renderer, you will need to use configurations for the Quill Editor. See https://quilljs.com/docs/configuration for more information.', waitPdfConverting: 'Converting PDF. Please wait.', uploading: 'Uploading', pasteBelow: 'Paste below', copy: 'Copy', move: 'Move', edit: 'Edit', editJson: 'Edit JSON', remove: 'Remove', clickToSetValue: 'Click to set value', words: 'words', characters: 'characters', addAnother: 'Add Another', yes: 'Yes', no: 'No', wantToClearData: 'Do you want to clear data?', yesDelete: 'Yes, delete it', waitFileProcessing: 'Processing file. Please wait...', wrongFileType: 'File is the wrong type; it must be {{ pattern }}', fileTooSmall: 'File is too small; it must be at least {{ size }}', fileTooBig: 'File is too big; it must be at most {{ size }}', noFileService: 'File Service not provided.', fileProcessingFailed: 'File processing has been failed.', readyForUpload: 'Ready to be uploaded into storage', readyForRemovingFromStorage: 'Ready to be removed from storage', preparingFileToRemove: 'Preparing file to remove', succefullyRemoved: 'Succefully removed', succefullyUploaded: 'Succefully uploaded', maxSelectItems: 'You may only select up to {{maxCount}} items', minSelectItems: 'You must select at least {{minCount}} items', clickToSign: 'Click to Sign', surveyQuestion: 'Question', surveyQuestionValue: 'Value', success: 'Success', noResultsFound: 'No results found', noChoices: 'No choices to choose from', typeToSearch: 'Type to search', loading: 'Loading' });\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/translations/en.js?");
5803
5803
 
5804
5804
  /***/ }),
5805
5805
 
@@ -6096,7 +6096,7 @@ eval("\nvar __createBinding = (this && this.__createBinding) || (Object.create ?
6096
6096
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
6097
6097
 
6098
6098
  "use strict";
6099
- eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.translateHTMLTemplate = exports.getContextButtons = exports.getContextComponents = exports.observeOverload = exports.withSwitch = exports.firstNonNil = exports.unfold = exports.bootstrapVersion = exports.uniqueKey = exports.iterateKey = exports.delay = exports.fieldData = exports.getCurrencyAffixes = exports.getNumberDecimalLimit = exports.getNumberSeparators = exports.matchInputMask = exports.unmaskValue = exports.getInputMask = exports.convertFormatToMask = exports.convertFormatToDayjs = exports.convertFormatToFlatpickr = exports.getLocaleDateFormatInfo = exports.formatOffset = exports.formatDate = exports.dayjsDate = exports.shouldHandleTimezone = exports.offsetDate = exports.currentTimezone = exports.isValidDate = exports.getDateSetting = exports.guid = exports.uniqueName = exports.convertStringToHTMLElement = exports.unescapeHTML = exports.removeHTML = exports.setActionProperty = exports.checkTrigger = exports.checkCondition = exports.checkJsonConditional = exports.checkCustomConditional = exports.getComponentActualValue = exports.checkSimpleConditional = exports.checkCalculated = exports.isMongoId = exports.boolValue = exports.getScriptPlugin = exports.getElementRect = exports.getPropertyValue = exports.getRandomComponentId = exports.evaluate = void 0;\nexports.hasEncodedTimezone = exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports.getFocusableElements = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.fastCloneDeep = exports.sanitize = void 0;\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst moment_timezone_1 = __importDefault(__webpack_require__(/*! moment-timezone/moment-timezone */ \"./node_modules/moment-timezone/moment-timezone.js\"));\nconst jstimezonedetect_1 = __importDefault(__webpack_require__(/*! jstimezonedetect */ \"./node_modules/jstimezonedetect/dist/jstz.min.js\"));\nconst dompurify_1 = __importDefault(__webpack_require__(/*! dompurify */ \"./node_modules/dompurify/dist/purify.cjs.js\"));\nconst dayjs_1 = __importDefault(__webpack_require__(/*! dayjs */ \"./node_modules/dayjs/dayjs.min.js\"));\nconst utc_1 = __importDefault(__webpack_require__(/*! dayjs/plugin/utc */ \"./node_modules/dayjs/plugin/utc.js\"));\nconst timezone_1 = __importDefault(__webpack_require__(/*! dayjs/plugin/timezone */ \"./node_modules/dayjs/plugin/timezone.js\"));\nconst advancedFormat_1 = __importDefault(__webpack_require__(/*! dayjs/plugin/advancedFormat */ \"./node_modules/dayjs/plugin/advancedFormat.js\"));\nconst core_1 = __webpack_require__(/*! @formio/core */ \"./node_modules/@formio/core/lib/index.js\");\nconst formUtils_1 = __webpack_require__(/*! ./formUtils */ \"./lib/cjs/utils/formUtils.js\");\nconst Evaluator_1 = __webpack_require__(/*! ./Evaluator */ \"./lib/cjs/utils/Evaluator.js\");\nconst conditionOperators_1 = __importDefault(__webpack_require__(/*! ./conditionOperators */ \"./lib/cjs/utils/conditionOperators/index.js\"));\ndayjs_1.default.extend(timezone_1.default);\ndayjs_1.default.extend(advancedFormat_1.default);\ndayjs_1.default.extend(utc_1.default);\n/**\n * Evaluate a method.\n * @param {Function|string|object} func - The function to evaluate.\n * @param {*} args - A map of arguments to pass to the function.\n * @param {string} ret - The name of the \"return\" variable in the script.\n * @param {boolean} interpolate - True if the script should be interpolated before being executed.\n * @param {import('@formio/core').EvaluatorOptions} options - The evaluator options.\n * @returns {*} - The result of the evaluation.\n */\nfunction evaluate(func, args, ret, interpolate, options = {}) {\n return Evaluator_1.Evaluator.evaluate(func, args, ret, interpolate, undefined, options);\n}\nexports.evaluate = evaluate;\n/**\n * Returns a random compoennt ID.\n * @returns {string} - A random component ID.\n */\nfunction getRandomComponentId() {\n return `e${Math.random().toString(36).substring(7)}`;\n}\nexports.getRandomComponentId = getRandomComponentId;\n/**\n * Get a property value of an element.\n * @param {CSSStyleDeclaration} style - The style element to get the property value from.\n * @param {string} prop - The property to get the value for.\n * @returns {number} - The value of the property.\n */\nfunction getPropertyValue(style, prop) {\n let value = style.getPropertyValue(prop);\n value = value ? value.replace(/[^0-9.]/g, '') : '0';\n return parseFloat(value);\n}\nexports.getPropertyValue = getPropertyValue;\n/**\n * Get an elements bounding rectagle.\n * @param {HTMLElement} element - A DOM element to get the bounding rectangle for.\n * @returns {{x: number, y: number, width: number, height: number}} - The bounding rectangle.\n */\nfunction getElementRect(element) {\n const style = window.getComputedStyle(element, null);\n return {\n x: getPropertyValue(style, 'left'),\n y: getPropertyValue(style, 'top'),\n width: getPropertyValue(style, 'width'),\n height: getPropertyValue(style, 'height')\n };\n}\nexports.getElementRect = getElementRect;\n/**\n * Get non HTMLElement property in the window object\n * @param {string} property - The window property to fetch the script plugin from.\n * @returns {any | undefined} - The HTML Element property on the window object.\n */\nfunction getScriptPlugin(property) {\n const obj = window[property];\n if (typeof HTMLElement === 'object' ? obj instanceof HTMLElement : //DOM2\n obj && typeof obj === 'object' && true && obj.nodeType === 1 && typeof obj.nodeName === 'string') {\n return undefined;\n }\n return obj;\n}\nexports.getScriptPlugin = getScriptPlugin;\n/**\n * Determines the boolean value of a setting.\n * @param {string|boolean} value - A string or boolean value to convert to boolean.\n * @returns {boolean} - The boolean value of the setting.\n */\nfunction boolValue(value) {\n if (lodash_1.default.isBoolean(value)) {\n return value;\n }\n else if (lodash_1.default.isString(value)) {\n return (value.toLowerCase() === 'true');\n }\n else {\n return !!value;\n }\n}\nexports.boolValue = boolValue;\n/**\n * Check to see if an ID is a mongoID.\n * @param {string} text - The text to check if it is a mongoID.\n * @returns {boolean} - TRUE if the text is a mongoID; FALSE otherwise.\n */\nfunction isMongoId(text) {\n return !!text.toString().match(/^[0-9a-fA-F]{24}$/);\n}\nexports.isMongoId = isMongoId;\n/**\n * Checks the calculated value for a provided component and data.\n * @param {import('@formio/core').Component} component - The component to check for the calculated value.\n * @param {import('@formio/core').Submission} submission - A submission object.\n * @param {*} rowData - The contextual row data for the component.\n */\nfunction checkCalculated(component, submission, rowData) {\n // Process calculated value stuff if present.\n if (component.calculateValue) {\n lodash_1.default.set(rowData, component.key, evaluate(component.calculateValue, {\n value: undefined,\n data: submission ? submission.data : rowData,\n row: rowData,\n util: this,\n component\n }, 'value'));\n }\n}\nexports.checkCalculated = checkCalculated;\n/**\n * Check if a simple conditional evaluates to true.\n * @param {import('@formio/core').Component} component - The component to check for the conditional.\n * @param {import('@formio/core').SimpleConditional} condition - The condition to check.\n * @param {*} row - The row data for the component.\n * @param {*} data - The full submission data.\n * @param {import('../../src/components/_classes/component/Component').Component} instance - The instance of the component.\n * @returns {boolean} - TRUE if the condition is true; FALSE otherwise.\n */\n/**\n *\n * @param conditionPaths\n * @param data\n */\nfunction getConditionalPathsRecursive(conditionPaths, data) {\n let currentGlobalIndex = 0;\n const conditionalPathsArray = [];\n const getConditionalPaths = (data, currentPath = '', localIndex = 0) => {\n currentPath = currentPath.replace(/^\\.+|\\.+$/g, '');\n const currentLocalIndex = localIndex;\n const currentData = lodash_1.default.get(data, currentPath);\n if (Array.isArray(currentData) && currentData.filter(Boolean).length > 0) {\n if (currentData.some(element => typeof element !== 'object')) {\n return;\n }\n const hasInnerDataArray = currentData.find(x => Array.isArray(x[conditionPaths[currentLocalIndex]]));\n if (hasInnerDataArray) {\n currentData.forEach((_, indexOutside) => {\n const innerCompDataPath = `${currentPath}[${indexOutside}].${conditionPaths[currentLocalIndex]}`;\n getConditionalPaths(data, innerCompDataPath, currentLocalIndex + 1);\n });\n }\n else {\n currentData.forEach((x, index) => {\n if (!lodash_1.default.isNil(x[conditionPaths[currentLocalIndex]])) {\n const compDataPath = `${currentPath}[${index}].${conditionPaths[currentLocalIndex]}`;\n conditionalPathsArray.push(compDataPath);\n }\n });\n }\n }\n else {\n if (!conditionPaths[currentGlobalIndex]) {\n return;\n }\n currentGlobalIndex = currentGlobalIndex + 1;\n getConditionalPaths(data, `${currentPath}.${conditionPaths[currentGlobalIndex - 1]}`, currentGlobalIndex);\n }\n };\n getConditionalPaths(data);\n return conditionalPathsArray;\n}\n/**\n *\n * @param component\n * @param condition\n * @param row\n * @param data\n * @param instance\n */\nfunction checkSimpleConditional(component, condition, row, data, instance) {\n if (condition.when) {\n const value = getComponentActualValue(condition.when, data, row);\n const eq = String(condition.eq);\n const show = String(condition.show);\n // Special check for selectboxes component.\n if (lodash_1.default.isObject(value) && lodash_1.default.has(value, condition.eq)) {\n return String(value[condition.eq]) === show;\n }\n // FOR-179 - Check for multiple values.\n if (Array.isArray(value) && value.map(String).includes(eq)) {\n return show === 'true';\n }\n return (String(value) === eq) === (show === 'true');\n }\n else {\n const { conditions = [], conjunction = 'all', show = true } = condition;\n if (!conditions.length) {\n return true;\n }\n const conditionsResult = lodash_1.default.map(conditions, (cond) => {\n var _a, _b;\n const { value: comparedValue, operator, component: conditionComponentPath } = cond;\n if (!conditionComponentPath) {\n return true;\n }\n const splittedConditionPath = conditionComponentPath.split('.');\n const conditionalPaths = ((_a = instance === null || instance === void 0 ? void 0 : instance.parent) === null || _a === void 0 ? void 0 : _a.type) === 'datagrid' || ((_b = instance === null || instance === void 0 ? void 0 : instance.parent) === null || _b === void 0 ? void 0 : _b.type) === 'editgrid' ? [] : getConditionalPathsRecursive(splittedConditionPath, data);\n if (conditionalPaths.length > 0) {\n return conditionalPaths.map((path) => {\n const value = getComponentActualValue(path, data, row);\n const ConditionOperator = conditionOperators_1.default[operator];\n return ConditionOperator\n ? new ConditionOperator().getResult({ value, comparedValue, instance, component, path })\n : true;\n });\n }\n else {\n const value = getComponentActualValue(conditionComponentPath, data, row);\n const СonditionOperator = conditionOperators_1.default[operator];\n return СonditionOperator\n ? new СonditionOperator().getResult({ value, comparedValue, instance, component, path: conditionComponentPath })\n : true;\n }\n });\n let result = false;\n switch (conjunction) {\n case 'any':\n result = lodash_1.default.some(conditionsResult.flat(), res => !!res);\n break;\n default:\n result = lodash_1.default.every(conditionsResult.flat(), res => !!res);\n }\n return (0, core_1.convertShowToBoolean)(show) ? result : !result;\n }\n}\nexports.checkSimpleConditional = checkSimpleConditional;\n/**\n * Returns a components normalized value.\n * @param {string} compPath - The full path to the component.\n * @param {*} data - The data object to get the value from.\n * @param {*} row - The contextual row data for the component.\n * @returns {*} - The normalized value of the component.\n */\nfunction getComponentActualValue(compPath, data, row) {\n let value = null;\n if (data) {\n value = (0, formUtils_1.getValue)({ data }, compPath);\n }\n if (row && lodash_1.default.isNil(value)) {\n value = (0, formUtils_1.getValue)({ data: row }, compPath);\n }\n // FOR-400 - Fix issue where falsey values were being evaluated as show=true\n if (lodash_1.default.isNil(value) || (lodash_1.default.isObject(value) && lodash_1.default.isEmpty(value))) {\n value = '';\n }\n return value;\n}\nexports.getComponentActualValue = getComponentActualValue;\n/**\n * Check custom javascript conditional.\n * @param {import('@formio/core').Component} component - The component to check for the conditional.\n * @param {string} custom - The custom conditional string to evaluate.\n * @param {*} row - The row data for the component.\n * @param {*} data - The full submission data.\n * @param {import('@formio/core').Form} form - The form object.\n * @param {string} variable - The variable name for the result of the custom conditional.\n * @param {*} onError - A custom return if there is an error or the value is null from the evaluation.\n * @param {import('../../src/components/_classes/component/Component').Component} instance - The component instance.\n * @returns {*} - The result of the evaulation.\n */\nfunction checkCustomConditional(component, custom, row, data, form, variable, onError, instance) {\n if (typeof custom === 'string') {\n custom = `var ${variable} = true; ${custom}; return ${variable};`;\n }\n const value = (instance && instance.evaluate) ?\n instance.evaluate(custom, { row, data, form }) :\n evaluate(custom, { row, data, form });\n if (value === null) {\n return onError;\n }\n return value;\n}\nexports.checkCustomConditional = checkCustomConditional;\n/**\n * Check a component for JSON conditionals.\n * @param {import('@formio/core').Component} component - The component\n * @param {import('@formio/core').JSONConditional} json - The json conditional to check.\n * @param {*} row - The contextual row data for the component.\n * @param {*} data - The full submission data.\n * @param {import('@formio/core').Form} form - The Form JSON of the form.\n * @param {*} onError - Custom return value if there is an error.\n * @returns {boolean} - TRUE if the condition is true; FALSE otherwise.\n */\nfunction checkJsonConditional(component, json, row, data, form, onError) {\n try {\n return core_1.jsonLogic.apply(json, {\n data,\n row,\n form,\n _: lodash_1.default,\n });\n }\n catch (err) {\n console.warn(`An error occurred in jsonLogic advanced condition for ${component.key}`, err);\n return onError;\n }\n}\nexports.checkJsonConditional = checkJsonConditional;\n/**\n * Returns the contextual row data for a component.\n * @param {import('@formio/core').Component} component - The component to get the row data for.\n * @param {*} row - The row data for the component.\n * @param {import('../../src/components/_classes/component/Component').Component} instance - The component instance.\n * @param {*} conditional - The component conditional.\n * @returns {*} - The contextual row data for the component.\n */\nfunction getRow(component, row, instance, conditional) {\n var _a, _b, _c;\n const condition = conditional || component.conditional;\n // If no component's instance passed (happens only in 6.x server), calculate its path based on the schema\n if (!instance) {\n instance = lodash_1.default.cloneDeep(component);\n }\n const dataParent = getDataParentComponent(instance);\n if (dataParent) {\n const parentPath = (_a = dataParent.paths) === null || _a === void 0 ? void 0 : _a.localDataPath;\n const isTriggerCondtionComponentPath = condition.when || !condition.conditions\n ? (_b = condition.when) === null || _b === void 0 ? void 0 : _b.startsWith((_c = dataParent.paths) === null || _c === void 0 ? void 0 : _c.localPath)\n : lodash_1.default.some(condition.conditions, cond => { var _a; return cond.component.startsWith((_a = dataParent.paths) === null || _a === void 0 ? void 0 : _a.localPath); });\n if (isTriggerCondtionComponentPath) {\n const newRow = {};\n lodash_1.default.set(newRow, parentPath, row);\n row = newRow;\n }\n }\n return row;\n}\n/**\n * Checks the conditions for a provided component and data.\n * @param {import('@formio/core').Component} component - The component to check for the condition.\n * @param {*} row - The data within a row\n * @param {*} data - The full submission data.\n * @param {import('@formio/core').Form} form - The form object.\n * @param {import('../../src/components/_classes/component/Component').Component} instance - The component instance.\n * @returns {boolean} - TRUE if the condition is true; FALSE otherwise.\n */\nfunction checkCondition(component, row, data, form, instance) {\n const { customConditional, conditional } = component;\n if (customConditional) {\n return checkCustomConditional(component, customConditional, row, data, form, 'show', true, instance);\n }\n else if (conditional && (conditional.when || lodash_1.default.some(conditional.conditions || [], condition => condition.component && condition.operator))) {\n row = getRow(component, row, instance);\n return checkSimpleConditional(component, conditional, row, data, instance);\n }\n else if (conditional && conditional.json) {\n return checkJsonConditional(component, conditional.json, row, data, form, true);\n }\n // Default to show.\n return true;\n}\nexports.checkCondition = checkCondition;\n/**\n * Test a trigger on a component.\n * @param {import('@formio/core').Component} component - The component to test the trigger against.\n * @param {import('@formio/core').LogicTrigger} trigger - The trigger configuration.\n * @param {import('@formio/core').DataObject} row - The contextual row data.\n * @param {import('@formio/core').DataObject} data - The root data object.\n * @param {import('@formio/core').Form} form - The form object.\n * @param {any} instance - The component that is performing the trigger.\n * @returns {boolean} - TRUE if the trigger should fire; FALSE otherwise.\n */\nfunction checkTrigger(component, trigger, row, data, form, instance) {\n // If trigger is empty, don't fire it\n if (!trigger || !trigger[trigger.type]) {\n return false;\n }\n switch (trigger.type) {\n case 'simple':\n row = getRow(component, row, instance, trigger.simple);\n return checkSimpleConditional(component, trigger.simple, row, data, instance);\n case 'javascript':\n return checkCustomConditional(component, trigger.javascript, row, data, form, 'result', false, instance);\n case 'json':\n return checkJsonConditional(component, trigger.json, row, data, form, false);\n }\n // If none of the types matched, don't fire the trigger.\n return false;\n}\nexports.checkTrigger = checkTrigger;\n/**\n * Sets a property on a component via an executed Logic action.\n * @param {import('@formio/core').Component} component - The component to set the property on.\n * @param {import('@formio/core').LogicAction} action - The action to perform on the component.\n * @param {string} result - The name of the variable in the evaulation to use as the result.\n * @param {import('@formio/core').DataObject} row - The contextual row data.\n * @param {import('@formio/core').DataObject} data - The full submission data.\n * @param {any} instance - The component instance.\n * @returns {import('@formio/core').Component} - The modified component.\n */\nfunction setActionProperty(component, action, result, row, data, instance) {\n const property = action.property.value;\n switch (action.property.type) {\n case 'boolean': {\n const currentValue = lodash_1.default.get(component, property, false).toString();\n const newValue = action.state.toString();\n if (currentValue !== newValue) {\n lodash_1.default.set(component, property, newValue === 'true');\n }\n break;\n }\n case 'string': {\n const evalData = {\n data,\n row,\n component,\n result,\n };\n const textValue = action.property.component ? action[action.property.component] : action.text;\n const currentValue = lodash_1.default.get(component, property, '');\n const newValue = (instance && instance.interpolate)\n ? instance.interpolate(textValue, evalData)\n : Evaluator_1.Evaluator.interpolate(textValue, evalData);\n if (newValue !== currentValue) {\n lodash_1.default.set(component, property, newValue);\n }\n break;\n }\n }\n return component;\n}\nexports.setActionProperty = setActionProperty;\n/**\n * Removes HTML tags from string e.g. <div>Hello World</div> => Hello World\n * @param {string} str - The string to remove HTML tags from.\n * @returns {string} - The string without HTML tags.\n */\nfunction removeHTML(str) {\n const doc = new window.DOMParser().parseFromString(str, 'text/html');\n return (doc.body.textContent || '').trim();\n}\nexports.removeHTML = removeHTML;\n/**\n * Unescape HTML characters like &lt, &gt, &amp and etc.\n * @param {string} str - The string to unescape.\n * @returns {string} - The unescaped string.\n */\nfunction unescapeHTML(str) {\n if (typeof window === 'undefined' || !('DOMParser' in window)) {\n return str;\n }\n const elem = document.createElement('textarea');\n elem.innerHTML = str;\n return elem.value;\n}\nexports.unescapeHTML = unescapeHTML;\n/**\n * Make HTML element from string\n * @param {string} str - The string to convert to an HTML element.\n * @param {string} selector - The selector to use to get the element once it is created.\n * @returns {HTMLElement} - The HTML element that was created.\n */\nfunction convertStringToHTMLElement(str, selector) {\n const doc = new window.DOMParser().parseFromString(str, 'text/html');\n return doc.body.querySelector(selector);\n}\nexports.convertStringToHTMLElement = convertStringToHTMLElement;\n/**\n * Make a filename guaranteed to be unique.\n * @param {string} name - The original name of the file.\n * @param {string} template - The template to use for the unique name.\n * @param {object} evalContext - The context to use for the evaluation.\n * @returns {string} - A unique filename.\n */\nfunction uniqueName(name, template, evalContext) {\n template = template || '{{fileName}}-{{guid}}';\n //include guid in template anyway, to prevent overwriting issue if filename matches existing file\n if (!template.includes('{{guid}}')) {\n template = `${template}-{{guid}}`;\n }\n const parts = name.split('.');\n let fileName = parts.slice(0, parts.length - 1).join('.');\n const extension = parts.length > 1\n ? `.${lodash_1.default.last(parts)}`\n : '';\n //allow only 100 characters from original name to avoid issues with filename length restrictions\n fileName = fileName.substr(0, 100);\n evalContext = Object.assign(evalContext || {}, {\n fileName,\n guid: guid()\n });\n //only letters, numbers, dots, dashes, underscores and spaces are allowed. Anything else will be replaced with dash\n const uniqueName = `${Evaluator_1.Evaluator.interpolate(template, evalContext)}${extension}`.replace(/[^0-9a-zA-Z.\\-_ ]/g, '-');\n return uniqueName;\n}\nexports.uniqueName = uniqueName;\n/**\n * Returns a GUID\n * @returns {string} - A GUID.\n */\nfunction guid() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0;\n const v = c === 'x'\n ? r\n : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\nexports.guid = guid;\n/**\n * Return a translated date setting.\n * @param {string|Date} date - The date to translate.\n * @returns {(null|dayjs.Dayjs)} - The translated date.\n */\nfunction getDateSetting(date) {\n if (lodash_1.default.isNil(date) || lodash_1.default.isNaN(date) || date === '') {\n return null;\n }\n if (date instanceof Date) {\n return date;\n }\n else if (typeof date.toDate === 'function') {\n return date.isValid() ? date.toDate() : null;\n }\n let dateSetting = ((typeof date !== 'string') || (date.indexOf('moment(') === -1)) ? (0, moment_timezone_1.default)(date) : null;\n if (dateSetting && dateSetting.isValid()) {\n return dateSetting.toDate();\n }\n dateSetting = null;\n try {\n const value = Evaluator_1.Evaluator.evaluator(`return ${date};`, 'moment')(moment_timezone_1.default);\n if (typeof value === 'string') {\n dateSetting = (0, dayjs_1.default)(value);\n }\n else if (typeof value.toDate === 'function') {\n dateSetting = (0, dayjs_1.default)(value.toDate().toUTCString());\n }\n else if (value instanceof Date) {\n dateSetting = (0, dayjs_1.default)(value);\n }\n }\n catch (e) {\n return null;\n }\n if (!dateSetting) {\n return null;\n }\n // Ensure this is a date.\n if (!dateSetting.isValid()) {\n return null;\n }\n return dateSetting.toDate();\n}\nexports.getDateSetting = getDateSetting;\n/**\n * Returns true if the date is a valid date. False otherwise.\n * @param {Date|string} date - The date to check for validity.\n * @returns {boolean} - TRUE if the date is valid; FALSE otherwise.\n */\nfunction isValidDate(date) {\n return lodash_1.default.isDate(date) && !lodash_1.default.isNaN(date.getDate());\n}\nexports.isValidDate = isValidDate;\n/**\n * Get the current timezone string.\n * @returns {string} - The current timezone.\n */\nfunction currentTimezone() {\n if (dayjs_1.default.currentTimezone) {\n return dayjs_1.default.currentTimezone;\n }\n dayjs_1.default.currentTimezone = jstimezonedetect_1.default.determine().name();\n return dayjs_1.default.currentTimezone;\n}\nexports.currentTimezone = currentTimezone;\n/**\n * Get an offset date provided a date object and timezone object.\n * @param {Date} date - The date to offset.\n * @param {string} timezone - The timezone to offset the date to.\n * @returns {{date: Date, abbr: string}} - The offset date.\n */\nfunction offsetDate(date, timezone) {\n if (timezone === 'UTC') {\n return {\n date: new Date(date.getTime() + (date.getTimezoneOffset() * 60000)),\n abbr: 'UTC'\n };\n }\n const dateMoment = (0, dayjs_1.default)(date).tz(timezone);\n return {\n date: new Date(date.getTime() + ((dateMoment.utcOffset() + date.getTimezoneOffset()) * 60000)),\n abbr: dateMoment.format('z')\n };\n}\nexports.offsetDate = offsetDate;\n/**\n * Returns if we should handle a timezone difference.\n * @param {string} timezone - The timezone to check if we should load the zones.\n * @returns {boolean} - TRUE if we should handle timezones; FALSE otherwise.\n */\nfunction shouldHandleTimezone(timezone) {\n return !(timezone === currentTimezone() || timezone === 'UTC');\n}\nexports.shouldHandleTimezone = shouldHandleTimezone;\n/**\n * Get the Dayjs date object for translating dates with timezones.\n * @param {string|Date} value - The value to convert into a dayjs date.\n * @param {string} format - The format to convert the date to.\n * @param {string} timezone - The timezone to convert the date to.\n * @param {object} options - The options object\n * @returns {dayjs.Dayjs} - The dayjs date object.\n */\nfunction dayjsDate(value, format, timezone, options) {\n const dayjsDate = (0, dayjs_1.default)(value);\n if (!timezone) {\n return dayjsDate;\n }\n if (timezone === 'UTC') {\n timezone = 'Etc/UTC';\n }\n if ((timezone !== currentTimezone() || (format && format.match(/\\s(z$|z\\s)/))) && (shouldHandleTimezone(timezone) || (options === null || options === void 0 ? void 0 : options.email))) {\n return dayjsDate.tz(timezone);\n }\n return dayjsDate;\n}\nexports.dayjsDate = dayjsDate;\n/**\n * Format a date provided a value, format, and timezone object.\n * @param {string|Date} value - The value to format.\n * @param {string} format - The format to format the date to.\n * @param {string} timezone - The timezone to format the date to.\n * @param {string} flatPickrInputFormat - The format to use for flatpickr input.\n * @returns {string} - The formatted date.\n */\nfunction formatDate(value, format, timezone, flatPickrInputFormat) {\n const dayjsDate = (0, dayjs_1.default)(value, flatPickrInputFormat || undefined);\n if (timezone === currentTimezone()) {\n // See if our format contains a \"z\" timezone character.\n if (format.match(/\\s(z$|z\\s)/)) {\n if (shouldHandleTimezone(timezone)) {\n return dayjsDate.tz(timezone).format(convertFormatToDayjs(format));\n }\n else {\n return dayjsDate.format(convertFormatToDayjs(format.replace(/\\s(z$|z\\s)/, '')));\n }\n }\n // Return the standard format.\n return dayjsDate.format(convertFormatToDayjs(format));\n }\n if (timezone === 'UTC') {\n const offset = offsetDate(dayjsDate.toDate(), 'UTC');\n return `${(0, dayjs_1.default)(offset.date).format(convertFormatToDayjs(format))} UTC`;\n }\n if (shouldHandleTimezone(timezone)) {\n return dayjsDate.tz(timezone).format(`${convertFormatToDayjs(format)} z`);\n }\n return dayjsDate.format(convertFormatToDayjs(format));\n}\nexports.formatDate = formatDate;\n/**\n * Pass a format function to format within a timezone.\n * @param {Function} formatFn - The format function to use.\n * @param {Date|string} date - The date to format.\n * @param {string} format - The format to format the date to.\n * @param {string} timezone - The timezone to format the date to.\n * @returns {string} - The formatted date.\n */\nfunction formatOffset(formatFn, date, format, timezone) {\n if (timezone === currentTimezone()) {\n return formatFn(date, format);\n }\n if (timezone === 'UTC') {\n return `${formatFn(offsetDate(date, 'UTC').date, format)} UTC`;\n }\n if (shouldHandleTimezone(timezone)) {\n const offset = offsetDate(date, timezone);\n return `${formatFn(offset.date, format)} ${offset.abbr}`;\n }\n else {\n return formatFn(date, format);\n }\n}\nexports.formatOffset = formatOffset;\n/**\n * Returns the local date format information.\n * @param {Intl.LocalesArgument} locale - The locale to get the date format for.\n * @returns {object} - The local date format information.\n */\nfunction getLocaleDateFormatInfo(locale) {\n const formatInfo = {};\n const day = 21;\n const exampleDate = new Date(2017, 11, day);\n const localDateString = exampleDate.toLocaleDateString(locale);\n formatInfo.dayFirst = localDateString.slice(0, 2) === day.toString();\n return formatInfo;\n}\nexports.getLocaleDateFormatInfo = getLocaleDateFormatInfo;\n/**\n * Convert the format from the angular-datepicker module to flatpickr format.\n * @param {string} format - The format to convert.\n * @returns {string} - The converted format.\n */\nfunction convertFormatToFlatpickr(format) {\n return format\n // Remove the Z timezone offset, not supported by flatpickr.\n .replace(/Z/g, '')\n // Year conversion.\n .replace(/y/g, 'Y')\n .replace('YYYY', 'Y')\n .replace('YY', 'y')\n // Month conversion.\n .replace('MMMM', 'F')\n .replace(/M/g, 'n')\n .replace('nnn', 'M')\n .replace('nn', 'm')\n // Day in month.\n .replace(/d/g, 'j')\n .replace(/jj/g, 'd')\n // Day in week.\n .replace('EEEE', 'l')\n .replace('EEE', 'D')\n // Hours, minutes, seconds\n .replace('HH', 'H')\n .replace('hh', 'G')\n .replace('mm', 'i')\n .replace('ss', 'S')\n .replace(/a/g, 'K');\n}\nexports.convertFormatToFlatpickr = convertFormatToFlatpickr;\n/**\n * Convert the format from the angular-datepicker module to moment format.\n * @param {string} format - The format to convert.\n * @returns {string} - The converted format.\n */\nfunction convertFormatToDayjs(format) {\n return format\n // Year conversion.\n .replace(/y/g, 'Y')\n // Day in month.\n .replace(/d/g, 'D')\n // Day in week.\n .replace(/E/g, 'd')\n // AM/PM marker\n .replace(/a/g, 'A')\n // Unix Timestamp\n .replace(/U/g, 'X');\n}\nexports.convertFormatToDayjs = convertFormatToDayjs;\n/**\n * Convert the format from the angular-datepicker module to mask format.\n * @param {string} format - The format to convert.\n * @returns {string} - The converted format.\n */\nfunction convertFormatToMask(format) {\n return format\n // Long month replacement.\n .replace(/M{4}/g, 'MM')\n // Initial short month conversion.\n .replace(/M{3}/g, '***')\n // Short month conversion if input as text.\n .replace(/e/g, 'Q')\n // Month number conversion.\n .replace(/W/g, '99')\n // Year conversion.\n .replace(/[ydhmswHMG]/g, '9')\n // AM/PM conversion.\n .replace(/a/g, 'AA');\n}\nexports.convertFormatToMask = convertFormatToMask;\n/**\n * Returns an input mask that is compatible with the input mask library.\n * @param {string} mask - The Form.io input mask.\n * @param {string} placeholderChar - Char which is used as a placeholder.\n * @returns {Array} - The input mask for the mask library.\n */\nfunction getInputMask(mask, placeholderChar) {\n if (mask instanceof Array) {\n return mask;\n }\n const maskArray = [];\n maskArray.numeric = true;\n for (let i = 0; i < mask.length; i++) {\n switch (mask[i]) {\n case '9':\n maskArray.push(/\\d/);\n break;\n case 'A':\n maskArray.numeric = false;\n maskArray.push(/[a-zA-Z]/);\n break;\n case 'a':\n maskArray.numeric = false;\n maskArray.push(/[a-z]/);\n break;\n case '*':\n maskArray.numeric = false;\n maskArray.push(/[a-zA-Z0-9]/);\n break;\n // If char which is used inside mask placeholder was used in the mask, replace it with space to prevent errors\n case placeholderChar:\n maskArray.numeric = false;\n maskArray.push(' ');\n break;\n default:\n maskArray.numeric = false;\n maskArray.push(mask[i]);\n break;\n }\n }\n return maskArray;\n}\nexports.getInputMask = getInputMask;\n/**\n * Unmasks a value using the provided mask and placeholder characters.\n * @param {string} value - The value to unmask.\n * @param {string} mask - The mask to use for unmasking.\n * @param {string} placeholderChar - The placeholder character to use for unmasking.\n * @returns {string} - The unmasked value.\n */\nfunction unmaskValue(value, mask, placeholderChar) {\n if (!mask || !value || value.length > mask.length) {\n return value;\n }\n let unmaskedValue = value.split('');\n for (let i = 0; i < mask.length; i++) {\n const char = value[i] || '';\n const charPart = mask[i];\n if (!lodash_1.default.isRegExp(charPart) && char === charPart) {\n unmaskedValue[i] = '';\n }\n }\n unmaskedValue = unmaskedValue.join('').replace(placeholderChar, '');\n return unmaskedValue;\n}\nexports.unmaskValue = unmaskValue;\n/**\n * Returns true if the value matches the input mask format.\n * @param {string} value - The value to check.\n * @param {string} inputMask - The input mask to check against.\n * @returns {boolean} - TRUE if the value matches the input mask; FALSE otherwise.\n */\nfunction matchInputMask(value, inputMask) {\n if (!inputMask) {\n return true;\n }\n // If value is longer than mask, it isn't valid.\n if (value.length > inputMask.length) {\n return false;\n }\n for (let i = 0; i < inputMask.length; i++) {\n const char = value[i] || '';\n const charPart = inputMask[i];\n if (!(lodash_1.default.isRegExp(charPart) && charPart.test(char) || charPart === char)) {\n return false;\n }\n }\n return true;\n}\nexports.matchInputMask = matchInputMask;\n/**\n * Returns the number separators (i.e. 1,000) for the provided language.\n * @param {string} lang - The language code to get the number separators for.\n * @returns {{delimiter: string, decimalSeparator: string}} - The number separators.\n */\nfunction getNumberSeparators(lang = 'en') {\n const formattedNumberString = (12345.6789).toLocaleString(lang);\n const delimeters = formattedNumberString.match(/..(.)...(.)../);\n if (!delimeters) {\n return {\n delimiter: ',',\n decimalSeparator: '.'\n };\n }\n return {\n delimiter: (delimeters.length > 1) ? delimeters[1] : ',',\n decimalSeparator: (delimeters.length > 2) ? delimeters[2] : '.',\n };\n}\nexports.getNumberSeparators = getNumberSeparators;\n/**\n * Returns the number for the maximum amount of decimal places for a number.\n * @param {import('@formio/core').Component} component - The component to check for decimal limits.\n * @param {number} defaultLimit - The default limit to use if none is provided in the component.\n * @returns {number} - The number of decimal places allowed.\n */\nfunction getNumberDecimalLimit(component, defaultLimit) {\n if (lodash_1.default.has(component, 'decimalLimit')) {\n return lodash_1.default.get(component, 'decimalLimit');\n }\n // Determine the decimal limit. Defaults to 20 but can be overridden by validate.step or decimalLimit settings.\n let decimalLimit = defaultLimit || 20;\n const step = lodash_1.default.get(component, 'validate.step', 'any');\n if (step !== 'any') {\n const parts = step.toString().split('.');\n if (parts.length > 1) {\n decimalLimit = parts[1].length;\n }\n }\n return decimalLimit;\n}\nexports.getNumberDecimalLimit = getNumberDecimalLimit;\n/**\n * Returns the currency affixes for a specific language.\n * @param {object} arg0 - The arguments object.\n * @param {string} arg0.currency - The currency code to get the affixes for.\n * @param {number} arg0.decimalLimit - The number of decimal places to use.\n * @param {string} arg0.decimalSeparator - The decimal separator to use.\n * @param {string} arg0.lang - The language code to use.\n * @returns {{prefix: string, suffix: string}} - The currency affixes.\n */\nfunction getCurrencyAffixes({ currency, decimalLimit, decimalSeparator, lang, }) {\n // Get the prefix and suffix from the localized string.\n let regex = `(.*)?${(100).toLocaleString(lang)}`;\n if (decimalLimit) {\n regex += `${decimalSeparator === '.' ? '\\\\.' : decimalSeparator}${(0).toLocaleString(lang)}{${decimalLimit}}`;\n }\n regex += '(.*)?';\n const parts = (100).toLocaleString(lang, {\n style: 'currency',\n currency: currency ? currency : 'USD',\n useGrouping: true,\n maximumFractionDigits: decimalLimit || 0,\n minimumFractionDigits: decimalLimit || 0\n }).replace('.', decimalSeparator).match(new RegExp(regex));\n return {\n prefix: (parts === null || parts === void 0 ? void 0 : parts[1]) || '',\n suffix: (parts === null || parts === void 0 ? void 0 : parts[2]) || ''\n };\n}\nexports.getCurrencyAffixes = getCurrencyAffixes;\n/**\n * Fetch the field data provided a component.\n * @param {import('@formio/core').DataObject} data - The data object to fetch the field data from.\n * @param {import('@formio/core').Component} component - The component to fetch the field data for.\n * @returns {*} - The field data.\n */\nfunction fieldData(data, component) {\n if (!data) {\n return '';\n }\n if (!component || !component.key) {\n return data;\n }\n if (component.key.includes('.')) {\n let value = data;\n const parts = component.key.split('.');\n let key = '';\n for (let i = 0; i < parts.length; i++) {\n key = parts[i];\n // Handle nested resources\n if (value.hasOwnProperty('_id')) {\n value = value.data;\n }\n // Return if the key is not found on the value.\n if (!value.hasOwnProperty(key)) {\n return;\n }\n // Convert old single field data in submissions to multiple\n if (key === parts[parts.length - 1] && component.multiple && !Array.isArray(value[key])) {\n value[key] = [value[key]];\n }\n // Set the value of this key.\n value = value[key];\n }\n return value;\n }\n else {\n // Convert old single field data in submissions to multiple\n if (component.multiple && !Array.isArray(data[component.key])) {\n data[component.key] = [data[component.key]];\n }\n // Fix for checkbox type radio submission values in tableView\n if (component.type === 'checkbox' && component.inputType === 'radio') {\n return data[component.name] === component.value;\n }\n return data[component.key];\n }\n}\nexports.fieldData = fieldData;\n/**\n * Delays function execution with possibility to execute function synchronously or cancel it.\n * @param {Function} fn - Function to delay\n * @param {number} delay - Delay time\n * @param {...any} args - Arguments to pass to the function\n * @returns {*} - Function to cancel the delay\n */\nfunction delay(fn, delay = 0, ...args) {\n const timer = setTimeout(fn, delay, ...args);\n /**\n *\n */\n function cancel() {\n clearTimeout(timer);\n }\n /**\n * Execute the function early.\n * @returns {*} - The result of the function.\n */\n function earlyCall() {\n cancel();\n return fn(...args);\n }\n earlyCall.timer = timer;\n earlyCall.cancel = cancel;\n return earlyCall;\n}\nexports.delay = delay;\n/**\n * Iterate the given key to make it unique.\n * @param {string} key\n * Modify the component key to be unique.\n * @returns {string}\n * The new component key.\n */\nfunction iterateKey(key) {\n if (!key.match(/(\\d+)$/)) {\n return `${key}1`;\n }\n return key.replace(/(\\d+)$/, function (suffix) {\n return Number(suffix) + 1;\n });\n}\nexports.iterateKey = iterateKey;\n/**\n * Determines a unique key within a map provided the base key.\n * @param {Record<string, string>} map - The map to check for uniqueness.\n * @param {string} base - The base path of the key.\n * @returns {string} - The unique key.\n */\nfunction uniqueKey(map, base) {\n let newKey = base;\n while (map.hasOwnProperty(newKey)) {\n newKey = iterateKey(newKey);\n }\n return newKey;\n}\nexports.uniqueKey = uniqueKey;\n/**\n * Determines the major version number of bootstrap.\n * @param {object} options - The options to check for bootstrap version.\n * @param {string} options.bootstrap - The bootstrap version to use.\n * @returns {number} - The bootstrap version.\n */\nfunction bootstrapVersion(options) {\n if (options.bootstrap) {\n return options.bootstrap;\n }\n if (window.bootstrap && window.bootstrap.Collapse) {\n return parseInt(window.bootstrap.Collapse.VERSION.split('.')[0], 10);\n }\n return 0;\n}\nexports.bootstrapVersion = bootstrapVersion;\n/**\n * Retrun provided argument.\n * If argument is a function, returns the result of a function call.\n * @param {Function|any} e - The argument to check if a function and call if so.\n * @returns {any} - Either the result of the function call (e) or e if it is not a function.\n */\nfunction unfold(e) {\n if (typeof e === 'function') {\n return e();\n }\n return e;\n}\nexports.unfold = unfold;\n/**\n * Map values through unfold and return first non-nil value.\n * @param {Array<T>} collection - The collection to map through unfold.;\n * @returns {T} - The first non-nil value.\n */\nexports.firstNonNil = lodash_1.default.flow([\n lodash_1.default.partialRight(lodash_1.default.map, unfold),\n lodash_1.default.partialRight(lodash_1.default.find, v => !lodash_1.default.isUndefined(v))\n]);\n/**\n * Create enclosed state. Returns functions to getting and cycling between states.\n * @param {*} a - initial state.\n * @param {*} b - next state.\n * @returns {Functions[]} -- [get, toggle];\n */\nfunction withSwitch(a, b) {\n let state = a;\n let next = b;\n /**\n * Returns the state of the switch.\n * @returns {*} - The current state.\n */\n function get() {\n return state;\n }\n /**\n * Toggles the state of the switch.\n */\n function toggle() {\n const prev = state;\n state = next;\n next = prev;\n }\n return [get, toggle];\n}\nexports.withSwitch = withSwitch;\n/**\n * Create a function that will call the provided function only the provided limit.\n * @param {Function} callback - The callback to call.\n * @param {object} options - The options to use.\n * @param {number} options.limit - The limit to call the callback.\n * @param {number} options.delay - The delay to wait before resetting the call count.\n * @returns {Function} - The function that will call the callback only the provided limit.\n */\nfunction observeOverload(callback, options = {}) {\n const { limit = 50, delay = 500 } = options;\n let callCount = 0;\n let timeoutID = 0;\n const reset = () => callCount = 0;\n return () => {\n if (timeoutID !== 0) {\n clearTimeout(timeoutID);\n timeoutID = 0;\n }\n timeoutID = setTimeout(reset, delay);\n callCount += 1;\n if (callCount >= limit) {\n clearTimeout(timeoutID);\n reset();\n return callback();\n }\n };\n}\nexports.observeOverload = observeOverload;\n/**\n * Returns the components that are provided within an evaluation context.\n * @param {any} context - The evaluation context to get the components from.\n * @param {boolean} excludeNested - Exclude nested components.\n * @param {Array<string>} excludedTypes - The types of components to exclude.\n * @returns {Array} - The components within the evaluation context.\n */\nfunction getContextComponents(context, excludeNested, excludedTypes = []) {\n const values = [];\n context.utils.eachComponent(context.instance.options.editForm.components, (component, path) => {\n const addToContextComponents = excludeNested ? !component.tree : true;\n if (component.key !== context.data.key && addToContextComponents && !lodash_1.default.includes(excludedTypes, component.type)) {\n values.push({\n label: `${component.label || component.key} (${path})`,\n value: path,\n });\n }\n });\n return values;\n}\nexports.getContextComponents = getContextComponents;\n/**\n * Returns the button components that are within an evaluation context.\n * @param {any} context - The evaluation context to get the components from.\n * @returns {Array} - The button components within the evaluation context.\n */\nfunction getContextButtons(context) {\n const values = [];\n context.utils.eachComponent(context.instance.options.editForm.components, (component) => {\n if (component.type === 'button') {\n values.push({\n label: `${component.key} (${component.label})`,\n value: component.key,\n });\n }\n });\n return values;\n}\nexports.getContextButtons = getContextButtons;\n// Tags that could be in text, that should be ommited or handled in a special way\nconst inTextTags = ['#text', 'A', 'B', 'EM', 'I', 'SMALL', 'STRONG', 'SUB', 'SUP', 'INS', 'DEL', 'MARK', 'CODE'];\n/**\n * Helper function for 'translateHTMLTemplate'. Translates text value of the passed html element.\n * @param {HTMLElement} elem - The element to translate.\n * @param {Function} translate - The translation function.\n * @returns {string} - Translated element template.\n */\nfunction translateElemValue(elem, translate) {\n if (!elem.innerText) {\n return elem.innerHTML;\n }\n const elemValue = elem.innerText.replace(Evaluator_1.Evaluator.templateSettings.interpolate, '').replace(/\\s\\s+/g, ' ').trim();\n const translatedValue = translate(elemValue);\n if (elemValue !== translatedValue) {\n const links = elem.innerHTML.match(/<a[^>]*>(.*?)<\\/a>/g);\n if (links && links.length) {\n if (links.length === 1 && links[0].length === elem.innerHTML.length) {\n return elem.innerHTML.replace(elemValue, translatedValue);\n }\n const translatedLinks = links.map(link => {\n const linkElem = document.createElement('a');\n linkElem.innerHTML = link;\n return translateElemValue(linkElem, translate);\n });\n return `${translatedValue} (${translatedLinks.join(', ')})`;\n }\n else {\n return elem.innerText.replace(elemValue, translatedValue);\n }\n }\n else {\n return elem.innerHTML;\n }\n}\n/**\n * Helper function for 'translateHTMLTemplate'. Goes deep through html tag children and calls function to translate their text values.\n * @param {HTMLElement} tag - The tag to translate.\n * @param {Function} translate - The translation function.\n * @returns {void}\n */\nfunction translateDeepTag(tag, translate) {\n const children = tag.children.length && [...tag.children];\n const shouldTranslateEntireContent = children && children.every(child => child.children.length === 0\n && inTextTags.some(tag => child.nodeName === tag));\n if (!children || shouldTranslateEntireContent) {\n tag.innerHTML = translateElemValue(tag, translate);\n }\n else {\n children.forEach(child => translateDeepTag(child, translate));\n }\n}\n/**\n * Translates text values in html template.\n * @param {string} template - The template to translate.\n * @param {Function} translate - The translation function.\n * @returns {string} - Html template with translated values.\n */\nfunction translateHTMLTemplate(template, translate) {\n const isHTML = /<[^>]*>/.test(template);\n if (!isHTML) {\n return translate(template);\n }\n const tempElem = document.createElement('div');\n tempElem.innerHTML = template;\n if (tempElem.innerText && tempElem.children.length) {\n translateDeepTag(tempElem, translate);\n return tempElem.innerHTML;\n }\n return template;\n}\nexports.translateHTMLTemplate = translateHTMLTemplate;\n/**\n * Sanitize an html string.\n * @param {string} string - The string to sanitize.\n * @param {any} options - The options to use for sanitization.\n * @returns {string} - The sanitized html string.\n */\nfunction sanitize(string, options) {\n if (typeof dompurify_1.default.sanitize !== 'function') {\n return string;\n }\n // Dompurify configuration\n const sanitizeOptions = {\n ADD_ATTR: ['ref', 'target'],\n USE_PROFILES: { html: true }\n };\n // Use profiles\n if (options.sanitizeConfig && options.sanitizeConfig.useProfiles) {\n Object.keys(options.sanitizeConfig.useProfiles).forEach(key => {\n sanitizeOptions.USE_PROFILES[key] = options.sanitizeConfig.useProfiles[key];\n });\n }\n // Add attrs\n if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.addAttr) && options.sanitizeConfig.addAttr.length > 0) {\n options.sanitizeConfig.addAttr.forEach((attr) => {\n sanitizeOptions.ADD_ATTR.push(attr);\n });\n }\n // Add tags\n if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.addTags) && options.sanitizeConfig.addTags.length > 0) {\n sanitizeOptions.ADD_TAGS = options.sanitizeConfig.addTags;\n }\n // Allow tags\n if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.allowedTags) && options.sanitizeConfig.allowedTags.length > 0) {\n sanitizeOptions.ALLOWED_TAGS = options.sanitizeConfig.allowedTags;\n }\n // Allow attributes\n if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.allowedAttrs) && options.sanitizeConfig.allowedAttrs.length > 0) {\n sanitizeOptions.ALLOWED_ATTR = options.sanitizeConfig.allowedAttrs;\n }\n // Allowd URI Regex\n if (options.sanitizeConfig && options.sanitizeConfig.allowedUriRegex) {\n const allowedUriRegex = options.sanitizeConfig.allowedUriRegex;\n sanitizeOptions.ALLOWED_URI_REGEXP = lodash_1.default.isString(allowedUriRegex) ? new RegExp(allowedUriRegex) : allowedUriRegex;\n }\n // Allow to extend the existing array of elements that are safe for URI-like values\n if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.addUriSafeAttr) && options.sanitizeConfig.addUriSafeAttr.length > 0) {\n sanitizeOptions.ADD_URI_SAFE_ATTR = options.sanitizeConfig.addUriSafeAttr;\n }\n return dompurify_1.default.sanitize(string, sanitizeOptions);\n}\nexports.sanitize = sanitize;\n/**\n * Fast cloneDeep for JSON objects only.\n * @param {any} obj - The object to perform a fast clone deep against.\n * @returns {any} - The cloned object.\n */\nfunction fastCloneDeep(obj) {\n return obj ? JSON.parse(JSON.stringify(obj)) : obj;\n}\nexports.fastCloneDeep = fastCloneDeep;\n/**\n * Returns if the component is an input component.\n * @param {import('@formio/core').Component} componentJson - The JSON of a component.\n * @returns {boolean} - TRUE if the component is an input component; FALSE otherwise.\n */\nfunction isInputComponent(componentJson) {\n if (componentJson.input === false || componentJson.input === true) {\n return componentJson.input;\n }\n switch (componentJson.type) {\n case 'htmlelement':\n case 'content':\n case 'columns':\n case 'fieldset':\n case 'panel':\n case 'table':\n case 'tabs':\n case 'well':\n case 'button':\n return false;\n default:\n return true;\n }\n}\nexports.isInputComponent = isInputComponent;\n/**\n * Takes a component path, and returns a component path array.\n * @param {string} pathStr - The path string to convert to an array.\n * @returns {Array<string>} - The array of paths.\n */\nfunction getArrayFromComponentPath(pathStr) {\n if (!pathStr || !lodash_1.default.isString(pathStr)) {\n if (!lodash_1.default.isArray(pathStr)) {\n return [pathStr];\n }\n return pathStr;\n }\n return pathStr.replace(/[[\\]]/g, '.')\n .replace(/\\.\\./g, '.')\n .replace(/(^\\.)|(\\.$)/g, '')\n .split('.')\n .map(part => lodash_1.default.defaultTo(lodash_1.default.toNumber(part), part));\n}\nexports.getArrayFromComponentPath = getArrayFromComponentPath;\n/**\n * Returns true if the component is a child of the parent.\n * @param {any} child - The child component to check.\n * @param {any} parent - The parent component to check.\n * @returns {boolean} - TRUE if the child is a child of the parent; FALSE otherwise.\n */\nfunction isChildOf(child, parent) {\n while (child && child.parent) {\n if (child.parent === parent) {\n return true;\n }\n child = child.parent;\n }\n return false;\n}\nexports.isChildOf = isChildOf;\n/**\n * Takes an array of component path indexes, and returns a string version of that array.\n * @param {Array<number>} path - The path array to convert to a string.\n * @returns {string} - The string version of the path.\n */\nfunction getStringFromComponentPath(path) {\n if (!lodash_1.default.isArray(path)) {\n return path;\n }\n let strPath = '';\n path.forEach((part, i) => {\n if (lodash_1.default.isNumber(part)) {\n strPath += `[${part}]`;\n }\n else {\n strPath += i === 0 ? part : `.${part}`;\n }\n });\n return strPath;\n}\nexports.getStringFromComponentPath = getStringFromComponentPath;\n/**\n * Takes a number and rounds it to the provided precision amount.\n * @param {number} number - The number to round.\n * @param {number} precision - The precision to round the number to.\n * @returns {string} - The rounded number.\n */\nfunction round(number, precision) {\n if (lodash_1.default.isNumber(number)) {\n return number.toFixed(precision);\n }\n return number.toString();\n}\nexports.round = round;\n/**\n * Check for Internet Explorer browser version\n * @returns {(number|null)} - The IE browser version or null if not IE\n */\nfunction getIEBrowserVersion() {\n const { ie, version } = getBrowserInfo();\n return ie ? version : null;\n}\nexports.getIEBrowserVersion = getIEBrowserVersion;\n/**\n * Get browser name and version (modified from 'jquery-browser-plugin')\n * @returns {object} -- {{browser name, version, isWebkit?}}\n * Possible browser names: chrome, safari, ie, edge, opera, mozilla, yabrowser\n */\nfunction getBrowserInfo() {\n const browser = {};\n if (typeof window === 'undefined') {\n return browser;\n }\n const ua = window.navigator.userAgent.toLowerCase();\n const match = /(edge|edg)\\/([\\w.]+)/.exec(ua) ||\n /(opr)[/]([\\w.]+)/.exec(ua) ||\n /(yabrowser)[ /]([\\w.]+)/.exec(ua) ||\n /(chrome)[ /]([\\w.]+)/.exec(ua) ||\n /(iemobile)[/]([\\w.]+)/.exec(ua) ||\n /(version)(applewebkit)[ /]([\\w.]+).*(safari)[ /]([\\w.]+)/.exec(ua) ||\n /(webkit)[ /]([\\w.]+).*(version)[ /]([\\w.]+).*(safari)[ /]([\\w.]+)/.exec(ua) ||\n /(webkit)[ /]([\\w.]+)/.exec(ua) ||\n /(opera)(?:.*version|)[ /]([\\w.]+)/.exec(ua) ||\n /(msie) ([\\w.]+)/.exec(ua) ||\n ua.indexOf('trident') >= 0 && /(rv)(?::| )([\\w.]+)/.exec(ua) ||\n ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec(ua) ||\n [];\n const matched = {\n browser: match[5] || match[3] || match[1] || '',\n version: match[4] || match[2] || '0'\n };\n if (matched.browser) {\n browser[matched.browser] = true;\n browser.version = parseInt(matched.version, 10);\n }\n // Chrome, Opera 15+, Safari and Yandex.Browser are webkit based browsers\n if (browser.chrome || browser.opr || browser.safari || browser.edg || browser.yabrowser) {\n browser.isWebkit = true;\n }\n // IE11 has a new token so we will assign it ie to avoid breaking changes\n if (browser.rv || browser.iemobile) {\n browser.ie = true;\n }\n // Edge has a new token since it became webkit based\n if (browser.edg) {\n browser.edge = true;\n }\n // Opera 15+ are identified as opr\n if (browser.opr) {\n browser.opera = true;\n }\n return browser;\n}\nexports.getBrowserInfo = getBrowserInfo;\n/**\n * Takes a component path, which may include array indicies (i.e. [0][1]), and returns the compoennt path without the indicies.\n * @param {string} path - The path to remove the indicies from.\n * @returns {string} - The path without the indicies.\n */\nfunction getComponentPathWithoutIndicies(path = '') {\n return path.replace(/\\[\\d+\\]/, '');\n}\nexports.getComponentPathWithoutIndicies = getComponentPathWithoutIndicies;\n/**\n * Returns a path to the component which based on its schema\n * @param {import('@formio/core').Component} component - Component containing link to its parent's schema in the 'parent' property\n * @returns {string} - Path to the component\n */\nfunction getComponentPath(component) {\n return component.paths.localDataPath;\n}\nexports.getComponentPath = getComponentPath;\n/**\n * Returns a parent component of the passed component instance skipping all the Layout components\n * @param {Component} componentInstance - The component to check for the parent.\n * @returns {Component|undefined} - The parent data component.\n */\nfunction getDataParentComponent(componentInstance) {\n if (!componentInstance) {\n return;\n }\n const { parent } = componentInstance;\n if (parent && (parent.isInputComponent || parent.input)) {\n return parent;\n }\n else {\n return getDataParentComponent(parent);\n }\n}\nexports.getDataParentComponent = getDataParentComponent;\n/**\n * Returns whether the value is a promise\n * @param {any} value - The value to check\n * @returns {boolean} - TRUE if the value is a promise; FALSE otherwise\n */\nfunction isPromise(value) {\n return value\n && value.then\n && typeof value.then === 'function'\n && Object.prototype.toString.call(value) === '[object Promise]';\n}\nexports.isPromise = isPromise;\n/**\n * Returns all the focusable elements within the provided dom element.\n * @param {HTMLElement} element - The element to get the focusable elements from.\n * @returns {NodeList<HTMLElement>} - The focusable elements within the provided element.\n */\nfunction getFocusableElements(element) {\n const focusableSelector = `button:not([disabled]), input:not([disabled]), select:not([disabled]),\n textarea:not([disabled]), button:not([disabled]), [href]`;\n return element.querySelectorAll(focusableSelector);\n}\nexports.getFocusableElements = getFocusableElements;\nexports.componentValueTypes = {\n number: 'number',\n string: 'string',\n boolean: 'boolean',\n array: 'array',\n object: 'object',\n date: 'date',\n any: 'any',\n};\n/**\n * Returns the saved types for the component\n * @param {import('@formio/core').Component} fullSchema - The component schema\n * @returns {Array<string>|null} - The saved types for the component\n */\nfunction getComponentSavedTypes(fullSchema) {\n const schema = fullSchema || {};\n if (schema.persistent !== true) {\n return [];\n }\n if (schema.multiple) {\n return [exports.componentValueTypes.array];\n }\n return null;\n}\nexports.getComponentSavedTypes = getComponentSavedTypes;\n/**\n * Interpolates @formio/core errors so that they are compatible with the renderer\n * @param {Component} component - The component to interpolate the errors for\n * @param {FieldError[]} errors - The errors to interpolate\n * @param {Function} interpolateFn - The interpolation function\n * @returns {[]} - The interpolated errors\n */\nconst interpolateErrors = (component, errors, interpolateFn) => {\n return errors.map((error) => {\n error.component = component;\n const { errorKeyOrMessage, context } = error;\n const toInterpolate = component.errors && component.errors[errorKeyOrMessage] ? component.errors[errorKeyOrMessage] : errorKeyOrMessage;\n return Object.assign(Object.assign({}, error), { message: unescapeHTML(interpolateFn(toInterpolate, context)), context: Object.assign({}, context) });\n });\n};\nexports.interpolateErrors = interpolateErrors;\n/**\n * Checks if a string has timezone information encoded in it\n * Example: 2024-01-01T00:00:00Z -> true\n * Example: 2024-01-01T00:00:00+03:00 -> true\n * Example: 2011-05-03T00:00:00 -> false\n * @param {string} value the string value to check\n * @returns {boolean} if value has encoded timezone\n */\nfunction hasEncodedTimezone(value) {\n if (typeof value !== 'string') {\n return false;\n }\n return (value.substring(value.length - 1) === 'z' || value.substring(value.length - 1) === 'Z' || value.match(/[+|-][0-9]{2}:[0-9]{2}$/));\n}\nexports.hasEncodedTimezone = hasEncodedTimezone;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/utils/utils.js?");
6099
+ eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.translateHTMLTemplate = exports.getContextButtons = exports.getContextComponents = exports.observeOverload = exports.withSwitch = exports.firstNonNil = exports.unfold = exports.bootstrapVersion = exports.uniqueKey = exports.iterateKey = exports.delay = exports.fieldData = exports.getCurrencyAffixes = exports.getNumberDecimalLimit = exports.getNumberSeparators = exports.matchInputMask = exports.unmaskValue = exports.getInputMask = exports.convertFormatToMask = exports.convertFormatToDayjs = exports.convertFormatToFlatpickr = exports.getLocaleDateFormatInfo = exports.formatOffset = exports.formatDate = exports.dayjsDate = exports.shouldHandleTimezone = exports.offsetDate = exports.currentTimezone = exports.isValidDate = exports.getDateSetting = exports.guid = exports.uniqueName = exports.convertStringToHTMLElement = exports.unescapeHTML = exports.removeHTML = exports.setActionProperty = exports.checkTrigger = exports.checkCondition = exports.checkJsonConditional = exports.checkCustomConditional = exports.getComponentActualValue = exports.checkSimpleConditional = exports.checkCalculated = exports.isMongoId = exports.boolValue = exports.getScriptPlugin = exports.getElementRect = exports.getPropertyValue = exports.getRandomComponentId = exports.evaluate = void 0;\nexports.hasEncodedTimezone = exports.interpolateErrors = exports.getComponentSavedTypes = exports.componentValueTypes = exports.getFocusableElements = exports.isPromise = exports.getDataParentComponent = exports.getComponentPath = exports.getComponentPathWithoutIndicies = exports.getBrowserInfo = exports.getIEBrowserVersion = exports.round = exports.getStringFromComponentPath = exports.isChildOf = exports.getArrayFromComponentPath = exports.isInputComponent = exports.fastCloneDeep = exports.sanitize = void 0;\n/* global jQuery */\nconst lodash_1 = __importDefault(__webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\"));\nconst moment_timezone_1 = __importDefault(__webpack_require__(/*! moment-timezone/moment-timezone */ \"./node_modules/moment-timezone/moment-timezone.js\"));\nconst jstimezonedetect_1 = __importDefault(__webpack_require__(/*! jstimezonedetect */ \"./node_modules/jstimezonedetect/dist/jstz.min.js\"));\nconst dompurify_1 = __importDefault(__webpack_require__(/*! dompurify */ \"./node_modules/dompurify/dist/purify.cjs.js\"));\nconst dayjs_1 = __importDefault(__webpack_require__(/*! dayjs */ \"./node_modules/dayjs/dayjs.min.js\"));\nconst utc_1 = __importDefault(__webpack_require__(/*! dayjs/plugin/utc */ \"./node_modules/dayjs/plugin/utc.js\"));\nconst timezone_1 = __importDefault(__webpack_require__(/*! dayjs/plugin/timezone */ \"./node_modules/dayjs/plugin/timezone.js\"));\nconst advancedFormat_1 = __importDefault(__webpack_require__(/*! dayjs/plugin/advancedFormat */ \"./node_modules/dayjs/plugin/advancedFormat.js\"));\nconst core_1 = __webpack_require__(/*! @formio/core */ \"./node_modules/@formio/core/lib/index.js\");\nconst formUtils_1 = __webpack_require__(/*! ./formUtils */ \"./lib/cjs/utils/formUtils.js\");\nconst Evaluator_1 = __webpack_require__(/*! ./Evaluator */ \"./lib/cjs/utils/Evaluator.js\");\nconst conditionOperators_1 = __importDefault(__webpack_require__(/*! ./conditionOperators */ \"./lib/cjs/utils/conditionOperators/index.js\"));\ndayjs_1.default.extend(timezone_1.default);\ndayjs_1.default.extend(advancedFormat_1.default);\ndayjs_1.default.extend(utc_1.default);\n/**\n * Evaluate a method.\n * @param {Function|string|object} func - The function to evaluate.\n * @param {*} args - A map of arguments to pass to the function.\n * @param {string} ret - The name of the \"return\" variable in the script.\n * @param {boolean} interpolate - True if the script should be interpolated before being executed.\n * @param {import('@formio/core').EvaluatorOptions} options - The evaluator options.\n * @returns {*} - The result of the evaluation.\n */\nfunction evaluate(func, args, ret, interpolate, options = {}) {\n return Evaluator_1.Evaluator.evaluate(func, args, ret, interpolate, undefined, options);\n}\nexports.evaluate = evaluate;\n/**\n * Returns a random compoennt ID.\n * @returns {string} - A random component ID.\n */\nfunction getRandomComponentId() {\n return `e${Math.random().toString(36).substring(7)}`;\n}\nexports.getRandomComponentId = getRandomComponentId;\n/**\n * Get a property value of an element.\n * @param {CSSStyleDeclaration} style - The style element to get the property value from.\n * @param {string} prop - The property to get the value for.\n * @returns {number} - The value of the property.\n */\nfunction getPropertyValue(style, prop) {\n let value = style.getPropertyValue(prop);\n value = value ? value.replace(/[^0-9.]/g, '') : '0';\n return parseFloat(value);\n}\nexports.getPropertyValue = getPropertyValue;\n/**\n * Get an elements bounding rectagle.\n * @param {HTMLElement} element - A DOM element to get the bounding rectangle for.\n * @returns {{x: number, y: number, width: number, height: number}} - The bounding rectangle.\n */\nfunction getElementRect(element) {\n const style = window.getComputedStyle(element, null);\n return {\n x: getPropertyValue(style, 'left'),\n y: getPropertyValue(style, 'top'),\n width: getPropertyValue(style, 'width'),\n height: getPropertyValue(style, 'height')\n };\n}\nexports.getElementRect = getElementRect;\n/**\n * Get non HTMLElement property in the window object\n * @param {string} property - The window property to fetch the script plugin from.\n * @returns {any | undefined} - The HTML Element property on the window object.\n */\nfunction getScriptPlugin(property) {\n const obj = window[property];\n if (typeof HTMLElement === 'object' ? obj instanceof HTMLElement : //DOM2\n obj && typeof obj === 'object' && true && obj.nodeType === 1 && typeof obj.nodeName === 'string') {\n return undefined;\n }\n return obj;\n}\nexports.getScriptPlugin = getScriptPlugin;\n/**\n * Determines the boolean value of a setting.\n * @param {string|boolean} value - A string or boolean value to convert to boolean.\n * @returns {boolean} - The boolean value of the setting.\n */\nfunction boolValue(value) {\n if (lodash_1.default.isBoolean(value)) {\n return value;\n }\n else if (lodash_1.default.isString(value)) {\n return (value.toLowerCase() === 'true');\n }\n else {\n return !!value;\n }\n}\nexports.boolValue = boolValue;\n/**\n * Check to see if an ID is a mongoID.\n * @param {string} text - The text to check if it is a mongoID.\n * @returns {boolean} - TRUE if the text is a mongoID; FALSE otherwise.\n */\nfunction isMongoId(text) {\n return !!text.toString().match(/^[0-9a-fA-F]{24}$/);\n}\nexports.isMongoId = isMongoId;\n/**\n * Checks the calculated value for a provided component and data.\n * @param {import('@formio/core').Component} component - The component to check for the calculated value.\n * @param {import('@formio/core').Submission} submission - A submission object.\n * @param {*} rowData - The contextual row data for the component.\n */\nfunction checkCalculated(component, submission, rowData) {\n // Process calculated value stuff if present.\n if (component.calculateValue) {\n lodash_1.default.set(rowData, component.key, evaluate(component.calculateValue, {\n value: undefined,\n data: submission ? submission.data : rowData,\n row: rowData,\n util: this,\n component\n }, 'value'));\n }\n}\nexports.checkCalculated = checkCalculated;\n/**\n * Check if a simple conditional evaluates to true.\n * @param {import('@formio/core').Component} component - The component to check for the conditional.\n * @param {import('@formio/core').SimpleConditional} condition - The condition to check.\n * @param {*} row - The row data for the component.\n * @param {*} data - The full submission data.\n * @param {import('../../src/components/_classes/component/Component').Component} instance - The instance of the component.\n * @returns {boolean} - TRUE if the condition is true; FALSE otherwise.\n */\n/**\n *\n * @param conditionPaths\n * @param data\n */\nfunction getConditionalPathsRecursive(conditionPaths, data) {\n let currentGlobalIndex = 0;\n const conditionalPathsArray = [];\n const getConditionalPaths = (data, currentPath = '', localIndex = 0) => {\n currentPath = currentPath.replace(/^\\.+|\\.+$/g, '');\n const currentLocalIndex = localIndex;\n const currentData = lodash_1.default.get(data, currentPath);\n if (Array.isArray(currentData) && currentData.filter(Boolean).length > 0) {\n if (currentData.some(element => typeof element !== 'object')) {\n return;\n }\n const hasInnerDataArray = currentData.find(x => Array.isArray(x[conditionPaths[currentLocalIndex]]));\n if (hasInnerDataArray) {\n currentData.forEach((_, indexOutside) => {\n const innerCompDataPath = `${currentPath}[${indexOutside}].${conditionPaths[currentLocalIndex]}`;\n getConditionalPaths(data, innerCompDataPath, currentLocalIndex + 1);\n });\n }\n else {\n currentData.forEach((x, index) => {\n if (!lodash_1.default.isNil(x[conditionPaths[currentLocalIndex]])) {\n const compDataPath = `${currentPath}[${index}].${conditionPaths[currentLocalIndex]}`;\n conditionalPathsArray.push(compDataPath);\n }\n });\n }\n }\n else {\n if (!conditionPaths[currentGlobalIndex]) {\n return;\n }\n currentGlobalIndex = currentGlobalIndex + 1;\n getConditionalPaths(data, `${currentPath}.${conditionPaths[currentGlobalIndex - 1]}`, currentGlobalIndex);\n }\n };\n getConditionalPaths(data);\n return conditionalPathsArray;\n}\n/**\n *\n * @param component\n * @param condition\n * @param row\n * @param data\n * @param instance\n */\nfunction checkSimpleConditional(component, condition, row, data, instance) {\n if (condition.when) {\n const value = getComponentActualValue(condition.when, data, row);\n const eq = String(condition.eq);\n const show = String(condition.show);\n // Special check for selectboxes component.\n if (lodash_1.default.isObject(value) && lodash_1.default.has(value, condition.eq)) {\n return String(value[condition.eq]) === show;\n }\n // FOR-179 - Check for multiple values.\n if (Array.isArray(value) && value.map(String).includes(eq)) {\n return show === 'true';\n }\n return (String(value) === eq) === (show === 'true');\n }\n else {\n const { conditions = [], conjunction = 'all', show = true } = condition;\n if (!conditions.length) {\n return true;\n }\n const conditionsResult = lodash_1.default.map(conditions, (cond) => {\n const { value: comparedValue, operator, component: conditionComponentPath } = cond;\n if (!conditionComponentPath) {\n return true;\n }\n const splittedConditionPath = conditionComponentPath.split('.');\n const checkParentTypeInTree = (instance, componentType) => {\n if (!(instance === null || instance === void 0 ? void 0 : instance.parent)) {\n return false;\n }\n return (instance === null || instance === void 0 ? void 0 : instance.parent.type) === componentType || checkParentTypeInTree(instance.parent, componentType);\n };\n const conditionalPaths = checkParentTypeInTree(instance, 'datagrid') || checkParentTypeInTree(instance, 'editgrid')\n ? []\n : getConditionalPathsRecursive(splittedConditionPath, data);\n if (conditionalPaths.length > 0) {\n return conditionalPaths.map((path) => {\n const value = getComponentActualValue(path, data, row);\n const ConditionOperator = conditionOperators_1.default[operator];\n return ConditionOperator\n ? new ConditionOperator().getResult({ value, comparedValue, instance, component, path })\n : true;\n });\n }\n else {\n const value = getComponentActualValue(conditionComponentPath, data, row);\n const СonditionOperator = conditionOperators_1.default[operator];\n return СonditionOperator\n ? new СonditionOperator().getResult({ value, comparedValue, instance, component, path: conditionComponentPath })\n : true;\n }\n });\n let result = false;\n switch (conjunction) {\n case 'any':\n result = lodash_1.default.some(conditionsResult.flat(), res => !!res);\n break;\n default:\n result = lodash_1.default.every(conditionsResult.flat(), res => !!res);\n }\n return (0, core_1.convertShowToBoolean)(show) ? result : !result;\n }\n}\nexports.checkSimpleConditional = checkSimpleConditional;\n/**\n * Returns a components normalized value.\n * @param {string} compPath - The full path to the component.\n * @param {*} data - The data object to get the value from.\n * @param {*} row - The contextual row data for the component.\n * @returns {*} - The normalized value of the component.\n */\nfunction getComponentActualValue(compPath, data, row) {\n let value = null;\n if (data) {\n value = (0, formUtils_1.getValue)({ data }, compPath);\n }\n if (row && lodash_1.default.isNil(value)) {\n value = (0, formUtils_1.getValue)({ data: row }, compPath);\n }\n // FOR-400 - Fix issue where falsey values were being evaluated as show=true\n if (lodash_1.default.isNil(value) || (lodash_1.default.isObject(value) && lodash_1.default.isEmpty(value))) {\n value = '';\n }\n return value;\n}\nexports.getComponentActualValue = getComponentActualValue;\n/**\n * Check custom javascript conditional.\n * @param {import('@formio/core').Component} component - The component to check for the conditional.\n * @param {string} custom - The custom conditional string to evaluate.\n * @param {*} row - The row data for the component.\n * @param {*} data - The full submission data.\n * @param {import('@formio/core').Form} form - The form object.\n * @param {string} variable - The variable name for the result of the custom conditional.\n * @param {*} onError - A custom return if there is an error or the value is null from the evaluation.\n * @param {import('../../src/components/_classes/component/Component').Component} instance - The component instance.\n * @returns {*} - The result of the evaulation.\n */\nfunction checkCustomConditional(component, custom, row, data, form, variable, onError, instance) {\n if (typeof custom === 'string') {\n custom = `var ${variable} = true; ${custom}; return ${variable};`;\n }\n const value = (instance && instance.evaluate) ?\n instance.evaluate(custom, { row, data, form }) :\n evaluate(custom, { row, data, form });\n if (value === null) {\n return onError;\n }\n return value;\n}\nexports.checkCustomConditional = checkCustomConditional;\n/**\n * Check a component for JSON conditionals.\n * @param {import('@formio/core').Component} component - The component\n * @param {import('@formio/core').JSONConditional} json - The json conditional to check.\n * @param {*} row - The contextual row data for the component.\n * @param {*} data - The full submission data.\n * @param {import('@formio/core').Form} form - The Form JSON of the form.\n * @param {*} onError - Custom return value if there is an error.\n * @returns {boolean} - TRUE if the condition is true; FALSE otherwise.\n */\nfunction checkJsonConditional(component, json, row, data, form, onError) {\n try {\n return core_1.jsonLogic.apply(json, {\n data,\n row,\n form,\n _: lodash_1.default,\n });\n }\n catch (err) {\n console.warn(`An error occurred in jsonLogic advanced condition for ${component.key}`, err);\n return onError;\n }\n}\nexports.checkJsonConditional = checkJsonConditional;\n/**\n * Returns the contextual row data for a component.\n * @param {import('@formio/core').Component} component - The component to get the row data for.\n * @param {*} row - The row data for the component.\n * @param {import('../../src/components/_classes/component/Component').Component} instance - The component instance.\n * @param {*} conditional - The component conditional.\n * @returns {*} - The contextual row data for the component.\n */\nfunction getRow(component, row, instance, conditional) {\n var _a, _b, _c;\n const condition = conditional || component.conditional;\n // If no component's instance passed (happens only in 6.x server), calculate its path based on the schema\n if (!instance) {\n instance = lodash_1.default.cloneDeep(component);\n }\n const dataParent = getDataParentComponent(instance);\n if (dataParent) {\n const parentPath = (_a = dataParent.paths) === null || _a === void 0 ? void 0 : _a.localPath;\n const isTriggerCondtionComponentPath = condition.when || !condition.conditions\n ? (_b = condition.when) === null || _b === void 0 ? void 0 : _b.startsWith((_c = dataParent.paths) === null || _c === void 0 ? void 0 : _c.localPath)\n : lodash_1.default.some(condition.conditions, cond => { var _a; return cond.component.startsWith((_a = dataParent.paths) === null || _a === void 0 ? void 0 : _a.localPath); });\n if (isTriggerCondtionComponentPath) {\n const newRow = {};\n lodash_1.default.set(newRow, parentPath, row);\n row = newRow;\n }\n }\n return row;\n}\n/**\n * Checks the conditions for a provided component and data.\n * @param {import('@formio/core').Component} component - The component to check for the condition.\n * @param {*} row - The data within a row\n * @param {*} data - The full submission data.\n * @param {import('@formio/core').Form} form - The form object.\n * @param {import('../../src/components/_classes/component/Component').Component} instance - The component instance.\n * @returns {boolean} - TRUE if the condition is true; FALSE otherwise.\n */\nfunction checkCondition(component, row, data, form, instance) {\n const { customConditional, conditional } = component;\n if (customConditional) {\n return checkCustomConditional(component, customConditional, row, data, form, 'show', true, instance);\n }\n else if (conditional && (conditional.when || lodash_1.default.some(conditional.conditions || [], condition => condition.component && condition.operator))) {\n row = getRow(component, row, instance);\n return checkSimpleConditional(component, conditional, row, data, instance);\n }\n else if (conditional && conditional.json) {\n return checkJsonConditional(component, conditional.json, row, data, form, true);\n }\n // Default to show.\n return true;\n}\nexports.checkCondition = checkCondition;\n/**\n * Test a trigger on a component.\n * @param {import('@formio/core').Component} component - The component to test the trigger against.\n * @param {import('@formio/core').LogicTrigger} trigger - The trigger configuration.\n * @param {import('@formio/core').DataObject} row - The contextual row data.\n * @param {import('@formio/core').DataObject} data - The root data object.\n * @param {import('@formio/core').Form} form - The form object.\n * @param {any} instance - The component that is performing the trigger.\n * @returns {boolean} - TRUE if the trigger should fire; FALSE otherwise.\n */\nfunction checkTrigger(component, trigger, row, data, form, instance) {\n // If trigger is empty, don't fire it\n if (!trigger || !trigger[trigger.type]) {\n return false;\n }\n switch (trigger.type) {\n case 'simple':\n row = getRow(component, row, instance, trigger.simple);\n return checkSimpleConditional(component, trigger.simple, row, data, instance);\n case 'javascript':\n return checkCustomConditional(component, trigger.javascript, row, data, form, 'result', false, instance);\n case 'json':\n return checkJsonConditional(component, trigger.json, row, data, form, false);\n }\n // If none of the types matched, don't fire the trigger.\n return false;\n}\nexports.checkTrigger = checkTrigger;\n/**\n * Sets a property on a component via an executed Logic action.\n * @param {import('@formio/core').Component} component - The component to set the property on.\n * @param {import('@formio/core').LogicAction} action - The action to perform on the component.\n * @param {string} result - The name of the variable in the evaulation to use as the result.\n * @param {import('@formio/core').DataObject} row - The contextual row data.\n * @param {import('@formio/core').DataObject} data - The full submission data.\n * @param {any} instance - The component instance.\n * @returns {import('@formio/core').Component} - The modified component.\n */\nfunction setActionProperty(component, action, result, row, data, instance) {\n const property = action.property.value;\n switch (action.property.type) {\n case 'boolean': {\n const currentValue = lodash_1.default.get(component, property, false).toString();\n const newValue = action.state.toString();\n if (currentValue !== newValue) {\n lodash_1.default.set(component, property, newValue === 'true');\n }\n break;\n }\n case 'string': {\n const evalData = {\n data,\n row,\n component,\n result,\n };\n const textValue = action.property.component ? action[action.property.component] : action.text;\n const currentValue = lodash_1.default.get(component, property, '');\n const newValue = (instance && instance.interpolate)\n ? instance.interpolate(textValue, evalData)\n : Evaluator_1.Evaluator.interpolate(textValue, evalData);\n if (newValue !== currentValue) {\n lodash_1.default.set(component, property, newValue);\n }\n break;\n }\n }\n return component;\n}\nexports.setActionProperty = setActionProperty;\n/**\n * Removes HTML tags from string e.g. <div>Hello World</div> => Hello World\n * @param {string} str - The string to remove HTML tags from.\n * @returns {string} - The string without HTML tags.\n */\nfunction removeHTML(str) {\n const doc = new window.DOMParser().parseFromString(str, 'text/html');\n return (doc.body.textContent || '').trim();\n}\nexports.removeHTML = removeHTML;\n/**\n * Unescape HTML characters like &lt, &gt, &amp and etc.\n * @param {string} str - The string to unescape.\n * @returns {string} - The unescaped string.\n */\nfunction unescapeHTML(str) {\n if (typeof window === 'undefined' || !('DOMParser' in window)) {\n return str;\n }\n const elem = document.createElement('textarea');\n elem.innerHTML = str;\n return elem.value;\n}\nexports.unescapeHTML = unescapeHTML;\n/**\n * Make HTML element from string\n * @param {string} str - The string to convert to an HTML element.\n * @param {string} selector - The selector to use to get the element once it is created.\n * @returns {HTMLElement} - The HTML element that was created.\n */\nfunction convertStringToHTMLElement(str, selector) {\n const doc = new window.DOMParser().parseFromString(str, 'text/html');\n return doc.body.querySelector(selector);\n}\nexports.convertStringToHTMLElement = convertStringToHTMLElement;\n/**\n * Make a filename guaranteed to be unique.\n * @param {string} name - The original name of the file.\n * @param {string} template - The template to use for the unique name.\n * @param {object} evalContext - The context to use for the evaluation.\n * @returns {string} - A unique filename.\n */\nfunction uniqueName(name, template, evalContext) {\n template = template || '{{fileName}}-{{guid}}';\n //include guid in template anyway, to prevent overwriting issue if filename matches existing file\n if (!template.includes('{{guid}}')) {\n template = `${template}-{{guid}}`;\n }\n const parts = name.split('.');\n let fileName = parts.slice(0, parts.length - 1).join('.');\n const extension = parts.length > 1\n ? `.${lodash_1.default.last(parts)}`\n : '';\n //allow only 100 characters from original name to avoid issues with filename length restrictions\n fileName = fileName.substr(0, 100);\n evalContext = Object.assign(evalContext || {}, {\n fileName,\n guid: guid()\n });\n //only letters, numbers, dots, dashes, underscores and spaces are allowed. Anything else will be replaced with dash\n const uniqueName = `${Evaluator_1.Evaluator.interpolate(template, evalContext)}${extension}`.replace(/[^0-9a-zA-Z.\\-_ ]/g, '-');\n return uniqueName;\n}\nexports.uniqueName = uniqueName;\n/**\n * Returns a GUID\n * @returns {string} - A GUID.\n */\nfunction guid() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0;\n const v = c === 'x'\n ? r\n : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\nexports.guid = guid;\n/**\n * Return a translated date setting.\n * @param {string|Date} date - The date to translate.\n * @returns {(null|dayjs.Dayjs)} - The translated date.\n */\nfunction getDateSetting(date) {\n if (lodash_1.default.isNil(date) || lodash_1.default.isNaN(date) || date === '') {\n return null;\n }\n if (date instanceof Date) {\n return date;\n }\n else if (typeof date.toDate === 'function') {\n return date.isValid() ? date.toDate() : null;\n }\n let dateSetting = ((typeof date !== 'string') || (date.indexOf('moment(') === -1)) ? (0, moment_timezone_1.default)(date) : null;\n if (dateSetting && dateSetting.isValid()) {\n return dateSetting.toDate();\n }\n dateSetting = null;\n try {\n const value = Evaluator_1.Evaluator.evaluator(`return ${date};`, 'moment')(moment_timezone_1.default);\n if (typeof value === 'string') {\n dateSetting = (0, dayjs_1.default)(value);\n }\n else if (typeof value.toDate === 'function') {\n dateSetting = (0, dayjs_1.default)(value.toDate().toUTCString());\n }\n else if (value instanceof Date) {\n dateSetting = (0, dayjs_1.default)(value);\n }\n }\n catch (e) {\n return null;\n }\n if (!dateSetting) {\n return null;\n }\n // Ensure this is a date.\n if (!dateSetting.isValid()) {\n return null;\n }\n return dateSetting.toDate();\n}\nexports.getDateSetting = getDateSetting;\n/**\n * Returns true if the date is a valid date. False otherwise.\n * @param {Date|string} date - The date to check for validity.\n * @returns {boolean} - TRUE if the date is valid; FALSE otherwise.\n */\nfunction isValidDate(date) {\n return lodash_1.default.isDate(date) && !lodash_1.default.isNaN(date.getDate());\n}\nexports.isValidDate = isValidDate;\n/**\n * Get the current timezone string.\n * @returns {string} - The current timezone.\n */\nfunction currentTimezone() {\n if (dayjs_1.default.currentTimezone) {\n return dayjs_1.default.currentTimezone;\n }\n dayjs_1.default.currentTimezone = jstimezonedetect_1.default.determine().name();\n return dayjs_1.default.currentTimezone;\n}\nexports.currentTimezone = currentTimezone;\n/**\n * Get an offset date provided a date object and timezone object.\n * @param {Date} date - The date to offset.\n * @param {string} timezone - The timezone to offset the date to.\n * @returns {{date: Date, abbr: string}} - The offset date.\n */\nfunction offsetDate(date, timezone) {\n if (timezone === 'UTC') {\n return {\n date: new Date(date.getTime() + (date.getTimezoneOffset() * 60000)),\n abbr: 'UTC'\n };\n }\n const dateMoment = (0, dayjs_1.default)(date).tz(timezone);\n return {\n date: new Date(date.getTime() + ((dateMoment.utcOffset() + date.getTimezoneOffset()) * 60000)),\n abbr: dateMoment.format('z')\n };\n}\nexports.offsetDate = offsetDate;\n/**\n * Returns if we should handle a timezone difference.\n * @param {string} timezone - The timezone to check if we should load the zones.\n * @returns {boolean} - TRUE if we should handle timezones; FALSE otherwise.\n */\nfunction shouldHandleTimezone(timezone) {\n return !(timezone === currentTimezone() || timezone === 'UTC');\n}\nexports.shouldHandleTimezone = shouldHandleTimezone;\n/**\n * Get the Dayjs date object for translating dates with timezones.\n * @param {string|Date} value - The value to convert into a dayjs date.\n * @param {string} format - The format to convert the date to.\n * @param {string} timezone - The timezone to convert the date to.\n * @param {object} options - The options object\n * @returns {dayjs.Dayjs} - The dayjs date object.\n */\nfunction dayjsDate(value, format, timezone, options) {\n const dayjsDate = (0, dayjs_1.default)(value);\n if (!timezone) {\n return dayjsDate;\n }\n if (timezone === 'UTC') {\n timezone = 'Etc/UTC';\n }\n if ((timezone !== currentTimezone() || (format && format.match(/\\s(z$|z\\s)/))) && (shouldHandleTimezone(timezone) || (options === null || options === void 0 ? void 0 : options.email))) {\n return dayjsDate.tz(timezone);\n }\n return dayjsDate;\n}\nexports.dayjsDate = dayjsDate;\n/**\n * Format a date provided a value, format, and timezone object.\n * @param {string|Date} value - The value to format.\n * @param {string} format - The format to format the date to.\n * @param {string} timezone - The timezone to format the date to.\n * @param {string} flatPickrInputFormat - The format to use for flatpickr input.\n * @returns {string} - The formatted date.\n */\nfunction formatDate(value, format, timezone, flatPickrInputFormat) {\n const dayjsDate = (0, dayjs_1.default)(value, flatPickrInputFormat || undefined);\n if (timezone === currentTimezone()) {\n // See if our format contains a \"z\" timezone character.\n if (format.match(/\\s(z$|z\\s)/)) {\n if (shouldHandleTimezone(timezone)) {\n return dayjsDate.tz(timezone).format(convertFormatToDayjs(format));\n }\n else {\n return dayjsDate.format(convertFormatToDayjs(format.replace(/\\s(z$|z\\s)/, '')));\n }\n }\n // Return the standard format.\n return dayjsDate.format(convertFormatToDayjs(format));\n }\n if (timezone === 'UTC') {\n const offset = offsetDate(dayjsDate.toDate(), 'UTC');\n return `${(0, dayjs_1.default)(offset.date).format(convertFormatToDayjs(format))} UTC`;\n }\n if (shouldHandleTimezone(timezone)) {\n return dayjsDate.tz(timezone).format(`${convertFormatToDayjs(format)} z`);\n }\n return dayjsDate.format(convertFormatToDayjs(format));\n}\nexports.formatDate = formatDate;\n/**\n * Pass a format function to format within a timezone.\n * @param {Function} formatFn - The format function to use.\n * @param {Date|string} date - The date to format.\n * @param {string} format - The format to format the date to.\n * @param {string} timezone - The timezone to format the date to.\n * @returns {string} - The formatted date.\n */\nfunction formatOffset(formatFn, date, format, timezone) {\n if (timezone === currentTimezone()) {\n return formatFn(date, format);\n }\n if (timezone === 'UTC') {\n return `${formatFn(offsetDate(date, 'UTC').date, format)} UTC`;\n }\n if (shouldHandleTimezone(timezone)) {\n const offset = offsetDate(date, timezone);\n return `${formatFn(offset.date, format)} ${offset.abbr}`;\n }\n else {\n return formatFn(date, format);\n }\n}\nexports.formatOffset = formatOffset;\n/**\n * Returns the local date format information.\n * @param {Intl.LocalesArgument} locale - The locale to get the date format for.\n * @returns {object} - The local date format information.\n */\nfunction getLocaleDateFormatInfo(locale) {\n const formatInfo = {};\n const day = 21;\n const exampleDate = new Date(2017, 11, day);\n const localDateString = exampleDate.toLocaleDateString(locale);\n formatInfo.dayFirst = localDateString.slice(0, 2) === day.toString();\n return formatInfo;\n}\nexports.getLocaleDateFormatInfo = getLocaleDateFormatInfo;\n/**\n * Convert the format from the angular-datepicker module to flatpickr format.\n * @param {string} format - The format to convert.\n * @returns {string} - The converted format.\n */\nfunction convertFormatToFlatpickr(format) {\n return format\n // Remove the Z timezone offset, not supported by flatpickr.\n .replace(/Z/g, '')\n // Year conversion.\n .replace(/y/g, 'Y')\n .replace('YYYY', 'Y')\n .replace('YY', 'y')\n // Month conversion.\n .replace('MMMM', 'F')\n .replace(/M/g, 'n')\n .replace('nnn', 'M')\n .replace('nn', 'm')\n // Day in month.\n .replace(/d/g, 'j')\n .replace(/jj/g, 'd')\n // Day in week.\n .replace('EEEE', 'l')\n .replace('EEE', 'D')\n // Hours, minutes, seconds\n .replace('HH', 'H')\n .replace('hh', 'G')\n .replace('mm', 'i')\n .replace('ss', 'S')\n .replace(/a/g, 'K');\n}\nexports.convertFormatToFlatpickr = convertFormatToFlatpickr;\n/**\n * Convert the format from the angular-datepicker module to moment format.\n * @param {string} format - The format to convert.\n * @returns {string} - The converted format.\n */\nfunction convertFormatToDayjs(format) {\n return format\n // Year conversion.\n .replace(/y/g, 'Y')\n // Day in month.\n .replace(/d/g, 'D')\n // Day in week.\n .replace(/E/g, 'd')\n // AM/PM marker\n .replace(/a/g, 'A')\n // Unix Timestamp\n .replace(/U/g, 'X');\n}\nexports.convertFormatToDayjs = convertFormatToDayjs;\n/**\n * Convert the format from the angular-datepicker module to mask format.\n * @param {string} format - The format to convert.\n * @returns {string} - The converted format.\n */\nfunction convertFormatToMask(format) {\n return format\n // Long month replacement.\n .replace(/M{4}/g, 'MM')\n // Initial short month conversion.\n .replace(/M{3}/g, '***')\n // Short month conversion if input as text.\n .replace(/e/g, 'Q')\n // Month number conversion.\n .replace(/W/g, '99')\n // Year conversion.\n .replace(/[ydhmswHMG]/g, '9')\n // AM/PM conversion.\n .replace(/a/g, 'AA');\n}\nexports.convertFormatToMask = convertFormatToMask;\n/**\n * Returns an input mask that is compatible with the input mask library.\n * @param {string} mask - The Form.io input mask.\n * @param {string} placeholderChar - Char which is used as a placeholder.\n * @returns {Array} - The input mask for the mask library.\n */\nfunction getInputMask(mask, placeholderChar) {\n if (mask instanceof Array) {\n return mask;\n }\n const maskArray = [];\n maskArray.numeric = true;\n for (let i = 0; i < mask.length; i++) {\n switch (mask[i]) {\n case '9':\n maskArray.push(/\\d/);\n break;\n case 'A':\n maskArray.numeric = false;\n maskArray.push(/[a-zA-Z]/);\n break;\n case 'a':\n maskArray.numeric = false;\n maskArray.push(/[a-z]/);\n break;\n case '*':\n maskArray.numeric = false;\n maskArray.push(/[a-zA-Z0-9]/);\n break;\n // If char which is used inside mask placeholder was used in the mask, replace it with space to prevent errors\n case placeholderChar:\n maskArray.numeric = false;\n maskArray.push(' ');\n break;\n default:\n maskArray.numeric = false;\n maskArray.push(mask[i]);\n break;\n }\n }\n return maskArray;\n}\nexports.getInputMask = getInputMask;\n/**\n * Unmasks a value using the provided mask and placeholder characters.\n * @param {string} value - The value to unmask.\n * @param {string} mask - The mask to use for unmasking.\n * @param {string} placeholderChar - The placeholder character to use for unmasking.\n * @returns {string} - The unmasked value.\n */\nfunction unmaskValue(value, mask, placeholderChar) {\n if (!mask || !value || value.length > mask.length) {\n return value;\n }\n let unmaskedValue = value.split('');\n for (let i = 0; i < mask.length; i++) {\n const char = value[i] || '';\n const charPart = mask[i];\n if (!lodash_1.default.isRegExp(charPart) && char === charPart) {\n unmaskedValue[i] = '';\n }\n }\n unmaskedValue = unmaskedValue.join('').replace(placeholderChar, '');\n return unmaskedValue;\n}\nexports.unmaskValue = unmaskValue;\n/**\n * Returns true if the value matches the input mask format.\n * @param {string} value - The value to check.\n * @param {string} inputMask - The input mask to check against.\n * @returns {boolean} - TRUE if the value matches the input mask; FALSE otherwise.\n */\nfunction matchInputMask(value, inputMask) {\n if (!inputMask) {\n return true;\n }\n // If value is longer than mask, it isn't valid.\n if (value.length > inputMask.length) {\n return false;\n }\n for (let i = 0; i < inputMask.length; i++) {\n const char = value[i] || '';\n const charPart = inputMask[i];\n if (!(lodash_1.default.isRegExp(charPart) && charPart.test(char) || charPart === char)) {\n return false;\n }\n }\n return true;\n}\nexports.matchInputMask = matchInputMask;\n/**\n * Returns the number separators (i.e. 1,000) for the provided language.\n * @param {string} lang - The language code to get the number separators for.\n * @returns {{delimiter: string, decimalSeparator: string}} - The number separators.\n */\nfunction getNumberSeparators(lang = 'en') {\n const formattedNumberString = (12345.6789).toLocaleString(lang);\n const delimeters = formattedNumberString.match(/..(.)...(.)../);\n if (!delimeters) {\n return {\n delimiter: ',',\n decimalSeparator: '.'\n };\n }\n return {\n delimiter: (delimeters.length > 1) ? delimeters[1] : ',',\n decimalSeparator: (delimeters.length > 2) ? delimeters[2] : '.',\n };\n}\nexports.getNumberSeparators = getNumberSeparators;\n/**\n * Returns the number for the maximum amount of decimal places for a number.\n * @param {import('@formio/core').Component} component - The component to check for decimal limits.\n * @param {number} defaultLimit - The default limit to use if none is provided in the component.\n * @returns {number} - The number of decimal places allowed.\n */\nfunction getNumberDecimalLimit(component, defaultLimit) {\n if (lodash_1.default.has(component, 'decimalLimit')) {\n return lodash_1.default.get(component, 'decimalLimit');\n }\n // Determine the decimal limit. Defaults to 20 but can be overridden by validate.step or decimalLimit settings.\n let decimalLimit = defaultLimit || 20;\n const step = lodash_1.default.get(component, 'validate.step', 'any');\n if (step !== 'any') {\n const parts = step.toString().split('.');\n if (parts.length > 1) {\n decimalLimit = parts[1].length;\n }\n }\n return decimalLimit;\n}\nexports.getNumberDecimalLimit = getNumberDecimalLimit;\n/**\n * Returns the currency affixes for a specific language.\n * @param {object} arg0 - The arguments object.\n * @param {string} arg0.currency - The currency code to get the affixes for.\n * @param {number} arg0.decimalLimit - The number of decimal places to use.\n * @param {string} arg0.decimalSeparator - The decimal separator to use.\n * @param {string} arg0.lang - The language code to use.\n * @returns {{prefix: string, suffix: string}} - The currency affixes.\n */\nfunction getCurrencyAffixes({ currency, decimalLimit, decimalSeparator, lang, }) {\n // Get the prefix and suffix from the localized string.\n let regex = `(.*)?${(100).toLocaleString(lang)}`;\n if (decimalLimit) {\n regex += `${decimalSeparator === '.' ? '\\\\.' : decimalSeparator}${(0).toLocaleString(lang)}{${decimalLimit}}`;\n }\n regex += '(.*)?';\n const parts = (100).toLocaleString(lang, {\n style: 'currency',\n currency: currency ? currency : 'USD',\n useGrouping: true,\n maximumFractionDigits: decimalLimit || 0,\n minimumFractionDigits: decimalLimit || 0\n }).replace('.', decimalSeparator).match(new RegExp(regex));\n return {\n prefix: (parts === null || parts === void 0 ? void 0 : parts[1]) || '',\n suffix: (parts === null || parts === void 0 ? void 0 : parts[2]) || ''\n };\n}\nexports.getCurrencyAffixes = getCurrencyAffixes;\n/**\n * Fetch the field data provided a component.\n * @param {import('@formio/core').DataObject} data - The data object to fetch the field data from.\n * @param {import('@formio/core').Component} component - The component to fetch the field data for.\n * @returns {*} - The field data.\n */\nfunction fieldData(data, component) {\n if (!data) {\n return '';\n }\n if (!component || !component.key) {\n return data;\n }\n if (component.key.includes('.')) {\n let value = data;\n const parts = component.key.split('.');\n let key = '';\n for (let i = 0; i < parts.length; i++) {\n key = parts[i];\n // Handle nested resources\n if (value.hasOwnProperty('_id')) {\n value = value.data;\n }\n // Return if the key is not found on the value.\n if (!value.hasOwnProperty(key)) {\n return;\n }\n // Convert old single field data in submissions to multiple\n if (key === parts[parts.length - 1] && component.multiple && !Array.isArray(value[key])) {\n value[key] = [value[key]];\n }\n // Set the value of this key.\n value = value[key];\n }\n return value;\n }\n else {\n // Convert old single field data in submissions to multiple\n if (component.multiple && !Array.isArray(data[component.key])) {\n data[component.key] = [data[component.key]];\n }\n // Fix for checkbox type radio submission values in tableView\n if (component.type === 'checkbox' && component.inputType === 'radio') {\n return data[component.name] === component.value;\n }\n return data[component.key];\n }\n}\nexports.fieldData = fieldData;\n/**\n * Delays function execution with possibility to execute function synchronously or cancel it.\n * @param {Function} fn - Function to delay\n * @param {number} delay - Delay time\n * @param {...any} args - Arguments to pass to the function\n * @returns {*} - Function to cancel the delay\n */\nfunction delay(fn, delay = 0, ...args) {\n const timer = setTimeout(fn, delay, ...args);\n /**\n *\n */\n function cancel() {\n clearTimeout(timer);\n }\n /**\n * Execute the function early.\n * @returns {*} - The result of the function.\n */\n function earlyCall() {\n cancel();\n return fn(...args);\n }\n earlyCall.timer = timer;\n earlyCall.cancel = cancel;\n return earlyCall;\n}\nexports.delay = delay;\n/**\n * Iterate the given key to make it unique.\n * @param {string} key\n * Modify the component key to be unique.\n * @returns {string}\n * The new component key.\n */\nfunction iterateKey(key) {\n if (!key.match(/(\\d+)$/)) {\n return `${key}1`;\n }\n return key.replace(/(\\d+)$/, function (suffix) {\n return Number(suffix) + 1;\n });\n}\nexports.iterateKey = iterateKey;\n/**\n * Determines a unique key within a map provided the base key.\n * @param {Record<string, string>} map - The map to check for uniqueness.\n * @param {string} base - The base path of the key.\n * @returns {string} - The unique key.\n */\nfunction uniqueKey(map, base) {\n let newKey = base;\n while (map.hasOwnProperty(newKey)) {\n newKey = iterateKey(newKey);\n }\n return newKey;\n}\nexports.uniqueKey = uniqueKey;\n/**\n * Determines the major version number of bootstrap.\n * @param {object} options - The options to check for bootstrap version.\n * @param {string} options.bootstrap - The bootstrap version to use.\n * @returns {number} - The bootstrap version.\n */\nfunction bootstrapVersion(options) {\n if (options.bootstrap) {\n return options.bootstrap;\n }\n if ((typeof jQuery === 'function') && (typeof jQuery().collapse === 'function')) {\n return parseInt(jQuery.fn.collapse.Constructor.VERSION.split('.')[0], 10);\n }\n if (window.bootstrap && window.bootstrap.Collapse) {\n return parseInt(window.bootstrap.Collapse.VERSION.split('.')[0], 10);\n }\n return 0;\n}\nexports.bootstrapVersion = bootstrapVersion;\n/**\n * Retrun provided argument.\n * If argument is a function, returns the result of a function call.\n * @param {Function|any} e - The argument to check if a function and call if so.\n * @returns {any} - Either the result of the function call (e) or e if it is not a function.\n */\nfunction unfold(e) {\n if (typeof e === 'function') {\n return e();\n }\n return e;\n}\nexports.unfold = unfold;\n/**\n * Map values through unfold and return first non-nil value.\n * @param {Array<T>} collection - The collection to map through unfold.;\n * @returns {T} - The first non-nil value.\n */\nexports.firstNonNil = lodash_1.default.flow([\n lodash_1.default.partialRight(lodash_1.default.map, unfold),\n lodash_1.default.partialRight(lodash_1.default.find, v => !lodash_1.default.isUndefined(v))\n]);\n/**\n * Create enclosed state. Returns functions to getting and cycling between states.\n * @param {*} a - initial state.\n * @param {*} b - next state.\n * @returns {Functions[]} -- [get, toggle];\n */\nfunction withSwitch(a, b) {\n let state = a;\n let next = b;\n /**\n * Returns the state of the switch.\n * @returns {*} - The current state.\n */\n function get() {\n return state;\n }\n /**\n * Toggles the state of the switch.\n */\n function toggle() {\n const prev = state;\n state = next;\n next = prev;\n }\n return [get, toggle];\n}\nexports.withSwitch = withSwitch;\n/**\n * Create a function that will call the provided function only the provided limit.\n * @param {Function} callback - The callback to call.\n * @param {object} options - The options to use.\n * @param {number} options.limit - The limit to call the callback.\n * @param {number} options.delay - The delay to wait before resetting the call count.\n * @returns {Function} - The function that will call the callback only the provided limit.\n */\nfunction observeOverload(callback, options = {}) {\n const { limit = 50, delay = 500 } = options;\n let callCount = 0;\n let timeoutID = 0;\n const reset = () => callCount = 0;\n return () => {\n if (timeoutID !== 0) {\n clearTimeout(timeoutID);\n timeoutID = 0;\n }\n timeoutID = setTimeout(reset, delay);\n callCount += 1;\n if (callCount >= limit) {\n clearTimeout(timeoutID);\n reset();\n return callback();\n }\n };\n}\nexports.observeOverload = observeOverload;\n/**\n * Returns the components that are provided within an evaluation context.\n * @param {any} context - The evaluation context to get the components from.\n * @param {boolean} excludeNested - Exclude nested components.\n * @param {Array<string>} excludedTypes - The types of components to exclude.\n * @returns {Array} - The components within the evaluation context.\n */\nfunction getContextComponents(context, excludeNested, excludedTypes = []) {\n const values = [];\n context.utils.eachComponent(context.instance.options.editForm.components, (component, path) => {\n const addToContextComponents = excludeNested ? !component.tree : true;\n if (component.key !== context.data.key && addToContextComponents && !lodash_1.default.includes(excludedTypes, component.type)) {\n values.push({\n label: `${component.label || component.key} (${path})`,\n value: path,\n });\n }\n });\n return values;\n}\nexports.getContextComponents = getContextComponents;\n/**\n * Returns the button components that are within an evaluation context.\n * @param {any} context - The evaluation context to get the components from.\n * @returns {Array} - The button components within the evaluation context.\n */\nfunction getContextButtons(context) {\n const values = [];\n context.utils.eachComponent(context.instance.options.editForm.components, (component) => {\n if (component.type === 'button') {\n values.push({\n label: `${component.key} (${component.label})`,\n value: component.key,\n });\n }\n });\n return values;\n}\nexports.getContextButtons = getContextButtons;\n// Tags that could be in text, that should be ommited or handled in a special way\nconst inTextTags = ['#text', 'A', 'B', 'EM', 'I', 'SMALL', 'STRONG', 'SUB', 'SUP', 'INS', 'DEL', 'MARK', 'CODE'];\n/**\n * Helper function for 'translateHTMLTemplate'. Translates text value of the passed html element.\n * @param {HTMLElement} elem - The element to translate.\n * @param {Function} translate - The translation function.\n * @returns {string} - Translated element template.\n */\nfunction translateElemValue(elem, translate) {\n if (!elem.innerText) {\n return elem.innerHTML;\n }\n const elemValue = elem.innerText.replace(Evaluator_1.Evaluator.templateSettings.interpolate, '').replace(/\\s\\s+/g, ' ').trim();\n const translatedValue = translate(elemValue);\n if (elemValue !== translatedValue) {\n const links = elem.innerHTML.match(/<a[^>]*>(.*?)<\\/a>/g);\n if (links && links.length) {\n if (links.length === 1 && links[0].length === elem.innerHTML.length) {\n return elem.innerHTML.replace(elemValue, translatedValue);\n }\n const translatedLinks = links.map(link => {\n const linkElem = document.createElement('a');\n linkElem.innerHTML = link;\n return translateElemValue(linkElem, translate);\n });\n return `${translatedValue} (${translatedLinks.join(', ')})`;\n }\n else {\n return elem.innerText.replace(elemValue, translatedValue);\n }\n }\n else {\n return elem.innerHTML;\n }\n}\n/**\n * Helper function for 'translateHTMLTemplate'. Goes deep through html tag children and calls function to translate their text values.\n * @param {HTMLElement} tag - The tag to translate.\n * @param {Function} translate - The translation function.\n * @returns {void}\n */\nfunction translateDeepTag(tag, translate) {\n const children = tag.children.length && [...tag.children];\n const shouldTranslateEntireContent = children && children.every(child => child.children.length === 0\n && inTextTags.some(tag => child.nodeName === tag));\n if (!children || shouldTranslateEntireContent) {\n tag.innerHTML = translateElemValue(tag, translate);\n }\n else {\n children.forEach(child => translateDeepTag(child, translate));\n }\n}\n/**\n * Translates text values in html template.\n * @param {string} template - The template to translate.\n * @param {Function} translate - The translation function.\n * @returns {string} - Html template with translated values.\n */\nfunction translateHTMLTemplate(template, translate) {\n const isHTML = /<[^>]*>/.test(template);\n if (!isHTML) {\n return translate(template);\n }\n const tempElem = document.createElement('div');\n tempElem.innerHTML = template;\n if (tempElem.innerText && tempElem.children.length) {\n translateDeepTag(tempElem, translate);\n return tempElem.innerHTML;\n }\n return template;\n}\nexports.translateHTMLTemplate = translateHTMLTemplate;\n/**\n * Sanitize an html string.\n * @param {string} string - The string to sanitize.\n * @param {any} options - The options to use for sanitization.\n * @returns {string} - The sanitized html string.\n */\nfunction sanitize(string, options) {\n if (typeof dompurify_1.default.sanitize !== 'function') {\n return string;\n }\n // Dompurify configuration\n const sanitizeOptions = {\n ADD_ATTR: ['ref', 'target'],\n USE_PROFILES: { html: true }\n };\n // Use profiles\n if (options.sanitizeConfig && options.sanitizeConfig.useProfiles) {\n Object.keys(options.sanitizeConfig.useProfiles).forEach(key => {\n sanitizeOptions.USE_PROFILES[key] = options.sanitizeConfig.useProfiles[key];\n });\n }\n // Add attrs\n if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.addAttr) && options.sanitizeConfig.addAttr.length > 0) {\n options.sanitizeConfig.addAttr.forEach((attr) => {\n sanitizeOptions.ADD_ATTR.push(attr);\n });\n }\n // Add tags\n if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.addTags) && options.sanitizeConfig.addTags.length > 0) {\n sanitizeOptions.ADD_TAGS = options.sanitizeConfig.addTags;\n }\n // Allow tags\n if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.allowedTags) && options.sanitizeConfig.allowedTags.length > 0) {\n sanitizeOptions.ALLOWED_TAGS = options.sanitizeConfig.allowedTags;\n }\n // Allow attributes\n if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.allowedAttrs) && options.sanitizeConfig.allowedAttrs.length > 0) {\n sanitizeOptions.ALLOWED_ATTR = options.sanitizeConfig.allowedAttrs;\n }\n // Allowd URI Regex\n if (options.sanitizeConfig && options.sanitizeConfig.allowedUriRegex) {\n const allowedUriRegex = options.sanitizeConfig.allowedUriRegex;\n sanitizeOptions.ALLOWED_URI_REGEXP = lodash_1.default.isString(allowedUriRegex) ? new RegExp(allowedUriRegex) : allowedUriRegex;\n }\n // Allow to extend the existing array of elements that are safe for URI-like values\n if (options.sanitizeConfig && Array.isArray(options.sanitizeConfig.addUriSafeAttr) && options.sanitizeConfig.addUriSafeAttr.length > 0) {\n sanitizeOptions.ADD_URI_SAFE_ATTR = options.sanitizeConfig.addUriSafeAttr;\n }\n return dompurify_1.default.sanitize(string, sanitizeOptions);\n}\nexports.sanitize = sanitize;\n/**\n * Fast cloneDeep for JSON objects only.\n * @param {any} obj - The object to perform a fast clone deep against.\n * @returns {any} - The cloned object.\n */\nfunction fastCloneDeep(obj) {\n return obj ? JSON.parse(JSON.stringify(obj)) : obj;\n}\nexports.fastCloneDeep = fastCloneDeep;\n/**\n * Returns if the component is an input component.\n * @param {import('@formio/core').Component} componentJson - The JSON of a component.\n * @returns {boolean} - TRUE if the component is an input component; FALSE otherwise.\n */\nfunction isInputComponent(componentJson) {\n if (componentJson.input === false || componentJson.input === true) {\n return componentJson.input;\n }\n switch (componentJson.type) {\n case 'htmlelement':\n case 'content':\n case 'columns':\n case 'fieldset':\n case 'panel':\n case 'table':\n case 'tabs':\n case 'well':\n case 'button':\n return false;\n default:\n return true;\n }\n}\nexports.isInputComponent = isInputComponent;\n/**\n * Takes a component path, and returns a component path array.\n * @param {string} pathStr - The path string to convert to an array.\n * @returns {Array<string>} - The array of paths.\n */\nfunction getArrayFromComponentPath(pathStr) {\n if (!pathStr || !lodash_1.default.isString(pathStr)) {\n if (!lodash_1.default.isArray(pathStr)) {\n return [pathStr];\n }\n return pathStr;\n }\n return pathStr.replace(/[[\\]]/g, '.')\n .replace(/\\.\\./g, '.')\n .replace(/(^\\.)|(\\.$)/g, '')\n .split('.')\n .map(part => lodash_1.default.defaultTo(lodash_1.default.toNumber(part), part));\n}\nexports.getArrayFromComponentPath = getArrayFromComponentPath;\n/**\n * Returns true if the component is a child of the parent.\n * @param {any} child - The child component to check.\n * @param {any} parent - The parent component to check.\n * @returns {boolean} - TRUE if the child is a child of the parent; FALSE otherwise.\n */\nfunction isChildOf(child, parent) {\n while (child && child.parent) {\n if (child.parent === parent) {\n return true;\n }\n child = child.parent;\n }\n return false;\n}\nexports.isChildOf = isChildOf;\n/**\n * Takes an array of component path indexes, and returns a string version of that array.\n * @param {Array<number>} path - The path array to convert to a string.\n * @returns {string} - The string version of the path.\n */\nfunction getStringFromComponentPath(path) {\n if (!lodash_1.default.isArray(path)) {\n return path;\n }\n let strPath = '';\n path.forEach((part, i) => {\n if (lodash_1.default.isNumber(part)) {\n strPath += `[${part}]`;\n }\n else {\n strPath += i === 0 ? part : `.${part}`;\n }\n });\n return strPath;\n}\nexports.getStringFromComponentPath = getStringFromComponentPath;\n/**\n * Takes a number and rounds it to the provided precision amount.\n * @param {number} number - The number to round.\n * @param {number} precision - The precision to round the number to.\n * @returns {string} - The rounded number.\n */\nfunction round(number, precision) {\n if (lodash_1.default.isNumber(number)) {\n return number.toFixed(precision);\n }\n return number.toString();\n}\nexports.round = round;\n/**\n * Check for Internet Explorer browser version\n * @returns {(number|null)} - The IE browser version or null if not IE\n */\nfunction getIEBrowserVersion() {\n const { ie, version } = getBrowserInfo();\n return ie ? version : null;\n}\nexports.getIEBrowserVersion = getIEBrowserVersion;\n/**\n * Get browser name and version (modified from 'jquery-browser-plugin')\n * @returns {object} -- {{browser name, version, isWebkit?}}\n * Possible browser names: chrome, safari, ie, edge, opera, mozilla, yabrowser\n */\nfunction getBrowserInfo() {\n const browser = {};\n if (typeof window === 'undefined') {\n return browser;\n }\n const ua = window.navigator.userAgent.toLowerCase();\n const match = /(edge|edg)\\/([\\w.]+)/.exec(ua) ||\n /(opr)[/]([\\w.]+)/.exec(ua) ||\n /(yabrowser)[ /]([\\w.]+)/.exec(ua) ||\n /(chrome)[ /]([\\w.]+)/.exec(ua) ||\n /(iemobile)[/]([\\w.]+)/.exec(ua) ||\n /(version)(applewebkit)[ /]([\\w.]+).*(safari)[ /]([\\w.]+)/.exec(ua) ||\n /(webkit)[ /]([\\w.]+).*(version)[ /]([\\w.]+).*(safari)[ /]([\\w.]+)/.exec(ua) ||\n /(webkit)[ /]([\\w.]+)/.exec(ua) ||\n /(opera)(?:.*version|)[ /]([\\w.]+)/.exec(ua) ||\n /(msie) ([\\w.]+)/.exec(ua) ||\n ua.indexOf('trident') >= 0 && /(rv)(?::| )([\\w.]+)/.exec(ua) ||\n ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec(ua) ||\n [];\n const matched = {\n browser: match[5] || match[3] || match[1] || '',\n version: match[4] || match[2] || '0'\n };\n if (matched.browser) {\n browser[matched.browser] = true;\n browser.version = parseInt(matched.version, 10);\n }\n // Chrome, Opera 15+, Safari and Yandex.Browser are webkit based browsers\n if (browser.chrome || browser.opr || browser.safari || browser.edg || browser.yabrowser) {\n browser.isWebkit = true;\n }\n // IE11 has a new token so we will assign it ie to avoid breaking changes\n if (browser.rv || browser.iemobile) {\n browser.ie = true;\n }\n // Edge has a new token since it became webkit based\n if (browser.edg) {\n browser.edge = true;\n }\n // Opera 15+ are identified as opr\n if (browser.opr) {\n browser.opera = true;\n }\n return browser;\n}\nexports.getBrowserInfo = getBrowserInfo;\n/**\n * Takes a component path, which may include array indicies (i.e. [0][1]), and returns the compoennt path without the indicies.\n * @param {string} path - The path to remove the indicies from.\n * @returns {string} - The path without the indicies.\n */\nfunction getComponentPathWithoutIndicies(path = '') {\n return path.replace(/\\[\\d+\\]/, '');\n}\nexports.getComponentPathWithoutIndicies = getComponentPathWithoutIndicies;\n/**\n * Returns a path to the component which based on its schema\n * @param {import('@formio/core').Component} component - Component containing link to its parent's schema in the 'parent' property\n * @returns {string} - Path to the component\n */\nfunction getComponentPath(component) {\n return component.paths.localDataPath;\n}\nexports.getComponentPath = getComponentPath;\n/**\n * Returns a parent component of the passed component instance skipping all the Layout components\n * @param {Component} componentInstance - The component to check for the parent.\n * @returns {Component|undefined} - The parent data component.\n */\nfunction getDataParentComponent(componentInstance) {\n if (!componentInstance) {\n return;\n }\n const { parent } = componentInstance;\n if (parent && (parent.isInputComponent || parent.input)) {\n return parent;\n }\n else {\n return getDataParentComponent(parent);\n }\n}\nexports.getDataParentComponent = getDataParentComponent;\n/**\n * Returns whether the value is a promise\n * @param {any} value - The value to check\n * @returns {boolean} - TRUE if the value is a promise; FALSE otherwise\n */\nfunction isPromise(value) {\n return value\n && value.then\n && typeof value.then === 'function'\n && Object.prototype.toString.call(value) === '[object Promise]';\n}\nexports.isPromise = isPromise;\n/**\n * Returns all the focusable elements within the provided dom element.\n * @param {HTMLElement} element - The element to get the focusable elements from.\n * @returns {NodeList<HTMLElement>} - The focusable elements within the provided element.\n */\nfunction getFocusableElements(element) {\n const focusableSelector = `button:not([disabled]), input:not([disabled]), select:not([disabled]),\n textarea:not([disabled]), button:not([disabled]), [href]`;\n return element.querySelectorAll(focusableSelector);\n}\nexports.getFocusableElements = getFocusableElements;\nexports.componentValueTypes = {\n number: 'number',\n string: 'string',\n boolean: 'boolean',\n array: 'array',\n object: 'object',\n date: 'date',\n any: 'any',\n};\n/**\n * Returns the saved types for the component\n * @param {import('@formio/core').Component} fullSchema - The component schema\n * @returns {Array<string>|null} - The saved types for the component\n */\nfunction getComponentSavedTypes(fullSchema) {\n const schema = fullSchema || {};\n if (schema.persistent !== true) {\n return [];\n }\n if (schema.multiple) {\n return [exports.componentValueTypes.array];\n }\n return null;\n}\nexports.getComponentSavedTypes = getComponentSavedTypes;\n/**\n * Interpolates @formio/core errors so that they are compatible with the renderer\n * @param {Component} component - The component to interpolate the errors for\n * @param {FieldError[]} errors - The errors to interpolate\n * @param {Function} interpolateFn - The interpolation function\n * @returns {[]} - The interpolated errors\n */\nconst interpolateErrors = (component, errors, interpolateFn) => {\n return errors.map((error) => {\n error.component = component;\n const { errorKeyOrMessage, context } = error;\n const toInterpolate = component.errors && component.errors[errorKeyOrMessage] ? component.errors[errorKeyOrMessage] : errorKeyOrMessage;\n return Object.assign(Object.assign({}, error), { message: unescapeHTML(interpolateFn(toInterpolate, context)), context: Object.assign({}, context) });\n });\n};\nexports.interpolateErrors = interpolateErrors;\n/**\n * Checks if a string has timezone information encoded in it\n * Example: 2024-01-01T00:00:00Z -> true\n * Example: 2024-01-01T00:00:00+03:00 -> true\n * Example: 2011-05-03T00:00:00 -> false\n * @param {string} value the string value to check\n * @returns {boolean} if value has encoded timezone\n */\nfunction hasEncodedTimezone(value) {\n if (typeof value !== 'string') {\n return false;\n }\n return (value.substring(value.length - 1) === 'z' || value.substring(value.length - 1) === 'Z' || value.match(/[+|-][0-9]{2}:[0-9]{2}$/));\n}\nexports.hasEncodedTimezone = hasEncodedTimezone;\n\n\n//# sourceURL=webpack://Formio/./lib/cjs/utils/utils.js?");
6100
6100
 
6101
6101
  /***/ }),
6102
6102