@formio/js 5.0.0-rc.87 → 5.0.0-rc.88

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,7 +10,7 @@
10
10
  * MIT licensed
11
11
  */
12
12
 
13
- /*! formiojs v5.0.0-rc.87 | https://unpkg.com/formiojs@5.0.0-rc.87/LICENSE.txt */
13
+ /*! formiojs v5.0.0-rc.88 | https://unpkg.com/formiojs@5.0.0-rc.88/LICENSE.txt */
14
14
 
15
15
  /**
16
16
  * @license
@@ -565,7 +565,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
565
565
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
566
566
 
567
567
  "use strict";
568
- 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.validateMultipleInfo = exports.validateMultipleSync = exports.validateMultiple = exports.shouldValidate = exports.emptyValueIsArray = exports.isEligible = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst error_1 = __webpack_require__(/*! ../../../error */ \"./node_modules/@formio/core/lib/error/index.js\");\nconst formUtil_1 = __webpack_require__(/*! ../../../utils/formUtil */ \"./node_modules/@formio/core/lib/utils/formUtil.js\");\nconst isEligible = (component) => {\n // TODO: would be nice if this was type safe\n switch (component.type) {\n case 'hidden':\n case 'address':\n if (!component.multiple) {\n return false;\n }\n return true;\n case 'textarea':\n if (!component.as ||\n component.as !== 'json' ||\n (component.as === 'json' && !component.multiple)) {\n return false;\n }\n return true;\n // TODO: For backwards compatibility, skip multiple validation for select components until we can investigate\n // how this validation might break existing forms\n case 'select':\n return false;\n default:\n return true;\n }\n};\nexports.isEligible = isEligible;\nconst isTagsComponent = (component) => {\n return (component === null || component === void 0 ? void 0 : component.type) === 'tags';\n};\nconst emptyValueIsArray = (component) => {\n // TODO: How do we infer the data model of the compoennt given only its JSON? For now, we have to hardcode component types\n switch (component.type) {\n case 'datagrid':\n case 'editgrid':\n case 'tagpad':\n case 'sketchpad':\n case 'datatable':\n case 'dynamicWizard':\n case 'file':\n return true;\n case 'select':\n case 'textfield':\n return !!component.multiple;\n case 'tags':\n return component.storeas !== 'string';\n default:\n return true;\n }\n};\nexports.emptyValueIsArray = emptyValueIsArray;\nconst shouldValidate = (context) => {\n const { component } = context;\n if (!(0, exports.isEligible)(component)) {\n return false;\n }\n return true;\n};\nexports.shouldValidate = shouldValidate;\nconst validateMultiple = (context) => __awaiter(void 0, void 0, void 0, function* () {\n return (0, exports.validateMultipleSync)(context);\n});\nexports.validateMultiple = validateMultiple;\nconst validateMultipleSync = (context) => {\n var _a;\n const { component, value } = context;\n // Skip multiple validation if the component tells us to\n if (!(0, exports.isEligible)(component)) {\n return null;\n }\n const shouldBeMultipleArray = !!component.multiple;\n const isRequired = !!((_a = component.validate) === null || _a === void 0 ? void 0 : _a.required);\n const underlyingValueShouldBeArray = ['nestedArray', 'nestedDataArray'].indexOf((0, formUtil_1.getModelType)(component)) !== -1 || (isTagsComponent(component) && component.storeas === 'array');\n const valueIsArray = Array.isArray(value);\n if (shouldBeMultipleArray) {\n if (valueIsArray && underlyingValueShouldBeArray) {\n if (value.length === 0) {\n return isRequired ? new error_1.FieldError('array_nonempty', Object.assign(Object.assign({}, context), { setting: true })) : null;\n }\n // TODO: We need to be permissive here for file components, which have an array model type but don't have an underlying array value\n // (in other words, a file component's data object will always be a single array regardless of whether or not multiple is set)\n // In the future, we could consider checking the underlying value's type to determine if it should be an array\n // return Array.isArray(value[0]) ? null : new FieldError('array', { ...context, setting: true });\n return null;\n }\n else if (valueIsArray && !underlyingValueShouldBeArray) {\n if (value.length === 0) {\n return isRequired ? new error_1.FieldError('array_nonempty', Object.assign(Object.assign({}, context), { setting: true })) : null;\n }\n return Array.isArray(value[0]) ? new error_1.FieldError('nonarray', Object.assign(Object.assign({}, context), { setting: true })) : null;\n }\n else {\n const error = new error_1.FieldError('array', Object.assign(Object.assign({}, context), { setting: true }));\n // Null/undefined is ok if this value isn't required; anything else should fail\n return (0, lodash_1.isNil)(value) ? (isRequired ? error : null) : error;\n }\n }\n else {\n const canBeArray = (0, exports.emptyValueIsArray)(component) || underlyingValueShouldBeArray;\n if (!canBeArray && valueIsArray) {\n return new error_1.FieldError('nonarray', Object.assign(Object.assign({}, context), { setting: false }));\n }\n return null;\n }\n};\nexports.validateMultipleSync = validateMultipleSync;\nexports.validateMultipleInfo = {\n name: 'validateMultiple',\n process: exports.validateMultiple,\n fullValue: true,\n processSync: exports.validateMultipleSync,\n shouldProcess: exports.shouldValidate,\n};\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/process/validation/rules/validateMultiple.js?");
568
+ 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.validateMultipleInfo = exports.validateMultipleSync = exports.validateMultiple = exports.shouldValidate = exports.emptyValueIsArray = exports.isEligible = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst error_1 = __webpack_require__(/*! ../../../error */ \"./node_modules/@formio/core/lib/error/index.js\");\nconst formUtil_1 = __webpack_require__(/*! ../../../utils/formUtil */ \"./node_modules/@formio/core/lib/utils/formUtil.js\");\nconst isEligible = (component) => {\n // TODO: would be nice if this was type safe\n switch (component.type) {\n case 'hidden':\n case 'address':\n if (!component.multiple) {\n return false;\n }\n return true;\n case 'textarea':\n if (!component.as ||\n component.as !== 'json' ||\n (component.as === 'json' && !component.multiple)) {\n return false;\n }\n return true;\n // TODO: For backwards compatibility, skip multiple validation for select components until we can investigate\n // how this validation might break existing forms\n case 'select':\n return false;\n default:\n return true;\n }\n};\nexports.isEligible = isEligible;\nconst isTagsComponent = (component) => {\n return (component === null || component === void 0 ? void 0 : component.type) === 'tags';\n};\nconst emptyValueIsArray = (component) => {\n // TODO: How do we infer the data model of the compoennt given only its JSON? For now, we have to hardcode component types\n switch (component.type) {\n case 'datagrid':\n case 'editgrid':\n case 'tagpad':\n case 'sketchpad':\n case 'datatable':\n case 'dynamicWizard':\n case 'file':\n return true;\n case 'select':\n case 'textfield':\n return !!component.multiple;\n case 'tags':\n return component.storeas !== 'string';\n default:\n return true;\n }\n};\nexports.emptyValueIsArray = emptyValueIsArray;\nconst shouldValidate = (context) => {\n const { component } = context;\n if (!(0, exports.isEligible)(component)) {\n return false;\n }\n return true;\n};\nexports.shouldValidate = shouldValidate;\nconst validateMultiple = (context) => __awaiter(void 0, void 0, void 0, function* () {\n return (0, exports.validateMultipleSync)(context);\n});\nexports.validateMultiple = validateMultiple;\nconst validateMultipleSync = (context) => {\n var _a;\n const { component, value } = context;\n // Skip multiple validation if the component tells us to\n if (!(0, exports.isEligible)(component)) {\n return null;\n }\n const shouldBeMultipleArray = !!component.multiple;\n const isRequired = !!((_a = component.validate) === null || _a === void 0 ? void 0 : _a.required);\n const compModelType = (0, formUtil_1.getModelType)(component);\n const underlyingValueShouldBeArray = ['nestedArray', 'nestedDataArray'].indexOf(compModelType) !== -1 || (isTagsComponent(component) && component.storeas === 'array');\n const valueIsArray = Array.isArray(value);\n if (shouldBeMultipleArray) {\n if (valueIsArray && underlyingValueShouldBeArray) {\n if (value.length === 0) {\n return isRequired ? new error_1.FieldError('array_nonempty', Object.assign(Object.assign({}, context), { setting: true })) : null;\n }\n // TODO: We need to be permissive here for file components, which have an array model type but don't have an underlying array value\n // (in other words, a file component's data object will always be a single array regardless of whether or not multiple is set)\n // In the future, we could consider checking the underlying value's type to determine if it should be an array\n // return Array.isArray(value[0]) ? null : new FieldError('array', { ...context, setting: true });\n return null;\n }\n else if (valueIsArray && !underlyingValueShouldBeArray) {\n if (value.length === 0) {\n return isRequired ? new error_1.FieldError('array_nonempty', Object.assign(Object.assign({}, context), { setting: true })) : null;\n }\n return Array.isArray(value[0]) && compModelType !== 'any' ? new error_1.FieldError('nonarray', Object.assign(Object.assign({}, context), { setting: true })) : null;\n }\n else {\n const error = new error_1.FieldError('array', Object.assign(Object.assign({}, context), { setting: true }));\n // Null/undefined is ok if this value isn't required; anything else should fail\n return (0, lodash_1.isNil)(value) ? (isRequired ? error : null) : error;\n }\n }\n else {\n const canBeArray = (0, exports.emptyValueIsArray)(component) || underlyingValueShouldBeArray;\n if (!canBeArray && valueIsArray) {\n return new error_1.FieldError('nonarray', Object.assign(Object.assign({}, context), { setting: false }));\n }\n return null;\n }\n};\nexports.validateMultipleSync = validateMultipleSync;\nexports.validateMultipleInfo = {\n name: 'validateMultiple',\n process: exports.validateMultiple,\n fullValue: true,\n processSync: exports.validateMultipleSync,\n shouldProcess: exports.shouldValidate,\n};\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/process/validation/rules/validateMultiple.js?");
569
569
 
570
570
  /***/ }),
571
571
 
@@ -1335,7 +1335,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
1335
1335
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
1336
1336
 
1337
1337
  "use strict";
1338
- 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.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.getComponentActualValue = exports.getComponentData = exports.eachComponentAsync = exports.eachComponent = exports.componentInfo = exports.getContextualRowData = exports.getContextualRowPath = exports.getComponentKey = exports.eachComponentData = exports.eachComponentDataAsync = exports.componentFormPath = exports.componentDataPath = exports.componentPath = exports.isComponentNestedDataType = exports.getComponentPath = exports.getComponentAbsolutePath = 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 Evaluator_1 = __webpack_require__(/*! ./Evaluator */ \"./node_modules/@formio/core/lib/utils/Evaluator.js\");\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 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: [\n 'datagrid',\n 'editgrid',\n 'datatable',\n 'dynamicWizard',\n ],\n nestedDataArray: [\n 'tagpad',\n ],\n dataObject: [\n 'form'\n ],\n object: [\n 'container',\n 'address',\n ],\n map: [\n 'datamap',\n ],\n content: [\n 'htmlelement',\n 'content'\n ],\n string: [\n 'textfield',\n 'textarea',\n 'password',\n 'email',\n 'url',\n 'phoneNumber',\n 'day',\n 'datetime',\n 'time',\n 'signature',\n ],\n number: [\n 'number',\n 'currency'\n ],\n boolean: [\n 'checkbox',\n 'radio',\n ],\n none: [\n 'table',\n 'well',\n 'columns',\n 'fieldset',\n 'panel',\n 'tabs'\n ],\n any: [\n 'survey',\n 'captcha',\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 // 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 return type;\n }\n }\n // Otherwise check for components that assert no value.\n if ((component.input === false)) {\n return 'none';\n }\n // Otherwise default to any.\n return 'any';\n}\nexports.getModelType = getModelType;\nfunction getComponentAbsolutePath(component) {\n let paths = [component.path];\n while (component.parent) {\n component = component.parent;\n // We only need to do this for nested forms because they reset the data contexts for the children.\n if (getModelType(component) === 'dataObject') {\n paths[paths.length - 1] = `data.${paths[paths.length - 1]}`;\n paths.push(component.path);\n }\n }\n return paths.reverse().join('.');\n}\nexports.getComponentAbsolutePath = getComponentAbsolutePath;\nfunction getComponentPath(component, path) {\n const key = getComponentKey(component);\n if (!key) {\n return path;\n }\n if (!path) {\n return key;\n }\n if (path.match(new RegExp(`${key}$`))) {\n return path;\n }\n return (getModelType(component) === 'none') ? `${path}.${key}` : path;\n}\nexports.getComponentPath = getComponentPath;\nfunction isComponentNestedDataType(component) {\n return component.tree || getModelType(component) === 'nestedArray' ||\n getModelType(component) === 'nestedDataArray' ||\n getModelType(component) === 'dataObject' ||\n getModelType(component) === 'object' ||\n getModelType(component) === 'map';\n}\nexports.isComponentNestedDataType = isComponentNestedDataType;\nfunction componentPath(component, parentPath) {\n parentPath = component.parentPath || parentPath;\n const key = getComponentKey(component);\n if (!key) {\n // If the component does not have a key, then just always return the parent path.\n return parentPath || '';\n }\n return parentPath ? `${parentPath}.${key}` : key;\n}\nexports.componentPath = componentPath;\nconst componentDataPath = (component, parentPath, path) => {\n parentPath = component.parentPath || parentPath;\n path = path || componentPath(component, parentPath);\n // See if we are a nested component.\n if (component.components && Array.isArray(component.components)) {\n if (getModelType(component) === 'dataObject') {\n return `${path}.data`;\n }\n if (getModelType(component) === 'nestedArray') {\n return `${path}[0]`;\n }\n if (getModelType(component) === 'nestedDataArray') {\n return `${path}[0].data`;\n }\n if (isComponentNestedDataType(component)) {\n return path;\n }\n return parentPath;\n }\n return path;\n};\nexports.componentDataPath = componentDataPath;\nconst componentFormPath = (component, parentPath, path) => {\n parentPath = component.parentPath || parentPath;\n path = path || componentPath(component, parentPath);\n if (getModelType(component) === 'dataObject') {\n return `${path}.data`;\n }\n if (isComponentNestedDataType(component)) {\n return path;\n }\n return parentPath;\n};\nexports.componentFormPath = componentFormPath;\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, path = \"\", index, parent, includeAll = false) {\n if (!components || !data) {\n return;\n }\n return yield eachComponentAsync(components, (component, compPath, componentComponents, compParent) => __awaiter(void 0, void 0, void 0, function* () {\n const row = getContextualRowData(component, compPath, data);\n if ((yield fn(component, data, row, compPath, componentComponents, index, compParent)) === true) {\n return true;\n }\n if (isComponentNestedDataType(component)) {\n const value = (0, lodash_1.get)(data, compPath, data);\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const nestedComponentPath = getModelType(component) === 'nestedDataArray' ? `${compPath}[${i}].data` : `${compPath}[${i}]`;\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, nestedComponentPath, i, component, includeAll);\n }\n return true;\n }\n else if ((0, lodash_1.isEmpty)(row) && !includeAll) {\n // Tree components may submit empty objects; since we've already evaluated the parent tree/layout component, we won't worry about constituent elements\n return true;\n }\n if (getModelType(component) === 'dataObject') {\n // No need to bother processing all the children data if there is no data for this form or the reference value has not been loaded.\n const nestedFormValue = (0, lodash_1.get)(data, component.path);\n const noReferenceAttached = (nestedFormValue === null || nestedFormValue === void 0 ? void 0 : nestedFormValue._id) && (0, lodash_1.isEmpty)(nestedFormValue.data) && !(0, lodash_1.has)(nestedFormValue, 'form');\n const shouldProcessNestedFormData = (nestedFormValue === null || nestedFormValue === void 0 ? void 0 : nestedFormValue._id) ? !noReferenceAttached : (0, lodash_1.has)(data, component.path);\n if (shouldProcessNestedFormData) {\n // For nested forms, we need to reset the \"data\" and \"path\" objects for all of the children components, and then re-establish the data when it is done.\n const childPath = (0, exports.componentDataPath)(component, path, compPath);\n const childData = (0, lodash_1.get)(data, childPath, null);\n yield (0, exports.eachComponentDataAsync)(component.components, childData, fn, '', index, component, includeAll);\n (0, lodash_1.set)(data, childPath, childData);\n }\n }\n else {\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, (0, exports.componentDataPath)(component, path, compPath), index, component, includeAll);\n }\n return true;\n }\n return false;\n }), true, path, parent);\n});\nexports.eachComponentDataAsync = eachComponentDataAsync;\nconst eachComponentData = (components, data, fn, path = \"\", index, parent, includeAll = false) => {\n if (!components || !data) {\n return;\n }\n return eachComponent(components, (component, compPath, componentComponents, compParent) => {\n const row = getContextualRowData(component, compPath, data);\n if (fn(component, data, row, compPath, componentComponents, index, compParent) === true) {\n return true;\n }\n if (isComponentNestedDataType(component)) {\n const value = (0, lodash_1.get)(data, compPath, data);\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const nestedComponentPath = getModelType(component) === 'nestedDataArray' ? `${compPath}[${i}].data` : `${compPath}[${i}]`;\n (0, exports.eachComponentData)(component.components, data, fn, nestedComponentPath, i, component, includeAll);\n }\n return true;\n }\n else if ((0, lodash_1.isEmpty)(row) && !includeAll) {\n // Tree components may submit empty objects; since we've already evaluated the parent tree/layout component, we won't worry about constituent elements\n return true;\n }\n if (getModelType(component) === 'dataObject') {\n // No need to bother processing all the children data if there is no data for this form or the reference value has not been loaded.\n const nestedFormValue = (0, lodash_1.get)(data, component.path);\n const noReferenceAttached = (nestedFormValue === null || nestedFormValue === void 0 ? void 0 : nestedFormValue._id) && (0, lodash_1.isEmpty)(nestedFormValue.data) && !(0, lodash_1.has)(nestedFormValue, 'form');\n const shouldProcessNestedFormData = (nestedFormValue === null || nestedFormValue === void 0 ? void 0 : nestedFormValue._id) ? !noReferenceAttached : (0, lodash_1.has)(data, component.path);\n if (shouldProcessNestedFormData) {\n // For nested forms, we need to reset the \"data\" and \"path\" objects for all of the children components, and then re-establish the data when it is done.\n const childPath = (0, exports.componentDataPath)(component, path, compPath);\n const childData = (0, lodash_1.get)(data, childPath, {});\n (0, exports.eachComponentData)(component.components, childData, fn, '', index, component, includeAll);\n (0, lodash_1.set)(data, childPath, childData);\n }\n }\n else {\n (0, exports.eachComponentData)(component.components, data, fn, (0, exports.componentDataPath)(component, path, compPath), index, component, includeAll);\n }\n return true;\n }\n return false;\n }, true, path, parent);\n};\nexports.eachComponentData = eachComponentData;\nfunction getComponentKey(component) {\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, path) {\n return path.replace(new RegExp(`\\.?${getComponentKey(component)}$`), '');\n}\nexports.getContextualRowPath = getContextualRowPath;\nfunction getContextualRowData(component, path, data) {\n const rowPath = getContextualRowPath(component, path);\n return rowPath ? (0, lodash_1.get)(data, rowPath, null) : data;\n}\nexports.getContextualRowData = getContextualRowData;\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/**\n * Iterate through each component within a form.\n *\n * @param {Object} components\n * The components to iterate.\n * @param {Function} fn\n * The iteration function to invoke for each component.\n * @param {Boolean} includeAll\n * Whether or not to include layout components.\n * @param {String} path\n * The current data path of the element. Example: data.user.firstName\n * @param {Object} parent\n * The parent object.\n */\nfunction eachComponent(components, fn, includeAll, path, parent) {\n if (!components)\n return;\n path = path || \"\";\n components.forEach((component) => {\n if (!component) {\n return;\n }\n const info = componentInfo(component);\n let noRecurse = false;\n // Keep track of parent references.\n if (parent) {\n // Ensure we don't create infinite JSON structures.\n Object.defineProperty(component, 'parent', {\n enumerable: false,\n writable: true,\n value: JSON.parse(JSON.stringify(parent))\n });\n Object.defineProperty(component.parent, 'parent', {\n enumerable: false,\n writable: true,\n value: parent.parent\n });\n Object.defineProperty(component.parent, 'path', {\n enumerable: false,\n writable: true,\n value: parent.path\n });\n delete component.parent.components;\n delete component.parent.componentMap;\n delete component.parent.columns;\n delete component.parent.rows;\n }\n Object.defineProperty(component, 'path', {\n enumerable: false,\n writable: true,\n value: componentPath(component, path)\n });\n if (includeAll || component.tree || !info.layout) {\n noRecurse = fn(component, component.path, components, parent);\n }\n if (!noRecurse) {\n if (info.hasColumns) {\n component.columns.forEach((column) => eachComponent(column.components, fn, includeAll, path, parent ? component : null));\n }\n else if (info.hasRows) {\n component.rows.forEach((row) => {\n if (Array.isArray(row)) {\n row.forEach((column) => eachComponent(column.components, fn, includeAll, path, parent ? component : null));\n }\n });\n }\n else if (info.hasComps) {\n eachComponent(component.components, fn, includeAll, (0, exports.componentFormPath)(component, path, component.path), parent ? component : null);\n }\n }\n });\n}\nexports.eachComponent = eachComponent;\n// Async each component.\nfunction eachComponentAsync(components_2, fn_1) {\n return __awaiter(this, arguments, void 0, function* (components, fn, includeAll = false, path = \"\", parent) {\n var _a, _b;\n if (!components)\n return;\n for (let i = 0; i < components.length; i++) {\n if (!components[i]) {\n continue;\n }\n let component = components[i];\n const info = componentInfo(component);\n // Keep track of parent references.\n if (parent) {\n // Ensure we don't create infinite JSON structures.\n Object.defineProperty(component, 'parent', {\n enumerable: false,\n writable: true,\n value: JSON.parse(JSON.stringify(parent))\n });\n Object.defineProperty(component.parent, 'parent', {\n enumerable: false,\n writable: true,\n value: parent.parent\n });\n Object.defineProperty(component.parent, 'path', {\n enumerable: false,\n writable: true,\n value: parent.path\n });\n delete component.parent.components;\n delete component.parent.componentMap;\n delete component.parent.columns;\n delete component.parent.rows;\n }\n Object.defineProperty(component, 'path', {\n enumerable: false,\n writable: true,\n value: componentPath(component, path)\n });\n if (includeAll || component.tree || !info.layout) {\n if (yield fn(component, component.path, components, parent)) {\n continue;\n }\n }\n if (info.hasColumns) {\n for (let j = 0; j < component.columns.length; j++) {\n yield eachComponentAsync((_a = component.columns[j]) === null || _a === void 0 ? void 0 : _a.components, fn, includeAll, path, parent ? component : null);\n }\n }\n else if (info.hasRows) {\n for (let j = 0; j < component.rows.length; j++) {\n let row = component.rows[j];\n if (Array.isArray(row)) {\n for (let k = 0; k < row.length; k++) {\n yield eachComponentAsync((_b = row[k]) === null || _b === void 0 ? void 0 : _b.components, fn, includeAll, path, parent ? component : null);\n }\n }\n }\n }\n else if (info.hasComps) {\n yield eachComponentAsync(component.components, fn, includeAll, (0, exports.componentFormPath)(component, path, component.path), parent ? component : null);\n }\n }\n });\n}\nexports.eachComponentAsync = eachComponentAsync;\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, exports.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 getComponentActualValue(component, compPath, data, row) {\n var _a;\n // The compPath here will NOT contain the indexes for DataGrids and EditGrids.\n //\n // a[0].b[2].c[3].d\n //\n // Because of this, we will need to determine our parent component path (not data path),\n // and find the \"row\" based comp path.\n //\n // a[0].b[2].c[3].d => a.b.c.d\n //\n let parentInputComponent = null;\n let parent = component;\n let rowPath = '';\n while (((_a = parent === null || parent === void 0 ? void 0 : parent.parent) === null || _a === void 0 ? void 0 : _a.path) && !parentInputComponent) {\n parent = parent.parent;\n if (parent.input) {\n parentInputComponent = parent;\n }\n }\n if (parentInputComponent) {\n const parentCompPath = parentInputComponent.path.replace(/\\[[0-9]+\\]/g, '');\n rowPath = compPath.replace(parentCompPath, '');\n rowPath = (0, lodash_1.trim)(rowPath, '. ');\n }\n let value = null;\n if (data) {\n value = (0, lodash_1.get)(data, compPath);\n }\n if (rowPath && row && (0, lodash_1.isNil)(value)) {\n value = (0, lodash_1.get)(row, rowPath);\n }\n if ((0, lodash_1.isNil)(value) || ((0, lodash_1.isObject)(value) && (0, lodash_1.isEmpty)(value))) {\n value = '';\n }\n return value;\n}\nexports.getComponentActualValue = getComponentActualValue;\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 && Array.isArray(component.columns)) ||\n (component.rows && Array.isArray(component.rows)) ||\n (component.components && 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) {\n if ((0, lodash_1.isString)(query)) {\n return (component.key === query) || (component.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 key\n *\n * @param {Object} components - The components to iterate.\n * @param {String|Object} key - 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, key, includeAll = false) {\n let result;\n eachComponent(components, (component, path) => {\n if ((path === key) || (component.path === key) || (component.input && (component.key === key))) {\n result = component;\n return true;\n }\n }, includeAll);\n return result;\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 eachComponent(components, (component) => {\n if (matchComponent(component, query)) {\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 // Using _.unset() leave a null value. Use Array splice instead.\n // @ts-ignore\n var 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 && (component.conditional.when ||\n component.conditional.json ||\n (component.conditional.conjunction && (0, lodash_1.isBoolean)(component.conditional.show) && !(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)\n ? value.replace(/[^\\de.+-]/gi, '')\n : 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)\n .toString()\n .split('.');\n parts[0] = (0, lodash_1.chunk)(Array.from(parts[0]).reverse(), 3)\n .reverse()\n .map((part) => part\n .reverse()\n .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 = ['label', 'title', 'legend', 'tooltip', 'description', 'placeholder', 'prefix', 'suffix', 'errorLabel', 'content', 'html'];\n const strings = [];\n 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') && component.hasOwnProperty('values') && Array.isArray(component.values) && 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 [\n 'loading...',\n 'Type to search'\n ].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 var found = false;\n switch (change.op) {\n case 'add':\n var 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 var container = (0, lodash_1.get)(parent, change.path);\n container.splice(change.index, 0, newComponent);\n });\n break;\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 (err) {\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 var 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 var 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 var rowPath = newPath.slice();\n rowPath.push(index);\n row.forEach(function (column, index) {\n var 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 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(value).some(Boolean);\n }\n else if (isDataGridComponent(component) || isEditGridComponent(component) || isDataTableComponent(component) || 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, exports.eachComponentData)([component], data, (thisComponent, data, row, path, components, index) => {\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 ? typeof value === 'string' ? isValueEmpty(component, value.trim()) : isValueEmpty(component, value) : isValueEmpty(component, trimBlanks(value));\n }\n else if (isTextFieldComponent(component)) {\n if (component.allowMultipleMasks && !!component.inputMasks && !!component.inputMasks.length) {\n return isValueEmpty(component, value) || (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\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/utils/formUtil.js?");
1338
+ 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.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.getComponentActualValue = exports.getComponentData = exports.eachComponentAsync = exports.eachComponent = exports.componentInfo = exports.getContextualRowData = exports.getContextualRowPath = exports.getComponentKey = exports.eachComponentData = exports.eachComponentDataAsync = exports.componentFormPath = exports.componentDataPath = exports.componentPath = exports.isComponentNestedDataType = exports.getComponentPath = exports.getComponentAbsolutePath = 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 Evaluator_1 = __webpack_require__(/*! ./Evaluator */ \"./node_modules/@formio/core/lib/utils/Evaluator.js\");\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 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: [\n 'datagrid',\n 'editgrid',\n 'datatable',\n 'dynamicWizard',\n ],\n nestedDataArray: [\n 'tagpad',\n ],\n dataObject: [\n 'form'\n ],\n object: [\n 'container',\n 'address',\n ],\n map: [\n 'datamap',\n ],\n content: [\n 'htmlelement',\n 'content'\n ],\n string: [\n 'textfield',\n 'password',\n 'email',\n 'url',\n 'phoneNumber',\n 'day',\n 'datetime',\n 'time',\n 'signature',\n ],\n number: [\n 'number',\n 'currency'\n ],\n boolean: [\n 'checkbox',\n 'radio',\n ],\n none: [\n 'table',\n 'well',\n 'columns',\n 'fieldset',\n 'panel',\n 'tabs'\n ],\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 // 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 return type;\n }\n }\n // Otherwise check for components that assert no value.\n if ((component.input === false)) {\n return 'none';\n }\n // Otherwise default to any.\n return 'any';\n}\nexports.getModelType = getModelType;\nfunction getComponentAbsolutePath(component) {\n let paths = [component.path];\n while (component.parent) {\n component = component.parent;\n // We only need to do this for nested forms because they reset the data contexts for the children.\n if (getModelType(component) === 'dataObject') {\n paths[paths.length - 1] = `data.${paths[paths.length - 1]}`;\n paths.push(component.path);\n }\n }\n return paths.reverse().join('.');\n}\nexports.getComponentAbsolutePath = getComponentAbsolutePath;\nfunction getComponentPath(component, path) {\n const key = getComponentKey(component);\n if (!key) {\n return path;\n }\n if (!path) {\n return key;\n }\n if (path.match(new RegExp(`${key}$`))) {\n return path;\n }\n return (getModelType(component) === 'none') ? `${path}.${key}` : path;\n}\nexports.getComponentPath = getComponentPath;\nfunction isComponentNestedDataType(component) {\n return component.tree || getModelType(component) === 'nestedArray' ||\n getModelType(component) === 'nestedDataArray' ||\n getModelType(component) === 'dataObject' ||\n getModelType(component) === 'object' ||\n getModelType(component) === 'map';\n}\nexports.isComponentNestedDataType = isComponentNestedDataType;\nfunction componentPath(component, parentPath) {\n parentPath = component.parentPath || parentPath;\n const key = getComponentKey(component);\n if (!key) {\n // If the component does not have a key, then just always return the parent path.\n return parentPath || '';\n }\n return parentPath ? `${parentPath}.${key}` : key;\n}\nexports.componentPath = componentPath;\nconst componentDataPath = (component, parentPath, path) => {\n parentPath = component.parentPath || parentPath;\n path = path || componentPath(component, parentPath);\n // See if we are a nested component.\n if (component.components && Array.isArray(component.components)) {\n if (getModelType(component) === 'dataObject') {\n return `${path}.data`;\n }\n if (getModelType(component) === 'nestedArray') {\n return `${path}[0]`;\n }\n if (getModelType(component) === 'nestedDataArray') {\n return `${path}[0].data`;\n }\n if (isComponentNestedDataType(component)) {\n return path;\n }\n return parentPath;\n }\n return path;\n};\nexports.componentDataPath = componentDataPath;\nconst componentFormPath = (component, parentPath, path) => {\n parentPath = component.parentPath || parentPath;\n path = path || componentPath(component, parentPath);\n if (getModelType(component) === 'dataObject') {\n return `${path}.data`;\n }\n if (isComponentNestedDataType(component)) {\n return path;\n }\n return parentPath;\n};\nexports.componentFormPath = componentFormPath;\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, path = \"\", index, parent, includeAll = false) {\n if (!components || !data) {\n return;\n }\n return yield eachComponentAsync(components, (component, compPath, componentComponents, compParent) => __awaiter(void 0, void 0, void 0, function* () {\n const row = getContextualRowData(component, compPath, data);\n if ((yield fn(component, data, row, compPath, componentComponents, index, compParent)) === true) {\n return true;\n }\n if (isComponentNestedDataType(component)) {\n const value = (0, lodash_1.get)(data, compPath, data);\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const nestedComponentPath = getModelType(component) === 'nestedDataArray' ? `${compPath}[${i}].data` : `${compPath}[${i}]`;\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, nestedComponentPath, i, component, includeAll);\n }\n return true;\n }\n else if ((0, lodash_1.isEmpty)(row) && !includeAll) {\n // Tree components may submit empty objects; since we've already evaluated the parent tree/layout component, we won't worry about constituent elements\n return true;\n }\n if (getModelType(component) === 'dataObject') {\n // No need to bother processing all the children data if there is no data for this form or the reference value has not been loaded.\n const nestedFormValue = (0, lodash_1.get)(data, component.path);\n const noReferenceAttached = (nestedFormValue === null || nestedFormValue === void 0 ? void 0 : nestedFormValue._id) && (0, lodash_1.isEmpty)(nestedFormValue.data) && !(0, lodash_1.has)(nestedFormValue, 'form');\n const shouldProcessNestedFormData = (nestedFormValue === null || nestedFormValue === void 0 ? void 0 : nestedFormValue._id) ? !noReferenceAttached : (0, lodash_1.has)(data, component.path);\n if (shouldProcessNestedFormData) {\n // For nested forms, we need to reset the \"data\" and \"path\" objects for all of the children components, and then re-establish the data when it is done.\n const childPath = (0, exports.componentDataPath)(component, path, compPath);\n const childData = (0, lodash_1.get)(data, childPath, null);\n yield (0, exports.eachComponentDataAsync)(component.components, childData, fn, '', index, component, includeAll);\n (0, lodash_1.set)(data, childPath, childData);\n }\n }\n else {\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, (0, exports.componentDataPath)(component, path, compPath), index, component, includeAll);\n }\n return true;\n }\n return false;\n }), true, path, parent);\n});\nexports.eachComponentDataAsync = eachComponentDataAsync;\nconst eachComponentData = (components, data, fn, path = \"\", index, parent, includeAll = false) => {\n if (!components || !data) {\n return;\n }\n return eachComponent(components, (component, compPath, componentComponents, compParent) => {\n const row = getContextualRowData(component, compPath, data);\n if (fn(component, data, row, compPath, componentComponents, index, compParent) === true) {\n return true;\n }\n if (isComponentNestedDataType(component)) {\n const value = (0, lodash_1.get)(data, compPath, data);\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const nestedComponentPath = getModelType(component) === 'nestedDataArray' ? `${compPath}[${i}].data` : `${compPath}[${i}]`;\n (0, exports.eachComponentData)(component.components, data, fn, nestedComponentPath, i, component, includeAll);\n }\n return true;\n }\n else if ((0, lodash_1.isEmpty)(row) && !includeAll) {\n // Tree components may submit empty objects; since we've already evaluated the parent tree/layout component, we won't worry about constituent elements\n return true;\n }\n if (getModelType(component) === 'dataObject') {\n // No need to bother processing all the children data if there is no data for this form or the reference value has not been loaded.\n const nestedFormValue = (0, lodash_1.get)(data, component.path);\n const noReferenceAttached = (nestedFormValue === null || nestedFormValue === void 0 ? void 0 : nestedFormValue._id) && (0, lodash_1.isEmpty)(nestedFormValue.data) && !(0, lodash_1.has)(nestedFormValue, 'form');\n const shouldProcessNestedFormData = (nestedFormValue === null || nestedFormValue === void 0 ? void 0 : nestedFormValue._id) ? !noReferenceAttached : (0, lodash_1.has)(data, component.path);\n if (shouldProcessNestedFormData) {\n // For nested forms, we need to reset the \"data\" and \"path\" objects for all of the children components, and then re-establish the data when it is done.\n const childPath = (0, exports.componentDataPath)(component, path, compPath);\n const childData = (0, lodash_1.get)(data, childPath, {});\n (0, exports.eachComponentData)(component.components, childData, fn, '', index, component, includeAll);\n (0, lodash_1.set)(data, childPath, childData);\n }\n }\n else {\n (0, exports.eachComponentData)(component.components, data, fn, (0, exports.componentDataPath)(component, path, compPath), index, component, includeAll);\n }\n return true;\n }\n return false;\n }, true, path, parent);\n};\nexports.eachComponentData = eachComponentData;\nfunction getComponentKey(component) {\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, path) {\n return path.replace(new RegExp(`\\.?${getComponentKey(component)}$`), '');\n}\nexports.getContextualRowPath = getContextualRowPath;\nfunction getContextualRowData(component, path, data) {\n const rowPath = getContextualRowPath(component, path);\n return rowPath ? (0, lodash_1.get)(data, rowPath, null) : data;\n}\nexports.getContextualRowData = getContextualRowData;\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/**\n * Iterate through each component within a form.\n *\n * @param {Object} components\n * The components to iterate.\n * @param {Function} fn\n * The iteration function to invoke for each component.\n * @param {Boolean} includeAll\n * Whether or not to include layout components.\n * @param {String} path\n * The current data path of the element. Example: data.user.firstName\n * @param {Object} parent\n * The parent object.\n */\nfunction eachComponent(components, fn, includeAll, path, parent) {\n if (!components)\n return;\n path = path || \"\";\n components.forEach((component) => {\n if (!component) {\n return;\n }\n const info = componentInfo(component);\n let noRecurse = false;\n // Keep track of parent references.\n if (parent) {\n // Ensure we don't create infinite JSON structures.\n Object.defineProperty(component, 'parent', {\n enumerable: false,\n writable: true,\n value: JSON.parse(JSON.stringify(parent))\n });\n Object.defineProperty(component.parent, 'parent', {\n enumerable: false,\n writable: true,\n value: parent.parent\n });\n Object.defineProperty(component.parent, 'path', {\n enumerable: false,\n writable: true,\n value: parent.path\n });\n delete component.parent.components;\n delete component.parent.componentMap;\n delete component.parent.columns;\n delete component.parent.rows;\n }\n Object.defineProperty(component, 'path', {\n enumerable: false,\n writable: true,\n value: componentPath(component, path)\n });\n if (includeAll || component.tree || !info.layout) {\n noRecurse = fn(component, component.path, components, parent);\n }\n if (!noRecurse) {\n if (info.hasColumns) {\n component.columns.forEach((column) => eachComponent(column.components, fn, includeAll, path, parent ? component : null));\n }\n else if (info.hasRows) {\n component.rows.forEach((row) => {\n if (Array.isArray(row)) {\n row.forEach((column) => eachComponent(column.components, fn, includeAll, path, parent ? component : null));\n }\n });\n }\n else if (info.hasComps) {\n eachComponent(component.components, fn, includeAll, (0, exports.componentFormPath)(component, path, component.path), parent ? component : null);\n }\n }\n });\n}\nexports.eachComponent = eachComponent;\n// Async each component.\nfunction eachComponentAsync(components_2, fn_1) {\n return __awaiter(this, arguments, void 0, function* (components, fn, includeAll = false, path = \"\", parent) {\n var _a, _b;\n if (!components)\n return;\n for (let i = 0; i < components.length; i++) {\n if (!components[i]) {\n continue;\n }\n let component = components[i];\n const info = componentInfo(component);\n // Keep track of parent references.\n if (parent) {\n // Ensure we don't create infinite JSON structures.\n Object.defineProperty(component, 'parent', {\n enumerable: false,\n writable: true,\n value: JSON.parse(JSON.stringify(parent))\n });\n Object.defineProperty(component.parent, 'parent', {\n enumerable: false,\n writable: true,\n value: parent.parent\n });\n Object.defineProperty(component.parent, 'path', {\n enumerable: false,\n writable: true,\n value: parent.path\n });\n delete component.parent.components;\n delete component.parent.componentMap;\n delete component.parent.columns;\n delete component.parent.rows;\n }\n Object.defineProperty(component, 'path', {\n enumerable: false,\n writable: true,\n value: componentPath(component, path)\n });\n if (includeAll || component.tree || !info.layout) {\n if (yield fn(component, component.path, components, parent)) {\n continue;\n }\n }\n if (info.hasColumns) {\n for (let j = 0; j < component.columns.length; j++) {\n yield eachComponentAsync((_a = component.columns[j]) === null || _a === void 0 ? void 0 : _a.components, fn, includeAll, path, parent ? component : null);\n }\n }\n else if (info.hasRows) {\n for (let j = 0; j < component.rows.length; j++) {\n let row = component.rows[j];\n if (Array.isArray(row)) {\n for (let k = 0; k < row.length; k++) {\n yield eachComponentAsync((_b = row[k]) === null || _b === void 0 ? void 0 : _b.components, fn, includeAll, path, parent ? component : null);\n }\n }\n }\n }\n else if (info.hasComps) {\n yield eachComponentAsync(component.components, fn, includeAll, (0, exports.componentFormPath)(component, path, component.path), parent ? component : null);\n }\n }\n });\n}\nexports.eachComponentAsync = eachComponentAsync;\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, exports.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 getComponentActualValue(component, compPath, data, row) {\n var _a;\n // The compPath here will NOT contain the indexes for DataGrids and EditGrids.\n //\n // a[0].b[2].c[3].d\n //\n // Because of this, we will need to determine our parent component path (not data path),\n // and find the \"row\" based comp path.\n //\n // a[0].b[2].c[3].d => a.b.c.d\n //\n let parentInputComponent = null;\n let parent = component;\n let rowPath = '';\n while (((_a = parent === null || parent === void 0 ? void 0 : parent.parent) === null || _a === void 0 ? void 0 : _a.path) && !parentInputComponent) {\n parent = parent.parent;\n if (parent.input) {\n parentInputComponent = parent;\n }\n }\n if (parentInputComponent) {\n const parentCompPath = parentInputComponent.path.replace(/\\[[0-9]+\\]/g, '');\n rowPath = compPath.replace(parentCompPath, '');\n rowPath = (0, lodash_1.trim)(rowPath, '. ');\n }\n let value = null;\n if (data) {\n value = (0, lodash_1.get)(data, compPath);\n }\n if (rowPath && row && (0, lodash_1.isNil)(value)) {\n value = (0, lodash_1.get)(row, rowPath);\n }\n if ((0, lodash_1.isNil)(value) || ((0, lodash_1.isObject)(value) && (0, lodash_1.isEmpty)(value))) {\n value = '';\n }\n return value;\n}\nexports.getComponentActualValue = getComponentActualValue;\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 && Array.isArray(component.columns)) ||\n (component.rows && Array.isArray(component.rows)) ||\n (component.components && 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) {\n if ((0, lodash_1.isString)(query)) {\n return (component.key === query) || (component.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 key\n *\n * @param {Object} components - The components to iterate.\n * @param {String|Object} key - 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, key, includeAll = false) {\n let result;\n eachComponent(components, (component, path) => {\n if ((path === key) || (component.path === key) || (component.input && (component.key === key))) {\n result = component;\n return true;\n }\n }, includeAll);\n return result;\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 eachComponent(components, (component) => {\n if (matchComponent(component, query)) {\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 // Using _.unset() leave a null value. Use Array splice instead.\n // @ts-ignore\n var 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 && (component.conditional.when ||\n component.conditional.json ||\n (component.conditional.conjunction && (0, lodash_1.isBoolean)(component.conditional.show) && !(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)\n ? value.replace(/[^\\de.+-]/gi, '')\n : 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)\n .toString()\n .split('.');\n parts[0] = (0, lodash_1.chunk)(Array.from(parts[0]).reverse(), 3)\n .reverse()\n .map((part) => part\n .reverse()\n .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 = ['label', 'title', 'legend', 'tooltip', 'description', 'placeholder', 'prefix', 'suffix', 'errorLabel', 'content', 'html'];\n const strings = [];\n 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') && component.hasOwnProperty('values') && Array.isArray(component.values) && 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 [\n 'loading...',\n 'Type to search'\n ].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 var found = false;\n switch (change.op) {\n case 'add':\n var 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 var container = (0, lodash_1.get)(parent, change.path);\n container.splice(change.index, 0, newComponent);\n });\n break;\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 (err) {\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 var 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 var 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 var rowPath = newPath.slice();\n rowPath.push(index);\n row.forEach(function (column, index) {\n var 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 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(value).some(Boolean);\n }\n else if (isDataGridComponent(component) || isEditGridComponent(component) || isDataTableComponent(component) || 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, exports.eachComponentData)([component], data, (thisComponent, data, row, path, components, index) => {\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 ? typeof value === 'string' ? isValueEmpty(component, value.trim()) : isValueEmpty(component, value) : isValueEmpty(component, trimBlanks(value));\n }\n else if (isTextFieldComponent(component)) {\n if (component.allowMultipleMasks && !!component.inputMasks && !!component.inputMasks.length) {\n return isValueEmpty(component, value) || (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\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/utils/formUtil.js?");
1339
1339
 
1340
1340
  /***/ }),
1341
1341